Skip to content

Commit 3faed1a

Browse files
jwrdegoedeJiri Kosina
authored andcommitted
HID: hid-microsoft: Add support for scrollwheel and special keypad keys
The Microsoft Office keyboard has a scrollwheel as well as some special keys above the keypad which are handled through the custom MS usage page, this commit adds support for these. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
1 parent aac59f6 commit 3faed1a

3 files changed

Lines changed: 50 additions & 1 deletion

File tree

drivers/hid/hid-core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,6 +1779,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
17791779
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) },
17801780
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) },
17811781
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },
1782+
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) },
17821783
{ HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
17831784
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
17841785
{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1) },

drivers/hid/hid-ids.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,7 @@
609609

610610
#define USB_VENDOR_ID_MICROSOFT 0x045e
611611
#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b
612+
#define USB_DEVICE_ID_MS_OFFICE_KB 0x0048
612613
#define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d
613614
#define USB_DEVICE_ID_MS_NE4K 0x00db
614615
#define USB_DEVICE_ID_MS_NE4K_JP 0x00dc

drivers/hid/hid-microsoft.c

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,26 @@ static int ms_ergonomy_kb_quirk(struct hid_input *hi, struct hid_usage *usage,
6868
switch (usage->hid & HID_USAGE) {
6969
case 0xfd06: ms_map_key_clear(KEY_CHAT); break;
7070
case 0xfd07: ms_map_key_clear(KEY_PHONE); break;
71+
case 0xff00:
72+
/* Special keypad keys */
73+
ms_map_key_clear(KEY_KPEQUAL);
74+
set_bit(KEY_KPLEFTPAREN, input->keybit);
75+
set_bit(KEY_KPRIGHTPAREN, input->keybit);
76+
break;
77+
case 0xff01:
78+
/* Scroll wheel */
79+
hid_map_usage_clear(hi, usage, bit, max, EV_REL, REL_WHEEL);
80+
break;
81+
case 0xff02:
82+
/*
83+
* This byte contains a copy of the modifier keys byte of a
84+
* standard hid keyboard report, as send by interface 0
85+
* (this usage is found on interface 1).
86+
*
87+
* This byte only gets send when another key in the same report
88+
* changes state, and as such is useless, ignore it.
89+
*/
90+
return -1;
7191
case 0xff05:
7292
set_bit(EV_REP, input->evbit);
7393
ms_map_key_clear(KEY_F13);
@@ -137,14 +157,39 @@ static int ms_event(struct hid_device *hdev, struct hid_field *field,
137157
struct hid_usage *usage, __s32 value)
138158
{
139159
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
160+
struct input_dev *input;
140161

141162
if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
142163
!usage->type)
143164
return 0;
144165

166+
input = field->hidinput->input;
167+
145168
/* Handling MS keyboards special buttons */
169+
if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff00)) {
170+
/* Special keypad keys */
171+
input_report_key(input, KEY_KPEQUAL, value & 0x01);
172+
input_report_key(input, KEY_KPLEFTPAREN, value & 0x02);
173+
input_report_key(input, KEY_KPRIGHTPAREN, value & 0x04);
174+
return 1;
175+
}
176+
177+
if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff01)) {
178+
/* Scroll wheel */
179+
int step = ((value & 0x60) >> 5) + 1;
180+
181+
switch (value & 0x1f) {
182+
case 0x01:
183+
input_report_rel(input, REL_WHEEL, step);
184+
break;
185+
case 0x1f:
186+
input_report_rel(input, REL_WHEEL, -step);
187+
break;
188+
}
189+
return 1;
190+
}
191+
146192
if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
147-
struct input_dev *input = field->hidinput->input;
148193
static unsigned int last_key = 0;
149194
unsigned int key = 0;
150195
switch (value) {
@@ -197,6 +242,8 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
197242
static const struct hid_device_id ms_devices[] = {
198243
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV),
199244
.driver_data = MS_HIDINPUT },
245+
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB),
246+
.driver_data = MS_ERGONOMY },
200247
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K),
201248
.driver_data = MS_ERGONOMY },
202249
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K_JP),

0 commit comments

Comments
 (0)