Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
[linux-2.6] / arch / arm / mach-at91 / leds.c
1 /*
2  * LED driver for Atmel AT91-based boards.
3  *
4  *  Copyright (C) SAN People (Pty) Ltd
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10 */
11
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/init.h>
15
16 #include <asm/mach-types.h>
17 #include <asm/arch/board.h>
18 #include <asm/arch/gpio.h>
19
20
21 /* ------------------------------------------------------------------------- */
22
23 #if defined(CONFIG_NEW_LEDS)
24
25 #include <linux/platform_device.h>
26
27 /*
28  * New cross-platform LED support.
29  */
30
31 static struct gpio_led_platform_data led_data;
32
33 static struct platform_device at91_leds = {
34         .name                   = "leds-gpio",
35         .id                     = -1,
36         .dev.platform_data      = &led_data,
37 };
38
39 void __init at91_gpio_leds(struct gpio_led *leds, int nr)
40 {
41         int i;
42
43         if (!nr)
44                 return;
45
46         for (i = 0; i < nr; i++)
47                 at91_set_gpio_output(leds[i].gpio, leds[i].active_low);
48
49         led_data.leds = leds;
50         led_data.num_leds = nr;
51         platform_device_register(&at91_leds);
52 }
53
54 #else
55 void __init at91_gpio_leds(struct gpio_led *leds, int nr) {}
56 #endif
57
58
59 /* ------------------------------------------------------------------------- */
60
61 #if defined(CONFIG_LEDS)
62
63 #include <asm/leds.h>
64
65 /*
66  * Old ARM-specific LED framework; not fully functional when generic time is
67  * in use.
68  */
69
70 static u8 at91_leds_cpu;
71 static u8 at91_leds_timer;
72
73 static inline void at91_led_on(unsigned int led)
74 {
75         at91_set_gpio_value(led, 0);
76 }
77
78 static inline void at91_led_off(unsigned int led)
79 {
80         at91_set_gpio_value(led, 1);
81 }
82
83 static inline void at91_led_toggle(unsigned int led)
84 {
85         unsigned long is_off = at91_get_gpio_value(led);
86         if (is_off)
87                 at91_led_on(led);
88         else
89                 at91_led_off(led);
90 }
91
92
93 /*
94  * Handle LED events.
95  */
96 static void at91_leds_event(led_event_t evt)
97 {
98         unsigned long flags;
99
100         local_irq_save(flags);
101
102         switch(evt) {
103         case led_start:         /* System startup */
104                 at91_led_on(at91_leds_cpu);
105                 break;
106
107         case led_stop:          /* System stop / suspend */
108                 at91_led_off(at91_leds_cpu);
109                 break;
110
111 #ifdef CONFIG_LEDS_TIMER
112         case led_timer:         /* Every 50 timer ticks */
113                 at91_led_toggle(at91_leds_timer);
114                 break;
115 #endif
116
117 #ifdef CONFIG_LEDS_CPU
118         case led_idle_start:    /* Entering idle state */
119                 at91_led_off(at91_leds_cpu);
120                 break;
121
122         case led_idle_end:      /* Exit idle state */
123                 at91_led_on(at91_leds_cpu);
124                 break;
125 #endif
126
127         default:
128                 break;
129         }
130
131         local_irq_restore(flags);
132 }
133
134
135 static int __init leds_init(void)
136 {
137         if (!at91_leds_timer || !at91_leds_cpu)
138                 return -ENODEV;
139
140         leds_event = at91_leds_event;
141
142         leds_event(led_start);
143         return 0;
144 }
145
146 __initcall(leds_init);
147
148
149 void __init at91_init_leds(u8 cpu_led, u8 timer_led)
150 {
151         /* Enable GPIO to access the LEDs */
152         at91_set_gpio_output(cpu_led, 1);
153         at91_set_gpio_output(timer_led, 1);
154
155         at91_leds_cpu   = cpu_led;
156         at91_leds_timer = timer_led;
157 }
158
159 #else
160 void __init at91_init_leds(u8 cpu_led, u8 timer_led) {}
161 #endif