diff options
-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); |