aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid/hid-lenovo.c
diff options
context:
space:
mode:
authorJamie Lentin <jm@lentin.co.uk>2014-07-23 18:30:46 -0400
committerJiri Kosina <jkosina@suse.cz>2014-07-29 05:24:46 -0400
commit6a5b414b4216be0fb7d26aadcf35de0fa24a03e3 (patch)
treeb274a1270f82140c05b66a5a01625da505b913e2 /drivers/hid/hid-lenovo.c
parent94723bfa7bf1b647fe49c9717ee02e99d7a59957 (diff)
HID: lenovo: Prepare support for adding other devices
Ensure all tpkbd specifics are within a postfixed function, the main functions for the driver should just switch to the appropriate function depending on product ID. Given this, we can add extra devices by including extra postfixed functions. Signed-off-by: Jamie Lentin <jm@lentin.co.uk> Reviewed-by: Antonio Ospite <ao2@ao2.it> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
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};