/*
 * Copyright (c) 2017 BayLibre, SAS
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT zephyr_i2c_target_eeprom

#include <zephyr/sys/util.h>
#include <zephyr/kernel.h>
#include <errno.h>
#include <zephyr/drivers/i2c.h>
#include <string.h>
#include <zephyr/drivers/i2c/target/eeprom.h>

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

struct i2c_eeprom_target_data {
	struct i2c_target_config config;
	uint32_t buffer_size;
	uint8_t *buffer;
	uint32_t buffer_idx;
	bool first_write;
};

struct i2c_eeprom_target_config {
	struct i2c_dt_spec bus;
	uint32_t buffer_size;
	uint8_t *buffer;
};

int eeprom_target_program(const struct device *dev, const uint8_t *eeprom_data,
			 unsigned int length)
{
	struct i2c_eeprom_target_data *data = dev->data;

	if (length > data->buffer_size) {
		return -EINVAL;
	}

	memcpy(data->buffer, eeprom_data, length);

	return 0;
}

int eeprom_target_read(const struct device *dev, uint8_t *eeprom_data,
		      unsigned int offset)
{
	struct i2c_eeprom_target_data *data = dev->data;

	if (!data || offset >= data->buffer_size) {
		return -EINVAL;
	}

	*eeprom_data = data->buffer[offset];

	return 0;
}

static int eeprom_target_write_requested(struct i2c_target_config *config)
{
	struct i2c_eeprom_target_data *data = CONTAINER_OF(config,
						struct i2c_eeprom_target_data,
						config);

	LOG_DBG("eeprom: write req");

	data->first_write = true;

	return 0;
}

static int eeprom_target_read_requested(struct i2c_target_config *config,
				       uint8_t *val)
{
	struct i2c_eeprom_target_data *data = CONTAINER_OF(config,
						struct i2c_eeprom_target_data,
						config);

	*val = data->buffer[data->buffer_idx];

	LOG_DBG("eeprom: read req, val=0x%x", *val);

	/* Increment will be done in the read_processed callback */

	return 0;
}

static int eeprom_target_write_received(struct i2c_target_config *config,
				       uint8_t val)
{
	struct i2c_eeprom_target_data *data = CONTAINER_OF(config,
						struct i2c_eeprom_target_data,
						config);

	LOG_DBG("eeprom: write done, val=0x%x", val);

	/* In case EEPROM wants to be R/O, return !0 here could trigger
	 * a NACK to the I2C controller, support depends on the
	 * I2C controller support
	 */

	if (data->first_write) {
		data->buffer_idx = val;
		data->first_write = false;
	} else {
		data->buffer[data->buffer_idx++] = val;
	}

	data->buffer_idx = data->buffer_idx % data->buffer_size;

	return 0;
}

static int eeprom_target_read_processed(struct i2c_target_config *config,
				       uint8_t *val)
{
	struct i2c_eeprom_target_data *data = CONTAINER_OF(config,
						struct i2c_eeprom_target_data,
						config);

	/* Increment here */
	data->buffer_idx = (data->buffer_idx + 1) % data->buffer_size;

	*val = data->buffer[data->buffer_idx];

	LOG_DBG("eeprom: read done, val=0x%x", *val);

	/* Increment will be done in the next read_processed callback
	 * In case of STOP, the byte won't be taken in account
	 */

	return 0;
}

static int eeprom_target_stop(struct i2c_target_config *config)
{
	struct i2c_eeprom_target_data *data = CONTAINER_OF(config,
						struct i2c_eeprom_target_data,
						config);

	LOG_DBG("eeprom: stop");

	data->first_write = true;

	return 0;
}

static int eeprom_target_register(const struct device *dev)
{
	const struct i2c_eeprom_target_config *cfg = dev->config;
	struct i2c_eeprom_target_data *data = dev->data;

	return i2c_target_register(cfg->bus.bus, &data->config);
}

static int eeprom_target_unregister(const struct device *dev)
{
	const struct i2c_eeprom_target_config *cfg = dev->config;
	struct i2c_eeprom_target_data *data = dev->data;

	return i2c_target_unregister(cfg->bus.bus, &data->config);
}

static const struct i2c_target_driver_api api_funcs = {
	.driver_register = eeprom_target_register,
	.driver_unregister = eeprom_target_unregister,
};

static const struct i2c_target_callbacks eeprom_callbacks = {
	.write_requested = eeprom_target_write_requested,
	.read_requested = eeprom_target_read_requested,
	.write_received = eeprom_target_write_received,
	.read_processed = eeprom_target_read_processed,
	.stop = eeprom_target_stop,
};

static int i2c_eeprom_target_init(const struct device *dev)
{
	struct i2c_eeprom_target_data *data = dev->data;
	const struct i2c_eeprom_target_config *cfg = dev->config;

	if (!device_is_ready(cfg->bus.bus)) {
		LOG_ERR("I2C controller device not ready");
		return -ENODEV;
	}

	data->buffer_size = cfg->buffer_size;
	data->buffer = cfg->buffer;
	data->config.address = cfg->bus.addr;
	data->config.callbacks = &eeprom_callbacks;

	return 0;
}

#define I2C_EEPROM_INIT(inst)						\
	static struct i2c_eeprom_target_data				\
		i2c_eeprom_target_##inst##_dev_data;			\
									\
	static uint8_t							\
	i2c_eeprom_target_##inst##_buffer[(DT_INST_PROP(inst, size))];	\
									\
	static const struct i2c_eeprom_target_config			\
		i2c_eeprom_target_##inst##_cfg = {			\
		.bus = I2C_DT_SPEC_INST_GET(inst),			\
		.buffer_size = DT_INST_PROP(inst, size),		\
		.buffer = i2c_eeprom_target_##inst##_buffer		\
	};								\
									\
	DEVICE_DT_INST_DEFINE(inst,					\
			    &i2c_eeprom_target_init,			\
			    NULL,			\
			    &i2c_eeprom_target_##inst##_dev_data,	\
			    &i2c_eeprom_target_##inst##_cfg,		\
			    POST_KERNEL,				\
			    CONFIG_I2C_TARGET_INIT_PRIORITY,		\
			    &api_funcs);

DT_INST_FOREACH_STATUS_OKAY(I2C_EEPROM_INIT)
