Skip to content

Commit a109d5c

Browse files
boustrophedonbentiss
authored andcommitted
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 <[email protected]> Signed-off-by: Benjamin Tissoires <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent a1f7642 commit a109d5c

File tree

4 files changed

+59
-0
lines changed

4 files changed

+59
-0
lines changed

drivers/hid/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,6 +1141,12 @@ config HID_TOPSEED
11411141
Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic
11421142
CLLRCMCE remote control.
11431143

1144+
config HID_TOPRE
1145+
tristate "Topre REALFORCE keyboards"
1146+
depends on HID
1147+
help
1148+
Say Y for N-key rollover support on Topre REALFORCE R2 108 key keyboards.
1149+
11441150
config HID_THINGM
11451151
tristate "ThingM blink(1) USB RGB LED"
11461152
depends on HID

drivers/hid/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o
123123
obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o hid-thrustmaster.o
124124
obj-$(CONFIG_HID_TIVO) += hid-tivo.o
125125
obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o
126+
obj-$(CONFIG_HID_TOPRE) += hid-topre.o
126127
obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o
127128
obj-$(CONFIG_HID_U2FZERO) += hid-u2fzero.o
128129
hid-uclogic-objs := hid-uclogic-core.o \

drivers/hid/hid-ids.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,6 +1231,9 @@
12311231
#define USB_DEVICE_ID_TIVO_SLIDE 0x1201
12321232
#define USB_DEVICE_ID_TIVO_SLIDE_PRO 0x1203
12331233

1234+
#define USB_VENDOR_ID_TOPRE 0x0853
1235+
#define USB_DEVICE_ID_TOPRE_REALFORCE_R2_108 0x0148
1236+
12341237
#define USB_VENDOR_ID_TOPSEED 0x0766
12351238
#define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204
12361239

drivers/hid/hid-topre.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// SPDX-License-Identifier: GPL-2.0+
2+
/*
3+
* HID driver for Topre REALFORCE Keyboards
4+
*
5+
* Copyright (c) 2022 Harry Stern <[email protected]>
6+
*
7+
* Based on the hid-macally driver
8+
*/
9+
10+
#include <linux/hid.h>
11+
#include <linux/module.h>
12+
13+
#include "hid-ids.h"
14+
15+
MODULE_AUTHOR("Harry Stern <[email protected]>");
16+
MODULE_DESCRIPTION("REALFORCE R2 Keyboard driver");
17+
MODULE_LICENSE("GPL");
18+
19+
/*
20+
* Fix the REALFORCE R2's non-boot interface's report descriptor to match the
21+
* events it's actually sending. It claims to send array events but is instead
22+
* sending variable events.
23+
*/
24+
static __u8 *topre_report_fixup(struct hid_device *hdev, __u8 *rdesc,
25+
unsigned int *rsize)
26+
{
27+
if (*rsize >= 119 && rdesc[69] == 0x29 && rdesc[70] == 0xe7 &&
28+
rdesc[71] == 0x81 && rdesc[72] == 0x00) {
29+
hid_info(hdev,
30+
"fixing up Topre REALFORCE keyboard report descriptor\n");
31+
rdesc[72] = 0x02;
32+
}
33+
return rdesc;
34+
}
35+
36+
static const struct hid_device_id topre_id_table[] = {
37+
{ HID_USB_DEVICE(USB_VENDOR_ID_TOPRE,
38+
USB_DEVICE_ID_TOPRE_REALFORCE_R2_108) },
39+
{ }
40+
};
41+
MODULE_DEVICE_TABLE(hid, topre_id_table);
42+
43+
static struct hid_driver topre_driver = {
44+
.name = "topre",
45+
.id_table = topre_id_table,
46+
.report_fixup = topre_report_fixup,
47+
};
48+
49+
module_hid_driver(topre_driver);

0 commit comments

Comments
 (0)