
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@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