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 bool fn_lock; 41 }; 42 43 #define map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c)) 44 45 static int lenovo_input_mapping_tpkbd(struct hid_device *hdev, 46 struct hid_input *hi, struct hid_field *field, 47 struct hid_usage *usage, unsigned long **bit, int *max) 48 { 49 if (usage->hid == (HID_UP_BUTTON | 0x0010)) { 50 /* This sub-device contains trackpoint, mark it */ 51 hid_set_drvdata(hdev, (void *)1); 52 map_key_clear(KEY_MICMUTE); 53 return 1; 54 } 55 return 0; 56 } 57 58 static int lenovo_input_mapping_cptkbd(struct hid_device *hdev, 59 struct hid_input *hi, struct hid_field *field, 60 struct hid_usage *usage, unsigned long **bit, int *max) 61 { 62 /* HID_UP_LNVENDOR = USB, HID_UP_MSVENDOR = BT */ 63 if ((usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR || 64 (usage->hid & HID_USAGE_PAGE) == HID_UP_LNVENDOR) { 65 switch (usage->hid & HID_USAGE) { 66 case 0x00f1: /* Fn-F4: Mic mute */ 67 map_key_clear(KEY_MICMUTE); 68 return 1; 69 case 0x00f2: /* Fn-F5: Brightness down */ 70 map_key_clear(KEY_BRIGHTNESSDOWN); 71 return 1; 72 case 0x00f3: /* Fn-F6: Brightness up */ 73 map_key_clear(KEY_BRIGHTNESSUP); 74 return 1; 75 case 0x00f4: /* Fn-F7: External display (projector) */ 76 map_key_clear(KEY_SWITCHVIDEOMODE); 77 return 1; 78 case 0x00f5: /* Fn-F8: Wireless */ 79 map_key_clear(KEY_WLAN); 80 return 1; 81 case 0x00f6: /* Fn-F9: Control panel */ 82 map_key_clear(KEY_CONFIG); 83 return 1; 84 case 0x00f8: /* Fn-F11: View open applications (3 boxes) */ 85 map_key_clear(KEY_SCALE); 86 return 1; 87 case 0x00f9: /* Fn-F12: Open My computer (6 boxes) USB-only */ 88 /* NB: This mapping is invented in raw_event below */ 89 map_key_clear(KEY_FILE); 90 return 1; 91 case 0x00fa: /* Fn-Esc: Fn-lock toggle */ 92 map_key_clear(KEY_FN_ESC); 93 return 1; 94 } 95 } 96 97 return 0; 98 } 99 100 static int lenovo_input_mapping(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 switch (hdev->product) { 105 case USB_DEVICE_ID_LENOVO_TPKBD: 106 return lenovo_input_mapping_tpkbd(hdev, hi, field, 107 usage, bit, max); 108 case USB_DEVICE_ID_LENOVO_CUSBKBD: 109 case USB_DEVICE_ID_LENOVO_CBTKBD: 110 return lenovo_input_mapping_cptkbd(hdev, hi, field, 111 usage, bit, max); 112 default: 113 return 0; 114 } 115 } 116 117 #undef map_key_clear 118 119 /* Send a config command to the keyboard */ 120 static int lenovo_send_cmd_cptkbd(struct hid_device *hdev, 121 unsigned char byte2, unsigned char byte3) 122 { 123 int ret; 124 unsigned char buf[] = {0x18, byte2, byte3}; 125 126 switch (hdev->product) { 127 case USB_DEVICE_ID_LENOVO_CUSBKBD: 128 ret = hid_hw_raw_request(hdev, 0x13, buf, sizeof(buf), 129 HID_FEATURE_REPORT, HID_REQ_SET_REPORT); 130 break; 131 case USB_DEVICE_ID_LENOVO_CBTKBD: 132 ret = hid_hw_output_report(hdev, buf, sizeof(buf)); 133 break; 134 default: 135 ret = -EINVAL; 136 break; 137 } 138 139 return ret < 0 ? ret : 0; /* BT returns 0, USB returns sizeof(buf) */ 140 } 141 142 static void lenovo_features_set_cptkbd(struct hid_device *hdev) 143 { 144 int ret; 145 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); 146 147 ret = lenovo_send_cmd_cptkbd(hdev, 0x05, cptkbd_data->fn_lock); 148 if (ret) 149 hid_err(hdev, "Fn-lock setting failed: %d\n", ret); 150 } 151 152 static ssize_t attr_fn_lock_show_cptkbd(struct device *dev, 153 struct device_attribute *attr, 154 char *buf) 155 { 156 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 157 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); 158 159 return snprintf(buf, PAGE_SIZE, "%u\n", cptkbd_data->fn_lock); 160 } 161 162 static ssize_t attr_fn_lock_store_cptkbd(struct device *dev, 163 struct device_attribute *attr, 164 const char *buf, 165 size_t count) 166 { 167 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 168 struct lenovo_drvdata_cptkbd *cptkbd_data = hid_get_drvdata(hdev); 169 int value; 170 171 if (kstrtoint(buf, 10, &value)) 172 return -EINVAL; 173 if (value < 0 || value > 1) 174 return -EINVAL; 175 176 cptkbd_data->fn_lock = !!value; 177 lenovo_features_set_cptkbd(hdev); 178 179 return count; 180 } 181 182 static struct device_attribute dev_attr_fn_lock_cptkbd = 183 __ATTR(fn_lock, S_IWUSR | S_IRUGO, 184 attr_fn_lock_show_cptkbd, 185 attr_fn_lock_store_cptkbd); 186 187 static struct attribute *lenovo_attributes_cptkbd[] = { 188 &dev_attr_fn_lock_cptkbd.attr, 189 NULL 190 }; 191 192 static const struct attribute_group lenovo_attr_group_cptkbd = { 193 .attrs = lenovo_attributes_cptkbd, 194 }; 195 196 static int lenovo_raw_event(struct hid_device *hdev, 197 struct hid_report *report, u8 *data, int size) 198 { 199 /* 200 * Compact USB keyboard's Fn-F12 report holds down many other keys, and 201 * its own key is outside the usage page range. Remove extra 202 * keypresses and remap to inside usage page. 203 */ 204 if (unlikely(hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD 205 && size == 3 206 && data[0] == 0x15 207 && data[1] == 0x94 208 && data[2] == 0x01)) { 209 data[1] = 0x00; 210 data[2] = 0x01; 211 } 212 213 return 0; 214 } 215 216 static int lenovo_features_set_tpkbd(struct hid_device *hdev) 217 { 218 struct hid_report *report; 219 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 220 221 report = hdev->report_enum[HID_FEATURE_REPORT].report_id_hash[4]; 222 223 report->field[0]->value[0] = data_pointer->press_to_select ? 0x01 : 0x02; 224 report->field[0]->value[0] |= data_pointer->dragging ? 0x04 : 0x08; 225 report->field[0]->value[0] |= data_pointer->release_to_select ? 0x10 : 0x20; 226 report->field[0]->value[0] |= data_pointer->select_right ? 0x80 : 0x40; 227 report->field[1]->value[0] = 0x03; // unknown setting, imitate windows driver 228 report->field[2]->value[0] = data_pointer->sensitivity; 229 report->field[3]->value[0] = data_pointer->press_speed; 230 231 hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 232 return 0; 233 } 234 235 static ssize_t attr_press_to_select_show_tpkbd(struct device *dev, 236 struct device_attribute *attr, 237 char *buf) 238 { 239 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 240 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 241 242 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->press_to_select); 243 } 244 245 static ssize_t attr_press_to_select_store_tpkbd(struct device *dev, 246 struct device_attribute *attr, 247 const char *buf, 248 size_t count) 249 { 250 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 251 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 252 int value; 253 254 if (kstrtoint(buf, 10, &value)) 255 return -EINVAL; 256 if (value < 0 || value > 1) 257 return -EINVAL; 258 259 data_pointer->press_to_select = value; 260 lenovo_features_set_tpkbd(hdev); 261 262 return count; 263 } 264 265 static ssize_t attr_dragging_show_tpkbd(struct device *dev, 266 struct device_attribute *attr, 267 char *buf) 268 { 269 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 270 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 271 272 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->dragging); 273 } 274 275 static ssize_t attr_dragging_store_tpkbd(struct device *dev, 276 struct device_attribute *attr, 277 const char *buf, 278 size_t count) 279 { 280 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 281 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 282 int value; 283 284 if (kstrtoint(buf, 10, &value)) 285 return -EINVAL; 286 if (value < 0 || value > 1) 287 return -EINVAL; 288 289 data_pointer->dragging = value; 290 lenovo_features_set_tpkbd(hdev); 291 292 return count; 293 } 294 295 static ssize_t attr_release_to_select_show_tpkbd(struct device *dev, 296 struct device_attribute *attr, 297 char *buf) 298 { 299 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 300 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 301 302 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->release_to_select); 303 } 304 305 static ssize_t attr_release_to_select_store_tpkbd(struct device *dev, 306 struct device_attribute *attr, 307 const char *buf, 308 size_t count) 309 { 310 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 311 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 312 int value; 313 314 if (kstrtoint(buf, 10, &value)) 315 return -EINVAL; 316 if (value < 0 || value > 1) 317 return -EINVAL; 318 319 data_pointer->release_to_select = value; 320 lenovo_features_set_tpkbd(hdev); 321 322 return count; 323 } 324 325 static ssize_t attr_select_right_show_tpkbd(struct device *dev, 326 struct device_attribute *attr, 327 char *buf) 328 { 329 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 330 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 331 332 return snprintf(buf, PAGE_SIZE, "%u\n", data_pointer->select_right); 333 } 334 335 static ssize_t attr_select_right_store_tpkbd(struct device *dev, 336 struct device_attribute *attr, 337 const char *buf, 338 size_t count) 339 { 340 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 341 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 342 int value; 343 344 if (kstrtoint(buf, 10, &value)) 345 return -EINVAL; 346 if (value < 0 || value > 1) 347 return -EINVAL; 348 349 data_pointer->select_right = value; 350 lenovo_features_set_tpkbd(hdev); 351 352 return count; 353 } 354 355 static ssize_t attr_sensitivity_show_tpkbd(struct device *dev, 356 struct device_attribute *attr, 357 char *buf) 358 { 359 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 360 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 361 362 return snprintf(buf, PAGE_SIZE, "%u\n", 363 data_pointer->sensitivity); 364 } 365 366 static ssize_t attr_sensitivity_store_tpkbd(struct device *dev, 367 struct device_attribute *attr, 368 const char *buf, 369 size_t count) 370 { 371 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 372 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 373 int value; 374 375 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255) 376 return -EINVAL; 377 378 data_pointer->sensitivity = value; 379 lenovo_features_set_tpkbd(hdev); 380 381 return count; 382 } 383 384 static ssize_t attr_press_speed_show_tpkbd(struct device *dev, 385 struct device_attribute *attr, 386 char *buf) 387 { 388 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 389 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 390 391 return snprintf(buf, PAGE_SIZE, "%u\n", 392 data_pointer->press_speed); 393 } 394 395 static ssize_t attr_press_speed_store_tpkbd(struct device *dev, 396 struct device_attribute *attr, 397 const char *buf, 398 size_t count) 399 { 400 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 401 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 402 int value; 403 404 if (kstrtoint(buf, 10, &value) || value < 1 || value > 255) 405 return -EINVAL; 406 407 data_pointer->press_speed = value; 408 lenovo_features_set_tpkbd(hdev); 409 410 return count; 411 } 412 413 static struct device_attribute dev_attr_press_to_select_tpkbd = 414 __ATTR(press_to_select, S_IWUSR | S_IRUGO, 415 attr_press_to_select_show_tpkbd, 416 attr_press_to_select_store_tpkbd); 417 418 static struct device_attribute dev_attr_dragging_tpkbd = 419 __ATTR(dragging, S_IWUSR | S_IRUGO, 420 attr_dragging_show_tpkbd, 421 attr_dragging_store_tpkbd); 422 423 static struct device_attribute dev_attr_release_to_select_tpkbd = 424 __ATTR(release_to_select, S_IWUSR | S_IRUGO, 425 attr_release_to_select_show_tpkbd, 426 attr_release_to_select_store_tpkbd); 427 428 static struct device_attribute dev_attr_select_right_tpkbd = 429 __ATTR(select_right, S_IWUSR | S_IRUGO, 430 attr_select_right_show_tpkbd, 431 attr_select_right_store_tpkbd); 432 433 static struct device_attribute dev_attr_sensitivity_tpkbd = 434 __ATTR(sensitivity, S_IWUSR | S_IRUGO, 435 attr_sensitivity_show_tpkbd, 436 attr_sensitivity_store_tpkbd); 437 438 static struct device_attribute dev_attr_press_speed_tpkbd = 439 __ATTR(press_speed, S_IWUSR | S_IRUGO, 440 attr_press_speed_show_tpkbd, 441 attr_press_speed_store_tpkbd); 442 443 static struct attribute *lenovo_attributes_tpkbd[] = { 444 &dev_attr_press_to_select_tpkbd.attr, 445 &dev_attr_dragging_tpkbd.attr, 446 &dev_attr_release_to_select_tpkbd.attr, 447 &dev_attr_select_right_tpkbd.attr, 448 &dev_attr_sensitivity_tpkbd.attr, 449 &dev_attr_press_speed_tpkbd.attr, 450 NULL 451 }; 452 453 static const struct attribute_group lenovo_attr_group_tpkbd = { 454 .attrs = lenovo_attributes_tpkbd, 455 }; 456 457 static enum led_brightness lenovo_led_brightness_get_tpkbd( 458 struct led_classdev *led_cdev) 459 { 460 struct device *dev = led_cdev->dev->parent; 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 led_nr = 0; 464 465 if (led_cdev == &data_pointer->led_micmute) 466 led_nr = 1; 467 468 return data_pointer->led_state & (1 << led_nr) 469 ? LED_FULL 470 : LED_OFF; 471 } 472 473 static void lenovo_led_brightness_set_tpkbd(struct led_classdev *led_cdev, 474 enum led_brightness value) 475 { 476 struct device *dev = led_cdev->dev->parent; 477 struct hid_device *hdev = container_of(dev, struct hid_device, dev); 478 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 479 struct hid_report *report; 480 int led_nr = 0; 481 482 if (led_cdev == &data_pointer->led_micmute) 483 led_nr = 1; 484 485 if (value == LED_OFF) 486 data_pointer->led_state &= ~(1 << led_nr); 487 else 488 data_pointer->led_state |= 1 << led_nr; 489 490 report = hdev->report_enum[HID_OUTPUT_REPORT].report_id_hash[3]; 491 report->field[0]->value[0] = (data_pointer->led_state >> 0) & 1; 492 report->field[0]->value[1] = (data_pointer->led_state >> 1) & 1; 493 hid_hw_request(hdev, report, HID_REQ_SET_REPORT); 494 } 495 496 static int lenovo_probe_tpkbd(struct hid_device *hdev) 497 { 498 struct device *dev = &hdev->dev; 499 struct lenovo_drvdata_tpkbd *data_pointer; 500 size_t name_sz = strlen(dev_name(dev)) + 16; 501 char *name_mute, *name_micmute; 502 int i; 503 int ret; 504 505 /* 506 * Only register extra settings against subdevice where input_mapping 507 * set drvdata to 1, i.e. the trackpoint. 508 */ 509 if (!hid_get_drvdata(hdev)) 510 return 0; 511 512 hid_set_drvdata(hdev, NULL); 513 514 /* Validate required reports. */ 515 for (i = 0; i < 4; i++) { 516 if (!hid_validate_values(hdev, HID_FEATURE_REPORT, 4, i, 1)) 517 return -ENODEV; 518 } 519 if (!hid_validate_values(hdev, HID_OUTPUT_REPORT, 3, 0, 2)) 520 return -ENODEV; 521 522 ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_tpkbd); 523 if (ret) 524 hid_warn(hdev, "Could not create sysfs group: %d\n", ret); 525 526 data_pointer = devm_kzalloc(&hdev->dev, 527 sizeof(struct lenovo_drvdata_tpkbd), 528 GFP_KERNEL); 529 if (data_pointer == NULL) { 530 hid_err(hdev, "Could not allocate memory for driver data\n"); 531 return -ENOMEM; 532 } 533 534 // set same default values as windows driver 535 data_pointer->sensitivity = 0xa0; 536 data_pointer->press_speed = 0x38; 537 538 name_mute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL); 539 name_micmute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL); 540 if (name_mute == NULL || name_micmute == NULL) { 541 hid_err(hdev, "Could not allocate memory for led data\n"); 542 return -ENOMEM; 543 } 544 snprintf(name_mute, name_sz, "%s:amber:mute", dev_name(dev)); 545 snprintf(name_micmute, name_sz, "%s:amber:micmute", dev_name(dev)); 546 547 hid_set_drvdata(hdev, data_pointer); 548 549 data_pointer->led_mute.name = name_mute; 550 data_pointer->led_mute.brightness_get = lenovo_led_brightness_get_tpkbd; 551 data_pointer->led_mute.brightness_set = lenovo_led_brightness_set_tpkbd; 552 data_pointer->led_mute.dev = dev; 553 led_classdev_register(dev, &data_pointer->led_mute); 554 555 data_pointer->led_micmute.name = name_micmute; 556 data_pointer->led_micmute.brightness_get = 557 lenovo_led_brightness_get_tpkbd; 558 data_pointer->led_micmute.brightness_set = 559 lenovo_led_brightness_set_tpkbd; 560 data_pointer->led_micmute.dev = dev; 561 led_classdev_register(dev, &data_pointer->led_micmute); 562 563 lenovo_features_set_tpkbd(hdev); 564 565 return 0; 566 } 567 568 static int lenovo_probe_cptkbd(struct hid_device *hdev) 569 { 570 int ret; 571 struct lenovo_drvdata_cptkbd *cptkbd_data; 572 573 /* All the custom action happens on the USBMOUSE device for USB */ 574 if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD 575 && hdev->type != HID_TYPE_USBMOUSE) { 576 hid_dbg(hdev, "Ignoring keyboard half of device\n"); 577 return 0; 578 } 579 580 cptkbd_data = devm_kzalloc(&hdev->dev, 581 sizeof(*cptkbd_data), 582 GFP_KERNEL); 583 if (cptkbd_data == NULL) { 584 hid_err(hdev, "can't alloc keyboard descriptor\n"); 585 return -ENOMEM; 586 } 587 hid_set_drvdata(hdev, cptkbd_data); 588 589 /* 590 * Tell the keyboard a driver understands it, and turn F7, F9, F11 into 591 * regular keys 592 */ 593 ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03); 594 if (ret) 595 hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); 596 597 /* Turn Fn-Lock on by default */ 598 cptkbd_data->fn_lock = true; 599 lenovo_features_set_cptkbd(hdev); 600 601 ret = sysfs_create_group(&hdev->dev.kobj, &lenovo_attr_group_cptkbd); 602 if (ret) 603 hid_warn(hdev, "Could not create sysfs group: %d\n", ret); 604 605 return 0; 606 } 607 608 static int lenovo_probe(struct hid_device *hdev, 609 const struct hid_device_id *id) 610 { 611 int ret; 612 613 ret = hid_parse(hdev); 614 if (ret) { 615 hid_err(hdev, "hid_parse failed\n"); 616 goto err; 617 } 618 619 ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); 620 if (ret) { 621 hid_err(hdev, "hid_hw_start failed\n"); 622 goto err; 623 } 624 625 switch (hdev->product) { 626 case USB_DEVICE_ID_LENOVO_TPKBD: 627 ret = lenovo_probe_tpkbd(hdev); 628 break; 629 case USB_DEVICE_ID_LENOVO_CUSBKBD: 630 case USB_DEVICE_ID_LENOVO_CBTKBD: 631 ret = lenovo_probe_cptkbd(hdev); 632 break; 633 default: 634 ret = 0; 635 break; 636 } 637 if (ret) 638 goto err_hid; 639 640 return 0; 641 err_hid: 642 hid_hw_stop(hdev); 643 err: 644 return ret; 645 } 646 647 static void lenovo_remove_tpkbd(struct hid_device *hdev) 648 { 649 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 650 651 /* 652 * Only the trackpoint half of the keyboard has drvdata and stuff that 653 * needs unregistering. 654 */ 655 if (data_pointer == NULL) 656 return; 657 658 sysfs_remove_group(&hdev->dev.kobj, 659 &lenovo_attr_group_tpkbd); 660 661 led_classdev_unregister(&data_pointer->led_micmute); 662 led_classdev_unregister(&data_pointer->led_mute); 663 664 hid_set_drvdata(hdev, NULL); 665 } 666 667 static void lenovo_remove_cptkbd(struct hid_device *hdev) 668 { 669 sysfs_remove_group(&hdev->dev.kobj, 670 &lenovo_attr_group_cptkbd); 671 } 672 673 static void lenovo_remove(struct hid_device *hdev) 674 { 675 switch (hdev->product) { 676 case USB_DEVICE_ID_LENOVO_TPKBD: 677 lenovo_remove_tpkbd(hdev); 678 break; 679 case USB_DEVICE_ID_LENOVO_CUSBKBD: 680 case USB_DEVICE_ID_LENOVO_CBTKBD: 681 lenovo_remove_cptkbd(hdev); 682 break; 683 } 684 685 hid_hw_stop(hdev); 686 } 687 688 static const struct hid_device_id lenovo_devices[] = { 689 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_TPKBD) }, 690 { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CUSBKBD) }, 691 { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_CBTKBD) }, 692 { } 693 }; 694 695 MODULE_DEVICE_TABLE(hid, lenovo_devices); 696 697 static struct hid_driver lenovo_driver = { 698 .name = "lenovo", 699 .id_table = lenovo_devices, 700 .input_mapping = lenovo_input_mapping, 701 .probe = lenovo_probe, 702 .remove = lenovo_remove, 703 .raw_event = lenovo_raw_event, 704 }; 705 module_hid_driver(lenovo_driver); 706 707 MODULE_LICENSE("GPL"); 708