/*
 * Copyright (c) 2023 Stephen Boylan <stephen.boylan@beechwoods.com>
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT raspberrypi_pico_spi_pio

#define LOG_LEVEL CONFIG_SPI_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(spi_pico_pio);

#include <zephyr/sys/util.h>
#include <zephyr/sys/sys_io.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/drivers/pinctrl.h>
#include "spi_context.h"

#include <zephyr/drivers/misc/pio_rpi_pico/pio_rpi_pico.h>

#include <hardware/pio.h>
#include "hardware/clocks.h"

#define PIO_CYCLES     (4)
#define PIO_FIFO_DEPTH (4)

struct spi_pico_pio_config {
	const struct device *piodev;
	const struct pinctrl_dev_config *pin_cfg;
	struct gpio_dt_spec clk_gpio;
	struct gpio_dt_spec mosi_gpio;
	struct gpio_dt_spec miso_gpio;
	const struct device *clk_dev;
	clock_control_subsys_t clk_id;
};

struct spi_pico_pio_data {
	struct spi_context spi_ctx;
	uint32_t tx_count;
	uint32_t rx_count;
	PIO pio;
	size_t pio_sm;
	uint32_t dfs;
};

RPI_PICO_PIO_DEFINE_PROGRAM(spi_cpol_0_cpha_0, 0, 1,
		/*     .wrap_target */
	0x6101, /*  0: out    pins, 1         side 0 [1] */
	0x5101, /*  1: in     pins, 1         side 1 [1] */
		/*     .wrap */
);

RPI_PICO_PIO_DEFINE_PROGRAM(spi_cpol_1_cpha_1, 0, 2,
		/*     .wrap_target */
	0x7021, /*  0: out    x, 1            side 1 */
	0xa101, /*  1: mov    pins, x         side 0 [1] */
	0x5001, /*  2: in     pins, 1         side 1 */
		/*     .wrap */
);

static float spi_pico_pio_clock_divisor(const uint32_t clock_freq, uint32_t spi_frequency)
{
	return (float)clock_freq / (float)(PIO_CYCLES * spi_frequency);
}

static uint32_t spi_pico_pio_maximum_clock_frequency(const uint32_t clock_freq)
{
	return clock_freq / PIO_CYCLES;
}

static uint32_t spi_pico_pio_minimum_clock_frequency(const uint32_t clock_freq)
{
	return clock_freq / (PIO_CYCLES * 65536);
}

static inline bool spi_pico_pio_transfer_ongoing(struct spi_pico_pio_data *data)
{
	return spi_context_tx_on(&data->spi_ctx) || spi_context_rx_on(&data->spi_ctx);
}

static inline void spi_pico_pio_sm_put8(PIO pio, uint sm, uint8_t data)
{
	/* Do 8 bit accesses on FIFO, so that write data is byte-replicated. This */
	/* gets us the left-justification for free (for MSB-first shift-out) */
	io_rw_8 *txfifo = (io_rw_8 *)&pio->txf[sm];

	*txfifo = data;
}

static inline uint8_t spi_pico_pio_sm_get8(PIO pio, uint sm)
{
	/* Do 8 bit accesses on FIFO, so that write data is byte-replicated. This */
	/* gets us the left-justification for free (for MSB-first shift-out) */
	io_rw_8 *rxfifo = (io_rw_8 *)&pio->rxf[sm];

	return *rxfifo;
}

static int spi_pico_pio_configure(const struct spi_pico_pio_config *dev_cfg,
				  struct spi_pico_pio_data *data, const struct spi_config *spi_cfg)
{
	const struct gpio_dt_spec *miso;
	const struct gpio_dt_spec *mosi;
	const struct gpio_dt_spec *clk;
	pio_sm_config sm_config;
	uint32_t offset;
	uint32_t wrap_target;
	uint32_t wrap;
	uint32_t cpol = 0;
	uint32_t cpha = 0;
	uint32_t bits;
	uint32_t clock_freq;
	float clock_div;
	const pio_program_t *program;
	int rc;

	rc = clock_control_on(dev_cfg->clk_dev, dev_cfg->clk_id);
	if (rc < 0) {
		LOG_ERR("Failed to enable the clock");
		return rc;
	}

	rc = clock_control_get_rate(dev_cfg->clk_dev, dev_cfg->clk_id, &clock_freq);
	if (rc < 0) {
		LOG_ERR("Failed to get clock frequency");
		return rc;
	}

	if (spi_context_configured(&data->spi_ctx, spi_cfg)) {
		return 0;
	}

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

	if (spi_cfg->operation & SPI_TRANSFER_LSB) {
		LOG_ERR("Unsupported configuration");
		return -ENOTSUP;
	}

#if defined(CONFIG_SPI_EXTENDED_MODES)
	if (spi_cfg->operation & (SPI_LINES_DUAL | SPI_LINES_QUAD | SPI_LINES_OCTAL)) {
		LOG_ERR("Unsupported configuration");
		return -ENOTSUP;
	}
#endif /* CONFIG_SPI_EXTENDED_MODES */

	bits = SPI_WORD_SIZE_GET(spi_cfg->operation);

	if (bits != 8) {
		LOG_ERR("Only 8 bit word size is supported");
		return -ENOTSUP;
	}

	data->dfs = DIV_ROUND_UP(bits, 8);

	if ((spi_cfg->frequency < spi_pico_pio_minimum_clock_frequency(clock_freq)) ||
	    (spi_cfg->frequency > spi_pico_pio_maximum_clock_frequency(clock_freq))) {
		LOG_ERR("clock-frequency out of range");
		return -EINVAL;
	}

	clock_div = spi_pico_pio_clock_divisor(clock_freq, spi_cfg->frequency);

	/* Half-duplex mode has not been implemented */
	if (spi_cfg->operation & SPI_HALF_DUPLEX) {
		LOG_ERR("Half-duplex not supported");
		return -ENOTSUP;
	}

	if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPOL) {
		cpol = 1;
	}
	if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_CPHA) {
		cpha = 1;
	}
	if (SPI_MODE_GET(spi_cfg->operation) & SPI_MODE_LOOP) {
		LOG_ERR("Loopback not supported");
		return -ENOTSUP;
	}

	mosi = &dev_cfg->mosi_gpio;
	miso = &dev_cfg->miso_gpio;
	clk = &dev_cfg->clk_gpio;
	data->pio = pio_rpi_pico_get_pio(dev_cfg->piodev);
	rc = pio_rpi_pico_allocate_sm(dev_cfg->piodev, &data->pio_sm);
	if (rc < 0) {
		return rc;
	}

	if ((cpol == 0) && (cpha == 0)) {
		program = RPI_PICO_PIO_GET_PROGRAM(spi_cpol_0_cpha_0);
		wrap_target = RPI_PICO_PIO_GET_WRAP_TARGET(spi_cpol_0_cpha_0);
		wrap = RPI_PICO_PIO_GET_WRAP(spi_cpol_0_cpha_0);
	} else if ((cpol == 1) && (cpha == 1)) {
		program = RPI_PICO_PIO_GET_PROGRAM(spi_cpol_1_cpha_1);
		wrap_target = RPI_PICO_PIO_GET_WRAP_TARGET(spi_cpol_1_cpha_1);
		wrap = RPI_PICO_PIO_GET_WRAP(spi_cpol_1_cpha_1);
	} else {
		LOG_ERR("Not supported:  cpol=%d, cpha=%d\n", cpol, cpha);
		return -ENOTSUP;
	}

	if (!pio_can_add_program(data->pio, program)) {
		return -EBUSY;
	}

	offset = pio_add_program(data->pio, program);
	sm_config = pio_get_default_sm_config();

	sm_config_set_clkdiv(&sm_config, clock_div);
	sm_config_set_in_pins(&sm_config, miso->pin);
	sm_config_set_in_shift(&sm_config, false, true, bits);
	sm_config_set_out_pins(&sm_config, mosi->pin, 1);
	sm_config_set_out_shift(&sm_config, false, true, bits);
	sm_config_set_sideset_pins(&sm_config, clk->pin);
	sm_config_set_sideset(&sm_config, 1, false, false);
	sm_config_set_wrap(&sm_config, offset + wrap_target, offset + wrap);

	pio_sm_set_consecutive_pindirs(data->pio, data->pio_sm, miso->pin, 1, false);
	pio_sm_set_pindirs_with_mask(data->pio, data->pio_sm, (BIT(clk->pin) | BIT(mosi->pin)),
				     (BIT(clk->pin) | BIT(mosi->pin)));
	pio_sm_set_pins_with_mask(data->pio, data->pio_sm, (cpol << clk->pin),
				  BIT(clk->pin) | BIT(mosi->pin));
	pio_gpio_init(data->pio, mosi->pin);
	pio_gpio_init(data->pio, miso->pin);
	pio_gpio_init(data->pio, clk->pin);

	pio_sm_init(data->pio, data->pio_sm, offset, &sm_config);
	pio_sm_set_enabled(data->pio, data->pio_sm, true);

	data->spi_ctx.config = spi_cfg;

	return 0;
}

static void spi_pico_pio_txrx(const struct device *dev)
{
	struct spi_pico_pio_data *data = dev->data;
	const size_t chunk_len = spi_context_max_continuous_chunk(&data->spi_ctx);
	const void *txbuf = data->spi_ctx.tx_buf;
	void *rxbuf = data->spi_ctx.rx_buf;
	uint32_t txrx;
	size_t fifo_cnt = 0;

	data->tx_count = 0;
	data->rx_count = 0;

	pio_sm_clear_fifos(data->pio, data->pio_sm);

	while (data->rx_count < chunk_len || data->tx_count < chunk_len) {
		/* Fill up fifo with available TX data */
		while ((!pio_sm_is_tx_fifo_full(data->pio, data->pio_sm)) &&
		       data->tx_count < chunk_len && fifo_cnt < PIO_FIFO_DEPTH) {
			/* Send 0 in the case of read only operation */
			txrx = 0;

			if (txbuf) {
				txrx = ((uint8_t *)txbuf)[data->tx_count];
			}
			spi_pico_pio_sm_put8(data->pio, data->pio_sm, txrx);
			data->tx_count++;
			fifo_cnt++;
		}

		while ((!pio_sm_is_rx_fifo_empty(data->pio, data->pio_sm)) &&
		       data->rx_count < chunk_len && fifo_cnt > 0) {
			txrx = spi_pico_pio_sm_get8(data->pio, data->pio_sm);

			/* Discard received data if rx buffer not assigned */
			if (rxbuf) {
				((uint8_t *)rxbuf)[data->rx_count] = (uint8_t)txrx;
			}
			data->rx_count++;
			fifo_cnt--;
		}
	}
}

static int spi_pico_pio_transceive_impl(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_pico_pio_config *dev_cfg = dev->config;
	struct spi_pico_pio_data *data = dev->data;
	struct spi_context *spi_ctx = &data->spi_ctx;
	int rc = 0;

	spi_context_lock(spi_ctx, asynchronous, cb, userdata, spi_cfg);

	rc = spi_pico_pio_configure(dev_cfg, data, spi_cfg);
	if (rc < 0) {
		goto error;
	}

	spi_context_buffers_setup(spi_ctx, tx_bufs, rx_bufs, data->dfs);
	spi_context_cs_control(spi_ctx, true);

	do {
		spi_pico_pio_txrx(dev);
		spi_context_update_tx(spi_ctx, 1, data->tx_count);
		spi_context_update_rx(spi_ctx, 1, data->rx_count);
	} while (spi_pico_pio_transfer_ongoing(data));

	spi_context_cs_control(spi_ctx, false);

error:
	spi_context_release(spi_ctx, rc);

	return rc;
}

static int spi_pico_pio_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 spi_pico_pio_transceive_impl(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL);
}

int spi_pico_pio_release(const struct device *dev, const struct spi_config *spi_cfg)
{
	struct spi_pico_pio_data *data = dev->data;

	spi_context_unlock_unconditionally(&data->spi_ctx);

	return 0;
}

static const struct spi_driver_api spi_pico_pio_api = {
	.transceive = spi_pico_pio_transceive,
	.release = spi_pico_pio_release,
};

int spi_pico_pio_init(const struct device *dev)
{
	const struct spi_pico_pio_config *dev_cfg = dev->config;
	struct spi_pico_pio_data *data = dev->data;
	int rc;

	rc = pinctrl_apply_state(dev_cfg->pin_cfg, PINCTRL_STATE_DEFAULT);
	if (rc) {
		LOG_ERR("Failed to apply pinctrl state");
		return rc;
	}

	rc = spi_context_cs_configure_all(&data->spi_ctx);
	if (rc < 0) {
		LOG_ERR("Failed to configure CS pins: %d", rc);
		return rc;
	}

	spi_context_unlock_unconditionally(&data->spi_ctx);

	return 0;
}

#define SPI_PICO_PIO_INIT(inst) \
	PINCTRL_DT_INST_DEFINE(inst); \
	static struct spi_pico_pio_config spi_pico_pio_config_##inst = { \
		.piodev = DEVICE_DT_GET(DT_INST_PARENT(inst)), \
		.pin_cfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \
		.clk_gpio = GPIO_DT_SPEC_INST_GET(inst, clk_gpios), \
		.mosi_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, mosi_gpios, {0}), \
		.miso_gpio = GPIO_DT_SPEC_INST_GET_OR(inst, miso_gpios, {0}), \
		.clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(inst)), \
		.clk_id = (clock_control_subsys_t)DT_INST_PHA_BY_IDX(inst, clocks, 0, clk_id), \
	}; \
	static struct spi_pico_pio_data spi_pico_pio_data_##inst = { \
		SPI_CONTEXT_INIT_LOCK(spi_pico_pio_data_##inst, spi_ctx), \
		SPI_CONTEXT_INIT_SYNC(spi_pico_pio_data_##inst, spi_ctx), \
		SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(inst), spi_ctx)}; \
	DEVICE_DT_INST_DEFINE(inst, spi_pico_pio_init, NULL, &spi_pico_pio_data_##inst, \
			      &spi_pico_pio_config_##inst, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \
			      &spi_pico_pio_api); \
	BUILD_ASSERT(DT_INST_NODE_HAS_PROP(inst, clk_gpios)); \
	BUILD_ASSERT(DT_INST_NODE_HAS_PROP(inst, mosi_gpios)); \
	BUILD_ASSERT(DT_INST_NODE_HAS_PROP(inst, miso_gpios));

DT_INST_FOREACH_STATUS_OKAY(SPI_PICO_PIO_INIT)
