/*
 * Copyright 2020 Google LLC
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT atmel_at24

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

#include <zephyr/device.h>
#include <zephyr/drivers/emul.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/i2c_emul.h>

/** Run-time data used by the emulator */
struct at24_emul_data {
	/** I2C emulator detail */
	struct i2c_emul emul;
	/** AT24 device being emulated */
	const struct device *i2c;
	/** Current register to read (address) */
	uint32_t cur_reg;
};

/** Static configuration for the emulator */
struct at24_emul_cfg {
	/** EEPROM data contents */
	uint8_t *buf;
	/** Size of EEPROM in bytes */
	uint32_t size;
	/** Address of EEPROM on i2c bus */
	uint16_t addr;
	/** Address width for EEPROM in bits (only 8 is supported at present) */
	uint8_t addr_width;
};

/**
 * Emulator an I2C transfer to an AT24 chip
 *
 * This handles simple reads and writes
 *
 * @param emul I2C emulation information
 * @param msgs List of messages to process. For 'read' messages, this function
 *	updates the 'buf' member with the data that was read
 * @param num_msgs Number of messages to process
 * @param addr Address of the I2C target device. This is assumed to be correct,
 *	due to the
 * @retval 0 If successful
 * @retval -EIO General input / output error
 */
static int at24_emul_transfer(const struct emul *target, struct i2c_msg *msgs,
			      int num_msgs, int addr)
{
	struct at24_emul_data *data;
	const struct at24_emul_cfg *cfg;
	unsigned int len;
	bool too_fast;
	uint32_t i2c_cfg;

	data = target->data;
	cfg = target->cfg;

	if (cfg->addr != addr) {
		LOG_ERR("Address mismatch, expected %02x, got %02x", cfg->addr,
			addr);
		return -EIO;
	}

	if (i2c_get_config(data->i2c, &i2c_cfg)) {
		LOG_ERR("i2c_get_config failed");
		return -EIO;
	}
	/* For testing purposes, fail if the bus speed is above standard */
	too_fast = (I2C_SPEED_GET(i2c_cfg) > I2C_SPEED_STANDARD);
	if (too_fast) {
		LOG_ERR("Speed too high");
		return -EIO;
	}

	i2c_dump_msgs_rw("emul", msgs, num_msgs, addr, false);
	switch (num_msgs) {
	case 1:
		if (msgs->flags & I2C_MSG_READ) {
			/* handle read */
			break;
		}
		data->cur_reg = msgs->buf[0];
		len = MIN(msgs->len - 1, cfg->size - data->cur_reg);
		memcpy(&cfg->buf[data->cur_reg], &msgs->buf[1], len);
		return 0;
	case 2:
		if (msgs->flags & I2C_MSG_READ) {
			LOG_ERR("Unexpected read");
			return -EIO;
		}
		data->cur_reg = msgs->buf[0];

		/* Now process the 'read' part of the message */
		msgs++;
		if (!(msgs->flags & I2C_MSG_READ)) {
			LOG_ERR("Unexpected write");
			return -EIO;
		}
		break;
	default:
		LOG_ERR("Invalid number of messages");
		return -EIO;
	}

	/* Read data from the EEPROM into the buffer */
	len = MIN(msgs->len, cfg->size - data->cur_reg);
	memcpy(msgs->buf, &cfg->buf[data->cur_reg], len);
	data->cur_reg += len;

	return 0;
}

/* Device instantiation */

static struct i2c_emul_api bus_api = {
	.transfer = at24_emul_transfer,
};

/**
 * Set up a new AT24 emulator
 *
 * This should be called for each AT24 device that needs to be emulated. It
 * registers it with the I2C emulation controller.
 *
 * @param target Emulation information
 * @param parent Device to emulate (must use AT24 driver)
 * @return 0 indicating success (always)
 */
static int emul_atmel_at24_init(const struct emul *target, const struct device *parent)
{
	const struct at24_emul_cfg *cfg = target->cfg;
	struct at24_emul_data *data = target->data;

	data->emul.api = &bus_api;
	data->emul.addr = cfg->addr;
	data->emul.target = target;
	data->i2c = parent;
	data->cur_reg = 0;

	/* Start with an erased EEPROM, assuming all 0xff */
	memset(cfg->buf, 0xff, cfg->size);

	return 0;
}

#define EEPROM_AT24_EMUL(n)                                                                        \
	static uint8_t at24_emul_buf_##n[DT_INST_PROP(n, size)];                                   \
	static struct at24_emul_data at24_emul_data_##n;                                           \
	static const struct at24_emul_cfg at24_emul_cfg_##n = {                                    \
		.buf = at24_emul_buf_##n,                                                          \
		.size = DT_INST_PROP(n, size),                                                     \
		.addr = DT_INST_REG_ADDR(n),                                                       \
		.addr_width = 8,                                                                   \
	};                                                                                         \
	EMUL_DT_INST_DEFINE(n, emul_atmel_at24_init, &at24_emul_data_##n, &at24_emul_cfg_##n,      \
			    &bus_api, NULL)

DT_INST_FOREACH_STATUS_OKAY(EEPROM_AT24_EMUL)
