linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] HID: semitek: new driver for GK6X series keyboards
@ 2021-02-07 18:47 Benjamin Moody
  2021-05-05 12:21 ` Jiri Kosina
  0 siblings, 1 reply; 2+ messages in thread
From: Benjamin Moody @ 2021-02-07 18:47 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires, linux-input; +Cc: linux-kernel, Benjamin Moody

From: Benjamin Moody <bmoody@member.fsf.org>

A number of USB keyboards, using the Semitek firmware, are capable of
handling arbitrary N-key rollover, but due to a buggy report
descriptor, keys beyond the sixth cannot be detected by the generic
HID driver.

There are numerous hardware variants sold by several vendors, mostly
using generic names like "GK61" for the 61-key version.  These
keyboards are sometimes known collectively as the "GK6X" series.

The keyboard has three USB interfaces.  Interface 0 uses the standard
HID boot protocol, limited to eight modifier keys and six normal keys;
interface 2 uses a custom report format that permits any number of
keys.  If more than six keys are pressed simultaneously, the first six
are reported via interface 0 while subsequent keys are reported via
interface 2.

(Interface 1 uses a custom protocol for reprogramming the keyboard;
this can be controlled through userspace tools and is not of concern
for the present driver.)

The report descriptor for interface 2, however, is incorrect (for
report ID 0x04, the input field is marked as "array" rather than
"variable".)  The descriptor appears to be correct in other respects,
so we simply replace the incorrect byte before parsing the descriptor.

Signed-off-by: Benjamin Moody <bmoody@member.fsf.org>
---
 drivers/hid/Kconfig       | 15 +++++++++++++++
 drivers/hid/Makefile      |  1 +
 drivers/hid/hid-ids.h     |  3 +++
 drivers/hid/hid-semitek.c | 40 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 59 insertions(+)
 create mode 100644 drivers/hid/hid-semitek.c

diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 09fa75a2b..06131a79d 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -893,6 +893,21 @@ config HID_SAMSUNG
 	help
 	Support for Samsung InfraRed remote control or keyboards.
 
+config HID_SEMITEK
+	tristate "Semitek USB keyboards"
+	depends on HID
+	help
+	Support for Semitek USB keyboards that are not fully compliant
+	with the HID standard.
+
+	There are many variants, including:
+	- GK61, GK64, GK68, GK84, GK96, etc.
+	- SK61, SK64, SK68, SK84, SK96, etc.
+	- Dierya DK61/DK66
+	- Tronsmart TK09R
+	- Woo-dy
+	- X-Bows Nature/Knight
+
 config HID_SONY
 	tristate "Sony PS2/3/4 accessories"
 	depends on USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 014d21fe7..1c02f551e 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -104,6 +104,7 @@ obj-$(CONFIG_HID_ROCCAT)	+= hid-roccat.o hid-roccat-common.o \
 obj-$(CONFIG_HID_RMI)		+= hid-rmi.o
 obj-$(CONFIG_HID_SAITEK)	+= hid-saitek.o
 obj-$(CONFIG_HID_SAMSUNG)	+= hid-samsung.o
+obj-$(CONFIG_HID_SEMITEK)	+= hid-semitek.o
 obj-$(CONFIG_HID_SMARTJOYPLUS)	+= hid-sjoy.o
 obj-$(CONFIG_HID_SONY)		+= hid-sony.o
 obj-$(CONFIG_HID_SPEEDLINK)	+= hid-speedlink.o
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 5ba0aa1d2..def7626d0 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -1041,6 +1041,9 @@
 #define USB_DEVICE_ID_SEMICO_USB_KEYKOARD	0x0023
 #define USB_DEVICE_ID_SEMICO_USB_KEYKOARD2	0x0027
 
+#define USB_VENDOR_ID_SEMITEK	0x1ea7
+#define USB_DEVICE_ID_SEMITEK_KEYBOARD	0x0907
+
 #define USB_VENDOR_ID_SENNHEISER	0x1395
 #define USB_DEVICE_ID_SENNHEISER_BTD500USB	0x002c
 
diff --git a/drivers/hid/hid-semitek.c b/drivers/hid/hid-semitek.c
new file mode 100644
index 000000000..ba6607d5e
--- /dev/null
+++ b/drivers/hid/hid-semitek.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *  HID driver for Semitek keyboards
+ *
+ *  Copyright (c) 2021 Benjamin Moody
+ */
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+static __u8 *semitek_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+                                  unsigned int *rsize)
+{
+	/* In the report descriptor for interface 2, fix the incorrect
+	   description of report ID 0x04 (the report contains a
+	   bitmask, not an array of keycodes.) */
+	if (*rsize == 0xcb && rdesc[0x83] == 0x81 && rdesc[0x84] == 0x00) {
+		hid_info(hdev, "fixing up Semitek report descriptor\n");
+		rdesc[0x84] = 0x02;
+	}
+	return rdesc;
+}
+
+static const struct hid_device_id semitek_devices[] = {
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SEMITEK, USB_DEVICE_ID_SEMITEK_KEYBOARD) },
+	{ }
+};
+MODULE_DEVICE_TABLE(hid, semitek_devices);
+
+static struct hid_driver semitek_driver = {
+	.name = "semitek",
+	.id_table = semitek_devices,
+	.report_fixup = semitek_report_fixup,
+};
+module_hid_driver(semitek_driver);
+
+MODULE_LICENSE("GPL");
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] HID: semitek: new driver for GK6X series keyboards
  2021-02-07 18:47 [PATCH] HID: semitek: new driver for GK6X series keyboards Benjamin Moody
@ 2021-05-05 12:21 ` Jiri Kosina
  0 siblings, 0 replies; 2+ messages in thread
From: Jiri Kosina @ 2021-05-05 12:21 UTC (permalink / raw)
  To: Benjamin Moody
  Cc: Benjamin Tissoires, linux-input, linux-kernel, Benjamin Moody

On Sun, 7 Feb 2021, Benjamin Moody wrote:

> From: Benjamin Moody <bmoody@member.fsf.org>
> 
> A number of USB keyboards, using the Semitek firmware, are capable of
> handling arbitrary N-key rollover, but due to a buggy report
> descriptor, keys beyond the sixth cannot be detected by the generic
> HID driver.
> 
> There are numerous hardware variants sold by several vendors, mostly
> using generic names like "GK61" for the 61-key version.  These
> keyboards are sometimes known collectively as the "GK6X" series.
> 
> The keyboard has three USB interfaces.  Interface 0 uses the standard
> HID boot protocol, limited to eight modifier keys and six normal keys;
> interface 2 uses a custom report format that permits any number of
> keys.  If more than six keys are pressed simultaneously, the first six
> are reported via interface 0 while subsequent keys are reported via
> interface 2.
> 
> (Interface 1 uses a custom protocol for reprogramming the keyboard;
> this can be controlled through userspace tools and is not of concern
> for the present driver.)
> 
> The report descriptor for interface 2, however, is incorrect (for
> report ID 0x04, the input field is marked as "array" rather than
> "variable".)  The descriptor appears to be correct in other respects,
> so we simply replace the incorrect byte before parsing the descriptor.
> 
> Signed-off-by: Benjamin Moody <bmoody@member.fsf.org>

Applied, thanks.

-- 
Jiri Kosina
SUSE Labs


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-05-05 12:21 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-07 18:47 [PATCH] HID: semitek: new driver for GK6X series keyboards Benjamin Moody
2021-05-05 12:21 ` Jiri Kosina

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).