1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 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) 7 * 8 * Copyright (c) 2012 Bernhard Seibold 9 * Copyright (c) 2014 Jamie Lentin <jm@lentin.co.uk> 10 * 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 18 * 19 * Copyright (c) 2012 Peter De Wachter <pdewacht@gmail.com> 20 * Copyright (c) 2018 Peter Ganzhorn <peter.ganzhorn@gmail.com> 21 */ 22 23/* 24 */ 25 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> 33 34#include "hid-ids.h" 35 36/* Userspace expects F20 for mic-mute KEY_MICMUTE does not work */ 37#define LENOVO_KEY_MICMUTE KEY_F20 38 39struct lenovo_drvdata { 40 u8 led_report[3]; /* Must be first for proper alignment */ 41 int led_state; 42 struct mutex led_report_mutex; 43 struct led_classdev led_mute; 44 struct led_classdev led_micmute; 45 struct work_struct fn_lock_sync_work; 46 struct hid_device *hdev; 47 int press_to_select; 48 int dragging; 49 int release_to_select; 50 int select_right; 51 int sensitivity; 52 int press_speed; 53 /* 0: Up 54 * 1: Down (undecided) 55 * 2: Scrolling 56 * 3: Patched firmware, disable workaround 57 */ 58 u8 middlebutton_state; 59 bool fn_lock; 60}; 61 62#define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c)) 63 64#define TP10UBKBD_LED_OUTPUT_REPORT 9 65 66#define TP10UBKBD_FN_LOCK_LED 0x54 67#define TP10UBKBD_MUTE_LED 0x64 68#define TP10UBKBD_MICMUTE_LED 0x74 69 70#define TP10UBKBD_LED_OFF 1 71#define TP10UBKBD_LED_ON 2 72 73static int lenovo_led_set_tp10ubkbd(struct hid_device *hdev, u8 led_code, 74 enum led_brightness value) 75{ 76 struct lenovo_drvdata *data = hid_get_drvdata(hdev); 77 int ret; 78 79 mutex_lock(&data->led_report_mutex); 80 81 data->led_report[0] = TP10UBKBD_LED_OUTPUT_REPORT; 82 data->led_report[1] = led_code; 83 data->led_report[2] = value ? TP10UBKBD_LED_ON : TP10UBKBD_LED_OFF; 84 ret = hid_hw_raw_request(hdev, data->led_report[0], data->led_report, 3, 85 HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); 86 if (ret != 3) { 87 if (ret != -ENODEV) 88 hid_err(hdev, "Set LED output report error: %d\n", ret); 89 90 ret = ret < 0 ? ret : -EIO; 91 } else { 92 ret = 0; 93 } 94 95 mutex_unlock(&data->led_report_mutex); 96 97 return ret; 98} 99 100static void lenovo_tp10ubkbd_sync_fn_lock(struct work_struct *work) 101{ 102 struct lenovo_drvdata *data = 103 container_of(work, struct lenovo_drvdata, fn_lock_sync_work); 104 105 lenovo_led_set_tp10ubkbd(data->hdev, TP10UBKBD_FN_LOCK_LED, 106 data->fn_lock); 107} 108 109static const __u8 lenovo_pro_dock_need_fixup_collection[] = { 110 0x05, 0x88, /* Usage Page (Vendor Usage Page 0x88) */ 111 0x09, 0x01, /* Usage (Vendor Usage 0x01) */ 112 0xa1, 0x01, /* Collection (Application) */ 113 0x85, 0x04, /* Report ID (4) */ 114 0x19, 0x00, /* Usage Minimum (0) */ 115 0x2a, 0xff, 0xff, /* Usage Maximum (65535) */ 116}; 117 118static __u8 *lenovo_report_fixup(struct hid_device *hdev, __u8 *rdesc, 119 unsigned int *rsize) 120{ 121 switch (hdev->product) { 122 case USB_DEVICE_ID_LENOVO_TPPRODOCK: 123 /* the fixups that need to be done: 124 * - get a reasonable usage max for the vendor collection 125 * 0x8801 from the report ID 4 126 */ 127 if (*rsize >= 153 && 128 memcmp(&rdesc[140], lenovo_pro_dock_need_fixup_collection, 129 sizeof(lenovo_pro_dock_need_fixup_collection)) == 0) { 130 rdesc[151] = 0x01; 131 rdesc[152] = 0x00; 132 } 133 break; 134 } 135 return rdesc; 136} 137 138static int lenovo_input_mapping_tpkbd(struct hid_device *hdev, 139 struct hid_input *hi, struct hid_field *field, 140 struct hid_usage *usage, unsigned long **bit, int *max) 141{ 142 if (usage->hid == (HID_UP_BUTTON | 0x0010)) { 143 /* This sub-device contains trackpoint, mark it */ 144 hid_set_drvdata(hdev, (void *)1); 145 map_key_clear(LENOVO_KEY_MICMUTE); 146 return 1; 147 } 148 return 0; 149} 150 151static int lenovo_input_mapping_cptkbd(struct hid_device *hdev, 152 struct hid_input *hi, struct hid_field *field, 153 struct hid_usage *usage, unsigned long **bit, int *max) 154{ 155 /* HID_UP_LNVENDOR = USB, HID_UP_MSVENDOR = BT */ 156 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR || 157 (usage->hid & HID_USAGE_PAGE) == HID_UP_LNVENDOR) { 158 switch (usage->hid & HID_USAGE) { 159 case 0x00f1: /* Fn-F4: Mic mute */ 160 map_key_clear(LENOVO_KEY_MICMUTE); 161 return 1; 162 case 0x00f2: /* Fn-F5: Brightness down */ 163 map_key_clear(KEY_BRIGHTNESSDOWN); 164 return 1; 165 case 0x00f3: /* Fn-F6: Brightness up */ 166 map_key_clear(KEY_BRIGHTNESSUP); 167 return 1; 168 case 0x00f4: /* Fn-F7: External display (projector) */ 169 map_key_clear(KEY_SWITCHVIDEOMODE); 170 return 1; 171 case 0x00f5: /* Fn-F8: Wireless */ 172 map_key_clear(KEY_WLAN); 173 return 1; 174 case 0x00f6: /* Fn-F9: Control panel */ 175 map_key_clear(KEY_CONFIG); 176 return 1; 177 case 0x00f8: /* Fn-F11: View open applications (3 boxes) */ 178 map_key_clear(KEY_SCALE); 179 return 1; 180 case 0x00f9: /* Fn-F12: Open My computer (6 boxes) USB-only */ 181 /* NB: This mapping is invented in raw_event below */ 182 map_key_clear(KEY_FILE); 183 return 1; 184 case 0x00fa: /* Fn-Esc: Fn-lock toggle */ 185 map_key_clear(KEY_FN_ESC); 186 return 1; 187 case 0x00fb: /* Middle mouse button (in native mode) */ 188 map_key_clear(BTN_MIDDLE); 189 return 1; 190 } 191 } 192 193 /* Compatibility middle/wheel mappings should be ignored */ 194 if (usage->hid == HID_GD_WHEEL) 195 return -1; 196 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON && 197 (usage->hid & HID_USAGE) == 0x003) 198 return -1; 199 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER && 200 (usage->hid & HID_USAGE) == 0x238) 201 return -1; 202 203 /* Map wheel emulation reports: 0xffa1 = USB, 0xff10 = BT */ 204 if ((usage->hid & HID_USAGE_PAGE) == 0xff100000 || 205 (usage->hid & HID_USAGE_PAGE) == 0xffa10000) { 206 field->flags |= HID_MAIN_ITEM_RELATIVE | HID_MAIN_ITEM_VARIABLE; 207 field->logical_minimum = -127; 208 field->logical_maximum = 127; 209 210 switch (usage->hid & HID_USAGE) { 211 case 0x0000: 212 hid_map_usage(hi, usage, bit, max, EV_REL, REL_HWHEEL); 213 return 1; 214 case 0x0001: 215 hid_map_usage(hi, usage, bit, max, EV_REL, REL_WHEEL); 216 return 1; 217 default: 218 return -1; 219 } 220 } 221 222 return 0; 223} 224 225static int lenovo_input_mapping_scrollpoint(struct hid_device *hdev, 226 struct hid_input *hi, struct hid_field *field, 227 struct hid_usage *usage, unsigned long **bit, int *max) 228{ 229 if (usage->hid == HID_GD_Z) { 230 hid_map_usage(hi, usage, bit, max, EV_REL, REL_HWHEEL); 231 return 1; 232 } 233 return 0; 234} 235 236static int lenovo_input_mapping_tp10_ultrabook_kbd(struct hid_device *hdev, 237 struct hid_input *hi, struct hid_field *field, 238 struct hid_usage *usage, unsigned long **bit, int *max) 239{ 240 /* 241 * The ThinkPad 10 Ultrabook Keyboard uses 0x000c0001 usage for 242 * a bunch of keys which have no standard consumer page code. 243 */ 244 if (usage->hid == 0x000c0001) { 245 switch (usage->usage_index) { 246 case 8: /* Fn-Esc: Fn-lock toggle */ 247 map_key_clear(KEY_FN_ESC); 248 return 1; 249 case 9: /* Fn-F4: Mic mute */ 250 map_key_clear(LENOVO_KEY_MICMUTE); 251 return 1; 252 case 10: /* Fn-F7: Control panel */ 253 map_key_clear(KEY_CONFIG); 254 return 1; 255 case 11: /* Fn-F8: Search (magnifier glass) */ 256 map_key_clear(KEY_SEARCH); 257 return 1; 258 case 12: /* Fn-F10: Open My computer (6 boxes) */ 259 map_key_clear(KEY_FILE); 260 return 1; 261 } 262 } 263 264 /* 265 * The Ultrabook Keyboard sends a spurious F23 key-press when resuming 266 * from suspend and it does not actually have a F23 key, ignore it. 267 */ 268 if (usage->hid == 0x00070072) 269 return -1; 270 271 return 0; 272} 273 274static int lenovo_input_mapping(struct hid_device *hdev, 275 struct hid_input *hi, struct hid_field *field, 276 struct hid_usage *usage, unsigned long **bit, int *max) 277{ 278 switch (hdev->product) { 279 case USB_DEVICE_ID_LENOVO_TPKBD: 280 return lenovo_input_mapping_tpkbd(hdev, hi, field, 281 usage, bit, max); 282 case USB_DEVICE_ID_LENOVO_CUSBKBD: 283 case USB_DEVICE_ID_LENOVO_CBTKBD: 284 return lenovo_input_mapping_cptkbd(hdev, hi, field, 285 usage, bit, max); 286 case USB_DEVICE_ID_IBM_SCROLLPOINT_III: 287 case USB_DEVICE_ID_IBM_SCROLLPOINT_PRO: 288 case USB_DEVICE_ID_IBM_SCROLLPOINT_OPTICAL: 289 case USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL: 290 case USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL_PRO: 291 case USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL: 292 return lenovo_input_mapping_scrollpoint(hdev, hi, field, 293 usage, bit, max); 294 case USB_DEVICE_ID_LENOVO_TP10UBKBD: 295 return lenovo_input_mapping_tp10_ultrabook_kbd(hdev, hi, field, 296 usage, bit, max); 297 default: 298 return 0; 299 } 300} 301 302#undef map_key_clear 303 304/* Send a config command to the keyboard */ 305static int lenovo_send_cmd_cptkbd(struct hid_device *hdev, 306 unsigned char byte2, unsigned char byte3) 307{ 308 int ret; 309 unsigned char *buf; 310 311 buf = kzalloc(3, GFP_KERNEL); 312 if (!buf) 313 return -ENOMEM; 314 315 buf[0] = 0x18; 316 buf[1] = byte2; 317 buf[2] = byte3; 318 319 switch (hdev->product) { 320 case USB_DEVICE_ID_LENOVO_CUSBKBD: 321 ret = hid_hw_raw_request(hdev, 0x13, buf, 3, 322 HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 323 break; 324 case USB_DEVICE_ID_LENOVO_CBTKBD: 325 ret = hid_hw_output_report(hdev, buf, 3); 326 break; 327 default: 328 ret = -EINVAL; 329 break; 330 } 331 332 kfree(buf); 333 334 return ret < 0 ? ret : 0; /* BT returns 0, USB returns sizeof(buf) */ 335} 336 337static void lenovo_features_set_cptkbd(struct hid_device *hdev) 338{ 339 int ret; 340 struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev); 341 342 ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock); 343 if (ret) 344 hid_err(hdev, "Fn-lock setting failed: %d\n", ret); 345 346 ret = lenovo_send_cmd_cptkbd(hdev, 0x02, cptkbd_data->sensitivity); 347 if (ret) 348 hid_err(hdev, "Sensitivity setting failed: %d\n", ret); 349} 350 351static ssize_t attr_fn_lock_show(struct device *dev, 352 struct device_attribute *attr, 353 char *buf) 354{ 355 struct hid_device *hdev = to_hid_device(dev); 356 struct lenovo_drvdata *data = hid_get_drvdata(hdev); 357 358 return snprintf(buf, PAGE_SIZE, "%u\n", data->fn_lock); 359} 360 361static ssize_t attr_fn_lock_store(struct device *dev, 362 struct device_attribute *attr, 363 const char *buf, 364 size_t count) 365{ 366 struct hid_device *hdev = to_hid_device(dev); 367 struct lenovo_drvdata *data = hid_get_drvdata(hdev); 368 int value, ret; 369 370 if (kstrtoint(buf, 10, &value)) 371 return -EINVAL; 372 if (value < 0 || value > 1) 373 return -EINVAL; 374 375 data->fn_lock = !!value; 376 377 switch (hdev->product) { 378 case USB_DEVICE_ID_LENOVO_CUSBKBD: 379 case USB_DEVICE_ID_LENOVO_CBTKBD: 380 lenovo_features_set_cptkbd(hdev); 381 break; 382 case USB_DEVICE_ID_LENOVO_TP10UBKBD: 383 ret = lenovo_led_set_tp10ubkbd(hdev, TP10UBKBD_FN_LOCK_LED, value); 384 if (ret) 385 return ret; 386 break; 387 } 388 389 return count; 390} 391 392static ssize_t attr_sensitivity_show_cptkbd(struct device *dev, 393 struct device_attribute *attr, 394 char *buf) 395{ 396 struct hid_device *hdev = to_hid_device(dev); 397 struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev); 398 399 return snprintf(buf, PAGE_SIZE, "%u\n", 400 cptkbd_data->sensitivity); 401} 402 403static ssize_t attr_sensitivity_store_cptkbd(struct device *dev, 404 struct device_attribute *attr, 405 const char *buf, 406 size_t count) 407{ 408 struct hid_device *hdev = to_hid_device(dev); 409 struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev); 410 int value; 411 412 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255) 413 return -EINVAL; 414 415 cptkbd_data->sensitivity = value; 416 lenovo_features_set_cptkbd(hdev); 417 418 return count; 419} 420 421 422static struct device_attribute dev_attr_fn_lock = 423 __ATTR(fn_lock, S_IWUSR | S_IRUGO, 424 attr_fn_lock_show, 425 attr_fn_lock_store); 426 427static struct device_attribute dev_attr_sensitivity_cptkbd = 428 __ATTR(sensitivity, S_IWUSR | S_IRUGO, 429 attr_sensitivity_show_cptkbd, 430 attr_sensitivity_store_cptkbd); 431 432 433static struct attribute *lenovo_attributes_cptkbd[] = { 434 &dev_attr_fn_lock.attr, 435 &dev_attr_sensitivity_cptkbd.attr, 436 NULL 437}; 438 439static const struct attribute_group lenovo_attr_group_cptkbd = { 440 .attrs = lenovo_attributes_cptkbd, 441}; 442 443static int lenovo_raw_event(struct hid_device *hdev, 444 struct hid_report *report, u8 *data, int size) 445{ 446 /* 447 * Compact USB keyboard's Fn-F12 report holds down many other keys, and 448 * its own key is outside the usage page range. Remove extra 449 * keypresses and remap to inside usage page. 450 */ 451 if (unlikely(hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD 452 && size == 3 453 && data[0] == 0x15 454 && data[1] == 0x94 455 && data[2] == 0x01)) { 456 data[1] = 0x00; 457 data[2] = 0x01; 458 } 459 460 return 0; 461} 462 463static int lenovo_event_tp10ubkbd(struct hid_device *hdev, 464 struct hid_field *field, struct hid_usage *usage, __s32 value) 465{ 466 struct lenovo_drvdata *data = hid_get_drvdata(hdev); 467 468 if (usage->type == EV_KEY && usage->code == KEY_FN_ESC && value == 1) { 469 /* 470 * The user has toggled the Fn-lock state. Toggle our own 471 * cached value of it and sync our value to the keyboard to 472 * ensure things are in sync (the sycning should be a no-op). 473 */ 474 data->fn_lock = !data->fn_lock; 475 schedule_work(&data->fn_lock_sync_work); 476 } 477 478 return 0; 479} 480 481static int lenovo_event_cptkbd(struct hid_device *hdev, 482 struct hid_field *field, struct hid_usage *usage, __s32 value) 483{ 484 struct lenovo_drvdata *cptkbd_data = hid_get_drvdata(hdev); 485 486 if (cptkbd_data->middlebutton_state != 3) { 487 /* REL_X and REL_Y events during middle button pressed 488 * are only possible on patched, bug-free firmware 489 * so set middlebutton_state to 3 490 * to never apply workaround anymore 491 */ 492 if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD && 493 cptkbd_data->middlebutton_state == 1 && 494 usage->type == EV_REL && 495 (usage->code == REL_X || usage->code == REL_Y)) { 496 cptkbd_data->middlebutton_state = 3; 497 /* send middle button press which was hold before */ 498 input_event(field->hidinput->input, 499 EV_KEY, BTN_MIDDLE, 1); 500 input_sync(field->hidinput->input); 501 } 502 503 /* "wheel" scroll events */ 504 if (usage->type == EV_REL && (usage->code == REL_WHEEL || 505 usage->code == REL_HWHEEL)) { 506 /* Scroll events disable middle-click event */ 507 cptkbd_data->middlebutton_state = 2; 508 return 0; 509 } 510 511 /* Middle click events */ 512 if (usage->type == EV_KEY && usage->code == BTN_MIDDLE) { 513 if (value == 1) { 514 cptkbd_data->middlebutton_state = 1; 515 } else if (value == 0) { 516 if (cptkbd_data->middlebutton_state == 1) { 517 /* No scrolling inbetween, send middle-click */ 518 input_event(field->hidinput->input, 519 EV_KEY, BTN_MIDDLE, 1); 520 input_sync(field->hidinput->input); 521 input_event(field->hidinput->input, 522 EV_KEY, BTN_MIDDLE, 0); 523 input_sync(field->hidinput->input); 524 } 525 cptkbd_data->middlebutton_state = 0; 526 } 527 return 1; 528 } 529 } 530 531 return 0; 532} 533 534static int lenovo_event(struct hid_device *hdev, struct hid_field *field, 535 struct hid_usage *usage, __s32 value) 536{ 537 if (!hid_get_drvdata(hdev)) 538 return 0; 539 540 switch (hdev->product) { 541 case USB_DEVICE_ID_LENOVO_CUSBKBD: 542 case USB_DEVICE_ID_LENOVO_CBTKBD: 543 return lenovo_event_cptkbd(hdev, field, usage, value); 544 case USB_DEVICE_ID_LENOVO_TP10UBKBD: 545 return lenovo_event_tp10ubkbd(hdev, field, usage, value); 546 default: 547 return 0; 548 } 549} 550 551static int lenovo_features_set_tpkbd(struct hid_device *hdev) 552{ 553 struct hid_report *report; 554 struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev); 555 556 report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[4]; 557 558 report->field[0]->value[0] = data_pointer->press_to_select ? 0x01 : 0x02; 559 report->field[0]->value[0] |= data_pointer->dragging ? 0x04 : 0x08; 560 report->field[0]->value[0] |= data_pointer->release_to_select ? 0x10 : 0x20; 561 report->field[0]->value[0] |= data_pointer->select_right ? 0x80 : 0x40; 562 report->field[1]->value[0] = 0x03; // unknown setting, imitate windows driver 563 report->field[2]->value[0] = data_pointer->sensitivity; 564 report->field[3]->value[0] = data_pointer->press_speed; 565 566 hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 567 return 0; 568} 569 570static ssize_t attr_press_to_select_show_tpkbd(struct device *dev, 571 struct device_attribute *attr, 572 char *buf) 573{ 574 struct hid_device *hdev = to_hid_device(dev); 575 struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev); 576 577 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->press_to_select); 578} 579 580static ssize_t attr_press_to_select_store_tpkbd(struct device *dev, 581 struct device_attribute *attr, 582 const char *buf, 583 size_t count) 584{ 585 struct hid_device *hdev = to_hid_device(dev); 586 struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev); 587 int value; 588 589 if (kstrtoint(buf, 10, &value)) 590 return -EINVAL; 591 if (value < 0 || value > 1) 592 return -EINVAL; 593 594 data_pointer->press_to_select = value; 595 lenovo_features_set_tpkbd(hdev); 596 597 return count; 598} 599 600static ssize_t attr_dragging_show_tpkbd(struct device *dev, 601 struct device_attribute *attr, 602 char *buf) 603{ 604 struct hid_device *hdev = to_hid_device(dev); 605 struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev); 606 607 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->dragging); 608} 609 610static ssize_t attr_dragging_store_tpkbd(struct device *dev, 611 struct device_attribute *attr, 612 const char *buf, 613 size_t count) 614{ 615 struct hid_device *hdev = to_hid_device(dev); 616 struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev); 617 int value; 618 619 if (kstrtoint(buf, 10, &value)) 620 return -EINVAL; 621 if (value < 0 || value > 1) 622 return -EINVAL; 623 624 data_pointer->dragging = value; 625 lenovo_features_set_tpkbd(hdev); 626 627 return count; 628} 629 630static ssize_t attr_release_to_select_show_tpkbd(struct device *dev, 631 struct device_attribute *attr, 632 char *buf) 633{ 634 struct hid_device *hdev = to_hid_device(dev); 635 struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev); 636 637 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->release_to_select); 638} 639 640static ssize_t attr_release_to_select_store_tpkbd(struct device *dev, 641 struct device_attribute *attr, 642 const char *buf, 643 size_t count) 644{ 645 struct hid_device *hdev = to_hid_device(dev); 646 struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev); 647 int value; 648 649 if (kstrtoint(buf, 10, &value)) 650 return -EINVAL; 651 if (value < 0 || value > 1) 652 return -EINVAL; 653 654 data_pointer->release_to_select = value; 655 lenovo_features_set_tpkbd(hdev); 656 657 return count; 658} 659 660static ssize_t attr_select_right_show_tpkbd(struct device *dev, 661 struct device_attribute *attr, 662 char *buf) 663{ 664 struct hid_device *hdev = to_hid_device(dev); 665 struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev); 666 667 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->select_right); 668} 669 670static ssize_t attr_select_right_store_tpkbd(struct device *dev, 671 struct device_attribute *attr, 672 const char *buf, 673 size_t count) 674{ 675 struct hid_device *hdev = to_hid_device(dev); 676 struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev); 677 int value; 678 679 if (kstrtoint(buf, 10, &value)) 680 return -EINVAL; 681 if (value < 0 || value > 1) 682 return -EINVAL; 683 684 data_pointer->select_right = value; 685 lenovo_features_set_tpkbd(hdev); 686 687 return count; 688} 689 690static ssize_t attr_sensitivity_show_tpkbd(struct device *dev, 691 struct device_attribute *attr, 692 char *buf) 693{ 694 struct hid_device *hdev = to_hid_device(dev); 695 struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev); 696 697 return snprintf(buf, PAGE_SIZE, "%u\n", 698 data_pointer->sensitivity); 699} 700 701static ssize_t attr_sensitivity_store_tpkbd(struct device *dev, 702 struct device_attribute *attr, 703 const char *buf, 704 size_t count) 705{ 706 struct hid_device *hdev = to_hid_device(dev); 707 struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev); 708 int value; 709 710 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255) 711 return -EINVAL; 712 713 data_pointer->sensitivity = value; 714 lenovo_features_set_tpkbd(hdev); 715 716 return count; 717} 718 719static ssize_t attr_press_speed_show_tpkbd(struct device *dev, 720 struct device_attribute *attr, 721 char *buf) 722{ 723 struct hid_device *hdev = to_hid_device(dev); 724 struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev); 725 726 return snprintf(buf, PAGE_SIZE, "%u\n", 727 data_pointer->press_speed); 728} 729 730static ssize_t attr_press_speed_store_tpkbd(struct device *dev, 731 struct device_attribute *attr, 732 const char *buf, 733 size_t count) 734{ 735 struct hid_device *hdev = to_hid_device(dev); 736 struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev); 737 int value; 738 739 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255) 740 return -EINVAL; 741 742 data_pointer->press_speed = value; 743 lenovo_features_set_tpkbd(hdev); 744 745 return count; 746} 747 748static struct device_attribute dev_attr_press_to_select_tpkbd = 749 __ATTR(press_to_select, S_IWUSR | S_IRUGO, 750 attr_press_to_select_show_tpkbd, 751 attr_press_to_select_store_tpkbd); 752 753static struct device_attribute dev_attr_dragging_tpkbd = 754 __ATTR(dragging, S_IWUSR | S_IRUGO, 755 attr_dragging_show_tpkbd, 756 attr_dragging_store_tpkbd); 757 758static struct device_attribute dev_attr_release_to_select_tpkbd = 759 __ATTR(release_to_select, S_IWUSR | S_IRUGO, 760 attr_release_to_select_show_tpkbd, 761 attr_release_to_select_store_tpkbd); 762 763static struct device_attribute dev_attr_select_right_tpkbd = 764 __ATTR(select_right, S_IWUSR | S_IRUGO, 765 attr_select_right_show_tpkbd, 766 attr_select_right_store_tpkbd); 767 768static struct device_attribute dev_attr_sensitivity_tpkbd = 769 __ATTR(sensitivity, S_IWUSR | S_IRUGO, 770 attr_sensitivity_show_tpkbd, 771 attr_sensitivity_store_tpkbd); 772 773static struct device_attribute dev_attr_press_speed_tpkbd = 774 __ATTR(press_speed, S_IWUSR | S_IRUGO, 775 attr_press_speed_show_tpkbd, 776 attr_press_speed_store_tpkbd); 777 778static struct attribute *lenovo_attributes_tpkbd[] = { 779 &dev_attr_press_to_select_tpkbd.attr, 780 &dev_attr_dragging_tpkbd.attr, 781 &dev_attr_release_to_select_tpkbd.attr, 782 &dev_attr_select_right_tpkbd.attr, 783 &dev_attr_sensitivity_tpkbd.attr, 784 &dev_attr_press_speed_tpkbd.attr, 785 NULL 786}; 787 788static const struct attribute_group lenovo_attr_group_tpkbd = { 789 .attrs = lenovo_attributes_tpkbd, 790}; 791 792static void lenovo_led_set_tpkbd(struct hid_device *hdev) 793{ 794 struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev); 795 struct hid_report *report; 796 797 report = hdev->report_enum[HID_OUTPUT_REPORT].report_id_hash[3]; 798 report->field[0]->value[0] = (data_pointer->led_state >> 0) & 1; 799 report->field[0]->value[1] = (data_pointer->led_state >> 1) & 1; 800 hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 801} 802 803static enum led_brightness lenovo_led_brightness_get( 804 struct led_classdev *led_cdev) 805{ 806 struct device *dev = led_cdev->dev->parent; 807 struct hid_device *hdev = to_hid_device(dev); 808 struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev); 809 int led_nr = 0; 810 811 if (led_cdev == &data_pointer->led_micmute) 812 led_nr = 1; 813 814 return data_pointer->led_state & (1 << led_nr) 815 ? LED_FULL 816 : LED_OFF; 817} 818 819static int lenovo_led_brightness_set(struct led_classdev *led_cdev, 820 enum led_brightness value) 821{ 822 struct device *dev = led_cdev->dev->parent; 823 struct hid_device *hdev = to_hid_device(dev); 824 struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev); 825 u8 tp10ubkbd_led[] = { TP10UBKBD_MUTE_LED, TP10UBKBD_MICMUTE_LED }; 826 int led_nr = 0; 827 int ret = 0; 828 829 if (led_cdev == &data_pointer->led_micmute) 830 led_nr = 1; 831 832 if (value == LED_OFF) 833 data_pointer->led_state &= ~(1 << led_nr); 834 else 835 data_pointer->led_state |= 1 << led_nr; 836 837 switch (hdev->product) { 838 case USB_DEVICE_ID_LENOVO_TPKBD: 839 lenovo_led_set_tpkbd(hdev); 840 break; 841 case USB_DEVICE_ID_LENOVO_TP10UBKBD: 842 ret = lenovo_led_set_tp10ubkbd(hdev, tp10ubkbd_led[led_nr], value); 843 break; 844 } 845 846 return ret; 847} 848 849static int lenovo_register_leds(struct hid_device *hdev) 850{ 851 struct lenovo_drvdata *data = hid_get_drvdata(hdev); 852 size_t name_sz = strlen(dev_name(&hdev->dev)) + 16; 853 char *name_mute, *name_micm; 854 int ret; 855 856 name_mute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL); 857 name_micm = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL); 858 if (name_mute == NULL || name_micm == NULL) { 859 hid_err(hdev, "Could not allocate memory for led data\n"); 860 return -ENOMEM; 861 } 862 snprintf(name_mute, name_sz, "%s:amber:mute", dev_name(&hdev->dev)); 863 snprintf(name_micm, name_sz, "%s:amber:micmute", dev_name(&hdev->dev)); 864 865 data->led_mute.name = name_mute; 866 data->led_mute.brightness_get = lenovo_led_brightness_get; 867 data->led_mute.brightness_set_blocking = lenovo_led_brightness_set; 868 data->led_mute.flags = LED_HW_PLUGGABLE; 869 data->led_mute.dev = &hdev->dev; 870 ret = led_classdev_register(&hdev->dev, &data->led_mute); 871 if (ret < 0) 872 return ret; 873 874 data->led_micmute.name = name_micm; 875 data->led_micmute.brightness_get = lenovo_led_brightness_get; 876 data->led_micmute.brightness_set_blocking = lenovo_led_brightness_set; 877 data->led_micmute.flags = LED_HW_PLUGGABLE; 878 data->led_micmute.dev = &hdev->dev; 879 ret = led_classdev_register(&hdev->dev, &data->led_micmute); 880 if (ret < 0) { 881 led_classdev_unregister(&data->led_mute); 882 return ret; 883 } 884 885 return 0; 886} 887 888static int lenovo_probe_tpkbd(struct hid_device *hdev) 889{ 890 struct lenovo_drvdata *data_pointer; 891 int i, ret; 892 893 /* 894 * Only register extra settings against subdevice where input_mapping 895 * set drvdata to 1, i.e. the trackpoint. 896 */ 897 if (!hid_get_drvdata(hdev)) 898 return 0; 899 900 hid_set_drvdata(hdev, NULL); 901 902 /* Validate required reports. */ 903 for (i = 0; i < 4; i++) { 904 if (!hid_validate_values(hdev, HID_FEATURE_REPORT, 4, i, 1)) 905 return -ENODEV; 906 } 907 if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 3, 0, 2)) 908 return -ENODEV; 909 910 ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_tpkbd); 911 if (ret) 912 hid_warn(hdev, "Could not create sysfs group: %d\n", ret); 913 914 data_pointer = devm_kzalloc(&hdev->dev, 915 sizeof(struct lenovo_drvdata), 916 GFP_KERNEL); 917 if (data_pointer == NULL) { 918 hid_err(hdev, "Could not allocate memory for driver data\n"); 919 ret = -ENOMEM; 920 goto err; 921 } 922 923 // set same default values as windows driver 924 data_pointer->sensitivity = 0xa0; 925 data_pointer->press_speed = 0x38; 926 927 hid_set_drvdata(hdev, data_pointer); 928 929 ret = lenovo_register_leds(hdev); 930 if (ret) 931 goto err; 932 933 lenovo_features_set_tpkbd(hdev); 934 935 return 0; 936err: 937 sysfs_remove_group(&hdev->dev.kobj, &lenovo_attr_group_tpkbd); 938 return ret; 939} 940 941static int lenovo_probe_cptkbd(struct hid_device *hdev) 942{ 943 int ret; 944 struct lenovo_drvdata *cptkbd_data; 945 946 /* All the custom action happens on the USBMOUSE device for USB */ 947 if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD 948 && hdev->type != HID_TYPE_USBMOUSE) { 949 hid_dbg(hdev, "Ignoring keyboard half of device\n"); 950 return 0; 951 } 952 953 cptkbd_data = devm_kzalloc(&hdev->dev, 954 sizeof(*cptkbd_data), 955 GFP_KERNEL); 956 if (cptkbd_data == NULL) { 957 hid_err(hdev, "can't alloc keyboard descriptor\n"); 958 return -ENOMEM; 959 } 960 hid_set_drvdata(hdev, cptkbd_data); 961 962 /* 963 * Tell the keyboard a driver understands it, and turn F7, F9, F11 into 964 * regular keys 965 */ 966 ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03); 967 if (ret) 968 hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); 969 970 /* Switch middle button to native mode */ 971 ret = lenovo_send_cmd_cptkbd(hdev, 0x09, 0x01); 972 if (ret) 973 hid_warn(hdev, "Failed to switch middle button: %d\n", ret); 974 975 /* Set keyboard settings to known state */ 976 cptkbd_data->middlebutton_state = 0; 977 cptkbd_data->fn_lock = true; 978 cptkbd_data->sensitivity = 0x05; 979 lenovo_features_set_cptkbd(hdev); 980 981 ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd); 982 if (ret) 983 hid_warn(hdev, "Could not create sysfs group: %d\n", ret); 984 985 return 0; 986} 987 988static struct attribute *lenovo_attributes_tp10ubkbd[] = { 989 &dev_attr_fn_lock.attr, 990 NULL 991}; 992 993static const struct attribute_group lenovo_attr_group_tp10ubkbd = { 994 .attrs = lenovo_attributes_tp10ubkbd, 995}; 996 997static int lenovo_probe_tp10ubkbd(struct hid_device *hdev) 998{ 999 struct lenovo_drvdata *data; 1000 int ret; 1001 1002 /* All the custom action happens on the USBMOUSE device for USB */ 1003 if (hdev->type != HID_TYPE_USBMOUSE) 1004 return 0; 1005 1006 data = devm_kzalloc(&hdev->dev, sizeof(*data), GFP_KERNEL); 1007 if (!data) 1008 return -ENOMEM; 1009 1010 mutex_init(&data->led_report_mutex); 1011 INIT_WORK(&data->fn_lock_sync_work, lenovo_tp10ubkbd_sync_fn_lock); 1012 data->hdev = hdev; 1013 1014 hid_set_drvdata(hdev, data); 1015 1016 /* 1017 * The Thinkpad 10 ultrabook USB kbd dock's Fn-lock defaults to on. 1018 * We cannot read the state, only set it, so we force it to on here 1019 * (which should be a no-op) to make sure that our state matches the 1020 * keyboard's FN-lock state. This is the same as what Windows does. 1021 */ 1022 data->fn_lock = true; 1023 lenovo_led_set_tp10ubkbd(hdev, TP10UBKBD_FN_LOCK_LED, data->fn_lock); 1024 1025 ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_tp10ubkbd); 1026 if (ret) 1027 return ret; 1028 1029 ret = lenovo_register_leds(hdev); 1030 if (ret) 1031 goto err; 1032 1033 return 0; 1034err: 1035 sysfs_remove_group(&hdev->dev.kobj, &lenovo_attr_group_tp10ubkbd); 1036 return ret; 1037} 1038 1039static int lenovo_probe(struct hid_device *hdev, 1040 const struct hid_device_id *id) 1041{ 1042 int ret; 1043 1044 ret = hid_parse(hdev); 1045 if (ret) { 1046 hid_err(hdev, "hid_parse failed\n"); 1047 goto err; 1048 } 1049 1050 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 1051 if (ret) { 1052 hid_err(hdev, "hid_hw_start failed\n"); 1053 goto err; 1054 } 1055 1056 switch (hdev->product) { 1057 case USB_DEVICE_ID_LENOVO_TPKBD: 1058 ret = lenovo_probe_tpkbd(hdev); 1059 break; 1060 case USB_DEVICE_ID_LENOVO_CUSBKBD: 1061 case USB_DEVICE_ID_LENOVO_CBTKBD: 1062 ret = lenovo_probe_cptkbd(hdev); 1063 break; 1064 case USB_DEVICE_ID_LENOVO_TP10UBKBD: 1065 ret = lenovo_probe_tp10ubkbd(hdev); 1066 break; 1067 default: 1068 ret = 0; 1069 break; 1070 } 1071 if (ret) 1072 goto err_hid; 1073 1074 return 0; 1075err_hid: 1076 hid_hw_stop(hdev); 1077err: 1078 return ret; 1079} 1080 1081static void lenovo_remove_tpkbd(struct hid_device *hdev) 1082{ 1083 struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev); 1084 1085 /* 1086 * Only the trackpoint half of the keyboard has drvdata and stuff that 1087 * needs unregistering. 1088 */ 1089 if (data_pointer == NULL) 1090 return; 1091 1092 sysfs_remove_group(&hdev->dev.kobj, 1093 &lenovo_attr_group_tpkbd); 1094 1095 led_classdev_unregister(&data_pointer->led_micmute); 1096 led_classdev_unregister(&data_pointer->led_mute); 1097} 1098 1099static void lenovo_remove_cptkbd(struct hid_device *hdev) 1100{ 1101 sysfs_remove_group(&hdev->dev.kobj, 1102 &lenovo_attr_group_cptkbd); 1103} 1104 1105static void lenovo_remove_tp10ubkbd(struct hid_device *hdev) 1106{ 1107 struct lenovo_drvdata *data = hid_get_drvdata(hdev); 1108 1109 if (data == NULL) 1110 return; 1111 1112 led_classdev_unregister(&data->led_micmute); 1113 led_classdev_unregister(&data->led_mute); 1114 1115 sysfs_remove_group(&hdev->dev.kobj, &lenovo_attr_group_tp10ubkbd); 1116 cancel_work_sync(&data->fn_lock_sync_work); 1117} 1118 1119static void lenovo_remove(struct hid_device *hdev) 1120{ 1121 switch (hdev->product) { 1122 case USB_DEVICE_ID_LENOVO_TPKBD: 1123 lenovo_remove_tpkbd(hdev); 1124 break; 1125 case USB_DEVICE_ID_LENOVO_CUSBKBD: 1126 case USB_DEVICE_ID_LENOVO_CBTKBD: 1127 lenovo_remove_cptkbd(hdev); 1128 break; 1129 case USB_DEVICE_ID_LENOVO_TP10UBKBD: 1130 lenovo_remove_tp10ubkbd(hdev); 1131 break; 1132 } 1133 1134 hid_hw_stop(hdev); 1135} 1136 1137static int lenovo_input_configured(struct hid_device *hdev, 1138 struct hid_input *hi) 1139{ 1140 switch (hdev->product) { 1141 case USB_DEVICE_ID_LENOVO_TPKBD: 1142 case USB_DEVICE_ID_LENOVO_CUSBKBD: 1143 case USB_DEVICE_ID_LENOVO_CBTKBD: 1144 if (test_bit(EV_REL, hi->input->evbit)) { 1145 /* set only for trackpoint device */ 1146 __set_bit(INPUT_PROP_POINTER, hi->input->propbit); 1147 __set_bit(INPUT_PROP_POINTING_STICK, 1148 hi->input->propbit); 1149 } 1150 break; 1151 } 1152 1153 return 0; 1154} 1155 1156 1157static const struct hid_device_id lenovo_devices[] = { 1158 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) }, 1159 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) }, 1160 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) }, 1161 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPPRODOCK) }, 1162 { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_III) }, 1163 { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_PRO) }, 1164 { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_OPTICAL) }, 1165 { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL) }, 1166 { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL_PRO) }, 1167 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL) }, 1168 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TP10UBKBD) }, 1169 { } 1170}; 1171 1172MODULE_DEVICE_TABLE(hid, lenovo_devices); 1173 1174static struct hid_driver lenovo_driver = { 1175 .name = "lenovo", 1176 .id_table = lenovo_devices, 1177 .input_configured = lenovo_input_configured, 1178 .input_mapping = lenovo_input_mapping, 1179 .probe = lenovo_probe, 1180 .remove = lenovo_remove, 1181 .raw_event = lenovo_raw_event, 1182 .event = lenovo_event, 1183 .report_fixup = lenovo_report_fixup, 1184}; 1185module_hid_driver(lenovo_driver); 1186 1187MODULE_LICENSE("GPL"); 1188