/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Support For Battery EEPROM
 *
 * Copyright 2018 Google, LLC
 *
 */

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

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#include <linux/nvmem-consumer.h>
#include <linux/module.h>
#include <linux/delay.h>
#include "gbms_storage.h"

#define BATT_EEPROM_TAG_MINF_OFFSET	0x00
#define BATT_EEPROM_TAG_MINF_LEN	GBMS_MINF_LEN
#define BATT_EEPROM_TAG_BGPN_OFFSET	0x03
#define BATT_EEPROM_TAG_BGPN_LEN	GBMS_BGPN_LEN
#define BATT_EEPROM_TAG_BRID_OFFSET	0x17
#define BATT_EEPROM_TAG_BRID_LEN	1
#define BATT_EEPROM_TAG_MYMD_OFFSET	0x1A
#define BATT_EEPROM_TAG_MYMD_LEN	4
#define BATT_EEPROM_TAG_STRD_OFFSET	0x1E
#define BATT_EEPROM_TAG_STRD_LEN	12
#define BATT_EEPROM_TAG_RSOC_OFFSET	0x2A
#define BATT_EEPROM_TAG_RSOC_LEN	2
#define BATT_EEPROM_TAG_ACIM_OFFSET	0x2C
#define BATT_EEPROM_TAG_ACIM_LEN	2
#define BATT_EEPROM_TAG_BCNT_OFFSET	0x2E
#define BATT_EEPROM_TAG_BCNT_LEN	(GBMS_CCBIN_BUCKET_COUNT * 2)
#define BATT_EEPROM_TAG_GMSR_OFFSET	0x42
#define BATT_EEPROM_TAG_GMSR_LEN	GBMS_GMSR_LEN
#define BATT_EEPROM_TAG_LOTR_OFFSET	0x59 // Layout Track
#define BATT_EEPROM_TAG_LOTR_LEN	1
#define BATT_EEPROM_TAG_CNHS_OFFSET	0x5A
#define BATT_EEPROM_TAG_CNHS_LEN	2
#define BATT_EEPROM_TAG_SELC_OFFSET	0x5C
#define BATT_EEPROM_TAG_SELC_LEN	1
#define BATT_EEPROM_TAG_CELC_OFFSET	0x5D
#define BATT_EEPROM_TAG_CELC_LEN	1

#define BATT_EEPROM_TAG_HIST_OFFSET	0x5E
#define BATT_EEPROM_TAG_HIST_LEN	BATT_ONE_HIST_LEN
#define BATT_TOTAL_HIST_LEN		(BATT_ONE_HIST_LEN * BATT_MAX_HIST_CNT)

#define BATT_EEPROM_TAG_EXTRA_START	(BATT_EEPROM_TAG_HIST_OFFSET + BATT_TOTAL_HIST_LEN)

// 0x3E2 is the first free with 75 history entries
#define BATT_EEPROM_TAG_AYMD_OFFSET	0x3E4
#define BATT_EEPROM_TAG_AYMD_LEN	4
#define BATT_EEPROM_TAG_GCFE_OFFSET	0x3E8
#define BATT_EEPROM_TAG_GCFE_LEN	2
#define BATT_EEPROM_TAG_RAVG_OFFSET	0x3EA
#define BATT_EEPROM_TAG_RAVG_LEN	2
#define BATT_EEPROM_TAG_RFCN_OFFSET	0x3EC
#define BATT_EEPROM_TAG_RFCN_LEN	2
#define BATT_EEPROM_TAG_DINF_OFFSET	0x3EE
#define BATT_EEPROM_TAG_DINF_LEN	GBMS_DINF_LEN
#define BATT_EEPROM_TAG_THAS_OFFSET	0x3FE
#define BATT_EEPROM_TAG_THAS_LEN	2

static struct gbms_storage_desc *gbee_desc;

#define GBEE_GET_NVRAM(ptr) ((struct nvmem_device *)(ptr))
#define GBEE_STORAGE_INFO(tag, addr, count, ptr) \
	(gbee_desc && gbee_desc->info) ? gbee_desc->info(tag, addr, count, ptr) : \
		gbee_storage_info(tag, addr, count, ptr)

/*
 * I2C error when try to write continuous data.
 * Add delay before write to wait previous internal write complete
 * http://b/179235291#comment8
 */
#define BATT_WAIT_INTERNAL_WRITE_MS	1

int gbee_storage_info(gbms_tag_t tag, size_t *addr, size_t *count, void *ptr)
{
	int ret = 0;

	switch (tag) {
	case GBMS_TAG_MINF:
		*addr = BATT_EEPROM_TAG_MINF_OFFSET;
		*count = BATT_EEPROM_TAG_MINF_LEN;
		break;
	case GBMS_TAG_DINF:
		*addr = BATT_EEPROM_TAG_DINF_OFFSET;
		*count = BATT_EEPROM_TAG_DINF_LEN;
		break;
	case GBMS_TAG_HIST:
		*addr = BATT_EEPROM_TAG_HIST_OFFSET;
		*count = BATT_EEPROM_TAG_HIST_LEN;
		break;
	case GBMS_TAG_SNUM:
	case GBMS_TAG_BGPN:
		*addr = BATT_EEPROM_TAG_BGPN_OFFSET;
		*count = BATT_EEPROM_TAG_BGPN_LEN;
		break;
	case GBMS_TAG_GMSR:
		*addr = BATT_EEPROM_TAG_GMSR_OFFSET;
		*count = BATT_EEPROM_TAG_GMSR_LEN;
		break;
	case GBMS_TAG_BCNT:
		*addr = BATT_EEPROM_TAG_BCNT_OFFSET;
		*count = BATT_EEPROM_TAG_BCNT_LEN;
		break;
	case GBMS_TAG_CNHS:
		*addr = BATT_EEPROM_TAG_CNHS_OFFSET;
		*count = BATT_EEPROM_TAG_CNHS_LEN;
		break;
	case GBMS_TAG_LOTR:
		*addr = BATT_EEPROM_TAG_LOTR_OFFSET;
		*count = BATT_EEPROM_TAG_LOTR_LEN;
		break;
	case GBMS_TAG_SELC:
		*addr = BATT_EEPROM_TAG_SELC_OFFSET;
		*count = BATT_EEPROM_TAG_SELC_LEN;
		break;
	case GBMS_TAG_CELC:
		*addr = BATT_EEPROM_TAG_CELC_OFFSET;
		*count = BATT_EEPROM_TAG_CELC_LEN;
		break;
	case GBMS_TAG_STRD:
		*addr = BATT_EEPROM_TAG_STRD_OFFSET;
		*count = BATT_EEPROM_TAG_STRD_LEN;
		break;
	case GBMS_TAG_RSOC:
		*addr = BATT_EEPROM_TAG_RSOC_OFFSET;
		*count = BATT_EEPROM_TAG_RSOC_LEN;
		break;
	case GBMS_TAG_ACIM:
		*addr = BATT_EEPROM_TAG_ACIM_OFFSET;
		*count = BATT_EEPROM_TAG_ACIM_LEN;
		break;
	case GBMS_TAG_GCFE:
		*addr = BATT_EEPROM_TAG_GCFE_OFFSET;
		*count = BATT_EEPROM_TAG_GCFE_LEN;
		break;
	case GBMS_TAG_RAVG:
		*addr = BATT_EEPROM_TAG_RAVG_OFFSET;
		*count = BATT_EEPROM_TAG_RAVG_LEN;
		break;
	case GBMS_TAG_RFCN:
		*addr = BATT_EEPROM_TAG_RFCN_OFFSET;
		*count = BATT_EEPROM_TAG_RFCN_LEN;
		break;
	case GBMS_TAG_THAS:
		*addr = BATT_EEPROM_TAG_THAS_OFFSET;
		*count = BATT_EEPROM_TAG_THAS_LEN;
		break;
	case GBMS_TAG_AYMD:
		*addr = BATT_EEPROM_TAG_AYMD_OFFSET;
		*count = BATT_EEPROM_TAG_AYMD_LEN;
		break;
	case GBMS_TAG_MYMD:
		*addr = BATT_EEPROM_TAG_MYMD_OFFSET;
		*count = BATT_EEPROM_TAG_MYMD_LEN;
		break;
	default:
		ret = -ENOENT;
		break;
	}

	return ret;
}

static int gbee_storage_iter(int index, gbms_tag_t *tag, void *ptr)
{
	static const gbms_tag_t keys[] = { GBMS_TAG_BGPN, GBMS_TAG_MINF,
					   GBMS_TAG_DINF, GBMS_TAG_HIST,
					   GBMS_TAG_BRID, GBMS_TAG_SNUM,
					   GBMS_TAG_GMSR, GBMS_TAG_BCNT,
					   GBMS_TAG_CNHS, GBMS_TAG_SELC,
					   GBMS_TAG_CELC, GBMS_TAG_LOTR,
					   GBMS_TAG_STRD, GBMS_TAG_RSOC,
					   GBMS_TAG_ACIM, GBMS_TAG_GCFE,
					   GBMS_TAG_RAVG, GBMS_TAG_RFCN,
					   GBMS_TAG_THAS, GBMS_TAG_AYMD,
					   GBMS_TAG_MYMD};
	const int count = ARRAY_SIZE(keys);

	if (index < 0 || index >= count)
		return -ENOENT;

	*tag = keys[index];
	return 0;
}

static int gbee_storage_read(gbms_tag_t tag, void *buff, size_t size, void *ptr)
{
	struct nvmem_device *nvmem = GBEE_GET_NVRAM(ptr);
	size_t offset = 0, len = 0;
	int ret;

	if (tag == GBMS_TAG_BRID) {
		u8 temp;

		if (size != sizeof(u32))
			return -ENOMEM;

		ret = nvmem_device_read(nvmem, BATT_EEPROM_TAG_BRID_OFFSET,
					1, &temp);
		if (ret < 0)
			return ret;

		((u32*)buff)[0] = temp;
		return len;
	}

	ret = GBEE_STORAGE_INFO(tag, &offset, &len, ptr);
	if (ret < 0)
		return ret;
	if (!len)
		return -ENOENT;
	if (len > size)
		return -ENOMEM;

	ret = nvmem_device_read(nvmem, offset, len, buff);
	if (ret == 0)
		ret = len;

	return ret;
}

static bool gbee_storage_is_writable(gbms_tag_t tag)
{
	switch (tag) {
	case GBMS_TAG_DINF:
	case GBMS_TAG_GMSR:
	case GBMS_TAG_BCNT:
	case GBMS_TAG_CNHS:
	case GBMS_TAG_SELC:
	case GBMS_TAG_CELC:
	case GBMS_TAG_BPST:
	case GBMS_TAG_STRD:
	case GBMS_TAG_RSOC:
	case GBMS_TAG_ACIM:
	case GBMS_TAG_GCFE:
	case GBMS_TAG_RAVG:
	case GBMS_TAG_RFCN:
	case GBMS_TAG_THAS:
	case GBMS_TAG_AYMD:
		return true;
	default:
		return false;
	}

}

static int gbee_storage_write(gbms_tag_t tag, const void *buff, size_t size,
			      void *ptr)
{
	struct nvmem_device *nvmem = ptr;
	size_t offset = 0, len = 0;
	int ret, write_size = 0;

	if (!gbee_storage_is_writable(tag))
		return -ENOENT;

	ret = GBEE_STORAGE_INFO(tag, &offset, &len, ptr);
	if (ret < 0)
		return ret;
	if (size > len)
		return -ENOMEM;

	for (write_size = 0; write_size < size; write_size++) {
		ret = nvmem_device_write(nvmem, write_size + offset, 1,
					 &((char *)buff)[write_size]);
		if (ret < 0)
			return ret;
		msleep(BATT_WAIT_INTERNAL_WRITE_MS);
	}

	ret = size;

	return ret;
}

static int gbee_storage_read_data(gbms_tag_t tag, void *data, size_t count,
				  int idx, void *ptr)
{
	struct nvmem_device *nvmem = GBEE_GET_NVRAM(ptr);
	size_t offset = 0, len = 0;
	int ret;

	switch (tag) {
	case GBMS_TAG_HIST:
		ret = GBEE_STORAGE_INFO(tag, &offset, &len, ptr);
		break;
	default:
		ret = -ENOENT;
		break;
	}

	if (ret < 0)
		return ret;

	if (!data || !count) {
		if (idx == GBMS_STORAGE_INDEX_INVALID)
			return 0;
		else
			return BATT_MAX_HIST_CNT;
	}

	if (idx < 0)
		return -EINVAL;

	/* index == 0 is ok here */
	if (idx >= BATT_MAX_HIST_CNT)
		return -ENODATA;

	if (len > count)
		return -EINVAL;

	offset += len * idx;

	ret = nvmem_device_read(nvmem, offset, len, data);
	if (ret == 0)
		ret = len;

	return ret;
}

static int gbee_storage_write_data(gbms_tag_t tag, const void *data,
				   size_t count, int idx, void *ptr)
{
	struct nvmem_device *nvmem = GBEE_GET_NVRAM(ptr);
	size_t offset = 0, len = 0;
	int ret, write_size = 0;

	switch (tag) {
	case GBMS_TAG_HIST:
		ret = GBEE_STORAGE_INFO(tag, &offset, &len, ptr);
		break;
	default:
		ret = -ENOENT;
		break;
	}

	if (ret < 0)
		return ret;

	if (idx < 0 || !data || !count)
		return -EINVAL;

	/* index == 0 is ok here */
	if (idx >= BATT_MAX_HIST_CNT)
		return -ENODATA;

	if (count > len)
		return -EINVAL;

	offset += len * idx;

	for (write_size = 0; write_size < len; write_size++) {
		ret = nvmem_device_write(nvmem, write_size + offset, 1,
					 &((char *)data)[write_size]);
		if (ret < 0)
			return ret;
		msleep(BATT_WAIT_INTERNAL_WRITE_MS);
	}

	ret = len;

	return ret;
}

static struct gbms_storage_desc gbee_storage_dsc = {
	.info = gbee_storage_info,
	.iter = gbee_storage_iter,
	.read = gbee_storage_read,
	.write = gbee_storage_write,
	.read_data = gbee_storage_read_data,
	.write_data = gbee_storage_write_data,
};

struct gbms_storage_desc gbee_storage01_dsc = {
	.info = gbee_storage01_info,
	.iter = gbee_storage01_iter,
	.read = gbee_storage_read,
	.write = gbee_storage_write,
	.read_data = gbee_storage_read_data,
	.write_data = gbee_storage_write_data,
};

/* TODO: factor history mechanics out of google battery? */
static int gbms_hist_move(struct nvmem_device *nvmem, int from, int to, int len)
{
	u8 *buff, *p;
	int index, ret;

	buff = kzalloc(len, GFP_KERNEL);
	if (!buff)
		return -ENOMEM;

	/* move only the entries that are used */
	p = buff;
	for (index = 0; index < BATT_MAX_HIST_CNT; index++) {
		ret = nvmem_device_read(nvmem, from, BATT_ONE_HIST_LEN, p);
		if (ret < 0) {
			pr_err("%s: cannot read history data (%d)\n", __func__, ret);
			goto exit;
		}

		/* verify 1st byte for tempco */
		if (*p == 0xff)
			break;
		/* move to next history entry */
		from += BATT_ONE_HIST_LEN;
		p += BATT_ONE_HIST_LEN;
	}

	/* when the history data is empty */
	if (index == 0)
		goto exit;

	ret = nvmem_device_write(nvmem, to, (BATT_ONE_HIST_LEN * index), buff);
	if (ret < 0)
		pr_err("%s: cannot write history data (%d)\n", __func__, ret);

exit:
	kfree(buff);
	return ret;
}

/* LOTR is in a fixed position, move  */
static int gbms_lotr_update(struct nvmem_device *nvmem, int lotr_to)
{
	int ret, lotr_from = 0;
	static u8 init_data[5]= { 0 };

	ret = nvmem_device_read(nvmem, BATT_EEPROM_TAG_LOTR_OFFSET,
				BATT_EEPROM_TAG_LOTR_LEN, &lotr_from);
	if (ret < 0 || lotr_from == lotr_to)
		return ret;

	if (lotr_to != GBMS_LOTR_V1 || lotr_from != GBMS_LOTR_DEFAULT)
		return 0;

	ret = gbms_hist_move(nvmem, 0x5E, 0x64, BATT_TOTAL_HIST_LEN);
	if (ret < 0) {
		pr_err("%s: cannot move history\n", __func__);
		return ret;
		/* TODO: flag this in BPST? */
	}

	ret = nvmem_device_write(nvmem, 0x5E, sizeof(init_data), init_data);
	if (ret != sizeof(init_data)) {
		pr_err("%s: cannot init new fields\n", __func__);
		return ret < 0 ? ret : -EINVAL;
	}

	/* TODO: how do we handle backporting? */

	/* now write lotr to the right place */
	ret = nvmem_device_write(nvmem, BATT_EEPROM_TAG_LOTR_OFFSET,
				BATT_EEPROM_TAG_LOTR_LEN, &lotr_to);
	if (ret == BATT_EEPROM_TAG_LOTR_LEN)
		pr_info("%s: lotr migrated %d->%d\n", __func__, lotr_from, lotr_to);

	return ret;
}

static struct gbms_storage_desc *gbms_lotr_2_dsc(int lotr_ver)
{
	switch (lotr_ver) {
	case GBMS_LOTR_V1:
		return &gbee_storage01_dsc;
	default:
		return &gbee_storage_dsc;
	}
}

/*
 * Caller will use something like of_nvmem_device_get() to retrieve the
 * nvmem_device instance.
 * TODO: this only supports a singleton but the model can be extended to
 * multiple eeproms passing a structure to gbms_storage_register() and
 * modifying the implementation of GBEE_GET_NVRAM and GBEE_STORAGE_INFO
 * TODO: map nvram cells to tags
 */
int gbee_register_device(const char *name, int lotr, struct nvmem_device *nvram)
{
	int ret;

	gbee_desc = gbms_lotr_2_dsc(lotr);
	if (!gbee_desc)
		return -EINVAL;

	/* convert the layout (if needed) */
	ret = gbms_lotr_update(nvram, lotr);
	if (ret < 0) {
		pr_err("gbee %s update lotr failed, %d\n", name, ret);
		goto error_exit;
	}

	/* watch out for races on gbee_desc */
	ret = gbms_storage_register(gbee_desc, name, nvram);
	if (ret == 0)
		return 0;

error_exit:
	gbee_desc = NULL;
	return ret;
}
EXPORT_SYMBOL_GPL(gbee_register_device);

void gbee_destroy_device(void)
{

}
EXPORT_SYMBOL_GPL(gbee_destroy_device);

MODULE_AUTHOR("AleX Pelosi <apelosi@google.com>");
MODULE_DESCRIPTION("Google EEPROM");
MODULE_LICENSE("GPL");
