Merge branch 'for-6.9/lenovo' into for-linus
[linux-2.6-microblaze.git] / drivers / hid / hid-lenovo.c
index 149a3c7..f86c1ea 100644 (file)
@@ -54,10 +54,10 @@ struct lenovo_drvdata {
        /* 0: Up
         * 1: Down (undecided)
         * 2: Scrolling
-        * 3: Patched firmware, disable workaround
         */
        u8 middlebutton_state;
        bool fn_lock;
+       bool middleclick_workaround_cptkbd;
 };
 
 #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,
        return count;
 }
 
+static ssize_t attr_middleclick_workaround_show_cptkbd(struct device *dev,
+               struct device_attribute *attr,
+               char *buf)
+{
+       struct hid_device *hdev = to_hid_device(dev);
+       struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev);
+
+       return snprintf(buf, PAGE_SIZE, "%u\n",
+               cptkbd_data->middleclick_workaround_cptkbd);
+}
+
+static ssize_t attr_middleclick_workaround_store_cptkbd(struct device *dev,
+               struct device_attribute *attr,
+               const char *buf,
+               size_t count)
+{
+       struct hid_device *hdev = to_hid_device(dev);
+       struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev);
+       int value;
+
+       if (kstrtoint(buf, 10, &value))
+               return -EINVAL;
+       if (value < 0 || value > 1)
+               return -EINVAL;
+
+       cptkbd_data->middleclick_workaround_cptkbd = !!value;
+
+       return count;
+}
+
 
 static struct device_attribute dev_attr_fn_lock =
        __ATTR(fn_lock, S_IWUSR | S_IRUGO,
@@ -632,10 +662,16 @@ static struct device_attribute dev_attr_sensitivity_cptkbd =
                        attr_sensitivity_show_cptkbd,
                        attr_sensitivity_store_cptkbd);
 
+static struct device_attribute dev_attr_middleclick_workaround_cptkbd =
+       __ATTR(middleclick_workaround, S_IWUSR | S_IRUGO,
+                       attr_middleclick_workaround_show_cptkbd,
+                       attr_middleclick_workaround_store_cptkbd);
+
 
 static struct attribute *lenovo_attributes_cptkbd[] = {
        &dev_attr_fn_lock.attr,
        &dev_attr_sensitivity_cptkbd.attr,
+       &dev_attr_middleclick_workaround_cptkbd.attr,
        NULL
 };
 
@@ -686,23 +722,7 @@ static int lenovo_event_cptkbd(struct hid_device *hdev,
 {
        struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev);
 
-       if (cptkbd_data->middlebutton_state != 3) {
-               /* REL_X and REL_Y events during middle button pressed
-                * are only possible on patched, bug-free firmware
-                * so set middlebutton_state to 3
-                * to never apply workaround anymore
-                */
-               if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD &&
-                               cptkbd_data->middlebutton_state == 1 &&
-                               usage->type == EV_REL &&
-                               (usage->code == REL_X || usage->code == REL_Y)) {
-                       cptkbd_data->middlebutton_state = 3;
-                       /* send middle button press which was hold before */
-                       input_event(field->hidinput->input,
-                               EV_KEY, BTN_MIDDLE, 1);
-                       input_sync(field->hidinput->input);
-               }
-
+       if (cptkbd_data->middleclick_workaround_cptkbd) {
                /* "wheel" scroll events */
                if (usage->type == EV_REL && (usage->code == REL_WHEEL ||
                                usage->code == REL_HWHEEL)) {
@@ -1166,6 +1186,7 @@ static int lenovo_probe_cptkbd(struct hid_device *hdev)
        cptkbd_data->middlebutton_state = 0;
        cptkbd_data->fn_lock = true;
        cptkbd_data->sensitivity = 0x05;
+       cptkbd_data->middleclick_workaround_cptkbd = true;
        lenovo_features_set_cptkbd(hdev);
 
        ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd);