diff options
-rw-r--r-- | drivers/hid/Makefile | 2 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 12 | ||||
-rw-r--r-- | drivers/hid/hid-input-quirks.c | 423 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 295 | ||||
-rw-r--r-- | drivers/hid/usbhid/Kconfig | 5 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 118 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-tmff.c | 7 | ||||
-rw-r--r-- | drivers/hid/usbhid/usbkbd.c | 8 | ||||
-rw-r--r-- | drivers/hid/usbhid/usbmouse.c | 8 | ||||
-rw-r--r-- | include/linux/hid.h | 18 |
10 files changed, 651 insertions, 245 deletions
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 1ac5103f7c93..275dc522c738 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the HID driver | 2 | # Makefile for the HID driver |
3 | # | 3 | # |
4 | hid-objs := hid-core.o hid-input.o | 4 | hid-objs := hid-core.o hid-input.o hid-input-quirks.o |
5 | 5 | ||
6 | obj-$(CONFIG_HID) += hid.o | 6 | obj-$(CONFIG_HID) += hid.o |
7 | 7 | ||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 2884b036495a..d73a768e176e 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/input.h> | 26 | #include <linux/input.h> |
27 | #include <linux/wait.h> | 27 | #include <linux/wait.h> |
28 | #include <linux/vmalloc.h> | 28 | #include <linux/vmalloc.h> |
29 | #include <linux/sched.h> | ||
29 | 30 | ||
30 | #include <linux/hid.h> | 31 | #include <linux/hid.h> |
31 | #include <linux/hiddev.h> | 32 | #include <linux/hiddev.h> |
@@ -758,7 +759,9 @@ static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) | |||
758 | { | 759 | { |
759 | u64 x; | 760 | u64 x; |
760 | 761 | ||
761 | WARN_ON(n > 32); | 762 | if (n > 32) |
763 | printk(KERN_WARNING "HID: extract() called with n (%d) > 32! (%s)\n", | ||
764 | n, current->comm); | ||
762 | 765 | ||
763 | report += offset >> 3; /* adjust byte index */ | 766 | report += offset >> 3; /* adjust byte index */ |
764 | offset &= 7; /* now only need bit offset into one byte */ | 767 | offset &= 7; /* now only need bit offset into one byte */ |
@@ -780,8 +783,13 @@ static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u3 | |||
780 | __le64 x; | 783 | __le64 x; |
781 | u64 m = (1ULL << n) - 1; | 784 | u64 m = (1ULL << n) - 1; |
782 | 785 | ||
783 | WARN_ON(n > 32); | 786 | if (n > 32) |
787 | printk(KERN_WARNING "HID: implement() called with n (%d) > 32! (%s)\n", | ||
788 | n, current->comm); | ||
784 | 789 | ||
790 | if (value > m) | ||
791 | printk(KERN_WARNING "HID: implement() called with too large value %d! (%s)\n", | ||
792 | value, current->comm); | ||
785 | WARN_ON(value > m); | 793 | WARN_ON(value > m); |
786 | value &= m; | 794 | value &= m; |
787 | 795 | ||
diff --git a/drivers/hid/hid-input-quirks.c b/drivers/hid/hid-input-quirks.c new file mode 100644 index 000000000000..a870ba58faa3 --- /dev/null +++ b/drivers/hid/hid-input-quirks.c | |||
@@ -0,0 +1,423 @@ | |||
1 | /* | ||
2 | * HID-input usage mapping quirks | ||
3 | * | ||
4 | * This is used to handle HID-input mappings for devices violating | ||
5 | * HUT 1.12 specification. | ||
6 | * | ||
7 | * Copyright (c) 2007-2008 Jiri Kosina | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the Free | ||
13 | * Software Foundation; either version 2 of the License | ||
14 | */ | ||
15 | |||
16 | #include <linux/input.h> | ||
17 | #include <linux/hid.h> | ||
18 | |||
19 | #define map_abs(c) do { usage->code = c; usage->type = EV_ABS; *bit = input->absbit; *max = ABS_MAX; } while (0) | ||
20 | #define map_rel(c) do { usage->code = c; usage->type = EV_REL; *bit = input->relbit; *max = REL_MAX; } while (0) | ||
21 | #define map_key(c) do { usage->code = c; usage->type = EV_KEY; *bit = input->keybit; *max = KEY_MAX; } while (0) | ||
22 | #define map_led(c) do { usage->code = c; usage->type = EV_LED; *bit = input->ledbit; *max = LED_MAX; } while (0) | ||
23 | |||
24 | #define map_abs_clear(c) do { map_abs(c); clear_bit(c, *bit); } while (0) | ||
25 | #define map_key_clear(c) do { map_key(c); clear_bit(c, *bit); } while (0) | ||
26 | |||
27 | static int quirk_belkin_wkbd(struct hid_usage *usage, struct input_dev *input, | ||
28 | unsigned long **bit, int *max) | ||
29 | { | ||
30 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) | ||
31 | return 0; | ||
32 | |||
33 | switch (usage->hid & HID_USAGE) { | ||
34 | case 0x03a: map_key_clear(KEY_SOUND); break; | ||
35 | case 0x03b: map_key_clear(KEY_CAMERA); break; | ||
36 | case 0x03c: map_key_clear(KEY_DOCUMENTS); break; | ||
37 | default: | ||
38 | return 0; | ||
39 | } | ||
40 | return 1; | ||
41 | } | ||
42 | |||
43 | static int quirk_cherry_cymotion(struct hid_usage *usage, struct input_dev *input, | ||
44 | unsigned long **bit, int *max) | ||
45 | { | ||
46 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) | ||
47 | return 0; | ||
48 | |||
49 | switch (usage->hid & HID_USAGE) { | ||
50 | case 0x301: map_key_clear(KEY_PROG1); break; | ||
51 | case 0x302: map_key_clear(KEY_PROG2); break; | ||
52 | case 0x303: map_key_clear(KEY_PROG3); break; | ||
53 | default: | ||
54 | return 0; | ||
55 | } | ||
56 | return 1; | ||
57 | } | ||
58 | |||
59 | static int quirk_logitech_ultrax_remote(struct hid_usage *usage, struct input_dev *input, | ||
60 | unsigned long **bit, int *max) | ||
61 | { | ||
62 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) | ||
63 | return 0; | ||
64 | |||
65 | set_bit(EV_REP, input->evbit); | ||
66 | switch(usage->hid & HID_USAGE) { | ||
67 | /* Reported on Logitech Ultra X Media Remote */ | ||
68 | case 0x004: map_key_clear(KEY_AGAIN); break; | ||
69 | case 0x00d: map_key_clear(KEY_HOME); break; | ||
70 | case 0x024: map_key_clear(KEY_SHUFFLE); break; | ||
71 | case 0x025: map_key_clear(KEY_TV); break; | ||
72 | case 0x026: map_key_clear(KEY_MENU); break; | ||
73 | case 0x031: map_key_clear(KEY_AUDIO); break; | ||
74 | case 0x032: map_key_clear(KEY_TEXT); break; | ||
75 | case 0x033: map_key_clear(KEY_LAST); break; | ||
76 | case 0x047: map_key_clear(KEY_MP3); break; | ||
77 | case 0x048: map_key_clear(KEY_DVD); break; | ||
78 | case 0x049: map_key_clear(KEY_MEDIA); break; | ||
79 | case 0x04a: map_key_clear(KEY_VIDEO); break; | ||
80 | case 0x04b: map_key_clear(KEY_ANGLE); break; | ||
81 | case 0x04c: map_key_clear(KEY_LANGUAGE); break; | ||
82 | case 0x04d: map_key_clear(KEY_SUBTITLE); break; | ||
83 | case 0x051: map_key_clear(KEY_RED); break; | ||
84 | case 0x052: map_key_clear(KEY_CLOSE); break; | ||
85 | |||
86 | default: | ||
87 | return 0; | ||
88 | } | ||
89 | return 1; | ||
90 | } | ||
91 | |||
92 | static int quirk_chicony_tactical_pad(struct hid_usage *usage, struct input_dev *input, | ||
93 | unsigned long **bit, int *max) | ||
94 | { | ||
95 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) | ||
96 | return 0; | ||
97 | |||
98 | set_bit(EV_REP, input->evbit); | ||
99 | switch (usage->hid & HID_USAGE) { | ||
100 | case 0xff01: map_key_clear(BTN_1); break; | ||
101 | case 0xff02: map_key_clear(BTN_2); break; | ||
102 | case 0xff03: map_key_clear(BTN_3); break; | ||
103 | case 0xff04: map_key_clear(BTN_4); break; | ||
104 | case 0xff05: map_key_clear(BTN_5); break; | ||
105 | case 0xff06: map_key_clear(BTN_6); break; | ||
106 | case 0xff07: map_key_clear(BTN_7); break; | ||
107 | case 0xff08: map_key_clear(BTN_8); break; | ||
108 | case 0xff09: map_key_clear(BTN_9); break; | ||
109 | case 0xff0a: map_key_clear(BTN_A); break; | ||
110 | case 0xff0b: map_key_clear(BTN_B); break; | ||
111 | default: | ||
112 | return 0; | ||
113 | } | ||
114 | return 1; | ||
115 | } | ||
116 | |||
117 | static int quirk_microsoft_ergonomy_kb(struct hid_usage *usage, struct input_dev *input, | ||
118 | unsigned long **bit, int *max) | ||
119 | { | ||
120 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) | ||
121 | return 0; | ||
122 | |||
123 | switch(usage->hid & HID_USAGE) { | ||
124 | case 0xfd06: map_key_clear(KEY_CHAT); break; | ||
125 | case 0xfd07: map_key_clear(KEY_PHONE); break; | ||
126 | case 0xff05: | ||
127 | set_bit(EV_REP, input->evbit); | ||
128 | map_key_clear(KEY_F13); | ||
129 | set_bit(KEY_F14, input->keybit); | ||
130 | set_bit(KEY_F15, input->keybit); | ||
131 | set_bit(KEY_F16, input->keybit); | ||
132 | set_bit(KEY_F17, input->keybit); | ||
133 | set_bit(KEY_F18, input->keybit); | ||
134 | default: | ||
135 | return 0; | ||
136 | } | ||
137 | return 1; | ||
138 | } | ||
139 | |||
140 | static int quirk_microsoft_presenter_8k(struct hid_usage *usage, struct input_dev *input, | ||
141 | unsigned long **bit, int *max) | ||
142 | { | ||
143 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR) | ||
144 | return 0; | ||
145 | |||
146 | set_bit(EV_REP, input->evbit); | ||
147 | switch(usage->hid & HID_USAGE) { | ||
148 | case 0xfd08: map_key_clear(KEY_FORWARD); break; | ||
149 | case 0xfd09: map_key_clear(KEY_BACK); break; | ||
150 | case 0xfd0b: map_key_clear(KEY_PLAYPAUSE); break; | ||
151 | case 0xfd0e: map_key_clear(KEY_CLOSE); break; | ||
152 | case 0xfd0f: map_key_clear(KEY_PLAY); break; | ||
153 | default: | ||
154 | return 0; | ||
155 | } | ||
156 | return 1; | ||
157 | } | ||
158 | |||
159 | static int quirk_petalynx_remote(struct hid_usage *usage, struct input_dev *input, | ||
160 | unsigned long **bit, int *max) | ||
161 | { | ||
162 | if (((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR) && | ||
163 | ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER)) | ||
164 | return 0; | ||
165 | |||
166 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_LOGIVENDOR) | ||
167 | switch(usage->hid & HID_USAGE) { | ||
168 | case 0x05a: map_key_clear(KEY_TEXT); break; | ||
169 | case 0x05b: map_key_clear(KEY_RED); break; | ||
170 | case 0x05c: map_key_clear(KEY_GREEN); break; | ||
171 | case 0x05d: map_key_clear(KEY_YELLOW); break; | ||
172 | case 0x05e: map_key_clear(KEY_BLUE); break; | ||
173 | default: | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) | ||
178 | switch(usage->hid & HID_USAGE) { | ||
179 | case 0x0f6: map_key_clear(KEY_NEXT); break; | ||
180 | case 0x0fa: map_key_clear(KEY_BACK); break; | ||
181 | default: | ||
182 | return 0; | ||
183 | } | ||
184 | return 1; | ||
185 | } | ||
186 | |||
187 | static int quirk_logitech_wireless(struct hid_usage *usage, struct input_dev *input, | ||
188 | unsigned long **bit, int *max) | ||
189 | { | ||
190 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) | ||
191 | return 0; | ||
192 | |||
193 | switch (usage->hid & HID_USAGE) { | ||
194 | case 0x1001: map_key_clear(KEY_MESSENGER); break; | ||
195 | case 0x1003: map_key_clear(KEY_SOUND); break; | ||
196 | case 0x1004: map_key_clear(KEY_VIDEO); break; | ||
197 | case 0x1005: map_key_clear(KEY_AUDIO); break; | ||
198 | case 0x100a: map_key_clear(KEY_DOCUMENTS); break; | ||
199 | case 0x1011: map_key_clear(KEY_PREVIOUSSONG); break; | ||
200 | case 0x1012: map_key_clear(KEY_NEXTSONG); break; | ||
201 | case 0x1013: map_key_clear(KEY_CAMERA); break; | ||
202 | case 0x1014: map_key_clear(KEY_MESSENGER); break; | ||
203 | case 0x1015: map_key_clear(KEY_RECORD); break; | ||
204 | case 0x1016: map_key_clear(KEY_PLAYER); break; | ||
205 | case 0x1017: map_key_clear(KEY_EJECTCD); break; | ||
206 | case 0x1018: map_key_clear(KEY_MEDIA); break; | ||
207 | case 0x1019: map_key_clear(KEY_PROG1); break; | ||
208 | case 0x101a: map_key_clear(KEY_PROG2); break; | ||
209 | case 0x101b: map_key_clear(KEY_PROG3); break; | ||
210 | case 0x101f: map_key_clear(KEY_ZOOMIN); break; | ||
211 | case 0x1020: map_key_clear(KEY_ZOOMOUT); break; | ||
212 | case 0x1021: map_key_clear(KEY_ZOOMRESET); break; | ||
213 | case 0x1023: map_key_clear(KEY_CLOSE); break; | ||
214 | case 0x1027: map_key_clear(KEY_MENU); break; | ||
215 | /* this one is marked as 'Rotate' */ | ||
216 | case 0x1028: map_key_clear(KEY_ANGLE); break; | ||
217 | case 0x1029: map_key_clear(KEY_SHUFFLE); break; | ||
218 | case 0x102a: map_key_clear(KEY_BACK); break; | ||
219 | case 0x102b: map_key_clear(KEY_CYCLEWINDOWS); break; | ||
220 | case 0x1041: map_key_clear(KEY_BATTERY); break; | ||
221 | case 0x1042: map_key_clear(KEY_WORDPROCESSOR); break; | ||
222 | case 0x1043: map_key_clear(KEY_SPREADSHEET); break; | ||
223 | case 0x1044: map_key_clear(KEY_PRESENTATION); break; | ||
224 | case 0x1045: map_key_clear(KEY_UNDO); break; | ||
225 | case 0x1046: map_key_clear(KEY_REDO); break; | ||
226 | case 0x1047: map_key_clear(KEY_PRINT); break; | ||
227 | case 0x1048: map_key_clear(KEY_SAVE); break; | ||
228 | case 0x1049: map_key_clear(KEY_PROG1); break; | ||
229 | case 0x104a: map_key_clear(KEY_PROG2); break; | ||
230 | case 0x104b: map_key_clear(KEY_PROG3); break; | ||
231 | case 0x104c: map_key_clear(KEY_PROG4); break; | ||
232 | |||
233 | default: | ||
234 | return 0; | ||
235 | } | ||
236 | return 1; | ||
237 | } | ||
238 | |||
239 | static int quirk_cherry_genius_29e(struct hid_usage *usage, struct input_dev *input, | ||
240 | unsigned long **bit, int *max) | ||
241 | { | ||
242 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) | ||
243 | return 0; | ||
244 | |||
245 | switch (usage->hid & HID_USAGE) { | ||
246 | case 0x156: map_key_clear(KEY_WORDPROCESSOR); break; | ||
247 | case 0x157: map_key_clear(KEY_SPREADSHEET); break; | ||
248 | case 0x158: map_key_clear(KEY_PRESENTATION); break; | ||
249 | case 0x15c: map_key_clear(KEY_STOP); break; | ||
250 | |||
251 | default: | ||
252 | return 0; | ||
253 | } | ||
254 | return 1; | ||
255 | } | ||
256 | |||
257 | static int quirk_btc_8193(struct hid_usage *usage, struct input_dev *input, | ||
258 | unsigned long **bit, int *max) | ||
259 | { | ||
260 | if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) | ||
261 | return 0; | ||
262 | |||
263 | switch (usage->hid & HID_USAGE) { | ||
264 | case 0x230: map_key(BTN_MOUSE); break; | ||
265 | case 0x231: map_rel(REL_WHEEL); break; | ||
266 | /* | ||
267 | * this keyboard has a scrollwheel implemented in | ||
268 | * totally broken way. We map this usage temporarily | ||
269 | * to HWHEEL and handle it in the event quirk handler | ||
270 | */ | ||
271 | case 0x232: map_rel(REL_HWHEEL); break; | ||
272 | |||
273 | default: | ||
274 | return 0; | ||
275 | } | ||
276 | return 1; | ||
277 | } | ||
278 | |||
279 | #define VENDOR_ID_BELKIN 0x1020 | ||
280 | #define DEVICE_ID_BELKIN_WIRELESS_KEYBOARD 0x0006 | ||
281 | |||
282 | #define VENDOR_ID_CHERRY 0x046a | ||
283 | #define DEVICE_ID_CHERRY_CYMOTION 0x0023 | ||
284 | |||
285 | #define VENDOR_ID_CHICONY 0x04f2 | ||
286 | #define DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418 | ||
287 | |||
288 | #define VENDOR_ID_EZKEY 0x0518 | ||
289 | #define DEVICE_ID_BTC_8193 0x0002 | ||
290 | |||
291 | #define VENDOR_ID_LOGITECH 0x046d | ||
292 | #define DEVICE_ID_LOGITECH_RECEIVER 0xc101 | ||
293 | #define DEVICE_ID_S510_RECEIVER 0xc50c | ||
294 | #define DEVICE_ID_S510_RECEIVER_2 0xc517 | ||
295 | #define DEVICE_ID_MX3000_RECEIVER 0xc513 | ||
296 | |||
297 | #define VENDOR_ID_MICROSOFT 0x045e | ||
298 | #define DEVICE_ID_MS4K 0x00db | ||
299 | #define DEVICE_ID_MS6K 0x00f9 | ||
300 | #define DEVICE_IS_MS_PRESENTER_8K_BT 0x0701 | ||
301 | #define DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 | ||
302 | |||
303 | #define VENDOR_ID_MONTEREY 0x0566 | ||
304 | #define DEVICE_ID_GENIUS_KB29E 0x3004 | ||
305 | |||
306 | #define VENDOR_ID_PETALYNX 0x18b1 | ||
307 | #define DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037 | ||
308 | |||
309 | static const struct hid_input_blacklist { | ||
310 | __u16 idVendor; | ||
311 | __u16 idProduct; | ||
312 | int (*quirk)(struct hid_usage *, struct input_dev *, unsigned long **, int *); | ||
313 | } hid_input_blacklist[] = { | ||
314 | { VENDOR_ID_BELKIN, DEVICE_ID_BELKIN_WIRELESS_KEYBOARD, quirk_belkin_wkbd }, | ||
315 | |||
316 | { VENDOR_ID_CHERRY, DEVICE_ID_CHERRY_CYMOTION, quirk_cherry_cymotion }, | ||
317 | |||
318 | { VENDOR_ID_CHICONY, DEVICE_ID_CHICONY_TACTICAL_PAD, quirk_chicony_tactical_pad }, | ||
319 | |||
320 | { VENDOR_ID_EZKEY, DEVICE_ID_BTC_8193, quirk_btc_8193 }, | ||
321 | |||
322 | { VENDOR_ID_LOGITECH, DEVICE_ID_LOGITECH_RECEIVER, quirk_logitech_ultrax_remote }, | ||
323 | { VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER, quirk_logitech_wireless }, | ||
324 | { VENDOR_ID_LOGITECH, DEVICE_ID_S510_RECEIVER_2, quirk_logitech_wireless }, | ||
325 | { VENDOR_ID_LOGITECH, DEVICE_ID_MX3000_RECEIVER, quirk_logitech_wireless }, | ||
326 | |||
327 | { VENDOR_ID_MICROSOFT, DEVICE_ID_MS4K, quirk_microsoft_ergonomy_kb }, | ||
328 | { VENDOR_ID_MICROSOFT, DEVICE_ID_MS6K, quirk_microsoft_ergonomy_kb }, | ||
329 | { VENDOR_ID_MICROSOFT, DEVICE_IS_MS_PRESENTER_8K_BT, quirk_microsoft_presenter_8k }, | ||
330 | { VENDOR_ID_MICROSOFT, DEVICE_ID_MS_PRESENTER_8K_USB, quirk_microsoft_presenter_8k }, | ||
331 | |||
332 | { VENDOR_ID_MONTEREY, DEVICE_ID_GENIUS_KB29E, quirk_cherry_genius_29e }, | ||
333 | |||
334 | { VENDOR_ID_PETALYNX, DEVICE_ID_PETALYNX_MAXTER_REMOTE, quirk_petalynx_remote }, | ||
335 | |||
336 | { 0, 0, 0 } | ||
337 | }; | ||
338 | |||
339 | int hidinput_mapping_quirks(struct hid_usage *usage, | ||
340 | struct input_dev *input, | ||
341 | unsigned long **bit, int *max) | ||
342 | { | ||
343 | struct hid_device *device = input_get_drvdata(input); | ||
344 | int i = 0; | ||
345 | |||
346 | while (hid_input_blacklist[i].quirk) { | ||
347 | if (hid_input_blacklist[i].idVendor == device->vendor && | ||
348 | hid_input_blacklist[i].idProduct == device->product) | ||
349 | return hid_input_blacklist[i].quirk(usage, input, bit, max); | ||
350 | i++; | ||
351 | } | ||
352 | return 0; | ||
353 | } | ||
354 | |||
355 | void hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) | ||
356 | { | ||
357 | struct input_dev *input; | ||
358 | |||
359 | input = field->hidinput->input; | ||
360 | |||
361 | if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) | ||
362 | || ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) { | ||
363 | if (value) hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON; | ||
364 | else hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON; | ||
365 | return; | ||
366 | } | ||
367 | |||
368 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) && | ||
369 | (usage->type == EV_REL) && | ||
370 | (usage->code == REL_WHEEL)) { | ||
371 | hid->delayed_value = value; | ||
372 | return; | ||
373 | } | ||
374 | |||
375 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) && | ||
376 | (usage->hid == 0x000100b8)) { | ||
377 | input_event(input, EV_REL, value ? REL_HWHEEL : REL_WHEEL, hid->delayed_value); | ||
378 | return; | ||
379 | } | ||
380 | |||
381 | if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) { | ||
382 | input_event(input, usage->type, usage->code, -value); | ||
383 | return; | ||
384 | } | ||
385 | |||
386 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) { | ||
387 | input_event(input, usage->type, REL_HWHEEL, value); | ||
388 | return; | ||
389 | } | ||
390 | |||
391 | if ((hid->quirks & HID_QUIRK_APPLE_HAS_FN) && hidinput_apple_event(hid, input, usage, value)) | ||
392 | return; | ||
393 | |||
394 | /* Handling MS keyboards special buttons */ | ||
395 | if (hid->quirks & HID_QUIRK_MICROSOFT_KEYS && | ||
396 | usage->hid == (HID_UP_MSVENDOR | 0xff05)) { | ||
397 | int key = 0; | ||
398 | static int last_key = 0; | ||
399 | switch (value) { | ||
400 | case 0x01: key = KEY_F14; break; | ||
401 | case 0x02: key = KEY_F15; break; | ||
402 | case 0x04: key = KEY_F16; break; | ||
403 | case 0x08: key = KEY_F17; break; | ||
404 | case 0x10: key = KEY_F18; break; | ||
405 | default: break; | ||
406 | } | ||
407 | if (key) { | ||
408 | input_event(input, usage->type, key, 1); | ||
409 | last_key = key; | ||
410 | } else { | ||
411 | input_event(input, usage->type, last_key, 0); | ||
412 | } | ||
413 | } | ||
414 | |||
415 | /* handle the temporary quirky mapping to HWHEEL */ | ||
416 | if (hid->quirks & HID_QUIRK_HWHEEL_WHEEL_INVERT && | ||
417 | usage->type == EV_REL && usage->code == REL_HWHEEL) { | ||
418 | input_event(input, usage->type, REL_WHEEL, -value); | ||
419 | return; | ||
420 | } | ||
421 | } | ||
422 | |||
423 | |||
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 0b27da7d7497..5325d98b4328 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -34,10 +34,10 @@ | |||
34 | #include <linux/hid.h> | 34 | #include <linux/hid.h> |
35 | #include <linux/hid-debug.h> | 35 | #include <linux/hid-debug.h> |
36 | 36 | ||
37 | static int hid_pb_fnmode = 1; | 37 | static int hid_apple_fnmode = 1; |
38 | module_param_named(pb_fnmode, hid_pb_fnmode, int, 0644); | 38 | module_param_named(pb_fnmode, hid_apple_fnmode, int, 0644); |
39 | MODULE_PARM_DESC(pb_fnmode, | 39 | MODULE_PARM_DESC(pb_fnmode, |
40 | "Mode of fn key on PowerBooks (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)"); | 40 | "Mode of fn key on Apple keyboards (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)"); |
41 | 41 | ||
42 | #define unk KEY_UNKNOWN | 42 | #define unk KEY_UNKNOWN |
43 | 43 | ||
@@ -86,10 +86,6 @@ static const struct { | |||
86 | #define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0) | 86 | #define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0) |
87 | #define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0) | 87 | #define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0) |
88 | 88 | ||
89 | /* hardware needing special handling due to colliding MSVENDOR page usages */ | ||
90 | #define IS_CHICONY_TACTICAL_PAD(x) (x->vendor == 0x04f2 && device->product == 0x0418) | ||
91 | #define IS_MS_KB(x) (x->vendor == 0x045e && (x->product == 0x00db || x->product == 0x00f9)) | ||
92 | |||
93 | #ifdef CONFIG_USB_HIDINPUT_POWERBOOK | 89 | #ifdef CONFIG_USB_HIDINPUT_POWERBOOK |
94 | 90 | ||
95 | struct hidinput_key_translation { | 91 | struct hidinput_key_translation { |
@@ -98,20 +94,36 @@ struct hidinput_key_translation { | |||
98 | u8 flags; | 94 | u8 flags; |
99 | }; | 95 | }; |
100 | 96 | ||
101 | #define POWERBOOK_FLAG_FKEY 0x01 | 97 | #define APPLE_FLAG_FKEY 0x01 |
98 | |||
99 | static struct hidinput_key_translation apple_fn_keys[] = { | ||
100 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, | ||
101 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, | ||
102 | { KEY_F3, KEY_CYCLEWINDOWS, APPLE_FLAG_FKEY }, /* Exposé */ | ||
103 | { KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */ | ||
104 | { KEY_F5, KEY_FN_F5 }, | ||
105 | { KEY_F6, KEY_FN_F6 }, | ||
106 | { KEY_F7, KEY_BACK, APPLE_FLAG_FKEY }, | ||
107 | { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, | ||
108 | { KEY_F9, KEY_FORWARD, APPLE_FLAG_FKEY }, | ||
109 | { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY }, | ||
110 | { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, | ||
111 | { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, | ||
112 | { } | ||
113 | }; | ||
102 | 114 | ||
103 | static struct hidinput_key_translation powerbook_fn_keys[] = { | 115 | static struct hidinput_key_translation powerbook_fn_keys[] = { |
104 | { KEY_BACKSPACE, KEY_DELETE }, | 116 | { KEY_BACKSPACE, KEY_DELETE }, |
105 | { KEY_F1, KEY_BRIGHTNESSDOWN, POWERBOOK_FLAG_FKEY }, | 117 | { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, |
106 | { KEY_F2, KEY_BRIGHTNESSUP, POWERBOOK_FLAG_FKEY }, | 118 | { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, |
107 | { KEY_F3, KEY_MUTE, POWERBOOK_FLAG_FKEY }, | 119 | { KEY_F3, KEY_MUTE, APPLE_FLAG_FKEY }, |
108 | { KEY_F4, KEY_VOLUMEDOWN, POWERBOOK_FLAG_FKEY }, | 120 | { KEY_F4, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, |
109 | { KEY_F5, KEY_VOLUMEUP, POWERBOOK_FLAG_FKEY }, | 121 | { KEY_F5, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, |
110 | { KEY_F6, KEY_NUMLOCK, POWERBOOK_FLAG_FKEY }, | 122 | { KEY_F6, KEY_NUMLOCK, APPLE_FLAG_FKEY }, |
111 | { KEY_F7, KEY_SWITCHVIDEOMODE, POWERBOOK_FLAG_FKEY }, | 123 | { KEY_F7, KEY_SWITCHVIDEOMODE, APPLE_FLAG_FKEY }, |
112 | { KEY_F8, KEY_KBDILLUMTOGGLE, POWERBOOK_FLAG_FKEY }, | 124 | { KEY_F8, KEY_KBDILLUMTOGGLE, APPLE_FLAG_FKEY }, |
113 | { KEY_F9, KEY_KBDILLUMDOWN, POWERBOOK_FLAG_FKEY }, | 125 | { KEY_F9, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY }, |
114 | { KEY_F10, KEY_KBDILLUMUP, POWERBOOK_FLAG_FKEY }, | 126 | { KEY_F10, KEY_KBDILLUMUP, APPLE_FLAG_FKEY }, |
115 | { KEY_UP, KEY_PAGEUP }, | 127 | { KEY_UP, KEY_PAGEUP }, |
116 | { KEY_DOWN, KEY_PAGEDOWN }, | 128 | { KEY_DOWN, KEY_PAGEDOWN }, |
117 | { KEY_LEFT, KEY_HOME }, | 129 | { KEY_LEFT, KEY_HOME }, |
@@ -142,7 +154,7 @@ static struct hidinput_key_translation powerbook_numlock_keys[] = { | |||
142 | { } | 154 | { } |
143 | }; | 155 | }; |
144 | 156 | ||
145 | static struct hidinput_key_translation powerbook_iso_keyboard[] = { | 157 | static struct hidinput_key_translation apple_iso_keyboard[] = { |
146 | { KEY_GRAVE, KEY_102ND }, | 158 | { KEY_GRAVE, KEY_102ND }, |
147 | { KEY_102ND, KEY_GRAVE }, | 159 | { KEY_102ND, KEY_GRAVE }, |
148 | { } | 160 | { } |
@@ -160,39 +172,42 @@ static struct hidinput_key_translation *find_translation(struct hidinput_key_tra | |||
160 | return NULL; | 172 | return NULL; |
161 | } | 173 | } |
162 | 174 | ||
163 | static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, | 175 | int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, |
164 | struct hid_usage *usage, __s32 value) | 176 | struct hid_usage *usage, __s32 value) |
165 | { | 177 | { |
166 | struct hidinput_key_translation *trans; | 178 | struct hidinput_key_translation *trans; |
167 | 179 | ||
168 | if (usage->code == KEY_FN) { | 180 | if (usage->code == KEY_FN) { |
169 | if (value) hid->quirks |= HID_QUIRK_POWERBOOK_FN_ON; | 181 | if (value) hid->quirks |= HID_QUIRK_APPLE_FN_ON; |
170 | else hid->quirks &= ~HID_QUIRK_POWERBOOK_FN_ON; | 182 | else hid->quirks &= ~HID_QUIRK_APPLE_FN_ON; |
171 | 183 | ||
172 | input_event(input, usage->type, usage->code, value); | 184 | input_event(input, usage->type, usage->code, value); |
173 | 185 | ||
174 | return 1; | 186 | return 1; |
175 | } | 187 | } |
176 | 188 | ||
177 | if (hid_pb_fnmode) { | 189 | if (hid_apple_fnmode) { |
178 | int do_translate; | 190 | int do_translate; |
179 | 191 | ||
180 | trans = find_translation(powerbook_fn_keys, usage->code); | 192 | trans = find_translation((hid->product < 0x220 || |
193 | hid->product >= 0x300) ? | ||
194 | powerbook_fn_keys : apple_fn_keys, | ||
195 | usage->code); | ||
181 | if (trans) { | 196 | if (trans) { |
182 | if (test_bit(usage->code, hid->pb_pressed_fn)) | 197 | if (test_bit(usage->code, hid->apple_pressed_fn)) |
183 | do_translate = 1; | 198 | do_translate = 1; |
184 | else if (trans->flags & POWERBOOK_FLAG_FKEY) | 199 | else if (trans->flags & APPLE_FLAG_FKEY) |
185 | do_translate = | 200 | do_translate = |
186 | (hid_pb_fnmode == 2 && (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) || | 201 | (hid_apple_fnmode == 2 && (hid->quirks & HID_QUIRK_APPLE_FN_ON)) || |
187 | (hid_pb_fnmode == 1 && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)); | 202 | (hid_apple_fnmode == 1 && !(hid->quirks & HID_QUIRK_APPLE_FN_ON)); |
188 | else | 203 | else |
189 | do_translate = (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON); | 204 | do_translate = (hid->quirks & HID_QUIRK_APPLE_FN_ON); |
190 | 205 | ||
191 | if (do_translate) { | 206 | if (do_translate) { |
192 | if (value) | 207 | if (value) |
193 | set_bit(usage->code, hid->pb_pressed_fn); | 208 | set_bit(usage->code, hid->apple_pressed_fn); |
194 | else | 209 | else |
195 | clear_bit(usage->code, hid->pb_pressed_fn); | 210 | clear_bit(usage->code, hid->apple_pressed_fn); |
196 | 211 | ||
197 | input_event(input, usage->type, trans->to, value); | 212 | input_event(input, usage->type, trans->to, value); |
198 | 213 | ||
@@ -217,8 +232,8 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, | |||
217 | } | 232 | } |
218 | } | 233 | } |
219 | 234 | ||
220 | if (hid->quirks & HID_QUIRK_POWERBOOK_ISO_KEYBOARD) { | 235 | if (hid->quirks & HID_QUIRK_APPLE_ISO_KEYBOARD) { |
221 | trans = find_translation(powerbook_iso_keyboard, usage->code); | 236 | trans = find_translation(apple_iso_keyboard, usage->code); |
222 | if (trans) { | 237 | if (trans) { |
223 | input_event(input, usage->type, trans->to, value); | 238 | input_event(input, usage->type, trans->to, value); |
224 | return 1; | 239 | return 1; |
@@ -228,31 +243,35 @@ static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, | |||
228 | return 0; | 243 | return 0; |
229 | } | 244 | } |
230 | 245 | ||
231 | static void hidinput_pb_setup(struct input_dev *input) | 246 | static void hidinput_apple_setup(struct input_dev *input) |
232 | { | 247 | { |
233 | struct hidinput_key_translation *trans; | 248 | struct hidinput_key_translation *trans; |
234 | 249 | ||
235 | set_bit(KEY_NUMLOCK, input->keybit); | 250 | set_bit(KEY_NUMLOCK, input->keybit); |
236 | 251 | ||
237 | /* Enable all needed keys */ | 252 | /* Enable all needed keys */ |
253 | for (trans = apple_fn_keys; trans->from; trans++) | ||
254 | set_bit(trans->to, input->keybit); | ||
255 | |||
238 | for (trans = powerbook_fn_keys; trans->from; trans++) | 256 | for (trans = powerbook_fn_keys; trans->from; trans++) |
239 | set_bit(trans->to, input->keybit); | 257 | set_bit(trans->to, input->keybit); |
240 | 258 | ||
241 | for (trans = powerbook_numlock_keys; trans->from; trans++) | 259 | for (trans = powerbook_numlock_keys; trans->from; trans++) |
242 | set_bit(trans->to, input->keybit); | 260 | set_bit(trans->to, input->keybit); |
243 | 261 | ||
244 | for (trans = powerbook_iso_keyboard; trans->from; trans++) | 262 | for (trans = apple_iso_keyboard; trans->from; trans++) |
245 | set_bit(trans->to, input->keybit); | 263 | set_bit(trans->to, input->keybit); |
246 | 264 | ||
247 | } | 265 | } |
248 | #else | 266 | #else |
249 | static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, | 267 | inline int hidinput_apple_event(struct hid_device *hid, |
250 | struct hid_usage *usage, __s32 value) | 268 | struct input_dev *input, |
269 | struct hid_usage *usage, __s32 value) | ||
251 | { | 270 | { |
252 | return 0; | 271 | return 0; |
253 | } | 272 | } |
254 | 273 | ||
255 | static inline void hidinput_pb_setup(struct input_dev *input) | 274 | static inline void hidinput_apple_setup(struct input_dev *input) |
256 | { | 275 | { |
257 | } | 276 | } |
258 | #endif | 277 | #endif |
@@ -343,7 +362,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
343 | { | 362 | { |
344 | struct input_dev *input = hidinput->input; | 363 | struct input_dev *input = hidinput->input; |
345 | struct hid_device *device = input_get_drvdata(input); | 364 | struct hid_device *device = input_get_drvdata(input); |
346 | int max = 0, code; | 365 | int max = 0, code, ret; |
347 | unsigned long *bit = NULL; | 366 | unsigned long *bit = NULL; |
348 | 367 | ||
349 | field->hidinput = hidinput; | 368 | field->hidinput = hidinput; |
@@ -362,6 +381,11 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
362 | goto ignore; | 381 | goto ignore; |
363 | } | 382 | } |
364 | 383 | ||
384 | /* handle input mappings for quirky devices */ | ||
385 | ret = hidinput_mapping_quirks(usage, input, &bit, &max); | ||
386 | if (ret) | ||
387 | goto mapped; | ||
388 | |||
365 | switch (usage->hid & HID_USAGE_PAGE) { | 389 | switch (usage->hid & HID_USAGE_PAGE) { |
366 | 390 | ||
367 | case HID_UP_UNDEFINED: | 391 | case HID_UP_UNDEFINED: |
@@ -549,14 +573,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
549 | case 0x000: goto ignore; | 573 | case 0x000: goto ignore; |
550 | case 0x034: map_key_clear(KEY_SLEEP); break; | 574 | case 0x034: map_key_clear(KEY_SLEEP); break; |
551 | case 0x036: map_key_clear(BTN_MISC); break; | 575 | case 0x036: map_key_clear(BTN_MISC); break; |
552 | /* | ||
553 | * The next three are reported by Belkin wireless | ||
554 | * keyboard (1020:0006). These values are "reserved" | ||
555 | * in HUT 1.12. | ||
556 | */ | ||
557 | case 0x03a: map_key_clear(KEY_SOUND); break; | ||
558 | case 0x03b: map_key_clear(KEY_CAMERA); break; | ||
559 | case 0x03c: map_key_clear(KEY_DOCUMENTS); break; | ||
560 | 576 | ||
561 | case 0x040: map_key_clear(KEY_MENU); break; | 577 | case 0x040: map_key_clear(KEY_MENU); break; |
562 | case 0x045: map_key_clear(KEY_RADIO); break; | 578 | case 0x045: map_key_clear(KEY_RADIO); break; |
@@ -602,10 +618,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
602 | case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; | 618 | case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; |
603 | case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; | 619 | case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; |
604 | 620 | ||
605 | /* reserved in HUT 1.12. Reported on Petalynx remote */ | ||
606 | case 0x0f6: map_key_clear(KEY_NEXT); break; | ||
607 | case 0x0fa: map_key_clear(KEY_BACK); break; | ||
608 | |||
609 | case 0x182: map_key_clear(KEY_BOOKMARKS); break; | 621 | case 0x182: map_key_clear(KEY_BOOKMARKS); break; |
610 | case 0x183: map_key_clear(KEY_CONFIG); break; | 622 | case 0x183: map_key_clear(KEY_CONFIG); break; |
611 | case 0x184: map_key_clear(KEY_WORDPROCESSOR); break; | 623 | case 0x184: map_key_clear(KEY_WORDPROCESSOR); break; |
@@ -665,51 +677,6 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
665 | case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; | 677 | case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; |
666 | case 0x28c: map_key_clear(KEY_SEND); break; | 678 | case 0x28c: map_key_clear(KEY_SEND); break; |
667 | 679 | ||
668 | /* Reported on a Cherry Cymotion keyboard */ | ||
669 | case 0x301: map_key_clear(KEY_PROG1); break; | ||
670 | case 0x302: map_key_clear(KEY_PROG2); break; | ||
671 | case 0x303: map_key_clear(KEY_PROG3); break; | ||
672 | |||
673 | /* Reported on certain Logitech wireless keyboards */ | ||
674 | case 0x1001: map_key_clear(KEY_MESSENGER); break; | ||
675 | case 0x1003: map_key_clear(KEY_SOUND); break; | ||
676 | case 0x1004: map_key_clear(KEY_VIDEO); break; | ||
677 | case 0x1005: map_key_clear(KEY_AUDIO); break; | ||
678 | case 0x100a: map_key_clear(KEY_DOCUMENTS); break; | ||
679 | case 0x1011: map_key_clear(KEY_PREVIOUSSONG); break; | ||
680 | case 0x1012: map_key_clear(KEY_NEXTSONG); break; | ||
681 | case 0x1013: map_key_clear(KEY_CAMERA); break; | ||
682 | case 0x1014: map_key_clear(KEY_MESSENGER); break; | ||
683 | case 0x1015: map_key_clear(KEY_RECORD); break; | ||
684 | case 0x1016: map_key_clear(KEY_PLAYER); break; | ||
685 | case 0x1017: map_key_clear(KEY_EJECTCD); break; | ||
686 | case 0x1018: map_key_clear(KEY_MEDIA); break; | ||
687 | case 0x1019: map_key_clear(KEY_PROG1); break; | ||
688 | case 0x101a: map_key_clear(KEY_PROG2); break; | ||
689 | case 0x101b: map_key_clear(KEY_PROG3); break; | ||
690 | case 0x101f: map_key_clear(KEY_ZOOMIN); break; | ||
691 | case 0x1020: map_key_clear(KEY_ZOOMOUT); break; | ||
692 | case 0x1021: map_key_clear(KEY_ZOOMRESET); break; | ||
693 | case 0x1023: map_key_clear(KEY_CLOSE); break; | ||
694 | case 0x1027: map_key_clear(KEY_MENU); break; | ||
695 | /* this one is marked as 'Rotate' */ | ||
696 | case 0x1028: map_key_clear(KEY_ANGLE); break; | ||
697 | case 0x1029: map_key_clear(KEY_SHUFFLE); break; | ||
698 | case 0x102a: map_key_clear(KEY_BACK); break; | ||
699 | case 0x102b: map_key_clear(KEY_CYCLEWINDOWS); break; | ||
700 | case 0x1041: map_key_clear(KEY_BATTERY); break; | ||
701 | case 0x1042: map_key_clear(KEY_WORDPROCESSOR); break; | ||
702 | case 0x1043: map_key_clear(KEY_SPREADSHEET); break; | ||
703 | case 0x1044: map_key_clear(KEY_PRESENTATION); break; | ||
704 | case 0x1045: map_key_clear(KEY_UNDO); break; | ||
705 | case 0x1046: map_key_clear(KEY_REDO); break; | ||
706 | case 0x1047: map_key_clear(KEY_PRINT); break; | ||
707 | case 0x1048: map_key_clear(KEY_SAVE); break; | ||
708 | case 0x1049: map_key_clear(KEY_PROG1); break; | ||
709 | case 0x104a: map_key_clear(KEY_PROG2); break; | ||
710 | case 0x104b: map_key_clear(KEY_PROG3); break; | ||
711 | case 0x104c: map_key_clear(KEY_PROG4); break; | ||
712 | |||
713 | default: goto ignore; | 680 | default: goto ignore; |
714 | } | 681 | } |
715 | break; | 682 | break; |
@@ -736,63 +703,16 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
736 | 703 | ||
737 | case HID_UP_MSVENDOR: | 704 | case HID_UP_MSVENDOR: |
738 | 705 | ||
739 | /* Unfortunately, there are multiple devices which | 706 | goto ignore; |
740 | * emit usages from MSVENDOR page that require different | ||
741 | * handling. If this list grows too much in the future, | ||
742 | * more general handling will have to be introduced here | ||
743 | * (i.e. another blacklist). | ||
744 | */ | ||
745 | |||
746 | /* Chicony Chicony KU-0418 tactical pad */ | ||
747 | if (IS_CHICONY_TACTICAL_PAD(device)) { | ||
748 | set_bit(EV_REP, input->evbit); | ||
749 | switch(usage->hid & HID_USAGE) { | ||
750 | case 0xff01: map_key_clear(BTN_1); break; | ||
751 | case 0xff02: map_key_clear(BTN_2); break; | ||
752 | case 0xff03: map_key_clear(BTN_3); break; | ||
753 | case 0xff04: map_key_clear(BTN_4); break; | ||
754 | case 0xff05: map_key_clear(BTN_5); break; | ||
755 | case 0xff06: map_key_clear(BTN_6); break; | ||
756 | case 0xff07: map_key_clear(BTN_7); break; | ||
757 | case 0xff08: map_key_clear(BTN_8); break; | ||
758 | case 0xff09: map_key_clear(BTN_9); break; | ||
759 | case 0xff0a: map_key_clear(BTN_A); break; | ||
760 | case 0xff0b: map_key_clear(BTN_B); break; | ||
761 | default: goto ignore; | ||
762 | } | ||
763 | |||
764 | /* Microsoft Natural Ergonomic Keyboard 4000 */ | ||
765 | } else if (IS_MS_KB(device)) { | ||
766 | switch(usage->hid & HID_USAGE) { | ||
767 | case 0xfd06: | ||
768 | map_key_clear(KEY_CHAT); | ||
769 | break; | ||
770 | case 0xfd07: | ||
771 | map_key_clear(KEY_PHONE); | ||
772 | break; | ||
773 | case 0xff05: | ||
774 | set_bit(EV_REP, input->evbit); | ||
775 | map_key_clear(KEY_F13); | ||
776 | set_bit(KEY_F14, input->keybit); | ||
777 | set_bit(KEY_F15, input->keybit); | ||
778 | set_bit(KEY_F16, input->keybit); | ||
779 | set_bit(KEY_F17, input->keybit); | ||
780 | set_bit(KEY_F18, input->keybit); | ||
781 | default: goto ignore; | ||
782 | } | ||
783 | } else { | ||
784 | goto ignore; | ||
785 | } | ||
786 | break; | ||
787 | 707 | ||
788 | case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */ | 708 | case HID_UP_CUSTOM: /* Reported on Logitech and Apple USB keyboards */ |
789 | 709 | ||
790 | set_bit(EV_REP, input->evbit); | 710 | set_bit(EV_REP, input->evbit); |
791 | switch(usage->hid & HID_USAGE) { | 711 | switch(usage->hid & HID_USAGE) { |
792 | case 0x003: | 712 | case 0x003: |
793 | /* The fn key on Apple PowerBooks */ | 713 | /* The fn key on Apple USB keyboards */ |
794 | map_key_clear(KEY_FN); | 714 | map_key_clear(KEY_FN); |
795 | hidinput_pb_setup(input); | 715 | hidinput_apple_setup(input); |
796 | break; | 716 | break; |
797 | 717 | ||
798 | default: goto ignore; | 718 | default: goto ignore; |
@@ -800,38 +720,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
800 | break; | 720 | break; |
801 | 721 | ||
802 | case HID_UP_LOGIVENDOR: | 722 | case HID_UP_LOGIVENDOR: |
803 | set_bit(EV_REP, input->evbit); | ||
804 | switch(usage->hid & HID_USAGE) { | ||
805 | /* Reported on Logitech Ultra X Media Remote */ | ||
806 | case 0x004: map_key_clear(KEY_AGAIN); break; | ||
807 | case 0x00d: map_key_clear(KEY_HOME); break; | ||
808 | case 0x024: map_key_clear(KEY_SHUFFLE); break; | ||
809 | case 0x025: map_key_clear(KEY_TV); break; | ||
810 | case 0x026: map_key_clear(KEY_MENU); break; | ||
811 | case 0x031: map_key_clear(KEY_AUDIO); break; | ||
812 | case 0x032: map_key_clear(KEY_TEXT); break; | ||
813 | case 0x033: map_key_clear(KEY_LAST); break; | ||
814 | case 0x047: map_key_clear(KEY_MP3); break; | ||
815 | case 0x048: map_key_clear(KEY_DVD); break; | ||
816 | case 0x049: map_key_clear(KEY_MEDIA); break; | ||
817 | case 0x04a: map_key_clear(KEY_VIDEO); break; | ||
818 | case 0x04b: map_key_clear(KEY_ANGLE); break; | ||
819 | case 0x04c: map_key_clear(KEY_LANGUAGE); break; | ||
820 | case 0x04d: map_key_clear(KEY_SUBTITLE); break; | ||
821 | case 0x051: map_key_clear(KEY_RED); break; | ||
822 | case 0x052: map_key_clear(KEY_CLOSE); break; | ||
823 | |||
824 | /* Reported on Petalynx Maxter remote */ | ||
825 | case 0x05a: map_key_clear(KEY_TEXT); break; | ||
826 | case 0x05b: map_key_clear(KEY_RED); break; | ||
827 | case 0x05c: map_key_clear(KEY_GREEN); break; | ||
828 | case 0x05d: map_key_clear(KEY_YELLOW); break; | ||
829 | case 0x05e: map_key_clear(KEY_BLUE); break; | ||
830 | |||
831 | default: goto ignore; | ||
832 | } | ||
833 | break; | ||
834 | 723 | ||
724 | goto ignore; | ||
725 | |||
835 | case HID_UP_PID: | 726 | case HID_UP_PID: |
836 | 727 | ||
837 | switch(usage->hid & HID_USAGE) { | 728 | switch(usage->hid & HID_USAGE) { |
@@ -858,6 +749,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
858 | break; | 749 | break; |
859 | } | 750 | } |
860 | 751 | ||
752 | mapped: | ||
861 | if (device->quirks & HID_QUIRK_MIGHTYMOUSE) { | 753 | if (device->quirks & HID_QUIRK_MIGHTYMOUSE) { |
862 | if (usage->hid == HID_GD_Z) | 754 | if (usage->hid == HID_GD_Z) |
863 | map_rel(REL_HWHEEL); | 755 | map_rel(REL_HWHEEL); |
@@ -867,9 +759,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel | |||
867 | map_key(BTN_1); | 759 | map_key(BTN_1); |
868 | } | 760 | } |
869 | 761 | ||
870 | if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) && | 762 | if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5 | |
871 | (usage->type == EV_REL) && (usage->code == REL_WHEEL)) | 763 | HID_QUIRK_2WHEEL_MOUSE_HACK_B8)) && (usage->type == EV_REL) && |
872 | set_bit(REL_HWHEEL, bit); | 764 | (usage->code == REL_WHEEL)) |
765 | set_bit(REL_HWHEEL, bit); | ||
873 | 766 | ||
874 | if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) | 767 | if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) |
875 | || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) | 768 | || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) |
@@ -960,25 +853,8 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct | |||
960 | if (!usage->type) | 853 | if (!usage->type) |
961 | return; | 854 | return; |
962 | 855 | ||
963 | if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) | 856 | /* handle input events for quirky devices */ |
964 | || ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) { | 857 | hidinput_event_quirks(hid, field, usage, value); |
965 | if (value) hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON; | ||
966 | else hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON; | ||
967 | return; | ||
968 | } | ||
969 | |||
970 | if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) { | ||
971 | input_event(input, usage->type, usage->code, -value); | ||
972 | return; | ||
973 | } | ||
974 | |||
975 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) { | ||
976 | input_event(input, usage->type, REL_HWHEEL, value); | ||
977 | return; | ||
978 | } | ||
979 | |||
980 | if ((hid->quirks & HID_QUIRK_POWERBOOK_HAS_FN) && hidinput_pb_event(hid, input, usage, value)) | ||
981 | return; | ||
982 | 858 | ||
983 | if (usage->hat_min < usage->hat_max || usage->hat_dir) { | 859 | if (usage->hat_min < usage->hat_max || usage->hat_dir) { |
984 | int hat_dir = usage->hat_dir; | 860 | int hat_dir = usage->hat_dir; |
@@ -1039,25 +915,6 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct | |||
1039 | return; | 915 | return; |
1040 | } | 916 | } |
1041 | 917 | ||
1042 | /* Handling MS keyboards special buttons */ | ||
1043 | if (IS_MS_KB(hid) && usage->hid == (HID_UP_MSVENDOR | 0xff05)) { | ||
1044 | int key = 0; | ||
1045 | static int last_key = 0; | ||
1046 | switch (value) { | ||
1047 | case 0x01: key = KEY_F14; break; | ||
1048 | case 0x02: key = KEY_F15; break; | ||
1049 | case 0x04: key = KEY_F16; break; | ||
1050 | case 0x08: key = KEY_F17; break; | ||
1051 | case 0x10: key = KEY_F18; break; | ||
1052 | default: break; | ||
1053 | } | ||
1054 | if (key) { | ||
1055 | input_event(input, usage->type, key, 1); | ||
1056 | last_key = key; | ||
1057 | } else { | ||
1058 | input_event(input, usage->type, last_key, 0); | ||
1059 | } | ||
1060 | } | ||
1061 | /* report the usage code as scancode if the key status has changed */ | 918 | /* report the usage code as scancode if the key status has changed */ |
1062 | if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value) | 919 | if (usage->type == EV_KEY && !!test_bit(usage->code, input->key) != value) |
1063 | input_event(input, EV_MSC, MSC_SCAN, usage->hid); | 920 | input_event(input, EV_MSC, MSC_SCAN, usage->hid); |
diff --git a/drivers/hid/usbhid/Kconfig b/drivers/hid/usbhid/Kconfig index c557d7040a69..7160fa65d79b 100644 --- a/drivers/hid/usbhid/Kconfig +++ b/drivers/hid/usbhid/Kconfig | |||
@@ -25,12 +25,13 @@ comment "Input core support is needed for USB HID input layer or HIDBP support" | |||
25 | depends on USB_HID && INPUT=n | 25 | depends on USB_HID && INPUT=n |
26 | 26 | ||
27 | config USB_HIDINPUT_POWERBOOK | 27 | config USB_HIDINPUT_POWERBOOK |
28 | bool "Enable support for iBook/PowerBook/MacBook/MacBookPro special keys" | 28 | bool "Enable support for Apple laptop/aluminum USB special keys" |
29 | default n | 29 | default n |
30 | depends on USB_HID | 30 | depends on USB_HID |
31 | help | 31 | help |
32 | Say Y here if you want support for the special keys (Fn, Numlock) on | 32 | Say Y here if you want support for the special keys (Fn, Numlock) on |
33 | Apple iBooks, PowerBooks, MacBooks and MacBook Pros. | 33 | Apple iBooks, PowerBooks, MacBooks, MacBook Pros and aluminum USB |
34 | keyboards. | ||
34 | 35 | ||
35 | If unsure, say N. | 36 | If unsure, say N. |
36 | 37 | ||
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index a2552856476b..b77b61e0cd7b 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #define USB_VENDOR_ID_A4TECH 0x09da | 20 | #define USB_VENDOR_ID_A4TECH 0x09da |
21 | #define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 | 21 | #define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 |
22 | #define USB_DEVICE_ID_A4TECH_X5_005D 0x000a | ||
22 | 23 | ||
23 | #define USB_VENDOR_ID_AASHIMA 0x06d6 | 24 | #define USB_VENDOR_ID_AASHIMA 0x06d6 |
24 | #define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 | 25 | #define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 |
@@ -28,6 +29,9 @@ | |||
28 | #define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 | 29 | #define USB_DEVICE_ID_ACECAD_FLAIR 0x0004 |
29 | #define USB_DEVICE_ID_ACECAD_302 0x0008 | 30 | #define USB_DEVICE_ID_ACECAD_302 0x0008 |
30 | 31 | ||
32 | #define USB_VENDOR_ID_ADS_TECH 0x06e1 | ||
33 | #define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155 | ||
34 | |||
31 | #define USB_VENDOR_ID_AIPTEK 0x08ca | 35 | #define USB_VENDOR_ID_AIPTEK 0x08ca |
32 | #define USB_DEVICE_ID_AIPTEK_01 0x0001 | 36 | #define USB_DEVICE_ID_AIPTEK_01 0x0001 |
33 | #define USB_DEVICE_ID_AIPTEK_10 0x0010 | 37 | #define USB_DEVICE_ID_AIPTEK_10 0x0010 |
@@ -59,6 +63,9 @@ | |||
59 | #define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a | 63 | #define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a |
60 | #define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b | 64 | #define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b |
61 | #define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c | 65 | #define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c |
66 | #define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220 | ||
67 | #define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221 | ||
68 | #define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222 | ||
62 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a | 69 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a |
63 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b | 70 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b |
64 | #define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 | 71 | #define USB_DEVICE_ID_APPLE_IRCONTROL4 0x8242 |
@@ -94,6 +101,9 @@ | |||
94 | #define USB_DEVICE_ID_CODEMERCS_IOW_FIRST 0x1500 | 101 | #define USB_DEVICE_ID_CODEMERCS_IOW_FIRST 0x1500 |
95 | #define USB_DEVICE_ID_CODEMERCS_IOW_LAST 0x15ff | 102 | #define USB_DEVICE_ID_CODEMERCS_IOW_LAST 0x15ff |
96 | 103 | ||
104 | #define USB_VENDOR_ID_CYGNAL 0x10c4 | ||
105 | #define USB_DEVICE_ID_CYGNAL_RADIO_SI470X 0x818a | ||
106 | |||
97 | #define USB_VENDOR_ID_CYPRESS 0x04b4 | 107 | #define USB_VENDOR_ID_CYPRESS 0x04b4 |
98 | #define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 | 108 | #define USB_DEVICE_ID_CYPRESS_MOUSE 0x0001 |
99 | #define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 | 109 | #define USB_DEVICE_ID_CYPRESS_HIDCOM 0x5500 |
@@ -114,6 +124,9 @@ | |||
114 | #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f | 124 | #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f |
115 | #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 | 125 | #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 |
116 | 126 | ||
127 | #define USB_VENDOR_ID_EZKEY 0x0518 | ||
128 | #define USB_DEVICE_ID_BTC_8193 0x0002 | ||
129 | |||
117 | #define USB_VENDOR_ID_GAMERON 0x0810 | 130 | #define USB_VENDOR_ID_GAMERON 0x0810 |
118 | #define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001 | 131 | #define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001 |
119 | 132 | ||
@@ -134,6 +147,9 @@ | |||
134 | #define USB_DEVICE_ID_GOGOPEN 0x00ce | 147 | #define USB_DEVICE_ID_GOGOPEN 0x00ce |
135 | #define USB_DEVICE_ID_PENPOWER 0x00f4 | 148 | #define USB_DEVICE_ID_PENPOWER 0x00f4 |
136 | 149 | ||
150 | #define USB_VENDOR_ID_GRETAGMACBETH 0x0971 | ||
151 | #define USB_DEVICE_ID_GRETAGMACBETH_HUEY 0x2005 | ||
152 | |||
137 | #define USB_VENDOR_ID_GRIFFIN 0x077d | 153 | #define USB_VENDOR_ID_GRIFFIN 0x077d |
138 | #define USB_DEVICE_ID_POWERMATE 0x0410 | 154 | #define USB_DEVICE_ID_POWERMATE 0x0410 |
139 | #define USB_DEVICE_ID_SOUNDKNOB 0x04AA | 155 | #define USB_DEVICE_ID_SOUNDKNOB 0x04AA |
@@ -278,7 +294,9 @@ | |||
278 | #define USB_DEVICE_ID_LOGITECH_HARMONY_62 0xc14d | 294 | #define USB_DEVICE_ID_LOGITECH_HARMONY_62 0xc14d |
279 | #define USB_DEVICE_ID_LOGITECH_HARMONY_63 0xc14e | 295 | #define USB_DEVICE_ID_LOGITECH_HARMONY_63 0xc14e |
280 | #define USB_DEVICE_ID_LOGITECH_HARMONY_64 0xc14f | 296 | #define USB_DEVICE_ID_LOGITECH_HARMONY_64 0xc14f |
297 | #define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215 | ||
281 | #define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 | 298 | #define USB_DEVICE_ID_LOGITECH_WHEEL 0xc294 |
299 | #define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a | ||
282 | #define USB_DEVICE_ID_LOGITECH_KBD 0xc311 | 300 | #define USB_DEVICE_ID_LOGITECH_KBD 0xc311 |
283 | #define USB_DEVICE_ID_S510_RECEIVER 0xc50c | 301 | #define USB_DEVICE_ID_S510_RECEIVER 0xc50c |
284 | #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 | 302 | #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 |
@@ -296,6 +314,12 @@ | |||
296 | 314 | ||
297 | #define USB_VENDOR_ID_MICROSOFT 0x045e | 315 | #define USB_VENDOR_ID_MICROSOFT 0x045e |
298 | #define USB_DEVICE_ID_SIDEWINDER_GV 0x003b | 316 | #define USB_DEVICE_ID_SIDEWINDER_GV 0x003b |
317 | #define USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0 0x009d | ||
318 | #define USB_DEVICE_ID_MS_NE4K 0x00db | ||
319 | #define USB_DEVICE_ID_MS_LK6K 0x00f9 | ||
320 | |||
321 | #define USB_VENDOR_ID_MONTEREY 0x0566 | ||
322 | #define USB_DEVICE_ID_GENIUS_KB29E 0x3004 | ||
299 | 323 | ||
300 | #define USB_VENDOR_ID_NCR 0x0404 | 324 | #define USB_VENDOR_ID_NCR 0x0404 |
301 | #define USB_DEVICE_ID_NCR_FIRST 0x0300 | 325 | #define USB_DEVICE_ID_NCR_FIRST 0x0300 |
@@ -324,6 +348,9 @@ | |||
324 | #define USB_VENDOR_ID_SAITEK 0x06a3 | 348 | #define USB_VENDOR_ID_SAITEK 0x06a3 |
325 | #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 | 349 | #define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 |
326 | 350 | ||
351 | #define USB_VENDOR_ID_SAMSUNG 0x0419 | ||
352 | #define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 | ||
353 | |||
327 | #define USB_VENDOR_ID_SONY 0x054c | 354 | #define USB_VENDOR_ID_SONY 0x054c |
328 | #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 | 355 | #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 |
329 | 356 | ||
@@ -368,6 +395,7 @@ static const struct hid_blacklist { | |||
368 | } hid_blacklist[] = { | 395 | } hid_blacklist[] = { |
369 | 396 | ||
370 | { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, | 397 | { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, |
398 | { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D, HID_QUIRK_2WHEEL_MOUSE_HACK_B8 }, | ||
371 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, | 399 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE, HID_QUIRK_2WHEEL_MOUSE_HACK_5 }, |
372 | 400 | ||
373 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER, HID_QUIRK_BAD_RELATIVE_KEYS }, | 401 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER, HID_QUIRK_BAD_RELATIVE_KEYS }, |
@@ -390,6 +418,9 @@ static const struct hid_blacklist { | |||
390 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT }, | 418 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT }, |
391 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV, HID_QUIRK_HIDINPUT }, | 419 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV, HID_QUIRK_HIDINPUT }, |
392 | 420 | ||
421 | { USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193, HID_QUIRK_HWHEEL_WHEEL_INVERT }, | ||
422 | |||
423 | { USB_VENDOR_ID_ADS_TECH, USB_DEVICE_ID_ADS_TECH_RADIO_SI470X, HID_QUIRK_IGNORE }, | ||
393 | { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE }, | 424 | { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_01, HID_QUIRK_IGNORE }, |
394 | { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE }, | 425 | { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_10, HID_QUIRK_IGNORE }, |
395 | { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20, HID_QUIRK_IGNORE }, | 426 | { USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_20, HID_QUIRK_IGNORE }, |
@@ -402,6 +433,7 @@ static const struct hid_blacklist { | |||
402 | { USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM, HID_QUIRK_IGNORE}, | 433 | { USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_LCM, HID_QUIRK_IGNORE}, |
403 | { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, | 434 | { USB_VENDOR_ID_BERKSHIRE, USB_DEVICE_ID_BERKSHIRE_PCWD, HID_QUIRK_IGNORE }, |
404 | { USB_VENDOR_ID_CIDC, 0x0103, HID_QUIRK_IGNORE }, | 435 | { USB_VENDOR_ID_CIDC, 0x0103, HID_QUIRK_IGNORE }, |
436 | { USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_RADIO_SI470X, HID_QUIRK_IGNORE }, | ||
405 | { USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109, HID_QUIRK_IGNORE }, | 437 | { USB_VENDOR_ID_CMEDIA, USB_DEVICE_ID_CM109, HID_QUIRK_IGNORE }, |
406 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, | 438 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, |
407 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE, HID_QUIRK_IGNORE }, | 439 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_ULTRAMOUSE, HID_QUIRK_IGNORE }, |
@@ -423,6 +455,7 @@ static const struct hid_blacklist { | |||
423 | { USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_SUPER_Q2, HID_QUIRK_IGNORE }, | 455 | { USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_SUPER_Q2, HID_QUIRK_IGNORE }, |
424 | { USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_GOGOPEN, HID_QUIRK_IGNORE }, | 456 | { USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_GOGOPEN, HID_QUIRK_IGNORE }, |
425 | { USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_PENPOWER, HID_QUIRK_IGNORE }, | 457 | { USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_PENPOWER, HID_QUIRK_IGNORE }, |
458 | { USB_VENDOR_ID_GRETAGMACBETH, USB_DEVICE_ID_GRETAGMACBETH_HUEY, HID_QUIRK_IGNORE }, | ||
426 | { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, | 459 | { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, |
427 | { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, | 460 | { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, |
428 | { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_90, HID_QUIRK_IGNORE }, | 461 | { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_90, HID_QUIRK_IGNORE }, |
@@ -516,14 +549,18 @@ static const struct hid_blacklist { | |||
516 | { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE }, | 549 | { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_FLAIR, HID_QUIRK_IGNORE }, |
517 | { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE }, | 550 | { USB_VENDOR_ID_ACECAD, USB_DEVICE_ID_ACECAD_302, HID_QUIRK_IGNORE }, |
518 | 551 | ||
552 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_ELITE_KBD, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP }, | ||
519 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP }, | 553 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500, HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL | HID_QUIRK_LOGITECH_EXPANDED_KEYMAP }, |
520 | 554 | ||
555 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K, HID_QUIRK_MICROSOFT_KEYS }, | ||
556 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K, HID_QUIRK_MICROSOFT_KEYS }, | ||
557 | |||
521 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL }, | 558 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL }, |
522 | 559 | ||
523 | { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, | 560 | { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, |
524 | { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, | 561 | { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, |
525 | 562 | ||
526 | { USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER }, | 563 | { USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER | HID_QUIRK_HIDDEV }, |
527 | 564 | ||
528 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, | 565 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, |
529 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, | 566 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, |
@@ -531,7 +568,9 @@ static const struct hid_blacklist { | |||
531 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, | 568 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET }, |
532 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, | 569 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET }, |
533 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, | 570 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, |
571 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D, HID_QUIRK_NOGET }, | ||
534 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL, HID_QUIRK_NOGET }, | 572 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL, HID_QUIRK_NOGET }, |
573 | { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0, HID_QUIRK_NOGET }, | ||
535 | { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_NOGET }, | 574 | { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_NOGET }, |
536 | { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, | 575 | { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, |
537 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, | 576 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, |
@@ -540,19 +579,22 @@ static const struct hid_blacklist { | |||
540 | 579 | ||
541 | { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, | 580 | { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, |
542 | 581 | ||
543 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 582 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
544 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 583 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
545 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 584 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
546 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, | 585 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD}, |
547 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 586 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
548 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 587 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
549 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, | 588 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD}, |
550 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 589 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
551 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 590 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
552 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, | 591 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD}, |
553 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 592 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
554 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 593 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI, HID_QUIRK_APPLE_HAS_FN }, |
555 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | 594 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD }, |
595 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS, HID_QUIRK_APPLE_HAS_FN }, | ||
596 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | ||
597 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, | ||
556 | 598 | ||
557 | { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS }, | 599 | { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS }, |
558 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD, HID_QUIRK_RESET_LEDS }, | 600 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KBD, HID_QUIRK_RESET_LEDS }, |
@@ -638,10 +680,14 @@ static const struct hid_rdesc_blacklist { | |||
638 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_RDESC_LOGITECH }, | 680 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER, HID_QUIRK_RDESC_LOGITECH }, |
639 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_RDESC_LOGITECH }, | 681 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2, HID_QUIRK_RDESC_LOGITECH }, |
640 | 682 | ||
683 | { USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E, HID_QUIRK_RDESC_BUTTON_CONSUMER }, | ||
684 | |||
641 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_RDESC_MACBOOK_JIS }, | 685 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_RDESC_MACBOOK_JIS }, |
642 | 686 | ||
643 | { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_RDESC_PETALYNX }, | 687 | { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_RDESC_PETALYNX }, |
644 | 688 | ||
689 | { USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_RDESC_SAMSUNG_REMOTE }, | ||
690 | |||
645 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_RDESC_SWAPPED_MIN_MAX }, | 691 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1, HID_QUIRK_RDESC_SWAPPED_MIN_MAX }, |
646 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_RDESC_SWAPPED_MIN_MAX }, | 692 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2, HID_QUIRK_RDESC_SWAPPED_MIN_MAX }, |
647 | 693 | ||
@@ -884,6 +930,8 @@ u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct) | |||
884 | return quirks; | 930 | return quirks; |
885 | } | 931 | } |
886 | 932 | ||
933 | EXPORT_SYMBOL_GPL(usbhid_lookup_quirk); | ||
934 | |||
887 | /* | 935 | /* |
888 | * Cherry Cymotion keyboard have an invalid HID report descriptor, | 936 | * Cherry Cymotion keyboard have an invalid HID report descriptor, |
889 | * that needs fixing before we can parse it. | 937 | * that needs fixing before we can parse it. |
@@ -914,6 +962,33 @@ static void usbhid_fixup_logitech_descriptor(unsigned char *rdesc, int rsize) | |||
914 | } | 962 | } |
915 | } | 963 | } |
916 | 964 | ||
965 | /* | ||
966 | * Samsung IrDA remote controller (reports as Cypress USB Mouse). | ||
967 | * | ||
968 | * Vendor specific report #4 has a size of 48 bit, | ||
969 | * and therefore is not accepted when inspecting the descriptors. | ||
970 | * As a workaround we reinterpret the report as: | ||
971 | * Variable type, count 6, size 8 bit, log. maximum 255 | ||
972 | * The burden to reconstruct the data is moved into user space. | ||
973 | */ | ||
974 | static void usbhid_fixup_samsung_irda_descriptor(unsigned char *rdesc, | ||
975 | int rsize) | ||
976 | { | ||
977 | if (rsize >= 182 && rdesc[175] == 0x25 | ||
978 | && rdesc[176] == 0x40 | ||
979 | && rdesc[177] == 0x75 | ||
980 | && rdesc[178] == 0x30 | ||
981 | && rdesc[179] == 0x95 | ||
982 | && rdesc[180] == 0x01 | ||
983 | && rdesc[182] == 0x40) { | ||
984 | printk(KERN_INFO "Fixing up Samsung IrDA report descriptor\n"); | ||
985 | rdesc[176] = 0xff; | ||
986 | rdesc[178] = 0x08; | ||
987 | rdesc[180] = 0x06; | ||
988 | rdesc[182] = 0x42; | ||
989 | } | ||
990 | } | ||
991 | |||
917 | /* Petalynx Maxter Remote has maximum for consumer page set too low */ | 992 | /* Petalynx Maxter Remote has maximum for consumer page set too low */ |
918 | static void usbhid_fixup_petalynx_descriptor(unsigned char *rdesc, int rsize) | 993 | static void usbhid_fixup_petalynx_descriptor(unsigned char *rdesc, int rsize) |
919 | { | 994 | { |
@@ -965,6 +1040,14 @@ static void usbhid_fixup_macbook_descriptor(unsigned char *rdesc, int rsize) | |||
965 | } | 1040 | } |
966 | } | 1041 | } |
967 | 1042 | ||
1043 | static void usbhid_fixup_button_consumer_descriptor(unsigned char *rdesc, int rsize) | ||
1044 | { | ||
1045 | if (rsize >= 30 && rdesc[29] == 0x05 | ||
1046 | && rdesc[30] == 0x09) { | ||
1047 | printk(KERN_INFO "Fixing up button/consumer in HID report descriptor\n"); | ||
1048 | rdesc[30] = 0x0c; | ||
1049 | } | ||
1050 | } | ||
968 | 1051 | ||
969 | static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize) | 1052 | static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize) |
970 | { | 1053 | { |
@@ -982,6 +1065,13 @@ static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned | |||
982 | 1065 | ||
983 | if (quirks & HID_QUIRK_RDESC_MACBOOK_JIS) | 1066 | if (quirks & HID_QUIRK_RDESC_MACBOOK_JIS) |
984 | usbhid_fixup_macbook_descriptor(rdesc, rsize); | 1067 | usbhid_fixup_macbook_descriptor(rdesc, rsize); |
1068 | |||
1069 | if (quirks & HID_QUIRK_RDESC_BUTTON_CONSUMER) | ||
1070 | usbhid_fixup_button_consumer_descriptor(rdesc, rsize); | ||
1071 | |||
1072 | if (quirks & HID_QUIRK_RDESC_SAMSUNG_REMOTE) | ||
1073 | usbhid_fixup_samsung_irda_descriptor(rdesc, rsize); | ||
1074 | |||
985 | } | 1075 | } |
986 | 1076 | ||
987 | /** | 1077 | /** |
diff --git a/drivers/hid/usbhid/hid-tmff.c b/drivers/hid/usbhid/hid-tmff.c index 69882a726e99..144578b1a00c 100644 --- a/drivers/hid/usbhid/hid-tmff.c +++ b/drivers/hid/usbhid/hid-tmff.c | |||
@@ -137,7 +137,8 @@ static int hid_tmff_play(struct input_dev *dev, void *data, struct ff_effect *ef | |||
137 | int hid_tmff_init(struct hid_device *hid) | 137 | int hid_tmff_init(struct hid_device *hid) |
138 | { | 138 | { |
139 | struct tmff_device *tmff; | 139 | struct tmff_device *tmff; |
140 | struct list_head *pos; | 140 | struct hid_report *report; |
141 | struct list_head *report_list; | ||
141 | struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); | 142 | struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); |
142 | struct input_dev *input_dev = hidinput->input; | 143 | struct input_dev *input_dev = hidinput->input; |
143 | const signed short *ff_bits = ff_joystick; | 144 | const signed short *ff_bits = ff_joystick; |
@@ -149,8 +150,8 @@ int hid_tmff_init(struct hid_device *hid) | |||
149 | return -ENOMEM; | 150 | return -ENOMEM; |
150 | 151 | ||
151 | /* Find the report to use */ | 152 | /* Find the report to use */ |
152 | list_for_each(pos, &hid->report_enum[HID_OUTPUT_REPORT].report_list) { | 153 | report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; |
153 | struct hid_report *report = (struct hid_report *)pos; | 154 | list_for_each_entry(report, report_list, list) { |
154 | int fieldnum; | 155 | int fieldnum; |
155 | 156 | ||
156 | for (fieldnum = 0; fieldnum < report->maxfield; ++fieldnum) { | 157 | for (fieldnum = 0; fieldnum < report->maxfield; ++fieldnum) { |
diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c index 775a1ef28a29..5d9dbb47e4a8 100644 --- a/drivers/hid/usbhid/usbkbd.c +++ b/drivers/hid/usbhid/usbkbd.c | |||
@@ -235,6 +235,14 @@ static int usb_kbd_probe(struct usb_interface *iface, | |||
235 | if (!usb_endpoint_is_int_in(endpoint)) | 235 | if (!usb_endpoint_is_int_in(endpoint)) |
236 | return -ENODEV; | 236 | return -ENODEV; |
237 | 237 | ||
238 | #ifdef CONFIG_USB_HID | ||
239 | if (usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor), | ||
240 | le16_to_cpu(dev->descriptor.idProduct)) | ||
241 | & HID_QUIRK_IGNORE) { | ||
242 | return -ENODEV; | ||
243 | } | ||
244 | #endif | ||
245 | |||
238 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); | 246 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); |
239 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); | 247 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); |
240 | 248 | ||
diff --git a/drivers/hid/usbhid/usbmouse.c b/drivers/hid/usbhid/usbmouse.c index f8ad6910d3d9..df0d96d989de 100644 --- a/drivers/hid/usbhid/usbmouse.c +++ b/drivers/hid/usbhid/usbmouse.c | |||
@@ -131,6 +131,14 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i | |||
131 | if (!usb_endpoint_is_int_in(endpoint)) | 131 | if (!usb_endpoint_is_int_in(endpoint)) |
132 | return -ENODEV; | 132 | return -ENODEV; |
133 | 133 | ||
134 | #ifdef CONFIG_USB_HID | ||
135 | if (usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor), | ||
136 | le16_to_cpu(dev->descriptor.idProduct)) | ||
137 | & (HID_QUIRK_IGNORE|HID_QUIRK_IGNORE_MOUSE)) { | ||
138 | return -ENODEV; | ||
139 | } | ||
140 | #endif | ||
141 | |||
134 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); | 142 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); |
135 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); | 143 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); |
136 | 144 | ||
diff --git a/include/linux/hid.h b/include/linux/hid.h index 6e35b92b1d2c..3902690647b0 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -267,10 +267,10 @@ struct hid_item { | |||
267 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100 | 267 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100 |
268 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200 | 268 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200 |
269 | #define HID_QUIRK_MIGHTYMOUSE 0x00000400 | 269 | #define HID_QUIRK_MIGHTYMOUSE 0x00000400 |
270 | #define HID_QUIRK_POWERBOOK_HAS_FN 0x00000800 | 270 | #define HID_QUIRK_APPLE_HAS_FN 0x00000800 |
271 | #define HID_QUIRK_POWERBOOK_FN_ON 0x00001000 | 271 | #define HID_QUIRK_APPLE_FN_ON 0x00001000 |
272 | #define HID_QUIRK_INVERT_HWHEEL 0x00002000 | 272 | #define HID_QUIRK_INVERT_HWHEEL 0x00002000 |
273 | #define HID_QUIRK_POWERBOOK_ISO_KEYBOARD 0x00004000 | 273 | #define HID_QUIRK_APPLE_ISO_KEYBOARD 0x00004000 |
274 | #define HID_QUIRK_BAD_RELATIVE_KEYS 0x00008000 | 274 | #define HID_QUIRK_BAD_RELATIVE_KEYS 0x00008000 |
275 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 | 275 | #define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 |
276 | #define HID_QUIRK_IGNORE_MOUSE 0x00020000 | 276 | #define HID_QUIRK_IGNORE_MOUSE 0x00020000 |
@@ -281,6 +281,9 @@ struct hid_item { | |||
281 | #define HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL 0x00400000 | 281 | #define HID_QUIRK_LOGITECH_IGNORE_DOUBLED_WHEEL 0x00400000 |
282 | #define HID_QUIRK_LOGITECH_EXPANDED_KEYMAP 0x00800000 | 282 | #define HID_QUIRK_LOGITECH_EXPANDED_KEYMAP 0x00800000 |
283 | #define HID_QUIRK_IGNORE_HIDINPUT 0x01000000 | 283 | #define HID_QUIRK_IGNORE_HIDINPUT 0x01000000 |
284 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_B8 0x02000000 | ||
285 | #define HID_QUIRK_HWHEEL_WHEEL_INVERT 0x04000000 | ||
286 | #define HID_QUIRK_MICROSOFT_KEYS 0x08000000 | ||
284 | 287 | ||
285 | /* | 288 | /* |
286 | * Separate quirks for runtime report descriptor fixup | 289 | * Separate quirks for runtime report descriptor fixup |
@@ -291,6 +294,8 @@ struct hid_item { | |||
291 | #define HID_QUIRK_RDESC_SWAPPED_MIN_MAX 0x00000004 | 294 | #define HID_QUIRK_RDESC_SWAPPED_MIN_MAX 0x00000004 |
292 | #define HID_QUIRK_RDESC_PETALYNX 0x00000008 | 295 | #define HID_QUIRK_RDESC_PETALYNX 0x00000008 |
293 | #define HID_QUIRK_RDESC_MACBOOK_JIS 0x00000010 | 296 | #define HID_QUIRK_RDESC_MACBOOK_JIS 0x00000010 |
297 | #define HID_QUIRK_RDESC_BUTTON_CONSUMER 0x00000020 | ||
298 | #define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000040 | ||
294 | 299 | ||
295 | /* | 300 | /* |
296 | * This is the global environment of the parser. This information is | 301 | * This is the global environment of the parser. This information is |
@@ -456,6 +461,8 @@ struct hid_device { /* device report descriptor */ | |||
456 | 461 | ||
457 | void *driver_data; | 462 | void *driver_data; |
458 | 463 | ||
464 | __s32 delayed_value; /* For A4 Tech mice hwheel quirk */ | ||
465 | |||
459 | /* device-specific function pointers */ | 466 | /* device-specific function pointers */ |
460 | int (*hidinput_input_event) (struct input_dev *, unsigned int, unsigned int, int); | 467 | int (*hidinput_input_event) (struct input_dev *, unsigned int, unsigned int, int); |
461 | int (*hid_open) (struct hid_device *); | 468 | int (*hid_open) (struct hid_device *); |
@@ -469,7 +476,7 @@ struct hid_device { /* device report descriptor */ | |||
469 | /* handler for raw output data, used by hidraw */ | 476 | /* handler for raw output data, used by hidraw */ |
470 | int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t); | 477 | int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t); |
471 | #ifdef CONFIG_USB_HIDINPUT_POWERBOOK | 478 | #ifdef CONFIG_USB_HIDINPUT_POWERBOOK |
472 | unsigned long pb_pressed_fn[BITS_TO_LONGS(KEY_CNT)]; | 479 | unsigned long apple_pressed_fn[BITS_TO_LONGS(KEY_CNT)]; |
473 | unsigned long pb_pressed_numlock[BITS_TO_LONGS(KEY_CNT)]; | 480 | unsigned long pb_pressed_numlock[BITS_TO_LONGS(KEY_CNT)]; |
474 | #endif | 481 | #endif |
475 | }; | 482 | }; |
@@ -520,6 +527,9 @@ extern void hidinput_disconnect(struct hid_device *); | |||
520 | int hid_set_field(struct hid_field *, unsigned, __s32); | 527 | int hid_set_field(struct hid_field *, unsigned, __s32); |
521 | int hid_input_report(struct hid_device *, int type, u8 *, int, int); | 528 | int hid_input_report(struct hid_device *, int type, u8 *, int, int); |
522 | int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); | 529 | int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field); |
530 | int hidinput_mapping_quirks(struct hid_usage *, struct input_dev *, unsigned long **, int *); | ||
531 | void hidinput_event_quirks(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); | ||
532 | int hidinput_apple_event(struct hid_device *, struct input_dev *, struct hid_usage *, __s32); | ||
523 | void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt); | 533 | void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt); |
524 | void hid_output_report(struct hid_report *report, __u8 *data); | 534 | void hid_output_report(struct hid_report *report, __u8 *data); |
525 | void hid_free_device(struct hid_device *device); | 535 | void hid_free_device(struct hid_device *device); |