summaryrefslogtreecommitdiff
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
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>
-rw-r--r--board/drawcia/board.c19
-rw-r--r--board/drawcia/board.h7
-rw-r--r--board/drawcia/gpio.inc7
-rw-r--r--board/drawcia/led.c186
4 files changed, 134 insertions, 85 deletions
diff --git a/board/drawcia/board.c b/board/drawcia/board.c
index d8ac3b8063..a9468ae475 100644
--- a/board/drawcia/board.c
+++ b/board/drawcia/board.c
@@ -439,26 +439,7 @@ const struct pwm_t pwm_channels[] = {
.channel = 0,
.flags = PWM_CONFIG_DSLEEP,
.freq_hz = 10000,
- },
-
- [PWM_CH_LED_RED] = {
- .channel = 1,
- .flags = PWM_CONFIG_DSLEEP | PWM_CONFIG_ACTIVE_LOW,
- .freq_hz = 2400,
- },
-
- [PWM_CH_LED_GREEN] = {
- .channel = 2,
- .flags = PWM_CONFIG_DSLEEP | PWM_CONFIG_ACTIVE_LOW,
- .freq_hz = 2400,
- },
-
- [PWM_CH_LED_BLUE] = {
- .channel = 3,
- .flags = PWM_CONFIG_DSLEEP | PWM_CONFIG_ACTIVE_LOW,
- .freq_hz = 2400,
}
-
};
BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT);
diff --git a/board/drawcia/board.h b/board/drawcia/board.h
index 5386b518c9..5352fc6cb8 100644
--- a/board/drawcia/board.h
+++ b/board/drawcia/board.h
@@ -31,10 +31,6 @@
#define CONFIG_CHARGER_OTG
#undef CONFIG_CHARGER_SINGLE_CHIP
-/* LED */
-#define CONFIG_LED_PWM
-#define CONFIG_LED_PWM_COUNT 1
-
/* Sensors */
#define CONFIG_ACCEL_LIS2DE /* Lid accel */
#define CONFIG_ACCELGYRO_LSM6DSM /* Base accel */
@@ -94,9 +90,6 @@ enum chg_id {
enum pwm_channel {
PWM_CH_KBLIGHT,
- PWM_CH_LED_RED,
- PWM_CH_LED_GREEN,
- PWM_CH_LED_BLUE,
PWM_CH_COUNT,
};
diff --git a/board/drawcia/gpio.inc b/board/drawcia/gpio.inc
index f77b48cf9d..0f80d6443c 100644
--- a/board/drawcia/gpio.inc
+++ b/board/drawcia/gpio.inc
@@ -116,6 +116,11 @@ GPIO(GPIOJ5_NC, PIN(J, 5), GPIO_INPUT | GPIO_PULL_DOWN)
GPIO(GPIOJ6_NC, PIN(J, 6), GPIO_INPUT | GPIO_PULL_DOWN)
GPIO(GPIOM6_NC, PIN(M, 6), GPIO_INPUT | GPIO_PULL_DOWN)
+/* LED */
+GPIO(BAT_LED_AMBER_L, PIN(A, 1), GPIO_OUT_HIGH)
+GPIO(BAT_LED_WHITE_L, PIN(A, 2), GPIO_OUT_HIGH)
+GPIO(PWR_LED_WHITE_L, PIN(A, 3), GPIO_OUT_HIGH)
+
/* Alternate functions GPIO definitions */
/* UART */
ALTERNATE(PIN_MASK(B, BIT(0) | BIT(1)), 0, MODULE_UART, 0) /* UART for debug */
@@ -135,4 +140,4 @@ ALTERNATE(PIN_MASK(I, BIT(0) | BIT(2) | BIT(3)), 0, MODULE_ADC, 0) /* ADC0: EC_V
ALTERNATE(PIN_MASK(J, BIT(2)), 0, MODULE_DAC, 0) /* DAC2: EC_AP_PSYS */
/* PWM */
-ALTERNATE(PIN_MASK(A, BIT(0) | BIT(1) | BIT(2) | BIT(3)), 0, MODULE_PWM, 0) /* KB_BL_PWM, LED_[R,G,B]_ODL */
+ALTERNATE(PIN_MASK(A, BIT(0)), 0, MODULE_PWM, 0) /* KB_BL_PWM */
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);