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

#ifndef MAX1720X_BATTERY_H_
#define MAX1720X_BATTERY_H_

#include <linux/device.h>
#include <linux/regmap.h>
#include <linux/math64.h>

#define MAX1720X_GAUGE_TYPE	0
#define MAX1730X_GAUGE_TYPE	1
#define MAX_M5_GAUGE_TYPE	2

#define EEPROM_SN	0
#define MAX1720X_SN	1

/* multiply by 2 when task period = 351 ms */
static inline int reg_to_micro_amp_h(s16 val, u16 rsense, int lsb)
{
	/* LSB: 5.0μVh/RSENSE ; Rsense LSB is 10μΩ */
	return div_s64((s64) val * 500000, rsense) * lsb;
}

/* divide by 2 when task period = 351 ms */
static inline s16 micro_amp_h_to_reg(int val, u16 rsense, int lsb)
{
	/* LSB: 5.0μVh/RSENSE ; Rsense LSB is 10μΩ */
	return div_s64((s64)(val / lsb) * rsense, 500000);
}

static inline int reg_to_micro_volt(u16 val)
{
	/* LSB: 0.078125mV */
	return div_u64((u64) val * 78125, 1000);
}

enum max17x0x_reg_tags {
	MAX17X0X_TAG_avgc,
	MAX17X0X_TAG_cnfg,
	MAX17X0X_TAG_mmdv,
	MAX17X0X_TAG_vcel,
	MAX17X0X_TAG_temp,
	MAX17X0X_TAG_curr,
	MAX17X0X_TAG_mcap,
	MAX17X0X_TAG_avgr,
	MAX17X0X_TAG_vfsoc,
	MAX17X0X_TAG_vfocv,

	MAX17X0X_TAG_BCNT,
	MAX17X0X_TAG_SNUM,
	MAX17X0X_TAG_HSTY,
	MAX17X0X_TAG_BCEA,
	MAX17X0X_TAG_rset,
	MAX17X0X_TAG_BRES,

	MAXFG_TAG_fcnom,
	MAXFG_TAG_dpacc,
	MAXFG_TAG_dqacc,
	MAXFG_TAG_fcrep,
	MAXFG_TAG_repsoc,
	MAXFG_TAG_msoc,
	MAXFG_TAG_learn,
	MAXFG_TAG_rcomp0,
	MAXFG_TAG_tempco,
	MAXFG_TAG_fstat,
	MAXFG_TAG_avgt,
	MAXFG_TAG_temp,
	MAXFG_TAG_qh,
	MAXFG_TAG_vcel,
	MAXFG_TAG_avgv,
	MAXFG_TAG_vfocv,
};

enum max17x0x_reg_types {
	GBMS_ATOM_TYPE_MAP = 0,
	GBMS_ATOM_TYPE_REG = 1,
	GBMS_ATOM_TYPE_ZONE = 2,
	GBMS_ATOM_TYPE_SET = 3,
};

/* this is a map for u16 registers */
#define ATOM_INIT_MAP(...)			\
	.type = GBMS_ATOM_TYPE_MAP,		\
	.size = 2 * sizeof((u8[]){__VA_ARGS__}),\
	.map = (u8[]){__VA_ARGS__}

#define ATOM_INIT_REG16(r)		\
	.type = GBMS_ATOM_TYPE_REG,	\
	.size = 2,			\
	.reg = r

#define ATOM_INIT_ZONE(start, sz)	\
	.type = GBMS_ATOM_TYPE_ZONE,	\
	.size = sz,			\
	.base = start

/* a set has no storage and cannot be used in load/store */
#define ATOM_INIT_SET(...)		\
	.type = GBMS_ATOM_TYPE_SET,	\
	.size = 0,			\
	.map = (u8[]){__VA_ARGS__}

#define ATOM_INIT_SET16(...)		\
	.type = GBMS_ATOM_TYPE_SET,	\
	.size = 0,			\
	.map16 = (u16[]){__VA_ARGS__}

struct max17x0x_reg {
	int type;
	int size;
	union {
		unsigned int base;
		unsigned int reg;
		const u16 *map16;
		const u8 *map;
	};
};

struct max17x0x_cache_data {
	struct max17x0x_reg atom;
	u16 *cache_data;
};

#define NB_REGMAP_MAX 256

struct max17x0x_reglog {
	u16 data[NB_REGMAP_MAX];
	DECLARE_BITMAP(valid, NB_REGMAP_MAX);
	int errors[NB_REGMAP_MAX];
	int count[NB_REGMAP_MAX];
};

struct max17x0x_regtags {
	const struct max17x0x_reg *map;
	unsigned int max;
};

struct max17x0x_regmap {
	struct regmap *regmap;
	struct max17x0x_regtags regtags;
	struct max17x0x_reglog *reglog;
};

static inline const struct max17x0x_reg *max17x0x_find_by_index(struct max17x0x_regtags *tags,
							  int index)
{
	if (index < 0 || !tags || index >= tags->max)
		return NULL;

	return &tags->map[index];
}

static inline const struct max17x0x_reg *max17x0x_find_by_tag(struct max17x0x_regmap *map,
								enum max17x0x_reg_tags tag)
{
	return max17x0x_find_by_index(&map->regtags, tag);
}

static inline int max17x0x_reg_read(struct max17x0x_regmap *map,
				    enum max17x0x_reg_tags tag,
				    u16 *val)
{
	const struct max17x0x_reg *reg;
	unsigned int tmp;
	int rtn;

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

	rtn = regmap_read(map->regmap, reg->reg, &tmp);
	if (rtn == 0)
		*val = tmp;

	return rtn;
}


int max1720x_get_capacity(struct i2c_client *client, int *iic_raw);
int max1720x_get_voltage_now(struct i2c_client *client, int *iic_raw);
int max17x0x_sw_reset(struct i2c_client *client);

/* */
#ifdef CONFIG_MAX1720X_REGLOG_LOG
static inline void max17x0x_reglog_log(struct max17x0x_reglog *reglog,
				       unsigned int reg, u16 data, int rtn)
{
	if (!reglog)
		return;

	reglog->count[reg] += 1;
	if (rtn != 0) {
		reglog->errors[reg] += 1;
	} else {
		__set_bit(reg, reglog->valid);
		reglog->data[reg] = data;
	}

}

#else
static inline void max17x0x_reglog_log(struct max17x0x_reglog *reglog,
				       unsigned int reg, u16 data, int rtn)
{

}
#endif

static inline int max17x0x_regmap_read(const struct max17x0x_regmap *map,
				       unsigned int reg,
				       u16 *val,
				       const char *name)
{
	int rtn;
	unsigned int tmp;

	if (!map->regmap) {
		pr_err("Failed to read %s, no regmap\n", name);
		return -EIO;
	}

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

	return rtn;
}

#define REGMAP_READ(regmap, what, dst) \
	max17x0x_regmap_read(regmap, what, dst, #what)

static inline int max17x0x_regmap_write(const struct max17x0x_regmap *map,
				       unsigned int reg,
				       u16 data,
				       const char *name)
{
	int rtn;

	if (!map->regmap) {
		pr_err("Failed to write %s, no regmap\n", name);
		return -EIO;
	}

	rtn = regmap_write(map->regmap, reg, data);
	if (rtn)
		pr_err("Failed to write %s\n", name);

	max17x0x_reglog_log(map->reglog, reg, data, rtn);

	return rtn;
}

#define REGMAP_WRITE(regmap, what, value) \
	max17x0x_regmap_write(regmap, what, value, #what)

#define WAIT_VERIFY	(10 * USEC_PER_MSEC) /* 10 msec */
static inline int max1720x_regmap_writeverify(const struct max17x0x_regmap *map,
					unsigned int reg,
					u16 data,
					const char *name)
{
	int tmp, ret, retries;

	if (!map->regmap) {
		pr_err("Failed to write %s, no regmap\n", name);
		return -EINVAL;
	}

	for (retries = 3; retries > 0; retries--) {
		ret = regmap_write(map->regmap, reg, data);
		if (ret < 0)
			continue;

		usleep_range(WAIT_VERIFY, WAIT_VERIFY + 100);

		ret = regmap_read(map->regmap, reg, &tmp);
		if (ret < 0)
			continue;

		if (tmp == data)
			return 0;
	}

	return -EIO;
}

#define REGMAP_WRITE_VERIFY(regmap, what, value) \
	max1720x_regmap_writeverify(regmap, what, value, #what)

enum max1720x_drift_algo_version {
	MAX1720X_DA_VER_NONE = -1,	/* MW RC2 */
	MAX1720X_DA_VER_ORIG = 0,	/* MW A0, max1720x */
	MAX1720X_DA_VER_MWA1 = 1,	/* MW A1 RC1 */
	MAX1720X_DA_VER_MWA2 = 2,	/* MW A2 RC1 */
};

#define max1720x_check_drift_enabled(dd) \
		((dd)->algo_ver >= MAX1720X_DA_VER_ORIG)
#define max1720x_check_drift_on_soc(dd) \
		((dd)->algo_ver == MAX1720X_DA_VER_MWA1)
#define max1720x_check_drift_delay(dd) \
		((dd)->algo_ver == MAX1720X_DA_VER_MWA1 ? 351 : 0)

/* fix to capacity estimation */
struct max1720x_drift_data {
	u16 rsense;
	enum max1720x_drift_algo_version algo_ver;

	u16 design_capacity;
	int cycle_band;
	int cycle_fade;
	int cycle_stable;
	int ini_rcomp0;
	int ini_tempco;
	int ini_filtercfg;
};

struct max1720x_dyn_filtercfg {
	s32 temp;
	s32 hysteresis;
	u16 curr_val;
	u16 default_val;
	u16 adjust_val;
	struct mutex lock;
	bool disable_dynamic_filtercfg;
};

extern int max1720x_fixup_comp(struct max1720x_drift_data *ddata,
			       struct max17x0x_regmap *map,
			       int plugged);
extern int max1720x_fixup_dxacc(struct max1720x_drift_data *ddata,
				struct max17x0x_regmap *map,
				int cycle_count,
				int plugged,
				int lsb);

#endif
