summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/samus/panel.c84
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, &reg);
+ rv = lp8555_read_with_retry(LP8555_REG_CONFIG, &reg);
+ 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, &reg);
+ rv = lp8555_read_with_retry(LP8555_REG_COMMAND, &reg);
+ 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);