summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2014-07-18 17:09:37 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-07-23 02:29:59 +0000
commitb9677a48c81cc3b5074c532902076ff4ac64fe03 (patch)
treef3b3b0adb850d70d320ab142e88129cf09a369c0
parent4eee9fe42688e77c6c845a3904adb531a75f569a (diff)
downloadchrome-ec-b9677a48c81cc3b5074c532902076ff4ac64fe03.tar.gz
samus: Kick battery out of disconnect state when AC is attached
The Samus battery can be placed into a disconnect state by asserting a disconnect input signal. In this state, the battery will not function until a charging current is applied. This patch adds detection of the disconnect state. If a battery in disconnect state is found, a current is force-applied to the battery to kick it out of disconnect. BRANCH=None TEST=Manual on Samus. 1. Put battery into disconnect state 2. Pull AC, then reattach AC 3. Verify "found battery in disconnect state" is seen on the EC console. 4. Pull AC and verify that EC console is still accessable Also verify that battery gets out of reset state: 1. Pull AC 2. Issue "i2cxfer w16 0 0x16 0x0 0x12" command on EC console 3. Re-attach AC 4. Pull AC and verify that EC console is still accessable BUG=chrome-os-partner:29465 Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org> Change-Id: Ib4268887fb483094ac4e641749200268160d3014 Reviewed-on: https://chromium-review.googlesource.com/209013 Reviewed-by: Alec Berg <alecaberg@chromium.org> Commit-Queue: Alec Berg <alecaberg@chromium.org> Tested-by: Alec Berg <alecaberg@chromium.org>
-rw-r--r--board/samus/board.h1
-rw-r--r--common/charge_state_v2.c16
-rw-r--r--driver/battery/samus.c62
-rw-r--r--include/battery.h11
-rw-r--r--include/battery_smart.h14
-rw-r--r--include/config.h7
6 files changed, 111 insertions, 0 deletions
diff --git a/board/samus/board.h b/board/samus/board.h
index 2755eb3ff1..d6b41f408e 100644
--- a/board/samus/board.h
+++ b/board/samus/board.h
@@ -33,6 +33,7 @@
#define CONFIG_BATTERY_REQUESTS_NIL_WHEN_DEAD
#define CONFIG_CHARGER_PROFILE_OVERRIDE
#define CONFIG_BATTERY_SMART
+#define CONFIG_BATTERY_REVIVE_DISCONNECT
#define CONFIG_CHARGER
#define CONFIG_CHARGER_V2
#define CONFIG_CHARGER_BQ24773
diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c
index c44d05e096..a3d6384027 100644
--- a/common/charge_state_v2.c
+++ b/common/charge_state_v2.c
@@ -598,6 +598,22 @@ void charger_task(void)
batt_info->precharge_current;
} else
#endif
+#ifdef CONFIG_BATTERY_REVIVE_DISCONNECT
+ if (curr.requested_voltage == 0 &&
+ curr.requested_current == 0 &&
+ battery_get_disconnect_state() ==
+ BATTERY_DISCONNECTED) {
+ /*
+ * Battery is in disconnect state. Apply a
+ * current to kick it out of this state.
+ */
+ CPRINTS("found battery in disconnect state");
+ curr.requested_voltage =
+ batt_info->voltage_max;
+ curr.requested_current =
+ batt_info->precharge_current;
+ } else
+#endif
if (curr.state == ST_PRECHARGE ||
battery_seems_to_be_dead) {
CPRINTS("battery woke up");
diff --git a/driver/battery/samus.c b/driver/battery/samus.c
index de361b2d59..4c4f3480c4 100644
--- a/driver/battery/samus.c
+++ b/driver/battery/samus.c
@@ -5,9 +5,11 @@
* Battery pack vendor provided charging profile
*/
+#include "battery_smart.h"
#include "charge_state.h"
#include "console.h"
#include "ec_commands.h"
+#include "extpower.h"
#include "util.h"
static const struct battery_info info = {
@@ -152,3 +154,63 @@ DECLARE_CONSOLE_COMMAND(fastcharge, command_fastcharge,
NULL);
#endif /* CONFIG_CHARGER_PROFILE_OVERRIDE */
+
+#ifdef CONFIG_BATTERY_REVIVE_DISCONNECT
+/*
+ * Check if battery is in disconnect state, a state entered by pulling
+ * BATT_DISCONN_N low, and clear that state if we have external power plugged
+ * and no battery faults are detected. Disconnect state resembles battery
+ * shutdown mode, but extra steps must be taken to get the battery out of this
+ * mode.
+ */
+enum battery_disconnect_state battery_get_disconnect_state(void)
+{
+ uint8_t data[6];
+ int rv;
+ /*
+ * Take note if we find that the battery isn't in disconnect state,
+ * and always return NOT_DISCONNECTED without probing the battery.
+ * This assumes the battery will not go to disconnect state during
+ * runtime.
+ */
+ static int not_disconnected;
+
+ if (not_disconnected)
+ return BATTERY_NOT_DISCONNECTED;
+
+ if (extpower_is_present()) {
+ /* Check if battery charging + discharging is disabled. */
+ rv = sb_write(SB_MANUFACTURER_ACCESS, PARAM_OPERATION_STATUS);
+ if (rv)
+ return BATTERY_DISCONNECT_ERROR;
+
+ rv = sb_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
+ SB_ALT_MANUFACTURER_ACCESS, data, 6);
+
+ if (rv || !(data[3] & BATTERY_DISCHARGING_DISABLED) ||
+ !(data[3] & BATTERY_CHARGING_DISABLED)) {
+ not_disconnected = 1;
+ return BATTERY_NOT_DISCONNECTED;
+ }
+
+ /*
+ * Battery is neither charging nor discharging. Verify that
+ * we didn't enter this state due to a safety fault.
+ */
+ rv = sb_write(SB_MANUFACTURER_ACCESS, PARAM_SAFETY_STATUS);
+ if (rv)
+ return BATTERY_DISCONNECT_ERROR;
+
+ rv = sb_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
+ SB_ALT_MANUFACTURER_ACCESS, data, 6);
+
+ if (rv || data[2] || data[3] || data[4] || data[5])
+ return BATTERY_DISCONNECT_ERROR;
+ else
+ /* No safety fault -- clear disconnect state. */
+ return BATTERY_DISCONNECTED;
+ }
+ not_disconnected = 1;
+ return BATTERY_NOT_DISCONNECTED;
+}
+#endif /* CONFIG_BATTERY_REVIVE_DISCONNECT */
diff --git a/include/battery.h b/include/battery.h
index 898e3da403..18c84a37d3 100644
--- a/include/battery.h
+++ b/include/battery.h
@@ -49,6 +49,12 @@ enum battery_cutoff_states {
BATTERY_CUTOFF_STATE_PENDING,
};
+enum battery_disconnect_state {
+ BATTERY_DISCONNECTED = 0,
+ BATTERY_NOT_DISCONNECTED,
+ BATTERY_DISCONNECT_ERROR,
+};
+
/* Battery parameters */
struct batt_params {
int temperature; /* Temperature in 0.1 K */
@@ -320,4 +326,9 @@ int battery_wait_for_stable(void);
*/
void print_battery_debug(void);
+/**
+ * Get the disconnect state of the battery.
+ */
+enum battery_disconnect_state battery_get_disconnect_state(void);
+
#endif /* __CROS_EC_BATTERY_H */
diff --git a/include/battery_smart.h b/include/battery_smart.h
index 3e031b8f60..428608e5f4 100644
--- a/include/battery_smart.h
+++ b/include/battery_smart.h
@@ -56,6 +56,8 @@
#define SB_DEVICE_NAME 0x21
#define SB_DEVICE_CHEMISTRY 0x22
#define SB_MANUFACTURER_DATA 0x23
+/* Extention of smart battery spec, may not be supported on all platforms */
+#define SB_ALT_MANUFACTURER_ACCESS 0x44
/* Battery mode */
#define MODE_INTERNAL_CHARGE_CONTROLLER (1 << 0)
@@ -127,6 +129,14 @@
#define INFO_CHARGER_SPEC(INFO) ((INFO) & 0xf)
#define INFO_SELECTOR_SUPPORT(INFO) (((INFO) >> 4) & 1)
+/* Manufacturer Access parameters */
+#define PARAM_SAFETY_STATUS 0x51
+#define PARAM_OPERATION_STATUS 0x54
+/* Operation status masks -- 6 byte reply */
+/* reply[3] */
+#define BATTERY_DISCHARGING_DISABLED 0x20
+#define BATTERY_CHARGING_DISABLED 0x40
+
/* Read from charger */
int sbc_read(int cmd, int *param);
@@ -136,6 +146,10 @@ int sbc_write(int cmd, int param);
/* Read from battery */
int sb_read(int cmd, int *param);
+/* Read sequence from battery */
+int sb_read_string(int port, int slave_addr, int offset, uint8_t *data,
+ int len);
+
/* Write to battery */
int sb_write(int cmd, int param);
diff --git a/include/config.h b/include/config.h
index 0d1e1977df..641660da13 100644
--- a/include/config.h
+++ b/include/config.h
@@ -156,6 +156,13 @@
*/
#undef CONFIG_BATTERY_REQUESTS_NIL_WHEN_DEAD
+/*
+ * Check for battery in disconnect state (similar to cut-off state). If this
+ * battery is found to be in disconnect state, take it out of this state by
+ * force-applying a charge current.
+ */
+#undef CONFIG_BATTERY_REVIVE_DISCONNECT
+
/*****************************************************************************/
/*