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

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

Pull HID updates from Jiri Kosina:

- more bullet-proof handling of devres-managed resources in HID core
(Dmitry Torokhov)

- conversion of hid-wacom to use ktime_t (Jason Gerecke)

- touch selftests for hid-wacom (Joshua Dickens)

- support for nVidia Thunderstrike (SHIELD 2017) controller (Rahul
Rameshbabu)

- power management reset-during-suspend fix for goodix Chromebook
devices (Fei Shao)

- assorted device ID additions, device-specific quirks and code
cleanups

* tag 'for-linus-2023062701' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (27 commits)
HID: wacom: Use ktime_t rather than int when dealing with timestamps
HID: hidraw: fix data race on device refcount
HID: intel-ish-hid: ipc: Add Arrow Lake PCI device ID
HID: logitech-hidpp: add HIDPP_QUIRK_DELAYED_INIT for the T651.
HID: add quirk for 03f0:464a HP Elite Presenter Mouse
HID: nvidia-shield: Support LED functionality for Thunderstrike
HID: nvidia-shield: Add mappings for consumer HID USAGE buttons
HID: nvidia-shield: Initial driver implementation with Thunderstrike support
HID: apple: Option to swap only left side mod keys
HID: uclogic: Modular KUnit tests should not depend on KUNIT=y
HID: fix an error code in hid_check_device_match()
HID: logitech-hidpp: Add USB and Bluetooth IDs for the Logitech G915 TKL Keyboard
HID: i2c-hid: Switch i2c drivers back to use .probe()
HID: i2c-hid: goodix: Add support for "goodix,no-reset-during-suspend" property
dt-bindings: input: goodix: Add "goodix,no-reset-during-suspend" property
HID: microsoft: Add rumble support to latest xbox controllers
selftests: hid: Add touch tests for Wacom devices
HID: ensure timely release of driver-allocated resources
HID: split apart hid_device_probe to make logic more apparent
HID: amd_sfh: Split sensor and HID initialization for SFH1.1
...

+1034 -143
+9
Documentation/devicetree/bindings/input/goodix,gt7375p.yaml
··· 43 43 itself as long as it allows the main board to make signals compatible 44 44 with what the touchscreen is expecting for its IO rails. 45 45 46 + goodix,no-reset-during-suspend: 47 + description: 48 + Set this to true to enforce the driver to not assert the reset GPIO 49 + during suspend. 50 + Due to potential touchscreen hardware flaw, back-powering could happen in 51 + suspend if the power supply is on and with active-low reset GPIO asserted. 52 + This property is used to avoid the back-powering issue. 53 + type: boolean 54 + 46 55 required: 47 56 - compatible 48 57 - reg
+6
MAINTAINERS
··· 9200 9200 S: Maintained 9201 9201 F: drivers/hid/hid-pxrc.c 9202 9202 9203 + HID NVIDIA SHIELD DRIVER 9204 + M: Rahul Rameshbabu <rrameshbabu@nvidia.com> 9205 + L: linux-input@vger.kernel.org 9206 + S: Maintained 9207 + F: drivers/hid/hid-nvidia-shield.c 9208 + 9203 9209 HID PLAYSTATION DRIVER 9204 9210 M: Roderick Colenbrander <roderick.colenbrander@sony.com> 9205 9211 L: linux-input@vger.kernel.org
+19 -1
drivers/hid/Kconfig
··· 788 788 help 789 789 Support for N-Trig touch screen. 790 790 791 + config HID_NVIDIA_SHIELD 792 + tristate "NVIDIA SHIELD devices" 793 + depends on USB_HID 794 + depends on BT_HIDP 795 + help 796 + Support for NVIDIA SHIELD accessories. 797 + 798 + Supported devices: 799 + - Thunderstrike (NVIDIA SHIELD Controller 2017) 800 + 801 + config NVIDIA_SHIELD_FF 802 + bool "NVIDIA SHIELD force feedback support" 803 + depends on HID_NVIDIA_SHIELD 804 + select INPUT_FF_MEMLESS 805 + help 806 + Say Y here if you would like to enable force feedback support for 807 + NVIDIA SHIELD accessories with haptics capabilities. 808 + 791 809 config HID_ORTEK 792 810 tristate "Ortek PKB-1700/WKB-2000/Skycable wireless keyboard and mouse trackpad" 793 811 help ··· 1303 1285 1304 1286 config HID_KUNIT_TEST 1305 1287 tristate "KUnit tests for HID" if !KUNIT_ALL_TESTS 1306 - depends on KUNIT=y 1288 + depends on KUNIT 1307 1289 depends on HID_BATTERY_STRENGTH 1308 1290 depends on HID_UCLOGIC 1309 1291 default KUNIT_ALL_TESTS
+1
drivers/hid/Makefile
··· 87 87 obj-$(CONFIG_HID_NINTENDO) += hid-nintendo.o 88 88 obj-$(CONFIG_HID_NTI) += hid-nti.o 89 89 obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o 90 + obj-$(CONFIG_HID_NVIDIA_SHIELD) += hid-nvidia-shield.o 90 91 obj-$(CONFIG_HID_ORTEK) += hid-ortek.o 91 92 obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o 92 93 obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o
+14 -33
drivers/hid/amd-sfh-hid/amd_sfh_client.c
··· 215 215 struct device *dev; 216 216 u32 feature_report_size; 217 217 u32 input_report_size; 218 - int rc, i, status; 218 + int rc, i; 219 219 u8 cl_idx; 220 220 221 221 req_list = &cl_data->req_list; ··· 286 286 if (rc) 287 287 goto cleanup; 288 288 mp2_ops->start(privdata, info); 289 - status = amd_sfh_wait_for_response 290 - (privdata, cl_data->sensor_idx[i], SENSOR_ENABLED); 291 - if (status == SENSOR_ENABLED) { 289 + cl_data->sensor_sts[i] = amd_sfh_wait_for_response 290 + (privdata, cl_data->sensor_idx[i], SENSOR_ENABLED); 291 + } 292 + 293 + for (i = 0; i < cl_data->num_hid_devices; i++) { 294 + cl_data->cur_hid_dev = i; 295 + if (cl_data->sensor_sts[i] == SENSOR_ENABLED) { 292 296 cl_data->is_any_sensor_enabled = true; 293 - cl_data->sensor_sts[i] = SENSOR_ENABLED; 294 - rc = amdtp_hid_probe(cl_data->cur_hid_dev, cl_data); 295 - if (rc) { 296 - mp2_ops->stop(privdata, cl_data->sensor_idx[i]); 297 - status = amd_sfh_wait_for_response 298 - (privdata, cl_data->sensor_idx[i], SENSOR_DISABLED); 299 - if (status != SENSOR_ENABLED) 300 - cl_data->sensor_sts[i] = SENSOR_DISABLED; 301 - dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n", 302 - cl_data->sensor_idx[i], 303 - get_sensor_name(cl_data->sensor_idx[i]), 304 - cl_data->sensor_sts[i]); 297 + rc = amdtp_hid_probe(i, cl_data); 298 + if (rc) 305 299 goto cleanup; 306 - } 307 300 } else { 308 301 cl_data->sensor_sts[i] = SENSOR_DISABLED; 309 - dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n", 310 - cl_data->sensor_idx[i], 311 - get_sensor_name(cl_data->sensor_idx[i]), 312 - cl_data->sensor_sts[i]); 313 302 } 314 303 dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n", 315 304 cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]), 316 305 cl_data->sensor_sts[i]); 317 306 } 307 + 318 308 if (!cl_data->is_any_sensor_enabled || 319 309 (mp2_ops->discovery_status && mp2_ops->discovery_status(privdata) == 0)) { 320 - amd_sfh_hid_client_deinit(privdata); 321 - for (i = 0; i < cl_data->num_hid_devices; i++) { 322 - devm_kfree(dev, cl_data->feature_report[i]); 323 - devm_kfree(dev, in_data->input_report[i]); 324 - devm_kfree(dev, cl_data->report_descr[i]); 325 - } 326 310 dev_warn(dev, "Failed to discover, sensors not enabled is %d\n", cl_data->is_any_sensor_enabled); 327 - return -EOPNOTSUPP; 311 + rc = -EOPNOTSUPP; 312 + goto cleanup; 328 313 } 329 314 schedule_delayed_work(&cl_data->work_buffer, msecs_to_jiffies(AMD_SFH_IDLE_LOOP)); 330 315 return 0; 331 316 332 317 cleanup: 318 + amd_sfh_hid_client_deinit(privdata); 333 319 for (i = 0; i < cl_data->num_hid_devices; i++) { 334 - if (in_data->sensor_virt_addr[i]) { 335 - dma_free_coherent(&privdata->pdev->dev, 8 * sizeof(int), 336 - in_data->sensor_virt_addr[i], 337 - cl_data->sensor_dma_addr[i]); 338 - } 339 320 devm_kfree(dev, cl_data->feature_report[i]); 340 321 devm_kfree(dev, in_data->input_report[i]); 341 322 devm_kfree(dev, cl_data->report_descr[i]);
+6 -18
drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_init.c
··· 168 168 status = amd_sfh_wait_for_response 169 169 (privdata, cl_data->sensor_idx[i], ENABLE_SENSOR); 170 170 171 - status = (status == 0) ? SENSOR_ENABLED : SENSOR_DISABLED; 171 + cl_data->sensor_sts[i] = (status == 0) ? SENSOR_ENABLED : SENSOR_DISABLED; 172 + } 172 173 173 - if (status == SENSOR_ENABLED) { 174 + for (i = 0; i < cl_data->num_hid_devices; i++) { 175 + cl_data->cur_hid_dev = i; 176 + if (cl_data->sensor_sts[i] == SENSOR_ENABLED) { 174 177 cl_data->is_any_sensor_enabled = true; 175 - cl_data->sensor_sts[i] = SENSOR_ENABLED; 176 178 rc = amdtp_hid_probe(i, cl_data); 177 - if (rc) { 178 - mp2_ops->stop(privdata, cl_data->sensor_idx[i]); 179 - status = amd_sfh_wait_for_response 180 - (privdata, cl_data->sensor_idx[i], DISABLE_SENSOR); 181 - if (status == 0) 182 - status = SENSOR_DISABLED; 183 - if (status != SENSOR_ENABLED) 184 - cl_data->sensor_sts[i] = SENSOR_DISABLED; 185 - dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n", 186 - cl_data->sensor_idx[i], 187 - get_sensor_name(cl_data->sensor_idx[i]), 188 - cl_data->sensor_sts[i]); 179 + if (rc) 189 180 goto cleanup; 190 - } 191 - } else { 192 - cl_data->sensor_sts[i] = SENSOR_DISABLED; 193 181 } 194 182 dev_dbg(dev, "sid 0x%x (%s) status 0x%x\n", 195 183 cl_data->sensor_idx[i], get_sensor_name(cl_data->sensor_idx[i]),
+11 -2
drivers/hid/hid-apple.c
··· 58 58 module_param(swap_opt_cmd, uint, 0644); 59 59 MODULE_PARM_DESC(swap_opt_cmd, "Swap the Option (\"Alt\") and Command (\"Flag\") keys. " 60 60 "(For people who want to keep Windows PC keyboard muscle memory. " 61 - "[0] = as-is, Mac layout. 1 = swapped, Windows layout.)"); 61 + "[0] = as-is, Mac layout. 1 = swapped, Windows layout., 2 = swapped, Swap only left side)"); 62 62 63 63 static unsigned int swap_ctrl_cmd; 64 64 module_param(swap_ctrl_cmd, uint, 0644); ··· 319 319 { } 320 320 }; 321 321 322 + static const struct apple_key_translation swapped_option_cmd_left_keys[] = { 323 + { KEY_LEFTALT, KEY_LEFTMETA }, 324 + { KEY_LEFTMETA, KEY_LEFTALT }, 325 + { } 326 + }; 327 + 322 328 static const struct apple_key_translation swapped_ctrl_cmd_keys[] = { 323 329 { KEY_LEFTCTRL, KEY_LEFTMETA }, 324 330 { KEY_LEFTMETA, KEY_LEFTCTRL }, ··· 422 416 } 423 417 424 418 if (swap_opt_cmd) { 425 - trans = apple_find_translation(swapped_option_cmd_keys, code); 419 + if (swap_opt_cmd == 2) 420 + trans = apple_find_translation(swapped_option_cmd_left_keys, code); 421 + else 422 + trans = apple_find_translation(swapped_option_cmd_keys, code); 426 423 427 424 if (trans) 428 425 code = trans->to;
+15 -25
drivers/hid/hid-asus.c
··· 884 884 case 0xb5: asus_map_key_clear(KEY_CALC); break; 885 885 case 0xc4: asus_map_key_clear(KEY_KBDILLUMUP); break; 886 886 case 0xc5: asus_map_key_clear(KEY_KBDILLUMDOWN); break; 887 + case 0xc7: asus_map_key_clear(KEY_KBDILLUMTOGGLE); break; 887 888 888 - /* ASUS touchpad toggle */ 889 - case 0x6b: asus_map_key_clear(KEY_F21); break; 889 + case 0x6b: asus_map_key_clear(KEY_F21); break; /* ASUS touchpad toggle */ 890 + case 0x38: asus_map_key_clear(KEY_PROG1); break; /* ROG key */ 891 + case 0xba: asus_map_key_clear(KEY_PROG2); break; /* Fn+C ASUS Splendid */ 892 + case 0x5c: asus_map_key_clear(KEY_PROG3); break; /* Fn+Space Power4Gear */ 893 + case 0x99: asus_map_key_clear(KEY_PROG4); break; /* Fn+F5 "fan" symbol */ 894 + case 0xae: asus_map_key_clear(KEY_PROG4); break; /* Fn+F5 "fan" symbol */ 895 + case 0x92: asus_map_key_clear(KEY_CALC); break; /* Fn+Ret "Calc" symbol */ 896 + case 0xb2: asus_map_key_clear(KEY_PROG2); break; /* Fn+Left previous aura */ 897 + case 0xb3: asus_map_key_clear(KEY_PROG3); break; /* Fn+Left next aura */ 898 + case 0x6a: asus_map_key_clear(KEY_F13); break; /* Screenpad toggle */ 899 + case 0x4b: asus_map_key_clear(KEY_F14); break; /* Arrows/Pg-Up/Dn toggle */ 890 900 891 - /* ROG key */ 892 - case 0x38: asus_map_key_clear(KEY_PROG1); break; 893 - 894 - /* Fn+C ASUS Splendid */ 895 - case 0xba: asus_map_key_clear(KEY_PROG2); break; 896 - 897 - /* Fn+Space Power4Gear Hybrid */ 898 - case 0x5c: asus_map_key_clear(KEY_PROG3); break; 899 - 900 - /* Fn+F5 "fan" symbol on FX503VD */ 901 - case 0x99: asus_map_key_clear(KEY_PROG4); break; 902 - 903 - /* Fn+F5 "fan" symbol on N-Key keyboard */ 904 - case 0xae: asus_map_key_clear(KEY_PROG4); break; 905 - 906 - /* Fn+Ret "Calc" symbol on N-Key keyboard */ 907 - case 0x92: asus_map_key_clear(KEY_CALC); break; 908 - 909 - /* Fn+Left Aura mode previous on N-Key keyboard */ 910 - case 0xb2: asus_map_key_clear(KEY_PROG2); break; 911 - 912 - /* Fn+Right Aura mode next on N-Key keyboard */ 913 - case 0xb3: asus_map_key_clear(KEY_PROG3); break; 914 901 915 902 default: 916 903 /* ASUS lazily declares 256 usages, ignore the rest, ··· 1254 1267 QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, 1255 1268 { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, 1256 1269 USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2), 1270 + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, 1271 + { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, 1272 + USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3), 1257 1273 QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, 1258 1274 { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, 1259 1275 USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD),
+71 -47
drivers/hid/hid-core.c
··· 2587 2587 } 2588 2588 EXPORT_SYMBOL_GPL(hid_compare_device_paths); 2589 2589 2590 + static bool hid_check_device_match(struct hid_device *hdev, 2591 + struct hid_driver *hdrv, 2592 + const struct hid_device_id **id) 2593 + { 2594 + *id = hid_match_device(hdev, hdrv); 2595 + if (!*id) 2596 + return false; 2597 + 2598 + if (hdrv->match) 2599 + return hdrv->match(hdev, hid_ignore_special_drivers); 2600 + 2601 + /* 2602 + * hid-generic implements .match(), so we must be dealing with a 2603 + * different HID driver here, and can simply check if 2604 + * hid_ignore_special_drivers is set or not. 2605 + */ 2606 + return !hid_ignore_special_drivers; 2607 + } 2608 + 2609 + static int __hid_device_probe(struct hid_device *hdev, struct hid_driver *hdrv) 2610 + { 2611 + const struct hid_device_id *id; 2612 + int ret; 2613 + 2614 + if (!hid_check_device_match(hdev, hdrv, &id)) 2615 + return -ENODEV; 2616 + 2617 + hdev->devres_group_id = devres_open_group(&hdev->dev, NULL, GFP_KERNEL); 2618 + if (!hdev->devres_group_id) 2619 + return -ENOMEM; 2620 + 2621 + /* reset the quirks that has been previously set */ 2622 + hdev->quirks = hid_lookup_quirk(hdev); 2623 + hdev->driver = hdrv; 2624 + 2625 + if (hdrv->probe) { 2626 + ret = hdrv->probe(hdev, id); 2627 + } else { /* default probe */ 2628 + ret = hid_open_report(hdev); 2629 + if (!ret) 2630 + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 2631 + } 2632 + 2633 + /* 2634 + * Note that we are not closing the devres group opened above so 2635 + * even resources that were attached to the device after probe is 2636 + * run are released when hid_device_remove() is executed. This is 2637 + * needed as some drivers would allocate additional resources, 2638 + * for example when updating firmware. 2639 + */ 2640 + 2641 + if (ret) { 2642 + devres_release_group(&hdev->dev, hdev->devres_group_id); 2643 + hid_close_report(hdev); 2644 + hdev->driver = NULL; 2645 + } 2646 + 2647 + return ret; 2648 + } 2649 + 2590 2650 static int hid_device_probe(struct device *dev) 2591 2651 { 2592 - struct hid_driver *hdrv = to_hid_driver(dev->driver); 2593 2652 struct hid_device *hdev = to_hid_device(dev); 2594 - const struct hid_device_id *id; 2653 + struct hid_driver *hdrv = to_hid_driver(dev->driver); 2595 2654 int ret = 0; 2596 2655 2597 - if (down_interruptible(&hdev->driver_input_lock)) { 2598 - ret = -EINTR; 2599 - goto end; 2600 - } 2601 - hdev->io_started = false; 2656 + if (down_interruptible(&hdev->driver_input_lock)) 2657 + return -EINTR; 2602 2658 2659 + hdev->io_started = false; 2603 2660 clear_bit(ffs(HID_STAT_REPROBED), &hdev->status); 2604 2661 2605 - if (!hdev->driver) { 2606 - id = hid_match_device(hdev, hdrv); 2607 - if (id == NULL) { 2608 - ret = -ENODEV; 2609 - goto unlock; 2610 - } 2662 + if (!hdev->driver) 2663 + ret = __hid_device_probe(hdev, hdrv); 2611 2664 2612 - if (hdrv->match) { 2613 - if (!hdrv->match(hdev, hid_ignore_special_drivers)) { 2614 - ret = -ENODEV; 2615 - goto unlock; 2616 - } 2617 - } else { 2618 - /* 2619 - * hid-generic implements .match(), so if 2620 - * hid_ignore_special_drivers is set, we can safely 2621 - * return. 2622 - */ 2623 - if (hid_ignore_special_drivers) { 2624 - ret = -ENODEV; 2625 - goto unlock; 2626 - } 2627 - } 2628 - 2629 - /* reset the quirks that has been previously set */ 2630 - hdev->quirks = hid_lookup_quirk(hdev); 2631 - hdev->driver = hdrv; 2632 - if (hdrv->probe) { 2633 - ret = hdrv->probe(hdev, id); 2634 - } else { /* default probe */ 2635 - ret = hid_open_report(hdev); 2636 - if (!ret) 2637 - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 2638 - } 2639 - if (ret) { 2640 - hid_close_report(hdev); 2641 - hdev->driver = NULL; 2642 - } 2643 - } 2644 - unlock: 2645 2665 if (!hdev->io_started) 2646 2666 up(&hdev->driver_input_lock); 2647 - end: 2667 + 2648 2668 return ret; 2649 2669 } 2650 2670 ··· 2682 2662 hdrv->remove(hdev); 2683 2663 else /* default remove */ 2684 2664 hid_hw_stop(hdev); 2665 + 2666 + /* Release all devres resources allocated by the driver */ 2667 + devres_release_group(&hdev->dev, hdev->devres_group_id); 2668 + 2685 2669 hid_close_report(hdev); 2686 2670 hdev->driver = NULL; 2687 2671 }
+14 -1
drivers/hid/hid-ids.h
··· 207 207 #define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD3 0x1822 208 208 #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD 0x1866 209 209 #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2 0x19b6 210 + #define USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD3 0x1a30 210 211 #define USB_DEVICE_ID_ASUSTEK_ROG_CLAYMORE_II_KEYBOARD 0x196b 211 212 #define USB_DEVICE_ID_ASUSTEK_FX503VD_KEYBOARD 0x1869 212 213 ··· 621 620 #define USB_DEVICE_ID_UGCI_FIGHTING 0x0030 622 621 623 622 #define USB_VENDOR_ID_HP 0x03f0 623 + #define USB_PRODUCT_ID_HP_ELITE_PRESENTER_MOUSE_464A 0x464a 624 624 #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A 0x0a4a 625 625 #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A 0x0b4a 626 626 #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE 0x134a ··· 936 934 #define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9 937 935 #define USB_DEVICE_ID_MS_POWER_COVER 0x07da 938 936 #define USB_DEVICE_ID_MS_SURFACE3_COVER 0x07de 939 - #define USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER 0x02fd 937 + /* 938 + * For a description of the Xbox controller models, refer to: 939 + * https://en.wikipedia.org/wiki/Xbox_Wireless_Controller#Summary 940 + */ 941 + #define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1708 0x02fd 942 + #define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1708_BLE 0x0b20 943 + #define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1914 0x0b13 944 + #define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1797 0x0b05 945 + #define USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1797_BLE 0x0b22 940 946 #define USB_DEVICE_ID_MS_PIXART_MOUSE 0x00cb 941 947 #define USB_DEVICE_ID_8BITDO_SN30_PRO_PLUS 0x02e0 942 948 #define USB_DEVICE_ID_MS_MOUSE_0783 0x0783 ··· 1014 1004 #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_17 0x0013 1015 1005 #define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18 0x0014 1016 1006 #define USB_DEVICE_ID_NTRIG_DUOSENSE 0x1500 1007 + 1008 + #define USB_VENDOR_ID_NVIDIA 0x0955 1009 + #define USB_DEVICE_ID_NVIDIA_THUNDERSTRIKE_CONTROLLER 0x7214 1017 1010 1018 1011 #define USB_VENDOR_ID_ONTRAK 0x0a07 1019 1012 #define USB_DEVICE_ID_ONTRAK_ADU100 0x0064
+5 -1
drivers/hid/hid-logitech-hidpp.c
··· 4553 4553 { /* wireless touchpad T651 */ 4554 4554 HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 4555 4555 USB_DEVICE_ID_LOGITECH_T651), 4556 - .driver_data = HIDPP_QUIRK_CLASS_WTP }, 4556 + .driver_data = HIDPP_QUIRK_CLASS_WTP | HIDPP_QUIRK_DELAYED_INIT }, 4557 4557 { /* Mouse Logitech Anywhere MX */ 4558 4558 LDJ_DEVICE(0x1017), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_1P0 }, 4559 4559 { /* Mouse logitech M560 */ ··· 4608 4608 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC086) }, 4609 4609 { /* Logitech G903 Hero Gaming Mouse over USB */ 4610 4610 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC091) }, 4611 + { /* Logitech G915 TKL Keyboard over USB */ 4612 + HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC343) }, 4611 4613 { /* Logitech G920 Wheel over USB */ 4612 4614 HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G920_WHEEL), 4613 4615 .driver_data = HIDPP_QUIRK_CLASS_G920 | HIDPP_QUIRK_FORCE_OUTPUT_REPORTS}, ··· 4632 4630 { /* MX5500 keyboard over Bluetooth */ 4633 4631 HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb30b), 4634 4632 .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, 4633 + { /* Logitech G915 TKL keyboard over Bluetooth */ 4634 + HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb35f) }, 4635 4635 { /* M-RCQ142 V470 Cordless Laser Mouse over Bluetooth */ 4636 4636 HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb008) }, 4637 4637 { /* MX Master mouse over Bluetooth */
+10 -1
drivers/hid/hid-microsoft.c
··· 446 446 .driver_data = MS_PRESENTER }, 447 447 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, 0x091B), 448 448 .driver_data = MS_SURFACE_DIAL }, 449 - { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_ONE_S_CONTROLLER), 449 + 450 + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1708), 451 + .driver_data = MS_QUIRK_FF }, 452 + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1708_BLE), 453 + .driver_data = MS_QUIRK_FF }, 454 + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1914), 455 + .driver_data = MS_QUIRK_FF }, 456 + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1797), 457 + .driver_data = MS_QUIRK_FF }, 458 + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_XBOX_CONTROLLER_MODEL_1797_BLE), 450 459 .driver_data = MS_QUIRK_FF }, 451 460 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_8BITDO_SN30_PRO_PLUS), 452 461 .driver_data = MS_QUIRK_FF },
+738
drivers/hid/hid-nvidia-shield.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. 4 + * 5 + * HID driver for NVIDIA SHIELD peripherals. 6 + */ 7 + 8 + #include <linux/hid.h> 9 + #include <linux/input-event-codes.h> 10 + #include <linux/input.h> 11 + #include <linux/leds.h> 12 + #include <linux/module.h> 13 + #include <linux/spinlock.h> 14 + #include <linux/workqueue.h> 15 + 16 + #include "hid-ids.h" 17 + 18 + #define NOT_INIT_STR "NOT INITIALIZED" 19 + #define android_map_key(c) hid_map_usage(hi, usage, bit, max, EV_KEY, (c)) 20 + 21 + enum { 22 + HID_USAGE_ANDROID_PLAYPAUSE_BTN = 0xcd, /* Double-tap volume slider */ 23 + HID_USAGE_ANDROID_VOLUMEUP_BTN = 0xe9, 24 + HID_USAGE_ANDROID_VOLUMEDOWN_BTN = 0xea, 25 + HID_USAGE_ANDROID_SEARCH_BTN = 0x221, /* NVIDIA btn on Thunderstrike */ 26 + HID_USAGE_ANDROID_HOME_BTN = 0x223, 27 + HID_USAGE_ANDROID_BACK_BTN = 0x224, 28 + }; 29 + 30 + enum { 31 + SHIELD_FW_VERSION_INITIALIZED = 0, 32 + SHIELD_BOARD_INFO_INITIALIZED, 33 + }; 34 + 35 + enum { 36 + THUNDERSTRIKE_FW_VERSION_UPDATE = 0, 37 + THUNDERSTRIKE_BOARD_INFO_UPDATE, 38 + THUNDERSTRIKE_HAPTICS_UPDATE, 39 + THUNDERSTRIKE_LED_UPDATE, 40 + }; 41 + 42 + enum { 43 + THUNDERSTRIKE_HOSTCMD_REPORT_SIZE = 33, 44 + THUNDERSTRIKE_HOSTCMD_REQ_REPORT_ID = 0x4, 45 + THUNDERSTRIKE_HOSTCMD_RESP_REPORT_ID = 0x3, 46 + }; 47 + 48 + enum { 49 + THUNDERSTRIKE_HOSTCMD_ID_FW_VERSION = 1, 50 + THUNDERSTRIKE_HOSTCMD_ID_LED = 6, 51 + THUNDERSTRIKE_HOSTCMD_ID_BOARD_INFO = 16, 52 + THUNDERSTRIKE_HOSTCMD_ID_USB_INIT = 53, 53 + THUNDERSTRIKE_HOSTCMD_ID_HAPTICS = 57, 54 + THUNDERSTRIKE_HOSTCMD_ID_BLUETOOTH_INIT = 58, 55 + }; 56 + 57 + enum thunderstrike_led_state { 58 + THUNDERSTRIKE_LED_OFF = 1, 59 + THUNDERSTRIKE_LED_ON = 8, 60 + } __packed; 61 + static_assert(sizeof(enum thunderstrike_led_state) == 1); 62 + 63 + struct thunderstrike_hostcmd_board_info { 64 + __le16 revision; 65 + __le16 serial[7]; 66 + }; 67 + 68 + struct thunderstrike_hostcmd_haptics { 69 + u8 motor_left; 70 + u8 motor_right; 71 + }; 72 + 73 + struct thunderstrike_hostcmd_resp_report { 74 + u8 report_id; /* THUNDERSTRIKE_HOSTCMD_RESP_REPORT_ID */ 75 + u8 cmd_id; 76 + u8 reserved_at_10; 77 + 78 + union { 79 + struct thunderstrike_hostcmd_board_info board_info; 80 + struct thunderstrike_hostcmd_haptics motors; 81 + __le16 fw_version; 82 + enum thunderstrike_led_state led_state; 83 + u8 payload[30]; 84 + }; 85 + } __packed; 86 + static_assert(sizeof(struct thunderstrike_hostcmd_resp_report) == 87 + THUNDERSTRIKE_HOSTCMD_REPORT_SIZE); 88 + 89 + struct thunderstrike_hostcmd_req_report { 90 + u8 report_id; /* THUNDERSTRIKE_HOSTCMD_REQ_REPORT_ID */ 91 + u8 cmd_id; 92 + u8 reserved_at_10; 93 + 94 + union { 95 + struct { 96 + u8 update; 97 + enum thunderstrike_led_state state; 98 + } led; 99 + struct { 100 + u8 update; 101 + struct thunderstrike_hostcmd_haptics motors; 102 + } haptics; 103 + }; 104 + u8 reserved_at_30[27]; 105 + } __packed; 106 + static_assert(sizeof(struct thunderstrike_hostcmd_req_report) == 107 + THUNDERSTRIKE_HOSTCMD_REPORT_SIZE); 108 + 109 + /* Common struct for shield accessories. */ 110 + struct shield_device { 111 + struct hid_device *hdev; 112 + 113 + unsigned long initialized_flags; 114 + const char *codename; 115 + u16 fw_version; 116 + struct { 117 + u16 revision; 118 + char serial_number[15]; 119 + } board_info; 120 + }; 121 + 122 + struct thunderstrike { 123 + struct shield_device base; 124 + 125 + /* Sub-devices */ 126 + struct input_dev *haptics_dev; 127 + struct led_classdev led_dev; 128 + 129 + /* Resources */ 130 + void *req_report_dmabuf; 131 + unsigned long update_flags; 132 + struct thunderstrike_hostcmd_haptics haptics_val; 133 + spinlock_t haptics_update_lock; 134 + u8 led_state : 1; 135 + enum thunderstrike_led_state led_value; 136 + struct work_struct hostcmd_req_work; 137 + }; 138 + 139 + static inline void thunderstrike_hostcmd_req_report_init( 140 + struct thunderstrike_hostcmd_req_report *report, u8 cmd_id) 141 + { 142 + memset(report, 0, sizeof(*report)); 143 + report->report_id = THUNDERSTRIKE_HOSTCMD_REQ_REPORT_ID; 144 + report->cmd_id = cmd_id; 145 + } 146 + 147 + static inline void shield_strrev(char *dest, size_t len, u16 rev) 148 + { 149 + dest[0] = ('A' - 1) + (rev >> 8); 150 + snprintf(&dest[1], len - 1, "%02X", 0xff & rev); 151 + } 152 + 153 + static struct input_dev *shield_allocate_input_dev(struct hid_device *hdev, 154 + const char *name_suffix) 155 + { 156 + struct input_dev *idev; 157 + 158 + idev = input_allocate_device(); 159 + if (!idev) 160 + goto err_device; 161 + 162 + idev->id.bustype = hdev->bus; 163 + idev->id.vendor = hdev->vendor; 164 + idev->id.product = hdev->product; 165 + idev->id.version = hdev->version; 166 + idev->uniq = hdev->uniq; 167 + idev->name = devm_kasprintf(&idev->dev, GFP_KERNEL, "%s %s", hdev->name, 168 + name_suffix); 169 + if (!idev->name) 170 + goto err_name; 171 + 172 + input_set_drvdata(idev, hdev); 173 + 174 + return idev; 175 + 176 + err_name: 177 + input_free_device(idev); 178 + err_device: 179 + return ERR_PTR(-ENOMEM); 180 + } 181 + 182 + static struct input_dev *shield_haptics_create( 183 + struct shield_device *dev, 184 + int (*play_effect)(struct input_dev *, void *, struct ff_effect *)) 185 + { 186 + struct input_dev *haptics; 187 + int ret; 188 + 189 + if (!IS_ENABLED(CONFIG_NVIDIA_SHIELD_FF)) 190 + return NULL; 191 + 192 + haptics = shield_allocate_input_dev(dev->hdev, "Haptics"); 193 + if (IS_ERR(haptics)) 194 + return haptics; 195 + 196 + input_set_capability(haptics, EV_FF, FF_RUMBLE); 197 + input_ff_create_memless(haptics, NULL, play_effect); 198 + 199 + ret = input_register_device(haptics); 200 + if (ret) 201 + goto err; 202 + 203 + return haptics; 204 + 205 + err: 206 + input_free_device(haptics); 207 + return ERR_PTR(ret); 208 + } 209 + 210 + static inline void thunderstrike_send_hostcmd_request(struct thunderstrike *ts) 211 + { 212 + struct thunderstrike_hostcmd_req_report *report = ts->req_report_dmabuf; 213 + struct shield_device *shield_dev = &ts->base; 214 + int ret; 215 + 216 + ret = hid_hw_raw_request(shield_dev->hdev, report->report_id, 217 + ts->req_report_dmabuf, 218 + THUNDERSTRIKE_HOSTCMD_REPORT_SIZE, 219 + HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); 220 + 221 + if (ret < 0) { 222 + hid_err(shield_dev->hdev, 223 + "Failed to output Thunderstrike HOSTCMD request HID report due to %pe\n", 224 + ERR_PTR(ret)); 225 + } 226 + } 227 + 228 + static void thunderstrike_hostcmd_req_work_handler(struct work_struct *work) 229 + { 230 + struct thunderstrike *ts = 231 + container_of(work, struct thunderstrike, hostcmd_req_work); 232 + struct thunderstrike_hostcmd_req_report *report; 233 + unsigned long flags; 234 + 235 + report = ts->req_report_dmabuf; 236 + 237 + if (test_and_clear_bit(THUNDERSTRIKE_FW_VERSION_UPDATE, &ts->update_flags)) { 238 + thunderstrike_hostcmd_req_report_init( 239 + report, THUNDERSTRIKE_HOSTCMD_ID_FW_VERSION); 240 + thunderstrike_send_hostcmd_request(ts); 241 + } 242 + 243 + if (test_and_clear_bit(THUNDERSTRIKE_LED_UPDATE, &ts->update_flags)) { 244 + thunderstrike_hostcmd_req_report_init(report, THUNDERSTRIKE_HOSTCMD_ID_LED); 245 + report->led.update = 1; 246 + report->led.state = ts->led_value; 247 + thunderstrike_send_hostcmd_request(ts); 248 + } 249 + 250 + if (test_and_clear_bit(THUNDERSTRIKE_BOARD_INFO_UPDATE, &ts->update_flags)) { 251 + thunderstrike_hostcmd_req_report_init( 252 + report, THUNDERSTRIKE_HOSTCMD_ID_BOARD_INFO); 253 + thunderstrike_send_hostcmd_request(ts); 254 + } 255 + 256 + if (test_and_clear_bit(THUNDERSTRIKE_HAPTICS_UPDATE, &ts->update_flags)) { 257 + thunderstrike_hostcmd_req_report_init( 258 + report, THUNDERSTRIKE_HOSTCMD_ID_HAPTICS); 259 + 260 + report->haptics.update = 1; 261 + spin_lock_irqsave(&ts->haptics_update_lock, flags); 262 + report->haptics.motors = ts->haptics_val; 263 + spin_unlock_irqrestore(&ts->haptics_update_lock, flags); 264 + 265 + thunderstrike_send_hostcmd_request(ts); 266 + } 267 + } 268 + 269 + static inline void thunderstrike_request_firmware_version(struct thunderstrike *ts) 270 + { 271 + set_bit(THUNDERSTRIKE_FW_VERSION_UPDATE, &ts->update_flags); 272 + schedule_work(&ts->hostcmd_req_work); 273 + } 274 + 275 + static inline void thunderstrike_request_board_info(struct thunderstrike *ts) 276 + { 277 + set_bit(THUNDERSTRIKE_BOARD_INFO_UPDATE, &ts->update_flags); 278 + schedule_work(&ts->hostcmd_req_work); 279 + } 280 + 281 + static inline int 282 + thunderstrike_update_haptics(struct thunderstrike *ts, 283 + struct thunderstrike_hostcmd_haptics *motors) 284 + { 285 + unsigned long flags; 286 + 287 + spin_lock_irqsave(&ts->haptics_update_lock, flags); 288 + ts->haptics_val = *motors; 289 + spin_unlock_irqrestore(&ts->haptics_update_lock, flags); 290 + 291 + set_bit(THUNDERSTRIKE_HAPTICS_UPDATE, &ts->update_flags); 292 + schedule_work(&ts->hostcmd_req_work); 293 + 294 + return 0; 295 + } 296 + 297 + static int thunderstrike_play_effect(struct input_dev *idev, void *data, 298 + struct ff_effect *effect) 299 + { 300 + struct hid_device *hdev = input_get_drvdata(idev); 301 + struct thunderstrike_hostcmd_haptics motors; 302 + struct shield_device *shield_dev; 303 + struct thunderstrike *ts; 304 + 305 + if (effect->type != FF_RUMBLE) 306 + return 0; 307 + 308 + shield_dev = hid_get_drvdata(hdev); 309 + ts = container_of(shield_dev, struct thunderstrike, base); 310 + 311 + /* Thunderstrike motor values range from 0 to 32 inclusively */ 312 + motors.motor_left = effect->u.rumble.strong_magnitude / 2047; 313 + motors.motor_right = effect->u.rumble.weak_magnitude / 2047; 314 + 315 + hid_dbg(hdev, "Thunderstrike FF_RUMBLE request, left: %u right: %u\n", 316 + motors.motor_left, motors.motor_right); 317 + 318 + return thunderstrike_update_haptics(ts, &motors); 319 + } 320 + 321 + static enum led_brightness 322 + thunderstrike_led_get_brightness(struct led_classdev *led) 323 + { 324 + struct hid_device *hdev = to_hid_device(led->dev->parent); 325 + struct shield_device *shield_dev = hid_get_drvdata(hdev); 326 + struct thunderstrike *ts; 327 + 328 + ts = container_of(shield_dev, struct thunderstrike, base); 329 + 330 + return ts->led_state; 331 + } 332 + 333 + static void thunderstrike_led_set_brightness(struct led_classdev *led, 334 + enum led_brightness value) 335 + { 336 + struct hid_device *hdev = to_hid_device(led->dev->parent); 337 + struct shield_device *shield_dev = hid_get_drvdata(hdev); 338 + struct thunderstrike *ts; 339 + 340 + ts = container_of(shield_dev, struct thunderstrike, base); 341 + 342 + switch (value) { 343 + case LED_OFF: 344 + ts->led_value = THUNDERSTRIKE_LED_OFF; 345 + break; 346 + default: 347 + ts->led_value = THUNDERSTRIKE_LED_ON; 348 + break; 349 + } 350 + 351 + set_bit(THUNDERSTRIKE_LED_UPDATE, &ts->update_flags); 352 + schedule_work(&ts->hostcmd_req_work); 353 + } 354 + 355 + static void 356 + thunderstrike_parse_fw_version_payload(struct shield_device *shield_dev, 357 + __le16 fw_version) 358 + { 359 + shield_dev->fw_version = le16_to_cpu(fw_version); 360 + 361 + set_bit(SHIELD_FW_VERSION_INITIALIZED, &shield_dev->initialized_flags); 362 + 363 + hid_dbg(shield_dev->hdev, "Thunderstrike firmware version 0x%04X\n", 364 + shield_dev->fw_version); 365 + } 366 + 367 + static void 368 + thunderstrike_parse_board_info_payload(struct shield_device *shield_dev, 369 + struct thunderstrike_hostcmd_board_info *board_info) 370 + { 371 + char board_revision_str[4]; 372 + int i; 373 + 374 + shield_dev->board_info.revision = le16_to_cpu(board_info->revision); 375 + for (i = 0; i < 7; ++i) { 376 + u16 val = le16_to_cpu(board_info->serial[i]); 377 + 378 + shield_dev->board_info.serial_number[2 * i] = val & 0xFF; 379 + shield_dev->board_info.serial_number[2 * i + 1] = val >> 8; 380 + } 381 + shield_dev->board_info.serial_number[14] = '\0'; 382 + 383 + set_bit(SHIELD_BOARD_INFO_INITIALIZED, &shield_dev->initialized_flags); 384 + 385 + shield_strrev(board_revision_str, 4, shield_dev->board_info.revision); 386 + hid_dbg(shield_dev->hdev, 387 + "Thunderstrike BOARD_REVISION_%s (0x%04X) S/N: %s\n", 388 + board_revision_str, shield_dev->board_info.revision, 389 + shield_dev->board_info.serial_number); 390 + } 391 + 392 + static inline void 393 + thunderstrike_parse_haptics_payload(struct shield_device *shield_dev, 394 + struct thunderstrike_hostcmd_haptics *haptics) 395 + { 396 + hid_dbg(shield_dev->hdev, 397 + "Thunderstrike haptics HOSTCMD response, left: %u right: %u\n", 398 + haptics->motor_left, haptics->motor_right); 399 + } 400 + 401 + static void 402 + thunderstrike_parse_led_payload(struct shield_device *shield_dev, 403 + enum thunderstrike_led_state led_state) 404 + { 405 + struct thunderstrike *ts = container_of(shield_dev, struct thunderstrike, base); 406 + 407 + switch (led_state) { 408 + case THUNDERSTRIKE_LED_OFF: 409 + ts->led_state = 0; 410 + break; 411 + case THUNDERSTRIKE_LED_ON: 412 + ts->led_state = 1; 413 + break; 414 + } 415 + 416 + hid_dbg(shield_dev->hdev, "Thunderstrike led HOSTCMD response, 0x%02X\n", led_state); 417 + } 418 + 419 + static int thunderstrike_parse_report(struct shield_device *shield_dev, 420 + struct hid_report *report, u8 *data, 421 + int size) 422 + { 423 + struct thunderstrike_hostcmd_resp_report *hostcmd_resp_report; 424 + struct thunderstrike *ts = 425 + container_of(shield_dev, struct thunderstrike, base); 426 + struct hid_device *hdev = shield_dev->hdev; 427 + 428 + switch (report->id) { 429 + case THUNDERSTRIKE_HOSTCMD_RESP_REPORT_ID: 430 + if (size != THUNDERSTRIKE_HOSTCMD_REPORT_SIZE) { 431 + hid_err(hdev, 432 + "Encountered Thunderstrike HOSTCMD HID report with unexpected size %d\n", 433 + size); 434 + return -EINVAL; 435 + } 436 + 437 + hostcmd_resp_report = 438 + (struct thunderstrike_hostcmd_resp_report *)data; 439 + 440 + switch (hostcmd_resp_report->cmd_id) { 441 + case THUNDERSTRIKE_HOSTCMD_ID_FW_VERSION: 442 + thunderstrike_parse_fw_version_payload( 443 + shield_dev, hostcmd_resp_report->fw_version); 444 + break; 445 + case THUNDERSTRIKE_HOSTCMD_ID_LED: 446 + thunderstrike_parse_led_payload(shield_dev, hostcmd_resp_report->led_state); 447 + break; 448 + case THUNDERSTRIKE_HOSTCMD_ID_BOARD_INFO: 449 + thunderstrike_parse_board_info_payload( 450 + shield_dev, &hostcmd_resp_report->board_info); 451 + break; 452 + case THUNDERSTRIKE_HOSTCMD_ID_HAPTICS: 453 + thunderstrike_parse_haptics_payload( 454 + shield_dev, &hostcmd_resp_report->motors); 455 + break; 456 + 457 + case THUNDERSTRIKE_HOSTCMD_ID_USB_INIT: 458 + case THUNDERSTRIKE_HOSTCMD_ID_BLUETOOTH_INIT: 459 + /* May block HOSTCMD requests till received initially */ 460 + thunderstrike_request_firmware_version(ts); 461 + thunderstrike_request_board_info(ts); 462 + /* Only HOSTCMD that can be triggered without a request */ 463 + return 0; 464 + default: 465 + hid_warn(hdev, 466 + "Unhandled Thunderstrike HOSTCMD id %d\n", 467 + hostcmd_resp_report->cmd_id); 468 + return -ENOENT; 469 + } 470 + 471 + break; 472 + default: 473 + return 0; 474 + } 475 + 476 + return 0; 477 + } 478 + 479 + static inline int thunderstrike_led_create(struct thunderstrike *ts) 480 + { 481 + struct led_classdev *led = &ts->led_dev; 482 + 483 + led->name = "thunderstrike:blue:led"; 484 + led->max_brightness = 1; 485 + led->flags = LED_CORE_SUSPENDRESUME; 486 + led->brightness_get = &thunderstrike_led_get_brightness; 487 + led->brightness_set = &thunderstrike_led_set_brightness; 488 + 489 + return led_classdev_register(&ts->base.hdev->dev, led); 490 + } 491 + 492 + static struct shield_device *thunderstrike_create(struct hid_device *hdev) 493 + { 494 + struct shield_device *shield_dev; 495 + struct thunderstrike *ts; 496 + int ret; 497 + 498 + ts = devm_kzalloc(&hdev->dev, sizeof(*ts), GFP_KERNEL); 499 + if (!ts) 500 + return ERR_PTR(-ENOMEM); 501 + 502 + ts->req_report_dmabuf = devm_kzalloc( 503 + &hdev->dev, THUNDERSTRIKE_HOSTCMD_REPORT_SIZE, GFP_KERNEL); 504 + if (!ts->req_report_dmabuf) 505 + return ERR_PTR(-ENOMEM); 506 + 507 + shield_dev = &ts->base; 508 + shield_dev->hdev = hdev; 509 + shield_dev->codename = "Thunderstrike"; 510 + 511 + spin_lock_init(&ts->haptics_update_lock); 512 + INIT_WORK(&ts->hostcmd_req_work, thunderstrike_hostcmd_req_work_handler); 513 + 514 + hid_set_drvdata(hdev, shield_dev); 515 + 516 + ret = thunderstrike_led_create(ts); 517 + if (ret) { 518 + hid_err(hdev, "Failed to create Thunderstrike LED instance\n"); 519 + return ERR_PTR(ret); 520 + } 521 + 522 + ts->haptics_dev = shield_haptics_create(shield_dev, thunderstrike_play_effect); 523 + if (IS_ERR(ts->haptics_dev)) 524 + goto err; 525 + 526 + hid_info(hdev, "Registered Thunderstrike controller\n"); 527 + return shield_dev; 528 + 529 + err: 530 + led_classdev_unregister(&ts->led_dev); 531 + return ERR_CAST(ts->haptics_dev); 532 + } 533 + 534 + static int android_input_mapping(struct hid_device *hdev, struct hid_input *hi, 535 + struct hid_field *field, 536 + struct hid_usage *usage, unsigned long **bit, 537 + int *max) 538 + { 539 + if ((usage->hid & HID_USAGE_PAGE) != HID_UP_CONSUMER) 540 + return 0; 541 + 542 + switch (usage->hid & HID_USAGE) { 543 + case HID_USAGE_ANDROID_PLAYPAUSE_BTN: 544 + android_map_key(KEY_PLAYPAUSE); 545 + break; 546 + case HID_USAGE_ANDROID_VOLUMEUP_BTN: 547 + android_map_key(KEY_VOLUMEUP); 548 + break; 549 + case HID_USAGE_ANDROID_VOLUMEDOWN_BTN: 550 + android_map_key(KEY_VOLUMEDOWN); 551 + break; 552 + case HID_USAGE_ANDROID_SEARCH_BTN: 553 + android_map_key(BTN_Z); 554 + break; 555 + case HID_USAGE_ANDROID_HOME_BTN: 556 + android_map_key(BTN_MODE); 557 + break; 558 + case HID_USAGE_ANDROID_BACK_BTN: 559 + android_map_key(BTN_SELECT); 560 + break; 561 + default: 562 + return 0; 563 + } 564 + 565 + return 1; 566 + } 567 + 568 + static ssize_t firmware_version_show(struct device *dev, 569 + struct device_attribute *attr, char *buf) 570 + { 571 + struct hid_device *hdev = to_hid_device(dev); 572 + struct shield_device *shield_dev; 573 + int ret; 574 + 575 + shield_dev = hid_get_drvdata(hdev); 576 + 577 + if (test_bit(SHIELD_FW_VERSION_INITIALIZED, &shield_dev->initialized_flags)) 578 + ret = sysfs_emit(buf, "0x%04X\n", shield_dev->fw_version); 579 + else 580 + ret = sysfs_emit(buf, NOT_INIT_STR "\n"); 581 + 582 + return ret; 583 + } 584 + 585 + static DEVICE_ATTR_RO(firmware_version); 586 + 587 + static ssize_t hardware_version_show(struct device *dev, 588 + struct device_attribute *attr, char *buf) 589 + { 590 + struct hid_device *hdev = to_hid_device(dev); 591 + struct shield_device *shield_dev; 592 + char board_revision_str[4]; 593 + int ret; 594 + 595 + shield_dev = hid_get_drvdata(hdev); 596 + 597 + if (test_bit(SHIELD_BOARD_INFO_INITIALIZED, &shield_dev->initialized_flags)) { 598 + shield_strrev(board_revision_str, 4, shield_dev->board_info.revision); 599 + ret = sysfs_emit(buf, "%s BOARD_REVISION_%s (0x%04X)\n", 600 + shield_dev->codename, board_revision_str, 601 + shield_dev->board_info.revision); 602 + } else 603 + ret = sysfs_emit(buf, NOT_INIT_STR "\n"); 604 + 605 + return ret; 606 + } 607 + 608 + static DEVICE_ATTR_RO(hardware_version); 609 + 610 + static ssize_t serial_number_show(struct device *dev, 611 + struct device_attribute *attr, char *buf) 612 + { 613 + struct hid_device *hdev = to_hid_device(dev); 614 + struct shield_device *shield_dev; 615 + int ret; 616 + 617 + shield_dev = hid_get_drvdata(hdev); 618 + 619 + if (test_bit(SHIELD_BOARD_INFO_INITIALIZED, &shield_dev->initialized_flags)) 620 + ret = sysfs_emit(buf, "%s\n", shield_dev->board_info.serial_number); 621 + else 622 + ret = sysfs_emit(buf, NOT_INIT_STR "\n"); 623 + 624 + return ret; 625 + } 626 + 627 + static DEVICE_ATTR_RO(serial_number); 628 + 629 + static struct attribute *shield_device_attrs[] = { 630 + &dev_attr_firmware_version.attr, 631 + &dev_attr_hardware_version.attr, 632 + &dev_attr_serial_number.attr, 633 + NULL, 634 + }; 635 + ATTRIBUTE_GROUPS(shield_device); 636 + 637 + static int shield_raw_event(struct hid_device *hdev, struct hid_report *report, 638 + u8 *data, int size) 639 + { 640 + struct shield_device *dev = hid_get_drvdata(hdev); 641 + 642 + return thunderstrike_parse_report(dev, report, data, size); 643 + } 644 + 645 + static int shield_probe(struct hid_device *hdev, const struct hid_device_id *id) 646 + { 647 + struct shield_device *shield_dev = NULL; 648 + struct thunderstrike *ts; 649 + int ret; 650 + 651 + ret = hid_parse(hdev); 652 + if (ret) { 653 + hid_err(hdev, "Parse failed\n"); 654 + return ret; 655 + } 656 + 657 + switch (id->product) { 658 + case USB_DEVICE_ID_NVIDIA_THUNDERSTRIKE_CONTROLLER: 659 + shield_dev = thunderstrike_create(hdev); 660 + break; 661 + } 662 + 663 + if (unlikely(!shield_dev)) { 664 + hid_err(hdev, "Failed to identify SHIELD device\n"); 665 + return -ENODEV; 666 + } 667 + if (IS_ERR(shield_dev)) { 668 + hid_err(hdev, "Failed to create SHIELD device\n"); 669 + return PTR_ERR(shield_dev); 670 + } 671 + 672 + ts = container_of(shield_dev, struct thunderstrike, base); 673 + 674 + ret = hid_hw_start(hdev, HID_CONNECT_HIDINPUT); 675 + if (ret) { 676 + hid_err(hdev, "Failed to start HID device\n"); 677 + goto err_haptics; 678 + } 679 + 680 + ret = hid_hw_open(hdev); 681 + if (ret) { 682 + hid_err(hdev, "Failed to open HID device\n"); 683 + goto err_stop; 684 + } 685 + 686 + thunderstrike_request_firmware_version(ts); 687 + thunderstrike_request_board_info(ts); 688 + 689 + return ret; 690 + 691 + err_stop: 692 + hid_hw_stop(hdev); 693 + err_haptics: 694 + if (ts->haptics_dev) 695 + input_unregister_device(ts->haptics_dev); 696 + return ret; 697 + } 698 + 699 + static void shield_remove(struct hid_device *hdev) 700 + { 701 + struct shield_device *dev = hid_get_drvdata(hdev); 702 + struct thunderstrike *ts; 703 + 704 + ts = container_of(dev, struct thunderstrike, base); 705 + 706 + hid_hw_close(hdev); 707 + led_classdev_unregister(&ts->led_dev); 708 + if (ts->haptics_dev) 709 + input_unregister_device(ts->haptics_dev); 710 + cancel_work_sync(&ts->hostcmd_req_work); 711 + hid_hw_stop(hdev); 712 + } 713 + 714 + static const struct hid_device_id shield_devices[] = { 715 + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NVIDIA, 716 + USB_DEVICE_ID_NVIDIA_THUNDERSTRIKE_CONTROLLER) }, 717 + { HID_USB_DEVICE(USB_VENDOR_ID_NVIDIA, 718 + USB_DEVICE_ID_NVIDIA_THUNDERSTRIKE_CONTROLLER) }, 719 + { } 720 + }; 721 + MODULE_DEVICE_TABLE(hid, shield_devices); 722 + 723 + static struct hid_driver shield_driver = { 724 + .name = "shield", 725 + .id_table = shield_devices, 726 + .input_mapping = android_input_mapping, 727 + .probe = shield_probe, 728 + .remove = shield_remove, 729 + .raw_event = shield_raw_event, 730 + .driver = { 731 + .dev_groups = shield_device_groups, 732 + }, 733 + }; 734 + module_hid_driver(shield_driver); 735 + 736 + MODULE_AUTHOR("Rahul Rameshbabu <rrameshbabu@nvidia.com>"); 737 + MODULE_DESCRIPTION("HID Driver for NVIDIA SHIELD peripherals."); 738 + MODULE_LICENSE("GPL");
+1
drivers/hid/hid-quirks.c
··· 96 96 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096), HID_QUIRK_NO_INIT_REPORTS }, 97 97 { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A293), HID_QUIRK_ALWAYS_POLL }, 98 98 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A), HID_QUIRK_ALWAYS_POLL }, 99 + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_ELITE_PRESENTER_MOUSE_464A), HID_QUIRK_MULTI_INPUT }, 99 100 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A), HID_QUIRK_ALWAYS_POLL }, 100 101 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL }, 101 102 { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_094A), HID_QUIRK_ALWAYS_POLL },
+7 -2
drivers/hid/hidraw.c
··· 272 272 goto out; 273 273 } 274 274 275 - down_read(&minors_rwsem); 275 + /* 276 + * Technically not writing to the hidraw_table but a write lock is 277 + * required to protect the device refcount. This is symmetrical to 278 + * hidraw_release(). 279 + */ 280 + down_write(&minors_rwsem); 276 281 if (!hidraw_table[minor] || !hidraw_table[minor]->exist) { 277 282 err = -ENODEV; 278 283 goto out_unlock; ··· 306 301 spin_unlock_irqrestore(&hidraw_table[minor]->list_lock, flags); 307 302 file->private_data = list; 308 303 out_unlock: 309 - up_read(&minors_rwsem); 304 + up_write(&minors_rwsem); 310 305 out: 311 306 if (err < 0) 312 307 kfree(list);
+1 -1
drivers/hid/i2c-hid/i2c-hid-acpi.c
··· 118 118 .acpi_match_table = i2c_hid_acpi_match, 119 119 }, 120 120 121 - .probe_new = i2c_hid_acpi_probe, 121 + .probe = i2c_hid_acpi_probe, 122 122 .remove = i2c_hid_core_remove, 123 123 .shutdown = i2c_hid_core_shutdown, 124 124 };
+1 -1
drivers/hid/i2c-hid/i2c-hid-of-elan.c
··· 118 118 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 119 119 .of_match_table = of_match_ptr(elan_i2c_hid_of_match), 120 120 }, 121 - .probe_new = i2c_hid_of_elan_probe, 121 + .probe = i2c_hid_of_elan_probe, 122 122 .remove = i2c_hid_core_remove, 123 123 .shutdown = i2c_hid_core_shutdown, 124 124 };
+16 -2
drivers/hid/i2c-hid/i2c-hid-of-goodix.c
··· 28 28 struct regulator *vdd; 29 29 struct regulator *vddio; 30 30 struct gpio_desc *reset_gpio; 31 + bool no_reset_during_suspend; 31 32 const struct goodix_i2c_hid_timing_data *timings; 32 33 }; 33 34 ··· 37 36 struct i2c_hid_of_goodix *ihid_goodix = 38 37 container_of(ops, struct i2c_hid_of_goodix, ops); 39 38 int ret; 39 + 40 + /* 41 + * We assert reset GPIO here (instead of during power-down) to ensure 42 + * the device will have a clean state after powering up, just like the 43 + * normal scenarios will have. 44 + */ 45 + if (ihid_goodix->no_reset_during_suspend) 46 + gpiod_set_value_cansleep(ihid_goodix->reset_gpio, 1); 40 47 41 48 ret = regulator_enable(ihid_goodix->vdd); 42 49 if (ret) ··· 69 60 struct i2c_hid_of_goodix *ihid_goodix = 70 61 container_of(ops, struct i2c_hid_of_goodix, ops); 71 62 72 - gpiod_set_value_cansleep(ihid_goodix->reset_gpio, 1); 63 + if (!ihid_goodix->no_reset_during_suspend) 64 + gpiod_set_value_cansleep(ihid_goodix->reset_gpio, 1); 65 + 73 66 regulator_disable(ihid_goodix->vddio); 74 67 regulator_disable(ihid_goodix->vdd); 75 68 } ··· 102 91 if (IS_ERR(ihid_goodix->vddio)) 103 92 return PTR_ERR(ihid_goodix->vddio); 104 93 94 + ihid_goodix->no_reset_during_suspend = 95 + of_property_read_bool(client->dev.of_node, "goodix,no-reset-during-suspend"); 96 + 105 97 ihid_goodix->timings = device_get_match_data(&client->dev); 106 98 107 99 return i2c_hid_core_probe(client, &ihid_goodix->ops, 0x0001, 0); ··· 128 114 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 129 115 .of_match_table = of_match_ptr(goodix_i2c_hid_of_match), 130 116 }, 131 - .probe_new = i2c_hid_of_goodix_probe, 117 + .probe = i2c_hid_of_goodix_probe, 132 118 .remove = i2c_hid_core_remove, 133 119 .shutdown = i2c_hid_core_shutdown, 134 120 };
+1 -1
drivers/hid/i2c-hid/i2c-hid-of.c
··· 157 157 .of_match_table = of_match_ptr(i2c_hid_of_match), 158 158 }, 159 159 160 - .probe_new = i2c_hid_of_probe, 160 + .probe = i2c_hid_of_probe, 161 161 .remove = i2c_hid_core_remove, 162 162 .shutdown = i2c_hid_core_shutdown, 163 163 .id_table = i2c_hid_of_id_table,
+1
drivers/hid/intel-ish-hid/ipc/hw-ish.h
··· 33 33 #define ADL_N_DEVICE_ID 0x54FC 34 34 #define RPL_S_DEVICE_ID 0x7A78 35 35 #define MTL_P_DEVICE_ID 0x7E45 36 + #define ARL_H_DEVICE_ID 0x7745 36 37 37 38 #define REVISION_ID_CHT_A0 0x6 38 39 #define REVISION_ID_CHT_Ax_SI 0x0
+1
drivers/hid/intel-ish-hid/ipc/pci-ish.c
··· 44 44 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ADL_N_DEVICE_ID)}, 45 45 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, RPL_S_DEVICE_ID)}, 46 46 {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MTL_P_DEVICE_ID)}, 47 + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, ARL_H_DEVICE_ID)}, 47 48 {0, } 48 49 }; 49 50 MODULE_DEVICE_TABLE(pci, ish_pci_tbl);
+3 -3
drivers/hid/wacom_wac.c
··· 1314 1314 struct input_dev *pen_input = wacom->pen_input; 1315 1315 unsigned char *data = wacom->data; 1316 1316 int number_of_valid_frames = 0; 1317 - int time_interval = 15000000; 1317 + ktime_t time_interval = 15000000; 1318 1318 ktime_t time_packet_received = ktime_get(); 1319 1319 int i; 1320 1320 ··· 1348 1348 if (number_of_valid_frames) { 1349 1349 if (wacom->hid_data.time_delayed) 1350 1350 time_interval = ktime_get() - wacom->hid_data.time_delayed; 1351 - time_interval /= number_of_valid_frames; 1351 + time_interval = div_u64(time_interval, number_of_valid_frames); 1352 1352 wacom->hid_data.time_delayed = time_packet_received; 1353 1353 } 1354 1354 ··· 1359 1359 bool range = frame[0] & 0x20; 1360 1360 bool invert = frame[0] & 0x10; 1361 1361 int frames_number_reversed = number_of_valid_frames - i - 1; 1362 - int event_timestamp = time_packet_received - frames_number_reversed * time_interval; 1362 + ktime_t event_timestamp = time_packet_received - frames_number_reversed * time_interval; 1363 1363 1364 1364 if (!valid) 1365 1365 continue;
+1 -1
drivers/hid/wacom_wac.h
··· 324 324 int ps_connected; 325 325 bool pad_input_event_flag; 326 326 unsigned short sequence_number; 327 - int time_delayed; 327 + ktime_t time_delayed; 328 328 }; 329 329 330 330 struct wacom_remote_data {
+1
include/linux/hid.h
··· 597 597 struct semaphore driver_input_lock; /* protects the current driver */ 598 598 struct device dev; /* device */ 599 599 struct hid_driver *driver; 600 + void *devres_group_id; /* ID of probe devres group */ 600 601 601 602 const struct hid_ll_driver *ll_driver; 602 603 struct mutex ll_open_lock;
+81 -3
tools/testing/selftests/hid/tests/test_wacom_generic.py
··· 31 31 from hidtools.hut import HUT 32 32 from hidtools.hid import HidUnit 33 33 from . import base 34 + from . import test_multitouch 34 35 import libevdev 35 36 import pytest 36 37 ··· 518 517 for usage in get_report_usages(report): 519 518 yield usage 520 519 521 - def assertName(self, uhdev): 520 + def assertName(self, uhdev, type): 522 521 """ 523 522 Assert that the name is as we expect. 524 523 ··· 527 526 this assertion from the base class to work properly. 528 527 """ 529 528 evdev = uhdev.get_evdev() 530 - expected_name = uhdev.name + " Pen" 529 + expected_name = uhdev.name + type 531 530 if "wacom" not in expected_name.lower(): 532 531 expected_name = "Wacom " + expected_name 533 532 assert evdev.name == expected_name ··· 548 547 PhysRange.CENTIMETER, 5, 150 549 548 ), 550 549 usage_id("Generic Desktop", "Y"): PhysRange( 550 + PhysRange.CENTIMETER, 5, 150 551 + ), 552 + usage_id("Digitizers", "Width"): PhysRange( 553 + PhysRange.CENTIMETER, 5, 150 554 + ), 555 + usage_id("Digitizers", "Height"): PhysRange( 551 556 PhysRange.CENTIMETER, 5, 150 552 557 ), 553 558 usage_id("Digitizers", "X Tilt"): PhysRange(PhysRange.DEGREE, 90, 180), ··· 610 603 pass 611 604 612 605 613 - class TestOpaqueTablet(BaseTest.TestTablet): 606 + class PenTabletTest(BaseTest.TestTablet): 607 + def assertName(self, uhdev): 608 + super().assertName(uhdev, " Pen") 609 + 610 + 611 + class TouchTabletTest(BaseTest.TestTablet): 612 + def assertName(self, uhdev): 613 + super().assertName(uhdev, " Finger") 614 + 615 + 616 + class TestOpaqueTablet(PenTabletTest): 614 617 def create_device(self): 615 618 return OpaqueTablet() 616 619 ··· 859 842 libevdev.InputEvent(libevdev.EV_KEY.BTN_0, 0), 860 843 ], 861 844 ) 845 + 846 + 847 + class TestDTH2452Tablet(test_multitouch.BaseTest.TestMultitouch, TouchTabletTest): 848 + def create_device(self): 849 + return test_multitouch.Digitizer( 850 + "DTH 2452", 851 + rdesc="05 0d 09 04 a1 01 85 0c 95 01 75 08 15 00 26 ff 00 81 03 09 54 81 02 09 22 a1 02 05 0d 95 01 75 01 25 01 09 42 81 02 81 03 09 47 81 02 95 05 81 03 09 51 26 ff 00 75 10 95 01 81 02 35 00 65 11 55 0e 05 01 09 30 26 a0 44 46 96 14 81 42 09 31 26 9a 26 46 95 0b 81 42 05 0d 75 08 95 01 15 00 09 48 26 5f 00 46 7c 14 81 02 09 49 25 35 46 7d 0b 81 02 45 00 65 00 55 00 c0 05 0d 09 22 a1 02 05 0d 95 01 75 01 25 01 09 42 81 02 81 03 09 47 81 02 95 05 81 03 09 51 26 ff 00 75 10 95 01 81 02 35 00 65 11 55 0e 05 01 09 30 26 a0 44 46 96 14 81 42 09 31 26 9a 26 46 95 0b 81 42 05 0d 75 08 95 01 15 00 09 48 26 5f 00 46 7c 14 81 02 09 49 25 35 46 7d 0b 81 02 45 00 65 00 55 00 c0 05 0d 09 22 a1 02 05 0d 95 01 75 01 25 01 09 42 81 02 81 03 09 47 81 02 95 05 81 03 09 51 26 ff 00 75 10 95 01 81 02 35 00 65 11 55 0e 05 01 09 30 26 a0 44 46 96 14 81 42 09 31 26 9a 26 46 95 0b 81 42 05 0d 75 08 95 01 15 00 09 48 26 5f 00 46 7c 14 81 02 09 49 25 35 46 7d 0b 81 02 45 00 65 00 55 00 c0 05 0d 09 22 a1 02 05 0d 95 01 75 01 25 01 09 42 81 02 81 03 09 47 81 02 95 05 81 03 09 51 26 ff 00 75 10 95 01 81 02 35 00 65 11 55 0e 05 01 09 30 26 a0 44 46 96 14 81 42 09 31 26 9a 26 46 95 0b 81 42 05 0d 75 08 95 01 15 00 09 48 26 5f 00 46 7c 14 81 02 09 49 25 35 46 7d 0b 81 02 45 00 65 00 55 00 c0 05 0d 09 22 a1 02 05 0d 95 01 75 01 25 01 09 42 81 02 81 03 09 47 81 02 95 05 81 03 09 51 26 ff 00 75 10 95 01 81 02 35 00 65 11 55 0e 05 01 09 30 26 a0 44 46 96 14 81 42 09 31 26 9a 26 46 95 0b 81 42 05 0d 75 08 95 01 15 00 09 48 26 5f 00 46 7c 14 81 02 09 49 25 35 46 7d 0b 81 02 45 00 65 00 55 00 c0 05 0d 27 ff ff 00 00 75 10 95 01 09 56 81 02 75 08 95 0e 81 03 09 55 26 ff 00 75 08 b1 02 85 0a 06 00 ff 09 c5 96 00 01 b1 02 c0 06 00 ff 09 01 a1 01 09 01 85 13 15 00 26 ff 00 75 08 95 3f 81 02 06 00 ff 09 01 15 00 26 ff 00 75 08 95 3f 91 02 c0", 852 + input_info=(0x3, 0x056A, 0x0383), 853 + ) 854 + 855 + def test_contact_id_0(self): 856 + """ 857 + Bring a finger in contact with the tablet, then hold it down and remove it. 858 + 859 + Ensure that even with contact ID = 0 which is usually given as an invalid 860 + touch event by most tablets with the exception of a few, that given the 861 + confidence bit is set to 1 it should process it as a valid touch to cover 862 + the few tablets using contact ID = 0 as a valid touch value. 863 + """ 864 + uhdev = self.uhdev 865 + evdev = uhdev.get_evdev() 866 + 867 + t0 = test_multitouch.Touch(0, 50, 100) 868 + r = uhdev.event([t0]) 869 + events = uhdev.next_sync_events() 870 + self.debug_reports(r, uhdev, events) 871 + 872 + slot = self.get_slot(uhdev, t0, 0) 873 + 874 + assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH, 1) in events 875 + assert evdev.slots[slot][libevdev.EV_ABS.ABS_MT_TRACKING_ID] == 0 876 + assert evdev.slots[slot][libevdev.EV_ABS.ABS_MT_POSITION_X] == 50 877 + assert evdev.slots[slot][libevdev.EV_ABS.ABS_MT_POSITION_Y] == 100 878 + 879 + t0.tipswitch = False 880 + if uhdev.quirks is None or "VALID_IS_INRANGE" not in uhdev.quirks: 881 + t0.inrange = False 882 + r = uhdev.event([t0]) 883 + events = uhdev.next_sync_events() 884 + self.debug_reports(r, uhdev, events) 885 + assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH, 0) in events 886 + assert evdev.slots[slot][libevdev.EV_ABS.ABS_MT_TRACKING_ID] == -1 887 + 888 + def test_confidence_false(self): 889 + """ 890 + Bring a finger in contact with the tablet with confidence set to false. 891 + 892 + Ensure that the confidence bit being set to false should not result in a touch event. 893 + """ 894 + uhdev = self.uhdev 895 + evdev = uhdev.get_evdev() 896 + 897 + t0 = test_multitouch.Touch(1, 50, 100) 898 + t0.confidence = False 899 + r = uhdev.event([t0]) 900 + events = uhdev.next_sync_events() 901 + self.debug_reports(r, uhdev, events) 902 + 903 + slot = self.get_slot(uhdev, t0, 0) 904 + 905 + assert not events