diff options
author | Divya Sasidharan <divya.s.sasidharan@intel.com> | 2018-03-23 22:41:45 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-04-05 15:20:39 -0700 |
commit | 96931840bcf4171a9c44e48d4645b3c7c227014b (patch) | |
tree | 7f9df1d13e85ae7acf7d88acdebff91cfe6b8233 /board/yorp | |
parent | 17536e60cd0dea1b9653ba5bed1a8642f74fca37 (diff) | |
download | chrome-ec-96931840bcf4171a9c44e48d4645b3c7c227014b.tar.gz |
yorp: Enable LED support
BUG=b:74952719
BRANCH=master
TEST=make buildall -j
Change-Id: I49c2f9729425c1c2a08d2a73449b1bfb1912ecc5
Signed-off-by: Divya Sasidharan <divya.s.sasidharan@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/979393
Commit-Ready: Divya S Sasidharan <divya.s.sasidharan@intel.com>
Tested-by: Divya S Sasidharan <divya.s.sasidharan@intel.com>
Reviewed-by: Furquan Shaikh <furquan@chromium.org>
Reviewed-by: Jett Rink <jettrink@chromium.org>
Diffstat (limited to 'board/yorp')
-rw-r--r-- | board/yorp/board.h | 2 | ||||
-rw-r--r-- | board/yorp/build.mk | 3 | ||||
-rw-r--r-- | board/yorp/led.c | 187 |
3 files changed, 184 insertions, 8 deletions
diff --git a/board/yorp/board.h b/board/yorp/board.h index e5d6e4299a..9869dcc38d 100644 --- a/board/yorp/board.h +++ b/board/yorp/board.h @@ -43,6 +43,8 @@ #define CONFIG_CMD_ACCELS #define CONFIG_CMD_ACCEL_INFO +#define CONFIG_LED_COMMON + /* Charger Configuration */ #define CONFIG_CHARGE_MANAGER #define CONFIG_CHARGE_RAMP_HW diff --git a/board/yorp/build.mk b/board/yorp/build.mk index 4a46b8fcf7..7f3e073a23 100644 --- a/board/yorp/build.mk +++ b/board/yorp/build.mk @@ -11,7 +11,6 @@ CHIP_FAMILY:=npcx7 CHIP_VARIANT:=npcx7m6f BASEBOARD:=octopus -board-y=board.o +board-y=board.o led.o board-$(CONFIG_BATTERY_SMART)+=battery.o -board-y+=led.o board-$(CONFIG_USB_POWER_DELIVERY)+=usb_pd_policy.o diff --git a/board/yorp/led.c b/board/yorp/led.c index 164a5c600b..2ad61775f8 100644 --- a/board/yorp/led.c +++ b/board/yorp/led.c @@ -5,18 +5,193 @@ * Power and battery LED control for Yorp */ +#include "battery.h" +#include "charge_state.h" +#include "chipset.h" +#include "ec_commands.h" +#include "extpower.h" #include "gpio.h" #include "hooks.h" +#include "led_common.h" +#include "system.h" +#include "util.h" -static void led_init(void) +#define LED_OFF_LVL 1 +#define LED_ON_LVL 0 +#define LED_INDEFINITE UINT8_MAX +#define LED_ONE_SEC (1000 / HOOK_TICK_INTERVAL_MS) +#define STATE_DEFAULT LED_NUM_STATES + +enum led_phase { + LED_PHASE_0, + LED_PHASE_1, + LED_NUM_PHASES +}; + +enum led_color { + LED_OFF = 0, + LED_COLOR_BLUE, + LED_COLOR_AMBER, + LED_COLOR_COUNT /* Max colors */ +}; + +enum led_states { + STATE_CHARGING, + STATE_CHARGING_FULLY_CHARGED, + STATE_DISCHARGE_S0, + STATE_DISCHARGE_S3, + STATE_DISCHARGE_S5, + STATE_BATTERY_ERROR, + LED_NUM_STATES +}; + +struct led_descriptor { + int8_t color; + uint8_t time; +}; + +/* Yorp: Note there is only LED for charge / power */ +static const struct led_descriptor + led_state_table[LED_NUM_STATES][LED_NUM_PHASES] = { + [STATE_CHARGING] = { {LED_COLOR_AMBER, LED_INDEFINITE} }, + [STATE_CHARGING_FULLY_CHARGED] = { {LED_COLOR_BLUE, LED_INDEFINITE} }, + [STATE_DISCHARGE_S0] = { {LED_COLOR_BLUE, LED_INDEFINITE} }, + [STATE_DISCHARGE_S3] = { {LED_COLOR_AMBER, 4 * LED_ONE_SEC}, + {LED_OFF, 1 * LED_ONE_SEC} }, + [STATE_DISCHARGE_S5] = { {LED_OFF, LED_INDEFINITE } }, + [STATE_BATTERY_ERROR] = { {LED_COLOR_BLUE, 2 * LED_ONE_SEC}, + {LED_COLOR_AMBER, 2 * LED_ONE_SEC} }, +}; + +const enum ec_led_id supported_led_ids[] = { EC_LED_ID_BATTERY_LED }; + +const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); + +static void led_set_color_battery(enum led_color color) +{ + switch (color) { + case LED_COLOR_BLUE: + gpio_set_level(GPIO_BAT_LED_BLUE_L, LED_ON_LVL); + gpio_set_level(GPIO_BAT_LED_ORANGE_L, LED_OFF_LVL); + break; + case LED_COLOR_AMBER: + gpio_set_level(GPIO_BAT_LED_BLUE_L, LED_OFF_LVL); + gpio_set_level(GPIO_BAT_LED_ORANGE_L, LED_ON_LVL); + break; + default: /* LED_OFF and other unsupported colors */ + gpio_set_level(GPIO_BAT_LED_BLUE_L, LED_OFF_LVL); + gpio_set_level(GPIO_BAT_LED_ORANGE_L, LED_OFF_LVL); + break; + } +} + +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; +} + +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_BLUE); + else if (brightness[EC_LED_COLOR_AMBER] != 0) + led_set_color_battery(LED_COLOR_AMBER); + else + led_set_color_battery(LED_OFF); + + return EC_SUCCESS; +} + +static enum led_states led_get_state(void) { + enum led_states new_state = LED_NUM_STATES; + + switch (charge_get_state()) { + case PWR_STATE_CHARGE: + new_state = STATE_CHARGING; + break; + case PWR_STATE_DISCHARGE_FULL: + if (extpower_is_present()) { + new_state = STATE_CHARGING_FULLY_CHARGED; + 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_FULLY_CHARGED; + break; + case PWR_STATE_IDLE: /* External power connected in IDLE */ + 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 uint8_t ticks, period; + static int led_state = STATE_DEFAULT; + int phase; + enum led_states desired_state = led_get_state(); + + /* Get updated state based on power state and charge level */ + if (desired_state != led_state) { + /* State is changing */ + led_state = desired_state; + /* Reset ticks and period when state changes */ + ticks = 0; + period = led_state_table[led_state][LED_PHASE_0].time + + led_state_table[led_state][LED_PHASE_1].time; + } else if (period == UINT8_MAX) + /* + * No change of state so no LED change needed + * for indefinite phase 0. + */ + return; + + if (led_state == STATE_DEFAULT) /* No change needed */ + return; + /* - * Temporary hack to turn on blue led to indicate that EC is up and - * running. This can be removed after adding proper LED support - * (b/74952719). + * Determine which phase of the state table to use. The phase is + * determined if it falls within first phase time duration. */ - gpio_set_level(GPIO_BAT_LED_BLUE_L, 0); - gpio_set_level(GPIO_BAT_LED_ORANGE_L, 1); + phase = ticks < led_state_table[led_state][LED_PHASE_0].time ? 0 : 1; + ticks = (ticks + 1) % period; + + /* Set the color for the given state and phase */ + led_set_color_battery(led_state_table[led_state][phase].color); } +static void led_init(void) +{ + led_set_color_battery(LED_OFF); +} DECLARE_HOOK(HOOK_INIT, led_init, HOOK_PRIO_DEFAULT); + +/* Called by hook task every hook tick (200 msec) */ +static void led_update(void) +{ + /* + * Yorp only has one LED, so overload it to act as both + * power LED and battery LED. + */ + if (led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED)) + led_update_battery(); +} +DECLARE_HOOK(HOOK_TICK, led_update, HOOK_PRIO_DEFAULT); |