blob: f15bbe8215b6f9589a3c56f780eee50f06f69b02 [file] [log] [blame]
wdenk0db5bca2003-03-31 17:27:09 +00001/*
2 * (C) Copyright 2000-2002 Wolfgang Denk, DENX Software Engineering, wd@denx.de
3 * (C) Copyright 2003 Martin Winistoerfer, martinwinistoerfer@gmx.ch.
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24/*
25 * File: status_led.c
26 *
27 * Discription: Blink a board led to show boot progress. Led's
28 * are connected via the MIOS module.
29 */
30
31#include <common.h>
32#include <mpc5xx.h>
33#include <status_led.h>
34
35#ifdef CONFIG_STATUS_LED
36
37typedef struct {
38 ulong mask;
39 int state;
40 int period;
41 int cnt;
42} led_dev_t;
43
44led_dev_t led_dev[] = {
45 { STATUS_LED_BIT,
46 STATUS_LED_STATE,
47 STATUS_LED_PERIOD,
48 0,
49 },
50#if defined(STATUS_LED_BIT1)
51 { STATUS_LED_BIT1,
52 STATUS_LED_STATE1,
53 STATUS_LED_PERIOD1,
54 0,
55 },
56#endif
57#if defined(STATUS_LED_BIT2)
58 { STATUS_LED_BIT2,
59 STATUS_LED_STATE2,
60 STATUS_LED_PERIOD2,
61 0,
62 },
63#endif
64#if defined(STATUS_LED_BIT3)
65 { STATUS_LED_BIT3,
66 STATUS_LED_STATE3,
67 STATUS_LED_PERIOD3,
68 0,
69 },
70#endif
71};
72
73#define MAX_LED_DEV (sizeof(led_dev)/sizeof(led_dev_t))
74
75static int status_led_init_done = 0;
76
77static void status_led_init (void)
78{
79 volatile immap_t *immr = (immap_t *)CFG_IMMR;
80 int i;
81
82 for (i=0; i<MAX_LED_DEV; ++i) {
83 led_dev_t *ld = &led_dev[i];
84
85 immr->STATUS_LED_DIR = STATUS_LED_BIT;
86
87#if (STATUS_LED_ACTIVE == 0)
88 if (ld->state == STATUS_LED_ON)
89 immr->STATUS_LED_DAT &= ~(ld->mask);
90 else
91 immr->STATUS_LED_DAT |= ld->mask ;
92#else
93 if (ld->state == STATUS_LED_ON)
94 immr->STATUS_LED_DAT |= ld->mask ;
95 else
96 immr->STATUS_LED_DAT &= ~(ld->mask);
97#endif
98 }
99
100 status_led_init_done = 1;
101}
102
103void status_led_tick (ulong timestamp)
104{
105 volatile immap_t *immr = (immap_t *)CFG_IMMR;
106 int i;
107
108 if (!status_led_init_done)
109 status_led_init();
110
111 for (i=0; i<MAX_LED_DEV; ++i) {
112 led_dev_t *ld = &led_dev[i];
113
114 if (ld->state != STATUS_LED_BLINKING)
115 continue;
116
117 if (++(ld->cnt) >= ld->period) {
118 immr->STATUS_LED_DAT ^= ld->mask;
119 ld->cnt -= ld->period;
120 }
121 }
122}
123
124void status_led_set (int led, int state)
125{
126 volatile immap_t *immr = (immap_t *)CFG_IMMR;
127 led_dev_t *ld;
128
129 if (led < 0 || led >= MAX_LED_DEV)
130 return;
131
132 if (!status_led_init_done)
133 status_led_init();
134
135 ld = &led_dev[led];
136
137 switch (state) {
138 default:
139 return;
140 case STATUS_LED_BLINKING:
141 ld->cnt = 0; /* always start with full period */
142 /* fall through */ /* always start with LED _ON_ */
143 case STATUS_LED_ON:
144#if (STATUS_LED_ACTIVE == 0)
145 immr->STATUS_LED_DAT &= ~(ld->mask);
146#else
147 immr->STATUS_LED_DAT |= ld->mask ;
148#endif
149 break;
150 case STATUS_LED_OFF:
151#if (STATUS_LED_ACTIVE == 0)
152 immr->STATUS_LED_DAT |= ld->mask ;
153#else
154 immr->STATUS_LED_DAT &= ~(ld->mask);
155#endif
156 break;
157 }
158 ld->state = state;
159}
160
161#endif /* CONFIG_STATUS_LED */