Home | History | Annotate | Download | only in misc
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * (C) Copyright 2000-2003
      4  * Wolfgang Denk, DENX Software Engineering, wd (at) 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 }
    125