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

#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

DECLARE_GLOBAL_DATA_PTR;

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

struct sandbox_i2c_flash {
	uint8_t *data;
};

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

static int sandbox_i2c_eeprom_xfer(struct udevice *emul, struct i2c_msg *msg,
				  int nmsgs)
{
	struct sandbox_i2c_flash *priv = dev_get_priv(emul);
	uint offset = 0;

	debug("\n%s\n", __func__);
	debug_buffer(0, priv->data, 1, 16, 0);
	for (; nmsgs > 0; nmsgs--, msg++) {
		struct sandbox_i2c_flash_plat_data *plat =
				dev_get_platdata(emul);
		int len;
		u8 *ptr;

		if (!plat->size)
			return -ENODEV;
		if (msg->addr + msg->len > plat->size) {
			debug("%s: Address %x, len %x is outside range 0..%x\n",
			      __func__, msg->addr, msg->len, plat->size);
			return -EINVAL;
		}
		len = msg->len;
		debug("   %s: msg->len=%d",
		      msg->flags & I2C_M_RD ? "read" : "write",
		      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);
			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);

			/* For testing, map offsets into our limited buffer */
			for (i = 24; i > 0; i -= 8) {
				if (offset > (1 << i)) {
					offset = (offset >> i) |
						(offset & ((1 << i) - 1));
					offset += i;
				}
			}
			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;

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