diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/hid/hid-logitech-hidpp.c | 21 | 
1 files changed, 21 insertions, 0 deletions
| diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index aaef405a717e..5e763de4b94f 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -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) }, | 
