]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
HID: lenovo: fixup Lenovo Yoga Slim 7x Keyboard rdesc
authorLauri Tirkkonen <lauri@hacktheplanet.fi>
Sat, 18 Oct 2025 06:35:15 +0000 (15:35 +0900)
committerJiri Kosina <jkosina@suse.com>
Thu, 30 Oct 2025 10:40:52 +0000 (11:40 +0100)
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>
drivers/hid/hid-ids.h
drivers/hid/hid-lenovo.c

index 52ae7c29f9e085cfa9adf538929f17b45b2302b2..85db279baa72e8fca24279207b619a265e79e35a 100644 (file)
 #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
 
index 654879814f97aaf876ac16c00bf9efca22d116f3..9cc3e029e9f613ee364534ed045951aef66bc4b6 100644 (file)
@@ -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) },
        { }
 };