diff options
author | Ting Shen <phoenixshen@google.com> | 2020-09-09 17:16:37 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-09-15 08:26:50 +0000 |
commit | 64013cb81d3f27908cfbca0d814008f32f7dae54 (patch) | |
tree | 7ceab5222f35b821ea3b2e16754e7037350e18fa | |
parent | 889b52a87e471615ba908246317ef6a502b70160 (diff) | |
download | chrome-ec-64013cb81d3f27908cfbca0d814008f32f7dae54.tar.gz |
asurada: rev1: update led control
Implemented manual led control according to b/167941026 comment#3.
BUG=b:167941026
TEST=ectool led left/right/power/battery amber/white
BRANCH=none
Signed-off-by: Ting Shen <phoenixshen@google.com>
Change-Id: Ic2bfbdc3e5c65420c96a807ba983d63a7fcebb63
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2400798
Reviewed-by: Eric Yilun Lin <yllin@chromium.org>
Commit-Queue: Ting Shen <phoenixshen@chromium.org>
Tested-by: Ting Shen <phoenixshen@chromium.org>
-rw-r--r-- | board/asurada/board.h | 2 | ||||
-rw-r--r-- | board/asurada/led.c | 211 | ||||
-rw-r--r-- | driver/bc12/mt6360.c | 7 | ||||
-rw-r--r-- | driver/bc12/mt6360.h | 3 |
4 files changed, 160 insertions, 63 deletions
diff --git a/board/asurada/board.h b/board/asurada/board.h index fd3d6b7fc0..9498b80370 100644 --- a/board/asurada/board.h +++ b/board/asurada/board.h @@ -82,8 +82,6 @@ /* LED */ #define CONFIG_LED_COMMON -#define CONFIG_LED_ONOFF_STATES -#define CONFIG_LED_POWER_LED /* PD / USB-C / PPC */ #define CONFIG_CMD_PPC_DUMP diff --git a/board/asurada/led.c b/board/asurada/led.c index 1412b0ead5..166ece92e9 100644 --- a/board/asurada/led.c +++ b/board/asurada/led.c @@ -4,56 +4,43 @@ * * 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 "led_common.h" -#include "led_onoff_states.h" #include "pwm.h" +#include "stdbool.h" +#include "util.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_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} }, -}; - -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] = {{LED_OFF, LED_INDEFINITE} }, - [PWR_LED_STATE_OFF] = {{LED_OFF, LED_INDEFINITE} }, -}; +#define LED_OFF EC_LED_COLOR_COUNT 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 */ EC_LED_ID_POWER_LED, EC_LED_ID_BATTERY_LED }; const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids); -void led_set_color_battery(enum ec_led_colors color) +static void led_set_color_left(enum ec_led_colors color, int duty) { + mt6360_led_set_brightness(MT6360_LED_RGB2, duty); + mt6360_led_set_brightness(MT6360_LED_RGB3, duty); + switch (color) { - case EC_LED_COLOR_WHITE: + case EC_LED_COLOR_AMBER: mt6360_led_enable(MT6360_LED_RGB2, 0); mt6360_led_enable(MT6360_LED_RGB3, 1); break; - case EC_LED_COLOR_AMBER: + case EC_LED_COLOR_WHITE: mt6360_led_enable(MT6360_LED_RGB2, 1); mt6360_led_enable(MT6360_LED_RGB3, 0); break; @@ -64,53 +51,155 @@ void led_set_color_battery(enum ec_led_colors color) } } -void led_set_color_power(enum ec_led_colors color) +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) +{ + mt6360_led_set_brightness(MT6360_LED_RGB1, duty); + 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) { - if (led_id == EC_LED_ID_BATTERY_LED) { - brightness_range[EC_LED_COLOR_AMBER] = 1; - brightness_range[EC_LED_COLOR_WHITE] = 1; - } else if (led_id == EC_LED_ID_POWER_LED) { - brightness_range[EC_LED_COLOR_WHITE] = 1; + switch (led_id) { + case EC_LED_ID_LEFT_LED: + brightness_range[EC_LED_COLOR_AMBER] = + 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: + brightness_range[EC_LED_COLOR_WHITE] = + MT6360_LED_BRIGHTNESS_MAX; + break; + default: + break; } } 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_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); + 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]); + + return set_color(led_id, LED_OFF, 0); +} + +static void update_led(enum ec_led_id led_id, bool is_active_charge_port, + int duty, int tick) +{ + 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 - led_set_color_power(LED_OFF); + set_color(led_id, EC_LED_COLOR_WHITE, duty); } else { - return EC_ERROR_INVAL; + /* + * Non-active port: + * Solid white in S0, blinking amber (3sec on + 1sec off) in S3, + * and LED off in S5 + */ + if (chipset_in_state(CHIPSET_STATE_ON)) + set_color(led_id, EC_LED_COLOR_WHITE, duty); + else if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) + set_color( + led_id, + (tick % 8 < 6) ? EC_LED_COLOR_AMBER : LED_OFF, + duty); + else + set_color(led_id, LED_OFF, 0); + } - return EC_SUCCESS; } -static void board_led_init(void) +static void led_tick(void) { - /* set brightness to lowest value */ - mt6360_led_set_brightness(MT6360_LED_RGB2, 0); - mt6360_led_set_brightness(MT6360_LED_RGB3, 0); - - /* Set PWM of LEDs to 5%. */ - pwm_set_duty(PWM_CH_LED1, 5); - pwm_enable(PWM_CH_LED1, 1); - pwm_set_duty(PWM_CH_LED2, 5); - pwm_enable(PWM_CH_LED2, 1); - pwm_set_duty(PWM_CH_LED3, 5); - pwm_enable(PWM_CH_LED3, 1); + 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_INIT, board_led_init, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_INIT, led_tick, HOOK_PRIO_DEFAULT); diff --git a/driver/bc12/mt6360.c b/driver/bc12/mt6360.c index 49de200f52..a5b5ceb487 100644 --- a/driver/bc12/mt6360.c +++ b/driver/bc12/mt6360.c @@ -399,6 +399,13 @@ int mt6360_ldo_get_voltage(enum mt6360_ldo_id ldo_id, int *voltage_mv) } /* RGB LED */ +void mt6360_led_init(void) +{ + /* Enable LED1 software mode */ + mt6360_set_bit(MT6360_REG_RGB_EN, MT6360_ISINK1_CHRIND_EN_SEL); +} +DECLARE_HOOK(HOOK_INIT, mt6360_led_init, HOOK_PRIO_DEFAULT); + int mt6360_led_enable(enum mt6360_led_id led_id, int enable) { if (!IN_RANGE(led_id, 0, MT6360_LED_COUNT)) diff --git a/driver/bc12/mt6360.h b/driver/bc12/mt6360.h index aa370b4e48..a51baee694 100644 --- a/driver/bc12/mt6360.h +++ b/driver/bc12/mt6360.h @@ -23,6 +23,7 @@ #define MT6360_REG_RGB_EN 0x80 #define MT6360_MASK_ISINK_EN(x) BIT(7 - (x)) +#define MT6360_ISINK1_CHRIND_EN_SEL BIT(3) #define MT6360_REG_RGB_ISINK(x) (0x81 + (x)) #define MT6360_MASK_CUR_SEL 0xF @@ -82,6 +83,8 @@ enum mt6360_led_id { MT6360_LED_COUNT, }; +#define MT6360_LED_BRIGHTNESS_MAX 15 + struct mt6360_config_t { int i2c_port; int i2c_addr_flags; |