diff options
author | Aseda Aboagye <aaboagye@google.com> | 2020-12-03 01:03:29 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-12-10 00:47:32 +0000 |
commit | 3625c3c9ff9e94583f80b199668ec34f6124c720 (patch) | |
tree | 78edfdbb21914aa0826890e225ff223e17164286 /driver/charger/sm5803.c | |
parent | 87c58967cf0fd5f4c7af1f434ba0c112afb71d3c (diff) | |
download | chrome-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/sm5803.c')
-rw-r--r-- | driver/charger/sm5803.c | 65 |
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, ®val); + 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, ®val); + 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, ®val); + 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, |