summaryrefslogtreecommitdiff
path: root/driver/charger
diff options
context:
space:
mode:
authorAseda Aboagye <aaboagye@google.com>2020-12-03 01:03:29 -0800
committerCommit Bot <commit-bot@chromium.org>2020-12-10 00:47:32 +0000
commit3625c3c9ff9e94583f80b199668ec34f6124c720 (patch)
tree78edfdbb21914aa0826890e225ff223e17164286 /driver/charger
parent87c58967cf0fd5f4c7af1f434ba0c112afb71d3c (diff)
downloadchrome-ec-3625c3c9ff9e94583f80b199668ec34f6124c720.tar.gz
sm5803: Add linear charge support
The SM5803 supports manipulating the BFET in the linear region. This will be used for the precharge portion of the charge curve in OCPC systems. This commit adds support for the linear charge feature for the charger IC. BUG=b:174683659 BRANCH=dedede TEST=With other changes, build and flash drawcia, charge from subboard on depleted battery and verify that linear charging is taking place according to precharge current limits. Signed-off-by: Aseda Aboagye <aaboagye@google.com> Change-Id: Ib3c7f14e127b89301cccc6e93848da9249232678 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2570938 Commit-Queue: Aseda Aboagye <aaboagye@chromium.org> Tested-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Diana Z <dzigterman@chromium.org>
Diffstat (limited to 'driver/charger')
-rw-r--r--driver/charger/sm5803.c65
1 files changed, 64 insertions, 1 deletions
diff --git a/driver/charger/sm5803.c b/driver/charger/sm5803.c
index 525492f47c..dec74093c6 100644
--- a/driver/charger/sm5803.c
+++ b/driver/charger/sm5803.c
@@ -63,11 +63,19 @@ struct {
/* Port to restart charging on */
static int active_restart_port = CHARGE_PORT_NONE;
+/*
+ * If powered from the sub board port, we need to attempt to enable the BFET
+ * before proceeding with charging.
+ */
+static int attempt_bfet_enable;
+
+
#define CHARGING_FAILURE_MAX_COUNT 5
#define CHARGING_FAILURE_INTERVAL MINUTE
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 enum ec_error_list sm5803_set_current(int chgnum, int current);
static inline enum ec_error_list chg_read8(int chgnum, int offset, int *value)
{
@@ -773,6 +781,58 @@ DECLARE_HOOK(HOOK_USB_PD_CONNECT,
sm5803_disable_runtime_low_power_mode,
HOOK_PRIO_FIRST);
+static enum ec_error_list sm5803_enable_linear_charge(int chgnum, bool enable)
+{
+ int rv;
+ int regval;
+ const struct battery_info *batt_info;
+
+ if (enable) {
+ /*
+ * We need to wait for the BFET enable attempt to complete,
+ * otherwise we may end up disabling linear charge.
+ */
+ if (!attempt_bfet_enable)
+ return EC_ERROR_TRY_AGAIN;
+ rv = main_write8(chgnum, 0x1F, 0x1);
+ rv |= test_write8(chgnum, 0x44, 0x20);
+ rv |= main_write8(chgnum, 0x1F, 0);
+
+ /*
+ * Precharge thresholds have already been set up as a part of
+ * init, however set fast charge current equal to the precharge
+ * current in case the battery moves beyond that threshold.
+ */
+ batt_info = battery_get_info();
+ rv |= sm5803_set_current(CHARGER_PRIMARY,
+ batt_info->precharge_current);
+
+ /* Enable linear charge mode. */
+ rv |= sm5803_flow1_update(chgnum,
+ SM5803_FLOW1_LINEAR_CHARGE_EN,
+ MASK_SET);
+ rv |= chg_read8(chgnum, SM5803_REG_FLOW3, &regval);
+ regval |= BIT(6) | BIT(5) | BIT(4);
+ rv |= chg_write8(chgnum, SM5803_REG_FLOW3, regval);
+ } else {
+ rv = sm5803_flow1_update(chgnum,
+ SM5803_FLOW1_LINEAR_CHARGE_EN,
+ MASK_CLR);
+ rv |= sm5803_flow2_update(chgnum,
+ SM5803_FLOW2_AUTO_ENABLED,
+ MASK_CLR);
+ rv |= chg_read8(chgnum, SM5803_REG_FLOW3, &regval);
+ regval &= ~(BIT(6) | BIT(5) | BIT(4) |
+ SM5803_FLOW3_SWITCH_BCK_BST);
+ rv |= chg_write8(chgnum, SM5803_REG_FLOW3, regval);
+ rv |= chg_read8(chgnum, SM5803_REG_SWITCHER_CONF, &regval);
+ regval |= SM5803_SW_BCK_BST_CONF_AUTO;
+ rv |= chg_write8(chgnum, SM5803_REG_SWITCHER_CONF, regval);
+ }
+
+ return rv;
+}
+
static void sm5803_enable_runtime_low_power_mode(void)
{
enum ec_error_list rv;
@@ -1194,7 +1254,6 @@ static enum ec_error_list sm5803_set_voltage(int chgnum, int voltage)
{
enum ec_error_list rv;
int regval;
- static int attempt_bfet_enable;
regval = SM5803_VOLTAGE_TO_REG(voltage);
@@ -1227,6 +1286,9 @@ static enum ec_error_list sm5803_set_voltage(int chgnum, int voltage)
attempt_bfet_enable = 1;
sm5803_vbus_sink_enable(chgnum, 1);
}
+ /* There's no need to attempt it if the BFET's already on. */
+ if (regval & SM5803_BATFET_ON)
+ attempt_bfet_enable = 1;
}
return rv;
@@ -1641,6 +1703,7 @@ const struct charger_drv sm5803_drv = {
.is_sourcing_otg_power = &sm5803_is_sourcing_otg_power,
.set_vsys_compensation = &sm5803_set_vsys_compensation,
.is_icl_reached = &sm5803_is_input_current_limit_reached,
+ .enable_linear_charge = &sm5803_enable_linear_charge,
#ifdef CONFIG_CHARGE_RAMP_HW
.set_hw_ramp = &sm5803_set_hw_ramp,
.ramp_is_stable = &sm5803_ramp_is_stable,