summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Collyer <scollyer@google.com>2018-01-18 14:31:30 -0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2018-01-23 22:32:02 +0000
commit67a02040c9ff465619d897e9aac453727eb8ea2c (patch)
tree9cc344109477cc53d0c4aaf2c948170e143d6088
parent3fc31d6e2bdb1d05a2990f2b8a046b56f539a723 (diff)
downloadchrome-ec-67a02040c9ff465619d897e9aac453727eb8ea2c.tar.gz
bd9995x: Clear VSYS_PRIORITY when Vbat > Vbat_min
VSYS_PRIORITY in the register VIN_CTRL_SET is set during bd9995x initialization to ensure VSYS remains up and stable during deeply discharged battery conditions. However, outside of this case, this bit should remain cleared. If set, there the input current limit is disabled between the time that the boost converter is enabled (USB_SUS = 0) and charging is enabled (CHG_EN = 1). This can lead to too much current being drawn which results in the connecting port shutting off VBUS due to its overcurrent protection. This has been observed when attempting to charge one DUT from another chromebook port, or with a Type C only charger. This CL adds a check in the bd99965x driver implementation of charger_get_voltage() that compares the current battery voltage to its minimum voltage. If it's higher, then it's not a deeply discharged battery and VSYS_PRIORITY can be cleared. BUG=chromium:69143827,71814128 BRANCH=coral,eve TEST=Tested with 2 Coral DUTs. Verified that VSYS_PRIORITY gets cleared when the charger state machine gets the charger parameters. Also verified that I can repeatedly initated charging from one Coral device to another. Without this fix, this would fail most of the of the time. Also tested Eve with deeply discharged battery to make sure the startup conditon still works. Change-Id: I5230560fa98e5bf16921eb4f2c70802eb962e7f3 Signed-off-by: Scott Collyer <scollyer@google.com> Reviewed-on: https://chromium-review.googlesource.com/875178 Commit-Ready: Scott Collyer <scollyer@chromium.org> Tested-by: Scott Collyer <scollyer@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> (cherry picked from commit f793f81b8b9bd82f14a18adf3f179df78a813261) Reviewed-on: https://chromium-review.googlesource.com/881587 Reviewed-by: Shawn N <shawnn@chromium.org> Commit-Queue: Scott Collyer <scollyer@chromium.org>
-rw-r--r--driver/charger/bd9995x.c45
1 files changed, 43 insertions, 2 deletions
diff --git a/driver/charger/bd9995x.c b/driver/charger/bd9995x.c
index 7f1a023830..6685708d18 100644
--- a/driver/charger/bd9995x.c
+++ b/driver/charger/bd9995x.c
@@ -54,6 +54,11 @@ static enum bd9995x_command charger_map_cmd = BD9995X_INVALID_COMMAND;
static struct mutex bd9995x_map_mutex;
+/* Tracks the state of VSYS_PRIORITY */
+static int vsys_priority;
+/* Mutex for VIN_CTRL_SET register */
+static struct mutex bd9995x_vin_mutex;
+
#ifdef HAS_TASK_USB_CHG
/* USB switch */
static enum usb_switch usb_switch_state[BD9995X_CHARGE_PORT_COUNT] = {
@@ -744,6 +749,36 @@ int charger_set_current(int current)
int charger_get_voltage(int *voltage)
{
+ if (vsys_priority) {
+ int batt_volt_measured;
+ int reg;
+ int rv;
+
+ /* Get battery voltage as reported by charger */
+ batt_volt_measured = bd9995x_get_battery_voltage();
+ if (batt_volt_measured > (battery_get_info()->voltage_min +
+ BD9995X_VSYS_PRECHARGE_OFFSET_MV)) {
+ /*
+ * Battery is not deeply discharged. Clear the
+ * VSYS_PRIORITY bit to ensure that input current limit
+ * is always active.
+ */
+ mutex_lock(&bd9995x_vin_mutex);
+ if (!ch_raw_read16(BD9995X_CMD_VIN_CTRL_SET, &reg,
+ BD9995X_EXTENDED_COMMAND)) {
+ reg &= ~BD9995X_CMD_VIN_CTRL_SET_VSYS_PRIORITY;
+ rv = ch_raw_write16(BD9995X_CMD_VIN_CTRL_SET,
+ reg,
+ BD9995X_EXTENDED_COMMAND);
+
+ /* Mirror the state of this bit */
+ if (!rv)
+ vsys_priority = 0;
+ }
+ mutex_unlock(&bd9995x_vin_mutex);
+ }
+ }
+
return ch_raw_read16(BD9995X_CMD_CHG_VOLTAGE, voltage,
BD9995X_BAT_CHG_COMMAND);
}
@@ -901,6 +936,8 @@ static void bd9995x_init(void)
reg |= BD9995X_CMD_VIN_CTRL_SET_VSYS_PRIORITY;
ch_raw_write16(BD9995X_CMD_VIN_CTRL_SET, reg,
BD9995X_EXTENDED_COMMAND);
+ /* Mirror the state of this bit */
+ vsys_priority = 1;
/* Define battery charging profile */
bd9995x_battery_charging_profile_settings();
@@ -1007,10 +1044,11 @@ int bd9995x_select_input_port(enum bd9995x_charge_port port, int select)
int rv;
int reg;
+ mutex_lock(&bd9995x_vin_mutex);
rv = ch_raw_read16(BD9995X_CMD_VIN_CTRL_SET, &reg,
BD9995X_EXTENDED_COMMAND);
if (rv)
- return rv;
+ goto select_input_port_exit;
if (select) {
if (port == BD9995X_CHARGE_PORT_VBUS) {
@@ -1039,8 +1077,11 @@ int bd9995x_select_input_port(enum bd9995x_charge_port port, int select)
panic("Invalid charge port");
}
- return ch_raw_write16(BD9995X_CMD_VIN_CTRL_SET, reg,
+ rv = ch_raw_write16(BD9995X_CMD_VIN_CTRL_SET, reg,
BD9995X_EXTENDED_COMMAND);
+select_input_port_exit:
+ mutex_unlock(&bd9995x_vin_mutex);
+ return rv;
}
#ifdef CONFIG_CHARGER_BATTERY_TSENSE