1 /* 2 * HID driver for Lenovo: 3 * - ThinkPad USB Keyboard with TrackPoint (tpkbd) 4 * - ThinkPad Compact Bluetooth Keyboard with TrackPoint (cptkbd) 5 * - ThinkPad Compact USB Keyboard with TrackPoint (cptkbd) 6 * 7 * Copyright (c) 2012 Bernhard Seibold 8 * Copyright (c) 2014 Jamie Lentin <jm@lentin.co.uk> 9 * 10 * Linux IBM/Lenovo Scrollpoint mouse driver: 11 * - IBM Scrollpoint III 12 * - IBM Scrollpoint Pro 13 * - IBM Scrollpoint Optical 14 * - IBM Scrollpoint Optical 800dpi 15 * - IBM Scrollpoint Optical 800dpi Pro 16 * - Lenovo Scrollpoint Optical 17 * 18 * Copyright (c) 2012 Peter De Wachter <pdewacht@gmail.com> 19 * Copyright (c) 2018 Peter Ganzhorn <peter.ganzhorn@gmail.com> 20 */ 21 22 /* 23 * This program is free software; you can redistribute it and/or modify it 24 * under the terms of the GNU General Public License as published by the Free 25 * Software Foundation; either version 2 of the License, or (at your option) 26 * any later version. 27 */ 28 29 #include <linux/module.h> 30 #include <linux/sysfs.h> 31 #include <linux/device.h> 32 #include <linux/hid.h> 33 #include <linux/input.h> 34 #include <linux/leds.h> 35 36 #include "hid-ids.h" 37 38 struct lenovo_drvdata_tpkbd { 39 int led_state; 40 struct led_classdev led_mute; 41 struct led_classdev led_micmute; 42 int press_to_select; 43 int dragging; 44 int release_to_select; 45 int select_right; 46 int sensitivity; 47 int press_speed; 48 }; 49 50 struct lenovo_drvdata_cptkbd { 51 u8 middlebutton_state; /* 0:Up, 1:Down (undecided), 2:Scrolling */ 52 bool fn_lock; 53 int sensitivity; 54 }; 55 56 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c)) 57 58 static const __u8 lenovo_pro_dock_need_fixup_collection[] = { 59 0x05, 0x88, /* Usage Page (Vendor Usage Page 0x88) */ 60 0x09, 0x01, /* Usage (Vendor Usage 0x01) */ 61 0xa1, 0x01, /* Collection (Application) */ 62 0x85, 0x04, /* Report ID (4) */ 63 0x19, 0x00, /* Usage Minimum (0) */ 64 0x2a, 0xff, 0xff, /* Usage Maximum (65535) */ 65 }; 66 67 static __u8 *lenovo_report_fixup(struct hid_device *hdev, __u8 *rdesc, 68 unsigned int *rsize) 69 { 70 switch (hdev->product) { 71 case USB_DEVICE_ID_LENOVO_TPPRODOCK: 72 /* the fixups that need to be done: 73 * - get a reasonable usage max for the vendor collection 74 * 0x8801 from the report ID 4 75 */ 76 if (*rsize >= 153 && 77 memcmp(&rdesc[140], lenovo_pro_dock_need_fixup_collection, 78 sizeof(lenovo_pro_dock_need_fixup_collection)) == 0) { 79 rdesc[151] = 0x01; 80 rdesc[152] = 0x00; 81 } 82 break; 83 } 84 return rdesc; 85 } 86 87 static int lenovo_input_mapping_tpkbd(struct hid_device *hdev, 88 struct hid_input *hi, struct hid_field *field, 89 struct hid_usage *usage, unsigned long **bit, int *max) 90 { 91 if (usage->hid == (HID_UP_BUTTON | 0x0010)) { 92 /* This sub-device contains trackpoint, mark it */ 93 hid_set_drvdata(hdev, (void *)1); 94 map_key_clear(KEY_MICMUTE); 95 return 1; 96 } 97 return 0; 98 } 99 100 static int lenovo_input_mapping_cptkbd(struct hid_device *hdev, 101 struct hid_input *hi, struct hid_field *field, 102 struct hid_usage *usage, unsigned long **bit, int *max) 103 { 104 /* HID_UP_LNVENDOR = USB, HID_UP_MSVENDOR = BT */ 105 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR || 106 (usage->hid & HID_USAGE_PAGE) == HID_UP_LNVENDOR) { 107 switch (usage->hid & HID_USAGE) { 108 case 0x00f1: /* Fn-F4: Mic mute */ 109 map_key_clear(KEY_MICMUTE); 110 return 1; 111 case 0x00f2: /* Fn-F5: Brightness down */ 112 map_key_clear(KEY_BRIGHTNESSDOWN); 113 return 1; 114 case 0x00f3: /* Fn-F6: Brightness up */ 115 map_key_clear(KEY_BRIGHTNESSUP); 116 return 1; 117 case 0x00f4: /* Fn-F7: External display (projector) */ 118 map_key_clear(KEY_SWITCHVIDEOMODE); 119 return 1; 120 case 0x00f5: /* Fn-F8: Wireless */ 121 map_key_clear(KEY_WLAN); 122 return 1; 123 case 0x00f6: /* Fn-F9: Control panel */ 124 map_key_clear(KEY_CONFIG); 125 return 1; 126 case 0x00f8: /* Fn-F11: View open applications (3 boxes) */ 127 map_key_clear(KEY_SCALE); 128 return 1; 129 case 0x00f9: /* Fn-F12: Open My computer (6 boxes) USB-only */ 130 /* NB: This mapping is invented in raw_event below */ 131 map_key_clear(KEY_FILE); 132 return 1; 133 case 0x00fa: /* Fn-Esc: Fn-lock toggle */ 134 map_key_clear(KEY_FN_ESC); 135 return 1; 136 case 0x00fb: /* Middle mouse button (in native mode) */ 137 map_key_clear(BTN_MIDDLE); 138 return 1; 139 } 140 } 141 142 /* Compatibility middle/wheel mappings should be ignored */ 143 if (usage->hid == HID_GD_WHEEL) 144 return -1; 145 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_BUTTON && 146 (usage->hid & HID_USAGE) == 0x003) 147 return -1; 148 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER && 149 (usage->hid & HID_USAGE) == 0x238) 150 return -1; 151 152 /* Map wheel emulation reports: 0xffa1 = USB, 0xff10 = BT */ 153 if ((usage->hid & HID_USAGE_PAGE) == 0xff100000 || 154 (usage->hid & HID_USAGE_PAGE) == 0xffa10000) { 155 field->flags |= HID_MAIN_ITEM_RELATIVE | HID_MAIN_ITEM_VARIABLE; 156 field->logical_minimum = -127; 157 field->logical_maximum = 127; 158 159 switch (usage->hid & HID_USAGE) { 160 case 0x0000: 161 hid_map_usage(hi, usage, bit, max, EV_REL, REL_HWHEEL); 162 return 1; 163 case 0x0001: 164 hid_map_usage(hi, usage, bit, max, EV_REL, REL_WHEEL); 165 return 1; 166 default: 167 return -1; 168 } 169 } 170 171 return 0; 172 } 173 174 static int lenovo_input_mapping_scrollpoint(struct hid_device *hdev, 175 struct hid_input *hi, struct hid_field *field, 176 struct hid_usage *usage, unsigned long **bit, int *max) 177 { 178 if (usage->hid == HID_GD_Z) { 179 hid_map_usage(hi, usage, bit, max, EV_REL, REL_HWHEEL); 180 return 1; 181 } 182 return 0; 183 } 184 185 static int lenovo_input_mapping(struct hid_device *hdev, 186 struct hid_input *hi, struct hid_field *field, 187 struct hid_usage *usage, unsigned long **bit, int *max) 188 { 189 switch (hdev->product) { 190 case USB_DEVICE_ID_LENOVO_TPKBD: 191 return lenovo_input_mapping_tpkbd(hdev, hi, field, 192 usage, bit, max); 193 case USB_DEVICE_ID_LENOVO_CUSBKBD: 194 case USB_DEVICE_ID_LENOVO_CBTKBD: 195 return lenovo_input_mapping_cptkbd(hdev, hi, field, 196 usage, bit, max); 197 case USB_DEVICE_ID_IBM_SCROLLPOINT_III: 198 case USB_DEVICE_ID_IBM_SCROLLPOINT_PRO: 199 case USB_DEVICE_ID_IBM_SCROLLPOINT_OPTICAL: 200 case USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL: 201 case USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL_PRO: 202 case USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL: 203 return lenovo_input_mapping_scrollpoint(hdev, hi, field, 204 usage, bit, max); 205 default: 206 return 0; 207 } 208 } 209 210 #undef map_key_clear 211 212 /* Send a config command to the keyboard */ 213 static int lenovo_send_cmd_cptkbd(struct hid_device *hdev, 214 unsigned char byte2, unsigned char byte3) 215 { 216 int ret; 217 unsigned char *buf; 218 219 buf = kzalloc(3, GFP_KERNEL); 220 if (!buf) 221 return -ENOMEM; 222 223 buf[0] = 0x18; 224 buf[1] = byte2; 225 buf[2] = byte3; 226 227 switch (hdev->product) { 228 case USB_DEVICE_ID_LENOVO_CUSBKBD: 229 ret = hid_hw_raw_request(hdev, 0x13, buf, 3, 230 HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 231 break; 232 case USB_DEVICE_ID_LENOVO_CBTKBD: 233 ret = hid_hw_output_report(hdev, buf, 3); 234 break; 235 default: 236 ret = -EINVAL; 237 break; 238 } 239 240 kfree(buf); 241 242 return ret < 0 ? ret : 0; /* BT returns 0, USB returns sizeof(buf) */ 243 } 244 245 static void lenovo_features_set_cptkbd(struct hid_device *hdev) 246 { 247 int ret; 248 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); 249 250 ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock); 251 if (ret) 252 hid_err(hdev, "Fn-lock setting failed: %d\n", ret); 253 254 ret = lenovo_send_cmd_cptkbd(hdev, 0x02, cptkbd_data->sensitivity); 255 if (ret) 256 hid_err(hdev, "Sensitivity setting failed: %d\n", ret); 257 } 258 259 static ssize_t attr_fn_lock_show_cptkbd(struct device *dev, 260 struct device_attribute *attr, 261 char *buf) 262 { 263 struct hid_device *hdev = to_hid_device(dev); 264 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); 265 266 return snprintf(buf, PAGE_SIZE, "%u\n", cptkbd_data->fn_lock); 267 } 268 269 static ssize_t attr_fn_lock_store_cptkbd(struct device *dev, 270 struct device_attribute *attr, 271 const char *buf, 272 size_t count) 273 { 274 struct hid_device *hdev = to_hid_device(dev); 275 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); 276 int value; 277 278 if (kstrtoint(buf, 10, &value)) 279 return -EINVAL; 280 if (value < 0 || value > 1) 281 return -EINVAL; 282 283 cptkbd_data->fn_lock = !!value; 284 lenovo_features_set_cptkbd(hdev); 285 286 return count; 287 } 288 289 static ssize_t attr_sensitivity_show_cptkbd(struct device *dev, 290 struct device_attribute *attr, 291 char *buf) 292 { 293 struct hid_device *hdev = to_hid_device(dev); 294 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); 295 296 return snprintf(buf, PAGE_SIZE, "%u\n", 297 cptkbd_data->sensitivity); 298 } 299 300 static ssize_t attr_sensitivity_store_cptkbd(struct device *dev, 301 struct device_attribute *attr, 302 const char *buf, 303 size_t count) 304 { 305 struct hid_device *hdev = to_hid_device(dev); 306 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); 307 int value; 308 309 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255) 310 return -EINVAL; 311 312 cptkbd_data->sensitivity = value; 313 lenovo_features_set_cptkbd(hdev); 314 315 return count; 316 } 317 318 319 static struct device_attribute dev_attr_fn_lock_cptkbd = 320 __ATTR(fn_lock, S_IWUSR | S_IRUGO, 321 attr_fn_lock_show_cptkbd, 322 attr_fn_lock_store_cptkbd); 323 324 static struct device_attribute dev_attr_sensitivity_cptkbd = 325 __ATTR(sensitivity, S_IWUSR | S_IRUGO, 326 attr_sensitivity_show_cptkbd, 327 attr_sensitivity_store_cptkbd); 328 329 330 static struct attribute *lenovo_attributes_cptkbd[] = { 331 &dev_attr_fn_lock_cptkbd.attr, 332 &dev_attr_sensitivity_cptkbd.attr, 333 NULL 334 }; 335 336 static const struct attribute_group lenovo_attr_group_cptkbd = { 337 .attrs = lenovo_attributes_cptkbd, 338 }; 339 340 static int lenovo_raw_event(struct hid_device *hdev, 341 struct hid_report *report, u8 *data, int size) 342 { 343 /* 344 * Compact USB keyboard's Fn-F12 report holds down many other keys, and 345 * its own key is outside the usage page range. Remove extra 346 * keypresses and remap to inside usage page. 347 */ 348 if (unlikely(hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD 349 && size == 3 350 && data[0] == 0x15 351 && data[1] == 0x94 352 && data[2] == 0x01)) { 353 data[1] = 0x00; 354 data[2] = 0x01; 355 } 356 357 return 0; 358 } 359 360 static int lenovo_event_cptkbd(struct hid_device *hdev, 361 struct hid_field *field, struct hid_usage *usage, __s32 value) 362 { 363 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); 364 365 /* "wheel" scroll events */ 366 if (usage->type == EV_REL && (usage->code == REL_WHEEL || 367 usage->code == REL_HWHEEL)) { 368 /* Scroll events disable middle-click event */ 369 cptkbd_data->middlebutton_state = 2; 370 return 0; 371 } 372 373 /* Middle click events */ 374 if (usage->type == EV_KEY && usage->code == BTN_MIDDLE) { 375 if (value == 1) { 376 cptkbd_data->middlebutton_state = 1; 377 } else if (value == 0) { 378 if (cptkbd_data->middlebutton_state == 1) { 379 /* No scrolling inbetween, send middle-click */ 380 input_event(field->hidinput->input, 381 EV_KEY, BTN_MIDDLE, 1); 382 input_sync(field->hidinput->input); 383 input_event(field->hidinput->input, 384 EV_KEY, BTN_MIDDLE, 0); 385 input_sync(field->hidinput->input); 386 } 387 cptkbd_data->middlebutton_state = 0; 388 } 389 return 1; 390 } 391 392 return 0; 393 } 394 395 static int lenovo_event(struct hid_device *hdev, struct hid_field *field, 396 struct hid_usage *usage, __s32 value) 397 { 398 switch (hdev->product) { 399 case USB_DEVICE_ID_LENOVO_CUSBKBD: 400 case USB_DEVICE_ID_LENOVO_CBTKBD: 401 return lenovo_event_cptkbd(hdev, field, usage, value); 402 default: 403 return 0; 404 } 405 } 406 407 static int lenovo_features_set_tpkbd(struct hid_device *hdev) 408 { 409 struct hid_report *report; 410 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 411 412 report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[4]; 413 414 report->field[0]->value[0] = data_pointer->press_to_select ? 0x01 : 0x02; 415 report->field[0]->value[0] |= data_pointer->dragging ? 0x04 : 0x08; 416 report->field[0]->value[0] |= data_pointer->release_to_select ? 0x10 : 0x20; 417 report->field[0]->value[0] |= data_pointer->select_right ? 0x80 : 0x40; 418 report->field[1]->value[0] = 0x03; // unknown setting, imitate windows driver 419 report->field[2]->value[0] = data_pointer->sensitivity; 420 report->field[3]->value[0] = data_pointer->press_speed; 421 422 hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 423 return 0; 424 } 425 426 static ssize_t attr_press_to_select_show_tpkbd(struct device *dev, 427 struct device_attribute *attr, 428 char *buf) 429 { 430 struct hid_device *hdev = to_hid_device(dev); 431 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 432 433 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->press_to_select); 434 } 435 436 static ssize_t attr_press_to_select_store_tpkbd(struct device *dev, 437 struct device_attribute *attr, 438 const char *buf, 439 size_t count) 440 { 441 struct hid_device *hdev = to_hid_device(dev); 442 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 443 int value; 444 445 if (kstrtoint(buf, 10, &value)) 446 return -EINVAL; 447 if (value < 0 || value > 1) 448 return -EINVAL; 449 450 data_pointer->press_to_select = value; 451 lenovo_features_set_tpkbd(hdev); 452 453 return count; 454 } 455 456 static ssize_t attr_dragging_show_tpkbd(struct device *dev, 457 struct device_attribute *attr, 458 char *buf) 459 { 460 struct hid_device *hdev = to_hid_device(dev); 461 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 462 463 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->dragging); 464 } 465 466 static ssize_t attr_dragging_store_tpkbd(struct device *dev, 467 struct device_attribute *attr, 468 const char *buf, 469 size_t count) 470 { 471 struct hid_device *hdev = to_hid_device(dev); 472 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 473 int value; 474 475 if (kstrtoint(buf, 10, &value)) 476 return -EINVAL; 477 if (value < 0 || value > 1) 478 return -EINVAL; 479 480 data_pointer->dragging = value; 481 lenovo_features_set_tpkbd(hdev); 482 483 return count; 484 } 485 486 static ssize_t attr_release_to_select_show_tpkbd(struct device *dev, 487 struct device_attribute *attr, 488 char *buf) 489 { 490 struct hid_device *hdev = to_hid_device(dev); 491 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 492 493 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->release_to_select); 494 } 495 496 static ssize_t attr_release_to_select_store_tpkbd(struct device *dev, 497 struct device_attribute *attr, 498 const char *buf, 499 size_t count) 500 { 501 struct hid_device *hdev = to_hid_device(dev); 502 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 503 int value; 504 505 if (kstrtoint(buf, 10, &value)) 506 return -EINVAL; 507 if (value < 0 || value > 1) 508 return -EINVAL; 509 510 data_pointer->release_to_select = value; 511 lenovo_features_set_tpkbd(hdev); 512 513 return count; 514 } 515 516 static ssize_t attr_select_right_show_tpkbd(struct device *dev, 517 struct device_attribute *attr, 518 char *buf) 519 { 520 struct hid_device *hdev = to_hid_device(dev); 521 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 522 523 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->select_right); 524 } 525 526 static ssize_t attr_select_right_store_tpkbd(struct device *dev, 527 struct device_attribute *attr, 528 const char *buf, 529 size_t count) 530 { 531 struct hid_device *hdev = to_hid_device(dev); 532 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 533 int value; 534 535 if (kstrtoint(buf, 10, &value)) 536 return -EINVAL; 537 if (value < 0 || value > 1) 538 return -EINVAL; 539 540 data_pointer->select_right = value; 541 lenovo_features_set_tpkbd(hdev); 542 543 return count; 544 } 545 546 static ssize_t attr_sensitivity_show_tpkbd(struct device *dev, 547 struct device_attribute *attr, 548 char *buf) 549 { 550 struct hid_device *hdev = to_hid_device(dev); 551 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 552 553 return snprintf(buf, PAGE_SIZE, "%u\n", 554 data_pointer->sensitivity); 555 } 556 557 static ssize_t attr_sensitivity_store_tpkbd(struct device *dev, 558 struct device_attribute *attr, 559 const char *buf, 560 size_t count) 561 { 562 struct hid_device *hdev = to_hid_device(dev); 563 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 564 int value; 565 566 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255) 567 return -EINVAL; 568 569 data_pointer->sensitivity = value; 570 lenovo_features_set_tpkbd(hdev); 571 572 return count; 573 } 574 575 static ssize_t attr_press_speed_show_tpkbd(struct device *dev, 576 struct device_attribute *attr, 577 char *buf) 578 { 579 struct hid_device *hdev = to_hid_device(dev); 580 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 581 582 return snprintf(buf, PAGE_SIZE, "%u\n", 583 data_pointer->press_speed); 584 } 585 586 static ssize_t attr_press_speed_store_tpkbd(struct device *dev, 587 struct device_attribute *attr, 588 const char *buf, 589 size_t count) 590 { 591 struct hid_device *hdev = to_hid_device(dev); 592 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 593 int value; 594 595 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255) 596 return -EINVAL; 597 598 data_pointer->press_speed = value; 599 lenovo_features_set_tpkbd(hdev); 600 601 return count; 602 } 603 604 static struct device_attribute dev_attr_press_to_select_tpkbd = 605 __ATTR(press_to_select, S_IWUSR | S_IRUGO, 606 attr_press_to_select_show_tpkbd, 607 attr_press_to_select_store_tpkbd); 608 609 static struct device_attribute dev_attr_dragging_tpkbd = 610 __ATTR(dragging, S_IWUSR | S_IRUGO, 611 attr_dragging_show_tpkbd, 612 attr_dragging_store_tpkbd); 613 614 static struct device_attribute dev_attr_release_to_select_tpkbd = 615 __ATTR(release_to_select, S_IWUSR | S_IRUGO, 616 attr_release_to_select_show_tpkbd, 617 attr_release_to_select_store_tpkbd); 618 619 static struct device_attribute dev_attr_select_right_tpkbd = 620 __ATTR(select_right, S_IWUSR | S_IRUGO, 621 attr_select_right_show_tpkbd, 622 attr_select_right_store_tpkbd); 623 624 static struct device_attribute dev_attr_sensitivity_tpkbd = 625 __ATTR(sensitivity, S_IWUSR | S_IRUGO, 626 attr_sensitivity_show_tpkbd, 627 attr_sensitivity_store_tpkbd); 628 629 static struct device_attribute dev_attr_press_speed_tpkbd = 630 __ATTR(press_speed, S_IWUSR | S_IRUGO, 631 attr_press_speed_show_tpkbd, 632 attr_press_speed_store_tpkbd); 633 634 static struct attribute *lenovo_attributes_tpkbd[] = { 635 &dev_attr_press_to_select_tpkbd.attr, 636 &dev_attr_dragging_tpkbd.attr, 637 &dev_attr_release_to_select_tpkbd.attr, 638 &dev_attr_select_right_tpkbd.attr, 639 &dev_attr_sensitivity_tpkbd.attr, 640 &dev_attr_press_speed_tpkbd.attr, 641 NULL 642 }; 643 644 static const struct attribute_group lenovo_attr_group_tpkbd = { 645 .attrs = lenovo_attributes_tpkbd, 646 }; 647 648 static enum led_brightness lenovo_led_brightness_get_tpkbd( 649 struct led_classdev *led_cdev) 650 { 651 struct device *dev = led_cdev->dev->parent; 652 struct hid_device *hdev = to_hid_device(dev); 653 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 654 int led_nr = 0; 655 656 if (led_cdev == &data_pointer->led_micmute) 657 led_nr = 1; 658 659 return data_pointer->led_state & (1 << led_nr) 660 ? LED_FULL 661 : LED_OFF; 662 } 663 664 static void lenovo_led_brightness_set_tpkbd(struct led_classdev *led_cdev, 665 enum led_brightness value) 666 { 667 struct device *dev = led_cdev->dev->parent; 668 struct hid_device *hdev = to_hid_device(dev); 669 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 670 struct hid_report *report; 671 int led_nr = 0; 672 673 if (led_cdev == &data_pointer->led_micmute) 674 led_nr = 1; 675 676 if (value == LED_OFF) 677 data_pointer->led_state &= ~(1 << led_nr); 678 else 679 data_pointer->led_state |= 1 << led_nr; 680 681 report = hdev->report_enum[HID_OUTPUT_REPORT].report_id_hash[3]; 682 report->field[0]->value[0] = (data_pointer->led_state >> 0) & 1; 683 report->field[0]->value[1] = (data_pointer->led_state >> 1) & 1; 684 hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 685 } 686 687 static int lenovo_probe_tpkbd(struct hid_device *hdev) 688 { 689 struct device *dev = &hdev->dev; 690 struct lenovo_drvdata_tpkbd *data_pointer; 691 size_t name_sz = strlen(dev_name(dev)) + 16; 692 char *name_mute, *name_micmute; 693 int i; 694 int ret; 695 696 /* 697 * Only register extra settings against subdevice where input_mapping 698 * set drvdata to 1, i.e. the trackpoint. 699 */ 700 if (!hid_get_drvdata(hdev)) 701 return 0; 702 703 hid_set_drvdata(hdev, NULL); 704 705 /* Validate required reports. */ 706 for (i = 0; i < 4; i++) { 707 if (!hid_validate_values(hdev, HID_FEATURE_REPORT, 4, i, 1)) 708 return -ENODEV; 709 } 710 if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 3, 0, 2)) 711 return -ENODEV; 712 713 ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_tpkbd); 714 if (ret) 715 hid_warn(hdev, "Could not create sysfs group: %d\n", ret); 716 717 data_pointer = devm_kzalloc(&hdev->dev, 718 sizeof(struct lenovo_drvdata_tpkbd), 719 GFP_KERNEL); 720 if (data_pointer == NULL) { 721 hid_err(hdev, "Could not allocate memory for driver data\n"); 722 ret = -ENOMEM; 723 goto err; 724 } 725 726 // set same default values as windows driver 727 data_pointer->sensitivity = 0xa0; 728 data_pointer->press_speed = 0x38; 729 730 name_mute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL); 731 name_micmute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL); 732 if (name_mute == NULL || name_micmute == NULL) { 733 hid_err(hdev, "Could not allocate memory for led data\n"); 734 ret = -ENOMEM; 735 goto err; 736 } 737 snprintf(name_mute, name_sz, "%s:amber:mute", dev_name(dev)); 738 snprintf(name_micmute, name_sz, "%s:amber:micmute", dev_name(dev)); 739 740 hid_set_drvdata(hdev, data_pointer); 741 742 data_pointer->led_mute.name = name_mute; 743 data_pointer->led_mute.brightness_get = lenovo_led_brightness_get_tpkbd; 744 data_pointer->led_mute.brightness_set = lenovo_led_brightness_set_tpkbd; 745 data_pointer->led_mute.dev = dev; 746 ret = led_classdev_register(dev, &data_pointer->led_mute); 747 if (ret < 0) 748 goto err; 749 750 data_pointer->led_micmute.name = name_micmute; 751 data_pointer->led_micmute.brightness_get = 752 lenovo_led_brightness_get_tpkbd; 753 data_pointer->led_micmute.brightness_set = 754 lenovo_led_brightness_set_tpkbd; 755 data_pointer->led_micmute.dev = dev; 756 ret = led_classdev_register(dev, &data_pointer->led_micmute); 757 if (ret < 0) { 758 led_classdev_unregister(&data_pointer->led_mute); 759 goto err; 760 } 761 762 lenovo_features_set_tpkbd(hdev); 763 764 return 0; 765 err: 766 sysfs_remove_group(&hdev->dev.kobj, &lenovo_attr_group_tpkbd); 767 return ret; 768 } 769 770 static int lenovo_probe_cptkbd(struct hid_device *hdev) 771 { 772 int ret; 773 struct lenovo_drvdata_cptkbd *cptkbd_data; 774 775 /* All the custom action happens on the USBMOUSE device for USB */ 776 if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD 777 && hdev->type != HID_TYPE_USBMOUSE) { 778 hid_dbg(hdev, "Ignoring keyboard half of device\n"); 779 return 0; 780 } 781 782 cptkbd_data = devm_kzalloc(&hdev->dev, 783 sizeof(*cptkbd_data), 784 GFP_KERNEL); 785 if (cptkbd_data == NULL) { 786 hid_err(hdev, "can't alloc keyboard descriptor\n"); 787 return -ENOMEM; 788 } 789 hid_set_drvdata(hdev, cptkbd_data); 790 791 /* 792 * Tell the keyboard a driver understands it, and turn F7, F9, F11 into 793 * regular keys 794 */ 795 ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03); 796 if (ret) 797 hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); 798 799 /* Switch middle button to native mode */ 800 ret = lenovo_send_cmd_cptkbd(hdev, 0x09, 0x01); 801 if (ret) 802 hid_warn(hdev, "Failed to switch middle button: %d\n", ret); 803 804 /* Set keyboard settings to known state */ 805 cptkbd_data->middlebutton_state = 0; 806 cptkbd_data->fn_lock = true; 807 cptkbd_data->sensitivity = 0x05; 808 lenovo_features_set_cptkbd(hdev); 809 810 ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd); 811 if (ret) 812 hid_warn(hdev, "Could not create sysfs group: %d\n", ret); 813 814 return 0; 815 } 816 817 static int lenovo_probe(struct hid_device *hdev, 818 const struct hid_device_id *id) 819 { 820 int ret; 821 822 ret = hid_parse(hdev); 823 if (ret) { 824 hid_err(hdev, "hid_parse failed\n"); 825 goto err; 826 } 827 828 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 829 if (ret) { 830 hid_err(hdev, "hid_hw_start failed\n"); 831 goto err; 832 } 833 834 switch (hdev->product) { 835 case USB_DEVICE_ID_LENOVO_TPKBD: 836 ret = lenovo_probe_tpkbd(hdev); 837 break; 838 case USB_DEVICE_ID_LENOVO_CUSBKBD: 839 case USB_DEVICE_ID_LENOVO_CBTKBD: 840 ret = lenovo_probe_cptkbd(hdev); 841 break; 842 default: 843 ret = 0; 844 break; 845 } 846 if (ret) 847 goto err_hid; 848 849 return 0; 850 err_hid: 851 hid_hw_stop(hdev); 852 err: 853 return ret; 854 } 855 856 static void lenovo_remove_tpkbd(struct hid_device *hdev) 857 { 858 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 859 860 /* 861 * Only the trackpoint half of the keyboard has drvdata and stuff that 862 * needs unregistering. 863 */ 864 if (data_pointer == NULL) 865 return; 866 867 sysfs_remove_group(&hdev->dev.kobj, 868 &lenovo_attr_group_tpkbd); 869 870 led_classdev_unregister(&data_pointer->led_micmute); 871 led_classdev_unregister(&data_pointer->led_mute); 872 873 hid_set_drvdata(hdev, NULL); 874 } 875 876 static void lenovo_remove_cptkbd(struct hid_device *hdev) 877 { 878 sysfs_remove_group(&hdev->dev.kobj, 879 &lenovo_attr_group_cptkbd); 880 } 881 882 static void lenovo_remove(struct hid_device *hdev) 883 { 884 switch (hdev->product) { 885 case USB_DEVICE_ID_LENOVO_TPKBD: 886 lenovo_remove_tpkbd(hdev); 887 break; 888 case USB_DEVICE_ID_LENOVO_CUSBKBD: 889 case USB_DEVICE_ID_LENOVO_CBTKBD: 890 lenovo_remove_cptkbd(hdev); 891 break; 892 } 893 894 hid_hw_stop(hdev); 895 } 896 897 static int lenovo_input_configured(struct hid_device *hdev, 898 struct hid_input *hi) 899 { 900 switch (hdev->product) { 901 case USB_DEVICE_ID_LENOVO_TPKBD: 902 case USB_DEVICE_ID_LENOVO_CUSBKBD: 903 case USB_DEVICE_ID_LENOVO_CBTKBD: 904 if (test_bit(EV_REL, hi->input->evbit)) { 905 /* set only for trackpoint device */ 906 __set_bit(INPUT_PROP_POINTER, hi->input->propbit); 907 __set_bit(INPUT_PROP_POINTING_STICK, 908 hi->input->propbit); 909 } 910 break; 911 } 912 913 return 0; 914 } 915 916 917 static const struct hid_device_id lenovo_devices[] = { 918 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) }, 919 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) }, 920 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) }, 921 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPPRODOCK) }, 922 { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_III) }, 923 { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_PRO) }, 924 { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_OPTICAL) }, 925 { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL) }, 926 { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL_PRO) }, 927 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL) }, 928 { } 929 }; 930 931 MODULE_DEVICE_TABLE(hid, lenovo_devices); 932 933 static struct hid_driver lenovo_driver = { 934 .name = "lenovo", 935 .id_table = lenovo_devices, 936 .input_configured = lenovo_input_configured, 937 .input_mapping = lenovo_input_mapping, 938 .probe = lenovo_probe, 939 .remove = lenovo_remove, 940 .raw_event = lenovo_raw_event, 941 .event = lenovo_event, 942 .report_fixup = lenovo_report_fixup, 943 }; 944 module_hid_driver(lenovo_driver); 945 946 MODULE_LICENSE("GPL"); 947