/*
 * SPDX-License-Identifier: Apache-2.0
 *
 * Copyright (c) 2023 Nuvoton Technology Corporation.
 */

#define DT_DRV_COMPAT nuvoton_numaker_spi

#include <errno.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/reset.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/clock_control/clock_control_numaker.h>
#include <zephyr/drivers/pinctrl.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(spi_numaker, CONFIG_SPI_LOG_LEVEL);

#include "spi_context.h"
#include <NuMicro.h>

#define SPI_NUMAKER_TX_NOP 0x00

struct spi_numaker_config {
	SPI_T *spi;
	bool is_qspi;
	const struct reset_dt_spec reset;
	/* clock configuration */
	uint32_t clk_modidx;
	uint32_t clk_src;
	uint32_t clk_div;
	const struct device *clk_dev;
	const struct pinctrl_dev_config *pincfg;
};

struct spi_numaker_data {
	struct spi_context ctx;
};

/*
 * CPOL/CPHA = 0/0 --> SPI_MODE_0
 * CPOL/CPHA = 0/1 --> SPI_MODE_1
 * CPOL/CPHA = 1/0 --> SPI_MODE_2
 * CPOL/CPHA = 1/1 --> SPI_MODE_3
 */
static const uint32_t smode_tbl[4] = {
	SPI_MODE_0, SPI_MODE_1, SPI_MODE_2, SPI_MODE_3
};

static const uint32_t qsmode_tbl[4] = {
	QSPI_MODE_0, QSPI_MODE_1, QSPI_MODE_2, QSPI_MODE_3
};

static int spi_numaker_configure(const struct device *dev, const struct spi_config *config)
{
	int mode;
	struct spi_numaker_data *data = dev->data;
	const struct spi_numaker_config *dev_cfg = dev->config;

	LOG_DBG("%s", __func__);
	if (spi_context_configured(&data->ctx, config)) {
		return 0;
	}

	if (SPI_MODE_GET(config->operation) & SPI_MODE_LOOP) {
		LOG_ERR("Loop back mode not support");
		return -ENOTSUP;
	}

	if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_SLAVE) {
		LOG_ERR("Slave mode not support");
		return -ENOTSUP;
	}

	/* Clear FIFO */
	SPI_ClearRxFIFO(dev_cfg->spi);
	SPI_ClearTxFIFO(dev_cfg->spi);

	if (SPI_MODE_GET(config->operation) & SPI_MODE_CPOL) {
		mode = (SPI_MODE_GET(config->operation) & SPI_MODE_CPHA) ? 3 : 2;
	} else {
		mode = (SPI_MODE_GET(config->operation) & SPI_MODE_CPHA) ? 1 : 0;
	}

	/* Make SPI module be ready to transfer */
	if (dev_cfg->is_qspi) {
		QSPI_Open((QSPI_T *)dev_cfg->spi,
			  (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_SLAVE) ? QSPI_SLAVE
										    : QSPI_MASTER,
			  qsmode_tbl[mode],
			  SPI_WORD_SIZE_GET(config->operation), config->frequency);
	} else {
		SPI_Open(dev_cfg->spi,
			 (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_SLAVE) ? SPI_SLAVE
										   : SPI_MASTER,
			 smode_tbl[mode],
			 SPI_WORD_SIZE_GET(config->operation), config->frequency);
	}

	/* Set Transfer LSB or MSB first */
	if ((config->operation) & SPI_TRANSFER_LSB) {
		SPI_SET_LSB_FIRST(dev_cfg->spi);
	} else {
		SPI_SET_MSB_FIRST(dev_cfg->spi);
	}

	/* full/half duplex */
	if (config->operation & SPI_HALF_DUPLEX) {
		/* half duplex, which results in 3-wire usage */
		SPI_ENABLE_3WIRE_MODE(dev_cfg->spi);
	} else {
		/* full duplex */
		SPI_DISABLE_3WIRE_MODE(dev_cfg->spi);
	}

	/* Active high CS logic */
	if (config->operation & SPI_CS_ACTIVE_HIGH) {
		SPI_SET_SS_HIGH(dev_cfg->spi);
	} else {
		SPI_SET_SS_LOW(dev_cfg->spi);
	}

	/* Enable the automatic hardware slave select function. Select the SS pin and configure as
	 * low-active.
	 */
	if (data->ctx.num_cs_gpios != 0) {
		SPI_EnableAutoSS(dev_cfg->spi, SPI_SS, SPI_SS_ACTIVE_LOW);
	} else {
		SPI_DisableAutoSS(dev_cfg->spi);
	}

	/* Be able to set TX/RX FIFO threshold, for ex: SPI_SetFIFO(dev_cfg->spi, 2, 2) */

	data->ctx.config = config;

	return 0;
}

static int spi_numaker_txrx(const struct device *dev)
{
	struct spi_numaker_data *data = dev->data;
	const struct spi_numaker_config *dev_cfg = dev->config;
	struct spi_context *ctx = &data->ctx;
	uint32_t tx_frame, rx_frame;
	uint8_t word_size, spi_dfs;
	uint32_t time_out_cnt;

	LOG_DBG("%s", __func__);
	word_size = SPI_WORD_SIZE_GET(ctx->config->operation);

	switch (word_size) {
	case 8:
		spi_dfs = 1;
		break;
	case 16:
		spi_dfs = 2;
		break;
	case 24:
		spi_dfs = 3;
		break;
	case 32:
		spi_dfs = 4;
		break;
	default:
		spi_dfs = 0;
		LOG_ERR("Not support SPI WORD size as [%d] bits", word_size);
		return -EIO;
	}

	LOG_DBG("%s -->word_size [%d]", __func__, word_size);

	if (spi_context_tx_on(ctx)) {
		tx_frame = ((ctx->tx_buf == NULL) ? SPI_NUMAKER_TX_NOP
						  : UNALIGNED_GET((uint8_t *)(data->ctx.tx_buf)));
		/* Write to TX register */
		SPI_WRITE_TX(dev_cfg->spi, tx_frame);
		spi_context_update_tx(ctx, spi_dfs, 1);

		/* Check SPI busy status */
		time_out_cnt = SystemCoreClock; /* 1 second time-out */
		while (SPI_IS_BUSY(dev_cfg->spi)) {
			if (--time_out_cnt == 0) {
				LOG_ERR("Wait for SPI time-out");
				return -EIO;
			}
		}

		LOG_DBG("%s --> TX [0x%x] done", __func__, tx_frame);
	}

	/* Read received data */
	if (spi_context_rx_on(ctx)) {
		if (SPI_GET_RX_FIFO_COUNT(dev_cfg->spi) > 0) {
			rx_frame = SPI_READ_RX(dev_cfg->spi);
			if (ctx->rx_buf != NULL) {
				UNALIGNED_PUT(rx_frame, (uint8_t *)data->ctx.rx_buf);
			}
			spi_context_update_rx(ctx, spi_dfs, 1);
			LOG_DBG("%s --> RX [0x%x] done", __func__, rx_frame);
		}
	}

	LOG_DBG("%s --> exit", __func__);
	return 0;
}

/* Remain TX/RX Data in spi_context TX/RX buffer */
static bool spi_numaker_remain_words(struct spi_numaker_data *data)
{
	return spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx);
}

static int spi_numaker_transceive(const struct device *dev, const struct spi_config *config,
				  const struct spi_buf_set *tx_bufs,
				  const struct spi_buf_set *rx_bufs)
{
	struct spi_numaker_data *data = dev->data;
	struct spi_context *ctx = &data->ctx;
	const struct spi_numaker_config *dev_cfg = dev->config;
	int ret;

	LOG_DBG("%s", __func__);
	spi_context_lock(ctx, false, NULL, NULL, config);
	ctx->config = config;

	ret = spi_numaker_configure(dev, config);
	if (ret < 0) {
		goto done;
	}

	SPI_ENABLE(dev_cfg->spi);

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

	/* if cs is defined: software cs control, set active true */
	if (spi_cs_is_gpio(config)) {
		spi_context_cs_control(&data->ctx, true);
	}

	/* transceive tx/rx data */
	do {
		ret = spi_numaker_txrx(dev);
		if (ret < 0) {
			break;
		}
	} while (spi_numaker_remain_words(data));

	/* if cs is defined: software cs control, set active false */
	if (spi_cs_is_gpio(config)) {
		spi_context_cs_control(&data->ctx, false);
	}
	SPI_DISABLE(dev_cfg->spi);

done:
	spi_context_release(ctx, ret);
	LOG_DBG("%s --> [%d]", __func__, ret);
	return ret;
}

static int spi_numaker_release(const struct device *dev, const struct spi_config *config)
{
	struct spi_numaker_data *data = dev->data;
	struct spi_context *ctx = &data->ctx;

	if (!spi_context_configured(ctx, config)) {
		return -EINVAL;
	}
	spi_context_unlock_unconditionally(ctx);

	return 0;
}

static const struct spi_driver_api spi_numaker_driver_api = {
	.transceive = spi_numaker_transceive,
	.release = spi_numaker_release
};

static int spi_numaker_init(const struct device *dev)
{
	struct spi_numaker_data *data = dev->data;
	const struct spi_numaker_config *dev_cfg = dev->config;
	int err = 0;
	struct numaker_scc_subsys scc_subsys;

	SYS_UnlockReg();

	/* CLK controller */
	memset(&scc_subsys, 0x00, sizeof(scc_subsys));
	scc_subsys.subsys_id = NUMAKER_SCC_SUBSYS_ID_PCC;
	scc_subsys.pcc.clk_modidx = dev_cfg->clk_modidx;
	scc_subsys.pcc.clk_src = dev_cfg->clk_src;
	scc_subsys.pcc.clk_div = dev_cfg->clk_div;

	/* Equivalent to CLK_EnableModuleClock() */
	err = clock_control_on(dev_cfg->clk_dev, (clock_control_subsys_t)&scc_subsys);
	if (err != 0) {
		goto done;
	}
	/* Equivalent to CLK_SetModuleClock() */
	err = clock_control_configure(dev_cfg->clk_dev, (clock_control_subsys_t)&scc_subsys, NULL);
	if (err != 0) {
		goto done;
	}

	err = pinctrl_apply_state(dev_cfg->pincfg, PINCTRL_STATE_DEFAULT);
	if (err) {
		LOG_ERR("Failed to apply pinctrl state");
		goto done;
	}

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

	spi_context_unlock_unconditionally(&data->ctx);

	/* Reset this module, same as BSP's SYS_ResetModule(id_rst) */
	if (!device_is_ready(dev_cfg->reset.dev)) {
		LOG_ERR("reset controller not ready");
		err = -ENODEV;
		goto done;
	}

	/* Reset SPI to default state */
	reset_line_toggle_dt(&dev_cfg->reset);

done:
	SYS_LockReg();
	return err;
}

#define NUMAKER_SPI_INIT(inst)                                                                     \
	PINCTRL_DT_INST_DEFINE(inst);                                                              \
	static struct spi_numaker_data spi_numaker_data_##inst = {                                 \
		SPI_CONTEXT_INIT_LOCK(spi_numaker_data_##inst, ctx),                               \
		SPI_CONTEXT_INIT_SYNC(spi_numaker_data_##inst, ctx),                               \
		SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(inst), ctx)};                          \
	static struct spi_numaker_config spi_numaker_config_##inst = {                             \
		.spi = (SPI_T *)DT_INST_REG_ADDR(inst),                                            \
		.is_qspi = DT_INST_NODE_HAS_PROP(inst, qspi),                                      \
		.reset = RESET_DT_SPEC_INST_GET(inst),                                             \
		.clk_modidx = DT_INST_CLOCKS_CELL(inst, clock_module_index),                       \
		.clk_src = DT_INST_CLOCKS_CELL(inst, clock_source),                                \
		.clk_div = DT_INST_CLOCKS_CELL(inst, clock_divider),                               \
		.clk_dev = DEVICE_DT_GET(DT_PARENT(DT_INST_CLOCKS_CTLR(inst))),                    \
		.pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst),                                    \
	};                                                                                         \
	DEVICE_DT_INST_DEFINE(inst, &spi_numaker_init, NULL, &spi_numaker_data_##inst,             \
			      &spi_numaker_config_##inst, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY,   \
			      &spi_numaker_driver_api);

DT_INST_FOREACH_STATUS_OKAY(NUMAKER_SPI_INIT)
