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