/*
 * 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 <drivers/eeprom.h>
#include <drivers/flash.h>
#include <zephyr.h>
#define LOG_LEVEL CONFIG_EEPROM_LOG_LEVEL
#include <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 PART_DEV_NAME(part) \
	DT_PROP(PART_DEV_ID(part), label)

#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)
