NKRO on Topre Realforce R2 keyboard
Summary
My keyboard supports N-key rollover, that is, it should support more than 6 keys being pressed at a time. Indeed it does: if you hold down 1-6 with your thumb on your left hand and then press Fn+F1, a seventh event (a media key) gets reported. However, pressing more than 6 "regular" keys at a time does not work.
The 7th+ keys appear when inspecting the raw HID interface in /dev/hidraw5 (see line 119 in nkro_hid.txt) but do not appear from the libinput side.
Steps to reproduce
Press more than 6 keys at once and notice only the first 6 pressed get events.
Required information
- libinput version: 1.21.0-1
- hardware information: Topre Realforce R2 PFU Limited Edition
attached are the outputs of:
nkro_libinput.yml libinput record --multiple --output-file=nkro_libinput.yml /dev/input/event{2,6,7}
nkro_hid.txt hid-recorder /dev/hidraw{4,5} > nkro_hid.txt
device_info.txt containing lsusb -vvv
and udevadm info
report_descriptors.txt omitted from lsusb
More details
It appears (see device_info.txt) that there are 3 hid interfaces provided by the device according to lsusb (see attached device_info.txt). Presumably this is a way to be bios compatible with older BIOSes or something.
The boot interface keyboard (/dev/input/event2) comes from hidraw4 and provides 6 regular key inputs, and the "secondary" ones (/dev/input/event{6,7}) come from hidraw5 and provides both "extra"/media keys (like fn+f1 -> XF86HomePage) and also appear to be attempting to provide nkro/overflow keys.
That is, when running hid-recorder on hidraw5, pressing the first 6 keys does nothing, and then events show up for any further pressed keys (and media keys always), whereas the reverse happens on hidraw4: the first 6 events show up but further events don't.
However, the 7th+ inputs (from hidraw4) only show up in hid-recorder and not libinput record. This is where I'm not sure if the mapping has to take place in a hid kernel driver or if it can be done in libinput - it seems like it might have to be at the hid event level. I'm also not sure why both event6 and event7 map to the same hidraw interface. I'm guessing since the third interface described (bInterfaceNumber 2
in lsusb) has both input and output endpoint descriptors that it's used by the realforce software to configure settings via software.
Here's the most interesting lines from the output of hid-recorder, showing what happens when the keys 12345678 are held down simultaneously:
D: 0
<snip: events 1-5 being pressed>
E: 000000.652216 8 00 00 1e 1f 20 21 22 00
# LeftControl: 0 | LeftShift: 0 | LeftAlt: 0 | Left GUI: 0 | RightControl: 0 | RightShift: 0 | RightAlt: 0 | Right GUI: 0 | # |Keyboard ['1 and !', '2 and @',
'3 and #', '4 and $', '5 and %', '6 and ^']
E: 000000.715064 8 00 00 1e 1f 20 21 22 23
D: 1
# ReportID: 2 / # /Keyboard ['00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', 'ErrorRollOver', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00']
E: 000000.780853 31 02 00 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
# ReportID: 2 / # /Keyboard ['00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', 'ErrorRollOver', 'ErrorRollOver', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00', '00']
The ReportID: 2 lines have 232 entries in the arrays. the ErrorRollOver entries are in position 36 and 37 - ErrorRollOver is 0x01 in the HID Usage Table, and coincidentally 36 and 37 (0x24,25) correspond to 'Keyboard 7 and &' and 'Keyboard 8 and *' in the HID Usage Table.