[PATCH 5.10 127/238] HID: lenovo: Add middleclick_workaround sysfs knob for cptkbd

Sasha Levin posted 238 patches 1 year, 8 months ago
[PATCH 5.10 127/238] HID: lenovo: Add middleclick_workaround sysfs knob for cptkbd
Posted by Sasha Levin 1 year, 8 months ago
From: Mikhail Khvainitski <me@khvoinitsky.org>

[ Upstream commit 2814646f76f8518326964f12ff20aaee70ba154d ]

Previous attempt to autodetect well-behaving patched firmware
introduced in commit 46a0a2c96f0f ("HID: lenovo: Detect quirk-free fw
on cptkbd and stop applying workaround") has shown that there are
false-positives on original firmware (on both 1st gen and 2nd gen
keyboards) which causes the middle button click workaround to be
mistakenly disabled.

This commit adds explicit parameter to sysfs to control this
workaround.

Fixes: 46a0a2c96f0f ("HID: lenovo: Detect quirk-free fw on cptkbd and stop applying workaround")
Fixes: 43527a0094c1 ("HID: lenovo: Restrict detection of patched firmware only to USB cptkbd")
Signed-off-by: Mikhail Khvainitski <me@khvoinitsky.org>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 drivers/hid/hid-lenovo.c | 57 +++++++++++++++++++++++++++-------------
 1 file changed, 39 insertions(+), 18 deletions(-)

diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c
index 249af8d26fe78..c9fdeffbe1a9e 100644
--- a/drivers/hid/hid-lenovo.c
+++ b/drivers/hid/hid-lenovo.c
@@ -53,10 +53,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))
@@ -418,6 +418,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,
@@ -429,10 +459,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
 };
 
@@ -483,23 +519,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)) {
@@ -976,6 +996,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);
-- 
2.43.0
Re: [PATCH 5.10 127/238] HID: lenovo: Add middleclick_workaround sysfs knob for cptkbd
Posted by Pavel Machek 1 year, 8 months ago
Hi!

> From: Mikhail Khvainitski <me@khvoinitsky.org>
> 
> [ Upstream commit 2814646f76f8518326964f12ff20aaee70ba154d ]
> 
> Previous attempt to autodetect well-behaving patched firmware
> introduced in commit 46a0a2c96f0f ("HID: lenovo: Detect quirk-free fw
> on cptkbd and stop applying workaround") has shown that there are
> false-positives on original firmware (on both 1st gen and 2nd gen
> keyboards) which causes the middle button click workaround to be
> mistakenly disabled.
> 
> This commit adds explicit parameter to sysfs to control this
> workaround.

Should this go to stable? We have stream of lenovo workarounds, maybe
-stable should wait for upstream to solve this.

Plus it should really have documentation.

Oh and we normally solve this stuff with module parameters, so that it
can be fixed during bootup.

Best regards,
							Pavel

> Fixes: 46a0a2c96f0f ("HID: lenovo: Detect quirk-free fw on cptkbd and stop applying workaround")
> Fixes: 43527a0094c1 ("HID: lenovo: Restrict detection of patched firmware only to USB cptkbd")
> Signed-off-by: Mikhail Khvainitski <me@khvoinitsky.org>
> Signed-off-by: Jiri Kosina <jkosina@suse.com>
> Signed-off-by: Sasha Levin <sashal@kernel.org>

-- 
DENX Software Engineering GmbH,        Managing Director: Erika Unter
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Re: [PATCH 5.10 127/238] HID: lenovo: Add middleclick_workaround sysfs knob for cptkbd
Posted by Mikhail Khvoinitsky 1 year, 8 months ago
Hi,
This patch is already on upstream. Unfortunately, previous backports
of related commits caused some issues so just skipping this one isn't
a good option.

For module parameters, while it's quite unrealistic for users to have
more than one identical keyboard but with different firmware, this is
possible and having a module option would prevent tuning only specific
keyboard.

For the documentation, makes sense. Sorry, I should have done it
together with the change, I'll fix it, thanks for pointing it out.

On Thu, 28 Mar 2024 at 12:40, Pavel Machek <pavel@denx.de> wrote:
>
> Hi!
>
> > From: Mikhail Khvainitski <me@khvoinitsky.org>
> >
> > [ Upstream commit 2814646f76f8518326964f12ff20aaee70ba154d ]
> >
> > Previous attempt to autodetect well-behaving patched firmware
> > introduced in commit 46a0a2c96f0f ("HID: lenovo: Detect quirk-free fw
> > on cptkbd and stop applying workaround") has shown that there are
> > false-positives on original firmware (on both 1st gen and 2nd gen
> > keyboards) which causes the middle button click workaround to be
> > mistakenly disabled.
> >
> > This commit adds explicit parameter to sysfs to control this
> > workaround.
>
> Should this go to stable? We have stream of lenovo workarounds, maybe
> -stable should wait for upstream to solve this.
>
> Plus it should really have documentation.
>
> Oh and we normally solve this stuff with module parameters, so that it
> can be fixed during bootup.
>
> Best regards,
>                                                         Pavel
>
> > Fixes: 46a0a2c96f0f ("HID: lenovo: Detect quirk-free fw on cptkbd and stop applying workaround")
> > Fixes: 43527a0094c1 ("HID: lenovo: Restrict detection of patched firmware only to USB cptkbd")
> > Signed-off-by: Mikhail Khvainitski <me@khvoinitsky.org>
> > Signed-off-by: Jiri Kosina <jkosina@suse.com>
> > Signed-off-by: Sasha Levin <sashal@kernel.org>
>
> --
> DENX Software Engineering GmbH,        Managing Director: Erika Unter
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany