diff options
Diffstat (limited to 'board/coral/led.c')
-rw-r--r-- | board/coral/led.c | 325 |
1 files changed, 0 insertions, 325 deletions
diff --git a/board/coral/led.c b/board/coral/led.c deleted file mode 100644 index 2a1e39946c..0000000000 --- a/board/coral/led.c +++ /dev/null @@ -1,325 +0,0 @@ -/* Copyright 2016 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Power and battery LED control for Coral - */ - -#include "battery.h" -#include "charge_state.h" -#include "chipset.h" -#include "ec_commands.h" -#include "extpower.h" -#include "gpio.h" -#include "hooks.h" -#include "host_command.h" -#include "led_common.h" -#include "system.h" -#include "util.h" - -#define LED_ON_LVL 0 -#define LED_OFF_LVL 1 -#define LED_INDEFINITE -1 -#define LED_ONE_SEC (1000 / HOOK_TICK_INTERVAL_MS) -#define LED_CHARGE_LEVEL_1_DEFAULT 100 -#define LED_CHARGE_LEVEL_1_ROBO 5 -#define LED_POWER_BLINK_ON_MSEC 3000 -#define LED_POWER_BLINK_OFF_MSEC 600 -#define LED_POWER_ON_TICKS (LED_POWER_BLINK_ON_MSEC / HOOK_TICK_INTERVAL_MS) -#define LED_POWER_OFF_TICKS (LED_POWER_BLINK_OFF_MSEC / HOOK_TICK_INTERVAL_MS) - -const enum ec_led_id supported_led_ids[] = { - EC_LED_ID_BATTERY_LED}; - -const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); - -#define GPIO_LED_COLOR_1 GPIO_BAT_LED_AMBER -#define GPIO_LED_COLOR_2 GPIO_BAT_LED_BLUE -#define GPIO_LED_COLOR_3 GPIO_POW_LED - -enum led_phase { - LED_PHASE_0, - LED_PHASE_1, - LED_NUM_PHASES -}; - -enum led_color { - LED_OFF, - LED_COLOR_1, - LED_COLOR_2, - LED_COLOR_BOTH, - LED_COLOR_COUNT /* Number of colors, not a color itself */ -}; - -enum led_states { - STATE_CHARGING_LVL_1, - STATE_CHARGING_LVL_2, - STATE_CHARGING_LVL_3, - STATE_DISCHARGE_S0, - STATE_DISCHARGE_S3, - STATE_DISCHARGE_S5, - STATE_BATTERY_ERROR, - STATE_FACTORY_TEST, - LED_NUM_STATES -}; - -struct led_descriptor { - int8_t color; - int8_t time; -}; - -struct led_info { - enum led_states state; - uint8_t charge_lvl_1; - const struct led_descriptor (*state_table)[LED_NUM_PHASES]; - void (*update_power)(void); -}; - -/* - * LED state tables describe the desired LED behavior for a each possible - * state. The LED state is based on both chip power state and the battery charge - * level. The first parameter is the color and the 2nd parameter is the time in - * ticks, where each tick is 200 msec. If the time parameter is set to -1, that - * means it is a non-blinking pattern. - */ - -/* COLOR_1 = Amber, COLOR_2 = Blue */ -static const struct led_descriptor led_default_state_table[][LED_NUM_PHASES] = { - { {LED_COLOR_1, LED_INDEFINITE}, {LED_OFF, LED_INDEFINITE} }, - { {LED_COLOR_2, LED_INDEFINITE}, {LED_COLOR_1, LED_INDEFINITE} }, - { {LED_COLOR_2, LED_INDEFINITE}, {LED_OFF, LED_INDEFINITE} }, - { {LED_COLOR_2, LED_INDEFINITE}, {LED_OFF, LED_INDEFINITE} }, - { {LED_COLOR_1, 1 * LED_ONE_SEC }, {LED_OFF, 3 * LED_ONE_SEC} }, - { {LED_OFF, LED_INDEFINITE}, {LED_OFF, LED_INDEFINITE} }, - { {LED_COLOR_1, 1 * LED_ONE_SEC}, {LED_OFF, 1 * LED_ONE_SEC} }, - { {LED_COLOR_1, 2 * LED_ONE_SEC}, {LED_COLOR_2, 2 * LED_ONE_SEC} }, -}; - -/* COLOR_1 = Green, COLOR_2 = Red */ -static const struct led_descriptor led_robo_state_table[][LED_NUM_PHASES] = { - { {LED_COLOR_2, LED_INDEFINITE}, {LED_OFF, LED_INDEFINITE} }, - { {LED_COLOR_BOTH, LED_INDEFINITE}, {LED_OFF, LED_INDEFINITE} }, - { {LED_COLOR_1, LED_INDEFINITE}, {LED_OFF, LED_INDEFINITE} }, - { {LED_OFF, LED_INDEFINITE}, {LED_OFF, LED_INDEFINITE} }, - { {LED_OFF, LED_INDEFINITE}, {LED_OFF, LED_INDEFINITE} }, - { {LED_OFF, LED_INDEFINITE}, {LED_OFF, LED_INDEFINITE} }, - { {LED_COLOR_2, 1 * LED_ONE_SEC}, {LED_OFF, 1 * LED_ONE_SEC} }, - { {LED_COLOR_2, 2 * LED_ONE_SEC}, {LED_COLOR_1, 2 * LED_ONE_SEC} }, -}; - -static const struct led_descriptor led_nasher_state_table[][LED_NUM_PHASES] = { - { {LED_COLOR_1, LED_INDEFINITE}, {LED_OFF, LED_INDEFINITE} }, - { {LED_COLOR_2, LED_INDEFINITE}, {LED_COLOR_1, LED_INDEFINITE} }, - { {LED_COLOR_2, LED_INDEFINITE}, {LED_OFF, LED_INDEFINITE} }, - { {LED_COLOR_2, LED_INDEFINITE}, {LED_OFF, LED_INDEFINITE} }, - { {LED_COLOR_2, 1 * LED_ONE_SEC}, {LED_OFF, 1 * LED_ONE_SEC} }, - { {LED_OFF, LED_INDEFINITE}, {LED_OFF, LED_INDEFINITE} }, - { {LED_COLOR_1, 1 * LED_ONE_SEC}, {LED_OFF, 1 * LED_ONE_SEC} }, - { {LED_COLOR_1, 2 * LED_ONE_SEC}, {LED_COLOR_2, 2 * LED_ONE_SEC} }, -}; - -static struct led_info led; - -static int led_set_color_battery(enum led_color color) -{ - switch (color) { - case LED_OFF: - gpio_set_level(GPIO_LED_COLOR_1, LED_OFF_LVL); - gpio_set_level(GPIO_LED_COLOR_2, LED_OFF_LVL); - break; - case LED_COLOR_1: - gpio_set_level(GPIO_LED_COLOR_1, LED_ON_LVL); - gpio_set_level(GPIO_LED_COLOR_2, LED_OFF_LVL); - break; - case LED_COLOR_2: - gpio_set_level(GPIO_LED_COLOR_1, LED_OFF_LVL); - gpio_set_level(GPIO_LED_COLOR_2, LED_ON_LVL); - break; - case LED_COLOR_BOTH: - gpio_set_level(GPIO_LED_COLOR_1, LED_ON_LVL); - gpio_set_level(GPIO_LED_COLOR_2, LED_ON_LVL); - break; - default: - return EC_ERROR_UNKNOWN; - } - return EC_SUCCESS; -} - -static void led_set_color_power(int level) -{ - gpio_set_level(GPIO_POWER_LED, level); -} - -void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) -{ - brightness_range[EC_LED_COLOR_BLUE] = 1; - brightness_range[EC_LED_COLOR_AMBER] = 1; - brightness_range[EC_LED_COLOR_RED] = 1; - brightness_range[EC_LED_COLOR_GREEN] = 1; -} - -int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) -{ - if (brightness[EC_LED_COLOR_BLUE] != 0) - led_set_color_battery(LED_COLOR_2); - else if (brightness[EC_LED_COLOR_AMBER] != 0) - led_set_color_battery(LED_COLOR_1); - else if (brightness[EC_LED_COLOR_RED] != 0) - led_set_color_battery(LED_COLOR_2); - else if (brightness[EC_LED_COLOR_GREEN] != 0) - led_set_color_battery(LED_COLOR_1); - else - led_set_color_battery(LED_OFF); - - return EC_SUCCESS; -} - -static enum led_states led_get_state(void) -{ - int charge_lvl; - enum led_states new_state = LED_NUM_STATES; - - switch (charge_get_state()) { - case PWR_STATE_CHARGE: - /* Get percent charge */ - charge_lvl = charge_get_percent(); - /* Determine which charge state to use */ - new_state = charge_lvl <= led.charge_lvl_1 ? - STATE_CHARGING_LVL_1 : STATE_CHARGING_LVL_2; - break; - case PWR_STATE_DISCHARGE_FULL: - if (extpower_is_present()) { - new_state = STATE_CHARGING_LVL_3; - break; - } - /* Intentional fall-through */ - case PWR_STATE_DISCHARGE /* and PWR_STATE_DISCHARGE_FULL */: - if (chipset_in_state(CHIPSET_STATE_ON)) - new_state = STATE_DISCHARGE_S0; - else if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) - new_state = STATE_DISCHARGE_S3; - else - new_state = STATE_DISCHARGE_S5; - break; - case PWR_STATE_ERROR: - new_state = STATE_BATTERY_ERROR; - break; - case PWR_STATE_CHARGE_NEAR_FULL: - new_state = STATE_CHARGING_LVL_3; - break; - case PWR_STATE_IDLE: /* External power connected in IDLE */ - if (charge_get_flags() & CHARGE_FLAG_FORCE_IDLE) - new_state = STATE_FACTORY_TEST; - else - new_state = STATE_DISCHARGE_S0; - break; - default: - /* Other states don't alter LED behavior */ - break; - } - - return new_state; -} - -static void led_update_battery(void) -{ - static int ticks; - int phase; - enum led_states desired_state = led_get_state(); - - /* Get updated state based on power state and charge level */ - if (desired_state < LED_NUM_STATES && desired_state != led.state) { - /* State is changing */ - led.state = desired_state; - /* Reset ticks counter when state changes */ - ticks = 0; - } - - /* - * Determine the which phase of the state table to use. Assume it's - * phase 0. If the time values for both phases of the current state are - * not -1, then this state uses some blinking pattern. The phase is then - * determined by taking the modulo of ticks by the blinking pattern - * period. - */ - phase = 0; - if ((led.state_table[led.state][LED_PHASE_0].time != LED_INDEFINITE) && - (led.state_table[led.state][LED_PHASE_1].time != LED_INDEFINITE)) { - int period; - - period = led.state_table[led.state][LED_PHASE_0].time + - led.state_table[led.state][LED_PHASE_1].time; - if (period) - phase = ticks % period < - led.state_table[led.state][LED_PHASE_0].time ? - 0 : 1; - } - - /* Set the color for the given state and phase */ - led_set_color_battery(led.state_table[led.state][phase].color); - ticks++; -} - -static void led_robo_update_power(void) -{ - int level; - static int ticks; - - if (chipset_in_state(CHIPSET_STATE_ON)) { - /* In S0 power LED is always on */ - level = LED_ON_LVL; - ticks = 0; - } else if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) && - led.state <= STATE_CHARGING_LVL_3) { - int period; - - /* - * If in suspend/standby and the device is charging, then the - * power LED is off for 600 msec, on for 3 seconds. - */ - period = LED_POWER_ON_TICKS + LED_POWER_OFF_TICKS; - level = ticks % period < LED_POWER_OFF_TICKS ? - LED_OFF_LVL : LED_ON_LVL; - ticks++; - } else { - level = LED_OFF_LVL; - ticks = 0; - } - - led_set_color_power(level); -} - -/* Called by hook task every hook tick (200 msec) */ -static void led_update(void) -{ - /* Update battery LED */ - if (led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED)) { - led_update_battery(); - if (led.update_power != NULL) - (*led.update_power)(); - } -} -DECLARE_HOOK(HOOK_TICK, led_update, HOOK_PRIO_DEFAULT); - -static void led_init(void) -{ - int sku = system_get_sku_id(); - - if ((sku >= 70 && sku <= 79) || (sku >= 124 && sku <= 125) || - (sku >= 144 && sku <= 145)) { - led.charge_lvl_1 = LED_CHARGE_LEVEL_1_ROBO; - led.state_table = led_robo_state_table; - led.update_power = led_robo_update_power; - } else if (sku >= 160 && sku <= 166) { - led.charge_lvl_1 = LED_CHARGE_LEVEL_1_DEFAULT; - led.state_table = led_nasher_state_table; - led.update_power = NULL; - } else { - led.charge_lvl_1 = LED_CHARGE_LEVEL_1_DEFAULT; - led.state_table = led_default_state_table; - led.update_power = NULL; - } - led_set_color_battery(LED_OFF); -} -/* Make sure this comes after SKU ID hook */ -DECLARE_HOOK(HOOK_INIT, led_init, HOOK_PRIO_DEFAULT + 2); |