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