aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds/ledtrig-timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/leds/ledtrig-timer.c')
-rw-r--r--drivers/leds/ledtrig-timer.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c
index 82c55d6e4902..5c99f4f0c692 100644
--- a/drivers/leds/ledtrig-timer.c
+++ b/drivers/leds/ledtrig-timer.c
@@ -25,6 +25,9 @@
25#include "leds.h" 25#include "leds.h"
26 26
27struct timer_trig_data { 27struct timer_trig_data {
28 int brightness_on; /* LED brightness during "on" period.
29 * (LED_OFF < brightness_on <= LED_FULL)
30 */
28 unsigned long delay_on; /* milliseconds on */ 31 unsigned long delay_on; /* milliseconds on */
29 unsigned long delay_off; /* milliseconds off */ 32 unsigned long delay_off; /* milliseconds off */
30 struct timer_list timer; 33 struct timer_list timer;
@@ -34,17 +37,26 @@ static void led_timer_function(unsigned long data)
34{ 37{
35 struct led_classdev *led_cdev = (struct led_classdev *) data; 38 struct led_classdev *led_cdev = (struct led_classdev *) data;
36 struct timer_trig_data *timer_data = led_cdev->trigger_data; 39 struct timer_trig_data *timer_data = led_cdev->trigger_data;
37 unsigned long brightness = LED_OFF; 40 unsigned long brightness;
38 unsigned long delay = timer_data->delay_off; 41 unsigned long delay;
39 42
40 if (!timer_data->delay_on || !timer_data->delay_off) { 43 if (!timer_data->delay_on || !timer_data->delay_off) {
41 led_set_brightness(led_cdev, LED_OFF); 44 led_set_brightness(led_cdev, LED_OFF);
42 return; 45 return;
43 } 46 }
44 47
45 if (!led_cdev->brightness) { 48 brightness = led_get_brightness(led_cdev);
46 brightness = LED_FULL; 49 if (!brightness) {
50 /* Time to switch the LED on. */
51 brightness = timer_data->brightness_on;
47 delay = timer_data->delay_on; 52 delay = timer_data->delay_on;
53 } else {
54 /* Store the current brightness value to be able
55 * to restore it when the delay_off period is over.
56 */
57 timer_data->brightness_on = brightness;
58 brightness = LED_OFF;
59 delay = timer_data->delay_off;
48 } 60 }
49 61
50 led_set_brightness(led_cdev, brightness); 62 led_set_brightness(led_cdev, brightness);
@@ -52,7 +64,7 @@ static void led_timer_function(unsigned long data)
52 mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay)); 64 mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay));
53} 65}
54 66
55static ssize_t led_delay_on_show(struct device *dev, 67static ssize_t led_delay_on_show(struct device *dev,
56 struct device_attribute *attr, char *buf) 68 struct device_attribute *attr, char *buf)
57{ 69{
58 struct led_classdev *led_cdev = dev_get_drvdata(dev); 70 struct led_classdev *led_cdev = dev_get_drvdata(dev);
@@ -63,7 +75,7 @@ static ssize_t led_delay_on_show(struct device *dev,
63 return strlen(buf) + 1; 75 return strlen(buf) + 1;
64} 76}
65 77
66static ssize_t led_delay_on_store(struct device *dev, 78static ssize_t led_delay_on_store(struct device *dev,
67 struct device_attribute *attr, const char *buf, size_t size) 79 struct device_attribute *attr, const char *buf, size_t size)
68{ 80{
69 struct led_classdev *led_cdev = dev_get_drvdata(dev); 81 struct led_classdev *led_cdev = dev_get_drvdata(dev);
@@ -87,7 +99,7 @@ static ssize_t led_delay_on_store(struct device *dev,
87 /* try to activate hardware acceleration, if any */ 99 /* try to activate hardware acceleration, if any */
88 if (!led_cdev->blink_set || 100 if (!led_cdev->blink_set ||
89 led_cdev->blink_set(led_cdev, 101 led_cdev->blink_set(led_cdev,
90 &timer_data->delay_on, &timer_data->delay_off)) { 102 &timer_data->delay_on, &timer_data->delay_off)) {
91 /* no hardware acceleration, blink via timer */ 103 /* no hardware acceleration, blink via timer */
92 mod_timer(&timer_data->timer, jiffies + 1); 104 mod_timer(&timer_data->timer, jiffies + 1);
93 } 105 }
@@ -98,7 +110,7 @@ static ssize_t led_delay_on_store(struct device *dev,
98 return ret; 110 return ret;
99} 111}
100 112
101static ssize_t led_delay_off_show(struct device *dev, 113static ssize_t led_delay_off_show(struct device *dev,
102 struct device_attribute *attr, char *buf) 114 struct device_attribute *attr, char *buf)
103{ 115{
104 struct led_classdev *led_cdev = dev_get_drvdata(dev); 116 struct led_classdev *led_cdev = dev_get_drvdata(dev);
@@ -109,7 +121,7 @@ static ssize_t led_delay_off_show(struct device *dev,
109 return strlen(buf) + 1; 121 return strlen(buf) + 1;
110} 122}
111 123
112static ssize_t led_delay_off_store(struct device *dev, 124static ssize_t led_delay_off_store(struct device *dev,
113 struct device_attribute *attr, const char *buf, size_t size) 125 struct device_attribute *attr, const char *buf, size_t size)
114{ 126{
115 struct led_classdev *led_cdev = dev_get_drvdata(dev); 127 struct led_classdev *led_cdev = dev_get_drvdata(dev);
@@ -133,7 +145,7 @@ static ssize_t led_delay_off_store(struct device *dev,
133 /* try to activate hardware acceleration, if any */ 145 /* try to activate hardware acceleration, if any */
134 if (!led_cdev->blink_set || 146 if (!led_cdev->blink_set ||
135 led_cdev->blink_set(led_cdev, 147 led_cdev->blink_set(led_cdev,
136 &timer_data->delay_on, &timer_data->delay_off)) { 148 &timer_data->delay_on, &timer_data->delay_off)) {
137 /* no hardware acceleration, blink via timer */ 149 /* no hardware acceleration, blink via timer */
138 mod_timer(&timer_data->timer, jiffies + 1); 150 mod_timer(&timer_data->timer, jiffies + 1);
139 } 151 }
@@ -156,6 +168,9 @@ static void timer_trig_activate(struct led_classdev *led_cdev)
156 if (!timer_data) 168 if (!timer_data)
157 return; 169 return;
158 170
171 timer_data->brightness_on = led_get_brightness(led_cdev);
172 if (timer_data->brightness_on == LED_OFF)
173 timer_data->brightness_on = LED_FULL;
159 led_cdev->trigger_data = timer_data; 174 led_cdev->trigger_data = timer_data;
160 175
161 init_timer(&timer_data->timer); 176 init_timer(&timer_data->timer);