uboot/drivers/misc/status_led.c
<<
>>
Prefs
   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
  22typedef struct {
  23        led_id_t mask;
  24        int state;
  25        int period;
  26        int cnt;
  27} led_dev_t;
  28
  29led_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
  60static int status_led_init_done = 0;
  61
  62static 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
  72void 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
  93void 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