summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDevin Lu <Devin.Lu@quantatw.com>2014-03-24 17:29:04 +0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-03-29 00:49:10 +0000
commitbd004fe1ae39c6ad87a4ba06d6cbc0bf8597dcf2 (patch)
treedc061b3e752c52ba6a8c015d345336efbe0f5015
parent614698f98635db6d89980a1ffcad50a71d5852a6 (diff)
downloadchrome-ec-bd004fe1ae39c6ad87a4ba06d6cbc0bf8597dcf2.tar.gz
Kip: Implement the power and battery LED behavior
Just copy falco's LEDs behavior, becuase HW's schematic was the same with falco. BUG=chrome-os-partner:26767 BRANCH=rambi TEST=manual Check battery LED show Amber when battery in charging. Check battery LED show white when battery fully. Check battery LED show blinking every 500ms when charging error. Check PWR LED light when system power on. Check PWR LED off when system power down. Check PWR LED will blinking every 1sec when system into suspend. Change-Id: I2d0d330d750156053bad16f196e32566260544aa Signed-off-by: Devin Lu <Devin.Lu@quantatw.com> Reviewed-by: Dave Parker <dparker@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/191243 Commit-Queue: Dave Parker <dparker@chromium.org>
-rw-r--r--board/kip/board.c4
-rw-r--r--board/kip/board.h4
-rw-r--r--board/kip/led.c205
3 files changed, 137 insertions, 76 deletions
diff --git a/board/kip/board.c b/board/kip/board.c
index 4620d2b0eb..3be8adf0ad 100644
--- a/board/kip/board.c
+++ b/board/kip/board.c
@@ -111,6 +111,9 @@ const struct gpio_info gpio_list[] = {
{"WLAN_OFF_L", LM4_GPIO_J, (1<<4), GPIO_OUT_LOW, NULL},
{"PCH_SCI_L", LM4_GPIO_M, (1<<1), GPIO_ODR_HIGH, NULL},
{"KBD_IRQ_L", LM4_GPIO_M, (1<<3), GPIO_ODR_HIGH, NULL},
+ {"BAT_LED0", LM4_GPIO_N, (1<<6), GPIO_OUT_LOW, NULL},
+ {"BAT_LED1", LM4_GPIO_N, (1<<4), GPIO_OUT_LOW, NULL},
+ {"PWR_LED_L", LM4_GPIO_M, (1<<6), GPIO_OUT_HIGH, NULL},
};
BUILD_ASSERT(ARRAY_SIZE(gpio_list) == GPIO_COUNT);
@@ -124,7 +127,6 @@ const struct gpio_alt_func gpio_alt_funcs[] = {
{GPIO_D, 0x0f, 2, MODULE_SPI}, /* SPI1 */
{GPIO_L, 0x3f, 15, MODULE_LPC}, /* LPC */
{GPIO_M, 0x21, 15, MODULE_LPC}, /* LPC */
- {GPIO_N, 0x50, 1, MODULE_PWM_LED, GPIO_OPEN_DRAIN}, /* FAN0PWM 3&4 */
};
const int gpio_alt_funcs_count = ARRAY_SIZE(gpio_alt_funcs);
diff --git a/board/kip/board.h b/board/kip/board.h
index 4bf579e934..acc682f52e 100644
--- a/board/kip/board.h
+++ b/board/kip/board.h
@@ -128,7 +128,9 @@ enum gpio_signal {
GPIO_WLAN_OFF_L, /* Disable WiFi radio */
GPIO_PCH_SCI_L, /* Assert SCI to PCH */
GPIO_KBD_IRQ_L, /* Negative edge triggered irq. */
-
+ GPIO_BAT_LED0, /* Battery charger status */
+ GPIO_BAT_LED1, /* Battery charger status */
+ GPIO_PWR_LED_L, /* Power LED */
/* Number of GPIOs; not an actual GPIO */
GPIO_COUNT
};
diff --git a/board/kip/led.c b/board/kip/led.c
index f0eda1c57a..4de1735e51 100644
--- a/board/kip/led.c
+++ b/board/kip/led.c
@@ -7,115 +7,172 @@
#include "charge_state.h"
#include "chipset.h"
+#include "extpower.h"
#include "gpio.h"
#include "hooks.h"
#include "led_common.h"
-#include "pwm.h"
#include "util.h"
-const enum ec_led_id supported_led_ids[] = {EC_LED_ID_BATTERY_LED};
+const enum ec_led_id supported_led_ids[] = {
+ EC_LED_ID_BATTERY_LED, EC_LED_ID_POWER_LED};
const int supported_led_ids_count = ARRAY_SIZE(supported_led_ids);
enum led_color {
LED_OFF = 0,
- LED_RED,
- LED_ORANGE,
- LED_YELLOW,
- LED_GREEN,
-
- /* Number of colors, not a color itself */
- LED_COLOR_COUNT
+ LED_WHITE,
+ LED_AMBER,
+ LED_COLOR_COUNT /* Number of colors, not a color itself */
};
-/* Brightness vs. color, for {red, green} LEDs */
-static const uint8_t color_brightness[LED_COLOR_COUNT][2] = {
- {0, 0},
- {100, 0},
- {30, 45},
- {20, 60},
- {0, 100},
-};
+static int bat_led_set_color(enum led_color color)
+{
+ switch (color) {
+ case LED_OFF:
+ gpio_set_level(GPIO_BAT_LED0, 1);
+ gpio_set_level(GPIO_BAT_LED1, 1);
+ break;
+ case LED_WHITE:
+ gpio_set_level(GPIO_BAT_LED0, 1);
+ gpio_set_level(GPIO_BAT_LED1, 0);
+ break;
+ case LED_AMBER:
+ gpio_set_level(GPIO_BAT_LED0, 0);
+ gpio_set_level(GPIO_BAT_LED1, 1);
+ break;
+ default:
+ return EC_ERROR_UNKNOWN;
+ }
+ return EC_SUCCESS;
+}
-/**
- * Set LED color
- *
- * @param color Enumerated color value
- */
-static void set_color(enum led_color color)
+static int pwr_led_set_color(enum led_color color)
{
- pwm_set_duty(PWM_CH_LED_RED, color_brightness[color][0]);
- pwm_set_duty(PWM_CH_LED_GREEN, color_brightness[color][1]);
+ switch (color) {
+ case LED_OFF:
+ gpio_set_level(GPIO_PWR_LED_L, 1);
+ break;
+ case LED_WHITE:
+ gpio_set_level(GPIO_PWR_LED_L, 0);
+ 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_RED] = 100;
- brightness_range[EC_LED_COLOR_GREEN] = 100;
+ switch (led_id) {
+ case EC_LED_ID_BATTERY_LED:
+ brightness_range[EC_LED_COLOR_WHITE] = 100;
+ brightness_range[EC_LED_COLOR_YELLOW] = 100;
+ break;
+ case EC_LED_ID_POWER_LED:
+ brightness_range[EC_LED_COLOR_WHITE] = 100;
+ break;
+ default:
+ /* Nothing to do */
+ break;
+ }
}
int led_set_brightness(enum ec_led_id led_id, const uint8_t *brightness)
{
- pwm_set_duty(PWM_CH_LED_RED, brightness[EC_LED_COLOR_RED]);
- pwm_set_duty(PWM_CH_LED_GREEN, brightness[EC_LED_COLOR_GREEN]);
+ switch (led_id) {
+ case EC_LED_ID_BATTERY_LED:
+ if (brightness[EC_LED_COLOR_WHITE] != 0)
+ bat_led_set_color(LED_WHITE);
+ else if (brightness[EC_LED_COLOR_YELLOW] != 0)
+ bat_led_set_color(LED_AMBER);
+ else
+ bat_led_set_color(LED_OFF);
+ break;
+ case EC_LED_ID_POWER_LED:
+ if (brightness[EC_LED_COLOR_WHITE] != 0)
+ pwr_led_set_color(LED_WHITE);
+ else
+ pwr_led_set_color(LED_OFF);
+ break;
+ default:
+ break;
+ }
return EC_SUCCESS;
}
-static void led_init(void)
+static void kip_led_set_power(void)
{
- /* Configure GPIOs */
- gpio_config_module(MODULE_PWM_LED, 1);
-
- /*
- * Enable PWMs and set to 0% duty cycle. If they're disabled, the LM4
- * seems to ground the pins instead of letting them float.
- */
- pwm_enable(PWM_CH_LED_RED, 1);
- pwm_enable(PWM_CH_LED_GREEN, 1);
- set_color(LED_OFF);
-}
-DECLARE_HOOK(HOOK_INIT, led_init, HOOK_PRIO_DEFAULT);
+ static int power_ticks;
+ static int previous_state_suspend;
-/**
- * Called by hook task every 250 ms
- */
-static void led_tick(void)
-{
- static unsigned ticks;
- int chstate = charge_get_state();
+ power_ticks++;
- ticks++;
+ if (chipset_in_state(CHIPSET_STATE_SUSPEND)) {
+ /* Reset ticks if entering suspend so LED turns amber
+ * as soon as possible. */
+ if (!previous_state_suspend)
+ power_ticks = 0;
- /* If we don't control the LED, nothing to do */
- if (!led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED))
- return;
+ /* Blink once every one second. */
+ pwr_led_set_color((power_ticks & 0x4) ? LED_WHITE : LED_OFF);
- /* If charging error, blink orange, 25% duty cycle, 4 sec period */
- if (chstate == PWR_STATE_ERROR) {
- set_color((ticks % 16) < 4 ? LED_ORANGE : LED_OFF);
+ previous_state_suspend = 1;
return;
}
- /* If charge-force-idle, blink green, 50% duty cycle, 2 sec period */
- if (chstate == PWR_STATE_IDLE &&
- (charge_get_flags() & CHARGE_FLAG_FORCE_IDLE)) {
- set_color((ticks & 0x4) ? LED_GREEN : LED_OFF);
- return;
- }
+ previous_state_suspend = 0;
- /* If the system is charging, solid orange */
- if (chstate == PWR_STATE_CHARGE) {
- set_color(LED_ORANGE);
- return;
- }
+ if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
+ pwr_led_set_color(LED_OFF);
+ else if (chipset_in_state(CHIPSET_STATE_ON))
+ pwr_led_set_color(LED_WHITE);
+}
- /* If AC connected and fully charged (or close to it), solid green */
- if (chstate == PWR_STATE_CHARGE_NEAR_FULL ||
- chstate == PWR_STATE_IDLE) {
- set_color(LED_GREEN);
- return;
+static void kip_led_set_battery(void)
+{
+ static int battery_ticks;
+ uint32_t chflags = charge_get_flags();
+
+ battery_ticks++;
+
+ /* Battery LED is solid white if AC connected, unless the battery is
+ * is charging or there is an error. */
+ bat_led_set_color(extpower_is_present() ? LED_WHITE : LED_OFF);
+
+ switch (charge_get_state()) {
+ case PWR_STATE_CHARGE:
+ bat_led_set_color(LED_AMBER);
+ break;
+ case PWR_STATE_DISCHARGE:
+ /* See crosbug.com/p/22159. There's a 3% difference
+ * between the battery level seen by the kernel and what's
+ * really going on, so if they want to see 12%, we use 15%.
+ * Hard code this number here, because this only affects the
+ * LED color, not the battery charge state. */
+ if (charge_get_percent() < 15)
+ bat_led_set_color(
+ (battery_ticks & 0x4) ? LED_WHITE : LED_OFF);
+ break;
+ case PWR_STATE_ERROR:
+ bat_led_set_color((battery_ticks & 0x2) ? LED_WHITE : LED_OFF);
+ break;
+ case PWR_STATE_IDLE:
+ if (chflags & CHARGE_FLAG_FORCE_IDLE)
+ bat_led_set_color(
+ (battery_ticks & 0x4) ? LED_AMBER : LED_OFF);
+ break;
+ default:
+ /* Other states don't alter LED behavior */
+ break;
}
+}
+
+/* Called by hook task every 250mSec */
+static void led_tick(void)
+{
+ if (led_auto_control_is_enabled(EC_LED_ID_POWER_LED))
+ kip_led_set_power();
- /* Otherwise, system is off and AC not connected, LED off */
- set_color(LED_OFF);
+ if (led_auto_control_is_enabled(EC_LED_ID_BATTERY_LED))
+ kip_led_set_battery();
}
DECLARE_HOOK(HOOK_TICK, led_tick, HOOK_PRIO_DEFAULT);