summaryrefslogtreecommitdiff
path: root/driver/charger/bq25710.c
diff options
context:
space:
mode:
authorScott Collyer <scollyer@google.com>2019-05-14 17:22:01 -0700
committerchrome-bot <chrome-bot@chromium.org>2019-05-21 14:20:40 -0700
commita8f20b538784156db4c57793798894bdd0f472c8 (patch)
tree834f6fc509ec8fd1d7bd08d99c5688bd75f2a9b5 /driver/charger/bq25710.c
parent1df7f1fb8b60d3a9314f354eae23db1674704a94 (diff)
downloadchrome-ec-a8f20b538784156db4c57793798894bdd0f472c8.tar.gz
bq25710: Allow IDCHG to be used as a prochot trigger
Kohaku units are currently using a 2S+1P battery back which is not able to provide sufficient power for peak CPU load when running on battery only. The bq25710 has various triggers for prochot and one of those is IDCHG (battery discharge current). This CL adds a new config option CONFIG_CHARGER_BQ25710_IDCHG_LIMIT_MA to enable this feature in the bq25710. For prochot to be active, the bq25710 must remain in performance mode. Chispet hooks are used to request the bq25710 in/out of performace mode when the IDCHG prochot feature is active. BUG=b:132285560 BRANCH=none TEST=Manual Connected wires to VBAT, PPVAR_SYS, PROCHOT_ODL signals and had a current probe connected to measure IBAT. Verfied that without this CL, VBAT shuts off when IBAT spikes. With this CL, then verified that prochot gets asserted whenever the current spikes to values specified by CONFIG_CHARGER_BQ25710_IDCHG_LIMIT_MA. In addition verified that with this CL, the system can successfully boot and remain powered on even as CPU load gets increased. Change-Id: If13d16f561b76289936d0d75a2b984d2b71b3c37 Signed-off-by: Scott Collyer <scollyer@google.com> Reviewed-on: https://chromium-review.googlesource.com/1613797 Commit-Ready: Scott Collyer <scollyer@chromium.org> Tested-by: Scott Collyer <scollyer@chromium.org> Legacy-Commit-Queue: Commit Bot <commit-bot@chromium.org> Reviewed-by: Tim Wawrzynczak <twawrzynczak@chromium.org>
Diffstat (limited to 'driver/charger/bq25710.c')
-rw-r--r--driver/charger/bq25710.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/driver/charger/bq25710.c b/driver/charger/bq25710.c
index 5deb59328b..5700a0325b 100644
--- a/driver/charger/bq25710.c
+++ b/driver/charger/bq25710.c
@@ -13,6 +13,7 @@
#include "console.h"
#include "hooks.h"
#include "i2c.h"
+#include "task.h"
#include "timer.h"
#ifndef CONFIG_CHARGER_NARROW_VDC
@@ -35,6 +36,16 @@
/* Console output macros */
#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args)
+#ifdef CONFIG_CHARGER_BQ25710_IDCHG_LIMIT_MA
+/*
+ * If this config option is defined, then the bq25710 needs to remain in
+ * performance mode when the AP is in S0. Performance mode is active whenever AC
+ * power is connected or when the EN_LWPWR bit in ChargeOption0 is clear.
+ */
+static uint32_t bq25710_perf_mode_req;
+static struct mutex bq25710_perf_mode_mutex;
+#endif
+
/* Charger parameters */
static const struct charger_info bq25710_charger_info = {
.name = "bq25710",
@@ -85,12 +96,30 @@ static int bq25710_set_low_power_mode(int enable)
if (rv)
return rv;
+#ifdef CONFIG_CHARGER_BQ25710_IDCHG_LIMIT_MA
+ mutex_lock(&bq25710_perf_mode_mutex);
+ /*
+ * Performance mode means not in low power mode. The bit that controls
+ * this is EN_LWPWR in ChargeOption0. The 'enable' param in this
+ * function is refeerring to low power mode, so enabling low power mode
+ * means disabling performance mode and vice versa.
+ */
+ if (enable)
+ bq25710_perf_mode_req &= ~(1 << task_get_current());
+ else
+ bq25710_perf_mode_req |= (1 << task_get_current());
+ enable = !bq25710_perf_mode_req;
+#endif
+
if (enable)
reg |= BQ25710_CHARGE_OPTION_0_LOW_POWER_MODE;
else
reg &= ~BQ25710_CHARGE_OPTION_0_LOW_POWER_MODE;
rv = raw_write16(BQ25710_REG_CHARGE_OPTION_0, reg);
+#ifdef CONFIG_CHARGER_BQ25710_IDCHG_LIMIT_MA
+ mutex_unlock(&bq25710_perf_mode_mutex);
+#endif
if (rv)
return rv;
@@ -175,6 +204,21 @@ static void bq25710_init(void)
* no battery is present prochot will continuosly be asserted.
*/
reg |= BQ25710_PROCHOT_PROFILE_VSYS;
+#ifdef CONFIG_CHARGER_BQ25710_IDCHG_LIMIT_MA
+ /*
+ * Set the IDCHG limit who's value is defined in the config
+ * option in mA. Also, enable IDCHG trigger for prochot.
+ */
+ reg &= ~BQ25710_PROCHOT_IDCHG_VTH_MASK;
+ /*
+ * IDCHG limit is in 512 mA steps. Note there is a 128 mA offset
+ * so the actual IDCHG limit will be the value stored in bits
+ * 15:10 + 128 mA.
+ */
+ reg |= ((CONFIG_CHARGER_BQ25710_IDCHG_LIMIT_MA << 1) &
+ BQ25710_PROCHOT_IDCHG_VTH_MASK);
+ reg |= BQ25710_PROCHOT_PROFILE_IDCHG;
+#endif
raw_write16(BQ25710_REG_PROCHOT_OPTION_1, reg);
}
@@ -484,6 +528,25 @@ error:
}
#endif /* CONFIG_CHARGE_RAMP_HW */
+#ifdef CONFIG_CHARGER_BQ25710_IDCHG_LIMIT_MA
+/* Called on AP S5 -> S3 and S3/S0iX -> S0 transition */
+static void bq25710_chipset_startup(void)
+{
+ bq25710_set_low_power_mode(0);
+}
+DECLARE_HOOK(HOOK_CHIPSET_STARTUP, bq25710_chipset_startup, HOOK_PRIO_DEFAULT);
+DECLARE_HOOK(HOOK_CHIPSET_RESUME, bq25710_chipset_startup, HOOK_PRIO_DEFAULT);
+
+
+/* Called on AP S0 -> S0iX/S3 or S3 -> S5 transition */
+static void bq25710_chipset_suspend(void)
+{
+ bq25710_set_low_power_mode(1);
+}
+DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, bq25710_chipset_suspend, HOOK_PRIO_DEFAULT);
+DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, bq25710_chipset_suspend, HOOK_PRIO_DEFAULT);
+#endif
+
#ifdef CONFIG_CMD_CHARGER_DUMP
static int console_bq25710_dump_regs(int argc, char **argv)
{