/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * 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.
 */

#define pr_fmt(fmt)	"ALG: %s: " fmt, __func__

#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/mutex.h>
#include <linux/power_supply.h>
#include <linux/slab.h>
#include <linux/sort.h>
#include "fg-alg.h"

#define FULL_SOC_RAW		255
#define FULL_BATT_SOC		GENMASK(31, 0)
#define CAPACITY_DELTA_DECIPCT	500

#define CENTI_ICORRECT_C0	105
#define CENTI_ICORRECT_C1	20

#define HOURS_TO_SECONDS	3600
#define OCV_SLOPE_UV		10869
#define MILLI_UNIT		1000
#define MICRO_UNIT		1000000
#define NANO_UNIT		1000000000

#define DEFAULT_TTF_RUN_PERIOD_MS	10000
#define DEFAULT_TTF_ITERM_DELTA_MA	200

static const struct ttf_pt ttf_ln_table[] = {
	{ 1000,		0 },
	{ 2000,		693 },
	{ 4000,		1386 },
	{ 6000,		1792 },
	{ 8000,		2079 },
	{ 16000,	2773 },
	{ 32000,	3466 },
	{ 64000,	4159 },
	{ 128000,	4852 },
};

/* Cycle counter APIs */

/**
 * restore_cycle_count -
 * @counter: Cycle counter object
 *
 * Restores all the counters back from FG/QG during boot
 *
 */
int restore_cycle_count(struct cycle_counter *counter)
{
	int rc = 0;

	if (!counter)
		return -ENODEV;

	mutex_lock(&counter->lock);
	rc = counter->restore_count(counter->data, counter->count,
			BUCKET_COUNT);
	if (rc < 0)
		pr_err("failed to restore cycle counter rc=%d\n", rc);
	mutex_unlock(&counter->lock);

	return rc;
}

/**
 * clear_cycle_count -
 * @counter: Cycle counter object
 *
 * Clears all the counters stored by FG/QG when a battery is inserted
 * or the profile is re-loaded.
 *
 */
void clear_cycle_count(struct cycle_counter *counter)
{
	int rc = 0, i;

	if (!counter)
		return;

	mutex_lock(&counter->lock);
	memset(counter->count, 0, sizeof(counter->count));
	for (i = 0; i < BUCKET_COUNT; i++) {
		counter->started[i] = false;
		counter->last_soc[i] = 0;
	}

	rc = counter->store_count(counter->data, counter->count, 0,
			BUCKET_COUNT * 2);
	if (rc < 0)
		pr_err("failed to clear cycle counter rc=%d\n", rc);

	mutex_unlock(&counter->lock);
}

/**
 * store_cycle_count -
 * @counter: Cycle counter object
 * @id: Cycle counter bucket id
 *
 * Stores the cycle counter for a bucket in FG/QG.
 *
 */
static int store_cycle_count(struct cycle_counter *counter, int id)
{
	int rc = 0;
	u16 cyc_count;

	if (!counter)
		return -ENODEV;

	if (id < 0 || (id > BUCKET_COUNT - 1)) {
		pr_err("Invalid id %d\n", id);
		return -EINVAL;
	}

	cyc_count = counter->count[id];
	cyc_count++;

	rc = counter->store_count(counter->data, &cyc_count, id, 2);
	if (rc < 0) {
		pr_err("failed to write cycle_count[%d] rc=%d\n",
			id, rc);
		return rc;
	}

	counter->count[id] = cyc_count;
	pr_debug("Stored count %d in id %d\n", cyc_count, id);

	return rc;
}

/**
 * cycle_count_update -
 * @counter: Cycle counter object
 * @batt_soc: Battery State of Charge (SOC)
 * @charge_status: Charging status from power supply
 * @charge_done: Indicator for charge termination
 * @input_present: Indicator for input presence
 *
 * Called by FG/QG whenever there is a state change (Charging status, SOC)
 *
 */
void cycle_count_update(struct cycle_counter *counter, int batt_soc,
			int charge_status, bool charge_done, bool input_present)
{
	int rc = 0, id, i, soc_thresh;

	if (!counter)
		return;

	mutex_lock(&counter->lock);

	/* Find out which id the SOC falls in */
	id = batt_soc / BUCKET_SOC_PCT;

	if (charge_status == POWER_SUPPLY_STATUS_CHARGING) {
		if (!counter->started[id] && id != counter->last_bucket) {
			counter->started[id] = true;
			counter->last_soc[id] = batt_soc;
		}
	} else if (charge_done || !input_present) {
		for (i = 0; i < BUCKET_COUNT; i++) {
			soc_thresh = counter->last_soc[i] + BUCKET_SOC_PCT / 2;
			if (counter->started[i] && batt_soc > soc_thresh) {
				rc = store_cycle_count(counter, i);
				if (rc < 0)
					pr_err("Error in storing cycle_ctr rc: %d\n",
						rc);
				counter->last_soc[i] = 0;
				counter->started[i] = false;
				counter->last_bucket = i;
			}
		}
	}

	pr_debug("batt_soc: %d id: %d chg_status: %d\n", batt_soc, id,
		charge_status);
	mutex_unlock(&counter->lock);
}

/**
 * get_bucket_cycle_count -
 * @counter: Cycle counter object
 *
 * Returns the cycle counter for a SOC bucket.
 *
 */
static int get_bucket_cycle_count(struct cycle_counter *counter)
{
	int count;

	if (!counter)
		return 0;

	if ((counter->id <= 0) || (counter->id > BUCKET_COUNT))
		return -EINVAL;

	mutex_lock(&counter->lock);
	count = counter->count[counter->id - 1];
	mutex_unlock(&counter->lock);
	return count;
}

/**
 * get_cycle_counts -
 * @counter: Cycle counter object
 * @buf: Bucket cycle counts formatted in a string returned to the caller
 *
 * Get cycle count for all buckets in a string format
 */
int get_cycle_counts(struct cycle_counter *counter, const char **buf)
{
	int i, rc, len = 0;

	for (i = 1; i <= BUCKET_COUNT; i++) {
		counter->id = i;
		rc = get_bucket_cycle_count(counter);
		if (rc < 0) {
			pr_err("Couldn't get cycle count rc=%d\n", rc);
			return rc;
		}

		if (sizeof(counter->str_buf) - len < 8) {
			pr_err("Invalid length %d\n", len);
			return -EINVAL;
		}

		len += snprintf(counter->str_buf+len, 8, "%d ", rc);
	}

	counter->str_buf[len] = '\0';
	*buf = counter->str_buf;
	return 0;
}

/**
 * get_cycle_count -
 * @counter: Cycle counter object
 * @count: Average cycle count returned to the caller
 *
 * Get average cycle count for all buckets
 */
int get_cycle_count(struct cycle_counter *counter, int *count)
{
	int i, rc, temp = 0;

	for (i = 1; i <= BUCKET_COUNT; i++) {
		counter->id = i;
		rc = get_bucket_cycle_count(counter);
		if (rc < 0) {
			pr_err("Couldn't get cycle count rc=%d\n", rc);
			return rc;
		}

		temp += rc;
	}

	/*
	 * Normalize the counter across each bucket so that we can get
	 * the overall charge cycle count.
	 */
	*count = temp / BUCKET_COUNT;
	return 0;
}

/**
 * cycle_count_init -
 * @counter: Cycle counter object
 *
 * FG/QG have to call this during driver probe to validate the required
 * parameters after allocating cycle_counter object.
 *
 */
int cycle_count_init(struct cycle_counter *counter)
{
	if (!counter)
		return -ENODEV;

	if (!counter->data || !counter->restore_count ||
		!counter->store_count) {
		pr_err("Invalid parameters for using cycle counter\n");
		return -EINVAL;
	}

	mutex_init(&counter->lock);
	counter->last_bucket = -1;
	return 0;
}

/* Capacity learning algorithm APIs */

/**
 * cap_learning_post_process -
 * @cl: Capacity learning object
 *
 * Does post processing on the learnt capacity based on the user specified
 * or default parameters for the capacity learning algorithm.
 *
 */
static void cap_learning_post_process(struct cap_learning *cl)
{
	int64_t max_inc_val, min_dec_val, old_cap;
	int rc;

	if (cl->dt.skew_decipct) {
		pr_debug("applying skew %d on current learnt capacity %lld\n",
			cl->dt.skew_decipct, cl->final_cap_uah);
		cl->final_cap_uah = cl->final_cap_uah *
					(1000 + cl->dt.skew_decipct);
		cl->final_cap_uah = div64_u64(cl->final_cap_uah, 1000);
	}

	max_inc_val = cl->learned_cap_uah * (1000 + cl->dt.max_cap_inc);
	max_inc_val = div64_u64(max_inc_val, 1000);

	min_dec_val = cl->learned_cap_uah * (1000 - cl->dt.max_cap_dec);
	min_dec_val = div64_u64(min_dec_val, 1000);

	old_cap = cl->learned_cap_uah;
	if (cl->final_cap_uah > max_inc_val)
		cl->learned_cap_uah = max_inc_val;
	else if (cl->final_cap_uah < min_dec_val)
		cl->learned_cap_uah = min_dec_val;
	else
		cl->learned_cap_uah = cl->final_cap_uah;

	if (cl->dt.max_cap_limit) {
		max_inc_val = (int64_t)cl->nom_cap_uah * (1000 +
				cl->dt.max_cap_limit);
		max_inc_val = div64_u64(max_inc_val, 1000);
		if (cl->final_cap_uah > max_inc_val) {
			pr_debug("learning capacity %lld goes above max limit %lld\n",
				cl->final_cap_uah, max_inc_val);
			cl->learned_cap_uah = max_inc_val;
		}
	}

	if (cl->dt.min_cap_limit) {
		min_dec_val = (int64_t)cl->nom_cap_uah * (1000 -
				cl->dt.min_cap_limit);
		min_dec_val = div64_u64(min_dec_val, 1000);
		if (cl->final_cap_uah < min_dec_val) {
			pr_debug("learning capacity %lld goes below min limit %lld\n",
				cl->final_cap_uah, min_dec_val);
			cl->learned_cap_uah = min_dec_val;
		}
	}

	if (cl->store_learned_capacity) {
		rc = cl->store_learned_capacity(cl->data, cl->learned_cap_uah);
		if (rc < 0)
			pr_err("Error in storing learned_cap_uah, rc=%d\n", rc);
	}

	pr_debug("final cap_uah = %lld, learned capacity %lld -> %lld uah\n",
		cl->final_cap_uah, old_cap, cl->learned_cap_uah);
}

/**
 * cap_learning_process_full_data -
 * @cl: Capacity learning object
 *
 * Processes the coulomb counter during charge termination and calculates the
 * delta w.r.to the coulomb counter obtained earlier when the learning begun.
 *
 */
static int cap_learning_process_full_data(struct cap_learning *cl)
{
	int rc, cc_soc_sw, cc_soc_delta_centi_pct;
	int64_t delta_cap_uah;

	rc = cl->get_cc_soc(cl->data, &cc_soc_sw);
	if (rc < 0) {
		pr_err("Error in getting CC_SOC_SW, rc=%d\n", rc);
		return rc;
	}

	cc_soc_delta_centi_pct =
		div64_s64((int64_t)(cc_soc_sw - cl->init_cc_soc_sw) * 10000,
			cl->cc_soc_max);

	/* If the delta is < 50%, then skip processing full data */
	if (cc_soc_delta_centi_pct < 5000) {
		pr_err("cc_soc_delta_centi_pct: %d\n", cc_soc_delta_centi_pct);
		return -ERANGE;
	}

	delta_cap_uah = div64_s64(cl->learned_cap_uah * cc_soc_delta_centi_pct,
				 10000);
	cl->final_cap_uah = cl->init_cap_uah + delta_cap_uah;
	pr_debug("Current cc_soc=%d cc_soc_delta_centi_pct=%d total_cap_uah=%lld\n",
		cc_soc_sw, cc_soc_delta_centi_pct, cl->final_cap_uah);
	return 0;
}

/**
 * cap_learning_begin -
 * @cl: Capacity learning object
 * @batt_soc: Battery State of Charge (SOC)
 *
 * Gets the coulomb counter from FG/QG when the conditions are suitable for
 * beginning capacity learning. Also, primes the coulomb counter based on
 * battery SOC if required.
 *
 */
static int cap_learning_begin(struct cap_learning *cl, u32 batt_soc)
{
	int rc, cc_soc_sw, batt_soc_msb, batt_soc_pct;

	batt_soc_msb = batt_soc >> 24;
	batt_soc_pct = DIV_ROUND_CLOSEST(batt_soc_msb * 100, FULL_SOC_RAW);

	if (batt_soc_pct > cl->dt.max_start_soc ||
			batt_soc_pct < cl->dt.min_start_soc) {
		pr_debug("Battery SOC %d is high/low, not starting\n",
			batt_soc_pct);
		return -EINVAL;
	}

	cl->init_cap_uah = div64_s64(cl->learned_cap_uah * batt_soc,
					FULL_BATT_SOC);

	if (cl->prime_cc_soc) {
		/*
		 * Prime cc_soc_sw with battery SOC when capacity learning
		 * begins.
		 */
		rc = cl->prime_cc_soc(cl->data, batt_soc);
		if (rc < 0) {
			pr_err("Error in writing cc_soc_sw, rc=%d\n", rc);
			goto out;
		}
	}

	rc = cl->get_cc_soc(cl->data, &cc_soc_sw);
	if (rc < 0) {
		pr_err("Error in getting CC_SOC_SW, rc=%d\n", rc);
		goto out;
	}

	cl->init_cc_soc_sw = cc_soc_sw;
	pr_debug("Capacity learning started @ battery SOC %d init_cc_soc_sw:%d\n",
		batt_soc_msb, cl->init_cc_soc_sw);
out:
	return rc;
}

/**
 * cap_learning_done -
 * @cl: Capacity learning object
 *
 * Top level function for getting coulomb counter and post processing the
 * data once the capacity learning is complete after charge termination.
 *
 */
static int cap_learning_done(struct cap_learning *cl)
{
	int rc;

	rc = cap_learning_process_full_data(cl);
	if (rc < 0) {
		pr_err("Error in processing cap learning full data, rc=%d\n",
			rc);
		goto out;
	}

	if (cl->prime_cc_soc) {
		/* Write a FULL value to cc_soc_sw */
		rc = cl->prime_cc_soc(cl->data, cl->cc_soc_max);
		if (rc < 0) {
			pr_err("Error in writing cc_soc_sw, rc=%d\n", rc);
			goto out;
		}
	}

	cap_learning_post_process(cl);
out:
	return rc;
}

/**
 * cap_learning_update -
 * @cl: Capacity learning object
 * @batt_temp - Battery temperature
 * @batt_soc: Battery State of Charge (SOC)
 * @charge_status: Charging status from power supply
 * @charge_done: Indicator for charge termination
 * @input_present: Indicator for input presence
 * @qnovo_en: Indicator for Qnovo enable status
 *
 * Called by FG/QG driver when there is a state change (Charging status, SOC)
 *
 */
void cap_learning_update(struct cap_learning *cl, int batt_temp,
			int batt_soc, int charge_status, bool charge_done,
			bool input_present, bool qnovo_en)
{
	int rc, batt_soc_msb, batt_soc_prime;
	bool prime_cc = false;

	if (!cl)
		return;

	mutex_lock(&cl->lock);

	if (batt_temp > cl->dt.max_temp || batt_temp < cl->dt.min_temp ||
		!cl->learned_cap_uah) {
		cl->active = false;
		cl->init_cap_uah = 0;
		goto out;
	}

	batt_soc_msb = (u32)batt_soc >> 24;
	pr_debug("Charge_status: %d active: %d batt_soc: %d\n",
		charge_status, cl->active, batt_soc_msb);

	/* Initialize the starting point of learning capacity */
	if (!cl->active) {
		if (charge_status == POWER_SUPPLY_STATUS_CHARGING) {
			rc = cap_learning_begin(cl, batt_soc);
			cl->active = (rc == 0);
		} else {
			if (charge_status == POWER_SUPPLY_STATUS_DISCHARGING ||
				charge_done)
				prime_cc = true;
		}
	} else {
		if (charge_done) {
			rc = cap_learning_done(cl);
			if (rc < 0)
				pr_err("Error in completing capacity learning, rc=%d\n",
					rc);

			cl->active = false;
			cl->init_cap_uah = 0;
		}

		if (charge_status == POWER_SUPPLY_STATUS_DISCHARGING) {
			if (!input_present) {
				pr_debug("Capacity learning aborted @ battery SOC %d\n",
					 batt_soc_msb);
				cl->active = false;
				cl->init_cap_uah = 0;
				prime_cc = true;
			}
		}

		if (charge_status == POWER_SUPPLY_STATUS_NOT_CHARGING) {
			if (qnovo_en && input_present) {
				/*
				 * Don't abort the capacity learning when qnovo
				 * is enabled and input is present where the
				 * charging status can go to "not charging"
				 * intermittently.
				 */
			} else {
				pr_debug("Capacity learning aborted @ battery SOC %d\n",
					batt_soc_msb);
				cl->active = false;
				cl->init_cap_uah = 0;
				prime_cc = true;
			}
		}
	}

	/*
	 * Prime CC_SOC_SW when the device is not charging or during charge
	 * termination when the capacity learning is not active.
	 */

	if (prime_cc && cl->prime_cc_soc) {
		if (charge_done)
			batt_soc_prime = cl->cc_soc_max;
		else
			batt_soc_prime = batt_soc;

		rc = cl->prime_cc_soc(cl->data, batt_soc_prime);
		if (rc < 0)
			pr_err("Error in writing cc_soc_sw, rc=%d\n",
				rc);
	}

out:
	mutex_unlock(&cl->lock);
}

/**
 * cap_learning_abort -
 * @cl: Capacity learning object
 *
 * Aborts the capacity learning and initializes variables
 *
 */
void cap_learning_abort(struct cap_learning *cl)
{
	if (!cl)
		return;

	mutex_lock(&cl->lock);
	pr_debug("Aborting cap_learning\n");
	cl->active = false;
	cl->init_cap_uah = 0;
	mutex_lock(&cl->lock);
}

/**
 * cap_learning_post_profile_init -
 * @cl: Capacity learning object
 * @nom_cap_uah: Nominal capacity of battery in uAh
 *
 * Called by FG/QG once the profile load is complete and nominal capacity
 * of battery is known. This also gets the last learned capacity back from
 * FG/QG to feed back to the algorithm.
 *
 */
int cap_learning_post_profile_init(struct cap_learning *cl, int64_t nom_cap_uah)
{
	int64_t delta_cap_uah, pct_nom_cap_uah;
	int rc;

	if (!cl || !cl->data)
		return -EINVAL;

	mutex_lock(&cl->lock);
	cl->nom_cap_uah = nom_cap_uah;
	rc = cl->get_learned_capacity(cl->data, &cl->learned_cap_uah);
	if (rc < 0) {
		pr_err("Couldn't get learned capacity, rc=%d\n", rc);
		goto out;
	}

	if (cl->learned_cap_uah != cl->nom_cap_uah) {
		if (cl->learned_cap_uah == 0)
			cl->learned_cap_uah = cl->nom_cap_uah;

		delta_cap_uah = abs(cl->learned_cap_uah - cl->nom_cap_uah);
		pct_nom_cap_uah = div64_s64((int64_t)cl->nom_cap_uah *
				CAPACITY_DELTA_DECIPCT, 1000);
		/*
		 * If the learned capacity is out of range by 50% from the
		 * nominal capacity, then overwrite the learned capacity with
		 * the nominal capacity.
		 */
		if (cl->nom_cap_uah && delta_cap_uah > pct_nom_cap_uah) {
			pr_debug("learned_cap_uah: %lld is higher than expected, capping it to nominal: %lld\n",
				cl->learned_cap_uah, cl->nom_cap_uah);
			cl->learned_cap_uah = cl->nom_cap_uah;
		}

		rc = cl->store_learned_capacity(cl->data, cl->learned_cap_uah);
		if (rc < 0)
			pr_err("Error in storing learned_cap_uah, rc=%d\n", rc);
	}

out:
	mutex_unlock(&cl->lock);
	return rc;
}

/**
 * cap_learning_init -
 * @cl: Capacity learning object
 *
 * FG/QG have to call this during driver probe to validate the required
 * parameters after allocating cap_learning object.
 *
 */
int cap_learning_init(struct cap_learning *cl)
{
	if (!cl)
		return -ENODEV;

	if (!cl->get_learned_capacity || !cl->store_learned_capacity ||
		!cl->get_cc_soc) {
		pr_err("Insufficient functions for supporting capacity learning\n");
		return -EINVAL;
	}

	if (!cl->cc_soc_max) {
		pr_err("Insufficient parameters for supporting capacity learning\n");
		return -EINVAL;
	}

	mutex_init(&cl->lock);
	return 0;
}

/* Time to full/empty algorithm  helper functions */

static void ttf_circ_buf_add(struct ttf_circ_buf *buf, int val)
{
	buf->arr[buf->head] = val;
	buf->head = (buf->head + 1) % ARRAY_SIZE(buf->arr);
	buf->size = min(++buf->size, (int)ARRAY_SIZE(buf->arr));
}

static void ttf_circ_buf_clr(struct ttf_circ_buf *buf)
{
	buf->size = 0;
	buf->head = 0;
	memset(buf->arr, 0, sizeof(buf->arr));
}

static int cmp_int(const void *a, const void *b)
{
	return *(int *)a - *(int *)b;
}

static int ttf_circ_buf_median(struct ttf_circ_buf *buf, int *median)
{
	int *temp;

	if (buf->size == 0)
		return -ENODATA;

	if (buf->size == 1) {
		*median = buf->arr[0];
		return 0;
	}

	temp = kmalloc_array(buf->size, sizeof(*temp), GFP_KERNEL);
	if (!temp)
		return -ENOMEM;

	memcpy(temp, buf->arr, buf->size * sizeof(*temp));
	sort(temp, buf->size, sizeof(*temp), cmp_int, NULL);

	if (buf->size % 2)
		*median = temp[buf->size / 2];
	else
		*median = (temp[buf->size / 2 - 1] + temp[buf->size / 2]) / 2;

	kfree(temp);
	return 0;
}

static int ttf_lerp(const struct ttf_pt *pts, size_t tablesize,
						s32 input, s32 *output)
{
	int i;
	s64 temp;

	if (pts == NULL) {
		pr_err("Table is NULL\n");
		return -EINVAL;
	}

	if (tablesize < 1) {
		pr_err("Table has no entries\n");
		return -ENOENT;
	}

	if (tablesize == 1) {
		*output = pts[0].y;
		return 0;
	}

	if (pts[0].x > pts[1].x) {
		pr_err("Table is not in acending order\n");
		return -EINVAL;
	}

	if (input <= pts[0].x) {
		*output = pts[0].y;
		return 0;
	}

	if (input >= pts[tablesize - 1].x) {
		*output = pts[tablesize - 1].y;
		return 0;
	}

	for (i = 1; i < tablesize; i++) {
		if (input >= pts[i].x)
			continue;

		temp = ((s64)pts[i].y - pts[i - 1].y) *
						((s64)input - pts[i - 1].x);
		temp = div_s64(temp, pts[i].x - pts[i - 1].x);
		*output = temp + pts[i - 1].y;
		return 0;
	}

	return -EINVAL;
}

static int get_time_to_full_locked(struct ttf *ttf, int *val)
{
	int rc, ibatt_avg, vbatt_avg, rbatt = 0, msoc = 0, act_cap_mah = 0,
		i_cc2cv = 0, soc_cc2cv, tau, divisor, iterm = 0, ttf_mode = 0,
		i, soc_per_step, msoc_this_step, msoc_next_step,
		ibatt_this_step, t_predicted_this_step, ttf_slope,
		t_predicted_cv, t_predicted = 0, charge_type = 0,
		float_volt_uv = 0, valid = 0, charge_status = 0;
	s64 delta_ms;

	rc = ttf->get_ttf_param(ttf->data, TTF_VALID, &valid);
	if (rc < 0) {
		pr_err("failed to get ttf_valid rc=%d\n", rc);
		return rc;
	}

	if (!valid) {
		*val = -1;
		return 0;
	}

	rc =  ttf->get_ttf_param(ttf->data, TTF_CHG_STATUS, &charge_status);
	if (rc < 0) {
		pr_err("failed to get charge-status rc=%d\n", rc);
		return rc;
	}

	if (charge_status != POWER_SUPPLY_STATUS_CHARGING) {
		*val = -1;
		return 0;
	}

	rc = ttf->get_ttf_param(ttf->data, TTF_MSOC, &msoc);
	if (rc < 0) {
		pr_err("failed to get msoc rc=%d\n", rc);
		return rc;
	}
	pr_debug("TTF: msoc=%d\n", msoc);

	/* the battery is considered full if the SOC is 100% */
	if (msoc >= 100) {
		*val = 0;
		return 0;
	}

	rc = ttf->get_ttf_param(ttf->data, TTF_MODE, &ttf_mode);

	/* when switching TTF algorithms the TTF needs to be reset */
	if (ttf->mode != ttf_mode) {
		ttf_circ_buf_clr(&ttf->ibatt);
		ttf_circ_buf_clr(&ttf->vbatt);
		ttf->last_ttf = 0;
		ttf->last_ms = 0;
		ttf->mode = ttf_mode;
	}

	/* at least 10 samples are required to produce a stable IBATT */
	if (ttf->ibatt.size < MAX_TTF_SAMPLES) {
		*val = -1;
		return 0;
	}

	rc = ttf_circ_buf_median(&ttf->ibatt, &ibatt_avg);
	if (rc < 0) {
		pr_err("failed to get IBATT AVG rc=%d\n", rc);
		return rc;
	}

	rc = ttf_circ_buf_median(&ttf->vbatt, &vbatt_avg);
	if (rc < 0) {
		pr_err("failed to get VBATT AVG rc=%d\n", rc);
		return rc;
	}

	ibatt_avg = -ibatt_avg / MILLI_UNIT;
	vbatt_avg /= MILLI_UNIT;

	rc = ttf->get_ttf_param(ttf->data, TTF_ITERM, &iterm);
	if (rc < 0) {
		pr_err("failed to get iterm rc=%d\n", rc);
		return rc;
	}
	/* clamp ibatt_avg to iterm */
	if (ibatt_avg < abs(iterm))
		ibatt_avg = abs(iterm);

	rc =  ttf->get_ttf_param(ttf->data, TTF_RBATT, &rbatt);
	if (rc < 0) {
		pr_err("failed to get battery resistance rc=%d\n", rc);
		return rc;
	}
	rbatt /= MILLI_UNIT;

	rc =  ttf->get_ttf_param(ttf->data, TTF_FCC, &act_cap_mah);
	if (rc < 0) {
		pr_err("failed to get ACT_BATT_CAP rc=%d\n", rc);
		return rc;
	}

	pr_debug(" TTF: ibatt_avg=%d vbatt_avg=%d rbatt=%d act_cap_mah=%d\n",
				ibatt_avg, vbatt_avg, rbatt, act_cap_mah);

	rc =  ttf->get_ttf_param(ttf->data, TTF_VFLOAT, &float_volt_uv);
	if (rc < 0) {
		pr_err("failed to get float_volt_uv rc=%d\n", rc);
		return rc;
	}

	rc =  ttf->get_ttf_param(ttf->data, TTF_CHG_TYPE, &charge_type);
	if (rc < 0) {
		pr_err("failed to get charge_type rc=%d\n", rc);
		return rc;
	}
	/* estimated battery current at the CC to CV transition */
	switch (ttf->mode) {
	case TTF_MODE_NORMAL:
		i_cc2cv = ibatt_avg * vbatt_avg /
			max(MILLI_UNIT, float_volt_uv / MILLI_UNIT);
		break;
	case TTF_MODE_QNOVO:
		i_cc2cv = min(
			ttf->cc_step.arr[MAX_CC_STEPS - 1] / MILLI_UNIT,
			ibatt_avg * vbatt_avg /
			max(MILLI_UNIT, float_volt_uv / MILLI_UNIT));
		break;
	default:
		pr_err("TTF mode %d is not supported\n", ttf->mode);
		break;
	}
	pr_debug("TTF: i_cc2cv=%d\n", i_cc2cv);

	/* if we are already in CV state then we can skip estimating CC */
	if (charge_type == POWER_SUPPLY_CHARGE_TYPE_TAPER)
		goto cv_estimate;

	/* estimated SOC at the CC to CV transition */
	soc_cc2cv = DIV_ROUND_CLOSEST(rbatt * i_cc2cv, OCV_SLOPE_UV);
	soc_cc2cv = 100 - soc_cc2cv;
	pr_debug("TTF: soc_cc2cv=%d\n", soc_cc2cv);

	switch (ttf->mode) {
	case TTF_MODE_NORMAL:
		if (soc_cc2cv - msoc <= 0)
			goto cv_estimate;

		divisor = max(100, (ibatt_avg + i_cc2cv) / 2 * 100);
		t_predicted = div_s64((s64)act_cap_mah * (soc_cc2cv - msoc) *
						HOURS_TO_SECONDS, divisor);
		break;
	case TTF_MODE_QNOVO:
		soc_per_step = 100 / MAX_CC_STEPS;
		for (i = msoc / soc_per_step; i < MAX_CC_STEPS - 1; ++i) {
			msoc_next_step = (i + 1) * soc_per_step;
			if (i == msoc / soc_per_step)
				msoc_this_step = msoc;
			else
				msoc_this_step = i * soc_per_step;

			/* scale ibatt by 85% to account for discharge pulses */
			ibatt_this_step = min(
					ttf->cc_step.arr[i] / MILLI_UNIT,
					ibatt_avg) * 85 / 100;
			divisor = max(100, ibatt_this_step * 100);
			t_predicted_this_step = div_s64((s64)act_cap_mah *
					(msoc_next_step - msoc_this_step) *
					HOURS_TO_SECONDS, divisor);
			t_predicted += t_predicted_this_step;
			pr_debug("TTF: [%d, %d] ma=%d t=%d\n",
				msoc_this_step, msoc_next_step,
				ibatt_this_step, t_predicted_this_step);
		}
		break;
	default:
		pr_err("TTF mode %d is not supported\n", ttf->mode);
		break;
	}

cv_estimate:
	pr_debug("TTF: t_predicted_cc=%d\n", t_predicted);

	iterm = max(100, abs(iterm) + ttf->iterm_delta);
	pr_debug("TTF: iterm=%d\n", iterm);

	if (charge_type == POWER_SUPPLY_CHARGE_TYPE_TAPER)
		tau = max(MILLI_UNIT, ibatt_avg * MILLI_UNIT / iterm);
	else
		tau = max(MILLI_UNIT, i_cc2cv * MILLI_UNIT / iterm);

	rc = ttf_lerp(ttf_ln_table, ARRAY_SIZE(ttf_ln_table), tau, &tau);
	if (rc < 0) {
		pr_err("failed to interpolate tau rc=%d\n", rc);
		return rc;
	}

	/* tau is scaled linearly from 95% to 100% SOC */
	if (msoc >= 95)
		tau = tau * 2 * (100 - msoc) / 10;

	pr_debug("TTF: tau=%d\n", tau);
	t_predicted_cv = div_s64((s64)act_cap_mah * rbatt * tau *
						HOURS_TO_SECONDS, NANO_UNIT);
	pr_debug("TTF: t_predicted_cv=%d\n", t_predicted_cv);
	t_predicted += t_predicted_cv;

	pr_debug("TTF: t_predicted_prefilter=%d\n", t_predicted);
	if (ttf->last_ms != 0) {
		delta_ms = ktime_ms_delta(ktime_get_boottime(),
					  ms_to_ktime(ttf->last_ms));
		if (delta_ms > 10000) {
			ttf_slope = div64_s64(
				((s64)t_predicted - ttf->last_ttf) *
				MICRO_UNIT, delta_ms);
			if (ttf_slope > -100)
				ttf_slope = -100;
			else if (ttf_slope < -2000)
				ttf_slope = -2000;

			t_predicted = div_s64(
				(s64)ttf_slope * delta_ms, MICRO_UNIT) +
				ttf->last_ttf;
			pr_debug("TTF: ttf_slope=%d\n", ttf_slope);
		} else {
			t_predicted = ttf->last_ttf;
		}
	}

	/* clamp the ttf to 0 */
	if (t_predicted < 0)
		t_predicted = 0;

	pr_debug("TTF: t_predicted_postfilter=%d\n", t_predicted);
	*val = t_predicted;
	return 0;
}

/**
 * ttf_get_time_to_full -
 * @ttf: ttf object
 * @val: Average time to full returned to the caller
 *
 * Get Average time to full the battery based on current soc, rbatt
 * battery voltage and charge current etc.
 */
int ttf_get_time_to_full(struct ttf *ttf, int *val)
{
	int rc;

	mutex_lock(&ttf->lock);
	rc = get_time_to_full_locked(ttf, val);
	mutex_unlock(&ttf->lock);

	return rc;
}

static void ttf_work(struct work_struct *work)
{
	struct ttf *ttf = container_of(work,
				struct ttf, ttf_work.work);
	int rc, ibatt_now, vbatt_now, ttf_now, charge_status;
	int valid = 0;
	ktime_t ktime_now;

	mutex_lock(&ttf->lock);
	rc = ttf->get_ttf_param(ttf->data, TTF_VALID, &valid);
	if (rc < 0) {
		pr_err("failed to get ttf_valid rc=%d\n", rc);
		goto end_work;
	}

	if (!valid)
		goto end_work;

	rc =  ttf->get_ttf_param(ttf->data, TTF_CHG_STATUS, &charge_status);
	if (rc < 0) {
		pr_err("failed to get charge_status rc=%d\n", rc);
		goto end_work;
	}
	if (charge_status != POWER_SUPPLY_STATUS_CHARGING &&
			charge_status != POWER_SUPPLY_STATUS_DISCHARGING)
		goto end_work;

	rc =  ttf->get_ttf_param(ttf->data, TTF_IBAT, &ibatt_now);
	if (rc < 0) {
		pr_err("failed to get battery current, rc=%d\n", rc);
		goto end_work;
	}

	rc =  ttf->get_ttf_param(ttf->data, TTF_VBAT, &vbatt_now);
	if (rc < 0) {
		pr_err("failed to get battery voltage, rc=%d\n", rc);
		goto end_work;
	}

	ttf_circ_buf_add(&ttf->ibatt, ibatt_now);
	ttf_circ_buf_add(&ttf->vbatt, vbatt_now);

	if (charge_status == POWER_SUPPLY_STATUS_CHARGING) {
		rc = get_time_to_full_locked(ttf, &ttf_now);
		if (rc < 0) {
			pr_err("failed to get ttf, rc=%d\n", rc);
			goto end_work;
		}

		/* keep the wake lock and prime the IBATT and VBATT buffers */
		if (ttf_now < 0) {
			/* delay for one FG cycle */
			schedule_delayed_work(&ttf->ttf_work,
					msecs_to_jiffies(1000));
			mutex_unlock(&ttf->lock);
			return;
		}

		/* update the TTF reference point every minute */
		ktime_now = ktime_get_boottime();
		if (ktime_ms_delta(ktime_now,
				   ms_to_ktime(ttf->last_ms)) > 60000 ||
				   ttf->last_ms == 0) {
			ttf->last_ttf = ttf_now;
			ttf->last_ms = ktime_to_ms(ktime_now);
		}
	}

	/* recurse every 10 seconds */
	schedule_delayed_work(&ttf->ttf_work, msecs_to_jiffies(ttf->period_ms));
end_work:
	ttf->awake_voter(ttf->data, false);
	mutex_unlock(&ttf->lock);
}

/**
 * ttf_get_time_to_empty -
 * @ttf: ttf object
 * @val: Average time to empty returned to the caller
 *
 * Get Average time to empty the battery based on current soc
 * and average battery current.
 */
int ttf_get_time_to_empty(struct ttf *ttf, int *val)
{
	int rc, ibatt_avg, msoc, act_cap_mah, divisor, valid = 0,
		charge_status = 0;

	rc = ttf->get_ttf_param(ttf->data, TTF_VALID, &valid);
	if (rc < 0) {
		pr_err("failed to get ttf_valid rc=%d\n", rc);
		return rc;
	}

	if (!valid) {
		*val = -1;
		return 0;
	}

	rc =  ttf->get_ttf_param(ttf->data, TTF_CHG_STATUS, &charge_status);
	if (rc < 0) {
		pr_err("failed to get charge-status rc=%d\n", rc);
		return rc;
	}

	if (charge_status == POWER_SUPPLY_STATUS_CHARGING) {
		*val = -1;
		return 0;
	}

	rc = ttf_circ_buf_median(&ttf->ibatt, &ibatt_avg);
	if (rc < 0) {
		/* try to get instantaneous current */
		rc = ttf->get_ttf_param(ttf->data, TTF_IBAT, &ibatt_avg);
		if (rc < 0) {
			pr_err("failed to get battery current, rc=%d\n", rc);
			return rc;
		}
	}

	ibatt_avg /= MILLI_UNIT;
	/* clamp ibatt_avg to 100mA */
	if (ibatt_avg < 100)
		ibatt_avg = 100;

	rc = ttf->get_ttf_param(ttf->data, TTF_MSOC, &msoc);
	if (rc < 0) {
		pr_err("Error in getting capacity, rc=%d\n", rc);
		return rc;
	}

	rc = ttf->get_ttf_param(ttf->data, TTF_FCC, &act_cap_mah);
	if (rc < 0) {
		pr_err("Error in getting ACT_BATT_CAP, rc=%d\n", rc);
		return rc;
	}

	divisor = CENTI_ICORRECT_C0 * 100 + CENTI_ICORRECT_C1 * msoc;
	divisor = ibatt_avg * divisor / 100;
	divisor = max(100, divisor);
	*val = act_cap_mah * msoc * HOURS_TO_SECONDS / divisor;

	pr_debug("TTF: ibatt_avg=%d msoc=%d act_cap_mah=%d TTE=%d\n",
			ibatt_avg, msoc, act_cap_mah, *val);

	return 0;
}

/**
 * ttf_update -
 * @ttf: ttf object
 * @input_present: Indicator for input presence
 *
 * Called by FG/QG driver when there is a state change (Charging status, SOC)
 *
 */
void ttf_update(struct ttf *ttf, bool input_present)
{
	int delay_ms, rc, valid = 0;

	rc = ttf->get_ttf_param(ttf->data, TTF_VALID, &valid);
	if (rc < 0) {
		pr_err("failed to get ttf_valid rc=%d\n", rc);
		return;
	}

	if (!valid)
		return;

	if (ttf->input_present == input_present)
		return;

	ttf->input_present = input_present;
	if (input_present)
		/* wait 35 seconds for the input to settle */
		delay_ms = 35000;
	else
		/* wait 5 seconds for current to settle during discharge */
		delay_ms = 5000;

	ttf->awake_voter(ttf->data, true);
	cancel_delayed_work_sync(&ttf->ttf_work);
	mutex_lock(&ttf->lock);
	ttf_circ_buf_clr(&ttf->ibatt);
	ttf_circ_buf_clr(&ttf->vbatt);
	ttf->last_ttf = 0;
	ttf->last_ms = 0;
	mutex_unlock(&ttf->lock);
	schedule_delayed_work(&ttf->ttf_work, msecs_to_jiffies(delay_ms));
}

/**
 * ttf_tte_init -
 * @ttf: Time to full object
 *
 * FG/QG have to call this during driver probe to validate the required
 * parameters after allocating ttf object.
 *
 */
int ttf_tte_init(struct ttf *ttf)
{
	if (!ttf)
		return -ENODEV;

	if (!ttf->awake_voter || !ttf->get_ttf_param) {
		pr_err("Insufficient functions for supporting ttf\n");
		return -EINVAL;
	}

	if (!ttf->iterm_delta)
		ttf->iterm_delta = DEFAULT_TTF_ITERM_DELTA_MA;
	if (!ttf->period_ms)
		ttf->period_ms = DEFAULT_TTF_RUN_PERIOD_MS;

	mutex_init(&ttf->lock);
	INIT_DELAYED_WORK(&ttf->ttf_work, ttf_work);

	return 0;
}
