aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-01-28 16:52:20 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-01-28 16:52:20 -0500
commitf4798748dee00c807a63f5518f08b3df161e0f6d (patch)
tree9b4c12712874de48c5ff1d437e584052bbec21f7 /drivers
parent8d01eddf292dcd78b640418c80fb300532799cd4 (diff)
parent3bce6f981aeeb7d0c14520cecd947716b377ef83 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (24 commits) HID: ADS/Tech Radio si470x needs blacklist entry HID: Logitech Extreme 3D needs NOGET quirk HID: Refactor MS Presenter 8K key mapping HID: MS Presenter mapping for PID 0x0701 HID: Support Samsung IR remote HID: fix compilation of hidbp drivers without usbhid HID: Blacklist the Gretag-Macbeth Huey display colorimeter HID: the `bit' in hidinput_mapping_quirks() is an out parameter HID: remove redundant WARN_ON()s in order not to scare users HID: force hiddev creation for SONY PS3 controller HID: Use hid blacklist in usbmouse/usbkbd HID: proper handling of MS 4k and 6k devices HID: remove unused variable in quirk event handler HID: hid-input quirk for BTC 8193 HID: separate hid-input event quirks from generic code HID: refactor mapping to input subsystem for quirky devices HID: Microsoft Wireless Optical Desktop 3.0 quirk HID: Add support for Logitech Elite keyboards HID: add full support for Genius KB-29E HID: fix a potential bug in pointer casting ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hid/Makefile2
-rw-r--r--drivers/hid/hid-core.c12
-rw-r--r--drivers/hid/hid-input-quirks.c423
-rw-r--r--drivers/hid/hid-input.c295
-rw-r--r--drivers/hid/usbhid/Kconfig5
-rw-r--r--drivers/hid/usbhid/hid-quirks.c118
-rw-r--r--drivers/hid/usbhid/hid-tmff.c7
-rw-r--r--drivers/hid/usbhid/usbkbd.c8
-rw-r--r--drivers/hid/usbhid/usbmouse.c8
9 files changed, 637 insertions, 241 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#
4hid-objs := hid-core.o hid-input.o 4hid-objs := hid-core.o hid-input.o hid-input-quirks.o
5 5
6obj-$(CONFIG_HID) += hid.o 6obj-$(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
27static 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
43static 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
59static 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
92static 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
117static 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
140static 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
159static 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
187static 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
239static 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
257static 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
309static 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
339int 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
355void 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
37static int hid_pb_fnmode = 1; 37static int hid_apple_fnmode = 1;
38module_param_named(pb_fnmode, hid_pb_fnmode, int, 0644); 38module_param_named(pb_fnmode, hid_apple_fnmode, int, 0644);
39MODULE_PARM_DESC(pb_fnmode, 39MODULE_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
95struct hidinput_key_translation { 91struct 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
99static 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
103static struct hidinput_key_translation powerbook_fn_keys[] = { 115static 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
145static struct hidinput_key_translation powerbook_iso_keyboard[] = { 157static 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
163static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, 175int 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
231static void hidinput_pb_setup(struct input_dev *input) 246static 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
249static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, 267inline 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
255static inline void hidinput_pb_setup(struct input_dev *input) 274static 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
752mapped:
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
27config USB_HIDINPUT_POWERBOOK 27config 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
933EXPORT_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 */
974static 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 */
918static void usbhid_fixup_petalynx_descriptor(unsigned char *rdesc, int rsize) 993static 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
1043static 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
969static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned rsize) 1052static 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
137int hid_tmff_init(struct hid_device *hid) 137int 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