/*
 * 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 <fdtdec.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 = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
				    "sandbox,size", 32);
	plat->filename = fdt_getprop(gd->fdt_blob, dev->of_offset,
				     "sandbox,filename", NULL);
	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,
};
