/*
 * 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 <drivers/eeprom.h>
#include <drivers/gpio.h>
#include <drivers/i2c.h>
#include <drivers/spi.h>
#include <sys/byteorder.h>
#include <zephyr.h>

#define LOG_LEVEL CONFIG_EEPROM_LOG_LEVEL
#include <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) */

struct eeprom_at2x_config {
	const struct device *bus_dev;
	union {
#ifdef CONFIG_EEPROM_AT24
		uint16_t i2c_addr;
#endif /* CONFIG_EEPROM_AT24 */
#ifdef CONFIG_EEPROM_AT25
		struct spi_config spi_cfg;
#endif /* CONFIG_EEPROM_AT25 */
	} bus;
	struct gpio_dt_spec wp_gpio;
	size_t size;
	size_t pagesize;
	uint8_t addr_width;
	bool readonly;
	uint16_t timeout;
	eeprom_api_read read_fn;
	eeprom_api_write write_fn;
};

struct eeprom_at2x_data {
	struct k_mutex lock;
};

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(config->wp_gpio.port, config->wp_gpio.pin, 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(config->wp_gpio.port, config->wp_gpio.pin, 0);
}

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

	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;
	}

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

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

	ret = eeprom_at2x_write_protect(dev);
	if (ret) {
		LOG_ERR("failed to write-protect EEPROM (err %d)", ret);
	}

	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

/**
 * @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_dev, 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_dev, 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 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(config->bus_dev, &config->bus.spi_cfg, &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(config->bus_dev, &config->bus.spi_cfg, &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(config->bus_dev, &config->bus.spi_cfg, &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(config->bus_dev, &config->bus.spi_cfg, &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;
	int err;

	k_mutex_init(&data->lock);

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

	if (config->wp_gpio.port) {
		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;
		}
	}

	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_addr = DT_REG_ADDR(INST_DT_AT2X(n, t)) }

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

#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_dev = DEVICE_DT_GET(DT_BUS(INST_DT_AT2X(n, t))), \
		.bus = EEPROM_AT##t##_BUS(n, t), \
		.wp_gpio = GPIO_DT_SPEC_GET_OR(INST_DT_AT2X(n, t), wp_gpios, {0}), \
		.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), \
		.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_AT2X_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) \
	UTIL_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
