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 led_classdev_register(dev, &data_pointer->led_mute); 747 748 data_pointer->led_micmute.name = name_micmute; 749 data_pointer->led_micmute.brightness_get = 750 lenovo_led_brightness_get_tpkbd; 751 data_pointer->led_micmute.brightness_set = 752 lenovo_led_brightness_set_tpkbd; 753 data_pointer->led_micmute.dev = dev; 754 led_classdev_register(dev, &data_pointer->led_micmute); 755 756 lenovo_features_set_tpkbd(hdev); 757 758 return 0; 759 err: 760 sysfs_remove_group(&hdev->dev.kobj, &lenovo_attr_group_tpkbd); 761 return ret; 762 } 763 764 static int lenovo_probe_cptkbd(struct hid_device *hdev) 765 { 766 int ret; 767 struct lenovo_drvdata_cptkbd *cptkbd_data; 768 769 /* All the custom action happens on the USBMOUSE device for USB */ 770 if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD 771 && hdev->type != HID_TYPE_USBMOUSE) { 772 hid_dbg(hdev, "Ignoring keyboard half of device\n"); 773 return 0; 774 } 775 776 cptkbd_data = devm_kzalloc(&hdev->dev, 777 sizeof(*cptkbd_data), 778 GFP_KERNEL); 779 if (cptkbd_data == NULL) { 780 hid_err(hdev, "can't alloc keyboard descriptor\n"); 781 return -ENOMEM; 782 } 783 hid_set_drvdata(hdev, cptkbd_data); 784 785 /* 786 * Tell the keyboard a driver understands it, and turn F7, F9, F11 into 787 * regular keys 788 */ 789 ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03); 790 if (ret) 791 hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); 792 793 /* Switch middle button to native mode */ 794 ret = lenovo_send_cmd_cptkbd(hdev, 0x09, 0x01); 795 if (ret) 796 hid_warn(hdev, "Failed to switch middle button: %d\n", ret); 797 798 /* Set keyboard settings to known state */ 799 cptkbd_data->middlebutton_state = 0; 800 cptkbd_data->fn_lock = true; 801 cptkbd_data->sensitivity = 0x05; 802 lenovo_features_set_cptkbd(hdev); 803 804 ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd); 805 if (ret) 806 hid_warn(hdev, "Could not create sysfs group: %d\n", ret); 807 808 return 0; 809 } 810 811 static int lenovo_probe(struct hid_device *hdev, 812 const struct hid_device_id *id) 813 { 814 int ret; 815 816 ret = hid_parse(hdev); 817 if (ret) { 818 hid_err(hdev, "hid_parse failed\n"); 819 goto err; 820 } 821 822 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 823 if (ret) { 824 hid_err(hdev, "hid_hw_start failed\n"); 825 goto err; 826 } 827 828 switch (hdev->product) { 829 case USB_DEVICE_ID_LENOVO_TPKBD: 830 ret = lenovo_probe_tpkbd(hdev); 831 break; 832 case USB_DEVICE_ID_LENOVO_CUSBKBD: 833 case USB_DEVICE_ID_LENOVO_CBTKBD: 834 ret = lenovo_probe_cptkbd(hdev); 835 break; 836 default: 837 ret = 0; 838 break; 839 } 840 if (ret) 841 goto err_hid; 842 843 return 0; 844 err_hid: 845 hid_hw_stop(hdev); 846 err: 847 return ret; 848 } 849 850 static void lenovo_remove_tpkbd(struct hid_device *hdev) 851 { 852 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 853 854 /* 855 * Only the trackpoint half of the keyboard has drvdata and stuff that 856 * needs unregistering. 857 */ 858 if (data_pointer == NULL) 859 return; 860 861 sysfs_remove_group(&hdev->dev.kobj, 862 &lenovo_attr_group_tpkbd); 863 864 led_classdev_unregister(&data_pointer->led_micmute); 865 led_classdev_unregister(&data_pointer->led_mute); 866 867 hid_set_drvdata(hdev, NULL); 868 } 869 870 static void lenovo_remove_cptkbd(struct hid_device *hdev) 871 { 872 sysfs_remove_group(&hdev->dev.kobj, 873 &lenovo_attr_group_cptkbd); 874 } 875 876 static void lenovo_remove(struct hid_device *hdev) 877 { 878 switch (hdev->product) { 879 case USB_DEVICE_ID_LENOVO_TPKBD: 880 lenovo_remove_tpkbd(hdev); 881 break; 882 case USB_DEVICE_ID_LENOVO_CUSBKBD: 883 case USB_DEVICE_ID_LENOVO_CBTKBD: 884 lenovo_remove_cptkbd(hdev); 885 break; 886 } 887 888 hid_hw_stop(hdev); 889 } 890 891 static int lenovo_input_configured(struct hid_device *hdev, 892 struct hid_input *hi) 893 { 894 switch (hdev->product) { 895 case USB_DEVICE_ID_LENOVO_TPKBD: 896 case USB_DEVICE_ID_LENOVO_CUSBKBD: 897 case USB_DEVICE_ID_LENOVO_CBTKBD: 898 if (test_bit(EV_REL, hi->input->evbit)) { 899 /* set only for trackpoint device */ 900 __set_bit(INPUT_PROP_POINTER, hi->input->propbit); 901 __set_bit(INPUT_PROP_POINTING_STICK, 902 hi->input->propbit); 903 } 904 break; 905 } 906 907 return 0; 908 } 909 910 911 static const struct hid_device_id lenovo_devices[] = { 912 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) }, 913 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) }, 914 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) }, 915 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPPRODOCK) }, 916 { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_III) }, 917 { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_PRO) }, 918 { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_OPTICAL) }, 919 { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL) }, 920 { HID_USB_DEVICE(USB_VENDOR_ID_IBM, USB_DEVICE_ID_IBM_SCROLLPOINT_800DPI_OPTICAL_PRO) }, 921 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL) }, 922 { } 923 }; 924 925 MODULE_DEVICE_TABLE(hid, lenovo_devices); 926 927 static struct hid_driver lenovo_driver = { 928 .name = "lenovo", 929 .id_table = lenovo_devices, 930 .input_configured = lenovo_input_configured, 931 .input_mapping = lenovo_input_mapping, 932 .probe = lenovo_probe, 933 .remove = lenovo_remove, 934 .raw_event = lenovo_raw_event, 935 .event = lenovo_event, 936 .report_fixup = lenovo_report_fixup, 937 }; 938 module_hid_driver(lenovo_driver); 939 940 MODULE_LICENSE("GPL"); 941