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