diff options
author | Heiner Kallweit <hkallweit1@gmail.com> | 2016-01-08 13:28:58 -0500 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2016-02-23 14:29:35 -0500 |
commit | 6d5d2ee63cee7025badda3b74ae2ef7ab097acfa (patch) | |
tree | 84d89e34753cdd8e2a00dabb73eb6c6e3d1896d6 /net/bluetooth/leds.c | |
parent | a30a9ea6e21b495372aff549f3dfd63198bd1f45 (diff) |
Bluetooth: add LED trigger for indicating HCI is powered up
Add support for LED triggers to the Bluetooth subsystem and add kernel
config symbol BT_LEDS for it.
For now one trigger for indicating "HCI is powered up" is supported.
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/leds.c')
-rw-r--r-- | net/bluetooth/leds.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/net/bluetooth/leds.c b/net/bluetooth/leds.c new file mode 100644 index 000000000000..ded7c88eaccc --- /dev/null +++ b/net/bluetooth/leds.c | |||
@@ -0,0 +1,80 @@ | |||
1 | /* | ||
2 | * Copyright 2015, Heiner Kallweit <hkallweit1@gmail.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | */ | ||
8 | |||
9 | #include <net/bluetooth/bluetooth.h> | ||
10 | #include <net/bluetooth/hci_core.h> | ||
11 | |||
12 | #include "leds.h" | ||
13 | |||
14 | struct hci_basic_led_trigger { | ||
15 | struct led_trigger led_trigger; | ||
16 | struct hci_dev *hdev; | ||
17 | }; | ||
18 | |||
19 | #define to_hci_basic_led_trigger(arg) container_of(arg, \ | ||
20 | struct hci_basic_led_trigger, led_trigger) | ||
21 | |||
22 | void hci_leds_update_powered(struct hci_dev *hdev, bool enabled) | ||
23 | { | ||
24 | if (hdev->power_led) | ||
25 | led_trigger_event(hdev->power_led, | ||
26 | enabled ? LED_FULL : LED_OFF); | ||
27 | } | ||
28 | |||
29 | static void power_activate(struct led_classdev *led_cdev) | ||
30 | { | ||
31 | struct hci_basic_led_trigger *htrig; | ||
32 | bool powered; | ||
33 | |||
34 | htrig = to_hci_basic_led_trigger(led_cdev->trigger); | ||
35 | powered = test_bit(HCI_UP, &htrig->hdev->flags); | ||
36 | |||
37 | led_trigger_event(led_cdev->trigger, powered ? LED_FULL : LED_OFF); | ||
38 | } | ||
39 | |||
40 | static struct led_trigger *led_allocate_basic(struct hci_dev *hdev, | ||
41 | void (*activate)(struct led_classdev *led_cdev), | ||
42 | const char *name) | ||
43 | { | ||
44 | struct hci_basic_led_trigger *htrig; | ||
45 | |||
46 | htrig = devm_kzalloc(&hdev->dev, sizeof(*htrig), GFP_KERNEL); | ||
47 | if (!htrig) | ||
48 | return NULL; | ||
49 | |||
50 | htrig->hdev = hdev; | ||
51 | htrig->led_trigger.activate = activate; | ||
52 | htrig->led_trigger.name = devm_kasprintf(&hdev->dev, GFP_KERNEL, | ||
53 | "%s-%s", hdev->name, | ||
54 | name); | ||
55 | if (!htrig->led_trigger.name) | ||
56 | goto err_alloc; | ||
57 | |||
58 | if (led_trigger_register(&htrig->led_trigger)) | ||
59 | goto err_register; | ||
60 | |||
61 | return &htrig->led_trigger; | ||
62 | |||
63 | err_register: | ||
64 | devm_kfree(&hdev->dev, (void *)htrig->led_trigger.name); | ||
65 | err_alloc: | ||
66 | devm_kfree(&hdev->dev, htrig); | ||
67 | return NULL; | ||
68 | } | ||
69 | |||
70 | void hci_leds_init(struct hci_dev *hdev) | ||
71 | { | ||
72 | /* initialize power_led */ | ||
73 | hdev->power_led = led_allocate_basic(hdev, power_activate, "power"); | ||
74 | } | ||
75 | |||
76 | void hci_leds_exit(struct hci_dev *hdev) | ||
77 | { | ||
78 | if (hdev->power_led) | ||
79 | led_trigger_unregister(hdev->power_led); | ||
80 | } | ||