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