aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-driver-hid-roccat-ryos178
-rw-r--r--drivers/hid/Kconfig22
-rw-r--r--drivers/hid/Makefile2
-rw-r--r--drivers/hid/hid-apple.c22
-rw-r--r--drivers/hid/hid-axff.c3
-rw-r--r--drivers/hid/hid-core.c25
-rw-r--r--drivers/hid/hid-elo.c35
-rw-r--r--drivers/hid/hid-holtek-mouse.c4
-rw-r--r--drivers/hid/hid-ids.h16
-rw-r--r--drivers/hid/hid-lenovo-tpkbd.c50
-rw-r--r--drivers/hid/hid-lg.c138
-rw-r--r--drivers/hid/hid-lg2ff.c2
-rw-r--r--drivers/hid/hid-lg4ff.c101
-rw-r--r--drivers/hid/hid-logitech-dj.c14
-rw-r--r--drivers/hid/hid-multitouch.c27
-rw-r--r--drivers/hid/hid-roccat-common.c65
-rw-r--r--drivers/hid/hid-roccat-common.h62
-rw-r--r--drivers/hid/hid-roccat-konepure.c158
-rw-r--r--drivers/hid/hid-roccat-konepure.h72
-rw-r--r--drivers/hid/hid-roccat-kovaplus.c4
-rw-r--r--drivers/hid/hid-roccat-ryos.c241
-rw-r--r--drivers/hid/hid-roccat-savu.c123
-rw-r--r--drivers/hid/hid-roccat-savu.h32
-rw-r--r--drivers/hid/hid-sensor-hub.c13
-rw-r--r--drivers/hid/hid-sony.c63
-rw-r--r--drivers/hid/i2c-hid/i2c-hid.c4
-rw-r--r--drivers/hid/usbhid/hid-quirks.c2
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c4
28 files changed, 1040 insertions, 442 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-ryos b/Documentation/ABI/testing/sysfs-driver-hid-roccat-ryos
new file mode 100644
index 000000000000..1d6a8cf9dc0a
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-ryos
@@ -0,0 +1,178 @@
1What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/control
2Date: October 2013
3Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
4Description: When written, this file lets one select which data from which
5 profile will be read next. The data has to be 3 bytes long.
6 This file is writeonly.
7Users: http://roccat.sourceforge.net
8
9What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/profile
10Date: October 2013
11Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
12Description: The mouse can store 5 profiles which can be switched by the
13 press of a button. profile holds index of actual profile.
14 This value is persistent, so its value determines the profile
15 that's active when the device is powered on next time.
16 When written, the device activates the set profile immediately.
17 The data has to be 3 bytes long.
18 The device will reject invalid data.
19Users: http://roccat.sourceforge.net
20
21What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/keys_primary
22Date: October 2013
23Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
24Description: When written, this file lets one set the default of all keys for
25 a specific profile. Profile index is included in written data.
26 The data has to be 125 bytes long.
27 Before reading this file, control has to be written to select
28 which profile to read.
29Users: http://roccat.sourceforge.net
30
31What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/keys_function
32Date: October 2013
33Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
34Description: When written, this file lets one set the function of the
35 function keys for a specific profile. Profile index is included
36 in written data. The data has to be 95 bytes long.
37 Before reading this file, control has to be written to select
38 which profile to read.
39Users: http://roccat.sourceforge.net
40
41What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/keys_macro
42Date: October 2013
43Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
44Description: When written, this file lets one set the function of the macro
45 keys for a specific profile. Profile index is included in
46 written data. The data has to be 35 bytes long.
47 Before reading this file, control has to be written to select
48 which profile to read.
49Users: http://roccat.sourceforge.net
50
51What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/keys_thumbster
52Date: October 2013
53Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
54Description: When written, this file lets one set the function of the
55 thumbster keys for a specific profile. Profile index is included
56 in written data. The data has to be 23 bytes long.
57 Before reading this file, control has to be written to select
58 which profile to read.
59Users: http://roccat.sourceforge.net
60
61What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/keys_extra
62Date: October 2013
63Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
64Description: When written, this file lets one set the function of the
65 capslock and function keys for a specific profile. Profile index
66 is included in written data. The data has to be 8 bytes long.
67 Before reading this file, control has to be written to select
68 which profile to read.
69Users: http://roccat.sourceforge.net
70
71What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/keys_easyzone
72Date: October 2013
73Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
74Description: When written, this file lets one set the function of the
75 easyzone keys for a specific profile. Profile index is included
76 in written data. The data has to be 294 bytes long.
77 Before reading this file, control has to be written to select
78 which profile to read.
79Users: http://roccat.sourceforge.net
80
81What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/key_mask
82Date: October 2013
83Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
84Description: When written, this file lets one deactivate certain keys like
85 windows and application keys, to prevent accidental presses.
86 Profile index for which this settings occur is included in
87 written data. The data has to be 6 bytes long.
88 Before reading this file, control has to be written to select
89 which profile to read.
90Users: http://roccat.sourceforge.net
91
92What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/light
93Date: October 2013
94Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
95Description: When written, this file lets one set the backlight intensity for
96 a specific profile. Profile index is included in written data.
97 This attribute is only valid for the glow and pro variant.
98 The data has to be 16 bytes long.
99 Before reading this file, control has to be written to select
100 which profile to read.
101Users: http://roccat.sourceforge.net
102
103What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/macro
104Date: October 2013
105Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
106Description: When written, this file lets one store macros with max 480
107 keystrokes for a specific button for a specific profile.
108 Button and profile indexes are included in written data.
109 The data has to be 2002 bytes long.
110 Before reading this file, control has to be written to select
111 which profile and key to read.
112Users: http://roccat.sourceforge.net
113
114What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/info
115Date: October 2013
116Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
117Description: When read, this file returns general data like firmware version.
118 The data is 8 bytes long.
119 This file is readonly.
120Users: http://roccat.sourceforge.net
121
122What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/reset
123Date: October 2013
124Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
125Description: When written, this file lets one reset the device.
126 The data has to be 3 bytes long.
127 This file is writeonly.
128Users: http://roccat.sourceforge.net
129
130What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/talk
131Date: October 2013
132Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
133Description: When written, this file lets one trigger easyshift functionality
134 from the host.
135 The data has to be 16 bytes long.
136 This file is writeonly.
137Users: http://roccat.sourceforge.net
138
139What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/light_control
140Date: October 2013
141Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
142Description: When written, this file lets one switch between stored and custom
143 light settings.
144 This attribute is only valid for the pro variant.
145 The data has to be 8 bytes long.
146 This file is writeonly.
147Users: http://roccat.sourceforge.net
148
149What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/stored_lights
150Date: October 2013
151Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
152Description: When written, this file lets one set per-key lighting for different
153 layers.
154 This attribute is only valid for the pro variant.
155 The data has to be 1382 bytes long.
156 Before reading this file, control has to be written to select
157 which profile to read.
158Users: http://roccat.sourceforge.net
159
160What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/custom_lights
161Date: October 2013
162Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
163Description: When written, this file lets one set the actual per-key lighting.
164 This attribute is only valid for the pro variant.
165 The data has to be 20 bytes long.
166 This file is writeonly.
167Users: http://roccat.sourceforge.net
168
169What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/light_macro
170Date: October 2013
171Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
172Description: When written, this file lets one set a light macro that is looped
173 whenever the device gets in dimness mode.
174 This attribute is only valid for the pro variant.
175 The data has to be 2002 bytes long.
176 Before reading this file, control has to be written to select
177 which profile to read.
178Users: http://roccat.sourceforge.net
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index c91d547191dd..329fbb9b5976 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -242,6 +242,7 @@ config HID_HOLTEK
242 - Tracer Sniper TRM-503 / NOVA Gaming Slider X200 / 242 - Tracer Sniper TRM-503 / NOVA Gaming Slider X200 /
243 Zalman ZM-GM1 243 Zalman ZM-GM1
244 - SHARKOON DarkGlider Gaming mouse 244 - SHARKOON DarkGlider Gaming mouse
245 - LEETGION Hellion Gaming Mouse
245 246
246config HOLTEK_FF 247config HOLTEK_FF
247 bool "Holtek On Line Grip force feedback support" 248 bool "Holtek On Line Grip force feedback support"
@@ -323,7 +324,7 @@ config HID_LCPOWER
323 324
324config HID_LENOVO_TPKBD 325config HID_LENOVO_TPKBD
325 tristate "Lenovo ThinkPad USB Keyboard with TrackPoint" 326 tristate "Lenovo ThinkPad USB Keyboard with TrackPoint"
326 depends on USB_HID 327 depends on HID
327 select NEW_LEDS 328 select NEW_LEDS
328 select LEDS_CLASS 329 select LEDS_CLASS
329 ---help--- 330 ---help---
@@ -362,19 +363,20 @@ config LOGITECH_FF
362 - Logitech WingMan Force 3D 363 - Logitech WingMan Force 3D
363 - Logitech Formula Force EX 364 - Logitech Formula Force EX
364 - Logitech WingMan Formula Force GP 365 - Logitech WingMan Formula Force GP
365 - Logitech MOMO Force wheel
366 366
367 and if you want to enable force feedback for them. 367 and if you want to enable force feedback for them.
368 Note: if you say N here, this device will still be supported, but without 368 Note: if you say N here, this device will still be supported, but without
369 force feedback. 369 force feedback.
370 370
371config LOGIRUMBLEPAD2_FF 371config LOGIRUMBLEPAD2_FF
372 bool "Logitech RumblePad/Rumblepad 2 force feedback support" 372 bool "Logitech force feedback support (variant 2)"
373 depends on HID_LOGITECH 373 depends on HID_LOGITECH
374 select INPUT_FF_MEMLESS 374 select INPUT_FF_MEMLESS
375 help 375 help
376 Say Y here if you want to enable force feedback support for Logitech 376 Say Y here if you want to enable force feedback support for:
377 RumblePad and Rumblepad 2 devices. 377 - Logitech RumblePad
378 - Logitech Rumblepad 2
379 - Logitech Formula Vibration Feedback Wheel
378 380
379config LOGIG940_FF 381config LOGIG940_FF
380 bool "Logitech Flight System G940 force feedback support" 382 bool "Logitech Flight System G940 force feedback support"
@@ -437,6 +439,7 @@ config HID_MULTITOUCH
437 - Chunghwa panels 439 - Chunghwa panels
438 - CVTouch panels 440 - CVTouch panels
439 - Cypress TrueTouch panels 441 - Cypress TrueTouch panels
442 - Elan Microelectronics touch panels
440 - Elo TouchSystems IntelliTouch Plus panels 443 - Elo TouchSystems IntelliTouch Plus panels
441 - GeneralTouch 'Sensing Win7-TwoFinger' panels 444 - GeneralTouch 'Sensing Win7-TwoFinger' panels
442 - GoodTouch panels 445 - GoodTouch panels
@@ -453,6 +456,7 @@ config HID_MULTITOUCH
453 - Pixcir dual touch panels 456 - Pixcir dual touch panels
454 - Quanta panels 457 - Quanta panels
455 - eGalax dual-touch panels, including the Joojoo and Wetab tablets 458 - eGalax dual-touch panels, including the Joojoo and Wetab tablets
459 - SiS multitouch panels
456 - Stantum multitouch panels 460 - Stantum multitouch panels
457 - Touch International Panels 461 - Touch International Panels
458 - Unitec Panels 462 - Unitec Panels
@@ -614,6 +618,14 @@ config HID_SONY
614 * Sony PS3 Blue-ray Disk Remote Control (Bluetooth) 618 * Sony PS3 Blue-ray Disk Remote Control (Bluetooth)
615 * Logitech Harmony adapter for Sony Playstation 3 (Bluetooth) 619 * Logitech Harmony adapter for Sony Playstation 3 (Bluetooth)
616 620
621config SONY_FF
622 bool "Sony PS2/3 accessories force feedback support"
623 depends on HID_SONY
624 select INPUT_FF_MEMLESS
625 ---help---
626 Say Y here if you have a Sony PS2/3 accessory and want to enable force
627 feedback support for it.
628
617config HID_SPEEDLINK 629config HID_SPEEDLINK
618 tristate "Speedlink VAD Cezanne mouse support" 630 tristate "Speedlink VAD Cezanne mouse support"
619 depends on HID 631 depends on HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index a959f4aecaf5..30e44318f87f 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -95,7 +95,7 @@ obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
95obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ 95obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \
96 hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ 96 hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \
97 hid-roccat-koneplus.o hid-roccat-konepure.o hid-roccat-kovaplus.o \ 97 hid-roccat-koneplus.o hid-roccat-konepure.o hid-roccat-kovaplus.o \
98 hid-roccat-lua.o hid-roccat-pyra.o hid-roccat-savu.o 98 hid-roccat-lua.o hid-roccat-pyra.o hid-roccat-ryos.o hid-roccat-savu.o
99obj-$(CONFIG_HID_SAITEK) += hid-saitek.o 99obj-$(CONFIG_HID_SAITEK) += hid-saitek.o
100obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o 100obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o
101obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o 101obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index 881cf7b4f9a4..497558127bb3 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -46,6 +46,12 @@ module_param(iso_layout, uint, 0644);
46MODULE_PARM_DESC(iso_layout, "Enable/Disable hardcoded ISO-layout of the keyboard. " 46MODULE_PARM_DESC(iso_layout, "Enable/Disable hardcoded ISO-layout of the keyboard. "
47 "(0 = disabled, [1] = enabled)"); 47 "(0 = disabled, [1] = enabled)");
48 48
49static unsigned int swap_opt_cmd;
50module_param(swap_opt_cmd, uint, 0644);
51MODULE_PARM_DESC(swap_opt_cmd, "Swap the Option (\"Alt\") and Command (\"Flag\") keys. "
52 "(For people who want to keep Windows PC keyboard muscle memory. "
53 "[0] = as-is, Mac layout. 1 = swapped, Windows layout.)");
54
49struct apple_sc { 55struct apple_sc {
50 unsigned long quirks; 56 unsigned long quirks;
51 unsigned int fn_on; 57 unsigned int fn_on;
@@ -150,6 +156,14 @@ static const struct apple_key_translation apple_iso_keyboard[] = {
150 { } 156 { }
151}; 157};
152 158
159static const struct apple_key_translation swapped_option_cmd_keys[] = {
160 { KEY_LEFTALT, KEY_LEFTMETA },
161 { KEY_LEFTMETA, KEY_LEFTALT },
162 { KEY_RIGHTALT, KEY_RIGHTMETA },
163 { KEY_RIGHTMETA,KEY_RIGHTALT },
164 { }
165};
166
153static const struct apple_key_translation *apple_find_translation( 167static const struct apple_key_translation *apple_find_translation(
154 const struct apple_key_translation *table, u16 from) 168 const struct apple_key_translation *table, u16 from)
155{ 169{
@@ -242,6 +256,14 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
242 } 256 }
243 } 257 }
244 258
259 if (swap_opt_cmd) {
260 trans = apple_find_translation(swapped_option_cmd_keys, usage->code);
261 if (trans) {
262 input_event(input, usage->type, trans->to, value);
263 return 1;
264 }
265 }
266
245 return 0; 267 return 0;
246} 268}
247 269
diff --git a/drivers/hid/hid-axff.c b/drivers/hid/hid-axff.c
index 64ab94a55aa7..a594e478a1e2 100644
--- a/drivers/hid/hid-axff.c
+++ b/drivers/hid/hid-axff.c
@@ -95,7 +95,7 @@ static int axff_init(struct hid_device *hid)
95 } 95 }
96 } 96 }
97 97
98 if (field_count < 4) { 98 if (field_count < 4 && hid->product != 0xf705) {
99 hid_err(hid, "not enough fields in the report: %d\n", 99 hid_err(hid, "not enough fields in the report: %d\n",
100 field_count); 100 field_count);
101 return -ENODEV; 101 return -ENODEV;
@@ -180,6 +180,7 @@ static void ax_remove(struct hid_device *hdev)
180 180
181static const struct hid_device_id ax_devices[] = { 181static const struct hid_device_id ax_devices[] = {
182 { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802), }, 182 { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802), },
183 { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0xf705), },
183 { } 184 { }
184}; 185};
185MODULE_DEVICE_TABLE(hid, ax_devices); 186MODULE_DEVICE_TABLE(hid, ax_devices);
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index e80da62363bc..8c10f2742233 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1418,10 +1418,8 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i
1418 1418
1419 if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) { 1419 if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) {
1420 ret = hdrv->raw_event(hid, report, data, size); 1420 ret = hdrv->raw_event(hid, report, data, size);
1421 if (ret < 0) { 1421 if (ret < 0)
1422 ret = ret < 0 ? ret : 0;
1423 goto unlock; 1422 goto unlock;
1424 }
1425 } 1423 }
1426 1424
1427 ret = hid_report_raw_event(hid, type, data, size, interrupt); 1425 ret = hid_report_raw_event(hid, type, data, size, interrupt);
@@ -1605,6 +1603,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1605 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) }, 1603 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
1606 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) }, 1604 { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) },
1607 { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) }, 1605 { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) },
1606 { HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0xf705) },
1608 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) }, 1607 { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MIGHTYMOUSE) },
1609 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) }, 1608 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICMOUSE) },
1610 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) }, 1609 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGICTRACKPAD) },
@@ -1716,6 +1715,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1716 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) }, 1715 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD) },
1717 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) }, 1716 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) },
1718 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) }, 1717 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) },
1718 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072) },
1719 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) }, 1719 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) },
1720 { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) }, 1720 { HID_USB_DEVICE(USB_VENDOR_ID_HUION, USB_DEVICE_ID_HUION_580) },
1721 { HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) }, 1721 { HID_USB_DEVICE(USB_VENDOR_ID_JESS2, USB_DEVICE_ID_JESS2_COLOR_RUMBLE_PAD) },
@@ -1754,6 +1754,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
1754 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940) }, 1754 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FLIGHT_SYSTEM_G940) },
1755 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) }, 1755 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL) },
1756 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) }, 1756 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) },
1757 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL) },
1757 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL) }, 1758 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL) },
1758 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL) }, 1759 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL) },
1759 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) }, 1760 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },
@@ -1801,21 +1802,28 @@ static const struct hid_device_id hid_have_special_driver[] = {
1801 { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) }, 1802 { HID_USB_DEVICE(USB_VENDOR_ID_PETALYNX, USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE) },
1802 { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) }, 1803 { HID_USB_DEVICE(USB_VENDOR_ID_PRIMAX, USB_DEVICE_ID_PRIMAX_KEYBOARD) },
1803#if IS_ENABLED(CONFIG_HID_ROCCAT) 1804#if IS_ENABLED(CONFIG_HID_ROCCAT)
1804 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
1805 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) }, 1805 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ARVO) },
1806 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) }, 1806 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKU) },
1807 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_ISKUFX) },
1808 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONE) },
1807 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) }, 1809 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPLUS) },
1808 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE) }, 1810 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE) },
1809 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE_OPTICAL) }, 1811 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEPURE_OPTICAL) },
1812 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KONEXTD) },
1810 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) }, 1813 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_KOVAPLUS) },
1811 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) }, 1814 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_LUA) },
1812 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) }, 1815 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRED) },
1813 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) }, 1816 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS) },
1817 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK) },
1818 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK_GLOW) },
1819 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK_PRO) },
1814 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) }, 1820 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) },
1815#endif 1821#endif
1816 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) }, 1822 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) },
1817 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) }, 1823 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
1818 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) }, 1824 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
1825 { HID_USB_DEVICE(USB_VENDOR_ID_SIS2_TOUCH, USB_DEVICE_ID_SIS9200_TOUCH) },
1826 { HID_USB_DEVICE(USB_VENDOR_ID_SIS2_TOUCH, USB_DEVICE_ID_SIS817_TOUCH) },
1819 { HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) }, 1827 { HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
1820 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) }, 1828 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) },
1821 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) }, 1829 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) },
@@ -2376,15 +2384,6 @@ bool hid_ignore(struct hid_device *hdev)
2376 hdev->type == HID_TYPE_USBNONE) 2384 hdev->type == HID_TYPE_USBNONE)
2377 return true; 2385 return true;
2378 break; 2386 break;
2379 case USB_VENDOR_ID_DWAV:
2380 /* These are handled by usbtouchscreen. hdev->type is probably
2381 * HID_TYPE_USBNONE, but we say !HID_TYPE_USBMOUSE to match
2382 * usbtouchscreen. */
2383 if ((hdev->product == USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER ||
2384 hdev->product == USB_DEVICE_ID_DWAV_TOUCHCONTROLLER) &&
2385 hdev->type != HID_TYPE_USBMOUSE)
2386 return true;
2387 break;
2388 case USB_VENDOR_ID_VELLEMAN: 2387 case USB_VENDOR_ID_VELLEMAN:
2389 /* These are not HID devices. They are handled by comedi. */ 2388 /* These are not HID devices. They are handled by comedi. */
2390 if ((hdev->product >= USB_DEVICE_ID_VELLEMAN_K8055_FIRST && 2389 if ((hdev->product >= USB_DEVICE_ID_VELLEMAN_K8055_FIRST &&
diff --git a/drivers/hid/hid-elo.c b/drivers/hid/hid-elo.c
index f042a6cf8b18..4e49462870ab 100644
--- a/drivers/hid/hid-elo.c
+++ b/drivers/hid/hid-elo.c
@@ -181,7 +181,40 @@ fail:
181 */ 181 */
182static bool elo_broken_firmware(struct usb_device *dev) 182static bool elo_broken_firmware(struct usb_device *dev)
183{ 183{
184 return use_fw_quirk && le16_to_cpu(dev->descriptor.bcdDevice) == 0x10d; 184 struct usb_device *hub = dev->parent;
185 struct usb_device *child = NULL;
186 u16 fw_lvl = le16_to_cpu(dev->descriptor.bcdDevice);
187 u16 child_vid, child_pid;
188 int i;
189
190 if (!use_fw_quirk)
191 return false;
192 if (fw_lvl != 0x10d)
193 return false;
194
195 /* iterate sibling devices of the touch controller */
196 usb_hub_for_each_child(hub, i, child) {
197 child_vid = le16_to_cpu(child->descriptor.idVendor);
198 child_pid = le16_to_cpu(child->descriptor.idProduct);
199
200 /*
201 * If one of the devices below is present attached as a sibling of
202 * the touch controller then this is a newer IBM 4820 monitor that
203 * does not need the IBM-requested workaround if fw level is
204 * 0x010d - aka 'M'.
205 * No other HW can have this combination.
206 */
207 if (child_vid==0x04b3) {
208 switch (child_pid) {
209 case 0x4676: /* 4820 21x Video */
210 case 0x4677: /* 4820 51x Video */
211 case 0x4678: /* 4820 2Lx Video */
212 case 0x4679: /* 4820 5Lx Video */
213 return false;
214 }
215 }
216 }
217 return true;
185} 218}
186 219
187static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id) 220static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id)
diff --git a/drivers/hid/hid-holtek-mouse.c b/drivers/hid/hid-holtek-mouse.c
index e696566cde46..0caa676de622 100644
--- a/drivers/hid/hid-holtek-mouse.c
+++ b/drivers/hid/hid-holtek-mouse.c
@@ -28,6 +28,7 @@
28 * - USB ID 04d9:a04a, sold as Tracer Sniper TRM-503, NOVA Gaming Slider X200 28 * - USB ID 04d9:a04a, sold as Tracer Sniper TRM-503, NOVA Gaming Slider X200
29 * and Zalman ZM-GM1 29 * and Zalman ZM-GM1
30 * - USB ID 04d9:a081, sold as SHARKOON DarkGlider Gaming mouse 30 * - USB ID 04d9:a081, sold as SHARKOON DarkGlider Gaming mouse
31 * - USB ID 04d9:a072, sold as LEETGION Hellion Gaming Mouse
31 */ 32 */
32 33
33static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, 34static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
@@ -40,6 +41,7 @@ static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc,
40 * 0x2fff, so they don't exceed HID_MAX_USAGES */ 41 * 0x2fff, so they don't exceed HID_MAX_USAGES */
41 switch (hdev->product) { 42 switch (hdev->product) {
42 case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067: 43 case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067:
44 case USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072:
43 if (*rsize >= 122 && rdesc[115] == 0xff && rdesc[116] == 0x7f 45 if (*rsize >= 122 && rdesc[115] == 0xff && rdesc[116] == 0x7f
44 && rdesc[120] == 0xff && rdesc[121] == 0x7f) { 46 && rdesc[120] == 0xff && rdesc[121] == 0x7f) {
45 hid_info(hdev, "Fixing up report descriptor\n"); 47 hid_info(hdev, "Fixing up report descriptor\n");
@@ -66,6 +68,8 @@ static const struct hid_device_id holtek_mouse_devices[] = {
66 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, 68 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT,
67 USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) }, 69 USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A) },
68 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, 70 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT,
71 USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072) },
72 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT,
69 USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) }, 73 USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081) },
70 { } 74 { }
71}; 75};
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index f0296a50be5f..76559629568c 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -332,6 +332,11 @@
332#define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc 332#define USB_VENDOR_ID_GENERAL_TOUCH 0x0dfc
333#define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0003 333#define USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS 0x0003
334#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PWT_TENFINGERS 0x0100 334#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PWT_TENFINGERS 0x0100
335#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_0101 0x0101
336#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_0102 0x0102
337#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_0106 0x0106
338#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_010A 0x010a
339#define USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100 0xe100
335 340
336#define USB_VENDOR_ID_GLAB 0x06c2 341#define USB_VENDOR_ID_GLAB 0x06c2
337#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038 342#define USB_DEVICE_ID_4_PHIDGETSERVO_30 0x0038
@@ -448,8 +453,9 @@
448 453
449#define USB_VENDOR_ID_HOLTEK_ALT 0x04d9 454#define USB_VENDOR_ID_HOLTEK_ALT 0x04d9
450#define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD 0xa055 455#define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD 0xa055
451#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067 0xa067
452#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A 0xa04a 456#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A04A 0xa04a
457#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067 0xa067
458#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A072 0xa072
453#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081 0xa081 459#define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081 0xa081
454 460
455#define USB_VENDOR_ID_IMATION 0x0718 461#define USB_VENDOR_ID_IMATION 0x0718
@@ -571,6 +577,7 @@
571#define USB_DEVICE_ID_DINOVO_EDGE 0xc714 577#define USB_DEVICE_ID_DINOVO_EDGE 0xc714
572#define USB_DEVICE_ID_DINOVO_MINI 0xc71f 578#define USB_DEVICE_ID_DINOVO_MINI 0xc71f
573#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2 0xca03 579#define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2 0xca03
580#define USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL 0xca04
574 581
575#define USB_VENDOR_ID_LUMIO 0x202e 582#define USB_VENDOR_ID_LUMIO 0x202e
576#define USB_DEVICE_ID_CRYSTALTOUCH 0x0006 583#define USB_DEVICE_ID_CRYSTALTOUCH 0x0006
@@ -726,6 +733,9 @@
726#define USB_DEVICE_ID_ROCCAT_LUA 0x2c2e 733#define USB_DEVICE_ID_ROCCAT_LUA 0x2c2e
727#define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24 734#define USB_DEVICE_ID_ROCCAT_PYRA_WIRED 0x2c24
728#define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6 735#define USB_DEVICE_ID_ROCCAT_PYRA_WIRELESS 0x2cf6
736#define USB_DEVICE_ID_ROCCAT_RYOS_MK 0x3138
737#define USB_DEVICE_ID_ROCCAT_RYOS_MK_GLOW 0x31ce
738#define USB_DEVICE_ID_ROCCAT_RYOS_MK_PRO 0x3232
729#define USB_DEVICE_ID_ROCCAT_SAVU 0x2d5a 739#define USB_DEVICE_ID_ROCCAT_SAVU 0x2d5a
730 740
731#define USB_VENDOR_ID_SAITEK 0x06a3 741#define USB_VENDOR_ID_SAITEK 0x06a3
@@ -745,6 +755,10 @@
745#define USB_VENDOR_ID_SIGMATEL 0x066F 755#define USB_VENDOR_ID_SIGMATEL 0x066F
746#define USB_DEVICE_ID_SIGMATEL_STMP3780 0x3780 756#define USB_DEVICE_ID_SIGMATEL_STMP3780 0x3780
747 757
758#define USB_VENDOR_ID_SIS2_TOUCH 0x0457
759#define USB_DEVICE_ID_SIS9200_TOUCH 0x9200
760#define USB_DEVICE_ID_SIS817_TOUCH 0x0817
761
748#define USB_VENDOR_ID_SKYCABLE 0x1223 762#define USB_VENDOR_ID_SKYCABLE 0x1223
749#define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07 763#define USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER 0x3F07
750 764
diff --git a/drivers/hid/hid-lenovo-tpkbd.c b/drivers/hid/hid-lenovo-tpkbd.c
index 31cf29a6ba17..2d25b6cbbc05 100644
--- a/drivers/hid/hid-lenovo-tpkbd.c
+++ b/drivers/hid/hid-lenovo-tpkbd.c
@@ -14,11 +14,9 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/sysfs.h> 15#include <linux/sysfs.h>
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/usb.h>
18#include <linux/hid.h> 17#include <linux/hid.h>
19#include <linux/input.h> 18#include <linux/input.h>
20#include <linux/leds.h> 19#include <linux/leds.h>
21#include "usbhid/usbhid.h"
22 20
23#include "hid-ids.h" 21#include "hid-ids.h"
24 22
@@ -41,10 +39,9 @@ static int tpkbd_input_mapping(struct hid_device *hdev,
41 struct hid_input *hi, struct hid_field *field, 39 struct hid_input *hi, struct hid_field *field,
42 struct hid_usage *usage, unsigned long **bit, int *max) 40 struct hid_usage *usage, unsigned long **bit, int *max)
43{ 41{
44 struct usbhid_device *uhdev; 42 if (usage->hid == (HID_UP_BUTTON | 0x0010)) {
45 43 /* mark the device as pointer */
46 uhdev = (struct usbhid_device *) hdev->driver_data; 44 hid_set_drvdata(hdev, (void *)1);
47 if (uhdev->ifnum == 1 && usage->hid == (HID_UP_BUTTON | 0x0010)) {
48 map_key_clear(KEY_MICMUTE); 45 map_key_clear(KEY_MICMUTE);
49 return 1; 46 return 1;
50 } 47 }
@@ -339,7 +336,7 @@ static int tpkbd_probe_tp(struct hid_device *hdev)
339 struct tpkbd_data_pointer *data_pointer; 336 struct tpkbd_data_pointer *data_pointer;
340 size_t name_sz = strlen(dev_name(dev)) + 16; 337 size_t name_sz = strlen(dev_name(dev)) + 16;
341 char *name_mute, *name_micmute; 338 char *name_mute, *name_micmute;
342 int i, ret; 339 int i;
343 340
344 /* Validate required reports. */ 341 /* Validate required reports. */
345 for (i = 0; i < 4; i++) { 342 for (i = 0; i < 4; i++) {
@@ -354,7 +351,9 @@ static int tpkbd_probe_tp(struct hid_device *hdev)
354 hid_warn(hdev, "Could not create sysfs group\n"); 351 hid_warn(hdev, "Could not create sysfs group\n");
355 } 352 }
356 353
357 data_pointer = kzalloc(sizeof(struct tpkbd_data_pointer), GFP_KERNEL); 354 data_pointer = devm_kzalloc(&hdev->dev,
355 sizeof(struct tpkbd_data_pointer),
356 GFP_KERNEL);
358 if (data_pointer == NULL) { 357 if (data_pointer == NULL) {
359 hid_err(hdev, "Could not allocate memory for driver data\n"); 358 hid_err(hdev, "Could not allocate memory for driver data\n");
360 return -ENOMEM; 359 return -ENOMEM;
@@ -364,20 +363,13 @@ static int tpkbd_probe_tp(struct hid_device *hdev)
364 data_pointer->sensitivity = 0xa0; 363 data_pointer->sensitivity = 0xa0;
365 data_pointer->press_speed = 0x38; 364 data_pointer->press_speed = 0x38;
366 365
367 name_mute = kzalloc(name_sz, GFP_KERNEL); 366 name_mute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
368 if (name_mute == NULL) { 367 name_micmute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
368 if (name_mute == NULL || name_micmute == NULL) {
369 hid_err(hdev, "Could not allocate memory for led data\n"); 369 hid_err(hdev, "Could not allocate memory for led data\n");
370 ret = -ENOMEM; 370 return -ENOMEM;
371 goto err;
372 } 371 }
373 snprintf(name_mute, name_sz, "%s:amber:mute", dev_name(dev)); 372 snprintf(name_mute, name_sz, "%s:amber:mute", dev_name(dev));
374
375 name_micmute = kzalloc(name_sz, GFP_KERNEL);
376 if (name_micmute == NULL) {
377 hid_err(hdev, "Could not allocate memory for led data\n");
378 ret = -ENOMEM;
379 goto err2;
380 }
381 snprintf(name_micmute, name_sz, "%s:amber:micmute", dev_name(dev)); 373 snprintf(name_micmute, name_sz, "%s:amber:micmute", dev_name(dev));
382 374
383 hid_set_drvdata(hdev, data_pointer); 375 hid_set_drvdata(hdev, data_pointer);
@@ -397,19 +389,12 @@ static int tpkbd_probe_tp(struct hid_device *hdev)
397 tpkbd_features_set(hdev); 389 tpkbd_features_set(hdev);
398 390
399 return 0; 391 return 0;
400
401err2:
402 kfree(name_mute);
403err:
404 kfree(data_pointer);
405 return ret;
406} 392}
407 393
408static int tpkbd_probe(struct hid_device *hdev, 394static int tpkbd_probe(struct hid_device *hdev,
409 const struct hid_device_id *id) 395 const struct hid_device_id *id)
410{ 396{
411 int ret; 397 int ret;
412 struct usbhid_device *uhdev;
413 398
414 ret = hid_parse(hdev); 399 ret = hid_parse(hdev);
415 if (ret) { 400 if (ret) {
@@ -423,9 +408,8 @@ static int tpkbd_probe(struct hid_device *hdev,
423 goto err; 408 goto err;
424 } 409 }
425 410
426 uhdev = (struct usbhid_device *) hdev->driver_data; 411 if (hid_get_drvdata(hdev)) {
427 412 hid_set_drvdata(hdev, NULL);
428 if (uhdev->ifnum == 1) {
429 ret = tpkbd_probe_tp(hdev); 413 ret = tpkbd_probe_tp(hdev);
430 if (ret) 414 if (ret)
431 goto err_hid; 415 goto err_hid;
@@ -449,17 +433,11 @@ static void tpkbd_remove_tp(struct hid_device *hdev)
449 led_classdev_unregister(&data_pointer->led_mute); 433 led_classdev_unregister(&data_pointer->led_mute);
450 434
451 hid_set_drvdata(hdev, NULL); 435 hid_set_drvdata(hdev, NULL);
452 kfree(data_pointer->led_micmute.name);
453 kfree(data_pointer->led_mute.name);
454 kfree(data_pointer);
455} 436}
456 437
457static void tpkbd_remove(struct hid_device *hdev) 438static void tpkbd_remove(struct hid_device *hdev)
458{ 439{
459 struct usbhid_device *uhdev; 440 if (hid_get_drvdata(hdev))
460
461 uhdev = (struct usbhid_device *) hdev->driver_data;
462 if (uhdev->ifnum == 1)
463 tpkbd_remove_tp(hdev); 441 tpkbd_remove_tp(hdev);
464 442
465 hid_hw_stop(hdev); 443 hid_hw_stop(hdev);
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index 6f12ecd36c88..06eb45fa6331 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -45,7 +45,9 @@
45/* Size of the original descriptors of the Driving Force (and Pro) wheels */ 45/* Size of the original descriptors of the Driving Force (and Pro) wheels */
46#define DF_RDESC_ORIG_SIZE 130 46#define DF_RDESC_ORIG_SIZE 130
47#define DFP_RDESC_ORIG_SIZE 97 47#define DFP_RDESC_ORIG_SIZE 97
48#define FV_RDESC_ORIG_SIZE 130
48#define MOMO_RDESC_ORIG_SIZE 87 49#define MOMO_RDESC_ORIG_SIZE 87
50#define MOMO2_RDESC_ORIG_SIZE 87
49 51
50/* Fixed report descriptors for Logitech Driving Force (and Pro) 52/* Fixed report descriptors for Logitech Driving Force (and Pro)
51 * wheel controllers 53 * wheel controllers
@@ -170,6 +172,73 @@ static __u8 dfp_rdesc_fixed[] = {
1700xC0 /* End Collection */ 1720xC0 /* End Collection */
171}; 173};
172 174
175static __u8 fv_rdesc_fixed[] = {
1760x05, 0x01, /* Usage Page (Desktop), */
1770x09, 0x04, /* Usage (Joystik), */
1780xA1, 0x01, /* Collection (Application), */
1790xA1, 0x02, /* Collection (Logical), */
1800x95, 0x01, /* Report Count (1), */
1810x75, 0x0A, /* Report Size (10), */
1820x15, 0x00, /* Logical Minimum (0), */
1830x26, 0xFF, 0x03, /* Logical Maximum (1023), */
1840x35, 0x00, /* Physical Minimum (0), */
1850x46, 0xFF, 0x03, /* Physical Maximum (1023), */
1860x09, 0x30, /* Usage (X), */
1870x81, 0x02, /* Input (Variable), */
1880x95, 0x0C, /* Report Count (12), */
1890x75, 0x01, /* Report Size (1), */
1900x25, 0x01, /* Logical Maximum (1), */
1910x45, 0x01, /* Physical Maximum (1), */
1920x05, 0x09, /* Usage Page (Button), */
1930x19, 0x01, /* Usage Minimum (01h), */
1940x29, 0x0C, /* Usage Maximum (0Ch), */
1950x81, 0x02, /* Input (Variable), */
1960x95, 0x02, /* Report Count (2), */
1970x06, 0x00, 0xFF, /* Usage Page (FF00h), */
1980x09, 0x01, /* Usage (01h), */
1990x81, 0x02, /* Input (Variable), */
2000x09, 0x02, /* Usage (02h), */
2010x26, 0xFF, 0x00, /* Logical Maximum (255), */
2020x46, 0xFF, 0x00, /* Physical Maximum (255), */
2030x95, 0x01, /* Report Count (1), */
2040x75, 0x08, /* Report Size (8), */
2050x81, 0x02, /* Input (Variable), */
2060x05, 0x01, /* Usage Page (Desktop), */
2070x25, 0x07, /* Logical Maximum (7), */
2080x46, 0x3B, 0x01, /* Physical Maximum (315), */
2090x75, 0x04, /* Report Size (4), */
2100x65, 0x14, /* Unit (Degrees), */
2110x09, 0x39, /* Usage (Hat Switch), */
2120x81, 0x42, /* Input (Variable, Null State), */
2130x75, 0x01, /* Report Size (1), */
2140x95, 0x04, /* Report Count (4), */
2150x65, 0x00, /* Unit, */
2160x06, 0x00, 0xFF, /* Usage Page (FF00h), */
2170x09, 0x01, /* Usage (01h), */
2180x25, 0x01, /* Logical Maximum (1), */
2190x45, 0x01, /* Physical Maximum (1), */
2200x81, 0x02, /* Input (Variable), */
2210x05, 0x01, /* Usage Page (Desktop), */
2220x95, 0x01, /* Report Count (1), */
2230x75, 0x08, /* Report Size (8), */
2240x26, 0xFF, 0x00, /* Logical Maximum (255), */
2250x46, 0xFF, 0x00, /* Physical Maximum (255), */
2260x09, 0x31, /* Usage (Y), */
2270x81, 0x02, /* Input (Variable), */
2280x09, 0x32, /* Usage (Z), */
2290x81, 0x02, /* Input (Variable), */
2300xC0, /* End Collection, */
2310xA1, 0x02, /* Collection (Logical), */
2320x26, 0xFF, 0x00, /* Logical Maximum (255), */
2330x46, 0xFF, 0x00, /* Physical Maximum (255), */
2340x95, 0x07, /* Report Count (7), */
2350x75, 0x08, /* Report Size (8), */
2360x09, 0x03, /* Usage (03h), */
2370x91, 0x02, /* Output (Variable), */
2380xC0, /* End Collection, */
2390xC0 /* End Collection */
240};
241
173static __u8 momo_rdesc_fixed[] = { 242static __u8 momo_rdesc_fixed[] = {
1740x05, 0x01, /* Usage Page (Desktop), */ 2430x05, 0x01, /* Usage Page (Desktop), */
1750x09, 0x04, /* Usage (Joystik), */ 2440x09, 0x04, /* Usage (Joystik), */
@@ -216,6 +285,54 @@ static __u8 momo_rdesc_fixed[] = {
2160xC0 /* End Collection */ 2850xC0 /* End Collection */
217}; 286};
218 287
288static __u8 momo2_rdesc_fixed[] = {
2890x05, 0x01, /* Usage Page (Desktop), */
2900x09, 0x04, /* Usage (Joystik), */
2910xA1, 0x01, /* Collection (Application), */
2920xA1, 0x02, /* Collection (Logical), */
2930x95, 0x01, /* Report Count (1), */
2940x75, 0x0A, /* Report Size (10), */
2950x15, 0x00, /* Logical Minimum (0), */
2960x26, 0xFF, 0x03, /* Logical Maximum (1023), */
2970x35, 0x00, /* Physical Minimum (0), */
2980x46, 0xFF, 0x03, /* Physical Maximum (1023), */
2990x09, 0x30, /* Usage (X), */
3000x81, 0x02, /* Input (Variable), */
3010x95, 0x0A, /* Report Count (10), */
3020x75, 0x01, /* Report Size (1), */
3030x25, 0x01, /* Logical Maximum (1), */
3040x45, 0x01, /* Physical Maximum (1), */
3050x05, 0x09, /* Usage Page (Button), */
3060x19, 0x01, /* Usage Minimum (01h), */
3070x29, 0x0A, /* Usage Maximum (0Ah), */
3080x81, 0x02, /* Input (Variable), */
3090x06, 0x00, 0xFF, /* Usage Page (FF00h), */
3100x09, 0x00, /* Usage (00h), */
3110x95, 0x04, /* Report Count (4), */
3120x81, 0x02, /* Input (Variable), */
3130x95, 0x01, /* Report Count (1), */
3140x75, 0x08, /* Report Size (8), */
3150x26, 0xFF, 0x00, /* Logical Maximum (255), */
3160x46, 0xFF, 0x00, /* Physical Maximum (255), */
3170x09, 0x01, /* Usage (01h), */
3180x81, 0x02, /* Input (Variable), */
3190x05, 0x01, /* Usage Page (Desktop), */
3200x09, 0x31, /* Usage (Y), */
3210x81, 0x02, /* Input (Variable), */
3220x09, 0x32, /* Usage (Z), */
3230x81, 0x02, /* Input (Variable), */
3240x06, 0x00, 0xFF, /* Usage Page (FF00h), */
3250x09, 0x00, /* Usage (00h), */
3260x81, 0x02, /* Input (Variable), */
3270xC0, /* End Collection, */
3280xA1, 0x02, /* Collection (Logical), */
3290x09, 0x02, /* Usage (02h), */
3300x95, 0x07, /* Report Count (7), */
3310x91, 0x02, /* Output (Variable), */
3320xC0, /* End Collection, */
3330xC0 /* End Collection */
334};
335
219/* 336/*
220 * Certain Logitech keyboards send in report #3 keys which are far 337 * Certain Logitech keyboards send in report #3 keys which are far
221 * above the logical maximum described in descriptor. This extends 338 * above the logical maximum described in descriptor. This extends
@@ -275,6 +392,24 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc,
275 } 392 }
276 break; 393 break;
277 394
395 case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2:
396 if (*rsize == MOMO2_RDESC_ORIG_SIZE) {
397 hid_info(hdev,
398 "fixing up Logitech Momo Racing Force (Black) report descriptor\n");
399 rdesc = momo2_rdesc_fixed;
400 *rsize = sizeof(momo2_rdesc_fixed);
401 }
402 break;
403
404 case USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL:
405 if (*rsize == FV_RDESC_ORIG_SIZE) {
406 hid_info(hdev,
407 "fixing up Logitech Formula Vibration report descriptor\n");
408 rdesc = fv_rdesc_fixed;
409 *rsize = sizeof(fv_rdesc_fixed);
410 }
411 break;
412
278 case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: 413 case USB_DEVICE_ID_LOGITECH_DFP_WHEEL:
279 if (*rsize == DFP_RDESC_ORIG_SIZE) { 414 if (*rsize == DFP_RDESC_ORIG_SIZE) {
280 hid_info(hdev, 415 hid_info(hdev,
@@ -492,6 +627,7 @@ static int lg_input_mapped(struct hid_device *hdev, struct hid_input *hi,
492 case USB_DEVICE_ID_LOGITECH_G27_WHEEL: 627 case USB_DEVICE_ID_LOGITECH_G27_WHEEL:
493 case USB_DEVICE_ID_LOGITECH_WII_WHEEL: 628 case USB_DEVICE_ID_LOGITECH_WII_WHEEL:
494 case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2: 629 case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2:
630 case USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL:
495 field->application = HID_GD_MULTIAXIS; 631 field->application = HID_GD_MULTIAXIS;
496 break; 632 break;
497 default: 633 default:
@@ -639,6 +775,8 @@ static const struct hid_device_id lg_devices[] = {
639 .driver_data = LG_NOGET | LG_FF4 }, 775 .driver_data = LG_NOGET | LG_FF4 },
640 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2), 776 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2),
641 .driver_data = LG_FF4 }, 777 .driver_data = LG_FF4 },
778 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_VIBRATION_WHEEL),
779 .driver_data = LG_FF2 },
642 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL), 780 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL),
643 .driver_data = LG_FF4 }, 781 .driver_data = LG_FF4 },
644 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL), 782 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFGT_WHEEL),
diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c
index 1a42eaa6ca02..0e3fb1a7e421 100644
--- a/drivers/hid/hid-lg2ff.c
+++ b/drivers/hid/hid-lg2ff.c
@@ -95,7 +95,7 @@ int lg2ff_init(struct hid_device *hid)
95 95
96 hid_hw_request(hid, report, HID_REQ_SET_REPORT); 96 hid_hw_request(hid, report, HID_REQ_SET_REPORT);
97 97
98 hid_info(hid, "Force feedback for Logitech RumblePad/Rumblepad 2 by Anssi Hannula <anssi.hannula@gmail.com>\n"); 98 hid_info(hid, "Force feedback for Logitech variant 2 rumble devices by Anssi Hannula <anssi.hannula@gmail.com>\n");
99 99
100 return 0; 100 return 0;
101} 101}
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c
index 8782fe1aaa07..befe0e336471 100644
--- a/drivers/hid/hid-lg4ff.c
+++ b/drivers/hid/hid-lg4ff.c
@@ -196,6 +196,21 @@ static int hid_lg4ff_play(struct input_dev *dev, void *data, struct ff_effect *e
196 case FF_CONSTANT: 196 case FF_CONSTANT:
197 x = effect->u.ramp.start_level + 0x80; /* 0x80 is no force */ 197 x = effect->u.ramp.start_level + 0x80; /* 0x80 is no force */
198 CLAMP(x); 198 CLAMP(x);
199
200 if (x == 0x80) {
201 /* De-activate force in slot-1*/
202 value[0] = 0x13;
203 value[1] = 0x00;
204 value[2] = 0x00;
205 value[3] = 0x00;
206 value[4] = 0x00;
207 value[5] = 0x00;
208 value[6] = 0x00;
209
210 hid_hw_request(hid, report, HID_REQ_SET_REPORT);
211 return 0;
212 }
213
199 value[0] = 0x11; /* Slot 1 */ 214 value[0] = 0x11; /* Slot 1 */
200 value[1] = 0x08; 215 value[1] = 0x08;
201 value[2] = x; 216 value[2] = x;
@@ -218,12 +233,70 @@ static void hid_lg4ff_set_autocenter_default(struct input_dev *dev, u16 magnitud
218 struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list; 233 struct list_head *report_list = &hid->report_enum[HID_OUTPUT_REPORT].report_list;
219 struct hid_report *report = list_entry(report_list->next, struct hid_report, list); 234 struct hid_report *report = list_entry(report_list->next, struct hid_report, list);
220 __s32 *value = report->field[0]->value; 235 __s32 *value = report->field[0]->value;
236 __u32 expand_a, expand_b;
237 struct lg4ff_device_entry *entry;
238 struct lg_drv_data *drv_data;
239
240 drv_data = hid_get_drvdata(hid);
241 if (!drv_data) {
242 hid_err(hid, "Private driver data not found!\n");
243 return;
244 }
245
246 entry = drv_data->device_props;
247 if (!entry) {
248 hid_err(hid, "Device properties not found!\n");
249 return;
250 }
251
252 /* De-activate Auto-Center */
253 if (magnitude == 0) {
254 value[0] = 0xf5;
255 value[1] = 0x00;
256 value[2] = 0x00;
257 value[3] = 0x00;
258 value[4] = 0x00;
259 value[5] = 0x00;
260 value[6] = 0x00;
261
262 hid_hw_request(hid, report, HID_REQ_SET_REPORT);
263 return;
264 }
265
266 if (magnitude <= 0xaaaa) {
267 expand_a = 0x0c * magnitude;
268 expand_b = 0x80 * magnitude;
269 } else {
270 expand_a = (0x0c * 0xaaaa) + 0x06 * (magnitude - 0xaaaa);
271 expand_b = (0x80 * 0xaaaa) + 0xff * (magnitude - 0xaaaa);
272 }
273
274 /* Adjust for non-MOMO wheels */
275 switch (entry->product_id) {
276 case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL:
277 case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2:
278 break;
279 default:
280 expand_a = expand_a >> 1;
281 break;
282 }
221 283
222 value[0] = 0xfe; 284 value[0] = 0xfe;
223 value[1] = 0x0d; 285 value[1] = 0x0d;
224 value[2] = magnitude >> 13; 286 value[2] = expand_a / 0xaaaa;
225 value[3] = magnitude >> 13; 287 value[3] = expand_a / 0xaaaa;
226 value[4] = magnitude >> 8; 288 value[4] = expand_b / 0xaaaa;
289 value[5] = 0x00;
290 value[6] = 0x00;
291
292 hid_hw_request(hid, report, HID_REQ_SET_REPORT);
293
294 /* Activate Auto-Center */
295 value[0] = 0x14;
296 value[1] = 0x00;
297 value[2] = 0x00;
298 value[3] = 0x00;
299 value[4] = 0x00;
227 value[5] = 0x00; 300 value[5] = 0x00;
228 value[6] = 0x00; 301 value[6] = 0x00;
229 302
@@ -540,17 +613,6 @@ int lg4ff_init(struct hid_device *hid)
540 if (error) 613 if (error)
541 return error; 614 return error;
542 615
543 /* Check if autocentering is available and
544 * set the centering force to zero by default */
545 if (test_bit(FF_AUTOCENTER, dev->ffbit)) {
546 if (rev_maj == FFEX_REV_MAJ && rev_min == FFEX_REV_MIN) /* Formula Force EX expects different autocentering command */
547 dev->ff->set_autocenter = hid_lg4ff_set_autocenter_ffex;
548 else
549 dev->ff->set_autocenter = hid_lg4ff_set_autocenter_default;
550
551 dev->ff->set_autocenter(dev, 0);
552 }
553
554 /* Get private driver data */ 616 /* Get private driver data */
555 drv_data = hid_get_drvdata(hid); 617 drv_data = hid_get_drvdata(hid);
556 if (!drv_data) { 618 if (!drv_data) {
@@ -571,6 +633,17 @@ int lg4ff_init(struct hid_device *hid)
571 entry->max_range = lg4ff_devices[i].max_range; 633 entry->max_range = lg4ff_devices[i].max_range;
572 entry->set_range = lg4ff_devices[i].set_range; 634 entry->set_range = lg4ff_devices[i].set_range;
573 635
636 /* Check if autocentering is available and
637 * set the centering force to zero by default */
638 if (test_bit(FF_AUTOCENTER, dev->ffbit)) {
639 if (rev_maj == FFEX_REV_MAJ && rev_min == FFEX_REV_MIN) /* Formula Force EX expects different autocentering command */
640 dev->ff->set_autocenter = hid_lg4ff_set_autocenter_ffex;
641 else
642 dev->ff->set_autocenter = hid_lg4ff_set_autocenter_default;
643
644 dev->ff->set_autocenter(dev, 0);
645 }
646
574 /* Create sysfs interface */ 647 /* Create sysfs interface */
575 error = device_create_file(&hid->dev, &dev_attr_range); 648 error = device_create_file(&hid->dev, &dev_attr_range);
576 if (error) 649 if (error)
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
index 2e5302462efb..a7947d8251a8 100644
--- a/drivers/hid/hid-logitech-dj.c
+++ b/drivers/hid/hid-logitech-dj.c
@@ -542,9 +542,9 @@ static int logi_dj_output_hidraw_report(struct hid_device *hid, u8 * buf,
542 return 0; 542 return 0;
543} 543}
544 544
545static void rdcat(char **rdesc, unsigned int *rsize, const char *data, unsigned int size) 545static void rdcat(char *rdesc, unsigned int *rsize, const char *data, unsigned int size)
546{ 546{
547 memcpy(*rdesc + *rsize, data, size); 547 memcpy(rdesc + *rsize, data, size);
548 *rsize += size; 548 *rsize += size;
549} 549}
550 550
@@ -567,31 +567,31 @@ static int logi_dj_ll_parse(struct hid_device *hid)
567 if (djdev->reports_supported & STD_KEYBOARD) { 567 if (djdev->reports_supported & STD_KEYBOARD) {
568 dbg_hid("%s: sending a kbd descriptor, reports_supported: %x\n", 568 dbg_hid("%s: sending a kbd descriptor, reports_supported: %x\n",
569 __func__, djdev->reports_supported); 569 __func__, djdev->reports_supported);
570 rdcat(&rdesc, &rsize, kbd_descriptor, sizeof(kbd_descriptor)); 570 rdcat(rdesc, &rsize, kbd_descriptor, sizeof(kbd_descriptor));
571 } 571 }
572 572
573 if (djdev->reports_supported & STD_MOUSE) { 573 if (djdev->reports_supported & STD_MOUSE) {
574 dbg_hid("%s: sending a mouse descriptor, reports_supported: " 574 dbg_hid("%s: sending a mouse descriptor, reports_supported: "
575 "%x\n", __func__, djdev->reports_supported); 575 "%x\n", __func__, djdev->reports_supported);
576 rdcat(&rdesc, &rsize, mse_descriptor, sizeof(mse_descriptor)); 576 rdcat(rdesc, &rsize, mse_descriptor, sizeof(mse_descriptor));
577 } 577 }
578 578
579 if (djdev->reports_supported & MULTIMEDIA) { 579 if (djdev->reports_supported & MULTIMEDIA) {
580 dbg_hid("%s: sending a multimedia report descriptor: %x\n", 580 dbg_hid("%s: sending a multimedia report descriptor: %x\n",
581 __func__, djdev->reports_supported); 581 __func__, djdev->reports_supported);
582 rdcat(&rdesc, &rsize, consumer_descriptor, sizeof(consumer_descriptor)); 582 rdcat(rdesc, &rsize, consumer_descriptor, sizeof(consumer_descriptor));
583 } 583 }
584 584
585 if (djdev->reports_supported & POWER_KEYS) { 585 if (djdev->reports_supported & POWER_KEYS) {
586 dbg_hid("%s: sending a power keys report descriptor: %x\n", 586 dbg_hid("%s: sending a power keys report descriptor: %x\n",
587 __func__, djdev->reports_supported); 587 __func__, djdev->reports_supported);
588 rdcat(&rdesc, &rsize, syscontrol_descriptor, sizeof(syscontrol_descriptor)); 588 rdcat(rdesc, &rsize, syscontrol_descriptor, sizeof(syscontrol_descriptor));
589 } 589 }
590 590
591 if (djdev->reports_supported & MEDIA_CENTER) { 591 if (djdev->reports_supported & MEDIA_CENTER) {
592 dbg_hid("%s: sending a media center report descriptor: %x\n", 592 dbg_hid("%s: sending a media center report descriptor: %x\n",
593 __func__, djdev->reports_supported); 593 __func__, djdev->reports_supported);
594 rdcat(&rdesc, &rsize, media_descriptor, sizeof(media_descriptor)); 594 rdcat(rdesc, &rsize, media_descriptor, sizeof(media_descriptor));
595 } 595 }
596 596
597 if (djdev->reports_supported & KBD_LEDS) { 597 if (djdev->reports_supported & KBD_LEDS) {
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 5e5fe1b8eebb..a2cedb8ae1c0 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -250,12 +250,12 @@ static struct mt_class mt_classes[] = {
250 { .name = MT_CLS_GENERALTOUCH_TWOFINGERS, 250 { .name = MT_CLS_GENERALTOUCH_TWOFINGERS,
251 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | 251 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
252 MT_QUIRK_VALID_IS_INRANGE | 252 MT_QUIRK_VALID_IS_INRANGE |
253 MT_QUIRK_SLOT_IS_CONTACTNUMBER, 253 MT_QUIRK_SLOT_IS_CONTACTID,
254 .maxcontacts = 2 254 .maxcontacts = 2
255 }, 255 },
256 { .name = MT_CLS_GENERALTOUCH_PWT_TENFINGERS, 256 { .name = MT_CLS_GENERALTOUCH_PWT_TENFINGERS,
257 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP | 257 .quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
258 MT_QUIRK_SLOT_IS_CONTACTNUMBER 258 MT_QUIRK_SLOT_IS_CONTACTID
259 }, 259 },
260 260
261 { .name = MT_CLS_FLATFROG, 261 { .name = MT_CLS_FLATFROG,
@@ -1173,6 +1173,21 @@ static const struct hid_device_id mt_devices[] = {
1173 { .driver_data = MT_CLS_GENERALTOUCH_PWT_TENFINGERS, 1173 { .driver_data = MT_CLS_GENERALTOUCH_PWT_TENFINGERS,
1174 MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 1174 MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
1175 USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PWT_TENFINGERS) }, 1175 USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PWT_TENFINGERS) },
1176 { .driver_data = MT_CLS_GENERALTOUCH_TWOFINGERS,
1177 MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
1178 USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_0101) },
1179 { .driver_data = MT_CLS_GENERALTOUCH_PWT_TENFINGERS,
1180 MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
1181 USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_0102) },
1182 { .driver_data = MT_CLS_GENERALTOUCH_PWT_TENFINGERS,
1183 MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
1184 USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_0106) },
1185 { .driver_data = MT_CLS_GENERALTOUCH_PWT_TENFINGERS,
1186 MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
1187 USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_010A) },
1188 { .driver_data = MT_CLS_GENERALTOUCH_PWT_TENFINGERS,
1189 MT_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
1190 USB_DEVICE_ID_GENERAL_TOUCH_WIN8_PIT_E100) },
1176 1191
1177 /* Gametel game controller */ 1192 /* Gametel game controller */
1178 { .driver_data = MT_CLS_NSMU, 1193 { .driver_data = MT_CLS_NSMU,
@@ -1284,6 +1299,14 @@ static const struct hid_device_id mt_devices[] = {
1284 MT_USB_DEVICE(USB_VENDOR_ID_QUANTA, 1299 MT_USB_DEVICE(USB_VENDOR_ID_QUANTA,
1285 USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008) }, 1300 USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008) },
1286 1301
1302 /* SiS panels */
1303 { .driver_data = MT_CLS_DEFAULT,
1304 HID_USB_DEVICE(USB_VENDOR_ID_SIS2_TOUCH,
1305 USB_DEVICE_ID_SIS9200_TOUCH) },
1306 { .driver_data = MT_CLS_DEFAULT,
1307 HID_USB_DEVICE(USB_VENDOR_ID_SIS2_TOUCH,
1308 USB_DEVICE_ID_SIS817_TOUCH) },
1309
1287 /* Stantum panels */ 1310 /* Stantum panels */
1288 { .driver_data = MT_CLS_CONFIDENCE, 1311 { .driver_data = MT_CLS_CONFIDENCE,
1289 MT_USB_DEVICE(USB_VENDOR_ID_STANTUM, 1312 MT_USB_DEVICE(USB_VENDOR_ID_STANTUM,
diff --git a/drivers/hid/hid-roccat-common.c b/drivers/hid/hid-roccat-common.c
index 74f704032627..02e28e9f4ea7 100644
--- a/drivers/hid/hid-roccat-common.c
+++ b/drivers/hid/hid-roccat-common.c
@@ -65,10 +65,11 @@ int roccat_common2_send(struct usb_device *usb_dev, uint report_id,
65EXPORT_SYMBOL_GPL(roccat_common2_send); 65EXPORT_SYMBOL_GPL(roccat_common2_send);
66 66
67enum roccat_common2_control_states { 67enum roccat_common2_control_states {
68 ROCCAT_COMMON_CONTROL_STATUS_OVERLOAD = 0, 68 ROCCAT_COMMON_CONTROL_STATUS_CRITICAL = 0,
69 ROCCAT_COMMON_CONTROL_STATUS_OK = 1, 69 ROCCAT_COMMON_CONTROL_STATUS_OK = 1,
70 ROCCAT_COMMON_CONTROL_STATUS_INVALID = 2, 70 ROCCAT_COMMON_CONTROL_STATUS_INVALID = 2,
71 ROCCAT_COMMON_CONTROL_STATUS_WAIT = 3, 71 ROCCAT_COMMON_CONTROL_STATUS_BUSY = 3,
72 ROCCAT_COMMON_CONTROL_STATUS_CRITICAL_NEW = 4,
72}; 73};
73 74
74static int roccat_common2_receive_control_status(struct usb_device *usb_dev) 75static int roccat_common2_receive_control_status(struct usb_device *usb_dev)
@@ -88,13 +89,12 @@ static int roccat_common2_receive_control_status(struct usb_device *usb_dev)
88 switch (control.value) { 89 switch (control.value) {
89 case ROCCAT_COMMON_CONTROL_STATUS_OK: 90 case ROCCAT_COMMON_CONTROL_STATUS_OK:
90 return 0; 91 return 0;
91 case ROCCAT_COMMON_CONTROL_STATUS_WAIT: 92 case ROCCAT_COMMON_CONTROL_STATUS_BUSY:
92 msleep(500); 93 msleep(500);
93 continue; 94 continue;
94 case ROCCAT_COMMON_CONTROL_STATUS_INVALID: 95 case ROCCAT_COMMON_CONTROL_STATUS_INVALID:
95 96 case ROCCAT_COMMON_CONTROL_STATUS_CRITICAL:
96 case ROCCAT_COMMON_CONTROL_STATUS_OVERLOAD: 97 case ROCCAT_COMMON_CONTROL_STATUS_CRITICAL_NEW:
97 /* seems to be critical - replug necessary */
98 return -EINVAL; 98 return -EINVAL;
99 default: 99 default:
100 dev_err(&usb_dev->dev, 100 dev_err(&usb_dev->dev,
@@ -122,6 +122,59 @@ int roccat_common2_send_with_status(struct usb_device *usb_dev,
122} 122}
123EXPORT_SYMBOL_GPL(roccat_common2_send_with_status); 123EXPORT_SYMBOL_GPL(roccat_common2_send_with_status);
124 124
125int roccat_common2_device_init_struct(struct usb_device *usb_dev,
126 struct roccat_common2_device *dev)
127{
128 mutex_init(&dev->lock);
129 return 0;
130}
131EXPORT_SYMBOL_GPL(roccat_common2_device_init_struct);
132
133ssize_t roccat_common2_sysfs_read(struct file *fp, struct kobject *kobj,
134 char *buf, loff_t off, size_t count,
135 size_t real_size, uint command)
136{
137 struct device *dev =
138 container_of(kobj, struct device, kobj)->parent->parent;
139 struct roccat_common2_device *roccat_dev = hid_get_drvdata(dev_get_drvdata(dev));
140 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
141 int retval;
142
143 if (off >= real_size)
144 return 0;
145
146 if (off != 0 || count != real_size)
147 return -EINVAL;
148
149 mutex_lock(&roccat_dev->lock);
150 retval = roccat_common2_receive(usb_dev, command, buf, real_size);
151 mutex_unlock(&roccat_dev->lock);
152
153 return retval ? retval : real_size;
154}
155EXPORT_SYMBOL_GPL(roccat_common2_sysfs_read);
156
157ssize_t roccat_common2_sysfs_write(struct file *fp, struct kobject *kobj,
158 void const *buf, loff_t off, size_t count,
159 size_t real_size, uint command)
160{
161 struct device *dev =
162 container_of(kobj, struct device, kobj)->parent->parent;
163 struct roccat_common2_device *roccat_dev = hid_get_drvdata(dev_get_drvdata(dev));
164 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev));
165 int retval;
166
167 if (off != 0 || count != real_size)
168 return -EINVAL;
169
170 mutex_lock(&roccat_dev->lock);
171 retval = roccat_common2_send_with_status(usb_dev, command, buf, real_size);
172 mutex_unlock(&roccat_dev->lock);
173
174 return retval ? retval : real_size;
175}
176EXPORT_SYMBOL_GPL(roccat_common2_sysfs_write);
177
125MODULE_AUTHOR("Stefan Achatz"); 178MODULE_AUTHOR("Stefan Achatz");
126MODULE_DESCRIPTION("USB Roccat common driver"); 179MODULE_DESCRIPTION("USB Roccat common driver");
127MODULE_LICENSE("GPL v2"); 180MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-roccat-common.h b/drivers/hid/hid-roccat-common.h
index a97746a63b70..eaa56eb7d5d1 100644
--- a/drivers/hid/hid-roccat-common.h
+++ b/drivers/hid/hid-roccat-common.h
@@ -32,4 +32,66 @@ int roccat_common2_send(struct usb_device *usb_dev, uint report_id,
32int roccat_common2_send_with_status(struct usb_device *usb_dev, 32int roccat_common2_send_with_status(struct usb_device *usb_dev,
33 uint command, void const *buf, uint size); 33 uint command, void const *buf, uint size);
34 34
35struct roccat_common2_device {
36 int roccat_claimed;
37 int chrdev_minor;
38 struct mutex lock;
39};
40
41int roccat_common2_device_init_struct(struct usb_device *usb_dev,
42 struct roccat_common2_device *dev);
43ssize_t roccat_common2_sysfs_read(struct file *fp, struct kobject *kobj,
44 char *buf, loff_t off, size_t count,
45 size_t real_size, uint command);
46ssize_t roccat_common2_sysfs_write(struct file *fp, struct kobject *kobj,
47 void const *buf, loff_t off, size_t count,
48 size_t real_size, uint command);
49
50#define ROCCAT_COMMON2_SYSFS_W(thingy, COMMAND, SIZE) \
51static ssize_t roccat_common2_sysfs_write_ ## thingy(struct file *fp, \
52 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
53 loff_t off, size_t count) \
54{ \
55 return roccat_common2_sysfs_write(fp, kobj, buf, off, count, \
56 SIZE, COMMAND); \
57}
58
59#define ROCCAT_COMMON2_SYSFS_R(thingy, COMMAND, SIZE) \
60static ssize_t roccat_common2_sysfs_read_ ## thingy(struct file *fp, \
61 struct kobject *kobj, struct bin_attribute *attr, char *buf, \
62 loff_t off, size_t count) \
63{ \
64 return roccat_common2_sysfs_read(fp, kobj, buf, off, count, \
65 SIZE, COMMAND); \
66}
67
68#define ROCCAT_COMMON2_SYSFS_RW(thingy, COMMAND, SIZE) \
69ROCCAT_COMMON2_SYSFS_W(thingy, COMMAND, SIZE) \
70ROCCAT_COMMON2_SYSFS_R(thingy, COMMAND, SIZE)
71
72#define ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(thingy, COMMAND, SIZE) \
73ROCCAT_COMMON2_SYSFS_RW(thingy, COMMAND, SIZE); \
74static struct bin_attribute bin_attr_ ## thingy = { \
75 .attr = { .name = #thingy, .mode = 0660 }, \
76 .size = SIZE, \
77 .read = roccat_common2_sysfs_read_ ## thingy, \
78 .write = roccat_common2_sysfs_write_ ## thingy \
79}
80
81#define ROCCAT_COMMON2_BIN_ATTRIBUTE_R(thingy, COMMAND, SIZE) \
82ROCCAT_COMMON2_SYSFS_R(thingy, COMMAND, SIZE); \
83static struct bin_attribute bin_attr_ ## thingy = { \
84 .attr = { .name = #thingy, .mode = 0440 }, \
85 .size = SIZE, \
86 .read = roccat_common2_sysfs_read_ ## thingy, \
87}
88
89#define ROCCAT_COMMON2_BIN_ATTRIBUTE_W(thingy, COMMAND, SIZE) \
90ROCCAT_COMMON2_SYSFS_W(thingy, COMMAND, SIZE); \
91static struct bin_attribute bin_attr_ ## thingy = { \
92 .attr = { .name = #thingy, .mode = 0220 }, \
93 .size = SIZE, \
94 .write = roccat_common2_sysfs_write_ ## thingy \
95}
96
35#endif 97#endif
diff --git a/drivers/hid/hid-roccat-konepure.c b/drivers/hid/hid-roccat-konepure.c
index 99a605ebb665..07de2f9014c6 100644
--- a/drivers/hid/hid-roccat-konepure.c
+++ b/drivers/hid/hid-roccat-konepure.c
@@ -15,6 +15,7 @@
15 * Roccat KonePure is a smaller version of KoneXTD with less buttons and lights. 15 * Roccat KonePure is a smaller version of KoneXTD with less buttons and lights.
16 */ 16 */
17 17
18#include <linux/types.h>
18#include <linux/device.h> 19#include <linux/device.h>
19#include <linux/input.h> 20#include <linux/input.h>
20#include <linux/hid.h> 21#include <linux/hid.h>
@@ -23,128 +24,50 @@
23#include <linux/hid-roccat.h> 24#include <linux/hid-roccat.h>
24#include "hid-ids.h" 25#include "hid-ids.h"
25#include "hid-roccat-common.h" 26#include "hid-roccat-common.h"
26#include "hid-roccat-konepure.h"
27 27
28static struct class *konepure_class; 28enum {
29 29 KONEPURE_MOUSE_REPORT_NUMBER_BUTTON = 3,
30static ssize_t konepure_sysfs_read(struct file *fp, struct kobject *kobj, 30};
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 konepure_device *konepure = 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(&konepure->konepure_lock);
47 retval = roccat_common2_receive(usb_dev, command, buf, real_size);
48 mutex_unlock(&konepure->konepure_lock);
49
50 return retval ? retval : real_size;
51}
52
53static ssize_t konepure_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 konepure_device *konepure = 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(&konepure->konepure_lock);
67 retval = roccat_common2_send_with_status(usb_dev, command,
68 (void *)buf, real_size);
69 mutex_unlock(&konepure->konepure_lock);
70
71 return retval ? retval : real_size;
72}
73
74#define KONEPURE_SYSFS_W(thingy, THINGY) \
75static ssize_t konepure_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 konepure_sysfs_write(fp, kobj, buf, off, count, \
80 KONEPURE_SIZE_ ## THINGY, KONEPURE_COMMAND_ ## THINGY); \
81}
82
83#define KONEPURE_SYSFS_R(thingy, THINGY) \
84static ssize_t konepure_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 konepure_sysfs_read(fp, kobj, buf, off, count, \
89 KONEPURE_SIZE_ ## THINGY, KONEPURE_COMMAND_ ## THINGY); \
90}
91 31
92#define KONEPURE_SYSFS_RW(thingy, THINGY) \ 32struct konepure_mouse_report_button {
93KONEPURE_SYSFS_W(thingy, THINGY) \ 33 uint8_t report_number; /* always KONEPURE_MOUSE_REPORT_NUMBER_BUTTON */
94KONEPURE_SYSFS_R(thingy, THINGY) 34 uint8_t zero;
95 35 uint8_t type;
96#define KONEPURE_BIN_ATTRIBUTE_RW(thingy, THINGY) \ 36 uint8_t data1;
97KONEPURE_SYSFS_RW(thingy, THINGY); \ 37 uint8_t data2;
98static struct bin_attribute bin_attr_##thingy = { \ 38 uint8_t zero2;
99 .attr = { .name = #thingy, .mode = 0660 }, \ 39 uint8_t unknown[2];
100 .size = KONEPURE_SIZE_ ## THINGY, \ 40} __packed;
101 .read = konepure_sysfs_read_ ## thingy, \
102 .write = konepure_sysfs_write_ ## thingy \
103}
104 41
105#define KONEPURE_BIN_ATTRIBUTE_R(thingy, THINGY) \ 42static struct class *konepure_class;
106KONEPURE_SYSFS_R(thingy, THINGY); \
107static struct bin_attribute bin_attr_##thingy = { \
108 .attr = { .name = #thingy, .mode = 0440 }, \
109 .size = KONEPURE_SIZE_ ## THINGY, \
110 .read = konepure_sysfs_read_ ## thingy, \
111}
112
113#define KONEPURE_BIN_ATTRIBUTE_W(thingy, THINGY) \
114KONEPURE_SYSFS_W(thingy, THINGY); \
115static struct bin_attribute bin_attr_##thingy = { \
116 .attr = { .name = #thingy, .mode = 0220 }, \
117 .size = KONEPURE_SIZE_ ## THINGY, \
118 .write = konepure_sysfs_write_ ## thingy \
119}
120 43
121KONEPURE_BIN_ATTRIBUTE_RW(actual_profile, ACTUAL_PROFILE); 44ROCCAT_COMMON2_BIN_ATTRIBUTE_W(control, 0x04, 0x03);
122KONEPURE_BIN_ATTRIBUTE_RW(info, INFO); 45ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(actual_profile, 0x05, 0x03);
123KONEPURE_BIN_ATTRIBUTE_RW(sensor, SENSOR); 46ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(profile_settings, 0x06, 0x1f);
124KONEPURE_BIN_ATTRIBUTE_RW(tcu, TCU); 47ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(profile_buttons, 0x07, 0x3b);
125KONEPURE_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS); 48ROCCAT_COMMON2_BIN_ATTRIBUTE_W(macro, 0x08, 0x0822);
126KONEPURE_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS); 49ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(info, 0x09, 0x06);
127KONEPURE_BIN_ATTRIBUTE_W(control, CONTROL); 50ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(tcu, 0x0c, 0x04);
128KONEPURE_BIN_ATTRIBUTE_W(talk, TALK); 51ROCCAT_COMMON2_BIN_ATTRIBUTE_R(tcu_image, 0x0c, 0x0404);
129KONEPURE_BIN_ATTRIBUTE_W(macro, MACRO); 52ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(sensor, 0x0f, 0x06);
130KONEPURE_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE); 53ROCCAT_COMMON2_BIN_ATTRIBUTE_W(talk, 0x10, 0x10);
131 54
132static struct bin_attribute *konepure_bin_attributes[] = { 55static struct bin_attribute *konepure_bin_attrs[] = {
133 &bin_attr_actual_profile, 56 &bin_attr_actual_profile,
57 &bin_attr_control,
134 &bin_attr_info, 58 &bin_attr_info,
59 &bin_attr_talk,
60 &bin_attr_macro,
135 &bin_attr_sensor, 61 &bin_attr_sensor,
136 &bin_attr_tcu, 62 &bin_attr_tcu,
63 &bin_attr_tcu_image,
137 &bin_attr_profile_settings, 64 &bin_attr_profile_settings,
138 &bin_attr_profile_buttons, 65 &bin_attr_profile_buttons,
139 &bin_attr_control,
140 &bin_attr_talk,
141 &bin_attr_macro,
142 &bin_attr_tcu_image,
143 NULL, 66 NULL,
144}; 67};
145 68
146static const struct attribute_group konepure_group = { 69static const struct attribute_group konepure_group = {
147 .bin_attrs = konepure_bin_attributes, 70 .bin_attrs = konepure_bin_attrs,
148}; 71};
149 72
150static const struct attribute_group *konepure_groups[] = { 73static const struct attribute_group *konepure_groups[] = {
@@ -152,20 +75,11 @@ static const struct attribute_group *konepure_groups[] = {
152 NULL, 75 NULL,
153}; 76};
154 77
155
156static int konepure_init_konepure_device_struct(struct usb_device *usb_dev,
157 struct konepure_device *konepure)
158{
159 mutex_init(&konepure->konepure_lock);
160
161 return 0;
162}
163
164static int konepure_init_specials(struct hid_device *hdev) 78static int konepure_init_specials(struct hid_device *hdev)
165{ 79{
166 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 80 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
167 struct usb_device *usb_dev = interface_to_usbdev(intf); 81 struct usb_device *usb_dev = interface_to_usbdev(intf);
168 struct konepure_device *konepure; 82 struct roccat_common2_device *konepure;
169 int retval; 83 int retval;
170 84
171 if (intf->cur_altsetting->desc.bInterfaceProtocol 85 if (intf->cur_altsetting->desc.bInterfaceProtocol
@@ -181,9 +95,9 @@ static int konepure_init_specials(struct hid_device *hdev)
181 } 95 }
182 hid_set_drvdata(hdev, konepure); 96 hid_set_drvdata(hdev, konepure);
183 97
184 retval = konepure_init_konepure_device_struct(usb_dev, konepure); 98 retval = roccat_common2_device_init_struct(usb_dev, konepure);
185 if (retval) { 99 if (retval) {
186 hid_err(hdev, "couldn't init struct konepure_device\n"); 100 hid_err(hdev, "couldn't init KonePure device\n");
187 goto exit_free; 101 goto exit_free;
188 } 102 }
189 103
@@ -205,7 +119,7 @@ exit_free:
205static void konepure_remove_specials(struct hid_device *hdev) 119static void konepure_remove_specials(struct hid_device *hdev)
206{ 120{
207 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 121 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
208 struct konepure_device *konepure; 122 struct roccat_common2_device *konepure;
209 123
210 if (intf->cur_altsetting->desc.bInterfaceProtocol 124 if (intf->cur_altsetting->desc.bInterfaceProtocol
211 != USB_INTERFACE_PROTOCOL_MOUSE) 125 != USB_INTERFACE_PROTOCOL_MOUSE)
@@ -258,7 +172,7 @@ static int konepure_raw_event(struct hid_device *hdev,
258 struct hid_report *report, u8 *data, int size) 172 struct hid_report *report, u8 *data, int size)
259{ 173{
260 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 174 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
261 struct konepure_device *konepure = hid_get_drvdata(hdev); 175 struct roccat_common2_device *konepure = hid_get_drvdata(hdev);
262 176
263 if (intf->cur_altsetting->desc.bInterfaceProtocol 177 if (intf->cur_altsetting->desc.bInterfaceProtocol
264 != USB_INTERFACE_PROTOCOL_MOUSE) 178 != USB_INTERFACE_PROTOCOL_MOUSE)
diff --git a/drivers/hid/hid-roccat-konepure.h b/drivers/hid/hid-roccat-konepure.h
deleted file mode 100644
index 2cd24e93dfd6..000000000000
--- a/drivers/hid/hid-roccat-konepure.h
+++ /dev/null
@@ -1,72 +0,0 @@
1#ifndef __HID_ROCCAT_KONEPURE_H
2#define __HID_ROCCAT_KONEPURE_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 KONEPURE_SIZE_ACTUAL_PROFILE = 0x03,
19 KONEPURE_SIZE_CONTROL = 0x03,
20 KONEPURE_SIZE_FIRMWARE_WRITE = 0x0402,
21 KONEPURE_SIZE_INFO = 0x06,
22 KONEPURE_SIZE_MACRO = 0x0822,
23 KONEPURE_SIZE_PROFILE_SETTINGS = 0x1f,
24 KONEPURE_SIZE_PROFILE_BUTTONS = 0x3b,
25 KONEPURE_SIZE_SENSOR = 0x06,
26 KONEPURE_SIZE_TALK = 0x10,
27 KONEPURE_SIZE_TCU = 0x04,
28 KONEPURE_SIZE_TCU_IMAGE = 0x0404,
29};
30
31enum konepure_control_requests {
32 KONEPURE_CONTROL_REQUEST_GENERAL = 0x80,
33 KONEPURE_CONTROL_REQUEST_BUTTONS = 0x90,
34};
35
36enum konepure_commands {
37 KONEPURE_COMMAND_CONTROL = 0x04,
38 KONEPURE_COMMAND_ACTUAL_PROFILE = 0x05,
39 KONEPURE_COMMAND_PROFILE_SETTINGS = 0x06,
40 KONEPURE_COMMAND_PROFILE_BUTTONS = 0x07,
41 KONEPURE_COMMAND_MACRO = 0x08,
42 KONEPURE_COMMAND_INFO = 0x09,
43 KONEPURE_COMMAND_TCU = 0x0c,
44 KONEPURE_COMMAND_TCU_IMAGE = 0x0c,
45 KONEPURE_COMMAND_E = 0x0e,
46 KONEPURE_COMMAND_SENSOR = 0x0f,
47 KONEPURE_COMMAND_TALK = 0x10,
48 KONEPURE_COMMAND_FIRMWARE_WRITE = 0x1b,
49 KONEPURE_COMMAND_FIRMWARE_WRITE_CONTROL = 0x1c,
50};
51
52enum {
53 KONEPURE_MOUSE_REPORT_NUMBER_BUTTON = 3,
54};
55
56struct konepure_mouse_report_button {
57 uint8_t report_number; /* always KONEPURE_MOUSE_REPORT_NUMBER_BUTTON */
58 uint8_t zero;
59 uint8_t type;
60 uint8_t data1;
61 uint8_t data2;
62 uint8_t zero2;
63 uint8_t unknown[2];
64} __packed;
65
66struct konepure_device {
67 int roccat_claimed;
68 int chrdev_minor;
69 struct mutex konepure_lock;
70};
71
72#endif
diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c
index 0c8e1ef0b67d..966047711fbf 100644
--- a/drivers/hid/hid-roccat-kovaplus.c
+++ b/drivers/hid/hid-roccat-kovaplus.c
@@ -554,9 +554,13 @@ static void kovaplus_keep_values_up_to_date(struct kovaplus_device *kovaplus,
554 break; 554 break;
555 case KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_CPI: 555 case KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_CPI:
556 kovaplus->actual_cpi = kovaplus_convert_event_cpi(button_report->data1); 556 kovaplus->actual_cpi = kovaplus_convert_event_cpi(button_report->data1);
557 break;
557 case KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_SENSITIVITY: 558 case KOVAPLUS_MOUSE_REPORT_BUTTON_TYPE_SENSITIVITY:
558 kovaplus->actual_x_sensitivity = button_report->data1; 559 kovaplus->actual_x_sensitivity = button_report->data1;
559 kovaplus->actual_y_sensitivity = button_report->data2; 560 kovaplus->actual_y_sensitivity = button_report->data2;
561 break;
562 default:
563 break;
560 } 564 }
561} 565}
562 566
diff --git a/drivers/hid/hid-roccat-ryos.c b/drivers/hid/hid-roccat-ryos.c
new file mode 100644
index 000000000000..47cc8f30ff6d
--- /dev/null
+++ b/drivers/hid/hid-roccat-ryos.c
@@ -0,0 +1,241 @@
1/*
2 * Roccat Ryos driver for Linux
3 *
4 * Copyright (c) 2013 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#include <linux/types.h>
15#include <linux/device.h>
16#include <linux/input.h>
17#include <linux/hid.h>
18#include <linux/module.h>
19#include <linux/slab.h>
20#include <linux/hid-roccat.h>
21#include "hid-ids.h"
22#include "hid-roccat-common.h"
23
24enum {
25 RYOS_REPORT_NUMBER_SPECIAL = 3,
26 RYOS_USB_INTERFACE_PROTOCOL = 0,
27};
28
29struct ryos_report_special {
30 uint8_t number; /* RYOS_REPORT_NUMBER_SPECIAL */
31 uint8_t data[4];
32} __packed;
33
34static struct class *ryos_class;
35
36ROCCAT_COMMON2_BIN_ATTRIBUTE_W(control, 0x04, 0x03);
37ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(profile, 0x05, 0x03);
38ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(keys_primary, 0x06, 0x7d);
39ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(keys_function, 0x07, 0x5f);
40ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(keys_macro, 0x08, 0x23);
41ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(keys_thumbster, 0x09, 0x17);
42ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(keys_extra, 0x0a, 0x08);
43ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(keys_easyzone, 0x0b, 0x126);
44ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(key_mask, 0x0c, 0x06);
45ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(light, 0x0d, 0x10);
46ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(macro, 0x0e, 0x7d2);
47ROCCAT_COMMON2_BIN_ATTRIBUTE_R(info, 0x0f, 0x08);
48ROCCAT_COMMON2_BIN_ATTRIBUTE_W(reset, 0x11, 0x03);
49ROCCAT_COMMON2_BIN_ATTRIBUTE_W(light_control, 0x13, 0x08);
50ROCCAT_COMMON2_BIN_ATTRIBUTE_W(talk, 0x16, 0x10);
51ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(stored_lights, 0x17, 0x0566);
52ROCCAT_COMMON2_BIN_ATTRIBUTE_W(custom_lights, 0x18, 0x14);
53ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(light_macro, 0x19, 0x07d2);
54
55static struct bin_attribute *ryos_bin_attrs[] = {
56 &bin_attr_control,
57 &bin_attr_profile,
58 &bin_attr_keys_primary,
59 &bin_attr_keys_function,
60 &bin_attr_keys_macro,
61 &bin_attr_keys_thumbster,
62 &bin_attr_keys_extra,
63 &bin_attr_keys_easyzone,
64 &bin_attr_key_mask,
65 &bin_attr_light,
66 &bin_attr_macro,
67 &bin_attr_info,
68 &bin_attr_reset,
69 &bin_attr_light_control,
70 &bin_attr_talk,
71 &bin_attr_stored_lights,
72 &bin_attr_custom_lights,
73 &bin_attr_light_macro,
74 NULL,
75};
76
77static const struct attribute_group ryos_group = {
78 .bin_attrs = ryos_bin_attrs,
79};
80
81static const struct attribute_group *ryos_groups[] = {
82 &ryos_group,
83 NULL,
84};
85
86static int ryos_init_specials(struct hid_device *hdev)
87{
88 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
89 struct usb_device *usb_dev = interface_to_usbdev(intf);
90 struct roccat_common2_device *ryos;
91 int retval;
92
93 if (intf->cur_altsetting->desc.bInterfaceProtocol
94 != RYOS_USB_INTERFACE_PROTOCOL) {
95 hid_set_drvdata(hdev, NULL);
96 return 0;
97 }
98
99 ryos = kzalloc(sizeof(*ryos), GFP_KERNEL);
100 if (!ryos) {
101 hid_err(hdev, "can't alloc device descriptor\n");
102 return -ENOMEM;
103 }
104 hid_set_drvdata(hdev, ryos);
105
106 retval = roccat_common2_device_init_struct(usb_dev, ryos);
107 if (retval) {
108 hid_err(hdev, "couldn't init Ryos device\n");
109 goto exit_free;
110 }
111
112 retval = roccat_connect(ryos_class, hdev,
113 sizeof(struct ryos_report_special));
114 if (retval < 0) {
115 hid_err(hdev, "couldn't init char dev\n");
116 } else {
117 ryos->chrdev_minor = retval;
118 ryos->roccat_claimed = 1;
119 }
120
121 return 0;
122exit_free:
123 kfree(ryos);
124 return retval;
125}
126
127static void ryos_remove_specials(struct hid_device *hdev)
128{
129 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
130 struct roccat_common2_device *ryos;
131
132 if (intf->cur_altsetting->desc.bInterfaceProtocol
133 != RYOS_USB_INTERFACE_PROTOCOL)
134 return;
135
136 ryos = hid_get_drvdata(hdev);
137 if (ryos->roccat_claimed)
138 roccat_disconnect(ryos->chrdev_minor);
139 kfree(ryos);
140}
141
142static int ryos_probe(struct hid_device *hdev,
143 const struct hid_device_id *id)
144{
145 int retval;
146
147 retval = hid_parse(hdev);
148 if (retval) {
149 hid_err(hdev, "parse failed\n");
150 goto exit;
151 }
152
153 retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
154 if (retval) {
155 hid_err(hdev, "hw start failed\n");
156 goto exit;
157 }
158
159 retval = ryos_init_specials(hdev);
160 if (retval) {
161 hid_err(hdev, "couldn't install mouse\n");
162 goto exit_stop;
163 }
164
165 return 0;
166
167exit_stop:
168 hid_hw_stop(hdev);
169exit:
170 return retval;
171}
172
173static void ryos_remove(struct hid_device *hdev)
174{
175 ryos_remove_specials(hdev);
176 hid_hw_stop(hdev);
177}
178
179static int ryos_raw_event(struct hid_device *hdev,
180 struct hid_report *report, u8 *data, int size)
181{
182 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
183 struct roccat_common2_device *ryos = hid_get_drvdata(hdev);
184
185 if (intf->cur_altsetting->desc.bInterfaceProtocol
186 != RYOS_USB_INTERFACE_PROTOCOL)
187 return 0;
188
189 if (data[0] != RYOS_REPORT_NUMBER_SPECIAL)
190 return 0;
191
192 if (ryos != NULL && ryos->roccat_claimed)
193 roccat_report_event(ryos->chrdev_minor, data);
194
195 return 0;
196}
197
198static const struct hid_device_id ryos_devices[] = {
199 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK) },
200 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK_GLOW) },
201 { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK_PRO) },
202 { }
203};
204
205MODULE_DEVICE_TABLE(hid, ryos_devices);
206
207static struct hid_driver ryos_driver = {
208 .name = "ryos",
209 .id_table = ryos_devices,
210 .probe = ryos_probe,
211 .remove = ryos_remove,
212 .raw_event = ryos_raw_event
213};
214
215static int __init ryos_init(void)
216{
217 int retval;
218
219 ryos_class = class_create(THIS_MODULE, "ryos");
220 if (IS_ERR(ryos_class))
221 return PTR_ERR(ryos_class);
222 ryos_class->dev_groups = ryos_groups;
223
224 retval = hid_register_driver(&ryos_driver);
225 if (retval)
226 class_destroy(ryos_class);
227 return retval;
228}
229
230static void __exit ryos_exit(void)
231{
232 hid_unregister_driver(&ryos_driver);
233 class_destroy(ryos_class);
234}
235
236module_init(ryos_init);
237module_exit(ryos_exit);
238
239MODULE_AUTHOR("Stefan Achatz");
240MODULE_DESCRIPTION("USB Roccat Ryos MK/Glow/Pro driver");
241MODULE_LICENSE("GPL v2");
diff --git a/drivers/hid/hid-roccat-savu.c b/drivers/hid/hid-roccat-savu.c
index 0332267199d5..6dbf6e04dce7 100644
--- a/drivers/hid/hid-roccat-savu.c
+++ b/drivers/hid/hid-roccat-savu.c
@@ -27,98 +27,15 @@
27 27
28static struct class *savu_class; 28static struct class *savu_class;
29 29
30static ssize_t savu_sysfs_read(struct file *fp, struct kobject *kobj, 30ROCCAT_COMMON2_BIN_ATTRIBUTE_W(control, 0x4, 0x03);
31 char *buf, loff_t off, size_t count, 31ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(profile, 0x5, 0x03);
32 size_t real_size, uint command) 32ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(general, 0x6, 0x10);
33{ 33ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(buttons, 0x7, 0x2f);
34 struct device *dev = 34ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(macro, 0x8, 0x0823);
35 container_of(kobj, struct device, kobj)->parent->parent; 35ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(info, 0x9, 0x08);
36 struct savu_device *savu = hid_get_drvdata(dev_get_drvdata(dev)); 36ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(sensor, 0xc, 0x04);
37 struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); 37
38 int retval; 38static struct bin_attribute *savu_bin_attrs[] = {
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) \
97SAVU_SYSFS_RW(thingy, THINGY); \
98static struct bin_attribute bin_attr_##thingy = { \
99 .attr = { .name = #thingy, .mode = 0660 }, \
100 .size = SAVU_SIZE_ ## THINGY, \
101 .read = savu_sysfs_read_ ## thingy, \
102 .write = savu_sysfs_write_ ## thingy \
103}
104
105#define SAVU_BIN_ATTRIBUTE_W(thingy, THINGY) \
106SAVU_SYSFS_W(thingy, THINGY); \
107static struct bin_attribute bin_attr_##thingy = { \
108 .attr = { .name = #thingy, .mode = 0220 }, \
109 .size = SAVU_SIZE_ ## THINGY, \
110 .write = savu_sysfs_write_ ## thingy \
111}
112
113SAVU_BIN_ATTRIBUTE_W(control, CONTROL);
114SAVU_BIN_ATTRIBUTE_RW(profile, PROFILE);
115SAVU_BIN_ATTRIBUTE_RW(general, GENERAL);
116SAVU_BIN_ATTRIBUTE_RW(buttons, BUTTONS);
117SAVU_BIN_ATTRIBUTE_RW(macro, MACRO);
118SAVU_BIN_ATTRIBUTE_RW(info, INFO);
119SAVU_BIN_ATTRIBUTE_RW(sensor, SENSOR);
120
121static struct bin_attribute *savu_bin_attributes[] = {
122 &bin_attr_control, 39 &bin_attr_control,
123 &bin_attr_profile, 40 &bin_attr_profile,
124 &bin_attr_general, 41 &bin_attr_general,
@@ -130,7 +47,7 @@ static struct bin_attribute *savu_bin_attributes[] = {
130}; 47};
131 48
132static const struct attribute_group savu_group = { 49static const struct attribute_group savu_group = {
133 .bin_attrs = savu_bin_attributes, 50 .bin_attrs = savu_bin_attrs,
134}; 51};
135 52
136static const struct attribute_group *savu_groups[] = { 53static const struct attribute_group *savu_groups[] = {
@@ -138,19 +55,11 @@ static const struct attribute_group *savu_groups[] = {
138 NULL, 55 NULL,
139}; 56};
140 57
141static int savu_init_savu_device_struct(struct usb_device *usb_dev,
142 struct savu_device *savu)
143{
144 mutex_init(&savu->savu_lock);
145
146 return 0;
147}
148
149static int savu_init_specials(struct hid_device *hdev) 58static int savu_init_specials(struct hid_device *hdev)
150{ 59{
151 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 60 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
152 struct usb_device *usb_dev = interface_to_usbdev(intf); 61 struct usb_device *usb_dev = interface_to_usbdev(intf);
153 struct savu_device *savu; 62 struct roccat_common2_device *savu;
154 int retval; 63 int retval;
155 64
156 if (intf->cur_altsetting->desc.bInterfaceProtocol 65 if (intf->cur_altsetting->desc.bInterfaceProtocol
@@ -166,9 +75,9 @@ static int savu_init_specials(struct hid_device *hdev)
166 } 75 }
167 hid_set_drvdata(hdev, savu); 76 hid_set_drvdata(hdev, savu);
168 77
169 retval = savu_init_savu_device_struct(usb_dev, savu); 78 retval = roccat_common2_device_init_struct(usb_dev, savu);
170 if (retval) { 79 if (retval) {
171 hid_err(hdev, "couldn't init struct savu_device\n"); 80 hid_err(hdev, "couldn't init Savu device\n");
172 goto exit_free; 81 goto exit_free;
173 } 82 }
174 83
@@ -190,7 +99,7 @@ exit_free:
190static void savu_remove_specials(struct hid_device *hdev) 99static void savu_remove_specials(struct hid_device *hdev)
191{ 100{
192 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 101 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
193 struct savu_device *savu; 102 struct roccat_common2_device *savu;
194 103
195 if (intf->cur_altsetting->desc.bInterfaceProtocol 104 if (intf->cur_altsetting->desc.bInterfaceProtocol
196 != USB_INTERFACE_PROTOCOL_MOUSE) 105 != USB_INTERFACE_PROTOCOL_MOUSE)
@@ -239,7 +148,7 @@ static void savu_remove(struct hid_device *hdev)
239 hid_hw_stop(hdev); 148 hid_hw_stop(hdev);
240} 149}
241 150
242static void savu_report_to_chrdev(struct savu_device const *savu, 151static void savu_report_to_chrdev(struct roccat_common2_device const *savu,
243 u8 const *data) 152 u8 const *data)
244{ 153{
245 struct savu_roccat_report roccat_report; 154 struct savu_roccat_report roccat_report;
@@ -261,7 +170,7 @@ static int savu_raw_event(struct hid_device *hdev,
261 struct hid_report *report, u8 *data, int size) 170 struct hid_report *report, u8 *data, int size)
262{ 171{
263 struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 172 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
264 struct savu_device *savu = hid_get_drvdata(hdev); 173 struct roccat_common2_device *savu = hid_get_drvdata(hdev);
265 174
266 if (intf->cur_altsetting->desc.bInterfaceProtocol 175 if (intf->cur_altsetting->desc.bInterfaceProtocol
267 != USB_INTERFACE_PROTOCOL_MOUSE) 176 != USB_INTERFACE_PROTOCOL_MOUSE)
diff --git a/drivers/hid/hid-roccat-savu.h b/drivers/hid/hid-roccat-savu.h
index 9120ba72087f..d23217bd2b86 100644
--- a/drivers/hid/hid-roccat-savu.h
+++ b/drivers/hid/hid-roccat-savu.h
@@ -14,31 +14,6 @@
14 14
15#include <linux/types.h> 15#include <linux/types.h>
16 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 { 17struct savu_mouse_report_special {
43 uint8_t report_number; /* always 3 */ 18 uint8_t report_number; /* always 3 */
44 uint8_t zero; 19 uint8_t zero;
@@ -77,11 +52,4 @@ struct savu_roccat_report {
77 uint8_t data[2]; 52 uint8_t data[2];
78} __packed; 53} __packed;
79 54
80struct savu_device {
81 int roccat_claimed;
82 int chrdev_minor;
83
84 struct mutex savu_lock;
85};
86
87#endif 55#endif
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index 10e1581022cf..9e4cdca549c0 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -326,7 +326,8 @@ int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,
326 field->logical == attr_usage_id) { 326 field->logical == attr_usage_id) {
327 sensor_hub_fill_attr_info(info, i, report->id, 327 sensor_hub_fill_attr_info(info, i, report->id,
328 field->unit, field->unit_exponent, 328 field->unit, field->unit_exponent,
329 field->report_size); 329 field->report_size *
330 field->report_count);
330 ret = 0; 331 ret = 0;
331 } else { 332 } else {
332 for (j = 0; j < field->maxusage; ++j) { 333 for (j = 0; j < field->maxusage; ++j) {
@@ -338,7 +339,8 @@ int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,
338 i, report->id, 339 i, report->id,
339 field->unit, 340 field->unit,
340 field->unit_exponent, 341 field->unit_exponent,
341 field->report_size); 342 field->report_size *
343 field->report_count);
342 ret = 0; 344 ret = 0;
343 break; 345 break;
344 } 346 }
@@ -425,9 +427,10 @@ static int sensor_hub_raw_event(struct hid_device *hdev,
425 hid_dbg(hdev, "%d collection_index:%x hid:%x sz:%x\n", 427 hid_dbg(hdev, "%d collection_index:%x hid:%x sz:%x\n",
426 i, report->field[i]->usage->collection_index, 428 i, report->field[i]->usage->collection_index,
427 report->field[i]->usage->hid, 429 report->field[i]->usage->hid,
428 report->field[i]->report_size/8); 430 (report->field[i]->report_size *
429 431 report->field[i]->report_count)/8);
430 sz = report->field[i]->report_size/8; 432 sz = (report->field[i]->report_size *
433 report->field[i]->report_count)/8;
431 if (pdata->pending.status && pdata->pending.attr_usage_id == 434 if (pdata->pending.status && pdata->pending.attr_usage_id ==
432 report->field[i]->usage->hid) { 435 report->field[i]->usage->hid) {
433 hid_dbg(hdev, "data was pending ...\n"); 436 hid_dbg(hdev, "data was pending ...\n");
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index b18320db5f7d..da551d113762 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -419,21 +419,14 @@ static int sixaxis_usb_output_raw_report(struct hid_device *hid, __u8 *buf,
419 */ 419 */
420static int sixaxis_set_operational_usb(struct hid_device *hdev) 420static int sixaxis_set_operational_usb(struct hid_device *hdev)
421{ 421{
422 struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
423 struct usb_device *dev = interface_to_usbdev(intf);
424 __u16 ifnum = intf->cur_altsetting->desc.bInterfaceNumber;
425 int ret; 422 int ret;
426 char *buf = kmalloc(18, GFP_KERNEL); 423 char *buf = kmalloc(18, GFP_KERNEL);
427 424
428 if (!buf) 425 if (!buf)
429 return -ENOMEM; 426 return -ENOMEM;
430 427
431 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), 428 ret = hdev->hid_get_raw_report(hdev, 0xf2, buf, 17, HID_FEATURE_REPORT);
432 HID_REQ_GET_REPORT, 429
433 USB_DIR_IN | USB_TYPE_CLASS |
434 USB_RECIP_INTERFACE,
435 (3 << 8) | 0xf2, ifnum, buf, 17,
436 USB_CTRL_GET_TIMEOUT);
437 if (ret < 0) 430 if (ret < 0)
438 hid_err(hdev, "can't set operational mode\n"); 431 hid_err(hdev, "can't set operational mode\n");
439 432
@@ -621,6 +614,54 @@ static void buzz_remove(struct hid_device *hdev)
621 drv_data->extra = NULL; 614 drv_data->extra = NULL;
622} 615}
623 616
617#ifdef CONFIG_SONY_FF
618static int sony_play_effect(struct input_dev *dev, void *data,
619 struct ff_effect *effect)
620{
621 unsigned char buf[] = {
622 0x01,
623 0x00, 0xff, 0x00, 0xff, 0x00,
624 0x00, 0x00, 0x00, 0x00, 0x03,
625 0xff, 0x27, 0x10, 0x00, 0x32,
626 0xff, 0x27, 0x10, 0x00, 0x32,
627 0xff, 0x27, 0x10, 0x00, 0x32,
628 0xff, 0x27, 0x10, 0x00, 0x32,
629 0x00, 0x00, 0x00, 0x00, 0x00
630 };
631 __u8 left;
632 __u8 right;
633 struct hid_device *hid = input_get_drvdata(dev);
634
635 if (effect->type != FF_RUMBLE)
636 return 0;
637
638 left = effect->u.rumble.strong_magnitude / 256;
639 right = effect->u.rumble.weak_magnitude ? 1 : 0;
640
641 buf[3] = right;
642 buf[5] = left;
643
644 return hid->hid_output_raw_report(hid, buf, sizeof(buf),
645 HID_OUTPUT_REPORT);
646}
647
648static int sony_init_ff(struct hid_device *hdev)
649{
650 struct hid_input *hidinput = list_entry(hdev->inputs.next,
651 struct hid_input, list);
652 struct input_dev *input_dev = hidinput->input;
653
654 input_set_capability(input_dev, EV_FF, FF_RUMBLE);
655 return input_ff_create_memless(input_dev, NULL, sony_play_effect);
656}
657
658#else
659static int sony_init_ff(struct hid_device *hdev)
660{
661 return 0;
662}
663#endif
664
624static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) 665static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
625{ 666{
626 int ret; 667 int ret;
@@ -670,6 +711,10 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
670 if (ret < 0) 711 if (ret < 0)
671 goto err_stop; 712 goto err_stop;
672 713
714 ret = sony_init_ff(hdev);
715 if (ret < 0)
716 goto err_stop;
717
673 return 0; 718 return 0;
674err_stop: 719err_stop:
675 hid_hw_stop(hdev); 720 hid_hw_stop(hdev);
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c
index c1336193b04b..4c13bf3ebe20 100644
--- a/drivers/hid/i2c-hid/i2c-hid.c
+++ b/drivers/hid/i2c-hid/i2c-hid.c
@@ -455,10 +455,6 @@ static void i2c_hid_init_reports(struct hid_device *hid)
455 } 455 }
456 456
457 list_for_each_entry(report, 457 list_for_each_entry(report,
458 &hid->report_enum[HID_INPUT_REPORT].report_list, list)
459 i2c_hid_init_report(report, inbuf, ihid->bufsize);
460
461 list_for_each_entry(report,
462 &hid->report_enum[HID_FEATURE_REPORT].report_list, list) 458 &hid->report_enum[HID_FEATURE_REPORT].report_list, list)
463 i2c_hid_init_report(report, inbuf, ihid->bufsize); 459 i2c_hid_init_report(report, inbuf, ihid->bufsize);
464 460
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
index 3fca3be08337..0db9a67278ba 100644
--- a/drivers/hid/usbhid/hid-quirks.c
+++ b/drivers/hid/usbhid/hid-quirks.c
@@ -84,6 +84,8 @@ static const struct hid_blacklist {
84 { USB_VENDOR_ID_REALTEK, USB_DEVICE_ID_REALTEK_READER, HID_QUIRK_NO_INIT_REPORTS }, 84 { USB_VENDOR_ID_REALTEK, USB_DEVICE_ID_REALTEK_READER, HID_QUIRK_NO_INIT_REPORTS },
85 { USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET }, 85 { USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET },
86 { USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780, HID_QUIRK_NOGET }, 86 { USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780, HID_QUIRK_NOGET },
87 { USB_VENDOR_ID_SIS2_TOUCH, USB_DEVICE_ID_SIS9200_TOUCH, HID_QUIRK_NOGET },
88 { USB_VENDOR_ID_SIS2_TOUCH, USB_DEVICE_ID_SIS817_TOUCH, HID_QUIRK_NOGET },
87 { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, 89 { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
88 { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET }, 90 { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET },
89 { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET }, 91 { USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, HID_QUIRK_NOGET },
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 721fdb3597ca..ae4b6b903629 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -146,12 +146,10 @@ enum {
146 146
147#define USB_DEVICE_HID_CLASS(vend, prod) \ 147#define USB_DEVICE_HID_CLASS(vend, prod) \
148 .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS \ 148 .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS \
149 | USB_DEVICE_ID_MATCH_INT_PROTOCOL \
150 | USB_DEVICE_ID_MATCH_DEVICE, \ 149 | USB_DEVICE_ID_MATCH_DEVICE, \
151 .idVendor = (vend), \ 150 .idVendor = (vend), \
152 .idProduct = (prod), \ 151 .idProduct = (prod), \
153 .bInterfaceClass = USB_INTERFACE_CLASS_HID, \ 152 .bInterfaceClass = USB_INTERFACE_CLASS_HID
154 .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE
155 153
156static const struct usb_device_id usbtouch_devices[] = { 154static const struct usb_device_id usbtouch_devices[] = {
157#ifdef CONFIG_TOUCHSCREEN_USB_EGALAX 155#ifdef CONFIG_TOUCHSCREEN_USB_EGALAX