David Herrmann | d99b8ba | 2012-06-10 15:16:26 +0200 | [diff] [blame] | 1 | UHID - User-space I/O driver support for HID subsystem |
| 2 | ======================================================== |
| 3 | |
| 4 | The HID subsystem needs two kinds of drivers. In this document we call them: |
| 5 | |
| 6 | 1. The "HID I/O Driver" is the driver that performs raw data I/O to the |
| 7 | low-level device. Internally, they register an hid_ll_driver structure with |
| 8 | the HID core. They perform device setup, read raw data from the device and |
| 9 | push it into the HID subsystem and they provide a callback so the HID |
| 10 | subsystem can send data to the device. |
| 11 | |
| 12 | 2. The "HID Device Driver" is the driver that parses HID reports and reacts on |
| 13 | them. There are generic drivers like "generic-usb" and "generic-bluetooth" |
| 14 | which adhere to the HID specification and provide the standardizes features. |
| 15 | But there may be special drivers and quirks for each non-standard device out |
| 16 | there. Internally, they use the hid_driver structure. |
| 17 | |
| 18 | Historically, the USB stack was the first subsystem to provide an HID I/O |
| 19 | Driver. However, other standards like Bluetooth have adopted the HID specs and |
| 20 | may provide HID I/O Drivers, too. The UHID driver allows to implement HID I/O |
| 21 | Drivers in user-space and feed the data into the kernel HID-subsystem. |
| 22 | |
| 23 | This allows user-space to operate on the same level as USB-HID, Bluetooth-HID |
| 24 | and similar. It does not provide a way to write HID Device Drivers, though. Use |
| 25 | hidraw for this purpose. |
| 26 | |
| 27 | There is an example user-space application in ./samples/uhid/uhid-example.c |
| 28 | |
| 29 | The UHID API |
| 30 | ------------ |
| 31 | |
| 32 | UHID is accessed through a character misc-device. The minor-number is allocated |
| 33 | dynamically so you need to rely on udev (or similar) to create the device node. |
| 34 | This is /dev/uhid by default. |
| 35 | |
| 36 | If a new device is detected by your HID I/O Driver and you want to register this |
| 37 | device with the HID subsystem, then you need to open /dev/uhid once for each |
| 38 | device you want to register. All further communication is done by read()'ing or |
| 39 | write()'ing "struct uhid_event" objects. Non-blocking operations are supported |
| 40 | by setting O_NONBLOCK. |
| 41 | |
| 42 | struct uhid_event { |
| 43 | __u32 type; |
| 44 | union { |
| 45 | struct uhid_create_req create; |
| 46 | struct uhid_data_req data; |
| 47 | ... |
| 48 | } u; |
| 49 | }; |
| 50 | |
| 51 | The "type" field contains the ID of the event. Depending on the ID different |
| 52 | payloads are sent. You must not split a single event across multiple read()'s or |
| 53 | multiple write()'s. A single event must always be sent as a whole. Furthermore, |
| 54 | only a single event can be sent per read() or write(). Pending data is ignored. |
| 55 | If you want to handle multiple events in a single syscall, then use vectored |
| 56 | I/O with readv()/writev(). |
| 57 | |
| 58 | The first thing you should do is sending an UHID_CREATE event. This will |
| 59 | register the device. UHID will respond with an UHID_START event. You can now |
| 60 | start sending data to and reading data from UHID. However, unless UHID sends the |
| 61 | UHID_OPEN event, the internally attached HID Device Driver has no user attached. |
| 62 | That is, you might put your device asleep unless you receive the UHID_OPEN |
| 63 | event. If you receive the UHID_OPEN event, you should start I/O. If the last |
| 64 | user closes the HID device, you will receive an UHID_CLOSE event. This may be |
| 65 | followed by an UHID_OPEN event again and so on. There is no need to perform |
| 66 | reference-counting in user-space. That is, you will never receive multiple |
| 67 | UHID_OPEN events without an UHID_CLOSE event. The HID subsystem performs |
| 68 | ref-counting for you. |
| 69 | You may decide to ignore UHID_OPEN/UHID_CLOSE, though. I/O is allowed even |
| 70 | though the device may have no users. |
| 71 | |
| 72 | If you want to send data to the HID subsystem, you send an HID_INPUT event with |
| 73 | your raw data payload. If the kernel wants to send data to the device, you will |
| 74 | read an UHID_OUTPUT or UHID_OUTPUT_EV event. |
| 75 | |
| 76 | If your device disconnects, you should send an UHID_DESTROY event. This will |
| 77 | unregister the device. You can now send UHID_CREATE again to register a new |
| 78 | device. |
| 79 | If you close() the fd, the device is automatically unregistered and destroyed |
| 80 | internally. |
| 81 | |
| 82 | write() |
| 83 | ------- |
| 84 | write() allows you to modify the state of the device and feed input data into |
| 85 | the kernel. The following types are supported: UHID_CREATE, UHID_DESTROY and |
| 86 | UHID_INPUT. The kernel will parse the event immediately and if the event ID is |
| 87 | not supported, it will return -EOPNOTSUPP. If the payload is invalid, then |
| 88 | -EINVAL is returned, otherwise, the amount of data that was read is returned and |
| 89 | the request was handled successfully. |
| 90 | |
| 91 | UHID_CREATE: |
| 92 | This creates the internal HID device. No I/O is possible until you send this |
| 93 | event to the kernel. The payload is of type struct uhid_create_req and |
| 94 | contains information about your device. You can start I/O now. |
| 95 | |
| 96 | UHID_DESTROY: |
| 97 | This destroys the internal HID device. No further I/O will be accepted. There |
| 98 | may still be pending messages that you can receive with read() but no further |
| 99 | UHID_INPUT events can be sent to the kernel. |
| 100 | You can create a new device by sending UHID_CREATE again. There is no need to |
| 101 | reopen the character device. |
| 102 | |
| 103 | UHID_INPUT: |
| 104 | You must send UHID_CREATE before sending input to the kernel! This event |
| 105 | contains a data-payload. This is the raw data that you read from your device. |
| 106 | The kernel will parse the HID reports and react on it. |
| 107 | |
| 108 | UHID_FEATURE_ANSWER: |
| 109 | If you receive a UHID_FEATURE request you must answer with this request. You |
| 110 | must copy the "id" field from the request into the answer. Set the "err" field |
Masanari Iida | 4e79162a | 2012-11-08 21:57:35 +0900 | [diff] [blame] | 111 | to 0 if no error occurred or to EIO if an I/O error occurred. |
David Herrmann | d99b8ba | 2012-06-10 15:16:26 +0200 | [diff] [blame] | 112 | If "err" is 0 then you should fill the buffer of the answer with the results |
| 113 | of the feature request and set "size" correspondingly. |
| 114 | |
| 115 | read() |
| 116 | ------ |
Carlos Garcia | c98be0c | 2014-04-04 22:31:00 -0400 | [diff] [blame^] | 117 | read() will return a queued output report. These output reports can be of type |
David Herrmann | d99b8ba | 2012-06-10 15:16:26 +0200 | [diff] [blame] | 118 | UHID_START, UHID_STOP, UHID_OPEN, UHID_CLOSE, UHID_OUTPUT or UHID_OUTPUT_EV. No |
| 119 | reaction is required to any of them but you should handle them according to your |
| 120 | needs. Only UHID_OUTPUT and UHID_OUTPUT_EV have payloads. |
| 121 | |
| 122 | UHID_START: |
| 123 | This is sent when the HID device is started. Consider this as an answer to |
| 124 | UHID_CREATE. This is always the first event that is sent. |
| 125 | |
| 126 | UHID_STOP: |
| 127 | This is sent when the HID device is stopped. Consider this as an answer to |
| 128 | UHID_DESTROY. |
| 129 | If the kernel HID device driver closes the device manually (that is, you |
| 130 | didn't send UHID_DESTROY) then you should consider this device closed and send |
| 131 | an UHID_DESTROY event. You may want to reregister your device, though. This is |
| 132 | always the last message that is sent to you unless you reopen the device with |
| 133 | UHID_CREATE. |
| 134 | |
| 135 | UHID_OPEN: |
| 136 | This is sent when the HID device is opened. That is, the data that the HID |
| 137 | device provides is read by some other process. You may ignore this event but |
| 138 | it is useful for power-management. As long as you haven't received this event |
| 139 | there is actually no other process that reads your data so there is no need to |
| 140 | send UHID_INPUT events to the kernel. |
| 141 | |
| 142 | UHID_CLOSE: |
| 143 | This is sent when there are no more processes which read the HID data. It is |
| 144 | the counterpart of UHID_OPEN and you may as well ignore this event. |
| 145 | |
| 146 | UHID_OUTPUT: |
| 147 | This is sent if the HID device driver wants to send raw data to the I/O |
| 148 | device. You should read the payload and forward it to the device. The payload |
| 149 | is of type "struct uhid_data_req". |
| 150 | This may be received even though you haven't received UHID_OPEN, yet. |
| 151 | |
David Herrmann | bdb829e | 2013-07-15 19:10:15 +0200 | [diff] [blame] | 152 | UHID_OUTPUT_EV (obsolete): |
David Herrmann | d99b8ba | 2012-06-10 15:16:26 +0200 | [diff] [blame] | 153 | Same as UHID_OUTPUT but this contains a "struct input_event" as payload. This |
| 154 | is called for force-feedback, LED or similar events which are received through |
| 155 | an input device by the HID subsystem. You should convert this into raw reports |
| 156 | and send them to your device similar to events of type UHID_OUTPUT. |
David Herrmann | bdb829e | 2013-07-15 19:10:15 +0200 | [diff] [blame] | 157 | This is no longer sent by newer kernels. Instead, HID core converts it into a |
| 158 | raw output report and sends it via UHID_OUTPUT. |
David Herrmann | d99b8ba | 2012-06-10 15:16:26 +0200 | [diff] [blame] | 159 | |
| 160 | UHID_FEATURE: |
| 161 | This event is sent if the kernel driver wants to perform a feature request as |
| 162 | described in the HID specs. The report-type and report-number are available in |
| 163 | the payload. |
| 164 | The kernel serializes feature requests so there will never be two in parallel. |
| 165 | However, if you fail to respond with a UHID_FEATURE_ANSWER in a time-span of 5 |
| 166 | seconds, then the requests will be dropped and a new one might be sent. |
| 167 | Therefore, the payload also contains an "id" field that identifies every |
| 168 | request. |
| 169 | |
| 170 | Document by: |
| 171 | David Herrmann <dh.herrmann@googlemail.com> |