// 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 <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,
};
