Martin Pieuchot <m...@openbsd.org> on Wed, Sep 21 2016:
> Can you do that without adding a new quirk?

Yes, but I guess then there would have to be a check for this particular
product in the generic driver path?

> Is this way of reporting extra buttons standard or is it a vendor-only
> feature?

It's certainly not standard in the sense of the USB HID spec being the
standard. Whether it is a de-facto standard by any measure is a good
question that I don't know a definitive answer to. A cursory search of
Linux's HID driver directory turned up no other matches.

https://github.com/torvalds/linux/search?utf8=%E2%9C%93&q=MSVENDOR

> Where did you get the documentation from?

This was "reverse engineered", if you can call it that. I looked at the
output of usbhidctl -r, augmented the tool to dump the raw descriptor,
and verified with the HID spec that it parsed everything correctly. Put
it in the kernel and it worked.

I then cross-checked how Linux handles things and it does essentially
the same: treat these extra inputs in the "Microsoft" page as buttons.

Cf:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=fdf93aa33268889e126aa677f2072238bd76adb0
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/hid/hid-kensington.c

>>--pesco
>> (sending from off-list)


PS: This is the report descriptor with my manual analysis, for reference:

report ID=0
Report descriptor:
Collection page=Generic_Desktop usage=Mouse (1:0x2)
Collection page=Generic_Desktop usage=Pointer (1:0x1)
Input   size=1 count=1 page=Button usage=Button_1 (9:0x1), logical range 0..1
Input   size=1 count=1 page=Button usage=Button_2 (9:0x2), logical range 0..1
Input   size=6 count=1 Const page=0x0000 usage=0x0000 (0:0x0), logical range 
0..1
Input   size=8 count=1 page=Generic_Desktop usage=X (1:0x30), logical range 
-127..127
Input   size=8 count=1 page=Generic_Desktop usage=Y (1:0x31), logical range 
-127..127
Input   size=8 count=1 page=Generic_Desktop usage=Wheel (1:0x38), logical range 
-127..127
Input   size=1 count=1 page=Microsoft usage=0x0001 (65280:0x1), logical range 
0..1
Input   size=1 count=1 page=Microsoft usage=0x0002 (65280:0x2), logical range 
0..1
Input   size=6 count=1 Const page=0x0000 usage=0x0000 (0:0x0), logical range 
0..1
End collection
End collection
Total   input size 5 bytes
Total  output size 0 bytes
Total feature size 0 bytes


-----
raw descriptor:

// small item format:
// 4 bit tag
// 2 bit type (main, global, local, ?)
// 2 bit size (0, 1, 2, 4)
// data

05 01
  type 1 (global), tag 0: set usage page to 1 (generic desktop)
09 02
  type 2 (local), tag 0: add usage 2 (mouse)
a1 01
  type 0 (main), tag 10: open collection 1 (application)
09 01
  type 2 (local), tag 0: add usage 1 (pointer)
a1 00
  type 0 (main), tag 10: open collection 0 (physical)
05 09
  type 1 (global), tag 0: set usage page to 9 (button)
19 01
  type 2 (local), tag 1: set usage minimum to 1
29 02
  type 2 (local), tag 2: set usage maximum to 2, adds usages 1-2
15 00
  type 1 (global), tag 1: set logical minimum to 0
25 01
  type 1 (global), tag 2: set logical maximum to 1
95 02
  type 1 (global), tag 9: set loc_count to 2
75 01
  type 1 (global), tag 7: set loc_size to 1
81 02
  type 0 (main), tag 8: input, flags=2 (VARIABLE)
95 01
  type 1 (global), tag 9: set loc_count to 1
75 06
  type 1 (global), tag 7: set loc_size to 6
81 03
  type 0 (main), tag 8: input, flags=2+1 (VARIABLE,CONST)
05 01
  type 1 (global), tag 0: set usage page to 1 (generic desktop)
09 30
  type 2 (local), tag 0: add usage 48 (X)
09 31
  type 2 (local), tag 0: add usage 49 (Y)
09 38
  type 2 (local), tag 0: add usage 56 (wheel)
15 81
  type 1 (global), tag 1: set logical minimum to -127
25 7f
  type 1 (global), tag 2: set logical maximum to 127
75 08
  type 1 (global), tag 7: set loc_size to 8
95 03
  type 1 (global), tag 9: set loc_count to 3
81 06
  type 0 (main), tag 8: add as inputs, flags=4+2 (RELATIVE,VARIABLE)
06 00 ff
  type 1 (global), tag 0: set usage page to 65280 (microsoft)
19 01
  type 2 (local), tag 1: set usage minimum to 1
29 02
  type 2 (local), tag 2: set usage maximum to 2, adds usages 1-2
15 00
  type 1 (global), tag 1: set logical minimum to 0
25 01
  type 1 (global), tag 2: set logical maximum to 1
95 02
  type 1 (global), tag 9: set loc_count to 2
75 01
  type 1 (global), tag 7: set loc_size to 1
81 02
  type 0 (main), tag 8: add as inputs, flags=2 (VARIABLE)
95 01
  type 1 (global), tag 9: set loc_count to 1
75 06
  type 1 (global), tag 7: set loc_size to 6
81 03
  type 0 (main), tag 8: add as inputs, flags=2+1 (VARIABLE,CONST)
c0
  type 0 (main), tag 12: end collection (0)
c0
  type 0 (main), tag 12: end collection (1)

Reply via email to