summaryrefslogtreecommitdiff
path: root/driver/battery
diff options
context:
space:
mode:
authorJonathan Brandmeyer <jbrandmeyer@chromium.org>2018-08-03 13:24:06 -0600
committerchrome-bot <chrome-bot@chromium.org>2018-08-08 04:29:20 -0700
commitb80693e94e6e9aa0a382c39c20efba6f2c7403a9 (patch)
treeb44a8b48858906c6f8a3875b6a69d7c2b6908ddc /driver/battery
parent5d2cdcab232748095d1efeb4e5c0fc23b13adb67 (diff)
downloadchrome-ec-b80693e94e6e9aa0a382c39c20efba6f2c7403a9.tar.gz
battery: Optionally prevent boot at low SOC with cell imbalance.
Measure the cell imbalance with method dispatch to a per-battery method, such that families with a plurality of configurable batteries can support them all. By default, cell imbalance is taken to be 'zero' in case we don't support that battery's management IC. Provide a driver for reading cell voltages for the TI BQ4050 family. This IC is quite popular, but by no means universal. BUG=b:111214767 BRANCH=none TEST=Boot on Careena with a custom debug print statement, showing that we can measure the typical battery voltages during and after the boot at the battery status polling interval. Change-Id: I235389b252ac9c373aa9706dbd1066f7c0bbce71 Signed-off-by: Jonathan Brandmeyer <jbrandmeyer@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1162663 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Diffstat (limited to 'driver/battery')
-rw-r--r--driver/battery/bq4050.c39
-rw-r--r--driver/battery/smart.c5
2 files changed, 44 insertions, 0 deletions
diff --git a/driver/battery/bq4050.c b/driver/battery/bq4050.c
new file mode 100644
index 0000000000..6f2890ff2d
--- /dev/null
+++ b/driver/battery/bq4050.c
@@ -0,0 +1,39 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Smart battery driver for TI BQ4050 family, including BQ40Z50 (and -R1, -R2)
+ * and BQ40Z552.
+ */
+
+#include "battery_smart.h"
+#include "util.h"
+
+#include <stdint.h>
+
+int battery_bq4050_imbalance_mv(void)
+{
+ /*
+ * The BQ4050 family can manage up to four cells. In testing it always
+ * returns a voltage for each cell, regardless of the number of cells
+ * actually installed in the pack. Unpopulated cells read exactly zero.
+ */
+ static const uint8_t cell_voltage_address[4] = {
+ 0x3c, 0x3d, 0x3e, 0x3f
+ };
+ int i, res, cell_voltage;
+ int n_cells = 0;
+ int max_voltage = 0;
+ int min_voltage = 0xffff;
+
+ for (i = 0; i != ARRAY_SIZE(cell_voltage_address); ++i) {
+ res = sb_read(cell_voltage_address[i], &cell_voltage);
+ if (res == EC_SUCCESS && cell_voltage != 0) {
+ n_cells++;
+ max_voltage = MAX(max_voltage, cell_voltage);
+ min_voltage = MIN(min_voltage, cell_voltage);
+ }
+ }
+ return (n_cells == 0) ? 0 : max_voltage - min_voltage;
+}
+
diff --git a/driver/battery/smart.c b/driver/battery/smart.c
index 743ebc1ee1..0ae35a5fba 100644
--- a/driver/battery/smart.c
+++ b/driver/battery/smart.c
@@ -351,6 +351,11 @@ void battery_get_params(struct batt_params *batt)
if ((batt_new.flags & BATT_FLAG_BAD_ANY) != BATT_FLAG_BAD_ANY)
batt_new.flags |= BATT_FLAG_RESPONSIVE;
+#ifdef CONFIG_BATTERY_MEASURE_IMBALANCE
+ if (battery_imbalance_mv() > CONFIG_BATTERY_MAX_IMBALANCE_MV)
+ batt_new.flags |= BATT_FLAG_IMBALANCED_CELL;
+#endif
+
#if defined(CONFIG_BATTERY_PRESENT_CUSTOM) || \
defined(CONFIG_BATTERY_PRESENT_GPIO)
/* Hardware can tell us for certain */