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 <asm/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); 35extern spinlock_t gpio_lock; 36 37static void netwinder_leds_event(led_event_t evt) 38{ 39 unsigned long flags; 40 41 spin_lock_irqsave(&leds_lock, flags); 42 43 switch (evt) { 44 case led_start: 45 led_state |= LED_STATE_ENABLED; 46 hw_led_state = GPIO_GREEN_LED; 47 break; 48 49 case led_stop: 50 led_state &= ~LED_STATE_ENABLED; 51 break; 52 53 case led_claim: 54 led_state |= LED_STATE_CLAIMED; 55 hw_led_state = 0; 56 break; 57 58 case led_release: 59 led_state &= ~LED_STATE_CLAIMED; 60 hw_led_state = 0; 61 break; 62 63#ifdef CONFIG_LEDS_TIMER 64 case led_timer: 65 if (!(led_state & LED_STATE_CLAIMED)) 66 hw_led_state ^= GPIO_GREEN_LED; 67 break; 68#endif 69 70#ifdef CONFIG_LEDS_CPU 71 case led_idle_start: 72 if (!(led_state & LED_STATE_CLAIMED)) 73 hw_led_state &= ~GPIO_RED_LED; 74 break; 75 76 case led_idle_end: 77 if (!(led_state & LED_STATE_CLAIMED)) 78 hw_led_state |= GPIO_RED_LED; 79 break; 80#endif 81 82 case led_halted: 83 if (!(led_state & LED_STATE_CLAIMED)) 84 hw_led_state |= GPIO_RED_LED; 85 break; 86 87 case led_green_on: 88 if (led_state & LED_STATE_CLAIMED) 89 hw_led_state |= GPIO_GREEN_LED; 90 break; 91 92 case led_green_off: 93 if (led_state & LED_STATE_CLAIMED) 94 hw_led_state &= ~GPIO_GREEN_LED; 95 break; 96 97 case led_amber_on: 98 if (led_state & LED_STATE_CLAIMED) 99 hw_led_state |= GPIO_GREEN_LED | GPIO_RED_LED; 100 break; 101 102 case led_amber_off: 103 if (led_state & LED_STATE_CLAIMED) 104 hw_led_state &= ~(GPIO_GREEN_LED | GPIO_RED_LED); 105 break; 106 107 case led_red_on: 108 if (led_state & LED_STATE_CLAIMED) 109 hw_led_state |= GPIO_RED_LED; 110 break; 111 112 case led_red_off: 113 if (led_state & LED_STATE_CLAIMED) 114 hw_led_state &= ~GPIO_RED_LED; 115 break; 116 117 default: 118 break; 119 } 120 121 spin_unlock_irqrestore(&leds_lock, flags); 122 123 if (led_state & LED_STATE_ENABLED) { 124 spin_lock_irqsave(&gpio_lock, flags); 125 gpio_modify_op(GPIO_RED_LED | GPIO_GREEN_LED, hw_led_state); 126 spin_unlock_irqrestore(&gpio_lock, flags); 127 } 128} 129 130static int __init leds_init(void) 131{ 132 if (machine_is_netwinder()) 133 leds_event = netwinder_leds_event; 134 135 leds_event(led_start); 136 137 return 0; 138} 139 140__initcall(leds_init); 141