Merge git://git.denx.de/u-boot-marvell
[platform/kernel/u-boot.git] / drivers / misc / status_led.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2000-2003
4  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5  */
6
7 #include <common.h>
8 #include <status_led.h>
9
10 /*
11  * The purpose of this code is to signal the operational status of a
12  * target which usually boots over the network; while running in
13  * U-Boot, a status LED is blinking. As soon as a valid BOOTP reply
14  * message has been received, the LED is turned off. The Linux
15  * kernel, once it is running, will start blinking the LED again,
16  * with another frequency.
17  */
18
19 /* ------------------------------------------------------------------------- */
20
21 typedef struct {
22         led_id_t mask;
23         int state;
24         int period;
25         int cnt;
26 } led_dev_t;
27
28 led_dev_t led_dev[] = {
29         {       CONFIG_LED_STATUS_BIT,
30                 CONFIG_LED_STATUS_STATE,
31                 LED_STATUS_PERIOD,
32                 0,
33         },
34 #if defined(CONFIG_LED_STATUS1)
35         {       CONFIG_LED_STATUS_BIT1,
36                 CONFIG_LED_STATUS_STATE1,
37                 LED_STATUS_PERIOD1,
38                 0,
39         },
40 #endif
41 #if defined(CONFIG_LED_STATUS2)
42         {       CONFIG_LED_STATUS_BIT2,
43                 CONFIG_LED_STATUS_STATE2,
44                 LED_STATUS_PERIOD2,
45                 0,
46         },
47 #endif
48 #if defined(CONFIG_LED_STATUS3)
49         {       CONFIG_LED_STATUS_BIT3,
50                 CONFIG_LED_STATUS_STATE3,
51                 LED_STATUS_PERIOD3,
52                 0,
53         },
54 #endif
55 #if defined(CONFIG_LED_STATUS4)
56         {       CONFIG_LED_STATUS_BIT4,
57                 CONFIG_LED_STATUS_STATE4,
58                 LED_STATUS_PERIOD4,
59                 0,
60         },
61 #endif
62 #if defined(CONFIG_LED_STATUS5)
63         {       CONFIG_LED_STATUS_BIT5,
64                 CONFIG_LED_STATUS_STATE5,
65                 LED_STATUS_PERIOD5,
66                 0,
67         },
68 #endif
69 };
70
71 #define MAX_LED_DEV     (sizeof(led_dev)/sizeof(led_dev_t))
72
73 static int status_led_init_done = 0;
74
75 void status_led_init(void)
76 {
77         led_dev_t *ld;
78         int i;
79
80         for (i = 0, ld = led_dev; i < MAX_LED_DEV; i++, ld++)
81                 __led_init (ld->mask, ld->state);
82         status_led_init_done = 1;
83 }
84
85 void status_led_tick (ulong timestamp)
86 {
87         led_dev_t *ld;
88         int i;
89
90         if (!status_led_init_done)
91                 status_led_init ();
92
93         for (i = 0, ld = led_dev; i < MAX_LED_DEV; i++, ld++) {
94
95                 if (ld->state != CONFIG_LED_STATUS_BLINKING)
96                         continue;
97
98                 if (++ld->cnt >= ld->period) {
99                         __led_toggle (ld->mask);
100                         ld->cnt -= ld->period;
101                 }
102
103         }
104 }
105
106 void status_led_set (int led, int state)
107 {
108         led_dev_t *ld;
109
110         if (led < 0 || led >= MAX_LED_DEV)
111                 return;
112
113         if (!status_led_init_done)
114                 status_led_init ();
115
116         ld = &led_dev[led];
117
118         ld->state = state;
119         if (state == CONFIG_LED_STATUS_BLINKING) {
120                 ld->cnt = 0;            /* always start with full period    */
121                 state = CONFIG_LED_STATUS_ON;   /* always start with LED _ON_ */
122         }
123         __led_set (ld->mask, state);
124 }