Skip to content

Commit 181a8b9

Browse files
bentissJiri Kosina
authored andcommitted
HID: lenovo: add support for Lenovo ThinkPad Keyboard Pro unit
This dock is used with the Thinkpad Helix 2 but suffers from an error in the report descriptor where an usage max is 65535. Add a report fixup for it and make the keyboard working. Tested-by: Jonathan Oppenheim <[email protected]> Tested-by: John Reid <[email protected]> Signed-off-by: Benjamin Tissoires <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent d92189e commit 181a8b9

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

drivers/hid/hid-core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1851,6 +1851,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
18511851
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) },
18521852
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) },
18531853
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) },
1854+
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPPRODOCK) },
18541855
#endif
18551856
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
18561857
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },

drivers/hid/hid-ids.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,7 @@
585585
#define USB_DEVICE_ID_LENOVO_TPKBD 0x6009
586586
#define USB_DEVICE_ID_LENOVO_CUSBKBD 0x6047
587587
#define USB_DEVICE_ID_LENOVO_CBTKBD 0x6048
588+
#define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067
588589

589590
#define USB_VENDOR_ID_LG 0x1fd2
590591
#define USB_DEVICE_ID_LG_MULTITOUCH 0x0064

drivers/hid/hid-lenovo.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,35 @@ struct lenovo_drvdata_cptkbd {
4343

4444
#define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
4545

46+
static const __u8 lenovo_pro_dock_need_fixup_collection[] = {
47+
0x05, 0x88, /* Usage Page (Vendor Usage Page 0x88) */
48+
0x09, 0x01, /* Usage (Vendor Usage 0x01) */
49+
0xa1, 0x01, /* Collection (Application) */
50+
0x85, 0x04, /* Report ID (4) */
51+
0x19, 0x00, /* Usage Minimum (0) */
52+
0x2a, 0xff, 0xff, /* Usage Maximum (65535) */
53+
};
54+
55+
static __u8 *lenovo_report_fixup(struct hid_device *hdev, __u8 *rdesc,
56+
unsigned int *rsize)
57+
{
58+
switch (hdev->product) {
59+
case USB_DEVICE_ID_LENOVO_TPPRODOCK:
60+
/* the fixups that need to be done:
61+
* - get a reasonable usage max for the vendor collection
62+
* 0x8801 from the report ID 4
63+
*/
64+
if (*rsize >= 153 &&
65+
memcmp(&rdesc[140], lenovo_pro_dock_need_fixup_collection,
66+
sizeof(lenovo_pro_dock_need_fixup_collection)) == 0) {
67+
rdesc[151] = 0x01;
68+
rdesc[152] = 0x00;
69+
}
70+
break;
71+
}
72+
return rdesc;
73+
}
74+
4675
static int lenovo_input_mapping_tpkbd(struct hid_device *hdev,
4776
struct hid_input *hi, struct hid_field *field,
4877
struct hid_usage *usage, unsigned long **bit, int *max)
@@ -784,6 +813,7 @@ static const struct hid_device_id lenovo_devices[] = {
784813
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) },
785814
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) },
786815
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) },
816+
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPPRODOCK) },
787817
{ }
788818
};
789819

@@ -797,6 +827,7 @@ static struct hid_driver lenovo_driver = {
797827
.probe = lenovo_probe,
798828
.remove = lenovo_remove,
799829
.raw_event = lenovo_raw_event,
830+
.report_fixup = lenovo_report_fixup,
800831
};
801832
module_hid_driver(lenovo_driver);
802833

0 commit comments

Comments
 (0)