]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - cpu/mpc5xx/status_led.c
* Patch by Martin Winistoerfer, 23 Mar 2003
[karo-tx-uboot.git] / cpu / mpc5xx / status_led.c
1 /*
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
37 typedef struct {
38         ulong   mask;
39         int     state;
40         int     period;
41         int     cnt;
42 } led_dev_t;
43
44 led_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
75 static int status_led_init_done = 0;
76
77 static 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
103 void 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
124 void 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 */