diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-15 19:48:22 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-15 19:48:22 -0500 |
commit | e0da5c9a49b927d9e5f62b21a7abc283e99022e2 (patch) | |
tree | c73688d7e30737f75efdc4a4f01d79fb7deb1833 /drivers/hid | |
parent | 9073e1a804c3096eda84ee7cbf11d1f174236c75 (diff) | |
parent | 7f9cc24a805ce444e082c01f9818f2d3a25ef268 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
Pull HID updates from Jiri Kosina:
- i2c-hid is not querying init reports any more, as it's not mandated
by the spec, and annoys quite a few devices during enumeration, by
Bibek Basu
- a lot of fixes for Logitech devices, by Simon Wood
- hid-apple now has an option to switch between Option and Command
mode, by Nanno Langstraat
- Some more workarounds for severely broken ELO devices, by Oliver
Neukum
- more devm conversions, by Benjamin Tissoires
- wiimote correctness fixes, by David Herrmann
- a lot of added support for various new device IDs and random small
fixes here and there"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (34 commits)
HID: enable Mayflash USB Gamecube Adapter
HID: sony: Add force feedback support for Dualshock3 USB
Input: usbtouchscreen: ignore eGalax/D-Wav/EETI HIDs
HID: don't ignore eGalax/D-Wav/EETI HIDs
HID: roccat: add missing special driver declarations
HID:hid-lg4ff: Correct Auto-center strength for wheels other than MOMO and MOMO2
HID:hid-lg4ff: Initialize device properties before we touch autocentering.
HID:hid-lg4ff: ensure ConstantForce is disabled when set to 0
HID:hid-lg4ff: Switch autocentering off when strength is set to zero.
HID:hid-lg4ff: Scale autocentering force properly on Logitech wheel
HID: roccat: fix Coverity CID 141438
HID: multitouch: add manufacturer to Kconfig help text
HID: logitech-dj: small cleanup in rdcat()
HID: remove self-assignment from hid_input_report
HID: hid-sensor-hub: fix report size
HID: i2c-hid: Stop querying for init reports
HID: roccat: add support for Ryos MK keyboards
HID: roccat: generalize some common code
HID: roccat: add new device return value
HID: wiimote: add pro-controller analog stick calibration
...
Diffstat (limited to 'drivers/hid')
28 files changed, 971 insertions, 448 deletions
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 | ||
246 | config HOLTEK_FF | 247 | config 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 | ||
324 | config HID_LENOVO_TPKBD | 325 | config 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 | ||
371 | config LOGIRUMBLEPAD2_FF | 371 | config 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 | ||
379 | config LOGIG940_FF | 381 | config 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 | ||
621 | config 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 | |||
617 | config HID_SPEEDLINK | 629 | config 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 | |||
95 | obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ | 95 | obj-$(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 |
99 | obj-$(CONFIG_HID_SAITEK) += hid-saitek.o | 99 | obj-$(CONFIG_HID_SAITEK) += hid-saitek.o |
100 | obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o | 100 | obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o |
101 | obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o | 101 | obj-$(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); | |||
46 | MODULE_PARM_DESC(iso_layout, "Enable/Disable hardcoded ISO-layout of the keyboard. " | 46 | MODULE_PARM_DESC(iso_layout, "Enable/Disable hardcoded ISO-layout of the keyboard. " |
47 | "(0 = disabled, [1] = enabled)"); | 47 | "(0 = disabled, [1] = enabled)"); |
48 | 48 | ||
49 | static unsigned int swap_opt_cmd; | ||
50 | module_param(swap_opt_cmd, uint, 0644); | ||
51 | MODULE_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 | |||
49 | struct apple_sc { | 55 | struct 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 | ||
159 | static 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 | |||
153 | static const struct apple_key_translation *apple_find_translation( | 167 | static 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 | ||
181 | static const struct hid_device_id ax_devices[] = { | 181 | static 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 | }; |
185 | MODULE_DEVICE_TABLE(hid, ax_devices); | 186 | MODULE_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 | */ |
182 | static bool elo_broken_firmware(struct usb_device *dev) | 182 | static 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 | ||
187 | static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id) | 220 | static 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 | ||
33 | static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 34 | static __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 | |||
401 | err2: | ||
402 | kfree(name_mute); | ||
403 | err: | ||
404 | kfree(data_pointer); | ||
405 | return ret; | ||
406 | } | 392 | } |
407 | 393 | ||
408 | static int tpkbd_probe(struct hid_device *hdev, | 394 | static 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 | ||
457 | static void tpkbd_remove(struct hid_device *hdev) | 438 | static 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[] = { | |||
170 | 0xC0 /* End Collection */ | 172 | 0xC0 /* End Collection */ |
171 | }; | 173 | }; |
172 | 174 | ||
175 | static __u8 fv_rdesc_fixed[] = { | ||
176 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
177 | 0x09, 0x04, /* Usage (Joystik), */ | ||
178 | 0xA1, 0x01, /* Collection (Application), */ | ||
179 | 0xA1, 0x02, /* Collection (Logical), */ | ||
180 | 0x95, 0x01, /* Report Count (1), */ | ||
181 | 0x75, 0x0A, /* Report Size (10), */ | ||
182 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
183 | 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ | ||
184 | 0x35, 0x00, /* Physical Minimum (0), */ | ||
185 | 0x46, 0xFF, 0x03, /* Physical Maximum (1023), */ | ||
186 | 0x09, 0x30, /* Usage (X), */ | ||
187 | 0x81, 0x02, /* Input (Variable), */ | ||
188 | 0x95, 0x0C, /* Report Count (12), */ | ||
189 | 0x75, 0x01, /* Report Size (1), */ | ||
190 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
191 | 0x45, 0x01, /* Physical Maximum (1), */ | ||
192 | 0x05, 0x09, /* Usage Page (Button), */ | ||
193 | 0x19, 0x01, /* Usage Minimum (01h), */ | ||
194 | 0x29, 0x0C, /* Usage Maximum (0Ch), */ | ||
195 | 0x81, 0x02, /* Input (Variable), */ | ||
196 | 0x95, 0x02, /* Report Count (2), */ | ||
197 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
198 | 0x09, 0x01, /* Usage (01h), */ | ||
199 | 0x81, 0x02, /* Input (Variable), */ | ||
200 | 0x09, 0x02, /* Usage (02h), */ | ||
201 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
202 | 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ | ||
203 | 0x95, 0x01, /* Report Count (1), */ | ||
204 | 0x75, 0x08, /* Report Size (8), */ | ||
205 | 0x81, 0x02, /* Input (Variable), */ | ||
206 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
207 | 0x25, 0x07, /* Logical Maximum (7), */ | ||
208 | 0x46, 0x3B, 0x01, /* Physical Maximum (315), */ | ||
209 | 0x75, 0x04, /* Report Size (4), */ | ||
210 | 0x65, 0x14, /* Unit (Degrees), */ | ||
211 | 0x09, 0x39, /* Usage (Hat Switch), */ | ||
212 | 0x81, 0x42, /* Input (Variable, Null State), */ | ||
213 | 0x75, 0x01, /* Report Size (1), */ | ||
214 | 0x95, 0x04, /* Report Count (4), */ | ||
215 | 0x65, 0x00, /* Unit, */ | ||
216 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
217 | 0x09, 0x01, /* Usage (01h), */ | ||
218 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
219 | 0x45, 0x01, /* Physical Maximum (1), */ | ||
220 | 0x81, 0x02, /* Input (Variable), */ | ||
221 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
222 | 0x95, 0x01, /* Report Count (1), */ | ||
223 | 0x75, 0x08, /* Report Size (8), */ | ||
224 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
225 | 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ | ||
226 | 0x09, 0x31, /* Usage (Y), */ | ||
227 | 0x81, 0x02, /* Input (Variable), */ | ||
228 | 0x09, 0x32, /* Usage (Z), */ | ||
229 | 0x81, 0x02, /* Input (Variable), */ | ||
230 | 0xC0, /* End Collection, */ | ||
231 | 0xA1, 0x02, /* Collection (Logical), */ | ||
232 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
233 | 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ | ||
234 | 0x95, 0x07, /* Report Count (7), */ | ||
235 | 0x75, 0x08, /* Report Size (8), */ | ||
236 | 0x09, 0x03, /* Usage (03h), */ | ||
237 | 0x91, 0x02, /* Output (Variable), */ | ||
238 | 0xC0, /* End Collection, */ | ||
239 | 0xC0 /* End Collection */ | ||
240 | }; | ||
241 | |||
173 | static __u8 momo_rdesc_fixed[] = { | 242 | static __u8 momo_rdesc_fixed[] = { |
174 | 0x05, 0x01, /* Usage Page (Desktop), */ | 243 | 0x05, 0x01, /* Usage Page (Desktop), */ |
175 | 0x09, 0x04, /* Usage (Joystik), */ | 244 | 0x09, 0x04, /* Usage (Joystik), */ |
@@ -216,6 +285,54 @@ static __u8 momo_rdesc_fixed[] = { | |||
216 | 0xC0 /* End Collection */ | 285 | 0xC0 /* End Collection */ |
217 | }; | 286 | }; |
218 | 287 | ||
288 | static __u8 momo2_rdesc_fixed[] = { | ||
289 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
290 | 0x09, 0x04, /* Usage (Joystik), */ | ||
291 | 0xA1, 0x01, /* Collection (Application), */ | ||
292 | 0xA1, 0x02, /* Collection (Logical), */ | ||
293 | 0x95, 0x01, /* Report Count (1), */ | ||
294 | 0x75, 0x0A, /* Report Size (10), */ | ||
295 | 0x15, 0x00, /* Logical Minimum (0), */ | ||
296 | 0x26, 0xFF, 0x03, /* Logical Maximum (1023), */ | ||
297 | 0x35, 0x00, /* Physical Minimum (0), */ | ||
298 | 0x46, 0xFF, 0x03, /* Physical Maximum (1023), */ | ||
299 | 0x09, 0x30, /* Usage (X), */ | ||
300 | 0x81, 0x02, /* Input (Variable), */ | ||
301 | 0x95, 0x0A, /* Report Count (10), */ | ||
302 | 0x75, 0x01, /* Report Size (1), */ | ||
303 | 0x25, 0x01, /* Logical Maximum (1), */ | ||
304 | 0x45, 0x01, /* Physical Maximum (1), */ | ||
305 | 0x05, 0x09, /* Usage Page (Button), */ | ||
306 | 0x19, 0x01, /* Usage Minimum (01h), */ | ||
307 | 0x29, 0x0A, /* Usage Maximum (0Ah), */ | ||
308 | 0x81, 0x02, /* Input (Variable), */ | ||
309 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
310 | 0x09, 0x00, /* Usage (00h), */ | ||
311 | 0x95, 0x04, /* Report Count (4), */ | ||
312 | 0x81, 0x02, /* Input (Variable), */ | ||
313 | 0x95, 0x01, /* Report Count (1), */ | ||
314 | 0x75, 0x08, /* Report Size (8), */ | ||
315 | 0x26, 0xFF, 0x00, /* Logical Maximum (255), */ | ||
316 | 0x46, 0xFF, 0x00, /* Physical Maximum (255), */ | ||
317 | 0x09, 0x01, /* Usage (01h), */ | ||
318 | 0x81, 0x02, /* Input (Variable), */ | ||
319 | 0x05, 0x01, /* Usage Page (Desktop), */ | ||
320 | 0x09, 0x31, /* Usage (Y), */ | ||
321 | 0x81, 0x02, /* Input (Variable), */ | ||
322 | 0x09, 0x32, /* Usage (Z), */ | ||
323 | 0x81, 0x02, /* Input (Variable), */ | ||
324 | 0x06, 0x00, 0xFF, /* Usage Page (FF00h), */ | ||
325 | 0x09, 0x00, /* Usage (00h), */ | ||
326 | 0x81, 0x02, /* Input (Variable), */ | ||
327 | 0xC0, /* End Collection, */ | ||
328 | 0xA1, 0x02, /* Collection (Logical), */ | ||
329 | 0x09, 0x02, /* Usage (02h), */ | ||
330 | 0x95, 0x07, /* Report Count (7), */ | ||
331 | 0x91, 0x02, /* Output (Variable), */ | ||
332 | 0xC0, /* End Collection, */ | ||
333 | 0xC0 /* 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 | ||
545 | static void rdcat(char **rdesc, unsigned int *rsize, const char *data, unsigned int size) | 545 | static 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, | |||
65 | EXPORT_SYMBOL_GPL(roccat_common2_send); | 65 | EXPORT_SYMBOL_GPL(roccat_common2_send); |
66 | 66 | ||
67 | enum roccat_common2_control_states { | 67 | enum 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 | ||
74 | static int roccat_common2_receive_control_status(struct usb_device *usb_dev) | 75 | static 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 | } |
123 | EXPORT_SYMBOL_GPL(roccat_common2_send_with_status); | 123 | EXPORT_SYMBOL_GPL(roccat_common2_send_with_status); |
124 | 124 | ||
125 | int 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 | } | ||
131 | EXPORT_SYMBOL_GPL(roccat_common2_device_init_struct); | ||
132 | |||
133 | ssize_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 | } | ||
155 | EXPORT_SYMBOL_GPL(roccat_common2_sysfs_read); | ||
156 | |||
157 | ssize_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 | } | ||
176 | EXPORT_SYMBOL_GPL(roccat_common2_sysfs_write); | ||
177 | |||
125 | MODULE_AUTHOR("Stefan Achatz"); | 178 | MODULE_AUTHOR("Stefan Achatz"); |
126 | MODULE_DESCRIPTION("USB Roccat common driver"); | 179 | MODULE_DESCRIPTION("USB Roccat common driver"); |
127 | MODULE_LICENSE("GPL v2"); | 180 | MODULE_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, | |||
32 | int roccat_common2_send_with_status(struct usb_device *usb_dev, | 32 | int 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 | ||
35 | struct roccat_common2_device { | ||
36 | int roccat_claimed; | ||
37 | int chrdev_minor; | ||
38 | struct mutex lock; | ||
39 | }; | ||
40 | |||
41 | int roccat_common2_device_init_struct(struct usb_device *usb_dev, | ||
42 | struct roccat_common2_device *dev); | ||
43 | ssize_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); | ||
46 | ssize_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) \ | ||
51 | static 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) \ | ||
60 | static 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) \ | ||
69 | ROCCAT_COMMON2_SYSFS_W(thingy, COMMAND, SIZE) \ | ||
70 | ROCCAT_COMMON2_SYSFS_R(thingy, COMMAND, SIZE) | ||
71 | |||
72 | #define ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(thingy, COMMAND, SIZE) \ | ||
73 | ROCCAT_COMMON2_SYSFS_RW(thingy, COMMAND, SIZE); \ | ||
74 | static 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) \ | ||
82 | ROCCAT_COMMON2_SYSFS_R(thingy, COMMAND, SIZE); \ | ||
83 | static 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) \ | ||
90 | ROCCAT_COMMON2_SYSFS_W(thingy, COMMAND, SIZE); \ | ||
91 | static 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 | ||
28 | static struct class *konepure_class; | 28 | enum { |
29 | 29 | KONEPURE_MOUSE_REPORT_NUMBER_BUTTON = 3, | |
30 | static 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 | |||
53 | static 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) \ | ||
75 | static 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) \ | ||
84 | static 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) \ | 32 | struct konepure_mouse_report_button { |
93 | KONEPURE_SYSFS_W(thingy, THINGY) \ | 33 | uint8_t report_number; /* always KONEPURE_MOUSE_REPORT_NUMBER_BUTTON */ |
94 | KONEPURE_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; |
97 | KONEPURE_SYSFS_RW(thingy, THINGY); \ | 37 | uint8_t data2; |
98 | static 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) \ | 42 | static struct class *konepure_class; |
106 | KONEPURE_SYSFS_R(thingy, THINGY); \ | ||
107 | static 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) \ | ||
114 | KONEPURE_SYSFS_W(thingy, THINGY); \ | ||
115 | static 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 | ||
121 | KONEPURE_BIN_ATTRIBUTE_RW(actual_profile, ACTUAL_PROFILE); | 44 | ROCCAT_COMMON2_BIN_ATTRIBUTE_W(control, 0x04, 0x03); |
122 | KONEPURE_BIN_ATTRIBUTE_RW(info, INFO); | 45 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(actual_profile, 0x05, 0x03); |
123 | KONEPURE_BIN_ATTRIBUTE_RW(sensor, SENSOR); | 46 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(profile_settings, 0x06, 0x1f); |
124 | KONEPURE_BIN_ATTRIBUTE_RW(tcu, TCU); | 47 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(profile_buttons, 0x07, 0x3b); |
125 | KONEPURE_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS); | 48 | ROCCAT_COMMON2_BIN_ATTRIBUTE_W(macro, 0x08, 0x0822); |
126 | KONEPURE_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS); | 49 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(info, 0x09, 0x06); |
127 | KONEPURE_BIN_ATTRIBUTE_W(control, CONTROL); | 50 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(tcu, 0x0c, 0x04); |
128 | KONEPURE_BIN_ATTRIBUTE_W(talk, TALK); | 51 | ROCCAT_COMMON2_BIN_ATTRIBUTE_R(tcu_image, 0x0c, 0x0404); |
129 | KONEPURE_BIN_ATTRIBUTE_W(macro, MACRO); | 52 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(sensor, 0x0f, 0x06); |
130 | KONEPURE_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE); | 53 | ROCCAT_COMMON2_BIN_ATTRIBUTE_W(talk, 0x10, 0x10); |
131 | 54 | ||
132 | static struct bin_attribute *konepure_bin_attributes[] = { | 55 | static 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 | ||
146 | static const struct attribute_group konepure_group = { | 69 | static const struct attribute_group konepure_group = { |
147 | .bin_attrs = konepure_bin_attributes, | 70 | .bin_attrs = konepure_bin_attrs, |
148 | }; | 71 | }; |
149 | 72 | ||
150 | static const struct attribute_group *konepure_groups[] = { | 73 | static 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 | |||
156 | static 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 | |||
164 | static int konepure_init_specials(struct hid_device *hdev) | 78 | static 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: | |||
205 | static void konepure_remove_specials(struct hid_device *hdev) | 119 | static 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 | |||
17 | enum { | ||
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 | |||
31 | enum konepure_control_requests { | ||
32 | KONEPURE_CONTROL_REQUEST_GENERAL = 0x80, | ||
33 | KONEPURE_CONTROL_REQUEST_BUTTONS = 0x90, | ||
34 | }; | ||
35 | |||
36 | enum 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 | |||
52 | enum { | ||
53 | KONEPURE_MOUSE_REPORT_NUMBER_BUTTON = 3, | ||
54 | }; | ||
55 | |||
56 | struct 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 | |||
66 | struct 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 | |||
24 | enum { | ||
25 | RYOS_REPORT_NUMBER_SPECIAL = 3, | ||
26 | RYOS_USB_INTERFACE_PROTOCOL = 0, | ||
27 | }; | ||
28 | |||
29 | struct ryos_report_special { | ||
30 | uint8_t number; /* RYOS_REPORT_NUMBER_SPECIAL */ | ||
31 | uint8_t data[4]; | ||
32 | } __packed; | ||
33 | |||
34 | static struct class *ryos_class; | ||
35 | |||
36 | ROCCAT_COMMON2_BIN_ATTRIBUTE_W(control, 0x04, 0x03); | ||
37 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(profile, 0x05, 0x03); | ||
38 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(keys_primary, 0x06, 0x7d); | ||
39 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(keys_function, 0x07, 0x5f); | ||
40 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(keys_macro, 0x08, 0x23); | ||
41 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(keys_thumbster, 0x09, 0x17); | ||
42 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(keys_extra, 0x0a, 0x08); | ||
43 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(keys_easyzone, 0x0b, 0x126); | ||
44 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(key_mask, 0x0c, 0x06); | ||
45 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(light, 0x0d, 0x10); | ||
46 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(macro, 0x0e, 0x7d2); | ||
47 | ROCCAT_COMMON2_BIN_ATTRIBUTE_R(info, 0x0f, 0x08); | ||
48 | ROCCAT_COMMON2_BIN_ATTRIBUTE_W(reset, 0x11, 0x03); | ||
49 | ROCCAT_COMMON2_BIN_ATTRIBUTE_W(light_control, 0x13, 0x08); | ||
50 | ROCCAT_COMMON2_BIN_ATTRIBUTE_W(talk, 0x16, 0x10); | ||
51 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(stored_lights, 0x17, 0x0566); | ||
52 | ROCCAT_COMMON2_BIN_ATTRIBUTE_W(custom_lights, 0x18, 0x14); | ||
53 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(light_macro, 0x19, 0x07d2); | ||
54 | |||
55 | static 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 | |||
77 | static const struct attribute_group ryos_group = { | ||
78 | .bin_attrs = ryos_bin_attrs, | ||
79 | }; | ||
80 | |||
81 | static const struct attribute_group *ryos_groups[] = { | ||
82 | &ryos_group, | ||
83 | NULL, | ||
84 | }; | ||
85 | |||
86 | static 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; | ||
122 | exit_free: | ||
123 | kfree(ryos); | ||
124 | return retval; | ||
125 | } | ||
126 | |||
127 | static 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 | |||
142 | static 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 | |||
167 | exit_stop: | ||
168 | hid_hw_stop(hdev); | ||
169 | exit: | ||
170 | return retval; | ||
171 | } | ||
172 | |||
173 | static void ryos_remove(struct hid_device *hdev) | ||
174 | { | ||
175 | ryos_remove_specials(hdev); | ||
176 | hid_hw_stop(hdev); | ||
177 | } | ||
178 | |||
179 | static 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 | |||
198 | static 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 | |||
205 | MODULE_DEVICE_TABLE(hid, ryos_devices); | ||
206 | |||
207 | static 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 | |||
215 | static 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 | |||
230 | static void __exit ryos_exit(void) | ||
231 | { | ||
232 | hid_unregister_driver(&ryos_driver); | ||
233 | class_destroy(ryos_class); | ||
234 | } | ||
235 | |||
236 | module_init(ryos_init); | ||
237 | module_exit(ryos_exit); | ||
238 | |||
239 | MODULE_AUTHOR("Stefan Achatz"); | ||
240 | MODULE_DESCRIPTION("USB Roccat Ryos MK/Glow/Pro driver"); | ||
241 | MODULE_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 | ||
28 | static struct class *savu_class; | 28 | static struct class *savu_class; |
29 | 29 | ||
30 | static ssize_t savu_sysfs_read(struct file *fp, struct kobject *kobj, | 30 | ROCCAT_COMMON2_BIN_ATTRIBUTE_W(control, 0x4, 0x03); |
31 | char *buf, loff_t off, size_t count, | 31 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(profile, 0x5, 0x03); |
32 | size_t real_size, uint command) | 32 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(general, 0x6, 0x10); |
33 | { | 33 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(buttons, 0x7, 0x2f); |
34 | struct device *dev = | 34 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(macro, 0x8, 0x0823); |
35 | container_of(kobj, struct device, kobj)->parent->parent; | 35 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(info, 0x9, 0x08); |
36 | struct savu_device *savu = hid_get_drvdata(dev_get_drvdata(dev)); | 36 | ROCCAT_COMMON2_BIN_ATTRIBUTE_RW(sensor, 0xc, 0x04); |
37 | struct usb_device *usb_dev = interface_to_usbdev(to_usb_interface(dev)); | 37 | |
38 | int retval; | 38 | static 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 | |||
53 | static 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) \ | ||
75 | static 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) \ | ||
84 | static 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) \ | ||
93 | SAVU_SYSFS_W(thingy, THINGY) \ | ||
94 | SAVU_SYSFS_R(thingy, THINGY) | ||
95 | |||
96 | #define SAVU_BIN_ATTRIBUTE_RW(thingy, THINGY) \ | ||
97 | SAVU_SYSFS_RW(thingy, THINGY); \ | ||
98 | static 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) \ | ||
106 | SAVU_SYSFS_W(thingy, THINGY); \ | ||
107 | static 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 | |||
113 | SAVU_BIN_ATTRIBUTE_W(control, CONTROL); | ||
114 | SAVU_BIN_ATTRIBUTE_RW(profile, PROFILE); | ||
115 | SAVU_BIN_ATTRIBUTE_RW(general, GENERAL); | ||
116 | SAVU_BIN_ATTRIBUTE_RW(buttons, BUTTONS); | ||
117 | SAVU_BIN_ATTRIBUTE_RW(macro, MACRO); | ||
118 | SAVU_BIN_ATTRIBUTE_RW(info, INFO); | ||
119 | SAVU_BIN_ATTRIBUTE_RW(sensor, SENSOR); | ||
120 | |||
121 | static 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 | ||
132 | static const struct attribute_group savu_group = { | 49 | static const struct attribute_group savu_group = { |
133 | .bin_attrs = savu_bin_attributes, | 50 | .bin_attrs = savu_bin_attrs, |
134 | }; | 51 | }; |
135 | 52 | ||
136 | static const struct attribute_group *savu_groups[] = { | 53 | static 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 | ||
141 | static 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 | |||
149 | static int savu_init_specials(struct hid_device *hdev) | 58 | static 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: | |||
190 | static void savu_remove_specials(struct hid_device *hdev) | 99 | static 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 | ||
242 | static void savu_report_to_chrdev(struct savu_device const *savu, | 151 | static 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 | ||
17 | enum { | ||
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 | |||
27 | enum savu_control_requests { | ||
28 | SAVU_CONTROL_REQUEST_GENERAL = 0x80, | ||
29 | SAVU_CONTROL_REQUEST_BUTTONS = 0x90, | ||
30 | }; | ||
31 | |||
32 | enum 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 | |||
42 | struct savu_mouse_report_special { | 17 | struct 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 | ||
80 | struct 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 88fc5aefcd96..a184e1921c11 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 | */ |
420 | static int sixaxis_set_operational_usb(struct hid_device *hdev) | 420 | static 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 | ||
618 | static 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 | |||
648 | static 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 | ||
659 | static int sony_init_ff(struct hid_device *hdev) | ||
660 | { | ||
661 | return 0; | ||
662 | } | ||
663 | #endif | ||
664 | |||
624 | static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) | 665 | static 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; |
674 | err_stop: | 719 | err_stop: |
675 | hid_hw_stop(hdev); | 720 | hid_hw_stop(hdev); |
diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c index 71adf9e60b13..6b61f01e01e7 100644 --- a/drivers/hid/hid-wiimote-modules.c +++ b/drivers/hid/hid-wiimote-modules.c | |||
@@ -1655,10 +1655,39 @@ static void wiimod_pro_in_ext(struct wiimote_data *wdata, const __u8 *ext) | |||
1655 | ly = (ext[4] & 0xff) | ((ext[5] & 0x0f) << 8); | 1655 | ly = (ext[4] & 0xff) | ((ext[5] & 0x0f) << 8); |
1656 | ry = (ext[6] & 0xff) | ((ext[7] & 0x0f) << 8); | 1656 | ry = (ext[6] & 0xff) | ((ext[7] & 0x0f) << 8); |
1657 | 1657 | ||
1658 | input_report_abs(wdata->extension.input, ABS_X, lx - 0x800); | 1658 | /* zero-point offsets */ |
1659 | input_report_abs(wdata->extension.input, ABS_Y, ly - 0x800); | 1659 | lx -= 0x800; |
1660 | input_report_abs(wdata->extension.input, ABS_RX, rx - 0x800); | 1660 | ly = 0x800 - ly; |
1661 | input_report_abs(wdata->extension.input, ABS_RY, ry - 0x800); | 1661 | rx -= 0x800; |
1662 | ry = 0x800 - ry; | ||
1663 | |||
1664 | /* Trivial automatic calibration. We don't know any calibration data | ||
1665 | * in the EEPROM so we must use the first report to calibrate the | ||
1666 | * null-position of the analog sticks. Users can retrigger calibration | ||
1667 | * via sysfs, or set it explicitly. If data is off more than abs(500), | ||
1668 | * we skip calibration as the sticks are likely to be moved already. */ | ||
1669 | if (!(wdata->state.flags & WIIPROTO_FLAG_PRO_CALIB_DONE)) { | ||
1670 | wdata->state.flags |= WIIPROTO_FLAG_PRO_CALIB_DONE; | ||
1671 | if (abs(lx) < 500) | ||
1672 | wdata->state.calib_pro_sticks[0] = -lx; | ||
1673 | if (abs(ly) < 500) | ||
1674 | wdata->state.calib_pro_sticks[1] = -ly; | ||
1675 | if (abs(rx) < 500) | ||
1676 | wdata->state.calib_pro_sticks[2] = -rx; | ||
1677 | if (abs(ry) < 500) | ||
1678 | wdata->state.calib_pro_sticks[3] = -ry; | ||
1679 | } | ||
1680 | |||
1681 | /* apply calibration data */ | ||
1682 | lx += wdata->state.calib_pro_sticks[0]; | ||
1683 | ly += wdata->state.calib_pro_sticks[1]; | ||
1684 | rx += wdata->state.calib_pro_sticks[2]; | ||
1685 | ry += wdata->state.calib_pro_sticks[3]; | ||
1686 | |||
1687 | input_report_abs(wdata->extension.input, ABS_X, lx); | ||
1688 | input_report_abs(wdata->extension.input, ABS_Y, ly); | ||
1689 | input_report_abs(wdata->extension.input, ABS_RX, rx); | ||
1690 | input_report_abs(wdata->extension.input, ABS_RY, ry); | ||
1662 | 1691 | ||
1663 | input_report_key(wdata->extension.input, | 1692 | input_report_key(wdata->extension.input, |
1664 | wiimod_pro_map[WIIMOD_PRO_KEY_RIGHT], | 1693 | wiimod_pro_map[WIIMOD_PRO_KEY_RIGHT], |
@@ -1766,12 +1795,70 @@ static int wiimod_pro_play(struct input_dev *dev, void *data, | |||
1766 | return 0; | 1795 | return 0; |
1767 | } | 1796 | } |
1768 | 1797 | ||
1798 | static ssize_t wiimod_pro_calib_show(struct device *dev, | ||
1799 | struct device_attribute *attr, | ||
1800 | char *out) | ||
1801 | { | ||
1802 | struct wiimote_data *wdata = dev_to_wii(dev); | ||
1803 | int r; | ||
1804 | |||
1805 | r = 0; | ||
1806 | r += sprintf(&out[r], "%+06hd:", wdata->state.calib_pro_sticks[0]); | ||
1807 | r += sprintf(&out[r], "%+06hd ", wdata->state.calib_pro_sticks[1]); | ||
1808 | r += sprintf(&out[r], "%+06hd:", wdata->state.calib_pro_sticks[2]); | ||
1809 | r += sprintf(&out[r], "%+06hd\n", wdata->state.calib_pro_sticks[3]); | ||
1810 | |||
1811 | return r; | ||
1812 | } | ||
1813 | |||
1814 | static ssize_t wiimod_pro_calib_store(struct device *dev, | ||
1815 | struct device_attribute *attr, | ||
1816 | const char *buf, size_t count) | ||
1817 | { | ||
1818 | struct wiimote_data *wdata = dev_to_wii(dev); | ||
1819 | int r; | ||
1820 | s16 x1, y1, x2, y2; | ||
1821 | |||
1822 | if (!strncmp(buf, "scan\n", 5)) { | ||
1823 | spin_lock_irq(&wdata->state.lock); | ||
1824 | wdata->state.flags &= ~WIIPROTO_FLAG_PRO_CALIB_DONE; | ||
1825 | spin_unlock_irq(&wdata->state.lock); | ||
1826 | } else { | ||
1827 | r = sscanf(buf, "%hd:%hd %hd:%hd", &x1, &y1, &x2, &y2); | ||
1828 | if (r != 4) | ||
1829 | return -EINVAL; | ||
1830 | |||
1831 | spin_lock_irq(&wdata->state.lock); | ||
1832 | wdata->state.flags |= WIIPROTO_FLAG_PRO_CALIB_DONE; | ||
1833 | spin_unlock_irq(&wdata->state.lock); | ||
1834 | |||
1835 | wdata->state.calib_pro_sticks[0] = x1; | ||
1836 | wdata->state.calib_pro_sticks[1] = y1; | ||
1837 | wdata->state.calib_pro_sticks[2] = x2; | ||
1838 | wdata->state.calib_pro_sticks[3] = y2; | ||
1839 | } | ||
1840 | |||
1841 | return strnlen(buf, PAGE_SIZE); | ||
1842 | } | ||
1843 | |||
1844 | static DEVICE_ATTR(pro_calib, S_IRUGO|S_IWUSR|S_IWGRP, wiimod_pro_calib_show, | ||
1845 | wiimod_pro_calib_store); | ||
1846 | |||
1769 | static int wiimod_pro_probe(const struct wiimod_ops *ops, | 1847 | static int wiimod_pro_probe(const struct wiimod_ops *ops, |
1770 | struct wiimote_data *wdata) | 1848 | struct wiimote_data *wdata) |
1771 | { | 1849 | { |
1772 | int ret, i; | 1850 | int ret, i; |
1851 | unsigned long flags; | ||
1773 | 1852 | ||
1774 | INIT_WORK(&wdata->rumble_worker, wiimod_rumble_worker); | 1853 | INIT_WORK(&wdata->rumble_worker, wiimod_rumble_worker); |
1854 | wdata->state.calib_pro_sticks[0] = 0; | ||
1855 | wdata->state.calib_pro_sticks[1] = 0; | ||
1856 | wdata->state.calib_pro_sticks[2] = 0; | ||
1857 | wdata->state.calib_pro_sticks[3] = 0; | ||
1858 | |||
1859 | spin_lock_irqsave(&wdata->state.lock, flags); | ||
1860 | wdata->state.flags &= ~WIIPROTO_FLAG_PRO_CALIB_DONE; | ||
1861 | spin_unlock_irqrestore(&wdata->state.lock, flags); | ||
1775 | 1862 | ||
1776 | wdata->extension.input = input_allocate_device(); | 1863 | wdata->extension.input = input_allocate_device(); |
1777 | if (!wdata->extension.input) | 1864 | if (!wdata->extension.input) |
@@ -1786,6 +1873,13 @@ static int wiimod_pro_probe(const struct wiimod_ops *ops, | |||
1786 | goto err_free; | 1873 | goto err_free; |
1787 | } | 1874 | } |
1788 | 1875 | ||
1876 | ret = device_create_file(&wdata->hdev->dev, | ||
1877 | &dev_attr_pro_calib); | ||
1878 | if (ret) { | ||
1879 | hid_err(wdata->hdev, "cannot create sysfs attribute\n"); | ||
1880 | goto err_free; | ||
1881 | } | ||
1882 | |||
1789 | wdata->extension.input->open = wiimod_pro_open; | 1883 | wdata->extension.input->open = wiimod_pro_open; |
1790 | wdata->extension.input->close = wiimod_pro_close; | 1884 | wdata->extension.input->close = wiimod_pro_close; |
1791 | wdata->extension.input->dev.parent = &wdata->hdev->dev; | 1885 | wdata->extension.input->dev.parent = &wdata->hdev->dev; |
@@ -1806,20 +1900,23 @@ static int wiimod_pro_probe(const struct wiimod_ops *ops, | |||
1806 | set_bit(ABS_RX, wdata->extension.input->absbit); | 1900 | set_bit(ABS_RX, wdata->extension.input->absbit); |
1807 | set_bit(ABS_RY, wdata->extension.input->absbit); | 1901 | set_bit(ABS_RY, wdata->extension.input->absbit); |
1808 | input_set_abs_params(wdata->extension.input, | 1902 | input_set_abs_params(wdata->extension.input, |
1809 | ABS_X, -0x800, 0x800, 2, 4); | 1903 | ABS_X, -0x400, 0x400, 4, 100); |
1810 | input_set_abs_params(wdata->extension.input, | 1904 | input_set_abs_params(wdata->extension.input, |
1811 | ABS_Y, -0x800, 0x800, 2, 4); | 1905 | ABS_Y, -0x400, 0x400, 4, 100); |
1812 | input_set_abs_params(wdata->extension.input, | 1906 | input_set_abs_params(wdata->extension.input, |
1813 | ABS_RX, -0x800, 0x800, 2, 4); | 1907 | ABS_RX, -0x400, 0x400, 4, 100); |
1814 | input_set_abs_params(wdata->extension.input, | 1908 | input_set_abs_params(wdata->extension.input, |
1815 | ABS_RY, -0x800, 0x800, 2, 4); | 1909 | ABS_RY, -0x400, 0x400, 4, 100); |
1816 | 1910 | ||
1817 | ret = input_register_device(wdata->extension.input); | 1911 | ret = input_register_device(wdata->extension.input); |
1818 | if (ret) | 1912 | if (ret) |
1819 | goto err_free; | 1913 | goto err_file; |
1820 | 1914 | ||
1821 | return 0; | 1915 | return 0; |
1822 | 1916 | ||
1917 | err_file: | ||
1918 | device_remove_file(&wdata->hdev->dev, | ||
1919 | &dev_attr_pro_calib); | ||
1823 | err_free: | 1920 | err_free: |
1824 | input_free_device(wdata->extension.input); | 1921 | input_free_device(wdata->extension.input); |
1825 | wdata->extension.input = NULL; | 1922 | wdata->extension.input = NULL; |
@@ -1837,6 +1934,8 @@ static void wiimod_pro_remove(const struct wiimod_ops *ops, | |||
1837 | input_unregister_device(wdata->extension.input); | 1934 | input_unregister_device(wdata->extension.input); |
1838 | wdata->extension.input = NULL; | 1935 | wdata->extension.input = NULL; |
1839 | cancel_work_sync(&wdata->rumble_worker); | 1936 | cancel_work_sync(&wdata->rumble_worker); |
1937 | device_remove_file(&wdata->hdev->dev, | ||
1938 | &dev_attr_pro_calib); | ||
1840 | 1939 | ||
1841 | spin_lock_irqsave(&wdata->state.lock, flags); | 1940 | spin_lock_irqsave(&wdata->state.lock, flags); |
1842 | wiiproto_req_rumble(wdata, 0); | 1941 | wiiproto_req_rumble(wdata, 0); |
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h index cfa63b0825b0..10934aa129fb 100644 --- a/drivers/hid/hid-wiimote.h +++ b/drivers/hid/hid-wiimote.h | |||
@@ -46,6 +46,7 @@ | |||
46 | #define WIIPROTO_FLAG_DRM_LOCKED 0x8000 | 46 | #define WIIPROTO_FLAG_DRM_LOCKED 0x8000 |
47 | #define WIIPROTO_FLAG_BUILTIN_MP 0x010000 | 47 | #define WIIPROTO_FLAG_BUILTIN_MP 0x010000 |
48 | #define WIIPROTO_FLAG_NO_MP 0x020000 | 48 | #define WIIPROTO_FLAG_NO_MP 0x020000 |
49 | #define WIIPROTO_FLAG_PRO_CALIB_DONE 0x040000 | ||
49 | 50 | ||
50 | #define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \ | 51 | #define WIIPROTO_FLAGS_LEDS (WIIPROTO_FLAG_LED1 | WIIPROTO_FLAG_LED2 | \ |
51 | WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4) | 52 | WIIPROTO_FLAG_LED3 | WIIPROTO_FLAG_LED4) |
@@ -135,6 +136,7 @@ struct wiimote_state { | |||
135 | 136 | ||
136 | /* calibration/cache data */ | 137 | /* calibration/cache data */ |
137 | __u16 calib_bboard[4][3]; | 138 | __u16 calib_bboard[4][3]; |
139 | __s16 calib_pro_sticks[4]; | ||
138 | __u8 cache_rumble; | 140 | __u8 cache_rumble; |
139 | }; | 141 | }; |
140 | 142 | ||
diff --git a/drivers/hid/i2c-hid/i2c-hid.c b/drivers/hid/i2c-hid/i2c-hid.c index fd7ce374f812..ae48d18ee315 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 }, |