diff options
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/Kconfig | 7 | ||||
-rw-r--r-- | drivers/hid/Makefile | 1 | ||||
-rw-r--r-- | drivers/hid/hid-a4tech.c | 162 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-dummy.c | 3 | ||||
-rw-r--r-- | drivers/hid/hid-input-quirks.c | 25 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 9 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 4 |
8 files changed, 175 insertions, 38 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 69f3420882a6..01456b1d3833 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
@@ -82,6 +82,13 @@ config HID_COMPAT | |||
82 | 82 | ||
83 | If unsure, say Y. | 83 | If unsure, say Y. |
84 | 84 | ||
85 | config HID_A4TECH | ||
86 | tristate "A4 tech" | ||
87 | default m | ||
88 | depends on USB_HID | ||
89 | ---help--- | ||
90 | Support for A4 tech X5 and WOP-35 / Trust 450L mice. | ||
91 | |||
85 | config HID_APPLE | 92 | config HID_APPLE |
86 | tristate "Apple" | 93 | tristate "Apple" |
87 | default m | 94 | default m |
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 061066201186..ceede11eed7c 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
@@ -12,6 +12,7 @@ ifdef CONFIG_HID_COMPAT | |||
12 | obj-m += hid-dummy.o | 12 | obj-m += hid-dummy.o |
13 | endif | 13 | endif |
14 | 14 | ||
15 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o | ||
15 | obj-$(CONFIG_HID_APPLE) += hid-apple.o | 16 | obj-$(CONFIG_HID_APPLE) += hid-apple.o |
16 | obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o | 17 | obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o |
17 | obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o | 18 | obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o |
diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c new file mode 100644 index 000000000000..26e16083a1f1 --- /dev/null +++ b/drivers/hid/hid-a4tech.c | |||
@@ -0,0 +1,162 @@ | |||
1 | /* | ||
2 | * HID driver for some a4tech "special" devices | ||
3 | * | ||
4 | * Copyright (c) 1999 Andreas Gal | ||
5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> | ||
6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc | ||
7 | * Copyright (c) 2006-2007 Jiri Kosina | ||
8 | * Copyright (c) 2007 Paul Walmsley | ||
9 | * Copyright (c) 2008 Jiri Slaby | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * This program is free software; you can redistribute it and/or modify it | ||
14 | * under the terms of the GNU General Public License as published by the Free | ||
15 | * Software Foundation; either version 2 of the License, or (at your option) | ||
16 | * any later version. | ||
17 | */ | ||
18 | |||
19 | #include <linux/device.h> | ||
20 | #include <linux/input.h> | ||
21 | #include <linux/hid.h> | ||
22 | #include <linux/module.h> | ||
23 | |||
24 | #include "hid-ids.h" | ||
25 | |||
26 | #define A4_2WHEEL_MOUSE_HACK_7 0x01 | ||
27 | #define A4_2WHEEL_MOUSE_HACK_B8 0x02 | ||
28 | |||
29 | struct a4tech_sc { | ||
30 | unsigned long quirks; | ||
31 | unsigned int hw_wheel; | ||
32 | __s32 delayed_value; | ||
33 | }; | ||
34 | |||
35 | static int a4_input_mapped(struct hid_device *hdev, struct hid_input *hi, | ||
36 | struct hid_field *field, struct hid_usage *usage, | ||
37 | unsigned long **bit, int *max) | ||
38 | { | ||
39 | struct a4tech_sc *a4 = hid_get_drvdata(hdev); | ||
40 | |||
41 | if (usage->type == EV_REL && usage->code == REL_WHEEL) | ||
42 | set_bit(REL_HWHEEL, *bit); | ||
43 | |||
44 | if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007) | ||
45 | return -1; | ||
46 | |||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | static int a4_event(struct hid_device *hdev, struct hid_field *field, | ||
51 | struct hid_usage *usage, __s32 value) | ||
52 | { | ||
53 | struct a4tech_sc *a4 = hid_get_drvdata(hdev); | ||
54 | struct input_dev *input; | ||
55 | |||
56 | if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput || | ||
57 | !usage->type) | ||
58 | return 0; | ||
59 | |||
60 | input = field->hidinput->input; | ||
61 | |||
62 | if (a4->quirks & A4_2WHEEL_MOUSE_HACK_B8) { | ||
63 | if (usage->type == EV_REL && usage->code == REL_WHEEL) { | ||
64 | a4->delayed_value = value; | ||
65 | return 1; | ||
66 | } | ||
67 | |||
68 | if (usage->hid == 0x000100b8) { | ||
69 | input_event(input, EV_REL, value ? REL_HWHEEL : | ||
70 | REL_WHEEL, a4->delayed_value); | ||
71 | return 1; | ||
72 | } | ||
73 | } | ||
74 | |||
75 | if ((a4->quirks & A4_2WHEEL_MOUSE_HACK_7) && usage->hid == 0x00090007) { | ||
76 | a4->hw_wheel = !!value; | ||
77 | return 1; | ||
78 | } | ||
79 | |||
80 | if (usage->code == REL_WHEEL && a4->hw_wheel) { | ||
81 | input_event(input, usage->type, REL_HWHEEL, value); | ||
82 | return 1; | ||
83 | } | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id) | ||
89 | { | ||
90 | struct a4tech_sc *a4; | ||
91 | int ret; | ||
92 | |||
93 | a4 = kzalloc(sizeof(*a4), GFP_KERNEL); | ||
94 | if (a4 == NULL) { | ||
95 | dev_err(&hdev->dev, "can't alloc device descriptor\n"); | ||
96 | ret = -ENOMEM; | ||
97 | goto err_free; | ||
98 | } | ||
99 | |||
100 | a4->quirks = id->driver_data; | ||
101 | |||
102 | hid_set_drvdata(hdev, a4); | ||
103 | |||
104 | ret = hid_parse(hdev); | ||
105 | if (ret) { | ||
106 | dev_err(&hdev->dev, "parse failed\n"); | ||
107 | goto err_free; | ||
108 | } | ||
109 | |||
110 | ret = hid_hw_start(hdev); | ||
111 | if (ret) { | ||
112 | dev_err(&hdev->dev, "hw start failed\n"); | ||
113 | goto err_free; | ||
114 | } | ||
115 | |||
116 | return 0; | ||
117 | err_free: | ||
118 | kfree(a4); | ||
119 | return ret; | ||
120 | } | ||
121 | |||
122 | static void a4_remove(struct hid_device *hdev) | ||
123 | { | ||
124 | struct a4tech_sc *a4 = hid_get_drvdata(hdev); | ||
125 | |||
126 | hid_hw_stop(hdev); | ||
127 | kfree(a4); | ||
128 | } | ||
129 | |||
130 | static const struct hid_device_id a4_devices[] = { | ||
131 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU), | ||
132 | .driver_data = A4_2WHEEL_MOUSE_HACK_7 }, | ||
133 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D), | ||
134 | .driver_data = A4_2WHEEL_MOUSE_HACK_B8 }, | ||
135 | { } | ||
136 | }; | ||
137 | MODULE_DEVICE_TABLE(hid, a4_devices); | ||
138 | |||
139 | static struct hid_driver a4_driver = { | ||
140 | .name = "a4tech", | ||
141 | .id_table = a4_devices, | ||
142 | .input_mapped = a4_input_mapped, | ||
143 | .event = a4_event, | ||
144 | .probe = a4_probe, | ||
145 | .remove = a4_remove, | ||
146 | }; | ||
147 | |||
148 | static int a4_init(void) | ||
149 | { | ||
150 | return hid_register_driver(&a4_driver); | ||
151 | } | ||
152 | |||
153 | static void a4_exit(void) | ||
154 | { | ||
155 | hid_unregister_driver(&a4_driver); | ||
156 | } | ||
157 | |||
158 | module_init(a4_init); | ||
159 | module_exit(a4_exit); | ||
160 | MODULE_LICENSE("GPL"); | ||
161 | |||
162 | HID_COMPAT_LOAD_DRIVER(a4tech); | ||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 331670b32e68..be582976db2c 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1132,6 +1132,8 @@ static const struct hid_device_id *hid_match_id(struct hid_device *hdev, | |||
1132 | } | 1132 | } |
1133 | 1133 | ||
1134 | static const struct hid_device_id hid_blacklist[] = { | 1134 | static const struct hid_device_id hid_blacklist[] = { |
1135 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, | ||
1136 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, | ||
1135 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, | 1137 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, |
1136 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, | 1138 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, |
1137 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, | 1139 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, |
diff --git a/drivers/hid/hid-dummy.c b/drivers/hid/hid-dummy.c index 27cffe3586f5..123f1c71cdf2 100644 --- a/drivers/hid/hid-dummy.c +++ b/drivers/hid/hid-dummy.c | |||
@@ -4,6 +4,9 @@ | |||
4 | 4 | ||
5 | static int __init hid_dummy_init(void) | 5 | static int __init hid_dummy_init(void) |
6 | { | 6 | { |
7 | #ifdef CONFIG_HID_A4TECH_MODULE | ||
8 | HID_COMPAT_CALL_DRIVER(a4tech); | ||
9 | #endif | ||
7 | #ifdef CONFIG_HID_APPLE_MODULE | 10 | #ifdef CONFIG_HID_APPLE_MODULE |
8 | HID_COMPAT_CALL_DRIVER(apple); | 11 | HID_COMPAT_CALL_DRIVER(apple); |
9 | #endif | 12 | #endif |
diff --git a/drivers/hid/hid-input-quirks.c b/drivers/hid/hid-input-quirks.c index 6e7314f7b998..5bacf181a8ca 100644 --- a/drivers/hid/hid-input-quirks.c +++ b/drivers/hid/hid-input-quirks.c | |||
@@ -236,31 +236,6 @@ int hidinput_event_quirks(struct hid_device *hid, struct hid_field *field, struc | |||
236 | 236 | ||
237 | input = field->hidinput->input; | 237 | input = field->hidinput->input; |
238 | 238 | ||
239 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && | ||
240 | (usage->hid == 0x00090007)) { | ||
241 | if (value) hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON; | ||
242 | else hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON; | ||
243 | return 1; | ||
244 | } | ||
245 | |||
246 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) && | ||
247 | (usage->type == EV_REL) && | ||
248 | (usage->code == REL_WHEEL)) { | ||
249 | hid->delayed_value = value; | ||
250 | return 1; | ||
251 | } | ||
252 | |||
253 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_B8) && | ||
254 | (usage->hid == 0x000100b8)) { | ||
255 | input_event(input, EV_REL, value ? REL_HWHEEL : REL_WHEEL, hid->delayed_value); | ||
256 | return 1; | ||
257 | } | ||
258 | |||
259 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) { | ||
260 | input_event(input, usage->type, REL_HWHEEL, value); | ||
261 | return 1; | ||
262 | } | ||
263 | |||
264 | /* handle the temporary quirky mapping to HWHEEL */ | 239 | /* handle the temporary quirky mapping to HWHEEL */ |
265 | if (hid->quirks & HID_QUIRK_HWHEEL_WHEEL_INVERT && | 240 | if (hid->quirks & HID_QUIRK_HWHEEL_WHEEL_INVERT && |
266 | usage->type == EV_REL && usage->code == REL_HWHEEL) { | 241 | usage->type == EV_REL && usage->code == REL_HWHEEL) { |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index f1df25ab0baa..1d2d0827820c 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -515,15 +515,6 @@ mapped: | |||
515 | hidinput, field, usage, &bit, &max) < 0) | 515 | hidinput, field, usage, &bit, &max) < 0) |
516 | goto ignore; | 516 | goto ignore; |
517 | 517 | ||
518 | if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | | ||
519 | HID_QUIRK_2WHEEL_MOUSE_HACK_B8)) && (usage->type == EV_REL) && | ||
520 | (usage->code == REL_WHEEL)) | ||
521 | set_bit(REL_HWHEEL, bit); | ||
522 | |||
523 | if ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && | ||
524 | (usage->hid == 0x00090007)) | ||
525 | goto ignore; | ||
526 | |||
527 | set_bit(usage->type, input->evbit); | 518 | set_bit(usage->type, input->evbit); |
528 | 519 | ||
529 | while (usage->code <= max && test_and_set_bit(usage->code, bit)) | 520 | while (usage->code <= max && test_and_set_bit(usage->code, bit)) |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index da80c64fb25c..1d12fb24829c 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -28,10 +28,6 @@ static const struct hid_blacklist { | |||
28 | __u16 idProduct; | 28 | __u16 idProduct; |
29 | __u32 quirks; | 29 | __u32 quirks; |
30 | } hid_blacklist[] = { | 30 | } hid_blacklist[] = { |
31 | |||
32 | { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU, HID_QUIRK_2WHEEL_MOUSE_HACK_7 }, | ||
33 | { USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D, HID_QUIRK_2WHEEL_MOUSE_HACK_B8 }, | ||
34 | |||
35 | { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD }, | 31 | { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_GAMEPAD, HID_QUIRK_BADPAD }, |
36 | { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD }, | 32 | { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD }, |
37 | { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, | 33 | { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, |