]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - cpu/mpc8xx/status_led.c
Initial revision
[karo-tx-uboot.git] / cpu / mpc8xx / status_led.c
1 /*
2  * (C) Copyright 2000
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
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 #include <common.h>
25 #include <mpc8xx.h>
26 #include <status_led.h>
27
28 /*
29  * The purpose of this code is to signal the operational status of a
30  * target which usually boots over the network; while running in
31  * PCBoot, a status LED is blinking. As soon as a valid BOOTP reply
32  * message has been received, the LED is turned off. The Linux
33  * kernel, once it is running, will start blinking the LED again,
34  * with another frequency.
35  */
36
37 /* ------------------------------------------------------------------------- */
38
39 #ifdef CONFIG_STATUS_LED
40
41 typedef struct {
42         ulong   mask;
43         int     state;
44         int     period;
45         int     cnt;
46 } led_dev_t;
47
48 led_dev_t led_dev[] = {
49     {   STATUS_LED_BIT,
50         STATUS_LED_STATE,
51         STATUS_LED_PERIOD,
52         0,
53     },
54 #if defined(STATUS_LED_BIT1)
55     {   STATUS_LED_BIT1,
56         STATUS_LED_STATE1,
57         STATUS_LED_PERIOD1,
58         0,
59     },
60 #endif
61 #if defined(STATUS_LED_BIT2)
62     {   STATUS_LED_BIT2,
63         STATUS_LED_STATE2,
64         STATUS_LED_PERIOD2,
65         0,
66     },
67 #endif
68 #if defined(STATUS_LED_BIT3)
69     {   STATUS_LED_BIT3,
70         STATUS_LED_STATE3,
71         STATUS_LED_PERIOD3,
72         0,
73     },
74 #endif
75 };
76
77 #define MAX_LED_DEV     (sizeof(led_dev)/sizeof(led_dev_t))
78
79 static int status_led_init_done = 0;
80
81 static void status_led_init (void)
82 {
83     volatile immap_t *immr = (immap_t *)CFG_IMMR;
84     int i;
85
86     for (i=0; i<MAX_LED_DEV; ++i) {
87         led_dev_t *ld = &led_dev[i];
88
89         immr->STATUS_LED_PAR &= ~(ld->mask);
90 #ifdef STATUS_LED_ODR
91         immr->STATUS_LED_ODR &= ~(ld->mask);
92 #endif
93 #if (STATUS_LED_ACTIVE == 0)
94         if (ld->state == STATUS_LED_ON)
95                 immr->STATUS_LED_DAT &= ~(ld->mask);
96         else
97                 immr->STATUS_LED_DAT |=   ld->mask ;
98 #else
99         if (ld->state == STATUS_LED_ON)
100                 immr->STATUS_LED_DAT |=   ld->mask ;
101         else
102                 immr->STATUS_LED_DAT &= ~(ld->mask);
103 #endif
104         immr->STATUS_LED_DIR |=   ld->mask ;
105     }
106
107     status_led_init_done  = 1;
108 }
109
110 void status_led_tick (ulong timestamp)
111 {
112     volatile immap_t *immr = (immap_t *)CFG_IMMR;
113     int i;
114
115     if (!status_led_init_done)
116         status_led_init();
117
118     for (i=0; i<MAX_LED_DEV; ++i) {
119         led_dev_t *ld = &led_dev[i];
120
121         if (ld->state != STATUS_LED_BLINKING)
122                 continue;
123
124         if (++(ld->cnt) >= ld->period) {
125                 immr->STATUS_LED_DAT ^= ld->mask;
126                 ld->cnt -= ld->period;
127         }
128     }
129 }
130
131 void status_led_set (int led, int state)
132 {
133     volatile immap_t *immr = (immap_t *)CFG_IMMR;
134     led_dev_t *ld;
135
136     if (led < 0 || led >= MAX_LED_DEV)
137         return;
138
139     if (!status_led_init_done)
140         status_led_init();
141
142     ld = &led_dev[led];
143
144     switch (state) {
145     default:
146         return;
147     case STATUS_LED_BLINKING:
148         ld->cnt = 0;            /* always start with full period        */
149         /* fall through */      /* always start with LED _ON_           */
150     case STATUS_LED_ON:
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     case STATUS_LED_OFF:
158 #if (STATUS_LED_ACTIVE == 0)
159         immr->STATUS_LED_DAT |=   ld->mask ;
160 #else
161         immr->STATUS_LED_DAT &= ~(ld->mask);
162 #endif
163         break;
164     }
165     ld->state = state;
166 }
167
168 #endif  /* CONFIG_STATUS_LED */