summaryrefslogtreecommitdiff
path: root/board/drawcia/led.c
diff options
context:
space:
mode:
authorDevin Lu <Devin.Lu@quantatw.com>2020-07-07 11:37:30 +0800
committerCommit Bot <commit-bot@chromium.org>2020-07-21 06:53:47 +0000
commita557e434e3748d2febcf6de9acccfb8ec520289e (patch)
treefd8193d06b25fc2fbcca232bff4476cb83b4272c /board/drawcia/led.c
parenteda8f40a9886eb209cf93c5f959ab0e46594e620 (diff)
downloadchrome-ec-a557e434e3748d2febcf6de9acccfb8ec520289e.tar.gz
drawcia: implement leds
Charging: Amber. Discharging: Off. Fully: White. Battery Error: Blinking white (0.5 sec on, 0.5 sec off) Fuel <10%: Blinking white (1 sec on, 1 sec off) Force idle for factory: Blinking amber (1 sec on, 1 sec off) System suspend without charging (Clamshell SKU): Blinking white (1 sec on, 1 sec off) BUG=none BRANCH=none TEST=make sure led is showing amber while battery is charging. make sure led is showing white while battery is fully charged. make sure led is blinking white while battery low. make sure led is blinking white on suspend without charging. make sure led is blinking white quickly while battery error. Signed-off-by: Devin Lu <Devin.Lu@quantatw.com> Change-Id: Iaba98c96bec1c1b9c0c66b01ba99c2c07e50008e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2289330 Reviewed-by: Marco Chen <marcochen@chromium.org>
Diffstat (limited to 'board/drawcia/led.c')
-rw-r--r--board/drawcia/led.c186
1 files changed, 128 insertions, 58 deletions
diff --git a/board/drawcia/led.c b/board/drawcia/led.c
index b19e594fbd..1cd435b4b0 100644
--- a/board/drawcia/led.c
+++ b/board/drawcia/led.c
@@ -3,80 +3,150 @@
* found in the LICENSE file.
*/
-/* Waddledee specific PWM LED settings. */
+/* Drawcia specific LED settings. */
-#include "common.h"
-#include "ec_commands.h"
-#include "led_pwm.h"
-#include "pwm.h"
-#include "util.h"
+#include "cbi_fw_config.h"
+#include "charge_state.h"
+#include "extpower.h"
+#include "hooks.h"
+#include "led_common.h"
+
+#define BAT_LED_ON 0
+#define BAT_LED_OFF 1
+
+const enum ec_led_id supported_led_ids[] = {EC_LED_ID_BATTERY_LED};
-const enum ec_led_id supported_led_ids[] = {
- EC_LED_ID_POWER_LED,
-};
const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids);
-/*
- * Board has one physical LED with red, green, and blue
- */
-struct pwm_led led_color_map[EC_LED_COLOR_COUNT] = {
- /* Red, Green, Blue */
- [EC_LED_COLOR_RED] = { 100, 0, 0 },
- [EC_LED_COLOR_GREEN] = { 0, 100, 0 },
- [EC_LED_COLOR_BLUE] = { 0, 0, 100 },
- [EC_LED_COLOR_YELLOW] = { 50, 50, 0 },
- [EC_LED_COLOR_WHITE] = { 50, 50, 50 },
- [EC_LED_COLOR_AMBER] = { 70, 30, 0 },
+enum led_color {
+ LED_OFF = 0,
+ LED_AMBER,
+ LED_WHITE,
+ LED_COLOR_COUNT /* Number of colors, not a color itself */
};
-/* One logical LED with red, green, and blue channels. */
-struct pwm_led pwm_leds[CONFIG_LED_PWM_COUNT] = {
- {
- .ch0 = PWM_CH_LED_RED,
- .ch1 = PWM_CH_LED_GREEN,
- .ch2 = PWM_CH_LED_BLUE,
- .enable = &pwm_enable,
- .set_duty = &pwm_set_duty,
- },
-};
+static int led_set_color_battery(enum led_color color)
+{
+ switch (color) {
+ case LED_OFF:
+ gpio_set_level(GPIO_BAT_LED_WHITE_L, BAT_LED_OFF);
+ gpio_set_level(GPIO_BAT_LED_AMBER_L, BAT_LED_OFF);
+ break;
+ case LED_WHITE:
+ gpio_set_level(GPIO_BAT_LED_WHITE_L, BAT_LED_ON);
+ gpio_set_level(GPIO_BAT_LED_AMBER_L, BAT_LED_OFF);
+ break;
+ case LED_AMBER:
+ gpio_set_level(GPIO_BAT_LED_WHITE_L, BAT_LED_OFF);
+ gpio_set_level(GPIO_BAT_LED_AMBER_L, BAT_LED_ON);
+ break;
+ default:
+ return EC_ERROR_UNKNOWN;
+ }
+ return EC_SUCCESS;
+}
void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range)
{
- memset(brightness_range, '\0',
- sizeof(*brightness_range) * EC_LED_COLOR_COUNT);
- brightness_range[EC_LED_COLOR_RED] = 100;
- brightness_range[EC_LED_COLOR_GREEN] = 100;
- brightness_range[EC_LED_COLOR_BLUE] = 100;
- brightness_range[EC_LED_COLOR_YELLOW] = 100;
- brightness_range[EC_LED_COLOR_WHITE] = 100;
- brightness_range[EC_LED_COLOR_AMBER] = 100;
+ brightness_range[EC_LED_COLOR_WHITE] = 1;
+ brightness_range[EC_LED_COLOR_AMBER] = 1;
}
-int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness)
+static int led_set_color(enum ec_led_id led_id, enum led_color color)
{
- enum pwm_led_id pwm_id;
+ int rv;
- /* Convert ec_led_id to pwm_led_id. */
- if (led_id == EC_LED_ID_POWER_LED)
- pwm_id = PWM_LED0;
- else
+ switch (led_id) {
+ case EC_LED_ID_BATTERY_LED:
+ rv = led_set_color_battery(color);
+ break;
+ default:
return EC_ERROR_UNKNOWN;
+ }
+ return rv;
+}
- if (brightness[EC_LED_COLOR_RED])
- set_pwm_led_color(pwm_id, EC_LED_COLOR_RED);
- else if (brightness[EC_LED_COLOR_GREEN])
- set_pwm_led_color(pwm_id, EC_LED_COLOR_GREEN);
- else if (brightness[EC_LED_COLOR_BLUE])
- set_pwm_led_color(pwm_id, EC_LED_COLOR_BLUE);
- else if (brightness[EC_LED_COLOR_YELLOW])
- set_pwm_led_color(pwm_id, EC_LED_COLOR_YELLOW);
- else if (brightness[EC_LED_COLOR_WHITE])
- set_pwm_led_color(pwm_id, EC_LED_COLOR_WHITE);
- else if (brightness[EC_LED_COLOR_AMBER])
- set_pwm_led_color(pwm_id, EC_LED_COLOR_AMBER);
+int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness)
+{
+ if (brightness[EC_LED_COLOR_WHITE] != 0)
+ led_set_color(led_id, LED_WHITE);
+ else if (brightness[EC_LED_COLOR_AMBER] != 0)
+ led_set_color(led_id, LED_AMBER);
else
- /* Otherwise, the "color" is "off". */
- set_pwm_led_color(pwm_id, -1);
+ led_set_color(led_id, LED_OFF);
return EC_SUCCESS;
}
+
+static void led_set_battery(void)
+{
+ static int battery_ticks;
+ static int power_ticks;
+ uint32_t chflags = charge_get_flags();
+
+ battery_ticks++;
+
+ /*
+ * Override battery LED for Drawlet/Drawman, Drawlet/Drawman
+ * don't have power LED, blinking battery white LED to indicate
+ * system suspend without charging.
+ */
+ if (get_cbi_fw_config_tablet_mode() == TABLET_MODE_ABSENT) {
+ if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) &&
+ charge_get_state() != PWR_STATE_CHARGE) {
+ led_set_color_battery(power_ticks++ & 0x2 ?
+ LED_WHITE : LED_OFF);
+ return;
+ }
+ }
+
+ power_ticks = 0;
+
+ switch (charge_get_state()) {
+ case PWR_STATE_CHARGE:
+ led_set_color_battery(LED_AMBER);
+ break;
+ case PWR_STATE_DISCHARGE_FULL:
+ if (extpower_is_present()) {
+ led_set_color_battery(LED_WHITE);
+ break;
+ }
+ /* Intentional fall-through */
+ case PWR_STATE_DISCHARGE:
+ /*
+ * Blink white light (1 sec on, 1 sec off)
+ * when battery capacity is less than 10%
+ */
+ if (charge_get_percent() < 10)
+ led_set_color_battery(
+ (battery_ticks & 0x2) ? LED_WHITE : LED_OFF);
+ else
+ led_set_color_battery(LED_OFF);
+ break;
+ case PWR_STATE_ERROR:
+ led_set_color_battery(
+ (battery_ticks % 0x2) ? LED_WHITE : LED_OFF);
+ break;
+ case PWR_STATE_CHARGE_NEAR_FULL:
+ led_set_color_battery(LED_WHITE);
+ break;
+ case PWR_STATE_IDLE: /* External power connected in IDLE */
+ if (chflags & CHARGE_FLAG_FORCE_IDLE)
+ led_set_color_battery(
+ (battery_ticks & 0x2) ? LED_AMBER : LED_OFF);
+ else
+ led_set_color_battery(LED_WHITE);
+ break;
+ default:
+ /* Other states don't alter LED behavior */
+ break;
+ }
+}
+
+/* Called by hook task every TICK */
+static void led_tick(void)
+{
+ if (led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED))
+ led_set_battery();
+}
+DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT);