diff options
author | Ben Chen <ben.chen2@quanta.corp-partner.google.com> | 2019-01-29 14:05:30 +0800 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2019-02-13 02:07:16 +0000 |
commit | 429b5477f39242c39876867db6fa271183ec0a2d (patch) | |
tree | 22ccba63640da96704381d296c2698e42b2e9fcb | |
parent | b60a51a20df1f4df0026a3683bb115d7b5e2c3f7 (diff) | |
download | chrome-ec-429b5477f39242c39876867db6fa271183ec0a2d.tar.gz |
Scarlet: Battery swelling potection
Change charge voltage for aged battery (based on cycle count)
Change charge voltage for long duration charging (AC-IN > 48 hrs)
BRANCH=scarlet
BUG=b:118799175
TEST=modify cycle count manually as 300/600/1000:
the charge voltages match the table: 4376/4320/4300mV.
TEST=plug in AC for longer than 48hrs: the charge voltage is 4.25V.
Change-Id: I27660d0efff9724657e9fcfaee8edee1bf619eb8
Signed-off-by: Ben Chen <ben.chen2@quanta.corp-partner.google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/1442392
Reviewed-by: Philip Chen <philipchen@chromium.org>
Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
Commit-Queue: Philip Chen <philipchen@chromium.org>
Tested-by: Philip Chen <philipchen@chromium.org>
Trybot-Ready: Philip Chen <philipchen@chromium.org>
-rw-r--r-- | board/scarlet/battery.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/board/scarlet/battery.c b/board/scarlet/battery.c index 33e746b464..abda04572c 100644 --- a/board/scarlet/battery.c +++ b/board/scarlet/battery.c @@ -17,6 +17,7 @@ #include "gpio.h" #include "hooks.h" #include "system.h" +#include "timer.h" #include "usb_pd.h" #include "util.h" @@ -31,8 +32,10 @@ #define TEMP_OUT_OF_RANGE TEMP_ZONE_COUNT #define BAT_LEVEL_PD_LIMIT 85 +#define AC_IN_TIMEOUT_US (48*HOUR) static uint8_t batt_id = 0xff; +static uint64_t acin_start_time; /* Do not change the enum values. We directly use strap gpio level to index. */ enum battery_type { @@ -129,6 +132,41 @@ enum battery_disconnect_state battery_get_disconnect_state(void) return BATTERY_DISCONNECTED; } +static struct { + int cycle_max; + int desired_voltage; +} cycle_zones[] = { + {300, 4376}, + {600, 4320}, + {1000, 4300}, + {INT32_MAX, 4250}, +}; + +void charge_cycle_lcv(struct charge_state_data *curr) +{ + int bat_cycle; + int cycle_zone; + + /* Cycle Count */ + battery_cycle_count(&bat_cycle); + + for (cycle_zone = 0; cycle_zone < ARRAY_SIZE(cycle_zones) - 1; + cycle_zone++) { + if (bat_cycle <= cycle_zones[cycle_zone].cycle_max) + break; + } + + curr->requested_voltage = MIN(curr->requested_voltage, + cycle_zones[cycle_zone].desired_voltage); +} + +/* Return 1 if AC plugged in for longer than 48 hours, return 0 otherwise. */ +static int ac_charge_timeout(void) +{ + return acin_start_time && + (get_time().val - acin_start_time > AC_IN_TIMEOUT_US); +} + int charger_profile_override(struct charge_state_data *curr) { /* battery temp in 0.1 deg C */ @@ -247,6 +285,13 @@ int charger_profile_override(struct charge_state_data *curr) break; } + /* Limit max charge voltage based on cycle count */ + charge_cycle_lcv(curr); + + /* Limit max charge voltage for long duration charging */ + if (ac_charge_timeout() && batt_id == BATTERY_SIMPLO) + curr->requested_voltage = MIN(curr->requested_voltage, 4250); + /* * When the charger says it's done charging, even if fuel gauge says * SOC < BATTERY_LEVEL_NEAR_FULL, we'll overwrite SOC with @@ -272,6 +317,8 @@ int charger_profile_override(struct charge_state_data *curr) static void board_protection_reset(void) { enable_idle(); + + acin_start_time = extpower_is_present() ? get_time().val : 0; } DECLARE_HOOK(HOOK_AC_CHANGE, board_protection_reset, HOOK_PRIO_DEFAULT); |