From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Lauri Tirkkonen <lauri@hacktheplanet.fi>,
Jiri Kosina <jkosina@suse.com>, Sasha Levin <sashal@kernel.org>,
jikos@kernel.org, bentiss@kernel.org,
linux-input@vger.kernel.org
Subject: [PATCH AUTOSEL 6.17] HID: lenovo: fixup Lenovo Yoga Slim 7x Keyboard rdesc
Date: Mon, 24 Nov 2025 03:06:24 -0500 [thread overview]
Message-ID: <20251124080644.3871678-10-sashal@kernel.org> (raw)
In-Reply-To: <20251124080644.3871678-1-sashal@kernel.org>
From: Lauri Tirkkonen <lauri@hacktheplanet.fi>
[ Upstream commit a45f15808fb753a14c6041fd1e5bef5d552bd2e3 ]
The keyboard of this device has the following in its report description
for Usage (Keyboard) in Collection (Application):
# 0x15, 0x00, // Logical Minimum (0) 52
# 0x25, 0x65, // Logical Maximum (101) 54
# 0x05, 0x07, // Usage Page (Keyboard) 56
# 0x19, 0x00, // Usage Minimum (0) 58
# 0x29, 0xdd, // Usage Maximum (221) 60
# 0x81, 0x00, // Input (Data,Arr,Abs) 62
Since the Usage Min/Max range exceeds the Logical Min/Max range,
keypresses outside the Logical range are not recognized. This includes,
for example, the Japanese language keyboard variant's keys for |, _ and
\.
Fixup the report description to make the Logical range match the Usage
range, fixing the interpretation of keypresses above 101 on this device.
Signed-off-by: Lauri Tirkkonen <lauri@hacktheplanet.fi>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
HID: lenovo: fixup Lenovo Yoga Slim 7x Keyboard rdesc
**1. COMMIT MESSAGE ANALYSIS**
- **Problem:** The commit addresses a firmware bug in the Lenovo Yoga
Slim 7x keyboard HID descriptor. The "Logical Maximum" (101) is
defined incorrectly as smaller than the "Usage Maximum" (221).
- **User Impact:** This causes the OS to ignore keypresses with usage
codes above 101. This specifically breaks functionality for keys like
`|`, `_`, and `\` on Japanese keyboard layouts, rendering the device
partially unusable for those users.
- **Fix:** The patch modifies the report descriptor at runtime to align
the Logical Maximum with the Usage Maximum.
- **Stable Context:** This is a classic "quirk" or "workaround" for
broken hardware, which is a standard exception for stable backports.
**2. DEEP CODE RESEARCH**
- **Mechanism:** The commit implements a fixup that intercepts the
report descriptor before the HID core parses it.
- **Specific Changes:**
1. Adds a new device ID
`I2C_DEVICE_ID_ITE_LENOVO_YOGA_SLIM_7X_KEYBOARD` (0x8987).
2. Defines the specific byte sequence of the broken descriptor to
identify it uniquely:
```151:157:drivers/hid/hid-lenovo.c
static const __u8 lenovo_yoga7x_kbd_need_fixup_collection[] = {
0x15, 0x00, // Logical Minimum (0)
0x25, 0x65, // Logical Maximum (101)
0x05, 0x07, // Usage Page (Keyboard)
```
3. Updates the `lenovo_report_fixup` function to apply the patch only
when the device ID matches *and* the descriptor content matches:
```189:192:drivers/hid/hid-lenovo.c
case I2C_DEVICE_ID_ITE_LENOVO_YOGA_SLIM_7X_KEYBOARD:
if (*rsize == 176 &&
memcmp(&rdesc[52], lenovo_yoga7x_kbd_need_fixup_collection,
sizeof(lenovo_yoga7x_kbd_need_fixup_collection)) == 0) {
```
- **Safety:** The fix is defensive. It requires an exact match of the
device product ID and the descriptor bytes. It uses established
patterns found elsewhere in the driver (e.g., for the ThinkPad Pro
Dock).
**3. STABLE KERNEL RULES ASSESSMENT**
- **Obviously correct and tested:** The fix uses standard HID subsystem
mechanisms for correcting buggy hardware descriptors.
- **Fixes real bug:** Without this patch, specific keys do not function
on this hardware.
- **Small and contained:** The changes are surgical, affecting only
`drivers/hid/hid-lenovo.c` and `drivers/hid/hid-ids.h`.
- **Exceptions Applied:**
- **NEW DEVICE IDs:** Adds support for the Yoga Slim 7x (allowed).
- **QUIRKS/WORKAROUNDS:** Fixes the broken report descriptor
(allowed).
**4. RISK VS BENEFIT**
- **Benefit:** High for affected users. It makes the keyboard fully
functional.
- **Risk:** Very Low. The change is additive and guarded by a specific
device ID check. It cannot cause regressions for other Lenovo devices
because the code path is unreachable for them.
**5. CONCLUSION**
This commit is a textbook candidate for stable backporting. It supports
new hardware (Device ID exception) and fixes a firmware bug that breaks
functionality (Quirk exception). It is low-risk, contained, and provides
a necessary fix for users of this specific laptop model.
**YES**
drivers/hid/hid-ids.h | 1 +
drivers/hid/hid-lenovo.c | 17 +++++++++++++++++
2 files changed, 18 insertions(+)
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 5721b8414bbdf..4b1946eb4e7fc 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -715,6 +715,7 @@
#define USB_DEVICE_ID_ITE_LENOVO_YOGA2 0x8350
#define I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720 0x837a
#define USB_DEVICE_ID_ITE_LENOVO_YOGA900 0x8396
+#define I2C_DEVICE_ID_ITE_LENOVO_YOGA_SLIM_7X_KEYBOARD 0x8987
#define USB_DEVICE_ID_ITE8595 0x8595
#define USB_DEVICE_ID_ITE_MEDION_E1239T 0xce50
diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c
index 654879814f97a..9cc3e029e9f61 100644
--- a/drivers/hid/hid-lenovo.c
+++ b/drivers/hid/hid-lenovo.c
@@ -148,6 +148,14 @@ static const __u8 lenovo_tpIIbtkbd_need_fixup_collection[] = {
0x81, 0x01, /* Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) */
};
+static const __u8 lenovo_yoga7x_kbd_need_fixup_collection[] = {
+ 0x15, 0x00, // Logical Minimum (0)
+ 0x25, 0x65, // Logical Maximum (101)
+ 0x05, 0x07, // Usage Page (Keyboard)
+ 0x19, 0x00, // Usage Minimum (0)
+ 0x29, 0xDD, // Usage Maximum (221)
+};
+
static const __u8 *lenovo_report_fixup(struct hid_device *hdev, __u8 *rdesc,
unsigned int *rsize)
{
@@ -177,6 +185,13 @@ static const __u8 *lenovo_report_fixup(struct hid_device *hdev, __u8 *rdesc,
rdesc[260] = 0x01; /* report count (2) = 0x01 */
}
break;
+ case I2C_DEVICE_ID_ITE_LENOVO_YOGA_SLIM_7X_KEYBOARD:
+ if (*rsize == 176 &&
+ memcmp(&rdesc[52], lenovo_yoga7x_kbd_need_fixup_collection,
+ sizeof(lenovo_yoga7x_kbd_need_fixup_collection)) == 0) {
+ rdesc[55] = rdesc[61]; // logical maximum = usage maximum
+ }
+ break;
}
return rdesc;
}
@@ -1538,6 +1553,8 @@ static const struct hid_device_id lenovo_devices[] = {
USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X12_TAB) },
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X12_TAB2) },
+ { HID_DEVICE(BUS_I2C, HID_GROUP_GENERIC,
+ USB_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_LENOVO_YOGA_SLIM_7X_KEYBOARD) },
{ }
};
--
2.51.0
next prev parent reply other threads:[~2025-11-24 8:07 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20251124080644.3871678-1-sashal@kernel.org>
2025-11-24 8:06 ` [PATCH AUTOSEL 6.17-5.15] HID: elecom: Add support for ELECOM M-XT3URBK (018F) Sasha Levin
2025-11-24 8:06 ` [PATCH AUTOSEL 6.17-6.6] HID: hid-input: Extend Elan ignore battery quirk to USB Sasha Levin
2025-11-24 8:06 ` Sasha Levin [this message]
2025-11-24 8:06 ` [PATCH AUTOSEL 6.17-6.1] HID: apple: Add SONiX AK870 PRO to non_apple_keyboards quirk list 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=20251124080644.3871678-10-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=bentiss@kernel.org \
--cc=jikos@kernel.org \
--cc=jkosina@suse.com \
--cc=lauri@hacktheplanet.fi \
--cc=linux-input@vger.kernel.org \
--cc=patches@lists.linux.dev \
--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;
as well as URLs for NNTP newsgroup(s).