1/* 2 * linux/arch/arm/mach-footbridge/netwinder-leds.c 3 * 4 * Copyright (C) 1998-1999 Russell King 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * NetWinder LED control routines. 11 * 12 * The Netwinder uses the leds as follows: 13 * - Green - toggles state every 50 timer interrupts 14 * - Red - On if the system is not idle 15 * 16 * Changelog: 17 * 02-05-1999 RMK Various cleanups 18 */ 19#include <linux/module.h> 20#include <linux/kernel.h> 21#include <linux/init.h> 22#include <linux/spinlock.h> 23 24#include <mach/hardware.h> 25#include <asm/leds.h> 26#include <asm/mach-types.h> 27#include <asm/system.h> 28 29#define LED_STATE_ENABLED 1 30#define LED_STATE_CLAIMED 2 31static char led_state; 32static char hw_led_state; 33 34static DEFINE_SPINLOCK(leds_lock); 35 36static void netwinder_leds_event(led_event_t evt) 37{ 38 unsigned long flags; 39 40 spin_lock_irqsave(&leds_lock, flags); 41 42 switch (evt) { 43 case led_start: 44 led_state |= LED_STATE_ENABLED; 45 hw_led_state = GPIO_GREEN_LED; 46 break; 47 48 case led_stop: 49 led_state &= ~LED_STATE_ENABLED; 50 break; 51 52 case led_claim: 53 led_state |= LED_STATE_CLAIMED; 54 hw_led_state = 0; 55 break; 56 57 case led_release: 58 led_state &= ~LED_STATE_CLAIMED; 59 hw_led_state = 0; 60 break; 61 62#ifdef CONFIG_LEDS_TIMER 63 case led_timer: 64 if (!(led_state & LED_STATE_CLAIMED)) 65 hw_led_state ^= GPIO_GREEN_LED; 66 break; 67#endif 68 69#ifdef CONFIG_LEDS_CPU 70 case led_idle_start: 71 if (!(led_state & LED_STATE_CLAIMED)) 72 hw_led_state &= ~GPIO_RED_LED; 73 break; 74 75 case led_idle_end: 76 if (!(led_state & LED_STATE_CLAIMED)) 77 hw_led_state |= GPIO_RED_LED; 78 break; 79#endif 80 81 case led_halted: 82 if (!(led_state & LED_STATE_CLAIMED)) 83 hw_led_state |= GPIO_RED_LED; 84 break; 85 86 case led_green_on: 87 if (led_state & LED_STATE_CLAIMED) 88 hw_led_state |= GPIO_GREEN_LED; 89 break; 90 91 case led_green_off: 92 if (led_state & LED_STATE_CLAIMED) 93 hw_led_state &= ~GPIO_GREEN_LED; 94 break; 95 96 case led_amber_on: 97 if (led_state & LED_STATE_CLAIMED) 98 hw_led_state |= GPIO_GREEN_LED | GPIO_RED_LED; 99 break; 100 101 case led_amber_off: 102 if (led_state & LED_STATE_CLAIMED) 103 hw_led_state &= ~(GPIO_GREEN_LED | GPIO_RED_LED); 104 break; 105 106 case led_red_on: 107 if (led_state & LED_STATE_CLAIMED) 108 hw_led_state |= GPIO_RED_LED; 109 break; 110 111 case led_red_off: 112 if (led_state & LED_STATE_CLAIMED) 113 hw_led_state &= ~GPIO_RED_LED; 114 break; 115 116 default: 117 break; 118 } 119 120 spin_unlock_irqrestore(&leds_lock, flags); 121 122 if (led_state & LED_STATE_ENABLED) { 123 spin_lock_irqsave(&nw_gpio_lock, flags); 124 nw_gpio_modify_op(GPIO_RED_LED | GPIO_GREEN_LED, hw_led_state); 125 spin_unlock_irqrestore(&nw_gpio_lock, flags); 126 } 127} 128 129static int __init leds_init(void) 130{ 131 if (machine_is_netwinder()) 132 leds_event = netwinder_leds_event; 133 134 leds_event(led_start); 135 136 return 0; 137} 138 139__initcall(leds_init); 140