mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 08:38:45 +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. | ||||
| 
 | ||||
| config HID_HAPTIC | ||||
| 	tristate "Haptic touchpad support" | ||||
| 	bool "Haptic touchpad support" | ||||
| 	default n | ||||
| 	help | ||||
| 	Support for touchpads with force sensors and haptic actuators instead of a | ||||
|  |  | |||
|  | @ -689,7 +689,14 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr, | |||
| 			count = cp2112_write_read_req(buf, addr, read_length, | ||||
| 						      command, NULL, 0); | ||||
| 		} else { | ||||
| 			count = cp2112_write_req(buf, addr, command, | ||||
| 			/* 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, | ||||
| 						 data->block + 1, | ||||
| 						 data->block[0]); | ||||
| 		} | ||||
|  | @ -700,7 +707,14 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr, | |||
| 						      I2C_SMBUS_BLOCK_MAX, | ||||
| 						      command, NULL, 0); | ||||
| 		} else { | ||||
| 			count = cp2112_write_req(buf, addr, command, | ||||
| 			/* 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, | ||||
| 						 data->block, | ||||
| 						 data->block[0] + 1); | ||||
| 		} | ||||
|  | @ -709,7 +723,14 @@ static int cp2112_xfer(struct i2c_adapter *adap, u16 addr, | |||
| 		size = I2C_SMBUS_BLOCK_DATA; | ||||
| 		read_write = I2C_SMBUS_READ; | ||||
| 
 | ||||
| 		count = cp2112_write_read_req(buf, addr, I2C_SMBUS_BLOCK_MAX, | ||||
| 		/* 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, | ||||
| 					      command, data->block, | ||||
| 					      data->block[0] + 1); | ||||
| 		break; | ||||
|  |  | |||
|  | @ -2523,7 +2523,7 @@ static const struct hid_usage_entry hid_usage_table[] = { | |||
| 		{ 0x85, 0x0088, "iDeviceName" }, | ||||
| 		{ 0x85, 0x0089, "iDeviceChemistry" }, | ||||
| 		{ 0x85, 0x008a, "ManufacturerData" }, | ||||
| 		{ 0x85, 0x008b, "Rechargable" }, | ||||
| 		{ 0x85, 0x008b, "Rechargeable" }, | ||||
| 		{ 0x85, 0x008c, "WarningCapacityLimit" }, | ||||
| 		{ 0x85, 0x008d, "CapacityGranularity1" }, | ||||
| 		{ 0x85, 0x008e, "CapacityGranularity2" }, | ||||
|  |  | |||
|  | @ -342,6 +342,9 @@ | |||
| #define USB_DEVICE_ID_CODEMERCS_IOW_FIRST	0x1500 | ||||
| #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_DEVICE_ID_CORSAIR_K90	0x1b02 | ||||
| #define USB_DEVICE_ID_CORSAIR_K70R      0x1b09 | ||||
|  | @ -1432,6 +1435,7 @@ | |||
| 
 | ||||
| #define USB_VENDOR_ID_VRS	0x0483 | ||||
| #define USB_DEVICE_ID_VRS_DFP	0xa355 | ||||
| #define USB_DEVICE_ID_VRS_R295	0xa44c | ||||
| 
 | ||||
| #define USB_VENDOR_ID_VTL		0x0306 | ||||
| #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; | ||||
| 	} | ||||
| 
 | ||||
| 	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; | ||||
| 
 | ||||
| 	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_HI_RES_SCROLL_1P0		BIT(28) | ||||
| #define HIDPP_QUIRK_WIRELESS_STATUS		BIT(29) | ||||
| #define HIDPP_QUIRK_RESET_HI_RES_SCROLL		BIT(30) | ||||
| 
 | ||||
| /* These are just aliases for now */ | ||||
| #define HIDPP_QUIRK_KBD_SCROLL_WHEEL HIDPP_QUIRK_HIDPP_WHEELS | ||||
|  | @ -193,6 +194,7 @@ struct hidpp_device { | |||
| 	void *private_data; | ||||
| 
 | ||||
| 	struct work_struct work; | ||||
| 	struct work_struct reset_hi_res_work; | ||||
| 	struct kfifo delayed_work_fifo; | ||||
| 	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 *report = (struct hidpp_report *)data; | ||||
| 	int ret; | ||||
| 	int last_online; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * 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"); | ||||
| 	} | ||||
| 
 | ||||
| 	last_online = hidpp->battery.online; | ||||
| 	if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_BATTERY) { | ||||
| 		ret = hidpp20_battery_event_1000(hidpp, data, size); | ||||
| 		if (ret != 0) | ||||
|  | @ -3901,6 +3905,11 @@ static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data, | |||
| 			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) { | ||||
| 		ret = hidpp10_wheel_raw_event(hidpp, data, size); | ||||
| 		if (ret != 0) | ||||
|  | @ -4274,6 +4283,13 @@ static void hidpp_connect_event(struct work_struct *work) | |||
| 	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 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->reset_hi_res_work, hidpp_reset_hi_res_handler); | ||||
| 	mutex_init(&hidpp->send_mutex); | ||||
| 	init_waitqueue_head(&hidpp->wait); | ||||
| 
 | ||||
|  | @ -4499,6 +4516,7 @@ static void hidpp_remove(struct hid_device *hdev) | |||
| 
 | ||||
| 	hid_hw_stop(hdev); | ||||
| 	cancel_work_sync(&hidpp->work); | ||||
| 	cancel_work_sync(&hidpp->reset_hi_res_work); | ||||
| 	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) */ | ||||
| 	  LDJ_DEVICE(0xb30b), | ||||
| 	  .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) }, | ||||
| 
 | ||||
|  |  | |||
|  | @ -94,9 +94,8 @@ enum report_mode { | |||
| 	TOUCHPAD_REPORT_ALL = TOUCHPAD_REPORT_BUTTONS | TOUCHPAD_REPORT_CONTACTS, | ||||
| }; | ||||
| 
 | ||||
| #define MT_IO_FLAGS_RUNNING		0 | ||||
| #define MT_IO_FLAGS_ACTIVE_SLOTS	1 | ||||
| #define MT_IO_FLAGS_PENDING_SLOTS	2 | ||||
| #define MT_IO_SLOTS_MASK		GENMASK(7, 0) /* reserve first 8 bits for slot tracking */ | ||||
| #define MT_IO_FLAGS_RUNNING		32 | ||||
| 
 | ||||
| static const bool mtrue = true;		/* default for true */ | ||||
| static const bool mfalse;		/* default for false */ | ||||
|  | @ -172,7 +171,11 @@ struct mt_device { | |||
| 	struct timer_list release_timer;	/* to release sticky fingers */ | ||||
| 	struct hid_haptic_device *haptic;	/* haptic related configuration */ | ||||
| 	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 maxcontacts; | ||||
| 	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) { | ||||
| 		clear_bit(slotnum, app->pending_palm_slots); | ||||
| 		clear_bit(slotnum, &td->mt_io_flags); | ||||
| 
 | ||||
| 		input_mt_slot(input, slotnum); | ||||
| 		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; | ||||
| 	if (td->is_haptic_touchpad) | ||||
| 		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) | ||||
|  | @ -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_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; | ||||
|  | @ -1337,7 +1337,7 @@ static void mt_touch_report(struct hid_device *hid, | |||
| 	 * defect. | ||||
| 	 */ | ||||
| 	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, | ||||
| 				  jiffies + msecs_to_jiffies(100)); | ||||
| 		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_GD_WIRELESS_RADIO_CTLS: | ||||
| 	case HID_GD_SYSTEM_MULTIAXIS: | ||||
| 	case HID_DG_PEN: | ||||
| 		/* already handled by hid core */ | ||||
| 		break; | ||||
| 	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++) { | ||||
| 				input_mt_slot(input_dev, i); | ||||
| 				input_mt_report_slot_inactive(input_dev); | ||||
| 				clear_bit(i, &td->mt_io_flags); | ||||
| 			} | ||||
| 			input_mt_sync_frame(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)) | ||||
| 		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); | ||||
| 	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_timestamp_us += 1000 * ctlr->imu_avg_delta_ms; | ||||
| 		if (dropped_pkts > JC_IMU_DROPPED_PKT_WARNING) { | ||||
| 			hid_warn(ctlr->hdev, | ||||
| 			hid_warn_ratelimited(ctlr->hdev, | ||||
| 				 "compensating for %u dropped IMU reports\n", | ||||
| 				 dropped_pkts); | ||||
| 			hid_warn(ctlr->hdev, | ||||
| 			hid_warn_ratelimited(ctlr->hdev, | ||||
| 				 "delta=%u avg_delta=%u\n", | ||||
| 				 delta, ctlr->imu_avg_delta_ms); | ||||
| 		} | ||||
|  | @ -2420,7 +2420,7 @@ static int joycon_read_info(struct joycon_ctlr *ctlr) | |||
| 	struct joycon_input_report *report; | ||||
| 
 | ||||
| 	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) { | ||||
| 		hid_err(ctlr->hdev, "Failed to get joycon info; ret=%d\n", 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_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_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_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 }, | ||||
|  | @ -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_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_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_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 }, | ||||
|  |  | |||
|  | @ -466,7 +466,7 @@ static void quicki2c_dma_adv_enable(struct quicki2c_device *qcdev) | |||
| 			dev_warn(qcdev->dev, | ||||
| 				 "Max frame size is smaller than hid max input length!"); | ||||
| 			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); | ||||
| 	} | ||||
|  |  | |||
|  | @ -33,6 +33,10 @@ struct quickspi_driver_data ptl = { | |||
| 	.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 */ | ||||
| /* HIDSPI Method: {6e2ac436-0fcf-41af-a265-b32a220dcfab} */ | ||||
| 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_WCL_DEVICE_ID_SPI_PORT1, &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); | ||||
|  |  | |||
|  | @ -21,6 +21,8 @@ | |||
| #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_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 */ | ||||
| #define ACPI_QUICKSPI_REVISION_NUM			2 | ||||
|  |  | |||
|  | @ -280,8 +280,7 @@ int reset_tic(struct quickspi_device *qsdev) | |||
| 
 | ||||
| 	qsdev->reset_ack = false; | ||||
| 
 | ||||
| 	/* First interrupt uses level trigger to avoid missing interrupt */ | ||||
| 	thc_int_trigger_type_select(qsdev->thc_hw, false); | ||||
| 	thc_int_trigger_type_select(qsdev->thc_hw, true); | ||||
| 
 | ||||
| 	ret = acpi_tic_reset(qsdev); | ||||
| 	if (ret) | ||||
|  |  | |||
|  | @ -1292,4 +1292,15 @@ void hid_quirks_exit(__u16 bus); | |||
| #define hid_dbg_once(hid, fmt, ...)			\ | ||||
| 	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 | ||||
|  |  | |||
|  | @ -1752,6 +1752,52 @@ class TestWin8TSConfidence(BaseTest.TestWin8Multitouch): | |||
|         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): | ||||
|     def create_device(self): | ||||
|         return Digitizer( | ||||
|  | @ -2086,3 +2132,12 @@ class Testsynaptics_06cb_ce08(BaseTest.TestPTP): | |||
|             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", | ||||
|         ) | ||||
| 
 | ||||
| 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