Linux Input/HID development
 help / color / mirror / Atom feed
* [PATCH] HID: lenovo: suppress spurious F23 key events on ThinkPad T14s gen6/7 snapdragon
@ 2026-11-09 21:43 Hans de Goede
  2026-11-10  0:49 ` Mark Pearson
  0 siblings, 1 reply; 4+ messages in thread
From: Hans de Goede @ 2026-11-09 21:43 UTC (permalink / raw)
  To: Derek J . Clark, Mark Pearson, Jiri Kosina, Benjamin Tissoires
  Cc: Hans de Goede, linux-input

The Lenovo ThinkPad T14s gen6/7 snapdragon version I2C-HID keyboard sends
spurirous F23 key-events when the Fn key is pressed/released. Leading to
e.g. garbage ESC-sequences in the terminal when doing FN key combos.

A hwdb entry was added to map these to KEY_UNKNOWN [1], but this also maps
the F23 part of the left-meta + left-shift + F23 combo send by the co-pilot
key to KEY_UNKNOWN making that key unusable.

Add a raw_event filter which removes any 0x72 codes from the 6 scancodes
reported in the standard HID keyboard boot protocol report, but only when
the report's modifier byte is not 0x0a to preserve the F23 press event
when the co-pilot key is pressed.

Link: https://github.com/systemd/systemd/pull/44733 [1]
Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
---
 drivers/hid/hid-ids.h    |  1 +
 drivers/hid/hid-lenovo.c | 21 +++++++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 994e8bc69924..70d18d32fe3c 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -473,6 +473,7 @@
 #define USB_DEVICE_ID_EDIFIER_QR30	0xa101	/* EDIFIER Hal0 2.0 SE */
 
 #define USB_VENDOR_ID_ELAN		0x04f3
+#define I2C_DEVICE_ID_ELAN_LENOVO_T14S_KEYBOARD	0x000d
 #define USB_DEVICE_ID_SB974D            0x0400
 #define USB_DEVICE_ID_TOSHIBA_CLICK_L9W	0x0401
 #define USB_DEVICE_ID_HP_X2		0x074d
diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c
index 30bd3f794243..e997d0cf2672 100644
--- a/drivers/hid/hid-lenovo.c
+++ b/drivers/hid/hid-lenovo.c
@@ -812,6 +812,22 @@ static int lenovo_raw_event(struct hid_device *hdev,
 		      size >= 4 && report->id == 0x03))
 		return lenovo_raw_event_TP_X12_tab(hdev, get_unaligned_le32(data));
 
+	/*
+	 * Lenovo ThinkPad T14s gen6/7 snapdragon version filter out spurious
+	 * F23 events when Fn key is pressed. F23 cannot be unmapped because of
+	 * the copilot key sending left-meta + left-shift + F23. Filter report 8
+	 * (keyboard) scancode 0x72 (F23) when the modifier byte is not 0x0a.
+	 */
+	if (unlikely(hdev->product == I2C_DEVICE_ID_ELAN_LENOVO_T14S_KEYBOARD &&
+		     size == 9 && data[0] == 8 && data[1] != 0x0a)) {
+		for (int i = 3; i < 9; i++)
+			if (data[i] == 0x72) {
+				memmove(&data[i], &data[i + 1], 8 - i);
+				data[8] = 0;
+				break;
+			}
+	}
+
 	return 0;
 }
 
@@ -1393,6 +1409,10 @@ static int lenovo_probe(struct hid_device *hdev,
 {
 	int ret;
 
+	/* Make the T14s  keyboard trackpoint a separate input-device */
+	if (hdev->product == I2C_DEVICE_ID_ELAN_LENOVO_T14S_KEYBOARD)
+		hdev->quirks |= HID_QUIRK_INPUT_PER_APP;
+
 	ret = hid_parse(hdev);
 	if (ret) {
 		hid_err(hdev, "hid_parse failed\n");
@@ -1558,6 +1578,7 @@ static const struct hid_device_id lenovo_devices[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL_PRO) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TP10UBKBD) },
+	{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ELAN_LENOVO_T14S_KEYBOARD) },
 	/*
 	 * Note bind to the HID_GROUP_GENERIC group, so that we only bind to the keyboard
 	 * part, while letting hid-multitouch.c handle the touchpad and trackpoint.
-- 
2.56.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-11-10 12:28 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-09 21:43 [PATCH] HID: lenovo: suppress spurious F23 key events on ThinkPad T14s gen6/7 snapdragon Hans de Goede
2026-11-10  0:49 ` Mark Pearson
2026-11-10  9:36   ` Hans de Goede
2026-11-10 12:27     ` Mark Pearson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox