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