summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Yung-Chieh Lo <yjlou@chromium.org>2014-04-24 13:34:59 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-04-24 23:59:47 +0000
commitaa95ddb8b1a6ba8b163a16338cae33041f326376 (patch)
treeaa7b46ca98b7431194a70d51d06d78e26b2a7b49
parentaa87df83efbd966fa485e6ee85798f418cde7919 (diff)
downloadchrome-ec-aa95ddb8b1a6ba8b163a16338cae33041f326376.tar.gz
battery: don't talk to battery after cut-off
Add a shortcut in smart battery driver and i2c passthru. Once the battery cut-off order is submitted (in the factory line), the EC will no longer talk to battery. BUG=chrome-os-partner:28248 BRANCH=tot,nyan TEST=See below > remove AC, cutoff: expect system is off. > cutoff, then remove AC: expect system is off. > cutoff, wait for 1 min, then remove AC: expect system is off. Signed-off-by: Louis Yung-Chieh Lo <yjlou@chromium.org> (cherry picked from commit 401901a83bd8b876a1033742b838311ca584d2a9) Change-Id: Id8b1ed4e7d2745ccc2bf240f488de55855324f43 Original-Change-Id: I5ee56484d3c60f5e1c28dedf5785234bef176404 Reviewed-on: https://chromium-review.googlesource.com/196946 Reviewed-by: Yung-chieh Lo <yjlou@chromium.org> Commit-Queue: Yung-chieh Lo <yjlou@chromium.org> Tested-by: Yung-chieh Lo <yjlou@chromium.org>
-rw-r--r--common/battery.c37
-rw-r--r--common/charge_state_v2.c9
-rw-r--r--common/i2c.c9
-rw-r--r--driver/battery/smart.c33
-rw-r--r--include/battery.h5
5 files changed, 86 insertions, 7 deletions
diff --git a/common/battery.c b/common/battery.c
index 19ad2e49b8..b6e79bb383 100644
--- a/common/battery.c
+++ b/common/battery.c
@@ -9,12 +9,18 @@
#include "charge_state.h"
#include "common.h"
#include "console.h"
+#include "extpower.h"
#include "gpio.h"
+#include "hooks.h"
#include "host_command.h"
#include "timer.h"
#include "util.h"
#include "watchdog.h"
+#ifdef CONFIG_BATTERY_CUT_OFF
+static int is_cut_off;
+#endif
+
#ifdef CONFIG_BATTERY_PRESENT_GPIO
#ifdef CONFIG_BATTERY_PRESENT_CUSTOM
#error "Don't define both CONFIG_BATTERY_PRESENT_CUSTOM and" \
@@ -252,19 +258,44 @@ DECLARE_CONSOLE_COMMAND(battery, command_battery,
#ifdef CONFIG_BATTERY_CUT_OFF
-int battery_command_cut_off(struct host_cmd_handler_args *args)
+int battery_is_cut_off(void)
+{
+ return is_cut_off;
+}
+
+static void clean_cut_off(void)
+{
+ if (extpower_is_present())
+ is_cut_off = 0;
+}
+DECLARE_HOOK(HOOK_AC_CHANGE, clean_cut_off, HOOK_PRIO_DEFAULT);
+
+static int battery_command_cut_off(struct host_cmd_handler_args *args)
{
- return board_cut_off_battery();
+ int rv = board_cut_off_battery();
+ if (!rv)
+ is_cut_off = 1;
+
+ return rv;
}
DECLARE_HOST_COMMAND(EC_CMD_BATTERY_CUT_OFF, battery_command_cut_off,
EC_VER_MASK(0));
static int command_cutoff(int argc, char **argv)
{
- return board_cut_off_battery();
+ int rv = board_cut_off_battery();
+ if (!rv)
+ is_cut_off = 1;
+
+ return rv;
}
DECLARE_CONSOLE_COMMAND(cutoff, command_cutoff,
"",
"Cut off the battery output",
NULL);
+#else
+int battery_is_cut_off(void)
+{
+ return 0; /* Always return NOT cut off */
+}
#endif /* CONFIG_BATTERY_CUT_OFF */
diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c
index 36addbe332..a5a621da8b 100644
--- a/common/charge_state_v2.c
+++ b/common/charge_state_v2.c
@@ -620,12 +620,19 @@ wait_for_it:
/* Charger only accpets request when AC is on. */
if (curr.ac) {
/*
+ * Some batteries would wake up after cut-off if we keep
+ * charging it. Thus, we only charge when AC is on and
+ * battery is not cut off yet.
+ */
+ if (battery_is_cut_off())
+ charge_request(0, 0);
+ /*
* As a safety feature, some chargers will stop
* charging if we don't communicate with it frequently
* enough. In manual mode, we'll just tell it what it
* knows.
*/
- if (manual_mode) {
+ else if (manual_mode) {
charge_request(curr.chg.voltage,
curr.chg.current);
} else {
diff --git a/common/i2c.c b/common/i2c.c
index f5ce577aa2..8667bff1cf 100644
--- a/common/i2c.c
+++ b/common/i2c.c
@@ -5,6 +5,7 @@
/* I2C cross-platform code for Chrome EC */
+#include "battery.h"
#include "clock.h"
#include "console.h"
#include "host_command.h"
@@ -492,6 +493,14 @@ static int i2c_command_passthru(struct host_cmd_handler_args *args)
return EC_RES_ACCESS_DENIED;
#endif
+#ifdef CONFIG_BATTERY_CUT_OFF
+ /*
+ * Some batteries would wake up after cut-off if we talk to it.
+ */
+ if (battery_is_cut_off())
+ return EC_RES_ACCESS_DENIED;
+#endif
+
ret = check_i2c_params(args);
if (ret)
return ret;
diff --git a/driver/battery/smart.c b/driver/battery/smart.c
index d4c44eb813..3fda584910 100644
--- a/driver/battery/smart.c
+++ b/driver/battery/smart.c
@@ -24,14 +24,41 @@ test_mockable int sbc_write(int cmd, int param)
test_mockable int sb_read(int cmd, int *param)
{
+#ifdef CONFIG_BATTERY_CUT_OFF
+ /*
+ * Some batteries would wake up after cut-off if we talk to it.
+ */
+ if (battery_is_cut_off())
+ return EC_RES_ACCESS_DENIED;
+#endif
return i2c_read16(I2C_PORT_BATTERY, BATTERY_ADDR, cmd, param);
}
test_mockable int sb_write(int cmd, int param)
{
+#ifdef CONFIG_BATTERY_CUT_OFF
+ /*
+ * Some batteries would wake up after cut-off if we talk to it.
+ */
+ if (battery_is_cut_off())
+ return EC_RES_ACCESS_DENIED;
+#endif
return i2c_write16(I2C_PORT_BATTERY, BATTERY_ADDR, cmd, param);
}
+int sb_read_string(int port, int slave_addr, int offset, uint8_t *data,
+ int len)
+{
+#ifdef CONFIG_BATTERY_CUT_OFF
+ /*
+ * Some batteries would wake up after cut-off if we talk to it.
+ */
+ if (battery_is_cut_off())
+ return EC_RES_ACCESS_DENIED;
+#endif
+ return i2c_read_string(port, slave_addr, offset, data, len);
+}
+
int battery_get_mode(int *mode)
{
return sb_read(SB_BATTERY_MODE, mode);
@@ -192,21 +219,21 @@ test_mockable int battery_manufacture_date(int *year, int *month, int *day)
/* Read manufacturer name */
test_mockable int battery_manufacturer_name(char *dest, int size)
{
- return i2c_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
+ return sb_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
SB_MANUFACTURER_NAME, dest, size);
}
/* Read device name */
test_mockable int battery_device_name(char *dest, int size)
{
- return i2c_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
+ return sb_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
SB_DEVICE_NAME, dest, size);
}
/* Read battery type/chemistry */
test_mockable int battery_device_chemistry(char *dest, int size)
{
- return i2c_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
+ return sb_read_string(I2C_PORT_BATTERY, BATTERY_ADDR,
SB_DEVICE_CHEMISTRY, dest, size);
}
diff --git a/include/battery.h b/include/battery.h
index 4201d1d658..fc0c4bbcc5 100644
--- a/include/battery.h
+++ b/include/battery.h
@@ -275,4 +275,9 @@ int battery_manufacturer_date(int *year, int *month, int *day);
*/
int board_cut_off_battery(void);
+/**
+ * Return if the battery has been cut off.
+ */
+int battery_is_cut_off(void);
+
#endif /* __CROS_EC_BATTERY_H */