summaryrefslogtreecommitdiff
path: root/driver/charger/sm5803.c
diff options
context:
space:
mode:
authorDiana Z <dzigterman@chromium.org>2020-08-07 10:57:28 -0600
committerCommit Bot <commit-bot@chromium.org>2020-08-11 20:24:38 +0000
commitd3ba2c4d0b2eeac179322f1ffd477130029e8e83 (patch)
tree3c9df4273a70a52bd69a72230535b38b781b77db /driver/charger/sm5803.c
parentc1231644fa6bfa46ff9867419d40a5d01dd00c14 (diff)
downloadchrome-ec-d3ba2c4d0b2eeac179322f1ffd477130029e8e83.tar.gz
SM5803: Flow 1 register updates
This commit adds: - bit names updated to the most recent SM5803A datasheet - centralized control of FLOW1 updates after init in one function - verification of charger register 0x5C contents before enabling charging - correction of init charger disable behavior BRANCH=None BUG=None TEST=on drawcia, observe that sink mode is enabled when charger is plugged in to MB, OTG bits are enabled with dongles plugged in Signed-off-by: Diana Z <dzigterman@chromium.org> Change-Id: I4e841e8288f85eeb8b4ee6afe953ea0f8df61fa0 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2343604 Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
Diffstat (limited to 'driver/charger/sm5803.c')
-rw-r--r--driver/charger/sm5803.c103
1 files changed, 75 insertions, 28 deletions
diff --git a/driver/charger/sm5803.c b/driver/charger/sm5803.c
index 59dcef0642..3950a94634 100644
--- a/driver/charger/sm5803.c
+++ b/driver/charger/sm5803.c
@@ -50,6 +50,7 @@ static struct mutex flow1_access_lock[CHARGER_NUM];
static int charger_vbus[CHARGER_NUM];
static int sm5803_is_sourcing_otg_power(int chgnum, int port);
+static enum ec_error_list sm5803_get_dev_id(int chgnum, int *id);
static inline enum ec_error_list chg_read8(int chgnum, int offset, int *value)
{
@@ -108,6 +109,49 @@ static inline enum ec_error_list test_update8(int chgnum, const int offset,
SM5803_ADDR_TEST_FLAGS, offset, mask, action);
}
+static enum ec_error_list sm5803_flow1_update(int chgnum, const uint8_t mask,
+ const enum mask_update_action action)
+{
+ int reg, rv, dev_id;
+
+ /*
+ * On Si rev 3, confirm that init value in 0x5C is intact before
+ * enabling charging.
+ */
+ rv = sm5803_get_dev_id(chgnum, &dev_id);
+ if (rv)
+ return rv;
+
+ if (dev_id == 0x03) {
+ rv = chg_read8(chgnum, 0x5C, &reg);
+ if (rv) {
+ CPRINTS("%s %d: Failed 0x5C read",
+ CHARGER_NAME, chgnum);
+ return rv;
+ }
+
+ if (reg != 0x7A) {
+ CPRINTS("%s %d: Unexpected 0x5C reg: 0x%02x. File bug",
+ CHARGER_NAME, chgnum, reg);
+
+ /* Fix it before enabling charging */
+ rv = chg_write8(chgnum, 0x5C, 0x7A);
+ }
+ }
+
+ /* Safety checks done, onto the actual register update */
+ mutex_lock(&flow1_access_lock[chgnum]);
+
+ rv = i2c_update8(chg_chips[chgnum].i2c_port,
+ chg_chips[chgnum].i2c_addr_flags,
+ SM5803_REG_FLOW1,
+ mask, action);
+
+ mutex_unlock(&flow1_access_lock[chgnum]);
+
+ return rv;
+}
+
int sm5803_is_vbus_present(int chgnum)
{
return charger_vbus[chgnum];
@@ -223,8 +267,7 @@ static void sm5803_init(int chgnum)
* No charger connected, disable CHG_EN
* (note other bits default to 0)
*/
- rv = chg_write8(chgnum, SM5803_FLOW1_CHG_EN,
- 0);
+ rv = chg_write8(chgnum, SM5803_REG_FLOW1, 0);
} else if (!sm5803_is_sourcing_otg_power(chgnum, chgnum)) {
charger_vbus[chgnum] = 1;
}
@@ -560,7 +603,9 @@ static enum ec_error_list sm5803_get_status(int chgnum, int *status)
if (rv)
return rv;
- if (!(reg & SM5803_FLOW1_CHG_EN))
+
+ if ((reg & SM5803_FLOW1_MODE) == CHARGER_MODE_DISABLED &&
+ !(reg & SM5803_FLOW1_LINEAR_CHARGE_EN))
*status |= CHARGER_CHARGE_INHIBITED;
return EC_SUCCESS;
@@ -569,11 +614,10 @@ static enum ec_error_list sm5803_get_status(int chgnum, int *status)
static enum ec_error_list sm5803_set_mode(int chgnum, int mode)
{
enum ec_error_list rv;
- int flow1_reg, flow2_reg;
+ int flow2_reg;
int dev_id;
rv = sm5803_get_dev_id(chgnum, &dev_id);
- mutex_lock(&flow1_access_lock[chgnum]);
/* New silicon version requires a new procedure to start charging. */
if ((dev_id >= 3) && (!(mode & CHARGE_FLAG_INHIBIT_CHARGE))) {
@@ -587,11 +631,8 @@ static enum ec_error_list sm5803_set_mode(int chgnum, int mode)
}
rv |= chg_read8(chgnum, SM5803_REG_FLOW2, &flow2_reg);
- rv |= chg_read8(chgnum, SM5803_REG_FLOW1, &flow1_reg);
- if (rv) {
- mutex_unlock(&flow1_access_lock[chgnum]);
+ if (rv)
return rv;
- }
/*
* Note: Charge may be enabled while OTG is enabled, but charge inhibit
@@ -599,18 +640,21 @@ static enum ec_error_list sm5803_set_mode(int chgnum, int mode)
* when battery is present.
*/
if (mode & CHARGE_FLAG_INHIBIT_CHARGE) {
- flow1_reg = 0;
+ rv |= sm5803_flow1_update(chgnum, 0xFF, MASK_CLR);
flow2_reg &= ~SM5803_FLOW2_AUTO_ENABLED;
} else {
- flow1_reg |= SM5803_FLOW1_CHG_EN;
+ /*
+ * TODO(b/163511546): SM5803: Consolidate flow control changes
+ *
+ * Should be a part of an initial sink enable function
+ */
+ rv |= sm5803_flow1_update(chgnum, CHARGER_MODE_SINK, MASK_SET);
if (battery_get_disconnect_state() == BATTERY_NOT_DISCONNECTED)
flow2_reg |= SM5803_FLOW2_AUTO_ENABLED;
}
- rv = chg_write8(chgnum, SM5803_REG_FLOW1, flow1_reg);
rv |= chg_write8(chgnum, SM5803_REG_FLOW2, flow2_reg);
- mutex_unlock(&flow1_access_lock[chgnum]);
return rv;
}
@@ -754,8 +798,12 @@ static enum ec_error_list sm5803_set_option(int chgnum, int option)
enum ec_error_list rv;
int reg;
+ mutex_lock(&flow1_access_lock[chgnum]);
+
reg = option & 0xFF;
rv = chg_write8(chgnum, SM5803_REG_FLOW1, reg);
+
+ mutex_unlock(&flow1_access_lock[chgnum]);
if (rv)
return rv;
@@ -820,13 +868,6 @@ static enum ec_error_list sm5803_enable_otg_power(int chgnum, int enabled)
reg &= ~SM5803_PHOT1_VBUS_MON_EN;
rv |= chg_write8(chgnum, SM5803_REG_PHOT1, reg);
- mutex_lock(&flow1_access_lock[chgnum]);
- rv |= chg_read8(chgnum, SM5803_REG_FLOW1, &reg);
- if (rv) {
- mutex_unlock(&flow1_access_lock[chgnum]);
- return rv;
- }
-
/*
* Enable: CHG_EN - turns on buck-boost
* VBUSIN_DISCH_EN - enable discharge on Vbus
@@ -837,14 +878,20 @@ static enum ec_error_list sm5803_enable_otg_power(int chgnum, int enabled)
* disabled through set_mode.
*/
if (enabled)
- reg |= (SM5803_FLOW1_CHG_EN | SM5803_FLOW1_VBUSIN_DISCHG_EN |
- SM5803_FLOW1_DIRECTCHG_SRC_EN);
+ rv = sm5803_flow1_update(chgnum, CHARGER_MODE_SOURCE |
+ SM5803_FLOW1_DIRECTCHG_SRC_EN,
+ MASK_SET);
else
- reg &= ~(SM5803_FLOW1_VBUSIN_DISCHG_EN |
- SM5803_FLOW1_DIRECTCHG_SRC_EN);
+ /*
+ * TODO(b/163511546): SM5803: Consolidate flow control changes
+ *
+ * May be able to disable mode entirely if PD task usage remains
+ * consistent.
+ */
+ rv = sm5803_flow1_update(chgnum, BIT(1) |
+ SM5803_FLOW1_DIRECTCHG_SRC_EN,
+ MASK_CLR);
- rv = chg_write8(chgnum, SM5803_REG_FLOW1, reg);
- mutex_unlock(&flow1_access_lock[chgnum]);
return rv;
}
@@ -857,8 +904,8 @@ static int sm5803_is_sourcing_otg_power(int chgnum, int port)
if (rv)
return 0;
- reg &= (SM5803_FLOW1_CHG_EN | SM5803_FLOW1_VBUSIN_DISCHG_EN);
- return reg == (SM5803_FLOW1_CHG_EN | SM5803_FLOW1_VBUSIN_DISCHG_EN);
+ reg &= SM5803_FLOW1_MODE;
+ return reg == CHARGER_MODE_SOURCE;
}
#ifdef CONFIG_CMD_CHARGER_DUMP