mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	hid-for-linus-2025101701
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEL65usyKPHcrRDEicpmLzj2vtYEkFAmjyYSUACgkQpmLzj2vt YEnGlxAAukp9PohVJYj5XXfIZXd6nl9wQyTLfVxCaw03R4IBSwq6/SpbSFP3Khr0 nR6wss6GdpiHGc8WA7Yo3EIZGsZtSolaOrg2pozKop24FD42S5bgq/qWeUNERhGF LU6+zpZbYhZ5Joo2Q57vRZ4D9UDYg7CoU1jVAkscEuvQhishLFKpG88VE9Jy/2Eu SGQ9Aqq/0NAC/msUHtVWn90EiLIQBS4izWO02Js6JObf8mdisH1MQscOeJ2rfJhV 7WcdMX/LkqL7DQ9dFFo3j5NqE3SF1aJFjhMY+xivQaYeuwPSffCuWrbVq6TM74hP uRfIII1YUYAEyh+69KgQbQLGl0OqZbDhtEZ5p2SCn3DaMwXu+sraxfWRQ8nkG55w Gw74ibc3F9pUwwls9i7FUJE3CzoNBcN/FdxvWST5izni4rC2XAC7pzeSmyO3jiQO Zvpwa0VkaOeZ1OmVqo4YQBZoNlgBIaBPxqtoHfHxwvEvqUmivSzU+//XFGbvXgK1 XL8hgYd7P1P6g9UVSvsgiVA6FIdR4EtpbOV3YxQpMVv8uAOCN5omeOAd9jRImN2a BxpKr5bcB4JhZcji/E4T4IPegA+8LUniZ6AW5KIUCCz34uDyeDSHsWB+cZiy31zc gGa0NqGRfhKOzqj9ExnnRDoZWyhnoHZ3yxUb41TPQfS2p5uZepM= =UpoT -----END PGP SIGNATURE----- Merge tag 'hid-for-linus-2025101701' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid Pull HID fixes from Jiri Kosina: - fix for sticky fingers handling in hid-multitouch (Benjamin Tissoires) - fix for reporting of 0 battery levels (Dmitry Torokhov) - build fix for hid-haptic in certain configurations (Jonathan Denose) - improved probe and avoiding spamming kernel log by hid-nintendo (Vicki Pfau) - fix for OOB in hid-cp2112 (Deepak Sharma) - interrupt handling fix for intel-thc-hid (Even Xu) - a couple of new device IDs and device-specific quirks * tag 'hid-for-linus-2025101701' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: HID: logitech-hidpp: Add HIDPP_QUIRK_RESET_HI_RES_SCROLL selftests/hid: add tests for missing release on the Dell Synaptics HID: multitouch: fix sticky fingers HID: multitouch: fix name of Stylus input devices HID: hid-input: only ignore 0 battery events for digitizers HID: hid-debug: Fix spelling mistake "Rechargable" -> "Rechargeable" HID: Kconfig: Fix build error from CONFIG_HID_HAPTIC HID: nintendo: Rate limit IMU compensation message HID: nintendo: Wait longer for initial probe HID: core: Add printk_ratelimited variants to hid_warn() etc HID: quirks: Add ALWAYS_POLL quirk for VRS R295 steering wheel HID: quirks: avoid Cooler Master MM712 dongle wakeup bug HID: cp2112: Add parameter validation to data length HID: intel-thc-hid: intel-quickspi: Add ARL PCI Device Id's HID: intel-thc-hid: Intel-quickspi: switch first interrupt from level to edge detection HID: intel-thc-hid: intel-quicki2c: Fix wrong type casting
This commit is contained in:
		
						commit
						2953fb6548
					
				
					 15 changed files with 151 additions and 25 deletions
				
			
		|  | @ -93,7 +93,7 @@ config HID_GENERIC | ||||||
| 	If unsure, say Y. | 	If unsure, say Y. | ||||||
| 
 | 
 | ||||||
| config HID_HAPTIC | config HID_HAPTIC | ||||||
| 	tristate "Haptic touchpad support" | 	bool "Haptic touchpad support" | ||||||
| 	default n | 	default n | ||||||
| 	help | 	help | ||||||
| 	Support for touchpads with force sensors and haptic actuators instead of a | 	Support for touchpads with force sensors and haptic actuators instead of a | ||||||
|  |  | ||||||
|  | @ -689,6 +689,13 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr, | ||||||
| 			count = cp2112_write_read_req(buf, addr, read_length, | 			count = cp2112_write_read_req(buf, addr, read_length, | ||||||
| 						      command, NULL, 0); | 						      command, NULL, 0); | ||||||
| 		} else { | 		} else { | ||||||
|  | 			/* Copy starts from data->block[1] so the length can
 | ||||||
|  | 			 * be at max I2C_SMBUS_CLOCK_MAX + 1 | ||||||
|  | 			 */ | ||||||
|  | 
 | ||||||
|  | 			if (data->block[0] > I2C_SMBUS_BLOCK_MAX + 1) | ||||||
|  | 				count = -EINVAL; | ||||||
|  | 			else | ||||||
| 				count = cp2112_write_req(buf, addr, command, | 				count = cp2112_write_req(buf, addr, command, | ||||||
| 						 data->block + 1, | 						 data->block + 1, | ||||||
| 						 data->block[0]); | 						 data->block[0]); | ||||||
|  | @ -700,6 +707,13 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr, | ||||||
| 						      I2C_SMBUS_BLOCK_MAX, | 						      I2C_SMBUS_BLOCK_MAX, | ||||||
| 						      command, NULL, 0); | 						      command, NULL, 0); | ||||||
| 		} else { | 		} else { | ||||||
|  | 			/* data_length here is data->block[0] + 1
 | ||||||
|  | 			 * so make sure that the data->block[0] is | ||||||
|  | 			 * less than or equals I2C_SMBUS_BLOCK_MAX + 1 | ||||||
|  | 			*/ | ||||||
|  | 			if (data->block[0] > I2C_SMBUS_BLOCK_MAX + 1) | ||||||
|  | 				count = -EINVAL; | ||||||
|  | 			else | ||||||
| 				count = cp2112_write_req(buf, addr, command, | 				count = cp2112_write_req(buf, addr, command, | ||||||
| 						 data->block, | 						 data->block, | ||||||
| 						 data->block[0] + 1); | 						 data->block[0] + 1); | ||||||
|  | @ -709,6 +723,13 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr, | ||||||
| 		size = I2C_SMBUS_BLOCK_DATA; | 		size = I2C_SMBUS_BLOCK_DATA; | ||||||
| 		read_write = I2C_SMBUS_READ; | 		read_write = I2C_SMBUS_READ; | ||||||
| 
 | 
 | ||||||
|  | 		/* data_length is data->block[0] + 1, so
 | ||||||
|  | 		 * so data->block[0] should be less than or | ||||||
|  | 		 * equal to the I2C_SMBUS_BLOCK_MAX + 1 | ||||||
|  | 		*/ | ||||||
|  | 		if (data->block[0] > I2C_SMBUS_BLOCK_MAX + 1) | ||||||
|  | 			count = -EINVAL; | ||||||
|  | 		else | ||||||
| 			count = cp2112_write_read_req(buf, addr, I2C_SMBUS_BLOCK_MAX, | 			count = cp2112_write_read_req(buf, addr, I2C_SMBUS_BLOCK_MAX, | ||||||
| 					      command, data->block, | 					      command, data->block, | ||||||
| 					      data->block[0] + 1); | 					      data->block[0] + 1); | ||||||
|  |  | ||||||
|  | @ -2523,7 +2523,7 @@ static const struct hid_usage_entry hid_usage_table[] = { | ||||||
| 		{ 0x85, 0x0088, "iDeviceName" }, | 		{ 0x85, 0x0088, "iDeviceName" }, | ||||||
| 		{ 0x85, 0x0089, "iDeviceChemistry" }, | 		{ 0x85, 0x0089, "iDeviceChemistry" }, | ||||||
| 		{ 0x85, 0x008a, "ManufacturerData" }, | 		{ 0x85, 0x008a, "ManufacturerData" }, | ||||||
| 		{ 0x85, 0x008b, "Rechargable" }, | 		{ 0x85, 0x008b, "Rechargeable" }, | ||||||
| 		{ 0x85, 0x008c, "WarningCapacityLimit" }, | 		{ 0x85, 0x008c, "WarningCapacityLimit" }, | ||||||
| 		{ 0x85, 0x008d, "CapacityGranularity1" }, | 		{ 0x85, 0x008d, "CapacityGranularity1" }, | ||||||
| 		{ 0x85, 0x008e, "CapacityGranularity2" }, | 		{ 0x85, 0x008e, "CapacityGranularity2" }, | ||||||
|  |  | ||||||
|  | @ -342,6 +342,9 @@ | ||||||
| #define USB_DEVICE_ID_CODEMERCS_IOW_FIRST	0x1500 | #define USB_DEVICE_ID_CODEMERCS_IOW_FIRST	0x1500 | ||||||
| #define USB_DEVICE_ID_CODEMERCS_IOW_LAST	0x15ff | #define USB_DEVICE_ID_CODEMERCS_IOW_LAST	0x15ff | ||||||
| 
 | 
 | ||||||
|  | #define USB_VENDOR_ID_COOLER_MASTER	0x2516 | ||||||
|  | #define USB_DEVICE_ID_COOLER_MASTER_MICE_DONGLE	0x01b7 | ||||||
|  | 
 | ||||||
| #define USB_VENDOR_ID_CORSAIR		0x1b1c | #define USB_VENDOR_ID_CORSAIR		0x1b1c | ||||||
| #define USB_DEVICE_ID_CORSAIR_K90	0x1b02 | #define USB_DEVICE_ID_CORSAIR_K90	0x1b02 | ||||||
| #define USB_DEVICE_ID_CORSAIR_K70R      0x1b09 | #define USB_DEVICE_ID_CORSAIR_K70R      0x1b09 | ||||||
|  | @ -1432,6 +1435,7 @@ | ||||||
| 
 | 
 | ||||||
| #define USB_VENDOR_ID_VRS	0x0483 | #define USB_VENDOR_ID_VRS	0x0483 | ||||||
| #define USB_DEVICE_ID_VRS_DFP	0xa355 | #define USB_DEVICE_ID_VRS_DFP	0xa355 | ||||||
|  | #define USB_DEVICE_ID_VRS_R295	0xa44c | ||||||
| 
 | 
 | ||||||
| #define USB_VENDOR_ID_VTL		0x0306 | #define USB_VENDOR_ID_VTL		0x0306 | ||||||
| #define USB_DEVICE_ID_VTL_MULTITOUCH_FF3F	0xff3f | #define USB_DEVICE_ID_VTL_MULTITOUCH_FF3F	0xff3f | ||||||
|  |  | ||||||
|  | @ -635,7 +635,10 @@ static void hidinput_update_battery(struct hid_device *dev, unsigned int usage, | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (value == 0 || value < dev->battery_min || value > dev->battery_max) | 	if ((usage & HID_USAGE_PAGE) == HID_UP_DIGITIZER && value == 0) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	if (value < dev->battery_min || value > dev->battery_max) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	capacity = hidinput_scale_battery_capacity(dev, value); | 	capacity = hidinput_scale_battery_capacity(dev, value); | ||||||
|  |  | ||||||
|  | @ -75,6 +75,7 @@ MODULE_PARM_DESC(disable_tap_to_click, | ||||||
| #define HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS	BIT(27) | #define HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS	BIT(27) | ||||||
| #define HIDPP_QUIRK_HI_RES_SCROLL_1P0		BIT(28) | #define HIDPP_QUIRK_HI_RES_SCROLL_1P0		BIT(28) | ||||||
| #define HIDPP_QUIRK_WIRELESS_STATUS		BIT(29) | #define HIDPP_QUIRK_WIRELESS_STATUS		BIT(29) | ||||||
|  | #define HIDPP_QUIRK_RESET_HI_RES_SCROLL		BIT(30) | ||||||
| 
 | 
 | ||||||
| /* These are just aliases for now */ | /* These are just aliases for now */ | ||||||
| #define HIDPP_QUIRK_KBD_SCROLL_WHEEL HIDPP_QUIRK_HIDPP_WHEELS | #define HIDPP_QUIRK_KBD_SCROLL_WHEEL HIDPP_QUIRK_HIDPP_WHEELS | ||||||
|  | @ -193,6 +194,7 @@ struct hidpp_device { | ||||||
| 	void *private_data; | 	void *private_data; | ||||||
| 
 | 
 | ||||||
| 	struct work_struct work; | 	struct work_struct work; | ||||||
|  | 	struct work_struct reset_hi_res_work; | ||||||
| 	struct kfifo delayed_work_fifo; | 	struct kfifo delayed_work_fifo; | ||||||
| 	struct input_dev *delayed_input; | 	struct input_dev *delayed_input; | ||||||
| 
 | 
 | ||||||
|  | @ -3836,6 +3838,7 @@ static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data, | ||||||
| 	struct hidpp_report *answer = hidpp->send_receive_buf; | 	struct hidpp_report *answer = hidpp->send_receive_buf; | ||||||
| 	struct hidpp_report *report = (struct hidpp_report *)data; | 	struct hidpp_report *report = (struct hidpp_report *)data; | ||||||
| 	int ret; | 	int ret; | ||||||
|  | 	int last_online; | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * If the mutex is locked then we have a pending answer from a | 	 * If the mutex is locked then we have a pending answer from a | ||||||
|  | @ -3877,6 +3880,7 @@ static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data, | ||||||
| 			"See: https://gitlab.freedesktop.org/jwrdegoede/logitech-27mhz-keyboard-encryption-setup/\n"); | 			"See: https://gitlab.freedesktop.org/jwrdegoede/logitech-27mhz-keyboard-encryption-setup/\n"); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	last_online = hidpp->battery.online; | ||||||
| 	if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_BATTERY) { | 	if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_BATTERY) { | ||||||
| 		ret = hidpp20_battery_event_1000(hidpp, data, size); | 		ret = hidpp20_battery_event_1000(hidpp, data, size); | ||||||
| 		if (ret != 0) | 		if (ret != 0) | ||||||
|  | @ -3901,6 +3905,11 @@ static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data, | ||||||
| 			return ret; | 			return ret; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if (hidpp->quirks & HIDPP_QUIRK_RESET_HI_RES_SCROLL) { | ||||||
|  | 		if (last_online == 0 && hidpp->battery.online == 1) | ||||||
|  | 			schedule_work(&hidpp->reset_hi_res_work); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	if (hidpp->quirks & HIDPP_QUIRK_HIDPP_WHEELS) { | 	if (hidpp->quirks & HIDPP_QUIRK_HIDPP_WHEELS) { | ||||||
| 		ret = hidpp10_wheel_raw_event(hidpp, data, size); | 		ret = hidpp10_wheel_raw_event(hidpp, data, size); | ||||||
| 		if (ret != 0) | 		if (ret != 0) | ||||||
|  | @ -4274,6 +4283,13 @@ static void hidpp_connect_event(struct work_struct *work) | ||||||
| 	hidpp->delayed_input = input; | 	hidpp->delayed_input = input; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void hidpp_reset_hi_res_handler(struct work_struct *work) | ||||||
|  | { | ||||||
|  | 	struct hidpp_device *hidpp = container_of(work, struct hidpp_device, reset_hi_res_work); | ||||||
|  | 
 | ||||||
|  | 	hi_res_scroll_enable(hidpp); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static DEVICE_ATTR(builtin_power_supply, 0000, NULL, NULL); | static DEVICE_ATTR(builtin_power_supply, 0000, NULL, NULL); | ||||||
| 
 | 
 | ||||||
| static struct attribute *sysfs_attrs[] = { | static struct attribute *sysfs_attrs[] = { | ||||||
|  | @ -4404,6 +4420,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	INIT_WORK(&hidpp->work, hidpp_connect_event); | 	INIT_WORK(&hidpp->work, hidpp_connect_event); | ||||||
|  | 	INIT_WORK(&hidpp->reset_hi_res_work, hidpp_reset_hi_res_handler); | ||||||
| 	mutex_init(&hidpp->send_mutex); | 	mutex_init(&hidpp->send_mutex); | ||||||
| 	init_waitqueue_head(&hidpp->wait); | 	init_waitqueue_head(&hidpp->wait); | ||||||
| 
 | 
 | ||||||
|  | @ -4499,6 +4516,7 @@ static void hidpp_remove(struct hid_device *hdev) | ||||||
| 
 | 
 | ||||||
| 	hid_hw_stop(hdev); | 	hid_hw_stop(hdev); | ||||||
| 	cancel_work_sync(&hidpp->work); | 	cancel_work_sync(&hidpp->work); | ||||||
|  | 	cancel_work_sync(&hidpp->reset_hi_res_work); | ||||||
| 	mutex_destroy(&hidpp->send_mutex); | 	mutex_destroy(&hidpp->send_mutex); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -4546,6 +4564,9 @@ static const struct hid_device_id hidpp_devices[] = { | ||||||
| 	{ /* Keyboard MX5500 (Bluetooth-receiver in HID proxy mode) */ | 	{ /* Keyboard MX5500 (Bluetooth-receiver in HID proxy mode) */ | ||||||
| 	  LDJ_DEVICE(0xb30b), | 	  LDJ_DEVICE(0xb30b), | ||||||
| 	  .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, | 	  .driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS }, | ||||||
|  | 	{ /* Logitech G502 Lightspeed Wireless Gaming Mouse */ | ||||||
|  | 	  LDJ_DEVICE(0x407f), | ||||||
|  | 	  .driver_data = HIDPP_QUIRK_RESET_HI_RES_SCROLL }, | ||||||
| 
 | 
 | ||||||
| 	{ LDJ_DEVICE(HID_ANY_ID) }, | 	{ LDJ_DEVICE(HID_ANY_ID) }, | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -94,9 +94,8 @@ enum report_mode { | ||||||
| 	TOUCHPAD_REPORT_ALL = TOUCHPAD_REPORT_BUTTONS | TOUCHPAD_REPORT_CONTACTS, | 	TOUCHPAD_REPORT_ALL = TOUCHPAD_REPORT_BUTTONS | TOUCHPAD_REPORT_CONTACTS, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #define MT_IO_FLAGS_RUNNING		0 | #define MT_IO_SLOTS_MASK		GENMASK(7, 0) /* reserve first 8 bits for slot tracking */ | ||||||
| #define MT_IO_FLAGS_ACTIVE_SLOTS	1 | #define MT_IO_FLAGS_RUNNING		32 | ||||||
| #define MT_IO_FLAGS_PENDING_SLOTS	2 |  | ||||||
| 
 | 
 | ||||||
| static const bool mtrue = true;		/* default for true */ | static const bool mtrue = true;		/* default for true */ | ||||||
| static const bool mfalse;		/* default for false */ | static const bool mfalse;		/* default for false */ | ||||||
|  | @ -172,7 +171,11 @@ struct mt_device { | ||||||
| 	struct timer_list release_timer;	/* to release sticky fingers */ | 	struct timer_list release_timer;	/* to release sticky fingers */ | ||||||
| 	struct hid_haptic_device *haptic;	/* haptic related configuration */ | 	struct hid_haptic_device *haptic;	/* haptic related configuration */ | ||||||
| 	struct hid_device *hdev;	/* hid_device we're attached to */ | 	struct hid_device *hdev;	/* hid_device we're attached to */ | ||||||
| 	unsigned long mt_io_flags;	/* mt flags (MT_IO_FLAGS_*) */ | 	unsigned long mt_io_flags;	/* mt flags (MT_IO_FLAGS_RUNNING)
 | ||||||
|  | 					 * first 8 bits are reserved for keeping the slot | ||||||
|  | 					 * states, this is fine because we only support up | ||||||
|  | 					 * to 250 slots (MT_MAX_MAXCONTACT) | ||||||
|  | 					 */ | ||||||
| 	__u8 inputmode_value;	/* InputMode HID feature value */ | 	__u8 inputmode_value;	/* InputMode HID feature value */ | ||||||
| 	__u8 maxcontacts; | 	__u8 maxcontacts; | ||||||
| 	bool is_buttonpad;	/* is this device a button pad? */ | 	bool is_buttonpad;	/* is this device a button pad? */ | ||||||
|  | @ -986,6 +989,7 @@ static void mt_release_pending_palms(struct mt_device *td, | ||||||
| 
 | 
 | ||||||
| 	for_each_set_bit(slotnum, app->pending_palm_slots, td->maxcontacts) { | 	for_each_set_bit(slotnum, app->pending_palm_slots, td->maxcontacts) { | ||||||
| 		clear_bit(slotnum, app->pending_palm_slots); | 		clear_bit(slotnum, app->pending_palm_slots); | ||||||
|  | 		clear_bit(slotnum, &td->mt_io_flags); | ||||||
| 
 | 
 | ||||||
| 		input_mt_slot(input, slotnum); | 		input_mt_slot(input, slotnum); | ||||||
| 		input_mt_report_slot_inactive(input); | 		input_mt_report_slot_inactive(input); | ||||||
|  | @ -1019,12 +1023,6 @@ static void mt_sync_frame(struct mt_device *td, struct mt_application *app, | ||||||
| 	app->left_button_state = 0; | 	app->left_button_state = 0; | ||||||
| 	if (td->is_haptic_touchpad) | 	if (td->is_haptic_touchpad) | ||||||
| 		hid_haptic_pressure_reset(td->haptic); | 		hid_haptic_pressure_reset(td->haptic); | ||||||
| 
 |  | ||||||
| 	if (test_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags)) |  | ||||||
| 		set_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags); |  | ||||||
| 	else |  | ||||||
| 		clear_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags); |  | ||||||
| 	clear_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int mt_compute_timestamp(struct mt_application *app, __s32 value) | static int mt_compute_timestamp(struct mt_application *app, __s32 value) | ||||||
|  | @ -1202,7 +1200,9 @@ static int mt_process_slot(struct mt_device *td, struct input_dev *input, | ||||||
| 		input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); | 		input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); | ||||||
| 		input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); | 		input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); | ||||||
| 
 | 
 | ||||||
| 		set_bit(MT_IO_FLAGS_ACTIVE_SLOTS, &td->mt_io_flags); | 		set_bit(slotnum, &td->mt_io_flags); | ||||||
|  | 	} else { | ||||||
|  | 		clear_bit(slotnum, &td->mt_io_flags); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
|  | @ -1337,7 +1337,7 @@ static void mt_touch_report(struct hid_device *hid, | ||||||
| 	 * defect. | 	 * defect. | ||||||
| 	 */ | 	 */ | ||||||
| 	if (app->quirks & MT_QUIRK_STICKY_FINGERS) { | 	if (app->quirks & MT_QUIRK_STICKY_FINGERS) { | ||||||
| 		if (test_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags)) | 		if (td->mt_io_flags & MT_IO_SLOTS_MASK) | ||||||
| 			mod_timer(&td->release_timer, | 			mod_timer(&td->release_timer, | ||||||
| 				  jiffies + msecs_to_jiffies(100)); | 				  jiffies + msecs_to_jiffies(100)); | ||||||
| 		else | 		else | ||||||
|  | @ -1742,6 +1742,7 @@ static int mt_input_configured(struct hid_device *hdev, struct hid_input *hi) | ||||||
| 	case HID_CP_CONSUMER_CONTROL: | 	case HID_CP_CONSUMER_CONTROL: | ||||||
| 	case HID_GD_WIRELESS_RADIO_CTLS: | 	case HID_GD_WIRELESS_RADIO_CTLS: | ||||||
| 	case HID_GD_SYSTEM_MULTIAXIS: | 	case HID_GD_SYSTEM_MULTIAXIS: | ||||||
|  | 	case HID_DG_PEN: | ||||||
| 		/* already handled by hid core */ | 		/* already handled by hid core */ | ||||||
| 		break; | 		break; | ||||||
| 	case HID_DG_TOUCHSCREEN: | 	case HID_DG_TOUCHSCREEN: | ||||||
|  | @ -1813,6 +1814,7 @@ static void mt_release_contacts(struct hid_device *hid) | ||||||
| 			for (i = 0; i < mt->num_slots; i++) { | 			for (i = 0; i < mt->num_slots; i++) { | ||||||
| 				input_mt_slot(input_dev, i); | 				input_mt_slot(input_dev, i); | ||||||
| 				input_mt_report_slot_inactive(input_dev); | 				input_mt_report_slot_inactive(input_dev); | ||||||
|  | 				clear_bit(i, &td->mt_io_flags); | ||||||
| 			} | 			} | ||||||
| 			input_mt_sync_frame(input_dev); | 			input_mt_sync_frame(input_dev); | ||||||
| 			input_sync(input_dev); | 			input_sync(input_dev); | ||||||
|  | @ -1835,7 +1837,7 @@ static void mt_expired_timeout(struct timer_list *t) | ||||||
| 	 */ | 	 */ | ||||||
| 	if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) | 	if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) | ||||||
| 		return; | 		return; | ||||||
| 	if (test_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags)) | 	if (td->mt_io_flags & MT_IO_SLOTS_MASK) | ||||||
| 		mt_release_contacts(hdev); | 		mt_release_contacts(hdev); | ||||||
| 	clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); | 	clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1455,10 +1455,10 @@ static void joycon_parse_imu_report(struct joycon_ctlr *ctlr, | ||||||
| 				ctlr->imu_avg_delta_ms; | 				ctlr->imu_avg_delta_ms; | ||||||
| 		ctlr->imu_timestamp_us += 1000 * ctlr->imu_avg_delta_ms; | 		ctlr->imu_timestamp_us += 1000 * ctlr->imu_avg_delta_ms; | ||||||
| 		if (dropped_pkts > JC_IMU_DROPPED_PKT_WARNING) { | 		if (dropped_pkts > JC_IMU_DROPPED_PKT_WARNING) { | ||||||
| 			hid_warn(ctlr->hdev, | 			hid_warn_ratelimited(ctlr->hdev, | ||||||
| 				 "compensating for %u dropped IMU reports\n", | 				 "compensating for %u dropped IMU reports\n", | ||||||
| 				 dropped_pkts); | 				 dropped_pkts); | ||||||
| 			hid_warn(ctlr->hdev, | 			hid_warn_ratelimited(ctlr->hdev, | ||||||
| 				 "delta=%u avg_delta=%u\n", | 				 "delta=%u avg_delta=%u\n", | ||||||
| 				 delta, ctlr->imu_avg_delta_ms); | 				 delta, ctlr->imu_avg_delta_ms); | ||||||
| 		} | 		} | ||||||
|  | @ -2420,7 +2420,7 @@ static int joycon_read_info(struct joycon_ctlr *ctlr) | ||||||
| 	struct joycon_input_report *report; | 	struct joycon_input_report *report; | ||||||
| 
 | 
 | ||||||
| 	req.subcmd_id = JC_SUBCMD_REQ_DEV_INFO; | 	req.subcmd_id = JC_SUBCMD_REQ_DEV_INFO; | ||||||
| 	ret = joycon_send_subcmd(ctlr, &req, 0, HZ); | 	ret = joycon_send_subcmd(ctlr, &req, 0, 2 * HZ); | ||||||
| 	if (ret) { | 	if (ret) { | ||||||
| 		hid_err(ctlr->hdev, "Failed to get joycon info; ret=%d\n", ret); | 		hid_err(ctlr->hdev, "Failed to get joycon info; ret=%d\n", ret); | ||||||
| 		return ret; | 		return ret; | ||||||
|  |  | ||||||
|  | @ -57,6 +57,7 @@ static const struct hid_device_id hid_quirks[] = { | ||||||
| 	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE), HID_QUIRK_NOGET }, | 	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE), HID_QUIRK_NOGET }, | ||||||
| 	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS), HID_QUIRK_NOGET }, | 	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS), HID_QUIRK_NOGET }, | ||||||
| 	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_THROTTLE), HID_QUIRK_NOGET }, | 	{ HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_THROTTLE), HID_QUIRK_NOGET }, | ||||||
|  | 	{ HID_USB_DEVICE(USB_VENDOR_ID_COOLER_MASTER, USB_DEVICE_ID_COOLER_MASTER_MICE_DONGLE), HID_QUIRK_ALWAYS_POLL }, | ||||||
| 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB), HID_QUIRK_NO_INIT_REPORTS }, | 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB), HID_QUIRK_NO_INIT_REPORTS }, | ||||||
| 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL }, | 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K65RGB_RAPIDFIRE), HID_QUIRK_NO_INIT_REPORTS | HID_QUIRK_ALWAYS_POLL }, | ||||||
| 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB), HID_QUIRK_NO_INIT_REPORTS }, | 	{ HID_USB_DEVICE(USB_VENDOR_ID_CORSAIR, USB_DEVICE_ID_CORSAIR_K70RGB), HID_QUIRK_NO_INIT_REPORTS }, | ||||||
|  | @ -206,6 +207,7 @@ static const struct hid_device_id hid_quirks[] = { | ||||||
| 	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5), HID_QUIRK_MULTI_INPUT }, | 	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5), HID_QUIRK_MULTI_INPUT }, | ||||||
| 	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWA60), HID_QUIRK_MULTI_INPUT }, | 	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWA60), HID_QUIRK_MULTI_INPUT }, | ||||||
| 	{ HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER, USB_DEVICE_ID_UGTIZER_TABLET_WP5540), HID_QUIRK_MULTI_INPUT }, | 	{ HID_USB_DEVICE(USB_VENDOR_ID_UGTIZER, USB_DEVICE_ID_UGTIZER_TABLET_WP5540), HID_QUIRK_MULTI_INPUT }, | ||||||
|  | 	{ HID_USB_DEVICE(USB_VENDOR_ID_VRS, USB_DEVICE_ID_VRS_R295), HID_QUIRK_ALWAYS_POLL }, | ||||||
| 	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH), HID_QUIRK_MULTI_INPUT }, | 	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH), HID_QUIRK_MULTI_INPUT }, | ||||||
| 	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH), HID_QUIRK_MULTI_INPUT }, | 	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_14_1_INCH), HID_QUIRK_MULTI_INPUT }, | ||||||
| 	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET), HID_QUIRK_MULTI_INPUT }, | 	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SIRIUS_BATTERY_FREE_TABLET), HID_QUIRK_MULTI_INPUT }, | ||||||
|  |  | ||||||
|  | @ -466,7 +466,7 @@ static void quicki2c_dma_adv_enable(struct quicki2c_device *qcdev) | ||||||
| 			dev_warn(qcdev->dev, | 			dev_warn(qcdev->dev, | ||||||
| 				 "Max frame size is smaller than hid max input length!"); | 				 "Max frame size is smaller than hid max input length!"); | ||||||
| 			thc_i2c_set_rx_max_size(qcdev->thc_hw, | 			thc_i2c_set_rx_max_size(qcdev->thc_hw, | ||||||
| 						le16_to_cpu(qcdev->i2c_max_frame_size)); | 						qcdev->i2c_max_frame_size); | ||||||
| 		} | 		} | ||||||
| 		thc_i2c_rx_max_size_enable(qcdev->thc_hw, true); | 		thc_i2c_rx_max_size_enable(qcdev->thc_hw, true); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -33,6 +33,10 @@ struct quickspi_driver_data ptl = { | ||||||
| 	.max_packet_size_value = MAX_PACKET_SIZE_VALUE_LNL, | 	.max_packet_size_value = MAX_PACKET_SIZE_VALUE_LNL, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | struct quickspi_driver_data arl = { | ||||||
|  | 	.max_packet_size_value = MAX_PACKET_SIZE_VALUE_MTL, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| /* THC QuickSPI ACPI method to get device properties */ | /* THC QuickSPI ACPI method to get device properties */ | ||||||
| /* HIDSPI Method: {6e2ac436-0fcf-41af-a265-b32a220dcfab} */ | /* HIDSPI Method: {6e2ac436-0fcf-41af-a265-b32a220dcfab} */ | ||||||
| static guid_t hidspi_guid = | static guid_t hidspi_guid = | ||||||
|  | @ -978,6 +982,8 @@ static const struct pci_device_id quickspi_pci_tbl[] = { | ||||||
| 	{PCI_DEVICE_DATA(INTEL, THC_PTL_U_DEVICE_ID_SPI_PORT2, &ptl), }, | 	{PCI_DEVICE_DATA(INTEL, THC_PTL_U_DEVICE_ID_SPI_PORT2, &ptl), }, | ||||||
| 	{PCI_DEVICE_DATA(INTEL, THC_WCL_DEVICE_ID_SPI_PORT1, &ptl), }, | 	{PCI_DEVICE_DATA(INTEL, THC_WCL_DEVICE_ID_SPI_PORT1, &ptl), }, | ||||||
| 	{PCI_DEVICE_DATA(INTEL, THC_WCL_DEVICE_ID_SPI_PORT2, &ptl), }, | 	{PCI_DEVICE_DATA(INTEL, THC_WCL_DEVICE_ID_SPI_PORT2, &ptl), }, | ||||||
|  | 	{PCI_DEVICE_DATA(INTEL, THC_ARL_DEVICE_ID_SPI_PORT1, &arl), }, | ||||||
|  | 	{PCI_DEVICE_DATA(INTEL, THC_ARL_DEVICE_ID_SPI_PORT2, &arl), }, | ||||||
| 	{} | 	{} | ||||||
| }; | }; | ||||||
| MODULE_DEVICE_TABLE(pci, quickspi_pci_tbl); | MODULE_DEVICE_TABLE(pci, quickspi_pci_tbl); | ||||||
|  |  | ||||||
|  | @ -21,6 +21,8 @@ | ||||||
| #define PCI_DEVICE_ID_INTEL_THC_PTL_U_DEVICE_ID_SPI_PORT2	0xE44B | #define PCI_DEVICE_ID_INTEL_THC_PTL_U_DEVICE_ID_SPI_PORT2	0xE44B | ||||||
| #define PCI_DEVICE_ID_INTEL_THC_WCL_DEVICE_ID_SPI_PORT1 	0x4D49 | #define PCI_DEVICE_ID_INTEL_THC_WCL_DEVICE_ID_SPI_PORT1 	0x4D49 | ||||||
| #define PCI_DEVICE_ID_INTEL_THC_WCL_DEVICE_ID_SPI_PORT2 	0x4D4B | #define PCI_DEVICE_ID_INTEL_THC_WCL_DEVICE_ID_SPI_PORT2 	0x4D4B | ||||||
|  | #define PCI_DEVICE_ID_INTEL_THC_ARL_DEVICE_ID_SPI_PORT1 	0x7749 | ||||||
|  | #define PCI_DEVICE_ID_INTEL_THC_ARL_DEVICE_ID_SPI_PORT2 	0x774B | ||||||
| 
 | 
 | ||||||
| /* HIDSPI special ACPI parameters DSM methods */ | /* HIDSPI special ACPI parameters DSM methods */ | ||||||
| #define ACPI_QUICKSPI_REVISION_NUM			2 | #define ACPI_QUICKSPI_REVISION_NUM			2 | ||||||
|  |  | ||||||
|  | @ -280,8 +280,7 @@ int reset_tic(struct quickspi_device *qsdev) | ||||||
| 
 | 
 | ||||||
| 	qsdev->reset_ack = false; | 	qsdev->reset_ack = false; | ||||||
| 
 | 
 | ||||||
| 	/* First interrupt uses level trigger to avoid missing interrupt */ | 	thc_int_trigger_type_select(qsdev->thc_hw, true); | ||||||
| 	thc_int_trigger_type_select(qsdev->thc_hw, false); |  | ||||||
| 
 | 
 | ||||||
| 	ret = acpi_tic_reset(qsdev); | 	ret = acpi_tic_reset(qsdev); | ||||||
| 	if (ret) | 	if (ret) | ||||||
|  |  | ||||||
|  | @ -1292,4 +1292,15 @@ void hid_quirks_exit(__u16 bus); | ||||||
| #define hid_dbg_once(hid, fmt, ...)			\ | #define hid_dbg_once(hid, fmt, ...)			\ | ||||||
| 	dev_dbg_once(&(hid)->dev, fmt, ##__VA_ARGS__) | 	dev_dbg_once(&(hid)->dev, fmt, ##__VA_ARGS__) | ||||||
| 
 | 
 | ||||||
|  | #define hid_err_ratelimited(hid, fmt, ...)			\ | ||||||
|  | 	dev_err_ratelimited(&(hid)->dev, fmt, ##__VA_ARGS__) | ||||||
|  | #define hid_notice_ratelimited(hid, fmt, ...)			\ | ||||||
|  | 	dev_notice_ratelimited(&(hid)->dev, fmt, ##__VA_ARGS__) | ||||||
|  | #define hid_warn_ratelimited(hid, fmt, ...)			\ | ||||||
|  | 	dev_warn_ratelimited(&(hid)->dev, fmt, ##__VA_ARGS__) | ||||||
|  | #define hid_info_ratelimited(hid, fmt, ...)			\ | ||||||
|  | 	dev_info_ratelimited(&(hid)->dev, fmt, ##__VA_ARGS__) | ||||||
|  | #define hid_dbg_ratelimited(hid, fmt, ...)			\ | ||||||
|  | 	dev_dbg_ratelimited(&(hid)->dev, fmt, ##__VA_ARGS__) | ||||||
|  | 
 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -1752,6 +1752,52 @@ class TestWin8TSConfidence(BaseTest.TestWin8Multitouch): | ||||||
|         assert evdev.slots[0][libevdev.EV_ABS.ABS_MT_TRACKING_ID] == -1 |         assert evdev.slots[0][libevdev.EV_ABS.ABS_MT_TRACKING_ID] == -1 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |     @pytest.mark.skip_if_uhdev( | ||||||
|  |         lambda uhdev: "Confidence" not in uhdev.fields, | ||||||
|  |         "Device not compatible, missing Confidence usage", | ||||||
|  |     ) | ||||||
|  |     def test_mt_confidence_bad_multi_release(self): | ||||||
|  |         """Check for the sticky finger being properly detected. | ||||||
|  | 
 | ||||||
|  |         We first inject 3 fingers, then release only the second. | ||||||
|  |         After 100 ms, we should receive a generated event about the | ||||||
|  |         2 missing fingers being released. | ||||||
|  |         """ | ||||||
|  |         uhdev = self.uhdev | ||||||
|  |         evdev = uhdev.get_evdev() | ||||||
|  | 
 | ||||||
|  |         # send 3 touches | ||||||
|  |         t0 = Touch(1, 50, 10) | ||||||
|  |         t1 = Touch(2, 150, 100) | ||||||
|  |         t2 = Touch(3, 250, 200) | ||||||
|  |         r = uhdev.event([t0, t1, t2]) | ||||||
|  |         events = uhdev.next_sync_events() | ||||||
|  |         self.debug_reports(r, uhdev, events) | ||||||
|  | 
 | ||||||
|  |         # release the second | ||||||
|  |         t1.tipswitch = False | ||||||
|  |         r = uhdev.event([t1]) | ||||||
|  |         events = uhdev.next_sync_events() | ||||||
|  |         self.debug_reports(r, uhdev, events) | ||||||
|  | 
 | ||||||
|  |         # only the second is released | ||||||
|  |         assert evdev.slots[0][libevdev.EV_ABS.ABS_MT_TRACKING_ID] != -1 | ||||||
|  |         assert evdev.slots[1][libevdev.EV_ABS.ABS_MT_TRACKING_ID] == -1 | ||||||
|  |         assert evdev.slots[2][libevdev.EV_ABS.ABS_MT_TRACKING_ID] != -1 | ||||||
|  | 
 | ||||||
|  |         # wait for the timer to kick in | ||||||
|  |         time.sleep(0.2) | ||||||
|  | 
 | ||||||
|  |         events = uhdev.next_sync_events() | ||||||
|  |         self.debug_reports([], uhdev, events) | ||||||
|  | 
 | ||||||
|  |         # now all 3 fingers are released | ||||||
|  |         assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH, 0) in events | ||||||
|  |         assert evdev.slots[0][libevdev.EV_ABS.ABS_MT_TRACKING_ID] == -1 | ||||||
|  |         assert evdev.slots[1][libevdev.EV_ABS.ABS_MT_TRACKING_ID] == -1 | ||||||
|  |         assert evdev.slots[2][libevdev.EV_ABS.ABS_MT_TRACKING_ID] == -1 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| class TestElanXPS9360(BaseTest.TestWin8Multitouch): | class TestElanXPS9360(BaseTest.TestWin8Multitouch): | ||||||
|     def create_device(self): |     def create_device(self): | ||||||
|         return Digitizer( |         return Digitizer( | ||||||
|  | @ -2086,3 +2132,12 @@ class Testsynaptics_06cb_ce08(BaseTest.TestPTP): | ||||||
|             input_info=(BusType.I2C, 0x06CB, 0xCE08), |             input_info=(BusType.I2C, 0x06CB, 0xCE08), | ||||||
|             rdesc="05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 75 01 95 02 81 02 95 06 81 01 05 01 09 30 09 31 15 81 25 7f 75 08 95 02 81 06 c0 c0 05 01 09 02 a1 01 85 18 09 01 a1 00 05 09 19 01 29 03 46 00 00 15 00 25 01 75 01 95 03 81 02 95 05 81 01 05 01 09 30 09 31 15 81 25 7f 75 08 95 02 81 06 c0 c0 06 00 ff 09 02 a1 01 85 20 09 01 a1 00 09 03 15 00 26 ff 00 35 00 46 ff 00 75 08 95 05 81 02 c0 c0 05 0d 09 05 a1 01 85 03 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 f8 04 75 10 55 0e 65 11 09 30 35 00 46 24 04 95 01 81 02 46 30 02 26 a0 02 09 31 81 02 c0 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 f8 04 75 10 55 0e 65 11 09 30 35 00 46 24 04 95 01 81 02 46 30 02 26 a0 02 09 31 81 02 c0 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 f8 04 75 10 55 0e 65 11 09 30 35 00 46 24 04 95 01 81 02 46 30 02 26 a0 02 09 31 81 02 c0 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 f8 04 75 10 55 0e 65 11 09 30 35 00 46 24 04 95 01 81 02 46 30 02 26 a0 02 09 31 81 02 c0 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 f8 04 75 10 55 0e 65 11 09 30 35 00 46 24 04 95 01 81 02 46 30 02 26 a0 02 09 31 81 02 c0 05 0d 55 0c 66 01 10 47 ff ff 00 00 27 ff ff 00 00 75 10 95 01 09 56 81 02 09 54 25 7f 95 01 75 08 81 02 05 09 09 01 25 01 75 01 95 01 81 02 95 07 81 03 05 0d 85 08 09 55 09 59 75 04 95 02 25 0f b1 02 85 0d 09 60 75 01 95 01 15 00 25 01 b1 02 95 07 b1 03 85 07 06 00 ff 09 c5 15 00 26 ff 00 75 08 96 00 01 b1 02 c0 05 0d 09 0e a1 01 85 04 09 22 a1 02 09 52 15 00 25 0a 75 08 95 01 b1 02 c0 09 22 a1 00 85 06 09 57 09 58 75 01 95 02 25 01 b1 02 95 06 b1 03 c0 c0 06 00 ff 09 01 a1 01 85 09 09 02 15 00 26 ff 00 75 08 95 14 91 02 85 0a 09 03 15 00 26 ff 00 75 08 95 14 91 02 85 0b 09 04 15 00 26 ff 00 75 08 95 45 81 02 85 0c 09 05 15 00 26 ff 00 75 08 95 45 81 02 85 0f 09 06 15 00 26 ff 00 75 08 95 03 b1 02 85 0e 09 07 15 00 26 ff 00 75 08 95 01 b1 02 c0", |             rdesc="05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 75 01 95 02 81 02 95 06 81 01 05 01 09 30 09 31 15 81 25 7f 75 08 95 02 81 06 c0 c0 05 01 09 02 a1 01 85 18 09 01 a1 00 05 09 19 01 29 03 46 00 00 15 00 25 01 75 01 95 03 81 02 95 05 81 01 05 01 09 30 09 31 15 81 25 7f 75 08 95 02 81 06 c0 c0 06 00 ff 09 02 a1 01 85 20 09 01 a1 00 09 03 15 00 26 ff 00 35 00 46 ff 00 75 08 95 05 81 02 c0 c0 05 0d 09 05 a1 01 85 03 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 f8 04 75 10 55 0e 65 11 09 30 35 00 46 24 04 95 01 81 02 46 30 02 26 a0 02 09 31 81 02 c0 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 f8 04 75 10 55 0e 65 11 09 30 35 00 46 24 04 95 01 81 02 46 30 02 26 a0 02 09 31 81 02 c0 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 f8 04 75 10 55 0e 65 11 09 30 35 00 46 24 04 95 01 81 02 46 30 02 26 a0 02 09 31 81 02 c0 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 f8 04 75 10 55 0e 65 11 09 30 35 00 46 24 04 95 01 81 02 46 30 02 26 a0 02 09 31 81 02 c0 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 f8 04 75 10 55 0e 65 11 09 30 35 00 46 24 04 95 01 81 02 46 30 02 26 a0 02 09 31 81 02 c0 05 0d 55 0c 66 01 10 47 ff ff 00 00 27 ff ff 00 00 75 10 95 01 09 56 81 02 09 54 25 7f 95 01 75 08 81 02 05 09 09 01 25 01 75 01 95 01 81 02 95 07 81 03 05 0d 85 08 09 55 09 59 75 04 95 02 25 0f b1 02 85 0d 09 60 75 01 95 01 15 00 25 01 b1 02 95 07 b1 03 85 07 06 00 ff 09 c5 15 00 26 ff 00 75 08 96 00 01 b1 02 c0 05 0d 09 0e a1 01 85 04 09 22 a1 02 09 52 15 00 25 0a 75 08 95 01 b1 02 c0 09 22 a1 00 85 06 09 57 09 58 75 01 95 02 25 01 b1 02 95 06 b1 03 c0 c0 06 00 ff 09 01 a1 01 85 09 09 02 15 00 26 ff 00 75 08 95 14 91 02 85 0a 09 03 15 00 26 ff 00 75 08 95 14 91 02 85 0b 09 04 15 00 26 ff 00 75 08 95 45 81 02 85 0c 09 05 15 00 26 ff 00 75 08 95 45 81 02 85 0f 09 06 15 00 26 ff 00 75 08 95 03 b1 02 85 0e 09 07 15 00 26 ff 00 75 08 95 01 b1 02 c0", | ||||||
|         ) |         ) | ||||||
|  | 
 | ||||||
|  | class Testsynaptics_06cb_ce26(TestWin8TSConfidence): | ||||||
|  |     def create_device(self): | ||||||
|  |         return PTP( | ||||||
|  |             "uhid test synaptics_06cb_ce26", | ||||||
|  |             max_contacts=5, | ||||||
|  |             input_info=(BusType.I2C, 0x06CB, 0xCE26), | ||||||
|  |             rdesc="05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 75 01 95 02 81 02 95 06 81 01 05 01 09 30 09 31 15 81 25 7f 75 08 95 02 81 06 c0 c0 05 0d 09 05 a1 01 85 03 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 45 05 75 10 55 0e 65 11 09 30 35 00 46 64 04 95 01 81 02 46 a2 02 26 29 03 09 31 81 02 c0 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 45 05 75 10 55 0e 65 11 09 30 35 00 46 64 04 95 01 81 02 46 a2 02 26 29 03 09 31 81 02 c0 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 45 05 75 10 55 0e 65 11 09 30 35 00 46 64 04 95 01 81 02 46 a2 02 26 29 03 09 31 81 02 c0 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 45 05 75 10 55 0e 65 11 09 30 35 00 46 64 04 95 01 81 02 46 a2 02 26 29 03 09 31 81 02 c0 05 0d 09 22 a1 02 15 00 25 01 09 47 09 42 95 02 75 01 81 02 95 01 75 03 25 05 09 51 81 02 75 01 95 03 81 03 05 01 15 00 26 45 05 75 10 55 0e 65 11 09 30 35 00 46 64 04 95 01 81 02 46 a2 02 26 29 03 09 31 81 02 c0 05 0d 55 0c 66 01 10 47 ff ff 00 00 27 ff ff 00 00 75 10 95 01 09 56 81 02 09 54 25 7f 95 01 75 08 81 02 05 09 09 01 25 01 75 01 95 01 81 02 95 07 81 03 05 0d 85 08 09 55 09 59 75 04 95 02 25 0f b1 02 85 0d 09 60 75 01 95 01 15 00 25 01 b1 02 95 07 b1 03 85 07 06 00 ff 09 c5 15 00 26 ff 00 75 08 96 00 01 b1 02 c0 05 0d 09 0e a1 01 85 04 09 22 a1 02 09 52 15 00 25 0a 75 08 95 01 b1 02 c0 09 22 a1 00 85 06 09 57 09 58 75 01 95 02 25 01 b1 02 95 06 b1 03 c0 c0 06 00 ff 09 01 a1 01 85 09 09 02 15 00 26 ff 00 75 08 95 14 91 02 85 0a 09 03 15 00 26 ff 00 75 08 95 14 91 02 85 0b 09 04 15 00 26 ff 00 75 08 95 3d 81 02 85 0c 09 05 15 00 26 ff 00 75 08 95 3d 81 02 85 0f 09 06 15 00 26 ff 00 75 08 95 03 b1 02 85 0e 09 07 15 00 26 ff 00 75 08 95 01 b1 02 c0", | ||||||
|  |         ) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Linus Torvalds
						Linus Torvalds