aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2008-06-18 17:36:49 -0400
committerJiri Kosina <jkosina@suse.cz>2008-10-14 17:50:49 -0400
commit8c19a51591d06f5226499972567f528cf6066bb7 (patch)
treeacfa47c0cb371c8b87f7282d19c627e44032dbe2
parentd458a9dfc4de24870b8c747484b1988726534bee (diff)
HID: move apple quirks
Move them from the core code to a separate driver. Signed-off-by: Jiri Slaby <jslaby@suse.cz> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/Kconfig14
-rw-r--r--drivers/hid/Makefile1
-rw-r--r--drivers/hid/hid-apple.c479
-rw-r--r--drivers/hid/hid-core.c32
-rw-r--r--drivers/hid/hid-input-quirks.c8
-rw-r--r--drivers/hid/hid-input.c221
-rw-r--r--drivers/hid/usbhid/Kconfig11
-rw-r--r--drivers/hid/usbhid/hid-core.c4
-rw-r--r--drivers/hid/usbhid/hid-quirks.c49
-rw-r--r--drivers/hid/usbhid/usbmouse.c5
-rw-r--r--include/linux/hid.h13
-rw-r--r--net/bluetooth/hidp/core.c22
12 files changed, 532 insertions, 327 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 066e8c08c268..41283fff5145 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -70,6 +70,20 @@ source "drivers/hid/usbhid/Kconfig"
70menu "Special HID drivers" 70menu "Special HID drivers"
71 depends on HID 71 depends on HID
72 72
73config HID_APPLE
74 tristate "Apple"
75 default m
76 depends on (USB_HID || BT_HIDP)
77 ---help---
78 Support for some Apple devices which less or more break
79 HID specification.
80
81 Say Y here if you want support for the special keys (Fn, Numlock) on
82 Apple iBooks, PowerBooks, MacBooks, MacBook Pros and aluminum USB
83 keyboards.
84
85 If unsure, say M.
86
73config HID_LOGITECH 87config HID_LOGITECH
74 tristate "Logitech" 88 tristate "Logitech"
75 default m 89 default m
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index cae036bfe837..4a14821ceefa 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_HID) += hid.o
8hid-$(CONFIG_HID_DEBUG) += hid-debug.o 8hid-$(CONFIG_HID_DEBUG) += hid-debug.o
9hid-$(CONFIG_HIDRAW) += hidraw.o 9hid-$(CONFIG_HIDRAW) += hidraw.o
10 10
11obj-$(CONFIG_HID_APPLE) += hid-apple.o
11obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o 12obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o
12 13
13obj-$(CONFIG_USB_HID) += usbhid/ 14obj-$(CONFIG_USB_HID) += usbhid/
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
new file mode 100644
index 000000000000..5642e2c685fc
--- /dev/null
+++ b/drivers/hid/hid-apple.c
@@ -0,0 +1,479 @@
1/*
2 * USB HID quirks support for Linux
3 *
4 * Copyright (c) 1999 Andreas Gal
5 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
6 * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
7 * Copyright (c) 2006-2007 Jiri Kosina
8 * Copyright (c) 2007 Paul Walmsley
9 * Copyright (c) 2008 Jiri Slaby <jirislaby@gmail.com>
10 */
11
12/*
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the Free
15 * Software Foundation; either version 2 of the License, or (at your option)
16 * any later version.
17 */
18
19#include <linux/device.h>
20#include <linux/hid.h>
21#include <linux/module.h>
22#include <linux/usb.h>
23
24#include "hid-ids.h"
25
26#define APPLE_RDESC_JIS 0x0001
27#define APPLE_IGNORE_MOUSE 0x0002
28#define APPLE_HAS_FN 0x0004
29#define APPLE_HIDDEV 0x0008
30#define APPLE_ISO_KEYBOARD 0x0010
31#define APPLE_MIGHTYMOUSE 0x0020
32#define APPLE_INVERT_HWHEEL 0x0040
33#define APPLE_IGNORE_HIDINPUT 0x0080
34#define APPLE_NUMLOCK_EMULATION 0x0100
35
36#define APPLE_FLAG_FKEY 0x01
37
38static unsigned int fnmode = 1;
39module_param(fnmode, uint, 0644);
40MODULE_PARM_DESC(fnmode, "Mode of fn key on Apple keyboards (0 = disabled, "
41 "[1] = fkeyslast, 2 = fkeysfirst)");
42
43struct apple_sc {
44 unsigned long quirks;
45 unsigned int fn_on;
46 DECLARE_BITMAP(pressed_fn, KEY_CNT);
47 DECLARE_BITMAP(pressed_numlock, KEY_CNT);
48};
49
50struct apple_key_translation {
51 u16 from;
52 u16 to;
53 u8 flags;
54};
55
56static struct apple_key_translation apple_fn_keys[] = {
57 { KEY_BACKSPACE, KEY_DELETE },
58 { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
59 { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
60 { KEY_F3, KEY_FN_F5, APPLE_FLAG_FKEY }, /* Exposé */
61 { KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */
62 { KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY },
63 { KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY },
64 { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY },
65 { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY },
66 { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY },
67 { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY },
68 { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
69 { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
70 { KEY_UP, KEY_PAGEUP },
71 { KEY_DOWN, KEY_PAGEDOWN },
72 { KEY_LEFT, KEY_HOME },
73 { KEY_RIGHT, KEY_END },
74 { }
75};
76
77static struct apple_key_translation powerbook_fn_keys[] = {
78 { KEY_BACKSPACE, KEY_DELETE },
79 { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
80 { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
81 { KEY_F3, KEY_MUTE, APPLE_FLAG_FKEY },
82 { KEY_F4, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
83 { KEY_F5, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
84 { KEY_F6, KEY_NUMLOCK, APPLE_FLAG_FKEY },
85 { KEY_F7, KEY_SWITCHVIDEOMODE, APPLE_FLAG_FKEY },
86 { KEY_F8, KEY_KBDILLUMTOGGLE, APPLE_FLAG_FKEY },
87 { KEY_F9, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY },
88 { KEY_F10, KEY_KBDILLUMUP, APPLE_FLAG_FKEY },
89 { KEY_UP, KEY_PAGEUP },
90 { KEY_DOWN, KEY_PAGEDOWN },
91 { KEY_LEFT, KEY_HOME },
92 { KEY_RIGHT, KEY_END },
93 { }
94};
95
96static struct apple_key_translation powerbook_numlock_keys[] = {
97 { KEY_J, KEY_KP1 },
98 { KEY_K, KEY_KP2 },
99 { KEY_L, KEY_KP3 },
100 { KEY_U, KEY_KP4 },
101 { KEY_I, KEY_KP5 },
102 { KEY_O, KEY_KP6 },
103 { KEY_7, KEY_KP7 },
104 { KEY_8, KEY_KP8 },
105 { KEY_9, KEY_KP9 },
106 { KEY_M, KEY_KP0 },
107 { KEY_DOT, KEY_KPDOT },
108 { KEY_SLASH, KEY_KPPLUS },
109 { KEY_SEMICOLON, KEY_KPMINUS },
110 { KEY_P, KEY_KPASTERISK },
111 { KEY_MINUS, KEY_KPEQUAL },
112 { KEY_0, KEY_KPSLASH },
113 { KEY_F6, KEY_NUMLOCK },
114 { KEY_KPENTER, KEY_KPENTER },
115 { KEY_BACKSPACE, KEY_BACKSPACE },
116 { }
117};
118
119static struct apple_key_translation apple_iso_keyboard[] = {
120 { KEY_GRAVE, KEY_102ND },
121 { KEY_102ND, KEY_GRAVE },
122 { }
123};
124
125static struct apple_key_translation *apple_find_translation(
126 struct apple_key_translation *table, u16 from)
127{
128 struct apple_key_translation *trans;
129
130 /* Look for the translation */
131 for (trans = table; trans->from; trans++)
132 if (trans->from == from)
133 return trans;
134
135 return NULL;
136}
137
138static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
139 struct hid_usage *usage, __s32 value)
140{
141 struct apple_sc *asc = hid_get_drvdata(hid);
142 struct apple_key_translation *trans;
143
144 if (usage->code == KEY_FN) {
145 asc->fn_on = !!value;
146 input_event(input, usage->type, usage->code, value);
147 return 1;
148 }
149
150 if (fnmode) {
151 int do_translate;
152
153 trans = apple_find_translation((hid->product < 0x220 ||
154 hid->product >= 0x300) ?
155 powerbook_fn_keys : apple_fn_keys,
156 usage->code);
157 if (trans) {
158 if (test_bit(usage->code, asc->pressed_fn))
159 do_translate = 1;
160 else if (trans->flags & APPLE_FLAG_FKEY)
161 do_translate = (fnmode == 2 && asc->fn_on) ||
162 (fnmode == 1 && !asc->fn_on);
163 else
164 do_translate = asc->fn_on;
165
166 if (do_translate) {
167 if (value)
168 set_bit(usage->code, asc->pressed_fn);
169 else
170 clear_bit(usage->code, asc->pressed_fn);
171
172 input_event(input, usage->type, trans->to,
173 value);
174
175 return 1;
176 }
177 }
178
179 if (asc->quirks & APPLE_NUMLOCK_EMULATION &&
180 (test_bit(usage->code, asc->pressed_numlock) ||
181 test_bit(LED_NUML, input->led))) {
182 trans = apple_find_translation(powerbook_numlock_keys,
183 usage->code);
184
185 if (trans) {
186 if (value)
187 set_bit(usage->code,
188 asc->pressed_numlock);
189 else
190 clear_bit(usage->code,
191 asc->pressed_numlock);
192
193 input_event(input, usage->type, trans->to,
194 value);
195 }
196
197 return 1;
198 }
199 }
200
201 if (asc->quirks & APPLE_ISO_KEYBOARD) {
202 trans = apple_find_translation(apple_iso_keyboard, usage->code);
203 if (trans) {
204 input_event(input, usage->type, trans->to, value);
205 return 1;
206 }
207 }
208
209 return 0;
210}
211
212static int apple_event(struct hid_device *hdev, struct hid_field *field,
213 struct hid_usage *usage, __s32 value)
214{
215 struct apple_sc *asc = hid_get_drvdata(hdev);
216
217 if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
218 !usage->type)
219 return 0;
220
221 if ((asc->quirks & APPLE_INVERT_HWHEEL) &&
222 usage->code == REL_HWHEEL) {
223 input_event(field->hidinput->input, usage->type, usage->code,
224 -value);
225 return 1;
226 }
227
228 if ((asc->quirks & APPLE_HAS_FN) &&
229 hidinput_apple_event(hdev, field->hidinput->input,
230 usage, value))
231 return 1;
232
233
234 return 0;
235}
236
237/*
238 * MacBook JIS keyboard has wrong logical maximum
239 */
240static void apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
241 unsigned int rsize)
242{
243 struct apple_sc *asc = hid_get_drvdata(hdev);
244
245 if ((asc->quirks & APPLE_RDESC_JIS) && rsize >= 60 &&
246 rdesc[53] == 0x65 && rdesc[59] == 0x65) {
247 dev_info(&hdev->dev, "fixing up MacBook JIS keyboard report "
248 "descriptor\n");
249 rdesc[53] = rdesc[59] = 0xe7;
250 }
251}
252
253static void apple_setup_input(struct input_dev *input)
254{
255 struct apple_key_translation *trans;
256
257 set_bit(KEY_NUMLOCK, input->keybit);
258
259 /* Enable all needed keys */
260 for (trans = apple_fn_keys; trans->from; trans++)
261 set_bit(trans->to, input->keybit);
262
263 for (trans = powerbook_fn_keys; trans->from; trans++)
264 set_bit(trans->to, input->keybit);
265
266 for (trans = powerbook_numlock_keys; trans->from; trans++)
267 set_bit(trans->to, input->keybit);
268
269 for (trans = apple_iso_keyboard; trans->from; trans++)
270 set_bit(trans->to, input->keybit);
271}
272
273static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi,
274 struct hid_field *field, struct hid_usage *usage,
275 unsigned long **bit, int *max)
276{
277 if (usage->hid == (HID_UP_CUSTOM | 0x0003)) {
278 /* The fn key on Apple USB keyboards */
279 set_bit(EV_REP, hi->input->evbit);
280 hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN);
281 apple_setup_input(hi->input);
282 return 1;
283 }
284
285 /* we want the hid layer to go through standard path (set and ignore) */
286 return 0;
287}
288
289static int apple_input_mapped(struct hid_device *hdev, struct hid_input *hi,
290 struct hid_field *field, struct hid_usage *usage,
291 unsigned long **bit, int *max)
292{
293 struct apple_sc *asc = hid_get_drvdata(hdev);
294
295 if (asc->quirks & APPLE_MIGHTYMOUSE) {
296 if (usage->hid == HID_GD_Z)
297 hid_map_usage(hi, usage, bit, max, EV_REL, REL_HWHEEL);
298 else if (usage->code == BTN_1)
299 hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_2);
300 else if (usage->code == BTN_2)
301 hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_1);
302 }
303
304 return 0;
305}
306
307static int apple_probe(struct hid_device *hdev,
308 const struct hid_device_id *id)
309{
310 unsigned long quirks = id->driver_data;
311 struct apple_sc *asc;
312 int ret;
313
314 /* return something else or move to hid layer? device will reside
315 allocated */
316 if (id->bus == BUS_USB && (quirks & APPLE_IGNORE_MOUSE) &&
317 to_usb_interface(hdev->dev.parent)->cur_altsetting->
318 desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE)
319 return -ENODEV;
320
321 asc = kzalloc(sizeof(*asc), GFP_KERNEL);
322 if (asc == NULL) {
323 dev_err(&hdev->dev, "can't alloc apple descriptor\n");
324 return -ENOMEM;
325 }
326
327 asc->quirks = quirks;
328
329 hid_set_drvdata(hdev, asc);
330
331 if (quirks & APPLE_HIDDEV)
332 hdev->quirks |= HID_QUIRK_HIDDEV;
333 if (quirks & APPLE_IGNORE_HIDINPUT)
334 hdev->quirks |= HID_QUIRK_IGNORE_HIDINPUT;
335
336 ret = hid_parse(hdev);
337 if (ret) {
338 dev_err(&hdev->dev, "parse failed\n");
339 goto err_free;
340 }
341
342 ret = hid_hw_start(hdev);
343 if (ret) {
344 dev_err(&hdev->dev, "hw start failed\n");
345 goto err_free;
346 }
347
348 return 0;
349err_free:
350 kfree(asc);
351 return ret;
352}
353
354static void apple_remove(struct hid_device *hdev)
355{
356 hid_hw_stop(hdev);
357 kfree(hid_get_drvdata(hdev));
358}
359
360static const struct hid_device_id apple_devices[] = {
361 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4),
362 .driver_data = APPLE_HIDDEV | APPLE_IGNORE_HIDINPUT },
363 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE),
364 .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL },
365
366 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI),
367 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
368 APPLE_IGNORE_MOUSE },
369 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO),
370 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
371 APPLE_IGNORE_MOUSE },
372 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI),
373 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
374 APPLE_IGNORE_MOUSE },
375 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO),
376 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
377 APPLE_IGNORE_MOUSE | APPLE_ISO_KEYBOARD },
378 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS),
379 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
380 APPLE_IGNORE_MOUSE },
381 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI),
382 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
383 APPLE_IGNORE_MOUSE },
384 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO),
385 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
386 APPLE_IGNORE_MOUSE | APPLE_ISO_KEYBOARD },
387 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS),
388 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
389 APPLE_IGNORE_MOUSE },
390 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI),
391 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
392 APPLE_IGNORE_MOUSE },
393 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO),
394 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
395 APPLE_IGNORE_MOUSE | APPLE_ISO_KEYBOARD },
396 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS),
397 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
398 APPLE_IGNORE_MOUSE | APPLE_RDESC_JIS},
399 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI),
400 .driver_data = APPLE_HAS_FN },
401 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO),
402 .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
403 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS),
404 .driver_data = APPLE_HAS_FN },
405 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI),
406 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
407 APPLE_IGNORE_MOUSE },
408 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO),
409 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
410 APPLE_IGNORE_MOUSE },
411 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS),
412 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
413 APPLE_IGNORE_MOUSE },
414 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
415 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
416 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO),
417 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
418 APPLE_ISO_KEYBOARD },
419 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS),
420 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
421 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
422 .driver_data = APPLE_HAS_FN | APPLE_IGNORE_MOUSE },
423 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO),
424 .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD |
425 APPLE_IGNORE_MOUSE },
426 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS),
427 .driver_data = APPLE_HAS_FN | APPLE_IGNORE_MOUSE },
428 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI),
429 .driver_data = APPLE_HAS_FN | APPLE_IGNORE_MOUSE },
430 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO),
431 .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD |
432 APPLE_IGNORE_MOUSE },
433 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS),
434 .driver_data = APPLE_HAS_FN | APPLE_IGNORE_MOUSE },
435 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY),
436 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
437 APPLE_IGNORE_MOUSE },
438 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY),
439 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
440 APPLE_IGNORE_MOUSE },
441
442 /* Apple wireless Mighty Mouse */
443 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c),
444 .driver_data = APPLE_MIGHTYMOUSE | APPLE_INVERT_HWHEEL },
445
446 { }
447};
448MODULE_DEVICE_TABLE(hid, apple_devices);
449
450static struct hid_driver apple_driver = {
451 .name = "apple",
452 .id_table = apple_devices,
453 .report_fixup = apple_report_fixup,
454 .probe = apple_probe,
455 .remove = apple_remove,
456 .event = apple_event,
457 .input_mapping = apple_input_mapping,
458 .input_mapped = apple_input_mapped,
459};
460
461static int apple_init(void)
462{
463 int ret;
464
465 ret = hid_register_driver(&apple_driver);
466 if (ret)
467 printk(KERN_ERR "can't register apple driver\n");
468
469 return ret;
470}
471
472static void apple_exit(void)
473{
474 hid_unregister_driver(&apple_driver);
475}
476
477module_init(apple_init);
478module_exit(apple_exit);
479MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 08470ab295b1..8e3c264c9b2b 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1130,6 +1130,36 @@ static const struct hid_device_id *hid_match_id(struct hid_device *hdev,
1130} 1130}
1131 1131
1132static const struct hid_device_id hid_blacklist[] = { 1132static const struct hid_device_id hid_blacklist[] = {
1133 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) },
1134 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
1135 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) },
1136 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) },
1137 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) },
1138 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO) },
1139 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS) },
1140 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI) },
1141 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO) },
1142 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS) },
1143 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) },
1144 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) },
1145 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) },
1146 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI) },
1147 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO) },
1148 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS) },
1149 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) },
1150 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) },
1151 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) },
1152 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) },
1153 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO) },
1154 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS) },
1155 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI) },
1156 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO) },
1157 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS) },
1158 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) },
1159 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) },
1160 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) },
1161 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
1162 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
1133 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, 1163 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
1134 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, 1164 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
1135 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, 1165 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) },
@@ -1144,6 +1174,8 @@ static const struct hid_device_id hid_blacklist[] = {
1144 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_V150) }, 1174 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_V150) },
1145 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, 1175 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) },
1146 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) }, 1176 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) },
1177
1178 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, 0x030c) },
1147 { } 1179 { }
1148}; 1180};
1149 1181
diff --git a/drivers/hid/hid-input-quirks.c b/drivers/hid/hid-input-quirks.c
index 10451ca3a786..878e193c6d75 100644
--- a/drivers/hid/hid-input-quirks.c
+++ b/drivers/hid/hid-input-quirks.c
@@ -331,19 +331,11 @@ int hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struc
331 return 1; 331 return 1;
332 } 332 }
333 333
334 if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) {
335 input_event(input, usage->type, usage->code, -value);
336 return 1;
337 }
338
339 if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) { 334 if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) {
340 input_event(input, usage->type, REL_HWHEEL, value); 335 input_event(input, usage->type, REL_HWHEEL, value);
341 return 1; 336 return 1;
342 } 337 }
343 338
344 if ((hid->quirks & HID_QUIRK_APPLE_HAS_FN) && hidinput_apple_event(hid, input, usage, value))
345 return 1;
346
347 /* Handling MS keyboards special buttons */ 339 /* Handling MS keyboards special buttons */
348 if (hid->quirks & HID_QUIRK_MICROSOFT_KEYS && 340 if (hid->quirks & HID_QUIRK_MICROSOFT_KEYS &&
349 usage->hid == (HID_UP_MSVENDOR | 0xff05)) { 341 usage->hid == (HID_UP_MSVENDOR | 0xff05)) {
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 4f2bac010f59..76ddf23f1965 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -32,11 +32,6 @@
32#include <linux/hid.h> 32#include <linux/hid.h>
33#include <linux/hid-debug.h> 33#include <linux/hid-debug.h>
34 34
35static int hid_apple_fnmode = 1;
36module_param_named(pb_fnmode, hid_apple_fnmode, int, 0644);
37MODULE_PARM_DESC(pb_fnmode,
38 "Mode of fn key on Apple keyboards (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)");
39
40#define unk KEY_UNKNOWN 35#define unk KEY_UNKNOWN
41 36
42static const unsigned char hid_keyboard[256] = { 37static const unsigned char hid_keyboard[256] = {
@@ -73,202 +68,6 @@ static const struct {
73#define map_key_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \ 68#define map_key_clear(c) hid_map_usage_clear(hidinput, usage, &bit, \
74 &max, EV_KEY, (c)) 69 &max, EV_KEY, (c))
75 70
76#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
77
78struct hidinput_key_translation {
79 u16 from;
80 u16 to;
81 u8 flags;
82};
83
84#define APPLE_FLAG_FKEY 0x01
85
86static struct hidinput_key_translation apple_fn_keys[] = {
87 { KEY_BACKSPACE, KEY_DELETE },
88 { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
89 { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
90 { KEY_F3, KEY_FN_F5, APPLE_FLAG_FKEY }, /* Exposé */
91 { KEY_F4, KEY_FN_F4, APPLE_FLAG_FKEY }, /* Dashboard */
92 { KEY_F5, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY },
93 { KEY_F6, KEY_KBDILLUMUP, APPLE_FLAG_FKEY },
94 { KEY_F7, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY },
95 { KEY_F8, KEY_PLAYPAUSE, APPLE_FLAG_FKEY },
96 { KEY_F9, KEY_NEXTSONG, APPLE_FLAG_FKEY },
97 { KEY_F10, KEY_MUTE, APPLE_FLAG_FKEY },
98 { KEY_F11, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
99 { KEY_F12, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
100 { KEY_UP, KEY_PAGEUP },
101 { KEY_DOWN, KEY_PAGEDOWN },
102 { KEY_LEFT, KEY_HOME },
103 { KEY_RIGHT, KEY_END },
104 { }
105};
106
107static struct hidinput_key_translation powerbook_fn_keys[] = {
108 { KEY_BACKSPACE, KEY_DELETE },
109 { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
110 { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
111 { KEY_F3, KEY_MUTE, APPLE_FLAG_FKEY },
112 { KEY_F4, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY },
113 { KEY_F5, KEY_VOLUMEUP, APPLE_FLAG_FKEY },
114 { KEY_F6, KEY_NUMLOCK, APPLE_FLAG_FKEY },
115 { KEY_F7, KEY_SWITCHVIDEOMODE, APPLE_FLAG_FKEY },
116 { KEY_F8, KEY_KBDILLUMTOGGLE, APPLE_FLAG_FKEY },
117 { KEY_F9, KEY_KBDILLUMDOWN, APPLE_FLAG_FKEY },
118 { KEY_F10, KEY_KBDILLUMUP, APPLE_FLAG_FKEY },
119 { KEY_UP, KEY_PAGEUP },
120 { KEY_DOWN, KEY_PAGEDOWN },
121 { KEY_LEFT, KEY_HOME },
122 { KEY_RIGHT, KEY_END },
123 { }
124};
125
126static struct hidinput_key_translation powerbook_numlock_keys[] = {
127 { KEY_J, KEY_KP1 },
128 { KEY_K, KEY_KP2 },
129 { KEY_L, KEY_KP3 },
130 { KEY_U, KEY_KP4 },
131 { KEY_I, KEY_KP5 },
132 { KEY_O, KEY_KP6 },
133 { KEY_7, KEY_KP7 },
134 { KEY_8, KEY_KP8 },
135 { KEY_9, KEY_KP9 },
136 { KEY_M, KEY_KP0 },
137 { KEY_DOT, KEY_KPDOT },
138 { KEY_SLASH, KEY_KPPLUS },
139 { KEY_SEMICOLON, KEY_KPMINUS },
140 { KEY_P, KEY_KPASTERISK },
141 { KEY_MINUS, KEY_KPEQUAL },
142 { KEY_0, KEY_KPSLASH },
143 { KEY_F6, KEY_NUMLOCK },
144 { KEY_KPENTER, KEY_KPENTER },
145 { KEY_BACKSPACE, KEY_BACKSPACE },
146 { }
147};
148
149static struct hidinput_key_translation apple_iso_keyboard[] = {
150 { KEY_GRAVE, KEY_102ND },
151 { KEY_102ND, KEY_GRAVE },
152 { }
153};
154
155static struct hidinput_key_translation *find_translation(struct hidinput_key_translation *table, u16 from)
156{
157 struct hidinput_key_translation *trans;
158
159 /* Look for the translation */
160 for (trans = table; trans->from; trans++)
161 if (trans->from == from)
162 return trans;
163
164 return NULL;
165}
166
167int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
168 struct hid_usage *usage, __s32 value)
169{
170 struct hidinput_key_translation *trans;
171
172 if (usage->code == KEY_FN) {
173 if (value) hid->quirks |= HID_QUIRK_APPLE_FN_ON;
174 else hid->quirks &= ~HID_QUIRK_APPLE_FN_ON;
175
176 input_event(input, usage->type, usage->code, value);
177
178 return 1;
179 }
180
181 if (hid_apple_fnmode) {
182 int do_translate;
183
184 trans = find_translation((hid->product < 0x220 ||
185 hid->product >= 0x300) ?
186 powerbook_fn_keys : apple_fn_keys,
187 usage->code);
188 if (trans) {
189 if (test_bit(usage->code, hid->apple_pressed_fn))
190 do_translate = 1;
191 else if (trans->flags & APPLE_FLAG_FKEY)
192 do_translate =
193 (hid_apple_fnmode == 2 && (hid->quirks & HID_QUIRK_APPLE_FN_ON)) ||
194 (hid_apple_fnmode == 1 && !(hid->quirks & HID_QUIRK_APPLE_FN_ON));
195 else
196 do_translate = (hid->quirks & HID_QUIRK_APPLE_FN_ON);
197
198 if (do_translate) {
199 if (value)
200 set_bit(usage->code, hid->apple_pressed_fn);
201 else
202 clear_bit(usage->code, hid->apple_pressed_fn);
203
204 input_event(input, usage->type, trans->to, value);
205
206 return 1;
207 }
208 }
209
210 if (hid->quirks & HID_QUIRK_APPLE_NUMLOCK_EMULATION && (
211 test_bit(usage->code, hid->pb_pressed_numlock) ||
212 test_bit(LED_NUML, input->led))) {
213 trans = find_translation(powerbook_numlock_keys, usage->code);
214
215 if (trans) {
216 if (value)
217 set_bit(usage->code, hid->pb_pressed_numlock);
218 else
219 clear_bit(usage->code, hid->pb_pressed_numlock);
220
221 input_event(input, usage->type, trans->to, value);
222 }
223
224 return 1;
225 }
226 }
227
228 if (hid->quirks & HID_QUIRK_APPLE_ISO_KEYBOARD) {
229 trans = find_translation(apple_iso_keyboard, usage->code);
230 if (trans) {
231 input_event(input, usage->type, trans->to, value);
232 return 1;
233 }
234 }
235
236 return 0;
237}
238
239static void hidinput_apple_setup(struct input_dev *input)
240{
241 struct hidinput_key_translation *trans;
242
243 set_bit(KEY_NUMLOCK, input->keybit);
244
245 /* Enable all needed keys */
246 for (trans = apple_fn_keys; trans->from; trans++)
247 set_bit(trans->to, input->keybit);
248
249 for (trans = powerbook_fn_keys; trans->from; trans++)
250 set_bit(trans->to, input->keybit);
251
252 for (trans = powerbook_numlock_keys; trans->from; trans++)
253 set_bit(trans->to, input->keybit);
254
255 for (trans = apple_iso_keyboard; trans->from; trans++)
256 set_bit(trans->to, input->keybit);
257
258}
259#else
260inline int hidinput_apple_event(struct hid_device *hid,
261 struct input_dev *input,
262 struct hid_usage *usage, __s32 value)
263{
264 return 0;
265}
266
267static inline void hidinput_apple_setup(struct input_dev *input)
268{
269}
270#endif
271
272static inline int match_scancode(int code, int scancode) 71static inline int match_scancode(int code, int scancode)
273{ 72{
274 if (scancode == 0) 73 if (scancode == 0)
@@ -696,16 +495,7 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
696 case HID_UP_CUSTOM: /* Reported on Logitech and Apple USB keyboards */ 495 case HID_UP_CUSTOM: /* Reported on Logitech and Apple USB keyboards */
697 496
698 set_bit(EV_REP, input->evbit); 497 set_bit(EV_REP, input->evbit);
699 switch(usage->hid & HID_USAGE) { 498 goto ignore;
700 case 0x003:
701 /* The fn key on Apple USB keyboards */
702 map_key_clear(KEY_FN);
703 hidinput_apple_setup(input);
704 break;
705
706 default: goto ignore;
707 }
708 break;
709 499
710 case HID_UP_LOGIVENDOR: 500 case HID_UP_LOGIVENDOR:
711 501
@@ -742,15 +532,6 @@ mapped:
742 hidinput, field, usage, &bit, &max) < 0) 532 hidinput, field, usage, &bit, &max) < 0)
743 goto ignore; 533 goto ignore;
744 534
745 if (device->quirks & HID_QUIRK_MIGHTYMOUSE) {
746 if (usage->hid == HID_GD_Z)
747 map_rel(REL_HWHEEL);
748 else if (usage->code == BTN_1)
749 map_key(BTN_2);
750 else if (usage->code == BTN_2)
751 map_key(BTN_1);
752 }
753
754 if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5 | 535 if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5 |
755 HID_QUIRK_2WHEEL_MOUSE_HACK_B8)) && (usage->type == EV_REL) && 536 HID_QUIRK_2WHEEL_MOUSE_HACK_B8)) && (usage->type == EV_REL) &&
756 (usage->code == REL_WHEEL)) 537 (usage->code == REL_WHEEL))
diff --git a/drivers/hid/usbhid/Kconfig b/drivers/hid/usbhid/Kconfig
index 18f09104765c..177bfa1a3e5b 100644
--- a/drivers/hid/usbhid/Kconfig
+++ b/drivers/hid/usbhid/Kconfig
@@ -24,17 +24,6 @@ config USB_HID
24comment "Input core support is needed for USB HID input layer or HIDBP support" 24comment "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
28 bool "Enable support for Apple laptop/aluminum USB special keys"
29 default n
30 depends on USB_HID
31 help
32 Say Y here if you want support for the special keys (Fn, Numlock) on
33 Apple iBooks, PowerBooks, MacBooks, MacBook Pros and aluminum USB
34 keyboards.
35
36 If unsure, say N.
37
38config HID_FF 27config HID_FF
39 bool "Force feedback support (EXPERIMENTAL)" 28 bool "Force feedback support (EXPERIMENTAL)"
40 depends on USB_HID && EXPERIMENTAL 29 depends on USB_HID && EXPERIMENTAL
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 9f5e100e95ec..972680820730 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -791,10 +791,6 @@ static int usbhid_parse(struct hid_device *hid)
791 quirks |= HID_QUIRK_NOGET; 791 quirks |= HID_QUIRK_NOGET;
792 } 792 }
793 793
794 if ((quirks & HID_QUIRK_IGNORE_MOUSE) &&
795 (interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE))
796 return -ENODEV;
797
798 if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && 794 if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) &&
799 (!interface->desc.bNumEndpoints || 795 (!interface->desc.bNumEndpoints ||
800 usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { 796 usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) {
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 466d608ba6ac..4c5ee9ecd40a 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -49,7 +49,6 @@ static const struct hid_blacklist {
49 { USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL }, 49 { USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL },
50 50
51 { USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM, HID_QUIRK_HIDDEV }, 51 { USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM, HID_QUIRK_HIDDEV },
52 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT },
53 { USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT }, 52 { USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_HIDDEV | HID_QUIRK_IGNORE_HIDINPUT },
54 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV, HID_QUIRK_HIDINPUT }, 53 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV, HID_QUIRK_HIDINPUT },
55 54
@@ -59,8 +58,6 @@ static const struct hid_blacklist {
59 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K, HID_QUIRK_MICROSOFT_KEYS }, 58 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K, HID_QUIRK_MICROSOFT_KEYS },
60 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K, HID_QUIRK_MICROSOFT_KEYS }, 59 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K, HID_QUIRK_MICROSOFT_KEYS },
61 60
62 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL },
63
64 { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, 61 { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
65 { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, 62 { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT },
66 63
@@ -82,35 +79,6 @@ static const struct hid_blacklist {
82 79
83 { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, 80 { USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
84 81
85 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
86 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
87 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
88 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD},
89 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
90 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
91 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD},
92 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
93 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
94 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_APPLE_ISO_KEYBOARD},
95 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
96 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI, HID_QUIRK_APPLE_HAS_FN },
97 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD },
98 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS, HID_QUIRK_APPLE_HAS_FN },
99 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
100 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
101 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
102 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN },
103 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD },
104 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN },
105 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
106 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD | HID_QUIRK_IGNORE_MOUSE},
107 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE},
108 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE},
109 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_APPLE_ISO_KEYBOARD | HID_QUIRK_IGNORE_MOUSE },
110 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS, HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
111 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
112 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_APPLE_NUMLOCK_EMULATION | HID_QUIRK_APPLE_HAS_FN | HID_QUIRK_IGNORE_MOUSE },
113
114 { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS }, 82 { USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_W7658, HID_QUIRK_RESET_LEDS },
115 83
116 { 0, 0 } 84 { 0, 0 }
@@ -129,8 +97,6 @@ static const struct hid_rdesc_blacklist {
129 97
130 { USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E, HID_QUIRK_RDESC_BUTTON_CONSUMER }, 98 { USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E, HID_QUIRK_RDESC_BUTTON_CONSUMER },
131 99
132 { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_RDESC_MACBOOK_JIS },
133
134 { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_RDESC_PETALYNX }, 100 { USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE, HID_QUIRK_RDESC_PETALYNX },
135 101
136 { USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_RDESC_SAMSUNG_REMOTE }, 102 { USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE, HID_QUIRK_RDESC_SAMSUNG_REMOTE },
@@ -461,18 +427,6 @@ static void usbhid_fixup_cypress_descriptor(unsigned char *rdesc, int rsize)
461 printk(KERN_INFO "Fixing up Cypress report descriptor\n"); 427 printk(KERN_INFO "Fixing up Cypress report descriptor\n");
462} 428}
463 429
464/*
465 * MacBook JIS keyboard has wrong logical maximum
466 */
467static void usbhid_fixup_macbook_descriptor(unsigned char *rdesc, int rsize)
468{
469 if (rsize >= 60 && rdesc[53] == 0x65
470 && rdesc[59] == 0x65) {
471 printk(KERN_INFO "Fixing up MacBook JIS keyboard report descriptor\n");
472 rdesc[53] = rdesc[59] = 0xe7;
473 }
474}
475
476static void usbhid_fixup_button_consumer_descriptor(unsigned char *rdesc, int rsize) 430static void usbhid_fixup_button_consumer_descriptor(unsigned char *rdesc, int rsize)
477{ 431{
478 if (rsize >= 30 && rdesc[29] == 0x05 432 if (rsize >= 30 && rdesc[29] == 0x05
@@ -515,9 +469,6 @@ static void __usbhid_fixup_report_descriptor(__u32 quirks, char *rdesc, unsigned
515 if (quirks & HID_QUIRK_RDESC_PETALYNX) 469 if (quirks & HID_QUIRK_RDESC_PETALYNX)
516 usbhid_fixup_petalynx_descriptor(rdesc, rsize); 470 usbhid_fixup_petalynx_descriptor(rdesc, rsize);
517 471
518 if (quirks & HID_QUIRK_RDESC_MACBOOK_JIS)
519 usbhid_fixup_macbook_descriptor(rdesc, rsize);
520
521 if (quirks & HID_QUIRK_RDESC_BUTTON_CONSUMER) 472 if (quirks & HID_QUIRK_RDESC_BUTTON_CONSUMER)
522 usbhid_fixup_button_consumer_descriptor(rdesc, rsize); 473 usbhid_fixup_button_consumer_descriptor(rdesc, rsize);
523 474
diff --git a/drivers/hid/usbhid/usbmouse.c b/drivers/hid/usbhid/usbmouse.c
index 35689ef172cc..a89646a3c1fc 100644
--- a/drivers/hid/usbhid/usbmouse.c
+++ b/drivers/hid/usbhid/usbmouse.c
@@ -31,6 +31,11 @@
31#include <linux/usb/input.h> 31#include <linux/usb/input.h>
32#include <linux/hid.h> 32#include <linux/hid.h>
33 33
34/* for apple IDs */
35#ifdef CONFIG_USB_HID_MODULE
36#include "../hid-ids.h"
37#endif
38
34/* 39/*
35 * Version Information 40 * Version Information
36 */ 41 */
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 0644fd33b983..75cc1531dd84 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -264,13 +264,7 @@ struct hid_item {
264#define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x00000080 264#define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x00000080
265#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100 265#define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100
266#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200 266#define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200
267#define HID_QUIRK_MIGHTYMOUSE 0x00000400
268#define HID_QUIRK_APPLE_HAS_FN 0x00000800
269#define HID_QUIRK_APPLE_FN_ON 0x00001000
270#define HID_QUIRK_INVERT_HWHEEL 0x00002000
271#define HID_QUIRK_APPLE_ISO_KEYBOARD 0x00004000
272#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000 267#define HID_QUIRK_SKIP_OUTPUT_REPORTS 0x00010000
273#define HID_QUIRK_IGNORE_MOUSE 0x00020000
274#define HID_QUIRK_SONY_PS3_CONTROLLER 0x00040000 268#define HID_QUIRK_SONY_PS3_CONTROLLER 0x00040000
275#define HID_QUIRK_RESET_LEDS 0x00100000 269#define HID_QUIRK_RESET_LEDS 0x00100000
276#define HID_QUIRK_HIDINPUT 0x00200000 270#define HID_QUIRK_HIDINPUT 0x00200000
@@ -279,7 +273,6 @@ struct hid_item {
279#define HID_QUIRK_HWHEEL_WHEEL_INVERT 0x04000000 273#define HID_QUIRK_HWHEEL_WHEEL_INVERT 0x04000000
280#define HID_QUIRK_MICROSOFT_KEYS 0x08000000 274#define HID_QUIRK_MICROSOFT_KEYS 0x08000000
281#define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000 275#define HID_QUIRK_FULLSPEED_INTERVAL 0x10000000
282#define HID_QUIRK_APPLE_NUMLOCK_EMULATION 0x20000000
283 276
284/* 277/*
285 * Separate quirks for runtime report descriptor fixup 278 * Separate quirks for runtime report descriptor fixup
@@ -288,7 +281,6 @@ struct hid_item {
288#define HID_QUIRK_RDESC_CYMOTION 0x00000001 281#define HID_QUIRK_RDESC_CYMOTION 0x00000001
289#define HID_QUIRK_RDESC_SWAPPED_MIN_MAX 0x00000004 282#define HID_QUIRK_RDESC_SWAPPED_MIN_MAX 0x00000004
290#define HID_QUIRK_RDESC_PETALYNX 0x00000008 283#define HID_QUIRK_RDESC_PETALYNX 0x00000008
291#define HID_QUIRK_RDESC_MACBOOK_JIS 0x00000010
292#define HID_QUIRK_RDESC_BUTTON_CONSUMER 0x00000020 284#define HID_QUIRK_RDESC_BUTTON_CONSUMER 0x00000020
293#define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000040 285#define HID_QUIRK_RDESC_SAMSUNG_REMOTE 0x00000040
294#define HID_QUIRK_RDESC_MICROSOFT_RECV_1028 0x00000080 286#define HID_QUIRK_RDESC_MICROSOFT_RECV_1028 0x00000080
@@ -475,10 +467,6 @@ struct hid_device { /* device report descriptor */
475 467
476 /* handler for raw output data, used by hidraw */ 468 /* handler for raw output data, used by hidraw */
477 int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t); 469 int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t);
478#ifdef CONFIG_USB_HIDINPUT_POWERBOOK
479 unsigned long apple_pressed_fn[BITS_TO_LONGS(KEY_CNT)];
480 unsigned long pb_pressed_numlock[BITS_TO_LONGS(KEY_CNT)];
481#endif
482}; 470};
483 471
484static inline void *hid_get_drvdata(struct hid_device *hdev) 472static inline void *hid_get_drvdata(struct hid_device *hdev)
@@ -652,7 +640,6 @@ int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int
652int hidinput_mapping_quirks(struct hid_usage *, struct hid_input *, 640int hidinput_mapping_quirks(struct hid_usage *, struct hid_input *,
653 unsigned long **, int *); 641 unsigned long **, int *);
654int hidinput_event_quirks(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); 642int hidinput_event_quirks(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
655int hidinput_apple_event(struct hid_device *, struct input_dev *, struct hid_usage *, __s32);
656void hid_output_report(struct hid_report *report, __u8 *data); 643void hid_output_report(struct hid_report *report, __u8 *data);
657struct hid_device *hid_allocate_device(void); 644struct hid_device *hid_allocate_device(void);
658int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); 645int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index 4ae3207e8a98..f3d830747b96 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -683,27 +683,6 @@ static void hidp_close(struct hid_device *hid)
683{ 683{
684} 684}
685 685
686static const struct {
687 __u16 idVendor;
688 __u16 idProduct;
689 unsigned quirks;
690} hidp_blacklist[] = {
691 /* Apple wireless Mighty Mouse */
692 { 0x05ac, 0x030c, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL },
693
694 { } /* Terminating entry */
695};
696
697static void hidp_setup_quirks(struct hid_device *hid)
698{
699 unsigned int n;
700
701 for (n = 0; hidp_blacklist[n].idVendor; n++)
702 if (hidp_blacklist[n].idVendor == le16_to_cpu(hid->vendor) &&
703 hidp_blacklist[n].idProduct == le16_to_cpu(hid->product))
704 hid->quirks = hidp_blacklist[n].quirks;
705}
706
707static int hidp_parse(struct hid_device *hid) 686static int hidp_parse(struct hid_device *hid)
708{ 687{
709 struct hidp_session *session = hid->driver_data; 688 struct hidp_session *session = hid->driver_data;
@@ -729,7 +708,6 @@ static int hidp_parse(struct hid_device *hid)
729 708
730 session->req = NULL; 709 session->req = NULL;
731 710
732 hidp_setup_quirks(hid);
733 return 0; 711 return 0;
734} 712}
735 713