Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

HID: Add introduction about HID for non-kernel programmers

Add an introduction about HID meant for the casual programmer
that is trying either to fix his device or to understand
what is going wrong.

Signed-off-by: Marco Morandini <marco.morandini@polimi.it>
Co-authored-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>

authored by

Marco Morandini
Peter Hutterer
and committed by
Jiri Kosina
2326dee4 1d754604

+597
+524
Documentation/hid/hidintro.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + ====================================== 4 + Introduction to HID report descriptors 5 + ====================================== 6 + 7 + This chapter is meant to give a broad overview of what HID report 8 + descriptors are, and of how a casual (non-kernel) programmer can deal 9 + with HID devices that are not working well with Linux. 10 + 11 + .. contents:: 12 + :local: 13 + :depth: 2 14 + 15 + .. toctree:: 16 + :maxdepth: 2 17 + 18 + hidreport-parsing 19 + 20 + 21 + Introduction 22 + ============ 23 + 24 + HID stands for Human Interface Device, and can be whatever device you 25 + are using to interact with a computer, be it a mouse, a touchpad, a 26 + tablet, a microphone. 27 + 28 + Many HID devices work out the box, even if their hardware is different. 29 + For example, mice can have any number of buttons; they may have a 30 + wheel; movement sensitivity differs between different models, and so 31 + on. Nonetheless, most of the time everything just works, without the 32 + need to have specialized code in the kernel for every mouse model 33 + developed since 1970. 34 + 35 + This is because modern HID devices do advertise their capabilities 36 + through the *HID report descriptor*, a fixed set of bytes describing 37 + exactly what *HID reports* may be sent between the device and the host 38 + and the meaning of each individual bit in those reports. For example, 39 + a HID Report Descriptor may specify that "in a report with ID 3 the 40 + bits from 8 to 15 is the delta x coordinate of a mouse". 41 + 42 + The HID report itself then merely carries the actual data values 43 + without any extra meta information. Note that HID reports may be sent 44 + from the device ("Input Reports", i.e. input events), to the device 45 + ("Output Reports" to e.g. change LEDs) or used for device configuration 46 + ("Feature reports"). A device may support one or more HID reports. 47 + 48 + The HID subsystem is in charge of parsing the HID report descriptors, 49 + and converts HID events into normal input device interfaces (see 50 + Documentation/hid/hid-transport.rst). Devices may misbehave because the 51 + HID report descriptor provided by the device is wrong, or because it 52 + needs to be dealt with in a special way, or because some special 53 + device or interaction mode is not handled by the default code. 54 + 55 + The format of HID report descriptors is described by two documents, 56 + available from the `USB Implementers Forum <https://www.usb.org/>`_ 57 + `HID web page <https://www.usb.org/hid>`_ address: 58 + 59 + * the `HID USB Device Class Definition 60 + <https://www.usb.org/document-library/device-class-definition-hid-111>`_ (HID Spec from now on) 61 + * the `HID Usage Tables <https://usb.org/document-library/hid-usage-tables-14>`_ (HUT from now on) 62 + 63 + The HID subsystem can deal with different transport drivers 64 + (USB, I2C, Bluetooth, etc.). See Documentation/hid/hid-transport.rst. 65 + 66 + Parsing HID report descriptors 67 + ============================== 68 + 69 + The current list of HID devices can be found at ``/sys/bus/hid/devices/``. 70 + For each device, say ``/sys/bus/hid/devices/0003\:093A\:2510.0002/``, 71 + one can read the corresponding report descriptor:: 72 + 73 + $ hexdump -C /sys/bus/hid/devices/0003\:093A\:2510.0002/report_descriptor 74 + 00000000 05 01 09 02 a1 01 09 01 a1 00 05 09 19 01 29 03 |..............).| 75 + 00000010 15 00 25 01 75 01 95 03 81 02 75 05 95 01 81 01 |..%.u.....u.....| 76 + 00000020 05 01 09 30 09 31 09 38 15 81 25 7f 75 08 95 03 |...0.1.8..%.u...| 77 + 00000030 81 06 c0 c0 |....| 78 + 00000034 79 + 80 + Optional: the HID report descriptor can be read also by 81 + directly accessing the hidraw driver [#hidraw]_. 82 + 83 + The basic structure of HID report descriptors is defined in the HID 84 + spec, while HUT "defines constants that can be interpreted by an 85 + application to identify the purpose and meaning of a data field in a 86 + HID report". Each entry is defined by at least two bytes, where the 87 + first one defines what type of value is following and is described in 88 + the HID spec, while the second one carries the actual value and is 89 + described in the HUT. 90 + 91 + HID report descriptors can, in principle, be painstakingly parsed by 92 + hand, byte by byte. 93 + 94 + A short introduction on how to do this is sketched in 95 + Documentation/hid/hidreport-parsing.rst; you only need to understand it 96 + if you need to patch HID report descriptors. 97 + 98 + In practice you should not parse HID report descriptors by hand; rather, 99 + you should use an existing parser. Among all the available ones 100 + 101 + * the online `USB Descriptor and Request Parser 102 + <http://eleccelerator.com/usbdescreqparser/>`_; 103 + * `hidrdd <https://github.com/abend0c1/hidrdd>`_, 104 + that provides very detailed and somewhat verbose descriptions 105 + (verbosity can be useful if you are not familiar with HID report 106 + descriptors); 107 + * `hid-tools <https://gitlab.freedesktop.org/libevdev/hid-tools>`_, 108 + a complete utility set that allows, among other things, 109 + to record and replay the raw HID reports and to debug 110 + and replay HID devices. 111 + It is being actively developed by the Linux HID subsystem maintainers. 112 + 113 + Parsing the mouse HID report descriptor with `hid-tools 114 + <https://gitlab.freedesktop.org/libevdev/hid-tools>`_ leads to 115 + (explanations interposed):: 116 + 117 + $ ./hid-decode /sys/bus/hid/devices/0003\:093A\:2510.0002/report_descriptor 118 + # device 0:0 119 + # 0x05, 0x01, // Usage Page (Generic Desktop) 0 120 + # 0x09, 0x02, // Usage (Mouse) 2 121 + # 0xa1, 0x01, // Collection (Application) 4 122 + # 0x09, 0x01, // Usage (Pointer) 6 123 + # 0xa1, 0x00, // Collection (Physical) 8 124 + # 0x05, 0x09, // Usage Page (Button) 10 125 + 126 + what follows is a button :: 127 + 128 + # 0x19, 0x01, // Usage Minimum (1) 12 129 + # 0x29, 0x03, // Usage Maximum (3) 14 130 + 131 + first button is button number 1, last button is button number 3 :: 132 + 133 + # 0x15, 0x00, // Logical Minimum (0) 16 134 + # 0x25, 0x01, // Logical Maximum (1) 18 135 + 136 + each button can send values from 0 up to including 1 137 + (i.e. they are binary buttons) :: 138 + 139 + # 0x75, 0x01, // Report Size (1) 20 140 + 141 + each button is sent as exactly one bit :: 142 + 143 + # 0x95, 0x03, // Report Count (3) 22 144 + 145 + and there are three of those bits (matching the three buttons) :: 146 + 147 + # 0x81, 0x02, // Input (Data,Var,Abs) 24 148 + 149 + it's actual Data (not constant padding), they represent 150 + a single variable (Var) and their values are Absolute (not relative); 151 + See HID spec Sec. 6.2.2.5 "Input, Output, and Feature Items" :: 152 + 153 + # 0x75, 0x05, // Report Size (5) 26 154 + 155 + five additional padding bits, needed to reach a byte :: 156 + 157 + # 0x95, 0x01, // Report Count (1) 28 158 + 159 + those five bits are repeated only once :: 160 + 161 + # 0x81, 0x01, // Input (Cnst,Arr,Abs) 30 162 + 163 + and take Constant (Cnst) values i.e. they can be ignored. :: 164 + 165 + # 0x05, 0x01, // Usage Page (Generic Desktop) 32 166 + # 0x09, 0x30, // Usage (X) 34 167 + # 0x09, 0x31, // Usage (Y) 36 168 + # 0x09, 0x38, // Usage (Wheel) 38 169 + 170 + The mouse has also two physical positions (Usage (X), Usage (Y)) 171 + and a wheel (Usage (Wheel)) :: 172 + 173 + # 0x15, 0x81, // Logical Minimum (-127) 40 174 + # 0x25, 0x7f, // Logical Maximum (127) 42 175 + 176 + each of them can send values ranging from -127 up to including 127 :: 177 + 178 + # 0x75, 0x08, // Report Size (8) 44 179 + 180 + which is represented by eight bits :: 181 + 182 + # 0x95, 0x03, // Report Count (3) 46 183 + 184 + and there are three of those eight bits, matching X, Y and Wheel. :: 185 + 186 + # 0x81, 0x06, // Input (Data,Var,Rel) 48 187 + 188 + This time the data values are Relative (Rel), i.e. they represent 189 + the change from the previously sent report (event) :: 190 + 191 + # 0xc0, // End Collection 50 192 + # 0xc0, // End Collection 51 193 + # 194 + R: 52 05 01 09 02 a1 01 09 01 a1 00 05 09 19 01 29 03 15 00 25 01 75 01 95 03 81 02 75 05 95 01 81 01 05 01 09 30 09 31 09 38 15 81 25 7f 75 08 95 03 81 06 c0 c0 195 + N: device 0:0 196 + I: 3 0001 0001 197 + 198 + 199 + This Report Descriptor tells us that the mouse input will be 200 + transmitted using four bytes: the first one for the buttons (three 201 + bits used, five for padding), the last three for the mouse X, Y and 202 + wheel changes, respectively. 203 + 204 + Indeed, for any event, the mouse will send a *report* of four bytes. 205 + We can check the values sent by resorting e.g. to the `hid-recorder` 206 + tool, from `hid-tools <https://gitlab.freedesktop.org/libevdev/hid-tools>`_: 207 + The sequence of bytes sent by clicking and releasing button 1, then button 2, then button 3 is:: 208 + 209 + $ sudo ./hid-recorder /dev/hidraw1 210 + 211 + .... 212 + output of hid-decode 213 + .... 214 + 215 + # Button: 1 0 0 | # | X: 0 | Y: 0 | Wheel: 0 216 + E: 000000.000000 4 01 00 00 00 217 + # Button: 0 0 0 | # | X: 0 | Y: 0 | Wheel: 0 218 + E: 000000.183949 4 00 00 00 00 219 + # Button: 0 1 0 | # | X: 0 | Y: 0 | Wheel: 0 220 + E: 000001.959698 4 02 00 00 00 221 + # Button: 0 0 0 | # | X: 0 | Y: 0 | Wheel: 0 222 + E: 000002.103899 4 00 00 00 00 223 + # Button: 0 0 1 | # | X: 0 | Y: 0 | Wheel: 0 224 + E: 000004.855799 4 04 00 00 00 225 + # Button: 0 0 0 | # | X: 0 | Y: 0 | Wheel: 0 226 + E: 000005.103864 4 00 00 00 00 227 + 228 + This example shows that when button 2 is clicked, 229 + the bytes ``02 00 00 00`` are sent, and the immediately subsequent 230 + event (``00 00 00 00``) is the release of button 2 (no buttons are 231 + pressed, remember that the data values are *absolute*). 232 + 233 + If instead one clicks and holds button 1, then clicks and holds button 234 + 2, releases button 1, and finally releases button 2, the reports are:: 235 + 236 + # Button: 1 0 0 | # | X: 0 | Y: 0 | Wheel: 0 237 + E: 000044.175830 4 01 00 00 00 238 + # Button: 1 1 0 | # | X: 0 | Y: 0 | Wheel: 0 239 + E: 000045.975997 4 03 00 00 00 240 + # Button: 0 1 0 | # | X: 0 | Y: 0 | Wheel: 0 241 + E: 000047.407930 4 02 00 00 00 242 + # Button: 0 0 0 | # | X: 0 | Y: 0 | Wheel: 0 243 + E: 000049.199919 4 00 00 00 00 244 + 245 + where with ``03 00 00 00`` both buttons are pressed, and with the 246 + subsequent ``02 00 00 00`` button 1 is released while button 2 is still 247 + active. 248 + 249 + Output, Input and Feature Reports 250 + --------------------------------- 251 + 252 + HID devices can have Input Reports, like in the mouse example, Output 253 + Reports, and Feature Reports. "Output" means that the information is 254 + sent to the device. For example, a joystick with force feedback will 255 + have some output; the led of a keyboard would need an output as well. 256 + "Input" means that data come from the device. 257 + 258 + "Feature"s are not meant to be consumed by the end user and define 259 + configuration options for the device. They can be queried from the host; 260 + when declared as *Volatile* they should be changed by the host. 261 + 262 + 263 + Collections, Report IDs and Evdev events 264 + ======================================== 265 + 266 + A single device can logically group data into different independent 267 + sets, called a *Collection*. Collections can be nested and there are 268 + different types of collections (see the HID spec 6.2.2.6 269 + "Collection, End Collection Items" for details). 270 + 271 + Different reports are identified by means of different *Report ID* 272 + fields, i.e. a number identifying the structure of the immediately 273 + following report. 274 + Whenever a Report ID is needed it is transmitted as the first byte of 275 + any report. A device with only one supported HID report (like the mouse 276 + example above) may omit the report ID. 277 + 278 + Consider the following HID report descriptor:: 279 + 280 + 05 01 09 02 A1 01 85 01 05 09 19 01 29 05 15 00 281 + 25 01 95 05 75 01 81 02 95 01 75 03 81 01 05 01 282 + 09 30 09 31 16 00 F8 26 FF 07 75 0C 95 02 81 06 283 + 09 38 15 80 25 7F 75 08 95 01 81 06 05 0C 0A 38 284 + 02 15 80 25 7F 75 08 95 01 81 06 C0 05 01 09 02 285 + A1 01 85 02 05 09 19 01 29 05 15 00 25 01 95 05 286 + 75 01 81 02 95 01 75 03 81 01 05 01 09 30 09 31 287 + 16 00 F8 26 FF 07 75 0C 95 02 81 06 09 38 15 80 288 + 25 7F 75 08 95 01 81 06 05 0C 0A 38 02 15 80 25 289 + 7F 75 08 95 01 81 06 C0 05 01 09 07 A1 01 85 05 290 + 05 07 15 00 25 01 09 29 09 3E 09 4B 09 4E 09 E3 291 + 09 E8 09 E8 09 E8 75 01 95 08 81 02 95 00 81 01 292 + C0 05 0C 09 01 A1 01 85 06 15 00 25 01 75 01 95 293 + 01 09 3F 81 06 09 3F 81 06 09 3F 81 06 09 3F 81 294 + 06 09 3F 81 06 09 3F 81 06 09 3F 81 06 09 3F 81 295 + 06 C0 05 0C 09 01 A1 01 85 03 09 05 15 00 26 FF 296 + 00 75 08 95 02 B1 02 C0 297 + 298 + After parsing it (try to parse it on your own using the suggested 299 + tools!) one can see that the device presents two ``Mouse`` Application 300 + Collections (with reports identified by Reports IDs 1 and 2, 301 + respectively), a ``Keypad`` Application Collection (whose report is 302 + identified by the Report ID 5) and two ``Consumer Controls`` Application 303 + Collections, (with Report IDs 6 and 3, respectively). Note, however, 304 + that a device can have different Report IDs for the same Application 305 + Collection. 306 + 307 + The data sent will begin with the Report ID byte, and will be followed 308 + by the corresponding information. For example, the data transmitted for 309 + the last consumer control:: 310 + 311 + 0x05, 0x0C, // Usage Page (Consumer) 312 + 0x09, 0x01, // Usage (Consumer Control) 313 + 0xA1, 0x01, // Collection (Application) 314 + 0x85, 0x03, // Report ID (3) 315 + 0x09, 0x05, // Usage (Headphone) 316 + 0x15, 0x00, // Logical Minimum (0) 317 + 0x26, 0xFF, 0x00, // Logical Maximum (255) 318 + 0x75, 0x08, // Report Size (8) 319 + 0x95, 0x02, // Report Count (2) 320 + 0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 321 + 0xC0, // End Collection 322 + 323 + will be of three bytes: the first for the Report ID (3), the next two 324 + for the headphone, with two (``Report Count (2)``) bytes 325 + (``Report Size (8)``), each ranging from 0 (``Logical Minimum (0)``) 326 + to 255 (``Logical Maximum (255)``). 327 + 328 + All the Input data sent by the device should be translated into 329 + corresponding Evdev events, so that the remaining part of the stack can 330 + know what is going on, e.g. the bit for the first button translates into 331 + the ``EV_KEY/BTN_LEFT`` evdev event and relative X movement translates 332 + into the ``EV_REL/REL_X`` evdev event". 333 + 334 + Events 335 + ====== 336 + 337 + In Linux, one ``/dev/input/event*`` is created for each ``Application 338 + Collection``. Going back to the mouse example, and repeating the 339 + sequence where one clicks and holds button 1, then clicks and holds 340 + button 2, releases button 1, and finally releases button 2, one gets:: 341 + 342 + $ sudo libinput record /dev/input/event1 343 + # libinput record 344 + version: 1 345 + ndevices: 1 346 + libinput: 347 + version: "1.23.0" 348 + git: "unknown" 349 + system: 350 + os: "opensuse-tumbleweed:20230619" 351 + kernel: "6.3.7-1-default" 352 + dmi: "dmi:bvnHP:bvrU77Ver.01.05.00:bd03/24/2022:br5.0:efr20.29:svnHP:pnHPEliteBook64514inchG9NotebookPC:pvr:rvnHP:rn89D2:rvrKBCVersion14.1D.00:cvnHP:ct10:cvr:sku5Y3J1EA#ABZ:" 353 + devices: 354 + - node: /dev/input/event1 355 + evdev: 356 + # Name: PixArt HP USB Optical Mouse 357 + # ID: bus 0x3 vendor 0x3f0 product 0x94a version 0x111 358 + # Supported Events: 359 + # Event type 0 (EV_SYN) 360 + # Event type 1 (EV_KEY) 361 + # Event code 272 (BTN_LEFT) 362 + # Event code 273 (BTN_RIGHT) 363 + # Event code 274 (BTN_MIDDLE) 364 + # Event type 2 (EV_REL) 365 + # Event code 0 (REL_X) 366 + # Event code 1 (REL_Y) 367 + # Event code 8 (REL_WHEEL) 368 + # Event code 11 (REL_WHEEL_HI_RES) 369 + # Event type 4 (EV_MSC) 370 + # Event code 4 (MSC_SCAN) 371 + # Properties: 372 + name: "PixArt HP USB Optical Mouse" 373 + id: [3, 1008, 2378, 273] 374 + codes: 375 + 0: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] # EV_SYN 376 + 1: [272, 273, 274] # EV_KEY 377 + 2: [0, 1, 8, 11] # EV_REL 378 + 4: [4] # EV_MSC 379 + properties: [] 380 + hid: [ 381 + 0x05, 0x01, 0x09, 0x02, 0xa1, 0x01, 0x09, 0x01, 0xa1, 0x00, 0x05, 0x09, 0x19, 0x01, 0x29, 0x03, 382 + 0x15, 0x00, 0x25, 0x01, 0x95, 0x08, 0x75, 0x01, 0x81, 0x02, 0x05, 0x01, 0x09, 0x30, 0x09, 0x31, 383 + 0x09, 0x38, 0x15, 0x81, 0x25, 0x7f, 0x75, 0x08, 0x95, 0x03, 0x81, 0x06, 0xc0, 0xc0 384 + ] 385 + udev: 386 + properties: 387 + - ID_INPUT=1 388 + - ID_INPUT_MOUSE=1 389 + - LIBINPUT_DEVICE_GROUP=3/3f0/94a:usb-0000:05:00.3-2 390 + quirks: 391 + events: 392 + # Current time is 12:31:56 393 + - evdev: 394 + - [ 0, 0, 4, 4, 30] # EV_MSC / MSC_SCAN 30 (obfuscated) 395 + - [ 0, 0, 1, 272, 1] # EV_KEY / BTN_LEFT 1 396 + - [ 0, 0, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +0ms 397 + - evdev: 398 + - [ 1, 207892, 4, 4, 30] # EV_MSC / MSC_SCAN 30 (obfuscated) 399 + - [ 1, 207892, 1, 273, 1] # EV_KEY / BTN_RIGHT 1 400 + - [ 1, 207892, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +1207ms 401 + - evdev: 402 + - [ 2, 367823, 4, 4, 30] # EV_MSC / MSC_SCAN 30 (obfuscated) 403 + - [ 2, 367823, 1, 272, 0] # EV_KEY / BTN_LEFT 0 404 + - [ 2, 367823, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +1160ms 405 + # Current time is 12:32:00 406 + - evdev: 407 + - [ 3, 247617, 4, 4, 30] # EV_MSC / MSC_SCAN 30 (obfuscated) 408 + - [ 3, 247617, 1, 273, 0] # EV_KEY / BTN_RIGHT 0 409 + - [ 3, 247617, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +880ms 410 + 411 + Note: if ``libinput record`` is not available on your system try using 412 + ``evemu-record``. 413 + 414 + When something does not work 415 + ============================ 416 + 417 + There can be a number of reasons why a device does not behave 418 + correctly. For example 419 + 420 + * The HID report descriptor provided by the HID device may be wrong 421 + because e.g. 422 + 423 + * it does not follow the standard, so that the kernel 424 + will not able to make sense of the HID report descriptor; 425 + * the HID report descriptor *does not match* what is actually 426 + sent by the device (this can be verified by reading the raw HID 427 + data); 428 + * the HID report descriptor may need some "quirks" (see later on). 429 + 430 + As a consequence, a ``/dev/input/event*`` may not be created 431 + for each Application Collection, and/or the events 432 + there may not match what you would expect. 433 + 434 + 435 + Quirks 436 + ------ 437 + 438 + There are some known peculiarities of HID devices that the kernel 439 + knows how to fix - these are called the HID quirks and a list of those 440 + is available in `include/linux/hid.h`. 441 + 442 + Should this be the case, it should be enough to add the required quirk 443 + in the kernel, for the HID device at hand. This can be done in the file 444 + `drivers/hid/hid-quirks.c`. How to do it should be relatively 445 + straightforward after looking into the file. 446 + 447 + The list of currently defined quirks, from `include/linux/hid.h`, is 448 + 449 + .. kernel-doc:: include/linux/hid.h 450 + :doc: HID quirks 451 + 452 + Quirks for USB devices can be specified while loading the usbhid module, 453 + see ``modinfo usbhid``, although the proper fix should go into 454 + hid-quirks.c and **be submitted upstream**. 455 + See Documentation/process/submitting-patches.rst for guidelines on how 456 + to submit a patch. Quirks for other busses need to go into hid-quirks.c. 457 + 458 + Fixing HID report descriptors 459 + ----------------------------- 460 + 461 + Should you need to patch HID report descriptors the easiest way is to 462 + resort to eBPF, as described in Documentation/hid/hid-bpf.rst. 463 + 464 + Basically, you can change any byte of the original HID report 465 + descriptor. The examples in samples/hid should be a good starting point 466 + for your code, see e.g. `samples/hid/hid_mouse.bpf.c`:: 467 + 468 + SEC("fmod_ret/hid_bpf_rdesc_fixup") 469 + int BPF_PROG(hid_rdesc_fixup, struct hid_bpf_ctx *hctx) 470 + { 471 + .... 472 + data[39] = 0x31; 473 + data[41] = 0x30; 474 + return 0; 475 + } 476 + 477 + Of course this can be also done within the kernel source code, see e.g. 478 + `drivers/hid/hid-aureal.c` or `drivers/hid/hid-samsung.c` for a slightly 479 + more complex file. 480 + 481 + Check Documentation/hid/hidreport-parsing.rst if you need any help 482 + navigating the HID manuals and understanding the exact meaning of 483 + the HID report descriptor hex numbers. 484 + 485 + Whatever solution you come up with, please remember to **submit the 486 + fix to the HID maintainers**, so that it can be directly integrated in 487 + the kernel and that particular HID device will start working for 488 + everyone else. See Documentation/process/submitting-patches.rst for 489 + guidelines on how to do this. 490 + 491 + 492 + Modifying the transmitted data on the fly 493 + ----------------------------------------- 494 + 495 + Using eBPF it is also possible to modify the data exchanged with the 496 + device. See again the examples in `samples/hid`. 497 + 498 + Again, **please post your fix**, so that it can be integrated in the 499 + kernel! 500 + 501 + Writing a specialized driver 502 + ---------------------------- 503 + 504 + This should really be your last resort. 505 + 506 + 507 + .. rubric:: Footnotes 508 + 509 + .. [#hidraw] read hidraw: see Documentation/hid/hidraw.rst and 510 + file `samples/hidraw/hid-example.c` for an example. 511 + The output of ``hid-example`` would be, for the same mouse:: 512 + 513 + $ sudo ./hid-example 514 + Report Descriptor Size: 52 515 + Report Descriptor: 516 + 5 1 9 2 a1 1 9 1 a1 0 5 9 19 1 29 3 15 0 25 1 75 1 95 3 81 2 75 5 95 1 81 1 5 1 9 30 9 31 9 38 15 81 25 7f 75 8 95 3 81 6 c0 c0 517 + 518 + Raw Name: PixArt USB Optical Mouse 519 + Raw Phys: usb-0000:05:00.4-2.3/input0 520 + Raw Info: 521 + bustype: 3 (USB) 522 + vendor: 0x093a 523 + product: 0x2510 524 + ...
+49
Documentation/hid/hidreport-parsing.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + ======================================== 4 + Manual parsing of HID report descriptors 5 + ======================================== 6 + 7 + Consider again the mouse HID report descriptor 8 + introduced in Documentation/hid/hidintro.rst:: 9 + 10 + $ hexdump -C /sys/bus/hid/devices/0003\:093A\:2510.0002/report_descriptor 11 + 00000000 05 01 09 02 a1 01 09 01 a1 00 05 09 19 01 29 03 |..............).| 12 + 00000010 15 00 25 01 75 01 95 03 81 02 75 05 95 01 81 01 |..%.u.....u.....| 13 + 00000020 05 01 09 30 09 31 09 38 15 81 25 7f 75 08 95 03 |...0.1.8..%.u...| 14 + 00000030 81 06 c0 c0 |....| 15 + 00000034 16 + 17 + and try to parse it by hand. 18 + 19 + Start with the first number, 0x05: it carries 2 bits for the 20 + length of the item, 2 bits for the type of the item and 4 bits for the 21 + function:: 22 + 23 + +----------+ 24 + | 00000101 | 25 + +----------+ 26 + ^^ 27 + ---- Length of data (see HID spec 6.2.2.2) 28 + ^^ 29 + ------ Type of the item (see HID spec 6.2.2.2, then jump to 6.2.2.7) 30 + ^^^^ 31 + --------- Function of the item (see HID spec 6.2.2.7, then HUT Sec 3) 32 + 33 + In our case, the length is 1 byte, the type is ``Global`` and the 34 + function is ``Usage Page``, thus for parsing the value 0x01 in the second byte 35 + we need to refer to HUT Sec 3. 36 + 37 + The second number is the actual data, and its meaning can be found in 38 + the HUT. We have a ``Usage Page``, thus we need to refer to HUT 39 + Sec. 3, "Usage Pages"; from there, one sees that ``0x01`` stands for 40 + ``Generic Desktop Page``. 41 + 42 + Moving now to the second two bytes, and following the same scheme, 43 + ``0x09`` (i.e. ``00001001``) will be followed by one byte (``01``) 44 + and is a ``Local`` item (``10``). Thus, the meaning of the remaining four bits 45 + (``0000``) is given in the HID spec Sec. 6.2.2.8 "Local Items", so that 46 + we have a ``Usage``. From HUT, Sec. 4, "Generic Desktop Page", we see that 47 + 0x02 stands for ``Mouse``. 48 + 49 + The following numbers can be parsed in the same way.
+1
Documentation/hid/index.rst
··· 7 7 .. toctree:: 8 8 :maxdepth: 1 9 9 10 + hidintro 10 11 hiddev 11 12 hidraw 12 13 hid-sensor
+23
include/linux/hid.h
··· 341 341 */ 342 342 #define MAX_USBHID_BOOT_QUIRKS 4 343 343 344 + /** 345 + * DOC: HID quirks 346 + * | @HID_QUIRK_NOTOUCH: 347 + * | @HID_QUIRK_IGNORE: ignore this device 348 + * | @HID_QUIRK_NOGET: 349 + * | @HID_QUIRK_HIDDEV_FORCE: 350 + * | @HID_QUIRK_BADPAD: 351 + * | @HID_QUIRK_MULTI_INPUT: 352 + * | @HID_QUIRK_HIDINPUT_FORCE: 353 + * | @HID_QUIRK_ALWAYS_POLL: 354 + * | @HID_QUIRK_INPUT_PER_APP: 355 + * | @HID_QUIRK_X_INVERT: 356 + * | @HID_QUIRK_Y_INVERT: 357 + * | @HID_QUIRK_SKIP_OUTPUT_REPORTS: 358 + * | @HID_QUIRK_SKIP_OUTPUT_REPORT_ID: 359 + * | @HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP: 360 + * | @HID_QUIRK_HAVE_SPECIAL_DRIVER: 361 + * | @HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE: 362 + * | @HID_QUIRK_FULLSPEED_INTERVAL: 363 + * | @HID_QUIRK_NO_INIT_REPORTS: 364 + * | @HID_QUIRK_NO_IGNORE: 365 + * | @HID_QUIRK_NO_INPUT_SYNC: 366 + */ 344 367 /* BIT(0) reserved for backward compatibility, was HID_QUIRK_INVERT */ 345 368 #define HID_QUIRK_NOTOUCH BIT(1) 346 369 #define HID_QUIRK_IGNORE BIT(2)