diff options
author | Louis Yung-Chieh Lo <yjlou@chromium.org> | 2014-04-24 13:34:59 -0700 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2014-04-25 03:41:58 +0000 |
commit | 3ac560d41bf8c225725cdf03c2b4f4d723739d0f (patch) | |
tree | 687b9335e739ffd62ffe910742bd8a87e987537a | |
parent | b0409436adcf68cda3bf70a2964b9fdee599189a (diff) | |
download | chrome-ec-3ac560d41bf8c225725cdf03c2b4f4d723739d0f.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>
Change-Id: Ied963c19d17d581ce99e4543469cf2fa165f0439
Reviewed-on: https://chromium-review.googlesource.com/196657
Tested-by: Yung-chieh Lo <yjlou@chromium.org>
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
Commit-Queue: Yung-chieh Lo <yjlou@chromium.org>
-rw-r--r-- | common/battery.c | 37 | ||||
-rw-r--r-- | common/charge_state_v2.c | 9 | ||||
-rw-r--r-- | common/i2c.c | 9 | ||||
-rw-r--r-- | driver/battery/smart.c | 33 | ||||
-rw-r--r-- | include/battery.h | 5 |
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 */ |