aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-lenovo.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hid/hid-lenovo.c')
-rw-r--r--drivers/hid/hid-lenovo.c53
1 files changed, 45 insertions, 8 deletions
diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c
index 0320b96ddf24..a56b9e7413ce 100644
--- a/drivers/hid/hid-lenovo.c
+++ b/drivers/hid/hid-lenovo.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * HID driver for Lenovo ThinkPad USB Keyboard with TrackPoint 2 * HID driver for Lenovo:
3 * - ThinkPad USB Keyboard with TrackPoint (tpkbd)
3 * 4 *
4 * Copyright (c) 2012 Bernhard Seibold 5 * Copyright (c) 2012 Bernhard Seibold
5 */ 6 */
@@ -39,7 +40,7 @@ static int lenovo_input_mapping_tpkbd(struct hid_device *hdev,
39 struct hid_usage *usage, unsigned long **bit, int *max) 40 struct hid_usage *usage, unsigned long **bit, int *max)
40{ 41{
41 if (usage->hid == (HID_UP_BUTTON | 0x0010)) { 42 if (usage->hid == (HID_UP_BUTTON | 0x0010)) {
42 /* mark the device as pointer */ 43 /* This sub-device contains trackpoint, mark it */
43 hid_set_drvdata(hdev, (void *)1); 44 hid_set_drvdata(hdev, (void *)1);
44 map_key_clear(KEY_MICMUTE); 45 map_key_clear(KEY_MICMUTE);
45 return 1; 46 return 1;
@@ -47,6 +48,19 @@ static int lenovo_input_mapping_tpkbd(struct hid_device *hdev,
47 return 0; 48 return 0;
48} 49}
49 50
51static int lenovo_input_mapping(struct hid_device *hdev,
52 struct hid_input *hi, struct hid_field *field,
53 struct hid_usage *usage, unsigned long **bit, int *max)
54{
55 switch (hdev->product) {
56 case USB_DEVICE_ID_LENOVO_TPKBD:
57 return lenovo_input_mapping_tpkbd(hdev, hi, field,
58 usage, bit, max);
59 default:
60 return 0;
61 }
62}
63
50#undef map_key_clear 64#undef map_key_clear
51 65
52static int lenovo_features_set_tpkbd(struct hid_device *hdev) 66static int lenovo_features_set_tpkbd(struct hid_device *hdev)
@@ -337,6 +351,15 @@ static int lenovo_probe_tpkbd(struct hid_device *hdev)
337 char *name_mute, *name_micmute; 351 char *name_mute, *name_micmute;
338 int i; 352 int i;
339 353
354 /*
355 * Only register extra settings against subdevice where input_mapping
356 * set drvdata to 1, i.e. the trackpoint.
357 */
358 if (!hid_get_drvdata(hdev))
359 return 0;
360
361 hid_set_drvdata(hdev, NULL);
362
340 /* Validate required reports. */ 363 /* Validate required reports. */
341 for (i = 0; i < 4; i++) { 364 for (i = 0; i < 4; i++) {
342 if (!hid_validate_values(hdev, HID_FEATURE_REPORT, 4, i, 1)) 365 if (!hid_validate_values(hdev, HID_FEATURE_REPORT, 4, i, 1))
@@ -409,12 +432,16 @@ static int lenovo_probe(struct hid_device *hdev,
409 goto err; 432 goto err;
410 } 433 }
411 434
412 if (hid_get_drvdata(hdev)) { 435 switch (hdev->product) {
413 hid_set_drvdata(hdev, NULL); 436 case USB_DEVICE_ID_LENOVO_TPKBD:
414 ret = lenovo_probe_tpkbd(hdev); 437 ret = lenovo_probe_tpkbd(hdev);
415 if (ret) 438 break;
416 goto err_hid; 439 default:
440 ret = 0;
441 break;
417 } 442 }
443 if (ret)
444 goto err_hid;
418 445
419 return 0; 446 return 0;
420err_hid: 447err_hid:
@@ -427,6 +454,13 @@ static void lenovo_remove_tpkbd(struct hid_device *hdev)
427{ 454{
428 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev); 455 struct lenovo_drvdata_tpkbd *data_pointer = hid_get_drvdata(hdev);
429 456
457 /*
458 * Only the trackpoint half of the keyboard has drvdata and stuff that
459 * needs unregistering.
460 */
461 if (data_pointer == NULL)
462 return;
463
430 sysfs_remove_group(&hdev->dev.kobj, 464 sysfs_remove_group(&hdev->dev.kobj,
431 &lenovo_attr_group_tpkbd); 465 &lenovo_attr_group_tpkbd);
432 466
@@ -438,8 +472,11 @@ static void lenovo_remove_tpkbd(struct hid_device *hdev)
438 472
439static void lenovo_remove(struct hid_device *hdev) 473static void lenovo_remove(struct hid_device *hdev)
440{ 474{
441 if (hid_get_drvdata(hdev)) 475 switch (hdev->product) {
476 case USB_DEVICE_ID_LENOVO_TPKBD:
442 lenovo_remove_tpkbd(hdev); 477 lenovo_remove_tpkbd(hdev);
478 break;
479 }
443 480
444 hid_hw_stop(hdev); 481 hid_hw_stop(hdev);
445} 482}
@@ -454,7 +491,7 @@ MODULE_DEVICE_TABLE(hid, lenovo_devices);
454static struct hid_driver lenovo_driver = { 491static struct hid_driver lenovo_driver = {
455 .name = "lenovo", 492 .name = "lenovo",
456 .id_table = lenovo_devices, 493 .id_table = lenovo_devices,
457 .input_mapping = lenovo_input_mapping_tpkbd, 494 .input_mapping = lenovo_input_mapping,
458 .probe = lenovo_probe, 495 .probe = lenovo_probe,
459 .remove = lenovo_remove, 496 .remove = lenovo_remove,
460}; 497};