summaryrefslogtreecommitdiffstats
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 82c55d6e490..5c99f4f0c69 100644
--- a/drivers/leds/ledtrig-timer.c
+++ b/drivers/leds/ledtrig-timer.c
@@ -25,6 +25,9 @@
#include "leds.h"
struct timer_trig_data {
+ int brightness_on; /* LED brightness during "on" period.
+ * (LED_OFF < brightness_on <= LED_FULL)
+ */
unsigned long delay_on; /* milliseconds on */
unsigned long delay_off; /* milliseconds off */
struct timer_list timer;
@@ -34,17 +37,26 @@ static void led_timer_function(unsigned long data)
{
struct led_classdev *led_cdev = (struct led_classdev *) data;
struct timer_trig_data *timer_data = led_cdev->trigger_data;
- unsigned long brightness = LED_OFF;
- unsigned long delay = timer_data->delay_off;
+ unsigned long brightness;
+ unsigned long delay;
if (!timer_data->delay_on || !timer_data->delay_off) {
led_set_brightness(led_cdev, LED_OFF);
return;
}
- if (!led_cdev->brightness) {
- brightness = LED_FULL;
+ brightness = led_get_brightness(led_cdev);
+ if (!brightness) {
+ /* Time to switch the LED on. */
+ brightness = timer_data->brightness_on;
delay = timer_data->delay_on;
+ } else {
+ /* Store the current brightness value to be able
+ * to restore it when the delay_off period is over.
+ */
+ timer_data->brightness_on = brightness;
+ brightness = LED_OFF;
+ delay = timer_data->delay_off;
}
led_set_brightness(led_cdev, brightness);
@@ -52,7 +64,7 @@ static void led_timer_function(unsigned long data)
mod_timer(&timer_data->timer, jiffies + msecs_to_jiffies(delay));
}
-static ssize_t led_delay_on_show(struct device *dev,
+static ssize_t led_delay_on_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
@@ -63,7 +75,7 @@ static ssize_t led_delay_on_show(struct device *dev,
return strlen(buf) + 1;
}
-static ssize_t led_delay_on_store(struct device *dev,
+static ssize_t led_delay_on_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
@@ -87,7 +99,7 @@ static ssize_t led_delay_on_store(struct device *dev,
/* try to activate hardware acceleration, if any */
if (!led_cdev->blink_set ||
led_cdev->blink_set(led_cdev,
- &timer_data->delay_on, &timer_data->delay_off)) {
+ &timer_data->delay_on, &timer_data->delay_off)) {
/* no hardware acceleration, blink via timer */
mod_timer(&timer_data->timer, jiffies + 1);
}
@@ -98,7 +110,7 @@ static ssize_t led_delay_on_store(struct device *dev,
return ret;
}
-static ssize_t led_delay_off_show(struct device *dev,
+static ssize_t led_delay_off_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
@@ -109,7 +121,7 @@ static ssize_t led_delay_off_show(struct device *dev,
return strlen(buf) + 1;
}
-static ssize_t led_delay_off_store(struct device *dev,
+static ssize_t led_delay_off_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct led_classdev *led_cdev = dev_get_drvdata(dev);
@@ -133,7 +145,7 @@ static ssize_t led_delay_off_store(struct device *dev,
/* try to activate hardware acceleration, if any */
if (!led_cdev->blink_set ||
led_cdev->blink_set(led_cdev,
- &timer_data->delay_on, &timer_data->delay_off)) {
+ &timer_data->delay_on, &timer_data->delay_off)) {
/* no hardware acceleration, blink via timer */
mod_timer(&timer_data->timer, jiffies + 1);
}
@@ -156,6 +168,9 @@ static void timer_trig_activate(struct led_classdev *led_cdev)
if (!timer_data)
return;
+ timer_data->brightness_on = led_get_brightness(led_cdev);
+ if (timer_data->brightness_on == LED_OFF)
+ timer_data->brightness_on = LED_FULL;
led_cdev->trigger_data = timer_data;
init_timer(&timer_data->timer);