[U-Boot] [PATCH v2 5/6] status_led: Add support for inverted LEDs

Otavio Salvador otavio at ossystems.com.br
Sat Sep 28 21:19:24 CEST 2013


There're cases we want to use active-low LEDs and the 'inverted' logic
needs to be added. This includes it using the STATUS_LED_INVERT macro.

Signed-off-by: Otavio Salvador <otavio at ossystems.com.br>
---
Changes in v2:
- rework to keep calling __led_init

 doc/README.LED            |  2 ++
 drivers/misc/status_led.c | 22 ++++++++++++++++++++--
 include/status_led.h      | 14 ++++++++++++++
 3 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/doc/README.LED b/doc/README.LED
index c3bcb3a..c14555a 100644
--- a/doc/README.LED
+++ b/doc/README.LED
@@ -43,6 +43,8 @@ STATUS_LED_RED is the red LED.  It is used signal errors. This must be a valid
 STATUS_LED_BIT value. Other similar color LED's are STATUS_LED_YELLOW and
 STATUS_LED_BLUE.
 
+STATUS_LED_INVERT and STATUS_LED_INVERT<n> to use active-low LEDs.
+
 These board must define these functions
 
 __led_init is called once to initialize the LED to STATUS_LED_STATE. One time
diff --git a/drivers/misc/status_led.c b/drivers/misc/status_led.c
index 33148c9..ef0aa00 100644
--- a/drivers/misc/status_led.c
+++ b/drivers/misc/status_led.c
@@ -23,6 +23,7 @@ typedef struct {
 	led_id_t mask;
 	int state;
 	int period;
+	int invert;
 	int cnt;
 } led_dev_t;
 
@@ -30,12 +31,14 @@ led_dev_t led_dev[] = {
     {	STATUS_LED_BIT,
 	STATUS_LED_STATE,
 	STATUS_LED_PERIOD,
+	STATUS_LED_INVERT,
 	0,
     },
 #if defined(STATUS_LED_BIT1)
     {	STATUS_LED_BIT1,
 	STATUS_LED_STATE1,
 	STATUS_LED_PERIOD1,
+	STATUS_LED_INVERT1,
 	0,
     },
 #endif
@@ -43,6 +46,7 @@ led_dev_t led_dev[] = {
     {	STATUS_LED_BIT2,
 	STATUS_LED_STATE2,
 	STATUS_LED_PERIOD2,
+	STATUS_LED_INVERT2,
 	0,
     },
 #endif
@@ -50,6 +54,7 @@ led_dev_t led_dev[] = {
     {	STATUS_LED_BIT3,
 	STATUS_LED_STATE3,
 	STATUS_LED_PERIOD3,
+	STATUS_LED_INVERT3,
 	0,
     },
 #endif
@@ -59,13 +64,26 @@ led_dev_t led_dev[] = {
 
 static int status_led_init_done = 0;
 
+static int led_state_value(led_dev_t *ld, int state)
+{
+	if (ld->invert) {
+		if (state == STATUS_LED_ON)
+			state = STATUS_LED_OFF;
+		else if (state == STATUS_LED_OFF)
+			state = STATUS_LED_ON;
+	}
+
+	return state;
+}
+
 static void status_led_init (void)
 {
 	led_dev_t *ld;
 	int i;
 
 	for (i = 0, ld = led_dev; i < MAX_LED_DEV; i++, ld++)
-		__led_init (ld->mask, ld->state);
+		__led_init (ld->mask, led_state_value(ld, ld->state));
+
 	status_led_init_done = 1;
 }
 
@@ -109,5 +127,5 @@ void status_led_set (int led, int state)
 		ld->cnt = 0;		/* always start with full period    */
 		state = STATUS_LED_ON;	/* always start with LED _ON_       */
 	}
-	__led_set (ld->mask, state);
+	__led_set (ld->mask, led_state_value(ld, state));
 }
diff --git a/include/status_led.h b/include/status_led.h
index ecff60d..0da3fda 100644
--- a/include/status_led.h
+++ b/include/status_led.h
@@ -288,6 +288,20 @@ extern void __led_set (led_id_t mask, int state);
 #else
 # error Status LED configuration missing
 #endif
+
+#ifndef STATUS_LED_INVERT
+#define STATUS_LED_INVERT 0
+#endif
+#ifndef STATUS_LED_INVERT1
+#define STATUS_LED_INVERT1 0
+#endif
+#ifndef STATUS_LED_INVERT2
+#define STATUS_LED_INVERT2 0
+#endif
+#ifndef STATUS_LED_INVERT3
+#define STATUS_LED_INVERT3 0
+#endif
+
 /************************************************************************/
 
 #ifndef CONFIG_BOARD_SPECIFIC_LED
-- 
1.8.4.rc3



More information about the U-Boot mailing list