aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorFabio Baltieri <fabio.baltieri@gmail.com>2012-06-06 18:11:05 -0400
committerBryan Wu <bryan.wu@canonical.com>2012-07-23 19:52:34 -0400
commit5e417281cde2ef56e9eb1a95d080d6254402e794 (patch)
tree142bdedb0e099b96276c0e094bf89a10251a7bc4 /drivers
parent437864828d82b9dee50b5741106fbf5fa12b139a (diff)
leds: add oneshot trigger
Add oneshot trigger to blink a led with configurale parameters via sysfs. Signed-off-by: Fabio Baltieri <fabio.baltieri@gmail.com> Cc: Shuah Khan <shuahkhan@gmail.com> Signed-off-by: Bryan Wu <bryan.wu@canonical.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/leds/Kconfig14
-rw-r--r--drivers/leds/Makefile1
-rw-r--r--drivers/leds/ledtrig-oneshot.c204
3 files changed, 219 insertions, 0 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 12b2b55c519e..54dd1a396fa9 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -443,6 +443,20 @@ config LEDS_TRIGGER_TIMER
443 443
444 If unsure, say Y. 444 If unsure, say Y.
445 445
446config LEDS_TRIGGER_ONESHOT
447 tristate "LED One-shot Trigger"
448 depends on LEDS_TRIGGERS
449 help
450 This allows LEDs to blink in one-shot pulses with parameters
451 controlled via sysfs. It's useful to notify the user on
452 sporadic events, when there are no clear begin and end trap points,
453 or on dense events, where this blinks the LED at constant rate if
454 rearmed continuously.
455
456 It also shows how to use the led_blink_set_oneshot() function.
457
458 If unsure, say Y.
459
446config LEDS_TRIGGER_IDE_DISK 460config LEDS_TRIGGER_IDE_DISK
447 bool "LED IDE Disk Trigger" 461 bool "LED IDE Disk Trigger"
448 depends on IDE_GD_ATA 462 depends on IDE_GD_ATA
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index f8958cd6cf6e..9112d518f9d4 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
53 53
54# LED Triggers 54# LED Triggers
55obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o 55obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
56obj-$(CONFIG_LEDS_TRIGGER_ONESHOT) += ledtrig-oneshot.o
56obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o 57obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o
57obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o 58obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o
58obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o 59obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o
diff --git a/drivers/leds/ledtrig-oneshot.c b/drivers/leds/ledtrig-oneshot.c
new file mode 100644
index 000000000000..5c9edf7f489c
--- /dev/null
+++ b/drivers/leds/ledtrig-oneshot.c
@@ -0,0 +1,204 @@
1/*
2 * One-shot LED Trigger
3 *
4 * Copyright 2012, Fabio Baltieri <fabio.baltieri@gmail.com>
5 *
6 * Based on ledtrig-timer.c by Richard Purdie <rpurdie@openedhand.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/device.h>
18#include <linux/ctype.h>
19#include <linux/slab.h>
20#include <linux/leds.h>
21#include "leds.h"
22
23#define DEFAULT_DELAY 100
24
25struct oneshot_trig_data {
26 unsigned int invert;
27};
28
29static ssize_t led_shot(struct device *dev,
30 struct device_attribute *attr, const char *buf, size_t size)
31{
32 struct led_classdev *led_cdev = dev_get_drvdata(dev);
33 struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data;
34
35 led_blink_set_oneshot(led_cdev,
36 &led_cdev->blink_delay_on, &led_cdev->blink_delay_off,
37 oneshot_data->invert);
38
39 /* content is ignored */
40 return size;
41}
42static ssize_t led_invert_show(struct device *dev,
43 struct device_attribute *attr, char *buf)
44{
45 struct led_classdev *led_cdev = dev_get_drvdata(dev);
46 struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data;
47
48 return sprintf(buf, "%u\n", oneshot_data->invert);
49}
50
51static ssize_t led_invert_store(struct device *dev,
52 struct device_attribute *attr, const char *buf, size_t size)
53{
54 struct led_classdev *led_cdev = dev_get_drvdata(dev);
55 struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data;
56 unsigned long state;
57 int ret;
58
59 ret = kstrtoul(buf, 0, &state);
60 if (ret)
61 return ret;
62
63 oneshot_data->invert = !!state;
64
65 if (oneshot_data->invert)
66 led_set_brightness(led_cdev, LED_FULL);
67 else
68 led_set_brightness(led_cdev, LED_OFF);
69
70 return size;
71}
72
73static ssize_t led_delay_on_show(struct device *dev,
74 struct device_attribute *attr, char *buf)
75{
76 struct led_classdev *led_cdev = dev_get_drvdata(dev);
77
78 return sprintf(buf, "%lu\n", led_cdev->blink_delay_on);
79}
80
81static ssize_t led_delay_on_store(struct device *dev,
82 struct device_attribute *attr, const char *buf, size_t size)
83{
84 struct led_classdev *led_cdev = dev_get_drvdata(dev);
85 unsigned long state;
86 int ret;
87
88 ret = kstrtoul(buf, 0, &state);
89 if (ret)
90 return ret;
91
92 led_cdev->blink_delay_on = state;
93
94 return size;
95}
96static ssize_t led_delay_off_show(struct device *dev,
97 struct device_attribute *attr, char *buf)
98{
99 struct led_classdev *led_cdev = dev_get_drvdata(dev);
100
101 return sprintf(buf, "%lu\n", led_cdev->blink_delay_off);
102}
103
104static ssize_t led_delay_off_store(struct device *dev,
105 struct device_attribute *attr, const char *buf, size_t size)
106{
107 struct led_classdev *led_cdev = dev_get_drvdata(dev);
108 unsigned long state;
109 int ret;
110
111 ret = kstrtoul(buf, 0, &state);
112 if (ret)
113 return ret;
114
115 led_cdev->blink_delay_off = state;
116
117 return size;
118}
119
120static DEVICE_ATTR(delay_on, 0644, led_delay_on_show, led_delay_on_store);
121static DEVICE_ATTR(delay_off, 0644, led_delay_off_show, led_delay_off_store);
122static DEVICE_ATTR(invert, 0644, led_invert_show, led_invert_store);
123static DEVICE_ATTR(shot, 0200, NULL, led_shot);
124
125static void oneshot_trig_activate(struct led_classdev *led_cdev)
126{
127 struct oneshot_trig_data *oneshot_data;
128 int rc;
129
130 oneshot_data = kzalloc(sizeof(*oneshot_data), GFP_KERNEL);
131 if (!oneshot_data)
132 return;
133
134 led_cdev->trigger_data = oneshot_data;
135
136 rc = device_create_file(led_cdev->dev, &dev_attr_delay_on);
137 if (rc)
138 goto err_out_trig_data;
139 rc = device_create_file(led_cdev->dev, &dev_attr_delay_off);
140 if (rc)
141 goto err_out_delayon;
142 rc = device_create_file(led_cdev->dev, &dev_attr_invert);
143 if (rc)
144 goto err_out_delayoff;
145 rc = device_create_file(led_cdev->dev, &dev_attr_shot);
146 if (rc)
147 goto err_out_invert;
148
149 led_cdev->blink_delay_on = DEFAULT_DELAY;
150 led_cdev->blink_delay_off = DEFAULT_DELAY;
151
152 led_cdev->activated = true;
153
154 return;
155
156err_out_invert:
157 device_remove_file(led_cdev->dev, &dev_attr_invert);
158err_out_delayoff:
159 device_remove_file(led_cdev->dev, &dev_attr_delay_off);
160err_out_delayon:
161 device_remove_file(led_cdev->dev, &dev_attr_delay_on);
162err_out_trig_data:
163 kfree(led_cdev->trigger_data);
164}
165
166static void oneshot_trig_deactivate(struct led_classdev *led_cdev)
167{
168 struct oneshot_trig_data *oneshot_data = led_cdev->trigger_data;
169
170 if (led_cdev->activated) {
171 device_remove_file(led_cdev->dev, &dev_attr_delay_on);
172 device_remove_file(led_cdev->dev, &dev_attr_delay_off);
173 device_remove_file(led_cdev->dev, &dev_attr_invert);
174 device_remove_file(led_cdev->dev, &dev_attr_shot);
175 kfree(oneshot_data);
176 led_cdev->activated = false;
177 }
178
179 /* Stop blinking */
180 led_brightness_set(led_cdev, LED_OFF);
181}
182
183static struct led_trigger oneshot_led_trigger = {
184 .name = "oneshot",
185 .activate = oneshot_trig_activate,
186 .deactivate = oneshot_trig_deactivate,
187};
188
189static int __init oneshot_trig_init(void)
190{
191 return led_trigger_register(&oneshot_led_trigger);
192}
193
194static void __exit oneshot_trig_exit(void)
195{
196 led_trigger_unregister(&oneshot_led_trigger);
197}
198
199module_init(oneshot_trig_init);
200module_exit(oneshot_trig_exit);
201
202MODULE_AUTHOR("Fabio Baltieri <fabio.baltieri@gmail.com>");
203MODULE_DESCRIPTION("One-shot LED trigger");
204MODULE_LICENSE("GPL");