1 /* 2 * (C) Copyright 2000-2003 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 8 #include <common.h> 9 #include <status_led.h> 10 11 /* 12 * The purpose of this code is to signal the operational status of a 13 * target which usually boots over the network; while running in 14 * U-Boot, a status LED is blinking. As soon as a valid BOOTP reply 15 * message has been received, the LED is turned off. The Linux 16 * kernel, once it is running, will start blinking the LED again, 17 * with another frequency. 18 */ 19 20 /* ------------------------------------------------------------------------- */ 21 22 typedef struct { 23 led_id_t mask; 24 int state; 25 int period; 26 int cnt; 27 } led_dev_t; 28 29 led_dev_t led_dev[] = { 30 { STATUS_LED_BIT, 31 STATUS_LED_STATE, 32 STATUS_LED_PERIOD, 33 0, 34 }, 35 #if defined(STATUS_LED_BIT1) 36 { STATUS_LED_BIT1, 37 STATUS_LED_STATE1, 38 STATUS_LED_PERIOD1, 39 0, 40 }, 41 #endif 42 #if defined(STATUS_LED_BIT2) 43 { STATUS_LED_BIT2, 44 STATUS_LED_STATE2, 45 STATUS_LED_PERIOD2, 46 0, 47 }, 48 #endif 49 #if defined(STATUS_LED_BIT3) 50 { STATUS_LED_BIT3, 51 STATUS_LED_STATE3, 52 STATUS_LED_PERIOD3, 53 0, 54 }, 55 #endif 56 }; 57 58 #define MAX_LED_DEV (sizeof(led_dev)/sizeof(led_dev_t)) 59 60 static int status_led_init_done = 0; 61 62 static void status_led_init (void) 63 { 64 led_dev_t *ld; 65 int i; 66 67 for (i = 0, ld = led_dev; i < MAX_LED_DEV; i++, ld++) 68 __led_init (ld->mask, ld->state); 69 status_led_init_done = 1; 70 } 71 72 void status_led_tick (ulong timestamp) 73 { 74 led_dev_t *ld; 75 int i; 76 77 if (!status_led_init_done) 78 status_led_init (); 79 80 for (i = 0, ld = led_dev; i < MAX_LED_DEV; i++, ld++) { 81 82 if (ld->state != STATUS_LED_BLINKING) 83 continue; 84 85 if (++ld->cnt >= ld->period) { 86 __led_toggle (ld->mask); 87 ld->cnt -= ld->period; 88 } 89 90 } 91 } 92 93 void status_led_set (int led, int state) 94 { 95 led_dev_t *ld; 96 97 if (led < 0 || led >= MAX_LED_DEV) 98 return; 99 100 if (!status_led_init_done) 101 status_led_init (); 102 103 ld = &led_dev[led]; 104 105 ld->state = state; 106 if (state == STATUS_LED_BLINKING) { 107 ld->cnt = 0; /* always start with full period */ 108 state = STATUS_LED_ON; /* always start with LED _ON_ */ 109 } 110 __led_set (ld->mask, state); 111 } 112