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 6.5 14/34] HID: lenovo: Detect quirk-free fw on cptkbd and stop applying workaround
Date: Tue, 7 Nov 2023 10:47:54 -0500 [thread overview]
Message-ID: <20231107154846.3766119-14-sashal@kernel.org> (raw)
In-Reply-To: <20231107154846.3766119-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 44763c0da4441..9c1181313e44d 100644
--- a/drivers/hid/hid-lenovo.c
+++ b/drivers/hid/hid-lenovo.c
@@ -51,7 +51,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;
};
@@ -668,31 +673,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;
}
if (usage->type == EV_KEY && usage->code == KEY_FN_ESC && value == 1) {
--
2.42.0
next prev parent reply other threads:[~2023-11-07 15:52 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-07 15:47 [PATCH AUTOSEL 6.5 01/34] ASoC: mediatek: mt8188-mt6359: support dynamic pinctrl Sasha Levin
2023-11-07 15:47 ` [PATCH AUTOSEL 6.5 02/34] ASoC: soc-card: Add storage for PCI SSID Sasha Levin
2023-11-07 15:47 ` [PATCH AUTOSEL 6.5 03/34] ASoC: SOF: Pass PCI SSID to machine driver Sasha Levin
2023-11-07 15:47 ` [PATCH AUTOSEL 6.5 04/34] crypto: pcrypt - Fix hungtask for PADATA_RESET Sasha Levin
2023-11-07 15:47 ` [PATCH AUTOSEL 6.5 05/34] ALSA: scarlett2: Move USB IDs out from device_info struct Sasha Levin
2023-11-07 15:47 ` [PATCH AUTOSEL 6.5 06/34] ASoC: SOF: ipc4: handle EXCEPTION_CAUGHT notification from firmware Sasha Levin
2023-11-07 15:47 ` [PATCH AUTOSEL 6.5 07/34] RDMA/hfi1: Use FIELD_GET() to extract Link Width Sasha Levin
2023-11-07 15:47 ` [PATCH AUTOSEL 6.5 08/34] scsi: hisi_sas: Set debugfs_dir pointer to NULL after removing debugfs Sasha Levin
2023-11-07 15:47 ` [PATCH AUTOSEL 6.5 09/34] scsi: ibmvfc: Remove BUG_ON in the case of an empty event pool Sasha Levin
2023-11-07 15:47 ` [PATCH AUTOSEL 6.5 10/34] fs/jfs: Add check for negative db_l2nbperpage Sasha Levin
2023-11-07 15:47 ` [PATCH AUTOSEL 6.5 11/34] fs/jfs: Add validity check for db_maxag and db_agpref Sasha Levin
2023-11-07 15:47 ` [PATCH AUTOSEL 6.5 12/34] jfs: fix array-index-out-of-bounds in dbFindLeaf Sasha Levin
2023-11-07 15:47 ` [PATCH AUTOSEL 6.5 13/34] jfs: fix array-index-out-of-bounds in diAlloc Sasha Levin
2023-11-07 15:47 ` Sasha Levin [this message]
2023-11-07 15:47 ` [PATCH AUTOSEL 6.5 15/34] ARM: 9320/1: fix stack depot IRQ stack filter Sasha Levin
2023-11-07 15:47 ` [PATCH AUTOSEL 6.5 16/34] ALSA: hda: Fix possible null-ptr-deref when assigning a stream Sasha Levin
2023-11-07 15:47 ` [PATCH AUTOSEL 6.5 17/34] gpiolib: of: Add quirk for mt2701-cs42448 ASoC sound Sasha Levin
2023-11-07 15:47 ` [PATCH AUTOSEL 6.5 18/34] PCI: tegra194: Use FIELD_GET()/FIELD_PREP() with Link Width fields Sasha Levin
2023-11-07 15:47 ` [PATCH AUTOSEL 6.5 19/34] PCI: mvebu: Use FIELD_PREP() with Link Width Sasha Levin
2023-11-07 15:48 ` [PATCH AUTOSEL 6.5 20/34] atm: iphase: Do PCI error checks on own line Sasha Levin
2023-11-07 15:48 ` [PATCH AUTOSEL 6.5 21/34] PCI: Do error check on own line to split long "if" conditions Sasha Levin
2023-11-07 15:48 ` [PATCH AUTOSEL 6.5 22/34] scsi: libfc: Fix potential NULL pointer dereference in fc_lport_ptp_setup() Sasha Levin
2023-11-07 15:48 ` [PATCH AUTOSEL 6.5 23/34] PCI: Use FIELD_GET() to extract Link Width Sasha Levin
2023-11-07 15:48 ` [PATCH AUTOSEL 6.5 24/34] PCI: Extract ATS disabling to a helper function Sasha Levin
2023-11-07 15:48 ` [PATCH AUTOSEL 6.5 25/34] PCI: Disable ATS for specific Intel IPU E2000 devices Sasha Levin
2023-11-07 15:48 ` [PATCH AUTOSEL 6.5 26/34] PCI: dwc: Add dw_pcie_link_set_max_link_width() Sasha Levin
2023-11-07 15:48 ` [PATCH AUTOSEL 6.5 27/34] PCI: dwc: Add missing PCI_EXP_LNKCAP_MLW handling Sasha Levin
2023-11-07 15:48 ` [PATCH AUTOSEL 6.5 28/34] misc: pci_endpoint_test: Add Device ID for R-Car S4-8 PCIe controller Sasha Levin
2023-11-07 15:48 ` [PATCH AUTOSEL 6.5 29/34] PCI: Use FIELD_GET() in Sapphire RX 5600 XT Pulse quirk Sasha Levin
2023-11-07 15:48 ` [PATCH AUTOSEL 6.5 30/34] ASoC: Intel: soc-acpi-cht: Add Lenovo Yoga Tab 3 Pro YT3-X90 quirk Sasha Levin
2023-11-07 15:48 ` [PATCH AUTOSEL 6.5 31/34] crypto: hisilicon/qm - prevent soft lockup in receive loop Sasha Levin
2023-11-07 15:48 ` [PATCH AUTOSEL 6.5 32/34] HID: Add quirk for Dell Pro Wireless Keyboard and Mouse KM5221W Sasha Levin
2023-11-07 15:48 ` [PATCH AUTOSEL 6.5 33/34] exfat: support handle zero-size directory Sasha Levin
2023-11-07 15:48 ` [PATCH AUTOSEL 6.5 34/34] mfd: intel-lpss: Add Intel Lunar Lake-M PCI IDs 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=20231107154846.3766119-14-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