diff options
author | Alec Berg <alecaberg@chromium.org> | 2015-02-17 18:16:43 -0800 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-02-20 03:00:07 +0000 |
commit | 279e2c6386e24dbbe8d9d8ad83556f065b4b1a20 (patch) | |
tree | 9b1fc4110af00b7bb88b4975e0d43ad3a355ae17 | |
parent | 02013f6aa3b5fbc64b15ec060e5fc5e87824353b (diff) | |
download | chrome-ec-279e2c6386e24dbbe8d9d8ad83556f065b4b1a20.tar.gz |
samus: add i2c retries to backlight control
Add i2c retries to backlight control. Also check return value,
if i2c transfer fails, do not continue.
Also modified backlight control so that we only send I2C commands
when backlight chip is enabled (in S0 and lid is open).
BUG=chrome-os-partner:36803
BRANCH=samus
TEST=test suspend/resume and booting and make sure panel always
comes up.
Change-Id: I0dd71c12d0c3f64a08fb389c37f64b1b0ac16fb8
Signed-off-by: Alec Berg <alecaberg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/250670
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
-rw-r--r-- | board/samus/panel.c | 84 |
1 files changed, 69 insertions, 15 deletions
diff --git a/board/samus/panel.c b/board/samus/panel.c index 6a8fa9ebe5..e29d0b9e60 100644 --- a/board/samus/panel.c +++ b/board/samus/panel.c @@ -11,8 +11,13 @@ #include "host_command.h" #include "i2c.h" #include "lid_switch.h" +#include "timer.h" + +#define CPRINTS(format, args...) cprints(CC_I2C, format, ## args) #define I2C_ADDR_BACKLIGHT ((0x2C << 1) | I2C_FLAG_BIG_ENDIAN) +#define I2C_RETRIES 3 +#define I2C_RETRY_DELAY (5*MSEC) #define LP8555_REG_COMMAND 0x00 #define LP8555_REG_COMMAND_ON 0x01 @@ -50,38 +55,87 @@ #define LP8555_REG_STEP_SMOOTH_MEDIUM (2 << 6) #define LP8555_REG_STEP_SMOOTH_HEAVY (3 << 6) +/* Read from lp8555 with automatic i2c retries */ +static int lp8555_read_with_retry(int reg, int *data) +{ + int i, rv; + + for (i = 0; i < I2C_RETRIES; i++) { + rv = i2c_read8(I2C_PORT_BACKLIGHT, I2C_ADDR_BACKLIGHT, + reg, data); + if (rv == EC_SUCCESS) + return EC_SUCCESS; + usleep(I2C_RETRY_DELAY); + } + + CPRINTS("Backlight read fail: reg 0x%02x", reg); + return rv; +} + +/* Write to lp8555 with automatic i2c retries */ +static int lp8555_write_with_retry(int reg, int data) +{ + int i, rv; + + for (i = 0; i < I2C_RETRIES; i++) { + rv = i2c_write8(I2C_PORT_BACKLIGHT, I2C_ADDR_BACKLIGHT, + reg, data); + if (rv == EC_SUCCESS) + return EC_SUCCESS; + usleep(I2C_RETRY_DELAY); + } + + CPRINTS("Backlight write fail: reg 0x%02x data %d", reg, data); + return rv; +} + /** * Setup backlight controller and turn it on. */ static void lp8555_enable_pwm_mode(void) { int reg; + int rv; + + /* + * If not in S0, then PCH backlight enable will not be on, and if + * lid is closed EC backlight enable will not be on. Since these + * two signals are AND'ed together, no point in trying to talk to + * the lp8555 if either one of them is not true. + */ + if (!chipset_in_state(CHIPSET_STATE_ON) || !lid_is_open()) + return; /* Enable PWM mode. */ - i2c_read8(I2C_PORT_BACKLIGHT, I2C_ADDR_BACKLIGHT, - LP8555_REG_CONFIG, ®); + rv = lp8555_read_with_retry(LP8555_REG_CONFIG, ®); + if (rv != EC_SUCCESS) + return; reg &= ~LP8555_REG_CONFIG_MODE_MASK; reg |= LP8555_REG_CONFIG_MODE_PWM; - i2c_write8(I2C_PORT_BACKLIGHT, I2C_ADDR_BACKLIGHT, - LP8555_REG_CONFIG, reg); + rv = lp8555_write_with_retry(LP8555_REG_CONFIG, reg); + if (rv != EC_SUCCESS) + return; /* Set max LED current to 23mA. */ - i2c_write8(I2C_PORT_BACKLIGHT, I2C_ADDR_BACKLIGHT, - LP8555_REG_CURRENT, LP8555_REG_CURRENT_MAXCURR_23MA); + rv = lp8555_write_with_retry(LP8555_REG_CURRENT, + LP8555_REG_CURRENT_MAXCURR_23MA); + if (rv != EC_SUCCESS) + return; /* Set the rate of brightness change. */ - i2c_write8(I2C_PORT_BACKLIGHT, I2C_ADDR_BACKLIGHT, - LP8555_REG_STEP, - LP8555_REG_STEP_STEP_200MS | - LP8555_REG_STEP_PWM_IN_HYST_8LSB | - LP8555_REG_STEP_SMOOTH_HEAVY); + rv = lp8555_write_with_retry(LP8555_REG_STEP, + LP8555_REG_STEP_STEP_200MS | + LP8555_REG_STEP_PWM_IN_HYST_8LSB | + LP8555_REG_STEP_SMOOTH_HEAVY); + if (rv != EC_SUCCESS) + return; /* Power on. */ - i2c_read8(I2C_PORT_BACKLIGHT, I2C_ADDR_BACKLIGHT, - LP8555_REG_COMMAND, ®); + rv = lp8555_read_with_retry(LP8555_REG_COMMAND, ®); + if (rv != EC_SUCCESS) + return; reg |= LP8555_REG_COMMAND_ON; - i2c_write8(I2C_PORT_BACKLIGHT, I2C_ADDR_BACKLIGHT, - LP8555_REG_COMMAND, reg); + rv = lp8555_write_with_retry(LP8555_REG_COMMAND, reg); } DECLARE_DEFERRED(lp8555_enable_pwm_mode); |