Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 1 | ================================================ |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 2 | Care and feeding of your Human Interface Devices |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 3 | ================================================ |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 4 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 5 | Introduction |
| 6 | ============ |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 7 | |
| 8 | In addition to the normal input type HID devices, USB also uses the |
| 9 | human interface device protocols for things that are not really human |
| 10 | interfaces, but have similar sorts of communication needs. The two big |
| 11 | examples for this are power devices (especially uninterruptable power |
| 12 | supplies) and monitor control on higher end monitors. |
| 13 | |
Matt LaPlante | 5d3f083 | 2006-11-30 05:21:10 +0100 | [diff] [blame] | 14 | To support these disparate requirements, the Linux USB system provides |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 15 | HID events to two separate interfaces: |
| 16 | * the input subsystem, which converts HID events into normal input |
| 17 | device interfaces (such as keyboard, mouse and joystick) and a |
Tom Saeger | 1752118 | 2017-10-10 12:36:23 -0500 | [diff] [blame] | 18 | normalised event interface - see Documentation/input/input.rst |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 19 | * the hiddev interface, which provides fairly raw HID events |
| 20 | |
| 21 | The data flow for a HID event produced by a device is something like |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 22 | the following:: |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 23 | |
| 24 | usb.c ---> hid-core.c ----> hid-input.c ----> [keyboard/mouse/joystick/event] |
| 25 | | |
| 26 | | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 27 | --> hiddev.c ----> POWER / MONITOR CONTROL |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 28 | |
| 29 | In addition, other subsystems (apart from USB) can potentially feed |
| 30 | events into the input subsystem, but these have no effect on the hid |
| 31 | device interface. |
| 32 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 33 | Using the HID Device Interface |
| 34 | ============================== |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 35 | |
| 36 | The hiddev interface is a char interface using the normal USB major, |
| 37 | with the minor numbers starting at 96 and finishing at 111. Therefore, |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 38 | you need the following commands:: |
| 39 | |
| 40 | mknod /dev/usb/hiddev0 c 180 96 |
| 41 | mknod /dev/usb/hiddev1 c 180 97 |
| 42 | mknod /dev/usb/hiddev2 c 180 98 |
| 43 | mknod /dev/usb/hiddev3 c 180 99 |
| 44 | mknod /dev/usb/hiddev4 c 180 100 |
| 45 | mknod /dev/usb/hiddev5 c 180 101 |
| 46 | mknod /dev/usb/hiddev6 c 180 102 |
| 47 | mknod /dev/usb/hiddev7 c 180 103 |
| 48 | mknod /dev/usb/hiddev8 c 180 104 |
| 49 | mknod /dev/usb/hiddev9 c 180 105 |
| 50 | mknod /dev/usb/hiddev10 c 180 106 |
| 51 | mknod /dev/usb/hiddev11 c 180 107 |
| 52 | mknod /dev/usb/hiddev12 c 180 108 |
| 53 | mknod /dev/usb/hiddev13 c 180 109 |
| 54 | mknod /dev/usb/hiddev14 c 180 110 |
| 55 | mknod /dev/usb/hiddev15 c 180 111 |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 56 | |
| 57 | So you point your hiddev compliant user-space program at the correct |
| 58 | interface for your device, and it all just works. |
| 59 | |
| 60 | Assuming that you have a hiddev compliant user-space program, of |
| 61 | course. If you need to write one, read on. |
| 62 | |
| 63 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 64 | The HIDDEV API |
| 65 | ============== |
| 66 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 67 | This description should be read in conjunction with the HID |
| 68 | specification, freely available from http://www.usb.org, and |
| 69 | conveniently linked of http://www.linux-usb.org. |
| 70 | |
| 71 | The hiddev API uses a read() interface, and a set of ioctl() calls. |
| 72 | |
| 73 | HID devices exchange data with the host computer using data |
| 74 | bundles called "reports". Each report is divided into "fields", |
| 75 | each of which can have one or more "usages". In the hid-core, |
| 76 | each one of these usages has a single signed 32 bit value. |
| 77 | |
| 78 | read(): |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 79 | ------- |
| 80 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 81 | This is the event interface. When the HID device's state changes, |
| 82 | it performs an interrupt transfer containing a report which contains |
| 83 | the changed value. The hid-core.c module parses the report, and |
| 84 | returns to hiddev.c the individual usages that have changed within |
| 85 | the report. In its basic mode, the hiddev will make these individual |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 86 | usage changes available to the reader using a struct hiddev_event:: |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 87 | |
| 88 | struct hiddev_event { |
| 89 | unsigned hid; |
| 90 | signed int value; |
| 91 | }; |
| 92 | |
| 93 | containing the HID usage identifier for the status that changed, and |
| 94 | the value that it was changed to. Note that the structure is defined |
| 95 | within <linux/hiddev.h>, along with some other useful #defines and |
| 96 | structures. The HID usage identifier is a composite of the HID usage |
| 97 | page shifted to the 16 high order bits ORed with the usage code. The |
| 98 | behavior of the read() function can be modified using the HIDIOCSFLAG |
| 99 | ioctl() described below. |
| 100 | |
| 101 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 102 | ioctl(): |
| 103 | -------- |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 104 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 105 | This is the control interface. There are a number of controls: |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 106 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 107 | HIDIOCGVERSION |
| 108 | - int (read) |
| 109 | |
| 110 | Gets the version code out of the hiddev driver. |
| 111 | |
| 112 | HIDIOCAPPLICATION |
| 113 | - (none) |
| 114 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 115 | This ioctl call returns the HID application usage associated with the |
| 116 | hid device. The third argument to ioctl() specifies which application |
| 117 | index to get. This is useful when the device has more than one |
| 118 | application collection. If the index is invalid (greater or equal to |
| 119 | the number of application collections this device has) the ioctl |
| 120 | returns -1. You can find out beforehand how many application |
| 121 | collections the device has from the num_applications field from the |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 122 | hiddev_devinfo structure. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 123 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 124 | HIDIOCGCOLLECTIONINFO |
| 125 | - struct hiddev_collection_info (read/write) |
| 126 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 127 | This returns a superset of the information above, providing not only |
| 128 | application collections, but all the collections the device has. It |
| 129 | also returns the level the collection lives in the hierarchy. |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 130 | The user passes in a hiddev_collection_info struct with the index |
| 131 | field set to the index that should be returned. The ioctl fills in |
| 132 | the other fields. If the index is larger than the last collection |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 133 | index, the ioctl returns -1 and sets errno to -EINVAL. |
| 134 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 135 | HIDIOCGDEVINFO |
| 136 | - struct hiddev_devinfo (read) |
| 137 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 138 | Gets a hiddev_devinfo structure which describes the device. |
| 139 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 140 | HIDIOCGSTRING |
| 141 | - struct hiddev_string_descriptor (read/write) |
| 142 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 143 | Gets a string descriptor from the device. The caller must fill in the |
| 144 | "index" field to indicate which descriptor should be returned. |
| 145 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 146 | HIDIOCINITREPORT |
| 147 | - (none) |
| 148 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 149 | Instructs the kernel to retrieve all input and feature report values |
| 150 | from the device. At this point, all the usage structures will contain |
| 151 | current values for the device, and will maintain it as the device |
| 152 | changes. Note that the use of this ioctl is unnecessary in general, |
| 153 | since later kernels automatically initialize the reports from the |
| 154 | device at attach time. |
| 155 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 156 | HIDIOCGNAME |
| 157 | - string (variable length) |
| 158 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 159 | Gets the device name |
| 160 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 161 | HIDIOCGREPORT |
| 162 | - struct hiddev_report_info (write) |
| 163 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 164 | Instructs the kernel to get a feature or input report from the device, |
| 165 | in order to selectively update the usage structures (in contrast to |
| 166 | INITREPORT). |
| 167 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 168 | HIDIOCSREPORT |
| 169 | - struct hiddev_report_info (write) |
| 170 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 171 | Instructs the kernel to send a report to the device. This report can |
| 172 | be filled in by the user through HIDIOCSUSAGE calls (below) to fill in |
| 173 | individual usage values in the report before sending the report in full |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 174 | to the device. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 175 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 176 | HIDIOCGREPORTINFO |
| 177 | - struct hiddev_report_info (read/write) |
| 178 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 179 | Fills in a hiddev_report_info structure for the user. The report is |
| 180 | looked up by type (input, output or feature) and id, so these fields |
| 181 | must be filled in by the user. The ID can be absolute -- the actual |
| 182 | report id as reported by the device -- or relative -- |
| 183 | HID_REPORT_ID_FIRST for the first report, and (HID_REPORT_ID_NEXT | |
| 184 | report_id) for the next report after report_id. Without a-priori |
| 185 | information about report ids, the right way to use this ioctl is to |
| 186 | use the relative IDs above to enumerate the valid IDs. The ioctl |
| 187 | returns non-zero when there is no more next ID. The real report ID is |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 188 | filled into the returned hiddev_report_info structure. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 189 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 190 | HIDIOCGFIELDINFO |
| 191 | - struct hiddev_field_info (read/write) |
| 192 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 193 | Returns the field information associated with a report in a |
| 194 | hiddev_field_info structure. The user must fill in report_id and |
| 195 | report_type in this structure, as above. The field_index should also |
| 196 | be filled in, which should be a number from 0 and maxfield-1, as |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 197 | returned from a previous HIDIOCGREPORTINFO call. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 198 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 199 | HIDIOCGUCODE |
| 200 | - struct hiddev_usage_ref (read/write) |
| 201 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 202 | Returns the usage_code in a hiddev_usage_ref structure, given that |
| 203 | given its report type, report id, field index, and index within the |
| 204 | field have already been filled into the structure. |
| 205 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 206 | HIDIOCGUSAGE |
| 207 | - struct hiddev_usage_ref (read/write) |
| 208 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 209 | Returns the value of a usage in a hiddev_usage_ref structure. The |
| 210 | usage to be retrieved can be specified as above, or the user can |
| 211 | choose to fill in the report_type field and specify the report_id as |
| 212 | HID_REPORT_ID_UNKNOWN. In this case, the hiddev_usage_ref will be |
| 213 | filled in with the report and field information associated with this |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 214 | usage if it is found. |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 215 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 216 | HIDIOCSUSAGE |
| 217 | - struct hiddev_usage_ref (write) |
| 218 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 219 | Sets the value of a usage in an output report. The user fills in |
| 220 | the hiddev_usage_ref structure as above, but additionally fills in |
| 221 | the value field. |
| 222 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 223 | HIDIOGCOLLECTIONINDEX |
| 224 | - struct hiddev_usage_ref (write) |
| 225 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 226 | Returns the collection index associated with this usage. This |
| 227 | indicates where in the collection hierarchy this usage sits. |
| 228 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 229 | HIDIOCGFLAG |
| 230 | - int (read) |
| 231 | HIDIOCSFLAG |
| 232 | - int (write) |
| 233 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 234 | These operations respectively inspect and replace the mode flags |
| 235 | that influence the read() call above. The flags are as follows: |
| 236 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 237 | HIDDEV_FLAG_UREF |
| 238 | - read() calls will now return |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 239 | struct hiddev_usage_ref instead of struct hiddev_event. |
| 240 | This is a larger structure, but in situations where the |
| 241 | device has more than one usage in its reports with the |
| 242 | same usage code, this mode serves to resolve such |
| 243 | ambiguity. |
| 244 | |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 245 | HIDDEV_FLAG_REPORT |
| 246 | - This flag can only be used in conjunction |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 247 | with HIDDEV_FLAG_UREF. With this flag set, when the device |
| 248 | sends a report, a struct hiddev_usage_ref will be returned |
Mauro Carvalho Chehab | cca4786 | 2019-06-28 09:19:59 -0300 | [diff] [blame] | 249 | to read() filled in with the report_type and report_id, but |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 250 | with field_index set to FIELD_INDEX_NONE. This serves as |
| 251 | additional notification when the device has sent a report. |