summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Chen <ben.chen2@quanta.corp-partner.google.com>2019-01-29 14:05:30 +0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2019-02-13 02:07:16 +0000
commit429b5477f39242c39876867db6fa271183ec0a2d (patch)
tree22ccba63640da96704381d296c2698e42b2e9fcb
parentb60a51a20df1f4df0026a3683bb115d7b5e2c3f7 (diff)
downloadchrome-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.c47
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);