diff options
author | Scott <scollyer@chromium.org> | 2017-01-31 15:32:28 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-02-03 17:52:19 -0800 |
commit | c19a3cad62defafd385f4ad6ffd1d506e8aac6cc (patch) | |
tree | 0e3ea5bd3f98908ff05d36d460b000c0abb35c79 | |
parent | ae41381a72b1338e20074423f070924bbc47e589 (diff) | |
download | chrome-ec-c19a3cad62defafd385f4ad6ffd1d506e8aac6cc.tar.gz |
eve: Add per port control of charge LEDs
Eve has two charge LEDs. This CL adds support to set a given color for
either left, right, or both LEDs. In addition, the LED policy for Eve
has been enhanced to accommodate separate charge LEDs.
Added amber and white color option plus console command 'led' can
choose the left/right side by adding 0|1 after the color.
S0: Default both LEDs are blue. If charger is connected, then the
active charging port's LED will be amber or green based on battery
level.
S3: If not charging, then both LEDs are blinking white. If charging
then follow same policy as S5.
S5: If not charging, then both LEDs are off. If charging then follow
previous policy, but applied only to the charging port's LED. The port
that isn't actively charging will have its LED off.
BRANCH=none
BUG=chrome-os-partner:60797
TEST=manual Verified the LEDs follow the operation as defined above.
Change-Id: I6f91d8a28999360aa620c7178d48c41625a1fa54
Signed-off-by: Scott <scollyer@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/437404
Commit-Ready: Scott Collyer <scollyer@chromium.org>
Tested-by: Scott Collyer <scollyer@chromium.org>
Reviewed-by: Duncan Laurie <dlaurie@google.com>
Reviewed-by: Todd Broch <tbroch@chromium.org>
-rw-r--r-- | board/eve/board.h | 5 | ||||
-rw-r--r-- | board/eve/led.c | 106 |
2 files changed, 88 insertions, 23 deletions
diff --git a/board/eve/board.h b/board/eve/board.h index 73f15489d0..faace6e46a 100644 --- a/board/eve/board.h +++ b/board/eve/board.h @@ -204,6 +204,11 @@ enum temp_sensor_id { TEMP_SENSOR_COUNT }; +/* + * The PWM channel enums for the LEDs need to be in Red, Green, Blue order as + * the 'set_color()' function assumes this order. The left vs right order + * doesn't matter as long as each side follows RGB order. + */ enum pwm_channel { PWM_CH_KBLIGHT, PWM_CH_LED_L_RED, diff --git a/board/eve/led.c b/board/eve/led.c index 1e7f4222d4..cf696c4a3c 100644 --- a/board/eve/led.c +++ b/board/eve/led.c @@ -5,6 +5,7 @@ * Power/Battery LED control for Eve */ +#include "charge_manager.h" #include "charge_state.h" #include "chipset.h" #include "console.h" @@ -33,36 +34,52 @@ enum led_color { LED_RED, LED_GREEN, LED_BLUE, + LED_WHITE, + LED_AMBER, /* Number of colors, not a color itself */ LED_COLOR_COUNT }; +enum led_side { + LED_LEFT = 0, + LED_RIGHT, + LED_BOTH +}; + /* Brightness vs. color, in the order of off, red, green and blue */ -static const uint8_t color_brightness[LED_COLOR_COUNT][3] = { +#define PWM_CHAN_PER_LED 3 +static const uint8_t color_brightness[LED_COLOR_COUNT][PWM_CHAN_PER_LED] = { /* {Red, Green, Blue}, */ [LED_OFF] = {100, 100, 100}, [LED_RED] = {20, 100, 100}, [LED_GREEN] = {100, 20, 100}, [LED_BLUE] = {100, 100, 20}, + [LED_WHITE] = {0, 0, 0}, + [LED_AMBER] = {0, 87, 100}, }; /** * Set LED color * - * @param color Enumerated color value + * @param color Enumerated color value + * @param side Left LED, Right LED, or both LEDs */ -static void set_color(enum led_color color) +static void set_color(enum led_color color, enum led_side side) { + int i; + /* Set color for left LED */ - pwm_set_duty(PWM_CH_LED_L_RED, color_brightness[color][0]); - pwm_set_duty(PWM_CH_LED_L_GREEN, color_brightness[color][1]); - pwm_set_duty(PWM_CH_LED_L_BLUE, color_brightness[color][2]); + if (side == LED_LEFT || side == LED_BOTH) + for (i = 0; i < PWM_CHAN_PER_LED; i++) + pwm_set_duty(PWM_CH_LED_L_RED + i, + color_brightness[color][i]); /* Set color for right LED */ - pwm_set_duty(PWM_CH_LED_R_RED, color_brightness[color][0]); - pwm_set_duty(PWM_CH_LED_R_GREEN, color_brightness[color][1]); - pwm_set_duty(PWM_CH_LED_R_BLUE, color_brightness[color][2]); + if (side == LED_RIGHT || side == LED_BOTH) + for (i = 0; i < PWM_CHAN_PER_LED; i++) + pwm_set_duty(PWM_CH_LED_R_RED + i, + color_brightness[color][i]); } void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range) @@ -90,9 +107,21 @@ static void eve_led_set_power_battery(void) { static int power_ticks; enum charge_state chg_state = charge_get_state(); + int side; + + /* Get active charge port which maps directly to left/right LED */ + side = charge_manager_get_active_charge_port(); + /* Ensure that side can be safely used as an index */ + if (side < 0 || side >= CONFIG_USB_PD_PORT_COUNT) + side = LED_BOTH; if (chipset_in_state(CHIPSET_STATE_ON)) { - set_color(LED_BLUE); + set_color(LED_BLUE, LED_BOTH); + if (chg_state == PWR_STATE_CHARGE) + set_color(LED_AMBER, side); + else if (chg_state == PWR_STATE_IDLE || chg_state == + PWR_STATE_CHARGE_NEAR_FULL) + set_color(LED_GREEN, side); return; } @@ -100,28 +129,45 @@ static void eve_led_set_power_battery(void) if (battery_is_present() != BP_YES || charge_get_percent() < CONFIG_CHARGER_MIN_BAT_PCT_FOR_POWER_ON) { set_color(((power_ticks++ % LED_TOTAL_TICKS) < LED_ON_TICKS) ? - LED_RED : LED_OFF); + LED_RED : LED_OFF, LED_BOTH); return; } + /* Suspend or Standby state */ + if (chipset_in_state(CHIPSET_STATE_SUSPEND) || + chipset_in_state(CHIPSET_STATE_STANDBY)) { + if (chg_state == PWR_STATE_DISCHARGE) { + /* + * If in S3/S0iX and not charging or in some error + * state, then flash both LEDs white. + */ + set_color(((power_ticks++ % LED_TOTAL_TICKS) < + LED_ON_TICKS) ? + LED_WHITE : LED_OFF, LED_BOTH); + return; + } + } + /* CHIPSET_STATE_OFF */ switch (chg_state) { case PWR_STATE_DISCHARGE: - set_color(LED_OFF); + set_color(LED_OFF, LED_BOTH); break; case PWR_STATE_CHARGE: - set_color(LED_RED); + set_color(LED_OFF, LED_BOTH); + set_color(LED_RED, side); break; case PWR_STATE_ERROR: set_color(((power_ticks++ % LED_TOTAL_TICKS) - < LED_ON_TICKS) ? LED_RED : LED_GREEN); + < LED_ON_TICKS) ? LED_RED : LED_GREEN, LED_BOTH); break; case PWR_STATE_CHARGE_NEAR_FULL: case PWR_STATE_IDLE: /* External power connected in IDLE. */ - set_color(LED_GREEN); + set_color(LED_OFF, LED_BOTH); + set_color(LED_GREEN, side); break; default: - set_color(LED_RED); + set_color(LED_RED, LED_BOTH); break; } if (chg_state != PWR_STATE_ERROR) @@ -144,7 +190,7 @@ static void led_init(void) pwm_enable(PWM_CH_LED_R_GREEN, 1); pwm_enable(PWM_CH_LED_R_BLUE, 1); - set_color(LED_OFF); + set_color(LED_OFF, LED_BOTH); } /* After pwm_pin_init() */ DECLARE_HOOK(HOOK_INIT, led_init, HOOK_PRIO_DEFAULT); @@ -169,19 +215,33 @@ DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT); /* Console commands */ static int command_led(int argc, char **argv) { + int side = LED_BOTH; + char *e; + if (argc > 1) { - ccprintf("cmd led %s\n", argv[1]); + if (argc > 2) { + side = strtoi(argv[2], &e, 10); + if (*e) + return EC_ERROR_PARAM2; + if (side > 1) + return EC_ERROR_PARAM2; + } + if (!strcasecmp(argv[1], "debug")) { led_debug ^= 1; CPRINTF("led_debug = %d\n", led_debug); } else if (!strcasecmp(argv[1], "off")) { - set_color(LED_OFF); + set_color(LED_OFF, side); } else if (!strcasecmp(argv[1], "red")) { - set_color(LED_RED); + set_color(LED_RED, side); } else if (!strcasecmp(argv[1], "green")) { - set_color(LED_GREEN); + set_color(LED_GREEN, side); } else if (!strcasecmp(argv[1], "blue")) { - set_color(LED_BLUE); + set_color(LED_BLUE, side); + } else if (!strcasecmp(argv[1], "white")) { + set_color(LED_WHITE, side); + } else if (!strcasecmp(argv[1], "amber")) { + set_color(LED_AMBER, side); } else { /* maybe handle charger_discharge_on_ac() too? */ return EC_ERROR_PARAM1; @@ -190,5 +250,5 @@ static int command_led(int argc, char **argv) return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(led, command_led, - "[debug|red|green|blue|off]", + "[debug|red|green|blue|white|amber|off <0|1>]", "Change LED color"); |