google_battery: add logging for OVERHEAT
Log triggers of TEMP-DEFEND and DWELL-DEFEND in a separate voltage
tier.
Bug: 172006737
Test: triggered, checked the logs
Signed-off-by: AleX Pelosi <[email protected]>
Change-Id: Iba8474ea20671854312e5c9b004267b8ed823de8
Signed-off-by: Ken Tsou <[email protected]>
(cherry picked from commit ac6ca8a21b100a37e37dab93151af5f67a46e465)
diff --git a/google_battery.c b/google_battery.c
index 02766fe..1cff3dd 100644
--- a/google_battery.c
+++ b/google_battery.c
@@ -909,7 +909,12 @@
/* ------------------------------------------------------------------------- */
-/* msc_logic_health() sync ce_data->ce_health to batt_drv->chg_health */
+/*
+ * msc_logic_health() sync ce_data->ce_health to batt_drv->chg_health
+ * return -EINVAL when the device is not connected to power or when
+ * ttf_soc_estimate() return a negative value.
+ *
+ */
static int batt_ttf_estimate(ktime_t *res, const struct batt_drv *batt_drv)
{
qnum_t soc_raw = ssoc_get_real_raw(&batt_drv->ssoc_state);
@@ -958,6 +963,13 @@
/* ------------------------------------------------------------------------- */
+static void cev_ts_init(struct gbms_ce_tier_stats *stats, int8_t idx)
+{
+ stats->vtier_idx = idx;
+ stats->temp_idx = -1;
+ stats->soc_in = -1;
+}
+
/* CEV = Charging EVent */
static void cev_stats_init(struct gbms_charging_event *ce_data,
const struct gbms_chg_profile *profile)
@@ -975,24 +987,17 @@
ttf_soc_init(&ce_data->soc_stats);
ce_data->last_soc = -1;
- for (i = 0; i < GBMS_STATS_TIER_COUNT ; i++) {
- ce_data->tier_stats[i].vtier_idx = i;
- ce_data->tier_stats[i].temp_idx = -1;
- ce_data->tier_stats[i].soc_in = -1;
- }
+ for (i = 0; i < GBMS_STATS_TIER_COUNT ; i++)
+ cev_ts_init(&ce_data->tier_stats[i], i);
/* batt_chg_health_stats_close() will fix this */
- ce_data->health_stats.vtier_idx = GBMS_STATS_AC_TI_INVALID;
- ce_data->health_stats.temp_idx = -1;
- ce_data->health_stats.soc_in = -1;
+ cev_ts_init(&ce_data->health_stats, GBMS_STATS_AC_TI_INVALID);
- ce_data->full_charge_stats.vtier_idx = GBMS_STATS_AC_TI_FULL_CHARGE;
- ce_data->full_charge_stats.temp_idx = -1;
- ce_data->full_charge_stats.soc_in = -1;
+ cev_ts_init(&ce_data->full_charge_stats, GBMS_STATS_AC_TI_FULL_CHARGE);
+ cev_ts_init(&ce_data->high_soc_stats, GBMS_STATS_AC_TI_HIGH_SOC);
+ cev_ts_init(&ce_data->overheat_stats, GBMS_STATS_BD_TI_OVERHEAT_TEMP);
+ cev_ts_init(&ce_data->cc_lvl_stats, GBMS_STATS_BD_TI_CUSTOM_LEVELS);
- ce_data->high_soc_stats.vtier_idx = GBMS_STATS_AC_TI_HIGH_SOC;
- ce_data->high_soc_stats.temp_idx = -1;
- ce_data->high_soc_stats.soc_in = -1;
}
static void batt_chg_stats_start(struct batt_drv *batt_drv)
@@ -1081,14 +1086,14 @@
ktime_t elap, int cc,
struct gbms_ce_tier_stats *tier)
{
- const int msc_state = batt_drv->msc_state;
const uint16_t icl_settled = batt_drv->chg_state.f.icl;
- if (batt_drv->batt_health == POWER_SUPPLY_HEALTH_OVERHEAT)
- return;
-
- /* book to previous state */
- batt_chg_stats_tier(tier, msc_state, elap);
+ /*
+ * book time to previous msc_state for this tier, there is an
+ * interesting wrinkle here since some tiers (health, full, etc)
+ * might be entered and exited multiple times.
+ */
+ batt_chg_stats_tier(tier, batt_drv->msc_state, elap);
if (tier->soc_in == -1) {
int soc_in;
@@ -1166,8 +1171,9 @@
ktime_t elap)
{
const int soc_real = ssoc_get_real(&batt_drv->ssoc_state);
- const int msc_state = batt_drv->msc_state;
- struct gbms_ce_tier_stats *tier;
+ const int msc_state = batt_drv->msc_state; /* last msc_state */
+ struct gbms_charging_event *ce_data = &batt_drv->ce_data;
+ struct gbms_ce_tier_stats *tier = NULL;
int cc;
if (elap == 0)
@@ -1181,18 +1187,32 @@
}
cc = cc / 1000;
+ /* Update this charge tiers in parallel */
+ if (soc_real >= SSOC_HIGH_SOC)
+ batt_chg_stats_update_tier(batt_drv, temp_idx, ibatt_ma, temp,
+ elap, cc,
+ &ce_data->high_soc_stats);
+
+ /* TODO: log to new voltage tiers, list in go/pixel-vtier-defs */
if (batt_drv->batt_full) {
+
+
/* Override regular charge tiers when fully charged */
- tier = &batt_drv->ce_data.full_charge_stats;
+ batt_chg_stats_update_tier(batt_drv, temp_idx, ibatt_ma,
+ temp, elap, cc,
+ &ce_data->full_charge_stats);
} else if (msc_state == MSC_HEALTH) {
/*
- * works because msc_logic books the time BEFORE updating
- * msc_state
+ * It works because msc_logic call BEFORE updating msc_state.
+ * NOTE: that OVERHEAT and CCLVL disable AC, I should not be
+ * here if either of them are set.
*/
/* tier used for TTF during HC, check msc_logic_health() */
- tier = &batt_drv->ce_data.health_stats;
+ batt_chg_stats_update_tier(batt_drv, temp_idx, ibatt_ma,
+ temp, elap, cc,
+ &ce_data->health_stats);
} else {
const qnum_t soc = ssoc_get_capacity_raw(&batt_drv->ssoc_state);
@@ -1200,22 +1220,43 @@
/* book to previous soc unless discharging */
if (msc_state != MSC_DSG) {
/* TODO: should I use ssoc instead? */
- batt_chg_stats_soc_update(&batt_drv->ce_data, soc, elap,
+ batt_chg_stats_soc_update(ce_data, soc, elap,
tier_idx, cc);
}
- tier = &batt_drv->ce_data.tier_stats[tier_idx];
+ /*
+ * ce_data.tier_stats[tier_idx] are used for time to full.
+ * Do not book to them if we are in overheat or LVL
+ */
+ tier = &ce_data->tier_stats[tier_idx];
}
- batt_chg_stats_update_tier(batt_drv, temp_idx, ibatt_ma, temp, elap, cc,
- tier);
-
- /* Update this charge tier in parallel */
- if (soc_real >= SSOC_HIGH_SOC) {
+ /* batt_drv->batt_health is protected with chg_lock, */
+ if (batt_drv->batt_health == POWER_SUPPLY_HEALTH_OVERHEAT) {
batt_chg_stats_update_tier(batt_drv, temp_idx, ibatt_ma, temp,
elap, cc,
- &batt_drv->ce_data.high_soc_stats);
+ &ce_data->overheat_stats);
+ tier = NULL;
}
+
+ /* custom charge levels (DWELL-DEFEND or RETAIL) */
+ if (batt_drv->chg_state.f.flags & GBMS_CS_FLAG_CCLVL) {
+ batt_chg_stats_update_tier(batt_drv, temp_idx, ibatt_ma, temp,
+ elap, cc,
+ &ce_data->cc_lvl_stats);
+ tier = NULL;
+ }
+
+ /*
+ * Time/current spent in OVERHEAT or at CustomLevel should not
+ * be booked to ce_data.tier_stats[tier_idx]
+ */
+
+ if (!tier)
+ return;
+
+ batt_chg_stats_update_tier(batt_drv, temp_idx, ibatt_ma, temp,
+ elap, cc, tier);
}
static int batt_chg_health_vti(const struct batt_chg_health *chg_health)
@@ -1228,6 +1269,7 @@
switch (rest_state) {
/* battery defender did it */
case CHG_HEALTH_BD_DISABLED:
+ case CHG_HEALTH_CCLVL_DISABLED:
tier_idx = GBMS_STATS_AC_TI_DEFENDER;
break;
/* user disabled with deadline */
@@ -1604,17 +1646,25 @@
soc_in, soc_next);
}
- if (ce_data->full_charge_stats.soc_in != -1) {
+ if (ce_data->full_charge_stats.soc_in != -1)
len += batt_chg_tier_stats_cstr(&buff[len], size - len,
&ce_data->full_charge_stats,
verbose);
- }
- if (ce_data->high_soc_stats.soc_in != -1) {
+ if (ce_data->high_soc_stats.soc_in != -1)
len += batt_chg_tier_stats_cstr(&buff[len], size - len,
&ce_data->high_soc_stats,
verbose);
- }
+
+ if (ce_data->overheat_stats.soc_in != -1)
+ len += batt_chg_tier_stats_cstr(&buff[len], size - len,
+ &ce_data->overheat_stats,
+ verbose);
+
+ if (ce_data->cc_lvl_stats.soc_in != -1)
+ len += batt_chg_tier_stats_cstr(&buff[len], size - len,
+ &ce_data->cc_lvl_stats,
+ verbose);
return len;
}
@@ -2094,7 +2144,8 @@
* on disconnect batt_reset_rest_state() will set rest_state to
* CHG_HEALTH_USER_DISABLED if the deadline is negative.
*/
- if (rest_state == CHG_HEALTH_BD_DISABLED ||
+ if (rest_state == CHG_HEALTH_CCLVL_DISABLED ||
+ rest_state == CHG_HEALTH_BD_DISABLED ||
rest_state == CHG_HEALTH_USER_DISABLED ||
rest_state == CHG_HEALTH_DISABLED ||
rest_state == CHG_HEALTH_INACTIVE)
@@ -2104,7 +2155,13 @@
if (rest_state == CHG_HEALTH_DONE)
goto done_exit;
- /* disable AC because BD triggered */
+ /* disable AC because we are running custom charging levels */
+ if (batt_drv->chg_state.f.flags & GBMS_CS_FLAG_CCLVL) {
+ rest_state = CHG_HEALTH_CCLVL_DISABLED;
+ goto done_exit;
+ }
+
+ /* disable AC because BD-TEMP triggered */
if (batt_drv->batt_health == POWER_SUPPLY_HEALTH_OVERHEAT) {
rest_state = CHG_HEALTH_BD_DISABLED;
goto done_exit;