/*
 * 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 <logging/log.h>
LOG_MODULE_REGISTER(spi_telink);

#include <drivers/spi.h>
#include "spi_context.h"
#include <drivers/pinmux.h>
#include <dt-bindings/pinctrl/b91-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 uint32_t *pinctrl_list;
	size_t pinctrl_list_size;
};
#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 complate */
	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)
{
	/* 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 hich */
	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 ((config->operation & SPI_LINES_MASK) == SPI_LINES_OCTAL) {
		LOG_ERR("SPI lines Octal configuration 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 configuration 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)
{
	const struct device *pinmux;
	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 ((config->operation & SPI_LINES_MASK) == SPI_LINES_SINGLE) {
		spi_set_io_mode(b91_config->peripheral_id, SPI_SINGLE_MODE);
	} else if ((config->operation & SPI_LINES_MASK) == SPI_LINES_DUAL) {
		spi_set_io_mode(b91_config->peripheral_id, SPI_DUAL_MODE);
	} else if ((config->operation & SPI_LINES_MASK) == SPI_LINES_QUAD) {
		spi_set_io_mode(b91_config->peripheral_id, HSPI_QUAD_MODE);
	}

	/* get pinmux driver */
	pinmux = DEVICE_DT_GET(DT_NODELABEL(pinmux));
	if (!device_is_ready(pinmux)) {
		return -ENODEV;
	}

	/* config pins */
	for (int i = 0; i < b91_config->pinctrl_list_size; i++) {
		pinmux_pin_set(pinmux, B91_PINMUX_GET_PIN(b91_config->pinctrl_list[i]),
			       B91_PINMUX_GET_FUNC(b91_config->pinctrl_list[i]));
	}

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

	/* config software CS control if enabled */
	if (config->cs != NULL) {
		spi_context_cs_configure(&b91_data->ctx);
	}

	return 0;
}

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

	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)							\
										\
	static const uint32_t spi_pins_##inst[] =				\
		B91_PINMUX_DT_INST_GET_ARRAY(inst, 0);				\
										\
	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),		\
	};									\
										\
	static struct spi_b91_cfg spi_b91_cfg_##inst = {			\
		.peripheral_id = DT_ENUM_IDX(DT_DRV_INST(inst), peripheral_id),	\
		.cs_pin[0] = DT_STRING_TOKEN(DT_DRV_INST(inst), cs0_pin),	\
		.cs_pin[1] = DT_STRING_TOKEN(DT_DRV_INST(inst), cs1_pin),	\
		.cs_pin[2] = DT_STRING_TOKEN(DT_DRV_INST(inst), cs2_pin),	\
		.pinctrl_list_size = ARRAY_SIZE(spi_pins_##inst),		\
		.pinctrl_list = spi_pins_##inst					\
	};									\
										\
	DEVICE_DT_INST_DEFINE(inst, spi_b91_init,				\
			      NULL,						\
			      &spi_b91_data_##inst,				\
			      &spi_b91_cfg_##inst,				\
			      POST_KERNEL,					\
			      CONFIG_KERNEL_INIT_PRIORITY_DEVICE,		\
			      &spi_b91_api);

DT_INST_FOREACH_STATUS_OKAY(SPI_B91_INIT)
