From 1866d471f496a4b6905332199f870cc45b7f2515 Mon Sep 17 00:00:00 2001 From: Vic Yang Date: Mon, 4 Mar 2013 15:38:32 +0800 Subject: spring: battery LED breath yellow on battery assist When in battery assit mode, show breathing yellow on battery LED slowly to indicate battery is actually discharging. BUG=chrome-os-partner:17561 TEST=Manual BRANCH=none Change-Id: I688470d8870b181bf2dd20b5ebcbd6e2d861c5b0 Signed-off-by: Vic Yang Reviewed-on: https://gerrit.chromium.org/gerrit/44514 Reviewed-by: Vincent Palatin --- board/spring/board.c | 72 +++++++++++++++++++++++++++++++++++++++++++++------- common/lp5562.c | 50 ++++++++++++++++++++++++++++++++++++ include/lp5562.h | 20 +++++++++++++++ 3 files changed, 133 insertions(+), 9 deletions(-) diff --git a/board/spring/board.c b/board/spring/board.c index da74c966ee..d7e7224bd2 100644 --- a/board/spring/board.c +++ b/board/spring/board.c @@ -31,10 +31,20 @@ #define HARD_RESET_TIMEOUT_MS 5 /* We use yellow LED instead of blue LED. Re-map colors here. */ +#define LED_COLOR_NONE LP5562_COLOR_NONE #define LED_COLOR_GREEN LP5562_COLOR_GREEN #define LED_COLOR_YELLOW LP5562_COLOR_BLUE #define LED_COLOR_RED LP5562_COLOR_RED +/* LED breathing program */ +uint8_t breathing_prog[] = {0x41, 0xff, /* 0x80 -> 0x0 */ + 0x41, 0x7f, /* 0x0 -> 0x80 */ + 0x7f, 0x00, /* Wait ~4s */ + 0x7f, 0x00, + 0x7f, 0x00, + 0x7f, 0x00, + 0x00, 0x00}; /* Repeat */ + /* GPIO interrupt handlers prototypes */ #ifndef CONFIG_TASK_GAIAPOWER #define gaia_power_event NULL @@ -299,11 +309,38 @@ int board_get_ac(void) adc_read_channel(ADC_CH_USB_VBUS_SNS) >= 4300; } +int board_led_breathing(int enabled) +{ + int ret = 0; + + if (!enabled) { + return lp5562_engine_control(LP5562_ENG_HOLD, + LP5562_ENG_HOLD, + LP5562_ENG_HOLD); + } + + ret |= lp5562_engine_load(LP5562_ENG_SEL_1, + breathing_prog, + sizeof(breathing_prog)); + ret |= lp5562_set_engine(LP5562_ENG_SEL_NONE, + LP5562_ENG_SEL_NONE, + LP5562_ENG_SEL_1); + ret |= lp5562_engine_control(LP5562_ENG_RUN, + LP5562_ENG_HOLD, + LP5562_ENG_HOLD); + + return ret; +} + int board_battery_led(enum charging_state state) { int current; int desired_current; - uint32_t color = LED_COLOR_RED; + static uint32_t color = LED_COLOR_RED; + static int breathing; + int new_color = LED_COLOR_RED; + int new_breathing = 0; + int ret = 0; /* * LED power is controlled by accessory detection. We only @@ -311,30 +348,47 @@ int board_battery_led(enum charging_state state) */ switch (state) { case ST_IDLE: - color = LED_COLOR_GREEN; + new_color = LED_COLOR_GREEN; + break; + case ST_DISCHARGING: + new_color = LED_COLOR_NONE; break; - case ST_DISCHARGING: /* Battery assist */ case ST_PRE_CHARGING: - color = LED_COLOR_YELLOW; + new_color = LED_COLOR_YELLOW; break; case ST_CHARGING: if (battery_current(¤t) || battery_desired_current(&desired_current)) { /* Cannot talk to the battery. Set LED to red. */ - color = LED_COLOR_RED; + new_color = LED_COLOR_RED; + break; + } + + if (current < 0 && desired_current > 0) { /* Battery assist */ + new_breathing = 1; + new_color = LED_COLOR_NONE; break; } + if (current && desired_current) - color = LED_COLOR_YELLOW; + new_color = LED_COLOR_YELLOW; else - color = LED_COLOR_GREEN; + new_color = LED_COLOR_GREEN; break; case ST_CHARGING_ERROR: - color = LED_COLOR_RED; + new_color = LED_COLOR_RED; break; } - return lp5562_set_color(color); + if (new_breathing != breathing) { + ret |= board_led_breathing(new_breathing); + breathing = new_breathing; + } + if (new_color != color) { + ret |= lp5562_set_color(new_color); + color = new_color; + } + return ret; } /*****************************************************************************/ diff --git a/common/lp5562.c b/common/lp5562.c index a4c0e85fd6..09ee0df2c5 100644 --- a/common/lp5562.c +++ b/common/lp5562.c @@ -21,6 +21,11 @@ inline int lp5562_write(uint8_t reg, uint8_t val) return i2c_write8(I2C_PORT_HOST, LP5562_I2C_ADDR, reg, val); } +inline int lp5562_read(uint8_t reg, int *val) +{ + return i2c_read8(I2C_PORT_HOST, LP5562_I2C_ADDR, reg, val); +} + int lp5562_set_color(uint32_t rgb) { int ret = 0; @@ -32,6 +37,51 @@ int lp5562_set_color(uint32_t rgb) return ret; } +int lp5562_set_engine(uint8_t r, uint8_t g, uint8_t b) +{ + return lp5562_write(LP5562_REG_LED_MAP, (r << 4) | (g << 2) | b); +} + +int lp5562_engine_load(int engine, uint8_t *program, int size) +{ + int prog_addr = LP5562_REG_ENG_PROG(engine); + int i, ret, val; + int shift = 6 - engine * 2; + + ret = lp5562_read(LP5562_REG_OP_MODE, &val); + if (ret) + return ret; + val &= ~(0x3 << shift); + val |= 0x1 << shift; + ret = lp5562_write(LP5562_REG_OP_MODE, val); + if (ret) + return ret; + + for (i = 0; i < size; ++i) { + ret = lp5562_write(prog_addr + i, program[i]); + if (ret) + return ret; + } + + val &= ~(0x3 << shift); + val |= 0x2 << shift; + ret = lp5562_write(LP5562_REG_OP_MODE, val); + + return ret; +} + +int lp5562_engine_control(int eng1, int eng2, int eng3) +{ + int ret, val; + + ret = lp5562_read(LP5562_REG_ENABLE, &val); + if (ret) + return ret; + val &= 0xc0; + val |= (eng1 << 4) | (eng2 << 2) | eng3; + return lp5562_write(LP5562_REG_ENABLE, val); +} + int lp5562_poweron(void) { int ret = 0; diff --git a/include/lp5562.h b/include/lp5562.h index 8bb8d71188..b993825c7a 100644 --- a/include/lp5562.h +++ b/include/lp5562.h @@ -26,10 +26,21 @@ #define LP5562_REG_W_CURRENT 0x0f #define LP5562_REG_LED_MAP 0x70 +#define LP5562_REG_ENG_PROG(n) (0x10 + ((n)-1) * 0x20) + +#define LP5562_COLOR_NONE 0x000000 #define LP5562_COLOR_RED 0x800000 #define LP5562_COLOR_GREEN 0x008000 #define LP5562_COLOR_BLUE 0x000080 +#define LP5562_ENG_SEL_NONE 0x0 +#define LP5562_ENG_SEL_1 0x1 +#define LP5562_ENG_SEL_2 0x2 +#define LP5562_ENG_SEL_3 0x3 + +#define LP5562_ENG_HOLD 0x0 +#define LP5562_ENG_RUN 0x2 + /* Power on and initialize LP5562. */ int lp5562_poweron(void); @@ -42,4 +53,13 @@ int lp5562_poweroff(void); */ int lp5562_set_color(uint32_t rgb); +/* Set lighting engine used by each color */ +int lp5562_set_engine(uint8_t r, uint8_t g, uint8_t b); + +/* Load lighting engine program */ +int lp5562_engine_load(int engine, uint8_t *program, int size); + +/* Control lighting engine execution state */ +int lp5562_engine_control(int eng1, int eng2, int eng3); + #endif /* LP5562_H */ -- cgit v1.2.1