aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-07-22 18:02:58 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-07-22 18:02:58 -0400
commit22a3b9771117d566def0150ea787fcc95f16e724 (patch)
tree20e24aa4df50cde8d28211531e893a7be61d1dfe
parentacb41c0f928fdb84a1c3753ac92c534a2a0f08d2 (diff)
parenta91f423e598912ab301592c7759cfd89e10682a1 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (31 commits) HID: fix support for Microsoft comfort mouse 4500 HID: hid-multitouch: add one new multitouch device's VID/PID HID: prodikeys: remove a redundant forward declaration of struct pcmidi_snd HID: prodikeys: make needlessly global symbols static HID: emsff: properly handle emsff_init failure HID: ACRUX - add missing hid_hw_stop() in ax_probe() error path HID: fix horizontal wheel for ms comfort mouse 4500 HID: uclogic: Add support for UC-Logic WP1062 HID: wiimote: Add sysfs support to wiimote driver HID: wiimote: Cache wiimote led state HID: wiimote: Add wiimote led request HID: wiimote: Add wiimote input button parser HID: wiimote: Add wiimote event handler HID: wiimote: Add output queue for wiimote driver HID: wiimote: Add wiimote send function HID: wiimote: Synchronize wiimote input and hid event handling HID: wiimote: Register input device in wiimote hid driver HID: wiimote: Add wiimote device structure HID: wiimote: Register wiimote hid driver stub HID: wiimote: Add Nintendo Wii Remote driver stub ...
-rw-r--r--Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus8
-rw-r--r--Documentation/ABI/testing/sysfs-driver-hid-wiimote10
-rw-r--r--drivers/hid/Kconfig44
-rw-r--r--drivers/hid/Makefile3
-rw-r--r--drivers/hid/hid-axff.c1
-rw-r--r--drivers/hid/hid-core.c13
-rw-r--r--drivers/hid/hid-emsff.c7
-rw-r--r--drivers/hid/hid-holtekff.c240
-rw-r--r--drivers/hid/hid-ids.h15
-rw-r--r--drivers/hid/hid-lg.c74
-rw-r--r--drivers/hid/hid-microsoft.c28
-rw-r--r--drivers/hid/hid-multitouch.c4
-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-wiimote.c489
-rw-r--r--drivers/hid/usbhid/hid-core.c2
-rw-r--r--include/linux/hid.h3
31 files changed, 1397 insertions, 136 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus b/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus
index c1b53b8bc2ae..65e6e5dd67e8 100644
--- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus
@@ -92,6 +92,14 @@ Description: The mouse has a tracking- and a distance-control-unit. These
92 This file is writeonly. 92 This file is writeonly.
93Users: http://roccat.sourceforge.net 93Users: http://roccat.sourceforge.net
94 94
95What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/talk
96Date: May 2011
97Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
98Description: Used to active some easy* functions of the mouse from outside.
99 The data has to be 16 bytes long.
100 This file is writeonly.
101Users: http://roccat.sourceforge.net
102
95What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu 103What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu
96Date: October 2010 104Date: October 2010
97Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 105Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-wiimote b/Documentation/ABI/testing/sysfs-driver-hid-wiimote
new file mode 100644
index 000000000000..5d5a16ea57c6
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-hid-wiimote
@@ -0,0 +1,10 @@
1What: /sys/bus/hid/drivers/wiimote/<dev>/led1
2What: /sys/bus/hid/drivers/wiimote/<dev>/led2
3What: /sys/bus/hid/drivers/wiimote/<dev>/led3
4What: /sys/bus/hid/drivers/wiimote/<dev>/led4
5Date: July 2011
6KernelVersion: 3.1
7Contact: David Herrmann <dh.herrmann@googlemail.com>
8Description: Make it possible to set/get current led state. Reading from it
9 returns 0 if led is off and 1 if it is on. Writing 0 to it
10 disables the led, writing 1 enables it.
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 36ca465c00ce..306b15f39c9c 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -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
@@ -322,6 +336,7 @@ config HID_MULTITOUCH
322 - Stantum multitouch panels 336 - Stantum multitouch panels
323 - Touch International Panels 337 - Touch International Panels
324 - Unitec Panels 338 - Unitec Panels
339 - XAT optical touch panels
325 340
326 If unsure, say N. 341 If unsure, say N.
327 342
@@ -435,6 +450,7 @@ config HID_QUANTA
435config HID_ROCCAT 450config HID_ROCCAT
436 tristate "Roccat special event support" 451 tristate "Roccat special event support"
437 depends on USB_HID 452 depends on USB_HID
453 select HID_ROCCAT_COMMON
438 ---help--- 454 ---help---
439 Support for Roccat special events. 455 Support for Roccat special events.
440 Say Y here if you have a Roccat mouse or keyboard and want OSD or 456 Say Y here if you have a Roccat mouse or keyboard and want OSD or
@@ -442,44 +458,40 @@ config HID_ROCCAT
442 458
443config HID_ROCCAT_COMMON 459config HID_ROCCAT_COMMON
444 tristate 460 tristate
461 depends on HID_ROCCAT
445 462
446config HID_ROCCAT_ARVO 463config HID_ROCCAT_ARVO
447 tristate "Roccat Arvo keyboard support" 464 tristate "Roccat Arvo keyboard support"
448 depends on USB_HID 465 depends on USB_HID
449 select HID_ROCCAT 466 depends on HID_ROCCAT
450 select HID_ROCCAT_COMMON
451 ---help--- 467 ---help---
452 Support for Roccat Arvo keyboard. 468 Support for Roccat Arvo keyboard.
453 469
454config HID_ROCCAT_KONE 470config HID_ROCCAT_KONE
455 tristate "Roccat Kone Mouse support" 471 tristate "Roccat Kone Mouse support"
456 depends on USB_HID 472 depends on USB_HID
457 select HID_ROCCAT 473 depends on HID_ROCCAT
458 select HID_ROCCAT_COMMON
459 ---help--- 474 ---help---
460 Support for Roccat Kone mouse. 475 Support for Roccat Kone mouse.
461 476
462config HID_ROCCAT_KONEPLUS 477config HID_ROCCAT_KONEPLUS
463 tristate "Roccat Kone[+] mouse support" 478 tristate "Roccat Kone[+] mouse support"
464 depends on USB_HID 479 depends on USB_HID
465 select HID_ROCCAT 480 depends on HID_ROCCAT
466 select HID_ROCCAT_COMMON
467 ---help--- 481 ---help---
468 Support for Roccat Kone[+] mouse. 482 Support for Roccat Kone[+] mouse.
469 483
470config HID_ROCCAT_KOVAPLUS 484config HID_ROCCAT_KOVAPLUS
471 tristate "Roccat Kova[+] mouse support" 485 tristate "Roccat Kova[+] mouse support"
472 depends on USB_HID 486 depends on USB_HID
473 select HID_ROCCAT 487 depends on HID_ROCCAT
474 select HID_ROCCAT_COMMON
475 ---help--- 488 ---help---
476 Support for Roccat Kova[+] mouse. 489 Support for Roccat Kova[+] mouse.
477 490
478config HID_ROCCAT_PYRA 491config HID_ROCCAT_PYRA
479 tristate "Roccat Pyra mouse support" 492 tristate "Roccat Pyra mouse support"
480 depends on USB_HID 493 depends on USB_HID
481 select HID_ROCCAT 494 depends on HID_ROCCAT
482 select HID_ROCCAT_COMMON
483 ---help--- 495 ---help---
484 Support for Roccat Pyra mouse. 496 Support for Roccat Pyra mouse.
485 497
@@ -495,6 +507,12 @@ config HID_SONY
495 ---help--- 507 ---help---
496 Support for Sony PS3 controller. 508 Support for Sony PS3 controller.
497 509
510config HID_SPEEDLINK
511 tristate "Speedlink VAD Cezanne mouse support"
512 depends on USB_HID
513 ---help---
514 Support for Speedlink Vicious and Divine Cezanne mouse.
515
498config HID_SUNPLUS 516config HID_SUNPLUS
499 tristate "Sunplus wireless desktop" 517 tristate "Sunplus wireless desktop"
500 depends on USB_HID 518 depends on USB_HID
@@ -568,6 +586,12 @@ config HID_WACOM_POWER_SUPPLY
568 Say Y here if you want to enable power supply status monitoring for 586 Say Y here if you want to enable power supply status monitoring for
569 Wacom Bluetooth devices. 587 Wacom Bluetooth devices.
570 588
589config HID_WIIMOTE
590 tristate "Nintendo Wii Remote support"
591 depends on BT_HIDP
592 ---help---
593 Support for the Nintendo Wii Remote bluetooth device.
594
571config HID_ZEROPLUS 595config HID_ZEROPLUS
572 tristate "Zeroplus based game controller support" 596 tristate "Zeroplus based game controller support"
573 depends on USB_HID 597 depends on USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index f8cc4ea7335a..0a0a38e9fd28 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-axff.c b/drivers/hid/hid-axff.c
index b4554288de00..121514149e0b 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 6f3289a57888..1a5cf0c9cfca 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1388,6 +1388,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) }, 1388 { 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) }, 1389 { 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) }, 1390 { HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) },
1391 { 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) }, 1392 { 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) }, 1393 { 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) }, 1394 { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
@@ -1426,10 +1427,12 @@ static const struct hid_device_id hid_have_special_driver[] = {
1426 { HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH_DUAL) }, 1427 { HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH_DUAL) },
1427 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) }, 1428 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) },
1428 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) }, 1429 { HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) },
1430 { 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) }, 1431 { 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) }, 1432 { 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) }, 1433 { 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) }, 1434 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) },
1435 { 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) }, 1436 { 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) }, 1437 { 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) }, 1438 { HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
@@ -1491,6 +1494,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) }, 1494 { 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) }, 1495 { 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) }, 1496 { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) },
1497 { 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) }, 1498 { 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) }, 1499 { 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) }, 1500 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
@@ -1499,11 +1503,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) }, 1503 { 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) }, 1504 { 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) }, 1505 { HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH) },
1506 { HID_USB_DEVICE(USB_VENDOR_ID_XAT, USB_DEVICE_ID_XAT_CSR) },
1507 { HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) },
1502 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) }, 1508 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0005) },
1503 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) }, 1509 { HID_USB_DEVICE(USB_VENDOR_ID_ZEROPLUS, 0x0030) },
1504 { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) }, 1510 { HID_USB_DEVICE(USB_VENDOR_ID_ZYDACRON, USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL) },
1505 1511
1506 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) }, 1512 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT) },
1513 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_WIIMOTE) },
1507 { } 1514 { }
1508}; 1515};
1509 1516
@@ -1771,7 +1778,6 @@ static const struct hid_device_id hid_ignore_list[] = {
1771 { HID_USB_DEVICE(USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006) }, 1778 { 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) }, 1779 { 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) }, 1780 { 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) }, 1781 { 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) }, 1782 { 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) }, 1783 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) },
@@ -1912,6 +1918,11 @@ static bool hid_ignore(struct hid_device *hdev)
1912 hdev->product <= USB_DEVICE_ID_HANWANG_TABLET_LAST) 1918 hdev->product <= USB_DEVICE_ID_HANWANG_TABLET_LAST)
1913 return true; 1919 return true;
1914 break; 1920 break;
1921 case USB_VENDOR_ID_JESS:
1922 if (hdev->product == USB_DEVICE_ID_JESS_YUREX &&
1923 hdev->type == HID_TYPE_USBNONE)
1924 return true;
1925 break;
1915 } 1926 }
1916 1927
1917 if (hdev->type == HID_TYPE_USBMOUSE && 1928 if (hdev->type == HID_TYPE_USBMOUSE &&
diff --git a/drivers/hid/hid-emsff.c b/drivers/hid/hid-emsff.c
index 81877c67caea..a5dc13fe367b 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 000000000000..91e3a032112b
--- /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 a756ee6c7df5..db63ccf21cc8 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -350,6 +350,9 @@
350#define USB_VENDOR_ID_ILITEK 0x222a 350#define USB_VENDOR_ID_ILITEK 0x222a
351#define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001 351#define USB_DEVICE_ID_ILITEK_MULTITOUCH 0x0001
352 352
353#define USB_VENDOR_ID_HOLTEK 0x1241
354#define USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP 0x5015
355
353#define USB_VENDOR_ID_IMATION 0x0718 356#define USB_VENDOR_ID_IMATION 0x0718
354#define USB_DEVICE_ID_DISC_STAKKA 0xd000 357#define USB_DEVICE_ID_DISC_STAKKA 0xd000
355 358
@@ -472,6 +475,8 @@
472#define USB_DEVICE_ID_MS_LK6K 0x00f9 475#define USB_DEVICE_ID_MS_LK6K 0x00f9
473#define USB_DEVICE_ID_MS_PRESENTER_8K_BT 0x0701 476#define USB_DEVICE_ID_MS_PRESENTER_8K_BT 0x0701
474#define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713 477#define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713
478#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730
479#define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c
475 480
476#define USB_VENDOR_ID_MOJO 0x8282 481#define USB_VENDOR_ID_MOJO 0x8282
477#define USB_DEVICE_ID_RETRO_ADAPTER 0x3201 482#define USB_DEVICE_ID_RETRO_ADAPTER 0x3201
@@ -495,6 +500,9 @@
495#define USB_VENDOR_ID_NEXTWINDOW 0x1926 500#define USB_VENDOR_ID_NEXTWINDOW 0x1926
496#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003 501#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003
497 502
503#define USB_VENDOR_ID_NINTENDO 0x057e
504#define USB_DEVICE_ID_NINTENDO_WIIMOTE 0x0306
505
498#define USB_VENDOR_ID_NTRIG 0x1b96 506#define USB_VENDOR_ID_NTRIG 0x1b96
499#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001 507#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001
500#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003 508#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003
@@ -630,6 +638,7 @@
630#define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003 638#define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U 0x0003
631#define USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U 0x0004 639#define USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U 0x0004
632#define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005 640#define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U 0x0005
641#define USB_DEVICE_ID_UCLOGIC_TABLET_WP1062 0x0064
633 642
634#define USB_VENDOR_ID_UNITEC 0x227d 643#define USB_VENDOR_ID_UNITEC 0x227d
635#define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709 644#define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709 0x0709
@@ -663,6 +672,12 @@
663#define USB_VENDOR_ID_WISEGROUP_LTD2 0x6677 672#define USB_VENDOR_ID_WISEGROUP_LTD2 0x6677
664#define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802 673#define USB_DEVICE_ID_SMARTJOY_DUAL_PLUS 0x8802
665 674
675#define USB_VENDOR_ID_X_TENSIONS 0x1ae7
676#define USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE 0x9001
677
678#define USB_VENDOR_ID_XAT 0x2505
679#define USB_DEVICE_ID_XAT_CSR 0x0220
680
666#define USB_VENDOR_ID_YEALINK 0x6993 681#define USB_VENDOR_ID_YEALINK 0x6993
667#define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001 682#define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001
668 683
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index 21f205f09250..a7f916e8fc32 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-microsoft.c b/drivers/hid/hid-microsoft.c
index 0f6fc54dc196..e5c699b6c6f3 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 62cac4dc3b62..58d0e7aaf088 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -727,6 +727,10 @@ static const struct hid_device_id mt_devices[] = {
727 { .driver_data = MT_CLS_DEFAULT, 727 { .driver_data = MT_CLS_DEFAULT,
728 HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, 728 HID_USB_DEVICE(USB_VENDOR_ID_UNITEC,
729 USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) }, 729 USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) },
730 /* XAT */
731 { .driver_data = MT_CLS_DEFAULT,
732 HID_USB_DEVICE(USB_VENDOR_ID_XAT,
733 USB_DEVICE_ID_XAT_CSR) },
730 734
731 { } 735 { }
732}; 736};
diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c
index ab19f2905d27..158b389d0fb7 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 2307471d96dc..093bfad00b02 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 d284a781c99e..ce8415e4f009 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 13b1eb0c8c65..edf898dee28b 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 fe45fae05bb9..9a5bc61f9699 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 a57838d15267..2b8f3a31ffb3 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 4109a028e138..64abb5b8a59a 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 5b640a7a15a7..59e47770fa10 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 c57a376ab8ae..c03332a4fa9a 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 984be2f8967e..1f8336e3f584 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 ce40607d21c7..fb2aed44a8e0 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 38280c055a19..8140776bd8c5 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 14cbbe1621e0..0442d7fa2dcf 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 936c911fdca6..5cd25bd907f8 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 000000000000..602013741718
--- /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 05fdc85a76e5..e15732f1a22d 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-wiimote.c b/drivers/hid/hid-wiimote.c
new file mode 100644
index 000000000000..a594383ce03d
--- /dev/null
+++ b/drivers/hid/hid-wiimote.c
@@ -0,0 +1,489 @@
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/atomic.h>
14#include <linux/device.h>
15#include <linux/hid.h>
16#include <linux/input.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 atomic_t ready;
37 struct hid_device *hdev;
38 struct input_dev *input;
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
56enum wiiproto_reqs {
57 WIIPROTO_REQ_LED = 0x11,
58 WIIPROTO_REQ_DRM_K = 0x30,
59};
60
61enum wiiproto_keys {
62 WIIPROTO_KEY_LEFT,
63 WIIPROTO_KEY_RIGHT,
64 WIIPROTO_KEY_UP,
65 WIIPROTO_KEY_DOWN,
66 WIIPROTO_KEY_PLUS,
67 WIIPROTO_KEY_MINUS,
68 WIIPROTO_KEY_ONE,
69 WIIPROTO_KEY_TWO,
70 WIIPROTO_KEY_A,
71 WIIPROTO_KEY_B,
72 WIIPROTO_KEY_HOME,
73 WIIPROTO_KEY_COUNT
74};
75
76static __u16 wiiproto_keymap[] = {
77 KEY_LEFT, /* WIIPROTO_KEY_LEFT */
78 KEY_RIGHT, /* WIIPROTO_KEY_RIGHT */
79 KEY_UP, /* WIIPROTO_KEY_UP */
80 KEY_DOWN, /* WIIPROTO_KEY_DOWN */
81 KEY_NEXT, /* WIIPROTO_KEY_PLUS */
82 KEY_PREVIOUS, /* WIIPROTO_KEY_MINUS */
83 BTN_1, /* WIIPROTO_KEY_ONE */
84 BTN_2, /* WIIPROTO_KEY_TWO */
85 BTN_A, /* WIIPROTO_KEY_A */
86 BTN_B, /* WIIPROTO_KEY_B */
87 BTN_MODE, /* WIIPROTO_KEY_HOME */
88};
89
90#define dev_to_wii(pdev) hid_get_drvdata(container_of(pdev, struct hid_device, \
91 dev))
92
93static ssize_t wiimote_hid_send(struct hid_device *hdev, __u8 *buffer,
94 size_t count)
95{
96 __u8 *buf;
97 ssize_t ret;
98
99 if (!hdev->hid_output_raw_report)
100 return -ENODEV;
101
102 buf = kmemdup(buffer, count, GFP_KERNEL);
103 if (!buf)
104 return -ENOMEM;
105
106 ret = hdev->hid_output_raw_report(hdev, buf, count, HID_OUTPUT_REPORT);
107
108 kfree(buf);
109 return ret;
110}
111
112static void wiimote_worker(struct work_struct *work)
113{
114 struct wiimote_data *wdata = container_of(work, struct wiimote_data,
115 worker);
116 unsigned long flags;
117
118 spin_lock_irqsave(&wdata->qlock, flags);
119
120 while (wdata->head != wdata->tail) {
121 spin_unlock_irqrestore(&wdata->qlock, flags);
122 wiimote_hid_send(wdata->hdev, wdata->outq[wdata->tail].data,
123 wdata->outq[wdata->tail].size);
124 spin_lock_irqsave(&wdata->qlock, flags);
125
126 wdata->tail = (wdata->tail + 1) % WIIMOTE_BUFSIZE;
127 }
128
129 spin_unlock_irqrestore(&wdata->qlock, flags);
130}
131
132static void wiimote_queue(struct wiimote_data *wdata, const __u8 *buffer,
133 size_t count)
134{
135 unsigned long flags;
136 __u8 newhead;
137
138 if (count > HID_MAX_BUFFER_SIZE) {
139 hid_warn(wdata->hdev, "Sending too large output report\n");
140 return;
141 }
142
143 /*
144 * Copy new request into our output queue and check whether the
145 * queue is full. If it is full, discard this request.
146 * If it is empty we need to start a new worker that will
147 * send out the buffer to the hid device.
148 * If the queue is not empty, then there must be a worker
149 * that is currently sending out our buffer and this worker
150 * will reschedule itself until the queue is empty.
151 */
152
153 spin_lock_irqsave(&wdata->qlock, flags);
154
155 memcpy(wdata->outq[wdata->head].data, buffer, count);
156 wdata->outq[wdata->head].size = count;
157 newhead = (wdata->head + 1) % WIIMOTE_BUFSIZE;
158
159 if (wdata->head == wdata->tail) {
160 wdata->head = newhead;
161 schedule_work(&wdata->worker);
162 } else if (newhead != wdata->tail) {
163 wdata->head = newhead;
164 } else {
165 hid_warn(wdata->hdev, "Output queue is full");
166 }
167
168 spin_unlock_irqrestore(&wdata->qlock, flags);
169}
170
171static void wiiproto_req_leds(struct wiimote_data *wdata, int leds)
172{
173 __u8 cmd[2];
174
175 leds &= WIIPROTO_FLAGS_LEDS;
176 if ((wdata->state.flags & WIIPROTO_FLAGS_LEDS) == leds)
177 return;
178 wdata->state.flags = (wdata->state.flags & ~WIIPROTO_FLAGS_LEDS) | leds;
179
180 cmd[0] = WIIPROTO_REQ_LED;
181 cmd[1] = 0;
182
183 if (leds & WIIPROTO_FLAG_LED1)
184 cmd[1] |= 0x10;
185 if (leds & WIIPROTO_FLAG_LED2)
186 cmd[1] |= 0x20;
187 if (leds & WIIPROTO_FLAG_LED3)
188 cmd[1] |= 0x40;
189 if (leds & WIIPROTO_FLAG_LED4)
190 cmd[1] |= 0x80;
191
192 wiimote_queue(wdata, cmd, sizeof(cmd));
193}
194
195#define wiifs_led_show_set(num) \
196static ssize_t wiifs_led_show_##num(struct device *dev, \
197 struct device_attribute *attr, char *buf) \
198{ \
199 struct wiimote_data *wdata = dev_to_wii(dev); \
200 unsigned long flags; \
201 int state; \
202 \
203 if (!atomic_read(&wdata->ready)) \
204 return -EBUSY; \
205 \
206 spin_lock_irqsave(&wdata->state.lock, flags); \
207 state = !!(wdata->state.flags & WIIPROTO_FLAG_LED##num); \
208 spin_unlock_irqrestore(&wdata->state.lock, flags); \
209 \
210 return sprintf(buf, "%d\n", state); \
211} \
212static ssize_t wiifs_led_set_##num(struct device *dev, \
213 struct device_attribute *attr, const char *buf, size_t count) \
214{ \
215 struct wiimote_data *wdata = dev_to_wii(dev); \
216 int tmp = simple_strtoul(buf, NULL, 10); \
217 unsigned long flags; \
218 __u8 state; \
219 \
220 if (!atomic_read(&wdata->ready)) \
221 return -EBUSY; \
222 \
223 spin_lock_irqsave(&wdata->state.lock, flags); \
224 \
225 state = wdata->state.flags; \
226 \
227 if (tmp) \
228 wiiproto_req_leds(wdata, state | WIIPROTO_FLAG_LED##num);\
229 else \
230 wiiproto_req_leds(wdata, state & ~WIIPROTO_FLAG_LED##num);\
231 \
232 spin_unlock_irqrestore(&wdata->state.lock, flags); \
233 \
234 return count; \
235} \
236static DEVICE_ATTR(led##num, S_IRUGO | S_IWUSR, wiifs_led_show_##num, \
237 wiifs_led_set_##num)
238
239wiifs_led_show_set(1);
240wiifs_led_show_set(2);
241wiifs_led_show_set(3);
242wiifs_led_show_set(4);
243
244static int wiimote_input_event(struct input_dev *dev, unsigned int type,
245 unsigned int code, int value)
246{
247 struct wiimote_data *wdata = input_get_drvdata(dev);
248
249 if (!atomic_read(&wdata->ready))
250 return -EBUSY;
251 /* smp_rmb: Make sure wdata->xy is available when wdata->ready is 1 */
252 smp_rmb();
253
254 return 0;
255}
256
257static void handler_keys(struct wiimote_data *wdata, const __u8 *payload)
258{
259 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_LEFT],
260 !!(payload[0] & 0x01));
261 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_RIGHT],
262 !!(payload[0] & 0x02));
263 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_DOWN],
264 !!(payload[0] & 0x04));
265 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_UP],
266 !!(payload[0] & 0x08));
267 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_PLUS],
268 !!(payload[0] & 0x10));
269 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_TWO],
270 !!(payload[1] & 0x01));
271 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_ONE],
272 !!(payload[1] & 0x02));
273 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_B],
274 !!(payload[1] & 0x04));
275 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_A],
276 !!(payload[1] & 0x08));
277 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_MINUS],
278 !!(payload[1] & 0x10));
279 input_report_key(wdata->input, wiiproto_keymap[WIIPROTO_KEY_HOME],
280 !!(payload[1] & 0x80));
281 input_sync(wdata->input);
282}
283
284struct wiiproto_handler {
285 __u8 id;
286 size_t size;
287 void (*func)(struct wiimote_data *wdata, const __u8 *payload);
288};
289
290static struct wiiproto_handler handlers[] = {
291 { .id = WIIPROTO_REQ_DRM_K, .size = 2, .func = handler_keys },
292 { .id = 0 }
293};
294
295static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report,
296 u8 *raw_data, int size)
297{
298 struct wiimote_data *wdata = hid_get_drvdata(hdev);
299 struct wiiproto_handler *h;
300 int i;
301 unsigned long flags;
302
303 if (!atomic_read(&wdata->ready))
304 return -EBUSY;
305 /* smp_rmb: Make sure wdata->xy is available when wdata->ready is 1 */
306 smp_rmb();
307
308 if (size < 1)
309 return -EINVAL;
310
311 spin_lock_irqsave(&wdata->state.lock, flags);
312
313 for (i = 0; handlers[i].id; ++i) {
314 h = &handlers[i];
315 if (h->id == raw_data[0] && h->size < size)
316 h->func(wdata, &raw_data[1]);
317 }
318
319 spin_unlock_irqrestore(&wdata->state.lock, flags);
320
321 return 0;
322}
323
324static struct wiimote_data *wiimote_create(struct hid_device *hdev)
325{
326 struct wiimote_data *wdata;
327 int i;
328
329 wdata = kzalloc(sizeof(*wdata), GFP_KERNEL);
330 if (!wdata)
331 return NULL;
332
333 wdata->input = input_allocate_device();
334 if (!wdata->input) {
335 kfree(wdata);
336 return NULL;
337 }
338
339 wdata->hdev = hdev;
340 hid_set_drvdata(hdev, wdata);
341
342 input_set_drvdata(wdata->input, wdata);
343 wdata->input->event = wiimote_input_event;
344 wdata->input->dev.parent = &wdata->hdev->dev;
345 wdata->input->id.bustype = wdata->hdev->bus;
346 wdata->input->id.vendor = wdata->hdev->vendor;
347 wdata->input->id.product = wdata->hdev->product;
348 wdata->input->id.version = wdata->hdev->version;
349 wdata->input->name = WIIMOTE_NAME;
350
351 set_bit(EV_KEY, wdata->input->evbit);
352 for (i = 0; i < WIIPROTO_KEY_COUNT; ++i)
353 set_bit(wiiproto_keymap[i], wdata->input->keybit);
354
355 spin_lock_init(&wdata->qlock);
356 INIT_WORK(&wdata->worker, wiimote_worker);
357
358 spin_lock_init(&wdata->state.lock);
359
360 return wdata;
361}
362
363static void wiimote_destroy(struct wiimote_data *wdata)
364{
365 kfree(wdata);
366}
367
368static int wiimote_hid_probe(struct hid_device *hdev,
369 const struct hid_device_id *id)
370{
371 struct wiimote_data *wdata;
372 int ret;
373
374 wdata = wiimote_create(hdev);
375 if (!wdata) {
376 hid_err(hdev, "Can't alloc device\n");
377 return -ENOMEM;
378 }
379
380 ret = device_create_file(&hdev->dev, &dev_attr_led1);
381 if (ret)
382 goto err;
383 ret = device_create_file(&hdev->dev, &dev_attr_led2);
384 if (ret)
385 goto err;
386 ret = device_create_file(&hdev->dev, &dev_attr_led3);
387 if (ret)
388 goto err;
389 ret = device_create_file(&hdev->dev, &dev_attr_led4);
390 if (ret)
391 goto err;
392
393 ret = hid_parse(hdev);
394 if (ret) {
395 hid_err(hdev, "HID parse failed\n");
396 goto err;
397 }
398
399 ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
400 if (ret) {
401 hid_err(hdev, "HW start failed\n");
402 goto err;
403 }
404
405 ret = input_register_device(wdata->input);
406 if (ret) {
407 hid_err(hdev, "Cannot register input device\n");
408 goto err_stop;
409 }
410
411 /* smp_wmb: Write wdata->xy first before wdata->ready is set to 1 */
412 smp_wmb();
413 atomic_set(&wdata->ready, 1);
414 hid_info(hdev, "New device registered\n");
415
416 /* by default set led1 after device initialization */
417 spin_lock_irq(&wdata->state.lock);
418 wiiproto_req_leds(wdata, WIIPROTO_FLAG_LED1);
419 spin_unlock_irq(&wdata->state.lock);
420
421 return 0;
422
423err_stop:
424 hid_hw_stop(hdev);
425err:
426 input_free_device(wdata->input);
427 device_remove_file(&hdev->dev, &dev_attr_led1);
428 device_remove_file(&hdev->dev, &dev_attr_led2);
429 device_remove_file(&hdev->dev, &dev_attr_led3);
430 device_remove_file(&hdev->dev, &dev_attr_led4);
431 wiimote_destroy(wdata);
432 return ret;
433}
434
435static void wiimote_hid_remove(struct hid_device *hdev)
436{
437 struct wiimote_data *wdata = hid_get_drvdata(hdev);
438
439 hid_info(hdev, "Device removed\n");
440
441 device_remove_file(&hdev->dev, &dev_attr_led1);
442 device_remove_file(&hdev->dev, &dev_attr_led2);
443 device_remove_file(&hdev->dev, &dev_attr_led3);
444 device_remove_file(&hdev->dev, &dev_attr_led4);
445
446 hid_hw_stop(hdev);
447 input_unregister_device(wdata->input);
448
449 cancel_work_sync(&wdata->worker);
450 wiimote_destroy(wdata);
451}
452
453static const struct hid_device_id wiimote_hid_devices[] = {
454 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO,
455 USB_DEVICE_ID_NINTENDO_WIIMOTE) },
456 { }
457};
458MODULE_DEVICE_TABLE(hid, wiimote_hid_devices);
459
460static struct hid_driver wiimote_hid_driver = {
461 .name = "wiimote",
462 .id_table = wiimote_hid_devices,
463 .probe = wiimote_hid_probe,
464 .remove = wiimote_hid_remove,
465 .raw_event = wiimote_hid_event,
466};
467
468static int __init wiimote_init(void)
469{
470 int ret;
471
472 ret = hid_register_driver(&wiimote_hid_driver);
473 if (ret)
474 pr_err("Can't register wiimote hid driver\n");
475
476 return ret;
477}
478
479static void __exit wiimote_exit(void)
480{
481 hid_unregister_driver(&wiimote_hid_driver);
482}
483
484module_init(wiimote_init);
485module_exit(wiimote_exit);
486MODULE_LICENSE("GPL");
487MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>");
488MODULE_DESCRIPTION(WIIMOTE_NAME " Device Driver");
489MODULE_VERSION(WIIMOTE_VERSION);
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 38c261a40c74..ad978f5748d3 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/include/linux/hid.h b/include/linux/hid.h
index 42f7e2fb501f..9cf8e7ae7450 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -453,7 +453,8 @@ struct hid_input {
453 453
454enum hid_type { 454enum hid_type {
455 HID_TYPE_OTHER = 0, 455 HID_TYPE_OTHER = 0,
456 HID_TYPE_USBMOUSE 456 HID_TYPE_USBMOUSE,
457 HID_TYPE_USBNONE
457}; 458};
458 459
459struct hid_driver; 460struct hid_driver;