mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-11 00:08:50 +00:00
Assorted HID drivers updates and fixes for 6.1
-----BEGIN PGP SIGNATURE----- iQJSBAABCAA8FiEEoEVH9lhNrxiMPSyI7MXwXhnZSjYFAmM9UhweHGJlbmphbWlu LnRpc3NvaXJlc0ByZWRoYXQuY29tAAoJEOzF8F4Z2Uo2pE8P/23iRM/+kO2KDeU8 3lp6z1Ny/Hp0HPAsWCgAywgPcNoG+JaxBdAFv2YXky0RI3/OMtI+6FK36XJs63E5 twjFwySxupY2CXLIXjSkLunAWlZUwtpRLnrBpPwgG87wKkI8IvPmv1AwkiYO9GD9 Q0vtd+GaE7Bx33XBga4IcVx1hODL/SDeT1ozS1czhv4NNutRsR7lxCsn6qKly9WK zwoTHEOIJnq4oLZElmnxuJeUU1vvRXy4g+xPV+rfqbnlZUh0zQeD//1G7lRchEel t6l5SDR9pZ+zbWUw7gtU/KoUtf4eJ5+4fX9ejMqtEvoQLquePYQOD6Pyzjqlq7ND x31MjTmVHaav4GZiON7ztkbUncnERYRVRiLr5iDw9xcS5MVnMg2a07VgY6Ld5Xnl FQ0ZaO7T1HUxl2Lig7kRdX/kIDVNMIgfS1e0H6yJC3b5sbouwSRknu6EoumK/6tG nx8njAYi8t+2DN7d/82Ck1Z3CfY100WONahBAVZeyNtu0p9QH1k0b6srZiCpFTvQ ffl6lXboiYYx3hV/HNoDiIJPTh/zJhjEAzi1MgUKlbt5ImYWJQ0tAnhY16e3+xt5 83ryRFdUmjwxE/0Oh0yi1Nk8VWid+40DCpay9Qm6veyRr+ECviChwoI0OUFsTrfR p2+2ghZHwFf4JTpUNlHdV0Kz0OJ9 =lo26 -----END PGP SIGNATURE----- Merge tag 'for-linus-2022100501' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid Pull HID updates from Benjamin Tissoires: - handle of all Logitech Bluetooth HID++ devices in the Logitech HID++ drivers (Bastien Nocera) - fix broken atomic checks in hid-multitouch by adding memory barriers (Andri Yngvason) - better handling of devices with AMD SFH1.1 (Basavaraj Natikar) - better support of Nintendo clone controllers (Icenowy Zheng and Johnothan King) - Support for various RC controllers (Marcus Folkesson) - Add UGEEv2 support in hid-uclogic (XP-PEN Deco Pro S and Parblo A610 PRO) (José Expósito) - some conversions to use dev_groups (Greg Kroah-Hartman) - HID-BPF preparatory patches, mostly to convert blank defines as enums (Benjamin Tissoires) * tag 'for-linus-2022100501' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (38 commits) HID: wacom: add three styli to wacom_intuos_get_tool_type HID: amd_sfh: Handle condition of "no sensors" for SFH1.1 HID: amd_sfh: Change dev_err to dev_dbg for additional debug info HID: nintendo: check analog user calibration for plausibility HID: nintendo: deregister home LED when it fails HID: roccat: Fix use-after-free in roccat_read() hid: topre: Add driver fixing report descriptor HID: multitouch: Add memory barriers HID: convert defines of HID class requests into a proper enum HID: export hid_report_type to uapi HID: core: store the unique system identifier in hid_device HID: Add driver for PhoenixRC Flight Controller HID: Add driver for VRC-2 Car Controller HID: sony: Fix double word in comments hid: hid-logitech-hidpp: avoid unnecessary assignments in hidpp_connect_event HID: logitech-hidpp: Detect hi-res scrolling support HID: logitech-hidpp: Remove hard-coded "Sw. Id." for HID++ 2.0 commands HID: logitech-hidpp: Fix "Sw. Id." for HID++ 2.0 commands HID: logitech-hidpp: Remove special-casing of Bluetooth devices HID: logitech-hidpp: Enable HID++ for all the Logitech Bluetooth devices ...
This commit is contained in:
commit
79d11de963
12
MAINTAINERS
12
MAINTAINERS
@ -9082,6 +9082,12 @@ L: linux-input@vger.kernel.org
|
|||||||
S: Supported
|
S: Supported
|
||||||
F: drivers/hid/hid-playstation.c
|
F: drivers/hid/hid-playstation.c
|
||||||
|
|
||||||
|
HID PHOENIX RC FLIGHT CONTROLLER
|
||||||
|
M: Marcus Folkesson <marcus.folkesson@gmail.com>
|
||||||
|
L: linux-input@vger.kernel.org
|
||||||
|
S: Maintained
|
||||||
|
F: drivers/hid/hid-pxrc.c
|
||||||
|
|
||||||
HID SENSOR HUB DRIVERS
|
HID SENSOR HUB DRIVERS
|
||||||
M: Jiri Kosina <jikos@kernel.org>
|
M: Jiri Kosina <jikos@kernel.org>
|
||||||
M: Jonathan Cameron <jic23@kernel.org>
|
M: Jonathan Cameron <jic23@kernel.org>
|
||||||
@ -9094,6 +9100,12 @@ F: drivers/hid/hid-sensor-*
|
|||||||
F: drivers/iio/*/hid-*
|
F: drivers/iio/*/hid-*
|
||||||
F: include/linux/hid-sensor-*
|
F: include/linux/hid-sensor-*
|
||||||
|
|
||||||
|
HID VRC-2 CAR CONTROLLER DRIVER
|
||||||
|
M: Marcus Folkesson <marcus.folkesson@gmail.com>
|
||||||
|
L: linux-input@vger.kernel.org
|
||||||
|
S: Maintained
|
||||||
|
F: drivers/hid/hid-vrc2.c
|
||||||
|
|
||||||
HID WACOM DRIVER
|
HID WACOM DRIVER
|
||||||
M: Ping Cheng <ping.cheng@wacom.com>
|
M: Ping Cheng <ping.cheng@wacom.com>
|
||||||
M: Jason Gerecke <jason.gerecke@wacom.com>
|
M: Jason Gerecke <jason.gerecke@wacom.com>
|
||||||
|
@ -28,7 +28,6 @@ if HID
|
|||||||
|
|
||||||
config HID_BATTERY_STRENGTH
|
config HID_BATTERY_STRENGTH
|
||||||
bool "Battery level reporting for HID devices"
|
bool "Battery level reporting for HID devices"
|
||||||
depends on HID
|
|
||||||
select POWER_SUPPLY
|
select POWER_SUPPLY
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
@ -38,7 +37,6 @@ config HID_BATTERY_STRENGTH
|
|||||||
|
|
||||||
config HIDRAW
|
config HIDRAW
|
||||||
bool "/dev/hidraw raw HID device support"
|
bool "/dev/hidraw raw HID device support"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Say Y here if you want to support HID devices (from the USB
|
Say Y here if you want to support HID devices (from the USB
|
||||||
specification standpoint) that aren't strictly user interface
|
specification standpoint) that aren't strictly user interface
|
||||||
@ -57,7 +55,6 @@ config HIDRAW
|
|||||||
|
|
||||||
config UHID
|
config UHID
|
||||||
tristate "User-space I/O driver support for HID subsystem"
|
tristate "User-space I/O driver support for HID subsystem"
|
||||||
depends on HID
|
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
Say Y here if you want to provide HID I/O Drivers from user-space.
|
Say Y here if you want to provide HID I/O Drivers from user-space.
|
||||||
@ -78,7 +75,6 @@ config UHID
|
|||||||
|
|
||||||
config HID_GENERIC
|
config HID_GENERIC
|
||||||
tristate "Generic HID driver"
|
tristate "Generic HID driver"
|
||||||
depends on HID
|
|
||||||
default HID
|
default HID
|
||||||
help
|
help
|
||||||
Support for generic devices on the HID bus. This includes most
|
Support for generic devices on the HID bus. This includes most
|
||||||
@ -90,11 +86,9 @@ config HID_GENERIC
|
|||||||
If unsure, say Y.
|
If unsure, say Y.
|
||||||
|
|
||||||
menu "Special HID drivers"
|
menu "Special HID drivers"
|
||||||
depends on HID
|
|
||||||
|
|
||||||
config HID_A4TECH
|
config HID_A4TECH
|
||||||
tristate "A4TECH mice"
|
tristate "A4TECH mice"
|
||||||
depends on HID
|
|
||||||
default !EXPERT
|
default !EXPERT
|
||||||
help
|
help
|
||||||
Support for some A4TECH mice with two scroll wheels.
|
Support for some A4TECH mice with two scroll wheels.
|
||||||
@ -113,7 +107,6 @@ config HID_ACCUTOUCH
|
|||||||
|
|
||||||
config HID_ACRUX
|
config HID_ACRUX
|
||||||
tristate "ACRUX game controller support"
|
tristate "ACRUX game controller support"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Say Y here if you want to enable support for ACRUX game controllers.
|
Say Y here if you want to enable support for ACRUX game controllers.
|
||||||
|
|
||||||
@ -127,7 +120,6 @@ config HID_ACRUX_FF
|
|||||||
|
|
||||||
config HID_APPLE
|
config HID_APPLE
|
||||||
tristate "Apple {i,Power,Mac}Books"
|
tristate "Apple {i,Power,Mac}Books"
|
||||||
depends on HID
|
|
||||||
depends on LEDS_CLASS
|
depends on LEDS_CLASS
|
||||||
depends on NEW_LEDS
|
depends on NEW_LEDS
|
||||||
default !EXPERT
|
default !EXPERT
|
||||||
@ -167,13 +159,11 @@ config HID_ASUS
|
|||||||
|
|
||||||
config HID_AUREAL
|
config HID_AUREAL
|
||||||
tristate "Aureal"
|
tristate "Aureal"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Aureal Cy se W-01RN Remote Controller and other Aureal derived remotes.
|
Support for Aureal Cy se W-01RN Remote Controller and other Aureal derived remotes.
|
||||||
|
|
||||||
config HID_BELKIN
|
config HID_BELKIN
|
||||||
tristate "Belkin Flip KVM and Wireless keyboard"
|
tristate "Belkin Flip KVM and Wireless keyboard"
|
||||||
depends on HID
|
|
||||||
default !EXPERT
|
default !EXPERT
|
||||||
help
|
help
|
||||||
Support for Belkin Flip KVM and Wireless keyboard.
|
Support for Belkin Flip KVM and Wireless keyboard.
|
||||||
@ -202,7 +192,6 @@ config HID_BIGBEN_FF
|
|||||||
|
|
||||||
config HID_CHERRY
|
config HID_CHERRY
|
||||||
tristate "Cherry Cymotion keyboard"
|
tristate "Cherry Cymotion keyboard"
|
||||||
depends on HID
|
|
||||||
default !EXPERT
|
default !EXPERT
|
||||||
help
|
help
|
||||||
Support for Cherry Cymotion keyboard.
|
Support for Cherry Cymotion keyboard.
|
||||||
@ -227,7 +216,6 @@ config HID_CORSAIR
|
|||||||
|
|
||||||
config HID_COUGAR
|
config HID_COUGAR
|
||||||
tristate "Cougar devices"
|
tristate "Cougar devices"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Cougar devices that are not fully compliant with the
|
Support for Cougar devices that are not fully compliant with the
|
||||||
HID standard.
|
HID standard.
|
||||||
@ -237,7 +225,6 @@ config HID_COUGAR
|
|||||||
|
|
||||||
config HID_MACALLY
|
config HID_MACALLY
|
||||||
tristate "Macally devices"
|
tristate "Macally devices"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Macally devices that are not fully compliant with the
|
Support for Macally devices that are not fully compliant with the
|
||||||
HID standard.
|
HID standard.
|
||||||
@ -262,7 +249,6 @@ config HID_PRODIKEYS
|
|||||||
|
|
||||||
config HID_CMEDIA
|
config HID_CMEDIA
|
||||||
tristate "CMedia audio chips"
|
tristate "CMedia audio chips"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for CMedia CM6533 HID audio jack controls
|
Support for CMedia CM6533 HID audio jack controls
|
||||||
and HS100B mute buttons.
|
and HS100B mute buttons.
|
||||||
@ -288,14 +274,12 @@ config HID_CREATIVE_SB0540
|
|||||||
|
|
||||||
config HID_CYPRESS
|
config HID_CYPRESS
|
||||||
tristate "Cypress mouse and barcode readers"
|
tristate "Cypress mouse and barcode readers"
|
||||||
depends on HID
|
|
||||||
default !EXPERT
|
default !EXPERT
|
||||||
help
|
help
|
||||||
Support for cypress mouse and barcode readers.
|
Support for cypress mouse and barcode readers.
|
||||||
|
|
||||||
config HID_DRAGONRISE
|
config HID_DRAGONRISE
|
||||||
tristate "DragonRise Inc. game controller"
|
tristate "DragonRise Inc. game controller"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Say Y here if you have DragonRise Inc. game controllers.
|
Say Y here if you have DragonRise Inc. game controllers.
|
||||||
These might be branded as:
|
These might be branded as:
|
||||||
@ -314,7 +298,6 @@ config DRAGONRISE_FF
|
|||||||
|
|
||||||
config HID_EMS_FF
|
config HID_EMS_FF
|
||||||
tristate "EMS Production Inc. force feedback support"
|
tristate "EMS Production Inc. force feedback support"
|
||||||
depends on HID
|
|
||||||
select INPUT_FF_MEMLESS
|
select INPUT_FF_MEMLESS
|
||||||
help
|
help
|
||||||
Say Y here if you want to enable force feedback support for devices by
|
Say Y here if you want to enable force feedback support for devices by
|
||||||
@ -332,7 +315,6 @@ config HID_ELAN
|
|||||||
|
|
||||||
config HID_ELECOM
|
config HID_ELECOM
|
||||||
tristate "ELECOM HID devices"
|
tristate "ELECOM HID devices"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for ELECOM devices:
|
Support for ELECOM devices:
|
||||||
- BM084 Bluetooth Mouse
|
- BM084 Bluetooth Mouse
|
||||||
@ -349,7 +331,6 @@ config HID_ELO
|
|||||||
|
|
||||||
config HID_EZKEY
|
config HID_EZKEY
|
||||||
tristate "Ezkey BTC 8193 keyboard"
|
tristate "Ezkey BTC 8193 keyboard"
|
||||||
depends on HID
|
|
||||||
default !EXPERT
|
default !EXPERT
|
||||||
help
|
help
|
||||||
Support for Ezkey BTC 8193 keyboard.
|
Support for Ezkey BTC 8193 keyboard.
|
||||||
@ -367,19 +348,16 @@ config HID_FT260
|
|||||||
|
|
||||||
config HID_GEMBIRD
|
config HID_GEMBIRD
|
||||||
tristate "Gembird Joypad"
|
tristate "Gembird Joypad"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Gembird JPD-DualForce 2.
|
Support for Gembird JPD-DualForce 2.
|
||||||
|
|
||||||
config HID_GFRM
|
config HID_GFRM
|
||||||
tristate "Google Fiber TV Box remote control support"
|
tristate "Google Fiber TV Box remote control support"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Google Fiber TV Box remote controls
|
Support for Google Fiber TV Box remote controls
|
||||||
|
|
||||||
config HID_GLORIOUS
|
config HID_GLORIOUS
|
||||||
tristate "Glorious PC Gaming Race mice"
|
tristate "Glorious PC Gaming Race mice"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Glorious PC Gaming Race mice such as
|
Support for Glorious PC Gaming Race mice such as
|
||||||
the Glorious Model O, O- and D.
|
the Glorious Model O, O- and D.
|
||||||
@ -424,7 +402,6 @@ config HID_VIVALDI
|
|||||||
tristate "Vivaldi Keyboard"
|
tristate "Vivaldi Keyboard"
|
||||||
select HID_VIVALDI_COMMON
|
select HID_VIVALDI_COMMON
|
||||||
select INPUT_VIVALDIFMAP
|
select INPUT_VIVALDIFMAP
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Say Y here if you want to enable support for Vivaldi keyboards.
|
Say Y here if you want to enable support for Vivaldi keyboards.
|
||||||
|
|
||||||
@ -447,7 +424,6 @@ config HID_GT683R
|
|||||||
|
|
||||||
config HID_KEYTOUCH
|
config HID_KEYTOUCH
|
||||||
tristate "Keytouch HID devices"
|
tristate "Keytouch HID devices"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Keytouch HID devices not fully compliant with
|
Support for Keytouch HID devices not fully compliant with
|
||||||
the specification. Currently supported:
|
the specification. Currently supported:
|
||||||
@ -455,7 +431,6 @@ config HID_KEYTOUCH
|
|||||||
|
|
||||||
config HID_KYE
|
config HID_KYE
|
||||||
tristate "KYE/Genius devices"
|
tristate "KYE/Genius devices"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for KYE/Genius devices not fully compliant with HID standard:
|
Support for KYE/Genius devices not fully compliant with HID standard:
|
||||||
- Ergo Mouse
|
- Ergo Mouse
|
||||||
@ -471,32 +446,37 @@ config HID_UCLOGIC
|
|||||||
|
|
||||||
config HID_WALTOP
|
config HID_WALTOP
|
||||||
tristate "Waltop"
|
tristate "Waltop"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Waltop tablets.
|
Support for Waltop tablets.
|
||||||
|
|
||||||
config HID_VIEWSONIC
|
config HID_VIEWSONIC
|
||||||
tristate "ViewSonic/Signotec"
|
tristate "ViewSonic/Signotec"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for ViewSonic/Signotec PD1011 signature pad.
|
Support for ViewSonic/Signotec PD1011 signature pad.
|
||||||
|
|
||||||
|
config HID_VRC2
|
||||||
|
tristate "VRC-2 Car Controller"
|
||||||
|
depends on HID
|
||||||
|
help
|
||||||
|
Support for VRC-2 which is a 2-axis controller often used in
|
||||||
|
car simulators.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called hid-vrc2.
|
||||||
|
|
||||||
config HID_XIAOMI
|
config HID_XIAOMI
|
||||||
tristate "Xiaomi"
|
tristate "Xiaomi"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Adds support for side buttons of Xiaomi Mi Dual Mode Wireless
|
Adds support for side buttons of Xiaomi Mi Dual Mode Wireless
|
||||||
Mouse Silent Edition.
|
Mouse Silent Edition.
|
||||||
|
|
||||||
config HID_GYRATION
|
config HID_GYRATION
|
||||||
tristate "Gyration remote control"
|
tristate "Gyration remote control"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Gyration remote control.
|
Support for Gyration remote control.
|
||||||
|
|
||||||
config HID_ICADE
|
config HID_ICADE
|
||||||
tristate "ION iCade arcade controller"
|
tristate "ION iCade arcade controller"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for the ION iCade arcade controller to work as a joystick.
|
Support for the ION iCade arcade controller to work as a joystick.
|
||||||
|
|
||||||
@ -505,14 +485,12 @@ config HID_ICADE
|
|||||||
|
|
||||||
config HID_ITE
|
config HID_ITE
|
||||||
tristate "ITE devices"
|
tristate "ITE devices"
|
||||||
depends on HID
|
|
||||||
default !EXPERT
|
default !EXPERT
|
||||||
help
|
help
|
||||||
Support for ITE devices not fully compliant with HID standard.
|
Support for ITE devices not fully compliant with HID standard.
|
||||||
|
|
||||||
config HID_JABRA
|
config HID_JABRA
|
||||||
tristate "Jabra USB HID Driver"
|
tristate "Jabra USB HID Driver"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Jabra USB HID devices.
|
Support for Jabra USB HID devices.
|
||||||
|
|
||||||
@ -523,26 +501,22 @@ config HID_JABRA
|
|||||||
|
|
||||||
config HID_TWINHAN
|
config HID_TWINHAN
|
||||||
tristate "Twinhan IR remote control"
|
tristate "Twinhan IR remote control"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Twinhan IR remote control.
|
Support for Twinhan IR remote control.
|
||||||
|
|
||||||
config HID_KENSINGTON
|
config HID_KENSINGTON
|
||||||
tristate "Kensington Slimblade Trackball"
|
tristate "Kensington Slimblade Trackball"
|
||||||
depends on HID
|
|
||||||
default !EXPERT
|
default !EXPERT
|
||||||
help
|
help
|
||||||
Support for Kensington Slimblade Trackball.
|
Support for Kensington Slimblade Trackball.
|
||||||
|
|
||||||
config HID_LCPOWER
|
config HID_LCPOWER
|
||||||
tristate "LC-Power"
|
tristate "LC-Power"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for LC-Power RC1000MCE RF remote control.
|
Support for LC-Power RC1000MCE RF remote control.
|
||||||
|
|
||||||
config HID_LED
|
config HID_LED
|
||||||
tristate "Simple RGB LED support"
|
tristate "Simple RGB LED support"
|
||||||
depends on HID
|
|
||||||
depends on LEDS_CLASS
|
depends on LEDS_CLASS
|
||||||
help
|
help
|
||||||
Support for simple RGB LED devices. Currently supported are:
|
Support for simple RGB LED devices. Currently supported are:
|
||||||
@ -557,7 +531,6 @@ config HID_LED
|
|||||||
|
|
||||||
config HID_LENOVO
|
config HID_LENOVO
|
||||||
tristate "Lenovo / Thinkpad devices"
|
tristate "Lenovo / Thinkpad devices"
|
||||||
depends on HID
|
|
||||||
select NEW_LEDS
|
select NEW_LEDS
|
||||||
select LEDS_CLASS
|
select LEDS_CLASS
|
||||||
help
|
help
|
||||||
@ -675,7 +648,6 @@ config LOGIWHEELS_FF
|
|||||||
|
|
||||||
config HID_MAGICMOUSE
|
config HID_MAGICMOUSE
|
||||||
tristate "Apple Magic Mouse/Trackpad multi-touch support"
|
tristate "Apple Magic Mouse/Trackpad multi-touch support"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for the Apple Magic Mouse/Trackpad multi-touch.
|
Support for the Apple Magic Mouse/Trackpad multi-touch.
|
||||||
|
|
||||||
@ -684,14 +656,12 @@ config HID_MAGICMOUSE
|
|||||||
|
|
||||||
config HID_MALTRON
|
config HID_MALTRON
|
||||||
tristate "Maltron L90 keyboard"
|
tristate "Maltron L90 keyboard"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Adds support for the volume up, volume down, mute, and play/pause buttons
|
Adds support for the volume up, volume down, mute, and play/pause buttons
|
||||||
of the Maltron L90 keyboard.
|
of the Maltron L90 keyboard.
|
||||||
|
|
||||||
config HID_MAYFLASH
|
config HID_MAYFLASH
|
||||||
tristate "Mayflash game controller adapter force feedback"
|
tristate "Mayflash game controller adapter force feedback"
|
||||||
depends on HID
|
|
||||||
select INPUT_FF_MEMLESS
|
select INPUT_FF_MEMLESS
|
||||||
help
|
help
|
||||||
Say Y here if you have HJZ Mayflash PS3 game controller adapters
|
Say Y here if you have HJZ Mayflash PS3 game controller adapters
|
||||||
@ -707,14 +677,12 @@ config HID_MEGAWORLD_FF
|
|||||||
|
|
||||||
config HID_REDRAGON
|
config HID_REDRAGON
|
||||||
tristate "Redragon keyboards"
|
tristate "Redragon keyboards"
|
||||||
depends on HID
|
|
||||||
default !EXPERT
|
default !EXPERT
|
||||||
help
|
help
|
||||||
Support for Redragon keyboards that need fix-ups to work properly.
|
Support for Redragon keyboards that need fix-ups to work properly.
|
||||||
|
|
||||||
config HID_MICROSOFT
|
config HID_MICROSOFT
|
||||||
tristate "Microsoft non-fully HID-compliant devices"
|
tristate "Microsoft non-fully HID-compliant devices"
|
||||||
depends on HID
|
|
||||||
default !EXPERT
|
default !EXPERT
|
||||||
select INPUT_FF_MEMLESS
|
select INPUT_FF_MEMLESS
|
||||||
help
|
help
|
||||||
@ -722,14 +690,12 @@ config HID_MICROSOFT
|
|||||||
|
|
||||||
config HID_MONTEREY
|
config HID_MONTEREY
|
||||||
tristate "Monterey Genius KB29E keyboard"
|
tristate "Monterey Genius KB29E keyboard"
|
||||||
depends on HID
|
|
||||||
default !EXPERT
|
default !EXPERT
|
||||||
help
|
help
|
||||||
Support for Monterey Genius KB29E.
|
Support for Monterey Genius KB29E.
|
||||||
|
|
||||||
config HID_MULTITOUCH
|
config HID_MULTITOUCH
|
||||||
tristate "HID Multitouch panels"
|
tristate "HID Multitouch panels"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Generic support for HID multitouch panels.
|
Generic support for HID multitouch panels.
|
||||||
|
|
||||||
@ -775,7 +741,6 @@ config HID_MULTITOUCH
|
|||||||
|
|
||||||
config HID_NINTENDO
|
config HID_NINTENDO
|
||||||
tristate "Nintendo Joy-Con and Pro Controller support"
|
tristate "Nintendo Joy-Con and Pro Controller support"
|
||||||
depends on HID
|
|
||||||
depends on NEW_LEDS
|
depends on NEW_LEDS
|
||||||
depends on LEDS_CLASS
|
depends on LEDS_CLASS
|
||||||
select POWER_SUPPLY
|
select POWER_SUPPLY
|
||||||
@ -811,7 +776,6 @@ config HID_NTRIG
|
|||||||
|
|
||||||
config HID_ORTEK
|
config HID_ORTEK
|
||||||
tristate "Ortek PKB-1700/WKB-2000/Skycable wireless keyboard and mouse trackpad"
|
tristate "Ortek PKB-1700/WKB-2000/Skycable wireless keyboard and mouse trackpad"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
There are certain devices which have LogicalMaximum wrong in the keyboard
|
There are certain devices which have LogicalMaximum wrong in the keyboard
|
||||||
usage page of their report descriptor. The most prevailing ones so far
|
usage page of their report descriptor. The most prevailing ones so far
|
||||||
@ -824,7 +788,6 @@ config HID_ORTEK
|
|||||||
|
|
||||||
config HID_PANTHERLORD
|
config HID_PANTHERLORD
|
||||||
tristate "Pantherlord/GreenAsia game controller"
|
tristate "Pantherlord/GreenAsia game controller"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Say Y here if you have a PantherLord/GreenAsia based game controller
|
Say Y here if you have a PantherLord/GreenAsia based game controller
|
||||||
or adapter.
|
or adapter.
|
||||||
@ -850,13 +813,11 @@ config HID_PENMOUNT
|
|||||||
|
|
||||||
config HID_PETALYNX
|
config HID_PETALYNX
|
||||||
tristate "Petalynx Maxter remote control"
|
tristate "Petalynx Maxter remote control"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Petalynx Maxter remote control.
|
Support for Petalynx Maxter remote control.
|
||||||
|
|
||||||
config HID_PICOLCD
|
config HID_PICOLCD
|
||||||
tristate "PicoLCD (graphic version)"
|
tristate "PicoLCD (graphic version)"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
This provides support for Minibox PicoLCD devices, currently
|
This provides support for Minibox PicoLCD devices, currently
|
||||||
only the graphical ones are supported.
|
only the graphical ones are supported.
|
||||||
@ -922,7 +883,6 @@ config HID_PICOLCD_CIR
|
|||||||
|
|
||||||
config HID_PLANTRONICS
|
config HID_PLANTRONICS
|
||||||
tristate "Plantronics USB HID Driver"
|
tristate "Plantronics USB HID Driver"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Provides HID support for Plantronics USB audio devices.
|
Provides HID support for Plantronics USB audio devices.
|
||||||
Correctly maps vendor unique volume up/down HID usages to
|
Correctly maps vendor unique volume up/down HID usages to
|
||||||
@ -933,7 +893,6 @@ config HID_PLANTRONICS
|
|||||||
|
|
||||||
config HID_PLAYSTATION
|
config HID_PLAYSTATION
|
||||||
tristate "PlayStation HID Driver"
|
tristate "PlayStation HID Driver"
|
||||||
depends on HID
|
|
||||||
depends on LEDS_CLASS_MULTICOLOR
|
depends on LEDS_CLASS_MULTICOLOR
|
||||||
select CRC32
|
select CRC32
|
||||||
select POWER_SUPPLY
|
select POWER_SUPPLY
|
||||||
@ -950,16 +909,23 @@ config PLAYSTATION_FF
|
|||||||
Say Y here if you would like to enable force feedback support for
|
Say Y here if you would like to enable force feedback support for
|
||||||
PlayStation game controllers.
|
PlayStation game controllers.
|
||||||
|
|
||||||
|
config HID_PXRC
|
||||||
|
tristate "PhoenixRC HID Flight Controller"
|
||||||
|
depends on HID
|
||||||
|
help
|
||||||
|
Support for PhoenixRC HID Flight Controller, a 8-axis flight controller.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called hid-pxrc.
|
||||||
|
|
||||||
config HID_RAZER
|
config HID_RAZER
|
||||||
tristate "Razer non-fully HID-compliant devices"
|
tristate "Razer non-fully HID-compliant devices"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Razer devices that are not fully compliant with the
|
Support for Razer devices that are not fully compliant with the
|
||||||
HID standard.
|
HID standard.
|
||||||
|
|
||||||
config HID_PRIMAX
|
config HID_PRIMAX
|
||||||
tristate "Primax non-fully HID-compliant devices"
|
tristate "Primax non-fully HID-compliant devices"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Primax devices that are not fully compliant with the
|
Support for Primax devices that are not fully compliant with the
|
||||||
HID standard.
|
HID standard.
|
||||||
@ -981,7 +947,6 @@ config HID_ROCCAT
|
|||||||
|
|
||||||
config HID_SAITEK
|
config HID_SAITEK
|
||||||
tristate "Saitek (Mad Catz) non-fully HID-compliant devices"
|
tristate "Saitek (Mad Catz) non-fully HID-compliant devices"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Saitek devices that are not fully compliant with the
|
Support for Saitek devices that are not fully compliant with the
|
||||||
HID standard.
|
HID standard.
|
||||||
@ -999,7 +964,6 @@ config HID_SAMSUNG
|
|||||||
|
|
||||||
config HID_SEMITEK
|
config HID_SEMITEK
|
||||||
tristate "Semitek USB keyboards"
|
tristate "Semitek USB keyboards"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Semitek USB keyboards that are not fully compliant
|
Support for Semitek USB keyboards that are not fully compliant
|
||||||
with the HID standard.
|
with the HID standard.
|
||||||
@ -1050,13 +1014,11 @@ config SONY_FF
|
|||||||
|
|
||||||
config HID_SPEEDLINK
|
config HID_SPEEDLINK
|
||||||
tristate "Speedlink VAD Cezanne mouse support"
|
tristate "Speedlink VAD Cezanne mouse support"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Speedlink Vicious and Divine Cezanne mouse.
|
Support for Speedlink Vicious and Divine Cezanne mouse.
|
||||||
|
|
||||||
config HID_STEAM
|
config HID_STEAM
|
||||||
tristate "Steam Controller support"
|
tristate "Steam Controller support"
|
||||||
depends on HID
|
|
||||||
select POWER_SUPPLY
|
select POWER_SUPPLY
|
||||||
help
|
help
|
||||||
Say Y here if you have a Steam Controller if you want to use it
|
Say Y here if you have a Steam Controller if you want to use it
|
||||||
@ -1065,19 +1027,16 @@ config HID_STEAM
|
|||||||
|
|
||||||
config HID_STEELSERIES
|
config HID_STEELSERIES
|
||||||
tristate "Steelseries SRW-S1 steering wheel support"
|
tristate "Steelseries SRW-S1 steering wheel support"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Steelseries SRW-S1 steering wheel
|
Support for Steelseries SRW-S1 steering wheel
|
||||||
|
|
||||||
config HID_SUNPLUS
|
config HID_SUNPLUS
|
||||||
tristate "Sunplus wireless desktop"
|
tristate "Sunplus wireless desktop"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Sunplus wireless desktop.
|
Support for Sunplus wireless desktop.
|
||||||
|
|
||||||
config HID_RMI
|
config HID_RMI
|
||||||
tristate "Synaptics RMI4 device support"
|
tristate "Synaptics RMI4 device support"
|
||||||
depends on HID
|
|
||||||
select RMI4_CORE
|
select RMI4_CORE
|
||||||
select RMI4_F03
|
select RMI4_F03
|
||||||
select RMI4_F11
|
select RMI4_F11
|
||||||
@ -1090,7 +1049,6 @@ config HID_RMI
|
|||||||
|
|
||||||
config HID_GREENASIA
|
config HID_GREENASIA
|
||||||
tristate "GreenAsia (Product ID 0x12) game controller support"
|
tristate "GreenAsia (Product ID 0x12) game controller support"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Say Y here if you have a GreenAsia (Product ID 0x12) based game
|
Say Y here if you have a GreenAsia (Product ID 0x12) based game
|
||||||
controller or adapter.
|
controller or adapter.
|
||||||
@ -1112,7 +1070,6 @@ config HID_HYPERV_MOUSE
|
|||||||
|
|
||||||
config HID_SMARTJOYPLUS
|
config HID_SMARTJOYPLUS
|
||||||
tristate "SmartJoy PLUS PS2/USB adapter support"
|
tristate "SmartJoy PLUS PS2/USB adapter support"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for SmartJoy PLUS PS2/USB adapter, Super Dual Box,
|
Support for SmartJoy PLUS PS2/USB adapter, Super Dual Box,
|
||||||
Super Joy Box 3 Pro, Super Dual Box Pro, and Super Joy Box 5 Pro.
|
Super Joy Box 3 Pro, Super Dual Box Pro, and Super Joy Box 5 Pro.
|
||||||
@ -1130,20 +1087,23 @@ config SMARTJOYPLUS_FF
|
|||||||
|
|
||||||
config HID_TIVO
|
config HID_TIVO
|
||||||
tristate "TiVo Slide Bluetooth remote control support"
|
tristate "TiVo Slide Bluetooth remote control support"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Say Y if you have a TiVo Slide Bluetooth remote control.
|
Say Y if you have a TiVo Slide Bluetooth remote control.
|
||||||
|
|
||||||
config HID_TOPSEED
|
config HID_TOPSEED
|
||||||
tristate "TopSeed Cyberlink, BTC Emprex, Conceptronic remote control support"
|
tristate "TopSeed Cyberlink, BTC Emprex, Conceptronic remote control support"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic
|
Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic
|
||||||
CLLRCMCE remote control.
|
CLLRCMCE remote control.
|
||||||
|
|
||||||
|
config HID_TOPRE
|
||||||
|
tristate "Topre REALFORCE keyboards"
|
||||||
|
depends on HID
|
||||||
|
help
|
||||||
|
Say Y for N-key rollover support on Topre REALFORCE R2 108 key keyboards.
|
||||||
|
|
||||||
config HID_THINGM
|
config HID_THINGM
|
||||||
tristate "ThingM blink(1) USB RGB LED"
|
tristate "ThingM blink(1) USB RGB LED"
|
||||||
depends on HID
|
|
||||||
depends on LEDS_CLASS
|
depends on LEDS_CLASS
|
||||||
select HID_LED
|
select HID_LED
|
||||||
help
|
help
|
||||||
@ -1170,7 +1130,6 @@ config THRUSTMASTER_FF
|
|||||||
|
|
||||||
config HID_UDRAW_PS3
|
config HID_UDRAW_PS3
|
||||||
tristate "THQ PS3 uDraw tablet"
|
tristate "THQ PS3 uDraw tablet"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Say Y here if you want to use the THQ uDraw gaming tablet for
|
Say Y here if you want to use the THQ uDraw gaming tablet for
|
||||||
the PS3.
|
the PS3.
|
||||||
@ -1207,7 +1166,6 @@ config HID_WACOM
|
|||||||
|
|
||||||
config HID_WIIMOTE
|
config HID_WIIMOTE
|
||||||
tristate "Nintendo Wii / Wii U peripherals"
|
tristate "Nintendo Wii / Wii U peripherals"
|
||||||
depends on HID
|
|
||||||
depends on LEDS_CLASS
|
depends on LEDS_CLASS
|
||||||
select POWER_SUPPLY
|
select POWER_SUPPLY
|
||||||
select INPUT_FF_MEMLESS
|
select INPUT_FF_MEMLESS
|
||||||
@ -1232,7 +1190,6 @@ config HID_WIIMOTE
|
|||||||
|
|
||||||
config HID_XINMO
|
config HID_XINMO
|
||||||
tristate "Xin-Mo non-fully compliant devices"
|
tristate "Xin-Mo non-fully compliant devices"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Xin-Mo devices that are not fully compliant with the HID
|
Support for Xin-Mo devices that are not fully compliant with the HID
|
||||||
standard. Currently only supports the Xin-Mo Dual Arcade. Say Y here
|
standard. Currently only supports the Xin-Mo Dual Arcade. Say Y here
|
||||||
@ -1240,7 +1197,6 @@ config HID_XINMO
|
|||||||
|
|
||||||
config HID_ZEROPLUS
|
config HID_ZEROPLUS
|
||||||
tristate "Zeroplus based game controller support"
|
tristate "Zeroplus based game controller support"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Say Y here if you have a Zeroplus based game controller.
|
Say Y here if you have a Zeroplus based game controller.
|
||||||
|
|
||||||
@ -1254,13 +1210,12 @@ config ZEROPLUS_FF
|
|||||||
|
|
||||||
config HID_ZYDACRON
|
config HID_ZYDACRON
|
||||||
tristate "Zydacron remote control support"
|
tristate "Zydacron remote control support"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Zydacron remote control.
|
Support for Zydacron remote control.
|
||||||
|
|
||||||
config HID_SENSOR_HUB
|
config HID_SENSOR_HUB
|
||||||
tristate "HID Sensors framework support"
|
tristate "HID Sensors framework support"
|
||||||
depends on HID && HAS_IOMEM
|
depends on HAS_IOMEM
|
||||||
select MFD_CORE
|
select MFD_CORE
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
@ -1289,7 +1244,6 @@ config HID_SENSOR_CUSTOM_SENSOR
|
|||||||
|
|
||||||
config HID_ALPS
|
config HID_ALPS
|
||||||
tristate "Alps HID device support"
|
tristate "Alps HID device support"
|
||||||
depends on HID
|
|
||||||
help
|
help
|
||||||
Support for Alps I2C HID touchpads and StickPointer.
|
Support for Alps I2C HID touchpads and StickPointer.
|
||||||
Say Y here if you have a Alps touchpads over i2c-hid or usbhid
|
Say Y here if you have a Alps touchpads over i2c-hid or usbhid
|
||||||
@ -1307,7 +1261,7 @@ config HID_MCP2221
|
|||||||
will be called hid-mcp2221.ko.
|
will be called hid-mcp2221.ko.
|
||||||
|
|
||||||
config HID_KUNIT_TEST
|
config HID_KUNIT_TEST
|
||||||
bool "KUnit tests for HID" if !KUNIT_ALL_TESTS
|
tristate "KUnit tests for HID" if !KUNIT_ALL_TESTS
|
||||||
depends on KUNIT=y
|
depends on KUNIT=y
|
||||||
depends on HID_UCLOGIC
|
depends on HID_UCLOGIC
|
||||||
default KUNIT_ALL_TESTS
|
default KUNIT_ALL_TESTS
|
||||||
|
@ -101,6 +101,7 @@ hid-picolcd-$(CONFIG_DEBUG_FS) += hid-picolcd_debugfs.o
|
|||||||
obj-$(CONFIG_HID_PLANTRONICS) += hid-plantronics.o
|
obj-$(CONFIG_HID_PLANTRONICS) += hid-plantronics.o
|
||||||
obj-$(CONFIG_HID_PLAYSTATION) += hid-playstation.o
|
obj-$(CONFIG_HID_PLAYSTATION) += hid-playstation.o
|
||||||
obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
|
obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
|
||||||
|
obj-$(CONFIG_HID_PXRC) += hid-pxrc.o
|
||||||
obj-$(CONFIG_HID_RAZER) += hid-razer.o
|
obj-$(CONFIG_HID_RAZER) += hid-razer.o
|
||||||
obj-$(CONFIG_HID_REDRAGON) += hid-redragon.o
|
obj-$(CONFIG_HID_REDRAGON) += hid-redragon.o
|
||||||
obj-$(CONFIG_HID_RETRODE) += hid-retrode.o
|
obj-$(CONFIG_HID_RETRODE) += hid-retrode.o
|
||||||
@ -123,6 +124,7 @@ obj-$(CONFIG_HID_GREENASIA) += hid-gaff.o
|
|||||||
obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o hid-thrustmaster.o
|
obj-$(CONFIG_HID_THRUSTMASTER) += hid-tmff.o hid-thrustmaster.o
|
||||||
obj-$(CONFIG_HID_TIVO) += hid-tivo.o
|
obj-$(CONFIG_HID_TIVO) += hid-tivo.o
|
||||||
obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o
|
obj-$(CONFIG_HID_TOPSEED) += hid-topseed.o
|
||||||
|
obj-$(CONFIG_HID_TOPRE) += hid-topre.o
|
||||||
obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o
|
obj-$(CONFIG_HID_TWINHAN) += hid-twinhan.o
|
||||||
obj-$(CONFIG_HID_U2FZERO) += hid-u2fzero.o
|
obj-$(CONFIG_HID_U2FZERO) += hid-u2fzero.o
|
||||||
hid-uclogic-objs := hid-uclogic-core.o \
|
hid-uclogic-objs := hid-uclogic-core.o \
|
||||||
@ -136,6 +138,7 @@ obj-$(CONFIG_HID_XINMO) += hid-xinmo.o
|
|||||||
obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o
|
obj-$(CONFIG_HID_ZEROPLUS) += hid-zpff.o
|
||||||
obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o
|
obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o
|
||||||
obj-$(CONFIG_HID_VIEWSONIC) += hid-viewsonic.o
|
obj-$(CONFIG_HID_VIEWSONIC) += hid-viewsonic.o
|
||||||
|
obj-$(CONFIG_HID_VRC2) += hid-vrc2.o
|
||||||
|
|
||||||
wacom-objs := wacom_wac.o wacom_sys.o
|
wacom-objs := wacom_wac.o wacom_sys.o
|
||||||
obj-$(CONFIG_HID_WACOM) += wacom.o
|
obj-$(CONFIG_HID_WACOM) += wacom.o
|
||||||
@ -144,8 +147,10 @@ obj-$(CONFIG_HID_WIIMOTE) += hid-wiimote.o
|
|||||||
obj-$(CONFIG_HID_SENSOR_HUB) += hid-sensor-hub.o
|
obj-$(CONFIG_HID_SENSOR_HUB) += hid-sensor-hub.o
|
||||||
obj-$(CONFIG_HID_SENSOR_CUSTOM_SENSOR) += hid-sensor-custom.o
|
obj-$(CONFIG_HID_SENSOR_CUSTOM_SENSOR) += hid-sensor-custom.o
|
||||||
|
|
||||||
obj-$(CONFIG_HID_KUNIT_TEST) += hid-uclogic-rdesc.o \
|
hid-uclogic-test-objs := hid-uclogic-rdesc.o \
|
||||||
|
hid-uclogic-params.o \
|
||||||
hid-uclogic-rdesc-test.o
|
hid-uclogic-rdesc-test.o
|
||||||
|
obj-$(CONFIG_HID_KUNIT_TEST) += hid-uclogic-test.o
|
||||||
|
|
||||||
obj-$(CONFIG_USB_HID) += usbhid/
|
obj-$(CONFIG_USB_HID) += usbhid/
|
||||||
obj-$(CONFIG_USB_MOUSE) += usbhid/
|
obj-$(CONFIG_USB_MOUSE) += usbhid/
|
||||||
|
@ -110,6 +110,8 @@ static int amd_sfh1_1_hid_client_init(struct amd_mp2_dev *privdata)
|
|||||||
amd_sfh1_1_set_desc_ops(mp2_ops);
|
amd_sfh1_1_set_desc_ops(mp2_ops);
|
||||||
|
|
||||||
cl_data->num_hid_devices = amd_sfh_get_sensor_num(privdata, &cl_data->sensor_idx[0]);
|
cl_data->num_hid_devices = amd_sfh_get_sensor_num(privdata, &cl_data->sensor_idx[0]);
|
||||||
|
if (cl_data->num_hid_devices == 0)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
INIT_DELAYED_WORK(&cl_data->work, amd_sfh_work);
|
INIT_DELAYED_WORK(&cl_data->work, amd_sfh_work);
|
||||||
INIT_DELAYED_WORK(&cl_data->work_buffer, amd_sfh_work_buffer);
|
INIT_DELAYED_WORK(&cl_data->work_buffer, amd_sfh_work_buffer);
|
||||||
@ -286,13 +288,13 @@ int amd_sfh1_1_init(struct amd_mp2_dev *mp2)
|
|||||||
|
|
||||||
phy_base <<= 21;
|
phy_base <<= 21;
|
||||||
if (!devm_request_mem_region(dev, phy_base, 128 * 1024, "amd_sfh")) {
|
if (!devm_request_mem_region(dev, phy_base, 128 * 1024, "amd_sfh")) {
|
||||||
dev_err(dev, "can't reserve mmio registers\n");
|
dev_dbg(dev, "can't reserve mmio registers\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp2->vsbase = devm_ioremap(dev, phy_base, 128 * 1024);
|
mp2->vsbase = devm_ioremap(dev, phy_base, 128 * 1024);
|
||||||
if (!mp2->vsbase) {
|
if (!mp2->vsbase) {
|
||||||
dev_err(dev, "failed to remap vsbase\n");
|
dev_dbg(dev, "failed to remap vsbase\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,7 +303,7 @@ int amd_sfh1_1_init(struct amd_mp2_dev *mp2)
|
|||||||
|
|
||||||
memcpy_fromio(&binfo, mp2->vsbase, sizeof(struct sfh_base_info));
|
memcpy_fromio(&binfo, mp2->vsbase, sizeof(struct sfh_base_info));
|
||||||
if (binfo.sbase.fw_info.fw_ver == 0 || binfo.sbase.s_list.sl.sensors == 0) {
|
if (binfo.sbase.fw_info.fw_ver == 0 || binfo.sbase.s_list.sl.sensors == 0) {
|
||||||
dev_err(dev, "failed to get sensors\n");
|
dev_dbg(dev, "failed to get sensors\n");
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
dev_dbg(dev, "firmware version 0x%x\n", binfo.sbase.fw_info.fw_ver);
|
dev_dbg(dev, "firmware version 0x%x\n", binfo.sbase.fw_info.fw_ver);
|
||||||
|
@ -55,7 +55,7 @@ MODULE_PARM_DESC(ignore_special_drivers, "Ignore any special drivers and handle
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct hid_report *hid_register_report(struct hid_device *device,
|
struct hid_report *hid_register_report(struct hid_device *device,
|
||||||
unsigned int type, unsigned int id,
|
enum hid_report_type type, unsigned int id,
|
||||||
unsigned int application)
|
unsigned int application)
|
||||||
{
|
{
|
||||||
struct hid_report_enum *report_enum = device->report_enum + type;
|
struct hid_report_enum *report_enum = device->report_enum + type;
|
||||||
@ -967,7 +967,7 @@ static const char * const hid_report_names[] = {
|
|||||||
* parsing.
|
* parsing.
|
||||||
*/
|
*/
|
||||||
struct hid_report *hid_validate_values(struct hid_device *hid,
|
struct hid_report *hid_validate_values(struct hid_device *hid,
|
||||||
unsigned int type, unsigned int id,
|
enum hid_report_type type, unsigned int id,
|
||||||
unsigned int field_index,
|
unsigned int field_index,
|
||||||
unsigned int report_counts)
|
unsigned int report_counts)
|
||||||
{
|
{
|
||||||
@ -1921,7 +1921,7 @@ static struct hid_report *hid_get_report(struct hid_report_enum *report_enum,
|
|||||||
* DO NOT USE in hid drivers directly, but through hid_hw_request instead.
|
* DO NOT USE in hid drivers directly, but through hid_hw_request instead.
|
||||||
*/
|
*/
|
||||||
int __hid_request(struct hid_device *hid, struct hid_report *report,
|
int __hid_request(struct hid_device *hid, struct hid_report *report,
|
||||||
int reqtype)
|
enum hid_class_request reqtype)
|
||||||
{
|
{
|
||||||
char *buf;
|
char *buf;
|
||||||
int ret;
|
int ret;
|
||||||
@ -1954,8 +1954,8 @@ out:
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(__hid_request);
|
EXPORT_SYMBOL_GPL(__hid_request);
|
||||||
|
|
||||||
int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
|
int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *data, u32 size,
|
||||||
int interrupt)
|
int interrupt)
|
||||||
{
|
{
|
||||||
struct hid_report_enum *report_enum = hid->report_enum + type;
|
struct hid_report_enum *report_enum = hid->report_enum + type;
|
||||||
struct hid_report *report;
|
struct hid_report *report;
|
||||||
@ -2019,7 +2019,8 @@ EXPORT_SYMBOL_GPL(hid_report_raw_event);
|
|||||||
*
|
*
|
||||||
* This is data entry for lower layers.
|
* This is data entry for lower layers.
|
||||||
*/
|
*/
|
||||||
int hid_input_report(struct hid_device *hid, int type, u8 *data, u32 size, int interrupt)
|
int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8 *data, u32 size,
|
||||||
|
int interrupt)
|
||||||
{
|
{
|
||||||
struct hid_report_enum *report_enum;
|
struct hid_report_enum *report_enum;
|
||||||
struct hid_driver *hdrv;
|
struct hid_driver *hdrv;
|
||||||
@ -2088,6 +2089,7 @@ const struct hid_device_id *hid_match_id(const struct hid_device *hdev,
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(hid_match_id);
|
||||||
|
|
||||||
static const struct hid_device_id hid_hiddev_list[] = {
|
static const struct hid_device_id hid_hiddev_list[] = {
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS) },
|
||||||
@ -2352,7 +2354,7 @@ EXPORT_SYMBOL_GPL(hid_hw_close);
|
|||||||
* @reqtype: hid request type
|
* @reqtype: hid request type
|
||||||
*/
|
*/
|
||||||
void hid_hw_request(struct hid_device *hdev,
|
void hid_hw_request(struct hid_device *hdev,
|
||||||
struct hid_report *report, int reqtype)
|
struct hid_report *report, enum hid_class_request reqtype)
|
||||||
{
|
{
|
||||||
if (hdev->ll_driver->request)
|
if (hdev->ll_driver->request)
|
||||||
return hdev->ll_driver->request(hdev, report, reqtype);
|
return hdev->ll_driver->request(hdev, report, reqtype);
|
||||||
@ -2377,7 +2379,7 @@ EXPORT_SYMBOL_GPL(hid_hw_request);
|
|||||||
*/
|
*/
|
||||||
int hid_hw_raw_request(struct hid_device *hdev,
|
int hid_hw_raw_request(struct hid_device *hdev,
|
||||||
unsigned char reportnum, __u8 *buf,
|
unsigned char reportnum, __u8 *buf,
|
||||||
size_t len, unsigned char rtype, int reqtype)
|
size_t len, enum hid_report_type rtype, enum hid_class_request reqtype)
|
||||||
{
|
{
|
||||||
if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf)
|
if (len < 1 || len > HID_MAX_BUFFER_SIZE || !buf)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -2739,10 +2741,12 @@ int hid_add_device(struct hid_device *hdev)
|
|||||||
hid_warn(hdev, "bad device descriptor (%d)\n", ret);
|
hid_warn(hdev, "bad device descriptor (%d)\n", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hdev->id = atomic_inc_return(&id);
|
||||||
|
|
||||||
/* XXX hack, any other cleaner solution after the driver core
|
/* XXX hack, any other cleaner solution after the driver core
|
||||||
* is converted to allow more than 20 bytes as the device name? */
|
* is converted to allow more than 20 bytes as the device name? */
|
||||||
dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
|
dev_set_name(&hdev->dev, "%04X:%04X:%04X.%04X", hdev->bus,
|
||||||
hdev->vendor, hdev->product, atomic_inc_return(&id));
|
hdev->vendor, hdev->product, hdev->id);
|
||||||
|
|
||||||
hid_debug_register(hdev, dev_name(&hdev->dev));
|
hid_debug_register(hdev, dev_name(&hdev->dev));
|
||||||
ret = device_add(&hdev->dev);
|
ret = device_add(&hdev->dev);
|
||||||
|
@ -608,9 +608,11 @@ static struct hid_driver hammer_driver = {
|
|||||||
.probe = hammer_probe,
|
.probe = hammer_probe,
|
||||||
.remove = hammer_remove,
|
.remove = hammer_remove,
|
||||||
.feature_mapping = vivaldi_feature_mapping,
|
.feature_mapping = vivaldi_feature_mapping,
|
||||||
.input_configured = vivaldi_input_configured,
|
|
||||||
.input_mapping = hammer_input_mapping,
|
.input_mapping = hammer_input_mapping,
|
||||||
.event = hammer_event,
|
.event = hammer_event,
|
||||||
|
.driver = {
|
||||||
|
.dev_groups = vivaldi_attribute_groups,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init hammer_init(void)
|
static int __init hammer_init(void)
|
||||||
|
@ -1231,6 +1231,9 @@
|
|||||||
#define USB_DEVICE_ID_TIVO_SLIDE 0x1201
|
#define USB_DEVICE_ID_TIVO_SLIDE 0x1201
|
||||||
#define USB_DEVICE_ID_TIVO_SLIDE_PRO 0x1203
|
#define USB_DEVICE_ID_TIVO_SLIDE_PRO 0x1203
|
||||||
|
|
||||||
|
#define USB_VENDOR_ID_TOPRE 0x0853
|
||||||
|
#define USB_DEVICE_ID_TOPRE_REALFORCE_R2_108 0x0148
|
||||||
|
|
||||||
#define USB_VENDOR_ID_TOPSEED 0x0766
|
#define USB_VENDOR_ID_TOPSEED 0x0766
|
||||||
#define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204
|
#define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204
|
||||||
|
|
||||||
@ -1279,10 +1282,12 @@
|
|||||||
#define USB_DEVICE_ID_YIYNOVA_TABLET 0x004d
|
#define USB_DEVICE_ID_YIYNOVA_TABLET 0x004d
|
||||||
|
|
||||||
#define USB_VENDOR_ID_UGEE 0x28bd
|
#define USB_VENDOR_ID_UGEE 0x28bd
|
||||||
|
#define USB_DEVICE_ID_UGEE_PARBLO_A610_PRO 0x1903
|
||||||
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540 0x0075
|
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_G540 0x0075
|
||||||
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_G640 0x0094
|
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_G640 0x0094
|
||||||
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01 0x0042
|
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01 0x0042
|
||||||
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L 0x0935
|
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L 0x0935
|
||||||
|
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_S 0x0909
|
||||||
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06 0x0078
|
#define USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06 0x0078
|
||||||
#define USB_DEVICE_ID_UGEE_TABLET_G5 0x0074
|
#define USB_DEVICE_ID_UGEE_TABLET_G5 0x0074
|
||||||
#define USB_DEVICE_ID_UGEE_TABLET_EX07S 0x0071
|
#define USB_DEVICE_ID_UGEE_TABLET_EX07S 0x0071
|
||||||
@ -1386,6 +1391,7 @@
|
|||||||
|
|
||||||
#define USB_VENDOR_ID_MULTIPLE_1781 0x1781
|
#define USB_VENDOR_ID_MULTIPLE_1781 0x1781
|
||||||
#define USB_DEVICE_ID_RAPHNET_4NES4SNES_OLD 0x0a9d
|
#define USB_DEVICE_ID_RAPHNET_4NES4SNES_OLD 0x0a9d
|
||||||
|
#define USB_DEVICE_ID_PHOENIXRC 0x0898
|
||||||
|
|
||||||
#define USB_VENDOR_ID_DRACAL_RAPHNET 0x289b
|
#define USB_VENDOR_ID_DRACAL_RAPHNET 0x289b
|
||||||
#define USB_DEVICE_ID_RAPHNET_2NES2SNES 0x0002
|
#define USB_DEVICE_ID_RAPHNET_2NES2SNES 0x0002
|
||||||
|
@ -41,6 +41,9 @@ module_param(disable_tap_to_click, bool, 0644);
|
|||||||
MODULE_PARM_DESC(disable_tap_to_click,
|
MODULE_PARM_DESC(disable_tap_to_click,
|
||||||
"Disable Tap-To-Click mode reporting for touchpads (only on the K400 currently).");
|
"Disable Tap-To-Click mode reporting for touchpads (only on the K400 currently).");
|
||||||
|
|
||||||
|
/* Define a non-zero software ID to identify our own requests */
|
||||||
|
#define LINUX_KERNEL_SW_ID 0x01
|
||||||
|
|
||||||
#define REPORT_ID_HIDPP_SHORT 0x10
|
#define REPORT_ID_HIDPP_SHORT 0x10
|
||||||
#define REPORT_ID_HIDPP_LONG 0x11
|
#define REPORT_ID_HIDPP_LONG 0x11
|
||||||
#define REPORT_ID_HIDPP_VERY_LONG 0x12
|
#define REPORT_ID_HIDPP_VERY_LONG 0x12
|
||||||
@ -71,21 +74,18 @@ MODULE_PARM_DESC(disable_tap_to_click,
|
|||||||
#define HIDPP_QUIRK_NO_HIDINPUT BIT(23)
|
#define HIDPP_QUIRK_NO_HIDINPUT BIT(23)
|
||||||
#define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24)
|
#define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24)
|
||||||
#define HIDPP_QUIRK_UNIFYING BIT(25)
|
#define HIDPP_QUIRK_UNIFYING BIT(25)
|
||||||
#define HIDPP_QUIRK_HI_RES_SCROLL_1P0 BIT(26)
|
#define HIDPP_QUIRK_HIDPP_WHEELS BIT(26)
|
||||||
#define HIDPP_QUIRK_HI_RES_SCROLL_X2120 BIT(27)
|
#define HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS BIT(27)
|
||||||
#define HIDPP_QUIRK_HI_RES_SCROLL_X2121 BIT(28)
|
#define HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS BIT(28)
|
||||||
#define HIDPP_QUIRK_HIDPP_WHEELS BIT(29)
|
|
||||||
#define HIDPP_QUIRK_HIDPP_EXTRA_MOUSE_BTNS BIT(30)
|
|
||||||
#define HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS BIT(31)
|
|
||||||
|
|
||||||
/* These are just aliases for now */
|
/* These are just aliases for now */
|
||||||
#define HIDPP_QUIRK_KBD_SCROLL_WHEEL HIDPP_QUIRK_HIDPP_WHEELS
|
#define HIDPP_QUIRK_KBD_SCROLL_WHEEL HIDPP_QUIRK_HIDPP_WHEELS
|
||||||
#define HIDPP_QUIRK_KBD_ZOOM_WHEEL HIDPP_QUIRK_HIDPP_WHEELS
|
#define HIDPP_QUIRK_KBD_ZOOM_WHEEL HIDPP_QUIRK_HIDPP_WHEELS
|
||||||
|
|
||||||
/* Convenience constant to check for any high-res support. */
|
/* Convenience constant to check for any high-res support. */
|
||||||
#define HIDPP_QUIRK_HI_RES_SCROLL (HIDPP_QUIRK_HI_RES_SCROLL_1P0 | \
|
#define HIDPP_CAPABILITY_HI_RES_SCROLL (HIDPP_CAPABILITY_HIDPP10_FAST_SCROLL | \
|
||||||
HIDPP_QUIRK_HI_RES_SCROLL_X2120 | \
|
HIDPP_CAPABILITY_HIDPP20_HI_RES_SCROLL | \
|
||||||
HIDPP_QUIRK_HI_RES_SCROLL_X2121)
|
HIDPP_CAPABILITY_HIDPP20_HI_RES_WHEEL)
|
||||||
|
|
||||||
#define HIDPP_QUIRK_DELAYED_INIT HIDPP_QUIRK_NO_HIDINPUT
|
#define HIDPP_QUIRK_DELAYED_INIT HIDPP_QUIRK_NO_HIDINPUT
|
||||||
|
|
||||||
@ -96,6 +96,9 @@ MODULE_PARM_DESC(disable_tap_to_click,
|
|||||||
#define HIDPP_CAPABILITY_BATTERY_VOLTAGE BIT(4)
|
#define HIDPP_CAPABILITY_BATTERY_VOLTAGE BIT(4)
|
||||||
#define HIDPP_CAPABILITY_BATTERY_PERCENTAGE BIT(5)
|
#define HIDPP_CAPABILITY_BATTERY_PERCENTAGE BIT(5)
|
||||||
#define HIDPP_CAPABILITY_UNIFIED_BATTERY BIT(6)
|
#define HIDPP_CAPABILITY_UNIFIED_BATTERY BIT(6)
|
||||||
|
#define HIDPP_CAPABILITY_HIDPP20_HI_RES_WHEEL BIT(7)
|
||||||
|
#define HIDPP_CAPABILITY_HIDPP20_HI_RES_SCROLL BIT(8)
|
||||||
|
#define HIDPP_CAPABILITY_HIDPP10_FAST_SCROLL BIT(9)
|
||||||
|
|
||||||
#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
|
#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
|
||||||
|
|
||||||
@ -343,7 +346,7 @@ static int hidpp_send_fap_command_sync(struct hidpp_device *hidpp,
|
|||||||
else
|
else
|
||||||
message->report_id = REPORT_ID_HIDPP_LONG;
|
message->report_id = REPORT_ID_HIDPP_LONG;
|
||||||
message->fap.feature_index = feat_index;
|
message->fap.feature_index = feat_index;
|
||||||
message->fap.funcindex_clientid = funcindex_clientid;
|
message->fap.funcindex_clientid = funcindex_clientid | LINUX_KERNEL_SW_ID;
|
||||||
memcpy(&message->fap.params, params, param_count);
|
memcpy(&message->fap.params, params, param_count);
|
||||||
|
|
||||||
ret = hidpp_send_message_sync(hidpp, message, response);
|
ret = hidpp_send_message_sync(hidpp, message, response);
|
||||||
@ -856,8 +859,8 @@ static int hidpp_unifying_init(struct hidpp_device *hidpp)
|
|||||||
#define HIDPP_PAGE_ROOT 0x0000
|
#define HIDPP_PAGE_ROOT 0x0000
|
||||||
#define HIDPP_PAGE_ROOT_IDX 0x00
|
#define HIDPP_PAGE_ROOT_IDX 0x00
|
||||||
|
|
||||||
#define CMD_ROOT_GET_FEATURE 0x01
|
#define CMD_ROOT_GET_FEATURE 0x00
|
||||||
#define CMD_ROOT_GET_PROTOCOL_VERSION 0x11
|
#define CMD_ROOT_GET_PROTOCOL_VERSION 0x10
|
||||||
|
|
||||||
static int hidpp_root_get_feature(struct hidpp_device *hidpp, u16 feature,
|
static int hidpp_root_get_feature(struct hidpp_device *hidpp, u16 feature,
|
||||||
u8 *feature_index, u8 *feature_type)
|
u8 *feature_index, u8 *feature_type)
|
||||||
@ -934,9 +937,9 @@ print_version:
|
|||||||
|
|
||||||
#define HIDPP_PAGE_GET_DEVICE_NAME_TYPE 0x0005
|
#define HIDPP_PAGE_GET_DEVICE_NAME_TYPE 0x0005
|
||||||
|
|
||||||
#define CMD_GET_DEVICE_NAME_TYPE_GET_COUNT 0x01
|
#define CMD_GET_DEVICE_NAME_TYPE_GET_COUNT 0x00
|
||||||
#define CMD_GET_DEVICE_NAME_TYPE_GET_DEVICE_NAME 0x11
|
#define CMD_GET_DEVICE_NAME_TYPE_GET_DEVICE_NAME 0x10
|
||||||
#define CMD_GET_DEVICE_NAME_TYPE_GET_TYPE 0x21
|
#define CMD_GET_DEVICE_NAME_TYPE_GET_TYPE 0x20
|
||||||
|
|
||||||
static int hidpp_devicenametype_get_count(struct hidpp_device *hidpp,
|
static int hidpp_devicenametype_get_count(struct hidpp_device *hidpp,
|
||||||
u8 feature_index, u8 *nameLength)
|
u8 feature_index, u8 *nameLength)
|
||||||
@ -1966,8 +1969,8 @@ static int hidpp_touchpad_fw_items_set(struct hidpp_device *hidpp,
|
|||||||
|
|
||||||
#define HIDPP_PAGE_TOUCHPAD_RAW_XY 0x6100
|
#define HIDPP_PAGE_TOUCHPAD_RAW_XY 0x6100
|
||||||
|
|
||||||
#define CMD_TOUCHPAD_GET_RAW_INFO 0x01
|
#define CMD_TOUCHPAD_GET_RAW_INFO 0x00
|
||||||
#define CMD_TOUCHPAD_SET_RAW_REPORT_STATE 0x21
|
#define CMD_TOUCHPAD_SET_RAW_REPORT_STATE 0x20
|
||||||
|
|
||||||
#define EVENT_TOUCHPAD_RAW_XY 0x00
|
#define EVENT_TOUCHPAD_RAW_XY 0x00
|
||||||
|
|
||||||
@ -3415,14 +3418,14 @@ static int hi_res_scroll_enable(struct hidpp_device *hidpp)
|
|||||||
int ret;
|
int ret;
|
||||||
u8 multiplier = 1;
|
u8 multiplier = 1;
|
||||||
|
|
||||||
if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2121) {
|
if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_HI_RES_WHEEL) {
|
||||||
ret = hidpp_hrw_set_wheel_mode(hidpp, false, true, false);
|
ret = hidpp_hrw_set_wheel_mode(hidpp, false, true, false);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = hidpp_hrw_get_wheel_capability(hidpp, &multiplier);
|
ret = hidpp_hrw_get_wheel_capability(hidpp, &multiplier);
|
||||||
} else if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_X2120) {
|
} else if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_HI_RES_SCROLL) {
|
||||||
ret = hidpp_hrs_set_highres_scrolling_mode(hidpp, true,
|
ret = hidpp_hrs_set_highres_scrolling_mode(hidpp, true,
|
||||||
&multiplier);
|
&multiplier);
|
||||||
} else /* if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL_1P0) */ {
|
} else /* if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP10_FAST_SCROLL) */ {
|
||||||
ret = hidpp10_enable_scrolling_acceleration(hidpp);
|
ret = hidpp10_enable_scrolling_acceleration(hidpp);
|
||||||
multiplier = 8;
|
multiplier = 8;
|
||||||
}
|
}
|
||||||
@ -3437,6 +3440,49 @@ static int hi_res_scroll_enable(struct hidpp_device *hidpp)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hidpp_initialize_hires_scroll(struct hidpp_device *hidpp)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
unsigned long capabilities;
|
||||||
|
|
||||||
|
capabilities = hidpp->capabilities;
|
||||||
|
|
||||||
|
if (hidpp->protocol_major >= 2) {
|
||||||
|
u8 feature_index;
|
||||||
|
u8 feature_type;
|
||||||
|
|
||||||
|
ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HIRES_WHEEL,
|
||||||
|
&feature_index, &feature_type);
|
||||||
|
if (!ret) {
|
||||||
|
hidpp->capabilities |= HIDPP_CAPABILITY_HIDPP20_HI_RES_WHEEL;
|
||||||
|
hid_dbg(hidpp->hid_dev, "Detected HID++ 2.0 hi-res scroll wheel\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_HI_RESOLUTION_SCROLLING,
|
||||||
|
&feature_index, &feature_type);
|
||||||
|
if (!ret) {
|
||||||
|
hidpp->capabilities |= HIDPP_CAPABILITY_HIDPP20_HI_RES_SCROLL;
|
||||||
|
hid_dbg(hidpp->hid_dev, "Detected HID++ 2.0 hi-res scrolling\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
struct hidpp_report response;
|
||||||
|
|
||||||
|
ret = hidpp_send_rap_command_sync(hidpp,
|
||||||
|
REPORT_ID_HIDPP_SHORT,
|
||||||
|
HIDPP_GET_REGISTER,
|
||||||
|
HIDPP_ENABLE_FAST_SCROLL,
|
||||||
|
NULL, 0, &response);
|
||||||
|
if (!ret) {
|
||||||
|
hidpp->capabilities |= HIDPP_CAPABILITY_HIDPP10_FAST_SCROLL;
|
||||||
|
hid_dbg(hidpp->hid_dev, "Detected HID++ 1.0 fast scroll\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hidpp->capabilities == capabilities)
|
||||||
|
hid_dbg(hidpp->hid_dev, "Did not detect HID++ hi-res scrolling hardware support\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
/* Generic HID++ devices */
|
/* Generic HID++ devices */
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
@ -3691,8 +3737,9 @@ static int hidpp_event(struct hid_device *hdev, struct hid_field *field,
|
|||||||
* cases we must return early (falling back to default behaviour) to
|
* cases we must return early (falling back to default behaviour) to
|
||||||
* avoid a crash in hidpp_scroll_counter_handle_scroll.
|
* avoid a crash in hidpp_scroll_counter_handle_scroll.
|
||||||
*/
|
*/
|
||||||
if (!(hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL) || value == 0
|
if (!(hidpp->capabilities & HIDPP_CAPABILITY_HI_RES_SCROLL)
|
||||||
|| hidpp->input == NULL || counter->wheel_multiplier == 0)
|
|| value == 0 || hidpp->input == NULL
|
||||||
|
|| counter->wheel_multiplier == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
hidpp_scroll_counter_handle_scroll(hidpp->input, counter, value);
|
hidpp_scroll_counter_handle_scroll(hidpp->input, counter, value);
|
||||||
@ -3924,6 +3971,7 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
hidpp_initialize_battery(hidpp);
|
hidpp_initialize_battery(hidpp);
|
||||||
|
hidpp_initialize_hires_scroll(hidpp);
|
||||||
|
|
||||||
/* forward current battery state */
|
/* forward current battery state */
|
||||||
if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP10_BATTERY) {
|
if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP10_BATTERY) {
|
||||||
@ -3943,7 +3991,7 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
|
|||||||
if (hidpp->battery.ps)
|
if (hidpp->battery.ps)
|
||||||
power_supply_changed(hidpp->battery.ps);
|
power_supply_changed(hidpp->battery.ps);
|
||||||
|
|
||||||
if (hidpp->quirks & HIDPP_QUIRK_HI_RES_SCROLL)
|
if (hidpp->capabilities & HIDPP_CAPABILITY_HI_RES_SCROLL)
|
||||||
hi_res_scroll_enable(hidpp);
|
hi_res_scroll_enable(hidpp);
|
||||||
|
|
||||||
if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) || hidpp->delayed_input)
|
if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) || hidpp->delayed_input)
|
||||||
@ -3959,8 +4007,10 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
|
|||||||
hidpp_populate_input(hidpp, input);
|
hidpp_populate_input(hidpp, input);
|
||||||
|
|
||||||
ret = input_register_device(input);
|
ret = input_register_device(input);
|
||||||
if (ret)
|
if (ret) {
|
||||||
input_free_device(input);
|
input_free_device(input);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
hidpp->delayed_input = input;
|
hidpp->delayed_input = input;
|
||||||
}
|
}
|
||||||
@ -4219,6 +4269,21 @@ static void hidpp_remove(struct hid_device *hdev)
|
|||||||
mutex_destroy(&hidpp->send_mutex);
|
mutex_destroy(&hidpp->send_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct hid_device_id unhandled_hidpp_devices[] = {
|
||||||
|
/* Logitech Harmony Adapter for PS3, handled in hid-sony */
|
||||||
|
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) },
|
||||||
|
/* Handled in hid-generic */
|
||||||
|
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD) },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool hidpp_match(struct hid_device *hdev,
|
||||||
|
bool ignore_special_driver)
|
||||||
|
{
|
||||||
|
/* Refuse to handle devices handled by other HID drivers */
|
||||||
|
return !hid_match_id(hdev, unhandled_hidpp_devices);
|
||||||
|
}
|
||||||
|
|
||||||
#define LDJ_DEVICE(product) \
|
#define LDJ_DEVICE(product) \
|
||||||
HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, \
|
HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE, \
|
||||||
USB_VENDOR_ID_LOGITECH, (product))
|
USB_VENDOR_ID_LOGITECH, (product))
|
||||||
@ -4239,42 +4304,9 @@ static const struct hid_device_id hidpp_devices[] = {
|
|||||||
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
|
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
|
||||||
USB_DEVICE_ID_LOGITECH_T651),
|
USB_DEVICE_ID_LOGITECH_T651),
|
||||||
.driver_data = HIDPP_QUIRK_CLASS_WTP },
|
.driver_data = HIDPP_QUIRK_CLASS_WTP },
|
||||||
{ /* Mouse Logitech Anywhere MX */
|
|
||||||
LDJ_DEVICE(0x1017), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
|
|
||||||
{ /* Mouse Logitech Cube */
|
|
||||||
LDJ_DEVICE(0x4010), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
|
|
||||||
{ /* Mouse Logitech M335 */
|
|
||||||
LDJ_DEVICE(0x4050), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
|
||||||
{ /* Mouse Logitech M515 */
|
|
||||||
LDJ_DEVICE(0x4007), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
|
|
||||||
{ /* Mouse logitech M560 */
|
{ /* Mouse logitech M560 */
|
||||||
LDJ_DEVICE(0x402d),
|
LDJ_DEVICE(0x402d),
|
||||||
.driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560
|
.driver_data = HIDPP_QUIRK_DELAYED_INIT | HIDPP_QUIRK_CLASS_M560 },
|
||||||
| HIDPP_QUIRK_HI_RES_SCROLL_X2120 },
|
|
||||||
{ /* Mouse Logitech M705 (firmware RQM17) */
|
|
||||||
LDJ_DEVICE(0x101b), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
|
|
||||||
{ /* Mouse Logitech M705 (firmware RQM67) */
|
|
||||||
LDJ_DEVICE(0x406d), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
|
||||||
{ /* Mouse Logitech M720 */
|
|
||||||
LDJ_DEVICE(0x405e), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
|
||||||
{ /* Mouse Logitech MX Anywhere 2 */
|
|
||||||
LDJ_DEVICE(0x404a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
|
||||||
{ LDJ_DEVICE(0x4072), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
|
||||||
{ LDJ_DEVICE(0xb013), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
|
||||||
{ LDJ_DEVICE(0xb018), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
|
||||||
{ LDJ_DEVICE(0xb01f), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
|
||||||
{ /* Mouse Logitech MX Anywhere 2S */
|
|
||||||
LDJ_DEVICE(0x406a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
|
||||||
{ /* Mouse Logitech MX Master */
|
|
||||||
LDJ_DEVICE(0x4041), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
|
||||||
{ LDJ_DEVICE(0x4060), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
|
||||||
{ LDJ_DEVICE(0x4071), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
|
||||||
{ /* Mouse Logitech MX Master 2S */
|
|
||||||
LDJ_DEVICE(0x4069), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
|
||||||
{ /* Mouse Logitech MX Master 3 */
|
|
||||||
LDJ_DEVICE(0x4082), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
|
||||||
{ /* Mouse Logitech Performance MX */
|
|
||||||
LDJ_DEVICE(0x101a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 },
|
|
||||||
{ /* Keyboard logitech K400 */
|
{ /* Keyboard logitech K400 */
|
||||||
LDJ_DEVICE(0x4024),
|
LDJ_DEVICE(0x4024),
|
||||||
.driver_data = HIDPP_QUIRK_CLASS_K400 },
|
.driver_data = HIDPP_QUIRK_CLASS_K400 },
|
||||||
@ -4335,18 +4367,9 @@ static const struct hid_device_id hidpp_devices[] = {
|
|||||||
{ /* MX5500 keyboard over Bluetooth */
|
{ /* MX5500 keyboard over Bluetooth */
|
||||||
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb30b),
|
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb30b),
|
||||||
.driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
|
.driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
|
||||||
{ /* M-RCQ142 V470 Cordless Laser Mouse over Bluetooth */
|
|
||||||
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb008) },
|
{ /* And try to enable HID++ for all the Logitech Bluetooth devices */
|
||||||
{ /* MX Master mouse over Bluetooth */
|
HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_ANY, USB_VENDOR_ID_LOGITECH, HID_ANY_ID) },
|
||||||
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb012),
|
|
||||||
.driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
|
||||||
{ /* MX Ergo trackball over Bluetooth */
|
|
||||||
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb01d) },
|
|
||||||
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb01e),
|
|
||||||
.driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
|
||||||
{ /* MX Master 3 mouse over Bluetooth */
|
|
||||||
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb023),
|
|
||||||
.driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
|
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -4360,6 +4383,7 @@ static const struct hid_usage_id hidpp_usages[] = {
|
|||||||
static struct hid_driver hidpp_driver = {
|
static struct hid_driver hidpp_driver = {
|
||||||
.name = "logitech-hidpp-device",
|
.name = "logitech-hidpp-device",
|
||||||
.id_table = hidpp_devices,
|
.id_table = hidpp_devices,
|
||||||
|
.match = hidpp_match,
|
||||||
.report_fixup = hidpp_report_fixup,
|
.report_fixup = hidpp_report_fixup,
|
||||||
.probe = hidpp_probe,
|
.probe = hidpp_probe,
|
||||||
.remove = hidpp_remove,
|
.remove = hidpp_remove,
|
||||||
|
@ -1186,7 +1186,7 @@ static void mt_touch_report(struct hid_device *hid,
|
|||||||
int contact_count = -1;
|
int contact_count = -1;
|
||||||
|
|
||||||
/* sticky fingers release in progress, abort */
|
/* sticky fingers release in progress, abort */
|
||||||
if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
|
if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
scantime = *app->scantime;
|
scantime = *app->scantime;
|
||||||
@ -1267,7 +1267,7 @@ static void mt_touch_report(struct hid_device *hid,
|
|||||||
del_timer(&td->release_timer);
|
del_timer(&td->release_timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
clear_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
|
clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mt_touch_input_configured(struct hid_device *hdev,
|
static int mt_touch_input_configured(struct hid_device *hdev,
|
||||||
@ -1699,11 +1699,11 @@ static void mt_expired_timeout(struct timer_list *t)
|
|||||||
* An input report came in just before we release the sticky fingers,
|
* An input report came in just before we release the sticky fingers,
|
||||||
* it will take care of the sticky fingers.
|
* it will take care of the sticky fingers.
|
||||||
*/
|
*/
|
||||||
if (test_and_set_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
|
if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
|
||||||
return;
|
return;
|
||||||
if (test_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags))
|
if (test_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags))
|
||||||
mt_release_contacts(hdev);
|
mt_release_contacts(hdev);
|
||||||
clear_bit(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
|
clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||||
|
@ -760,12 +760,31 @@ static int joycon_read_stick_calibration(struct joycon_ctlr *ctlr, u16 cal_addr,
|
|||||||
cal_y->max = cal_y->center + y_max_above;
|
cal_y->max = cal_y->center + y_max_above;
|
||||||
cal_y->min = cal_y->center - y_min_below;
|
cal_y->min = cal_y->center - y_min_below;
|
||||||
|
|
||||||
return 0;
|
/* check if calibration values are plausible */
|
||||||
|
if (cal_x->min >= cal_x->center || cal_x->center >= cal_x->max ||
|
||||||
|
cal_y->min >= cal_y->center || cal_y->center >= cal_y->max)
|
||||||
|
ret = -EINVAL;
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const u16 DFLT_STICK_CAL_CEN = 2000;
|
static const u16 DFLT_STICK_CAL_CEN = 2000;
|
||||||
static const u16 DFLT_STICK_CAL_MAX = 3500;
|
static const u16 DFLT_STICK_CAL_MAX = 3500;
|
||||||
static const u16 DFLT_STICK_CAL_MIN = 500;
|
static const u16 DFLT_STICK_CAL_MIN = 500;
|
||||||
|
static void joycon_use_default_calibration(struct hid_device *hdev,
|
||||||
|
struct joycon_stick_cal *cal_x,
|
||||||
|
struct joycon_stick_cal *cal_y,
|
||||||
|
const char *stick, int ret)
|
||||||
|
{
|
||||||
|
hid_warn(hdev,
|
||||||
|
"Failed to read %s stick cal, using defaults; e=%d\n",
|
||||||
|
stick, ret);
|
||||||
|
|
||||||
|
cal_x->center = cal_y->center = DFLT_STICK_CAL_CEN;
|
||||||
|
cal_x->max = cal_y->max = DFLT_STICK_CAL_MAX;
|
||||||
|
cal_x->min = cal_y->min = DFLT_STICK_CAL_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
static int joycon_request_calibration(struct joycon_ctlr *ctlr)
|
static int joycon_request_calibration(struct joycon_ctlr *ctlr)
|
||||||
{
|
{
|
||||||
u16 left_stick_addr = JC_CAL_FCT_DATA_LEFT_ADDR;
|
u16 left_stick_addr = JC_CAL_FCT_DATA_LEFT_ADDR;
|
||||||
@ -793,38 +812,24 @@ static int joycon_request_calibration(struct joycon_ctlr *ctlr)
|
|||||||
&ctlr->left_stick_cal_x,
|
&ctlr->left_stick_cal_x,
|
||||||
&ctlr->left_stick_cal_y,
|
&ctlr->left_stick_cal_y,
|
||||||
true);
|
true);
|
||||||
if (ret) {
|
|
||||||
hid_warn(ctlr->hdev,
|
|
||||||
"Failed to read left stick cal, using dflts; e=%d\n",
|
|
||||||
ret);
|
|
||||||
|
|
||||||
ctlr->left_stick_cal_x.center = DFLT_STICK_CAL_CEN;
|
if (ret)
|
||||||
ctlr->left_stick_cal_x.max = DFLT_STICK_CAL_MAX;
|
joycon_use_default_calibration(ctlr->hdev,
|
||||||
ctlr->left_stick_cal_x.min = DFLT_STICK_CAL_MIN;
|
&ctlr->left_stick_cal_x,
|
||||||
|
&ctlr->left_stick_cal_y,
|
||||||
ctlr->left_stick_cal_y.center = DFLT_STICK_CAL_CEN;
|
"left", ret);
|
||||||
ctlr->left_stick_cal_y.max = DFLT_STICK_CAL_MAX;
|
|
||||||
ctlr->left_stick_cal_y.min = DFLT_STICK_CAL_MIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read the right stick calibration data */
|
/* read the right stick calibration data */
|
||||||
ret = joycon_read_stick_calibration(ctlr, right_stick_addr,
|
ret = joycon_read_stick_calibration(ctlr, right_stick_addr,
|
||||||
&ctlr->right_stick_cal_x,
|
&ctlr->right_stick_cal_x,
|
||||||
&ctlr->right_stick_cal_y,
|
&ctlr->right_stick_cal_y,
|
||||||
false);
|
false);
|
||||||
if (ret) {
|
|
||||||
hid_warn(ctlr->hdev,
|
|
||||||
"Failed to read right stick cal, using dflts; e=%d\n",
|
|
||||||
ret);
|
|
||||||
|
|
||||||
ctlr->right_stick_cal_x.center = DFLT_STICK_CAL_CEN;
|
if (ret)
|
||||||
ctlr->right_stick_cal_x.max = DFLT_STICK_CAL_MAX;
|
joycon_use_default_calibration(ctlr->hdev,
|
||||||
ctlr->right_stick_cal_x.min = DFLT_STICK_CAL_MIN;
|
&ctlr->right_stick_cal_x,
|
||||||
|
&ctlr->right_stick_cal_y,
|
||||||
ctlr->right_stick_cal_y.center = DFLT_STICK_CAL_CEN;
|
"right", ret);
|
||||||
ctlr->right_stick_cal_y.max = DFLT_STICK_CAL_MAX;
|
|
||||||
ctlr->right_stick_cal_y.min = DFLT_STICK_CAL_MIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
hid_dbg(ctlr->hdev, "calibration:\n"
|
hid_dbg(ctlr->hdev, "calibration:\n"
|
||||||
"l_x_c=%d l_x_max=%d l_x_min=%d\n"
|
"l_x_c=%d l_x_max=%d l_x_min=%d\n"
|
||||||
@ -1904,9 +1909,8 @@ static int joycon_leds_create(struct joycon_ctlr *ctlr)
|
|||||||
/* Set the home LED to 0 as default state */
|
/* Set the home LED to 0 as default state */
|
||||||
ret = joycon_home_led_brightness_set(led, 0);
|
ret = joycon_home_led_brightness_set(led, 0);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
hid_err(hdev, "Failed to set home LED dflt; ret=%d\n",
|
hid_warn(hdev, "Failed to set home LED default, unregistering home LED");
|
||||||
ret);
|
devm_led_classdev_unregister(&hdev->dev, led);
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,15 +692,12 @@ static ssize_t hardware_version_show(struct device *dev,
|
|||||||
|
|
||||||
static DEVICE_ATTR_RO(hardware_version);
|
static DEVICE_ATTR_RO(hardware_version);
|
||||||
|
|
||||||
static struct attribute *ps_device_attributes[] = {
|
static struct attribute *ps_device_attrs[] = {
|
||||||
&dev_attr_firmware_version.attr,
|
&dev_attr_firmware_version.attr,
|
||||||
&dev_attr_hardware_version.attr,
|
&dev_attr_hardware_version.attr,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
ATTRIBUTE_GROUPS(ps_device);
|
||||||
static const struct attribute_group ps_device_attribute_group = {
|
|
||||||
.attrs = ps_device_attributes,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int dualsense_get_calibration_data(struct dualsense *ds)
|
static int dualsense_get_calibration_data(struct dualsense *ds)
|
||||||
{
|
{
|
||||||
@ -1448,12 +1445,6 @@ static int ps_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = devm_device_add_group(&hdev->dev, &ps_device_attribute_group);
|
|
||||||
if (ret) {
|
|
||||||
hid_err(hdev, "Failed to register sysfs nodes.\n");
|
|
||||||
goto err_close;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
err_close:
|
err_close:
|
||||||
@ -1487,6 +1478,9 @@ static struct hid_driver ps_driver = {
|
|||||||
.probe = ps_probe,
|
.probe = ps_probe,
|
||||||
.remove = ps_remove,
|
.remove = ps_remove,
|
||||||
.raw_event = ps_raw_event,
|
.raw_event = ps_raw_event,
|
||||||
|
.driver = {
|
||||||
|
.dev_groups = ps_device_groups,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init ps_init(void)
|
static int __init ps_init(void)
|
||||||
|
112
drivers/hid/hid-pxrc.c
Normal file
112
drivers/hid/hid-pxrc.c
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
/*
|
||||||
|
* HID driver for PhoenixRC 8-axis flight controller
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Marcus Folkesson <marcus.folkesson@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/hid.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
|
||||||
|
#include "hid-ids.h"
|
||||||
|
|
||||||
|
struct pxrc_priv {
|
||||||
|
u8 slider;
|
||||||
|
u8 dial;
|
||||||
|
bool alternate;
|
||||||
|
};
|
||||||
|
|
||||||
|
static __u8 pxrc_rdesc_fixed[] = {
|
||||||
|
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||||||
|
0x09, 0x04, // Usage (Joystick)
|
||||||
|
0xA1, 0x01, // Collection (Application)
|
||||||
|
0x09, 0x01, // Usage (Pointer)
|
||||||
|
0xA1, 0x00, // Collection (Physical)
|
||||||
|
0x09, 0x30, // Usage (X)
|
||||||
|
0x09, 0x36, // Usage (Slider)
|
||||||
|
0x09, 0x31, // Usage (Y)
|
||||||
|
0x09, 0x32, // Usage (Z)
|
||||||
|
0x09, 0x33, // Usage (Rx)
|
||||||
|
0x09, 0x34, // Usage (Ry)
|
||||||
|
0x09, 0x35, // Usage (Rz)
|
||||||
|
0x09, 0x37, // Usage (Dial)
|
||||||
|
0x15, 0x00, // Logical Minimum (0)
|
||||||
|
0x26, 0xFF, 0x00, // Logical Maximum (255)
|
||||||
|
0x35, 0x00, // Physical Minimum (0)
|
||||||
|
0x46, 0xFF, 0x00, // Physical Maximum (255)
|
||||||
|
0x75, 0x08, // Report Size (8)
|
||||||
|
0x95, 0x08, // Report Count (8)
|
||||||
|
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||||
|
0xC0, // End Collection
|
||||||
|
0xC0, // End Collection
|
||||||
|
};
|
||||||
|
|
||||||
|
static __u8 *pxrc_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||||
|
unsigned int *rsize)
|
||||||
|
{
|
||||||
|
hid_info(hdev, "fixing up PXRC report descriptor\n");
|
||||||
|
*rsize = sizeof(pxrc_rdesc_fixed);
|
||||||
|
return pxrc_rdesc_fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pxrc_raw_event(struct hid_device *hdev, struct hid_report *report,
|
||||||
|
u8 *data, int size)
|
||||||
|
{
|
||||||
|
struct pxrc_priv *priv = hid_get_drvdata(hdev);
|
||||||
|
|
||||||
|
if (priv->alternate)
|
||||||
|
priv->slider = data[7];
|
||||||
|
else
|
||||||
|
priv->dial = data[7];
|
||||||
|
|
||||||
|
data[1] = priv->slider;
|
||||||
|
data[7] = priv->dial;
|
||||||
|
|
||||||
|
priv->alternate = !priv->alternate;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pxrc_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct pxrc_priv *priv;
|
||||||
|
|
||||||
|
priv = devm_kzalloc(&hdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||||
|
if (!priv)
|
||||||
|
return -ENOMEM;
|
||||||
|
hid_set_drvdata(hdev, priv);
|
||||||
|
|
||||||
|
ret = hid_parse(hdev);
|
||||||
|
if (ret) {
|
||||||
|
hid_err(hdev, "parse failed\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||||
|
if (ret) {
|
||||||
|
hid_err(hdev, "hw start failed\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct hid_device_id pxrc_devices[] = {
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_MULTIPLE_1781, USB_DEVICE_ID_PHOENIXRC) },
|
||||||
|
{ /* sentinel */ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(hid, pxrc_devices);
|
||||||
|
|
||||||
|
static struct hid_driver pxrc_driver = {
|
||||||
|
.name = "hid-pxrc",
|
||||||
|
.id_table = pxrc_devices,
|
||||||
|
.report_fixup = pxrc_report_fixup,
|
||||||
|
.probe = pxrc_probe,
|
||||||
|
.raw_event = pxrc_raw_event,
|
||||||
|
};
|
||||||
|
module_hid_driver(pxrc_driver);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Marcus Folkesson <marcus.folkesson@gmail.com>");
|
||||||
|
MODULE_DESCRIPTION("HID driver for PXRC 8-axis flight controller");
|
||||||
|
MODULE_LICENSE("GPL");
|
@ -237,8 +237,7 @@ static int rmi_hid_read_block(struct rmi_transport_dev *xport, u16 addr,
|
|||||||
|
|
||||||
read_input_count = data->readReport[1];
|
read_input_count = data->readReport[1];
|
||||||
memcpy(buf + bytes_read, &data->readReport[2],
|
memcpy(buf + bytes_read, &data->readReport[2],
|
||||||
read_input_count < bytes_needed ?
|
min(read_input_count, bytes_needed));
|
||||||
read_input_count : bytes_needed);
|
|
||||||
|
|
||||||
bytes_read += read_input_count;
|
bytes_read += read_input_count;
|
||||||
bytes_needed -= read_input_count;
|
bytes_needed -= read_input_count;
|
||||||
@ -347,8 +346,7 @@ static int rmi_read_data_event(struct hid_device *hdev, u8 *data, int size)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(hdata->readReport, data, size < hdata->input_report_size ?
|
memcpy(hdata->readReport, data, min((u32)size, hdata->input_report_size));
|
||||||
size : hdata->input_report_size);
|
|
||||||
set_bit(RMI_READ_DATA_PENDING, &hdata->flags);
|
set_bit(RMI_READ_DATA_PENDING, &hdata->flags);
|
||||||
wake_up(&hdata->wait);
|
wake_up(&hdata->wait);
|
||||||
|
|
||||||
|
@ -257,6 +257,8 @@ int roccat_report_event(int minor, u8 const *data)
|
|||||||
if (!new_value)
|
if (!new_value)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
mutex_lock(&device->cbuf_lock);
|
||||||
|
|
||||||
report = &device->cbuf[device->cbuf_end];
|
report = &device->cbuf[device->cbuf_end];
|
||||||
|
|
||||||
/* passing NULL is safe */
|
/* passing NULL is safe */
|
||||||
@ -276,6 +278,8 @@ int roccat_report_event(int minor, u8 const *data)
|
|||||||
reader->cbuf_start = (reader->cbuf_start + 1) % ROCCAT_CBUF_SIZE;
|
reader->cbuf_start = (reader->cbuf_start + 1) % ROCCAT_CBUF_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&device->cbuf_lock);
|
||||||
|
|
||||||
wake_up_interruptible(&device->wait);
|
wake_up_interruptible(&device->wait);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -368,7 +368,7 @@ static const unsigned int buzz_keymap[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* The Navigation controller is a partial DS3 and uses the same HID report
|
/* The Navigation controller is a partial DS3 and uses the same HID report
|
||||||
* and hence the same keymap indices, however not not all axes/buttons
|
* and hence the same keymap indices, however not all axes/buttons
|
||||||
* are physically present. We use the same axis and button mapping as
|
* are physically present. We use the same axis and button mapping as
|
||||||
* the DS3, which uses the Linux gamepad spec.
|
* the DS3, which uses the Linux gamepad spec.
|
||||||
*/
|
*/
|
||||||
|
@ -256,7 +256,7 @@ static int steam_get_serial(struct steam_device *steam)
|
|||||||
if (reply[0] != 0xae || reply[1] != 0x15 || reply[2] != 0x01)
|
if (reply[0] != 0xae || reply[1] != 0x15 || reply[2] != 0x01)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
reply[3 + STEAM_SERIAL_LEN] = 0;
|
reply[3 + STEAM_SERIAL_LEN] = 0;
|
||||||
strlcpy(steam->serial_no, reply + 3, sizeof(steam->serial_no));
|
strscpy(steam->serial_no, reply + 3, sizeof(steam->serial_no));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -524,7 +524,7 @@ static int steam_register(struct steam_device *steam)
|
|||||||
*/
|
*/
|
||||||
mutex_lock(&steam->mutex);
|
mutex_lock(&steam->mutex);
|
||||||
if (steam_get_serial(steam) < 0)
|
if (steam_get_serial(steam) < 0)
|
||||||
strlcpy(steam->serial_no, "XXXXXXXXXX",
|
strscpy(steam->serial_no, "XXXXXXXXXX",
|
||||||
sizeof(steam->serial_no));
|
sizeof(steam->serial_no));
|
||||||
mutex_unlock(&steam->mutex);
|
mutex_unlock(&steam->mutex);
|
||||||
|
|
||||||
@ -699,9 +699,9 @@ static struct hid_device *steam_create_client_hid(struct hid_device *hdev)
|
|||||||
client_hdev->version = hdev->version;
|
client_hdev->version = hdev->version;
|
||||||
client_hdev->type = hdev->type;
|
client_hdev->type = hdev->type;
|
||||||
client_hdev->country = hdev->country;
|
client_hdev->country = hdev->country;
|
||||||
strlcpy(client_hdev->name, hdev->name,
|
strscpy(client_hdev->name, hdev->name,
|
||||||
sizeof(client_hdev->name));
|
sizeof(client_hdev->name));
|
||||||
strlcpy(client_hdev->phys, hdev->phys,
|
strscpy(client_hdev->phys, hdev->phys,
|
||||||
sizeof(client_hdev->phys));
|
sizeof(client_hdev->phys));
|
||||||
/*
|
/*
|
||||||
* Since we use the same device info than the real interface to
|
* Since we use the same device info than the real interface to
|
||||||
|
49
drivers/hid/hid-topre.c
Normal file
49
drivers/hid/hid-topre.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* HID driver for Topre REALFORCE Keyboards
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 Harry Stern <harry@harrystern.net>
|
||||||
|
*
|
||||||
|
* Based on the hid-macally driver
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/hid.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
|
||||||
|
#include "hid-ids.h"
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Harry Stern <harry@harrystern.net>");
|
||||||
|
MODULE_DESCRIPTION("REALFORCE R2 Keyboard driver");
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fix the REALFORCE R2's non-boot interface's report descriptor to match the
|
||||||
|
* events it's actually sending. It claims to send array events but is instead
|
||||||
|
* sending variable events.
|
||||||
|
*/
|
||||||
|
static __u8 *topre_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||||
|
unsigned int *rsize)
|
||||||
|
{
|
||||||
|
if (*rsize >= 119 && rdesc[69] == 0x29 && rdesc[70] == 0xe7 &&
|
||||||
|
rdesc[71] == 0x81 && rdesc[72] == 0x00) {
|
||||||
|
hid_info(hdev,
|
||||||
|
"fixing up Topre REALFORCE keyboard report descriptor\n");
|
||||||
|
rdesc[72] = 0x02;
|
||||||
|
}
|
||||||
|
return rdesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct hid_device_id topre_id_table[] = {
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_TOPRE,
|
||||||
|
USB_DEVICE_ID_TOPRE_REALFORCE_R2_108) },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(hid, topre_id_table);
|
||||||
|
|
||||||
|
static struct hid_driver topre_driver = {
|
||||||
|
.name = "topre",
|
||||||
|
.id_table = topre_id_table,
|
||||||
|
.report_fixup = topre_report_fixup,
|
||||||
|
};
|
||||||
|
|
||||||
|
module_hid_driver(topre_driver);
|
@ -153,6 +153,7 @@ static int uclogic_input_configured(struct hid_device *hdev,
|
|||||||
suffix = "Pad";
|
suffix = "Pad";
|
||||||
break;
|
break;
|
||||||
case HID_DG_PEN:
|
case HID_DG_PEN:
|
||||||
|
case HID_DG_DIGITIZER:
|
||||||
suffix = "Pen";
|
suffix = "Pen";
|
||||||
break;
|
break;
|
||||||
case HID_CP_CONSUMER_CONTROL:
|
case HID_CP_CONSUMER_CONTROL:
|
||||||
@ -509,6 +510,8 @@ static const struct hid_device_id uclogic_devices[] = {
|
|||||||
USB_DEVICE_ID_UGTIZER_TABLET_GP0610) },
|
USB_DEVICE_ID_UGTIZER_TABLET_GP0610) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER,
|
{ HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER,
|
||||||
USB_DEVICE_ID_UGTIZER_TABLET_GT5040) },
|
USB_DEVICE_ID_UGTIZER_TABLET_GT5040) },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
|
||||||
|
USB_DEVICE_ID_UGEE_PARBLO_A610_PRO) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
|
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
|
||||||
USB_DEVICE_ID_UGEE_TABLET_G5) },
|
USB_DEVICE_ID_UGEE_TABLET_G5) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
|
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
|
||||||
@ -523,6 +526,8 @@ static const struct hid_device_id uclogic_devices[] = {
|
|||||||
USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01) },
|
USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO01) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
|
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
|
||||||
USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L) },
|
USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L) },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
|
||||||
|
USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_S) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
|
{ HID_USB_DEVICE(USB_VENDOR_ID_UGEE,
|
||||||
USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06) },
|
USB_DEVICE_ID_UGEE_XPPEN_TABLET_STAR06) },
|
||||||
{ }
|
{ }
|
||||||
|
192
drivers/hid/hid-uclogic-params-test.c
Normal file
192
drivers/hid/hid-uclogic-params-test.c
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HID driver for UC-Logic devices not fully compliant with HID standard
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 José Expósito <jose.exposito89@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <kunit/test.h>
|
||||||
|
#include "./hid-uclogic-params.h"
|
||||||
|
#include "./hid-uclogic-rdesc.h"
|
||||||
|
|
||||||
|
#define MAX_STR_DESC_SIZE 14
|
||||||
|
|
||||||
|
struct uclogic_parse_ugee_v2_desc_case {
|
||||||
|
const char *name;
|
||||||
|
int res;
|
||||||
|
const __u8 str_desc[MAX_STR_DESC_SIZE];
|
||||||
|
size_t str_desc_size;
|
||||||
|
const s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
|
||||||
|
enum uclogic_params_frame_type frame_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct uclogic_parse_ugee_v2_desc_case uclogic_parse_ugee_v2_desc_cases[] = {
|
||||||
|
{
|
||||||
|
.name = "invalid_str_desc",
|
||||||
|
.res = -EINVAL,
|
||||||
|
.str_desc = {},
|
||||||
|
.str_desc_size = 0,
|
||||||
|
.desc_params = {},
|
||||||
|
.frame_type = UCLOGIC_PARAMS_FRAME_BUTTONS,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "resolution_with_value_0",
|
||||||
|
.res = 0,
|
||||||
|
.str_desc = {
|
||||||
|
0x0E, 0x03,
|
||||||
|
0x70, 0xB2,
|
||||||
|
0x10, 0x77,
|
||||||
|
0x08,
|
||||||
|
0x00,
|
||||||
|
0xFF, 0x1F,
|
||||||
|
0x00, 0x00,
|
||||||
|
},
|
||||||
|
.str_desc_size = 12,
|
||||||
|
.desc_params = {
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_X_LM] = 0xB270,
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0,
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] = 0x7710,
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0,
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = 0x1FFF,
|
||||||
|
[UCLOGIC_RDESC_FRAME_PH_ID_UM] = 0x08,
|
||||||
|
},
|
||||||
|
.frame_type = UCLOGIC_PARAMS_FRAME_BUTTONS,
|
||||||
|
},
|
||||||
|
/* XP-PEN Deco L str_desc: Frame with 8 buttons */
|
||||||
|
{
|
||||||
|
.name = "frame_type_buttons",
|
||||||
|
.res = 0,
|
||||||
|
.str_desc = {
|
||||||
|
0x0E, 0x03,
|
||||||
|
0x70, 0xB2,
|
||||||
|
0x10, 0x77,
|
||||||
|
0x08,
|
||||||
|
0x00,
|
||||||
|
0xFF, 0x1F,
|
||||||
|
0xD8, 0x13,
|
||||||
|
},
|
||||||
|
.str_desc_size = 12,
|
||||||
|
.desc_params = {
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_X_LM] = 0xB270,
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0x2320,
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] = 0x7710,
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0x1770,
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = 0x1FFF,
|
||||||
|
[UCLOGIC_RDESC_FRAME_PH_ID_UM] = 0x08,
|
||||||
|
},
|
||||||
|
.frame_type = UCLOGIC_PARAMS_FRAME_BUTTONS,
|
||||||
|
},
|
||||||
|
/* PARBLO A610 PRO str_desc: Frame with 9 buttons and dial */
|
||||||
|
{
|
||||||
|
.name = "frame_type_dial",
|
||||||
|
.res = 0,
|
||||||
|
.str_desc = {
|
||||||
|
0x0E, 0x03,
|
||||||
|
0x96, 0xC7,
|
||||||
|
0xF9, 0x7C,
|
||||||
|
0x09,
|
||||||
|
0x01,
|
||||||
|
0xFF, 0x1F,
|
||||||
|
0xD8, 0x13,
|
||||||
|
},
|
||||||
|
.str_desc_size = 12,
|
||||||
|
.desc_params = {
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_X_LM] = 0xC796,
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0x2749,
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] = 0x7CF9,
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0x1899,
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = 0x1FFF,
|
||||||
|
[UCLOGIC_RDESC_FRAME_PH_ID_UM] = 0x09,
|
||||||
|
},
|
||||||
|
.frame_type = UCLOGIC_PARAMS_FRAME_DIAL,
|
||||||
|
},
|
||||||
|
/* XP-PEN Deco Pro S str_desc: Frame with 8 buttons and mouse */
|
||||||
|
{
|
||||||
|
.name = "frame_type_mouse",
|
||||||
|
.res = 0,
|
||||||
|
.str_desc = {
|
||||||
|
0x0E, 0x03,
|
||||||
|
0xC8, 0xB3,
|
||||||
|
0x34, 0x65,
|
||||||
|
0x08,
|
||||||
|
0x02,
|
||||||
|
0xFF, 0x1F,
|
||||||
|
0xD8, 0x13,
|
||||||
|
},
|
||||||
|
.str_desc_size = 12,
|
||||||
|
.desc_params = {
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_X_LM] = 0xB3C8,
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0x2363,
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] = 0x6534,
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0x13EC,
|
||||||
|
[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = 0x1FFF,
|
||||||
|
[UCLOGIC_RDESC_FRAME_PH_ID_UM] = 0x08,
|
||||||
|
},
|
||||||
|
.frame_type = UCLOGIC_PARAMS_FRAME_MOUSE,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void uclogic_parse_ugee_v2_desc_case_desc(struct uclogic_parse_ugee_v2_desc_case *t,
|
||||||
|
char *desc)
|
||||||
|
{
|
||||||
|
strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
KUNIT_ARRAY_PARAM(uclogic_parse_ugee_v2_desc, uclogic_parse_ugee_v2_desc_cases,
|
||||||
|
uclogic_parse_ugee_v2_desc_case_desc);
|
||||||
|
|
||||||
|
static void uclogic_parse_ugee_v2_desc_test(struct kunit *test)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
|
||||||
|
enum uclogic_params_frame_type frame_type;
|
||||||
|
const struct uclogic_parse_ugee_v2_desc_case *params = test->param_value;
|
||||||
|
|
||||||
|
res = uclogic_params_parse_ugee_v2_desc(params->str_desc,
|
||||||
|
params->str_desc_size,
|
||||||
|
desc_params,
|
||||||
|
ARRAY_SIZE(desc_params),
|
||||||
|
&frame_type);
|
||||||
|
KUNIT_ASSERT_EQ(test, res, params->res);
|
||||||
|
|
||||||
|
if (res)
|
||||||
|
return;
|
||||||
|
|
||||||
|
KUNIT_EXPECT_EQ(test,
|
||||||
|
params->desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM],
|
||||||
|
desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM]);
|
||||||
|
KUNIT_EXPECT_EQ(test,
|
||||||
|
params->desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM],
|
||||||
|
desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM]);
|
||||||
|
KUNIT_EXPECT_EQ(test,
|
||||||
|
params->desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM],
|
||||||
|
desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM]);
|
||||||
|
KUNIT_EXPECT_EQ(test,
|
||||||
|
params->desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM],
|
||||||
|
desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM]);
|
||||||
|
KUNIT_EXPECT_EQ(test,
|
||||||
|
params->desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM],
|
||||||
|
desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM]);
|
||||||
|
KUNIT_EXPECT_EQ(test,
|
||||||
|
params->desc_params[UCLOGIC_RDESC_FRAME_PH_ID_UM],
|
||||||
|
desc_params[UCLOGIC_RDESC_FRAME_PH_ID_UM]);
|
||||||
|
KUNIT_EXPECT_EQ(test, params->frame_type, frame_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct kunit_case hid_uclogic_params_test_cases[] = {
|
||||||
|
KUNIT_CASE_PARAM(uclogic_parse_ugee_v2_desc_test,
|
||||||
|
uclogic_parse_ugee_v2_desc_gen_params),
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct kunit_suite hid_uclogic_params_test_suite = {
|
||||||
|
.name = "hid_uclogic_params_test",
|
||||||
|
.test_cases = hid_uclogic_params_test_cases,
|
||||||
|
};
|
||||||
|
|
||||||
|
kunit_test_suite(hid_uclogic_params_test_suite);
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("KUnit tests for the UC-Logic driver");
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_AUTHOR("José Expósito <jose.exposito89@gmail.com>");
|
@ -1056,6 +1056,161 @@ cleanup:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* uclogic_params_parse_ugee_v2_desc - parse the string descriptor containing
|
||||||
|
* pen and frame parameters returned by UGEE v2 devices.
|
||||||
|
*
|
||||||
|
* @str_desc: String descriptor, cannot be NULL.
|
||||||
|
* @str_desc_size: Size of the string descriptor.
|
||||||
|
* @desc_params: Output description params list.
|
||||||
|
* @desc_params_size: Size of the output description params list.
|
||||||
|
* @frame_type: Output frame type.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Zero, if successful. A negative errno code on error.
|
||||||
|
*/
|
||||||
|
static int uclogic_params_parse_ugee_v2_desc(const __u8 *str_desc,
|
||||||
|
size_t str_desc_size,
|
||||||
|
s32 *desc_params,
|
||||||
|
size_t desc_params_size,
|
||||||
|
enum uclogic_params_frame_type *frame_type)
|
||||||
|
{
|
||||||
|
s32 pen_x_lm, pen_y_lm;
|
||||||
|
s32 pen_x_pm, pen_y_pm;
|
||||||
|
s32 pen_pressure_lm;
|
||||||
|
s32 frame_num_buttons;
|
||||||
|
s32 resolution;
|
||||||
|
|
||||||
|
/* Minimum descriptor length required, maximum seen so far is 14 */
|
||||||
|
const int min_str_desc_size = 12;
|
||||||
|
|
||||||
|
if (!str_desc || str_desc_size < min_str_desc_size)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (desc_params_size != UCLOGIC_RDESC_PH_ID_NUM)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
pen_x_lm = get_unaligned_le16(str_desc + 2);
|
||||||
|
pen_y_lm = get_unaligned_le16(str_desc + 4);
|
||||||
|
frame_num_buttons = str_desc[6];
|
||||||
|
*frame_type = str_desc[7];
|
||||||
|
pen_pressure_lm = get_unaligned_le16(str_desc + 8);
|
||||||
|
|
||||||
|
resolution = get_unaligned_le16(str_desc + 10);
|
||||||
|
if (resolution == 0) {
|
||||||
|
pen_x_pm = 0;
|
||||||
|
pen_y_pm = 0;
|
||||||
|
} else {
|
||||||
|
pen_x_pm = pen_x_lm * 1000 / resolution;
|
||||||
|
pen_y_pm = pen_y_lm * 1000 / resolution;
|
||||||
|
}
|
||||||
|
|
||||||
|
desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] = pen_x_lm;
|
||||||
|
desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = pen_x_pm;
|
||||||
|
desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] = pen_y_lm;
|
||||||
|
desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = pen_y_pm;
|
||||||
|
desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] = pen_pressure_lm;
|
||||||
|
desc_params[UCLOGIC_RDESC_FRAME_PH_ID_UM] = frame_num_buttons;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* uclogic_params_ugee_v2_init_frame_buttons() - initialize a UGEE v2 frame with
|
||||||
|
* buttons.
|
||||||
|
* @p: Parameters to fill in, cannot be NULL.
|
||||||
|
* @desc_params: Device description params list.
|
||||||
|
* @desc_params_size: Size of the description params list.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Zero, if successful. A negative errno code on error.
|
||||||
|
*/
|
||||||
|
static int uclogic_params_ugee_v2_init_frame_buttons(struct uclogic_params *p,
|
||||||
|
const s32 *desc_params,
|
||||||
|
size_t desc_params_size)
|
||||||
|
{
|
||||||
|
__u8 *rdesc_frame = NULL;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (!p || desc_params_size != UCLOGIC_RDESC_PH_ID_NUM)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
rdesc_frame = uclogic_rdesc_template_apply(
|
||||||
|
uclogic_rdesc_ugee_v2_frame_btn_template_arr,
|
||||||
|
uclogic_rdesc_ugee_v2_frame_btn_template_size,
|
||||||
|
desc_params, UCLOGIC_RDESC_PH_ID_NUM);
|
||||||
|
if (!rdesc_frame)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
rc = uclogic_params_frame_init_with_desc(&p->frame_list[0],
|
||||||
|
rdesc_frame,
|
||||||
|
uclogic_rdesc_ugee_v2_frame_btn_template_size,
|
||||||
|
UCLOGIC_RDESC_V1_FRAME_ID);
|
||||||
|
kfree(rdesc_frame);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* uclogic_params_ugee_v2_init_frame_dial() - initialize a UGEE v2 frame with a
|
||||||
|
* bitmap dial.
|
||||||
|
* @p: Parameters to fill in, cannot be NULL.
|
||||||
|
* @desc_params: Device description params list.
|
||||||
|
* @desc_params_size: Size of the description params list.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Zero, if successful. A negative errno code on error.
|
||||||
|
*/
|
||||||
|
static int uclogic_params_ugee_v2_init_frame_dial(struct uclogic_params *p,
|
||||||
|
const s32 *desc_params,
|
||||||
|
size_t desc_params_size)
|
||||||
|
{
|
||||||
|
__u8 *rdesc_frame = NULL;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (!p || desc_params_size != UCLOGIC_RDESC_PH_ID_NUM)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
rdesc_frame = uclogic_rdesc_template_apply(
|
||||||
|
uclogic_rdesc_ugee_v2_frame_dial_template_arr,
|
||||||
|
uclogic_rdesc_ugee_v2_frame_dial_template_size,
|
||||||
|
desc_params, UCLOGIC_RDESC_PH_ID_NUM);
|
||||||
|
if (!rdesc_frame)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
rc = uclogic_params_frame_init_with_desc(&p->frame_list[0],
|
||||||
|
rdesc_frame,
|
||||||
|
uclogic_rdesc_ugee_v2_frame_dial_template_size,
|
||||||
|
UCLOGIC_RDESC_V1_FRAME_ID);
|
||||||
|
kfree(rdesc_frame);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
p->frame_list[0].bitmap_dial_byte = 7;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* uclogic_params_ugee_v2_init_frame_mouse() - initialize a UGEE v2 frame with a
|
||||||
|
* mouse.
|
||||||
|
* @p: Parameters to fill in, cannot be NULL.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* Zero, if successful. A negative errno code on error.
|
||||||
|
*/
|
||||||
|
static int uclogic_params_ugee_v2_init_frame_mouse(struct uclogic_params *p)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (!p)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
rc = uclogic_params_frame_init_with_desc(&p->frame_list[1],
|
||||||
|
uclogic_rdesc_ugee_v2_frame_mouse_template_arr,
|
||||||
|
uclogic_rdesc_ugee_v2_frame_mouse_template_size,
|
||||||
|
UCLOGIC_RDESC_V1_FRAME_ID);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* uclogic_params_ugee_v2_init() - initialize a UGEE graphics tablets by
|
* uclogic_params_ugee_v2_init() - initialize a UGEE graphics tablets by
|
||||||
* discovering their parameters.
|
* discovering their parameters.
|
||||||
@ -1084,9 +1239,8 @@ static int uclogic_params_ugee_v2_init(struct uclogic_params *params,
|
|||||||
const int str_desc_len = 12;
|
const int str_desc_len = 12;
|
||||||
__u8 *str_desc = NULL;
|
__u8 *str_desc = NULL;
|
||||||
__u8 *rdesc_pen = NULL;
|
__u8 *rdesc_pen = NULL;
|
||||||
__u8 *rdesc_frame = NULL;
|
|
||||||
s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
|
s32 desc_params[UCLOGIC_RDESC_PH_ID_NUM];
|
||||||
s32 resolution;
|
enum uclogic_params_frame_type frame_type;
|
||||||
__u8 magic_arr[] = {
|
__u8 magic_arr[] = {
|
||||||
0x02, 0xb0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
0x02, 0xb0, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
};
|
};
|
||||||
@ -1100,6 +1254,15 @@ static int uclogic_params_ugee_v2_init(struct uclogic_params *params,
|
|||||||
|
|
||||||
iface = to_usb_interface(hdev->dev.parent);
|
iface = to_usb_interface(hdev->dev.parent);
|
||||||
bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
|
bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber;
|
||||||
|
|
||||||
|
if (bInterfaceNumber == 0) {
|
||||||
|
rc = uclogic_params_ugee_v2_init_frame_mouse(&p);
|
||||||
|
if (rc)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
goto output;
|
||||||
|
}
|
||||||
|
|
||||||
if (bInterfaceNumber != 2) {
|
if (bInterfaceNumber != 2) {
|
||||||
uclogic_params_init_invalid(&p);
|
uclogic_params_init_invalid(&p);
|
||||||
goto output;
|
goto output;
|
||||||
@ -1128,25 +1291,13 @@ static int uclogic_params_ugee_v2_init(struct uclogic_params *params,
|
|||||||
goto output;
|
goto output;
|
||||||
}
|
}
|
||||||
|
|
||||||
desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] =
|
rc = uclogic_params_parse_ugee_v2_desc(str_desc, str_desc_len,
|
||||||
get_unaligned_le16(str_desc + 2);
|
desc_params,
|
||||||
desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] =
|
ARRAY_SIZE(desc_params),
|
||||||
get_unaligned_le16(str_desc + 4);
|
&frame_type);
|
||||||
desc_params[UCLOGIC_RDESC_FRAME_PH_ID_UM] = str_desc[6];
|
if (rc)
|
||||||
desc_params[UCLOGIC_RDESC_PEN_PH_ID_PRESSURE_LM] =
|
goto cleanup;
|
||||||
get_unaligned_le16(str_desc + 8);
|
|
||||||
resolution = get_unaligned_le16(str_desc + 10);
|
|
||||||
if (resolution == 0) {
|
|
||||||
desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] = 0;
|
|
||||||
desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] = 0;
|
|
||||||
} else {
|
|
||||||
desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_PM] =
|
|
||||||
desc_params[UCLOGIC_RDESC_PEN_PH_ID_X_LM] * 1000 /
|
|
||||||
resolution;
|
|
||||||
desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_PM] =
|
|
||||||
desc_params[UCLOGIC_RDESC_PEN_PH_ID_Y_LM] * 1000 /
|
|
||||||
resolution;
|
|
||||||
}
|
|
||||||
kfree(str_desc);
|
kfree(str_desc);
|
||||||
str_desc = NULL;
|
str_desc = NULL;
|
||||||
|
|
||||||
@ -1167,24 +1318,21 @@ static int uclogic_params_ugee_v2_init(struct uclogic_params *params,
|
|||||||
p.pen.subreport_list[0].id = UCLOGIC_RDESC_V1_FRAME_ID;
|
p.pen.subreport_list[0].id = UCLOGIC_RDESC_V1_FRAME_ID;
|
||||||
|
|
||||||
/* Initialize the frame interface */
|
/* Initialize the frame interface */
|
||||||
rdesc_frame = uclogic_rdesc_template_apply(
|
switch (frame_type) {
|
||||||
uclogic_rdesc_ugee_v2_frame_btn_template_arr,
|
case UCLOGIC_PARAMS_FRAME_DIAL:
|
||||||
uclogic_rdesc_ugee_v2_frame_btn_template_size,
|
case UCLOGIC_PARAMS_FRAME_MOUSE:
|
||||||
desc_params, ARRAY_SIZE(desc_params));
|
rc = uclogic_params_ugee_v2_init_frame_dial(&p, desc_params,
|
||||||
if (!rdesc_frame) {
|
ARRAY_SIZE(desc_params));
|
||||||
rc = -ENOMEM;
|
break;
|
||||||
goto cleanup;
|
case UCLOGIC_PARAMS_FRAME_BUTTONS:
|
||||||
|
default:
|
||||||
|
rc = uclogic_params_ugee_v2_init_frame_buttons(&p, desc_params,
|
||||||
|
ARRAY_SIZE(desc_params));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = uclogic_params_frame_init_with_desc(&p.frame_list[0],
|
if (rc)
|
||||||
rdesc_frame,
|
goto cleanup;
|
||||||
uclogic_rdesc_ugee_v2_frame_btn_template_size,
|
|
||||||
UCLOGIC_RDESC_V1_FRAME_ID);
|
|
||||||
kfree(rdesc_frame);
|
|
||||||
if (rc) {
|
|
||||||
uclogic_params_init_invalid(&p);
|
|
||||||
goto output;
|
|
||||||
}
|
|
||||||
|
|
||||||
output:
|
output:
|
||||||
/* Output parameters */
|
/* Output parameters */
|
||||||
@ -1432,8 +1580,12 @@ int uclogic_params_init(struct uclogic_params *params,
|
|||||||
uclogic_params_init_invalid(&p);
|
uclogic_params_init_invalid(&p);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case VID_PID(USB_VENDOR_ID_UGEE,
|
||||||
|
USB_DEVICE_ID_UGEE_PARBLO_A610_PRO):
|
||||||
case VID_PID(USB_VENDOR_ID_UGEE,
|
case VID_PID(USB_VENDOR_ID_UGEE,
|
||||||
USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L):
|
USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_L):
|
||||||
|
case VID_PID(USB_VENDOR_ID_UGEE,
|
||||||
|
USB_DEVICE_ID_UGEE_XPPEN_TABLET_DECO_PRO_S):
|
||||||
rc = uclogic_params_ugee_v2_init(&p, hdev);
|
rc = uclogic_params_ugee_v2_init(&p, hdev);
|
||||||
if (rc != 0)
|
if (rc != 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -1517,3 +1669,7 @@ cleanup:
|
|||||||
uclogic_params_cleanup(&p);
|
uclogic_params_cleanup(&p);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_HID_KUNIT_TEST
|
||||||
|
#include "hid-uclogic-params-test.c"
|
||||||
|
#endif
|
||||||
|
@ -29,6 +29,16 @@ enum uclogic_params_pen_inrange {
|
|||||||
UCLOGIC_PARAMS_PEN_INRANGE_NONE,
|
UCLOGIC_PARAMS_PEN_INRANGE_NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Types of frames */
|
||||||
|
enum uclogic_params_frame_type {
|
||||||
|
/* Frame with buttons */
|
||||||
|
UCLOGIC_PARAMS_FRAME_BUTTONS = 0,
|
||||||
|
/* Frame with buttons and a dial */
|
||||||
|
UCLOGIC_PARAMS_FRAME_DIAL,
|
||||||
|
/* Frame with buttons and a mouse (shaped as a dial + touchpad) */
|
||||||
|
UCLOGIC_PARAMS_FRAME_MOUSE,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pen report's subreport data.
|
* Pen report's subreport data.
|
||||||
*/
|
*/
|
||||||
|
@ -97,7 +97,7 @@ static const __u8 template_params_none[] = {
|
|||||||
|
|
||||||
static struct uclogic_template_case uclogic_template_cases[] = {
|
static struct uclogic_template_case uclogic_template_cases[] = {
|
||||||
{
|
{
|
||||||
.name = "Empty template",
|
.name = "empty_template",
|
||||||
.template = template_empty,
|
.template = template_empty,
|
||||||
.template_size = sizeof(template_empty),
|
.template_size = sizeof(template_empty),
|
||||||
.param_list = params_pen_all,
|
.param_list = params_pen_all,
|
||||||
@ -105,7 +105,7 @@ static struct uclogic_template_case uclogic_template_cases[] = {
|
|||||||
.expected = template_empty,
|
.expected = template_empty,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Template smaller than the placeholder",
|
.name = "template_smaller_than_the_placeholder",
|
||||||
.template = template_small,
|
.template = template_small,
|
||||||
.template_size = sizeof(template_small),
|
.template_size = sizeof(template_small),
|
||||||
.param_list = params_pen_all,
|
.param_list = params_pen_all,
|
||||||
@ -113,7 +113,7 @@ static struct uclogic_template_case uclogic_template_cases[] = {
|
|||||||
.expected = template_small,
|
.expected = template_small,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "No placeholder",
|
.name = "no_placeholder",
|
||||||
.template = template_no_ph,
|
.template = template_no_ph,
|
||||||
.template_size = sizeof(template_no_ph),
|
.template_size = sizeof(template_no_ph),
|
||||||
.param_list = params_pen_all,
|
.param_list = params_pen_all,
|
||||||
@ -121,7 +121,7 @@ static struct uclogic_template_case uclogic_template_cases[] = {
|
|||||||
.expected = template_no_ph,
|
.expected = template_no_ph,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Pen placeholder at the end, without ID",
|
.name = "pen_placeholder_at_the_end_without_id",
|
||||||
.template = template_pen_ph_end,
|
.template = template_pen_ph_end,
|
||||||
.template_size = sizeof(template_pen_ph_end),
|
.template_size = sizeof(template_pen_ph_end),
|
||||||
.param_list = params_pen_all,
|
.param_list = params_pen_all,
|
||||||
@ -129,7 +129,7 @@ static struct uclogic_template_case uclogic_template_cases[] = {
|
|||||||
.expected = template_pen_ph_end,
|
.expected = template_pen_ph_end,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Frame button placeholder at the end, without ID",
|
.name = "frame_button_placeholder_at_the_end_without_id",
|
||||||
.template = template_btn_ph_end,
|
.template = template_btn_ph_end,
|
||||||
.template_size = sizeof(template_btn_ph_end),
|
.template_size = sizeof(template_btn_ph_end),
|
||||||
.param_list = params_frame_all,
|
.param_list = params_frame_all,
|
||||||
@ -137,7 +137,7 @@ static struct uclogic_template_case uclogic_template_cases[] = {
|
|||||||
.expected = template_btn_ph_end,
|
.expected = template_btn_ph_end,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "All params present in the pen template",
|
.name = "all_params_present_in_the_pen_template",
|
||||||
.template = template_pen_all_params,
|
.template = template_pen_all_params,
|
||||||
.template_size = sizeof(template_pen_all_params),
|
.template_size = sizeof(template_pen_all_params),
|
||||||
.param_list = params_pen_all,
|
.param_list = params_pen_all,
|
||||||
@ -145,7 +145,7 @@ static struct uclogic_template_case uclogic_template_cases[] = {
|
|||||||
.expected = expected_pen_all_params,
|
.expected = expected_pen_all_params,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "All params present in the frame template",
|
.name = "all_params_present_in_the_frame_template",
|
||||||
.template = template_frame_all_params,
|
.template = template_frame_all_params,
|
||||||
.template_size = sizeof(template_frame_all_params),
|
.template_size = sizeof(template_frame_all_params),
|
||||||
.param_list = params_frame_all,
|
.param_list = params_frame_all,
|
||||||
@ -153,7 +153,7 @@ static struct uclogic_template_case uclogic_template_cases[] = {
|
|||||||
.expected = expected_frame_all_params,
|
.expected = expected_frame_all_params,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Some params present in the pen template (complete param list)",
|
.name = "some_params_present_in_the_pen_template_with_complete_param_list",
|
||||||
.template = template_pen_some_params,
|
.template = template_pen_some_params,
|
||||||
.template_size = sizeof(template_pen_some_params),
|
.template_size = sizeof(template_pen_some_params),
|
||||||
.param_list = params_pen_all,
|
.param_list = params_pen_all,
|
||||||
@ -161,7 +161,7 @@ static struct uclogic_template_case uclogic_template_cases[] = {
|
|||||||
.expected = expected_pen_some_params,
|
.expected = expected_pen_some_params,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "Some params present in the pen template (incomplete param list)",
|
.name = "some_params_present_in_the_pen_template_with_incomplete_param_list",
|
||||||
.template = template_pen_some_params,
|
.template = template_pen_some_params,
|
||||||
.template_size = sizeof(template_pen_some_params),
|
.template_size = sizeof(template_pen_some_params),
|
||||||
.param_list = params_pen_some,
|
.param_list = params_pen_some,
|
||||||
@ -169,7 +169,7 @@ static struct uclogic_template_case uclogic_template_cases[] = {
|
|||||||
.expected = expected_pen_some_params,
|
.expected = expected_pen_some_params,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "No params present in the template",
|
.name = "no_params_present_in_the_template",
|
||||||
.template = template_params_none,
|
.template = template_params_none,
|
||||||
.template_size = sizeof(template_params_none),
|
.template_size = sizeof(template_params_none),
|
||||||
.param_list = params_pen_some,
|
.param_list = params_pen_some,
|
||||||
@ -208,7 +208,7 @@ static struct kunit_case hid_uclogic_rdesc_test_cases[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct kunit_suite hid_uclogic_rdesc_test_suite = {
|
static struct kunit_suite hid_uclogic_rdesc_test_suite = {
|
||||||
.name = "hid-uclogic-rdesc-test",
|
.name = "hid_uclogic_rdesc_test",
|
||||||
.test_cases = hid_uclogic_rdesc_test_cases,
|
.test_cases = hid_uclogic_rdesc_test_cases,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -961,6 +961,80 @@ const __u8 uclogic_rdesc_ugee_v2_frame_btn_template_arr[] = {
|
|||||||
const size_t uclogic_rdesc_ugee_v2_frame_btn_template_size =
|
const size_t uclogic_rdesc_ugee_v2_frame_btn_template_size =
|
||||||
sizeof(uclogic_rdesc_ugee_v2_frame_btn_template_arr);
|
sizeof(uclogic_rdesc_ugee_v2_frame_btn_template_arr);
|
||||||
|
|
||||||
|
/* Fixed report descriptor template for UGEE v2 frame reports (dial) */
|
||||||
|
const __u8 uclogic_rdesc_ugee_v2_frame_dial_template_arr[] = {
|
||||||
|
0x05, 0x01, /* Usage Page (Desktop), */
|
||||||
|
0x09, 0x07, /* Usage (Keypad), */
|
||||||
|
0xA1, 0x01, /* Collection (Application), */
|
||||||
|
0x85, UCLOGIC_RDESC_V1_FRAME_ID,
|
||||||
|
/* Report ID, */
|
||||||
|
0x05, 0x0D, /* Usage Page (Digitizer), */
|
||||||
|
0x09, 0x39, /* Usage (Tablet Function Keys), */
|
||||||
|
0xA0, /* Collection (Physical), */
|
||||||
|
0x75, 0x01, /* Report Size (1), */
|
||||||
|
0x95, 0x08, /* Report Count (8), */
|
||||||
|
0x81, 0x01, /* Input (Constant), */
|
||||||
|
0x05, 0x09, /* Usage Page (Button), */
|
||||||
|
0x19, 0x01, /* Usage Minimum (01h), */
|
||||||
|
UCLOGIC_RDESC_FRAME_PH_BTN,
|
||||||
|
/* Usage Maximum (PLACEHOLDER), */
|
||||||
|
0x95, 0x0A, /* Report Count (10), */
|
||||||
|
0x14, /* Logical Minimum (0), */
|
||||||
|
0x25, 0x01, /* Logical Maximum (1), */
|
||||||
|
0x81, 0x02, /* Input (Variable), */
|
||||||
|
0x95, 0x06, /* Report Count (6), */
|
||||||
|
0x81, 0x01, /* Input (Constant), */
|
||||||
|
0x75, 0x08, /* Report Size (8), */
|
||||||
|
0x95, 0x03, /* Report Count (3), */
|
||||||
|
0x81, 0x01, /* Input (Constant), */
|
||||||
|
0x05, 0x01, /* Usage Page (Desktop), */
|
||||||
|
0x09, 0x38, /* Usage (Wheel), */
|
||||||
|
0x95, 0x01, /* Report Count (1), */
|
||||||
|
0x15, 0xFF, /* Logical Minimum (-1), */
|
||||||
|
0x25, 0x01, /* Logical Maximum (1), */
|
||||||
|
0x81, 0x06, /* Input (Variable, Relative), */
|
||||||
|
0x95, 0x02, /* Report Count (2), */
|
||||||
|
0x81, 0x01, /* Input (Constant), */
|
||||||
|
0xC0, /* End Collection, */
|
||||||
|
0xC0 /* End Collection */
|
||||||
|
};
|
||||||
|
const size_t uclogic_rdesc_ugee_v2_frame_dial_template_size =
|
||||||
|
sizeof(uclogic_rdesc_ugee_v2_frame_dial_template_arr);
|
||||||
|
|
||||||
|
/* Fixed report descriptor template for UGEE v2 frame reports (mouse) */
|
||||||
|
const __u8 uclogic_rdesc_ugee_v2_frame_mouse_template_arr[] = {
|
||||||
|
0x05, 0x01, /* Usage Page (Desktop), */
|
||||||
|
0x09, 0x02, /* Usage (Mouse), */
|
||||||
|
0xA1, 0x01, /* Collection (Application), */
|
||||||
|
0x85, 0x01, /* Report ID (1), */
|
||||||
|
0x05, 0x01, /* Usage Page (Pointer), */
|
||||||
|
0xA0, /* Collection (Physical), */
|
||||||
|
0x75, 0x01, /* Report Size (1), */
|
||||||
|
0x95, 0x02, /* Report Count (2), */
|
||||||
|
0x05, 0x09, /* Usage Page (Button), */
|
||||||
|
0x19, 0x01, /* Usage Minimum (01h), */
|
||||||
|
0x29, 0x02, /* Usage Maximum (02h), */
|
||||||
|
0x14, /* Logical Minimum (0), */
|
||||||
|
0x25, 0x01, /* Logical Maximum (1), */
|
||||||
|
0x81, 0x02, /* Input (Variable), */
|
||||||
|
0x95, 0x06, /* Report Count (6), */
|
||||||
|
0x81, 0x01, /* Input (Constant), */
|
||||||
|
0x05, 0x01, /* Usage Page (Generic Desktop), */
|
||||||
|
0x09, 0x30, /* Usage (X), */
|
||||||
|
0x09, 0x31, /* Usage (Y), */
|
||||||
|
0x75, 0x10, /* Report Size (16), */
|
||||||
|
0x95, 0x02, /* Report Count (2), */
|
||||||
|
0x16, 0x00, 0x80, /* Logical Minimum (-32768), */
|
||||||
|
0x26, 0xFF, 0x7F, /* Logical Maximum (32767), */
|
||||||
|
0x81, 0x06, /* Input (Variable, Relative), */
|
||||||
|
0x95, 0x01, /* Report Count (1), */
|
||||||
|
0x81, 0x01, /* Input (Constant), */
|
||||||
|
0xC0, /* End Collection, */
|
||||||
|
0xC0 /* End Collection */
|
||||||
|
};
|
||||||
|
const size_t uclogic_rdesc_ugee_v2_frame_mouse_template_size =
|
||||||
|
sizeof(uclogic_rdesc_ugee_v2_frame_mouse_template_arr);
|
||||||
|
|
||||||
/* Fixed report descriptor for Ugee EX07 frame */
|
/* Fixed report descriptor for Ugee EX07 frame */
|
||||||
const __u8 uclogic_rdesc_ugee_ex07_frame_arr[] = {
|
const __u8 uclogic_rdesc_ugee_ex07_frame_arr[] = {
|
||||||
0x05, 0x01, /* Usage Page (Desktop), */
|
0x05, 0x01, /* Usage Page (Desktop), */
|
||||||
@ -1113,7 +1187,7 @@ __u8 *uclogic_rdesc_template_apply(const __u8 *template_ptr,
|
|||||||
memcmp(p, pen_head, sizeof(pen_head)) == 0 &&
|
memcmp(p, pen_head, sizeof(pen_head)) == 0 &&
|
||||||
p[sizeof(pen_head)] < param_num) {
|
p[sizeof(pen_head)] < param_num) {
|
||||||
v = param_list[p[sizeof(pen_head)]];
|
v = param_list[p[sizeof(pen_head)]];
|
||||||
put_unaligned(cpu_to_le32(v), (s32 *)p);
|
put_unaligned((__force u32)cpu_to_le32(v), (s32 *)p);
|
||||||
p += sizeof(pen_head) + 1;
|
p += sizeof(pen_head) + 1;
|
||||||
} else if (memcmp(p, btn_head, sizeof(btn_head)) == 0 &&
|
} else if (memcmp(p, btn_head, sizeof(btn_head)) == 0 &&
|
||||||
p[sizeof(btn_head)] < param_num) {
|
p[sizeof(btn_head)] < param_num) {
|
||||||
|
@ -169,6 +169,14 @@ extern const size_t uclogic_rdesc_ugee_v2_pen_template_size;
|
|||||||
extern const __u8 uclogic_rdesc_ugee_v2_frame_btn_template_arr[];
|
extern const __u8 uclogic_rdesc_ugee_v2_frame_btn_template_arr[];
|
||||||
extern const size_t uclogic_rdesc_ugee_v2_frame_btn_template_size;
|
extern const size_t uclogic_rdesc_ugee_v2_frame_btn_template_size;
|
||||||
|
|
||||||
|
/* Fixed report descriptor template for UGEE v2 frame reports (dial) */
|
||||||
|
extern const __u8 uclogic_rdesc_ugee_v2_frame_dial_template_arr[];
|
||||||
|
extern const size_t uclogic_rdesc_ugee_v2_frame_dial_template_size;
|
||||||
|
|
||||||
|
/* Fixed report descriptor template for UGEE v2 frame reports (mouse) */
|
||||||
|
extern const __u8 uclogic_rdesc_ugee_v2_frame_mouse_template_arr[];
|
||||||
|
extern const size_t uclogic_rdesc_ugee_v2_frame_mouse_template_size;
|
||||||
|
|
||||||
/* Fixed report descriptor for Ugee EX07 frame */
|
/* Fixed report descriptor for Ugee EX07 frame */
|
||||||
extern const __u8 uclogic_rdesc_ugee_ex07_frame_arr[];
|
extern const __u8 uclogic_rdesc_ugee_ex07_frame_arr[];
|
||||||
extern const size_t uclogic_rdesc_ugee_ex07_frame_size;
|
extern const size_t uclogic_rdesc_ugee_ex07_frame_size;
|
||||||
|
@ -116,25 +116,26 @@ static struct attribute *vivaldi_sysfs_attrs[] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct attribute_group vivaldi_attribute_group = {
|
static umode_t vivaldi_is_visible(struct kobject *kobj, struct attribute *attr,
|
||||||
.attrs = vivaldi_sysfs_attrs,
|
int n)
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* vivaldi_input_configured - Complete initialization of device using vivaldi map
|
|
||||||
* @hdev: HID device to which vivaldi attributes should be attached
|
|
||||||
* @hidinput: HID input device (unused)
|
|
||||||
*/
|
|
||||||
int vivaldi_input_configured(struct hid_device *hdev,
|
|
||||||
struct hid_input *hidinput)
|
|
||||||
{
|
{
|
||||||
|
struct hid_device *hdev = to_hid_device(kobj_to_dev(kobj));
|
||||||
struct vivaldi_data *data = hid_get_drvdata(hdev);
|
struct vivaldi_data *data = hid_get_drvdata(hdev);
|
||||||
|
|
||||||
if (!data->num_function_row_keys)
|
if (!data->num_function_row_keys)
|
||||||
return 0;
|
return 0;
|
||||||
|
return attr->mode;
|
||||||
return devm_device_add_group(&hdev->dev, &vivaldi_attribute_group);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(vivaldi_input_configured);
|
|
||||||
|
static const struct attribute_group vivaldi_attribute_group = {
|
||||||
|
.attrs = vivaldi_sysfs_attrs,
|
||||||
|
.is_visible = vivaldi_is_visible,
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct attribute_group *vivaldi_attribute_groups[] = {
|
||||||
|
&vivaldi_attribute_group,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
EXPORT_SYMBOL_GPL(vivaldi_attribute_groups);
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
@ -4,13 +4,11 @@
|
|||||||
|
|
||||||
struct hid_device;
|
struct hid_device;
|
||||||
struct hid_field;
|
struct hid_field;
|
||||||
struct hid_input;
|
|
||||||
struct hid_usage;
|
struct hid_usage;
|
||||||
|
|
||||||
void vivaldi_feature_mapping(struct hid_device *hdev,
|
void vivaldi_feature_mapping(struct hid_device *hdev,
|
||||||
struct hid_field *field, struct hid_usage *usage);
|
struct hid_field *field, struct hid_usage *usage);
|
||||||
|
|
||||||
int vivaldi_input_configured(struct hid_device *hdev,
|
extern const struct attribute_group *vivaldi_attribute_groups[];
|
||||||
struct hid_input *hidinput);
|
|
||||||
|
|
||||||
#endif /* _HID_VIVALDI_COMMON_H */
|
#endif /* _HID_VIVALDI_COMMON_H */
|
||||||
|
@ -45,7 +45,9 @@ static struct hid_driver hid_vivaldi = {
|
|||||||
.id_table = vivaldi_table,
|
.id_table = vivaldi_table,
|
||||||
.probe = vivaldi_probe,
|
.probe = vivaldi_probe,
|
||||||
.feature_mapping = vivaldi_feature_mapping,
|
.feature_mapping = vivaldi_feature_mapping,
|
||||||
.input_configured = vivaldi_input_configured,
|
.driver = {
|
||||||
|
.dev_groups = vivaldi_attribute_groups,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
module_hid_driver(hid_vivaldi);
|
module_hid_driver(hid_vivaldi);
|
||||||
|
91
drivers/hid/hid-vrc2.c
Normal file
91
drivers/hid/hid-vrc2.c
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
/*
|
||||||
|
* HID driver for VRC-2 2-axis Car controller
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Marcus Folkesson <marcus.folkesson@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/device.h>
|
||||||
|
#include <linux/hid.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VID/PID are probably "borrowed", so keep them locally and
|
||||||
|
* do not populate hid-ids.h with those.
|
||||||
|
*/
|
||||||
|
#define USB_VENDOR_ID_VRC2 (0x07c0)
|
||||||
|
#define USB_DEVICE_ID_VRC2 (0x1125)
|
||||||
|
|
||||||
|
static __u8 vrc2_rdesc_fixed[] = {
|
||||||
|
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
|
||||||
|
0x09, 0x04, // Usage (Joystick)
|
||||||
|
0xA1, 0x01, // Collection (Application)
|
||||||
|
0x09, 0x01, // Usage (Pointer)
|
||||||
|
0xA1, 0x00, // Collection (Physical)
|
||||||
|
0x09, 0x30, // Usage (X)
|
||||||
|
0x09, 0x31, // Usage (Y)
|
||||||
|
0x15, 0x00, // Logical Minimum (0)
|
||||||
|
0x26, 0xFF, 0x07, // Logical Maximum (2047)
|
||||||
|
0x35, 0x00, // Physical Minimum (0)
|
||||||
|
0x46, 0xFF, 0x00, // Physical Maximum (255)
|
||||||
|
0x75, 0x10, // Report Size (16)
|
||||||
|
0x95, 0x02, // Report Count (2)
|
||||||
|
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
|
||||||
|
0xC0, // End Collection
|
||||||
|
0x75, 0x08, // Report Size (8)
|
||||||
|
0x95, 0x03, // Report Count (3)
|
||||||
|
0x81, 0x03, // Input (Cnst,Var,Abs)
|
||||||
|
0xC0, // End Collection
|
||||||
|
};
|
||||||
|
|
||||||
|
static __u8 *vrc2_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||||
|
unsigned int *rsize)
|
||||||
|
{
|
||||||
|
hid_info(hdev, "fixing up VRC-2 report descriptor\n");
|
||||||
|
*rsize = sizeof(vrc2_rdesc_fixed);
|
||||||
|
return vrc2_rdesc_fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int vrc2_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The device gives us 2 separate USB endpoints.
|
||||||
|
* One of those (the one with report descriptor size of 23) is just bogus so ignore it
|
||||||
|
*/
|
||||||
|
if (hdev->dev_rsize == 23)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
ret = hid_parse(hdev);
|
||||||
|
if (ret) {
|
||||||
|
hid_err(hdev, "parse failed\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
|
||||||
|
if (ret) {
|
||||||
|
hid_err(hdev, "hw start failed\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct hid_device_id vrc2_devices[] = {
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_VRC2, USB_DEVICE_ID_VRC2) },
|
||||||
|
{ /* sentinel */ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(hid, vrc2_devices);
|
||||||
|
|
||||||
|
static struct hid_driver vrc2_driver = {
|
||||||
|
.name = "vrc2",
|
||||||
|
.id_table = vrc2_devices,
|
||||||
|
.report_fixup = vrc2_report_fixup,
|
||||||
|
.probe = vrc2_probe,
|
||||||
|
};
|
||||||
|
module_hid_driver(vrc2_driver);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Marcus Folkesson <marcus.folkesson@gmail.com>");
|
||||||
|
MODULE_DESCRIPTION("HID driver for VRC-2 2-axis Car controller");
|
||||||
|
MODULE_LICENSE("GPL");
|
@ -1036,7 +1036,7 @@ int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops,
|
|||||||
|
|
||||||
snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X",
|
snprintf(hid->name, sizeof(hid->name), "%s %04X:%04X",
|
||||||
client->name, (u16)hid->vendor, (u16)hid->product);
|
client->name, (u16)hid->vendor, (u16)hid->product);
|
||||||
strlcpy(hid->phys, dev_name(&client->dev), sizeof(hid->phys));
|
strscpy(hid->phys, dev_name(&client->dev), sizeof(hid->phys));
|
||||||
|
|
||||||
ihid->quirks = i2c_hid_lookup_quirk(hid->vendor, hid->product);
|
ihid->quirks = i2c_hid_lookup_quirk(hid->vendor, hid->product);
|
||||||
|
|
||||||
|
@ -1381,7 +1381,7 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
|
|||||||
hid->type = HID_TYPE_USBNONE;
|
hid->type = HID_TYPE_USBNONE;
|
||||||
|
|
||||||
if (dev->manufacturer)
|
if (dev->manufacturer)
|
||||||
strlcpy(hid->name, dev->manufacturer, sizeof(hid->name));
|
strscpy(hid->name, dev->manufacturer, sizeof(hid->name));
|
||||||
|
|
||||||
if (dev->product) {
|
if (dev->product) {
|
||||||
if (dev->manufacturer)
|
if (dev->manufacturer)
|
||||||
|
@ -294,7 +294,7 @@ static int usb_kbd_probe(struct usb_interface *iface,
|
|||||||
spin_lock_init(&kbd->leds_lock);
|
spin_lock_init(&kbd->leds_lock);
|
||||||
|
|
||||||
if (dev->manufacturer)
|
if (dev->manufacturer)
|
||||||
strlcpy(kbd->name, dev->manufacturer, sizeof(kbd->name));
|
strscpy(kbd->name, dev->manufacturer, sizeof(kbd->name));
|
||||||
|
|
||||||
if (dev->product) {
|
if (dev->product) {
|
||||||
if (dev->manufacturer)
|
if (dev->manufacturer)
|
||||||
|
@ -142,7 +142,7 @@ static int usb_mouse_probe(struct usb_interface *intf, const struct usb_device_i
|
|||||||
mouse->dev = input_dev;
|
mouse->dev = input_dev;
|
||||||
|
|
||||||
if (dev->manufacturer)
|
if (dev->manufacturer)
|
||||||
strlcpy(mouse->name, dev->manufacturer, sizeof(mouse->name));
|
strscpy(mouse->name, dev->manufacturer, sizeof(mouse->name));
|
||||||
|
|
||||||
if (dev->product) {
|
if (dev->product) {
|
||||||
if (dev->manufacturer)
|
if (dev->manufacturer)
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
/*
|
/*
|
||||||
* drivers/input/tablet/wacom.h
|
|
||||||
*
|
|
||||||
* USB Wacom tablet support
|
* USB Wacom tablet support
|
||||||
*
|
*
|
||||||
* Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz>
|
* Copyright (c) 2000-2004 Vojtech Pavlik <vojtech@ucw.cz>
|
||||||
@ -78,10 +76,9 @@
|
|||||||
* - integration of the Bluetooth devices
|
* - integration of the Bluetooth devices
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
*/
|
|
||||||
#ifndef WACOM_H
|
#ifndef WACOM_H
|
||||||
#define WACOM_H
|
#define WACOM_H
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/*
|
/*
|
||||||
* drivers/input/tablet/wacom_sys.c
|
|
||||||
*
|
|
||||||
* USB Wacom tablet support - system specific code
|
* USB Wacom tablet support - system specific code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "wacom_wac.h"
|
#include "wacom_wac.h"
|
||||||
#include "wacom.h"
|
#include "wacom.h"
|
||||||
#include <linux/input/mt.h>
|
#include <linux/input/mt.h>
|
||||||
@ -2226,7 +2221,7 @@ static void wacom_update_name(struct wacom *wacom, const char *suffix)
|
|||||||
} else if (strstr(product_name, "Wacom") ||
|
} else if (strstr(product_name, "Wacom") ||
|
||||||
strstr(product_name, "wacom") ||
|
strstr(product_name, "wacom") ||
|
||||||
strstr(product_name, "WACOM")) {
|
strstr(product_name, "WACOM")) {
|
||||||
strlcpy(name, product_name, sizeof(name));
|
strscpy(name, product_name, sizeof(name));
|
||||||
} else {
|
} else {
|
||||||
snprintf(name, sizeof(name), "Wacom %s", product_name);
|
snprintf(name, sizeof(name), "Wacom %s", product_name);
|
||||||
}
|
}
|
||||||
@ -2244,7 +2239,7 @@ static void wacom_update_name(struct wacom *wacom, const char *suffix)
|
|||||||
if (name[strlen(name)-1] == ' ')
|
if (name[strlen(name)-1] == ' ')
|
||||||
name[strlen(name)-1] = '\0';
|
name[strlen(name)-1] = '\0';
|
||||||
} else {
|
} else {
|
||||||
strlcpy(name, features->name, sizeof(name));
|
strscpy(name, features->name, sizeof(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(wacom_wac->name, sizeof(wacom_wac->name), "%s%s",
|
snprintf(wacom_wac->name, sizeof(wacom_wac->name), "%s%s",
|
||||||
@ -2509,7 +2504,7 @@ static void wacom_wireless_work(struct work_struct *work)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
strlcpy(wacom_wac->name, wacom_wac1->name,
|
strscpy(wacom_wac->name, wacom_wac1->name,
|
||||||
sizeof(wacom_wac->name));
|
sizeof(wacom_wac->name));
|
||||||
error = wacom_initialize_battery(wacom);
|
error = wacom_initialize_battery(wacom);
|
||||||
if (error)
|
if (error)
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
/*
|
/*
|
||||||
* drivers/input/tablet/wacom_wac.c
|
|
||||||
*
|
|
||||||
* USB Wacom tablet support - Wacom specific code
|
* USB Wacom tablet support - Wacom specific code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "wacom_wac.h"
|
#include "wacom_wac.h"
|
||||||
#include "wacom.h"
|
#include "wacom.h"
|
||||||
#include <linux/input/mt.h>
|
#include <linux/input/mt.h>
|
||||||
@ -713,11 +708,14 @@ static int wacom_intuos_get_tool_type(int tool_id)
|
|||||||
case 0x802: /* Intuos4/5 13HD/24HD General Pen */
|
case 0x802: /* Intuos4/5 13HD/24HD General Pen */
|
||||||
case 0x8e2: /* IntuosHT2 pen */
|
case 0x8e2: /* IntuosHT2 pen */
|
||||||
case 0x022:
|
case 0x022:
|
||||||
|
case 0x200: /* Pro Pen 3 */
|
||||||
|
case 0x04200: /* Pro Pen 3 */
|
||||||
case 0x10842: /* MobileStudio Pro Pro Pen slim */
|
case 0x10842: /* MobileStudio Pro Pro Pen slim */
|
||||||
case 0x14802: /* Intuos4/5 13HD/24HD Classic Pen */
|
case 0x14802: /* Intuos4/5 13HD/24HD Classic Pen */
|
||||||
case 0x16802: /* Cintiq 13HD Pro Pen */
|
case 0x16802: /* Cintiq 13HD Pro Pen */
|
||||||
case 0x18802: /* DTH2242 Pen */
|
case 0x18802: /* DTH2242 Pen */
|
||||||
case 0x10802: /* Intuos4/5 13HD/24HD General Pen */
|
case 0x10802: /* Intuos4/5 13HD/24HD General Pen */
|
||||||
|
case 0x80842: /* Intuos Pro and Cintiq Pro 3D Pen */
|
||||||
tool_type = BTN_TOOL_PEN;
|
tool_type = BTN_TOOL_PEN;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -4875,6 +4873,10 @@ static const struct wacom_features wacom_features_0x3c6 =
|
|||||||
static const struct wacom_features wacom_features_0x3c8 =
|
static const struct wacom_features wacom_features_0x3c8 =
|
||||||
{ "Wacom Intuos BT M", 21600, 13500, 4095, 63,
|
{ "Wacom Intuos BT M", 21600, 13500, 4095, 63,
|
||||||
INTUOSHT3_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 };
|
INTUOSHT3_BT, WACOM_INTUOS_RES, WACOM_INTUOS_RES, 4 };
|
||||||
|
static const struct wacom_features wacom_features_0x3dd =
|
||||||
|
{ "Wacom Intuos Pro S", 31920, 19950, 8191, 63,
|
||||||
|
INTUOSP2S_BT, WACOM_INTUOS3_RES, WACOM_INTUOS3_RES, 7,
|
||||||
|
.touch_max = 10 };
|
||||||
|
|
||||||
static const struct wacom_features wacom_features_HID_ANY_ID =
|
static const struct wacom_features wacom_features_HID_ANY_ID =
|
||||||
{ "Wacom HID", .type = HID_GENERIC, .oVid = HID_ANY_ID, .oPid = HID_ANY_ID };
|
{ "Wacom HID", .type = HID_GENERIC, .oVid = HID_ANY_ID, .oPid = HID_ANY_ID };
|
||||||
@ -5050,6 +5052,7 @@ const struct hid_device_id wacom_ids[] = {
|
|||||||
{ BT_DEVICE_WACOM(0x393) },
|
{ BT_DEVICE_WACOM(0x393) },
|
||||||
{ BT_DEVICE_WACOM(0x3c6) },
|
{ BT_DEVICE_WACOM(0x3c6) },
|
||||||
{ BT_DEVICE_WACOM(0x3c8) },
|
{ BT_DEVICE_WACOM(0x3c8) },
|
||||||
|
{ BT_DEVICE_WACOM(0x3dd) },
|
||||||
{ USB_DEVICE_WACOM(0x4001) },
|
{ USB_DEVICE_WACOM(0x4001) },
|
||||||
{ USB_DEVICE_WACOM(0x4004) },
|
{ USB_DEVICE_WACOM(0x4004) },
|
||||||
{ USB_DEVICE_WACOM(0x5000) },
|
{ USB_DEVICE_WACOM(0x5000) },
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
/*
|
|
||||||
* drivers/input/tablet/wacom_wac.h
|
|
||||||
*/
|
|
||||||
#ifndef WACOM_WAC_H
|
#ifndef WACOM_WAC_H
|
||||||
#define WACOM_WAC_H
|
#define WACOM_WAC_H
|
||||||
|
|
||||||
|
@ -314,15 +314,6 @@ struct hid_item {
|
|||||||
#define HID_BAT_ABSOLUTESTATEOFCHARGE 0x00850065
|
#define HID_BAT_ABSOLUTESTATEOFCHARGE 0x00850065
|
||||||
|
|
||||||
#define HID_VD_ASUS_CUSTOM_MEDIA_KEYS 0xff310076
|
#define HID_VD_ASUS_CUSTOM_MEDIA_KEYS 0xff310076
|
||||||
/*
|
|
||||||
* HID report types --- Ouch! HID spec says 1 2 3!
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define HID_INPUT_REPORT 0
|
|
||||||
#define HID_OUTPUT_REPORT 1
|
|
||||||
#define HID_FEATURE_REPORT 2
|
|
||||||
|
|
||||||
#define HID_REPORT_TYPES 3
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HID connect requests
|
* HID connect requests
|
||||||
@ -509,7 +500,7 @@ struct hid_report {
|
|||||||
struct list_head hidinput_list;
|
struct list_head hidinput_list;
|
||||||
struct list_head field_entry_list; /* ordered list of input fields */
|
struct list_head field_entry_list; /* ordered list of input fields */
|
||||||
unsigned int id; /* id of this report */
|
unsigned int id; /* id of this report */
|
||||||
unsigned int type; /* report type */
|
enum hid_report_type type; /* report type */
|
||||||
unsigned int application; /* application usage for this report */
|
unsigned int application; /* application usage for this report */
|
||||||
struct hid_field *field[HID_MAX_FIELDS]; /* fields of the report */
|
struct hid_field *field[HID_MAX_FIELDS]; /* fields of the report */
|
||||||
struct hid_field_entry *field_entries; /* allocated memory of input field_entry */
|
struct hid_field_entry *field_entries; /* allocated memory of input field_entry */
|
||||||
@ -658,6 +649,8 @@ struct hid_device { /* device report descriptor */
|
|||||||
struct list_head debug_list;
|
struct list_head debug_list;
|
||||||
spinlock_t debug_list_lock;
|
spinlock_t debug_list_lock;
|
||||||
wait_queue_head_t debug_wait;
|
wait_queue_head_t debug_wait;
|
||||||
|
|
||||||
|
unsigned int id; /* system unique id */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define to_hid_device(pdev) \
|
#define to_hid_device(pdev) \
|
||||||
@ -924,20 +917,21 @@ extern int hidinput_connect(struct hid_device *hid, unsigned int force);
|
|||||||
extern void hidinput_disconnect(struct hid_device *);
|
extern void hidinput_disconnect(struct hid_device *);
|
||||||
|
|
||||||
int hid_set_field(struct hid_field *, unsigned, __s32);
|
int hid_set_field(struct hid_field *, unsigned, __s32);
|
||||||
int hid_input_report(struct hid_device *, int type, u8 *, u32, int);
|
int hid_input_report(struct hid_device *hid, enum hid_report_type type, u8 *data, u32 size,
|
||||||
|
int interrupt);
|
||||||
struct hid_field *hidinput_get_led_field(struct hid_device *hid);
|
struct hid_field *hidinput_get_led_field(struct hid_device *hid);
|
||||||
unsigned int hidinput_count_leds(struct hid_device *hid);
|
unsigned int hidinput_count_leds(struct hid_device *hid);
|
||||||
__s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code);
|
__s32 hidinput_calc_abs_res(const struct hid_field *field, __u16 code);
|
||||||
void hid_output_report(struct hid_report *report, __u8 *data);
|
void hid_output_report(struct hid_report *report, __u8 *data);
|
||||||
int __hid_request(struct hid_device *hid, struct hid_report *rep, int reqtype);
|
int __hid_request(struct hid_device *hid, struct hid_report *rep, enum hid_class_request reqtype);
|
||||||
u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags);
|
u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags);
|
||||||
struct hid_device *hid_allocate_device(void);
|
struct hid_device *hid_allocate_device(void);
|
||||||
struct hid_report *hid_register_report(struct hid_device *device,
|
struct hid_report *hid_register_report(struct hid_device *device,
|
||||||
unsigned int type, unsigned int id,
|
enum hid_report_type type, unsigned int id,
|
||||||
unsigned int application);
|
unsigned int application);
|
||||||
int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
|
int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size);
|
||||||
struct hid_report *hid_validate_values(struct hid_device *hid,
|
struct hid_report *hid_validate_values(struct hid_device *hid,
|
||||||
unsigned int type, unsigned int id,
|
enum hid_report_type type, unsigned int id,
|
||||||
unsigned int field_index,
|
unsigned int field_index,
|
||||||
unsigned int report_counts);
|
unsigned int report_counts);
|
||||||
|
|
||||||
@ -1106,10 +1100,11 @@ void hid_hw_stop(struct hid_device *hdev);
|
|||||||
int __must_check hid_hw_open(struct hid_device *hdev);
|
int __must_check hid_hw_open(struct hid_device *hdev);
|
||||||
void hid_hw_close(struct hid_device *hdev);
|
void hid_hw_close(struct hid_device *hdev);
|
||||||
void hid_hw_request(struct hid_device *hdev,
|
void hid_hw_request(struct hid_device *hdev,
|
||||||
struct hid_report *report, int reqtype);
|
struct hid_report *report, enum hid_class_request reqtype);
|
||||||
int hid_hw_raw_request(struct hid_device *hdev,
|
int hid_hw_raw_request(struct hid_device *hdev,
|
||||||
unsigned char reportnum, __u8 *buf,
|
unsigned char reportnum, __u8 *buf,
|
||||||
size_t len, unsigned char rtype, int reqtype);
|
size_t len, enum hid_report_type rtype,
|
||||||
|
enum hid_class_request reqtype);
|
||||||
int hid_hw_output_report(struct hid_device *hdev, __u8 *buf, size_t len);
|
int hid_hw_output_report(struct hid_device *hdev, __u8 *buf, size_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1137,7 +1132,7 @@ static inline int hid_hw_power(struct hid_device *hdev, int level)
|
|||||||
* @reqtype: hid request type
|
* @reqtype: hid request type
|
||||||
*/
|
*/
|
||||||
static inline int hid_hw_idle(struct hid_device *hdev, int report, int idle,
|
static inline int hid_hw_idle(struct hid_device *hdev, int report, int idle,
|
||||||
int reqtype)
|
enum hid_class_request reqtype)
|
||||||
{
|
{
|
||||||
if (hdev->ll_driver->idle)
|
if (hdev->ll_driver->idle)
|
||||||
return hdev->ll_driver->idle(hdev, report, idle, reqtype);
|
return hdev->ll_driver->idle(hdev, report, idle, reqtype);
|
||||||
@ -1182,8 +1177,8 @@ static inline u32 hid_report_len(struct hid_report *report)
|
|||||||
return DIV_ROUND_UP(report->size, 8) + (report->id > 0);
|
return DIV_ROUND_UP(report->size, 8) + (report->id > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int hid_report_raw_event(struct hid_device *hid, int type, u8 *data, u32 size,
|
int hid_report_raw_event(struct hid_device *hid, enum hid_report_type type, u8 *data, u32 size,
|
||||||
int interrupt);
|
int interrupt);
|
||||||
|
|
||||||
/* HID quirks API */
|
/* HID quirks API */
|
||||||
unsigned long hid_lookup_quirk(const struct hid_device *hdev);
|
unsigned long hid_lookup_quirk(const struct hid_device *hdev);
|
||||||
|
@ -42,16 +42,30 @@
|
|||||||
#define USB_INTERFACE_PROTOCOL_KEYBOARD 1
|
#define USB_INTERFACE_PROTOCOL_KEYBOARD 1
|
||||||
#define USB_INTERFACE_PROTOCOL_MOUSE 2
|
#define USB_INTERFACE_PROTOCOL_MOUSE 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* HID report types --- Ouch! HID spec says 1 2 3!
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum hid_report_type {
|
||||||
|
HID_INPUT_REPORT = 0,
|
||||||
|
HID_OUTPUT_REPORT = 1,
|
||||||
|
HID_FEATURE_REPORT = 2,
|
||||||
|
|
||||||
|
HID_REPORT_TYPES,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HID class requests
|
* HID class requests
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define HID_REQ_GET_REPORT 0x01
|
enum hid_class_request {
|
||||||
#define HID_REQ_GET_IDLE 0x02
|
HID_REQ_GET_REPORT = 0x01,
|
||||||
#define HID_REQ_GET_PROTOCOL 0x03
|
HID_REQ_GET_IDLE = 0x02,
|
||||||
#define HID_REQ_SET_REPORT 0x09
|
HID_REQ_GET_PROTOCOL = 0x03,
|
||||||
#define HID_REQ_SET_IDLE 0x0A
|
HID_REQ_SET_REPORT = 0x09,
|
||||||
#define HID_REQ_SET_PROTOCOL 0x0B
|
HID_REQ_SET_IDLE = 0x0A,
|
||||||
|
HID_REQ_SET_PROTOCOL = 0x0B,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HID class descriptor types
|
* HID class descriptor types
|
||||||
|
Loading…
x
Reference in New Issue
Block a user