From 77f68f204f2e27f7ed7e80bcdd1e36280bbcff83 Mon Sep 17 00:00:00 2001 From: Mike Hsieh Date: Mon, 3 Aug 2015 19:15:41 +0800 Subject: glados: Implement LED functionality on EC Implement LED control for glados for both red and green LED. BUG=chrome-os-partner:40848 BRANCH=none TEST=Manually tested on glados with following commands: ectool led battery red ectool led battery green ectool led battery off Change-Id: I1b4f8c8c8f26779a11185ea8bbc6536d1d7f97b1 Signed-off-by: Mike Hsieh Reviewed-on: https://chromium-review.googlesource.com/289439 Reviewed-by: Shawn N --- board/glados/board.h | 4 +- board/glados/led.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 140 insertions(+), 3 deletions(-) diff --git a/board/glados/board.h b/board/glados/board.h index ad5d8d35ee..bdbb7cb9d9 100644 --- a/board/glados/board.h +++ b/board/glados/board.h @@ -88,7 +88,9 @@ #define WIRELESS_GPIO_WLAN GPIO_WLAN_OFF_L #define WIRELESS_GPIO_WLAN_POWER GPIO_PP3300_WLAN_EN - +/* LED signals */ +#define GPIO_BAT_LED_RED GPIO_CHARGE_LED_1 +#define GPIO_BAT_LED_GREEN GPIO_CHARGE_LED_2 /* I2C ports */ #ifdef GLADOS_BOARD_V1 diff --git a/board/glados/led.c b/board/glados/led.c index a34cbb69fe..3d2300fddd 100644 --- a/board/glados/led.c +++ b/board/glados/led.c @@ -15,16 +15,151 @@ #include "led_common.h" #include "util.h" +#define BAT_LED_ON 1 +#define BAT_LED_OFF 0 + +#define CRITICAL_LOW_BATTERY_PERCENTAGE 3 +#define LOW_BATTERY_PERCENTAGE 10 + +#define LED_TOTAL_4SECS_TICKS 16 +#define LED_TOTAL_2SECS_TICKS 8 +#define LED_ON_1SEC_TICKS 4 +#define LED_ON_2SECS_TICKS 8 + const enum ec_led_id supported_led_ids[] = { - EC_LED_ID_POWER_LED, EC_LED_ID_BATTERY_LED}; + EC_LED_ID_BATTERY_LED}; const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); -int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) +enum led_color { + LED_OFF = 0, + LED_RED, + LED_AMBER, + LED_GREEN, + LED_COLOR_COUNT /* Number of colors, not a color itself */ +}; + +static int bat_led_set_color(enum led_color color) { + switch (color) { + case LED_OFF: + gpio_set_level(GPIO_BAT_LED_RED, BAT_LED_OFF); + gpio_set_level(GPIO_BAT_LED_GREEN, BAT_LED_OFF); + break; + case LED_RED: + gpio_set_level(GPIO_BAT_LED_RED, BAT_LED_ON); + gpio_set_level(GPIO_BAT_LED_GREEN, BAT_LED_OFF); + break; + case LED_AMBER: + gpio_set_level(GPIO_BAT_LED_RED, BAT_LED_ON); + gpio_set_level(GPIO_BAT_LED_GREEN, BAT_LED_ON); + break; + case LED_GREEN: + gpio_set_level(GPIO_BAT_LED_RED, BAT_LED_OFF); + gpio_set_level(GPIO_BAT_LED_GREEN, BAT_LED_ON); + break; + default: + return EC_ERROR_UNKNOWN; + } return EC_SUCCESS; } void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) { + brightness_range[EC_LED_COLOR_RED] = 1; + brightness_range[EC_LED_COLOR_GREEN] = 1; +} + +static int glados_led_set_color_battery(enum led_color color) +{ + return bat_led_set_color(color); +} + +static int glados_led_set_color(enum ec_led_id led_id, enum led_color color) +{ + int rv; + + led_auto_control(led_id, 0); + switch (led_id) { + case EC_LED_ID_BATTERY_LED: + rv = glados_led_set_color_battery(color); + break; + default: + return EC_ERROR_UNKNOWN; + } + return rv; +} + +int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) +{ + if (brightness[EC_LED_COLOR_RED] != 0 && + brightness[EC_LED_COLOR_GREEN] != 0) + glados_led_set_color(led_id, LED_AMBER); + else if (brightness[EC_LED_COLOR_RED] != 0) + glados_led_set_color(led_id, LED_RED); + else if (brightness[EC_LED_COLOR_GREEN] != 0) + glados_led_set_color(led_id, LED_GREEN); + else + glados_led_set_color(led_id, LED_OFF); + + return EC_SUCCESS; +} + +static void glados_led_set_battery(void) +{ + static int battery_ticks; + uint32_t chflags = charge_get_flags(); + + battery_ticks++; + + /* BAT LED behavior: + * Same as the chromeos spec + * Green/Amber for CHARGE_FLAG_FORCE_IDLE + */ + switch (charge_get_state()) { + case PWR_STATE_CHARGE: + glados_led_set_color_battery(LED_AMBER); + break; + case PWR_STATE_DISCHARGE: + /* Less than 3%, blink one second every two second */ + if (charge_get_percent() < CRITICAL_LOW_BATTERY_PERCENTAGE) + glados_led_set_color_battery( + (battery_ticks % LED_TOTAL_2SECS_TICKS < + LED_ON_1SEC_TICKS) ? LED_AMBER : LED_OFF); + /* Less than 10%, blink one second every four seconds */ + else if (charge_get_percent() < LOW_BATTERY_PERCENTAGE) + glados_led_set_color_battery( + (battery_ticks % LED_TOTAL_4SECS_TICKS < + LED_ON_1SEC_TICKS) ? LED_AMBER : LED_OFF); + else + glados_led_set_color_battery(LED_OFF); + break; + case PWR_STATE_ERROR: + glados_led_set_color_battery( + (battery_ticks % LED_TOTAL_2SECS_TICKS < + LED_ON_1SEC_TICKS) ? LED_RED : LED_OFF); + break; + case PWR_STATE_CHARGE_NEAR_FULL: + glados_led_set_color_battery(LED_GREEN); + break; + case PWR_STATE_IDLE: /* External power connected in IDLE */ + if (chflags & CHARGE_FLAG_FORCE_IDLE) + glados_led_set_color_battery( + (battery_ticks % LED_TOTAL_4SECS_TICKS < + LED_ON_2SECS_TICKS) ? LED_GREEN : LED_AMBER); + else + glados_led_set_color_battery(LED_GREEN); + break; + default: + /* Other states don't alter LED behavior */ + break; + } +} + +/** * Called by hook task every 1 sec */ +static void led_second(void) +{ + if (led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED)) + glados_led_set_battery(); } +DECLARE_HOOK(HOOK_SECOND, led_second, HOOK_PRIO_DEFAULT); -- cgit v1.2.1