LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: "Németh Márton" <nm127@freemail.hu>
To: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Cc: Richard Purdie <rpurdie@rpsys.net>, LKML <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] leds: disable triggers on brightness set
Date: Sun, 10 Feb 2008 12:52:39 +0100	[thread overview]
Message-ID: <47AEE587.6010601@freemail.hu> (raw)
In-Reply-To: <20080207232309.GA2041@khazad-dum.debian.net>

Disable any active triggers when the brightness attribute is
set to zero.

Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: Márton Németh <nm127@freemail.hu>
Cc: Richard Purdie <rpurdie@rpsys.net>
---
diff --git a/Documentation/leds-class.txt b/Documentation/leds-class.txt
index 56757c7..d2aebfb 100644
--- a/Documentation/leds-class.txt
+++ b/Documentation/leds-class.txt
@@ -19,6 +19,12 @@ optimises away.

 Complex triggers whilst available to all LEDs have LED specific
 parameters and work on a per LED basis. The timer trigger is an example.
+The timer trigger will periodically change the LED brightness between
+LED_OFF and the current brightness setting. The "on" and "off" time can
+be specified via /sys/class/leds/<device>/delay_{on,off} in milliseconds.
+You can change the brightness value of a LED independently of the timer
+trigger. However, if you set the brightness value to LED_OFF it will
+also disable the timer trigger.

 You can change triggers in a similar manner to the way an IO scheduler
 is chosen (via /sys/class/leds/<device>/trigger). Trigger specific
@@ -63,9 +69,9 @@ value if it is called with *delay_on==0 && *delay_off==0 parameters. In
 this case the driver should give back the chosen value through delay_on
 and delay_off parameters to the leds subsystem.

-Any call to the brightness_set() callback function should cancel the
-previously programmed hardware blinking function so setting the brightness
-to 0 can also cancel the blinking of the LED.
+Setting the brightness to zero with brightness_set() callback function
+should completely turn off the LED and cancel the previously programmed
+hardware blinking function, if any.


 Known Issues
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index 4a93878..e6c5b98 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -51,6 +51,9 @@ static ssize_t led_brightness_store(struct device *dev,

 	if (count == size) {
 		ret = count;
+
+		if (state == LED_OFF)
+			led_trigger_remove(led_cdev);
 		led_set_brightness(led_cdev, state);
 	}

diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 13c9026..21dd969 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -45,9 +45,7 @@ ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr,
 		trigger_name[len - 1] = '\0';

 	if (!strcmp(trigger_name, "none")) {
-		down_write(&led_cdev->trigger_lock);
-		led_trigger_set(led_cdev, NULL);
-		up_write(&led_cdev->trigger_lock);
+		led_trigger_remove(led_cdev);
 		return count;
 	}

@@ -139,6 +137,13 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger)
 	led_cdev->trigger = trigger;
 }

+void led_trigger_remove(struct led_classdev *led_cdev)
+{
+	down_write(&led_cdev->trigger_lock);
+	led_trigger_set(led_cdev, NULL);
+	up_write(&led_cdev->trigger_lock);
+}
+
 void led_trigger_set_default(struct led_classdev *led_cdev)
 {
 	struct led_trigger *trig;
@@ -231,6 +236,7 @@ void led_trigger_unregister_simple(struct led_trigger *trigger)

 /* Used by LED Class */
 EXPORT_SYMBOL_GPL(led_trigger_set);
+EXPORT_SYMBOL_GPL(led_trigger_remove);
 EXPORT_SYMBOL_GPL(led_trigger_set_default);
 EXPORT_SYMBOL_GPL(led_trigger_show);
 EXPORT_SYMBOL_GPL(led_trigger_store);
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h
index 12b6fe9..0214799 100644
--- a/drivers/leds/leds.h
+++ b/drivers/leds/leds.h
@@ -27,6 +27,11 @@ static inline void led_set_brightness(struct led_classdev *led_cdev,
 		led_cdev->brightness_set(led_cdev, value);
 }

+static inline int led_get_brightness(struct led_classdev *led_cdev)
+{
+	return led_cdev->brightness;
+}
+
 extern struct rw_semaphore leds_list_lock;
 extern struct list_head leds_list;

@@ -34,9 +39,11 @@ extern struct list_head leds_list;
 void led_trigger_set_default(struct led_classdev *led_cdev);
 void led_trigger_set(struct led_classdev *led_cdev,
 			struct led_trigger *trigger);
+void led_trigger_remove(struct led_classdev *led_cdev);
 #else
 #define led_trigger_set_default(x) do {} while(0)
 #define led_trigger_set(x, y) do {} while(0)
+#define led_trigger_remove(x) do {} while(0)
 #endif

 ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr,
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c
index 82c55d6..7062977 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);
@@ -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);

  reply	other threads:[~2008-02-10 11:53 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-07 10:35 [GIT PULL] LED updates Richard Purdie
2008-02-07 21:38 ` Henrique de Moraes Holschuh
2008-02-07 22:13   ` Richard Purdie
2008-02-07 23:23     ` [PATCH] leds: disable triggers on brightness set Henrique de Moraes Holschuh
2008-02-10 11:52       ` Németh Márton [this message]
2008-02-17 23:30         ` Richard Purdie
2008-02-18  1:59           ` Henrique de Moraes Holschuh
2008-02-08  7:03     ` [GIT PULL] LED updates Németh Márton
2008-02-08 11:20       ` Henrique de Moraes Holschuh
2008-02-10 11:52         ` Németh Márton
2008-03-16 18:18     ` Henrique de Moraes Holschuh
2008-03-16 19:29       ` Richard Purdie
2008-03-16 19:48         ` Henrique de Moraes Holschuh
2008-03-17  3:34           ` LED naming standard for LED class Henrique de Moraes Holschuh
2008-03-17  9:51             ` Richard Purdie
2008-03-18  3:35               ` Henrique de Moraes Holschuh
2008-03-18  4:55                 ` Henrique de Moraes Holschuh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=47AEE587.6010601@freemail.hu \
    --to=nm127@freemail.hu \
    --cc=hmh@hmh.eng.br \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rpurdie@rpsys.net \
    --subject='Re: [PATCH] leds: disable triggers on brightness set' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).