diff options
author | Josh Tsai <josh_tsai@compal.corp-partner.google.com> | 2021-08-13 14:12:36 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-08-24 20:36:46 +0000 |
commit | 6b25cf6a373f3b4eac5a380a4deae9cab203f258 (patch) | |
tree | 0977b703c767a6668a29eb59132eeb769350e544 | |
parent | 988e681ee37c6cf137db2d58f94a03ca73dcf014 (diff) | |
download | chrome-ec-6b25cf6a373f3b4eac5a380a4deae9cab203f258.tar.gz |
Corori: modified power and battery LED behavior
Add Battery control for Corori
Power LED
System S0: White.
System S0ix: Blinking White. (1 sec on, 3 sec off)
System S5/G3: Off.
Battery LED
DC mode:
System S0: Off.
System S5/G3: Off.
AC mode:
Charging(0%-94%): Amber.
Full charged: White.
Battery low (OS 0%-10%)
System S0: Blinking Amber (1 sec on, 3 sec off)
System S0ix: Blinking White (1 sec on, 3 sec off)
System S5/G3: Off
Battery error
System S0: Blinking Amber (1 sec on, 1 sec off)
System S0ix: Blinking White (1 sec on, 3 sec off)
System S5/G3: Off
BUG=b:196723817
BRANCH=keeby
TEST=make BOARD=corori, test on keeby MB
Signed-off-by: Josh Tsai <josh_tsai@compal.corp-partner.google.com>
Change-Id: Iab747e29c85354cabb43759bfc7181717ea2ffe8
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3098123
Reviewed-by: Elmo Lan <elmo_lan@compal.corp-partner.google.com>
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Commit-Queue: Aseda Aboagye <aaboagye@chromium.org>
-rw-r--r-- | board/corori/board.h | 6 | ||||
-rw-r--r-- | board/corori/gpio.inc | 5 | ||||
-rw-r--r-- | board/corori/led.c | 196 |
3 files changed, 178 insertions, 29 deletions
diff --git a/board/corori/board.h b/board/corori/board.h index a48207f2eb..23377c18f6 100644 --- a/board/corori/board.h +++ b/board/corori/board.h @@ -34,7 +34,11 @@ #define CONFIG_PWM_KBLIGHT /* LED defines */ -#define CONFIG_LED_ONOFF_STATES +#define CONFIG_LED_COMMON +#define CONFIG_BATTERY_LEVEL_NEAR_FULL 94 +#define GPIO_BAT_LED_AMBER GPIO_LED_Y_ODL +#define GPIO_PWR_LED_WHITE GPIO_LED_W_ODL + /* PWM */ #define CONFIG_PWM diff --git a/board/corori/gpio.inc b/board/corori/gpio.inc index feaa742d1e..1abed874a9 100644 --- a/board/corori/gpio.inc +++ b/board/corori/gpio.inc @@ -63,9 +63,8 @@ GPIO(EN_BL_OD, PIN(D, 3), GPIO_ODR_LOW) GPIO(EC_CBI_WP, PIN(E, 5), GPIO_OUT_LOW) /* LED */ -GPIO(LED_B_ODL, PIN(C, 2), GPIO_OUT_HIGH) /* PWM_CH_LED2_BLUE */ -GPIO(LED_G_ODL, PIN(C, 3), GPIO_OUT_HIGH) /* PWM_CH_LED1_GREEN */ -GPIO(LED_R_ODL, PIN(C, 4), GPIO_OUT_HIGH) /* PWM_CH_LED2_ORANGE */ +GPIO(LED_W_ODL, PIN(C, 3), GPIO_OUT_HIGH) /* POWER LED */ +GPIO(LED_Y_ODL, PIN(C, 4), GPIO_OUT_HIGH) /* BATTERY LED */ /* Power Sequencing */ GPIO(EC_AP_PSYS, PIN(B, 7), GPIO_OUT_LOW) diff --git a/board/corori/led.c b/board/corori/led.c index cfe6f9eb6a..96a43caa76 100644 --- a/board/corori/led.c +++ b/board/corori/led.c @@ -5,31 +5,60 @@ * Power and battery LED control for lalala */ +#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 "led_onoff_states.h" -#include "chipset.h" +#include "system.h" +#include "util.h" #define LED_ON_LVL 0 #define LED_OFF_LVL 1 +#define LED_INDEFINITE UINT8_MAX +#define LED_ONE_SEC (1000 / HOOK_TICK_INTERVAL_MS) +#define LED_OFF EC_LED_COLOR_COUNT + +struct led_descriptor { + enum ec_led_colors color; + uint8_t time; +}; -__override const int led_charge_lvl_1 = 5; +enum led_phase { + LED_PHASE_0, + LED_PHASE_1, + LED_NUM_PHASES +}; -__override const int led_charge_lvl_2 = 95; +enum led_states { + STATE_CHARGING, + STATE_CHARGING_FULL_CHARGE, + STATE_DISCHARGE_S0, + STATE_DISCHARGE_S0_BAT_LOW, + STATE_BATTERY_S0_ERROR, + STATE_BATTERY_S3_BLINK, + STATE_BATTERY_S5_OFF, + STATE_FACTORY_TEST, + LED_NUM_STATES +}; -__override struct led_descriptor +static const struct led_descriptor led_bat_state_table[LED_NUM_STATES][LED_NUM_PHASES] = { - [STATE_CHARGING_LVL_1] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} }, - [STATE_CHARGING_LVL_2] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} }, - [STATE_CHARGING_FULL_CHARGE] = {{EC_LED_COLOR_BLUE, LED_INDEFINITE} }, - [STATE_DISCHARGE_S0] = {{EC_LED_COLOR_BLUE, LED_INDEFINITE} }, - [STATE_DISCHARGE_S3] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC}, - {LED_OFF, 3 * LED_ONE_SEC} }, - [STATE_DISCHARGE_S5] = {{LED_OFF, LED_INDEFINITE} }, - [STATE_BATTERY_ERROR] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC}, + [STATE_CHARGING] = {{EC_LED_COLOR_AMBER, LED_INDEFINITE} }, + [STATE_CHARGING_FULL_CHARGE] = {{EC_LED_COLOR_WHITE, LED_INDEFINITE} }, + [STATE_DISCHARGE_S0] = {{EC_LED_COLOR_WHITE, LED_INDEFINITE} }, + [STATE_DISCHARGE_S0_BAT_LOW] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC}, + {LED_OFF, 3 * LED_ONE_SEC} }, + [STATE_BATTERY_S0_ERROR] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC}, {LED_OFF, 1 * LED_ONE_SEC} }, - [STATE_FACTORY_TEST] = {{EC_LED_COLOR_BLUE, 2 * LED_ONE_SEC}, + [STATE_BATTERY_S3_BLINK] = {{EC_LED_COLOR_WHITE, 1 * LED_ONE_SEC}, + {LED_OFF, 3 * LED_ONE_SEC} }, + [STATE_BATTERY_S5_OFF] = {{LED_OFF, LED_INDEFINITE} }, + [STATE_FACTORY_TEST] = {{EC_LED_COLOR_WHITE, 2 * LED_ONE_SEC}, {EC_LED_COLOR_AMBER, 2 * LED_ONE_SEC} }, }; @@ -39,20 +68,26 @@ const enum ec_led_id supported_led_ids[] = { const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); -__override void led_set_color_battery(enum ec_led_colors color) + +static int led_get_charge_percent(void) +{ + return DIV_ROUND_NEAREST(charge_get_display_charge(), 10); +} + +void led_set_color_battery(enum ec_led_colors color) { switch (color) { case EC_LED_COLOR_AMBER: - gpio_set_level(GPIO_LED_R_ODL, LED_ON_LVL); - gpio_set_level(GPIO_LED_B_ODL, LED_OFF_LVL); + gpio_set_level(GPIO_BAT_LED_AMBER, LED_ON_LVL); + gpio_set_level(GPIO_PWR_LED_WHITE, LED_OFF_LVL); break; - case EC_LED_COLOR_BLUE: - gpio_set_level(GPIO_LED_R_ODL, LED_OFF_LVL); - gpio_set_level(GPIO_LED_B_ODL, LED_ON_LVL); + case EC_LED_COLOR_WHITE: + gpio_set_level(GPIO_BAT_LED_AMBER, LED_OFF_LVL); + gpio_set_level(GPIO_PWR_LED_WHITE, LED_ON_LVL); break; default: /* LED_OFF and other unsupported colors */ - gpio_set_level(GPIO_LED_R_ODL, LED_OFF_LVL); - gpio_set_level(GPIO_LED_B_ODL, LED_OFF_LVL); + gpio_set_level(GPIO_BAT_LED_AMBER, LED_OFF_LVL); + gpio_set_level(GPIO_PWR_LED_WHITE, LED_OFF_LVL); break; } } @@ -61,15 +96,15 @@ void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) { if (led_id == EC_LED_ID_BATTERY_LED) { brightness_range[EC_LED_COLOR_AMBER] = 1; - brightness_range[EC_LED_COLOR_BLUE] = 1; + brightness_range[EC_LED_COLOR_WHITE] = 1; } } int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) { if (led_id == EC_LED_ID_BATTERY_LED) { - if (brightness[EC_LED_COLOR_BLUE] != 0) - led_set_color_battery(EC_LED_COLOR_BLUE); + if (brightness[EC_LED_COLOR_WHITE] != 0) + led_set_color_battery(EC_LED_COLOR_WHITE); else if (brightness[EC_LED_COLOR_AMBER] != 0) led_set_color_battery(EC_LED_COLOR_AMBER); else @@ -77,3 +112,114 @@ int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) } return EC_SUCCESS; } + +/* Custom led on off states control */ +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_FULL_CHARGE; + break; + } + /* Intentional fall-through */ + case PWR_STATE_DISCHARGE /* and PWR_STATE_DISCHARGE_FULL */: + if (chipset_in_state(CHIPSET_STATE_ON)) + new_state = (led_get_charge_percent() < 10) ? + STATE_DISCHARGE_S0_BAT_LOW : STATE_DISCHARGE_S0; + else if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) + new_state = STATE_BATTERY_S3_BLINK; + else + new_state = STATE_BATTERY_S5_OFF; + break; + case PWR_STATE_ERROR: + if (chipset_in_state(CHIPSET_STATE_ON)) + new_state = STATE_BATTERY_S0_ERROR; + else if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) + new_state = STATE_BATTERY_S3_BLINK; + else + new_state = STATE_BATTERY_S5_OFF; + break; + case PWR_STATE_CHARGE_NEAR_FULL: + new_state = STATE_CHARGING_FULL_CHARGE; + 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 uint8_t ticks, period; + static int led_state = LED_NUM_STATES; + int phase; + enum led_states desired_state = led_get_state(); + + /* + * We always need to check the current state since the value could + * have been manually overwritten. If we're in a new valid state, + * update our ticks and period info. If our new state isn't defined, + * continue using the previous one. + */ + if (desired_state != led_state && desired_state < LED_NUM_STATES) { + /* State is changing */ + led_state = desired_state; + /* Reset ticks and period when state changes */ + ticks = 0; + + period = led_bat_state_table[led_state][LED_PHASE_0].time + + led_bat_state_table[led_state][LED_PHASE_1].time; + + } + + /* If this state is undefined, turn the LED off */ + if (period == 0) { + led_set_color_battery(LED_OFF); + return; + } + + /* + * Determine which phase of the state table to use. The phase is + * determined if it falls within first phase time duration. + */ + phase = ticks < led_bat_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_bat_state_table[led_state][phase].color); +} + +static void led_init(void) +{ + /* If battery LED is enabled, set it to "off" to start with */ + if (led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED)) + 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) +{ + /* + * If battery LED is enabled, set its state based on our power and + * charge + */ + if (led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED)) + led_update_battery(); +} +DECLARE_HOOK(HOOK_TICK, led_update, HOOK_PRIO_DEFAULT); |