2

Question

Is there any way to programmatically negotiate and enable NKRO (N-Key Rollover) for plugged keyboards when that feature is available? Also, how to properly distinguish between "standard mode" handler and NKRO?

Rationale

I do have three different keyboards that behave slightly differently from each other and even between platforms. All of them support NKRO in their own way. My main problem is that one of these doesn't have any key combination to enforce/switch NKRO mode, it only can be done by the driver/OS.

Tests

I played with my keyboards on Windows 10 and Linux 5.10.17+ (Pi Zero) platforms. My devices are Razer Ornata Chroma, HyperX HX-KB1BR1-NA and Havit HV-KB390L. I think I can put some behavior descriptions of that devices here.

By standard mode I'm referring to a low-speed 8-byte sized USB packet, which is commonly used. By game-mode I'm referring to a keyboard-specific feature if available.

Windows
- Razer: NKRO enabled by default regardless of game-mode state, game-mode only disables Win key,
         game-mode state stored only by platform driver
         (Razer Central installed)
- Havit: NKRO enabled by default, game-mode does nothing (probably configured via software)
         (no additional software installed)
- HyperX: stores NKRO state internally in keyboard and enforces it, game-mode disables Win key only
          (no additional software installed)
Linux
- Razer: standard mode by default, game-mode enforces NKRO and disables Win key
- Havit: standard mode by default, game-mode does nothing, There is no key sequence to enforce NKRO
- HyperX: behaves the same as on Windows, internal state changes works between platforms

So with that, HyperX implementation of standard mode/NKRO switching is the most favored by me, Razer at least provides a key combination to enforce NKRO (needed to do on every connection/bootup though), Havit unfortunately doesn't give an option to enable NKRO through any key combination.

I looked into Linux source code and documentation - /drivers/input, /Documentation/input, /drivers/hid/hid-input.c, but I didn't find anything that would help me to enforce NKRO, also understanding C code is not the easiest task for me. The only thing I found that mentions NKRO is this line:

#define HP_SDC_CFG_ROLLOVER 0x08 /* WTF is "N-key rollover"? */

Well, it is not really helpful.

So, is it possible to enable NKRO from the OS side?

Differentiate standard and NKRO handlers

During my tests, I found out that these two different modes relate to two different eventX handlers. We can inspect /proc/bus/input/devices file and find some more context.

I: Bus=0003 Vendor=0951 Product=16b7 Version=0111
N: Name="Kingston HyperX Alloy FPS Mechanical Gaming Keyboard"
P: Phys=usb-20980000.usb-1.1/input0
S: Sysfs=/devices/platform/soc/20980000.usb/usb1/1-1/1-1.1/1-1.1:1.0/0003:0951:16B7.0001/input/input0
U: Uniq=
H: Handlers=sysrq kbd leds event0
B: PROP=0
B: EV=120013
B: KEY=10000 7 ff9f207a c14057ff febeffdf ffefffff ffffffff fffffffe
B: MSC=10
B: LED=1f

I: Bus=0003 Vendor=0951 Product=16b7 Version=0111
N: Name="Kingston HyperX Alloy FPS Mechanical Gaming Keyboard Mouse"
P: Phys=usb-20980000.usb-1.1/input1
S: Sysfs=/devices/platform/soc/20980000.usb/usb1/1-1/1-1.1/1-1.1:1.1/0003:0951:16B7.0002/input/input1
U: Uniq=
H: Handlers=mouse0 event1
B: PROP=0
B: EV=17
B: KEY=1f0000 0 0 0 0 0 0 0 0
B: REL=1943
B: MSC=10

I: Bus=0003 Vendor=0951 Product=16b7 Version=0111
N: Name="Kingston HyperX Alloy FPS Mechanical Gaming Keyboard System Control"
P: Phys=usb-20980000.usb-1.1/input1
S: Sysfs=/devices/platform/soc/20980000.usb/usb1/1-1/1-1.1/1-1.1:1.1/0003:0951:16B7.0002/input/input2
U: Uniq=
H: Handlers=kbd event2
B: PROP=0
B: EV=13
B: KEY=c000 100000 0 0 0
B: MSC=10

I: Bus=0003 Vendor=0951 Product=16b7 Version=0111
N: Name="Kingston HyperX Alloy FPS Mechanical Gaming Keyboard Consumer Control"
P: Phys=usb-20980000.usb-1.1/input1
S: Sysfs=/devices/platform/soc/20980000.usb/usb1/1-1/1-1.1/1-1.1:1.1/0003:0951:16B7.0002/input/input3
U: Uniq=
H: Handlers=kbd event3
B: PROP=0
B: EV=1f
B: KEY=3f 301ff 0 0 0 0 483ffff 17aff32d bfd44446 0 0 1 130ff3 8b17c000 677bfa d9415fed 19ed680 4400 0 10000002
B: REL=1040
B: ABS=1 0
B: MSC=10

I: Bus=0003 Vendor=0951 Product=16b7 Version=0111
N: Name="Kingston HyperX Alloy FPS Mechanical Gaming Keyboard"
P: Phys=usb-20980000.usb-1.1/input1
S: Sysfs=/devices/platform/soc/20980000.usb/usb1/1-1/1-1.1/1-1.1:1.1/0003:0951:16B7.0002/input/input5
U: Uniq=
H: Handlers=sysrq kbd event4
B: PROP=0
B: EV=100013
B: KEY=10000 7 ff9f207a c14057ff febeffdf ffefffff ffffffff fffffffe
B: MSC=10

That file format is explained well here

In the HyperX case, there are five different handlers available (can be more/less in others):

  1. handler for keyboard events, standard mode
  2. mouse handler (e.g. remote USB keyboard witch touchpad). I'm assuming it is always there by design
  3. just by referring to its name "System Control", it provides events for power, sleep, etc.
  4. referring to "Consumer Control", it provides events for multimedia and related special keys
  5. handler for NKRO events

I can find the "standard mode" keyboard handler easily by looking for EV=120013 (I'm not sure if it is a proper way either). In that particular case I could look for other entries with an identical bitmap of supported keys, but unfortunately in Havit case that bitmap is pretty different. Another pattern that I see and might be useful is to look for sysrq in handlers, However, I don't know what it means.

And that's it.

How can I properly find both standard mode and NKRO handlers for given keyboard?

1

0

You must log in to answer this question.

Browse other questions tagged .