summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2016-07-21 14:59:00 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-07-25 17:09:02 -0700
commit7369f0a68912dbd749271b79606c569071db0a13 (patch)
tree094f5fbe654c444aa8ee9b5f0ae39248c1bd56d1
parent3a7d749f2c72f44edc6c5d8b9597e95a5203bbc2 (diff)
downloadchrome-ec-7369f0a68912dbd749271b79606c569071db0a13.tar.gz
charger: bd99955: Adjust VSYS based on fast vs precharge state
Rohm suggests setting VSYS to the higher value during precharge and only setting it to the lower voltage after we have crossed the lower voltage. Note that the VSYS register also controls the pre vs fastcharge threshold, so setting VSYS to the lower voltage essentially enables fastcharge. BUG=chrome-os-partner:55524 BRANCH=None TEST=Manual on kevin, verify dead battery is able to charge through precharge to fastcharge. Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Change-Id: Ia5b953c8dfbb25970ab329d5487a317ad37ba609 Reviewed-on: https://chromium-review.googlesource.com/362442 Commit-Ready: Shawn N <shawnn@chromium.org> Tested-by: David Schneider <dnschneid@chromium.org> Reviewed-by: Vijay P Hiremath <vijay.p.hiremath@intel.com> Reviewed-by: Aseda Aboagye <aaboagye@chromium.org>
-rw-r--r--driver/charger/bd99955.c113
-rw-r--r--driver/charger/bd99955.h6
2 files changed, 109 insertions, 10 deletions
diff --git a/driver/charger/bd99955.c b/driver/charger/bd99955.c
index 11217428e5..260eba8945 100644
--- a/driver/charger/bd99955.c
+++ b/driver/charger/bd99955.c
@@ -553,19 +553,113 @@ int charger_get_status(int *status)
return EC_SUCCESS;
}
-int charger_set_mode(int mode)
+/*
+ * Track charging state and update VSYS / charge enable when needed.
+ * VSYS must be set to FASTCHARGE_VSYSREG when charging in fastcharge mode,
+ * and PRECHARGE_DISCHARGE_VSYSREG otherwise.
+ */
+enum bd99955_charge_update {
+ BD99955_UPDATE_STOP_CHARGING,
+ BD99955_UPDATE_START_CHARGING,
+ BD99955_UPDATE_BAT_VOLTAGE,
+};
+
+enum bd99955_charge_state {
+ BD99955_CHARGE_STATE_UNINITIALIZED,
+ BD99955_CHARGE_STATE_NOT_CHARGING,
+ BD99955_CHARGE_STATE_PRECHARGE,
+ BD99955_CHARGE_STATE_FASTCHARGE,
+};
+
+/*
+ * Update battery charge state of bd99955 based upon parameter which indicates
+ * type of change.
+ */
+static int bd99955_update_charge_state(enum bd99955_charge_update update)
{
+ static enum bd99955_charge_state charge_state =
+ BD99955_CHARGE_STATE_UNINITIALIZED;
+ enum bd99955_charge_state new_state;
int rv;
+ int bat_voltage = 0;
+
+ switch (update) {
+ case BD99955_UPDATE_STOP_CHARGING:
+ /* Transition directly to not charging state if asked */
+ new_state = BD99955_CHARGE_STATE_NOT_CHARGING;
+ break;
+ case BD99955_UPDATE_BAT_VOLTAGE:
+ /* Battery voltage change is irrelevant if we're not charging */
+ if (charge_state == BD99955_CHARGE_STATE_NOT_CHARGING) {
+ new_state = BD99955_CHARGE_STATE_NOT_CHARGING;
+ break;
+ }
+ /* Fall through */
+ case BD99955_UPDATE_START_CHARGING:
+ /* Transition to fast or precharge upon battery */
+ rv = ch_raw_read16(BD99955_CMD_VBAT_VAL, &bat_voltage,
+ BD99955_EXTENDED_COMMAND);
+
+ /* Assume we're in precharge range on read error */
+ if (rv)
+ bat_voltage = 0;
+ new_state = bat_voltage > FASTCHARGE_VSYSREG ?
+ BD99955_CHARGE_STATE_FASTCHARGE :
+ BD99955_CHARGE_STATE_PRECHARGE;
+ break;
+ default:
+ panic("Invalid update param");
+ }
+
+ if (new_state == charge_state)
+ return 0;
- if (mode & CHARGE_FLAG_INHIBIT_CHARGE) {
- rv = bd99955_set_vsysreg(DISCHARGE_VSYSREG);
- msleep(50);
+ CPRINTS("New bd99955 state: %d (%d mV)", new_state, bat_voltage);
+
+ switch (new_state) {
+ case BD99955_CHARGE_STATE_NOT_CHARGING:
+ /* Bring up vsys if necessary, then disable charging */
+ if (charge_state != BD99955_CHARGE_STATE_PRECHARGE) {
+ rv = bd99955_set_vsysreg(PRECHARGE_DISCHARGE_VSYSREG);
+ msleep(50);
+ }
rv |= bd99955_charger_enable(0);
- } else {
- rv = bd99955_charger_enable(1);
- msleep(1);
- rv |= bd99955_set_vsysreg(CHARGE_VSYSREG);
+ break;
+
+ case BD99955_CHARGE_STATE_PRECHARGE:
+ case BD99955_CHARGE_STATE_FASTCHARGE:
+ /*
+ * Enable charging if necessary, then bring down vsys if
+ * fastcharging.
+ */
+ if (charge_state != BD99955_CHARGE_STATE_PRECHARGE &&
+ charge_state != BD99955_CHARGE_STATE_FASTCHARGE) {
+ rv = bd99955_charger_enable(1);
+ msleep(1);
+ }
+ rv |= bd99955_set_vsysreg(
+ new_state == BD99955_CHARGE_STATE_PRECHARGE ?
+ PRECHARGE_DISCHARGE_VSYSREG :
+ FASTCHARGE_VSYSREG);
+ break;
+
+ default:
+ panic("Invalid bd99955 state");
}
+
+ charge_state = new_state;
+ return rv;
+}
+
+int charger_set_mode(int mode)
+{
+ int rv;
+
+ if (mode & CHARGE_FLAG_INHIBIT_CHARGE)
+ rv = bd99955_update_charge_state(BD99955_UPDATE_STOP_CHARGING);
+ else
+ rv = bd99955_update_charge_state(BD99955_UPDATE_START_CHARGING);
+
if (rv)
return rv;
@@ -594,6 +688,9 @@ int charger_set_current(int current)
{
int rv;
+ /* Switch between precharge and fastcharge if required */
+ bd99955_update_charge_state(BD99955_UPDATE_BAT_VOLTAGE);
+
/* Charge current step 64 mA */
current &= ~0x3F;
diff --git a/driver/charger/bd99955.h b/driver/charger/bd99955.h
index 214a20fd7b..a2b53bbbae 100644
--- a/driver/charger/bd99955.h
+++ b/driver/charger/bd99955.h
@@ -43,8 +43,10 @@ enum bd99955_charge_port {
#define BD99955_NO_BATTERY_CHARGE_I_MIN 512
/* VSYSREG settings */
-#define DISCHARGE_VSYSREG 8960
-#define CHARGE_VSYSREG 6144
+/* Setting for precharge charging and discharge */
+#define PRECHARGE_DISCHARGE_VSYSREG 8960
+/* Setting for fastcharge charging */
+#define FASTCHARGE_VSYSREG 6144
/* Battery Charger Commands */
#define BD99955_CMD_CHG_CURRENT 0x14