| /* |
| * LED trigger support for barebox |
| * |
| * (C) Copyright 2010 Sascha Hauer, Pengutronix |
| * |
| * See file CREDITS for list of people who contributed to this |
| * project. |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU General Public License as |
| * published by the Free Software Foundation; either version 2 of |
| * the License, or (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
| * MA 02111-1307 USA |
| */ |
| |
| #include <common.h> |
| #include <poller.h> |
| #include <errno.h> |
| #include <clock.h> |
| #include <led.h> |
| #include <init.h> |
| |
| /** |
| * @file |
| * @brief LED trigger framework |
| * |
| * This file contains triggers which can be associated to LEDs. |
| * |
| * With this framework LEDs can be associated to different events. |
| * An event can be a heartbeat, network activity or panic. |
| * led_trigger() is the central function which is called in the |
| * different barebox frameworks to trigger an event. |
| * |
| * currently there are the following triggers are defined: |
| * |
| * led_trigger_panic: triggered in panic() |
| * led_trigger_heartbeat: shows the heartbeat of barebox. Blinks as long |
| * barebox is up and running. |
| * led_trigger_net_rx: Triggered during network packet reception |
| * led_trigger_net_tx: Triggered during network packet transmission |
| * led_trigger_net_txrx: combination of the two above |
| */ |
| |
| struct led_trigger_struct { |
| struct led *led; |
| uint64_t flash_start; |
| }; |
| |
| static struct led_trigger_struct triggers[LED_TRIGGER_MAX]; |
| |
| static void trigger_func(struct poller_struct *poller) |
| { |
| int i; |
| |
| for (i = 0; i < LED_TRIGGER_MAX; i++) { |
| if (triggers[i].led && |
| triggers[i].flash_start && |
| is_timeout(triggers[i].flash_start, 200 * MSECOND)) { |
| led_set(triggers[i].led, 0); |
| } |
| } |
| |
| if (triggers[LED_TRIGGER_HEARTBEAT].led && |
| is_timeout(triggers[LED_TRIGGER_HEARTBEAT].flash_start, SECOND)) |
| led_trigger(LED_TRIGGER_HEARTBEAT, TRIGGER_FLASH); |
| } |
| |
| static struct poller_struct trigger_poller = { |
| .func = trigger_func, |
| }; |
| |
| /** |
| * led_trigger - triggers a trigger |
| * @param trigger The trigger to enable/disable |
| * @param enable true if enable |
| * |
| * Enable/disable a LED for a given trigger. |
| */ |
| void led_trigger(enum led_trigger trigger, enum trigger_type type) |
| { |
| if (trigger >= LED_TRIGGER_MAX) |
| return; |
| if (!triggers[trigger].led) |
| return; |
| |
| if (type == TRIGGER_FLASH) { |
| if (is_timeout(triggers[trigger].flash_start, 400 * MSECOND)) { |
| led_set(triggers[trigger].led, 1); |
| triggers[trigger].flash_start = get_time_ns(); |
| } |
| return; |
| } |
| |
| led_set(triggers[trigger].led, type == TRIGGER_ENABLE ? 1 : 0); |
| } |
| |
| /** |
| * led_set_trigger - set the LED for a trigger |
| * @param trigger The trigger to set a LED for |
| * @param led The LED |
| * |
| * This function associates a trigger with a LED. Pass led = NULL |
| * to disable a trigger |
| */ |
| int led_set_trigger(enum led_trigger trigger, struct led *led) |
| { |
| int i; |
| |
| if (trigger >= LED_TRIGGER_MAX) |
| return -EINVAL; |
| |
| if (led) |
| for (i = 0; i < LED_TRIGGER_MAX; i++) |
| if (triggers[i].led == led) |
| return -EBUSY; |
| |
| if (triggers[trigger].led && !led) |
| led_set(triggers[trigger].led, 0); |
| |
| triggers[trigger].led = led; |
| |
| return 0; |
| } |
| |
| /** |
| * led_get_trigger - get the LED for a trigger |
| * @param trigger The trigger to set a LED for |
| * |
| * return the LED number of a trigger. |
| */ |
| int led_get_trigger(enum led_trigger trigger) |
| { |
| if (trigger >= LED_TRIGGER_MAX) |
| return -EINVAL; |
| if (!triggers[trigger].led) |
| return -ENODEV; |
| return led_get_number(triggers[trigger].led); |
| } |
| |
| int trigger_init(void) |
| { |
| return poller_register(&trigger_poller); |
| } |
| late_initcall(trigger_init); |