From 6f3e14163e066a6f43a54098a12185f25400fd68 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Sun, 10 Jul 2005 19:58:10 +0100 Subject: [PATCH] ARM: 2799/1: OMAP update 4/11: Move OMAP1 LED code into mach-omap1 directory Patch from Tony Lindgren This patch by Paul Mundt and other OMAP developers moves OMAP1 specific LED code into mach-omap1 directory. Signed-off-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/mach-omap/leds-h2p2-debug.c | 144 ------------------------- arch/arm/mach-omap/leds-innovator.c | 103 ------------------ arch/arm/mach-omap/leds-osk.c | 198 ---------------------------------- arch/arm/mach-omap/leds.c | 61 ----------- arch/arm/mach-omap/leds.h | 3 - arch/arm/mach-omap1/leds-h2p2-debug.c | 144 +++++++++++++++++++++++++ arch/arm/mach-omap1/leds-innovator.c | 103 ++++++++++++++++++ arch/arm/mach-omap1/leds-osk.c | 194 +++++++++++++++++++++++++++++++++ arch/arm/mach-omap1/leds.c | 61 +++++++++++ arch/arm/mach-omap1/leds.h | 3 + 10 files changed, 505 insertions(+), 509 deletions(-) delete mode 100644 arch/arm/mach-omap/leds-h2p2-debug.c delete mode 100644 arch/arm/mach-omap/leds-innovator.c delete mode 100644 arch/arm/mach-omap/leds-osk.c delete mode 100644 arch/arm/mach-omap/leds.c delete mode 100644 arch/arm/mach-omap/leds.h create mode 100644 arch/arm/mach-omap1/leds-h2p2-debug.c create mode 100644 arch/arm/mach-omap1/leds-innovator.c create mode 100644 arch/arm/mach-omap1/leds-osk.c create mode 100644 arch/arm/mach-omap1/leds.c create mode 100644 arch/arm/mach-omap1/leds.h diff --git a/arch/arm/mach-omap/leds-h2p2-debug.c b/arch/arm/mach-omap/leds-h2p2-debug.c deleted file mode 100644 index 6e98290cca5..00000000000 --- a/arch/arm/mach-omap/leds-h2p2-debug.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * linux/arch/arm/mach-omap/leds-h2p2-debug.c - * - * Copyright 2003 by Texas Instruments Incorporated - * - * There are 16 LEDs on the debug board (all green); four may be used - * for logical 'green', 'amber', 'red', and 'blue' (after "claiming"). - * - * The "surfer" expansion board and H2 sample board also have two-color - * green+red LEDs (in parallel), used here for timer and idle indicators. - */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include "leds.h" - - -#define GPIO_LED_RED 3 -#define GPIO_LED_GREEN OMAP_MPUIO(4) - - -#define LED_STATE_ENABLED 0x01 -#define LED_STATE_CLAIMED 0x02 -#define LED_TIMER_ON 0x04 - -#define GPIO_IDLE GPIO_LED_GREEN -#define GPIO_TIMER GPIO_LED_RED - - -void h2p2_dbg_leds_event(led_event_t evt) -{ - unsigned long flags; - - static struct h2p2_dbg_fpga __iomem *fpga; - static u16 led_state, hw_led_state; - - local_irq_save(flags); - - if (!(led_state & LED_STATE_ENABLED) && evt != led_start) - goto done; - - switch (evt) { - case led_start: - if (!fpga) - fpga = ioremap(H2P2_DBG_FPGA_START, - H2P2_DBG_FPGA_SIZE); - if (fpga) { - led_state |= LED_STATE_ENABLED; - __raw_writew(~0, &fpga->leds); - } - break; - - case led_stop: - case led_halted: - /* all leds off during suspend or shutdown */ - omap_set_gpio_dataout(GPIO_TIMER, 0); - omap_set_gpio_dataout(GPIO_IDLE, 0); - __raw_writew(~0, &fpga->leds); - led_state &= ~LED_STATE_ENABLED; - if (evt == led_halted) { - iounmap(fpga); - fpga = NULL; - } - goto done; - - case led_claim: - led_state |= LED_STATE_CLAIMED; - hw_led_state = 0; - break; - - case led_release: - led_state &= ~LED_STATE_CLAIMED; - break; - -#ifdef CONFIG_LEDS_TIMER - case led_timer: - led_state ^= LED_TIMER_ON; - omap_set_gpio_dataout(GPIO_TIMER, led_state & LED_TIMER_ON); - goto done; -#endif - -#ifdef CONFIG_LEDS_CPU - case led_idle_start: - omap_set_gpio_dataout(GPIO_IDLE, 1); - goto done; - - case led_idle_end: - omap_set_gpio_dataout(GPIO_IDLE, 0); - goto done; -#endif - - case led_green_on: - hw_led_state |= H2P2_DBG_FPGA_LED_GREEN; - break; - case led_green_off: - hw_led_state &= ~H2P2_DBG_FPGA_LED_GREEN; - break; - - case led_amber_on: - hw_led_state |= H2P2_DBG_FPGA_LED_AMBER; - break; - case led_amber_off: - hw_led_state &= ~H2P2_DBG_FPGA_LED_AMBER; - break; - - case led_red_on: - hw_led_state |= H2P2_DBG_FPGA_LED_RED; - break; - case led_red_off: - hw_led_state &= ~H2P2_DBG_FPGA_LED_RED; - break; - - case led_blue_on: - hw_led_state |= H2P2_DBG_FPGA_LED_BLUE; - break; - case led_blue_off: - hw_led_state &= ~H2P2_DBG_FPGA_LED_BLUE; - break; - - default: - break; - } - - - /* - * Actually burn the LEDs - */ - if (led_state & LED_STATE_CLAIMED) - __raw_writew(~hw_led_state, &fpga->leds); - -done: - local_irq_restore(flags); -} diff --git a/arch/arm/mach-omap/leds-innovator.c b/arch/arm/mach-omap/leds-innovator.c deleted file mode 100644 index 8043b7d0f66..00000000000 --- a/arch/arm/mach-omap/leds-innovator.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * linux/arch/arm/mach-omap/leds-innovator.c - */ -#include -#include - -#include -#include -#include - -#include "leds.h" - - -#define LED_STATE_ENABLED 1 -#define LED_STATE_CLAIMED 2 - -static unsigned int led_state; -static unsigned int hw_led_state; - -void innovator_leds_event(led_event_t evt) -{ - unsigned long flags; - - local_irq_save(flags); - - switch (evt) { - case led_start: - hw_led_state = 0; - led_state = LED_STATE_ENABLED; - break; - - case led_stop: - led_state &= ~LED_STATE_ENABLED; - hw_led_state = 0; - break; - - case led_claim: - led_state |= LED_STATE_CLAIMED; - hw_led_state = 0; - break; - - case led_release: - led_state &= ~LED_STATE_CLAIMED; - hw_led_state = 0; - break; - -#ifdef CONFIG_LEDS_TIMER - case led_timer: - if (!(led_state & LED_STATE_CLAIMED)) - hw_led_state ^= 0; - break; -#endif - -#ifdef CONFIG_LEDS_CPU - case led_idle_start: - if (!(led_state & LED_STATE_CLAIMED)) - hw_led_state |= 0; - break; - - case led_idle_end: - if (!(led_state & LED_STATE_CLAIMED)) - hw_led_state &= ~0; - break; -#endif - - case led_halted: - break; - - case led_green_on: - if (led_state & LED_STATE_CLAIMED) - hw_led_state &= ~0; - break; - - case led_green_off: - if (led_state & LED_STATE_CLAIMED) - hw_led_state |= 0; - break; - - case led_amber_on: - break; - - case led_amber_off: - break; - - case led_red_on: - if (led_state & LED_STATE_CLAIMED) - hw_led_state &= ~0; - break; - - case led_red_off: - if (led_state & LED_STATE_CLAIMED) - hw_led_state |= 0; - break; - - default: - break; - } - - if (led_state & LED_STATE_ENABLED) - ; - - local_irq_restore(flags); -} diff --git a/arch/arm/mach-omap/leds-osk.c b/arch/arm/mach-omap/leds-osk.c deleted file mode 100644 index f5177f43079..00000000000 --- a/arch/arm/mach-omap/leds-osk.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * linux/arch/arm/mach-omap/leds-osk.c - * - * LED driver for OSK, and optionally Mistral QVGA, boards - */ -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include "leds.h" - - -#define LED_STATE_ENABLED (1 << 0) -#define LED_STATE_CLAIMED (1 << 1) -static u8 led_state; - -#define GREEN_LED (1 << 0) /* TPS65010 LED1 */ -#define AMBER_LED (1 << 1) /* TPS65010 LED2 */ -#define RED_LED (1 << 2) /* TPS65010 GPIO2 */ -#define TIMER_LED (1 << 3) /* Mistral board */ -#define IDLE_LED (1 << 4) /* Mistral board */ -static u8 hw_led_state; - - -/* TPS65010 leds are changed using i2c -- from a task context. - * Using one of these for the "idle" LED would be impractical... - */ -#define TPS_LEDS (GREEN_LED | RED_LED | AMBER_LED) - -static u8 tps_leds_change; - -static void tps_work(void *unused) -{ - for (;;) { - u8 leds; - - local_irq_disable(); - leds = tps_leds_change; - tps_leds_change = 0; - local_irq_enable(); - - if (!leds) - break; - - /* careful: the set_led() value is on/off/blink */ - if (leds & GREEN_LED) - tps65010_set_led(LED1, !!(hw_led_state & GREEN_LED)); - if (leds & AMBER_LED) - tps65010_set_led(LED2, !!(hw_led_state & AMBER_LED)); - - /* the gpio led doesn't have that issue */ - if (leds & RED_LED) - tps65010_set_gpio_out_value(GPIO2, - !(hw_led_state & RED_LED)); - } -} - -static DECLARE_WORK(work, tps_work, NULL); - -#ifdef CONFIG_FB_OMAP - -/* For now, all system indicators require the Mistral board, since that - * LED can be manipulated without a task context. This LED is either red, - * or green, but not both; it can't give the full "disco led" effect. - */ - -#define GPIO_LED_RED 3 -#define GPIO_LED_GREEN OMAP_MPUIO(4) - -static void mistral_setled(void) -{ - int red = 0; - int green = 0; - - if (hw_led_state & TIMER_LED) - red = 1; - else if (hw_led_state & IDLE_LED) - green = 1; - // else both sides are disabled - - omap_set_gpio_dataout(GPIO_LED_GREEN, green); - omap_set_gpio_dataout(GPIO_LED_RED, red); -} - -#endif - -void osk_leds_event(led_event_t evt) -{ - unsigned long flags; - u16 leds; - - local_irq_save(flags); - - if (!(led_state & LED_STATE_ENABLED) && evt != led_start) - goto done; - - leds = hw_led_state; - switch (evt) { - case led_start: - led_state |= LED_STATE_ENABLED; - hw_led_state = 0; - leds = ~0; - break; - - case led_halted: - case led_stop: - led_state &= ~LED_STATE_ENABLED; - hw_led_state = 0; - // NOTE: work may still be pending!! - break; - - case led_claim: - led_state |= LED_STATE_CLAIMED; - hw_led_state = 0; - leds = ~0; - break; - - case led_release: - led_state &= ~LED_STATE_CLAIMED; - hw_led_state = 0; - break; - -#ifdef CONFIG_FB_OMAP - -#ifdef CONFIG_LEDS_TIMER - case led_timer: - hw_led_state ^= TIMER_LED; - mistral_setled(); - break; -#endif - -#ifdef CONFIG_LEDS_CPU - case led_idle_start: - hw_led_state |= IDLE_LED; - mistral_setled(); - break; - - case led_idle_end: - hw_led_state &= ~IDLE_LED; - mistral_setled(); - break; -#endif - -#endif /* CONFIG_FB_OMAP */ - - /* "green" == tps LED1 (leftmost, normally power-good) - * works only with DC adapter, not on battery power! - */ - case led_green_on: - if (led_state & LED_STATE_CLAIMED) - hw_led_state |= GREEN_LED; - break; - case led_green_off: - if (led_state & LED_STATE_CLAIMED) - hw_led_state &= ~GREEN_LED; - break; - - /* "amber" == tps LED2 (middle) */ - case led_amber_on: - if (led_state & LED_STATE_CLAIMED) - hw_led_state |= AMBER_LED; - break; - case led_amber_off: - if (led_state & LED_STATE_CLAIMED) - hw_led_state &= ~AMBER_LED; - break; - - /* "red" == LED on tps gpio3 (rightmost) */ - case led_red_on: - if (led_state & LED_STATE_CLAIMED) - hw_led_state |= RED_LED; - break; - case led_red_off: - if (led_state & LED_STATE_CLAIMED) - hw_led_state &= ~RED_LED; - break; - - default: - break; - } - - leds ^= hw_led_state; - leds &= TPS_LEDS; - if (leds && (led_state & LED_STATE_CLAIMED)) { - tps_leds_change |= leds; - schedule_work(&work); - } - -done: - local_irq_restore(flags); -} diff --git a/arch/arm/mach-omap/leds.c b/arch/arm/mach-omap/leds.c deleted file mode 100644 index 8ab21fe98e1..00000000000 --- a/arch/arm/mach-omap/leds.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * linux/arch/arm/mach-omap/leds.c - * - * OMAP LEDs dispatcher - */ -#include -#include - -#include -#include - -#include -#include - -#include "leds.h" - -static int __init -omap_leds_init(void) -{ - if (machine_is_omap_innovator()) - leds_event = innovator_leds_event; - - else if (machine_is_omap_h2() || machine_is_omap_perseus2()) - leds_event = h2p2_dbg_leds_event; - - else if (machine_is_omap_osk()) - leds_event = osk_leds_event; - - else - return -1; - - if (machine_is_omap_h2() - || machine_is_omap_perseus2() - || machine_is_omap_osk()) { - - /* LED1/LED2 pins can be used as GPIO (as done here), or by - * the LPG (works even in deep sleep!), to drive a bicolor - * LED on the H2 sample board, and another on the H2/P2 - * "surfer" expansion board. - * - * The same pins drive a LED on the OSK Mistral board, but - * that's a different kind of LED (just one color at a time). - */ - omap_cfg_reg(P18_1610_GPIO3); - if (omap_request_gpio(3) == 0) - omap_set_gpio_direction(3, 0); - else - printk(KERN_WARNING "LED: can't get GPIO3/red?\n"); - - omap_cfg_reg(MPUIO4); - if (omap_request_gpio(OMAP_MPUIO(4)) == 0) - omap_set_gpio_direction(OMAP_MPUIO(4), 0); - else - printk(KERN_WARNING "LED: can't get MPUIO4/green?\n"); - } - - leds_event(led_start); - return 0; -} - -__initcall(omap_leds_init); diff --git a/arch/arm/mach-omap/leds.h b/arch/arm/mach-omap/leds.h deleted file mode 100644 index a1e9fedc376..00000000000 --- a/arch/arm/mach-omap/leds.h +++ /dev/null @@ -1,3 +0,0 @@ -extern void innovator_leds_event(led_event_t evt); -extern void h2p2_dbg_leds_event(led_event_t evt); -extern void osk_leds_event(led_event_t evt); diff --git a/arch/arm/mach-omap1/leds-h2p2-debug.c b/arch/arm/mach-omap1/leds-h2p2-debug.c new file mode 100644 index 00000000000..6e98290cca5 --- /dev/null +++ b/arch/arm/mach-omap1/leds-h2p2-debug.c @@ -0,0 +1,144 @@ +/* + * linux/arch/arm/mach-omap/leds-h2p2-debug.c + * + * Copyright 2003 by Texas Instruments Incorporated + * + * There are 16 LEDs on the debug board (all green); four may be used + * for logical 'green', 'amber', 'red', and 'blue' (after "claiming"). + * + * The "surfer" expansion board and H2 sample board also have two-color + * green+red LEDs (in parallel), used here for timer and idle indicators. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "leds.h" + + +#define GPIO_LED_RED 3 +#define GPIO_LED_GREEN OMAP_MPUIO(4) + + +#define LED_STATE_ENABLED 0x01 +#define LED_STATE_CLAIMED 0x02 +#define LED_TIMER_ON 0x04 + +#define GPIO_IDLE GPIO_LED_GREEN +#define GPIO_TIMER GPIO_LED_RED + + +void h2p2_dbg_leds_event(led_event_t evt) +{ + unsigned long flags; + + static struct h2p2_dbg_fpga __iomem *fpga; + static u16 led_state, hw_led_state; + + local_irq_save(flags); + + if (!(led_state & LED_STATE_ENABLED) && evt != led_start) + goto done; + + switch (evt) { + case led_start: + if (!fpga) + fpga = ioremap(H2P2_DBG_FPGA_START, + H2P2_DBG_FPGA_SIZE); + if (fpga) { + led_state |= LED_STATE_ENABLED; + __raw_writew(~0, &fpga->leds); + } + break; + + case led_stop: + case led_halted: + /* all leds off during suspend or shutdown */ + omap_set_gpio_dataout(GPIO_TIMER, 0); + omap_set_gpio_dataout(GPIO_IDLE, 0); + __raw_writew(~0, &fpga->leds); + led_state &= ~LED_STATE_ENABLED; + if (evt == led_halted) { + iounmap(fpga); + fpga = NULL; + } + goto done; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = 0; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + led_state ^= LED_TIMER_ON; + omap_set_gpio_dataout(GPIO_TIMER, led_state & LED_TIMER_ON); + goto done; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + omap_set_gpio_dataout(GPIO_IDLE, 1); + goto done; + + case led_idle_end: + omap_set_gpio_dataout(GPIO_IDLE, 0); + goto done; +#endif + + case led_green_on: + hw_led_state |= H2P2_DBG_FPGA_LED_GREEN; + break; + case led_green_off: + hw_led_state &= ~H2P2_DBG_FPGA_LED_GREEN; + break; + + case led_amber_on: + hw_led_state |= H2P2_DBG_FPGA_LED_AMBER; + break; + case led_amber_off: + hw_led_state &= ~H2P2_DBG_FPGA_LED_AMBER; + break; + + case led_red_on: + hw_led_state |= H2P2_DBG_FPGA_LED_RED; + break; + case led_red_off: + hw_led_state &= ~H2P2_DBG_FPGA_LED_RED; + break; + + case led_blue_on: + hw_led_state |= H2P2_DBG_FPGA_LED_BLUE; + break; + case led_blue_off: + hw_led_state &= ~H2P2_DBG_FPGA_LED_BLUE; + break; + + default: + break; + } + + + /* + * Actually burn the LEDs + */ + if (led_state & LED_STATE_CLAIMED) + __raw_writew(~hw_led_state, &fpga->leds); + +done: + local_irq_restore(flags); +} diff --git a/arch/arm/mach-omap1/leds-innovator.c b/arch/arm/mach-omap1/leds-innovator.c new file mode 100644 index 00000000000..8043b7d0f66 --- /dev/null +++ b/arch/arm/mach-omap1/leds-innovator.c @@ -0,0 +1,103 @@ +/* + * linux/arch/arm/mach-omap/leds-innovator.c + */ +#include +#include + +#include +#include +#include + +#include "leds.h" + + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 + +static unsigned int led_state; +static unsigned int hw_led_state; + +void innovator_leds_event(led_event_t evt) +{ + unsigned long flags; + + local_irq_save(flags); + + switch (evt) { + case led_start: + hw_led_state = 0; + led_state = LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + hw_led_state = 0; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = 0; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = 0; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= 0; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= 0; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~0; + break; +#endif + + case led_halted: + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~0; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= 0; + break; + + case led_amber_on: + break; + + case led_amber_off: + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~0; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= 0; + break; + + default: + break; + } + + if (led_state & LED_STATE_ENABLED) + ; + + local_irq_restore(flags); +} diff --git a/arch/arm/mach-omap1/leds-osk.c b/arch/arm/mach-omap1/leds-osk.c new file mode 100644 index 00000000000..4a0e8b9d4fc --- /dev/null +++ b/arch/arm/mach-omap1/leds-osk.c @@ -0,0 +1,194 @@ +/* + * linux/arch/arm/mach-omap/leds-osk.c + * + * LED driver for OSK, and optionally Mistral QVGA, boards + */ +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include "leds.h" + + +#define LED_STATE_ENABLED (1 << 0) +#define LED_STATE_CLAIMED (1 << 1) +static u8 led_state; + +#define GREEN_LED (1 << 0) /* TPS65010 LED1 */ +#define AMBER_LED (1 << 1) /* TPS65010 LED2 */ +#define RED_LED (1 << 2) /* TPS65010 GPIO2 */ +#define TIMER_LED (1 << 3) /* Mistral board */ +#define IDLE_LED (1 << 4) /* Mistral board */ +static u8 hw_led_state; + + +/* TPS65010 leds are changed using i2c -- from a task context. + * Using one of these for the "idle" LED would be impractical... + */ +#define TPS_LEDS (GREEN_LED | RED_LED | AMBER_LED) + +static u8 tps_leds_change; + +static void tps_work(void *unused) +{ + for (;;) { + u8 leds; + + local_irq_disable(); + leds = tps_leds_change; + tps_leds_change = 0; + local_irq_enable(); + + if (!leds) + break; + + /* careful: the set_led() value is on/off/blink */ + if (leds & GREEN_LED) + tps65010_set_led(LED1, !!(hw_led_state & GREEN_LED)); + if (leds & AMBER_LED) + tps65010_set_led(LED2, !!(hw_led_state & AMBER_LED)); + + /* the gpio led doesn't have that issue */ + if (leds & RED_LED) + tps65010_set_gpio_out_value(GPIO2, + !(hw_led_state & RED_LED)); + } +} + +static DECLARE_WORK(work, tps_work, NULL); + +#ifdef CONFIG_FB_OMAP + +/* For now, all system indicators require the Mistral board, since that + * LED can be manipulated without a task context. This LED is either red, + * or green, but not both; it can't give the full "disco led" effect. + */ + +#define GPIO_LED_RED 3 +#define GPIO_LED_GREEN OMAP_MPUIO(4) + +static void mistral_setled(void) +{ + int red = 0; + int green = 0; + + if (hw_led_state & TIMER_LED) + red = 1; + else if (hw_led_state & IDLE_LED) + green = 1; + // else both sides are disabled + + omap_set_gpio_dataout(GPIO_LED_GREEN, green); + omap_set_gpio_dataout(GPIO_LED_RED, red); +} + +#endif + +void osk_leds_event(led_event_t evt) +{ + unsigned long flags; + u16 leds; + + local_irq_save(flags); + + if (!(led_state & LED_STATE_ENABLED) && evt != led_start) + goto done; + + leds = hw_led_state; + switch (evt) { + case led_start: + led_state |= LED_STATE_ENABLED; + hw_led_state = 0; + leds = ~0; + break; + + case led_halted: + case led_stop: + led_state &= ~LED_STATE_ENABLED; + hw_led_state = 0; + // NOTE: work may still be pending!! + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = 0; + leds = ~0; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = 0; + break; + +#ifdef CONFIG_FB_OMAP + + case led_timer: + hw_led_state ^= TIMER_LED; + mistral_setled(); + break; + + case led_idle_start: + hw_led_state |= IDLE_LED; + mistral_setled(); + break; + + case led_idle_end: + hw_led_state &= ~IDLE_LED; + mistral_setled(); + break; + +#endif /* CONFIG_FB_OMAP */ + + /* "green" == tps LED1 (leftmost, normally power-good) + * works only with DC adapter, not on battery power! + */ + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= GREEN_LED; + break; + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~GREEN_LED; + break; + + /* "amber" == tps LED2 (middle) */ + case led_amber_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= AMBER_LED; + break; + case led_amber_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~AMBER_LED; + break; + + /* "red" == LED on tps gpio3 (rightmost) */ + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= RED_LED; + break; + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~RED_LED; + break; + + default: + break; + } + + leds ^= hw_led_state; + leds &= TPS_LEDS; + if (leds && (led_state & LED_STATE_CLAIMED)) { + tps_leds_change |= leds; + schedule_work(&work); + } + +done: + local_irq_restore(flags); +} diff --git a/arch/arm/mach-omap1/leds.c b/arch/arm/mach-omap1/leds.c new file mode 100644 index 00000000000..8ab21fe98e1 --- /dev/null +++ b/arch/arm/mach-omap1/leds.c @@ -0,0 +1,61 @@ +/* + * linux/arch/arm/mach-omap/leds.c + * + * OMAP LEDs dispatcher + */ +#include +#include + +#include +#include + +#include +#include + +#include "leds.h" + +static int __init +omap_leds_init(void) +{ + if (machine_is_omap_innovator()) + leds_event = innovator_leds_event; + + else if (machine_is_omap_h2() || machine_is_omap_perseus2()) + leds_event = h2p2_dbg_leds_event; + + else if (machine_is_omap_osk()) + leds_event = osk_leds_event; + + else + return -1; + + if (machine_is_omap_h2() + || machine_is_omap_perseus2() + || machine_is_omap_osk()) { + + /* LED1/LED2 pins can be used as GPIO (as done here), or by + * the LPG (works even in deep sleep!), to drive a bicolor + * LED on the H2 sample board, and another on the H2/P2 + * "surfer" expansion board. + * + * The same pins drive a LED on the OSK Mistral board, but + * that's a different kind of LED (just one color at a time). + */ + omap_cfg_reg(P18_1610_GPIO3); + if (omap_request_gpio(3) == 0) + omap_set_gpio_direction(3, 0); + else + printk(KERN_WARNING "LED: can't get GPIO3/red?\n"); + + omap_cfg_reg(MPUIO4); + if (omap_request_gpio(OMAP_MPUIO(4)) == 0) + omap_set_gpio_direction(OMAP_MPUIO(4), 0); + else + printk(KERN_WARNING "LED: can't get MPUIO4/green?\n"); + } + + leds_event(led_start); + return 0; +} + +__initcall(omap_leds_init); diff --git a/arch/arm/mach-omap1/leds.h b/arch/arm/mach-omap1/leds.h new file mode 100644 index 00000000000..a1e9fedc376 --- /dev/null +++ b/arch/arm/mach-omap1/leds.h @@ -0,0 +1,3 @@ +extern void innovator_leds_event(led_event_t evt); +extern void h2p2_dbg_leds_event(led_event_t evt); +extern void osk_leds_event(led_event_t evt); -- cgit v1.2.3