Skip to content

Commit ed80cc4

Browse files
stuarthayhurstJiri Kosina
authored andcommitted
HID: logitech-hidpp: Add HIDPP_QUIRK_RESET_HI_RES_SCROLL
The Logitech G502 Hero Wireless's high resolution scrolling resets after being unplugged without notifying the driver, causing extremely slow scrolling. The only indication of this is a battery update packet, so add a quirk to detect when the device is unplugged and re-enable the scrolling. Link: https://bugzilla.kernel.org/show_bug.cgi?id=218037 Signed-off-by: Stuart Hayhurst <stuart.a.hayhurst@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.com>
1 parent d9b3014 commit ed80cc4

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

drivers/hid/hid-logitech-hidpp.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ MODULE_PARM_DESC(disable_tap_to_click,
7575
#define HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS BIT(27)
7676
#define HIDPP_QUIRK_HI_RES_SCROLL_1P0 BIT(28)
7777
#define HIDPP_QUIRK_WIRELESS_STATUS BIT(29)
78+
#define HIDPP_QUIRK_RESET_HI_RES_SCROLL BIT(30)
7879

7980
/* These are just aliases for now */
8081
#define HIDPP_QUIRK_KBD_SCROLL_WHEEL HIDPP_QUIRK_HIDPP_WHEELS
@@ -193,6 +194,7 @@ struct hidpp_device {
193194
void *private_data;
194195

195196
struct work_struct work;
197+
struct work_struct reset_hi_res_work;
196198
struct kfifo delayed_work_fifo;
197199
struct input_dev *delayed_input;
198200

@@ -3836,6 +3838,7 @@ static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data,
38363838
struct hidpp_report *answer = hidpp->send_receive_buf;
38373839
struct hidpp_report *report = (struct hidpp_report *)data;
38383840
int ret;
3841+
int last_online;
38393842

38403843
/*
38413844
* 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,
38773880
"See: https://gitlab.freedesktop.org/jwrdegoede/logitech-27mhz-keyboard-encryption-setup/\n");
38783881
}
38793882

3883+
last_online = hidpp->battery.online;
38803884
if (hidpp->capabilities & HIDPP_CAPABILITY_HIDPP20_BATTERY) {
38813885
ret = hidpp20_battery_event_1000(hidpp, data, size);
38823886
if (ret != 0)
@@ -3901,6 +3905,11 @@ static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data,
39013905
return ret;
39023906
}
39033907

3908+
if (hidpp->quirks & HIDPP_QUIRK_RESET_HI_RES_SCROLL) {
3909+
if (last_online == 0 && hidpp->battery.online == 1)
3910+
schedule_work(&hidpp->reset_hi_res_work);
3911+
}
3912+
39043913
if (hidpp->quirks & HIDPP_QUIRK_HIDPP_WHEELS) {
39053914
ret = hidpp10_wheel_raw_event(hidpp, data, size);
39063915
if (ret != 0)
@@ -4274,6 +4283,13 @@ static void hidpp_connect_event(struct work_struct *work)
42744283
hidpp->delayed_input = input;
42754284
}
42764285

4286+
static void hidpp_reset_hi_res_handler(struct work_struct *work)
4287+
{
4288+
struct hidpp_device *hidpp = container_of(work, struct hidpp_device, reset_hi_res_work);
4289+
4290+
hi_res_scroll_enable(hidpp);
4291+
}
4292+
42774293
static DEVICE_ATTR(builtin_power_supply, 0000, NULL, NULL);
42784294

42794295
static struct attribute *sysfs_attrs[] = {
@@ -4404,6 +4420,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
44044420
}
44054421

44064422
INIT_WORK(&hidpp->work, hidpp_connect_event);
4423+
INIT_WORK(&hidpp->reset_hi_res_work, hidpp_reset_hi_res_handler);
44074424
mutex_init(&hidpp->send_mutex);
44084425
init_waitqueue_head(&hidpp->wait);
44094426

@@ -4499,6 +4516,7 @@ static void hidpp_remove(struct hid_device *hdev)
44994516

45004517
hid_hw_stop(hdev);
45014518
cancel_work_sync(&hidpp->work);
4519+
cancel_work_sync(&hidpp->reset_hi_res_work);
45024520
mutex_destroy(&hidpp->send_mutex);
45034521
}
45044522

@@ -4546,6 +4564,9 @@ static const struct hid_device_id hidpp_devices[] = {
45464564
{ /* Keyboard MX5500 (Bluetooth-receiver in HID proxy mode) */
45474565
LDJ_DEVICE(0xb30b),
45484566
.driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
4567+
{ /* Logitech G502 Lightspeed Wireless Gaming Mouse */
4568+
LDJ_DEVICE(0x407f),
4569+
.driver_data = HIDPP_QUIRK_RESET_HI_RES_SCROLL },
45494570

45504571
{ LDJ_DEVICE(HID_ANY_ID) },
45514572

0 commit comments

Comments
 (0)