aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-24 16:30:14 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-24 16:30:14 -0400
commite8ff13b0bf88b5e696323a1eec877783d965b3c6 (patch)
treeaa55093da5ee435f0d2fa8ffede8973f426dbd67 /drivers
parent0cd5ff591ab6473355d5a6a47f7694def28e451d (diff)
parentc062c4d1de57789bf15f7641a24c429eeb8a1c6a (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID updates from Jiri Kosina: "The list of changes worth pointing out explicitly: - We are getting 'UHID', which is a new framework for implementing HID transport drivers in userspace (this is different from HIDRAW, which is transport-independent and provides report parsing facilities; uhid is for the other (transport) part of the pipeline). It's needed for (and currently being used by) Bluetooth-LowEnergy, as its specification mandates things we don't want in the kernel. Written by David Herrmann. - there have been quite a few bugs in runtime suspend/resume paths (probably never reported to actually happen in the wild, but still). Alan Stern fixed those. - a few other driver updates and fixes and random new device support." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (45 commits) HID: add ASUS AIO keyboard model AK1D HID: add support for Cypress barcode scanner 04B4:ED81 HID: Allow drivers to be their own listener HID: usbhid: fix error paths in suspend HID: usbhid: check for suspend or reset before restarting HID: usbhid: replace HID_REPORTED_IDLE with HID_SUSPENDED HID: usbhid: inline some simple routines HID: usbhid: fix autosuspend calls HID: usbhid: fix use-after-free bug HID: hid-core: optimize in case of hidraw HID: hidraw: fix list->buffer memleak HID: uhid: Fix sending events with invalid data HID: roccat: added sensor sysfs attribute for Savu HID: Add driver for Holtek based keyboards with broken HID HID: Add suport for the brightness control keys on HP keyboards HID: magicmouse: Implement Multi-touch Protocol B (MT-B) HID: magicmouse: Removing report_touches switch HID: roccat: rename roccat_common functions to roccat_common2 HID: roccat: fix wrong hid_err usage on struct usb_device HID: roccat: move functionality to roccat-common ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/hid/Kconfig40
-rw-r--r--drivers/hid/Makefile6
-rw-r--r--drivers/hid/hid-chicony.c1
-rw-r--r--drivers/hid/hid-core.c21
-rw-r--r--drivers/hid/hid-cypress.c2
-rw-r--r--drivers/hid/hid-holtek-kbd.c183
-rw-r--r--drivers/hid/hid-ids.h12
-rw-r--r--drivers/hid/hid-input.c9
-rw-r--r--drivers/hid/hid-lenovo-tpkbd.c564
-rw-r--r--drivers/hid/hid-magicmouse.c157
-rw-r--r--drivers/hid/hid-multitouch.c18
-rw-r--r--drivers/hid/hid-picolcd.c6
-rw-r--r--drivers/hid/hid-roccat-arvo.c16
-rw-r--r--drivers/hid/hid-roccat-common.c72
-rw-r--r--drivers/hid/hid-roccat-common.h16
-rw-r--r--drivers/hid/hid-roccat-isku.c52
-rw-r--r--drivers/hid/hid-roccat-isku.h7
-rw-r--r--drivers/hid/hid-roccat-kone.c6
-rw-r--r--drivers/hid/hid-roccat-koneplus.c98
-rw-r--r--drivers/hid/hid-roccat-koneplus.h22
-rw-r--r--drivers/hid/hid-roccat-kovaplus.c71
-rw-r--r--drivers/hid/hid-roccat-kovaplus.h15
-rw-r--r--drivers/hid/hid-roccat-pyra.c59
-rw-r--r--drivers/hid/hid-roccat-pyra.h12
-rw-r--r--drivers/hid/hid-roccat-savu.c316
-rw-r--r--drivers/hid/hid-roccat-savu.h87
-rw-r--r--drivers/hid/hid-wiimote-ext.c2
-rw-r--r--drivers/hid/hidraw.c12
-rw-r--r--drivers/hid/uhid.c572
-rw-r--r--drivers/hid/usbhid/hid-core.c294
-rw-r--r--drivers/hid/usbhid/usbhid.h1
31 files changed, 2195 insertions, 554 deletions
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 3fda8c87f02c..fbf49503508d 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -53,6 +53,27 @@ config HIDRAW
53 53
54 If unsure, say Y. 54 If unsure, say Y.
55 55
56config UHID
57 tristate "User-space I/O driver support for HID subsystem"
58 depends on HID
59 default n
60 ---help---
61 Say Y here if you want to provide HID I/O Drivers from user-space.
62 This allows to write I/O drivers in user-space and feed the data from
63 the device into the kernel. The kernel parses the HID reports, loads the
64 corresponding HID Device Driver or provides input devices on top of your
65 user-space device.
66
67 This driver cannot be used to parse HID-reports in user-space and write
68 special HID-drivers. You should use hidraw for that.
69 Instead, this driver allows to write the transport-layer driver in
70 user-space like USB-HID and Bluetooth-HID do in kernel-space.
71
72 If unsure, say N.
73
74 To compile this driver as a module, choose M here: the
75 module will be called uhid.
76
56config HID_GENERIC 77config HID_GENERIC
57 tristate "Generic HID driver" 78 tristate "Generic HID driver"
58 depends on HID 79 depends on HID
@@ -193,10 +214,12 @@ config HID_EZKEY
193 Support for Ezkey BTC 8193 keyboard. 214 Support for Ezkey BTC 8193 keyboard.
194 215
195config HID_HOLTEK 216config HID_HOLTEK
196 tristate "Holtek On Line Grip based game controller support" 217 tristate "Holtek HID devices"
197 depends on USB_HID 218 depends on USB_HID
198 ---help--- 219 ---help---
199 Say Y here if you have a Holtek On Line Grip based game controller. 220 Support for Holtek based devices:
221 - Holtek On Line Grip based game controller
222 - Trust GXT 18 Gaming Keyboard
200 223
201config HOLTEK_FF 224config HOLTEK_FF
202 bool "Holtek On Line Grip force feedback support" 225 bool "Holtek On Line Grip force feedback support"
@@ -261,6 +284,19 @@ config HID_LCPOWER
261 ---help--- 284 ---help---
262 Support for LC-Power RC1000MCE RF remote control. 285 Support for LC-Power RC1000MCE RF remote control.
263 286
287config HID_LENOVO_TPKBD
288 tristate "Lenovo ThinkPad USB Keyboard with TrackPoint"
289 depends on USB_HID
290 select NEW_LEDS
291 select LEDS_CLASS
292 ---help---
293 Support for the Lenovo ThinkPad USB Keyboard with TrackPoint.
294
295 Say Y here if you have a Lenovo ThinkPad USB Keyboard with TrackPoint
296 and would like to use device-specific features like changing the
297 sensitivity of the trackpoint, using the microphone mute button or
298 controlling the mute and microphone mute LEDs.
299
264config HID_LOGITECH 300config HID_LOGITECH
265 tristate "Logitech devices" if EXPERT 301 tristate "Logitech devices" if EXPERT
266 depends on USB_HID 302 depends on USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index ca6cc9f0485c..f975485f88b2 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -8,6 +8,7 @@ ifdef CONFIG_DEBUG_FS
8endif 8endif
9 9
10obj-$(CONFIG_HID) += hid.o 10obj-$(CONFIG_HID) += hid.o
11obj-$(CONFIG_UHID) += uhid.o
11 12
12obj-$(CONFIG_HID_GENERIC) += hid-generic.o 13obj-$(CONFIG_HID_GENERIC) += hid-generic.o
13 14
@@ -48,12 +49,14 @@ obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o
48obj-$(CONFIG_HID_ELECOM) += hid-elecom.o 49obj-$(CONFIG_HID_ELECOM) += hid-elecom.o
49obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o 50obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
50obj-$(CONFIG_HID_GYRATION) += hid-gyration.o 51obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
52obj-$(CONFIG_HID_HOLTEK) += hid-holtek-kbd.o
51obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o 53obj-$(CONFIG_HID_HOLTEK) += hid-holtekff.o
52obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o 54obj-$(CONFIG_HID_HYPERV_MOUSE) += hid-hyperv.o
53obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o 55obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
54obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o 56obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o
55obj-$(CONFIG_HID_KYE) += hid-kye.o 57obj-$(CONFIG_HID_KYE) += hid-kye.o
56obj-$(CONFIG_HID_LCPOWER) += hid-lcpower.o 58obj-$(CONFIG_HID_LCPOWER) += hid-lcpower.o
59obj-$(CONFIG_HID_LENOVO_TPKBD) += hid-lenovo-tpkbd.o
57obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o 60obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o
58obj-$(CONFIG_HID_LOGITECH_DJ) += hid-logitech-dj.o 61obj-$(CONFIG_HID_LOGITECH_DJ) += hid-logitech-dj.o
59obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o 62obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o
@@ -69,7 +72,8 @@ obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o
69obj-$(CONFIG_HID_PRIMAX) += hid-primax.o 72obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
70obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ 73obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \
71 hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ 74 hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \
72 hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-pyra.o 75 hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-pyra.o \
76 hid-roccat-savu.o
73obj-$(CONFIG_HID_SAITEK) += hid-saitek.o 77obj-$(CONFIG_HID_SAITEK) += hid-saitek.o
74obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o 78obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
75obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o 79obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c
index b99af346fdff..a2abb8e15727 100644
--- a/drivers/hid/hid-chicony.c
+++ b/drivers/hid/hid-chicony.c
@@ -60,6 +60,7 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
60static const struct hid_device_id ch_devices[] = { 60static const struct hid_device_id ch_devices[] = {
61 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, 61 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
62 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, 62 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) },
63 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) },
63 { } 64 { }
64}; 65};
65MODULE_DEVICE_TABLE(hid, ch_devices); 66MODULE_DEVICE_TABLE(hid, ch_devices);
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 4c87276c8ddb..500844f04f93 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1194,8 +1194,10 @@ int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size,
1194 goto out; 1194 goto out;
1195 } 1195 }
1196 1196
1197 for (a = 0; a < report->maxfield; a++) 1197 if (hid->claimed != HID_CLAIMED_HIDRAW) {
1198 hid_input_field(hid, report->field[a], cdata, interrupt); 1198 for (a = 0; a < report->maxfield; a++)
1199 hid_input_field(hid, report->field[a], cdata, interrupt);
1200 }
1199 1201
1200 if (hid->claimed & HID_CLAIMED_INPUT) 1202 if (hid->claimed & HID_CLAIMED_INPUT)
1201 hidinput_report_event(hid, report); 1203 hidinput_report_event(hid, report);
@@ -1243,6 +1245,10 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
1243 goto unlock; 1245 goto unlock;
1244 } 1246 }
1245 1247
1248 /* Avoid unnecessary overhead if debugfs is disabled */
1249 if (list_empty(&hid->debug_list))
1250 goto nomem;
1251
1246 buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC); 1252 buf = kmalloc(sizeof(char) * HID_DEBUG_BUFSIZE, GFP_ATOMIC);
1247 1253
1248 if (!buf) 1254 if (!buf)
@@ -1373,8 +1379,10 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask)
1373 if ((connect_mask & HID_CONNECT_HIDRAW) && !hidraw_connect(hdev)) 1379 if ((connect_mask & HID_CONNECT_HIDRAW) && !hidraw_connect(hdev))
1374 hdev->claimed |= HID_CLAIMED_HIDRAW; 1380 hdev->claimed |= HID_CLAIMED_HIDRAW;
1375 1381
1376 if (!hdev->claimed) { 1382 /* Drivers with the ->raw_event callback set are not required to connect
1377 hid_err(hdev, "claimed by neither input, hiddev nor hidraw\n"); 1383 * to any other listener. */
1384 if (!hdev->claimed && !hdev->driver->raw_event) {
1385 hid_err(hdev, "device has no listeners, quitting\n");
1378 return -ENODEV; 1386 return -ENODEV;
1379 } 1387 }
1380 1388
@@ -1521,10 +1529,12 @@ static const struct hid_device_id hid_have_special_driver[] = {
1521 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, 1529 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) },
1522 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) }, 1530 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) },
1523 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, 1531 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) },
1532 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) },
1524 { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, 1533 { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) },
1525 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, 1534 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
1526 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, 1535 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
1527 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) }, 1536 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) },
1537 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_4) },
1528 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, 1538 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
1529 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, 1539 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
1530 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) }, 1540 { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0011) },
@@ -1539,6 +1549,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1539 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) }, 1549 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
1540 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) }, 1550 { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
1541 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) }, 1551 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK, USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP) },
1552 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) },
1542 { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) }, 1553 { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
1543 { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) }, 1554 { HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
1544 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) }, 1555 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
@@ -1547,6 +1558,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1547 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) }, 1558 { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X) },
1548 { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) }, 1559 { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
1549 { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) }, 1560 { HID_USB_DEVICE(USB_VENDOR_ID_LCPOWER, USB_DEVICE_ID_LCPOWER_LC1000 ) },
1561 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) },
1550 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) }, 1562 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
1551 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) }, 1563 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
1552 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) }, 1564 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) },
@@ -1620,6 +1632,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1620 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) }, 1632 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) },
1621 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, 1633 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
1622 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) }, 1634 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) },
1635 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) },
1623 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) }, 1636 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) },
1624 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, 1637 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
1625 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, 1638 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c
index 2f0be4c66af7..9e43aaca9774 100644
--- a/drivers/hid/hid-cypress.c
+++ b/drivers/hid/hid-cypress.c
@@ -129,6 +129,8 @@ static const struct hid_device_id cp_devices[] = {
129 .driver_data = CP_RDESC_SWAPPED_MIN_MAX }, 129 .driver_data = CP_RDESC_SWAPPED_MIN_MAX },
130 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3), 130 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3),
131 .driver_data = CP_RDESC_SWAPPED_MIN_MAX }, 131 .driver_data = CP_RDESC_SWAPPED_MIN_MAX },
132 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_4),
133 .driver_data = CP_RDESC_SWAPPED_MIN_MAX },
132 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE), 134 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE),
133 .driver_data = CP_2WHEEL_MOUSE_HACK }, 135 .driver_data = CP_2WHEEL_MOUSE_HACK },
134 { } 136 { }
diff --git a/drivers/hid/hid-holtek-kbd.c b/drivers/hid/hid-holtek-kbd.c
new file mode 100644
index 000000000000..e0a5d1739fc3
--- /dev/null
+++ b/drivers/hid/hid-holtek-kbd.c
@@ -0,0 +1,183 @@
1/*
2 * HID driver for Holtek keyboard
3 * Copyright (c) 2012 Tom Harwood
4*/
5
6/*
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 */
12
13#include <linux/device.h>
14#include <linux/hid.h>
15#include <linux/module.h>
16#include <linux/usb.h>
17
18#include "hid-ids.h"
19#include "usbhid/usbhid.h"
20
21/* Holtek based keyboards (USB ID 04d9:a055) have the following issues:
22 * - The report descriptor specifies an excessively large number of consumer
23 * usages (2^15), which is more than HID_MAX_USAGES. This prevents proper
24 * parsing of the report descriptor.
25 * - The report descriptor reports on caps/scroll/num lock key presses, but
26 * doesn't have an LED output usage block.
27 *
28 * The replacement descriptor below fixes the number of consumer usages,
29 * and provides an LED output usage block. LED output events are redirected
30 * to the boot interface.
31 */
32
33static __u8 holtek_kbd_rdesc_fixed[] = {
34 /* Original report descriptor, with reduced number of consumer usages */
35 0x05, 0x01, /* Usage Page (Desktop), */
36 0x09, 0x80, /* Usage (Sys Control), */
37 0xA1, 0x01, /* Collection (Application), */
38 0x85, 0x01, /* Report ID (1), */
39 0x19, 0x81, /* Usage Minimum (Sys Power Down), */
40 0x29, 0x83, /* Usage Maximum (Sys Wake Up), */
41 0x15, 0x00, /* Logical Minimum (0), */
42 0x25, 0x01, /* Logical Maximum (1), */
43 0x95, 0x03, /* Report Count (3), */
44 0x75, 0x01, /* Report Size (1), */
45 0x81, 0x02, /* Input (Variable), */
46 0x95, 0x01, /* Report Count (1), */
47 0x75, 0x05, /* Report Size (5), */
48 0x81, 0x01, /* Input (Constant), */
49 0xC0, /* End Collection, */
50 0x05, 0x0C, /* Usage Page (Consumer), */
51 0x09, 0x01, /* Usage (Consumer Control), */
52 0xA1, 0x01, /* Collection (Application), */
53 0x85, 0x02, /* Report ID (2), */
54 0x19, 0x00, /* Usage Minimum (00h), */
55 0x2A, 0xFF, 0x2F, /* Usage Maximum (0x2FFF), previously 0x7FFF */
56 0x15, 0x00, /* Logical Minimum (0), */
57 0x26, 0xFF, 0x2F, /* Logical Maximum (0x2FFF),previously 0x7FFF*/
58 0x95, 0x01, /* Report Count (1), */
59 0x75, 0x10, /* Report Size (16), */
60 0x81, 0x00, /* Input, */
61 0xC0, /* End Collection, */
62 0x05, 0x01, /* Usage Page (Desktop), */
63 0x09, 0x06, /* Usage (Keyboard), */
64 0xA1, 0x01, /* Collection (Application), */
65 0x85, 0x03, /* Report ID (3), */
66 0x95, 0x38, /* Report Count (56), */
67 0x75, 0x01, /* Report Size (1), */
68 0x15, 0x00, /* Logical Minimum (0), */
69 0x25, 0x01, /* Logical Maximum (1), */
70 0x05, 0x07, /* Usage Page (Keyboard), */
71 0x19, 0xE0, /* Usage Minimum (KB Leftcontrol), */
72 0x29, 0xE7, /* Usage Maximum (KB Right GUI), */
73 0x19, 0x00, /* Usage Minimum (None), */
74 0x29, 0x2F, /* Usage Maximum (KB Lboxbracket And Lbrace),*/
75 0x81, 0x02, /* Input (Variable), */
76 0xC0, /* End Collection, */
77 0x05, 0x01, /* Usage Page (Desktop), */
78 0x09, 0x06, /* Usage (Keyboard), */
79 0xA1, 0x01, /* Collection (Application), */
80 0x85, 0x04, /* Report ID (4), */
81 0x95, 0x38, /* Report Count (56), */
82 0x75, 0x01, /* Report Size (1), */
83 0x15, 0x00, /* Logical Minimum (0), */
84 0x25, 0x01, /* Logical Maximum (1), */
85 0x05, 0x07, /* Usage Page (Keyboard), */
86 0x19, 0x30, /* Usage Minimum (KB Rboxbracket And Rbrace),*/
87 0x29, 0x67, /* Usage Maximum (KP Equals), */
88 0x81, 0x02, /* Input (Variable), */
89 0xC0, /* End Collection */
90
91 /* LED usage for the boot protocol interface */
92 0x05, 0x01, /* Usage Page (Desktop), */
93 0x09, 0x06, /* Usage (Keyboard), */
94 0xA1, 0x01, /* Collection (Application), */
95 0x05, 0x08, /* Usage Page (LED), */
96 0x19, 0x01, /* Usage Minimum (01h), */
97 0x29, 0x03, /* Usage Maximum (03h), */
98 0x15, 0x00, /* Logical Minimum (0), */
99 0x25, 0x01, /* Logical Maximum (1), */
100 0x75, 0x01, /* Report Size (1), */
101 0x95, 0x03, /* Report Count (3), */
102 0x91, 0x02, /* Output (Variable), */
103 0x95, 0x05, /* Report Count (5), */
104 0x91, 0x01, /* Output (Constant), */
105 0xC0, /* End Collection */
106};
107
108static __u8 *holtek_kbd_report_fixup(struct hid_device *hdev, __u8 *rdesc,
109 unsigned int *rsize)
110{
111 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
112
113 if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
114 rdesc = holtek_kbd_rdesc_fixed;
115 *rsize = sizeof(holtek_kbd_rdesc_fixed);
116 }
117 return rdesc;
118}
119
120static int holtek_kbd_input_event(struct input_dev *dev, unsigned int type,
121 unsigned int code,
122 int value)
123{
124 struct hid_device *hid = input_get_drvdata(dev);
125 struct usb_device *usb_dev = hid_to_usb_dev(hid);
126
127 /* Locate the boot interface, to receive the LED change events */
128 struct usb_interface *boot_interface = usb_ifnum_to_if(usb_dev, 0);
129
130 struct hid_device *boot_hid = usb_get_intfdata(boot_interface);
131 struct hid_input *boot_hid_input = list_first_entry(&boot_hid->inputs,
132 struct hid_input, list);
133
134 return boot_hid_input->input->event(boot_hid_input->input, type, code,
135 value);
136}
137
138static int holtek_kbd_probe(struct hid_device *hdev,
139 const struct hid_device_id *id)
140{
141 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
142 int ret = hid_parse(hdev);
143
144 if (!ret)
145 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
146
147 if (!ret && intf->cur_altsetting->desc.bInterfaceNumber == 1) {
148 struct hid_input *hidinput;
149 list_for_each_entry(hidinput, &hdev->inputs, list) {
150 hidinput->input->event = holtek_kbd_input_event;
151 }
152 }
153
154 return ret;
155}
156
157static const struct hid_device_id holtek_kbd_devices[] = {
158 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT,
159 USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) },
160 { }
161};
162MODULE_DEVICE_TABLE(hid, holtek_kbd_devices);
163
164static struct hid_driver holtek_kbd_driver = {
165 .name = "holtek_kbd",
166 .id_table = holtek_kbd_devices,
167 .report_fixup = holtek_kbd_report_fixup,
168 .probe = holtek_kbd_probe
169};
170
171static int __init holtek_kbd_init(void)
172{
173 return hid_register_driver(&holtek_kbd_driver);
174}
175
176static void __exit holtek_kbd_exit(void)
177{
178 hid_unregister_driver(&holtek_kbd_driver);
179}
180
181module_exit(holtek_kbd_exit);
182module_init(holtek_kbd_init);
183MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 32039235cfee..41c34f21bd00 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -208,6 +208,7 @@
208#define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d 208#define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d
209#define USB_DEVICE_ID_CHICONY_WIRELESS 0x0618 209#define USB_DEVICE_ID_CHICONY_WIRELESS 0x0618
210#define USB_DEVICE_ID_CHICONY_WIRELESS2 0x1123 210#define USB_DEVICE_ID_CHICONY_WIRELESS2 0x1123
211#define USB_DEVICE_ID_CHICONY_AK1D 0x1125
211 212
212#define USB_VENDOR_ID_CHUNGHWAT 0x2247 213#define USB_VENDOR_ID_CHUNGHWAT 0x2247
213#define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH 0x0001 214#define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH 0x0001
@@ -237,6 +238,7 @@
237#define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61 238#define USB_DEVICE_ID_CYPRESS_BARCODE_1 0xde61
238#define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64 239#define USB_DEVICE_ID_CYPRESS_BARCODE_2 0xde64
239#define USB_DEVICE_ID_CYPRESS_BARCODE_3 0xbca1 240#define USB_DEVICE_ID_CYPRESS_BARCODE_3 0xbca1
241#define USB_DEVICE_ID_CYPRESS_BARCODE_4 0xed81
240#define USB_DEVICE_ID_CYPRESS_TRUETOUCH 0xc001 242#define USB_DEVICE_ID_CYPRESS_TRUETOUCH 0xc001
241 243
242#define USB_VENDOR_ID_DEALEXTREAME 0x10c5 244#define USB_VENDOR_ID_DEALEXTREAME 0x10c5
@@ -410,6 +412,9 @@
410#define USB_VENDOR_ID_HOLTEK 0x1241 412#define USB_VENDOR_ID_HOLTEK 0x1241
411#define USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP 0x5015 413#define USB_DEVICE_ID_HOLTEK_ON_LINE_GRIP 0x5015
412 414
415#define USB_VENDOR_ID_HOLTEK_ALT 0x04d9
416#define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD 0xa055
417
413#define USB_VENDOR_ID_IMATION 0x0718 418#define USB_VENDOR_ID_IMATION 0x0718
414#define USB_DEVICE_ID_DISC_STAKKA 0xd000 419#define USB_DEVICE_ID_DISC_STAKKA 0xd000
415 420
@@ -479,6 +484,9 @@
479#define USB_DEVICE_ID_LD_HYBRID 0x2090 484#define USB_DEVICE_ID_LD_HYBRID 0x2090
480#define USB_DEVICE_ID_LD_HEATCONTROL 0x20A0 485#define USB_DEVICE_ID_LD_HEATCONTROL 0x20A0
481 486
487#define USB_VENDOR_ID_LENOVO 0x17ef
488#define USB_DEVICE_ID_LENOVO_TPKBD 0x6009
489
482#define USB_VENDOR_ID_LG 0x1fd2 490#define USB_VENDOR_ID_LG 0x1fd2
483#define USB_DEVICE_ID_LG_MULTITOUCH 0x0064 491#define USB_DEVICE_ID_LG_MULTITOUCH 0x0064
484 492
@@ -573,6 +581,9 @@
573#define USB_VENDOR_ID_NINTENDO 0x057e 581#define USB_VENDOR_ID_NINTENDO 0x057e
574#define USB_DEVICE_ID_NINTENDO_WIIMOTE 0x0306 582#define USB_DEVICE_ID_NINTENDO_WIIMOTE 0x0306
575 583
584#define USB_VENDOR_ID_NOVATEK 0x0603
585#define USB_DEVICE_ID_NOVATEK_PCT 0x0600
586
576#define USB_VENDOR_ID_NTRIG 0x1b96 587#define USB_VENDOR_ID_NTRIG 0x1b96
577#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001 588#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001
578#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003 589#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003
@@ -650,6 +661,7 @@
650#define USB_DEVICE_ID_ROCCAT_KOVAPLUS 0x2d50 661#define USB_DEVICE_ID_ROCCAT_KOVAPLUS 0x2d50
651#define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24 662#define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24
652#define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6 663#define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6
664#define USB_DEVICE_ID_ROCCAT_SAVU 0x2d5a
653 665
654#define USB_VENDOR_ID_SAITEK 0x06a3 666#define USB_VENDOR_ID_SAITEK 0x06a3
655#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17 667#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 5301006f6c15..811bfad64609 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -837,6 +837,15 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
837 } 837 }
838 break; 838 break;
839 839
840 case HID_UP_HPVENDOR2:
841 set_bit(EV_REP, input->evbit);
842 switch (usage->hid & HID_USAGE) {
843 case 0x003: map_key_clear(KEY_BRIGHTNESSDOWN); break;
844 case 0x004: map_key_clear(KEY_BRIGHTNESSUP); break;
845 default: goto ignore;
846 }
847 break;
848
840 case HID_UP_MSVENDOR: 849 case HID_UP_MSVENDOR:
841 goto ignore; 850 goto ignore;
842 851
diff --git a/drivers/hid/hid-lenovo-tpkbd.c b/drivers/hid/hid-lenovo-tpkbd.c
new file mode 100644
index 000000000000..77d2df04c97b
--- /dev/null
+++ b/drivers/hid/hid-lenovo-tpkbd.c
@@ -0,0 +1,564 @@
1/*
2 * HID driver for Lenovo ThinkPad USB Keyboard with TrackPoint
3 *
4 * Copyright (c) 2012 Bernhard Seibold
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 */
13
14#include <linux/module.h>
15#include <linux/sysfs.h>
16#include <linux/device.h>
17#include <linux/usb.h>
18#include <linux/hid.h>
19#include <linux/input.h>
20#include <linux/leds.h>
21#include "usbhid/usbhid.h"
22
23#include "hid-ids.h"
24
25/* This is only used for the trackpoint part of the driver, hence _tp */
26struct tpkbd_data_pointer {
27 int led_state;
28 struct led_classdev led_mute;
29 struct led_classdev led_micmute;
30 int press_to_select;
31 int dragging;
32 int release_to_select;
33 int select_right;
34 int sensitivity;
35 int press_speed;
36};
37
38#define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
39
40static int tpkbd_input_mapping(struct hid_device *hdev,
41 struct hid_input *hi, struct hid_field *field,
42 struct hid_usage *usage, unsigned long **bit, int *max)
43{
44 struct usbhid_device *uhdev;
45
46 uhdev = (struct usbhid_device *) hdev->driver_data;
47 if (uhdev->ifnum == 1 && usage->hid == (HID_UP_BUTTON | 0x0010)) {
48 map_key_clear(KEY_MICMUTE);
49 return 1;
50 }
51 return 0;
52}
53
54#undef map_key_clear
55
56static int tpkbd_features_set(struct hid_device *hdev)
57{
58 struct hid_report *report;
59 struct tpkbd_data_pointer *data_pointer;
60
61 data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev);
62 report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[4];
63
64 report->field[0]->value[0] = data_pointer->press_to_select ? 0x01 : 0x02;
65 report->field[0]->value[0] |= data_pointer->dragging ? 0x04 : 0x08;
66 report->field[0]->value[0] |= data_pointer->release_to_select ? 0x10 : 0x20;
67 report->field[0]->value[0] |= data_pointer->select_right ? 0x80 : 0x40;
68 report->field[1]->value[0] = 0x03; // unknown setting, imitate windows driver
69 report->field[2]->value[0] = data_pointer->sensitivity;
70 report->field[3]->value[0] = data_pointer->press_speed;
71
72 usbhid_submit_report(hdev, report, USB_DIR_OUT);
73 return 0;
74}
75
76static ssize_t pointer_press_to_select_show(struct device *dev,
77 struct device_attribute *attr,
78 char *buf)
79{
80 struct hid_device *hdev;
81 struct tpkbd_data_pointer *data_pointer;
82
83 hdev = container_of(dev, struct hid_device, dev);
84 if (hdev == NULL)
85 return -ENODEV;
86
87 data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev);
88
89 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->press_to_select);
90}
91
92static ssize_t pointer_press_to_select_store(struct device *dev,
93 struct device_attribute *attr,
94 const char *buf,
95 size_t count)
96{
97 struct hid_device *hdev;
98 struct tpkbd_data_pointer *data_pointer;
99 int value;
100
101 hdev = container_of(dev, struct hid_device, dev);
102 if (hdev == NULL)
103 return -ENODEV;
104
105 data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev);
106
107 if (kstrtoint(buf, 10, &value))
108 return -EINVAL;
109 if (value < 0 || value > 1)
110 return -EINVAL;
111
112 data_pointer->press_to_select = value;
113 tpkbd_features_set(hdev);
114
115 return count;
116}
117
118static ssize_t pointer_dragging_show(struct device *dev,
119 struct device_attribute *attr,
120 char *buf)
121{
122 struct hid_device *hdev;
123 struct tpkbd_data_pointer *data_pointer;
124
125 hdev = container_of(dev, struct hid_device, dev);
126 if (hdev == NULL)
127 return -ENODEV;
128
129 data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev);
130
131 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->dragging);
132}
133
134static ssize_t pointer_dragging_store(struct device *dev,
135 struct device_attribute *attr,
136 const char *buf,
137 size_t count)
138{
139 struct hid_device *hdev;
140 struct tpkbd_data_pointer *data_pointer;
141 int value;
142
143 hdev = container_of(dev, struct hid_device, dev);
144 if (hdev == NULL)
145 return -ENODEV;
146
147 data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev);
148
149 if (kstrtoint(buf, 10, &value))
150 return -EINVAL;
151 if (value < 0 || value > 1)
152 return -EINVAL;
153
154 data_pointer->dragging = value;
155 tpkbd_features_set(hdev);
156
157 return count;
158}
159
160static ssize_t pointer_release_to_select_show(struct device *dev,
161 struct device_attribute *attr,
162 char *buf)
163{
164 struct hid_device *hdev;
165 struct tpkbd_data_pointer *data_pointer;
166
167 hdev = container_of(dev, struct hid_device, dev);
168 if (hdev == NULL)
169 return -ENODEV;
170
171 data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev);
172
173 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->release_to_select);
174}
175
176static ssize_t pointer_release_to_select_store(struct device *dev,
177 struct device_attribute *attr,
178 const char *buf,
179 size_t count)
180{
181 struct hid_device *hdev;
182 struct tpkbd_data_pointer *data_pointer;
183 int value;
184
185 hdev = container_of(dev, struct hid_device, dev);
186 if (hdev == NULL)
187 return -ENODEV;
188
189 data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev);
190
191 if (kstrtoint(buf, 10, &value))
192 return -EINVAL;
193 if (value < 0 || value > 1)
194 return -EINVAL;
195
196 data_pointer->release_to_select = value;
197 tpkbd_features_set(hdev);
198
199 return count;
200}
201
202static ssize_t pointer_select_right_show(struct device *dev,
203 struct device_attribute *attr,
204 char *buf)
205{
206 struct hid_device *hdev;
207 struct tpkbd_data_pointer *data_pointer;
208
209 hdev = container_of(dev, struct hid_device, dev);
210 if (hdev == NULL)
211 return -ENODEV;
212
213 data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev);
214
215 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->select_right);
216}
217
218static ssize_t pointer_select_right_store(struct device *dev,
219 struct device_attribute *attr,
220 const char *buf,
221 size_t count)
222{
223 struct hid_device *hdev;
224 struct tpkbd_data_pointer *data_pointer;
225 int value;
226
227 hdev = container_of(dev, struct hid_device, dev);
228 if (hdev == NULL)
229 return -ENODEV;
230
231 data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev);
232
233 if (kstrtoint(buf, 10, &value))
234 return -EINVAL;
235 if (value < 0 || value > 1)
236 return -EINVAL;
237
238 data_pointer->select_right = value;
239 tpkbd_features_set(hdev);
240
241 return count;
242}
243
244static ssize_t pointer_sensitivity_show(struct device *dev,
245 struct device_attribute *attr,
246 char *buf)
247{
248 struct hid_device *hdev;
249 struct tpkbd_data_pointer *data_pointer;
250
251 hdev = container_of(dev, struct hid_device, dev);
252 if (hdev == NULL)
253 return -ENODEV;
254
255 data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev);
256
257 return snprintf(buf, PAGE_SIZE, "%u\n",
258 data_pointer->sensitivity);
259}
260
261static ssize_t pointer_sensitivity_store(struct device *dev,
262 struct device_attribute *attr,
263 const char *buf,
264 size_t count)
265{
266 struct hid_device *hdev;
267 struct tpkbd_data_pointer *data_pointer;
268 int value;
269
270 hdev = container_of(dev, struct hid_device, dev);
271 if (hdev == NULL)
272 return -ENODEV;
273
274 data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev);
275
276 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255)
277 return -EINVAL;
278
279 data_pointer->sensitivity = value;
280 tpkbd_features_set(hdev);
281
282 return count;
283}
284
285static ssize_t pointer_press_speed_show(struct device *dev,
286 struct device_attribute *attr,
287 char *buf)
288{
289 struct hid_device *hdev;
290 struct tpkbd_data_pointer *data_pointer;
291
292 hdev = container_of(dev, struct hid_device, dev);
293 if (hdev == NULL)
294 return -ENODEV;
295
296 data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev);
297
298 return snprintf(buf, PAGE_SIZE, "%u\n",
299 data_pointer->press_speed);
300}
301
302static ssize_t pointer_press_speed_store(struct device *dev,
303 struct device_attribute *attr,
304 const char *buf,
305 size_t count)
306{
307 struct hid_device *hdev;
308 struct tpkbd_data_pointer *data_pointer;
309 int value;
310
311 hdev = container_of(dev, struct hid_device, dev);
312 if (hdev == NULL)
313 return -ENODEV;
314
315 data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev);
316
317 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255)
318 return -EINVAL;
319
320 data_pointer->press_speed = value;
321 tpkbd_features_set(hdev);
322
323 return count;
324}
325
326static struct device_attribute dev_attr_pointer_press_to_select =
327 __ATTR(press_to_select, S_IWUSR | S_IRUGO,
328 pointer_press_to_select_show,
329 pointer_press_to_select_store);
330
331static struct device_attribute dev_attr_pointer_dragging =
332 __ATTR(dragging, S_IWUSR | S_IRUGO,
333 pointer_dragging_show,
334 pointer_dragging_store);
335
336static struct device_attribute dev_attr_pointer_release_to_select =
337 __ATTR(release_to_select, S_IWUSR | S_IRUGO,
338 pointer_release_to_select_show,
339 pointer_release_to_select_store);
340
341static struct device_attribute dev_attr_pointer_select_right =
342 __ATTR(select_right, S_IWUSR | S_IRUGO,
343 pointer_select_right_show,
344 pointer_select_right_store);
345
346static struct device_attribute dev_attr_pointer_sensitivity =
347 __ATTR(sensitivity, S_IWUSR | S_IRUGO,
348 pointer_sensitivity_show,
349 pointer_sensitivity_store);
350
351static struct device_attribute dev_attr_pointer_press_speed =
352 __ATTR(press_speed, S_IWUSR | S_IRUGO,
353 pointer_press_speed_show,
354 pointer_press_speed_store);
355
356static struct attribute *tpkbd_attributes_pointer[] = {
357 &dev_attr_pointer_press_to_select.attr,
358 &dev_attr_pointer_dragging.attr,
359 &dev_attr_pointer_release_to_select.attr,
360 &dev_attr_pointer_select_right.attr,
361 &dev_attr_pointer_sensitivity.attr,
362 &dev_attr_pointer_press_speed.attr,
363 NULL
364};
365
366static const struct attribute_group tpkbd_attr_group_pointer = {
367 .attrs = tpkbd_attributes_pointer,
368};
369
370static enum led_brightness tpkbd_led_brightness_get(
371 struct led_classdev *led_cdev)
372{
373 struct device *dev;
374 struct hid_device *hdev;
375 struct tpkbd_data_pointer *data_pointer;
376 int led_nr = 0;
377
378 dev = led_cdev->dev->parent;
379 hdev = container_of(dev, struct hid_device, dev);
380 data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev);
381
382 if (led_cdev == &data_pointer->led_micmute)
383 led_nr = 1;
384
385 return data_pointer->led_state & (1 << led_nr)
386 ? LED_FULL
387 : LED_OFF;
388}
389
390static void tpkbd_led_brightness_set(struct led_classdev *led_cdev,
391 enum led_brightness value)
392{
393 struct device *dev;
394 struct hid_device *hdev;
395 struct hid_report *report;
396 struct tpkbd_data_pointer *data_pointer;
397 int led_nr = 0;
398
399 dev = led_cdev->dev->parent;
400 hdev = container_of(dev, struct hid_device, dev);
401 data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev);
402
403 if (led_cdev == &data_pointer->led_micmute)
404 led_nr = 1;
405
406 if (value == LED_OFF)
407 data_pointer->led_state &= ~(1 << led_nr);
408 else
409 data_pointer->led_state |= 1 << led_nr;
410
411 report = hdev->report_enum[HID_OUTPUT_REPORT].report_id_hash[3];
412 report->field[0]->value[0] = (data_pointer->led_state >> 0) & 1;
413 report->field[0]->value[1] = (data_pointer->led_state >> 1) & 1;
414 usbhid_submit_report(hdev, report, USB_DIR_OUT);
415}
416
417static int tpkbd_probe_tp(struct hid_device *hdev)
418{
419 struct device *dev = &hdev->dev;
420 struct tpkbd_data_pointer *data_pointer;
421 size_t name_sz = strlen(dev_name(dev)) + 16;
422 char *name_mute, *name_micmute;
423 int ret;
424
425 if (sysfs_create_group(&hdev->dev.kobj,
426 &tpkbd_attr_group_pointer)) {
427 hid_warn(hdev, "Could not create sysfs group\n");
428 }
429
430 data_pointer = kzalloc(sizeof(struct tpkbd_data_pointer), GFP_KERNEL);
431 if (data_pointer == NULL) {
432 hid_err(hdev, "Could not allocate memory for driver data\n");
433 return -ENOMEM;
434 }
435
436 // set same default values as windows driver
437 data_pointer->sensitivity = 0xa0;
438 data_pointer->press_speed = 0x38;
439
440 name_mute = kzalloc(name_sz, GFP_KERNEL);
441 if (name_mute == NULL) {
442 hid_err(hdev, "Could not allocate memory for led data\n");
443 ret = -ENOMEM;
444 goto err;
445 }
446 snprintf(name_mute, name_sz, "%s:amber:mute", dev_name(dev));
447
448 name_micmute = kzalloc(name_sz, GFP_KERNEL);
449 if (name_micmute == NULL) {
450 hid_err(hdev, "Could not allocate memory for led data\n");
451 ret = -ENOMEM;
452 goto err2;
453 }
454 snprintf(name_micmute, name_sz, "%s:amber:micmute", dev_name(dev));
455
456 hid_set_drvdata(hdev, data_pointer);
457
458 data_pointer->led_mute.name = name_mute;
459 data_pointer->led_mute.brightness_get = tpkbd_led_brightness_get;
460 data_pointer->led_mute.brightness_set = tpkbd_led_brightness_set;
461 data_pointer->led_mute.dev = dev;
462 led_classdev_register(dev, &data_pointer->led_mute);
463
464 data_pointer->led_micmute.name = name_micmute;
465 data_pointer->led_micmute.brightness_get = tpkbd_led_brightness_get;
466 data_pointer->led_micmute.brightness_set = tpkbd_led_brightness_set;
467 data_pointer->led_micmute.dev = dev;
468 led_classdev_register(dev, &data_pointer->led_micmute);
469
470 tpkbd_features_set(hdev);
471
472 return 0;
473
474err2:
475 kfree(name_mute);
476err:
477 kfree(data_pointer);
478 return ret;
479}
480
481static int tpkbd_probe(struct hid_device *hdev,
482 const struct hid_device_id *id)
483{
484 int ret;
485 struct usbhid_device *uhdev;
486
487 ret = hid_parse(hdev);
488 if (ret) {
489 hid_err(hdev, "hid_parse failed\n");
490 goto err_free;
491 }
492
493 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
494 if (ret) {
495 hid_err(hdev, "hid_hw_start failed\n");
496 goto err_free;
497 }
498
499 uhdev = (struct usbhid_device *) hdev->driver_data;
500
501 if (uhdev->ifnum == 1)
502 return tpkbd_probe_tp(hdev);
503
504 return 0;
505err_free:
506 return ret;
507}
508
509static void tpkbd_remove_tp(struct hid_device *hdev)
510{
511 struct tpkbd_data_pointer *data_pointer;
512
513 sysfs_remove_group(&hdev->dev.kobj,
514 &tpkbd_attr_group_pointer);
515
516 data_pointer = (struct tpkbd_data_pointer *) hid_get_drvdata(hdev);
517
518 led_classdev_unregister(&data_pointer->led_micmute);
519 led_classdev_unregister(&data_pointer->led_mute);
520
521 hid_set_drvdata(hdev, NULL);
522 kfree(data_pointer);
523}
524
525static void tpkbd_remove(struct hid_device *hdev)
526{
527 struct usbhid_device *uhdev;
528
529 uhdev = (struct usbhid_device *) hdev->driver_data;
530 if (uhdev->ifnum == 1)
531 tpkbd_remove_tp(hdev);
532
533 hid_hw_stop(hdev);
534}
535
536static const struct hid_device_id tpkbd_devices[] = {
537 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) },
538 { }
539};
540
541MODULE_DEVICE_TABLE(hid, tpkbd_devices);
542
543static struct hid_driver tpkbd_driver = {
544 .name = "lenovo_tpkbd",
545 .id_table = tpkbd_devices,
546 .input_mapping = tpkbd_input_mapping,
547 .probe = tpkbd_probe,
548 .remove = tpkbd_remove,
549};
550
551static int __init tpkbd_init(void)
552{
553 return hid_register_driver(&tpkbd_driver);
554}
555
556static void __exit tpkbd_exit(void)
557{
558 hid_unregister_driver(&tpkbd_driver);
559}
560
561module_init(tpkbd_init);
562module_exit(tpkbd_exit);
563
564MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index 40ac6654f1d1..73647266daad 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -16,6 +16,7 @@
16 16
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/hid.h> 18#include <linux/hid.h>
19#include <linux/input/mt.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
21#include <linux/usb.h> 22#include <linux/usb.h>
@@ -48,10 +49,6 @@ static bool scroll_acceleration = false;
48module_param(scroll_acceleration, bool, 0644); 49module_param(scroll_acceleration, bool, 0644);
49MODULE_PARM_DESC(scroll_acceleration, "Accelerate sequential scroll events"); 50MODULE_PARM_DESC(scroll_acceleration, "Accelerate sequential scroll events");
50 51
51static bool report_touches = true;
52module_param(report_touches, bool, 0644);
53MODULE_PARM_DESC(report_touches, "Emit touch records (otherwise, only use them for emulation)");
54
55static bool report_undeciphered; 52static bool report_undeciphered;
56module_param(report_undeciphered, bool, 0644); 53module_param(report_undeciphered, bool, 0644);
57MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event"); 54MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state field using a MSC_RAW event");
@@ -72,15 +69,6 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
72 69
73#define SCROLL_ACCEL_DEFAULT 7 70#define SCROLL_ACCEL_DEFAULT 7
74 71
75/* Single touch emulation should only begin when no touches are currently down.
76 * This is true when single_touch_id is equal to NO_TOUCHES. If multiple touches
77 * are down and the touch providing for single touch emulation is lifted,
78 * single_touch_id is equal to SINGLE_TOUCH_UP. While single touch emulation is
79 * occurring, single_touch_id corresponds with the tracking id of the touch used.
80 */
81#define NO_TOUCHES -1
82#define SINGLE_TOUCH_UP -2
83
84/* Touch surface information. Dimension is in hundredths of a mm, min and max 72/* Touch surface information. Dimension is in hundredths of a mm, min and max
85 * are in units. */ 73 * are in units. */
86#define MOUSE_DIMENSION_X (float)9056 74#define MOUSE_DIMENSION_X (float)9056
@@ -129,7 +117,6 @@ struct magicmouse_sc {
129 u8 size; 117 u8 size;
130 } touches[16]; 118 } touches[16];
131 int tracking_ids[16]; 119 int tracking_ids[16];
132 int single_touch_id;
133}; 120};
134 121
135static int magicmouse_firm_touch(struct magicmouse_sc *msc) 122static int magicmouse_firm_touch(struct magicmouse_sc *msc)
@@ -268,16 +255,14 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
268 } 255 }
269 } 256 }
270 257
271 if (down) { 258 if (down)
272 msc->ntouches++; 259 msc->ntouches++;
273 if (msc->single_touch_id == NO_TOUCHES) 260
274 msc->single_touch_id = id; 261 input_mt_slot(input, id);
275 } else if (msc->single_touch_id == id) 262 input_mt_report_slot_state(input, MT_TOOL_FINGER, down);
276 msc->single_touch_id = SINGLE_TOUCH_UP;
277 263
278 /* Generate the input events for this touch. */ 264 /* Generate the input events for this touch. */
279 if (report_touches && down) { 265 if (down) {
280 input_report_abs(input, ABS_MT_TRACKING_ID, id);
281 input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2); 266 input_report_abs(input, ABS_MT_TOUCH_MAJOR, touch_major << 2);
282 input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2); 267 input_report_abs(input, ABS_MT_TOUCH_MINOR, touch_minor << 2);
283 input_report_abs(input, ABS_MT_ORIENTATION, -orientation); 268 input_report_abs(input, ABS_MT_ORIENTATION, -orientation);
@@ -290,8 +275,6 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
290 else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ 275 else /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
291 input_event(input, EV_MSC, MSC_RAW, tdata[8]); 276 input_event(input, EV_MSC, MSC_RAW, tdata[8]);
292 } 277 }
293
294 input_mt_sync(input);
295 } 278 }
296} 279}
297 280
@@ -312,12 +295,6 @@ static int magicmouse_raw_event(struct hid_device *hdev,
312 for (ii = 0; ii < npoints; ii++) 295 for (ii = 0; ii < npoints; ii++)
313 magicmouse_emit_touch(msc, ii, data + ii * 9 + 4); 296 magicmouse_emit_touch(msc, ii, data + ii * 9 + 4);
314 297
315 /* We don't need an MT sync here because trackpad emits a
316 * BTN_TOUCH event in a new frame when all touches are released.
317 */
318 if (msc->ntouches == 0)
319 msc->single_touch_id = NO_TOUCHES;
320
321 clicks = data[1]; 298 clicks = data[1];
322 299
323 /* The following bits provide a device specific timestamp. They 300 /* The following bits provide a device specific timestamp. They
@@ -335,9 +312,6 @@ static int magicmouse_raw_event(struct hid_device *hdev,
335 for (ii = 0; ii < npoints; ii++) 312 for (ii = 0; ii < npoints; ii++)
336 magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); 313 magicmouse_emit_touch(msc, ii, data + ii * 8 + 6);
337 314
338 if (report_touches && msc->ntouches == 0)
339 input_mt_sync(input);
340
341 /* When emulating three-button mode, it is important 315 /* When emulating three-button mode, it is important
342 * to have the current touch information before 316 * to have the current touch information before
343 * generating a click event. 317 * generating a click event.
@@ -370,25 +344,17 @@ static int magicmouse_raw_event(struct hid_device *hdev,
370 input_report_rel(input, REL_Y, y); 344 input_report_rel(input, REL_Y, y);
371 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */ 345 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
372 input_report_key(input, BTN_MOUSE, clicks & 1); 346 input_report_key(input, BTN_MOUSE, clicks & 1);
373 input_report_key(input, BTN_TOUCH, msc->ntouches > 0); 347 input_mt_report_pointer_emulation(input, true);
374 input_report_key(input, BTN_TOOL_FINGER, msc->ntouches == 1);
375 input_report_key(input, BTN_TOOL_DOUBLETAP, msc->ntouches == 2);
376 input_report_key(input, BTN_TOOL_TRIPLETAP, msc->ntouches == 3);
377 input_report_key(input, BTN_TOOL_QUADTAP, msc->ntouches == 4);
378 if (msc->single_touch_id >= 0) {
379 input_report_abs(input, ABS_X,
380 msc->touches[msc->single_touch_id].x);
381 input_report_abs(input, ABS_Y,
382 msc->touches[msc->single_touch_id].y);
383 }
384 } 348 }
385 349
386 input_sync(input); 350 input_sync(input);
387 return 1; 351 return 1;
388} 352}
389 353
390static void magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev) 354static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hdev)
391{ 355{
356 int error;
357
392 __set_bit(EV_KEY, input->evbit); 358 __set_bit(EV_KEY, input->evbit);
393 359
394 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) { 360 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
@@ -417,62 +383,66 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
417 __set_bit(BTN_TOOL_DOUBLETAP, input->keybit); 383 __set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
418 __set_bit(BTN_TOOL_TRIPLETAP, input->keybit); 384 __set_bit(BTN_TOOL_TRIPLETAP, input->keybit);
419 __set_bit(BTN_TOOL_QUADTAP, input->keybit); 385 __set_bit(BTN_TOOL_QUADTAP, input->keybit);
386 __set_bit(BTN_TOOL_QUINTTAP, input->keybit);
420 __set_bit(BTN_TOUCH, input->keybit); 387 __set_bit(BTN_TOUCH, input->keybit);
421 __set_bit(INPUT_PROP_POINTER, input->propbit); 388 __set_bit(INPUT_PROP_POINTER, input->propbit);
422 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); 389 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
423 } 390 }
424 391
425 if (report_touches) {
426 __set_bit(EV_ABS, input->evbit);
427
428 input_set_abs_params(input, ABS_MT_TRACKING_ID, 0, 15, 0, 0);
429 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2,
430 4, 0);
431 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255 << 2,
432 4, 0);
433 input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0);
434
435 /* Note: Touch Y position from the device is inverted relative
436 * to how pointer motion is reported (and relative to how USB
437 * HID recommends the coordinates work). This driver keeps
438 * the origin at the same position, and just uses the additive
439 * inverse of the reported Y.
440 */
441 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
442 input_set_abs_params(input, ABS_MT_POSITION_X,
443 MOUSE_MIN_X, MOUSE_MAX_X, 4, 0);
444 input_set_abs_params(input, ABS_MT_POSITION_Y,
445 MOUSE_MIN_Y, MOUSE_MAX_Y, 4, 0);
446
447 input_abs_set_res(input, ABS_MT_POSITION_X,
448 MOUSE_RES_X);
449 input_abs_set_res(input, ABS_MT_POSITION_Y,
450 MOUSE_RES_Y);
451 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
452 input_set_abs_params(input, ABS_X, TRACKPAD_MIN_X,
453 TRACKPAD_MAX_X, 4, 0);
454 input_set_abs_params(input, ABS_Y, TRACKPAD_MIN_Y,
455 TRACKPAD_MAX_Y, 4, 0);
456 input_set_abs_params(input, ABS_MT_POSITION_X,
457 TRACKPAD_MIN_X, TRACKPAD_MAX_X, 4, 0);
458 input_set_abs_params(input, ABS_MT_POSITION_Y,
459 TRACKPAD_MIN_Y, TRACKPAD_MAX_Y, 4, 0);
460
461 input_abs_set_res(input, ABS_X, TRACKPAD_RES_X);
462 input_abs_set_res(input, ABS_Y, TRACKPAD_RES_Y);
463 input_abs_set_res(input, ABS_MT_POSITION_X,
464 TRACKPAD_RES_X);
465 input_abs_set_res(input, ABS_MT_POSITION_Y,
466 TRACKPAD_RES_Y);
467 }
468 392
469 input_set_events_per_packet(input, 60); 393 __set_bit(EV_ABS, input->evbit);
394
395 error = input_mt_init_slots(input, 16);
396 if (error)
397 return error;
398 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255 << 2,
399 4, 0);
400 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255 << 2,
401 4, 0);
402 input_set_abs_params(input, ABS_MT_ORIENTATION, -31, 32, 1, 0);
403
404 /* Note: Touch Y position from the device is inverted relative
405 * to how pointer motion is reported (and relative to how USB
406 * HID recommends the coordinates work). This driver keeps
407 * the origin at the same position, and just uses the additive
408 * inverse of the reported Y.
409 */
410 if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
411 input_set_abs_params(input, ABS_MT_POSITION_X,
412 MOUSE_MIN_X, MOUSE_MAX_X, 4, 0);
413 input_set_abs_params(input, ABS_MT_POSITION_Y,
414 MOUSE_MIN_Y, MOUSE_MAX_Y, 4, 0);
415
416 input_abs_set_res(input, ABS_MT_POSITION_X,
417 MOUSE_RES_X);
418 input_abs_set_res(input, ABS_MT_POSITION_Y,
419 MOUSE_RES_Y);
420 } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
421 input_set_abs_params(input, ABS_X, TRACKPAD_MIN_X,
422 TRACKPAD_MAX_X, 4, 0);
423 input_set_abs_params(input, ABS_Y, TRACKPAD_MIN_Y,
424 TRACKPAD_MAX_Y, 4, 0);
425 input_set_abs_params(input, ABS_MT_POSITION_X,
426 TRACKPAD_MIN_X, TRACKPAD_MAX_X, 4, 0);
427 input_set_abs_params(input, ABS_MT_POSITION_Y,
428 TRACKPAD_MIN_Y, TRACKPAD_MAX_Y, 4, 0);
429
430 input_abs_set_res(input, ABS_X, TRACKPAD_RES_X);
431 input_abs_set_res(input, ABS_Y, TRACKPAD_RES_Y);
432 input_abs_set_res(input, ABS_MT_POSITION_X,
433 TRACKPAD_RES_X);
434 input_abs_set_res(input, ABS_MT_POSITION_Y,
435 TRACKPAD_RES_Y);
470 } 436 }
471 437
438 input_set_events_per_packet(input, 60);
439
472 if (report_undeciphered) { 440 if (report_undeciphered) {
473 __set_bit(EV_MSC, input->evbit); 441 __set_bit(EV_MSC, input->evbit);
474 __set_bit(MSC_RAW, input->mscbit); 442 __set_bit(MSC_RAW, input->mscbit);
475 } 443 }
444
445 return 0;
476} 446}
477 447
478static int magicmouse_input_mapping(struct hid_device *hdev, 448static int magicmouse_input_mapping(struct hid_device *hdev,
@@ -511,8 +481,6 @@ static int magicmouse_probe(struct hid_device *hdev,
511 msc->quirks = id->driver_data; 481 msc->quirks = id->driver_data;
512 hid_set_drvdata(hdev, msc); 482 hid_set_drvdata(hdev, msc);
513 483
514 msc->single_touch_id = NO_TOUCHES;
515
516 ret = hid_parse(hdev); 484 ret = hid_parse(hdev);
517 if (ret) { 485 if (ret) {
518 hid_err(hdev, "magicmouse hid parse failed\n"); 486 hid_err(hdev, "magicmouse hid parse failed\n");
@@ -528,8 +496,13 @@ static int magicmouse_probe(struct hid_device *hdev,
528 /* We do this after hid-input is done parsing reports so that 496 /* We do this after hid-input is done parsing reports so that
529 * hid-input uses the most natural button and axis IDs. 497 * hid-input uses the most natural button and axis IDs.
530 */ 498 */
531 if (msc->input) 499 if (msc->input) {
532 magicmouse_setup_input(msc->input, hdev); 500 ret = magicmouse_setup_input(msc->input, hdev);
501 if (ret) {
502 hid_err(hdev, "magicmouse setup input failed (%d)\n", ret);
503 goto err_stop_hw;
504 }
505 }
533 506
534 if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE) 507 if (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE)
535 report = hid_register_report(hdev, HID_INPUT_REPORT, 508 report = hid_register_report(hdev, HID_INPUT_REPORT,
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 76479246d4ee..59c8b5c1d2de 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -83,6 +83,7 @@ struct mt_device {
83 unsigned last_field_index; /* last field index of the report */ 83 unsigned last_field_index; /* last field index of the report */
84 unsigned last_slot_field; /* the last field of a slot */ 84 unsigned last_slot_field; /* the last field of a slot */
85 __s8 inputmode; /* InputMode HID feature, -1 if non-existent */ 85 __s8 inputmode; /* InputMode HID feature, -1 if non-existent */
86 __s8 inputmode_index; /* InputMode HID feature index in the report */
86 __s8 maxcontact_report_id; /* Maximum Contact Number HID feature, 87 __s8 maxcontact_report_id; /* Maximum Contact Number HID feature,
87 -1 if non-existent */ 88 -1 if non-existent */
88 __u8 num_received; /* how many contacts we received */ 89 __u8 num_received; /* how many contacts we received */
@@ -260,10 +261,20 @@ static void mt_feature_mapping(struct hid_device *hdev,
260 struct hid_field *field, struct hid_usage *usage) 261 struct hid_field *field, struct hid_usage *usage)
261{ 262{
262 struct mt_device *td = hid_get_drvdata(hdev); 263 struct mt_device *td = hid_get_drvdata(hdev);
264 int i;
263 265
264 switch (usage->hid) { 266 switch (usage->hid) {
265 case HID_DG_INPUTMODE: 267 case HID_DG_INPUTMODE:
266 td->inputmode = field->report->id; 268 td->inputmode = field->report->id;
269 td->inputmode_index = 0; /* has to be updated below */
270
271 for (i=0; i < field->maxusage; i++) {
272 if (field->usage[i].hid == usage->hid) {
273 td->inputmode_index = i;
274 break;
275 }
276 }
277
267 break; 278 break;
268 case HID_DG_CONTACTMAX: 279 case HID_DG_CONTACTMAX:
269 td->maxcontact_report_id = field->report->id; 280 td->maxcontact_report_id = field->report->id;
@@ -618,7 +629,7 @@ static void mt_set_input_mode(struct hid_device *hdev)
618 re = &(hdev->report_enum[HID_FEATURE_REPORT]); 629 re = &(hdev->report_enum[HID_FEATURE_REPORT]);
619 r = re->report_id_hash[td->inputmode]; 630 r = re->report_id_hash[td->inputmode];
620 if (r) { 631 if (r) {
621 r->field[0]->value[0] = 0x02; 632 r->field[0]->value[td->inputmode_index] = 0x02;
622 usbhid_submit_report(hdev, r, USB_DIR_OUT); 633 usbhid_submit_report(hdev, r, USB_DIR_OUT);
623 } 634 }
624} 635}
@@ -951,6 +962,11 @@ static const struct hid_device_id mt_devices[] = {
951 MT_USB_DEVICE(USB_VENDOR_ID_PANASONIC, 962 MT_USB_DEVICE(USB_VENDOR_ID_PANASONIC,
952 USB_DEVICE_ID_PANABOARD_UBT880) }, 963 USB_DEVICE_ID_PANABOARD_UBT880) },
953 964
965 /* Novatek Panel */
966 { .driver_data = MT_CLS_DEFAULT,
967 MT_USB_DEVICE(USB_VENDOR_ID_NOVATEK,
968 USB_DEVICE_ID_NOVATEK_PCT) },
969
954 /* PenMount panels */ 970 /* PenMount panels */
955 { .driver_data = MT_CLS_CONFIDENCE, 971 { .driver_data = MT_CLS_CONFIDENCE,
956 MT_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, 972 MT_USB_DEVICE(USB_VENDOR_ID_PENMOUNT,
diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c
index 45c3433f7986..27c8ebdfad01 100644
--- a/drivers/hid/hid-picolcd.c
+++ b/drivers/hid/hid-picolcd.c
@@ -1846,7 +1846,7 @@ static void picolcd_debug_out_report(struct picolcd_data *data,
1846#define BUFF_SZ 256 1846#define BUFF_SZ 256
1847 1847
1848 /* Avoid unnecessary overhead if debugfs is disabled */ 1848 /* Avoid unnecessary overhead if debugfs is disabled */
1849 if (!hdev->debug_events) 1849 if (list_empty(&hdev->debug_list))
1850 return; 1850 return;
1851 1851
1852 buff = kmalloc(BUFF_SZ, GFP_ATOMIC); 1852 buff = kmalloc(BUFF_SZ, GFP_ATOMIC);
@@ -2613,11 +2613,7 @@ static int picolcd_probe(struct hid_device *hdev,
2613 goto err_cleanup_data; 2613 goto err_cleanup_data;
2614 } 2614 }
2615 2615
2616 /* We don't use hidinput but hid_hw_start() fails if nothing is
2617 * claimed. So spoof claimed input. */
2618 hdev->claimed = HID_CLAIMED_INPUT;
2619 error = hid_hw_start(hdev, 0); 2616 error = hid_hw_start(hdev, 0);
2620 hdev->claimed = 0;
2621 if (error) { 2617 if (error) {
2622 hid_err(hdev, "hardware start failed\n"); 2618 hid_err(hdev, "hardware start failed\n");
2623 goto err_cleanup_data; 2619 goto err_cleanup_data;
diff --git a/drivers/hid/hid-roccat-arvo.c b/drivers/hid/hid-roccat-arvo.c
index 093bfad00b02..327f9b8ed1f4 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_COMMAND_MODE_KEY, 42 retval = roccat_common2_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_COMMAND_MODE_KEY, 70 retval = roccat_common2_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_COMMAND_KEY_MASK, 90 retval = roccat_common2_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_COMMAND_KEY_MASK, 118 retval = roccat_common2_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_COMMAND_ACTUAL_PROFILE, 133 retval = roccat_common2_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)
@@ -170,7 +170,7 @@ static ssize_t arvo_sysfs_set_actual_profile(struct device *dev,
170 temp_buf.actual_profile = profile; 170 temp_buf.actual_profile = profile;
171 171
172 mutex_lock(&arvo->arvo_lock); 172 mutex_lock(&arvo->arvo_lock);
173 retval = roccat_common_send(usb_dev, ARVO_COMMAND_ACTUAL_PROFILE, 173 retval = roccat_common2_send(usb_dev, ARVO_COMMAND_ACTUAL_PROFILE,
174 &temp_buf, sizeof(struct arvo_actual_profile)); 174 &temp_buf, sizeof(struct arvo_actual_profile));
175 if (!retval) { 175 if (!retval) {
176 arvo->actual_profile = profile; 176 arvo->actual_profile = profile;
@@ -194,7 +194,7 @@ static ssize_t arvo_sysfs_write(struct file *fp,
194 return -EINVAL; 194 return -EINVAL;
195 195
196 mutex_lock(&arvo->arvo_lock); 196 mutex_lock(&arvo->arvo_lock);
197 retval = roccat_common_send(usb_dev, command, buf, real_size); 197 retval = roccat_common2_send(usb_dev, command, buf, real_size);
198 mutex_unlock(&arvo->arvo_lock); 198 mutex_unlock(&arvo->arvo_lock);
199 199
200 return (retval ? retval : real_size); 200 return (retval ? retval : real_size);
@@ -217,7 +217,7 @@ static ssize_t arvo_sysfs_read(struct file *fp,
217 return -EINVAL; 217 return -EINVAL;
218 218
219 mutex_lock(&arvo->arvo_lock); 219 mutex_lock(&arvo->arvo_lock);
220 retval = roccat_common_receive(usb_dev, command, buf, real_size); 220 retval = roccat_common2_receive(usb_dev, command, buf, real_size);
221 mutex_unlock(&arvo->arvo_lock); 221 mutex_unlock(&arvo->arvo_lock);
222 222
223 return (retval ? retval : real_size); 223 return (retval ? retval : real_size);
diff --git a/drivers/hid/hid-roccat-common.c b/drivers/hid/hid-roccat-common.c
index a6d93992c75a..74f704032627 100644
--- a/drivers/hid/hid-roccat-common.c
+++ b/drivers/hid/hid-roccat-common.c
@@ -16,12 +16,12 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include "hid-roccat-common.h" 17#include "hid-roccat-common.h"
18 18
19static inline uint16_t roccat_common_feature_report(uint8_t report_id) 19static inline uint16_t roccat_common2_feature_report(uint8_t report_id)
20{ 20{
21 return 0x300 | report_id; 21 return 0x300 | report_id;
22} 22}
23 23
24int roccat_common_receive(struct usb_device *usb_dev, uint report_id, 24int roccat_common2_receive(struct usb_device *usb_dev, uint report_id,
25 void *data, uint size) 25 void *data, uint size)
26{ 26{
27 char *buf; 27 char *buf;
@@ -34,16 +34,16 @@ int roccat_common_receive(struct usb_device *usb_dev, uint report_id,
34 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), 34 len = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0),
35 HID_REQ_GET_REPORT, 35 HID_REQ_GET_REPORT,
36 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 36 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN,
37 roccat_common_feature_report(report_id), 37 roccat_common2_feature_report(report_id),
38 0, buf, size, USB_CTRL_SET_TIMEOUT); 38 0, buf, size, USB_CTRL_SET_TIMEOUT);
39 39
40 memcpy(data, buf, size); 40 memcpy(data, buf, size);
41 kfree(buf); 41 kfree(buf);
42 return ((len < 0) ? len : ((len != size) ? -EIO : 0)); 42 return ((len < 0) ? len : ((len != size) ? -EIO : 0));
43} 43}
44EXPORT_SYMBOL_GPL(roccat_common_receive); 44EXPORT_SYMBOL_GPL(roccat_common2_receive);
45 45
46int roccat_common_send(struct usb_device *usb_dev, uint report_id, 46int roccat_common2_send(struct usb_device *usb_dev, uint report_id,
47 void const *data, uint size) 47 void const *data, uint size)
48{ 48{
49 char *buf; 49 char *buf;
@@ -56,13 +56,71 @@ int roccat_common_send(struct usb_device *usb_dev, uint report_id,
56 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0), 56 len = usb_control_msg(usb_dev, usb_sndctrlpipe(usb_dev, 0),
57 HID_REQ_SET_REPORT, 57 HID_REQ_SET_REPORT,
58 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, 58 USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT,
59 roccat_common_feature_report(report_id), 59 roccat_common2_feature_report(report_id),
60 0, buf, size, USB_CTRL_SET_TIMEOUT); 60 0, buf, size, USB_CTRL_SET_TIMEOUT);
61 61
62 kfree(buf); 62 kfree(buf);
63 return ((len < 0) ? len : ((len != size) ? -EIO : 0)); 63 return ((len < 0) ? len : ((len != size) ? -EIO : 0));
64} 64}
65EXPORT_SYMBOL_GPL(roccat_common_send); 65EXPORT_SYMBOL_GPL(roccat_common2_send);
66
67enum roccat_common2_control_states {
68 ROCCAT_COMMON_CONTROL_STATUS_OVERLOAD = 0,
69 ROCCAT_COMMON_CONTROL_STATUS_OK = 1,
70 ROCCAT_COMMON_CONTROL_STATUS_INVALID = 2,
71 ROCCAT_COMMON_CONTROL_STATUS_WAIT = 3,
72};
73
74static int roccat_common2_receive_control_status(struct usb_device *usb_dev)
75{
76 int retval;
77 struct roccat_common2_control control;
78
79 do {
80 msleep(50);
81 retval = roccat_common2_receive(usb_dev,
82 ROCCAT_COMMON_COMMAND_CONTROL,
83 &control, sizeof(struct roccat_common2_control));
84
85 if (retval)
86 return retval;
87
88 switch (control.value) {
89 case ROCCAT_COMMON_CONTROL_STATUS_OK:
90 return 0;
91 case ROCCAT_COMMON_CONTROL_STATUS_WAIT:
92 msleep(500);
93 continue;
94 case ROCCAT_COMMON_CONTROL_STATUS_INVALID:
95
96 case ROCCAT_COMMON_CONTROL_STATUS_OVERLOAD:
97 /* seems to be critical - replug necessary */
98 return -EINVAL;
99 default:
100 dev_err(&usb_dev->dev,
101 "roccat_common2_receive_control_status: "
102 "unknown response value 0x%x\n",
103 control.value);
104 return -EINVAL;
105 }
106
107 } while (1);
108}
109
110int roccat_common2_send_with_status(struct usb_device *usb_dev,
111 uint command, void const *buf, uint size)
112{
113 int retval;
114
115 retval = roccat_common2_send(usb_dev, command, buf, size);
116 if (retval)
117 return retval;
118
119 msleep(100);
120
121 return roccat_common2_receive_control_status(usb_dev);
122}
123EXPORT_SYMBOL_GPL(roccat_common2_send_with_status);
66 124
67MODULE_AUTHOR("Stefan Achatz"); 125MODULE_AUTHOR("Stefan Achatz");
68MODULE_DESCRIPTION("USB Roccat common driver"); 126MODULE_DESCRIPTION("USB Roccat common driver");
diff --git a/drivers/hid/hid-roccat-common.h b/drivers/hid/hid-roccat-common.h
index 9a5bc61f9699..a97746a63b70 100644
--- a/drivers/hid/hid-roccat-common.h
+++ b/drivers/hid/hid-roccat-common.h
@@ -15,9 +15,21 @@
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 report_id, 18enum roccat_common2_commands {
19 ROCCAT_COMMON_COMMAND_CONTROL = 0x4,
20};
21
22struct roccat_common2_control {
23 uint8_t command;
24 uint8_t value;
25 uint8_t request; /* always 0 on requesting write check */
26} __packed;
27
28int roccat_common2_receive(struct usb_device *usb_dev, uint report_id,
19 void *data, uint size); 29 void *data, uint size);
20int roccat_common_send(struct usb_device *usb_dev, uint report_id, 30int roccat_common2_send(struct usb_device *usb_dev, uint report_id,
21 void const *data, uint size); 31 void const *data, uint size);
32int roccat_common2_send_with_status(struct usb_device *usb_dev,
33 uint command, void const *buf, uint size);
22 34
23#endif 35#endif
diff --git a/drivers/hid/hid-roccat-isku.c b/drivers/hid/hid-roccat-isku.c
index 0e4a0ab47142..5669916c2943 100644
--- a/drivers/hid/hid-roccat-isku.c
+++ b/drivers/hid/hid-roccat-isku.c
@@ -36,51 +36,7 @@ static void isku_profile_activated(struct isku_device *isku, uint new_profile)
36static int isku_receive(struct usb_device *usb_dev, uint command, 36static int isku_receive(struct usb_device *usb_dev, uint command,
37 void *buf, uint size) 37 void *buf, uint size)
38{ 38{
39 return roccat_common_receive(usb_dev, command, buf, size); 39 return roccat_common2_receive(usb_dev, command, buf, size);
40}
41
42static int isku_receive_control_status(struct usb_device *usb_dev)
43{
44 int retval;
45 struct isku_control control;
46
47 do {
48 msleep(50);
49 retval = isku_receive(usb_dev, ISKU_COMMAND_CONTROL,
50 &control, sizeof(struct isku_control));
51
52 if (retval)
53 return retval;
54
55 switch (control.value) {
56 case ISKU_CONTROL_VALUE_STATUS_OK:
57 return 0;
58 case ISKU_CONTROL_VALUE_STATUS_WAIT:
59 continue;
60 case ISKU_CONTROL_VALUE_STATUS_INVALID:
61 /* seems to be critical - replug necessary */
62 case ISKU_CONTROL_VALUE_STATUS_OVERLOAD:
63 return -EINVAL;
64 default:
65 hid_err(usb_dev, "isku_receive_control_status: "
66 "unknown response value 0x%x\n",
67 control.value);
68 return -EINVAL;
69 }
70
71 } while (1);
72}
73
74static int isku_send(struct usb_device *usb_dev, uint command,
75 void const *buf, uint size)
76{
77 int retval;
78
79 retval = roccat_common_send(usb_dev, command, buf, size);
80 if (retval)
81 return retval;
82
83 return isku_receive_control_status(usb_dev);
84} 40}
85 41
86static int isku_get_actual_profile(struct usb_device *usb_dev) 42static int isku_get_actual_profile(struct usb_device *usb_dev)
@@ -100,7 +56,8 @@ static int isku_set_actual_profile(struct usb_device *usb_dev, int new_profile)
100 buf.command = ISKU_COMMAND_ACTUAL_PROFILE; 56 buf.command = ISKU_COMMAND_ACTUAL_PROFILE;
101 buf.size = sizeof(struct isku_actual_profile); 57 buf.size = sizeof(struct isku_actual_profile);
102 buf.actual_profile = new_profile; 58 buf.actual_profile = new_profile;
103 return isku_send(usb_dev, ISKU_COMMAND_ACTUAL_PROFILE, &buf, 59 return roccat_common2_send_with_status(usb_dev,
60 ISKU_COMMAND_ACTUAL_PROFILE, &buf,
104 sizeof(struct isku_actual_profile)); 61 sizeof(struct isku_actual_profile));
105} 62}
106 63
@@ -197,7 +154,8 @@ static ssize_t isku_sysfs_write(struct file *fp, struct kobject *kobj,
197 return -EINVAL; 154 return -EINVAL;
198 155
199 mutex_lock(&isku->isku_lock); 156 mutex_lock(&isku->isku_lock);
200 retval = isku_send(usb_dev, command, (void *)buf, real_size); 157 retval = roccat_common2_send_with_status(usb_dev, command,
158 (void *)buf, real_size);
201 mutex_unlock(&isku->isku_lock); 159 mutex_unlock(&isku->isku_lock);
202 160
203 return retval ? retval : real_size; 161 return retval ? retval : real_size;
diff --git a/drivers/hid/hid-roccat-isku.h b/drivers/hid/hid-roccat-isku.h
index 075f6efaec58..605b3ce21638 100644
--- a/drivers/hid/hid-roccat-isku.h
+++ b/drivers/hid/hid-roccat-isku.h
@@ -25,13 +25,6 @@ struct isku_control {
25 uint8_t request; 25 uint8_t request;
26} __packed; 26} __packed;
27 27
28enum isku_control_values {
29 ISKU_CONTROL_VALUE_STATUS_OVERLOAD = 0,
30 ISKU_CONTROL_VALUE_STATUS_OK = 1,
31 ISKU_CONTROL_VALUE_STATUS_INVALID = 2,
32 ISKU_CONTROL_VALUE_STATUS_WAIT = 3,
33};
34
35struct isku_actual_profile { 28struct isku_actual_profile {
36 uint8_t command; /* ISKU_COMMAND_ACTUAL_PROFILE */ 29 uint8_t command; /* ISKU_COMMAND_ACTUAL_PROFILE */
37 uint8_t size; /* always 3 */ 30 uint8_t size; /* always 3 */
diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c
index 40090d602158..9ce2d0b615a4 100644
--- a/drivers/hid/hid-roccat-kone.c
+++ b/drivers/hid/hid-roccat-kone.c
@@ -138,7 +138,7 @@ static int kone_check_write(struct usb_device *usb_dev)
138 return 0; 138 return 0;
139 139
140 /* unknown answer */ 140 /* unknown answer */
141 hid_err(usb_dev, "got retval %d when checking write\n", data); 141 dev_err(&usb_dev->dev, "got retval %d when checking write\n", data);
142 return -EIO; 142 return -EIO;
143} 143}
144 144
@@ -503,7 +503,7 @@ static ssize_t kone_sysfs_set_tcu(struct device *dev,
503 503
504 retval = kone_set_settings(usb_dev, &kone->settings); 504 retval = kone_set_settings(usb_dev, &kone->settings);
505 if (retval) { 505 if (retval) {
506 hid_err(usb_dev, "couldn't set tcu state\n"); 506 dev_err(&usb_dev->dev, "couldn't set tcu state\n");
507 /* 507 /*
508 * try to reread valid settings into buffer overwriting 508 * try to reread valid settings into buffer overwriting
509 * first error code 509 * first error code
@@ -519,7 +519,7 @@ static ssize_t kone_sysfs_set_tcu(struct device *dev,
519 519
520 retval = size; 520 retval = size;
521exit_no_settings: 521exit_no_settings:
522 hid_err(usb_dev, "couldn't read settings\n"); 522 dev_err(&usb_dev->dev, "couldn't read settings\n");
523exit_unlock: 523exit_unlock:
524 mutex_unlock(&kone->kone_lock); 524 mutex_unlock(&kone->kone_lock);
525 return retval; 525 return retval;
diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c
index 59e47770fa10..f5602fec4865 100644
--- a/drivers/hid/hid-roccat-koneplus.c
+++ b/drivers/hid/hid-roccat-koneplus.c
@@ -39,88 +39,26 @@ static void koneplus_profile_activated(struct koneplus_device *koneplus,
39static int koneplus_send_control(struct usb_device *usb_dev, uint value, 39static int koneplus_send_control(struct usb_device *usb_dev, uint value,
40 enum koneplus_control_requests request) 40 enum koneplus_control_requests request)
41{ 41{
42 struct koneplus_control control; 42 struct roccat_common2_control control;
43 43
44 if ((request == KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS || 44 if ((request == KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS ||
45 request == KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) && 45 request == KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) &&
46 value > 4) 46 value > 4)
47 return -EINVAL; 47 return -EINVAL;
48 48
49 control.command = KONEPLUS_COMMAND_CONTROL; 49 control.command = ROCCAT_COMMON_COMMAND_CONTROL;
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_COMMAND_CONTROL, 53 return roccat_common2_send_with_status(usb_dev,
54 &control, sizeof(struct koneplus_control)); 54 ROCCAT_COMMON_COMMAND_CONTROL,
55} 55 &control, sizeof(struct roccat_common2_control));
56
57static int koneplus_receive_control_status(struct usb_device *usb_dev)
58{
59 int retval;
60 struct koneplus_control control;
61
62 do {
63 retval = roccat_common_receive(usb_dev, KONEPLUS_COMMAND_CONTROL,
64 &control, sizeof(struct koneplus_control));
65
66 /* check if we get a completely wrong answer */
67 if (retval)
68 return retval;
69
70 if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_OK)
71 return 0;
72
73 /* indicates that hardware needs some more time to complete action */
74 if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_WAIT) {
75 msleep(500); /* windows driver uses 1000 */
76 continue;
77 }
78
79 /* seems to be critical - replug necessary */
80 if (control.value == KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD)
81 return -EINVAL;
82
83 hid_err(usb_dev, "koneplus_receive_control_status: "
84 "unknown response value 0x%x\n", control.value);
85 return -EINVAL;
86 } while (1);
87}
88
89static int koneplus_send(struct usb_device *usb_dev, uint command,
90 void const *buf, uint size)
91{
92 int retval;
93
94 retval = roccat_common_send(usb_dev, command, buf, size);
95 if (retval)
96 return retval;
97
98 return koneplus_receive_control_status(usb_dev);
99}
100
101static int koneplus_select_profile(struct usb_device *usb_dev, uint number,
102 enum koneplus_control_requests request)
103{
104 int retval;
105
106 retval = koneplus_send_control(usb_dev, number, request);
107 if (retval)
108 return retval;
109
110 /* allow time to settle things - windows driver uses 500 */
111 msleep(100);
112
113 retval = koneplus_receive_control_status(usb_dev);
114 if (retval)
115 return retval;
116
117 return 0;
118} 56}
119 57
120static int koneplus_get_info(struct usb_device *usb_dev, 58static int koneplus_get_info(struct usb_device *usb_dev,
121 struct koneplus_info *buf) 59 struct koneplus_info *buf)
122{ 60{
123 return roccat_common_receive(usb_dev, KONEPLUS_COMMAND_INFO, 61 return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_INFO,
124 buf, sizeof(struct koneplus_info)); 62 buf, sizeof(struct koneplus_info));
125} 63}
126 64
@@ -129,19 +67,20 @@ static int koneplus_get_profile_settings(struct usb_device *usb_dev,
129{ 67{
130 int retval; 68 int retval;
131 69
132 retval = koneplus_select_profile(usb_dev, number, 70 retval = koneplus_send_control(usb_dev, number,
133 KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS); 71 KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS);
134 if (retval) 72 if (retval)
135 return retval; 73 return retval;
136 74
137 return roccat_common_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_SETTINGS, 75 return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_SETTINGS,
138 buf, sizeof(struct koneplus_profile_settings)); 76 buf, sizeof(struct koneplus_profile_settings));
139} 77}
140 78
141static int koneplus_set_profile_settings(struct usb_device *usb_dev, 79static int koneplus_set_profile_settings(struct usb_device *usb_dev,
142 struct koneplus_profile_settings const *settings) 80 struct koneplus_profile_settings const *settings)
143{ 81{
144 return koneplus_send(usb_dev, KONEPLUS_COMMAND_PROFILE_SETTINGS, 82 return roccat_common2_send_with_status(usb_dev,
83 KONEPLUS_COMMAND_PROFILE_SETTINGS,
145 settings, sizeof(struct koneplus_profile_settings)); 84 settings, sizeof(struct koneplus_profile_settings));
146} 85}
147 86
@@ -150,19 +89,20 @@ static int koneplus_get_profile_buttons(struct usb_device *usb_dev,
150{ 89{
151 int retval; 90 int retval;
152 91
153 retval = koneplus_select_profile(usb_dev, number, 92 retval = koneplus_send_control(usb_dev, number,
154 KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS); 93 KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS);
155 if (retval) 94 if (retval)
156 return retval; 95 return retval;
157 96
158 return roccat_common_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_BUTTONS, 97 return roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_PROFILE_BUTTONS,
159 buf, sizeof(struct koneplus_profile_buttons)); 98 buf, sizeof(struct koneplus_profile_buttons));
160} 99}
161 100
162static int koneplus_set_profile_buttons(struct usb_device *usb_dev, 101static int koneplus_set_profile_buttons(struct usb_device *usb_dev,
163 struct koneplus_profile_buttons const *buttons) 102 struct koneplus_profile_buttons const *buttons)
164{ 103{
165 return koneplus_send(usb_dev, KONEPLUS_COMMAND_PROFILE_BUTTONS, 104 return roccat_common2_send_with_status(usb_dev,
105 KONEPLUS_COMMAND_PROFILE_BUTTONS,
166 buttons, sizeof(struct koneplus_profile_buttons)); 106 buttons, sizeof(struct koneplus_profile_buttons));
167} 107}
168 108
@@ -172,7 +112,7 @@ static int koneplus_get_actual_profile(struct usb_device *usb_dev)
172 struct koneplus_actual_profile buf; 112 struct koneplus_actual_profile buf;
173 int retval; 113 int retval;
174 114
175 retval = roccat_common_receive(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE, 115 retval = roccat_common2_receive(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE,
176 &buf, sizeof(struct koneplus_actual_profile)); 116 &buf, sizeof(struct koneplus_actual_profile));
177 117
178 return retval ? retval : buf.actual_profile; 118 return retval ? retval : buf.actual_profile;
@@ -187,7 +127,8 @@ static int koneplus_set_actual_profile(struct usb_device *usb_dev,
187 buf.size = sizeof(struct koneplus_actual_profile); 127 buf.size = sizeof(struct koneplus_actual_profile);
188 buf.actual_profile = new_profile; 128 buf.actual_profile = new_profile;
189 129
190 return koneplus_send(usb_dev, KONEPLUS_COMMAND_ACTUAL_PROFILE, 130 return roccat_common2_send_with_status(usb_dev,
131 KONEPLUS_COMMAND_ACTUAL_PROFILE,
191 &buf, sizeof(struct koneplus_actual_profile)); 132 &buf, sizeof(struct koneplus_actual_profile));
192} 133}
193 134
@@ -208,7 +149,7 @@ static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj,
208 return -EINVAL; 149 return -EINVAL;
209 150
210 mutex_lock(&koneplus->koneplus_lock); 151 mutex_lock(&koneplus->koneplus_lock);
211 retval = roccat_common_receive(usb_dev, command, buf, real_size); 152 retval = roccat_common2_receive(usb_dev, command, buf, real_size);
212 mutex_unlock(&koneplus->koneplus_lock); 153 mutex_unlock(&koneplus->koneplus_lock);
213 154
214 if (retval) 155 if (retval)
@@ -231,7 +172,8 @@ static ssize_t koneplus_sysfs_write(struct file *fp, struct kobject *kobj,
231 return -EINVAL; 172 return -EINVAL;
232 173
233 mutex_lock(&koneplus->koneplus_lock); 174 mutex_lock(&koneplus->koneplus_lock);
234 retval = koneplus_send(usb_dev, command, buf, real_size); 175 retval = roccat_common2_send_with_status(usb_dev, command,
176 buf, real_size);
235 mutex_unlock(&koneplus->koneplus_lock); 177 mutex_unlock(&koneplus->koneplus_lock);
236 178
237 if (retval) 179 if (retval)
diff --git a/drivers/hid/hid-roccat-koneplus.h b/drivers/hid/hid-roccat-koneplus.h
index c03332a4fa9a..7074b2a4b94b 100644
--- a/drivers/hid/hid-roccat-koneplus.h
+++ b/drivers/hid/hid-roccat-koneplus.h
@@ -20,32 +20,11 @@ struct koneplus_talk {
20 uint8_t data[14]; 20 uint8_t data[14];
21} __packed; 21} __packed;
22 22
23/*
24 * case 1: writes request 80 and reads value 1
25 *
26 */
27struct koneplus_control {
28 uint8_t command; /* KONEPLUS_COMMAND_CONTROL */
29 /*
30 * value is profile number in range 0-4 for requesting settings and buttons
31 * 1 if status ok for requesting status
32 */
33 uint8_t value;
34 uint8_t request;
35} __attribute__ ((__packed__));
36
37enum koneplus_control_requests { 23enum koneplus_control_requests {
38 KONEPLUS_CONTROL_REQUEST_STATUS = 0x00,
39 KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x80, 24 KONEPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x80,
40 KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x90, 25 KONEPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x90,
41}; 26};
42 27
43enum koneplus_control_values {
44 KONEPLUS_CONTROL_REQUEST_STATUS_OVERLOAD = 0,
45 KONEPLUS_CONTROL_REQUEST_STATUS_OK = 1,
46 KONEPLUS_CONTROL_REQUEST_STATUS_WAIT = 3,
47};
48
49struct koneplus_actual_profile { 28struct koneplus_actual_profile {
50 uint8_t command; /* KONEPLUS_COMMAND_ACTUAL_PROFILE */ 29 uint8_t command; /* KONEPLUS_COMMAND_ACTUAL_PROFILE */
51 uint8_t size; /* always 3 */ 30 uint8_t size; /* always 3 */
@@ -137,7 +116,6 @@ struct koneplus_tcu_image {
137} __attribute__ ((__packed__)); 116} __attribute__ ((__packed__));
138 117
139enum koneplus_commands { 118enum koneplus_commands {
140 KONEPLUS_COMMAND_CONTROL = 0x4,
141 KONEPLUS_COMMAND_ACTUAL_PROFILE = 0x5, 119 KONEPLUS_COMMAND_ACTUAL_PROFILE = 0x5,
142 KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6, 120 KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6,
143 KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7, 121 KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7,
diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c
index 112d934132c8..ca6527ac655d 100644
--- a/drivers/hid/hid-roccat-kovaplus.c
+++ b/drivers/hid/hid-roccat-kovaplus.c
@@ -47,69 +47,23 @@ static int kovaplus_send_control(struct usb_device *usb_dev, uint value,
47 enum kovaplus_control_requests request) 47 enum kovaplus_control_requests request)
48{ 48{
49 int retval; 49 int retval;
50 struct kovaplus_control control; 50 struct roccat_common2_control control;
51 51
52 if ((request == KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS || 52 if ((request == KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS ||
53 request == KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) && 53 request == KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS) &&
54 value > 4) 54 value > 4)
55 return -EINVAL; 55 return -EINVAL;
56 56
57 control.command = KOVAPLUS_COMMAND_CONTROL; 57 control.command = ROCCAT_COMMON_COMMAND_CONTROL;
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_COMMAND_CONTROL, 61 retval = roccat_common2_send(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL,
62 &control, sizeof(struct kovaplus_control)); 62 &control, sizeof(struct roccat_common2_control));
63 63
64 return retval; 64 return retval;
65} 65}
66 66
67static int kovaplus_receive_control_status(struct usb_device *usb_dev)
68{
69 int retval;
70 struct kovaplus_control control;
71
72 do {
73 retval = roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_CONTROL,
74 &control, sizeof(struct kovaplus_control));
75
76 /* check if we get a completely wrong answer */
77 if (retval)
78 return retval;
79
80 if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_OK)
81 return 0;
82
83 /* indicates that hardware needs some more time to complete action */
84 if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_WAIT) {
85 msleep(500); /* windows driver uses 1000 */
86 continue;
87 }
88
89 /* seems to be critical - replug necessary */
90 if (control.value == KOVAPLUS_CONTROL_REQUEST_STATUS_OVERLOAD)
91 return -EINVAL;
92
93 hid_err(usb_dev, "roccat_common_receive_control_status: "
94 "unknown response value 0x%x\n", control.value);
95 return -EINVAL;
96 } while (1);
97}
98
99static int kovaplus_send(struct usb_device *usb_dev, uint command,
100 void const *buf, uint size)
101{
102 int retval;
103
104 retval = roccat_common_send(usb_dev, command, buf, size);
105 if (retval)
106 return retval;
107
108 msleep(100);
109
110 return kovaplus_receive_control_status(usb_dev);
111}
112
113static int kovaplus_select_profile(struct usb_device *usb_dev, uint number, 67static int kovaplus_select_profile(struct usb_device *usb_dev, uint number,
114 enum kovaplus_control_requests request) 68 enum kovaplus_control_requests request)
115{ 69{
@@ -119,7 +73,7 @@ static int kovaplus_select_profile(struct usb_device *usb_dev, uint number,
119static int kovaplus_get_info(struct usb_device *usb_dev, 73static int kovaplus_get_info(struct usb_device *usb_dev,
120 struct kovaplus_info *buf) 74 struct kovaplus_info *buf)
121{ 75{
122 return roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_INFO, 76 return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_INFO,
123 buf, sizeof(struct kovaplus_info)); 77 buf, sizeof(struct kovaplus_info));
124} 78}
125 79
@@ -133,14 +87,15 @@ static int kovaplus_get_profile_settings(struct usb_device *usb_dev,
133 if (retval) 87 if (retval)
134 return retval; 88 return retval;
135 89
136 return roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS, 90 return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS,
137 buf, sizeof(struct kovaplus_profile_settings)); 91 buf, sizeof(struct kovaplus_profile_settings));
138} 92}
139 93
140static int kovaplus_set_profile_settings(struct usb_device *usb_dev, 94static int kovaplus_set_profile_settings(struct usb_device *usb_dev,
141 struct kovaplus_profile_settings const *settings) 95 struct kovaplus_profile_settings const *settings)
142{ 96{
143 return kovaplus_send(usb_dev, KOVAPLUS_COMMAND_PROFILE_SETTINGS, 97 return roccat_common2_send_with_status(usb_dev,
98 KOVAPLUS_COMMAND_PROFILE_SETTINGS,
144 settings, sizeof(struct kovaplus_profile_settings)); 99 settings, sizeof(struct kovaplus_profile_settings));
145} 100}
146 101
@@ -154,14 +109,15 @@ static int kovaplus_get_profile_buttons(struct usb_device *usb_dev,
154 if (retval) 109 if (retval)
155 return retval; 110 return retval;
156 111
157 return roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS, 112 return roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS,
158 buf, sizeof(struct kovaplus_profile_buttons)); 113 buf, sizeof(struct kovaplus_profile_buttons));
159} 114}
160 115
161static int kovaplus_set_profile_buttons(struct usb_device *usb_dev, 116static int kovaplus_set_profile_buttons(struct usb_device *usb_dev,
162 struct kovaplus_profile_buttons const *buttons) 117 struct kovaplus_profile_buttons const *buttons)
163{ 118{
164 return kovaplus_send(usb_dev, KOVAPLUS_COMMAND_PROFILE_BUTTONS, 119 return roccat_common2_send_with_status(usb_dev,
120 KOVAPLUS_COMMAND_PROFILE_BUTTONS,
165 buttons, sizeof(struct kovaplus_profile_buttons)); 121 buttons, sizeof(struct kovaplus_profile_buttons));
166} 122}
167 123
@@ -171,7 +127,7 @@ static int kovaplus_get_actual_profile(struct usb_device *usb_dev)
171 struct kovaplus_actual_profile buf; 127 struct kovaplus_actual_profile buf;
172 int retval; 128 int retval;
173 129
174 retval = roccat_common_receive(usb_dev, KOVAPLUS_COMMAND_ACTUAL_PROFILE, 130 retval = roccat_common2_receive(usb_dev, KOVAPLUS_COMMAND_ACTUAL_PROFILE,
175 &buf, sizeof(struct kovaplus_actual_profile)); 131 &buf, sizeof(struct kovaplus_actual_profile));
176 132
177 return retval ? retval : buf.actual_profile; 133 return retval ? retval : buf.actual_profile;
@@ -186,7 +142,8 @@ static int kovaplus_set_actual_profile(struct usb_device *usb_dev,
186 buf.size = sizeof(struct kovaplus_actual_profile); 142 buf.size = sizeof(struct kovaplus_actual_profile);
187 buf.actual_profile = new_profile; 143 buf.actual_profile = new_profile;
188 144
189 return kovaplus_send(usb_dev, KOVAPLUS_COMMAND_ACTUAL_PROFILE, 145 return roccat_common2_send_with_status(usb_dev,
146 KOVAPLUS_COMMAND_ACTUAL_PROFILE,
190 &buf, sizeof(struct kovaplus_actual_profile)); 147 &buf, sizeof(struct kovaplus_actual_profile));
191} 148}
192 149
diff --git a/drivers/hid/hid-roccat-kovaplus.h b/drivers/hid/hid-roccat-kovaplus.h
index fb2aed44a8e0..f82daa1cdcb9 100644
--- a/drivers/hid/hid-roccat-kovaplus.h
+++ b/drivers/hid/hid-roccat-kovaplus.h
@@ -14,27 +14,13 @@
14 14
15#include <linux/types.h> 15#include <linux/types.h>
16 16
17struct kovaplus_control {
18 uint8_t command; /* KOVAPLUS_COMMAND_CONTROL */
19 uint8_t value;
20 uint8_t request;
21} __packed;
22
23enum kovaplus_control_requests { 17enum kovaplus_control_requests {
24 /* read after write; value = 1 */
25 KOVAPLUS_CONTROL_REQUEST_STATUS = 0x0,
26 /* write; value = profile number range 0-4 */ 18 /* write; value = profile number range 0-4 */
27 KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10, 19 KOVAPLUS_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10,
28 /* write; value = profile number range 0-4 */ 20 /* write; value = profile number range 0-4 */
29 KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20, 21 KOVAPLUS_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20,
30}; 22};
31 23
32enum kovaplus_control_values {
33 KOVAPLUS_CONTROL_REQUEST_STATUS_OVERLOAD = 0, /* supposed */
34 KOVAPLUS_CONTROL_REQUEST_STATUS_OK = 1,
35 KOVAPLUS_CONTROL_REQUEST_STATUS_WAIT = 3, /* supposed */
36};
37
38struct kovaplus_actual_profile { 24struct kovaplus_actual_profile {
39 uint8_t command; /* KOVAPLUS_COMMAND_ACTUAL_PROFILE */ 25 uint8_t command; /* KOVAPLUS_COMMAND_ACTUAL_PROFILE */
40 uint8_t size; /* always 3 */ 26 uint8_t size; /* always 3 */
@@ -75,7 +61,6 @@ struct kovaplus_a {
75} __packed; 61} __packed;
76 62
77enum kovaplus_commands { 63enum kovaplus_commands {
78 KOVAPLUS_COMMAND_CONTROL = 0x4,
79 KOVAPLUS_COMMAND_ACTUAL_PROFILE = 0x5, 64 KOVAPLUS_COMMAND_ACTUAL_PROFILE = 0x5,
80 KOVAPLUS_COMMAND_PROFILE_SETTINGS = 0x6, 65 KOVAPLUS_COMMAND_PROFILE_SETTINGS = 0x6,
81 KOVAPLUS_COMMAND_PROFILE_BUTTONS = 0x7, 66 KOVAPLUS_COMMAND_PROFILE_BUTTONS = 0x7,
diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c
index df05c1b1064f..1317c177a3e2 100644
--- a/drivers/hid/hid-roccat-pyra.c
+++ b/drivers/hid/hid-roccat-pyra.c
@@ -42,43 +42,19 @@ static void profile_activated(struct pyra_device *pyra,
42static int pyra_send_control(struct usb_device *usb_dev, int value, 42static int pyra_send_control(struct usb_device *usb_dev, int value,
43 enum pyra_control_requests request) 43 enum pyra_control_requests request)
44{ 44{
45 struct pyra_control control; 45 struct roccat_common2_control control;
46 46
47 if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS || 47 if ((request == PYRA_CONTROL_REQUEST_PROFILE_SETTINGS ||
48 request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) && 48 request == PYRA_CONTROL_REQUEST_PROFILE_BUTTONS) &&
49 (value < 0 || value > 4)) 49 (value < 0 || value > 4))
50 return -EINVAL; 50 return -EINVAL;
51 51
52 control.command = PYRA_COMMAND_CONTROL; 52 control.command = ROCCAT_COMMON_COMMAND_CONTROL;
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_COMMAND_CONTROL, 56 return roccat_common2_send(usb_dev, ROCCAT_COMMON_COMMAND_CONTROL,
57 &control, sizeof(struct pyra_control)); 57 &control, sizeof(struct roccat_common2_control));
58}
59
60static int pyra_receive_control_status(struct usb_device *usb_dev)
61{
62 int retval;
63 struct pyra_control control;
64
65 do {
66 msleep(10);
67 retval = roccat_common_receive(usb_dev, PYRA_COMMAND_CONTROL,
68 &control, sizeof(struct pyra_control));
69
70 /* requested too early, try again */
71 } while (retval == -EPROTO);
72
73 if (!retval && control.command == PYRA_COMMAND_CONTROL &&
74 control.request == PYRA_CONTROL_REQUEST_STATUS &&
75 control.value == 1)
76 return 0;
77 else {
78 hid_err(usb_dev, "receive control status: unknown response 0x%x 0x%x\n",
79 control.request, control.value);
80 return retval ? retval : -EINVAL;
81 }
82} 58}
83 59
84static int pyra_get_profile_settings(struct usb_device *usb_dev, 60static int pyra_get_profile_settings(struct usb_device *usb_dev,
@@ -89,7 +65,7 @@ static int pyra_get_profile_settings(struct usb_device *usb_dev,
89 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS); 65 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS);
90 if (retval) 66 if (retval)
91 return retval; 67 return retval;
92 return roccat_common_receive(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS, 68 return roccat_common2_receive(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS,
93 buf, sizeof(struct pyra_profile_settings)); 69 buf, sizeof(struct pyra_profile_settings));
94} 70}
95 71
@@ -101,51 +77,44 @@ static int pyra_get_profile_buttons(struct usb_device *usb_dev,
101 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS); 77 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS);
102 if (retval) 78 if (retval)
103 return retval; 79 return retval;
104 return roccat_common_receive(usb_dev, PYRA_COMMAND_PROFILE_BUTTONS, 80 return roccat_common2_receive(usb_dev, PYRA_COMMAND_PROFILE_BUTTONS,
105 buf, sizeof(struct pyra_profile_buttons)); 81 buf, sizeof(struct pyra_profile_buttons));
106} 82}
107 83
108static int pyra_get_settings(struct usb_device *usb_dev, 84static int pyra_get_settings(struct usb_device *usb_dev,
109 struct pyra_settings *buf) 85 struct pyra_settings *buf)
110{ 86{
111 return roccat_common_receive(usb_dev, PYRA_COMMAND_SETTINGS, 87 return roccat_common2_receive(usb_dev, PYRA_COMMAND_SETTINGS,
112 buf, sizeof(struct pyra_settings)); 88 buf, sizeof(struct pyra_settings));
113} 89}
114 90
115static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf) 91static int pyra_get_info(struct usb_device *usb_dev, struct pyra_info *buf)
116{ 92{
117 return roccat_common_receive(usb_dev, PYRA_COMMAND_INFO, 93 return roccat_common2_receive(usb_dev, PYRA_COMMAND_INFO,
118 buf, sizeof(struct pyra_info)); 94 buf, sizeof(struct pyra_info));
119} 95}
120 96
121static int pyra_send(struct usb_device *usb_dev, uint command,
122 void const *buf, uint size)
123{
124 int retval;
125 retval = roccat_common_send(usb_dev, command, buf, size);
126 if (retval)
127 return retval;
128 return pyra_receive_control_status(usb_dev);
129}
130
131static int pyra_set_profile_settings(struct usb_device *usb_dev, 97static int pyra_set_profile_settings(struct usb_device *usb_dev,
132 struct pyra_profile_settings const *settings) 98 struct pyra_profile_settings const *settings)
133{ 99{
134 return pyra_send(usb_dev, PYRA_COMMAND_PROFILE_SETTINGS, settings, 100 return roccat_common2_send_with_status(usb_dev,
101 PYRA_COMMAND_PROFILE_SETTINGS, settings,
135 sizeof(struct pyra_profile_settings)); 102 sizeof(struct pyra_profile_settings));
136} 103}
137 104
138static int pyra_set_profile_buttons(struct usb_device *usb_dev, 105static int pyra_set_profile_buttons(struct usb_device *usb_dev,
139 struct pyra_profile_buttons const *buttons) 106 struct pyra_profile_buttons const *buttons)
140{ 107{
141 return pyra_send(usb_dev, PYRA_COMMAND_PROFILE_BUTTONS, buttons, 108 return roccat_common2_send_with_status(usb_dev,
109 PYRA_COMMAND_PROFILE_BUTTONS, buttons,
142 sizeof(struct pyra_profile_buttons)); 110 sizeof(struct pyra_profile_buttons));
143} 111}
144 112
145static int pyra_set_settings(struct usb_device *usb_dev, 113static int pyra_set_settings(struct usb_device *usb_dev,
146 struct pyra_settings const *settings) 114 struct pyra_settings const *settings)
147{ 115{
148 return pyra_send(usb_dev, PYRA_COMMAND_SETTINGS, settings, 116 return roccat_common2_send_with_status(usb_dev,
117 PYRA_COMMAND_SETTINGS, settings,
149 sizeof(struct pyra_settings)); 118 sizeof(struct pyra_settings));
150} 119}
151 120
diff --git a/drivers/hid/hid-roccat-pyra.h b/drivers/hid/hid-roccat-pyra.h
index 0442d7fa2dcf..eada7830fa99 100644
--- a/drivers/hid/hid-roccat-pyra.h
+++ b/drivers/hid/hid-roccat-pyra.h
@@ -20,18 +20,7 @@ struct pyra_b {
20 uint8_t unknown; /* 1 */ 20 uint8_t unknown; /* 1 */
21} __attribute__ ((__packed__)); 21} __attribute__ ((__packed__));
22 22
23struct pyra_control {
24 uint8_t command; /* PYRA_COMMAND_CONTROL */
25 /*
26 * value is profile number for request_settings and request_buttons
27 * 1 if status ok for request_status
28 */
29 uint8_t value; /* Range 0-4 */
30 uint8_t request;
31} __attribute__ ((__packed__));
32
33enum pyra_control_requests { 23enum pyra_control_requests {
34 PYRA_CONTROL_REQUEST_STATUS = 0x00,
35 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10, 24 PYRA_CONTROL_REQUEST_PROFILE_SETTINGS = 0x10,
36 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20 25 PYRA_CONTROL_REQUEST_PROFILE_BUTTONS = 0x20
37}; 26};
@@ -75,7 +64,6 @@ struct pyra_info {
75} __attribute__ ((__packed__)); 64} __attribute__ ((__packed__));
76 65
77enum pyra_commands { 66enum pyra_commands {
78 PYRA_COMMAND_CONTROL = 0x4,
79 PYRA_COMMAND_SETTINGS = 0x5, 67 PYRA_COMMAND_SETTINGS = 0x5,
80 PYRA_COMMAND_PROFILE_SETTINGS = 0x6, 68 PYRA_COMMAND_PROFILE_SETTINGS = 0x6,
81 PYRA_COMMAND_PROFILE_BUTTONS = 0x7, 69 PYRA_COMMAND_PROFILE_BUTTONS = 0x7,
diff --git a/drivers/hid/hid-roccat-savu.c b/drivers/hid/hid-roccat-savu.c
new file mode 100644
index 000000000000..014afba407e0
--- /dev/null
+++ b/drivers/hid/hid-roccat-savu.c
@@ -0,0 +1,316 @@
1/*
2 * Roccat Savu driver for Linux
3 *
4 * Copyright (c) 2012 Stefan Achatz <erazor_de@users.sourceforge.net>
5 */
6
7/*
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 */
13
14/* Roccat Savu is a gamer mouse with macro keys that can be configured in
15 * 5 profiles.
16 */
17
18#include <linux/device.h>
19#include <linux/input.h>
20#include <linux/hid.h>
21#include <linux/module.h>
22#include <linux/slab.h>
23#include <linux/hid-roccat.h>
24#include "hid-ids.h"
25#include "hid-roccat-common.h"
26#include "hid-roccat-savu.h"
27
28static struct class *savu_class;
29
30static ssize_t savu_sysfs_read(struct file *fp, struct kobject *kobj,
31 char *buf, loff_t off, size_t count,
32 size_t real_size, uint command)
33{
34 struct device *dev =
35 container_of(kobj, struct device, kobj)->parent->parent;
36 struct savu_device *savu = hid_get_drvdata(dev_get_drvdata(dev));
37 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
38 int retval;
39
40 if (off >= real_size)
41 return 0;
42
43 if (off != 0 || count != real_size)
44 return -EINVAL;
45
46 mutex_lock(&savu->savu_lock);
47 retval = roccat_common2_receive(usb_dev, command, buf, real_size);
48 mutex_unlock(&savu->savu_lock);
49
50 return retval ? retval : real_size;
51}
52
53static ssize_t savu_sysfs_write(struct file *fp, struct kobject *kobj,
54 void const *buf, loff_t off, size_t count,
55 size_t real_size, uint command)
56{
57 struct device *dev =
58 container_of(kobj, struct device, kobj)->parent->parent;
59 struct savu_device *savu = hid_get_drvdata(dev_get_drvdata(dev));
60 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
61 int retval;
62
63 if (off != 0 || count != real_size)
64 return -EINVAL;
65
66 mutex_lock(&savu->savu_lock);
67 retval = roccat_common2_send_with_status(usb_dev, command,
68 (void *)buf, real_size);
69 mutex_unlock(&savu->savu_lock);
70
71 return retval ? retval : real_size;
72}
73
74#define SAVU_SYSFS_W(thingy, THINGY) \
75static ssize_t savu_sysfs_write_ ## thingy(struct file *fp, \
76 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
77 loff_t off, size_t count) \
78{ \
79 return savu_sysfs_write(fp, kobj, buf, off, count, \
80 SAVU_SIZE_ ## THINGY, SAVU_COMMAND_ ## THINGY); \
81}
82
83#define SAVU_SYSFS_R(thingy, THINGY) \
84static ssize_t savu_sysfs_read_ ## thingy(struct file *fp, \
85 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
86 loff_t off, size_t count) \
87{ \
88 return savu_sysfs_read(fp, kobj, buf, off, count, \
89 SAVU_SIZE_ ## THINGY, SAVU_COMMAND_ ## THINGY); \
90}
91
92#define SAVU_SYSFS_RW(thingy, THINGY) \
93SAVU_SYSFS_W(thingy, THINGY) \
94SAVU_SYSFS_R(thingy, THINGY)
95
96#define SAVU_BIN_ATTRIBUTE_RW(thingy, THINGY) \
97{ \
98 .attr = { .name = #thingy, .mode = 0660 }, \
99 .size = SAVU_SIZE_ ## THINGY, \
100 .read = savu_sysfs_read_ ## thingy, \
101 .write = savu_sysfs_write_ ## thingy \
102}
103
104#define SAVU_BIN_ATTRIBUTE_R(thingy, THINGY) \
105{ \
106 .attr = { .name = #thingy, .mode = 0440 }, \
107 .size = SAVU_SIZE_ ## THINGY, \
108 .read = savu_sysfs_read_ ## thingy, \
109}
110
111#define SAVU_BIN_ATTRIBUTE_W(thingy, THINGY) \
112{ \
113 .attr = { .name = #thingy, .mode = 0220 }, \
114 .size = SAVU_SIZE_ ## THINGY, \
115 .write = savu_sysfs_write_ ## thingy \
116}
117
118SAVU_SYSFS_W(control, CONTROL)
119SAVU_SYSFS_RW(profile, PROFILE)
120SAVU_SYSFS_RW(general, GENERAL)
121SAVU_SYSFS_RW(buttons, BUTTONS)
122SAVU_SYSFS_RW(macro, MACRO)
123SAVU_SYSFS_R(info, INFO)
124SAVU_SYSFS_RW(sensor, SENSOR)
125
126static struct bin_attribute savu_bin_attributes[] = {
127 SAVU_BIN_ATTRIBUTE_W(control, CONTROL),
128 SAVU_BIN_ATTRIBUTE_RW(profile, PROFILE),
129 SAVU_BIN_ATTRIBUTE_RW(general, GENERAL),
130 SAVU_BIN_ATTRIBUTE_RW(buttons, BUTTONS),
131 SAVU_BIN_ATTRIBUTE_RW(macro, MACRO),
132 SAVU_BIN_ATTRIBUTE_R(info, INFO),
133 SAVU_BIN_ATTRIBUTE_RW(sensor, SENSOR),
134 __ATTR_NULL
135};
136
137static int savu_init_savu_device_struct(struct usb_device *usb_dev,
138 struct savu_device *savu)
139{
140 mutex_init(&savu->savu_lock);
141
142 return 0;
143}
144
145static int savu_init_specials(struct hid_device *hdev)
146{
147 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
148 struct usb_device *usb_dev = interface_to_usbdev(intf);
149 struct savu_device *savu;
150 int retval;
151
152 if (intf->cur_altsetting->desc.bInterfaceProtocol
153 != USB_INTERFACE_PROTOCOL_MOUSE) {
154 hid_set_drvdata(hdev, NULL);
155 return 0;
156 }
157
158 savu = kzalloc(sizeof(*savu), GFP_KERNEL);
159 if (!savu) {
160 hid_err(hdev, "can't alloc device descriptor\n");
161 return -ENOMEM;
162 }
163 hid_set_drvdata(hdev, savu);
164
165 retval = savu_init_savu_device_struct(usb_dev, savu);
166 if (retval) {
167 hid_err(hdev, "couldn't init struct savu_device\n");
168 goto exit_free;
169 }
170
171 retval = roccat_connect(savu_class, hdev,
172 sizeof(struct savu_roccat_report));
173 if (retval < 0) {
174 hid_err(hdev, "couldn't init char dev\n");
175 } else {
176 savu->chrdev_minor = retval;
177 savu->roccat_claimed = 1;
178 }
179
180 return 0;
181exit_free:
182 kfree(savu);
183 return retval;
184}
185
186static void savu_remove_specials(struct hid_device *hdev)
187{
188 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
189 struct savu_device *savu;
190
191 if (intf->cur_altsetting->desc.bInterfaceProtocol
192 != USB_INTERFACE_PROTOCOL_MOUSE)
193 return;
194
195 savu = hid_get_drvdata(hdev);
196 if (savu->roccat_claimed)
197 roccat_disconnect(savu->chrdev_minor);
198 kfree(savu);
199}
200
201static int savu_probe(struct hid_device *hdev,
202 const struct hid_device_id *id)
203{
204 int retval;
205
206 retval = hid_parse(hdev);
207 if (retval) {
208 hid_err(hdev, "parse failed\n");
209 goto exit;
210 }
211
212 retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
213 if (retval) {
214 hid_err(hdev, "hw start failed\n");
215 goto exit;
216 }
217
218 retval = savu_init_specials(hdev);
219 if (retval) {
220 hid_err(hdev, "couldn't install mouse\n");
221 goto exit_stop;
222 }
223
224 return 0;
225
226exit_stop:
227 hid_hw_stop(hdev);
228exit:
229 return retval;
230}
231
232static void savu_remove(struct hid_device *hdev)
233{
234 savu_remove_specials(hdev);
235 hid_hw_stop(hdev);
236}
237
238static void savu_report_to_chrdev(struct savu_device const *savu,
239 u8 const *data)
240{
241 struct savu_roccat_report roccat_report;
242 struct savu_mouse_report_special const *special_report;
243
244 if (data[0] != SAVU_MOUSE_REPORT_NUMBER_SPECIAL)
245 return;
246
247 special_report = (struct savu_mouse_report_special const *)data;
248
249 roccat_report.type = special_report->type;
250 roccat_report.data[0] = special_report->data[0];
251 roccat_report.data[1] = special_report->data[1];
252 roccat_report_event(savu->chrdev_minor,
253 (uint8_t const *)&roccat_report);
254}
255
256static int savu_raw_event(struct hid_device *hdev,
257 struct hid_report *report, u8 *data, int size)
258{
259 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
260 struct savu_device *savu = hid_get_drvdata(hdev);
261
262 if (intf->cur_altsetting->desc.bInterfaceProtocol
263 != USB_INTERFACE_PROTOCOL_MOUSE)
264 return 0;
265
266 if (savu == NULL)
267 return 0;
268
269 if (savu->roccat_claimed)
270 savu_report_to_chrdev(savu, data);
271
272 return 0;
273}
274
275static const struct hid_device_id savu_devices[] = {
276 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) },
277 { }
278};
279
280MODULE_DEVICE_TABLE(hid, savu_devices);
281
282static struct hid_driver savu_driver = {
283 .name = "savu",
284 .id_table = savu_devices,
285 .probe = savu_probe,
286 .remove = savu_remove,
287 .raw_event = savu_raw_event
288};
289
290static int __init savu_init(void)
291{
292 int retval;
293
294 savu_class = class_create(THIS_MODULE, "savu");
295 if (IS_ERR(savu_class))
296 return PTR_ERR(savu_class);
297 savu_class->dev_bin_attrs = savu_bin_attributes;
298
299 retval = hid_register_driver(&savu_driver);
300 if (retval)
301 class_destroy(savu_class);
302 return retval;
303}
304
305static void __exit savu_exit(void)
306{
307 hid_unregister_driver(&savu_driver);
308 class_destroy(savu_class);
309}
310
311module_init(savu_init);
312module_exit(savu_exit);
313
314MODULE_AUTHOR("Stefan Achatz");
315MODULE_DESCRIPTION("USB Roccat Savu driver");
316MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-roccat-savu.h b/drivers/hid/hid-roccat-savu.h
new file mode 100644
index 000000000000..9120ba72087f
--- /dev/null
+++ b/drivers/hid/hid-roccat-savu.h
@@ -0,0 +1,87 @@
1#ifndef __HID_ROCCAT_SAVU_H
2#define __HID_ROCCAT_SAVU_H
3
4/*
5 * Copyright (c) 2012 Stefan Achatz <erazor_de@users.sourceforge.net>
6 */
7
8/*
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the Free
11 * Software Foundation; either version 2 of the License, or (at your option)
12 * any later version.
13 */
14
15#include <linux/types.h>
16
17enum {
18 SAVU_SIZE_CONTROL = 0x03,
19 SAVU_SIZE_PROFILE = 0x03,
20 SAVU_SIZE_GENERAL = 0x10,
21 SAVU_SIZE_BUTTONS = 0x2f,
22 SAVU_SIZE_MACRO = 0x0823,
23 SAVU_SIZE_INFO = 0x08,
24 SAVU_SIZE_SENSOR = 0x04,
25};
26
27enum savu_control_requests {
28 SAVU_CONTROL_REQUEST_GENERAL = 0x80,
29 SAVU_CONTROL_REQUEST_BUTTONS = 0x90,
30};
31
32enum savu_commands {
33 SAVU_COMMAND_CONTROL = 0x4,
34 SAVU_COMMAND_PROFILE = 0x5,
35 SAVU_COMMAND_GENERAL = 0x6,
36 SAVU_COMMAND_BUTTONS = 0x7,
37 SAVU_COMMAND_MACRO = 0x8,
38 SAVU_COMMAND_INFO = 0x9,
39 SAVU_COMMAND_SENSOR = 0xc,
40};
41
42struct savu_mouse_report_special {
43 uint8_t report_number; /* always 3 */
44 uint8_t zero;
45 uint8_t type;
46 uint8_t data[2];
47} __packed;
48
49enum {
50 SAVU_MOUSE_REPORT_NUMBER_SPECIAL = 3,
51};
52
53enum savu_mouse_report_button_types {
54 /* data1 = new profile range 1-5 */
55 SAVU_MOUSE_REPORT_BUTTON_TYPE_PROFILE = 0x20,
56
57 /* data1 = button number range 1-24; data2 = action */
58 SAVU_MOUSE_REPORT_BUTTON_TYPE_QUICKLAUNCH = 0x60,
59
60 /* data1 = button number range 1-24; data2 = action */
61 SAVU_MOUSE_REPORT_BUTTON_TYPE_TIMER = 0x80,
62
63 /* data1 = setting number range 1-5 */
64 SAVU_MOUSE_REPORT_BUTTON_TYPE_CPI = 0xb0,
65
66 /* data1 and data2 = range 0x1-0xb */
67 SAVU_MOUSE_REPORT_BUTTON_TYPE_SENSITIVITY = 0xc0,
68
69 /* data1 = 22 = next track...
70 * data2 = action
71 */
72 SAVU_MOUSE_REPORT_BUTTON_TYPE_MULTIMEDIA = 0xf0,
73};
74
75struct savu_roccat_report {
76 uint8_t type;
77 uint8_t data[2];
78} __packed;
79
80struct savu_device {
81 int roccat_claimed;
82 int chrdev_minor;
83
84 struct mutex savu_lock;
85};
86
87#endif
diff --git a/drivers/hid/hid-wiimote-ext.c b/drivers/hid/hid-wiimote-ext.c
index aa958706c0e5..0a1805c9b0e5 100644
--- a/drivers/hid/hid-wiimote-ext.c
+++ b/drivers/hid/hid-wiimote-ext.c
@@ -77,7 +77,7 @@ static __u16 wiiext_keymap[] = {
77 BTN_TR, /* WIIEXT_KEY_RT */ 77 BTN_TR, /* WIIEXT_KEY_RT */
78}; 78};
79 79
80/* diable all extensions */ 80/* disable all extensions */
81static void ext_disable(struct wiimote_ext *ext) 81static void ext_disable(struct wiimote_ext *ext)
82{ 82{
83 unsigned long flags; 83 unsigned long flags;
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 36fa77b40ffb..3b6f7bf5a77e 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -96,6 +96,7 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
96 } 96 }
97 97
98 kfree(list->buffer[list->tail].value); 98 kfree(list->buffer[list->tail].value);
99 list->buffer[list->tail].value = NULL;
99 list->tail = (list->tail + 1) & (HIDRAW_BUFFER_SIZE - 1); 100 list->tail = (list->tail + 1) & (HIDRAW_BUFFER_SIZE - 1);
100 } 101 }
101out: 102out:
@@ -300,6 +301,7 @@ static int hidraw_release(struct inode * inode, struct file * file)
300 struct hidraw *dev; 301 struct hidraw *dev;
301 struct hidraw_list *list = file->private_data; 302 struct hidraw_list *list = file->private_data;
302 int ret; 303 int ret;
304 int i;
303 305
304 mutex_lock(&minors_lock); 306 mutex_lock(&minors_lock);
305 if (!hidraw_table[minor]) { 307 if (!hidraw_table[minor]) {
@@ -317,6 +319,9 @@ static int hidraw_release(struct inode * inode, struct file * file)
317 kfree(list->hidraw); 319 kfree(list->hidraw);
318 } 320 }
319 } 321 }
322
323 for (i = 0; i < HIDRAW_BUFFER_SIZE; ++i)
324 kfree(list->buffer[i].value);
320 kfree(list); 325 kfree(list);
321 ret = 0; 326 ret = 0;
322unlock: 327unlock:
@@ -446,12 +451,17 @@ int hidraw_report_event(struct hid_device *hid, u8 *data, int len)
446 int ret = 0; 451 int ret = 0;
447 452
448 list_for_each_entry(list, &dev->list, node) { 453 list_for_each_entry(list, &dev->list, node) {
454 int new_head = (list->head + 1) & (HIDRAW_BUFFER_SIZE - 1);
455
456 if (new_head == list->tail)
457 continue;
458
449 if (!(list->buffer[list->head].value = kmemdup(data, len, GFP_ATOMIC))) { 459 if (!(list->buffer[list->head].value = kmemdup(data, len, GFP_ATOMIC))) {
450 ret = -ENOMEM; 460 ret = -ENOMEM;
451 break; 461 break;
452 } 462 }
453 list->buffer[list->head].len = len; 463 list->buffer[list->head].len = len;
454 list->head = (list->head + 1) & (HIDRAW_BUFFER_SIZE - 1); 464 list->head = new_head;
455 kill_fasync(&list->fasync, SIGIO, POLL_IN); 465 kill_fasync(&list->fasync, SIGIO, POLL_IN);
456 } 466 }
457 467
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c
new file mode 100644
index 000000000000..714cd8cc9579
--- /dev/null
+++ b/drivers/hid/uhid.c
@@ -0,0 +1,572 @@
1/*
2 * User-space I/O driver support for HID subsystem
3 * Copyright (c) 2012 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/fs.h>
16#include <linux/hid.h>
17#include <linux/input.h>
18#include <linux/miscdevice.h>
19#include <linux/module.h>
20#include <linux/mutex.h>
21#include <linux/poll.h>
22#include <linux/sched.h>
23#include <linux/spinlock.h>
24#include <linux/uhid.h>
25#include <linux/wait.h>
26
27#define UHID_NAME "uhid"
28#define UHID_BUFSIZE 32
29
30struct uhid_device {
31 struct mutex devlock;
32 bool running;
33
34 __u8 *rd_data;
35 uint rd_size;
36
37 struct hid_device *hid;
38 struct uhid_event input_buf;
39
40 wait_queue_head_t waitq;
41 spinlock_t qlock;
42 __u8 head;
43 __u8 tail;
44 struct uhid_event *outq[UHID_BUFSIZE];
45
46 struct mutex report_lock;
47 wait_queue_head_t report_wait;
48 atomic_t report_done;
49 atomic_t report_id;
50 struct uhid_event report_buf;
51};
52
53static struct miscdevice uhid_misc;
54
55static void uhid_queue(struct uhid_device *uhid, struct uhid_event *ev)
56{
57 __u8 newhead;
58
59 newhead = (uhid->head + 1) % UHID_BUFSIZE;
60
61 if (newhead != uhid->tail) {
62 uhid->outq[uhid->head] = ev;
63 uhid->head = newhead;
64 wake_up_interruptible(&uhid->waitq);
65 } else {
66 hid_warn(uhid->hid, "Output queue is full\n");
67 kfree(ev);
68 }
69}
70
71static int uhid_queue_event(struct uhid_device *uhid, __u32 event)
72{
73 unsigned long flags;
74 struct uhid_event *ev;
75
76 ev = kzalloc(sizeof(*ev), GFP_KERNEL);
77 if (!ev)
78 return -ENOMEM;
79
80 ev->type = event;
81
82 spin_lock_irqsave(&uhid->qlock, flags);
83 uhid_queue(uhid, ev);
84 spin_unlock_irqrestore(&uhid->qlock, flags);
85
86 return 0;
87}
88
89static int uhid_hid_start(struct hid_device *hid)
90{
91 struct uhid_device *uhid = hid->driver_data;
92
93 return uhid_queue_event(uhid, UHID_START);
94}
95
96static void uhid_hid_stop(struct hid_device *hid)
97{
98 struct uhid_device *uhid = hid->driver_data;
99
100 hid->claimed = 0;
101 uhid_queue_event(uhid, UHID_STOP);
102}
103
104static int uhid_hid_open(struct hid_device *hid)
105{
106 struct uhid_device *uhid = hid->driver_data;
107
108 return uhid_queue_event(uhid, UHID_OPEN);
109}
110
111static void uhid_hid_close(struct hid_device *hid)
112{
113 struct uhid_device *uhid = hid->driver_data;
114
115 uhid_queue_event(uhid, UHID_CLOSE);
116}
117
118static int uhid_hid_input(struct input_dev *input, unsigned int type,
119 unsigned int code, int value)
120{
121 struct hid_device *hid = input_get_drvdata(input);
122 struct uhid_device *uhid = hid->driver_data;
123 unsigned long flags;
124 struct uhid_event *ev;
125
126 ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
127 if (!ev)
128 return -ENOMEM;
129
130 ev->type = UHID_OUTPUT_EV;
131 ev->u.output_ev.type = type;
132 ev->u.output_ev.code = code;
133 ev->u.output_ev.value = value;
134
135 spin_lock_irqsave(&uhid->qlock, flags);
136 uhid_queue(uhid, ev);
137 spin_unlock_irqrestore(&uhid->qlock, flags);
138
139 return 0;
140}
141
142static int uhid_hid_parse(struct hid_device *hid)
143{
144 struct uhid_device *uhid = hid->driver_data;
145
146 return hid_parse_report(hid, uhid->rd_data, uhid->rd_size);
147}
148
149static int uhid_hid_get_raw(struct hid_device *hid, unsigned char rnum,
150 __u8 *buf, size_t count, unsigned char rtype)
151{
152 struct uhid_device *uhid = hid->driver_data;
153 __u8 report_type;
154 struct uhid_event *ev;
155 unsigned long flags;
156 int ret;
157 size_t uninitialized_var(len);
158 struct uhid_feature_answer_req *req;
159
160 if (!uhid->running)
161 return -EIO;
162
163 switch (rtype) {
164 case HID_FEATURE_REPORT:
165 report_type = UHID_FEATURE_REPORT;
166 break;
167 case HID_OUTPUT_REPORT:
168 report_type = UHID_OUTPUT_REPORT;
169 break;
170 case HID_INPUT_REPORT:
171 report_type = UHID_INPUT_REPORT;
172 break;
173 default:
174 return -EINVAL;
175 }
176
177 ret = mutex_lock_interruptible(&uhid->report_lock);
178 if (ret)
179 return ret;
180
181 ev = kzalloc(sizeof(*ev), GFP_KERNEL);
182 if (!ev) {
183 ret = -ENOMEM;
184 goto unlock;
185 }
186
187 spin_lock_irqsave(&uhid->qlock, flags);
188 ev->type = UHID_FEATURE;
189 ev->u.feature.id = atomic_inc_return(&uhid->report_id);
190 ev->u.feature.rnum = rnum;
191 ev->u.feature.rtype = report_type;
192
193 atomic_set(&uhid->report_done, 0);
194 uhid_queue(uhid, ev);
195 spin_unlock_irqrestore(&uhid->qlock, flags);
196
197 ret = wait_event_interruptible_timeout(uhid->report_wait,
198 atomic_read(&uhid->report_done), 5 * HZ);
199
200 /*
201 * Make sure "uhid->running" is cleared on shutdown before
202 * "uhid->report_done" is set.
203 */
204 smp_rmb();
205 if (!ret || !uhid->running) {
206 ret = -EIO;
207 } else if (ret < 0) {
208 ret = -ERESTARTSYS;
209 } else {
210 spin_lock_irqsave(&uhid->qlock, flags);
211 req = &uhid->report_buf.u.feature_answer;
212
213 if (req->err) {
214 ret = -EIO;
215 } else {
216 ret = 0;
217 len = min(count,
218 min_t(size_t, req->size, UHID_DATA_MAX));
219 memcpy(buf, req->data, len);
220 }
221
222 spin_unlock_irqrestore(&uhid->qlock, flags);
223 }
224
225 atomic_set(&uhid->report_done, 1);
226
227unlock:
228 mutex_unlock(&uhid->report_lock);
229 return ret ? ret : len;
230}
231
232static int uhid_hid_output_raw(struct hid_device *hid, __u8 *buf, size_t count,
233 unsigned char report_type)
234{
235 struct uhid_device *uhid = hid->driver_data;
236 __u8 rtype;
237 unsigned long flags;
238 struct uhid_event *ev;
239
240 switch (report_type) {
241 case HID_FEATURE_REPORT:
242 rtype = UHID_FEATURE_REPORT;
243 break;
244 case HID_OUTPUT_REPORT:
245 rtype = UHID_OUTPUT_REPORT;
246 break;
247 default:
248 return -EINVAL;
249 }
250
251 if (count < 1 || count > UHID_DATA_MAX)
252 return -EINVAL;
253
254 ev = kzalloc(sizeof(*ev), GFP_KERNEL);
255 if (!ev)
256 return -ENOMEM;
257
258 ev->type = UHID_OUTPUT;
259 ev->u.output.size = count;
260 ev->u.output.rtype = rtype;
261 memcpy(ev->u.output.data, buf, count);
262
263 spin_lock_irqsave(&uhid->qlock, flags);
264 uhid_queue(uhid, ev);
265 spin_unlock_irqrestore(&uhid->qlock, flags);
266
267 return count;
268}
269
270static struct hid_ll_driver uhid_hid_driver = {
271 .start = uhid_hid_start,
272 .stop = uhid_hid_stop,
273 .open = uhid_hid_open,
274 .close = uhid_hid_close,
275 .hidinput_input_event = uhid_hid_input,
276 .parse = uhid_hid_parse,
277};
278
279static int uhid_dev_create(struct uhid_device *uhid,
280 const struct uhid_event *ev)
281{
282 struct hid_device *hid;
283 int ret;
284
285 if (uhid->running)
286 return -EALREADY;
287
288 uhid->rd_size = ev->u.create.rd_size;
289 if (uhid->rd_size <= 0 || uhid->rd_size > HID_MAX_DESCRIPTOR_SIZE)
290 return -EINVAL;
291
292 uhid->rd_data = kmalloc(uhid->rd_size, GFP_KERNEL);
293 if (!uhid->rd_data)
294 return -ENOMEM;
295
296 if (copy_from_user(uhid->rd_data, ev->u.create.rd_data,
297 uhid->rd_size)) {
298 ret = -EFAULT;
299 goto err_free;
300 }
301
302 hid = hid_allocate_device();
303 if (IS_ERR(hid)) {
304 ret = PTR_ERR(hid);
305 goto err_free;
306 }
307
308 strncpy(hid->name, ev->u.create.name, 127);
309 hid->name[127] = 0;
310 strncpy(hid->phys, ev->u.create.phys, 63);
311 hid->phys[63] = 0;
312 strncpy(hid->uniq, ev->u.create.uniq, 63);
313 hid->uniq[63] = 0;
314
315 hid->ll_driver = &uhid_hid_driver;
316 hid->hid_get_raw_report = uhid_hid_get_raw;
317 hid->hid_output_raw_report = uhid_hid_output_raw;
318 hid->bus = ev->u.create.bus;
319 hid->vendor = ev->u.create.vendor;
320 hid->product = ev->u.create.product;
321 hid->version = ev->u.create.version;
322 hid->country = ev->u.create.country;
323 hid->driver_data = uhid;
324 hid->dev.parent = uhid_misc.this_device;
325
326 uhid->hid = hid;
327 uhid->running = true;
328
329 ret = hid_add_device(hid);
330 if (ret) {
331 hid_err(hid, "Cannot register HID device\n");
332 goto err_hid;
333 }
334
335 return 0;
336
337err_hid:
338 hid_destroy_device(hid);
339 uhid->hid = NULL;
340 uhid->running = false;
341err_free:
342 kfree(uhid->rd_data);
343 return ret;
344}
345
346static int uhid_dev_destroy(struct uhid_device *uhid)
347{
348 if (!uhid->running)
349 return -EINVAL;
350
351 /* clear "running" before setting "report_done" */
352 uhid->running = false;
353 smp_wmb();
354 atomic_set(&uhid->report_done, 1);
355 wake_up_interruptible(&uhid->report_wait);
356
357 hid_destroy_device(uhid->hid);
358 kfree(uhid->rd_data);
359
360 return 0;
361}
362
363static int uhid_dev_input(struct uhid_device *uhid, struct uhid_event *ev)
364{
365 if (!uhid->running)
366 return -EINVAL;
367
368 hid_input_report(uhid->hid, HID_INPUT_REPORT, ev->u.input.data,
369 min_t(size_t, ev->u.input.size, UHID_DATA_MAX), 0);
370
371 return 0;
372}
373
374static int uhid_dev_feature_answer(struct uhid_device *uhid,
375 struct uhid_event *ev)
376{
377 unsigned long flags;
378
379 if (!uhid->running)
380 return -EINVAL;
381
382 spin_lock_irqsave(&uhid->qlock, flags);
383
384 /* id for old report; drop it silently */
385 if (atomic_read(&uhid->report_id) != ev->u.feature_answer.id)
386 goto unlock;
387 if (atomic_read(&uhid->report_done))
388 goto unlock;
389
390 memcpy(&uhid->report_buf, ev, sizeof(*ev));
391 atomic_set(&uhid->report_done, 1);
392 wake_up_interruptible(&uhid->report_wait);
393
394unlock:
395 spin_unlock_irqrestore(&uhid->qlock, flags);
396 return 0;
397}
398
399static int uhid_char_open(struct inode *inode, struct file *file)
400{
401 struct uhid_device *uhid;
402
403 uhid = kzalloc(sizeof(*uhid), GFP_KERNEL);
404 if (!uhid)
405 return -ENOMEM;
406
407 mutex_init(&uhid->devlock);
408 mutex_init(&uhid->report_lock);
409 spin_lock_init(&uhid->qlock);
410 init_waitqueue_head(&uhid->waitq);
411 init_waitqueue_head(&uhid->report_wait);
412 uhid->running = false;
413 atomic_set(&uhid->report_done, 1);
414
415 file->private_data = uhid;
416 nonseekable_open(inode, file);
417
418 return 0;
419}
420
421static int uhid_char_release(struct inode *inode, struct file *file)
422{
423 struct uhid_device *uhid = file->private_data;
424 unsigned int i;
425
426 uhid_dev_destroy(uhid);
427
428 for (i = 0; i < UHID_BUFSIZE; ++i)
429 kfree(uhid->outq[i]);
430
431 kfree(uhid);
432
433 return 0;
434}
435
436static ssize_t uhid_char_read(struct file *file, char __user *buffer,
437 size_t count, loff_t *ppos)
438{
439 struct uhid_device *uhid = file->private_data;
440 int ret;
441 unsigned long flags;
442 size_t len;
443
444 /* they need at least the "type" member of uhid_event */
445 if (count < sizeof(__u32))
446 return -EINVAL;
447
448try_again:
449 if (file->f_flags & O_NONBLOCK) {
450 if (uhid->head == uhid->tail)
451 return -EAGAIN;
452 } else {
453 ret = wait_event_interruptible(uhid->waitq,
454 uhid->head != uhid->tail);
455 if (ret)
456 return ret;
457 }
458
459 ret = mutex_lock_interruptible(&uhid->devlock);
460 if (ret)
461 return ret;
462
463 if (uhid->head == uhid->tail) {
464 mutex_unlock(&uhid->devlock);
465 goto try_again;
466 } else {
467 len = min(count, sizeof(**uhid->outq));
468 if (copy_to_user(buffer, uhid->outq[uhid->tail], len)) {
469 ret = -EFAULT;
470 } else {
471 kfree(uhid->outq[uhid->tail]);
472 uhid->outq[uhid->tail] = NULL;
473
474 spin_lock_irqsave(&uhid->qlock, flags);
475 uhid->tail = (uhid->tail + 1) % UHID_BUFSIZE;
476 spin_unlock_irqrestore(&uhid->qlock, flags);
477 }
478 }
479
480 mutex_unlock(&uhid->devlock);
481 return ret ? ret : len;
482}
483
484static ssize_t uhid_char_write(struct file *file, const char __user *buffer,
485 size_t count, loff_t *ppos)
486{
487 struct uhid_device *uhid = file->private_data;
488 int ret;
489 size_t len;
490
491 /* we need at least the "type" member of uhid_event */
492 if (count < sizeof(__u32))
493 return -EINVAL;
494
495 ret = mutex_lock_interruptible(&uhid->devlock);
496 if (ret)
497 return ret;
498
499 memset(&uhid->input_buf, 0, sizeof(uhid->input_buf));
500 len = min(count, sizeof(uhid->input_buf));
501 if (copy_from_user(&uhid->input_buf, buffer, len)) {
502 ret = -EFAULT;
503 goto unlock;
504 }
505
506 switch (uhid->input_buf.type) {
507 case UHID_CREATE:
508 ret = uhid_dev_create(uhid, &uhid->input_buf);
509 break;
510 case UHID_DESTROY:
511 ret = uhid_dev_destroy(uhid);
512 break;
513 case UHID_INPUT:
514 ret = uhid_dev_input(uhid, &uhid->input_buf);
515 break;
516 case UHID_FEATURE_ANSWER:
517 ret = uhid_dev_feature_answer(uhid, &uhid->input_buf);
518 break;
519 default:
520 ret = -EOPNOTSUPP;
521 }
522
523unlock:
524 mutex_unlock(&uhid->devlock);
525
526 /* return "count" not "len" to not confuse the caller */
527 return ret ? ret : count;
528}
529
530static unsigned int uhid_char_poll(struct file *file, poll_table *wait)
531{
532 struct uhid_device *uhid = file->private_data;
533
534 poll_wait(file, &uhid->waitq, wait);
535
536 if (uhid->head != uhid->tail)
537 return POLLIN | POLLRDNORM;
538
539 return 0;
540}
541
542static const struct file_operations uhid_fops = {
543 .owner = THIS_MODULE,
544 .open = uhid_char_open,
545 .release = uhid_char_release,
546 .read = uhid_char_read,
547 .write = uhid_char_write,
548 .poll = uhid_char_poll,
549 .llseek = no_llseek,
550};
551
552static struct miscdevice uhid_misc = {
553 .fops = &uhid_fops,
554 .minor = MISC_DYNAMIC_MINOR,
555 .name = UHID_NAME,
556};
557
558static int __init uhid_init(void)
559{
560 return misc_register(&uhid_misc);
561}
562
563static void __exit uhid_exit(void)
564{
565 misc_deregister(&uhid_misc);
566}
567
568module_init(uhid_init);
569module_exit(uhid_exit);
570MODULE_LICENSE("GPL");
571MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>");
572MODULE_DESCRIPTION("User-space I/O driver support for HID subsystem");
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index 482f936fc29b..dedd8e4e5c6d 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -84,7 +84,7 @@ static int hid_start_in(struct hid_device *hid)
84 spin_lock_irqsave(&usbhid->lock, flags); 84 spin_lock_irqsave(&usbhid->lock, flags);
85 if (hid->open > 0 && 85 if (hid->open > 0 &&
86 !test_bit(HID_DISCONNECTED, &usbhid->iofl) && 86 !test_bit(HID_DISCONNECTED, &usbhid->iofl) &&
87 !test_bit(HID_REPORTED_IDLE, &usbhid->iofl) && 87 !test_bit(HID_SUSPENDED, &usbhid->iofl) &&
88 !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) { 88 !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) {
89 rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC); 89 rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC);
90 if (rc != 0) { 90 if (rc != 0) {
@@ -207,15 +207,27 @@ static int usbhid_restart_out_queue(struct usbhid_device *usbhid)
207 int kicked; 207 int kicked;
208 int r; 208 int r;
209 209
210 if (!hid) 210 if (!hid || test_bit(HID_RESET_PENDING, &usbhid->iofl) ||
211 test_bit(HID_SUSPENDED, &usbhid->iofl))
211 return 0; 212 return 0;
212 213
213 if ((kicked = (usbhid->outhead != usbhid->outtail))) { 214 if ((kicked = (usbhid->outhead != usbhid->outtail))) {
214 hid_dbg(hid, "Kicking head %d tail %d", usbhid->outhead, usbhid->outtail); 215 hid_dbg(hid, "Kicking head %d tail %d", usbhid->outhead, usbhid->outtail);
215 216
217 /* Try to wake up from autosuspend... */
216 r = usb_autopm_get_interface_async(usbhid->intf); 218 r = usb_autopm_get_interface_async(usbhid->intf);
217 if (r < 0) 219 if (r < 0)
218 return r; 220 return r;
221
222 /*
223 * If still suspended, don't submit. Submission will
224 * occur if/when resume drains the queue.
225 */
226 if (test_bit(HID_SUSPENDED, &usbhid->iofl)) {
227 usb_autopm_put_interface_no_suspend(usbhid->intf);
228 return r;
229 }
230
219 /* Asynchronously flush queue. */ 231 /* Asynchronously flush queue. */
220 set_bit(HID_OUT_RUNNING, &usbhid->iofl); 232 set_bit(HID_OUT_RUNNING, &usbhid->iofl);
221 if (hid_submit_out(hid)) { 233 if (hid_submit_out(hid)) {
@@ -234,15 +246,27 @@ static int usbhid_restart_ctrl_queue(struct usbhid_device *usbhid)
234 int r; 246 int r;
235 247
236 WARN_ON(hid == NULL); 248 WARN_ON(hid == NULL);
237 if (!hid) 249 if (!hid || test_bit(HID_RESET_PENDING, &usbhid->iofl) ||
250 test_bit(HID_SUSPENDED, &usbhid->iofl))
238 return 0; 251 return 0;
239 252
240 if ((kicked = (usbhid->ctrlhead != usbhid->ctrltail))) { 253 if ((kicked = (usbhid->ctrlhead != usbhid->ctrltail))) {
241 hid_dbg(hid, "Kicking head %d tail %d", usbhid->ctrlhead, usbhid->ctrltail); 254 hid_dbg(hid, "Kicking head %d tail %d", usbhid->ctrlhead, usbhid->ctrltail);
242 255
256 /* Try to wake up from autosuspend... */
243 r = usb_autopm_get_interface_async(usbhid->intf); 257 r = usb_autopm_get_interface_async(usbhid->intf);
244 if (r < 0) 258 if (r < 0)
245 return r; 259 return r;
260
261 /*
262 * If still suspended, don't submit. Submission will
263 * occur if/when resume drains the queue.
264 */
265 if (test_bit(HID_SUSPENDED, &usbhid->iofl)) {
266 usb_autopm_put_interface_no_suspend(usbhid->intf);
267 return r;
268 }
269
246 /* Asynchronously flush queue. */ 270 /* Asynchronously flush queue. */
247 set_bit(HID_CTRL_RUNNING, &usbhid->iofl); 271 set_bit(HID_CTRL_RUNNING, &usbhid->iofl);
248 if (hid_submit_ctrl(hid)) { 272 if (hid_submit_ctrl(hid)) {
@@ -331,9 +355,12 @@ static int hid_submit_out(struct hid_device *hid)
331 usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 355 usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) +
332 1 + (report->id > 0); 356 1 + (report->id > 0);
333 usbhid->urbout->dev = hid_to_usb_dev(hid); 357 usbhid->urbout->dev = hid_to_usb_dev(hid);
334 memcpy(usbhid->outbuf, raw_report, 358 if (raw_report) {
335 usbhid->urbout->transfer_buffer_length); 359 memcpy(usbhid->outbuf, raw_report,
336 kfree(raw_report); 360 usbhid->urbout->transfer_buffer_length);
361 kfree(raw_report);
362 usbhid->out[usbhid->outtail].raw_report = NULL;
363 }
337 364
338 dbg_hid("submitting out urb\n"); 365 dbg_hid("submitting out urb\n");
339 366
@@ -362,8 +389,11 @@ static int hid_submit_ctrl(struct hid_device *hid)
362 if (dir == USB_DIR_OUT) { 389 if (dir == USB_DIR_OUT) {
363 usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0); 390 usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0);
364 usbhid->urbctrl->transfer_buffer_length = len; 391 usbhid->urbctrl->transfer_buffer_length = len;
365 memcpy(usbhid->ctrlbuf, raw_report, len); 392 if (raw_report) {
366 kfree(raw_report); 393 memcpy(usbhid->ctrlbuf, raw_report, len);
394 kfree(raw_report);
395 usbhid->ctrl[usbhid->ctrltail].raw_report = NULL;
396 }
367 } else { 397 } else {
368 int maxpacket, padlen; 398 int maxpacket, padlen;
369 399
@@ -407,16 +437,6 @@ static int hid_submit_ctrl(struct hid_device *hid)
407 * Output interrupt completion handler. 437 * Output interrupt completion handler.
408 */ 438 */
409 439
410static int irq_out_pump_restart(struct hid_device *hid)
411{
412 struct usbhid_device *usbhid = hid->driver_data;
413
414 if (usbhid->outhead != usbhid->outtail)
415 return hid_submit_out(hid);
416 else
417 return -1;
418}
419
420static void hid_irq_out(struct urb *urb) 440static void hid_irq_out(struct urb *urb)
421{ 441{
422 struct hid_device *hid = urb->context; 442 struct hid_device *hid = urb->context;
@@ -441,15 +461,17 @@ static void hid_irq_out(struct urb *urb)
441 461
442 spin_lock_irqsave(&usbhid->lock, flags); 462 spin_lock_irqsave(&usbhid->lock, flags);
443 463
444 if (unplug) 464 if (unplug) {
445 usbhid->outtail = usbhid->outhead; 465 usbhid->outtail = usbhid->outhead;
446 else 466 } else {
447 usbhid->outtail = (usbhid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1); 467 usbhid->outtail = (usbhid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1);
448 468
449 if (!irq_out_pump_restart(hid)) { 469 if (usbhid->outhead != usbhid->outtail &&
450 /* Successfully submitted next urb in queue */ 470 hid_submit_out(hid) == 0) {
451 spin_unlock_irqrestore(&usbhid->lock, flags); 471 /* Successfully submitted next urb in queue */
452 return; 472 spin_unlock_irqrestore(&usbhid->lock, flags);
473 return;
474 }
453 } 475 }
454 476
455 clear_bit(HID_OUT_RUNNING, &usbhid->iofl); 477 clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
@@ -461,15 +483,6 @@ static void hid_irq_out(struct urb *urb)
461/* 483/*
462 * Control pipe completion handler. 484 * Control pipe completion handler.
463 */ 485 */
464static int ctrl_pump_restart(struct hid_device *hid)
465{
466 struct usbhid_device *usbhid = hid->driver_data;
467
468 if (usbhid->ctrlhead != usbhid->ctrltail)
469 return hid_submit_ctrl(hid);
470 else
471 return -1;
472}
473 486
474static void hid_ctrl(struct urb *urb) 487static void hid_ctrl(struct urb *urb)
475{ 488{
@@ -498,15 +511,17 @@ static void hid_ctrl(struct urb *urb)
498 hid_warn(urb->dev, "ctrl urb status %d received\n", status); 511 hid_warn(urb->dev, "ctrl urb status %d received\n", status);
499 } 512 }
500 513
501 if (unplug) 514 if (unplug) {
502 usbhid->ctrltail = usbhid->ctrlhead; 515 usbhid->ctrltail = usbhid->ctrlhead;
503 else 516 } else {
504 usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); 517 usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
505 518
506 if (!ctrl_pump_restart(hid)) { 519 if (usbhid->ctrlhead != usbhid->ctrltail &&
507 /* Successfully submitted next urb in queue */ 520 hid_submit_ctrl(hid) == 0) {
508 spin_unlock(&usbhid->lock); 521 /* Successfully submitted next urb in queue */
509 return; 522 spin_unlock(&usbhid->lock);
523 return;
524 }
510 } 525 }
511 526
512 clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); 527 clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
@@ -540,49 +555,36 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re
540 usbhid->out[usbhid->outhead].report = report; 555 usbhid->out[usbhid->outhead].report = report;
541 usbhid->outhead = head; 556 usbhid->outhead = head;
542 557
543 /* Try to awake from autosuspend... */ 558 /* If the queue isn't running, restart it */
544 if (usb_autopm_get_interface_async(usbhid->intf) < 0) 559 if (!test_bit(HID_OUT_RUNNING, &usbhid->iofl)) {
545 return; 560 usbhid_restart_out_queue(usbhid);
546 561
547 /* 562 /* Otherwise see if an earlier request has timed out */
548 * But if still suspended, leave urb enqueued, don't submit. 563 } else if (time_after(jiffies, usbhid->last_out + HZ * 5)) {
549 * Submission will occur if/when resume() drains the queue. 564
550 */ 565 /* Prevent autosuspend following the unlink */
551 if (test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) 566 usb_autopm_get_interface_no_resume(usbhid->intf);
552 return;
553 567
554 if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl)) {
555 if (hid_submit_out(hid)) {
556 clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
557 usb_autopm_put_interface_async(usbhid->intf);
558 }
559 wake_up(&usbhid->wait);
560 } else {
561 /* 568 /*
562 * the queue is known to run 569 * Prevent resubmission in case the URB completes
563 * but an earlier request may be stuck 570 * before we can unlink it. We don't want to cancel
564 * we may need to time out 571 * the wrong transfer!
565 * no race because the URB is blocked under
566 * spinlock
567 */ 572 */
568 if (time_after(jiffies, usbhid->last_out + HZ * 5)) { 573 usb_block_urb(usbhid->urbout);
569 usb_block_urb(usbhid->urbout);
570 /* drop lock to not deadlock if the callback is called */
571 spin_unlock(&usbhid->lock);
572 usb_unlink_urb(usbhid->urbout);
573 spin_lock(&usbhid->lock);
574 usb_unblock_urb(usbhid->urbout);
575 /*
576 * if the unlinking has already completed
577 * the pump will have been stopped
578 * it must be restarted now
579 */
580 if (!test_bit(HID_OUT_RUNNING, &usbhid->iofl))
581 if (!irq_out_pump_restart(hid))
582 set_bit(HID_OUT_RUNNING, &usbhid->iofl);
583 574
575 /* Drop lock to avoid deadlock if the callback runs */
576 spin_unlock(&usbhid->lock);
584 577
585 } 578 usb_unlink_urb(usbhid->urbout);
579 spin_lock(&usbhid->lock);
580 usb_unblock_urb(usbhid->urbout);
581
582 /* Unlink might have stopped the queue */
583 if (!test_bit(HID_OUT_RUNNING, &usbhid->iofl))
584 usbhid_restart_out_queue(usbhid);
585
586 /* Now we can allow autosuspend again */
587 usb_autopm_put_interface_async(usbhid->intf);
586 } 588 }
587 return; 589 return;
588 } 590 }
@@ -604,47 +606,36 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re
604 usbhid->ctrl[usbhid->ctrlhead].dir = dir; 606 usbhid->ctrl[usbhid->ctrlhead].dir = dir;
605 usbhid->ctrlhead = head; 607 usbhid->ctrlhead = head;
606 608
607 /* Try to awake from autosuspend... */ 609 /* If the queue isn't running, restart it */
608 if (usb_autopm_get_interface_async(usbhid->intf) < 0) 610 if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl)) {
609 return; 611 usbhid_restart_ctrl_queue(usbhid);
610 612
611 /* 613 /* Otherwise see if an earlier request has timed out */
612 * If already suspended, leave urb enqueued, but don't submit. 614 } else if (time_after(jiffies, usbhid->last_ctrl + HZ * 5)) {
613 * Submission will occur if/when resume() drains the queue. 615
614 */ 616 /* Prevent autosuspend following the unlink */
615 if (test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) 617 usb_autopm_get_interface_no_resume(usbhid->intf);
616 return;
617 618
618 if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl)) {
619 if (hid_submit_ctrl(hid)) {
620 clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
621 usb_autopm_put_interface_async(usbhid->intf);
622 }
623 wake_up(&usbhid->wait);
624 } else {
625 /* 619 /*
626 * the queue is known to run 620 * Prevent resubmission in case the URB completes
627 * but an earlier request may be stuck 621 * before we can unlink it. We don't want to cancel
628 * we may need to time out 622 * the wrong transfer!
629 * no race because the URB is blocked under
630 * spinlock
631 */ 623 */
632 if (time_after(jiffies, usbhid->last_ctrl + HZ * 5)) { 624 usb_block_urb(usbhid->urbctrl);
633 usb_block_urb(usbhid->urbctrl); 625
634 /* drop lock to not deadlock if the callback is called */ 626 /* Drop lock to avoid deadlock if the callback runs */
635 spin_unlock(&usbhid->lock); 627 spin_unlock(&usbhid->lock);
636 usb_unlink_urb(usbhid->urbctrl); 628
637 spin_lock(&usbhid->lock); 629 usb_unlink_urb(usbhid->urbctrl);
638 usb_unblock_urb(usbhid->urbctrl); 630 spin_lock(&usbhid->lock);
639 /* 631 usb_unblock_urb(usbhid->urbctrl);
640 * if the unlinking has already completed 632
641 * the pump will have been stopped 633 /* Unlink might have stopped the queue */
642 * it must be restarted now 634 if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
643 */ 635 usbhid_restart_ctrl_queue(usbhid);
644 if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl)) 636
645 if (!ctrl_pump_restart(hid)) 637 /* Now we can allow autosuspend again */
646 set_bit(HID_CTRL_RUNNING, &usbhid->iofl); 638 usb_autopm_put_interface_async(usbhid->intf);
647 }
648 } 639 }
649} 640}
650 641
@@ -1002,9 +993,10 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
1002 993
1003static void usbhid_restart_queues(struct usbhid_device *usbhid) 994static void usbhid_restart_queues(struct usbhid_device *usbhid)
1004{ 995{
1005 if (usbhid->urbout) 996 if (usbhid->urbout && !test_bit(HID_OUT_RUNNING, &usbhid->iofl))
1006 usbhid_restart_out_queue(usbhid); 997 usbhid_restart_out_queue(usbhid);
1007 usbhid_restart_ctrl_queue(usbhid); 998 if (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl))
999 usbhid_restart_ctrl_queue(usbhid);
1008} 1000}
1009 1001
1010static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) 1002static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
@@ -1471,11 +1463,38 @@ void usbhid_put_power(struct hid_device *hid)
1471 1463
1472 1464
1473#ifdef CONFIG_PM 1465#ifdef CONFIG_PM
1466static int hid_resume_common(struct hid_device *hid, bool driver_suspended)
1467{
1468 struct usbhid_device *usbhid = hid->driver_data;
1469 int status;
1470
1471 spin_lock_irq(&usbhid->lock);
1472 clear_bit(HID_SUSPENDED, &usbhid->iofl);
1473 usbhid_mark_busy(usbhid);
1474
1475 if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) ||
1476 test_bit(HID_RESET_PENDING, &usbhid->iofl))
1477 schedule_work(&usbhid->reset_work);
1478 usbhid->retry_delay = 0;
1479
1480 usbhid_restart_queues(usbhid);
1481 spin_unlock_irq(&usbhid->lock);
1482
1483 status = hid_start_in(hid);
1484 if (status < 0)
1485 hid_io_error(hid);
1486
1487 if (driver_suspended && hid->driver && hid->driver->resume)
1488 status = hid->driver->resume(hid);
1489 return status;
1490}
1491
1474static int hid_suspend(struct usb_interface *intf, pm_message_t message) 1492static int hid_suspend(struct usb_interface *intf, pm_message_t message)
1475{ 1493{
1476 struct hid_device *hid = usb_get_intfdata(intf); 1494 struct hid_device *hid = usb_get_intfdata(intf);
1477 struct usbhid_device *usbhid = hid->driver_data; 1495 struct usbhid_device *usbhid = hid->driver_data;
1478 int status; 1496 int status;
1497 bool driver_suspended = false;
1479 1498
1480 if (PMSG_IS_AUTO(message)) { 1499 if (PMSG_IS_AUTO(message)) {
1481 spin_lock_irq(&usbhid->lock); /* Sync with error handler */ 1500 spin_lock_irq(&usbhid->lock); /* Sync with error handler */
@@ -1486,13 +1505,14 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
1486 && !test_bit(HID_KEYS_PRESSED, &usbhid->iofl) 1505 && !test_bit(HID_KEYS_PRESSED, &usbhid->iofl)
1487 && (!usbhid->ledcount || ignoreled)) 1506 && (!usbhid->ledcount || ignoreled))
1488 { 1507 {
1489 set_bit(HID_REPORTED_IDLE, &usbhid->iofl); 1508 set_bit(HID_SUSPENDED, &usbhid->iofl);
1490 spin_unlock_irq(&usbhid->lock); 1509 spin_unlock_irq(&usbhid->lock);
1491 if (hid->driver && hid->driver->suspend) { 1510 if (hid->driver && hid->driver->suspend) {
1492 status = hid->driver->suspend(hid, message); 1511 status = hid->driver->suspend(hid, message);
1493 if (status < 0) 1512 if (status < 0)
1494 return status; 1513 goto failed;
1495 } 1514 }
1515 driver_suspended = true;
1496 } else { 1516 } else {
1497 usbhid_mark_busy(usbhid); 1517 usbhid_mark_busy(usbhid);
1498 spin_unlock_irq(&usbhid->lock); 1518 spin_unlock_irq(&usbhid->lock);
@@ -1505,11 +1525,14 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
1505 if (status < 0) 1525 if (status < 0)
1506 return status; 1526 return status;
1507 } 1527 }
1528 driver_suspended = true;
1508 spin_lock_irq(&usbhid->lock); 1529 spin_lock_irq(&usbhid->lock);
1509 set_bit(HID_REPORTED_IDLE, &usbhid->iofl); 1530 set_bit(HID_SUSPENDED, &usbhid->iofl);
1510 spin_unlock_irq(&usbhid->lock); 1531 spin_unlock_irq(&usbhid->lock);
1511 if (usbhid_wait_io(hid) < 0) 1532 if (usbhid_wait_io(hid) < 0) {
1512 return -EIO; 1533 status = -EIO;
1534 goto failed;
1535 }
1513 } 1536 }
1514 1537
1515 hid_cancel_delayed_stuff(usbhid); 1538 hid_cancel_delayed_stuff(usbhid);
@@ -1517,14 +1540,15 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
1517 1540
1518 if (PMSG_IS_AUTO(message) && test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) { 1541 if (PMSG_IS_AUTO(message) && test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) {
1519 /* lost race against keypresses */ 1542 /* lost race against keypresses */
1520 status = hid_start_in(hid); 1543 status = -EBUSY;
1521 if (status < 0) 1544 goto failed;
1522 hid_io_error(hid);
1523 usbhid_mark_busy(usbhid);
1524 return -EBUSY;
1525 } 1545 }
1526 dev_dbg(&intf->dev, "suspend\n"); 1546 dev_dbg(&intf->dev, "suspend\n");
1527 return 0; 1547 return 0;
1548
1549 failed:
1550 hid_resume_common(hid, driver_suspended);
1551 return status;
1528} 1552}
1529 1553
1530static int hid_resume(struct usb_interface *intf) 1554static int hid_resume(struct usb_interface *intf)
@@ -1536,23 +1560,7 @@ static int hid_resume(struct usb_interface *intf)
1536 if (!test_bit(HID_STARTED, &usbhid->iofl)) 1560 if (!test_bit(HID_STARTED, &usbhid->iofl))
1537 return 0; 1561 return 0;
1538 1562
1539 clear_bit(HID_REPORTED_IDLE, &usbhid->iofl); 1563 status = hid_resume_common(hid, true);
1540 usbhid_mark_busy(usbhid);
1541
1542 if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) ||
1543 test_bit(HID_RESET_PENDING, &usbhid->iofl))
1544 schedule_work(&usbhid->reset_work);
1545 usbhid->retry_delay = 0;
1546 status = hid_start_in(hid);
1547 if (status < 0)
1548 hid_io_error(hid);
1549 usbhid_restart_queues(usbhid);
1550
1551 if (status >= 0 && hid->driver && hid->driver->resume) {
1552 int ret = hid->driver->resume(hid);
1553 if (ret < 0)
1554 status = ret;
1555 }
1556 dev_dbg(&intf->dev, "resume status %d\n", status); 1564 dev_dbg(&intf->dev, "resume status %d\n", status);
1557 return 0; 1565 return 0;
1558} 1566}
@@ -1563,7 +1571,7 @@ static int hid_reset_resume(struct usb_interface *intf)
1563 struct usbhid_device *usbhid = hid->driver_data; 1571 struct usbhid_device *usbhid = hid->driver_data;
1564 int status; 1572 int status;
1565 1573
1566 clear_bit(HID_REPORTED_IDLE, &usbhid->iofl); 1574 clear_bit(HID_SUSPENDED, &usbhid->iofl);
1567 status = hid_post_reset(intf); 1575 status = hid_post_reset(intf);
1568 if (status >= 0 && hid->driver && hid->driver->reset_resume) { 1576 if (status >= 0 && hid->driver && hid->driver->reset_resume) {
1569 int ret = hid->driver->reset_resume(hid); 1577 int ret = hid->driver->reset_resume(hid);
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h
index 1883d7b94870..bd87a61e5303 100644
--- a/drivers/hid/usbhid/usbhid.h
+++ b/drivers/hid/usbhid/usbhid.h
@@ -53,7 +53,6 @@ struct usb_interface *usbhid_find_interface(int minor);
53#define HID_CLEAR_HALT 6 53#define HID_CLEAR_HALT 6
54#define HID_DISCONNECTED 7 54#define HID_DISCONNECTED 7
55#define HID_STARTED 8 55#define HID_STARTED 8
56#define HID_REPORTED_IDLE 9
57#define HID_KEYS_PRESSED 10 56#define HID_KEYS_PRESSED 10
58#define HID_NO_BANDWIDTH 11 57#define HID_NO_BANDWIDTH 11
59 58