Skip to content

Commit 9459630

Browse files
author
Jiri Kosina
committed
Merge branch 'for-6.9/lenovo' into for-linus
- 2nd version of code for applying proper quirk depending on firmware version for lenovo/cptkbd (Mikhail Khvainitski)
2 parents 2e21dee + 2814646 commit 9459630

File tree

1 file changed

+39
-18
lines changed

1 file changed

+39
-18
lines changed

drivers/hid/hid-lenovo.c

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ struct lenovo_drvdata {
5454
/* 0: Up
5555
* 1: Down (undecided)
5656
* 2: Scrolling
57-
* 3: Patched firmware, disable workaround
5857
*/
5958
u8 middlebutton_state;
6059
bool fn_lock;
60+
bool middleclick_workaround_cptkbd;
6161
};
6262

6363
#define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
@@ -621,6 +621,36 @@ static ssize_t attr_sensitivity_store_cptkbd(struct device *dev,
621621
return count;
622622
}
623623

624+
static ssize_t attr_middleclick_workaround_show_cptkbd(struct device *dev,
625+
struct device_attribute *attr,
626+
char *buf)
627+
{
628+
struct hid_device *hdev = to_hid_device(dev);
629+
struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev);
630+
631+
return snprintf(buf, PAGE_SIZE, "%u\n",
632+
cptkbd_data->middleclick_workaround_cptkbd);
633+
}
634+
635+
static ssize_t attr_middleclick_workaround_store_cptkbd(struct device *dev,
636+
struct device_attribute *attr,
637+
const char *buf,
638+
size_t count)
639+
{
640+
struct hid_device *hdev = to_hid_device(dev);
641+
struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev);
642+
int value;
643+
644+
if (kstrtoint(buf, 10, &value))
645+
return -EINVAL;
646+
if (value < 0 || value > 1)
647+
return -EINVAL;
648+
649+
cptkbd_data->middleclick_workaround_cptkbd = !!value;
650+
651+
return count;
652+
}
653+
624654

625655
static struct device_attribute dev_attr_fn_lock =
626656
__ATTR(fn_lock, S_IWUSR | S_IRUGO,
@@ -632,10 +662,16 @@ static struct device_attribute dev_attr_sensitivity_cptkbd =
632662
attr_sensitivity_show_cptkbd,
633663
attr_sensitivity_store_cptkbd);
634664

665+
static struct device_attribute dev_attr_middleclick_workaround_cptkbd =
666+
__ATTR(middleclick_workaround, S_IWUSR | S_IRUGO,
667+
attr_middleclick_workaround_show_cptkbd,
668+
attr_middleclick_workaround_store_cptkbd);
669+
635670

636671
static struct attribute *lenovo_attributes_cptkbd[] = {
637672
&dev_attr_fn_lock.attr,
638673
&dev_attr_sensitivity_cptkbd.attr,
674+
&dev_attr_middleclick_workaround_cptkbd.attr,
639675
NULL
640676
};
641677

@@ -686,23 +722,7 @@ static int lenovo_event_cptkbd(struct hid_device *hdev,
686722
{
687723
struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev);
688724

689-
if (cptkbd_data->middlebutton_state != 3) {
690-
/* REL_X and REL_Y events during middle button pressed
691-
* are only possible on patched, bug-free firmware
692-
* so set middlebutton_state to 3
693-
* to never apply workaround anymore
694-
*/
695-
if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD &&
696-
cptkbd_data->middlebutton_state == 1 &&
697-
usage->type == EV_REL &&
698-
(usage->code == REL_X || usage->code == REL_Y)) {
699-
cptkbd_data->middlebutton_state = 3;
700-
/* send middle button press which was hold before */
701-
input_event(field->hidinput->input,
702-
EV_KEY, BTN_MIDDLE, 1);
703-
input_sync(field->hidinput->input);
704-
}
705-
725+
if (cptkbd_data->middleclick_workaround_cptkbd) {
706726
/* "wheel" scroll events */
707727
if (usage->type == EV_REL && (usage->code == REL_WHEEL ||
708728
usage->code == REL_HWHEEL)) {
@@ -1166,6 +1186,7 @@ static int lenovo_probe_cptkbd(struct hid_device *hdev)
11661186
cptkbd_data->middlebutton_state = 0;
11671187
cptkbd_data->fn_lock = true;
11681188
cptkbd_data->sensitivity = 0x05;
1189+
cptkbd_data->middleclick_workaround_cptkbd = true;
11691190
lenovo_features_set_cptkbd(hdev);
11701191

11711192
ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd);

0 commit comments

Comments
 (0)