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

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull HID updates from Jiri Kosina:
"Core:
- fixed handling of 0-sized reports (Dmitry Torokhov)
- convert core code to __free() (Dmitry Torokhov)
- support for multiple batteries per HID device (Lucas Zampieri)

Drivers:
- support for rumble effects in winwing driver (Ivan Gorinov)
- new support for a variety of Sony Rock Band and Sony DJ Hero
Turntable devices (Rosalie Wanders)
- new driver for Lenovo Legion Go / S devices (Derek J. Clark)
- power management improvements to intel-thc-hid driver (Even Xu)

... other assorted cleanups, fixes and device-specific quirks"

* tag 'hid-for-linus-2026041601' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (73 commits)
HID: core: clamp report_size in s32ton() to avoid undefined shift
HID: logitech-dj: fix wrong detection of bad DJ_SHORT output report
HID: logitech-hidpp: fix race condition when accessing stale stack pointer
HID: winwing: Enable rumble effects
HID: core: do not allow parsing 0-sized reports
HID: usbhid: refactor endpoint lookup
HID: huawei: fix CD30 keyboard report descriptor issue
HID: playstation: validate num_touch_reports in DualShock 4 reports
HID: drop 'default !EXPERT' from tristate symbols
HID: usbhid: fix deadlock in hid_post_reset()
HID: apple: ensure the keyboard backlight is off if suspending
HID: quirks: Set ALWAYS_POLL for LOGITECH_BOLT_RECEIVER
HID: alps: fix NULL pointer dereference in alps_raw_event()
HID: logitech-dj: Prevent REPORT_ID_DJ_SHORT related user initiated OOB write
HID: logitech-dj: Standardise hid_report_enum variable nomenclature
HID: sony: update module description
HID: logitech-hidpp: Check bounds when deleting force-feedback effects
HID: sony: add battery status support for Rock Band 4 PS5 guitars
HID: sony: fix style issues
HID: quirks: update hid-sony supported devices
...

+10177 -501
+724
Documentation/ABI/testing/sysfs-driver-hid-lenovo-go
··· 1 + What: /sys/class/leds/go:rgb:joystick_rings/effect 2 + Date: April 2026 3 + Contact: linux-input@vger.kernel.org 4 + Description: This controls the display effect of the RGB interface. 5 + 6 + Values are monocolor, breathe, chroma, or rainbow. 7 + 8 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 9 + 10 + What: /sys/class/leds/go:rgb:joystick_rings/effect_index 11 + Date: April 2026 12 + Contact: linux-input@vger.kernel.org 13 + Description: This displays the available options for the effect attribute. 14 + 15 + Values are monocolor, breathe, chroma, or rainbow. 16 + 17 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 18 + 19 + What: /sys/class/leds/go:rgb:joystick_rings/enabled 20 + Date: April 2026 21 + Contact: linux-input@vger.kernel.org 22 + Description: This controls enabling or disabling the RGB interface. 23 + 24 + Values are true or false. 25 + 26 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 27 + 28 + What: /sys/class/leds/go:rgb:joystick_rings/enabled_index 29 + Date: April 2026 30 + Contact: linux-input@vger.kernel.org 31 + Description: This displays the available options for the enabled attribute. 32 + 33 + Values are true or false. 34 + 35 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 36 + 37 + What: /sys/class/leds/go:rgb:joystick_rings/mode 38 + Date: April 2026 39 + Contact: linux-input@vger.kernel.org 40 + Description: This controls the operating mode of the RGB interface. 41 + 42 + Values are dynamic or custom. Custom allows setting the RGB effect and color. 43 + Dynamic is a Windows mode for syncing Lenovo RGB interfaces not currently 44 + supported under Linux. 45 + 46 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 47 + 48 + What: /sys/class/leds/go:rgb:joystick_rings/mode_index 49 + Date: April 2026 50 + Contact: linux-input@vger.kernel.org 51 + Description: This displays the available options for the mode attribute. 52 + 53 + Values are dynamic or custom. 54 + 55 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 56 + 57 + What: /sys/class/leds/go:rgb:joystick_rings/profile 58 + Date: April 2026 59 + Contact: linux-input@vger.kernel.org 60 + Description: This controls selecting the configured RGB profile. 61 + 62 + Values are 1-3. 63 + 64 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 65 + 66 + What: /sys/class/leds/go:rgb:joystick_rings/profile_range 67 + Date: April 2026 68 + Contact: linux-input@vger.kernel.org 69 + Description: This displays the available options for the profile attribute. 70 + 71 + Values are 1-3. 72 + 73 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 74 + 75 + What: /sys/class/leds/go:rgb:joystick_rings/speed 76 + Date: April 2026 77 + Contact: linux-input@vger.kernel.org 78 + Description: This controls the change rate for the breathe, chroma, and rainbow effects. 79 + 80 + Values are 0-100. 81 + 82 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 83 + 84 + What: /sys/class/leds/go:rgb:joystick_rings/speed_range 85 + Date: April 2026 86 + Contact: linux-input@vger.kernel.org 87 + Description: This displays the available options for the speed attribute. 88 + 89 + Values are 0-100. 90 + 91 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 92 + 93 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/firmware_version 94 + Date: April 2026 95 + Contact: linux-input@vger.kernel.org 96 + Description: This displays the firmware version of the internal MCU. 97 + 98 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 99 + 100 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/fps_mode_dpi 101 + Date: April 2026 102 + Contact: linux-input@vger.kernel.org 103 + Description: This displays the DPI of the right handle when the FPS mode switch is on. 104 + 105 + Values are 500, 800, 1200, and 1800. 106 + 107 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 108 + 109 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/fps_mode_dpi_index 110 + Date: April 2026 111 + Contact: linux-input@vger.kernel.org 112 + Description: This displays the available options for the fps_mode_dpi attribute. 113 + 114 + Values are 500, 800, 1200, and 1800. 115 + 116 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 117 + 118 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/hardware_generation 119 + Date: April 2026 120 + Contact: linux-input@vger.kernel.org 121 + Description: This displays the hardware generation of the internal MCU. 122 + 123 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 124 + 125 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/hardware_version 126 + Date: April 2026 127 + Contact: linux-input@vger.kernel.org 128 + Description: This displays the hardware version of the internal MCU. 129 + 130 + 131 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 132 + 133 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/auto_sleep_time 134 + Date: April 2026 135 + Contact: linux-input@vger.kernel.org 136 + Description: This controls the sleep timer due to inactivity for the left removable controller. 137 + 138 + Values are 0-255. 139 + 140 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 141 + 142 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/auto_sleep_time_range 143 + Date: April 2026 144 + Contact: linux-input@vger.kernel.org 145 + Description: This displays the available options for the left_handle/auto_sleep_time attribute. 146 + 147 + Values are 0-255. 148 + 149 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 150 + 151 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/calibrate_gyro 152 + Date: April 2026 153 + Contact: linux-input@vger.kernel.org 154 + Description: This initiates or halts calibration of the left removable controller's IMU. 155 + 156 + Values are start, stop. 157 + 158 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 159 + 160 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/calibrate_gyro_index 161 + Date: April 2026 162 + Contact: linux-input@vger.kernel.org 163 + Description: This displays the available options for the left_handle/calibrate_gyro attribute. 164 + 165 + Values are start, stop. 166 + 167 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 168 + 169 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/calibrate_gyro_status 170 + Date: April 2026 171 + Contact: linux-input@vger.kernel.org 172 + Description: This displays the result of the last attempted calibration of the left removable controller's IMU. 173 + 174 + Values are unknown, success, failure. 175 + 176 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 177 + 178 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/calibrate_joystick 179 + Date: April 2026 180 + Contact: linux-input@vger.kernel.org 181 + Description: This initiates or halts calibration of the left removable controller's joystick. 182 + 183 + Values are start, stop. 184 + 185 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 186 + 187 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/calibrate_joystick_index 188 + Date: April 2026 189 + Contact: linux-input@vger.kernel.org 190 + Description: This displays the available options for the left_handle/calibrate_jotstick attribute. 191 + 192 + Values are start, stop. 193 + 194 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 195 + 196 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/calibrate_joystick_status 197 + Date: April 2026 198 + Contact: linux-input@vger.kernel.org 199 + Description: This displays the result of the last attempted calibration of the left removable controller's joystick. 200 + 201 + Values are unknown, success, failure. 202 + 203 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 204 + 205 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/calibrate_tirgger 206 + Date: April 2026 207 + Contact: linux-input@vger.kernel.org 208 + Description: This initiates or halts calibration of the left removable controller's trigger. 209 + 210 + Values are start, stop. 211 + 212 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 213 + 214 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/calibrate_gyro_trigger 215 + Date: April 2026 216 + Contact: linux-input@vger.kernel.org 217 + Description: This displays the available options for the left_handle/calibrate_trigger attribute. 218 + 219 + Values are start, stop. 220 + 221 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 222 + 223 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/calibrate_trigger_status 224 + Date: April 2026 225 + Contact: linux-input@vger.kernel.org 226 + Description: This displays the result of the last attempted calibration of the left removable controller's trigger. 227 + 228 + Values are unknown, success, failure. 229 + 230 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 231 + 232 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/firmware_version 233 + Date: April 2026 234 + Contact: linux-input@vger.kernel.org 235 + Description: This displays the left removable controller's firmware version. 236 + 237 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 238 + 239 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/hardware_generation 240 + Date: April 2026 241 + Contact: linux-input@vger.kernel.org 242 + Description: This displays the hardware generation of the left removable controller. 243 + 244 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 245 + 246 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/hardware_version 247 + Date: April 2026 248 + Contact: linux-input@vger.kernel.org 249 + Description: This displays the hardware version of the left removable controller. 250 + 251 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 252 + 253 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/imu_bypass_enabled 254 + Date: April 2026 255 + Contact: linux-input@vger.kernel.org 256 + Description: This controls enabling or disabling the IMU bypass function of the left removable controller. 257 + 258 + Values are true or false. 259 + 260 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 261 + 262 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/imu_bypass_enabled_index 263 + Date: April 2026 264 + Contact: linux-input@vger.kernel.org 265 + Description: This displays the available options for the left_handle/imu_bypass_enabled attribute. 266 + 267 + Values are true or false. 268 + 269 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/imu_enabled 270 + Date: April 2026 271 + Contact: linux-input@vger.kernel.org 272 + Description: This controls enabling or disabling the IMU of the left removable controller. 273 + 274 + Values are true or false. 275 + 276 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 277 + 278 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/imu_enabled_index 279 + Date: April 2026 280 + Contact: linux-input@vger.kernel.org 281 + Description: This displays the available options for the left_handle/imu_enabled attribute. 282 + 283 + Values are true or false. 284 + 285 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 286 + 287 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/product_version 288 + Date: April 2026 289 + Contact: linux-input@vger.kernel.org 290 + Description: This displays the product version of the left removable controller. 291 + 292 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 293 + 294 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/protocol_version 295 + Date: April 2026 296 + Contact: linux-input@vger.kernel.org 297 + Description: This displays the protocol version of the left removable controller. 298 + 299 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 300 + 301 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/reset 302 + Date: April 2026 303 + Contact: linux-input@vger.kernel.org 304 + Description: Resets the left removable controller to factory defaults. 305 + 306 + Writing 1 to this path initiates. 307 + 308 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 309 + 310 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/rumble_mode 311 + Date: April 2026 312 + Contact: linux-input@vger.kernel.org 313 + Description: This controls setting the response behavior for rumble events for the left removable controller. 314 + 315 + Values are fps, racing, standarg, spg, rpg. 316 + 317 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 318 + 319 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/rumble_mode_index 320 + Date: April 2026 321 + Contact: linux-input@vger.kernel.org 322 + Description: This displays the available options for the left_handle/rumble_mode attribute. 323 + 324 + Values are fps, racing, standarg, spg, rpg. 325 + 326 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 327 + 328 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/rumble_notification 329 + Date: April 2026 330 + Contact: linux-input@vger.kernel.org 331 + Description: This controls enabling haptic rumble events for the left removable controller. 332 + 333 + Values are true, false. 334 + 335 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 336 + 337 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/rumble_notification_index 338 + Date: April 2026 339 + Contact: linux-input@vger.kernel.org 340 + Description: This displays the available options for the left_handle/rumble_notification attribute. 341 + 342 + Values are true, false. 343 + 344 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 345 + 346 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/mode 347 + Date: April 2026 348 + Contact: linux-input@vger.kernel.org 349 + Description: This controls the operating mode of the built-in controller. 350 + 351 + Values are xinput or dinput. 352 + 353 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 354 + 355 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/left_handle/mode_index 356 + Date: April 2026 357 + Contact: linux-input@vger.kernel.org 358 + Description: This displays the available options for the mode attribute. 359 + 360 + Values are xinput or dinput. 361 + 362 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 363 + 364 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/os_mode 365 + Date: April 2026 366 + Contact: linux-input@vger.kernel.org 367 + Description: This controls the behavior of built in chord combinations. 368 + 369 + Values are windows or linux. 370 + 371 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 372 + 373 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/os_mode_index 374 + Date: April 2026 375 + Contact: linux-input@vger.kernel.org 376 + Description: This displays the available options for the os_mode attribute. 377 + 378 + Values are windows or linux. 379 + 380 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 381 + 382 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/product_version 383 + Date: April 2026 384 + Contact: linux-input@vger.kernel.org 385 + Description: This displays the product version of the internal MCU. 386 + 387 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 388 + 389 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/protocol_version 390 + Date: April 2026 391 + Contact: linux-input@vger.kernel.org 392 + Description: This displays the protocol version of the internal MCU. 393 + 394 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 395 + 396 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/reset_mcu 397 + Date: April 2026 398 + Contact: linux-input@vger.kernel.org 399 + Description: Resets the internal MCU to factory defaults. 400 + 401 + Writing 1 to this path initiates. 402 + 403 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 404 + 405 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/auto_sleep_time 406 + Date: April 2026 407 + Contact: linux-input@vger.kernel.org 408 + Description: This controls the sleep timer due to inactivity for the right removable controller. 409 + 410 + Values are 0-255. 411 + 412 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 413 + 414 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/auto_sleep_time_range 415 + Date: April 2026 416 + Contact: linux-input@vger.kernel.org 417 + Description: This displays the available options for the right_handle/auto_sleep_time attribute. 418 + 419 + Values are 0-255. 420 + 421 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 422 + 423 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/calibrate_gyro 424 + Date: April 2026 425 + Contact: linux-input@vger.kernel.org 426 + Description: This initiates or halts calibration of the right removable controller's IMU. 427 + 428 + Values are start, stop. 429 + 430 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 431 + 432 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/calibrate_gyro_index 433 + Date: April 2026 434 + Contact: linux-input@vger.kernel.org 435 + Description: This displays the available options for the right_handle/calibrate_gyro attribute. 436 + 437 + Values are start, stop. 438 + 439 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 440 + 441 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/calibrate_gyro_status 442 + Date: April 2026 443 + Contact: linux-input@vger.kernel.org 444 + Description: This displays the result of the last attempted calibration of the right removable controller's IMU. 445 + 446 + Values are unknown, success, failure. 447 + 448 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 449 + 450 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/calibrate_joystick 451 + Date: April 2026 452 + Contact: linux-input@vger.kernel.org 453 + Description: This initiates or halts calibration of the right removable controller's joystick. 454 + 455 + Values are start, stop. 456 + 457 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 458 + 459 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/calibrate_joystick_index 460 + Date: April 2026 461 + Contact: linux-input@vger.kernel.org 462 + Description: This displays the available options for the right_handle/calibrate_jotstick attribute. 463 + 464 + Values are start, stop. 465 + 466 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 467 + 468 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/calibrate_joystick_status 469 + Date: April 2026 470 + Contact: linux-input@vger.kernel.org 471 + Description: This displays the result of the last attempted calibration of the right removable controller's joystick. 472 + 473 + Values are unknown, success, failure. 474 + 475 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 476 + 477 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/calibrate_tirgger 478 + Date: April 2026 479 + Contact: linux-input@vger.kernel.org 480 + Description: This initiates or halts calibration of the right removable controller's trigger. 481 + 482 + Values are start, stop. 483 + 484 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 485 + 486 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/calibrate_gyro_trigger 487 + Date: April 2026 488 + Contact: linux-input@vger.kernel.org 489 + Description: This displays the available options for the right_handle/calibrate_trigger attribute. 490 + 491 + Values are start, stop. 492 + 493 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 494 + 495 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/calibrate_trigger_status 496 + Date: April 2026 497 + Contact: linux-input@vger.kernel.org 498 + Description: This displays the result of the last attempted calibration of the right removable controller's trigger. 499 + 500 + Values are unknown, success, failure. 501 + 502 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 503 + 504 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/firmware_version 505 + Date: April 2026 506 + Contact: linux-input@vger.kernel.org 507 + Description: This displays the right removable controller's firmware version. 508 + 509 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 510 + 511 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/hardware_generation 512 + Date: April 2026 513 + Contact: linux-input@vger.kernel.org 514 + Description: This displays the hardware generation of the right removable controller. 515 + 516 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 517 + 518 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/hardware_version 519 + Date: April 2026 520 + Contact: linux-input@vger.kernel.org 521 + Description: This displays the hardware version of the right removable controller. 522 + 523 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 524 + 525 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/imu_bypass_enabled 526 + Date: April 2026 527 + Contact: linux-input@vger.kernel.org 528 + Description: This controls enabling or disabling the IMU bypass function of the right removable controller. 529 + 530 + Values are true or false. 531 + 532 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 533 + 534 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/imu_bypass_enabled_index 535 + Date: April 2026 536 + Contact: linux-input@vger.kernel.org 537 + Description: This displays the available options for the right_handle/imu_bypass_enabled attribute. 538 + 539 + Values are true or false. 540 + 541 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/imu_enabled 542 + Date: April 2026 543 + Contact: linux-input@vger.kernel.org 544 + Description: This controls enabling or disabling the IMU of the right removable controller. 545 + 546 + Values are true or false. 547 + 548 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 549 + 550 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/imu_enabled_index 551 + Date: April 2026 552 + Contact: linux-input@vger.kernel.org 553 + Description: This displays the available options for the right_handle/imu_enabled attribute. 554 + 555 + Values are true or false. 556 + 557 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 558 + 559 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/product_version 560 + Date: April 2026 561 + Contact: linux-input@vger.kernel.org 562 + Description: This displays the product version of the right removable controller. 563 + 564 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 565 + 566 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/protocol_version 567 + Date: April 2026 568 + Contact: linux-input@vger.kernel.org 569 + Description: This displays the protocol version of the right removable controller. 570 + 571 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 572 + 573 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/reset 574 + Date: April 2026 575 + Contact: linux-input@vger.kernel.org 576 + Description: Resets the right removable controller to factory defaults. 577 + 578 + Writing 1 to this path initiates. 579 + 580 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 581 + 582 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/rumble_mode 583 + Date: April 2026 584 + Contact: linux-input@vger.kernel.org 585 + Description: This controls setting the response behavior for rumble events for the right removable controller. 586 + 587 + Values are fps, racing, standarg, spg, rpg. 588 + 589 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 590 + 591 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/rumble_mode_index 592 + Date: April 2026 593 + Contact: linux-input@vger.kernel.org 594 + Description: This displays the available options for the right_handle/rumble_mode attribute. 595 + 596 + Values are fps, racing, standarg, spg, rpg. 597 + 598 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 599 + 600 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/rumble_notification 601 + Date: April 2026 602 + Contact: linux-input@vger.kernel.org 603 + Description: This controls enabling haptic rumble events for the right removable controller. 604 + 605 + Values are true, false. 606 + 607 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 608 + 609 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/right_handle/rumble_notification_index 610 + Date: April 2026 611 + Contact: linux-input@vger.kernel.org 612 + Description: This displays the available options for the right_handle/rumble_notification attribute. 613 + 614 + Values are true, false. 615 + 616 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 617 + 618 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/rumble_intensity 619 + Date: April 2026 620 + Contact: linux-input@vger.kernel.org 621 + Description: This controls setting the rumble intensity for both removable controllers. 622 + 623 + Values are off, low, medium, high. 624 + 625 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 626 + 627 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/rumble_intensity_index 628 + Date: April 2026 629 + Contact: linux-input@vger.kernel.org 630 + Description: This displays the available options for the rumble_intensity attribute. 631 + 632 + Values are off, low, medium, high. 633 + 634 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 635 + 636 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/touchpad/enabled 637 + Date: April 2026 638 + Contact: linux-input@vger.kernel.org 639 + Description: This controls enabling or disabling the touchpad. 640 + 641 + Values are true, false. 642 + 643 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 644 + 645 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/touchpad/enabled_index 646 + Date: April 2026 647 + Contact: linux-input@vger.kernel.org 648 + Description: This displays the available options for the touchpad/enabled attribute. 649 + 650 + Values are true, false. 651 + 652 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 653 + 654 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/touchpad/vibration_enabled 655 + Date: April 2026 656 + Contact: linux-input@vger.kernel.org 657 + Description: This controls enabling haptic rumble events for the touchpad. 658 + 659 + Values are true, false. 660 + 661 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 662 + 663 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/touchpad/vibration_enabled_index 664 + Date: April 2026 665 + Contact: linux-input@vger.kernel.org 666 + Description: This displays the available options for the touchpad/vibration_enabled attribute. 667 + 668 + Values are true, false. 669 + 670 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 671 + 672 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/touchpad/vibration_intensity 673 + Date: April 2026 674 + Contact: linux-input@vger.kernel.org 675 + Description: This controls setting the intensity of the touchpad haptics. 676 + 677 + Values are off, low, medium, high. 678 + 679 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 680 + 681 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/touchpad/vibration_intensity_index 682 + Date: April 2026 683 + Contact: linux-input@vger.kernel.org 684 + Description: This displays the available options for the touchpad/vibration_intensity attribute. 685 + 686 + Values are off, low, medium, high. 687 + 688 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 689 + 690 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/tx_dongle/firmware_version 691 + Date: April 2026 692 + Contact: linux-input@vger.kernel.org 693 + Description: This displays the firmware version of the internal wireless transmission dongle. 694 + 695 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 696 + 697 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/tx_dongle/hardware_generation 698 + Date: April 2026 699 + Contact: linux-input@vger.kernel.org 700 + Description: This displays the hardware generation of the internal wireless transmission dongle. 701 + 702 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 703 + 704 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/tx_dongle/hardware_version 705 + Date: April 2026 706 + Contact: linux-input@vger.kernel.org 707 + Description: This displays the hardware version of the internal wireless transmission dongle. 708 + 709 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 710 + 711 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/tx_dongle/product_version 712 + Date: April 2026 713 + Contact: linux-input@vger.kernel.org 714 + Description: This displays the product version of the internal wireless transmission dongle. 715 + 716 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 717 + 718 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/tx_dongle/protocol_version 719 + Date: April 2026 720 + Contact: linux-input@vger.kernel.org 721 + Description: This displays the protocol version of the internal wireless transmission dongle. 722 + 723 + Applies to Lenovo Legion Go and Go 2 line of handheld devices. 724 +
+304
Documentation/ABI/testing/sysfs-driver-hid-lenovo-go-s
··· 1 + What: /sys/class/leds/go_s:rgb:joystick_rings/effect 2 + Date: April 2026 3 + Contact: linux-input@vger.kernel.org 4 + Description: This controls the display effect of the RGB interface. 5 + 6 + Values are monocolor, breathe, chroma, or rainbow. 7 + 8 + Applies to Lenovo Legion Go S line of handheld devices. 9 + 10 + What: /sys/class/leds/go_s:rgb:joystick_rings/effect_index 11 + Date: April 2026 12 + Contact: linux-input@vger.kernel.org 13 + Description: This displays the available options for the effect attribute. 14 + 15 + Values are monocolor, breathe, chroma, or rainbow. 16 + 17 + Applies to Lenovo Legion Go S line of handheld devices. 18 + 19 + What: /sys/class/leds/go_s:rgb:joystick_rings/enabled 20 + Date: April 2026 21 + Contact: linux-input@vger.kernel.org 22 + Description: This controls enabling or disabling the RGB interface. 23 + 24 + Values are true or false. 25 + 26 + Applies to Lenovo Legion Go S line of handheld devices. 27 + 28 + What: /sys/class/leds/go_s:rgb:joystick_rings/enabled_index 29 + Date: April 2026 30 + Contact: linux-input@vger.kernel.org 31 + Description: This displays the available options for the enabled attribute. 32 + 33 + Values are true or false. 34 + 35 + Applies to Lenovo Legion Go S line of handheld devices. 36 + 37 + What: /sys/class/leds/go_s:rgb:joystick_rings/mode 38 + Date: April 2026 39 + Contact: linux-input@vger.kernel.org 40 + Description: This controls the operating mode of the RGB interface. 41 + 42 + Values are dynamic or custom. Custom allows setting the RGB effect and color. 43 + Dynamic is a Windows mode for syncing Lenovo RGB interfaces not currently 44 + supported under Linux. 45 + 46 + Applies to Lenovo Legion Go S line of handheld devices. 47 + 48 + What: /sys/class/leds/go_s:rgb:joystick_rings/mode_index 49 + Date: April 2026 50 + Contact: linux-input@vger.kernel.org 51 + Description: This displays the available options for the mode attribute. 52 + 53 + Values are dynamic or custom. 54 + 55 + Applies to Lenovo Legion Go S line of handheld devices. 56 + 57 + What: /sys/class/leds/go_s:rgb:joystick_rings/profile 58 + Date: April 2026 59 + Contact: linux-input@vger.kernel.org 60 + Description: This controls selecting the configured RGB profile. 61 + 62 + Values are 1-3. 63 + 64 + Applies to Lenovo Legion Go S line of handheld devices. 65 + 66 + What: /sys/class/leds/go_s:rgb:joystick_rings/profile_range 67 + Date: April 2026 68 + Contact: linux-input@vger.kernel.org 69 + Description: This displays the available options for the profile attribute. 70 + 71 + Values are 1-3. 72 + 73 + Applies to Lenovo Legion Go S line of handheld devices. 74 + 75 + What: /sys/class/leds/go_s:rgb:joystick_rings/speed 76 + Date: April 2026 77 + Contact: linux-input@vger.kernel.org 78 + Description: This controls the change rate for the breathe, chroma, and rainbow effects. 79 + 80 + Values are 0-100. 81 + 82 + Applies to Lenovo Legion Go S line of handheld devices. 83 + 84 + What: /sys/class/leds/go_s:rgb:joystick_rings/speed_range 85 + Date: April 2026 86 + Contact: linux-input@vger.kernel.org 87 + Description: This displays the available options for the speed attribute. 88 + 89 + Values are 0-100. 90 + 91 + Applies to Lenovo Legion Go S line of handheld devices. 92 + 93 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/gamepad/auto_sleep_time 94 + Date: April 2026 95 + Contact: linux-input@vger.kernel.org 96 + Description: This controls the sleep timer due to inactivity for the built-in controller. 97 + 98 + Values are 0-255. 99 + 100 + Applies to Lenovo Legion Go S line of handheld devices. 101 + 102 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/gamepad/auto_sleep_time_range 103 + Date: April 2026 104 + Contact: linux-input@vger.kernel.org 105 + Description: This displays the available options for the gamepad/auto_sleep_time attribute. 106 + 107 + Values are 0-255. 108 + 109 + Applies to Lenovo Legion Go S line of handheld devices. 110 + 111 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/gamepad/dpad_mode 112 + Date: April 2026 113 + Contact: linux-input@vger.kernel.org 114 + Description: This controls the operating mode of the built-in controllers D-pad. 115 + 116 + Values are 4-way or 8-way. 117 + 118 + Applies to Lenovo Legion Go S line of handheld devices. 119 + 120 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/gamepad/dpad_mode_index 121 + Date: April 2026 122 + Contact: linux-input@vger.kernel.org 123 + Description: This displays the available options for the gamepad/dpad_mode attribute. 124 + 125 + Values are 4-way or 8-way. 126 + 127 + Applies to Lenovo Legion Go S line of handheld devices. 128 + 129 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/gamepad/mode 130 + Date: April 2026 131 + Contact: linux-input@vger.kernel.org 132 + Description: This controls the operating mode of the built-in controller. 133 + 134 + Values are xinput or dinput. 135 + 136 + Applies to Lenovo Legion Go S line of handheld devices. 137 + 138 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/gamepad/mode_index 139 + Date: April 2026 140 + Contact: linux-input@vger.kernel.org 141 + Description: This displays the available options for the gamepad/mode attribute. 142 + 143 + Values are xinput or dinput. 144 + 145 + Applies to Lenovo Legion Go S line of handheld devices. 146 + 147 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/gamepad/poll_rate 148 + Date: April 2026 149 + Contact: linux-input@vger.kernel.org 150 + Description: This controls the poll rate in Hz of the built-in controller. 151 + 152 + Values are 125, 250, 500, or 1000. 153 + 154 + Applies to Lenovo Legion Go S line of handheld devices. 155 + 156 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/gamepad/poll_rate_index 157 + Date: April 2026 158 + Contact: linux-input@vger.kernel.org 159 + Description: This displays the available options for the gamepad/poll_rate attribute. 160 + 161 + Values are 125, 250, 500, or 1000. 162 + 163 + Applies to Lenovo Legion Go S line of handheld devices. 164 + 165 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/imu/bypass_enabled 166 + Date: April 2026 167 + Contact: linux-input@vger.kernel.org 168 + Description: This controls enabling or disabling the IMU bypass function. When enabled the IMU data is directly reported to the OS through 169 + an HIDRAW interface. 170 + 171 + Values are true or false. 172 + 173 + Applies to Lenovo Legion Go S line of handheld devices. 174 + 175 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/imu/bypass_enabled_index 176 + Date: April 2026 177 + Contact: linux-input@vger.kernel.org 178 + Description: This displays the available options for the imu/bypass_enabled attribute. 179 + 180 + Values are true or false. 181 + 182 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/imu/manufacturer 183 + Date: April 2026 184 + Contact: linux-input@vger.kernel.org 185 + Description: This displays the manufacturer of the intertial measurment unit. 186 + 187 + Values are Bosch or ST. 188 + 189 + Applies to Lenovo Legion Go S line of handheld devices. 190 + 191 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/imu/sensor_enabled 192 + Date: April 2026 193 + Contact: linux-input@vger.kernel.org 194 + Description: This controls enabling or disabling the IMU. 195 + 196 + Values are true, false, or wake-2s. 197 + 198 + Applies to Lenovo Legion Go S line of handheld devices. 199 + 200 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/imu/sensor_enabled_index 201 + Date: April 2026 202 + Contact: linux-input@vger.kernel.org 203 + Description: This displays the available options for the imu/sensor_enabled attribute. 204 + 205 + Values are true, false, or wake-2s. 206 + 207 + Applies to Lenovo Legion Go S line of handheld devices. 208 + 209 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/mcu_id 210 + Date: April 2026 211 + Contact: linux-input@vger.kernel.org 212 + Description: This displays the MCU Identification Number 213 + 214 + Applies to Lenovo Legion Go S line of handheld devices. 215 + 216 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/mouse/step 217 + Date: April 2026 218 + Contact: linux-input@vger.kernel.org 219 + Description: This controls which value is used for the mouse sensitivity. 220 + 221 + Values are 1-127. 222 + 223 + Applies to Lenovo Legion Go S line of handheld devices. 224 + 225 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/mouse/step_range 226 + Date: April 2026 227 + Contact: linux-input@vger.kernel.org 228 + Description: This displays the available options for the mouse/step attribute. 229 + 230 + Values are 1-127. 231 + 232 + Applies to Lenovo Legion Go S line of handheld devices. 233 + 234 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/os_mode 235 + Date: April 2026 236 + Contact: linux-input@vger.kernel.org 237 + Description: This controls which value is used for the touchpads operating mode. 238 + 239 + Values are windows or linux. 240 + 241 + Applies to Lenovo Legion Go S line of handheld devices. 242 + 243 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/os_mode_index 244 + Date: April 2026 245 + Contact: linux-input@vger.kernel.org 246 + Description: This displays the available options for the os_mode attribute. 247 + 248 + Values are windows or linux. 249 + 250 + Applies to Lenovo Legion Go S line of handheld devices. 251 + 252 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/touchpad/enabled 253 + Date: April 2026 254 + Contact: linux-input@vger.kernel.org 255 + Description: This controls enabling or disabling the built-in touchpad. 256 + 257 + Values are true or false. 258 + 259 + Applies to Lenovo Legion Go S line of handheld devices. 260 + 261 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/touchpad/enabled_index 262 + Date: April 2026 263 + Contact: linux-input@vger.kernel.org 264 + Description: This displays the available options for the touchpad/enabled attribute. 265 + 266 + Values are true or false. 267 + 268 + Applies to Lenovo Legion Go S line of handheld devices. 269 + 270 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/touchpad/linux_mode 271 + Date: April 2026 272 + Contact: linux-input@vger.kernel.org 273 + Description: This controls behavior of the touchpad events when os_mode is set to linux. 274 + 275 + Values are absolute or relative. 276 + 277 + Applies to Lenovo Legion Go S line of handheld devices. 278 + 279 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/touchpad/linux_mode_index 280 + Date: April 2026 281 + Contact: linux-input@vger.kernel.org 282 + Description: This displays the available options for the touchpad/linux_mode attribute. 283 + 284 + Values are absolute or relative. 285 + 286 + Applies to Lenovo Legion Go S line of handheld devices. 287 + 288 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/touchpad/windows_mode 289 + Date: April 2026 290 + Contact: linux-input@vger.kernel.org 291 + Description: This controls behavior of the touchpad events when os_mode is set to windows. 292 + 293 + Values are absolute or relative. 294 + 295 + Applies to Lenovo Legion Go S line of handheld devices. 296 + 297 + What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/touchpad/windows_mode_index 298 + Date: April 2026 299 + Contact: linux-input@vger.kernel.org 300 + Description: This displays the available options for the touchpad/windows_mode attribute. 301 + 302 + Values are absolute or relative. 303 + 304 + Applies to Lenovo Legion Go S line of handheld devices.
+20 -8
MAINTAINERS
··· 11432 11432 F: drivers/iio/*/hid-* 11433 11433 F: include/linux/hid-sensor-* 11434 11434 11435 - HID UNIVERSAL PIDFF DRIVER 11436 - M: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com> 11437 - M: Oleg Makarenko <oleg@makarenk.ooo> 11438 - L: linux-input@vger.kernel.org 11439 - S: Maintained 11440 - B: https://github.com/JacKeTUs/universal-pidff/issues 11441 - F: drivers/hid/hid-universal-pidff.c 11442 - 11443 11435 HID VRC-2 CAR CONTROLLER DRIVER 11444 11436 M: Marcus Folkesson <marcus.folkesson@gmail.com> 11445 11437 L: linux-input@vger.kernel.org ··· 14546 14554 L: platform-driver-x86@vger.kernel.org 14547 14555 S: Maintained 14548 14556 F: drivers/platform/x86/lenovo/wmi-hotkey-utilities.c 14557 + 14558 + LENOVO HID drivers 14559 + M: Derek J. Clark <derekjohn.clark@gmail.com> 14560 + M: Mark Pearson <mpearson-lenovo@squebb.ca> 14561 + L: linux-input@vger.kernel.org 14562 + S: Maintained 14563 + F: Documentation/ABI/testing/sysfs-driver-hid-lenovo-go 14564 + F: Documentation/ABI/testing/sysfs-driver-hid-lenovo-go-s 14565 + F: drivers/hid/hid-lenovo-go-s.c 14566 + F: drivers/hid/hid-lenovo-go.c 14567 + F: drivers/hid/hid-lenovo.c 14549 14568 14550 14569 LETSKETCH HID TABLET DRIVER 14551 14570 M: Hans de Goede <hansg@kernel.org> ··· 27494 27491 T: git git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git 27495 27492 F: Documentation/hid/hiddev.rst 27496 27493 F: drivers/hid/usbhid/ 27494 + 27495 + USB HID PID DRIVERS (USB WHEELBASES, JOYSTICKS, RUDDERS, ...) 27496 + M: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com> 27497 + M: Oleg Makarenko <oleg@makarenk.ooo> 27498 + L: linux-input@vger.kernel.org 27499 + S: Maintained 27500 + B: https://github.com/JacKeTUs/universal-pidff/issues 27501 + F: drivers/hid/usbhid/hid-pidff* 27502 + F: drivers/hid/hid-universal-pidff.c 27497 27503 27498 27504 USB INTEL XHCI ROLE MUX DRIVER 27499 27505 M: Hans de Goede <hansg@kernel.org>
+37 -20
drivers/hid/Kconfig
··· 107 107 108 108 config HID_A4TECH 109 109 tristate "A4TECH mice" 110 - default !EXPERT 111 110 help 112 111 Support for some A4TECH mice with two scroll wheels. 113 112 ··· 139 140 tristate "Apple {i,Power,Mac}Books" 140 141 depends on LEDS_CLASS 141 142 depends on NEW_LEDS 142 - default !EXPERT 143 143 help 144 144 Support for some Apple devices which less or more break 145 145 HID specification. ··· 207 209 208 210 config HID_BELKIN 209 211 tristate "Belkin Flip KVM and Wireless keyboard" 210 - default !EXPERT 211 212 help 212 213 Support for Belkin Flip KVM and Wireless keyboard. 213 214 ··· 234 237 235 238 config HID_CHERRY 236 239 tristate "Cherry Cymotion keyboard" 237 - default !EXPERT 238 240 help 239 241 Support for Cherry Cymotion keyboard. 240 242 241 243 config HID_CHICONY 242 244 tristate "Chicony devices" 243 245 depends on USB_HID 244 - default !EXPERT 245 246 help 246 247 Support for Chicony Tactical pad and special keys on Chicony keyboards. 247 248 ··· 317 322 318 323 config HID_CYPRESS 319 324 tristate "Cypress mouse and barcode readers" 320 - default !EXPERT 321 325 help 322 326 Support for cypress mouse and barcode readers. 323 327 ··· 382 388 383 389 config HID_EZKEY 384 390 tristate "Ezkey BTC 8193 keyboard" 385 - default !EXPERT 386 391 help 387 392 Support for Ezkey BTC 8193 keyboard. 388 393 ··· 557 564 558 565 config HID_ITE 559 566 tristate "ITE devices" 560 - default !EXPERT 561 567 help 562 568 Support for ITE devices not fully compliant with HID standard. 563 569 ··· 577 585 578 586 config HID_KENSINGTON 579 587 tristate "Kensington Slimblade Trackball" 580 - default !EXPERT 581 588 help 582 589 Support for Kensington Slimblade Trackball. 583 590 ··· 601 610 602 611 config HID_LENOVO 603 612 tristate "Lenovo / Thinkpad devices" 604 - select NEW_LEDS 605 - select LEDS_CLASS 613 + depends on LEDS_CLASS 606 614 help 607 615 Support for IBM/Lenovo devices that are not fully compliant with HID standard. 608 616 ··· 612 622 configuration) 613 623 - ThinkPad Compact Bluetooth Keyboard with TrackPoint (supports Fn keys) 614 624 - ThinkPad Compact USB Keyboard with TrackPoint (supports Fn keys) 625 + 626 + config HID_LENOVO_GO 627 + tristate "HID Driver for Lenovo Legion Go Series Controllers" 628 + depends on USB_HID 629 + depends on LEDS_CLASS_MULTICOLOR 630 + help 631 + Support for Lenovo Legion Go devices with detachable controllers. 632 + 633 + Say Y here to include configuration interface support for the Lenovo Legion Go 634 + and Legion Go 2 Handheld Console Controllers. Say M here to compile this 635 + driver as a module. The module will be called hid-lenovo-go. 636 + 637 + config HID_LENOVO_GO_S 638 + tristate "HID Driver for Lenovo Legion Go S Controller" 639 + depends on USB_HID 640 + depends on LEDS_CLASS_MULTICOLOR 641 + help 642 + Support for Lenovo Legion Go S Handheld Console Controller. 643 + 644 + Say Y here to include configuration interface support for the Lenovo Legion Go 645 + S. Say M here to compile this driver as a module. The module will be called 646 + hid-lenovo-go-s. 615 647 616 648 config HID_LETSKETCH 617 649 tristate "Letsketch WP9620N tablets" ··· 654 642 depends on USB_HID 655 643 depends on LEDS_CLASS 656 644 depends on LEDS_CLASS_MULTICOLOR 657 - default !EXPERT 658 645 help 659 646 Support for Logitech devices that are not fully compliant with HID standard. 660 647 ··· 768 757 769 758 config HID_REDRAGON 770 759 tristate "Redragon keyboards" 771 - default !EXPERT 772 760 help 773 761 Support for Redragon keyboards that need fix-ups to work properly. 774 762 775 763 config HID_MICROSOFT 776 764 tristate "Microsoft non-fully HID-compliant devices" 777 - default !EXPERT 778 765 select INPUT_FF_MEMLESS 779 766 help 780 767 Support for Microsoft devices that are not fully compliant with HID standard. 781 768 782 769 config HID_MONTEREY 783 770 tristate "Monterey Genius KB29E keyboard" 784 - default !EXPERT 785 771 help 786 772 Support for Monterey Genius KB29E. 787 773 ··· 1108 1100 help 1109 1101 Support for 1110 1102 1111 - * Sony PS3 6-axis controllers 1103 + * Sixaxis controllers for PS3 1112 1104 * Buzz controllers 1113 - * Sony PS3 Blue-ray Disk Remote Control (Bluetooth) 1114 - * Logitech Harmony adapter for Sony Playstation 3 (Bluetooth) 1115 - * Guitar Hero Live PS3, Wii U and PS4 guitar dongles 1116 - * Guitar Hero PS3 and PC guitar dongles 1105 + * Blu-ray Disc Remote Control for PS3 1106 + * Logitech Harmony adapter for PS3 1107 + * Guitar Hero Live PS3, Wii U and PS4 guitars 1108 + * Guitar Hero PS3 and PC guitars 1109 + * Rock Band 1, 2 and 3 PS3 and Wii instruments 1117 1110 * Rock Band 4 PS4 and PS5 guitars 1111 + * DJ Hero Turntable for PS3 1118 1112 1119 1113 config SONY_FF 1120 1114 bool "Sony PS2/3/4 accessories force feedback support" ··· 1444 1434 Documentation/dev-tools/kunit/. 1445 1435 1446 1436 If in doubt, say "N". 1437 + 1438 + config HID_HUAWEI 1439 + tristate "Huawei HID devices support" 1440 + depends on USB_HID 1441 + help 1442 + Support for huawei cd30 keyboard or other hid devices 1443 + that need fix-ups to work properly. 1447 1444 1448 1445 endmenu 1449 1446
+3
drivers/hid/Makefile
··· 76 76 obj-$(CONFIG_HID_KYSONA) += hid-kysona.o 77 77 obj-$(CONFIG_HID_LCPOWER) += hid-lcpower.o 78 78 obj-$(CONFIG_HID_LENOVO) += hid-lenovo.o 79 + obj-$(CONFIG_HID_LENOVO_GO) += hid-lenovo-go.o 80 + obj-$(CONFIG_HID_LENOVO_GO_S) += hid-lenovo-go-s.o 79 81 obj-$(CONFIG_HID_LETSKETCH) += hid-letsketch.o 80 82 obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o 81 83 obj-$(CONFIG_HID_LOGITECH) += hid-lg-g15.o ··· 154 152 obj-$(CONFIG_HID_ZYDACRON) += hid-zydacron.o 155 153 obj-$(CONFIG_HID_VIEWSONIC) += hid-viewsonic.o 156 154 obj-$(CONFIG_HID_VRC2) += hid-vrc2.o 155 + obj-$(CONFIG_HID_HUAWEI) += hid-huawei.o 157 156 158 157 wacom-objs := wacom_wac.o wacom_sys.o 159 158 obj-$(CONFIG_HID_WACOM) += wacom.o
+90
drivers/hid/bpf/progs/Generic__touchpad.bpf.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* Copyright (c) 2025 Benjamin Tissoires 3 + */ 4 + 5 + #include "vmlinux.h" 6 + #include "hid_bpf.h" 7 + #include "hid_bpf_helpers.h" 8 + #include "hid_report_helpers.h" 9 + #include "hid_usages.h" 10 + #include <bpf/bpf_tracing.h> 11 + 12 + HID_BPF_CONFIG( 13 + HID_DEVICE(BUS_ANY, HID_GROUP_MULTITOUCH_WIN_8, HID_VID_ANY, HID_PID_ANY), 14 + ); 15 + 16 + EXPORT_UDEV_PROP(HID_DIGITIZER_PAD_TYPE, 32); 17 + 18 + __u8 hw_req_buf[1024]; 19 + 20 + /* to be filled by udev-hid-bpf */ 21 + struct hid_rdesc_descriptor HID_REPORT_DESCRIPTOR; 22 + 23 + SEC("syscall") 24 + int probe(struct hid_bpf_probe_args *ctx) 25 + { 26 + struct hid_rdesc_report *pad_type_feature = NULL; 27 + struct hid_rdesc_field *pad_type = NULL; 28 + struct hid_rdesc_report *feature; 29 + struct hid_bpf_ctx *hid_ctx; 30 + char *pad_type_str = ""; 31 + int ret; 32 + 33 + hid_bpf_for_each_feature_report(&HID_REPORT_DESCRIPTOR, feature) { 34 + struct hid_rdesc_field *field; 35 + 36 + hid_bpf_for_each_field(feature, field) { 37 + if (field->usage_page == HidUsagePage_Digitizers && 38 + field->usage_id == HidUsage_Dig_PadType) { 39 + pad_type = field; 40 + pad_type_feature = feature; 41 + break; 42 + } 43 + } 44 + if (pad_type) 45 + break; 46 + } 47 + 48 + if (!pad_type || !pad_type_feature) { 49 + ctx->retval = -EINVAL; 50 + return 0; 51 + } 52 + 53 + hid_ctx = hid_bpf_allocate_context(ctx->hid); 54 + 55 + if (!hid_ctx) 56 + return -1; /* EPERM check */ 57 + 58 + hw_req_buf[0] = pad_type_feature->report_id; 59 + 60 + ret = hid_bpf_hw_request(hid_ctx, hw_req_buf, sizeof(hw_req_buf), 61 + HID_FEATURE_REPORT, HID_REQ_GET_REPORT); 62 + hid_bpf_release_context(hid_ctx); 63 + 64 + if (ret < 0) { 65 + ctx->retval = ret; 66 + return 0; 67 + } 68 + 69 + ctx->retval = 0; 70 + 71 + switch (EXTRACT_BITS(hw_req_buf, pad_type)) { 72 + case 0: 73 + pad_type_str = "Clickpad"; 74 + break; 75 + case 1: 76 + pad_type_str = "Pressurepad"; 77 + break; 78 + case 2: 79 + pad_type_str = "Discrete"; 80 + break; 81 + default: 82 + pad_type_str = "Unknown"; 83 + } 84 + 85 + UDEV_PROP_SPRINTF(HID_DIGITIZER_PAD_TYPE, "%s", pad_type_str); 86 + 87 + return 0; 88 + } 89 + 90 + char _license[] SEC("license") = "GPL";
+492
drivers/hid/bpf/progs/Huion__KeydialK20-Bluetooth.bpf.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* Copyright (c) 2024 Red Hat, Inc 3 + */ 4 + 5 + #include "vmlinux.h" 6 + #include "hid_bpf.h" 7 + #include "hid_bpf_helpers.h" 8 + #include "hid_report_helpers.h" 9 + #include <bpf/bpf_tracing.h> 10 + 11 + #define VID_HUION 0x256C 12 + #define PID_KEYDIAL_K20_BLUETOOTH 0x8251 13 + 14 + HID_BPF_CONFIG( 15 + HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_GENERIC, VID_HUION, PID_KEYDIAL_K20_BLUETOOTH), 16 + ); 17 + 18 + /* This is the same device as in 0010-Huion__KeydialK20 but connected via Bluetooth. 19 + * It does not need (to support?) switching to a vendor mode so we just modify the 20 + * existing mode. 21 + * 22 + * By default it exports two hidraw nodes, only the second one sends events. 23 + * 24 + * This is the first hidraw node which we disable: 25 + * 26 + * # Keydial mini-050 27 + * # Report descriptor length: 114 bytes 28 + * # Bytes // Field Name Offset 29 + * # ---------------------------------------------------------------------------------- 30 + * # 🮥 0x05, 0x01, // Usage Page (Generic Desktop) 0 31 + * # 🭬 0x09, 0x0e, // Usage (System Multi-Axis Controller) 2 32 + * # 0xa1, 0x01, // Collection (Application) 4 33 + * # ┅ 0x85, 0x03, // Report ID (3) 6 34 + * # 🮥 0x05, 0x0d, // Usage Page (Digitizers) 8 35 + * # 0x75, 0x08, // Report Size (8) 10 36 + * # 0x95, 0x01, // Report Count (1) 12 37 + * # ┇ 0x81, 0x01, // Input (Cnst,Arr,Abs) 14 38 + * # 🭬 0x09, 0x21, // Usage (Puck) 16 39 + * # 0xa1, 0x02, // Collection (Logical) 18 40 + * # 0x15, 0x00, // Logical Minimum (0) 20 41 + * # 0x25, 0x01, // Logical Maximum (1) 22 42 + * # 0x75, 0x01, // Report Size (1) 24 43 + * # 0x95, 0x01, // Report Count (1) 26 44 + * # 0xa1, 0x00, // Collection (Physical) 28 45 + * # 🮥 0x05, 0x09, // Usage Page (Button) 30 46 + * # 🭬 0x09, 0x01, // Usage (Button 1) 32 47 + * # ┇ 0x81, 0x02, // Input (Data,Var,Abs) 34 48 + * # 🮥 0x05, 0x0d, // Usage Page (Digitizers) 36 49 + * # 🭬 0x09, 0x33, // Usage (Touch) 38 50 + * # ┇ 0x81, 0x02, // Input (Data,Var,Abs) 40 51 + * # 0x95, 0x06, // Report Count (6) 42 52 + * # ┇ 0x81, 0x03, // Input (Cnst,Var,Abs) 44 53 + * # 0xa1, 0x02, // Collection (Logical) 46 54 + * # 🮥 0x05, 0x01, // Usage Page (Generic Desktop) 48 55 + * # 🭬 0x09, 0x37, // Usage (Dial) 50 56 + * # 0x16, 0x00, 0x80, // Logical Minimum (32768) 52 57 + * # 0x26, 0xff, 0x7f, // Logical Maximum (32767) 55 58 + * # 0x75, 0x10, // Report Size (16) 58 59 + * # 0x95, 0x01, // Report Count (1) 60 60 + * # ┇ 0x81, 0x06, // Input (Data,Var,Rel) 62 61 + * # 0x35, 0x00, // Physical Minimum (0) 64 62 + * # 0x46, 0x10, 0x0e, // Physical Maximum (3600) 66 63 + * # 0x15, 0x00, // Logical Minimum (0) 69 64 + * # 0x26, 0x10, 0x0e, // Logical Maximum (3600) 71 65 + * # 🭬 0x09, 0x48, // Usage (Resolution Multiplier) 74 66 + * # ║ 0xb1, 0x02, // Feature (Data,Var,Abs) 76 67 + * # 0x45, 0x00, // Physical Maximum (0) 78 68 + * # 0xc0, // End Collection 80 69 + * # 0x75, 0x08, // Report Size (8) 81 70 + * # 0x95, 0x01, // Report Count (1) 83 71 + * # ┇ 0x81, 0x01, // Input (Cnst,Arr,Abs) 85 72 + * # 0x75, 0x08, // Report Size (8) 87 73 + * # 0x95, 0x01, // Report Count (1) 89 74 + * # ┇ 0x81, 0x01, // Input (Cnst,Arr,Abs) 91 75 + * # 0x75, 0x08, // Report Size (8) 93 76 + * # 0x95, 0x01, // Report Count (1) 95 77 + * # ┇ 0x81, 0x01, // Input (Cnst,Arr,Abs) 97 78 + * # 0x75, 0x08, // Report Size (8) 99 79 + * # 0x95, 0x01, // Report Count (1) 101 80 + * # ┇ 0x81, 0x01, // Input (Cnst,Arr,Abs) 103 81 + * # 0x75, 0x08, // Report Size (8) 105 82 + * # 0x95, 0x01, // Report Count (1) 107 83 + * # ┇ 0x81, 0x01, // Input (Cnst,Arr,Abs) 109 84 + * # 0xc0, // End Collection 111 85 + * # 0xc0, // End Collection 112 86 + * # 0xc0, // End Collection 113 87 + * R: 114 05 01 09 0e a1 01 85 03 05 0d 75 08 95 01 81 01 09 21 a1 02 15 00 25 01 75 01 95 01 a1 00 05 09 09 01 81 02 05 0d 09 33 81 02 95 06 81 03 a1 02 05 01 09 37 16 00 80 26 ff 7f 75 10 95 01 81 06 35 00 46 10 0e 15 00 26 10 0e 09 48 b1 02 45 00 c0 75 08 95 01 81 01 75 08 95 01 81 01 75 08 95 01 81 01 75 08 95 01 81 01 75 08 95 01 81 01 c0 c0 c0 88 + * N: Keydial mini-050 89 + * I: 5 256c 8251 90 + * 91 + * The second hidraw node is what sends events: 92 + * 93 + * # Keydial mini-050 94 + * # Report descriptor length: 160 bytes 95 + * # Bytes // Field Name Offset 96 + * # ---------------------------------------------------------------------------------- 97 + * # 🮥 0x05, 0x01, // Usage Page (Generic Desktop) 0 98 + * # 🭬 0x09, 0x06, // Usage (Keyboard) 2 99 + * # 0xa1, 0x01, // Collection (Application) 4 100 + * # ┅ 0x85, 0x01, // Report ID (1) 6 101 + * # 🮥 0x05, 0x07, // Usage Page (Keyboard/Keypad) 8 102 + * # 🭬 0x19, 0xe0, // Usage Minimum (224) 10 103 + * # 🭬 0x29, 0xe7, // Usage Maximum (231) 12 104 + * # 0x15, 0x00, // Logical Minimum (0) 14 105 + * # 0x25, 0x01, // Logical Maximum (1) 16 106 + * # 0x75, 0x01, // Report Size (1) 18 107 + * # 0x95, 0x08, // Report Count (8) 20 108 + * # ┇ 0x81, 0x02, // Input (Data,Var,Abs) 22 109 + * # 0x95, 0x01, // Report Count (1) 24 110 + * # 0x75, 0x08, // Report Size (8) 26 111 + * # ┇ 0x81, 0x01, // Input (Cnst,Arr,Abs) 28 112 + * # 0x95, 0x05, // Report Count (5) 30 113 + * # 0x75, 0x01, // Report Size (1) 32 114 + * # 🮥 0x05, 0x08, // Usage Page (LED) 34 115 + * # 🭬 0x19, 0x01, // Usage Minimum (1) 36 116 + * # 🭬 0x29, 0x05, // Usage Maximum (5) 38 117 + * # ┊ 0x91, 0x02, // Output (Data,Var,Abs) 40 118 + * # 0x95, 0x01, // Report Count (1) 42 119 + * # 0x75, 0x03, // Report Size (3) 44 120 + * # ┊ 0x91, 0x01, // Output (Cnst,Arr,Abs) 46 121 + * # 0x95, 0x06, // Report Count (6) 48 122 + * # 0x75, 0x08, // Report Size (8) 50 123 + * # 0x15, 0x00, // Logical Minimum (0) 52 124 + * # 0x25, 0xf1, // Logical Maximum (241) 54 125 + * # 🮥 0x05, 0x07, // Usage Page (Keyboard/Keypad) 56 126 + * # 🭬 0x19, 0x00, // Usage Minimum (0) 58 127 + * # 🭬 0x29, 0xf1, // Usage Maximum (241) 60 128 + * # ┇ 0x81, 0x00, // Input (Data,Arr,Abs) 62 129 + * # 0xc0, // End Collection 64 130 + * # 🮥 0x05, 0x0c, // Usage Page (Consumer) 65 131 + * # 🭬 0x09, 0x01, // Usage (Consumer Control) 67 132 + * # 0xa1, 0x01, // Collection (Application) 69 133 + * # ┅ 0x85, 0x02, // Report ID (2) 71 134 + * # 🮥 0x05, 0x0c, // Usage Page (Consumer) 73 135 + * # 🭬 0x19, 0x00, // Usage Minimum (0) 75 136 + * # 🭬 0x2a, 0x80, 0x03, // Usage Maximum (896) 77 137 + * # 0x15, 0x00, // Logical Minimum (0) 80 138 + * # 0x26, 0x80, 0x03, // Logical Maximum (896) 82 139 + * # 0x75, 0x10, // Report Size (16) 85 140 + * # 0x95, 0x01, // Report Count (1) 87 141 + * # ┇ 0x81, 0x00, // Input (Data,Arr,Abs) 89 142 + * # 0xc0, // End Collection 91 143 + * # 🮥 0x05, 0x01, // Usage Page (Generic Desktop) 92 144 + * # 🭬 0x09, 0x02, // Usage (Mouse) 94 145 + * # 0xa1, 0x01, // Collection (Application) 96 146 + * # 🭬 0x09, 0x01, // Usage (Pointer) 98 147 + * # ┅ 0x85, 0x05, // Report ID (5) 100 148 + * # 0xa1, 0x00, // Collection (Physical) 102 149 + * # 🮥 0x05, 0x09, // Usage Page (Button) 104 150 + * # 🭬 0x19, 0x01, // Usage Minimum (1) 106 151 + * # 🭬 0x29, 0x05, // Usage Maximum (5) 108 152 + * # 0x15, 0x00, // Logical Minimum (0) 110 153 + * # 0x25, 0x01, // Logical Maximum (1) 112 154 + * # 0x95, 0x05, // Report Count (5) 114 155 + * # 0x75, 0x01, // Report Size (1) 116 156 + * # ┇ 0x81, 0x02, // Input (Data,Var,Abs) 118 157 + * # 0x95, 0x01, // Report Count (1) 120 158 + * # 0x75, 0x03, // Report Size (3) 122 159 + * # ┇ 0x81, 0x01, // Input (Cnst,Arr,Abs) 124 160 + * # 🮥 0x05, 0x01, // Usage Page (Generic Desktop) 126 161 + * # 🭬 0x09, 0x30, // Usage (X) 128 162 + * # 🭬 0x09, 0x31, // Usage (Y) 130 163 + * # 0x16, 0x01, 0x80, // Logical Minimum (32769) 132 164 + * # 0x26, 0xff, 0x7f, // Logical Maximum (32767) 135 165 + * # 0x75, 0x10, // Report Size (16) 138 166 + * # 0x95, 0x02, // Report Count (2) 140 167 + * # ┇ 0x81, 0x06, // Input (Data,Var,Rel) 142 168 + * # 🮥 0x05, 0x01, // Usage Page (Generic Desktop) 144 169 + * # 🭬 0x09, 0x38, // Usage (Wheel) 146 170 + * # 0x15, 0x81, // Logical Minimum (129) 148 171 + * # 0x25, 0x7f, // Logical Maximum (127) 150 172 + * # 0x95, 0x01, // Report Count (1) 152 173 + * # 0x75, 0x08, // Report Size (8) 154 174 + * # ┇ 0x81, 0x06, // Input (Data,Var,Rel) 156 175 + * # 0xc0, // End Collection 158 176 + * # 0xc0, // End Collection 159 177 + * R: 160 05 01 09 06 a1 01 85 01 05 07 19 e0 29 e7 15 00 25 01 75 01 95 08 81 02 95 01 75 08 81 01 95 05 75 01 05 08 19 01 29 05 91 02 95 01 75 03 91 01 95 06 75 08 15 00 25 f1 05 07 19 00 29 f1 81 00 c0 05 0c 09 01 a1 01 85 02 05 0c 19 00 2a 80 03 15 00 26 80 03 75 10 95 01 81 00 c0 05 01 09 02 a1 01 09 01 85 05 a1 00 05 09 19 01 29 05 15 00 25 01 95 05 75 01 81 02 95 01 75 03 81 01 05 01 09 30 09 31 16 01 80 26 ff 7f 75 10 95 02 81 06 05 01 09 38 15 81 25 7f 95 01 75 08 81 06 c0 c0 178 + * N: Keydial mini-050 179 + * I: 5 256c 8251 180 + * # Report descriptor: 181 + * # ------- Input Report ------- 182 + * # ░ Report ID: 1 183 + * # ░ | Report size: 72 bits 184 + * # ░ Bit: 8 Usage: 0007/00e0: Keyboard/Keypad / Keyboard LeftControl Logical Range: 0..=1 185 + * # ░ Bit: 9 Usage: 0007/00e1: Keyboard/Keypad / Keyboard LeftShift Logical Range: 0..=1 186 + * # ░ Bit: 10 Usage: 0007/00e2: Keyboard/Keypad / Keyboard LeftAlt Logical Range: 0..=1 187 + * # ░ Bit: 11 Usage: 0007/00e3: Keyboard/Keypad / Keyboard Left GUI Logical Range: 0..=1 188 + * # ░ Bit: 12 Usage: 0007/00e4: Keyboard/Keypad / Keyboard RightControl Logical Range: 0..=1 189 + * # ░ Bit: 13 Usage: 0007/00e5: Keyboard/Keypad / Keyboard RightShift Logical Range: 0..=1 190 + * # ░ Bit: 14 Usage: 0007/00e6: Keyboard/Keypad / Keyboard RightAlt Logical Range: 0..=1 191 + * # ░ Bit: 15 Usage: 0007/00e7: Keyboard/Keypad / Keyboard Right GUI Logical Range: 0..=1 192 + * # ░ Bits: 16..=23 ######### Padding 193 + * # ░ Bits: 24..=71 Usages: Logical Range: 0..=241 194 + * # ░ 0007/0000: <unknown> 195 + * # ░ 0007/0001: Keyboard/Keypad / ErrorRollOver 196 + * # ░ 0007/0002: Keyboard/Keypad / POSTFail 197 + * # ░ 0007/0003: Keyboard/Keypad / ErrorUndefined 198 + * # ░ 0007/0004: Keyboard/Keypad / Keyboard A 199 + * # ░ ... use --full to see all usages 200 + * # ------- Input Report ------- 201 + * # ▒ Report ID: 2 202 + * # ▒ | Report size: 24 bits 203 + * # ▒ Bits: 8..=23 Usages: Logical Range: 0..=896 204 + * # ▒ 000c/0000: <unknown> 205 + * # ▒ 000c/0001: Consumer / Consumer Control 206 + * # ▒ 000c/0002: Consumer / Numeric Key Pad 207 + * # ▒ 000c/0003: Consumer / Programmable Buttons 208 + * # ▒ 000c/0004: Consumer / Microphone 209 + * # ▒ ... use --full to see all usages 210 + * # ------- Input Report ------- 211 + * # ▞ Report ID: 5 212 + * # ▞ | Report size: 56 bits 213 + * # ▞ Bit: 8 Usage: 0009/0001: Button / Button 1 Logical Range: 0..=1 214 + * # ▞ Bit: 9 Usage: 0009/0002: Button / Button 2 Logical Range: 0..=1 215 + * # ▞ Bit: 10 Usage: 0009/0003: Button / Button 3 Logical Range: 0..=1 216 + * # ▞ Bit: 11 Usage: 0009/0004: Button / Button 4 Logical Range: 0..=1 217 + * # ▞ Bit: 12 Usage: 0009/0005: Button / Button 5 Logical Range: 0..=1 218 + * # ▞ Bits: 13..=15 ######### Padding 219 + * # ▞ Bits: 16..=31 Usage: 0001/0030: Generic Desktop / X Logical Range: 32769..=32767 220 + * # ▞ Bits: 32..=47 Usage: 0001/0031: Generic Desktop / Y Logical Range: 32769..=32767 221 + * # ▞ Bits: 48..=55 Usage: 0001/0038: Generic Desktop / Wheel Logical Range: 129..=127 222 + * # ------- Output Report ------- 223 + * # ░ Report ID: 1 224 + * # ░ | Report size: 16 bits 225 + * # ░ Bit: 8 Usage: 0008/0001: LED / Num Lock Logical Range: 0..=1 226 + * # ░ Bit: 9 Usage: 0008/0002: LED / Caps Lock Logical Range: 0..=1 227 + * # ░ Bit: 10 Usage: 0008/0003: LED / Scroll Lock Logical Range: 0..=1 228 + * # ░ Bit: 11 Usage: 0008/0004: LED / Compose Logical Range: 0..=1 229 + * # ░ Bit: 12 Usage: 0008/0005: LED / Kana Logical Range: 0..=1 230 + * # ░ Bits: 13..=15 ######### Padding 231 + * ############################################################################## 232 + * # Event nodes: 233 + * # - /dev/input/event12: "Keydial mini-050 Keyboard" 234 + * # - /dev/input/event14: "Keydial mini-050 Mouse" 235 + * ############################################################################## 236 + * # Recorded events below in format: 237 + * # E: <seconds>.<microseconds> <length-in-bytes> [bytes ...] 238 + * # 239 + * 240 + * - Report ID 1 sends keyboard shortcuts when pressing the buttons, e.g. 241 + * 242 + * # ░ Report ID: 1 / 243 + * # ░ Keyboard LeftControl: 0 |Keyboard LeftShift: 0 |Keyboard LeftAlt: 0 |Keyboard Left GUI: 0 |Keyboard RightControl: 0 |Keyboard RightShift: 0 |Keyboard RightAlt: 0 |Keyboard Right GUI: 0 |<8 bits padding> |0007/0000: 0| Keyboard K: 14| 0007/0000: 0| 0007/0000: 0| 0007/0000: 0| 0007/0000: 0 244 + * E: 000000.000292 9 01 00 00 00 0e 00 00 00 00 245 + * 246 + * - Report ID 2 sends the button inside the wheel/dial thing 247 + * # ▒ Report ID: 2 / 248 + * # ▒ Play/Pause: 205 249 + * E: 000134.347845 3 02 cd 00 250 + * # ▒ Report ID: 2 / 251 + * # ▒ 000c/0000: 0 252 + * E: 000134.444965 3 02 00 00 253 + * 254 + * - Report ID 5 sends the wheel relative events (always a double-event with the second as zero) 255 + * # ▞ Report ID: 5 / 256 + * # ▞ Button 1: 0 |Button 2: 0 |Button 3: 0 |Button 4: 0 |Button 5: 0 |<3 bits padding> |X: 0 |Y: 0 |Wheel: 255 257 + * E: 000064.859915 7 05 00 00 00 00 00 ff 258 + * # ▞ Report ID: 5 / 259 + * # ▞ Button 1: 0 |Button 2: 0 |Button 3: 0 |Button 4: 0 |Button 5: 0 |<3 bits padding> |X: 0 |Y: 0 |Wheel: 0 260 + * E: 000064.882009 7 05 00 00 00 00 00 00 261 + */ 262 + 263 + #define BT_PAD_REPORT_DESCRIPTOR_LENGTH 160 264 + #define BT_PUCK_REPORT_DESCRIPTOR_LENGTH 114 // This one doesn't send events 265 + #define BT_PAD_KBD_REPORT_ID 1 266 + #define BT_PAD_CC_REPORT_ID 2 267 + #define BT_PAD_MOUSE_REPORT_ID 5 268 + #define BT_PAD_KBD_REPORT_LENGTH 9 269 + #define BT_PAD_CC_REPORT_LENGTH 3 270 + #define BT_PAD_MOUSE_REPORT_LENGTH 7 271 + #define OUR_REPORT_ID 11 /* "randomly" picked report ID for our reports */ 272 + 273 + __u32 last_button_state = 0; 274 + 275 + static const __u8 disabled_rdesc_puck[] = { 276 + FixedSizeVendorReport(BT_PUCK_REPORT_DESCRIPTOR_LENGTH) 277 + }; 278 + 279 + static const __u8 fixed_rdesc_pad[] = { 280 + UsagePage_GenericDesktop 281 + Usage_GD_Keypad 282 + CollectionApplication( 283 + // Byte 0 284 + ReportId(OUR_REPORT_ID) 285 + UsagePage_Digitizers 286 + Usage_Dig_TabletFunctionKeys 287 + CollectionPhysical( 288 + // Byte 1 is a button so we look like a tablet 289 + Usage_Dig_BarrelSwitch // BTN_STYLUS, needed so we get to be a tablet pad 290 + ReportCount(1) 291 + ReportSize(1) 292 + Input(Var|Abs) 293 + ReportCount(7) // Padding 294 + Input(Const) 295 + // Bytes 2/3 - x/y just exist so we get to be a tablet pad 296 + UsagePage_GenericDesktop 297 + Usage_GD_X 298 + Usage_GD_Y 299 + LogicalMinimum_i8(0x0) 300 + LogicalMaximum_i8(0x1) 301 + ReportCount(2) 302 + ReportSize(8) 303 + Input(Var|Abs) 304 + // Bytes 4-7 are the button state for 19 buttons + pad out to u32 305 + // We send the first 10 buttons as buttons 1-10 which is BTN_0 -> BTN_9 306 + UsagePage_Button 307 + UsageMinimum_i8(1) 308 + UsageMaximum_i8(10) 309 + LogicalMinimum_i8(0x0) 310 + LogicalMaximum_i8(0x1) 311 + ReportCount(10) 312 + ReportSize(1) 313 + Input(Var|Abs) 314 + // We send the other 9 buttons as buttons 0x31 and above -> BTN_A - BTN_TL2 315 + UsageMinimum_i8(0x31) 316 + UsageMaximum_i8(0x3a) 317 + ReportCount(9) 318 + ReportSize(1) 319 + Input(Var|Abs) 320 + ReportCount(13) 321 + ReportSize(1) 322 + Input(Const) // padding 323 + // Byte 8 is the wheel 324 + UsagePage_GenericDesktop 325 + Usage_GD_Wheel 326 + LogicalMinimum_i8(-1) 327 + LogicalMaximum_i8(1) 328 + ReportCount(1) 329 + ReportSize(8) 330 + Input(Var|Rel) 331 + ) 332 + // Make sure we match our original report length 333 + FixedSizeVendorReport(BT_PAD_KBD_REPORT_LENGTH) 334 + ) 335 + }; 336 + 337 + SEC(HID_BPF_RDESC_FIXUP) 338 + int BPF_PROG(k20_bt_fix_rdesc, struct hid_bpf_ctx *hctx) 339 + { 340 + __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, HID_MAX_DESCRIPTOR_SIZE /* size */); 341 + __s32 rdesc_size = hctx->size; 342 + 343 + if (!data) 344 + return 0; /* EPERM check */ 345 + 346 + if (rdesc_size == BT_PAD_REPORT_DESCRIPTOR_LENGTH) { 347 + __builtin_memcpy(data, fixed_rdesc_pad, sizeof(fixed_rdesc_pad)); 348 + return sizeof(fixed_rdesc_pad); 349 + } 350 + if (rdesc_size == BT_PUCK_REPORT_DESCRIPTOR_LENGTH) { 351 + // This hidraw node doesn't send anything and can be ignored 352 + __builtin_memcpy(data, disabled_rdesc_puck, sizeof(disabled_rdesc_puck)); 353 + return sizeof(disabled_rdesc_puck); 354 + } 355 + 356 + return 0; 357 + } 358 + 359 + SEC(HID_BPF_DEVICE_EVENT) 360 + int BPF_PROG(k20_bt_fix_events, struct hid_bpf_ctx *hctx) 361 + { 362 + __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 12 /* size */); 363 + struct pad_report { 364 + __u8 report_id; 365 + __u8 btn_stylus:1; 366 + __u8 pad:7; 367 + __u8 x; 368 + __u8 y; 369 + __u32 buttons; 370 + __u8 wheel; 371 + } __packed * pad_report = (struct pad_report *)data; 372 + 373 + if (!data) 374 + return 0; /* EPERM check */ 375 + 376 + /* Report ID 1 - Keyboard events (button presses) */ 377 + if (data[0] == BT_PAD_KBD_REPORT_ID) { 378 + const __u8 button_mapping[] = { 379 + 0x0e, /* Button 1: K */ 380 + 0x0a, /* Button 2: G */ 381 + 0x0f, /* Button 3: L */ 382 + 0x4c, /* Button 4: Delete */ 383 + 0x0c, /* Button 5: I */ 384 + 0x07, /* Button 6: D */ 385 + 0x05, /* Button 7: B */ 386 + 0x08, /* Button 8: E */ 387 + 0x16, /* Button 9: S */ 388 + 0x1d, /* Button 10: Z */ 389 + 0x06, /* Button 11: C */ 390 + 0x19, /* Button 12: V */ 391 + 0xff, /* Button 13: LeftControl */ 392 + 0xff, /* Button 14: LeftAlt */ 393 + 0xff, /* Button 15: LeftShift */ 394 + 0x28, /* Button 16: Return Enter */ 395 + 0x2c, /* Button 17: Spacebar */ 396 + 0x11, /* Button 18: N */ 397 + }; 398 + 399 + __u8 modifiers = data[1]; 400 + __u32 buttons = 0; 401 + 402 + if (modifiers & 0x01) { /* Control */ 403 + buttons |= BIT(12); 404 + } 405 + if (modifiers & 0x02) { /* Shift */ 406 + buttons |= BIT(14); 407 + } 408 + if (modifiers & 0x04) { /* Alt */ 409 + buttons |= BIT(13); 410 + } 411 + 412 + for (int i = 4; i < BT_PAD_KBD_REPORT_LENGTH; i++) { 413 + if (!data[i]) 414 + break; 415 + 416 + for (size_t b = 0; b < ARRAY_SIZE(button_mapping); b++) { 417 + if (data[i] != 0xff && data[i] == button_mapping[b]) { 418 + buttons |= BIT(b); 419 + break; 420 + } 421 + } 422 + } 423 + 424 + last_button_state = buttons; 425 + 426 + pad_report->report_id = OUR_REPORT_ID; 427 + pad_report->btn_stylus = 0; 428 + pad_report->x = 0; 429 + pad_report->y = 0; 430 + pad_report->buttons = buttons; 431 + pad_report->wheel = 0; 432 + 433 + return sizeof(struct pad_report); 434 + } 435 + 436 + /* Report ID 2 - Consumer control events (the button inside the wheel) */ 437 + if (data[0] == BT_PAD_CC_REPORT_ID) { 438 + const __u8 PlayPause = 0xcd; 439 + 440 + if (data[1] == PlayPause) 441 + last_button_state |= BIT(18); 442 + else 443 + last_button_state &= ~BIT(18); 444 + 445 + pad_report->report_id = OUR_REPORT_ID; 446 + pad_report->btn_stylus = 0; 447 + pad_report->x = 0; 448 + pad_report->y = 0; 449 + pad_report->buttons = last_button_state; 450 + pad_report->wheel = 0; 451 + 452 + return sizeof(struct pad_report); 453 + } 454 + 455 + /* Report ID 5 - Mouse events (wheel rotation) */ 456 + if (data[0] == BT_PAD_MOUSE_REPORT_ID) { 457 + __u8 wheel_delta = data[6]; 458 + 459 + pad_report->report_id = OUR_REPORT_ID; 460 + pad_report->btn_stylus = 0; 461 + pad_report->x = 0; 462 + pad_report->y = 0; 463 + pad_report->buttons = last_button_state; 464 + pad_report->wheel = wheel_delta; 465 + 466 + return sizeof(struct pad_report); 467 + } 468 + 469 + return 0; 470 + } 471 + 472 + HID_BPF_OPS(keydial_k20_bluetooth) = { 473 + .hid_device_event = (void *)k20_bt_fix_events, 474 + .hid_rdesc_fixup = (void *)k20_bt_fix_rdesc, 475 + }; 476 + 477 + SEC("syscall") 478 + int probe(struct hid_bpf_probe_args *ctx) 479 + { 480 + switch (ctx->rdesc_size) { 481 + case BT_PAD_REPORT_DESCRIPTOR_LENGTH: 482 + case BT_PUCK_REPORT_DESCRIPTOR_LENGTH: 483 + ctx->retval = 0; 484 + break; 485 + default: 486 + ctx->retval = -EINVAL; 487 + } 488 + 489 + return 0; 490 + } 491 + 492 + char _license[] SEC("license") = "GPL";
+2 -1
drivers/hid/bpf/progs/Huion__KeydialK20.bpf.c
··· 462 462 __u32 buttons; 463 463 __u8 wheel; 464 464 } __attribute__((packed)) *pad_report; 465 - int i, b; 465 + int i; 466 + size_t b; 466 467 __u8 modifiers = data[1]; 467 468 __u32 buttons = 0; 468 469
+1 -1
drivers/hid/bpf/progs/IOGEAR__Kaliber-MMOmentum.bpf.c
··· 34 34 if (data[3] != 0x06) 35 35 return 0; 36 36 37 - for (int idx = 0; idx < ARRAY_SIZE(offsets); idx++) { 37 + for (size_t idx = 0; idx < ARRAY_SIZE(offsets); idx++) { 38 38 u8 offset = offsets[idx]; 39 39 40 40 /* if Input (Cnst,Var,Abs) , make it Input (Data,Var,Abs) */
+49
drivers/hid/bpf/progs/Trust__Philips-SPK6327.bpf.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* Fix for Trust Philips SPK6327 (145f:024b) 3 + * Modifier keys report as Array (0x00) instead of Variable (0x02) 4 + * causing LCtrl, LAlt, Super etc. to all act as LShift 5 + */ 6 + #include "vmlinux.h" 7 + #include "hid_bpf.h" 8 + #include "hid_bpf_helpers.h" 9 + #include <bpf/bpf_tracing.h> 10 + 11 + #define VID_TRUST 0x145F 12 + #define PID_SPK6327 0x024B 13 + 14 + HID_BPF_CONFIG( 15 + HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, VID_TRUST, PID_SPK6327) 16 + ); 17 + 18 + SEC(HID_BPF_RDESC_FIXUP) 19 + int BPF_PROG(hid_fix_rdesc, struct hid_bpf_ctx *hctx) 20 + { 21 + __u8 *data = hid_bpf_get_data(hctx, 0, 4096); 22 + 23 + if (!data) 24 + return 0; 25 + 26 + /* Fix modifier keys: Input Array (0x00) -> Input Variable (0x02) */ 27 + if (data[101] == 0x00) 28 + data[101] = 0x02; 29 + 30 + return 0; 31 + } 32 + 33 + HID_BPF_OPS(trust_spk6327) = { 34 + .hid_rdesc_fixup = (void *)hid_fix_rdesc, 35 + }; 36 + 37 + SEC("syscall") 38 + int probe(struct hid_bpf_probe_args *ctx) 39 + { 40 + /* Only apply to interface 1 (169 bytes) not interface 0 (62 bytes) */ 41 + if (ctx->rdesc_size == 169) 42 + ctx->retval = 0; 43 + else 44 + ctx->retval = -EINVAL; 45 + 46 + return 0; 47 + } 48 + 49 + char _license[] SEC("license") = "GPL";
+1 -1
drivers/hid/bpf/progs/Wacom__ArtPen.bpf.c
··· 148 148 { 149 149 struct hid_bpf_ctx *hid_ctx; 150 150 __u16 pid; 151 - int i; 151 + size_t i; 152 152 153 153 /* get a struct hid_device to access the actual pid of the device */ 154 154 hid_ctx = hid_bpf_allocate_context(ctx->hid);
+1 -1
drivers/hid/bpf/progs/XPPen__DecoMini4.bpf.c
··· 173 173 { 174 174 __u8 *data = hid_bpf_get_data(hctx, 0 /* offset */, 8 /* size */); 175 175 __u8 button_mask = 0; 176 - int d, b; 176 + size_t d, b; 177 177 178 178 if (!data) 179 179 return 0; /* EPERM check */
+18 -18
drivers/hid/bpf/progs/hid_bpf_async.h
··· 116 116 if (!elem) 117 117 return -ENOMEM; /* should never happen */ 118 118 119 - bpf_spin_lock(&elem->lock); 119 + { 120 + guard(bpf_spin)(&elem->lock); 120 121 121 - if (elem->state == HID_BPF_ASYNC_STATE_UNSET) { 122 - elem->state = HID_BPF_ASYNC_STATE_INITIALIZING; 123 - bpf_spin_unlock(&elem->lock); 124 - return i; 122 + if (elem->state == HID_BPF_ASYNC_STATE_UNSET) { 123 + elem->state = HID_BPF_ASYNC_STATE_INITIALIZING; 124 + return i; 125 + } 125 126 } 126 - 127 - bpf_spin_unlock(&elem->lock); 128 127 } 129 128 130 129 return -EINVAL; ··· 174 175 if (!elem) 175 176 return -EINVAL; 176 177 177 - bpf_spin_lock(&elem->lock); 178 - /* The wq must be: 179 - * - HID_BPF_ASYNC_STATE_INITIALIZED -> it's been initialized and ready to be called 180 - * - HID_BPF_ASYNC_STATE_RUNNING -> possible re-entry from the wq itself 181 - */ 182 - if (elem->state != HID_BPF_ASYNC_STATE_INITIALIZED && 183 - elem->state != HID_BPF_ASYNC_STATE_RUNNING) { 184 - bpf_spin_unlock(&elem->lock); 185 - return -EINVAL; 178 + { 179 + guard(bpf_spin)(&elem->lock); 180 + 181 + /* The wq must be: 182 + * - HID_BPF_ASYNC_STATE_INITIALIZED -> it's been initialized and ready to be called 183 + * - HID_BPF_ASYNC_STATE_RUNNING -> possible re-entry from the wq itself 184 + */ 185 + if (elem->state != HID_BPF_ASYNC_STATE_INITIALIZED && 186 + elem->state != HID_BPF_ASYNC_STATE_RUNNING) 187 + return -EINVAL; 188 + 189 + elem->state = HID_BPF_ASYNC_STATE_STARTING; 186 190 } 187 - elem->state = HID_BPF_ASYNC_STATE_STARTING; 188 - bpf_spin_unlock(&elem->lock); 189 191 190 192 elem->hid = hctx->hid->id; 191 193
+321
drivers/hid/bpf/progs/hid_bpf_helpers.h
··· 7 7 8 8 #include "vmlinux.h" 9 9 #include <bpf/bpf_helpers.h> 10 + #include <bpf/bpf_endian.h> 10 11 #include <linux/errno.h> 12 + #include "hid_report_descriptor_helpers.h" 13 + 14 + /* Compiler attributes */ 15 + #ifndef __packed 16 + #define __packed __attribute__((packed)) 17 + #endif 18 + 19 + #ifndef __maybe_unused 20 + #define __maybe_unused __attribute__((__unused__)) 21 + #endif 11 22 12 23 extern __u8 *hid_bpf_get_data(struct hid_bpf_ctx *ctx, 13 24 unsigned int offset, ··· 50 39 51 40 #define HID_MAX_DESCRIPTOR_SIZE 4096 52 41 #define HID_IGNORE_EVENT -1 42 + 43 + /** 44 + * Use: _cleanup_(somefunction) struct foo *bar; 45 + */ 46 + #define _cleanup_(_x) __attribute__((cleanup(_x))) 47 + 48 + /** 49 + * Use: _release_(foo) *bar; 50 + * 51 + * This requires foo_releasep() to be present, use DEFINE_RELEASE_CLEANUP_FUNC. 52 + */ 53 + #define _release_(_type) struct _type __attribute__((cleanup(_type##_releasep))) 54 + 55 + /** 56 + * Define a cleanup function for the struct type foo with a matching 57 + * foo_release(). Use: 58 + * DEFINE_RELEASE_CLEANUP_FUNC(foo) 59 + * _unref_(foo) struct foo *bar; 60 + */ 61 + #define DEFINE_RELEASE_CLEANUP_FUNC(_type) \ 62 + static inline void _type##_releasep(struct _type **_p) { \ 63 + if (*_p) \ 64 + _type##_release(*_p); \ 65 + } \ 66 + struct __useless_struct_to_allow_trailing_semicolon__ 67 + 68 + /* for being able to have a cleanup function */ 69 + #define hid_bpf_ctx_release hid_bpf_release_context 70 + DEFINE_RELEASE_CLEANUP_FUNC(hid_bpf_ctx); 71 + 72 + /* 73 + * Kernel-style guard macros adapted for BPF 74 + * Based on include/linux/cleanup.h from the Linux kernel 75 + * 76 + * These provide automatic lock/unlock using __attribute__((cleanup)) 77 + * similar to how _release_() works for contexts. 78 + */ 79 + 80 + /** 81 + * DEFINE_GUARD(name, type, lock, unlock): 82 + * Define a guard for automatic lock/unlock using the same pattern as _release_() 83 + * @name: identifier for the guard (e.g., bpf_spin) 84 + * @type: lock variable type (e.g., struct bpf_spin_lock) 85 + * @lock: lock function name (e.g., bpf_spin_lock) 86 + * @unlock: unlock function name (e.g., bpf_spin_unlock) 87 + * 88 + * guard(name): 89 + * Declare and lock in one statement - lock held until end of scope 90 + * 91 + * Example: 92 + * DEFINE_GUARD(bpf_spin, struct bpf_spin_lock, bpf_spin_lock, bpf_spin_unlock) 93 + * 94 + * void foo(struct bpf_spin_lock *lock) { 95 + * guard(bpf_spin)(lock); 96 + * // lock held until end of scope 97 + * } 98 + */ 99 + 100 + /* Guard helper struct - stores lock pointer for cleanup */ 101 + #define DEFINE_GUARD(_name, _type, _lock, _unlock) \ 102 + struct _name##_guard { \ 103 + _type *lock; \ 104 + }; \ 105 + static inline void _name##_guard_cleanup(struct _name##_guard *g) { \ 106 + if (g && g->lock) \ 107 + _unlock(g->lock); \ 108 + } \ 109 + static inline struct _name##_guard _name##_guard_init(_type *l) { \ 110 + if (l) \ 111 + _lock(l); \ 112 + return (struct _name##_guard){.lock = l}; \ 113 + } \ 114 + struct __useless_struct_to_allow_trailing_semicolon__ 115 + 116 + #define guard(_name) \ 117 + struct _name##_guard COMBINE(guard, __LINE__) __attribute__((cleanup(_name##_guard_cleanup))) = \ 118 + _name##_guard_init 119 + 120 + /* Define BPF spinlock guard */ 121 + DEFINE_GUARD(bpf_spin, struct bpf_spin_lock, bpf_spin_lock, bpf_spin_unlock); 53 122 54 123 /* extracted from <linux/input.h> */ 55 124 #define BUS_ANY 0x00 ··· 273 182 #define HID_BPF_CONFIG(...) union { \ 274 183 _EXPAND(_ARG, __VA_ARGS__) \ 275 184 } _device_ids SEC(".hid_bpf_config") 185 + 186 + 187 + /* Equivalency macros for bpf_htons and friends which are 188 + * Big Endian only - HID needs little endian so these are the 189 + * corresponding macros for that. See bpf/bpf_endian.h 190 + */ 191 + #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 192 + # define __hid_bpf_le16_to_cpu(x) (x) 193 + # define __hid_bpf_le32_to_cpu(x) (x) 194 + # define __hid_bpf_le64_to_cpu(x) (x) 195 + # define __hid_bpf_cpu_to_le16(x) (x) 196 + # define __hid_bpf_cpu_to_le32(x) (x) 197 + # define __hid_bpf_cpu_to_le64(x) (x) 198 + # define __hid_bpf_constant_le16_to_cpu(x) (x) 199 + # define __hid_bpf_constant_le32_to_cpu(x) (x) 200 + # define __hid_bpf_constant_le64_to_cpu(x) (x) 201 + # define __hid_bpf_constant_cpu_to_le16(x) (x) 202 + # define __hid_bpf_constant_cpu_to_le32(x) (x) 203 + # define __hid_bpf_constant_cpu_to_le64(x) (x) 204 + #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 205 + # define __hid_bpf_le16_to_cpu(x) __builtin_bswap16(x) 206 + # define __hid_bpf_le32_to_cpu(x) __builtin_bswap32(x) 207 + # define __hid_bpf_le64_to_cpu(x) __builtin_bswap64(x) 208 + # define __hid_bpf_cpu_to_le16(x) __builtin_bswap16(x) 209 + # define __hid_bpf_cpu_to_le32(x) __builtin_bswap32(x) 210 + # define __hid_bpf_cpu_to_le64(x) __builtin_bswap64(x) 211 + # define __hid_bpf_constant_le16_to_cpu(x) __bpf_swab16(x) 212 + # define __hid_bpf_constant_le32_to_cpu(x) __bpf_swab32(x) 213 + # define __hid_bpf_constant_le64_to_cpu(x) __bpf_swab64(x) 214 + # define __hid_bpf_constant_cpu_to_le16(x) __bpf_swab16(x) 215 + # define __hid_bpf_constant_cpu_to_le32(x) __bpf_swab32(x) 216 + # define __hid_bpf_constant_cpu_to_le64(x) __bpf_swab64(x) 217 + #else 218 + # error "Invalid __BYTE_ORDER__" 219 + #endif 220 + 221 + #define hid_bpf_le16_to_cpu(x) \ 222 + (__builtin_constant_p(x) ? \ 223 + __hid_bpf_constant_le16_to_cpu(x) : __hid_bpf_le16_to_cpu(x)) 224 + 225 + #define hid_bpf_le32_to_cpu(x) \ 226 + (__builtin_constant_p(x) ? \ 227 + __hid_bpf_constant_le32_to_cpu(x) : __hid_bpf_le32_to_cpu(x)) 228 + 229 + #define hid_bpf_le64_to_cpu(x) \ 230 + (__builtin_constant_p(x) ? \ 231 + __hid_bpf_constant_le64_to_cpu(x) : __hid_bpf_le64_to_cpu(x)) 232 + 233 + #define hid_bpf_cpu_to_le16(x) \ 234 + (__builtin_constant_p(x) ? \ 235 + __hid_bpf_constant_cpu_to_le16(x) : __hid_bpf_cpu_to_le16(x)) 236 + 237 + #define hid_bpf_cpu_to_le32(x) \ 238 + (__builtin_constant_p(x) ? \ 239 + __hid_bpf_constant_cpu_to_le32(x) : __hid_bpf_cpu_to_le32(x)) 240 + 241 + #define hid_bpf_cpu_to_le64(x) \ 242 + (__builtin_constant_p(x) ? \ 243 + __hid_bpf_constant_cpu_to_le64(x) : __hid_bpf_cpu_to_le64(x)) 244 + 245 + #define hid_bpf_be16_to_cpu(x) bpf_ntohs(x) 246 + #define hid_bpf_be32_to_cpu(x) bpf_ntohl(x) 247 + #define hid_bpf_be64_to_cpu(x) bpf_be64_to_cpu(x) 248 + #define hid_bpf_cpu_to_be16(x) bpf_htons(x) 249 + #define hid_bpf_cpu_to_be32(x) bpf_htonl(x) 250 + #define hid_bpf_cpu_to_be64(x) bpf_cpu_to_be64(x) 251 + 252 + /* 253 + * The following macros are helpers for exporting udev properties: 254 + * 255 + * EXPORT_UDEV_PROP(name, len) generates: 256 + * - a map with a single element UDEV_PROP_##name, of size len 257 + * - a const global declaration of that len: SIZEOF_##name 258 + * 259 + * udev_prop_ptr(name) retrieves the data pointer behind the map. 260 + * 261 + * UDEV_PROP_SPRINTF(name, fmt, ...) writes data into the udev property. 262 + * 263 + * Can be used as such: 264 + * EXPORT_UDEV_PROP(HID_FOO, 32); 265 + * 266 + * SEC("syscall") 267 + * int probe(struct hid_bpf_probe_args *ctx) 268 + * { 269 + * const char *foo = "foo"; 270 + * UDEV_PROP_SPRINTF(HID_FOO, "%s", foo); 271 + * 272 + * return 0; 273 + * } 274 + */ 275 + #define EXPORT_UDEV_PROP(name, len) \ 276 + const __u32 SIZEOF_##name = len; \ 277 + struct COMBINE(udev_prop, __LINE__) { \ 278 + __uint(type, BPF_MAP_TYPE_ARRAY); \ 279 + __uint(max_entries, 1); \ 280 + __type(key, __u32); \ 281 + __type(value, __u8[len]); \ 282 + } UDEV_PROP_##name SEC(".maps"); 283 + 284 + #define udev_prop_ptr(name) \ 285 + bpf_map_lookup_elem(&UDEV_PROP_##name, &(__u32){0}) 286 + 287 + #define UDEV_PROP_SPRINTF(name, fmt, ...) \ 288 + BPF_SNPRINTF(udev_prop_ptr(name), SIZEOF_##name, fmt, ##__VA_ARGS__) 289 + 290 + static inline __maybe_unused __u16 field_start_byte(struct hid_rdesc_field *field) 291 + { 292 + return field->bits_start / 8; 293 + } 294 + 295 + static inline __maybe_unused __u16 field_end_byte(struct hid_rdesc_field *field) 296 + { 297 + if (!field->bits_end) 298 + return 0; 299 + 300 + return (__u16)(field->bits_end - 1) / 8; 301 + } 302 + 303 + static __maybe_unused __u32 extract_bits(__u8 *buffer, const size_t size, struct hid_rdesc_field *field) 304 + { 305 + __s32 nbits = field->bits_end - field->bits_start; 306 + __u32 start = field_start_byte(field); 307 + __u32 end = field_end_byte(field); 308 + __u8 base_shift = field->bits_start % 8; 309 + 310 + if (nbits <= 0 || nbits > 32 || start >= size || end >= size) 311 + return 0; 312 + 313 + /* Fast path for byte-aligned standard-sized reads */ 314 + if (base_shift == 0) { 315 + /* 8-bit aligned read */ 316 + if (nbits == 8 && start < size) 317 + return buffer[start]; 318 + 319 + /* 16-bit aligned read - use separate variables for verifier */ 320 + if (nbits == 16) { 321 + __u32 off0 = start; 322 + __u32 off1 = start + 1; 323 + 324 + if (off0 < size && off1 < size) { 325 + return buffer[off0] | 326 + ((__u32)buffer[off1] << 8); 327 + } 328 + } 329 + 330 + /* 32-bit aligned read - use separate variables for verifier */ 331 + if (nbits == 32) { 332 + __u32 off0 = start; 333 + __u32 off1 = start + 1; 334 + __u32 off2 = start + 2; 335 + __u32 off3 = start + 3; 336 + 337 + if (off0 < size && off1 < size && 338 + off2 < size && off3 < size) { 339 + return buffer[off0] | 340 + ((__u32)buffer[off1] << 8) | 341 + ((__u32)buffer[off2] << 16) | 342 + ((__u32)buffer[off3] << 24); 343 + } 344 + } 345 + } 346 + 347 + /* General case: bit manipulation for unaligned or non-standard sizes */ 348 + int mask = 0xffffffff >> (32 - nbits); 349 + __u64 value = 0; 350 + __u32 i; 351 + 352 + bpf_for (i, start, end + 1) { 353 + value |= (__u64)buffer[i] << ((i - start) * 8); 354 + } 355 + 356 + return (value >> base_shift) & mask; 357 + } 358 + 359 + #define EXTRACT_BITS(buffer, field) extract_bits(buffer, sizeof(buffer), field) 360 + 361 + /* Base macro for iterating over HID arrays with bounds checking. 362 + * Follows the bpf_for pattern from libbpf. 363 + */ 364 + #define __hid_bpf_for_each_array(array, num_elements, max_elements, var) \ 365 + for ( \ 366 + /* initialize and define destructor */ \ 367 + struct bpf_iter_num ___it __attribute__((aligned(8), \ 368 + cleanup(bpf_iter_num_destroy))), \ 369 + /* ___p pointer is necessary to call bpf_iter_num_new() *once* */ \ 370 + *___p __attribute__((unused)) = ( \ 371 + /* always initialize iterator; if bounds fail, iterate 0 times */ \ 372 + bpf_iter_num_new(&___it, 0, \ 373 + (num_elements) > (max_elements) ? \ 374 + 0 : (num_elements)), \ 375 + /* workaround for Clang bug */ \ 376 + (void)bpf_iter_num_destroy, (void *)0); \ 377 + ({ \ 378 + /* iteration step */ \ 379 + int *___t = bpf_iter_num_next(&___it); \ 380 + int ___i; \ 381 + /* termination and bounds check, assign var */ \ 382 + (___t && (___i = *___t, ___i >= 0 && ___i < (num_elements)) && \ 383 + ((num_elements) <= (max_elements)) && \ 384 + (var = &(array)[___i], 1)); \ 385 + }); \ 386 + ) 387 + 388 + /* Iterate over input reports in a descriptor */ 389 + #define hid_bpf_for_each_input_report(descriptor, report_var) \ 390 + __hid_bpf_for_each_array((descriptor)->input_reports, \ 391 + (descriptor)->num_input_reports, \ 392 + HID_MAX_REPORTS, report_var) 393 + 394 + /* Iterate over feature reports in a descriptor */ 395 + #define hid_bpf_for_each_feature_report(descriptor, report_var) \ 396 + __hid_bpf_for_each_array((descriptor)->feature_reports, \ 397 + (descriptor)->num_feature_reports, \ 398 + HID_MAX_REPORTS, report_var) 399 + 400 + /* Iterate over output reports in a descriptor */ 401 + #define hid_bpf_for_each_output_report(descriptor, report_var) \ 402 + __hid_bpf_for_each_array((descriptor)->output_reports, \ 403 + (descriptor)->num_output_reports, \ 404 + HID_MAX_REPORTS, report_var) 405 + 406 + /* Iterate over fields in a report */ 407 + #define hid_bpf_for_each_field(report, field_var) \ 408 + __hid_bpf_for_each_array((report)->fields, (report)->num_fields, \ 409 + HID_MAX_FIELDS, field_var) 410 + 411 + /* Iterate over collections in a field */ 412 + #define hid_bpf_for_each_collection(field, collection_var) \ 413 + __hid_bpf_for_each_array((field)->collections, (field)->num_collections, \ 414 + HID_MAX_COLLECTIONS, collection_var) 276 415 277 416 #endif /* __HID_BPF_HELPERS_H */
+80
drivers/hid/bpf/progs/hid_report_descriptor_helpers.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* Copyright (c) 2022 Benjamin Tissoires 3 + */ 4 + 5 + #ifndef __HID_REPORT_DESCRIPTOR_HELPERS_H 6 + #define __HID_REPORT_DESCRIPTOR_HELPERS_H 7 + 8 + #include "vmlinux.h" 9 + 10 + /* Compiler attributes */ 11 + #ifndef __packed 12 + #define __packed __attribute__((packed)) 13 + #endif 14 + 15 + #ifndef __maybe_unused 16 + #define __maybe_unused __attribute__((__unused__)) 17 + #endif 18 + 19 + /* Report Descriptor Structures */ 20 + #define HID_MAX_COLLECTIONS 32 21 + #define HID_MAX_FIELDS 64 22 + #define HID_MAX_REPORTS 16 23 + 24 + enum hid_rdesc_field_type { 25 + HID_FIELD_VARIABLE = 0, 26 + HID_FIELD_ARRAY = 1, 27 + HID_FIELD_CONSTANT = 2, 28 + }; 29 + 30 + struct hid_rdesc_collection { 31 + __u16 usage_page; 32 + __u16 usage_id; 33 + __u8 collection_type; 34 + } __packed; 35 + 36 + struct hid_rdesc_field { 37 + __u8 field_type; /* enum hid_rdesc_field_type */ 38 + __u8 num_collections; 39 + __u16 bits_start; 40 + __u16 bits_end; 41 + __u16 usage_page; 42 + union { 43 + __u16 usage_id; /* For Variable fields */ 44 + struct __packed { /* For Array fields */ 45 + __u16 usage_minimum; 46 + __u16 usage_maximum; 47 + }; 48 + }; 49 + __s32 logical_minimum; 50 + __s32 logical_maximum; 51 + struct { 52 + __u8 is_relative:1; /* Data is relative to previous value */ 53 + __u8 wraps:1; /* Value wraps around (e.g., rotary encoder) */ 54 + __u8 is_nonlinear:1; /* Non-linear relationship between logical/physical */ 55 + __u8 has_no_preferred_state:1; /* No rest position (e.g., free-floating joystick) */ 56 + __u8 has_null_state:1; /* Can report null/no-data values */ 57 + __u8 is_volatile:1; /* Volatile (Output/Feature) - NOT POPULATED, always 0 */ 58 + __u8 is_buffered_bytes:1; /* Fixed-size byte stream vs bitfield */ 59 + __u8 reserved:1; /* Reserved for future use */ 60 + } flags; 61 + struct hid_rdesc_collection collections[HID_MAX_COLLECTIONS]; 62 + } __packed; 63 + 64 + struct hid_rdesc_report { 65 + __u8 report_id; /* 0 means no report ID */ 66 + __u16 size_in_bits; 67 + __u8 num_fields; 68 + struct hid_rdesc_field fields[HID_MAX_FIELDS]; 69 + } __packed; 70 + 71 + struct hid_rdesc_descriptor { 72 + __u8 num_input_reports; 73 + __u8 num_output_reports; 74 + __u8 num_feature_reports; 75 + struct hid_rdesc_report input_reports[HID_MAX_REPORTS]; 76 + struct hid_rdesc_report output_reports[HID_MAX_REPORTS]; 77 + struct hid_rdesc_report feature_reports[HID_MAX_REPORTS]; 78 + } __packed; 79 + 80 + #endif /* __HID_REPORT_DESCRIPTOR_HELPERS_H */
+2810
drivers/hid/bpf/progs/hid_usages.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* Copyright (c) 2025 Red Hat, Inc 3 + */ 4 + 5 + // THIS FILE IS GENERATED, DO NOT EDIT 6 + 7 + #pragma once 8 + 9 + /* ----- Generated Usage Pages and Usages ------ */ 10 + #define HidUsagePage_GenericDesktop 0x01 11 + #define HidUsagePage_SimulationControls 0x02 12 + #define HidUsagePage_VRControls 0x03 13 + #define HidUsagePage_SportControls 0x04 14 + #define HidUsagePage_GameControls 0x05 15 + #define HidUsagePage_GenericDeviceControls 0x06 16 + #define HidUsagePage_KeyboardKeypad 0x07 17 + #define HidUsagePage_LED 0x08 18 + #define HidUsagePage_Button 0x09 19 + #define HidUsagePage_Ordinal 0x0a 20 + #define HidUsagePage_TelephonyDevice 0x0b 21 + #define HidUsagePage_Consumer 0x0c 22 + #define HidUsagePage_Digitizers 0x0d 23 + #define HidUsagePage_Haptics 0x0e 24 + #define HidUsagePage_PhysicalInputDevice 0x0f 25 + #define HidUsagePage_Unicode 0x10 26 + #define HidUsagePage_SoC 0x11 27 + #define HidUsagePage_EyeandHeadTrackers 0x12 28 + #define HidUsagePage_AuxiliaryDisplay 0x14 29 + #define HidUsagePage_Sensors 0x20 30 + #define HidUsagePage_MedicalInstrument 0x40 31 + #define HidUsagePage_BrailleDisplay 0x41 32 + #define HidUsagePage_LightingAndIllumination 0x59 33 + #define HidUsagePage_Monitor 0x80 34 + #define HidUsagePage_MonitorEnumerated 0x81 35 + #define HidUsagePage_VESAVirtualControls 0x82 36 + #define HidUsagePage_Power 0x84 37 + #define HidUsagePage_BatterySystem 0x85 38 + #define HidUsagePage_BarcodeScanner 0x8c 39 + #define HidUsagePage_Scales 0x8d 40 + #define HidUsagePage_MagneticStripeReader 0x8e 41 + #define HidUsagePage_CameraControl 0x90 42 + #define HidUsagePage_Arcade 0x91 43 + #define HidUsagePage_FIDOAlliance 0xf1d0 44 + 45 + #define HidUsage_GD_Pointer 0x01 46 + #define HidUsage_GD_Mouse 0x02 47 + #define HidUsage_GD_Joystick 0x04 48 + #define HidUsage_GD_Gamepad 0x05 49 + #define HidUsage_GD_Keyboard 0x06 50 + #define HidUsage_GD_Keypad 0x07 51 + #define HidUsage_GD_MultiaxisController 0x08 52 + #define HidUsage_GD_TabletPCSystemControls 0x09 53 + #define HidUsage_GD_WaterCoolingDevice 0x0a 54 + #define HidUsage_GD_ComputerChassisDevice 0x0b 55 + #define HidUsage_GD_WirelessRadioControls 0x0c 56 + #define HidUsage_GD_PortableDeviceControl 0x0d 57 + #define HidUsage_GD_SystemMultiAxisController 0x0e 58 + #define HidUsage_GD_SpatialController 0x0f 59 + #define HidUsage_GD_AssistiveControl 0x10 60 + #define HidUsage_GD_DeviceDock 0x11 61 + #define HidUsage_GD_DockableDevice 0x12 62 + #define HidUsage_GD_CallStateManagementControl 0x13 63 + #define HidUsage_GD_X 0x30 64 + #define HidUsage_GD_Y 0x31 65 + #define HidUsage_GD_Z 0x32 66 + #define HidUsage_GD_Rx 0x33 67 + #define HidUsage_GD_Ry 0x34 68 + #define HidUsage_GD_Rz 0x35 69 + #define HidUsage_GD_Slider 0x36 70 + #define HidUsage_GD_Dial 0x37 71 + #define HidUsage_GD_Wheel 0x38 72 + #define HidUsage_GD_HatSwitch 0x39 73 + #define HidUsage_GD_CountedBuffer 0x3a 74 + #define HidUsage_GD_ByteCount 0x3b 75 + #define HidUsage_GD_MotionWakeup 0x3c 76 + #define HidUsage_GD_Start 0x3d 77 + #define HidUsage_GD_Select 0x3e 78 + #define HidUsage_GD_Vx 0x40 79 + #define HidUsage_GD_Vy 0x41 80 + #define HidUsage_GD_Vz 0x42 81 + #define HidUsage_GD_Vbrx 0x43 82 + #define HidUsage_GD_Vbry 0x44 83 + #define HidUsage_GD_Vbrz 0x45 84 + #define HidUsage_GD_Vno 0x46 85 + #define HidUsage_GD_FeatureNotification 0x47 86 + #define HidUsage_GD_ResolutionMultiplier 0x48 87 + #define HidUsage_GD_Qx 0x49 88 + #define HidUsage_GD_Qy 0x4a 89 + #define HidUsage_GD_Qz 0x4b 90 + #define HidUsage_GD_Qw 0x4c 91 + #define HidUsage_GD_SystemControl 0x80 92 + #define HidUsage_GD_SystemPowerDown 0x81 93 + #define HidUsage_GD_SystemSleep 0x82 94 + #define HidUsage_GD_SystemWakeUp 0x83 95 + #define HidUsage_GD_SystemContextMenu 0x84 96 + #define HidUsage_GD_SystemMainMenu 0x85 97 + #define HidUsage_GD_SystemAppMenu 0x86 98 + #define HidUsage_GD_SystemMenuHelp 0x87 99 + #define HidUsage_GD_SystemMenuExit 0x88 100 + #define HidUsage_GD_SystemMenuSelect 0x89 101 + #define HidUsage_GD_SystemMenuRight 0x8a 102 + #define HidUsage_GD_SystemMenuLeft 0x8b 103 + #define HidUsage_GD_SystemMenuUp 0x8c 104 + #define HidUsage_GD_SystemMenuDown 0x8d 105 + #define HidUsage_GD_SystemColdRestart 0x8e 106 + #define HidUsage_GD_SystemWarmRestart 0x8f 107 + #define HidUsage_GD_DpadUp 0x90 108 + #define HidUsage_GD_DpadDown 0x91 109 + #define HidUsage_GD_DpadRight 0x92 110 + #define HidUsage_GD_DpadLeft 0x93 111 + #define HidUsage_GD_IndexTrigger 0x94 112 + #define HidUsage_GD_PalmTrigger 0x95 113 + #define HidUsage_GD_Thumbstick 0x96 114 + #define HidUsage_GD_SystemFunctionShift 0x97 115 + #define HidUsage_GD_SystemFunctionShiftLock 0x98 116 + #define HidUsage_GD_SystemFunctionShiftLockIndicator 0x99 117 + #define HidUsage_GD_SystemDismissNotification 0x9a 118 + #define HidUsage_GD_SystemDoNotDisturb 0x9b 119 + #define HidUsage_GD_SystemDock 0xa0 120 + #define HidUsage_GD_SystemUndock 0xa1 121 + #define HidUsage_GD_SystemSetup 0xa2 122 + #define HidUsage_GD_SystemBreak 0xa3 123 + #define HidUsage_GD_SystemDebuggerBreak 0xa4 124 + #define HidUsage_GD_ApplicationBreak 0xa5 125 + #define HidUsage_GD_ApplicationDebuggerBreak 0xa6 126 + #define HidUsage_GD_SystemSpeakerMute 0xa7 127 + #define HidUsage_GD_SystemHibernate 0xa8 128 + #define HidUsage_GD_SystemMicrophoneMute 0xa9 129 + #define HidUsage_GD_SystemAccessibilityBinding 0xaa 130 + #define HidUsage_GD_SystemDisplayInvert 0xb0 131 + #define HidUsage_GD_SystemDisplayInternal 0xb1 132 + #define HidUsage_GD_SystemDisplayExternal 0xb2 133 + #define HidUsage_GD_SystemDisplayBoth 0xb3 134 + #define HidUsage_GD_SystemDisplayDual 0xb4 135 + #define HidUsage_GD_SystemDisplayToggleIntExtMode 0xb5 136 + #define HidUsage_GD_SystemDisplaySwapPrimarySecondary 0xb6 137 + #define HidUsage_GD_SystemDisplayToggleLCDAutoscale 0xb7 138 + #define HidUsage_GD_SensorZone 0xc0 139 + #define HidUsage_GD_RPM 0xc1 140 + #define HidUsage_GD_CoolantLevel 0xc2 141 + #define HidUsage_GD_CoolantCriticalLevel 0xc3 142 + #define HidUsage_GD_CoolantPump 0xc4 143 + #define HidUsage_GD_ChassisEnclosure 0xc5 144 + #define HidUsage_GD_WirelessRadioButton 0xc6 145 + #define HidUsage_GD_WirelessRadioLED 0xc7 146 + #define HidUsage_GD_WirelessRadioSliderSwitch 0xc8 147 + #define HidUsage_GD_SystemDisplayRotationLockButton 0xc9 148 + #define HidUsage_GD_SystemDisplayRotationLockSliderSwitch 0xca 149 + #define HidUsage_GD_ControlEnable 0xcb 150 + #define HidUsage_GD_DockableDeviceUniqueID 0xd0 151 + #define HidUsage_GD_DockableDeviceVendorID 0xd1 152 + #define HidUsage_GD_DockableDevicePrimaryUsagePage 0xd2 153 + #define HidUsage_GD_DockableDevicePrimaryUsageID 0xd3 154 + #define HidUsage_GD_DockableDeviceDockingState 0xd4 155 + #define HidUsage_GD_DockableDeviceDisplayOcclusion 0xd5 156 + #define HidUsage_GD_DockableDeviceObjectType 0xd6 157 + #define HidUsage_GD_CallActiveLED 0xe0 158 + #define HidUsage_GD_CallMuteToggle 0xe1 159 + #define HidUsage_GD_CallMuteLED 0xe2 160 + #define HidUsage_SC_FlightSimulationDevice 0x01 161 + #define HidUsage_SC_AutomobileSimulationDevice 0x02 162 + #define HidUsage_SC_TankSimulationDevice 0x03 163 + #define HidUsage_SC_SpaceshipSimulationDevice 0x04 164 + #define HidUsage_SC_SubmarineSimulationDevice 0x05 165 + #define HidUsage_SC_SailingSimulationDevice 0x06 166 + #define HidUsage_SC_MotorcycleSimulationDevice 0x07 167 + #define HidUsage_SC_SportsSimulationDevice 0x08 168 + #define HidUsage_SC_AirplaneSimulationDevice 0x09 169 + #define HidUsage_SC_HelicopterSimulationDevice 0x0a 170 + #define HidUsage_SC_MagicCarpetSimulationDevice 0x0b 171 + #define HidUsage_SC_BicycleSimulationDevice 0x0c 172 + #define HidUsage_SC_FlightControlStick 0x20 173 + #define HidUsage_SC_FlightStick 0x21 174 + #define HidUsage_SC_CyclicControl 0x22 175 + #define HidUsage_SC_CyclicTrim 0x23 176 + #define HidUsage_SC_FlightYoke 0x24 177 + #define HidUsage_SC_TrackControl 0x25 178 + #define HidUsage_SC_Aileron 0xb0 179 + #define HidUsage_SC_AileronTrim 0xb1 180 + #define HidUsage_SC_AntiTorqueControl 0xb2 181 + #define HidUsage_SC_AutopilotEnable 0xb3 182 + #define HidUsage_SC_ChaffRelease 0xb4 183 + #define HidUsage_SC_CollectiveControl 0xb5 184 + #define HidUsage_SC_DiveBrake 0xb6 185 + #define HidUsage_SC_ElectronicCountermeasures 0xb7 186 + #define HidUsage_SC_Elevator 0xb8 187 + #define HidUsage_SC_ElevatorTrim 0xb9 188 + #define HidUsage_SC_Rudder 0xba 189 + #define HidUsage_SC_Throttle 0xbb 190 + #define HidUsage_SC_FlightCommunications 0xbc 191 + #define HidUsage_SC_FlareRelease 0xbd 192 + #define HidUsage_SC_LandingGear 0xbe 193 + #define HidUsage_SC_ToeBrake 0xbf 194 + #define HidUsage_SC_Trigger 0xc0 195 + #define HidUsage_SC_WeaponsArm 0xc1 196 + #define HidUsage_SC_WeaponsSelect 0xc2 197 + #define HidUsage_SC_WingFlaps 0xc3 198 + #define HidUsage_SC_Accelerator 0xc4 199 + #define HidUsage_SC_Brake 0xc5 200 + #define HidUsage_SC_Clutch 0xc6 201 + #define HidUsage_SC_Shifter 0xc7 202 + #define HidUsage_SC_Steering 0xc8 203 + #define HidUsage_SC_TurretDirection 0xc9 204 + #define HidUsage_SC_BarrelElevation 0xca 205 + #define HidUsage_SC_DivePlane 0xcb 206 + #define HidUsage_SC_Ballast 0xcc 207 + #define HidUsage_SC_BicycleCrank 0xcd 208 + #define HidUsage_SC_HandleBars 0xce 209 + #define HidUsage_SC_FrontBrake 0xcf 210 + #define HidUsage_SC_RearBrake 0xd0 211 + #define HidUsage_VRC_Belt 0x01 212 + #define HidUsage_VRC_BodySuit 0x02 213 + #define HidUsage_VRC_Flexor 0x03 214 + #define HidUsage_VRC_Glove 0x04 215 + #define HidUsage_VRC_HeadTracker 0x05 216 + #define HidUsage_VRC_HeadMountedDisplay 0x06 217 + #define HidUsage_VRC_HandTracker 0x07 218 + #define HidUsage_VRC_Oculometer 0x08 219 + #define HidUsage_VRC_Vest 0x09 220 + #define HidUsage_VRC_AnimatronicDevice 0x0a 221 + #define HidUsage_VRC_StereoEnable 0x20 222 + #define HidUsage_VRC_DisplayEnable 0x21 223 + #define HidUsage_SC_BaseballBat 0x01 224 + #define HidUsage_SC_GolfClub 0x02 225 + #define HidUsage_SC_RowingMachine 0x03 226 + #define HidUsage_SC_Treadmill 0x04 227 + #define HidUsage_SC_Oar 0x30 228 + #define HidUsage_SC_Slope 0x31 229 + #define HidUsage_SC_Rate 0x32 230 + #define HidUsage_SC_StickSpeed 0x33 231 + #define HidUsage_SC_StickFaceAngle 0x34 232 + #define HidUsage_SC_StickHeelToe 0x35 233 + #define HidUsage_SC_StickFollowThrough 0x36 234 + #define HidUsage_SC_StickTempo 0x37 235 + #define HidUsage_SC_StickType 0x38 236 + #define HidUsage_SC_StickHeight 0x39 237 + #define HidUsage_SC_Putter 0x50 238 + #define HidUsage_SC_OneIron 0x51 239 + #define HidUsage_SC_TwoIron 0x52 240 + #define HidUsage_SC_ThreeIron 0x53 241 + #define HidUsage_SC_FourIron 0x54 242 + #define HidUsage_SC_FiveIron 0x55 243 + #define HidUsage_SC_SixIron 0x56 244 + #define HidUsage_SC_SevenIron 0x57 245 + #define HidUsage_SC_EightIron 0x58 246 + #define HidUsage_SC_NineIron 0x59 247 + #define HidUsage_SC_One0Iron 0x5a 248 + #define HidUsage_SC_One1Iron 0x5b 249 + #define HidUsage_SC_SandWedge 0x5c 250 + #define HidUsage_SC_LoftWedge 0x5d 251 + #define HidUsage_SC_PowerWedge 0x5e 252 + #define HidUsage_SC_OneWood 0x5f 253 + #define HidUsage_SC_ThreeWood 0x60 254 + #define HidUsage_SC_FiveWood 0x61 255 + #define HidUsage_SC_SevenWood 0x62 256 + #define HidUsage_SC_NineWood 0x63 257 + #define HidUsage_GC_ThreeDGameController 0x01 258 + #define HidUsage_GC_PinballDevice 0x02 259 + #define HidUsage_GC_GunDevice 0x03 260 + #define HidUsage_GC_PointofView 0x20 261 + #define HidUsage_GC_TurnRightLeft 0x21 262 + #define HidUsage_GC_PitchForwardBackward 0x22 263 + #define HidUsage_GC_RollRightLeft 0x23 264 + #define HidUsage_GC_MoveRightLeft 0x24 265 + #define HidUsage_GC_MoveForwardBackward 0x25 266 + #define HidUsage_GC_MoveUpDown 0x26 267 + #define HidUsage_GC_LeanRightLeft 0x27 268 + #define HidUsage_GC_LeanForwardBackward 0x28 269 + #define HidUsage_GC_HeightofPOV 0x29 270 + #define HidUsage_GC_Flipper 0x2a 271 + #define HidUsage_GC_SecondaryFlipper 0x2b 272 + #define HidUsage_GC_Bump 0x2c 273 + #define HidUsage_GC_NewGame 0x2d 274 + #define HidUsage_GC_ShootBall 0x2e 275 + #define HidUsage_GC_Player 0x2f 276 + #define HidUsage_GC_GunBolt 0x30 277 + #define HidUsage_GC_GunClip 0x31 278 + #define HidUsage_GC_GunSelector 0x32 279 + #define HidUsage_GC_GunSingleShot 0x33 280 + #define HidUsage_GC_GunBurst 0x34 281 + #define HidUsage_GC_GunAutomatic 0x35 282 + #define HidUsage_GC_GunSafety 0x36 283 + #define HidUsage_GC_GamepadFireJump 0x37 284 + #define HidUsage_GC_GamepadTrigger 0x39 285 + #define HidUsage_GC_FormfittingGamepad 0x3a 286 + #define HidUsage_GDC_BackgroundNonuserControls 0x01 287 + #define HidUsage_GDC_BatteryStrength 0x20 288 + #define HidUsage_GDC_WirelessChannel 0x21 289 + #define HidUsage_GDC_WirelessID 0x22 290 + #define HidUsage_GDC_DiscoverWirelessControl 0x23 291 + #define HidUsage_GDC_SecurityCodeCharacterEntered 0x24 292 + #define HidUsage_GDC_SecurityCodeCharacterErased 0x25 293 + #define HidUsage_GDC_SecurityCodeCleared 0x26 294 + #define HidUsage_GDC_SequenceID 0x27 295 + #define HidUsage_GDC_SequenceIDReset 0x28 296 + #define HidUsage_GDC_RFSignalStrength 0x29 297 + #define HidUsage_GDC_SoftwareVersion 0x2a 298 + #define HidUsage_GDC_ProtocolVersion 0x2b 299 + #define HidUsage_GDC_HardwareVersion 0x2c 300 + #define HidUsage_GDC_Major 0x2d 301 + #define HidUsage_GDC_Minor 0x2e 302 + #define HidUsage_GDC_Revision 0x2f 303 + #define HidUsage_GDC_Handedness 0x30 304 + #define HidUsage_GDC_EitherHand 0x31 305 + #define HidUsage_GDC_LeftHand 0x32 306 + #define HidUsage_GDC_RightHand 0x33 307 + #define HidUsage_GDC_BothHands 0x34 308 + #define HidUsage_GDC_GripPoseOffset 0x40 309 + #define HidUsage_GDC_PointerPoseOffset 0x41 310 + #define HidUsage_KK_ErrorRollOver 0x01 311 + #define HidUsage_KK_POSTFail 0x02 312 + #define HidUsage_KK_ErrorUndefined 0x03 313 + #define HidUsage_KK_KeyboardA 0x04 314 + #define HidUsage_KK_KeyboardB 0x05 315 + #define HidUsage_KK_KeyboardC 0x06 316 + #define HidUsage_KK_KeyboardD 0x07 317 + #define HidUsage_KK_KeyboardE 0x08 318 + #define HidUsage_KK_KeyboardF 0x09 319 + #define HidUsage_KK_KeyboardG 0x0a 320 + #define HidUsage_KK_KeyboardH 0x0b 321 + #define HidUsage_KK_KeyboardI 0x0c 322 + #define HidUsage_KK_KeyboardJ 0x0d 323 + #define HidUsage_KK_KeyboardK 0x0e 324 + #define HidUsage_KK_KeyboardL 0x0f 325 + #define HidUsage_KK_KeyboardM 0x10 326 + #define HidUsage_KK_KeyboardN 0x11 327 + #define HidUsage_KK_KeyboardO 0x12 328 + #define HidUsage_KK_KeyboardP 0x13 329 + #define HidUsage_KK_KeyboardQ 0x14 330 + #define HidUsage_KK_KeyboardR 0x15 331 + #define HidUsage_KK_KeyboardS 0x16 332 + #define HidUsage_KK_KeyboardT 0x17 333 + #define HidUsage_KK_KeyboardU 0x18 334 + #define HidUsage_KK_KeyboardV 0x19 335 + #define HidUsage_KK_KeyboardW 0x1a 336 + #define HidUsage_KK_KeyboardX 0x1b 337 + #define HidUsage_KK_KeyboardY 0x1c 338 + #define HidUsage_KK_KeyboardZ 0x1d 339 + #define HidUsage_KK_Keyboard1andBang 0x1e 340 + #define HidUsage_KK_Keyboard2andAt 0x1f 341 + #define HidUsage_KK_Keyboard3andHash 0x20 342 + #define HidUsage_KK_Keyboard4andDollar 0x21 343 + #define HidUsage_KK_Keyboard5andPercent 0x22 344 + #define HidUsage_KK_Keyboard6andCaret 0x23 345 + #define HidUsage_KK_Keyboard7andAmpersand 0x24 346 + #define HidUsage_KK_Keyboard8andStar 0x25 347 + #define HidUsage_KK_Keyboard9andLeftBracket 0x26 348 + #define HidUsage_KK_Keyboard0andRightBracket 0x27 349 + #define HidUsage_KK_KeyboardReturnEnter 0x28 350 + #define HidUsage_KK_KeyboardEscape 0x29 351 + #define HidUsage_KK_KeyboardDelete 0x2a 352 + #define HidUsage_KK_KeyboardTab 0x2b 353 + #define HidUsage_KK_KeyboardSpacebar 0x2c 354 + #define HidUsage_KK_KeyboardDashandUnderscore 0x2d 355 + #define HidUsage_KK_KeyboardEqualsandPlus 0x2e 356 + #define HidUsage_KK_KeyboardLeftBrace 0x2f 357 + #define HidUsage_KK_KeyboardRightBrace 0x30 358 + #define HidUsage_KK_KeyboardBackslashandPipe 0x31 359 + #define HidUsage_KK_KeyboardNonUSHashandTilde 0x32 360 + #define HidUsage_KK_KeyboardSemiColonandColon 0x33 361 + #define HidUsage_KK_KeyboardLeftAposandDouble 0x34 362 + #define HidUsage_KK_KeyboardGraveAccentandTilde 0x35 363 + #define HidUsage_KK_KeyboardCommaandLessThan 0x36 364 + #define HidUsage_KK_KeyboardPeriodandGreaterThan 0x37 365 + #define HidUsage_KK_KeyboardForwardSlashandQuestionMark 0x38 366 + #define HidUsage_KK_KeyboardCapsLock 0x39 367 + #define HidUsage_KK_KeyboardF1 0x3a 368 + #define HidUsage_KK_KeyboardF2 0x3b 369 + #define HidUsage_KK_KeyboardF3 0x3c 370 + #define HidUsage_KK_KeyboardF4 0x3d 371 + #define HidUsage_KK_KeyboardF5 0x3e 372 + #define HidUsage_KK_KeyboardF6 0x3f 373 + #define HidUsage_KK_KeyboardF7 0x40 374 + #define HidUsage_KK_KeyboardF8 0x41 375 + #define HidUsage_KK_KeyboardF9 0x42 376 + #define HidUsage_KK_KeyboardF10 0x43 377 + #define HidUsage_KK_KeyboardF11 0x44 378 + #define HidUsage_KK_KeyboardF12 0x45 379 + #define HidUsage_KK_KeyboardPrintScreen 0x46 380 + #define HidUsage_KK_KeyboardScrollLock 0x47 381 + #define HidUsage_KK_KeyboardPause 0x48 382 + #define HidUsage_KK_KeyboardInsert 0x49 383 + #define HidUsage_KK_KeyboardHome 0x4a 384 + #define HidUsage_KK_KeyboardPageUp 0x4b 385 + #define HidUsage_KK_KeyboardDeleteForward 0x4c 386 + #define HidUsage_KK_KeyboardEnd 0x4d 387 + #define HidUsage_KK_KeyboardPageDown 0x4e 388 + #define HidUsage_KK_KeyboardRightArrow 0x4f 389 + #define HidUsage_KK_KeyboardLeftArrow 0x50 390 + #define HidUsage_KK_KeyboardDownArrow 0x51 391 + #define HidUsage_KK_KeyboardUpArrow 0x52 392 + #define HidUsage_KK_KeypadNumLockandClear 0x53 393 + #define HidUsage_KK_KeypadForwardSlash 0x54 394 + #define HidUsage_KK_KeypadStar 0x55 395 + #define HidUsage_KK_KeypadDash 0x56 396 + #define HidUsage_KK_KeypadPlus 0x57 397 + #define HidUsage_KK_KeypadENTER 0x58 398 + #define HidUsage_KK_Keypad1andEnd 0x59 399 + #define HidUsage_KK_Keypad2andDownArrow 0x5a 400 + #define HidUsage_KK_Keypad3andPageDn 0x5b 401 + #define HidUsage_KK_Keypad4andLeftArrow 0x5c 402 + #define HidUsage_KK_Keypad5 0x5d 403 + #define HidUsage_KK_Keypad6andRightArrow 0x5e 404 + #define HidUsage_KK_Keypad7andHome 0x5f 405 + #define HidUsage_KK_Keypad8andUpArrow 0x60 406 + #define HidUsage_KK_Keypad9andPageUp 0x61 407 + #define HidUsage_KK_Keypad0andInsert 0x62 408 + #define HidUsage_KK_KeypadPeriodandDelete 0x63 409 + #define HidUsage_KK_KeyboardNonUSBackslashandPipe 0x64 410 + #define HidUsage_KK_KeyboardApplication 0x65 411 + #define HidUsage_KK_KeyboardPower 0x66 412 + #define HidUsage_KK_KeypadEquals 0x67 413 + #define HidUsage_KK_KeyboardF13 0x68 414 + #define HidUsage_KK_KeyboardF14 0x69 415 + #define HidUsage_KK_KeyboardF15 0x6a 416 + #define HidUsage_KK_KeyboardF16 0x6b 417 + #define HidUsage_KK_KeyboardF17 0x6c 418 + #define HidUsage_KK_KeyboardF18 0x6d 419 + #define HidUsage_KK_KeyboardF19 0x6e 420 + #define HidUsage_KK_KeyboardF20 0x6f 421 + #define HidUsage_KK_KeyboardF21 0x70 422 + #define HidUsage_KK_KeyboardF22 0x71 423 + #define HidUsage_KK_KeyboardF23 0x72 424 + #define HidUsage_KK_KeyboardF24 0x73 425 + #define HidUsage_KK_KeyboardExecute 0x74 426 + #define HidUsage_KK_KeyboardHelp 0x75 427 + #define HidUsage_KK_KeyboardMenu 0x76 428 + #define HidUsage_KK_KeyboardSelect 0x77 429 + #define HidUsage_KK_KeyboardStop 0x78 430 + #define HidUsage_KK_KeyboardAgain 0x79 431 + #define HidUsage_KK_KeyboardUndo 0x7a 432 + #define HidUsage_KK_KeyboardCut 0x7b 433 + #define HidUsage_KK_KeyboardCopy 0x7c 434 + #define HidUsage_KK_KeyboardPaste 0x7d 435 + #define HidUsage_KK_KeyboardFind 0x7e 436 + #define HidUsage_KK_KeyboardMute 0x7f 437 + #define HidUsage_KK_KeyboardVolumeUp 0x80 438 + #define HidUsage_KK_KeyboardVolumeDown 0x81 439 + #define HidUsage_KK_KeyboardLockingCapsLock 0x82 440 + #define HidUsage_KK_KeyboardLockingNumLock 0x83 441 + #define HidUsage_KK_KeyboardLockingScrollLock 0x84 442 + #define HidUsage_KK_KeypadComma 0x85 443 + #define HidUsage_KK_KeypadEqualSign 0x86 444 + #define HidUsage_KK_KeyboardInternational1 0x87 445 + #define HidUsage_KK_KeyboardInternational2 0x88 446 + #define HidUsage_KK_KeyboardInternational3 0x89 447 + #define HidUsage_KK_KeyboardInternational4 0x8a 448 + #define HidUsage_KK_KeyboardInternational5 0x8b 449 + #define HidUsage_KK_KeyboardInternational6 0x8c 450 + #define HidUsage_KK_KeyboardInternational7 0x8d 451 + #define HidUsage_KK_KeyboardInternational8 0x8e 452 + #define HidUsage_KK_KeyboardInternational9 0x8f 453 + #define HidUsage_KK_KeyboardLANG1 0x90 454 + #define HidUsage_KK_KeyboardLANG2 0x91 455 + #define HidUsage_KK_KeyboardLANG3 0x92 456 + #define HidUsage_KK_KeyboardLANG4 0x93 457 + #define HidUsage_KK_KeyboardLANG5 0x94 458 + #define HidUsage_KK_KeyboardLANG6 0x95 459 + #define HidUsage_KK_KeyboardLANG7 0x96 460 + #define HidUsage_KK_KeyboardLANG8 0x97 461 + #define HidUsage_KK_KeyboardLANG9 0x98 462 + #define HidUsage_KK_KeyboardAlternateErase 0x99 463 + #define HidUsage_KK_KeyboardSysReqAttention 0x9a 464 + #define HidUsage_KK_KeyboardCancel 0x9b 465 + #define HidUsage_KK_KeyboardClear 0x9c 466 + #define HidUsage_KK_KeyboardPrior 0x9d 467 + #define HidUsage_KK_KeyboardReturn 0x9e 468 + #define HidUsage_KK_KeyboardSeparator 0x9f 469 + #define HidUsage_KK_KeyboardOut 0xa0 470 + #define HidUsage_KK_KeyboardOper 0xa1 471 + #define HidUsage_KK_KeyboardClearAgain 0xa2 472 + #define HidUsage_KK_KeyboardCrSelProps 0xa3 473 + #define HidUsage_KK_KeyboardExSel 0xa4 474 + #define HidUsage_KK_KeypadDouble0 0xb0 475 + #define HidUsage_KK_KeypadTriple0 0xb1 476 + #define HidUsage_KK_ThousandsSeparator 0xb2 477 + #define HidUsage_KK_DecimalSeparator 0xb3 478 + #define HidUsage_KK_CurrencyUnit 0xb4 479 + #define HidUsage_KK_CurrencySubunit 0xb5 480 + #define HidUsage_KK_KeypadLeftBracket 0xb6 481 + #define HidUsage_KK_KeypadRightBracket 0xb7 482 + #define HidUsage_KK_KeypadLeftBrace 0xb8 483 + #define HidUsage_KK_KeypadRightBrace 0xb9 484 + #define HidUsage_KK_KeypadTab 0xba 485 + #define HidUsage_KK_KeypadBackspace 0xbb 486 + #define HidUsage_KK_KeypadA 0xbc 487 + #define HidUsage_KK_KeypadB 0xbd 488 + #define HidUsage_KK_KeypadC 0xbe 489 + #define HidUsage_KK_KeypadD 0xbf 490 + #define HidUsage_KK_KeypadE 0xc0 491 + #define HidUsage_KK_KeypadF 0xc1 492 + #define HidUsage_KK_KeypadXOR 0xc2 493 + #define HidUsage_KK_KeypadCaret 0xc3 494 + #define HidUsage_KK_KeypadPercentage 0xc4 495 + #define HidUsage_KK_KeypadLess 0xc5 496 + #define HidUsage_KK_KeypadGreater 0xc6 497 + #define HidUsage_KK_KeypadAmpersand 0xc7 498 + #define HidUsage_KK_KeypadDoubleAmpersand 0xc8 499 + #define HidUsage_KK_KeypadBar 0xc9 500 + #define HidUsage_KK_KeypadDoubleBar 0xca 501 + #define HidUsage_KK_KeypadColon 0xcb 502 + #define HidUsage_KK_KeypadHash 0xcc 503 + #define HidUsage_KK_KeypadSpace 0xcd 504 + #define HidUsage_KK_KeypadAt 0xce 505 + #define HidUsage_KK_KeypadBang 0xcf 506 + #define HidUsage_KK_KeypadMemoryStore 0xd0 507 + #define HidUsage_KK_KeypadMemoryRecall 0xd1 508 + #define HidUsage_KK_KeypadMemoryClear 0xd2 509 + #define HidUsage_KK_KeypadMemoryAdd 0xd3 510 + #define HidUsage_KK_KeypadMemorySubtract 0xd4 511 + #define HidUsage_KK_KeypadMemoryMultiply 0xd5 512 + #define HidUsage_KK_KeypadMemoryDivide 0xd6 513 + #define HidUsage_KK_KeypadPlusMinus 0xd7 514 + #define HidUsage_KK_KeypadClear 0xd8 515 + #define HidUsage_KK_KeypadClearEntry 0xd9 516 + #define HidUsage_KK_KeypadBinary 0xda 517 + #define HidUsage_KK_KeypadOctal 0xdb 518 + #define HidUsage_KK_KeypadDecimal 0xdc 519 + #define HidUsage_KK_KeypadHexadecimal 0xdd 520 + #define HidUsage_KK_KeyboardLeftControl 0xe0 521 + #define HidUsage_KK_KeyboardLeftShift 0xe1 522 + #define HidUsage_KK_KeyboardLeftAlt 0xe2 523 + #define HidUsage_KK_KeyboardLeftGUI 0xe3 524 + #define HidUsage_KK_KeyboardRightControl 0xe4 525 + #define HidUsage_KK_KeyboardRightShift 0xe5 526 + #define HidUsage_KK_KeyboardRightAlt 0xe6 527 + #define HidUsage_KK_KeyboardRightGUI 0xe7 528 + #define HidUsage_LED_NumLock 0x01 529 + #define HidUsage_LED_CapsLock 0x02 530 + #define HidUsage_LED_ScrollLock 0x03 531 + #define HidUsage_LED_Compose 0x04 532 + #define HidUsage_LED_Kana 0x05 533 + #define HidUsage_LED_Power 0x06 534 + #define HidUsage_LED_Shift 0x07 535 + #define HidUsage_LED_DoNotDisturb 0x08 536 + #define HidUsage_LED_Mute 0x09 537 + #define HidUsage_LED_ToneEnable 0x0a 538 + #define HidUsage_LED_HighCutFilter 0x0b 539 + #define HidUsage_LED_LowCutFilter 0x0c 540 + #define HidUsage_LED_EqualizerEnable 0x0d 541 + #define HidUsage_LED_SoundFieldOn 0x0e 542 + #define HidUsage_LED_SurroundOn 0x0f 543 + #define HidUsage_LED_Repeat 0x10 544 + #define HidUsage_LED_Stereo 0x11 545 + #define HidUsage_LED_SamplingRateDetect 0x12 546 + #define HidUsage_LED_Spinning 0x13 547 + #define HidUsage_LED_CAV 0x14 548 + #define HidUsage_LED_CLV 0x15 549 + #define HidUsage_LED_RecordingFormatDetect 0x16 550 + #define HidUsage_LED_OffHook 0x17 551 + #define HidUsage_LED_Ring 0x18 552 + #define HidUsage_LED_MessageWaiting 0x19 553 + #define HidUsage_LED_DataMode 0x1a 554 + #define HidUsage_LED_BatteryOperation 0x1b 555 + #define HidUsage_LED_BatteryOK 0x1c 556 + #define HidUsage_LED_BatteryLow 0x1d 557 + #define HidUsage_LED_Speaker 0x1e 558 + #define HidUsage_LED_Headset 0x1f 559 + #define HidUsage_LED_Hold 0x20 560 + #define HidUsage_LED_Microphone 0x21 561 + #define HidUsage_LED_Coverage 0x22 562 + #define HidUsage_LED_NightMode 0x23 563 + #define HidUsage_LED_SendCalls 0x24 564 + #define HidUsage_LED_CallPickup 0x25 565 + #define HidUsage_LED_Conference 0x26 566 + #define HidUsage_LED_Standby 0x27 567 + #define HidUsage_LED_CameraOn 0x28 568 + #define HidUsage_LED_CameraOff 0x29 569 + #define HidUsage_LED_OnLine 0x2a 570 + #define HidUsage_LED_OffLine 0x2b 571 + #define HidUsage_LED_Busy 0x2c 572 + #define HidUsage_LED_Ready 0x2d 573 + #define HidUsage_LED_PaperOut 0x2e 574 + #define HidUsage_LED_PaperJam 0x2f 575 + #define HidUsage_LED_Remote 0x30 576 + #define HidUsage_LED_Forward 0x31 577 + #define HidUsage_LED_Reverse 0x32 578 + #define HidUsage_LED_Stop 0x33 579 + #define HidUsage_LED_Rewind 0x34 580 + #define HidUsage_LED_FastForward 0x35 581 + #define HidUsage_LED_Play 0x36 582 + #define HidUsage_LED_Pause 0x37 583 + #define HidUsage_LED_Record 0x38 584 + #define HidUsage_LED_Error 0x39 585 + #define HidUsage_LED_UsageSelectedIndicator 0x3a 586 + #define HidUsage_LED_UsageInUseIndicator 0x3b 587 + #define HidUsage_LED_UsageMultiModeIndicator 0x3c 588 + #define HidUsage_LED_IndicatorOn 0x3d 589 + #define HidUsage_LED_IndicatorFlash 0x3e 590 + #define HidUsage_LED_IndicatorSlowBlink 0x3f 591 + #define HidUsage_LED_IndicatorFastBlink 0x40 592 + #define HidUsage_LED_IndicatorOff 0x41 593 + #define HidUsage_LED_FlashOnTime 0x42 594 + #define HidUsage_LED_SlowBlinkOnTime 0x43 595 + #define HidUsage_LED_SlowBlinkOffTime 0x44 596 + #define HidUsage_LED_FastBlinkOnTime 0x45 597 + #define HidUsage_LED_FastBlinkOffTime 0x46 598 + #define HidUsage_LED_UsageIndicatorColor 0x47 599 + #define HidUsage_LED_IndicatorRed 0x48 600 + #define HidUsage_LED_IndicatorGreen 0x49 601 + #define HidUsage_LED_IndicatorAmber 0x4a 602 + #define HidUsage_LED_GenericIndicator 0x4b 603 + #define HidUsage_LED_SystemSuspend 0x4c 604 + #define HidUsage_LED_ExternalPowerConnected 0x4d 605 + #define HidUsage_LED_IndicatorBlue 0x4e 606 + #define HidUsage_LED_IndicatorOrange 0x4f 607 + #define HidUsage_LED_GoodStatus 0x50 608 + #define HidUsage_LED_WarningStatus 0x51 609 + #define HidUsage_LED_RGBLED 0x52 610 + #define HidUsage_LED_RedLEDChannel 0x53 611 + #define HidUsage_LED_BlueLEDChannel 0x54 612 + #define HidUsage_LED_GreenLEDChannel 0x55 613 + #define HidUsage_LED_LEDIntensity 0x56 614 + #define HidUsage_LED_SystemMicrophoneMute 0x57 615 + #define HidUsage_LED_PlayerIndicator 0x60 616 + #define HidUsage_LED_Player1 0x61 617 + #define HidUsage_LED_Player2 0x62 618 + #define HidUsage_LED_Player3 0x63 619 + #define HidUsage_LED_Player4 0x64 620 + #define HidUsage_LED_Player5 0x65 621 + #define HidUsage_LED_Player6 0x66 622 + #define HidUsage_LED_Player7 0x67 623 + #define HidUsage_LED_Player8 0x68 624 + #define HidUsage_TD_Phone 0x01 625 + #define HidUsage_TD_AnsweringMachine 0x02 626 + #define HidUsage_TD_MessageControls 0x03 627 + #define HidUsage_TD_Handset 0x04 628 + #define HidUsage_TD_Headset 0x05 629 + #define HidUsage_TD_TelephonyKeyPad 0x06 630 + #define HidUsage_TD_ProgrammableButton 0x07 631 + #define HidUsage_TD_HookSwitch 0x20 632 + #define HidUsage_TD_Flash 0x21 633 + #define HidUsage_TD_Feature 0x22 634 + #define HidUsage_TD_Hold 0x23 635 + #define HidUsage_TD_Redial 0x24 636 + #define HidUsage_TD_Transfer 0x25 637 + #define HidUsage_TD_Drop 0x26 638 + #define HidUsage_TD_Park 0x27 639 + #define HidUsage_TD_ForwardCalls 0x28 640 + #define HidUsage_TD_AlternateFunction 0x29 641 + #define HidUsage_TD_Line 0x2a 642 + #define HidUsage_TD_SpeakerPhone 0x2b 643 + #define HidUsage_TD_Conference 0x2c 644 + #define HidUsage_TD_RingEnable 0x2d 645 + #define HidUsage_TD_RingSelect 0x2e 646 + #define HidUsage_TD_PhoneMute 0x2f 647 + #define HidUsage_TD_CallerID 0x30 648 + #define HidUsage_TD_Send 0x31 649 + #define HidUsage_TD_SpeedDial 0x50 650 + #define HidUsage_TD_StoreNumber 0x51 651 + #define HidUsage_TD_RecallNumber 0x52 652 + #define HidUsage_TD_PhoneDirectory 0x53 653 + #define HidUsage_TD_VoiceMail 0x70 654 + #define HidUsage_TD_ScreenCalls 0x71 655 + #define HidUsage_TD_DoNotDisturb 0x72 656 + #define HidUsage_TD_Message 0x73 657 + #define HidUsage_TD_AnswerOnOff 0x74 658 + #define HidUsage_TD_InsideDialTone 0x90 659 + #define HidUsage_TD_OutsideDialTone 0x91 660 + #define HidUsage_TD_InsideRingTone 0x92 661 + #define HidUsage_TD_OutsideRingTone 0x93 662 + #define HidUsage_TD_PriorityRingTone 0x94 663 + #define HidUsage_TD_InsideRingback 0x95 664 + #define HidUsage_TD_PriorityRingback 0x96 665 + #define HidUsage_TD_LineBusyTone 0x97 666 + #define HidUsage_TD_ReorderTone 0x98 667 + #define HidUsage_TD_CallWaitingTone 0x99 668 + #define HidUsage_TD_ConfirmationTone1 0x9a 669 + #define HidUsage_TD_ConfirmationTone2 0x9b 670 + #define HidUsage_TD_TonesOff 0x9c 671 + #define HidUsage_TD_OutsideRingback 0x9d 672 + #define HidUsage_TD_Ringer 0x9e 673 + #define HidUsage_TD_PhoneKey0 0xb0 674 + #define HidUsage_TD_PhoneKey1 0xb1 675 + #define HidUsage_TD_PhoneKey2 0xb2 676 + #define HidUsage_TD_PhoneKey3 0xb3 677 + #define HidUsage_TD_PhoneKey4 0xb4 678 + #define HidUsage_TD_PhoneKey5 0xb5 679 + #define HidUsage_TD_PhoneKey6 0xb6 680 + #define HidUsage_TD_PhoneKey7 0xb7 681 + #define HidUsage_TD_PhoneKey8 0xb8 682 + #define HidUsage_TD_PhoneKey9 0xb9 683 + #define HidUsage_TD_PhoneKeyStar 0xba 684 + #define HidUsage_TD_PhoneKeyPound 0xbb 685 + #define HidUsage_TD_PhoneKeyA 0xbc 686 + #define HidUsage_TD_PhoneKeyB 0xbd 687 + #define HidUsage_TD_PhoneKeyC 0xbe 688 + #define HidUsage_TD_PhoneKeyD 0xbf 689 + #define HidUsage_TD_PhoneCallHistoryKey 0xc0 690 + #define HidUsage_TD_PhoneCallerIDKey 0xc1 691 + #define HidUsage_TD_PhoneSettingsKey 0xc2 692 + #define HidUsage_TD_HostControl 0xf0 693 + #define HidUsage_TD_HostAvailable 0xf1 694 + #define HidUsage_TD_HostCallActive 0xf2 695 + #define HidUsage_TD_ActivateHandsetAudio 0xf3 696 + #define HidUsage_TD_RingType 0xf4 697 + #define HidUsage_TD_RedialablePhoneNumber 0xf5 698 + #define HidUsage_TD_StopRingTone 0xf8 699 + #define HidUsage_TD_PSTNRingTone 0xf9 700 + #define HidUsage_TD_HostRingTone 0xfa 701 + #define HidUsage_TD_AlertSoundError 0xfb 702 + #define HidUsage_TD_AlertSoundConfirm 0xfc 703 + #define HidUsage_TD_AlertSoundNotification 0xfd 704 + #define HidUsage_TD_SilentRing 0xfe 705 + #define HidUsage_TD_EmailMessageWaiting 0x108 706 + #define HidUsage_TD_VoicemailMessageWaiting 0x109 707 + #define HidUsage_TD_HostHold 0x10a 708 + #define HidUsage_TD_IncomingCallHistoryCount 0x110 709 + #define HidUsage_TD_OutgoingCallHistoryCount 0x111 710 + #define HidUsage_TD_IncomingCallHistory 0x112 711 + #define HidUsage_TD_OutgoingCallHistory 0x113 712 + #define HidUsage_TD_PhoneLocale 0x114 713 + #define HidUsage_TD_PhoneTimeSecond 0x140 714 + #define HidUsage_TD_PhoneTimeMinute 0x141 715 + #define HidUsage_TD_PhoneTimeHour 0x142 716 + #define HidUsage_TD_PhoneDateDay 0x143 717 + #define HidUsage_TD_PhoneDateMonth 0x144 718 + #define HidUsage_TD_PhoneDateYear 0x145 719 + #define HidUsage_TD_HandsetNickname 0x146 720 + #define HidUsage_TD_AddressBookID 0x147 721 + #define HidUsage_TD_CallDuration 0x14a 722 + #define HidUsage_TD_DualModePhone 0x14b 723 + #define HidUsage_Con_ConsumerControl 0x01 724 + #define HidUsage_Con_NumericKeyPad 0x02 725 + #define HidUsage_Con_ProgrammableButtons 0x03 726 + #define HidUsage_Con_Microphone 0x04 727 + #define HidUsage_Con_Headphone 0x05 728 + #define HidUsage_Con_GraphicEqualizer 0x06 729 + #define HidUsage_Con_Plus10 0x20 730 + #define HidUsage_Con_Plus100 0x21 731 + #define HidUsage_Con_AMPM 0x22 732 + #define HidUsage_Con_Power 0x30 733 + #define HidUsage_Con_Reset 0x31 734 + #define HidUsage_Con_Sleep 0x32 735 + #define HidUsage_Con_SleepAfter 0x33 736 + #define HidUsage_Con_SleepMode 0x34 737 + #define HidUsage_Con_Illumination 0x35 738 + #define HidUsage_Con_FunctionButtons 0x36 739 + #define HidUsage_Con_Menu 0x40 740 + #define HidUsage_Con_MenuPick 0x41 741 + #define HidUsage_Con_MenuUp 0x42 742 + #define HidUsage_Con_MenuDown 0x43 743 + #define HidUsage_Con_MenuLeft 0x44 744 + #define HidUsage_Con_MenuRight 0x45 745 + #define HidUsage_Con_MenuEscape 0x46 746 + #define HidUsage_Con_MenuValueIncrease 0x47 747 + #define HidUsage_Con_MenuValueDecrease 0x48 748 + #define HidUsage_Con_DataOnScreen 0x60 749 + #define HidUsage_Con_ClosedCaption 0x61 750 + #define HidUsage_Con_ClosedCaptionSelect 0x62 751 + #define HidUsage_Con_VCRTV 0x63 752 + #define HidUsage_Con_BroadcastMode 0x64 753 + #define HidUsage_Con_Snapshot 0x65 754 + #define HidUsage_Con_Still 0x66 755 + #define HidUsage_Con_PictureinPictureToggle 0x67 756 + #define HidUsage_Con_PictureinPictureSwap 0x68 757 + #define HidUsage_Con_RedMenuButton 0x69 758 + #define HidUsage_Con_GreenMenuButton 0x6a 759 + #define HidUsage_Con_BlueMenuButton 0x6b 760 + #define HidUsage_Con_YellowMenuButton 0x6c 761 + #define HidUsage_Con_Aspect 0x6d 762 + #define HidUsage_Con_ThreeDModeSelect 0x6e 763 + #define HidUsage_Con_DisplayBrightnessIncrement 0x6f 764 + #define HidUsage_Con_DisplayBrightnessDecrement 0x70 765 + #define HidUsage_Con_DisplayBrightness 0x71 766 + #define HidUsage_Con_DisplayBacklightToggle 0x72 767 + #define HidUsage_Con_DisplaySetBrightnesstoMinimum 0x73 768 + #define HidUsage_Con_DisplaySetBrightnesstoMaximum 0x74 769 + #define HidUsage_Con_DisplaySetAutoBrightness 0x75 770 + #define HidUsage_Con_CameraAccessEnabled 0x76 771 + #define HidUsage_Con_CameraAccessDisabled 0x77 772 + #define HidUsage_Con_CameraAccessToggle 0x78 773 + #define HidUsage_Con_KeyboardBrightnessIncrement 0x79 774 + #define HidUsage_Con_KeyboardBrightnessDecrement 0x7a 775 + #define HidUsage_Con_KeyboardBacklightSetLevel 0x7b 776 + #define HidUsage_Con_KeyboardBacklightOOC 0x7c 777 + #define HidUsage_Con_KeyboardBacklightSetMinimum 0x7d 778 + #define HidUsage_Con_KeyboardBacklightSetMaximum 0x7e 779 + #define HidUsage_Con_KeyboardBacklightAuto 0x7f 780 + #define HidUsage_Con_Selection 0x80 781 + #define HidUsage_Con_AssignSelection 0x81 782 + #define HidUsage_Con_ModeStep 0x82 783 + #define HidUsage_Con_RecallLast 0x83 784 + #define HidUsage_Con_EnterChannel 0x84 785 + #define HidUsage_Con_OrderMovie 0x85 786 + #define HidUsage_Con_Channel 0x86 787 + #define HidUsage_Con_MediaSelection 0x87 788 + #define HidUsage_Con_MediaSelectComputer 0x88 789 + #define HidUsage_Con_MediaSelectTV 0x89 790 + #define HidUsage_Con_MediaSelectWWW 0x8a 791 + #define HidUsage_Con_MediaSelectDVD 0x8b 792 + #define HidUsage_Con_MediaSelectTelephone 0x8c 793 + #define HidUsage_Con_MediaSelectProgramGuide 0x8d 794 + #define HidUsage_Con_MediaSelectVideoPhone 0x8e 795 + #define HidUsage_Con_MediaSelectGames 0x8f 796 + #define HidUsage_Con_MediaSelectMessages 0x90 797 + #define HidUsage_Con_MediaSelectCD 0x91 798 + #define HidUsage_Con_MediaSelectVCR 0x92 799 + #define HidUsage_Con_MediaSelectTuner 0x93 800 + #define HidUsage_Con_Quit 0x94 801 + #define HidUsage_Con_Help 0x95 802 + #define HidUsage_Con_MediaSelectTape 0x96 803 + #define HidUsage_Con_MediaSelectCable 0x97 804 + #define HidUsage_Con_MediaSelectSatellite 0x98 805 + #define HidUsage_Con_MediaSelectSecurity 0x99 806 + #define HidUsage_Con_MediaSelectHome 0x9a 807 + #define HidUsage_Con_MediaSelectCall 0x9b 808 + #define HidUsage_Con_ChannelIncrement 0x9c 809 + #define HidUsage_Con_ChannelDecrement 0x9d 810 + #define HidUsage_Con_MediaSelectSAP 0x9e 811 + #define HidUsage_Con_VCRPlus 0xa0 812 + #define HidUsage_Con_Once 0xa1 813 + #define HidUsage_Con_Daily 0xa2 814 + #define HidUsage_Con_Weekly 0xa3 815 + #define HidUsage_Con_Monthly 0xa4 816 + #define HidUsage_Con_Play 0xb0 817 + #define HidUsage_Con_Pause 0xb1 818 + #define HidUsage_Con_Record 0xb2 819 + #define HidUsage_Con_FastForward 0xb3 820 + #define HidUsage_Con_Rewind 0xb4 821 + #define HidUsage_Con_ScanNextTrack 0xb5 822 + #define HidUsage_Con_ScanPreviousTrack 0xb6 823 + #define HidUsage_Con_Stop 0xb7 824 + #define HidUsage_Con_Eject 0xb8 825 + #define HidUsage_Con_RandomPlay 0xb9 826 + #define HidUsage_Con_SelectDisc 0xba 827 + #define HidUsage_Con_EnterDisc 0xbb 828 + #define HidUsage_Con_Repeat 0xbc 829 + #define HidUsage_Con_Tracking 0xbd 830 + #define HidUsage_Con_TrackNormal 0xbe 831 + #define HidUsage_Con_SlowTracking 0xbf 832 + #define HidUsage_Con_FrameForward 0xc0 833 + #define HidUsage_Con_FrameBack 0xc1 834 + #define HidUsage_Con_Mark 0xc2 835 + #define HidUsage_Con_ClearMark 0xc3 836 + #define HidUsage_Con_RepeatFromMark 0xc4 837 + #define HidUsage_Con_ReturnToMark 0xc5 838 + #define HidUsage_Con_SearchMarkForward 0xc6 839 + #define HidUsage_Con_SearchMarkBackwards 0xc7 840 + #define HidUsage_Con_CounterReset 0xc8 841 + #define HidUsage_Con_ShowCounter 0xc9 842 + #define HidUsage_Con_TrackingIncrement 0xca 843 + #define HidUsage_Con_TrackingDecrement 0xcb 844 + #define HidUsage_Con_StopEject 0xcc 845 + #define HidUsage_Con_PlayPause 0xcd 846 + #define HidUsage_Con_PlaySkip 0xce 847 + #define HidUsage_Con_VoiceCommand 0xcf 848 + #define HidUsage_Con_InvokeCaptureInterface 0xd0 849 + #define HidUsage_Con_StartorStopGameRecording 0xd1 850 + #define HidUsage_Con_HistoricalGameCapture 0xd2 851 + #define HidUsage_Con_CaptureGameScreenshot 0xd3 852 + #define HidUsage_Con_ShoworHideRecordingIndicator 0xd4 853 + #define HidUsage_Con_StartorStopMicrophoneCapture 0xd5 854 + #define HidUsage_Con_StartorStopCameraCapture 0xd6 855 + #define HidUsage_Con_StartorStopGameBroadcast 0xd7 856 + #define HidUsage_Con_StartorStopVoiceDictationSession 0xd8 857 + #define HidUsage_Con_InvokeDismissEmojiPicker 0xd9 858 + #define HidUsage_Con_Volume 0xe0 859 + #define HidUsage_Con_Balance 0xe1 860 + #define HidUsage_Con_Mute 0xe2 861 + #define HidUsage_Con_Bass 0xe3 862 + #define HidUsage_Con_Treble 0xe4 863 + #define HidUsage_Con_BassBoost 0xe5 864 + #define HidUsage_Con_SurroundMode 0xe6 865 + #define HidUsage_Con_Loudness 0xe7 866 + #define HidUsage_Con_MPX 0xe8 867 + #define HidUsage_Con_VolumeIncrement 0xe9 868 + #define HidUsage_Con_VolumeDecrement 0xea 869 + #define HidUsage_Con_SpeedSelect 0xf0 870 + #define HidUsage_Con_PlaybackSpeed 0xf1 871 + #define HidUsage_Con_StandardPlay 0xf2 872 + #define HidUsage_Con_LongPlay 0xf3 873 + #define HidUsage_Con_ExtendedPlay 0xf4 874 + #define HidUsage_Con_Slow 0xf5 875 + #define HidUsage_Con_FanEnable 0x100 876 + #define HidUsage_Con_FanSpeed 0x101 877 + #define HidUsage_Con_LightEnable 0x102 878 + #define HidUsage_Con_LightIlluminationLevel 0x103 879 + #define HidUsage_Con_ClimateControlEnable 0x104 880 + #define HidUsage_Con_RoomTemperature 0x105 881 + #define HidUsage_Con_SecurityEnable 0x106 882 + #define HidUsage_Con_FireAlarm 0x107 883 + #define HidUsage_Con_PoliceAlarm 0x108 884 + #define HidUsage_Con_Proximity 0x109 885 + #define HidUsage_Con_Motion 0x10a 886 + #define HidUsage_Con_DuressAlarm 0x10b 887 + #define HidUsage_Con_HoldupAlarm 0x10c 888 + #define HidUsage_Con_MedicalAlarm 0x10d 889 + #define HidUsage_Con_BalanceRight 0x150 890 + #define HidUsage_Con_BalanceLeft 0x151 891 + #define HidUsage_Con_BassIncrement 0x152 892 + #define HidUsage_Con_BassDecrement 0x153 893 + #define HidUsage_Con_TrebleIncrement 0x154 894 + #define HidUsage_Con_TrebleDecrement 0x155 895 + #define HidUsage_Con_SpeakerSystem 0x160 896 + #define HidUsage_Con_ChannelLeft 0x161 897 + #define HidUsage_Con_ChannelRight 0x162 898 + #define HidUsage_Con_ChannelCenter 0x163 899 + #define HidUsage_Con_ChannelFront 0x164 900 + #define HidUsage_Con_ChannelCenterFront 0x165 901 + #define HidUsage_Con_ChannelSide 0x166 902 + #define HidUsage_Con_ChannelSurround 0x167 903 + #define HidUsage_Con_ChannelLowFrequencyEnhancement 0x168 904 + #define HidUsage_Con_ChannelTop 0x169 905 + #define HidUsage_Con_ChannelUnknown 0x16a 906 + #define HidUsage_Con_Subchannel 0x170 907 + #define HidUsage_Con_SubchannelIncrement 0x171 908 + #define HidUsage_Con_SubchannelDecrement 0x172 909 + #define HidUsage_Con_AlternateAudioIncrement 0x173 910 + #define HidUsage_Con_AlternateAudioDecrement 0x174 911 + #define HidUsage_Con_ApplicationLaunchButtons 0x180 912 + #define HidUsage_Con_ALLaunchButtonConfigurationTool 0x181 913 + #define HidUsage_Con_ALProgrammableButtonConfiguration 0x182 914 + #define HidUsage_Con_ALConsumerControlConfiguration 0x183 915 + #define HidUsage_Con_ALWordProcessor 0x184 916 + #define HidUsage_Con_ALTextEditor 0x185 917 + #define HidUsage_Con_ALSpreadsheet 0x186 918 + #define HidUsage_Con_ALGraphicsEditor 0x187 919 + #define HidUsage_Con_ALPresentationApp 0x188 920 + #define HidUsage_Con_ALDatabaseApp 0x189 921 + #define HidUsage_Con_ALEmailReader 0x18a 922 + #define HidUsage_Con_ALNewsreader 0x18b 923 + #define HidUsage_Con_ALVoicemail 0x18c 924 + #define HidUsage_Con_ALContactsAddressBook 0x18d 925 + #define HidUsage_Con_ALCalendarSchedule 0x18e 926 + #define HidUsage_Con_ALTaskProjectManager 0x18f 927 + #define HidUsage_Con_ALLogJournalTimecard 0x190 928 + #define HidUsage_Con_ALCheckbookFinance 0x191 929 + #define HidUsage_Con_ALCalculator 0x192 930 + #define HidUsage_Con_ALAVCapturePlayback 0x193 931 + #define HidUsage_Con_ALLocalMachineBrowser 0x194 932 + #define HidUsage_Con_ALLANWANBrowser 0x195 933 + #define HidUsage_Con_ALInternetBrowser 0x196 934 + #define HidUsage_Con_ALRemoteNetworkingISPConnect 0x197 935 + #define HidUsage_Con_ALNetworkConference 0x198 936 + #define HidUsage_Con_ALNetworkChat 0x199 937 + #define HidUsage_Con_ALTelephonyDialer 0x19a 938 + #define HidUsage_Con_ALLogon 0x19b 939 + #define HidUsage_Con_ALLogoff 0x19c 940 + #define HidUsage_Con_ALLogonLogoff 0x19d 941 + #define HidUsage_Con_ALTerminalLockScreensaver 0x19e 942 + #define HidUsage_Con_ALControlPanel 0x19f 943 + #define HidUsage_Con_ALCommandLineProcessorRun 0x1a0 944 + #define HidUsage_Con_ALProcessTaskManager 0x1a1 945 + #define HidUsage_Con_ALSelectTaskApplication 0x1a2 946 + #define HidUsage_Con_ALNextTaskApplication 0x1a3 947 + #define HidUsage_Con_ALPreviousTaskApplication 0x1a4 948 + #define HidUsage_Con_ALPreemptiveHaltTaskApplication 0x1a5 949 + #define HidUsage_Con_ALIntegratedHelpCenter 0x1a6 950 + #define HidUsage_Con_ALDocuments 0x1a7 951 + #define HidUsage_Con_ALThesaurus 0x1a8 952 + #define HidUsage_Con_ALDictionary 0x1a9 953 + #define HidUsage_Con_ALDesktop 0x1aa 954 + #define HidUsage_Con_ALSpellCheck 0x1ab 955 + #define HidUsage_Con_ALGrammarCheck 0x1ac 956 + #define HidUsage_Con_ALWirelessStatus 0x1ad 957 + #define HidUsage_Con_ALKeyboardLayout 0x1ae 958 + #define HidUsage_Con_ALVirusProtection 0x1af 959 + #define HidUsage_Con_ALEncryption 0x1b0 960 + #define HidUsage_Con_ALScreenSaver 0x1b1 961 + #define HidUsage_Con_ALAlarms 0x1b2 962 + #define HidUsage_Con_ALClock 0x1b3 963 + #define HidUsage_Con_ALFileBrowser 0x1b4 964 + #define HidUsage_Con_ALPowerStatus 0x1b5 965 + #define HidUsage_Con_ALImageBrowser 0x1b6 966 + #define HidUsage_Con_ALAudioBrowser 0x1b7 967 + #define HidUsage_Con_ALMovieBrowser 0x1b8 968 + #define HidUsage_Con_ALDigitalRightsManager 0x1b9 969 + #define HidUsage_Con_ALDigitalWallet 0x1ba 970 + #define HidUsage_Con_ALInstantMessaging 0x1bc 971 + #define HidUsage_Con_ALOEMFeaturesTipsTutorialBrowser 0x1bd 972 + #define HidUsage_Con_ALOEMHelp 0x1be 973 + #define HidUsage_Con_ALOnlineCommunity 0x1bf 974 + #define HidUsage_Con_ALEntertainmentContentBrowser 0x1c0 975 + #define HidUsage_Con_ALOnlineShoppingBrowser 0x1c1 976 + #define HidUsage_Con_ALSmartCardInformationHelp 0x1c2 977 + #define HidUsage_Con_ALMarketMonitorFinanceBrowser 0x1c3 978 + #define HidUsage_Con_ALCustomizedCorporateNewsBrowser 0x1c4 979 + #define HidUsage_Con_ALOnlineActivityBrowser 0x1c5 980 + #define HidUsage_Con_ALResearchSearchBrowser 0x1c6 981 + #define HidUsage_Con_ALAudioPlayer 0x1c7 982 + #define HidUsage_Con_ALMessageStatus 0x1c8 983 + #define HidUsage_Con_ALContactSync 0x1c9 984 + #define HidUsage_Con_ALNavigation 0x1ca 985 + #define HidUsage_Con_ALContextawareDesktopAssistant 0x1cb 986 + #define HidUsage_Con_GenericGUIApplicationControls 0x200 987 + #define HidUsage_Con_ACNew 0x201 988 + #define HidUsage_Con_ACOpen 0x202 989 + #define HidUsage_Con_ACClose 0x203 990 + #define HidUsage_Con_ACExit 0x204 991 + #define HidUsage_Con_ACMaximize 0x205 992 + #define HidUsage_Con_ACMinimize 0x206 993 + #define HidUsage_Con_ACSave 0x207 994 + #define HidUsage_Con_ACPrint 0x208 995 + #define HidUsage_Con_ACProperties 0x209 996 + #define HidUsage_Con_ACUndo 0x21a 997 + #define HidUsage_Con_ACCopy 0x21b 998 + #define HidUsage_Con_ACCut 0x21c 999 + #define HidUsage_Con_ACPaste 0x21d 1000 + #define HidUsage_Con_ACSelectAll 0x21e 1001 + #define HidUsage_Con_ACFind 0x21f 1002 + #define HidUsage_Con_ACFindandReplace 0x220 1003 + #define HidUsage_Con_ACSearch 0x221 1004 + #define HidUsage_Con_ACGoTo 0x222 1005 + #define HidUsage_Con_ACHome 0x223 1006 + #define HidUsage_Con_ACBack 0x224 1007 + #define HidUsage_Con_ACForward 0x225 1008 + #define HidUsage_Con_ACStop 0x226 1009 + #define HidUsage_Con_ACRefresh 0x227 1010 + #define HidUsage_Con_ACPreviousLink 0x228 1011 + #define HidUsage_Con_ACNextLink 0x229 1012 + #define HidUsage_Con_ACBookmarks 0x22a 1013 + #define HidUsage_Con_ACHistory 0x22b 1014 + #define HidUsage_Con_ACSubscriptions 0x22c 1015 + #define HidUsage_Con_ACZoomIn 0x22d 1016 + #define HidUsage_Con_ACZoomOut 0x22e 1017 + #define HidUsage_Con_ACZoom 0x22f 1018 + #define HidUsage_Con_ACFullScreenView 0x230 1019 + #define HidUsage_Con_ACNormalView 0x231 1020 + #define HidUsage_Con_ACViewToggle 0x232 1021 + #define HidUsage_Con_ACScrollUp 0x233 1022 + #define HidUsage_Con_ACScrollDown 0x234 1023 + #define HidUsage_Con_ACScroll 0x235 1024 + #define HidUsage_Con_ACPanLeft 0x236 1025 + #define HidUsage_Con_ACPanRight 0x237 1026 + #define HidUsage_Con_ACPan 0x238 1027 + #define HidUsage_Con_ACNewWindow 0x239 1028 + #define HidUsage_Con_ACTileHorizontally 0x23a 1029 + #define HidUsage_Con_ACTileVertically 0x23b 1030 + #define HidUsage_Con_ACFormat 0x23c 1031 + #define HidUsage_Con_ACEdit 0x23d 1032 + #define HidUsage_Con_ACBold 0x23e 1033 + #define HidUsage_Con_ACItalics 0x23f 1034 + #define HidUsage_Con_ACUnderline 0x240 1035 + #define HidUsage_Con_ACStrikethrough 0x241 1036 + #define HidUsage_Con_ACSubscript 0x242 1037 + #define HidUsage_Con_ACSuperscript 0x243 1038 + #define HidUsage_Con_ACAllCaps 0x244 1039 + #define HidUsage_Con_ACRotate 0x245 1040 + #define HidUsage_Con_ACResize 0x246 1041 + #define HidUsage_Con_ACFlipHorizontal 0x247 1042 + #define HidUsage_Con_ACFlipVertical 0x248 1043 + #define HidUsage_Con_ACMirrorHorizontal 0x249 1044 + #define HidUsage_Con_ACMirrorVertical 0x24a 1045 + #define HidUsage_Con_ACFontSelect 0x24b 1046 + #define HidUsage_Con_ACFontColor 0x24c 1047 + #define HidUsage_Con_ACFontSize 0x24d 1048 + #define HidUsage_Con_ACJustifyLeft 0x24e 1049 + #define HidUsage_Con_ACJustifyCenterH 0x24f 1050 + #define HidUsage_Con_ACJustifyRight 0x250 1051 + #define HidUsage_Con_ACJustifyBlockH 0x251 1052 + #define HidUsage_Con_ACJustifyTop 0x252 1053 + #define HidUsage_Con_ACJustifyCenterV 0x253 1054 + #define HidUsage_Con_ACJustifyBottom 0x254 1055 + #define HidUsage_Con_ACJustifyBlockV 0x255 1056 + #define HidUsage_Con_ACIndentDecrease 0x256 1057 + #define HidUsage_Con_ACIndentIncrease 0x257 1058 + #define HidUsage_Con_ACNumberedList 0x258 1059 + #define HidUsage_Con_ACRestartNumbering 0x259 1060 + #define HidUsage_Con_ACBulletedList 0x25a 1061 + #define HidUsage_Con_ACPromote 0x25b 1062 + #define HidUsage_Con_ACDemote 0x25c 1063 + #define HidUsage_Con_ACYes 0x25d 1064 + #define HidUsage_Con_ACNo 0x25e 1065 + #define HidUsage_Con_ACCancel 0x25f 1066 + #define HidUsage_Con_ACCatalog 0x260 1067 + #define HidUsage_Con_ACBuyCheckout 0x261 1068 + #define HidUsage_Con_ACAddtoCart 0x262 1069 + #define HidUsage_Con_ACExpand 0x263 1070 + #define HidUsage_Con_ACExpandAll 0x264 1071 + #define HidUsage_Con_ACCollapse 0x265 1072 + #define HidUsage_Con_ACCollapseAll 0x266 1073 + #define HidUsage_Con_ACPrintPreview 0x267 1074 + #define HidUsage_Con_ACPasteSpecial 0x268 1075 + #define HidUsage_Con_ACInsertMode 0x269 1076 + #define HidUsage_Con_ACDelete 0x26a 1077 + #define HidUsage_Con_ACLock 0x26b 1078 + #define HidUsage_Con_ACUnlock 0x26c 1079 + #define HidUsage_Con_ACProtect 0x26d 1080 + #define HidUsage_Con_ACUnprotect 0x26e 1081 + #define HidUsage_Con_ACAttachComment 0x26f 1082 + #define HidUsage_Con_ACDeleteComment 0x270 1083 + #define HidUsage_Con_ACViewComment 0x271 1084 + #define HidUsage_Con_ACSelectWord 0x272 1085 + #define HidUsage_Con_ACSelectSentence 0x273 1086 + #define HidUsage_Con_ACSelectParagraph 0x274 1087 + #define HidUsage_Con_ACSelectColumn 0x275 1088 + #define HidUsage_Con_ACSelectRow 0x276 1089 + #define HidUsage_Con_ACSelectTable 0x277 1090 + #define HidUsage_Con_ACSelectObject 0x278 1091 + #define HidUsage_Con_ACRedoRepeat 0x279 1092 + #define HidUsage_Con_ACSort 0x27a 1093 + #define HidUsage_Con_ACSortAscending 0x27b 1094 + #define HidUsage_Con_ACSortDescending 0x27c 1095 + #define HidUsage_Con_ACFilter 0x27d 1096 + #define HidUsage_Con_ACSetClock 0x27e 1097 + #define HidUsage_Con_ACViewClock 0x27f 1098 + #define HidUsage_Con_ACSelectTimeZone 0x280 1099 + #define HidUsage_Con_ACEditTimeZones 0x281 1100 + #define HidUsage_Con_ACSetAlarm 0x282 1101 + #define HidUsage_Con_ACClearAlarm 0x283 1102 + #define HidUsage_Con_ACSnoozeAlarm 0x284 1103 + #define HidUsage_Con_ACResetAlarm 0x285 1104 + #define HidUsage_Con_ACSynchronize 0x286 1105 + #define HidUsage_Con_ACSendReceive 0x287 1106 + #define HidUsage_Con_ACSendTo 0x288 1107 + #define HidUsage_Con_ACReply 0x289 1108 + #define HidUsage_Con_ACReplyAll 0x28a 1109 + #define HidUsage_Con_ACForwardMsg 0x28b 1110 + #define HidUsage_Con_ACSend 0x28c 1111 + #define HidUsage_Con_ACAttachFile 0x28d 1112 + #define HidUsage_Con_ACUpload 0x28e 1113 + #define HidUsage_Con_ACDownloadSaveTargetAs 0x28f 1114 + #define HidUsage_Con_ACSetBorders 0x290 1115 + #define HidUsage_Con_ACInsertRow 0x291 1116 + #define HidUsage_Con_ACInsertColumn 0x292 1117 + #define HidUsage_Con_ACInsertFile 0x293 1118 + #define HidUsage_Con_ACInsertPicture 0x294 1119 + #define HidUsage_Con_ACInsertObject 0x295 1120 + #define HidUsage_Con_ACInsertSymbol 0x296 1121 + #define HidUsage_Con_ACSaveandClose 0x297 1122 + #define HidUsage_Con_ACRename 0x298 1123 + #define HidUsage_Con_ACMerge 0x299 1124 + #define HidUsage_Con_ACSplit 0x29a 1125 + #define HidUsage_Con_ACDisributeHorizontally 0x29b 1126 + #define HidUsage_Con_ACDistributeVertically 0x29c 1127 + #define HidUsage_Con_ACNextKeyboardLayoutSelect 0x29d 1128 + #define HidUsage_Con_ACNavigationGuidance 0x29e 1129 + #define HidUsage_Con_ACDesktopShowAllWindows 0x29f 1130 + #define HidUsage_Con_ACSoftKeyLeft 0x2a0 1131 + #define HidUsage_Con_ACSoftKeyRight 0x2a1 1132 + #define HidUsage_Con_ACDesktopShowAllApplications 0x2a2 1133 + #define HidUsage_Con_ACIdleKeepAlive 0x2b0 1134 + #define HidUsage_Con_ExtendedKeyboardAttributesCollection 0x2c0 1135 + #define HidUsage_Con_KeyboardFormFactor 0x2c1 1136 + #define HidUsage_Con_KeyboardKeyType 0x2c2 1137 + #define HidUsage_Con_KeyboardPhysicalLayout 0x2c3 1138 + #define HidUsage_Con_VendorSpecificKeyboardPhysicalLayout 0x2c4 1139 + #define HidUsage_Con_KeyboardIETFLanguageTagIndex 0x2c5 1140 + #define HidUsage_Con_ImplementedKeyboardInputAssistControls 0x2c6 1141 + #define HidUsage_Con_KeyboardInputAssistPrevious 0x2c7 1142 + #define HidUsage_Con_KeyboardInputAssistNext 0x2c8 1143 + #define HidUsage_Con_KeyboardInputAssistPreviousGroup 0x2c9 1144 + #define HidUsage_Con_KeyboardInputAssistNextGroup 0x2ca 1145 + #define HidUsage_Con_KeyboardInputAssistAccept 0x2cb 1146 + #define HidUsage_Con_KeyboardInputAssistCancel 0x2cc 1147 + #define HidUsage_Con_PrivacyScreenToggle 0x2d0 1148 + #define HidUsage_Con_PrivacyScreenLevelDecrement 0x2d1 1149 + #define HidUsage_Con_PrivacyScreenLevelIncrement 0x2d2 1150 + #define HidUsage_Con_PrivacyScreenLevelMinimum 0x2d3 1151 + #define HidUsage_Con_PrivacyScreenLevelMaximum 0x2d4 1152 + #define HidUsage_Con_ContactEdited 0x500 1153 + #define HidUsage_Con_ContactAdded 0x501 1154 + #define HidUsage_Con_ContactRecordActive 0x502 1155 + #define HidUsage_Con_ContactIndex 0x503 1156 + #define HidUsage_Con_ContactNickname 0x504 1157 + #define HidUsage_Con_ContactFirstName 0x505 1158 + #define HidUsage_Con_ContactLastName 0x506 1159 + #define HidUsage_Con_ContactFullName 0x507 1160 + #define HidUsage_Con_ContactPhoneNumberPersonal 0x508 1161 + #define HidUsage_Con_ContactPhoneNumberBusiness 0x509 1162 + #define HidUsage_Con_ContactPhoneNumberMobile 0x50a 1163 + #define HidUsage_Con_ContactPhoneNumberPager 0x50b 1164 + #define HidUsage_Con_ContactPhoneNumberFax 0x50c 1165 + #define HidUsage_Con_ContactPhoneNumberOther 0x50d 1166 + #define HidUsage_Con_ContactEmailPersonal 0x50e 1167 + #define HidUsage_Con_ContactEmailBusiness 0x50f 1168 + #define HidUsage_Con_ContactEmailOther 0x510 1169 + #define HidUsage_Con_ContactEmailMain 0x511 1170 + #define HidUsage_Con_ContactSpeedDialNumber 0x512 1171 + #define HidUsage_Con_ContactStatusFlag 0x513 1172 + #define HidUsage_Con_ContactMisc 0x514 1173 + #define HidUsage_Dig_Digitizer 0x01 1174 + #define HidUsage_Dig_Pen 0x02 1175 + #define HidUsage_Dig_LightPen 0x03 1176 + #define HidUsage_Dig_TouchScreen 0x04 1177 + #define HidUsage_Dig_TouchPad 0x05 1178 + #define HidUsage_Dig_Whiteboard 0x06 1179 + #define HidUsage_Dig_CoordinateMeasuringMachine 0x07 1180 + #define HidUsage_Dig_ThreeDDigitizer 0x08 1181 + #define HidUsage_Dig_StereoPlotter 0x09 1182 + #define HidUsage_Dig_ArticulatedArm 0x0a 1183 + #define HidUsage_Dig_Armature 0x0b 1184 + #define HidUsage_Dig_MultiplePointDigitizer 0x0c 1185 + #define HidUsage_Dig_FreeSpaceWand 0x0d 1186 + #define HidUsage_Dig_DeviceConfiguration 0x0e 1187 + #define HidUsage_Dig_CapacitiveHeatMapDigitizer 0x0f 1188 + #define HidUsage_Dig_Stylus 0x20 1189 + #define HidUsage_Dig_Puck 0x21 1190 + #define HidUsage_Dig_Finger 0x22 1191 + #define HidUsage_Dig_Devicesettings 0x23 1192 + #define HidUsage_Dig_CharacterGesture 0x24 1193 + #define HidUsage_Dig_TipPressure 0x30 1194 + #define HidUsage_Dig_BarrelPressure 0x31 1195 + #define HidUsage_Dig_InRange 0x32 1196 + #define HidUsage_Dig_Touch 0x33 1197 + #define HidUsage_Dig_Untouch 0x34 1198 + #define HidUsage_Dig_Tap 0x35 1199 + #define HidUsage_Dig_Quality 0x36 1200 + #define HidUsage_Dig_DataValid 0x37 1201 + #define HidUsage_Dig_TransducerIndex 0x38 1202 + #define HidUsage_Dig_TabletFunctionKeys 0x39 1203 + #define HidUsage_Dig_ProgramChangeKeys 0x3a 1204 + #define HidUsage_Dig_BatteryStrength 0x3b 1205 + #define HidUsage_Dig_Invert 0x3c 1206 + #define HidUsage_Dig_XTilt 0x3d 1207 + #define HidUsage_Dig_YTilt 0x3e 1208 + #define HidUsage_Dig_Azimuth 0x3f 1209 + #define HidUsage_Dig_Altitude 0x40 1210 + #define HidUsage_Dig_Twist 0x41 1211 + #define HidUsage_Dig_TipSwitch 0x42 1212 + #define HidUsage_Dig_SecondaryTipSwitch 0x43 1213 + #define HidUsage_Dig_BarrelSwitch 0x44 1214 + #define HidUsage_Dig_Eraser 0x45 1215 + #define HidUsage_Dig_TabletPick 0x46 1216 + #define HidUsage_Dig_TouchValid 0x47 1217 + #define HidUsage_Dig_Width 0x48 1218 + #define HidUsage_Dig_Height 0x49 1219 + #define HidUsage_Dig_ContactIdentifier 0x51 1220 + #define HidUsage_Dig_DeviceMode 0x52 1221 + #define HidUsage_Dig_DeviceIdentifier 0x53 1222 + #define HidUsage_Dig_ContactCount 0x54 1223 + #define HidUsage_Dig_ContactCountMaximum 0x55 1224 + #define HidUsage_Dig_ScanTime 0x56 1225 + #define HidUsage_Dig_SurfaceSwitch 0x57 1226 + #define HidUsage_Dig_ButtonSwitch 0x58 1227 + #define HidUsage_Dig_PadType 0x59 1228 + #define HidUsage_Dig_SecondaryBarrelSwitch 0x5a 1229 + #define HidUsage_Dig_TransducerSerialNumber 0x5b 1230 + #define HidUsage_Dig_PreferredColor 0x5c 1231 + #define HidUsage_Dig_PreferredColorisLocked 0x5d 1232 + #define HidUsage_Dig_PreferredLineWidth 0x5e 1233 + #define HidUsage_Dig_PreferredLineWidthisLocked 0x5f 1234 + #define HidUsage_Dig_LatencyMode 0x60 1235 + #define HidUsage_Dig_GestureCharacterQuality 0x61 1236 + #define HidUsage_Dig_CharacterGestureDataLength 0x62 1237 + #define HidUsage_Dig_CharacterGestureData 0x63 1238 + #define HidUsage_Dig_GestureCharacterEncoding 0x64 1239 + #define HidUsage_Dig_UTF8CharacterGestureEncoding 0x65 1240 + #define HidUsage_Dig_UTF16LittleEndianCharacterGestureEncoding 0x66 1241 + #define HidUsage_Dig_UTF16BigEndianCharacterGestureEncoding 0x67 1242 + #define HidUsage_Dig_UTF32LittleEndianCharacterGestureEncoding 0x68 1243 + #define HidUsage_Dig_UTF32BigEndianCharacterGestureEncoding 0x69 1244 + #define HidUsage_Dig_CapacitiveHeatMapProtocolVendorID 0x6a 1245 + #define HidUsage_Dig_CapacitiveHeatMapProtocolVersion 0x6b 1246 + #define HidUsage_Dig_CapacitiveHeatMapFrameData 0x6c 1247 + #define HidUsage_Dig_GestureCharacterEnable 0x6d 1248 + #define HidUsage_Dig_TransducerSerialNumberPart2 0x6e 1249 + #define HidUsage_Dig_NoPreferredColor 0x6f 1250 + #define HidUsage_Dig_PreferredLineStyle 0x70 1251 + #define HidUsage_Dig_PreferredLineStyleisLocked 0x71 1252 + #define HidUsage_Dig_Ink 0x72 1253 + #define HidUsage_Dig_Pencil 0x73 1254 + #define HidUsage_Dig_Highlighter 0x74 1255 + #define HidUsage_Dig_ChiselMarker 0x75 1256 + #define HidUsage_Dig_Brush 0x76 1257 + #define HidUsage_Dig_NoPreference 0x77 1258 + #define HidUsage_Dig_DigitizerDiagnostic 0x80 1259 + #define HidUsage_Dig_DigitizerError 0x81 1260 + #define HidUsage_Dig_ErrNormalStatus 0x82 1261 + #define HidUsage_Dig_ErrTransducersExceeded 0x83 1262 + #define HidUsage_Dig_ErrFullTransFeaturesUnavailable 0x84 1263 + #define HidUsage_Dig_ErrChargeLow 0x85 1264 + #define HidUsage_Dig_TransducerSoftwareInfo 0x90 1265 + #define HidUsage_Dig_TransducerVendorId 0x91 1266 + #define HidUsage_Dig_TransducerProductId 0x92 1267 + #define HidUsage_Dig_DeviceSupportedProtocols 0x93 1268 + #define HidUsage_Dig_TransducerSupportedProtocols 0x94 1269 + #define HidUsage_Dig_NoProtocol 0x95 1270 + #define HidUsage_Dig_WacomAESProtocol 0x96 1271 + #define HidUsage_Dig_USIProtocol 0x97 1272 + #define HidUsage_Dig_MicrosoftPenProtocol 0x98 1273 + #define HidUsage_Dig_SupportedReportRates 0xa0 1274 + #define HidUsage_Dig_ReportRate 0xa1 1275 + #define HidUsage_Dig_TransducerConnected 0xa2 1276 + #define HidUsage_Dig_SwitchDisabled 0xa3 1277 + #define HidUsage_Dig_SwitchUnimplemented 0xa4 1278 + #define HidUsage_Dig_TransducerSwitches 0xa5 1279 + #define HidUsage_Dig_TransducerIndexSelector 0xa6 1280 + #define HidUsage_Dig_ButtonPressThreshold 0xb0 1281 + #define HidUsage_Hap_SimpleHapticController 0x01 1282 + #define HidUsage_Hap_WaveformList 0x10 1283 + #define HidUsage_Hap_DurationList 0x11 1284 + #define HidUsage_Hap_AutoTrigger 0x20 1285 + #define HidUsage_Hap_ManualTrigger 0x21 1286 + #define HidUsage_Hap_AutoTriggerAssociatedControl 0x22 1287 + #define HidUsage_Hap_Intensity 0x23 1288 + #define HidUsage_Hap_RepeatCount 0x24 1289 + #define HidUsage_Hap_RetriggerPeriod 0x25 1290 + #define HidUsage_Hap_WaveformVendorPage 0x26 1291 + #define HidUsage_Hap_WaveformVendorID 0x27 1292 + #define HidUsage_Hap_WaveformCutoffTime 0x28 1293 + #define HidUsage_Hap_WaveformNone 0x1001 1294 + #define HidUsage_Hap_WaveformStop 0x1002 1295 + #define HidUsage_Hap_WaveformClick 0x1003 1296 + #define HidUsage_Hap_WaveformBuzzContinuous 0x1004 1297 + #define HidUsage_Hap_WaveformRumbleContinuous 0x1005 1298 + #define HidUsage_Hap_WaveformPress 0x1006 1299 + #define HidUsage_Hap_WaveformRelease 0x1007 1300 + #define HidUsage_Hap_WaveformHover 0x1008 1301 + #define HidUsage_Hap_WaveformSuccess 0x1009 1302 + #define HidUsage_Hap_WaveformError 0x100a 1303 + #define HidUsage_Hap_WaveformInkContinuous 0x100b 1304 + #define HidUsage_Hap_WaveformPencilContinuous 0x100c 1305 + #define HidUsage_Hap_WaveformMarkerContinuous 0x100d 1306 + #define HidUsage_Hap_WaveformChiselMarkerContinuous 0x100e 1307 + #define HidUsage_Hap_WaveformBrushContinuous 0x100f 1308 + #define HidUsage_Hap_WaveformEraserContinuous 0x1010 1309 + #define HidUsage_Hap_WaveformSparkleContinuous 0x1011 1310 + #define HidUsage_PID_PhysicalInputDevice 0x01 1311 + #define HidUsage_PID_Normal 0x20 1312 + #define HidUsage_PID_SetEffectReport 0x21 1313 + #define HidUsage_PID_EffectParameterBlockIndex 0x22 1314 + #define HidUsage_PID_ParameterBlockOffset 0x23 1315 + #define HidUsage_PID_ROMFlag 0x24 1316 + #define HidUsage_PID_EffectType 0x25 1317 + #define HidUsage_PID_ETConstantForce 0x26 1318 + #define HidUsage_PID_ETRamp 0x27 1319 + #define HidUsage_PID_ETCustomForce 0x28 1320 + #define HidUsage_PID_ETSquare 0x30 1321 + #define HidUsage_PID_ETSine 0x31 1322 + #define HidUsage_PID_ETTriangle 0x32 1323 + #define HidUsage_PID_ETSawtoothUp 0x33 1324 + #define HidUsage_PID_ETSawtoothDown 0x34 1325 + #define HidUsage_PID_ETSpring 0x40 1326 + #define HidUsage_PID_ETDamper 0x41 1327 + #define HidUsage_PID_ETInertia 0x42 1328 + #define HidUsage_PID_ETFriction 0x43 1329 + #define HidUsage_PID_Duration 0x50 1330 + #define HidUsage_PID_SamplePeriod 0x51 1331 + #define HidUsage_PID_Gain 0x52 1332 + #define HidUsage_PID_TriggerButton 0x53 1333 + #define HidUsage_PID_TriggerRepeatInterval 0x54 1334 + #define HidUsage_PID_AxesEnable 0x55 1335 + #define HidUsage_PID_DirectionEnable 0x56 1336 + #define HidUsage_PID_Direction 0x57 1337 + #define HidUsage_PID_TypeSpecificBlockOffset 0x58 1338 + #define HidUsage_PID_BlockType 0x59 1339 + #define HidUsage_PID_SetEnvelopeReport 0x5a 1340 + #define HidUsage_PID_AttackLevel 0x5b 1341 + #define HidUsage_PID_AttackTime 0x5c 1342 + #define HidUsage_PID_FadeLevel 0x5d 1343 + #define HidUsage_PID_FadeTime 0x5e 1344 + #define HidUsage_PID_SetConditionReport 0x5f 1345 + #define HidUsage_PID_CenterPointOffset 0x60 1346 + #define HidUsage_PID_PositiveCoefficient 0x61 1347 + #define HidUsage_PID_NegativeCoefficient 0x62 1348 + #define HidUsage_PID_PositiveSaturation 0x63 1349 + #define HidUsage_PID_NegativeSaturation 0x64 1350 + #define HidUsage_PID_DeadBand 0x65 1351 + #define HidUsage_PID_DownloadForceSample 0x66 1352 + #define HidUsage_PID_IsochCustomForceEnable 0x67 1353 + #define HidUsage_PID_CustomForceDataReport 0x68 1354 + #define HidUsage_PID_CustomForceData 0x69 1355 + #define HidUsage_PID_CustomForceVendorDefinedData 0x6a 1356 + #define HidUsage_PID_SetCustomForceReport 0x6b 1357 + #define HidUsage_PID_CustomForceDataOffset 0x6c 1358 + #define HidUsage_PID_SampleCount 0x6d 1359 + #define HidUsage_PID_SetPeriodicReport 0x6e 1360 + #define HidUsage_PID_Offset 0x6f 1361 + #define HidUsage_PID_Magnitude 0x70 1362 + #define HidUsage_PID_Phase 0x71 1363 + #define HidUsage_PID_Period 0x72 1364 + #define HidUsage_PID_SetConstantForceReport 0x73 1365 + #define HidUsage_PID_SetRampForceReport 0x74 1366 + #define HidUsage_PID_RampStart 0x75 1367 + #define HidUsage_PID_RampEnd 0x76 1368 + #define HidUsage_PID_EffectOperationReport 0x77 1369 + #define HidUsage_PID_EffectOperation 0x78 1370 + #define HidUsage_PID_OpEffectStart 0x79 1371 + #define HidUsage_PID_OpEffectStartSolo 0x7a 1372 + #define HidUsage_PID_OpEffectStop 0x7b 1373 + #define HidUsage_PID_LoopCount 0x7c 1374 + #define HidUsage_PID_DeviceGainReport 0x7d 1375 + #define HidUsage_PID_DeviceGain 0x7e 1376 + #define HidUsage_PID_ParameterBlockPoolsReport 0x7f 1377 + #define HidUsage_PID_RAMPoolSize 0x80 1378 + #define HidUsage_PID_ROMPoolSize 0x81 1379 + #define HidUsage_PID_ROMEffectBlockCount 0x82 1380 + #define HidUsage_PID_SimultaneousEffectsMax 0x83 1381 + #define HidUsage_PID_PoolAlignment 0x84 1382 + #define HidUsage_PID_ParameterBlockMoveReport 0x85 1383 + #define HidUsage_PID_MoveSource 0x86 1384 + #define HidUsage_PID_MoveDestination 0x87 1385 + #define HidUsage_PID_MoveLength 0x88 1386 + #define HidUsage_PID_EffectParameterBlockLoadReport 0x89 1387 + #define HidUsage_PID_EffectParameterBlockLoadStatus 0x8b 1388 + #define HidUsage_PID_BlockLoadSuccess 0x8c 1389 + #define HidUsage_PID_BlockLoadFull 0x8d 1390 + #define HidUsage_PID_BlockLoadError 0x8e 1391 + #define HidUsage_PID_BlockHandle 0x8f 1392 + #define HidUsage_PID_EffectParameterBlockFreeReport 0x90 1393 + #define HidUsage_PID_TypeSpecificBlockHandle 0x91 1394 + #define HidUsage_PID_PIDStateReport 0x92 1395 + #define HidUsage_PID_EffectPlaying 0x94 1396 + #define HidUsage_PID_PIDDeviceControlReport 0x95 1397 + #define HidUsage_PID_PIDDeviceControl 0x96 1398 + #define HidUsage_PID_DCEnableActuators 0x97 1399 + #define HidUsage_PID_DCDisableActuators 0x98 1400 + #define HidUsage_PID_DCStopAllEffects 0x99 1401 + #define HidUsage_PID_DCReset 0x9a 1402 + #define HidUsage_PID_DCPause 0x9b 1403 + #define HidUsage_PID_DCContinue 0x9c 1404 + #define HidUsage_PID_DevicePaused 0x9f 1405 + #define HidUsage_PID_ActuatorsEnabled 0xa0 1406 + #define HidUsage_PID_SafetySwitch 0xa4 1407 + #define HidUsage_PID_ActuatorOverrideSwitch 0xa5 1408 + #define HidUsage_PID_ActuatorPower 0xa6 1409 + #define HidUsage_PID_StartDelay 0xa7 1410 + #define HidUsage_PID_ParameterBlockSize 0xa8 1411 + #define HidUsage_PID_DeviceManagedPool 0xa9 1412 + #define HidUsage_PID_SharedParameterBlocks 0xaa 1413 + #define HidUsage_PID_CreateNewEffectParameterBlockReport 0xab 1414 + #define HidUsage_PID_RAMPoolAvailable 0xac 1415 + #define HidUsage_SC_SocControl 0x01 1416 + #define HidUsage_SC_FirmwareTransfer 0x02 1417 + #define HidUsage_SC_FirmwareFileId 0x03 1418 + #define HidUsage_SC_FileOffsetInBytes 0x04 1419 + #define HidUsage_SC_FileTransferSizeMaxInBytes 0x05 1420 + #define HidUsage_SC_FilePayload 0x06 1421 + #define HidUsage_SC_FilePayloadSizeInBytes 0x07 1422 + #define HidUsage_SC_FilePayloadContainsLastBytes 0x08 1423 + #define HidUsage_SC_FileTransferStop 0x09 1424 + #define HidUsage_SC_FileTransferTillEnd 0x0a 1425 + #define HidUsage_EHT_EyeTracker 0x01 1426 + #define HidUsage_EHT_HeadTracker 0x02 1427 + #define HidUsage_EHT_TrackingData 0x10 1428 + #define HidUsage_EHT_Capabilities 0x11 1429 + #define HidUsage_EHT_Configuration 0x12 1430 + #define HidUsage_EHT_Status 0x13 1431 + #define HidUsage_EHT_Control 0x14 1432 + #define HidUsage_EHT_SensorTimestamp 0x20 1433 + #define HidUsage_EHT_PositionX 0x21 1434 + #define HidUsage_EHT_PositionY 0x22 1435 + #define HidUsage_EHT_PositionZ 0x23 1436 + #define HidUsage_EHT_GazePoint 0x24 1437 + #define HidUsage_EHT_LeftEyePosition 0x25 1438 + #define HidUsage_EHT_RightEyePosition 0x26 1439 + #define HidUsage_EHT_HeadPosition 0x27 1440 + #define HidUsage_EHT_HeadDirectionPoint 0x28 1441 + #define HidUsage_EHT_RotationaboutXaxis 0x29 1442 + #define HidUsage_EHT_RotationaboutYaxis 0x2a 1443 + #define HidUsage_EHT_RotationaboutZaxis 0x2b 1444 + #define HidUsage_EHT_TrackerQuality 0x100 1445 + #define HidUsage_EHT_MinimumTrackingDistance 0x101 1446 + #define HidUsage_EHT_OptimumTrackingDistance 0x102 1447 + #define HidUsage_EHT_MaximumTrackingDistance 0x103 1448 + #define HidUsage_EHT_MaximumScreenPlaneWidth 0x104 1449 + #define HidUsage_EHT_MaximumScreenPlaneHeight 0x105 1450 + #define HidUsage_EHT_DisplayManufacturerID 0x200 1451 + #define HidUsage_EHT_DisplayProductID 0x201 1452 + #define HidUsage_EHT_DisplaySerialNumber 0x202 1453 + #define HidUsage_EHT_DisplayManufacturerDate 0x203 1454 + #define HidUsage_EHT_CalibratedScreenWidth 0x204 1455 + #define HidUsage_EHT_CalibratedScreenHeight 0x205 1456 + #define HidUsage_EHT_SamplingFrequency 0x300 1457 + #define HidUsage_EHT_ConfigurationStatus 0x301 1458 + #define HidUsage_EHT_DeviceModeRequest 0x400 1459 + #define HidUsage_AD_AlphanumericDisplay 0x01 1460 + #define HidUsage_AD_AuxiliaryDisplay 0x02 1461 + #define HidUsage_AD_DisplayAttributesReport 0x20 1462 + #define HidUsage_AD_ASCIICharacterSet 0x21 1463 + #define HidUsage_AD_DataReadBack 0x22 1464 + #define HidUsage_AD_FontReadBack 0x23 1465 + #define HidUsage_AD_DisplayControlReport 0x24 1466 + #define HidUsage_AD_ClearDisplay 0x25 1467 + #define HidUsage_AD_DisplayEnable 0x26 1468 + #define HidUsage_AD_ScreenSaverDelay 0x27 1469 + #define HidUsage_AD_ScreenSaverEnable 0x28 1470 + #define HidUsage_AD_VerticalScroll 0x29 1471 + #define HidUsage_AD_HorizontalScroll 0x2a 1472 + #define HidUsage_AD_CharacterReport 0x2b 1473 + #define HidUsage_AD_DisplayData 0x2c 1474 + #define HidUsage_AD_DisplayStatus 0x2d 1475 + #define HidUsage_AD_StatNotReady 0x2e 1476 + #define HidUsage_AD_StatReady 0x2f 1477 + #define HidUsage_AD_ErrNotaloadablecharacter 0x30 1478 + #define HidUsage_AD_ErrFontdatacannotberead 0x31 1479 + #define HidUsage_AD_CursorPositionReport 0x32 1480 + #define HidUsage_AD_Row 0x33 1481 + #define HidUsage_AD_Column 0x34 1482 + #define HidUsage_AD_Rows 0x35 1483 + #define HidUsage_AD_Columns 0x36 1484 + #define HidUsage_AD_CursorPixelPositioning 0x37 1485 + #define HidUsage_AD_CursorMode 0x38 1486 + #define HidUsage_AD_CursorEnable 0x39 1487 + #define HidUsage_AD_CursorBlink 0x3a 1488 + #define HidUsage_AD_FontReport 0x3b 1489 + #define HidUsage_AD_FontData 0x3c 1490 + #define HidUsage_AD_CharacterWidth 0x3d 1491 + #define HidUsage_AD_CharacterHeight 0x3e 1492 + #define HidUsage_AD_CharacterSpacingHorizontal 0x3f 1493 + #define HidUsage_AD_CharacterSpacingVertical 0x40 1494 + #define HidUsage_AD_UnicodeCharacterSet 0x41 1495 + #define HidUsage_AD_Font7Segment 0x42 1496 + #define HidUsage_AD_SevenSegmentDirectMap 0x43 1497 + #define HidUsage_AD_Font14Segment 0x44 1498 + #define HidUsage_AD_One4SegmentDirectMap 0x45 1499 + #define HidUsage_AD_DisplayBrightness 0x46 1500 + #define HidUsage_AD_DisplayContrast 0x47 1501 + #define HidUsage_AD_CharacterAttribute 0x48 1502 + #define HidUsage_AD_AttributeReadback 0x49 1503 + #define HidUsage_AD_AttributeData 0x4a 1504 + #define HidUsage_AD_CharAttrEnhance 0x4b 1505 + #define HidUsage_AD_CharAttrUnderline 0x4c 1506 + #define HidUsage_AD_CharAttrBlink 0x4d 1507 + #define HidUsage_AD_BitmapSizeX 0x80 1508 + #define HidUsage_AD_BitmapSizeY 0x81 1509 + #define HidUsage_AD_MaxBlitSize 0x82 1510 + #define HidUsage_AD_BitDepthFormat 0x83 1511 + #define HidUsage_AD_DisplayOrientation 0x84 1512 + #define HidUsage_AD_PaletteReport 0x85 1513 + #define HidUsage_AD_PaletteDataSize 0x86 1514 + #define HidUsage_AD_PaletteDataOffset 0x87 1515 + #define HidUsage_AD_PaletteData 0x88 1516 + #define HidUsage_AD_BlitReport 0x8a 1517 + #define HidUsage_AD_BlitRectangleX1 0x8b 1518 + #define HidUsage_AD_BlitRectangleY1 0x8c 1519 + #define HidUsage_AD_BlitRectangleX2 0x8d 1520 + #define HidUsage_AD_BlitRectangleY2 0x8e 1521 + #define HidUsage_AD_BlitData 0x8f 1522 + #define HidUsage_AD_SoftButton 0x90 1523 + #define HidUsage_AD_SoftButtonID 0x91 1524 + #define HidUsage_AD_SoftButtonSide 0x92 1525 + #define HidUsage_AD_SoftButtonOffset1 0x93 1526 + #define HidUsage_AD_SoftButtonOffset2 0x94 1527 + #define HidUsage_AD_SoftButtonReport 0x95 1528 + #define HidUsage_AD_SoftKeys 0xc2 1529 + #define HidUsage_AD_DisplayDataExtensions 0xcc 1530 + #define HidUsage_AD_CharacterMapping 0xcf 1531 + #define HidUsage_AD_UnicodeEquivalent 0xdd 1532 + #define HidUsage_AD_CharacterPageMapping 0xdf 1533 + #define HidUsage_AD_RequestReport 0xff 1534 + #define HidUsage_Sen_Sensor 0x01 1535 + #define HidUsage_Sen_Biometric 0x10 1536 + #define HidUsage_Sen_BiometricHumanPresence 0x11 1537 + #define HidUsage_Sen_BiometricHumanProximity 0x12 1538 + #define HidUsage_Sen_BiometricHumanTouch 0x13 1539 + #define HidUsage_Sen_BiometricBloodPressure 0x14 1540 + #define HidUsage_Sen_BiometricBodyTemperature 0x15 1541 + #define HidUsage_Sen_BiometricHeartRate 0x16 1542 + #define HidUsage_Sen_BiometricHeartRateVariability 0x17 1543 + #define HidUsage_Sen_BiometricPeripheralOxygenSaturation 0x18 1544 + #define HidUsage_Sen_BiometricRespiratoryRate 0x19 1545 + #define HidUsage_Sen_Electrical 0x20 1546 + #define HidUsage_Sen_ElectricalCapacitance 0x21 1547 + #define HidUsage_Sen_ElectricalCurrent 0x22 1548 + #define HidUsage_Sen_ElectricalPower 0x23 1549 + #define HidUsage_Sen_ElectricalInductance 0x24 1550 + #define HidUsage_Sen_ElectricalResistance 0x25 1551 + #define HidUsage_Sen_ElectricalVoltage 0x26 1552 + #define HidUsage_Sen_ElectricalPotentiometer 0x27 1553 + #define HidUsage_Sen_ElectricalFrequency 0x28 1554 + #define HidUsage_Sen_ElectricalPeriod 0x29 1555 + #define HidUsage_Sen_Environmental 0x30 1556 + #define HidUsage_Sen_EnvironmentalAtmosphericPressure 0x31 1557 + #define HidUsage_Sen_EnvironmentalHumidity 0x32 1558 + #define HidUsage_Sen_EnvironmentalTemperature 0x33 1559 + #define HidUsage_Sen_EnvironmentalWindDirection 0x34 1560 + #define HidUsage_Sen_EnvironmentalWindSpeed 0x35 1561 + #define HidUsage_Sen_EnvironmentalAirQuality 0x36 1562 + #define HidUsage_Sen_EnvironmentalHeatIndex 0x37 1563 + #define HidUsage_Sen_EnvironmentalSurfaceTemperature 0x38 1564 + #define HidUsage_Sen_EnvironmentalVolatileOrganicCompounds 0x39 1565 + #define HidUsage_Sen_EnvironmentalObjectPresence 0x3a 1566 + #define HidUsage_Sen_EnvironmentalObjectProximity 0x3b 1567 + #define HidUsage_Sen_Light 0x40 1568 + #define HidUsage_Sen_LightAmbientLight 0x41 1569 + #define HidUsage_Sen_LightConsumerInfrared 0x42 1570 + #define HidUsage_Sen_LightInfraredLight 0x43 1571 + #define HidUsage_Sen_LightVisibleLight 0x44 1572 + #define HidUsage_Sen_LightUltravioletLight 0x45 1573 + #define HidUsage_Sen_Location 0x50 1574 + #define HidUsage_Sen_LocationBroadcast 0x51 1575 + #define HidUsage_Sen_LocationDeadReckoning 0x52 1576 + #define HidUsage_Sen_LocationGPSGlobalPositioningSystem 0x53 1577 + #define HidUsage_Sen_LocationLookup 0x54 1578 + #define HidUsage_Sen_LocationOther 0x55 1579 + #define HidUsage_Sen_LocationStatic 0x56 1580 + #define HidUsage_Sen_LocationTriangulation 0x57 1581 + #define HidUsage_Sen_Mechanical 0x60 1582 + #define HidUsage_Sen_MechanicalBooleanSwitch 0x61 1583 + #define HidUsage_Sen_MechanicalBooleanSwitchArray 0x62 1584 + #define HidUsage_Sen_MechanicalMultivalueSwitch 0x63 1585 + #define HidUsage_Sen_MechanicalForce 0x64 1586 + #define HidUsage_Sen_MechanicalPressure 0x65 1587 + #define HidUsage_Sen_MechanicalStrain 0x66 1588 + #define HidUsage_Sen_MechanicalWeight 0x67 1589 + #define HidUsage_Sen_MechanicalHapticVibrator 0x68 1590 + #define HidUsage_Sen_MechanicalHallEffectSwitch 0x69 1591 + #define HidUsage_Sen_Motion 0x70 1592 + #define HidUsage_Sen_MotionAccelerometer1D 0x71 1593 + #define HidUsage_Sen_MotionAccelerometer2D 0x72 1594 + #define HidUsage_Sen_MotionAccelerometer3D 0x73 1595 + #define HidUsage_Sen_MotionGyrometer1D 0x74 1596 + #define HidUsage_Sen_MotionGyrometer2D 0x75 1597 + #define HidUsage_Sen_MotionGyrometer3D 0x76 1598 + #define HidUsage_Sen_MotionMotionDetector 0x77 1599 + #define HidUsage_Sen_MotionSpeedometer 0x78 1600 + #define HidUsage_Sen_MotionAccelerometer 0x79 1601 + #define HidUsage_Sen_MotionGyrometer 0x7a 1602 + #define HidUsage_Sen_MotionGravityVector 0x7b 1603 + #define HidUsage_Sen_MotionLinearAccelerometer 0x7c 1604 + #define HidUsage_Sen_Orientation 0x80 1605 + #define HidUsage_Sen_OrientationCompass1D 0x81 1606 + #define HidUsage_Sen_OrientationCompass2D 0x82 1607 + #define HidUsage_Sen_OrientationCompass3D 0x83 1608 + #define HidUsage_Sen_OrientationInclinometer1D 0x84 1609 + #define HidUsage_Sen_OrientationInclinometer2D 0x85 1610 + #define HidUsage_Sen_OrientationInclinometer3D 0x86 1611 + #define HidUsage_Sen_OrientationDistance1D 0x87 1612 + #define HidUsage_Sen_OrientationDistance2D 0x88 1613 + #define HidUsage_Sen_OrientationDistance3D 0x89 1614 + #define HidUsage_Sen_OrientationDeviceOrientation 0x8a 1615 + #define HidUsage_Sen_OrientationCompass 0x8b 1616 + #define HidUsage_Sen_OrientationInclinometer 0x8c 1617 + #define HidUsage_Sen_OrientationDistance 0x8d 1618 + #define HidUsage_Sen_OrientationRelativeOrientation 0x8e 1619 + #define HidUsage_Sen_OrientationSimpleOrientation 0x8f 1620 + #define HidUsage_Sen_Scanner 0x90 1621 + #define HidUsage_Sen_ScannerBarcode 0x91 1622 + #define HidUsage_Sen_ScannerRFID 0x92 1623 + #define HidUsage_Sen_ScannerNFC 0x93 1624 + #define HidUsage_Sen_Time 0xa0 1625 + #define HidUsage_Sen_TimeAlarmTimer 0xa1 1626 + #define HidUsage_Sen_TimeRealTimeClock 0xa2 1627 + #define HidUsage_Sen_PersonalActivity 0xb0 1628 + #define HidUsage_Sen_PersonalActivityActivityDetection 0xb1 1629 + #define HidUsage_Sen_PersonalActivityDevicePosition 0xb2 1630 + #define HidUsage_Sen_PersonalActivityFloorTracker 0xb3 1631 + #define HidUsage_Sen_PersonalActivityPedometer 0xb4 1632 + #define HidUsage_Sen_PersonalActivityStepDetection 0xb5 1633 + #define HidUsage_Sen_OrientationExtended 0xc0 1634 + #define HidUsage_Sen_OrientationExtendedGeomagneticOrientation 0xc1 1635 + #define HidUsage_Sen_OrientationExtendedMagnetometer 0xc2 1636 + #define HidUsage_Sen_Gesture 0xd0 1637 + #define HidUsage_Sen_GestureChassisFlipGesture 0xd1 1638 + #define HidUsage_Sen_GestureHingeFoldGesture 0xd2 1639 + #define HidUsage_Sen_Other 0xe0 1640 + #define HidUsage_Sen_OtherCustom 0xe1 1641 + #define HidUsage_Sen_OtherGeneric 0xe2 1642 + #define HidUsage_Sen_OtherGenericEnumerator 0xe3 1643 + #define HidUsage_Sen_OtherHingeAngle 0xe4 1644 + #define HidUsage_Sen_VendorReserved1 0xf0 1645 + #define HidUsage_Sen_VendorReserved2 0xf1 1646 + #define HidUsage_Sen_VendorReserved3 0xf2 1647 + #define HidUsage_Sen_VendorReserved4 0xf3 1648 + #define HidUsage_Sen_VendorReserved5 0xf4 1649 + #define HidUsage_Sen_VendorReserved6 0xf5 1650 + #define HidUsage_Sen_VendorReserved7 0xf6 1651 + #define HidUsage_Sen_VendorReserved8 0xf7 1652 + #define HidUsage_Sen_VendorReserved9 0xf8 1653 + #define HidUsage_Sen_VendorReserved10 0xf9 1654 + #define HidUsage_Sen_VendorReserved11 0xfa 1655 + #define HidUsage_Sen_VendorReserved12 0xfb 1656 + #define HidUsage_Sen_VendorReserved13 0xfc 1657 + #define HidUsage_Sen_VendorReserved14 0xfd 1658 + #define HidUsage_Sen_VendorReserved15 0xfe 1659 + #define HidUsage_Sen_VendorReserved16 0xff 1660 + #define HidUsage_Sen_Event 0x200 1661 + #define HidUsage_Sen_EventSensorState 0x201 1662 + #define HidUsage_Sen_EventSensorEvent 0x202 1663 + #define HidUsage_Sen_Property 0x300 1664 + #define HidUsage_Sen_PropertyFriendlyName 0x301 1665 + #define HidUsage_Sen_PropertyPersistentUniqueID 0x302 1666 + #define HidUsage_Sen_PropertySensorStatus 0x303 1667 + #define HidUsage_Sen_PropertyMinimumReportInterval 0x304 1668 + #define HidUsage_Sen_PropertySensorManufacturer 0x305 1669 + #define HidUsage_Sen_PropertySensorModel 0x306 1670 + #define HidUsage_Sen_PropertySensorSerialNumber 0x307 1671 + #define HidUsage_Sen_PropertySensorDescription 0x308 1672 + #define HidUsage_Sen_PropertySensorConnectionType 0x309 1673 + #define HidUsage_Sen_PropertySensorDevicePath 0x30a 1674 + #define HidUsage_Sen_PropertyHardwareRevision 0x30b 1675 + #define HidUsage_Sen_PropertyFirmwareVersion 0x30c 1676 + #define HidUsage_Sen_PropertyReleaseDate 0x30d 1677 + #define HidUsage_Sen_PropertyReportInterval 0x30e 1678 + #define HidUsage_Sen_PropertyChangeSensitivityAbsolute 0x30f 1679 + #define HidUsage_Sen_PropertyChangeSensitivityPercentofRange 0x310 1680 + #define HidUsage_Sen_PropertyChangeSensitivityPercentRelative 0x311 1681 + #define HidUsage_Sen_PropertyAccuracy 0x312 1682 + #define HidUsage_Sen_PropertyResolution 0x313 1683 + #define HidUsage_Sen_PropertyMaximum 0x314 1684 + #define HidUsage_Sen_PropertyMinimum 0x315 1685 + #define HidUsage_Sen_PropertyReportingState 0x316 1686 + #define HidUsage_Sen_PropertySamplingRate 0x317 1687 + #define HidUsage_Sen_PropertyResponseCurve 0x318 1688 + #define HidUsage_Sen_PropertyPowerState 0x319 1689 + #define HidUsage_Sen_PropertyMaximumFIFOEvents 0x31a 1690 + #define HidUsage_Sen_PropertyReportLatency 0x31b 1691 + #define HidUsage_Sen_PropertyFlushFIFOEvents 0x31c 1692 + #define HidUsage_Sen_PropertyMaximumPowerConsumption 0x31d 1693 + #define HidUsage_Sen_PropertyIsPrimary 0x31e 1694 + #define HidUsage_Sen_PropertyHumanPresenceDetectionType 0x31f 1695 + #define HidUsage_Sen_DataFieldLocation 0x400 1696 + #define HidUsage_Sen_DataFieldAltitudeAntennaSeaLevel 0x402 1697 + #define HidUsage_Sen_DataFieldDifferentialReferenceStationID 0x403 1698 + #define HidUsage_Sen_DataFieldAltitudeEllipsoidError 0x404 1699 + #define HidUsage_Sen_DataFieldAltitudeEllipsoid 0x405 1700 + #define HidUsage_Sen_DataFieldAltitudeSeaLevelError 0x406 1701 + #define HidUsage_Sen_DataFieldAltitudeSeaLevel 0x407 1702 + #define HidUsage_Sen_DataFieldDifferentialGPSDataAge 0x408 1703 + #define HidUsage_Sen_DataFieldErrorRadius 0x409 1704 + #define HidUsage_Sen_DataFieldFixQuality 0x40a 1705 + #define HidUsage_Sen_DataFieldFixType 0x40b 1706 + #define HidUsage_Sen_DataFieldGeoidalSeparation 0x40c 1707 + #define HidUsage_Sen_DataFieldGPSOperationMode 0x40d 1708 + #define HidUsage_Sen_DataFieldGPSSelectionMode 0x40e 1709 + #define HidUsage_Sen_DataFieldGPSStatus 0x40f 1710 + #define HidUsage_Sen_DataFieldPositionDilutionofPrecision 0x410 1711 + #define HidUsage_Sen_DataFieldHorizontalDilutionofPrecision 0x411 1712 + #define HidUsage_Sen_DataFieldVerticalDilutionofPrecision 0x412 1713 + #define HidUsage_Sen_DataFieldLatitude 0x413 1714 + #define HidUsage_Sen_DataFieldLongitude 0x414 1715 + #define HidUsage_Sen_DataFieldTrueHeading 0x415 1716 + #define HidUsage_Sen_DataFieldMagneticHeading 0x416 1717 + #define HidUsage_Sen_DataFieldMagneticVariation 0x417 1718 + #define HidUsage_Sen_DataFieldSpeed 0x418 1719 + #define HidUsage_Sen_DataFieldSatellitesinView 0x419 1720 + #define HidUsage_Sen_DataFieldSatellitesinViewAzimuth 0x41a 1721 + #define HidUsage_Sen_DataFieldSatellitesinViewElevation 0x41b 1722 + #define HidUsage_Sen_DataFieldSatellitesinViewIDs 0x41c 1723 + #define HidUsage_Sen_DataFieldSatellitesinViewPRNs 0x41d 1724 + #define HidUsage_Sen_DataFieldSatellitesinViewSNRatios 0x41e 1725 + #define HidUsage_Sen_DataFieldSatellitesUsedCount 0x41f 1726 + #define HidUsage_Sen_DataFieldSatellitesUsedPRNs 0x420 1727 + #define HidUsage_Sen_DataFieldNMEASentence 0x421 1728 + #define HidUsage_Sen_DataFieldAddressLine1 0x422 1729 + #define HidUsage_Sen_DataFieldAddressLine2 0x423 1730 + #define HidUsage_Sen_DataFieldCity 0x424 1731 + #define HidUsage_Sen_DataFieldStateorProvince 0x425 1732 + #define HidUsage_Sen_DataFieldCountryorRegion 0x426 1733 + #define HidUsage_Sen_DataFieldPostalCode 0x427 1734 + #define HidUsage_Sen_PropertyLocation 0x42a 1735 + #define HidUsage_Sen_PropertyLocationDesiredAccuracy 0x42b 1736 + #define HidUsage_Sen_DataFieldEnvironmental 0x430 1737 + #define HidUsage_Sen_DataFieldAtmosphericPressure 0x431 1738 + #define HidUsage_Sen_DataFieldRelativeHumidity 0x433 1739 + #define HidUsage_Sen_DataFieldTemperature 0x434 1740 + #define HidUsage_Sen_DataFieldWindDirection 0x435 1741 + #define HidUsage_Sen_DataFieldWindSpeed 0x436 1742 + #define HidUsage_Sen_DataFieldAirQualityIndex 0x437 1743 + #define HidUsage_Sen_DataFieldEquivalentCO2 0x438 1744 + #define HidUsage_Sen_DataFieldVolatileOrganicCompoundConcentration 0x439 1745 + #define HidUsage_Sen_DataFieldObjectPresence 0x43a 1746 + #define HidUsage_Sen_DataFieldObjectProximityRange 0x43b 1747 + #define HidUsage_Sen_DataFieldObjectProximityOutofRange 0x43c 1748 + #define HidUsage_Sen_PropertyEnvironmental 0x440 1749 + #define HidUsage_Sen_PropertyReferencePressure 0x441 1750 + #define HidUsage_Sen_DataFieldMotion 0x450 1751 + #define HidUsage_Sen_DataFieldMotionState 0x451 1752 + #define HidUsage_Sen_DataFieldAcceleration 0x452 1753 + #define HidUsage_Sen_DataFieldAccelerationAxisX 0x453 1754 + #define HidUsage_Sen_DataFieldAccelerationAxisY 0x454 1755 + #define HidUsage_Sen_DataFieldAccelerationAxisZ 0x455 1756 + #define HidUsage_Sen_DataFieldAngularVelocity 0x456 1757 + #define HidUsage_Sen_DataFieldAngularVelocityaboutXAxis 0x457 1758 + #define HidUsage_Sen_DataFieldAngularVelocityaboutYAxis 0x458 1759 + #define HidUsage_Sen_DataFieldAngularVelocityaboutZAxis 0x459 1760 + #define HidUsage_Sen_DataFieldAngularPosition 0x45a 1761 + #define HidUsage_Sen_DataFieldAngularPositionaboutXAxis 0x45b 1762 + #define HidUsage_Sen_DataFieldAngularPositionaboutYAxis 0x45c 1763 + #define HidUsage_Sen_DataFieldAngularPositionaboutZAxis 0x45d 1764 + #define HidUsage_Sen_DataFieldMotionSpeed 0x45e 1765 + #define HidUsage_Sen_DataFieldMotionIntensity 0x45f 1766 + #define HidUsage_Sen_DataFieldOrientation 0x470 1767 + #define HidUsage_Sen_DataFieldHeading 0x471 1768 + #define HidUsage_Sen_DataFieldHeadingXAxis 0x472 1769 + #define HidUsage_Sen_DataFieldHeadingYAxis 0x473 1770 + #define HidUsage_Sen_DataFieldHeadingZAxis 0x474 1771 + #define HidUsage_Sen_DataFieldHeadingCompensatedMagneticNorth 0x475 1772 + #define HidUsage_Sen_DataFieldHeadingCompensatedTrueNorth 0x476 1773 + #define HidUsage_Sen_DataFieldHeadingMagneticNorth 0x477 1774 + #define HidUsage_Sen_DataFieldHeadingTrueNorth 0x478 1775 + #define HidUsage_Sen_DataFieldDistance 0x479 1776 + #define HidUsage_Sen_DataFieldDistanceXAxis 0x47a 1777 + #define HidUsage_Sen_DataFieldDistanceYAxis 0x47b 1778 + #define HidUsage_Sen_DataFieldDistanceZAxis 0x47c 1779 + #define HidUsage_Sen_DataFieldDistanceOutofRange 0x47d 1780 + #define HidUsage_Sen_DataFieldTilt 0x47e 1781 + #define HidUsage_Sen_DataFieldTiltXAxis 0x47f 1782 + #define HidUsage_Sen_DataFieldTiltYAxis 0x480 1783 + #define HidUsage_Sen_DataFieldTiltZAxis 0x481 1784 + #define HidUsage_Sen_DataFieldRotationMatrix 0x482 1785 + #define HidUsage_Sen_DataFieldQuaternion 0x483 1786 + #define HidUsage_Sen_DataFieldMagneticFlux 0x484 1787 + #define HidUsage_Sen_DataFieldMagneticFluxXAxis 0x485 1788 + #define HidUsage_Sen_DataFieldMagneticFluxYAxis 0x486 1789 + #define HidUsage_Sen_DataFieldMagneticFluxZAxis 0x487 1790 + #define HidUsage_Sen_DataFieldMagnetometerAccuracy 0x488 1791 + #define HidUsage_Sen_DataFieldSimpleOrientationDirection 0x489 1792 + #define HidUsage_Sen_DataFieldMechanical 0x490 1793 + #define HidUsage_Sen_DataFieldBooleanSwitchState 0x491 1794 + #define HidUsage_Sen_DataFieldBooleanSwitchArrayStates 0x492 1795 + #define HidUsage_Sen_DataFieldMultivalueSwitchValue 0x493 1796 + #define HidUsage_Sen_DataFieldForce 0x494 1797 + #define HidUsage_Sen_DataFieldAbsolutePressure 0x495 1798 + #define HidUsage_Sen_DataFieldGaugePressure 0x496 1799 + #define HidUsage_Sen_DataFieldStrain 0x497 1800 + #define HidUsage_Sen_DataFieldWeight 0x498 1801 + #define HidUsage_Sen_PropertyMechanical 0x4a0 1802 + #define HidUsage_Sen_PropertyVibrationState 0x4a1 1803 + #define HidUsage_Sen_PropertyForwardVibrationSpeed 0x4a2 1804 + #define HidUsage_Sen_PropertyBackwardVibrationSpeed 0x4a3 1805 + #define HidUsage_Sen_DataFieldBiometric 0x4b0 1806 + #define HidUsage_Sen_DataFieldHumanPresence 0x4b1 1807 + #define HidUsage_Sen_DataFieldHumanProximityRange 0x4b2 1808 + #define HidUsage_Sen_DataFieldHumanProximityOutofRange 0x4b3 1809 + #define HidUsage_Sen_DataFieldHumanTouchState 0x4b4 1810 + #define HidUsage_Sen_DataFieldBloodPressure 0x4b5 1811 + #define HidUsage_Sen_DataFieldBloodPressureDiastolic 0x4b6 1812 + #define HidUsage_Sen_DataFieldBloodPressureSystolic 0x4b7 1813 + #define HidUsage_Sen_DataFieldHeartRate 0x4b8 1814 + #define HidUsage_Sen_DataFieldRestingHeartRate 0x4b9 1815 + #define HidUsage_Sen_DataFieldHeartbeatInterval 0x4ba 1816 + #define HidUsage_Sen_DataFieldRespiratoryRate 0x4bb 1817 + #define HidUsage_Sen_DataFieldSpO2 0x4bc 1818 + #define HidUsage_Sen_DataFieldHumanAttentionDetected 0x4bd 1819 + #define HidUsage_Sen_DataFieldHumanHeadAzimuth 0x4be 1820 + #define HidUsage_Sen_DataFieldHumanHeadAltitude 0x4bf 1821 + #define HidUsage_Sen_DataFieldHumanHeadRoll 0x4c0 1822 + #define HidUsage_Sen_DataFieldHumanHeadPitch 0x4c1 1823 + #define HidUsage_Sen_DataFieldHumanHeadYaw 0x4c2 1824 + #define HidUsage_Sen_DataFieldHumanCorrelationId 0x4c3 1825 + #define HidUsage_Sen_DataFieldLight 0x4d0 1826 + #define HidUsage_Sen_DataFieldIlluminance 0x4d1 1827 + #define HidUsage_Sen_DataFieldColorTemperature 0x4d2 1828 + #define HidUsage_Sen_DataFieldChromaticity 0x4d3 1829 + #define HidUsage_Sen_DataFieldChromaticityX 0x4d4 1830 + #define HidUsage_Sen_DataFieldChromaticityY 0x4d5 1831 + #define HidUsage_Sen_DataFieldConsumerIRSentenceReceive 0x4d6 1832 + #define HidUsage_Sen_DataFieldInfraredLight 0x4d7 1833 + #define HidUsage_Sen_DataFieldRedLight 0x4d8 1834 + #define HidUsage_Sen_DataFieldGreenLight 0x4d9 1835 + #define HidUsage_Sen_DataFieldBlueLight 0x4da 1836 + #define HidUsage_Sen_DataFieldUltravioletALight 0x4db 1837 + #define HidUsage_Sen_DataFieldUltravioletBLight 0x4dc 1838 + #define HidUsage_Sen_DataFieldUltravioletIndex 0x4dd 1839 + #define HidUsage_Sen_DataFieldNearInfraredLight 0x4de 1840 + #define HidUsage_Sen_PropertyLight 0x4df 1841 + #define HidUsage_Sen_PropertyConsumerIRSentenceSend 0x4e0 1842 + #define HidUsage_Sen_PropertyAutoBrightnessPreferred 0x4e2 1843 + #define HidUsage_Sen_PropertyAutoColorPreferred 0x4e3 1844 + #define HidUsage_Sen_DataFieldScanner 0x4f0 1845 + #define HidUsage_Sen_DataFieldRFIDTag40Bit 0x4f1 1846 + #define HidUsage_Sen_DataFieldNFCSentenceReceive 0x4f2 1847 + #define HidUsage_Sen_PropertyScanner 0x4f8 1848 + #define HidUsage_Sen_PropertyNFCSentenceSend 0x4f9 1849 + #define HidUsage_Sen_DataFieldElectrical 0x500 1850 + #define HidUsage_Sen_DataFieldCapacitance 0x501 1851 + #define HidUsage_Sen_DataFieldCurrent 0x502 1852 + #define HidUsage_Sen_DataFieldElectricalPower 0x503 1853 + #define HidUsage_Sen_DataFieldInductance 0x504 1854 + #define HidUsage_Sen_DataFieldResistance 0x505 1855 + #define HidUsage_Sen_DataFieldVoltage 0x506 1856 + #define HidUsage_Sen_DataFieldFrequency 0x507 1857 + #define HidUsage_Sen_DataFieldPeriod 0x508 1858 + #define HidUsage_Sen_DataFieldPercentofRange 0x509 1859 + #define HidUsage_Sen_DataFieldTime 0x520 1860 + #define HidUsage_Sen_DataFieldYear 0x521 1861 + #define HidUsage_Sen_DataFieldMonth 0x522 1862 + #define HidUsage_Sen_DataFieldDay 0x523 1863 + #define HidUsage_Sen_DataFieldDayofWeek 0x524 1864 + #define HidUsage_Sen_DataFieldHour 0x525 1865 + #define HidUsage_Sen_DataFieldMinute 0x526 1866 + #define HidUsage_Sen_DataFieldSecond 0x527 1867 + #define HidUsage_Sen_DataFieldMillisecond 0x528 1868 + #define HidUsage_Sen_DataFieldTimestamp 0x529 1869 + #define HidUsage_Sen_DataFieldJulianDayofYear 0x52a 1870 + #define HidUsage_Sen_DataFieldTimeSinceSystemBoot 0x52b 1871 + #define HidUsage_Sen_PropertyTime 0x530 1872 + #define HidUsage_Sen_PropertyTimeZoneOffsetfromUTC 0x531 1873 + #define HidUsage_Sen_PropertyTimeZoneName 0x532 1874 + #define HidUsage_Sen_PropertyDaylightSavingsTimeObserved 0x533 1875 + #define HidUsage_Sen_PropertyTimeTrimAdjustment 0x534 1876 + #define HidUsage_Sen_PropertyArmAlarm 0x535 1877 + #define HidUsage_Sen_DataFieldCustom 0x540 1878 + #define HidUsage_Sen_DataFieldCustomUsage 0x541 1879 + #define HidUsage_Sen_DataFieldCustomBooleanArray 0x542 1880 + #define HidUsage_Sen_DataFieldCustomValue 0x543 1881 + #define HidUsage_Sen_DataFieldCustomValue1 0x544 1882 + #define HidUsage_Sen_DataFieldCustomValue2 0x545 1883 + #define HidUsage_Sen_DataFieldCustomValue3 0x546 1884 + #define HidUsage_Sen_DataFieldCustomValue4 0x547 1885 + #define HidUsage_Sen_DataFieldCustomValue5 0x548 1886 + #define HidUsage_Sen_DataFieldCustomValue6 0x549 1887 + #define HidUsage_Sen_DataFieldCustomValue7 0x54a 1888 + #define HidUsage_Sen_DataFieldCustomValue8 0x54b 1889 + #define HidUsage_Sen_DataFieldCustomValue9 0x54c 1890 + #define HidUsage_Sen_DataFieldCustomValue10 0x54d 1891 + #define HidUsage_Sen_DataFieldCustomValue11 0x54e 1892 + #define HidUsage_Sen_DataFieldCustomValue12 0x54f 1893 + #define HidUsage_Sen_DataFieldCustomValue13 0x550 1894 + #define HidUsage_Sen_DataFieldCustomValue14 0x551 1895 + #define HidUsage_Sen_DataFieldCustomValue15 0x552 1896 + #define HidUsage_Sen_DataFieldCustomValue16 0x553 1897 + #define HidUsage_Sen_DataFieldCustomValue17 0x554 1898 + #define HidUsage_Sen_DataFieldCustomValue18 0x555 1899 + #define HidUsage_Sen_DataFieldCustomValue19 0x556 1900 + #define HidUsage_Sen_DataFieldCustomValue20 0x557 1901 + #define HidUsage_Sen_DataFieldCustomValue21 0x558 1902 + #define HidUsage_Sen_DataFieldCustomValue22 0x559 1903 + #define HidUsage_Sen_DataFieldCustomValue23 0x55a 1904 + #define HidUsage_Sen_DataFieldCustomValue24 0x55b 1905 + #define HidUsage_Sen_DataFieldCustomValue25 0x55c 1906 + #define HidUsage_Sen_DataFieldCustomValue26 0x55d 1907 + #define HidUsage_Sen_DataFieldCustomValue27 0x55e 1908 + #define HidUsage_Sen_DataFieldCustomValue28 0x55f 1909 + #define HidUsage_Sen_DataFieldGeneric 0x560 1910 + #define HidUsage_Sen_DataFieldGenericGUIDorPROPERTYKEY 0x561 1911 + #define HidUsage_Sen_DataFieldGenericCategoryGUID 0x562 1912 + #define HidUsage_Sen_DataFieldGenericTypeGUID 0x563 1913 + #define HidUsage_Sen_DataFieldGenericEventPROPERTYKEY 0x564 1914 + #define HidUsage_Sen_DataFieldGenericPropertyPROPERTYKEY 0x565 1915 + #define HidUsage_Sen_DataFieldGenericDataFieldPROPERTYKEY 0x566 1916 + #define HidUsage_Sen_DataFieldGenericEvent 0x567 1917 + #define HidUsage_Sen_DataFieldGenericProperty 0x568 1918 + #define HidUsage_Sen_DataFieldGenericDataField 0x569 1919 + #define HidUsage_Sen_DataFieldEnumeratorTableRowIndex 0x56a 1920 + #define HidUsage_Sen_DataFieldEnumeratorTableRowCount 0x56b 1921 + #define HidUsage_Sen_DataFieldGenericGUIDorPROPERTYKEYkind 0x56c 1922 + #define HidUsage_Sen_DataFieldGenericGUID 0x56d 1923 + #define HidUsage_Sen_DataFieldGenericPROPERTYKEY 0x56e 1924 + #define HidUsage_Sen_DataFieldGenericTopLevelCollectionID 0x56f 1925 + #define HidUsage_Sen_DataFieldGenericReportID 0x570 1926 + #define HidUsage_Sen_DataFieldGenericReportItemPositionIndex 0x571 1927 + #define HidUsage_Sen_DataFieldGenericFirmwareVARTYPE 0x572 1928 + #define HidUsage_Sen_DataFieldGenericUnitofMeasure 0x573 1929 + #define HidUsage_Sen_DataFieldGenericUnitExponent 0x574 1930 + #define HidUsage_Sen_DataFieldGenericReportSize 0x575 1931 + #define HidUsage_Sen_DataFieldGenericReportCount 0x576 1932 + #define HidUsage_Sen_PropertyGeneric 0x580 1933 + #define HidUsage_Sen_PropertyEnumeratorTableRowIndex 0x581 1934 + #define HidUsage_Sen_PropertyEnumeratorTableRowCount 0x582 1935 + #define HidUsage_Sen_DataFieldPersonalActivity 0x590 1936 + #define HidUsage_Sen_DataFieldActivityType 0x591 1937 + #define HidUsage_Sen_DataFieldActivityState 0x592 1938 + #define HidUsage_Sen_DataFieldDevicePosition 0x593 1939 + #define HidUsage_Sen_DataFieldStepCount 0x594 1940 + #define HidUsage_Sen_DataFieldStepCountReset 0x595 1941 + #define HidUsage_Sen_DataFieldStepDuration 0x596 1942 + #define HidUsage_Sen_DataFieldStepType 0x597 1943 + #define HidUsage_Sen_PropertyMinimumActivityDetectionInterval 0x5a0 1944 + #define HidUsage_Sen_PropertySupportedActivityTypes 0x5a1 1945 + #define HidUsage_Sen_PropertySubscribedActivityTypes 0x5a2 1946 + #define HidUsage_Sen_PropertySupportedStepTypes 0x5a3 1947 + #define HidUsage_Sen_PropertySubscribedStepTypes 0x5a4 1948 + #define HidUsage_Sen_PropertyFloorHeight 0x5a5 1949 + #define HidUsage_Sen_DataFieldCustomTypeID 0x5b0 1950 + #define HidUsage_Sen_PropertyCustom 0x5c0 1951 + #define HidUsage_Sen_PropertyCustomValue1 0x5c1 1952 + #define HidUsage_Sen_PropertyCustomValue2 0x5c2 1953 + #define HidUsage_Sen_PropertyCustomValue3 0x5c3 1954 + #define HidUsage_Sen_PropertyCustomValue4 0x5c4 1955 + #define HidUsage_Sen_PropertyCustomValue5 0x5c5 1956 + #define HidUsage_Sen_PropertyCustomValue6 0x5c6 1957 + #define HidUsage_Sen_PropertyCustomValue7 0x5c7 1958 + #define HidUsage_Sen_PropertyCustomValue8 0x5c8 1959 + #define HidUsage_Sen_PropertyCustomValue9 0x5c9 1960 + #define HidUsage_Sen_PropertyCustomValue10 0x5ca 1961 + #define HidUsage_Sen_PropertyCustomValue11 0x5cb 1962 + #define HidUsage_Sen_PropertyCustomValue12 0x5cc 1963 + #define HidUsage_Sen_PropertyCustomValue13 0x5cd 1964 + #define HidUsage_Sen_PropertyCustomValue14 0x5ce 1965 + #define HidUsage_Sen_PropertyCustomValue15 0x5cf 1966 + #define HidUsage_Sen_PropertyCustomValue16 0x5d0 1967 + #define HidUsage_Sen_DataFieldHinge 0x5e0 1968 + #define HidUsage_Sen_DataFieldHingeAngle 0x5e1 1969 + #define HidUsage_Sen_DataFieldGestureSensor 0x5f0 1970 + #define HidUsage_Sen_DataFieldGestureState 0x5f1 1971 + #define HidUsage_Sen_DataFieldHingeFoldInitialAngle 0x5f2 1972 + #define HidUsage_Sen_DataFieldHingeFoldFinalAngle 0x5f3 1973 + #define HidUsage_Sen_DataFieldHingeFoldContributingPanel 0x5f4 1974 + #define HidUsage_Sen_DataFieldHingeFoldType 0x5f5 1975 + #define HidUsage_Sen_SensorStateUndefined 0x800 1976 + #define HidUsage_Sen_SensorStateReady 0x801 1977 + #define HidUsage_Sen_SensorStateNotAvailable 0x802 1978 + #define HidUsage_Sen_SensorStateNoData 0x803 1979 + #define HidUsage_Sen_SensorStateInitializing 0x804 1980 + #define HidUsage_Sen_SensorStateAccessDenied 0x805 1981 + #define HidUsage_Sen_SensorStateError 0x806 1982 + #define HidUsage_Sen_SensorEventUnknown 0x810 1983 + #define HidUsage_Sen_SensorEventStateChanged 0x811 1984 + #define HidUsage_Sen_SensorEventPropertyChanged 0x812 1985 + #define HidUsage_Sen_SensorEventDataUpdated 0x813 1986 + #define HidUsage_Sen_SensorEventPollResponse 0x814 1987 + #define HidUsage_Sen_SensorEventChangeSensitivity 0x815 1988 + #define HidUsage_Sen_SensorEventRangeMaximumReached 0x816 1989 + #define HidUsage_Sen_SensorEventRangeMinimumReached 0x817 1990 + #define HidUsage_Sen_SensorEventHighThresholdCrossUpward 0x818 1991 + #define HidUsage_Sen_SensorEventHighThresholdCrossDownward 0x819 1992 + #define HidUsage_Sen_SensorEventLowThresholdCrossUpward 0x81a 1993 + #define HidUsage_Sen_SensorEventLowThresholdCrossDownward 0x81b 1994 + #define HidUsage_Sen_SensorEventZeroThresholdCrossUpward 0x81c 1995 + #define HidUsage_Sen_SensorEventZeroThresholdCrossDownward 0x81d 1996 + #define HidUsage_Sen_SensorEventPeriodExceeded 0x81e 1997 + #define HidUsage_Sen_SensorEventFrequencyExceeded 0x81f 1998 + #define HidUsage_Sen_SensorEventComplexTrigger 0x820 1999 + #define HidUsage_Sen_ConnectionTypePCIntegrated 0x830 2000 + #define HidUsage_Sen_ConnectionTypePCAttached 0x831 2001 + #define HidUsage_Sen_ConnectionTypePCExternal 0x832 2002 + #define HidUsage_Sen_ReportingStateReportNoEvents 0x840 2003 + #define HidUsage_Sen_ReportingStateReportAllEvents 0x841 2004 + #define HidUsage_Sen_ReportingStateReportThresholdEvents 0x842 2005 + #define HidUsage_Sen_ReportingStateWakeOnNoEvents 0x843 2006 + #define HidUsage_Sen_ReportingStateWakeOnAllEvents 0x844 2007 + #define HidUsage_Sen_ReportingStateWakeOnThresholdEvents 0x845 2008 + #define HidUsage_Sen_ReportingStateAnytime 0x846 2009 + #define HidUsage_Sen_PowerStateUndefined 0x850 2010 + #define HidUsage_Sen_PowerStateD0FullPower 0x851 2011 + #define HidUsage_Sen_PowerStateD1LowPower 0x852 2012 + #define HidUsage_Sen_PowerStateD2StandbyPowerwithWakeup 0x853 2013 + #define HidUsage_Sen_PowerStateD3SleepwithWakeup 0x854 2014 + #define HidUsage_Sen_PowerStateD4PowerOff 0x855 2015 + #define HidUsage_Sen_AccuracyDefault 0x860 2016 + #define HidUsage_Sen_AccuracyHigh 0x861 2017 + #define HidUsage_Sen_AccuracyMedium 0x862 2018 + #define HidUsage_Sen_AccuracyLow 0x863 2019 + #define HidUsage_Sen_FixQualityNoFix 0x870 2020 + #define HidUsage_Sen_FixQualityGPS 0x871 2021 + #define HidUsage_Sen_FixQualityDGPS 0x872 2022 + #define HidUsage_Sen_FixTypeNoFix 0x880 2023 + #define HidUsage_Sen_FixTypeGPSSPSModeFixValid 0x881 2024 + #define HidUsage_Sen_FixTypeDGPSSPSModeFixValid 0x882 2025 + #define HidUsage_Sen_FixTypeGPSPPSModeFixValid 0x883 2026 + #define HidUsage_Sen_FixTypeRealTimeKinematic 0x884 2027 + #define HidUsage_Sen_FixTypeFloatRTK 0x885 2028 + #define HidUsage_Sen_FixTypeEstimateddeadreckoned 0x886 2029 + #define HidUsage_Sen_FixTypeManualInputMode 0x887 2030 + #define HidUsage_Sen_FixTypeSimulatorMode 0x888 2031 + #define HidUsage_Sen_GPSOperationModeManual 0x890 2032 + #define HidUsage_Sen_GPSOperationModeAutomatic 0x891 2033 + #define HidUsage_Sen_GPSSelectionModeAutonomous 0x8a0 2034 + #define HidUsage_Sen_GPSSelectionModeDGPS 0x8a1 2035 + #define HidUsage_Sen_GPSSelectionModeEstimateddeadreckoned 0x8a2 2036 + #define HidUsage_Sen_GPSSelectionModeManualInput 0x8a3 2037 + #define HidUsage_Sen_GPSSelectionModeSimulator 0x8a4 2038 + #define HidUsage_Sen_GPSSelectionModeDataNotValid 0x8a5 2039 + #define HidUsage_Sen_GPSStatusDataValid 0x8b0 2040 + #define HidUsage_Sen_GPSStatusDataNotValid 0x8b1 2041 + #define HidUsage_Sen_DayofWeekSunday 0x8c0 2042 + #define HidUsage_Sen_DayofWeekMonday 0x8c1 2043 + #define HidUsage_Sen_DayofWeekTuesday 0x8c2 2044 + #define HidUsage_Sen_DayofWeekWednesday 0x8c3 2045 + #define HidUsage_Sen_DayofWeekThursday 0x8c4 2046 + #define HidUsage_Sen_DayofWeekFriday 0x8c5 2047 + #define HidUsage_Sen_DayofWeekSaturday 0x8c6 2048 + #define HidUsage_Sen_KindCategory 0x8d0 2049 + #define HidUsage_Sen_KindType 0x8d1 2050 + #define HidUsage_Sen_KindEvent 0x8d2 2051 + #define HidUsage_Sen_KindProperty 0x8d3 2052 + #define HidUsage_Sen_KindDataField 0x8d4 2053 + #define HidUsage_Sen_MagnetometerAccuracyLow 0x8e0 2054 + #define HidUsage_Sen_MagnetometerAccuracyMedium 0x8e1 2055 + #define HidUsage_Sen_MagnetometerAccuracyHigh 0x8e2 2056 + #define HidUsage_Sen_SimpleOrientationDirectionNotRotated 0x8f0 2057 + #define HidUsage_Sen_SimpleOrientationDirectionRotated90DegreesCCW 0x8f1 2058 + #define HidUsage_Sen_SimpleOrientationDirectionRotated180DegreesCCW 0x8f2 2059 + #define HidUsage_Sen_SimpleOrientationDirectionRotated270DegreesCCW 0x8f3 2060 + #define HidUsage_Sen_SimpleOrientationDirectionFaceUp 0x8f4 2061 + #define HidUsage_Sen_SimpleOrientationDirectionFaceDown 0x8f5 2062 + #define HidUsage_Sen_VT_NULL 0x900 2063 + #define HidUsage_Sen_VT_BOOL 0x901 2064 + #define HidUsage_Sen_VT_UI1 0x902 2065 + #define HidUsage_Sen_VT_I1 0x903 2066 + #define HidUsage_Sen_VT_UI2 0x904 2067 + #define HidUsage_Sen_VT_I2 0x905 2068 + #define HidUsage_Sen_VT_UI4 0x906 2069 + #define HidUsage_Sen_VT_I4 0x907 2070 + #define HidUsage_Sen_VT_UI8 0x908 2071 + #define HidUsage_Sen_VT_I8 0x909 2072 + #define HidUsage_Sen_VT_R4 0x90a 2073 + #define HidUsage_Sen_VT_R8 0x90b 2074 + #define HidUsage_Sen_VT_WSTR 0x90c 2075 + #define HidUsage_Sen_VT_STR 0x90d 2076 + #define HidUsage_Sen_VT_CLSID 0x90e 2077 + #define HidUsage_Sen_VT_VECTORVT_UI1 0x90f 2078 + #define HidUsage_Sen_VT_F16E0 0x910 2079 + #define HidUsage_Sen_VT_F16E1 0x911 2080 + #define HidUsage_Sen_VT_F16E2 0x912 2081 + #define HidUsage_Sen_VT_F16E3 0x913 2082 + #define HidUsage_Sen_VT_F16E4 0x914 2083 + #define HidUsage_Sen_VT_F16E5 0x915 2084 + #define HidUsage_Sen_VT_F16E6 0x916 2085 + #define HidUsage_Sen_VT_F16E7 0x917 2086 + #define HidUsage_Sen_VT_F16E8 0x918 2087 + #define HidUsage_Sen_VT_F16E9 0x919 2088 + #define HidUsage_Sen_VT_F16EA 0x91a 2089 + #define HidUsage_Sen_VT_F16EB 0x91b 2090 + #define HidUsage_Sen_VT_F16EC 0x91c 2091 + #define HidUsage_Sen_VT_F16ED 0x91d 2092 + #define HidUsage_Sen_VT_F16EE 0x91e 2093 + #define HidUsage_Sen_VT_F16EF 0x91f 2094 + #define HidUsage_Sen_VT_F32E0 0x920 2095 + #define HidUsage_Sen_VT_F32E1 0x921 2096 + #define HidUsage_Sen_VT_F32E2 0x922 2097 + #define HidUsage_Sen_VT_F32E3 0x923 2098 + #define HidUsage_Sen_VT_F32E4 0x924 2099 + #define HidUsage_Sen_VT_F32E5 0x925 2100 + #define HidUsage_Sen_VT_F32E6 0x926 2101 + #define HidUsage_Sen_VT_F32E7 0x927 2102 + #define HidUsage_Sen_VT_F32E8 0x928 2103 + #define HidUsage_Sen_VT_F32E9 0x929 2104 + #define HidUsage_Sen_VT_F32EA 0x92a 2105 + #define HidUsage_Sen_VT_F32EB 0x92b 2106 + #define HidUsage_Sen_VT_F32EC 0x92c 2107 + #define HidUsage_Sen_VT_F32ED 0x92d 2108 + #define HidUsage_Sen_VT_F32EE 0x92e 2109 + #define HidUsage_Sen_VT_F32EF 0x92f 2110 + #define HidUsage_Sen_ActivityTypeUnknown 0x930 2111 + #define HidUsage_Sen_ActivityTypeStationary 0x931 2112 + #define HidUsage_Sen_ActivityTypeFidgeting 0x932 2113 + #define HidUsage_Sen_ActivityTypeWalking 0x933 2114 + #define HidUsage_Sen_ActivityTypeRunning 0x934 2115 + #define HidUsage_Sen_ActivityTypeInVehicle 0x935 2116 + #define HidUsage_Sen_ActivityTypeBiking 0x936 2117 + #define HidUsage_Sen_ActivityTypeIdle 0x937 2118 + #define HidUsage_Sen_UnitNotSpecified 0x940 2119 + #define HidUsage_Sen_UnitLux 0x941 2120 + #define HidUsage_Sen_UnitDegreesKelvin 0x942 2121 + #define HidUsage_Sen_UnitDegreesCelsius 0x943 2122 + #define HidUsage_Sen_UnitPascal 0x944 2123 + #define HidUsage_Sen_UnitNewton 0x945 2124 + #define HidUsage_Sen_UnitMetersSecond 0x946 2125 + #define HidUsage_Sen_UnitKilogram 0x947 2126 + #define HidUsage_Sen_UnitMeter 0x948 2127 + #define HidUsage_Sen_UnitMetersSecondSecond 0x949 2128 + #define HidUsage_Sen_UnitFarad 0x94a 2129 + #define HidUsage_Sen_UnitAmpere 0x94b 2130 + #define HidUsage_Sen_UnitWatt 0x94c 2131 + #define HidUsage_Sen_UnitHenry 0x94d 2132 + #define HidUsage_Sen_UnitOhm 0x94e 2133 + #define HidUsage_Sen_UnitVolt 0x94f 2134 + #define HidUsage_Sen_UnitHertz 0x950 2135 + #define HidUsage_Sen_UnitBar 0x951 2136 + #define HidUsage_Sen_UnitDegreesAnticlockwise 0x952 2137 + #define HidUsage_Sen_UnitDegreesClockwise 0x953 2138 + #define HidUsage_Sen_UnitDegrees 0x954 2139 + #define HidUsage_Sen_UnitDegreesSecond 0x955 2140 + #define HidUsage_Sen_UnitDegreesSecondSecond 0x956 2141 + #define HidUsage_Sen_UnitKnot 0x957 2142 + #define HidUsage_Sen_UnitPercent 0x958 2143 + #define HidUsage_Sen_UnitSecond 0x959 2144 + #define HidUsage_Sen_UnitMillisecond 0x95a 2145 + #define HidUsage_Sen_UnitG 0x95b 2146 + #define HidUsage_Sen_UnitBytes 0x95c 2147 + #define HidUsage_Sen_UnitMilligauss 0x95d 2148 + #define HidUsage_Sen_UnitBits 0x95e 2149 + #define HidUsage_Sen_ActivityStateNoStateChange 0x960 2150 + #define HidUsage_Sen_ActivityStateStartActivity 0x961 2151 + #define HidUsage_Sen_ActivityStateEndActivity 0x962 2152 + #define HidUsage_Sen_Exponent0 0x970 2153 + #define HidUsage_Sen_Exponent1 0x971 2154 + #define HidUsage_Sen_Exponent2 0x972 2155 + #define HidUsage_Sen_Exponent3 0x973 2156 + #define HidUsage_Sen_Exponent4 0x974 2157 + #define HidUsage_Sen_Exponent5 0x975 2158 + #define HidUsage_Sen_Exponent6 0x976 2159 + #define HidUsage_Sen_Exponent7 0x977 2160 + #define HidUsage_Sen_Exponent8 0x978 2161 + #define HidUsage_Sen_Exponent9 0x979 2162 + #define HidUsage_Sen_ExponentA 0x97a 2163 + #define HidUsage_Sen_ExponentB 0x97b 2164 + #define HidUsage_Sen_ExponentC 0x97c 2165 + #define HidUsage_Sen_ExponentD 0x97d 2166 + #define HidUsage_Sen_ExponentE 0x97e 2167 + #define HidUsage_Sen_ExponentF 0x97f 2168 + #define HidUsage_Sen_DevicePositionUnknown 0x980 2169 + #define HidUsage_Sen_DevicePositionUnchanged 0x981 2170 + #define HidUsage_Sen_DevicePositionOnDesk 0x982 2171 + #define HidUsage_Sen_DevicePositionInHand 0x983 2172 + #define HidUsage_Sen_DevicePositionMovinginBag 0x984 2173 + #define HidUsage_Sen_DevicePositionStationaryinBag 0x985 2174 + #define HidUsage_Sen_StepTypeUnknown 0x990 2175 + #define HidUsage_Sen_StepTypeWalking 0x991 2176 + #define HidUsage_Sen_StepTypeRunning 0x992 2177 + #define HidUsage_Sen_GestureStateUnknown 0x9a0 2178 + #define HidUsage_Sen_GestureStateStarted 0x9a1 2179 + #define HidUsage_Sen_GestureStateCompleted 0x9a2 2180 + #define HidUsage_Sen_GestureStateCancelled 0x9a3 2181 + #define HidUsage_Sen_HingeFoldContributingPanelUnknown 0x9b0 2182 + #define HidUsage_Sen_HingeFoldContributingPanelPanel1 0x9b1 2183 + #define HidUsage_Sen_HingeFoldContributingPanelPanel2 0x9b2 2184 + #define HidUsage_Sen_HingeFoldContributingPanelBoth 0x9b3 2185 + #define HidUsage_Sen_HingeFoldTypeUnknown 0x9b4 2186 + #define HidUsage_Sen_HingeFoldTypeIncreasing 0x9b5 2187 + #define HidUsage_Sen_HingeFoldTypeDecreasing 0x9b6 2188 + #define HidUsage_Sen_HumanPresenceDetectionTypeVendorDefinedNonBiometric 0x9c0 2189 + #define HidUsage_Sen_HumanPresenceDetectionTypeVendorDefinedBiometric 0x9c1 2190 + #define HidUsage_Sen_HumanPresenceDetectionTypeFacialBiometric 0x9c2 2191 + #define HidUsage_Sen_HumanPresenceDetectionTypeAudioBiometric 0x9c3 2192 + #define HidUsage_Sen_ModifierChangeSensitivityAbsolute 0x1000 2193 + #define HidUsage_Sen_ModifierMaximum 0x2000 2194 + #define HidUsage_Sen_ModifierMinimum 0x3000 2195 + #define HidUsage_Sen_ModifierAccuracy 0x4000 2196 + #define HidUsage_Sen_ModifierResolution 0x5000 2197 + #define HidUsage_Sen_ModifierThresholdHigh 0x6000 2198 + #define HidUsage_Sen_ModifierThresholdLow 0x7000 2199 + #define HidUsage_Sen_ModifierCalibrationOffset 0x8000 2200 + #define HidUsage_Sen_ModifierCalibrationMultiplier 0x9000 2201 + #define HidUsage_Sen_ModifierReportInterval 0xa000 2202 + #define HidUsage_Sen_ModifierFrequencyMax 0xb000 2203 + #define HidUsage_Sen_ModifierPeriodMax 0xc000 2204 + #define HidUsage_Sen_ModifierChangeSensitivityPercentofRange 0xd000 2205 + #define HidUsage_Sen_ModifierChangeSensitivityPercentRelative 0xe000 2206 + #define HidUsage_Sen_ModifierVendorReserved 0xf000 2207 + #define HidUsage_MI_MedicalUltrasound 0x01 2208 + #define HidUsage_MI_VCRAcquisition 0x20 2209 + #define HidUsage_MI_FreezeThaw 0x21 2210 + #define HidUsage_MI_ClipStore 0x22 2211 + #define HidUsage_MI_Update 0x23 2212 + #define HidUsage_MI_Next 0x24 2213 + #define HidUsage_MI_Save 0x25 2214 + #define HidUsage_MI_Print 0x26 2215 + #define HidUsage_MI_MicrophoneEnable 0x27 2216 + #define HidUsage_MI_Cine 0x40 2217 + #define HidUsage_MI_TransmitPower 0x41 2218 + #define HidUsage_MI_Volume 0x42 2219 + #define HidUsage_MI_Focus 0x43 2220 + #define HidUsage_MI_Depth 0x44 2221 + #define HidUsage_MI_SoftStepPrimary 0x60 2222 + #define HidUsage_MI_SoftStepSecondary 0x61 2223 + #define HidUsage_MI_DepthGainCompensation 0x70 2224 + #define HidUsage_MI_ZoomSelect 0x80 2225 + #define HidUsage_MI_ZoomAdjust 0x81 2226 + #define HidUsage_MI_SpectralDopplerModeSelect 0x82 2227 + #define HidUsage_MI_SpectralDopplerAdjust 0x83 2228 + #define HidUsage_MI_ColorDopplerModeSelect 0x84 2229 + #define HidUsage_MI_ColorDopplerAdjust 0x85 2230 + #define HidUsage_MI_MotionModeSelect 0x86 2231 + #define HidUsage_MI_MotionModeAdjust 0x87 2232 + #define HidUsage_MI_TwoDModeSelect 0x88 2233 + #define HidUsage_MI_TwoDModeAdjust 0x89 2234 + #define HidUsage_MI_SoftControlSelect 0xa0 2235 + #define HidUsage_MI_SoftControlAdjust 0xa1 2236 + #define HidUsage_BD_BrailleDisplay 0x01 2237 + #define HidUsage_BD_BrailleRow 0x02 2238 + #define HidUsage_BD_EightDotBrailleCell 0x03 2239 + #define HidUsage_BD_SixDotBrailleCell 0x04 2240 + #define HidUsage_BD_NumberofBrailleCells 0x05 2241 + #define HidUsage_BD_ScreenReaderControl 0x06 2242 + #define HidUsage_BD_ScreenReaderIdentifier 0x07 2243 + #define HidUsage_BD_RouterSet1 0xfa 2244 + #define HidUsage_BD_RouterSet2 0xfb 2245 + #define HidUsage_BD_RouterSet3 0xfc 2246 + #define HidUsage_BD_RouterKey 0x100 2247 + #define HidUsage_BD_RowRouterKey 0x101 2248 + #define HidUsage_BD_BrailleButtons 0x200 2249 + #define HidUsage_BD_BrailleKeyboardDot1 0x201 2250 + #define HidUsage_BD_BrailleKeyboardDot2 0x202 2251 + #define HidUsage_BD_BrailleKeyboardDot3 0x203 2252 + #define HidUsage_BD_BrailleKeyboardDot4 0x204 2253 + #define HidUsage_BD_BrailleKeyboardDot5 0x205 2254 + #define HidUsage_BD_BrailleKeyboardDot6 0x206 2255 + #define HidUsage_BD_BrailleKeyboardDot7 0x207 2256 + #define HidUsage_BD_BrailleKeyboardDot8 0x208 2257 + #define HidUsage_BD_BrailleKeyboardSpace 0x209 2258 + #define HidUsage_BD_BrailleKeyboardLeftSpace 0x20a 2259 + #define HidUsage_BD_BrailleKeyboardRightSpace 0x20b 2260 + #define HidUsage_BD_BrailleFaceControls 0x20c 2261 + #define HidUsage_BD_BrailleLeftControls 0x20d 2262 + #define HidUsage_BD_BrailleRightControls 0x20e 2263 + #define HidUsage_BD_BrailleTopControls 0x20f 2264 + #define HidUsage_BD_BrailleJoystickCenter 0x210 2265 + #define HidUsage_BD_BrailleJoystickUp 0x211 2266 + #define HidUsage_BD_BrailleJoystickDown 0x212 2267 + #define HidUsage_BD_BrailleJoystickLeft 0x213 2268 + #define HidUsage_BD_BrailleJoystickRight 0x214 2269 + #define HidUsage_BD_BrailleDPadCenter 0x215 2270 + #define HidUsage_BD_BrailleDPadUp 0x216 2271 + #define HidUsage_BD_BrailleDPadDown 0x217 2272 + #define HidUsage_BD_BrailleDPadLeft 0x218 2273 + #define HidUsage_BD_BrailleDPadRight 0x219 2274 + #define HidUsage_BD_BraillePanLeft 0x21a 2275 + #define HidUsage_BD_BraillePanRight 0x21b 2276 + #define HidUsage_BD_BrailleRockerUp 0x21c 2277 + #define HidUsage_BD_BrailleRockerDown 0x21d 2278 + #define HidUsage_BD_BrailleRockerPress 0x21e 2279 + #define HidUsage_LAI_LampArray 0x01 2280 + #define HidUsage_LAI_LampArrayAttributesReport 0x02 2281 + #define HidUsage_LAI_LampCount 0x03 2282 + #define HidUsage_LAI_BoundingBoxWidthInMicrometers 0x04 2283 + #define HidUsage_LAI_BoundingBoxHeightInMicrometers 0x05 2284 + #define HidUsage_LAI_BoundingBoxDepthInMicrometers 0x06 2285 + #define HidUsage_LAI_LampArrayKind 0x07 2286 + #define HidUsage_LAI_MinUpdateIntervalInMicroseconds 0x08 2287 + #define HidUsage_LAI_LampAttributesRequestReport 0x20 2288 + #define HidUsage_LAI_LampId 0x21 2289 + #define HidUsage_LAI_LampAttributesResponseReport 0x22 2290 + #define HidUsage_LAI_PositionXInMicrometers 0x23 2291 + #define HidUsage_LAI_PositionYInMicrometers 0x24 2292 + #define HidUsage_LAI_PositionZInMicrometers 0x25 2293 + #define HidUsage_LAI_LampPurposes 0x26 2294 + #define HidUsage_LAI_UpdateLatencyInMicroseconds 0x27 2295 + #define HidUsage_LAI_RedLevelCount 0x28 2296 + #define HidUsage_LAI_GreenLevelCount 0x29 2297 + #define HidUsage_LAI_BlueLevelCount 0x2a 2298 + #define HidUsage_LAI_IntensityLevelCount 0x2b 2299 + #define HidUsage_LAI_IsProgrammable 0x2c 2300 + #define HidUsage_LAI_InputBinding 0x2d 2301 + #define HidUsage_LAI_LampMultiUpdateReport 0x50 2302 + #define HidUsage_LAI_RedUpdateChannel 0x51 2303 + #define HidUsage_LAI_GreenUpdateChannel 0x52 2304 + #define HidUsage_LAI_BlueUpdateChannel 0x53 2305 + #define HidUsage_LAI_IntensityUpdateChannel 0x54 2306 + #define HidUsage_LAI_LampUpdateFlags 0x55 2307 + #define HidUsage_LAI_LampRangeUpdateReport 0x60 2308 + #define HidUsage_LAI_LampIdStart 0x61 2309 + #define HidUsage_LAI_LampIdEnd 0x62 2310 + #define HidUsage_LAI_LampArrayControlReport 0x70 2311 + #define HidUsage_LAI_AutonomousMode 0x71 2312 + #define HidUsage_Mon_MonitorControl 0x01 2313 + #define HidUsage_Mon_EDIDInformation 0x02 2314 + #define HidUsage_Mon_VDIFInformation 0x03 2315 + #define HidUsage_Mon_VESAVersion 0x04 2316 + #define HidUsage_VESAVC_Degauss 0x01 2317 + #define HidUsage_VESAVC_Brightness 0x10 2318 + #define HidUsage_VESAVC_Contrast 0x12 2319 + #define HidUsage_VESAVC_RedVideoGain 0x16 2320 + #define HidUsage_VESAVC_GreenVideoGain 0x18 2321 + #define HidUsage_VESAVC_BlueVideoGain 0x1a 2322 + #define HidUsage_VESAVC_Focus 0x1c 2323 + #define HidUsage_VESAVC_HorizontalPosition 0x20 2324 + #define HidUsage_VESAVC_HorizontalSize 0x22 2325 + #define HidUsage_VESAVC_HorizontalPincushion 0x24 2326 + #define HidUsage_VESAVC_HorizontalPincushionBalance 0x26 2327 + #define HidUsage_VESAVC_HorizontalMisconvergence 0x28 2328 + #define HidUsage_VESAVC_HorizontalLinearity 0x2a 2329 + #define HidUsage_VESAVC_HorizontalLinearityBalance 0x2c 2330 + #define HidUsage_VESAVC_VerticalPosition 0x30 2331 + #define HidUsage_VESAVC_VerticalSize 0x32 2332 + #define HidUsage_VESAVC_VerticalPincushion 0x34 2333 + #define HidUsage_VESAVC_VerticalPincushionBalance 0x36 2334 + #define HidUsage_VESAVC_VerticalMisconvergence 0x38 2335 + #define HidUsage_VESAVC_VerticalLinearity 0x3a 2336 + #define HidUsage_VESAVC_VerticalLinearityBalance 0x3c 2337 + #define HidUsage_VESAVC_ParallelogramDistortionKeyBalance 0x40 2338 + #define HidUsage_VESAVC_TrapezoidalDistortionKey 0x42 2339 + #define HidUsage_VESAVC_TiltRotation 0x44 2340 + #define HidUsage_VESAVC_TopCornerDistortionControl 0x46 2341 + #define HidUsage_VESAVC_TopCornerDistortionBalance 0x48 2342 + #define HidUsage_VESAVC_BottomCornerDistortionControl 0x4a 2343 + #define HidUsage_VESAVC_BottomCornerDistortionBalance 0x4c 2344 + #define HidUsage_VESAVC_HorizontalMoiré 0x56 2345 + #define HidUsage_VESAVC_VerticalMoiré 0x58 2346 + #define HidUsage_VESAVC_InputLevelSelect 0x5e 2347 + #define HidUsage_VESAVC_InputSourceSelect 0x60 2348 + #define HidUsage_VESAVC_RedVideoBlackLevel 0x6c 2349 + #define HidUsage_VESAVC_GreenVideoBlackLevel 0x6e 2350 + #define HidUsage_VESAVC_BlueVideoBlackLevel 0x70 2351 + #define HidUsage_VESAVC_AutoSizeCenter 0xa2 2352 + #define HidUsage_VESAVC_PolarityHorizontalSynchronization 0xa4 2353 + #define HidUsage_VESAVC_PolarityVerticalSynchronization 0xa6 2354 + #define HidUsage_VESAVC_SynchronizationType 0xa8 2355 + #define HidUsage_VESAVC_ScreenOrientation 0xaa 2356 + #define HidUsage_VESAVC_HorizontalFrequency 0xac 2357 + #define HidUsage_VESAVC_VerticalFrequency 0xae 2358 + #define HidUsage_VESAVC_Settings 0xb0 2359 + #define HidUsage_VESAVC_OnScreenDisplay 0xca 2360 + #define HidUsage_VESAVC_StereoMode 0xd4 2361 + #define HidUsage_Pow_iName 0x01 2362 + #define HidUsage_Pow_PresentStatus 0x02 2363 + #define HidUsage_Pow_ChangedStatus 0x03 2364 + #define HidUsage_Pow_UPS 0x04 2365 + #define HidUsage_Pow_PowerSupply 0x05 2366 + #define HidUsage_Pow_BatterySystem 0x10 2367 + #define HidUsage_Pow_BatterySystemId 0x11 2368 + #define HidUsage_Pow_Battery 0x12 2369 + #define HidUsage_Pow_BatteryId 0x13 2370 + #define HidUsage_Pow_Charger 0x14 2371 + #define HidUsage_Pow_ChargerId 0x15 2372 + #define HidUsage_Pow_PowerConverter 0x16 2373 + #define HidUsage_Pow_PowerConverterId 0x17 2374 + #define HidUsage_Pow_OutletSystem 0x18 2375 + #define HidUsage_Pow_OutletSystemId 0x19 2376 + #define HidUsage_Pow_Input 0x1a 2377 + #define HidUsage_Pow_InputId 0x1b 2378 + #define HidUsage_Pow_Output 0x1c 2379 + #define HidUsage_Pow_OutputId 0x1d 2380 + #define HidUsage_Pow_Flow 0x1e 2381 + #define HidUsage_Pow_FlowId 0x1f 2382 + #define HidUsage_Pow_Outlet 0x20 2383 + #define HidUsage_Pow_OutletId 0x21 2384 + #define HidUsage_Pow_Gang 0x22 2385 + #define HidUsage_Pow_GangId 0x23 2386 + #define HidUsage_Pow_PowerSummary 0x24 2387 + #define HidUsage_Pow_PowerSummaryId 0x25 2388 + #define HidUsage_Pow_Voltage 0x30 2389 + #define HidUsage_Pow_Current 0x31 2390 + #define HidUsage_Pow_Frequency 0x32 2391 + #define HidUsage_Pow_ApparentPower 0x33 2392 + #define HidUsage_Pow_ActivePower 0x34 2393 + #define HidUsage_Pow_PercentLoad 0x35 2394 + #define HidUsage_Pow_Temperature 0x36 2395 + #define HidUsage_Pow_Humidity 0x37 2396 + #define HidUsage_Pow_BadCount 0x38 2397 + #define HidUsage_Pow_ConfigVoltage 0x40 2398 + #define HidUsage_Pow_ConfigCurrent 0x41 2399 + #define HidUsage_Pow_ConfigFrequency 0x42 2400 + #define HidUsage_Pow_ConfigApparentPower 0x43 2401 + #define HidUsage_Pow_ConfigActivePower 0x44 2402 + #define HidUsage_Pow_ConfigPercentLoad 0x45 2403 + #define HidUsage_Pow_ConfigTemperature 0x46 2404 + #define HidUsage_Pow_ConfigHumidity 0x47 2405 + #define HidUsage_Pow_SwitchOnControl 0x50 2406 + #define HidUsage_Pow_SwitchOffControl 0x51 2407 + #define HidUsage_Pow_ToggleControl 0x52 2408 + #define HidUsage_Pow_LowVoltageTransfer 0x53 2409 + #define HidUsage_Pow_HighVoltageTransfer 0x54 2410 + #define HidUsage_Pow_DelayBeforeReboot 0x55 2411 + #define HidUsage_Pow_DelayBeforeStartup 0x56 2412 + #define HidUsage_Pow_DelayBeforeShutdown 0x57 2413 + #define HidUsage_Pow_Test 0x58 2414 + #define HidUsage_Pow_ModuleReset 0x59 2415 + #define HidUsage_Pow_AudibleAlarmControl 0x5a 2416 + #define HidUsage_Pow_Present 0x60 2417 + #define HidUsage_Pow_Good 0x61 2418 + #define HidUsage_Pow_InternalFailure 0x62 2419 + #define HidUsage_Pow_VoltagOutOfRange 0x63 2420 + #define HidUsage_Pow_FrequencyOutOfRange 0x64 2421 + #define HidUsage_Pow_Overload 0x65 2422 + #define HidUsage_Pow_OverCharged 0x66 2423 + #define HidUsage_Pow_OverTemperature 0x67 2424 + #define HidUsage_Pow_ShutdownRequested 0x68 2425 + #define HidUsage_Pow_ShutdownImminent 0x69 2426 + #define HidUsage_Pow_SwitchOnOff 0x6b 2427 + #define HidUsage_Pow_Switchable 0x6c 2428 + #define HidUsage_Pow_Used 0x6d 2429 + #define HidUsage_Pow_Boost 0x6e 2430 + #define HidUsage_Pow_Buck 0x6f 2431 + #define HidUsage_Pow_Initialized 0x70 2432 + #define HidUsage_Pow_Tested 0x71 2433 + #define HidUsage_Pow_AwaitingPower 0x72 2434 + #define HidUsage_Pow_CommunicationLost 0x73 2435 + #define HidUsage_Pow_iManufacturer 0xfd 2436 + #define HidUsage_Pow_iProduct 0xfe 2437 + #define HidUsage_Pow_iSerialNumber 0xff 2438 + #define HidUsage_BS_SmartBatteryBatteryMode 0x01 2439 + #define HidUsage_BS_SmartBatteryBatteryStatus 0x02 2440 + #define HidUsage_BS_SmartBatteryAlarmWarning 0x03 2441 + #define HidUsage_BS_SmartBatteryChargerMode 0x04 2442 + #define HidUsage_BS_SmartBatteryChargerStatus 0x05 2443 + #define HidUsage_BS_SmartBatteryChargerSpecInfo 0x06 2444 + #define HidUsage_BS_SmartBatterySelectorState 0x07 2445 + #define HidUsage_BS_SmartBatterySelectorPresets 0x08 2446 + #define HidUsage_BS_SmartBatterySelectorInfo 0x09 2447 + #define HidUsage_BS_OptionalMfgFunction1 0x10 2448 + #define HidUsage_BS_OptionalMfgFunction2 0x11 2449 + #define HidUsage_BS_OptionalMfgFunction3 0x12 2450 + #define HidUsage_BS_OptionalMfgFunction4 0x13 2451 + #define HidUsage_BS_OptionalMfgFunction5 0x14 2452 + #define HidUsage_BS_ConnectionToSMBus 0x15 2453 + #define HidUsage_BS_OutputConnection 0x16 2454 + #define HidUsage_BS_ChargerConnection 0x17 2455 + #define HidUsage_BS_BatteryInsertion 0x18 2456 + #define HidUsage_BS_UseNext 0x19 2457 + #define HidUsage_BS_OKToUse 0x1a 2458 + #define HidUsage_BS_BatterySupported 0x1b 2459 + #define HidUsage_BS_SelectorRevision 0x1c 2460 + #define HidUsage_BS_ChargingIndicator 0x1d 2461 + #define HidUsage_BS_ManufacturerAccess 0x28 2462 + #define HidUsage_BS_RemainingCapacityLimit 0x29 2463 + #define HidUsage_BS_RemainingTimeLimit 0x2a 2464 + #define HidUsage_BS_AtRate 0x2b 2465 + #define HidUsage_BS_CapacityMode 0x2c 2466 + #define HidUsage_BS_BroadcastToCharger 0x2d 2467 + #define HidUsage_BS_PrimaryBattery 0x2e 2468 + #define HidUsage_BS_ChargeController 0x2f 2469 + #define HidUsage_BS_TerminateCharge 0x40 2470 + #define HidUsage_BS_TerminateDischarge 0x41 2471 + #define HidUsage_BS_BelowRemainingCapacityLimit 0x42 2472 + #define HidUsage_BS_RemainingTimeLimitExpired 0x43 2473 + #define HidUsage_BS_Charging 0x44 2474 + #define HidUsage_BS_Discharging 0x45 2475 + #define HidUsage_BS_FullyCharged 0x46 2476 + #define HidUsage_BS_FullyDischarged 0x47 2477 + #define HidUsage_BS_ConditioningFlag 0x48 2478 + #define HidUsage_BS_AtRateOK 0x49 2479 + #define HidUsage_BS_SmartBatteryErrorCode 0x4a 2480 + #define HidUsage_BS_NeedReplacement 0x4b 2481 + #define HidUsage_BS_AtRateTimeToFull 0x60 2482 + #define HidUsage_BS_AtRateTimeToEmpty 0x61 2483 + #define HidUsage_BS_AverageCurrent 0x62 2484 + #define HidUsage_BS_MaxError 0x63 2485 + #define HidUsage_BS_RelativeStateOfCharge 0x64 2486 + #define HidUsage_BS_AbsoluteStateOfCharge 0x65 2487 + #define HidUsage_BS_RemainingCapacity 0x66 2488 + #define HidUsage_BS_FullChargeCapacity 0x67 2489 + #define HidUsage_BS_RunTimeToEmpty 0x68 2490 + #define HidUsage_BS_AverageTimeToEmpty 0x69 2491 + #define HidUsage_BS_AverageTimeToFull 0x6a 2492 + #define HidUsage_BS_CycleCount 0x6b 2493 + #define HidUsage_BS_BatteryPackModelLevel 0x80 2494 + #define HidUsage_BS_InternalChargeController 0x81 2495 + #define HidUsage_BS_PrimaryBatterySupport 0x82 2496 + #define HidUsage_BS_DesignCapacity 0x83 2497 + #define HidUsage_BS_SpecificationInfo 0x84 2498 + #define HidUsage_BS_ManufactureDate 0x85 2499 + #define HidUsage_BS_SerialNumber 0x86 2500 + #define HidUsage_BS_iManufacturerName 0x87 2501 + #define HidUsage_BS_iDeviceName 0x88 2502 + #define HidUsage_BS_iDeviceChemistry 0x89 2503 + #define HidUsage_BS_ManufacturerData 0x8a 2504 + #define HidUsage_BS_Rechargeable 0x8b 2505 + #define HidUsage_BS_WarningCapacityLimit 0x8c 2506 + #define HidUsage_BS_CapacityGranularity1 0x8d 2507 + #define HidUsage_BS_CapacityGranularity2 0x8e 2508 + #define HidUsage_BS_iOEMInformation 0x8f 2509 + #define HidUsage_BS_InhibitCharge 0xc0 2510 + #define HidUsage_BS_EnablePolling 0xc1 2511 + #define HidUsage_BS_ResetToZero 0xc2 2512 + #define HidUsage_BS_ACPresent 0xd0 2513 + #define HidUsage_BS_BatteryPresent 0xd1 2514 + #define HidUsage_BS_PowerFail 0xd2 2515 + #define HidUsage_BS_AlarmInhibited 0xd3 2516 + #define HidUsage_BS_ThermistorUnderRange 0xd4 2517 + #define HidUsage_BS_ThermistorHot 0xd5 2518 + #define HidUsage_BS_ThermistorCold 0xd6 2519 + #define HidUsage_BS_ThermistorOverRange 0xd7 2520 + #define HidUsage_BS_VoltageOutOfRange 0xd8 2521 + #define HidUsage_BS_CurrentOutOfRange 0xd9 2522 + #define HidUsage_BS_CurrentNotRegulated 0xda 2523 + #define HidUsage_BS_VoltageNotRegulated 0xdb 2524 + #define HidUsage_BS_MasterMode 0xdc 2525 + #define HidUsage_BS_ChargerSelectorSupport 0xf0 2526 + #define HidUsage_BS_ChargerSpec 0xf1 2527 + #define HidUsage_BS_Level2 0xf2 2528 + #define HidUsage_BS_Level3 0xf3 2529 + #define HidUsage_BS_BarcodeBadgeReader 0x01 2530 + #define HidUsage_BS_BarcodeScanner 0x02 2531 + #define HidUsage_BS_DumbBarCodeScanner 0x03 2532 + #define HidUsage_BS_CordlessScannerBase 0x04 2533 + #define HidUsage_BS_BarCodeScannerCradle 0x05 2534 + #define HidUsage_BS_AttributeReport 0x10 2535 + #define HidUsage_BS_SettingsReport 0x11 2536 + #define HidUsage_BS_ScannedDataReport 0x12 2537 + #define HidUsage_BS_RawScannedDataReport 0x13 2538 + #define HidUsage_BS_TriggerReport 0x14 2539 + #define HidUsage_BS_StatusReport 0x15 2540 + #define HidUsage_BS_UPCEANControlReport 0x16 2541 + #define HidUsage_BS_EAN23LabelControlReport 0x17 2542 + #define HidUsage_BS_Code39ControlReport 0x18 2543 + #define HidUsage_BS_Interleaved2of5ControlReport 0x19 2544 + #define HidUsage_BS_Standard2of5ControlReport 0x1a 2545 + #define HidUsage_BS_MSIPlesseyControlReport 0x1b 2546 + #define HidUsage_BS_CodabarControlReport 0x1c 2547 + #define HidUsage_BS_Code128ControlReport 0x1d 2548 + #define HidUsage_BS_Misc1DControlReport 0x1e 2549 + #define HidUsage_BS_TwoDControlReport 0x1f 2550 + #define HidUsage_BS_AimingPointerMode 0x30 2551 + #define HidUsage_BS_BarCodePresentSensor 0x31 2552 + #define HidUsage_BS_Class1ALaser 0x32 2553 + #define HidUsage_BS_Class2Laser 0x33 2554 + #define HidUsage_BS_HeaterPresent 0x34 2555 + #define HidUsage_BS_ContactScanner 0x35 2556 + #define HidUsage_BS_ElectronicArticleSurveillanceNotification 0x36 2557 + #define HidUsage_BS_ConstantElectronicArticleSurveillance 0x37 2558 + #define HidUsage_BS_ErrorIndication 0x38 2559 + #define HidUsage_BS_FixedBeeper 0x39 2560 + #define HidUsage_BS_GoodDecodeIndication 0x3a 2561 + #define HidUsage_BS_HandsFreeScanning 0x3b 2562 + #define HidUsage_BS_IntrinsicallySafe 0x3c 2563 + #define HidUsage_BS_KlasseEinsLaser 0x3d 2564 + #define HidUsage_BS_LongRangeScanner 0x3e 2565 + #define HidUsage_BS_MirrorSpeedControl 0x3f 2566 + #define HidUsage_BS_NotOnFileIndication 0x40 2567 + #define HidUsage_BS_ProgrammableBeeper 0x41 2568 + #define HidUsage_BS_Triggerless 0x42 2569 + #define HidUsage_BS_Wand 0x43 2570 + #define HidUsage_BS_WaterResistant 0x44 2571 + #define HidUsage_BS_MultiRangeScanner 0x45 2572 + #define HidUsage_BS_ProximitySensor 0x46 2573 + #define HidUsage_BS_FragmentDecoding 0x4d 2574 + #define HidUsage_BS_ScannerReadConfidence 0x4e 2575 + #define HidUsage_BS_DataPrefix 0x4f 2576 + #define HidUsage_BS_PrefixAIMI 0x50 2577 + #define HidUsage_BS_PrefixNone 0x51 2578 + #define HidUsage_BS_PrefixProprietary 0x52 2579 + #define HidUsage_BS_ActiveTime 0x55 2580 + #define HidUsage_BS_AimingLaserPattern 0x56 2581 + #define HidUsage_BS_BarCodePresent 0x57 2582 + #define HidUsage_BS_BeeperState 0x58 2583 + #define HidUsage_BS_LaserOnTime 0x59 2584 + #define HidUsage_BS_LaserState 0x5a 2585 + #define HidUsage_BS_LockoutTime 0x5b 2586 + #define HidUsage_BS_MotorState 0x5c 2587 + #define HidUsage_BS_MotorTimeout 0x5d 2588 + #define HidUsage_BS_PowerOnResetScanner 0x5e 2589 + #define HidUsage_BS_PreventReadofBarcodes 0x5f 2590 + #define HidUsage_BS_InitiateBarcodeRead 0x60 2591 + #define HidUsage_BS_TriggerState 0x61 2592 + #define HidUsage_BS_TriggerMode 0x62 2593 + #define HidUsage_BS_TriggerModeBlinkingLaserOn 0x63 2594 + #define HidUsage_BS_TriggerModeContinuousLaserOn 0x64 2595 + #define HidUsage_BS_TriggerModeLaseronwhilePulled 0x65 2596 + #define HidUsage_BS_TriggerModeLaserstaysonafterrelease 0x66 2597 + #define HidUsage_BS_CommitParameterstoNVM 0x6d 2598 + #define HidUsage_BS_ParameterScanning 0x6e 2599 + #define HidUsage_BS_ParametersChanged 0x6f 2600 + #define HidUsage_BS_Setparameterdefaultvalues 0x70 2601 + #define HidUsage_BS_ScannerInCradle 0x75 2602 + #define HidUsage_BS_ScannerInRange 0x76 2603 + #define HidUsage_BS_AimDuration 0x7a 2604 + #define HidUsage_BS_GoodReadLampDuration 0x7b 2605 + #define HidUsage_BS_GoodReadLampIntensity 0x7c 2606 + #define HidUsage_BS_GoodReadLED 0x7d 2607 + #define HidUsage_BS_GoodReadToneFrequency 0x7e 2608 + #define HidUsage_BS_GoodReadToneLength 0x7f 2609 + #define HidUsage_BS_GoodReadToneVolume 0x80 2610 + #define HidUsage_BS_NoReadMessage 0x82 2611 + #define HidUsage_BS_NotonFileVolume 0x83 2612 + #define HidUsage_BS_PowerupBeep 0x84 2613 + #define HidUsage_BS_SoundErrorBeep 0x85 2614 + #define HidUsage_BS_SoundGoodReadBeep 0x86 2615 + #define HidUsage_BS_SoundNotOnFileBeep 0x87 2616 + #define HidUsage_BS_GoodReadWhentoWrite 0x88 2617 + #define HidUsage_BS_GRWTIAfterDecode 0x89 2618 + #define HidUsage_BS_GRWTIBeepLampaftertransmit 0x8a 2619 + #define HidUsage_BS_GRWTINoBeepLampuseatall 0x8b 2620 + #define HidUsage_BS_BooklandEAN 0x91 2621 + #define HidUsage_BS_ConvertEAN8to13Type 0x92 2622 + #define HidUsage_BS_ConvertUPCAtoEAN13 0x93 2623 + #define HidUsage_BS_ConvertUPCEtoA 0x94 2624 + #define HidUsage_BS_EAN13 0x95 2625 + #define HidUsage_BS_EAN8 0x96 2626 + #define HidUsage_BS_EAN99128Mandatory 0x97 2627 + #define HidUsage_BS_EAN99P5128Optional 0x98 2628 + #define HidUsage_BS_EnableEANTwoLabel 0x99 2629 + #define HidUsage_BS_UPCEAN 0x9a 2630 + #define HidUsage_BS_UPCEANCouponCode 0x9b 2631 + #define HidUsage_BS_UPCEANPeriodicals 0x9c 2632 + #define HidUsage_BS_UPCA 0x9d 2633 + #define HidUsage_BS_UPCAwith128Mandatory 0x9e 2634 + #define HidUsage_BS_UPCAwith128Optional 0x9f 2635 + #define HidUsage_BS_UPCAwithP5Optional 0xa0 2636 + #define HidUsage_BS_UPCE 0xa1 2637 + #define HidUsage_BS_UPCE1 0xa2 2638 + #define HidUsage_BS_Periodical 0xa9 2639 + #define HidUsage_BS_PeriodicalAutoDiscriminatePlus2 0xaa 2640 + #define HidUsage_BS_PeriodicalOnlyDecodewithPlus2 0xab 2641 + #define HidUsage_BS_PeriodicalIgnorePlus2 0xac 2642 + #define HidUsage_BS_PeriodicalAutoDiscriminatePlus5 0xad 2643 + #define HidUsage_BS_PeriodicalOnlyDecodewithPlus5 0xae 2644 + #define HidUsage_BS_PeriodicalIgnorePlus5 0xaf 2645 + #define HidUsage_BS_Check 0xb0 2646 + #define HidUsage_BS_CheckDisablePrice 0xb1 2647 + #define HidUsage_BS_CheckEnable4digitPrice 0xb2 2648 + #define HidUsage_BS_CheckEnable5digitPrice 0xb3 2649 + #define HidUsage_BS_CheckEnableEuropean4digitPrice 0xb4 2650 + #define HidUsage_BS_CheckEnableEuropean5digitPrice 0xb5 2651 + #define HidUsage_BS_EANTwoLabel 0xb7 2652 + #define HidUsage_BS_EANThreeLabel 0xb8 2653 + #define HidUsage_BS_EAN8FlagDigit1 0xb9 2654 + #define HidUsage_BS_EAN8FlagDigit2 0xba 2655 + #define HidUsage_BS_EAN8FlagDigit3 0xbb 2656 + #define HidUsage_BS_EAN13FlagDigit1 0xbc 2657 + #define HidUsage_BS_EAN13FlagDigit2 0xbd 2658 + #define HidUsage_BS_EAN13FlagDigit3 0xbe 2659 + #define HidUsage_BS_AddEAN23LabelDefinition 0xbf 2660 + #define HidUsage_BS_ClearallEAN23LabelDefinitions 0xc0 2661 + #define HidUsage_BS_Codabar 0xc3 2662 + #define HidUsage_BS_Code128 0xc4 2663 + #define HidUsage_BS_Code39 0xc7 2664 + #define HidUsage_BS_Code93 0xc8 2665 + #define HidUsage_BS_FullASCIIConversion 0xc9 2666 + #define HidUsage_BS_Interleaved2of5 0xca 2667 + #define HidUsage_BS_ItalianPharmacyCode 0xcb 2668 + #define HidUsage_BS_MSIPlessey 0xcc 2669 + #define HidUsage_BS_Standard2of5IATA 0xcd 2670 + #define HidUsage_BS_Standard2of5 0xce 2671 + #define HidUsage_BS_TransmitStartStop 0xd3 2672 + #define HidUsage_BS_TriOptic 0xd4 2673 + #define HidUsage_BS_UCCEAN128 0xd5 2674 + #define HidUsage_BS_CheckDigit 0xd6 2675 + #define HidUsage_BS_CheckDigitDisable 0xd7 2676 + #define HidUsage_BS_CheckDigitEnableInterleaved2of5OPCC 0xd8 2677 + #define HidUsage_BS_CheckDigitEnableInterleaved2of5USS 0xd9 2678 + #define HidUsage_BS_CheckDigitEnableStandard2of5OPCC 0xda 2679 + #define HidUsage_BS_CheckDigitEnableStandard2of5USS 0xdb 2680 + #define HidUsage_BS_CheckDigitEnableOneMSIPlessey 0xdc 2681 + #define HidUsage_BS_CheckDigitEnableTwoMSIPlessey 0xdd 2682 + #define HidUsage_BS_CheckDigitCodabarEnable 0xde 2683 + #define HidUsage_BS_CheckDigitCode39Enable 0xdf 2684 + #define HidUsage_BS_TransmitCheckDigit 0xf0 2685 + #define HidUsage_BS_DisableCheckDigitTransmit 0xf1 2686 + #define HidUsage_BS_EnableCheckDigitTransmit 0xf2 2687 + #define HidUsage_BS_SymbologyIdentifier1 0xfb 2688 + #define HidUsage_BS_SymbologyIdentifier2 0xfc 2689 + #define HidUsage_BS_SymbologyIdentifier3 0xfd 2690 + #define HidUsage_BS_DecodedData 0xfe 2691 + #define HidUsage_BS_DecodeDataContinued 0xff 2692 + #define HidUsage_BS_BarSpaceData 0x100 2693 + #define HidUsage_BS_ScannerDataAccuracy 0x101 2694 + #define HidUsage_BS_RawDataPolarity 0x102 2695 + #define HidUsage_BS_PolarityInvertedBarCode 0x103 2696 + #define HidUsage_BS_PolarityNormalBarCode 0x104 2697 + #define HidUsage_BS_MinimumLengthtoDecode 0x106 2698 + #define HidUsage_BS_MaximumLengthtoDecode 0x107 2699 + #define HidUsage_BS_DiscreteLengthtoDecode1 0x108 2700 + #define HidUsage_BS_DiscreteLengthtoDecode2 0x109 2701 + #define HidUsage_BS_DataLengthMethod 0x10a 2702 + #define HidUsage_BS_DLMethodReadany 0x10b 2703 + #define HidUsage_BS_DLMethodCheckinRange 0x10c 2704 + #define HidUsage_BS_DLMethodCheckforDiscrete 0x10d 2705 + #define HidUsage_BS_AztecCode 0x110 2706 + #define HidUsage_BS_BC412 0x111 2707 + #define HidUsage_BS_ChannelCode 0x112 2708 + #define HidUsage_BS_Code16 0x113 2709 + #define HidUsage_BS_Code32 0x114 2710 + #define HidUsage_BS_Code49 0x115 2711 + #define HidUsage_BS_CodeOne 0x116 2712 + #define HidUsage_BS_Colorcode 0x117 2713 + #define HidUsage_BS_DataMatrix 0x118 2714 + #define HidUsage_BS_MaxiCode 0x119 2715 + #define HidUsage_BS_MicroPDF 0x11a 2716 + #define HidUsage_BS_PDF417 0x11b 2717 + #define HidUsage_BS_PosiCode 0x11c 2718 + #define HidUsage_BS_QRCode 0x11d 2719 + #define HidUsage_BS_SuperCode 0x11e 2720 + #define HidUsage_BS_UltraCode 0x11f 2721 + #define HidUsage_BS_USD5SlugCode 0x120 2722 + #define HidUsage_BS_VeriCode 0x121 2723 + #define HidUsage_Sca_Scales 0x01 2724 + #define HidUsage_Sca_ScaleDevice 0x20 2725 + #define HidUsage_Sca_ScaleClass 0x21 2726 + #define HidUsage_Sca_ScaleClassIMetric 0x22 2727 + #define HidUsage_Sca_ScaleClassIIMetric 0x23 2728 + #define HidUsage_Sca_ScaleClassIIIMetric 0x24 2729 + #define HidUsage_Sca_ScaleClassIIILMetric 0x25 2730 + #define HidUsage_Sca_ScaleClassIVMetric 0x26 2731 + #define HidUsage_Sca_ScaleClassIIIEnglish 0x27 2732 + #define HidUsage_Sca_ScaleClassIIILEnglish 0x28 2733 + #define HidUsage_Sca_ScaleClassIVEnglish 0x29 2734 + #define HidUsage_Sca_ScaleClassGeneric 0x2a 2735 + #define HidUsage_Sca_ScaleAttributeReport 0x30 2736 + #define HidUsage_Sca_ScaleControlReport 0x31 2737 + #define HidUsage_Sca_ScaleDataReport 0x32 2738 + #define HidUsage_Sca_ScaleStatusReport 0x33 2739 + #define HidUsage_Sca_ScaleWeightLimitReport 0x34 2740 + #define HidUsage_Sca_ScaleStatisticsReport 0x35 2741 + #define HidUsage_Sca_DataWeight 0x40 2742 + #define HidUsage_Sca_DataScaling 0x41 2743 + #define HidUsage_Sca_WeightUnit 0x50 2744 + #define HidUsage_Sca_WeightUnitMilligram 0x51 2745 + #define HidUsage_Sca_WeightUnitGram 0x52 2746 + #define HidUsage_Sca_WeightUnitKilogram 0x53 2747 + #define HidUsage_Sca_WeightUnitCarats 0x54 2748 + #define HidUsage_Sca_WeightUnitTaels 0x55 2749 + #define HidUsage_Sca_WeightUnitGrains 0x56 2750 + #define HidUsage_Sca_WeightUnitPennyweights 0x57 2751 + #define HidUsage_Sca_WeightUnitMetricTon 0x58 2752 + #define HidUsage_Sca_WeightUnitAvoirTon 0x59 2753 + #define HidUsage_Sca_WeightUnitTroyOunce 0x5a 2754 + #define HidUsage_Sca_WeightUnitOunce 0x5b 2755 + #define HidUsage_Sca_WeightUnitPound 0x5c 2756 + #define HidUsage_Sca_CalibrationCount 0x60 2757 + #define HidUsage_Sca_ReZeroCount 0x61 2758 + #define HidUsage_Sca_ScaleStatus 0x70 2759 + #define HidUsage_Sca_ScaleStatusFault 0x71 2760 + #define HidUsage_Sca_ScaleStatusStableatCenterofZero 0x72 2761 + #define HidUsage_Sca_ScaleStatusInMotion 0x73 2762 + #define HidUsage_Sca_ScaleStatusWeightStable 0x74 2763 + #define HidUsage_Sca_ScaleStatusUnderZero 0x75 2764 + #define HidUsage_Sca_ScaleStatusOverWeightLimit 0x76 2765 + #define HidUsage_Sca_ScaleStatusRequiresCalibration 0x77 2766 + #define HidUsage_Sca_ScaleStatusRequiresRezeroing 0x78 2767 + #define HidUsage_Sca_ZeroScale 0x80 2768 + #define HidUsage_Sca_EnforcedZeroReturn 0x81 2769 + #define HidUsage_MSR_MSRDeviceReadOnly 0x01 2770 + #define HidUsage_MSR_Track1Length 0x11 2771 + #define HidUsage_MSR_Track2Length 0x12 2772 + #define HidUsage_MSR_Track3Length 0x13 2773 + #define HidUsage_MSR_TrackJISLength 0x14 2774 + #define HidUsage_MSR_TrackData 0x20 2775 + #define HidUsage_MSR_Track1Data 0x21 2776 + #define HidUsage_MSR_Track2Data 0x22 2777 + #define HidUsage_MSR_Track3Data 0x23 2778 + #define HidUsage_MSR_TrackJISData 0x24 2779 + #define HidUsage_CC_CameraAutofocus 0x20 2780 + #define HidUsage_CC_CameraShutter 0x21 2781 + #define HidUsage_Arc_GeneralPurposeIOCard 0x01 2782 + #define HidUsage_Arc_CoinDoor 0x02 2783 + #define HidUsage_Arc_WatchdogTimer 0x03 2784 + #define HidUsage_Arc_GeneralPurposeAnalogInputState 0x30 2785 + #define HidUsage_Arc_GeneralPurposeDigitalInputState 0x31 2786 + #define HidUsage_Arc_GeneralPurposeOpticalInputState 0x32 2787 + #define HidUsage_Arc_GeneralPurposeDigitalOutputState 0x33 2788 + #define HidUsage_Arc_NumberofCoinDoors 0x34 2789 + #define HidUsage_Arc_CoinDrawerDropCount 0x35 2790 + #define HidUsage_Arc_CoinDrawerStart 0x36 2791 + #define HidUsage_Arc_CoinDrawerService 0x37 2792 + #define HidUsage_Arc_CoinDrawerTilt 0x38 2793 + #define HidUsage_Arc_CoinDoorTest 0x39 2794 + #define HidUsage_Arc_CoinDoorLockout 0x40 2795 + #define HidUsage_Arc_WatchdogTimeout 0x41 2796 + #define HidUsage_Arc_WatchdogAction 0x42 2797 + #define HidUsage_Arc_WatchdogReboot 0x43 2798 + #define HidUsage_Arc_WatchdogRestart 0x44 2799 + #define HidUsage_Arc_AlarmInput 0x45 2800 + #define HidUsage_Arc_CoinDoorCounter 0x46 2801 + #define HidUsage_Arc_IODirectionMapping 0x47 2802 + #define HidUsage_Arc_SetIODirectionMapping 0x48 2803 + #define HidUsage_Arc_ExtendedOpticalInputState 0x49 2804 + #define HidUsage_Arc_PinPadInputState 0x4a 2805 + #define HidUsage_Arc_PinPadStatus 0x4b 2806 + #define HidUsage_Arc_PinPadOutput 0x4c 2807 + #define HidUsage_Arc_PinPadCommand 0x4d 2808 + #define HidUsage_FIDOA_U2FAuthenticatorDevice 0x01 2809 + #define HidUsage_FIDOA_InputReportData 0x20 2810 + #define HidUsage_FIDOA_OutputReportData 0x21
+3
drivers/hid/hid-alps.c
··· 437 437 int ret = 0; 438 438 struct alps_dev *hdata = hid_get_drvdata(hdev); 439 439 440 + if (!(hdev->claimed & HID_CLAIMED_INPUT) || !hdata->input) 441 + return 0; 442 + 440 443 switch (hdev->product) { 441 444 case HID_PRODUCT_ID_T4_BTNLESS: 442 445 ret = t4_raw_event(hdata, data, size);
+8 -4
drivers/hid/hid-apple.c
··· 623 623 struct apple_sc *asc = hid_get_drvdata(hdev); 624 624 struct hid_report_enum *report_enum; 625 625 struct hid_report *report; 626 + struct hid_battery *bat; 626 627 627 - if (!(asc->quirks & APPLE_RDESC_BATTERY) || !hdev->battery) 628 + bat = hid_get_battery(hdev); 629 + if (!(asc->quirks & APPLE_RDESC_BATTERY) || !bat) 628 630 return -1; 629 631 630 - report_enum = &hdev->report_enum[hdev->battery_report_type]; 631 - report = report_enum->report_id_hash[hdev->battery_report_id]; 632 + report_enum = &hdev->report_enum[bat->report_type]; 633 + report = report_enum->report_id_hash[bat->report_id]; 632 634 633 635 if (!report || report->maxfield < 1) 634 636 return -1; 635 637 636 - if (hdev->battery_capacity == hdev->battery_max) 638 + if (bat->capacity == bat->max) 637 639 return -1; 638 640 639 641 hid_hw_request(hdev, report, HID_REQ_GET_REPORT); ··· 860 858 asc->backlight->cdev.name = "apple::kbd_backlight"; 861 859 asc->backlight->cdev.max_brightness = rep->backlight_on_max; 862 860 asc->backlight->cdev.brightness_set_blocking = apple_backlight_led_set; 861 + asc->backlight->cdev.flags = LED_CORE_SUSPENDRESUME; 863 862 864 863 ret = apple_backlight_set(hdev, 0, 0); 865 864 if (ret < 0) { ··· 929 926 backlight->cdev.name = ":white:" LED_FUNCTION_KBD_BACKLIGHT; 930 927 backlight->cdev.max_brightness = backlight->brightness->field[0]->logical_maximum; 931 928 backlight->cdev.brightness_set_blocking = apple_magic_backlight_led_set; 929 + backlight->cdev.flags = LED_CORE_SUSPENDRESUME; 932 930 933 931 apple_magic_backlight_set(backlight, 0, 0); 934 932
+57 -51
drivers/hid/hid-asus.c
··· 20 20 * Copyright (c) 2016 Frederik Wenigwieser <frederik.wenigwieser@gmail.com> 21 21 */ 22 22 23 - /* 24 - */ 25 - 26 23 #include <linux/acpi.h> 24 + #include <linux/cleanup.h> 27 25 #include <linux/dmi.h> 28 26 #include <linux/hid.h> 29 27 #include <linux/module.h> ··· 99 101 #define QUIRK_ROG_CLAYMORE_II_KEYBOARD BIT(12) 100 102 #define QUIRK_ROG_ALLY_XPAD BIT(13) 101 103 #define QUIRK_HID_FN_LOCK BIT(14) 102 - #define QUIRK_ROG_NKEY_ID1ID2_INIT BIT(15) 103 104 104 105 #define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \ 105 106 QUIRK_NO_INIT_REPORTS | \ ··· 203 206 .contact_size = 5, 204 207 .max_contacts = 5, 205 208 .report_size = 32 /* 2 byte header + 5 * 5 + 5 byte footer */, 209 + }; 210 + 211 + static const u8 asus_report_id_init[] = { 212 + FEATURE_KBD_REPORT_ID, 213 + FEATURE_KBD_LED_REPORT_ID1, 214 + FEATURE_KBD_LED_REPORT_ID2 206 215 }; 207 216 208 217 static void asus_report_contact_down(struct asus_drvdata *drvdat, ··· 357 354 struct hid_usage *usage, __s32 value) 358 355 { 359 356 struct asus_drvdata *drvdata = hid_get_drvdata(hdev); 360 - 357 + 361 358 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_ASUSVENDOR && 362 359 (usage->hid & HID_USAGE) != 0x00 && 363 360 (usage->hid & HID_USAGE) != 0xff && !usage->type) { ··· 446 443 /* 447 444 * G713 and G733 send these codes on some keypresses, depending on 448 445 * the key pressed it can trigger a shutdown event if not caught. 449 - */ 450 - if (data[0] == 0x02 && data[1] == 0x30) { 446 + */ 447 + if (data[0] == 0x02 && data[1] == 0x30) 451 448 return -1; 452 - } 453 449 } 454 450 455 451 if (drvdata->quirks & QUIRK_ROG_CLAYMORE_II_KEYBOARD) { 456 452 /* 457 453 * CLAYMORE II keyboard sends this packet when it goes to sleep 458 454 * this causes the whole system to go into suspend. 459 - */ 460 - 461 - if(size == 2 && data[0] == 0x02 && data[1] == 0x00) { 455 + */ 456 + if (size == 2 && data[0] == 0x02 && data[1] == 0x00) 462 457 return -1; 463 - } 464 458 } 465 459 466 460 return 0; ··· 465 465 466 466 static int asus_kbd_set_report(struct hid_device *hdev, const u8 *buf, size_t buf_size) 467 467 { 468 - unsigned char *dmabuf; 469 - int ret; 470 - 471 - dmabuf = kmemdup(buf, buf_size, GFP_KERNEL); 468 + u8 *dmabuf __free(kfree) = kmemdup(buf, buf_size, GFP_KERNEL); 472 469 if (!dmabuf) 473 470 return -ENOMEM; 474 471 475 472 /* 476 473 * The report ID should be set from the incoming buffer due to LED and key 477 474 * interfaces having different pages 478 - */ 479 - ret = hid_hw_raw_request(hdev, buf[0], dmabuf, 480 - buf_size, HID_FEATURE_REPORT, 481 - HID_REQ_SET_REPORT); 482 - kfree(dmabuf); 483 - 484 - return ret; 475 + */ 476 + return hid_hw_raw_request(hdev, buf[0], dmabuf, buf_size, HID_FEATURE_REPORT, 477 + HID_REQ_SET_REPORT); 485 478 } 486 479 487 480 static int asus_kbd_init(struct hid_device *hdev, u8 report_id) ··· 715 722 } 716 723 } 717 724 725 + static bool asus_has_report_id(struct hid_device *hdev, u16 report_id) 726 + { 727 + struct hid_report *report; 728 + int t; 729 + 730 + for (t = HID_INPUT_REPORT; t <= HID_FEATURE_REPORT; t++) { 731 + list_for_each_entry(report, &hdev->report_enum[t].report_list, list) { 732 + if (report->id == report_id) 733 + return true; 734 + } 735 + } 736 + 737 + return false; 738 + } 739 + 718 740 static int asus_kbd_register_leds(struct hid_device *hdev) 719 741 { 720 742 struct asus_drvdata *drvdata = hid_get_drvdata(hdev); ··· 737 729 struct usb_device *udev; 738 730 unsigned char kbd_func; 739 731 int ret; 740 - 741 - ret = asus_kbd_init(hdev, FEATURE_KBD_REPORT_ID); 742 - if (ret < 0) 743 - return ret; 744 732 745 733 /* Get keyboard functions */ 746 734 ret = asus_kbd_get_functions(hdev, &kbd_func, FEATURE_KBD_REPORT_ID); ··· 746 742 /* Check for backlight support */ 747 743 if (!(kbd_func & SUPPORT_KBD_BACKLIGHT)) 748 744 return -ENODEV; 749 - 750 - if (drvdata->quirks & QUIRK_ROG_NKEY_ID1ID2_INIT) { 751 - asus_kbd_init(hdev, FEATURE_KBD_LED_REPORT_ID1); 752 - asus_kbd_init(hdev, FEATURE_KBD_LED_REPORT_ID2); 753 - } 754 745 755 746 if (dmi_match(DMI_PRODUCT_FAMILY, "ProArt P16")) { 756 747 ret = asus_kbd_disable_oobe(hdev); ··· 1162 1163 return 0; 1163 1164 } 1164 1165 1165 - static int __maybe_unused asus_resume(struct hid_device *hdev) { 1166 + static int __maybe_unused asus_resume(struct hid_device *hdev) 1167 + { 1166 1168 struct asus_drvdata *drvdata = hid_get_drvdata(hdev); 1167 1169 int ret = 0; 1168 1170 ··· 1294 1294 return ret; 1295 1295 } 1296 1296 1297 + for (int r = 0; r < ARRAY_SIZE(asus_report_id_init); r++) { 1298 + if (asus_has_report_id(hdev, asus_report_id_init[r])) { 1299 + ret = asus_kbd_init(hdev, asus_report_id_init[r]); 1300 + if (ret < 0) 1301 + hid_warn(hdev, "Failed to initialize 0x%x: %d.\n", 1302 + asus_report_id_init[r], ret); 1303 + } 1304 + } 1305 + 1306 + /* Laptops keyboard backlight is always at 0x5a */ 1297 1307 if (is_vendor && (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT) && 1298 - asus_kbd_register_leds(hdev)) 1308 + (asus_has_report_id(hdev, FEATURE_KBD_REPORT_ID)) && 1309 + (asus_kbd_register_leds(hdev))) 1299 1310 hid_warn(hdev, "Failed to initialize backlight.\n"); 1300 1311 1301 1312 /* ··· 1322 1311 * were freed during registration due to no usages being mapped, 1323 1312 * leaving drvdata->input pointing to freed memory. 1324 1313 */ 1325 - if (!drvdata->input || !(hdev->claimed & HID_CLAIMED_INPUT)) { 1326 - hid_err(hdev, "Asus input not registered\n"); 1327 - ret = -ENOMEM; 1328 - goto err_stop_hw; 1329 - } 1314 + if (drvdata->input && (hdev->claimed & HID_CLAIMED_INPUT)) { 1315 + if (drvdata->tp) 1316 + drvdata->input->name = "Asus TouchPad"; 1317 + else 1318 + drvdata->input->name = "Asus Keyboard"; 1330 1319 1331 - if (drvdata->tp) { 1332 - drvdata->input->name = "Asus TouchPad"; 1333 - } else { 1334 - drvdata->input->name = "Asus Keyboard"; 1335 - } 1336 - 1337 - if (drvdata->tp) { 1338 - ret = asus_start_multitouch(hdev); 1339 - if (ret) 1340 - goto err_stop_hw; 1320 + if (drvdata->tp) { 1321 + ret = asus_start_multitouch(hdev); 1322 + if (ret) 1323 + goto err_stop_hw; 1324 + } 1341 1325 } 1342 1326 1343 1327 return 0; ··· 1490 1484 QUIRK_USE_KBD_BACKLIGHT }, 1491 1485 { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, 1492 1486 USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD), 1493 - QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_NKEY_ID1ID2_INIT }, 1487 + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, 1494 1488 { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, 1495 1489 USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2), 1496 - QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_HID_FN_LOCK | QUIRK_ROG_NKEY_ID1ID2_INIT }, 1490 + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_HID_FN_LOCK }, 1497 1491 { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, 1498 1492 USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR), 1499 1493 QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
+111 -95
drivers/hid/hid-core.c
··· 71 71 if (!value || !n) 72 72 return 0; 73 73 74 + if (n > 32) 75 + n = 32; 76 + 74 77 a = value >> (n - 1); 75 78 if (a && a != -1) 76 79 return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; ··· 927 924 */ 928 925 static int hid_scan_report(struct hid_device *hid) 929 926 { 930 - struct hid_parser *parser; 931 927 struct hid_item item; 932 928 const __u8 *start = hid->dev_rdesc; 933 929 const __u8 *end = start + hid->dev_rsize; ··· 938 936 hid_parser_reserved 939 937 }; 940 938 941 - parser = vzalloc(sizeof(struct hid_parser)); 939 + struct hid_parser *parser __free(kvfree) = vzalloc(sizeof(*parser)); 942 940 if (!parser) 943 941 return -ENOMEM; 944 942 ··· 989 987 } 990 988 991 989 kfree(parser->collection_stack); 992 - vfree(parser); 993 990 return 0; 994 991 } 995 992 ··· 1245 1244 } 1246 1245 EXPORT_SYMBOL_GPL(hid_setup_resolution_multiplier); 1247 1246 1247 + static int hid_parse_collections(struct hid_device *device) 1248 + { 1249 + struct hid_item item; 1250 + const u8 *start = device->rdesc; 1251 + const u8 *end = start + device->rsize; 1252 + const u8 *next; 1253 + int ret; 1254 + static typeof(hid_parser_main) (* const dispatch_type[]) = { 1255 + hid_parser_main, 1256 + hid_parser_global, 1257 + hid_parser_local, 1258 + hid_parser_reserved 1259 + }; 1260 + 1261 + struct hid_parser *parser __free(kvfree) = vzalloc(sizeof(*parser)); 1262 + if (!parser) 1263 + return -ENOMEM; 1264 + 1265 + parser->device = device; 1266 + 1267 + device->collection = kzalloc_objs(*device->collection, 1268 + HID_DEFAULT_NUM_COLLECTIONS); 1269 + if (!device->collection) 1270 + return -ENOMEM; 1271 + 1272 + device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; 1273 + for (unsigned int i = 0; i < HID_DEFAULT_NUM_COLLECTIONS; i++) 1274 + device->collection[i].parent_idx = -1; 1275 + 1276 + ret = -EINVAL; 1277 + if (start == end) { 1278 + hid_err(device, "rejecting 0-sized report descriptor\n"); 1279 + goto out; 1280 + } 1281 + 1282 + while ((next = fetch_item(start, end, &item)) != NULL) { 1283 + start = next; 1284 + 1285 + if (item.format != HID_ITEM_FORMAT_SHORT) { 1286 + hid_err(device, "unexpected long global item\n"); 1287 + goto out; 1288 + } 1289 + 1290 + if (dispatch_type[item.type](parser, &item)) { 1291 + hid_err(device, "item %u %u %u %u parsing failed\n", 1292 + item.format, 1293 + (unsigned int)item.size, 1294 + (unsigned int)item.type, 1295 + (unsigned int)item.tag); 1296 + goto out; 1297 + } 1298 + } 1299 + 1300 + if (start != end) { 1301 + hid_err(device, "item fetching failed at offset %u/%u\n", 1302 + device->rsize - (unsigned int)(end - start), 1303 + device->rsize); 1304 + goto out; 1305 + } 1306 + 1307 + if (parser->collection_stack_ptr) { 1308 + hid_err(device, "unbalanced collection at end of report description\n"); 1309 + goto out; 1310 + } 1311 + 1312 + if (parser->local.delimiter_depth) { 1313 + hid_err(device, "unbalanced delimiter at end of report description\n"); 1314 + goto out; 1315 + } 1316 + 1317 + /* 1318 + * fetch initial values in case the device's 1319 + * default multiplier isn't the recommended 1 1320 + */ 1321 + hid_setup_resolution_multiplier(device); 1322 + 1323 + device->status |= HID_STAT_PARSED; 1324 + ret = 0; 1325 + 1326 + out: 1327 + kfree(parser->collection_stack); 1328 + return ret; 1329 + } 1330 + 1248 1331 /** 1249 1332 * hid_open_report - open a driver-specific device report 1250 1333 * ··· 1343 1258 */ 1344 1259 int hid_open_report(struct hid_device *device) 1345 1260 { 1346 - struct hid_parser *parser; 1347 - struct hid_item item; 1348 1261 unsigned int size; 1349 - const __u8 *start; 1350 - const __u8 *end; 1351 - const __u8 *next; 1352 - int ret; 1353 - int i; 1354 - static int (*dispatch_type[])(struct hid_parser *parser, 1355 - struct hid_item *item) = { 1356 - hid_parser_main, 1357 - hid_parser_global, 1358 - hid_parser_local, 1359 - hid_parser_reserved 1360 - }; 1262 + const u8 *start; 1263 + int error; 1361 1264 1362 1265 if (WARN_ON(device->status & HID_STAT_PARSED)) 1363 1266 return -EBUSY; ··· 1361 1288 * on a copy of our report descriptor so it can 1362 1289 * change it. 1363 1290 */ 1364 - __u8 *buf = kmemdup(start, size, GFP_KERNEL); 1291 + u8 *buf __free(kfree) = kmemdup(start, size, GFP_KERNEL); 1365 1292 1366 - if (buf == NULL) 1293 + if (!buf) 1367 1294 return -ENOMEM; 1368 1295 1369 1296 start = device->driver->report_fixup(device, buf, &size); ··· 1374 1301 * needs to be cleaned up or not at the end. 1375 1302 */ 1376 1303 start = kmemdup(start, size, GFP_KERNEL); 1377 - kfree(buf); 1378 - if (start == NULL) 1304 + if (!start) 1379 1305 return -ENOMEM; 1380 1306 } 1381 1307 1382 1308 device->rdesc = start; 1383 1309 device->rsize = size; 1384 1310 1385 - parser = vzalloc(sizeof(struct hid_parser)); 1386 - if (!parser) { 1387 - ret = -ENOMEM; 1388 - goto alloc_err; 1311 + error = hid_parse_collections(device); 1312 + if (error) { 1313 + hid_close_report(device); 1314 + return error; 1389 1315 } 1390 1316 1391 - parser->device = device; 1392 - 1393 - end = start + size; 1394 - 1395 - device->collection = kzalloc_objs(struct hid_collection, 1396 - HID_DEFAULT_NUM_COLLECTIONS); 1397 - if (!device->collection) { 1398 - ret = -ENOMEM; 1399 - goto err; 1400 - } 1401 - device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; 1402 - for (i = 0; i < HID_DEFAULT_NUM_COLLECTIONS; i++) 1403 - device->collection[i].parent_idx = -1; 1404 - 1405 - ret = -EINVAL; 1406 - while ((next = fetch_item(start, end, &item)) != NULL) { 1407 - start = next; 1408 - 1409 - if (item.format != HID_ITEM_FORMAT_SHORT) { 1410 - hid_err(device, "unexpected long global item\n"); 1411 - goto err; 1412 - } 1413 - 1414 - if (dispatch_type[item.type](parser, &item)) { 1415 - hid_err(device, "item %u %u %u %u parsing failed\n", 1416 - item.format, (unsigned)item.size, 1417 - (unsigned)item.type, (unsigned)item.tag); 1418 - goto err; 1419 - } 1420 - 1421 - if (start == end) { 1422 - if (parser->collection_stack_ptr) { 1423 - hid_err(device, "unbalanced collection at end of report description\n"); 1424 - goto err; 1425 - } 1426 - if (parser->local.delimiter_depth) { 1427 - hid_err(device, "unbalanced delimiter at end of report description\n"); 1428 - goto err; 1429 - } 1430 - 1431 - /* 1432 - * fetch initial values in case the device's 1433 - * default multiplier isn't the recommended 1 1434 - */ 1435 - hid_setup_resolution_multiplier(device); 1436 - 1437 - kfree(parser->collection_stack); 1438 - vfree(parser); 1439 - device->status |= HID_STAT_PARSED; 1440 - 1441 - return 0; 1442 - } 1443 - } 1444 - 1445 - hid_err(device, "item fetching failed at offset %u/%u\n", 1446 - size - (unsigned int)(end - start), size); 1447 - err: 1448 - kfree(parser->collection_stack); 1449 - alloc_err: 1450 - vfree(parser); 1451 - hid_close_report(device); 1452 - return ret; 1317 + return 0; 1453 1318 } 1454 1319 EXPORT_SYMBOL_GPL(hid_open_report); 1455 1320 ··· 2000 1989 int __hid_request(struct hid_device *hid, struct hid_report *report, 2001 1990 enum hid_class_request reqtype) 2002 1991 { 2003 - char *buf, *data_buf; 1992 + u8 *data_buf; 2004 1993 int ret; 2005 1994 u32 len; 2006 1995 2007 - buf = hid_alloc_report_buf(report, GFP_KERNEL); 1996 + u8 *buf __free(kfree) = hid_alloc_report_buf(report, GFP_KERNEL); 2008 1997 if (!buf) 2009 1998 return -ENOMEM; 2010 1999 ··· 2023 2012 ret = hid_hw_raw_request(hid, report->id, buf, len, report->type, reqtype); 2024 2013 if (ret < 0) { 2025 2014 dbg_hid("unable to complete request: %d\n", ret); 2026 - goto out; 2015 + return ret; 2027 2016 } 2028 2017 2029 2018 if (reqtype == HID_REQ_GET_REPORT) 2030 2019 hid_input_report(hid, report->type, buf, ret, 0); 2031 2020 2032 - ret = 0; 2033 - 2034 - out: 2035 - kfree(buf); 2036 - return ret; 2021 + return 0; 2037 2022 } 2038 2023 EXPORT_SYMBOL_GPL(__hid_request); 2039 2024 ··· 2895 2888 if (add_uevent_var(env, "MODALIAS=hid:b%04Xg%04Xv%08Xp%08X", 2896 2889 hdev->bus, hdev->group, hdev->vendor, hdev->product)) 2897 2890 return -ENOMEM; 2891 + if (hdev->firmware_version) { 2892 + if (add_uevent_var(env, "HID_FIRMWARE_VERSION=0x%04llX", 2893 + hdev->firmware_version)) 2894 + return -ENOMEM; 2895 + } 2898 2896 2899 2897 return 0; 2900 2898 } ··· 3002 2990 sema_init(&hdev->driver_input_lock, 1); 3003 2991 mutex_init(&hdev->ll_open_lock); 3004 2992 kref_init(&hdev->ref); 2993 + 2994 + #ifdef CONFIG_HID_BATTERY_STRENGTH 2995 + INIT_LIST_HEAD(&hdev->batteries); 2996 + #endif 3005 2997 3006 2998 ret = hid_bpf_device_init(hdev); 3007 2999 if (ret)
+82
drivers/hid/hid-huawei.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * HID driver for some huawei "special" devices 4 + * 5 + * Copyright (c) 2026 Miao Li <limiao@kylinos.cn> 6 + */ 7 + 8 + #include <linux/device.h> 9 + #include <linux/hid.h> 10 + #include <linux/module.h> 11 + #include <linux/usb.h> 12 + 13 + #include "hid-ids.h" 14 + 15 + static const __u8 huawei_cd30_kbd_rdesc_fixed[] = { 16 + 0x05, 0x01, /* Usage Page (Generic Desktop) */ 17 + 0x09, 0x80, /* Usage (System Control) */ 18 + 0xa1, 0x01, /* Collection (Application) */ 19 + 0x85, 0x01, /* Report ID (1) */ 20 + 0x19, 0x81, /* Usage Minimum (System Power Down) */ 21 + 0x29, 0x83, /* Usage Maximum (System Wake Up) */ 22 + 0x15, 0x00, /* Logical Minimum (0) */ 23 + 0x25, 0x01, /* Logical Maximum (1) */ 24 + 0x75, 0x01, /* Report Size (1 bit) */ 25 + 0x95, 0x03, /* Report Count (3) */ 26 + 0x81, 0x02, /* Input (Data,Var,Abs) */ 27 + 0x95, 0x05, /* Report Count (5) */ 28 + 0x81, 0x01, /* Input (Cnst,Ary,Abs) */ 29 + 0xc0, /* End Collection */ 30 + 0x05, 0x0c, /* Usage Page (Consumer) */ 31 + 0x09, 0x01, /* Usage (Consumer Control) */ 32 + 0xa1, 0x01, /* Collection (Application) */ 33 + 0x85, 0x02, /* Report ID (2) */ 34 + 0x19, 0x00, /* Usage Minimum (0) */ 35 + 0x2a, 0x3c, 0x02, /* Usage Maximum (0x023C) */ 36 + 0x15, 0x00, /* Logical Minimum (0) */ 37 + 0x26, 0x3c, 0x02, /* Logical Maximum (0x023C) */ 38 + 0x95, 0x01, /* Report Count (1) */ 39 + 0x75, 0x10, /* Report Size (16 bits) */ 40 + 0x81, 0x00, /* Input (Data,Ary,Abs) */ 41 + 0xc0 /* End Collection */ 42 + }; 43 + 44 + static const __u8 *huawei_report_fixup(struct hid_device *hdev, __u8 *rdesc, 45 + unsigned int *rsize) 46 + { 47 + struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 48 + 49 + switch (hdev->product) { 50 + case USB_DEVICE_ID_HUAWEI_CD30KBD: 51 + if (intf->cur_altsetting->desc.bInterfaceNumber == 1) { 52 + if (*rsize != sizeof(huawei_cd30_kbd_rdesc_fixed) || 53 + memcmp(huawei_cd30_kbd_rdesc_fixed, rdesc, 54 + sizeof(huawei_cd30_kbd_rdesc_fixed)) != 0) { 55 + hid_info(hdev, "Replacing Huawei cd30 keyboard report descriptor.\n"); 56 + *rsize = sizeof(huawei_cd30_kbd_rdesc_fixed); 57 + return huawei_cd30_kbd_rdesc_fixed; 58 + } 59 + } 60 + break; 61 + } 62 + 63 + return rdesc; 64 + } 65 + 66 + static const struct hid_device_id huawei_devices[] = { 67 + /* HUAWEI cd30 keyboard */ 68 + { HID_USB_DEVICE(USB_VENDOR_ID_HUAWEI, USB_DEVICE_ID_HUAWEI_CD30KBD)}, 69 + { } 70 + }; 71 + MODULE_DEVICE_TABLE(hid, huawei_devices); 72 + 73 + static struct hid_driver huawei_driver = { 74 + .name = "huawei", 75 + .id_table = huawei_devices, 76 + .report_fixup = huawei_report_fixup, 77 + }; 78 + module_hid_driver(huawei_driver); 79 + 80 + MODULE_LICENSE("GPL"); 81 + MODULE_AUTHOR("Miao Li <limiao@kylinos.cn>"); 82 + MODULE_DESCRIPTION("HID driver for some huawei \"special\" devices");
+34 -2
drivers/hid/hid-ids.h
··· 667 667 #define USB_DEVICE_ID_UGCI_FLYING 0x0020 668 668 #define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 669 669 670 + #define USB_VENDOR_ID_HARMONIX 0x1bad 671 + #define USB_DEVICE_ID_HARMONIX_WII_RB1_GUITAR 0x0004 672 + #define USB_DEVICE_ID_HARMONIX_WII_RB2_GUITAR 0x3010 673 + #define USB_DEVICE_ID_HARMONIX_WII_RB1_DRUMS 0x0005 674 + #define USB_DEVICE_ID_HARMONIX_WII_RB2_DRUMS 0x3110 675 + #define USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_DRUMS_MODE 0x3138 676 + #define USB_DEVICE_ID_HARMONIX_WII_RB3_MUSTANG_GUITAR 0x3430 677 + #define USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_MUSTANG_MODE 0x3438 678 + #define USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_SQUIER_MODE 0x3538 679 + #define USB_DEVICE_ID_HARMONIX_WII_RB3_KEYBOARD 0x3330 680 + #define USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_KEYBOARD_MODE 0x3338 681 + 670 682 #define USB_VENDOR_ID_HP 0x03f0 671 683 #define USB_PRODUCT_ID_HP_ELITE_PRESENTER_MOUSE_464A 0x464a 672 684 #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A 0x0a4a ··· 753 741 #define I2C_DEVICE_ID_ITE_LENOVO_YOGA_SLIM_7X_KEYBOARD 0x8987 754 742 #define USB_DEVICE_ID_ITE8595 0x8595 755 743 #define USB_DEVICE_ID_ITE_MEDION_E1239T 0xce50 744 + 745 + #define USB_VENDOR_ID_QHE 0x1a86 746 + #define USB_DEVICE_ID_LENOVO_LEGION_GO_S_XINPUT 0xe310 747 + #define USB_DEVICE_ID_LENOVO_LEGION_GO_S_DINPUT 0xe311 756 748 757 749 #define USB_VENDOR_ID_JABRA 0x0b0e 758 750 #define USB_DEVICE_ID_JABRA_SPEAK_410 0x0412 ··· 877 861 #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E 0x602e 878 862 #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6093 0x6093 879 863 #define USB_DEVICE_ID_LENOVO_LEGION_GO_DUAL_DINPUT 0x6184 864 + #define USB_DEVICE_ID_LENOVO_LEGION_GO2_XINPUT 0x61eb 865 + #define USB_DEVICE_ID_LENOVO_LEGION_GO2_DINPUT 0x61ec 880 866 #define USB_DEVICE_ID_LENOVO_LEGION_GO2_DUAL_DINPUT 0x61ed 867 + #define USB_DEVICE_ID_LENOVO_LEGION_GO2_FPS 0x61ee 881 868 882 869 #define USB_VENDOR_ID_LETSKETCH 0x6161 883 870 #define USB_DEVICE_ID_WP9620N 0x4d15 ··· 1320 1301 #define USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER 0x1000 1321 1302 1322 1303 #define USB_VENDOR_ID_SONY_RHYTHM 0x12ba 1323 - #define USB_DEVICE_ID_SONY_PS3WIIU_GHLIVE_DONGLE 0x074b 1324 - #define USB_DEVICE_ID_SONY_PS3_GUITAR_DONGLE 0x0100 1304 + #define USB_DEVICE_ID_SONY_PS3WIIU_GHLIVE 0x074b 1305 + #define USB_DEVICE_ID_SONY_PS3_GH_GUITAR 0x0100 1306 + #define USB_DEVICE_ID_SONY_PS3_GH_DRUMS 0x0120 1307 + #define USB_DEVICE_ID_SONY_PS3_DJH_TURNTABLE 0x0140 1308 + #define USB_DEVICE_ID_SONY_PS3_RB_GUITAR 0x0200 1309 + #define USB_DEVICE_ID_SONY_PS3_RB_DRUMS 0x0210 1310 + #define USB_DEVICE_ID_SONY_PS3_RB3_MPA_DRUMS_MODE 0x0218 1311 + #define USB_DEVICE_ID_SONY_PS3_RB3_MUSTANG_GUITAR 0x2430 1312 + #define USB_DEVICE_ID_SONY_PS3_RB3_MPA_MUSTANG_MODE 0x2438 1313 + #define USB_DEVICE_ID_SONY_PS3_RB3_MPA_SQUIER_MODE 0x2538 1314 + #define USB_DEVICE_ID_SONY_PS3_RB3_KEYBOARD 0x2330 1315 + #define USB_DEVICE_ID_SONY_PS3_RB3_MPA_KEYBOARD_MODE 0x2338 1325 1316 1326 1317 #define USB_VENDOR_ID_SINO_LITE 0x1345 1327 1318 #define USB_DEVICE_ID_SINO_LITE_CONTROLLER 0x3008 ··· 1615 1586 1616 1587 #define USB_VENDOR_ID_JIELI_SDK_DEFAULT 0x4c4a 1617 1588 #define USB_DEVICE_ID_JIELI_SDK_4155 0x4155 1589 + 1590 + #define USB_VENDOR_ID_HUAWEI 0x12d1 1591 + #define USB_DEVICE_ID_HUAWEI_CD30KBD 0x109b 1618 1592 1619 1593 #endif
+22 -17
drivers/hid/hid-input-test.c
··· 9 9 10 10 static void hid_test_input_update_battery_charge_status(struct kunit *test) 11 11 { 12 - struct hid_device *dev; 12 + struct hid_battery *bat; 13 13 bool handled; 14 14 15 - dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL); 16 - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); 15 + bat = kunit_kzalloc(test, sizeof(*bat), GFP_KERNEL); 16 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, bat); 17 17 18 - handled = hidinput_update_battery_charge_status(dev, HID_DG_HEIGHT, 0); 18 + handled = hidinput_update_battery_charge_status(bat, HID_DG_HEIGHT, 0); 19 19 KUNIT_EXPECT_FALSE(test, handled); 20 - KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_UNKNOWN); 20 + KUNIT_EXPECT_EQ(test, bat->charge_status, POWER_SUPPLY_STATUS_UNKNOWN); 21 21 22 - handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 0); 22 + handled = hidinput_update_battery_charge_status(bat, HID_BAT_CHARGING, 0); 23 23 KUNIT_EXPECT_TRUE(test, handled); 24 - KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_DISCHARGING); 24 + KUNIT_EXPECT_EQ(test, bat->charge_status, POWER_SUPPLY_STATUS_DISCHARGING); 25 25 26 - handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 1); 26 + handled = hidinput_update_battery_charge_status(bat, HID_BAT_CHARGING, 1); 27 27 KUNIT_EXPECT_TRUE(test, handled); 28 - KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_CHARGING); 28 + KUNIT_EXPECT_EQ(test, bat->charge_status, POWER_SUPPLY_STATUS_CHARGING); 29 29 } 30 30 31 31 static void hid_test_input_get_battery_property(struct kunit *test) 32 32 { 33 33 struct power_supply *psy; 34 + struct hid_battery *bat; 34 35 struct hid_device *dev; 35 36 union power_supply_propval val; 36 37 int ret; 37 38 38 39 dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL); 39 40 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); 40 - dev->battery_avoid_query = true; 41 + 42 + bat = kunit_kzalloc(test, sizeof(*bat), GFP_KERNEL); 43 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, bat); 44 + bat->dev = dev; 45 + bat->avoid_query = true; 41 46 42 47 psy = kunit_kzalloc(test, sizeof(*psy), GFP_KERNEL); 43 48 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, psy); 44 - psy->drv_data = dev; 49 + psy->drv_data = bat; 45 50 46 - dev->battery_status = HID_BATTERY_UNKNOWN; 47 - dev->battery_charge_status = POWER_SUPPLY_STATUS_CHARGING; 51 + bat->status = HID_BATTERY_UNKNOWN; 52 + bat->charge_status = POWER_SUPPLY_STATUS_CHARGING; 48 53 ret = hidinput_get_battery_property(psy, POWER_SUPPLY_PROP_STATUS, &val); 49 54 KUNIT_EXPECT_EQ(test, ret, 0); 50 55 KUNIT_EXPECT_EQ(test, val.intval, POWER_SUPPLY_STATUS_UNKNOWN); 51 56 52 - dev->battery_status = HID_BATTERY_REPORTED; 53 - dev->battery_charge_status = POWER_SUPPLY_STATUS_CHARGING; 57 + bat->status = HID_BATTERY_REPORTED; 58 + bat->charge_status = POWER_SUPPLY_STATUS_CHARGING; 54 59 ret = hidinput_get_battery_property(psy, POWER_SUPPLY_PROP_STATUS, &val); 55 60 KUNIT_EXPECT_EQ(test, ret, 0); 56 61 KUNIT_EXPECT_EQ(test, val.intval, POWER_SUPPLY_STATUS_CHARGING); 57 62 58 - dev->battery_status = HID_BATTERY_REPORTED; 59 - dev->battery_charge_status = POWER_SUPPLY_STATUS_DISCHARGING; 63 + bat->status = HID_BATTERY_REPORTED; 64 + bat->charge_status = POWER_SUPPLY_STATUS_DISCHARGING; 60 65 ret = hidinput_get_battery_property(psy, POWER_SUPPLY_PROP_STATUS, &val); 61 66 KUNIT_EXPECT_EQ(test, ret, 0); 62 67 KUNIT_EXPECT_EQ(test, val.intval, POWER_SUPPLY_STATUS_DISCHARGING);
+107 -103
drivers/hid/hid-input.c
··· 416 416 return quirks; 417 417 } 418 418 419 - static int hidinput_scale_battery_capacity(struct hid_device *dev, 419 + static int hidinput_scale_battery_capacity(struct hid_battery *bat, 420 420 int value) 421 421 { 422 - if (dev->battery_min < dev->battery_max && 423 - value >= dev->battery_min && value <= dev->battery_max) 424 - value = ((value - dev->battery_min) * 100) / 425 - (dev->battery_max - dev->battery_min); 422 + if (bat->min < bat->max && 423 + value >= bat->min && value <= bat->max) 424 + value = ((value - bat->min) * 100) / 425 + (bat->max - bat->min); 426 426 427 427 return value; 428 428 } 429 429 430 - static int hidinput_query_battery_capacity(struct hid_device *dev) 430 + static int hidinput_query_battery_capacity(struct hid_battery *bat) 431 431 { 432 - u8 *buf; 433 432 int ret; 434 433 435 - buf = kmalloc(4, GFP_KERNEL); 434 + u8 *buf __free(kfree) = kmalloc(4, GFP_KERNEL); 436 435 if (!buf) 437 436 return -ENOMEM; 438 437 439 - ret = hid_hw_raw_request(dev, dev->battery_report_id, buf, 4, 440 - dev->battery_report_type, HID_REQ_GET_REPORT); 441 - if (ret < 2) { 442 - kfree(buf); 438 + ret = hid_hw_raw_request(bat->dev, bat->report_id, buf, 4, 439 + bat->report_type, HID_REQ_GET_REPORT); 440 + if (ret < 2) 443 441 return -ENODATA; 444 - } 445 442 446 - ret = hidinput_scale_battery_capacity(dev, buf[1]); 447 - kfree(buf); 448 - return ret; 443 + return hidinput_scale_battery_capacity(bat, buf[1]); 449 444 } 450 445 451 446 static int hidinput_get_battery_property(struct power_supply *psy, 452 447 enum power_supply_property prop, 453 448 union power_supply_propval *val) 454 449 { 455 - struct hid_device *dev = power_supply_get_drvdata(psy); 450 + struct hid_battery *bat = power_supply_get_drvdata(psy); 451 + struct hid_device *dev = bat->dev; 456 452 int value; 457 453 int ret = 0; 458 454 ··· 458 462 break; 459 463 460 464 case POWER_SUPPLY_PROP_PRESENT: 461 - val->intval = dev->battery_present; 465 + val->intval = bat->present; 462 466 break; 463 467 464 468 case POWER_SUPPLY_PROP_CAPACITY: 465 - if (dev->battery_status != HID_BATTERY_REPORTED && 466 - !dev->battery_avoid_query) { 467 - value = hidinput_query_battery_capacity(dev); 469 + if (bat->status != HID_BATTERY_REPORTED && 470 + !bat->avoid_query) { 471 + value = hidinput_query_battery_capacity(bat); 468 472 if (value < 0) 469 473 return value; 470 474 } else { 471 - value = dev->battery_capacity; 475 + value = bat->capacity; 472 476 } 473 477 474 478 val->intval = value; ··· 479 483 break; 480 484 481 485 case POWER_SUPPLY_PROP_STATUS: 482 - if (dev->battery_status != HID_BATTERY_REPORTED && 483 - !dev->battery_avoid_query) { 484 - value = hidinput_query_battery_capacity(dev); 486 + if (bat->status != HID_BATTERY_REPORTED && 487 + !bat->avoid_query) { 488 + value = hidinput_query_battery_capacity(bat); 485 489 if (value < 0) 486 490 return value; 487 491 488 - dev->battery_capacity = value; 489 - dev->battery_status = HID_BATTERY_QUERIED; 492 + bat->capacity = value; 493 + bat->status = HID_BATTERY_QUERIED; 490 494 } 491 495 492 - if (dev->battery_status == HID_BATTERY_UNKNOWN) 496 + if (bat->status == HID_BATTERY_UNKNOWN) 493 497 val->intval = POWER_SUPPLY_STATUS_UNKNOWN; 494 498 else 495 - val->intval = dev->battery_charge_status; 499 + val->intval = bat->charge_status; 496 500 break; 497 501 498 502 case POWER_SUPPLY_PROP_SCOPE: ··· 507 511 return ret; 508 512 } 509 513 514 + static struct hid_battery *hidinput_find_battery(struct hid_device *dev, 515 + int report_id) 516 + { 517 + struct hid_battery *bat; 518 + 519 + list_for_each_entry(bat, &dev->batteries, list) { 520 + if (bat->report_id == report_id) 521 + return bat; 522 + } 523 + return NULL; 524 + } 525 + 510 526 static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type, 511 527 struct hid_field *field, bool is_percentage) 512 528 { 529 + struct hid_battery *bat; 513 530 struct power_supply_desc *psy_desc; 514 - struct power_supply_config psy_cfg = { .drv_data = dev, }; 531 + struct power_supply_config psy_cfg = { 0 }; 515 532 unsigned quirks; 516 533 s32 min, max; 517 534 int error; 518 535 519 - if (dev->battery) 520 - return 0; /* already initialized? */ 536 + /* Check if battery for this report ID already exists */ 537 + if (hidinput_find_battery(dev, field->report->id)) 538 + return 0; 521 539 522 540 quirks = find_battery_quirk(dev); 523 541 524 - hid_dbg(dev, "device %x:%x:%x %d quirks %d\n", 525 - dev->bus, dev->vendor, dev->product, dev->version, quirks); 542 + hid_dbg(dev, "device %x:%x:%x %d quirks %d report_id %d\n", 543 + dev->bus, dev->vendor, dev->product, dev->version, quirks, 544 + field->report->id); 526 545 527 546 if (quirks & HID_BATTERY_QUIRK_IGNORE) 528 547 return 0; 529 548 530 - psy_desc = kzalloc_obj(*psy_desc); 531 - if (!psy_desc) 549 + bat = devm_kzalloc(&dev->dev, sizeof(*bat), GFP_KERNEL); 550 + if (!bat) 532 551 return -ENOMEM; 533 552 534 - psy_desc->name = kasprintf(GFP_KERNEL, "hid-%s-battery", 535 - strlen(dev->uniq) ? 536 - dev->uniq : dev_name(&dev->dev)); 553 + psy_desc = devm_kzalloc(&dev->dev, sizeof(*psy_desc), GFP_KERNEL); 554 + if (!psy_desc) { 555 + error = -ENOMEM; 556 + goto err_free_bat; 557 + } 558 + 559 + psy_desc->name = devm_kasprintf(&dev->dev, GFP_KERNEL, 560 + "hid-%s-battery-%d", 561 + strlen(dev->uniq) ? 562 + dev->uniq : dev_name(&dev->dev), 563 + field->report->id); 537 564 if (!psy_desc->name) { 538 565 error = -ENOMEM; 539 - goto err_free_mem; 566 + goto err_free_desc; 540 567 } 541 568 542 569 psy_desc->type = POWER_SUPPLY_TYPE_BATTERY; ··· 579 560 if (quirks & HID_BATTERY_QUIRK_FEATURE) 580 561 report_type = HID_FEATURE_REPORT; 581 562 582 - dev->battery_min = min; 583 - dev->battery_max = max; 584 - dev->battery_report_type = report_type; 585 - dev->battery_report_id = field->report->id; 586 - dev->battery_charge_status = POWER_SUPPLY_STATUS_DISCHARGING; 563 + bat->dev = dev; 564 + bat->min = min; 565 + bat->max = max; 566 + bat->report_type = report_type; 567 + bat->report_id = field->report->id; 568 + bat->charge_status = POWER_SUPPLY_STATUS_DISCHARGING; 569 + bat->status = HID_BATTERY_UNKNOWN; 587 570 588 571 /* 589 572 * Stylus is normally not connected to the device and thus we 590 573 * can't query the device and get meaningful battery strength. 591 574 * We have to wait for the device to report it on its own. 592 575 */ 593 - dev->battery_avoid_query = report_type == HID_INPUT_REPORT && 594 - field->physical == HID_DG_STYLUS; 576 + bat->avoid_query = report_type == HID_INPUT_REPORT && 577 + field->physical == HID_DG_STYLUS; 595 578 596 579 if (quirks & HID_BATTERY_QUIRK_AVOID_QUERY) 597 - dev->battery_avoid_query = true; 580 + bat->avoid_query = true; 598 581 599 - dev->battery_present = (quirks & HID_BATTERY_QUIRK_DYNAMIC) ? false : true; 582 + bat->present = (quirks & HID_BATTERY_QUIRK_DYNAMIC) ? false : true; 600 583 601 - dev->battery = power_supply_register(&dev->dev, psy_desc, &psy_cfg); 602 - if (IS_ERR(dev->battery)) { 603 - error = PTR_ERR(dev->battery); 584 + psy_cfg.drv_data = bat; 585 + bat->ps = devm_power_supply_register(&dev->dev, psy_desc, &psy_cfg); 586 + if (IS_ERR(bat->ps)) { 587 + error = PTR_ERR(bat->ps); 604 588 hid_warn(dev, "can't register power supply: %d\n", error); 605 589 goto err_free_name; 606 590 } 607 591 608 - power_supply_powers(dev->battery, &dev->dev); 592 + power_supply_powers(bat->ps, &dev->dev); 593 + list_add_tail(&bat->list, &dev->batteries); 609 594 return 0; 610 595 611 596 err_free_name: 612 - kfree(psy_desc->name); 613 - err_free_mem: 614 - kfree(psy_desc); 615 - dev->battery = NULL; 597 + devm_kfree(&dev->dev, psy_desc->name); 598 + err_free_desc: 599 + devm_kfree(&dev->dev, psy_desc); 600 + err_free_bat: 601 + devm_kfree(&dev->dev, bat); 616 602 return error; 617 603 } 618 604 619 - static void hidinput_cleanup_battery(struct hid_device *dev) 620 - { 621 - const struct power_supply_desc *psy_desc; 622 - 623 - if (!dev->battery) 624 - return; 625 - 626 - psy_desc = dev->battery->desc; 627 - power_supply_unregister(dev->battery); 628 - kfree(psy_desc->name); 629 - kfree(psy_desc); 630 - dev->battery = NULL; 631 - } 632 - 633 - static bool hidinput_update_battery_charge_status(struct hid_device *dev, 605 + static bool hidinput_update_battery_charge_status(struct hid_battery *bat, 634 606 unsigned int usage, int value) 635 607 { 636 608 switch (usage) { 637 609 case HID_BAT_CHARGING: 638 - dev->battery_charge_status = value ? 639 - POWER_SUPPLY_STATUS_CHARGING : 640 - POWER_SUPPLY_STATUS_DISCHARGING; 610 + bat->charge_status = value ? 611 + POWER_SUPPLY_STATUS_CHARGING : 612 + POWER_SUPPLY_STATUS_DISCHARGING; 641 613 return true; 642 614 } 643 615 644 616 return false; 645 617 } 646 618 647 - static void hidinput_update_battery(struct hid_device *dev, unsigned int usage, 648 - int value) 619 + static void hidinput_update_battery(struct hid_device *dev, int report_id, 620 + unsigned int usage, int value) 649 621 { 622 + struct hid_battery *bat; 650 623 int capacity; 651 624 652 - if (!dev->battery) 625 + bat = hidinput_find_battery(dev, report_id); 626 + if (!bat) 653 627 return; 654 628 655 - if (hidinput_update_battery_charge_status(dev, usage, value)) { 656 - dev->battery_present = true; 657 - power_supply_changed(dev->battery); 629 + if (hidinput_update_battery_charge_status(bat, usage, value)) { 630 + bat->present = true; 631 + power_supply_changed(bat->ps); 658 632 return; 659 633 } 660 634 661 635 if ((usage & HID_USAGE_PAGE) == HID_UP_DIGITIZER && value == 0) 662 636 return; 663 637 664 - if (value < dev->battery_min || value > dev->battery_max) 638 + if (value < bat->min || value > bat->max) 665 639 return; 666 640 667 - capacity = hidinput_scale_battery_capacity(dev, value); 641 + capacity = hidinput_scale_battery_capacity(bat, value); 668 642 669 - if (dev->battery_status != HID_BATTERY_REPORTED || 670 - capacity != dev->battery_capacity || 671 - ktime_after(ktime_get_coarse(), dev->battery_ratelimit_time)) { 672 - dev->battery_present = true; 673 - dev->battery_capacity = capacity; 674 - dev->battery_status = HID_BATTERY_REPORTED; 675 - dev->battery_ratelimit_time = 643 + if (bat->status != HID_BATTERY_REPORTED || 644 + capacity != bat->capacity || 645 + ktime_after(ktime_get_coarse(), bat->ratelimit_time)) { 646 + bat->present = true; 647 + bat->capacity = capacity; 648 + bat->status = HID_BATTERY_REPORTED; 649 + bat->ratelimit_time = 676 650 ktime_add_ms(ktime_get_coarse(), 30 * 1000); 677 - power_supply_changed(dev->battery); 651 + power_supply_changed(bat->ps); 678 652 } 679 653 } 680 654 #else /* !CONFIG_HID_BATTERY_STRENGTH */ ··· 677 665 return 0; 678 666 } 679 667 680 - static void hidinput_cleanup_battery(struct hid_device *dev) 681 - { 682 - } 683 - 684 - static void hidinput_update_battery(struct hid_device *dev, unsigned int usage, 685 - int value) 668 + static void hidinput_update_battery(struct hid_device *dev, int report_id, 669 + unsigned int usage, int value) 686 670 { 687 671 } 688 672 #endif /* CONFIG_HID_BATTERY_STRENGTH */ ··· 1565 1557 return; 1566 1558 1567 1559 if (usage->type == EV_PWR) { 1568 - hidinput_update_battery(hid, usage->hid, value); 1560 + hidinput_update_battery(hid, report->id, usage->hid, value); 1569 1561 return; 1570 1562 } 1571 1563 ··· 1847 1839 struct hid_report *report; 1848 1840 int ret; 1849 1841 u32 len; 1850 - __u8 *buf; 1851 1842 1852 1843 field = hidinput_get_led_field(hid); 1853 1844 if (!field) ··· 1873 1866 1874 1867 /* fall back to generic raw-output-report */ 1875 1868 len = hid_report_len(report); 1876 - buf = hid_alloc_report_buf(report, GFP_KERNEL); 1869 + u8 *buf __free(kfree) = hid_alloc_report_buf(report, GFP_KERNEL); 1877 1870 if (!buf) 1878 1871 return; 1879 1872 ··· 1883 1876 if (ret == -ENOSYS) 1884 1877 hid_hw_raw_request(hid, report->id, buf, len, HID_OUTPUT_REPORT, 1885 1878 HID_REQ_SET_REPORT); 1886 - kfree(buf); 1887 1879 } 1888 1880 1889 1881 static int hidinput_input_event(struct input_dev *dev, unsigned int type, ··· 2408 2402 void hidinput_disconnect(struct hid_device *hid) 2409 2403 { 2410 2404 struct hid_input *hidinput, *next; 2411 - 2412 - hidinput_cleanup_battery(hid); 2413 2405 2414 2406 list_for_each_entry_safe(hidinput, next, &hid->inputs, list) { 2415 2407 list_del(&hidinput->list);
+1504
drivers/hid/hid-lenovo-go-s.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * HID driver for Lenovo Legion Go S devices. 4 + * 5 + * Copyright (c) 2026 Derek J. Clark <derekjohn.clark@gmail.com> 6 + * Copyright (c) 2026 Valve Corporation 7 + */ 8 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 9 + 10 + #include <linux/array_size.h> 11 + #include <linux/cleanup.h> 12 + #include <linux/completion.h> 13 + #include <linux/delay.h> 14 + #include <linux/dev_printk.h> 15 + #include <linux/device.h> 16 + #include <linux/hid.h> 17 + #include <linux/jiffies.h> 18 + #include <linux/kstrtox.h> 19 + #include <linux/led-class-multicolor.h> 20 + #include <linux/mutex.h> 21 + #include <linux/printk.h> 22 + #include <linux/string.h> 23 + #include <linux/sysfs.h> 24 + #include <linux/types.h> 25 + #include <linux/unaligned.h> 26 + #include <linux/usb.h> 27 + #include <linux/workqueue.h> 28 + #include <linux/workqueue_types.h> 29 + 30 + #include "hid-ids.h" 31 + 32 + #define GO_S_CFG_INTF_IN 0x84 33 + #define GO_S_PACKET_SIZE 64 34 + 35 + static struct hid_gos_cfg { 36 + struct delayed_work gos_cfg_setup; 37 + struct completion send_cmd_complete; 38 + struct led_classdev *led_cdev; 39 + struct hid_device *hdev; 40 + struct mutex cfg_mutex; /*ensure single synchronous output report*/ 41 + u8 gp_auto_sleep_time; 42 + u8 gp_dpad_mode; 43 + u8 gp_mode; 44 + u8 gp_poll_rate; 45 + u8 imu_bypass_en; 46 + u8 imu_manufacturer; 47 + u8 imu_sensor_en; 48 + u8 mcu_id[12]; 49 + u8 mouse_step; 50 + u8 os_mode; 51 + u8 rgb_effect; 52 + u8 rgb_en; 53 + u8 rgb_mode; 54 + u8 rgb_profile; 55 + u8 rgb_speed; 56 + u8 tp_en; 57 + u8 tp_linux_mode; 58 + u8 tp_windows_mode; 59 + u8 tp_version; 60 + u8 tp_manufacturer; 61 + } drvdata; 62 + 63 + struct gos_cfg_attr { 64 + u8 index; 65 + }; 66 + 67 + struct command_report { 68 + u8 cmd; 69 + u8 sub_cmd; 70 + u8 data[63]; 71 + } __packed; 72 + 73 + struct version_report { 74 + u8 cmd; 75 + u32 version; 76 + u8 reserved[59]; 77 + } __packed; 78 + 79 + enum mcu_command_index { 80 + GET_VERSION = 0x01, 81 + GET_MCU_ID, 82 + GET_GAMEPAD_CFG, 83 + SET_GAMEPAD_CFG, 84 + GET_TP_PARAM, 85 + SET_TP_PARAM, 86 + GET_RGB_CFG = 0x0f, 87 + SET_RGB_CFG, 88 + GET_PL_TEST = 0xdf, 89 + }; 90 + 91 + enum feature_enabled_index { 92 + FEATURE_DISABLED, 93 + FEATURE_ENABLED, 94 + }; 95 + 96 + static const char *const feature_enabled_text[] = { 97 + [FEATURE_DISABLED] = "false", 98 + [FEATURE_ENABLED] = "true", 99 + }; 100 + 101 + enum feature_status_index { 102 + FEATURE_NONE = 0x00, 103 + FEATURE_GAMEPAD_MODE = 0x01, 104 + FEATURE_AUTO_SLEEP_TIME = 0x04, 105 + FEATURE_IMU_BYPASS, 106 + FEATURE_RGB_ENABLE, 107 + FEATURE_IMU_ENABLE, 108 + FEATURE_TOUCHPAD_ENABLE, 109 + FEATURE_OS_MODE = 0x0A, 110 + FEATURE_POLL_RATE = 0x10, 111 + FEATURE_DPAD_MODE, 112 + FEATURE_MOUSE_WHEEL_STEP, 113 + }; 114 + 115 + enum gamepad_mode_index { 116 + XINPUT, 117 + DINPUT, 118 + }; 119 + 120 + static const char *const gamepad_mode_text[] = { 121 + [XINPUT] = "xinput", 122 + [DINPUT] = "dinput", 123 + }; 124 + 125 + enum os_type_index { 126 + WINDOWS, 127 + LINUX, 128 + }; 129 + 130 + static const char *const os_type_text[] = { 131 + [WINDOWS] = "windows", 132 + [LINUX] = "linux", 133 + }; 134 + 135 + enum poll_rate_index { 136 + HZ125, 137 + HZ250, 138 + HZ500, 139 + HZ1000, 140 + }; 141 + 142 + static const char *const poll_rate_text[] = { 143 + [HZ125] = "125", 144 + [HZ250] = "250", 145 + [HZ500] = "500", 146 + [HZ1000] = "1000", 147 + }; 148 + 149 + enum dpad_mode_index { 150 + DIR8, 151 + DIR4, 152 + }; 153 + 154 + static const char *const dpad_mode_text[] = { 155 + [DIR8] = "8-way", 156 + [DIR4] = "4-way", 157 + }; 158 + 159 + enum touchpad_mode_index { 160 + TP_REL, 161 + TP_ABS, 162 + }; 163 + 164 + static const char *const touchpad_mode_text[] = { 165 + [TP_REL] = "relative", 166 + [TP_ABS] = "absolute", 167 + }; 168 + 169 + enum touchpad_config_index { 170 + CFG_WINDOWS_MODE = 0x03, 171 + CFG_LINUX_MODE, 172 + 173 + }; 174 + 175 + enum rgb_mode_index { 176 + RGB_MODE_DYNAMIC, 177 + RGB_MODE_CUSTOM, 178 + }; 179 + 180 + static const char *const rgb_mode_text[] = { 181 + [RGB_MODE_DYNAMIC] = "dynamic", 182 + [RGB_MODE_CUSTOM] = "custom", 183 + }; 184 + 185 + enum rgb_effect_index { 186 + RGB_EFFECT_MONO, 187 + RGB_EFFECT_BREATHE, 188 + RGB_EFFECT_CHROMA, 189 + RGB_EFFECT_RAINBOW, 190 + }; 191 + 192 + static const char *const rgb_effect_text[] = { 193 + [RGB_EFFECT_MONO] = "monocolor", 194 + [RGB_EFFECT_BREATHE] = "breathe", 195 + [RGB_EFFECT_CHROMA] = "chroma", 196 + [RGB_EFFECT_RAINBOW] = "rainbow", 197 + }; 198 + 199 + enum rgb_config_index { 200 + LIGHT_MODE_SEL = 0x01, 201 + LIGHT_PROFILE_SEL, 202 + USR_LIGHT_PROFILE_1, 203 + USR_LIGHT_PROFILE_2, 204 + USR_LIGHT_PROFILE_3, 205 + }; 206 + 207 + enum test_command_index { 208 + TEST_TP_MFR = 0x02, 209 + TEST_IMU_MFR, 210 + TEST_TP_VER, 211 + }; 212 + 213 + enum tp_mfr_index { 214 + TP_NONE, 215 + TP_BETTERLIFE, 216 + TP_SIPO, 217 + }; 218 + 219 + static const char *const touchpad_manufacturer_text[] = { 220 + [TP_NONE] = "none", 221 + [TP_BETTERLIFE] = "BetterLife", 222 + [TP_SIPO] = "SIPO", 223 + }; 224 + 225 + enum imu_mfr_index { 226 + IMU_NONE, 227 + IMU_BOSCH, 228 + IMU_ST, 229 + }; 230 + 231 + static const char *const imu_manufacturer_text[] = { 232 + [IMU_NONE] = "none", 233 + [IMU_BOSCH] = "Bosch", 234 + [IMU_ST] = "ST", 235 + }; 236 + 237 + static int hid_gos_version_event(u8 *data) 238 + { 239 + struct version_report *ver_rep = (struct version_report *)data; 240 + 241 + drvdata.hdev->firmware_version = get_unaligned_le32(&ver_rep->version); 242 + return 0; 243 + } 244 + 245 + static int hid_gos_mcu_id_event(struct command_report *cmd_rep) 246 + { 247 + drvdata.mcu_id[0] = cmd_rep->sub_cmd; 248 + memcpy(&drvdata.mcu_id[1], cmd_rep->data, 11); 249 + 250 + return 0; 251 + } 252 + 253 + static int hid_gos_gamepad_cfg_event(struct command_report *cmd_rep) 254 + { 255 + int ret = 0; 256 + 257 + switch (cmd_rep->sub_cmd) { 258 + case FEATURE_GAMEPAD_MODE: 259 + drvdata.gp_mode = cmd_rep->data[0]; 260 + break; 261 + case FEATURE_AUTO_SLEEP_TIME: 262 + drvdata.gp_auto_sleep_time = cmd_rep->data[0]; 263 + break; 264 + case FEATURE_IMU_BYPASS: 265 + drvdata.imu_bypass_en = cmd_rep->data[0]; 266 + break; 267 + case FEATURE_RGB_ENABLE: 268 + drvdata.rgb_en = cmd_rep->data[0]; 269 + break; 270 + case FEATURE_IMU_ENABLE: 271 + drvdata.imu_sensor_en = cmd_rep->data[0]; 272 + break; 273 + case FEATURE_TOUCHPAD_ENABLE: 274 + drvdata.tp_en = cmd_rep->data[0]; 275 + break; 276 + case FEATURE_OS_MODE: 277 + drvdata.os_mode = cmd_rep->data[0]; 278 + break; 279 + case FEATURE_POLL_RATE: 280 + drvdata.gp_poll_rate = cmd_rep->data[0]; 281 + break; 282 + case FEATURE_DPAD_MODE: 283 + drvdata.gp_dpad_mode = cmd_rep->data[0]; 284 + break; 285 + case FEATURE_MOUSE_WHEEL_STEP: 286 + drvdata.mouse_step = cmd_rep->data[0]; 287 + break; 288 + default: 289 + ret = -EINVAL; 290 + break; 291 + } 292 + 293 + return ret; 294 + } 295 + 296 + static int hid_gos_touchpad_event(struct command_report *cmd_rep) 297 + { 298 + int ret = 0; 299 + 300 + switch (cmd_rep->sub_cmd) { 301 + case CFG_LINUX_MODE: 302 + drvdata.tp_linux_mode = cmd_rep->data[0]; 303 + break; 304 + case CFG_WINDOWS_MODE: 305 + drvdata.tp_windows_mode = cmd_rep->data[0]; 306 + break; 307 + default: 308 + ret = -EINVAL; 309 + break; 310 + } 311 + 312 + return ret; 313 + } 314 + 315 + static int hid_gos_pl_test_event(struct command_report *cmd_rep) 316 + { 317 + int ret = 0; 318 + 319 + switch (cmd_rep->sub_cmd) { 320 + case TEST_TP_MFR: 321 + drvdata.tp_manufacturer = cmd_rep->data[0]; 322 + ret = 0; 323 + break; 324 + case TEST_IMU_MFR: 325 + drvdata.imu_manufacturer = cmd_rep->data[0]; 326 + ret = 0; 327 + break; 328 + case TEST_TP_VER: 329 + drvdata.tp_version = cmd_rep->data[0]; 330 + ret = 0; 331 + break; 332 + default: 333 + ret = -EINVAL; 334 + break; 335 + } 336 + return ret; 337 + } 338 + 339 + static int hid_gos_light_event(struct command_report *cmd_rep) 340 + { 341 + struct led_classdev_mc *mc_cdev; 342 + int ret = 0; 343 + 344 + switch (cmd_rep->sub_cmd) { 345 + case LIGHT_MODE_SEL: 346 + drvdata.rgb_mode = cmd_rep->data[0]; 347 + ret = 0; 348 + break; 349 + case LIGHT_PROFILE_SEL: 350 + drvdata.rgb_profile = cmd_rep->data[0]; 351 + ret = 0; 352 + break; 353 + case USR_LIGHT_PROFILE_1: 354 + case USR_LIGHT_PROFILE_2: 355 + case USR_LIGHT_PROFILE_3: 356 + mc_cdev = lcdev_to_mccdev(drvdata.led_cdev); 357 + drvdata.rgb_effect = cmd_rep->data[0]; 358 + mc_cdev->subled_info[0].intensity = cmd_rep->data[1]; 359 + mc_cdev->subled_info[1].intensity = cmd_rep->data[2]; 360 + mc_cdev->subled_info[2].intensity = cmd_rep->data[3]; 361 + drvdata.led_cdev->brightness = cmd_rep->data[4]; 362 + drvdata.rgb_speed = cmd_rep->data[5]; 363 + ret = 0; 364 + break; 365 + default: 366 + ret = -EINVAL; 367 + break; 368 + } 369 + return ret; 370 + } 371 + 372 + static int hid_gos_set_event_return(struct command_report *cmd_rep) 373 + { 374 + if (cmd_rep->data[0] != 0) 375 + return -EIO; 376 + 377 + return 0; 378 + } 379 + 380 + static int get_endpoint_address(struct hid_device *hdev) 381 + { 382 + struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 383 + struct usb_host_endpoint *ep; 384 + 385 + if (intf) { 386 + ep = intf->cur_altsetting->endpoint; 387 + if (ep) 388 + return ep->desc.bEndpointAddress; 389 + } 390 + 391 + return -ENODEV; 392 + } 393 + 394 + static int hid_gos_raw_event(struct hid_device *hdev, struct hid_report *report, 395 + u8 *data, int size) 396 + { 397 + struct command_report *cmd_rep; 398 + int ep, ret; 399 + 400 + ep = get_endpoint_address(hdev); 401 + if (ep != GO_S_CFG_INTF_IN) 402 + return 0; 403 + 404 + if (size != GO_S_PACKET_SIZE) 405 + return -EINVAL; 406 + 407 + cmd_rep = (struct command_report *)data; 408 + 409 + switch (cmd_rep->cmd) { 410 + case GET_VERSION: 411 + ret = hid_gos_version_event(data); 412 + break; 413 + case GET_MCU_ID: 414 + ret = hid_gos_mcu_id_event(cmd_rep); 415 + break; 416 + case GET_GAMEPAD_CFG: 417 + ret = hid_gos_gamepad_cfg_event(cmd_rep); 418 + break; 419 + case GET_TP_PARAM: 420 + ret = hid_gos_touchpad_event(cmd_rep); 421 + break; 422 + case GET_PL_TEST: 423 + ret = hid_gos_pl_test_event(cmd_rep); 424 + break; 425 + case GET_RGB_CFG: 426 + ret = hid_gos_light_event(cmd_rep); 427 + break; 428 + case SET_GAMEPAD_CFG: 429 + case SET_RGB_CFG: 430 + case SET_TP_PARAM: 431 + ret = hid_gos_set_event_return(cmd_rep); 432 + break; 433 + default: 434 + ret = -EINVAL; 435 + break; 436 + } 437 + dev_dbg(&hdev->dev, "Rx data as raw input report: [%*ph]\n", 438 + GO_S_PACKET_SIZE, data); 439 + 440 + complete(&drvdata.send_cmd_complete); 441 + return ret; 442 + } 443 + 444 + static int mcu_property_out(struct hid_device *hdev, u8 command, u8 index, 445 + u8 *data, size_t len) 446 + { 447 + unsigned char *dmabuf __free(kfree) = NULL; 448 + u8 header[] = { command, index }; 449 + size_t header_size = ARRAY_SIZE(header); 450 + int timeout, ret; 451 + 452 + if (header_size + len > GO_S_PACKET_SIZE) 453 + return -EINVAL; 454 + 455 + guard(mutex)(&drvdata.cfg_mutex); 456 + /* We can't use a devm_alloc reusable buffer without side effects during suspend */ 457 + dmabuf = kzalloc(GO_S_PACKET_SIZE, GFP_KERNEL); 458 + if (!dmabuf) 459 + return -ENOMEM; 460 + 461 + memcpy(dmabuf, header, header_size); 462 + memcpy(dmabuf + header_size, data, len); 463 + 464 + dev_dbg(&hdev->dev, "Send data as raw output report: [%*ph]\n", 465 + GO_S_PACKET_SIZE, dmabuf); 466 + 467 + ret = hid_hw_output_report(hdev, dmabuf, GO_S_PACKET_SIZE); 468 + if (ret < 0) 469 + return ret; 470 + 471 + ret = ret == GO_S_PACKET_SIZE ? 0 : -EINVAL; 472 + if (ret) 473 + return ret; 474 + 475 + /* PL_TEST commands can take longer because they go out to another device */ 476 + timeout = (command == GET_PL_TEST) ? 200 : 5; 477 + ret = wait_for_completion_interruptible_timeout(&drvdata.send_cmd_complete, 478 + msecs_to_jiffies(timeout)); 479 + 480 + if (ret == 0) /* timeout occurred */ 481 + ret = -EBUSY; 482 + 483 + reinit_completion(&drvdata.send_cmd_complete); 484 + return 0; 485 + } 486 + 487 + static ssize_t gamepad_property_store(struct device *dev, 488 + struct device_attribute *attr, 489 + const char *buf, size_t count, 490 + enum feature_status_index index) 491 + { 492 + size_t size = 1; 493 + u8 val = 0; 494 + int ret; 495 + 496 + switch (index) { 497 + case FEATURE_GAMEPAD_MODE: 498 + ret = sysfs_match_string(gamepad_mode_text, buf); 499 + if (ret < 0) 500 + return ret; 501 + val = ret; 502 + break; 503 + case FEATURE_AUTO_SLEEP_TIME: 504 + ret = kstrtou8(buf, 10, &val); 505 + if (ret) 506 + return ret; 507 + break; 508 + case FEATURE_IMU_ENABLE: 509 + ret = sysfs_match_string(feature_enabled_text, buf); 510 + if (ret < 0) 511 + return ret; 512 + val = ret; 513 + break; 514 + case FEATURE_IMU_BYPASS: 515 + ret = sysfs_match_string(feature_enabled_text, buf); 516 + if (ret < 0) 517 + return ret; 518 + val = ret; 519 + break; 520 + case FEATURE_RGB_ENABLE: 521 + ret = sysfs_match_string(feature_enabled_text, buf); 522 + if (ret < 0) 523 + return ret; 524 + val = ret; 525 + break; 526 + case FEATURE_TOUCHPAD_ENABLE: 527 + ret = sysfs_match_string(feature_enabled_text, buf); 528 + if (ret < 0) 529 + return ret; 530 + val = ret; 531 + break; 532 + case FEATURE_OS_MODE: 533 + ret = sysfs_match_string(os_type_text, buf); 534 + if (ret < 0) 535 + return ret; 536 + val = ret; 537 + break; 538 + case FEATURE_POLL_RATE: 539 + ret = sysfs_match_string(poll_rate_text, buf); 540 + if (ret < 0) 541 + return ret; 542 + val = ret; 543 + break; 544 + case FEATURE_DPAD_MODE: 545 + ret = sysfs_match_string(dpad_mode_text, buf); 546 + if (ret < 0) 547 + return ret; 548 + val = ret; 549 + break; 550 + case FEATURE_MOUSE_WHEEL_STEP: 551 + ret = kstrtou8(buf, 10, &val); 552 + if (ret) 553 + return ret; 554 + if (val < 1 || val > 127) 555 + return -EINVAL; 556 + break; 557 + default: 558 + return -EINVAL; 559 + } 560 + 561 + if (!val) 562 + size = 0; 563 + 564 + ret = mcu_property_out(drvdata.hdev, SET_GAMEPAD_CFG, index, &val, 565 + size); 566 + if (ret < 0) 567 + return ret; 568 + 569 + return count; 570 + } 571 + 572 + static ssize_t gamepad_property_show(struct device *dev, 573 + struct device_attribute *attr, char *buf, 574 + enum feature_status_index index) 575 + { 576 + ssize_t count = 0; 577 + u8 i; 578 + 579 + count = mcu_property_out(drvdata.hdev, GET_GAMEPAD_CFG, index, NULL, 0); 580 + if (count < 0) 581 + return count; 582 + 583 + switch (index) { 584 + case FEATURE_GAMEPAD_MODE: 585 + i = drvdata.gp_mode; 586 + if (i >= ARRAY_SIZE(gamepad_mode_text)) 587 + return -EINVAL; 588 + count = sysfs_emit(buf, "%s\n", gamepad_mode_text[i]); 589 + break; 590 + case FEATURE_AUTO_SLEEP_TIME: 591 + count = sysfs_emit(buf, "%u\n", drvdata.gp_auto_sleep_time); 592 + break; 593 + case FEATURE_IMU_ENABLE: 594 + i = drvdata.imu_sensor_en; 595 + if (i >= ARRAY_SIZE(feature_enabled_text)) 596 + return -EINVAL; 597 + count = sysfs_emit(buf, "%s\n", feature_enabled_text[i]); 598 + break; 599 + case FEATURE_IMU_BYPASS: 600 + i = drvdata.imu_bypass_en; 601 + if (i >= ARRAY_SIZE(feature_enabled_text)) 602 + return -EINVAL; 603 + count = sysfs_emit(buf, "%s\n", feature_enabled_text[i]); 604 + break; 605 + case FEATURE_RGB_ENABLE: 606 + i = drvdata.rgb_en; 607 + if (i >= ARRAY_SIZE(feature_enabled_text)) 608 + return -EINVAL; 609 + count = sysfs_emit(buf, "%s\n", feature_enabled_text[i]); 610 + break; 611 + case FEATURE_TOUCHPAD_ENABLE: 612 + i = drvdata.tp_en; 613 + if (i >= ARRAY_SIZE(feature_enabled_text)) 614 + return -EINVAL; 615 + count = sysfs_emit(buf, "%s\n", feature_enabled_text[i]); 616 + break; 617 + case FEATURE_OS_MODE: 618 + i = drvdata.os_mode; 619 + if (i >= ARRAY_SIZE(os_type_text)) 620 + return -EINVAL; 621 + count = sysfs_emit(buf, "%s\n", os_type_text[i]); 622 + break; 623 + case FEATURE_POLL_RATE: 624 + i = drvdata.gp_poll_rate; 625 + if (i >= ARRAY_SIZE(poll_rate_text)) 626 + return -EINVAL; 627 + count = sysfs_emit(buf, "%s\n", poll_rate_text[i]); 628 + break; 629 + case FEATURE_DPAD_MODE: 630 + i = drvdata.gp_dpad_mode; 631 + if (i >= ARRAY_SIZE(dpad_mode_text)) 632 + return -EINVAL; 633 + count = sysfs_emit(buf, "%s\n", dpad_mode_text[i]); 634 + break; 635 + case FEATURE_MOUSE_WHEEL_STEP: 636 + i = drvdata.mouse_step; 637 + if (i < 1 || i > 127) 638 + return -EINVAL; 639 + count = sysfs_emit(buf, "%u\n", i); 640 + break; 641 + default: 642 + return -EINVAL; 643 + } 644 + 645 + return count; 646 + } 647 + 648 + static ssize_t gamepad_property_options(struct device *dev, 649 + struct device_attribute *attr, 650 + char *buf, 651 + enum feature_status_index index) 652 + { 653 + size_t count = 0; 654 + unsigned int i; 655 + 656 + switch (index) { 657 + case FEATURE_GAMEPAD_MODE: 658 + for (i = 0; i < ARRAY_SIZE(gamepad_mode_text); i++) { 659 + count += sysfs_emit_at(buf, count, "%s ", 660 + gamepad_mode_text[i]); 661 + } 662 + break; 663 + case FEATURE_AUTO_SLEEP_TIME: 664 + return sysfs_emit(buf, "0-255\n"); 665 + case FEATURE_IMU_ENABLE: 666 + for (i = 0; i < ARRAY_SIZE(feature_enabled_text); i++) { 667 + count += sysfs_emit_at(buf, count, "%s ", 668 + feature_enabled_text[i]); 669 + } 670 + break; 671 + case FEATURE_IMU_BYPASS: 672 + case FEATURE_RGB_ENABLE: 673 + case FEATURE_TOUCHPAD_ENABLE: 674 + for (i = 0; i < ARRAY_SIZE(feature_enabled_text); i++) { 675 + count += sysfs_emit_at(buf, count, "%s ", 676 + feature_enabled_text[i]); 677 + } 678 + break; 679 + case FEATURE_OS_MODE: 680 + for (i = 0; i < ARRAY_SIZE(os_type_text); i++) { 681 + count += sysfs_emit_at(buf, count, "%s ", 682 + os_type_text[i]); 683 + } 684 + break; 685 + case FEATURE_POLL_RATE: 686 + for (i = 0; i < ARRAY_SIZE(poll_rate_text); i++) { 687 + count += sysfs_emit_at(buf, count, "%s ", 688 + poll_rate_text[i]); 689 + } 690 + break; 691 + case FEATURE_DPAD_MODE: 692 + for (i = 0; i < ARRAY_SIZE(dpad_mode_text); i++) { 693 + count += sysfs_emit_at(buf, count, "%s ", 694 + dpad_mode_text[i]); 695 + } 696 + break; 697 + case FEATURE_MOUSE_WHEEL_STEP: 698 + return sysfs_emit(buf, "1-127\n"); 699 + default: 700 + return count; 701 + } 702 + 703 + if (count) 704 + buf[count - 1] = '\n'; 705 + 706 + return count; 707 + } 708 + 709 + static ssize_t touchpad_property_store(struct device *dev, 710 + struct device_attribute *attr, 711 + const char *buf, size_t count, 712 + enum touchpad_config_index index) 713 + { 714 + size_t size = 1; 715 + u8 val = 0; 716 + int ret; 717 + 718 + switch (index) { 719 + case CFG_WINDOWS_MODE: 720 + ret = sysfs_match_string(touchpad_mode_text, buf); 721 + if (ret < 0) 722 + return ret; 723 + val = ret; 724 + break; 725 + case CFG_LINUX_MODE: 726 + ret = sysfs_match_string(touchpad_mode_text, buf); 727 + if (ret < 0) 728 + return ret; 729 + val = ret; 730 + break; 731 + default: 732 + return -EINVAL; 733 + } 734 + if (!val) 735 + size = 0; 736 + 737 + ret = mcu_property_out(drvdata.hdev, SET_TP_PARAM, index, &val, size); 738 + if (ret < 0) 739 + return ret; 740 + 741 + return count; 742 + } 743 + 744 + static ssize_t touchpad_property_show(struct device *dev, 745 + struct device_attribute *attr, char *buf, 746 + enum touchpad_config_index index) 747 + { 748 + int ret = 0; 749 + u8 i; 750 + 751 + ret = mcu_property_out(drvdata.hdev, GET_TP_PARAM, index, NULL, 0); 752 + if (ret < 0) 753 + return ret; 754 + 755 + switch (index) { 756 + case CFG_WINDOWS_MODE: 757 + i = drvdata.tp_windows_mode; 758 + break; 759 + case CFG_LINUX_MODE: 760 + i = drvdata.tp_linux_mode; 761 + break; 762 + default: 763 + return -EINVAL; 764 + } 765 + 766 + if (i >= ARRAY_SIZE(touchpad_mode_text)) 767 + return -EINVAL; 768 + 769 + return sysfs_emit(buf, "%s\n", touchpad_mode_text[i]); 770 + } 771 + 772 + static ssize_t touchpad_property_options(struct device *dev, 773 + struct device_attribute *attr, 774 + char *buf, 775 + enum touchpad_config_index index) 776 + { 777 + size_t count = 0; 778 + unsigned int i; 779 + 780 + switch (index) { 781 + case CFG_WINDOWS_MODE: 782 + case CFG_LINUX_MODE: 783 + for (i = 0; i < ARRAY_SIZE(touchpad_mode_text); i++) { 784 + count += sysfs_emit_at(buf, count, "%s ", 785 + touchpad_mode_text[i]); 786 + } 787 + break; 788 + default: 789 + return count; 790 + } 791 + 792 + if (count) 793 + buf[count - 1] = '\n'; 794 + 795 + return count; 796 + } 797 + 798 + static ssize_t test_property_show(struct device *dev, 799 + struct device_attribute *attr, char *buf, 800 + enum test_command_index index) 801 + { 802 + size_t count = 0; 803 + u8 i; 804 + 805 + switch (index) { 806 + case TEST_TP_MFR: 807 + i = drvdata.tp_manufacturer; 808 + if (i >= ARRAY_SIZE(touchpad_manufacturer_text)) 809 + return -EINVAL; 810 + count = sysfs_emit(buf, "%s\n", touchpad_manufacturer_text[i]); 811 + break; 812 + case TEST_IMU_MFR: 813 + i = drvdata.imu_manufacturer; 814 + if (i >= ARRAY_SIZE(imu_manufacturer_text)) 815 + return -EINVAL; 816 + count = sysfs_emit(buf, "%s\n", imu_manufacturer_text[i]); 817 + break; 818 + case TEST_TP_VER: 819 + count = sysfs_emit(buf, "%u\n", drvdata.tp_version); 820 + break; 821 + default: 822 + count = -EINVAL; 823 + break; 824 + } 825 + 826 + return count; 827 + } 828 + 829 + static ssize_t mcu_id_show(struct device *dev, struct device_attribute *attr, 830 + char *buf) 831 + { 832 + return sysfs_emit(buf, "%*phN\n", 12, &drvdata.mcu_id); 833 + } 834 + 835 + static int rgb_cfg_call(struct hid_device *hdev, enum mcu_command_index cmd, 836 + enum rgb_config_index index, u8 *val, size_t size) 837 + { 838 + if (cmd != SET_RGB_CFG && cmd != GET_RGB_CFG) 839 + return -EINVAL; 840 + 841 + if (index < LIGHT_MODE_SEL || index > USR_LIGHT_PROFILE_3) 842 + return -EINVAL; 843 + 844 + return mcu_property_out(hdev, cmd, index, val, size); 845 + } 846 + 847 + static int rgb_attr_show(void) 848 + { 849 + enum rgb_config_index index; 850 + 851 + index = drvdata.rgb_profile + 2; 852 + 853 + return rgb_cfg_call(drvdata.hdev, GET_RGB_CFG, index, NULL, 0); 854 + }; 855 + 856 + static ssize_t rgb_effect_store(struct device *dev, 857 + struct device_attribute *attr, const char *buf, 858 + size_t count) 859 + { 860 + struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(drvdata.led_cdev); 861 + enum rgb_config_index index; 862 + u8 effect; 863 + int ret; 864 + 865 + ret = sysfs_match_string(rgb_effect_text, buf); 866 + if (ret < 0) 867 + return ret; 868 + 869 + effect = ret; 870 + index = drvdata.rgb_profile + 2; 871 + u8 rgb_profile[6] = { effect, 872 + mc_cdev->subled_info[0].intensity, 873 + mc_cdev->subled_info[1].intensity, 874 + mc_cdev->subled_info[2].intensity, 875 + drvdata.led_cdev->brightness, 876 + drvdata.rgb_speed }; 877 + 878 + ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, index, rgb_profile, 6); 879 + if (ret) 880 + return ret; 881 + 882 + drvdata.rgb_effect = effect; 883 + return count; 884 + }; 885 + 886 + static ssize_t rgb_effect_show(struct device *dev, 887 + struct device_attribute *attr, char *buf) 888 + { 889 + int ret; 890 + 891 + ret = rgb_attr_show(); 892 + if (ret) 893 + return ret; 894 + 895 + if (drvdata.rgb_effect >= ARRAY_SIZE(rgb_effect_text)) 896 + return -EINVAL; 897 + 898 + return sysfs_emit(buf, "%s\n", rgb_effect_text[drvdata.rgb_effect]); 899 + } 900 + 901 + static ssize_t rgb_effect_index_show(struct device *dev, 902 + struct device_attribute *attr, char *buf) 903 + { 904 + ssize_t count = 0; 905 + unsigned int i; 906 + 907 + for (i = 0; i < ARRAY_SIZE(rgb_effect_text); i++) 908 + count += sysfs_emit_at(buf, count, "%s ", rgb_effect_text[i]); 909 + 910 + if (count) 911 + buf[count - 1] = '\n'; 912 + 913 + return count; 914 + } 915 + 916 + static ssize_t rgb_speed_store(struct device *dev, 917 + struct device_attribute *attr, const char *buf, 918 + size_t count) 919 + { 920 + struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(drvdata.led_cdev); 921 + enum rgb_config_index index; 922 + int val = 0; 923 + int ret; 924 + 925 + ret = kstrtoint(buf, 10, &val); 926 + if (ret) 927 + return ret; 928 + 929 + if (val < 0 || val > 100) 930 + return -EINVAL; 931 + 932 + index = drvdata.rgb_profile + 2; 933 + u8 rgb_profile[6] = { drvdata.rgb_effect, 934 + mc_cdev->subled_info[0].intensity, 935 + mc_cdev->subled_info[1].intensity, 936 + mc_cdev->subled_info[2].intensity, 937 + drvdata.led_cdev->brightness, 938 + val }; 939 + 940 + ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, index, rgb_profile, 6); 941 + if (ret) 942 + return ret; 943 + 944 + drvdata.rgb_speed = val; 945 + 946 + return count; 947 + }; 948 + 949 + static ssize_t rgb_speed_show(struct device *dev, struct device_attribute *attr, 950 + char *buf) 951 + { 952 + int ret; 953 + 954 + ret = rgb_attr_show(); 955 + if (ret) 956 + return ret; 957 + 958 + if (drvdata.rgb_speed > 100) 959 + return -EINVAL; 960 + 961 + return sysfs_emit(buf, "%hhu\n", drvdata.rgb_speed); 962 + } 963 + 964 + static ssize_t rgb_speed_range_show(struct device *dev, 965 + struct device_attribute *attr, char *buf) 966 + { 967 + return sysfs_emit(buf, "0-100\n"); 968 + } 969 + 970 + static ssize_t rgb_mode_store(struct device *dev, struct device_attribute *attr, 971 + const char *buf, size_t count) 972 + { 973 + int ret; 974 + u8 val; 975 + 976 + ret = sysfs_match_string(rgb_mode_text, buf); 977 + if (ret <= 0) 978 + return ret; 979 + 980 + val = ret; 981 + 982 + ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, LIGHT_MODE_SEL, &val, 983 + 1); 984 + if (ret) 985 + return ret; 986 + 987 + drvdata.rgb_mode = val; 988 + 989 + return count; 990 + }; 991 + 992 + static ssize_t rgb_mode_show(struct device *dev, struct device_attribute *attr, 993 + char *buf) 994 + { 995 + int ret; 996 + 997 + ret = rgb_cfg_call(drvdata.hdev, GET_RGB_CFG, LIGHT_MODE_SEL, NULL, 0); 998 + if (ret) 999 + return ret; 1000 + 1001 + if (drvdata.rgb_mode >= ARRAY_SIZE(rgb_mode_text)) 1002 + return -EINVAL; 1003 + 1004 + return sysfs_emit(buf, "%s\n", rgb_mode_text[drvdata.rgb_mode]); 1005 + }; 1006 + 1007 + static ssize_t rgb_mode_index_show(struct device *dev, 1008 + struct device_attribute *attr, char *buf) 1009 + { 1010 + ssize_t count = 0; 1011 + unsigned int i; 1012 + 1013 + for (i = 1; i < ARRAY_SIZE(rgb_mode_text); i++) 1014 + count += sysfs_emit_at(buf, count, "%s ", rgb_mode_text[i]); 1015 + 1016 + if (count) 1017 + buf[count - 1] = '\n'; 1018 + 1019 + return count; 1020 + } 1021 + 1022 + static ssize_t rgb_profile_store(struct device *dev, 1023 + struct device_attribute *attr, const char *buf, 1024 + size_t count) 1025 + { 1026 + size_t size = 1; 1027 + int ret; 1028 + u8 val; 1029 + 1030 + ret = kstrtou8(buf, 10, &val); 1031 + if (ret < 0) 1032 + return ret; 1033 + 1034 + if (val < 1 || val > 3) 1035 + return -EINVAL; 1036 + 1037 + ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, LIGHT_PROFILE_SEL, &val, size); 1038 + if (ret) 1039 + return ret; 1040 + 1041 + drvdata.rgb_profile = val; 1042 + 1043 + return count; 1044 + }; 1045 + 1046 + static ssize_t rgb_profile_show(struct device *dev, 1047 + struct device_attribute *attr, char *buf) 1048 + { 1049 + int ret; 1050 + 1051 + ret = rgb_cfg_call(drvdata.hdev, GET_RGB_CFG, LIGHT_PROFILE_SEL, NULL, 0); 1052 + if (ret) 1053 + return ret; 1054 + 1055 + if (drvdata.rgb_profile < 1 || drvdata.rgb_profile > 3) 1056 + return -EINVAL; 1057 + 1058 + return sysfs_emit(buf, "%hhu\n", drvdata.rgb_profile); 1059 + }; 1060 + 1061 + static ssize_t rgb_profile_range_show(struct device *dev, 1062 + struct device_attribute *attr, char *buf) 1063 + { 1064 + return sysfs_emit(buf, "1-3\n"); 1065 + } 1066 + 1067 + static void hid_gos_brightness_set(struct led_classdev *led_cdev, 1068 + enum led_brightness brightness) 1069 + { 1070 + struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(drvdata.led_cdev); 1071 + enum rgb_config_index index; 1072 + int ret; 1073 + 1074 + if (brightness > led_cdev->max_brightness) { 1075 + dev_err(led_cdev->dev, "Invalid argument\n"); 1076 + return; 1077 + } 1078 + 1079 + index = drvdata.rgb_profile + 2; 1080 + u8 rgb_profile[6] = { drvdata.rgb_effect, 1081 + mc_cdev->subled_info[0].intensity, 1082 + mc_cdev->subled_info[1].intensity, 1083 + mc_cdev->subled_info[2].intensity, 1084 + brightness, 1085 + drvdata.rgb_speed }; 1086 + 1087 + ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, index, rgb_profile, 6); 1088 + switch (ret) { 1089 + case 0: 1090 + led_cdev->brightness = brightness; 1091 + break; 1092 + case -ENODEV: /* during switch to IAP -ENODEV is expected */ 1093 + case -ENOSYS: /* during rmmod -ENOSYS is expected */ 1094 + dev_dbg(led_cdev->dev, "Failed to write RGB profile: %i\n", 1095 + ret); 1096 + break; 1097 + default: 1098 + dev_err(led_cdev->dev, "Failed to write RGB profile: %i\n", 1099 + ret); 1100 + } 1101 + } 1102 + 1103 + #define LEGOS_DEVICE_ATTR_RW(_name, _attrname, _rtype, _group) \ 1104 + static ssize_t _name##_store(struct device *dev, \ 1105 + struct device_attribute *attr, \ 1106 + const char *buf, size_t count) \ 1107 + { \ 1108 + return _group##_property_store(dev, attr, buf, count, \ 1109 + _name.index); \ 1110 + } \ 1111 + static ssize_t _name##_show(struct device *dev, \ 1112 + struct device_attribute *attr, char *buf) \ 1113 + { \ 1114 + return _group##_property_show(dev, attr, buf, _name.index); \ 1115 + } \ 1116 + static ssize_t _name##_##_rtype##_show( \ 1117 + struct device *dev, struct device_attribute *attr, char *buf) \ 1118 + { \ 1119 + return _group##_property_options(dev, attr, buf, _name.index); \ 1120 + } \ 1121 + static DEVICE_ATTR_RW_NAMED(_name, _attrname) 1122 + 1123 + #define LEGOS_DEVICE_ATTR_RO(_name, _attrname, _group) \ 1124 + static ssize_t _name##_show(struct device *dev, \ 1125 + struct device_attribute *attr, char *buf) \ 1126 + { \ 1127 + return _group##_property_show(dev, attr, buf, _name.index); \ 1128 + } \ 1129 + static DEVICE_ATTR_RO_NAMED(_name, _attrname) 1130 + 1131 + /* Gamepad */ 1132 + static struct gos_cfg_attr auto_sleep_time = { FEATURE_AUTO_SLEEP_TIME }; 1133 + LEGOS_DEVICE_ATTR_RW(auto_sleep_time, "auto_sleep_time", range, gamepad); 1134 + static DEVICE_ATTR_RO(auto_sleep_time_range); 1135 + 1136 + static struct gos_cfg_attr dpad_mode = { FEATURE_DPAD_MODE }; 1137 + LEGOS_DEVICE_ATTR_RW(dpad_mode, "dpad_mode", index, gamepad); 1138 + static DEVICE_ATTR_RO(dpad_mode_index); 1139 + 1140 + static struct gos_cfg_attr gamepad_mode = { FEATURE_GAMEPAD_MODE }; 1141 + LEGOS_DEVICE_ATTR_RW(gamepad_mode, "mode", index, gamepad); 1142 + static DEVICE_ATTR_RO_NAMED(gamepad_mode_index, "mode_index"); 1143 + 1144 + static struct gos_cfg_attr gamepad_poll_rate = { FEATURE_POLL_RATE }; 1145 + LEGOS_DEVICE_ATTR_RW(gamepad_poll_rate, "poll_rate", index, gamepad); 1146 + static DEVICE_ATTR_RO_NAMED(gamepad_poll_rate_index, "poll_rate_index"); 1147 + 1148 + static struct attribute *legos_gamepad_attrs[] = { 1149 + &dev_attr_auto_sleep_time.attr, 1150 + &dev_attr_auto_sleep_time_range.attr, 1151 + &dev_attr_dpad_mode.attr, 1152 + &dev_attr_dpad_mode_index.attr, 1153 + &dev_attr_gamepad_mode.attr, 1154 + &dev_attr_gamepad_mode_index.attr, 1155 + &dev_attr_gamepad_poll_rate.attr, 1156 + &dev_attr_gamepad_poll_rate_index.attr, 1157 + NULL, 1158 + }; 1159 + 1160 + static const struct attribute_group gamepad_attr_group = { 1161 + .name = "gamepad", 1162 + .attrs = legos_gamepad_attrs, 1163 + }; 1164 + 1165 + /* IMU */ 1166 + static struct gos_cfg_attr imu_bypass_enabled = { FEATURE_IMU_BYPASS }; 1167 + LEGOS_DEVICE_ATTR_RW(imu_bypass_enabled, "bypass_enabled", index, gamepad); 1168 + static DEVICE_ATTR_RO_NAMED(imu_bypass_enabled_index, "bypass_enabled_index"); 1169 + 1170 + static struct gos_cfg_attr imu_manufacturer = { TEST_IMU_MFR }; 1171 + LEGOS_DEVICE_ATTR_RO(imu_manufacturer, "manufacturer", test); 1172 + 1173 + static struct gos_cfg_attr imu_sensor_enabled = { FEATURE_IMU_ENABLE }; 1174 + LEGOS_DEVICE_ATTR_RW(imu_sensor_enabled, "sensor_enabled", index, gamepad); 1175 + static DEVICE_ATTR_RO_NAMED(imu_sensor_enabled_index, "sensor_enabled_index"); 1176 + 1177 + static struct attribute *legos_imu_attrs[] = { 1178 + &dev_attr_imu_bypass_enabled.attr, 1179 + &dev_attr_imu_bypass_enabled_index.attr, 1180 + &dev_attr_imu_manufacturer.attr, 1181 + &dev_attr_imu_sensor_enabled.attr, 1182 + &dev_attr_imu_sensor_enabled_index.attr, 1183 + NULL, 1184 + }; 1185 + 1186 + static const struct attribute_group imu_attr_group = { 1187 + .name = "imu", 1188 + .attrs = legos_imu_attrs, 1189 + }; 1190 + 1191 + /* MCU */ 1192 + static DEVICE_ATTR_RO(mcu_id); 1193 + 1194 + static struct gos_cfg_attr os_mode = { FEATURE_OS_MODE }; 1195 + LEGOS_DEVICE_ATTR_RW(os_mode, "os_mode", index, gamepad); 1196 + static DEVICE_ATTR_RO(os_mode_index); 1197 + 1198 + static struct attribute *legos_mcu_attrs[] = { 1199 + &dev_attr_mcu_id.attr, 1200 + &dev_attr_os_mode.attr, 1201 + &dev_attr_os_mode_index.attr, 1202 + NULL, 1203 + }; 1204 + 1205 + static const struct attribute_group mcu_attr_group = { 1206 + .attrs = legos_mcu_attrs, 1207 + }; 1208 + 1209 + /* Mouse */ 1210 + static struct gos_cfg_attr mouse_wheel_step = { FEATURE_MOUSE_WHEEL_STEP }; 1211 + LEGOS_DEVICE_ATTR_RW(mouse_wheel_step, "step", range, gamepad); 1212 + static DEVICE_ATTR_RO_NAMED(mouse_wheel_step_range, "step_range"); 1213 + 1214 + static struct attribute *legos_mouse_attrs[] = { 1215 + &dev_attr_mouse_wheel_step.attr, 1216 + &dev_attr_mouse_wheel_step_range.attr, 1217 + NULL, 1218 + }; 1219 + 1220 + static const struct attribute_group mouse_attr_group = { 1221 + .name = "mouse", 1222 + .attrs = legos_mouse_attrs, 1223 + }; 1224 + 1225 + /* Touchpad */ 1226 + static struct gos_cfg_attr touchpad_enabled = { FEATURE_TOUCHPAD_ENABLE }; 1227 + LEGOS_DEVICE_ATTR_RW(touchpad_enabled, "enabled", index, gamepad); 1228 + static DEVICE_ATTR_RO_NAMED(touchpad_enabled_index, "enabled_index"); 1229 + 1230 + static struct gos_cfg_attr touchpad_linux_mode = { CFG_LINUX_MODE }; 1231 + LEGOS_DEVICE_ATTR_RW(touchpad_linux_mode, "linux_mode", index, touchpad); 1232 + static DEVICE_ATTR_RO_NAMED(touchpad_linux_mode_index, "linux_mode_index"); 1233 + 1234 + static struct gos_cfg_attr touchpad_manufacturer = { TEST_TP_MFR }; 1235 + LEGOS_DEVICE_ATTR_RO(touchpad_manufacturer, "manufacturer", test); 1236 + 1237 + static struct gos_cfg_attr touchpad_version = { TEST_TP_VER }; 1238 + LEGOS_DEVICE_ATTR_RO(touchpad_version, "version", test); 1239 + 1240 + static struct gos_cfg_attr touchpad_windows_mode = { CFG_WINDOWS_MODE }; 1241 + LEGOS_DEVICE_ATTR_RW(touchpad_windows_mode, "windows_mode", index, touchpad); 1242 + static DEVICE_ATTR_RO_NAMED(touchpad_windows_mode_index, "windows_mode_index"); 1243 + 1244 + static struct attribute *legos_touchpad_attrs[] = { 1245 + &dev_attr_touchpad_enabled.attr, 1246 + &dev_attr_touchpad_enabled_index.attr, 1247 + &dev_attr_touchpad_linux_mode.attr, 1248 + &dev_attr_touchpad_linux_mode_index.attr, 1249 + &dev_attr_touchpad_manufacturer.attr, 1250 + &dev_attr_touchpad_version.attr, 1251 + &dev_attr_touchpad_windows_mode.attr, 1252 + &dev_attr_touchpad_windows_mode_index.attr, 1253 + NULL, 1254 + }; 1255 + 1256 + static const struct attribute_group touchpad_attr_group = { 1257 + .name = "touchpad", 1258 + .attrs = legos_touchpad_attrs, 1259 + }; 1260 + 1261 + static const struct attribute_group *top_level_attr_groups[] = { 1262 + &gamepad_attr_group, 1263 + &imu_attr_group, 1264 + &mcu_attr_group, 1265 + &mouse_attr_group, 1266 + &touchpad_attr_group, 1267 + NULL, 1268 + }; 1269 + 1270 + /* RGB */ 1271 + static struct gos_cfg_attr rgb_enabled = { FEATURE_RGB_ENABLE }; 1272 + LEGOS_DEVICE_ATTR_RW(rgb_enabled, "enabled", index, gamepad); 1273 + static DEVICE_ATTR_RO_NAMED(rgb_enabled_index, "enabled_index"); 1274 + 1275 + static DEVICE_ATTR_RW_NAMED(rgb_effect, "effect"); 1276 + static DEVICE_ATTR_RO_NAMED(rgb_effect_index, "effect_index"); 1277 + static DEVICE_ATTR_RW_NAMED(rgb_mode, "mode"); 1278 + static DEVICE_ATTR_RO_NAMED(rgb_mode_index, "mode_index"); 1279 + static DEVICE_ATTR_RW_NAMED(rgb_profile, "profile"); 1280 + static DEVICE_ATTR_RO_NAMED(rgb_profile_range, "profile_range"); 1281 + static DEVICE_ATTR_RW_NAMED(rgb_speed, "speed"); 1282 + static DEVICE_ATTR_RO_NAMED(rgb_speed_range, "speed_range"); 1283 + 1284 + static struct attribute *gos_rgb_attrs[] = { 1285 + &dev_attr_rgb_enabled.attr, 1286 + &dev_attr_rgb_enabled_index.attr, 1287 + &dev_attr_rgb_effect.attr, 1288 + &dev_attr_rgb_effect_index.attr, 1289 + &dev_attr_rgb_mode.attr, 1290 + &dev_attr_rgb_mode_index.attr, 1291 + &dev_attr_rgb_profile.attr, 1292 + &dev_attr_rgb_profile_range.attr, 1293 + &dev_attr_rgb_speed.attr, 1294 + &dev_attr_rgb_speed_range.attr, 1295 + NULL, 1296 + }; 1297 + 1298 + static struct attribute_group rgb_attr_group = { 1299 + .attrs = gos_rgb_attrs, 1300 + }; 1301 + 1302 + static struct mc_subled gos_rgb_subled_info[] = { 1303 + { 1304 + .color_index = LED_COLOR_ID_RED, 1305 + .brightness = 0x50, 1306 + .intensity = 0x24, 1307 + .channel = 0x1, 1308 + }, 1309 + { 1310 + .color_index = LED_COLOR_ID_GREEN, 1311 + .brightness = 0x50, 1312 + .intensity = 0x22, 1313 + .channel = 0x2, 1314 + }, 1315 + { 1316 + .color_index = LED_COLOR_ID_BLUE, 1317 + .brightness = 0x50, 1318 + .intensity = 0x99, 1319 + .channel = 0x3, 1320 + }, 1321 + }; 1322 + 1323 + static struct led_classdev_mc gos_cdev_rgb = { 1324 + .led_cdev = { 1325 + .name = "go_s:rgb:joystick_rings", 1326 + .brightness = 0x50, 1327 + .max_brightness = 0x64, 1328 + .brightness_set = hid_gos_brightness_set, 1329 + }, 1330 + .num_colors = ARRAY_SIZE(gos_rgb_subled_info), 1331 + .subled_info = gos_rgb_subled_info, 1332 + }; 1333 + 1334 + static void cfg_setup(struct work_struct *work) 1335 + { 1336 + int ret; 1337 + 1338 + /* MCU */ 1339 + ret = mcu_property_out(drvdata.hdev, GET_MCU_ID, FEATURE_NONE, NULL, 0); 1340 + if (ret) { 1341 + dev_err(&drvdata.hdev->dev, "Failed to retrieve MCU ID: %i\n", 1342 + ret); 1343 + return; 1344 + } 1345 + 1346 + ret = mcu_property_out(drvdata.hdev, GET_VERSION, FEATURE_NONE, NULL, 0); 1347 + if (ret) { 1348 + dev_err(&drvdata.hdev->dev, "Failed to retrieve MCU Version: %i\n", ret); 1349 + return; 1350 + } 1351 + 1352 + ret = mcu_property_out(drvdata.hdev, GET_PL_TEST, TEST_TP_MFR, NULL, 0); 1353 + if (ret) { 1354 + dev_err(&drvdata.hdev->dev, 1355 + "Failed to retrieve Touchpad Manufacturer: %i\n", ret); 1356 + return; 1357 + } 1358 + 1359 + ret = mcu_property_out(drvdata.hdev, GET_PL_TEST, TEST_TP_VER, NULL, 0); 1360 + if (ret) { 1361 + dev_err(&drvdata.hdev->dev, 1362 + "Failed to retrieve Touchpad Firmware Version: %i\n", ret); 1363 + return; 1364 + } 1365 + 1366 + ret = mcu_property_out(drvdata.hdev, GET_PL_TEST, TEST_IMU_MFR, NULL, 0); 1367 + if (ret) { 1368 + dev_err(&drvdata.hdev->dev, 1369 + "Failed to retrieve IMU Manufacturer: %i\n", ret); 1370 + return; 1371 + } 1372 + } 1373 + 1374 + static int hid_gos_cfg_probe(struct hid_device *hdev, 1375 + const struct hid_device_id *_id) 1376 + { 1377 + int ret; 1378 + 1379 + hid_set_drvdata(hdev, &drvdata); 1380 + drvdata.hdev = hdev; 1381 + mutex_init(&drvdata.cfg_mutex); 1382 + 1383 + ret = sysfs_create_groups(&hdev->dev.kobj, top_level_attr_groups); 1384 + if (ret) { 1385 + dev_err_probe(&hdev->dev, ret, 1386 + "Failed to create gamepad configuration attributes\n"); 1387 + return ret; 1388 + } 1389 + 1390 + ret = devm_led_classdev_multicolor_register(&hdev->dev, &gos_cdev_rgb); 1391 + if (ret) { 1392 + dev_err_probe(&hdev->dev, ret, "Failed to create RGB device\n"); 1393 + return ret; 1394 + } 1395 + 1396 + ret = devm_device_add_group(gos_cdev_rgb.led_cdev.dev, &rgb_attr_group); 1397 + if (ret) { 1398 + dev_err_probe(&hdev->dev, ret, 1399 + "Failed to create RGB configuration attributes\n"); 1400 + return ret; 1401 + } 1402 + 1403 + drvdata.led_cdev = &gos_cdev_rgb.led_cdev; 1404 + 1405 + init_completion(&drvdata.send_cmd_complete); 1406 + 1407 + /* Executing calls prior to returning from probe will lock the MCU. Schedule 1408 + * initial data call after probe has completed and MCU can accept calls. 1409 + */ 1410 + INIT_DELAYED_WORK(&drvdata.gos_cfg_setup, &cfg_setup); 1411 + ret = schedule_delayed_work(&drvdata.gos_cfg_setup, msecs_to_jiffies(2)); 1412 + if (!ret) { 1413 + dev_err(&hdev->dev, "Failed to schedule startup delayed work\n"); 1414 + return -ENODEV; 1415 + } 1416 + 1417 + return 0; 1418 + } 1419 + 1420 + static void hid_gos_cfg_remove(struct hid_device *hdev) 1421 + { 1422 + guard(mutex)(&drvdata.cfg_mutex); 1423 + cancel_delayed_work_sync(&drvdata.gos_cfg_setup); 1424 + sysfs_remove_groups(&hdev->dev.kobj, top_level_attr_groups); 1425 + hid_hw_close(hdev); 1426 + hid_hw_stop(hdev); 1427 + hid_set_drvdata(hdev, NULL); 1428 + } 1429 + 1430 + static int hid_gos_probe(struct hid_device *hdev, 1431 + const struct hid_device_id *id) 1432 + { 1433 + int ret, ep; 1434 + 1435 + ret = hid_parse(hdev); 1436 + if (ret) { 1437 + hid_err(hdev, "Parse failed\n"); 1438 + return ret; 1439 + } 1440 + 1441 + ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); 1442 + if (ret) { 1443 + hid_err(hdev, "Failed to start HID device\n"); 1444 + return ret; 1445 + } 1446 + 1447 + ret = hid_hw_open(hdev); 1448 + if (ret) { 1449 + hid_err(hdev, "Failed to open HID device\n"); 1450 + hid_hw_stop(hdev); 1451 + return ret; 1452 + } 1453 + 1454 + ep = get_endpoint_address(hdev); 1455 + if (ep != GO_S_CFG_INTF_IN) { 1456 + dev_dbg(&hdev->dev, "Started interface %x as generic HID device.\n", ep); 1457 + return 0; 1458 + } 1459 + 1460 + ret = hid_gos_cfg_probe(hdev, id); 1461 + if (ret) 1462 + dev_err_probe(&hdev->dev, ret, "Failed to start configuration interface"); 1463 + 1464 + dev_dbg(&hdev->dev, "Started interface %x as Go S configuration interface\n", ep); 1465 + return ret; 1466 + } 1467 + 1468 + static void hid_gos_remove(struct hid_device *hdev) 1469 + { 1470 + int ep = get_endpoint_address(hdev); 1471 + 1472 + switch (ep) { 1473 + case GO_S_CFG_INTF_IN: 1474 + hid_gos_cfg_remove(hdev); 1475 + break; 1476 + default: 1477 + hid_hw_close(hdev); 1478 + hid_hw_stop(hdev); 1479 + 1480 + break; 1481 + } 1482 + } 1483 + 1484 + static const struct hid_device_id hid_gos_devices[] = { 1485 + { HID_USB_DEVICE(USB_VENDOR_ID_QHE, 1486 + USB_DEVICE_ID_LENOVO_LEGION_GO_S_XINPUT) }, 1487 + { HID_USB_DEVICE(USB_VENDOR_ID_QHE, 1488 + USB_DEVICE_ID_LENOVO_LEGION_GO_S_DINPUT) }, 1489 + {} 1490 + }; 1491 + 1492 + MODULE_DEVICE_TABLE(hid, hid_gos_devices); 1493 + static struct hid_driver hid_lenovo_go_s = { 1494 + .name = "hid-lenovo-go-s", 1495 + .id_table = hid_gos_devices, 1496 + .probe = hid_gos_probe, 1497 + .remove = hid_gos_remove, 1498 + .raw_event = hid_gos_raw_event, 1499 + }; 1500 + module_hid_driver(hid_lenovo_go_s); 1501 + 1502 + MODULE_AUTHOR("Derek J. Clark"); 1503 + MODULE_DESCRIPTION("HID Driver for Lenovo Legion Go S Series gamepad."); 1504 + MODULE_LICENSE("GPL");
+2500
drivers/hid/hid-lenovo-go.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * HID driver for Lenovo Legion Go series gamepads. 4 + * 5 + * Copyright (c) 2026 Derek J. Clark <derekjohn.clark@gmail.com> 6 + * Copyright (c) 2026 Valve Corporation 7 + */ 8 + 9 + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 10 + 11 + #include <linux/array_size.h> 12 + #include <linux/cleanup.h> 13 + #include <linux/completion.h> 14 + #include <linux/delay.h> 15 + #include <linux/dev_printk.h> 16 + #include <linux/device.h> 17 + #include <linux/device/devres.h> 18 + #include <linux/hid.h> 19 + #include <linux/jiffies.h> 20 + #include <linux/kstrtox.h> 21 + #include <linux/led-class-multicolor.h> 22 + #include <linux/mutex.h> 23 + #include <linux/printk.h> 24 + #include <linux/sysfs.h> 25 + #include <linux/types.h> 26 + #include <linux/unaligned.h> 27 + #include <linux/usb.h> 28 + #include <linux/workqueue.h> 29 + #include <linux/workqueue_types.h> 30 + 31 + #include "hid-ids.h" 32 + 33 + #define GO_GP_INTF_IN 0x83 34 + #define GO_OUTPUT_REPORT_ID 0x05 35 + #define GO_GP_RESET_SUCCESS 0x01 36 + #define GO_PACKET_SIZE 64 37 + 38 + static struct hid_go_cfg { 39 + struct delayed_work go_cfg_setup; 40 + struct completion send_cmd_complete; 41 + struct led_classdev *led_cdev; 42 + struct hid_device *hdev; 43 + struct mutex cfg_mutex; /*ensure single synchronous output report*/ 44 + u8 fps_mode; 45 + u8 gp_left_auto_sleep_time; 46 + u8 gp_left_gyro_cal_status; 47 + u8 gp_left_joy_cal_status; 48 + u8 gp_left_notify_en; 49 + u8 gp_left_rumble_mode; 50 + u8 gp_left_trigg_cal_status; 51 + u32 gp_left_version_firmware; 52 + u8 gp_left_version_gen; 53 + u32 gp_left_version_hardware; 54 + u32 gp_left_version_product; 55 + u32 gp_left_version_protocol; 56 + u8 gp_mode; 57 + u8 gp_right_auto_sleep_time; 58 + u8 gp_right_gyro_cal_status; 59 + u8 gp_right_joy_cal_status; 60 + u8 gp_right_notify_en; 61 + u8 gp_right_rumble_mode; 62 + u8 gp_right_trigg_cal_status; 63 + u32 gp_right_version_firmware; 64 + u8 gp_right_version_gen; 65 + u32 gp_right_version_hardware; 66 + u32 gp_right_version_product; 67 + u32 gp_right_version_protocol; 68 + u8 gp_rumble_intensity; 69 + u8 imu_left_bypass_en; 70 + u8 imu_left_sensor_en; 71 + u8 imu_right_bypass_en; 72 + u8 imu_right_sensor_en; 73 + u32 mcu_version_firmware; 74 + u8 mcu_version_gen; 75 + u32 mcu_version_hardware; 76 + u32 mcu_version_product; 77 + u32 mcu_version_protocol; 78 + u32 mouse_dpi; 79 + u8 os_mode; 80 + u8 rgb_effect; 81 + u8 rgb_en; 82 + u8 rgb_mode; 83 + u8 rgb_profile; 84 + u8 rgb_speed; 85 + u8 tp_en; 86 + u8 tp_vibration_en; 87 + u8 tp_vibration_intensity; 88 + u32 tx_dongle_version_firmware; 89 + u8 tx_dongle_version_gen; 90 + u32 tx_dongle_version_hardware; 91 + u32 tx_dongle_version_product; 92 + u32 tx_dongle_version_protocol; 93 + } drvdata; 94 + 95 + struct go_cfg_attr { 96 + u8 index; 97 + }; 98 + 99 + struct command_report { 100 + u8 report_id; 101 + u8 id; 102 + u8 cmd; 103 + u8 sub_cmd; 104 + u8 device_type; 105 + u8 data[59]; 106 + } __packed; 107 + 108 + enum command_id { 109 + MCU_CONFIG_DATA = 0x00, 110 + OS_MODE_DATA = 0x06, 111 + GAMEPAD_DATA = 0x3c, 112 + }; 113 + 114 + enum mcu_command_index { 115 + GET_VERSION_DATA = 0x02, 116 + GET_FEATURE_STATUS, 117 + SET_FEATURE_STATUS, 118 + GET_MOTOR_CFG, 119 + SET_MOTOR_CFG, 120 + GET_DPI_CFG, 121 + SET_DPI_CFG, 122 + SET_TRIGGER_CFG = 0x0a, 123 + SET_JOYSTICK_CFG = 0x0c, 124 + SET_GYRO_CFG = 0x0e, 125 + GET_RGB_CFG, 126 + SET_RGB_CFG, 127 + GET_DEVICE_STATUS = 0xa0, 128 + 129 + }; 130 + 131 + enum dev_type { 132 + UNSPECIFIED, 133 + USB_MCU, 134 + TX_DONGLE, 135 + LEFT_CONTROLLER, 136 + RIGHT_CONTROLLER, 137 + }; 138 + 139 + enum enabled_status_index { 140 + FEATURE_UNKNOWN, 141 + FEATURE_ENABLED, 142 + FEATURE_DISABLED, 143 + }; 144 + 145 + static const char *const enabled_status_text[] = { 146 + [FEATURE_UNKNOWN] = "unknown", 147 + [FEATURE_ENABLED] = "true", 148 + [FEATURE_DISABLED] = "false", 149 + }; 150 + 151 + enum version_data_index { 152 + PRODUCT_VERSION = 0x02, 153 + PROTOCOL_VERSION, 154 + FIRMWARE_VERSION, 155 + HARDWARE_VERSION, 156 + HARDWARE_GENERATION, 157 + }; 158 + 159 + enum feature_status_index { 160 + FEATURE_RESET_GAMEPAD = 0x02, 161 + FEATURE_IMU_BYPASS, 162 + FEATURE_IMU_ENABLE = 0x05, 163 + FEATURE_TOUCHPAD_ENABLE = 0x07, 164 + FEATURE_LIGHT_ENABLE, 165 + FEATURE_AUTO_SLEEP_TIME, 166 + FEATURE_FPS_SWITCH_STATUS = 0x0b, 167 + FEATURE_GAMEPAD_MODE = 0x0e, 168 + }; 169 + 170 + #define FEATURE_OS_MODE 0x69 171 + 172 + enum fps_switch_status_index { 173 + FPS_STATUS_UNKNOWN, 174 + GAMEPAD, 175 + FPS, 176 + }; 177 + 178 + static const char *const fps_switch_text[] = { 179 + [FPS_STATUS_UNKNOWN] = "unknown", 180 + [GAMEPAD] = "gamepad", 181 + [FPS] = "fps", 182 + }; 183 + 184 + enum gamepad_mode_index { 185 + GAMEPAD_MODE_UNKNOWN, 186 + XINPUT, 187 + DINPUT, 188 + }; 189 + 190 + static const char *const gamepad_mode_text[] = { 191 + [GAMEPAD_MODE_UNKNOWN] = "unknown", 192 + [XINPUT] = "xinput", 193 + [DINPUT] = "dinput", 194 + }; 195 + 196 + enum motor_cfg_index { 197 + MOTOR_CFG_ALL = 0x01, 198 + MOTOR_INTENSITY, 199 + VIBRATION_NOTIFY_ENABLE, 200 + RUMBLE_MODE, 201 + TP_VIBRATION_ENABLE, 202 + TP_VIBRATION_INTENSITY, 203 + }; 204 + 205 + enum intensity_index { 206 + INTENSITY_UNKNOWN, 207 + INTENSITY_OFF, 208 + INTENSITY_LOW, 209 + INTENSITY_MEDIUM, 210 + INTENSITY_HIGH, 211 + }; 212 + 213 + static const char *const intensity_text[] = { 214 + [INTENSITY_UNKNOWN] = "unknown", 215 + [INTENSITY_OFF] = "off", 216 + [INTENSITY_LOW] = "low", 217 + [INTENSITY_MEDIUM] = "medium", 218 + [INTENSITY_HIGH] = "high", 219 + }; 220 + 221 + enum rumble_mode_index { 222 + RUMBLE_MODE_UNKNOWN, 223 + RUMBLE_MODE_FPS, 224 + RUMBLE_MODE_RACE, 225 + RUMBLE_MODE_AVERAGE, 226 + RUMBLE_MODE_SPG, 227 + RUMBLE_MODE_RPG, 228 + }; 229 + 230 + static const char *const rumble_mode_text[] = { 231 + [RUMBLE_MODE_UNKNOWN] = "unknown", 232 + [RUMBLE_MODE_FPS] = "fps", 233 + [RUMBLE_MODE_RACE] = "racing", 234 + [RUMBLE_MODE_AVERAGE] = "standard", 235 + [RUMBLE_MODE_SPG] = "spg", 236 + [RUMBLE_MODE_RPG] = "rpg", 237 + }; 238 + 239 + #define FPS_MODE_DPI 0x02 240 + #define TRIGGER_CALIBRATE 0x04 241 + #define JOYSTICK_CALIBRATE 0x04 242 + #define GYRO_CALIBRATE 0x06 243 + 244 + enum cal_device_type { 245 + CALDEV_GYROSCOPE = 0x01, 246 + CALDEV_JOYSTICK, 247 + CALDEV_TRIGGER, 248 + CALDEV_JOY_TRIGGER, 249 + }; 250 + 251 + enum cal_enable { 252 + CAL_UNKNOWN, 253 + CAL_START, 254 + CAL_STOP, 255 + }; 256 + 257 + static const char *const cal_enabled_text[] = { 258 + [CAL_UNKNOWN] = "unknown", 259 + [CAL_START] = "start", 260 + [CAL_STOP] = "stop", 261 + }; 262 + 263 + enum cal_status_index { 264 + CAL_STAT_UNKNOWN, 265 + CAL_STAT_SUCCESS, 266 + CAL_STAT_FAILURE, 267 + }; 268 + 269 + static const char *const cal_status_text[] = { 270 + [CAL_STAT_UNKNOWN] = "unknown", 271 + [CAL_STAT_SUCCESS] = "success", 272 + [CAL_STAT_FAILURE] = "failure", 273 + }; 274 + 275 + enum rgb_config_index { 276 + LIGHT_CFG_ALL = 0x01, 277 + LIGHT_MODE_SEL, 278 + LIGHT_PROFILE_SEL, 279 + USR_LIGHT_PROFILE_1, 280 + USR_LIGHT_PROFILE_2, 281 + USR_LIGHT_PROFILE_3, 282 + }; 283 + 284 + enum rgb_mode_index { 285 + RGB_MODE_UNKNOWN, 286 + RGB_MODE_DYNAMIC, 287 + RGB_MODE_CUSTOM, 288 + }; 289 + 290 + static const char *const rgb_mode_text[] = { 291 + [RGB_MODE_UNKNOWN] = "unknown", 292 + [RGB_MODE_DYNAMIC] = "dynamic", 293 + [RGB_MODE_CUSTOM] = "custom", 294 + }; 295 + 296 + enum rgb_effect_index { 297 + RGB_EFFECT_MONO, 298 + RGB_EFFECT_BREATHE, 299 + RGB_EFFECT_CHROMA, 300 + RGB_EFFECT_RAINBOW, 301 + }; 302 + 303 + static const char *const rgb_effect_text[] = { 304 + [RGB_EFFECT_MONO] = "monocolor", 305 + [RGB_EFFECT_BREATHE] = "breathe", 306 + [RGB_EFFECT_CHROMA] = "chroma", 307 + [RGB_EFFECT_RAINBOW] = "rainbow", 308 + }; 309 + 310 + enum device_status_index { 311 + GET_CAL_STATUS = 0x02, 312 + GET_UPGRADE_STATUS, 313 + GET_MACRO_REC_STATUS, 314 + GET_HOTKEY_TRIGG_STATUS, 315 + }; 316 + 317 + enum os_mode_cfg_index { 318 + SET_OS_MODE = 0x09, 319 + GET_OS_MODE, 320 + }; 321 + 322 + enum os_mode_type_index { 323 + OS_UNKNOWN, 324 + WINDOWS, 325 + LINUX, 326 + }; 327 + 328 + static const char *const os_mode_text[] = { 329 + [OS_UNKNOWN] = "unknown", 330 + [WINDOWS] = "windows", 331 + [LINUX] = "linux", 332 + }; 333 + 334 + static int hid_go_version_event(struct command_report *cmd_rep) 335 + { 336 + switch (cmd_rep->sub_cmd) { 337 + case PRODUCT_VERSION: 338 + switch (cmd_rep->device_type) { 339 + case USB_MCU: 340 + drvdata.mcu_version_product = 341 + get_unaligned_be32(cmd_rep->data); 342 + return 0; 343 + case TX_DONGLE: 344 + drvdata.tx_dongle_version_product = 345 + get_unaligned_be32(cmd_rep->data); 346 + return 0; 347 + case LEFT_CONTROLLER: 348 + drvdata.gp_left_version_product = 349 + get_unaligned_be32(cmd_rep->data); 350 + return 0; 351 + case RIGHT_CONTROLLER: 352 + drvdata.gp_right_version_product = 353 + get_unaligned_be32(cmd_rep->data); 354 + return 0; 355 + default: 356 + return -EINVAL; 357 + } 358 + case PROTOCOL_VERSION: 359 + switch (cmd_rep->device_type) { 360 + case USB_MCU: 361 + drvdata.mcu_version_protocol = 362 + get_unaligned_be32(cmd_rep->data); 363 + return 0; 364 + case TX_DONGLE: 365 + drvdata.tx_dongle_version_protocol = 366 + get_unaligned_be32(cmd_rep->data); 367 + return 0; 368 + case LEFT_CONTROLLER: 369 + drvdata.gp_left_version_protocol = 370 + get_unaligned_be32(cmd_rep->data); 371 + return 0; 372 + case RIGHT_CONTROLLER: 373 + drvdata.gp_right_version_protocol = 374 + get_unaligned_be32(cmd_rep->data); 375 + return 0; 376 + default: 377 + return -EINVAL; 378 + } 379 + case FIRMWARE_VERSION: 380 + switch (cmd_rep->device_type) { 381 + case USB_MCU: 382 + drvdata.mcu_version_firmware = 383 + get_unaligned_be32(cmd_rep->data); 384 + return 0; 385 + case TX_DONGLE: 386 + drvdata.tx_dongle_version_firmware = 387 + get_unaligned_be32(cmd_rep->data); 388 + return 0; 389 + case LEFT_CONTROLLER: 390 + drvdata.gp_left_version_firmware = 391 + get_unaligned_be32(cmd_rep->data); 392 + return 0; 393 + case RIGHT_CONTROLLER: 394 + drvdata.gp_right_version_firmware = 395 + get_unaligned_be32(cmd_rep->data); 396 + return 0; 397 + default: 398 + return -EINVAL; 399 + } 400 + case HARDWARE_VERSION: 401 + switch (cmd_rep->device_type) { 402 + case USB_MCU: 403 + drvdata.mcu_version_hardware = 404 + get_unaligned_be32(cmd_rep->data); 405 + return 0; 406 + case TX_DONGLE: 407 + drvdata.tx_dongle_version_hardware = 408 + get_unaligned_be32(cmd_rep->data); 409 + return 0; 410 + case LEFT_CONTROLLER: 411 + drvdata.gp_left_version_hardware = 412 + get_unaligned_be32(cmd_rep->data); 413 + return 0; 414 + case RIGHT_CONTROLLER: 415 + drvdata.gp_right_version_hardware = 416 + get_unaligned_be32(cmd_rep->data); 417 + return 0; 418 + default: 419 + return -EINVAL; 420 + } 421 + case HARDWARE_GENERATION: 422 + switch (cmd_rep->device_type) { 423 + case USB_MCU: 424 + drvdata.mcu_version_gen = cmd_rep->data[0]; 425 + return 0; 426 + case TX_DONGLE: 427 + drvdata.tx_dongle_version_gen = cmd_rep->data[0]; 428 + return 0; 429 + case LEFT_CONTROLLER: 430 + drvdata.gp_left_version_gen = cmd_rep->data[0]; 431 + return 0; 432 + case RIGHT_CONTROLLER: 433 + drvdata.gp_right_version_gen = cmd_rep->data[0]; 434 + return 0; 435 + default: 436 + return -EINVAL; 437 + } 438 + default: 439 + return -EINVAL; 440 + } 441 + } 442 + 443 + static int hid_go_feature_status_event(struct command_report *cmd_rep) 444 + { 445 + switch (cmd_rep->sub_cmd) { 446 + case FEATURE_RESET_GAMEPAD: 447 + return 0; 448 + case FEATURE_IMU_ENABLE: 449 + switch (cmd_rep->device_type) { 450 + case LEFT_CONTROLLER: 451 + drvdata.imu_left_sensor_en = cmd_rep->data[0]; 452 + return 0; 453 + case RIGHT_CONTROLLER: 454 + drvdata.imu_right_sensor_en = cmd_rep->data[0]; 455 + return 0; 456 + default: 457 + return -EINVAL; 458 + } 459 + case FEATURE_IMU_BYPASS: 460 + switch (cmd_rep->device_type) { 461 + case LEFT_CONTROLLER: 462 + drvdata.imu_left_bypass_en = cmd_rep->data[0]; 463 + return 0; 464 + case RIGHT_CONTROLLER: 465 + drvdata.imu_right_bypass_en = cmd_rep->data[0]; 466 + return 0; 467 + default: 468 + return -EINVAL; 469 + } 470 + break; 471 + case FEATURE_LIGHT_ENABLE: 472 + drvdata.rgb_en = cmd_rep->data[0]; 473 + return 0; 474 + case FEATURE_AUTO_SLEEP_TIME: 475 + switch (cmd_rep->device_type) { 476 + case LEFT_CONTROLLER: 477 + drvdata.gp_left_auto_sleep_time = cmd_rep->data[0]; 478 + return 0; 479 + case RIGHT_CONTROLLER: 480 + drvdata.gp_right_auto_sleep_time = cmd_rep->data[0]; 481 + return 0; 482 + default: 483 + return -EINVAL; 484 + } 485 + break; 486 + case FEATURE_TOUCHPAD_ENABLE: 487 + drvdata.tp_en = cmd_rep->data[0]; 488 + return 0; 489 + case FEATURE_GAMEPAD_MODE: 490 + drvdata.gp_mode = cmd_rep->data[0]; 491 + return 0; 492 + case FEATURE_FPS_SWITCH_STATUS: 493 + drvdata.fps_mode = cmd_rep->data[0]; 494 + return 0; 495 + default: 496 + return -EINVAL; 497 + } 498 + } 499 + 500 + static int hid_go_motor_event(struct command_report *cmd_rep) 501 + { 502 + switch (cmd_rep->sub_cmd) { 503 + case MOTOR_CFG_ALL: 504 + return -EINVAL; 505 + case MOTOR_INTENSITY: 506 + drvdata.gp_rumble_intensity = cmd_rep->data[0]; 507 + return 0; 508 + case VIBRATION_NOTIFY_ENABLE: 509 + switch (cmd_rep->device_type) { 510 + case LEFT_CONTROLLER: 511 + drvdata.gp_left_notify_en = cmd_rep->data[0]; 512 + return 0; 513 + case RIGHT_CONTROLLER: 514 + drvdata.gp_right_notify_en = cmd_rep->data[0]; 515 + return 0; 516 + default: 517 + return -EINVAL; 518 + } 519 + break; 520 + case RUMBLE_MODE: 521 + switch (cmd_rep->device_type) { 522 + case LEFT_CONTROLLER: 523 + drvdata.gp_left_rumble_mode = cmd_rep->data[0]; 524 + return 0; 525 + case RIGHT_CONTROLLER: 526 + drvdata.gp_right_rumble_mode = cmd_rep->data[0]; 527 + return 0; 528 + default: 529 + return -EINVAL; 530 + } 531 + case TP_VIBRATION_ENABLE: 532 + drvdata.tp_vibration_en = cmd_rep->data[0]; 533 + return 0; 534 + case TP_VIBRATION_INTENSITY: 535 + drvdata.tp_vibration_intensity = cmd_rep->data[0]; 536 + return 0; 537 + } 538 + return -EINVAL; 539 + } 540 + 541 + static int hid_go_fps_dpi_event(struct command_report *cmd_rep) 542 + { 543 + if (cmd_rep->sub_cmd != FPS_MODE_DPI) 544 + return -EINVAL; 545 + 546 + drvdata.mouse_dpi = get_unaligned_le32(cmd_rep->data); 547 + 548 + return 0; 549 + } 550 + 551 + static int hid_go_light_event(struct command_report *cmd_rep) 552 + { 553 + struct led_classdev_mc *mc_cdev; 554 + 555 + switch (cmd_rep->sub_cmd) { 556 + case LIGHT_MODE_SEL: 557 + drvdata.rgb_mode = cmd_rep->data[0]; 558 + return 0; 559 + case LIGHT_PROFILE_SEL: 560 + drvdata.rgb_profile = cmd_rep->data[0]; 561 + return 0; 562 + case USR_LIGHT_PROFILE_1: 563 + case USR_LIGHT_PROFILE_2: 564 + case USR_LIGHT_PROFILE_3: 565 + mc_cdev = lcdev_to_mccdev(drvdata.led_cdev); 566 + drvdata.rgb_effect = cmd_rep->data[0]; 567 + mc_cdev->subled_info[0].intensity = cmd_rep->data[1]; 568 + mc_cdev->subled_info[1].intensity = cmd_rep->data[2]; 569 + mc_cdev->subled_info[2].intensity = cmd_rep->data[3]; 570 + drvdata.led_cdev->brightness = cmd_rep->data[4]; 571 + drvdata.rgb_speed = 100 - cmd_rep->data[5]; 572 + return 0; 573 + default: 574 + return -EINVAL; 575 + } 576 + } 577 + 578 + static int hid_go_device_status_event(struct command_report *cmd_rep) 579 + { 580 + switch (cmd_rep->device_type) { 581 + case LEFT_CONTROLLER: 582 + switch (cmd_rep->data[0]) { 583 + case CALDEV_GYROSCOPE: 584 + drvdata.gp_left_gyro_cal_status = cmd_rep->data[1]; 585 + return 0; 586 + case CALDEV_JOYSTICK: 587 + drvdata.gp_left_joy_cal_status = cmd_rep->data[1]; 588 + return 0; 589 + case CALDEV_TRIGGER: 590 + drvdata.gp_left_trigg_cal_status = cmd_rep->data[1]; 591 + return 0; 592 + default: 593 + return -EINVAL; 594 + } 595 + break; 596 + case RIGHT_CONTROLLER: 597 + switch (cmd_rep->data[0]) { 598 + case CALDEV_GYROSCOPE: 599 + drvdata.gp_right_gyro_cal_status = cmd_rep->data[1]; 600 + return 0; 601 + case CALDEV_JOYSTICK: 602 + drvdata.gp_right_joy_cal_status = cmd_rep->data[1]; 603 + return 0; 604 + case CALDEV_TRIGGER: 605 + drvdata.gp_right_trigg_cal_status = cmd_rep->data[1]; 606 + return 0; 607 + default: 608 + return -EINVAL; 609 + } 610 + break; 611 + default: 612 + return -EINVAL; 613 + } 614 + } 615 + 616 + static int hid_go_os_mode_cfg_event(struct command_report *cmd_rep) 617 + { 618 + switch (cmd_rep->sub_cmd) { 619 + case SET_OS_MODE: 620 + if (cmd_rep->data[0] != 1) 621 + return -EIO; 622 + return 0; 623 + case GET_OS_MODE: 624 + drvdata.os_mode = cmd_rep->data[0]; 625 + return 0; 626 + default: 627 + return -EINVAL; 628 + } 629 + } 630 + 631 + static int hid_go_set_event_return(struct command_report *cmd_rep) 632 + { 633 + if (cmd_rep->data[0] != 0) 634 + return -EIO; 635 + 636 + return 0; 637 + } 638 + 639 + static int get_endpoint_address(struct hid_device *hdev) 640 + { 641 + struct usb_interface *intf = to_usb_interface(hdev->dev.parent); 642 + struct usb_host_endpoint *ep; 643 + 644 + if (!intf) 645 + return -ENODEV; 646 + 647 + ep = intf->cur_altsetting->endpoint; 648 + if (!ep) 649 + return -ENODEV; 650 + 651 + return ep->desc.bEndpointAddress; 652 + } 653 + 654 + static int hid_go_raw_event(struct hid_device *hdev, struct hid_report *report, 655 + u8 *data, int size) 656 + { 657 + struct command_report *cmd_rep; 658 + int ep, ret; 659 + 660 + if (size != GO_PACKET_SIZE) 661 + goto passthrough; 662 + 663 + ep = get_endpoint_address(hdev); 664 + if (ep != GO_GP_INTF_IN) 665 + goto passthrough; 666 + 667 + cmd_rep = (struct command_report *)data; 668 + 669 + switch (cmd_rep->id) { 670 + case MCU_CONFIG_DATA: 671 + switch (cmd_rep->cmd) { 672 + case GET_VERSION_DATA: 673 + ret = hid_go_version_event(cmd_rep); 674 + break; 675 + case GET_FEATURE_STATUS: 676 + ret = hid_go_feature_status_event(cmd_rep); 677 + break; 678 + case GET_MOTOR_CFG: 679 + ret = hid_go_motor_event(cmd_rep); 680 + break; 681 + case GET_DPI_CFG: 682 + ret = hid_go_fps_dpi_event(cmd_rep); 683 + break; 684 + case GET_RGB_CFG: 685 + ret = hid_go_light_event(cmd_rep); 686 + break; 687 + case GET_DEVICE_STATUS: 688 + ret = hid_go_device_status_event(cmd_rep); 689 + break; 690 + case SET_FEATURE_STATUS: 691 + case SET_MOTOR_CFG: 692 + case SET_DPI_CFG: 693 + case SET_RGB_CFG: 694 + case SET_TRIGGER_CFG: 695 + case SET_JOYSTICK_CFG: 696 + case SET_GYRO_CFG: 697 + ret = hid_go_set_event_return(cmd_rep); 698 + break; 699 + default: 700 + ret = -EINVAL; 701 + break; 702 + } 703 + break; 704 + case OS_MODE_DATA: 705 + ret = hid_go_os_mode_cfg_event(cmd_rep); 706 + break; 707 + default: 708 + goto passthrough; 709 + } 710 + dev_dbg(&hdev->dev, "Rx data as raw input report: [%*ph]\n", 711 + GO_PACKET_SIZE, data); 712 + 713 + complete(&drvdata.send_cmd_complete); 714 + return ret; 715 + 716 + passthrough: 717 + /* Forward other HID reports so they generate events */ 718 + hid_input_report(hdev, HID_INPUT_REPORT, data, size, 1); 719 + return 0; 720 + } 721 + 722 + static int mcu_property_out(struct hid_device *hdev, u8 id, u8 command, 723 + u8 index, enum dev_type device, u8 *data, size_t len) 724 + { 725 + unsigned char *dmabuf __free(kfree) = NULL; 726 + u8 header[] = { GO_OUTPUT_REPORT_ID, id, command, index, device }; 727 + size_t header_size = ARRAY_SIZE(header); 728 + int timeout = 50; 729 + int ret; 730 + 731 + if (header_size + len > GO_PACKET_SIZE) 732 + return -EINVAL; 733 + 734 + guard(mutex)(&drvdata.cfg_mutex); 735 + /* We can't use a devm_alloc reusable buffer without side effects during suspend */ 736 + dmabuf = kzalloc(GO_PACKET_SIZE, GFP_KERNEL); 737 + if (!dmabuf) 738 + return -ENOMEM; 739 + 740 + memcpy(dmabuf, header, header_size); 741 + memcpy(dmabuf + header_size, data, len); 742 + 743 + dev_dbg(&hdev->dev, "Send data as raw output report: [%*ph]\n", 744 + GO_PACKET_SIZE, dmabuf); 745 + 746 + ret = hid_hw_output_report(hdev, dmabuf, GO_PACKET_SIZE); 747 + if (ret < 0) 748 + return ret; 749 + 750 + ret = ret == GO_PACKET_SIZE ? 0 : -EINVAL; 751 + if (ret) 752 + return ret; 753 + 754 + ret = wait_for_completion_interruptible_timeout(&drvdata.send_cmd_complete, 755 + msecs_to_jiffies(timeout)); 756 + 757 + if (ret == 0) /* timeout occurred */ 758 + ret = -EBUSY; 759 + 760 + reinit_completion(&drvdata.send_cmd_complete); 761 + return 0; 762 + } 763 + 764 + static ssize_t version_show(struct device *dev, struct device_attribute *attr, 765 + char *buf, enum version_data_index index, 766 + enum dev_type device_type) 767 + { 768 + ssize_t count = 0; 769 + int ret; 770 + 771 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 772 + index, device_type, NULL, 0); 773 + if (ret) 774 + return ret; 775 + 776 + switch (index) { 777 + case PRODUCT_VERSION: 778 + switch (device_type) { 779 + case USB_MCU: 780 + count = sysfs_emit(buf, "%x\n", 781 + drvdata.mcu_version_product); 782 + break; 783 + case TX_DONGLE: 784 + count = sysfs_emit(buf, "%x\n", 785 + drvdata.tx_dongle_version_product); 786 + break; 787 + case LEFT_CONTROLLER: 788 + count = sysfs_emit(buf, "%x\n", 789 + drvdata.gp_left_version_product); 790 + break; 791 + case RIGHT_CONTROLLER: 792 + count = sysfs_emit(buf, "%x\n", 793 + drvdata.gp_right_version_product); 794 + break; 795 + default: 796 + return -EINVAL; 797 + } 798 + break; 799 + case PROTOCOL_VERSION: 800 + switch (device_type) { 801 + case USB_MCU: 802 + count = sysfs_emit(buf, "%x\n", 803 + drvdata.mcu_version_protocol); 804 + break; 805 + case TX_DONGLE: 806 + count = sysfs_emit(buf, "%x\n", 807 + drvdata.tx_dongle_version_protocol); 808 + break; 809 + case LEFT_CONTROLLER: 810 + count = sysfs_emit(buf, "%x\n", 811 + drvdata.gp_left_version_protocol); 812 + break; 813 + case RIGHT_CONTROLLER: 814 + count = sysfs_emit(buf, "%x\n", 815 + drvdata.gp_right_version_protocol); 816 + break; 817 + default: 818 + return -EINVAL; 819 + } 820 + break; 821 + case FIRMWARE_VERSION: 822 + switch (device_type) { 823 + case USB_MCU: 824 + count = sysfs_emit(buf, "%x\n", 825 + drvdata.mcu_version_firmware); 826 + break; 827 + case TX_DONGLE: 828 + count = sysfs_emit(buf, "%x\n", 829 + drvdata.tx_dongle_version_firmware); 830 + break; 831 + case LEFT_CONTROLLER: 832 + count = sysfs_emit(buf, "%x\n", 833 + drvdata.gp_left_version_firmware); 834 + break; 835 + case RIGHT_CONTROLLER: 836 + count = sysfs_emit(buf, "%x\n", 837 + drvdata.gp_right_version_firmware); 838 + break; 839 + default: 840 + return -EINVAL; 841 + } 842 + break; 843 + case HARDWARE_VERSION: 844 + switch (device_type) { 845 + case USB_MCU: 846 + count = sysfs_emit(buf, "%x\n", 847 + drvdata.mcu_version_hardware); 848 + break; 849 + case TX_DONGLE: 850 + count = sysfs_emit(buf, "%x\n", 851 + drvdata.tx_dongle_version_hardware); 852 + break; 853 + case LEFT_CONTROLLER: 854 + count = sysfs_emit(buf, "%x\n", 855 + drvdata.gp_left_version_hardware); 856 + break; 857 + case RIGHT_CONTROLLER: 858 + count = sysfs_emit(buf, "%x\n", 859 + drvdata.gp_right_version_hardware); 860 + break; 861 + default: 862 + return -EINVAL; 863 + } 864 + break; 865 + case HARDWARE_GENERATION: 866 + switch (device_type) { 867 + case USB_MCU: 868 + count = sysfs_emit(buf, "%x\n", 869 + drvdata.mcu_version_gen); 870 + break; 871 + case TX_DONGLE: 872 + count = sysfs_emit(buf, "%x\n", 873 + drvdata.tx_dongle_version_gen); 874 + break; 875 + case LEFT_CONTROLLER: 876 + count = sysfs_emit(buf, "%x\n", 877 + drvdata.gp_left_version_gen); 878 + break; 879 + case RIGHT_CONTROLLER: 880 + count = sysfs_emit(buf, "%x\n", 881 + drvdata.gp_right_version_gen); 882 + break; 883 + default: 884 + return -EINVAL; 885 + } 886 + break; 887 + } 888 + 889 + return count; 890 + } 891 + 892 + static ssize_t feature_status_store(struct device *dev, 893 + struct device_attribute *attr, 894 + const char *buf, size_t count, 895 + enum feature_status_index index, 896 + enum dev_type device_type) 897 + { 898 + size_t size = 1; 899 + u8 val = 0; 900 + int ret; 901 + 902 + switch (index) { 903 + case FEATURE_IMU_ENABLE: 904 + case FEATURE_IMU_BYPASS: 905 + case FEATURE_LIGHT_ENABLE: 906 + case FEATURE_TOUCHPAD_ENABLE: 907 + ret = sysfs_match_string(enabled_status_text, buf); 908 + val = ret; 909 + break; 910 + case FEATURE_AUTO_SLEEP_TIME: 911 + ret = kstrtou8(buf, 10, &val); 912 + break; 913 + case FEATURE_RESET_GAMEPAD: 914 + ret = kstrtou8(buf, 10, &val); 915 + if (val != GO_GP_RESET_SUCCESS) 916 + return -EINVAL; 917 + break; 918 + case FEATURE_FPS_SWITCH_STATUS: 919 + ret = sysfs_match_string(fps_switch_text, buf); 920 + val = ret; 921 + break; 922 + case FEATURE_GAMEPAD_MODE: 923 + ret = sysfs_match_string(gamepad_mode_text, buf); 924 + val = ret; 925 + break; 926 + default: 927 + return -EINVAL; 928 + } 929 + 930 + if (ret < 0) 931 + return ret; 932 + 933 + if (!val) 934 + size = 0; 935 + 936 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, 937 + SET_FEATURE_STATUS, index, device_type, &val, 938 + size); 939 + if (ret < 0) 940 + return ret; 941 + 942 + return count; 943 + } 944 + 945 + static ssize_t feature_status_show(struct device *dev, 946 + struct device_attribute *attr, char *buf, 947 + enum feature_status_index index, 948 + enum dev_type device_type) 949 + { 950 + ssize_t count = 0; 951 + int ret; 952 + u8 i; 953 + 954 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, 955 + GET_FEATURE_STATUS, index, device_type, NULL, 0); 956 + if (ret) 957 + return ret; 958 + 959 + switch (index) { 960 + case FEATURE_IMU_ENABLE: 961 + switch (device_type) { 962 + case LEFT_CONTROLLER: 963 + i = drvdata.imu_left_sensor_en; 964 + break; 965 + case RIGHT_CONTROLLER: 966 + i = drvdata.imu_right_sensor_en; 967 + break; 968 + default: 969 + return -EINVAL; 970 + } 971 + if (i >= ARRAY_SIZE(enabled_status_text)) 972 + return -EINVAL; 973 + 974 + count = sysfs_emit(buf, "%s\n", enabled_status_text[i]); 975 + break; 976 + case FEATURE_IMU_BYPASS: 977 + switch (device_type) { 978 + case LEFT_CONTROLLER: 979 + i = drvdata.imu_left_bypass_en; 980 + break; 981 + case RIGHT_CONTROLLER: 982 + i = drvdata.imu_right_bypass_en; 983 + break; 984 + default: 985 + return -EINVAL; 986 + } 987 + if (i >= ARRAY_SIZE(enabled_status_text)) 988 + return -EINVAL; 989 + 990 + count = sysfs_emit(buf, "%s\n", enabled_status_text[i]); 991 + break; 992 + case FEATURE_LIGHT_ENABLE: 993 + i = drvdata.rgb_en; 994 + if (i >= ARRAY_SIZE(enabled_status_text)) 995 + return -EINVAL; 996 + 997 + count = sysfs_emit(buf, "%s\n", enabled_status_text[i]); 998 + break; 999 + case FEATURE_TOUCHPAD_ENABLE: 1000 + i = drvdata.tp_en; 1001 + if (i >= ARRAY_SIZE(enabled_status_text)) 1002 + return -EINVAL; 1003 + 1004 + count = sysfs_emit(buf, "%s\n", enabled_status_text[i]); 1005 + break; 1006 + case FEATURE_AUTO_SLEEP_TIME: 1007 + switch (device_type) { 1008 + case LEFT_CONTROLLER: 1009 + i = drvdata.gp_left_auto_sleep_time; 1010 + break; 1011 + case RIGHT_CONTROLLER: 1012 + i = drvdata.gp_right_auto_sleep_time; 1013 + break; 1014 + default: 1015 + return -EINVAL; 1016 + } 1017 + count = sysfs_emit(buf, "%u\n", i); 1018 + break; 1019 + case FEATURE_FPS_SWITCH_STATUS: 1020 + i = drvdata.fps_mode; 1021 + if (i >= ARRAY_SIZE(fps_switch_text)) 1022 + return -EINVAL; 1023 + 1024 + count = sysfs_emit(buf, "%s\n", fps_switch_text[i]); 1025 + break; 1026 + case FEATURE_GAMEPAD_MODE: 1027 + i = drvdata.gp_mode; 1028 + if (i >= ARRAY_SIZE(gamepad_mode_text)) 1029 + return -EINVAL; 1030 + 1031 + count = sysfs_emit(buf, "%s\n", gamepad_mode_text[i]); 1032 + break; 1033 + default: 1034 + return -EINVAL; 1035 + } 1036 + 1037 + return count; 1038 + } 1039 + 1040 + static ssize_t feature_status_options(struct device *dev, 1041 + struct device_attribute *attr, char *buf, 1042 + enum feature_status_index index) 1043 + { 1044 + ssize_t count = 0; 1045 + unsigned int i; 1046 + 1047 + switch (index) { 1048 + case FEATURE_IMU_ENABLE: 1049 + case FEATURE_IMU_BYPASS: 1050 + case FEATURE_LIGHT_ENABLE: 1051 + case FEATURE_TOUCHPAD_ENABLE: 1052 + for (i = 1; i < ARRAY_SIZE(enabled_status_text); i++) { 1053 + count += sysfs_emit_at(buf, count, "%s ", 1054 + enabled_status_text[i]); 1055 + } 1056 + break; 1057 + case FEATURE_AUTO_SLEEP_TIME: 1058 + return sysfs_emit(buf, "0-255\n"); 1059 + case FEATURE_FPS_SWITCH_STATUS: 1060 + for (i = 1; i < ARRAY_SIZE(fps_switch_text); i++) { 1061 + count += sysfs_emit_at(buf, count, "%s ", 1062 + fps_switch_text[i]); 1063 + } 1064 + break; 1065 + case FEATURE_GAMEPAD_MODE: 1066 + for (i = 1; i < ARRAY_SIZE(gamepad_mode_text); i++) { 1067 + count += sysfs_emit_at(buf, count, "%s ", 1068 + gamepad_mode_text[i]); 1069 + } 1070 + break; 1071 + default: 1072 + return -EINVAL; 1073 + } 1074 + 1075 + if (count) 1076 + buf[count - 1] = '\n'; 1077 + 1078 + return count; 1079 + } 1080 + 1081 + static ssize_t motor_config_store(struct device *dev, 1082 + struct device_attribute *attr, 1083 + const char *buf, size_t count, 1084 + enum motor_cfg_index index, 1085 + enum dev_type device_type) 1086 + { 1087 + size_t size = 1; 1088 + u8 val = 0; 1089 + int ret; 1090 + 1091 + switch (index) { 1092 + case MOTOR_CFG_ALL: 1093 + return -EINVAL; 1094 + case MOTOR_INTENSITY: 1095 + ret = sysfs_match_string(intensity_text, buf); 1096 + val = ret; 1097 + break; 1098 + case VIBRATION_NOTIFY_ENABLE: 1099 + ret = sysfs_match_string(enabled_status_text, buf); 1100 + val = ret; 1101 + break; 1102 + case RUMBLE_MODE: 1103 + ret = sysfs_match_string(rumble_mode_text, buf); 1104 + val = ret; 1105 + break; 1106 + case TP_VIBRATION_ENABLE: 1107 + ret = sysfs_match_string(enabled_status_text, buf); 1108 + val = ret; 1109 + break; 1110 + case TP_VIBRATION_INTENSITY: 1111 + ret = sysfs_match_string(intensity_text, buf); 1112 + val = ret; 1113 + break; 1114 + } 1115 + 1116 + if (ret < 0) 1117 + return ret; 1118 + 1119 + if (!val) 1120 + size = 0; 1121 + 1122 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, SET_MOTOR_CFG, 1123 + index, device_type, &val, size); 1124 + if (ret < 0) 1125 + return ret; 1126 + 1127 + return count; 1128 + } 1129 + 1130 + static ssize_t motor_config_show(struct device *dev, 1131 + struct device_attribute *attr, char *buf, 1132 + enum motor_cfg_index index, 1133 + enum dev_type device_type) 1134 + { 1135 + ssize_t count = 0; 1136 + int ret; 1137 + u8 i; 1138 + 1139 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_MOTOR_CFG, 1140 + index, device_type, NULL, 0); 1141 + if (ret) 1142 + return ret; 1143 + 1144 + switch (index) { 1145 + case MOTOR_CFG_ALL: 1146 + return -EINVAL; 1147 + case MOTOR_INTENSITY: 1148 + i = drvdata.gp_rumble_intensity; 1149 + if (i >= ARRAY_SIZE(intensity_text)) 1150 + return -EINVAL; 1151 + 1152 + count = sysfs_emit(buf, "%s\n", intensity_text[i]); 1153 + break; 1154 + case VIBRATION_NOTIFY_ENABLE: 1155 + switch (device_type) { 1156 + case LEFT_CONTROLLER: 1157 + i = drvdata.gp_left_notify_en; 1158 + break; 1159 + case RIGHT_CONTROLLER: 1160 + i = drvdata.gp_right_notify_en; 1161 + break; 1162 + default: 1163 + return -EINVAL; 1164 + } 1165 + if (i >= ARRAY_SIZE(enabled_status_text)) 1166 + return -EINVAL; 1167 + 1168 + count = sysfs_emit(buf, "%s\n", enabled_status_text[i]); 1169 + break; 1170 + case RUMBLE_MODE: 1171 + switch (device_type) { 1172 + case LEFT_CONTROLLER: 1173 + i = drvdata.gp_left_rumble_mode; 1174 + break; 1175 + case RIGHT_CONTROLLER: 1176 + i = drvdata.gp_right_rumble_mode; 1177 + break; 1178 + default: 1179 + return -EINVAL; 1180 + } 1181 + if (i >= ARRAY_SIZE(rumble_mode_text)) 1182 + return -EINVAL; 1183 + 1184 + count = sysfs_emit(buf, "%s\n", rumble_mode_text[i]); 1185 + break; 1186 + case TP_VIBRATION_ENABLE: 1187 + i = drvdata.tp_vibration_en; 1188 + if (i >= ARRAY_SIZE(enabled_status_text)) 1189 + return -EINVAL; 1190 + 1191 + count = sysfs_emit(buf, "%s\n", enabled_status_text[i]); 1192 + break; 1193 + case TP_VIBRATION_INTENSITY: 1194 + i = drvdata.tp_vibration_intensity; 1195 + if (i >= ARRAY_SIZE(intensity_text)) 1196 + return -EINVAL; 1197 + 1198 + count = sysfs_emit(buf, "%s\n", intensity_text[i]); 1199 + break; 1200 + } 1201 + 1202 + return count; 1203 + } 1204 + 1205 + static ssize_t motor_config_options(struct device *dev, 1206 + struct device_attribute *attr, char *buf, 1207 + enum motor_cfg_index index) 1208 + { 1209 + ssize_t count = 0; 1210 + unsigned int i; 1211 + 1212 + switch (index) { 1213 + case MOTOR_CFG_ALL: 1214 + break; 1215 + case RUMBLE_MODE: 1216 + for (i = 1; i < ARRAY_SIZE(rumble_mode_text); i++) { 1217 + count += sysfs_emit_at(buf, count, "%s ", 1218 + rumble_mode_text[i]); 1219 + } 1220 + break; 1221 + case MOTOR_INTENSITY: 1222 + case TP_VIBRATION_INTENSITY: 1223 + for (i = 1; i < ARRAY_SIZE(intensity_text); i++) { 1224 + count += sysfs_emit_at(buf, count, "%s ", 1225 + intensity_text[i]); 1226 + } 1227 + break; 1228 + case VIBRATION_NOTIFY_ENABLE: 1229 + case TP_VIBRATION_ENABLE: 1230 + for (i = 1; i < ARRAY_SIZE(enabled_status_text); i++) { 1231 + count += sysfs_emit_at(buf, count, "%s ", 1232 + enabled_status_text[i]); 1233 + } 1234 + break; 1235 + } 1236 + 1237 + if (count) 1238 + buf[count - 1] = '\n'; 1239 + 1240 + return count; 1241 + } 1242 + 1243 + static ssize_t fps_mode_dpi_store(struct device *dev, 1244 + struct device_attribute *attr, 1245 + const char *buf, size_t count) 1246 + 1247 + { 1248 + size_t size = 4; 1249 + u32 value; 1250 + u8 val[4]; 1251 + int ret; 1252 + 1253 + ret = kstrtou32(buf, 10, &value); 1254 + if (ret) 1255 + return ret; 1256 + 1257 + if (value != 500 && value != 800 && value != 1200 && value != 1800) 1258 + return -EINVAL; 1259 + 1260 + put_unaligned_le32(value, val); 1261 + 1262 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, SET_DPI_CFG, 1263 + FPS_MODE_DPI, UNSPECIFIED, val, size); 1264 + if (ret < 0) 1265 + return ret; 1266 + 1267 + return count; 1268 + } 1269 + 1270 + static ssize_t fps_mode_dpi_show(struct device *dev, 1271 + struct device_attribute *attr, char *buf) 1272 + { 1273 + int ret; 1274 + 1275 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_DPI_CFG, 1276 + FPS_MODE_DPI, UNSPECIFIED, NULL, 0); 1277 + if (ret < 0) 1278 + return ret; 1279 + 1280 + return sysfs_emit(buf, "%u\n", drvdata.mouse_dpi); 1281 + } 1282 + 1283 + static ssize_t fps_mode_dpi_index_show(struct device *dev, 1284 + struct device_attribute *attr, char *buf) 1285 + { 1286 + return sysfs_emit(buf, "500 800 1200 1800\n"); 1287 + } 1288 + 1289 + static ssize_t device_status_show(struct device *dev, 1290 + struct device_attribute *attr, char *buf, 1291 + enum device_status_index index, 1292 + enum dev_type device_type, 1293 + enum cal_device_type cal_type) 1294 + { 1295 + u8 i; 1296 + 1297 + switch (index) { 1298 + case GET_CAL_STATUS: 1299 + switch (device_type) { 1300 + case LEFT_CONTROLLER: 1301 + switch (cal_type) { 1302 + case CALDEV_GYROSCOPE: 1303 + i = drvdata.gp_left_gyro_cal_status; 1304 + break; 1305 + case CALDEV_JOYSTICK: 1306 + i = drvdata.gp_left_joy_cal_status; 1307 + break; 1308 + case CALDEV_TRIGGER: 1309 + i = drvdata.gp_left_trigg_cal_status; 1310 + break; 1311 + default: 1312 + return -EINVAL; 1313 + } 1314 + break; 1315 + case RIGHT_CONTROLLER: 1316 + switch (cal_type) { 1317 + case CALDEV_GYROSCOPE: 1318 + i = drvdata.gp_right_gyro_cal_status; 1319 + break; 1320 + case CALDEV_JOYSTICK: 1321 + i = drvdata.gp_right_joy_cal_status; 1322 + break; 1323 + case CALDEV_TRIGGER: 1324 + i = drvdata.gp_right_trigg_cal_status; 1325 + break; 1326 + default: 1327 + return -EINVAL; 1328 + } 1329 + break; 1330 + default: 1331 + return -EINVAL; 1332 + } 1333 + break; 1334 + default: 1335 + return -EINVAL; 1336 + } 1337 + 1338 + if (i >= ARRAY_SIZE(cal_status_text)) 1339 + return -EINVAL; 1340 + 1341 + return sysfs_emit(buf, "%s\n", cal_status_text[i]); 1342 + } 1343 + 1344 + static ssize_t calibrate_config_store(struct device *dev, 1345 + struct device_attribute *attr, 1346 + const char *buf, u8 cmd, u8 sub_cmd, 1347 + size_t count, enum dev_type device_type) 1348 + { 1349 + size_t size = 1; 1350 + u8 val = 0; 1351 + int ret; 1352 + 1353 + ret = sysfs_match_string(cal_enabled_text, buf); 1354 + if (ret < 0) 1355 + return ret; 1356 + 1357 + val = ret; 1358 + if (!val) 1359 + size = 0; 1360 + 1361 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, cmd, sub_cmd, 1362 + device_type, &val, size); 1363 + if (ret < 0) 1364 + return ret; 1365 + 1366 + return count; 1367 + } 1368 + 1369 + static ssize_t calibrate_config_options(struct device *dev, 1370 + struct device_attribute *attr, 1371 + char *buf) 1372 + { 1373 + ssize_t count = 0; 1374 + unsigned int i; 1375 + 1376 + for (i = 1; i < ARRAY_SIZE(cal_enabled_text); i++) 1377 + count += sysfs_emit_at(buf, count, "%s ", cal_enabled_text[i]); 1378 + 1379 + buf[count - 1] = '\n'; 1380 + 1381 + return count; 1382 + } 1383 + 1384 + static ssize_t os_mode_store(struct device *dev, struct device_attribute *attr, 1385 + const char *buf, size_t count) 1386 + { 1387 + size_t size = 1; 1388 + int ret; 1389 + u8 val; 1390 + 1391 + ret = sysfs_match_string(os_mode_text, buf); 1392 + if (ret <= 0) 1393 + return ret; 1394 + 1395 + val = ret; 1396 + ret = mcu_property_out(drvdata.hdev, OS_MODE_DATA, FEATURE_OS_MODE, 1397 + SET_OS_MODE, USB_MCU, &val, size); 1398 + if (ret < 0) 1399 + return ret; 1400 + 1401 + drvdata.os_mode = val; 1402 + 1403 + return count; 1404 + } 1405 + 1406 + static ssize_t os_mode_show(struct device *dev, struct device_attribute *attr, 1407 + char *buf) 1408 + { 1409 + ssize_t count = 0; 1410 + int ret; 1411 + u8 i; 1412 + 1413 + ret = mcu_property_out(drvdata.hdev, OS_MODE_DATA, FEATURE_OS_MODE, 1414 + GET_OS_MODE, USB_MCU, NULL, 0); 1415 + if (ret) 1416 + return ret; 1417 + 1418 + i = drvdata.os_mode; 1419 + if (i >= ARRAY_SIZE(os_mode_text)) 1420 + return -EINVAL; 1421 + 1422 + count = sysfs_emit(buf, "%s\n", os_mode_text[i]); 1423 + 1424 + return count; 1425 + } 1426 + 1427 + static ssize_t os_mode_index_show(struct device *dev, 1428 + struct device_attribute *attr, char *buf) 1429 + { 1430 + ssize_t count = 0; 1431 + unsigned int i; 1432 + 1433 + for (i = 1; i < ARRAY_SIZE(os_mode_text); i++) 1434 + count += sysfs_emit_at(buf, count, "%s ", os_mode_text[i]); 1435 + 1436 + if (count) 1437 + buf[count - 1] = '\n'; 1438 + 1439 + return count; 1440 + } 1441 + 1442 + static int rgb_cfg_call(struct hid_device *hdev, enum mcu_command_index cmd, 1443 + enum rgb_config_index index, u8 *val, size_t size) 1444 + { 1445 + if (cmd != SET_RGB_CFG && cmd != GET_RGB_CFG) 1446 + return -EINVAL; 1447 + 1448 + if (index < LIGHT_CFG_ALL || index > USR_LIGHT_PROFILE_3) 1449 + return -EINVAL; 1450 + 1451 + return mcu_property_out(hdev, MCU_CONFIG_DATA, cmd, index, UNSPECIFIED, 1452 + val, size); 1453 + } 1454 + 1455 + static int rgb_attr_show(void) 1456 + { 1457 + enum rgb_config_index index; 1458 + 1459 + index = drvdata.rgb_profile + 3; 1460 + 1461 + return rgb_cfg_call(drvdata.hdev, GET_RGB_CFG, index, NULL, 0); 1462 + } 1463 + 1464 + static ssize_t rgb_effect_store(struct device *dev, 1465 + struct device_attribute *attr, const char *buf, 1466 + size_t count) 1467 + { 1468 + struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(drvdata.led_cdev); 1469 + enum rgb_config_index index; 1470 + u8 effect; 1471 + int ret; 1472 + 1473 + ret = sysfs_match_string(rgb_effect_text, buf); 1474 + if (ret < 0) 1475 + return ret; 1476 + 1477 + effect = ret; 1478 + index = drvdata.rgb_profile + 3; 1479 + u8 rgb_profile[6] = { effect, 1480 + mc_cdev->subled_info[0].intensity, 1481 + mc_cdev->subled_info[1].intensity, 1482 + mc_cdev->subled_info[2].intensity, 1483 + drvdata.led_cdev->brightness, 1484 + drvdata.rgb_speed }; 1485 + 1486 + ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, index, rgb_profile, 6); 1487 + if (ret) 1488 + return ret; 1489 + 1490 + drvdata.rgb_effect = effect; 1491 + return count; 1492 + } 1493 + 1494 + static ssize_t rgb_effect_show(struct device *dev, 1495 + struct device_attribute *attr, char *buf) 1496 + { 1497 + int ret; 1498 + 1499 + ret = rgb_attr_show(); 1500 + if (ret) 1501 + return ret; 1502 + 1503 + if (drvdata.rgb_effect >= ARRAY_SIZE(rgb_effect_text)) 1504 + return -EINVAL; 1505 + 1506 + return sysfs_emit(buf, "%s\n", rgb_effect_text[drvdata.rgb_effect]); 1507 + } 1508 + 1509 + static ssize_t rgb_effect_index_show(struct device *dev, 1510 + struct device_attribute *attr, char *buf) 1511 + { 1512 + ssize_t count = 0; 1513 + unsigned int i; 1514 + 1515 + for (i = 0; i < ARRAY_SIZE(rgb_effect_text); i++) 1516 + count += sysfs_emit_at(buf, count, "%s ", rgb_effect_text[i]); 1517 + 1518 + if (count) 1519 + buf[count - 1] = '\n'; 1520 + 1521 + return count; 1522 + } 1523 + 1524 + static ssize_t rgb_speed_store(struct device *dev, 1525 + struct device_attribute *attr, const char *buf, 1526 + size_t count) 1527 + { 1528 + struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(drvdata.led_cdev); 1529 + enum rgb_config_index index; 1530 + int val = 0; 1531 + int ret; 1532 + 1533 + ret = kstrtoint(buf, 10, &val); 1534 + if (ret) 1535 + return ret; 1536 + 1537 + if (val < 0 || val > 100) 1538 + return -EINVAL; 1539 + 1540 + /* This is a delay setting, invert logic for consistency with other drivers */ 1541 + val = 100 - val; 1542 + 1543 + index = drvdata.rgb_profile + 3; 1544 + u8 rgb_profile[6] = { drvdata.rgb_effect, 1545 + mc_cdev->subled_info[0].intensity, 1546 + mc_cdev->subled_info[1].intensity, 1547 + mc_cdev->subled_info[2].intensity, 1548 + drvdata.led_cdev->brightness, 1549 + val }; 1550 + 1551 + ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, index, rgb_profile, 6); 1552 + if (ret) 1553 + return ret; 1554 + 1555 + drvdata.rgb_speed = val; 1556 + 1557 + return count; 1558 + } 1559 + 1560 + static ssize_t rgb_speed_show(struct device *dev, struct device_attribute *attr, 1561 + char *buf) 1562 + { 1563 + int ret, val; 1564 + 1565 + ret = rgb_attr_show(); 1566 + if (ret) 1567 + return ret; 1568 + 1569 + if (drvdata.rgb_speed > 100) 1570 + return -EINVAL; 1571 + 1572 + val = drvdata.rgb_speed; 1573 + 1574 + return sysfs_emit(buf, "%hhu\n", val); 1575 + } 1576 + 1577 + static ssize_t rgb_speed_range_show(struct device *dev, 1578 + struct device_attribute *attr, char *buf) 1579 + { 1580 + return sysfs_emit(buf, "0-100\n"); 1581 + } 1582 + 1583 + static ssize_t rgb_mode_store(struct device *dev, struct device_attribute *attr, 1584 + const char *buf, size_t count) 1585 + { 1586 + int ret; 1587 + u8 val; 1588 + 1589 + ret = sysfs_match_string(rgb_mode_text, buf); 1590 + if (ret <= 0) 1591 + return ret; 1592 + 1593 + val = ret; 1594 + 1595 + ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, LIGHT_MODE_SEL, &val, 1); 1596 + if (ret) 1597 + return ret; 1598 + 1599 + drvdata.rgb_mode = val; 1600 + 1601 + return count; 1602 + } 1603 + 1604 + static ssize_t rgb_mode_show(struct device *dev, struct device_attribute *attr, 1605 + char *buf) 1606 + { 1607 + int ret; 1608 + 1609 + ret = rgb_cfg_call(drvdata.hdev, GET_RGB_CFG, LIGHT_MODE_SEL, NULL, 0); 1610 + if (ret) 1611 + return ret; 1612 + 1613 + if (drvdata.rgb_mode >= ARRAY_SIZE(rgb_mode_text)) 1614 + return -EINVAL; 1615 + 1616 + return sysfs_emit(buf, "%s\n", rgb_mode_text[drvdata.rgb_mode]); 1617 + } 1618 + 1619 + static ssize_t rgb_mode_index_show(struct device *dev, 1620 + struct device_attribute *attr, char *buf) 1621 + { 1622 + ssize_t count = 0; 1623 + unsigned int i; 1624 + 1625 + for (i = 1; i < ARRAY_SIZE(rgb_mode_text); i++) 1626 + count += sysfs_emit_at(buf, count, "%s ", rgb_mode_text[i]); 1627 + 1628 + if (count) 1629 + buf[count - 1] = '\n'; 1630 + 1631 + return count; 1632 + } 1633 + 1634 + static ssize_t rgb_profile_store(struct device *dev, 1635 + struct device_attribute *attr, const char *buf, 1636 + size_t count) 1637 + { 1638 + size_t size = 1; 1639 + int ret; 1640 + u8 val; 1641 + 1642 + ret = kstrtou8(buf, 10, &val); 1643 + if (ret < 0) 1644 + return ret; 1645 + 1646 + if (val < 1 || val > 3) 1647 + return -EINVAL; 1648 + 1649 + ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, LIGHT_PROFILE_SEL, &val, size); 1650 + if (ret) 1651 + return ret; 1652 + 1653 + drvdata.rgb_profile = val; 1654 + 1655 + return count; 1656 + } 1657 + 1658 + static ssize_t rgb_profile_show(struct device *dev, 1659 + struct device_attribute *attr, char *buf) 1660 + { 1661 + int ret; 1662 + 1663 + ret = rgb_cfg_call(drvdata.hdev, GET_RGB_CFG, LIGHT_PROFILE_SEL, NULL, 0); 1664 + if (ret) 1665 + return ret; 1666 + 1667 + if (drvdata.rgb_profile < 1 || drvdata.rgb_profile > 3) 1668 + return -EINVAL; 1669 + 1670 + return sysfs_emit(buf, "%hhu\n", drvdata.rgb_profile); 1671 + } 1672 + 1673 + static ssize_t rgb_profile_range_show(struct device *dev, 1674 + struct device_attribute *attr, char *buf) 1675 + { 1676 + return sysfs_emit(buf, "1-3\n"); 1677 + } 1678 + 1679 + static void hid_go_brightness_set(struct led_classdev *led_cdev, 1680 + enum led_brightness brightness) 1681 + { 1682 + struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(drvdata.led_cdev); 1683 + enum rgb_config_index index; 1684 + int ret; 1685 + 1686 + if (brightness > led_cdev->max_brightness) { 1687 + dev_err(led_cdev->dev, "Invalid argument\n"); 1688 + return; 1689 + } 1690 + 1691 + index = drvdata.rgb_profile + 3; 1692 + u8 rgb_profile[6] = { drvdata.rgb_effect, 1693 + mc_cdev->subled_info[0].intensity, 1694 + mc_cdev->subled_info[1].intensity, 1695 + mc_cdev->subled_info[2].intensity, 1696 + brightness, 1697 + drvdata.rgb_speed }; 1698 + 1699 + ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, index, rgb_profile, 6); 1700 + switch (ret) { 1701 + case 0: 1702 + led_cdev->brightness = brightness; 1703 + break; 1704 + case -ENODEV: /* during switch to IAP -ENODEV is expected */ 1705 + case -ENOSYS: /* during rmmod -ENOSYS is expected */ 1706 + dev_dbg(led_cdev->dev, "Failed to write RGB profile: %i\n", ret); 1707 + break; 1708 + default: 1709 + dev_err(led_cdev->dev, "Failed to write RGB profile: %i\n", ret); 1710 + } 1711 + } 1712 + 1713 + #define LEGO_DEVICE_ATTR_RW(_name, _attrname, _dtype, _rtype, _group) \ 1714 + static ssize_t _name##_store(struct device *dev, \ 1715 + struct device_attribute *attr, \ 1716 + const char *buf, size_t count) \ 1717 + { \ 1718 + return _group##_store(dev, attr, buf, count, _name.index, \ 1719 + _dtype); \ 1720 + } \ 1721 + static ssize_t _name##_show(struct device *dev, \ 1722 + struct device_attribute *attr, char *buf) \ 1723 + { \ 1724 + return _group##_show(dev, attr, buf, _name.index, _dtype); \ 1725 + } \ 1726 + static ssize_t _name##_##_rtype##_show( \ 1727 + struct device *dev, struct device_attribute *attr, char *buf) \ 1728 + { \ 1729 + return _group##_options(dev, attr, buf, _name.index); \ 1730 + } \ 1731 + static DEVICE_ATTR_RW_NAMED(_name, _attrname) 1732 + 1733 + #define LEGO_DEVICE_ATTR_WO(_name, _attrname, _dtype, _group) \ 1734 + static ssize_t _name##_store(struct device *dev, \ 1735 + struct device_attribute *attr, \ 1736 + const char *buf, size_t count) \ 1737 + { \ 1738 + return _group##_store(dev, attr, buf, count, _name.index, \ 1739 + _dtype); \ 1740 + } \ 1741 + static DEVICE_ATTR_WO_NAMED(_name, _attrname) 1742 + 1743 + #define LEGO_DEVICE_ATTR_RO(_name, _attrname, _dtype, _group) \ 1744 + static ssize_t _name##_show(struct device *dev, \ 1745 + struct device_attribute *attr, char *buf) \ 1746 + { \ 1747 + return _group##_show(dev, attr, buf, _name.index, _dtype); \ 1748 + } \ 1749 + static DEVICE_ATTR_RO_NAMED(_name, _attrname) 1750 + 1751 + #define LEGO_CAL_DEVICE_ATTR(_name, _attrname, _scmd, _dtype, _rtype) \ 1752 + static ssize_t _name##_store(struct device *dev, \ 1753 + struct device_attribute *attr, \ 1754 + const char *buf, size_t count) \ 1755 + { \ 1756 + return calibrate_config_store(dev, attr, buf, _name.index, \ 1757 + _scmd, count, _dtype); \ 1758 + } \ 1759 + static ssize_t _name##_##_rtype##_show( \ 1760 + struct device *dev, struct device_attribute *attr, char *buf) \ 1761 + { \ 1762 + return calibrate_config_options(dev, attr, buf); \ 1763 + } \ 1764 + static DEVICE_ATTR_WO_NAMED(_name, _attrname) 1765 + 1766 + #define LEGO_DEVICE_STATUS_ATTR(_name, _attrname, _scmd, _dtype) \ 1767 + static ssize_t _name##_show(struct device *dev, \ 1768 + struct device_attribute *attr, char *buf) \ 1769 + { \ 1770 + return device_status_show(dev, attr, buf, _name.index, _scmd, \ 1771 + _dtype); \ 1772 + } \ 1773 + static DEVICE_ATTR_RO_NAMED(_name, _attrname) 1774 + 1775 + /* Gamepad - MCU */ 1776 + static struct go_cfg_attr version_product_mcu = { PRODUCT_VERSION }; 1777 + LEGO_DEVICE_ATTR_RO(version_product_mcu, "product_version", USB_MCU, version); 1778 + 1779 + static struct go_cfg_attr version_protocol_mcu = { PROTOCOL_VERSION }; 1780 + LEGO_DEVICE_ATTR_RO(version_protocol_mcu, "protocol_version", USB_MCU, version); 1781 + 1782 + static struct go_cfg_attr version_firmware_mcu = { FIRMWARE_VERSION }; 1783 + LEGO_DEVICE_ATTR_RO(version_firmware_mcu, "firmware_version", USB_MCU, version); 1784 + 1785 + static struct go_cfg_attr version_hardware_mcu = { HARDWARE_VERSION }; 1786 + LEGO_DEVICE_ATTR_RO(version_hardware_mcu, "hardware_version", USB_MCU, version); 1787 + 1788 + static struct go_cfg_attr version_gen_mcu = { HARDWARE_GENERATION }; 1789 + LEGO_DEVICE_ATTR_RO(version_gen_mcu, "hardware_generation", USB_MCU, version); 1790 + 1791 + static struct go_cfg_attr fps_switch_status = { FEATURE_FPS_SWITCH_STATUS }; 1792 + LEGO_DEVICE_ATTR_RO(fps_switch_status, "fps_switch_status", UNSPECIFIED, 1793 + feature_status); 1794 + 1795 + static struct go_cfg_attr gamepad_mode = { FEATURE_GAMEPAD_MODE }; 1796 + LEGO_DEVICE_ATTR_RW(gamepad_mode, "mode", UNSPECIFIED, index, feature_status); 1797 + static DEVICE_ATTR_RO_NAMED(gamepad_mode_index, "mode_index"); 1798 + 1799 + static struct go_cfg_attr reset_mcu = { FEATURE_RESET_GAMEPAD }; 1800 + LEGO_DEVICE_ATTR_WO(reset_mcu, "reset_mcu", USB_MCU, feature_status); 1801 + 1802 + static struct go_cfg_attr gamepad_rumble_intensity = { MOTOR_INTENSITY }; 1803 + LEGO_DEVICE_ATTR_RW(gamepad_rumble_intensity, "rumble_intensity", UNSPECIFIED, 1804 + index, motor_config); 1805 + static DEVICE_ATTR_RO_NAMED(gamepad_rumble_intensity_index, 1806 + "rumble_intensity_index"); 1807 + 1808 + static DEVICE_ATTR_RW(fps_mode_dpi); 1809 + static DEVICE_ATTR_RO(fps_mode_dpi_index); 1810 + 1811 + static DEVICE_ATTR_RW(os_mode); 1812 + static DEVICE_ATTR_RO(os_mode_index); 1813 + 1814 + static struct attribute *mcu_attrs[] = { 1815 + &dev_attr_fps_mode_dpi.attr, 1816 + &dev_attr_fps_mode_dpi_index.attr, 1817 + &dev_attr_fps_switch_status.attr, 1818 + &dev_attr_gamepad_mode.attr, 1819 + &dev_attr_gamepad_mode_index.attr, 1820 + &dev_attr_gamepad_rumble_intensity.attr, 1821 + &dev_attr_gamepad_rumble_intensity_index.attr, 1822 + &dev_attr_os_mode.attr, 1823 + &dev_attr_os_mode_index.attr, 1824 + &dev_attr_reset_mcu.attr, 1825 + &dev_attr_version_firmware_mcu.attr, 1826 + &dev_attr_version_gen_mcu.attr, 1827 + &dev_attr_version_hardware_mcu.attr, 1828 + &dev_attr_version_product_mcu.attr, 1829 + &dev_attr_version_protocol_mcu.attr, 1830 + NULL, 1831 + }; 1832 + 1833 + static const struct attribute_group mcu_attr_group = { 1834 + .attrs = mcu_attrs, 1835 + }; 1836 + 1837 + /* Gamepad - TX Dongle */ 1838 + static struct go_cfg_attr version_product_tx_dongle = { PRODUCT_VERSION }; 1839 + LEGO_DEVICE_ATTR_RO(version_product_tx_dongle, "product_version", TX_DONGLE, version); 1840 + 1841 + static struct go_cfg_attr version_protocol_tx_dongle = { PROTOCOL_VERSION }; 1842 + LEGO_DEVICE_ATTR_RO(version_protocol_tx_dongle, "protocol_version", TX_DONGLE, version); 1843 + 1844 + static struct go_cfg_attr version_firmware_tx_dongle = { FIRMWARE_VERSION }; 1845 + LEGO_DEVICE_ATTR_RO(version_firmware_tx_dongle, "firmware_version", TX_DONGLE, version); 1846 + 1847 + static struct go_cfg_attr version_hardware_tx_dongle = { HARDWARE_VERSION }; 1848 + LEGO_DEVICE_ATTR_RO(version_hardware_tx_dongle, "hardware_version", TX_DONGLE, version); 1849 + 1850 + static struct go_cfg_attr version_gen_tx_dongle = { HARDWARE_GENERATION }; 1851 + LEGO_DEVICE_ATTR_RO(version_gen_tx_dongle, "hardware_generation", TX_DONGLE, version); 1852 + 1853 + static struct go_cfg_attr reset_tx_dongle = { FEATURE_RESET_GAMEPAD }; 1854 + LEGO_DEVICE_ATTR_RO(reset_tx_dongle, "reset", TX_DONGLE, feature_status); 1855 + 1856 + static struct attribute *tx_dongle_attrs[] = { 1857 + &dev_attr_reset_tx_dongle.attr, 1858 + &dev_attr_version_hardware_tx_dongle.attr, 1859 + &dev_attr_version_firmware_tx_dongle.attr, 1860 + &dev_attr_version_gen_tx_dongle.attr, 1861 + &dev_attr_version_product_tx_dongle.attr, 1862 + &dev_attr_version_protocol_tx_dongle.attr, 1863 + NULL, 1864 + }; 1865 + 1866 + static const struct attribute_group tx_dongle_attr_group = { 1867 + .name = "tx_dongle", 1868 + .attrs = tx_dongle_attrs, 1869 + }; 1870 + 1871 + /* Gamepad - Left */ 1872 + static struct go_cfg_attr version_product_left = { PRODUCT_VERSION }; 1873 + LEGO_DEVICE_ATTR_RO(version_product_left, "product_version", LEFT_CONTROLLER, version); 1874 + 1875 + static struct go_cfg_attr version_protocol_left = { PROTOCOL_VERSION }; 1876 + LEGO_DEVICE_ATTR_RO(version_protocol_left, "protocol_version", LEFT_CONTROLLER, version); 1877 + 1878 + static struct go_cfg_attr version_firmware_left = { FIRMWARE_VERSION }; 1879 + LEGO_DEVICE_ATTR_RO(version_firmware_left, "firmware_version", LEFT_CONTROLLER, version); 1880 + 1881 + static struct go_cfg_attr version_hardware_left = { HARDWARE_VERSION }; 1882 + LEGO_DEVICE_ATTR_RO(version_hardware_left, "hardware_version", LEFT_CONTROLLER, version); 1883 + 1884 + static struct go_cfg_attr version_gen_left = { HARDWARE_GENERATION }; 1885 + LEGO_DEVICE_ATTR_RO(version_gen_left, "hardware_generation", LEFT_CONTROLLER, version); 1886 + 1887 + static struct go_cfg_attr auto_sleep_time_left = { FEATURE_AUTO_SLEEP_TIME }; 1888 + LEGO_DEVICE_ATTR_RW(auto_sleep_time_left, "auto_sleep_time", LEFT_CONTROLLER, 1889 + range, feature_status); 1890 + static DEVICE_ATTR_RO_NAMED(auto_sleep_time_left_range, 1891 + "auto_sleep_time_range"); 1892 + 1893 + static struct go_cfg_attr imu_bypass_left = { FEATURE_IMU_BYPASS }; 1894 + LEGO_DEVICE_ATTR_RW(imu_bypass_left, "imu_bypass_enabled", LEFT_CONTROLLER, 1895 + index, feature_status); 1896 + static DEVICE_ATTR_RO_NAMED(imu_bypass_left_index, "imu_bypass_enabled_index"); 1897 + 1898 + static struct go_cfg_attr imu_enabled_left = { FEATURE_IMU_ENABLE }; 1899 + LEGO_DEVICE_ATTR_RW(imu_enabled_left, "imu_enabled", LEFT_CONTROLLER, index, 1900 + feature_status); 1901 + static DEVICE_ATTR_RO_NAMED(imu_enabled_left_index, "imu_enabled_index"); 1902 + 1903 + static struct go_cfg_attr reset_left = { FEATURE_RESET_GAMEPAD }; 1904 + LEGO_DEVICE_ATTR_WO(reset_left, "reset", LEFT_CONTROLLER, feature_status); 1905 + 1906 + static struct go_cfg_attr rumble_mode_left = { RUMBLE_MODE }; 1907 + LEGO_DEVICE_ATTR_RW(rumble_mode_left, "rumble_mode", LEFT_CONTROLLER, index, 1908 + motor_config); 1909 + static DEVICE_ATTR_RO_NAMED(rumble_mode_left_index, "rumble_mode_index"); 1910 + 1911 + static struct go_cfg_attr rumble_notification_left = { VIBRATION_NOTIFY_ENABLE }; 1912 + LEGO_DEVICE_ATTR_RW(rumble_notification_left, "rumble_notification", 1913 + LEFT_CONTROLLER, index, motor_config); 1914 + static DEVICE_ATTR_RO_NAMED(rumble_notification_left_index, 1915 + "rumble_notification_index"); 1916 + 1917 + static struct go_cfg_attr cal_trigg_left = { TRIGGER_CALIBRATE }; 1918 + LEGO_CAL_DEVICE_ATTR(cal_trigg_left, "calibrate_trigger", SET_TRIGGER_CFG, 1919 + LEFT_CONTROLLER, index); 1920 + static DEVICE_ATTR_RO_NAMED(cal_trigg_left_index, "calibrate_trigger_index"); 1921 + 1922 + static struct go_cfg_attr cal_joy_left = { JOYSTICK_CALIBRATE }; 1923 + LEGO_CAL_DEVICE_ATTR(cal_joy_left, "calibrate_joystick", SET_JOYSTICK_CFG, 1924 + LEFT_CONTROLLER, index); 1925 + static DEVICE_ATTR_RO_NAMED(cal_joy_left_index, "calibrate_joystick_index"); 1926 + 1927 + static struct go_cfg_attr cal_gyro_left = { GYRO_CALIBRATE }; 1928 + LEGO_CAL_DEVICE_ATTR(cal_gyro_left, "calibrate_gyro", SET_GYRO_CFG, 1929 + LEFT_CONTROLLER, index); 1930 + static DEVICE_ATTR_RO_NAMED(cal_gyro_left_index, "calibrate_gyro_index"); 1931 + 1932 + static struct go_cfg_attr cal_trigg_left_status = { GET_CAL_STATUS }; 1933 + LEGO_DEVICE_STATUS_ATTR(cal_trigg_left_status, "calibrate_trigger_status", 1934 + LEFT_CONTROLLER, CALDEV_TRIGGER); 1935 + 1936 + static struct go_cfg_attr cal_joy_left_status = { GET_CAL_STATUS }; 1937 + LEGO_DEVICE_STATUS_ATTR(cal_joy_left_status, "calibrate_joystick_status", 1938 + LEFT_CONTROLLER, CALDEV_JOYSTICK); 1939 + 1940 + static struct go_cfg_attr cal_gyro_left_status = { GET_CAL_STATUS }; 1941 + LEGO_DEVICE_STATUS_ATTR(cal_gyro_left_status, "calibrate_gyro_status", 1942 + LEFT_CONTROLLER, CALDEV_GYROSCOPE); 1943 + 1944 + static struct attribute *left_gamepad_attrs[] = { 1945 + &dev_attr_auto_sleep_time_left.attr, 1946 + &dev_attr_auto_sleep_time_left_range.attr, 1947 + &dev_attr_cal_gyro_left.attr, 1948 + &dev_attr_cal_gyro_left_index.attr, 1949 + &dev_attr_cal_gyro_left_status.attr, 1950 + &dev_attr_cal_joy_left.attr, 1951 + &dev_attr_cal_joy_left_index.attr, 1952 + &dev_attr_cal_joy_left_status.attr, 1953 + &dev_attr_cal_trigg_left.attr, 1954 + &dev_attr_cal_trigg_left_index.attr, 1955 + &dev_attr_cal_trigg_left_status.attr, 1956 + &dev_attr_imu_bypass_left.attr, 1957 + &dev_attr_imu_bypass_left_index.attr, 1958 + &dev_attr_imu_enabled_left.attr, 1959 + &dev_attr_imu_enabled_left_index.attr, 1960 + &dev_attr_reset_left.attr, 1961 + &dev_attr_rumble_mode_left.attr, 1962 + &dev_attr_rumble_mode_left_index.attr, 1963 + &dev_attr_rumble_notification_left.attr, 1964 + &dev_attr_rumble_notification_left_index.attr, 1965 + &dev_attr_version_hardware_left.attr, 1966 + &dev_attr_version_firmware_left.attr, 1967 + &dev_attr_version_gen_left.attr, 1968 + &dev_attr_version_product_left.attr, 1969 + &dev_attr_version_protocol_left.attr, 1970 + NULL, 1971 + }; 1972 + 1973 + static const struct attribute_group left_gamepad_attr_group = { 1974 + .name = "left_handle", 1975 + .attrs = left_gamepad_attrs, 1976 + }; 1977 + 1978 + /* Gamepad - Right */ 1979 + static struct go_cfg_attr version_product_right = { PRODUCT_VERSION }; 1980 + LEGO_DEVICE_ATTR_RO(version_product_right, "product_version", RIGHT_CONTROLLER, version); 1981 + 1982 + static struct go_cfg_attr version_protocol_right = { PROTOCOL_VERSION }; 1983 + LEGO_DEVICE_ATTR_RO(version_protocol_right, "protocol_version", RIGHT_CONTROLLER, version); 1984 + 1985 + static struct go_cfg_attr version_firmware_right = { FIRMWARE_VERSION }; 1986 + LEGO_DEVICE_ATTR_RO(version_firmware_right, "firmware_version", RIGHT_CONTROLLER, version); 1987 + 1988 + static struct go_cfg_attr version_hardware_right = { HARDWARE_VERSION }; 1989 + LEGO_DEVICE_ATTR_RO(version_hardware_right, "hardware_version", RIGHT_CONTROLLER, version); 1990 + 1991 + static struct go_cfg_attr version_gen_right = { HARDWARE_GENERATION }; 1992 + LEGO_DEVICE_ATTR_RO(version_gen_right, "hardware_generation", RIGHT_CONTROLLER, version); 1993 + 1994 + static struct go_cfg_attr auto_sleep_time_right = { FEATURE_AUTO_SLEEP_TIME }; 1995 + LEGO_DEVICE_ATTR_RW(auto_sleep_time_right, "auto_sleep_time", RIGHT_CONTROLLER, 1996 + range, feature_status); 1997 + static DEVICE_ATTR_RO_NAMED(auto_sleep_time_right_range, 1998 + "auto_sleep_time_range"); 1999 + 2000 + static struct go_cfg_attr imu_bypass_right = { FEATURE_IMU_BYPASS }; 2001 + LEGO_DEVICE_ATTR_RW(imu_bypass_right, "imu_bypass_enabled", RIGHT_CONTROLLER, 2002 + index, feature_status); 2003 + static DEVICE_ATTR_RO_NAMED(imu_bypass_right_index, "imu_bypass_enabled_index"); 2004 + 2005 + static struct go_cfg_attr imu_enabled_right = { FEATURE_IMU_BYPASS }; 2006 + LEGO_DEVICE_ATTR_RW(imu_enabled_right, "imu_enabled", RIGHT_CONTROLLER, index, 2007 + feature_status); 2008 + static DEVICE_ATTR_RO_NAMED(imu_enabled_right_index, "imu_enabled_index"); 2009 + 2010 + static struct go_cfg_attr reset_right = { FEATURE_RESET_GAMEPAD }; 2011 + LEGO_DEVICE_ATTR_WO(reset_right, "reset", LEFT_CONTROLLER, feature_status); 2012 + 2013 + static struct go_cfg_attr rumble_mode_right = { RUMBLE_MODE }; 2014 + LEGO_DEVICE_ATTR_RW(rumble_mode_right, "rumble_mode", RIGHT_CONTROLLER, index, 2015 + motor_config); 2016 + static DEVICE_ATTR_RO_NAMED(rumble_mode_right_index, "rumble_mode_index"); 2017 + 2018 + static struct go_cfg_attr rumble_notification_right = { VIBRATION_NOTIFY_ENABLE }; 2019 + LEGO_DEVICE_ATTR_RW(rumble_notification_right, "rumble_notification", 2020 + RIGHT_CONTROLLER, index, motor_config); 2021 + static DEVICE_ATTR_RO_NAMED(rumble_notification_right_index, 2022 + "rumble_notification_index"); 2023 + 2024 + static struct go_cfg_attr cal_trigg_right = { TRIGGER_CALIBRATE }; 2025 + LEGO_CAL_DEVICE_ATTR(cal_trigg_right, "calibrate_trigger", SET_TRIGGER_CFG, 2026 + RIGHT_CONTROLLER, index); 2027 + static DEVICE_ATTR_RO_NAMED(cal_trigg_right_index, "calibrate_trigger_index"); 2028 + 2029 + static struct go_cfg_attr cal_joy_right = { JOYSTICK_CALIBRATE }; 2030 + LEGO_CAL_DEVICE_ATTR(cal_joy_right, "calibrate_joystick", SET_JOYSTICK_CFG, 2031 + RIGHT_CONTROLLER, index); 2032 + static DEVICE_ATTR_RO_NAMED(cal_joy_right_index, "calibrate_joystick_index"); 2033 + 2034 + static struct go_cfg_attr cal_gyro_right = { GYRO_CALIBRATE }; 2035 + LEGO_CAL_DEVICE_ATTR(cal_gyro_right, "calibrate_gyro", SET_GYRO_CFG, 2036 + RIGHT_CONTROLLER, index); 2037 + static DEVICE_ATTR_RO_NAMED(cal_gyro_right_index, "calibrate_gyro_index"); 2038 + 2039 + static struct go_cfg_attr cal_trigg_right_status = { GET_CAL_STATUS }; 2040 + LEGO_DEVICE_STATUS_ATTR(cal_trigg_right_status, "calibrate_trigger_status", 2041 + RIGHT_CONTROLLER, CALDEV_TRIGGER); 2042 + 2043 + static struct go_cfg_attr cal_joy_right_status = { GET_CAL_STATUS }; 2044 + LEGO_DEVICE_STATUS_ATTR(cal_joy_right_status, "calibrate_joystick_status", 2045 + RIGHT_CONTROLLER, CALDEV_JOYSTICK); 2046 + 2047 + static struct go_cfg_attr cal_gyro_right_status = { GET_CAL_STATUS }; 2048 + LEGO_DEVICE_STATUS_ATTR(cal_gyro_right_status, "calibrate_gyro_status", 2049 + RIGHT_CONTROLLER, CALDEV_GYROSCOPE); 2050 + 2051 + static struct attribute *right_gamepad_attrs[] = { 2052 + &dev_attr_auto_sleep_time_right.attr, 2053 + &dev_attr_auto_sleep_time_right_range.attr, 2054 + &dev_attr_cal_gyro_right.attr, 2055 + &dev_attr_cal_gyro_right_index.attr, 2056 + &dev_attr_cal_gyro_right_status.attr, 2057 + &dev_attr_cal_joy_right.attr, 2058 + &dev_attr_cal_joy_right_index.attr, 2059 + &dev_attr_cal_joy_right_status.attr, 2060 + &dev_attr_cal_trigg_right.attr, 2061 + &dev_attr_cal_trigg_right_index.attr, 2062 + &dev_attr_cal_trigg_right_status.attr, 2063 + &dev_attr_imu_bypass_right.attr, 2064 + &dev_attr_imu_bypass_right_index.attr, 2065 + &dev_attr_imu_enabled_right.attr, 2066 + &dev_attr_imu_enabled_right_index.attr, 2067 + &dev_attr_reset_right.attr, 2068 + &dev_attr_rumble_mode_right.attr, 2069 + &dev_attr_rumble_mode_right_index.attr, 2070 + &dev_attr_rumble_notification_right.attr, 2071 + &dev_attr_rumble_notification_right_index.attr, 2072 + &dev_attr_version_hardware_right.attr, 2073 + &dev_attr_version_firmware_right.attr, 2074 + &dev_attr_version_gen_right.attr, 2075 + &dev_attr_version_product_right.attr, 2076 + &dev_attr_version_protocol_right.attr, 2077 + NULL, 2078 + }; 2079 + 2080 + static const struct attribute_group right_gamepad_attr_group = { 2081 + .name = "right_handle", 2082 + .attrs = right_gamepad_attrs, 2083 + }; 2084 + 2085 + /* Touchpad */ 2086 + static struct go_cfg_attr touchpad_enabled = { FEATURE_TOUCHPAD_ENABLE }; 2087 + LEGO_DEVICE_ATTR_RW(touchpad_enabled, "enabled", UNSPECIFIED, index, 2088 + feature_status); 2089 + static DEVICE_ATTR_RO_NAMED(touchpad_enabled_index, "enabled_index"); 2090 + 2091 + static struct go_cfg_attr touchpad_vibration_enabled = { TP_VIBRATION_ENABLE }; 2092 + LEGO_DEVICE_ATTR_RW(touchpad_vibration_enabled, "vibration_enabled", UNSPECIFIED, 2093 + index, motor_config); 2094 + static DEVICE_ATTR_RO_NAMED(touchpad_vibration_enabled_index, 2095 + "vibration_enabled_index"); 2096 + 2097 + static struct go_cfg_attr touchpad_vibration_intensity = { TP_VIBRATION_INTENSITY }; 2098 + LEGO_DEVICE_ATTR_RW(touchpad_vibration_intensity, "vibration_intensity", 2099 + UNSPECIFIED, index, motor_config); 2100 + static DEVICE_ATTR_RO_NAMED(touchpad_vibration_intensity_index, 2101 + "vibration_intensity_index"); 2102 + 2103 + static struct attribute *touchpad_attrs[] = { 2104 + &dev_attr_touchpad_enabled.attr, 2105 + &dev_attr_touchpad_enabled_index.attr, 2106 + &dev_attr_touchpad_vibration_enabled.attr, 2107 + &dev_attr_touchpad_vibration_enabled_index.attr, 2108 + &dev_attr_touchpad_vibration_intensity.attr, 2109 + &dev_attr_touchpad_vibration_intensity_index.attr, 2110 + NULL, 2111 + }; 2112 + 2113 + static const struct attribute_group touchpad_attr_group = { 2114 + .name = "touchpad", 2115 + .attrs = touchpad_attrs, 2116 + }; 2117 + 2118 + static const struct attribute_group *top_level_attr_groups[] = { 2119 + &mcu_attr_group, &tx_dongle_attr_group, 2120 + &left_gamepad_attr_group, &right_gamepad_attr_group, 2121 + &touchpad_attr_group, NULL, 2122 + }; 2123 + 2124 + /* RGB */ 2125 + static struct go_cfg_attr rgb_enabled = { FEATURE_LIGHT_ENABLE }; 2126 + 2127 + LEGO_DEVICE_ATTR_RW(rgb_enabled, "enabled", UNSPECIFIED, index, feature_status); 2128 + static DEVICE_ATTR_RO_NAMED(rgb_effect_index, "effect_index"); 2129 + static DEVICE_ATTR_RO_NAMED(rgb_enabled_index, "enabled_index"); 2130 + static DEVICE_ATTR_RO_NAMED(rgb_mode_index, "mode_index"); 2131 + static DEVICE_ATTR_RO_NAMED(rgb_profile_range, "profile_range"); 2132 + static DEVICE_ATTR_RO_NAMED(rgb_speed_range, "speed_range"); 2133 + static DEVICE_ATTR_RW_NAMED(rgb_effect, "effect"); 2134 + static DEVICE_ATTR_RW_NAMED(rgb_mode, "mode"); 2135 + static DEVICE_ATTR_RW_NAMED(rgb_profile, "profile"); 2136 + static DEVICE_ATTR_RW_NAMED(rgb_speed, "speed"); 2137 + 2138 + static struct attribute *go_rgb_attrs[] = { 2139 + &dev_attr_rgb_effect.attr, 2140 + &dev_attr_rgb_effect_index.attr, 2141 + &dev_attr_rgb_enabled.attr, 2142 + &dev_attr_rgb_enabled_index.attr, 2143 + &dev_attr_rgb_mode.attr, 2144 + &dev_attr_rgb_mode_index.attr, 2145 + &dev_attr_rgb_profile.attr, 2146 + &dev_attr_rgb_profile_range.attr, 2147 + &dev_attr_rgb_speed.attr, 2148 + &dev_attr_rgb_speed_range.attr, 2149 + NULL, 2150 + }; 2151 + 2152 + static struct attribute_group rgb_attr_group = { 2153 + .attrs = go_rgb_attrs, 2154 + }; 2155 + 2156 + static struct mc_subled go_rgb_subled_info[] = { 2157 + { 2158 + .color_index = LED_COLOR_ID_RED, 2159 + .brightness = 0x50, 2160 + .intensity = 0x24, 2161 + .channel = 0x1, 2162 + }, 2163 + { 2164 + .color_index = LED_COLOR_ID_GREEN, 2165 + .brightness = 0x50, 2166 + .intensity = 0x22, 2167 + .channel = 0x2, 2168 + }, 2169 + { 2170 + .color_index = LED_COLOR_ID_BLUE, 2171 + .brightness = 0x50, 2172 + .intensity = 0x99, 2173 + .channel = 0x3, 2174 + }, 2175 + }; 2176 + 2177 + static struct led_classdev_mc go_cdev_rgb = { 2178 + .led_cdev = { 2179 + .name = "go:rgb:joystick_rings", 2180 + .color = LED_COLOR_ID_RGB, 2181 + .brightness = 0x50, 2182 + .max_brightness = 0x64, 2183 + .brightness_set = hid_go_brightness_set, 2184 + }, 2185 + .num_colors = ARRAY_SIZE(go_rgb_subled_info), 2186 + .subled_info = go_rgb_subled_info, 2187 + }; 2188 + 2189 + static void cfg_setup(struct work_struct *work) 2190 + { 2191 + int ret; 2192 + 2193 + /* MCU Version Attrs */ 2194 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2195 + PRODUCT_VERSION, USB_MCU, NULL, 0); 2196 + if (ret < 0) { 2197 + dev_err(&drvdata.hdev->dev, 2198 + "Failed to retrieve USB_MCU Product Version: %i\n", ret); 2199 + return; 2200 + } 2201 + 2202 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2203 + PROTOCOL_VERSION, USB_MCU, NULL, 0); 2204 + if (ret < 0) { 2205 + dev_err(&drvdata.hdev->dev, 2206 + "Failed to retrieve USB_MCU Protocol Version: %i\n", ret); 2207 + return; 2208 + } 2209 + 2210 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2211 + FIRMWARE_VERSION, USB_MCU, NULL, 0); 2212 + if (ret < 0) { 2213 + dev_err(&drvdata.hdev->dev, 2214 + "Failed to retrieve USB_MCU Firmware Version: %i\n", ret); 2215 + return; 2216 + } 2217 + 2218 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2219 + HARDWARE_VERSION, USB_MCU, NULL, 0); 2220 + if (ret < 0) { 2221 + dev_err(&drvdata.hdev->dev, 2222 + "Failed to retrieve USB_MCU Hardware Version: %i\n", ret); 2223 + return; 2224 + } 2225 + 2226 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2227 + HARDWARE_GENERATION, USB_MCU, NULL, 0); 2228 + if (ret < 0) { 2229 + dev_err(&drvdata.hdev->dev, 2230 + "Failed to retrieve USB_MCU Hardware Generation: %i\n", ret); 2231 + return; 2232 + } 2233 + 2234 + /* TX Dongle Version Attrs */ 2235 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2236 + PRODUCT_VERSION, TX_DONGLE, NULL, 0); 2237 + if (ret < 0) { 2238 + dev_err(&drvdata.hdev->dev, 2239 + "Failed to retrieve TX_DONGLE Product Version: %i\n", ret); 2240 + return; 2241 + } 2242 + 2243 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2244 + PROTOCOL_VERSION, TX_DONGLE, NULL, 0); 2245 + if (ret < 0) { 2246 + dev_err(&drvdata.hdev->dev, 2247 + "Failed to retrieve TX_DONGLE Protocol Version: %i\n", ret); 2248 + return; 2249 + } 2250 + 2251 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2252 + FIRMWARE_VERSION, TX_DONGLE, NULL, 0); 2253 + if (ret < 0) { 2254 + dev_err(&drvdata.hdev->dev, 2255 + "Failed to retrieve TX_DONGLE Firmware Version: %i\n", ret); 2256 + return; 2257 + } 2258 + 2259 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2260 + HARDWARE_VERSION, TX_DONGLE, NULL, 0); 2261 + if (ret < 0) { 2262 + dev_err(&drvdata.hdev->dev, 2263 + "Failed to retrieve TX_DONGLE Hardware Version: %i\n", ret); 2264 + return; 2265 + } 2266 + 2267 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2268 + HARDWARE_GENERATION, TX_DONGLE, NULL, 0); 2269 + if (ret < 0) { 2270 + dev_err(&drvdata.hdev->dev, 2271 + "Failed to retrieve TX_DONGLE Hardware Generation: %i\n", ret); 2272 + return; 2273 + } 2274 + 2275 + /* Left Handle Version Attrs */ 2276 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2277 + PRODUCT_VERSION, LEFT_CONTROLLER, NULL, 0); 2278 + if (ret < 0) { 2279 + dev_err(&drvdata.hdev->dev, 2280 + "Failed to retrieve LEFT_CONTROLLER Product Version: %i\n", ret); 2281 + return; 2282 + } 2283 + 2284 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2285 + PROTOCOL_VERSION, LEFT_CONTROLLER, NULL, 0); 2286 + if (ret < 0) { 2287 + dev_err(&drvdata.hdev->dev, 2288 + "Failed to retrieve LEFT_CONTROLLER Protocol Version: %i\n", ret); 2289 + return; 2290 + } 2291 + 2292 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2293 + FIRMWARE_VERSION, LEFT_CONTROLLER, NULL, 0); 2294 + if (ret < 0) { 2295 + dev_err(&drvdata.hdev->dev, 2296 + "Failed to retrieve LEFT_CONTROLLER Firmware Version: %i\n", ret); 2297 + return; 2298 + } 2299 + 2300 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2301 + HARDWARE_VERSION, LEFT_CONTROLLER, NULL, 0); 2302 + if (ret < 0) { 2303 + dev_err(&drvdata.hdev->dev, 2304 + "Failed to retrieve LEFT_CONTROLLER Hardware Version: %i\n", ret); 2305 + return; 2306 + } 2307 + 2308 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2309 + HARDWARE_GENERATION, LEFT_CONTROLLER, NULL, 0); 2310 + if (ret < 0) { 2311 + dev_err(&drvdata.hdev->dev, 2312 + "Failed to retrieve LEFT_CONTROLLER Hardware Generation: %i\n", ret); 2313 + return; 2314 + } 2315 + 2316 + /* Right Handle Version Attrs */ 2317 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2318 + PRODUCT_VERSION, RIGHT_CONTROLLER, NULL, 0); 2319 + if (ret < 0) { 2320 + dev_err(&drvdata.hdev->dev, 2321 + "Failed to retrieve RIGHT_CONTROLLER Product Version: %i\n", ret); 2322 + return; 2323 + } 2324 + 2325 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2326 + PROTOCOL_VERSION, RIGHT_CONTROLLER, NULL, 0); 2327 + if (ret < 0) { 2328 + dev_err(&drvdata.hdev->dev, 2329 + "Failed to retrieve RIGHT_CONTROLLER Protocol Version: %i\n", ret); 2330 + return; 2331 + } 2332 + 2333 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2334 + FIRMWARE_VERSION, RIGHT_CONTROLLER, NULL, 0); 2335 + if (ret < 0) { 2336 + dev_err(&drvdata.hdev->dev, 2337 + "Failed to retrieve RIGHT_CONTROLLER Firmware Version: %i\n", ret); 2338 + return; 2339 + } 2340 + 2341 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2342 + HARDWARE_VERSION, RIGHT_CONTROLLER, NULL, 0); 2343 + if (ret < 0) { 2344 + dev_err(&drvdata.hdev->dev, 2345 + "Failed to retrieve RIGHT_CONTROLLER Hardware Version: %i\n", ret); 2346 + return; 2347 + } 2348 + 2349 + ret = mcu_property_out(drvdata.hdev, MCU_CONFIG_DATA, GET_VERSION_DATA, 2350 + HARDWARE_GENERATION, RIGHT_CONTROLLER, NULL, 0); 2351 + if (ret < 0) { 2352 + dev_err(&drvdata.hdev->dev, 2353 + "Failed to retrieve RIGHT_CONTROLLER Hardware Generation: %i\n", ret); 2354 + return; 2355 + } 2356 + } 2357 + 2358 + static int hid_go_cfg_probe(struct hid_device *hdev, 2359 + const struct hid_device_id *_id) 2360 + { 2361 + unsigned char *buf; 2362 + int ret; 2363 + 2364 + buf = devm_kzalloc(&hdev->dev, GO_PACKET_SIZE, GFP_KERNEL); 2365 + if (!buf) 2366 + return -ENOMEM; 2367 + 2368 + hid_set_drvdata(hdev, &drvdata); 2369 + drvdata.hdev = hdev; 2370 + mutex_init(&drvdata.cfg_mutex); 2371 + 2372 + ret = sysfs_create_groups(&hdev->dev.kobj, top_level_attr_groups); 2373 + if (ret) { 2374 + dev_err_probe(&hdev->dev, ret, 2375 + "Failed to create gamepad configuration attributes\n"); 2376 + return ret; 2377 + } 2378 + 2379 + ret = devm_led_classdev_multicolor_register(&hdev->dev, &go_cdev_rgb); 2380 + if (ret) { 2381 + dev_err_probe(&hdev->dev, ret, "Failed to create RGB device\n"); 2382 + return ret; 2383 + } 2384 + 2385 + ret = devm_device_add_group(go_cdev_rgb.led_cdev.dev, &rgb_attr_group); 2386 + if (ret) { 2387 + dev_err_probe(&hdev->dev, ret, 2388 + "Failed to create RGB configuration attributes\n"); 2389 + return ret; 2390 + } 2391 + 2392 + drvdata.led_cdev = &go_cdev_rgb.led_cdev; 2393 + 2394 + init_completion(&drvdata.send_cmd_complete); 2395 + 2396 + /* Executing calls prior to returning from probe will lock the MCU. Schedule 2397 + * initial data call after probe has completed and MCU can accept calls. 2398 + */ 2399 + INIT_DELAYED_WORK(&drvdata.go_cfg_setup, &cfg_setup); 2400 + ret = schedule_delayed_work(&drvdata.go_cfg_setup, msecs_to_jiffies(2)); 2401 + if (!ret) { 2402 + dev_err(&hdev->dev, 2403 + "Failed to schedule startup delayed work\n"); 2404 + return -ENODEV; 2405 + } 2406 + return 0; 2407 + } 2408 + 2409 + static void hid_go_cfg_remove(struct hid_device *hdev) 2410 + { 2411 + guard(mutex)(&drvdata.cfg_mutex); 2412 + sysfs_remove_groups(&hdev->dev.kobj, top_level_attr_groups); 2413 + hid_hw_close(hdev); 2414 + hid_hw_stop(hdev); 2415 + hid_set_drvdata(hdev, NULL); 2416 + } 2417 + 2418 + static int hid_go_probe(struct hid_device *hdev, const struct hid_device_id *id) 2419 + { 2420 + int ret, ep; 2421 + 2422 + hdev->quirks |= HID_QUIRK_INPUT_PER_APP | HID_QUIRK_MULTI_INPUT; 2423 + 2424 + ret = hid_parse(hdev); 2425 + if (ret) { 2426 + hid_err(hdev, "Parse failed\n"); 2427 + return ret; 2428 + } 2429 + 2430 + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 2431 + if (ret) { 2432 + hid_err(hdev, "Failed to start HID device\n"); 2433 + return ret; 2434 + } 2435 + 2436 + ret = hid_hw_open(hdev); 2437 + if (ret) { 2438 + hid_err(hdev, "Failed to open HID device\n"); 2439 + hid_hw_stop(hdev); 2440 + return ret; 2441 + } 2442 + 2443 + ep = get_endpoint_address(hdev); 2444 + if (ep != GO_GP_INTF_IN) { 2445 + dev_dbg(&hdev->dev, "Started interface %x as generic HID device\n", ep); 2446 + return 0; 2447 + } 2448 + 2449 + ret = hid_go_cfg_probe(hdev, id); 2450 + if (ret) 2451 + dev_err_probe(&hdev->dev, ret, "Failed to start configuration interface\n"); 2452 + 2453 + dev_dbg(&hdev->dev, "Started Legion Go HID Device: %x\n", ep); 2454 + 2455 + return ret; 2456 + } 2457 + 2458 + static void hid_go_remove(struct hid_device *hdev) 2459 + { 2460 + int ep = get_endpoint_address(hdev); 2461 + 2462 + if (ep <= 0) 2463 + return; 2464 + 2465 + switch (ep) { 2466 + case GO_GP_INTF_IN: 2467 + hid_go_cfg_remove(hdev); 2468 + break; 2469 + default: 2470 + hid_hw_close(hdev); 2471 + hid_hw_stop(hdev); 2472 + break; 2473 + } 2474 + } 2475 + 2476 + static const struct hid_device_id hid_go_devices[] = { 2477 + { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, 2478 + USB_DEVICE_ID_LENOVO_LEGION_GO2_XINPUT) }, 2479 + { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, 2480 + USB_DEVICE_ID_LENOVO_LEGION_GO2_DINPUT) }, 2481 + { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, 2482 + USB_DEVICE_ID_LENOVO_LEGION_GO2_DUAL_DINPUT) }, 2483 + { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, 2484 + USB_DEVICE_ID_LENOVO_LEGION_GO2_FPS) }, 2485 + {} 2486 + }; 2487 + MODULE_DEVICE_TABLE(hid, hid_go_devices); 2488 + 2489 + static struct hid_driver hid_lenovo_go = { 2490 + .name = "hid-lenovo-go", 2491 + .id_table = hid_go_devices, 2492 + .probe = hid_go_probe, 2493 + .remove = hid_go_remove, 2494 + .raw_event = hid_go_raw_event, 2495 + }; 2496 + module_hid_driver(hid_lenovo_go); 2497 + 2498 + MODULE_AUTHOR("Derek J. Clark"); 2499 + MODULE_DESCRIPTION("HID Driver for Lenovo Legion Go Series Gamepads."); 2500 + MODULE_LICENSE("GPL");
+17 -6
drivers/hid/hid-logitech-dj.c
··· 1858 1858 static int logi_dj_probe(struct hid_device *hdev, 1859 1859 const struct hid_device_id *id) 1860 1860 { 1861 - struct hid_report_enum *rep_enum; 1861 + struct hid_report_enum *input_report_enum; 1862 + struct hid_report_enum *output_report_enum; 1862 1863 struct hid_report *rep; 1863 1864 struct dj_receiver_dev *djrcv_dev; 1864 1865 struct usb_interface *intf; ··· 1904 1903 } 1905 1904 } 1906 1905 1907 - rep_enum = &hdev->report_enum[HID_INPUT_REPORT]; 1906 + output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT]; 1907 + rep = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT]; 1908 + 1909 + if (rep && (rep->maxfield < 1 || 1910 + rep->field[0]->report_count != DJREPORT_SHORT_LENGTH - 1)) { 1911 + hid_err(hdev, "Expected size of DJ short report is %d, but got %d", 1912 + DJREPORT_SHORT_LENGTH - 1, rep->field[0]->report_count); 1913 + return -EINVAL; 1914 + } 1915 + 1916 + input_report_enum = &hdev->report_enum[HID_INPUT_REPORT]; 1908 1917 1909 1918 /* no input reports, bail out */ 1910 - if (list_empty(&rep_enum->report_list)) 1919 + if (list_empty(&input_report_enum->report_list)) 1911 1920 return -ENODEV; 1912 1921 1913 1922 /* ··· 1925 1914 * Note: we should theoretically check for HID++ and DJ 1926 1915 * collections, but this will do. 1927 1916 */ 1928 - list_for_each_entry(rep, &rep_enum->report_list, list) { 1917 + list_for_each_entry(rep, &input_report_enum->report_list, list) { 1929 1918 if (rep->application == 0xff000001) 1930 1919 has_hidpp = true; 1931 1920 } ··· 1938 1927 return -ENODEV; 1939 1928 1940 1929 /* get the current application attached to the node */ 1941 - rep = list_first_entry(&rep_enum->report_list, struct hid_report, list); 1930 + rep = list_first_entry(&input_report_enum->report_list, struct hid_report, list); 1942 1931 djrcv_dev = dj_get_receiver_dev(hdev, id->driver_data, 1943 1932 rep->application, has_hidpp); 1944 1933 if (!djrcv_dev) { ··· 1946 1935 return -ENOMEM; 1947 1936 } 1948 1937 1949 - if (!rep_enum->numbered) 1938 + if (!input_report_enum->numbered) 1950 1939 djrcv_dev->unnumbered_application = rep->application; 1951 1940 1952 1941 /* Starts the usb device and connects to upper interfaces hiddev and
+26 -13
drivers/hid/hid-logitech-hidpp.c
··· 306 306 if (ret) { 307 307 dbg_hid("__hidpp_send_report returned err: %d\n", ret); 308 308 memset(response, 0, sizeof(struct hidpp_report)); 309 - return ret; 309 + goto out; 310 310 } 311 311 312 312 if (!wait_event_timeout(hidpp->wait, hidpp->answer_available, 313 313 5*HZ)) { 314 314 dbg_hid("%s:timeout waiting for response\n", __func__); 315 315 memset(response, 0, sizeof(struct hidpp_report)); 316 - return -ETIMEDOUT; 316 + ret = -ETIMEDOUT; 317 + goto out; 317 318 } 318 319 319 320 if (response->report_id == REPORT_ID_HIDPP_SHORT && 320 321 response->rap.sub_id == HIDPP_ERROR) { 321 322 ret = response->rap.params[1]; 322 323 dbg_hid("%s:got hidpp error %02X\n", __func__, ret); 323 - return ret; 324 + goto out; 324 325 } 325 326 326 327 if ((response->report_id == REPORT_ID_HIDPP_LONG || ··· 329 328 response->fap.feature_index == HIDPP20_ERROR) { 330 329 ret = response->fap.params[1]; 331 330 dbg_hid("%s:got hidpp 2.0 error %02X\n", __func__, ret); 332 - return ret; 331 + goto out; 333 332 } 334 333 335 - return 0; 334 + ret = 0; 335 + 336 + out: 337 + hidpp->send_receive_buf = NULL; 338 + return ret; 336 339 } 337 340 338 341 /* ··· 2507 2502 } 2508 2503 break; 2509 2504 case HIDPP_FF_DESTROY_EFFECT: 2510 - if (wd->effect_id >= 0) 2511 - /* regular effect destroyed */ 2512 - data->effect_ids[wd->params[0]-1] = -1; 2513 - else if (wd->effect_id >= HIDPP_FF_EFFECTID_AUTOCENTER) 2514 - /* autocenter spring destroyed */ 2515 - data->slot_autocenter = 0; 2505 + slot = wd->params[0]; 2506 + if (slot > 0 && slot <= data->num_effects) { 2507 + if (wd->effect_id >= 0) 2508 + /* regular effect destroyed */ 2509 + data->effect_ids[slot-1] = -1; 2510 + else if (wd->effect_id >= HIDPP_FF_EFFECTID_AUTOCENTER) 2511 + /* autocenter spring destroyed */ 2512 + data->slot_autocenter = 0; 2513 + } 2516 2514 break; 2517 2515 case HIDPP_FF_SET_GLOBAL_GAINS: 2518 2516 data->gain = (wd->params[0] << 8) + wd->params[1]; ··· 3848 3840 static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data, 3849 3841 int size) 3850 3842 { 3851 - struct hidpp_report *question = hidpp->send_receive_buf; 3852 - struct hidpp_report *answer = hidpp->send_receive_buf; 3843 + struct hidpp_report *question, *answer; 3853 3844 struct hidpp_report *report = (struct hidpp_report *)data; 3854 3845 int ret; 3855 3846 int last_online; ··· 3858 3851 * previously sent command. 3859 3852 */ 3860 3853 if (unlikely(mutex_is_locked(&hidpp->send_mutex))) { 3854 + question = hidpp->send_receive_buf; 3855 + answer = hidpp->send_receive_buf; 3856 + 3857 + if (!question) 3858 + return 0; 3859 + 3861 3860 /* 3862 3861 * Check for a correct hidpp20 answer or the corresponding 3863 3862 * error
+6 -4
drivers/hid/hid-magicmouse.c
··· 817 817 #ifdef CONFIG_HID_BATTERY_STRENGTH 818 818 struct hid_report_enum *report_enum; 819 819 struct hid_report *report; 820 + struct hid_battery *bat; 820 821 821 - if (!hdev->battery || 822 + bat = hid_get_battery(hdev); 823 + if (!bat || 822 824 (!is_usb_magicmouse2(hdev->vendor, hdev->product) && 823 825 !is_usb_magictrackpad2(hdev->vendor, hdev->product))) 824 826 return -1; 825 827 826 - report_enum = &hdev->report_enum[hdev->battery_report_type]; 827 - report = report_enum->report_id_hash[hdev->battery_report_id]; 828 + report_enum = &hdev->report_enum[bat->report_type]; 829 + report = report_enum->report_id_hash[bat->report_id]; 828 830 829 831 if (!report || report->maxfield < 1) 830 832 return -1; 831 833 832 - if (hdev->battery_capacity == hdev->battery_max) 834 + if (bat->capacity == bat->max) 833 835 return -1; 834 836 835 837 hid_hw_request(hdev, report, HID_REQ_GET_REPORT);
+23 -13
drivers/hid/hid-mcp2221.c
··· 19 19 #include <linux/gpio/driver.h> 20 20 #include <linux/iio/iio.h> 21 21 #include <linux/minmax.h> 22 + #include <linux/moduleparam.h> 22 23 #include "hid-ids.h" 24 + 25 + static bool gpio_mode_enforce; 26 + 27 + module_param(gpio_mode_enforce, bool, 0644); 28 + MODULE_PARM_DESC(gpio_mode_enforce, 29 + "Enforce GPIO mode for GP0 thru GP3 (default: false, will be used for IIO)"); 23 30 24 31 /* Commands codes in a raw output report */ 25 32 enum { ··· 543 536 if (ret) 544 537 goto exit; 545 538 546 - mcp->rxbuf_idx = 0; 547 - mcp->rxbuf = data->block; 548 - mcp->txbuf[0] = MCP2221_I2C_GET_DATA; 549 - ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1); 539 + ret = mcp_i2c_smbus_read(mcp, NULL, 540 + MCP2221_I2C_RD_RPT_START, 541 + addr, data->block[0] + 1, 542 + data->block); 550 543 if (ret) 551 544 goto exit; 552 545 } else { ··· 562 555 case I2C_SMBUS_I2C_BLOCK_DATA: 563 556 if (read_write == I2C_SMBUS_READ) { 564 557 ret = mcp_smbus_write(mcp, addr, command, NULL, 565 - 0, MCP2221_I2C_WR_NO_STOP, 1); 558 + 0, MCP2221_I2C_WR_NO_STOP, 0); 566 559 if (ret) 567 560 goto exit; 568 561 569 - mcp->rxbuf_idx = 0; 570 - mcp->rxbuf = data->block; 571 - mcp->txbuf[0] = MCP2221_I2C_GET_DATA; 572 - ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1); 562 + ret = mcp_i2c_smbus_read(mcp, NULL, 563 + MCP2221_I2C_RD_RPT_START, 564 + addr, data->block[0], 565 + &data->block[1]); 573 566 if (ret) 574 567 goto exit; 575 568 } else { ··· 657 650 int needgpiofix = 0; 658 651 int ret; 659 652 660 - if (IS_ENABLED(CONFIG_IIO)) 653 + if (IS_ENABLED(CONFIG_IIO) && !gpio_mode_enforce) 661 654 return 0; 662 655 663 656 ret = mcp_gpio_read_sram(mcp); ··· 1052 1045 #if IS_REACHABLE(CONFIG_IIO) 1053 1046 struct mcp2221 *mcp = hid_get_drvdata(hdev); 1054 1047 1055 - cancel_delayed_work_sync(&mcp->init_work); 1048 + if (!gpio_mode_enforce) 1049 + cancel_delayed_work_sync(&mcp->init_work); 1056 1050 #endif 1057 1051 } 1058 1052 ··· 1327 1319 #endif 1328 1320 1329 1321 #if IS_REACHABLE(CONFIG_IIO) 1330 - INIT_DELAYED_WORK(&mcp->init_work, mcp_init_work); 1331 - schedule_delayed_work(&mcp->init_work, msecs_to_jiffies(100)); 1322 + if (!gpio_mode_enforce) { 1323 + INIT_DELAYED_WORK(&mcp->init_work, mcp_init_work); 1324 + schedule_delayed_work(&mcp->init_work, msecs_to_jiffies(100)); 1325 + } 1332 1326 #endif 1333 1327 1334 1328 return 0;
+4 -8
drivers/hid/hid-pl.c
··· 24 24 */ 25 25 26 26 27 - /* #define DEBUG */ 28 - 29 - #define debug(format, arg...) pr_debug("hid-plff: " format "\n" , ## arg) 30 - 31 27 #include <linux/input.h> 32 28 #include <linux/slab.h> 33 29 #include <linux/module.h> ··· 49 53 50 54 left = effect->u.rumble.strong_magnitude; 51 55 right = effect->u.rumble.weak_magnitude; 52 - debug("called with 0x%04x 0x%04x", left, right); 56 + hid_dbg(dev, "called with 0x%04x 0x%04x", left, right); 53 57 54 58 left = left * plff->maxval / 0xffff; 55 59 right = right * plff->maxval / 0xffff; 56 60 57 61 *plff->strong = left; 58 62 *plff->weak = right; 59 - debug("running with 0x%02x 0x%02x", left, right); 63 + hid_dbg(dev, "running with 0x%02x 0x%02x", left, right); 60 64 hid_hw_request(hid, plff->report, HID_REQ_SET_REPORT); 61 65 62 66 return 0; ··· 115 119 report->field[0]->value[1] = 0x00; 116 120 strong = &report->field[0]->value[2]; 117 121 weak = &report->field[0]->value[3]; 118 - debug("detected single-field device"); 122 + hid_dbg(hid, "detected single-field device"); 119 123 } else if (report->field[0]->maxusage == 1 && 120 124 report->field[0]->usage[0].hid == 121 125 (HID_UP_LED | 0x43) && ··· 130 134 weak = &report->field[3]->value[0]; 131 135 if (hid->vendor == USB_VENDOR_ID_JESS2) 132 136 maxval = 0xff; 133 - debug("detected 4-field device"); 137 + hid_dbg(hid, "detected 4-field device"); 134 138 } else { 135 139 hid_err(hid, "not enough fields or values\n"); 136 140 return -ENODEV;
+12
drivers/hid/hid-playstation.c
··· 2377 2377 struct dualshock4_input_report_usb *usb = 2378 2378 (struct dualshock4_input_report_usb *)data; 2379 2379 2380 + if (usb->num_touch_reports > ARRAY_SIZE(usb->touch_reports)) { 2381 + hid_err(hdev, "DualShock4 USB input report has invalid num_touch_reports=%d\n", 2382 + usb->num_touch_reports); 2383 + return -EINVAL; 2384 + } 2385 + 2380 2386 ds4_report = &usb->common; 2381 2387 num_touch_reports = usb->num_touch_reports; 2382 2388 touch_reports = usb->touch_reports; ··· 2395 2389 if (!ps_check_crc32(PS_INPUT_CRC32_SEED, data, size - 4, report_crc)) { 2396 2390 hid_err(hdev, "DualShock4 input CRC's check failed\n"); 2397 2391 return -EILSEQ; 2392 + } 2393 + 2394 + if (bt->num_touch_reports > ARRAY_SIZE(bt->touch_reports)) { 2395 + hid_err(hdev, "DualShock4 BT input report has invalid num_touch_reports=%d\n", 2396 + bt->num_touch_reports); 2397 + return -EINVAL; 2398 2398 } 2399 2399 2400 2400 ds4_report = &bt->common;
+40 -7
drivers/hid/hid-quirks.c
··· 134 134 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019), HID_QUIRK_ALWAYS_POLL }, 135 135 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E), HID_QUIRK_ALWAYS_POLL }, 136 136 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6093), HID_QUIRK_ALWAYS_POLL }, 137 + { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER), HID_QUIRK_ALWAYS_POLL }, 137 138 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007), HID_QUIRK_ALWAYS_POLL }, 138 139 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077), HID_QUIRK_ALWAYS_POLL }, 139 140 { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS), HID_QUIRK_NOGET }, ··· 692 691 { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD, USB_DEVICE_ID_SUPER_JOY_BOX_5_PRO) }, 693 692 #endif 694 693 #if IS_ENABLED(CONFIG_HID_SONY) 694 + { HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS4_GIBSON_SG) }, 695 + { HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS4_GIBSON_SG_DONGLE) }, 696 + { HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS5_GIBSON_SG) }, 697 + { HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS5_GIBSON_SG_DONGLE) }, 698 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB1_DRUMS) }, 699 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB1_GUITAR) }, 700 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB2_DRUMS) }, 701 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB2_GUITAR) }, 702 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_KEYBOARD) }, 703 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_DRUMS_MODE) }, 704 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_KEYBOARD_MODE) }, 705 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_MUSTANG_MODE) }, 706 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_SQUIER_MODE) }, 707 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MUSTANG_GUITAR) }, 695 708 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) }, 696 - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE) }, 709 + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_PS4_STRATOCASTER) }, 710 + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_PDP, USB_DEVICE_ID_PDP_PS4_JAGUAR) }, 711 + { HID_USB_DEVICE(USB_VENDOR_ID_PDP, USB_DEVICE_ID_PDP_PS4_RIFFMASTER) }, 712 + { HID_USB_DEVICE(USB_VENDOR_ID_PDP, USB_DEVICE_ID_PDP_PS5_RIFFMASTER) }, 713 + { HID_USB_DEVICE(USB_VENDOR_ID_REDOCTANE, USB_DEVICE_ID_REDOCTANE_GUITAR_DONGLE) }, 714 + { HID_USB_DEVICE(USB_VENDOR_ID_REDOCTANE, USB_DEVICE_ID_REDOCTANE_PS4_GHLIVE_DONGLE) }, 715 + { HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER) }, 697 716 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_NSG_MR5U_REMOTE) }, 698 717 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_NSG_MR7U_REMOTE) }, 718 + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_PS3_BDREMOTE) }, 699 719 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_BUZZ_CONTROLLER) }, 700 - { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) }, 701 - { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER) }, 702 720 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER) }, 703 - { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) }, 721 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_MOTION_CONTROLLER) }, 704 722 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) }, 723 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) }, 705 724 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) }, 706 - { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 707 725 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 708 - { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, 726 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, 709 727 { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) }, 710 - { HID_USB_DEVICE(USB_VENDOR_ID_SINO_LITE, USB_DEVICE_ID_SINO_LITE_CONTROLLER) }, 728 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE) }, 729 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_WIRELESS_BUZZ_CONTROLLER) }, 730 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3WIIU_GHLIVE) }, 731 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_DJH_TURNTABLE) }, 732 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_GH_DRUMS) }, 733 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_GH_GUITAR) }, 734 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_KEYBOARD) }, 735 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_DRUMS_MODE) }, 736 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_KEYBOARD_MODE) }, 737 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_MUSTANG_MODE) }, 738 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_SQUIER_MODE) }, 739 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MUSTANG_GUITAR) }, 740 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB_DRUMS) }, 741 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB_GUITAR) }, 711 742 #endif 712 743 #if IS_ENABLED(CONFIG_HID_SPEEDLINK) 713 744 { HID_USB_DEVICE(USB_VENDOR_ID_X_TENSIONS, USB_DEVICE_ID_SPEEDLINK_VAD_CEZANNE) },
+283 -70
drivers/hid/hid-sony.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-or-later 2 2 /* 3 - * HID driver for Sony / PS2 / PS3 / PS4 BD devices. 3 + * HID driver for Sony / PS2 / PS3 BD / PS4 / PS5 devices. 4 4 * 5 5 * Copyright (c) 1999 Andreas Gal 6 6 * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> ··· 12 12 * Copyright (c) 2014-2016 Frank Praznik <frank.praznik@gmail.com> 13 13 * Copyright (c) 2018 Todd Kelner 14 14 * Copyright (c) 2020-2021 Pascal Giard <pascal.giard@etsmtl.ca> 15 - * Copyright (c) 2020 Sanjay Govind <sanjay.govind9@gmail.com> 15 + * Copyright (c) 2020-2026 Sanjay Govind <sanjay.govind9@gmail.com> 16 16 * Copyright (c) 2021 Daniel Nguyen <daniel.nguyen.1@ens.etsmtl.ca> 17 17 * Copyright (c) 2026 Rosalie Wanders <rosalie@mailbox.org> 18 + * Copyright (c) 2026 Brenton Simpson <appsforartists@google.com> 18 19 */ 19 20 20 21 /* ··· 60 59 #define NSG_MR5U_REMOTE_BT BIT(11) 61 60 #define NSG_MR7U_REMOTE_BT BIT(12) 62 61 #define SHANWAN_GAMEPAD BIT(13) 63 - #define GH_GUITAR_CONTROLLER BIT(14) 64 - #define GHL_GUITAR_PS3WIIU BIT(15) 65 - #define GHL_GUITAR_PS4 BIT(16) 66 - #define RB4_GUITAR_PS4_USB BIT(17) 67 - #define RB4_GUITAR_PS4_BT BIT(18) 68 - #define RB4_GUITAR_PS5 BIT(19) 62 + #define INSTRUMENT BIT(14) 63 + #define GH_GUITAR_TILT BIT(15) 64 + #define GHL_GUITAR_PS3WIIU BIT(16) 65 + #define GHL_GUITAR_PS4 BIT(17) 66 + #define RB4_GUITAR_PS4_USB BIT(18) 67 + #define RB4_GUITAR_PS4_BT BIT(19) 68 + #define RB4_GUITAR_PS5 BIT(20) 69 + #define RB3_PRO_INSTRUMENT BIT(21) 70 + #define DJH_TURNTABLE BIT(22) 69 71 70 72 #define SIXAXIS_CONTROLLER (SIXAXIS_CONTROLLER_USB | SIXAXIS_CONTROLLER_BT) 71 73 #define MOTION_CONTROLLER (MOTION_CONTROLLER_USB | MOTION_CONTROLLER_BT) ··· 76 72 NAVIGATION_CONTROLLER_BT) 77 73 #define SONY_LED_SUPPORT (SIXAXIS_CONTROLLER | BUZZ_CONTROLLER |\ 78 74 MOTION_CONTROLLER | NAVIGATION_CONTROLLER) 79 - #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER) 75 + #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER |\ 76 + RB4_GUITAR_PS5) 80 77 #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | MOTION_CONTROLLER) 81 78 #define SONY_BT_DEVICE (SIXAXIS_CONTROLLER_BT | MOTION_CONTROLLER_BT | NAVIGATION_CONTROLLER_BT) 82 79 #define NSG_MRXU_REMOTE (NSG_MR5U_REMOTE_BT | NSG_MR7U_REMOTE_BT) ··· 91 86 */ 92 87 #define GHL_GUITAR_POKE_INTERVAL 8 /* In seconds */ 93 88 #define GUITAR_TILT_USAGE 44 89 + 90 + #define TURNTABLE_EFFECTS_KNOB_USAGE 44 91 + #define TURNTABLE_PLATTER_BUTTONS_USAGE 45 92 + #define TURNTABLE_CROSS_FADER_USAGE 46 94 93 95 94 /* Magic data taken from GHLtarUtility: 96 95 * https://github.com/ghlre/GHLtarUtility/blob/master/PS3Guitar.cs ··· 436 427 [0x31] = ABS_Y, 437 428 }; 438 429 439 - static const unsigned int rb4_keymap[] = { 440 - [0x1] = BTN_WEST, /* Square */ 441 - [0x2] = BTN_SOUTH, /* Cross */ 442 - [0x3] = BTN_EAST, /* Circle */ 443 - [0x4] = BTN_NORTH, /* Triangle */ 444 - [0x5] = BTN_TL, /* L1 */ 445 - [0x6] = BTN_TR, /* R1 */ 446 - [0x7] = BTN_TL2, /* L2 */ 447 - [0x8] = BTN_TR2, /* R2 */ 448 - [0x9] = BTN_SELECT, /* Share */ 449 - [0xa] = BTN_START, /* Options */ 450 - [0xb] = BTN_THUMBL, /* L3 */ 451 - [0xc] = BTN_THUMBR, /* R3 */ 452 - [0xd] = BTN_MODE, /* PS */ 430 + static const unsigned int ps3_turntable_absmap[] = { 431 + [0x32] = ABS_X, 432 + [0x35] = ABS_Y, 433 + }; 434 + 435 + static const unsigned int instrument_keymap[] = { 436 + [0x1] = BTN_WEST, 437 + [0x2] = BTN_SOUTH, 438 + [0x3] = BTN_EAST, 439 + [0x4] = BTN_NORTH, 440 + [0x5] = BTN_TL, 441 + [0x6] = BTN_TR, 442 + [0x7] = BTN_TL2, 443 + [0x8] = BTN_TR2, 444 + [0x9] = BTN_SELECT, 445 + [0xa] = BTN_START, 446 + [0xb] = BTN_THUMBL, 447 + [0xc] = BTN_THUMBR, 448 + [0xd] = BTN_MODE, 453 449 }; 454 450 455 451 static enum power_supply_property sony_battery_props[] = { ··· 471 457 u8 duty_off; /* % of duty_length the led is off (0xff means 100%) */ 472 458 u8 duty_on; /* % of duty_length the led is on (0xff mean 100%) */ 473 459 } __packed; 460 + static_assert(sizeof(struct sixaxis_led) == 5); 474 461 475 462 struct sixaxis_rumble { 476 463 u8 padding; ··· 480 465 u8 left_duration; /* Left motor duration (0xff means forever) */ 481 466 u8 left_motor_force; /* left (large) motor, supports force values from 0 to 255 */ 482 467 } __packed; 468 + static_assert(sizeof(struct sixaxis_rumble) == 5); 483 469 484 470 struct sixaxis_output_report { 485 471 u8 report_id; ··· 490 474 struct sixaxis_led led[4]; /* LEDx at (4 - x) */ 491 475 struct sixaxis_led _reserved; /* LED5, not actually soldered */ 492 476 } __packed; 477 + static_assert(sizeof(struct sixaxis_output_report) == 36); 493 478 494 479 union sixaxis_output_report_01 { 495 480 struct sixaxis_output_report data; 496 481 u8 buf[36]; 497 482 }; 483 + static_assert(sizeof(union sixaxis_output_report_01) == 36); 498 484 499 485 struct motion_output_report_02 { 500 486 u8 type, zero; ··· 504 486 u8 zero2; 505 487 u8 rumble; 506 488 }; 489 + static_assert(sizeof(struct motion_output_report_02) == 7); 507 490 508 491 #define SIXAXIS_REPORT_0xF2_SIZE 17 509 492 #define SIXAXIS_REPORT_0xF5_SIZE 8 510 493 #define MOTION_REPORT_0x02_SIZE 49 494 + #define PRO_INSTRUMENT_0x00_SIZE 8 511 495 512 496 #define SENSOR_SUFFIX " Motion Sensors" 513 497 #define TOUCHPAD_SUFFIX " Touchpad" ··· 535 515 struct led_classdev *leds[MAX_LEDS]; 536 516 unsigned long quirks; 537 517 struct work_struct state_worker; 538 - void (*send_output_report)(struct sony_sc *); 518 + void (*send_output_report)(struct sony_sc *sc); 539 519 struct power_supply *battery; 540 520 struct power_supply_desc battery_desc; 541 521 int device_id; ··· 559 539 /* GH Live */ 560 540 struct urb *ghl_urb; 561 541 struct timer_list ghl_poke_timer; 542 + 543 + /* Rock Band 3 Pro Instruments */ 544 + unsigned long rb3_pro_poke_jiffies; 562 545 }; 563 546 564 547 static void sony_set_leds(struct sony_sc *sc); ··· 612 589 pipe = usb_sndctrlpipe(usbdev, 0); 613 590 614 591 cr = devm_kzalloc(&sc->hdev->dev, sizeof(*cr), GFP_ATOMIC); 615 - if (cr == NULL) 592 + if (!cr) 616 593 return -ENOMEM; 617 594 618 595 databuf = devm_kzalloc(&sc->hdev->dev, poke_size, GFP_ATOMIC); 619 - if (databuf == NULL) 596 + if (!databuf) 620 597 return -ENOMEM; 621 598 622 599 cr->bRequestType = ··· 630 607 sc->ghl_urb, usbdev, pipe, 631 608 (unsigned char *) cr, databuf, poke_size, 632 609 ghl_magic_poke_cb, sc); 610 + return 0; 611 + } 612 + 613 + 614 + 615 + /* 616 + * Sending HID_REQ_SET_REPORT enables the full report. Without this 617 + * Rock Band 3 Pro instruments only report navigation events 618 + */ 619 + static int rb3_pro_instrument_enable_full_report(struct sony_sc *sc) 620 + { 621 + struct hid_device *hdev = sc->hdev; 622 + static const u8 report[] = { 0x00, 0xE9, 0x00, 0x89, 0x1B, 623 + 0x00, 0x00, 0x00, 0x02, 0x00, 624 + 0x00, 0x00, 0x00, 0x00, 0x00, 625 + 0x00, 0x00, 0x00, 0x00, 0x00, 626 + 0x00, 0x00, 0x80, 0x00, 0x00, 627 + 0x00, 0x00, 0x89, 0x00, 0x00, 628 + 0x00, 0x00, 0x00, 0xE9, 0x01, 629 + 0x00, 0x00, 0x00, 0x00, 0x00, 630 + 0x00 }; 631 + u8 *buf; 632 + int ret; 633 + 634 + buf = kmemdup(report, sizeof(report), GFP_KERNEL); 635 + if (!buf) 636 + return -ENOMEM; 637 + 638 + ret = hid_hw_raw_request(hdev, buf[0], buf, sizeof(report), 639 + HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 640 + 641 + kfree(buf); 642 + 643 + return ret; 644 + } 645 + 646 + static int djh_turntable_mapping(struct hid_device *hdev, struct hid_input *hi, 647 + struct hid_field *field, struct hid_usage *usage, 648 + unsigned long **bit, int *max) 649 + { 650 + if ((usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR) { 651 + unsigned int abs = usage->hid & HID_USAGE; 652 + 653 + if (abs == TURNTABLE_CROSS_FADER_USAGE) { 654 + hid_map_usage_clear(hi, usage, bit, max, EV_ABS, ABS_RX); 655 + return 1; 656 + } else if (abs == TURNTABLE_EFFECTS_KNOB_USAGE) { 657 + hid_map_usage_clear(hi, usage, bit, max, EV_ABS, ABS_RY); 658 + return 1; 659 + } else if (abs == TURNTABLE_PLATTER_BUTTONS_USAGE) { 660 + hid_map_usage_clear(hi, usage, bit, max, EV_ABS, ABS_RZ); 661 + return 1; 662 + } 663 + } else if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK) { 664 + unsigned int abs = usage->hid & HID_USAGE; 665 + 666 + if (abs >= ARRAY_SIZE(ps3_turntable_absmap)) 667 + return -1; 668 + 669 + abs = ps3_turntable_absmap[abs]; 670 + 671 + hid_map_usage_clear(hi, usage, bit, max, EV_ABS, abs); 672 + return 1; 673 + } 674 + return 0; 675 + } 676 + 677 + static int instrument_mapping(struct hid_device *hdev, struct hid_input *hi, 678 + struct hid_field *field, struct hid_usage *usage, 679 + unsigned long **bit, int *max) 680 + { 681 + if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) { 682 + unsigned int key = usage->hid & HID_USAGE; 683 + 684 + if (key >= ARRAY_SIZE(instrument_keymap)) 685 + return 0; 686 + 687 + key = instrument_keymap[key]; 688 + hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 689 + return 1; 690 + } 691 + 633 692 return 0; 634 693 } 635 694 ··· 734 629 struct hid_field *field, struct hid_usage *usage, 735 630 unsigned long **bit, int *max) 736 631 { 737 - if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON) { 738 - unsigned int key = usage->hid & HID_USAGE; 739 - 740 - if (key >= ARRAY_SIZE(rb4_keymap)) 741 - return 0; 742 - 743 - key = rb4_keymap[key]; 744 - hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key); 745 - return 1; 746 - } else if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK) { 632 + if ((usage->hid & HID_USAGE_PAGE) == HID_UP_GENDESK) { 747 633 unsigned int abs = usage->hid & HID_USAGE; 748 634 749 635 /* Let the HID parser deal with the HAT. */ ··· 951 855 static const u8 sixaxis_battery_capacity[] = { 0, 1, 25, 50, 75, 100 }; 952 856 unsigned long flags; 953 857 int offset; 858 + u8 index; 954 859 u8 battery_capacity; 955 860 int battery_status; 956 861 ··· 967 870 battery_capacity = 100; 968 871 battery_status = (rd[offset] & 0x01) ? POWER_SUPPLY_STATUS_FULL : POWER_SUPPLY_STATUS_CHARGING; 969 872 } else { 970 - u8 index = rd[offset] <= 5 ? rd[offset] : 5; 873 + index = rd[offset] <= 5 ? rd[offset] : 5; 971 874 battery_capacity = sixaxis_battery_capacity[index]; 972 875 battery_status = POWER_SUPPLY_STATUS_DISCHARGING; 973 876 } ··· 1005 908 * the touch-related data starts at offset 2. 1006 909 * For the first byte, bit 0 is set when touchpad button is pressed. 1007 910 * Bit 2 is set when a touch is active and the drag (Fn) key is pressed. 1008 - * This drag key is mapped to BTN_LEFT. It is operational only when a 911 + * This drag key is mapped to BTN_LEFT. It is operational only when a 1009 912 * touch point is active. 1010 913 * Bit 4 is set when only the first touch point is active. 1011 914 * Bit 6 is set when only the second touch point is active. ··· 1088 991 1089 992 static void rb4_ps5_guitar_parse_report(struct sony_sc *sc, u8 *rd, int size) 1090 993 { 994 + u8 charging_status; 995 + u8 battery_data; 996 + u8 battery_capacity; 997 + u8 battery_status; 998 + unsigned long flags; 999 + 1091 1000 /* 1092 1001 * Rock Band 4 PS5 guitars have whammy and 1093 1002 * tilt functionality, they're located at ··· 1105 1002 */ 1106 1003 input_report_abs(sc->input_dev, ABS_Z, rd[41]); 1107 1004 input_report_abs(sc->input_dev, ABS_RZ, rd[42]); 1005 + 1006 + /* 1007 + * Rock Band 4 PS5 guitars also report the 1008 + * battery status and level at byte 30. 1009 + */ 1010 + charging_status = (rd[30] >> 4) & 0x0F; 1011 + battery_data = rd[30] & 0x0F; 1012 + 1013 + switch (charging_status) { 1014 + case 0x0: 1015 + battery_capacity = min(battery_data * 10 + 5, 100); 1016 + battery_status = POWER_SUPPLY_STATUS_DISCHARGING; 1017 + break; 1018 + case 0x1: 1019 + battery_capacity = min(battery_data * 10 + 5, 100); 1020 + battery_status = POWER_SUPPLY_STATUS_CHARGING; 1021 + break; 1022 + case 0x2: 1023 + battery_capacity = 100; 1024 + battery_status = POWER_SUPPLY_STATUS_FULL; 1025 + break; 1026 + default: 1027 + battery_capacity = 0; 1028 + battery_status = POWER_SUPPLY_STATUS_UNKNOWN; 1029 + break; 1030 + } 1031 + 1032 + spin_lock_irqsave(&sc->lock, flags); 1033 + sc->battery_capacity = battery_capacity; 1034 + sc->battery_status = battery_status; 1035 + spin_unlock_irqrestore(&sc->lock, flags); 1108 1036 1109 1037 input_sync(sc->input_dev); 1110 1038 } ··· 1186 1052 return 1; 1187 1053 } 1188 1054 1055 + /* Rock Band 3 PS3 Pro instruments set rd[24] to 0xE0 when they're 1056 + * sending full reports, and 0x02 when only sending navigation. 1057 + */ 1058 + if ((sc->quirks & RB3_PRO_INSTRUMENT) && rd[24] == 0x02) { 1059 + /* Only attempt to enable full report every 8 seconds */ 1060 + if (time_after(jiffies, sc->rb3_pro_poke_jiffies)) { 1061 + sc->rb3_pro_poke_jiffies = jiffies + secs_to_jiffies(8); 1062 + rb3_pro_instrument_enable_full_report(sc); 1063 + } 1064 + } 1065 + 1189 1066 if (sc->defer_initialization) { 1190 1067 sc->defer_initialization = 0; 1191 1068 sony_schedule_work(sc, SONY_WORKER_STATE); ··· 1210 1065 unsigned long **bit, int *max) 1211 1066 { 1212 1067 struct sony_sc *sc = hid_get_drvdata(hdev); 1068 + int ret; 1213 1069 1214 1070 if (sc->quirks & BUZZ_CONTROLLER) { 1215 1071 unsigned int key = usage->hid & HID_USAGE; ··· 1244 1098 if (sc->quirks & SIXAXIS_CONTROLLER) 1245 1099 return sixaxis_mapping(hdev, hi, field, usage, bit, max); 1246 1100 1247 - if (sc->quirks & GH_GUITAR_CONTROLLER) 1101 + /* INSTRUMENT quirk is used as a base mapping for instruments */ 1102 + if (sc->quirks & INSTRUMENT) { 1103 + ret = instrument_mapping(hdev, hi, field, usage, bit, max); 1104 + if (ret != 0) 1105 + return ret; 1106 + } 1107 + 1108 + if (sc->quirks & GH_GUITAR_TILT) 1248 1109 return gh_guitar_mapping(hdev, hi, field, usage, bit, max); 1110 + 1111 + if (sc->quirks & DJH_TURNTABLE) 1112 + return djh_turntable_mapping(hdev, hi, field, usage, bit, max); 1249 1113 1250 1114 if (sc->quirks & (RB4_GUITAR_PS4_USB | RB4_GUITAR_PS4_BT)) 1251 1115 return rb4_guitar_mapping(hdev, hi, field, usage, bit, max); ··· 1309 1153 input_set_abs_params(sc->touchpad, ABS_MT_POSITION_Y, 0, h, 0, 0); 1310 1154 1311 1155 if (touch_major > 0) { 1312 - input_set_abs_params(sc->touchpad, ABS_MT_TOUCH_MAJOR, 1156 + input_set_abs_params(sc->touchpad, ABS_MT_TOUCH_MAJOR, 1313 1157 0, touch_major, 0, 0); 1314 1158 if (touch_minor > 0) 1315 - input_set_abs_params(sc->touchpad, ABS_MT_TOUCH_MINOR, 1159 + input_set_abs_params(sc->touchpad, ABS_MT_TOUCH_MINOR, 1316 1160 0, touch_minor, 0, 0); 1317 1161 if (orientation > 0) 1318 - input_set_abs_params(sc->touchpad, ABS_MT_ORIENTATION, 1162 + input_set_abs_params(sc->touchpad, ABS_MT_ORIENTATION, 1319 1163 0, orientation, 0, 0); 1320 1164 } 1321 1165 1322 - if (sc->quirks & NSG_MRXU_REMOTE) { 1166 + if (sc->quirks & NSG_MRXU_REMOTE) 1323 1167 __set_bit(EV_REL, sc->touchpad->evbit); 1324 - } 1325 1168 1326 1169 ret = input_mt_init_slots(sc->touchpad, touch_count, INPUT_MT_POINTER); 1327 1170 if (ret < 0) ··· 1475 1320 1476 1321 int id = sc->device_id; 1477 1322 1478 - BUILD_BUG_ON(MAX_LEDS < ARRAY_SIZE(sixaxis_leds[0])); 1323 + BUILD_BUG_ON(ARRAY_SIZE(sixaxis_leds[0]) > MAX_LEDS); 1479 1324 1480 1325 if (id < 0) 1481 1326 return; ··· 1493 1338 struct hid_report, list); 1494 1339 s32 *value = report->field[0]->value; 1495 1340 1496 - BUILD_BUG_ON(MAX_LEDS < 4); 1341 + BUILD_BUG_ON(4 > MAX_LEDS); 1497 1342 1498 1343 value[0] = 0x00; 1499 1344 value[1] = sc->led_state[0] ? 0xff : 0x00; ··· 1690 1535 name_sz = strlen(dev_name(&hdev->dev)) + strlen(color_name_str[n]) + 2; 1691 1536 1692 1537 led = devm_kzalloc(&hdev->dev, sizeof(struct led_classdev) + name_sz, GFP_KERNEL); 1693 - if (!led) { 1694 - hid_err(hdev, "Couldn't allocate memory for LED %d\n", n); 1538 + if (!led) 1695 1539 return -ENOMEM; 1696 - } 1697 1540 1698 1541 name = (void *)(&led[1]); 1699 1542 if (use_color_names) 1700 - snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), 1701 - color_name_str[n]); 1543 + snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), color_name_str[n]); 1702 1544 else 1703 1545 snprintf(name, name_sz, name_fmt, dev_name(&hdev->dev), n + 1); 1704 1546 led->name = name; ··· 2212 2060 } 2213 2061 2214 2062 sony_init_output_report(sc, sixaxis_send_output_report); 2063 + } else if (sc->quirks & RB3_PRO_INSTRUMENT) { 2064 + /* 2065 + * Rock Band 3 PS3 Pro Instruments also do not handle HID Output 2066 + * Reports on the interrupt EP like they should, so we need to force 2067 + * HID output reports to use HID_REQ_SET_REPORT on the Control EP. 2068 + * 2069 + * There is also another issue about HID Output Reports via USB, 2070 + * these instruments do not want the report_id as part of the data 2071 + * packet, so we have to discard buf[0] when sending the actual 2072 + * control message, even for numbered reports. 2073 + */ 2074 + hdev->quirks |= HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP; 2075 + hdev->quirks |= HID_QUIRK_SKIP_OUTPUT_REPORT_ID; 2215 2076 } else if (sc->quirks & SIXAXIS_CONTROLLER_USB) { 2216 2077 /* 2217 2078 * The Sony Sixaxis does not handle HID Output Reports on the ··· 2341 2176 quirks |= SHANWAN_GAMEPAD; 2342 2177 2343 2178 sc = devm_kzalloc(&hdev->dev, sizeof(*sc), GFP_KERNEL); 2344 - if (sc == NULL) { 2345 - hid_err(hdev, "can't alloc sony descriptor\n"); 2179 + if (!sc) 2346 2180 return -ENOMEM; 2347 - } 2348 2181 2349 2182 spin_lock_init(&sc->lock); 2350 2183 ··· 2389 2226 ret = -ENODEV; 2390 2227 goto err; 2391 2228 } 2229 + 2230 + if (sc->quirks & RB3_PRO_INSTRUMENT) 2231 + sc->rb3_pro_poke_jiffies = 0; 2392 2232 2393 2233 if (sc->quirks & (GHL_GUITAR_PS3WIIU | GHL_GUITAR_PS4)) { 2394 2234 if (!hid_is_usb(hdev)) { ··· 2530 2364 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SMK, USB_DEVICE_ID_SMK_NSG_MR7U_REMOTE), 2531 2365 .driver_data = NSG_MR7U_REMOTE_BT }, 2532 2366 /* Guitar Hero Live PS3 and Wii U guitar dongles */ 2533 - { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3WIIU_GHLIVE_DONGLE), 2534 - .driver_data = GHL_GUITAR_PS3WIIU | GH_GUITAR_CONTROLLER }, 2367 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3WIIU_GHLIVE), 2368 + .driver_data = GHL_GUITAR_PS3WIIU | GH_GUITAR_TILT | INSTRUMENT }, 2535 2369 /* Guitar Hero PC Guitar Dongle */ 2536 2370 { HID_USB_DEVICE(USB_VENDOR_ID_REDOCTANE, USB_DEVICE_ID_REDOCTANE_GUITAR_DONGLE), 2537 - .driver_data = GH_GUITAR_CONTROLLER }, 2538 - /* Guitar Hero PS3 World Tour Guitar Dongle */ 2539 - { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_GUITAR_DONGLE), 2540 - .driver_data = GH_GUITAR_CONTROLLER }, 2371 + .driver_data = GH_GUITAR_TILT | INSTRUMENT }, 2372 + /* Guitar Hero PS3 Guitar Dongle */ 2373 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_GH_GUITAR), 2374 + .driver_data = GH_GUITAR_TILT | INSTRUMENT }, 2375 + /* Guitar Hero PS3 Drum Dongle */ 2376 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_GH_DRUMS), 2377 + .driver_data = INSTRUMENT }, 2378 + /* DJ Hero PS3 Guitar Dongle */ 2379 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_DJH_TURNTABLE), 2380 + .driver_data = DJH_TURNTABLE | INSTRUMENT }, 2541 2381 /* Guitar Hero Live PS4 guitar dongles */ 2542 2382 { HID_USB_DEVICE(USB_VENDOR_ID_REDOCTANE, USB_DEVICE_ID_REDOCTANE_PS4_GHLIVE_DONGLE), 2543 - .driver_data = GHL_GUITAR_PS4 | GH_GUITAR_CONTROLLER }, 2383 + .driver_data = GHL_GUITAR_PS4 | GH_GUITAR_TILT | INSTRUMENT }, 2384 + /* Rock Band 1 Wii instruments */ 2385 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB1_GUITAR), 2386 + .driver_data = INSTRUMENT }, 2387 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB1_DRUMS), 2388 + .driver_data = INSTRUMENT }, 2389 + /* Rock Band 2 Wii instruments */ 2390 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB2_GUITAR), 2391 + .driver_data = INSTRUMENT }, 2392 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB2_DRUMS), 2393 + .driver_data = INSTRUMENT }, 2394 + /* Rock Band 3 Wii instruments */ 2395 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_DRUMS_MODE), 2396 + .driver_data = INSTRUMENT }, 2397 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MUSTANG_GUITAR), 2398 + .driver_data = INSTRUMENT }, 2399 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_MUSTANG_MODE), 2400 + .driver_data = INSTRUMENT }, 2401 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_SQUIER_MODE), 2402 + .driver_data = INSTRUMENT }, 2403 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_KEYBOARD), 2404 + .driver_data = INSTRUMENT }, 2405 + { HID_USB_DEVICE(USB_VENDOR_ID_HARMONIX, USB_DEVICE_ID_HARMONIX_WII_RB3_MPA_KEYBOARD_MODE), 2406 + .driver_data = INSTRUMENT }, 2407 + /* Rock Band 3 PS3 instruments */ 2408 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB_GUITAR), 2409 + .driver_data = INSTRUMENT }, 2410 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB_DRUMS), 2411 + .driver_data = INSTRUMENT }, 2412 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_DRUMS_MODE), 2413 + .driver_data = INSTRUMENT }, 2414 + /* Rock Band 3 PS3 Pro instruments */ 2415 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MUSTANG_GUITAR), 2416 + .driver_data = INSTRUMENT | RB3_PRO_INSTRUMENT }, 2417 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_MUSTANG_MODE), 2418 + .driver_data = INSTRUMENT | RB3_PRO_INSTRUMENT }, 2419 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_SQUIER_MODE), 2420 + .driver_data = INSTRUMENT | RB3_PRO_INSTRUMENT }, 2421 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_KEYBOARD), 2422 + .driver_data = INSTRUMENT | RB3_PRO_INSTRUMENT }, 2423 + { HID_USB_DEVICE(USB_VENDOR_ID_SONY_RHYTHM, USB_DEVICE_ID_SONY_PS3_RB3_MPA_KEYBOARD_MODE), 2424 + .driver_data = INSTRUMENT | RB3_PRO_INSTRUMENT }, 2544 2425 /* Rock Band 4 PS4 guitars */ 2545 2426 { HID_USB_DEVICE(USB_VENDOR_ID_PDP, USB_DEVICE_ID_PDP_PS4_RIFFMASTER), 2546 - .driver_data = RB4_GUITAR_PS4_USB }, 2427 + .driver_data = RB4_GUITAR_PS4_USB | INSTRUMENT }, 2547 2428 { HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS4_GIBSON_SG), 2548 - .driver_data = RB4_GUITAR_PS4_USB }, 2429 + .driver_data = RB4_GUITAR_PS4_USB | INSTRUMENT }, 2549 2430 { HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS4_GIBSON_SG_DONGLE), 2550 - .driver_data = RB4_GUITAR_PS4_USB }, 2431 + .driver_data = RB4_GUITAR_PS4_USB | INSTRUMENT }, 2551 2432 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_PDP, USB_DEVICE_ID_PDP_PS4_JAGUAR), 2552 - .driver_data = RB4_GUITAR_PS4_BT }, 2433 + .driver_data = RB4_GUITAR_PS4_BT | INSTRUMENT }, 2553 2434 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_PS4_STRATOCASTER), 2554 - .driver_data = RB4_GUITAR_PS4_BT }, 2435 + .driver_data = RB4_GUITAR_PS4_BT | INSTRUMENT }, 2555 2436 /* Rock Band 4 PS5 guitars */ 2556 2437 { HID_USB_DEVICE(USB_VENDOR_ID_PDP, USB_DEVICE_ID_PDP_PS5_RIFFMASTER), 2557 - .driver_data = RB4_GUITAR_PS5 }, 2438 + .driver_data = RB4_GUITAR_PS5 | INSTRUMENT }, 2558 2439 { HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS5_GIBSON_SG), 2559 - .driver_data = RB4_GUITAR_PS5 }, 2440 + .driver_data = RB4_GUITAR_PS5 | INSTRUMENT }, 2560 2441 { HID_USB_DEVICE(USB_VENDOR_ID_CRKD, USB_DEVICE_ID_CRKD_PS5_GIBSON_SG_DONGLE), 2561 - .driver_data = RB4_GUITAR_PS5 }, 2442 + .driver_data = RB4_GUITAR_PS5 | INSTRUMENT }, 2562 2443 { } 2563 2444 }; 2564 2445 MODULE_DEVICE_TABLE(hid, sony_devices); ··· 2641 2428 module_init(sony_init); 2642 2429 module_exit(sony_exit); 2643 2430 2644 - MODULE_DESCRIPTION("HID driver for Sony / PS2 / PS3 / PS4 BD devices"); 2431 + MODULE_DESCRIPTION("HID driver for Sony / PS2 / PS3 BD / PS4 / PS5 devices"); 2645 2432 MODULE_LICENSE("GPL");
+182 -14
drivers/hid/hid-winwing.c
··· 12 12 #include <linux/kernel.h> 13 13 #include <linux/module.h> 14 14 #include <linux/mutex.h> 15 + #include <linux/workqueue.h> 15 16 16 17 #define MAX_REPORT 16 17 18 ··· 36 35 37 36 struct winwing_drv_data { 38 37 struct hid_device *hdev; 39 - __u8 *report_buf; 40 - struct mutex lock; 41 - int map_more_buttons; 42 - unsigned int num_leds; 38 + struct mutex lights_lock; 39 + __u8 *report_lights; 40 + __u8 *report_rumble; 41 + struct work_struct rumble_work; 42 + struct ff_rumble_effect rumble; 43 + int rumble_left; 44 + int rumble_right; 45 + int has_grip15; 43 46 struct winwing_led leds[]; 44 47 }; 45 48 ··· 52 47 { 53 48 struct winwing_led *led = (struct winwing_led *) cdev; 54 49 struct winwing_drv_data *data = hid_get_drvdata(led->hdev); 55 - __u8 *buf = data->report_buf; 50 + __u8 *buf = data->report_lights; 56 51 int ret; 57 52 58 - mutex_lock(&data->lock); 53 + mutex_lock(&data->lights_lock); 59 54 55 + /* 56 + * Mimicking requests captured by usbmon when LEDs 57 + * are controlled by the vendor's app in a VM. 58 + */ 60 59 buf[0] = 0x02; 61 60 buf[1] = 0x60; 62 61 buf[2] = 0xbe; ··· 78 69 79 70 ret = hid_hw_output_report(led->hdev, buf, 14); 80 71 81 - mutex_unlock(&data->lock); 72 + mutex_unlock(&data->lights_lock); 82 73 83 74 return ret; 84 75 } ··· 96 87 if (!data) 97 88 return -EINVAL; 98 89 99 - data->report_buf = devm_kmalloc(&hdev->dev, MAX_REPORT, GFP_KERNEL); 90 + data->report_lights = devm_kzalloc(&hdev->dev, MAX_REPORT, GFP_KERNEL); 100 91 101 - if (!data->report_buf) 92 + if (!data->report_lights) 102 93 return -ENOMEM; 103 94 104 95 for (i = 0; i < 3; i += 1) { ··· 126 117 return ret; 127 118 } 128 119 129 - static int winwing_map_button(int button, int map_more_buttons) 120 + static int winwing_map_button(int button, int has_grip15) 130 121 { 131 122 if (button < 1) 132 123 return KEY_RESERVED; ··· 150 141 return (button - 65) + BTN_TRIGGER_HAPPY17; 151 142 } 152 143 153 - if (!map_more_buttons) { 144 + if (!has_grip15) { 154 145 /* 155 146 * Not mapping numbers [33 .. 64] which 156 147 * are not assigned to any real buttons ··· 203 194 /* Button numbers start with 1 */ 204 195 button = usage->hid & HID_USAGE; 205 196 206 - code = winwing_map_button(button, data->map_more_buttons); 197 + code = winwing_map_button(button, data->has_grip15); 207 198 208 199 hid_map_usage(hi, usage, bit, max, EV_KEY, code); 209 200 210 201 return 1; 202 + } 203 + 204 + /* 205 + * If x ≤ 0, return 0; 206 + * if x is in [1 .. 65535], return a value in [1 .. 255] 207 + */ 208 + static inline int convert_magnitude(int x) 209 + { 210 + if (x < 1) 211 + return 0; 212 + 213 + return ((x * 255) >> 16) + 1; 214 + } 215 + 216 + static int winwing_haptic_rumble(struct winwing_drv_data *data) 217 + { 218 + __u8 *buf; 219 + __u8 m; 220 + 221 + if (!data) 222 + return -EINVAL; 223 + 224 + if (!data->hdev) 225 + return -EINVAL; 226 + 227 + buf = data->report_rumble; 228 + 229 + if (!buf) 230 + return -EINVAL; 231 + 232 + m = convert_magnitude(data->rumble.strong_magnitude); 233 + if (m != data->rumble_left) { 234 + int ret; 235 + 236 + /* 237 + * Mimicking requests captured by usbmon when rumble 238 + * is activated by the vendor's app in a VM. 239 + */ 240 + buf[0] = 0x02; 241 + buf[1] = 0x01; 242 + buf[2] = 0xbf; 243 + buf[3] = 0x00; 244 + buf[4] = 0x00; 245 + buf[5] = 0x03; 246 + buf[6] = 0x49; 247 + buf[7] = 0x00; 248 + buf[8] = m; 249 + buf[9] = 0x00; 250 + buf[10] = 0; 251 + buf[11] = 0; 252 + buf[12] = 0; 253 + buf[13] = 0; 254 + 255 + ret = hid_hw_output_report(data->hdev, buf, 14); 256 + if (ret < 0) { 257 + hid_err(data->hdev, "error %d (%*ph)\n", ret, 14, buf); 258 + return ret; 259 + } 260 + data->rumble_left = m; 261 + } 262 + 263 + m = convert_magnitude(data->rumble.weak_magnitude); 264 + if (m != data->rumble_right) { 265 + int ret; 266 + 267 + /* 268 + * Mimicking requests captured by usbmon when rumble 269 + * is activated by the vendor's app in a VM. 270 + */ 271 + buf[0] = 0x02; 272 + buf[1] = 0x03; 273 + buf[2] = 0xbf; 274 + buf[3] = 0x00; 275 + buf[4] = 0x00; 276 + buf[5] = 0x03; 277 + buf[6] = 0x49; 278 + buf[7] = 0x00; 279 + buf[8] = m; 280 + buf[9] = 0x00; 281 + buf[10] = 0; 282 + buf[11] = 0; 283 + buf[12] = 0; 284 + buf[13] = 0; 285 + 286 + ret = hid_hw_output_report(data->hdev, buf, 14); 287 + if (ret < 0) { 288 + hid_err(data->hdev, "error %d (%*ph)\n", ret, 14, buf); 289 + return ret; 290 + } 291 + data->rumble_right = m; 292 + } 293 + 294 + return 0; 295 + } 296 + 297 + 298 + static void winwing_haptic_rumble_cb(struct work_struct *work) 299 + { 300 + struct winwing_drv_data *data; 301 + 302 + data = container_of(work, struct winwing_drv_data, rumble_work); 303 + winwing_haptic_rumble(data); 304 + } 305 + 306 + static int winwing_play_effect(struct input_dev *dev, void *context, 307 + struct ff_effect *effect) 308 + { 309 + struct winwing_drv_data *data = (struct winwing_drv_data *) context; 310 + 311 + if (effect->type != FF_RUMBLE) 312 + return 0; 313 + 314 + if (!data) 315 + return -EINVAL; 316 + 317 + data->rumble = effect->u.rumble; 318 + 319 + return schedule_work(&data->rumble_work); 320 + } 321 + 322 + static int winwing_init_ff(struct hid_device *hdev, struct hid_input *hidinput) 323 + { 324 + struct winwing_drv_data *data; 325 + 326 + data = (struct winwing_drv_data *) hid_get_drvdata(hdev); 327 + if (!data) 328 + return -EINVAL; 329 + 330 + data->report_rumble = devm_kzalloc(&hdev->dev, MAX_REPORT, GFP_KERNEL); 331 + data->rumble_left = -1; 332 + data->rumble_right = -1; 333 + 334 + input_set_capability(hidinput->input, EV_FF, FF_RUMBLE); 335 + 336 + return input_ff_create_memless(hidinput->input, data, 337 + winwing_play_effect); 211 338 } 212 339 213 340 static int winwing_probe(struct hid_device *hdev, ··· 364 219 if (!data) 365 220 return -ENOMEM; 366 221 367 - data->map_more_buttons = id->driver_data; 368 - 222 + data->hdev = hdev; 223 + data->has_grip15 = id->driver_data; 369 224 hid_set_drvdata(hdev, data); 225 + 226 + INIT_WORK(&data->rumble_work, winwing_haptic_rumble_cb); 370 227 371 228 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 372 229 if (ret) { ··· 379 232 return 0; 380 233 } 381 234 235 + static void winwing_remove(struct hid_device *hdev) 236 + { 237 + struct winwing_drv_data *data; 238 + 239 + data = (struct winwing_drv_data *) hid_get_drvdata(hdev); 240 + 241 + if (data) 242 + cancel_work_sync(&data->rumble_work); 243 + 244 + hid_hw_close(hdev); 245 + hid_hw_stop(hdev); 246 + } 247 + 382 248 static int winwing_input_configured(struct hid_device *hdev, 383 249 struct hid_input *hidinput) 384 250 { 251 + struct winwing_drv_data *data; 385 252 int ret; 253 + 254 + data = (struct winwing_drv_data *) hid_get_drvdata(hdev); 386 255 387 256 ret = winwing_init_led(hdev, hidinput->input); 388 257 389 258 if (ret) 390 259 hid_err(hdev, "led init failed\n"); 391 260 261 + if (data->has_grip15) 262 + winwing_init_ff(hdev, hidinput); 263 + 392 264 return ret; 393 265 } 394 266 267 + /* Set driver_data to 1 for grips with rumble motor and more than 32 buttons */ 395 268 static const struct hid_device_id winwing_devices[] = { 396 269 { HID_USB_DEVICE(0x4098, 0xbd65), .driver_data = 1 }, /* TGRIP-15E */ 397 270 { HID_USB_DEVICE(0x4098, 0xbd64), .driver_data = 1 }, /* TGRIP-15EX */ ··· 428 261 .input_configured = winwing_input_configured, 429 262 .input_mapping = winwing_input_mapping, 430 263 .probe = winwing_probe, 264 + .remove = winwing_remove, 431 265 }; 432 266 module_hid_driver(winwing_driver); 433 267
+10 -6
drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
··· 753 753 if (!qsdev) 754 754 return -ENODEV; 755 755 756 - ret = quickspi_set_power(qsdev, HIDSPI_SLEEP); 757 - if (ret) 758 - return ret; 756 + if (!device_may_wakeup(qsdev->dev)) { 757 + ret = quickspi_set_power(qsdev, HIDSPI_SLEEP); 758 + if (ret) 759 + return ret; 760 + } 759 761 760 762 ret = thc_interrupt_quiesce(qsdev->thc_hw, true); 761 763 if (ret) ··· 796 794 if (ret) 797 795 return ret; 798 796 799 - ret = quickspi_set_power(qsdev, HIDSPI_ON); 800 - if (ret) 801 - return ret; 797 + if (!device_may_wakeup(qsdev->dev)) 798 + return quickspi_set_power(qsdev, HIDSPI_ON); 802 799 803 800 return 0; 804 801 } ··· 855 854 qsdev = pci_get_drvdata(pdev); 856 855 if (!qsdev) 857 856 return -ENODEV; 857 + 858 + /* Ignore the return value as platform will be poweroff soon */ 859 + quickspi_set_power(qsdev, HIDSPI_OFF); 858 860 859 861 ret = thc_interrupt_quiesce(qsdev->thc_hw, true); 860 862 if (ret)
+47
drivers/hid/intel-thc-hid/intel-thc/intel-thc-dev.c
··· 1112 1112 EXPORT_SYMBOL_NS_GPL(thc_port_select, "INTEL_THC"); 1113 1113 1114 1114 #define THC_SPI_FREQUENCY_7M 7812500 1115 + #define THC_SPI_FREQUENCY_10M 10416700 1115 1116 #define THC_SPI_FREQUENCY_15M 15625000 1116 1117 #define THC_SPI_FREQUENCY_17M 17857100 1117 1118 #define THC_SPI_FREQUENCY_20M 20833000 1118 1119 #define THC_SPI_FREQUENCY_25M 25000000 1119 1120 #define THC_SPI_FREQUENCY_31M 31250000 1121 + #define THC_SPI_FREQUENCY_35M 35714200 1120 1122 #define THC_SPI_FREQUENCY_41M 41666700 1123 + #define THC_SPI_FREQUENCY_50M 50000000 1121 1124 1122 1125 #define THC_SPI_LOW_FREQUENCY THC_SPI_FREQUENCY_17M 1123 1126 ··· 1128 1125 { 1129 1126 static const int frequency[] = { 1130 1127 THC_SPI_FREQUENCY_7M, 1128 + THC_SPI_FREQUENCY_10M, 1131 1129 THC_SPI_FREQUENCY_15M, 1132 1130 THC_SPI_FREQUENCY_17M, 1133 1131 THC_SPI_FREQUENCY_20M, 1134 1132 THC_SPI_FREQUENCY_25M, 1135 1133 THC_SPI_FREQUENCY_31M, 1134 + THC_SPI_FREQUENCY_35M, 1136 1135 THC_SPI_FREQUENCY_41M, 1136 + THC_SPI_FREQUENCY_50M, 1137 1137 }; 1138 1138 static const u8 frequency_div[] = { 1139 1139 THC_SPI_FRQ_DIV_2, 1140 + THC_SPI_FRQ_DIV_1, 1140 1141 THC_SPI_FRQ_DIV_1, 1141 1142 THC_SPI_FRQ_DIV_7, 1142 1143 THC_SPI_FRQ_DIV_6, 1143 1144 THC_SPI_FRQ_DIV_5, 1144 1145 THC_SPI_FRQ_DIV_4, 1145 1146 THC_SPI_FRQ_DIV_3, 1147 + THC_SPI_FRQ_DIV_3, 1148 + THC_SPI_FRQ_DIV_2, 1146 1149 }; 1147 1150 int size = ARRAY_SIZE(frequency); 1148 1151 u32 closest_freq; ··· 1198 1189 1199 1190 if (spi_freq_val < THC_SPI_LOW_FREQUENCY) 1200 1191 is_low_freq = true; 1192 + 1193 + /* 10M, 35M and 50M CLK need 1.5, 3.5 and 2.5 half divider */ 1194 + if ((freq_div == THC_SPI_FRQ_DIV_2 && spi_freq_val >= THC_SPI_FREQUENCY_50M) || 1195 + (freq_div == THC_SPI_FRQ_DIV_3 && spi_freq_val < THC_SPI_FREQUENCY_41M) || 1196 + (freq_div == THC_SPI_FRQ_DIV_1 && spi_freq_val < THC_SPI_FREQUENCY_15M)) { 1197 + regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPI_DUTYC_CFG_OFFSET, 1198 + THC_M_PRT_SPI_DUTYC_CFG_SPI_TCRF_HALF_DIV_EN, 1199 + THC_M_PRT_SPI_DUTYC_CFG_SPI_TCRF_HALF_DIV_EN); 1200 + 1201 + regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPARE_REG_OFFSET, 1202 + THC_M_PRT_SPARE_REG_SPI_CLK_INV_ENABLE, 1203 + THC_M_PRT_SPARE_REG_SPI_CLK_INV_ENABLE); 1204 + } else { 1205 + regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPI_DUTYC_CFG_OFFSET, 1206 + THC_M_PRT_SPI_DUTYC_CFG_SPI_TCRF_HALF_DIV_EN, 0); 1207 + 1208 + regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPARE_REG_OFFSET, 1209 + THC_M_PRT_SPARE_REG_SPI_CLK_INV_ENABLE, 0); 1210 + } 1201 1211 1202 1212 cfg = FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_TCRF, freq_div) | 1203 1213 FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_TRMODE, io_mode) | ··· 1270 1242 1271 1243 if (spi_freq_val < THC_SPI_LOW_FREQUENCY) 1272 1244 is_low_freq = true; 1245 + 1246 + /* 10M, 35M and 50M CLK need 1.5, 3.5 and 2.5 half divider */ 1247 + if ((freq_div == THC_SPI_FRQ_DIV_2 && spi_freq_val >= THC_SPI_FREQUENCY_50M) || 1248 + (freq_div == THC_SPI_FRQ_DIV_3 && spi_freq_val < THC_SPI_FREQUENCY_41M) || 1249 + (freq_div == THC_SPI_FRQ_DIV_1 && spi_freq_val < THC_SPI_FREQUENCY_15M)) { 1250 + regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPI_DUTYC_CFG_OFFSET, 1251 + THC_M_PRT_SPI_DUTYC_CFG_SPI_TCWF_HALF_DIV_EN, 1252 + THC_M_PRT_SPI_DUTYC_CFG_SPI_TCWF_HALF_DIV_EN); 1253 + 1254 + regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPARE_REG_OFFSET, 1255 + THC_M_PRT_SPARE_REG_SPI_CLK_INV_ENABLE, 1256 + THC_M_PRT_SPARE_REG_SPI_CLK_INV_ENABLE); 1257 + } else { 1258 + regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPI_DUTYC_CFG_OFFSET, 1259 + THC_M_PRT_SPI_DUTYC_CFG_SPI_TCWF_HALF_DIV_EN, 0); 1260 + 1261 + regmap_write_bits(dev->thc_regmap, THC_M_PRT_SPARE_REG_OFFSET, 1262 + THC_M_PRT_SPARE_REG_SPI_CLK_INV_ENABLE, 0); 1263 + } 1273 1264 1274 1265 cfg = FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_TCWF, freq_div) | 1275 1266 FIELD_PREP(THC_M_PRT_SPI_CFG_SPI_TWMODE, io_mode) |
+4
drivers/hid/intel-thc-hid/intel-thc/intel-thc-hw.h
··· 643 643 644 644 #define THC_M_PRT_SPI_DUTYC_CFG_SPI_CSA_CK_DELAY_VAL GENMASK(3, 0) 645 645 #define THC_M_PRT_SPI_DUTYC_CFG_SPI_CSA_CK_DELAY_EN BIT(25) 646 + #define THC_M_PRT_SPI_DUTYC_CFG_SPI_TCRF_HALF_DIV_EN BIT(30) 647 + #define THC_M_PRT_SPI_DUTYC_CFG_SPI_TCWF_HALF_DIV_EN BIT(31) 648 + 649 + #define THC_M_PRT_SPARE_REG_SPI_CLK_INV_ENABLE BIT(2) 646 650 647 651 /* CS Assertion delay default value */ 648 652 #define THC_CSA_CK_DELAY_VAL_DEFAULT 4
+4 -6
drivers/hid/usbhid/hid-core.c
··· 1363 1363 { 1364 1364 struct usb_host_interface *interface = intf->cur_altsetting; 1365 1365 struct usb_device *dev = interface_to_usbdev(intf); 1366 + struct usb_endpoint_descriptor *ep; 1366 1367 struct usbhid_device *usbhid; 1367 1368 struct hid_device *hid; 1368 - unsigned int n, has_in = 0; 1369 1369 size_t len; 1370 1370 int ret; 1371 1371 1372 1372 dbg_hid("HID probe called for ifnum %d\n", 1373 1373 intf->altsetting->desc.bInterfaceNumber); 1374 1374 1375 - for (n = 0; n < interface->desc.bNumEndpoints; n++) 1376 - if (usb_endpoint_is_int_in(&interface->endpoint[n].desc)) 1377 - has_in++; 1378 - if (!has_in) { 1375 + ret = usb_find_int_in_endpoint(interface, &ep); 1376 + if (ret) { 1379 1377 hid_err(intf, "couldn't find an input interrupt endpoint\n"); 1380 1378 return -ENODEV; 1381 1379 } ··· 1550 1552 * configuration descriptors passed, we already know that 1551 1553 * the size of the HID report descriptor has not changed. 1552 1554 */ 1553 - rdesc = kmalloc(hid->dev_rsize, GFP_KERNEL); 1555 + rdesc = kmalloc(hid->dev_rsize, GFP_NOIO); 1554 1556 if (!rdesc) 1555 1557 return -ENOMEM; 1556 1558
+38 -19
drivers/hid/usbhid/hid-pidff.c
··· 13 13 #include <linux/input.h> 14 14 #include <linux/minmax.h> 15 15 #include <linux/slab.h> 16 + #include <linux/stringify.h> 16 17 #include <linux/usb.h> 17 18 18 19 #define PID_EFFECTS_MAX 64 ··· 82 81 #define PID_NEG_COEFFICIENT 4 83 82 #define PID_POS_SATURATION 5 84 83 #define PID_NEG_SATURATION 6 85 - #define PID_DEAD_BAND 7 84 + #define PID_DEADBAND 7 86 85 static const u8 pidff_set_condition[] = { 87 86 0x22, 0x23, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65 88 87 }; ··· 619 618 effect->u.condition[i].center); 620 619 pidff_set_signed(&pidff->set_condition[PID_POS_COEFFICIENT], 621 620 effect->u.condition[i].right_coeff); 622 - pidff_set_signed(&pidff->set_condition[PID_NEG_COEFFICIENT], 623 - effect->u.condition[i].left_coeff); 624 621 pidff_set(&pidff->set_condition[PID_POS_SATURATION], 625 622 effect->u.condition[i].right_saturation); 626 - pidff_set(&pidff->set_condition[PID_NEG_SATURATION], 627 - effect->u.condition[i].left_saturation); 628 - pidff_set(&pidff->set_condition[PID_DEAD_BAND], 629 - effect->u.condition[i].deadband); 623 + 624 + /* Omit Negative Coefficient if missing */ 625 + if (!(pidff->quirks & HID_PIDFF_QUIRK_MISSING_NEG_COEFFICIENT)) 626 + pidff_set_signed(&pidff->set_condition[PID_NEG_COEFFICIENT], 627 + effect->u.condition[i].left_coeff); 628 + 629 + /* Omit Negative Saturation if missing */ 630 + if (!(pidff->quirks & HID_PIDFF_QUIRK_MISSING_NEG_SATURATION)) 631 + pidff_set_signed(&pidff->set_condition[PID_NEG_SATURATION], 632 + effect->u.condition[i].left_saturation); 633 + 634 + /* Omit Deadband field if missing */ 635 + if (!(pidff->quirks & HID_PIDFF_QUIRK_MISSING_DEADBAND)) 636 + pidff_set(&pidff->set_condition[PID_DEADBAND], 637 + effect->u.condition[i].deadband); 638 + 630 639 hid_hw_request(pidff->hid, pidff->reports[PID_SET_CONDITION], 631 640 HID_REQ_SET_REPORT); 632 641 } ··· 1064 1053 return -1; 1065 1054 } 1066 1055 1056 + #define PIDFF_MISSING_FIELD(name, quirks) \ 1057 + ({ pr_debug("%s field not found, but that's OK\n", __stringify(name)); \ 1058 + pr_debug("Setting MISSING_%s quirk\n", __stringify(name)); \ 1059 + *quirks |= HID_PIDFF_QUIRK_MISSING_ ## name; }) 1060 + 1067 1061 /* 1068 1062 * Find fields from a report and fill a pidff_usage 1069 1063 */ ··· 1076 1060 struct hid_report *report, int count, int strict, 1077 1061 u32 *quirks) 1078 1062 { 1079 - const u8 block_offset = pidff_set_condition[PID_PARAM_BLOCK_OFFSET]; 1080 - const u8 delay = pidff_set_effect[PID_START_DELAY]; 1081 - 1082 1063 if (!report) { 1083 1064 pr_debug("%s, null report\n", __func__); 1084 1065 return -1; ··· 1093 1080 continue; 1094 1081 } 1095 1082 1096 - if (table[i] == delay) { 1097 - pr_debug("Delay field not found, but that's OK\n"); 1098 - pr_debug("Setting MISSING_DELAY quirk\n"); 1099 - *quirks |= HID_PIDFF_QUIRK_MISSING_DELAY; 1083 + /* Field quirks auto-detection */ 1084 + if (table[i] == pidff_set_effect[PID_START_DELAY]) 1085 + PIDFF_MISSING_FIELD(DELAY, quirks); 1100 1086 1101 - } else if (table[i] == block_offset) { 1102 - pr_debug("PBO field not found, but that's OK\n"); 1103 - pr_debug("Setting MISSING_PBO quirk\n"); 1104 - *quirks |= HID_PIDFF_QUIRK_MISSING_PBO; 1087 + else if (table[i] == pidff_set_condition[PID_PARAM_BLOCK_OFFSET]) 1088 + PIDFF_MISSING_FIELD(PBO, quirks); 1105 1089 1106 - } else if (strict) { 1090 + else if (table[i] == pidff_set_condition[PID_NEG_COEFFICIENT]) 1091 + PIDFF_MISSING_FIELD(NEG_COEFFICIENT, quirks); 1092 + 1093 + else if (table[i] == pidff_set_condition[PID_NEG_SATURATION]) 1094 + PIDFF_MISSING_FIELD(NEG_SATURATION, quirks); 1095 + 1096 + else if (table[i] == pidff_set_condition[PID_DEADBAND]) 1097 + PIDFF_MISSING_FIELD(DEADBAND, quirks); 1098 + 1099 + else if (strict) { 1107 1100 pr_debug("failed to locate %d\n", i); 1108 1101 return -1; 1109 1102 }
+9
drivers/hid/usbhid/hid-pidff.h
··· 21 21 /* Force all periodic effects to be uploaded as SINE */ 22 22 #define HID_PIDFF_QUIRK_PERIODIC_SINE_ONLY BIT(4) 23 23 24 + /* Allow devices with missing negative coefficient in the set condition usage */ 25 + #define HID_PIDFF_QUIRK_MISSING_NEG_COEFFICIENT BIT(5) 26 + 27 + /* Allow devices with missing negative saturation in the set condition usage */ 28 + #define HID_PIDFF_QUIRK_MISSING_NEG_SATURATION BIT(6) 29 + 30 + /* Allow devices with missing deadband in the set condition usage */ 31 + #define HID_PIDFF_QUIRK_MISSING_DEADBAND BIT(7) 32 + 24 33 #ifdef CONFIG_HID_PID 25 34 int hid_pidff_init(struct hid_device *hid); 26 35 int hid_pidff_init_with_quirks(struct hid_device *hid, u32 initial_quirks);
+46
include/linux/device.h
··· 190 190 struct device_attribute dev_attr_##_name = __ATTR_RW_MODE(_name, 0600) 191 191 192 192 /** 193 + * DEVICE_ATTR_RW_NAMED - Define a read-write device attribute with a sysfs name 194 + * that differs from the function name. 195 + * @_name: Attribute function preface 196 + * @_attrname: Attribute name as it wil be exposed in the sysfs. 197 + * 198 + * Like DEVICE_ATTR_RW(), but allows for reusing names under separate paths in 199 + * the same driver. 200 + */ 201 + #define DEVICE_ATTR_RW_NAMED(_name, _attrname) \ 202 + struct device_attribute dev_attr_##_name = { \ 203 + .attr = { .name = _attrname, .mode = 0644 }, \ 204 + .show = _name##_show, \ 205 + .store = _name##_store, \ 206 + } 207 + 208 + /** 193 209 * DEVICE_ATTR_RO - Define a readable device attribute. 194 210 * @_name: Attribute name. 195 211 * ··· 224 208 struct device_attribute dev_attr_##_name = __ATTR_RO_MODE(_name, 0400) 225 209 226 210 /** 211 + * DEVICE_ATTR_RO_NAMED - Define a read-only device attribute with a sysfs name 212 + * that differs from the function name. 213 + * @_name: Attribute function preface 214 + * @_attrname: Attribute name as it wil be exposed in the sysfs. 215 + * 216 + * Like DEVICE_ATTR_RO(), but allows for reusing names under separate paths in 217 + * the same driver. 218 + */ 219 + #define DEVICE_ATTR_RO_NAMED(_name, _attrname) \ 220 + struct device_attribute dev_attr_##_name = { \ 221 + .attr = { .name = _attrname, .mode = 0444 }, \ 222 + .show = _name##_show, \ 223 + } 224 + 225 + /** 227 226 * DEVICE_ATTR_WO - Define an admin-only writable device attribute. 228 227 * @_name: Attribute name. 229 228 * ··· 246 215 */ 247 216 #define DEVICE_ATTR_WO(_name) \ 248 217 struct device_attribute dev_attr_##_name = __ATTR_WO(_name) 218 + 219 + /** 220 + * DEVICE_ATTR_WO_NAMED - Define a read-only device attribute with a sysfs name 221 + * that differs from the function name. 222 + * @_name: Attribute function preface 223 + * @_attrname: Attribute name as it wil be exposed in the sysfs. 224 + * 225 + * Like DEVICE_ATTR_WO(), but allows for reusing names under separate paths in 226 + * the same driver. 227 + */ 228 + #define DEVICE_ATTR_WO_NAMED(_name, _attrname) \ 229 + struct device_attribute dev_attr_##_name = { \ 230 + .attr = { .name = _attrname, .mode = 0200 }, \ 231 + .store = _name##_store, \ 232 + } 249 233 250 234 /** 251 235 * DEVICE_ULONG_ATTR - Define a device attribute backed by an unsigned long.
+45 -13
include/linux/hid.h
··· 634 634 HID_BATTERY_REPORTED, /* Device sent unsolicited battery strength report */ 635 635 }; 636 636 637 + /** 638 + * struct hid_battery - represents a single battery power supply 639 + * @dev: pointer to the parent hid_device 640 + * @ps: the power supply instance 641 + * @min: minimum battery value from HID descriptor 642 + * @max: maximum battery value from HID descriptor 643 + * @report_type: HID report type (input/feature) 644 + * @report_id: HID report ID for this battery 645 + * @charge_status: current charging status 646 + * @status: battery reporting status 647 + * @capacity: current battery capacity (0-100) 648 + * @avoid_query: if true, avoid querying battery (e.g., for stylus) 649 + * @present: if true, battery is present (may be dynamic) 650 + * @ratelimit_time: rate limiting for battery reports 651 + * @list: list node for linking into hid_device's battery list 652 + */ 653 + struct hid_battery { 654 + struct hid_device *dev; 655 + struct power_supply *ps; 656 + __s32 min; 657 + __s32 max; 658 + __s32 report_type; 659 + __s32 report_id; 660 + __s32 charge_status; 661 + enum hid_battery_status status; 662 + __s32 capacity; 663 + bool avoid_query; 664 + bool present; 665 + ktime_t ratelimit_time; 666 + struct list_head list; 667 + }; 668 + 637 669 struct hid_driver; 638 670 struct hid_ll_driver; 639 671 ··· 702 670 #ifdef CONFIG_HID_BATTERY_STRENGTH 703 671 /* 704 672 * Power supply information for HID devices which report 705 - * battery strength. power_supply was successfully registered if 706 - * battery is non-NULL. 673 + * battery strength. Each battery is tracked separately in the 674 + * batteries list. 707 675 */ 708 - struct power_supply *battery; 709 - __s32 battery_capacity; 710 - __s32 battery_min; 711 - __s32 battery_max; 712 - __s32 battery_report_type; 713 - __s32 battery_report_id; 714 - __s32 battery_charge_status; 715 - enum hid_battery_status battery_status; 716 - bool battery_avoid_query; 717 - bool battery_present; 718 - ktime_t battery_ratelimit_time; 676 + struct list_head batteries; 719 677 #endif 720 678 721 679 unsigned long status; /* see STAT flags above */ ··· 721 699 char name[128]; /* Device name */ 722 700 char phys[64]; /* Device physical location */ 723 701 char uniq[64]; /* Device unique identifier (serial #) */ 702 + u64 firmware_version; /* Firmware version */ 724 703 725 704 void *driver_data; 726 705 ··· 766 743 { 767 744 dev_set_drvdata(&hdev->dev, data); 768 745 } 746 + 747 + #ifdef CONFIG_HID_BATTERY_STRENGTH 748 + static inline struct hid_battery *hid_get_battery(struct hid_device *hdev) 749 + { 750 + if (list_empty(&hdev->batteries)) 751 + return NULL; 752 + return list_first_entry(&hdev->batteries, struct hid_battery, list); 753 + } 754 + #endif 769 755 770 756 #define HID_GLOBAL_STACK_SIZE 4 771 757 #define HID_COLLECTION_STACK_SIZE 4