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