/*
 * Copyright (c) 2021 Telink Semiconductor
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT telink_b91_spi

/*  Redefine 'spi_read' and 'spi_write' functions names from HAL */
#define spi_read    hal_spi_read
#define spi_write   hal_spi_write
#include "spi.c"
#undef spi_read
#undef spi_write

#include "clock.h"

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(spi_telink);

#include <zephyr/drivers/spi.h>
#include "spi_context.h"
#include <zephyr/drivers/pinctrl.h>


#define CHIP_SELECT_COUNT               3u
#define SPI_WORD_SIZE                   8u
#define SPI_WR_RD_CHUNK_SIZE_MAX        16u


/* SPI configuration structure */
struct spi_b91_cfg {
	uint8_t peripheral_id;
	gpio_pin_e cs_pin[CHIP_SELECT_COUNT];
	const struct pinctrl_dev_config *pcfg;
};
#define SPI_CFG(dev)                    ((struct spi_b91_cfg *) ((dev)->config))

/* SPI data structure */
struct spi_b91_data {
	struct spi_context ctx;
};
#define SPI_DATA(dev)                   ((struct spi_b91_data *) ((dev)->data))


/* disable hardware cs flow control */
static void spi_b91_hw_cs_disable(const struct spi_b91_cfg *config)
{
	gpio_pin_e pin;

	/* loop through all cs pins (cs0..cs2) */
	for (int i = 0; i < CHIP_SELECT_COUNT; i++) {
		/* get CS pin defined in device tree */
		pin = config->cs_pin[i];

		/* if CS pin is defined in device tree */
		if (pin != 0) {
			if (config->peripheral_id == PSPI_MODULE) {
				/* disable CS pin for PSPI */
				pspi_cs_pin_dis(pin);
			} else {
				/* disable CS pin for MSPI */
				hspi_cs_pin_dis(pin);
			}
		}
	}
}

/* config cs flow control: hardware or software */
static bool spi_b91_config_cs(const struct device *dev,
			      const struct spi_config *config)
{
	pspi_csn_pin_def_e cs_pin = 0;
	const struct spi_b91_cfg *b91_config = SPI_CFG(dev);

	/* software flow control */
	if (config->cs) {
		/* disable all hardware CS pins */
		spi_b91_hw_cs_disable(b91_config);
		return true;
	}

	/* hardware flow control */

	/* check for correct slave id */
	if (config->slave >= CHIP_SELECT_COUNT) {
		LOG_ERR("Slave %d not supported (max. %d)", config->slave, CHIP_SELECT_COUNT - 1);
		return false;
	}

	/* loop through all cs pins: cs0, cs1 and cs2 */
	for (int cs_id = 0; cs_id < CHIP_SELECT_COUNT; cs_id++) {
		/* get cs pin defined in device tree */
		cs_pin = b91_config->cs_pin[cs_id];

		/*  if cs pin is not defined for the selected slave, return error */
		if ((cs_pin == 0) && (cs_id == config->slave)) {
			LOG_ERR("cs%d-pin is not defined in device tree", config->slave);
			return false;
		}

		/* disable cs pin if it is defined and is not requested */
		if ((cs_pin != 0) && (cs_id != config->slave)) {
			if (b91_config->peripheral_id == PSPI_MODULE) {
				pspi_cs_pin_dis(cs_pin);
			} else {
				hspi_cs_pin_dis(cs_pin);
			}
		}

		/* enable cs pin if it is defined and is requested */
		if ((cs_pin != 0) && (cs_id == config->slave)) {
			if (b91_config->peripheral_id == PSPI_MODULE) {
				pspi_set_pin_mux(cs_pin);
				pspi_cs_pin_en(cs_pin);
			} else {
				hspi_set_pin_mux(cs_pin);
				hspi_cs_pin_en(cs_pin);
			}
		}
	}

	return true;
}

/* get spi transaction length */
static uint32_t spi_b91_get_txrx_len(const struct spi_buf_set *tx_bufs,
				     const struct spi_buf_set *rx_bufs)
{
	uint32_t len_tx = 0;
	uint32_t len_rx = 0;
	const struct spi_buf *tx_buf = tx_bufs->buffers;
	const struct spi_buf *rx_buf = rx_bufs->buffers;

	/* calculate tx len */
	for (int i = 0; i < tx_bufs->count; i++) {
		len_tx += tx_buf->len;
		tx_buf++;
	}

	/* calculate rx len */
	for (int i = 0; i < rx_bufs->count; i++) {
		len_rx += rx_buf->len;
		rx_buf++;
	}

	return MAX(len_tx, len_rx);
}

/* process tx data */
_attribute_ram_code_sec_
static void spi_b91_tx(uint8_t peripheral_id, struct spi_context *ctx, uint8_t len)
{
	uint8_t tx;

	for (int i = 0; i < len; i++) {
		if (spi_context_tx_buf_on(ctx)) {
			tx = *(uint8_t *)(ctx->tx_buf);
		} else {
			tx = 0;
		}
		spi_context_update_tx(ctx, 1, 1);
		while (reg_spi_fifo_state(peripheral_id) & FLD_SPI_TXF_FULL) {
		};
		reg_spi_wr_rd_data(peripheral_id, i % 4) = tx;
	}
}

/* process rx data */
_attribute_ram_code_sec_
static void spi_b91_rx(uint8_t peripheral_id, struct spi_context *ctx, uint8_t len)
{
	uint8_t rx = 0;

	for (int i = 0; i < len; i++) {
		while (reg_spi_fifo_state(peripheral_id) & FLD_SPI_RXF_EMPTY) {
		};
		rx = reg_spi_wr_rd_data(peripheral_id, i % 4);

		if (spi_context_rx_buf_on(ctx)) {
			*ctx->rx_buf = rx;
		}
		spi_context_update_rx(ctx, 1, 1);
	}
}

/* SPI transceive internal */
_attribute_ram_code_sec_
static void spi_b91_txrx(const struct device *dev, uint32_t len)
{
	unsigned int chunk_size = SPI_WR_RD_CHUNK_SIZE_MAX;
	struct spi_b91_cfg *cfg = SPI_CFG(dev);
	struct spi_context *ctx = &SPI_DATA(dev)->ctx;

	/* prepare SPI module */
	spi_set_transmode(cfg->peripheral_id, SPI_MODE_WRITE_AND_READ);
	spi_set_cmd(cfg->peripheral_id, 0);
	spi_tx_cnt(cfg->peripheral_id, len);
	spi_rx_cnt(cfg->peripheral_id, len);

	/* write and read bytes in chunks */
	for (int i = 0; i < len; i = i + chunk_size) {
		/* check for tail */
		if (chunk_size > (len - i)) {
			chunk_size = len - i;
		}

		/* write bytes */
		spi_b91_tx(cfg->peripheral_id, ctx, chunk_size);

		/* read bytes */
		if (len <= SPI_WR_RD_CHUNK_SIZE_MAX) {
			/* read all bytes if len is less than chunk size */
			spi_b91_rx(cfg->peripheral_id, ctx, chunk_size);
		} else if (i == 0) {
			/* head, read 1 byte less than is sent */
			spi_b91_rx(cfg->peripheral_id, ctx, chunk_size - 1);
		} else if ((len - i) > SPI_WR_RD_CHUNK_SIZE_MAX) {
			/* body, read so many bytes as is sent*/
			spi_b91_rx(cfg->peripheral_id, ctx, chunk_size);
		} else {
			/* tail, read the rest bytes */
			spi_b91_rx(cfg->peripheral_id, ctx, chunk_size + 1);
		}

		/* clear TX and RX fifo */
		BM_SET(reg_spi_fifo_state(cfg->peripheral_id), FLD_SPI_TXF_CLR);
		BM_SET(reg_spi_fifo_state(cfg->peripheral_id), FLD_SPI_RXF_CLR);
	}

	/* wait fot SPI is ready */
	while (spi_is_busy(cfg->peripheral_id)) {
	};

	/* context complete */
	spi_context_complete(ctx, 0);
}

/* Check for supported configuration */
static bool spi_b91_is_config_supported(const struct spi_config *config,
					struct spi_b91_cfg *b91_config)
{
	if (config->operation & SPI_HALF_DUPLEX) {
		LOG_ERR("Half-duplex not supported");
		return false;
	}

	/* check for loop back */
	if (config->operation & SPI_MODE_LOOP) {
		LOG_ERR("Loop back mode not supported");
		return false;
	}

	/* check for transfer LSB first */
	if (config->operation & SPI_TRANSFER_LSB) {
		LOG_ERR("LSB first not supported");
		return false;
	}

	/* check word size */
	if (SPI_WORD_SIZE_GET(config->operation) != SPI_WORD_SIZE) {
		LOG_ERR("Word size must be %d", SPI_WORD_SIZE);
		return false;
	}

	/* check for CS active high */
	if (config->operation & SPI_CS_ACTIVE_HIGH) {
		LOG_ERR("CS active high not supported for HW flow control");
		return false;
	}

	/* check for lines configuration */
	if (IS_ENABLED(CONFIG_SPI_EXTENDED_MODES)) {
		if ((config->operation & SPI_LINES_MASK) == SPI_LINES_OCTAL) {
			LOG_ERR("SPI lines Octal is not supported");
			return false;
		} else if (((config->operation & SPI_LINES_MASK) ==
			    SPI_LINES_QUAD) &&
			   (b91_config->peripheral_id == PSPI_MODULE)) {
			LOG_ERR("SPI lines Quad is not supported by PSPI");
			return false;
		}
	}

	/* check for slave configuration */
	if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_SLAVE) {
		LOG_ERR("SPI Slave is not implemented");
		return -ENOTSUP;
	}

	return true;
}

/* SPI configuration */
static int spi_b91_config(const struct device *dev,
			  const struct spi_config *config)
{
	int status = 0;
	spi_mode_type_e mode = SPI_MODE0;
	struct spi_b91_cfg *b91_config = SPI_CFG(dev);
	struct spi_b91_data *b91_data = SPI_DATA(dev);
	uint8_t clk_src = b91_config->peripheral_id == PSPI_MODULE ? sys_clk.pclk : sys_clk.hclk;

	/* check for unsupported configuration */
	if (!spi_b91_is_config_supported(config, b91_config)) {
		return -ENOTSUP;
	}

	/* config slave selection (CS): hw or sw */
	if (!spi_b91_config_cs(dev, config)) {
		return -ENOTSUP;
	}

	/* get SPI mode */
	if (((config->operation & SPI_MODE_CPHA) == 0) &&
	    ((config->operation & SPI_MODE_CPOL) == 0)) {
		mode = SPI_MODE0;
	} else if (((config->operation & SPI_MODE_CPHA) == 0) &&
		   ((config->operation & SPI_MODE_CPOL) == SPI_MODE_CPOL)) {
		mode = SPI_MODE1;
	} else if (((config->operation & SPI_MODE_CPHA) == SPI_MODE_CPHA) &&
		   ((config->operation & SPI_MODE_CPOL) == 0)) {
		mode = SPI_MODE2;
	} else if (((config->operation & SPI_MODE_CPHA) == SPI_MODE_CPHA) &&
		   ((config->operation & SPI_MODE_CPOL) == SPI_MODE_CPOL)) {
		mode = SPI_MODE3;
	}

	/* init SPI master */
	spi_master_init(b91_config->peripheral_id,
			clk_src * 1000000 / (2 * config->frequency) - 1, mode);
	spi_master_config(b91_config->peripheral_id, SPI_NOMAL);

	/* set lines configuration */
	if (IS_ENABLED(CONFIG_SPI_EXTENDED_MODES)) {
		uint32_t lines = config->operation & SPI_LINES_MASK;

		if (lines == SPI_LINES_SINGLE) {
			spi_set_io_mode(b91_config->peripheral_id,
					SPI_SINGLE_MODE);
		} else if (lines == SPI_LINES_DUAL) {
			spi_set_io_mode(b91_config->peripheral_id,
					SPI_DUAL_MODE);
		} else if (lines == SPI_LINES_QUAD) {
			spi_set_io_mode(b91_config->peripheral_id,
					HSPI_QUAD_MODE);
		}
	}

	/* configure pins */
	status = pinctrl_apply_state(b91_config->pcfg, PINCTRL_STATE_DEFAULT);
	if (status < 0) {
		LOG_ERR("Failed to configure SPI pins");
		return status;
	}

	/* save context config */
	b91_data->ctx.config = config;

	return 0;
}

/* API implementation: init */
static int spi_b91_init(const struct device *dev)
{
	int err;
	struct spi_b91_data *data = SPI_DATA(dev);

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

	spi_context_unlock_unconditionally(&data->ctx);

	return 0;
}

/* API implementation: transceive */
static int spi_b91_transceive(const struct device *dev,
			      const struct spi_config *config,
			      const struct spi_buf_set *tx_bufs,
			      const struct spi_buf_set *rx_bufs)
{
	int status = 0;
	struct spi_b91_data *data = SPI_DATA(dev);
	uint32_t txrx_len = spi_b91_get_txrx_len(tx_bufs, rx_bufs);

	/* set configuration */
	status = spi_b91_config(dev, config);
	if (status) {
		return status;
	}

	/* context setup */
	spi_context_lock(&data->ctx, false, NULL, config);
	spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1);

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

	/* transceive data */
	spi_b91_txrx(dev, txrx_len);

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

	/* release context */
	status = spi_context_wait_for_completion(&data->ctx);
	spi_context_release(&data->ctx, status);

	return status;
}

#ifdef CONFIG_SPI_ASYNC
/* API implementation: transceive_async */
static int spi_b91_transceive_async(const struct device *dev,
				    const struct spi_config *config,
				    const struct spi_buf_set *tx_bufs,
				    const struct spi_buf_set *rx_bufs,
				    struct k_poll_signal *async)
{
	ARG_UNUSED(dev);
	ARG_UNUSED(config);
	ARG_UNUSED(tx_bufs);
	ARG_UNUSED(rx_bufs);
	ARG_UNUSED(async);

	return -ENOTSUP;
}
#endif /* CONFIG_SPI_ASYNC */

/* API implementation: release */
static int spi_b91_release(const struct device *dev,
			   const struct spi_config *config)
{
	struct spi_b91_data *data = SPI_DATA(dev);

	if (!spi_context_configured(&data->ctx, config)) {
		return -EINVAL;
	}

	spi_context_unlock_unconditionally(&data->ctx);

	return 0;
}

/* SPI driver APIs structure */
static struct spi_driver_api spi_b91_api = {
	.transceive = spi_b91_transceive,
	.release = spi_b91_release,
#ifdef CONFIG_SPI_ASYNC
	.transceive_async = spi_b91_transceive_async,
#endif /* CONFIG_SPI_ASYNC */
};

/* SPI driver registration */
#define SPI_B91_INIT(inst)						  \
									  \
	PINCTRL_DT_INST_DEFINE(inst);					  \
									  \
	static struct spi_b91_data spi_b91_data_##inst = {		  \
		SPI_CONTEXT_INIT_LOCK(spi_b91_data_##inst, ctx),	  \
		SPI_CONTEXT_INIT_SYNC(spi_b91_data_##inst, ctx),	  \
		SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(inst), ctx)	  \
	};								  \
									  \
	static struct spi_b91_cfg spi_b91_cfg_##inst = {		  \
		.peripheral_id = DT_INST_ENUM_IDX(inst, peripheral_id),	  \
		.cs_pin[0] = DT_INST_STRING_TOKEN(inst, cs0_pin),	  \
		.cs_pin[1] = DT_INST_STRING_TOKEN(inst, cs1_pin),	  \
		.cs_pin[2] = DT_INST_STRING_TOKEN(inst, cs2_pin),	  \
		.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst),		  \
	};								  \
									  \
	DEVICE_DT_INST_DEFINE(inst, spi_b91_init,			  \
			      NULL,					  \
			      &spi_b91_data_##inst,			  \
			      &spi_b91_cfg_##inst,			  \
			      POST_KERNEL,				  \
			      CONFIG_SPI_INIT_PRIORITY,			  \
			      &spi_b91_api);

DT_INST_FOREACH_STATUS_OKAY(SPI_B91_INIT)
