summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSue Chen <sue.chen@quanta.corp-partner.google.com>2020-08-19 12:15:14 +0800
committerCommit Bot <commit-bot@chromium.org>2020-08-22 06:09:39 +0000
commit61d40d6eaa88437d48e06fba9b773f7eb99f6ecc (patch)
tree3353784c4287d111061847900935fcea36d76296
parentc2c19821c41f0e20de1cc0c3f6103d338f868198 (diff)
downloadchrome-ec-61d40d6eaa88437d48e06fba9b773f7eb99f6ecc.tar.gz
Zork: Workaround for bad ISL9241 CONTROL1 read
Sometimes CONTROL1 was read 0xFF03 for unknown reason when the state change from S0 to S3, but the second read will get the correct 0x0103. Retry CONTROL1 read before update learn mode to make sure write the correct value. BUG=b:163076059 b:163136699 BRANCH=none TEST=none Signed-off-by: Sue Chen <sue.chen@quanta.corp-partner.google.com> Change-Id: Iec56dab838b0aa362c543cce74d64615faf40bfc Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2362386 Tested-by: Edward Hill <ecgh@chromium.org> Reviewed-by: Denis Brockus <dbrockus@chromium.org> Commit-Queue: Edward Hill <ecgh@chromium.org>
-rw-r--r--baseboard/zork/baseboard.c30
-rw-r--r--driver/charger/isl9241.c16
-rw-r--r--driver/charger/isl9241.h5
3 files changed, 46 insertions, 5 deletions
diff --git a/baseboard/zork/baseboard.c b/baseboard/zork/baseboard.c
index 5bd1faf16e..3546ed3f60 100644
--- a/baseboard/zork/baseboard.c
+++ b/baseboard/zork/baseboard.c
@@ -311,3 +311,33 @@ static int command_temps_log(int argc, char **argv)
DECLARE_CONSOLE_COMMAND(tempslog, command_temps_log,
"seconds",
"Print temp sensors periodically");
+/*
+ * b/163076059: Sometimes CONTROL1 reads as 0xFF03 for unknown reason
+ * when the state change from S0 to S3, but the second read will get
+ * the correct 0x0103. Retry CONTROL1 read before update learn mode
+ * to make sure write the correct value.
+ */
+__override int isl9241_update_learn_mode(int chgnum, int enable)
+{
+ int rv;
+ int i;
+ int reg;
+
+ /* Retry CONTROL1 read if high byte is 0xFF. */
+ for (i = 0; i < 10; i++) {
+ rv = isl9241_read(chgnum, ISL9241_REG_CONTROL1, &reg);
+ if (rv == EC_SUCCESS && (reg >> 8) != 0xFF)
+ break;
+ ccprints("isl9241 error: CONTROL1=0x%x (rv=%d i=%d)",
+ reg, rv, i);
+ if (rv)
+ return rv;
+ }
+
+ if (enable)
+ reg |= ISL9241_CONTROL1_LEARN_MODE;
+ else
+ reg &= ~ISL9241_CONTROL1_LEARN_MODE;
+
+ return isl9241_write(chgnum, ISL9241_REG_CONTROL1, reg);
+}
diff --git a/driver/charger/isl9241.c b/driver/charger/isl9241.c
index d6dbf395d8..7d724d24be 100644
--- a/driver/charger/isl9241.c
+++ b/driver/charger/isl9241.c
@@ -60,7 +60,7 @@ static const struct charger_info isl9241_charger_info = {
static enum ec_error_list isl9241_discharge_on_ac(int chgnum, int enable);
-static inline enum ec_error_list isl9241_read(int chgnum, int offset,
+inline enum ec_error_list isl9241_read(int chgnum, int offset,
int *value)
{
return i2c_read16(chg_chips[chgnum].i2c_port,
@@ -68,7 +68,7 @@ static inline enum ec_error_list isl9241_read(int chgnum, int offset,
offset, value);
}
-static inline enum ec_error_list isl9241_write(int chgnum, int offset,
+inline enum ec_error_list isl9241_write(int chgnum, int offset,
int value)
{
return i2c_write16(chg_chips[chgnum].i2c_port,
@@ -304,15 +304,21 @@ static enum ec_error_list isl9241_post_init(int chgnum)
return EC_SUCCESS;
}
+__overridable int isl9241_update_learn_mode(int chgnum, int enable)
+{
+ return isl9241_update(chgnum, ISL9241_REG_CONTROL1,
+ ISL9241_CONTROL1_LEARN_MODE,
+ (enable) ? MASK_SET : MASK_CLR);
+}
+
static enum ec_error_list isl9241_discharge_on_ac(int chgnum, int enable)
{
int rv;
mutex_lock(&control1_mutex);
- rv = isl9241_update(chgnum, ISL9241_REG_CONTROL1,
- ISL9241_CONTROL1_LEARN_MODE,
- (enable) ? MASK_SET : MASK_CLR);
+ rv = isl9241_update_learn_mode(chgnum, enable);
+
if (!rv)
learn_mode = enable;
diff --git a/driver/charger/isl9241.h b/driver/charger/isl9241.h
index 1110f11b8a..17e98cfaaf 100644
--- a/driver/charger/isl9241.h
+++ b/driver/charger/isl9241.h
@@ -122,6 +122,11 @@
extern const struct charger_drv isl9241_drv;
+enum ec_error_list isl9241_read(int chgnum, int offset,
+ int *value);
+enum ec_error_list isl9241_write(int chgnum, int offset,
+ int value);
+__override_proto int isl9241_update_learn_mode(int chgnum, int enable);
/**
* Set AC prochot threshold
*