Lines Matching +full:middle +full:- +full:button
1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * - ThinkPad USB Keyboard with TrackPoint (tpkbd)
5 * - ThinkPad Compact Bluetooth Keyboard with TrackPoint (cptkbd)
6 * - ThinkPad Compact USB Keyboard with TrackPoint (cptkbd)
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
34 #include "hid-ids.h"
36 /* Userspace expects F20 for mic-mute KEY_MICMUTE does not work */
79 mutex_lock(&data->led_report_mutex); in lenovo_led_set_tp10ubkbd()
81 data->led_report[0] = TP10UBKBD_LED_OUTPUT_REPORT; in lenovo_led_set_tp10ubkbd()
82 data->led_report[1] = led_code; in lenovo_led_set_tp10ubkbd()
83 data->led_report[2] = value ? TP10UBKBD_LED_ON : TP10UBKBD_LED_OFF; in lenovo_led_set_tp10ubkbd()
84 ret = hid_hw_raw_request(hdev, data->led_report[0], data->led_report, 3, in lenovo_led_set_tp10ubkbd()
87 if (ret != -ENODEV) in lenovo_led_set_tp10ubkbd()
90 ret = ret < 0 ? ret : -EIO; in lenovo_led_set_tp10ubkbd()
95 mutex_unlock(&data->led_report_mutex); in lenovo_led_set_tp10ubkbd()
105 lenovo_led_set_tp10ubkbd(data->hdev, TP10UBKBD_FN_LOCK_LED, in lenovo_tp10ubkbd_sync_fn_lock()
106 data->fn_lock); in lenovo_tp10ubkbd_sync_fn_lock()
121 switch (hdev->product) { in lenovo_report_fixup()
124 * - get a reasonable usage max for the vendor collection in lenovo_report_fixup()
142 if (usage->hid == (HID_UP_BUTTON | 0x0010)) { in lenovo_input_mapping_tpkbd()
143 /* This sub-device contains trackpoint, mark it */ in lenovo_input_mapping_tpkbd()
156 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR || in lenovo_input_mapping_cptkbd()
157 (usage->hid & HID_USAGE_PAGE) == HID_UP_LNVENDOR) { in lenovo_input_mapping_cptkbd()
158 switch (usage->hid & HID_USAGE) { in lenovo_input_mapping_cptkbd()
159 case 0x00f1: /* Fn-F4: Mic mute */ in lenovo_input_mapping_cptkbd()
162 case 0x00f2: /* Fn-F5: Brightness down */ in lenovo_input_mapping_cptkbd()
165 case 0x00f3: /* Fn-F6: Brightness up */ in lenovo_input_mapping_cptkbd()
168 case 0x00f4: /* Fn-F7: External display (projector) */ in lenovo_input_mapping_cptkbd()
171 case 0x00f5: /* Fn-F8: Wireless */ in lenovo_input_mapping_cptkbd()
174 case 0x00f6: /* Fn-F9: Control panel */ in lenovo_input_mapping_cptkbd()
177 case 0x00f8: /* Fn-F11: View open applications (3 boxes) */ in lenovo_input_mapping_cptkbd()
180 case 0x00f9: /* Fn-F12: Open My computer (6 boxes) USB-only */ in lenovo_input_mapping_cptkbd()
184 case 0x00fa: /* Fn-Esc: Fn-lock toggle */ in lenovo_input_mapping_cptkbd()
187 case 0x00fb: /* Middle mouse button (in native mode) */ in lenovo_input_mapping_cptkbd()
193 /* Compatibility middle/wheel mappings should be ignored */ in lenovo_input_mapping_cptkbd()
194 if (usage->hid == HID_GD_WHEEL) in lenovo_input_mapping_cptkbd()
195 return -1; in lenovo_input_mapping_cptkbd()
196 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON && in lenovo_input_mapping_cptkbd()
197 (usage->hid & HID_USAGE) == 0x003) in lenovo_input_mapping_cptkbd()
198 return -1; in lenovo_input_mapping_cptkbd()
199 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER && in lenovo_input_mapping_cptkbd()
200 (usage->hid & HID_USAGE) == 0x238) in lenovo_input_mapping_cptkbd()
201 return -1; in lenovo_input_mapping_cptkbd()
204 if ((usage->hid & HID_USAGE_PAGE) == 0xff100000 || in lenovo_input_mapping_cptkbd()
205 (usage->hid & HID_USAGE_PAGE) == 0xffa10000) { in lenovo_input_mapping_cptkbd()
206 field->flags |= HID_MAIN_ITEM_RELATIVE | HID_MAIN_ITEM_VARIABLE; in lenovo_input_mapping_cptkbd()
207 field->logical_minimum = -127; in lenovo_input_mapping_cptkbd()
208 field->logical_maximum = 127; in lenovo_input_mapping_cptkbd()
210 switch (usage->hid & HID_USAGE) { in lenovo_input_mapping_cptkbd()
218 return -1; in lenovo_input_mapping_cptkbd()
229 if (usage->hid == HID_GD_Z) { in lenovo_input_mapping_scrollpoint()
244 if (usage->hid == 0x000c0001) { in lenovo_input_mapping_tp10_ultrabook_kbd()
245 switch (usage->usage_index) { in lenovo_input_mapping_tp10_ultrabook_kbd()
246 case 8: /* Fn-Esc: Fn-lock toggle */ in lenovo_input_mapping_tp10_ultrabook_kbd()
249 case 9: /* Fn-F4: Mic mute */ in lenovo_input_mapping_tp10_ultrabook_kbd()
252 case 10: /* Fn-F7: Control panel */ in lenovo_input_mapping_tp10_ultrabook_kbd()
255 case 11: /* Fn-F8: Search (magnifier glass) */ in lenovo_input_mapping_tp10_ultrabook_kbd()
258 case 12: /* Fn-F10: Open My computer (6 boxes) */ in lenovo_input_mapping_tp10_ultrabook_kbd()
265 * The Ultrabook Keyboard sends a spurious F23 key-press when resuming in lenovo_input_mapping_tp10_ultrabook_kbd()
268 if (usage->hid == 0x00070072) in lenovo_input_mapping_tp10_ultrabook_kbd()
269 return -1; in lenovo_input_mapping_tp10_ultrabook_kbd()
278 switch (hdev->product) { in lenovo_input_mapping()
313 return -ENOMEM; in lenovo_send_cmd_cptkbd()
319 switch (hdev->product) { in lenovo_send_cmd_cptkbd()
328 ret = -EINVAL; in lenovo_send_cmd_cptkbd()
342 ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock); in lenovo_features_set_cptkbd()
344 hid_err(hdev, "Fn-lock setting failed: %d\n", ret); in lenovo_features_set_cptkbd()
346 ret = lenovo_send_cmd_cptkbd(hdev, 0x02, cptkbd_data->sensitivity); in lenovo_features_set_cptkbd()
358 return snprintf(buf, PAGE_SIZE, "%u\n", data->fn_lock); in attr_fn_lock_show()
371 return -EINVAL; in attr_fn_lock_store()
373 return -EINVAL; in attr_fn_lock_store()
375 data->fn_lock = !!value; in attr_fn_lock_store()
377 switch (hdev->product) { in attr_fn_lock_store()
400 cptkbd_data->sensitivity); in attr_sensitivity_show_cptkbd()
413 return -EINVAL; in attr_sensitivity_store_cptkbd()
415 cptkbd_data->sensitivity = value; in attr_sensitivity_store_cptkbd()
447 * Compact USB keyboard's Fn-F12 report holds down many other keys, and in lenovo_raw_event()
451 if (unlikely(hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD in lenovo_raw_event()
468 if (usage->type == EV_KEY && usage->code == KEY_FN_ESC && value == 1) { in lenovo_event_tp10ubkbd()
470 * The user has toggled the Fn-lock state. Toggle our own in lenovo_event_tp10ubkbd()
472 * ensure things are in sync (the sycning should be a no-op). in lenovo_event_tp10ubkbd()
474 data->fn_lock = !data->fn_lock; in lenovo_event_tp10ubkbd()
475 schedule_work(&data->fn_lock_sync_work); in lenovo_event_tp10ubkbd()
486 if (cptkbd_data->middlebutton_state != 3) { in lenovo_event_cptkbd()
487 /* REL_X and REL_Y events during middle button pressed in lenovo_event_cptkbd()
488 * are only possible on patched, bug-free firmware in lenovo_event_cptkbd()
492 if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD && in lenovo_event_cptkbd()
493 cptkbd_data->middlebutton_state == 1 && in lenovo_event_cptkbd()
494 usage->type == EV_REL && in lenovo_event_cptkbd()
495 (usage->code == REL_X || usage->code == REL_Y)) { in lenovo_event_cptkbd()
496 cptkbd_data->middlebutton_state = 3; in lenovo_event_cptkbd()
497 /* send middle button press which was hold before */ in lenovo_event_cptkbd()
498 input_event(field->hidinput->input, in lenovo_event_cptkbd()
500 input_sync(field->hidinput->input); in lenovo_event_cptkbd()
504 if (usage->type == EV_REL && (usage->code == REL_WHEEL || in lenovo_event_cptkbd()
505 usage->code == REL_HWHEEL)) { in lenovo_event_cptkbd()
506 /* Scroll events disable middle-click event */ in lenovo_event_cptkbd()
507 cptkbd_data->middlebutton_state = 2; in lenovo_event_cptkbd()
511 /* Middle click events */ in lenovo_event_cptkbd()
512 if (usage->type == EV_KEY && usage->code == BTN_MIDDLE) { in lenovo_event_cptkbd()
514 cptkbd_data->middlebutton_state = 1; in lenovo_event_cptkbd()
516 if (cptkbd_data->middlebutton_state == 1) { in lenovo_event_cptkbd()
517 /* No scrolling inbetween, send middle-click */ in lenovo_event_cptkbd()
518 input_event(field->hidinput->input, in lenovo_event_cptkbd()
520 input_sync(field->hidinput->input); in lenovo_event_cptkbd()
521 input_event(field->hidinput->input, in lenovo_event_cptkbd()
523 input_sync(field->hidinput->input); in lenovo_event_cptkbd()
525 cptkbd_data->middlebutton_state = 0; in lenovo_event_cptkbd()
540 switch (hdev->product) { in lenovo_event()
556 report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[4]; in lenovo_features_set_tpkbd()
558 report->field[0]->value[0] = data_pointer->press_to_select ? 0x01 : 0x02; in lenovo_features_set_tpkbd()
559 report->field[0]->value[0] |= data_pointer->dragging ? 0x04 : 0x08; in lenovo_features_set_tpkbd()
560 report->field[0]->value[0] |= data_pointer->release_to_select ? 0x10 : 0x20; in lenovo_features_set_tpkbd()
561 report->field[0]->value[0] |= data_pointer->select_right ? 0x80 : 0x40; in lenovo_features_set_tpkbd()
562 report->field[1]->value[0] = 0x03; // unknown setting, imitate windows driver in lenovo_features_set_tpkbd()
563 report->field[2]->value[0] = data_pointer->sensitivity; in lenovo_features_set_tpkbd()
564 report->field[3]->value[0] = data_pointer->press_speed; in lenovo_features_set_tpkbd()
577 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->press_to_select); in attr_press_to_select_show_tpkbd()
590 return -EINVAL; in attr_press_to_select_store_tpkbd()
592 return -EINVAL; in attr_press_to_select_store_tpkbd()
594 data_pointer->press_to_select = value; in attr_press_to_select_store_tpkbd()
607 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->dragging); in attr_dragging_show_tpkbd()
620 return -EINVAL; in attr_dragging_store_tpkbd()
622 return -EINVAL; in attr_dragging_store_tpkbd()
624 data_pointer->dragging = value; in attr_dragging_store_tpkbd()
637 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->release_to_select); in attr_release_to_select_show_tpkbd()
650 return -EINVAL; in attr_release_to_select_store_tpkbd()
652 return -EINVAL; in attr_release_to_select_store_tpkbd()
654 data_pointer->release_to_select = value; in attr_release_to_select_store_tpkbd()
667 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->select_right); in attr_select_right_show_tpkbd()
680 return -EINVAL; in attr_select_right_store_tpkbd()
682 return -EINVAL; in attr_select_right_store_tpkbd()
684 data_pointer->select_right = value; in attr_select_right_store_tpkbd()
698 data_pointer->sensitivity); in attr_sensitivity_show_tpkbd()
711 return -EINVAL; in attr_sensitivity_store_tpkbd()
713 data_pointer->sensitivity = value; in attr_sensitivity_store_tpkbd()
727 data_pointer->press_speed); in attr_press_speed_show_tpkbd()
740 return -EINVAL; in attr_press_speed_store_tpkbd()
742 data_pointer->press_speed = value; in attr_press_speed_store_tpkbd()
797 report = hdev->report_enum[HID_OUTPUT_REPORT].report_id_hash[3]; in lenovo_led_set_tpkbd()
798 report->field[0]->value[0] = (data_pointer->led_state >> 0) & 1; in lenovo_led_set_tpkbd()
799 report->field[0]->value[1] = (data_pointer->led_state >> 1) & 1; in lenovo_led_set_tpkbd()
806 struct device *dev = led_cdev->dev->parent; in lenovo_led_brightness_get()
811 if (led_cdev == &data_pointer->led_micmute) in lenovo_led_brightness_get()
814 return data_pointer->led_state & (1 << led_nr) in lenovo_led_brightness_get()
822 struct device *dev = led_cdev->dev->parent; in lenovo_led_brightness_set()
829 if (led_cdev == &data_pointer->led_micmute) in lenovo_led_brightness_set()
833 data_pointer->led_state &= ~(1 << led_nr); in lenovo_led_brightness_set()
835 data_pointer->led_state |= 1 << led_nr; in lenovo_led_brightness_set()
837 switch (hdev->product) { in lenovo_led_brightness_set()
852 size_t name_sz = strlen(dev_name(&hdev->dev)) + 16; in lenovo_register_leds()
856 name_mute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL); in lenovo_register_leds()
857 name_micm = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL); in lenovo_register_leds()
860 return -ENOMEM; in lenovo_register_leds()
862 snprintf(name_mute, name_sz, "%s:amber:mute", dev_name(&hdev->dev)); in lenovo_register_leds()
863 snprintf(name_micm, name_sz, "%s:amber:micmute", dev_name(&hdev->dev)); in lenovo_register_leds()
865 data->led_mute.name = name_mute; in lenovo_register_leds()
866 data->led_mute.brightness_get = lenovo_led_brightness_get; in lenovo_register_leds()
867 data->led_mute.brightness_set_blocking = lenovo_led_brightness_set; in lenovo_register_leds()
868 data->led_mute.flags = LED_HW_PLUGGABLE; in lenovo_register_leds()
869 data->led_mute.dev = &hdev->dev; in lenovo_register_leds()
870 ret = led_classdev_register(&hdev->dev, &data->led_mute); in lenovo_register_leds()
874 data->led_micmute.name = name_micm; in lenovo_register_leds()
875 data->led_micmute.brightness_get = lenovo_led_brightness_get; in lenovo_register_leds()
876 data->led_micmute.brightness_set_blocking = lenovo_led_brightness_set; in lenovo_register_leds()
877 data->led_micmute.flags = LED_HW_PLUGGABLE; in lenovo_register_leds()
878 data->led_micmute.dev = &hdev->dev; in lenovo_register_leds()
879 ret = led_classdev_register(&hdev->dev, &data->led_micmute); in lenovo_register_leds()
881 led_classdev_unregister(&data->led_mute); in lenovo_register_leds()
905 return -ENODEV; in lenovo_probe_tpkbd()
908 return -ENODEV; in lenovo_probe_tpkbd()
910 ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_tpkbd); in lenovo_probe_tpkbd()
914 data_pointer = devm_kzalloc(&hdev->dev, in lenovo_probe_tpkbd()
919 ret = -ENOMEM; in lenovo_probe_tpkbd()
924 data_pointer->sensitivity = 0xa0; in lenovo_probe_tpkbd()
925 data_pointer->press_speed = 0x38; in lenovo_probe_tpkbd()
937 sysfs_remove_group(&hdev->dev.kobj, &lenovo_attr_group_tpkbd); in lenovo_probe_tpkbd()
947 if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD in lenovo_probe_cptkbd()
948 && hdev->type != HID_TYPE_USBMOUSE) { in lenovo_probe_cptkbd()
953 cptkbd_data = devm_kzalloc(&hdev->dev, in lenovo_probe_cptkbd()
958 return -ENOMEM; in lenovo_probe_cptkbd()
970 /* Switch middle button to native mode */ in lenovo_probe_cptkbd()
973 hid_warn(hdev, "Failed to switch middle button: %d\n", ret); in lenovo_probe_cptkbd()
976 cptkbd_data->middlebutton_state = 0; in lenovo_probe_cptkbd()
977 cptkbd_data->fn_lock = true; in lenovo_probe_cptkbd()
978 cptkbd_data->sensitivity = 0x05; in lenovo_probe_cptkbd()
981 ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd); in lenovo_probe_cptkbd()
1003 if (hdev->type != HID_TYPE_USBMOUSE) in lenovo_probe_tp10ubkbd()
1006 data = devm_kzalloc(&hdev->dev, sizeof(*data), GFP_KERNEL); in lenovo_probe_tp10ubkbd()
1008 return -ENOMEM; in lenovo_probe_tp10ubkbd()
1010 mutex_init(&data->led_report_mutex); in lenovo_probe_tp10ubkbd()
1011 INIT_WORK(&data->fn_lock_sync_work, lenovo_tp10ubkbd_sync_fn_lock); in lenovo_probe_tp10ubkbd()
1012 data->hdev = hdev; in lenovo_probe_tp10ubkbd()
1017 * The Thinkpad 10 ultrabook USB kbd dock's Fn-lock defaults to on. in lenovo_probe_tp10ubkbd()
1019 * (which should be a no-op) to make sure that our state matches the in lenovo_probe_tp10ubkbd()
1020 * keyboard's FN-lock state. This is the same as what Windows does. in lenovo_probe_tp10ubkbd()
1022 data->fn_lock = true; in lenovo_probe_tp10ubkbd()
1023 lenovo_led_set_tp10ubkbd(hdev, TP10UBKBD_FN_LOCK_LED, data->fn_lock); in lenovo_probe_tp10ubkbd()
1025 ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_tp10ubkbd); in lenovo_probe_tp10ubkbd()
1035 sysfs_remove_group(&hdev->dev.kobj, &lenovo_attr_group_tp10ubkbd); in lenovo_probe_tp10ubkbd()
1056 switch (hdev->product) { in lenovo_probe()
1092 sysfs_remove_group(&hdev->dev.kobj, in lenovo_remove_tpkbd()
1095 led_classdev_unregister(&data_pointer->led_micmute); in lenovo_remove_tpkbd()
1096 led_classdev_unregister(&data_pointer->led_mute); in lenovo_remove_tpkbd()
1101 sysfs_remove_group(&hdev->dev.kobj, in lenovo_remove_cptkbd()
1112 led_classdev_unregister(&data->led_micmute); in lenovo_remove_tp10ubkbd()
1113 led_classdev_unregister(&data->led_mute); in lenovo_remove_tp10ubkbd()
1115 sysfs_remove_group(&hdev->dev.kobj, &lenovo_attr_group_tp10ubkbd); in lenovo_remove_tp10ubkbd()
1116 cancel_work_sync(&data->fn_lock_sync_work); in lenovo_remove_tp10ubkbd()
1121 switch (hdev->product) { in lenovo_remove()
1140 switch (hdev->product) { in lenovo_input_configured()
1144 if (test_bit(EV_REL, hi->input->evbit)) { in lenovo_input_configured()
1146 __set_bit(INPUT_PROP_POINTER, hi->input->propbit); in lenovo_input_configured()
1148 hi->input->propbit); in lenovo_input_configured()