Search code examples
clinux-kernelusblinux-device-driverhid

hid report descriptor: wrong padding


i have a device that has the following hid report descriptor:

Collection (Logical) A1 02 

Usage Page (Physical Input Device) 05

Usage (DC Enable Actuators) 09 97  
Logical Minimum (0) 15 00  
Logical Maximum (1) 25 01  
Report Size (4) 75 04  
Report Count (1) 95 01  
Output (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 02

Logical Minimum (0) 15 00  
Logical Maximum (0) 25 00  
Output (Cnst,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 03  

Usage (Magnitude) 09 70  
Logical Minimum (0) 15 00  
Logical Maximum (100) 25 64  
Report Size (8) 75 08  
Report Count (4) 95 04  
Output (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 02  

...

End Collection C0

I would therefore think that the device expects data in the following manner:

8 Bits: Report ID, 4 Bits: DC Enable Actuators, 4 Bits: Padding, 32 Bits: Magnitude

Hence, my driver code in linux would look something like that:

...
static const u8 buf[] =  {0x03, 0b00010000, 0x00, 0x00, 0x60, 0x60, 10, 0x00, 10};
hid_hw_output_report(hid, buf, 9);
...

Unfortunately that's not what the device expects! In fact it does only react if the data is structured like:

8 Bits: Report ID, 4 Bits: Padding, 4 Bits: DC Enable Actuators, 32 Bits: Magnitude

Which is:

...
static const u8 buf[] =  {0x03, 0b00000001, 0x00, 0x00, 0x60, 0x60, 10, 0x00, 10};
hid_hw_output_report(hid, buf, 9);
...

That means the padding comes before the DC Enable Actuators field, not after.

Does anyone understand why these two fields are switched?

Thank you in advance!


Solution

  • I think you're confused about how binary literals work. In your first example 0b00010000 represents 0x10, or 16 in decimal. In your second example 0b00000001 represents 0x01, or 1 in decimal. The bits increase in significance from right to left, just like the digits in hex or decimal. Thus 0b00010000 represents four bits of padding (0b0000) followed by the DC enable actuators field (0b0001) which is not the correct format for this HID report. Your second example shows the correct order (0b00000001), with the DC enable actuators field (the lowest 4 bits, on the right) followed by 4 bits of padding (the highest 4 bits, on the left).