From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Mikhail Khvainitski <me@khvoinitsky.org>,
Jiri Kosina <jkosina@suse.cz>, Sasha Levin <sashal@kernel.org>,
jikos@kernel.org, benjamin.tissoires@redhat.com,
linux-input@vger.kernel.org
Subject: [PATCH AUTOSEL 5.10 08/16] HID: lenovo: Detect quirk-free fw on cptkbd and stop applying workaround
Date: Tue, 7 Nov 2023 10:52:27 -0500 [thread overview]
Message-ID: <20231107155249.3768098-8-sashal@kernel.org> (raw)
In-Reply-To: <20231107155249.3768098-1-sashal@kernel.org>
From: Mikhail Khvainitski <me@khvoinitsky.org>
[ Upstream commit 46a0a2c96f0f47628190f122c2e3d879e590bcbe ]
Built-in firmware of cptkbd handles scrolling by itself (when middle
button is pressed) but with issues: it does not support horizontal and
hi-res scrolling and upon middle button release it sends middle button
click even if there was a scrolling event. Commit 3cb5ff0220e3 ("HID:
lenovo: Hide middle-button press until release") workarounds last
issue but it's impossible to workaround scrolling-related issues
without firmware modification.
Likely, Dennis Schneider has reverse engineered the firmware and
provided an instruction on how to patch it [1]. However,
aforementioned workaround prevents userspace (libinput) from knowing
exact moment when middle button has been pressed down and performing
"On-Button scrolling". This commit detects correctly-behaving patched
firmware if cursor movement events has been received during middle
button being pressed and stops applying workaround for this device.
Link: https://hohlerde.org/rauch/en/elektronik/projekte/tpkbd-fix/ [1]
Signed-off-by: Mikhail Khvainitski <me@khvoinitsky.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hid/hid-lenovo.c | 68 ++++++++++++++++++++++++++--------------
1 file changed, 45 insertions(+), 23 deletions(-)
diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c
index 0ff03fed97709..71f7b0d539df5 100644
--- a/drivers/hid/hid-lenovo.c
+++ b/drivers/hid/hid-lenovo.c
@@ -50,7 +50,12 @@ struct lenovo_drvdata {
int select_right;
int sensitivity;
int press_speed;
- u8 middlebutton_state; /* 0:Up, 1:Down (undecided), 2:Scrolling */
+ /* 0: Up
+ * 1: Down (undecided)
+ * 2: Scrolling
+ * 3: Patched firmware, disable workaround
+ */
+ u8 middlebutton_state;
bool fn_lock;
};
@@ -478,31 +483,48 @@ static int lenovo_event_cptkbd(struct hid_device *hdev,
{
struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev);
- /* "wheel" scroll events */
- if (usage->type == EV_REL && (usage->code == REL_WHEEL ||
- usage->code == REL_HWHEEL)) {
- /* Scroll events disable middle-click event */
- cptkbd_data->middlebutton_state = 2;
- return 0;
- }
+ 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 (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);
+ }
- /* Middle click events */
- if (usage->type == EV_KEY && usage->code == BTN_MIDDLE) {
- if (value == 1) {
- cptkbd_data->middlebutton_state = 1;
- } else if (value == 0) {
- if (cptkbd_data->middlebutton_state == 1) {
- /* No scrolling inbetween, send middle-click */
- input_event(field->hidinput->input,
- EV_KEY, BTN_MIDDLE, 1);
- input_sync(field->hidinput->input);
- input_event(field->hidinput->input,
- EV_KEY, BTN_MIDDLE, 0);
- input_sync(field->hidinput->input);
+ /* "wheel" scroll events */
+ if (usage->type == EV_REL && (usage->code == REL_WHEEL ||
+ usage->code == REL_HWHEEL)) {
+ /* Scroll events disable middle-click event */
+ cptkbd_data->middlebutton_state = 2;
+ return 0;
+ }
+
+ /* Middle click events */
+ if (usage->type == EV_KEY && usage->code == BTN_MIDDLE) {
+ if (value == 1) {
+ cptkbd_data->middlebutton_state = 1;
+ } else if (value == 0) {
+ if (cptkbd_data->middlebutton_state == 1) {
+ /* No scrolling inbetween, send middle-click */
+ input_event(field->hidinput->input,
+ EV_KEY, BTN_MIDDLE, 1);
+ input_sync(field->hidinput->input);
+ input_event(field->hidinput->input,
+ EV_KEY, BTN_MIDDLE, 0);
+ input_sync(field->hidinput->input);
+ }
+ cptkbd_data->middlebutton_state = 0;
}
- cptkbd_data->middlebutton_state = 0;
+ return 1;
}
- return 1;
}
return 0;
--
2.42.0
next prev parent reply other threads:[~2023-11-07 16:01 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-07 15:52 [PATCH AUTOSEL 5.10 01/16] ASoC: soc-card: Add storage for PCI SSID Sasha Levin
2023-11-07 15:52 ` [PATCH AUTOSEL 5.10 02/16] crypto: pcrypt - Fix hungtask for PADATA_RESET Sasha Levin
2023-11-07 15:52 ` [PATCH AUTOSEL 5.10 03/16] RDMA/hfi1: Use FIELD_GET() to extract Link Width Sasha Levin
2023-11-07 15:52 ` [PATCH AUTOSEL 5.10 04/16] fs/jfs: Add check for negative db_l2nbperpage Sasha Levin
2023-11-07 15:52 ` [PATCH AUTOSEL 5.10 05/16] fs/jfs: Add validity check for db_maxag and db_agpref Sasha Levin
2023-11-07 15:52 ` [PATCH AUTOSEL 5.10 06/16] jfs: fix array-index-out-of-bounds in dbFindLeaf Sasha Levin
2023-11-07 15:52 ` [PATCH AUTOSEL 5.10 07/16] jfs: fix array-index-out-of-bounds in diAlloc Sasha Levin
2023-11-07 15:52 ` Sasha Levin [this message]
2023-11-07 15:52 ` [PATCH AUTOSEL 5.10 09/16] ARM: 9320/1: fix stack depot IRQ stack filter Sasha Levin
2023-11-07 15:52 ` [PATCH AUTOSEL 5.10 10/16] ALSA: hda: Fix possible null-ptr-deref when assigning a stream Sasha Levin
2023-11-07 15:52 ` [PATCH AUTOSEL 5.10 11/16] PCI: tegra194: Use FIELD_GET()/FIELD_PREP() with Link Width fields Sasha Levin
2023-11-07 15:52 ` [PATCH AUTOSEL 5.10 12/16] atm: iphase: Do PCI error checks on own line Sasha Levin
2023-11-07 15:52 ` [PATCH AUTOSEL 5.10 13/16] scsi: libfc: Fix potential NULL pointer dereference in fc_lport_ptp_setup() Sasha Levin
2023-11-07 15:52 ` [PATCH AUTOSEL 5.10 14/16] misc: pci_endpoint_test: Add Device ID for R-Car S4-8 PCIe controller Sasha Levin
2023-11-07 15:52 ` [PATCH AUTOSEL 5.10 15/16] HID: Add quirk for Dell Pro Wireless Keyboard and Mouse KM5221W Sasha Levin
2023-11-07 15:52 ` [PATCH AUTOSEL 5.10 16/16] exfat: support handle zero-size directory Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231107155249.3768098-8-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=benjamin.tissoires@redhat.com \
--cc=jikos@kernel.org \
--cc=jkosina@suse.cz \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=me@khvoinitsky.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox