/*
 * Copyright 2018 Google, LLC
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/kernel.h>
#include <linux/printk.h>
#include <linux/of.h>
#include <linux/slab.h>
#include "google_bms.h"
#include "google_psy.h"
#include "qmath.h"

#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
#endif

#define ELAP_LIMIT_S 60


void ttf_log(const struct batt_ttf_stats *stats, const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	logbuffer_vlog(stats->ttf_log, fmt, args);
	va_end(args);
}

/* actual adapter current capability for this charging event
 * NOTE: peformance for a tier are known only after entering the tier
 */
static int ttf_pwr_icl(const struct gbms_ce_tier_stats *ts,
		       const union gbms_ce_adapter_details *ad)
{
	int elap, amperage;

	elap = ts->time_fast + ts->time_taper;
	if (elap <= ELAP_LIMIT_S)
		amperage = ad->ad_amperage * 100;
	else
		amperage = ts->icl_sum / (elap + ts->time_other);

	return amperage;
}

/* NOTE: the current in taper might need to be accounted in a different way */
int ttf_pwr_ibatt(const struct gbms_ce_tier_stats *ts)
{
	int avg_ibatt, elap, sign = 1;

	elap = ts->time_fast + ts->time_taper;
	/* averages are not reliable until after some time in tier */
	if (elap <= ELAP_LIMIT_S) {
		pr_debug("%s: limit=%d elap=%d (%d+%d) o=%d\n", __func__,
			 elap, ELAP_LIMIT_S, ts->time_fast, ts->time_taper,
			 ts->time_other);
		return 0;
	}

	/* actual, called only when avg_ibatt in tier indicates charging */
	avg_ibatt = ts->ibatt_sum / (elap + ts->time_other);
	if (avg_ibatt < 0)
		sign = -1;

	pr_debug("%s: elap=%d (%d+%d+%d) sum=%ld avg_ibatt=%d\n", __func__,
		 elap, ts->time_fast, ts->time_taper, ts->time_other,
		 ts->ibatt_sum, avg_ibatt * sign);

	return avg_ibatt * sign;
}

/* nominal voltage tier index for this soc */
int ttf_pwr_vtier_idx(const struct batt_ttf_stats *stats, int soc)
{
	int i;

	for (i = 1; i < GBMS_STATS_TIER_COUNT; i++)
		if (soc < stats->tier_stats[i].soc_in >> 8)
			break;

	return i - 1;
}

/*
 * reference or current average current demand for a soc at max rate.
 * NOTE: always <= cc_max for reference temperature
 */
int ttf_ref_cc(const struct batt_ttf_stats *stats, int soc)
{
	const struct ttf_soc_stats *sstat = NULL;
	int delta_cc;

	/* out of range */
	if (soc + 1 >= GBMS_SOC_STATS_LEN)
		return 0;

	/* soc average current demand */
	if (stats->soc_stats.cc[soc + 1] && stats->soc_stats.cc[soc] &&
	    stats->soc_stats.elap[soc])
		sstat = &stats->soc_stats;
	else if (stats->soc_ref.cc[soc + 1] && stats->soc_ref.cc[soc] &&
		 stats->soc_ref.elap[soc])
		sstat = &stats->soc_ref;
	else
		return 0;

	delta_cc = (sstat->cc[soc + 1] - sstat->cc[soc]);

	pr_debug("%s %d: delta_cc=%d elap=%ld\n", __func__, soc,
		delta_cc, sstat->elap[soc]);

	return (delta_cc * 3600) / sstat->elap[soc];
}

/* assumes that health is active for any soc greater than CHG_HEALTH_REST_SOC */
static int ttf_pwr_health(const struct gbms_charging_event *ce_data,
			  int soc)
{
	return CHG_HEALTH_REST_IS_ACTIVE(&ce_data->ce_health) &&
	       soc >= CHG_HEALTH_REST_SOC(&ce_data->ce_health);
}

static int ttf_pwr_health_pause(const struct gbms_charging_event *ce_data,
			  int soc)
{
	return CHG_HEALTH_REST_IS_PAUSE(&ce_data->ce_health) &&
	       soc >= CHG_HEALTH_REST_SOC(&ce_data->ce_health);
}

/*
 * equivalent icl: minimum between actual input current limit and battery
 * everage current _while_in_tier. actual_icl will be lower in high current
 * tiers for bad cables, ibatt is affected by temperature tier and sysload.
 */
static int ttf_pwr_equiv_icl(const struct gbms_charging_event *ce_data,
			     int vbatt_idx, int soc)
{
	const struct gbms_chg_profile *profile = ce_data->chg_profile;
	const int aratio = (ce_data->adapter_details.ad_voltage * 10000) /
			   (profile->volt_limits[vbatt_idx] / 1000);
	const struct gbms_ce_tier_stats *tier_stats;
	const int efficiency = 95; /* TODO: use real efficiency */
	const u32 capacity_ma = profile->capacity_ma;
	const int rest_rate = ce_data->ce_health.rest_rate;
	int equiv_icl, act_icl, act_ibatt, health_ibatt = -1;

	/* Health collects in ce_data->health_stats vtier */
	if (ttf_pwr_health(ce_data, soc)) {
		health_ibatt = ce_data->ce_health.rest_cc_max / 1000;
		tier_stats = &ce_data->health_stats;
	} else if (ttf_pwr_health_pause(ce_data, soc)) {
		/* use ACTIVE current in PAUSE stat for ttf calculation */
		health_ibatt = (capacity_ma * rest_rate * 10) / 1000;
		/* use ACTIVE tier in PAUSE stat for ttf calculation */
		tier_stats = &ce_data->health_stats;
	} else {
		tier_stats = &ce_data->tier_stats[vbatt_idx];
	}

	/*
	 * actual adapter capabilities at adapter voltage for vtier
	 * NOTE: demand and cable might cause voltage and icl do droop
	 */
	act_icl = ttf_pwr_icl(tier_stats, &ce_data->adapter_details);
	if (act_icl <= 0) {
		pr_debug("%s: negative,null act_icl=%d\n", __func__, act_icl);
		return -EINVAL;
	}

	/* scale icl (at adapter voltage) to vtier */
	equiv_icl = (act_icl * aratio * efficiency) / 10000;
	pr_debug("%s: act_icl=%d aratio=%d equiv_icl=%d\n",
		 __func__, act_icl, aratio, equiv_icl);

	/* actual ibatt in this tier: act_ibatt==0 when too early to tell */
	act_ibatt = ttf_pwr_ibatt(tier_stats);
	if (act_ibatt == 0 && health_ibatt > 0)
		act_ibatt = health_ibatt;
	if (act_ibatt < 0) {
		pr_debug("%s: discharging ibatt=%d\n", __func__, act_ibatt);
		return -EINVAL;
	}

	/* assume that can deliver equiv_icl when act_ibatt == 0 */
	if (act_ibatt > 0 && act_ibatt < equiv_icl) {
		pr_debug("%s: sysload ibatt=%d, reduce icl %d->%d\n",
			 __func__, act_ibatt, equiv_icl, act_ibatt);
		equiv_icl = act_ibatt;
	}

	pr_debug("%s: equiv_icl=%d\n", __func__, equiv_icl);
	return equiv_icl;
}

/*
 * time scaling factor for available power and SOC demand.
 * NOTE: usually called when soc < ssoc_in && soc > ce_data->last_soc
 * TODO: this is very inefficient
 */
static int ttf_pwr_ratio(const struct batt_ttf_stats *stats,
			 const struct gbms_charging_event *ce_data,
			 int soc)
{
	const struct gbms_chg_profile *profile = ce_data->chg_profile;
	int cc_max, vbatt_idx, temp_idx;
	int avg_cc, equiv_icl;
	int ratio;

	/* regular charging tier */
	vbatt_idx = ttf_pwr_vtier_idx(stats, soc);
	if (vbatt_idx < 0)
		return -EINVAL;

	/* TODO: compensate with average increase/decrease of temperature? */
	temp_idx = ce_data->tier_stats[vbatt_idx].temp_idx;
	if (temp_idx == -1) {
		int64_t t_avg = 0;
		const int elap = ce_data->tier_stats[vbatt_idx].time_fast +
		 		 ce_data->tier_stats[vbatt_idx].time_taper +
		 		 ce_data->tier_stats[vbatt_idx].time_other;

		if (ce_data->tier_stats[vbatt_idx].temp_sum != 0 || elap == 0)
			t_avg = ce_data->tier_stats[vbatt_idx].temp_in;
		if (t_avg == 0)
			t_avg = 250;

		/* average temperature in tier for charge tier index */
		temp_idx = gbms_msc_temp_idx(profile, t_avg);
		pr_debug("%s %d: temp_idx=%d t_avg=%ld sum=%ld elap=%d\n",
			__func__, soc, temp_idx, t_avg,
			ce_data->tier_stats[vbatt_idx].temp_sum,
			elap);

		if (temp_idx < 0)
			return -EINVAL;
	}

	/* max tier demand for voltage tier at this temperature index */
	cc_max = GBMS_CCCM_LIMITS(profile, temp_idx, vbatt_idx) / 1000;
	/* statistical current demand for soc (<= cc_max) */
	avg_cc = ttf_ref_cc(stats, soc);
	if (avg_cc <= 0) {
		/* default to cc_max if we have no data */
		pr_debug("%s %d: demand use default avg_cc=%d->%d\n",
			__func__, soc, avg_cc, cc_max);
		avg_cc = cc_max;
	}

	/* statistical or reference max power demand for the tier at */
	pr_debug("%s %d:%d,%d: avg_cc=%d cc_max=%d\n",
		 __func__, soc, temp_idx, vbatt_idx,
		 avg_cc, cc_max);

	/* equivalent input current for adapter at vtier */
	equiv_icl = ttf_pwr_equiv_icl(ce_data, vbatt_idx, soc);
	if (equiv_icl <= 0) {
		pr_debug("%s %d: negative, null act_icl=%d\n",
			 __func__, soc, equiv_icl);
		return -EINVAL;
	}

	/* lower to cc_max if in HOT and COLD */
	if (cc_max < equiv_icl) {
		pr_debug("%s %d: reduce act_icl=%d to cc_max=%d\n",
			 __func__, soc, equiv_icl, cc_max);
		equiv_icl = cc_max;
	}

	/*
	 * This is the trick that makes everything work:
	 *   equiv_icl = min(act_icl, act_ibatt, cc_max)
	 *
	 * act_icl = adapter max or adapter actual icl (due to bad cable,
	 *           AC enabled or temperature shift) scaled to vtier
	 * act_ibatt = measured for
	 *   at reference temperature or actual < cc_max due to sysload
	 * cc_max = cc_max from profile (lower than ref for  HOT or COLD)
	 *
	 */

	/* ratio for elap time: it doesn't work if reference is not maximal */
	if (equiv_icl < avg_cc)
		ratio = (avg_cc * 100) / equiv_icl;
	else
		ratio = 100;

	pr_debug("%s %d: equiv_icl=%d, avg_cc=%d ratio=%d\n",
		 __func__, soc, equiv_icl, avg_cc, ratio);

	return ratio;
}

/* SOC estimates ---------------------------------------------------------  */

/* reference of current elap for a soc at max rate */
static int ttf_ref_elap(const struct batt_ttf_stats *stats, int soc)
{
	ktime_t elap;

	if (soc < 0 || soc >= 100)
		return 0;

	elap = stats->soc_stats.elap[soc];
	if (elap == 0)
		elap = stats->soc_ref.elap[soc];

	return elap;
}

/* elap time for a single soc% */
static int ttf_elap(ktime_t *estimate, const struct batt_ttf_stats *stats,
		    const struct gbms_charging_event *ce_data,
		    int soc)
{
	ktime_t elap;
	int ratio;

	/* cannot really return 0 elap unless the data is corrupted */
	elap = ttf_ref_elap(stats, soc);
	if (elap == 0) {
		pr_debug("%s %d: zero elap\n", __func__, soc);
		return -EINVAL;
	}

	ratio = ttf_pwr_ratio(stats, ce_data, soc);
	if (ratio < 0) {
		pr_debug("%s %d: negative ratio=%d\n", __func__, soc, ratio);
		return -EINVAL;
	}

	*estimate = elap * ratio;

	pr_debug("%s: soc=%d estimate=%lld elap=%lld ratio=%d\n",
		 __func__, soc, *estimate, elap, ratio);

	return ratio;
}

/*
 * time to full from SOC% using the actual stats
 * NOTE: prediction is based stats and corrected with the ce_data
 * NOTE: usually called with soc > ce_data->last_soc
 */
int ttf_soc_estimate(ktime_t *res, const struct batt_ttf_stats *stats,
		     const struct gbms_charging_event *ce_data,
		     qnum_t soc, qnum_t last)
{
	const int ssoc_in = ce_data->charging_stats.ssoc_in;
	ktime_t elap, estimate = 0;
	int i = 0, ratio, frac, max_ratio = 0;

	if (last > qnum_rconst(100) || last < soc)
		return -EINVAL;

	if (last == soc) {
		*res = 0;
		return 0;
	}

	/* FIRST: 100 - first 2 digits of the fractional part of soc if any */
	frac = (int)qnum_nfracdgt(soc, 2);
	if (frac) {

		ratio = ttf_elap(&elap, stats, ce_data, qnum_toint(soc));
		if (ratio >= 0)
			estimate += (elap * (100 - frac)) / 100;

		i += 1;
	}

	/* accumulate ttf_elap starting from i + 1 until end */
	for (i += qnum_toint(soc); i < qnum_toint(last); i++) {

		if (i >= ssoc_in && i < ce_data->last_soc) {
			/* use real data if within charging event */
			elap = ce_data->soc_stats.elap[i] * 100;
		} else {
			/* future (and soc before ssoc_in) */
			ratio = ttf_elap(&elap, stats, ce_data, i);
			if (ratio < 0)
				return ratio;
			if (ratio > max_ratio)
				max_ratio = ratio;
		}

		estimate += elap;
	}

	/* LAST: first 2 digits of the fractional part of soc if any */
	frac = (int)qnum_nfracdgt(last, 2);
	if (frac) {
		ratio = ttf_elap(&elap, stats, ce_data, qnum_toint(last));
		if (ratio >= 0)
			estimate += (elap * frac) / 100;
	}

	*res = estimate / 100;
	return max_ratio;
}

int ttf_soc_cstr(char *buff, int size, const struct ttf_soc_stats *soc_stats,
		 int start, int end)
{
	int i, len = 0, split = 100;

	if (start < 0 || start >= GBMS_SOC_STATS_LEN ||
	    end < 0 || end >= GBMS_SOC_STATS_LEN ||
	    start > end)
		return 0;

	len += scnprintf(&buff[len], size - len, "\n");

	/* only one way to print data @ 100 */
	if (end == 100 && start != 100)
		end = 99;
	/* std newline every 10 entries */
	if (start == 0 && end == 99)
		split = 10;

	/* dump elap time as T: */
	for (i = start; i <= end; i++) {
		if (i % split == 0 || i == start) {
			len += scnprintf(&buff[len], size - len, "T");
			if (split == 10)
				len += scnprintf(&buff[len], size - len,
						"%d", i / 10);
			len += scnprintf(&buff[len], size - len, ":");
		}

		len += scnprintf(&buff[len], size - len, " %4ld",
				soc_stats->elap[i]);
		if (i != end && (i + 1) % split == 0)
			len += scnprintf(&buff[len], size - len, "\n");
	}

	len += scnprintf(&buff[len], size - len, "\n");

	/* dump coulumb count as C: */
	for (i = start; i <= end; i++) {
		if (i % split == 0 || i == start) {
			len += scnprintf(&buff[len], size - len, "C");
			if (split == 10)
				len += scnprintf(&buff[len], size - len,
						 "%d", i / 10);
			len += scnprintf(&buff[len], size - len, ":");
		}

		len += scnprintf(&buff[len], size - len, " %4d",
				soc_stats->cc[i]);
		if (i != end && (i + 1) % split == 0)
			len += scnprintf(&buff[len], size - len, "\n");
	}

	len += scnprintf(&buff[len], size - len, "\n");

	return len;
}

/* TODO: tune these values */

/* discard updates for adapters that have less than 80% of nominal */
#define TTF_SOC_QUAL_ELAP_RATIO_MAX	200
/* cap updates of cc to no more of +-*_CUR_ABS_MAX from previous */
#define TTF_SOC_QUAL_ELAP_DELTA_CUR_ABS_MAX	60
/* cap udpdates to cc max to no more of +-20% of reference */
#define TTF_SOC_QUAL_ELAP_DELTA_REF_PCT_MAX	20

/* return the weight to apply to this change */
static ktime_t ttf_soc_qual_elap(const struct batt_ttf_stats *stats,
				 const struct gbms_charging_event *ce_data,
				 int i)
{
	const struct ttf_soc_stats *src = &ce_data->soc_stats;
	const struct ttf_soc_stats *dst = &stats->soc_stats;
	const int limit = TTF_SOC_QUAL_ELAP_RATIO_MAX;
	const int max_elap = ((100 + TTF_SOC_QUAL_ELAP_DELTA_REF_PCT_MAX) *
			     stats->soc_ref.elap[i]) / 100;
	const int min_elap = ((100 - TTF_SOC_QUAL_ELAP_DELTA_REF_PCT_MAX) *
			     stats->soc_ref.elap[i]) / 100;
	ktime_t elap, elap_new, elap_cur;
	int ratio;

	if (!src->elap[i])
		return 0;

	/* weight the adapter, discard if ratio is too high (poor adapter) */
	ratio = ttf_pwr_ratio(stats, ce_data, i);
	if (ratio <= 0 || ratio > limit) {
		pr_debug("%d: ratio=%d limit=%d\n", i, ratio, limit);
		return 0;
	}

	elap_new = (src->elap[i] * 100) / ratio;
	elap_cur = dst->elap[i];
	if (!elap_cur)
		elap_cur = stats->soc_ref.elap[i];
	elap = (elap_cur + elap_new) / 2;

	/* bounds check to previous */
	if (elap > (elap_cur + TTF_SOC_QUAL_ELAP_DELTA_CUR_ABS_MAX))
		elap = elap_cur + TTF_SOC_QUAL_ELAP_DELTA_CUR_ABS_MAX;
	else if (elap < (elap_cur - TTF_SOC_QUAL_ELAP_DELTA_CUR_ABS_MAX))
		elap = elap_cur - TTF_SOC_QUAL_ELAP_DELTA_CUR_ABS_MAX;

	/* bounds check to reference */
	if (elap > max_elap)
		elap = max_elap;
	else if (elap < min_elap)
		elap = min_elap;

	pr_debug("%d: dst->elap=%ld, ref_elap=%ld, elap=%ld, src_elap=%ld ratio=%d, min=%d max=%d\n",
		i, dst->elap[i], stats->soc_ref.elap[i], elap, src->elap[i],
		ratio, min_elap, max_elap);

	return elap;
}

/* cap updates of cc to no more of +-*_CUR_ABS_MAX from previous */
#define TTF_SOC_QUAL_CC_DELTA_CUR_ABS_MAX	40
/* cap udpdates to cc max to no more of +-20% of reference */
#define TTF_SOC_QUAL_CC_DELTA_REF_PCT_MAX	20

static int ttf_soc_qual_cc(const struct batt_ttf_stats *stats,
			   const struct gbms_charging_event *ce_data,
			   int i)
{
	const struct ttf_soc_stats *src = &ce_data->soc_stats;
	const struct ttf_soc_stats *dst = &stats->soc_stats;
	const int max_cc = ((100 + TTF_SOC_QUAL_CC_DELTA_REF_PCT_MAX) *
			   stats->soc_ref.cc[i]) / 100;
	const int min_cc = ((100 - TTF_SOC_QUAL_CC_DELTA_REF_PCT_MAX) *
			   stats->soc_ref.cc[i]) / 100;
	int cc, cc_cur;

	if (!src->cc[i])
		return 0;

	cc_cur = dst->cc[i];
	if (cc_cur <= 0)
		cc_cur = stats->soc_ref.cc[i];

	cc = (cc_cur + src->cc[i]) / 2;

	/* bounds check to previous */
	if (cc > cc_cur + TTF_SOC_QUAL_CC_DELTA_CUR_ABS_MAX)
		cc = cc_cur + TTF_SOC_QUAL_CC_DELTA_CUR_ABS_MAX;
	else if (cc < cc_cur  -TTF_SOC_QUAL_CC_DELTA_CUR_ABS_MAX)
		cc = cc_cur - TTF_SOC_QUAL_CC_DELTA_CUR_ABS_MAX;

	/* bounds check to reference */
	if (cc > max_cc)
		cc = max_cc;
	else if (cc < min_cc)
		cc = min_cc;

	pr_debug("%d: cc_cur=%d, ref_cc=%d src->cc=%d, cc=%d\n",
		 i, cc_cur, stats->soc_ref.cc[i], src->cc[i], cc);

	return cc;
}

/* update soc_stats using the charging event
 * NOTE: first_soc and last_soc are inclusive, will skip socs that have no
 * elap and no cc.
 */
static void ttf_soc_update(struct batt_ttf_stats *stats,
			   const struct gbms_charging_event *ce_data,
			   int first_soc, int last_soc)
{
	const struct ttf_soc_stats *src = &ce_data->soc_stats;
	int i;

	for (i = first_soc; i <= last_soc; i++) {
		ktime_t elap;
		int cc;

		/* need to have data on both */
		if (!src->elap[i] || !src->cc[i])
			continue;

		/* average the elap time at soc */
		elap = ttf_soc_qual_elap(stats, ce_data, i);
		if (elap)
			stats->soc_stats.elap[i] = elap;

		/* average the coulumb count at soc */
		cc = ttf_soc_qual_cc(stats, ce_data, i);
		if (cc)
			stats->soc_stats.cc[i] = cc;
	}
}

void ttf_soc_init(struct ttf_soc_stats *dst)
{
	memset(dst, 0, sizeof(*dst));
}

/* Tier estimates ---------------------------------------------------------  */

#define TTF_STATS_FMT "[%d,%d %d %ld]"

#define BATT_TTF_TS_VALID(ts) \
	(ts->cc_total != 0 && ts->avg_time != 0)

/* TODO: adjust for adapter capability */
static ktime_t ttf_tier_accumulate(const struct ttf_tier_stat *ts,
				  int vbatt_idx,
				  const struct batt_ttf_stats *stats)
{
	ktime_t estimate = 0;

	if (vbatt_idx >= GBMS_STATS_TIER_COUNT)
		return 0;

	for (; vbatt_idx < GBMS_STATS_TIER_COUNT; vbatt_idx++) {

		/* no data in this tier, sorry */
		if (!BATT_TTF_TS_VALID(ts))
			return -ENODATA;

		estimate += ts[vbatt_idx].avg_time;
	}

	return estimate;
}

/* */
static int ttf_tier_sscan(struct batt_ttf_stats *stats,
			  const char *buff,
			  size_t size)
{
	int j, len = 0;

	memset(&stats->tier_stats, 0, sizeof(stats->tier_stats));

	while (buff[len] != '[' && len < size)
		len++;

	for (j = 0; j < GBMS_STATS_TIER_COUNT; j++) {
		sscanf(&buff[len], TTF_STATS_FMT, &stats->tier_stats[j].soc_in,
		       &stats->tier_stats[j].cc_in,
		       &stats->tier_stats[j].cc_total,
		       &stats->tier_stats[j].avg_time);

		len += sizeof(TTF_STATS_FMT) - 1;
	}

	return 0;
}

int ttf_tier_cstr(char *buff, int size, const struct ttf_tier_stat *tier_stats)
{
	int len = 0;

	len += scnprintf(&buff[len], size - len,
			 TTF_STATS_FMT,
			 tier_stats->soc_in >> 8,
			 tier_stats->cc_in,
			 tier_stats->cc_total,
			 tier_stats->avg_time);
	return len;
}

/* average soc_in, cc_in, cc_total an and avg time for charge tier */
static void ttf_tier_update_stats(struct ttf_tier_stat *ttf_ts,
			    	  const struct gbms_ce_tier_stats *chg_ts,
				  bool force)
{
	int elap;

	if (!force) {
		if (chg_ts->cc_total == 0)
			return;

		/* TODO: check dsg, qualify with adapter? */
	}

	/* TODO: check with -1 */
	if (ttf_ts->soc_in == 0)
		ttf_ts->soc_in = chg_ts->soc_in;
	 ttf_ts->soc_in = (ttf_ts->soc_in + chg_ts->soc_in) / 2;

	/* TODO: check with -1 */
	if (ttf_ts->cc_in == 0)
		ttf_ts->cc_in = chg_ts->cc_in;
	 ttf_ts->cc_in = (ttf_ts->cc_in + chg_ts->cc_in) / 2;

	if (ttf_ts->cc_total == 0)
		 ttf_ts->cc_total = chg_ts->cc_total;
	 ttf_ts->cc_total = (ttf_ts->cc_total + chg_ts->cc_total) / 2;

	/* */
	elap = chg_ts->time_fast + chg_ts->time_taper + chg_ts->time_other;
	if (ttf_ts->avg_time == 0)
		ttf_ts->avg_time = elap;

	/* qualify time with ratio */
	ttf_ts->avg_time =(ttf_ts->avg_time + elap) / 2;
}

/* updated tier stats using the charging event
 * NOTE: the ce has data from 1+ charging voltage and temperature tiers */
static void ttf_tier_update(struct batt_ttf_stats *stats,
			    const struct gbms_charging_event *data,
			    bool force)
{
	int i;

	for (i = 0; i < GBMS_STATS_TIER_COUNT; i++) {
		const bool last_tier = i == (GBMS_STATS_TIER_COUNT - 1);
		const struct gbms_ce_tier_stats *chg_ts = &data->tier_stats[i];
		const struct gbms_ce_stats *chg_s = &data->charging_stats;
		long elap;

		/* skip data that has a temperature switch */
		if (chg_ts->temp_idx == -1)
			continue;
		/* or entries that have no actual charging */
		elap = chg_ts->time_fast + chg_ts->time_taper;
		if (!elap)
			continue;
		/* update first tier stats only at low soc_in */
		if (!force && i == 0 && (chg_ts->soc_in >> 8) > 1)
			continue;
		/* update last tier stats only at full */
		if (!force && last_tier && chg_s->ssoc_out != 100)
			continue;

		/*  */
		ttf_tier_update_stats(&stats->tier_stats[i], chg_ts, false);
	}

}

/* tier estimates only, */
int ttf_tier_estimate(ktime_t *res, const struct batt_ttf_stats *stats,
		      int temp_idx, int vbatt_idx,
		      int capacity, int full_capacity)
{
	ktime_t estimate = 0;
	const struct ttf_tier_stat *ts;

	/* tier estimates, only when in tier */
	if (vbatt_idx == -1 && temp_idx == -1)
		return -EINVAL;

	ts = &stats->tier_stats[vbatt_idx];
	if (!ts || !BATT_TTF_TS_VALID(ts))
		return -ENODATA;

	/* accumulate next tier */
	estimate = ttf_tier_accumulate(ts, vbatt_idx + 1, stats);
	if (estimate < 0)
		return -ENODATA;

	/* eyeball current tier
	 * estimate =
	 * 	(ts->cc_in + ts->cc_total - capacity) *
	 * 	rs->avg_time) / ts->cc_total
	 */

	/* TODO: adjust for crossing thermals? */

	*res = estimate;
	return 0;
}

/* ----------------------------------------------------------------------- */

/* QUAL DELTA >= 3 */
#define TTF_STATS_QUAL_DELTA_MIN	3
#define TTF_STATS_QUAL_DELTA		TTF_STATS_QUAL_DELTA_MIN

static int ttf_soc_cstr_elap(char *buff, int size,
			     const struct ttf_soc_stats *soc_stats,
			     int start, int end)
{
	int i, len = 0;

	len += scnprintf(&buff[len], size - len, "T%d:", start);
	for (i = start; i < end; i++)
		len += scnprintf(&buff[len], size - len, " %4ld",
				 soc_stats->elap[i]);

	return len;
}

static int ttf_soc_cstr_cc(char *buff, int size,
			   const struct ttf_soc_stats *soc_stats,
			   int start, int end)
{
	int i, len = 0;

	len += scnprintf(&buff[len], size - len, "C%d:", start);
	for (i = start; i < end; i++)
		len += scnprintf(&buff[len], size - len, " %4d",
				 soc_stats->cc[i]);

	return len;
}

/* update ttf tier and soc stats using the charging event.
 * call holding stats->lock
 */
void ttf_stats_update(struct batt_ttf_stats *stats,
		      struct gbms_charging_event *ce_data,
		      bool force)
{
	int first_soc = ce_data->charging_stats.ssoc_in;
	const int last_soc = ce_data->last_soc;
	const int delta_soc = last_soc - first_soc;
	const int limit = force ? TTF_STATS_QUAL_DELTA_MIN :
			  TTF_STATS_QUAL_DELTA;
	const int tmp_size = PAGE_SIZE;
	char *tmp;

	/* skip data short periods */
	if (delta_soc < limit) {
		ttf_log(stats, "no updates delta_soc=%d, limit=%d, force=%d",
			delta_soc, limit, force);
		return;
	}

	/* ignore first nozero and last entry because they are partial */
	for ( ; first_soc <= last_soc; first_soc++)
		if (ce_data->soc_stats.elap[first_soc] != 0)
			break;

	ttf_soc_update(stats, ce_data, first_soc + 1, last_soc - 1);
	ttf_tier_update(stats, ce_data, force);

	/* dump update stats to logbuffer */
	tmp = kzalloc(tmp_size, GFP_KERNEL);
	if (tmp) {
		const int split = 10;
		int i;

		for (i = first_soc + 1;i < last_soc - 1; i += split) {
			int end_soc = i + split;

			if (end_soc > last_soc - 1)
				end_soc = last_soc - 1;

			ttf_soc_cstr_elap(tmp, tmp_size, &stats->soc_stats,
					  i, end_soc);
			ttf_log(stats, "%s", tmp);
			ttf_soc_cstr_cc(tmp, tmp_size, &stats->soc_stats,
					  i,  end_soc);
			ttf_log(stats, "%s", tmp);
		}

		kfree(tmp);
	}
}

static int ttf_init_soc_parse_dt(struct ttf_adapter_stats *as,
				 struct device *device)
{
	int table_count;
	int ret;

	table_count = of_property_count_elems_of_size(device->of_node,
						      "google,ttf-soc-table",
						      sizeof(u32));
	if (table_count <= 0)
		return -EINVAL;
	if (table_count % 2)
		return -EINVAL;

	as->soc_table = devm_kzalloc(device, table_count * 2 * sizeof(u32),
				     GFP_KERNEL);
	if (!as->soc_table)
		return -ENOMEM;

	ret = of_property_read_u32_array(device->of_node,
					"google,ttf-soc-table",
					as->soc_table, table_count);
	if (ret < 0) {
		pr_err("cannot read google,ttf-soc-table %d\n", ret);
		return ret;
	}

	as->elap_table = &as->soc_table[table_count];
	ret = of_property_read_u32_array(device->of_node,
					"google,ttf-elap-table",
					as->elap_table, table_count);
	if (ret < 0) {
		pr_err("cannot read google,ttf-elap-table %d\n", ret);
		return ret;
	}

	as->table_count = table_count;
	return 0;
}

int ttf_stats_sscan(struct batt_ttf_stats *stats,
		    const char *buff,
		    size_t size)
{
	/* TODO: scan ttf_soc_* data as well */

	return ttf_tier_sscan(stats, buff, size);
}

static int ttf_as_default(struct ttf_adapter_stats *as, int i, int table_i)
{
	while (i > as->soc_table[table_i] && table_i < as->table_count)
		table_i++;

	return table_i;
}

void ttf_tier_reset(struct batt_ttf_stats *stats)
{
	int i;

	for (i = 0; i < GBMS_STATS_TIER_COUNT; i++) {
		stats->tier_stats[i].cc_in = 0;
		stats->tier_stats[i].cc_total = 0;
		stats->tier_stats[i].avg_time = 0;
	}
}

static int ttf_init_tier_parse_dt(struct batt_ttf_stats *stats,
				  struct device *device)
{
	int i, count, ret;
	u32 tier_table[GBMS_STATS_TIER_COUNT];

	count = of_property_count_elems_of_size(device->of_node,
						"google,ttf-tier-table",
						sizeof(u32));
	if (count != GBMS_STATS_TIER_COUNT)
		return -EINVAL;

	ret = of_property_read_u32_array(device->of_node,
					"google,ttf-tier-table",
					tier_table, count);
	if (ret < 0) {
		pr_err("cannot read google,ttf-tier-table %d\n", ret);
		return ret;
	}

	for (i = 0; i < GBMS_STATS_TIER_COUNT; i++)
		stats->tier_stats[i].soc_in = tier_table[i] << 8;

	ttf_tier_reset(stats);

	return 0;
}

/* clone and clear the stats */
struct batt_ttf_stats *ttf_stats_dup(struct batt_ttf_stats *dst,
				     const struct batt_ttf_stats *src)
{
	memcpy(dst, src, sizeof(*dst));
	memset(&dst->soc_stats, 0, sizeof(dst->soc_stats));
	memset(&dst->tier_stats, 0, sizeof(dst->tier_stats));
	return dst;
}

static void ttf_init_ref_table(struct batt_ttf_stats *stats,
			       struct ttf_adapter_stats *as,
			       int capacity_ma)
{
	int i, table_i = 0;
	const int cc = (capacity_ma * 100) / GBMS_SOC_STATS_LEN;

	for (i = 0; i < GBMS_SOC_STATS_LEN; i++) {
		table_i = ttf_as_default(as, i, table_i);

		stats->soc_ref.elap[i] = as->elap_table[table_i];

		/* assume same cc for each soc */
		stats->soc_ref.cc[i] = (cc * i) / 100;
	}

	/* TODO: allocate as->soc_table witk kzalloc, free here */
}

/* must come after charge profile */
int ttf_stats_init(struct batt_ttf_stats *stats, struct device *device,
		   int capacity_ma)
{
	struct ttf_adapter_stats as;
	u32 value;
	int ret;

	memset(stats, 0, sizeof(*stats));
	stats->ttf_fake = -1;

	/* reference adapter */
	ret = of_property_read_u32(device->of_node, "google,ttf-adapter",
				   &value);
	if (ret < 0)
		return ret;

	stats->ref_watts = value;

	/* reference temperature  */
	ret = of_property_read_u32(device->of_node, "google,ttf-temp-idx",
				   &value);
	if (ret < 0)
		return ret;

	stats->ref_temp_idx = value;

	/* reference soc estimates */
	ret = ttf_init_soc_parse_dt(&as, device);
	if (ret < 0)
		return ret;

	/* reference tier-based statistics */
	ret = ttf_init_tier_parse_dt(stats, device);
	if (ret < 0)
		return ret;

	/* initialize the reference stats for the reference soc estimates */
	ttf_init_ref_table(stats, &as, capacity_ma);


	/* TODO: use the soc stats to calculate cc_in */
	stats->tier_stats[0].cc_in = 0;
	stats->tier_stats[1].cc_in = (capacity_ma *
					stats->tier_stats[1].soc_in) /
					100;
	stats->tier_stats[2].cc_in = (capacity_ma *
					stats->tier_stats[2].soc_in) /
					100;

	/* TODO: use the soc stats to calculate cc_total */
	stats->tier_stats[0].cc_total = 0;
	stats->tier_stats[1].cc_total = (capacity_ma *
					(stats->tier_stats[2].soc_in -
					stats->tier_stats[1].soc_in)) /
					100;
	stats->tier_stats[2].cc_total = capacity_ma -
					stats->tier_stats[2].cc_in;


	return 0;
}


/* tier and soc details */
ssize_t ttf_dump_details(char *buf, int max_size,
			 const struct batt_ttf_stats *ttf_stats,
			 int last_soc)
{
	int i, len = 0;

	/* interleave tier with SOC data */
	for (i = 0; i < GBMS_STATS_TIER_COUNT; i++) {
		int next_soc_in;

		len += scnprintf(&buf[len], max_size - len, "%d: ", i);
		len += ttf_tier_cstr(&buf[len], max_size - len,
				     &ttf_stats->tier_stats[i]);
		len += scnprintf(&buf[len], max_size - len, "\n");

		/* continue only first */
		if (ttf_stats->tier_stats[i].avg_time == 0)
			continue;

		if (i == GBMS_STATS_TIER_COUNT - 1) {
			next_soc_in = -1;
		} else {
			next_soc_in = ttf_stats->tier_stats[i + 1].soc_in >> 8;
			if (next_soc_in == 0)
				next_soc_in = -1;
		}

		if (next_soc_in == -1)
			next_soc_in = last_soc - 1;

		len += ttf_soc_cstr(&buf[len], max_size - len,
				    &ttf_stats->soc_stats,
				    ttf_stats->tier_stats[i].soc_in >> 8,
				    next_soc_in);
	}

	return len;
}
