/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Fuel gauge driver for MAX77779 Fuel Gauges with M5 Algo
 *
 * 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.
 */

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

#include <linux/crc8.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/power_supply.h>
#include <linux/regmap.h>
#include "google_bms.h"
#include "google_psy.h"

#include "max77779_fg.h"
#include "maxfg_common.h"

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

#define MAX7779_FG_CRC8_POLYNOMIAL		0x07	/* (x^8) + x^2 + x + 1 */
DECLARE_CRC8_TABLE(max77779_fg_crc8_table);

/*
 * b/329101930: using MAX77779 sp to save model version
 * SP reset value is undefined and only reset when entering shipmode and UVLO.
 * If current SP value is the same as model version, then model won't reload.
 * Otherwise, model will reload and SP data will be model version.
 * If enter shipmode or UVLO, POR will lead to reload model regardless of SP data.
 * So undefined reset value won't be a side effect for that.
 */
int max77779_model_read_version(const struct max77779_model_data *model_data)
{
	u8 temp;
	int ret;

	ret = gbms_storage_read(GBMS_TAG_MDLV, &temp, sizeof(temp));

	return ret < 0 ? ret : temp;
}

int max77779_model_write_version(const struct max77779_model_data *model_data, int version)
{
	u8 temp;
	int ret;

	if (version == MAX77779_FG_INVALID_VERSION)
		return 0;

	temp = (u8)version;
	ret = gbms_storage_write(GBMS_TAG_MDLV, &temp, sizeof(temp));

	return ret < 0 ? ret : 0;
}

int max77779_reset_state_data(struct max77779_model_data *model_data)
{
	struct model_state_save data;
	struct max77779_fg_chip *chip = dev_get_drvdata(model_data->dev);
	int ret = 0;

	__pm_stay_awake(chip->fg_wake_lock);
	mutex_lock(&chip->save_data_lock);

	memset(&data, 0xff, sizeof(data));

	ret = gbms_storage_write(GBMS_TAG_GMSR, &data, sizeof(data));

	mutex_unlock(&chip->save_data_lock);
	__pm_relax(chip->fg_wake_lock);

	if (ret != GBMS_GMSR_LEN)
		dev_warn(model_data->dev, "Erase GMSR fail (%d)\n", ret);

	return ret == sizeof(data) ? 0 : ret;
}

static int max77779_read_custom_model(struct regmap *regmap, u16 *model_data,
				    int count)
{
	return regmap_raw_read(regmap, MAX77779_FG_MODEL_START, model_data, count * 2);
}

static int max77779_write_custom_model(const struct maxfg_regmap *regmap, u16 *model_data,
				       int count)
{
	int ret;

	ret = regmap_raw_write(regmap->regmap, MAX77779_FG_MODEL_START, model_data, count * 2);
	if (ret < 0)
		pr_err("%s: Failed to write custom model ret=%d\n", __func__, ret);

	return ret;
}

/* Requires the fg registers be unlocked */
static int max77779_update_custom_model(struct max77779_model_data *model_data)
{
	int ret = 0;
	bool success;
	u16 *data;

	data = kzalloc(model_data->custom_model_size * 2, GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	ret = REGMAP_WRITE(model_data->regmap, MAX77779_FG_RepCap, 0);
	if (ret < 0)
		goto error_exit;

	ret = max77779_write_custom_model(model_data->regmap, model_data->custom_model,
					  model_data->custom_model_size);
	if (ret < 0) {
		dev_err(model_data->dev, "cannot write custom model (%d)\n", ret);
		goto error_exit;
	}

	ret = max77779_read_custom_model(model_data->regmap->regmap, data,
					 model_data->custom_model_size);
	if (ret < 0) {
		dev_err(model_data->dev, "cannot read custom model (%d)\n", ret);
		goto error_exit;
	}

	ret = memcmp(model_data->custom_model, data, model_data->custom_model_size * 2);
	success = ret == 0;
	if (!success) {
		dev_err(model_data->dev, "cannot write custom model (%d)\n", ret);
		dump_model(model_data->dev, MAX77779_FG_MODEL_START, model_data->custom_model,
			   model_data->custom_model_size);
		dump_model(model_data->dev, MAX77779_FG_MODEL_START, data,
			   model_data->custom_model_size);
		ret = -ERANGE;
	}

error_exit:
	kfree(data);
	return ret;
}

static int max77779_update_custom_parameters(struct max77779_model_data *model_data, int revision,
					     int sub_rev)
{
	struct max77779_custom_parameters *cp = &model_data->parameters;
	struct maxfg_regmap *debug_regmap = model_data->debug_regmap;
	struct maxfg_regmap *regmap = model_data->regmap;
	const u16 hibcfg = model_data->hibcfg > 0 ? model_data->hibcfg : 0x0909;
	int ret, attempt;
	u16 data;

	ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_nDesignCap, cp->designcap);
	if (ret < 0)
		return ret;

	ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_nFullCapRep, cp->fullcaprep);
	if (ret < 0)
		return ret;

	for (attempt = 0; attempt < 3; attempt++) {
		ret = REGMAP_WRITE(regmap, MAX77779_FG_dPAcc, cp->dpacc);
		if (ret < 0)
			continue;
		msleep(2);
		ret = REGMAP_READ(regmap, MAX77779_FG_dPAcc, &data);
		if (ret == 0 && data == 0xC80)
			break;
	}

	if (attempt == 3)
		return ret;

	if (ret == 0)
		ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_nFullCapNom, cp->fullcapnom);
	if (ret == 0)
		ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_nIChgTerm, cp->ichgterm);
	if (ret == 0)
		ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_nVEmpty, cp->v_empty);
	if (ret == 0)
		ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_nRComp0, cp->rcomp0);
	if (ret == 0)
		ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_nTempCo, cp->tempco);
	if (ret == 0)
		ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_nCycles, model_data->cycles);
	if (ret == 0)
		ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_nQRTable00, cp->qresidual00);
	if (ret == 0)
		ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_nQRTable10, cp->qresidual10);
	if (ret == 0)
		ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_nQRTable20, cp->qresidual20);
	if (ret == 0)
		ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_nQRTable30, cp->qresidual30);
	if (ret == 0)
		ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_nHibCfg, hibcfg);
	/* b/308287790 - Clear nMOdelCfg.Refresh if firmware revision < 2.6 */
	if (revision < 2 || (revision == 2 && sub_rev < 6)) {
		if (ret == 0)
			ret = REGMAP_READ(debug_regmap, MAX77779_FG_NVM_nModelCfg, &data);
		if (ret == 0)
			ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_nModelCfg, data & 0x7FFF);
	}
	if (ret == 0)
		ret = REGMAP_WRITE_VERIFY(debug_regmap, MAX77779_FG_NVM_nLearnCfg, cp->learncfg);
	if (ret == 0)
		ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_RelaxCFG, cp->relaxcfg);
	if (ret == 0)
		ret = REGMAP_WRITE(regmap, MAX77779_FG_Config, cp->config);
	if (ret == 0)
		ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_nFullSOCThr, cp->fullsocthr);
	if (ret == 0)
		ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_nMiscCfg, cp->misccfg);

	/* In INI but not part of model loading guide */
	if (ret == 0)
		ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_nThermCfg, cp->thermcfg);
	if (ret == 0)
		ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_nNVCfg0, cp->nvcfg0);
	if (ret == 0)
		ret = REGMAP_WRITE(debug_regmap, MAX77779_FG_NVM_nFilterCfg, cp->filtercfg);

	return ret;
}

/*
 * Model loading procedure version: 0.2.1
 * 0 is ok
 */
#define MODEL_LOADING_VERSION "0.2.1"
int max77779_load_gauge_model(struct max77779_model_data *model_data, int rev, int sub_rev)
{
	struct maxfg_regmap *regmap = model_data->regmap;
	u16 data, config2, status, temp;
	int rc, ret, retries;

	if (!model_data || !model_data->custom_model || !model_data->custom_model_size)
		return -ENODATA;

	if (!rev && !sub_rev)
		return -EINVAL;

	if (!regmap) {
		dev_err(model_data->dev, "Error! No regmap\n");
		return -EIO;
	}

	dev_info(model_data->dev, "Model loading version:%s\n", MODEL_LOADING_VERSION);

	/*
	 * Step 1: Check for POR (not needed, we're here when POR is set)
	 * substep: check RISC-V status, 0x82 should be present
	 */
	for (retries = 20; retries > 0; retries--) {
		ret = REGMAP_READ(regmap, MAX77779_FG_BOOT_CHECK_REG, &data);
		if (ret == 0 &&
		    (data & MAX77779_FG_BOOT_CHECK_SUCCESS) == MAX77779_FG_BOOT_CHECK_SUCCESS)
			break;

		msleep(10);
	}
	if (retries == 0) {
		dev_err(model_data->dev, "Error RISC-V is not ready\n");
		return -ETIMEDOUT;
	}

	/*
	 * Step 2: Delay until FSTAT.DNR bit == 0
	 * check FStat.DNR to wait it clear for data read
	 */
	for (retries = 20; retries > 0; retries--) {
		ret = REGMAP_READ(regmap, MAX77779_FG_FStat, &data);
		if (ret == 0 && !(data & MAX77779_FG_FStat_DNR_MASK))
			break;
		msleep(10);
	}
	dev_info(model_data->dev, "retries:%d, FSTAT:%#x\n", retries, data);
	if (retries == 0) {
		dev_err(model_data->dev, "Error FSTAT.DNR not clear\n");
		return -ETIMEDOUT;
	}

	/* Step 3.1: Unlock command */
	ret = max77779_fg_usr_lock_section(regmap, MAX77779_FG_ALL_SECTION, false);
	if (ret < 0) {
		dev_err(model_data->dev, "Error Unlock (%d)\n", ret);
		return ret;
	}

	ret = REGMAP_READ(regmap, MAX77779_FG_HibCfg, &model_data->hibcfg);
	if (ret == 0)
		ret = REGMAP_WRITE(regmap, MAX77779_FG_HibCfg, 0);
	if (ret < 0) {
		dev_err(model_data->dev, "Error read/write HibCFG (%d)\n", ret);
		goto error_done;
	}

	/* Step 3.4.1: Write/read/verify the Custom Model */
	ret = max77779_update_custom_model(model_data);
	if (ret < 0) {
		dev_err(model_data->dev, "cannot update custom model (%d)\n", ret);
		goto error_done;
	}

	/* step 3.5 Identify Battery: already done in max77779_load_state_data */

	/* Step 3.6: Write Custom Parameters */
	ret = max77779_update_custom_parameters(model_data, rev, sub_rev);
	if (ret < 0) {
		dev_err(model_data->dev, "cannot update custom parameters (%d)\n", ret);
		goto error_done;
	}

	/* Step 3.6.1: Initiate Model Loading */
	ret = REGMAP_READ(regmap, MAX77779_FG_Config2, &config2);
	if (ret < 0) {
		dev_err(model_data->dev, "Failed read config2 (%d)\n", ret);
		goto error_done;
	}

	ret = REGMAP_WRITE(regmap, MAX77779_FG_Config2, config2 | MAX77779_FG_Config2_LDMdl_MASK);
	if (ret < 0) {
		dev_err(model_data->dev, "Failed initiate model loading (%d)\n", ret);
		goto error_done;
	}

	/* Step 3.6.2: Poll Config2.LdMdl */
	for (retries = 20; retries > 0; retries--) {
		ret = REGMAP_READ(regmap, MAX77779_FG_Config2, &config2);
		if (ret == 0 && !(config2 & MAX77779_FG_Config2_LDMdl_MASK))
			break;

		usleep_range(WAIT_VERIFY, WAIT_VERIFY + 100);
	}

	if (retries == 0) {
		dev_err(model_data->dev, "cannot initiate model loading (%d)\n", ret);
		ret = -ETIMEDOUT;
		goto error_done;
	}

	/* Restore Config2 */
	ret = REGMAP_WRITE(regmap, MAX77779_FG_Config2, model_data->parameters.config2);
	if (ret < 0)
		dev_err(model_data->dev, "cannot restore Config2 (%d)\n", ret);

	/* b/328398641 need delay to internal register re-synchronized when FW ver. < 3.8 */
	if (rev < 3 || (rev == 3 && sub_rev < 8))
		msleep(200);

	/* Step 4.1: Clear POR bit */
	for (retries = 10; retries > 0; retries--) {
		ret = REGMAP_WRITE(regmap, MAX77779_FG_FG_INT_STS,
				   MAX77779_FG_FG_INT_MASK_POR_m_MASK);
		msleep(100);

		if (ret == 0)
			ret = REGMAP_READ(regmap, MAX77779_FG_FG_INT_STS, &status);

		if (ret == 0 && !(status & MAX77779_FG_FG_INT_MASK_POR_m_MASK))
			break;
	}

	if (retries == 0) {
		dev_err(model_data->dev, "cannot clear PONR bit, fg_int_sts:%#x\n", status);
		return -ETIMEDOUT;
	}

	/* Step 4.2: Lock command */
	ret = max77779_fg_usr_lock_section(regmap, MAX77779_FG_ALL_SECTION, true);
	if (ret < 0) {
		dev_err(model_data->dev, "Error Lock (%d)\n", ret);
		return ret;
	}

	/*
	 * NOTE: Not a part of loading guide
	 * version could be in the DT: this will overwrite it if set.
	 * Invalid version is not written out.
	 */
	ret = max77779_model_write_version(model_data, model_data->model_version);
	if (ret < 0) {
		dev_err(model_data->dev, "cannot update version (%d)\n", ret);
		return ret;
	}

	temp = max77779_model_read_version(model_data);
	if (model_data->model_version == MAX77779_FG_INVALID_VERSION) {
		dev_err(model_data->dev, "No Model Version, Current %x\n", temp);
		return -EINVAL;
	} else if (temp != model_data->model_version) {
		dev_err(model_data->dev, "Model Version %x, Mismatch %x\n",
			model_data->model_version, temp);
		return -EINVAL;
	}

	return 0;

error_done:
	rc = max77779_fg_usr_lock_section(regmap, MAX77779_FG_ALL_SECTION, true);
	if (rc < 0)
		dev_err(model_data->dev, "Error Lock (%d)\n", rc);

	return ret;
}

#define MAX77779_FG_CAP_MAX_RATIO	110
#define MAX77779_FG_CAP_MIN_RATIO	50
static int max77779_fg_check_state_data(struct model_state_save *state,
					struct max77779_custom_parameters *ini)
{
	int max_cap = ini->designcap * MAX77779_FG_CAP_MAX_RATIO / 100;
	int min_cap = ini->designcap * MAX77779_FG_CAP_MIN_RATIO / 100;

	if (state->rcomp0 == 0xFFFF || state->rcomp0 == 0)
		return -ERANGE;

	if (state->tempco == 0xFFFF || state->tempco == 0)
		return -ERANGE;

	if (state->fullcaprep > max_cap)
		return -ERANGE;

	if (state->fullcapnom > max_cap)
		return -ERANGE;

	if (state->fullcaprep < min_cap)
		return -ERANGE;

	if (state->fullcapnom < min_cap)
		return -ERANGE;

	if (state->cycles == 0xFFFF)
		return -ERANGE;

	return 0;
}

static u8 max77779_fg_crc(u8 *pdata, size_t nbytes, u8 crc)
{
	return crc8(max77779_fg_crc8_table, pdata, nbytes, crc);
}

static u8 max77779_fg_data_crc(char *reason, struct model_state_save *state)
{
	u8 crc;

	/* Last byte is for saving CRC */
	crc = max77779_fg_crc((u8 *)state, sizeof(struct model_state_save) - 1,
			  CRC8_INIT_VALUE);

	pr_info("%s gmsr: %X %X %X %X %X %X %X %X %X %X (%X)\n",
		reason, state->qrtable00, state->qrtable10, state->qrtable20, state->qrtable30,
		state->fullcaprep, state->fullcapnom, state->rcomp0, state->tempco,
		state->cycles, state->crc, crc);

	return crc;
}

/*
 * Load parameters and model state from permanent storage.
 * Called on boot after POR
 */
int max77779_load_state_data(struct max77779_model_data *model_data)
{
	struct max77779_custom_parameters *cp = &model_data->parameters;
	struct max77779_fg_chip *chip = dev_get_drvdata(model_data->dev);
	u8 crc;
	int ret;

	if (!model_data)
		return -EINVAL;

	/* might return -EAGAIN during init */
	mutex_lock(&chip->save_data_lock);
	ret = gbms_storage_read(GBMS_TAG_GMSR, &model_data->model_save,
				sizeof(model_data->model_save));
	mutex_unlock(&chip->save_data_lock);

	if (ret != GBMS_GMSR_LEN) {
		dev_info(model_data->dev, "Saved Model Data empty\n");
		return ret;
	}

	ret = max77779_fg_check_state_data(&model_data->model_save, cp);
	if (ret < 0)
		return ret;

	crc = max77779_fg_data_crc("restore", &model_data->model_save);
	if (crc != model_data->model_save.crc)
		return -EINVAL;

	cp->qresidual00 = model_data->model_save.qrtable00;
	cp->qresidual10 = model_data->model_save.qrtable10;
	cp->qresidual20 = model_data->model_save.qrtable20;
	cp->qresidual30 = model_data->model_save.qrtable30;
	cp->fullcaprep = model_data->model_save.fullcaprep;
	cp->fullcapnom = model_data->model_save.fullcapnom;
	cp->rcomp0 = model_data->model_save.rcomp0;
	cp->tempco = model_data->model_save.tempco;
	model_data->cycles = model_data->model_save.cycles;

	return 0;
}

/* save/commit parameters and model state to permanent storage */
int max77779_save_state_data(struct max77779_model_data *model_data)
{
	struct max77779_custom_parameters *cp = &model_data->parameters;
	struct max77779_fg_chip *chip = dev_get_drvdata(model_data->dev);

	struct model_state_save rb;
	int ret = 0;

	__pm_stay_awake(chip->fg_wake_lock);
	mutex_lock(&chip->save_data_lock);

	model_data->model_save.qrtable00 = cp->qresidual00;
	model_data->model_save.qrtable10 = cp->qresidual10;
	model_data->model_save.qrtable20 = cp->qresidual20;
	model_data->model_save.qrtable30 = cp->qresidual30;
	model_data->model_save.fullcaprep = cp->fullcaprep;
	model_data->model_save.fullcapnom = cp->fullcapnom;
	model_data->model_save.rcomp0 = cp->rcomp0;
	model_data->model_save.tempco = cp->tempco;
	model_data->model_save.cycles = model_data->cycles;

	model_data->model_save.crc = max77779_fg_data_crc("save", &model_data->model_save);


	ret = gbms_storage_write(GBMS_TAG_GMSR, (const void *)&model_data->model_save,
				 sizeof(model_data->model_save));
	if (ret != GBMS_GMSR_LEN)
		goto max77779_save_state_data_exit;

	if (ret != sizeof(model_data->model_save)) {
		ret = -ERANGE;
		goto max77779_save_state_data_exit;
	}

	/* Read back to make sure data all good */
	ret = gbms_storage_read(GBMS_TAG_GMSR, &rb, sizeof(rb));
	if (ret != GBMS_GMSR_LEN) {
		dev_info(model_data->dev, "Read Back Data Failed ret=%d\n", ret);
		goto max77779_save_state_data_exit;
	}

	if (rb.rcomp0 != model_data->model_save.rcomp0 ||
	    rb.tempco != model_data->model_save.tempco ||
	    rb.fullcaprep != model_data->model_save.fullcaprep ||
	    rb.fullcapnom != model_data->model_save.fullcapnom ||
	    rb.cycles != model_data->model_save.cycles ||
	    rb.crc != model_data->model_save.crc)
		ret = -EINVAL;
	else
		ret = 0;

max77779_save_state_data_exit:
	mutex_unlock(&chip->save_data_lock);
	__pm_relax(chip->fg_wake_lock);

	return ret;
}

bool max77779_fg_check_state(struct max77779_model_data *model_data)
{
	int rc;
	struct maxfg_regmap *regmap = model_data->regmap;
	struct maxfg_regmap *debug_regmap = model_data->debug_regmap;
	struct max77779_custom_parameters *cp = &model_data->parameters;
	const int min_cap = cp->designcap * MAX77779_FG_CAP_MIN_RATIO / 100;
	u16 fullcapnom, fullcaprep, rcomp0, tempco;

	rc = REGMAP_READ(regmap, MAX77779_FG_FullCapRep, &fullcaprep);
	if (rc == 0 && fullcaprep < min_cap)
		return false;

	rc = REGMAP_READ(regmap, MAX77779_FG_FullCapNom, &fullcapnom);
	if (rc == 0 && fullcapnom < min_cap)
		return false;

	rc = REGMAP_READ(debug_regmap, MAX77779_FG_NVM_nRComp0, &rcomp0);
	if (rc == 0 && rcomp0 == 0)
		return false;

	rc = REGMAP_READ(debug_regmap, MAX77779_FG_NVM_nTempCo, &tempco);
	if (rc == 0 && tempco == 0)
		return false;

	return true;
}

/* 0 ok, < 0 error. Call after reading from the FG */
int max77779_model_check_state(struct max77779_model_data *model_data)
{
	struct max77779_custom_parameters *fg_param = &model_data->parameters;

	if (fg_param->rcomp0 == 0xFF)
		return -ERANGE;

	if (fg_param->tempco == 0xFFFF)
		return -ERANGE;
	return 0;
}

/*
 * read fuel gauge state to parameters/model state.
 * NOTE: Called on boot if POR is not set or during save state.
 */
int max77779_model_read_state(struct max77779_model_data *model_data)
{
	int rc;
	struct maxfg_regmap *regmap = model_data->regmap;
	struct maxfg_regmap *debug_regmap = model_data->debug_regmap;
	struct max77779_custom_parameters *cp = &model_data->parameters;

	rc = REGMAP_READ(regmap, MAX77779_FG_QRTable00, &cp->qresidual00);
	if (rc == 0)
		rc = REGMAP_READ(regmap, MAX77779_FG_QRTable10, &cp->qresidual10);
	if (rc == 0)
		rc = REGMAP_READ(regmap, MAX77779_FG_QRTable20, &cp->qresidual20);
	if (rc == 0)
		rc = REGMAP_READ(regmap, MAX77779_FG_QRTable30, &cp->qresidual30);
	if (rc == 0)
		rc = REGMAP_READ(regmap, MAX77779_FG_FullCapNom, &cp->fullcapnom);
	if (rc == 0)
		rc = REGMAP_READ(regmap, MAX77779_FG_FullCapRep, &cp->fullcaprep);
	if (rc == 0)
		rc = REGMAP_READ(debug_regmap, MAX77779_FG_NVM_nRComp0, &cp->rcomp0);
	if (rc == 0)
		rc = REGMAP_READ(debug_regmap, MAX77779_FG_NVM_nTempCo, &cp->tempco);
	if (rc == 0)
		rc = REGMAP_READ(regmap, MAX77779_FG_Cycles, &model_data->cycles);

	return rc;
}

u16 max77779_get_relaxcfg(const struct max77779_model_data *model_data)
{
	return model_data->parameters.relaxcfg;
}

u16 max77779_get_designcap(const struct max77779_model_data *model_data)
{
	return model_data->parameters.designcap;
}

ssize_t max77779_model_state_cstr(char *buf, int max, struct max77779_model_data *model_data)
{
	int len = 0;

	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nRComp0,
			 model_data->parameters.rcomp0);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nTempCo,
			 model_data->parameters.tempco);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_FullCapRep,
			 model_data->parameters.fullcaprep);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_Cycles,
			 model_data->cycles);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_FullCapNom,
			 model_data->parameters.fullcapnom);

	return len;
}

int max77779_fg_param_cstr(char *buf, int max, const struct max77779_model_data *model_data)
{
	int len = 0;

	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nNVCfg0,
			 model_data->parameters.nvcfg0);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_RelaxCFG,
			 model_data->parameters.relaxcfg);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nLearnCfg,
			 model_data->parameters.learncfg);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_Config,
			 model_data->parameters.config);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_Config2,
			 model_data->parameters.config2);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nFullSOCThr,
			 model_data->parameters.fullsocthr);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nFullCapRep,
			 model_data->parameters.fullcaprep);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nDesignCap,
			 model_data->parameters.designcap);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_dPAcc,
			 model_data->parameters.dpacc);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nFullCapNom,
			 model_data->parameters.fullcapnom);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nVEmpty,
			 model_data->parameters.v_empty);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nQRTable00,
			 model_data->parameters.qresidual00);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nQRTable10,
			 model_data->parameters.qresidual10);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nQRTable20,
			 model_data->parameters.qresidual20);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nQRTable30,
			 model_data->parameters.qresidual30);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nRComp0,
			 model_data->parameters.rcomp0);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nTempCo,
			 model_data->parameters.tempco);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nIChgTerm,
			 model_data->parameters.ichgterm);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nMiscCfg,
			 model_data->parameters.misccfg);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nModelCfg,
			 model_data->parameters.modelcfg);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nThermCfg,
			 model_data->parameters.thermcfg);
	len += scnprintf(&buf[len], max - len, "%02x: %04x\n", MAX77779_FG_NVM_nFilterCfg,
			 model_data->parameters.filtercfg);

	return len;
}

/* can be use to restore parameters and model state after POR */
int max77779_fg_param_sscan(struct max77779_model_data *model_data, const char *buf, int max)
{
	int ret, index, reg, val;

	for (index = 0; index < max ; index += 1) {
		ret = sscanf(&buf[index], "%x:%x", &reg, &val);
		if (ret != 2) {
			dev_err(model_data->dev, "@%d: sscan error %d\n",
				index, ret);
			return -EINVAL;
		}

		dev_info(model_data->dev, "@%d: reg=%x val=%x\n", index, reg, val);

		switch (reg) {
		/* model parameters (fg-params) */
		case MAX77779_FG_NVM_nNVCfg0:
			model_data->parameters.nvcfg0 = val;
			break;
		case MAX77779_FG_NVM_RelaxCFG:
			model_data->parameters.relaxcfg = val;
			break;
		case MAX77779_FG_NVM_nLearnCfg:
			model_data->parameters.learncfg = val;
			break;
		case MAX77779_FG_Config:
			model_data->parameters.config = val;
			break;
		case MAX77779_FG_Config2:
			model_data->parameters.config2 = val;
			break;
		case MAX77779_FG_NVM_nFullSOCThr:
			model_data->parameters.fullsocthr = val;
			break;
		case MAX77779_FG_NVM_nFullCapRep:
			model_data->parameters.fullcaprep = val;
			break;
		case MAX77779_FG_NVM_nDesignCap:
			model_data->parameters.designcap = val;
			break;
		case MAX77779_FG_dPAcc:
			model_data->parameters.dpacc = val;
			break;
		case MAX77779_FG_NVM_nFullCapNom:
			model_data->parameters.fullcapnom = val;
			break;
		case MAX77779_FG_NVM_nVEmpty:
			model_data->parameters.v_empty = val;
			break;
		case MAX77779_FG_NVM_nQRTable00:
			model_data->parameters.qresidual00 = val;
			break;
		case MAX77779_FG_NVM_nQRTable10:
			model_data->parameters.qresidual10 = val;
			break;
		case MAX77779_FG_NVM_nQRTable20:
			model_data->parameters.qresidual20 = val;
			break;
		case MAX77779_FG_NVM_nQRTable30:
			model_data->parameters.qresidual30 = val;
			break;
		case MAX77779_FG_NVM_nRComp0:
			model_data->parameters.rcomp0 = val;
			break;
		case MAX77779_FG_NVM_nTempCo:
			model_data->parameters.tempco = val;
			break;
		case MAX77779_FG_NVM_nIChgTerm:
			model_data->parameters.ichgterm = val;
			break;
		case MAX77779_FG_NVM_nMiscCfg:
			model_data->parameters.misccfg = val;
			break;
		case MAX77779_FG_NVM_nModelCfg:
			model_data->parameters.modelcfg = val;
			break;
		case MAX77779_FG_NVM_nThermCfg:
			model_data->parameters.thermcfg = val;
			break;
		case MAX77779_FG_NVM_nFilterCfg:
			model_data->parameters.filtercfg = val;
			break;
		default:
			dev_err(model_data->dev, "@%d: reg=%x out of range\n", index, reg);
			return -EINVAL;
		}

		for ( ; index < max && buf[index] != '\n'; index++)
			;
	}

	return 0;
}

ssize_t max77779_gmsr_state_cstr(char *buf, int max)
{
	struct model_state_save saved_data;
	int ret = 0, len = 0;

	ret = gbms_storage_read(GBMS_TAG_GMSR, &saved_data, GBMS_GMSR_LEN);
	if (ret < 0)
		return ret;
	if (ret != GBMS_GMSR_LEN)
		return -EIO;

	len = scnprintf(&buf[len], max - len,
			"rcomp0     :%04X\ntempco     :%04X\n"
			"fullcaprep :%04X\ncycles     :%04X\n"
			"fullcapnom :%04X\nqresidual00:%04X\n"
			"qresidual10:%04X\nqresidual20:%04X\n"
			"qresidual30:%04X\n",
			saved_data.rcomp0, saved_data.tempco,
			saved_data.fullcaprep, saved_data.cycles,
			saved_data.fullcapnom, saved_data.qrtable00,
			saved_data.qrtable10, saved_data.qrtable20,
			saved_data.qrtable30);

	return len;
}

/* custom model parameters */
int max77779_fg_model_cstr(char *buf, int max, const struct max77779_model_data *model_data)
{
	int i, len;

	if (!model_data->custom_model || !model_data->custom_model_size)
		return -EINVAL;

	for (len = 0, i = 0; i < model_data->custom_model_size; i += 1)
		len += scnprintf(&buf[len], max - len, "%x: %04x\n",
				 MAX77779_FG_MODEL_START + i,
				 model_data->custom_model[i]);
	return len;
}

/* custom model parameters */
int max77779_fg_model_sscan(struct max77779_model_data *model_data, const char *buf, int max)
{
	int ret, index, reg, val, fg_model_end;

	if (!model_data->custom_model)
		return -EINVAL;

	/* use the default size */
	if (!model_data->custom_model_size)
		model_data->custom_model_size = MAX77779_FG_MODEL_SIZE;

	fg_model_end = MAX77779_FG_MODEL_START + model_data->custom_model_size;
	for (index = 0; index < max ; index += 1) {
		ret = sscanf(&buf[index], "%x:%x", &reg, &val);
		if (ret != 2) {
			dev_err(model_data->dev, "@%d: sscan error %d\n",
				index, ret);
			return -EINVAL;
		}

		dev_info(model_data->dev, "@%d: reg=%x val=%x\n", index, reg, val);

		if (reg >= MAX77779_FG_MODEL_START && reg < fg_model_end) {
			const int offset = reg - MAX77779_FG_MODEL_START;

			model_data->custom_model[offset] = val;
		}

		for ( ; index < max && buf[index] != '\n'; index++)
			;
	}

	return 0;
}

static int max77779_init_custom_parameters(struct device *dev,
					   struct max77779_custom_parameters *cp,
					   struct device_node *node)
{
	const char *propname = "max77779,fg-params";
	const int cnt_default = sizeof(*cp) / 2;
	int ret, cnt;

	memset(cp, 0, sizeof(*cp));

	cnt = of_property_count_elems_of_size(node, propname, sizeof(u16));
	if (cnt < 0)
		return -ENODATA;

	if (cnt != cnt_default) {
		dev_err(dev, "fg-params: %s has %d elements, need %ld\n",
			propname, cnt, sizeof(*cp) / 2);
		return -ERANGE;
	}

	ret = of_property_read_u16_array(node, propname, (u16 *)cp, cnt);
	if (ret < 0) {
		dev_err(dev, "fg-params: failed to read %s %s: %d\n",
			node->name, propname, ret);
		return -EINVAL;
	}

	return 0;
}

void max77779_free_data(struct max77779_model_data *model_data)
{
	devm_kfree(model_data->dev, model_data);
}

/* mark model_data->model_version as invalid to prevent from reloading if failed to read */
void *max77779_init_data(struct device *dev, struct device_node *node,
			 struct maxfg_regmap *regmap, struct maxfg_regmap *debug_regmap)
{
	const char *propname = "max77779,fg-model";
	struct max77779_model_data *model_data;
	int cnt, ret;
	u16 *model;
	u32 temp;

	model_data = devm_kzalloc(dev, sizeof(*model_data), GFP_KERNEL);
	if (!model_data) {
		dev_err(dev, "fg-model: %s not found\n", propname);
		return ERR_PTR(-ENOMEM);
	}

	model = devm_kmalloc_array(dev, MAX77779_FG_MODEL_SIZE, sizeof(u16),
				   GFP_KERNEL);
	if (!model) {
		dev_err(dev, "fg-model: out of memory\n");
		return ERR_PTR(-ENOMEM);
	}

	cnt = of_property_count_elems_of_size(node, propname, sizeof(u16));
	if (cnt != MAX77779_FG_MODEL_SIZE) {
		dev_err(dev, "fg-model: not found, or invalid %d\n", cnt);
		model_data->model_version = MAX77779_FG_INVALID_VERSION;
	} else {
		ret = of_property_read_u16_array(node, propname, model, cnt);
		if (ret < 0) {
			dev_err(dev, "fg-model: no data cnt=%d %s %s: %d\n",
				cnt, node->name, propname, ret);
			model_data->model_version = MAX77779_FG_INVALID_VERSION;
		} else {
			model_data->custom_model_size = cnt;
		}
	}

	model_data->force_reset_model_data =
		of_property_read_bool(node, "max77779,force-reset-model-data");

	/*
	 * Initial values: check max_m5_model_read_state() for the registers
	 * updated from max1720x_model_work()
	 */
	ret = max77779_init_custom_parameters(dev, &model_data->parameters, node);
	if (ret < 0) {
		dev_err(dev, "fg-params: not found ret=%d\n", ret);
		model_data->model_version = MAX77779_FG_INVALID_VERSION;
	}

	if (model_data->model_version != MAX77779_FG_INVALID_VERSION) {
		ret = of_property_read_u32(node, "max77779,model-version", &temp);
		if (ret < 0 || temp > 255)
			temp = MAX77779_FG_INVALID_VERSION;
		model_data->model_version = temp;
	}

	crc8_populate_msb(max77779_fg_crc8_table, MAX7779_FG_CRC8_POLYNOMIAL);

	model_data->custom_model = model;
	model_data->debug_regmap = debug_regmap;
	model_data->regmap = regmap;
	model_data->dev = dev;

	return model_data;
}
