diff options
Diffstat (limited to 'board/cherry/led.c')
-rw-r--r-- | board/cherry/led.c | 216 |
1 files changed, 65 insertions, 151 deletions
diff --git a/board/cherry/led.c b/board/cherry/led.c index 0a58cddd64..c06fdef0cb 100644 --- a/board/cherry/led.c +++ b/board/cherry/led.c @@ -1,39 +1,55 @@ /* Copyright 2021 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 Asurada */ -#include "charge_manager.h" -#include "charge_state.h" -#include "common.h" -#include "console.h" -#include "driver/bc12/mt6360.h" -#include "hooks.h" + +#include "ec_commands.h" +#include "gpio.h" #include "led_common.h" -#include "pwm.h" -#include "stdbool.h" -#include "util.h" +#include "led_onoff_states.h" +#include "chipset.h" +#include "driver/bc12/mt6360.h" -#define CPRINTS(format, args...) cprints(CC_PWM, format, ## args) +const int led_charge_lvl_1 = 5; +const int led_charge_lvl_2 = 95; + +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_WHITE, LED_INDEFINITE} }, + [STATE_DISCHARGE_S0] = {{LED_OFF, LED_INDEFINITE} }, + [STATE_DISCHARGE_S0_BAT_LOW] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC}, + {LED_OFF, 3 * LED_ONE_SEC} }, + [STATE_DISCHARGE_S3] = {{LED_OFF, LED_INDEFINITE} }, + [STATE_DISCHARGE_S5] = {{LED_OFF, LED_INDEFINITE} }, + [STATE_BATTERY_ERROR] = {{EC_LED_COLOR_AMBER, 1 * LED_ONE_SEC}, + {LED_OFF, 1 * LED_ONE_SEC} }, + [STATE_FACTORY_TEST] = {{EC_LED_COLOR_WHITE, 2 * LED_ONE_SEC}, + {EC_LED_COLOR_AMBER, 2 * LED_ONE_SEC} }, +}; -#define LED_OFF EC_LED_COLOR_COUNT +const struct led_descriptor + led_pwr_state_table[PWR_LED_NUM_STATES][LED_NUM_PHASES] = { + [PWR_LED_STATE_ON] = {{EC_LED_COLOR_WHITE, LED_INDEFINITE} }, + [PWR_LED_STATE_SUSPEND_AC] = {{EC_LED_COLOR_WHITE, 1 * LED_ONE_SEC}, + {LED_OFF, 3 * LED_ONE_SEC} }, + [PWR_LED_STATE_SUSPEND_NO_AC] = {{EC_LED_COLOR_WHITE, 1 * LED_ONE_SEC}, + {LED_OFF, 3 * LED_ONE_SEC} }, + [PWR_LED_STATE_OFF] = {{LED_OFF, LED_INDEFINITE} }, +}; -const enum ec_led_id supported_led_ids[] = { - /* Main LED */ - EC_LED_ID_LEFT_LED, - EC_LED_ID_RIGHT_LED, - /* Not used, give them some random name for testing */ +const enum ec_led_id supported_led_ids[] = { + EC_LED_ID_BATTERY_LED, EC_LED_ID_POWER_LED, - EC_LED_ID_BATTERY_LED }; + const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); -static void led_set_color_left(enum ec_led_colors color, int duty) +void led_set_color_battery(enum ec_led_colors color) { - mt6360_led_set_brightness(MT6360_LED_RGB2, duty); - mt6360_led_set_brightness(MT6360_LED_RGB3, duty); + mt6360_led_set_brightness(MT6360_LED_RGB2, 50); + mt6360_led_set_brightness(MT6360_LED_RGB3, 50); switch (color) { case EC_LED_COLOR_AMBER: @@ -51,155 +67,53 @@ static void led_set_color_left(enum ec_led_colors color, int duty) } } -static void led_set_color_right(enum ec_led_colors color, int duty) -{ - pwm_set_duty(PWM_CH_LED2, duty); - pwm_set_duty(PWM_CH_LED3, duty); - - switch (color) { - case EC_LED_COLOR_AMBER: - pwm_enable(PWM_CH_LED2, 0); - pwm_enable(PWM_CH_LED3, 1); - break; - case EC_LED_COLOR_WHITE: - pwm_enable(PWM_CH_LED2, 1); - pwm_enable(PWM_CH_LED3, 0); - break; - default: /* LED_OFF and other unsupported colors */ - pwm_enable(PWM_CH_LED2, 0); - pwm_enable(PWM_CH_LED3, 0); - break; - } -} - -static void led_set_color_power(enum ec_led_colors color, int duty) -{ - pwm_set_duty(PWM_CH_LED1, duty); - pwm_enable(PWM_CH_LED1, color == EC_LED_COLOR_WHITE); -} - -static void led_set_color_battery(enum ec_led_colors color, int duty) +void led_set_color_power(enum ec_led_colors color) { - mt6360_led_set_brightness(MT6360_LED_RGB1, duty); + mt6360_led_set_brightness(MT6360_LED_RGB1, 1); mt6360_led_enable(MT6360_LED_RGB1, color == EC_LED_COLOR_WHITE); } -static enum ec_error_list set_color(enum ec_led_id led_id, - enum ec_led_colors color, - int duty) -{ - switch (led_id) { - case EC_LED_ID_LEFT_LED: - led_set_color_left(color, duty); - return EC_SUCCESS; - case EC_LED_ID_RIGHT_LED: - led_set_color_right(color, duty); - return EC_SUCCESS; - case EC_LED_ID_POWER_LED: - led_set_color_power(color, duty); - return EC_SUCCESS; - case EC_LED_ID_BATTERY_LED: - led_set_color_battery(color, duty); - return EC_SUCCESS; - default: - return EC_ERROR_INVAL; - } -} - void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) { - switch (led_id) { - case EC_LED_ID_LEFT_LED: + if (led_id == EC_LED_ID_BATTERY_LED) { brightness_range[EC_LED_COLOR_AMBER] = - MT6360_LED_BRIGHTNESS_MAX; + MT6360_LED_BRIGHTNESS_MAX; brightness_range[EC_LED_COLOR_WHITE] = - MT6360_LED_BRIGHTNESS_MAX; - break; - case EC_LED_ID_RIGHT_LED: - brightness_range[EC_LED_COLOR_AMBER] = 100; - brightness_range[EC_LED_COLOR_WHITE] = 100; - break; - case EC_LED_ID_POWER_LED: - brightness_range[EC_LED_COLOR_WHITE] = 100; - break; - case EC_LED_ID_BATTERY_LED: + MT6360_LED_BRIGHTNESS_MAX; + } else if (led_id == EC_LED_ID_POWER_LED) { brightness_range[EC_LED_COLOR_WHITE] = - MT6360_LED_BRIGHTNESS_MAX; - break; - default: - break; + MT6360_LED_BRIGHTNESS_MAX; } } int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness) { - if (brightness[EC_LED_COLOR_AMBER]) - return set_color(led_id, EC_LED_COLOR_AMBER, - brightness[EC_LED_COLOR_AMBER]); - if (brightness[EC_LED_COLOR_WHITE]) - return set_color(led_id, EC_LED_COLOR_WHITE, - brightness[EC_LED_COLOR_WHITE]); + if (led_id == EC_LED_ID_BATTERY_LED) { + if (brightness[EC_LED_COLOR_AMBER] != 0) + led_set_color_battery(EC_LED_COLOR_AMBER); + else if (brightness[EC_LED_COLOR_WHITE] != 0) + led_set_color_battery(EC_LED_COLOR_WHITE); + else + led_set_color_battery(LED_OFF); + } else if (led_id == EC_LED_ID_POWER_LED) { + if (brightness[EC_LED_COLOR_WHITE] != 0) + led_set_color_power(EC_LED_COLOR_WHITE); + else + led_set_color_power(LED_OFF); + } - return set_color(led_id, LED_OFF, 0); + return EC_SUCCESS; } -static void update_led(enum ec_led_id led_id, bool is_active_charge_port, - int duty, int tick) +__override enum led_states board_led_get_state(enum led_states desired_state) { - enum charge_state power_state = charge_get_state(); - - if (power_state == PWR_STATE_IDLE) { - /* Factory mode: blinking white (2sec on + 2sec off) */ - set_color(led_id, (tick % 8 < 4) ? EC_LED_COLOR_WHITE : LED_OFF, - duty); - } else if (power_state == PWR_STATE_ERROR) { - /* Battery error: blinking amber (1sec on + 1sec off) */ - set_color(led_id, (tick % 4 < 2) ? EC_LED_COLOR_AMBER : LED_OFF, - duty); - } else if (is_active_charge_port) { - /* - * Active charge port: amber when charging, white if fully - * charged. - */ - if (power_state == PWR_STATE_CHARGE) - set_color(led_id, EC_LED_COLOR_AMBER, duty); - else - set_color(led_id, EC_LED_COLOR_WHITE, duty); - } else { - /* - * Non-active port: - * Solid white in S0, blinking amber (3sec on + 1sec off) in S3, - * and LED off in S5 - */ + if (desired_state == STATE_BATTERY_ERROR) { if (chipset_in_state(CHIPSET_STATE_ON)) - set_color(led_id, EC_LED_COLOR_WHITE, duty); + return desired_state; else if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) - set_color( - led_id, - (tick % 8 < 6) ? EC_LED_COLOR_AMBER : LED_OFF, - duty); + return STATE_DISCHARGE_S3; else - set_color(led_id, LED_OFF, 0); - + return STATE_DISCHARGE_S5; } + return desired_state; } - -static void led_tick(void) -{ - static int tick; - int port = charge_manager_get_active_charge_port(); - - ++tick; - /* Pick duty 1 and 50 respectively to have same brightness */ - if (led_auto_control_is_enabled(EC_LED_ID_LEFT_LED)) - update_led(EC_LED_ID_LEFT_LED, port == 0, 1, tick); - if (led_auto_control_is_enabled(EC_LED_ID_RIGHT_LED)) - update_led(EC_LED_ID_RIGHT_LED, port == 1, 50, tick); - /* Turn off unused LEDs */ - if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED)) - set_color(EC_LED_ID_POWER_LED, LED_OFF, 0); - if (led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED)) - set_color(EC_LED_ID_BATTERY_LED, LED_OFF, 0); -} -DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT); -DECLARE_HOOK(HOOK_INIT, led_tick, HOOK_PRIO_DEFAULT); |