summaryrefslogtreecommitdiff
path: root/drivers/hid/hid-topre.c
diff options
context:
space:
mode:
authorHarry Stern <harry@harrystern.net>2022-09-11 03:36:13 +0300
committerBenjamin Tissoires <benjamin.tissoires@redhat.com>2022-09-20 14:16:25 +0300
commita109d5c45b3d6728b9430716b915afbe16eef27c (patch)
treed17e024db9f3c8c9386b2c1154da94e71c48936f /drivers/hid/hid-topre.c
parenta1f764268f3390406f4dcbe3d2f537f2424f22ca (diff)
downloadlinux-a109d5c45b3d6728b9430716b915afbe16eef27c.tar.xz
hid: topre: Add driver fixing report descriptor
The Topre REALFORCE R2 firmware incorrectly reports that interface descriptor number 1, input report descriptor 2's events are array events rather than variable events. That particular report descriptor is used to report keypresses when there are more than 6 keys held at a time. This bug prevents events from this interface from being registered properly, so only 6 keypresses (from a different interface) can be registered at once, rather than full n-key rollover. This commit fixes the bug by setting the correct value in a report_fixup function. The original bug report can be found here: Link: https://gitlab.freedesktop.org/libinput/libinput/-/issues/804 Thanks to Benjamin Tissoires for diagnosing the issue with the report descriptor. Signed-off-by: Harry Stern <harry@harrystern.net> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Link: https://lore.kernel.org/r/20220911003614.297613-1-harry@harrystern.net
Diffstat (limited to 'drivers/hid/hid-topre.c')
-rw-r--r--drivers/hid/hid-topre.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/drivers/hid/hid-topre.c b/drivers/hid/hid-topre.c
new file mode 100644
index 000000000000..88a91cdad5f8
--- /dev/null
+++ b/drivers/hid/hid-topre.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * HID driver for Topre REALFORCE Keyboards
+ *
+ * Copyright (c) 2022 Harry Stern <harry@harrystern.net>
+ *
+ * Based on the hid-macally driver
+ */
+
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+MODULE_AUTHOR("Harry Stern <harry@harrystern.net>");
+MODULE_DESCRIPTION("REALFORCE R2 Keyboard driver");
+MODULE_LICENSE("GPL");
+
+/*
+ * Fix the REALFORCE R2's non-boot interface's report descriptor to match the
+ * events it's actually sending. It claims to send array events but is instead
+ * sending variable events.
+ */
+static __u8 *topre_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int *rsize)
+{
+ if (*rsize >= 119 && rdesc[69] == 0x29 && rdesc[70] == 0xe7 &&
+ rdesc[71] == 0x81 && rdesc[72] == 0x00) {
+ hid_info(hdev,
+ "fixing up Topre REALFORCE keyboard report descriptor\n");
+ rdesc[72] = 0x02;
+ }
+ return rdesc;
+}
+
+static const struct hid_device_id topre_id_table[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_TOPRE,
+ USB_DEVICE_ID_TOPRE_REALFORCE_R2_108) },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, topre_id_table);
+
+static struct hid_driver topre_driver = {
+ .name = "topre",
+ .id_table = topre_id_table,
+ .report_fixup = topre_report_fixup,
+};
+
+module_hid_driver(topre_driver);