Skip to content

Commit 484921f

Browse files
jwrdegoedeJiri Kosina
authored andcommitted
HID: lenovo: Factor out generic parts of the LED code
Factor out the generic parts of the tpkbd LED code, so that they can be re-used for supporting the LEDs on the Thinkpad 10 ultrabook kbd. Signed-off-by: Hans de Goede <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent b72cdfa commit 484921f

File tree

1 file changed

+58
-40
lines changed

1 file changed

+58
-40
lines changed

drivers/hid/hid-lenovo.c

Lines changed: 58 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,18 @@ static const struct attribute_group lenovo_attr_group_tpkbd = {
638638
.attrs = lenovo_attributes_tpkbd,
639639
};
640640

641-
static enum led_brightness lenovo_led_brightness_get_tpkbd(
641+
static void lenovo_led_set_tpkbd(struct hid_device *hdev)
642+
{
643+
struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev);
644+
struct hid_report *report;
645+
646+
report = hdev->report_enum[HID_OUTPUT_REPORT].report_id_hash[3];
647+
report->field[0]->value[0] = (data_pointer->led_state >> 0) & 1;
648+
report->field[0]->value[1] = (data_pointer->led_state >> 1) & 1;
649+
hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
650+
}
651+
652+
static enum led_brightness lenovo_led_brightness_get(
642653
struct led_classdev *led_cdev)
643654
{
644655
struct device *dev = led_cdev->dev->parent;
@@ -654,13 +665,12 @@ static enum led_brightness lenovo_led_brightness_get_tpkbd(
654665
: LED_OFF;
655666
}
656667

657-
static void lenovo_led_brightness_set_tpkbd(struct led_classdev *led_cdev,
668+
static void lenovo_led_brightness_set(struct led_classdev *led_cdev,
658669
enum led_brightness value)
659670
{
660671
struct device *dev = led_cdev->dev->parent;
661672
struct hid_device *hdev = to_hid_device(dev);
662673
struct lenovo_drvdata *data_pointer = hid_get_drvdata(hdev);
663-
struct hid_report *report;
664674
int led_nr = 0;
665675

666676
if (led_cdev == &data_pointer->led_micmute)
@@ -671,20 +681,54 @@ static void lenovo_led_brightness_set_tpkbd(struct led_classdev *led_cdev,
671681
else
672682
data_pointer->led_state |= 1 << led_nr;
673683

674-
report = hdev->report_enum[HID_OUTPUT_REPORT].report_id_hash[3];
675-
report->field[0]->value[0] = (data_pointer->led_state >> 0) & 1;
676-
report->field[0]->value[1] = (data_pointer->led_state >> 1) & 1;
677-
hid_hw_request(hdev, report, HID_REQ_SET_REPORT);
684+
switch (hdev->product) {
685+
case USB_DEVICE_ID_LENOVO_TPKBD:
686+
lenovo_led_set_tpkbd(hdev);
687+
break;
688+
}
689+
}
690+
691+
static int lenovo_register_leds(struct hid_device *hdev)
692+
{
693+
struct lenovo_drvdata *data = hid_get_drvdata(hdev);
694+
size_t name_sz = strlen(dev_name(&hdev->dev)) + 16;
695+
char *name_mute, *name_micm;
696+
int ret;
697+
698+
name_mute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
699+
name_micm = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
700+
if (name_mute == NULL || name_micm == NULL) {
701+
hid_err(hdev, "Could not allocate memory for led data\n");
702+
return -ENOMEM;
703+
}
704+
snprintf(name_mute, name_sz, "%s:amber:mute", dev_name(&hdev->dev));
705+
snprintf(name_micm, name_sz, "%s:amber:micmute", dev_name(&hdev->dev));
706+
707+
data->led_mute.name = name_mute;
708+
data->led_mute.brightness_get = lenovo_led_brightness_get;
709+
data->led_mute.brightness_set = lenovo_led_brightness_set;
710+
data->led_mute.dev = &hdev->dev;
711+
ret = led_classdev_register(&hdev->dev, &data->led_mute);
712+
if (ret < 0)
713+
return ret;
714+
715+
data->led_micmute.name = name_micm;
716+
data->led_micmute.brightness_get = lenovo_led_brightness_get;
717+
data->led_micmute.brightness_set = lenovo_led_brightness_set;
718+
data->led_micmute.dev = &hdev->dev;
719+
ret = led_classdev_register(&hdev->dev, &data->led_micmute);
720+
if (ret < 0) {
721+
led_classdev_unregister(&data->led_mute);
722+
return ret;
723+
}
724+
725+
return 0;
678726
}
679727

680728
static int lenovo_probe_tpkbd(struct hid_device *hdev)
681729
{
682-
struct device *dev = &hdev->dev;
683730
struct lenovo_drvdata *data_pointer;
684-
size_t name_sz = strlen(dev_name(dev)) + 16;
685-
char *name_mute, *name_micmute;
686-
int i;
687-
int ret;
731+
int i, ret;
688732

689733
/*
690734
* Only register extra settings against subdevice where input_mapping
@@ -720,37 +764,11 @@ static int lenovo_probe_tpkbd(struct hid_device *hdev)
720764
data_pointer->sensitivity = 0xa0;
721765
data_pointer->press_speed = 0x38;
722766

723-
name_mute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
724-
name_micmute = devm_kzalloc(&hdev->dev, name_sz, GFP_KERNEL);
725-
if (name_mute == NULL || name_micmute == NULL) {
726-
hid_err(hdev, "Could not allocate memory for led data\n");
727-
ret = -ENOMEM;
728-
goto err;
729-
}
730-
snprintf(name_mute, name_sz, "%s:amber:mute", dev_name(dev));
731-
snprintf(name_micmute, name_sz, "%s:amber:micmute", dev_name(dev));
732-
733767
hid_set_drvdata(hdev, data_pointer);
734768

735-
data_pointer->led_mute.name = name_mute;
736-
data_pointer->led_mute.brightness_get = lenovo_led_brightness_get_tpkbd;
737-
data_pointer->led_mute.brightness_set = lenovo_led_brightness_set_tpkbd;
738-
data_pointer->led_mute.dev = dev;
739-
ret = led_classdev_register(dev, &data_pointer->led_mute);
740-
if (ret < 0)
741-
goto err;
742-
743-
data_pointer->led_micmute.name = name_micmute;
744-
data_pointer->led_micmute.brightness_get =
745-
lenovo_led_brightness_get_tpkbd;
746-
data_pointer->led_micmute.brightness_set =
747-
lenovo_led_brightness_set_tpkbd;
748-
data_pointer->led_micmute.dev = dev;
749-
ret = led_classdev_register(dev, &data_pointer->led_micmute);
750-
if (ret < 0) {
751-
led_classdev_unregister(&data_pointer->led_mute);
769+
ret = lenovo_register_leds(hdev);
770+
if (ret)
752771
goto err;
753-
}
754772

755773
lenovo_features_set_tpkbd(hdev);
756774

0 commit comments

Comments
 (0)