1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * HID driver for Lenovo:
4 * - ThinkPad USB Keyboard with TrackPoint (tpkbd)
5 * - ThinkPad Compact Bluetooth Keyboard with TrackPoint (cptkbd)
6 * - ThinkPad Compact USB Keyboard with TrackPoint (cptkbd)
8 * Copyright (c) 2012 Bernhard Seibold
9 * Copyright (c) 2014 Jamie Lentin <jm@lentin.co.uk>
11 * Linux IBM/Lenovo Scrollpoint mouse driver:
12 * - IBM Scrollpoint III
13 * - IBM Scrollpoint Pro
14 * - IBM Scrollpoint Optical
15 * - IBM Scrollpoint Optical 800dpi
16 * - IBM Scrollpoint Optical 800dpi Pro
17 * - Lenovo Scrollpoint Optical
19 * Copyright (c) 2012 Peter De Wachter <pdewacht@gmail.com>
20 * Copyright (c) 2018 Peter Ganzhorn <peter.ganzhorn@gmail.com>
26 #include <linux/module.h>
27 #include <linux/sysfs.h>
28 #include <linux/device.h>
29 #include <linux/hid.h>
30 #include <linux/input.h>
31 #include <linux/leds.h>
32 #include <linux/workqueue.h>
36 struct lenovo_drvdata
{
37 u8 led_report
[3]; /* Must be first for proper alignment */
39 struct mutex led_report_mutex
;
40 struct led_classdev led_mute
;
41 struct led_classdev led_micmute
;
42 struct work_struct fn_lock_sync_work
;
43 struct hid_device
*hdev
;
46 int release_to_select
;
50 u8 middlebutton_state
; /* 0:Up, 1:Down (undecided), 2:Scrolling */
54 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
56 #define TP10UBKBD_LED_OUTPUT_REPORT 9
58 #define TP10UBKBD_FN_LOCK_LED 0x54
59 #define TP10UBKBD_MUTE_LED 0x64
60 #define TP10UBKBD_MICMUTE_LED 0x74
62 #define TP10UBKBD_LED_OFF 1
63 #define TP10UBKBD_LED_ON 2
65 static void lenovo_led_set_tp10ubkbd(struct hid_device
*hdev
, u8 led_code
,
66 enum led_brightness value
)
68 struct lenovo_drvdata
*data
= hid_get_drvdata(hdev
);
71 mutex_lock(&data
->led_report_mutex
);
73 data
->led_report
[0] = TP10UBKBD_LED_OUTPUT_REPORT
;
74 data
->led_report
[1] = led_code
;
75 data
->led_report
[2] = value
? TP10UBKBD_LED_ON
: TP10UBKBD_LED_OFF
;
76 ret
= hid_hw_raw_request(hdev
, data
->led_report
[0], data
->led_report
, 3,
77 HID_OUTPUT_REPORT
, HID_REQ_SET_REPORT
);
79 hid_err(hdev
, "Set LED output report error: %d\n", ret
);
81 mutex_unlock(&data
->led_report_mutex
);
84 static void lenovo_tp10ubkbd_sync_fn_lock(struct work_struct
*work
)
86 struct lenovo_drvdata
*data
=
87 container_of(work
, struct lenovo_drvdata
, fn_lock_sync_work
);
89 lenovo_led_set_tp10ubkbd(data
->hdev
, TP10UBKBD_FN_LOCK_LED
,
93 static const __u8 lenovo_pro_dock_need_fixup_collection
[] = {
94 0x05, 0x88, /* Usage Page (Vendor Usage Page 0x88) */
95 0x09, 0x01, /* Usage (Vendor Usage 0x01) */
96 0xa1, 0x01, /* Collection (Application) */
97 0x85, 0x04, /* Report ID (4) */
98 0x19, 0x00, /* Usage Minimum (0) */
99 0x2a, 0xff, 0xff, /* Usage Maximum (65535) */
102 static __u8
*lenovo_report_fixup(struct hid_device
*hdev
, __u8
*rdesc
,
105 switch (hdev
->product
) {
106 case USB_DEVICE_ID_LENOVO_TPPRODOCK
:
107 /* the fixups that need to be done:
108 * - get a reasonable usage max for the vendor collection
109 * 0x8801 from the report ID 4
112 memcmp(&rdesc
[140], lenovo_pro_dock_need_fixup_collection
,
113 sizeof(lenovo_pro_dock_need_fixup_collection
)) == 0) {
122 static int lenovo_input_mapping_tpkbd(struct hid_device
*hdev
,
123 struct hid_input
*hi
, struct hid_field
*field
,
124 struct hid_usage
*usage
, unsigned long **bit
, int *max
)
126 if (usage
->hid
== (HID_UP_BUTTON
| 0x0010)) {
127 /* This sub-device contains trackpoint, mark it */
128 hid_set_drvdata(hdev
, (void *)1);
129 map_key_clear(KEY_MICMUTE
);
135 static int lenovo_input_mapping_cptkbd(struct hid_device
*hdev
,
136 struct hid_input
*hi
, struct hid_field
*field
,
137 struct hid_usage
*usage
, unsigned long **bit
, int *max
)
139 /* HID_UP_LNVENDOR = USB, HID_UP_MSVENDOR = BT */
140 if ((usage
->hid
& HID_USAGE_PAGE
) == HID_UP_MSVENDOR
||
141 (usage
->hid
& HID_USAGE_PAGE
) == HID_UP_LNVENDOR
) {
142 switch (usage
->hid
& HID_USAGE
) {
143 case 0x00f1: /* Fn-F4: Mic mute */
144 map_key_clear(KEY_MICMUTE
);
146 case 0x00f2: /* Fn-F5: Brightness down */
147 map_key_clear(KEY_BRIGHTNESSDOWN
);
149 case 0x00f3: /* Fn-F6: Brightness up */
150 map_key_clear(KEY_BRIGHTNESSUP
);
152 case 0x00f4: /* Fn-F7: External display (projector) */
153 map_key_clear(KEY_SWITCHVIDEOMODE
);
155 case 0x00f5: /* Fn-F8: Wireless */
156 map_key_clear(KEY_WLAN
);
158 case 0x00f6: /* Fn-F9: Control panel */
159 map_key_clear(KEY_CONFIG
);
161 case 0x00f8: /* Fn-F11: View open applications (3 boxes) */
162 map_key_clear(KEY_SCALE
);
164 case 0x00f9: /* Fn-F12: Open My computer (6 boxes) USB-only */
165 /* NB: This mapping is invented in raw_event below */
166 map_key_clear(KEY_FILE
);
168 case 0x00fa: /* Fn-Esc: Fn-lock toggle */
169 map_key_clear(KEY_FN_ESC
);
171 case 0x00fb: /* Middle mouse button (in native mode) */
172 map_key_clear(BTN_MIDDLE
);
177 /* Compatibility middle/wheel mappings should be ignored */
178 if (usage
->hid
== HID_GD_WHEEL
)
180 if ((usage
->hid
& HID_USAGE_PAGE
) == HID_UP_BUTTON
&&
181 (usage
->hid
& HID_USAGE
) == 0x003)
183 if ((usage
->hid
& HID_USAGE_PAGE
) == HID_UP_CONSUMER
&&
184 (usage
->hid
& HID_USAGE
) == 0x238)
187 /* Map wheel emulation reports: 0xffa1 = USB, 0xff10 = BT */
188 if ((usage
->hid
& HID_USAGE_PAGE
) == 0xff100000 ||
189 (usage
->hid
& HID_USAGE_PAGE
) == 0xffa10000) {
190 field
->flags
|= HID_MAIN_ITEM_RELATIVE
| HID_MAIN_ITEM_VARIABLE
;
191 field
->logical_minimum
= -127;
192 field
->logical_maximum
= 127;
194 switch (usage
->hid
& HID_USAGE
) {
196 hid_map_usage(hi
, usage
, bit
, max
, EV_REL
, REL_HWHEEL
);
199 hid_map_usage(hi
, usage
, bit
, max
, EV_REL
, REL_WHEEL
);
209 static int lenovo_input_mapping_scrollpoint(struct hid_device
*hdev
,
210 struct hid_input
*hi
, struct hid_field
*field
,
211 struct hid_usage
*usage
, unsigned long **bit
, int *max
)
213 if (usage
->hid
== HID_GD_Z
) {
214 hid_map_usage(hi
, usage
, bit
, max
, EV_REL
, REL_HWHEEL
);
220 static int lenovo_input_mapping_tp10_ultrabook_kbd(struct hid_device
*hdev
,
221 struct hid_input
*hi
, struct hid_field
*field
,
222 struct hid_usage
*usage
, unsigned long **bit
, int *max
)
225 * The ThinkPad 10 Ultrabook Keyboard uses 0x000c0001 usage for
226 * a bunch of keys which have no standard consumer page code.
228 if (usage
->hid
== 0x000c0001) {
229 switch (usage
->usage_index
) {
230 case 8: /* Fn-Esc: Fn-lock toggle */
231 map_key_clear(KEY_FN_ESC
);
233 case 9: /* Fn-F4: Mic mute */
234 map_key_clear(KEY_MICMUTE
);
236 case 10: /* Fn-F7: Control panel */
237 map_key_clear(KEY_CONFIG
);
239 case 11: /* Fn-F8: Search (magnifier glass) */
240 map_key_clear(KEY_SEARCH
);
242 case 12: /* Fn-F10: Open My computer (6 boxes) */
243 map_key_clear(KEY_FILE
);
249 * The Ultrabook Keyboard sends a spurious F23 key-press when resuming
250 * from suspend and it does not actually have a F23 key, ignore it.
252 if (usage
->hid
== 0x00070072)
258 static int lenovo_input_mapping(struct hid_device
*hdev
,
259 struct hid_input
*hi
, struct hid_field
*field
,
260 struct hid_usage
*usage
, unsigned long **bit
, int *max
)
262 switch (hdev
->product
) {
263 case USB_DEVICE_ID_LENOVO_TPKBD
:
264 return lenovo_input_mapping_tpkbd(hdev
, hi
, field
,
266 case USB_DEVICE_ID_LENOVO_CUSBKBD
:
267 case USB_DEVICE_ID_LENOVO_CBTKBD
:
268 return lenovo_input_mapping_cptkbd(hdev
, hi
, field
,
270 case USB_DEVICE_ID_IBM_SCROLLPOINT_III
:
271 case USB_DEVICE_ID_IBM_SCROLLPOINT_PRO
:
272 case USB_DEVICE_ID_IBM_SCROLLPOINT_OPTICAL
:
273 case USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL
:
274 case USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL_PRO
:
275 case USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL
:
276 return lenovo_input_mapping_scrollpoint(hdev
, hi
, field
,
278 case USB_DEVICE_ID_LENOVO_TP10UBKBD
:
279 return lenovo_input_mapping_tp10_ultrabook_kbd(hdev
, hi
, field
,
288 /* Send a config command to the keyboard */
289 static int lenovo_send_cmd_cptkbd(struct hid_device
*hdev
,
290 unsigned char byte2
, unsigned char byte3
)
295 buf
= kzalloc(3, GFP_KERNEL
);
303 switch (hdev
->product
) {
304 case USB_DEVICE_ID_LENOVO_CUSBKBD
:
305 ret
= hid_hw_raw_request(hdev
, 0x13, buf
, 3,
306 HID_FEATURE_REPORT
, HID_REQ_SET_REPORT
);
308 case USB_DEVICE_ID_LENOVO_CBTKBD
:
309 ret
= hid_hw_output_report(hdev
, buf
, 3);
318 return ret
< 0 ? ret
: 0; /* BT returns 0, USB returns sizeof(buf) */
321 static void lenovo_features_set_cptkbd(struct hid_device
*hdev
)
324 struct lenovo_drvdata
*cptkbd_data
= hid_get_drvdata(hdev
);
326 ret
= lenovo_send_cmd_cptkbd(hdev
, 0x05, cptkbd_data
->fn_lock
);
328 hid_err(hdev
, "Fn-lock setting failed: %d\n", ret
);
330 ret
= lenovo_send_cmd_cptkbd(hdev
, 0x02, cptkbd_data
->sensitivity
);
332 hid_err(hdev
, "Sensitivity setting failed: %d\n", ret
);
335 static ssize_t
attr_fn_lock_show(struct device
*dev
,
336 struct device_attribute
*attr
,
339 struct hid_device
*hdev
= to_hid_device(dev
);
340 struct lenovo_drvdata
*data
= hid_get_drvdata(hdev
);
342 return snprintf(buf
, PAGE_SIZE
, "%u\n", data
->fn_lock
);
345 static ssize_t
attr_fn_lock_store(struct device
*dev
,
346 struct device_attribute
*attr
,
350 struct hid_device
*hdev
= to_hid_device(dev
);
351 struct lenovo_drvdata
*data
= hid_get_drvdata(hdev
);
354 if (kstrtoint(buf
, 10, &value
))
356 if (value
< 0 || value
> 1)
359 data
->fn_lock
= !!value
;
361 switch (hdev
->product
) {
362 case USB_DEVICE_ID_LENOVO_CUSBKBD
:
363 case USB_DEVICE_ID_LENOVO_CBTKBD
:
364 lenovo_features_set_cptkbd(hdev
);
366 case USB_DEVICE_ID_LENOVO_TP10UBKBD
:
367 lenovo_led_set_tp10ubkbd(hdev
, TP10UBKBD_FN_LOCK_LED
, value
);
374 static ssize_t
attr_sensitivity_show_cptkbd(struct device
*dev
,
375 struct device_attribute
*attr
,
378 struct hid_device
*hdev
= to_hid_device(dev
);
379 struct lenovo_drvdata
*cptkbd_data
= hid_get_drvdata(hdev
);
381 return snprintf(buf
, PAGE_SIZE
, "%u\n",
382 cptkbd_data
->sensitivity
);
385 static ssize_t
attr_sensitivity_store_cptkbd(struct device
*dev
,
386 struct device_attribute
*attr
,
390 struct hid_device
*hdev
= to_hid_device(dev
);
391 struct lenovo_drvdata
*cptkbd_data
= hid_get_drvdata(hdev
);
394 if (kstrtoint(buf
, 10, &value
) || value
< 1 || value
> 255)
397 cptkbd_data
->sensitivity
= value
;
398 lenovo_features_set_cptkbd(hdev
);
404 static struct device_attribute dev_attr_fn_lock
=
405 __ATTR(fn_lock
, S_IWUSR
| S_IRUGO
,
409 static struct device_attribute dev_attr_sensitivity_cptkbd
=
410 __ATTR(sensitivity
, S_IWUSR
| S_IRUGO
,
411 attr_sensitivity_show_cptkbd
,
412 attr_sensitivity_store_cptkbd
);
415 static struct attribute
*lenovo_attributes_cptkbd
[] = {
416 &dev_attr_fn_lock
.attr
,
417 &dev_attr_sensitivity_cptkbd
.attr
,
421 static const struct attribute_group lenovo_attr_group_cptkbd
= {
422 .attrs
= lenovo_attributes_cptkbd
,
425 static int lenovo_raw_event(struct hid_device
*hdev
,
426 struct hid_report
*report
, u8
*data
, int size
)
429 * Compact USB keyboard's Fn-F12 report holds down many other keys, and
430 * its own key is outside the usage page range. Remove extra
431 * keypresses and remap to inside usage page.
433 if (unlikely(hdev
->product
== USB_DEVICE_ID_LENOVO_CUSBKBD
437 && data
[2] == 0x01)) {
445 static int lenovo_event_tp10ubkbd(struct hid_device
*hdev
,
446 struct hid_field
*field
, struct hid_usage
*usage
, __s32 value
)
448 struct lenovo_drvdata
*data
= hid_get_drvdata(hdev
);
450 if (usage
->type
== EV_KEY
&& usage
->code
== KEY_FN_ESC
&& value
== 1) {
452 * The user has toggled the Fn-lock state. Toggle our own
453 * cached value of it and sync our value to the keyboard to
454 * ensure things are in sync (the sycning should be a no-op).
456 data
->fn_lock
= !data
->fn_lock
;
457 schedule_work(&data
->fn_lock_sync_work
);
463 static int lenovo_event_cptkbd(struct hid_device
*hdev
,
464 struct hid_field
*field
, struct hid_usage
*usage
, __s32 value
)
466 struct lenovo_drvdata
*cptkbd_data
= hid_get_drvdata(hdev
);
468 /* "wheel" scroll events */
469 if (usage
->type
== EV_REL
&& (usage
->code
== REL_WHEEL
||
470 usage
->code
== REL_HWHEEL
)) {
471 /* Scroll events disable middle-click event */
472 cptkbd_data
->middlebutton_state
= 2;
476 /* Middle click events */
477 if (usage
->type
== EV_KEY
&& usage
->code
== BTN_MIDDLE
) {
479 cptkbd_data
->middlebutton_state
= 1;
480 } else if (value
== 0) {
481 if (cptkbd_data
->middlebutton_state
== 1) {
482 /* No scrolling inbetween, send middle-click */
483 input_event(field
->hidinput
->input
,
484 EV_KEY
, BTN_MIDDLE
, 1);
485 input_sync(field
->hidinput
->input
);
486 input_event(field
->hidinput
->input
,
487 EV_KEY
, BTN_MIDDLE
, 0);
488 input_sync(field
->hidinput
->input
);
490 cptkbd_data
->middlebutton_state
= 0;
498 static int lenovo_event(struct hid_device
*hdev
, struct hid_field
*field
,
499 struct hid_usage
*usage
, __s32 value
)
501 switch (hdev
->product
) {
502 case USB_DEVICE_ID_LENOVO_CUSBKBD
:
503 case USB_DEVICE_ID_LENOVO_CBTKBD
:
504 return lenovo_event_cptkbd(hdev
, field
, usage
, value
);
505 case USB_DEVICE_ID_LENOVO_TP10UBKBD
:
506 return lenovo_event_tp10ubkbd(hdev
, field
, usage
, value
);
512 static int lenovo_features_set_tpkbd(struct hid_device
*hdev
)
514 struct hid_report
*report
;
515 struct lenovo_drvdata
*data_pointer
= hid_get_drvdata(hdev
);
517 report
= hdev
->report_enum
[HID_FEATURE_REPORT
].report_id_hash
[4];
519 report
->field
[0]->value
[0] = data_pointer
->press_to_select
? 0x01 : 0x02;
520 report
->field
[0]->value
[0] |= data_pointer
->dragging
? 0x04 : 0x08;
521 report
->field
[0]->value
[0] |= data_pointer
->release_to_select
? 0x10 : 0x20;
522 report
->field
[0]->value
[0] |= data_pointer
->select_right
? 0x80 : 0x40;
523 report
->field
[1]->value
[0] = 0x03; // unknown setting, imitate windows driver
524 report
->field
[2]->value
[0] = data_pointer
->sensitivity
;
525 report
->field
[3]->value
[0] = data_pointer
->press_speed
;
527 hid_hw_request(hdev
, report
, HID_REQ_SET_REPORT
);
531 static ssize_t
attr_press_to_select_show_tpkbd(struct device
*dev
,
532 struct device_attribute
*attr
,
535 struct hid_device
*hdev
= to_hid_device(dev
);
536 struct lenovo_drvdata
*data_pointer
= hid_get_drvdata(hdev
);
538 return snprintf(buf
, PAGE_SIZE
, "%u\n", data_pointer
->press_to_select
);
541 static ssize_t
attr_press_to_select_store_tpkbd(struct device
*dev
,
542 struct device_attribute
*attr
,
546 struct hid_device
*hdev
= to_hid_device(dev
);
547 struct lenovo_drvdata
*data_pointer
= hid_get_drvdata(hdev
);
550 if (kstrtoint(buf
, 10, &value
))
552 if (value
< 0 || value
> 1)
555 data_pointer
->press_to_select
= value
;
556 lenovo_features_set_tpkbd(hdev
);
561 static ssize_t
attr_dragging_show_tpkbd(struct device
*dev
,
562 struct device_attribute
*attr
,
565 struct hid_device
*hdev
= to_hid_device(dev
);
566 struct lenovo_drvdata
*data_pointer
= hid_get_drvdata(hdev
);
568 return snprintf(buf
, PAGE_SIZE
, "%u\n", data_pointer
->dragging
);
571 static ssize_t
attr_dragging_store_tpkbd(struct device
*dev
,
572 struct device_attribute
*attr
,
576 struct hid_device
*hdev
= to_hid_device(dev
);
577 struct lenovo_drvdata
*data_pointer
= hid_get_drvdata(hdev
);
580 if (kstrtoint(buf
, 10, &value
))
582 if (value
< 0 || value
> 1)
585 data_pointer
->dragging
= value
;
586 lenovo_features_set_tpkbd(hdev
);
591 static ssize_t
attr_release_to_select_show_tpkbd(struct device
*dev
,
592 struct device_attribute
*attr
,
595 struct hid_device
*hdev
= to_hid_device(dev
);
596 struct lenovo_drvdata
*data_pointer
= hid_get_drvdata(hdev
);
598 return snprintf(buf
, PAGE_SIZE
, "%u\n", data_pointer
->release_to_select
);
601 static ssize_t
attr_release_to_select_store_tpkbd(struct device
*dev
,
602 struct device_attribute
*attr
,
606 struct hid_device
*hdev
= to_hid_device(dev
);
607 struct lenovo_drvdata
*data_pointer
= hid_get_drvdata(hdev
);
610 if (kstrtoint(buf
, 10, &value
))
612 if (value
< 0 || value
> 1)
615 data_pointer
->release_to_select
= value
;
616 lenovo_features_set_tpkbd(hdev
);
621 static ssize_t
attr_select_right_show_tpkbd(struct device
*dev
,
622 struct device_attribute
*attr
,
625 struct hid_device
*hdev
= to_hid_device(dev
);
626 struct lenovo_drvdata
*data_pointer
= hid_get_drvdata(hdev
);
628 return snprintf(buf
, PAGE_SIZE
, "%u\n", data_pointer
->select_right
);
631 static ssize_t
attr_select_right_store_tpkbd(struct device
*dev
,
632 struct device_attribute
*attr
,
636 struct hid_device
*hdev
= to_hid_device(dev
);
637 struct lenovo_drvdata
*data_pointer
= hid_get_drvdata(hdev
);
640 if (kstrtoint(buf
, 10, &value
))
642 if (value
< 0 || value
> 1)
645 data_pointer
->select_right
= value
;
646 lenovo_features_set_tpkbd(hdev
);
651 static ssize_t
attr_sensitivity_show_tpkbd(struct device
*dev
,
652 struct device_attribute
*attr
,
655 struct hid_device
*hdev
= to_hid_device(dev
);
656 struct lenovo_drvdata
*data_pointer
= hid_get_drvdata(hdev
);
658 return snprintf(buf
, PAGE_SIZE
, "%u\n",
659 data_pointer
->sensitivity
);
662 static ssize_t
attr_sensitivity_store_tpkbd(struct device
*dev
,
663 struct device_attribute
*attr
,
667 struct hid_device
*hdev
= to_hid_device(dev
);
668 struct lenovo_drvdata
*data_pointer
= hid_get_drvdata(hdev
);
671 if (kstrtoint(buf
, 10, &value
) || value
< 1 || value
> 255)
674 data_pointer
->sensitivity
= value
;
675 lenovo_features_set_tpkbd(hdev
);
680 static ssize_t
attr_press_speed_show_tpkbd(struct device
*dev
,
681 struct device_attribute
*attr
,
684 struct hid_device
*hdev
= to_hid_device(dev
);
685 struct lenovo_drvdata
*data_pointer
= hid_get_drvdata(hdev
);
687 return snprintf(buf
, PAGE_SIZE
, "%u\n",
688 data_pointer
->press_speed
);
691 static ssize_t
attr_press_speed_store_tpkbd(struct device
*dev
,
692 struct device_attribute
*attr
,
696 struct hid_device
*hdev
= to_hid_device(dev
);
697 struct lenovo_drvdata
*data_pointer
= hid_get_drvdata(hdev
);
700 if (kstrtoint(buf
, 10, &value
) || value
< 1 || value
> 255)
703 data_pointer
->press_speed
= value
;
704 lenovo_features_set_tpkbd(hdev
);
709 static struct device_attribute dev_attr_press_to_select_tpkbd
=
710 __ATTR(press_to_select
, S_IWUSR
| S_IRUGO
,
711 attr_press_to_select_show_tpkbd
,
712 attr_press_to_select_store_tpkbd
);
714 static struct device_attribute dev_attr_dragging_tpkbd
=
715 __ATTR(dragging
, S_IWUSR
| S_IRUGO
,
716 attr_dragging_show_tpkbd
,
717 attr_dragging_store_tpkbd
);
719 static struct device_attribute dev_attr_release_to_select_tpkbd
=
720 __ATTR(release_to_select
, S_IWUSR
| S_IRUGO
,
721 attr_release_to_select_show_tpkbd
,
722 attr_release_to_select_store_tpkbd
);
724 static struct device_attribute dev_attr_select_right_tpkbd
=
725 __ATTR(select_right
, S_IWUSR
| S_IRUGO
,
726 attr_select_right_show_tpkbd
,
727 attr_select_right_store_tpkbd
);
729 static struct device_attribute dev_attr_sensitivity_tpkbd
=
730 __ATTR(sensitivity
, S_IWUSR
| S_IRUGO
,
731 attr_sensitivity_show_tpkbd
,
732 attr_sensitivity_store_tpkbd
);
734 static struct device_attribute dev_attr_press_speed_tpkbd
=
735 __ATTR(press_speed
, S_IWUSR
| S_IRUGO
,
736 attr_press_speed_show_tpkbd
,
737 attr_press_speed_store_tpkbd
);
739 static struct attribute
*lenovo_attributes_tpkbd
[] = {
740 &dev_attr_press_to_select_tpkbd
.attr
,
741 &dev_attr_dragging_tpkbd
.attr
,
742 &dev_attr_release_to_select_tpkbd
.attr
,
743 &dev_attr_select_right_tpkbd
.attr
,
744 &dev_attr_sensitivity_tpkbd
.attr
,
745 &dev_attr_press_speed_tpkbd
.attr
,
749 static const struct attribute_group lenovo_attr_group_tpkbd
= {
750 .attrs
= lenovo_attributes_tpkbd
,
753 static void lenovo_led_set_tpkbd(struct hid_device
*hdev
)
755 struct lenovo_drvdata
*data_pointer
= hid_get_drvdata(hdev
);
756 struct hid_report
*report
;
758 report
= hdev
->report_enum
[HID_OUTPUT_REPORT
].report_id_hash
[3];
759 report
->field
[0]->value
[0] = (data_pointer
->led_state
>> 0) & 1;
760 report
->field
[0]->value
[1] = (data_pointer
->led_state
>> 1) & 1;
761 hid_hw_request(hdev
, report
, HID_REQ_SET_REPORT
);
764 static enum led_brightness
lenovo_led_brightness_get(
765 struct led_classdev
*led_cdev
)
767 struct device
*dev
= led_cdev
->dev
->parent
;
768 struct hid_device
*hdev
= to_hid_device(dev
);
769 struct lenovo_drvdata
*data_pointer
= hid_get_drvdata(hdev
);
772 if (led_cdev
== &data_pointer
->led_micmute
)
775 return data_pointer
->led_state
& (1 << led_nr
)
780 static void lenovo_led_brightness_set(struct led_classdev
*led_cdev
,
781 enum led_brightness value
)
783 struct device
*dev
= led_cdev
->dev
->parent
;
784 struct hid_device
*hdev
= to_hid_device(dev
);
785 struct lenovo_drvdata
*data_pointer
= hid_get_drvdata(hdev
);
786 u8 tp10ubkbd_led
[] = { TP10UBKBD_MUTE_LED
, TP10UBKBD_MICMUTE_LED
};
789 if (led_cdev
== &data_pointer
->led_micmute
)
792 if (value
== LED_OFF
)
793 data_pointer
->led_state
&= ~(1 << led_nr
);
795 data_pointer
->led_state
|= 1 << led_nr
;
797 switch (hdev
->product
) {
798 case USB_DEVICE_ID_LENOVO_TPKBD
:
799 lenovo_led_set_tpkbd(hdev
);
801 case USB_DEVICE_ID_LENOVO_TP10UBKBD
:
802 lenovo_led_set_tp10ubkbd(hdev
, tp10ubkbd_led
[led_nr
], value
);
807 static int lenovo_register_leds(struct hid_device
*hdev
)
809 struct lenovo_drvdata
*data
= hid_get_drvdata(hdev
);
810 size_t name_sz
= strlen(dev_name(&hdev
->dev
)) + 16;
811 char *name_mute
, *name_micm
;
814 name_mute
= devm_kzalloc(&hdev
->dev
, name_sz
, GFP_KERNEL
);
815 name_micm
= devm_kzalloc(&hdev
->dev
, name_sz
, GFP_KERNEL
);
816 if (name_mute
== NULL
|| name_micm
== NULL
) {
817 hid_err(hdev
, "Could not allocate memory for led data\n");
820 snprintf(name_mute
, name_sz
, "%s:amber:mute", dev_name(&hdev
->dev
));
821 snprintf(name_micm
, name_sz
, "%s:amber:micmute", dev_name(&hdev
->dev
));
823 data
->led_mute
.name
= name_mute
;
824 data
->led_mute
.brightness_get
= lenovo_led_brightness_get
;
825 data
->led_mute
.brightness_set
= lenovo_led_brightness_set
;
826 data
->led_mute
.dev
= &hdev
->dev
;
827 ret
= led_classdev_register(&hdev
->dev
, &data
->led_mute
);
831 data
->led_micmute
.name
= name_micm
;
832 data
->led_micmute
.brightness_get
= lenovo_led_brightness_get
;
833 data
->led_micmute
.brightness_set
= lenovo_led_brightness_set
;
834 data
->led_micmute
.dev
= &hdev
->dev
;
835 ret
= led_classdev_register(&hdev
->dev
, &data
->led_micmute
);
837 led_classdev_unregister(&data
->led_mute
);
844 static int lenovo_probe_tpkbd(struct hid_device
*hdev
)
846 struct lenovo_drvdata
*data_pointer
;
850 * Only register extra settings against subdevice where input_mapping
851 * set drvdata to 1, i.e. the trackpoint.
853 if (!hid_get_drvdata(hdev
))
856 hid_set_drvdata(hdev
, NULL
);
858 /* Validate required reports. */
859 for (i
= 0; i
< 4; i
++) {
860 if (!hid_validate_values(hdev
, HID_FEATURE_REPORT
, 4, i
, 1))
863 if (!hid_validate_values(hdev
, HID_OUTPUT_REPORT
, 3, 0, 2))
866 ret
= sysfs_create_group(&hdev
->dev
.kobj
, &lenovo_attr_group_tpkbd
);
868 hid_warn(hdev
, "Could not create sysfs group: %d\n", ret
);
870 data_pointer
= devm_kzalloc(&hdev
->dev
,
871 sizeof(struct lenovo_drvdata
),
873 if (data_pointer
== NULL
) {
874 hid_err(hdev
, "Could not allocate memory for driver data\n");
879 // set same default values as windows driver
880 data_pointer
->sensitivity
= 0xa0;
881 data_pointer
->press_speed
= 0x38;
883 hid_set_drvdata(hdev
, data_pointer
);
885 ret
= lenovo_register_leds(hdev
);
889 lenovo_features_set_tpkbd(hdev
);
893 sysfs_remove_group(&hdev
->dev
.kobj
, &lenovo_attr_group_tpkbd
);
897 static int lenovo_probe_cptkbd(struct hid_device
*hdev
)
900 struct lenovo_drvdata
*cptkbd_data
;
902 /* All the custom action happens on the USBMOUSE device for USB */
903 if (hdev
->product
== USB_DEVICE_ID_LENOVO_CUSBKBD
904 && hdev
->type
!= HID_TYPE_USBMOUSE
) {
905 hid_dbg(hdev
, "Ignoring keyboard half of device\n");
909 cptkbd_data
= devm_kzalloc(&hdev
->dev
,
910 sizeof(*cptkbd_data
),
912 if (cptkbd_data
== NULL
) {
913 hid_err(hdev
, "can't alloc keyboard descriptor\n");
916 hid_set_drvdata(hdev
, cptkbd_data
);
919 * Tell the keyboard a driver understands it, and turn F7, F9, F11 into
922 ret
= lenovo_send_cmd_cptkbd(hdev
, 0x01, 0x03);
924 hid_warn(hdev
, "Failed to switch F7/9/11 mode: %d\n", ret
);
926 /* Switch middle button to native mode */
927 ret
= lenovo_send_cmd_cptkbd(hdev
, 0x09, 0x01);
929 hid_warn(hdev
, "Failed to switch middle button: %d\n", ret
);
931 /* Set keyboard settings to known state */
932 cptkbd_data
->middlebutton_state
= 0;
933 cptkbd_data
->fn_lock
= true;
934 cptkbd_data
->sensitivity
= 0x05;
935 lenovo_features_set_cptkbd(hdev
);
937 ret
= sysfs_create_group(&hdev
->dev
.kobj
, &lenovo_attr_group_cptkbd
);
939 hid_warn(hdev
, "Could not create sysfs group: %d\n", ret
);
944 static struct attribute
*lenovo_attributes_tp10ubkbd
[] = {
945 &dev_attr_fn_lock
.attr
,
949 static const struct attribute_group lenovo_attr_group_tp10ubkbd
= {
950 .attrs
= lenovo_attributes_tp10ubkbd
,
953 static int lenovo_probe_tp10ubkbd(struct hid_device
*hdev
)
955 struct lenovo_drvdata
*data
;
958 /* All the custom action happens on the USBMOUSE device for USB */
959 if (hdev
->type
!= HID_TYPE_USBMOUSE
)
962 data
= devm_kzalloc(&hdev
->dev
, sizeof(*data
), GFP_KERNEL
);
966 mutex_init(&data
->led_report_mutex
);
967 INIT_WORK(&data
->fn_lock_sync_work
, lenovo_tp10ubkbd_sync_fn_lock
);
970 hid_set_drvdata(hdev
, data
);
973 * The Thinkpad 10 ultrabook USB kbd dock's Fn-lock defaults to on.
974 * We cannot read the state, only set it, so we force it to on here
975 * (which should be a no-op) to make sure that our state matches the
976 * keyboard's FN-lock state. This is the same as what Windows does.
978 data
->fn_lock
= true;
979 lenovo_led_set_tp10ubkbd(hdev
, TP10UBKBD_FN_LOCK_LED
, data
->fn_lock
);
981 ret
= sysfs_create_group(&hdev
->dev
.kobj
, &lenovo_attr_group_tp10ubkbd
);
985 ret
= lenovo_register_leds(hdev
);
991 sysfs_remove_group(&hdev
->dev
.kobj
, &lenovo_attr_group_tp10ubkbd
);
995 static int lenovo_probe(struct hid_device
*hdev
,
996 const struct hid_device_id
*id
)
1000 ret
= hid_parse(hdev
);
1002 hid_err(hdev
, "hid_parse failed\n");
1006 ret
= hid_hw_start(hdev
, HID_CONNECT_DEFAULT
);
1008 hid_err(hdev
, "hid_hw_start failed\n");
1012 switch (hdev
->product
) {
1013 case USB_DEVICE_ID_LENOVO_TPKBD
:
1014 ret
= lenovo_probe_tpkbd(hdev
);
1016 case USB_DEVICE_ID_LENOVO_CUSBKBD
:
1017 case USB_DEVICE_ID_LENOVO_CBTKBD
:
1018 ret
= lenovo_probe_cptkbd(hdev
);
1020 case USB_DEVICE_ID_LENOVO_TP10UBKBD
:
1021 ret
= lenovo_probe_tp10ubkbd(hdev
);
1037 static void lenovo_remove_tpkbd(struct hid_device
*hdev
)
1039 struct lenovo_drvdata
*data_pointer
= hid_get_drvdata(hdev
);
1042 * Only the trackpoint half of the keyboard has drvdata and stuff that
1043 * needs unregistering.
1045 if (data_pointer
== NULL
)
1048 sysfs_remove_group(&hdev
->dev
.kobj
,
1049 &lenovo_attr_group_tpkbd
);
1051 led_classdev_unregister(&data_pointer
->led_micmute
);
1052 led_classdev_unregister(&data_pointer
->led_mute
);
1055 static void lenovo_remove_cptkbd(struct hid_device
*hdev
)
1057 sysfs_remove_group(&hdev
->dev
.kobj
,
1058 &lenovo_attr_group_cptkbd
);
1061 static void lenovo_remove_tp10ubkbd(struct hid_device
*hdev
)
1063 struct lenovo_drvdata
*data
= hid_get_drvdata(hdev
);
1068 led_classdev_unregister(&data
->led_micmute
);
1069 led_classdev_unregister(&data
->led_mute
);
1071 sysfs_remove_group(&hdev
->dev
.kobj
, &lenovo_attr_group_tp10ubkbd
);
1072 cancel_work_sync(&data
->fn_lock_sync_work
);
1075 static void lenovo_remove(struct hid_device
*hdev
)
1077 switch (hdev
->product
) {
1078 case USB_DEVICE_ID_LENOVO_TPKBD
:
1079 lenovo_remove_tpkbd(hdev
);
1081 case USB_DEVICE_ID_LENOVO_CUSBKBD
:
1082 case USB_DEVICE_ID_LENOVO_CBTKBD
:
1083 lenovo_remove_cptkbd(hdev
);
1085 case USB_DEVICE_ID_LENOVO_TP10UBKBD
:
1086 lenovo_remove_tp10ubkbd(hdev
);
1093 static int lenovo_input_configured(struct hid_device
*hdev
,
1094 struct hid_input
*hi
)
1096 switch (hdev
->product
) {
1097 case USB_DEVICE_ID_LENOVO_TPKBD
:
1098 case USB_DEVICE_ID_LENOVO_CUSBKBD
:
1099 case USB_DEVICE_ID_LENOVO_CBTKBD
:
1100 if (test_bit(EV_REL
, hi
->input
->evbit
)) {
1101 /* set only for trackpoint device */
1102 __set_bit(INPUT_PROP_POINTER
, hi
->input
->propbit
);
1103 __set_bit(INPUT_PROP_POINTING_STICK
,
1104 hi
->input
->propbit
);
1113 static const struct hid_device_id lenovo_devices
[] = {
1114 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO
, USB_DEVICE_ID_LENOVO_TPKBD
) },
1115 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO
, USB_DEVICE_ID_LENOVO_CUSBKBD
) },
1116 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO
, USB_DEVICE_ID_LENOVO_CBTKBD
) },
1117 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO
, USB_DEVICE_ID_LENOVO_TPPRODOCK
) },
1118 { HID_USB_DEVICE(USB_VENDOR_ID_IBM
, USB_DEVICE_ID_IBM_SCROLLPOINT_III
) },
1119 { HID_USB_DEVICE(USB_VENDOR_ID_IBM
, USB_DEVICE_ID_IBM_SCROLLPOINT_PRO
) },
1120 { HID_USB_DEVICE(USB_VENDOR_ID_IBM
, USB_DEVICE_ID_IBM_SCROLLPOINT_OPTICAL
) },
1121 { HID_USB_DEVICE(USB_VENDOR_ID_IBM
, USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL
) },
1122 { HID_USB_DEVICE(USB_VENDOR_ID_IBM
, USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL_PRO
) },
1123 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO
, USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL
) },
1124 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO
, USB_DEVICE_ID_LENOVO_TP10UBKBD
) },
1128 MODULE_DEVICE_TABLE(hid
, lenovo_devices
);
1130 static struct hid_driver lenovo_driver
= {
1132 .id_table
= lenovo_devices
,
1133 .input_configured
= lenovo_input_configured
,
1134 .input_mapping
= lenovo_input_mapping
,
1135 .probe
= lenovo_probe
,
1136 .remove
= lenovo_remove
,
1137 .raw_event
= lenovo_raw_event
,
1138 .event
= lenovo_event
,
1139 .report_fixup
= lenovo_report_fixup
,
1141 module_hid_driver(lenovo_driver
);
1143 MODULE_LICENSE("GPL");