summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorScott <scollyer@chromium.org>2016-12-15 19:12:46 -0800
committerchrome-bot <chrome-bot@chromium.org>2017-01-31 17:07:40 -0800
commit1fdca3156233c71f51e2ffdd8758dcd53cf882cb (patch)
tree9182975aaf698fb3b3ae139ac5020b3e5d70dec3 /board
parenta4bddf7f2144a4a42e67260fa274da64d79fb2c7 (diff)
downloadchrome-ec-1fdca3156233c71f51e2ffdd8758dcd53cf882cb.tar.gz
eve: Add support for 3 color PWM controlled LEDs
Eve has two 3 color PWM controlled LEDs. This CL adds basic support for these LEDs so that they can be set to off, red, green, or blue. In addition, the LED policy from Kevin is appropriated. In S0 the LEDs will be blue. In S3/S5 if no charger is connected, then the LEDs are off If a charger is connected and the charge level is less than a threshold, both LEDs are set to red. When the charge level gets above a certain level or if the charge state is idle, then the LEDs are set to green. BRANCH=none BUG=chrome-os-partner:60797 TEST=manual Turn the system on so it's in S0, verify both LEDs are blue. Close the lid with no external charger and verify that the LEDs are both off. Connect the charger, and using battfake <> EC command verify that when the charge level is less than the threshold the LEDs are red, otherwise they are green. Set battfake to 0, and verified flashing red. Change-Id: I556ccdafde03cd5f5205e8948d5737dcbdc09d6d Signed-off-by: Scott <scollyer@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/434146 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>
Diffstat (limited to 'board')
-rw-r--r--board/eve/board.c15
-rw-r--r--board/eve/board.h7
-rw-r--r--board/eve/build.mk2
-rw-r--r--board/eve/gpio.inc16
-rw-r--r--board/eve/led.c194
5 files changed, 217 insertions, 17 deletions
diff --git a/board/eve/board.c b/board/eve/board.c
index a130b0f1fb..ea7a0e76b6 100644
--- a/board/eve/board.c
+++ b/board/eve/board.c
@@ -114,7 +114,13 @@ struct keyboard_scan_config keyscan_config = {
/* PWM channels. Must be in the exactly same order as in enum pwm_channel. */
const struct pwm_t pwm_channels[] = {
- [PWM_CH_KBLIGHT] = { 5, PWM_CONFIG_DSLEEP, 100 },
+ [PWM_CH_KBLIGHT] = { 5, PWM_CONFIG_DSLEEP, 100 },
+ [PWM_CH_LED_L_RED] = { 2, PWM_CONFIG_DSLEEP, 100 },
+ [PWM_CH_LED_L_GREEN] = { 3, PWM_CONFIG_DSLEEP, 100 },
+ [PWM_CH_LED_L_BLUE] = { 4, PWM_CONFIG_DSLEEP, 100 },
+ [PWM_CH_LED_R_RED] = { 1, PWM_CONFIG_DSLEEP, 100 },
+ [PWM_CH_LED_R_GREEN] = { 0, PWM_CONFIG_DSLEEP, 100 },
+ [PWM_CH_LED_R_BLUE] = { 6, PWM_CONFIG_DSLEEP, 100 },
};
BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT);
@@ -575,13 +581,6 @@ void board_hibernate_late(void)
int i;
const uint32_t hibernate_pins[][2] = {
{GPIO_LID_OPEN, GPIO_INT_RISING},
- /* Turn off LEDs in hibernate */
- {GPIO_CHARGE_LED_1, GPIO_OUTPUT | GPIO_HIGH},
- {GPIO_CHARGE_LED_2, GPIO_OUTPUT | GPIO_HIGH},
- {GPIO_CHARGE_LED_3, GPIO_OUTPUT | GPIO_HIGH},
- {GPIO_CHARGE_LED_4, GPIO_OUTPUT | GPIO_HIGH},
- {GPIO_CHARGE_LED_5, GPIO_OUTPUT | GPIO_HIGH},
- {GPIO_CHARGE_LED_6, GPIO_OUTPUT | GPIO_HIGH},
/*
* BD99956 handles charge input automatically. We'll disable
* charge output in hibernate. Charger will assert ACOK_OD
diff --git a/board/eve/board.h b/board/eve/board.h
index 521fe1631f..73f15489d0 100644
--- a/board/eve/board.h
+++ b/board/eve/board.h
@@ -27,6 +27,7 @@
#define CONFIG_FPU
#define CONFIG_I2C
#define CONFIG_I2C_MASTER
+#define CONFIG_LED_COMMON
#define CONFIG_LID_SWITCH
#define CONFIG_LTO
#define CONFIG_PWM
@@ -205,6 +206,12 @@ enum temp_sensor_id {
enum pwm_channel {
PWM_CH_KBLIGHT,
+ PWM_CH_LED_L_RED,
+ PWM_CH_LED_L_GREEN,
+ PWM_CH_LED_L_BLUE,
+ PWM_CH_LED_R_RED,
+ PWM_CH_LED_R_GREEN,
+ PWM_CH_LED_R_BLUE,
PWM_CH_COUNT
};
diff --git a/board/eve/build.mk b/board/eve/build.mk
index 705891e38c..f47b5d9caf 100644
--- a/board/eve/build.mk
+++ b/board/eve/build.mk
@@ -9,6 +9,6 @@
CHIP:=npcx
CHIP_VARIANT:=npcx5m6g
-board-y=board.o
+board-y=board.o led.o
board-$(CONFIG_BATTERY_SMART)+=battery.o
board-$(CONFIG_USB_POWER_DELIVERY)+=usb_pd_policy.o
diff --git a/board/eve/gpio.inc b/board/eve/gpio.inc
index 1814b32684..12960f467b 100644
--- a/board/eve/gpio.inc
+++ b/board/eve/gpio.inc
@@ -59,14 +59,6 @@ GPIO(I2C2_SDA, PIN(9, 1), GPIO_INPUT) /* EC_I2C2_SENSOR_3V3_SDA */
GPIO(I2C3_SCL, PIN(D, 1), GPIO_INPUT) /* EC_I2C3_POWER_SCL */
GPIO(I2C3_SDA, PIN(D, 0), GPIO_INPUT) /* EC_I2C3_POWER_SDA */
-/* Charge LED */
-GPIO(CHARGE_LED_1, PIN(8, 0), GPIO_OUT_LOW) /* Charge LED 1 */
-GPIO(CHARGE_LED_2, PIN(C, 4), GPIO_OUT_LOW) /* Charge LED 2 */
-GPIO(CHARGE_LED_3, PIN(B, 6), GPIO_OUT_LOW) /* Charge LED 3 */
-GPIO(CHARGE_LED_4, PIN(C, 0), GPIO_OUT_LOW) /* Charge LED 4 */
-GPIO(CHARGE_LED_5, PIN(C, 3), GPIO_OUT_LOW) /* Charge LED 5 */
-GPIO(CHARGE_LED_6, PIN(C, 2), GPIO_OUT_LOW) /* Charge LED 6 */
-
/* AP wake sources when in Deep-S3 state */
GPIO(TOUCHPAD_WAKE_L, PIN(7, 1), GPIO_INPUT | GPIO_SEL_1P8V) /* INT# from Trackpad */
GPIO(DSP_WAKE_L, PIN(C, 6), GPIO_INPUT | GPIO_SEL_1P8V) /* INT# from DSP Mic */
@@ -103,6 +95,14 @@ ALTERNATE(PIN_MASK(B, 0x30), 1, MODULE_I2C, 0) /* GPIOB4-B5 */ /* EC_I2C00_USB
ALTERNATE(PIN_MASK(B, 0x0C), 1, MODULE_I2C, 0) /* GPOPB2-B3 */ /* EC_I2C01_USB_C1_SDA/SCL */
ALTERNATE(PIN_MASK(D, 0x03), 1, MODULE_I2C, 0) /* GPIOD0-D1 */ /* EC_I2C3_POWER_SDA/SCL */
ALTERNATE(PIN_MASK(B, 0x80), 1, MODULE_PWM, 0) /* GPIOB7 */ /* KBD_BL_PWM */
+/* Left LED PWM Channels */
+ALTERNATE(PIN_MASK(C, 0x10), 1, MODULE_PWM, 0) /* GPIOC4 PWM2 Red*/
+ALTERNATE(PIN_MASK(B, 0x40), 1, MODULE_PWM, 0) /* GPOB6 PWM3 Green*/
+ALTERNATE(PIN_MASK(8, 0x01), 1, MODULE_PWM, 0) /* GPIO80 PWM4 Blue*/
+/* Right LED PWM Channels */
+ALTERNATE(PIN_MASK(C, 0x04), 1, MODULE_PWM, 0) /* GPIOC2 PWM1 Red*/
+ALTERNATE(PIN_MASK(C, 0x08), 1, MODULE_PWM, 0) /* GPIOC3 PWM0 Green */
+ALTERNATE(PIN_MASK(C, 0x01), 1, MODULE_PWM, 0) /* GPIOC0 PWM6 Blue */
/* Keyboard pins */
#define GPIO_KB_INPUT (GPIO_INPUT | GPIO_PULL_UP)
diff --git a/board/eve/led.c b/board/eve/led.c
new file mode 100644
index 0000000000..1e7f4222d4
--- /dev/null
+++ b/board/eve/led.c
@@ -0,0 +1,194 @@
+/* Copyright 2017 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/Battery LED control for Eve
+ */
+
+#include "charge_state.h"
+#include "chipset.h"
+#include "console.h"
+#include "extpower.h"
+#include "gpio.h"
+#include "hooks.h"
+#include "led_common.h"
+#include "pwm.h"
+#include "registers.h"
+#include "util.h"
+
+#define CPRINTF(format, args...) cprintf(CC_PWM, format, ## args)
+#define CPRINTS(format, args...) cprints(CC_PWM, format, ## args)
+
+#define LED_TOTAL_TICKS 16
+#define LED_ON_TICKS 8
+
+static int led_debug;
+
+const enum ec_led_id supported_led_ids[] = {
+ EC_LED_ID_POWER_LED, EC_LED_ID_BATTERY_LED};
+const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids);
+
+enum led_color {
+ LED_OFF = 0,
+ LED_RED,
+ LED_GREEN,
+ LED_BLUE,
+
+ /* Number of colors, not a color itself */
+ LED_COLOR_COUNT
+};
+
+/* Brightness vs. color, in the order of off, red, green and blue */
+static const uint8_t color_brightness[LED_COLOR_COUNT][3] = {
+ /* {Red, Green, Blue}, */
+ [LED_OFF] = {100, 100, 100},
+ [LED_RED] = {20, 100, 100},
+ [LED_GREEN] = {100, 20, 100},
+ [LED_BLUE] = {100, 100, 20},
+};
+
+/**
+ * Set LED color
+ *
+ * @param color Enumerated color value
+ */
+static void set_color(enum led_color color)
+{
+ /* 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]);
+
+ /* 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]);
+}
+
+void led_get_brightness_range(enum ec_led_id led_id, uint8_t *brightness_range)
+{
+ brightness_range[EC_LED_COLOR_RED] = 100;
+ brightness_range[EC_LED_COLOR_BLUE] = 100;
+ brightness_range[EC_LED_COLOR_GREEN] = 100;
+}
+
+int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness)
+{
+ /* Set brightness for left LED */
+ pwm_set_duty(PWM_CH_LED_L_RED, brightness[EC_LED_COLOR_RED]);
+ pwm_set_duty(PWM_CH_LED_L_BLUE, brightness[EC_LED_COLOR_BLUE]);
+ pwm_set_duty(PWM_CH_LED_L_GREEN, brightness[EC_LED_COLOR_GREEN]);
+
+ /* Set brightness for right LED */
+ pwm_set_duty(PWM_CH_LED_R_RED, brightness[EC_LED_COLOR_RED]);
+ pwm_set_duty(PWM_CH_LED_R_BLUE, brightness[EC_LED_COLOR_BLUE]);
+ pwm_set_duty(PWM_CH_LED_R_GREEN, brightness[EC_LED_COLOR_GREEN]);
+ return EC_SUCCESS;
+}
+
+static void eve_led_set_power_battery(void)
+{
+ static int power_ticks;
+ enum charge_state chg_state = charge_get_state();
+
+ if (chipset_in_state(CHIPSET_STATE_ON)) {
+ set_color(LED_BLUE);
+ return;
+ }
+
+ /* Flash red on critical battery, which usually inhibits AP power-on. */
+ 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);
+ return;
+ }
+
+ /* CHIPSET_STATE_OFF */
+ switch (chg_state) {
+ case PWR_STATE_DISCHARGE:
+ set_color(LED_OFF);
+ break;
+ case PWR_STATE_CHARGE:
+ set_color(LED_RED);
+ break;
+ case PWR_STATE_ERROR:
+ set_color(((power_ticks++ % LED_TOTAL_TICKS)
+ < LED_ON_TICKS) ? LED_RED : LED_GREEN);
+ break;
+ case PWR_STATE_CHARGE_NEAR_FULL:
+ case PWR_STATE_IDLE: /* External power connected in IDLE. */
+ set_color(LED_GREEN);
+ break;
+ default:
+ set_color(LED_RED);
+ break;
+ }
+ if (chg_state != PWR_STATE_ERROR)
+ power_ticks = 0;
+}
+
+static void led_init(void)
+{
+ /*
+ * Enable PWMs and set to 0% duty cycle. If they're disabled,
+ * seems to ground the pins instead of letting them float.
+ */
+ /* Initialize PWM channels for left LED */
+ pwm_enable(PWM_CH_LED_L_RED, 1);
+ pwm_enable(PWM_CH_LED_L_GREEN, 1);
+ pwm_enable(PWM_CH_LED_L_BLUE, 1);
+
+ /* Initialize PWM channels for right LED */
+ pwm_enable(PWM_CH_LED_R_RED, 1);
+ pwm_enable(PWM_CH_LED_R_GREEN, 1);
+ pwm_enable(PWM_CH_LED_R_BLUE, 1);
+
+ set_color(LED_OFF);
+}
+/* After pwm_pin_init() */
+DECLARE_HOOK(HOOK_INIT, led_init, HOOK_PRIO_DEFAULT);
+
+/**
+ * Called by hook task every 250 ms
+ */
+static void led_tick(void)
+{
+ if (led_debug)
+ return;
+
+ if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED) &&
+ led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED)) {
+ eve_led_set_power_battery();
+ return;
+ }
+}
+DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT);
+
+/******************************************************************/
+/* Console commands */
+static int command_led(int argc, char **argv)
+{
+ if (argc > 1) {
+ ccprintf("cmd led %s\n", argv[1]);
+ 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);
+ } else if (!strcasecmp(argv[1], "red")) {
+ set_color(LED_RED);
+ } else if (!strcasecmp(argv[1], "green")) {
+ set_color(LED_GREEN);
+ } else if (!strcasecmp(argv[1], "blue")) {
+ set_color(LED_BLUE);
+ } else {
+ /* maybe handle charger_discharge_on_ac() too? */
+ return EC_ERROR_PARAM1;
+ }
+ }
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(led, command_led,
+ "[debug|red|green|blue|off]",
+ "Change LED color");