/*
 * Fuel gauge driver for common
 *
 * Copyright (C) 2023 Google Inc.
 *
 * 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/of.h>
#include <linux/debugfs.h>
#include "maxfg_common.h"

/* dump FG model data */
void dump_model(struct device *dev, u16 model_start, u16 *data, int count)
{
	int i, j, len;
	char buff[16 * 5 + 1] = {};

	for (i = 0; i < count; i += 16) {

		for (len = 0, j = 0; j < 16; j++)
			len += scnprintf(&buff[len], sizeof(buff) - len,
					 "%04x ", data[i + j]);

		dev_info(dev, "%x: %s\n", i + model_start, buff);
	}
}

int maxfg_get_fade_rate(struct device *dev, int bhi_fcn_count, int *fade_rate, enum gbms_property p)
{
	struct maxfg_eeprom_history hist = { 0 };
	int ret, ratio, i, fcn_sum = 0, fcr_sum = 0;
	u16 hist_idx;

	ret = gbms_storage_read(GBMS_TAG_HCNT, &hist_idx, sizeof(hist_idx));
	if (ret < 0) {
		dev_err(dev, "failed to get history index (%d)\n", ret);
		return -EIO;
	}

	dev_dbg(dev, "%s: hist_idx=%d\n", __func__, hist_idx);

	/* no fade for new battery (less than 30 cycles) */
	if (hist_idx < bhi_fcn_count)
		return 0;

	while (hist_idx >= BATT_MAX_HIST_CNT && bhi_fcn_count > 1) {
		hist_idx--;
		bhi_fcn_count--;
		if (bhi_fcn_count == 1) {
			hist_idx = BATT_MAX_HIST_CNT - 1;
			break;
		}
	}

	for (i = bhi_fcn_count; i ; i--, hist_idx--) {
		ret = gbms_storage_read_data(GBMS_TAG_HIST, &hist,
					     sizeof(hist), hist_idx);

		dev_dbg(dev, "%s: idx=%d hist.fcn=%d (%x) hist.fcr=%d (%x) ret=%d\n",
			     __func__, hist_idx, hist.fullcapnom, hist.fullcapnom,
			     hist.fullcaprep, hist.fullcaprep, ret);

		if (ret < 0 || ret != sizeof(hist))
			return -EINVAL;

		/* hist.fullcapnom = fullcapnom * 800 / designcap */
		fcn_sum += hist.fullcapnom;
		fcr_sum += hist.fullcaprep;
	}

	/* convert from maxfg_eeprom_history to percent */
	ratio = (p == GBMS_PROP_CAPACITY_FADE_RATE_FCR) ? fcr_sum / (bhi_fcn_count * 8)
							: fcn_sum / (bhi_fcn_count * 8);

	/* allow negative value when capacity larger than design */
	*fade_rate = 100 - ratio;

	return 0;
}

static const struct maxfg_reg * maxfg_find_by_index(struct maxfg_regtags *tags, int index)
{
	if (index < 0 || !tags || index >= tags->max)
		return NULL;

	return &tags->map[index];
}

const struct maxfg_reg * maxfg_find_by_tag(struct maxfg_regmap *map, enum maxfg_reg_tags tag)
{
	return maxfg_find_by_index(&map->regtags, tag);
}

int maxfg_reg_read(struct maxfg_regmap *map, enum maxfg_reg_tags tag, u16 *val)
{
	const struct maxfg_reg *reg;
	unsigned int tmp;
	int rtn;

	reg = maxfg_find_by_tag(map, tag);
	if (!reg)
		return -EINVAL;

	rtn = regmap_read(map->regmap, reg->reg, &tmp);
	if (rtn)
		pr_err("Failed to read %x\n", reg->reg);
	else
		*val = tmp;

	return rtn;
}

static int maxfg_reg_read_addr(struct maxfg_regmap *map, enum maxfg_reg_tags tag,
			       u16 *val, u16 *addr)
{
	const struct maxfg_reg *reg;
	unsigned int tmp;
	int rtn;

	reg = maxfg_find_by_tag(map, tag);
	if (!reg)
		return -EINVAL;

	*addr = reg->reg;

	rtn = regmap_read(map->regmap, reg->reg, &tmp);
	if (rtn)
		pr_err("Failed to read %x\n", reg->reg);
	else
		*val = tmp;

	return rtn;
}

static int maxfg_reg_write_verify(struct maxfg_regmap *map, enum maxfg_reg_tags tag, u16 val)
{
	const struct maxfg_reg *reg;
	unsigned int tmp = val;
	unsigned int check_tmp;
	int rtn;

	reg = maxfg_find_by_tag(map, tag);
	if (!reg)
		return -EINVAL;

	rtn = regmap_write(map->regmap, reg->reg, tmp);
	if (rtn == 0)
		rtn = regmap_read(map->regmap, reg->reg, &check_tmp);
	if (rtn)
		return -EIO;
	if (check_tmp != tmp)
		return -EAGAIN;
	return 0;
}


#define REG_HALF_HIGH(reg)     ((reg >> 8) & 0x00FF)
#define REG_HALF_LOW(reg)      (reg & 0x00FF)
int maxfg_collect_history_data(void *buff, size_t size, bool is_por, u16 designcap, u16 RSense,
			       struct maxfg_regmap *regmap, struct maxfg_regmap *regmap_debug)
{
	struct maxfg_eeprom_history hist = { 0 };
	u16 data;
	int temp, ret;

	if (is_por)
		return -EINVAL;

	ret = maxfg_reg_read(regmap_debug, MAXFG_TAG_tempco, &data);
	if (ret)
		return ret;

	hist.tempco = data;

	ret = maxfg_reg_read(regmap_debug, MAXFG_TAG_rcomp0, &data);
	if (ret)
		return ret;

	hist.rcomp0 = data;

	ret = maxfg_reg_read(regmap, MAXFG_TAG_timerh, &data);
	if (ret)
		return ret;

	/* Convert LSB from 3.2hours(192min) to 5days(7200min) */
	hist.timerh = data * 192 / 7200;

	if (!designcap) {
		ret = maxfg_reg_read(regmap, MAXFG_TAG_descap, &designcap);
		if (ret)
			return ret;
	}

	/* multiply by 100 to convert from mAh to %, LSB 0.125% */
	ret = maxfg_reg_read(regmap, MAXFG_TAG_fcnom, &data);
	if (ret)
		return ret;

	temp = (int)data * 800 / (int)designcap;
	hist.fullcapnom = temp > MAX_HIST_FULLCAP ? MAX_HIST_FULLCAP : temp;

	/* multiply by 100 to convert from mAh to %, LSB 0.125% */
	ret = maxfg_reg_read(regmap, MAXFG_TAG_fcrep, &data);
	if (ret)
		return ret;

	temp = (int)data * 800 / (int)designcap;
	hist.fullcaprep = temp > MAX_HIST_FULLCAP ? MAX_HIST_FULLCAP : temp;

	ret = maxfg_reg_read(regmap, MAXFG_TAG_msoc, &data);
	if (ret)
		return ret;

	/* Convert LSB from 1% to 2% */
	hist.mixsoc = REG_HALF_HIGH(data) / 2;

	ret = maxfg_reg_read(regmap, MAXFG_TAG_vfsoc, &data);
	if (ret)
		return ret;

	/* Convert LSB from 1% to 2% */
	hist.vfsoc = REG_HALF_HIGH(data) / 2;


	ret = maxfg_reg_read(regmap, MAXFG_TAG_mmdv, &data);
	if (ret)
		return ret;

	/* LSB is 20mV, store values from 4.2V min */
	hist.maxvolt = (REG_HALF_HIGH(data) * 20 - 4200) / 20;
	/* Convert LSB from 20mV to 10mV, store values from 2.5V min */
	hist.minvolt = (REG_HALF_LOW(data) * 20 - 2500) / 10;

	ret = maxfg_reg_read(regmap, MAXFG_TAG_mmdt, &data);
	if (ret)
		return ret;

	/* Convert LSB from 1degC to 3degC, store values from 25degC min to 70degC max */
	hist.maxtemp = s8_to_u4_boundary(((s8)REG_HALF_HIGH(data) - 25) / 3);
	/* Convert LSB from 1degC to 3degC, store values from -20degC min to 25degC max */
	hist.mintemp = s8_to_u4_boundary(((s8)REG_HALF_LOW(data) + 20) / 3);

	ret = maxfg_reg_read(regmap, MAXFG_TAG_mmdc, &data);
	if (ret)
		return ret;

	/* Convert LSB from 400uV/RSENSE(Rsense LSB is 10μΩ) to 0.5A, range 0A to 7.5A */
	hist.maxchgcurr = (s8)REG_HALF_HIGH(data) * 400 * 2 / (RSense * 10);
	hist.maxdischgcurr = -(s8)REG_HALF_LOW(data) * 400 * 2 / (RSense * 10);

	memcpy(buff, &hist, sizeof(hist));
	return (size_t)sizeof(hist);
}

/* resistance and impedance ------------------------------------------------ */

int maxfg_read_resistance_avg(u16 RSense)
{
	u16 ravg;
	int ret = 0;

	ret = gbms_storage_read(GBMS_TAG_RAVG, &ravg, sizeof(ravg));
	if (ret < 0)
		return ret;

	return reg_to_resistance_micro_ohms(ravg, RSense);
}

int maxfg_read_resistance_raw(struct maxfg_regmap *map)
{
	u16 data;
	int ret;

	ret = maxfg_reg_read(map, MAXFG_TAG_rslow, &data);
	if (ret < 0)
		return ret;

	return data;
}

int maxfg_read_resistance(struct maxfg_regmap *map, u16 RSense)
{
	int rslow;

	rslow = maxfg_read_resistance_raw(map);
	if (rslow < 0)
		return rslow;

	return reg_to_resistance_micro_ohms(rslow, RSense);
}

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

/* will return error if the value is not valid  */
int maxfg_health_get_ai(struct device *dev, int bhi_acim, u16 RSense)
{
	u16 act_impedance, act_timerh;
	int ret;

	if (bhi_acim != 0)
		return bhi_acim;

	/* read both and recalculate for compatibility */
	ret = gbms_storage_read(GBMS_TAG_ACIM, &act_impedance, sizeof(act_impedance));
	if (ret < 0)
		return -EIO;

	ret = gbms_storage_read(GBMS_TAG_THAS, &act_timerh, sizeof(act_timerh));
	if (ret < 0)
		return -EIO;

	/* need to get starting impedance (if qualified) */
	if (act_impedance == 0xffff || act_timerh == 0xffff)
		return -EINVAL;

	/* not zero, not negative */
	bhi_acim = reg_to_resistance_micro_ohms(act_impedance, RSense);

	/* TODO: correct impedance with timerh */

	dev_info(dev, "%s: bhi_acim =%d act_impedance=%x act_timerh=%x\n",
		 __func__, bhi_acim, act_impedance, act_timerh);

	return bhi_acim;
}

/* Capacity Estimation functions*/
static int batt_ce_regmap_read(struct maxfg_regmap *map, const struct maxfg_reg *bcea, u32 reg, u16 *data)
{
	int err;
	u16 val;

	if (!bcea)
		return -EINVAL;

	err = REGMAP_READ(map, bcea->map[reg], &val);
	if (err)
		return err;

	switch(reg) {
	case CE_DELTA_CC_SUM_REG:
	case CE_DELTA_VFSOC_SUM_REG:
		*data = val;
		break;
	case CE_CAP_FILTER_COUNT:
		val = val & 0x0F00;
		*data = val >> 8;
		break;
	default:
		break;
	}

	return err;
}

int batt_ce_load_data(struct maxfg_regmap *map, struct gbatt_capacity_estimation *cap_esti)
{
	u16 data;
	const struct maxfg_reg *bcea = cap_esti->bcea;

	cap_esti->estimate_state = ESTIMATE_NONE;
	if (batt_ce_regmap_read(map, bcea, CE_DELTA_CC_SUM_REG, &data) == 0)
		cap_esti->delta_cc_sum = data;
	else
		cap_esti->delta_cc_sum = 0;

	if (batt_ce_regmap_read(map, bcea, CE_DELTA_VFSOC_SUM_REG, &data) == 0)
		cap_esti->delta_vfsoc_sum = data;
	else
		cap_esti->delta_vfsoc_sum = 0;

	if (batt_ce_regmap_read(map, bcea, CE_CAP_FILTER_COUNT, &data) == 0)
		cap_esti->cap_filter_count = data;
	else
		cap_esti->cap_filter_count = 0;
	return 0;
}

void batt_ce_dump_data(const struct gbatt_capacity_estimation *cap_esti, struct logbuffer *log)
{
	logbuffer_log(log, "cap_filter_count: %d"
			    " start_cc: %d"
			    " start_vfsoc: %d"
			    " delta_cc_sum: %d"
			    " delta_vfsoc_sum: %d"
			    " state: %d"
			    " cable: %d",
			    cap_esti->cap_filter_count,
			    cap_esti->start_cc,
			    cap_esti->start_vfsoc,
			    cap_esti->delta_cc_sum,
			    cap_esti->delta_vfsoc_sum,
			    cap_esti->estimate_state,
			    cap_esti->cable_in);
}

static int batt_ce_regmap_write(struct maxfg_regmap *map,
				const struct maxfg_reg *bcea,
				u32 reg, u16 data)
{
	int err = -EINVAL;
	u16 val;

	if (!bcea)
		return -EINVAL;

	switch(reg) {
	case CE_DELTA_CC_SUM_REG:
	case CE_DELTA_VFSOC_SUM_REG:
		err = REGMAP_WRITE(map, bcea->map[reg], data);
		break;
	case CE_CAP_FILTER_COUNT:
		err = REGMAP_READ(map, bcea->map[reg], &val);
		if (err)
			return err;
		val = val & 0xF0FF;
		if (data > CE_FILTER_COUNT_MAX)
			val = val | 0x0F00;
		else
			val = val | (data << 8);
		err = REGMAP_WRITE(map, bcea->map[reg], val);
		break;
	default:
		break;
	}

	return err;
}

/* call holding &cap_esti->batt_ce_lock */
void batt_ce_store_data(struct maxfg_regmap *map, struct gbatt_capacity_estimation *cap_esti)
{
	if (cap_esti->cap_filter_count <= CE_FILTER_COUNT_MAX) {
		batt_ce_regmap_write(map, cap_esti->bcea,
					  CE_CAP_FILTER_COUNT,
					  cap_esti->cap_filter_count);
	}

	batt_ce_regmap_write(map, cap_esti->bcea,
				  CE_DELTA_VFSOC_SUM_REG,
				  cap_esti->delta_vfsoc_sum);
	batt_ce_regmap_write(map, cap_esti->bcea,
				  CE_DELTA_CC_SUM_REG,
				  cap_esti->delta_cc_sum);
}

/* call holding &cap_esti->batt_ce_lock */
void batt_ce_stop_estimation(struct gbatt_capacity_estimation *cap_esti, int reason)
{
	cap_esti->estimate_state = reason;
	cap_esti->start_vfsoc = 0;
	cap_esti->start_cc = 0;
}

int maxfg_health_write_ai(u16 act_impedance, u16 act_timerh)
{
	int ret;

	ret = gbms_storage_write(GBMS_TAG_ACIM, &act_impedance, sizeof(act_impedance));
	if (ret < 0)
		return -EIO;

	ret = gbms_storage_write(GBMS_TAG_THAS, &act_timerh, sizeof(act_timerh));
	if (ret < 0)
		return -EIO;

	return 0;
}

/* for abnormal event log */
static enum maxfg_reg_tags fg_event_regs[] = {
	MAXFG_TAG_cycles,
	MAXFG_TAG_vcel,
	MAXFG_TAG_avgv,
	MAXFG_TAG_curr,
	MAXFG_TAG_avgc,
	MAXFG_TAG_timerh,
	MAXFG_TAG_temp,
	MAXFG_TAG_repcap,
	MAXFG_TAG_mixcap,
	MAXFG_TAG_fcrep,
	MAXFG_TAG_fcnom,
	MAXFG_TAG_qresd,
	MAXFG_TAG_avcap,
	MAXFG_TAG_vfremcap,
	MAXFG_TAG_repsoc,
	MAXFG_TAG_vfsoc,
	MAXFG_TAG_msoc,
	MAXFG_TAG_vfocv,
	MAXFG_TAG_dpacc,
	MAXFG_TAG_dqacc,
	MAXFG_TAG_qh,
	MAXFG_TAG_qh0,
	MAXFG_TAG_vfsoc0,
	MAXFG_TAG_qrtable20,
	MAXFG_TAG_qrtable30,
	MAXFG_TAG_status,
	MAXFG_TAG_fstat,
};

static enum maxfg_reg_tags fg_event_dbg_regs[] = {
	MAXFG_TAG_rcomp0,
	MAXFG_TAG_tempco,
};


int maxfg_reg_log_abnormal(struct maxfg_regmap *map, struct maxfg_regmap *map_debug,
			   char *buf, int buf_len)
{
	u16 ret, i, addr, val, pos = 0;
	size_t reg_cnt = sizeof(fg_event_regs) / sizeof(enum maxfg_reg_tags);
	size_t dbg_reg_cnt = sizeof(fg_event_dbg_regs) / sizeof(enum maxfg_reg_tags);

	for (i = 0; i < reg_cnt; i++) {
		ret = maxfg_reg_read_addr(map, fg_event_regs[i], &val, &addr);
		if (ret < 0)
			return ret;
		pos += scnprintf(&buf[pos], buf_len - pos, " %04X", val);
	}

	for (i = 0; i < dbg_reg_cnt; i++) {
		ret = maxfg_reg_read_addr(map_debug, fg_event_dbg_regs[i], &val, &addr);
		if (ret < 0)
			return ret;
		pos += scnprintf(&buf[pos], buf_len - pos, " %04X", val);
	}

	return 0;
}

int maxfg_reg_log_data(struct maxfg_regmap *map, struct maxfg_regmap *map_debug, char *buf)
{
	u16 vfsoc, avcap, repcap, fullcap, fullcaprep, fullcapnom, qh0, qh, dqacc, dpacc, fstat;
	u16 qresidual, rcomp0, cycles, learncfg, tempco, filtercfg, mixcap, vfremcap, vcell, ibat;
	u16 vfsoc_addr, avcap_addr, repcap_addr, fullcap_addr, fullcaprep_addr, fullcapnom_addr;
	u16 qh0_addr, qh_addr, dqacc_addr, dpacc_addr, fstat_addr, qresidual_addr, rcomp0_addr;
	u16 cycles_addr, learncfg_addr, tempco_addr, filtercfg_addr, mixcap_addr, vfremcap_addr;
	u16 vcell_addr, ibat_addr;
	int ret, len;

	ret = maxfg_reg_read_addr(map, MAXFG_TAG_vfsoc, &vfsoc, &vfsoc_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map, MAXFG_TAG_avcap, &avcap, &avcap_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map, MAXFG_TAG_repcap, &repcap, &repcap_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map, MAXFG_TAG_fulcap, &fullcap, &fullcap_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map, MAXFG_TAG_fcrep, &fullcaprep, &fullcaprep_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map, MAXFG_TAG_fcnom, &fullcapnom, &fullcapnom_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map, MAXFG_TAG_qh0, &qh0, &qh0_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map, MAXFG_TAG_qh, &qh, &qh_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map, MAXFG_TAG_dqacc, &dqacc, &dqacc_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map, MAXFG_TAG_dpacc, &dpacc, &dpacc_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map, MAXFG_TAG_qresd, &qresidual, &qresidual_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map, MAXFG_TAG_fstat, &fstat, &fstat_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map, MAXFG_TAG_learn, &learncfg, &learncfg_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map_debug, MAXFG_TAG_tempco, &tempco, &tempco_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map_debug, MAXFG_TAG_filcfg, &filtercfg, &filtercfg_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map, MAXFG_TAG_mcap, &mixcap, &mixcap_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map, MAXFG_TAG_vfcap, &vfremcap, &vfremcap_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map, MAXFG_TAG_vcel, &vcell, &vcell_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map, MAXFG_TAG_curr, &ibat, &ibat_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map_debug, MAXFG_TAG_rcomp0, &rcomp0, &rcomp0_addr);
	if (ret < 0)
		return ret;

	ret = maxfg_reg_read_addr(map, MAXFG_TAG_cycles, &cycles, &cycles_addr);
	if (ret < 0)
		return ret;

	len = scnprintf(&buf[0], PAGE_SIZE, "%02X:%04X %02X:%04X %02X:%04X %02X:%04X"
			" %02X:%04X %02X:%04X %02X:%04X %02X:%04X %02X:%04X %02X:%04X"
			" %02X:%04X %02X:%04X %02X:%04X %02X:%04X %02X:%04X %02X:%04X"
			" %02X:%04X %02X:%04X %02X:%04X %02X:%04X %02X:%04X",
			vfsoc_addr, vfsoc, avcap_addr, avcap, repcap_addr, repcap,
			fullcap_addr, fullcap, fullcaprep_addr, fullcaprep,
			fullcapnom_addr, fullcapnom, qh0_addr, qh0, qh_addr, qh, dqacc_addr, dqacc,
			dpacc_addr, dpacc, qresidual_addr, qresidual, fstat_addr, fstat,
			learncfg_addr, learncfg, tempco_addr, tempco, filtercfg_addr, filtercfg,
			mixcap_addr, mixcap, vfremcap_addr, vfremcap, vcell_addr, vcell,
			ibat_addr , ibat, rcomp0_addr, rcomp0, cycles_addr, cycles);

	return len;
}

/* learning parameters */
#define MAX_FG_LEARNING_CONFIG_NORMAL_REGS 14
#define MAX_FG_LEARNING_CONFIG_DEBUG_REGS 2

static enum maxfg_reg_tags fg_learning_param[] ={
	/* from normal regmap */
	MAXFG_TAG_fcnom,
	MAXFG_TAG_dpacc,
	MAXFG_TAG_dqacc,
	MAXFG_TAG_fcrep,
	MAXFG_TAG_repsoc,
	MAXFG_TAG_msoc,
	MAXFG_TAG_vfsoc,
	MAXFG_TAG_fstat,
	MAXFG_TAG_avgt,
	MAXFG_TAG_temp,
	MAXFG_TAG_qh,
	MAXFG_TAG_vcel,
	MAXFG_TAG_avgv,
	MAXFG_TAG_vfocv,

	/* from debug_regmap */
	MAXFG_TAG_rcomp0,
	MAXFG_TAG_tempco,
};

void maxfg_init_fg_learn_capture_config(struct maxfg_capture_config *config,
					struct maxfg_regmap *regmap,
					struct maxfg_regmap *debug_regmap)
{
	if (!config) {
		pr_err("no config for logging FG learn\n");
		return;
	}

	scnprintf(&config->name[0], MAX_FG_CAPTURE_CONFIG_NAME_MAX, "FG Learning Parameters");
	config->normal.tag = &fg_learning_param[0];
	config->normal.reg_cnt = MAX_FG_LEARNING_CONFIG_NORMAL_REGS;
	config->normal.regmap = regmap;

	config->debug.tag = &fg_learning_param[MAX_FG_LEARNING_CONFIG_NORMAL_REGS];
	config->debug.reg_cnt = MAX_FG_LEARNING_CONFIG_DEBUG_REGS;
	config->debug.regmap = debug_regmap;

	config->data_size = (config->normal.reg_cnt + config->debug.reg_cnt) * sizeof(u16);
}

static inline int maxfg_read_registers(struct maxfg_capture_regs *regs, u16 *buffer)
{
	int ret, idx;

	for (idx = 0; idx < regs->reg_cnt; idx++) {
		ret = maxfg_reg_read(regs->regmap, regs->tag[idx], &buffer[idx]);
		if (ret < 0) {
			pr_err("failed to reg_tag(%u) %d\n", regs->tag[idx], ret);
			return ret;
		}
	}

	return 0;
}

int maxfg_alloc_capture_buf(struct maxfg_capture_buf *buf, int slots)
{
	if ((slots & (slots-1)) || !buf || !buf->config.data_size || !slots)
		return -EINVAL;

	buf->slots = 0;
	buf->cb.buf = kzalloc(buf->config.data_size * slots, GFP_KERNEL);
	if (!buf->cb.buf)
		return -ENOMEM;

	buf->cb.head = 0;
	buf->cb.tail = 0;
	buf->slots = slots;
	buf->latest_entry = NULL;

	mutex_init(&buf->cb_wr_lock);
	mutex_init(&buf->cb_rd_lock);

	return 0;
}

void maxfg_clear_capture_buf(struct maxfg_capture_buf *buf)
{
	int head, tail;

	if (!buf || !buf->cb.buf)
		return;

	mutex_lock(&buf->cb_wr_lock);
	mutex_lock(&buf->cb_rd_lock);

	head = buf->cb.head;
	tail = buf->cb.tail;

	if (CIRC_CNT(head, tail, buf->slots)) {
		head = (head + 1) & (buf->slots - 1);

		smp_wmb();

		/* make buffer empty by (head == tail) while preserving latest_entry as a seed */
		WRITE_ONCE(buf->cb.head, head);
		WRITE_ONCE(buf->cb.tail, head);
	}

	mutex_unlock(&buf->cb_rd_lock);
	mutex_unlock(&buf->cb_wr_lock);
}

void maxfg_free_capture_buf(struct maxfg_capture_buf *buf)
{
	if (!buf || !buf->cb.buf ){
		pr_err("Invalid maxfg_capture_buf\n");
		return;
	}

	if (buf->cb.buf && buf->slots > 0)
		kfree(buf->cb.buf);

	mutex_destroy(&buf->cb_wr_lock);
	mutex_destroy(&buf->cb_rd_lock);

	buf->cb.buf = NULL;
	buf->slots = 0;
}

int maxfg_capture_registers(struct maxfg_capture_buf *buf)
{
	struct maxfg_capture_config *config = &buf->config;
	u16* reg_val;
	void* latest_entry;
	int head, tail, ret;

	mutex_lock(&buf->cb_wr_lock);

	head = buf->cb.head;
	tail = READ_ONCE(buf->cb.tail);

	/* if buffer is full, drop the last entry */
	if (CIRC_SPACE(head, tail, buf->slots) == 0) {
		mutex_lock(&buf->cb_rd_lock);
		WRITE_ONCE(buf->cb.tail, (tail + 1) & (buf->slots - 1));
		mutex_unlock(&buf->cb_rd_lock);
	}

	reg_val = (u16*)&buf->cb.buf[head * buf->config.data_size];
	latest_entry = reg_val;

	ret = maxfg_read_registers(&config->normal, reg_val);
	if (ret < 0) {
		mutex_unlock(&buf->cb_wr_lock);
		return ret;
	}

	reg_val += config->normal.reg_cnt;

	ret = maxfg_read_registers(&config->debug, reg_val);
	if (ret < 0) {
		mutex_unlock(&buf->cb_wr_lock);
		return ret;
	}

	smp_wmb();
	WRITE_ONCE(buf->cb.head, (head + 1) & (buf->slots - 1));

	buf->latest_entry = latest_entry;
	mutex_unlock(&buf->cb_wr_lock);

	return 0;
}

int maxfg_capture_to_cstr(struct maxfg_capture_config *config, u16* reg_val,
				 char* str_buf, int buf_len)
{
	const struct maxfg_reg *fg_reg;
	int len = 0, reg_idx = 0;

	for (reg_idx = 0; reg_idx < config->normal.reg_cnt && len < buf_len; reg_idx++) {
		fg_reg = maxfg_find_by_tag(config->normal.regmap, config->normal.tag[reg_idx]);
		if (!fg_reg)
			return len;

		len += scnprintf(&str_buf[len], buf_len - len, "%02X:%04X ", fg_reg->reg,
				 reg_val[reg_idx]);
	}

	reg_val += config->normal.reg_cnt;

	for (reg_idx = 0; reg_idx < config->debug.reg_cnt && len < buf_len; reg_idx++) {
		fg_reg = maxfg_find_by_tag(config->debug.regmap, config->debug.tag[reg_idx]);
		if (!fg_reg)
			return len;

		len += scnprintf(&str_buf[len], buf_len - len, "%02X:%04X ", fg_reg->reg,
				 reg_val[reg_idx]);
	}

	len += scnprintf(&str_buf[len], buf_len - len, "TS:%X",
			 (unsigned int)ktime_get_real_seconds());

	return len;
}

int maxfg_show_captured_buffer(struct maxfg_capture_buf *buf, char *str_buf, int buf_len)
{
	struct maxfg_capture_config *config = &buf->config;
	u16* reg_val;
	int head, tail, count, to_end, idx, rt;

	if (!buf)
		return -EINVAL;

	mutex_lock(&buf->cb_rd_lock);

	head = READ_ONCE(buf->cb.head);
	tail = buf->cb.tail;

	count = CIRC_CNT(head, tail, buf->slots);
	rt = scnprintf(&str_buf[0], buf_len, "%s (%d):\n", config->name, count);

	if (count == 0)
		goto maxfg_show_captured_buffer_exit;

	to_end = CIRC_CNT_TO_END(head, tail, buf->slots);

	for (idx = 0; idx < to_end && rt < buf_len; idx++) {
		reg_val = (u16*)&buf->cb.buf[(tail+idx) * buf->config.data_size];
		rt += maxfg_capture_to_cstr(config, reg_val, &str_buf[rt], buf_len - rt);
		rt += scnprintf(&str_buf[rt], buf_len - rt, "\n");
	}

	count -= idx;

	for (idx = 0; idx < count && rt < buf_len; idx++) {
		reg_val = (u16*)&buf->cb.buf[idx * buf->config.data_size];
		rt += maxfg_capture_to_cstr(config, reg_val, &str_buf[rt], buf_len - rt);
		rt += scnprintf(&str_buf[rt], buf_len - rt, "\n");
	}

maxfg_show_captured_buffer_exit:
	mutex_unlock(&buf->cb_rd_lock);

	return rt;
}

/*
 * data in prev_val follows the order of fg_learning_param[]
 *  prev_val[0]: fcnom
 *  prev_val[1]: dpacc
 *  prev_val[2]: dqacc
 *  prev_val[7]: fstat
*/
bool maxfg_ce_relaxed(struct maxfg_regmap *regmap, const u16 relax_mask, const u16* prev_val)
{
	u16 fstat, fcnom, dqacc, dpacc;
	int ret;

	ret = maxfg_reg_read(regmap, MAXFG_TAG_fstat, &fstat);
	if (ret < 0)
		return false;

	ret = maxfg_reg_read(regmap, MAXFG_TAG_fcnom, &fcnom);
	if (ret < 0)
		return false;

	ret = maxfg_reg_read(regmap, MAXFG_TAG_dpacc, &dpacc);
	if (ret < 0)
		return false;

	ret = maxfg_reg_read(regmap, MAXFG_TAG_dqacc, &dqacc);
	if (ret < 0)
		return false;

	/*
	 * log when relaxed state changes, when fcnom, dpacc, dqacc change
	 * TODO: b/326639382
	 *  - log only when dpacc, dqacc or fcnom change and simply
	 *    count the relaxation event otherwise.
	 */
	return (fstat & relax_mask) != (prev_val[7] & relax_mask) ||
		dpacc != prev_val[1] || dqacc != prev_val[2] ||
		fcnom != prev_val[0];
}

bool maxfg_is_relaxed(struct maxfg_regmap *regmap, u16 *fstat, u16 mask)
{
	return maxfg_reg_read(regmap, MAXFG_TAG_fstat, fstat) == 0 &&
		(*fstat & mask);
}

#define MAXFG_DR_VFSOC_DELTA_DEFAULT		0
#define MAXFG_DR_LEARN_STAGE_MIN_DEFAULT	7
#define MAXFG_DR_TEMP_MIN_DEFAULT		150
#define MAXFG_DR_TEMP_MAX_DEFAULT		350
#define MAXFG_DR_VFOCV_MV_INHIB_MIN_DEFAULT	3900
#define MAXFG_DR_VFOCV_MV_INHIB_MAX_DEFAULT	4200
#define MAXFG_DR_RELAX_INVALID			0xffff
#define MAXFG_DR_RELCFG_INHIBIT			0x1ff
#define MAXFG_DR_RELAX_FIRST			false

/* true if the device is allowed to relax given the parameters */
bool maxfg_dynrel_can_relax(struct maxfg_dynrel_state *dr_state,
			    struct maxfg_regmap *regmap)
{
	const bool has_vfocv_range = dr_state->vfocv_inhibit.min !=
					dr_state->vfocv_inhibit.max;
	const bool has_temp_range = dr_state->temp_qual.min !=
					dr_state->temp_qual.max;
	bool allowed = true;
	u16 delta_vfsoc;
	int ret;

	ret = maxfg_reg_read(regmap, MAXFG_TAG_vfsoc, &dr_state->vfsoc_last);
	if (ret < 0)
		allowed = false;

	ret = maxfg_reg_read(regmap, MAXFG_TAG_temp, &dr_state->temp_last);
	if (ret < 0 || (has_temp_range &&
			(dr_state->temp_last < dr_state->temp_qual.min ||
			dr_state->temp_last > dr_state->temp_qual.max)))
		allowed = false;

	/* exclude */
	ret = maxfg_reg_read(regmap, MAXFG_TAG_vfocv, &dr_state->vfocv_last);
	if (ret < 0 || (has_vfocv_range &&
			dr_state->vfocv_last >= dr_state->vfocv_inhibit.min &&
			dr_state->vfocv_last <= dr_state->vfocv_inhibit.max))
		allowed = false;

	/*
	 * define MAXFG_DR_RELAX_FIRST to true to always qualify the first
	 * relaxation after boot. Set it to false to qualify the first
	 * relaxation after boot with valid soc, temperature and inhibit ranges
	 * (if defined).
	 */
	if (dr_state->vfsoc_det == MAXFG_DR_RELAX_INVALID)
		return MAXFG_DR_RELAX_FIRST || allowed;

	/* ->vfsoc_delta=0 will void this test */
	delta_vfsoc = abs(dr_state->vfsoc_last - dr_state->vfsoc_det);
	if (delta_vfsoc < dr_state->vfsoc_delta)
		allowed = false;

	return allowed;
}

int maxfg_dynrel_mark_det(struct maxfg_dynrel_state *dr_state,
			    struct maxfg_regmap *regmap)
{
	int ret;

	/* needs vfsoc, dpacc, dqacc for next round */
	ret = maxfg_reg_read(regmap, MAXFG_TAG_vfsoc, &dr_state->vfsoc_det);
	if (ret == 0)
		ret = maxfg_reg_read(regmap, MAXFG_TAG_dpacc, &dr_state->dpacc_det);
	if (ret == 0)
		ret = maxfg_reg_read(regmap, MAXFG_TAG_dqacc, &dr_state->dqacc_det);
	if (ret < 0)
		return -EIO;

	ret = maxfg_reg_read(regmap, MAXFG_TAG_temp, &dr_state->temp_det);
	if (ret < 0)
		dr_state->temp_det = 0xffff;
	ret = maxfg_reg_read(regmap, MAXFG_TAG_vfocv, &dr_state->vfocv_det);
	if (ret < 0)
		dr_state->vfocv_det = 0xffff;

	return 0;
}

int maxfg_dynrel_override_dxacc(struct maxfg_dynrel_state *dr_state,
				struct maxfg_regmap *regmap)
{
	int ret;

	/* ignore if there is no previous relaxation */
	if (dr_state->vfsoc_det == MAXFG_DR_RELAX_INVALID)
		return -EINVAL;

	ret = maxfg_reg_write_verify(regmap, MAXFG_TAG_dpacc,
				     dr_state->dpacc_det);
	if (ret == 0)
		ret = maxfg_reg_write_verify(regmap, MAXFG_TAG_dqacc,
					     dr_state->dqacc_det);

	return ret;
}

/* enable=false inhibit relaxation unless ->relcfg_allow==->relcfg_inhibit */
int maxfg_dynrel_relaxcfg(struct maxfg_dynrel_state *dr_state,
			  struct maxfg_regmap *regmap, bool enable)
{
	return maxfg_reg_write_verify(regmap, MAXFG_TAG_relaxcfg, enable ?
			dr_state->relcfg_allow : dr_state->relcfg_inhibit);
}

void maxfg_dynrel_init(struct maxfg_dynrel_state *dr_state,
		       struct device_node *node)
{
	u16 value16;
	u32 value;
	int ret;

	dr_state->vfsoc_det = MAXFG_DR_RELAX_INVALID;

	ret = of_property_read_u16(node, "maxfg,dr_relcfg_inhibit", &value16);
	if (ret < 0)
		value16 = MAXFG_DR_RELCFG_INHIBIT;
	dr_state->relcfg_inhibit = value16;

	/* if set override the one from the model */
	ret = of_property_read_u16(node, "maxfg,dr_relcfg_allow", &value16);
	if (ret == 0)
		dr_state->relcfg_allow = value16;

	/*  default to override_mode if allow=relax will set if explicit */
	dr_state->override_mode =
		dr_state->relcfg_inhibit == dr_state->relcfg_allow ||
		of_property_read_bool(node, "maxfg,dr_mode_override");

	ret = of_property_read_u32(node, "maxfg,dr_vfsoc_delta", &value);
	if (ret < 0)
		value = MAXFG_DR_VFSOC_DELTA_DEFAULT;
	dr_state->vfsoc_delta = percentage_to_reg(value);

	ret = of_property_read_u32(node, "maxfg,learn_stage_min", &value);
	if (ret < 0)
		value = MAXFG_DR_LEARN_STAGE_MIN_DEFAULT;
	dr_state->learn_stage_min = value;

	ret = of_property_read_u32(node, "maxfg,dr_min_deci_temp_c", &value);
	if (ret < 0)
		value = MAXFG_DR_TEMP_MIN_DEFAULT;
	dr_state->temp_qual.min = deci_deg_cel_to_reg(value);
	ret = of_property_read_u32(node, "maxfg,dr_max_deci_temp_c", &value);
	if (ret < 0)
		value = MAXFG_DR_TEMP_MAX_DEFAULT;
	dr_state->temp_qual.max = deci_deg_cel_to_reg(value);

	ret = of_property_read_u32(node, "maxfg,vfocv_inhibit_min_mv", &value);
	if (ret < 0)
		value = MAXFG_DR_VFOCV_MV_INHIB_MIN_DEFAULT;
	dr_state->vfocv_inhibit.min = micro_volt_to_reg(value * 1000);
	ret = of_property_read_u32(node, "maxfg,vfocv_inhibit_max_mv", &value);
	if (ret < 0)
		value = MAXFG_DR_VFOCV_MV_INHIB_MAX_DEFAULT;
	dr_state->vfocv_inhibit.max = micro_volt_to_reg(value * 1000);
}

void maxfg_dynrel_log_cfg(struct logbuffer *mon, struct device *dev,
			  const struct maxfg_dynrel_state *dr_state)
{
	gbms_logbuffer_devlog(mon, dev, LOGLEVEL_INFO, 0, LOGLEVEL_INFO,
		"dynrel_cfg temp=%d,%d vfocv=%d,%d delta=%d cfg=%x,%x dxacc=%d",
		reg_to_deci_deg_cel(dr_state->temp_qual.min),
		reg_to_deci_deg_cel(dr_state->temp_qual.max),
		reg_to_micro_volt(dr_state->vfocv_inhibit.min) / 1000,
		reg_to_micro_volt(dr_state->vfocv_inhibit.max) / 1000,
		reg_to_percentage(dr_state->vfsoc_delta),
		dr_state->relcfg_allow, dr_state->relcfg_inhibit,
		dr_state->override_mode);
}

static void maxfg_dynrel_log__(struct logbuffer *mon, struct device *dev,
			       const struct maxfg_dynrel_state *dr_state,
			        u16 fstat, u16 vfocv, u16 vfsoc, u16 temp)
{
	int vfsoc_det;

	if (dr_state->vfsoc_det == MAXFG_DR_RELAX_INVALID) {
		vfsoc_det = -1;
	} else {
		vfsoc_det = reg_to_percentage(dr_state->vfsoc_det);
	}

	gbms_logbuffer_devlog(mon, dev, LOGLEVEL_INFO, 0, LOGLEVEL_INFO,
			"dynrel fstat=%x sticky=%d allowed=%d vsoc_det=%d, temp=%d vfocv=%d vfsoc=%d dpacc_det=%d dqacc_det=%d",
			fstat, dr_state->sticky_cnt, dr_state->relax_allowed,
			vfsoc_det, reg_to_deci_deg_cel(temp),
			reg_to_micro_volt(vfocv) / 1000,
			reg_to_percentage(vfsoc),
			dr_state->dpacc_det, dr_state->dqacc_det);
}


void maxfg_dynrel_log_rel(struct logbuffer *mon, struct device *dev, u16 fstat,
			  const struct maxfg_dynrel_state *dr_state)
{
	maxfg_dynrel_log__(mon, dev, dr_state, fstat, dr_state->vfocv_det,
			   dr_state->vfsoc_det, dr_state->temp_det);
}

void maxfg_dynrel_log(struct logbuffer *mon, struct device *dev, u16 fstat,
		      const struct maxfg_dynrel_state *dr_state)
{
	maxfg_dynrel_log__(mon, dev, dr_state, fstat, dr_state->vfocv_last,
			   dr_state->vfsoc_last, dr_state->temp_last);
}