/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (C) 2024 Google LLC
 */

#include <linux/err.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include "google_bms.h"
#include "max1720x_battery.h"
#include "maxfg_logging.h"

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

/* see maxfg_ce_relaxed() */
static const enum max17x0x_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,
	MAX17X0X_TAG_vfsoc,
	MAXFG_TAG_fstat,
	MAXFG_TAG_avgt,
	MAX17X0X_TAG_temp,
	MAXFG_TAG_qh,
	MAXFG_TAG_vcel,
	MAXFG_TAG_avgv,
	MAXFG_TAG_vfocv,

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

/* this could be static */
void maxfg_init_fg_learn_capture_config(struct maxfg_capture_config *config,
					struct max17x0x_regmap *regmap,
					struct max17x0x_regmap *debug_regmap)
{
	strscpy(config->name,  "FG Learning Events", sizeof(config->name));
	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 = ARRAY_SIZE(fg_learning_param) * sizeof(u16);
}


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->latest_entry = NULL;

	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;

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

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 = max17x0x_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_capture_registers(struct maxfg_capture_buf *buf)
{
	struct maxfg_capture_config *config = &buf->config;
	const int data_size = config->data_size;
	void *latest_entry;
	int head, tail, ret;
	u16 *reg_val;

	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 * data_size];
	latest_entry = reg_val;

	ret = maxfg_read_registers(&config->normal, reg_val);
	if (ret < 0)
		goto exit_done;

	reg_val += config->normal.reg_cnt;

	ret = maxfg_read_registers(&config->debug, reg_val);
	if (ret < 0)
		goto exit_done;

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

	buf->latest_entry = latest_entry;

exit_done:
	return ret;
}

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

	for (reg_idx = 0; reg_idx < config->normal.reg_cnt && len < buf_len; reg_idx++) {
		fg_reg = max17x0x_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 = max17x0x_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;
	const int data_size = config->data_size;
	int head, tail, count, to_end, idx, rt;
	u16 *reg_val;

	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) * 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 * 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 max17x0x_regmap *regmap, const u16 relax_mask,
                      const u16 *prev_val)
{
	u16 fstat, fcnom, dpacc, dqacc;
	int ret;

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

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

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

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

	/*
	 * log when relaxed state changes, when fcnom, dpacc, dqacc change
	 * TODO: 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];
}
