aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/Kconfig7
-rw-r--r--drivers/hid/Makefile1
-rw-r--r--drivers/hid/hid-a4tech.c162
-rw-r--r--drivers/hid/hid-core.c2
-rw-r--r--drivers/hid/hid-dummy.c3
-rw-r--r--drivers/hid/hid-input-quirks.c25
-rw-r--r--drivers/hid/hid-input.c9
-rw-r--r--drivers/hid/usbhid/hid-quirks.c4
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
85config 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
85config HID_APPLE 92config 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
12obj-m += hid-dummy.o 12obj-m += hid-dummy.o
13endif 13endif
14 14
15obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o
15obj-$(CONFIG_HID_APPLE) += hid-apple.o 16obj-$(CONFIG_HID_APPLE) += hid-apple.o
16obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o 17obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o
17obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o 18obj-$(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
29struct a4tech_sc {
30 unsigned long quirks;
31 unsigned int hw_wheel;
32 __s32 delayed_value;
33};
34
35static 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
50static 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
88static 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;
117err_free:
118 kfree(a4);
119 return ret;
120}
121
122static 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
130static 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};
137MODULE_DEVICE_TABLE(hid, a4_devices);
138
139static 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
148static int a4_init(void)
149{
150 return hid_register_driver(&a4_driver);
151}
152
153static void a4_exit(void)
154{
155 hid_unregister_driver(&a4_driver);
156}
157
158module_init(a4_init);
159module_exit(a4_exit);
160MODULE_LICENSE("GPL");
161
162HID_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
1134static const struct hid_device_id hid_blacklist[] = { 1134static 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
5static int __init hid_dummy_init(void) 5static 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 },