/*
 * 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
 */

static bool ttf_cc_check(const struct ttf_soc_stats *soc_stats, int soc)
{
	/* delta_cc shouldn't be negative */
	return soc_stats->cc[soc] && soc_stats->cc[soc + 1] &&
	       soc_stats->cc[soc] < soc_stats->cc[soc + 1];
}

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 (ttf_cc_check(&stats->soc_stats, soc) && stats->soc_stats.elap[soc])
		sstat = &stats->soc_stats;
	else if (ttf_cc_check(&stats->soc_ref, 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;
		if (ratio > max_ratio)
			max_ratio = ratio;

		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;
		if (ratio > max_ratio)
			max_ratio = ratio;
	}

	*res = estimate / 100;
	return max_ratio;
}

static int ttf_cstr(char *buff, int size, const struct ttf_soc_stats *soc_stats,
		    const struct ttf_soc_stats *soc_ref, int start, int end,
		    int const split, const char type)
{
	const bool combine = soc_ref == NULL ? false : true;
	int i, cc, len = 0;
	ktime_t elap;

	for (i = start; i <= end; i++) {
		if (i % split == 0 || i == start) {
			len += scnprintf(&buff[len], size - len, &type);
			if (split == 10)
				len += scnprintf(&buff[len], size - len,
						"%d", i / 10);
			len += scnprintf(&buff[len], size - len, ":");
		}
		if (type == 'T') {
			elap = soc_stats->elap[i];
			if (combine && elap == 0)
				elap = soc_ref->elap[i];
			len += scnprintf(&buff[len], size - len, " %4ld", elap);
		} else if (type == 'C') {
			cc = soc_stats->cc[i];
			if (combine && cc == 0)
				cc = soc_ref->cc[i];
			len += scnprintf(&buff[len], size - len, " %4d", cc);
		}

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

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

	return len;
}

int ttf_soc_cstr(char *buff, int size, const struct ttf_soc_stats *soc_stats,
		 int start, int end)
{
	int 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: */
	len += ttf_cstr(&buff[len], size - len, soc_stats, NULL, start, end, split, 'T');

	/* dump coulumb count as C: */
	len += ttf_cstr(&buff[len], size - len, soc_stats, NULL, start, end, split, 'C');

	return len;
}

int ttf_soc_cstr_combine(char *buff, int size, const struct ttf_soc_stats *soc_ref,
			 const struct ttf_soc_stats *soc_stats)
{
	int len = 0;

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

	/* dump elap time as T: */
	len += ttf_cstr(&buff[len], size - len, soc_stats, soc_ref, 0, 99, 10, 'T');

	/* dump coulumb count as C: */
	len += ttf_cstr(&buff[len], size - len, soc_stats, soc_ref, 0, 99, 10, 'C');

	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;
	}

	/* need to manually update cc[99] by adding ref_cc because it's not inclusive */
	if (last_soc == 98 && ttf_cc_check(&stats->soc_ref, 98))
		stats->soc_stats.cc[99] = stats->soc_stats.cc[98] +
					  (stats->soc_ref.cc[99] - stats->soc_ref.cc[98]);
}

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 */
#define TTF_REPORT_MAX_RATIO	300
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;

	/* max ratio to report ttf */
	ret = of_property_read_u32(device->of_node, "google,ttf-report-max-ratio",
				   &stats->report_max_ratio);
	if (ret < 0)
		stats->report_max_ratio = TTF_REPORT_MAX_RATIO;

	/* 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;
}
