/* 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 8
#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,

	/* 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)
{
	if (!buf)
		return;

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

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

	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;

	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 * 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:
	mutex_unlock(&buf->cb_wr_lock);
	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]);
	}

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