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

#define DEV_CONFIG(dev) ((dev)->config)
#define DEV_DATA(dev) ((dev)->data)

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(dev);

	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(dev);
	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(dev);
	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(dev);
	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(dev);
	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(dev);

	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(dev);

	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(dev);
	const struct eeprom_emu_data *dev_data = DEV_DATA(dev);
	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(dev);
	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(dev);
	struct eeprom_emu_data *dev_data = DEV_DATA(dev);
	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(dev);
	struct eeprom_emu_data *dev_data = DEV_DATA(dev);
	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(dev);
	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(dev);

	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(dev);
	struct eeprom_emu_data *dev_data = DEV_DATA(dev);
	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(dev);
	struct eeprom_emu_data *dev_data = DEV_DATA(dev);
	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(dev);

	return dev_config->size;
}

static int eeprom_emu_init(const struct device *dev)
{
	const struct eeprom_emu_config *dev_config = DEV_CONFIG(dev);
	struct eeprom_emu_data *dev_data = DEV_DATA(dev);
	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_PHANDLE_BY_IDX(DT_DRV_INST(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_EMULATOR_INIT_PRIORITY, &eeprom_emu_api); \

DT_INST_FOREACH_STATUS_OKAY(EEPROM_EMU_INIT)
