aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds/ledtrig-timer.c
diff options
context:
space:
mode:
authorMárton Németh <nm127@freemail.hu>2007-10-31 10:07:12 -0400
committerRichard Purdie <rpurdie@rpsys.net>2008-02-07 04:49:38 -0500
commit4c79141d28bc290ae307e3f81f5bc909c26faf6e (patch)
tree9c6dc51c441dfc1c84cc27ece43087515c06967c /drivers/leds/ledtrig-timer.c
parent6c152beefbf90579d21afc4f7e075b1f801f9a75 (diff)
leds: Add support for hardware accelerated LED flashing
Extends the leds subsystem with a blink_set() callback function which can be optionally implemented by a LED driver. If implemented, the driver can use the hardware acceleration for blinking a LED. Signed-off-by: Márton Németh <nm127@freemail.hu> Signed-off-by: Richard Purdie <rpurdie@rpsys.net>
Diffstat (limited to 'drivers/leds/ledtrig-timer.c')
-rw-r--r--drivers/leds/ledtrig-timer.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c
index ed9ff02c77ea..82c55d6e4902 100644
--- a/drivers/leds/ledtrig-timer.c
+++ b/drivers/leds/ledtrig-timer.c
@@ -77,8 +77,21 @@ static ssize_t led_delay_on_store(struct device *dev,
77 count++; 77 count++;
78 78
79 if (count == size) { 79 if (count == size) {
80 timer_data->delay_on = state; 80 if (timer_data->delay_on != state) {
81 mod_timer(&timer_data->timer, jiffies + 1); 81 /* the new value differs from the previous */
82 timer_data->delay_on = state;
83
84 /* deactivate previous settings */
85 del_timer_sync(&timer_data->timer);
86
87 /* try to activate hardware acceleration, if any */
88 if (!led_cdev->blink_set ||
89 led_cdev->blink_set(led_cdev,
90 &timer_data->delay_on, &timer_data->delay_off)) {
91 /* no hardware acceleration, blink via timer */
92 mod_timer(&timer_data->timer, jiffies + 1);
93 }
94 }
82 ret = count; 95 ret = count;
83 } 96 }
84 97
@@ -110,8 +123,21 @@ static ssize_t led_delay_off_store(struct device *dev,
110 count++; 123 count++;
111 124
112 if (count == size) { 125 if (count == size) {
113 timer_data->delay_off = state; 126 if (timer_data->delay_off != state) {
114 mod_timer(&timer_data->timer, jiffies + 1); 127 /* the new value differs from the previous */
128 timer_data->delay_off = state;
129
130 /* deactivate previous settings */
131 del_timer_sync(&timer_data->timer);
132
133 /* try to activate hardware acceleration, if any */
134 if (!led_cdev->blink_set ||
135 led_cdev->blink_set(led_cdev,
136 &timer_data->delay_on, &timer_data->delay_off)) {
137 /* no hardware acceleration, blink via timer */
138 mod_timer(&timer_data->timer, jiffies + 1);
139 }
140 }
115 ret = count; 141 ret = count;
116 } 142 }
117 143
@@ -143,6 +169,13 @@ static void timer_trig_activate(struct led_classdev *led_cdev)
143 if (rc) 169 if (rc)
144 goto err_out_delayon; 170 goto err_out_delayon;
145 171
172 /* If there is hardware support for blinking, start one
173 * user friendly blink rate chosen by the driver.
174 */
175 if (led_cdev->blink_set)
176 led_cdev->blink_set(led_cdev,
177 &timer_data->delay_on, &timer_data->delay_off);
178
146 return; 179 return;
147 180
148err_out_delayon: 181err_out_delayon: