Download raw body.
uhidev fix for set report output command
When I was trying to add LED support for ikbd(4), I noticed that the set
report output command in ihidev isn't working as expected, so my caps
lock LED never got lit. While checking with kettenis@ on that topic,
he reported that he faced the same issue back then when trying to add
LED support to ikbd(4), and he is suspecting an issue in the ihidev set
report command.
After investigating further, it turned out that when we use the
wOutputRegister for the set report output command, the wCommandRegister
block needs to be omitted. There is a clear statement in the Linux
driver about it:
https://github.com/torvalds/linux/blob/master/drivers/hid/i2c-hid/i2c-hid-core.c#L372
With the following patch, and the ikbd LED extension (which I would
share once this got fixed), I can control the caps lock LED on my Samsung
laptop. I allowed myself to add some comment, since this isn't so
obvious to grasp, and not very well documented in the hid-over-i2c specs
IMO.
I couldn't find any other driver which uses the I2C_HID_REPORT_TYPE_OUTPUT
set report command yet. Probably the reason why this kept undiscovered
until now.
Feedback, OKs?
Index: sys/dev/i2c/ihidev.c
===================================================================
RCS file: /cvs/src/sys/dev/i2c/ihidev.c,v
diff -u -p -u -p -r1.35 ihidev.c
--- sys/dev/i2c/ihidev.c 6 Jan 2025 02:13:55 -0000 1.35
+++ sys/dev/i2c/ihidev.c 6 Jan 2025 20:40:39 -0000
@@ -453,6 +453,22 @@ ihidev_hid_command(struct ihidev_softc *
cmd[dataoff++] = htole16(sc->hid_desc.wDataRegister)
>> 8;
} else {
+ /*
+ * When using the wOutputRegister for a set report
+ * output command, the wCommandRegister command needs
+ * to be omitted, and we write the report data straight
+ * in to the wOutputRegister:
+ *
+ * cmd[0] = wOutputRegister (LSB)
+ * cmd[1] = wOutputRegister (MSB)
+ * cmd[2] = Length Field (LSB)
+ * cmd[3] = Length Field (MSB)
+ * cmd[4] = Report ID
+ * cmd[5] = DATA
+ * ...
+ */
+ cmdlen = 5;
+ dataoff = 0;
cmd[dataoff++] = htole16(sc->hid_desc.wOutputRegister)
& 0xff;
cmd[dataoff++] = htole16(sc->hid_desc.wOutputRegister)
uhidev fix for set report output command