// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Polling/bitbanging SPI host controller controller driver utilities
 */

#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/time64.h>

#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>

#define SPI_BITBANG_CS_DELAY	100


/*----------------------------------------------------------------------*/

/*
 * FIRST PART (OPTIONAL):  word-at-a-time spi_transfer support.
 * Use this for GPIO or shift-register level hardware APIs.
 *
 * spi_bitbang_cs is in spi_device->controller_state, which is unavailable
 * to glue code.  These bitbang setup() and cleanup() routines are always
 * used, though maybe they're called from controller-aware code.
 *
 * chipselect() and friends may use spi_device->controller_data and
 * controller registers as appropriate.
 *
 *
 * NOTE:  SPI controller pins can often be used as GPIO pins instead,
 * which means you could use a bitbang driver either to get hardware
 * working quickly, or testing for differences that aren't speed related.
 */

typedef unsigned int (*spi_bb_txrx_bufs_fn)(struct spi_device *, spi_bb_txrx_word_fn,
					    unsigned int, struct spi_transfer *,
					    unsigned int);

struct spi_bitbang_cs {
	unsigned int nsecs;	/* (clock cycle time) / 2 */
	spi_bb_txrx_word_fn txrx_word;
	spi_bb_txrx_bufs_fn txrx_bufs;
};

static unsigned int bitbang_txrx_8(struct spi_device *spi,
	spi_bb_txrx_word_fn txrx_word,
	unsigned int ns,
	struct spi_transfer	*t,
	unsigned int flags)
{
	struct spi_bitbang	*bitbang;
	unsigned int		bits = t->bits_per_word;
	unsigned int		count = t->len;
	const u8		*tx = t->tx_buf;
	u8			*rx = t->rx_buf;

	bitbang = spi_controller_get_devdata(spi->controller);
	while (likely(count > 0)) {
		u8		word = 0;

		if (tx)
			word = *tx++;
		else
			word = spi->mode & SPI_MOSI_IDLE_HIGH ? 0xFF : 0;
		word = txrx_word(spi, ns, word, bits, flags);
		if (rx)
			*rx++ = word;
		count -= 1;
	}
	if (bitbang->set_mosi_idle)
		bitbang->set_mosi_idle(spi);

	return t->len - count;
}

static unsigned int bitbang_txrx_16(struct spi_device *spi,
	spi_bb_txrx_word_fn txrx_word,
	unsigned int ns,
	struct spi_transfer	*t,
	unsigned int flags)
{
	struct spi_bitbang	*bitbang;
	unsigned int		bits = t->bits_per_word;
	unsigned int		count = t->len;
	const u16		*tx = t->tx_buf;
	u16			*rx = t->rx_buf;

	bitbang = spi_controller_get_devdata(spi->controller);
	while (likely(count > 1)) {
		u16		word = 0;

		if (tx)
			word = *tx++;
		else
			word = spi->mode & SPI_MOSI_IDLE_HIGH ? 0xFFFF : 0;
		word = txrx_word(spi, ns, word, bits, flags);
		if (rx)
			*rx++ = word;
		count -= 2;
	}
	if (bitbang->set_mosi_idle)
		bitbang->set_mosi_idle(spi);

	return t->len - count;
}

static unsigned int bitbang_txrx_32(struct spi_device *spi,
	spi_bb_txrx_word_fn txrx_word,
	unsigned int ns,
	struct spi_transfer	*t,
	unsigned int flags)
{
	struct spi_bitbang	*bitbang;
	unsigned int		bits = t->bits_per_word;
	unsigned int		count = t->len;
	const u32		*tx = t->tx_buf;
	u32			*rx = t->rx_buf;

	bitbang = spi_controller_get_devdata(spi->controller);
	while (likely(count > 3)) {
		u32		word = 0;

		if (tx)
			word = *tx++;
		else
			word = spi->mode & SPI_MOSI_IDLE_HIGH ? 0xFFFFFFFF : 0;
		word = txrx_word(spi, ns, word, bits, flags);
		if (rx)
			*rx++ = word;
		count -= 4;
	}
	if (bitbang->set_mosi_idle)
		bitbang->set_mosi_idle(spi);

	return t->len - count;
}

int spi_bitbang_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
{
	struct spi_bitbang_cs	*cs = spi->controller_state;
	u8			bits_per_word;
	u32			hz;

	if (t) {
		bits_per_word = t->bits_per_word;
		hz = t->speed_hz;
	} else {
		bits_per_word = 0;
		hz = 0;
	}

	/* spi_transfer level calls that work per-word */
	if (!bits_per_word)
		bits_per_word = spi->bits_per_word;
	if (bits_per_word <= 8)
		cs->txrx_bufs = bitbang_txrx_8;
	else if (bits_per_word <= 16)
		cs->txrx_bufs = bitbang_txrx_16;
	else if (bits_per_word <= 32)
		cs->txrx_bufs = bitbang_txrx_32;
	else
		return -EINVAL;

	/* nsecs = (clock period)/2 */
	if (!hz)
		hz = spi->max_speed_hz;
	if (hz) {
		cs->nsecs = (NSEC_PER_SEC / 2) / hz;
		if (cs->nsecs > (MAX_UDELAY_MS * NSEC_PER_MSEC))
			return -EINVAL;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(spi_bitbang_setup_transfer);

/*
 * spi_bitbang_setup - default setup for per-word I/O loops
 */
int spi_bitbang_setup(struct spi_device *spi)
{
	struct spi_bitbang_cs	*cs = spi->controller_state;
	struct spi_bitbang	*bitbang;
	bool			initial_setup = false;
	int			retval;

	bitbang = spi_controller_get_devdata(spi->controller);

	if (!cs) {
		cs = kzalloc(sizeof(*cs), GFP_KERNEL);
		if (!cs)
			return -ENOMEM;
		spi->controller_state = cs;
		initial_setup = true;
	}

	/* per-word shift register access, in hardware or bitbanging */
	cs->txrx_word = bitbang->txrx_word[spi->mode & (SPI_CPOL|SPI_CPHA)];
	if (!cs->txrx_word) {
		retval = -EINVAL;
		goto err_free;
	}

	if (bitbang->setup_transfer) {
		retval = bitbang->setup_transfer(spi, NULL);
		if (retval < 0)
			goto err_free;
	}

	if (bitbang->set_mosi_idle)
		bitbang->set_mosi_idle(spi);

	dev_dbg(&spi->dev, "%s, %u nsec/bit\n", __func__, 2 * cs->nsecs);

	return 0;

err_free:
	if (initial_setup)
		kfree(cs);
	return retval;
}
EXPORT_SYMBOL_GPL(spi_bitbang_setup);

/*
 * spi_bitbang_cleanup - default cleanup for per-word I/O loops
 */
void spi_bitbang_cleanup(struct spi_device *spi)
{
	kfree(spi->controller_state);
}
EXPORT_SYMBOL_GPL(spi_bitbang_cleanup);

static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)
{
	struct spi_bitbang_cs	*cs = spi->controller_state;
	unsigned int		nsecs = cs->nsecs;
	struct spi_bitbang	*bitbang;

	bitbang = spi_controller_get_devdata(spi->controller);
	if (bitbang->set_line_direction) {
		int err;

		err = bitbang->set_line_direction(spi, !!(t->tx_buf));
		if (err < 0)
			return err;
	}

	if (spi->mode & SPI_3WIRE) {
		unsigned int flags;

		flags = t->tx_buf ? SPI_CONTROLLER_NO_RX : SPI_CONTROLLER_NO_TX;
		return cs->txrx_bufs(spi, cs->txrx_word, nsecs, t, flags);
	}
	return cs->txrx_bufs(spi, cs->txrx_word, nsecs, t, 0);
}

/*----------------------------------------------------------------------*/

/*
 * SECOND PART ... simple transfer queue runner.
 *
 * This costs a task context per controller, running the queue by
 * performing each transfer in sequence.  Smarter hardware can queue
 * several DMA transfers at once, and process several controller queues
 * in parallel; this driver doesn't match such hardware very well.
 *
 * Drivers can provide word-at-a-time i/o primitives, or provide
 * transfer-at-a-time ones to leverage dma or fifo hardware.
 */

static int spi_bitbang_prepare_hardware(struct spi_controller *spi)
{
	struct spi_bitbang	*bitbang;

	bitbang = spi_controller_get_devdata(spi);

	mutex_lock(&bitbang->lock);
	bitbang->busy = 1;
	mutex_unlock(&bitbang->lock);

	return 0;
}

static int spi_bitbang_transfer_one(struct spi_controller *ctlr,
				    struct spi_device *spi,
				    struct spi_transfer *transfer)
{
	struct spi_bitbang *bitbang = spi_controller_get_devdata(ctlr);
	int status = 0;

	if (bitbang->setup_transfer) {
		status = bitbang->setup_transfer(spi, transfer);
		if (status < 0)
			goto out;
	}

	if (transfer->len)
		status = bitbang->txrx_bufs(spi, transfer);

	if (status == transfer->len)
		status = 0;
	else if (status >= 0)
		status = -EREMOTEIO;

out:
	spi_finalize_current_transfer(ctlr);

	return status;
}

static int spi_bitbang_unprepare_hardware(struct spi_controller *spi)
{
	struct spi_bitbang	*bitbang;

	bitbang = spi_controller_get_devdata(spi);

	mutex_lock(&bitbang->lock);
	bitbang->busy = 0;
	mutex_unlock(&bitbang->lock);

	return 0;
}

static void spi_bitbang_set_cs(struct spi_device *spi, bool enable)
{
	struct spi_bitbang *bitbang = spi_controller_get_devdata(spi->controller);

	/* SPI core provides CS high / low, but bitbang driver
	 * expects CS active
	 * spi device driver takes care of handling SPI_CS_HIGH
	 */
	enable = (!!(spi->mode & SPI_CS_HIGH) == enable);

	ndelay(SPI_BITBANG_CS_DELAY);
	bitbang->chipselect(spi, enable ? BITBANG_CS_ACTIVE :
			    BITBANG_CS_INACTIVE);
	ndelay(SPI_BITBANG_CS_DELAY);
}

/*----------------------------------------------------------------------*/

int spi_bitbang_init(struct spi_bitbang *bitbang)
{
	struct spi_controller *ctlr = bitbang->ctlr;
	bool custom_cs;

	if (!ctlr)
		return -EINVAL;
	/*
	 * We only need the chipselect callback if we are actually using it.
	 * If we just use GPIO descriptors, it is surplus. If the
	 * SPI_CONTROLLER_GPIO_SS flag is set, we always need to call the
	 * driver-specific chipselect routine.
	 */
	custom_cs = (!ctlr->use_gpio_descriptors ||
		     (ctlr->flags & SPI_CONTROLLER_GPIO_SS));

	if (custom_cs && !bitbang->chipselect)
		return -EINVAL;

	mutex_init(&bitbang->lock);

	if (!ctlr->mode_bits)
		ctlr->mode_bits = SPI_CPOL | SPI_CPHA | bitbang->flags;

	if (ctlr->transfer || ctlr->transfer_one_message)
		return -EINVAL;

	ctlr->prepare_transfer_hardware = spi_bitbang_prepare_hardware;
	ctlr->unprepare_transfer_hardware = spi_bitbang_unprepare_hardware;
	ctlr->transfer_one = spi_bitbang_transfer_one;
	/*
	 * When using GPIO descriptors, the ->set_cs() callback doesn't even
	 * get called unless SPI_CONTROLLER_GPIO_SS is set.
	 */
	if (custom_cs)
		ctlr->set_cs = spi_bitbang_set_cs;

	if (!bitbang->txrx_bufs) {
		bitbang->use_dma = 0;
		bitbang->txrx_bufs = spi_bitbang_bufs;
		if (!ctlr->setup) {
			if (!bitbang->setup_transfer)
				bitbang->setup_transfer =
					 spi_bitbang_setup_transfer;
			ctlr->setup = spi_bitbang_setup;
			ctlr->cleanup = spi_bitbang_cleanup;
		}
	}

	return 0;
}
EXPORT_SYMBOL_GPL(spi_bitbang_init);

/**
 * spi_bitbang_start - start up a polled/bitbanging SPI host controller driver
 * @bitbang: driver handle
 *
 * Caller should have zero-initialized all parts of the structure, and then
 * provided callbacks for chip selection and I/O loops.  If the host controller has
 * a transfer method, its final step should call spi_bitbang_transfer(); or,
 * that's the default if the transfer routine is not initialized.  It should
 * also set up the bus number and number of chipselects.
 *
 * For i/o loops, provide callbacks either per-word (for bitbanging, or for
 * hardware that basically exposes a shift register) or per-spi_transfer
 * (which takes better advantage of hardware like fifos or DMA engines).
 *
 * Drivers using per-word I/O loops should use (or call) spi_bitbang_setup(),
 * spi_bitbang_cleanup() and spi_bitbang_setup_transfer() to handle those SPI
 * host controller methods.  Those methods are the defaults if the bitbang->txrx_bufs
 * routine isn't initialized.
 *
 * This routine registers the spi_controller, which will process requests in a
 * dedicated task, keeping IRQs unblocked most of the time.  To stop
 * processing those requests, call spi_bitbang_stop().
 *
 * On success, this routine will take a reference to the controller. The caller
 * is responsible for calling spi_bitbang_stop() to decrement the reference and
 * spi_controller_put() as counterpart of spi_alloc_host() to prevent a memory
 * leak.
 */
int spi_bitbang_start(struct spi_bitbang *bitbang)
{
	struct spi_controller *ctlr = bitbang->ctlr;
	int ret;

	ret = spi_bitbang_init(bitbang);
	if (ret)
		return ret;

	/* driver may get busy before register() returns, especially
	 * if someone registered boardinfo for devices
	 */
	ret = spi_register_controller(spi_controller_get(ctlr));
	if (ret)
		spi_controller_put(ctlr);

	return ret;
}
EXPORT_SYMBOL_GPL(spi_bitbang_start);

/*
 * spi_bitbang_stop - stops the task providing spi communication
 */
void spi_bitbang_stop(struct spi_bitbang *bitbang)
{
	spi_unregister_controller(bitbang->ctlr);
}
EXPORT_SYMBOL_GPL(spi_bitbang_stop);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Utilities for Bitbanging SPI host controllers");
