/*
 * Copyright (c) 2020 Laczen
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/*
 * This driver emulates an EEPROM device in flash.
 *
 * The emulation represents the EEPROM in flash as a region that is a direct
 * map of the EEPROM data (EEPROM data) followed by a region where changes to
 * the EEPROM data (EEPROM changes) are stored. The combination of EEPROM data
 * and EEPROM changes form a EEPROM page (see drawing below). Changes to EEPROM
 * data are written as address-data combinations. The size of such a combination
 * is determined by the flash write block size and the size of the EEPROM
 * (required address space), with a minimum of 4 byte.
 *
 * When there is no more space to store changes a new EEPROM page is taken into
 * use. This copies the existing data to the EEPROM data area of the new page.
 * During this copying the write that is performed is applied at the same time.
 * The old page is then invalidated.
 *
 * The EEPROM page needs to be a multiple of a flash page size. Multiple EEPROM
 * pages are also supported and increases the number of writes that can be
 * performed.
 *
 * The representation of the EEPROM on flash is shown in the next graph.
 *
 *  |-----------------------------------------------------------------------|
 *  ||----------------------| |----------------------| |-------------------||
 *  || EEPROM data          | |                      | |-Flash page--------||
 *  ||                      | |                      |                      |
 *  || size = EEPROM size   | |                      |                      |
 *  ||----------------------| |----------------------|    ...               |
 *  || EEPROM changes:      | |                      |                      |
 *  || (address, new data)  | |                      |                      |
 *  ||                      | |                      |                      |
 *  ||                    XX| |                    XX|                      |
 *  ||--EEPROM page 0-------| |--EEPROM page 1-------|                      |
 *  |------------------------------------------------------------Partition--|
 *  XX: page validity marker: all 0x00: page invalid
 *
 * Internally the address of an EEPROM byte is represented by a uint32_t (this
 * should be sufficient in all cases). In case the EEPROM size is smaller than
 * 64kB only a uint16_t is used to store changes. In this case the change stored
 * for a 4 byte flash write block size are a combination of 2 byte address and
 * 2 byte data.
 *
 * The EEPROM size, pagesize and the flash partition used for the EEPROM are
 * defined in the dts. The flash partition should allow at least two EEPROM
 * pages.
 *
 */

#define DT_DRV_COMPAT zephyr_emu_eeprom

#define EEPROM_EMU_VERSION 0
#define EEPROM_EMU_MAGIC 0x45454d55 /* EEMU in hex */

#include <zephyr/drivers/eeprom.h>
#include <zephyr/drivers/flash.h>
#include <zephyr/zephyr.h>
#define LOG_LEVEL CONFIG_EEPROM_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(eeprom_emulator);

struct eeprom_emu_config {
	/* EEPROM size */
	size_t size;
	/* EEPROM is read-only */
	bool readonly;
	/* Page size used to emulate the EEPROM, contains one area of EEPROM
	 * size and a area to store changes.
	 */
	size_t page_size;
	/* Offset of the flash partition used to emulate the EEPROM */
	off_t flash_offset;
	/* Size of the flash partition to emulate the EEPROM */
	size_t flash_size;
	/* Delay the erase of EEPROM pages until the complete partition is used.
	 */
	bool partitionerase;
	/* Size of a change block */
	uint8_t flash_cbs;
	uint8_t *rambuf;
	/* Device of the flash partition used to emulate the EEPROM */
	const struct device *flash_dev;
};

struct eeprom_emu_data {
	/* Offset in current (EEPROM) page where next change is written */
	off_t write_offset;
	/* Offset of the current (EEPROM) page */
	off_t page_offset;
	struct k_mutex lock;
};

/* read/write context */
struct eeprom_emu_ctx {
	const void *data; /* pointer to data */
	const size_t len; /* data length */
	const off_t address; /* eeprom address */
	size_t rlen; /* data remaining (unprocessed) length */
};

/*
 * basic flash read, only used with offset aligned to flash write block size
 */
static inline int eeprom_emu_flash_read(const struct device *dev, off_t offset,
					uint8_t *blk, size_t len)
{
	const struct eeprom_emu_config *dev_config = dev->config;

	return flash_read(dev_config->flash_dev, dev_config->flash_offset +
			  offset, blk, len);
}

/*
 * basic flash write, only used with offset aligned to flash write block size
 */
static inline int eeprom_emu_flash_write(const struct device *dev, off_t offset,
				   const uint8_t *blk, size_t len)
{
	const struct eeprom_emu_config *dev_config = dev->config;
	int rc;

	rc = flash_write(dev_config->flash_dev, dev_config->flash_offset +
			 offset, blk, len);
	return rc;
}

/*
 * basic flash erase, only used with offset aligned to flash page and len a
 * multiple of the flash page size
 */
static inline int eeprom_emu_flash_erase(const struct device *dev, off_t offset,
				   size_t len)
{
	const struct eeprom_emu_config *dev_config = dev->config;
	int rc;

	rc = flash_erase(dev_config->flash_dev, dev_config->flash_offset +
			 offset, len);
	return rc;
}

/*
 * eeprom_emu_page_invalidate: invalidate a page by writing all zeros at the end
 */
static int eeprom_emu_page_invalidate(const struct device *dev, off_t offset)
{
	const struct eeprom_emu_config *dev_config = dev->config;
	uint8_t buf[dev_config->flash_cbs];

	LOG_DBG("Invalidating page at [0x%tx]", (ptrdiff_t)offset);

	memset(buf, 0x00, sizeof(buf));

	offset += (dev_config->page_size - sizeof(buf));
	return eeprom_emu_flash_write(dev, offset, buf, sizeof(buf));
}

/*
 * eeprom_emu_get_address: read the address from a change block
 */
static uint32_t eeprom_emu_get_address(const struct device *dev,
				       const uint8_t *blk)
{
	const struct eeprom_emu_config *dev_config = dev->config;
	uint32_t address = 0U;

	blk += dev_config->flash_cbs / 2;
	for (int i = 0; i < sizeof(address); i++) {
		if (2 * i == dev_config->flash_cbs) {
			break;
		}

		address += ((uint32_t)(*blk) << (8 * i));
		blk++;
	}

	return address;
}

/*
 * eeprom_emu_set_change: create change blocks from data in blk and address
 */
static void eeprom_emu_set_change(const struct device *dev,
				  const uint32_t address, const uint8_t *data,
				  uint8_t *blk)
{
	const struct eeprom_emu_config *dev_config = dev->config;

	for (int i = 0; i < (dev_config->flash_cbs / 2); i++) {
		(*blk++) = (*data++);
	}

	for (int i = 0; i < (dev_config->flash_cbs / 2); i++) {
		if (i < sizeof(address)) {
			(*blk++) = (uint8_t)(((address >> (8 * i)) & 0xff));
		} else {
			(*blk++) = 0xff;
		}

	}

}

/*
 * eeprom_emu_is_word_used: check if word is not empty
 */
static int eeprom_emu_is_word_used(const struct device *dev, const uint8_t *blk)
{
	const struct eeprom_emu_config *dev_config = dev->config;

	for (int i = 0; i < dev_config->flash_cbs; i++) {
		if ((*blk++) != 0xff) {
			return 1;
		}

	}

	return 0;
}

/*
 * eeprom_emu_word_read: read basic word (cbs byte of data) item from
 * address directly from flash.
 */
static int eeprom_emu_word_read(const struct device *dev, off_t address,
				uint8_t *data)
{
	const struct eeprom_emu_config *dev_config = dev->config;
	const struct eeprom_emu_data *dev_data = dev->data;
	uint8_t buf[dev_config->flash_cbs];
	off_t direct_address;
	int rc;

	direct_address = dev_data->page_offset + address;

	/* Direct flash read */
	rc = eeprom_emu_flash_read(dev, direct_address, data, sizeof(buf));
	if (rc) {
		return rc;
	}

	/* Process changes written to flash */
	off_t offset, ch_address;
	bool mc1 = false, mc2 = false;

	offset = dev_data->write_offset;
	while (((!mc1) || (!mc2)) && (offset > dev_config->size)) {
		offset -= sizeof(buf);
		/* read the change */
		rc = eeprom_emu_flash_read(dev, dev_data->page_offset + offset,
					   buf, sizeof(buf));
		if (rc) {
			return rc;
		}

		/* get the address from a change block */
		ch_address = eeprom_emu_get_address(dev, buf);
		if ((!mc1) && (ch_address == address)) {
			memcpy(data, buf, sizeof(buf)/2);
			mc1 = true;
		}

		if ((!mc2) && (ch_address == (address + sizeof(buf)/2))) {
			memcpy(data + sizeof(buf)/2, buf, sizeof(buf)/2);
			mc2 = true;
		}

	}

	return rc;
}

/* Update data specified in ctx from flash */
static int eeprom_emu_flash_get(const struct device *dev,
				struct eeprom_emu_ctx *ctx)
{
	const struct eeprom_emu_config *dev_config = dev->config;
	off_t address = ctx->address + ctx->len - ctx->rlen;
	uint8_t *data8 = (uint8_t *)(ctx->data);
	uint8_t buf[dev_config->flash_cbs];
	const off_t addr_jmp = address & (sizeof(buf) - 1);
	size_t len;
	int rc;

	data8 += (ctx->len - ctx->rlen);
	len = MIN((sizeof(buf) - addr_jmp), ctx->rlen);
	rc = eeprom_emu_word_read(dev, address - addr_jmp, buf);
	if (rc) {
		return rc;
	}

	memcpy(data8, buf + addr_jmp, len);
	ctx->rlen -= len;

	return rc;
}

/*
 * eeprom_emu_compactor: start a new EEPROM page and copy existing data to the
 * new page. During copy update the data with present write data. Invalidate
 * the old page.
 */
static int eeprom_emu_compactor(const struct device *dev,
				struct eeprom_emu_ctx *ctx)
{
	const struct eeprom_emu_config *dev_config = dev->config;
	struct eeprom_emu_data *dev_data = dev->data;
	off_t next_page_offset;
	int rc = 0;

	LOG_DBG("Compactor called for page at [0x%tx]",
		(ptrdiff_t)dev_data->page_offset);

	next_page_offset = dev_data->page_offset + dev_config->page_size;
	if (next_page_offset >= dev_config->flash_size) {
		next_page_offset = 0;
	}

	if (!dev_config->partitionerase) {
		/* erase the new page */
		rc = eeprom_emu_flash_erase(dev, next_page_offset,
					    dev_config->page_size);
	} else if (next_page_offset == 0) {
		/* erase the entire partition */
		rc = eeprom_emu_flash_erase(dev, next_page_offset,
					    dev_config->flash_size);
	} else {
		rc = 0;
	}

	if (rc) {
		return rc;
	}

	if (dev_config->rambuf && (ctx != NULL)) {
		rc = eeprom_emu_flash_write(dev, next_page_offset,
					    dev_config->rambuf,
					    dev_config->size);
		if (rc) {
			return rc;
		}

		ctx->rlen = 0;
	} else {
		off_t rd_offset = 0;
		uint8_t buf[dev_config->flash_cbs];

		/* reset the context if available */
		if (ctx != NULL) {
			ctx->rlen = ctx->len;
		}

		/* copy existing data */
		while (rd_offset < dev_config->size) {

			rc = eeprom_emu_word_read(dev, rd_offset, buf);
			if (rc) {
				return rc;
			}

			if ((ctx != NULL) && (ctx->len) &&
			    (rd_offset > (ctx->address - sizeof(buf))))  {
				/* overwrite buf data with context data */
				uint8_t *data8 = (uint8_t *)(ctx->data);
				off_t address, addr_jmp;
				size_t len;

				address = ctx->address + ctx->len - ctx->rlen;
				addr_jmp = address & (sizeof(buf) - 1);
				len = MIN((sizeof(buf) - addr_jmp), ctx->rlen);
				data8 += (ctx->len - ctx->rlen);
				memcpy(buf + addr_jmp, data8, len);
				ctx->rlen -= len;
			}

			if (eeprom_emu_is_word_used(dev, buf)) {
				rc = eeprom_emu_flash_write(dev,
							    next_page_offset +
							    rd_offset, buf,
							    sizeof(buf));
				if (rc) {
					return rc;
				}

			}

			rd_offset += sizeof(buf);
		}

	}

	if ((dev_config->partitionerase) && (next_page_offset == 0)) {
		/* no need to invalidate previous page as it has been deleted */
		rc = 0;
	} else {
		/* invalidate the old page */
		rc = eeprom_emu_page_invalidate(dev, dev_data->page_offset);
	}

	if (!rc) {
		dev_data->write_offset = dev_config->size;
		dev_data->page_offset = next_page_offset;
	}
	return rc;
}

/*
 * eeprom_emu_word_write: write basic word (cbs bytes of data) item to address,
 */
static int eeprom_emu_word_write(const struct device *dev, off_t address,
				 const uint8_t *data,
				 struct eeprom_emu_ctx *ctx)
{
	const struct eeprom_emu_config *dev_config = dev->config;
	struct eeprom_emu_data *dev_data = dev->data;
	uint8_t buf[dev_config->flash_cbs], tmp[dev_config->flash_cbs];
	off_t direct_address, wraddr;
	int rc;

	direct_address = dev_data->page_offset + address;

	rc = eeprom_emu_flash_read(dev, direct_address, buf, sizeof(buf));
	if (rc) {
		return rc;
	}

	if (!eeprom_emu_is_word_used(dev, buf)) {
		if (eeprom_emu_is_word_used(dev, data)) {
			rc = eeprom_emu_flash_write(dev, direct_address, data,
						    sizeof(buf));
		}

		return rc;
	}

	rc = eeprom_emu_word_read(dev, address, buf);
	if (rc) {
		return rc;
	}

	if (!memcmp(buf, data, sizeof(buf))) {
		/* data has not changed */
		return rc;
	}

	wraddr = address;
	/* store change */
	for (uint8_t i = 0; i < 2; i++) {
		if (memcmp(&buf[i*sizeof(buf)/2], data, sizeof(buf)/2)) {
			eeprom_emu_set_change(dev, wraddr, data, tmp);
			rc = eeprom_emu_flash_write(dev, dev_data->page_offset +
						    dev_data->write_offset, tmp,
						    sizeof(buf));
			if (rc) {
				return rc;
			}

			dev_data->write_offset += sizeof(buf);
			if ((dev_data->write_offset + sizeof(buf)) >=
			    dev_config->page_size) {
				rc = eeprom_emu_compactor(dev, ctx);
				return rc;

			}

		}

		data += sizeof(buf)/2;
		wraddr += sizeof(buf)/2;
	}

	return rc;
}

/* Update flash with data specified in ctx */
static int eeprom_emu_flash_set(const struct device *dev,
				struct eeprom_emu_ctx *ctx)
{
	const struct eeprom_emu_config *dev_config = dev->config;
	off_t address = ctx->address + ctx->len - ctx->rlen;
	uint8_t *data8 = (uint8_t *)(ctx->data);
	uint8_t buf[dev_config->flash_cbs];
	const off_t addr_jmp = address & (sizeof(buf) - 1);
	size_t len;
	int rc;

	data8 += (ctx->len - ctx->rlen);
	len = MIN((sizeof(buf) - addr_jmp), ctx->rlen);
	rc = eeprom_emu_word_read(dev, address - addr_jmp, buf);
	if (rc) {
		return rc;
	}

	memcpy(buf + addr_jmp, data8, len);
	rc = eeprom_emu_word_write(dev, address - addr_jmp, buf, ctx);
	if (rc) {
		return rc;
	}

	if (ctx->rlen) {
		ctx->rlen -= len;
	}

	return rc;
}

static int eeprom_emu_range_is_valid(const struct device *dev, off_t address,
				     size_t len)
{
	const struct eeprom_emu_config *dev_config = dev->config;

	if ((address + len) <= dev_config->size) {
		return 1;
	}

	return 0;
}

static int eeprom_emu_read(const struct device *dev, off_t address, void *data,
			   size_t len)
{
	const struct eeprom_emu_config *dev_config = dev->config;
	struct eeprom_emu_data *dev_data = dev->data;
	struct eeprom_emu_ctx ctx = {
		.data = data,
		.len = len,
		.address = address,
		.rlen = len,
	};
	int rc = 0;

	/* Nothing to do */
	if (!len) {
		return 0;
	}

	/* Error checking */
	if ((!data) || (!eeprom_emu_range_is_valid(dev, address, len))) {
		return -EINVAL;
	}

	if (!device_is_ready(dev_config->flash_dev)) {
		LOG_ERR("flash device is not ready");
		return -EIO;
	}

	/* Handle normal case */
	LOG_DBG("EEPROM read at [0x%tx] length[%d]", (ptrdiff_t)address, len);
	k_mutex_lock(&dev_data->lock, K_FOREVER);

	/* read from rambuffer if possible */
	if (dev_config->rambuf) {
		memcpy(data, dev_config->rambuf + address, len);
	} else {
		/* read from flash if no rambuffer */
		while (ctx.rlen) {
			rc = eeprom_emu_flash_get(dev, &ctx);
			if (rc) {
				break;
			}

		}
	}

	k_mutex_unlock(&dev_data->lock);

	return rc;
}

static int eeprom_emu_write(const struct device *dev, off_t address,
			    const void *data, size_t len)
{
	const struct eeprom_emu_config *dev_config = dev->config;
	struct eeprom_emu_data *dev_data = dev->data;
	struct eeprom_emu_ctx ctx = {
		.data = data,
		.len = len,
		.address = address,
		.rlen = len,
	};
	int rc = 0;

	/* Nothing to do */
	if (!len) {
		return 0;
	}

	/* Error checking */
	if ((!data) || (!eeprom_emu_range_is_valid(dev, address, len))) {
		return -EINVAL;
	}

	if (dev_config->readonly) {
		LOG_ERR("attempt to write to read-only device");
		return -EACCES;
	}

	if (!device_is_ready(dev_config->flash_dev)) {
		LOG_ERR("flash device is not ready");
		return -EIO;
	}

	/* Handle normal case */
	LOG_DBG("EEPROM write at [0x%tx] length[%d]", (ptrdiff_t)address, len);

	k_mutex_lock(&dev_data->lock, K_FOREVER);

	/* first update the rambuffer */
	if (dev_config->rambuf) {
		memcpy(dev_config->rambuf + address, data, len);
	}

	/* second update the flash */
	while (ctx.rlen) {
		rc = eeprom_emu_flash_set(dev, &ctx);
		if (rc) {
			break;
		}

	}

	k_mutex_unlock(&dev_data->lock);

	return rc;
}

static size_t eeprom_emu_size(const struct device *dev)
{
	const struct eeprom_emu_config *dev_config = dev->config;

	return dev_config->size;
}

static int eeprom_emu_init(const struct device *dev)
{
	const struct eeprom_emu_config *dev_config = dev->config;
	struct eeprom_emu_data *dev_data = dev->data;
	off_t offset;
	uint8_t buf[dev_config->flash_cbs];
	int rc;

	k_mutex_init(&dev_data->lock);
	if (!device_is_ready(dev_config->flash_dev)) {
		__ASSERT(0, "Could not get flash device binding");
		return -ENODEV;
	}

	/* Find the page offset */
	dev_data->page_offset = 0U;
	dev_data->write_offset = dev_config->page_size - sizeof(buf);
	while (dev_data->page_offset < dev_config->flash_size) {
		offset = dev_data->page_offset + dev_data->write_offset;
		rc = eeprom_emu_flash_read(dev, offset, buf, sizeof(buf));
		if (rc) {
			return rc;
		}

		if (!eeprom_emu_is_word_used(dev, buf)) {
			break;
		}

		dev_data->page_offset += dev_config->page_size;
	}

	if (dev_data->page_offset == dev_config->flash_size) {
		__ASSERT(0, "All pages are invalid, is this a EEPROM area?");
		return -EINVAL;
	}

	dev_data->write_offset = dev_config->size;

	/* Update the write offset */
	while ((dev_data->write_offset + sizeof(buf)) < dev_config->page_size) {
		offset = dev_data->page_offset + dev_data->write_offset;
		rc = eeprom_emu_flash_read(dev, offset, buf, sizeof(buf));
		if (rc) {
			return rc;
		}

		if (!eeprom_emu_is_word_used(dev, buf)) {
			break;
		}

		dev_data->write_offset += sizeof(buf);
	}

	/* dev_data->write_offset reaches last possible location, compaction
	 * might have been interrupted: call eeprom_emu_compactor again, but
	 * only in case we are using a write-enabled eeprom
	 */
	if ((!dev_config->readonly) &&
	    ((dev_data->write_offset + sizeof(buf)) >= dev_config->page_size)) {
		rc = eeprom_emu_compactor(dev, NULL);
		if (rc) {
			return rc;
		}

	}

	/* Fill the ram buffer if enabled */
	if (dev_config->rambuf) {
		offset = 0;
		while (offset < dev_config->size) {
			rc = eeprom_emu_word_read(dev, offset, buf);
			if (rc) {
				return rc;
			}

			memcpy(dev_config->rambuf + offset, buf, sizeof(buf));
			offset += sizeof(buf);
		}

	}

	return rc;
}

static const struct eeprom_driver_api eeprom_emu_api = {
	.read = eeprom_emu_read,
	.write = eeprom_emu_write,
	.size = eeprom_emu_size,
};

#define EEPROM_PARTITION(n) DT_INST_PHANDLE_BY_IDX(n, partition, 0)

#define PART_WBS(part) \
	DT_PROP(COND_CODE_1(DT_NODE_HAS_COMPAT(DT_GPARENT(part), soc_nv_flash),\
		(DT_GPARENT(part)), (DT_PARENT(part))), write_block_size)

#define PART_CBS(part, size) (PART_WBS(part) < 4) ? \
	((size > (2^16)) ? 8 : 4) : PART_WBS(part)

#define PART_DEV_ID(part) \
	COND_CODE_1(DT_NODE_HAS_COMPAT(DT_GPARENT(part), soc_nv_flash), \
		 (DT_PARENT(DT_GPARENT(part))), (DT_GPARENT(part)))

#define PART_DEV(part) \
	DEVICE_DT_GET(PART_DEV_ID(part))

#define RECALC_SIZE(size, cbs) \
	(size % cbs) ? ((size + cbs - 1) & ~(cbs - 1)) : size

#define ASSERT_SIZE_PAGESIZE_VALID(size, pagesize, readonly) \
	BUILD_ASSERT(readonly ? (size <= pagesize) : (4*size <= 3*pagesize), \
		     "EEPROM size to big for pagesize")

#define ASSERT_PAGESIZE_PARTSIZE_VALID(pagesize, partsize) \
	BUILD_ASSERT(partsize % pagesize == 0U, \
		     "Partition size not a multiple of pagesize")

#define ASSERT_PAGESIZE_SIZE(pagesize, partsize, onepage) \
	BUILD_ASSERT(onepage ? (partsize >= pagesize) : (partsize > pagesize),\
		     "Partition size to small")

#define EEPROM_EMU_READ_ONLY(n) \
	DT_INST_PROP(n, read_only) || \
	DT_PROP(EEPROM_PARTITION(n), read_only)

#define EEPROM_EMU_ONEPAGE(n) \
	EEPROM_EMU_READ_ONLY(n) || DT_INST_PROP(n, partition_erase)

#define EEPROM_EMU_ENABLE_RAMBUF(n) \
	COND_CODE_1(DT_INST_PROP(n, rambuf), (1), \
		(COND_CODE_1(DT_INST_PROP(n, partition_erase), (1), (0))))

#define EEPROM_EMU_RAMBUF(n) \
	COND_CODE_0(EEPROM_EMU_ENABLE_RAMBUF(n), (), \
		(static uint8_t eeprom_emu_##n##_rambuf[DT_INST_PROP(n, size)];))

#define EEPROM_EMU_RAMBUF_LINK(n) \
	COND_CODE_0(EEPROM_EMU_ENABLE_RAMBUF(n), (NULL), \
		(eeprom_emu_##n##_rambuf))

#define EEPROM_EMU_INIT(n) \
	ASSERT_SIZE_PAGESIZE_VALID(DT_INST_PROP(n, size), \
		DT_INST_PROP(n, pagesize), EEPROM_EMU_ONEPAGE(n)); \
	ASSERT_PAGESIZE_PARTSIZE_VALID(DT_INST_PROP(n, pagesize), \
		DT_REG_SIZE(EEPROM_PARTITION(n))); \
	ASSERT_PAGESIZE_SIZE(DT_INST_PROP(n, pagesize), \
		DT_REG_SIZE(EEPROM_PARTITION(n)), EEPROM_EMU_ONEPAGE(n)); \
	EEPROM_EMU_RAMBUF(n) \
	static const struct eeprom_emu_config eeprom_emu_##n##_config = { \
		.size = RECALC_SIZE( \
			DT_INST_PROP(n, size), \
			(PART_CBS(EEPROM_PARTITION(n), DT_INST_PROP(n, size))) \
			), \
		.readonly = EEPROM_EMU_READ_ONLY(n), \
		.page_size = DT_INST_PROP(n, pagesize), \
		.flash_offset = DT_REG_ADDR(EEPROM_PARTITION(n)), \
		.flash_size = DT_REG_SIZE(EEPROM_PARTITION(n)), \
		.partitionerase = DT_INST_PROP(n, partition_erase), \
		.flash_cbs = PART_CBS(EEPROM_PARTITION(n), \
				      DT_INST_PROP(n, size)), \
		.flash_dev = PART_DEV(EEPROM_PARTITION(n)),\
		.rambuf = EEPROM_EMU_RAMBUF_LINK(n), \
	}; \
	static struct eeprom_emu_data eeprom_emu_##n##_data; \
	DEVICE_DT_INST_DEFINE(n, &eeprom_emu_init, \
		NULL, &eeprom_emu_##n##_data, \
		&eeprom_emu_##n##_config, POST_KERNEL, \
		CONFIG_EEPROM_INIT_PRIORITY, &eeprom_emu_api); \

DT_INST_FOREACH_STATUS_OKAY(EEPROM_EMU_INIT)
