/*
 * Copyright (c) 2020 Espressif Systems (Shanghai) Co., Ltd.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT espressif_esp32_spi

/* Include esp-idf headers first to avoid redefining BIT() macro */
#include <hal/spi_hal.h>
#include <esp_attr.h>

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(esp32_spi, CONFIG_SPI_LOG_LEVEL);

#include <soc.h>
#include <soc/soc_memory_types.h>
#include <zephyr/drivers/spi.h>
#ifndef CONFIG_SOC_ESP32C3
#include <zephyr/drivers/interrupt_controller/intc_esp32.h>
#else
#include <hal/gdma_hal.h>
#include <hal/gdma_ll.h>
#include <zephyr/drivers/interrupt_controller/intc_esp32c3.h>
#endif
#include <zephyr/drivers/clock_control.h>
#include "spi_context.h"
#include "spi_esp32_spim.h"

#ifdef CONFIG_SOC_ESP32C3
#define ISR_HANDLER isr_handler_t
#else
#define ISR_HANDLER intr_handler_t
#endif

static bool spi_esp32_transfer_ongoing(struct spi_esp32_data *data)
{
	return spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx);
}

static inline void spi_esp32_complete(const struct device *dev,
				      struct spi_esp32_data *data,
				      spi_dev_t *spi, int status)
{
#ifdef CONFIG_SPI_ESP32_INTERRUPT
	spi_ll_disable_int(spi);
	spi_ll_clear_int_stat(spi);
#endif

	spi_context_cs_control(&data->ctx, false);

#ifdef CONFIG_SPI_ESP32_INTERRUPT
	spi_context_complete(&data->ctx, dev, status);
#endif

}

static int IRAM_ATTR spi_esp32_transfer(const struct device *dev)
{
	struct spi_esp32_data *data = dev->data;
	const struct spi_esp32_config *cfg = dev->config;
	struct spi_context *ctx = &data->ctx;
	spi_hal_context_t *hal = &data->hal;
	spi_hal_dev_config_t *hal_dev = &data->dev_config;
	spi_hal_trans_config_t *hal_trans = &data->trans_config;
	size_t chunk_len = spi_context_max_continuous_chunk(&data->ctx);
	chunk_len = MIN(chunk_len, SOC_SPI_MAXIMUM_BUFFER_SIZE);
	size_t bit_len = chunk_len << 3;
	uint8_t *rx_temp = NULL;
	uint8_t *tx_temp = NULL;

	if (cfg->dma_enabled) {
		/* bit_len needs to be at least one byte long when using DMA */
		bit_len = !bit_len ? 8 : bit_len;
		if (ctx->tx_buf && !esp_ptr_dma_capable((uint32_t *)&ctx->tx_buf[0])) {
			tx_temp = k_malloc(ctx->tx_len);
			if (!tx_temp) {
				LOG_ERR("Error allocating temp buffer Tx");
				return -ENOMEM;
			}
			memcpy(tx_temp, &ctx->tx_buf[0], ctx->tx_len);
		}
		if (ctx->rx_buf && (!esp_ptr_dma_capable((uint32_t *)&ctx->rx_buf[0]) ||
				    ((int)&ctx->rx_buf[0] % 4 != 0))) {
			/* The rx buffer need to be length of
			 * multiples of 32 bits to avoid heap
			 * corruption.
			 */
			rx_temp = k_calloc(((ctx->rx_len << 3) + 31) / 8, sizeof(uint8_t));
			if (!rx_temp) {
				LOG_ERR("Error allocating temp buffer Rx");
				return -ENOMEM;
			}
		}
	}

	/* clean up and prepare SPI hal */
	memset((uint32_t *)hal->hw->data_buf, 0, sizeof(hal->hw->data_buf));
	hal_trans->send_buffer = tx_temp ? tx_temp : (uint8_t *)ctx->tx_buf;
	hal_trans->rcv_buffer = rx_temp ? rx_temp : ctx->rx_buf;
	hal_trans->tx_bitlen = bit_len;
	hal_trans->rx_bitlen = bit_len;

	/* configure SPI */
	spi_hal_setup_trans(hal, hal_dev, hal_trans);
	spi_hal_prepare_data(hal, hal_dev, hal_trans);

	/* send data */
	spi_hal_user_start(hal);
	spi_context_update_tx(&data->ctx, data->dfs, chunk_len);

	while (!spi_hal_usr_is_done(hal)) {
		/* nop */
	}

	/* read data */
	spi_hal_fetch_result(hal);

	if (rx_temp) {
		memcpy(&ctx->rx_buf[0], rx_temp, chunk_len);
	}

	spi_context_update_rx(&data->ctx, data->dfs, chunk_len);

	if (tx_temp) {
		k_free(tx_temp);
	}

	if (rx_temp) {
		k_free(rx_temp);
	}

	return 0;
}

#ifdef CONFIG_SPI_ESP32_INTERRUPT
static void IRAM_ATTR spi_esp32_isr(void *arg)
{
	const struct device *dev = (const struct device *)arg;
	const struct spi_esp32_config *cfg = dev->config;
	struct spi_esp32_data *data = dev->data;

	do {
		spi_esp32_transfer(dev);
	} while (spi_esp32_transfer_ongoing(data));

	spi_esp32_complete(dev, data, cfg->spi, 0);
}
#endif

static int spi_esp32_init_dma(const struct device *dev)
{
	const struct spi_esp32_config *cfg = dev->config;
	struct spi_esp32_data *data = dev->data;
	uint8_t channel_offset;

	if (clock_control_on(cfg->clock_dev, (clock_control_subsys_t)cfg->dma_clk_src)) {
		LOG_ERR("Could not enable DMA clock");
		return -EIO;
	}

#ifdef CONFIG_SOC_ESP32C3
	gdma_hal_init(&data->hal_gdma, 0);
	gdma_ll_enable_clock(data->hal_gdma.dev, true);
	gdma_ll_tx_reset_channel(data->hal_gdma.dev, cfg->dma_host);
	gdma_ll_rx_reset_channel(data->hal_gdma.dev, cfg->dma_host);
	gdma_ll_tx_connect_to_periph(data->hal_gdma.dev, cfg->dma_host, 0);
	gdma_ll_rx_connect_to_periph(data->hal_gdma.dev, cfg->dma_host, 0);
	channel_offset = 0;
#else
	channel_offset = 1;
#endif /* CONFIG_SOC_ESP32C3 */
#ifdef CONFIG_SOC_ESP32
	/*Connect SPI and DMA*/
	DPORT_SET_PERI_REG_BITS(DPORT_SPI_DMA_CHAN_SEL_REG, 3, cfg->dma_host + 1,
				((cfg->dma_host + 1) * 2));
#endif /* CONFIG_SOC_ESP32 */

	data->hal_config.dma_in = (spi_dma_dev_t *)cfg->spi;
	data->hal_config.dma_out = (spi_dma_dev_t *)cfg->spi;
	data->hal_config.dma_enabled = true;
	data->hal_config.tx_dma_chan = cfg->dma_host + channel_offset;
	data->hal_config.rx_dma_chan = cfg->dma_host + channel_offset;
	data->hal_config.dmadesc_n = 1;
	data->hal_config.dmadesc_rx = &data->dma_desc_rx;
	data->hal_config.dmadesc_tx = &data->dma_desc_tx;

	if (data->hal_config.dmadesc_tx == NULL || data->hal_config.dmadesc_rx == NULL) {
		k_free(data->hal_config.dmadesc_tx);
		k_free(data->hal_config.dmadesc_rx);
		return -ENOMEM;
	}

	spi_hal_init(&data->hal, cfg->dma_host + 1, &data->hal_config);
	return 0;
}

static int spi_esp32_init(const struct device *dev)
{
	int err;
	const struct spi_esp32_config *cfg = dev->config;
	struct spi_esp32_data *data = dev->data;

	if (!cfg->clock_dev) {
		return -EINVAL;
	}

	if (cfg->dma_enabled) {
		spi_esp32_init_dma(dev);
	}

#ifdef CONFIG_SPI_ESP32_INTERRUPT
	data->irq_line = esp_intr_alloc(cfg->irq_source,
			0,
			(ISR_HANDLER)spi_esp32_isr,
			(void *)dev,
			NULL);
#endif

	err = spi_context_cs_configure_all(&data->ctx);
	if (err < 0) {
		return err;
	}

	spi_context_unlock_unconditionally(&data->ctx);

	return 0;
}

static inline uint8_t spi_esp32_get_line_mode(uint16_t operation)
{
	if (IS_ENABLED(CONFIG_SPI_EXTENDED_MODES)) {
		switch (operation & SPI_LINES_MASK) {
		case SPI_LINES_SINGLE:
			return 1;
		case SPI_LINES_DUAL:
			return 2;
		case SPI_LINES_OCTAL:
			return 8;
		case SPI_LINES_QUAD:
			return 4;
		default:
			break;
		}
	}

	return 1;
}

static int IRAM_ATTR spi_esp32_configure(const struct device *dev,
					 const struct spi_config *spi_cfg)
{
	const struct spi_esp32_config *cfg = dev->config;
	struct spi_esp32_data *data = dev->data;
	struct spi_context *ctx = &data->ctx;
	spi_hal_context_t *hal = &data->hal;
	spi_hal_dev_config_t *hal_dev = &data->dev_config;
	int freq;

	if (spi_context_configured(ctx, spi_cfg)) {
		return 0;
	}

	if (!device_is_ready(cfg->clock_dev)) {
		LOG_ERR("clock control device not ready");
		return -ENODEV;
	}

	/* enables SPI peripheral */
	if (clock_control_on(cfg->clock_dev, cfg->clock_subsys)) {
		LOG_ERR("Could not enable SPI clock");
		return -EIO;
	}

	spi_ll_master_init(hal->hw);

	ctx->config = spi_cfg;

	if (spi_cfg->operation & SPI_HALF_DUPLEX) {
		LOG_ERR("Half-duplex not supported");
		return -ENOTSUP;
	}

	if (spi_cfg->operation & SPI_OP_MODE_SLAVE) {
		LOG_ERR("Slave mode not supported");
		return -ENOTSUP;
	}

	if (spi_cfg->operation & SPI_MODE_LOOP) {
		LOG_ERR("Loopback mode is not supported");
		return -ENOTSUP;
	}

	hal_dev->cs_pin_id = ctx->config->slave;
	int ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);

	/* input parameters to calculate timing configuration */
	spi_hal_timing_param_t timing_param = {
		.half_duplex = hal_dev->half_duplex,
		.no_compensate = hal_dev->no_compensate,
		.clock_speed_hz = spi_cfg->frequency,
		.duty_cycle = cfg->duty_cycle == 0 ? 128 : cfg->duty_cycle,
		.input_delay_ns = cfg->input_delay_ns,
		.use_gpio = !cfg->use_iomux,

	};

	spi_hal_cal_clock_conf(&timing_param, &freq, &hal_dev->timing_conf);

	data->trans_config.dummy_bits = hal_dev->timing_conf.timing_dummy;

	hal_dev->tx_lsbfirst = spi_cfg->operation & SPI_TRANSFER_LSB ? 1 : 0;
	hal_dev->rx_lsbfirst = spi_cfg->operation & SPI_TRANSFER_LSB ? 1 : 0;

	data->trans_config.line_mode.data_lines = spi_esp32_get_line_mode(spi_cfg->operation);

	/* multiline for command and address not supported */
	data->trans_config.line_mode.addr_lines = 1;
	data->trans_config.line_mode.cmd_lines = 1;

	/* keep cs line after transmission not supported */
	data->trans_config.cs_keep_active = 0;

	/* SPI mode */
	hal_dev->mode = 0;
	if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL) {
		hal_dev->mode = BIT(0);
	}

	if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPHA) {
		hal_dev->mode |= BIT(1);
	}

	spi_hal_setup_device(hal, hal_dev);

	return 0;
}

static inline uint8_t spi_esp32_get_frame_size(const struct spi_config *spi_cfg)
{
	uint8_t dfs = SPI_WORD_SIZE_GET(spi_cfg->operation);

	dfs /= 8;

	if ((dfs == 0) || (dfs > 4)) {
		LOG_WRN("Unsupported dfs, 1-byte size will be used");
		dfs = 1;
	}

	return dfs;
}

static int transceive(const struct device *dev,
		      const struct spi_config *spi_cfg,
		      const struct spi_buf_set *tx_bufs,
		      const struct spi_buf_set *rx_bufs, bool asynchronous,
		      spi_callback_t cb,
		      void *userdata)
{
	const struct spi_esp32_config *cfg = dev->config;
	struct spi_esp32_data *data = dev->data;
	int ret;

	if (!tx_bufs && !rx_bufs) {
		return 0;
	}

#ifndef CONFIG_SPI_ESP32_INTERRUPT
	if (asynchronous) {
		return -ENOTSUP;
	}
#endif

	spi_context_lock(&data->ctx, asynchronous, cb, userdata, spi_cfg);

	ret = spi_esp32_configure(dev, spi_cfg);
	if (ret) {
		goto done;
	}

	data->dfs = spi_esp32_get_frame_size(spi_cfg);

	spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, data->dfs);

	spi_context_cs_control(&data->ctx, true);

#ifdef CONFIG_SPI_ESP32_INTERRUPT
	spi_ll_enable_int(cfg->spi);
	spi_ll_set_int_stat(cfg->spi);
#else

	do {
		spi_esp32_transfer(dev);
	} while (spi_esp32_transfer_ongoing(data));

	spi_esp32_complete(dev, data, cfg->spi, 0);

#endif  /* CONFIG_SPI_ESP32_INTERRUPT */

done:
	spi_context_release(&data->ctx, ret);

	return ret;
}

static int spi_esp32_transceive(const struct device *dev,
				const struct spi_config *spi_cfg,
				const struct spi_buf_set *tx_bufs,
				const struct spi_buf_set *rx_bufs)
{
	return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL);
}

#ifdef CONFIG_SPI_ASYNC
static int spi_esp32_transceive_async(const struct device *dev,
				      const struct spi_config *spi_cfg,
				      const struct spi_buf_set *tx_bufs,
				      const struct spi_buf_set *rx_bufs,
				      spi_callback_t cb,
				      void *userdata)
{
	return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, cb, userdata);
}
#endif /* CONFIG_SPI_ASYNC */

static int spi_esp32_release(const struct device *dev,
			     const struct spi_config *config)
{
	struct spi_esp32_data *data = dev->data;

	spi_context_unlock_unconditionally(&data->ctx);

	return 0;
}

static const struct spi_driver_api spi_api = {
	.transceive = spi_esp32_transceive,
#ifdef CONFIG_SPI_ASYNC
	.transceive_async = spi_esp32_transceive_async,
#endif
	.release = spi_esp32_release
};

#ifdef CONFIG_SOC_ESP32
#define GET_AS_CS(idx) .as_cs = DT_INST_PROP(idx, clk_as_cs),
#else
#define GET_AS_CS(idx)
#endif

#define ESP32_SPI_INIT(idx)	\
				\
	PINCTRL_DT_INST_DEFINE(idx);	\
										\
	static struct spi_esp32_data spi_data_##idx = {	\
		SPI_CONTEXT_INIT_LOCK(spi_data_##idx, ctx),	\
		SPI_CONTEXT_INIT_SYNC(spi_data_##idx, ctx),	\
		SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(idx), ctx)	\
		.hal = {	\
			.hw = (spi_dev_t *)DT_INST_REG_ADDR(idx),	\
		},	\
		.dev_config = {	\
			.half_duplex = DT_INST_PROP(idx, half_duplex),	\
			GET_AS_CS(idx)							\
			.positive_cs = DT_INST_PROP(idx, positive_cs),	\
			.no_compensate = DT_INST_PROP(idx, dummy_comp),	\
			.sio = DT_INST_PROP(idx, sio)	\
		}	\
	};	\
		\
	static const struct spi_esp32_config spi_config_##idx = {	\
		.spi = (spi_dev_t *)DT_INST_REG_ADDR(idx),	\
			\
		.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)),	\
		.duty_cycle = 0, \
		.input_delay_ns = 0, \
		.irq_source = DT_INST_IRQN(idx), \
		.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx),	\
		.clock_subsys =	\
			(clock_control_subsys_t)DT_INST_CLOCKS_CELL(idx, offset),	\
		.use_iomux = DT_INST_PROP(idx, use_iomux),	\
		.dma_enabled = DT_INST_PROP(idx, dma_enabled),	\
		.dma_clk_src = DT_INST_PROP(idx, dma_clk),	\
		.dma_host = DT_INST_PROP(idx, dma_host),	\
	};	\
		\
	DEVICE_DT_INST_DEFINE(idx, &spi_esp32_init,	\
			      NULL, &spi_data_##idx,	\
			      &spi_config_##idx, POST_KERNEL,	\
			      CONFIG_SPI_INIT_PRIORITY, &spi_api);

DT_INST_FOREACH_STATUS_OKAY(ESP32_SPI_INIT)
