xref: /openbmc/u-boot/drivers/misc/status_led.c (revision 83d290c56fab2d38cd1ab4c4cc7099559c1d5046)
1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2318c0b90SJean-Christophe PLAGNIOL-VILLARD /*
3318c0b90SJean-Christophe PLAGNIOL-VILLARD  * (C) Copyright 2000-2003
4318c0b90SJean-Christophe PLAGNIOL-VILLARD  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5318c0b90SJean-Christophe PLAGNIOL-VILLARD  */
6318c0b90SJean-Christophe PLAGNIOL-VILLARD 
7318c0b90SJean-Christophe PLAGNIOL-VILLARD #include <common.h>
8318c0b90SJean-Christophe PLAGNIOL-VILLARD #include <status_led.h>
9318c0b90SJean-Christophe PLAGNIOL-VILLARD 
10318c0b90SJean-Christophe PLAGNIOL-VILLARD /*
11318c0b90SJean-Christophe PLAGNIOL-VILLARD  * The purpose of this code is to signal the operational status of a
12318c0b90SJean-Christophe PLAGNIOL-VILLARD  * target which usually boots over the network; while running in
13318c0b90SJean-Christophe PLAGNIOL-VILLARD  * U-Boot, a status LED is blinking. As soon as a valid BOOTP reply
14318c0b90SJean-Christophe PLAGNIOL-VILLARD  * message has been received, the LED is turned off. The Linux
15318c0b90SJean-Christophe PLAGNIOL-VILLARD  * kernel, once it is running, will start blinking the LED again,
16318c0b90SJean-Christophe PLAGNIOL-VILLARD  * with another frequency.
17318c0b90SJean-Christophe PLAGNIOL-VILLARD  */
18318c0b90SJean-Christophe PLAGNIOL-VILLARD 
19318c0b90SJean-Christophe PLAGNIOL-VILLARD /* ------------------------------------------------------------------------- */
20318c0b90SJean-Christophe PLAGNIOL-VILLARD 
21318c0b90SJean-Christophe PLAGNIOL-VILLARD typedef struct {
22318c0b90SJean-Christophe PLAGNIOL-VILLARD 	led_id_t mask;
23318c0b90SJean-Christophe PLAGNIOL-VILLARD 	int state;
24318c0b90SJean-Christophe PLAGNIOL-VILLARD 	int period;
25318c0b90SJean-Christophe PLAGNIOL-VILLARD 	int cnt;
26318c0b90SJean-Christophe PLAGNIOL-VILLARD } led_dev_t;
27318c0b90SJean-Christophe PLAGNIOL-VILLARD 
28318c0b90SJean-Christophe PLAGNIOL-VILLARD led_dev_t led_dev[] = {
292d8d190cSUri Mashiach 	{	CONFIG_LED_STATUS_BIT,
302d8d190cSUri Mashiach 		CONFIG_LED_STATUS_STATE,
312d8d190cSUri Mashiach 		LED_STATUS_PERIOD,
32318c0b90SJean-Christophe PLAGNIOL-VILLARD 		0,
33318c0b90SJean-Christophe PLAGNIOL-VILLARD 	},
342d8d190cSUri Mashiach #if defined(CONFIG_LED_STATUS1)
352d8d190cSUri Mashiach 	{	CONFIG_LED_STATUS_BIT1,
362d8d190cSUri Mashiach 		CONFIG_LED_STATUS_STATE1,
372d8d190cSUri Mashiach 		LED_STATUS_PERIOD1,
38318c0b90SJean-Christophe PLAGNIOL-VILLARD 		0,
39318c0b90SJean-Christophe PLAGNIOL-VILLARD 	},
40318c0b90SJean-Christophe PLAGNIOL-VILLARD #endif
412d8d190cSUri Mashiach #if defined(CONFIG_LED_STATUS2)
422d8d190cSUri Mashiach 	{	CONFIG_LED_STATUS_BIT2,
432d8d190cSUri Mashiach 		CONFIG_LED_STATUS_STATE2,
442d8d190cSUri Mashiach 		LED_STATUS_PERIOD2,
45318c0b90SJean-Christophe PLAGNIOL-VILLARD 		0,
46318c0b90SJean-Christophe PLAGNIOL-VILLARD 	},
47318c0b90SJean-Christophe PLAGNIOL-VILLARD #endif
482d8d190cSUri Mashiach #if defined(CONFIG_LED_STATUS3)
492d8d190cSUri Mashiach 	{	CONFIG_LED_STATUS_BIT3,
502d8d190cSUri Mashiach 		CONFIG_LED_STATUS_STATE3,
512d8d190cSUri Mashiach 		LED_STATUS_PERIOD3,
52318c0b90SJean-Christophe PLAGNIOL-VILLARD 		0,
53318c0b90SJean-Christophe PLAGNIOL-VILLARD 	},
54318c0b90SJean-Christophe PLAGNIOL-VILLARD #endif
552d8d190cSUri Mashiach #if defined(CONFIG_LED_STATUS4)
562d8d190cSUri Mashiach 	{	CONFIG_LED_STATUS_BIT4,
572d8d190cSUri Mashiach 		CONFIG_LED_STATUS_STATE4,
582d8d190cSUri Mashiach 		LED_STATUS_PERIOD4,
59a8eeaf2fSStefan Roese 		0,
60a8eeaf2fSStefan Roese 	},
61a8eeaf2fSStefan Roese #endif
622d8d190cSUri Mashiach #if defined(CONFIG_LED_STATUS5)
632d8d190cSUri Mashiach 	{	CONFIG_LED_STATUS_BIT5,
642d8d190cSUri Mashiach 		CONFIG_LED_STATUS_STATE5,
652d8d190cSUri Mashiach 		LED_STATUS_PERIOD5,
66a8eeaf2fSStefan Roese 		0,
67a8eeaf2fSStefan Roese 	},
68a8eeaf2fSStefan Roese #endif
69318c0b90SJean-Christophe PLAGNIOL-VILLARD };
70318c0b90SJean-Christophe PLAGNIOL-VILLARD 
71318c0b90SJean-Christophe PLAGNIOL-VILLARD #define MAX_LED_DEV	(sizeof(led_dev)/sizeof(led_dev_t))
72318c0b90SJean-Christophe PLAGNIOL-VILLARD 
73318c0b90SJean-Christophe PLAGNIOL-VILLARD static int status_led_init_done = 0;
74318c0b90SJean-Christophe PLAGNIOL-VILLARD 
status_led_init(void)7513cfbe51SBernhard Nortmann void status_led_init(void)
76318c0b90SJean-Christophe PLAGNIOL-VILLARD {
77318c0b90SJean-Christophe PLAGNIOL-VILLARD 	led_dev_t *ld;
78318c0b90SJean-Christophe PLAGNIOL-VILLARD 	int i;
79318c0b90SJean-Christophe PLAGNIOL-VILLARD 
80318c0b90SJean-Christophe PLAGNIOL-VILLARD 	for (i = 0, ld = led_dev; i < MAX_LED_DEV; i++, ld++)
81318c0b90SJean-Christophe PLAGNIOL-VILLARD 		__led_init (ld->mask, ld->state);
82318c0b90SJean-Christophe PLAGNIOL-VILLARD 	status_led_init_done = 1;
83318c0b90SJean-Christophe PLAGNIOL-VILLARD }
84318c0b90SJean-Christophe PLAGNIOL-VILLARD 
status_led_tick(ulong timestamp)85318c0b90SJean-Christophe PLAGNIOL-VILLARD void status_led_tick (ulong timestamp)
86318c0b90SJean-Christophe PLAGNIOL-VILLARD {
87318c0b90SJean-Christophe PLAGNIOL-VILLARD 	led_dev_t *ld;
88318c0b90SJean-Christophe PLAGNIOL-VILLARD 	int i;
89318c0b90SJean-Christophe PLAGNIOL-VILLARD 
90318c0b90SJean-Christophe PLAGNIOL-VILLARD 	if (!status_led_init_done)
91318c0b90SJean-Christophe PLAGNIOL-VILLARD 		status_led_init ();
92318c0b90SJean-Christophe PLAGNIOL-VILLARD 
93318c0b90SJean-Christophe PLAGNIOL-VILLARD 	for (i = 0, ld = led_dev; i < MAX_LED_DEV; i++, ld++) {
94318c0b90SJean-Christophe PLAGNIOL-VILLARD 
952d8d190cSUri Mashiach 		if (ld->state != CONFIG_LED_STATUS_BLINKING)
96318c0b90SJean-Christophe PLAGNIOL-VILLARD 			continue;
97318c0b90SJean-Christophe PLAGNIOL-VILLARD 
98318c0b90SJean-Christophe PLAGNIOL-VILLARD 		if (++ld->cnt >= ld->period) {
99318c0b90SJean-Christophe PLAGNIOL-VILLARD 			__led_toggle (ld->mask);
100318c0b90SJean-Christophe PLAGNIOL-VILLARD 			ld->cnt -= ld->period;
101318c0b90SJean-Christophe PLAGNIOL-VILLARD 		}
102318c0b90SJean-Christophe PLAGNIOL-VILLARD 
103318c0b90SJean-Christophe PLAGNIOL-VILLARD 	}
104318c0b90SJean-Christophe PLAGNIOL-VILLARD }
105318c0b90SJean-Christophe PLAGNIOL-VILLARD 
status_led_set(int led,int state)106318c0b90SJean-Christophe PLAGNIOL-VILLARD void status_led_set (int led, int state)
107318c0b90SJean-Christophe PLAGNIOL-VILLARD {
108318c0b90SJean-Christophe PLAGNIOL-VILLARD 	led_dev_t *ld;
109318c0b90SJean-Christophe PLAGNIOL-VILLARD 
110318c0b90SJean-Christophe PLAGNIOL-VILLARD 	if (led < 0 || led >= MAX_LED_DEV)
111318c0b90SJean-Christophe PLAGNIOL-VILLARD 		return;
112318c0b90SJean-Christophe PLAGNIOL-VILLARD 
113318c0b90SJean-Christophe PLAGNIOL-VILLARD 	if (!status_led_init_done)
114318c0b90SJean-Christophe PLAGNIOL-VILLARD 		status_led_init ();
115318c0b90SJean-Christophe PLAGNIOL-VILLARD 
116318c0b90SJean-Christophe PLAGNIOL-VILLARD 	ld = &led_dev[led];
117318c0b90SJean-Christophe PLAGNIOL-VILLARD 
118318c0b90SJean-Christophe PLAGNIOL-VILLARD 	ld->state = state;
1192d8d190cSUri Mashiach 	if (state == CONFIG_LED_STATUS_BLINKING) {
120318c0b90SJean-Christophe PLAGNIOL-VILLARD 		ld->cnt = 0;		/* always start with full period    */
1212d8d190cSUri Mashiach 		state = CONFIG_LED_STATUS_ON;	/* always start with LED _ON_ */
122318c0b90SJean-Christophe PLAGNIOL-VILLARD 	}
123318c0b90SJean-Christophe PLAGNIOL-VILLARD 	__led_set (ld->mask, state);
124318c0b90SJean-Christophe PLAGNIOL-VILLARD }
125