Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid

Pull HID updates from Jiri Kosina:
"Highlights:

- Intel Skylake Win8 precision touchpads support fixes/improvements
from Mika Westerberg

- Lenovo Yoga 2 quirk from Ritesh Raj Sarraf

- potential uninitialized buffer access fix in HID core from Richard
Purdie

- Wacom Intuos and Wacom Cintiq 2 support improvements from Jason
Gerecke and Ping Cheng

- initiation of sysfs deprecation process for most of the roccat
drivers, from the roccat support maintiner Stefan Achatz

- quite a few device ID / quirk additions and small fixes"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid: (30 commits)
HID: logitech: Add support for G29
HID: logitech: Simplify wheel detection scheme
HID: wacom: Call 'wacom_query_tablet_data' only after 'hid_hw_start'
HID: wacom: Fix ABS_MISC reporting for Cintiq Companion 2
HID: wacom: Remove useless conditions from 'wacom_query_tablet_data'
HID: wacom: fix Intuos wireless report id issue
HID: fix some indenting issues
HID: wacom: Expect 'touch_max' touches if HID_DG_CONTACTCOUNT not present
HID: wacom: Tie cached HID_DG_CONTACTCOUNT indices to report ID
HID: roccat: Fixed resubmit: Deprecating most Roccat sysfs attributes
HID: wacom: Report full pressure range for Intuos, Cintiq 13HD Touch
HID: wacom: Add support for Cintiq Companion 2
HID: multitouch: Fetch feature reports on demand for Win8 devices
HID: sensor-hub: Add quirk for Lenovo Yoga 2 with ITE Chips
HID: usbhid: Fix for the WiiU adapter from Mayflash
HID: corsair: boolify struct k90_led.removed
HID: corsair: Add Corsair Vengeance K90 driver
HID: hid-input: allow input_configured callback return errors
HID: multitouch: Add suffix for HID_DG_TOUCHPAD
HID: i2c-hid: Fill in physical device providing HID functionality
...

+1491 -322
+97
Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus
··· 1 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/actual_profile 2 + Date: October 2010 3 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 4 + Description: The integer value of this attribute ranges from 0-4. 5 + When read, this attribute returns the number of the actual 6 + profile. This value is persistent, so its equivalent to the 7 + profile that's active when the mouse is powered on next time. 8 + When written, this file sets the number of the startup profile 9 + and the mouse activates this profile immediately. 10 + Users: http://roccat.sourceforge.net 11 + 1 12 What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/startup_profile 2 13 Date: October 2010 3 14 Contact: Stefan Achatz <erazor_de@users.sourceforge.net> ··· 33 22 Please read binary attribute info which contains firmware version. 34 23 Users: http://roccat.sourceforge.net 35 24 25 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/info 26 + Date: November 2012 27 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 28 + Description: When read, this file returns general data like firmware version. 29 + When written, the device can be reset. 30 + The data is 8 bytes long. 31 + Users: http://roccat.sourceforge.net 32 + 33 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/macro 34 + Date: October 2010 35 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 36 + Description: The mouse can store a macro with max 500 key/button strokes 37 + internally. 38 + When written, this file lets one set the sequence for a specific 39 + button for a specific profile. Button and profile numbers are 40 + included in written data. The data has to be 2082 bytes long. 41 + This file is writeonly. 42 + Users: http://roccat.sourceforge.net 43 + 44 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile_buttons 45 + Date: August 2010 46 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 47 + Description: The mouse can store 5 profiles which can be switched by the 48 + press of a button. A profile is split in settings and buttons. 49 + profile_buttons holds information about button layout. 50 + When written, this file lets one write the respective profile 51 + buttons back to the mouse. The data has to be 77 bytes long. 52 + The mouse will reject invalid data. 53 + Which profile to write is determined by the profile number 54 + contained in the data. 55 + Before reading this file, control has to be written to select 56 + which profile to read. 57 + Users: http://roccat.sourceforge.net 58 + 36 59 What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile[1-5]_buttons 37 60 Date: August 2010 38 61 Contact: Stefan Achatz <erazor_de@users.sourceforge.net> ··· 77 32 The returned data is 77 bytes in size. 78 33 This file is readonly. 79 34 Write control to select profile and read profile_buttons instead. 35 + Users: http://roccat.sourceforge.net 36 + 37 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile_settings 38 + Date: October 2010 39 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 40 + Description: The mouse can store 5 profiles which can be switched by the 41 + press of a button. A profile is split in settings and buttons. 42 + profile_settings holds information like resolution, sensitivity 43 + and light effects. 44 + When written, this file lets one write the respective profile 45 + settings back to the mouse. The data has to be 43 bytes long. 46 + The mouse will reject invalid data. 47 + Which profile to write is determined by the profile number 48 + contained in the data. 49 + Before reading this file, control has to be written to select 50 + which profile to read. 80 51 Users: http://roccat.sourceforge.net 81 52 82 53 What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile[1-5]_settings ··· 106 45 The returned data is 43 bytes in size. 107 46 This file is readonly. 108 47 Write control to select profile and read profile_settings instead. 48 + Users: http://roccat.sourceforge.net 49 + 50 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/sensor 51 + Date: October 2010 52 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 53 + Description: The mouse has a tracking- and a distance-control-unit. These 54 + can be activated/deactivated and the lift-off distance can be 55 + set. The data has to be 6 bytes long. 56 + This file is writeonly. 57 + Users: http://roccat.sourceforge.net 58 + 59 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/talk 60 + Date: May 2011 61 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 62 + Description: Used to active some easy* functions of the mouse from outside. 63 + The data has to be 16 bytes long. 64 + This file is writeonly. 65 + Users: http://roccat.sourceforge.net 66 + 67 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu 68 + Date: October 2010 69 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 70 + Description: When written a calibration process for the tracking control unit 71 + can be initiated/cancelled. Also lets one read/write sensor 72 + registers. 73 + The data has to be 4 bytes long. 74 + Users: http://roccat.sourceforge.net 75 + 76 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu_image 77 + Date: October 2010 78 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 79 + Description: When read the mouse returns a 30x30 pixel image of the 80 + sampled underground. This works only in the course of a 81 + calibration process initiated with tcu. 82 + The returned data is 1028 bytes in size. 83 + This file is readonly. 109 84 Users: http://roccat.sourceforge.net
+50
Documentation/ABI/obsolete/sysfs-driver-hid-roccat-kovaplus
··· 8 8 Has never been used. If bookkeeping is done, it's done in userland tools. 9 9 Users: http://roccat.sourceforge.net 10 10 11 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_profile 12 + Date: January 2011 13 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 14 + Description: The integer value of this attribute ranges from 0-4. 15 + When read, this attribute returns the number of the active 16 + profile. 17 + When written, the mouse activates this profile immediately. 18 + The profile that's active when powered down is the same that's 19 + active when the mouse is powered on. 20 + Users: http://roccat.sourceforge.net 21 + 11 22 What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_sensitivity_x 12 23 Date: January 2011 13 24 Contact: Stefan Achatz <erazor_de@users.sourceforge.net> ··· 51 40 Obsoleted by binary sysfs attribute "info". 52 41 Users: http://roccat.sourceforge.net 53 42 43 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/info 44 + Date: November 2012 45 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 46 + Description: When read, this file returns general data like firmware version. 47 + When written, the device can be reset. 48 + The data is 6 bytes long. 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>/kovaplus/roccatkovaplus<minor>/profile_buttons 52 + Date: January 2011 53 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 54 + Description: The mouse can store 5 profiles which can be switched by the 55 + press of a button. A profile is split in settings and buttons. 56 + profile_buttons holds information about button layout. 57 + When written, this file lets one write the respective profile 58 + buttons back to the mouse. The data has to be 23 bytes long. 59 + The mouse will reject invalid data. 60 + Which profile to write is determined by the profile number 61 + contained in the data. 62 + Before reading this file, control has to be written to select 63 + which profile to read. 64 + Users: http://roccat.sourceforge.net 65 + 54 66 What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile[1-5]_buttons 55 67 Date: January 2011 56 68 Contact: Stefan Achatz <erazor_de@users.sourceforge.net> ··· 84 50 The returned data is 23 bytes in size. 85 51 This file is readonly. 86 52 Write control to select profile and read profile_buttons instead. 53 + Users: http://roccat.sourceforge.net 54 + 55 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile_settings 56 + Date: January 2011 57 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 58 + Description: The mouse can store 5 profiles which can be switched by the 59 + press of a button. A profile is split in settings and buttons. 60 + profile_settings holds information like resolution, sensitivity 61 + and light effects. 62 + When written, this file lets one write the respective profile 63 + settings back to the mouse. The data has to be 16 bytes long. 64 + The mouse will reject invalid data. 65 + Which profile to write is determined by the profile number 66 + contained in the data. 67 + Before reading this file, control has to be written to select 68 + which profile to read. 87 69 Users: http://roccat.sourceforge.net 88 70 89 71 What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile[1-5]_settings
+50
Documentation/ABI/obsolete/sysfs-driver-hid-roccat-pyra
··· 37 37 Please use binary attribute "info" which provides this information. 38 38 Users: http://roccat.sourceforge.net 39 39 40 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/info 41 + Date: November 2012 42 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 43 + Description: When read, this file returns general data like firmware version. 44 + When written, the device can be reset. 45 + The data is 6 bytes long. 46 + Users: http://roccat.sourceforge.net 47 + 48 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile_buttons 49 + Date: August 2010 50 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 51 + Description: The mouse can store 5 profiles which can be switched by the 52 + press of a button. A profile is split in settings and buttons. 53 + profile_buttons holds information about button layout. 54 + When written, this file lets one write the respective profile 55 + buttons back to the mouse. The data has to be 19 bytes long. 56 + The mouse will reject invalid data. 57 + Which profile to write is determined by the profile number 58 + contained in the data. 59 + Before reading this file, control has to be written to select 60 + which profile to read. 61 + Users: http://roccat.sourceforge.net 62 + 40 63 What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile[1-5]_buttons 41 64 Date: August 2010 42 65 Contact: Stefan Achatz <erazor_de@users.sourceforge.net> ··· 70 47 The returned data is 19 bytes in size. 71 48 This file is readonly. 72 49 Write control to select profile and read profile_buttons instead. 50 + Users: http://roccat.sourceforge.net 51 + 52 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile_settings 53 + Date: August 2010 54 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 55 + Description: The mouse can store 5 profiles which can be switched by the 56 + press of a button. A profile is split in settings and buttons. 57 + profile_settings holds information like resolution, sensitivity 58 + and light effects. 59 + When written, this file lets one write the respective profile 60 + settings back to the mouse. The data has to be 13 bytes long. 61 + The mouse will reject invalid data. 62 + Which profile to write is determined by the profile number 63 + contained in the data. 64 + Before reading this file, control has to be written to select 65 + which profile to read. 73 66 Users: http://roccat.sourceforge.net 74 67 75 68 What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile[1-5]_settings ··· 99 60 The returned data is 13 bytes in size. 100 61 This file is readonly. 101 62 Write control to select profile and read profile_settings instead. 63 + Users: http://roccat.sourceforge.net 64 + 65 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/settings 66 + Date: August 2010 67 + Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 68 + Description: When read, this file returns the settings stored in the mouse. 69 + The size of the data is 3 bytes and holds information on the 70 + startup_profile. 71 + When written, this file lets write settings back to the mouse. 72 + The data has to be 3 bytes long. The mouse will reject invalid 73 + data. 102 74 Users: http://roccat.sourceforge.net 103 75 104 76 What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/startup_profile
+15
Documentation/ABI/testing/sysfs-driver-hid-corsair
··· 1 + What: /sys/bus/drivers/corsair/<dev>/macro_mode 2 + Date: August 2015 3 + KernelVersion: 4.2 4 + Contact: Clement Vuchener <clement.vuchener@gmail.com> 5 + Description: Get/set the current playback mode. "SW" for software mode 6 + where G-keys triggers their regular key codes. "HW" for 7 + hardware playback mode where the G-keys play their macro 8 + from the on-board memory. 9 + 10 + 11 + What: /sys/bus/drivers/corsair/<dev>/current_profile 12 + Date: August 2015 13 + KernelVersion: 4.2 14 + Contact: Clement Vuchener <clement.vuchener@gmail.com> 15 + Description: Get/set the current selected profile. Values are from 1 to 3.
Documentation/ABI/testing/sysfs-driver-hid-roccat-arvo Documentation/ABI/obsolete/sysfs-driver-hid-roccat-arvo
Documentation/ABI/testing/sysfs-driver-hid-roccat-isku Documentation/ABI/obsolete/sysfs-driver-hid-roccat-isku
-96
Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus
··· 1 - What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/actual_profile 2 - Date: October 2010 3 - Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 4 - Description: The integer value of this attribute ranges from 0-4. 5 - When read, this attribute returns the number of the actual 6 - profile. This value is persistent, so its equivalent to the 7 - profile that's active when the mouse is powered on next time. 8 - When written, this file sets the number of the startup profile 9 - and the mouse activates this profile immediately. 10 - Users: http://roccat.sourceforge.net 11 - 12 - What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/info 13 - Date: November 2012 14 - Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 15 - Description: When read, this file returns general data like firmware version. 16 - When written, the device can be reset. 17 - The data is 8 bytes long. 18 - Users: http://roccat.sourceforge.net 19 - 20 - What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/macro 21 - Date: October 2010 22 - Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 23 - Description: The mouse can store a macro with max 500 key/button strokes 24 - internally. 25 - When written, this file lets one set the sequence for a specific 26 - button for a specific profile. Button and profile numbers are 27 - included in written data. The data has to be 2082 bytes long. 28 - This file is writeonly. 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>/koneplus/roccatkoneplus<minor>/profile_buttons 32 - Date: August 2010 33 - Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 34 - Description: The mouse can store 5 profiles which can be switched by the 35 - press of a button. A profile is split in settings and buttons. 36 - profile_buttons holds information about button layout. 37 - When written, this file lets one write the respective profile 38 - buttons back to the mouse. The data has to be 77 bytes long. 39 - The mouse will reject invalid data. 40 - Which profile to write is determined by the profile number 41 - contained in the data. 42 - Before reading this file, control has to be written to select 43 - which profile to read. 44 - Users: http://roccat.sourceforge.net 45 - 46 - What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/profile_settings 47 - Date: October 2010 48 - Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 49 - Description: The mouse can store 5 profiles which can be switched by the 50 - press of a button. A profile is split in settings and buttons. 51 - profile_settings holds information like resolution, sensitivity 52 - and light effects. 53 - When written, this file lets one write the respective profile 54 - settings back to the mouse. The data has to be 43 bytes long. 55 - The mouse will reject invalid data. 56 - Which profile to write is determined by the profile number 57 - contained in the data. 58 - Before reading this file, control has to be written to select 59 - which profile to read. 60 - Users: http://roccat.sourceforge.net 61 - 62 - What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/sensor 63 - Date: October 2010 64 - Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 65 - Description: The mouse has a tracking- and a distance-control-unit. These 66 - can be activated/deactivated and the lift-off distance can be 67 - set. The data has to be 6 bytes long. 68 - This file is writeonly. 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>/koneplus/roccatkoneplus<minor>/talk 72 - Date: May 2011 73 - Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 74 - Description: Used to active some easy* functions of the mouse from outside. 75 - The data has to be 16 bytes long. 76 - This file is writeonly. 77 - Users: http://roccat.sourceforge.net 78 - 79 - What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu 80 - Date: October 2010 81 - Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 82 - Description: When written a calibration process for the tracking control unit 83 - can be initiated/cancelled. Also lets one read/write sensor 84 - registers. 85 - The data has to be 4 bytes long. 86 - Users: http://roccat.sourceforge.net 87 - 88 - What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu_image 89 - Date: October 2010 90 - Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 91 - Description: When read the mouse returns a 30x30 pixel image of the 92 - sampled underground. This works only in the course of a 93 - calibration process initiated with tcu. 94 - The returned data is 1028 bytes in size. 95 - This file is readonly. 96 - Users: http://roccat.sourceforge.net
Documentation/ABI/testing/sysfs-driver-hid-roccat-konepure Documentation/ABI/obsolete/sysfs-driver-hid-roccat-konepure
-49
Documentation/ABI/testing/sysfs-driver-hid-roccat-kovaplus
··· 1 - What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/actual_profile 2 - Date: January 2011 3 - Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 4 - Description: The integer value of this attribute ranges from 0-4. 5 - When read, this attribute returns the number of the active 6 - profile. 7 - When written, the mouse activates this profile immediately. 8 - The profile that's active when powered down is the same that's 9 - active when the mouse is powered on. 10 - Users: http://roccat.sourceforge.net 11 - 12 - What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/info 13 - Date: November 2012 14 - Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 15 - Description: When read, this file returns general data like firmware version. 16 - When written, the device can be reset. 17 - The data is 6 bytes long. 18 - Users: http://roccat.sourceforge.net 19 - 20 - What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile_buttons 21 - Date: January 2011 22 - Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 23 - Description: The mouse can store 5 profiles which can be switched by the 24 - press of a button. A profile is split in settings and buttons. 25 - profile_buttons holds information about button layout. 26 - When written, this file lets one write the respective profile 27 - buttons back to the mouse. The data has to be 23 bytes long. 28 - The mouse will reject invalid data. 29 - Which profile to write is determined by the profile number 30 - contained in the data. 31 - Before reading this file, control has to be written to select 32 - which profile to read. 33 - Users: http://roccat.sourceforge.net 34 - 35 - What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/kovaplus/roccatkovaplus<minor>/profile_settings 36 - Date: January 2011 37 - Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 38 - Description: The mouse can store 5 profiles which can be switched by the 39 - press of a button. A profile is split in settings and buttons. 40 - profile_settings holds information like resolution, sensitivity 41 - and light effects. 42 - When written, this file lets one write the respective profile 43 - settings back to the mouse. The data has to be 16 bytes long. 44 - The mouse will reject invalid data. 45 - Which profile to write is determined by the profile number 46 - contained in the data. 47 - Before reading this file, control has to be written to select 48 - which profile to read. 49 - Users: http://roccat.sourceforge.net
Documentation/ABI/testing/sysfs-driver-hid-roccat-lua Documentation/ABI/obsolete/sysfs-driver-hid-roccat-lua
-49
Documentation/ABI/testing/sysfs-driver-hid-roccat-pyra
··· 1 - What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/info 2 - Date: November 2012 3 - Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 4 - Description: When read, this file returns general data like firmware version. 5 - When written, the device can be reset. 6 - The data is 6 bytes long. 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>/pyra/roccatpyra<minor>/profile_settings 10 - Date: August 2010 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. A profile is split in settings and buttons. 14 - profile_settings holds information like resolution, sensitivity 15 - and light effects. 16 - When written, this file lets one write the respective profile 17 - settings back to the mouse. The data has to be 13 bytes long. 18 - The mouse will reject invalid data. 19 - Which profile to write is determined by the profile number 20 - contained in the data. 21 - Before reading this file, control has to be written to select 22 - which profile to read. 23 - Users: http://roccat.sourceforge.net 24 - 25 - What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/profile_buttons 26 - Date: August 2010 27 - Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 28 - Description: The mouse can store 5 profiles which can be switched by the 29 - press of a button. A profile is split in settings and buttons. 30 - profile_buttons holds information about button layout. 31 - When written, this file lets one write the respective profile 32 - buttons back to the mouse. The data has to be 19 bytes long. 33 - The mouse will reject invalid data. 34 - Which profile to write is determined by the profile number 35 - contained in the data. 36 - Before reading this file, control has to be written to select 37 - which profile to read. 38 - Users: http://roccat.sourceforge.net 39 - 40 - What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/pyra/roccatpyra<minor>/settings 41 - Date: August 2010 42 - Contact: Stefan Achatz <erazor_de@users.sourceforge.net> 43 - Description: When read, this file returns the settings stored in the mouse. 44 - The size of the data is 3 bytes and holds information on the 45 - startup_profile. 46 - When written, this file lets write settings back to the mouse. 47 - The data has to be 3 bytes long. The mouse will reject invalid 48 - data. 49 - Users: http://roccat.sourceforge.net
Documentation/ABI/testing/sysfs-driver-hid-roccat-ryos Documentation/ABI/obsolete/sysfs-driver-hid-roccat-ryos
Documentation/ABI/testing/sysfs-driver-hid-roccat-savu Documentation/ABI/obsolete/sysfs-driver-hid-roccat-savu
+12 -3
drivers/hid/Kconfig
··· 171 171 ---help--- 172 172 Support for Chicony Tactical pad. 173 173 174 + config HID_CORSAIR 175 + tristate "Corsair devices" 176 + depends on HID && USB && LEDS_CLASS 177 + ---help--- 178 + Support for Corsair devices that are not fully compliant with the 179 + HID standard. 180 + 181 + Supported devices: 182 + - Vengeance K90 183 + 174 184 config HID_PRODIKEYS 175 185 tristate "Prodikeys PC-MIDI Keyboard support" 176 186 depends on HID && SND ··· 688 678 689 679 Supported devices: 690 680 - PS1000 Dual Analog Pad 691 - - R.A.T.9 Gaming Mouse 692 - - R.A.T.7 Gaming Mouse 693 - - M.M.O.7 Gaming Mouse 681 + - Saitek R.A.T.7, R.A.T.9, M.M.O.7 Gaming Mice 682 + - Mad Catz R.A.T.5, R.A.T.9 Gaming Mice 694 683 695 684 config HID_SAMSUNG 696 685 tristate "Samsung InfraRed remote control or keyboards"
+1
drivers/hid/Makefile
··· 29 29 obj-$(CONFIG_HID_BETOP_FF) += hid-betopff.o 30 30 obj-$(CONFIG_HID_CHERRY) += hid-cherry.o 31 31 obj-$(CONFIG_HID_CHICONY) += hid-chicony.o 32 + obj-$(CONFIG_HID_CORSAIR) += hid-corsair.o 32 33 obj-$(CONFIG_HID_CP2112) += hid-cp2112.o 33 34 obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o 34 35 obj-$(CONFIG_HID_DRAGONRISE) += hid-dr.o
+2 -1
drivers/hid/hid-aureal.c
··· 23 23 if (*rsize >= 54 && rdesc[52] == 0x25 && rdesc[53] == 0x01) { 24 24 dev_info(&hdev->dev, "fixing Aureal Cy se W-01RN USB_V3.1 report descriptor.\n"); 25 25 rdesc[53] = 0x65; 26 - } return rdesc; 26 + } 27 + return rdesc; 27 28 } 28 29 29 30 static const struct hid_device_id aureal_devices[] = {
+9 -1
drivers/hid/hid-core.c
··· 725 725 726 726 if (hid->vendor == USB_VENDOR_ID_MICROSOFT && 727 727 (hid->product == USB_DEVICE_ID_MS_TYPE_COVER_PRO_3 || 728 + hid->product == USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2 || 728 729 hid->product == USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP || 729 730 hid->product == USB_DEVICE_ID_MS_TYPE_COVER_3 || 730 731 hid->product == USB_DEVICE_ID_MS_POWER_COVER) && ··· 1612 1611 "Multi-Axis Controller" 1613 1612 }; 1614 1613 const char *type, *bus; 1615 - char buf[64]; 1614 + char buf[64] = ""; 1616 1615 unsigned int i; 1617 1616 int len; 1618 1617 int ret; ··· 1678 1677 break; 1679 1678 case BUS_BLUETOOTH: 1680 1679 bus = "BLUETOOTH"; 1680 + break; 1681 + case BUS_I2C: 1682 + bus = "I2C"; 1681 1683 break; 1682 1684 default: 1683 1685 bus = "<UNKNOWN>"; ··· 1832 1828 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, 1833 1829 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_AK1D) }, 1834 1830 { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_ACER_SWITCH12) }, 1831 + { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K90) }, 1835 1832 { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, 1836 1833 { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_CP2112) }, 1837 1834 { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, ··· 1901 1896 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD) }, 1902 1897 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD) }, 1903 1898 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2_2) }, 1899 + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G29_WHEEL) }, 1904 1900 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_F3D) }, 1905 1901 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WINGMAN_FFG ) }, 1906 1902 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_FORCE3D_PRO) }, ··· 1934 1928 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_WIRELESS_OPTICAL_DESKTOP_3_0) }, 1935 1929 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_OFFICE_KB) }, 1936 1930 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3) }, 1931 + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2) }, 1937 1932 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP) }, 1938 1933 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3) }, 1939 1934 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER) }, ··· 1988 1981 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7_OLD) }, 1989 1982 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7) }, 1990 1983 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_MMO7) }, 1984 + { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT5) }, 1991 1985 { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9) }, 1992 1986 #endif 1993 1987 { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
+673
drivers/hid/hid-corsair.c
··· 1 + /* 2 + * HID driver for Corsair devices 3 + * 4 + * Supported devices: 5 + * - Vengeance K90 Keyboard 6 + * 7 + * Copyright (c) 2015 Clement Vuchener 8 + */ 9 + 10 + /* 11 + * This program is free software; you can redistribute it and/or modify it 12 + * under the terms of the GNU General Public License as published by the Free 13 + * Software Foundation; either version 2 of the License, or (at your option) 14 + * any later version. 15 + */ 16 + 17 + #include <linux/hid.h> 18 + #include <linux/module.h> 19 + #include <linux/usb.h> 20 + #include <linux/leds.h> 21 + 22 + #include "hid-ids.h" 23 + 24 + #define CORSAIR_USE_K90_MACRO (1<<0) 25 + #define CORSAIR_USE_K90_BACKLIGHT (1<<1) 26 + 27 + struct k90_led { 28 + struct led_classdev cdev; 29 + int brightness; 30 + struct work_struct work; 31 + bool removed; 32 + }; 33 + 34 + struct k90_drvdata { 35 + struct k90_led record_led; 36 + }; 37 + 38 + struct corsair_drvdata { 39 + unsigned long quirks; 40 + struct k90_drvdata *k90; 41 + struct k90_led *backlight; 42 + }; 43 + 44 + #define K90_GKEY_COUNT 18 45 + 46 + static int corsair_usage_to_gkey(unsigned int usage) 47 + { 48 + /* G1 (0xd0) to G16 (0xdf) */ 49 + if (usage >= 0xd0 && usage <= 0xdf) 50 + return usage - 0xd0 + 1; 51 + /* G17 (0xe8) to G18 (0xe9) */ 52 + if (usage >= 0xe8 && usage <= 0xe9) 53 + return usage - 0xe8 + 17; 54 + return 0; 55 + } 56 + 57 + static unsigned short corsair_gkey_map[K90_GKEY_COUNT] = { 58 + BTN_TRIGGER_HAPPY1, 59 + BTN_TRIGGER_HAPPY2, 60 + BTN_TRIGGER_HAPPY3, 61 + BTN_TRIGGER_HAPPY4, 62 + BTN_TRIGGER_HAPPY5, 63 + BTN_TRIGGER_HAPPY6, 64 + BTN_TRIGGER_HAPPY7, 65 + BTN_TRIGGER_HAPPY8, 66 + BTN_TRIGGER_HAPPY9, 67 + BTN_TRIGGER_HAPPY10, 68 + BTN_TRIGGER_HAPPY11, 69 + BTN_TRIGGER_HAPPY12, 70 + BTN_TRIGGER_HAPPY13, 71 + BTN_TRIGGER_HAPPY14, 72 + BTN_TRIGGER_HAPPY15, 73 + BTN_TRIGGER_HAPPY16, 74 + BTN_TRIGGER_HAPPY17, 75 + BTN_TRIGGER_HAPPY18, 76 + }; 77 + 78 + module_param_array_named(gkey_codes, corsair_gkey_map, ushort, NULL, S_IRUGO); 79 + MODULE_PARM_DESC(gkey_codes, "Key codes for the G-keys"); 80 + 81 + static unsigned short corsair_record_keycodes[2] = { 82 + BTN_TRIGGER_HAPPY19, 83 + BTN_TRIGGER_HAPPY20 84 + }; 85 + 86 + module_param_array_named(recordkey_codes, corsair_record_keycodes, ushort, 87 + NULL, S_IRUGO); 88 + MODULE_PARM_DESC(recordkey_codes, "Key codes for the MR (start and stop record) button"); 89 + 90 + static unsigned short corsair_profile_keycodes[3] = { 91 + BTN_TRIGGER_HAPPY21, 92 + BTN_TRIGGER_HAPPY22, 93 + BTN_TRIGGER_HAPPY23 94 + }; 95 + 96 + module_param_array_named(profilekey_codes, corsair_profile_keycodes, ushort, 97 + NULL, S_IRUGO); 98 + MODULE_PARM_DESC(profilekey_codes, "Key codes for the profile buttons"); 99 + 100 + #define CORSAIR_USAGE_SPECIAL_MIN 0xf0 101 + #define CORSAIR_USAGE_SPECIAL_MAX 0xff 102 + 103 + #define CORSAIR_USAGE_MACRO_RECORD_START 0xf6 104 + #define CORSAIR_USAGE_MACRO_RECORD_STOP 0xf7 105 + 106 + #define CORSAIR_USAGE_PROFILE 0xf1 107 + #define CORSAIR_USAGE_M1 0xf1 108 + #define CORSAIR_USAGE_M2 0xf2 109 + #define CORSAIR_USAGE_M3 0xf3 110 + #define CORSAIR_USAGE_PROFILE_MAX 0xf3 111 + 112 + #define CORSAIR_USAGE_META_OFF 0xf4 113 + #define CORSAIR_USAGE_META_ON 0xf5 114 + 115 + #define CORSAIR_USAGE_LIGHT 0xfa 116 + #define CORSAIR_USAGE_LIGHT_OFF 0xfa 117 + #define CORSAIR_USAGE_LIGHT_DIM 0xfb 118 + #define CORSAIR_USAGE_LIGHT_MEDIUM 0xfc 119 + #define CORSAIR_USAGE_LIGHT_BRIGHT 0xfd 120 + #define CORSAIR_USAGE_LIGHT_MAX 0xfd 121 + 122 + /* USB control protocol */ 123 + 124 + #define K90_REQUEST_BRIGHTNESS 49 125 + #define K90_REQUEST_MACRO_MODE 2 126 + #define K90_REQUEST_STATUS 4 127 + #define K90_REQUEST_GET_MODE 5 128 + #define K90_REQUEST_PROFILE 20 129 + 130 + #define K90_MACRO_MODE_SW 0x0030 131 + #define K90_MACRO_MODE_HW 0x0001 132 + 133 + #define K90_MACRO_LED_ON 0x0020 134 + #define K90_MACRO_LED_OFF 0x0040 135 + 136 + /* 137 + * LED class devices 138 + */ 139 + 140 + #define K90_BACKLIGHT_LED_SUFFIX "::backlight" 141 + #define K90_RECORD_LED_SUFFIX "::record" 142 + 143 + static enum led_brightness k90_backlight_get(struct led_classdev *led_cdev) 144 + { 145 + int ret; 146 + struct k90_led *led = container_of(led_cdev, struct k90_led, cdev); 147 + struct device *dev = led->cdev.dev->parent; 148 + struct usb_interface *usbif = to_usb_interface(dev->parent); 149 + struct usb_device *usbdev = interface_to_usbdev(usbif); 150 + int brightness; 151 + char data[8]; 152 + 153 + ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 154 + K90_REQUEST_STATUS, 155 + USB_DIR_IN | USB_TYPE_VENDOR | 156 + USB_RECIP_DEVICE, 0, 0, data, 8, 157 + USB_CTRL_SET_TIMEOUT); 158 + if (ret < 0) { 159 + dev_warn(dev, "Failed to get K90 initial state (error %d).\n", 160 + ret); 161 + return -EIO; 162 + } 163 + brightness = data[4]; 164 + if (brightness < 0 || brightness > 3) { 165 + dev_warn(dev, 166 + "Read invalid backlight brightness: %02hhx.\n", 167 + data[4]); 168 + return -EIO; 169 + } 170 + return brightness; 171 + } 172 + 173 + static enum led_brightness k90_record_led_get(struct led_classdev *led_cdev) 174 + { 175 + struct k90_led *led = container_of(led_cdev, struct k90_led, cdev); 176 + 177 + return led->brightness; 178 + } 179 + 180 + static void k90_brightness_set(struct led_classdev *led_cdev, 181 + enum led_brightness brightness) 182 + { 183 + struct k90_led *led = container_of(led_cdev, struct k90_led, cdev); 184 + 185 + led->brightness = brightness; 186 + schedule_work(&led->work); 187 + } 188 + 189 + static void k90_backlight_work(struct work_struct *work) 190 + { 191 + int ret; 192 + struct k90_led *led = container_of(work, struct k90_led, work); 193 + struct device *dev; 194 + struct usb_interface *usbif; 195 + struct usb_device *usbdev; 196 + 197 + if (led->removed) 198 + return; 199 + 200 + dev = led->cdev.dev->parent; 201 + usbif = to_usb_interface(dev->parent); 202 + usbdev = interface_to_usbdev(usbif); 203 + 204 + ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 205 + K90_REQUEST_BRIGHTNESS, 206 + USB_DIR_OUT | USB_TYPE_VENDOR | 207 + USB_RECIP_DEVICE, led->brightness, 0, 208 + NULL, 0, USB_CTRL_SET_TIMEOUT); 209 + if (ret != 0) 210 + dev_warn(dev, "Failed to set backlight brightness (error: %d).\n", 211 + ret); 212 + } 213 + 214 + static void k90_record_led_work(struct work_struct *work) 215 + { 216 + int ret; 217 + struct k90_led *led = container_of(work, struct k90_led, work); 218 + struct device *dev; 219 + struct usb_interface *usbif; 220 + struct usb_device *usbdev; 221 + int value; 222 + 223 + if (led->removed) 224 + return; 225 + 226 + dev = led->cdev.dev->parent; 227 + usbif = to_usb_interface(dev->parent); 228 + usbdev = interface_to_usbdev(usbif); 229 + 230 + if (led->brightness > 0) 231 + value = K90_MACRO_LED_ON; 232 + else 233 + value = K90_MACRO_LED_OFF; 234 + 235 + ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 236 + K90_REQUEST_MACRO_MODE, 237 + USB_DIR_OUT | USB_TYPE_VENDOR | 238 + USB_RECIP_DEVICE, value, 0, NULL, 0, 239 + USB_CTRL_SET_TIMEOUT); 240 + if (ret != 0) 241 + dev_warn(dev, "Failed to set record LED state (error: %d).\n", 242 + ret); 243 + } 244 + 245 + /* 246 + * Keyboard attributes 247 + */ 248 + 249 + static ssize_t k90_show_macro_mode(struct device *dev, 250 + struct device_attribute *attr, char *buf) 251 + { 252 + int ret; 253 + struct usb_interface *usbif = to_usb_interface(dev->parent); 254 + struct usb_device *usbdev = interface_to_usbdev(usbif); 255 + const char *macro_mode; 256 + char data[8]; 257 + 258 + ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 259 + K90_REQUEST_GET_MODE, 260 + USB_DIR_IN | USB_TYPE_VENDOR | 261 + USB_RECIP_DEVICE, 0, 0, data, 2, 262 + USB_CTRL_SET_TIMEOUT); 263 + if (ret < 0) { 264 + dev_warn(dev, "Failed to get K90 initial mode (error %d).\n", 265 + ret); 266 + return -EIO; 267 + } 268 + 269 + switch (data[0]) { 270 + case K90_MACRO_MODE_HW: 271 + macro_mode = "HW"; 272 + break; 273 + 274 + case K90_MACRO_MODE_SW: 275 + macro_mode = "SW"; 276 + break; 277 + default: 278 + dev_warn(dev, "K90 in unknown mode: %02hhx.\n", 279 + data[0]); 280 + return -EIO; 281 + } 282 + 283 + return snprintf(buf, PAGE_SIZE, "%s\n", macro_mode); 284 + } 285 + 286 + static ssize_t k90_store_macro_mode(struct device *dev, 287 + struct device_attribute *attr, 288 + const char *buf, size_t count) 289 + { 290 + int ret; 291 + struct usb_interface *usbif = to_usb_interface(dev->parent); 292 + struct usb_device *usbdev = interface_to_usbdev(usbif); 293 + __u16 value; 294 + 295 + if (strncmp(buf, "SW", 2) == 0) 296 + value = K90_MACRO_MODE_SW; 297 + else if (strncmp(buf, "HW", 2) == 0) 298 + value = K90_MACRO_MODE_HW; 299 + else 300 + return -EINVAL; 301 + 302 + ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 303 + K90_REQUEST_MACRO_MODE, 304 + USB_DIR_OUT | USB_TYPE_VENDOR | 305 + USB_RECIP_DEVICE, value, 0, NULL, 0, 306 + USB_CTRL_SET_TIMEOUT); 307 + if (ret != 0) { 308 + dev_warn(dev, "Failed to set macro mode.\n"); 309 + return ret; 310 + } 311 + 312 + return count; 313 + } 314 + 315 + static ssize_t k90_show_current_profile(struct device *dev, 316 + struct device_attribute *attr, 317 + char *buf) 318 + { 319 + int ret; 320 + struct usb_interface *usbif = to_usb_interface(dev->parent); 321 + struct usb_device *usbdev = interface_to_usbdev(usbif); 322 + int current_profile; 323 + char data[8]; 324 + 325 + ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 326 + K90_REQUEST_STATUS, 327 + USB_DIR_IN | USB_TYPE_VENDOR | 328 + USB_RECIP_DEVICE, 0, 0, data, 8, 329 + USB_CTRL_SET_TIMEOUT); 330 + if (ret < 0) { 331 + dev_warn(dev, "Failed to get K90 initial state (error %d).\n", 332 + ret); 333 + return -EIO; 334 + } 335 + current_profile = data[7]; 336 + if (current_profile < 1 || current_profile > 3) { 337 + dev_warn(dev, "Read invalid current profile: %02hhx.\n", 338 + data[7]); 339 + return -EIO; 340 + } 341 + 342 + return snprintf(buf, PAGE_SIZE, "%d\n", current_profile); 343 + } 344 + 345 + static ssize_t k90_store_current_profile(struct device *dev, 346 + struct device_attribute *attr, 347 + const char *buf, size_t count) 348 + { 349 + int ret; 350 + struct usb_interface *usbif = to_usb_interface(dev->parent); 351 + struct usb_device *usbdev = interface_to_usbdev(usbif); 352 + int profile; 353 + 354 + if (kstrtoint(buf, 10, &profile)) 355 + return -EINVAL; 356 + if (profile < 1 || profile > 3) 357 + return -EINVAL; 358 + 359 + ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 360 + K90_REQUEST_PROFILE, 361 + USB_DIR_OUT | USB_TYPE_VENDOR | 362 + USB_RECIP_DEVICE, profile, 0, NULL, 0, 363 + USB_CTRL_SET_TIMEOUT); 364 + if (ret != 0) { 365 + dev_warn(dev, "Failed to change current profile (error %d).\n", 366 + ret); 367 + return ret; 368 + } 369 + 370 + return count; 371 + } 372 + 373 + static DEVICE_ATTR(macro_mode, 0644, k90_show_macro_mode, k90_store_macro_mode); 374 + static DEVICE_ATTR(current_profile, 0644, k90_show_current_profile, 375 + k90_store_current_profile); 376 + 377 + static struct attribute *k90_attrs[] = { 378 + &dev_attr_macro_mode.attr, 379 + &dev_attr_current_profile.attr, 380 + NULL 381 + }; 382 + 383 + static const struct attribute_group k90_attr_group = { 384 + .attrs = k90_attrs, 385 + }; 386 + 387 + /* 388 + * Driver functions 389 + */ 390 + 391 + static int k90_init_backlight(struct hid_device *dev) 392 + { 393 + int ret; 394 + struct corsair_drvdata *drvdata = hid_get_drvdata(dev); 395 + size_t name_sz; 396 + char *name; 397 + 398 + drvdata->backlight = kzalloc(sizeof(struct k90_led), GFP_KERNEL); 399 + if (!drvdata->backlight) { 400 + ret = -ENOMEM; 401 + goto fail_backlight_alloc; 402 + } 403 + 404 + name_sz = 405 + strlen(dev_name(&dev->dev)) + sizeof(K90_BACKLIGHT_LED_SUFFIX); 406 + name = kzalloc(name_sz, GFP_KERNEL); 407 + if (!name) { 408 + ret = -ENOMEM; 409 + goto fail_name_alloc; 410 + } 411 + snprintf(name, name_sz, "%s" K90_BACKLIGHT_LED_SUFFIX, 412 + dev_name(&dev->dev)); 413 + drvdata->backlight->removed = false; 414 + drvdata->backlight->cdev.name = name; 415 + drvdata->backlight->cdev.max_brightness = 3; 416 + drvdata->backlight->cdev.brightness_set = k90_brightness_set; 417 + drvdata->backlight->cdev.brightness_get = k90_backlight_get; 418 + INIT_WORK(&drvdata->backlight->work, k90_backlight_work); 419 + ret = led_classdev_register(&dev->dev, &drvdata->backlight->cdev); 420 + if (ret != 0) 421 + goto fail_register_cdev; 422 + 423 + return 0; 424 + 425 + fail_register_cdev: 426 + kfree(drvdata->backlight->cdev.name); 427 + fail_name_alloc: 428 + kfree(drvdata->backlight); 429 + drvdata->backlight = NULL; 430 + fail_backlight_alloc: 431 + return ret; 432 + } 433 + 434 + static int k90_init_macro_functions(struct hid_device *dev) 435 + { 436 + int ret; 437 + struct corsair_drvdata *drvdata = hid_get_drvdata(dev); 438 + struct k90_drvdata *k90; 439 + size_t name_sz; 440 + char *name; 441 + 442 + k90 = kzalloc(sizeof(struct k90_drvdata), GFP_KERNEL); 443 + if (!k90) { 444 + ret = -ENOMEM; 445 + goto fail_drvdata; 446 + } 447 + drvdata->k90 = k90; 448 + 449 + /* Init LED device for record LED */ 450 + name_sz = strlen(dev_name(&dev->dev)) + sizeof(K90_RECORD_LED_SUFFIX); 451 + name = kzalloc(name_sz, GFP_KERNEL); 452 + if (!name) { 453 + ret = -ENOMEM; 454 + goto fail_record_led_alloc; 455 + } 456 + snprintf(name, name_sz, "%s" K90_RECORD_LED_SUFFIX, 457 + dev_name(&dev->dev)); 458 + k90->record_led.removed = false; 459 + k90->record_led.cdev.name = name; 460 + k90->record_led.cdev.max_brightness = 1; 461 + k90->record_led.cdev.brightness_set = k90_brightness_set; 462 + k90->record_led.cdev.brightness_get = k90_record_led_get; 463 + INIT_WORK(&k90->record_led.work, k90_record_led_work); 464 + k90->record_led.brightness = 0; 465 + ret = led_classdev_register(&dev->dev, &k90->record_led.cdev); 466 + if (ret != 0) 467 + goto fail_record_led; 468 + 469 + /* Init attributes */ 470 + ret = sysfs_create_group(&dev->dev.kobj, &k90_attr_group); 471 + if (ret != 0) 472 + goto fail_sysfs; 473 + 474 + return 0; 475 + 476 + fail_sysfs: 477 + k90->record_led.removed = true; 478 + led_classdev_unregister(&k90->record_led.cdev); 479 + cancel_work_sync(&k90->record_led.work); 480 + fail_record_led: 481 + kfree(k90->record_led.cdev.name); 482 + fail_record_led_alloc: 483 + kfree(k90); 484 + fail_drvdata: 485 + drvdata->k90 = NULL; 486 + return ret; 487 + } 488 + 489 + static void k90_cleanup_backlight(struct hid_device *dev) 490 + { 491 + struct corsair_drvdata *drvdata = hid_get_drvdata(dev); 492 + 493 + if (drvdata->backlight) { 494 + drvdata->backlight->removed = true; 495 + led_classdev_unregister(&drvdata->backlight->cdev); 496 + cancel_work_sync(&drvdata->backlight->work); 497 + kfree(drvdata->backlight->cdev.name); 498 + kfree(drvdata->backlight); 499 + } 500 + } 501 + 502 + static void k90_cleanup_macro_functions(struct hid_device *dev) 503 + { 504 + struct corsair_drvdata *drvdata = hid_get_drvdata(dev); 505 + struct k90_drvdata *k90 = drvdata->k90; 506 + 507 + if (k90) { 508 + sysfs_remove_group(&dev->dev.kobj, &k90_attr_group); 509 + 510 + k90->record_led.removed = true; 511 + led_classdev_unregister(&k90->record_led.cdev); 512 + cancel_work_sync(&k90->record_led.work); 513 + kfree(k90->record_led.cdev.name); 514 + 515 + kfree(k90); 516 + } 517 + } 518 + 519 + static int corsair_probe(struct hid_device *dev, const struct hid_device_id *id) 520 + { 521 + int ret; 522 + unsigned long quirks = id->driver_data; 523 + struct corsair_drvdata *drvdata; 524 + struct usb_interface *usbif = to_usb_interface(dev->dev.parent); 525 + 526 + drvdata = devm_kzalloc(&dev->dev, sizeof(struct corsair_drvdata), 527 + GFP_KERNEL); 528 + if (drvdata == NULL) 529 + return -ENOMEM; 530 + drvdata->quirks = quirks; 531 + hid_set_drvdata(dev, drvdata); 532 + 533 + ret = hid_parse(dev); 534 + if (ret != 0) { 535 + hid_err(dev, "parse failed\n"); 536 + return ret; 537 + } 538 + ret = hid_hw_start(dev, HID_CONNECT_DEFAULT); 539 + if (ret != 0) { 540 + hid_err(dev, "hw start failed\n"); 541 + return ret; 542 + } 543 + 544 + if (usbif->cur_altsetting->desc.bInterfaceNumber == 0) { 545 + if (quirks & CORSAIR_USE_K90_MACRO) { 546 + ret = k90_init_macro_functions(dev); 547 + if (ret != 0) 548 + hid_warn(dev, "Failed to initialize K90 macro functions.\n"); 549 + } 550 + if (quirks & CORSAIR_USE_K90_BACKLIGHT) { 551 + ret = k90_init_backlight(dev); 552 + if (ret != 0) 553 + hid_warn(dev, "Failed to initialize K90 backlight.\n"); 554 + } 555 + } 556 + 557 + return 0; 558 + } 559 + 560 + static void corsair_remove(struct hid_device *dev) 561 + { 562 + k90_cleanup_macro_functions(dev); 563 + k90_cleanup_backlight(dev); 564 + 565 + hid_hw_stop(dev); 566 + } 567 + 568 + static int corsair_event(struct hid_device *dev, struct hid_field *field, 569 + struct hid_usage *usage, __s32 value) 570 + { 571 + struct corsair_drvdata *drvdata = hid_get_drvdata(dev); 572 + 573 + if (!drvdata->k90) 574 + return 0; 575 + 576 + switch (usage->hid & HID_USAGE) { 577 + case CORSAIR_USAGE_MACRO_RECORD_START: 578 + drvdata->k90->record_led.brightness = 1; 579 + break; 580 + case CORSAIR_USAGE_MACRO_RECORD_STOP: 581 + drvdata->k90->record_led.brightness = 0; 582 + break; 583 + default: 584 + break; 585 + } 586 + 587 + return 0; 588 + } 589 + 590 + static int corsair_input_mapping(struct hid_device *dev, 591 + struct hid_input *input, 592 + struct hid_field *field, 593 + struct hid_usage *usage, unsigned long **bit, 594 + int *max) 595 + { 596 + int gkey; 597 + 598 + gkey = corsair_usage_to_gkey(usage->hid & HID_USAGE); 599 + if (gkey != 0) { 600 + hid_map_usage_clear(input, usage, bit, max, EV_KEY, 601 + corsair_gkey_map[gkey - 1]); 602 + return 1; 603 + } 604 + if ((usage->hid & HID_USAGE) >= CORSAIR_USAGE_SPECIAL_MIN && 605 + (usage->hid & HID_USAGE) <= CORSAIR_USAGE_SPECIAL_MAX) { 606 + switch (usage->hid & HID_USAGE) { 607 + case CORSAIR_USAGE_MACRO_RECORD_START: 608 + hid_map_usage_clear(input, usage, bit, max, EV_KEY, 609 + corsair_record_keycodes[0]); 610 + return 1; 611 + 612 + case CORSAIR_USAGE_MACRO_RECORD_STOP: 613 + hid_map_usage_clear(input, usage, bit, max, EV_KEY, 614 + corsair_record_keycodes[1]); 615 + return 1; 616 + 617 + case CORSAIR_USAGE_M1: 618 + hid_map_usage_clear(input, usage, bit, max, EV_KEY, 619 + corsair_profile_keycodes[0]); 620 + return 1; 621 + 622 + case CORSAIR_USAGE_M2: 623 + hid_map_usage_clear(input, usage, bit, max, EV_KEY, 624 + corsair_profile_keycodes[1]); 625 + return 1; 626 + 627 + case CORSAIR_USAGE_M3: 628 + hid_map_usage_clear(input, usage, bit, max, EV_KEY, 629 + corsair_profile_keycodes[2]); 630 + return 1; 631 + 632 + default: 633 + return -1; 634 + } 635 + } 636 + 637 + return 0; 638 + } 639 + 640 + static const struct hid_device_id corsair_devices[] = { 641 + { HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K90), 642 + .driver_data = CORSAIR_USE_K90_MACRO | 643 + CORSAIR_USE_K90_BACKLIGHT }, 644 + {} 645 + }; 646 + 647 + MODULE_DEVICE_TABLE(hid, corsair_devices); 648 + 649 + static struct hid_driver corsair_driver = { 650 + .name = "corsair", 651 + .id_table = corsair_devices, 652 + .probe = corsair_probe, 653 + .event = corsair_event, 654 + .remove = corsair_remove, 655 + .input_mapping = corsair_input_mapping, 656 + }; 657 + 658 + static int __init corsair_init(void) 659 + { 660 + return hid_register_driver(&corsair_driver); 661 + } 662 + 663 + static void corsair_exit(void) 664 + { 665 + hid_unregister_driver(&corsair_driver); 666 + } 667 + 668 + module_init(corsair_init); 669 + module_exit(corsair_exit); 670 + 671 + MODULE_LICENSE("GPL"); 672 + MODULE_AUTHOR("Clement Vuchener"); 673 + MODULE_DESCRIPTION("HID driver for Corsair devices");
+58
drivers/hid/hid-dr.c
··· 234 234 0xC0 /* End Collection */ 235 235 }; 236 236 237 + static __u8 pid0006_rdesc_fixed[] = { 238 + 0x05, 0x01, /* Usage Page (Generic Desktop) */ 239 + 0x09, 0x04, /* Usage (Joystick) */ 240 + 0xA1, 0x01, /* Collection (Application) */ 241 + 0xA1, 0x02, /* Collection (Logical) */ 242 + 0x75, 0x08, /* Report Size (8) */ 243 + 0x95, 0x05, /* Report Count (5) */ 244 + 0x15, 0x00, /* Logical Minimum (0) */ 245 + 0x26, 0xFF, 0x00, /* Logical Maximum (255) */ 246 + 0x35, 0x00, /* Physical Minimum (0) */ 247 + 0x46, 0xFF, 0x00, /* Physical Maximum (255) */ 248 + 0x09, 0x30, /* Usage (X) */ 249 + 0x09, 0x33, /* Usage (Ry) */ 250 + 0x09, 0x32, /* Usage (Z) */ 251 + 0x09, 0x31, /* Usage (Y) */ 252 + 0x09, 0x34, /* Usage (Ry) */ 253 + 0x81, 0x02, /* Input (Variable) */ 254 + 0x75, 0x04, /* Report Size (4) */ 255 + 0x95, 0x01, /* Report Count (1) */ 256 + 0x25, 0x07, /* Logical Maximum (7) */ 257 + 0x46, 0x3B, 0x01, /* Physical Maximum (315) */ 258 + 0x65, 0x14, /* Unit (Centimeter) */ 259 + 0x09, 0x39, /* Usage (Hat switch) */ 260 + 0x81, 0x42, /* Input (Variable) */ 261 + 0x65, 0x00, /* Unit (None) */ 262 + 0x75, 0x01, /* Report Size (1) */ 263 + 0x95, 0x0C, /* Report Count (12) */ 264 + 0x25, 0x01, /* Logical Maximum (1) */ 265 + 0x45, 0x01, /* Physical Maximum (1) */ 266 + 0x05, 0x09, /* Usage Page (Button) */ 267 + 0x19, 0x01, /* Usage Minimum (0x01) */ 268 + 0x29, 0x0C, /* Usage Maximum (0x0C) */ 269 + 0x81, 0x02, /* Input (Variable) */ 270 + 0x06, 0x00, 0xFF, /* Usage Page (Vendor Defined) */ 271 + 0x75, 0x01, /* Report Size (1) */ 272 + 0x95, 0x08, /* Report Count (8) */ 273 + 0x25, 0x01, /* Logical Maximum (1) */ 274 + 0x45, 0x01, /* Physical Maximum (1) */ 275 + 0x09, 0x01, /* Usage (0x01) */ 276 + 0x81, 0x02, /* Input (Variable) */ 277 + 0xC0, /* End Collection */ 278 + 0xA1, 0x02, /* Collection (Logical) */ 279 + 0x75, 0x08, /* Report Size (8) */ 280 + 0x95, 0x07, /* Report Count (7) */ 281 + 0x46, 0xFF, 0x00, /* Physical Maximum (255) */ 282 + 0x26, 0xFF, 0x00, /* Logical Maximum (255) */ 283 + 0x09, 0x02, /* Usage (0x02) */ 284 + 0x91, 0x02, /* Output (Variable) */ 285 + 0xC0, /* End Collection */ 286 + 0xC0 /* End Collection */ 287 + }; 288 + 237 289 static __u8 *dr_report_fixup(struct hid_device *hdev, __u8 *rdesc, 238 290 unsigned int *rsize) 239 291 { ··· 294 242 if (*rsize == PID0011_RDESC_ORIG_SIZE) { 295 243 rdesc = pid0011_rdesc_fixed; 296 244 *rsize = sizeof(pid0011_rdesc_fixed); 245 + } 246 + break; 247 + case 0x0006: 248 + if (*rsize == sizeof(pid0006_rdesc_fixed)) { 249 + rdesc = pid0006_rdesc_fixed; 250 + *rsize = sizeof(pid0006_rdesc_fixed); 297 251 } 298 252 break; 299 253 }
+1 -1
drivers/hid/hid-elecom.c
··· 27 27 hid_info(hdev, "Fixing up Elecom BM084 report descriptor\n"); 28 28 rdesc[47] = 0x00; 29 29 } 30 - return rdesc; 30 + return rdesc; 31 31 } 32 32 33 33 static const struct hid_device_id elecom_devices[] = {
+7
drivers/hid/hid-ids.h
··· 251 251 #define USB_DEVICE_ID_CODEMERCS_IOW_FIRST 0x1500 252 252 #define USB_DEVICE_ID_CODEMERCS_IOW_LAST 0x15ff 253 253 254 + #define USB_VENDOR_ID_CORSAIR 0x1b1c 255 + #define USB_DEVICE_ID_CORSAIR_K90 0x1b02 256 + 254 257 #define USB_VENDOR_ID_CREATIVELABS 0x041e 255 258 #define USB_DEVICE_ID_PRODIKEYS_PCMIDI 0x2801 256 259 ··· 291 288 #define USB_DEVICE_ID_DMI_ENC 0x5fab 292 289 293 290 #define USB_VENDOR_ID_DRAGONRISE 0x0079 291 + #define USB_DEVICE_ID_DRAGONRISE_WIIU 0x1800 294 292 295 293 #define USB_VENDOR_ID_DWAV 0x0eef 296 294 #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 ··· 514 510 515 511 #define USB_VENDOR_ID_ITE 0x048d 516 512 #define USB_DEVICE_ID_ITE_LENOVO_YOGA 0x8386 513 + #define USB_DEVICE_ID_ITE_LENOVO_YOGA2 0x8350 517 514 518 515 #define USB_VENDOR_ID_JABRA 0x0b0e 519 516 #define USB_DEVICE_ID_JABRA_SPEAK_410 0x0412 ··· 651 646 652 647 #define USB_VENDOR_ID_MADCATZ 0x0738 653 648 #define USB_DEVICE_ID_MADCATZ_BEATPAD 0x4540 649 + #define USB_DEVICE_ID_MADCATZ_RAT5 0x1705 654 650 #define USB_DEVICE_ID_MADCATZ_RAT9 0x1709 655 651 656 652 #define USB_VENDOR_ID_MCC 0x09db ··· 685 679 #define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7 686 680 #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 687 681 #define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3 0x07dc 682 + #define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2 0x07e2 688 683 #define USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP 0x07dd 689 684 #define USB_DEVICE_ID_MS_TYPE_COVER_3 0x07de 690 685 #define USB_DEVICE_ID_MS_POWER_COVER 0x07da
+9
drivers/hid/hid-lg.c
··· 620 620 usage->code == ABS_Y || usage->code == ABS_Z || 621 621 usage->code == ABS_RZ)) { 622 622 switch (hdev->product) { 623 + case USB_DEVICE_ID_LOGITECH_G29_WHEEL: 623 624 case USB_DEVICE_ID_LOGITECH_WHEEL: 624 625 case USB_DEVICE_ID_LOGITECH_MOMO_WHEEL: 625 626 case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: ··· 659 658 660 659 static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) 661 660 { 661 + struct usb_interface *iface = to_usb_interface(hdev->dev.parent); 662 + __u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber; 662 663 unsigned int connect_mask = HID_CONNECT_DEFAULT; 663 664 struct lg_drv_data *drv_data; 664 665 int ret; 666 + 667 + /* Only work with the 1st interface (G29 presents multiple) */ 668 + if (iface_num != 0) { 669 + dbg_hid("%s: ignoring ifnum %d\n", __func__, iface_num); 670 + return -ENODEV; 671 + } 665 672 666 673 drv_data = kzalloc(sizeof(struct lg_drv_data), GFP_KERNEL); 667 674 if (!drv_data) {
+81 -46
drivers/hid/hid-lg4ff.c
··· 45 45 #define LG4FF_MODE_G25_IDX 3 46 46 #define LG4FF_MODE_DFGT_IDX 4 47 47 #define LG4FF_MODE_G27_IDX 5 48 - #define LG4FF_MODE_MAX_IDX 6 48 + #define LG4FF_MODE_G29_IDX 6 49 + #define LG4FF_MODE_MAX_IDX 7 49 50 50 51 #define LG4FF_MODE_NATIVE BIT(LG4FF_MODE_NATIVE_IDX) 51 52 #define LG4FF_MODE_DFEX BIT(LG4FF_MODE_DFEX_IDX) ··· 54 53 #define LG4FF_MODE_G25 BIT(LG4FF_MODE_G25_IDX) 55 54 #define LG4FF_MODE_DFGT BIT(LG4FF_MODE_DFGT_IDX) 56 55 #define LG4FF_MODE_G27 BIT(LG4FF_MODE_G27_IDX) 56 + #define LG4FF_MODE_G29 BIT(LG4FF_MODE_G29_IDX) 57 57 58 58 #define LG4FF_DFEX_TAG "DF-EX" 59 59 #define LG4FF_DFEX_NAME "Driving Force / Formula EX" ··· 64 62 #define LG4FF_G25_NAME "G25 Racing Wheel" 65 63 #define LG4FF_G27_TAG "G27" 66 64 #define LG4FF_G27_NAME "G27 Racing Wheel" 65 + #define LG4FF_G29_TAG "G29" 66 + #define LG4FF_G29_NAME "G29 Racing Wheel" 67 67 #define LG4FF_DFGT_TAG "DFGT" 68 68 #define LG4FF_DFGT_NAME "Driving Force GT" 69 69 ··· 118 114 }; 119 115 120 116 struct lg4ff_wheel_ident_info { 117 + const u32 modes; 121 118 const u16 mask; 122 119 const u16 result; 123 120 const u16 real_product_id; 124 - }; 125 - 126 - struct lg4ff_wheel_ident_checklist { 127 - const u32 count; 128 - const struct lg4ff_wheel_ident_info *models[]; 129 121 }; 130 122 131 123 struct lg4ff_multimode_wheel { ··· 144 144 {USB_DEVICE_ID_LOGITECH_G25_WHEEL, lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25}, 145 145 {USB_DEVICE_ID_LOGITECH_DFGT_WHEEL, lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25}, 146 146 {USB_DEVICE_ID_LOGITECH_G27_WHEEL, lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25}, 147 + {USB_DEVICE_ID_LOGITECH_G29_WHEEL, lg4ff_wheel_effects, 40, 900, lg4ff_set_range_g25}, 147 148 {USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2, lg4ff_wheel_effects, 40, 270, NULL}, 148 149 {USB_DEVICE_ID_LOGITECH_WII_WHEEL, lg4ff_wheel_effects, 40, 270, NULL} 149 150 }; ··· 162 161 {USB_DEVICE_ID_LOGITECH_G27_WHEEL, 163 162 LG4FF_MODE_NATIVE | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, 164 163 LG4FF_G27_TAG, LG4FF_G27_NAME}, 164 + {USB_DEVICE_ID_LOGITECH_G29_WHEEL, 165 + LG4FF_MODE_NATIVE | LG4FF_MODE_G29 | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, 166 + LG4FF_G29_TAG, LG4FF_G29_NAME}, 165 167 }; 166 168 167 169 static const struct lg4ff_alternate_mode lg4ff_alternate_modes[] = { ··· 173 169 [LG4FF_MODE_DFP_IDX] = {USB_DEVICE_ID_LOGITECH_DFP_WHEEL, LG4FF_DFP_TAG, LG4FF_DFP_NAME}, 174 170 [LG4FF_MODE_G25_IDX] = {USB_DEVICE_ID_LOGITECH_G25_WHEEL, LG4FF_G25_TAG, LG4FF_G25_NAME}, 175 171 [LG4FF_MODE_DFGT_IDX] = {USB_DEVICE_ID_LOGITECH_DFGT_WHEEL, LG4FF_DFGT_TAG, LG4FF_DFGT_NAME}, 176 - [LG4FF_MODE_G27_IDX] = {USB_DEVICE_ID_LOGITECH_G27_WHEEL, LG4FF_G27_TAG, LG4FF_G27_NAME} 172 + [LG4FF_MODE_G27_IDX] = {USB_DEVICE_ID_LOGITECH_G27_WHEEL, LG4FF_G27_TAG, LG4FF_G27_NAME}, 173 + [LG4FF_MODE_G29_IDX] = {USB_DEVICE_ID_LOGITECH_G29_WHEEL, LG4FF_G29_TAG, LG4FF_G29_NAME}, 177 174 }; 178 175 179 176 /* Multimode wheel identificators */ 180 177 static const struct lg4ff_wheel_ident_info lg4ff_dfp_ident_info = { 178 + LG4FF_MODE_DFP | LG4FF_MODE_DFEX, 181 179 0xf000, 182 180 0x1000, 183 181 USB_DEVICE_ID_LOGITECH_DFP_WHEEL 184 182 }; 185 183 186 184 static const struct lg4ff_wheel_ident_info lg4ff_g25_ident_info = { 185 + LG4FF_MODE_G25 | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, 187 186 0xff00, 188 187 0x1200, 189 188 USB_DEVICE_ID_LOGITECH_G25_WHEEL 190 189 }; 191 190 192 191 static const struct lg4ff_wheel_ident_info lg4ff_g27_ident_info = { 192 + LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, 193 193 0xfff0, 194 194 0x1230, 195 195 USB_DEVICE_ID_LOGITECH_G27_WHEEL 196 196 }; 197 197 198 198 static const struct lg4ff_wheel_ident_info lg4ff_dfgt_ident_info = { 199 + LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, 199 200 0xff00, 200 201 0x1300, 201 202 USB_DEVICE_ID_LOGITECH_DFGT_WHEEL 202 203 }; 203 204 205 + static const struct lg4ff_wheel_ident_info lg4ff_g29_ident_info = { 206 + LG4FF_MODE_G29 | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, 207 + 0xfff8, 208 + 0x1350, 209 + USB_DEVICE_ID_LOGITECH_G29_WHEEL 210 + }; 211 + 212 + static const struct lg4ff_wheel_ident_info lg4ff_g29_ident_info2 = { 213 + LG4FF_MODE_G29 | LG4FF_MODE_G27 | LG4FF_MODE_G25 | LG4FF_MODE_DFGT | LG4FF_MODE_DFP | LG4FF_MODE_DFEX, 214 + 0xff00, 215 + 0x8900, 216 + USB_DEVICE_ID_LOGITECH_G29_WHEEL 217 + }; 218 + 204 219 /* Multimode wheel identification checklists */ 205 - static const struct lg4ff_wheel_ident_checklist lg4ff_main_checklist = { 206 - 4, 207 - {&lg4ff_dfgt_ident_info, 208 - &lg4ff_g27_ident_info, 209 - &lg4ff_g25_ident_info, 210 - &lg4ff_dfp_ident_info} 220 + static const struct lg4ff_wheel_ident_info *lg4ff_main_checklist[] = { 221 + &lg4ff_g29_ident_info, 222 + &lg4ff_g29_ident_info2, 223 + &lg4ff_dfgt_ident_info, 224 + &lg4ff_g27_ident_info, 225 + &lg4ff_g25_ident_info, 226 + &lg4ff_dfp_ident_info 211 227 }; 212 228 213 229 /* Compatibility mode switching commands */ ··· 260 236 2, 261 237 {0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, /* Revert mode upon USB reset */ 262 238 0xf8, 0x09, 0x04, 0x01, 0x00, 0x00, 0x00} /* Switch mode to G27 with detach */ 239 + }; 240 + 241 + static const struct lg4ff_compat_mode_switch lg4ff_mode_switch_ext09_g29 = { 242 + 2, 243 + {0xf8, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, /* Revert mode upon USB reset */ 244 + 0xf8, 0x09, 0x05, 0x01, 0x01, 0x00, 0x00} /* Switch mode to G29 with detach */ 263 245 }; 264 246 265 247 /* EXT_CMD1 - Understood by DFP, G25, G27 and DFGT */ ··· 681 651 return NULL; 682 652 } 683 653 break; 654 + case USB_DEVICE_ID_LOGITECH_G29_WHEEL: 655 + switch (target_product_id) { 656 + case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: 657 + return &lg4ff_mode_switch_ext09_dfp; 658 + case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL: 659 + return &lg4ff_mode_switch_ext09_dfgt; 660 + case USB_DEVICE_ID_LOGITECH_G25_WHEEL: 661 + return &lg4ff_mode_switch_ext09_g25; 662 + case USB_DEVICE_ID_LOGITECH_G27_WHEEL: 663 + return &lg4ff_mode_switch_ext09_g27; 664 + case USB_DEVICE_ID_LOGITECH_G29_WHEEL: 665 + return &lg4ff_mode_switch_ext09_g29; 666 + /* G29 can only be switched to DF-EX, DFP, DFGT, G25, G27 or its native mode */ 667 + default: 668 + return NULL; 669 + } 670 + break; 684 671 case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL: 685 672 switch (target_product_id) { 686 673 case USB_DEVICE_ID_LOGITECH_WHEEL: ··· 1084 1037 1085 1038 static u16 lg4ff_identify_multimode_wheel(struct hid_device *hid, const u16 reported_product_id, const u16 bcdDevice) 1086 1039 { 1087 - const struct lg4ff_wheel_ident_checklist *checklist; 1088 - int i, from_idx, to_idx; 1040 + u32 current_mode; 1041 + int i; 1089 1042 1090 - switch (reported_product_id) { 1091 - case USB_DEVICE_ID_LOGITECH_WHEEL: 1092 - case USB_DEVICE_ID_LOGITECH_DFP_WHEEL: 1093 - checklist = &lg4ff_main_checklist; 1094 - from_idx = 0; 1095 - to_idx = checklist->count - 1; 1096 - break; 1097 - case USB_DEVICE_ID_LOGITECH_G25_WHEEL: 1098 - checklist = &lg4ff_main_checklist; 1099 - from_idx = 0; 1100 - to_idx = checklist->count - 2; /* End identity check at G25 */ 1101 - break; 1102 - case USB_DEVICE_ID_LOGITECH_G27_WHEEL: 1103 - checklist = &lg4ff_main_checklist; 1104 - from_idx = 1; /* Start identity check at G27 */ 1105 - to_idx = checklist->count - 3; /* End identity check at G27 */ 1106 - break; 1107 - case USB_DEVICE_ID_LOGITECH_DFGT_WHEEL: 1108 - checklist = &lg4ff_main_checklist; 1109 - from_idx = 0; 1110 - to_idx = checklist->count - 4; /* End identity check at DFGT */ 1111 - break; 1112 - default: 1113 - return 0; 1043 + /* identify current mode from USB PID */ 1044 + for (i = 1; i < ARRAY_SIZE(lg4ff_alternate_modes); i++) { 1045 + dbg_hid("Testing whether PID is %X\n", lg4ff_alternate_modes[i].product_id); 1046 + if (reported_product_id == lg4ff_alternate_modes[i].product_id) 1047 + break; 1114 1048 } 1115 1049 1116 - for (i = from_idx; i <= to_idx; i++) { 1117 - const u16 mask = checklist->models[i]->mask; 1118 - const u16 result = checklist->models[i]->result; 1119 - const u16 real_product_id = checklist->models[i]->real_product_id; 1050 + if (i == ARRAY_SIZE(lg4ff_alternate_modes)) 1051 + return 0; 1120 1052 1121 - if ((bcdDevice & mask) == result) { 1053 + current_mode = BIT(i); 1054 + 1055 + for (i = 0; i < ARRAY_SIZE(lg4ff_main_checklist); i++) { 1056 + const u16 mask = lg4ff_main_checklist[i]->mask; 1057 + const u16 result = lg4ff_main_checklist[i]->result; 1058 + const u16 real_product_id = lg4ff_main_checklist[i]->real_product_id; 1059 + 1060 + if ((current_mode & lg4ff_main_checklist[i]->modes) && \ 1061 + (bcdDevice & mask) == result) { 1122 1062 dbg_hid("Found wheel with real PID %X whose reported PID is %X\n", real_product_id, reported_product_id); 1123 1063 return real_product_id; 1124 1064 } ··· 1280 1246 entry->wdata.set_range(hid, entry->wdata.range); 1281 1247 1282 1248 #ifdef CONFIG_LEDS_CLASS 1283 - /* register led subsystem - G27 only */ 1249 + /* register led subsystem - G27/G29 only */ 1284 1250 entry->wdata.led_state = 0; 1285 1251 for (j = 0; j < 5; j++) 1286 1252 entry->wdata.led[j] = NULL; 1287 1253 1288 - if (lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G27_WHEEL) { 1254 + if (lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G27_WHEEL || 1255 + lg4ff_devices[i].product_id == USB_DEVICE_ID_LOGITECH_G29_WHEEL) { 1289 1256 struct led_classdev *led; 1290 1257 size_t name_sz; 1291 1258 char *name;
+150 -9
drivers/hid/hid-logitech-hidpp.c
··· 33 33 MODULE_PARM_DESC(disable_raw_mode, 34 34 "Disable Raw mode reporting for touchpads and keep firmware gestures."); 35 35 36 + static bool disable_tap_to_click; 37 + module_param(disable_tap_to_click, bool, 0644); 38 + MODULE_PARM_DESC(disable_tap_to_click, 39 + "Disable Tap-To-Click mode reporting for touchpads (only on the K400 currently)."); 40 + 36 41 #define REPORT_ID_HIDPP_SHORT 0x10 37 42 #define REPORT_ID_HIDPP_LONG 0x11 38 43 ··· 46 41 47 42 #define HIDPP_QUIRK_CLASS_WTP BIT(0) 48 43 #define HIDPP_QUIRK_CLASS_M560 BIT(1) 44 + #define HIDPP_QUIRK_CLASS_K400 BIT(2) 49 45 50 46 /* bits 2..20 are reserved for classes */ 51 - #define HIDPP_QUIRK_DELAYED_INIT BIT(21) 47 + #define HIDPP_QUIRK_CONNECT_EVENTS BIT(21) 52 48 #define HIDPP_QUIRK_WTP_PHYSICAL_BUTTONS BIT(22) 49 + #define HIDPP_QUIRK_NO_HIDINPUT BIT(23) 50 + 51 + #define HIDPP_QUIRK_DELAYED_INIT (HIDPP_QUIRK_NO_HIDINPUT | \ 52 + HIDPP_QUIRK_CONNECT_EVENTS) 53 53 54 54 /* 55 55 * There are two hidpp protocols in use, the first version hidpp10 is known ··· 560 550 hidpp_prefix_name(&name, __name_length + 1); 561 551 562 552 return name; 553 + } 554 + 555 + /* -------------------------------------------------------------------------- */ 556 + /* 0x6010: Touchpad FW items */ 557 + /* -------------------------------------------------------------------------- */ 558 + 559 + #define HIDPP_PAGE_TOUCHPAD_FW_ITEMS 0x6010 560 + 561 + #define CMD_TOUCHPAD_FW_ITEMS_SET 0x10 562 + 563 + struct hidpp_touchpad_fw_items { 564 + uint8_t presence; 565 + uint8_t desired_state; 566 + uint8_t state; 567 + uint8_t persistent; 568 + }; 569 + 570 + /** 571 + * send a set state command to the device by reading the current items->state 572 + * field. items is then filled with the current state. 573 + */ 574 + static int hidpp_touchpad_fw_items_set(struct hidpp_device *hidpp, 575 + u8 feature_index, 576 + struct hidpp_touchpad_fw_items *items) 577 + { 578 + struct hidpp_report response; 579 + int ret; 580 + u8 *params = (u8 *)response.fap.params; 581 + 582 + ret = hidpp_send_fap_command_sync(hidpp, feature_index, 583 + CMD_TOUCHPAD_FW_ITEMS_SET, &items->state, 1, &response); 584 + 585 + if (ret > 0) { 586 + hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n", 587 + __func__, ret); 588 + return -EPROTO; 589 + } 590 + if (ret) 591 + return ret; 592 + 593 + items->presence = params[0]; 594 + items->desired_state = params[1]; 595 + items->state = params[2]; 596 + items->persistent = params[3]; 597 + 598 + return 0; 563 599 } 564 600 565 601 /* -------------------------------------------------------------------------- */ ··· 1188 1132 return -1; 1189 1133 } 1190 1134 1135 + /* ------------------------------------------------------------------------- */ 1136 + /* Logitech K400 devices */ 1137 + /* ------------------------------------------------------------------------- */ 1138 + 1139 + /* 1140 + * The Logitech K400 keyboard has an embedded touchpad which is seen 1141 + * as a mouse from the OS point of view. There is a hardware shortcut to disable 1142 + * tap-to-click but the setting is not remembered accross reset, annoying some 1143 + * users. 1144 + * 1145 + * We can toggle this feature from the host by using the feature 0x6010: 1146 + * Touchpad FW items 1147 + */ 1148 + 1149 + struct k400_private_data { 1150 + u8 feature_index; 1151 + }; 1152 + 1153 + static int k400_disable_tap_to_click(struct hidpp_device *hidpp) 1154 + { 1155 + struct k400_private_data *k400 = hidpp->private_data; 1156 + struct hidpp_touchpad_fw_items items = {}; 1157 + int ret; 1158 + u8 feature_type; 1159 + 1160 + if (!k400->feature_index) { 1161 + ret = hidpp_root_get_feature(hidpp, 1162 + HIDPP_PAGE_TOUCHPAD_FW_ITEMS, 1163 + &k400->feature_index, &feature_type); 1164 + if (ret) 1165 + /* means that the device is not powered up */ 1166 + return ret; 1167 + } 1168 + 1169 + ret = hidpp_touchpad_fw_items_set(hidpp, k400->feature_index, &items); 1170 + if (ret) 1171 + return ret; 1172 + 1173 + return 0; 1174 + } 1175 + 1176 + static int k400_allocate(struct hid_device *hdev) 1177 + { 1178 + struct hidpp_device *hidpp = hid_get_drvdata(hdev); 1179 + struct k400_private_data *k400; 1180 + 1181 + k400 = devm_kzalloc(&hdev->dev, sizeof(struct k400_private_data), 1182 + GFP_KERNEL); 1183 + if (!k400) 1184 + return -ENOMEM; 1185 + 1186 + hidpp->private_data = k400; 1187 + 1188 + return 0; 1189 + }; 1190 + 1191 + static int k400_connect(struct hid_device *hdev, bool connected) 1192 + { 1193 + struct hidpp_device *hidpp = hid_get_drvdata(hdev); 1194 + 1195 + if (!connected) 1196 + return 0; 1197 + 1198 + if (!disable_tap_to_click) 1199 + return 0; 1200 + 1201 + return k400_disable_tap_to_click(hidpp); 1202 + } 1203 + 1191 1204 /* -------------------------------------------------------------------------- */ 1192 1205 /* Generic HID++ devices */ 1193 1206 /* -------------------------------------------------------------------------- */ ··· 1330 1205 if (unlikely(hidpp_report_is_connect_event(report))) { 1331 1206 atomic_set(&hidpp->connected, 1332 1207 !(report->rap.params[0] & (1 << 6))); 1333 - if ((hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) && 1208 + if ((hidpp->quirks & HIDPP_QUIRK_CONNECT_EVENTS) && 1334 1209 (schedule_work(&hidpp->work) == 0)) 1335 1210 dbg_hid("%s: connect event already queued\n", __func__); 1336 1211 return 1; ··· 1455 1330 ret = m560_send_config_command(hdev, connected); 1456 1331 if (ret) 1457 1332 return; 1333 + } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_K400) { 1334 + ret = k400_connect(hdev, connected); 1335 + if (ret) 1336 + return; 1458 1337 } 1459 1338 1460 1339 if (!connected || hidpp->delayed_input) 1461 1340 return; 1462 1341 1342 + /* the device is already connected, we can ask for its name and 1343 + * protocol */ 1463 1344 if (!hidpp->protocol_major) { 1464 1345 ret = !hidpp_is_connected(hidpp); 1465 1346 if (ret) { 1466 1347 hid_err(hdev, "Can not get the protocol version.\n"); 1467 1348 return; 1468 1349 } 1350 + hid_info(hdev, "HID++ %u.%u device connected.\n", 1351 + hidpp->protocol_major, hidpp->protocol_minor); 1469 1352 } 1470 1353 1471 - /* the device is already connected, we can ask for its name and 1472 - * protocol */ 1473 - hid_info(hdev, "HID++ %u.%u device connected.\n", 1474 - hidpp->protocol_major, hidpp->protocol_minor); 1354 + if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT)) 1355 + /* if HID created the input nodes for us, we can stop now */ 1356 + return; 1475 1357 1476 1358 if (!hidpp->name || hidpp->name == hdev->name) { 1477 1359 name = hidpp_get_device_name(hidpp); ··· 1531 1399 1532 1400 if (disable_raw_mode) { 1533 1401 hidpp->quirks &= ~HIDPP_QUIRK_CLASS_WTP; 1534 - hidpp->quirks &= ~HIDPP_QUIRK_DELAYED_INIT; 1402 + hidpp->quirks &= ~HIDPP_QUIRK_CONNECT_EVENTS; 1403 + hidpp->quirks &= ~HIDPP_QUIRK_NO_HIDINPUT; 1535 1404 } 1536 1405 1537 1406 if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) { ··· 1541 1408 goto allocate_fail; 1542 1409 } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560) { 1543 1410 ret = m560_allocate(hdev); 1411 + if (ret) 1412 + goto allocate_fail; 1413 + } else if (hidpp->quirks & HIDPP_QUIRK_CLASS_K400) { 1414 + ret = k400_allocate(hdev); 1544 1415 if (ret) 1545 1416 goto allocate_fail; 1546 1417 } ··· 1587 1450 /* Block incoming packets */ 1588 1451 hid_device_io_stop(hdev); 1589 1452 1590 - if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) 1453 + if (hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) 1591 1454 connect_mask &= ~HID_CONNECT_HIDINPUT; 1592 1455 1593 1456 ret = hid_hw_start(hdev, connect_mask); ··· 1596 1459 goto hid_hw_start_fail; 1597 1460 } 1598 1461 1599 - if (hidpp->quirks & HIDPP_QUIRK_DELAYED_INIT) { 1462 + if (hidpp->quirks & HIDPP_QUIRK_CONNECT_EVENTS) { 1600 1463 /* Allow incoming packets */ 1601 1464 hid_device_io_start(hdev); 1602 1465 ··· 1641 1504 HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, 1642 1505 USB_VENDOR_ID_LOGITECH, 0x402d), 1643 1506 .driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560 }, 1507 + { /* Keyboard logitech K400 */ 1508 + HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, 1509 + USB_VENDOR_ID_LOGITECH, 0x4024), 1510 + .driver_data = HIDPP_QUIRK_CONNECT_EVENTS | HIDPP_QUIRK_CLASS_K400 }, 1644 1511 1645 1512 { HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, 1646 1513 USB_VENDOR_ID_LOGITECH, HID_ANY_ID)},
+2
drivers/hid/hid-microsoft.c
··· 278 278 .driver_data = MS_DUPLICATE_USAGES }, 279 279 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3), 280 280 .driver_data = MS_HIDINPUT }, 281 + { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2), 282 + .driver_data = MS_HIDINPUT }, 281 283 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP), 282 284 .driver_data = MS_HIDINPUT }, 283 285 { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3),
+47 -1
drivers/hid/hid-multitouch.c
··· 309 309 .attrs = sysfs_attrs 310 310 }; 311 311 312 + static void mt_get_feature(struct hid_device *hdev, struct hid_report *report) 313 + { 314 + struct mt_device *td = hid_get_drvdata(hdev); 315 + int ret, size = hid_report_len(report); 316 + u8 *buf; 317 + 318 + /* 319 + * Only fetch the feature report if initial reports are not already 320 + * been retrieved. Currently this is only done for Windows 8 touch 321 + * devices. 322 + */ 323 + if (!(hdev->quirks & HID_QUIRK_NO_INIT_REPORTS)) 324 + return; 325 + if (td->mtclass.name != MT_CLS_WIN_8) 326 + return; 327 + 328 + buf = hid_alloc_report_buf(report, GFP_KERNEL); 329 + if (!buf) 330 + return; 331 + 332 + ret = hid_hw_raw_request(hdev, report->id, buf, size, 333 + HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 334 + if (ret < 0) { 335 + dev_warn(&hdev->dev, "failed to fetch feature %d\n", 336 + report->id); 337 + } else { 338 + ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, buf, 339 + size, 0); 340 + if (ret) 341 + dev_warn(&hdev->dev, "failed to report feature\n"); 342 + } 343 + 344 + kfree(buf); 345 + } 346 + 312 347 static void mt_feature_mapping(struct hid_device *hdev, 313 348 struct hid_field *field, struct hid_usage *usage) 314 349 { ··· 362 327 363 328 break; 364 329 case HID_DG_CONTACTMAX: 330 + mt_get_feature(hdev, field->report); 331 + 365 332 td->maxcontact_report_id = field->report->id; 366 333 td->maxcontacts = field->value[0]; 367 334 if (!td->maxcontacts && ··· 380 343 break; 381 344 } 382 345 346 + mt_get_feature(hdev, field->report); 383 347 if (field->value[usage->usage_index] == MT_BUTTONTYPE_CLICKPAD) 384 348 td->is_buttonpad = true; 385 349 ··· 1014 976 case HID_DG_TOUCHSCREEN: 1015 977 /* we do not set suffix = "Touchscreen" */ 1016 978 break; 979 + case HID_DG_TOUCHPAD: 980 + suffix = "Touchpad"; 981 + break; 1017 982 case HID_GD_SYSTEM_CONTROL: 1018 983 suffix = "System Control"; 1019 984 break; ··· 1077 1036 * reports. Fortunately, the Win8 spec says that all touches 1078 1037 * should be sent during each report, making the initialization 1079 1038 * of input reports unnecessary. 1039 + * 1040 + * In addition some touchpads do not behave well if we read 1041 + * all feature reports from them. Instead we prevent 1042 + * initial report fetching and then selectively fetch each 1043 + * report we are interested in. 1080 1044 */ 1081 - hdev->quirks |= HID_QUIRK_NO_INIT_INPUT_REPORTS; 1045 + hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; 1082 1046 1083 1047 td = devm_kzalloc(&hdev->dev, sizeof(struct mt_device), GFP_KERNEL); 1084 1048 if (!td) {
+2 -2
drivers/hid/hid-prodikeys.c
··· 427 427 pm->midi_octave = 2; 428 428 dbg_hid("pcmidi mode: %d octave: %d\n", 429 429 pm->midi_mode, pm->midi_octave); 430 - continue; 430 + continue; 431 431 } else 432 432 key = KEY_MESSENGER; 433 433 break; ··· 695 695 if (err < 0) { 696 696 pk_error("failed to register pc-midi sound card: error %d\n", 697 697 err); 698 - goto fail_register; 698 + goto fail_register; 699 699 } 700 700 701 701 dbg_hid("pcmidi_snd_initialise finished ok\n");
+2
drivers/hid/hid-saitek.c
··· 177 177 static const struct hid_device_id saitek_devices[] = { 178 178 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000), 179 179 .driver_data = SAITEK_FIX_PS1000 }, 180 + { HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT5), 181 + .driver_data = SAITEK_RELEASE_MODE_RAT7 }, 180 182 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7_OLD), 181 183 .driver_data = SAITEK_RELEASE_MODE_RAT7 }, 182 184 { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7),
+21 -4
drivers/hid/hid-sensor-hub.c
··· 593 593 } 594 594 } 595 595 596 + /* Checks if the report descriptor of Thinkpad Helix 2 has a logical 597 + * minimum for magnetic flux axis greater than the maximum */ 598 + if (hdev->product == USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA && 599 + *rsize == 2558 && rdesc[913] == 0x17 && rdesc[914] == 0x40 && 600 + rdesc[915] == 0x81 && rdesc[916] == 0x08 && 601 + rdesc[917] == 0x00 && rdesc[918] == 0x27 && 602 + rdesc[921] == 0x07 && rdesc[922] == 0x00) { 603 + /* Sets negative logical minimum for mag x, y and z */ 604 + rdesc[914] = rdesc[935] = rdesc[956] = 0xc0; 605 + rdesc[915] = rdesc[936] = rdesc[957] = 0x7e; 606 + rdesc[916] = rdesc[937] = rdesc[958] = 0xf7; 607 + rdesc[917] = rdesc[938] = rdesc[959] = 0xff; 608 + } 609 + 596 610 return rdesc; 597 611 } 598 612 ··· 660 646 GFP_KERNEL); 661 647 if (sd->hid_sensor_hub_client_devs == NULL) { 662 648 hid_err(hdev, "Failed to allocate memory for mfd cells\n"); 663 - ret = -ENOMEM; 664 - goto err_stop_hw; 649 + ret = -ENOMEM; 650 + goto err_stop_hw; 665 651 } 666 652 667 653 for (i = 0; i < hdev->maxcollection; ++i) { ··· 698 684 collection->usage); 699 685 if (name == NULL) { 700 686 hid_err(hdev, "Failed MFD device name\n"); 701 - ret = -ENOMEM; 702 - goto err_stop_hw; 687 + ret = -ENOMEM; 688 + goto err_stop_hw; 703 689 } 704 690 sd->hid_sensor_hub_client_devs[ 705 691 sd->hid_sensor_client_cnt].name = name; ··· 790 776 .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, 791 777 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_ITE, 792 778 USB_DEVICE_ID_ITE_LENOVO_YOGA), 779 + .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, 780 + { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_ITE, 781 + USB_DEVICE_ID_ITE_LENOVO_YOGA2), 793 782 .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, 794 783 { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID, 795 784 HID_ANY_ID) },
+1
drivers/hid/i2c-hid/i2c-hid.c
··· 1028 1028 1029 1029 snprintf(hid->name, sizeof(hid->name), "%s %04hX:%04hX", 1030 1030 client->name, hid->vendor, hid->product); 1031 + strlcpy(hid->phys, dev_name(&client->dev), sizeof(hid->phys)); 1031 1032 1032 1033 ret = hid_add_device(hid); 1033 1034 if (ret) {
+2
drivers/hid/usbhid/hid-quirks.c
··· 71 71 { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_AXIS_295, HID_QUIRK_NOGET }, 72 72 { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL }, 73 73 { USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET }, 74 + { USB_VENDOR_ID_DRAGONRISE, USB_DEVICE_ID_DRAGONRISE_WIIU, HID_QUIRK_MULTI_INPUT }, 74 75 { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN, HID_QUIRK_ALWAYS_POLL }, 75 76 { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_009B, HID_QUIRK_ALWAYS_POLL }, 76 77 { USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ELAN_TOUCHSCREEN_0103, HID_QUIRK_ALWAYS_POLL }, ··· 92 91 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2, HID_QUIRK_NO_INIT_REPORTS }, 93 92 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2, HID_QUIRK_NO_INIT_REPORTS }, 94 93 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3, HID_QUIRK_NO_INIT_REPORTS }, 94 + { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_2, HID_QUIRK_NO_INIT_REPORTS }, 95 95 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_PRO_3_JP, HID_QUIRK_NO_INIT_REPORTS }, 96 96 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_3, HID_QUIRK_NO_INIT_REPORTS }, 97 97 { USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_POWER_COVER, HID_QUIRK_NO_INIT_REPORTS },
+40 -18
drivers/hid/wacom_sys.c
··· 211 211 * Bamboo models do not support HID_DG_CONTACTMAX. 212 212 * And, Bamboo Pen only descriptor contains touch. 213 213 */ 214 - if (features->type != BAMBOO_PT) { 214 + if (features->type > BAMBOO_PT) { 215 215 /* ISDv4 touch devices at least supports one touch point */ 216 216 if (finger && !features->touch_max) 217 217 features->touch_max = 1; ··· 222 222 features->x_max = field->logical_maximum; 223 223 if (finger) { 224 224 features->x_phy = field->physical_maximum; 225 - if (features->type != BAMBOO_PT) { 225 + if ((features->type != BAMBOO_PT) && 226 + (features->type != BAMBOO_TOUCH)) { 226 227 features->unit = field->unit; 227 228 features->unitExpo = field->unit_exponent; 228 229 } ··· 233 232 features->y_max = field->logical_maximum; 234 233 if (finger) { 235 234 features->y_phy = field->physical_maximum; 236 - if (features->type != BAMBOO_PT) { 235 + if ((features->type != BAMBOO_PT) && 236 + (features->type != BAMBOO_TOUCH)) { 237 237 features->unit = field->unit; 238 238 features->unitExpo = field->unit_exponent; 239 239 } ··· 422 420 /* MT Tablet PC touch */ 423 421 return wacom_set_device_mode(hdev, 3, 4, 4); 424 422 } 425 - else if (features->type == WACOM_24HDT || features->type == CINTIQ_HYBRID) { 423 + else if (features->type == WACOM_24HDT) { 426 424 return wacom_set_device_mode(hdev, 18, 3, 2); 427 425 } 428 426 else if (features->type == WACOM_27QHDT) { ··· 432 430 return wacom_set_device_mode(hdev, 2, 2, 2); 433 431 } 434 432 } else if (features->device_type & WACOM_DEVICETYPE_PEN) { 435 - if (features->type <= BAMBOO_PT && features->type != WIRELESS) { 433 + if (features->type <= BAMBOO_PT) { 436 434 return wacom_set_device_mode(hdev, 2, 2, 2); 437 435 } 438 436 } ··· 1549 1547 wacom_wac1->features = 1550 1548 *((struct wacom_features *)id->driver_data); 1551 1549 wacom_wac1->features.device_type |= WACOM_DEVICETYPE_PEN; 1552 - if (wacom_wac1->features.type != INTUOSHT && 1553 - wacom_wac1->features.type != BAMBOO_PT) 1554 - wacom_wac1->features.device_type |= WACOM_DEVICETYPE_PAD; 1555 1550 wacom_set_default_phy(&wacom_wac1->features); 1556 1551 wacom_calculate_res(&wacom_wac1->features); 1557 1552 snprintf(wacom_wac1->pen_name, WACOM_NAME_MAX, "%s (WL) Pen", 1558 1553 wacom_wac1->features.name); 1559 - snprintf(wacom_wac1->pad_name, WACOM_NAME_MAX, "%s (WL) Pad", 1560 - wacom_wac1->features.name); 1554 + if (wacom_wac1->features.type < BAMBOO_PEN || 1555 + wacom_wac1->features.type > BAMBOO_PT) { 1556 + snprintf(wacom_wac1->pad_name, WACOM_NAME_MAX, "%s (WL) Pad", 1557 + wacom_wac1->features.name); 1558 + wacom_wac1->features.device_type |= WACOM_DEVICETYPE_PAD; 1559 + } 1561 1560 wacom_wac1->shared->touch_max = wacom_wac1->features.touch_max; 1562 1561 wacom_wac1->shared->type = wacom_wac1->features.type; 1563 1562 wacom_wac1->pid = wacom_wac->pid; ··· 1569 1566 1570 1567 /* Touch interface */ 1571 1568 if (wacom_wac1->features.touch_max || 1572 - wacom_wac1->features.type == INTUOSHT) { 1569 + (wacom_wac1->features.type >= INTUOSHT && 1570 + wacom_wac1->features.type <= BAMBOO_PT)) { 1573 1571 wacom_wac2->features = 1574 1572 *((struct wacom_features *)id->driver_data); 1575 1573 wacom_wac2->features.pktlen = WACOM_PKGLEN_BBTOUCH3; ··· 1579 1575 wacom_calculate_res(&wacom_wac2->features); 1580 1576 snprintf(wacom_wac2->touch_name, WACOM_NAME_MAX, 1581 1577 "%s (WL) Finger",wacom_wac2->features.name); 1582 - snprintf(wacom_wac2->pad_name, WACOM_NAME_MAX, 1583 - "%s (WL) Pad",wacom_wac2->features.name); 1584 1578 if (wacom_wac1->features.touch_max) 1585 1579 wacom_wac2->features.device_type |= WACOM_DEVICETYPE_TOUCH; 1586 - if (wacom_wac1->features.type == INTUOSHT || 1587 - wacom_wac1->features.type == BAMBOO_PT) 1580 + if (wacom_wac1->features.type >= INTUOSHT && 1581 + wacom_wac1->features.type <= BAMBOO_PT) { 1582 + snprintf(wacom_wac2->pad_name, WACOM_NAME_MAX, 1583 + "%s (WL) Pad",wacom_wac2->features.name); 1588 1584 wacom_wac2->features.device_type |= WACOM_DEVICETYPE_PAD; 1585 + } 1589 1586 wacom_wac2->pid = wacom_wac->pid; 1590 1587 error = wacom_allocate_inputs(wacom2) || 1591 1588 wacom_register_inputs(wacom2); 1592 1589 if (error) 1593 1590 goto fail; 1594 1591 1595 - if (wacom_wac1->features.type == INTUOSHT && 1592 + if ((wacom_wac1->features.type == INTUOSHT || 1593 + wacom_wac1->features.type == INTUOSHT2) && 1596 1594 wacom_wac1->features.touch_max) 1597 1595 wacom_wac->shared->touch_input = wacom_wac2->touch_input; 1598 1596 } ··· 1818 1812 /* Note that if query fails it is not a hard failure */ 1819 1813 wacom_query_tablet_data(hdev, features); 1820 1814 1815 + /* touch only Bamboo doesn't support pen */ 1816 + if ((features->type == BAMBOO_TOUCH) && 1817 + (features->device_type & WACOM_DEVICETYPE_PEN)) { 1818 + error = -ENODEV; 1819 + goto fail_hw_start; 1820 + } 1821 + 1822 + /* pen only Bamboo neither support touch nor pad */ 1823 + if ((features->type == BAMBOO_PEN) && 1824 + ((features->device_type & WACOM_DEVICETYPE_TOUCH) || 1825 + (features->device_type & WACOM_DEVICETYPE_PAD))) { 1826 + error = -ENODEV; 1827 + goto fail_hw_start; 1828 + } 1829 + 1821 1830 if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR) 1822 1831 error = hid_hw_open(hdev); 1823 1832 1824 - if (wacom_wac->features.type == INTUOSHT && 1825 - wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH) { 1833 + if ((wacom_wac->features.type == INTUOSHT || 1834 + wacom_wac->features.type == INTUOSHT2) && 1835 + (wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH)) { 1826 1836 wacom_wac->shared->touch_input = wacom_wac->touch_input; 1827 1837 } 1828 1838
+151 -40
drivers/hid/wacom_wac.c
··· 765 765 /* general pen packet */ 766 766 if ((data[1] & 0xb8) == 0xa0) { 767 767 t = (data[6] << 2) | ((data[7] >> 6) & 3); 768 - if (features->type >= INTUOS4S && features->type <= CINTIQ_HYBRID) { 768 + if (features->pressure_max == 2047) { 769 769 t = (t << 1) | (data[1] & 1); 770 770 } 771 771 input_report_abs(input, ABS_PRESSURE, t); 772 - input_report_abs(input, ABS_TILT_X, 772 + if (features->type != INTUOSHT2) { 773 + input_report_abs(input, ABS_TILT_X, 773 774 (((data[7] << 1) & 0x7e) | (data[8] >> 7)) - 64); 774 - input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64); 775 + input_report_abs(input, ABS_TILT_Y, (data[8] & 0x7f) - 64); 776 + } 775 777 input_report_key(input, BTN_STYLUS, data[1] & 2); 776 778 input_report_key(input, BTN_STYLUS2, data[1] & 4); 777 779 input_report_key(input, BTN_TOUCH, t > 10); ··· 801 799 data[0] != WACOM_REPORT_INTUOSREAD && 802 800 data[0] != WACOM_REPORT_INTUOSWRITE && 803 801 data[0] != WACOM_REPORT_INTUOSPAD && 802 + data[0] != WACOM_REPORT_INTUOS_PEN && 804 803 data[0] != WACOM_REPORT_CINTIQ && 805 804 data[0] != WACOM_REPORT_CINTIQPAD && 806 805 data[0] != WACOM_REPORT_INTUOS5PAD) { ··· 951 948 } else { 952 949 input_report_abs(input, ABS_MISC, 0); 953 950 } 951 + 952 + } else if (features->type == CINTIQ_COMPANION_2) { 953 + input_report_key(input, BTN_1, (data[1] & 0x02)); 954 + input_report_key(input, BTN_2, (data[2] & 0x01)); 955 + input_report_key(input, BTN_3, (data[2] & 0x02)); 956 + input_report_key(input, BTN_4, (data[2] & 0x04)); 957 + input_report_key(input, BTN_5, (data[2] & 0x08)); 958 + input_report_key(input, BTN_6, (data[1] & 0x04)); 959 + 960 + input_report_key(input, BTN_7, (data[2] & 0x10)); /* Right */ 961 + input_report_key(input, BTN_8, (data[2] & 0x20)); /* Up */ 962 + input_report_key(input, BTN_9, (data[2] & 0x40)); /* Left */ 963 + input_report_key(input, BTN_A, (data[2] & 0x80)); /* Down */ 964 + input_report_key(input, BTN_0, (data[1] & 0x01)); /* Center */ 965 + 966 + if (data[2] | (data[1] & 0x07)) { 967 + input_report_abs(input, ABS_MISC, PAD_DEVICE_ID); 968 + } else { 969 + input_report_abs(input, ABS_MISC, 0); 970 + } 971 + 954 972 } else if (features->type >= INTUOS5S && features->type <= INTUOSPL) { 955 973 int i; 956 974 ··· 1652 1628 wacom_map_usage(input, usage, field, EV_KEY, BTN_TOUCH, 0); 1653 1629 break; 1654 1630 case HID_DG_CONTACTCOUNT: 1631 + wacom_wac->hid_data.cc_report = field->report->id; 1655 1632 wacom_wac->hid_data.cc_index = field->index; 1656 1633 wacom_wac->hid_data.cc_value_index = usage->usage_index; 1657 1634 break; ··· 1740 1715 struct wacom_wac *wacom_wac = &wacom->wacom_wac; 1741 1716 struct hid_data* hid_data = &wacom_wac->hid_data; 1742 1717 1743 - if (hid_data->cc_index >= 0) { 1718 + if (hid_data->cc_report != 0 && 1719 + hid_data->cc_report != report->id) { 1720 + int i; 1721 + 1722 + hid_data->cc_report = report->id; 1723 + hid_data->cc_index = -1; 1724 + hid_data->cc_value_index = -1; 1725 + 1726 + for (i = 0; i < report->maxfield; i++) { 1727 + struct hid_field *field = report->field[i]; 1728 + int j; 1729 + 1730 + for (j = 0; j < field->maxusage; j++) { 1731 + if (field->usage[j].hid == HID_DG_CONTACTCOUNT) { 1732 + hid_data->cc_index = i; 1733 + hid_data->cc_value_index = j; 1734 + 1735 + /* break */ 1736 + i = report->maxfield; 1737 + j = field->maxusage; 1738 + } 1739 + } 1740 + } 1741 + } 1742 + if (hid_data->cc_report != 0 && 1743 + hid_data->cc_index >= 0) { 1744 1744 struct hid_field *field = report->field[hid_data->cc_index]; 1745 1745 int value = field->value[hid_data->cc_value_index]; 1746 1746 if (value) ··· 1946 1896 int y = (data[3] << 4) | (data[4] & 0x0f); 1947 1897 int width, height; 1948 1898 1949 - if (features->type >= INTUOSPS && features->type <= INTUOSHT) { 1899 + if (features->type >= INTUOSPS && features->type <= INTUOSHT2) { 1950 1900 width = data[5] * 100; 1951 1901 height = data[6] * 100; 1952 1902 } else { ··· 1974 1924 struct input_dev *input = wacom->pad_input; 1975 1925 struct wacom_features *features = &wacom->features; 1976 1926 1977 - if (features->type == INTUOSHT) { 1927 + if (features->type == INTUOSHT || features->type == INTUOSHT2) { 1978 1928 input_report_key(input, BTN_LEFT, (data[1] & 0x02) != 0); 1979 1929 input_report_key(input, BTN_BACK, (data[1] & 0x08) != 0); 1980 1930 } else { ··· 1989 1939 { 1990 1940 unsigned char *data = wacom->data; 1991 1941 int count = data[1] & 0x07; 1992 - int i; 1942 + int touch_changed = 0, i; 1993 1943 1994 1944 if (data[0] != 0x02) 1995 1945 return 0; ··· 1999 1949 int offset = (8 * i) + 2; 2000 1950 int msg_id = data[offset]; 2001 1951 2002 - if (msg_id >= 2 && msg_id <= 17) 1952 + if (msg_id >= 2 && msg_id <= 17) { 2003 1953 wacom_bpt3_touch_msg(wacom, data + offset); 2004 - else if (msg_id == 128) 1954 + touch_changed++; 1955 + } else if (msg_id == 128) 2005 1956 wacom_bpt3_button_msg(wacom, data + offset); 2006 1957 2007 1958 } 2008 1959 2009 - /* only update the touch if we actually have a touchpad */ 2010 - if (wacom->touch_registered) { 1960 + /* only update touch if we actually have a touchpad and touch data changed */ 1961 + if (wacom->touch_registered && touch_changed) { 2011 1962 input_mt_sync_frame(wacom->touch_input); 2012 1963 wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom); 2013 1964 } ··· 2089 2038 2090 2039 static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len) 2091 2040 { 2092 - if (len == WACOM_PKGLEN_BBTOUCH) 2041 + struct wacom_features *features = &wacom->features; 2042 + 2043 + if ((features->type == INTUOSHT2) && 2044 + (features->device_type & WACOM_DEVICETYPE_PEN)) 2045 + return wacom_intuos_irq(wacom); 2046 + else if (len == WACOM_PKGLEN_BBTOUCH) 2093 2047 return wacom_bpt_touch(wacom); 2094 2048 else if (len == WACOM_PKGLEN_BBTOUCH3) 2095 2049 return wacom_bpt3_touch(wacom); ··· 2201 2145 if (connected) { 2202 2146 int pid, battery, charging; 2203 2147 2204 - if ((wacom->shared->type == INTUOSHT) && 2148 + if ((wacom->shared->type == INTUOSHT || 2149 + wacom->shared->type == INTUOSHT2) && 2205 2150 wacom->shared->touch_input && 2206 2151 wacom->shared->touch_max) { 2207 2152 input_report_switch(wacom->shared->touch_input, ··· 2240 2183 if (data[0] != WACOM_REPORT_USB) 2241 2184 return 0; 2242 2185 2243 - if (features->type == INTUOSHT && 2186 + if ((features->type == INTUOSHT || 2187 + features->type == INTUOSHT2) && 2244 2188 wacom_wac->shared->touch_input && 2245 2189 features->touch_max) { 2246 2190 input_report_switch(wacom_wac->shared->touch_input, ··· 2322 2264 case WACOM_27QHD: 2323 2265 case DTK: 2324 2266 case CINTIQ_HYBRID: 2267 + case CINTIQ_COMPANION_2: 2325 2268 sync = wacom_intuos_irq(wacom_wac); 2326 2269 break; 2327 2270 ··· 2359 2300 break; 2360 2301 2361 2302 case BAMBOO_PT: 2303 + case BAMBOO_PEN: 2304 + case BAMBOO_TOUCH: 2362 2305 case INTUOSHT: 2306 + case INTUOSHT2: 2363 2307 if (wacom_wac->data[0] == WACOM_REPORT_USB) 2364 2308 sync = wacom_status_irq(wacom_wac, len); 2365 2309 else ··· 2399 2337 } 2400 2338 } 2401 2339 2402 - static void wacom_setup_cintiq(struct wacom_wac *wacom_wac) 2340 + static void wacom_setup_basic_pro_pen(struct wacom_wac *wacom_wac) 2403 2341 { 2404 2342 struct input_dev *input_dev = wacom_wac->pen_input; 2405 2343 2406 2344 input_set_capability(input_dev, EV_MSC, MSC_SERIAL); 2407 2345 2408 - __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); 2409 2346 __set_bit(BTN_TOOL_PEN, input_dev->keybit); 2410 - __set_bit(BTN_TOOL_BRUSH, input_dev->keybit); 2411 - __set_bit(BTN_TOOL_PENCIL, input_dev->keybit); 2412 - __set_bit(BTN_TOOL_AIRBRUSH, input_dev->keybit); 2413 2347 __set_bit(BTN_STYLUS, input_dev->keybit); 2414 2348 __set_bit(BTN_STYLUS2, input_dev->keybit); 2415 2349 2416 2350 input_set_abs_params(input_dev, ABS_DISTANCE, 2417 2351 0, wacom_wac->features.distance_max, 0, 0); 2352 + } 2353 + 2354 + static void wacom_setup_cintiq(struct wacom_wac *wacom_wac) 2355 + { 2356 + struct input_dev *input_dev = wacom_wac->pen_input; 2357 + 2358 + wacom_setup_basic_pro_pen(wacom_wac); 2359 + 2360 + __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); 2361 + __set_bit(BTN_TOOL_BRUSH, input_dev->keybit); 2362 + __set_bit(BTN_TOOL_PENCIL, input_dev->keybit); 2363 + __set_bit(BTN_TOOL_AIRBRUSH, input_dev->keybit); 2364 + 2418 2365 input_set_abs_params(input_dev, ABS_WHEEL, 0, 1023, 0, 0); 2419 2366 input_set_abs_params(input_dev, ABS_TILT_X, -64, 63, 0, 0); 2420 2367 input_abs_set_res(input_dev, ABS_TILT_X, 57); ··· 2458 2387 2459 2388 /* The pen and pad share the same interface on most devices */ 2460 2389 if (features->type == GRAPHIRE_BT || features->type == WACOM_G4 || 2461 - features->type == DTUS || features->type == WACOM_MO || 2462 - (features->type >= INTUOS3S && features->type <= WACOM_13HD && 2463 - features->type != INTUOSHT)) { 2390 + features->type == DTUS || 2391 + (features->type >= INTUOS3S && features->type <= WACOM_MO)) { 2464 2392 if (features->device_type & WACOM_DEVICETYPE_PEN) 2465 2393 features->device_type |= WACOM_DEVICETYPE_PAD; 2466 2394 } ··· 2476 2406 * interface (PacketSize of WACOM_PKGLEN_BBTOUCH3), override the 2477 2407 * tablet values. 2478 2408 */ 2479 - if ((features->type >= INTUOS5S && features->type <= INTUOSHT) || 2480 - (features->type == BAMBOO_PT)) { 2409 + if ((features->type >= INTUOS5S && features->type <= INTUOSPL) || 2410 + (features->type >= INTUOSHT && features->type <= BAMBOO_PT)) { 2481 2411 if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { 2482 2412 if (features->touch_max) 2483 2413 features->device_type |= WACOM_DEVICETYPE_TOUCH; 2484 - if (features->type == BAMBOO_PT || features->type == INTUOSHT) 2414 + if (features->type >= INTUOSHT || features->type <= BAMBOO_PT) 2485 2415 features->device_type |= WACOM_DEVICETYPE_PAD; 2486 2416 2487 2417 features->x_max = 4096; ··· 2590 2520 case CINTIQ: 2591 2521 case WACOM_13HD: 2592 2522 case CINTIQ_HYBRID: 2523 + case CINTIQ_COMPANION_2: 2593 2524 input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); 2594 2525 input_abs_set_res(input_dev, ABS_Z, 287); 2595 2526 __set_bit(INPUT_PROP_DIRECT, input_dev->propbit); ··· 2669 2598 2670 2599 case INTUOSHT: 2671 2600 case BAMBOO_PT: 2672 - __clear_bit(ABS_MISC, input_dev->absbit); 2673 - 2601 + case BAMBOO_PEN: 2602 + case INTUOSHT2: 2674 2603 __set_bit(INPUT_PROP_POINTER, input_dev->propbit); 2675 - __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); 2676 - __set_bit(BTN_TOOL_PEN, input_dev->keybit); 2677 - __set_bit(BTN_STYLUS, input_dev->keybit); 2678 - __set_bit(BTN_STYLUS2, input_dev->keybit); 2679 - input_set_abs_params(input_dev, ABS_DISTANCE, 0, 2604 + 2605 + if (features->type == INTUOSHT2) { 2606 + wacom_setup_basic_pro_pen(wacom_wac); 2607 + } else { 2608 + __clear_bit(ABS_MISC, input_dev->absbit); 2609 + __set_bit(BTN_TOOL_PEN, input_dev->keybit); 2610 + __set_bit(BTN_TOOL_RUBBER, input_dev->keybit); 2611 + __set_bit(BTN_STYLUS, input_dev->keybit); 2612 + __set_bit(BTN_STYLUS2, input_dev->keybit); 2613 + input_set_abs_params(input_dev, ABS_DISTANCE, 0, 2680 2614 features->distance_max, 2681 2615 0, 0); 2616 + } 2682 2617 break; 2683 2618 case BAMBOO_PAD: 2684 2619 __clear_bit(ABS_MISC, input_dev->absbit); ··· 2765 2688 break; 2766 2689 2767 2690 case INTUOSHT: 2691 + case INTUOSHT2: 2768 2692 input_dev->evbit[0] |= BIT_MASK(EV_SW); 2769 2693 __set_bit(SW_MUTE_DEVICE, input_dev->swbit); 2770 2694 /* fall through */ 2771 2695 2772 2696 case BAMBOO_PT: 2697 + case BAMBOO_TOUCH: 2773 2698 if (features->pktlen == WACOM_PKGLEN_BBTOUCH3) { 2774 2699 input_set_abs_params(input_dev, 2775 2700 ABS_MT_TOUCH_MAJOR, ··· 2831 2752 switch (features->type) { 2832 2753 2833 2754 case CINTIQ_HYBRID: 2755 + case CINTIQ_COMPANION_2: 2834 2756 case DTK: 2835 2757 case DTUS: 2836 2758 case GRAPHIRE_BT: ··· 2925 2845 2926 2846 case INTUOSHT: 2927 2847 case BAMBOO_PT: 2848 + case BAMBOO_TOUCH: 2849 + case INTUOSHT2: 2928 2850 __clear_bit(ABS_MISC, input_dev->absbit); 2929 2851 2930 2852 __set_bit(BTN_LEFT, input_dev->keybit); ··· 3317 3235 { "Wacom Intuos2 6x8", 20320, 16240, 1023, 31, 3318 3236 INTUOS, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 3319 3237 static const struct wacom_features wacom_features_0x84 = 3320 - { "Wacom Wireless Receiver", 0, 0, 0, 0, 3321 - WIRELESS, 0, 0, .touch_max = 16 }; 3238 + { "Wacom Wireless Receiver", .type = WIRELESS, .touch_max = 16 }; 3322 3239 static const struct wacom_features wacom_features_0xD0 = 3323 3240 { "Wacom Bamboo 2FG", 14720, 9200, 1023, 31, 3324 - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 }; 3241 + BAMBOO_TOUCH, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 }; 3325 3242 static const struct wacom_features wacom_features_0xD1 = 3326 3243 { "Wacom Bamboo 2FG 4x5", 14720, 9200, 1023, 31, 3327 3244 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 }; ··· 3332 3251 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 }; 3333 3252 static const struct wacom_features wacom_features_0xD4 = 3334 3253 { "Wacom Bamboo Pen", 14720, 9200, 1023, 31, 3335 - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 3254 + BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 3336 3255 static const struct wacom_features wacom_features_0xD5 = 3337 3256 { "Wacom Bamboo Pen 6x8", 21648, 13700, 1023, 31, 3338 - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 3257 + BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 3339 3258 static const struct wacom_features wacom_features_0xD6 = 3340 3259 { "Wacom BambooPT 2FG 4x5", 14720, 9200, 1023, 31, 3341 3260 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 2 }; ··· 3362 3281 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16 }; 3363 3282 static const struct wacom_features wacom_features_0x300 = 3364 3283 { "Wacom Bamboo One S", 14720, 9225, 1023, 31, 3365 - BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 3284 + BAMBOO_PEN, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; 3366 3285 static const struct wacom_features wacom_features_0x301 = 3367 3286 { "Wacom Bamboo One M", 21648, 13530, 1023, 31, 3368 3287 BAMBOO_PT, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; ··· 3405 3324 static const struct wacom_features wacom_features_0x319 = 3406 3325 { "Wacom Wireless Bamboo PAD", 4095, 4095, /* Touch */ 3407 3326 .type = BAMBOO_PAD, 35, 48, .touch_max = 4 }; 3327 + static const struct wacom_features wacom_features_0x325 = 3328 + { "Wacom ISDv5 325", 59552, 33848, 2047, 63, 3329 + CINTIQ_COMPANION_2, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 11, 3330 + WACOM_CINTIQ_OFFSET, WACOM_CINTIQ_OFFSET, 3331 + .oVid = USB_VENDOR_ID_WACOM, .oPid = 0x326 }; 3332 + static const struct wacom_features wacom_features_0x326 = /* Touch */ 3333 + { "Wacom ISDv5 326", .type = HID_GENERIC, .oVid = USB_VENDOR_ID_WACOM, 3334 + .oPid = 0x325 }; 3408 3335 static const struct wacom_features wacom_features_0x323 = 3409 3336 { "Wacom Intuos P M", 21600, 13500, 1023, 31, 3410 3337 INTUOSHT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 3411 3338 .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; 3412 3339 static const struct wacom_features wacom_features_0x331 = 3413 - { "Wacom Express Key Remote", 0, 0, 0, 0, 3414 - REMOTE, 0, 0, 18, .check_for_hid_type = true, 3340 + { "Wacom Express Key Remote", .type = REMOTE, 3341 + .numbered_buttons = 18, .check_for_hid_type = true, 3415 3342 .hid_type = HID_TYPE_USBNONE }; 3343 + static const struct wacom_features wacom_features_0x33B = 3344 + { "Wacom Intuos S 2", 15200, 9500, 2047, 63, 3345 + INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 3346 + .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; 3347 + static const struct wacom_features wacom_features_0x33C = 3348 + { "Wacom Intuos PT S 2", 15200, 9500, 2047, 63, 3349 + INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16, 3350 + .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; 3351 + static const struct wacom_features wacom_features_0x33D = 3352 + { "Wacom Intuos P M 2", 21600, 13500, 2047, 63, 3353 + INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 3354 + .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; 3355 + static const struct wacom_features wacom_features_0x33E = 3356 + { "Wacom Intuos PT M 2", 21600, 13500, 2047, 63, 3357 + INTUOSHT2, WACOM_INTUOS_RES, WACOM_INTUOS_RES, .touch_max = 16, 3358 + .check_for_hid_type = true, .hid_type = HID_TYPE_USBNONE }; 3416 3359 3417 3360 static const struct wacom_features wacom_features_HID_ANY_ID = 3418 3361 { "Wacom HID", .type = HID_GENERIC }; ··· 3588 3483 { USB_DEVICE_WACOM(0x318) }, 3589 3484 { USB_DEVICE_WACOM(0x319) }, 3590 3485 { USB_DEVICE_WACOM(0x323) }, 3486 + { USB_DEVICE_WACOM(0x325) }, 3487 + { USB_DEVICE_WACOM(0x326) }, 3591 3488 { USB_DEVICE_WACOM(0x32A) }, 3592 3489 { USB_DEVICE_WACOM(0x32B) }, 3593 3490 { USB_DEVICE_WACOM(0x32C) }, ··· 3598 3491 { USB_DEVICE_WACOM(0x333) }, 3599 3492 { USB_DEVICE_WACOM(0x335) }, 3600 3493 { USB_DEVICE_WACOM(0x336) }, 3494 + { USB_DEVICE_WACOM(0x33B) }, 3495 + { USB_DEVICE_WACOM(0x33C) }, 3496 + { USB_DEVICE_WACOM(0x33D) }, 3497 + { USB_DEVICE_WACOM(0x33E) }, 3601 3498 { USB_DEVICE_WACOM(0x4001) }, 3602 3499 { USB_DEVICE_WACOM(0x4004) }, 3603 3500 { USB_DEVICE_WACOM(0x5000) },
+8 -2
drivers/hid/wacom_wac.h
··· 68 68 #define WACOM_REPORT_BPAD_PEN 3 69 69 #define WACOM_REPORT_BPAD_TOUCH 16 70 70 #define WACOM_REPORT_DEVICE_LIST 16 71 + #define WACOM_REPORT_INTUOS_PEN 16 71 72 #define WACOM_REPORT_REMOTE 17 72 73 73 74 /* device quirks */ ··· 118 117 INTUOSPS, 119 118 INTUOSPM, 120 119 INTUOSPL, 121 - INTUOSHT, 122 120 WACOM_21UX2, 123 121 WACOM_22HD, 124 122 DTK, 125 123 WACOM_24HD, 126 124 WACOM_27QHD, 127 125 CINTIQ_HYBRID, 126 + CINTIQ_COMPANION_2, 128 127 CINTIQ, 129 128 WACOM_BEE, 130 129 WACOM_13HD, 131 130 WACOM_MO, 132 - WIRELESS, 131 + BAMBOO_PEN, 132 + INTUOSHT, 133 + INTUOSHT2, 134 + BAMBOO_TOUCH, 133 135 BAMBOO_PT, 134 136 WACOM_24HDT, 135 137 WACOM_27QHDT, 136 138 BAMBOO_PAD, 139 + WIRELESS, 137 140 REMOTE, 138 141 TABLETPC, /* add new TPC below */ 139 142 TABLETPCE, ··· 203 198 int width; 204 199 int height; 205 200 int id; 201 + int cc_report; 206 202 int cc_index; 207 203 int cc_value_index; 208 204 int num_expected;