// SPDX-License-Identifier: GPL-2.0+
/*
 * Simulate an I2C eeprom
 *
 * Copyright (c) 2014 Google, Inc
 */

#include <common.h>
#include <dm.h>
#include <errno.h>
#include <i2c.h>
#include <log.h>
#include <malloc.h>
#include <asm/test.h>

#ifdef DEBUG
#define debug_buffer print_buffer
#else
#define debug_buffer(x, ...)
#endif

struct sandbox_i2c_flash_plat_data {
	enum sandbox_i2c_eeprom_test_mode test_mode;
	const char *filename;
	int offset_len;		/* Length of an offset in bytes */
	int size;		/* Size of data buffer */
	uint chip_addr_offset_mask; /* mask of addr bits used for offset */
};

struct sandbox_i2c_flash {
	uint8_t *data;
	uint prev_addr;		/* slave address of previous access */
	uint prev_offset;	/* offset of previous access */
};

void sandbox_i2c_eeprom_set_test_mode(struct udevice *dev,
				      enum sandbox_i2c_eeprom_test_mode mode)
{
	struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(dev);

	plat->test_mode = mode;
}

void sandbox_i2c_eeprom_set_offset_len(struct udevice *dev, int offset_len)
{
	struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(dev);

	plat->offset_len = offset_len;
}

void sandbox_i2c_eeprom_set_chip_addr_offset_mask(struct udevice *dev,
						  uint mask)
{
	struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(dev);

	plat->chip_addr_offset_mask = mask;
}

uint sanbox_i2c_eeprom_get_prev_addr(struct udevice *dev)
{
	struct sandbox_i2c_flash *priv = dev_get_priv(dev);

	return priv->prev_addr;
}

uint sanbox_i2c_eeprom_get_prev_offset(struct udevice *dev)
{
	struct sandbox_i2c_flash *priv = dev_get_priv(dev);

	return priv->prev_offset;
}

static int sandbox_i2c_eeprom_xfer(struct udevice *emul, struct i2c_msg *msg,
				  int nmsgs)
{
	struct sandbox_i2c_flash *priv = dev_get_priv(emul);
	struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(emul);
	uint offset = msg->addr & plat->chip_addr_offset_mask;

	debug("\n%s\n", __func__);
	debug_buffer(0, priv->data, 1, 16, 0);

	/* store addr for testing visibity */
	priv->prev_addr = msg->addr;

	for (; nmsgs > 0; nmsgs--, msg++) {
		int len;
		u8 *ptr;

		if (!plat->size)
			return -ENODEV;
		len = msg->len;
		debug("   %s: msg->addr=%x msg->len=%d",
		      msg->flags & I2C_M_RD ? "read" : "write",
		      msg->addr, msg->len);
		if (msg->flags & I2C_M_RD) {
			if (plat->test_mode == SIE_TEST_MODE_SINGLE_BYTE)
				len = 1;
			debug(", offset %x, len %x: ", offset, len);
			if (offset + len > plat->size) {
				int overflow = offset + len - plat->size;
				int initial = len - overflow;

				memcpy(msg->buf, priv->data + offset, initial);
				memcpy(msg->buf + initial, priv->data,
				       overflow);
			} else {
				memcpy(msg->buf, priv->data + offset, len);
			}
			memset(msg->buf + len, '\xff', msg->len - len);
			debug_buffer(0, msg->buf, 1, msg->len, 0);
		} else if (len >= plat->offset_len) {
			int i;

			ptr = msg->buf;
			for (i = 0; i < plat->offset_len; i++, len--)
				offset = (offset << 8) | *ptr++;
			debug(", set offset %x: ", offset);
			debug_buffer(0, msg->buf, 1, msg->len, 0);
			if (plat->test_mode == SIE_TEST_MODE_SINGLE_BYTE)
				len = min(len, 1);

			/* store offset for testing visibility */
			priv->prev_offset = offset;

			/* For testing, map offsets into our limited buffer.
			 * offset wraps every 256 bytes
			 */
			offset &= 0xff;
			debug("mapped offset to %x\n", offset);

			if (offset + len > plat->size) {
				int overflow = offset + len - plat->size;
				int initial = len - overflow;

				memcpy(priv->data + offset, ptr, initial);
				memcpy(priv->data, ptr + initial, overflow);
			} else {
				memcpy(priv->data + offset, ptr, len);
			}
		}
	}
	debug_buffer(0, priv->data, 1, 16, 0);

	return 0;
}

struct dm_i2c_ops sandbox_i2c_emul_ops = {
	.xfer = sandbox_i2c_eeprom_xfer,
};

static int sandbox_i2c_eeprom_ofdata_to_platdata(struct udevice *dev)
{
	struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(dev);

	plat->size = dev_read_u32_default(dev, "sandbox,size", 32);
	plat->filename = dev_read_string(dev, "sandbox,filename");
	if (!plat->filename) {
		debug("%s: No filename for device '%s'\n", __func__,
		      dev->name);
		return -EINVAL;
	}
	plat->test_mode = SIE_TEST_MODE_NONE;
	plat->offset_len = 1;
	plat->chip_addr_offset_mask = 0;

	return 0;
}

static int sandbox_i2c_eeprom_probe(struct udevice *dev)
{
	struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(dev);
	struct sandbox_i2c_flash *priv = dev_get_priv(dev);

	priv->data = calloc(1, plat->size);
	if (!priv->data)
		return -ENOMEM;

	return 0;
}

static int sandbox_i2c_eeprom_remove(struct udevice *dev)
{
	struct sandbox_i2c_flash *priv = dev_get_priv(dev);

	free(priv->data);

	return 0;
}

static const struct udevice_id sandbox_i2c_ids[] = {
	{ .compatible = "sandbox,i2c-eeprom" },
	{ }
};

U_BOOT_DRIVER(sandbox_i2c_emul) = {
	.name		= "sandbox_i2c_eeprom_emul",
	.id		= UCLASS_I2C_EMUL,
	.of_match	= sandbox_i2c_ids,
	.ofdata_to_platdata = sandbox_i2c_eeprom_ofdata_to_platdata,
	.probe		= sandbox_i2c_eeprom_probe,
	.remove		= sandbox_i2c_eeprom_remove,
	.priv_auto_alloc_size = sizeof(struct sandbox_i2c_flash),
	.platdata_auto_alloc_size = sizeof(struct sandbox_i2c_flash_plat_data),
	.ops		= &sandbox_i2c_emul_ops,
};
