summaryrefslogtreecommitdiff
path: root/board/kappa/led.c
diff options
context:
space:
mode:
authorDevin Lu <devin.lu@quantatw.com>2020-02-17 20:37:31 +0800
committerCommit Bot <commit-bot@chromium.org>2020-02-18 09:29:54 +0000
commit599428feb0b21b57c5d50cde60e064806376e8e6 (patch)
tree43ad76f5c71f69a0dea9cf2f4a6c5573ae9e6586 /board/kappa/led.c
parent4b8d829d6ab0131716ec8972847479056cd3fbba (diff)
downloadchrome-ec-599428feb0b21b57c5d50cde60e064806376e8e6.tar.gz
kappa: add gpio led controlling
CL:1712887 added ioexpander gpio control. This patch add customize led behavior. 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: Blinking white (1 sec on, 1 sec off) BUG=b:146844869 BRANCH=kukui 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. Change-Id: I2790cba404222c98d2e9741865ed3a532a6d001e Signed-off-by: Devin Lu <Devin.Lu@quantatw.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2060249 Reviewed-by: Ting Shen <phoenixshen@chromium.org>
Diffstat (limited to 'board/kappa/led.c')
-rw-r--r--board/kappa/led.c150
1 files changed, 123 insertions, 27 deletions
diff --git a/board/kappa/led.c b/board/kappa/led.c
index de4eca8bbf..5b65d7b948 100644
--- a/board/kappa/led.c
+++ b/board/kappa/led.c
@@ -5,47 +5,143 @@
* Power and battery LED control for Kappa
*/
-#include "common.h"
-#include "driver/ioexpander/it8801.h"
-#include "ec_commands.h"
+#include "charge_state.h"
+#include "extpower.h"
+#include "hooks.h"
+#include "ioexpander.h"
#include "led_common.h"
-#include "led_pwm.h"
-const enum ec_led_id supported_led_ids[] = {
- EC_LED_ID_POWER_LED,
-};
+#define BAT_LED_ON 0
+#define BAT_LED_OFF 1
+
+const enum ec_led_id supported_led_ids[] = {EC_LED_ID_BATTERY_LED};
+
const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids);
-struct pwm_led led_color_map[EC_LED_COLOR_COUNT] = {
- [EC_LED_COLOR_AMBER] = {100, 0, 0},
- [EC_LED_COLOR_WHITE] = {0, 0, 100},
+enum led_color {
+ LED_OFF = 0,
+ LED_AMBER,
+ LED_WHITE,
+ LED_COLOR_COUNT /* Number of colors, not a color itself */
};
-struct pwm_led pwm_leds[CONFIG_LED_PWM_COUNT] = {
- [PWM_LED0] = {
- .ch0 = PWM_CH_LED_AMBER,
- .ch1 = PWM_LED_NO_CHANNEL,
- .ch2 = PWM_CH_LED_WHITE,
- .enable = &it8801_pwm_enable,
- .set_duty = &it8801_pwm_set_duty,
- },
-};
+static int led_set_color_battery(enum led_color color)
+{
+ switch (color) {
+ case LED_OFF:
+ ioex_set_level(IOEX_BAT_LED_WHITE_L, BAT_LED_OFF);
+ ioex_set_level(IOEX_BAT_LED_AMBER_L, BAT_LED_OFF);
+ break;
+ case LED_WHITE:
+ ioex_set_level(IOEX_BAT_LED_WHITE_L, BAT_LED_ON);
+ ioex_set_level(IOEX_BAT_LED_AMBER_L, BAT_LED_OFF);
+ break;
+ case LED_AMBER:
+ ioex_set_level(IOEX_BAT_LED_WHITE_L, BAT_LED_OFF);
+ ioex_set_level(IOEX_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)
{
- brightness_range[EC_LED_COLOR_AMBER] = 100;
- brightness_range[EC_LED_COLOR_WHITE] = 100;
+ brightness_range[EC_LED_COLOR_WHITE] = 1;
+ brightness_range[EC_LED_COLOR_AMBER] = 1;
+}
+
+static int led_set_color(enum ec_led_id led_id, enum led_color color)
+{
+ int rv;
+
+ switch (led_id) {
+ case EC_LED_ID_BATTERY_LED:
+ rv = led_set_color_battery(color);
+ break;
+ default:
+ return EC_ERROR_UNKNOWN;
+ }
+ return rv;
}
int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness)
{
- if (brightness[EC_LED_COLOR_AMBER])
- set_pwm_led_color(PWM_LED0, EC_LED_COLOR_AMBER);
- else if (brightness[EC_LED_COLOR_WHITE])
- set_pwm_led_color(PWM_LED0, EC_LED_COLOR_WHITE);
+ 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_LED0, -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 system suspend */
+ if (chipset_in_state(CHIPSET_STATE_SUSPEND |
+ CHIPSET_STATE_STANDBY) &&
+ 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);