aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilliam Whistler <wtbw@wtbw.co.uk>2019-01-14 12:50:07 -0500
committerBenjamin Tissoires <benjamin.tissoires@redhat.com>2019-01-14 14:11:01 -0500
commitaf8cd70a99300a7c3451c76efe1afa8eca37cfce (patch)
treed23c2ba2ab420863f7153c2a0a413d2f184418b2
parentcf26057a9441173ad552e90cea3344607075c9ad (diff)
Support for Maltron L90 keyboard media keys
The USB report descriptor sent by the Maltron L90 keyboard is invalid, causing the media key reports not to be accepted. This patch adds a driver which uses a report fixup to replace the descriptor. Signed-off-by: William Whistler <wtbw@wtbw.co.uk> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
-rw-r--r--drivers/hid/Kconfig7
-rw-r--r--drivers/hid/Makefile1
-rw-r--r--drivers/hid/hid-ids.h1
-rw-r--r--drivers/hid/hid-maltron.c165
4 files changed, 174 insertions, 0 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 41e9935fc584..661fe610ee5b 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -590,6 +590,13 @@ config HID_MAGICMOUSE
590 Say Y here if you want support for the multi-touch features of the 590 Say Y here if you want support for the multi-touch features of the
591 Apple Wireless "Magic" Mouse and the Apple Wireless "Magic" Trackpad. 591 Apple Wireless "Magic" Mouse and the Apple Wireless "Magic" Trackpad.
592 592
593config HID_MALTRON
594 tristate "Maltron L90 keyboard"
595 depends on HID
596 ---help---
597 Adds support for the volume up, volume down, mute, and play/pause buttons
598 of the Maltron L90 keyboard.
599
593config HID_MAYFLASH 600config HID_MAYFLASH
594 tristate "Mayflash game controller adapter force feedback" 601 tristate "Mayflash game controller adapter force feedback"
595 depends on HID 602 depends on HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 896a51ce7ce0..cf2752003253 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o
66obj-$(CONFIG_HID_LOGITECH_DJ) += hid-logitech-dj.o 66obj-$(CONFIG_HID_LOGITECH_DJ) += hid-logitech-dj.o
67obj-$(CONFIG_HID_LOGITECH_HIDPP) += hid-logitech-hidpp.o 67obj-$(CONFIG_HID_LOGITECH_HIDPP) += hid-logitech-hidpp.o
68obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o 68obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o
69obj-$(CONFIG_HID_MALTRON) += hid-maltron.o
69obj-$(CONFIG_HID_MAYFLASH) += hid-mf.o 70obj-$(CONFIG_HID_MAYFLASH) += hid-mf.o
70obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o 71obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o
71obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o 72obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 518fa76414f5..01d565357dbe 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -72,6 +72,7 @@
72 72
73#define USB_VENDOR_ID_ALCOR 0x058f 73#define USB_VENDOR_ID_ALCOR 0x058f
74#define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 74#define USB_DEVICE_ID_ALCOR_USBRS232 0x9720
75#define USB_DEVICE_ID_ALCOR_MALTRON_KB 0x9410
75 76
76#define USB_VENDOR_ID_ALPS 0x0433 77#define USB_VENDOR_ID_ALPS 0x0433
77#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101 78#define USB_DEVICE_ID_IBM_GAMEPAD 0x1101
diff --git a/drivers/hid/hid-maltron.c b/drivers/hid/hid-maltron.c
new file mode 100644
index 000000000000..dcd6db6a646e
--- /dev/null
+++ b/drivers/hid/hid-maltron.c
@@ -0,0 +1,165 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * HID driver for Maltron L90
4 *
5 * Copyright (c) 1999 Andreas Gal
6 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
7 * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
8 * Copyright (c) 2008 Jiri Slaby
9 * Copyright (c) 2012 David Dillow <dave@thedillows.org>
10 * Copyright (c) 2006-2013 Jiri Kosina
11 * Copyright (c) 2013 Colin Leitner <colin.leitner@gmail.com>
12 * Copyright (c) 2014-2016 Frank Praznik <frank.praznik@gmail.com>
13 * Copyright (c) 2010 Richard Nauber <Richard.Nauber@gmail.com>
14 * Copyright (c) 2016 Yuxuan Shui <yshuiv7@gmail.com>
15 * Copyright (c) 2018 William Whistler <wtbw@wtbw.co.uk>
16 */
17
18#include <linux/device.h>
19#include <linux/hid.h>
20#include <linux/module.h>
21
22#include "hid-ids.h"
23
24/* The original buggy USB descriptor */
25static u8 maltron_rdesc_o[] = {
26 0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */
27 0x09, 0x80, /* Usage (Sys Control) */
28 0xA1, 0x01, /* Collection (Application) */
29 0x85, 0x02, /* Report ID (2) */
30 0x75, 0x01, /* Report Size (1) */
31 0x95, 0x01, /* Report Count (1) */
32 0x15, 0x00, /* Logical Minimum (0) */
33 0x25, 0x01, /* Logical Maximum (1) */
34 0x09, 0x82, /* Usage (Sys Sleep) */
35 0x81, 0x06, /* Input (Data,Var,Rel) */
36 0x09, 0x82, /* Usage (Sys Sleep) */
37 0x81, 0x06, /* Input (Data,Var,Rel) */
38 0x09, 0x83, /* Usage (Sys Wake Up) */
39 0x81, 0x06, /* Input (Data,Var,Rel) */
40 0x75, 0x05, /* Report Size (5) */
41 0x81, 0x01, /* Input (Const,Array,Abs) */
42 0xC0, /* End Collection */
43 0x05, 0x0C, /* Usage Page (Consumer) */
44 0x09, 0x01, /* Usage (Consumer Control) */
45 0xA1, 0x01, /* Collection (Application) */
46 0x85, 0x03, /* Report ID (3) */
47 0x95, 0x01, /* Report Count (1) */
48 0x75, 0x10, /* Report Size (16) */
49 0x19, 0x00, /* Usage Minimum (Unassigned) */
50 0x2A, 0xFF, 0x7F, /* Usage Maximum (0x7FFF) */
51 0x81, 0x00, /* Input (Data,Array,Abs) */
52 0xC0, /* End Collection */
53 0x06, 0x7F, 0xFF, /* Usage Page (Vendor Defined 0xFF7F) */
54 0x09, 0x01, /* Usage (0x01) */
55 0xA1, 0x01, /* Collection (Application) */
56 0x85, 0x04, /* Report ID (4) */
57 0x95, 0x01, /* Report Count (1) */
58 0x75, 0x10, /* Report Size (16) */
59 0x19, 0x00, /* Usage Minimum (0x00) */
60 0x2A, 0xFF, 0x7F, /* Usage Maximum (0x7FFF) */
61 0x81, 0x00, /* Input (Data,Array,Abs) */
62 0x75, 0x02, /* Report Size (2) */
63 0x25, 0x02, /* Logical Maximum (2) */
64 0x09, 0x90, /* Usage (0x90) */
65 0xB1, 0x02, /* Feature (Data,Var,Abs) */
66 0x75, 0x06, /* Report Size (6) */
67 0xB1, 0x01, /* Feature (Const,Array,Abs) */
68 0x75, 0x01, /* Report Size (1) */
69 0x25, 0x01, /* Logical Maximum (1) */
70 0x05, 0x08, /* Usage Page (LEDs) */
71 0x09, 0x2A, /* Usage (On-Line) */
72 0x91, 0x02, /* Output (Data,Var,Abs) */
73 0x09, 0x4B, /* Usage (Generic Indicator) */
74 0x91, 0x02, /* Output (Data,Var,Abs) */
75 0x75, 0x06, /* Report Size (6) */
76 0x95, 0x01, /* Report Count (1) */
77 0x91, 0x01, /* Output (Const,Array,Abs) */
78 0xC0 /* End Collection */
79};
80
81/* The patched descriptor, allowing media key events to be accepted as valid */
82static u8 maltron_rdesc[] = {
83 0x05, 0x01, /* Usage Page (Generic Desktop Ctrls) */
84 0x09, 0x80, /* Usage (Sys Control) */
85 0xA1, 0x01, /* Collection (Application) */
86 0x85, 0x02, /* Report ID (2) */
87 0x75, 0x01, /* Report Size (1) */
88 0x95, 0x01, /* Report Count (1) */
89 0x15, 0x00, /* Logical Minimum (0) */
90 0x25, 0x01, /* Logical Maximum (1) */
91 0x09, 0x82, /* Usage (Sys Sleep) */
92 0x81, 0x06, /* Input (Data,Var,Rel) */
93 0x09, 0x82, /* Usage (Sys Sleep) */
94 0x81, 0x06, /* Input (Data,Var,Rel) */
95 0x09, 0x83, /* Usage (Sys Wake Up) */
96 0x81, 0x06, /* Input (Data,Var,Rel) */
97 0x75, 0x05, /* Report Size (5) */
98 0x81, 0x01, /* Input (Const,Array,Abs) */
99 0xC0, /* End Collection */
100 0x05, 0x0C, /* Usage Page (Consumer) */
101 0x09, 0x01, /* Usage (Consumer Control) */
102 0xA1, 0x01, /* Collection (Application) */
103 0x85, 0x03, /* Report ID (3) */
104 0x15, 0x00, /* Logical Minimum (0) - changed */
105 0x26, 0xFF, 0x7F, /* Logical Maximum (32767) - changed */
106 0x95, 0x01, /* Report Count (1) */
107 0x75, 0x10, /* Report Size (16) */
108 0x19, 0x00, /* Usage Minimum (Unassigned) */
109 0x2A, 0xFF, 0x7F, /* Usage Maximum (0x7FFF) */
110 0x81, 0x00, /* Input (Data,Array,Abs) */
111 0xC0, /* End Collection */
112 0x06, 0x7F, 0xFF, /* Usage Page (Vendor Defined 0xFF7F) */
113 0x09, 0x01, /* Usage (0x01) */
114 0xA1, 0x01, /* Collection (Application) */
115 0x85, 0x04, /* Report ID (4) */
116 0x95, 0x01, /* Report Count (1) */
117 0x75, 0x10, /* Report Size (16) */
118 0x19, 0x00, /* Usage Minimum (0x00) */
119 0x2A, 0xFF, 0x7F, /* Usage Maximum (0x7FFF) */
120 0x81, 0x00, /* Input (Data,Array,Abs) */
121 0x75, 0x02, /* Report Size (2) */
122 0x25, 0x02, /* Logical Maximum (2) */
123 0x09, 0x90, /* Usage (0x90) */
124 0xB1, 0x02, /* Feature (Data,Var,Abs) */
125 0x75, 0x06, /* Report Size (6) */
126 0xB1, 0x01, /* Feature (Const,Array,Abs) */
127 0x75, 0x01, /* Report Size (1) */
128 0x25, 0x01, /* Logical Maximum (1) */
129 0x05, 0x08, /* Usage Page (LEDs) */
130 0x09, 0x2A, /* Usage (On-Line) */
131 0x91, 0x02, /* Output (Data,Var,Abs) */
132 0x09, 0x4B, /* Usage (Generic Indicator) */
133 0x91, 0x02, /* Output (Data,Var,Abs) */
134 0x75, 0x06, /* Report Size (6) */
135 0x95, 0x01, /* Report Count (1) */
136 0x91, 0x01, /* Output (Const,Array,Abs) */
137 0xC0 /* End Collection */
138};
139
140static __u8 *maltron_report_fixup(struct hid_device *hdev, __u8 *rdesc,
141 unsigned int *rsize)
142{
143 if (*rsize == sizeof(maltron_rdesc_o) &&
144 !memcmp(maltron_rdesc_o, rdesc, sizeof(maltron_rdesc_o))) {
145 hid_info(hdev, "Replacing Maltron L90 keyboard report descriptor\n");
146 *rsize = sizeof(maltron_rdesc);
147 return maltron_rdesc;
148 }
149 return rdesc;
150}
151
152static const struct hid_device_id maltron_devices[] = {
153 { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_MALTRON_KB)},
154 { }
155};
156MODULE_DEVICE_TABLE(hid, maltron_devices);
157
158static struct hid_driver maltron_driver = {
159 .name = "maltron",
160 .id_table = maltron_devices,
161 .report_fixup = maltron_report_fixup
162};
163module_hid_driver(maltron_driver);
164
165MODULE_LICENSE("GPL");