/*
 * Copyright (c) 2023 Cypress Semiconductor Corporation (an Infineon company) or
 * an affiliate of Cypress Semiconductor Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @brief I2C driver for Infineon CAT1 MCU family.
 */

#define DT_DRV_COMPAT infineon_cat1_i2c

#include <zephyr/drivers/i2c.h>
#include <zephyr/drivers/pinctrl.h>
#include <cyhal_i2c.h>
#include <cyhal_utils_psoc.h>
#include <cyhal_utils_psoc.h>
#include <cyhal_scb_common.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(i2c_infineon_cat1, CONFIG_I2C_LOG_LEVEL);

#define I2C_CAT1_EVENTS_MASK  (CYHAL_I2C_MASTER_WR_CMPLT_EVENT | CYHAL_I2C_MASTER_RD_CMPLT_EVENT | \
			       CYHAL_I2C_MASTER_ERR_EVENT)

#define I2C_CAT1_SLAVE_EVENTS_MASK                                                                 \
	(CYHAL_I2C_SLAVE_READ_EVENT | CYHAL_I2C_SLAVE_WRITE_EVENT |                                \
	 CYHAL_I2C_SLAVE_RD_BUF_EMPTY_EVENT | CYHAL_I2C_SLAVE_RD_CMPLT_EVENT |                     \
	 CYHAL_I2C_SLAVE_WR_CMPLT_EVENT | CYHAL_I2C_SLAVE_RD_BUF_EMPTY_EVENT |                     \
	 CYHAL_I2C_SLAVE_ERR_EVENT)

/* States for ASYNC operations */
#define CAT1_I2C_PENDING_NONE           (0U)
#define CAT1_I2C_PENDING_RX             (1U)
#define CAT1_I2C_PENDING_TX             (2U)
#define CAT1_I2C_PENDING_TX_RX          (3U)

/* I2C speed */
#define CAT1_I2C_SPEED_STANDARD_HZ      (100000UL)
#define CAT1_I2C_SPEED_FAST_HZ          (400000UL)
#define CAT1_I2C_SPEED_FAST_PLUS_HZ     (1000000UL)

/* Data structure */
struct ifx_cat1_i2c_data {
	cyhal_i2c_t obj;
	cyhal_i2c_cfg_t cfg;
	struct k_sem operation_sem;
	struct k_sem transfer_sem;
	uint32_t error_status;
	uint32_t async_pending;
	cyhal_resource_inst_t hw_resource;
	cyhal_clock_t clock;
	struct i2c_target_config *p_target_config;
	uint8_t i2c_target_wr_byte;
	uint8_t target_wr_buffer[CONFIG_I2C_INFINEON_CAT1_TARGET_BUF];
};

/* Device config structure */
struct ifx_cat1_i2c_config {
	uint32_t master_frequency;
	CySCB_Type *reg_addr;
	const struct pinctrl_dev_config *pcfg;
	uint8_t irq_priority;
};

/* Default SCB/I2C configuration structure */
static const cy_stc_scb_i2c_config_t _cyhal_i2c_default_config = {
	.i2cMode = CY_SCB_I2C_MASTER,
	.useRxFifo = false,
	.useTxFifo = true,
	.slaveAddress = 0U,
	.slaveAddressMask = 0U,
	.acceptAddrInFifo = false,
	.ackGeneralAddr = false,
	.enableWakeFromSleep = false,
	.enableDigitalFilter = false,
	.lowPhaseDutyCycle = 8U,
	.highPhaseDutyCycle = 8U,
};

static int32_t _get_hw_block_num(CySCB_Type *reg_addr)
{
	uint32_t i;

	for (i = 0u; i < _SCB_ARRAY_SIZE; i++) {
		if (_CYHAL_SCB_BASE_ADDRESSES[i] == reg_addr) {
			return i;
		}
	}

	return -ENOMEM;
}

#ifdef CONFIG_I2C_INFINEON_CAT1_ASYNC
static void ifx_master_event_handler(void *callback_arg, cyhal_i2c_event_t event)
{
	const struct device *dev = (const struct device *) callback_arg;
	struct ifx_cat1_i2c_data *data = dev->data;

	if (((CYHAL_I2C_MASTER_ERR_EVENT | CYHAL_I2C_SLAVE_ERR_EVENT) & event) != 0U) {
		/* In case of error abort transfer */
		(void)cyhal_i2c_abort_async(&data->obj);
		data->error_status = 1;
	}

	/* Release semaphore if operation complete
	 * When we have pending TX, RX operations, the semaphore will be released
	 * after TX, RX complete.
	 */
	if (((data->async_pending == CAT1_I2C_PENDING_TX_RX) &&
	     ((CYHAL_I2C_MASTER_RD_CMPLT_EVENT & event) != 0U)) ||
	    (data->async_pending != CAT1_I2C_PENDING_TX_RX)) {

		/* Release semaphore (After I2C async transfer is complete) */
		k_sem_give(&data->transfer_sem);
	}

	if (0 != (CYHAL_I2C_SLAVE_READ_EVENT & event)) {
		if (data->p_target_config->callbacks->read_requested) {
			data->p_target_config->callbacks->read_requested(data->p_target_config,
									 &data->i2c_target_wr_byte);
			data->obj.context.slaveTxBufferIdx = 0;
			data->obj.context.slaveTxBufferCnt = 0;
			data->obj.context.slaveTxBufferSize = 1;
			data->obj.context.slaveTxBuffer = &data->i2c_target_wr_byte;
		}
	}

	if (0 != (CYHAL_I2C_SLAVE_RD_BUF_EMPTY_EVENT & event)) {
		if (data->p_target_config->callbacks->read_processed) {
			data->p_target_config->callbacks->read_processed(data->p_target_config,
									 &data->i2c_target_wr_byte);
			data->obj.context.slaveTxBufferIdx = 0;
			data->obj.context.slaveTxBufferCnt = 0;
			data->obj.context.slaveTxBufferSize = 1;
			data->obj.context.slaveTxBuffer = &data->i2c_target_wr_byte;
		}
	}

	if (0 != (CYHAL_I2C_SLAVE_WRITE_EVENT & event)) {
		cyhal_i2c_slave_config_write_buffer(&data->obj, data->target_wr_buffer,
						    CONFIG_I2C_INFINEON_CAT1_TARGET_BUF);
		if (data->p_target_config->callbacks->write_requested) {
			data->p_target_config->callbacks->write_requested(data->p_target_config);
		}
	}

	if (0 != (CYHAL_I2C_SLAVE_WR_CMPLT_EVENT & event)) {
		if (data->p_target_config->callbacks->write_received) {
			for (int i = 0; i < data->obj.context.slaveRxBufferIdx; i++) {
				data->p_target_config->callbacks->write_received(
					data->p_target_config, data->target_wr_buffer[i]);
			}
		}
		if (data->p_target_config->callbacks->stop) {
			data->p_target_config->callbacks->stop(data->p_target_config);
		}
	}

	if (0 != (CYHAL_I2C_SLAVE_RD_CMPLT_EVENT & event)) {
		if (data->p_target_config->callbacks->stop) {
			data->p_target_config->callbacks->stop(data->p_target_config);
		}
	}
}
#endif

static int ifx_cat1_i2c_configure(const struct device *dev, uint32_t dev_config)
{
	struct ifx_cat1_i2c_data *data = dev->data;
	cy_rslt_t rslt;
	int ret;

	if (dev_config != 0) {
		switch (I2C_SPEED_GET(dev_config)) {
		case I2C_SPEED_STANDARD:
			data->cfg.frequencyhal_hz = CAT1_I2C_SPEED_STANDARD_HZ;
			break;
		case I2C_SPEED_FAST:
			data->cfg.frequencyhal_hz = CAT1_I2C_SPEED_FAST_HZ;
			break;
		case I2C_SPEED_FAST_PLUS:
			data->cfg.frequencyhal_hz = CAT1_I2C_SPEED_FAST_PLUS_HZ;
			break;
		default:
			LOG_ERR("Unsupported speed");
			return -ERANGE;
		}

		/* This is deprecated and could be ignored in the future */
		if (dev_config & I2C_ADDR_10_BITS) {
			LOG_ERR("10-bit addressing mode is not supported");
			return -EIO;
		}
	}

	/* Acquire semaphore (block I2C operation for another thread) */
	ret = k_sem_take(&data->operation_sem, K_FOREVER);
	if (ret) {
		return -EIO;
	}

	/* Configure the I2C resource to be master */
	rslt = cyhal_i2c_configure(&data->obj, &data->cfg);
	if (rslt != CY_RSLT_SUCCESS) {
		LOG_ERR("cyhal_i2c_configure failed with err 0x%x", rslt);
		k_sem_give(&data->operation_sem);
		return -EIO;
	}

#ifdef CONFIG_I2C_INFINEON_CAT1_ASYNC
	/* Register an I2C event callback handler */
	cyhal_i2c_register_callback(&data->obj, ifx_master_event_handler, (void *)dev);
#endif
	/* Release semaphore */
	k_sem_give(&data->operation_sem);
	return 0;
}

static int ifx_cat1_i2c_get_config(const struct device *dev, uint32_t *dev_config)
{
	struct ifx_cat1_i2c_data *data = dev->data;
	uint32_t config;

	switch (data->cfg.frequencyhal_hz) {
	case CAT1_I2C_SPEED_STANDARD_HZ:
		config = I2C_SPEED_SET(I2C_SPEED_STANDARD);
		break;
	case CAT1_I2C_SPEED_FAST_HZ:
		config = I2C_SPEED_SET(I2C_SPEED_FAST);
		break;
	case CAT1_I2C_SPEED_FAST_PLUS_HZ:
		config = I2C_SPEED_SET(I2C_SPEED_FAST_PLUS);
		break;
	default:
		LOG_ERR("Unsupported speed");
		return -ERANGE;
	}

	/* Return current configuration */
	*dev_config = config | I2C_MODE_CONTROLLER;

	return 0;
}

static int ifx_cat1_i2c_msg_validate(struct i2c_msg *msg, uint8_t num_msgs)
{
	for (uint32_t i = 0u; i < num_msgs; i++) {
		if ((I2C_MSG_ADDR_10_BITS & msg[i].flags) || (msg[i].buf == NULL)) {
			return -EINVAL;
		}
	}
	return 0;
}

static int ifx_cat1_i2c_transfer(const struct device *dev, struct i2c_msg *msg, uint8_t num_msgs,
				 uint16_t addr)
{
	struct ifx_cat1_i2c_data *data = dev->data;
	cy_rslt_t rslt = CY_RSLT_SUCCESS;
	int ret;

	if (!num_msgs) {
		return 0;
	}

	/* Acquire semaphore (block I2C transfer for another thread) */
	ret = k_sem_take(&data->operation_sem, K_FOREVER);
	if (ret) {
		return -EIO;
	}

	/* This function checks if msg.buf is not NULL and if
	 * target address is not 10 bit.
	 */
	if (ifx_cat1_i2c_msg_validate(msg, num_msgs) != 0) {
		k_sem_give(&data->operation_sem);
		return -EINVAL;
	}

#ifdef CONFIG_I2C_INFINEON_CAT1_ASYNC
	const struct ifx_cat1_i2c_config *const config = dev->config;

	struct i2c_msg *tx_msg;
	struct i2c_msg *rx_msg;

	data->error_status = 0;
	data->async_pending = CAT1_I2C_PENDING_NONE;

	/* Enable I2C Interrupt */
	cyhal_i2c_enable_event(&data->obj, (cyhal_i2c_event_t)I2C_CAT1_EVENTS_MASK,
			       config->irq_priority, true);

	for (uint32_t i = 0u; i < num_msgs; i++) {
		tx_msg = NULL;
		rx_msg = NULL;

		if ((msg[i].flags & I2C_MSG_RW_MASK) == I2C_MSG_WRITE) {
			tx_msg = &msg[i];
			data->async_pending = CAT1_I2C_PENDING_TX;
		}

		if ((msg[i].flags & I2C_MSG_RW_MASK) == I2C_MSG_READ) {
			rx_msg = &msg[i];
			data->async_pending = CAT1_I2C_PENDING_TX;
		}

		if ((tx_msg != NULL) && ((i + 1U) < num_msgs) &&
		    ((msg[i + 1U].flags & I2C_MSG_RW_MASK) == I2C_MSG_READ)) {
			rx_msg = &msg[i + 1U];
			i++;
			data->async_pending = CAT1_I2C_PENDING_TX_RX;
		}

		/* Initiate master write and read transfer
		 * using tx_buff and rx_buff respectively
		 */
		rslt = cyhal_i2c_master_transfer_async(&data->obj, addr,
						       (tx_msg == NULL) ? NULL : tx_msg->buf,
						       (tx_msg == NULL) ? 0u : tx_msg->len,
						       (rx_msg == NULL) ? NULL : rx_msg->buf,
						       (rx_msg == NULL) ? 0u : rx_msg->len);

		if (rslt != CY_RSLT_SUCCESS) {
			k_sem_give(&data->operation_sem);
			return -EIO;
		}

		/* Acquire semaphore (block I2C async transfer for another thread) */
		ret = k_sem_take(&data->transfer_sem, K_FOREVER);
		if (ret) {
			k_sem_give(&data->operation_sem);
			return -EIO;
		}

		/* If error_status != 1 we have error during transfer async.
		 * error_status is handling in master_event_handler function.
		 */
		if (data->error_status != 0) {
			/* Release semaphore */
			k_sem_give(&data->operation_sem);
			return -EIO;
		}
	}

	/* Disable I2C Interrupt */
	cyhal_i2c_enable_event(&data->obj, (cyhal_i2c_event_t)
			       I2C_CAT1_EVENTS_MASK, config->irq_priority, false);
#else
	for (uint32_t i = 0u; i < num_msgs; i++) {
		bool stop_flag = ((msg[i].flags & I2C_MSG_STOP) != 0u) ? true : false;

		if ((msg[i].flags & I2C_MSG_RW_MASK) == I2C_MSG_WRITE) {
			rslt = cyhal_i2c_master_write(&data->obj,
						      addr, msg[i].buf, msg[i].len, 0, stop_flag);
		}
		if ((msg[i].flags & I2C_MSG_RW_MASK) == I2C_MSG_READ) {
			rslt = cyhal_i2c_master_read(&data->obj,
						     addr, msg[i].buf, msg[i].len, 0, stop_flag);
		}

		if (rslt != CY_RSLT_SUCCESS) {
			/* Release semaphore */
			k_sem_give(&data->operation_sem);
			return -EIO;
		}
	}
#endif
	/* Release semaphore (After I2C transfer is complete) */
	k_sem_give(&data->operation_sem);
	return 0;
}

static int ifx_cat1_i2c_init(const struct device *dev)
{
	struct ifx_cat1_i2c_data *data = dev->data;
	const struct ifx_cat1_i2c_config *config = dev->config;
	cy_rslt_t result;
	int ret;

	/* Configuration structure to initialisation I2C */
	cyhal_i2c_configurator_t i2c_init_cfg = {
		.resource = &data->hw_resource,
		.config = &_cyhal_i2c_default_config,
		.clock = &data->clock,
	};

	/* Dedicate SCB HW resource */
	data->hw_resource.type = CYHAL_RSC_SCB;
	data->hw_resource.block_num = _get_hw_block_num(config->reg_addr);


	/* Configure semaphores */
	ret = k_sem_init(&data->transfer_sem, 0, 1);
	if (ret) {
		return ret;
	}

	ret = k_sem_init(&data->operation_sem, 1, 1);
	if (ret) {
		return ret;
	}

	/* Configure dt provided device signals when available */
	ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
	if (ret < 0) {
		return ret;
	}

	/* Allocating clock for I2C driver */
	result = _cyhal_utils_allocate_clock(&data->clock, &data->hw_resource,
					     CYHAL_CLOCK_BLOCK_PERIPHERAL_16BIT, true);
	if (result != CY_RSLT_SUCCESS) {
		return -ENOTSUP;
	}

	/* Assigns a programmable divider to a selected IP block */
	en_clk_dst_t clk_idx = _cyhal_scb_get_clock_index(i2c_init_cfg.resource->block_num);

	result = _cyhal_utils_peri_pclk_assign_divider(clk_idx, i2c_init_cfg.clock);
	if (result != CY_RSLT_SUCCESS) {
		return -ENOTSUP;
	}

	/* Initialize the I2C peripheral */
	result = cyhal_i2c_init_cfg(&data->obj, &i2c_init_cfg);
	if (result != CY_RSLT_SUCCESS) {
		return -ENOTSUP;
	}
	data->obj.is_clock_owned = true;

	/* Store Master initial configuration */
	data->cfg.is_slave = false;
	data->cfg.address = 0;
	data->cfg.frequencyhal_hz = config->master_frequency;

	if (ifx_cat1_i2c_configure(dev, 0) != 0) {
		/* Free I2C resource */
		cyhal_i2c_free(&data->obj);
	}
	return 0;
}

static int ifx_cat1_i2c_target_register(const struct device *dev, struct i2c_target_config *cfg)
{
	struct ifx_cat1_i2c_data *data = (struct ifx_cat1_i2c_data *)dev->data;
	const struct ifx_cat1_i2c_config *config = dev->config;

	if (!cfg) {
		return -EINVAL;
	}

	if (cfg->flags & I2C_TARGET_FLAGS_ADDR_10_BITS) {
		return -ENOTSUP;
	}

	data->p_target_config = cfg;
	data->cfg.is_slave = true;
	data->cfg.address = data->p_target_config->address;
	data->cfg.frequencyhal_hz = 100000;

	if (ifx_cat1_i2c_configure(dev, I2C_SPEED_SET(I2C_SPEED_FAST)) != 0) {
		/* Free I2C resource */
		cyhal_i2c_free(&data->obj);
		/* Release semaphore */
		k_sem_give(&data->operation_sem);
		return -EIO;
	}

	cyhal_i2c_enable_event(&data->obj, (cyhal_i2c_event_t)I2C_CAT1_SLAVE_EVENTS_MASK,
			       config->irq_priority, true);
	return 0;
}

static int ifx_cat1_i2c_target_unregister(const struct device *dev, struct i2c_target_config *cfg)
{
	struct ifx_cat1_i2c_data *data = (struct ifx_cat1_i2c_data *)dev->data;
	const struct ifx_cat1_i2c_config *config = dev->config;

	/* Acquire semaphore (block I2C operation for another thread) */
	k_sem_take(&data->operation_sem, K_FOREVER);

	cyhal_i2c_free(&data->obj);
	data->p_target_config = NULL;
	cyhal_i2c_enable_event(&data->obj, (cyhal_i2c_event_t)I2C_CAT1_SLAVE_EVENTS_MASK,
			       config->irq_priority, false);

	/* Release semaphore */
	k_sem_give(&data->operation_sem);
	return 0;
}

/* I2C API structure */
static const struct i2c_driver_api i2c_cat1_driver_api = {
	.configure = ifx_cat1_i2c_configure,
	.transfer = ifx_cat1_i2c_transfer,
	.get_config = ifx_cat1_i2c_get_config,
	.target_register = ifx_cat1_i2c_target_register,
	.target_unregister = ifx_cat1_i2c_target_unregister};

/* Macros for I2C instance declaration */
#define INFINEON_CAT1_I2C_INIT(n)                                                                  \
	PINCTRL_DT_INST_DEFINE(n);                                                                 \
                                                                                                   \
	static struct ifx_cat1_i2c_data ifx_cat1_i2c_data##n;                                      \
                                                                                                   \
	static const struct ifx_cat1_i2c_config i2c_cat1_cfg_##n = {                               \
		.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n),                                         \
		.master_frequency = DT_INST_PROP_OR(n, clock_frequency, 100000),                   \
		.reg_addr = (CySCB_Type *)DT_INST_REG_ADDR(n),                                     \
		.irq_priority = DT_INST_IRQ(n, priority),                                          \
	};                                                                                         \
                                                                                                   \
	I2C_DEVICE_DT_INST_DEFINE(n, ifx_cat1_i2c_init, NULL, &ifx_cat1_i2c_data##n,               \
				  &i2c_cat1_cfg_##n, POST_KERNEL,                                  \
				  CONFIG_I2C_INIT_PRIORITY, &i2c_cat1_driver_api);

DT_INST_FOREACH_STATUS_OKAY(INFINEON_CAT1_I2C_INIT)
