aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2008-06-20 15:26:11 -0400
committerJiri Kosina <jkosina@suse.cz>2008-10-14 17:50:50 -0400
commit78a849a682a1d5ee7b7187b08abdc48656326a4e (patch)
treea56ddeecfb80f14d6ea38e81605cbb65bec03bc3
parent880d29f109428be1d027adf919a7457d8fe41fd3 (diff)
HID: move microsoft quirks
Move them from the core code to a separate driver. Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/Kconfig8
-rw-r--r--drivers/hid/Makefile1
-rw-r--r--drivers/hid/hid-core.c6
-rw-r--r--drivers/hid/hid-dummy.c3
-rw-r--r--drivers/hid/hid-ids.h4
-rw-r--r--drivers/hid/hid-input-quirks.c76
-rw-r--r--drivers/hid/hid-microsoft.c220
-rw-r--r--drivers/hid/usbhid/hid-quirks.c33
-rw-r--r--include/linux/hid.h2
9 files changed, 241 insertions, 112 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index d9d1a5671d95..8067b653f8bf 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -104,6 +104,14 @@ config HID_LOGITECH
104 Support for some Logitech devices which breaks less or more 104 Support for some Logitech devices which breaks less or more
105 HID specification. 105 HID specification.
106 106
107config HID_MICROSOFT
108 tristate "Microsoft"
109 default m
110 depends on USB_HID
111 ---help---
112 Support for some Microsoft devices which breaks less or more
113 HID specification.
114
107endmenu 115endmenu
108 116
109endif # HID_SUPPORT 117endif # HID_SUPPORT
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 8e053eca4742..3dc2828fb719 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -14,6 +14,7 @@ endif
14 14
15obj-$(CONFIG_HID_APPLE) += hid-apple.o 15obj-$(CONFIG_HID_APPLE) += hid-apple.o
16obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o 16obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o
17obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o
17 18
18obj-$(CONFIG_USB_HID) += usbhid/ 19obj-$(CONFIG_USB_HID) += usbhid/
19obj-$(CONFIG_USB_MOUSE) += usbhid/ 20obj-$(CONFIG_USB_MOUSE) += usbhid/
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 5e62e010d805..db8fbd2f5028 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1176,8 +1176,14 @@ static const struct hid_device_id hid_blacklist[] = {
1176 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_V150) }, 1176 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_V150) },
1177 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, 1177 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) },
1178 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) }, 1178 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) },
1179 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) },
1180 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) },
1181 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) },
1182 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) },
1183 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },
1179 1184
1180 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) }, 1185 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) },
1186 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
1181 { } 1187 { }
1182}; 1188};
1183 1189
diff --git a/drivers/hid/hid-dummy.c b/drivers/hid/hid-dummy.c
index b76c44efe1b8..fe64d60f9010 100644
--- a/drivers/hid/hid-dummy.c
+++ b/drivers/hid/hid-dummy.c
@@ -10,6 +10,9 @@ static int __init hid_dummy_init(void)
10#ifdef CONFIG_HID_LOGITECH_MODULE 10#ifdef CONFIG_HID_LOGITECH_MODULE
11 HID_COMPAT_CALL_DRIVER(logitech); 11 HID_COMPAT_CALL_DRIVER(logitech);
12#endif 12#endif
13#ifdef CONFIG_HID_MICROSOFT_MODULE
14 HID_COMPAT_CALL_DRIVER(microsoft);
15#endif
13 16
14 return -EIO; 17 return -EIO;
15} 18}
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 23d021bd95d0..d7e548dbe7c3 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -280,9 +280,11 @@
280#define USB_VENDOR_ID_MICROSOFT 0x045e 280#define USB_VENDOR_ID_MICROSOFT 0x045e
281#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b 281#define USB_DEVICE_ID_SIDEWINDER_GV 0x003b
282#define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d 282#define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d
283#define USB_DEVICE_ID_DESKTOP_RECV_1028 0x00f9
284#define USB_DEVICE_ID_MS_NE4K 0x00db 283#define USB_DEVICE_ID_MS_NE4K 0x00db
285#define USB_DEVICE_ID_MS_LK6K 0x00f9 284#define USB_DEVICE_ID_MS_LK6K 0x00f9
285#define USB_DEVICE_ID_MS_PRESENTER_8K_BT 0x0701
286#define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713
287
286 288
287#define USB_VENDOR_ID_MONTEREY 0x0566 289#define USB_VENDOR_ID_MONTEREY 0x0566
288#define USB_DEVICE_ID_GENIUS_KB29E 0x3004 290#define USB_DEVICE_ID_GENIUS_KB29E 0x3004
diff --git a/drivers/hid/hid-input-quirks.c b/drivers/hid/hid-input-quirks.c
index 878e193c6d75..d1b4f093dcb3 100644
--- a/drivers/hid/hid-input-quirks.c
+++ b/drivers/hid/hid-input-quirks.c
@@ -102,50 +102,6 @@ static int quirk_chicony_tactical_pad(struct hid_usage *usage,
102 return 1; 102 return 1;
103} 103}
104 104
105static int quirk_microsoft_ergonomy_kb(struct hid_usage *usage,
106 struct hid_input *hidinput, unsigned long **bit, int *max)
107{
108 struct input_dev *input = hidinput->input;
109
110 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
111 return 0;
112
113 switch(usage->hid & HID_USAGE) {
114 case 0xfd06: map_key_clear(KEY_CHAT); break;
115 case 0xfd07: map_key_clear(KEY_PHONE); break;
116 case 0xff05:
117 set_bit(EV_REP, input->evbit);
118 map_key_clear(KEY_F13);
119 set_bit(KEY_F14, input->keybit);
120 set_bit(KEY_F15, input->keybit);
121 set_bit(KEY_F16, input->keybit);
122 set_bit(KEY_F17, input->keybit);
123 set_bit(KEY_F18, input->keybit);
124 default:
125 return 0;
126 }
127 return 1;
128}
129
130static int quirk_microsoft_presenter_8k(struct hid_usage *usage,
131 struct hid_input *hidinput, unsigned long **bit, int *max)
132{
133 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
134 return 0;
135
136 set_bit(EV_REP, hidinput->input->evbit);
137 switch(usage->hid & HID_USAGE) {
138 case 0xfd08: map_key_clear(KEY_FORWARD); break;
139 case 0xfd09: map_key_clear(KEY_BACK); break;
140 case 0xfd0b: map_key_clear(KEY_PLAYPAUSE); break;
141 case 0xfd0e: map_key_clear(KEY_CLOSE); break;
142 case 0xfd0f: map_key_clear(KEY_PLAY); break;
143 default:
144 return 0;
145 }
146 return 1;
147}
148
149static int quirk_petalynx_remote(struct hid_usage *usage, 105static int quirk_petalynx_remote(struct hid_usage *usage,
150 struct hid_input *hidinput, unsigned long **bit, int *max) 106 struct hid_input *hidinput, unsigned long **bit, int *max)
151{ 107{
@@ -244,12 +200,6 @@ static int quirk_sunplus_wdesktop(struct hid_usage *usage,
244#define VENDOR_ID_GYRATION 0x0c16 200#define VENDOR_ID_GYRATION 0x0c16
245#define DEVICE_ID_GYRATION_REMOTE 0x0002 201#define DEVICE_ID_GYRATION_REMOTE 0x0002
246 202
247#define VENDOR_ID_MICROSOFT 0x045e
248#define DEVICE_ID_MS4K 0x00db
249#define DEVICE_ID_MS6K 0x00f9
250#define DEVICE_IS_MS_PRESENTER_8K_BT 0x0701
251#define DEVICE_ID_MS_PRESENTER_8K_USB 0x0713
252
253#define VENDOR_ID_MONTEREY 0x0566 203#define VENDOR_ID_MONTEREY 0x0566
254#define DEVICE_ID_GENIUS_KB29E 0x3004 204#define DEVICE_ID_GENIUS_KB29E 0x3004
255 205
@@ -275,11 +225,6 @@ static const struct hid_input_blacklist {
275 225
276 { VENDOR_ID_GYRATION, DEVICE_ID_GYRATION_REMOTE, quirk_gyration_remote }, 226 { VENDOR_ID_GYRATION, DEVICE_ID_GYRATION_REMOTE, quirk_gyration_remote },
277 227
278 { VENDOR_ID_MICROSOFT, DEVICE_ID_MS4K, quirk_microsoft_ergonomy_kb },
279 { VENDOR_ID_MICROSOFT, DEVICE_ID_MS6K, quirk_microsoft_ergonomy_kb },
280 { VENDOR_ID_MICROSOFT, DEVICE_IS_MS_PRESENTER_8K_BT, quirk_microsoft_presenter_8k },
281 { VENDOR_ID_MICROSOFT, DEVICE_ID_MS_PRESENTER_8K_USB, quirk_microsoft_presenter_8k },
282
283 { VENDOR_ID_MONTEREY, DEVICE_ID_GENIUS_KB29E, quirk_cherry_genius_29e }, 228 { VENDOR_ID_MONTEREY, DEVICE_ID_GENIUS_KB29E, quirk_cherry_genius_29e },
284 229
285 { VENDOR_ID_PETALYNX, DEVICE_ID_PETALYNX_MAXTER_REMOTE, quirk_petalynx_remote }, 230 { VENDOR_ID_PETALYNX, DEVICE_ID_PETALYNX_MAXTER_REMOTE, quirk_petalynx_remote },
@@ -336,27 +281,6 @@ int hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struc
336 return 1; 281 return 1;
337 } 282 }
338 283
339 /* Handling MS keyboards special buttons */
340 if (hid->quirks & HID_QUIRK_MICROSOFT_KEYS &&
341 usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
342 int key = 0;
343 static int last_key = 0;
344 switch (value) {
345 case 0x01: key = KEY_F14; break;
346 case 0x02: key = KEY_F15; break;
347 case 0x04: key = KEY_F16; break;
348 case 0x08: key = KEY_F17; break;
349 case 0x10: key = KEY_F18; break;
350 default: break;
351 }
352 if (key) {
353 input_event(input, usage->type, key, 1);
354 last_key = key;
355 } else {
356 input_event(input, usage->type, last_key, 0);
357 }
358 }
359
360 /* handle the temporary quirky mapping to HWHEEL */ 284 /* handle the temporary quirky mapping to HWHEEL */
361 if (hid->quirks & HID_QUIRK_HWHEEL_WHEEL_INVERT && 285 if (hid->quirks & HID_QUIRK_HWHEEL_WHEEL_INVERT &&
362 usage->type == EV_REL && usage->code == REL_HWHEEL) { 286 usage->type == EV_REL && usage->code == REL_HWHEEL) {
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
new file mode 100644
index 000000000000..1fa8b813d441
--- /dev/null
+++ b/drivers/hid/hid-microsoft.c
@@ -0,0 +1,220 @@
1/*
2 * HID driver for some microsoft "special" devices
3 *
4 * Copyright (c) 1999 Andreas Gal
5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
6 * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
7 * Copyright (c) 2006-2007 Jiri Kosina
8 * Copyright (c) 2007 Paul Walmsley
9 * Copyright (c) 2008 Jiri Slaby
10 */
11
12/*
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the Free
15 * Software Foundation; either version 2 of the License, or (at your option)
16 * any later version.
17 */
18
19#include <linux/device.h>
20#include <linux/input.h>
21#include <linux/hid.h>
22#include <linux/module.h>
23
24#include "hid-ids.h"
25
26#define MS_HIDINPUT 0x01
27#define MS_ERGONOMY 0x02
28#define MS_PRESENTER 0x04
29#define MS_RDESC 0x08
30#define MS_NOGET 0x10
31
32/*
33 * Microsoft Wireless Desktop Receiver (Model 1028) has several
34 * 'Usage Min/Max' where it ought to have 'Physical Min/Max'
35 */
36static void ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
37 unsigned int rsize)
38{
39 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
40
41 if ((quirks & MS_RDESC) && rsize == 571 && rdesc[284] == 0x19 &&
42 rdesc[286] == 0x2a && rdesc[304] == 0x19 &&
43 rdesc[306] == 0x29 && rdesc[352] == 0x1a &&
44 rdesc[355] == 0x2a && rdesc[557] == 0x19 &&
45 rdesc[559] == 0x29) {
46 dev_info(&hdev->dev, "fixing up Microsoft Wireless Receiver "
47 "Model 1028 report descriptor\n");
48 rdesc[284] = rdesc[304] = rdesc[557] = 0x35;
49 rdesc[352] = 0x36;
50 rdesc[286] = rdesc[355] = 0x46;
51 rdesc[306] = rdesc[559] = 0x45;
52 }
53}
54
55#define ms_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
56 EV_KEY, (c))
57static int ms_ergonomy_kb_quirk(struct hid_input *hi, struct hid_usage *usage,
58 unsigned long **bit, int *max)
59{
60 struct input_dev *input = hi->input;
61
62 switch (usage->hid & HID_USAGE) {
63 case 0xfd06: ms_map_key_clear(KEY_CHAT); break;
64 case 0xfd07: ms_map_key_clear(KEY_PHONE); break;
65 case 0xff05:
66 set_bit(EV_REP, input->evbit);
67 ms_map_key_clear(KEY_F13);
68 set_bit(KEY_F14, input->keybit);
69 set_bit(KEY_F15, input->keybit);
70 set_bit(KEY_F16, input->keybit);
71 set_bit(KEY_F17, input->keybit);
72 set_bit(KEY_F18, input->keybit);
73 default:
74 return 0;
75 }
76 return 1;
77}
78
79static int ms_presenter_8k_quirk(struct hid_input *hi, struct hid_usage *usage,
80 unsigned long **bit, int *max)
81{
82 set_bit(EV_REP, hi->input->evbit);
83 switch (usage->hid & HID_USAGE) {
84 case 0xfd08: ms_map_key_clear(KEY_FORWARD); break;
85 case 0xfd09: ms_map_key_clear(KEY_BACK); break;
86 case 0xfd0b: ms_map_key_clear(KEY_PLAYPAUSE); break;
87 case 0xfd0e: ms_map_key_clear(KEY_CLOSE); break;
88 case 0xfd0f: ms_map_key_clear(KEY_PLAY); break;
89 default:
90 return 0;
91 }
92 return 1;
93}
94
95static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi,
96 struct hid_field *field, struct hid_usage *usage,
97 unsigned long **bit, int *max)
98{
99 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
100
101 if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
102 return 0;
103
104 if (quirks & MS_ERGONOMY) {
105 int ret = ms_ergonomy_kb_quirk(hi, usage, bit, max);
106 if (ret)
107 return ret;
108 }
109
110 if ((quirks & MS_PRESENTER) &&
111 ms_presenter_8k_quirk(hi, usage, bit, max))
112 return 1;
113
114 return 0;
115}
116
117static int ms_event(struct hid_device *hdev, struct hid_field *field,
118 struct hid_usage *usage, __s32 value)
119{
120 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
121
122 if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
123 !usage->type)
124 return 0;
125
126 /* Handling MS keyboards special buttons */
127 if (quirks & MS_ERGONOMY && usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
128 struct input_dev *input = field->hidinput->input;
129 static unsigned int last_key = 0;
130 unsigned int key = 0;
131 switch (value) {
132 case 0x01: key = KEY_F14; break;
133 case 0x02: key = KEY_F15; break;
134 case 0x04: key = KEY_F16; break;
135 case 0x08: key = KEY_F17; break;
136 case 0x10: key = KEY_F18; break;
137 }
138 if (key) {
139 input_event(input, usage->type, key, 1);
140 last_key = key;
141 } else
142 input_event(input, usage->type, last_key, 0);
143
144 return 1;
145 }
146
147 return 0;
148}
149
150static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id)
151{
152 unsigned long quirks = id->driver_data;
153 int ret;
154
155 hid_set_drvdata(hdev, (void *)quirks);
156
157 if (quirks & MS_HIDINPUT)
158 hdev->quirks |= HID_QUIRK_HIDINPUT;
159 if (quirks & MS_NOGET)
160 hdev->quirks |= HID_QUIRK_NOGET;
161
162 ret = hid_parse(hdev);
163 if (ret) {
164 dev_err(&hdev->dev, "parse failed\n");
165 goto err_free;
166 }
167
168 ret = hid_hw_start(hdev);
169 if (ret) {
170 dev_err(&hdev->dev, "hw start failed\n");
171 goto err_free;
172 }
173
174 return 0;
175err_free:
176 return ret;
177}
178
179static const struct hid_device_id ms_devices[] = {
180 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV),
181 .driver_data = MS_HIDINPUT },
182 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K),
183 .driver_data = MS_ERGONOMY },
184 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K),
185 .driver_data = MS_ERGONOMY | MS_RDESC },
186 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB),
187 .driver_data = MS_PRESENTER },
188 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0),
189 .driver_data = MS_NOGET },
190
191 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT),
192 .driver_data = MS_PRESENTER },
193 { }
194};
195MODULE_DEVICE_TABLE(hid, ms_devices);
196
197static struct hid_driver ms_driver = {
198 .name = "microsoft",
199 .id_table = ms_devices,
200 .report_fixup = ms_report_fixup,
201 .input_mapping = ms_input_mapping,
202 .event = ms_event,
203 .probe = ms_probe,
204};
205
206static int ms_init(void)
207{
208 return hid_register_driver(&ms_driver);
209}
210
211static void ms_exit(void)
212{
213 hid_unregister_driver(&ms_driver);
214}
215
216module_init(ms_init);
217module_exit(ms_exit);
218MODULE_LICENSE("GPL");
219
220HID_COMPAT_LOAD_DRIVER(microsoft);
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 4c5ee9ecd40a..1614ed2efc15 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -50,14 +50,9 @@ static const struct hid_blacklist {
50 50
51 { USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM, HID_QUIRK_HIDDEV }, 51 { USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM, HID_QUIRK_HIDDEV },
52 { USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT }, 52 { USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT },
53 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV, HID_QUIRK_HIDINPUT },
54 53
55 { USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193, HID_QUIRK_HWHEEL_WHEEL_INVERT }, 54 { USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193, HID_QUIRK_HWHEEL_WHEEL_INVERT },
56 55
57
58 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K, HID_QUIRK_MICROSOFT_KEYS },
59 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K, HID_QUIRK_MICROSOFT_KEYS },
60
61 { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, 56 { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
62 { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, 57 { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT },
63 58
@@ -70,7 +65,6 @@ static const struct hid_blacklist {
70 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, 65 { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
71 { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, 66 { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
72 { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, 67 { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
73 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0, HID_QUIRK_NOGET },
74 { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_NOGET }, 68 { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_NOGET },
75 { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, 69 { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
76 { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, 70 { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET },
@@ -93,8 +87,6 @@ static const struct hid_rdesc_blacklist {
93 87
94 { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_RDESC_CYMOTION }, 88 { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_RDESC_CYMOTION },
95 89
96 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_DESKTOP_RECV_1028, HID_QUIRK_RDESC_MICROSOFT_RECV_1028 },
97
98 { USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E, HID_QUIRK_RDESC_BUTTON_CONSUMER }, 90 { USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E, HID_QUIRK_RDESC_BUTTON_CONSUMER },
99 91
100 { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_RDESC_PETALYNX }, 92 { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_RDESC_PETALYNX },
@@ -436,28 +428,6 @@ static void usbhid_fixup_button_consumer_descriptor(unsigned char *rdesc, int rs
436 } 428 }
437} 429}
438 430
439/*
440 * Microsoft Wireless Desktop Receiver (Model 1028) has several
441 * 'Usage Min/Max' where it ought to have 'Physical Min/Max'
442 */
443static void usbhid_fixup_microsoft_descriptor(unsigned char *rdesc, int rsize)
444{
445 if (rsize == 571 && rdesc[284] == 0x19
446 && rdesc[286] == 0x2a
447 && rdesc[304] == 0x19
448 && rdesc[306] == 0x29
449 && rdesc[352] == 0x1a
450 && rdesc[355] == 0x2a
451 && rdesc[557] == 0x19
452 && rdesc[559] == 0x29) {
453 printk(KERN_INFO "Fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n");
454 rdesc[284] = rdesc[304] = rdesc[557] = 0x35;
455 rdesc[352] = 0x36;
456 rdesc[286] = rdesc[355] = 0x46;
457 rdesc[306] = rdesc[559] = 0x45;
458 }
459}
460
461static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize) 431static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize)
462{ 432{
463 if ((quirks & HID_QUIRK_RDESC_CYMOTION)) 433 if ((quirks & HID_QUIRK_RDESC_CYMOTION))
@@ -475,9 +445,6 @@ static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned
475 if (quirks & HID_QUIRK_RDESC_SAMSUNG_REMOTE) 445 if (quirks & HID_QUIRK_RDESC_SAMSUNG_REMOTE)
476 usbhid_fixup_samsung_irda_descriptor(rdesc, rsize); 446 usbhid_fixup_samsung_irda_descriptor(rdesc, rsize);
477 447
478 if (quirks & HID_QUIRK_RDESC_MICROSOFT_RECV_1028)
479 usbhid_fixup_microsoft_descriptor(rdesc, rsize);
480
481 if (quirks & HID_QUIRK_RDESC_SUNPLUS_WDESKTOP) 448 if (quirks & HID_QUIRK_RDESC_SUNPLUS_WDESKTOP)
482 usbhid_fixup_sunplus_wdesktop(rdesc, rsize); 449 usbhid_fixup_sunplus_wdesktop(rdesc, rsize);
483} 450}
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 60e44e6b86e6..1f1edd886ef8 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -271,7 +271,6 @@ struct hid_item {
271#define HID_QUIRK_IGNORE_HIDINPUT 0x01000000 271#define HID_QUIRK_IGNORE_HIDINPUT 0x01000000
272#define HID_QUIRK_2WHEEL_MOUSE_HACK_B8 0x02000000 272#define HID_QUIRK_2WHEEL_MOUSE_HACK_B8 0x02000000
273#define HID_QUIRK_HWHEEL_WHEEL_INVERT 0x04000000 273#define HID_QUIRK_HWHEEL_WHEEL_INVERT 0x04000000
274#define HID_QUIRK_MICROSOFT_KEYS 0x08000000
275#define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 274#define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000
276 275
277/* 276/*
@@ -283,7 +282,6 @@ struct hid_item {
283#define HID_QUIRK_RDESC_PETALYNX 0x00000008 282#define HID_QUIRK_RDESC_PETALYNX 0x00000008
284#define HID_QUIRK_RDESC_BUTTON_CONSUMER 0x00000020 283#define HID_QUIRK_RDESC_BUTTON_CONSUMER 0x00000020
285#define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000040 284#define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000040
286#define HID_QUIRK_RDESC_MICROSOFT_RECV_1028 0x00000080
287#define HID_QUIRK_RDESC_SUNPLUS_WDESKTOP 0x00000100 285#define HID_QUIRK_RDESC_SUNPLUS_WDESKTOP 0x00000100
288 286
289/* 287/*