diff options
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/Kconfig | 72 | ||||
-rw-r--r-- | drivers/hid/Makefile | 3 | ||||
-rw-r--r-- | drivers/hid/hid-3m-pct.c | 127 | ||||
-rw-r--r-- | drivers/hid/hid-a4tech.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-cando.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 12 | ||||
-rw-r--r-- | drivers/hid/hid-debug.c | 3 | ||||
-rw-r--r-- | drivers/hid/hid-egalax.c | 16 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 20 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 83 | ||||
-rw-r--r-- | drivers/hid/hid-lg.c | 41 | ||||
-rw-r--r-- | drivers/hid/hid-lg.h | 6 | ||||
-rw-r--r-- | drivers/hid/hid-lg2ff.c | 4 | ||||
-rw-r--r-- | drivers/hid/hid-lg4ff.c | 136 | ||||
-rw-r--r-- | drivers/hid/hid-magicmouse.c | 325 | ||||
-rw-r--r-- | drivers/hid/hid-mosart.c | 1 | ||||
-rw-r--r-- | drivers/hid/hid-ntrig.c | 69 | ||||
-rw-r--r-- | drivers/hid/hid-roccat.c | 1 | ||||
-rw-r--r-- | drivers/hid/hid-sony.c | 49 | ||||
-rw-r--r-- | drivers/hid/hid-stantum.c | 2 | ||||
-rw-r--r-- | drivers/hid/hid-topseed.c | 1 | ||||
-rw-r--r-- | drivers/hid/hidraw.c | 26 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 17 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-quirks.c | 7 | ||||
-rw-r--r-- | drivers/hid/usbhid/hiddev.c | 43 | ||||
-rw-r--r-- | drivers/hid/usbhid/usbhid.h | 1 |
26 files changed, 759 insertions, 310 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index b07440a172b5..68a7e862068e 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig | |||
@@ -56,20 +56,20 @@ menu "Special HID drivers" | |||
56 | depends on HID | 56 | depends on HID |
57 | 57 | ||
58 | config HID_3M_PCT | 58 | config HID_3M_PCT |
59 | tristate "3M PCT" | 59 | tristate "3M PCT touchscreen" |
60 | depends on USB_HID | 60 | depends on USB_HID |
61 | ---help--- | 61 | ---help--- |
62 | Support for 3M PCT touch screens. | 62 | Support for 3M PCT touch screens. |
63 | 63 | ||
64 | config HID_A4TECH | 64 | config HID_A4TECH |
65 | tristate "A4 tech" if EMBEDDED | 65 | tristate "A4 tech mice" if EMBEDDED |
66 | depends on USB_HID | 66 | depends on USB_HID |
67 | default !EMBEDDED | 67 | default !EMBEDDED |
68 | ---help--- | 68 | ---help--- |
69 | Support for A4 tech X5 and WOP-35 / Trust 450L mice. | 69 | Support for A4 tech X5 and WOP-35 / Trust 450L mice. |
70 | 70 | ||
71 | config HID_ACRUX_FF | 71 | config HID_ACRUX_FF |
72 | tristate "ACRUX force feedback support" | 72 | tristate "ACRUX force feedback" |
73 | depends on USB_HID | 73 | depends on USB_HID |
74 | select INPUT_FF_MEMLESS | 74 | select INPUT_FF_MEMLESS |
75 | ---help--- | 75 | ---help--- |
@@ -77,7 +77,7 @@ config HID_ACRUX_FF | |||
77 | game controllers. | 77 | game controllers. |
78 | 78 | ||
79 | config HID_APPLE | 79 | config HID_APPLE |
80 | tristate "Apple" if EMBEDDED | 80 | tristate "Apple {i,Power,Mac}Books" if EMBEDDED |
81 | depends on (USB_HID || BT_HIDP) | 81 | depends on (USB_HID || BT_HIDP) |
82 | default !EMBEDDED | 82 | default !EMBEDDED |
83 | ---help--- | 83 | ---help--- |
@@ -88,7 +88,7 @@ config HID_APPLE | |||
88 | MacBooks, MacBook Pros and Apple Aluminum. | 88 | MacBooks, MacBook Pros and Apple Aluminum. |
89 | 89 | ||
90 | config HID_BELKIN | 90 | config HID_BELKIN |
91 | tristate "Belkin" if EMBEDDED | 91 | tristate "Belkin Flip KVM and Wireless keyboard" if EMBEDDED |
92 | depends on USB_HID | 92 | depends on USB_HID |
93 | default !EMBEDDED | 93 | default !EMBEDDED |
94 | ---help--- | 94 | ---help--- |
@@ -101,14 +101,14 @@ config HID_CANDO | |||
101 | Support for Cando dual touch panel. | 101 | Support for Cando dual touch panel. |
102 | 102 | ||
103 | config HID_CHERRY | 103 | config HID_CHERRY |
104 | tristate "Cherry" if EMBEDDED | 104 | tristate "Cherry Cymotion keyboard" if EMBEDDED |
105 | depends on USB_HID | 105 | depends on USB_HID |
106 | default !EMBEDDED | 106 | default !EMBEDDED |
107 | ---help--- | 107 | ---help--- |
108 | Support for Cherry Cymotion keyboard. | 108 | Support for Cherry Cymotion keyboard. |
109 | 109 | ||
110 | config HID_CHICONY | 110 | config HID_CHICONY |
111 | tristate "Chicony" if EMBEDDED | 111 | tristate "Chicony Tactical pad" if EMBEDDED |
112 | depends on USB_HID | 112 | depends on USB_HID |
113 | default !EMBEDDED | 113 | default !EMBEDDED |
114 | ---help--- | 114 | ---help--- |
@@ -130,20 +130,20 @@ config HID_PRODIKEYS | |||
130 | and some additional multimedia keys. | 130 | and some additional multimedia keys. |
131 | 131 | ||
132 | config HID_CYPRESS | 132 | config HID_CYPRESS |
133 | tristate "Cypress" if EMBEDDED | 133 | tristate "Cypress mouse and barcode readers" if EMBEDDED |
134 | depends on USB_HID | 134 | depends on USB_HID |
135 | default !EMBEDDED | 135 | default !EMBEDDED |
136 | ---help--- | 136 | ---help--- |
137 | Support for cypress mouse and barcode readers. | 137 | Support for cypress mouse and barcode readers. |
138 | 138 | ||
139 | config HID_DRAGONRISE | 139 | config HID_DRAGONRISE |
140 | tristate "DragonRise Inc. support" | 140 | tristate "DragonRise Inc. game controller" |
141 | depends on USB_HID | 141 | depends on USB_HID |
142 | ---help--- | 142 | ---help--- |
143 | Say Y here if you have DragonRise Inc.game controllers. | 143 | Say Y here if you have DragonRise Inc.game controllers. |
144 | 144 | ||
145 | config DRAGONRISE_FF | 145 | config DRAGONRISE_FF |
146 | bool "DragonRise Inc. force feedback support" | 146 | bool "DragonRise Inc. force feedback" |
147 | depends on HID_DRAGONRISE | 147 | depends on HID_DRAGONRISE |
148 | select INPUT_FF_MEMLESS | 148 | select INPUT_FF_MEMLESS |
149 | ---help--- | 149 | ---help--- |
@@ -157,46 +157,46 @@ config HID_EGALAX | |||
157 | Support for the eGalax dual-touch panel. | 157 | Support for the eGalax dual-touch panel. |
158 | 158 | ||
159 | config HID_ELECOM | 159 | config HID_ELECOM |
160 | tristate "ELECOM" | 160 | tristate "ELECOM BM084 bluetooth mouse" |
161 | depends on BT_HIDP | 161 | depends on BT_HIDP |
162 | ---help--- | 162 | ---help--- |
163 | Support for the ELECOM BM084 (bluetooth mouse). | 163 | Support for the ELECOM BM084 (bluetooth mouse). |
164 | 164 | ||
165 | config HID_EZKEY | 165 | config HID_EZKEY |
166 | tristate "Ezkey" if EMBEDDED | 166 | tristate "Ezkey BTC 8193 keyboard" if EMBEDDED |
167 | depends on USB_HID | 167 | depends on USB_HID |
168 | default !EMBEDDED | 168 | default !EMBEDDED |
169 | ---help--- | 169 | ---help--- |
170 | Support for Ezkey BTC 8193 keyboard. | 170 | Support for Ezkey BTC 8193 keyboard. |
171 | 171 | ||
172 | config HID_KYE | 172 | config HID_KYE |
173 | tristate "Kye" if EMBEDDED | 173 | tristate "Kye/Genius Ergo Mouse" if EMBEDDED |
174 | depends on USB_HID | 174 | depends on USB_HID |
175 | default !EMBEDDED | 175 | default !EMBEDDED |
176 | ---help--- | 176 | ---help--- |
177 | Support for Kye/Genius Ergo Mouse. | 177 | Support for Kye/Genius Ergo Mouse. |
178 | 178 | ||
179 | config HID_GYRATION | 179 | config HID_GYRATION |
180 | tristate "Gyration" | 180 | tristate "Gyration remote control" |
181 | depends on USB_HID | 181 | depends on USB_HID |
182 | ---help--- | 182 | ---help--- |
183 | Support for Gyration remote control. | 183 | Support for Gyration remote control. |
184 | 184 | ||
185 | config HID_TWINHAN | 185 | config HID_TWINHAN |
186 | tristate "Twinhan" | 186 | tristate "Twinhan IR remote control" |
187 | depends on USB_HID | 187 | depends on USB_HID |
188 | ---help--- | 188 | ---help--- |
189 | Support for Twinhan IR remote control. | 189 | Support for Twinhan IR remote control. |
190 | 190 | ||
191 | config HID_KENSINGTON | 191 | config HID_KENSINGTON |
192 | tristate "Kensington" if EMBEDDED | 192 | tristate "Kensington Slimblade Trackball" if EMBEDDED |
193 | depends on USB_HID | 193 | depends on USB_HID |
194 | default !EMBEDDED | 194 | default !EMBEDDED |
195 | ---help--- | 195 | ---help--- |
196 | Support for Kensington Slimblade Trackball. | 196 | Support for Kensington Slimblade Trackball. |
197 | 197 | ||
198 | config HID_LOGITECH | 198 | config HID_LOGITECH |
199 | tristate "Logitech" if EMBEDDED | 199 | tristate "Logitech devices" if EMBEDDED |
200 | depends on USB_HID | 200 | depends on USB_HID |
201 | default !EMBEDDED | 201 | default !EMBEDDED |
202 | ---help--- | 202 | ---help--- |
@@ -220,12 +220,12 @@ config LOGITECH_FF | |||
220 | force feedback. | 220 | force feedback. |
221 | 221 | ||
222 | config LOGIRUMBLEPAD2_FF | 222 | config LOGIRUMBLEPAD2_FF |
223 | bool "Logitech Rumblepad 2 force feedback support" | 223 | bool "Logitech RumblePad/Rumblepad 2 force feedback support" |
224 | depends on HID_LOGITECH | 224 | depends on HID_LOGITECH |
225 | select INPUT_FF_MEMLESS | 225 | select INPUT_FF_MEMLESS |
226 | help | 226 | help |
227 | Say Y here if you want to enable force feedback support for Logitech | 227 | Say Y here if you want to enable force feedback support for Logitech |
228 | Rumblepad 2 devices. | 228 | RumblePad and Rumblepad 2 devices. |
229 | 229 | ||
230 | config LOGIG940_FF | 230 | config LOGIG940_FF |
231 | bool "Logitech Flight System G940 force feedback support" | 231 | bool "Logitech Flight System G940 force feedback support" |
@@ -235,6 +235,14 @@ config LOGIG940_FF | |||
235 | Say Y here if you want to enable force feedback support for Logitech | 235 | Say Y here if you want to enable force feedback support for Logitech |
236 | Flight System G940 devices. | 236 | Flight System G940 devices. |
237 | 237 | ||
238 | config LOGIWII_FF | ||
239 | bool "Logitech Speed Force Wireless force feedback support" | ||
240 | depends on HID_LOGITECH | ||
241 | select INPUT_FF_MEMLESS | ||
242 | help | ||
243 | Say Y here if you want to enable force feedback support for Logitech | ||
244 | Speed Force Wireless (Wii) devices. | ||
245 | |||
238 | config HID_MAGICMOUSE | 246 | config HID_MAGICMOUSE |
239 | tristate "Apple MagicMouse multi-touch support" | 247 | tristate "Apple MagicMouse multi-touch support" |
240 | depends on BT_HIDP | 248 | depends on BT_HIDP |
@@ -245,39 +253,39 @@ config HID_MAGICMOUSE | |||
245 | Apple Wireless "Magic" Mouse. | 253 | Apple Wireless "Magic" Mouse. |
246 | 254 | ||
247 | config HID_MICROSOFT | 255 | config HID_MICROSOFT |
248 | tristate "Microsoft" if EMBEDDED | 256 | tristate "Microsoft non-fully HID-compliant devices" if EMBEDDED |
249 | depends on USB_HID | 257 | depends on USB_HID |
250 | default !EMBEDDED | 258 | default !EMBEDDED |
251 | ---help--- | 259 | ---help--- |
252 | Support for Microsoft devices that are not fully compliant with HID standard. | 260 | Support for Microsoft devices that are not fully compliant with HID standard. |
253 | 261 | ||
254 | config HID_MOSART | 262 | config HID_MOSART |
255 | tristate "MosArt" | 263 | tristate "MosArt dual-touch panels" |
256 | depends on USB_HID | 264 | depends on USB_HID |
257 | ---help--- | 265 | ---help--- |
258 | Support for MosArt dual-touch panels. | 266 | Support for MosArt dual-touch panels. |
259 | 267 | ||
260 | config HID_MONTEREY | 268 | config HID_MONTEREY |
261 | tristate "Monterey" if EMBEDDED | 269 | tristate "Monterey Genius KB29E keyboard" if EMBEDDED |
262 | depends on USB_HID | 270 | depends on USB_HID |
263 | default !EMBEDDED | 271 | default !EMBEDDED |
264 | ---help--- | 272 | ---help--- |
265 | Support for Monterey Genius KB29E. | 273 | Support for Monterey Genius KB29E. |
266 | 274 | ||
267 | config HID_NTRIG | 275 | config HID_NTRIG |
268 | tristate "NTrig" | 276 | tristate "N-Trig touch screen" |
269 | depends on USB_HID | 277 | depends on USB_HID |
270 | ---help--- | 278 | ---help--- |
271 | Support for N-Trig touch screen. | 279 | Support for N-Trig touch screen. |
272 | 280 | ||
273 | config HID_ORTEK | 281 | config HID_ORTEK |
274 | tristate "Ortek" | 282 | tristate "Ortek WKB-2000 wireless keyboard and mouse trackpad" |
275 | depends on USB_HID | 283 | depends on USB_HID |
276 | ---help--- | 284 | ---help--- |
277 | Support for Ortek WKB-2000 wireless keyboard + mouse trackpad. | 285 | Support for Ortek WKB-2000 wireless keyboard + mouse trackpad. |
278 | 286 | ||
279 | config HID_PANTHERLORD | 287 | config HID_PANTHERLORD |
280 | tristate "Pantherlord support" | 288 | tristate "Pantherlord/GreenAsia game controller" |
281 | depends on USB_HID | 289 | depends on USB_HID |
282 | ---help--- | 290 | ---help--- |
283 | Say Y here if you have a PantherLord/GreenAsia based game controller | 291 | Say Y here if you have a PantherLord/GreenAsia based game controller |
@@ -292,7 +300,7 @@ config PANTHERLORD_FF | |||
292 | or adapter and want to enable force feedback support for it. | 300 | or adapter and want to enable force feedback support for it. |
293 | 301 | ||
294 | config HID_PETALYNX | 302 | config HID_PETALYNX |
295 | tristate "Petalynx" | 303 | tristate "Petalynx Maxter remote control" |
296 | depends on USB_HID | 304 | depends on USB_HID |
297 | ---help--- | 305 | ---help--- |
298 | Support for Petalynx Maxter remote control. | 306 | Support for Petalynx Maxter remote control. |
@@ -356,7 +364,7 @@ config HID_PICOLCD_LEDS | |||
356 | Provide access to PicoLCD's GPO pins via leds class. | 364 | Provide access to PicoLCD's GPO pins via leds class. |
357 | 365 | ||
358 | config HID_QUANTA | 366 | config HID_QUANTA |
359 | tristate "Quanta Optical Touch" | 367 | tristate "Quanta Optical Touch panels" |
360 | depends on USB_HID | 368 | depends on USB_HID |
361 | ---help--- | 369 | ---help--- |
362 | Support for Quanta Optical Touch dual-touch panels. | 370 | Support for Quanta Optical Touch dual-touch panels. |
@@ -384,31 +392,31 @@ config HID_ROCCAT_PYRA | |||
384 | Support for Roccat Pyra mouse. | 392 | Support for Roccat Pyra mouse. |
385 | 393 | ||
386 | config HID_SAMSUNG | 394 | config HID_SAMSUNG |
387 | tristate "Samsung" | 395 | tristate "Samsung InfraRed remote control or keyboards" |
388 | depends on USB_HID | 396 | depends on USB_HID |
389 | ---help--- | 397 | ---help--- |
390 | Support for Samsung InfraRed remote control or keyboards. | 398 | Support for Samsung InfraRed remote control or keyboards. |
391 | 399 | ||
392 | config HID_SONY | 400 | config HID_SONY |
393 | tristate "Sony" | 401 | tristate "Sony PS3 controller" |
394 | depends on USB_HID | 402 | depends on USB_HID |
395 | ---help--- | 403 | ---help--- |
396 | Support for Sony PS3 controller. | 404 | Support for Sony PS3 controller. |
397 | 405 | ||
398 | config HID_STANTUM | 406 | config HID_STANTUM |
399 | tristate "Stantum" | 407 | tristate "Stantum multitouch panel" |
400 | depends on USB_HID | 408 | depends on USB_HID |
401 | ---help--- | 409 | ---help--- |
402 | Support for Stantum multitouch panel. | 410 | Support for Stantum multitouch panel. |
403 | 411 | ||
404 | config HID_SUNPLUS | 412 | config HID_SUNPLUS |
405 | tristate "Sunplus" | 413 | tristate "Sunplus wireless desktop" |
406 | depends on USB_HID | 414 | depends on USB_HID |
407 | ---help--- | 415 | ---help--- |
408 | Support for Sunplus wireless desktop. | 416 | Support for Sunplus wireless desktop. |
409 | 417 | ||
410 | config HID_GREENASIA | 418 | config HID_GREENASIA |
411 | tristate "GreenAsia (Product ID 0x12) support" | 419 | tristate "GreenAsia (Product ID 0x12) game controller support" |
412 | depends on USB_HID | 420 | depends on USB_HID |
413 | ---help--- | 421 | ---help--- |
414 | Say Y here if you have a GreenAsia (Product ID 0x12) based game | 422 | Say Y here if you have a GreenAsia (Product ID 0x12) based game |
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index d224fa342187..ad74abcc73d5 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile | |||
@@ -21,6 +21,9 @@ endif | |||
21 | ifdef CONFIG_LOGIG940_FF | 21 | ifdef CONFIG_LOGIG940_FF |
22 | hid-logitech-objs += hid-lg3ff.o | 22 | hid-logitech-objs += hid-lg3ff.o |
23 | endif | 23 | endif |
24 | ifdef CONFIG_LOGIWII_FF | ||
25 | hid-logitech-objs += hid-lg4ff.o | ||
26 | endif | ||
24 | 27 | ||
25 | obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o | 28 | obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o |
26 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o | 29 | obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o |
diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c index 2a0d56b7a02b..02d8cd3b1b1b 100644 --- a/drivers/hid/hid-3m-pct.c +++ b/drivers/hid/hid-3m-pct.c | |||
@@ -2,6 +2,8 @@ | |||
2 | * HID driver for 3M PCT multitouch panels | 2 | * HID driver for 3M PCT multitouch panels |
3 | * | 3 | * |
4 | * Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr> | 4 | * Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr> |
5 | * Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se> | ||
6 | * Copyright (c) 2010 Canonical, Ltd. | ||
5 | * | 7 | * |
6 | */ | 8 | */ |
7 | 9 | ||
@@ -24,15 +26,26 @@ MODULE_LICENSE("GPL"); | |||
24 | 26 | ||
25 | #include "hid-ids.h" | 27 | #include "hid-ids.h" |
26 | 28 | ||
29 | #define MAX_SLOTS 60 | ||
30 | #define MAX_TRKID USHRT_MAX | ||
31 | #define MAX_EVENTS 360 | ||
32 | |||
33 | /* estimated signal-to-noise ratios */ | ||
34 | #define SN_MOVE 2048 | ||
35 | #define SN_WIDTH 128 | ||
36 | |||
27 | struct mmm_finger { | 37 | struct mmm_finger { |
28 | __s32 x, y, w, h; | 38 | __s32 x, y, w, h; |
29 | __u8 rank; | 39 | __u16 id; |
40 | bool prev_touch; | ||
30 | bool touch, valid; | 41 | bool touch, valid; |
31 | }; | 42 | }; |
32 | 43 | ||
33 | struct mmm_data { | 44 | struct mmm_data { |
34 | struct mmm_finger f[10]; | 45 | struct mmm_finger f[MAX_SLOTS]; |
35 | __u8 curid, num; | 46 | __u16 id; |
47 | __u8 curid; | ||
48 | __u8 nexp, nreal; | ||
36 | bool touch, valid; | 49 | bool touch, valid; |
37 | }; | 50 | }; |
38 | 51 | ||
@@ -40,6 +53,10 @@ static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
40 | struct hid_field *field, struct hid_usage *usage, | 53 | struct hid_field *field, struct hid_usage *usage, |
41 | unsigned long **bit, int *max) | 54 | unsigned long **bit, int *max) |
42 | { | 55 | { |
56 | int f1 = field->logical_minimum; | ||
57 | int f2 = field->logical_maximum; | ||
58 | int df = f2 - f1; | ||
59 | |||
43 | switch (usage->hid & HID_USAGE_PAGE) { | 60 | switch (usage->hid & HID_USAGE_PAGE) { |
44 | 61 | ||
45 | case HID_UP_BUTTON: | 62 | case HID_UP_BUTTON: |
@@ -50,18 +67,20 @@ static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
50 | case HID_GD_X: | 67 | case HID_GD_X: |
51 | hid_map_usage(hi, usage, bit, max, | 68 | hid_map_usage(hi, usage, bit, max, |
52 | EV_ABS, ABS_MT_POSITION_X); | 69 | EV_ABS, ABS_MT_POSITION_X); |
70 | input_set_abs_params(hi->input, ABS_MT_POSITION_X, | ||
71 | f1, f2, df / SN_MOVE, 0); | ||
53 | /* touchscreen emulation */ | 72 | /* touchscreen emulation */ |
54 | input_set_abs_params(hi->input, ABS_X, | 73 | input_set_abs_params(hi->input, ABS_X, |
55 | field->logical_minimum, | 74 | f1, f2, df / SN_MOVE, 0); |
56 | field->logical_maximum, 0, 0); | ||
57 | return 1; | 75 | return 1; |
58 | case HID_GD_Y: | 76 | case HID_GD_Y: |
59 | hid_map_usage(hi, usage, bit, max, | 77 | hid_map_usage(hi, usage, bit, max, |
60 | EV_ABS, ABS_MT_POSITION_Y); | 78 | EV_ABS, ABS_MT_POSITION_Y); |
79 | input_set_abs_params(hi->input, ABS_MT_POSITION_Y, | ||
80 | f1, f2, df / SN_MOVE, 0); | ||
61 | /* touchscreen emulation */ | 81 | /* touchscreen emulation */ |
62 | input_set_abs_params(hi->input, ABS_Y, | 82 | input_set_abs_params(hi->input, ABS_Y, |
63 | field->logical_minimum, | 83 | f1, f2, df / SN_MOVE, 0); |
64 | field->logical_maximum, 0, 0); | ||
65 | return 1; | 84 | return 1; |
66 | } | 85 | } |
67 | return 0; | 86 | return 0; |
@@ -81,21 +100,31 @@ static int mmm_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
81 | case HID_DG_TIPSWITCH: | 100 | case HID_DG_TIPSWITCH: |
82 | /* touchscreen emulation */ | 101 | /* touchscreen emulation */ |
83 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); | 102 | hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH); |
103 | input_set_capability(hi->input, EV_KEY, BTN_TOUCH); | ||
84 | return 1; | 104 | return 1; |
85 | case HID_DG_WIDTH: | 105 | case HID_DG_WIDTH: |
86 | hid_map_usage(hi, usage, bit, max, | 106 | hid_map_usage(hi, usage, bit, max, |
87 | EV_ABS, ABS_MT_TOUCH_MAJOR); | 107 | EV_ABS, ABS_MT_TOUCH_MAJOR); |
108 | input_set_abs_params(hi->input, ABS_MT_TOUCH_MAJOR, | ||
109 | f1, f2, df / SN_WIDTH, 0); | ||
88 | return 1; | 110 | return 1; |
89 | case HID_DG_HEIGHT: | 111 | case HID_DG_HEIGHT: |
90 | hid_map_usage(hi, usage, bit, max, | 112 | hid_map_usage(hi, usage, bit, max, |
91 | EV_ABS, ABS_MT_TOUCH_MINOR); | 113 | EV_ABS, ABS_MT_TOUCH_MINOR); |
114 | input_set_abs_params(hi->input, ABS_MT_TOUCH_MINOR, | ||
115 | f1, f2, df / SN_WIDTH, 0); | ||
92 | input_set_abs_params(hi->input, ABS_MT_ORIENTATION, | 116 | input_set_abs_params(hi->input, ABS_MT_ORIENTATION, |
93 | 1, 1, 0, 0); | 117 | 0, 1, 0, 0); |
94 | return 1; | 118 | return 1; |
95 | case HID_DG_CONTACTID: | 119 | case HID_DG_CONTACTID: |
96 | field->logical_maximum = 59; | 120 | field->logical_maximum = MAX_TRKID; |
97 | hid_map_usage(hi, usage, bit, max, | 121 | hid_map_usage(hi, usage, bit, max, |
98 | EV_ABS, ABS_MT_TRACKING_ID); | 122 | EV_ABS, ABS_MT_TRACKING_ID); |
123 | input_set_abs_params(hi->input, ABS_MT_TRACKING_ID, | ||
124 | 0, MAX_TRKID, 0, 0); | ||
125 | if (!hi->input->mt) | ||
126 | input_mt_create_slots(hi->input, MAX_SLOTS); | ||
127 | input_set_events_per_packet(hi->input, MAX_EVENTS); | ||
99 | return 1; | 128 | return 1; |
100 | } | 129 | } |
101 | /* let hid-input decide for the others */ | 130 | /* let hid-input decide for the others */ |
@@ -113,10 +142,10 @@ static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi, | |||
113 | struct hid_field *field, struct hid_usage *usage, | 142 | struct hid_field *field, struct hid_usage *usage, |
114 | unsigned long **bit, int *max) | 143 | unsigned long **bit, int *max) |
115 | { | 144 | { |
145 | /* tell hid-input to skip setup of these event types */ | ||
116 | if (usage->type == EV_KEY || usage->type == EV_ABS) | 146 | if (usage->type == EV_KEY || usage->type == EV_ABS) |
117 | clear_bit(usage->code, *bit); | 147 | set_bit(usage->type, hi->input->evbit); |
118 | 148 | return -1; | |
119 | return 0; | ||
120 | } | 149 | } |
121 | 150 | ||
122 | /* | 151 | /* |
@@ -126,70 +155,49 @@ static int mmm_input_mapped(struct hid_device *hdev, struct hid_input *hi, | |||
126 | static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) | 155 | static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) |
127 | { | 156 | { |
128 | struct mmm_finger *oldest = 0; | 157 | struct mmm_finger *oldest = 0; |
129 | bool pressed = false, released = false; | ||
130 | int i; | 158 | int i; |
131 | 159 | for (i = 0; i < MAX_SLOTS; ++i) { | |
132 | /* | ||
133 | * we need to iterate on all fingers to decide if we have a press | ||
134 | * or a release event in our touchscreen emulation. | ||
135 | */ | ||
136 | for (i = 0; i < 10; ++i) { | ||
137 | struct mmm_finger *f = &md->f[i]; | 160 | struct mmm_finger *f = &md->f[i]; |
138 | if (!f->valid) { | 161 | if (!f->valid) { |
139 | /* this finger is just placeholder data, ignore */ | 162 | /* this finger is just placeholder data, ignore */ |
140 | } else if (f->touch) { | 163 | continue; |
164 | } | ||
165 | input_mt_slot(input, i); | ||
166 | if (f->touch) { | ||
141 | /* this finger is on the screen */ | 167 | /* this finger is on the screen */ |
142 | int wide = (f->w > f->h); | 168 | int wide = (f->w > f->h); |
143 | input_event(input, EV_ABS, ABS_MT_TRACKING_ID, i); | 169 | /* divided by two to match visual scale of touch */ |
170 | int major = max(f->w, f->h) >> 1; | ||
171 | int minor = min(f->w, f->h) >> 1; | ||
172 | |||
173 | if (!f->prev_touch) | ||
174 | f->id = md->id++; | ||
175 | input_event(input, EV_ABS, ABS_MT_TRACKING_ID, f->id); | ||
144 | input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x); | 176 | input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x); |
145 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y); | 177 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y); |
146 | input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); | 178 | input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide); |
147 | input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, | 179 | input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); |
148 | wide ? f->w : f->h); | 180 | input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); |
149 | input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, | 181 | /* touchscreen emulation: pick the oldest contact */ |
150 | wide ? f->h : f->w); | 182 | if (!oldest || ((f->id - oldest->id) & (SHRT_MAX + 1))) |
151 | input_mt_sync(input); | ||
152 | /* | ||
153 | * touchscreen emulation: maintain the age rank | ||
154 | * of this finger, decide if we have a press | ||
155 | */ | ||
156 | if (f->rank == 0) { | ||
157 | f->rank = ++(md->num); | ||
158 | if (f->rank == 1) | ||
159 | pressed = true; | ||
160 | } | ||
161 | if (f->rank == 1) | ||
162 | oldest = f; | 183 | oldest = f; |
163 | } else { | 184 | } else { |
164 | /* this finger took off the screen */ | 185 | /* this finger took off the screen */ |
165 | /* touchscreen emulation: maintain age rank of others */ | 186 | input_event(input, EV_ABS, ABS_MT_TRACKING_ID, -1); |
166 | int j; | ||
167 | |||
168 | for (j = 0; j < 10; ++j) { | ||
169 | struct mmm_finger *g = &md->f[j]; | ||
170 | if (g->rank > f->rank) { | ||
171 | g->rank--; | ||
172 | if (g->rank == 1) | ||
173 | oldest = g; | ||
174 | } | ||
175 | } | ||
176 | f->rank = 0; | ||
177 | --(md->num); | ||
178 | if (md->num == 0) | ||
179 | released = true; | ||
180 | } | 187 | } |
188 | f->prev_touch = f->touch; | ||
181 | f->valid = 0; | 189 | f->valid = 0; |
182 | } | 190 | } |
183 | 191 | ||
184 | /* touchscreen emulation */ | 192 | /* touchscreen emulation */ |
185 | if (oldest) { | 193 | if (oldest) { |
186 | if (pressed) | 194 | input_event(input, EV_KEY, BTN_TOUCH, 1); |
187 | input_event(input, EV_KEY, BTN_TOUCH, 1); | ||
188 | input_event(input, EV_ABS, ABS_X, oldest->x); | 195 | input_event(input, EV_ABS, ABS_X, oldest->x); |
189 | input_event(input, EV_ABS, ABS_Y, oldest->y); | 196 | input_event(input, EV_ABS, ABS_Y, oldest->y); |
190 | } else if (released) { | 197 | } else { |
191 | input_event(input, EV_KEY, BTN_TOUCH, 0); | 198 | input_event(input, EV_KEY, BTN_TOUCH, 0); |
192 | } | 199 | } |
200 | input_sync(input); | ||
193 | } | 201 | } |
194 | 202 | ||
195 | /* | 203 | /* |
@@ -223,10 +231,12 @@ static int mmm_event(struct hid_device *hid, struct hid_field *field, | |||
223 | md->f[md->curid].h = value; | 231 | md->f[md->curid].h = value; |
224 | break; | 232 | break; |
225 | case HID_DG_CONTACTID: | 233 | case HID_DG_CONTACTID: |
234 | value = clamp_val(value, 0, MAX_SLOTS - 1); | ||
226 | if (md->valid) { | 235 | if (md->valid) { |
227 | md->curid = value; | 236 | md->curid = value; |
228 | md->f[value].touch = md->touch; | 237 | md->f[value].touch = md->touch; |
229 | md->f[value].valid = 1; | 238 | md->f[value].valid = 1; |
239 | md->nreal++; | ||
230 | } | 240 | } |
231 | break; | 241 | break; |
232 | case HID_GD_X: | 242 | case HID_GD_X: |
@@ -238,7 +248,12 @@ static int mmm_event(struct hid_device *hid, struct hid_field *field, | |||
238 | md->f[md->curid].y = value; | 248 | md->f[md->curid].y = value; |
239 | break; | 249 | break; |
240 | case HID_DG_CONTACTCOUNT: | 250 | case HID_DG_CONTACTCOUNT: |
241 | mmm_filter_event(md, input); | 251 | if (value) |
252 | md->nexp = value; | ||
253 | if (md->nreal >= md->nexp) { | ||
254 | mmm_filter_event(md, input); | ||
255 | md->nreal = 0; | ||
256 | } | ||
242 | break; | 257 | break; |
243 | } | 258 | } |
244 | } | 259 | } |
@@ -255,6 +270,8 @@ static int mmm_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
255 | int ret; | 270 | int ret; |
256 | struct mmm_data *md; | 271 | struct mmm_data *md; |
257 | 272 | ||
273 | hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC; | ||
274 | |||
258 | md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL); | 275 | md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL); |
259 | if (!md) { | 276 | if (!md) { |
260 | dev_err(&hdev->dev, "cannot allocate 3M data\n"); | 277 | dev_err(&hdev->dev, "cannot allocate 3M data\n"); |
diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c index 3a2b223c1da4..1666c1684e79 100644 --- a/drivers/hid/hid-a4tech.c +++ b/drivers/hid/hid-a4tech.c | |||
@@ -133,6 +133,8 @@ static const struct hid_device_id a4_devices[] = { | |||
133 | .driver_data = A4_2WHEEL_MOUSE_HACK_7 }, | 133 | .driver_data = A4_2WHEEL_MOUSE_HACK_7 }, |
134 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D), | 134 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D), |
135 | .driver_data = A4_2WHEEL_MOUSE_HACK_B8 }, | 135 | .driver_data = A4_2WHEEL_MOUSE_HACK_B8 }, |
136 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649), | ||
137 | .driver_data = A4_2WHEEL_MOUSE_HACK_B8 }, | ||
136 | { } | 138 | { } |
137 | }; | 139 | }; |
138 | MODULE_DEVICE_TABLE(hid, a4_devices); | 140 | MODULE_DEVICE_TABLE(hid, a4_devices); |
diff --git a/drivers/hid/hid-cando.c b/drivers/hid/hid-cando.c index 4267a6fdc277..5925bdcd417d 100644 --- a/drivers/hid/hid-cando.c +++ b/drivers/hid/hid-cando.c | |||
@@ -237,6 +237,8 @@ static const struct hid_device_id cando_devices[] = { | |||
237 | USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, | 237 | USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, |
238 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | 238 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, |
239 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, | 239 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, |
240 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, | ||
241 | USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, | ||
240 | { } | 242 | { } |
241 | }; | 243 | }; |
242 | MODULE_DEVICE_TABLE(hid, cando_devices); | 244 | MODULE_DEVICE_TABLE(hid, cando_devices); |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 18608b89e76b..cb7dc99d8b29 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1241,6 +1241,7 @@ static const struct hid_device_id hid_blacklist[] = { | |||
1241 | { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) }, | 1241 | { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) }, |
1242 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, | 1242 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, |
1243 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, | 1243 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, |
1244 | { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) }, | ||
1244 | #if defined(CONFIG_HID_ACRUX_FF) || defined(CONFIG_HID_ACRUX_FF_MODULE) | 1245 | #if defined(CONFIG_HID_ACRUX_FF) || defined(CONFIG_HID_ACRUX_FF_MODULE) |
1245 | { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) }, | 1246 | { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) }, |
1246 | #endif | 1247 | #endif |
@@ -1248,6 +1249,7 @@ static const struct hid_device_id hid_blacklist[] = { | |||
1248 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, | 1249 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, |
1249 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, | 1250 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, |
1250 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) }, | 1251 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) }, |
1252 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) }, | ||
1251 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, | 1253 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI) }, |
1252 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) }, | 1254 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO) }, |
1253 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) }, | 1255 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) }, |
@@ -1285,10 +1287,14 @@ static const struct hid_device_id hid_blacklist[] = { | |||
1285 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, | 1287 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, |
1286 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, | 1288 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, |
1287 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, | 1289 | { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, |
1290 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) }, | ||
1291 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, | ||
1288 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, | 1292 | { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) }, |
1289 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, | 1293 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, |
1294 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, | ||
1290 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, | 1295 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH) }, |
1291 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, | 1296 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) }, |
1297 | { HID_USB_DEVICE(USB_VENDOR_ID_CANDO, USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) }, | ||
1292 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, | 1298 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, |
1293 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, | 1299 | { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, |
1294 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, | 1300 | { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, |
@@ -1323,6 +1329,7 @@ static const struct hid_device_id hid_blacklist[] = { | |||
1323 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, | 1329 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, |
1324 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, | 1330 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, |
1325 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) }, | 1331 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) }, |
1332 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) }, | ||
1326 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, | 1333 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, |
1327 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, | 1334 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, |
1328 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, | 1335 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, |
@@ -1332,6 +1339,7 @@ static const struct hid_device_id hid_blacklist[] = { | |||
1332 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) }, | 1339 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) }, |
1333 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) }, | 1340 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) }, |
1334 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) }, | 1341 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) }, |
1342 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) }, | ||
1335 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, | 1343 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, |
1336 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) }, | 1344 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) }, |
1337 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) }, | 1345 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) }, |
@@ -1374,6 +1382,8 @@ static const struct hid_device_id hid_blacklist[] = { | |||
1374 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, | 1382 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, |
1375 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, | 1383 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, |
1376 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) }, | 1384 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) }, |
1385 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM) }, | ||
1386 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX) }, | ||
1377 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, | 1387 | { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, |
1378 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, | 1388 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, |
1379 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, | 1389 | { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, |
@@ -1579,7 +1589,6 @@ static const struct hid_device_id hid_ignore_list[] = { | |||
1579 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24) }, | 1589 | { HID_USB_DEVICE(USB_VENDOR_ID_AIPTEK, USB_DEVICE_ID_AIPTEK_24) }, |
1580 | { HID_USB_DEVICE(USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1) }, | 1590 | { HID_USB_DEVICE(USB_VENDOR_ID_AIRCABLE, USB_DEVICE_ID_AIRCABLE1) }, |
1581 | { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) }, | 1591 | { HID_USB_DEVICE(USB_VENDOR_ID_ALCOR, USB_DEVICE_ID_ALCOR_USBRS232) }, |
1582 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT)}, | ||
1583 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM)}, | 1592 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM)}, |
1584 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM2)}, | 1593 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_LCM2)}, |
1585 | { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, | 1594 | { HID_USB_DEVICE(USB_VENDOR_ID_AVERMEDIA, USB_DEVICE_ID_AVER_FM_MR800) }, |
@@ -1660,6 +1669,7 @@ static const struct hid_device_id hid_ignore_list[] = { | |||
1660 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) }, | 1669 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) }, |
1661 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) }, | 1670 | { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) }, |
1662 | { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) }, | 1671 | { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) }, |
1672 | { HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_JESS_YUREX) }, | ||
1663 | { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) }, | 1673 | { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) }, |
1664 | { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) }, | 1674 | { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) }, |
1665 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) }, | 1675 | { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) }, |
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index 850d02a7a925..75c5e23d09d2 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c | |||
@@ -570,6 +570,8 @@ void hid_debug_event(struct hid_device *hdev, char *buf) | |||
570 | buf[i]; | 570 | buf[i]; |
571 | list->tail = (list->tail + i) % HID_DEBUG_BUFSIZE; | 571 | list->tail = (list->tail + i) % HID_DEBUG_BUFSIZE; |
572 | } | 572 | } |
573 | |||
574 | wake_up_interruptible(&hdev->debug_wait); | ||
573 | } | 575 | } |
574 | EXPORT_SYMBOL_GPL(hid_debug_event); | 576 | EXPORT_SYMBOL_GPL(hid_debug_event); |
575 | 577 | ||
@@ -1051,6 +1053,7 @@ static const struct file_operations hid_debug_events_fops = { | |||
1051 | .read = hid_debug_events_read, | 1053 | .read = hid_debug_events_read, |
1052 | .poll = hid_debug_events_poll, | 1054 | .poll = hid_debug_events_poll, |
1053 | .release = hid_debug_events_release, | 1055 | .release = hid_debug_events_release, |
1056 | .llseek = noop_llseek, | ||
1054 | }; | 1057 | }; |
1055 | 1058 | ||
1056 | 1059 | ||
diff --git a/drivers/hid/hid-egalax.c b/drivers/hid/hid-egalax.c index 8ca7f65cf2f8..54b017ad258d 100644 --- a/drivers/hid/hid-egalax.c +++ b/drivers/hid/hid-egalax.c | |||
@@ -31,7 +31,7 @@ struct egalax_data { | |||
31 | bool first; /* is this the first finger in the frame? */ | 31 | bool first; /* is this the first finger in the frame? */ |
32 | bool valid; /* valid finger data, or just placeholder? */ | 32 | bool valid; /* valid finger data, or just placeholder? */ |
33 | bool activity; /* at least one active finger previously? */ | 33 | bool activity; /* at least one active finger previously? */ |
34 | __u16 lastx, lasty; /* latest valid (x, y) in the frame */ | 34 | __u16 lastx, lasty, lastz; /* latest valid (x, y, z) in the frame */ |
35 | }; | 35 | }; |
36 | 36 | ||
37 | static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 37 | static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
@@ -79,6 +79,10 @@ static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
79 | case HID_DG_TIPPRESSURE: | 79 | case HID_DG_TIPPRESSURE: |
80 | hid_map_usage(hi, usage, bit, max, | 80 | hid_map_usage(hi, usage, bit, max, |
81 | EV_ABS, ABS_MT_PRESSURE); | 81 | EV_ABS, ABS_MT_PRESSURE); |
82 | /* touchscreen emulation */ | ||
83 | input_set_abs_params(hi->input, ABS_PRESSURE, | ||
84 | field->logical_minimum, | ||
85 | field->logical_maximum, 0, 0); | ||
82 | return 1; | 86 | return 1; |
83 | } | 87 | } |
84 | return 0; | 88 | return 0; |
@@ -109,8 +113,8 @@ static void egalax_filter_event(struct egalax_data *td, struct input_dev *input) | |||
109 | if (td->valid) { | 113 | if (td->valid) { |
110 | /* emit multitouch events */ | 114 | /* emit multitouch events */ |
111 | input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id); | 115 | input_event(input, EV_ABS, ABS_MT_TRACKING_ID, td->id); |
112 | input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x); | 116 | input_event(input, EV_ABS, ABS_MT_POSITION_X, td->x >> 3); |
113 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y); | 117 | input_event(input, EV_ABS, ABS_MT_POSITION_Y, td->y >> 3); |
114 | input_event(input, EV_ABS, ABS_MT_PRESSURE, td->z); | 118 | input_event(input, EV_ABS, ABS_MT_PRESSURE, td->z); |
115 | 119 | ||
116 | input_mt_sync(input); | 120 | input_mt_sync(input); |
@@ -121,6 +125,7 @@ static void egalax_filter_event(struct egalax_data *td, struct input_dev *input) | |||
121 | */ | 125 | */ |
122 | td->lastx = td->x; | 126 | td->lastx = td->x; |
123 | td->lasty = td->y; | 127 | td->lasty = td->y; |
128 | td->lastz = td->z; | ||
124 | } | 129 | } |
125 | 130 | ||
126 | /* | 131 | /* |
@@ -129,8 +134,9 @@ static void egalax_filter_event(struct egalax_data *td, struct input_dev *input) | |||
129 | * the oldest on the panel, the one we want for single touch | 134 | * the oldest on the panel, the one we want for single touch |
130 | */ | 135 | */ |
131 | if (!td->first && td->activity) { | 136 | if (!td->first && td->activity) { |
132 | input_event(input, EV_ABS, ABS_X, td->lastx); | 137 | input_event(input, EV_ABS, ABS_X, td->lastx >> 3); |
133 | input_event(input, EV_ABS, ABS_Y, td->lasty); | 138 | input_event(input, EV_ABS, ABS_Y, td->lasty >> 3); |
139 | input_event(input, EV_ABS, ABS_PRESSURE, td->lastz); | ||
134 | } | 140 | } |
135 | 141 | ||
136 | if (!td->valid) { | 142 | if (!td->valid) { |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 5787b1a1339f..ae8f74431d92 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -25,6 +25,7 @@ | |||
25 | #define USB_VENDOR_ID_A4TECH 0x09da | 25 | #define USB_VENDOR_ID_A4TECH 0x09da |
26 | #define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 | 26 | #define USB_DEVICE_ID_A4TECH_WCP32PU 0x0006 |
27 | #define USB_DEVICE_ID_A4TECH_X5_005D 0x000a | 27 | #define USB_DEVICE_ID_A4TECH_X5_005D 0x000a |
28 | #define USB_DEVICE_ID_A4TECH_RP_649 0x001a | ||
28 | 29 | ||
29 | #define USB_VENDOR_ID_AASHIMA 0x06d6 | 30 | #define USB_VENDOR_ID_AASHIMA 0x06d6 |
30 | #define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 | 31 | #define USB_DEVICE_ID_AASHIMA_GAMEPAD 0x0025 |
@@ -63,6 +64,7 @@ | |||
63 | #define USB_VENDOR_ID_APPLE 0x05ac | 64 | #define USB_VENDOR_ID_APPLE 0x05ac |
64 | #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 | 65 | #define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304 |
65 | #define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d | 66 | #define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d |
67 | #define USB_DEVICE_ID_APPLE_MAGICTRACKPAD 0x030e | ||
66 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e | 68 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI 0x020e |
67 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f | 69 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_ISO 0x020f |
68 | #define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214 | 70 | #define USB_DEVICE_ID_APPLE_GEYSER_ANSI 0x0214 |
@@ -105,6 +107,7 @@ | |||
105 | 107 | ||
106 | #define USB_VENDOR_ID_ASUS 0x0486 | 108 | #define USB_VENDOR_ID_ASUS 0x0486 |
107 | #define USB_DEVICE_ID_ASUS_T91MT 0x0185 | 109 | #define USB_DEVICE_ID_ASUS_T91MT 0x0185 |
110 | #define USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO 0x0186 | ||
108 | 111 | ||
109 | #define USB_VENDOR_ID_ASUSTEK 0x0b05 | 112 | #define USB_VENDOR_ID_ASUSTEK 0x0b05 |
110 | #define USB_DEVICE_ID_ASUSTEK_LCM 0x1726 | 113 | #define USB_DEVICE_ID_ASUSTEK_LCM 0x1726 |
@@ -128,10 +131,12 @@ | |||
128 | 131 | ||
129 | #define USB_VENDOR_ID_BTC 0x046e | 132 | #define USB_VENDOR_ID_BTC 0x046e |
130 | #define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578 | 133 | #define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578 |
134 | #define USB_DEVICE_ID_BTC_EMPREX_REMOTE_2 0x5577 | ||
131 | 135 | ||
132 | #define USB_VENDOR_ID_CANDO 0x2087 | 136 | #define USB_VENDOR_ID_CANDO 0x2087 |
133 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01 | 137 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01 |
134 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6 0x0b03 | 138 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6 0x0b03 |
139 | #define USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6 0x0f01 | ||
135 | 140 | ||
136 | #define USB_VENDOR_ID_CH 0x068e | 141 | #define USB_VENDOR_ID_CH 0x068e |
137 | #define USB_DEVICE_ID_CH_PRO_PEDALS 0x00f2 | 142 | #define USB_DEVICE_ID_CH_PRO_PEDALS 0x00f2 |
@@ -139,6 +144,7 @@ | |||
139 | #define USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE 0x0051 | 144 | #define USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE 0x0051 |
140 | #define USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE 0x00ff | 145 | #define USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE 0x00ff |
141 | #define USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK 0x00d3 | 146 | #define USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK 0x00d3 |
147 | #define USB_DEVICE_ID_CH_AXIS_295 0x001c | ||
142 | 148 | ||
143 | #define USB_VENDOR_ID_CHERRY 0x046a | 149 | #define USB_VENDOR_ID_CHERRY 0x046a |
144 | #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 | 150 | #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 |
@@ -149,6 +155,7 @@ | |||
149 | 155 | ||
150 | #define USB_VENDOR_ID_CHICONY 0x04f2 | 156 | #define USB_VENDOR_ID_CHICONY 0x04f2 |
151 | #define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418 | 157 | #define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418 |
158 | #define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d | ||
152 | 159 | ||
153 | #define USB_VENDOR_ID_CIDC 0x1677 | 160 | #define USB_VENDOR_ID_CIDC 0x1677 |
154 | 161 | ||
@@ -300,6 +307,9 @@ | |||
300 | #define USB_VENDOR_ID_IMATION 0x0718 | 307 | #define USB_VENDOR_ID_IMATION 0x0718 |
301 | #define USB_DEVICE_ID_DISC_STAKKA 0xd000 | 308 | #define USB_DEVICE_ID_DISC_STAKKA 0xd000 |
302 | 309 | ||
310 | #define USB_VENDOR_ID_JESS 0x0c45 | ||
311 | #define USB_DEVICE_ID_JESS_YUREX 0x1010 | ||
312 | |||
303 | #define USB_VENDOR_ID_KBGEAR 0x084e | 313 | #define USB_VENDOR_ID_KBGEAR 0x084e |
304 | #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 | 314 | #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 |
305 | 315 | ||
@@ -336,6 +346,7 @@ | |||
336 | #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 | 346 | #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 |
337 | #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 | 347 | #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 |
338 | #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f | 348 | #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f |
349 | #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD 0xc20a | ||
339 | #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211 | 350 | #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211 |
340 | #define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215 | 351 | #define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215 |
341 | #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 | 352 | #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 |
@@ -347,6 +358,7 @@ | |||
347 | #define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293 | 358 | #define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293 |
348 | #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 | 359 | #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 |
349 | #define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299 | 360 | #define USB_DEVICE_ID_LOGITECH_G25_WHEEL 0xc299 |
361 | #define USB_DEVICE_ID_LOGITECH_WII_WHEEL 0xc29c | ||
350 | #define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a | 362 | #define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a |
351 | #define USB_DEVICE_ID_S510_RECEIVER 0xc50c | 363 | #define USB_DEVICE_ID_S510_RECEIVER 0xc50c |
352 | #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 | 364 | #define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 |
@@ -480,6 +492,12 @@ | |||
480 | #define USB_VENDOR_ID_STANTUM 0x1f87 | 492 | #define USB_VENDOR_ID_STANTUM 0x1f87 |
481 | #define USB_DEVICE_ID_MTP 0x0002 | 493 | #define USB_DEVICE_ID_MTP 0x0002 |
482 | 494 | ||
495 | #define USB_VENDOR_ID_STANTUM_STM 0x0483 | ||
496 | #define USB_DEVICE_ID_MTP_STM 0x3261 | ||
497 | |||
498 | #define USB_VENDOR_ID_STANTUM_SITRONIX 0x1403 | ||
499 | #define USB_DEVICE_ID_MTP_SITRONIX 0x5001 | ||
500 | |||
483 | #define USB_VENDOR_ID_SUN 0x0430 | 501 | #define USB_VENDOR_ID_SUN 0x0430 |
484 | #define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab | 502 | #define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab |
485 | 503 | ||
@@ -502,6 +520,7 @@ | |||
502 | 520 | ||
503 | #define USB_VENDOR_ID_TURBOX 0x062a | 521 | #define USB_VENDOR_ID_TURBOX 0x062a |
504 | #define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 | 522 | #define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 |
523 | #define USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART 0x7100 | ||
505 | 524 | ||
506 | #define USB_VENDOR_ID_TWINHAN 0x6253 | 525 | #define USB_VENDOR_ID_TWINHAN 0x6253 |
507 | #define USB_DEVICE_ID_TWINHAN_IR_REMOTE 0x0100 | 526 | #define USB_DEVICE_ID_TWINHAN_IR_REMOTE 0x0100 |
@@ -509,6 +528,7 @@ | |||
509 | #define USB_VENDOR_ID_UCLOGIC 0x5543 | 528 | #define USB_VENDOR_ID_UCLOGIC 0x5543 |
510 | #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042 | 529 | #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042 |
511 | #define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003 | 530 | #define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003 |
531 | #define USB_DEVICE_ID_UCLOGIC_TABLET_KNA5 0x6001 | ||
512 | 532 | ||
513 | #define USB_VENDOR_ID_VERNIER 0x08f7 | 533 | #define USB_VENDOR_ID_VERNIER 0x08f7 |
514 | #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 | 534 | #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 6c03dcc5760a..b9877a86eca7 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -149,6 +149,83 @@ static int hidinput_setkeycode(struct input_dev *dev, | |||
149 | } | 149 | } |
150 | 150 | ||
151 | 151 | ||
152 | /** | ||
153 | * hidinput_calc_abs_res - calculate an absolute axis resolution | ||
154 | * @field: the HID report field to calculate resolution for | ||
155 | * @code: axis code | ||
156 | * | ||
157 | * The formula is: | ||
158 | * (logical_maximum - logical_minimum) | ||
159 | * resolution = ---------------------------------------------------------- | ||
160 | * (physical_maximum - physical_minimum) * 10 ^ unit_exponent | ||
161 | * | ||
162 | * as seen in the HID specification v1.11 6.2.2.7 Global Items. | ||
163 | * | ||
164 | * Only exponent 1 length units are processed. Centimeters are converted to | ||
165 | * inches. Degrees are converted to radians. | ||
166 | */ | ||
167 | static __s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code) | ||
168 | { | ||
169 | __s32 unit_exponent = field->unit_exponent; | ||
170 | __s32 logical_extents = field->logical_maximum - | ||
171 | field->logical_minimum; | ||
172 | __s32 physical_extents = field->physical_maximum - | ||
173 | field->physical_minimum; | ||
174 | __s32 prev; | ||
175 | |||
176 | /* Check if the extents are sane */ | ||
177 | if (logical_extents <= 0 || physical_extents <= 0) | ||
178 | return 0; | ||
179 | |||
180 | /* | ||
181 | * Verify and convert units. | ||
182 | * See HID specification v1.11 6.2.2.7 Global Items for unit decoding | ||
183 | */ | ||
184 | if (code == ABS_X || code == ABS_Y || code == ABS_Z) { | ||
185 | if (field->unit == 0x11) { /* If centimeters */ | ||
186 | /* Convert to inches */ | ||
187 | prev = logical_extents; | ||
188 | logical_extents *= 254; | ||
189 | if (logical_extents < prev) | ||
190 | return 0; | ||
191 | unit_exponent += 2; | ||
192 | } else if (field->unit != 0x13) { /* If not inches */ | ||
193 | return 0; | ||
194 | } | ||
195 | } else if (code == ABS_RX || code == ABS_RY || code == ABS_RZ) { | ||
196 | if (field->unit == 0x14) { /* If degrees */ | ||
197 | /* Convert to radians */ | ||
198 | prev = logical_extents; | ||
199 | logical_extents *= 573; | ||
200 | if (logical_extents < prev) | ||
201 | return 0; | ||
202 | unit_exponent += 1; | ||
203 | } else if (field->unit != 0x12) { /* If not radians */ | ||
204 | return 0; | ||
205 | } | ||
206 | } else { | ||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | /* Apply negative unit exponent */ | ||
211 | for (; unit_exponent < 0; unit_exponent++) { | ||
212 | prev = logical_extents; | ||
213 | logical_extents *= 10; | ||
214 | if (logical_extents < prev) | ||
215 | return 0; | ||
216 | } | ||
217 | /* Apply positive unit exponent */ | ||
218 | for (; unit_exponent > 0; unit_exponent--) { | ||
219 | prev = physical_extents; | ||
220 | physical_extents *= 10; | ||
221 | if (physical_extents < prev) | ||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | /* Calculate resolution */ | ||
226 | return logical_extents / physical_extents; | ||
227 | } | ||
228 | |||
152 | static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, | 229 | static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, |
153 | struct hid_usage *usage) | 230 | struct hid_usage *usage) |
154 | { | 231 | { |
@@ -537,6 +614,9 @@ mapped: | |||
537 | input_set_abs_params(input, usage->code, a, b, (b - a) >> 8, (b - a) >> 4); | 614 | input_set_abs_params(input, usage->code, a, b, (b - a) >> 8, (b - a) >> 4); |
538 | else input_set_abs_params(input, usage->code, a, b, 0, 0); | 615 | else input_set_abs_params(input, usage->code, a, b, 0, 0); |
539 | 616 | ||
617 | input_abs_set_res(input, usage->code, | ||
618 | hidinput_calc_abs_res(field, usage->code)); | ||
619 | |||
540 | /* use a larger default input buffer for MT devices */ | 620 | /* use a larger default input buffer for MT devices */ |
541 | if (usage->code == ABS_MT_POSITION_X && input->hint_events_per_packet == 0) | 621 | if (usage->code == ABS_MT_POSITION_X && input->hint_events_per_packet == 0) |
542 | input_set_events_per_packet(input, 60); | 622 | input_set_events_per_packet(input, 60); |
@@ -659,6 +739,9 @@ void hidinput_report_event(struct hid_device *hid, struct hid_report *report) | |||
659 | { | 739 | { |
660 | struct hid_input *hidinput; | 740 | struct hid_input *hidinput; |
661 | 741 | ||
742 | if (hid->quirks & HID_QUIRK_NO_INPUT_SYNC) | ||
743 | return; | ||
744 | |||
662 | list_for_each_entry(hidinput, &hid->inputs, list) | 745 | list_for_each_entry(hidinput, &hid->inputs, list) |
663 | input_sync(hidinput->input); | 746 | input_sync(hidinput->input); |
664 | } | 747 | } |
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index f6433d8050a9..9e92c27002ca 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * Copyright (c) 2006-2007 Jiri Kosina | 7 | * Copyright (c) 2006-2007 Jiri Kosina |
8 | * Copyright (c) 2007 Paul Walmsley | 8 | * Copyright (c) 2007 Paul Walmsley |
9 | * Copyright (c) 2008 Jiri Slaby | 9 | * Copyright (c) 2008 Jiri Slaby |
10 | * Copyright (c) 2010 Hendrik Iben | ||
10 | */ | 11 | */ |
11 | 12 | ||
12 | /* | 13 | /* |
@@ -19,6 +20,9 @@ | |||
19 | #include <linux/device.h> | 20 | #include <linux/device.h> |
20 | #include <linux/hid.h> | 21 | #include <linux/hid.h> |
21 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/random.h> | ||
24 | #include <linux/sched.h> | ||
25 | #include <linux/wait.h> | ||
22 | 26 | ||
23 | #include "hid-ids.h" | 27 | #include "hid-ids.h" |
24 | #include "hid-lg.h" | 28 | #include "hid-lg.h" |
@@ -35,6 +39,7 @@ | |||
35 | #define LG_FF2 0x400 | 39 | #define LG_FF2 0x400 |
36 | #define LG_RDESC_REL_ABS 0x800 | 40 | #define LG_RDESC_REL_ABS 0x800 |
37 | #define LG_FF3 0x1000 | 41 | #define LG_FF3 0x1000 |
42 | #define LG_FF4 0x2000 | ||
38 | 43 | ||
39 | /* | 44 | /* |
40 | * Certain Logitech keyboards send in report #3 keys which are far | 45 | * Certain Logitech keyboards send in report #3 keys which are far |
@@ -60,6 +65,17 @@ static void lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
60 | "report descriptor\n"); | 65 | "report descriptor\n"); |
61 | rdesc[33] = rdesc[50] = 0x02; | 66 | rdesc[33] = rdesc[50] = 0x02; |
62 | } | 67 | } |
68 | |||
69 | if ((quirks & LG_FF4) && rsize >= 101 && | ||
70 | rdesc[41] == 0x95 && rdesc[42] == 0x0B && | ||
71 | rdesc[47] == 0x05 && rdesc[48] == 0x09) { | ||
72 | dev_info(&hdev->dev, "fixing up Logitech Speed Force Wireless " | ||
73 | "button descriptor\n"); | ||
74 | rdesc[41] = 0x05; | ||
75 | rdesc[42] = 0x09; | ||
76 | rdesc[47] = 0x95; | ||
77 | rdesc[48] = 0x0B; | ||
78 | } | ||
63 | } | 79 | } |
64 | 80 | ||
65 | #define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ | 81 | #define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ |
@@ -285,12 +301,33 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
285 | goto err_free; | 301 | goto err_free; |
286 | } | 302 | } |
287 | 303 | ||
304 | if (quirks & LG_FF4) { | ||
305 | unsigned char buf[] = { 0x00, 0xAF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | ||
306 | |||
307 | ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); | ||
308 | |||
309 | if (ret >= 0) { | ||
310 | /* insert a little delay of 10 jiffies ~ 40ms */ | ||
311 | wait_queue_head_t wait; | ||
312 | init_waitqueue_head (&wait); | ||
313 | wait_event_interruptible_timeout(wait, 0, 10); | ||
314 | |||
315 | /* Select random Address */ | ||
316 | buf[1] = 0xB2; | ||
317 | get_random_bytes(&buf[2], 2); | ||
318 | |||
319 | ret = hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); | ||
320 | } | ||
321 | } | ||
322 | |||
288 | if (quirks & LG_FF) | 323 | if (quirks & LG_FF) |
289 | lgff_init(hdev); | 324 | lgff_init(hdev); |
290 | if (quirks & LG_FF2) | 325 | if (quirks & LG_FF2) |
291 | lg2ff_init(hdev); | 326 | lg2ff_init(hdev); |
292 | if (quirks & LG_FF3) | 327 | if (quirks & LG_FF3) |
293 | lg3ff_init(hdev); | 328 | lg3ff_init(hdev); |
329 | if (quirks & LG_FF4) | ||
330 | lg4ff_init(hdev); | ||
294 | 331 | ||
295 | return 0; | 332 | return 0; |
296 | err_free: | 333 | err_free: |
@@ -325,6 +362,8 @@ static const struct hid_device_id lg_devices[] = { | |||
325 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL), | 362 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL), |
326 | .driver_data = LG_NOGET | LG_FF }, | 363 | .driver_data = LG_NOGET | LG_FF }, |
327 | 364 | ||
365 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD), | ||
366 | .driver_data = LG_FF2 }, | ||
328 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD), | 367 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD), |
329 | .driver_data = LG_FF }, | 368 | .driver_data = LG_FF }, |
330 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2), | 369 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2), |
@@ -339,6 +378,8 @@ static const struct hid_device_id lg_devices[] = { | |||
339 | .driver_data = LG_FF }, | 378 | .driver_data = LG_FF }, |
340 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL), | 379 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL), |
341 | .driver_data = LG_FF }, | 380 | .driver_data = LG_FF }, |
381 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL), | ||
382 | .driver_data = LG_FF4 }, | ||
342 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ), | 383 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ), |
343 | .driver_data = LG_FF }, | 384 | .driver_data = LG_FF }, |
344 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2), | 385 | { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2), |
diff --git a/drivers/hid/hid-lg.h b/drivers/hid/hid-lg.h index ce2ac8672624..b0100ba2ae0b 100644 --- a/drivers/hid/hid-lg.h +++ b/drivers/hid/hid-lg.h | |||
@@ -19,4 +19,10 @@ int lg3ff_init(struct hid_device *hdev); | |||
19 | static inline int lg3ff_init(struct hid_device *hdev) { return -1; } | 19 | static inline int lg3ff_init(struct hid_device *hdev) { return -1; } |
20 | #endif | 20 | #endif |
21 | 21 | ||
22 | #ifdef CONFIG_LOGIWII_FF | ||
23 | int lg4ff_init(struct hid_device *hdev); | ||
24 | #else | ||
25 | static inline int lg4ff_init(struct hid_device *hdev) { return -1; } | ||
26 | #endif | ||
27 | |||
22 | #endif | 28 | #endif |
diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c index d888f1e6794f..4258253c36b3 100644 --- a/drivers/hid/hid-lg2ff.c +++ b/drivers/hid/hid-lg2ff.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Force feedback support for Logitech Rumblepad 2 | 2 | * Force feedback support for Logitech RumblePad and Rumblepad 2 |
3 | * | 3 | * |
4 | * Copyright (c) 2008 Anssi Hannula <anssi.hannula@gmail.com> | 4 | * Copyright (c) 2008 Anssi Hannula <anssi.hannula@gmail.com> |
5 | */ | 5 | */ |
@@ -110,7 +110,7 @@ int lg2ff_init(struct hid_device *hid) | |||
110 | 110 | ||
111 | usbhid_submit_report(hid, report, USB_DIR_OUT); | 111 | usbhid_submit_report(hid, report, USB_DIR_OUT); |
112 | 112 | ||
113 | dev_info(&hid->dev, "Force feedback for Logitech Rumblepad 2 by " | 113 | dev_info(&hid->dev, "Force feedback for Logitech RumblePad/Rumblepad 2 by " |
114 | "Anssi Hannula <anssi.hannula@gmail.com>\n"); | 114 | "Anssi Hannula <anssi.hannula@gmail.com>\n"); |
115 | 115 | ||
116 | return 0; | 116 | return 0; |
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c new file mode 100644 index 000000000000..7eef5a2ce948 --- /dev/null +++ b/drivers/hid/hid-lg4ff.c | |||
@@ -0,0 +1,136 @@ | |||
1 | /* | ||
2 | * Force feedback support for Logitech Speed Force Wireless | ||
3 | * | ||
4 | * http://wiibrew.org/wiki/Logitech_USB_steering_wheel | ||
5 | * | ||
6 | * Copyright (c) 2010 Simon Wood <simon@mungewell.org> | ||
7 | */ | ||
8 | |||
9 | /* | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | */ | ||
24 | |||
25 | |||
26 | #include <linux/input.h> | ||
27 | #include <linux/usb.h> | ||
28 | #include <linux/hid.h> | ||
29 | |||
30 | #include "usbhid/usbhid.h" | ||
31 | #include "hid-lg.h" | ||
32 | |||
33 | struct lg4ff_device { | ||
34 | struct hid_report *report; | ||
35 | }; | ||
36 | |||
37 | static const signed short ff4_wheel_ac[] = { | ||
38 | FF_CONSTANT, | ||
39 | FF_AUTOCENTER, | ||
40 | -1 | ||
41 | }; | ||
42 | |||
43 | static int hid_lg4ff_play(struct input_dev *dev, void *data, | ||
44 | struct ff_effect *effect) | ||
45 | { | ||
46 | struct hid_device *hid = input_get_drvdata(dev); | ||
47 | struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; | ||
48 | struct hid_report *report = list_entry(report_list->next, struct hid_report, list); | ||
49 | int x; | ||
50 | |||
51 | #define CLAMP(x) if (x < 0) x = 0; if (x > 0xff) x = 0xff | ||
52 | |||
53 | switch (effect->type) { | ||
54 | case FF_CONSTANT: | ||
55 | x = effect->u.ramp.start_level + 0x80; /* 0x80 is no force */ | ||
56 | CLAMP(x); | ||
57 | report->field[0]->value[0] = 0x11; /* Slot 1 */ | ||
58 | report->field[0]->value[1] = 0x10; | ||
59 | report->field[0]->value[2] = x; | ||
60 | report->field[0]->value[3] = 0x00; | ||
61 | report->field[0]->value[4] = 0x00; | ||
62 | report->field[0]->value[5] = 0x08; | ||
63 | report->field[0]->value[6] = 0x00; | ||
64 | dbg_hid("Autocenter, x=0x%02X\n", x); | ||
65 | |||
66 | usbhid_submit_report(hid, report, USB_DIR_OUT); | ||
67 | break; | ||
68 | } | ||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static void hid_lg4ff_set_autocenter(struct input_dev *dev, u16 magnitude) | ||
73 | { | ||
74 | struct hid_device *hid = input_get_drvdata(dev); | ||
75 | struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; | ||
76 | struct hid_report *report = list_entry(report_list->next, struct hid_report, list); | ||
77 | __s32 *value = report->field[0]->value; | ||
78 | |||
79 | *value++ = 0xfe; | ||
80 | *value++ = 0x0d; | ||
81 | *value++ = 0x07; | ||
82 | *value++ = 0x07; | ||
83 | *value++ = (magnitude >> 8) & 0xff; | ||
84 | *value++ = 0x00; | ||
85 | *value = 0x00; | ||
86 | |||
87 | usbhid_submit_report(hid, report, USB_DIR_OUT); | ||
88 | } | ||
89 | |||
90 | |||
91 | int lg4ff_init(struct hid_device *hid) | ||
92 | { | ||
93 | struct hid_input *hidinput = list_entry(hid->inputs.next, struct hid_input, list); | ||
94 | struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; | ||
95 | struct input_dev *dev = hidinput->input; | ||
96 | struct hid_report *report; | ||
97 | struct hid_field *field; | ||
98 | const signed short *ff_bits = ff4_wheel_ac; | ||
99 | int error; | ||
100 | int i; | ||
101 | |||
102 | /* Find the report to use */ | ||
103 | if (list_empty(report_list)) { | ||
104 | err_hid("No output report found"); | ||
105 | return -1; | ||
106 | } | ||
107 | |||
108 | /* Check that the report looks ok */ | ||
109 | report = list_entry(report_list->next, struct hid_report, list); | ||
110 | if (!report) { | ||
111 | err_hid("NULL output report"); | ||
112 | return -1; | ||
113 | } | ||
114 | |||
115 | field = report->field[0]; | ||
116 | if (!field) { | ||
117 | err_hid("NULL field"); | ||
118 | return -1; | ||
119 | } | ||
120 | |||
121 | for (i = 0; ff_bits[i] >= 0; i++) | ||
122 | set_bit(ff_bits[i], dev->ffbit); | ||
123 | |||
124 | error = input_ff_create_memless(dev, NULL, hid_lg4ff_play); | ||
125 | |||
126 | if (error) | ||
127 | return error; | ||
128 | |||
129 | if (test_bit(FF_AUTOCENTER, dev->ffbit)) | ||
130 | dev->ff->set_autocenter = hid_lg4ff_set_autocenter; | ||
131 | |||
132 | dev_info(&hid->dev, "Force feedback for Logitech Speed Force Wireless by " | ||
133 | "Simon Wood <simon@mungewell.org>\n"); | ||
134 | return 0; | ||
135 | } | ||
136 | |||
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 319b0e57ee41..e6dc15171664 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Apple "Magic" Wireless Mouse driver | 2 | * Apple "Magic" Wireless Mouse driver |
3 | * | 3 | * |
4 | * Copyright (c) 2010 Michael Poole <mdpoole@troilus.org> | 4 | * Copyright (c) 2010 Michael Poole <mdpoole@troilus.org> |
5 | * Copyright (c) 2010 Chase Douglas <chase.douglas@canonical.com> | ||
5 | */ | 6 | */ |
6 | 7 | ||
7 | /* | 8 | /* |
@@ -53,7 +54,9 @@ static bool report_undeciphered; | |||
53 | module_param(report_undeciphered, bool, 0644); | 54 | module_param(report_undeciphered, bool, 0644); |
54 | MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event"); | 55 | MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event"); |
55 | 56 | ||
56 | #define TOUCH_REPORT_ID 0x29 | 57 | #define TRACKPAD_REPORT_ID 0x28 |
58 | #define MOUSE_REPORT_ID 0x29 | ||
59 | #define DOUBLE_REPORT_ID 0xf7 | ||
57 | /* These definitions are not precise, but they're close enough. (Bits | 60 | /* These definitions are not precise, but they're close enough. (Bits |
58 | * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem | 61 | * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem |
59 | * to be some kind of bit mask -- 0x20 may be a near-field reading, | 62 | * to be some kind of bit mask -- 0x20 may be a near-field reading, |
@@ -67,15 +70,19 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie | |||
67 | 70 | ||
68 | #define SCROLL_ACCEL_DEFAULT 7 | 71 | #define SCROLL_ACCEL_DEFAULT 7 |
69 | 72 | ||
73 | /* Single touch emulation should only begin when no touches are currently down. | ||
74 | * This is true when single_touch_id is equal to NO_TOUCHES. If multiple touches | ||
75 | * are down and the touch providing for single touch emulation is lifted, | ||
76 | * single_touch_id is equal to SINGLE_TOUCH_UP. While single touch emulation is | ||
77 | * occuring, single_touch_id corresponds with the tracking id of the touch used. | ||
78 | */ | ||
79 | #define NO_TOUCHES -1 | ||
80 | #define SINGLE_TOUCH_UP -2 | ||
81 | |||
70 | /** | 82 | /** |
71 | * struct magicmouse_sc - Tracks Magic Mouse-specific data. | 83 | * struct magicmouse_sc - Tracks Magic Mouse-specific data. |
72 | * @input: Input device through which we report events. | 84 | * @input: Input device through which we report events. |
73 | * @quirks: Currently unused. | 85 | * @quirks: Currently unused. |
74 | * @last_timestamp: Timestamp from most recent (18-bit) touch report | ||
75 | * (units of milliseconds over short windows, but seems to | ||
76 | * increase faster when there are no touches). | ||
77 | * @delta_time: 18-bit difference between the two most recent touch | ||
78 | * reports from the mouse. | ||
79 | * @ntouches: Number of touches in most recent touch report. | 86 | * @ntouches: Number of touches in most recent touch report. |
80 | * @scroll_accel: Number of consecutive scroll motions. | 87 | * @scroll_accel: Number of consecutive scroll motions. |
81 | * @scroll_jiffies: Time of last scroll motion. | 88 | * @scroll_jiffies: Time of last scroll motion. |
@@ -86,8 +93,6 @@ struct magicmouse_sc { | |||
86 | struct input_dev *input; | 93 | struct input_dev *input; |
87 | unsigned long quirks; | 94 | unsigned long quirks; |
88 | 95 | ||
89 | int last_timestamp; | ||
90 | int delta_time; | ||
91 | int ntouches; | 96 | int ntouches; |
92 | int scroll_accel; | 97 | int scroll_accel; |
93 | unsigned long scroll_jiffies; | 98 | unsigned long scroll_jiffies; |
@@ -98,9 +103,9 @@ struct magicmouse_sc { | |||
98 | short scroll_x; | 103 | short scroll_x; |
99 | short scroll_y; | 104 | short scroll_y; |
100 | u8 size; | 105 | u8 size; |
101 | u8 down; | ||
102 | } touches[16]; | 106 | } touches[16]; |
103 | int tracking_ids[16]; | 107 | int tracking_ids[16]; |
108 | int single_touch_id; | ||
104 | }; | 109 | }; |
105 | 110 | ||
106 | static int magicmouse_firm_touch(struct magicmouse_sc *msc) | 111 | static int magicmouse_firm_touch(struct magicmouse_sc *msc) |
@@ -166,18 +171,35 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state) | |||
166 | static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata) | 171 | static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata) |
167 | { | 172 | { |
168 | struct input_dev *input = msc->input; | 173 | struct input_dev *input = msc->input; |
169 | __s32 x_y = tdata[0] << 8 | tdata[1] << 16 | tdata[2] << 24; | 174 | int id, x, y, size, orientation, touch_major, touch_minor, state, down; |
170 | int misc = tdata[5] | tdata[6] << 8; | 175 | |
171 | int id = (misc >> 6) & 15; | 176 | if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { |
172 | int x = x_y << 12 >> 20; | 177 | id = (tdata[6] << 2 | tdata[5] >> 6) & 0xf; |
173 | int y = -(x_y >> 20); | 178 | x = (tdata[1] << 28 | tdata[0] << 20) >> 20; |
174 | int down = (tdata[7] & TOUCH_STATE_MASK) != TOUCH_STATE_NONE; | 179 | y = -((tdata[2] << 24 | tdata[1] << 16) >> 20); |
180 | size = tdata[5] & 0x3f; | ||
181 | orientation = (tdata[6] >> 2) - 32; | ||
182 | touch_major = tdata[3]; | ||
183 | touch_minor = tdata[4]; | ||
184 | state = tdata[7] & TOUCH_STATE_MASK; | ||
185 | down = state != TOUCH_STATE_NONE; | ||
186 | } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ | ||
187 | id = (tdata[7] << 2 | tdata[6] >> 6) & 0xf; | ||
188 | x = (tdata[1] << 27 | tdata[0] << 19) >> 19; | ||
189 | y = -((tdata[3] << 30 | tdata[2] << 22 | tdata[1] << 14) >> 19); | ||
190 | size = tdata[6] & 0x3f; | ||
191 | orientation = (tdata[7] >> 2) - 32; | ||
192 | touch_major = tdata[4]; | ||
193 | touch_minor = tdata[5]; | ||
194 | state = tdata[8] & TOUCH_STATE_MASK; | ||
195 | down = state != TOUCH_STATE_NONE; | ||
196 | } | ||
175 | 197 | ||
176 | /* Store tracking ID and other fields. */ | 198 | /* Store tracking ID and other fields. */ |
177 | msc->tracking_ids[raw_id] = id; | 199 | msc->tracking_ids[raw_id] = id; |
178 | msc->touches[id].x = x; | 200 | msc->touches[id].x = x; |
179 | msc->touches[id].y = y; | 201 | msc->touches[id].y = y; |
180 | msc->touches[id].size = misc & 63; | 202 | msc->touches[id].size = size; |
181 | 203 | ||
182 | /* If requested, emulate a scroll wheel by detecting small | 204 | /* If requested, emulate a scroll wheel by detecting small |
183 | * vertical touch motions. | 205 | * vertical touch motions. |
@@ -188,7 +210,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda | |||
188 | int step_y = msc->touches[id].scroll_y - y; | 210 | int step_y = msc->touches[id].scroll_y - y; |
189 | 211 | ||
190 | /* Calculate and apply the scroll motion. */ | 212 | /* Calculate and apply the scroll motion. */ |
191 | switch (tdata[7] & TOUCH_STATE_MASK) { | 213 | switch (state) { |
192 | case TOUCH_STATE_START: | 214 | case TOUCH_STATE_START: |
193 | msc->touches[id].scroll_x = x; | 215 | msc->touches[id].scroll_x = x; |
194 | msc->touches[id].scroll_y = y; | 216 | msc->touches[id].scroll_y = y; |
@@ -222,21 +244,28 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda | |||
222 | } | 244 | } |
223 | } | 245 | } |
224 | 246 | ||
247 | if (down) { | ||
248 | msc->ntouches++; | ||
249 | if (msc->single_touch_id == NO_TOUCHES) | ||
250 | msc->single_touch_id = id; | ||
251 | } else if (msc->single_touch_id == id) | ||
252 | msc->single_touch_id = SINGLE_TOUCH_UP; | ||
253 | |||
225 | /* Generate the input events for this touch. */ | 254 | /* Generate the input events for this touch. */ |
226 | if (report_touches && down) { | 255 | if (report_touches && down) { |
227 | int orientation = (misc >> 10) - 32; | ||
228 | |||
229 | msc->touches[id].down = 1; | ||
230 | |||
231 | input_report_abs(input, ABS_MT_TRACKING_ID, id); | 256 | input_report_abs(input, ABS_MT_TRACKING_ID, id); |
232 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, tdata[3]); | 257 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2); |
233 | input_report_abs(input, ABS_MT_TOUCH_MINOR, tdata[4]); | 258 | input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2); |
234 | input_report_abs(input, ABS_MT_ORIENTATION, orientation); | 259 | input_report_abs(input, ABS_MT_ORIENTATION, orientation); |
235 | input_report_abs(input, ABS_MT_POSITION_X, x); | 260 | input_report_abs(input, ABS_MT_POSITION_X, x); |
236 | input_report_abs(input, ABS_MT_POSITION_Y, y); | 261 | input_report_abs(input, ABS_MT_POSITION_Y, y); |
237 | 262 | ||
238 | if (report_undeciphered) | 263 | if (report_undeciphered) { |
239 | input_event(input, EV_MSC, MSC_RAW, tdata[7]); | 264 | if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) |
265 | input_event(input, EV_MSC, MSC_RAW, tdata[7]); | ||
266 | else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ | ||
267 | input_event(input, EV_MSC, MSC_RAW, tdata[8]); | ||
268 | } | ||
240 | 269 | ||
241 | input_mt_sync(input); | 270 | input_mt_sync(input); |
242 | } | 271 | } |
@@ -247,39 +276,43 @@ static int magicmouse_raw_event(struct hid_device *hdev, | |||
247 | { | 276 | { |
248 | struct magicmouse_sc *msc = hid_get_drvdata(hdev); | 277 | struct magicmouse_sc *msc = hid_get_drvdata(hdev); |
249 | struct input_dev *input = msc->input; | 278 | struct input_dev *input = msc->input; |
250 | int x, y, ts, ii, clicks, last_up; | 279 | int x = 0, y = 0, ii, clicks = 0, npoints; |
251 | 280 | ||
252 | switch (data[0]) { | 281 | switch (data[0]) { |
253 | case 0x10: | 282 | case TRACKPAD_REPORT_ID: |
254 | if (size != 6) | 283 | /* Expect four bytes of prefix, and N*9 bytes of touch data. */ |
284 | if (size < 4 || ((size - 4) % 9) != 0) | ||
255 | return 0; | 285 | return 0; |
256 | x = (__s16)(data[2] | data[3] << 8); | 286 | npoints = (size - 4) / 9; |
257 | y = (__s16)(data[4] | data[5] << 8); | 287 | msc->ntouches = 0; |
288 | for (ii = 0; ii < npoints; ii++) | ||
289 | magicmouse_emit_touch(msc, ii, data + ii * 9 + 4); | ||
290 | |||
291 | /* We don't need an MT sync here because trackpad emits a | ||
292 | * BTN_TOUCH event in a new frame when all touches are released. | ||
293 | */ | ||
294 | if (msc->ntouches == 0) | ||
295 | msc->single_touch_id = NO_TOUCHES; | ||
296 | |||
258 | clicks = data[1]; | 297 | clicks = data[1]; |
298 | |||
299 | /* The following bits provide a device specific timestamp. They | ||
300 | * are unused here. | ||
301 | * | ||
302 | * ts = data[1] >> 6 | data[2] << 2 | data[3] << 10; | ||
303 | */ | ||
259 | break; | 304 | break; |
260 | case TOUCH_REPORT_ID: | 305 | case MOUSE_REPORT_ID: |
261 | /* Expect six bytes of prefix, and N*8 bytes of touch data. */ | 306 | /* Expect six bytes of prefix, and N*8 bytes of touch data. */ |
262 | if (size < 6 || ((size - 6) % 8) != 0) | 307 | if (size < 6 || ((size - 6) % 8) != 0) |
263 | return 0; | 308 | return 0; |
264 | ts = data[3] >> 6 | data[4] << 2 | data[5] << 10; | 309 | npoints = (size - 6) / 8; |
265 | msc->delta_time = (ts - msc->last_timestamp) & 0x3ffff; | 310 | msc->ntouches = 0; |
266 | msc->last_timestamp = ts; | 311 | for (ii = 0; ii < npoints; ii++) |
267 | msc->ntouches = (size - 6) / 8; | ||
268 | for (ii = 0; ii < msc->ntouches; ii++) | ||
269 | magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); | 312 | magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); |
270 | 313 | ||
271 | if (report_touches) { | 314 | if (report_touches && msc->ntouches == 0) |
272 | last_up = 1; | 315 | input_mt_sync(input); |
273 | for (ii = 0; ii < ARRAY_SIZE(msc->touches); ii++) { | ||
274 | if (msc->touches[ii].down) { | ||
275 | last_up = 0; | ||
276 | msc->touches[ii].down = 0; | ||
277 | } | ||
278 | } | ||
279 | if (last_up) { | ||
280 | input_mt_sync(input); | ||
281 | } | ||
282 | } | ||
283 | 316 | ||
284 | /* When emulating three-button mode, it is important | 317 | /* When emulating three-button mode, it is important |
285 | * to have the current touch information before | 318 | * to have the current touch information before |
@@ -288,68 +321,72 @@ static int magicmouse_raw_event(struct hid_device *hdev, | |||
288 | x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22; | 321 | x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22; |
289 | y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; | 322 | y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22; |
290 | clicks = data[3]; | 323 | clicks = data[3]; |
324 | |||
325 | /* The following bits provide a device specific timestamp. They | ||
326 | * are unused here. | ||
327 | * | ||
328 | * ts = data[3] >> 6 | data[4] << 2 | data[5] << 10; | ||
329 | */ | ||
330 | break; | ||
331 | case DOUBLE_REPORT_ID: | ||
332 | /* Sometimes the trackpad sends two touch reports in one | ||
333 | * packet. | ||
334 | */ | ||
335 | magicmouse_raw_event(hdev, report, data + 2, data[1]); | ||
336 | magicmouse_raw_event(hdev, report, data + 2 + data[1], | ||
337 | size - 2 - data[1]); | ||
291 | break; | 338 | break; |
292 | case 0x20: /* Theoretically battery status (0-100), but I have | ||
293 | * never seen it -- maybe it is only upon request. | ||
294 | */ | ||
295 | case 0x60: /* Unknown, maybe laser on/off. */ | ||
296 | case 0x61: /* Laser reflection status change. | ||
297 | * data[1]: 0 = spotted, 1 = lost | ||
298 | */ | ||
299 | default: | 339 | default: |
300 | return 0; | 340 | return 0; |
301 | } | 341 | } |
302 | 342 | ||
303 | magicmouse_emit_buttons(msc, clicks & 3); | 343 | if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { |
304 | input_report_rel(input, REL_X, x); | 344 | magicmouse_emit_buttons(msc, clicks & 3); |
305 | input_report_rel(input, REL_Y, y); | 345 | input_report_rel(input, REL_X, x); |
346 | input_report_rel(input, REL_Y, y); | ||
347 | } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ | ||
348 | input_report_key(input, BTN_MOUSE, clicks & 1); | ||
349 | input_report_key(input, BTN_TOUCH, msc->ntouches > 0); | ||
350 | input_report_key(input, BTN_TOOL_FINGER, msc->ntouches == 1); | ||
351 | input_report_key(input, BTN_TOOL_DOUBLETAP, msc->ntouches == 2); | ||
352 | input_report_key(input, BTN_TOOL_TRIPLETAP, msc->ntouches == 3); | ||
353 | input_report_key(input, BTN_TOOL_QUADTAP, msc->ntouches == 4); | ||
354 | if (msc->single_touch_id >= 0) { | ||
355 | input_report_abs(input, ABS_X, | ||
356 | msc->touches[msc->single_touch_id].x); | ||
357 | input_report_abs(input, ABS_Y, | ||
358 | msc->touches[msc->single_touch_id].y); | ||
359 | } | ||
360 | } | ||
361 | |||
306 | input_sync(input); | 362 | input_sync(input); |
307 | return 1; | 363 | return 1; |
308 | } | 364 | } |
309 | 365 | ||
310 | static int magicmouse_input_open(struct input_dev *dev) | ||
311 | { | ||
312 | struct hid_device *hid = input_get_drvdata(dev); | ||
313 | |||
314 | return hid->ll_driver->open(hid); | ||
315 | } | ||
316 | |||
317 | static void magicmouse_input_close(struct input_dev *dev) | ||
318 | { | ||
319 | struct hid_device *hid = input_get_drvdata(dev); | ||
320 | |||
321 | hid->ll_driver->close(hid); | ||
322 | } | ||
323 | |||
324 | static void magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev) | 366 | static void magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev) |
325 | { | 367 | { |
326 | input_set_drvdata(input, hdev); | ||
327 | input->event = hdev->ll_driver->hidinput_input_event; | ||
328 | input->open = magicmouse_input_open; | ||
329 | input->close = magicmouse_input_close; | ||
330 | |||
331 | input->name = hdev->name; | ||
332 | input->phys = hdev->phys; | ||
333 | input->uniq = hdev->uniq; | ||
334 | input->id.bustype = hdev->bus; | ||
335 | input->id.vendor = hdev->vendor; | ||
336 | input->id.product = hdev->product; | ||
337 | input->id.version = hdev->version; | ||
338 | input->dev.parent = hdev->dev.parent; | ||
339 | |||
340 | __set_bit(EV_KEY, input->evbit); | 368 | __set_bit(EV_KEY, input->evbit); |
341 | __set_bit(BTN_LEFT, input->keybit); | 369 | |
342 | __set_bit(BTN_RIGHT, input->keybit); | 370 | if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { |
343 | if (emulate_3button) | 371 | __set_bit(BTN_LEFT, input->keybit); |
344 | __set_bit(BTN_MIDDLE, input->keybit); | 372 | __set_bit(BTN_RIGHT, input->keybit); |
345 | __set_bit(BTN_TOOL_FINGER, input->keybit); | 373 | if (emulate_3button) |
346 | 374 | __set_bit(BTN_MIDDLE, input->keybit); | |
347 | __set_bit(EV_REL, input->evbit); | 375 | |
348 | __set_bit(REL_X, input->relbit); | 376 | __set_bit(EV_REL, input->evbit); |
349 | __set_bit(REL_Y, input->relbit); | 377 | __set_bit(REL_X, input->relbit); |
350 | if (emulate_scroll_wheel) { | 378 | __set_bit(REL_Y, input->relbit); |
351 | __set_bit(REL_WHEEL, input->relbit); | 379 | if (emulate_scroll_wheel) { |
352 | __set_bit(REL_HWHEEL, input->relbit); | 380 | __set_bit(REL_WHEEL, input->relbit); |
381 | __set_bit(REL_HWHEEL, input->relbit); | ||
382 | } | ||
383 | } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ | ||
384 | __set_bit(BTN_MOUSE, input->keybit); | ||
385 | __set_bit(BTN_TOOL_FINGER, input->keybit); | ||
386 | __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); | ||
387 | __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); | ||
388 | __set_bit(BTN_TOOL_QUADTAP, input->keybit); | ||
389 | __set_bit(BTN_TOUCH, input->keybit); | ||
353 | } | 390 | } |
354 | 391 | ||
355 | if (report_touches) { | 392 | if (report_touches) { |
@@ -359,16 +396,26 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h | |||
359 | input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0); | 396 | input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 4, 0); |
360 | input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0); | 397 | input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 4, 0); |
361 | input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0); | 398 | input_set_abs_params(input, ABS_MT_ORIENTATION, -32, 31, 1, 0); |
362 | input_set_abs_params(input, ABS_MT_POSITION_X, -1100, 1358, | 399 | |
363 | 4, 0); | ||
364 | /* Note: Touch Y position from the device is inverted relative | 400 | /* Note: Touch Y position from the device is inverted relative |
365 | * to how pointer motion is reported (and relative to how USB | 401 | * to how pointer motion is reported (and relative to how USB |
366 | * HID recommends the coordinates work). This driver keeps | 402 | * HID recommends the coordinates work). This driver keeps |
367 | * the origin at the same position, and just uses the additive | 403 | * the origin at the same position, and just uses the additive |
368 | * inverse of the reported Y. | 404 | * inverse of the reported Y. |
369 | */ | 405 | */ |
370 | input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, 2047, | 406 | if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { |
371 | 4, 0); | 407 | input_set_abs_params(input, ABS_MT_POSITION_X, -1100, |
408 | 1358, 4, 0); | ||
409 | input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, | ||
410 | 2047, 4, 0); | ||
411 | } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ | ||
412 | input_set_abs_params(input, ABS_X, -2909, 3167, 4, 0); | ||
413 | input_set_abs_params(input, ABS_Y, -2456, 2565, 4, 0); | ||
414 | input_set_abs_params(input, ABS_MT_POSITION_X, -2909, | ||
415 | 3167, 4, 0); | ||
416 | input_set_abs_params(input, ABS_MT_POSITION_Y, -2456, | ||
417 | 2565, 4, 0); | ||
418 | } | ||
372 | } | 419 | } |
373 | 420 | ||
374 | if (report_undeciphered) { | 421 | if (report_undeciphered) { |
@@ -377,12 +424,22 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h | |||
377 | } | 424 | } |
378 | } | 425 | } |
379 | 426 | ||
427 | static int magicmouse_input_mapping(struct hid_device *hdev, | ||
428 | struct hid_input *hi, struct hid_field *field, | ||
429 | struct hid_usage *usage, unsigned long **bit, int *max) | ||
430 | { | ||
431 | struct magicmouse_sc *msc = hid_get_drvdata(hdev); | ||
432 | |||
433 | if (!msc->input) | ||
434 | msc->input = hi->input; | ||
435 | |||
436 | return 0; | ||
437 | } | ||
438 | |||
380 | static int magicmouse_probe(struct hid_device *hdev, | 439 | static int magicmouse_probe(struct hid_device *hdev, |
381 | const struct hid_device_id *id) | 440 | const struct hid_device_id *id) |
382 | { | 441 | { |
383 | __u8 feature_1[] = { 0xd7, 0x01 }; | 442 | __u8 feature[] = { 0xd7, 0x01 }; |
384 | __u8 feature_2[] = { 0xf8, 0x01, 0x32 }; | ||
385 | struct input_dev *input; | ||
386 | struct magicmouse_sc *msc; | 443 | struct magicmouse_sc *msc; |
387 | struct hid_report *report; | 444 | struct hid_report *report; |
388 | int ret; | 445 | int ret; |
@@ -398,6 +455,8 @@ static int magicmouse_probe(struct hid_device *hdev, | |||
398 | msc->quirks = id->driver_data; | 455 | msc->quirks = id->driver_data; |
399 | hid_set_drvdata(hdev, msc); | 456 | hid_set_drvdata(hdev, msc); |
400 | 457 | ||
458 | msc->single_touch_id = NO_TOUCHES; | ||
459 | |||
401 | ret = hid_parse(hdev); | 460 | ret = hid_parse(hdev); |
402 | if (ret) { | 461 | if (ret) { |
403 | dev_err(&hdev->dev, "magicmouse hid parse failed\n"); | 462 | dev_err(&hdev->dev, "magicmouse hid parse failed\n"); |
@@ -410,10 +469,22 @@ static int magicmouse_probe(struct hid_device *hdev, | |||
410 | goto err_free; | 469 | goto err_free; |
411 | } | 470 | } |
412 | 471 | ||
413 | /* we are handling the input ourselves */ | 472 | /* We do this after hid-input is done parsing reports so that |
414 | hidinput_disconnect(hdev); | 473 | * hid-input uses the most natural button and axis IDs. |
474 | */ | ||
475 | if (msc->input) | ||
476 | magicmouse_setup_input(msc->input, hdev); | ||
477 | |||
478 | if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE) | ||
479 | report = hid_register_report(hdev, HID_INPUT_REPORT, | ||
480 | MOUSE_REPORT_ID); | ||
481 | else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ | ||
482 | report = hid_register_report(hdev, HID_INPUT_REPORT, | ||
483 | TRACKPAD_REPORT_ID); | ||
484 | report = hid_register_report(hdev, HID_INPUT_REPORT, | ||
485 | DOUBLE_REPORT_ID); | ||
486 | } | ||
415 | 487 | ||
416 | report = hid_register_report(hdev, HID_INPUT_REPORT, TOUCH_REPORT_ID); | ||
417 | if (!report) { | 488 | if (!report) { |
418 | dev_err(&hdev->dev, "unable to register touch report\n"); | 489 | dev_err(&hdev->dev, "unable to register touch report\n"); |
419 | ret = -ENOMEM; | 490 | ret = -ENOMEM; |
@@ -421,39 +492,15 @@ static int magicmouse_probe(struct hid_device *hdev, | |||
421 | } | 492 | } |
422 | report->size = 6; | 493 | report->size = 6; |
423 | 494 | ||
424 | ret = hdev->hid_output_raw_report(hdev, feature_1, sizeof(feature_1), | 495 | ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature), |
425 | HID_FEATURE_REPORT); | 496 | HID_FEATURE_REPORT); |
426 | if (ret != sizeof(feature_1)) { | 497 | if (ret != sizeof(feature)) { |
427 | dev_err(&hdev->dev, "unable to request touch data (1:%d)\n", | 498 | dev_err(&hdev->dev, "unable to request touch data (%d)\n", |
428 | ret); | ||
429 | goto err_stop_hw; | ||
430 | } | ||
431 | ret = hdev->hid_output_raw_report(hdev, feature_2, | ||
432 | sizeof(feature_2), HID_FEATURE_REPORT); | ||
433 | if (ret != sizeof(feature_2)) { | ||
434 | dev_err(&hdev->dev, "unable to request touch data (2:%d)\n", | ||
435 | ret); | 499 | ret); |
436 | goto err_stop_hw; | 500 | goto err_stop_hw; |
437 | } | 501 | } |
438 | 502 | ||
439 | input = input_allocate_device(); | ||
440 | if (!input) { | ||
441 | dev_err(&hdev->dev, "can't alloc input device\n"); | ||
442 | ret = -ENOMEM; | ||
443 | goto err_stop_hw; | ||
444 | } | ||
445 | magicmouse_setup_input(input, hdev); | ||
446 | |||
447 | ret = input_register_device(input); | ||
448 | if (ret) { | ||
449 | dev_err(&hdev->dev, "input device registration failed\n"); | ||
450 | goto err_input; | ||
451 | } | ||
452 | msc->input = input; | ||
453 | |||
454 | return 0; | 503 | return 0; |
455 | err_input: | ||
456 | input_free_device(input); | ||
457 | err_stop_hw: | 504 | err_stop_hw: |
458 | hid_hw_stop(hdev); | 505 | hid_hw_stop(hdev); |
459 | err_free: | 506 | err_free: |
@@ -466,13 +513,14 @@ static void magicmouse_remove(struct hid_device *hdev) | |||
466 | struct magicmouse_sc *msc = hid_get_drvdata(hdev); | 513 | struct magicmouse_sc *msc = hid_get_drvdata(hdev); |
467 | 514 | ||
468 | hid_hw_stop(hdev); | 515 | hid_hw_stop(hdev); |
469 | input_unregister_device(msc->input); | ||
470 | kfree(msc); | 516 | kfree(msc); |
471 | } | 517 | } |
472 | 518 | ||
473 | static const struct hid_device_id magic_mice[] = { | 519 | static const struct hid_device_id magic_mice[] = { |
474 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE), | 520 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, |
475 | .driver_data = 0 }, | 521 | USB_DEVICE_ID_APPLE_MAGICMOUSE), .driver_data = 0 }, |
522 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, | ||
523 | USB_DEVICE_ID_APPLE_MAGICTRACKPAD), .driver_data = 0 }, | ||
476 | { } | 524 | { } |
477 | }; | 525 | }; |
478 | MODULE_DEVICE_TABLE(hid, magic_mice); | 526 | MODULE_DEVICE_TABLE(hid, magic_mice); |
@@ -483,6 +531,7 @@ static struct hid_driver magicmouse_driver = { | |||
483 | .probe = magicmouse_probe, | 531 | .probe = magicmouse_probe, |
484 | .remove = magicmouse_remove, | 532 | .remove = magicmouse_remove, |
485 | .raw_event = magicmouse_raw_event, | 533 | .raw_event = magicmouse_raw_event, |
534 | .input_mapping = magicmouse_input_mapping, | ||
486 | }; | 535 | }; |
487 | 536 | ||
488 | static int __init magicmouse_init(void) | 537 | static int __init magicmouse_init(void) |
diff --git a/drivers/hid/hid-mosart.c b/drivers/hid/hid-mosart.c index e91437c18906..ac5421d568f1 100644 --- a/drivers/hid/hid-mosart.c +++ b/drivers/hid/hid-mosart.c | |||
@@ -239,6 +239,7 @@ static void mosart_remove(struct hid_device *hdev) | |||
239 | 239 | ||
240 | static const struct hid_device_id mosart_devices[] = { | 240 | static const struct hid_device_id mosart_devices[] = { |
241 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) }, | 241 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) }, |
242 | { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) }, | ||
242 | { } | 243 | { } |
243 | }; | 244 | }; |
244 | MODULE_DEVICE_TABLE(hid, mosart_devices); | 245 | MODULE_DEVICE_TABLE(hid, mosart_devices); |
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index fb69b8c4953f..69169efa1e16 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c | |||
@@ -90,6 +90,55 @@ struct ntrig_data { | |||
90 | }; | 90 | }; |
91 | 91 | ||
92 | 92 | ||
93 | /* | ||
94 | * This function converts the 4 byte raw firmware code into | ||
95 | * a string containing 5 comma separated numbers. | ||
96 | */ | ||
97 | static int ntrig_version_string(unsigned char *raw, char *buf) | ||
98 | { | ||
99 | __u8 a = (raw[1] & 0x0e) >> 1; | ||
100 | __u8 b = (raw[0] & 0x3c) >> 2; | ||
101 | __u8 c = ((raw[0] & 0x03) << 3) | ((raw[3] & 0xe0) >> 5); | ||
102 | __u8 d = ((raw[3] & 0x07) << 3) | ((raw[2] & 0xe0) >> 5); | ||
103 | __u8 e = raw[2] & 0x07; | ||
104 | |||
105 | /* | ||
106 | * As yet unmapped bits: | ||
107 | * 0b11000000 0b11110001 0b00011000 0b00011000 | ||
108 | */ | ||
109 | |||
110 | return sprintf(buf, "%u.%u.%u.%u.%u", a, b, c, d, e); | ||
111 | } | ||
112 | |||
113 | static void ntrig_report_version(struct hid_device *hdev) | ||
114 | { | ||
115 | int ret; | ||
116 | char buf[20]; | ||
117 | struct usb_device *usb_dev = hid_to_usb_dev(hdev); | ||
118 | unsigned char *data = kmalloc(8, GFP_KERNEL); | ||
119 | |||
120 | if (!data) | ||
121 | goto err_free; | ||
122 | |||
123 | ret = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | ||
124 | USB_REQ_CLEAR_FEATURE, | ||
125 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | | ||
126 | USB_DIR_IN, | ||
127 | 0x30c, 1, data, 8, | ||
128 | USB_CTRL_SET_TIMEOUT); | ||
129 | |||
130 | if (ret == 8) { | ||
131 | ret = ntrig_version_string(&data[2], buf); | ||
132 | |||
133 | dev_info(&hdev->dev, | ||
134 | "Firmware version: %s (%02x%02x %02x%02x)\n", | ||
135 | buf, data[2], data[3], data[4], data[5]); | ||
136 | } | ||
137 | |||
138 | err_free: | ||
139 | kfree(data); | ||
140 | } | ||
141 | |||
93 | static ssize_t show_phys_width(struct device *dev, | 142 | static ssize_t show_phys_width(struct device *dev, |
94 | struct device_attribute *attr, | 143 | struct device_attribute *attr, |
95 | char *buf) | 144 | char *buf) |
@@ -377,8 +426,8 @@ static struct attribute_group ntrig_attribute_group = { | |||
377 | */ | 426 | */ |
378 | 427 | ||
379 | static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, | 428 | static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, |
380 | struct hid_field *field, struct hid_usage *usage, | 429 | struct hid_field *field, struct hid_usage *usage, |
381 | unsigned long **bit, int *max) | 430 | unsigned long **bit, int *max) |
382 | { | 431 | { |
383 | struct ntrig_data *nd = hid_get_drvdata(hdev); | 432 | struct ntrig_data *nd = hid_get_drvdata(hdev); |
384 | 433 | ||
@@ -448,13 +497,13 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
448 | /* width/height mapped on TouchMajor/TouchMinor/Orientation */ | 497 | /* width/height mapped on TouchMajor/TouchMinor/Orientation */ |
449 | case HID_DG_WIDTH: | 498 | case HID_DG_WIDTH: |
450 | hid_map_usage(hi, usage, bit, max, | 499 | hid_map_usage(hi, usage, bit, max, |
451 | EV_ABS, ABS_MT_TOUCH_MAJOR); | 500 | EV_ABS, ABS_MT_TOUCH_MAJOR); |
452 | return 1; | 501 | return 1; |
453 | case HID_DG_HEIGHT: | 502 | case HID_DG_HEIGHT: |
454 | hid_map_usage(hi, usage, bit, max, | 503 | hid_map_usage(hi, usage, bit, max, |
455 | EV_ABS, ABS_MT_TOUCH_MINOR); | 504 | EV_ABS, ABS_MT_TOUCH_MINOR); |
456 | input_set_abs_params(hi->input, ABS_MT_ORIENTATION, | 505 | input_set_abs_params(hi->input, ABS_MT_ORIENTATION, |
457 | 0, 1, 0, 0); | 506 | 0, 1, 0, 0); |
458 | return 1; | 507 | return 1; |
459 | } | 508 | } |
460 | return 0; | 509 | return 0; |
@@ -468,8 +517,8 @@ static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
468 | } | 517 | } |
469 | 518 | ||
470 | static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, | 519 | static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, |
471 | struct hid_field *field, struct hid_usage *usage, | 520 | struct hid_field *field, struct hid_usage *usage, |
472 | unsigned long **bit, int *max) | 521 | unsigned long **bit, int *max) |
473 | { | 522 | { |
474 | /* No special mappings needed for the pen and single touch */ | 523 | /* No special mappings needed for the pen and single touch */ |
475 | if (field->physical) | 524 | if (field->physical) |
@@ -489,7 +538,7 @@ static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, | |||
489 | * and call input_mt_sync after each point if necessary | 538 | * and call input_mt_sync after each point if necessary |
490 | */ | 539 | */ |
491 | static int ntrig_event (struct hid_device *hid, struct hid_field *field, | 540 | static int ntrig_event (struct hid_device *hid, struct hid_field *field, |
492 | struct hid_usage *usage, __s32 value) | 541 | struct hid_usage *usage, __s32 value) |
493 | { | 542 | { |
494 | struct input_dev *input = field->hidinput->input; | 543 | struct input_dev *input = field->hidinput->input; |
495 | struct ntrig_data *nd = hid_get_drvdata(hid); | 544 | struct ntrig_data *nd = hid_get_drvdata(hid); |
@@ -848,6 +897,8 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
848 | if (report) | 897 | if (report) |
849 | usbhid_submit_report(hdev, report, USB_DIR_OUT); | 898 | usbhid_submit_report(hdev, report, USB_DIR_OUT); |
850 | 899 | ||
900 | ntrig_report_version(hdev); | ||
901 | |||
851 | ret = sysfs_create_group(&hdev->dev.kobj, | 902 | ret = sysfs_create_group(&hdev->dev.kobj, |
852 | &ntrig_attribute_group); | 903 | &ntrig_attribute_group); |
853 | 904 | ||
@@ -860,7 +911,7 @@ err_free: | |||
860 | static void ntrig_remove(struct hid_device *hdev) | 911 | static void ntrig_remove(struct hid_device *hdev) |
861 | { | 912 | { |
862 | sysfs_remove_group(&hdev->dev.kobj, | 913 | sysfs_remove_group(&hdev->dev.kobj, |
863 | &ntrig_attribute_group); | 914 | &ntrig_attribute_group); |
864 | hid_hw_stop(hdev); | 915 | hid_hw_stop(hdev); |
865 | kfree(hid_get_drvdata(hdev)); | 916 | kfree(hid_get_drvdata(hdev)); |
866 | } | 917 | } |
diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c index f6e80c7ca61e..5a6879e235ac 100644 --- a/drivers/hid/hid-roccat.c +++ b/drivers/hid/hid-roccat.c | |||
@@ -384,6 +384,7 @@ static const struct file_operations roccat_ops = { | |||
384 | .poll = roccat_poll, | 384 | .poll = roccat_poll, |
385 | .open = roccat_open, | 385 | .open = roccat_open, |
386 | .release = roccat_release, | 386 | .release = roccat_release, |
387 | .llseek = noop_llseek, | ||
387 | }; | 388 | }; |
388 | 389 | ||
389 | static int __init roccat_init(void) | 390 | static int __init roccat_init(void) |
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 402d5574b574..0c164b3dce3a 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c | |||
@@ -24,7 +24,9 @@ | |||
24 | 24 | ||
25 | #include "hid-ids.h" | 25 | #include "hid-ids.h" |
26 | 26 | ||
27 | #define VAIO_RDESC_CONSTANT 0x0001 | 27 | #define VAIO_RDESC_CONSTANT (1 << 0) |
28 | #define SIXAXIS_CONTROLLER_USB (1 << 1) | ||
29 | #define SIXAXIS_CONTROLLER_BT (1 << 2) | ||
28 | 30 | ||
29 | struct sony_sc { | 31 | struct sony_sc { |
30 | unsigned long quirks; | 32 | unsigned long quirks; |
@@ -44,12 +46,31 @@ static void sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
44 | } | 46 | } |
45 | } | 47 | } |
46 | 48 | ||
49 | static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf, | ||
50 | size_t count, unsigned char report_type) | ||
51 | { | ||
52 | struct usb_interface *intf = to_usb_interface(hid->dev.parent); | ||
53 | struct usb_device *dev = interface_to_usbdev(intf); | ||
54 | struct usb_host_interface *interface = intf->cur_altsetting; | ||
55 | int report_id = buf[0]; | ||
56 | int ret; | ||
57 | |||
58 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
59 | HID_REQ_SET_REPORT, | ||
60 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | ||
61 | ((report_type + 1) << 8) | report_id, | ||
62 | interface->desc.bInterfaceNumber, buf, count, | ||
63 | USB_CTRL_SET_TIMEOUT); | ||
64 | |||
65 | return ret; | ||
66 | } | ||
67 | |||
47 | /* | 68 | /* |
48 | * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller | 69 | * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller |
49 | * to "operational". Without this, the ps3 controller will not report any | 70 | * to "operational". Without this, the ps3 controller will not report any |
50 | * events. | 71 | * events. |
51 | */ | 72 | */ |
52 | static int sony_set_operational_usb(struct hid_device *hdev) | 73 | static int sixaxis_set_operational_usb(struct hid_device *hdev) |
53 | { | 74 | { |
54 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); | 75 | struct usb_interface *intf = to_usb_interface(hdev->dev.parent); |
55 | struct usb_device *dev = interface_to_usbdev(intf); | 76 | struct usb_device *dev = interface_to_usbdev(intf); |
@@ -74,7 +95,7 @@ static int sony_set_operational_usb(struct hid_device *hdev) | |||
74 | return ret; | 95 | return ret; |
75 | } | 96 | } |
76 | 97 | ||
77 | static int sony_set_operational_bt(struct hid_device *hdev) | 98 | static int sixaxis_set_operational_bt(struct hid_device *hdev) |
78 | { | 99 | { |
79 | unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; | 100 | unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; |
80 | return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); | 101 | return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); |
@@ -108,16 +129,14 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
108 | goto err_free; | 129 | goto err_free; |
109 | } | 130 | } |
110 | 131 | ||
111 | switch (hdev->bus) { | 132 | if (sc->quirks & SIXAXIS_CONTROLLER_USB) { |
112 | case BUS_USB: | 133 | hdev->hid_output_raw_report = sixaxis_usb_output_raw_report; |
113 | ret = sony_set_operational_usb(hdev); | 134 | ret = sixaxis_set_operational_usb(hdev); |
114 | break; | ||
115 | case BUS_BLUETOOTH: | ||
116 | ret = sony_set_operational_bt(hdev); | ||
117 | break; | ||
118 | default: | ||
119 | ret = 0; | ||
120 | } | 135 | } |
136 | else if (sc->quirks & SIXAXIS_CONTROLLER_BT) | ||
137 | ret = sixaxis_set_operational_bt(hdev); | ||
138 | else | ||
139 | ret = 0; | ||
121 | 140 | ||
122 | if (ret < 0) | 141 | if (ret < 0) |
123 | goto err_stop; | 142 | goto err_stop; |
@@ -137,8 +156,10 @@ static void sony_remove(struct hid_device *hdev) | |||
137 | } | 156 | } |
138 | 157 | ||
139 | static const struct hid_device_id sony_devices[] = { | 158 | static const struct hid_device_id sony_devices[] = { |
140 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, | 159 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), |
141 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, | 160 | .driver_data = SIXAXIS_CONTROLLER_USB }, |
161 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER), | ||
162 | .driver_data = SIXAXIS_CONTROLLER_BT }, | ||
142 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), | 163 | { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), |
143 | .driver_data = VAIO_RDESC_CONSTANT }, | 164 | .driver_data = VAIO_RDESC_CONSTANT }, |
144 | { } | 165 | { } |
diff --git a/drivers/hid/hid-stantum.c b/drivers/hid/hid-stantum.c index 90df886c5e04..3171be28c3d5 100644 --- a/drivers/hid/hid-stantum.c +++ b/drivers/hid/hid-stantum.c | |||
@@ -249,6 +249,8 @@ static void stantum_remove(struct hid_device *hdev) | |||
249 | 249 | ||
250 | static const struct hid_device_id stantum_devices[] = { | 250 | static const struct hid_device_id stantum_devices[] = { |
251 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) }, | 251 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) }, |
252 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM) }, | ||
253 | { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX) }, | ||
252 | { } | 254 | { } |
253 | }; | 255 | }; |
254 | MODULE_DEVICE_TABLE(hid, stantum_devices); | 256 | MODULE_DEVICE_TABLE(hid, stantum_devices); |
diff --git a/drivers/hid/hid-topseed.c b/drivers/hid/hid-topseed.c index 5771f851f856..956ed9ac19d4 100644 --- a/drivers/hid/hid-topseed.c +++ b/drivers/hid/hid-topseed.c | |||
@@ -64,6 +64,7 @@ static int ts_input_mapping(struct hid_device *hdev, struct hid_input *hi, | |||
64 | static const struct hid_device_id ts_devices[] = { | 64 | static const struct hid_device_id ts_devices[] = { |
65 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, | 65 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, |
66 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, | 66 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, |
67 | { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, | ||
67 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, | 68 | { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, |
68 | { } | 69 | { } |
69 | }; | 70 | }; |
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 47d70c523d93..8a4b32dca9f7 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c | |||
@@ -109,6 +109,12 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t | |||
109 | int ret = 0; | 109 | int ret = 0; |
110 | 110 | ||
111 | mutex_lock(&minors_lock); | 111 | mutex_lock(&minors_lock); |
112 | |||
113 | if (!hidraw_table[minor]) { | ||
114 | ret = -ENODEV; | ||
115 | goto out; | ||
116 | } | ||
117 | |||
112 | dev = hidraw_table[minor]->hid; | 118 | dev = hidraw_table[minor]->hid; |
113 | 119 | ||
114 | if (!dev->hid_output_raw_report) { | 120 | if (!dev->hid_output_raw_report) { |
@@ -212,9 +218,13 @@ static int hidraw_release(struct inode * inode, struct file * file) | |||
212 | unsigned int minor = iminor(inode); | 218 | unsigned int minor = iminor(inode); |
213 | struct hidraw *dev; | 219 | struct hidraw *dev; |
214 | struct hidraw_list *list = file->private_data; | 220 | struct hidraw_list *list = file->private_data; |
221 | int ret; | ||
215 | 222 | ||
216 | if (!hidraw_table[minor]) | 223 | mutex_lock(&minors_lock); |
217 | return -ENODEV; | 224 | if (!hidraw_table[minor]) { |
225 | ret = -ENODEV; | ||
226 | goto unlock; | ||
227 | } | ||
218 | 228 | ||
219 | list_del(&list->node); | 229 | list_del(&list->node); |
220 | dev = hidraw_table[minor]; | 230 | dev = hidraw_table[minor]; |
@@ -227,10 +237,12 @@ static int hidraw_release(struct inode * inode, struct file * file) | |||
227 | kfree(list->hidraw); | 237 | kfree(list->hidraw); |
228 | } | 238 | } |
229 | } | 239 | } |
230 | |||
231 | kfree(list); | 240 | kfree(list); |
241 | ret = 0; | ||
242 | unlock: | ||
243 | mutex_unlock(&minors_lock); | ||
232 | 244 | ||
233 | return 0; | 245 | return ret; |
234 | } | 246 | } |
235 | 247 | ||
236 | static long hidraw_ioctl(struct file *file, unsigned int cmd, | 248 | static long hidraw_ioctl(struct file *file, unsigned int cmd, |
@@ -244,6 +256,10 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd, | |||
244 | 256 | ||
245 | mutex_lock(&minors_lock); | 257 | mutex_lock(&minors_lock); |
246 | dev = hidraw_table[minor]; | 258 | dev = hidraw_table[minor]; |
259 | if (!dev) { | ||
260 | ret = -ENODEV; | ||
261 | goto out; | ||
262 | } | ||
247 | 263 | ||
248 | switch (cmd) { | 264 | switch (cmd) { |
249 | case HIDIOCGRDESCSIZE: | 265 | case HIDIOCGRDESCSIZE: |
@@ -317,6 +333,7 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd, | |||
317 | 333 | ||
318 | ret = -ENOTTY; | 334 | ret = -ENOTTY; |
319 | } | 335 | } |
336 | out: | ||
320 | mutex_unlock(&minors_lock); | 337 | mutex_unlock(&minors_lock); |
321 | return ret; | 338 | return ret; |
322 | } | 339 | } |
@@ -329,6 +346,7 @@ static const struct file_operations hidraw_ops = { | |||
329 | .open = hidraw_open, | 346 | .open = hidraw_open, |
330 | .release = hidraw_release, | 347 | .release = hidraw_release, |
331 | .unlocked_ioctl = hidraw_ioctl, | 348 | .unlocked_ioctl = hidraw_ioctl, |
349 | .llseek = noop_llseek, | ||
332 | }; | 350 | }; |
333 | 351 | ||
334 | void hidraw_report_event(struct hid_device *hid, u8 *data, int len) | 352 | void hidraw_report_event(struct hid_device *hid, u8 *data, int len) |
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index b729c0286679..5489eab3a6bd 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -807,9 +807,10 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co | |||
807 | struct usb_host_interface *interface = intf->cur_altsetting; | 807 | struct usb_host_interface *interface = intf->cur_altsetting; |
808 | int ret; | 808 | int ret; |
809 | 809 | ||
810 | if (usbhid->urbout) { | 810 | if (usbhid->urbout && report_type != HID_FEATURE_REPORT) { |
811 | int actual_length; | 811 | int actual_length; |
812 | int skipped_report_id = 0; | 812 | int skipped_report_id = 0; |
813 | |||
813 | if (buf[0] == 0x0) { | 814 | if (buf[0] == 0x0) { |
814 | /* Don't send the Report ID */ | 815 | /* Don't send the Report ID */ |
815 | buf++; | 816 | buf++; |
@@ -828,6 +829,7 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co | |||
828 | } | 829 | } |
829 | } else { | 830 | } else { |
830 | int skipped_report_id = 0; | 831 | int skipped_report_id = 0; |
832 | int report_id = buf[0]; | ||
831 | if (buf[0] == 0x0) { | 833 | if (buf[0] == 0x0) { |
832 | /* Don't send the Report ID */ | 834 | /* Don't send the Report ID */ |
833 | buf++; | 835 | buf++; |
@@ -837,7 +839,7 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co | |||
837 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 839 | ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
838 | HID_REQ_SET_REPORT, | 840 | HID_REQ_SET_REPORT, |
839 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 841 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
840 | ((report_type + 1) << 8) | *buf, | 842 | ((report_type + 1) << 8) | report_id, |
841 | interface->desc.bInterfaceNumber, buf, count, | 843 | interface->desc.bInterfaceNumber, buf, count, |
842 | USB_CTRL_SET_TIMEOUT); | 844 | USB_CTRL_SET_TIMEOUT); |
843 | /* count also the report id, if this was a numbered report. */ | 845 | /* count also the report id, if this was a numbered report. */ |
@@ -1445,6 +1447,11 @@ static const struct hid_device_id hid_usb_table[] = { | |||
1445 | { } | 1447 | { } |
1446 | }; | 1448 | }; |
1447 | 1449 | ||
1450 | struct usb_interface *usbhid_find_interface(int minor) | ||
1451 | { | ||
1452 | return usb_find_interface(&hid_driver, minor); | ||
1453 | } | ||
1454 | |||
1448 | static struct hid_driver hid_usb_driver = { | 1455 | static struct hid_driver hid_usb_driver = { |
1449 | .name = "generic-usb", | 1456 | .name = "generic-usb", |
1450 | .id_table = hid_usb_table, | 1457 | .id_table = hid_usb_table, |
@@ -1463,9 +1470,6 @@ static int __init hid_init(void) | |||
1463 | retval = usbhid_quirks_init(quirks_param); | 1470 | retval = usbhid_quirks_init(quirks_param); |
1464 | if (retval) | 1471 | if (retval) |
1465 | goto usbhid_quirks_init_fail; | 1472 | goto usbhid_quirks_init_fail; |
1466 | retval = hiddev_init(); | ||
1467 | if (retval) | ||
1468 | goto hiddev_init_fail; | ||
1469 | retval = usb_register(&hid_driver); | 1473 | retval = usb_register(&hid_driver); |
1470 | if (retval) | 1474 | if (retval) |
1471 | goto usb_register_fail; | 1475 | goto usb_register_fail; |
@@ -1473,8 +1477,6 @@ static int __init hid_init(void) | |||
1473 | 1477 | ||
1474 | return 0; | 1478 | return 0; |
1475 | usb_register_fail: | 1479 | usb_register_fail: |
1476 | hiddev_exit(); | ||
1477 | hiddev_init_fail: | ||
1478 | usbhid_quirks_exit(); | 1480 | usbhid_quirks_exit(); |
1479 | usbhid_quirks_init_fail: | 1481 | usbhid_quirks_init_fail: |
1480 | hid_unregister_driver(&hid_usb_driver); | 1482 | hid_unregister_driver(&hid_usb_driver); |
@@ -1487,7 +1489,6 @@ no_queue: | |||
1487 | static void __exit hid_exit(void) | 1489 | static void __exit hid_exit(void) |
1488 | { | 1490 | { |
1489 | usb_deregister(&hid_driver); | 1491 | usb_deregister(&hid_driver); |
1490 | hiddev_exit(); | ||
1491 | usbhid_quirks_exit(); | 1492 | usbhid_quirks_exit(); |
1492 | hid_unregister_driver(&hid_usb_driver); | 1493 | hid_unregister_driver(&hid_usb_driver); |
1493 | destroy_workqueue(resumption_waker); | 1494 | destroy_workqueue(resumption_waker); |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 2643d3147621..836a87473c58 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -33,8 +33,9 @@ static const struct hid_blacklist { | |||
33 | { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD }, | 33 | { USB_VENDOR_ID_AASHIMA, USB_DEVICE_ID_AASHIMA_PREDATOR, HID_QUIRK_BADPAD }, |
34 | { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, | 34 | { USB_VENDOR_ID_ALPS, USB_DEVICE_ID_IBM_GAMEPAD, HID_QUIRK_BADPAD }, |
35 | { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, | 35 | { USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD, HID_QUIRK_BADPAD }, |
36 | { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH, HID_QUIRK_MULTI_INPUT }, | 36 | { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET }, |
37 | { USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT }, | 37 | { USB_VENDOR_ID_MOJO, USB_DEVICE_ID_RETRO_ADAPTER, HID_QUIRK_MULTI_INPUT }, |
38 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART, HID_QUIRK_MULTI_INPUT }, | ||
38 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, | 39 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_DRIVING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, |
39 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, | 40 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, |
40 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, | 41 | { USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING, HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, |
@@ -61,6 +62,7 @@ static const struct hid_blacklist { | |||
61 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE, HID_QUIRK_NOGET }, | 62 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE, HID_QUIRK_NOGET }, |
62 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS, HID_QUIRK_NOGET }, | 63 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS, HID_QUIRK_NOGET }, |
63 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK, HID_QUIRK_NOGET }, | 64 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK, HID_QUIRK_NOGET }, |
65 | { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, | ||
64 | { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, | 66 | { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, |
65 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, | 67 | { USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET }, |
66 | { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, | 68 | { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, |
@@ -69,6 +71,7 @@ static const struct hid_blacklist { | |||
69 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, | 71 | { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD, HID_QUIRK_NOGET }, |
70 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT }, | 72 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209, HID_QUIRK_MULTI_INPUT }, |
71 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT }, | 73 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U, HID_QUIRK_MULTI_INPUT }, |
74 | { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5, HID_QUIRK_MULTI_INPUT }, | ||
72 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, | 75 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, |
73 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, | 76 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, |
74 | 77 | ||
@@ -77,6 +80,8 @@ static const struct hid_blacklist { | |||
77 | 80 | ||
78 | { USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE }, | 81 | { USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE }, |
79 | 82 | ||
83 | { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT }, | ||
84 | |||
80 | { 0, 0 } | 85 | { 0, 0 } |
81 | }; | 86 | }; |
82 | 87 | ||
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 0a29c51114aa..fedd88df9a18 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
@@ -67,8 +67,6 @@ struct hiddev_list { | |||
67 | struct mutex thread_lock; | 67 | struct mutex thread_lock; |
68 | }; | 68 | }; |
69 | 69 | ||
70 | static struct usb_driver hiddev_driver; | ||
71 | |||
72 | /* | 70 | /* |
73 | * Find a report, given the report's type and ID. The ID can be specified | 71 | * Find a report, given the report's type and ID. The ID can be specified |
74 | * indirectly by REPORT_ID_FIRST (which returns the first report of the given | 72 | * indirectly by REPORT_ID_FIRST (which returns the first report of the given |
@@ -270,7 +268,7 @@ static int hiddev_open(struct inode *inode, struct file *file) | |||
270 | struct hiddev *hiddev; | 268 | struct hiddev *hiddev; |
271 | int res; | 269 | int res; |
272 | 270 | ||
273 | intf = usb_find_interface(&hiddev_driver, iminor(inode)); | 271 | intf = usbhid_find_interface(iminor(inode)); |
274 | if (!intf) | 272 | if (!intf) |
275 | return -ENODEV; | 273 | return -ENODEV; |
276 | hid = usb_get_intfdata(intf); | 274 | hid = usb_get_intfdata(intf); |
@@ -847,6 +845,7 @@ static const struct file_operations hiddev_fops = { | |||
847 | #ifdef CONFIG_COMPAT | 845 | #ifdef CONFIG_COMPAT |
848 | .compat_ioctl = hiddev_compat_ioctl, | 846 | .compat_ioctl = hiddev_compat_ioctl, |
849 | #endif | 847 | #endif |
848 | .llseek = noop_llseek, | ||
850 | }; | 849 | }; |
851 | 850 | ||
852 | static char *hiddev_devnode(struct device *dev, mode_t *mode) | 851 | static char *hiddev_devnode(struct device *dev, mode_t *mode) |
@@ -925,41 +924,3 @@ void hiddev_disconnect(struct hid_device *hid) | |||
925 | kfree(hiddev); | 924 | kfree(hiddev); |
926 | } | 925 | } |
927 | } | 926 | } |
928 | |||
929 | /* Currently this driver is a USB driver. It's not a conventional one in | ||
930 | * the sense that it doesn't probe at the USB level. Instead it waits to | ||
931 | * be connected by HID through the hiddev_connect / hiddev_disconnect | ||
932 | * routines. The reason to register as a USB device is to gain part of the | ||
933 | * minor number space from the USB major. | ||
934 | * | ||
935 | * In theory, should the HID code be generalized to more than one physical | ||
936 | * medium (say, IEEE 1384), this driver will probably need to register its | ||
937 | * own major number, and in doing so, no longer need to register with USB. | ||
938 | * At that point the probe routine and hiddev_driver struct below will no | ||
939 | * longer be useful. | ||
940 | */ | ||
941 | |||
942 | |||
943 | /* We never attach in this manner, and rely on HID to connect us. This | ||
944 | * is why there is no disconnect routine defined in the usb_driver either. | ||
945 | */ | ||
946 | static int hiddev_usbd_probe(struct usb_interface *intf, | ||
947 | const struct usb_device_id *hiddev_info) | ||
948 | { | ||
949 | return -ENODEV; | ||
950 | } | ||
951 | |||
952 | static /* const */ struct usb_driver hiddev_driver = { | ||
953 | .name = "hiddev", | ||
954 | .probe = hiddev_usbd_probe, | ||
955 | }; | ||
956 | |||
957 | int __init hiddev_init(void) | ||
958 | { | ||
959 | return usb_register(&hiddev_driver); | ||
960 | } | ||
961 | |||
962 | void hiddev_exit(void) | ||
963 | { | ||
964 | usb_deregister(&hiddev_driver); | ||
965 | } | ||
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h index 693fd3e720df..89d2e847dcc6 100644 --- a/drivers/hid/usbhid/usbhid.h +++ b/drivers/hid/usbhid/usbhid.h | |||
@@ -42,6 +42,7 @@ void usbhid_submit_report | |||
42 | (struct hid_device *hid, struct hid_report *report, unsigned char dir); | 42 | (struct hid_device *hid, struct hid_report *report, unsigned char dir); |
43 | int usbhid_get_power(struct hid_device *hid); | 43 | int usbhid_get_power(struct hid_device *hid); |
44 | void usbhid_put_power(struct hid_device *hid); | 44 | void usbhid_put_power(struct hid_device *hid); |
45 | struct usb_interface *usbhid_find_interface(int minor); | ||
45 | 46 | ||
46 | /* iofl flags */ | 47 | /* iofl flags */ |
47 | #define HID_CTRL_RUNNING 1 | 48 | #define HID_CTRL_RUNNING 1 |