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

#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_plat(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_plat(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_plat(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_plat(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_of_to_plat(struct udevice *dev)
{
	struct sandbox_i2c_flash_plat_data *plat = dev_get_plat(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_plat(dev);
	struct sandbox_i2c_flash *priv = dev_get_priv(dev);
	/* For eth3 */
	const u8 mac[] = { 0x02, 0x00, 0x11, 0x22, 0x33, 0x45 };

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

	memcpy(&priv->data[24], mac, sizeof(mac));

	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,
	.of_to_plat = sandbox_i2c_eeprom_of_to_plat,
	.probe		= sandbox_i2c_eeprom_probe,
	.remove		= sandbox_i2c_eeprom_remove,
	.priv_auto	= sizeof(struct sandbox_i2c_flash),
	.plat_auto	= sizeof(struct sandbox_i2c_flash_plat_data),
	.ops		= &sandbox_i2c_emul_ops,
};
