/*
 * 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("emul", msgs, num_msgs, addr);
	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)

DT_INST_FOREACH_STATUS_OKAY(EEPROM_AT24_EMUL)
