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 | |
| 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
...
31 files changed, 1168 insertions, 451 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-ryos b/Documentation/ABI/testing/sysfs-driver-hid-roccat-ryos new file mode 100644 index 000000000000..1d6a8cf9dc0a --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-ryos | |||
| @@ -0,0 +1,178 @@ | |||
| 1 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/control | ||
| 2 | Date: October 2013 | ||
| 3 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 4 | Description: When written, this file lets one select which data from which | ||
| 5 | profile will be read next. The data has to be 3 bytes long. | ||
| 6 | This file is writeonly. | ||
| 7 | Users: http://roccat.sourceforge.net | ||
| 8 | |||
| 9 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/profile | ||
| 10 | Date: October 2013 | ||
| 11 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 12 | Description: The mouse can store 5 profiles which can be switched by the | ||
| 13 | press of a button. profile holds index of actual profile. | ||
| 14 | This value is persistent, so its value determines the profile | ||
| 15 | that's active when the device is powered on next time. | ||
| 16 | When written, the device activates the set profile immediately. | ||
| 17 | The data has to be 3 bytes long. | ||
| 18 | The device will reject invalid data. | ||
| 19 | Users: http://roccat.sourceforge.net | ||
| 20 | |||
| 21 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/keys_primary | ||
| 22 | Date: October 2013 | ||
| 23 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 24 | Description: When written, this file lets one set the default of all keys for | ||
| 25 | a specific profile. Profile index is included in written data. | ||
| 26 | The data has to be 125 bytes long. | ||
| 27 | Before reading this file, control has to be written to select | ||
| 28 | which profile to read. | ||
| 29 | Users: http://roccat.sourceforge.net | ||
| 30 | |||
| 31 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/keys_function | ||
| 32 | Date: October 2013 | ||
| 33 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 34 | Description: When written, this file lets one set the function of the | ||
| 35 | function keys for a specific profile. Profile index is included | ||
| 36 | in written data. The data has to be 95 bytes long. | ||
| 37 | Before reading this file, control has to be written to select | ||
| 38 | which profile to read. | ||
| 39 | Users: http://roccat.sourceforge.net | ||
| 40 | |||
| 41 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/keys_macro | ||
| 42 | Date: October 2013 | ||
| 43 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 44 | Description: When written, this file lets one set the function of the macro | ||
| 45 | keys for a specific profile. Profile index is included in | ||
| 46 | written data. The data has to be 35 bytes long. | ||
| 47 | Before reading this file, control has to be written to select | ||
| 48 | which profile to read. | ||
| 49 | Users: http://roccat.sourceforge.net | ||
| 50 | |||
| 51 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/keys_thumbster | ||
| 52 | Date: October 2013 | ||
| 53 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 54 | Description: When written, this file lets one set the function of the | ||
| 55 | thumbster keys for a specific profile. Profile index is included | ||
| 56 | in written data. The data has to be 23 bytes long. | ||
| 57 | Before reading this file, control has to be written to select | ||
| 58 | which profile to read. | ||
| 59 | Users: http://roccat.sourceforge.net | ||
| 60 | |||
| 61 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/keys_extra | ||
| 62 | Date: October 2013 | ||
| 63 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 64 | Description: When written, this file lets one set the function of the | ||
| 65 | capslock and function keys for a specific profile. Profile index | ||
| 66 | is included in written data. The data has to be 8 bytes long. | ||
| 67 | Before reading this file, control has to be written to select | ||
| 68 | which profile to read. | ||
| 69 | Users: http://roccat.sourceforge.net | ||
| 70 | |||
| 71 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/keys_easyzone | ||
| 72 | Date: October 2013 | ||
| 73 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 74 | Description: When written, this file lets one set the function of the | ||
| 75 | easyzone keys for a specific profile. Profile index is included | ||
| 76 | in written data. The data has to be 294 bytes long. | ||
| 77 | Before reading this file, control has to be written to select | ||
| 78 | which profile to read. | ||
| 79 | Users: http://roccat.sourceforge.net | ||
| 80 | |||
| 81 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/key_mask | ||
| 82 | Date: October 2013 | ||
| 83 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 84 | Description: When written, this file lets one deactivate certain keys like | ||
| 85 | windows and application keys, to prevent accidental presses. | ||
| 86 | Profile index for which this settings occur is included in | ||
| 87 | written data. The data has to be 6 bytes long. | ||
| 88 | Before reading this file, control has to be written to select | ||
| 89 | which profile to read. | ||
| 90 | Users: http://roccat.sourceforge.net | ||
| 91 | |||
| 92 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/light | ||
| 93 | Date: October 2013 | ||
| 94 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 95 | Description: When written, this file lets one set the backlight intensity for | ||
| 96 | a specific profile. Profile index is included in written data. | ||
| 97 | This attribute is only valid for the glow and pro variant. | ||
| 98 | The data has to be 16 bytes long. | ||
| 99 | Before reading this file, control has to be written to select | ||
| 100 | which profile to read. | ||
| 101 | Users: http://roccat.sourceforge.net | ||
| 102 | |||
| 103 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/macro | ||
| 104 | Date: October 2013 | ||
| 105 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 106 | Description: When written, this file lets one store macros with max 480 | ||
| 107 | keystrokes for a specific button for a specific profile. | ||
| 108 | Button and profile indexes are included in written data. | ||
| 109 | The data has to be 2002 bytes long. | ||
| 110 | Before reading this file, control has to be written to select | ||
| 111 | which profile and key to read. | ||
| 112 | Users: http://roccat.sourceforge.net | ||
| 113 | |||
| 114 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/info | ||
| 115 | Date: October 2013 | ||
| 116 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 117 | Description: When read, this file returns general data like firmware version. | ||
| 118 | The data is 8 bytes long. | ||
| 119 | This file is readonly. | ||
| 120 | Users: http://roccat.sourceforge.net | ||
| 121 | |||
| 122 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/reset | ||
| 123 | Date: October 2013 | ||
| 124 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 125 | Description: When written, this file lets one reset the device. | ||
| 126 | The data has to be 3 bytes long. | ||
| 127 | This file is writeonly. | ||
| 128 | Users: http://roccat.sourceforge.net | ||
| 129 | |||
| 130 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/talk | ||
| 131 | Date: October 2013 | ||
| 132 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 133 | Description: When written, this file lets one trigger easyshift functionality | ||
| 134 | from the host. | ||
| 135 | The data has to be 16 bytes long. | ||
| 136 | This file is writeonly. | ||
| 137 | Users: http://roccat.sourceforge.net | ||
| 138 | |||
| 139 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/light_control | ||
| 140 | Date: October 2013 | ||
| 141 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 142 | Description: When written, this file lets one switch between stored and custom | ||
| 143 | light settings. | ||
| 144 | This attribute is only valid for the pro variant. | ||
| 145 | The data has to be 8 bytes long. | ||
| 146 | This file is writeonly. | ||
| 147 | Users: http://roccat.sourceforge.net | ||
| 148 | |||
| 149 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/stored_lights | ||
| 150 | Date: October 2013 | ||
| 151 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 152 | Description: When written, this file lets one set per-key lighting for different | ||
| 153 | layers. | ||
| 154 | This attribute is only valid for the pro variant. | ||
| 155 | The data has to be 1382 bytes long. | ||
| 156 | Before reading this file, control has to be written to select | ||
| 157 | which profile to read. | ||
| 158 | Users: http://roccat.sourceforge.net | ||
| 159 | |||
| 160 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/custom_lights | ||
| 161 | Date: October 2013 | ||
| 162 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 163 | Description: When written, this file lets one set the actual per-key lighting. | ||
| 164 | This attribute is only valid for the pro variant. | ||
| 165 | The data has to be 20 bytes long. | ||
| 166 | This file is writeonly. | ||
| 167 | Users: http://roccat.sourceforge.net | ||
| 168 | |||
| 169 | What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/ryos/roccatryos<minor>/light_macro | ||
| 170 | Date: October 2013 | ||
| 171 | Contact: Stefan Achatz <erazor_de@users.sourceforge.net> | ||
| 172 | Description: When written, this file lets one set a light macro that is looped | ||
| 173 | whenever the device gets in dimness mode. | ||
| 174 | This attribute is only valid for the pro variant. | ||
| 175 | The data has to be 2002 bytes long. | ||
| 176 | Before reading this file, control has to be written to select | ||
| 177 | which profile to read. | ||
| 178 | Users: http://roccat.sourceforge.net | ||
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-wiimote b/Documentation/ABI/testing/sysfs-driver-hid-wiimote index ed5dd567d397..39dfa5cb1cc5 100644 --- a/Documentation/ABI/testing/sysfs-driver-hid-wiimote +++ b/Documentation/ABI/testing/sysfs-driver-hid-wiimote | |||
| @@ -57,3 +57,21 @@ Description: This attribute is only provided if the device was detected as a | |||
| 57 | Calibration data is already applied by the kernel to all input | 57 | Calibration data is already applied by the kernel to all input |
| 58 | values but may be used by user-space to perform other | 58 | values but may be used by user-space to perform other |
| 59 | transformations. | 59 | transformations. |
| 60 | |||
| 61 | What: /sys/bus/hid/drivers/wiimote/<dev>/pro_calib | ||
| 62 | Date: October 2013 | ||
| 63 | KernelVersion: 3.13 | ||
| 64 | Contact: David Herrmann <dh.herrmann@gmail.com> | ||
| 65 | Description: This attribute is only provided if the device was detected as a | ||
| 66 | pro-controller. It provides a single line with 4 calibration | ||
| 67 | values for all 4 analog sticks. Format is: "x1:y1 x2:y2". Data | ||
| 68 | is prefixed with a +/-. Each value is a signed 16bit number. | ||
| 69 | Data is encoded as decimal numbers and specifies the offsets of | ||
| 70 | the analog sticks of the pro-controller. | ||
| 71 | Calibration data is already applied by the kernel to all input | ||
| 72 | values but may be used by user-space to perform other | ||
| 73 | transformations. | ||
| 74 | Calibration data is detected by the kernel during device setup. | ||
| 75 | You can write "scan\n" into this file to re-trigger calibration. | ||
| 76 | You can also write data directly in the form "x1:y1 x2:y2" to | ||
| 77 | set the calibration values manually. | ||
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 }, |
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index 721fdb3597ca..ae4b6b903629 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c | |||
| @@ -146,12 +146,10 @@ enum { | |||
| 146 | 146 | ||
| 147 | #define USB_DEVICE_HID_CLASS(vend, prod) \ | 147 | #define USB_DEVICE_HID_CLASS(vend, prod) \ |
| 148 | .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS \ | 148 | .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS \ |
| 149 | | USB_DEVICE_ID_MATCH_INT_PROTOCOL \ | ||
| 150 | | USB_DEVICE_ID_MATCH_DEVICE, \ | 149 | | USB_DEVICE_ID_MATCH_DEVICE, \ |
| 151 | .idVendor = (vend), \ | 150 | .idVendor = (vend), \ |
| 152 | .idProduct = (prod), \ | 151 | .idProduct = (prod), \ |
| 153 | .bInterfaceClass = USB_INTERFACE_CLASS_HID, \ | 152 | .bInterfaceClass = USB_INTERFACE_CLASS_HID |
| 154 | .bInterfaceProtocol = USB_INTERFACE_PROTOCOL_MOUSE | ||
| 155 | 153 | ||
| 156 | static const struct usb_device_id usbtouch_devices[] = { | 154 | static const struct usb_device_id usbtouch_devices[] = { |
| 157 | #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX | 155 | #ifdef CONFIG_TOUCHSCREEN_USB_EGALAX |
