aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-10-24 15:44:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-10-24 15:44:59 -0400
commit7c024e9534f9edd8d052380a1b40d376c8feb11b (patch)
tree521eeb9d1eaa851e254a372bd008a07ab1f5e574 /drivers
parent188e213dbc5758bbfb62f7ce0367c5c8de057f02 (diff)
parentd8692ac012104ebffb343c0bcb4a2b8642c821a6 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (47 commits) HID: fix mismerge in hid-lg HID: hidraw: fix window in hidraw_release HID: hid-sony: override usbhid_output_raw_report for Sixaxis HID: add absolute axis resolution calculation HID: force feedback support for Logitech RumblePad gamepad HID: support STmicroelectronics and Sitronix with hid-stantuml driver HID: magicmouse: Adjust major / minor axes to scale HID: Fix for problems with eGalax/DWAV multi-touch-screen HID: waltop: add support for Waltop Slim Tablet 12.1 inch HID: add NOGET quirk for AXIS 295 Video Surveillance Joystick HID: usbhid: remove unused hiddev_driver HID: magicmouse: Use hid-input parsing rather than bypassing it HID: trivial formatting fix HID: Add support for Logitech Speed Force Wireless gaming wheel HID: don't Send Feature Reports on Interrupt Endpoint HID: 3m: Adjust major / minor axes to scale HID: 3m: Correct touchscreen emulation HID: 3m: Convert to MT slots HID: 3m: Output proper orientation range HID: 3m: Adjust to sequential MT HID protocol ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hid/Kconfig91
-rw-r--r--drivers/hid/Makefile6
-rw-r--r--drivers/hid/hid-3m-pct.c127
-rw-r--r--drivers/hid/hid-a4tech.c2
-rw-r--r--drivers/hid/hid-apple.c7
-rw-r--r--drivers/hid/hid-cherry.c7
-rw-r--r--drivers/hid/hid-core.c23
-rw-r--r--drivers/hid/hid-cypress.c9
-rw-r--r--drivers/hid/hid-debug.c2
-rw-r--r--drivers/hid/hid-egalax.c16
-rw-r--r--drivers/hid/hid-elecom.c7
-rw-r--r--drivers/hid/hid-ids.h23
-rw-r--r--drivers/hid/hid-input.c87
-rw-r--r--drivers/hid/hid-kye.c7
-rw-r--r--drivers/hid/hid-lg.c49
-rw-r--r--drivers/hid/hid-lg.h6
-rw-r--r--drivers/hid/hid-lg2ff.c4
-rw-r--r--drivers/hid/hid-lg4ff.c136
-rw-r--r--drivers/hid/hid-magicmouse.c325
-rw-r--r--drivers/hid/hid-microsoft.c7
-rw-r--r--drivers/hid/hid-monterey.c7
-rw-r--r--drivers/hid/hid-ntrig.c69
-rw-r--r--drivers/hid/hid-ortek.c7
-rw-r--r--drivers/hid/hid-petalynx.c7
-rw-r--r--drivers/hid/hid-prodikeys.c7
-rw-r--r--drivers/hid/hid-roccat-pyra.c968
-rw-r--r--drivers/hid/hid-roccat-pyra.h186
-rw-r--r--drivers/hid/hid-samsung.c20
-rw-r--r--drivers/hid/hid-sony.c56
-rw-r--r--drivers/hid/hid-stantum.c2
-rw-r--r--drivers/hid/hid-sunplus.c7
-rw-r--r--drivers/hid/hid-uclogic.c623
-rw-r--r--drivers/hid/hid-waltop.c1099
-rw-r--r--drivers/hid/hid-zydacron.c7
-rw-r--r--drivers/hid/hidraw.c14
-rw-r--r--drivers/hid/usbhid/hid-core.c9
-rw-r--r--drivers/hid/usbhid/hid-quirks.c6
-rw-r--r--drivers/hid/usbhid/hiddev.c40
38 files changed, 3707 insertions, 368 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 6369ba7f96f8..3052e2969ad0 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
58config HID_3M_PCT 58config 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
64config HID_A4TECH 64config 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
71config HID_ACRUX_FF 71config 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
79config HID_APPLE 79config 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
90config HID_BELKIN 90config 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
103config HID_CHERRY 103config 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
110config HID_CHICONY 110config 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
132config HID_CYPRESS 132config 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
139config HID_DRAGONRISE 139config 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
145config DRAGONRISE_FF 145config 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,58 @@ config HID_EGALAX
157 Support for the eGalax dual-touch panel. 157 Support for the eGalax dual-touch panel.
158 158
159config HID_ELECOM 159config 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
165config HID_EZKEY 165config 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
172config HID_KYE 172config 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
179config HID_UCLOGIC
180 tristate "UC-Logic"
181 depends on USB_HID
182 ---help---
183 Support for UC-Logic tablets.
184
185config HID_WALTOP
186 tristate "Waltop"
187 depends on USB_HID
188 ---help---
189 Support for Waltop tablets.
190
179config HID_GYRATION 191config HID_GYRATION
180 tristate "Gyration" 192 tristate "Gyration remote control"
181 depends on USB_HID 193 depends on USB_HID
182 ---help--- 194 ---help---
183 Support for Gyration remote control. 195 Support for Gyration remote control.
184 196
185config HID_TWINHAN 197config HID_TWINHAN
186 tristate "Twinhan" 198 tristate "Twinhan IR remote control"
187 depends on USB_HID 199 depends on USB_HID
188 ---help--- 200 ---help---
189 Support for Twinhan IR remote control. 201 Support for Twinhan IR remote control.
190 202
191config HID_KENSINGTON 203config HID_KENSINGTON
192 tristate "Kensington" if EMBEDDED 204 tristate "Kensington Slimblade Trackball" if EMBEDDED
193 depends on USB_HID 205 depends on USB_HID
194 default !EMBEDDED 206 default !EMBEDDED
195 ---help--- 207 ---help---
196 Support for Kensington Slimblade Trackball. 208 Support for Kensington Slimblade Trackball.
197 209
198config HID_LOGITECH 210config HID_LOGITECH
199 tristate "Logitech" if EMBEDDED 211 tristate "Logitech devices" if EMBEDDED
200 depends on USB_HID 212 depends on USB_HID
201 default !EMBEDDED 213 default !EMBEDDED
202 ---help--- 214 ---help---
@@ -220,12 +232,12 @@ config LOGITECH_FF
220 force feedback. 232 force feedback.
221 233
222config LOGIRUMBLEPAD2_FF 234config LOGIRUMBLEPAD2_FF
223 bool "Logitech Rumblepad 2 force feedback support" 235 bool "Logitech RumblePad/Rumblepad 2 force feedback support"
224 depends on HID_LOGITECH 236 depends on HID_LOGITECH
225 select INPUT_FF_MEMLESS 237 select INPUT_FF_MEMLESS
226 help 238 help
227 Say Y here if you want to enable force feedback support for Logitech 239 Say Y here if you want to enable force feedback support for Logitech
228 Rumblepad 2 devices. 240 RumblePad and Rumblepad 2 devices.
229 241
230config LOGIG940_FF 242config LOGIG940_FF
231 bool "Logitech Flight System G940 force feedback support" 243 bool "Logitech Flight System G940 force feedback support"
@@ -235,6 +247,14 @@ config LOGIG940_FF
235 Say Y here if you want to enable force feedback support for Logitech 247 Say Y here if you want to enable force feedback support for Logitech
236 Flight System G940 devices. 248 Flight System G940 devices.
237 249
250config LOGIWII_FF
251 bool "Logitech Speed Force Wireless force feedback support"
252 depends on HID_LOGITECH
253 select INPUT_FF_MEMLESS
254 help
255 Say Y here if you want to enable force feedback support for Logitech
256 Speed Force Wireless (Wii) devices.
257
238config HID_MAGICMOUSE 258config HID_MAGICMOUSE
239 tristate "Apple MagicMouse multi-touch support" 259 tristate "Apple MagicMouse multi-touch support"
240 depends on BT_HIDP 260 depends on BT_HIDP
@@ -245,39 +265,39 @@ config HID_MAGICMOUSE
245 Apple Wireless "Magic" Mouse. 265 Apple Wireless "Magic" Mouse.
246 266
247config HID_MICROSOFT 267config HID_MICROSOFT
248 tristate "Microsoft" if EMBEDDED 268 tristate "Microsoft non-fully HID-compliant devices" if EMBEDDED
249 depends on USB_HID 269 depends on USB_HID
250 default !EMBEDDED 270 default !EMBEDDED
251 ---help--- 271 ---help---
252 Support for Microsoft devices that are not fully compliant with HID standard. 272 Support for Microsoft devices that are not fully compliant with HID standard.
253 273
254config HID_MOSART 274config HID_MOSART
255 tristate "MosArt" 275 tristate "MosArt dual-touch panels"
256 depends on USB_HID 276 depends on USB_HID
257 ---help--- 277 ---help---
258 Support for MosArt dual-touch panels. 278 Support for MosArt dual-touch panels.
259 279
260config HID_MONTEREY 280config HID_MONTEREY
261 tristate "Monterey" if EMBEDDED 281 tristate "Monterey Genius KB29E keyboard" if EMBEDDED
262 depends on USB_HID 282 depends on USB_HID
263 default !EMBEDDED 283 default !EMBEDDED
264 ---help--- 284 ---help---
265 Support for Monterey Genius KB29E. 285 Support for Monterey Genius KB29E.
266 286
267config HID_NTRIG 287config HID_NTRIG
268 tristate "NTrig" 288 tristate "N-Trig touch screen"
269 depends on USB_HID 289 depends on USB_HID
270 ---help--- 290 ---help---
271 Support for N-Trig touch screen. 291 Support for N-Trig touch screen.
272 292
273config HID_ORTEK 293config HID_ORTEK
274 tristate "Ortek" 294 tristate "Ortek WKB-2000 wireless keyboard and mouse trackpad"
275 depends on USB_HID 295 depends on USB_HID
276 ---help--- 296 ---help---
277 Support for Ortek WKB-2000 wireless keyboard + mouse trackpad. 297 Support for Ortek WKB-2000 wireless keyboard + mouse trackpad.
278 298
279config HID_PANTHERLORD 299config HID_PANTHERLORD
280 tristate "Pantherlord support" 300 tristate "Pantherlord/GreenAsia game controller"
281 depends on USB_HID 301 depends on USB_HID
282 ---help--- 302 ---help---
283 Say Y here if you have a PantherLord/GreenAsia based game controller 303 Say Y here if you have a PantherLord/GreenAsia based game controller
@@ -292,7 +312,7 @@ config PANTHERLORD_FF
292 or adapter and want to enable force feedback support for it. 312 or adapter and want to enable force feedback support for it.
293 313
294config HID_PETALYNX 314config HID_PETALYNX
295 tristate "Petalynx" 315 tristate "Petalynx Maxter remote control"
296 depends on USB_HID 316 depends on USB_HID
297 ---help--- 317 ---help---
298 Support for Petalynx Maxter remote control. 318 Support for Petalynx Maxter remote control.
@@ -356,7 +376,7 @@ config HID_PICOLCD_LEDS
356 Provide access to PicoLCD's GPO pins via leds class. 376 Provide access to PicoLCD's GPO pins via leds class.
357 377
358config HID_QUANTA 378config HID_QUANTA
359 tristate "Quanta Optical Touch" 379 tristate "Quanta Optical Touch panels"
360 depends on USB_HID 380 depends on USB_HID
361 ---help--- 381 ---help---
362 Support for Quanta Optical Touch dual-touch panels. 382 Support for Quanta Optical Touch dual-touch panels.
@@ -376,32 +396,39 @@ config HID_ROCCAT_KONE
376 ---help--- 396 ---help---
377 Support for Roccat Kone mouse. 397 Support for Roccat Kone mouse.
378 398
399config HID_ROCCAT_PYRA
400 tristate "Roccat Pyra mouse support"
401 depends on USB_HID
402 select HID_ROCCAT
403 ---help---
404 Support for Roccat Pyra mouse.
405
379config HID_SAMSUNG 406config HID_SAMSUNG
380 tristate "Samsung" 407 tristate "Samsung InfraRed remote control or keyboards"
381 depends on USB_HID 408 depends on USB_HID
382 ---help--- 409 ---help---
383 Support for Samsung InfraRed remote control or keyboards. 410 Support for Samsung InfraRed remote control or keyboards.
384 411
385config HID_SONY 412config HID_SONY
386 tristate "Sony" 413 tristate "Sony PS3 controller"
387 depends on USB_HID 414 depends on USB_HID
388 ---help--- 415 ---help---
389 Support for Sony PS3 controller. 416 Support for Sony PS3 controller.
390 417
391config HID_STANTUM 418config HID_STANTUM
392 tristate "Stantum" 419 tristate "Stantum multitouch panel"
393 depends on USB_HID 420 depends on USB_HID
394 ---help--- 421 ---help---
395 Support for Stantum multitouch panel. 422 Support for Stantum multitouch panel.
396 423
397config HID_SUNPLUS 424config HID_SUNPLUS
398 tristate "Sunplus" 425 tristate "Sunplus wireless desktop"
399 depends on USB_HID 426 depends on USB_HID
400 ---help--- 427 ---help---
401 Support for Sunplus wireless desktop. 428 Support for Sunplus wireless desktop.
402 429
403config HID_GREENASIA 430config HID_GREENASIA
404 tristate "GreenAsia (Product ID 0x12) support" 431 tristate "GreenAsia (Product ID 0x12) game controller support"
405 depends on USB_HID 432 depends on USB_HID
406 ---help--- 433 ---help---
407 Say Y here if you have a GreenAsia (Product ID 0x12) based game 434 Say Y here if you have a GreenAsia (Product ID 0x12) based game
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 46f037f3df80..c335605b9200 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -21,6 +21,9 @@ endif
21ifdef CONFIG_LOGIG940_FF 21ifdef CONFIG_LOGIG940_FF
22 hid-logitech-objs += hid-lg3ff.o 22 hid-logitech-objs += hid-lg3ff.o
23endif 23endif
24ifdef CONFIG_LOGIWII_FF
25 hid-logitech-objs += hid-lg4ff.o
26endif
24 27
25obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o 28obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o
26obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o 29obj-$(CONFIG_HID_A4TECH) += hid-a4tech.o
@@ -52,6 +55,7 @@ obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
52obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o 55obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o
53obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o 56obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o
54obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o 57obj-$(CONFIG_HID_ROCCAT_KONE) += hid-roccat-kone.o
58obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o
55obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o 59obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
56obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o 60obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
57obj-$(CONFIG_HID_SONY) += hid-sony.o 61obj-$(CONFIG_HID_SONY) += hid-sony.o
@@ -61,9 +65,11 @@ obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o
61obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o 65obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o
62obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o 66obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o
63obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o 67obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o
68obj-$(CONFIG_HID_UCLOGIC) += hid-uclogic.o
64obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o 69obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o
65obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o 70obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o
66obj-$(CONFIG_HID_WACOM) += hid-wacom.o 71obj-$(CONFIG_HID_WACOM) += hid-wacom.o
72obj-$(CONFIG_HID_WALTOP) += hid-waltop.o
67 73
68obj-$(CONFIG_USB_HID) += usbhid/ 74obj-$(CONFIG_USB_HID) += usbhid/
69obj-$(CONFIG_USB_MOUSE) += usbhid/ 75obj-$(CONFIG_USB_MOUSE) += usbhid/
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
27struct mmm_finger { 37struct 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
33struct mmm_data { 44struct 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,
126static void mmm_filter_event(struct mmm_data *md, struct input_dev *input) 155static 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};
138MODULE_DEVICE_TABLE(hid, a4_devices); 140MODULE_DEVICE_TABLE(hid, a4_devices);
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index bba05d0a8980..eaeca564a8d3 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -246,17 +246,18 @@ static int apple_event(struct hid_device *hdev, struct hid_field *field,
246/* 246/*
247 * MacBook JIS keyboard has wrong logical maximum 247 * MacBook JIS keyboard has wrong logical maximum
248 */ 248 */
249static void apple_report_fixup(struct hid_device *hdev, __u8 *rdesc, 249static __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
250 unsigned int rsize) 250 unsigned int *rsize)
251{ 251{
252 struct apple_sc *asc = hid_get_drvdata(hdev); 252 struct apple_sc *asc = hid_get_drvdata(hdev);
253 253
254 if ((asc->quirks & APPLE_RDESC_JIS) && rsize >= 60 && 254 if ((asc->quirks & APPLE_RDESC_JIS) && *rsize >= 60 &&
255 rdesc[53] == 0x65 && rdesc[59] == 0x65) { 255 rdesc[53] == 0x65 && rdesc[59] == 0x65) {
256 dev_info(&hdev->dev, "fixing up MacBook JIS keyboard report " 256 dev_info(&hdev->dev, "fixing up MacBook JIS keyboard report "
257 "descriptor\n"); 257 "descriptor\n");
258 rdesc[53] = rdesc[59] = 0xe7; 258 rdesc[53] = rdesc[59] = 0xe7;
259 } 259 }
260 return rdesc;
260} 261}
261 262
262static void apple_setup_input(struct input_dev *input) 263static void apple_setup_input(struct input_dev *input)
diff --git a/drivers/hid/hid-cherry.c b/drivers/hid/hid-cherry.c
index 24663a8717b1..e880086c2311 100644
--- a/drivers/hid/hid-cherry.c
+++ b/drivers/hid/hid-cherry.c
@@ -26,15 +26,16 @@
26 * Cherry Cymotion keyboard have an invalid HID report descriptor, 26 * Cherry Cymotion keyboard have an invalid HID report descriptor,
27 * that needs fixing before we can parse it. 27 * that needs fixing before we can parse it.
28 */ 28 */
29static void ch_report_fixup(struct hid_device *hdev, __u8 *rdesc, 29static __u8 *ch_report_fixup(struct hid_device *hdev, __u8 *rdesc,
30 unsigned int rsize) 30 unsigned int *rsize)
31{ 31{
32 if (rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { 32 if (*rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) {
33 dev_info(&hdev->dev, "fixing up Cherry Cymotion report " 33 dev_info(&hdev->dev, "fixing up Cherry Cymotion report "
34 "descriptor\n"); 34 "descriptor\n");
35 rdesc[11] = rdesc[16] = 0xff; 35 rdesc[11] = rdesc[16] = 0xff;
36 rdesc[12] = rdesc[17] = 0x03; 36 rdesc[12] = rdesc[17] = 0x03;
37 } 37 }
38 return rdesc;
38} 39}
39 40
40#define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ 41#define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 3cb6632d4518..7832b6e2478b 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -388,12 +388,6 @@ static int hid_parser_local(struct hid_parser *parser, struct hid_item *item)
388 __u32 data; 388 __u32 data;
389 unsigned n; 389 unsigned n;
390 390
391 /* Local delimiter could have value 0, which allows size to be 0 */
392 if (item->size == 0 && item->tag != HID_LOCAL_ITEM_TAG_DELIMITER) {
393 dbg_hid("item data expected for local item\n");
394 return -1;
395 }
396
397 data = item_udata(item); 391 data = item_udata(item);
398 392
399 switch (item->tag) { 393 switch (item->tag) {
@@ -651,7 +645,7 @@ int hid_parse_report(struct hid_device *device, __u8 *start,
651 }; 645 };
652 646
653 if (device->driver->report_fixup) 647 if (device->driver->report_fixup)
654 device->driver->report_fixup(device, start, size); 648 start = device->driver->report_fixup(device, start, &size);
655 649
656 device->rdesc = kmemdup(start, size, GFP_KERNEL); 650 device->rdesc = kmemdup(start, size, GFP_KERNEL);
657 if (device->rdesc == NULL) 651 if (device->rdesc == NULL)
@@ -1241,6 +1235,7 @@ static const struct hid_device_id hid_blacklist[] = {
1241 { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) }, 1235 { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) },
1242 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, 1236 { 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) }, 1237 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
1238 { 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) 1239#if defined(CONFIG_HID_ACRUX_FF) || defined(CONFIG_HID_ACRUX_FF_MODULE)
1245 { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) }, 1240 { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) },
1246#endif 1241#endif
@@ -1248,6 +1243,7 @@ static const struct hid_device_id hid_blacklist[] = {
1248 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IRCONTROL4) }, 1243 { 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) }, 1244 { 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) }, 1245 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) },
1246 { 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) }, 1247 { 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) }, 1248 { 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) }, 1249 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI) },
@@ -1327,6 +1323,7 @@ static const struct hid_device_id hid_blacklist[] = {
1327 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) }, 1323 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_CORDLESS_DESKTOP_LX500) },
1328 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) }, 1324 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_EXTREME_3D) },
1329 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) }, 1325 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WHEEL) },
1326 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) },
1330 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, 1327 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) },
1331 { 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_RUMBLEPAD2_2) },
1332 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, 1329 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) },
@@ -1336,6 +1333,7 @@ static const struct hid_device_id hid_blacklist[] = {
1336 { 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_WHEEL) },
1337 { 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_MOMO_WHEEL2) },
1338 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) }, 1335 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },
1336 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) },
1339 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) }, 1337 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
1340 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) }, 1338 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },
1341 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) }, 1339 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) },
@@ -1371,12 +1369,15 @@ static const struct hid_device_id hid_blacklist[] = {
1371 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) }, 1369 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH) },
1372 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) }, 1370 { HID_USB_DEVICE(USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN) },
1373 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) }, 1371 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
1372 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
1374 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, 1373 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
1375 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, 1374 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
1376 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 1375 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
1377 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 1376 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
1378 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, 1377 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) },
1379 { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) }, 1378 { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM, USB_DEVICE_ID_MTP) },
1379 { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM) },
1380 { HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX) },
1380 { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, 1381 { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) },
1381 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, 1382 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) },
1382 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, 1383 { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) },
@@ -1388,8 +1389,16 @@ static const struct hid_device_id hid_blacklist[] = {
1388 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) }, 1389 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
1389 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, 1390 { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
1390 { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) }, 1391 { HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
1392 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) },
1393 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) },
1394 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) },
1395 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) },
1391 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, 1396 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
1392 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) }, 1397 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
1398 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
1399 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) },
1400 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) },
1401 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) },
1393 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, 1402 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
1394 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, 1403 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
1395 { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) }, 1404 { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c
index 998b6f443d7d..4cd0e2345991 100644
--- a/drivers/hid/hid-cypress.c
+++ b/drivers/hid/hid-cypress.c
@@ -31,16 +31,16 @@
31 * Some USB barcode readers from cypress have usage min and usage max in 31 * Some USB barcode readers from cypress have usage min and usage max in
32 * the wrong order 32 * the wrong order
33 */ 33 */
34static void cp_report_fixup(struct hid_device *hdev, __u8 *rdesc, 34static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
35 unsigned int rsize) 35 unsigned int *rsize)
36{ 36{
37 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); 37 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
38 unsigned int i; 38 unsigned int i;
39 39
40 if (!(quirks & CP_RDESC_SWAPPED_MIN_MAX)) 40 if (!(quirks & CP_RDESC_SWAPPED_MIN_MAX))
41 return; 41 return rdesc;
42 42
43 for (i = 0; i < rsize - 4; i++) 43 for (i = 0; i < *rsize - 4; i++)
44 if (rdesc[i] == 0x29 && rdesc[i + 2] == 0x19) { 44 if (rdesc[i] == 0x29 && rdesc[i + 2] == 0x19) {
45 __u8 tmp; 45 __u8 tmp;
46 46
@@ -50,6 +50,7 @@ static void cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
50 rdesc[i + 3] = rdesc[i + 1]; 50 rdesc[i + 3] = rdesc[i + 1];
51 rdesc[i + 1] = tmp; 51 rdesc[i + 1] = tmp;
52 } 52 }
53 return rdesc;
53} 54}
54 55
55static int cp_input_mapped(struct hid_device *hdev, struct hid_input *hi, 56static int cp_input_mapped(struct hid_device *hdev, struct hid_input *hi,
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index 61a3e572224a..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}
574EXPORT_SYMBOL_GPL(hid_debug_event); 576EXPORT_SYMBOL_GPL(hid_debug_event);
575 577
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
37static int egalax_input_mapping(struct hid_device *hdev, struct hid_input *hi, 37static 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-elecom.c b/drivers/hid/hid-elecom.c
index 7a40878f46b4..6e31f305397d 100644
--- a/drivers/hid/hid-elecom.c
+++ b/drivers/hid/hid-elecom.c
@@ -20,14 +20,15 @@
20 20
21#include "hid-ids.h" 21#include "hid-ids.h"
22 22
23static void elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc, 23static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
24 unsigned int rsize) 24 unsigned int *rsize)
25{ 25{
26 if (rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) { 26 if (*rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) {
27 dev_info(&hdev->dev, "Fixing up Elecom BM084 " 27 dev_info(&hdev->dev, "Fixing up Elecom BM084 "
28 "report descriptor.\n"); 28 "report descriptor.\n");
29 rdesc[47] = 0x00; 29 rdesc[47] = 0x00;
30 } 30 }
31 return rdesc;
31} 32}
32 33
33static const struct hid_device_id elecom_devices[] = { 34static const struct hid_device_id elecom_devices[] = {
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 855aa8e355f4..3ee999d33004 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
@@ -142,6 +144,7 @@
142#define USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE 0x0051 144#define USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE 0x0051
143#define USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE 0x00ff 145#define USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE 0x00ff
144#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
145 148
146#define USB_VENDOR_ID_CHERRY 0x046a 149#define USB_VENDOR_ID_CHERRY 0x046a
147#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 150#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
@@ -343,6 +346,7 @@
343#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 346#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
344#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 347#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110
345#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
346#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211 350#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211
347#define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215 351#define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215
348#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218 352#define USB_DEVICE_ID_LOGITECH_RUMBLEPAD2 0xc218
@@ -354,6 +358,7 @@
354#define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293 358#define USB_DEVICE_ID_LOGITECH_WINGMAN_FFG 0xc293
355#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295 359#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL 0xc295
356#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
357#define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a 362#define USB_DEVICE_ID_LOGITECH_ELITE_KBD 0xc30a
358#define USB_DEVICE_ID_S510_RECEIVER 0xc50c 363#define USB_DEVICE_ID_S510_RECEIVER 0xc50c
359#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517 364#define USB_DEVICE_ID_S510_RECEIVER_2 0xc517
@@ -466,6 +471,8 @@
466 471
467#define USB_VENDOR_ID_ROCCAT 0x1e7d 472#define USB_VENDOR_ID_ROCCAT 0x1e7d
468#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced 473#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced
474#define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24
475#define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6
469 476
470#define USB_VENDOR_ID_SAITEK 0x06a3 477#define USB_VENDOR_ID_SAITEK 0x06a3
471#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 478#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
@@ -485,6 +492,12 @@
485#define USB_VENDOR_ID_STANTUM 0x1f87 492#define USB_VENDOR_ID_STANTUM 0x1f87
486#define USB_DEVICE_ID_MTP 0x0002 493#define USB_DEVICE_ID_MTP 0x0002
487 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
488#define USB_VENDOR_ID_SUN 0x0430 501#define USB_VENDOR_ID_SUN 0x0430
489#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab 502#define USB_DEVICE_ID_RARITAN_KVM_DONGLE 0xcdab
490 503
@@ -514,8 +527,10 @@
514 527
515#define USB_VENDOR_ID_UCLOGIC 0x5543 528#define USB_VENDOR_ID_UCLOGIC 0x5543
516#define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042 529#define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042
517#define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003
518#define USB_DEVICE_ID_UCLOGIC_TABLET_KNA5 0x6001 530#define USB_DEVICE_ID_UCLOGIC_TABLET_KNA5 0x6001
531#define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003
532#define USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U 0x0004
533#define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005
519 534
520#define USB_VENDOR_ID_VERNIER 0x08f7 535#define USB_VENDOR_ID_VERNIER 0x08f7
521#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 536#define USB_DEVICE_ID_VERNIER_LABPRO 0x0001
@@ -527,6 +542,12 @@
527#define USB_VENDOR_ID_WACOM 0x056a 542#define USB_VENDOR_ID_WACOM 0x056a
528#define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81 543#define USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH 0x81
529 544
545#define USB_VENDOR_ID_WALTOP 0x172f
546#define USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH 0x0032
547#define USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH 0x0034
548#define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH 0x0501
549#define USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH 0x0500
550
530#define USB_VENDOR_ID_WISEGROUP 0x0925 551#define USB_VENDOR_ID_WISEGROUP 0x0925
531#define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005 552#define USB_DEVICE_ID_SMARTJOY_PLUS 0x0005
532#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101 553#define USB_DEVICE_ID_1_PHIDGETSERVO_20 0x8101
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 6c03dcc5760a..834ef47b76d6 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 */
167static __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
152static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, 229static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field,
153 struct hid_usage *usage) 230 struct hid_usage *usage)
154{ 231{
@@ -336,6 +413,10 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
336 map_key_clear(BTN_STYLUS); 413 map_key_clear(BTN_STYLUS);
337 break; 414 break;
338 415
416 case 0x46: /* TabletPick */
417 map_key_clear(BTN_STYLUS2);
418 break;
419
339 default: goto unknown; 420 default: goto unknown;
340 } 421 }
341 break; 422 break;
@@ -537,6 +618,9 @@ mapped:
537 input_set_abs_params(input, usage->code, a, b, (b - a) >> 8, (b - a) >> 4); 618 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); 619 else input_set_abs_params(input, usage->code, a, b, 0, 0);
539 620
621 input_abs_set_res(input, usage->code,
622 hidinput_calc_abs_res(field, usage->code));
623
540 /* use a larger default input buffer for MT devices */ 624 /* use a larger default input buffer for MT devices */
541 if (usage->code == ABS_MT_POSITION_X && input->hint_events_per_packet == 0) 625 if (usage->code == ABS_MT_POSITION_X && input->hint_events_per_packet == 0)
542 input_set_events_per_packet(input, 60); 626 input_set_events_per_packet(input, 60);
@@ -659,6 +743,9 @@ void hidinput_report_event(struct hid_device *hid, struct hid_report *report)
659{ 743{
660 struct hid_input *hidinput; 744 struct hid_input *hidinput;
661 745
746 if (hid->quirks & HID_QUIRK_NO_INPUT_SYNC)
747 return;
748
662 list_for_each_entry(hidinput, &hid->inputs, list) 749 list_for_each_entry(hidinput, &hid->inputs, list)
663 input_sync(hidinput->input); 750 input_sync(hidinput->input);
664} 751}
diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c
index f8871712b7b5..817247ee006c 100644
--- a/drivers/hid/hid-kye.c
+++ b/drivers/hid/hid-kye.c
@@ -23,10 +23,10 @@
23 * - report size 8 count 1 must be size 1 count 8 for button bitfield 23 * - report size 8 count 1 must be size 1 count 8 for button bitfield
24 * - change the button usage range to 4-7 for the extra buttons 24 * - change the button usage range to 4-7 for the extra buttons
25 */ 25 */
26static void kye_report_fixup(struct hid_device *hdev, __u8 *rdesc, 26static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
27 unsigned int rsize) 27 unsigned int *rsize)
28{ 28{
29 if (rsize >= 74 && 29 if (*rsize >= 74 &&
30 rdesc[61] == 0x05 && rdesc[62] == 0x08 && 30 rdesc[61] == 0x05 && rdesc[62] == 0x08 &&
31 rdesc[63] == 0x19 && rdesc[64] == 0x08 && 31 rdesc[63] == 0x19 && rdesc[64] == 0x08 &&
32 rdesc[65] == 0x29 && rdesc[66] == 0x0f && 32 rdesc[65] == 0x29 && rdesc[66] == 0x0f &&
@@ -40,6 +40,7 @@ static void kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
40 rdesc[72] = 0x01; 40 rdesc[72] = 0x01;
41 rdesc[74] = 0x08; 41 rdesc[74] = 0x08;
42 } 42 }
43 return rdesc;
43} 44}
44 45
45static const struct hid_device_id kye_devices[] = { 46static const struct hid_device_id kye_devices[] = {
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index f6433d8050a9..b629fba5a057 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,31 +39,43 @@
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
41 * above the logical maximum described in descriptor. This extends 46 * above the logical maximum described in descriptor. This extends
42 * the original value of 0x28c of logical maximum to 0x104d 47 * the original value of 0x28c of logical maximum to 0x104d
43 */ 48 */
44static void lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, 49static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
45 unsigned int rsize) 50 unsigned int *rsize)
46{ 51{
47 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); 52 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
48 53
49 if ((quirks & LG_RDESC) && rsize >= 90 && rdesc[83] == 0x26 && 54 if ((quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 &&
50 rdesc[84] == 0x8c && rdesc[85] == 0x02) { 55 rdesc[84] == 0x8c && rdesc[85] == 0x02) {
51 dev_info(&hdev->dev, "fixing up Logitech keyboard report " 56 dev_info(&hdev->dev, "fixing up Logitech keyboard report "
52 "descriptor\n"); 57 "descriptor\n");
53 rdesc[84] = rdesc[89] = 0x4d; 58 rdesc[84] = rdesc[89] = 0x4d;
54 rdesc[85] = rdesc[90] = 0x10; 59 rdesc[85] = rdesc[90] = 0x10;
55 } 60 }
56 if ((quirks & LG_RDESC_REL_ABS) && rsize >= 50 && 61 if ((quirks & LG_RDESC_REL_ABS) && *rsize >= 50 &&
57 rdesc[32] == 0x81 && rdesc[33] == 0x06 && 62 rdesc[32] == 0x81 && rdesc[33] == 0x06 &&
58 rdesc[49] == 0x81 && rdesc[50] == 0x06) { 63 rdesc[49] == 0x81 && rdesc[50] == 0x06) {
59 dev_info(&hdev->dev, "fixing up rel/abs in Logitech " 64 dev_info(&hdev->dev, "fixing up rel/abs in Logitech "
60 "report descriptor\n"); 65 "report descriptor\n");
61 rdesc[33] = rdesc[50] = 0x02; 66 rdesc[33] = rdesc[50] = 0x02;
62 } 67 }
68 if ((quirks & LG_FF4) && *rsize >= 101 &&
69 rdesc[41] == 0x95 && rdesc[42] == 0x0B &&
70 rdesc[47] == 0x05 && rdesc[48] == 0x09) {
71 dev_info(&hdev->dev, "fixing up Logitech Speed Force Wireless "
72 "button descriptor\n");
73 rdesc[41] = 0x05;
74 rdesc[42] = 0x09;
75 rdesc[47] = 0x95;
76 rdesc[48] = 0x0B;
77 }
78 return rdesc;
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;
296err_free: 333err_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);
19static inline int lg3ff_init(struct hid_device *hdev) { return -1; } 19static inline int lg3ff_init(struct hid_device *hdev) { return -1; }
20#endif 20#endif
21 21
22#ifdef CONFIG_LOGIWII_FF
23int lg4ff_init(struct hid_device *hdev);
24#else
25static 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
33struct lg4ff_device {
34 struct hid_report *report;
35};
36
37static const signed short ff4_wheel_ac[] = {
38 FF_CONSTANT,
39 FF_AUTOCENTER,
40 -1
41};
42
43static 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
72static 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
91int 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;
53module_param(report_undeciphered, bool, 0644); 54module_param(report_undeciphered, bool, 0644);
54MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event"); 55MODULE_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
106static int magicmouse_firm_touch(struct magicmouse_sc *msc) 111static int magicmouse_firm_touch(struct magicmouse_sc *msc)
@@ -166,18 +171,35 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state)
166static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata) 171static 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
310static 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
317static 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
324static void magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev) 366static 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
427static 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
380static int magicmouse_probe(struct hid_device *hdev, 439static 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;
455err_input:
456 input_free_device(input);
457err_stop_hw: 504err_stop_hw:
458 hid_hw_stop(hdev); 505 hid_hw_stop(hdev);
459err_free: 506err_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
473static const struct hid_device_id magic_mice[] = { 519static 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};
478MODULE_DEVICE_TABLE(hid, magic_mice); 526MODULE_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
488static int __init magicmouse_init(void) 537static int __init magicmouse_init(void)
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 359cc447c6c6..dc618c33d0a2 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -33,18 +33,19 @@
33 * Microsoft Wireless Desktop Receiver (Model 1028) has 33 * Microsoft Wireless Desktop Receiver (Model 1028) has
34 * 'Usage Min/Max' where it ought to have 'Physical Min/Max' 34 * 'Usage Min/Max' where it ought to have 'Physical Min/Max'
35 */ 35 */
36static void ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, 36static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc,
37 unsigned int rsize) 37 unsigned int *rsize)
38{ 38{
39 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev); 39 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
40 40
41 if ((quirks & MS_RDESC) && rsize == 571 && rdesc[557] == 0x19 && 41 if ((quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 &&
42 rdesc[559] == 0x29) { 42 rdesc[559] == 0x29) {
43 dev_info(&hdev->dev, "fixing up Microsoft Wireless Receiver " 43 dev_info(&hdev->dev, "fixing up Microsoft Wireless Receiver "
44 "Model 1028 report descriptor\n"); 44 "Model 1028 report descriptor\n");
45 rdesc[557] = 0x35; 45 rdesc[557] = 0x35;
46 rdesc[559] = 0x45; 46 rdesc[559] = 0x45;
47 } 47 }
48 return rdesc;
48} 49}
49 50
50#define ms_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ 51#define ms_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
diff --git a/drivers/hid/hid-monterey.c b/drivers/hid/hid-monterey.c
index 2cd05aa244b9..c95c31e2d869 100644
--- a/drivers/hid/hid-monterey.c
+++ b/drivers/hid/hid-monterey.c
@@ -22,14 +22,15 @@
22 22
23#include "hid-ids.h" 23#include "hid-ids.h"
24 24
25static void mr_report_fixup(struct hid_device *hdev, __u8 *rdesc, 25static __u8 *mr_report_fixup(struct hid_device *hdev, __u8 *rdesc,
26 unsigned int rsize) 26 unsigned int *rsize)
27{ 27{
28 if (rsize >= 30 && rdesc[29] == 0x05 && rdesc[30] == 0x09) { 28 if (*rsize >= 30 && rdesc[29] == 0x05 && rdesc[30] == 0x09) {
29 dev_info(&hdev->dev, "fixing up button/consumer in HID report " 29 dev_info(&hdev->dev, "fixing up button/consumer in HID report "
30 "descriptor\n"); 30 "descriptor\n");
31 rdesc[30] = 0x0c; 31 rdesc[30] = 0x0c;
32 } 32 }
33 return rdesc;
33} 34}
34 35
35#define mr_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ 36#define mr_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
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 */
97static 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
113static 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
138err_free:
139 kfree(data);
140}
141
93static ssize_t show_phys_width(struct device *dev, 142static 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
379static int ntrig_input_mapping(struct hid_device *hdev, struct hid_input *hi, 428static 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
470static int ntrig_input_mapped(struct hid_device *hdev, struct hid_input *hi, 519static 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 */
491static int ntrig_event (struct hid_device *hid, struct hid_field *field, 540static 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:
860static void ntrig_remove(struct hid_device *hdev) 911static 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-ortek.c b/drivers/hid/hid-ortek.c
index aa9a960f73a4..2e79716dca31 100644
--- a/drivers/hid/hid-ortek.c
+++ b/drivers/hid/hid-ortek.c
@@ -19,14 +19,15 @@
19 19
20#include "hid-ids.h" 20#include "hid-ids.h"
21 21
22static void ortek_report_fixup(struct hid_device *hdev, __u8 *rdesc, 22static __u8 *ortek_report_fixup(struct hid_device *hdev, __u8 *rdesc,
23 unsigned int rsize) 23 unsigned int *rsize)
24{ 24{
25 if (rsize >= 56 && rdesc[54] == 0x25 && rdesc[55] == 0x01) { 25 if (*rsize >= 56 && rdesc[54] == 0x25 && rdesc[55] == 0x01) {
26 dev_info(&hdev->dev, "Fixing up Ortek WKB-2000 " 26 dev_info(&hdev->dev, "Fixing up Ortek WKB-2000 "
27 "report descriptor.\n"); 27 "report descriptor.\n");
28 rdesc[55] = 0x92; 28 rdesc[55] = 0x92;
29 } 29 }
30 return rdesc;
30} 31}
31 32
32static const struct hid_device_id ortek_devices[] = { 33static const struct hid_device_id ortek_devices[] = {
diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c
index 500fbd0652dc..308d6ae48a3e 100644
--- a/drivers/hid/hid-petalynx.c
+++ b/drivers/hid/hid-petalynx.c
@@ -23,10 +23,10 @@
23#include "hid-ids.h" 23#include "hid-ids.h"
24 24
25/* Petalynx Maxter Remote has maximum for consumer page set too low */ 25/* Petalynx Maxter Remote has maximum for consumer page set too low */
26static void pl_report_fixup(struct hid_device *hdev, __u8 *rdesc, 26static __u8 *pl_report_fixup(struct hid_device *hdev, __u8 *rdesc,
27 unsigned int rsize) 27 unsigned int *rsize)
28{ 28{
29 if (rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 && 29 if (*rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 &&
30 rdesc[41] == 0x00 && rdesc[59] == 0x26 && 30 rdesc[41] == 0x00 && rdesc[59] == 0x26 &&
31 rdesc[60] == 0xf9 && rdesc[61] == 0x00) { 31 rdesc[60] == 0xf9 && rdesc[61] == 0x00) {
32 dev_info(&hdev->dev, "fixing up Petalynx Maxter Remote report " 32 dev_info(&hdev->dev, "fixing up Petalynx Maxter Remote report "
@@ -34,6 +34,7 @@ static void pl_report_fixup(struct hid_device *hdev, __u8 *rdesc,
34 rdesc[60] = 0xfa; 34 rdesc[60] = 0xfa;
35 rdesc[40] = 0xfa; 35 rdesc[40] = 0xfa;
36 } 36 }
37 return rdesc;
37} 38}
38 39
39#define pl_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ 40#define pl_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c
index 845f428b8090..48eab84f53b5 100644
--- a/drivers/hid/hid-prodikeys.c
+++ b/drivers/hid/hid-prodikeys.c
@@ -740,10 +740,10 @@ int pcmidi_snd_terminate(struct pcmidi_snd *pm)
740/* 740/*
741 * PC-MIDI report descriptor for report id is wrong. 741 * PC-MIDI report descriptor for report id is wrong.
742 */ 742 */
743static void pk_report_fixup(struct hid_device *hdev, __u8 *rdesc, 743static __u8 *pk_report_fixup(struct hid_device *hdev, __u8 *rdesc,
744 unsigned int rsize) 744 unsigned int *rsize)
745{ 745{
746 if (rsize == 178 && 746 if (*rsize == 178 &&
747 rdesc[111] == 0x06 && rdesc[112] == 0x00 && 747 rdesc[111] == 0x06 && rdesc[112] == 0x00 &&
748 rdesc[113] == 0xff) { 748 rdesc[113] == 0xff) {
749 dev_info(&hdev->dev, "fixing up pc-midi keyboard report " 749 dev_info(&hdev->dev, "fixing up pc-midi keyboard report "
@@ -751,6 +751,7 @@ static void pk_report_fixup(struct hid_device *hdev, __u8 *rdesc,
751 751
752 rdesc[144] = 0x18; /* report 4: was 0x10 report count */ 752 rdesc[144] = 0x18; /* report 4: was 0x10 report count */
753 } 753 }
754 return rdesc;
754} 755}
755 756
756static int pk_input_mapping(struct hid_device *hdev, struct hid_input *hi, 757static int pk_input_mapping(struct hid_device *hdev, struct hid_input *hi,
diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c
new file mode 100644
index 000000000000..9bf23047892a
--- /dev/null
+++ b/drivers/hid/hid-roccat-pyra.c
@@ -0,0 +1,968 @@
1/*
2 * Roccat Pyra driver for Linux
3 *
4 * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 */
13
14/*
15 * Roccat Pyra is a mobile gamer mouse which comes in wired and wireless
16 * variant. Wireless variant is not tested.
17 * Userland tools can be found at http://sourceforge.net/projects/roccat
18 */
19
20#include <linux/device.h>
21#include <linux/input.h>
22#include <linux/hid.h>
23#include <linux/usb.h>
24#include <linux/module.h>
25#include <linux/slab.h>
26#include "hid-ids.h"
27#include "hid-roccat.h"
28#include "hid-roccat-pyra.h"
29
30static void profile_activated(struct pyra_device *pyra,
31 unsigned int new_profile)
32{
33 pyra->actual_profile = new_profile;
34 pyra->actual_cpi = pyra->profile_settings[pyra->actual_profile].y_cpi;
35}
36
37static int pyra_send_control(struct usb_device *usb_dev, int value,
38 enum pyra_control_requests request)
39{
40 int len;
41 struct pyra_control control;
42
43 if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS ||
44 request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) &&
45 (value < 0 || value > 4))
46 return -EINVAL;
47
48 control.command = PYRA_COMMAND_CONTROL;
49 control.value = value;
50 control.request = request;
51
52 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
53 USB_REQ_SET_CONFIGURATION,
54 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
55 PYRA_USB_COMMAND_CONTROL, 0, (char *)&control,
56 sizeof(struct pyra_control),
57 USB_CTRL_SET_TIMEOUT);
58
59 if (len != sizeof(struct pyra_control))
60 return len;
61
62 return 0;
63}
64
65static int pyra_receive_control_status(struct usb_device *usb_dev)
66{
67 int len;
68 struct pyra_control control;
69
70 do {
71 msleep(10);
72
73 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
74 USB_REQ_CLEAR_FEATURE,
75 USB_TYPE_CLASS | USB_RECIP_INTERFACE |
76 USB_DIR_IN,
77 PYRA_USB_COMMAND_CONTROL, 0, (char *)&control,
78 sizeof(struct pyra_control),
79 USB_CTRL_SET_TIMEOUT);
80
81 /* requested too early, try again */
82 } while (len == -EPROTO);
83
84 if (len == sizeof(struct pyra_control) &&
85 control.command == PYRA_COMMAND_CONTROL &&
86 control.request == PYRA_CONTROL_REQUEST_STATUS &&
87 control.value == 1)
88 return 0;
89 else {
90 dev_err(&usb_dev->dev, "receive control status: "
91 "unknown response 0x%x 0x%x\n",
92 control.request, control.value);
93 return -EINVAL;
94 }
95}
96
97static int pyra_get_profile_settings(struct usb_device *usb_dev,
98 struct pyra_profile_settings *buf, int number)
99{
100 int retval;
101
102 retval = pyra_send_control(usb_dev, number,
103 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS);
104
105 if (retval)
106 return retval;
107
108 retval = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
109 USB_REQ_CLEAR_FEATURE,
110 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
111 PYRA_USB_COMMAND_PROFILE_SETTINGS, 0, (char *)buf,
112 sizeof(struct pyra_profile_settings),
113 USB_CTRL_SET_TIMEOUT);
114
115 if (retval != sizeof(struct pyra_profile_settings))
116 return retval;
117
118 return 0;
119}
120
121static int pyra_get_profile_buttons(struct usb_device *usb_dev,
122 struct pyra_profile_buttons *buf, int number)
123{
124 int retval;
125
126 retval = pyra_send_control(usb_dev, number,
127 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS);
128
129 if (retval)
130 return retval;
131
132 retval = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
133 USB_REQ_CLEAR_FEATURE,
134 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
135 PYRA_USB_COMMAND_PROFILE_BUTTONS, 0, (char *)buf,
136 sizeof(struct pyra_profile_buttons),
137 USB_CTRL_SET_TIMEOUT);
138
139 if (retval != sizeof(struct pyra_profile_buttons))
140 return retval;
141
142 return 0;
143}
144
145static int pyra_get_settings(struct usb_device *usb_dev,
146 struct pyra_settings *buf)
147{
148 int len;
149 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
150 USB_REQ_CLEAR_FEATURE,
151 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
152 PYRA_USB_COMMAND_SETTINGS, 0, buf,
153 sizeof(struct pyra_settings), USB_CTRL_SET_TIMEOUT);
154 if (len != sizeof(struct pyra_settings))
155 return -EIO;
156 return 0;
157}
158
159static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf)
160{
161 int len;
162 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
163 USB_REQ_CLEAR_FEATURE,
164 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
165 PYRA_USB_COMMAND_INFO, 0, buf,
166 sizeof(struct pyra_info), USB_CTRL_SET_TIMEOUT);
167 if (len != sizeof(struct pyra_info))
168 return -EIO;
169 return 0;
170}
171
172static int pyra_set_profile_settings(struct usb_device *usb_dev,
173 struct pyra_profile_settings const *settings)
174{
175 int len;
176 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
177 USB_REQ_SET_CONFIGURATION,
178 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
179 PYRA_USB_COMMAND_PROFILE_SETTINGS, 0, (char *)settings,
180 sizeof(struct pyra_profile_settings),
181 USB_CTRL_SET_TIMEOUT);
182 if (len != sizeof(struct pyra_profile_settings))
183 return -EIO;
184 if (pyra_receive_control_status(usb_dev))
185 return -EIO;
186 return 0;
187}
188
189static int pyra_set_profile_buttons(struct usb_device *usb_dev,
190 struct pyra_profile_buttons const *buttons)
191{
192 int len;
193 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
194 USB_REQ_SET_CONFIGURATION,
195 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
196 PYRA_USB_COMMAND_PROFILE_BUTTONS, 0, (char *)buttons,
197 sizeof(struct pyra_profile_buttons),
198 USB_CTRL_SET_TIMEOUT);
199 if (len != sizeof(struct pyra_profile_buttons))
200 return -EIO;
201 if (pyra_receive_control_status(usb_dev))
202 return -EIO;
203 return 0;
204}
205
206static int pyra_set_settings(struct usb_device *usb_dev,
207 struct pyra_settings const *settings)
208{
209 int len;
210 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
211 USB_REQ_SET_CONFIGURATION,
212 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
213 PYRA_USB_COMMAND_SETTINGS, 0, (char *)settings,
214 sizeof(struct pyra_settings), USB_CTRL_SET_TIMEOUT);
215 if (len != sizeof(struct pyra_settings))
216 return -EIO;
217 if (pyra_receive_control_status(usb_dev))
218 return -EIO;
219 return 0;
220}
221
222static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp,
223 struct kobject *kobj, struct bin_attribute *attr, char *buf,
224 loff_t off, size_t count, int number)
225{
226 struct device *dev = container_of(kobj, struct device, kobj);
227 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
228
229 if (off >= sizeof(struct pyra_profile_settings))
230 return 0;
231
232 if (off + count > sizeof(struct pyra_profile_settings))
233 count = sizeof(struct pyra_profile_settings) - off;
234
235 mutex_lock(&pyra->pyra_lock);
236 memcpy(buf, ((char const *)&pyra->profile_settings[number]) + off,
237 count);
238 mutex_unlock(&pyra->pyra_lock);
239
240 return count;
241}
242
243static ssize_t pyra_sysfs_read_profile1_settings(struct file *fp,
244 struct kobject *kobj, struct bin_attribute *attr, char *buf,
245 loff_t off, size_t count)
246{
247 return pyra_sysfs_read_profilex_settings(fp, kobj,
248 attr, buf, off, count, 0);
249}
250
251static ssize_t pyra_sysfs_read_profile2_settings(struct file *fp,
252 struct kobject *kobj, struct bin_attribute *attr, char *buf,
253 loff_t off, size_t count)
254{
255 return pyra_sysfs_read_profilex_settings(fp, kobj,
256 attr, buf, off, count, 1);
257}
258
259static ssize_t pyra_sysfs_read_profile3_settings(struct file *fp,
260 struct kobject *kobj, struct bin_attribute *attr, char *buf,
261 loff_t off, size_t count)
262{
263 return pyra_sysfs_read_profilex_settings(fp, kobj,
264 attr, buf, off, count, 2);
265}
266
267static ssize_t pyra_sysfs_read_profile4_settings(struct file *fp,
268 struct kobject *kobj, struct bin_attribute *attr, char *buf,
269 loff_t off, size_t count)
270{
271 return pyra_sysfs_read_profilex_settings(fp, kobj,
272 attr, buf, off, count, 3);
273}
274
275static ssize_t pyra_sysfs_read_profile5_settings(struct file *fp,
276 struct kobject *kobj, struct bin_attribute *attr, char *buf,
277 loff_t off, size_t count)
278{
279 return pyra_sysfs_read_profilex_settings(fp, kobj,
280 attr, buf, off, count, 4);
281}
282
283static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp,
284 struct kobject *kobj, struct bin_attribute *attr, char *buf,
285 loff_t off, size_t count, int number)
286{
287 struct device *dev = container_of(kobj, struct device, kobj);
288 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
289
290 if (off >= sizeof(struct pyra_profile_buttons))
291 return 0;
292
293 if (off + count > sizeof(struct pyra_profile_buttons))
294 count = sizeof(struct pyra_profile_buttons) - off;
295
296 mutex_lock(&pyra->pyra_lock);
297 memcpy(buf, ((char const *)&pyra->profile_buttons[number]) + off,
298 count);
299 mutex_unlock(&pyra->pyra_lock);
300
301 return count;
302}
303
304static ssize_t pyra_sysfs_read_profile1_buttons(struct file *fp,
305 struct kobject *kobj, struct bin_attribute *attr, char *buf,
306 loff_t off, size_t count)
307{
308 return pyra_sysfs_read_profilex_buttons(fp, kobj,
309 attr, buf, off, count, 0);
310}
311
312static ssize_t pyra_sysfs_read_profile2_buttons(struct file *fp,
313 struct kobject *kobj, struct bin_attribute *attr, char *buf,
314 loff_t off, size_t count)
315{
316 return pyra_sysfs_read_profilex_buttons(fp, kobj,
317 attr, buf, off, count, 1);
318}
319
320static ssize_t pyra_sysfs_read_profile3_buttons(struct file *fp,
321 struct kobject *kobj, struct bin_attribute *attr, char *buf,
322 loff_t off, size_t count)
323{
324 return pyra_sysfs_read_profilex_buttons(fp, kobj,
325 attr, buf, off, count, 2);
326}
327
328static ssize_t pyra_sysfs_read_profile4_buttons(struct file *fp,
329 struct kobject *kobj, struct bin_attribute *attr, char *buf,
330 loff_t off, size_t count)
331{
332 return pyra_sysfs_read_profilex_buttons(fp, kobj,
333 attr, buf, off, count, 3);
334}
335
336static ssize_t pyra_sysfs_read_profile5_buttons(struct file *fp,
337 struct kobject *kobj, struct bin_attribute *attr, char *buf,
338 loff_t off, size_t count)
339{
340 return pyra_sysfs_read_profilex_buttons(fp, kobj,
341 attr, buf, off, count, 4);
342}
343
344static ssize_t pyra_sysfs_write_profile_settings(struct file *fp,
345 struct kobject *kobj, struct bin_attribute *attr, char *buf,
346 loff_t off, size_t count)
347{
348 struct device *dev = container_of(kobj, struct device, kobj);
349 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
350 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
351 int retval = 0;
352 int difference;
353 int profile_number;
354 struct pyra_profile_settings *profile_settings;
355
356 if (off != 0 || count != sizeof(struct pyra_profile_settings))
357 return -EINVAL;
358
359 profile_number = ((struct pyra_profile_settings const *)buf)->number;
360 profile_settings = &pyra->profile_settings[profile_number];
361
362 mutex_lock(&pyra->pyra_lock);
363 difference = memcmp(buf, profile_settings,
364 sizeof(struct pyra_profile_settings));
365 if (difference) {
366 retval = pyra_set_profile_settings(usb_dev,
367 (struct pyra_profile_settings const *)buf);
368 if (!retval)
369 memcpy(profile_settings, buf,
370 sizeof(struct pyra_profile_settings));
371 }
372 mutex_unlock(&pyra->pyra_lock);
373
374 if (retval)
375 return retval;
376
377 return sizeof(struct pyra_profile_settings);
378}
379
380static ssize_t pyra_sysfs_write_profile_buttons(struct file *fp,
381 struct kobject *kobj, struct bin_attribute *attr, char *buf,
382 loff_t off, size_t count)
383{
384 struct device *dev = container_of(kobj, struct device, kobj);
385 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
386 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
387 int retval = 0;
388 int difference;
389 int profile_number;
390 struct pyra_profile_buttons *profile_buttons;
391
392 if (off != 0 || count != sizeof(struct pyra_profile_buttons))
393 return -EINVAL;
394
395 profile_number = ((struct pyra_profile_buttons const *)buf)->number;
396 profile_buttons = &pyra->profile_buttons[profile_number];
397
398 mutex_lock(&pyra->pyra_lock);
399 difference = memcmp(buf, profile_buttons,
400 sizeof(struct pyra_profile_buttons));
401 if (difference) {
402 retval = pyra_set_profile_buttons(usb_dev,
403 (struct pyra_profile_buttons const *)buf);
404 if (!retval)
405 memcpy(profile_buttons, buf,
406 sizeof(struct pyra_profile_buttons));
407 }
408 mutex_unlock(&pyra->pyra_lock);
409
410 if (retval)
411 return retval;
412
413 return sizeof(struct pyra_profile_buttons);
414}
415
416static ssize_t pyra_sysfs_read_settings(struct file *fp,
417 struct kobject *kobj, struct bin_attribute *attr, char *buf,
418 loff_t off, size_t count)
419{
420 struct device *dev = container_of(kobj, struct device, kobj);
421 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
422
423 if (off >= sizeof(struct pyra_settings))
424 return 0;
425
426 if (off + count > sizeof(struct pyra_settings))
427 count = sizeof(struct pyra_settings) - off;
428
429 mutex_lock(&pyra->pyra_lock);
430 memcpy(buf, ((char const *)&pyra->settings) + off, count);
431 mutex_unlock(&pyra->pyra_lock);
432
433 return count;
434}
435
436static ssize_t pyra_sysfs_write_settings(struct file *fp,
437 struct kobject *kobj, struct bin_attribute *attr, char *buf,
438 loff_t off, size_t count)
439{
440 struct device *dev = container_of(kobj, struct device, kobj);
441 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
442 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
443 int retval = 0;
444 int difference;
445
446 if (off != 0 || count != sizeof(struct pyra_settings))
447 return -EINVAL;
448
449 mutex_lock(&pyra->pyra_lock);
450 difference = memcmp(buf, &pyra->settings, sizeof(struct pyra_settings));
451 if (difference) {
452 retval = pyra_set_settings(usb_dev,
453 (struct pyra_settings const *)buf);
454 if (!retval)
455 memcpy(&pyra->settings, buf,
456 sizeof(struct pyra_settings));
457 }
458 mutex_unlock(&pyra->pyra_lock);
459
460 if (retval)
461 return retval;
462
463 profile_activated(pyra, pyra->settings.startup_profile);
464
465 return sizeof(struct pyra_settings);
466}
467
468
469static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev,
470 struct device_attribute *attr, char *buf)
471{
472 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
473 return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_cpi);
474}
475
476static ssize_t pyra_sysfs_show_actual_profile(struct device *dev,
477 struct device_attribute *attr, char *buf)
478{
479 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
480 return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_profile);
481}
482
483static ssize_t pyra_sysfs_show_firmware_version(struct device *dev,
484 struct device_attribute *attr, char *buf)
485{
486 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
487 return snprintf(buf, PAGE_SIZE, "%d\n", pyra->firmware_version);
488}
489
490static ssize_t pyra_sysfs_show_startup_profile(struct device *dev,
491 struct device_attribute *attr, char *buf)
492{
493 struct pyra_device *pyra = hid_get_drvdata(dev_get_drvdata(dev));
494 return snprintf(buf, PAGE_SIZE, "%d\n", pyra->settings.startup_profile);
495}
496
497static DEVICE_ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL);
498
499static DEVICE_ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL);
500
501static DEVICE_ATTR(firmware_version, 0440,
502 pyra_sysfs_show_firmware_version, NULL);
503
504static DEVICE_ATTR(startup_profile, 0440,
505 pyra_sysfs_show_startup_profile, NULL);
506
507static struct attribute *pyra_attributes[] = {
508 &dev_attr_actual_cpi.attr,
509 &dev_attr_actual_profile.attr,
510 &dev_attr_firmware_version.attr,
511 &dev_attr_startup_profile.attr,
512 NULL
513};
514
515static struct attribute_group pyra_attribute_group = {
516 .attrs = pyra_attributes
517};
518
519static struct bin_attribute pyra_profile_settings_attr = {
520 .attr = { .name = "profile_settings", .mode = 0220 },
521 .size = sizeof(struct pyra_profile_settings),
522 .write = pyra_sysfs_write_profile_settings
523};
524
525static struct bin_attribute pyra_profile1_settings_attr = {
526 .attr = { .name = "profile1_settings", .mode = 0440 },
527 .size = sizeof(struct pyra_profile_settings),
528 .read = pyra_sysfs_read_profile1_settings
529};
530
531static struct bin_attribute pyra_profile2_settings_attr = {
532 .attr = { .name = "profile2_settings", .mode = 0440 },
533 .size = sizeof(struct pyra_profile_settings),
534 .read = pyra_sysfs_read_profile2_settings
535};
536
537static struct bin_attribute pyra_profile3_settings_attr = {
538 .attr = { .name = "profile3_settings", .mode = 0440 },
539 .size = sizeof(struct pyra_profile_settings),
540 .read = pyra_sysfs_read_profile3_settings
541};
542
543static struct bin_attribute pyra_profile4_settings_attr = {
544 .attr = { .name = "profile4_settings", .mode = 0440 },
545 .size = sizeof(struct pyra_profile_settings),
546 .read = pyra_sysfs_read_profile4_settings
547};
548
549static struct bin_attribute pyra_profile5_settings_attr = {
550 .attr = { .name = "profile5_settings", .mode = 0440 },
551 .size = sizeof(struct pyra_profile_settings),
552 .read = pyra_sysfs_read_profile5_settings
553};
554
555static struct bin_attribute pyra_profile_buttons_attr = {
556 .attr = { .name = "profile_buttons", .mode = 0220 },
557 .size = sizeof(struct pyra_profile_buttons),
558 .write = pyra_sysfs_write_profile_buttons
559};
560
561static struct bin_attribute pyra_profile1_buttons_attr = {
562 .attr = { .name = "profile1_buttons", .mode = 0440 },
563 .size = sizeof(struct pyra_profile_buttons),
564 .read = pyra_sysfs_read_profile1_buttons
565};
566
567static struct bin_attribute pyra_profile2_buttons_attr = {
568 .attr = { .name = "profile2_buttons", .mode = 0440 },
569 .size = sizeof(struct pyra_profile_buttons),
570 .read = pyra_sysfs_read_profile2_buttons
571};
572
573static struct bin_attribute pyra_profile3_buttons_attr = {
574 .attr = { .name = "profile3_buttons", .mode = 0440 },
575 .size = sizeof(struct pyra_profile_buttons),
576 .read = pyra_sysfs_read_profile3_buttons
577};
578
579static struct bin_attribute pyra_profile4_buttons_attr = {
580 .attr = { .name = "profile4_buttons", .mode = 0440 },
581 .size = sizeof(struct pyra_profile_buttons),
582 .read = pyra_sysfs_read_profile4_buttons
583};
584
585static struct bin_attribute pyra_profile5_buttons_attr = {
586 .attr = { .name = "profile5_buttons", .mode = 0440 },
587 .size = sizeof(struct pyra_profile_buttons),
588 .read = pyra_sysfs_read_profile5_buttons
589};
590
591static struct bin_attribute pyra_settings_attr = {
592 .attr = { .name = "settings", .mode = 0660 },
593 .size = sizeof(struct pyra_settings),
594 .read = pyra_sysfs_read_settings,
595 .write = pyra_sysfs_write_settings
596};
597
598static int pyra_create_sysfs_attributes(struct usb_interface *intf)
599{
600 int retval;
601
602 retval = sysfs_create_group(&intf->dev.kobj, &pyra_attribute_group);
603 if (retval)
604 goto exit_1;
605
606 retval = sysfs_create_bin_file(&intf->dev.kobj,
607 &pyra_profile_settings_attr);
608 if (retval)
609 goto exit_2;
610
611 retval = sysfs_create_bin_file(&intf->dev.kobj,
612 &pyra_profile1_settings_attr);
613 if (retval)
614 goto exit_3;
615
616 retval = sysfs_create_bin_file(&intf->dev.kobj,
617 &pyra_profile2_settings_attr);
618 if (retval)
619 goto exit_4;
620
621 retval = sysfs_create_bin_file(&intf->dev.kobj,
622 &pyra_profile3_settings_attr);
623 if (retval)
624 goto exit_5;
625
626 retval = sysfs_create_bin_file(&intf->dev.kobj,
627 &pyra_profile4_settings_attr);
628 if (retval)
629 goto exit_6;
630
631 retval = sysfs_create_bin_file(&intf->dev.kobj,
632 &pyra_profile5_settings_attr);
633 if (retval)
634 goto exit_7;
635
636 retval = sysfs_create_bin_file(&intf->dev.kobj,
637 &pyra_profile_buttons_attr);
638 if (retval)
639 goto exit_8;
640
641 retval = sysfs_create_bin_file(&intf->dev.kobj,
642 &pyra_profile1_buttons_attr);
643 if (retval)
644 goto exit_9;
645
646 retval = sysfs_create_bin_file(&intf->dev.kobj,
647 &pyra_profile2_buttons_attr);
648 if (retval)
649 goto exit_10;
650
651 retval = sysfs_create_bin_file(&intf->dev.kobj,
652 &pyra_profile3_buttons_attr);
653 if (retval)
654 goto exit_11;
655
656 retval = sysfs_create_bin_file(&intf->dev.kobj,
657 &pyra_profile4_buttons_attr);
658 if (retval)
659 goto exit_12;
660
661 retval = sysfs_create_bin_file(&intf->dev.kobj,
662 &pyra_profile5_buttons_attr);
663 if (retval)
664 goto exit_13;
665
666 retval = sysfs_create_bin_file(&intf->dev.kobj,
667 &pyra_settings_attr);
668 if (retval)
669 goto exit_14;
670
671 return 0;
672
673exit_14:
674 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_buttons_attr);
675exit_13:
676 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_buttons_attr);
677exit_12:
678 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_buttons_attr);
679exit_11:
680 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_buttons_attr);
681exit_10:
682 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_buttons_attr);
683exit_9:
684 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_buttons_attr);
685exit_8:
686 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_settings_attr);
687exit_7:
688 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_settings_attr);
689exit_6:
690 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_settings_attr);
691exit_5:
692 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_settings_attr);
693exit_4:
694 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_settings_attr);
695exit_3:
696 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_settings_attr);
697exit_2:
698 sysfs_remove_group(&intf->dev.kobj, &pyra_attribute_group);
699exit_1:
700 return retval;
701}
702
703static void pyra_remove_sysfs_attributes(struct usb_interface *intf)
704{
705 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_settings_attr);
706 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_buttons_attr);
707 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_buttons_attr);
708 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_buttons_attr);
709 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_buttons_attr);
710 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_buttons_attr);
711 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_buttons_attr);
712 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile5_settings_attr);
713 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile4_settings_attr);
714 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile3_settings_attr);
715 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile2_settings_attr);
716 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile1_settings_attr);
717 sysfs_remove_bin_file(&intf->dev.kobj, &pyra_profile_settings_attr);
718 sysfs_remove_group(&intf->dev.kobj, &pyra_attribute_group);
719}
720
721static int pyra_init_pyra_device_struct(struct usb_device *usb_dev,
722 struct pyra_device *pyra)
723{
724 struct pyra_info *info;
725 int retval, i;
726
727 mutex_init(&pyra->pyra_lock);
728
729 info = kmalloc(sizeof(struct pyra_info), GFP_KERNEL);
730 if (!info)
731 return -ENOMEM;
732 retval = pyra_get_info(usb_dev, info);
733 if (retval) {
734 kfree(info);
735 return retval;
736 }
737 pyra->firmware_version = info->firmware_version;
738 kfree(info);
739
740 retval = pyra_get_settings(usb_dev, &pyra->settings);
741 if (retval)
742 return retval;
743
744 for (i = 0; i < 5; ++i) {
745 retval = pyra_get_profile_settings(usb_dev,
746 &pyra->profile_settings[i], i);
747 if (retval)
748 return retval;
749
750 retval = pyra_get_profile_buttons(usb_dev,
751 &pyra->profile_buttons[i], i);
752 if (retval)
753 return retval;
754 }
755
756 profile_activated(pyra, pyra->settings.startup_profile);
757
758 return 0;
759}
760
761static int pyra_init_specials(struct hid_device *hdev)
762{
763 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
764 struct usb_device *usb_dev = interface_to_usbdev(intf);
765 struct pyra_device *pyra;
766 int retval;
767
768 if (intf->cur_altsetting->desc.bInterfaceProtocol
769 == USB_INTERFACE_PROTOCOL_MOUSE) {
770
771 pyra = kzalloc(sizeof(*pyra), GFP_KERNEL);
772 if (!pyra) {
773 dev_err(&hdev->dev, "can't alloc device descriptor\n");
774 return -ENOMEM;
775 }
776 hid_set_drvdata(hdev, pyra);
777
778 retval = pyra_init_pyra_device_struct(usb_dev, pyra);
779 if (retval) {
780 dev_err(&hdev->dev,
781 "couldn't init struct pyra_device\n");
782 goto exit_free;
783 }
784
785 retval = roccat_connect(hdev);
786 if (retval < 0) {
787 dev_err(&hdev->dev, "couldn't init char dev\n");
788 } else {
789 pyra->chrdev_minor = retval;
790 pyra->roccat_claimed = 1;
791 }
792
793 retval = pyra_create_sysfs_attributes(intf);
794 if (retval) {
795 dev_err(&hdev->dev, "cannot create sysfs files\n");
796 goto exit_free;
797 }
798 } else {
799 hid_set_drvdata(hdev, NULL);
800 }
801
802 return 0;
803exit_free:
804 kfree(pyra);
805 return retval;
806}
807
808static void pyra_remove_specials(struct hid_device *hdev)
809{
810 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
811 struct pyra_device *pyra;
812
813 if (intf->cur_altsetting->desc.bInterfaceProtocol
814 == USB_INTERFACE_PROTOCOL_MOUSE) {
815 pyra_remove_sysfs_attributes(intf);
816 pyra = hid_get_drvdata(hdev);
817 if (pyra->roccat_claimed)
818 roccat_disconnect(pyra->chrdev_minor);
819 kfree(hid_get_drvdata(hdev));
820 }
821}
822
823static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id)
824{
825 int retval;
826
827 retval = hid_parse(hdev);
828 if (retval) {
829 dev_err(&hdev->dev, "parse failed\n");
830 goto exit;
831 }
832
833 retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
834 if (retval) {
835 dev_err(&hdev->dev, "hw start failed\n");
836 goto exit;
837 }
838
839 retval = pyra_init_specials(hdev);
840 if (retval) {
841 dev_err(&hdev->dev, "couldn't install mouse\n");
842 goto exit_stop;
843 }
844 return 0;
845
846exit_stop:
847 hid_hw_stop(hdev);
848exit:
849 return retval;
850}
851
852static void pyra_remove(struct hid_device *hdev)
853{
854 pyra_remove_specials(hdev);
855 hid_hw_stop(hdev);
856}
857
858static void pyra_keep_values_up_to_date(struct pyra_device *pyra,
859 u8 const *data)
860{
861 struct pyra_mouse_event_button const *button_event;
862
863 switch (data[0]) {
864 case PYRA_MOUSE_REPORT_NUMBER_BUTTON:
865 button_event = (struct pyra_mouse_event_button const *)data;
866 switch (button_event->type) {
867 case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2:
868 profile_activated(pyra, button_event->data1 - 1);
869 break;
870 case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI:
871 pyra->actual_cpi = button_event->data1;
872 break;
873 }
874 break;
875 }
876}
877
878static void pyra_report_to_chrdev(struct pyra_device const *pyra,
879 u8 const *data)
880{
881 struct pyra_roccat_report roccat_report;
882 struct pyra_mouse_event_button const *button_event;
883
884 if (data[0] != PYRA_MOUSE_REPORT_NUMBER_BUTTON)
885 return;
886
887 button_event = (struct pyra_mouse_event_button const *)data;
888
889 switch (button_event->type) {
890 case PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2:
891 case PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI:
892 roccat_report.type = button_event->type;
893 roccat_report.value = button_event->data1;
894 roccat_report.key = 0;
895 roccat_report_event(pyra->chrdev_minor,
896 (uint8_t const *)&roccat_report,
897 sizeof(struct pyra_roccat_report));
898 break;
899 case PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO:
900 case PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT:
901 case PYRA_MOUSE_EVENT_BUTTON_TYPE_QUICKLAUNCH:
902 if (button_event->data2 == PYRA_MOUSE_EVENT_BUTTON_PRESS) {
903 roccat_report.type = button_event->type;
904 roccat_report.key = button_event->data1;
905 /*
906 * pyra reports profile numbers with range 1-5.
907 * Keeping this behaviour.
908 */
909 roccat_report.value = pyra->actual_profile + 1;
910 roccat_report_event(pyra->chrdev_minor,
911 (uint8_t const *)&roccat_report,
912 sizeof(struct pyra_roccat_report));
913 }
914 break;
915 }
916}
917
918static int pyra_raw_event(struct hid_device *hdev, struct hid_report *report,
919 u8 *data, int size)
920{
921 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
922 struct pyra_device *pyra = hid_get_drvdata(hdev);
923
924 if (intf->cur_altsetting->desc.bInterfaceProtocol
925 != USB_INTERFACE_PROTOCOL_MOUSE)
926 return 0;
927
928 pyra_keep_values_up_to_date(pyra, data);
929
930 if (pyra->roccat_claimed)
931 pyra_report_to_chrdev(pyra, data);
932
933 return 0;
934}
935
936static const struct hid_device_id pyra_devices[] = {
937 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT,
938 USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
939 /* TODO add USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS after testing */
940 { }
941};
942
943MODULE_DEVICE_TABLE(hid, pyra_devices);
944
945static struct hid_driver pyra_driver = {
946 .name = "pyra",
947 .id_table = pyra_devices,
948 .probe = pyra_probe,
949 .remove = pyra_remove,
950 .raw_event = pyra_raw_event
951};
952
953static int __init pyra_init(void)
954{
955 return hid_register_driver(&pyra_driver);
956}
957
958static void __exit pyra_exit(void)
959{
960 hid_unregister_driver(&pyra_driver);
961}
962
963module_init(pyra_init);
964module_exit(pyra_exit);
965
966MODULE_AUTHOR("Stefan Achatz");
967MODULE_DESCRIPTION("USB Roccat Pyra driver");
968MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-roccat-pyra.h b/drivers/hid/hid-roccat-pyra.h
new file mode 100644
index 000000000000..22f80a8f26f9
--- /dev/null
+++ b/drivers/hid/hid-roccat-pyra.h
@@ -0,0 +1,186 @@
1#ifndef __HID_ROCCAT_PYRA_H
2#define __HID_ROCCAT_PYRA_H
3
4/*
5 * Copyright (c) 2010 Stefan Achatz <erazor_de@users.sourceforge.net>
6 */
7
8/*
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 */
14
15#include <linux/types.h>
16
17#pragma pack(push)
18#pragma pack(1)
19
20struct pyra_b {
21 uint8_t command; /* PYRA_COMMAND_B */
22 uint8_t size; /* always 3 */
23 uint8_t unknown; /* 1 */
24};
25
26struct pyra_control {
27 uint8_t command; /* PYRA_COMMAND_CONTROL */
28 /*
29 * value is profile number for request_settings and request_buttons
30 * 1 if status ok for request_status
31 */
32 uint8_t value; /* Range 0-4 */
33 uint8_t request;
34};
35
36enum pyra_control_requests {
37 PYRA_CONTROL_REQUEST_STATUS = 0x00,
38 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10,
39 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20
40};
41
42struct pyra_settings {
43 uint8_t command; /* PYRA_COMMAND_SETTINGS */
44 uint8_t size; /* always 3 */
45 uint8_t startup_profile; /* Range 0-4! */
46};
47
48struct pyra_profile_settings {
49 uint8_t command; /* PYRA_COMMAND_PROFILE_SETTINGS */
50 uint8_t size; /* always 0xd */
51 uint8_t number; /* Range 0-4 */
52 uint8_t xysync;
53 uint8_t x_sensitivity; /* 0x1-0xa */
54 uint8_t y_sensitivity;
55 uint8_t x_cpi; /* unused */
56 uint8_t y_cpi; /* this value is for x and y */
57 uint8_t lightswitch; /* 0 = off, 1 = on */
58 uint8_t light_effect;
59 uint8_t handedness;
60 uint16_t checksum; /* byte sum */
61};
62
63struct pyra_profile_buttons {
64 uint8_t command; /* PYRA_COMMAND_PROFILE_BUTTONS */
65 uint8_t size; /* always 0x13 */
66 uint8_t number; /* Range 0-4 */
67 uint8_t buttons[14];
68 uint16_t checksum; /* byte sum */
69};
70
71struct pyra_info {
72 uint8_t command; /* PYRA_COMMAND_INFO */
73 uint8_t size; /* always 6 */
74 uint8_t firmware_version;
75 uint8_t unknown1; /* always 0 */
76 uint8_t unknown2; /* always 1 */
77 uint8_t unknown3; /* always 0 */
78};
79
80enum pyra_commands {
81 PYRA_COMMAND_CONTROL = 0x4,
82 PYRA_COMMAND_SETTINGS = 0x5,
83 PYRA_COMMAND_PROFILE_SETTINGS = 0x6,
84 PYRA_COMMAND_PROFILE_BUTTONS = 0x7,
85 PYRA_COMMAND_INFO = 0x9,
86 PYRA_COMMAND_B = 0xb
87};
88
89enum pyra_usb_commands {
90 PYRA_USB_COMMAND_CONTROL = 0x304,
91 PYRA_USB_COMMAND_SETTINGS = 0x305,
92 PYRA_USB_COMMAND_PROFILE_SETTINGS = 0x306,
93 PYRA_USB_COMMAND_PROFILE_BUTTONS = 0x307,
94 PYRA_USB_COMMAND_INFO = 0x309,
95 PYRA_USB_COMMAND_B = 0x30b /* writes 3 bytes */
96};
97
98enum pyra_mouse_report_numbers {
99 PYRA_MOUSE_REPORT_NUMBER_HID = 1,
100 PYRA_MOUSE_REPORT_NUMBER_AUDIO = 2,
101 PYRA_MOUSE_REPORT_NUMBER_BUTTON = 3,
102};
103
104struct pyra_mouse_event_button {
105 uint8_t report_number; /* always 3 */
106 uint8_t unknown; /* always 0 */
107 uint8_t type;
108 uint8_t data1;
109 uint8_t data2;
110};
111
112struct pyra_mouse_event_audio {
113 uint8_t report_number; /* always 2 */
114 uint8_t type;
115 uint8_t unused; /* always 0 */
116};
117
118/* hid audio controls */
119enum pyra_mouse_event_audio_types {
120 PYRA_MOUSE_EVENT_AUDIO_TYPE_MUTE = 0xe2,
121 PYRA_MOUSE_EVENT_AUDIO_TYPE_VOLUME_UP = 0xe9,
122 PYRA_MOUSE_EVENT_AUDIO_TYPE_VOLUME_DOWN = 0xea,
123};
124
125enum pyra_mouse_event_button_types {
126 /*
127 * Mouse sends tilt events on report_number 1 and 3
128 * Tilt events are sent repeatedly with 0.94s between first and second
129 * event and 0.22s on subsequent
130 */
131 PYRA_MOUSE_EVENT_BUTTON_TYPE_TILT = 0x10,
132
133 /*
134 * These are sent sequentially
135 * data1 contains new profile number in range 1-5
136 */
137 PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_1 = 0x20,
138 PYRA_MOUSE_EVENT_BUTTON_TYPE_PROFILE_2 = 0x30,
139
140 /*
141 * data1 = button_number (rmp index)
142 * data2 = pressed/released
143 */
144 PYRA_MOUSE_EVENT_BUTTON_TYPE_MACRO = 0x40,
145 PYRA_MOUSE_EVENT_BUTTON_TYPE_SHORTCUT = 0x50,
146
147 /*
148 * data1 = button_number (rmp index)
149 */
150 PYRA_MOUSE_EVENT_BUTTON_TYPE_QUICKLAUNCH = 0x60,
151
152 /* data1 = new cpi */
153 PYRA_MOUSE_EVENT_BUTTON_TYPE_CPI = 0xb0,
154
155 /* data1 and data2 = new sensitivity */
156 PYRA_MOUSE_EVENT_BUTTON_TYPE_SENSITIVITY = 0xc0,
157
158 PYRA_MOUSE_EVENT_BUTTON_TYPE_MULTIMEDIA = 0xf0,
159};
160
161enum {
162 PYRA_MOUSE_EVENT_BUTTON_PRESS = 0,
163 PYRA_MOUSE_EVENT_BUTTON_RELEASE = 1,
164};
165
166struct pyra_roccat_report {
167 uint8_t type;
168 uint8_t value;
169 uint8_t key;
170};
171
172#pragma pack(pop)
173
174struct pyra_device {
175 int actual_profile;
176 int actual_cpi;
177 int firmware_version;
178 int roccat_claimed;
179 int chrdev_minor;
180 struct mutex pyra_lock;
181 struct pyra_settings settings;
182 struct pyra_profile_settings profile_settings[5];
183 struct pyra_profile_buttons profile_buttons[5];
184};
185
186#endif
diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c
index bda0fd60c98d..35894444e000 100644
--- a/drivers/hid/hid-samsung.c
+++ b/drivers/hid/hid-samsung.c
@@ -61,10 +61,10 @@ static inline void samsung_irda_dev_trace(struct hid_device *hdev,
61 "descriptor\n", rsize); 61 "descriptor\n", rsize);
62} 62}
63 63
64static void samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc, 64static __u8 *samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc,
65 unsigned int rsize) 65 unsigned int *rsize)
66{ 66{
67 if (rsize == 184 && rdesc[175] == 0x25 && rdesc[176] == 0x40 && 67 if (*rsize == 184 && rdesc[175] == 0x25 && rdesc[176] == 0x40 &&
68 rdesc[177] == 0x75 && rdesc[178] == 0x30 && 68 rdesc[177] == 0x75 && rdesc[178] == 0x30 &&
69 rdesc[179] == 0x95 && rdesc[180] == 0x01 && 69 rdesc[179] == 0x95 && rdesc[180] == 0x01 &&
70 rdesc[182] == 0x40) { 70 rdesc[182] == 0x40) {
@@ -74,24 +74,25 @@ static void samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc,
74 rdesc[180] = 0x06; 74 rdesc[180] = 0x06;
75 rdesc[182] = 0x42; 75 rdesc[182] = 0x42;
76 } else 76 } else
77 if (rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 && 77 if (*rsize == 203 && rdesc[192] == 0x15 && rdesc[193] == 0x0 &&
78 rdesc[194] == 0x25 && rdesc[195] == 0x12) { 78 rdesc[194] == 0x25 && rdesc[195] == 0x12) {
79 samsung_irda_dev_trace(hdev, 203); 79 samsung_irda_dev_trace(hdev, 203);
80 rdesc[193] = 0x1; 80 rdesc[193] = 0x1;
81 rdesc[195] = 0xf; 81 rdesc[195] = 0xf;
82 } else 82 } else
83 if (rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 && 83 if (*rsize == 135 && rdesc[124] == 0x15 && rdesc[125] == 0x0 &&
84 rdesc[126] == 0x25 && rdesc[127] == 0x11) { 84 rdesc[126] == 0x25 && rdesc[127] == 0x11) {
85 samsung_irda_dev_trace(hdev, 135); 85 samsung_irda_dev_trace(hdev, 135);
86 rdesc[125] = 0x1; 86 rdesc[125] = 0x1;
87 rdesc[127] = 0xe; 87 rdesc[127] = 0xe;
88 } else 88 } else
89 if (rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 && 89 if (*rsize == 171 && rdesc[160] == 0x15 && rdesc[161] == 0x0 &&
90 rdesc[162] == 0x25 && rdesc[163] == 0x01) { 90 rdesc[162] == 0x25 && rdesc[163] == 0x01) {
91 samsung_irda_dev_trace(hdev, 171); 91 samsung_irda_dev_trace(hdev, 171);
92 rdesc[161] = 0x1; 92 rdesc[161] = 0x1;
93 rdesc[163] = 0x3; 93 rdesc[163] = 0x3;
94 } 94 }
95 return rdesc;
95} 96}
96 97
97#define samsung_kbd_mouse_map_key_clear(c) \ 98#define samsung_kbd_mouse_map_key_clear(c) \
@@ -130,11 +131,12 @@ static int samsung_kbd_mouse_input_mapping(struct hid_device *hdev,
130 return 1; 131 return 1;
131} 132}
132 133
133static void samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc, 134static __u8 *samsung_report_fixup(struct hid_device *hdev, __u8 *rdesc,
134 unsigned int rsize) 135 unsigned int *rsize)
135{ 136{
136 if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product) 137 if (USB_DEVICE_ID_SAMSUNG_IR_REMOTE == hdev->product)
137 samsung_irda_report_fixup(hdev, rdesc, rsize); 138 rdesc = samsung_irda_report_fixup(hdev, rdesc, rsize);
139 return rdesc;
138} 140}
139 141
140static int samsung_input_mapping(struct hid_device *hdev, struct hid_input *hi, 142static int samsung_input_mapping(struct hid_device *hdev, struct hid_input *hi,
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 402d5574b574..677bb3da10e8 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -24,24 +24,46 @@
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
29struct sony_sc { 31struct sony_sc {
30 unsigned long quirks; 32 unsigned long quirks;
31}; 33};
32 34
33/* Sony Vaio VGX has wrongly mouse pointer declared as constant */ 35/* Sony Vaio VGX has wrongly mouse pointer declared as constant */
34static void sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, 36static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
35 unsigned int rsize) 37 unsigned int *rsize)
36{ 38{
37 struct sony_sc *sc = hid_get_drvdata(hdev); 39 struct sony_sc *sc = hid_get_drvdata(hdev);
38 40
39 if ((sc->quirks & VAIO_RDESC_CONSTANT) && 41 if ((sc->quirks & VAIO_RDESC_CONSTANT) &&
40 rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) { 42 *rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) {
41 dev_info(&hdev->dev, "Fixing up Sony Vaio VGX report " 43 dev_info(&hdev->dev, "Fixing up Sony Vaio VGX report "
42 "descriptor\n"); 44 "descriptor\n");
43 rdesc[55] = 0x06; 45 rdesc[55] = 0x06;
44 } 46 }
47 return rdesc;
48}
49
50static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf,
51 size_t count, unsigned char report_type)
52{
53 struct usb_interface *intf = to_usb_interface(hid->dev.parent);
54 struct usb_device *dev = interface_to_usbdev(intf);
55 struct usb_host_interface *interface = intf->cur_altsetting;
56 int report_id = buf[0];
57 int ret;
58
59 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
60 HID_REQ_SET_REPORT,
61 USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
62 ((report_type + 1) << 8) | report_id,
63 interface->desc.bInterfaceNumber, buf, count,
64 USB_CTRL_SET_TIMEOUT);
65
66 return ret;
45} 67}
46 68
47/* 69/*
@@ -49,7 +71,7 @@ static void sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
49 * to "operational". Without this, the ps3 controller will not report any 71 * to "operational". Without this, the ps3 controller will not report any
50 * events. 72 * events.
51 */ 73 */
52static int sony_set_operational_usb(struct hid_device *hdev) 74static int sixaxis_set_operational_usb(struct hid_device *hdev)
53{ 75{
54 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 76 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
55 struct usb_device *dev = interface_to_usbdev(intf); 77 struct usb_device *dev = interface_to_usbdev(intf);
@@ -74,7 +96,7 @@ static int sony_set_operational_usb(struct hid_device *hdev)
74 return ret; 96 return ret;
75} 97}
76 98
77static int sony_set_operational_bt(struct hid_device *hdev) 99static int sixaxis_set_operational_bt(struct hid_device *hdev)
78{ 100{
79 unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 }; 101 unsigned char buf[] = { 0xf4, 0x42, 0x03, 0x00, 0x00 };
80 return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT); 102 return hdev->hid_output_raw_report(hdev, buf, sizeof(buf), HID_FEATURE_REPORT);
@@ -108,16 +130,14 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
108 goto err_free; 130 goto err_free;
109 } 131 }
110 132
111 switch (hdev->bus) { 133 if (sc->quirks & SIXAXIS_CONTROLLER_USB) {
112 case BUS_USB: 134 hdev->hid_output_raw_report = sixaxis_usb_output_raw_report;
113 ret = sony_set_operational_usb(hdev); 135 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 } 136 }
137 else if (sc->quirks & SIXAXIS_CONTROLLER_BT)
138 ret = sixaxis_set_operational_bt(hdev);
139 else
140 ret = 0;
121 141
122 if (ret < 0) 142 if (ret < 0)
123 goto err_stop; 143 goto err_stop;
@@ -137,8 +157,10 @@ static void sony_remove(struct hid_device *hdev)
137} 157}
138 158
139static const struct hid_device_id sony_devices[] = { 159static const struct hid_device_id sony_devices[] = {
140 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 160 { 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) }, 161 .driver_data = SIXAXIS_CONTROLLER_USB },
162 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
163 .driver_data = SIXAXIS_CONTROLLER_BT },
142 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE), 164 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
143 .driver_data = VAIO_RDESC_CONSTANT }, 165 .driver_data = VAIO_RDESC_CONSTANT },
144 { } 166 { }
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
250static const struct hid_device_id stantum_devices[] = { 250static 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};
254MODULE_DEVICE_TABLE(hid, stantum_devices); 256MODULE_DEVICE_TABLE(hid, stantum_devices);
diff --git a/drivers/hid/hid-sunplus.c b/drivers/hid/hid-sunplus.c
index 438107d9f1b2..164ed568f6cf 100644
--- a/drivers/hid/hid-sunplus.c
+++ b/drivers/hid/hid-sunplus.c
@@ -22,16 +22,17 @@
22 22
23#include "hid-ids.h" 23#include "hid-ids.h"
24 24
25static void sp_report_fixup(struct hid_device *hdev, __u8 *rdesc, 25static __u8 *sp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
26 unsigned int rsize) 26 unsigned int *rsize)
27{ 27{
28 if (rsize >= 107 && rdesc[104] == 0x26 && rdesc[105] == 0x80 && 28 if (*rsize >= 107 && rdesc[104] == 0x26 && rdesc[105] == 0x80 &&
29 rdesc[106] == 0x03) { 29 rdesc[106] == 0x03) {
30 dev_info(&hdev->dev, "fixing up Sunplus Wireless Desktop " 30 dev_info(&hdev->dev, "fixing up Sunplus Wireless Desktop "
31 "report descriptor\n"); 31 "report descriptor\n");
32 rdesc[105] = rdesc[110] = 0x03; 32 rdesc[105] = rdesc[110] = 0x03;
33 rdesc[106] = rdesc[111] = 0x21; 33 rdesc[106] = rdesc[111] = 0x21;
34 } 34 }
35 return rdesc;
35} 36}
36 37
37#define sp_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ 38#define sp_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \
diff --git a/drivers/hid/hid-uclogic.c b/drivers/hid/hid-uclogic.c
new file mode 100644
index 000000000000..05fdc85a76e5
--- /dev/null
+++ b/drivers/hid/hid-uclogic.c
@@ -0,0 +1,623 @@
1/*
2 * HID driver for UC-Logic devices not fully compliant with HID standard
3 *
4 * Copyright (c) 2010 Nikolai Kondrashov
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 */
13
14#include <linux/device.h>
15#include <linux/hid.h>
16#include <linux/module.h>
17
18#include "hid-ids.h"
19
20/*
21 * The original descriptors of WPXXXXU tablets have three report IDs, of
22 * which only two are used (8 and 9), and the remaining (7) seems to have
23 * the originally intended pen description which was abandoned for some
24 * reason. From this unused description it is possible to extract the
25 * actual physical extents and resolution. All the models use the same
26 * descriptor with different extents for the unused report ID.
27 *
28 * Here it is:
29 *
30 * Usage Page (Digitizer), ; Digitizer (0Dh)
31 * Usage (Pen), ; Pen (02h, application collection)
32 * Collection (Application),
33 * Report ID (7),
34 * Usage (Stylus), ; Stylus (20h, logical collection)
35 * Collection (Physical),
36 * Usage (Tip Switch), ; Tip switch (42h, momentary control)
37 * Usage (Barrel Switch), ; Barrel switch (44h, momentary control)
38 * Usage (Eraser), ; Eraser (45h, momentary control)
39 * Logical Minimum (0),
40 * Logical Maximum (1),
41 * Report Size (1),
42 * Report Count (3),
43 * Input (Variable),
44 * Report Count (3),
45 * Input (Constant, Variable),
46 * Usage (In Range), ; In range (32h, momentary control)
47 * Report Count (1),
48 * Input (Variable),
49 * Report Count (1),
50 * Input (Constant, Variable),
51 * Usage Page (Desktop), ; Generic desktop controls (01h)
52 * Usage (X), ; X (30h, dynamic value)
53 * Report Size (16),
54 * Report Count (1),
55 * Push,
56 * Unit Exponent (13),
57 * Unit (Inch^3),
58 * Physical Minimum (0),
59 * Physical Maximum (Xpm),
60 * Logical Maximum (Xlm),
61 * Input (Variable),
62 * Usage (Y), ; Y (31h, dynamic value)
63 * Physical Maximum (Ypm),
64 * Logical Maximum (Ylm),
65 * Input (Variable),
66 * Pop,
67 * Usage Page (Digitizer), ; Digitizer (0Dh)
68 * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value)
69 * Logical Maximum (1023),
70 * Input (Variable),
71 * Report Size (16),
72 * End Collection,
73 * End Collection,
74 * Usage Page (Desktop), ; Generic desktop controls (01h)
75 * Usage (Mouse), ; Mouse (02h, application collection)
76 * Collection (Application),
77 * Report ID (8),
78 * Usage (Pointer), ; Pointer (01h, physical collection)
79 * Collection (Physical),
80 * Usage Page (Button), ; Button (09h)
81 * Usage Minimum (01h),
82 * Usage Maximum (03h),
83 * Logical Minimum (0),
84 * Logical Maximum (1),
85 * Report Count (3),
86 * Report Size (1),
87 * Input (Variable),
88 * Report Count (5),
89 * Input (Constant),
90 * Usage Page (Desktop), ; Generic desktop controls (01h)
91 * Usage (X), ; X (30h, dynamic value)
92 * Usage (Y), ; Y (31h, dynamic value)
93 * Usage (Wheel), ; Wheel (38h, dynamic value)
94 * Usage (00h),
95 * Logical Minimum (-127),
96 * Logical Maximum (127),
97 * Report Size (8),
98 * Report Count (4),
99 * Input (Variable, Relative),
100 * End Collection,
101 * End Collection,
102 * Usage Page (Desktop), ; Generic desktop controls (01h)
103 * Usage (Mouse), ; Mouse (02h, application collection)
104 * Collection (Application),
105 * Report ID (9),
106 * Usage (Pointer), ; Pointer (01h, physical collection)
107 * Collection (Physical),
108 * Usage Page (Button), ; Button (09h)
109 * Usage Minimum (01h),
110 * Usage Maximum (03h),
111 * Logical Minimum (0),
112 * Logical Maximum (1),
113 * Report Count (3),
114 * Report Size (1),
115 * Input (Variable),
116 * Report Count (5),
117 * Input (Constant),
118 * Usage Page (Desktop), ; Generic desktop controls (01h)
119 * Usage (X), ; X (30h, dynamic value)
120 * Usage (Y), ; Y (31h, dynamic value)
121 * Logical Minimum (0),
122 * Logical Maximum (32767),
123 * Physical Minimum (0),
124 * Physical Maximum (32767),
125 * Report Count (2),
126 * Report Size (16),
127 * Input (Variable),
128 * Usage Page (Digitizer), ; Digitizer (0Dh)
129 * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value)
130 * Logical Maximum (1023),
131 * Report Count (1),
132 * Report Size (16),
133 * Input (Variable),
134 * End Collection,
135 * End Collection
136 *
137 * Here are the extents values for the WPXXXXU models:
138 *
139 * Xpm Xlm Ypm Ylm
140 * WP4030U 4000 8000 3000 6000
141 * WP5540U 5500 11000 4000 8000
142 * WP8060U 8000 16000 6000 12000
143 *
144 * This suggests that all of them have 2000 LPI resolution, as advertised.
145 */
146
147/* Size of the original descriptor of WPXXXXU tablets */
148#define WPXXXXU_RDESC_ORIG_SIZE 212
149
150/*
151 * Fixed WP4030U report descriptor.
152 * Although the hardware might actually support it, the mouse description
153 * has been removed, since there seems to be no devices having one and it
154 * wouldn't make much sense because of the working area size.
155 */
156static __u8 wp4030u_rdesc_fixed[] = {
157 0x05, 0x0D, /* Usage Page (Digitizer), */
158 0x09, 0x02, /* Usage (Pen), */
159 0xA1, 0x01, /* Collection (Application), */
160 0x85, 0x09, /* Report ID (9), */
161 0x09, 0x20, /* Usage (Stylus), */
162 0xA0, /* Collection (Physical), */
163 0x75, 0x01, /* Report Size (1), */
164 0x09, 0x42, /* Usage (Tip Switch), */
165 0x09, 0x44, /* Usage (Barrel Switch), */
166 0x09, 0x46, /* Usage (Tablet Pick), */
167 0x14, /* Logical Minimum (0), */
168 0x25, 0x01, /* Logical Maximum (1), */
169 0x95, 0x03, /* Report Count (3), */
170 0x81, 0x02, /* Input (Variable), */
171 0x95, 0x05, /* Report Count (5), */
172 0x81, 0x01, /* Input (Constant), */
173 0x75, 0x10, /* Report Size (16), */
174 0x95, 0x01, /* Report Count (1), */
175 0x14, /* Logical Minimum (0), */
176 0xA4, /* Push, */
177 0x05, 0x01, /* Usage Page (Desktop), */
178 0x55, 0xFD, /* Unit Exponent (-3), */
179 0x65, 0x13, /* Unit (Inch), */
180 0x34, /* Physical Minimum (0), */
181 0x09, 0x30, /* Usage (X), */
182 0x46, 0xA0, 0x0F, /* Physical Maximum (4000), */
183 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
184 0x81, 0x02, /* Input (Variable), */
185 0x09, 0x31, /* Usage (Y), */
186 0x46, 0xB8, 0x0B, /* Physical Maximum (3000), */
187 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
188 0x81, 0x02, /* Input (Variable), */
189 0xB4, /* Pop, */
190 0x09, 0x30, /* Usage (Tip Pressure), */
191 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
192 0x81, 0x02, /* Input (Variable), */
193 0xC0, /* End Collection, */
194 0xC0 /* End Collection */
195};
196
197/* Fixed WP5540U report descriptor */
198static __u8 wp5540u_rdesc_fixed[] = {
199 0x05, 0x0D, /* Usage Page (Digitizer), */
200 0x09, 0x02, /* Usage (Pen), */
201 0xA1, 0x01, /* Collection (Application), */
202 0x85, 0x09, /* Report ID (9), */
203 0x09, 0x20, /* Usage (Stylus), */
204 0xA0, /* Collection (Physical), */
205 0x75, 0x01, /* Report Size (1), */
206 0x09, 0x42, /* Usage (Tip Switch), */
207 0x09, 0x44, /* Usage (Barrel Switch), */
208 0x09, 0x46, /* Usage (Tablet Pick), */
209 0x14, /* Logical Minimum (0), */
210 0x25, 0x01, /* Logical Maximum (1), */
211 0x95, 0x03, /* Report Count (3), */
212 0x81, 0x02, /* Input (Variable), */
213 0x95, 0x05, /* Report Count (5), */
214 0x81, 0x01, /* Input (Constant), */
215 0x75, 0x10, /* Report Size (16), */
216 0x95, 0x01, /* Report Count (1), */
217 0x14, /* Logical Minimum (0), */
218 0xA4, /* Push, */
219 0x05, 0x01, /* Usage Page (Desktop), */
220 0x55, 0xFD, /* Unit Exponent (-3), */
221 0x65, 0x13, /* Unit (Inch), */
222 0x34, /* Physical Minimum (0), */
223 0x09, 0x30, /* Usage (X), */
224 0x46, 0x7C, 0x15, /* Physical Maximum (5500), */
225 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
226 0x81, 0x02, /* Input (Variable), */
227 0x09, 0x31, /* Usage (Y), */
228 0x46, 0xA0, 0x0F, /* Physical Maximum (4000), */
229 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
230 0x81, 0x02, /* Input (Variable), */
231 0xB4, /* Pop, */
232 0x09, 0x30, /* Usage (Tip Pressure), */
233 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
234 0x81, 0x02, /* Input (Variable), */
235 0xC0, /* End Collection, */
236 0xC0, /* End Collection, */
237 0x05, 0x01, /* Usage Page (Desktop), */
238 0x09, 0x02, /* Usage (Mouse), */
239 0xA1, 0x01, /* Collection (Application), */
240 0x85, 0x08, /* Report ID (8), */
241 0x09, 0x01, /* Usage (Pointer), */
242 0xA0, /* Collection (Physical), */
243 0x75, 0x01, /* Report Size (1), */
244 0x05, 0x09, /* Usage Page (Button), */
245 0x19, 0x01, /* Usage Minimum (01h), */
246 0x29, 0x03, /* Usage Maximum (03h), */
247 0x14, /* Logical Minimum (0), */
248 0x25, 0x01, /* Logical Maximum (1), */
249 0x95, 0x03, /* Report Count (3), */
250 0x81, 0x02, /* Input (Variable), */
251 0x95, 0x05, /* Report Count (5), */
252 0x81, 0x01, /* Input (Constant), */
253 0x05, 0x01, /* Usage Page (Desktop), */
254 0x75, 0x08, /* Report Size (8), */
255 0x09, 0x30, /* Usage (X), */
256 0x09, 0x31, /* Usage (Y), */
257 0x15, 0x81, /* Logical Minimum (-127), */
258 0x25, 0x7F, /* Logical Maximum (127), */
259 0x95, 0x02, /* Report Count (2), */
260 0x81, 0x06, /* Input (Variable, Relative), */
261 0x09, 0x38, /* Usage (Wheel), */
262 0x15, 0xFF, /* Logical Minimum (-1), */
263 0x25, 0x01, /* Logical Maximum (1), */
264 0x95, 0x01, /* Report Count (1), */
265 0x81, 0x06, /* Input (Variable, Relative), */
266 0x81, 0x01, /* Input (Constant), */
267 0xC0, /* End Collection, */
268 0xC0 /* End Collection */
269};
270
271/* Fixed WP8060U report descriptor */
272static __u8 wp8060u_rdesc_fixed[] = {
273 0x05, 0x0D, /* Usage Page (Digitizer), */
274 0x09, 0x02, /* Usage (Pen), */
275 0xA1, 0x01, /* Collection (Application), */
276 0x85, 0x09, /* Report ID (9), */
277 0x09, 0x20, /* Usage (Stylus), */
278 0xA0, /* Collection (Physical), */
279 0x75, 0x01, /* Report Size (1), */
280 0x09, 0x42, /* Usage (Tip Switch), */
281 0x09, 0x44, /* Usage (Barrel Switch), */
282 0x09, 0x46, /* Usage (Tablet Pick), */
283 0x14, /* Logical Minimum (0), */
284 0x25, 0x01, /* Logical Maximum (1), */
285 0x95, 0x03, /* Report Count (3), */
286 0x81, 0x02, /* Input (Variable), */
287 0x95, 0x05, /* Report Count (5), */
288 0x81, 0x01, /* Input (Constant), */
289 0x75, 0x10, /* Report Size (16), */
290 0x95, 0x01, /* Report Count (1), */
291 0x14, /* Logical Minimum (0), */
292 0xA4, /* Push, */
293 0x05, 0x01, /* Usage Page (Desktop), */
294 0x55, 0xFD, /* Unit Exponent (-3), */
295 0x65, 0x13, /* Unit (Inch), */
296 0x34, /* Physical Minimum (0), */
297 0x09, 0x30, /* Usage (X), */
298 0x46, 0x40, 0x1F, /* Physical Maximum (8000), */
299 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
300 0x81, 0x02, /* Input (Variable), */
301 0x09, 0x31, /* Usage (Y), */
302 0x46, 0x70, 0x17, /* Physical Maximum (6000), */
303 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
304 0x81, 0x02, /* Input (Variable), */
305 0xB4, /* Pop, */
306 0x09, 0x30, /* Usage (Tip Pressure), */
307 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
308 0x81, 0x02, /* Input (Variable), */
309 0xC0, /* End Collection, */
310 0xC0, /* End Collection, */
311 0x05, 0x01, /* Usage Page (Desktop), */
312 0x09, 0x02, /* Usage (Mouse), */
313 0xA1, 0x01, /* Collection (Application), */
314 0x85, 0x08, /* Report ID (8), */
315 0x09, 0x01, /* Usage (Pointer), */
316 0xA0, /* Collection (Physical), */
317 0x75, 0x01, /* Report Size (1), */
318 0x05, 0x09, /* Usage Page (Button), */
319 0x19, 0x01, /* Usage Minimum (01h), */
320 0x29, 0x03, /* Usage Maximum (03h), */
321 0x14, /* Logical Minimum (0), */
322 0x25, 0x01, /* Logical Maximum (1), */
323 0x95, 0x03, /* Report Count (3), */
324 0x81, 0x02, /* Input (Variable), */
325 0x95, 0x05, /* Report Count (5), */
326 0x81, 0x01, /* Input (Constant), */
327 0x05, 0x01, /* Usage Page (Desktop), */
328 0x75, 0x08, /* Report Size (8), */
329 0x09, 0x30, /* Usage (X), */
330 0x09, 0x31, /* Usage (Y), */
331 0x15, 0x81, /* Logical Minimum (-127), */
332 0x25, 0x7F, /* Logical Maximum (127), */
333 0x95, 0x02, /* Report Count (2), */
334 0x81, 0x06, /* Input (Variable, Relative), */
335 0x09, 0x38, /* Usage (Wheel), */
336 0x15, 0xFF, /* Logical Minimum (-1), */
337 0x25, 0x01, /* Logical Maximum (1), */
338 0x95, 0x01, /* Report Count (1), */
339 0x81, 0x06, /* Input (Variable, Relative), */
340 0x81, 0x01, /* Input (Constant), */
341 0xC0, /* End Collection, */
342 0xC0 /* End Collection */
343};
344
345/*
346 * Original PF1209 report descriptor.
347 *
348 * The descriptor is similar to WPXXXXU descriptors, with an addition of a
349 * feature report (ID 4) of unknown purpose.
350 *
351 * Although the advertised resolution is 4000 LPI the unused report ID
352 * (taken from WPXXXXU, it seems) states 2000 LPI, but it is probably
353 * incorrect and is a result of blind copying without understanding. Anyway
354 * the real logical extents are always scaled to 0..32767, which IMHO spoils
355 * the precision.
356 *
357 * Usage Page (Digitizer), ; Digitizer (0Dh)
358 * Usage (Pen), ; Pen (02h, application collection)
359 * Collection (Application),
360 * Report ID (7),
361 * Usage (Stylus), ; Stylus (20h, logical collection)
362 * Collection (Physical),
363 * Usage (Tip Switch), ; Tip switch (42h, momentary control)
364 * Usage (Barrel Switch), ; Barrel switch (44h, momentary control)
365 * Usage (Eraser), ; Eraser (45h, momentary control)
366 * Logical Minimum (0),
367 * Logical Maximum (1),
368 * Report Size (1),
369 * Report Count (3),
370 * Input (Variable),
371 * Report Count (3),
372 * Input (Constant, Variable),
373 * Usage (In Range), ; In range (32h, momentary control)
374 * Report Count (1),
375 * Input (Variable),
376 * Report Count (1),
377 * Input (Constant, Variable),
378 * Usage Page (Desktop), ; Generic desktop controls (01h)
379 * Usage (X), ; X (30h, dynamic value)
380 * Report Size (16),
381 * Report Count (1),
382 * Push,
383 * Unit Exponent (13),
384 * Unit (Inch^3),
385 * Physical Minimum (0),
386 * Physical Maximum (12000),
387 * Logical Maximum (24000),
388 * Input (Variable),
389 * Usage (Y), ; Y (31h, dynamic value)
390 * Physical Maximum (9000),
391 * Logical Maximum (18000),
392 * Input (Variable),
393 * Pop,
394 * Usage Page (Digitizer), ; Digitizer (0Dh)
395 * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value)
396 * Logical Maximum (1023),
397 * Input (Variable),
398 * Report Size (16),
399 * End Collection,
400 * End Collection,
401 * Usage Page (Desktop), ; Generic desktop controls (01h)
402 * Usage (Mouse), ; Mouse (02h, application collection)
403 * Collection (Application),
404 * Report ID (8),
405 * Usage (Pointer), ; Pointer (01h, physical collection)
406 * Collection (Physical),
407 * Usage Page (Button), ; Button (09h)
408 * Usage Minimum (01h),
409 * Usage Maximum (03h),
410 * Logical Minimum (0),
411 * Logical Maximum (1),
412 * Report Count (3),
413 * Report Size (1),
414 * Input (Variable),
415 * Report Count (5),
416 * Input (Constant),
417 * Usage Page (Desktop), ; Generic desktop controls (01h)
418 * Usage (X), ; X (30h, dynamic value)
419 * Usage (Y), ; Y (31h, dynamic value)
420 * Usage (Wheel), ; Wheel (38h, dynamic value)
421 * Usage (00h),
422 * Logical Minimum (-127),
423 * Logical Maximum (127),
424 * Report Size (8),
425 * Report Count (4),
426 * Input (Variable, Relative),
427 * End Collection,
428 * End Collection,
429 * Usage Page (Desktop), ; Generic desktop controls (01h)
430 * Usage (Mouse), ; Mouse (02h, application collection)
431 * Collection (Application),
432 * Report ID (9),
433 * Usage (Pointer), ; Pointer (01h, physical collection)
434 * Collection (Physical),
435 * Usage Page (Button), ; Button (09h)
436 * Usage Minimum (01h),
437 * Usage Maximum (03h),
438 * Logical Minimum (0),
439 * Logical Maximum (1),
440 * Report Count (3),
441 * Report Size (1),
442 * Input (Variable),
443 * Report Count (5),
444 * Input (Constant),
445 * Usage Page (Desktop), ; Generic desktop controls (01h)
446 * Usage (X), ; X (30h, dynamic value)
447 * Usage (Y), ; Y (31h, dynamic value)
448 * Logical Minimum (0),
449 * Logical Maximum (32767),
450 * Physical Minimum (0),
451 * Physical Maximum (32767),
452 * Report Count (2),
453 * Report Size (16),
454 * Input (Variable),
455 * Usage Page (Digitizer), ; Digitizer (0Dh)
456 * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value)
457 * Logical Maximum (1023),
458 * Report Count (1),
459 * Report Size (16),
460 * Input (Variable),
461 * End Collection,
462 * End Collection,
463 * Usage Page (Desktop), ; Generic desktop controls (01h)
464 * Usage (00h),
465 * Collection (Application),
466 * Report ID (4),
467 * Logical Minimum (0),
468 * Logical Maximum (255),
469 * Usage (00h),
470 * Report Size (8),
471 * Report Count (3),
472 * Feature (Variable),
473 * End Collection
474 */
475
476/* Size of the original descriptor of PF1209 tablet */
477#define PF1209_RDESC_ORIG_SIZE 234
478
479/*
480 * Fixed PF1209 report descriptor
481 *
482 * The descriptor is fixed similarly to WP5540U and WP8060U, plus the
483 * feature report is removed, because its purpose is unknown and it is of no
484 * use to the generic HID driver anyway for now.
485 */
486static __u8 pf1209_rdesc_fixed[] = {
487 0x05, 0x0D, /* Usage Page (Digitizer), */
488 0x09, 0x02, /* Usage (Pen), */
489 0xA1, 0x01, /* Collection (Application), */
490 0x85, 0x09, /* Report ID (9), */
491 0x09, 0x20, /* Usage (Stylus), */
492 0xA0, /* Collection (Physical), */
493 0x75, 0x01, /* Report Size (1), */
494 0x09, 0x42, /* Usage (Tip Switch), */
495 0x09, 0x44, /* Usage (Barrel Switch), */
496 0x09, 0x46, /* Usage (Tablet Pick), */
497 0x14, /* Logical Minimum (0), */
498 0x25, 0x01, /* Logical Maximum (1), */
499 0x95, 0x03, /* Report Count (3), */
500 0x81, 0x02, /* Input (Variable), */
501 0x95, 0x05, /* Report Count (5), */
502 0x81, 0x01, /* Input (Constant), */
503 0x75, 0x10, /* Report Size (16), */
504 0x95, 0x01, /* Report Count (1), */
505 0x14, /* Logical Minimum (0), */
506 0xA4, /* Push, */
507 0x05, 0x01, /* Usage Page (Desktop), */
508 0x55, 0xFD, /* Unit Exponent (-3), */
509 0x65, 0x13, /* Unit (Inch), */
510 0x34, /* Physical Minimum (0), */
511 0x09, 0x30, /* Usage (X), */
512 0x46, 0xE0, 0x2E, /* Physical Maximum (12000), */
513 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
514 0x81, 0x02, /* Input (Variable), */
515 0x09, 0x31, /* Usage (Y), */
516 0x46, 0x28, 0x23, /* Physical Maximum (9000), */
517 0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
518 0x81, 0x02, /* Input (Variable), */
519 0xB4, /* Pop, */
520 0x09, 0x30, /* Usage (Tip Pressure), */
521 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
522 0x81, 0x02, /* Input (Variable), */
523 0xC0, /* End Collection, */
524 0xC0, /* End Collection, */
525 0x05, 0x01, /* Usage Page (Desktop), */
526 0x09, 0x02, /* Usage (Mouse), */
527 0xA1, 0x01, /* Collection (Application), */
528 0x85, 0x08, /* Report ID (8), */
529 0x09, 0x01, /* Usage (Pointer), */
530 0xA0, /* Collection (Physical), */
531 0x75, 0x01, /* Report Size (1), */
532 0x05, 0x09, /* Usage Page (Button), */
533 0x19, 0x01, /* Usage Minimum (01h), */
534 0x29, 0x03, /* Usage Maximum (03h), */
535 0x14, /* Logical Minimum (0), */
536 0x25, 0x01, /* Logical Maximum (1), */
537 0x95, 0x03, /* Report Count (3), */
538 0x81, 0x02, /* Input (Variable), */
539 0x95, 0x05, /* Report Count (5), */
540 0x81, 0x01, /* Input (Constant), */
541 0x05, 0x01, /* Usage Page (Desktop), */
542 0x75, 0x08, /* Report Size (8), */
543 0x09, 0x30, /* Usage (X), */
544 0x09, 0x31, /* Usage (Y), */
545 0x15, 0x81, /* Logical Minimum (-127), */
546 0x25, 0x7F, /* Logical Maximum (127), */
547 0x95, 0x02, /* Report Count (2), */
548 0x81, 0x06, /* Input (Variable, Relative), */
549 0x09, 0x38, /* Usage (Wheel), */
550 0x15, 0xFF, /* Logical Minimum (-1), */
551 0x25, 0x01, /* Logical Maximum (1), */
552 0x95, 0x01, /* Report Count (1), */
553 0x81, 0x06, /* Input (Variable, Relative), */
554 0x81, 0x01, /* Input (Constant), */
555 0xC0, /* End Collection, */
556 0xC0 /* End Collection */
557};
558
559static __u8 *uclogic_report_fixup(struct hid_device *hdev, __u8 *rdesc,
560 unsigned int *rsize)
561{
562 switch (hdev->product) {
563 case USB_DEVICE_ID_UCLOGIC_TABLET_PF1209:
564 if (*rsize == PF1209_RDESC_ORIG_SIZE) {
565 rdesc = pf1209_rdesc_fixed;
566 *rsize = sizeof(pf1209_rdesc_fixed);
567 }
568 break;
569 case USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U:
570 if (*rsize == WPXXXXU_RDESC_ORIG_SIZE) {
571 rdesc = wp4030u_rdesc_fixed;
572 *rsize = sizeof(wp4030u_rdesc_fixed);
573 }
574 break;
575 case USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U:
576 if (*rsize == WPXXXXU_RDESC_ORIG_SIZE) {
577 rdesc = wp5540u_rdesc_fixed;
578 *rsize = sizeof(wp5540u_rdesc_fixed);
579 }
580 break;
581 case USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U:
582 if (*rsize == WPXXXXU_RDESC_ORIG_SIZE) {
583 rdesc = wp8060u_rdesc_fixed;
584 *rsize = sizeof(wp8060u_rdesc_fixed);
585 }
586 break;
587 }
588
589 return rdesc;
590}
591
592static const struct hid_device_id uclogic_devices[] = {
593 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
594 USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) },
595 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
596 USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) },
597 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
598 USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) },
599 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
600 USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) },
601 { }
602};
603MODULE_DEVICE_TABLE(hid, uclogic_devices);
604
605static struct hid_driver uclogic_driver = {
606 .name = "uclogic",
607 .id_table = uclogic_devices,
608 .report_fixup = uclogic_report_fixup,
609};
610
611static int __init uclogic_init(void)
612{
613 return hid_register_driver(&uclogic_driver);
614}
615
616static void __exit uclogic_exit(void)
617{
618 hid_unregister_driver(&uclogic_driver);
619}
620
621module_init(uclogic_init);
622module_exit(uclogic_exit);
623MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-waltop.c b/drivers/hid/hid-waltop.c
new file mode 100644
index 000000000000..b3a4163f2e67
--- /dev/null
+++ b/drivers/hid/hid-waltop.c
@@ -0,0 +1,1099 @@
1/*
2 * HID driver for Waltop devices not fully compliant with HID standard
3 *
4 * Copyright (c) 2010 Nikolai Kondrashov
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 */
13
14#include <linux/device.h>
15#include <linux/hid.h>
16#include <linux/module.h>
17
18#include "hid-ids.h"
19
20/*
21 * There exists an official driver on the manufacturer's website, which
22 * wasn't submitted to the kernel, for some reason. The official driver
23 * doesn't seem to support extra features of some tablets, like wheels.
24 *
25 * It shows that the feature report ID 2 could be used to control any waltop
26 * tablet input mode, switching it between "default", "tablet" and "ink".
27 *
28 * This driver only uses "default" mode for all the supported tablets. This
29 * mode tries to be HID-compatible (not very successfully), but cripples the
30 * resolution of some tablets.
31 *
32 * The "tablet" mode uses some proprietary, yet decipherable protocol, which
33 * represents the correct resolution, but is possibly HID-incompatible (i.e.
34 * indescribable by a report descriptor).
35 *
36 * The purpose of the "ink" mode is unknown.
37 *
38 * The feature reports needed for switching to each mode are these:
39 *
40 * 02 16 00 default
41 * 02 16 01 tablet
42 * 02 16 02 ink
43 */
44
45/*
46 * Original Slim Tablet 5.8 inch report descriptor.
47 *
48 * All the reports except the report with ID 16 (the stylus) are unused,
49 * possibly because the tablet is not configured to, or because they were
50 * just copied from a more capable model. The full purpose of features
51 * described for report ID 2 is unknown.
52 *
53 * The stylus buttons are described as three bit fields, whereas actually
54 * it's an "array", i.e. they're reported as button numbers (1, 2 and 3).
55 * The "eraser" field is not used. There is also a "push" without a "pop" in
56 * the stylus description.
57 *
58 * Usage Page (Desktop), ; Generic desktop controls (01h)
59 * Usage (Mouse), ; Mouse (02h, application collection)
60 * Collection (Application),
61 * Report ID (1),
62 * Usage (Pointer), ; Pointer (01h, physical collection)
63 * Collection (Physical),
64 * Usage Page (Button), ; Button (09h)
65 * Usage Minimum (01h),
66 * Usage Maximum (05h),
67 * Logical Minimum (0),
68 * Logical Maximum (1),
69 * Report Size (1),
70 * Report Count (5),
71 * Input (Variable),
72 * Report Size (3),
73 * Report Count (1),
74 * Input (Constant, Variable),
75 * Usage Page (Desktop), ; Generic desktop controls (01h)
76 * Usage (X), ; X (30h, dynamic value)
77 * Usage (Y), ; Y (31h, dynamic value)
78 * Usage (Wheel), ; Wheel (38h, dynamic value)
79 * Logical Minimum (-127),
80 * Logical Maximum (127),
81 * Report Size (8),
82 * Report Count (3),
83 * Input (Variable, Relative),
84 * End Collection,
85 * End Collection,
86 * Usage Page (Digitizer), ; Digitizer (0Dh)
87 * Usage (Pen), ; Pen (02h, application collection)
88 * Collection (Application),
89 * Report ID (2),
90 * Usage (Stylus), ; Stylus (20h, logical collection)
91 * Collection (Physical),
92 * Usage (00h),
93 * Logical Minimum (0),
94 * Logical Maximum (255),
95 * Report Size (8),
96 * Report Count (7),
97 * Input (Variable),
98 * Usage (Azimuth), ; Azimuth (3Fh, dynamic value)
99 * Usage (Altitude), ; Altitude (40h, dynamic value)
100 * Logical Minimum (0),
101 * Logical Maximum (255),
102 * Report Size (8),
103 * Report Count (2),
104 * Feature (Variable),
105 * End Collection,
106 * Report ID (5),
107 * Usage Page (Digitizer), ; Digitizer (0Dh)
108 * Usage (Stylus), ; Stylus (20h, logical collection)
109 * Collection (Physical),
110 * Usage (00h),
111 * Logical Minimum (0),
112 * Logical Maximum (255),
113 * Report Size (8),
114 * Report Count (7),
115 * Input (Variable),
116 * End Collection,
117 * Report ID (10),
118 * Usage Page (Digitizer), ; Digitizer (0Dh)
119 * Usage (Stylus), ; Stylus (20h, logical collection)
120 * Collection (Physical),
121 * Usage (00h),
122 * Logical Minimum (0),
123 * Logical Maximum (255),
124 * Report Size (8),
125 * Report Count (3),
126 * Input (Variable),
127 * End Collection,
128 * Report ID (16),
129 * Usage (Stylus), ; Stylus (20h, logical collection)
130 * Collection (Physical),
131 * Usage (Tip Switch), ; Tip switch (42h, momentary control)
132 * Usage (Barrel Switch), ; Barrel switch (44h, momentary control)
133 * Usage (Invert), ; Invert (3Ch, momentary control)
134 * Usage (Eraser), ; Eraser (45h, momentary control)
135 * Usage (In Range), ; In range (32h, momentary control)
136 * Logical Minimum (0),
137 * Logical Maximum (1),
138 * Report Size (1),
139 * Report Count (5),
140 * Input (Variable),
141 * Report Count (3),
142 * Input (Constant, Variable),
143 * Usage Page (Desktop), ; Generic desktop controls (01h)
144 * Usage (X), ; X (30h, dynamic value)
145 * Report Size (16),
146 * Report Count (1),
147 * Push,
148 * Unit Exponent (13),
149 * Unit (Inch^3),
150 * Logical Minimum (0),
151 * Logical Maximum (10000),
152 * Physical Minimum (0),
153 * Physical Maximum (10000),
154 * Input (Variable),
155 * Usage (Y), ; Y (31h, dynamic value)
156 * Logical Maximum (6000),
157 * Physical Maximum (6000),
158 * Input (Variable),
159 * Usage Page (Digitizer), ; Digitizer (0Dh)
160 * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value)
161 * Logical Minimum (0),
162 * Logical Maximum (1023),
163 * Physical Minimum (0),
164 * Physical Maximum (1023),
165 * Input (Variable),
166 * End Collection,
167 * End Collection
168 */
169
170/* Size of the original report descriptor of Slim Tablet 5.8 inch */
171#define SLIM_TABLET_5_8_INCH_RDESC_ORIG_SIZE 222
172
173/*
174 * Fixed Slim Tablet 5.8 inch descriptor.
175 *
176 * All the reports except the stylus report (ID 16) were removed as unused.
177 * The stylus buttons description was fixed.
178 */
179static __u8 slim_tablet_5_8_inch_rdesc_fixed[] = {
180 0x05, 0x0D, /* Usage Page (Digitizer), */
181 0x09, 0x02, /* Usage (Pen), */
182 0xA1, 0x01, /* Collection (Application), */
183 0x85, 0x10, /* Report ID (16), */
184 0x09, 0x20, /* Usage (Stylus), */
185 0xA0, /* Collection (Physical), */
186 0x09, 0x42, /* Usage (Tip Switch), */
187 0x09, 0x44, /* Usage (Barrel Switch), */
188 0x09, 0x46, /* Usage (Tablet Pick), */
189 0x15, 0x01, /* Logical Minimum (1), */
190 0x25, 0x03, /* Logical Maximum (3), */
191 0x75, 0x04, /* Report Size (4), */
192 0x95, 0x01, /* Report Count (1), */
193 0x80, /* Input, */
194 0x09, 0x32, /* Usage (In Range), */
195 0x14, /* Logical Minimum (0), */
196 0x25, 0x01, /* Logical Maximum (1), */
197 0x75, 0x01, /* Report Size (1), */
198 0x95, 0x01, /* Report Count (1), */
199 0x81, 0x02, /* Input (Variable), */
200 0x95, 0x03, /* Report Count (3), */
201 0x81, 0x03, /* Input (Constant, Variable), */
202 0x75, 0x10, /* Report Size (16), */
203 0x95, 0x01, /* Report Count (1), */
204 0x14, /* Logical Minimum (0), */
205 0xA4, /* Push, */
206 0x05, 0x01, /* Usage Page (Desktop), */
207 0x65, 0x13, /* Unit (Inch), */
208 0x55, 0xFD, /* Unit Exponent (-3), */
209 0x34, /* Physical Minimum (0), */
210 0x09, 0x30, /* Usage (X), */
211 0x46, 0x88, 0x13, /* Physical Maximum (5000), */
212 0x26, 0x10, 0x27, /* Logical Maximum (10000), */
213 0x81, 0x02, /* Input (Variable), */
214 0x09, 0x31, /* Usage (Y), */
215 0x46, 0xB8, 0x0B, /* Physical Maximum (3000), */
216 0x26, 0x70, 0x17, /* Logical Maximum (6000), */
217 0x81, 0x02, /* Input (Variable), */
218 0xB4, /* Pop, */
219 0x09, 0x30, /* Usage (Tip Pressure), */
220 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
221 0x81, 0x02, /* Input (Variable), */
222 0xC0, /* End Collection, */
223 0xC0 /* End Collection */
224};
225
226/*
227 * Original Slim Tablet 12.1 inch report descriptor.
228 *
229 * The descriptor is similar to the Slim Tablet 5.8 inch descriptor with the
230 * addition of a keyboard report, seemingly unused. It may have get here
231 * from a Media Tablet - probably an unimplemented feature.
232 *
233 * Usage Page (Desktop), ; Generic desktop controls (01h)
234 * Usage (Mouse), ; Mouse (02h, application collection)
235 * Collection (Application),
236 * Report ID (1),
237 * Usage (Pointer), ; Pointer (01h, physical collection)
238 * Collection (Physical),
239 * Usage Page (Button), ; Button (09h)
240 * Usage Minimum (01h),
241 * Usage Maximum (05h),
242 * Logical Minimum (0),
243 * Logical Maximum (1),
244 * Report Size (1),
245 * Report Count (5),
246 * Input (Variable),
247 * Report Size (3),
248 * Report Count (1),
249 * Input (Constant, Variable),
250 * Usage Page (Desktop), ; Generic desktop controls (01h)
251 * Usage (X), ; X (30h, dynamic value)
252 * Usage (Y), ; Y (31h, dynamic value)
253 * Usage (Wheel), ; Wheel (38h, dynamic value)
254 * Logical Minimum (-127),
255 * Logical Maximum (127),
256 * Report Size (8),
257 * Report Count (3),
258 * Input (Variable, Relative),
259 * End Collection,
260 * End Collection,
261 * Usage Page (Digitizer), ; Digitizer (0Dh)
262 * Usage (Pen), ; Pen (02h, application collection)
263 * Collection (Application),
264 * Report ID (2),
265 * Usage (Stylus), ; Stylus (20h, logical collection)
266 * Collection (Physical),
267 * Usage (00h),
268 * Logical Minimum (0),
269 * Logical Maximum (255),
270 * Report Size (8),
271 * Report Count (7),
272 * Input (Variable),
273 * Usage (Azimuth), ; Azimuth (3Fh, dynamic value)
274 * Usage (Altitude), ; Altitude (40h, dynamic value)
275 * Logical Minimum (0),
276 * Logical Maximum (255),
277 * Report Size (8),
278 * Report Count (2),
279 * Feature (Variable),
280 * End Collection,
281 * Report ID (5),
282 * Usage Page (Digitizer), ; Digitizer (0Dh)
283 * Usage (Stylus), ; Stylus (20h, logical collection)
284 * Collection (Physical),
285 * Usage (00h),
286 * Logical Minimum (0),
287 * Logical Maximum (255),
288 * Report Size (8),
289 * Report Count (7),
290 * Input (Variable),
291 * End Collection,
292 * Report ID (10),
293 * Usage Page (Digitizer), ; Digitizer (0Dh)
294 * Usage (Stylus), ; Stylus (20h, logical collection)
295 * Collection (Physical),
296 * Usage (00h),
297 * Logical Minimum (0),
298 * Logical Maximum (255),
299 * Report Size (8),
300 * Report Count (3),
301 * Input (Variable),
302 * End Collection,
303 * Report ID (16),
304 * Usage (Stylus), ; Stylus (20h, logical collection)
305 * Collection (Physical),
306 * Usage (Tip Switch), ; Tip switch (42h, momentary control)
307 * Usage (Barrel Switch), ; Barrel switch (44h, momentary control)
308 * Usage (Invert), ; Invert (3Ch, momentary control)
309 * Usage (Eraser), ; Eraser (45h, momentary control)
310 * Usage (In Range), ; In range (32h, momentary control)
311 * Logical Minimum (0),
312 * Logical Maximum (1),
313 * Report Size (1),
314 * Report Count (5),
315 * Input (Variable),
316 * Report Count (3),
317 * Input (Constant, Variable),
318 * Usage Page (Desktop), ; Generic desktop controls (01h)
319 * Usage (X), ; X (30h, dynamic value)
320 * Report Size (16),
321 * Report Count (1),
322 * Push,
323 * Unit Exponent (13),
324 * Unit (Inch^3),
325 * Logical Minimum (0),
326 * Logical Maximum (20000),
327 * Physical Minimum (0),
328 * Physical Maximum (20000),
329 * Input (Variable),
330 * Usage (Y), ; Y (31h, dynamic value)
331 * Logical Maximum (12500),
332 * Physical Maximum (12500),
333 * Input (Variable),
334 * Usage Page (Digitizer), ; Digitizer (0Dh)
335 * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value)
336 * Logical Minimum (0),
337 * Logical Maximum (1023),
338 * Physical Minimum (0),
339 * Physical Maximum (1023),
340 * Input (Variable),
341 * End Collection,
342 * End Collection,
343 * Usage Page (Desktop), ; Generic desktop controls (01h)
344 * Usage (Keyboard), ; Keyboard (06h, application collection)
345 * Collection (Application),
346 * Report ID (13),
347 * Usage Page (Keyboard), ; Keyboard/keypad (07h)
348 * Usage Minimum (KB Leftcontrol), ; Keyboard left control
349 * ; (E0h, dynamic value)
350 * Usage Maximum (KB Right GUI), ; Keyboard right GUI (E7h, dynamic value)
351 * Logical Minimum (0),
352 * Logical Maximum (1),
353 * Report Size (1),
354 * Report Count (8),
355 * Input (Variable),
356 * Report Size (8),
357 * Report Count (1),
358 * Input (Constant),
359 * Usage Page (Keyboard), ; Keyboard/keypad (07h)
360 * Usage Minimum (None), ; No event (00h, selector)
361 * Usage Maximum (KB Application), ; Keyboard Application (65h, selector)
362 * Logical Minimum (0),
363 * Logical Maximum (101),
364 * Report Size (8),
365 * Report Count (5),
366 * Input,
367 * End Collection
368 */
369
370/* Size of the original report descriptor of Slim Tablet 12.1 inch */
371#define SLIM_TABLET_12_1_INCH_RDESC_ORIG_SIZE 269
372
373/*
374 * Fixed Slim Tablet 12.1 inch descriptor.
375 *
376 * All the reports except the stylus report (ID 16) were removed as unused.
377 * The stylus buttons description was fixed.
378 */
379static __u8 slim_tablet_12_1_inch_rdesc_fixed[] = {
380 0x05, 0x0D, /* Usage Page (Digitizer), */
381 0x09, 0x02, /* Usage (Pen), */
382 0xA1, 0x01, /* Collection (Application), */
383 0x85, 0x10, /* Report ID (16), */
384 0x09, 0x20, /* Usage (Stylus), */
385 0xA0, /* Collection (Physical), */
386 0x09, 0x42, /* Usage (Tip Switch), */
387 0x09, 0x44, /* Usage (Barrel Switch), */
388 0x09, 0x46, /* Usage (Tablet Pick), */
389 0x15, 0x01, /* Logical Minimum (1), */
390 0x25, 0x03, /* Logical Maximum (3), */
391 0x75, 0x04, /* Report Size (4), */
392 0x95, 0x01, /* Report Count (1), */
393 0x80, /* Input, */
394 0x09, 0x32, /* Usage (In Range), */
395 0x14, /* Logical Minimum (0), */
396 0x25, 0x01, /* Logical Maximum (1), */
397 0x75, 0x01, /* Report Size (1), */
398 0x95, 0x01, /* Report Count (1), */
399 0x81, 0x02, /* Input (Variable), */
400 0x95, 0x03, /* Report Count (3), */
401 0x81, 0x03, /* Input (Constant, Variable), */
402 0x75, 0x10, /* Report Size (16), */
403 0x95, 0x01, /* Report Count (1), */
404 0x14, /* Logical Minimum (0), */
405 0xA4, /* Push, */
406 0x05, 0x01, /* Usage Page (Desktop), */
407 0x65, 0x13, /* Unit (Inch), */
408 0x55, 0xFD, /* Unit Exponent (-3), */
409 0x34, /* Physical Minimum (0), */
410 0x09, 0x30, /* Usage (X), */
411 0x46, 0x10, 0x27, /* Physical Maximum (10000), */
412 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */
413 0x81, 0x02, /* Input (Variable), */
414 0x09, 0x31, /* Usage (Y), */
415 0x46, 0x6A, 0x18, /* Physical Maximum (6250), */
416 0x26, 0xD4, 0x30, /* Logical Maximum (12500), */
417 0x81, 0x02, /* Input (Variable), */
418 0xB4, /* Pop, */
419 0x09, 0x30, /* Usage (Tip Pressure), */
420 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
421 0x81, 0x02, /* Input (Variable), */
422 0xC0, /* End Collection, */
423 0xC0 /* End Collection */
424};
425
426/*
427 * Original Media Tablet 10.6 inch report descriptor.
428 *
429 * There are at least two versions of this model in the wild. They are
430 * represented by Genius G-Pen M609 (older version) and Genius G-Pen M609X
431 * (newer version).
432 *
433 * Both versions have the usual pen with two barrel buttons and two
434 * identical wheels with center buttons in the top corners of the tablet
435 * base. They also have buttons on the top, between the wheels, for
436 * selecting the wheels' functions and wide/standard mode. In the wide mode
437 * the whole working surface is sensed, in the standard mode a narrower area
438 * is sensed, but the logical report extents remain the same. These modes
439 * correspond roughly to 16:9 and 4:3 aspect ratios respectively.
440 *
441 * The older version has three wheel function buttons ("scroll", "zoom" and
442 * "volume") and two separate buttons for wide and standard mode. The newer
443 * version has four wheel function buttons (plus "brush") and only one
444 * button is used for selecting wide/standard mode. So, the total number of
445 * buttons remains the same, but one of the mode buttons is repurposed as a
446 * wheels' function button in the newer version.
447 *
448 * The wheel functions are:
449 * scroll - the wheels act as scroll wheels, the center buttons switch
450 * between vertical and horizontal scrolling;
451 * zoom - the wheels zoom in/out, the buttons supposedly reset to 100%;
452 * volume - the wheels control the sound volume, the buttons mute;
453 * brush - the wheels are supposed to control brush width in a graphics
454 * editor, the buttons do nothing.
455 *
456 * Below is the newer version's report descriptor. It may very well be that
457 * the older version's descriptor is different and thus it won't be
458 * supported.
459 *
460 * The mouse report (ID 1) only uses the wheel field for reporting the tablet
461 * wheels' scroll mode. The keyboard report (ID 13) is used to report the
462 * wheels' zoom and brush control functions as key presses. The report ID 12
463 * is used to report the wheels' volume control functions. The stylus report
464 * (ID 16) has the same problems as the Slim Tablet 5.8 inch report has.
465 *
466 * The rest of the reports are unused, at least in the default configuration.
467 * The purpose of the features is unknown.
468 *
469 * Usage Page (Desktop),
470 * Usage (Mouse),
471 * Collection (Application),
472 * Report ID (1),
473 * Usage (Pointer),
474 * Collection (Physical),
475 * Usage Page (Button),
476 * Usage Minimum (01h),
477 * Usage Maximum (05h),
478 * Logical Minimum (0),
479 * Logical Maximum (1),
480 * Report Size (1),
481 * Report Count (5),
482 * Input (Variable),
483 * Report Size (3),
484 * Report Count (1),
485 * Input (Constant, Variable),
486 * Usage Page (Desktop),
487 * Usage (X),
488 * Usage (Y),
489 * Usage (Wheel),
490 * Logical Minimum (-127),
491 * Logical Maximum (127),
492 * Report Size (8),
493 * Report Count (3),
494 * Input (Variable, Relative),
495 * End Collection,
496 * End Collection,
497 * Usage Page (Digitizer),
498 * Usage (Pen),
499 * Collection (Application),
500 * Report ID (2),
501 * Usage (Stylus),
502 * Collection (Physical),
503 * Usage (00h),
504 * Logical Minimum (0),
505 * Logical Maximum (255),
506 * Report Size (8),
507 * Report Count (7),
508 * Input (Variable),
509 * Usage (Azimuth),
510 * Usage (Altitude),
511 * Logical Minimum (0),
512 * Logical Maximum (255),
513 * Report Size (8),
514 * Report Count (2),
515 * Feature (Variable),
516 * End Collection,
517 * Report ID (5),
518 * Usage Page (Digitizer),
519 * Usage (Stylus),
520 * Collection (Physical),
521 * Usage (00h),
522 * Logical Minimum (0),
523 * Logical Maximum (255),
524 * Report Size (8),
525 * Report Count (7),
526 * Input (Variable),
527 * End Collection,
528 * Report ID (10),
529 * Usage Page (Digitizer),
530 * Usage (Stylus),
531 * Collection (Physical),
532 * Usage (00h),
533 * Logical Minimum (0),
534 * Logical Maximum (255),
535 * Report Size (8),
536 * Report Count (7),
537 * Input (Variable),
538 * End Collection,
539 * Report ID (16),
540 * Usage (Stylus),
541 * Collection (Physical),
542 * Usage (Tip Switch),
543 * Usage (Barrel Switch),
544 * Usage (Invert),
545 * Usage (Eraser),
546 * Usage (In Range),
547 * Logical Minimum (0),
548 * Logical Maximum (1),
549 * Report Size (1),
550 * Report Count (5),
551 * Input (Variable),
552 * Report Count (3),
553 * Input (Constant, Variable),
554 * Usage Page (Desktop),
555 * Usage (X),
556 * Report Size (16),
557 * Report Count (1),
558 * Push,
559 * Unit Exponent (13),
560 * Unit (Inch^3),
561 * Logical Minimum (0),
562 * Logical Maximum (18000),
563 * Physical Minimum (0),
564 * Physical Maximum (18000),
565 * Input (Variable),
566 * Usage (Y),
567 * Logical Maximum (11000),
568 * Physical Maximum (11000),
569 * Input (Variable),
570 * Usage Page (Digitizer),
571 * Usage (Tip Pressure),
572 * Logical Minimum (0),
573 * Logical Maximum (1023),
574 * Physical Minimum (0),
575 * Physical Maximum (1023),
576 * Input (Variable),
577 * End Collection,
578 * End Collection,
579 * Usage Page (Desktop),
580 * Usage (Keyboard),
581 * Collection (Application),
582 * Report ID (13),
583 * Usage Page (Keyboard),
584 * Usage Minimum (KB Leftcontrol),
585 * Usage Maximum (KB Right GUI),
586 * Logical Minimum (0),
587 * Logical Maximum (1),
588 * Report Size (1),
589 * Report Count (8),
590 * Input (Variable),
591 * Report Size (8),
592 * Report Count (1),
593 * Input (Constant),
594 * Usage Page (Keyboard),
595 * Usage Minimum (None),
596 * Usage Maximum (KB Application),
597 * Logical Minimum (0),
598 * Logical Maximum (101),
599 * Report Size (8),
600 * Report Count (5),
601 * Input,
602 * End Collection,
603 * Usage Page (Consumer),
604 * Usage (Consumer Control),
605 * Collection (Application),
606 * Report ID (12),
607 * Usage (Volume Inc),
608 * Usage (Volume Dec),
609 * Usage (Mute),
610 * Logical Minimum (0),
611 * Logical Maximum (1),
612 * Report Size (1),
613 * Report Count (3),
614 * Input (Variable, Relative),
615 * Report Size (5),
616 * Report Count (1),
617 * Input (Constant, Variable, Relative),
618 * End Collection
619 */
620
621/* Size of the original report descriptor of Media Tablet 10.6 inch */
622#define MEDIA_TABLET_10_6_INCH_RDESC_ORIG_SIZE 300
623
624/*
625 * Fixed Media Tablet 10.6 inch descriptor.
626 *
627 * The descriptions of reports unused in the default configuration are
628 * removed. The stylus report (ID 16) is fixed similarly to Slim Tablet 5.8
629 * inch. The unused mouse report (ID 1) fields are replaced with constant
630 * padding.
631 *
632 * The keyboard report (ID 13) is hacked to instead have an "array" field
633 * reporting consumer page controls, and all the unused bits are masked out
634 * with constant padding. The "brush" wheels' function is represented as "Scan
635 * Previous/Next Track" controls due to the lack of brush controls in the
636 * usage tables specification.
637 */
638static __u8 media_tablet_10_6_inch_rdesc_fixed[] = {
639 0x05, 0x0D, /* Usage Page (Digitizer), */
640 0x09, 0x02, /* Usage (Pen), */
641 0xA1, 0x01, /* Collection (Application), */
642 0x85, 0x10, /* Report ID (16), */
643 0x09, 0x20, /* Usage (Stylus), */
644 0xA0, /* Collection (Physical), */
645 0x09, 0x42, /* Usage (Tip Switch), */
646 0x09, 0x44, /* Usage (Barrel Switch), */
647 0x09, 0x46, /* Usage (Tablet Pick), */
648 0x15, 0x01, /* Logical Minimum (1), */
649 0x25, 0x03, /* Logical Maximum (3), */
650 0x75, 0x04, /* Report Size (4), */
651 0x95, 0x01, /* Report Count (1), */
652 0x80, /* Input, */
653 0x75, 0x01, /* Report Size (1), */
654 0x09, 0x32, /* Usage (In Range), */
655 0x14, /* Logical Minimum (0), */
656 0x25, 0x01, /* Logical Maximum (1), */
657 0x95, 0x01, /* Report Count (1), */
658 0x81, 0x02, /* Input (Variable), */
659 0x95, 0x03, /* Report Count (3), */
660 0x81, 0x03, /* Input (Constant, Variable), */
661 0x75, 0x10, /* Report Size (16), */
662 0x95, 0x01, /* Report Count (1), */
663 0x14, /* Logical Minimum (0), */
664 0xA4, /* Push, */
665 0x05, 0x01, /* Usage Page (Desktop), */
666 0x65, 0x13, /* Unit (Inch), */
667 0x55, 0xFD, /* Unit Exponent (-3), */
668 0x34, /* Physical Minimum (0), */
669 0x09, 0x30, /* Usage (X), */
670 0x46, 0x28, 0x23, /* Physical Maximum (9000), */
671 0x26, 0x50, 0x46, /* Logical Maximum (18000), */
672 0x81, 0x02, /* Input (Variable), */
673 0x09, 0x31, /* Usage (Y), */
674 0x46, 0x7C, 0x15, /* Physical Maximum (5500), */
675 0x26, 0xF8, 0x2A, /* Logical Maximum (11000), */
676 0x81, 0x02, /* Input (Variable), */
677 0xB4, /* Pop, */
678 0x09, 0x30, /* Usage (Tip Pressure), */
679 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
680 0x81, 0x02, /* Input (Variable), */
681 0xC0, /* End Collection, */
682 0xC0, /* End Collection, */
683 0x05, 0x01, /* Usage Page (Desktop), */
684 0x09, 0x02, /* Usage (Mouse), */
685 0xA1, 0x01, /* Collection (Application), */
686 0x85, 0x01, /* Report ID (1), */
687 0x09, 0x01, /* Usage (Pointer), */
688 0xA0, /* Collection (Physical), */
689 0x75, 0x08, /* Report Size (8), */
690 0x95, 0x03, /* Report Count (3), */
691 0x81, 0x03, /* Input (Constant, Variable), */
692 0x95, 0x02, /* Report Count (2), */
693 0x15, 0xFF, /* Logical Minimum (-1), */
694 0x25, 0x01, /* Logical Maximum (1), */
695 0x09, 0x38, /* Usage (Wheel), */
696 0x0B, 0x38, 0x02, /* Usage (Consumer AC Pan), */
697 0x0C, 0x00,
698 0x81, 0x06, /* Input (Variable, Relative), */
699 0x95, 0x02, /* Report Count (2), */
700 0x81, 0x03, /* Input (Constant, Variable), */
701 0xC0, /* End Collection, */
702 0xC0, /* End Collection, */
703 0x05, 0x0C, /* Usage Page (Consumer), */
704 0x09, 0x01, /* Usage (Consumer Control), */
705 0xA1, 0x01, /* Collection (Application), */
706 0x85, 0x0D, /* Report ID (13), */
707 0x95, 0x01, /* Report Count (1), */
708 0x75, 0x10, /* Report Size (16), */
709 0x81, 0x03, /* Input (Constant, Variable), */
710 0x0A, 0x2F, 0x02, /* Usage (AC Zoom), */
711 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */
712 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */
713 0x09, 0xB6, /* Usage (Scan Previous Track), */
714 0x09, 0xB5, /* Usage (Scan Next Track), */
715 0x08, /* Usage (00h), */
716 0x08, /* Usage (00h), */
717 0x08, /* Usage (00h), */
718 0x08, /* Usage (00h), */
719 0x08, /* Usage (00h), */
720 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */
721 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */
722 0x15, 0x0C, /* Logical Minimum (12), */
723 0x25, 0x17, /* Logical Maximum (23), */
724 0x75, 0x05, /* Report Size (5), */
725 0x80, /* Input, */
726 0x75, 0x03, /* Report Size (3), */
727 0x81, 0x03, /* Input (Constant, Variable), */
728 0x75, 0x20, /* Report Size (32), */
729 0x81, 0x03, /* Input (Constant, Variable), */
730 0xC0, /* End Collection, */
731 0x09, 0x01, /* Usage (Consumer Control), */
732 0xA1, 0x01, /* Collection (Application), */
733 0x85, 0x0C, /* Report ID (12), */
734 0x75, 0x01, /* Report Size (1), */
735 0x09, 0xE9, /* Usage (Volume Inc), */
736 0x09, 0xEA, /* Usage (Volume Dec), */
737 0x09, 0xE2, /* Usage (Mute), */
738 0x14, /* Logical Minimum (0), */
739 0x25, 0x01, /* Logical Maximum (1), */
740 0x95, 0x03, /* Report Count (3), */
741 0x81, 0x06, /* Input (Variable, Relative), */
742 0x95, 0x35, /* Report Count (53), */
743 0x81, 0x03, /* Input (Constant, Variable), */
744 0xC0 /* End Collection */
745};
746
747/*
748 * Original Media Tablet 14.1 inch report descriptor.
749 *
750 * There are at least two versions of this model in the wild. They are
751 * represented by Genius G-Pen M712 (older version) and Genius G-Pen M712X
752 * (newer version). The hardware difference between these versions is the same
753 * as between older and newer versions of Media Tablet 10.6 inch. The report
754 * descriptors are identical for both versions.
755 *
756 * The function, behavior and report descriptor of this tablet is similar to
757 * that of Media Tablet 10.6 inch. However, there is one more field (with
758 * Consumer AC Pan usage) in the mouse description. Then the tablet X and Y
759 * logical extents both get scaled to 0..16383 range (a hardware limit?),
760 * which kind of defeats the advertised 4000 LPI resolution, considering the
761 * physical extents of 12x7.25 inches. Plus, reports 5, 10 and 255 are used
762 * sometimes (while moving the pen) with unknown purpose. Also, the key codes
763 * generated for zoom in/out are different.
764 *
765 * Usage Page (Desktop),
766 * Usage (Mouse),
767 * Collection (Application),
768 * Report ID (1),
769 * Usage (Pointer),
770 * Collection (Physical),
771 * Usage Page (Button),
772 * Usage Minimum (01h),
773 * Usage Maximum (05h),
774 * Logical Minimum (0),
775 * Logical Maximum (1),
776 * Report Size (1),
777 * Report Count (5),
778 * Input (Variable),
779 * Report Size (3),
780 * Report Count (1),
781 * Input (Constant, Variable),
782 * Usage Page (Desktop),
783 * Usage (X),
784 * Usage (Y),
785 * Usage (Wheel),
786 * Logical Minimum (-127),
787 * Logical Maximum (127),
788 * Report Size (8),
789 * Report Count (3),
790 * Input (Variable, Relative),
791 * Usage Page (Consumer),
792 * Logical Minimum (-127),
793 * Logical Maximum (127),
794 * Report Size (8),
795 * Report Count (1),
796 * Usage (AC Pan),
797 * Input (Variable, Relative),
798 * End Collection,
799 * End Collection,
800 * Usage Page (Digitizer),
801 * Usage (Pen),
802 * Collection (Application),
803 * Report ID (2),
804 * Usage (Stylus),
805 * Collection (Physical),
806 * Usage (00h),
807 * Logical Minimum (0),
808 * Logical Maximum (255),
809 * Report Size (8),
810 * Report Count (7),
811 * Input (Variable),
812 * Usage (Azimuth),
813 * Usage (Altitude),
814 * Logical Minimum (0),
815 * Logical Maximum (255),
816 * Report Size (8),
817 * Report Count (2),
818 * Feature (Variable),
819 * End Collection,
820 * Report ID (5),
821 * Usage Page (Digitizer),
822 * Usage (Stylus),
823 * Collection (Physical),
824 * Usage (00h),
825 * Logical Minimum (0),
826 * Logical Maximum (255),
827 * Report Size (8),
828 * Report Count (7),
829 * Input (Variable),
830 * End Collection,
831 * Report ID (10),
832 * Usage Page (Digitizer),
833 * Usage (Stylus),
834 * Collection (Physical),
835 * Usage (00h),
836 * Logical Minimum (0),
837 * Logical Maximum (255),
838 * Report Size (8),
839 * Report Count (7),
840 * Input (Variable),
841 * End Collection,
842 * Report ID (16),
843 * Usage (Stylus),
844 * Collection (Physical),
845 * Usage (Tip Switch),
846 * Usage (Barrel Switch),
847 * Usage (Invert),
848 * Usage (Eraser),
849 * Usage (In Range),
850 * Logical Minimum (0),
851 * Logical Maximum (1),
852 * Report Size (1),
853 * Report Count (5),
854 * Input (Variable),
855 * Report Count (3),
856 * Input (Constant, Variable),
857 * Usage Page (Desktop),
858 * Usage (X),
859 * Report Size (16),
860 * Report Count (1),
861 * Push,
862 * Unit Exponent (13),
863 * Unit (Inch^3),
864 * Logical Minimum (0),
865 * Logical Maximum (16383),
866 * Physical Minimum (0),
867 * Physical Maximum (16383),
868 * Input (Variable),
869 * Usage (Y),
870 * Input (Variable),
871 * Usage Page (Digitizer),
872 * Usage (Tip Pressure),
873 * Logical Minimum (0),
874 * Logical Maximum (1023),
875 * Physical Minimum (0),
876 * Physical Maximum (1023),
877 * Input (Variable),
878 * End Collection,
879 * End Collection,
880 * Usage Page (Desktop),
881 * Usage (Keyboard),
882 * Collection (Application),
883 * Report ID (13),
884 * Usage Page (Keyboard),
885 * Usage Minimum (KB Leftcontrol),
886 * Usage Maximum (KB Right GUI),
887 * Logical Minimum (0),
888 * Logical Maximum (1),
889 * Report Size (1),
890 * Report Count (8),
891 * Input (Variable),
892 * Report Size (8),
893 * Report Count (1),
894 * Input (Constant),
895 * Usage Page (Keyboard),
896 * Usage Minimum (None),
897 * Usage Maximum (KB Application),
898 * Logical Minimum (0),
899 * Logical Maximum (101),
900 * Report Size (8),
901 * Report Count (5),
902 * Input,
903 * End Collection,
904 * Usage Page (Consumer),
905 * Usage (Consumer Control),
906 * Collection (Application),
907 * Report ID (12),
908 * Usage (Volume Inc),
909 * Usage (Volume Dec),
910 * Usage (Mute),
911 * Logical Minimum (0),
912 * Logical Maximum (1),
913 * Report Size (1),
914 * Report Count (3),
915 * Input (Variable, Relative),
916 * Report Size (5),
917 * Report Count (1),
918 * Input (Constant, Variable, Relative),
919 * End Collection
920 */
921
922/* Size of the original report descriptor of Media Tablet 14.1 inch */
923#define MEDIA_TABLET_14_1_INCH_RDESC_ORIG_SIZE 309
924
925/*
926 * Fixed Media Tablet 14.1 inch descriptor.
927 * It is fixed similarly to the Media Tablet 10.6 inch descriptor.
928 */
929static __u8 media_tablet_14_1_inch_rdesc_fixed[] = {
930 0x05, 0x0D, /* Usage Page (Digitizer), */
931 0x09, 0x02, /* Usage (Pen), */
932 0xA1, 0x01, /* Collection (Application), */
933 0x85, 0x10, /* Report ID (16), */
934 0x09, 0x20, /* Usage (Stylus), */
935 0xA0, /* Collection (Physical), */
936 0x09, 0x42, /* Usage (Tip Switch), */
937 0x09, 0x44, /* Usage (Barrel Switch), */
938 0x09, 0x46, /* Usage (Tablet Pick), */
939 0x15, 0x01, /* Logical Minimum (1), */
940 0x25, 0x03, /* Logical Maximum (3), */
941 0x75, 0x04, /* Report Size (4), */
942 0x95, 0x01, /* Report Count (1), */
943 0x80, /* Input, */
944 0x75, 0x01, /* Report Size (1), */
945 0x09, 0x32, /* Usage (In Range), */
946 0x14, /* Logical Minimum (0), */
947 0x25, 0x01, /* Logical Maximum (1), */
948 0x95, 0x01, /* Report Count (1), */
949 0x81, 0x02, /* Input (Variable), */
950 0x95, 0x03, /* Report Count (3), */
951 0x81, 0x03, /* Input (Constant, Variable), */
952 0x75, 0x10, /* Report Size (16), */
953 0x95, 0x01, /* Report Count (1), */
954 0x14, /* Logical Minimum (0), */
955 0xA4, /* Push, */
956 0x05, 0x01, /* Usage Page (Desktop), */
957 0x65, 0x13, /* Unit (Inch), */
958 0x55, 0xFD, /* Unit Exponent (-3), */
959 0x34, /* Physical Minimum (0), */
960 0x09, 0x30, /* Usage (X), */
961 0x46, 0xE0, 0x2E, /* Physical Maximum (12000), */
962 0x26, 0xFF, 0x3F, /* Logical Maximum (16383), */
963 0x81, 0x02, /* Input (Variable), */
964 0x09, 0x31, /* Usage (Y), */
965 0x46, 0x52, 0x1C, /* Physical Maximum (7250), */
966 0x26, 0xFF, 0x3F, /* Logical Maximum (16383), */
967 0x81, 0x02, /* Input (Variable), */
968 0xB4, /* Pop, */
969 0x09, 0x30, /* Usage (Tip Pressure), */
970 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
971 0x81, 0x02, /* Input (Variable), */
972 0xC0, /* End Collection, */
973 0xC0, /* End Collection, */
974 0x05, 0x01, /* Usage Page (Desktop), */
975 0x09, 0x02, /* Usage (Mouse), */
976 0xA1, 0x01, /* Collection (Application), */
977 0x85, 0x01, /* Report ID (1), */
978 0x09, 0x01, /* Usage (Pointer), */
979 0xA0, /* Collection (Physical), */
980 0x75, 0x08, /* Report Size (8), */
981 0x95, 0x03, /* Report Count (3), */
982 0x81, 0x03, /* Input (Constant, Variable), */
983 0x95, 0x02, /* Report Count (2), */
984 0x15, 0xFF, /* Logical Minimum (-1), */
985 0x25, 0x01, /* Logical Maximum (1), */
986 0x09, 0x38, /* Usage (Wheel), */
987 0x0B, 0x38, 0x02, /* Usage (Consumer AC Pan), */
988 0x0C, 0x00,
989 0x81, 0x06, /* Input (Variable, Relative), */
990 0xC0, /* End Collection, */
991 0xC0, /* End Collection, */
992 0x05, 0x0C, /* Usage Page (Consumer), */
993 0x09, 0x01, /* Usage (Consumer Control), */
994 0xA1, 0x01, /* Collection (Application), */
995 0x85, 0x0D, /* Report ID (13), */
996 0x95, 0x01, /* Report Count (1), */
997 0x75, 0x10, /* Report Size (16), */
998 0x81, 0x03, /* Input (Constant, Variable), */
999 0x0A, 0x2F, 0x02, /* Usage (AC Zoom), */
1000 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */
1001 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */
1002 0x09, 0xB6, /* Usage (Scan Previous Track), */
1003 0x09, 0xB5, /* Usage (Scan Next Track), */
1004 0x08, /* Usage (00h), */
1005 0x08, /* Usage (00h), */
1006 0x08, /* Usage (00h), */
1007 0x08, /* Usage (00h), */
1008 0x08, /* Usage (00h), */
1009 0x0A, 0x2E, 0x02, /* Usage (AC Zoom Out), */
1010 0x0A, 0x2D, 0x02, /* Usage (AC Zoom In), */
1011 0x15, 0x0C, /* Logical Minimum (12), */
1012 0x25, 0x17, /* Logical Maximum (23), */
1013 0x75, 0x05, /* Report Size (5), */
1014 0x80, /* Input, */
1015 0x75, 0x03, /* Report Size (3), */
1016 0x81, 0x03, /* Input (Constant, Variable), */
1017 0x75, 0x20, /* Report Size (32), */
1018 0x81, 0x03, /* Input (Constant, Variable), */
1019 0xC0, /* End Collection, */
1020 0x09, 0x01, /* Usage (Consumer Control), */
1021 0xA1, 0x01, /* Collection (Application), */
1022 0x85, 0x0C, /* Report ID (12), */
1023 0x75, 0x01, /* Report Size (1), */
1024 0x09, 0xE9, /* Usage (Volume Inc), */
1025 0x09, 0xEA, /* Usage (Volume Dec), */
1026 0x09, 0xE2, /* Usage (Mute), */
1027 0x14, /* Logical Minimum (0), */
1028 0x25, 0x01, /* Logical Maximum (1), */
1029 0x95, 0x03, /* Report Count (3), */
1030 0x81, 0x06, /* Input (Variable, Relative), */
1031 0x75, 0x05, /* Report Size (5), */
1032 0x81, 0x03, /* Input (Constant, Variable), */
1033 0xC0 /* End Collection */
1034};
1035
1036static __u8 *waltop_report_fixup(struct hid_device *hdev, __u8 *rdesc,
1037 unsigned int *rsize)
1038{
1039 switch (hdev->product) {
1040 case USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH:
1041 if (*rsize == SLIM_TABLET_5_8_INCH_RDESC_ORIG_SIZE) {
1042 rdesc = slim_tablet_5_8_inch_rdesc_fixed;
1043 *rsize = sizeof(slim_tablet_5_8_inch_rdesc_fixed);
1044 }
1045 break;
1046 case USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH:
1047 if (*rsize == SLIM_TABLET_12_1_INCH_RDESC_ORIG_SIZE) {
1048 rdesc = slim_tablet_12_1_inch_rdesc_fixed;
1049 *rsize = sizeof(slim_tablet_12_1_inch_rdesc_fixed);
1050 }
1051 break;
1052 case USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH:
1053 if (*rsize == MEDIA_TABLET_10_6_INCH_RDESC_ORIG_SIZE) {
1054 rdesc = media_tablet_10_6_inch_rdesc_fixed;
1055 *rsize = sizeof(media_tablet_10_6_inch_rdesc_fixed);
1056 }
1057 break;
1058 case USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH:
1059 if (*rsize == MEDIA_TABLET_14_1_INCH_RDESC_ORIG_SIZE) {
1060 rdesc = media_tablet_14_1_inch_rdesc_fixed;
1061 *rsize = sizeof(media_tablet_14_1_inch_rdesc_fixed);
1062 }
1063 break;
1064 }
1065 return rdesc;
1066}
1067
1068static const struct hid_device_id waltop_devices[] = {
1069 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
1070 USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
1071 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
1072 USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) },
1073 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
1074 USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) },
1075 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP,
1076 USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) },
1077 { }
1078};
1079MODULE_DEVICE_TABLE(hid, waltop_devices);
1080
1081static struct hid_driver waltop_driver = {
1082 .name = "waltop",
1083 .id_table = waltop_devices,
1084 .report_fixup = waltop_report_fixup,
1085};
1086
1087static int __init waltop_init(void)
1088{
1089 return hid_register_driver(&waltop_driver);
1090}
1091
1092static void __exit waltop_exit(void)
1093{
1094 hid_unregister_driver(&waltop_driver);
1095}
1096
1097module_init(waltop_init);
1098module_exit(waltop_exit);
1099MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-zydacron.c b/drivers/hid/hid-zydacron.c
index 9e8d35a203e4..aac1f9273149 100644
--- a/drivers/hid/hid-zydacron.c
+++ b/drivers/hid/hid-zydacron.c
@@ -27,10 +27,10 @@ struct zc_device {
27* Zydacron remote control has an invalid HID report descriptor, 27* Zydacron remote control has an invalid HID report descriptor,
28* that needs fixing before we can parse it. 28* that needs fixing before we can parse it.
29*/ 29*/
30static void zc_report_fixup(struct hid_device *hdev, __u8 *rdesc, 30static __u8 *zc_report_fixup(struct hid_device *hdev, __u8 *rdesc,
31 unsigned int rsize) 31 unsigned int *rsize)
32{ 32{
33 if (rsize >= 253 && 33 if (*rsize >= 253 &&
34 rdesc[0x96] == 0xbc && rdesc[0x97] == 0xff && 34 rdesc[0x96] == 0xbc && rdesc[0x97] == 0xff &&
35 rdesc[0xca] == 0xbc && rdesc[0xcb] == 0xff && 35 rdesc[0xca] == 0xbc && rdesc[0xcb] == 0xff &&
36 rdesc[0xe1] == 0xbc && rdesc[0xe2] == 0xff) { 36 rdesc[0xe1] == 0xbc && rdesc[0xe2] == 0xff) {
@@ -40,6 +40,7 @@ static void zc_report_fixup(struct hid_device *hdev, __u8 *rdesc,
40 rdesc[0x96] = rdesc[0xca] = rdesc[0xe1] = 0x0c; 40 rdesc[0x96] = rdesc[0xca] = rdesc[0xe1] = 0x0c;
41 rdesc[0x97] = rdesc[0xcb] = rdesc[0xe2] = 0x00; 41 rdesc[0x97] = rdesc[0xcb] = rdesc[0xe2] = 0x00;
42 } 42 }
43 return rdesc;
43} 44}
44 45
45#define zc_map_key_clear(c) \ 46#define zc_map_key_clear(c) \
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 925992f549f0..8a4b32dca9f7 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -218,9 +218,13 @@ static int hidraw_release(struct inode * inode, struct file * file)
218 unsigned int minor = iminor(inode); 218 unsigned int minor = iminor(inode);
219 struct hidraw *dev; 219 struct hidraw *dev;
220 struct hidraw_list *list = file->private_data; 220 struct hidraw_list *list = file->private_data;
221 int ret;
221 222
222 if (!hidraw_table[minor]) 223 mutex_lock(&minors_lock);
223 return -ENODEV; 224 if (!hidraw_table[minor]) {
225 ret = -ENODEV;
226 goto unlock;
227 }
224 228
225 list_del(&list->node); 229 list_del(&list->node);
226 dev = hidraw_table[minor]; 230 dev = hidraw_table[minor];
@@ -233,10 +237,12 @@ static int hidraw_release(struct inode * inode, struct file * file)
233 kfree(list->hidraw); 237 kfree(list->hidraw);
234 } 238 }
235 } 239 }
236
237 kfree(list); 240 kfree(list);
241 ret = 0;
242unlock:
243 mutex_unlock(&minors_lock);
238 244
239 return 0; 245 return ret;
240} 246}
241 247
242static long hidraw_ioctl(struct file *file, unsigned int cmd, 248static long hidraw_ioctl(struct file *file, unsigned int cmd,
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 599041a7f670..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++;
@@ -1469,9 +1470,6 @@ static int __init hid_init(void)
1469 retval = usbhid_quirks_init(quirks_param); 1470 retval = usbhid_quirks_init(quirks_param);
1470 if (retval) 1471 if (retval)
1471 goto usbhid_quirks_init_fail; 1472 goto usbhid_quirks_init_fail;
1472 retval = hiddev_init();
1473 if (retval)
1474 goto hiddev_init_fail;
1475 retval = usb_register(&hid_driver); 1473 retval = usb_register(&hid_driver);
1476 if (retval) 1474 if (retval)
1477 goto usb_register_fail; 1475 goto usb_register_fail;
@@ -1479,8 +1477,6 @@ static int __init hid_init(void)
1479 1477
1480 return 0; 1478 return 0;
1481usb_register_fail: 1479usb_register_fail:
1482 hiddev_exit();
1483hiddev_init_fail:
1484 usbhid_quirks_exit(); 1480 usbhid_quirks_exit();
1485usbhid_quirks_init_fail: 1481usbhid_quirks_init_fail:
1486 hid_unregister_driver(&hid_usb_driver); 1482 hid_unregister_driver(&hid_usb_driver);
@@ -1493,7 +1489,6 @@ no_queue:
1493static void __exit hid_exit(void) 1489static void __exit hid_exit(void)
1494{ 1490{
1495 usb_deregister(&hid_driver); 1491 usb_deregister(&hid_driver);
1496 hiddev_exit();
1497 usbhid_quirks_exit(); 1492 usbhid_quirks_exit();
1498 hid_unregister_driver(&hid_usb_driver); 1493 hid_unregister_driver(&hid_usb_driver);
1499 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 f0260c699adb..2c185477eeb3 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -34,7 +34,6 @@ static const struct hid_blacklist {
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_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET }, 36 { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER, HID_QUIRK_MULTI_INPUT | HID_QUIRK_NOGET },
37 { USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH, HID_QUIRK_MULTI_INPUT },
38 { 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 },
39 { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART, HID_QUIRK_MULTI_INPUT }, 38 { USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART, HID_QUIRK_MULTI_INPUT },
40 { 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 },
@@ -63,6 +62,7 @@ static const struct hid_blacklist {
63 { 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 },
64 { 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 },
65 { 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 },
66 { 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 },
67 { 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 },
68 { 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 },
@@ -72,6 +72,10 @@ static const struct hid_blacklist {
72 { 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 },
73 { 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 }, 74 { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5, HID_QUIRK_MULTI_INPUT },
75 { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U, HID_QUIRK_MULTI_INPUT },
76 { USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT },
77 { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT },
78 { USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH, HID_QUIRK_MULTI_INPUT },
75 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, 79 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_DUAL_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
76 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, 80 { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD, HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT },
77 81
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index dfcb27613ec5..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
70static 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
@@ -926,41 +924,3 @@ void hiddev_disconnect(struct hid_device *hid)
926 kfree(hiddev); 924 kfree(hiddev);
927 } 925 }
928} 926}
929
930/* Currently this driver is a USB driver. It's not a conventional one in
931 * the sense that it doesn't probe at the USB level. Instead it waits to
932 * be connected by HID through the hiddev_connect / hiddev_disconnect
933 * routines. The reason to register as a USB device is to gain part of the
934 * minor number space from the USB major.
935 *
936 * In theory, should the HID code be generalized to more than one physical
937 * medium (say, IEEE 1384), this driver will probably need to register its
938 * own major number, and in doing so, no longer need to register with USB.
939 * At that point the probe routine and hiddev_driver struct below will no
940 * longer be useful.
941 */
942
943
944/* We never attach in this manner, and rely on HID to connect us. This
945 * is why there is no disconnect routine defined in the usb_driver either.
946 */
947static int hiddev_usbd_probe(struct usb_interface *intf,
948 const struct usb_device_id *hiddev_info)
949{
950 return -ENODEV;
951}
952
953static /* const */ struct usb_driver hiddev_driver = {
954 .name = "hiddev",
955 .probe = hiddev_usbd_probe,
956};
957
958int __init hiddev_init(void)
959{
960 return usb_register(&hiddev_driver);
961}
962
963void hiddev_exit(void)
964{
965 usb_deregister(&hiddev_driver);
966}