diff options
author | Scott Collyer <scollyer@google.com> | 2018-12-18 11:03:44 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-01-29 21:35:05 -0800 |
commit | d10286cc838c0a51266bd0c162f1cce49d036c2a (patch) | |
tree | ef6776845fc5256597a413dec645aef61ad65263 | |
parent | f71c06294fcfa383cefa52d8705b4443c16db8f4 (diff) | |
download | chrome-ec-d10286cc838c0a51266bd0c162f1cce49d036c2a.tar.gz |
hatch: Add support for 2 color LED
This CL adds board specific files/functions required to support the
battery LED. Similar to Coral or Octopus, the LEDs are controlled by
GPIO on/off instead of PWM.
BRANCH=none
BUG=b:122251649
TEST=make buildall. Verfied charging LED turns when external power is
connected.
Change-Id: Ic16d4192aaeba6e765e97743ded772d52ca47111
Signed-off-by: Scott Collyer <scollyer@google.com>
Reviewed-on: https://chromium-review.googlesource.com/1387586
Commit-Ready: Scott Collyer <scollyer@chromium.org>
Tested-by: Scott Collyer <scollyer@chromium.org>
Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Reviewed-by: Zack Yang <zack_yang@compal.corp-partner.google.com>
-rw-r--r-- | baseboard/hatch/build.mk | 1 | ||||
-rw-r--r-- | baseboard/hatch/led_states.c | 133 | ||||
-rw-r--r-- | baseboard/hatch/led_states.h | 69 | ||||
-rw-r--r-- | board/hatch/board.h | 1 | ||||
-rw-r--r-- | board/hatch/build.mk | 2 | ||||
-rw-r--r-- | board/hatch/gpio.inc | 4 | ||||
-rw-r--r-- | board/hatch/led.c | 79 |
7 files changed, 288 insertions, 1 deletions
diff --git a/baseboard/hatch/build.mk b/baseboard/hatch/build.mk index 864225f605..85cfaff6f3 100644 --- a/baseboard/hatch/build.mk +++ b/baseboard/hatch/build.mk @@ -8,4 +8,5 @@ baseboard-y=baseboard.o baseboard-$(CONFIG_BATTERY_SMART)+=battery.o +baseboard-$(CONFIG_LED_COMMON)+=led_states.o baseboard-$(CONFIG_USB_POWER_DELIVERY)+=usb_pd_policy.o diff --git a/baseboard/hatch/led_states.c b/baseboard/hatch/led_states.c new file mode 100644 index 0000000000..e342946bca --- /dev/null +++ b/baseboard/hatch/led_states.c @@ -0,0 +1,133 @@ +/* Copyright 2018 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. + * + * Battery LED state control for hatch boards + */ + +#include "battery.h" +#include "charge_state.h" +#include "chipset.h" +#include "console.h" +#include "ec_commands.h" +#include "extpower.h" +#include "hooks.h" +#include "led_common.h" +#include "led_states.h" + +#define CPRINTS(format, args...) cprints(CC_GPIO, format, ## args) + +static enum led_states led_get_state(void) +{ + int charge_lvl; + enum led_states new_state = LED_NUM_STATES; + + switch (charge_get_state()) { + case PWR_STATE_CHARGE: + /* Get percent charge */ + charge_lvl = charge_get_percent(); + /* Determine which charge state to use */ + if (charge_lvl < led_charge_lvl_1) + new_state = STATE_CHARGING_LVL_1; + else if (charge_lvl < led_charge_lvl_2) + new_state = STATE_CHARGING_LVL_2; + else + new_state = STATE_CHARGING_FULL_CHARGE; + 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 = 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_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) { + CPRINTS("Undefined LED behavior for battery state %d," + "turning off LED", led_state); + 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); diff --git a/baseboard/hatch/led_states.h b/baseboard/hatch/led_states.h new file mode 100644 index 0000000000..d7ae58c005 --- /dev/null +++ b/baseboard/hatch/led_states.h @@ -0,0 +1,69 @@ +/* Copyright 2019 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. + * + * Common functions for stateful LEDs (charger) + */ + +#ifndef __CROS_EC_BASEBOARD_LED_H +#define __CROS_EC_BASEBOARD_LED_H + +#include "ec_commands.h" + +#define LED_INDEFINITE UINT8_MAX +#define LED_ONE_SEC (1000 / HOOK_TICK_INTERVAL_MS) +#define LED_OFF EC_LED_COLOR_COUNT + +/* + * All LED states should have one phase defined, + * and an additional phase can be defined for blinking + */ +enum led_phase { + LED_PHASE_0, + LED_PHASE_1, + LED_NUM_PHASES +}; + +/* + * STATE_CHARGING_LVL_1 is when 0 <= charge_percentage < led_charge_level_1 + * STATE_CHARGING_LVL_2 is when led_chg_level_1 <= chg_% < led_charge_level_2 + * STATE_CHARGING_FULL_CHARGE is when led_charge_level_2 <= charge_% < 100 + */ +enum led_states { + STATE_CHARGING_LVL_1, + STATE_CHARGING_LVL_2, + STATE_CHARGING_FULL_CHARGE, + STATE_DISCHARGE_S0, + STATE_DISCHARGE_S0_BAT_LOW, + STATE_DISCHARGE_S3, + STATE_DISCHARGE_S5, + STATE_BATTERY_ERROR, + STATE_FACTORY_TEST, + LED_NUM_STATES +}; + +struct led_descriptor { + enum ec_led_colors color; + uint8_t time; +}; + + +/* Charging LED state table - defined in board's led.c */ +extern struct led_descriptor + led_bat_state_table[LED_NUM_STATES][LED_NUM_PHASES]; + +/* Charging LED state level 1 - defined in board's led.c */ +extern const int led_charge_lvl_1; + +/* Charging LED state level 2 - defined in board's led.c */ +extern const int led_charge_lvl_2; + +/** + * Set battery LED color - defined in board's led.c + * + * @param color Color to set on battery LED + * + */ +void led_set_color_battery(enum ec_led_colors color); + +#endif /* __CROS_EC_BASEBOARD_LED_H */ diff --git a/board/hatch/board.h b/board/hatch/board.h index 35b3f7351b..bf9c21bf9b 100644 --- a/board/hatch/board.h +++ b/board/hatch/board.h @@ -17,6 +17,7 @@ #define CONFIG_POWER_BUTTON #define CONFIG_KEYBOARD_BOARD_CONFIG #define CONFIG_KEYBOARD_PROTOCOL_8042 +#define CONFIG_LED_COMMON #define CONFIG_LOW_POWER_IDLE #define CONFIG_HOSTCMD_ESPI diff --git a/board/hatch/build.mk b/board/hatch/build.mk index dda2da02f0..733912454f 100644 --- a/board/hatch/build.mk +++ b/board/hatch/build.mk @@ -11,5 +11,5 @@ CHIP_FAMILY:=npcx7 CHIP_VARIANT:=npcx7m6fc BASEBOARD:=hatch -board-y=board.o +board-y=board.o led.o board-$(CONFIG_BATTERY_SMART)+=battery.o diff --git a/board/hatch/gpio.inc b/board/hatch/gpio.inc index bffbecb830..d7f305fccd 100644 --- a/board/hatch/gpio.inc +++ b/board/hatch/gpio.inc @@ -52,6 +52,10 @@ GPIO(EN_USB_A_LOW_PWR_ODL, PIN(9, 4), GPIO_OUT_LOW) /* Misc Signals */ GPIO(EC_BATT_PRES_ODL, PIN(E, 1), GPIO_INPUT) +GPIO(LED_1_L, PIN(C, 4), GPIO_OUT_HIGH) /* Yellow (hatch) */ +GPIO(LED_2_L, PIN(C, 3), GPIO_OUT_HIGH) /* White (hatch) */ +GPIO(LED_3_L, PIN(C, 2), GPIO_OUT_HIGH) +GPIO(LED_4_L, PIN(6, 0), GPIO_OUT_HIGH) /* I2C pins - Alternate function below configures I2C module on these pins */ GPIO(I2C0_SCL, PIN(B, 5), GPIO_INPUT | diff --git a/board/hatch/led.c b/board/hatch/led.c new file mode 100644 index 0000000000..ccba8054cb --- /dev/null +++ b/board/hatch/led.c @@ -0,0 +1,79 @@ +/* Copyright 2018 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 Hatch + */ + +#include "ec_commands.h" +#include "gpio.h" +#include "led_common.h" +#include "led_states.h" +#include "chipset.h" + +#define LED_ON_LVL 0 +#define LED_OFF_LVL 1 + +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 enum ec_led_id supported_led_ids[] = { + 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) +{ + switch (color) { + case EC_LED_COLOR_AMBER: + gpio_set_level(GPIO_LED_2_L, LED_OFF_LVL); + gpio_set_level(GPIO_LED_1_L, LED_ON_LVL); + break; + case EC_LED_COLOR_WHITE: + gpio_set_level(GPIO_LED_1_L, LED_OFF_LVL); + gpio_set_level(GPIO_LED_2_L, LED_ON_LVL); + break; + default: /* LED_OFF and other unsupported colors */ + gpio_set_level(GPIO_LED_1_L, LED_OFF_LVL); + gpio_set_level(GPIO_LED_2_L, LED_OFF_LVL); + break; + } +} + +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; + } +} + +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); + } + + return EC_SUCCESS; +} + |