diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 6ce92830b5d1..c4308d4988dc 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -1141,6 +1141,12 @@ config HID_TOPSEED Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic CLLRCMCE remote control. +config HID_TOPRE + tristate "Topre REALFORCE keyboards" + depends on HID + help + Say Y for N-key rollover support on Topre REALFORCE R2 108 key keyboards. + config HID_THINGM tristate "ThingM blink(1) USB RGB LED" depends on HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index b0bef8098139..bccaec0d77d3 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -123,6 +123,7 @@ obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o hid-thrustmaster.o obj-$(CONFIG_HID_TIVO) += hid-tivo.o obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o +obj-$(CONFIG_HID_TOPRE) += hid-topre.o obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o obj-$(CONFIG_HID_U2FZERO) += hid-u2fzero.o hid-uclogic-objs := hid-uclogic-core.o \ diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index f80d6193fca6..50bab12d9476 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -1231,6 +1231,9 @@ #define USB_DEVICE_ID_TIVO_SLIDE 0x1201 #define USB_DEVICE_ID_TIVO_SLIDE_PRO 0x1203 +#define USB_VENDOR_ID_TOPRE 0x0853 +#define USB_DEVICE_ID_TOPRE_REALFORCE_R2_108 0x0148 + #define USB_VENDOR_ID_TOPSEED 0x0766 #define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204 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 + * + * Based on the hid-macally driver + */ + +#include +#include + +#include "hid-ids.h" + +MODULE_AUTHOR("Harry Stern "); +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);