google_battery: Add health dry run mode to allow for prediction based logging

Bug: 195470436
Signed-off-by: Stephane Lee <[email protected]>
Change-Id: Id541a07ffd660612ee70e52d1ab486c35e8d0a6e
(cherry picked from commit 6aa31d204633461b679baca5bcf33b0ec38775a7)
diff --git a/google_battery.c b/google_battery.c
index 97ba09a..0c4f0a0 100644
--- a/google_battery.c
+++ b/google_battery.c
@@ -1198,6 +1198,7 @@
 	/* batt_chg_health_stats_close() will fix this */
 	cev_ts_init(&ce_data->health_stats, GBMS_STATS_AC_TI_INVALID);
 	cev_ts_init(&ce_data->health_pause_stats, GBMS_STATS_AC_TI_PAUSE);
+	cev_ts_init(&ce_data->health_dryrun_stats, GBMS_STATS_AC_TI_V2_PREDICT);
 
 	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);
@@ -1401,6 +1402,11 @@
 					   elap, cc,
 					   &ce_data->high_soc_stats);
 
+	if (batt_drv->chg_health.dry_run_deadline > 0)
+		batt_chg_stats_update_tier(batt_drv, temp_idx, ibatt_ma, temp,
+					   elap, cc,
+					   &ce_data->health_dryrun_stats);
+
 	/* --- Log tiers in SERIES below --- */
 	if (batt_drv->batt_full) {
 
@@ -1550,12 +1556,13 @@
 				POWER_SUPPLY_PROP_VOLTAGE_NOW);
 	const int cc_out = GPSY_GET_PROP(batt_drv->fg_psy,
 				POWER_SUPPLY_PROP_CHARGE_COUNTER);
+	const ktime_t now = get_boot_sec();
+	const ktime_t dry_run_deadline = batt_drv->chg_health.dry_run_deadline;
 
 	/* book last period to the current tier
 	 * NOTE: vbatt_idx != -1 -> temp_idx != -1
 	 */
 	if (batt_drv->vbatt_idx != -1 && batt_drv->temp_idx != -1) {
-		const ktime_t now = get_boot_sec();
 		const ktime_t elap = now - batt_drv->ce_data.last_update;
 		const int tier_idx = batt_chg_vbat2tier(batt_drv->vbatt_idx);
 		const int ibatt = GPSY_GET_PROP(batt_drv->fg_psy,
@@ -1582,6 +1589,9 @@
 	       sizeof(batt_drv->ce_data.ce_health));
 	batt_drv->ce_data.health_stats.vtier_idx =
 				batt_chg_health_vti(&batt_drv->chg_health);
+	batt_drv->ce_data.health_dryrun_stats.vtier_idx =
+		(now > dry_run_deadline) ? GBMS_STATS_AC_TI_V2_PREDICT_SUCCESS :
+						 GBMS_STATS_AC_TI_V2_PREDICT;
 
 	/* TODO: add a field to ce_data to qual weird charge sessions */
 	publish = force || batt_chg_stats_qual(batt_drv);
@@ -1877,6 +1887,12 @@
 					    soc_in, soc_next);
 	}
 
+	/* Does not currently check MSC_HEALTH */
+	if (ce_data->health_dryrun_stats.soc_in != -1)
+		len += batt_chg_tier_stats_cstr(&buff[len], size - len,
+						&ce_data->health_dryrun_stats,
+						verbose);
+
 	if (ce_data->full_charge_stats.soc_in != -1)
 		len += batt_chg_tier_stats_cstr(&buff[len], size - len,
 						&ce_data->full_charge_stats,
@@ -2031,6 +2047,8 @@
 		chg_health->rest_state = CHG_HEALTH_INACTIVE;
 		chg_health->rest_deadline = 0;
 	}
+
+	chg_health->dry_run_deadline = 0;
 }
 
 /* should not reset rl state */
@@ -4170,6 +4188,31 @@
 static const DEVICE_ATTR(charge_deadline, 0664, batt_show_chg_deadline,
 						batt_set_chg_deadline);
 
+static ssize_t charge_deadline_dryrun_store(struct device *dev,
+					    struct device_attribute *attr,
+					    const char *buf, size_t count)
+{
+	struct power_supply *psy = container_of(dev, struct power_supply, dev);
+	struct batt_drv *batt_drv =
+		(struct batt_drv *)power_supply_get_drvdata(psy);
+	long long deadline_s;
+
+	/* API works in seconds */
+	deadline_s = simple_strtoll(buf, NULL, 10);
+
+	mutex_lock(&batt_drv->chg_lock);
+	if (!batt_drv->ssoc_state.buck_enabled || deadline_s < 0) {
+		mutex_unlock(&batt_drv->chg_lock);
+		return -EINVAL;
+	}
+	batt_drv->chg_health.dry_run_deadline = get_boot_sec() + deadline_s;
+	mutex_unlock(&batt_drv->chg_lock);
+
+	return count;
+}
+
+static DEVICE_ATTR_WO(charge_deadline_dryrun);
+
 enum batt_ssoc_status {
 	BATT_SSOC_STATUS_UNKNOWN = 0,
 	BATT_SSOC_STATUS_CONNECTED = 1,
@@ -4610,6 +4653,10 @@
 	if (ret != 0)
 		dev_err(&batt_drv->psy->dev, "Failed to create ac_soc\n");
 
+	ret = device_create_file(&batt_drv->psy->dev, &dev_attr_charge_deadline_dryrun);
+	if (ret != 0)
+		dev_err(&batt_drv->psy->dev, "Failed to create chg_deadline_dryrun\n");
+
 	/* time to full */
 	ret = device_create_file(&batt_drv->psy->dev, &dev_attr_ttf_stats);
 	if (ret)