/*
 * Copyright (c) 2019 Vestas Wind Systems A/S
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief Driver for Atmel AT24 I2C and Atmel AT25 SPI EEPROMs.
 */

#include <zephyr/drivers/eeprom.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/kernel.h>

#define LOG_LEVEL CONFIG_EEPROM_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(eeprom_at2x);

/* AT25 instruction set */
#define EEPROM_AT25_WRSR  0x01U /* Write STATUS register        */
#define EEPROM_AT25_WRITE 0x02U /* Write data to memory array   */
#define EEPROM_AT25_READ  0x03U /* Read data from memory array  */
#define EEPROM_AT25_WRDI  0x04U /* Reset the write enable latch */
#define EEPROM_AT25_RDSR  0x05U /* Read STATUS register         */
#define EEPROM_AT25_WREN  0x06U /* Set the write enable latch   */

/* AT25 status register bits */
#define EEPROM_AT25_STATUS_WIP BIT(0) /* Write-In-Process   (RO) */
#define EEPROM_AT25_STATUS_WEL BIT(1) /* Write Enable Latch (RO) */
#define EEPROM_AT25_STATUS_BP0 BIT(2) /* Block Protection 0 (RW) */
#define EEPROM_AT25_STATUS_BP1 BIT(3) /* Block Protection 1 (RW) */

#define HAS_WP_OR(id) DT_NODE_HAS_PROP(id, wp_gpios) ||
#define ANY_INST_HAS_WP_GPIOS (DT_FOREACH_STATUS_OKAY(atmel_at24, HAS_WP_OR) \
			       DT_FOREACH_STATUS_OKAY(atmel_at25, HAS_WP_OR) 0)

struct eeprom_at2x_config {
	union {
#ifdef CONFIG_EEPROM_AT24
		struct i2c_dt_spec i2c;
#endif /* CONFIG_EEPROM_AT24 */
#ifdef CONFIG_EEPROM_AT25
		struct spi_dt_spec spi;
#endif /* CONFIG_EEPROM_AT25 */
	} bus;
#if ANY_INST_HAS_WP_GPIOS
	struct gpio_dt_spec wp_gpio;
#endif /* ANY_INST_HAS_WP_GPIOS */
	size_t size;
	size_t pagesize;
	uint8_t addr_width;
	bool readonly;
	uint16_t timeout;
	bool (*bus_is_ready)(const struct device *dev);
	eeprom_api_read read_fn;
	eeprom_api_write write_fn;
};

struct eeprom_at2x_data {
	struct k_mutex lock;
};

#if ANY_INST_HAS_WP_GPIOS
static inline int eeprom_at2x_write_protect(const struct device *dev)
{
	const struct eeprom_at2x_config *config = dev->config;

	if (!config->wp_gpio.port) {
		return 0;
	}

	return gpio_pin_set_dt(&config->wp_gpio, 1);
}

static inline int eeprom_at2x_write_enable(const struct device *dev)
{
	const struct eeprom_at2x_config *config = dev->config;

	if (!config->wp_gpio.port) {
		return 0;
	}

	return gpio_pin_set_dt(&config->wp_gpio, 0);
}
#endif /* ANY_INST_HAS_WP_GPIOS */

static int eeprom_at2x_read(const struct device *dev, off_t offset, void *buf,
			    size_t len)
{
	const struct eeprom_at2x_config *config = dev->config;
	struct eeprom_at2x_data *data = dev->data;
	uint8_t *pbuf = buf;
	int ret;

	if (!len) {
		return 0;
	}

	if ((offset + len) > config->size) {
		LOG_WRN("attempt to read past device boundary");
		return -EINVAL;
	}

	k_mutex_lock(&data->lock, K_FOREVER);
	while (len) {
		ret = config->read_fn(dev, offset, pbuf, len);
		if (ret < 0) {
			LOG_ERR("failed to read EEPROM (err %d)", ret);
			k_mutex_unlock(&data->lock);
			return ret;
		}

		pbuf += ret;
		offset += ret;
		len -= ret;
	}

	k_mutex_unlock(&data->lock);

	return 0;
}

static size_t eeprom_at2x_limit_write_count(const struct device *dev,
					    off_t offset,
					    size_t len)
{
	const struct eeprom_at2x_config *config = dev->config;
	size_t count = len;
	off_t page_boundary;

	/* We can at most write one page at a time */
	if (count > config->pagesize) {
		count = config->pagesize;
	}

	/* Writes can not cross a page boundary */
	page_boundary = ROUND_UP(offset + 1, config->pagesize);
	if (offset + count > page_boundary) {
		count = page_boundary - offset;
	}

	return count;
}

static int eeprom_at2x_write(const struct device *dev, off_t offset,
			     const void *buf,
			     size_t len)
{
	const struct eeprom_at2x_config *config = dev->config;
	struct eeprom_at2x_data *data = dev->data;
	const uint8_t *pbuf = buf;
	int ret;

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

	if (!len) {
		return 0;
	}

	if ((offset + len) > config->size) {
		LOG_WRN("attempt to write past device boundary");
		return -EINVAL;
	}

	k_mutex_lock(&data->lock, K_FOREVER);

#if ANY_INST_HAS_WP_GPIOS
	ret = eeprom_at2x_write_enable(dev);
	if (ret) {
		LOG_ERR("failed to write-enable EEPROM (err %d)", ret);
		k_mutex_unlock(&data->lock);
		return ret;
	}
#endif /* ANY_INST_HAS_WP_GPIOS */

	while (len) {
		ret = config->write_fn(dev, offset, pbuf, len);
		if (ret < 0) {
			LOG_ERR("failed to write to EEPROM (err %d)", ret);
#if ANY_INST_HAS_WP_GPIOS
			eeprom_at2x_write_protect(dev);
#endif /* ANY_INST_HAS_WP_GPIOS */
			k_mutex_unlock(&data->lock);
			return ret;
		}

		pbuf += ret;
		offset += ret;
		len -= ret;
	}

#if ANY_INST_HAS_WP_GPIOS
	ret = eeprom_at2x_write_protect(dev);
	if (ret) {
		LOG_ERR("failed to write-protect EEPROM (err %d)", ret);
	}
#else
	ret = 0;
#endif /* ANY_INST_HAS_WP_GPIOS */

	k_mutex_unlock(&data->lock);

	return ret;
}

static size_t eeprom_at2x_size(const struct device *dev)
{
	const struct eeprom_at2x_config *config = dev->config;

	return config->size;
}

#ifdef CONFIG_EEPROM_AT24

static bool eeprom_at24_bus_is_ready(const struct device *dev)
{
	const struct eeprom_at2x_config *config = dev->config;

	return device_is_ready(config->bus.i2c.bus);
}

/**
 * @brief translate an offset to a device address / offset pair
 *
 * It allows to address several devices as a continuous memory region
 * but also to address higher part of eeprom for chips
 * with more than 2^(addr_width) adressable word.
 */
static uint16_t eeprom_at24_translate_offset(const struct device *dev,
					     off_t *offset)
{
	const struct eeprom_at2x_config *config = dev->config;

	const uint16_t addr_incr = *offset >> config->addr_width;
	*offset &= BIT_MASK(config->addr_width);

	return config->bus.i2c.addr + addr_incr;
}

static size_t eeprom_at24_adjust_read_count(const struct device *dev,
					    off_t offset, size_t len)
{
	const struct eeprom_at2x_config *config = dev->config;
	const size_t remainder = BIT(config->addr_width) - offset;

	if (len > remainder) {
		len = remainder;
	}

	return len;
}

static int eeprom_at24_read(const struct device *dev, off_t offset, void *buf,
			    size_t len)
{
	const struct eeprom_at2x_config *config = dev->config;
	int64_t timeout;
	uint8_t addr[2];
	uint16_t bus_addr;
	int err;

	bus_addr = eeprom_at24_translate_offset(dev, &offset);

	if (config->addr_width == 16) {
		sys_put_be16(offset, addr);
	} else {
		addr[0] = offset & BIT_MASK(8);
	}

	len = eeprom_at24_adjust_read_count(dev, offset, len);

	/*
	 * A write cycle may be in progress so reads must be attempted
	 * until the current write cycle should be completed.
	 */
	timeout = k_uptime_get() + config->timeout;
	while (1) {
		int64_t now = k_uptime_get();
		err = i2c_write_read(config->bus.i2c.bus, bus_addr,
				     addr, config->addr_width / 8,
				     buf, len);
		if (!err || now > timeout) {
			break;
		}
		k_sleep(K_MSEC(1));
	}

	if (err < 0) {
		return err;
	}

	return len;
}

static int eeprom_at24_write(const struct device *dev, off_t offset,
			     const void *buf, size_t len)
{
	const struct eeprom_at2x_config *config = dev->config;
	int count = eeprom_at2x_limit_write_count(dev, offset, len);
	uint8_t block[config->addr_width / 8 + count];
	int64_t timeout;
	uint16_t bus_addr;
	int i = 0;
	int err;

	bus_addr = eeprom_at24_translate_offset(dev, &offset);

	/*
	 * Not all I2C EEPROMs support repeated start so the the
	 * address (offset) and data (buf) must be provided in one
	 * write transaction (block).
	 */
	if (config->addr_width == 16) {
		block[i++] = offset >> 8;
	}
	block[i++] = offset;
	memcpy(&block[i], buf, count);

	/*
	 * A write cycle may already be in progress so writes must be
	 * attempted until the previous write cycle should be
	 * completed.
	 */
	timeout = k_uptime_get() + config->timeout;
	while (1) {
		int64_t now = k_uptime_get();
		err = i2c_write(config->bus.i2c.bus, block, sizeof(block),
				bus_addr);
		if (!err || now > timeout) {
			break;
		}
		k_sleep(K_MSEC(1));
	}

	if (err < 0) {
		return err;
	}

	return count;
}
#endif /* CONFIG_EEPROM_AT24 */

#ifdef CONFIG_EEPROM_AT25

static bool eeprom_at25_bus_is_ready(const struct device *dev)
{
	const struct eeprom_at2x_config *config = dev->config;

	return spi_is_ready(&config->bus.spi);
}

static int eeprom_at25_rdsr(const struct device *dev, uint8_t *status)
{
	const struct eeprom_at2x_config *config = dev->config;
	uint8_t rdsr[2] = { EEPROM_AT25_RDSR, 0 };
	uint8_t sr[2];
	int err;
	const struct spi_buf tx_buf = {
		.buf = rdsr,
		.len = sizeof(rdsr),
	};
	const struct spi_buf_set tx = {
		.buffers = &tx_buf,
		.count = 1,
	};
	const struct spi_buf rx_buf = {
		.buf = sr,
		.len = sizeof(sr),
	};
	const struct spi_buf_set rx = {
		.buffers = &rx_buf,
		.count = 1,
	};

	err = spi_transceive_dt(&config->bus.spi, &tx, &rx);
	if (!err) {
		*status = sr[1];
	}

	return err;
}

static int eeprom_at25_wait_for_idle(const struct device *dev)
{
	const struct eeprom_at2x_config *config = dev->config;
	int64_t timeout;
	uint8_t status;
	int err;

	timeout = k_uptime_get() + config->timeout;
	while (1) {
		int64_t now = k_uptime_get();
		err = eeprom_at25_rdsr(dev, &status);
		if (err) {
			LOG_ERR("Could not read status register (err %d)", err);
			return err;
		}

		if (!(status & EEPROM_AT25_STATUS_WIP)) {
			return 0;
		}
		if (now > timeout) {
			break;
		}
		k_sleep(K_MSEC(1));
	}

	return -EBUSY;
}

static int eeprom_at25_read(const struct device *dev, off_t offset, void *buf,
			    size_t len)
{
	const struct eeprom_at2x_config *config = dev->config;
	struct eeprom_at2x_data *data = dev->data;
	size_t cmd_len = 1 + config->addr_width / 8;
	uint8_t cmd[4] = { EEPROM_AT25_READ, 0, 0, 0 };
	uint8_t *paddr;
	int err;
	const struct spi_buf tx_buf = {
		.buf = cmd,
		.len = cmd_len,
	};
	const struct spi_buf_set tx = {
		.buffers = &tx_buf,
		.count = 1,
	};
	const struct spi_buf rx_bufs[2] = {
		{
			.buf = NULL,
			.len = cmd_len,
		},
		{
			.buf = buf,
			.len = len,
		},
	};
	const struct spi_buf_set rx = {
		.buffers = rx_bufs,
		.count = ARRAY_SIZE(rx_bufs),
	};

	if (!len) {
		return 0;
	}

	if ((offset + len) > config->size) {
		LOG_WRN("attempt to read past device boundary");
		return -EINVAL;
	}

	paddr = &cmd[1];
	switch (config->addr_width) {
	case 24:
		*paddr++ = offset >> 16;
		__fallthrough;
	case 16:
		*paddr++ = offset >> 8;
		__fallthrough;
	case 8:
		*paddr++ = offset;
		break;
	default:
		__ASSERT(0, "invalid address width");
	}

	err = eeprom_at25_wait_for_idle(dev);
	if (err) {
		LOG_ERR("EEPROM idle wait failed (err %d)", err);
		k_mutex_unlock(&data->lock);
		return err;
	}

	err = spi_transceive_dt(&config->bus.spi, &tx, &rx);
	if (err < 0) {
		return err;
	}

	return len;
}

static int eeprom_at25_wren(const struct device *dev)
{
	const struct eeprom_at2x_config *config = dev->config;
	uint8_t cmd = EEPROM_AT25_WREN;
	const struct spi_buf tx_buf = {
		.buf = &cmd,
		.len = 1,
	};
	const struct spi_buf_set tx = {
		.buffers = &tx_buf,
		.count = 1,
	};

	return spi_write_dt(&config->bus.spi, &tx);
}

static int eeprom_at25_write(const struct device *dev, off_t offset,
			     const void *buf, size_t len)
{
	const struct eeprom_at2x_config *config = dev->config;
	int count = eeprom_at2x_limit_write_count(dev, offset, len);
	uint8_t cmd[4] = { EEPROM_AT25_WRITE, 0, 0, 0 };
	size_t cmd_len = 1 + config->addr_width / 8;
	uint8_t *paddr;
	int err;
	const struct spi_buf tx_bufs[2] = {
		{
			.buf = cmd,
			.len = cmd_len,
		},
		{
			.buf = (void *)buf,
			.len = count,
		},
	};
	const struct spi_buf_set tx = {
		.buffers = tx_bufs,
		.count = ARRAY_SIZE(tx_bufs),
	};

	paddr = &cmd[1];
	switch (config->addr_width) {
	case 24:
		*paddr++ = offset >> 16;
		__fallthrough;
	case 16:
		*paddr++ = offset >> 8;
		__fallthrough;
	case 8:
		*paddr++ = offset;
		break;
	default:
		__ASSERT(0, "invalid address width");
	}

	err = eeprom_at25_wait_for_idle(dev);
	if (err) {
		LOG_ERR("EEPROM idle wait failed (err %d)", err);
		return err;
	}

	err = eeprom_at25_wren(dev);
	if (err) {
		LOG_ERR("failed to disable write protection (err %d)", err);
		return err;
	}

	err = spi_transceive_dt(&config->bus.spi, &tx, NULL);
	if (err) {
		return err;
	}

	return count;
}
#endif /* CONFIG_EEPROM_AT25 */

static int eeprom_at2x_init(const struct device *dev)
{
	const struct eeprom_at2x_config *config = dev->config;
	struct eeprom_at2x_data *data = dev->data;

	k_mutex_init(&data->lock);

	if (!config->bus_is_ready(dev)) {
		LOG_ERR("parent bus device not ready");
		return -EINVAL;
	}

#if ANY_INST_HAS_WP_GPIOS
	if (config->wp_gpio.port) {
		int err;
		if (!device_is_ready(config->wp_gpio.port)) {
			LOG_ERR("wp gpio device not ready");
			return -EINVAL;
		}

		err = gpio_pin_configure_dt(&config->wp_gpio, GPIO_OUTPUT_ACTIVE);
		if (err) {
			LOG_ERR("failed to configure WP GPIO pin (err %d)", err);
			return err;
		}
	}
#endif /* ANY_INST_HAS_WP_GPIOS */

	return 0;
}

static const struct eeprom_driver_api eeprom_at2x_api = {
	.read = eeprom_at2x_read,
	.write = eeprom_at2x_write,
	.size = eeprom_at2x_size,
};

#define ASSERT_AT24_ADDR_W_VALID(w) \
	BUILD_ASSERT(w == 8U || w == 16U,		\
		     "Unsupported address width")

#define ASSERT_AT25_ADDR_W_VALID(w)			\
	BUILD_ASSERT(w == 8U || w == 16U || w == 24U,	\
		     "Unsupported address width")

#define ASSERT_PAGESIZE_IS_POWER_OF_2(page) \
	BUILD_ASSERT((page != 0U) && ((page & (page - 1)) == 0U),	\
		     "Page size is not a power of two")

#define ASSERT_SIZE_PAGESIZE_VALID(size, page)				\
	BUILD_ASSERT(size % page == 0U,					\
		     "Size is not an integer multiple of page size")

#define INST_DT_AT2X(inst, t) DT_INST(inst, atmel_at##t)

#define EEPROM_AT24_BUS(n, t) \
	{ .i2c = I2C_DT_SPEC_GET(INST_DT_AT2X(n, t)) }

#define EEPROM_AT25_BUS(n, t)						 \
	{ .spi = SPI_DT_SPEC_GET(INST_DT_AT2X(n, t),			 \
				 SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | \
				 SPI_WORD_SET(8), 0) }

#define EEPROM_AT2X_WP_GPIOS(id)					\
	IF_ENABLED(DT_NODE_HAS_PROP(id, wp_gpios),			\
		   (.wp_gpio = GPIO_DT_SPEC_GET(id, wp_gpios),))

#define EEPROM_AT2X_DEVICE(n, t) \
	ASSERT_PAGESIZE_IS_POWER_OF_2(DT_PROP(INST_DT_AT2X(n, t), pagesize)); \
	ASSERT_SIZE_PAGESIZE_VALID(DT_PROP(INST_DT_AT2X(n, t), size), \
				   DT_PROP(INST_DT_AT2X(n, t), pagesize)); \
	ASSERT_AT##t##_ADDR_W_VALID(DT_PROP(INST_DT_AT2X(n, t), \
					    address_width)); \
	static const struct eeprom_at2x_config eeprom_at##t##_config_##n = { \
		.bus = EEPROM_AT##t##_BUS(n, t), \
		EEPROM_AT2X_WP_GPIOS(INST_DT_AT2X(n, t)) \
		.size = DT_PROP(INST_DT_AT2X(n, t), size), \
		.pagesize = DT_PROP(INST_DT_AT2X(n, t), pagesize), \
		.addr_width = DT_PROP(INST_DT_AT2X(n, t), address_width), \
		.readonly = DT_PROP(INST_DT_AT2X(n, t), read_only), \
		.timeout = DT_PROP(INST_DT_AT2X(n, t), timeout), \
		.bus_is_ready = eeprom_at##t##_bus_is_ready, \
		.read_fn = eeprom_at##t##_read, \
		.write_fn = eeprom_at##t##_write, \
	}; \
	static struct eeprom_at2x_data eeprom_at##t##_data_##n; \
	DEVICE_DT_DEFINE(INST_DT_AT2X(n, t), &eeprom_at2x_init, \
			    NULL, &eeprom_at##t##_data_##n, \
			    &eeprom_at##t##_config_##n, POST_KERNEL, \
			    CONFIG_EEPROM_INIT_PRIORITY, \
			    &eeprom_at2x_api)

#define EEPROM_AT24_DEVICE(n) EEPROM_AT2X_DEVICE(n, 24)
#define EEPROM_AT25_DEVICE(n) EEPROM_AT2X_DEVICE(n, 25)

#define CALL_WITH_ARG(arg, expr) expr(arg);

#define INST_DT_AT2X_FOREACH(t, inst_expr) \
	LISTIFY(DT_NUM_INST_STATUS_OKAY(atmel_at##t),	\
		CALL_WITH_ARG, (), inst_expr)

#ifdef CONFIG_EEPROM_AT24
INST_DT_AT2X_FOREACH(24, EEPROM_AT24_DEVICE);
#endif

#ifdef CONFIG_EEPROM_AT25
INST_DT_AT2X_FOREACH(25, EEPROM_AT25_DEVICE);
#endif
