aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/Kconfig48
-rw-r--r--drivers/hid/Makefile3
-rw-r--r--drivers/hid/hid-apple.c27
-rw-r--r--drivers/hid/hid-axff.c1
-rw-r--r--drivers/hid/hid-core.c34
-rw-r--r--drivers/hid/hid-debug.c5
-rw-r--r--drivers/hid/hid-emsff.c7
-rw-r--r--drivers/hid/hid-holtekff.c240
-rw-r--r--drivers/hid/hid-ids.h37
-rw-r--r--drivers/hid/hid-input.c7
-rw-r--r--drivers/hid/hid-lg.c74
-rw-r--r--drivers/hid/hid-magicmouse.c79
-rw-r--r--drivers/hid/hid-microsoft.c28
-rw-r--r--drivers/hid/hid-multitouch.c19
-rw-r--r--drivers/hid/hid-prodikeys.c17
-rw-r--r--drivers/hid/hid-roccat-arvo.c21
-rw-r--r--drivers/hid/hid-roccat-arvo.h13
-rw-r--r--drivers/hid/hid-roccat-common.c20
-rw-r--r--drivers/hid/hid-roccat-common.h4
-rw-r--r--drivers/hid/hid-roccat-kone.c56
-rw-r--r--drivers/hid/hid-roccat-kone.h2
-rw-r--r--drivers/hid/hid-roccat-koneplus.c49
-rw-r--r--drivers/hid/hid-roccat-koneplus.h23
-rw-r--r--drivers/hid/hid-roccat-kovaplus.c25
-rw-r--r--drivers/hid/hid-roccat-kovaplus.h9
-rw-r--r--drivers/hid/hid-roccat-pyra.c25
-rw-r--r--drivers/hid/hid-roccat-pyra.h9
-rw-r--r--drivers/hid/hid-sony.c35
-rw-r--r--drivers/hid/hid-speedlink.c89
-rw-r--r--drivers/hid/hid-uclogic.c195
-rw-r--r--drivers/hid/hid-wacom.c24
-rw-r--r--drivers/hid/hid-wiimote.c578
-rw-r--r--drivers/hid/usbhid/hid-core.c2
-rw-r--r--drivers/hid/usbhid/hid-quirks.c2
34 files changed, 1638 insertions, 169 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 36ca465c00c..7978c55db84 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -69,7 +69,7 @@ config HID_ACRUX
69 Say Y here if you want to enable support for ACRUX game controllers. 69 Say Y here if you want to enable support for ACRUX game controllers.
70 70
71config HID_ACRUX_FF 71config HID_ACRUX_FF
72 tristate "ACRUX force feedback support" 72 bool "ACRUX force feedback support"
73 depends on HID_ACRUX 73 depends on HID_ACRUX
74 select INPUT_FF_MEMLESS 74 select INPUT_FF_MEMLESS
75 ---help--- 75 ---help---
@@ -172,6 +172,20 @@ config HID_EZKEY
172 ---help--- 172 ---help---
173 Support for Ezkey BTC 8193 keyboard. 173 Support for Ezkey BTC 8193 keyboard.
174 174
175config HID_HOLTEK
176 tristate "Holtek On Line Grip based game controller support"
177 depends on USB_HID
178 ---help---
179 Say Y here if you have a Holtek On Line Grip based game controller.
180
181config HOLTEK_FF
182 bool "Holtek On Line Grip force feedback support"
183 depends on HID_HOLTEK
184 select INPUT_FF_MEMLESS
185 ---help---
186 Say Y here if you have a Holtek On Line Grip based game controller
187 and want to have force feedback support for it.
188
175config HID_KEYTOUCH 189config HID_KEYTOUCH
176 tristate "Keytouch HID devices" 190 tristate "Keytouch HID devices"
177 depends on USB_HID 191 depends on USB_HID
@@ -314,6 +328,7 @@ config HID_MULTITOUCH
314 - Hanvon dual touch panels 328 - Hanvon dual touch panels
315 - Ilitek dual touch panels 329 - Ilitek dual touch panels
316 - IrTouch Infrared USB panels 330 - IrTouch Infrared USB panels
331 - LG Display panels (Dell ST2220Tc)
317 - Lumio CrystalTouch panels 332 - Lumio CrystalTouch panels
318 - MosArt dual-touch panels 333 - MosArt dual-touch panels
319 - PenMount dual touch panels 334 - PenMount dual touch panels
@@ -322,6 +337,7 @@ config HID_MULTITOUCH
322 - Stantum multitouch panels 337 - Stantum multitouch panels
323 - Touch International Panels 338 - Touch International Panels
324 - Unitec Panels 339 - Unitec Panels
340 - XAT optical touch panels
325 341
326 If unsure, say N. 342 If unsure, say N.
327 343
@@ -435,6 +451,7 @@ config HID_QUANTA
435config HID_ROCCAT 451config HID_ROCCAT
436 tristate "Roccat special event support" 452 tristate "Roccat special event support"
437 depends on USB_HID 453 depends on USB_HID
454 select HID_ROCCAT_COMMON
438 ---help--- 455 ---help---
439 Support for Roccat special events. 456 Support for Roccat special events.
440 Say Y here if you have a Roccat mouse or keyboard and want OSD or 457 Say Y here if you have a Roccat mouse or keyboard and want OSD or
@@ -442,44 +459,40 @@ config HID_ROCCAT
442 459
443config HID_ROCCAT_COMMON 460config HID_ROCCAT_COMMON
444 tristate 461 tristate
462 depends on HID_ROCCAT
445 463
446config HID_ROCCAT_ARVO 464config HID_ROCCAT_ARVO
447 tristate "Roccat Arvo keyboard support" 465 tristate "Roccat Arvo keyboard support"
448 depends on USB_HID 466 depends on USB_HID
449 select HID_ROCCAT 467 depends on HID_ROCCAT
450 select HID_ROCCAT_COMMON
451 ---help--- 468 ---help---
452 Support for Roccat Arvo keyboard. 469 Support for Roccat Arvo keyboard.
453 470
454config HID_ROCCAT_KONE 471config HID_ROCCAT_KONE
455 tristate "Roccat Kone Mouse support" 472 tristate "Roccat Kone Mouse support"
456 depends on USB_HID 473 depends on USB_HID
457 select HID_ROCCAT 474 depends on HID_ROCCAT
458 select HID_ROCCAT_COMMON
459 ---help--- 475 ---help---
460 Support for Roccat Kone mouse. 476 Support for Roccat Kone mouse.
461 477
462config HID_ROCCAT_KONEPLUS 478config HID_ROCCAT_KONEPLUS
463 tristate "Roccat Kone[+] mouse support" 479 tristate "Roccat Kone[+] mouse support"
464 depends on USB_HID 480 depends on USB_HID
465 select HID_ROCCAT 481 depends on HID_ROCCAT
466 select HID_ROCCAT_COMMON
467 ---help--- 482 ---help---
468 Support for Roccat Kone[+] mouse. 483 Support for Roccat Kone[+] mouse.
469 484
470config HID_ROCCAT_KOVAPLUS 485config HID_ROCCAT_KOVAPLUS
471 tristate "Roccat Kova[+] mouse support" 486 tristate "Roccat Kova[+] mouse support"
472 depends on USB_HID 487 depends on USB_HID
473 select HID_ROCCAT 488 depends on HID_ROCCAT
474 select HID_ROCCAT_COMMON
475 ---help--- 489 ---help---
476 Support for Roccat Kova[+] mouse. 490 Support for Roccat Kova[+] mouse.
477 491
478config HID_ROCCAT_PYRA 492config HID_ROCCAT_PYRA
479 tristate "Roccat Pyra mouse support" 493 tristate "Roccat Pyra mouse support"
480 depends on USB_HID 494 depends on USB_HID
481 select HID_ROCCAT 495 depends on HID_ROCCAT
482 select HID_ROCCAT_COMMON
483 ---help--- 496 ---help---
484 Support for Roccat Pyra mouse. 497 Support for Roccat Pyra mouse.
485 498
@@ -495,6 +508,12 @@ config HID_SONY
495 ---help--- 508 ---help---
496 Support for Sony PS3 controller. 509 Support for Sony PS3 controller.
497 510
511config HID_SPEEDLINK
512 tristate "Speedlink VAD Cezanne mouse support"
513 depends on USB_HID
514 ---help---
515 Support for Speedlink Vicious and Divine Cezanne mouse.
516
498config HID_SUNPLUS 517config HID_SUNPLUS
499 tristate "Sunplus wireless desktop" 518 tristate "Sunplus wireless desktop"
500 depends on USB_HID 519 depends on USB_HID
@@ -568,6 +587,13 @@ config HID_WACOM_POWER_SUPPLY
568 Say Y here if you want to enable power supply status monitoring for 587 Say Y here if you want to enable power supply status monitoring for
569 Wacom Bluetooth devices. 588 Wacom Bluetooth devices.
570 589
590config HID_WIIMOTE
591 tristate "Nintendo Wii Remote support"
592 depends on BT_HIDP
593 depends on LEDS_CLASS
594 ---help---
595 Support for the Nintendo Wii Remote bluetooth device.
596
571config HID_ZEROPLUS 597config HID_ZEROPLUS
572 tristate "Zeroplus based game controller support" 598 tristate "Zeroplus based game controller support"
573 depends on USB_HID 599 depends on USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index f8cc4ea7335..0a0a38e9fd2 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o
37obj-$(CONFIG_HID_ELECOM) += hid-elecom.o 37obj-$(CONFIG_HID_ELECOM) += hid-elecom.o
38obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o 38obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
39obj-$(CONFIG_HID_GYRATION) += hid-gyration.o 39obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
40obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o
40obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o 41obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
41obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o 42obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o
42obj-$(CONFIG_HID_KYE) += hid-kye.o 43obj-$(CONFIG_HID_KYE) += hid-kye.o
@@ -63,6 +64,7 @@ obj-$(CONFIG_HID_ROCCAT_PYRA) += hid-roccat-pyra.o
63obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o 64obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
64obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o 65obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
65obj-$(CONFIG_HID_SONY) += hid-sony.o 66obj-$(CONFIG_HID_SONY) += hid-sony.o
67obj-$(CONFIG_HID_SPEEDLINK) += hid-speedlink.o
66obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o 68obj-$(CONFIG_HID_SUNPLUS) += hid-sunplus.o
67obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o 69obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o
68obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o 70obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o
@@ -73,6 +75,7 @@ obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o
73obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o 75obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o
74obj-$(CONFIG_HID_WACOM) += hid-wacom.o 76obj-$(CONFIG_HID_WACOM) += hid-wacom.o
75obj-$(CONFIG_HID_WALTOP) += hid-waltop.o 77obj-$(CONFIG_HID_WALTOP) += hid-waltop.o
78obj-$(CONFIG_HID_WIIMOTE) += hid-wiimote.o
76 79
77obj-$(CONFIG_USB_HID) += usbhid/ 80obj-$(CONFIG_USB_HID) += usbhid/
78obj-$(CONFIG_USB_MOUSE) += usbhid/ 81obj-$(CONFIG_USB_MOUSE) += usbhid/
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index b85744fe846..299d2387112 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -444,11 +444,20 @@ static const struct hid_device_id apple_devices[] = {
444 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS), 444 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS),
445 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | 445 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
446 APPLE_RDESC_JIS }, 446 APPLE_RDESC_JIS },
447 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI),
448 .driver_data = APPLE_HAS_FN },
449 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO),
450 .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
451 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS),
452 .driver_data = APPLE_HAS_FN },
447 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI), 453 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
448 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, 454 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
449 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO), 455 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO),
450 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN | 456 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
451 APPLE_ISO_KEYBOARD }, 457 APPLE_ISO_KEYBOARD },
458 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO),
459 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
460 APPLE_ISO_KEYBOARD },
452 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS), 461 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS),
453 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, 462 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
454 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI), 463 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
@@ -487,6 +496,24 @@ static const struct hid_device_id apple_devices[] = {
487 .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, 496 .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
488 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS), 497 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS),
489 .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, 498 .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
499 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI),
500 .driver_data = APPLE_HAS_FN },
501 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO),
502 .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
503 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS),
504 .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
505 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI),
506 .driver_data = APPLE_HAS_FN },
507 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO),
508 .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
509 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS),
510 .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
511 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI),
512 .driver_data = APPLE_HAS_FN },
513 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO),
514 .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
515 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS),
516 .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS },
490 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), 517 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI),
491 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, 518 .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
492 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), 519 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
diff --git a/drivers/hid/hid-axff.c b/drivers/hid/hid-axff.c
index b4554288de0..121514149e0 100644
--- a/drivers/hid/hid-axff.c
+++ b/drivers/hid/hid-axff.c
@@ -154,6 +154,7 @@ static int ax_probe(struct hid_device *hdev, const struct hid_device_id *id)
154 error = hid_hw_open(hdev); 154 error = hid_hw_open(hdev);
155 if (error) { 155 if (error) {
156 dev_err(&hdev->dev, "hw open failed\n"); 156 dev_err(&hdev->dev, "hw open failed\n");
157 hid_hw_stop(hdev);
157 return error; 158 return error;
158 } 159 }
159 160
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 6f3289a5788..e9c8f803de1 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -361,7 +361,7 @@ static int hid_parser_global(struct hid_parser *parser, struct hid_item *item)
361 361
362 case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: 362 case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
363 parser->global.report_size = item_udata(item); 363 parser->global.report_size = item_udata(item);
364 if (parser->global.report_size > 32) { 364 if (parser->global.report_size > 96) {
365 dbg_hid("invalid report_size %d\n", 365 dbg_hid("invalid report_size %d\n",
366 parser->global.report_size); 366 parser->global.report_size);
367 return -1; 367 return -1;
@@ -1340,9 +1340,22 @@ static const struct hid_device_id hid_have_special_driver[] = {
1340 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) }, 1340 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) },
1341 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) }, 1341 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) },
1342 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) }, 1342 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) },
1343 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI) },
1344 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO) },
1345 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS) },
1346 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI) },
1347 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_ISO) },
1348 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6_JIS) },
1349 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI) },
1350 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO) },
1351 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS) },
1352 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ANSI) },
1353 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_ISO) },
1354 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_REVB_JIS) },
1343 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, 1355 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) },
1344 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, 1356 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) },
1345 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, 1357 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) },
1358 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO) },
1346 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, 1359 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
1347 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, 1360 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
1348 { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) }, 1361 { HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUS_T91MT) },
@@ -1388,6 +1401,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1388 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, 1401 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
1389 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, 1402 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
1390 { HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) }, 1403 { HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) },
1404 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },
1391 { HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, USB_DEVICE_ID_ILITEK_MULTITOUCH) }, 1405 { HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, USB_DEVICE_ID_ILITEK_MULTITOUCH) },
1392 { HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, 1406 { HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
1393 { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, 1407 { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
@@ -1395,6 +1409,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1395 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, 1409 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
1396 { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, 1410 { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
1397 { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, 1411 { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) },
1412 { HID_USB_DEVICE(USB_VENDOR_ID_LG, USB_DEVICE_ID_LG_MULTITOUCH) },
1398 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, 1413 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
1399 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, 1414 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
1400 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, 1415 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) },
@@ -1426,10 +1441,12 @@ static const struct hid_device_id hid_have_special_driver[] = {
1426 { HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH_DUAL) }, 1441 { HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH_DUAL) },
1427 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) }, 1442 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) },
1428 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) }, 1443 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) },
1444 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500) },
1429 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) }, 1445 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) },
1430 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) }, 1446 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_NE4K) },
1431 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) }, 1447 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_LK6K) },
1432 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) }, 1448 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) },
1449 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) },
1433 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, 1450 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) },
1434 { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) }, 1451 { HID_USB_DEVICE(USB_VENDOR_ID_MONTEREY, USB_DEVICE_ID_GENIUS_KB29E) },
1435 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) }, 1452 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
@@ -1491,6 +1508,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1491 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) }, 1508 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) },
1492 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) }, 1509 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) },
1493 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) }, 1510 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) },
1511 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP1062) },
1494 { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) }, 1512 { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) },
1495 { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, 1513 { HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) },
1496 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) }, 1514 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
@@ -1499,11 +1517,14 @@ static const struct hid_device_id hid_have_special_driver[] = {
1499 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) }, 1517 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_12_1_INCH) },
1500 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) }, 1518 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH) },
1501 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) }, 1519 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) },
1520 { HID_USB_DEVICE(USB_VENDOR_ID_XAT, USB_DEVICE_ID_XAT_CSR) },
1521 { HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) },
1502 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, 1522 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
1503 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, 1523 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
1504 { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) }, 1524 { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
1505 1525
1506 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, 1526 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
1527 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
1507 { } 1528 { }
1508}; 1529};
1509 1530
@@ -1707,8 +1728,8 @@ static const struct hid_device_id hid_ignore_list[] = {
1707 { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) }, 1728 { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) },
1708 { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) }, 1729 { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC5UH) },
1709 { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) }, 1730 { HID_USB_DEVICE(USB_VENDOR_ID_ETT, USB_DEVICE_ID_TC4UM) },
1731 { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) },
1710 { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) }, 1732 { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) },
1711 { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) },
1712 { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0004) }, 1733 { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0004) },
1713 { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30) }, 1734 { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30) },
1714 { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30) }, 1735 { HID_USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30) },
@@ -1771,7 +1792,6 @@ static const struct hid_device_id hid_ignore_list[] = {
1771 { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) }, 1792 { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) },
1772 { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) }, 1793 { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1007) },
1773 { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) }, 1794 { HID_USB_DEVICE(USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA) },
1774 { HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_JESS_YUREX) },
1775 { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) }, 1795 { HID_USB_DEVICE(USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO) },
1776 { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) }, 1796 { HID_USB_DEVICE(USB_VENDOR_ID_KWORLD, USB_DEVICE_ID_KWORLD_RADIO_FM700) },
1777 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) }, 1797 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) },
@@ -1883,6 +1903,9 @@ static const struct hid_device_id hid_mouse_ignore_list[] = {
1883 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) }, 1903 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI) },
1884 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) }, 1904 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_ISO) },
1885 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) }, 1905 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5_JIS) },
1906 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI) },
1907 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO) },
1908 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS) },
1886 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, 1909 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
1887 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, 1910 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
1888 { } 1911 { }
@@ -1912,6 +1935,11 @@ static bool hid_ignore(struct hid_device *hdev)
1912 hdev->product <= USB_DEVICE_ID_HANWANG_TABLET_LAST) 1935 hdev->product <= USB_DEVICE_ID_HANWANG_TABLET_LAST)
1913 return true; 1936 return true;
1914 break; 1937 break;
1938 case USB_VENDOR_ID_JESS:
1939 if (hdev->product == USB_DEVICE_ID_JESS_YUREX &&
1940 hdev->type == HID_TYPE_USBNONE)
1941 return true;
1942 break;
1915 } 1943 }
1916 1944
1917 if (hdev->type == HID_TYPE_USBMOUSE && 1945 if (hdev->type == HID_TYPE_USBMOUSE &&
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index bae48745bb4..9a243ca96e6 100644
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -450,6 +450,11 @@ void hid_dump_field(struct hid_field *field, int n, struct seq_file *f) {
450 seq_printf(f, "Logical("); 450 seq_printf(f, "Logical(");
451 hid_resolv_usage(field->logical, f); seq_printf(f, ")\n"); 451 hid_resolv_usage(field->logical, f); seq_printf(f, ")\n");
452 } 452 }
453 if (field->application) {
454 tab(n, f);
455 seq_printf(f, "Application(");
456 hid_resolv_usage(field->application, f); seq_printf(f, ")\n");
457 }
453 tab(n, f); seq_printf(f, "Usage(%d)\n", field->maxusage); 458 tab(n, f); seq_printf(f, "Usage(%d)\n", field->maxusage);
454 for (j = 0; j < field->maxusage; j++) { 459 for (j = 0; j < field->maxusage; j++) {
455 tab(n+2, f); hid_resolv_usage(field->usage[j].hid, f); seq_printf(f, "\n"); 460 tab(n+2, f); hid_resolv_usage(field->usage[j].hid, f); seq_printf(f, "\n");
diff --git a/drivers/hid/hid-emsff.c b/drivers/hid/hid-emsff.c
index 81877c67cae..a5dc13fe367 100644
--- a/drivers/hid/hid-emsff.c
+++ b/drivers/hid/hid-emsff.c
@@ -126,7 +126,12 @@ static int ems_probe(struct hid_device *hdev, const struct hid_device_id *id)
126 goto err; 126 goto err;
127 } 127 }
128 128
129 emsff_init(hdev); 129 ret = emsff_init(hdev);
130 if (ret) {
131 dev_err(&hdev->dev, "force feedback init failed\n");
132 hid_hw_stop(hdev);
133 goto err;
134 }
130 135
131 return 0; 136 return 0;
132err: 137err:
diff --git a/drivers/hid/hid-holtekff.c b/drivers/hid/hid-holtekff.c
new file mode 100644
index 00000000000..91e3a032112
--- /dev/null
+++ b/drivers/hid/hid-holtekff.c
@@ -0,0 +1,240 @@
1/*
2 * Force feedback support for Holtek On Line Grip based gamepads
3 *
4 * These include at least a Brazilian "Clone Joypad Super Power Fire"
5 * which uses vendor ID 0x1241 and identifies as "HOLTEK On Line Grip".
6 *
7 * Copyright (c) 2011 Anssi Hannula <anssi.hannula@iki.fi>
8 */
9
10/*
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26#include <linux/hid.h>
27#include <linux/input.h>
28#include <linux/slab.h>
29#include <linux/usb.h>
30
31#include "hid-ids.h"
32
33#ifdef CONFIG_HOLTEK_FF
34#include "usbhid/usbhid.h"
35
36MODULE_LICENSE("GPL");
37MODULE_AUTHOR("Anssi Hannula <anssi.hannula@iki.fi>");
38MODULE_DESCRIPTION("Force feedback support for Holtek On Line Grip based devices");
39
40/*
41 * These commands and parameters are currently known:
42 *
43 * byte 0: command id:
44 * 01 set effect parameters
45 * 02 play specified effect
46 * 03 stop specified effect
47 * 04 stop all effects
48 * 06 stop all effects
49 * (the difference between 04 and 06 isn't known; win driver
50 * sends 06,04 on application init, and 06 otherwise)
51 *
52 * Commands 01 and 02 need to be sent as pairs, i.e. you need to send 01
53 * before each 02.
54 *
55 * The rest of the bytes are parameters. Command 01 takes all of them, and
56 * commands 02,03 take only the effect id.
57 *
58 * byte 1:
59 * bits 0-3: effect id:
60 * 1: very strong rumble
61 * 2: periodic rumble, short intervals
62 * 3: very strong rumble
63 * 4: periodic rumble, long intervals
64 * 5: weak periodic rumble, long intervals
65 * 6: weak periodic rumble, short intervals
66 * 7: periodic rumble, short intervals
67 * 8: strong periodic rumble, short intervals
68 * 9: very strong rumble
69 * a: causes an error
70 * b: very strong periodic rumble, very short intervals
71 * c-f: nothing
72 * bit 6: right (weak) motor enabled
73 * bit 7: left (strong) motor enabled
74 *
75 * bytes 2-3: time in milliseconds, big-endian
76 * bytes 5-6: unknown (win driver seems to use at least 10e0 with effect 1
77 * and 0014 with effect 6)
78 * byte 7:
79 * bits 0-3: effect magnitude
80 */
81
82#define HOLTEKFF_MSG_LENGTH 7
83
84static const u8 start_effect_1[] = { 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 };
85static const u8 stop_all4[] = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
86static const u8 stop_all6[] = { 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
87
88struct holtekff_device {
89 struct hid_field *field;
90};
91
92static void holtekff_send(struct holtekff_device *holtekff,
93 struct hid_device *hid,
94 const u8 data[HOLTEKFF_MSG_LENGTH])
95{
96 int i;
97
98 for (i = 0; i < HOLTEKFF_MSG_LENGTH; i++) {
99 holtekff->field->value[i] = data[i];
100 }
101
102 dbg_hid("sending %02x %02x %02x %02x %02x %02x %02x\n", data[0],
103 data[1], data[2], data[3], data[4], data[5], data[6]);
104
105 usbhid_submit_report(hid, holtekff->field->report, USB_DIR_OUT);
106}
107
108static int holtekff_play(struct input_dev *dev, void *data,
109 struct ff_effect *effect)
110{
111 struct hid_device *hid = input_get_drvdata(dev);
112 struct holtekff_device *holtekff = data;
113 int left, right;
114 /* effect type 1, length 65535 msec */
115 u8 buf[HOLTEKFF_MSG_LENGTH] =
116 { 0x01, 0x01, 0xff, 0xff, 0x10, 0xe0, 0x00 };
117
118 left = effect->u.rumble.strong_magnitude;
119 right = effect->u.rumble.weak_magnitude;
120 dbg_hid("called with 0x%04x 0x%04x\n", left, right);
121
122 if (!left && !right) {
123 holtekff_send(holtekff, hid, stop_all6);
124 return 0;
125 }
126
127 if (left)
128 buf[1] |= 0x80;
129 if (right)
130 buf[1] |= 0x40;
131
132 /* The device takes a single magnitude, so we just sum them up. */
133 buf[6] = min(0xf, (left >> 12) + (right >> 12));
134
135 holtekff_send(holtekff, hid, buf);
136 holtekff_send(holtekff, hid, start_effect_1);
137
138 return 0;
139}
140
141static int holtekff_init(struct hid_device *hid)
142{
143 struct holtekff_device *holtekff;
144 struct hid_report *report;
145 struct hid_input *hidinput = list_entry(hid->inputs.next,
146 struct hid_input, list);
147 struct list_head *report_list =
148 &hid->report_enum[HID_OUTPUT_REPORT].report_list;
149 struct input_dev *dev = hidinput->input;
150 int error;
151
152 if (list_empty(report_list)) {
153 hid_err(hid, "no output report found\n");
154 return -ENODEV;
155 }
156
157 report = list_entry(report_list->next, struct hid_report, list);
158
159 if (report->maxfield < 1 || report->field[0]->report_count != 7) {
160 hid_err(hid, "unexpected output report layout\n");
161 return -ENODEV;
162 }
163
164 holtekff = kzalloc(sizeof(*holtekff), GFP_KERNEL);
165 if (!holtekff)
166 return -ENOMEM;
167
168 set_bit(FF_RUMBLE, dev->ffbit);
169
170 holtekff->field = report->field[0];
171
172 /* initialize the same way as win driver does */
173 holtekff_send(holtekff, hid, stop_all4);
174 holtekff_send(holtekff, hid, stop_all6);
175
176 error = input_ff_create_memless(dev, holtekff, holtekff_play);
177 if (error) {
178 kfree(holtekff);
179 return error;
180 }
181
182 hid_info(hid, "Force feedback for Holtek On Line Grip based devices by Anssi Hannula <anssi.hannula@iki.fi>\n");
183
184 return 0;
185}
186#else
187static inline int holtekff_init(struct hid_device *hid)
188{
189 return 0;
190}
191#endif
192
193static int holtek_probe(struct hid_device *hdev, const struct hid_device_id *id)
194{
195 int ret;
196
197 ret = hid_parse(hdev);
198 if (ret) {
199 hid_err(hdev, "parse failed\n");
200 goto err;
201 }
202
203 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
204 if (ret) {
205 hid_err(hdev, "hw start failed\n");
206 goto err;
207 }
208
209 holtekff_init(hdev);
210
211 return 0;
212err:
213 return ret;
214}
215
216static const struct hid_device_id holtek_devices[] = {
217 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },
218 { }
219};
220MODULE_DEVICE_TABLE(hid, holtek_devices);
221
222static struct hid_driver holtek_driver = {
223 .name = "holtek",
224 .id_table = holtek_devices,
225 .probe = holtek_probe,
226};
227
228static int __init holtek_init(void)
229{
230 return hid_register_driver(&holtek_driver);
231}
232
233static void __exit holtek_exit(void)
234{
235 hid_unregister_driver(&holtek_driver);
236}
237
238module_init(holtek_init);
239module_exit(holtek_exit);
240
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index a756ee6c7df..53c4634fed3 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -109,9 +109,22 @@
109#define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI 0x0245 109#define USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI 0x0245
110#define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO 0x0246 110#define USB_DEVICE_ID_APPLE_WELLSPRING5_ISO 0x0246
111#define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS 0x0247 111#define USB_DEVICE_ID_APPLE_WELLSPRING5_JIS 0x0247
112#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI 0x0249
113#define USB_DEVICE_ID_APPLE_WELLSPRING6A_ISO 0x024a
114#define USB_DEVICE_ID_APPLE_WELLSPRING6A_JIS 0x024b
115#define USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI 0x024c
116#define USB_DEVICE_ID_APPLE_WELLSPRING6_ISO 0x024d
117#define USB_DEVICE_ID_APPLE_WELLSPRING6_JIS 0x024e
118#define USB_DEVICE_ID_APPLE_ALU_REVB_ANSI 0x024f
119#define USB_DEVICE_ID_APPLE_ALU_REVB_ISO 0x0250
120#define USB_DEVICE_ID_APPLE_ALU_REVB_JIS 0x0251
121#define USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI 0x0252
122#define USB_DEVICE_ID_APPLE_WELLSPRING5A_ISO 0x0253
123#define USB_DEVICE_ID_APPLE_WELLSPRING5A_JIS 0x0254
112#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239 124#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239
113#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a 125#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a
114#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b 126#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b
127#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO 0x0256
115#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a 128#define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a
116#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b 129#define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b
117#define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241 130#define USB_DEVICE_ID_APPLE_ATV_IRCONTROL 0x8241
@@ -253,7 +266,7 @@
253#define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002 266#define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002
254 267
255#define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc 268#define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc
256#define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0001 269#define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0003
257 270
258#define USB_VENDOR_ID_GLAB 0x06c2 271#define USB_VENDOR_ID_GLAB 0x06c2
259#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 272#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038
@@ -274,6 +287,7 @@
274#define USB_DEVICE_ID_PENPOWER 0x00f4 287#define USB_DEVICE_ID_PENPOWER 0x00f4
275 288
276#define USB_VENDOR_ID_GREENASIA 0x0e8f 289#define USB_VENDOR_ID_GREENASIA 0x0e8f
290#define USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD 0x3013
277 291
278#define USB_VENDOR_ID_GRETAGMACBETH 0x0971 292#define USB_VENDOR_ID_GRETAGMACBETH 0x0971
279#define USB_DEVICE_ID_GRETAGMACBETH_HUEY 0x2005 293#define USB_DEVICE_ID_GRETAGMACBETH_HUEY 0x2005
@@ -350,6 +364,9 @@
350#define USB_VENDOR_ID_ILITEK 0x222a 364#define USB_VENDOR_ID_ILITEK 0x222a
351#define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 365#define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001
352 366
367#define USB_VENDOR_ID_HOLTEK 0x1241
368#define USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP 0x5015
369
353#define USB_VENDOR_ID_IMATION 0x0718 370#define USB_VENDOR_ID_IMATION 0x0718
354#define USB_DEVICE_ID_DISC_STAKKA 0xd000 371#define USB_DEVICE_ID_DISC_STAKKA 0xd000
355 372
@@ -416,6 +433,9 @@
416#define USB_DEVICE_ID_LD_HYBRID 0x2090 433#define USB_DEVICE_ID_LD_HYBRID 0x2090
417#define USB_DEVICE_ID_LD_HEATCONTROL 0x20A0 434#define USB_DEVICE_ID_LD_HEATCONTROL 0x20A0
418 435
436#define USB_VENDOR_ID_LG 0x1fd2
437#define USB_DEVICE_ID_LG_MULTITOUCH 0x0064
438
419#define USB_VENDOR_ID_LOGITECH 0x046d 439#define USB_VENDOR_ID_LOGITECH 0x046d
420#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101 440#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
421#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110 441#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110
@@ -472,6 +492,8 @@
472#define USB_DEVICE_ID_MS_LK6K 0x00f9 492#define USB_DEVICE_ID_MS_LK6K 0x00f9
473#define USB_DEVICE_ID_MS_PRESENTER_8K_BT 0x0701 493#define USB_DEVICE_ID_MS_PRESENTER_8K_BT 0x0701
474#define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 494#define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713
495#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730
496#define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c
475 497
476#define USB_VENDOR_ID_MOJO 0x8282 498#define USB_VENDOR_ID_MOJO 0x8282
477#define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 499#define USB_DEVICE_ID_RETRO_ADAPTER 0x3201
@@ -495,6 +517,9 @@
495#define USB_VENDOR_ID_NEXTWINDOW 0x1926 517#define USB_VENDOR_ID_NEXTWINDOW 0x1926
496#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003 518#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003
497 519
520#define USB_VENDOR_ID_NINTENDO 0x057e
521#define USB_DEVICE_ID_NINTENDO_WIIMOTE 0x0306
522
498#define USB_VENDOR_ID_NTRIG 0x1b96 523#define USB_VENDOR_ID_NTRIG 0x1b96
499#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001 524#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001
500#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003 525#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003
@@ -568,6 +593,9 @@
568#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001 593#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
569#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600 594#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600
570 595
596#define USB_VENDOR_ID_SIGMA_MICRO 0x1c4f
597#define USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD 0x0002
598
571#define USB_VENDOR_ID_SKYCABLE 0x1223 599#define USB_VENDOR_ID_SKYCABLE 0x1223
572#define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07 600#define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07
573 601
@@ -630,6 +658,7 @@
630#define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003 658#define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003
631#define USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U 0x0004 659#define USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U 0x0004
632#define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005 660#define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005
661#define USB_DEVICE_ID_UCLOGIC_TABLET_WP1062 0x0064
633 662
634#define USB_VENDOR_ID_UNITEC 0x227d 663#define USB_VENDOR_ID_UNITEC 0x227d
635#define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709 664#define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709
@@ -663,6 +692,12 @@
663#define USB_VENDOR_ID_WISEGROUP_LTD2 0x6677 692#define USB_VENDOR_ID_WISEGROUP_LTD2 0x6677
664#define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802 693#define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802
665 694
695#define USB_VENDOR_ID_X_TENSIONS 0x1ae7
696#define USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE 0x9001
697
698#define USB_VENDOR_ID_XAT 0x2505
699#define USB_DEVICE_ID_XAT_CSR 0x0220
700
666#define USB_VENDOR_ID_YEALINK 0x6993 701#define USB_VENDOR_ID_YEALINK 0x6993
667#define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001 702#define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001
668 703
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 6559e2e3364..1483c8296d5 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -971,6 +971,9 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
971 * UGCI) cram a lot of unrelated inputs into the 971 * UGCI) cram a lot of unrelated inputs into the
972 * same interface. */ 972 * same interface. */
973 hidinput->report = report; 973 hidinput->report = report;
974 if (hid->driver->input_register &&
975 hid->driver->input_register(hid, hidinput))
976 goto out_cleanup;
974 if (input_register_device(hidinput->input)) 977 if (input_register_device(hidinput->input))
975 goto out_cleanup; 978 goto out_cleanup;
976 hidinput = NULL; 979 hidinput = NULL;
@@ -978,6 +981,10 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
978 } 981 }
979 } 982 }
980 983
984 if (hidinput && hid->driver->input_register &&
985 hid->driver->input_register(hid, hidinput))
986 goto out_cleanup;
987
981 if (hidinput && input_register_device(hidinput->input)) 988 if (hidinput && input_register_device(hidinput->input))
982 goto out_cleanup; 989 goto out_cleanup;
983 990
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index 21f205f0925..a7f916e8fc3 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -41,6 +41,66 @@
41#define LG_FF3 0x1000 41#define LG_FF3 0x1000
42#define LG_FF4 0x2000 42#define LG_FF4 0x2000
43 43
44/* Size of the original descriptor of the Driving Force Pro wheel */
45#define DFP_RDESC_ORIG_SIZE 97
46
47/* Fixed report descriptor for Logitech Driving Force Pro wheel controller
48 *
49 * The original descriptor hides the separate throttle and brake axes in
50 * a custom vendor usage page, providing only a combined value as
51 * GenericDesktop.Y.
52 * This descriptor removes the combined Y axis and instead reports
53 * separate throttle (Y) and brake (RZ).
54 */
55static __u8 dfp_rdesc_fixed[] = {
560x05, 0x01, /* Usage Page (Desktop), */
570x09, 0x04, /* Usage (Joystik), */
580xA1, 0x01, /* Collection (Application), */
590xA1, 0x02, /* Collection (Logical), */
600x95, 0x01, /* Report Count (1), */
610x75, 0x0E, /* Report Size (14), */
620x14, /* Logical Minimum (0), */
630x26, 0xFF, 0x3F, /* Logical Maximum (16383), */
640x34, /* Physical Minimum (0), */
650x46, 0xFF, 0x3F, /* Physical Maximum (16383), */
660x09, 0x30, /* Usage (X), */
670x81, 0x02, /* Input (Variable), */
680x95, 0x0E, /* Report Count (14), */
690x75, 0x01, /* Report Size (1), */
700x25, 0x01, /* Logical Maximum (1), */
710x45, 0x01, /* Physical Maximum (1), */
720x05, 0x09, /* Usage Page (Button), */
730x19, 0x01, /* Usage Minimum (01h), */
740x29, 0x0E, /* Usage Maximum (0Eh), */
750x81, 0x02, /* Input (Variable), */
760x05, 0x01, /* Usage Page (Desktop), */
770x95, 0x01, /* Report Count (1), */
780x75, 0x04, /* Report Size (4), */
790x25, 0x07, /* Logical Maximum (7), */
800x46, 0x3B, 0x01, /* Physical Maximum (315), */
810x65, 0x14, /* Unit (Degrees), */
820x09, 0x39, /* Usage (Hat Switch), */
830x81, 0x42, /* Input (Variable, Nullstate), */
840x65, 0x00, /* Unit, */
850x26, 0xFF, 0x00, /* Logical Maximum (255), */
860x46, 0xFF, 0x00, /* Physical Maximum (255), */
870x75, 0x08, /* Report Size (8), */
880x81, 0x01, /* Input (Constant), */
890x09, 0x31, /* Usage (Y), */
900x81, 0x02, /* Input (Variable), */
910x09, 0x35, /* Usage (Rz), */
920x81, 0x02, /* Input (Variable), */
930x81, 0x01, /* Input (Constant), */
940xC0, /* End Collection, */
950xA1, 0x02, /* Collection (Logical), */
960x09, 0x02, /* Usage (02h), */
970x95, 0x07, /* Report Count (7), */
980x91, 0x02, /* Output (Variable), */
990xC0, /* End Collection, */
1000xC0 /* End Collection */
101};
102
103
44/* 104/*
45 * Certain Logitech keyboards send in report #3 keys which are far 105 * Certain Logitech keyboards send in report #3 keys which are far
46 * above the logical maximum described in descriptor. This extends 106 * above the logical maximum described in descriptor. This extends
@@ -74,6 +134,18 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
74 rdesc[47] = 0x95; 134 rdesc[47] = 0x95;
75 rdesc[48] = 0x0B; 135 rdesc[48] = 0x0B;
76 } 136 }
137
138 switch (hdev->product) {
139 case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
140 if (*rsize == DFP_RDESC_ORIG_SIZE) {
141 hid_info(hdev,
142 "fixing up Logitech Driving Force Pro report descriptor\n");
143 rdesc = dfp_rdesc_fixed;
144 *rsize = sizeof(dfp_rdesc_fixed);
145 }
146 break;
147 }
148
77 return rdesc; 149 return rdesc;
78} 150}
79 151
@@ -380,7 +452,7 @@ static const struct hid_device_id lg_devices[] = {
380 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL), 452 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL),
381 .driver_data = LG_FF }, 453 .driver_data = LG_FF },
382 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL), 454 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL),
383 .driver_data = LG_FF }, 455 .driver_data = LG_NOGET | LG_FF },
384 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL), 456 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL),
385 .driver_data = LG_FF4 }, 457 .driver_data = LG_FF4 },
386 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ), 458 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ),
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 0ec91c18a42..08f5dc77397 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -81,6 +81,28 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
81#define NO_TOUCHES -1 81#define NO_TOUCHES -1
82#define SINGLE_TOUCH_UP -2 82#define SINGLE_TOUCH_UP -2
83 83
84/* Touch surface information. Dimension is in hundredths of a mm, min and max
85 * are in units. */
86#define MOUSE_DIMENSION_X (float)9056
87#define MOUSE_MIN_X -1100
88#define MOUSE_MAX_X 1258
89#define MOUSE_RES_X ((MOUSE_MAX_X - MOUSE_MIN_X) / (MOUSE_DIMENSION_X / 100))
90#define MOUSE_DIMENSION_Y (float)5152
91#define MOUSE_MIN_Y -1589
92#define MOUSE_MAX_Y 2047
93#define MOUSE_RES_Y ((MOUSE_MAX_Y - MOUSE_MIN_Y) / (MOUSE_DIMENSION_Y / 100))
94
95#define TRACKPAD_DIMENSION_X (float)13000
96#define TRACKPAD_MIN_X -2909
97#define TRACKPAD_MAX_X 3167
98#define TRACKPAD_RES_X \
99 ((TRACKPAD_MAX_X - TRACKPAD_MIN_X) / (TRACKPAD_DIMENSION_X / 100))
100#define TRACKPAD_DIMENSION_Y (float)11000
101#define TRACKPAD_MIN_Y -2456
102#define TRACKPAD_MAX_Y 2565
103#define TRACKPAD_RES_Y \
104 ((TRACKPAD_MAX_Y - TRACKPAD_MIN_Y) / (TRACKPAD_DIMENSION_Y / 100))
105
84/** 106/**
85 * struct magicmouse_sc - Tracks Magic Mouse-specific data. 107 * struct magicmouse_sc - Tracks Magic Mouse-specific data.
86 * @input: Input device through which we report events. 108 * @input: Input device through which we report events.
@@ -365,8 +387,10 @@ static int magicmouse_raw_event(struct hid_device *hdev,
365 return 1; 387 return 1;
366} 388}
367 389
368static void magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev) 390static int magicmouse_setup_input(struct hid_device *hdev, struct hid_input *hi)
369{ 391{
392 struct input_dev *input = hi->input;
393
370 __set_bit(EV_KEY, input->evbit); 394 __set_bit(EV_KEY, input->evbit);
371 395
372 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { 396 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
@@ -406,17 +430,31 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
406 * inverse of the reported Y. 430 * inverse of the reported Y.
407 */ 431 */
408 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { 432 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
409 input_set_abs_params(input, ABS_MT_POSITION_X, -1100, 433 input_set_abs_params(input, ABS_MT_POSITION_X,
410 1358, 4, 0); 434 MOUSE_MIN_X, MOUSE_MAX_X, 4, 0);
411 input_set_abs_params(input, ABS_MT_POSITION_Y, -1589, 435 input_set_abs_params(input, ABS_MT_POSITION_Y,
412 2047, 4, 0); 436 MOUSE_MIN_Y, MOUSE_MAX_Y, 4, 0);
437
438 input_abs_set_res(input, ABS_MT_POSITION_X,
439 MOUSE_RES_X);
440 input_abs_set_res(input, ABS_MT_POSITION_Y,
441 MOUSE_RES_Y);
413 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ 442 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
414 input_set_abs_params(input, ABS_X, -2909, 3167, 4, 0); 443 input_set_abs_params(input, ABS_X, TRACKPAD_MIN_X,
415 input_set_abs_params(input, ABS_Y, -2456, 2565, 4, 0); 444 TRACKPAD_MAX_X, 4, 0);
416 input_set_abs_params(input, ABS_MT_POSITION_X, -2909, 445 input_set_abs_params(input, ABS_Y, TRACKPAD_MIN_Y,
417 3167, 4, 0); 446 TRACKPAD_MAX_Y, 4, 0);
418 input_set_abs_params(input, ABS_MT_POSITION_Y, -2456, 447 input_set_abs_params(input, ABS_MT_POSITION_X,
419 2565, 4, 0); 448 TRACKPAD_MIN_X, TRACKPAD_MAX_X, 4, 0);
449 input_set_abs_params(input, ABS_MT_POSITION_Y,
450 TRACKPAD_MIN_Y, TRACKPAD_MAX_Y, 4, 0);
451
452 input_abs_set_res(input, ABS_X, TRACKPAD_RES_X);
453 input_abs_set_res(input, ABS_Y, TRACKPAD_RES_Y);
454 input_abs_set_res(input, ABS_MT_POSITION_X,
455 TRACKPAD_RES_X);
456 input_abs_set_res(input, ABS_MT_POSITION_Y,
457 TRACKPAD_RES_Y);
420 } 458 }
421 459
422 input_set_events_per_packet(input, 60); 460 input_set_events_per_packet(input, 60);
@@ -426,6 +464,8 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
426 __set_bit(EV_MSC, input->evbit); 464 __set_bit(EV_MSC, input->evbit);
427 __set_bit(MSC_RAW, input->mscbit); 465 __set_bit(MSC_RAW, input->mscbit);
428 } 466 }
467
468 return 0;
429} 469}
430 470
431static int magicmouse_input_mapping(struct hid_device *hdev, 471static int magicmouse_input_mapping(struct hid_device *hdev,
@@ -478,12 +518,6 @@ static int magicmouse_probe(struct hid_device *hdev,
478 goto err_free; 518 goto err_free;
479 } 519 }
480 520
481 /* We do this after hid-input is done parsing reports so that
482 * hid-input uses the most natural button and axis IDs.
483 */
484 if (msc->input)
485 magicmouse_setup_input(msc->input, hdev);
486
487 if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE) 521 if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
488 report = hid_register_report(hdev, HID_INPUT_REPORT, 522 report = hid_register_report(hdev, HID_INPUT_REPORT,
489 MOUSE_REPORT_ID); 523 MOUSE_REPORT_ID);
@@ -501,9 +535,17 @@ static int magicmouse_probe(struct hid_device *hdev,
501 } 535 }
502 report->size = 6; 536 report->size = 6;
503 537
538 /*
539 * Some devices repond with 'invalid report id' when feature
540 * report switching it into multitouch mode is sent to it.
541 *
542 * This results in -EIO from the _raw low-level transport callback,
543 * but there seems to be no other way of switching the mode.
544 * Thus the super-ugly hacky success check below.
545 */
504 ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature), 546 ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature),
505 HID_FEATURE_REPORT); 547 HID_FEATURE_REPORT);
506 if (ret != sizeof(feature)) { 548 if (ret != -EIO && ret != sizeof(feature)) {
507 hid_err(hdev, "unable to request touch data (%d)\n", ret); 549 hid_err(hdev, "unable to request touch data (%d)\n", ret);
508 goto err_stop_hw; 550 goto err_stop_hw;
509 } 551 }
@@ -540,6 +582,7 @@ static struct hid_driver magicmouse_driver = {
540 .remove = magicmouse_remove, 582 .remove = magicmouse_remove,
541 .raw_event = magicmouse_raw_event, 583 .raw_event = magicmouse_raw_event,
542 .input_mapping = magicmouse_input_mapping, 584 .input_mapping = magicmouse_input_mapping,
585 .input_register = magicmouse_setup_input,
543}; 586};
544 587
545static int __init magicmouse_init(void) 588static int __init magicmouse_init(void)
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 0f6fc54dc19..e5c699b6c6f 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -23,11 +23,12 @@
23 23
24#include "hid-ids.h" 24#include "hid-ids.h"
25 25
26#define MS_HIDINPUT 0x01 26#define MS_HIDINPUT 0x01
27#define MS_ERGONOMY 0x02 27#define MS_ERGONOMY 0x02
28#define MS_PRESENTER 0x04 28#define MS_PRESENTER 0x04
29#define MS_RDESC 0x08 29#define MS_RDESC 0x08
30#define MS_NOGET 0x10 30#define MS_NOGET 0x10
31#define MS_DUPLICATE_USAGES 0x20
31 32
32/* 33/*
33 * Microsoft Wireless Desktop Receiver (Model 1028) has 34 * Microsoft Wireless Desktop Receiver (Model 1028) has
@@ -109,6 +110,18 @@ static int ms_input_mapping(struct hid_device *hdev, struct hid_input *hi,
109 return 0; 110 return 0;
110} 111}
111 112
113static int ms_input_mapped(struct hid_device *hdev, struct hid_input *hi,
114 struct hid_field *field, struct hid_usage *usage,
115 unsigned long **bit, int *max)
116{
117 unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
118
119 if (quirks & MS_DUPLICATE_USAGES)
120 clear_bit(usage->code, *bit);
121
122 return 0;
123}
124
112static int ms_event(struct hid_device *hdev, struct hid_field *field, 125static int ms_event(struct hid_device *hdev, struct hid_field *field,
113 struct hid_usage *usage, __s32 value) 126 struct hid_usage *usage, __s32 value)
114{ 127{
@@ -179,8 +192,12 @@ static const struct hid_device_id ms_devices[] = {
179 .driver_data = MS_ERGONOMY | MS_RDESC }, 192 .driver_data = MS_ERGONOMY | MS_RDESC },
180 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB), 193 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB),
181 .driver_data = MS_PRESENTER }, 194 .driver_data = MS_PRESENTER },
195 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K),
196 .driver_data = MS_ERGONOMY },
182 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0), 197 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0),
183 .driver_data = MS_NOGET }, 198 .driver_data = MS_NOGET },
199 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500),
200 .driver_data = MS_DUPLICATE_USAGES },
184 201
185 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT), 202 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT),
186 .driver_data = MS_PRESENTER }, 203 .driver_data = MS_PRESENTER },
@@ -193,6 +210,7 @@ static struct hid_driver ms_driver = {
193 .id_table = ms_devices, 210 .id_table = ms_devices,
194 .report_fixup = ms_report_fixup, 211 .report_fixup = ms_report_fixup,
195 .input_mapping = ms_input_mapping, 212 .input_mapping = ms_input_mapping,
213 .input_mapped = ms_input_mapped,
196 .event = ms_event, 214 .event = ms_event,
197 .probe = ms_probe, 215 .probe = ms_probe,
198}; 216};
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 62cac4dc3b6..b03a0b0e9b6 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -213,6 +213,16 @@ static int mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
213 struct mt_class *cls = td->mtclass; 213 struct mt_class *cls = td->mtclass;
214 __s32 quirks = cls->quirks; 214 __s32 quirks = cls->quirks;
215 215
216 /* Only map fields from TouchScreen or TouchPad collections.
217 * We need to ignore fields that belong to other collections
218 * such as Mouse that might have the same GenericDesktop usages. */
219 if (field->application == HID_DG_TOUCHSCREEN)
220 set_bit(INPUT_PROP_DIRECT, hi->input->propbit);
221 else if (field->application == HID_DG_TOUCHPAD)
222 set_bit(INPUT_PROP_POINTER, hi->input->propbit);
223 else
224 return 0;
225
216 switch (usage->hid & HID_USAGE_PAGE) { 226 switch (usage->hid & HID_USAGE_PAGE) {
217 227
218 case HID_UP_GENDESK: 228 case HID_UP_GENDESK:
@@ -672,6 +682,11 @@ static const struct hid_device_id mt_devices[] = {
672 HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, 682 HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS,
673 USB_DEVICE_ID_IRTOUCH_INFRARED_USB) }, 683 USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
674 684
685 /* LG Display panels */
686 { .driver_data = MT_CLS_DEFAULT,
687 HID_USB_DEVICE(USB_VENDOR_ID_LG,
688 USB_DEVICE_ID_LG_MULTITOUCH) },
689
675 /* Lumio panels */ 690 /* Lumio panels */
676 { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, 691 { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
677 HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, 692 HID_USB_DEVICE(USB_VENDOR_ID_LUMIO,
@@ -727,6 +742,10 @@ static const struct hid_device_id mt_devices[] = {
727 { .driver_data = MT_CLS_DEFAULT, 742 { .driver_data = MT_CLS_DEFAULT,
728 HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, 743 HID_USB_DEVICE(USB_VENDOR_ID_UNITEC,
729 USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, 744 USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) },
745 /* XAT */
746 { .driver_data = MT_CLS_DEFAULT,
747 HID_USB_DEVICE(USB_VENDOR_ID_XAT,
748 USB_DEVICE_ID_XAT_CSR) },
730 749
731 { } 750 { }
732}; 751};
diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c
index ab19f2905d2..158b389d0fb 100644
--- a/drivers/hid/hid-prodikeys.c
+++ b/drivers/hid/hid-prodikeys.c
@@ -44,8 +44,6 @@ struct pk_device {
44 struct pcmidi_snd *pm; /* pcmidi device context */ 44 struct pcmidi_snd *pm; /* pcmidi device context */
45}; 45};
46 46
47struct pcmidi_snd;
48
49struct pcmidi_sustain { 47struct pcmidi_sustain {
50 unsigned long in_use; 48 unsigned long in_use;
51 struct pcmidi_snd *pm; 49 struct pcmidi_snd *pm;
@@ -242,7 +240,7 @@ drop_note:
242 return; 240 return;
243} 241}
244 242
245void pcmidi_sustained_note_release(unsigned long data) 243static void pcmidi_sustained_note_release(unsigned long data)
246{ 244{
247 struct pcmidi_sustain *pms = (struct pcmidi_sustain *)data; 245 struct pcmidi_sustain *pms = (struct pcmidi_sustain *)data;
248 246
@@ -250,7 +248,7 @@ void pcmidi_sustained_note_release(unsigned long data)
250 pms->in_use = 0; 248 pms->in_use = 0;
251} 249}
252 250
253void init_sustain_timers(struct pcmidi_snd *pm) 251static void init_sustain_timers(struct pcmidi_snd *pm)
254{ 252{
255 struct pcmidi_sustain *pms; 253 struct pcmidi_sustain *pms;
256 unsigned i; 254 unsigned i;
@@ -264,7 +262,7 @@ void init_sustain_timers(struct pcmidi_snd *pm)
264 } 262 }
265} 263}
266 264
267void stop_sustain_timers(struct pcmidi_snd *pm) 265static void stop_sustain_timers(struct pcmidi_snd *pm)
268{ 266{
269 struct pcmidi_sustain *pms; 267 struct pcmidi_sustain *pms;
270 unsigned i; 268 unsigned i;
@@ -499,7 +497,7 @@ static int pcmidi_handle_report4(struct pcmidi_snd *pm, u8 *data)
499 return 1; 497 return 1;
500} 498}
501 499
502int pcmidi_handle_report( 500static int pcmidi_handle_report(
503 struct pcmidi_snd *pm, unsigned report_id, u8 *data, int size) 501 struct pcmidi_snd *pm, unsigned report_id, u8 *data, int size)
504{ 502{
505 int ret = 0; 503 int ret = 0;
@@ -518,7 +516,8 @@ int pcmidi_handle_report(
518 return ret; 516 return ret;
519} 517}
520 518
521void pcmidi_setup_extra_keys(struct pcmidi_snd *pm, struct input_dev *input) 519static void pcmidi_setup_extra_keys(
520 struct pcmidi_snd *pm, struct input_dev *input)
522{ 521{
523 /* reassigned functionality for N/A keys 522 /* reassigned functionality for N/A keys
524 MY PICTURES => KEY_WORDPROCESSOR 523 MY PICTURES => KEY_WORDPROCESSOR
@@ -602,7 +601,7 @@ static struct snd_rawmidi_ops pcmidi_in_ops = {
602 .trigger = pcmidi_in_trigger 601 .trigger = pcmidi_in_trigger
603}; 602};
604 603
605int pcmidi_snd_initialise(struct pcmidi_snd *pm) 604static int pcmidi_snd_initialise(struct pcmidi_snd *pm)
606{ 605{
607 static int dev; 606 static int dev;
608 struct snd_card *card; 607 struct snd_card *card;
@@ -720,7 +719,7 @@ fail:
720 return err; 719 return err;
721} 720}
722 721
723int pcmidi_snd_terminate(struct pcmidi_snd *pm) 722static int pcmidi_snd_terminate(struct pcmidi_snd *pm)
724{ 723{
725 if (pm->card) { 724 if (pm->card) {
726 stop_sustain_timers(pm); 725 stop_sustain_timers(pm);
diff --git a/drivers/hid/hid-roccat-arvo.c b/drivers/hid/hid-roccat-arvo.c
index 2307471d96d..093bfad00b0 100644
--- a/drivers/hid/hid-roccat-arvo.c
+++ b/drivers/hid/hid-roccat-arvo.c
@@ -39,7 +39,7 @@ static ssize_t arvo_sysfs_show_mode_key(struct device *dev,
39 int retval; 39 int retval;
40 40
41 mutex_lock(&arvo->arvo_lock); 41 mutex_lock(&arvo->arvo_lock);
42 retval = roccat_common_receive(usb_dev, ARVO_USB_COMMAND_MODE_KEY, 42 retval = roccat_common_receive(usb_dev, ARVO_COMMAND_MODE_KEY,
43 &temp_buf, sizeof(struct arvo_mode_key)); 43 &temp_buf, sizeof(struct arvo_mode_key));
44 mutex_unlock(&arvo->arvo_lock); 44 mutex_unlock(&arvo->arvo_lock);
45 if (retval) 45 if (retval)
@@ -67,7 +67,7 @@ static ssize_t arvo_sysfs_set_mode_key(struct device *dev,
67 temp_buf.state = state; 67 temp_buf.state = state;
68 68
69 mutex_lock(&arvo->arvo_lock); 69 mutex_lock(&arvo->arvo_lock);
70 retval = roccat_common_send(usb_dev, ARVO_USB_COMMAND_MODE_KEY, 70 retval = roccat_common_send(usb_dev, ARVO_COMMAND_MODE_KEY,
71 &temp_buf, sizeof(struct arvo_mode_key)); 71 &temp_buf, sizeof(struct arvo_mode_key));
72 mutex_unlock(&arvo->arvo_lock); 72 mutex_unlock(&arvo->arvo_lock);
73 if (retval) 73 if (retval)
@@ -87,7 +87,7 @@ static ssize_t arvo_sysfs_show_key_mask(struct device *dev,
87 int retval; 87 int retval;
88 88
89 mutex_lock(&arvo->arvo_lock); 89 mutex_lock(&arvo->arvo_lock);
90 retval = roccat_common_receive(usb_dev, ARVO_USB_COMMAND_KEY_MASK, 90 retval = roccat_common_receive(usb_dev, ARVO_COMMAND_KEY_MASK,
91 &temp_buf, sizeof(struct arvo_key_mask)); 91 &temp_buf, sizeof(struct arvo_key_mask));
92 mutex_unlock(&arvo->arvo_lock); 92 mutex_unlock(&arvo->arvo_lock);
93 if (retval) 93 if (retval)
@@ -115,7 +115,7 @@ static ssize_t arvo_sysfs_set_key_mask(struct device *dev,
115 temp_buf.key_mask = key_mask; 115 temp_buf.key_mask = key_mask;
116 116
117 mutex_lock(&arvo->arvo_lock); 117 mutex_lock(&arvo->arvo_lock);
118 retval = roccat_common_send(usb_dev, ARVO_USB_COMMAND_KEY_MASK, 118 retval = roccat_common_send(usb_dev, ARVO_COMMAND_KEY_MASK,
119 &temp_buf, sizeof(struct arvo_key_mask)); 119 &temp_buf, sizeof(struct arvo_key_mask));
120 mutex_unlock(&arvo->arvo_lock); 120 mutex_unlock(&arvo->arvo_lock);
121 if (retval) 121 if (retval)
@@ -130,7 +130,7 @@ static int arvo_get_actual_profile(struct usb_device *usb_dev)
130 struct arvo_actual_profile temp_buf; 130 struct arvo_actual_profile temp_buf;
131 int retval; 131 int retval;
132 132
133 retval = roccat_common_receive(usb_dev, ARVO_USB_COMMAND_ACTUAL_PROFILE, 133 retval = roccat_common_receive(usb_dev, ARVO_COMMAND_ACTUAL_PROFILE,
134 &temp_buf, sizeof(struct arvo_actual_profile)); 134 &temp_buf, sizeof(struct arvo_actual_profile));
135 135
136 if (retval) 136 if (retval)
@@ -163,11 +163,14 @@ static ssize_t arvo_sysfs_set_actual_profile(struct device *dev,
163 if (retval) 163 if (retval)
164 return retval; 164 return retval;
165 165
166 if (profile < 1 || profile > 5)
167 return -EINVAL;
168
166 temp_buf.command = ARVO_COMMAND_ACTUAL_PROFILE; 169 temp_buf.command = ARVO_COMMAND_ACTUAL_PROFILE;
167 temp_buf.actual_profile = profile; 170 temp_buf.actual_profile = profile;
168 171
169 mutex_lock(&arvo->arvo_lock); 172 mutex_lock(&arvo->arvo_lock);
170 retval = roccat_common_send(usb_dev, ARVO_USB_COMMAND_ACTUAL_PROFILE, 173 retval = roccat_common_send(usb_dev, ARVO_COMMAND_ACTUAL_PROFILE,
171 &temp_buf, sizeof(struct arvo_actual_profile)); 174 &temp_buf, sizeof(struct arvo_actual_profile));
172 if (!retval) { 175 if (!retval) {
173 arvo->actual_profile = profile; 176 arvo->actual_profile = profile;
@@ -225,7 +228,7 @@ static ssize_t arvo_sysfs_write_button(struct file *fp,
225 loff_t off, size_t count) 228 loff_t off, size_t count)
226{ 229{
227 return arvo_sysfs_write(fp, kobj, buf, off, count, 230 return arvo_sysfs_write(fp, kobj, buf, off, count,
228 sizeof(struct arvo_button), ARVO_USB_COMMAND_BUTTON); 231 sizeof(struct arvo_button), ARVO_COMMAND_BUTTON);
229} 232}
230 233
231static ssize_t arvo_sysfs_read_info(struct file *fp, 234static ssize_t arvo_sysfs_read_info(struct file *fp,
@@ -233,7 +236,7 @@ static ssize_t arvo_sysfs_read_info(struct file *fp,
233 loff_t off, size_t count) 236 loff_t off, size_t count)
234{ 237{
235 return arvo_sysfs_read(fp, kobj, buf, off, count, 238 return arvo_sysfs_read(fp, kobj, buf, off, count,
236 sizeof(struct arvo_info), ARVO_USB_COMMAND_INFO); 239 sizeof(struct arvo_info), ARVO_COMMAND_INFO);
237} 240}
238 241
239 242
@@ -399,7 +402,7 @@ static int arvo_raw_event(struct hid_device *hdev,
399 if (size != 3) 402 if (size != 3)
400 return 0; 403 return 0;
401 404
402 if (arvo->roccat_claimed) 405 if (arvo && arvo->roccat_claimed)
403 arvo_report_to_chrdev(arvo, data); 406 arvo_report_to_chrdev(arvo, data);
404 407
405 return 0; 408 return 0;
diff --git a/drivers/hid/hid-roccat-arvo.h b/drivers/hid/hid-roccat-arvo.h
index d284a781c99..ce8415e4f00 100644
--- a/drivers/hid/hid-roccat-arvo.h
+++ b/drivers/hid/hid-roccat-arvo.h
@@ -46,19 +46,6 @@ enum arvo_commands {
46 ARVO_COMMAND_ACTUAL_PROFILE = 0x7, 46 ARVO_COMMAND_ACTUAL_PROFILE = 0x7,
47}; 47};
48 48
49enum arvo_usb_commands {
50 ARVO_USB_COMMAND_MODE_KEY = 0x303,
51 /*
52 * read/write
53 * Read uses both index bytes as profile/key indexes
54 * Write has index 0, profile/key is determined by payload
55 */
56 ARVO_USB_COMMAND_BUTTON = 0x304,
57 ARVO_USB_COMMAND_INFO = 0x305,
58 ARVO_USB_COMMAND_KEY_MASK = 0x306,
59 ARVO_USB_COMMAND_ACTUAL_PROFILE = 0x307,
60};
61
62struct arvo_special_report { 49struct arvo_special_report {
63 uint8_t unknown1; /* always 0x01 */ 50 uint8_t unknown1; /* always 0x01 */
64 uint8_t event; 51 uint8_t event;
diff --git a/drivers/hid/hid-roccat-common.c b/drivers/hid/hid-roccat-common.c
index 13b1eb0c8c6..edf898dee28 100644
--- a/drivers/hid/hid-roccat-common.c
+++ b/drivers/hid/hid-roccat-common.c
@@ -11,10 +11,16 @@
11 * any later version. 11 * any later version.
12 */ 12 */
13 13
14#include <linux/hid.h>
14#include <linux/slab.h> 15#include <linux/slab.h>
15#include "hid-roccat-common.h" 16#include "hid-roccat-common.h"
16 17
17int roccat_common_receive(struct usb_device *usb_dev, uint usb_command, 18static inline uint16_t roccat_common_feature_report(uint8_t report_id)
19{
20 return 0x300 | report_id;
21}
22
23int roccat_common_receive(struct usb_device *usb_dev, uint report_id,
18 void *data, uint size) 24 void *data, uint size)
19{ 25{
20 char *buf; 26 char *buf;
@@ -25,9 +31,10 @@ int roccat_common_receive(struct usb_device *usb_dev, uint usb_command,
25 return -ENOMEM; 31 return -ENOMEM;
26 32
27 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 33 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
28 USB_REQ_CLEAR_FEATURE, 34 HID_REQ_GET_REPORT,
29 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 35 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
30 usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT); 36 roccat_common_feature_report(report_id),
37 0, buf, size, USB_CTRL_SET_TIMEOUT);
31 38
32 memcpy(data, buf, size); 39 memcpy(data, buf, size);
33 kfree(buf); 40 kfree(buf);
@@ -35,7 +42,7 @@ int roccat_common_receive(struct usb_device *usb_dev, uint usb_command,
35} 42}
36EXPORT_SYMBOL_GPL(roccat_common_receive); 43EXPORT_SYMBOL_GPL(roccat_common_receive);
37 44
38int roccat_common_send(struct usb_device *usb_dev, uint usb_command, 45int roccat_common_send(struct usb_device *usb_dev, uint report_id,
39 void const *data, uint size) 46 void const *data, uint size)
40{ 47{
41 char *buf; 48 char *buf;
@@ -48,9 +55,10 @@ int roccat_common_send(struct usb_device *usb_dev, uint usb_command,
48 memcpy(buf, data, size); 55 memcpy(buf, data, size);
49 56
50 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 57 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
51 USB_REQ_SET_CONFIGURATION, 58 HID_REQ_SET_REPORT,
52 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, 59 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
53 usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT); 60 roccat_common_feature_report(report_id),
61 0, buf, size, USB_CTRL_SET_TIMEOUT);
54 62
55 kfree(buf); 63 kfree(buf);
56 return ((len < 0) ? len : ((len != size) ? -EIO : 0)); 64 return ((len < 0) ? len : ((len != size) ? -EIO : 0));
diff --git a/drivers/hid/hid-roccat-common.h b/drivers/hid/hid-roccat-common.h
index fe45fae05bb..9a5bc61f969 100644
--- a/drivers/hid/hid-roccat-common.h
+++ b/drivers/hid/hid-roccat-common.h
@@ -15,9 +15,9 @@
15#include <linux/usb.h> 15#include <linux/usb.h>
16#include <linux/types.h> 16#include <linux/types.h>
17 17
18int roccat_common_receive(struct usb_device *usb_dev, uint usb_command, 18int roccat_common_receive(struct usb_device *usb_dev, uint report_id,
19 void *data, uint size); 19 void *data, uint size);
20int roccat_common_send(struct usb_device *usb_dev, uint usb_command, 20int roccat_common_send(struct usb_device *usb_dev, uint report_id,
21 void const *data, uint size); 21 void const *data, uint size);
22 22
23#endif 23#endif
diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c
index a57838d1526..2b8f3a31ffb 100644
--- a/drivers/hid/hid-roccat-kone.c
+++ b/drivers/hid/hid-roccat-kone.c
@@ -37,6 +37,47 @@
37 37
38static uint profile_numbers[5] = {0, 1, 2, 3, 4}; 38static uint profile_numbers[5] = {0, 1, 2, 3, 4};
39 39
40static int kone_receive(struct usb_device *usb_dev, uint usb_command,
41 void *data, uint size)
42{
43 char *buf;
44 int len;
45
46 buf = kmalloc(size, GFP_KERNEL);
47 if (buf == NULL)
48 return -ENOMEM;
49
50 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
51 HID_REQ_GET_REPORT,
52 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
53 usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
54
55 memcpy(data, buf, size);
56 kfree(buf);
57 return ((len < 0) ? len : ((len != size) ? -EIO : 0));
58}
59
60static int kone_send(struct usb_device *usb_dev, uint usb_command,
61 void const *data, uint size)
62{
63 char *buf;
64 int len;
65
66 buf = kmalloc(size, GFP_KERNEL);
67 if (buf == NULL)
68 return -ENOMEM;
69
70 memcpy(buf, data, size);
71
72 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
73 HID_REQ_SET_REPORT,
74 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
75 usb_command, 0, buf, size, USB_CTRL_SET_TIMEOUT);
76
77 kfree(buf);
78 return ((len < 0) ? len : ((len != size) ? -EIO : 0));
79}
80
40/* kone_class is used for creating sysfs attributes via roccat char device */ 81/* kone_class is used for creating sysfs attributes via roccat char device */
41static struct class *kone_class; 82static struct class *kone_class;
42 83
@@ -68,7 +109,7 @@ static int kone_check_write(struct usb_device *usb_dev)
68 */ 109 */
69 msleep(80); 110 msleep(80);
70 111
71 retval = roccat_common_receive(usb_dev, 112 retval = kone_receive(usb_dev,
72 kone_command_confirm_write, &data, 1); 113 kone_command_confirm_write, &data, 1);
73 if (retval) 114 if (retval)
74 return retval; 115 return retval;
@@ -96,7 +137,7 @@ static int kone_check_write(struct usb_device *usb_dev)
96static int kone_get_settings(struct usb_device *usb_dev, 137static int kone_get_settings(struct usb_device *usb_dev,
97 struct kone_settings *buf) 138 struct kone_settings *buf)
98{ 139{
99 return roccat_common_receive(usb_dev, kone_command_settings, buf, 140 return kone_receive(usb_dev, kone_command_settings, buf,
100 sizeof(struct kone_settings)); 141 sizeof(struct kone_settings));
101} 142}
102 143
@@ -109,7 +150,7 @@ static int kone_set_settings(struct usb_device *usb_dev,
109 struct kone_settings const *settings) 150 struct kone_settings const *settings)
110{ 151{
111 int retval; 152 int retval;
112 retval = roccat_common_send(usb_dev, kone_command_settings, 153 retval = kone_send(usb_dev, kone_command_settings,
113 settings, sizeof(struct kone_settings)); 154 settings, sizeof(struct kone_settings));
114 if (retval) 155 if (retval)
115 return retval; 156 return retval;
@@ -182,7 +223,7 @@ static int kone_get_weight(struct usb_device *usb_dev, int *result)
182 int retval; 223 int retval;
183 uint8_t data; 224 uint8_t data;
184 225
185 retval = roccat_common_receive(usb_dev, kone_command_weight, &data, 1); 226 retval = kone_receive(usb_dev, kone_command_weight, &data, 1);
186 227
187 if (retval) 228 if (retval)
188 return retval; 229 return retval;
@@ -201,7 +242,7 @@ static int kone_get_firmware_version(struct usb_device *usb_dev, int *result)
201 int retval; 242 int retval;
202 uint16_t data; 243 uint16_t data;
203 244
204 retval = roccat_common_receive(usb_dev, kone_command_firmware_version, 245 retval = kone_receive(usb_dev, kone_command_firmware_version,
205 &data, 2); 246 &data, 2);
206 if (retval) 247 if (retval)
207 return retval; 248 return retval;
@@ -384,7 +425,7 @@ static int kone_tcu_command(struct usb_device *usb_dev, int number)
384{ 425{
385 unsigned char value; 426 unsigned char value;
386 value = number; 427 value = number;
387 return roccat_common_send(usb_dev, kone_command_calibrate, &value, 1); 428 return kone_send(usb_dev, kone_command_calibrate, &value, 1);
388} 429}
389 430
390/* 431/*
@@ -791,6 +832,9 @@ static int kone_raw_event(struct hid_device *hdev, struct hid_report *report,
791 if (size != sizeof(struct kone_mouse_event)) 832 if (size != sizeof(struct kone_mouse_event))
792 return 0; 833 return 0;
793 834
835 if (kone == NULL)
836 return 0;
837
794 /* 838 /*
795 * Firmware 1.38 introduced new behaviour for tilt and special buttons. 839 * Firmware 1.38 introduced new behaviour for tilt and special buttons.
796 * Pressed button is reported in each movement event. 840 * Pressed button is reported in each movement event.
diff --git a/drivers/hid/hid-roccat-kone.h b/drivers/hid/hid-roccat-kone.h
index 4109a028e13..64abb5b8a59 100644
--- a/drivers/hid/hid-roccat-kone.h
+++ b/drivers/hid/hid-roccat-kone.h
@@ -166,7 +166,7 @@ enum kone_mouse_events {
166 /* osd events are thought to be display on screen */ 166 /* osd events are thought to be display on screen */
167 kone_mouse_event_osd_dpi = 0xa0, 167 kone_mouse_event_osd_dpi = 0xa0,
168 kone_mouse_event_osd_profile = 0xb0, 168 kone_mouse_event_osd_profile = 0xb0,
169 /* TODO clarify meaning and occurrence of kone_mouse_event_calibration */ 169 /* TODO clarify meaning and occurence of kone_mouse_event_calibration */
170 kone_mouse_event_calibration = 0xc0, 170 kone_mouse_event_calibration = 0xc0,
171 kone_mouse_event_call_overlong_macro = 0xe0, 171 kone_mouse_event_call_overlong_macro = 0xe0,
172 /* switch events notify if user changed values with mousebutton click */ 172 /* switch events notify if user changed values with mousebutton click */
diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c
index 5b640a7a15a..59e47770fa1 100644
--- a/drivers/hid/hid-roccat-koneplus.c
+++ b/drivers/hid/hid-roccat-koneplus.c
@@ -50,7 +50,7 @@ static int koneplus_send_control(struct usb_device *usb_dev, uint value,
50 control.value = value; 50 control.value = value;
51 control.request = request; 51 control.request = request;
52 52
53 return roccat_common_send(usb_dev, KONEPLUS_USB_COMMAND_CONTROL, 53 return roccat_common_send(usb_dev, KONEPLUS_COMMAND_CONTROL,
54 &control, sizeof(struct koneplus_control)); 54 &control, sizeof(struct koneplus_control));
55} 55}
56 56
@@ -60,7 +60,7 @@ static int koneplus_receive_control_status(struct usb_device *usb_dev)
60 struct koneplus_control control; 60 struct koneplus_control control;
61 61
62 do { 62 do {
63 retval = roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_CONTROL, 63 retval = roccat_common_receive(usb_dev, KONEPLUS_COMMAND_CONTROL,
64 &control, sizeof(struct koneplus_control)); 64 &control, sizeof(struct koneplus_control));
65 65
66 /* check if we get a completely wrong answer */ 66 /* check if we get a completely wrong answer */
@@ -120,7 +120,7 @@ static int koneplus_select_profile(struct usb_device *usb_dev, uint number,
120static int koneplus_get_info(struct usb_device *usb_dev, 120static int koneplus_get_info(struct usb_device *usb_dev,
121 struct koneplus_info *buf) 121 struct koneplus_info *buf)
122{ 122{
123 return roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_INFO, 123 return roccat_common_receive(usb_dev, KONEPLUS_COMMAND_INFO,
124 buf, sizeof(struct koneplus_info)); 124 buf, sizeof(struct koneplus_info));
125} 125}
126 126
@@ -134,14 +134,14 @@ static int koneplus_get_profile_settings(struct usb_device *usb_dev,
134 if (retval) 134 if (retval)
135 return retval; 135 return retval;
136 136
137 return roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_SETTINGS, 137 return roccat_common_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_SETTINGS,
138 buf, sizeof(struct koneplus_profile_settings)); 138 buf, sizeof(struct koneplus_profile_settings));
139} 139}
140 140
141static int koneplus_set_profile_settings(struct usb_device *usb_dev, 141static int koneplus_set_profile_settings(struct usb_device *usb_dev,
142 struct koneplus_profile_settings const *settings) 142 struct koneplus_profile_settings const *settings)
143{ 143{
144 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_SETTINGS, 144 return koneplus_send(usb_dev, KONEPLUS_COMMAND_PROFILE_SETTINGS,
145 settings, sizeof(struct koneplus_profile_settings)); 145 settings, sizeof(struct koneplus_profile_settings));
146} 146}
147 147
@@ -155,14 +155,14 @@ static int koneplus_get_profile_buttons(struct usb_device *usb_dev,
155 if (retval) 155 if (retval)
156 return retval; 156 return retval;
157 157
158 return roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_BUTTONS, 158 return roccat_common_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_BUTTONS,
159 buf, sizeof(struct koneplus_profile_buttons)); 159 buf, sizeof(struct koneplus_profile_buttons));
160} 160}
161 161
162static int koneplus_set_profile_buttons(struct usb_device *usb_dev, 162static int koneplus_set_profile_buttons(struct usb_device *usb_dev,
163 struct koneplus_profile_buttons const *buttons) 163 struct koneplus_profile_buttons const *buttons)
164{ 164{
165 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_PROFILE_BUTTONS, 165 return koneplus_send(usb_dev, KONEPLUS_COMMAND_PROFILE_BUTTONS,
166 buttons, sizeof(struct koneplus_profile_buttons)); 166 buttons, sizeof(struct koneplus_profile_buttons));
167} 167}
168 168
@@ -172,7 +172,7 @@ static int koneplus_get_actual_profile(struct usb_device *usb_dev)
172 struct koneplus_actual_profile buf; 172 struct koneplus_actual_profile buf;
173 int retval; 173 int retval;
174 174
175 retval = roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_ACTUAL_PROFILE, 175 retval = roccat_common_receive(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE,
176 &buf, sizeof(struct koneplus_actual_profile)); 176 &buf, sizeof(struct koneplus_actual_profile));
177 177
178 return retval ? retval : buf.actual_profile; 178 return retval ? retval : buf.actual_profile;
@@ -187,7 +187,7 @@ static int koneplus_set_actual_profile(struct usb_device *usb_dev,
187 buf.size = sizeof(struct koneplus_actual_profile); 187 buf.size = sizeof(struct koneplus_actual_profile);
188 buf.actual_profile = new_profile; 188 buf.actual_profile = new_profile;
189 189
190 return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_ACTUAL_PROFILE, 190 return koneplus_send(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE,
191 &buf, sizeof(struct koneplus_actual_profile)); 191 &buf, sizeof(struct koneplus_actual_profile));
192} 192}
193 193
@@ -240,12 +240,20 @@ static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj,
240 return real_size; 240 return real_size;
241} 241}
242 242
243static ssize_t koneplus_sysfs_write_talk(struct file *fp,
244 struct kobject *kobj, struct bin_attribute *attr, char *buf,
245 loff_t off, size_t count)
246{
247 return koneplus_sysfs_write(fp, kobj, buf, off, count,
248 sizeof(struct koneplus_talk), KONEPLUS_COMMAND_TALK);
249}
250
243static ssize_t koneplus_sysfs_write_macro(struct file *fp, 251static ssize_t koneplus_sysfs_write_macro(struct file *fp,
244 struct kobject *kobj, struct bin_attribute *attr, char *buf, 252 struct kobject *kobj, struct bin_attribute *attr, char *buf,
245 loff_t off, size_t count) 253 loff_t off, size_t count)
246{ 254{
247 return koneplus_sysfs_write(fp, kobj, buf, off, count, 255 return koneplus_sysfs_write(fp, kobj, buf, off, count,
248 sizeof(struct koneplus_macro), KONEPLUS_USB_COMMAND_MACRO); 256 sizeof(struct koneplus_macro), KONEPLUS_COMMAND_MACRO);
249} 257}
250 258
251static ssize_t koneplus_sysfs_read_sensor(struct file *fp, 259static ssize_t koneplus_sysfs_read_sensor(struct file *fp,
@@ -253,7 +261,7 @@ static ssize_t koneplus_sysfs_read_sensor(struct file *fp,
253 loff_t off, size_t count) 261 loff_t off, size_t count)
254{ 262{
255 return koneplus_sysfs_read(fp, kobj, buf, off, count, 263 return koneplus_sysfs_read(fp, kobj, buf, off, count,
256 sizeof(struct koneplus_sensor), KONEPLUS_USB_COMMAND_SENSOR); 264 sizeof(struct koneplus_sensor), KONEPLUS_COMMAND_SENSOR);
257} 265}
258 266
259static ssize_t koneplus_sysfs_write_sensor(struct file *fp, 267static ssize_t koneplus_sysfs_write_sensor(struct file *fp,
@@ -261,7 +269,7 @@ static ssize_t koneplus_sysfs_write_sensor(struct file *fp,
261 loff_t off, size_t count) 269 loff_t off, size_t count)
262{ 270{
263 return koneplus_sysfs_write(fp, kobj, buf, off, count, 271 return koneplus_sysfs_write(fp, kobj, buf, off, count,
264 sizeof(struct koneplus_sensor), KONEPLUS_USB_COMMAND_SENSOR); 272 sizeof(struct koneplus_sensor), KONEPLUS_COMMAND_SENSOR);
265} 273}
266 274
267static ssize_t koneplus_sysfs_write_tcu(struct file *fp, 275static ssize_t koneplus_sysfs_write_tcu(struct file *fp,
@@ -269,7 +277,7 @@ static ssize_t koneplus_sysfs_write_tcu(struct file *fp,
269 loff_t off, size_t count) 277 loff_t off, size_t count)
270{ 278{
271 return koneplus_sysfs_write(fp, kobj, buf, off, count, 279 return koneplus_sysfs_write(fp, kobj, buf, off, count,
272 sizeof(struct koneplus_tcu), KONEPLUS_USB_COMMAND_TCU); 280 sizeof(struct koneplus_tcu), KONEPLUS_COMMAND_TCU);
273} 281}
274 282
275static ssize_t koneplus_sysfs_read_tcu_image(struct file *fp, 283static ssize_t koneplus_sysfs_read_tcu_image(struct file *fp,
@@ -277,7 +285,7 @@ static ssize_t koneplus_sysfs_read_tcu_image(struct file *fp,
277 loff_t off, size_t count) 285 loff_t off, size_t count)
278{ 286{
279 return koneplus_sysfs_read(fp, kobj, buf, off, count, 287 return koneplus_sysfs_read(fp, kobj, buf, off, count,
280 sizeof(struct koneplus_tcu_image), KONEPLUS_USB_COMMAND_TCU); 288 sizeof(struct koneplus_tcu_image), KONEPLUS_COMMAND_TCU);
281} 289}
282 290
283static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp, 291static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp,
@@ -423,6 +431,9 @@ static ssize_t koneplus_sysfs_set_actual_profile(struct device *dev,
423 if (retval) 431 if (retval)
424 return retval; 432 return retval;
425 433
434 if (profile > 4)
435 return -EINVAL;
436
426 mutex_lock(&koneplus->koneplus_lock); 437 mutex_lock(&koneplus->koneplus_lock);
427 438
428 retval = koneplus_set_actual_profile(usb_dev, profile); 439 retval = koneplus_set_actual_profile(usb_dev, profile);
@@ -431,7 +442,7 @@ static ssize_t koneplus_sysfs_set_actual_profile(struct device *dev,
431 return retval; 442 return retval;
432 } 443 }
433 444
434 koneplus->actual_profile = profile; 445 koneplus_profile_activated(koneplus, profile);
435 446
436 roccat_report.type = KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE; 447 roccat_report.type = KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE;
437 roccat_report.data1 = profile + 1; 448 roccat_report.data1 = profile + 1;
@@ -557,6 +568,11 @@ static struct bin_attribute koneplus_bin_attributes[] = {
557 .size = sizeof(struct koneplus_macro), 568 .size = sizeof(struct koneplus_macro),
558 .write = koneplus_sysfs_write_macro 569 .write = koneplus_sysfs_write_macro
559 }, 570 },
571 {
572 .attr = { .name = "talk", .mode = 0220 },
573 .size = sizeof(struct koneplus_talk),
574 .write = koneplus_sysfs_write_talk
575 },
560 __ATTR_NULL 576 __ATTR_NULL
561}; 577};
562 578
@@ -738,6 +754,9 @@ static int koneplus_raw_event(struct hid_device *hdev,
738 != USB_INTERFACE_PROTOCOL_MOUSE) 754 != USB_INTERFACE_PROTOCOL_MOUSE)
739 return 0; 755 return 0;
740 756
757 if (koneplus == NULL)
758 return 0;
759
741 koneplus_keep_values_up_to_date(koneplus, data); 760 koneplus_keep_values_up_to_date(koneplus, data);
742 761
743 if (koneplus->roccat_claimed) 762 if (koneplus->roccat_claimed)
diff --git a/drivers/hid/hid-roccat-koneplus.h b/drivers/hid/hid-roccat-koneplus.h
index c57a376ab8a..c03332a4fa9 100644
--- a/drivers/hid/hid-roccat-koneplus.h
+++ b/drivers/hid/hid-roccat-koneplus.h
@@ -14,6 +14,12 @@
14 14
15#include <linux/types.h> 15#include <linux/types.h>
16 16
17struct koneplus_talk {
18 uint8_t command; /* KONEPLUS_COMMAND_TALK */
19 uint8_t size; /* always 0x10 */
20 uint8_t data[14];
21} __packed;
22
17/* 23/*
18 * case 1: writes request 80 and reads value 1 24 * case 1: writes request 80 and reads value 1
19 * 25 *
@@ -137,26 +143,14 @@ enum koneplus_commands {
137 KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7, 143 KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7,
138 KONEPLUS_COMMAND_MACRO = 0x8, 144 KONEPLUS_COMMAND_MACRO = 0x8,
139 KONEPLUS_COMMAND_INFO = 0x9, 145 KONEPLUS_COMMAND_INFO = 0x9,
146 KONEPLUS_COMMAND_TCU = 0xc,
140 KONEPLUS_COMMAND_E = 0xe, 147 KONEPLUS_COMMAND_E = 0xe,
141 KONEPLUS_COMMAND_SENSOR = 0xf, 148 KONEPLUS_COMMAND_SENSOR = 0xf,
149 KONEPLUS_COMMAND_TALK = 0x10,
142 KONEPLUS_COMMAND_FIRMWARE_WRITE = 0x1b, 150 KONEPLUS_COMMAND_FIRMWARE_WRITE = 0x1b,
143 KONEPLUS_COMMAND_FIRMWARE_WRITE_CONTROL = 0x1c, 151 KONEPLUS_COMMAND_FIRMWARE_WRITE_CONTROL = 0x1c,
144}; 152};
145 153
146enum koneplus_usb_commands {
147 KONEPLUS_USB_COMMAND_CONTROL = 0x304,
148 KONEPLUS_USB_COMMAND_ACTUAL_PROFILE = 0x305,
149 KONEPLUS_USB_COMMAND_PROFILE_SETTINGS = 0x306,
150 KONEPLUS_USB_COMMAND_PROFILE_BUTTONS = 0x307,
151 KONEPLUS_USB_COMMAND_MACRO = 0x308,
152 KONEPLUS_USB_COMMAND_INFO = 0x309,
153 KONEPLUS_USB_COMMAND_TCU = 0x30c,
154 KONEPLUS_USB_COMMAND_E = 0x30e,
155 KONEPLUS_USB_COMMAND_SENSOR = 0x30f,
156 KONEPLUS_USB_COMMAND_FIRMWARE_WRITE = 0x31b,
157 KONEPLUS_USB_COMMAND_FIRMWARE_WRITE_CONTROL = 0x31c,
158};
159
160enum koneplus_mouse_report_numbers { 154enum koneplus_mouse_report_numbers {
161 KONEPLUS_MOUSE_REPORT_NUMBER_HID = 1, 155 KONEPLUS_MOUSE_REPORT_NUMBER_HID = 1,
162 KONEPLUS_MOUSE_REPORT_NUMBER_AUDIO = 2, 156 KONEPLUS_MOUSE_REPORT_NUMBER_AUDIO = 2,
@@ -193,6 +187,7 @@ enum koneplus_mouse_report_button_types {
193 * data2 = action 187 * data2 = action
194 */ 188 */
195 KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_MULTIMEDIA = 0xf0, 189 KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_MULTIMEDIA = 0xf0,
190 KONEPLUS_MOUSE_REPORT_TALK = 0xff,
196}; 191};
197 192
198enum koneplus_mouse_report_button_action { 193enum koneplus_mouse_report_button_action {
diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c
index 984be2f8967..1f8336e3f58 100644
--- a/drivers/hid/hid-roccat-kovaplus.c
+++ b/drivers/hid/hid-roccat-kovaplus.c
@@ -58,7 +58,7 @@ static int kovaplus_send_control(struct usb_device *usb_dev, uint value,
58 control.value = value; 58 control.value = value;
59 control.request = request; 59 control.request = request;
60 60
61 retval = roccat_common_send(usb_dev, KOVAPLUS_USB_COMMAND_CONTROL, 61 retval = roccat_common_send(usb_dev, KOVAPLUS_COMMAND_CONTROL,
62 &control, sizeof(struct kovaplus_control)); 62 &control, sizeof(struct kovaplus_control));
63 63
64 return retval; 64 return retval;
@@ -70,7 +70,7 @@ static int kovaplus_receive_control_status(struct usb_device *usb_dev)
70 struct kovaplus_control control; 70 struct kovaplus_control control;
71 71
72 do { 72 do {
73 retval = roccat_common_receive(usb_dev, KOVAPLUS_USB_COMMAND_CONTROL, 73 retval = roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_CONTROL,
74 &control, sizeof(struct kovaplus_control)); 74 &control, sizeof(struct kovaplus_control));
75 75
76 /* check if we get a completely wrong answer */ 76 /* check if we get a completely wrong answer */
@@ -90,7 +90,7 @@ static int kovaplus_receive_control_status(struct usb_device *usb_dev)
90 if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_OVERLOAD) 90 if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_OVERLOAD)
91 return -EINVAL; 91 return -EINVAL;
92 92
93 hid_err(usb_dev, "kovaplus_receive_control_status: " 93 hid_err(usb_dev, "roccat_common_receive_control_status: "
94 "unknown response value 0x%x\n", control.value); 94 "unknown response value 0x%x\n", control.value);
95 return -EINVAL; 95 return -EINVAL;
96 } while (1); 96 } while (1);
@@ -119,7 +119,7 @@ static int kovaplus_select_profile(struct usb_device *usb_dev, uint number,
119static int kovaplus_get_info(struct usb_device *usb_dev, 119static int kovaplus_get_info(struct usb_device *usb_dev,
120 struct kovaplus_info *buf) 120 struct kovaplus_info *buf)
121{ 121{
122 return roccat_common_receive(usb_dev, KOVAPLUS_USB_COMMAND_INFO, 122 return roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_INFO,
123 buf, sizeof(struct kovaplus_info)); 123 buf, sizeof(struct kovaplus_info));
124} 124}
125 125
@@ -133,14 +133,14 @@ static int kovaplus_get_profile_settings(struct usb_device *usb_dev,
133 if (retval) 133 if (retval)
134 return retval; 134 return retval;
135 135
136 return roccat_common_receive(usb_dev, KOVAPLUS_USB_COMMAND_PROFILE_SETTINGS, 136 return roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS,
137 buf, sizeof(struct kovaplus_profile_settings)); 137 buf, sizeof(struct kovaplus_profile_settings));
138} 138}
139 139
140static int kovaplus_set_profile_settings(struct usb_device *usb_dev, 140static int kovaplus_set_profile_settings(struct usb_device *usb_dev,
141 struct kovaplus_profile_settings const *settings) 141 struct kovaplus_profile_settings const *settings)
142{ 142{
143 return kovaplus_send(usb_dev, KOVAPLUS_USB_COMMAND_PROFILE_SETTINGS, 143 return kovaplus_send(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS,
144 settings, sizeof(struct kovaplus_profile_settings)); 144 settings, sizeof(struct kovaplus_profile_settings));
145} 145}
146 146
@@ -154,14 +154,14 @@ static int kovaplus_get_profile_buttons(struct usb_device *usb_dev,
154 if (retval) 154 if (retval)
155 return retval; 155 return retval;
156 156
157 return roccat_common_receive(usb_dev, KOVAPLUS_USB_COMMAND_PROFILE_BUTTONS, 157 return roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS,
158 buf, sizeof(struct kovaplus_profile_buttons)); 158 buf, sizeof(struct kovaplus_profile_buttons));
159} 159}
160 160
161static int kovaplus_set_profile_buttons(struct usb_device *usb_dev, 161static int kovaplus_set_profile_buttons(struct usb_device *usb_dev,
162 struct kovaplus_profile_buttons const *buttons) 162 struct kovaplus_profile_buttons const *buttons)
163{ 163{
164 return kovaplus_send(usb_dev, KOVAPLUS_USB_COMMAND_PROFILE_BUTTONS, 164 return kovaplus_send(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS,
165 buttons, sizeof(struct kovaplus_profile_buttons)); 165 buttons, sizeof(struct kovaplus_profile_buttons));
166} 166}
167 167
@@ -171,7 +171,7 @@ static int kovaplus_get_actual_profile(struct usb_device *usb_dev)
171 struct kovaplus_actual_profile buf; 171 struct kovaplus_actual_profile buf;
172 int retval; 172 int retval;
173 173
174 retval = roccat_common_receive(usb_dev, KOVAPLUS_USB_COMMAND_ACTUAL_PROFILE, 174 retval = roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_ACTUAL_PROFILE,
175 &buf, sizeof(struct kovaplus_actual_profile)); 175 &buf, sizeof(struct kovaplus_actual_profile));
176 176
177 return retval ? retval : buf.actual_profile; 177 return retval ? retval : buf.actual_profile;
@@ -186,7 +186,7 @@ static int kovaplus_set_actual_profile(struct usb_device *usb_dev,
186 buf.size = sizeof(struct kovaplus_actual_profile); 186 buf.size = sizeof(struct kovaplus_actual_profile);
187 buf.actual_profile = new_profile; 187 buf.actual_profile = new_profile;
188 188
189 return kovaplus_send(usb_dev, KOVAPLUS_USB_COMMAND_ACTUAL_PROFILE, 189 return kovaplus_send(usb_dev, KOVAPLUS_COMMAND_ACTUAL_PROFILE,
190 &buf, sizeof(struct kovaplus_actual_profile)); 190 &buf, sizeof(struct kovaplus_actual_profile));
191} 191}
192 192
@@ -337,7 +337,7 @@ static ssize_t kovaplus_sysfs_set_actual_profile(struct device *dev,
337 337
338 mutex_lock(&kovaplus->kovaplus_lock); 338 mutex_lock(&kovaplus->kovaplus_lock);
339 retval = kovaplus_set_actual_profile(usb_dev, profile); 339 retval = kovaplus_set_actual_profile(usb_dev, profile);
340 kovaplus->actual_profile = profile; 340 kovaplus_profile_activated(kovaplus, profile);
341 mutex_unlock(&kovaplus->kovaplus_lock); 341 mutex_unlock(&kovaplus->kovaplus_lock);
342 if (retval) 342 if (retval)
343 return retval; 343 return retval;
@@ -662,6 +662,9 @@ static int kovaplus_raw_event(struct hid_device *hdev,
662 != USB_INTERFACE_PROTOCOL_MOUSE) 662 != USB_INTERFACE_PROTOCOL_MOUSE)
663 return 0; 663 return 0;
664 664
665 if (kovaplus == NULL)
666 return 0;
667
665 kovaplus_keep_values_up_to_date(kovaplus, data); 668 kovaplus_keep_values_up_to_date(kovaplus, data);
666 669
667 if (kovaplus->roccat_claimed) 670 if (kovaplus->roccat_claimed)
diff --git a/drivers/hid/hid-roccat-kovaplus.h b/drivers/hid/hid-roccat-kovaplus.h
index ce40607d21c..fb2aed44a8e 100644
--- a/drivers/hid/hid-roccat-kovaplus.h
+++ b/drivers/hid/hid-roccat-kovaplus.h
@@ -83,15 +83,6 @@ enum kovaplus_commands {
83 KOVAPLUS_COMMAND_A = 0xa, 83 KOVAPLUS_COMMAND_A = 0xa,
84}; 84};
85 85
86enum kovaplus_usb_commands {
87 KOVAPLUS_USB_COMMAND_CONTROL = 0x304,
88 KOVAPLUS_USB_COMMAND_ACTUAL_PROFILE = 0x305,
89 KOVAPLUS_USB_COMMAND_PROFILE_SETTINGS = 0x306,
90 KOVAPLUS_USB_COMMAND_PROFILE_BUTTONS = 0x307,
91 KOVAPLUS_USB_COMMAND_INFO = 0x309,
92 KOVAPLUS_USB_COMMAND_A = 0x30a,
93};
94
95enum kovaplus_mouse_report_numbers { 86enum kovaplus_mouse_report_numbers {
96 KOVAPLUS_MOUSE_REPORT_NUMBER_MOUSE = 1, 87 KOVAPLUS_MOUSE_REPORT_NUMBER_MOUSE = 1,
97 KOVAPLUS_MOUSE_REPORT_NUMBER_AUDIO = 2, 88 KOVAPLUS_MOUSE_REPORT_NUMBER_AUDIO = 2,
diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c
index 38280c055a1..8140776bd8c 100644
--- a/drivers/hid/hid-roccat-pyra.c
+++ b/drivers/hid/hid-roccat-pyra.c
@@ -53,7 +53,7 @@ static int pyra_send_control(struct usb_device *usb_dev, int value,
53 control.value = value; 53 control.value = value;
54 control.request = request; 54 control.request = request;
55 55
56 return roccat_common_send(usb_dev, PYRA_USB_COMMAND_CONTROL, 56 return roccat_common_send(usb_dev, PYRA_COMMAND_CONTROL,
57 &control, sizeof(struct pyra_control)); 57 &control, sizeof(struct pyra_control));
58} 58}
59 59
@@ -64,7 +64,7 @@ static int pyra_receive_control_status(struct usb_device *usb_dev)
64 64
65 do { 65 do {
66 msleep(10); 66 msleep(10);
67 retval = roccat_common_receive(usb_dev, PYRA_USB_COMMAND_CONTROL, 67 retval = roccat_common_receive(usb_dev, PYRA_COMMAND_CONTROL,
68 &control, sizeof(struct pyra_control)); 68 &control, sizeof(struct pyra_control));
69 69
70 /* requested too early, try again */ 70 /* requested too early, try again */
@@ -89,7 +89,7 @@ static int pyra_get_profile_settings(struct usb_device *usb_dev,
89 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS); 89 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS);
90 if (retval) 90 if (retval)
91 return retval; 91 return retval;
92 return roccat_common_receive(usb_dev, PYRA_USB_COMMAND_PROFILE_SETTINGS, 92 return roccat_common_receive(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS,
93 buf, sizeof(struct pyra_profile_settings)); 93 buf, sizeof(struct pyra_profile_settings));
94} 94}
95 95
@@ -101,20 +101,20 @@ static int pyra_get_profile_buttons(struct usb_device *usb_dev,
101 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS); 101 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS);
102 if (retval) 102 if (retval)
103 return retval; 103 return retval;
104 return roccat_common_receive(usb_dev, PYRA_USB_COMMAND_PROFILE_BUTTONS, 104 return roccat_common_receive(usb_dev, PYRA_COMMAND_PROFILE_BUTTONS,
105 buf, sizeof(struct pyra_profile_buttons)); 105 buf, sizeof(struct pyra_profile_buttons));
106} 106}
107 107
108static int pyra_get_settings(struct usb_device *usb_dev, 108static int pyra_get_settings(struct usb_device *usb_dev,
109 struct pyra_settings *buf) 109 struct pyra_settings *buf)
110{ 110{
111 return roccat_common_receive(usb_dev, PYRA_USB_COMMAND_SETTINGS, 111 return roccat_common_receive(usb_dev, PYRA_COMMAND_SETTINGS,
112 buf, sizeof(struct pyra_settings)); 112 buf, sizeof(struct pyra_settings));
113} 113}
114 114
115static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf) 115static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf)
116{ 116{
117 return roccat_common_receive(usb_dev, PYRA_USB_COMMAND_INFO, 117 return roccat_common_receive(usb_dev, PYRA_COMMAND_INFO,
118 buf, sizeof(struct pyra_info)); 118 buf, sizeof(struct pyra_info));
119} 119}
120 120
@@ -131,26 +131,22 @@ static int pyra_send(struct usb_device *usb_dev, uint command,
131static int pyra_set_profile_settings(struct usb_device *usb_dev, 131static int pyra_set_profile_settings(struct usb_device *usb_dev,
132 struct pyra_profile_settings const *settings) 132 struct pyra_profile_settings const *settings)
133{ 133{
134 return pyra_send(usb_dev, PYRA_USB_COMMAND_PROFILE_SETTINGS, settings, 134 return pyra_send(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS, settings,
135 sizeof(struct pyra_profile_settings)); 135 sizeof(struct pyra_profile_settings));
136} 136}
137 137
138static int pyra_set_profile_buttons(struct usb_device *usb_dev, 138static int pyra_set_profile_buttons(struct usb_device *usb_dev,
139 struct pyra_profile_buttons const *buttons) 139 struct pyra_profile_buttons const *buttons)
140{ 140{
141 return pyra_send(usb_dev, PYRA_USB_COMMAND_PROFILE_BUTTONS, buttons, 141 return pyra_send(usb_dev, PYRA_COMMAND_PROFILE_BUTTONS, buttons,
142 sizeof(struct pyra_profile_buttons)); 142 sizeof(struct pyra_profile_buttons));
143} 143}
144 144
145static int pyra_set_settings(struct usb_device *usb_dev, 145static int pyra_set_settings(struct usb_device *usb_dev,
146 struct pyra_settings const *settings) 146 struct pyra_settings const *settings)
147{ 147{
148 int retval; 148 return pyra_send(usb_dev, PYRA_COMMAND_SETTINGS, settings,
149 retval = roccat_common_send(usb_dev, PYRA_USB_COMMAND_SETTINGS, settings,
150 sizeof(struct pyra_settings)); 149 sizeof(struct pyra_settings));
151 if (retval)
152 return retval;
153 return pyra_receive_control_status(usb_dev);
154} 150}
155 151
156static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp, 152static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp,
@@ -641,6 +637,9 @@ static int pyra_raw_event(struct hid_device *hdev, struct hid_report *report,
641 != USB_INTERFACE_PROTOCOL_MOUSE) 637 != USB_INTERFACE_PROTOCOL_MOUSE)
642 return 0; 638 return 0;
643 639
640 if (pyra == NULL)
641 return 0;
642
644 pyra_keep_values_up_to_date(pyra, data); 643 pyra_keep_values_up_to_date(pyra, data);
645 644
646 if (pyra->roccat_claimed) 645 if (pyra->roccat_claimed)
diff --git a/drivers/hid/hid-roccat-pyra.h b/drivers/hid/hid-roccat-pyra.h
index 14cbbe1621e..0442d7fa2dc 100644
--- a/drivers/hid/hid-roccat-pyra.h
+++ b/drivers/hid/hid-roccat-pyra.h
@@ -83,15 +83,6 @@ enum pyra_commands {
83 PYRA_COMMAND_B = 0xb 83 PYRA_COMMAND_B = 0xb
84}; 84};
85 85
86enum pyra_usb_commands {
87 PYRA_USB_COMMAND_CONTROL = 0x304,
88 PYRA_USB_COMMAND_SETTINGS = 0x305,
89 PYRA_USB_COMMAND_PROFILE_SETTINGS = 0x306,
90 PYRA_USB_COMMAND_PROFILE_BUTTONS = 0x307,
91 PYRA_USB_COMMAND_INFO = 0x309,
92 PYRA_USB_COMMAND_B = 0x30b /* writes 3 bytes */
93};
94
95enum pyra_mouse_report_numbers { 86enum pyra_mouse_report_numbers {
96 PYRA_MOUSE_REPORT_NUMBER_HID = 1, 87 PYRA_MOUSE_REPORT_NUMBER_HID = 1,
97 PYRA_MOUSE_REPORT_NUMBER_AUDIO = 2, 88 PYRA_MOUSE_REPORT_NUMBER_AUDIO = 2,
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 936c911fdca..5cd25bd907f 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -28,6 +28,12 @@
28#define SIXAXIS_CONTROLLER_USB (1 << 1) 28#define SIXAXIS_CONTROLLER_USB (1 << 1)
29#define SIXAXIS_CONTROLLER_BT (1 << 2) 29#define SIXAXIS_CONTROLLER_BT (1 << 2)
30 30
31static const u8 sixaxis_rdesc_fixup[] = {
32 0x95, 0x13, 0x09, 0x01, 0x81, 0x02, 0x95, 0x0C,
33 0x81, 0x01, 0x75, 0x10, 0x95, 0x04, 0x26, 0xFF,
34 0x03, 0x46, 0xFF, 0x03, 0x09, 0x01, 0x81, 0x02
35};
36
31struct sony_sc { 37struct sony_sc {
32 unsigned long quirks; 38 unsigned long quirks;
33}; 39};
@@ -43,9 +49,37 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc,
43 hid_info(hdev, "Fixing up Sony Vaio VGX report descriptor\n"); 49 hid_info(hdev, "Fixing up Sony Vaio VGX report descriptor\n");
44 rdesc[55] = 0x06; 50 rdesc[55] = 0x06;
45 } 51 }
52
53 /* The HID descriptor exposed over BT has a trailing zero byte */
54 if ((((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize == 148) ||
55 ((sc->quirks & SIXAXIS_CONTROLLER_BT) && *rsize == 149)) &&
56 rdesc[83] == 0x75) {
57 hid_info(hdev, "Fixing up Sony Sixaxis report descriptor\n");
58 memcpy((void *)&rdesc[83], (void *)&sixaxis_rdesc_fixup,
59 sizeof(sixaxis_rdesc_fixup));
60 }
46 return rdesc; 61 return rdesc;
47} 62}
48 63
64static int sony_raw_event(struct hid_device *hdev, struct hid_report *report,
65 __u8 *rd, int size)
66{
67 struct sony_sc *sc = hid_get_drvdata(hdev);
68
69 /* Sixaxis HID report has acclerometers/gyro with MSByte first, this
70 * has to be BYTE_SWAPPED before passing up to joystick interface
71 */
72 if ((sc->quirks & (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT)) &&
73 rd[0] == 0x01 && size == 49) {
74 swap(rd[41], rd[42]);
75 swap(rd[43], rd[44]);
76 swap(rd[45], rd[46]);
77 swap(rd[47], rd[48]);
78 }
79
80 return 0;
81}
82
49/* 83/*
50 * The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP 84 * The Sony Sixaxis does not handle HID Output Reports on the Interrupt EP
51 * like it should according to usbhid/hid-core.c::usbhid_output_raw_report() 85 * like it should according to usbhid/hid-core.c::usbhid_output_raw_report()
@@ -194,6 +228,7 @@ static struct hid_driver sony_driver = {
194 .probe = sony_probe, 228 .probe = sony_probe,
195 .remove = sony_remove, 229 .remove = sony_remove,
196 .report_fixup = sony_report_fixup, 230 .report_fixup = sony_report_fixup,
231 .raw_event = sony_raw_event
197}; 232};
198 233
199static int __init sony_init(void) 234static int __init sony_init(void)
diff --git a/drivers/hid/hid-speedlink.c b/drivers/hid/hid-speedlink.c
new file mode 100644
index 00000000000..60201374171
--- /dev/null
+++ b/drivers/hid/hid-speedlink.c
@@ -0,0 +1,89 @@
1/*
2 * HID driver for Speedlink Vicious and Divine Cezanne (USB mouse).
3 * Fixes "jumpy" cursor and removes nonexistent keyboard LEDS from
4 * the HID descriptor.
5 *
6 * Copyright (c) 2011 Stefan Kriwanek <mail@stefankriwanek.de>
7 */
8
9/*
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your option)
13 * any later version.
14 */
15
16#include <linux/device.h>
17#include <linux/hid.h>
18#include <linux/module.h>
19#include <linux/usb.h>
20
21#include "hid-ids.h"
22#include "usbhid/usbhid.h"
23
24static const struct hid_device_id speedlink_devices[] = {
25 { HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE)},
26 { }
27};
28
29static int speedlink_input_mapping(struct hid_device *hdev,
30 struct hid_input *hi,
31 struct hid_field *field, struct hid_usage *usage,
32 unsigned long **bit, int *max)
33{
34 /*
35 * The Cezanne mouse has a second "keyboard" USB endpoint for it is
36 * able to map keyboard events to the button presses.
37 * It sends a standard keyboard report descriptor, though, whose
38 * LEDs we ignore.
39 */
40 switch (usage->hid & HID_USAGE_PAGE) {
41 case HID_UP_LED:
42 return -1;
43 }
44 return 0;
45}
46
47static int speedlink_event(struct hid_device *hdev, struct hid_field *field,
48 struct hid_usage *usage, __s32 value)
49{
50 /* No other conditions due to usage_table. */
51 /* Fix "jumpy" cursor (invalid events sent by device). */
52 if (value == 256)
53 return 1;
54 /* Drop useless distance 0 events (on button clicks etc.) as well */
55 if (value == 0)
56 return 1;
57
58 return 0;
59}
60
61MODULE_DEVICE_TABLE(hid, speedlink_devices);
62
63static const struct hid_usage_id speedlink_grabbed_usages[] = {
64 { HID_GD_X, EV_REL, 0 },
65 { HID_GD_Y, EV_REL, 1 },
66 { HID_ANY_ID - 1, HID_ANY_ID - 1, HID_ANY_ID - 1}
67};
68
69static struct hid_driver speedlink_driver = {
70 .name = "speedlink",
71 .id_table = speedlink_devices,
72 .usage_table = speedlink_grabbed_usages,
73 .input_mapping = speedlink_input_mapping,
74 .event = speedlink_event,
75};
76
77static int __init speedlink_init(void)
78{
79 return hid_register_driver(&speedlink_driver);
80}
81
82static void __exit speedlink_exit(void)
83{
84 hid_unregister_driver(&speedlink_driver);
85}
86
87module_init(speedlink_init);
88module_exit(speedlink_exit);
89MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-uclogic.c b/drivers/hid/hid-uclogic.c
index 05fdc85a76e..e15732f1a22 100644
--- a/drivers/hid/hid-uclogic.c
+++ b/drivers/hid/hid-uclogic.c
@@ -343,6 +343,193 @@ static __u8 wp8060u_rdesc_fixed[] = {
343}; 343};
344 344
345/* 345/*
346 * Original WP1062 report descriptor.
347 *
348 * Only report ID 9 is actually used.
349 *
350 * Usage Page (Digitizer), ; Digitizer (0Dh)
351 * Usage (Pen), ; Pen (02h, application collection)
352 * Collection (Application),
353 * Report ID (7),
354 * Usage (Stylus), ; Stylus (20h, logical collection)
355 * Collection (Physical),
356 * Usage (Tip Switch), ; Tip switch (42h, momentary control)
357 * Usage (Barrel Switch), ; Barrel switch (44h, momentary control)
358 * Usage (Eraser), ; Eraser (45h, momentary control)
359 * Logical Minimum (0),
360 * Logical Maximum (1),
361 * Report Size (1),
362 * Report Count (3),
363 * Input (Variable),
364 * Report Count (3),
365 * Input (Constant, Variable),
366 * Usage (In Range), ; In range (32h, momentary control)
367 * Report Count (1),
368 * Input (Variable),
369 * Report Count (1),
370 * Input (Constant, Variable),
371 * Usage Page (Desktop), ; Generic desktop controls (01h)
372 * Usage (X), ; X (30h, dynamic value)
373 * Report Size (16),
374 * Report Count (1),
375 * Push,
376 * Unit Exponent (13),
377 * Unit (Inch),
378 * Physical Minimum (0),
379 * Physical Maximum (10000),
380 * Logical Maximum (20000),
381 * Input (Variable),
382 * Usage (Y), ; Y (31h, dynamic value)
383 * Physical Maximum (6583),
384 * Logical Maximum (13166),
385 * Input (Variable),
386 * Pop,
387 * Usage Page (Digitizer), ; Digitizer (0Dh)
388 * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value)
389 * Logical Maximum (1023),
390 * Input (Variable),
391 * Report Size (16),
392 * End Collection,
393 * End Collection,
394 * Usage Page (Desktop), ; Generic desktop controls (01h)
395 * Usage (Mouse), ; Mouse (02h, application collection)
396 * Collection (Application),
397 * Report ID (8),
398 * Usage (Pointer), ; Pointer (01h, physical collection)
399 * Collection (Physical),
400 * Usage Page (Button), ; Button (09h)
401 * Usage Minimum (01h),
402 * Usage Maximum (03h),
403 * Logical Minimum (0),
404 * Logical Maximum (1),
405 * Report Count (3),
406 * Report Size (1),
407 * Input (Variable),
408 * Report Count (5),
409 * Input (Constant),
410 * Usage Page (Desktop), ; Generic desktop controls (01h)
411 * Usage (X), ; X (30h, dynamic value)
412 * Usage (Y), ; Y (31h, dynamic value)
413 * Usage (Wheel), ; Wheel (38h, dynamic value)
414 * Usage (00h),
415 * Logical Minimum (-127),
416 * Logical Maximum (127),
417 * Report Size (8),
418 * Report Count (4),
419 * Input (Variable, Relative),
420 * End Collection,
421 * End Collection,
422 * Usage Page (Desktop), ; Generic desktop controls (01h)
423 * Usage (Mouse), ; Mouse (02h, application collection)
424 * Collection (Application),
425 * Report ID (9),
426 * Usage (Pointer), ; Pointer (01h, physical collection)
427 * Collection (Physical),
428 * Usage Page (Button), ; Button (09h)
429 * Usage Minimum (01h),
430 * Usage Maximum (03h),
431 * Logical Minimum (0),
432 * Logical Maximum (1),
433 * Report Count (3),
434 * Report Size (1),
435 * Input (Variable),
436 * Report Count (4),
437 * Input (Constant),
438 * Usage Page (Digitizer), ; Digitizer (0Dh)
439 * Usage (In Range), ; In range (32h, momentary control)
440 * Report Count (1),
441 * Input (Variable),
442 * Usage Page (Desktop), ; Generic desktop controls (01h)
443 * Usage (X), ; X (30h, dynamic value)
444 * Report Size (16),
445 * Report Count (1),
446 * Push,
447 * Unit Exponent (13),
448 * Unit (Inch),
449 * Physical Minimum (0),
450 * Physical Maximum (10000),
451 * Logical Maximum (20000),
452 * Input (Variable),
453 * Usage (Y), ; Y (31h, dynamic value)
454 * Physical Maximum (6583),
455 * Logical Maximum (13166),
456 * Input (Variable),
457 * Pop,
458 * Usage Page (Digitizer), ; Digitizer (0Dh)
459 * Usage (Tip Pressure), ; Tip pressure (30h, dynamic value)
460 * Logical Maximum (1023),
461 * Report Count (1),
462 * Report Size (16),
463 * Input (Variable),
464 * End Collection,
465 * End Collection,
466 * Usage Page (Desktop), ; Generic desktop controls (01h)
467 * Usage (00h),
468 * Collection (Application),
469 * Report ID (4),
470 * Logical Minimum (0),
471 * Logical Maximum (255),
472 * Usage (00h),
473 * Report Size (8),
474 * Report Count (3),
475 * Feature (Variable),
476 * End Collection
477 */
478
479/* Size of the original descriptor of WP1062 tablet */
480#define WP1062_RDESC_ORIG_SIZE 254
481
482/*
483 * Fixed WP1062 report descriptor.
484 *
485 * Removed unused reports, corrected second barrel button usage code, physical
486 * units.
487 */
488static __u8 wp1062_rdesc_fixed[] = {
489 0x05, 0x0D, /* Usage Page (Digitizer), */
490 0x09, 0x02, /* Usage (Pen), */
491 0xA1, 0x01, /* Collection (Application), */
492 0x85, 0x09, /* Report ID (9), */
493 0x09, 0x20, /* Usage (Stylus), */
494 0xA0, /* Collection (Physical), */
495 0x75, 0x01, /* Report Size (1), */
496 0x09, 0x42, /* Usage (Tip Switch), */
497 0x09, 0x44, /* Usage (Barrel Switch), */
498 0x09, 0x46, /* Usage (Tablet Pick), */
499 0x14, /* Logical Minimum (0), */
500 0x25, 0x01, /* Logical Maximum (1), */
501 0x95, 0x03, /* Report Count (3), */
502 0x81, 0x02, /* Input (Variable), */
503 0x95, 0x04, /* Report Count (4), */
504 0x81, 0x01, /* Input (Constant), */
505 0x09, 0x32, /* Usage (In Range), */
506 0x95, 0x01, /* Report Count (1), */
507 0x81, 0x02, /* Input (Variable), */
508 0x75, 0x10, /* Report Size (16), */
509 0x95, 0x01, /* Report Count (1), */
510 0x14, /* Logical Minimum (0), */
511 0xA4, /* Push, */
512 0x05, 0x01, /* Usage Page (Desktop), */
513 0x55, 0xFD, /* Unit Exponent (-3), */
514 0x65, 0x13, /* Unit (Inch), */
515 0x34, /* Physical Minimum (0), */
516 0x09, 0x30, /* Usage (X), */
517 0x46, 0x10, 0x27, /* Physical Maximum (10000), */
518 0x26, 0x20, 0x4E, /* Logical Maximum (20000), */
519 0x81, 0x02, /* Input (Variable), */
520 0x09, 0x31, /* Usage (Y), */
521 0x46, 0xB7, 0x19, /* Physical Maximum (6583), */
522 0x26, 0x6E, 0x33, /* Logical Maximum (13166), */
523 0x81, 0x02, /* Input (Variable), */
524 0xB4, /* Pop, */
525 0x09, 0x30, /* Usage (Tip Pressure), */
526 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */
527 0x81, 0x02, /* Input (Variable), */
528 0xC0, /* End Collection, */
529 0xC0 /* End Collection */
530};
531
532/*
346 * Original PF1209 report descriptor. 533 * Original PF1209 report descriptor.
347 * 534 *
348 * The descriptor is similar to WPXXXXU descriptors, with an addition of a 535 * The descriptor is similar to WPXXXXU descriptors, with an addition of a
@@ -584,6 +771,12 @@ static __u8 *uclogic_report_fixup(struct hid_device *hdev, __u8 *rdesc,
584 *rsize = sizeof(wp8060u_rdesc_fixed); 771 *rsize = sizeof(wp8060u_rdesc_fixed);
585 } 772 }
586 break; 773 break;
774 case USB_DEVICE_ID_UCLOGIC_TABLET_WP1062:
775 if (*rsize == WP1062_RDESC_ORIG_SIZE) {
776 rdesc = wp1062_rdesc_fixed;
777 *rsize = sizeof(wp1062_rdesc_fixed);
778 }
779 break;
587 } 780 }
588 781
589 return rdesc; 782 return rdesc;
@@ -598,6 +791,8 @@ static const struct hid_device_id uclogic_devices[] = {
598 USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) }, 791 USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) },
599 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, 792 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
600 USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) }, 793 USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) },
794 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
795 USB_DEVICE_ID_UCLOGIC_TABLET_WP1062) },
601 { } 796 { }
602}; 797};
603MODULE_DEVICE_TABLE(hid, uclogic_devices); 798MODULE_DEVICE_TABLE(hid, uclogic_devices);
diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c
index 06888323828..72ca689b647 100644
--- a/drivers/hid/hid-wacom.c
+++ b/drivers/hid/hid-wacom.c
@@ -353,11 +353,7 @@ static int wacom_probe(struct hid_device *hdev,
353 if (ret) { 353 if (ret) {
354 hid_warn(hdev, "can't create sysfs battery attribute, err: %d\n", 354 hid_warn(hdev, "can't create sysfs battery attribute, err: %d\n",
355 ret); 355 ret);
356 /* 356 goto err_battery;
357 * battery attribute is not critical for the tablet, but if it
358 * failed then there is no need to create ac attribute
359 */
360 goto move_on;
361 } 357 }
362 358
363 wdata->ac.properties = wacom_ac_props; 359 wdata->ac.properties = wacom_ac_props;
@@ -371,18 +367,14 @@ static int wacom_probe(struct hid_device *hdev,
371 if (ret) { 367 if (ret) {
372 hid_warn(hdev, 368 hid_warn(hdev,
373 "can't create ac battery attribute, err: %d\n", ret); 369 "can't create ac battery attribute, err: %d\n", ret);
374 /* 370 goto err_ac;
375 * ac attribute is not critical for the tablet, but if it
376 * failed then we don't want to battery attribute to exist
377 */
378 power_supply_unregister(&wdata->battery);
379 } 371 }
380
381move_on:
382#endif 372#endif
383 hidinput = list_entry(hdev->inputs.next, struct hid_input, list); 373 hidinput = list_entry(hdev->inputs.next, struct hid_input, list);
384 input = hidinput->input; 374 input = hidinput->input;
385 375
376 __set_bit(INPUT_PROP_POINTER, input->propbit);
377
386 /* Basics */ 378 /* Basics */
387 input->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL); 379 input->evbit[0] |= BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_REL);
388 380
@@ -416,6 +408,13 @@ move_on:
416 408
417 return 0; 409 return 0;
418 410
411#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
412err_ac:
413 power_supply_unregister(&wdata->battery);
414err_battery:
415 device_remove_file(&hdev->dev, &dev_attr_speed);
416 hid_hw_stop(hdev);
417#endif
419err_free: 418err_free:
420 kfree(wdata); 419 kfree(wdata);
421 return ret; 420 return ret;
@@ -426,6 +425,7 @@ static void wacom_remove(struct hid_device *hdev)
426#ifdef CONFIG_HID_WACOM_POWER_SUPPLY 425#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
427 struct wacom_data *wdata = hid_get_drvdata(hdev); 426 struct wacom_data *wdata = hid_get_drvdata(hdev);
428#endif 427#endif
428 device_remove_file(&hdev->dev, &dev_attr_speed);
429 hid_hw_stop(hdev); 429 hid_hw_stop(hdev);
430 430
431#ifdef CONFIG_HID_WACOM_POWER_SUPPLY 431#ifdef CONFIG_HID_WACOM_POWER_SUPPLY
diff --git a/drivers/hid/hid-wiimote.c b/drivers/hid/hid-wiimote.c
new file mode 100644
index 00000000000..85a02e5f9fe
--- /dev/null
+++ b/drivers/hid/hid-wiimote.c
@@ -0,0 +1,578 @@
1/*
2 * HID driver for Nintendo Wiimote devices
3 * Copyright (c) 2011 David Herrmann
4 */
5
6/*
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 */
12
13#include <linux/device.h>
14#include <linux/hid.h>
15#include <linux/input.h>
16#include <linux/leds.h>
17#include <linux/module.h>
18#include <linux/spinlock.h>
19#include "hid-ids.h"
20
21#define WIIMOTE_VERSION "0.1"
22#define WIIMOTE_NAME "Nintendo Wii Remote"
23#define WIIMOTE_BUFSIZE 32
24
25struct wiimote_buf {
26 __u8 data[HID_MAX_BUFFER_SIZE];
27 size_t size;
28};
29
30struct wiimote_state {
31 spinlock_t lock;
32 __u8 flags;
33};
34
35struct wiimote_data {
36 struct hid_device *hdev;
37 struct input_dev *input;
38 struct led_classdev *leds[4];
39
40 spinlock_t qlock;
41 __u8 head;
42 __u8 tail;
43 struct wiimote_buf outq[WIIMOTE_BUFSIZE];
44 struct work_struct worker;
45
46 struct wiimote_state state;
47};
48
49#define WIIPROTO_FLAG_LED1 0x01
50#define WIIPROTO_FLAG_LED2 0x02
51#define WIIPROTO_FLAG_LED3 0x04
52#define WIIPROTO_FLAG_LED4 0x08
53#define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \
54 WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4)
55
56/* return flag for led \num */
57#define WIIPROTO_FLAG_LED(num) (WIIPROTO_FLAG_LED1 << (num - 1))
58
59enum wiiproto_reqs {
60 WIIPROTO_REQ_NULL = 0x0,
61 WIIPROTO_REQ_LED = 0x11,
62 WIIPROTO_REQ_DRM = 0x12,
63 WIIPROTO_REQ_STATUS = 0x20,
64 WIIPROTO_REQ_RETURN = 0x22,
65 WIIPROTO_REQ_DRM_K = 0x30,
66};
67
68enum wiiproto_keys {
69 WIIPROTO_KEY_LEFT,
70 WIIPROTO_KEY_RIGHT,
71 WIIPROTO_KEY_UP,
72 WIIPROTO_KEY_DOWN,
73 WIIPROTO_KEY_PLUS,
74 WIIPROTO_KEY_MINUS,
75 WIIPROTO_KEY_ONE,
76 WIIPROTO_KEY_TWO,
77 WIIPROTO_KEY_A,
78 WIIPROTO_KEY_B,
79 WIIPROTO_KEY_HOME,
80 WIIPROTO_KEY_COUNT
81};
82
83static __u16 wiiproto_keymap[] = {
84 KEY_LEFT, /* WIIPROTO_KEY_LEFT */
85 KEY_RIGHT, /* WIIPROTO_KEY_RIGHT */
86 KEY_UP, /* WIIPROTO_KEY_UP */
87 KEY_DOWN, /* WIIPROTO_KEY_DOWN */
88 KEY_NEXT, /* WIIPROTO_KEY_PLUS */
89 KEY_PREVIOUS, /* WIIPROTO_KEY_MINUS */
90 BTN_1, /* WIIPROTO_KEY_ONE */
91 BTN_2, /* WIIPROTO_KEY_TWO */
92 BTN_A, /* WIIPROTO_KEY_A */
93 BTN_B, /* WIIPROTO_KEY_B */
94 BTN_MODE, /* WIIPROTO_KEY_HOME */
95};
96
97static ssize_t wiimote_hid_send(struct hid_device *hdev, __u8 *buffer,
98 size_t count)
99{
100 __u8 *buf;
101 ssize_t ret;
102
103 if (!hdev->hid_output_raw_report)
104 return -ENODEV;
105
106 buf = kmemdup(buffer, count, GFP_KERNEL);
107 if (!buf)
108 return -ENOMEM;
109
110 ret = hdev->hid_output_raw_report(hdev, buf, count, HID_OUTPUT_REPORT);
111
112 kfree(buf);
113 return ret;
114}
115
116static void wiimote_worker(struct work_struct *work)
117{
118 struct wiimote_data *wdata = container_of(work, struct wiimote_data,
119 worker);
120 unsigned long flags;
121
122 spin_lock_irqsave(&wdata->qlock, flags);
123
124 while (wdata->head != wdata->tail) {
125 spin_unlock_irqrestore(&wdata->qlock, flags);
126 wiimote_hid_send(wdata->hdev, wdata->outq[wdata->tail].data,
127 wdata->outq[wdata->tail].size);
128 spin_lock_irqsave(&wdata->qlock, flags);
129
130 wdata->tail = (wdata->tail + 1) % WIIMOTE_BUFSIZE;
131 }
132
133 spin_unlock_irqrestore(&wdata->qlock, flags);
134}
135
136static void wiimote_queue(struct wiimote_data *wdata, const __u8 *buffer,
137 size_t count)
138{
139 unsigned long flags;
140 __u8 newhead;
141
142 if (count > HID_MAX_BUFFER_SIZE) {
143 hid_warn(wdata->hdev, "Sending too large output report\n");
144 return;
145 }
146
147 /*
148 * Copy new request into our output queue and check whether the
149 * queue is full. If it is full, discard this request.
150 * If it is empty we need to start a new worker that will
151 * send out the buffer to the hid device.
152 * If the queue is not empty, then there must be a worker
153 * that is currently sending out our buffer and this worker
154 * will reschedule itself until the queue is empty.
155 */
156
157 spin_lock_irqsave(&wdata->qlock, flags);
158
159 memcpy(wdata->outq[wdata->head].data, buffer, count);
160 wdata->outq[wdata->head].size = count;
161 newhead = (wdata->head + 1) % WIIMOTE_BUFSIZE;
162
163 if (wdata->head == wdata->tail) {
164 wdata->head = newhead;
165 schedule_work(&wdata->worker);
166 } else if (newhead != wdata->tail) {
167 wdata->head = newhead;
168 } else {
169 hid_warn(wdata->hdev, "Output queue is full");
170 }
171
172 spin_unlock_irqrestore(&wdata->qlock, flags);
173}
174
175static void wiiproto_req_leds(struct wiimote_data *wdata, int leds)
176{
177 __u8 cmd[2];
178
179 leds &= WIIPROTO_FLAGS_LEDS;
180 if ((wdata->state.flags & WIIPROTO_FLAGS_LEDS) == leds)
181 return;
182 wdata->state.flags = (wdata->state.flags & ~WIIPROTO_FLAGS_LEDS) | leds;
183
184 cmd[0] = WIIPROTO_REQ_LED;
185 cmd[1] = 0;
186
187 if (leds & WIIPROTO_FLAG_LED1)
188 cmd[1] |= 0x10;
189 if (leds & WIIPROTO_FLAG_LED2)
190 cmd[1] |= 0x20;
191 if (leds & WIIPROTO_FLAG_LED3)
192 cmd[1] |= 0x40;
193 if (leds & WIIPROTO_FLAG_LED4)
194 cmd[1] |= 0x80;
195
196 wiimote_queue(wdata, cmd, sizeof(cmd));
197}
198
199/*
200 * Check what peripherals of the wiimote are currently
201 * active and select a proper DRM that supports all of
202 * the requested data inputs.
203 */
204static __u8 select_drm(struct wiimote_data *wdata)
205{
206 return WIIPROTO_REQ_DRM_K;
207}
208
209static void wiiproto_req_drm(struct wiimote_data *wdata, __u8 drm)
210{
211 __u8 cmd[3];
212
213 if (drm == WIIPROTO_REQ_NULL)
214 drm = select_drm(wdata);
215
216 cmd[0] = WIIPROTO_REQ_DRM;
217 cmd[1] = 0;
218 cmd[2] = drm;
219
220 wiimote_queue(wdata, cmd, sizeof(cmd));
221}
222
223static enum led_brightness wiimote_leds_get(struct led_classdev *led_dev)
224{
225 struct wiimote_data *wdata;
226 struct device *dev = led_dev->dev->parent;
227 int i;
228 unsigned long flags;
229 bool value = false;
230
231 wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev));
232
233 for (i = 0; i < 4; ++i) {
234 if (wdata->leds[i] == led_dev) {
235 spin_lock_irqsave(&wdata->state.lock, flags);
236 value = wdata->state.flags & WIIPROTO_FLAG_LED(i + 1);
237 spin_unlock_irqrestore(&wdata->state.lock, flags);
238 break;
239 }
240 }
241
242 return value ? LED_FULL : LED_OFF;
243}
244
245static void wiimote_leds_set(struct led_classdev *led_dev,
246 enum led_brightness value)
247{
248 struct wiimote_data *wdata;
249 struct device *dev = led_dev->dev->parent;
250 int i;
251 unsigned long flags;
252 __u8 state, flag;
253
254 wdata = hid_get_drvdata(container_of(dev, struct hid_device, dev));
255
256 for (i = 0; i < 4; ++i) {
257 if (wdata->leds[i] == led_dev) {
258 flag = WIIPROTO_FLAG_LED(i + 1);
259 spin_lock_irqsave(&wdata->state.lock, flags);
260 state = wdata->state.flags;
261 if (value == LED_OFF)
262 wiiproto_req_leds(wdata, state & ~flag);
263 else
264 wiiproto_req_leds(wdata, state | flag);
265 spin_unlock_irqrestore(&wdata->state.lock, flags);
266 break;
267 }
268 }
269}
270
271static int wiimote_input_event(struct input_dev *dev, unsigned int type,
272 unsigned int code, int value)
273{
274 return 0;
275}
276
277static int wiimote_input_open(struct input_dev *dev)
278{
279 struct wiimote_data *wdata = input_get_drvdata(dev);
280
281 return hid_hw_open(wdata->hdev);
282}
283
284static void wiimote_input_close(struct input_dev *dev)
285{
286 struct wiimote_data *wdata = input_get_drvdata(dev);
287
288 hid_hw_close(wdata->hdev);
289}
290
291static void handler_keys(struct wiimote_data *wdata, const __u8 *payload)
292{
293 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_LEFT],
294 !!(payload[0] & 0x01));
295 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_RIGHT],
296 !!(payload[0] & 0x02));
297 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_DOWN],
298 !!(payload[0] & 0x04));
299 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_UP],
300 !!(payload[0] & 0x08));
301 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_PLUS],
302 !!(payload[0] & 0x10));
303 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_TWO],
304 !!(payload[1] & 0x01));
305 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_ONE],
306 !!(payload[1] & 0x02));
307 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_B],
308 !!(payload[1] & 0x04));
309 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_A],
310 !!(payload[1] & 0x08));
311 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_MINUS],
312 !!(payload[1] & 0x10));
313 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_HOME],
314 !!(payload[1] & 0x80));
315 input_sync(wdata->input);
316}
317
318static void handler_status(struct wiimote_data *wdata, const __u8 *payload)
319{
320 handler_keys(wdata, payload);
321
322 /* on status reports the drm is reset so we need to resend the drm */
323 wiiproto_req_drm(wdata, WIIPROTO_REQ_NULL);
324}
325
326static void handler_return(struct wiimote_data *wdata, const __u8 *payload)
327{
328 __u8 err = payload[3];
329 __u8 cmd = payload[2];
330
331 handler_keys(wdata, payload);
332
333 if (err)
334 hid_warn(wdata->hdev, "Remote error %hhu on req %hhu\n", err,
335 cmd);
336}
337
338struct wiiproto_handler {
339 __u8 id;
340 size_t size;
341 void (*func)(struct wiimote_data *wdata, const __u8 *payload);
342};
343
344static struct wiiproto_handler handlers[] = {
345 { .id = WIIPROTO_REQ_STATUS, .size = 6, .func = handler_status },
346 { .id = WIIPROTO_REQ_RETURN, .size = 4, .func = handler_return },
347 { .id = WIIPROTO_REQ_DRM_K, .size = 2, .func = handler_keys },
348 { .id = 0 }
349};
350
351static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
352 u8 *raw_data, int size)
353{
354 struct wiimote_data *wdata = hid_get_drvdata(hdev);
355 struct wiiproto_handler *h;
356 int i;
357 unsigned long flags;
358
359 if (size < 1)
360 return -EINVAL;
361
362 spin_lock_irqsave(&wdata->state.lock, flags);
363
364 for (i = 0; handlers[i].id; ++i) {
365 h = &handlers[i];
366 if (h->id == raw_data[0] && h->size < size)
367 h->func(wdata, &raw_data[1]);
368 }
369
370 spin_unlock_irqrestore(&wdata->state.lock, flags);
371
372 return 0;
373}
374
375static void wiimote_leds_destroy(struct wiimote_data *wdata)
376{
377 int i;
378 struct led_classdev *led;
379
380 for (i = 0; i < 4; ++i) {
381 if (wdata->leds[i]) {
382 led = wdata->leds[i];
383 wdata->leds[i] = NULL;
384 led_classdev_unregister(led);
385 kfree(led);
386 }
387 }
388}
389
390static int wiimote_leds_create(struct wiimote_data *wdata)
391{
392 int i, ret;
393 struct device *dev = &wdata->hdev->dev;
394 size_t namesz = strlen(dev_name(dev)) + 9;
395 struct led_classdev *led;
396 char *name;
397
398 for (i = 0; i < 4; ++i) {
399 led = kzalloc(sizeof(struct led_classdev) + namesz, GFP_KERNEL);
400 if (!led) {
401 ret = -ENOMEM;
402 goto err;
403 }
404 name = (void*)&led[1];
405 snprintf(name, namesz, "%s:blue:p%d", dev_name(dev), i);
406 led->name = name;
407 led->brightness = 0;
408 led->max_brightness = 1;
409 led->brightness_get = wiimote_leds_get;
410 led->brightness_set = wiimote_leds_set;
411
412 ret = led_classdev_register(dev, led);
413 if (ret) {
414 kfree(led);
415 goto err;
416 }
417 wdata->leds[i] = led;
418 }
419
420 return 0;
421
422err:
423 wiimote_leds_destroy(wdata);
424 return ret;
425}
426
427static struct wiimote_data *wiimote_create(struct hid_device *hdev)
428{
429 struct wiimote_data *wdata;
430 int i;
431
432 wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);
433 if (!wdata)
434 return NULL;
435
436 wdata->input = input_allocate_device();
437 if (!wdata->input) {
438 kfree(wdata);
439 return NULL;
440 }
441
442 wdata->hdev = hdev;
443 hid_set_drvdata(hdev, wdata);
444
445 input_set_drvdata(wdata->input, wdata);
446 wdata->input->event = wiimote_input_event;
447 wdata->input->open = wiimote_input_open;
448 wdata->input->close = wiimote_input_close;
449 wdata->input->dev.parent = &wdata->hdev->dev;
450 wdata->input->id.bustype = wdata->hdev->bus;
451 wdata->input->id.vendor = wdata->hdev->vendor;
452 wdata->input->id.product = wdata->hdev->product;
453 wdata->input->id.version = wdata->hdev->version;
454 wdata->input->name = WIIMOTE_NAME;
455
456 set_bit(EV_KEY, wdata->input->evbit);
457 for (i = 0; i < WIIPROTO_KEY_COUNT; ++i)
458 set_bit(wiiproto_keymap[i], wdata->input->keybit);
459
460 spin_lock_init(&wdata->qlock);
461 INIT_WORK(&wdata->worker, wiimote_worker);
462
463 spin_lock_init(&wdata->state.lock);
464
465 return wdata;
466}
467
468static void wiimote_destroy(struct wiimote_data *wdata)
469{
470 wiimote_leds_destroy(wdata);
471
472 input_unregister_device(wdata->input);
473 cancel_work_sync(&wdata->worker);
474 hid_hw_stop(wdata->hdev);
475
476 kfree(wdata);
477}
478
479static int wiimote_hid_probe(struct hid_device *hdev,
480 const struct hid_device_id *id)
481{
482 struct wiimote_data *wdata;
483 int ret;
484
485 wdata = wiimote_create(hdev);
486 if (!wdata) {
487 hid_err(hdev, "Can't alloc device\n");
488 return -ENOMEM;
489 }
490
491 ret = hid_parse(hdev);
492 if (ret) {
493 hid_err(hdev, "HID parse failed\n");
494 goto err;
495 }
496
497 ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
498 if (ret) {
499 hid_err(hdev, "HW start failed\n");
500 goto err;
501 }
502
503 ret = input_register_device(wdata->input);
504 if (ret) {
505 hid_err(hdev, "Cannot register input device\n");
506 goto err_stop;
507 }
508
509 ret = wiimote_leds_create(wdata);
510 if (ret)
511 goto err_free;
512
513 hid_info(hdev, "New device registered\n");
514
515 /* by default set led1 after device initialization */
516 spin_lock_irq(&wdata->state.lock);
517 wiiproto_req_leds(wdata, WIIPROTO_FLAG_LED1);
518 spin_unlock_irq(&wdata->state.lock);
519
520 return 0;
521
522err_free:
523 wiimote_destroy(wdata);
524 return ret;
525
526err_stop:
527 hid_hw_stop(hdev);
528err:
529 input_free_device(wdata->input);
530 kfree(wdata);
531 return ret;
532}
533
534static void wiimote_hid_remove(struct hid_device *hdev)
535{
536 struct wiimote_data *wdata = hid_get_drvdata(hdev);
537
538 hid_info(hdev, "Device removed\n");
539 wiimote_destroy(wdata);
540}
541
542static const struct hid_device_id wiimote_hid_devices[] = {
543 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO,
544 USB_DEVICE_ID_NINTENDO_WIIMOTE) },
545 { }
546};
547MODULE_DEVICE_TABLE(hid, wiimote_hid_devices);
548
549static struct hid_driver wiimote_hid_driver = {
550 .name = "wiimote",
551 .id_table = wiimote_hid_devices,
552 .probe = wiimote_hid_probe,
553 .remove = wiimote_hid_remove,
554 .raw_event = wiimote_hid_event,
555};
556
557static int __init wiimote_init(void)
558{
559 int ret;
560
561 ret = hid_register_driver(&wiimote_hid_driver);
562 if (ret)
563 pr_err("Can't register wiimote hid driver\n");
564
565 return ret;
566}
567
568static void __exit wiimote_exit(void)
569{
570 hid_unregister_driver(&wiimote_hid_driver);
571}
572
573module_init(wiimote_init);
574module_exit(wiimote_exit);
575MODULE_LICENSE("GPL");
576MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>");
577MODULE_DESCRIPTION(WIIMOTE_NAME " Device Driver");
578MODULE_VERSION(WIIMOTE_VERSION);
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 38c261a40c7..ad978f5748d 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -1191,6 +1191,8 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
1191 if (intf->cur_altsetting->desc.bInterfaceProtocol == 1191 if (intf->cur_altsetting->desc.bInterfaceProtocol ==
1192 USB_INTERFACE_PROTOCOL_MOUSE) 1192 USB_INTERFACE_PROTOCOL_MOUSE)
1193 hid->type = HID_TYPE_USBMOUSE; 1193 hid->type = HID_TYPE_USBMOUSE;
1194 else if (intf->cur_altsetting->desc.bInterfaceProtocol == 0)
1195 hid->type = HID_TYPE_USBNONE;
1194 1196
1195 if (dev->manufacturer) 1197 if (dev->manufacturer)
1196 strlcpy(hid->name, dev->manufacturer, sizeof(hid->name)); 1198 strlcpy(hid->name, dev->manufacturer, sizeof(hid->name));
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 621959d5cc4..3146fdcda27 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -47,6 +47,7 @@ static const struct hid_blacklist {
47 { USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL }, 47 { USB_VENDOR_ID_AFATECH, USB_DEVICE_ID_AFATECH_AF9016, HID_QUIRK_FULLSPEED_INTERVAL },
48 48
49 { USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH, HID_QUIRK_MULTI_INPUT }, 49 { USB_VENDOR_ID_ETURBOTOUCH, USB_DEVICE_ID_ETURBOTOUCH, HID_QUIRK_MULTI_INPUT },
50 { USB_VENDOR_ID_GREENASIA, USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD, HID_QUIRK_MULTI_INPUT },
50 { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, 51 { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS },
51 { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, 52 { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT },
52 { USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, HID_QUIRK_MULTI_INPUT }, 53 { USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, HID_QUIRK_MULTI_INPUT },
@@ -89,6 +90,7 @@ static const struct hid_blacklist {
89 90
90 { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT }, 91 { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT },
91 { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT }, 92 { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT },
93 { USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS },
92 { 0, 0 } 94 { 0, 0 }
93}; 95};
94 96