// SPDX-License-Identifier: GPL-2.0-only
/*
 * OpenCores tiny SPI host driver
 *
 * https://opencores.org/project,tiny_spi
 *
 * Copyright (C) 2011 Thomas Chou <thomas@wytron.com.tw>
 *
 * Based on spi_s3c24xx.c, which is:
 * Copyright (c) 2006 Ben Dooks
 * Copyright (c) 2006 Simtec Electronics
 *	Ben Dooks <ben@simtec.co.uk>
 */

#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/spi/spi_oc_tiny.h>
#include <linux/io.h>
#include <linux/of.h>

#define DRV_NAME "spi_oc_tiny"

#define TINY_SPI_RXDATA 0
#define TINY_SPI_TXDATA 4
#define TINY_SPI_STATUS 8
#define TINY_SPI_CONTROL 12
#define TINY_SPI_BAUD 16

#define TINY_SPI_STATUS_TXE 0x1
#define TINY_SPI_STATUS_TXR 0x2

struct tiny_spi {
	/* bitbang has to be first */
	struct spi_bitbang bitbang;
	struct completion done;

	void __iomem *base;
	int irq;
	unsigned int freq;
	unsigned int baudwidth;
	unsigned int baud;
	unsigned int speed_hz;
	unsigned int mode;
	unsigned int len;
	unsigned int txc, rxc;
	const u8 *txp;
	u8 *rxp;
};

static inline struct tiny_spi *tiny_spi_to_hw(struct spi_device *sdev)
{
	return spi_controller_get_devdata(sdev->controller);
}

static unsigned int tiny_spi_baud(struct spi_device *spi, unsigned int hz)
{
	struct tiny_spi *hw = tiny_spi_to_hw(spi);

	return min(DIV_ROUND_UP(hw->freq, hz * 2), (1U << hw->baudwidth)) - 1;
}

static int tiny_spi_setup_transfer(struct spi_device *spi,
				   struct spi_transfer *t)
{
	struct tiny_spi *hw = tiny_spi_to_hw(spi);
	unsigned int baud = hw->baud;

	if (t) {
		if (t->speed_hz && t->speed_hz != hw->speed_hz)
			baud = tiny_spi_baud(spi, t->speed_hz);
	}
	writel(baud, hw->base + TINY_SPI_BAUD);
	writel(hw->mode, hw->base + TINY_SPI_CONTROL);
	return 0;
}

static int tiny_spi_setup(struct spi_device *spi)
{
	struct tiny_spi *hw = tiny_spi_to_hw(spi);

	if (spi->max_speed_hz != hw->speed_hz) {
		hw->speed_hz = spi->max_speed_hz;
		hw->baud = tiny_spi_baud(spi, hw->speed_hz);
	}
	hw->mode = spi->mode & SPI_MODE_X_MASK;
	return 0;
}

static inline void tiny_spi_wait_txr(struct tiny_spi *hw)
{
	while (!(readb(hw->base + TINY_SPI_STATUS) &
		 TINY_SPI_STATUS_TXR))
		cpu_relax();
}

static inline void tiny_spi_wait_txe(struct tiny_spi *hw)
{
	while (!(readb(hw->base + TINY_SPI_STATUS) &
		 TINY_SPI_STATUS_TXE))
		cpu_relax();
}

static int tiny_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
{
	struct tiny_spi *hw = tiny_spi_to_hw(spi);
	const u8 *txp = t->tx_buf;
	u8 *rxp = t->rx_buf;
	unsigned int i;

	if (hw->irq >= 0) {
		/* use interrupt driven data transfer */
		hw->len = t->len;
		hw->txp = t->tx_buf;
		hw->rxp = t->rx_buf;
		hw->txc = 0;
		hw->rxc = 0;

		/* send the first byte */
		if (t->len > 1) {
			writeb(hw->txp ? *hw->txp++ : 0,
			       hw->base + TINY_SPI_TXDATA);
			hw->txc++;
			writeb(hw->txp ? *hw->txp++ : 0,
			       hw->base + TINY_SPI_TXDATA);
			hw->txc++;
			writeb(TINY_SPI_STATUS_TXR, hw->base + TINY_SPI_STATUS);
		} else {
			writeb(hw->txp ? *hw->txp++ : 0,
			       hw->base + TINY_SPI_TXDATA);
			hw->txc++;
			writeb(TINY_SPI_STATUS_TXE, hw->base + TINY_SPI_STATUS);
		}

		wait_for_completion(&hw->done);
	} else {
		/* we need to tighten the transfer loop */
		writeb(txp ? *txp++ : 0, hw->base + TINY_SPI_TXDATA);
		for (i = 1; i < t->len; i++) {
			writeb(txp ? *txp++ : 0, hw->base + TINY_SPI_TXDATA);

			if (rxp || (i != t->len - 1))
				tiny_spi_wait_txr(hw);
			if (rxp)
				*rxp++ = readb(hw->base + TINY_SPI_TXDATA);
		}
		tiny_spi_wait_txe(hw);
		if (rxp)
			*rxp++ = readb(hw->base + TINY_SPI_RXDATA);
	}

	return t->len;
}

static irqreturn_t tiny_spi_irq(int irq, void *dev)
{
	struct tiny_spi *hw = dev;

	writeb(0, hw->base + TINY_SPI_STATUS);
	if (hw->rxc + 1 == hw->len) {
		if (hw->rxp)
			*hw->rxp++ = readb(hw->base + TINY_SPI_RXDATA);
		hw->rxc++;
		complete(&hw->done);
	} else {
		if (hw->rxp)
			*hw->rxp++ = readb(hw->base + TINY_SPI_TXDATA);
		hw->rxc++;
		if (hw->txc < hw->len) {
			writeb(hw->txp ? *hw->txp++ : 0,
			       hw->base + TINY_SPI_TXDATA);
			hw->txc++;
			writeb(TINY_SPI_STATUS_TXR,
			       hw->base + TINY_SPI_STATUS);
		} else {
			writeb(TINY_SPI_STATUS_TXE,
			       hw->base + TINY_SPI_STATUS);
		}
	}
	return IRQ_HANDLED;
}

#ifdef CONFIG_OF
#include <linux/of_gpio.h>

static int tiny_spi_of_probe(struct platform_device *pdev)
{
	struct tiny_spi *hw = platform_get_drvdata(pdev);
	struct device_node *np = pdev->dev.of_node;
	u32 val;

	if (!np)
		return 0;
	hw->bitbang.ctlr->dev.of_node = pdev->dev.of_node;
	if (!of_property_read_u32(np, "clock-frequency", &val))
		hw->freq = val;
	if (!of_property_read_u32(np, "baud-width", &val))
		hw->baudwidth = val;
	return 0;
}
#else /* !CONFIG_OF */
static int tiny_spi_of_probe(struct platform_device *pdev)
{
	return 0;
}
#endif /* CONFIG_OF */

static int tiny_spi_probe(struct platform_device *pdev)
{
	struct tiny_spi_platform_data *platp = dev_get_platdata(&pdev->dev);
	struct tiny_spi *hw;
	struct spi_controller *host;
	int err = -ENODEV;

	host = spi_alloc_host(&pdev->dev, sizeof(struct tiny_spi));
	if (!host)
		return err;

	/* setup the host state. */
	host->bus_num = pdev->id;
	host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
	host->setup = tiny_spi_setup;
	host->use_gpio_descriptors = true;

	hw = spi_controller_get_devdata(host);
	platform_set_drvdata(pdev, hw);

	/* setup the state for the bitbang driver */
	hw->bitbang.ctlr = host;
	hw->bitbang.setup_transfer = tiny_spi_setup_transfer;
	hw->bitbang.txrx_bufs = tiny_spi_txrx_bufs;

	/* find and map our resources */
	hw->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(hw->base)) {
		err = PTR_ERR(hw->base);
		goto exit;
	}
	/* irq is optional */
	hw->irq = platform_get_irq(pdev, 0);
	if (hw->irq >= 0) {
		init_completion(&hw->done);
		err = devm_request_irq(&pdev->dev, hw->irq, tiny_spi_irq, 0,
				       pdev->name, hw);
		if (err)
			goto exit;
	}
	/* find platform data */
	if (platp) {
		hw->freq = platp->freq;
		hw->baudwidth = platp->baudwidth;
	} else {
		err = tiny_spi_of_probe(pdev);
		if (err)
			goto exit;
	}

	/* register our spi controller */
	err = spi_bitbang_start(&hw->bitbang);
	if (err)
		goto exit;
	dev_info(&pdev->dev, "base %p, irq %d\n", hw->base, hw->irq);

	return 0;

exit:
	spi_controller_put(host);
	return err;
}

static void tiny_spi_remove(struct platform_device *pdev)
{
	struct tiny_spi *hw = platform_get_drvdata(pdev);
	struct spi_controller *host = hw->bitbang.ctlr;

	spi_bitbang_stop(&hw->bitbang);
	spi_controller_put(host);
}

#ifdef CONFIG_OF
static const struct of_device_id tiny_spi_match[] = {
	{ .compatible = "opencores,tiny-spi-rtlsvn2", },
	{},
};
MODULE_DEVICE_TABLE(of, tiny_spi_match);
#endif /* CONFIG_OF */

static struct platform_driver tiny_spi_driver = {
	.probe = tiny_spi_probe,
	.remove_new = tiny_spi_remove,
	.driver = {
		.name = DRV_NAME,
		.pm = NULL,
		.of_match_table = of_match_ptr(tiny_spi_match),
	},
};
module_platform_driver(tiny_spi_driver);

MODULE_DESCRIPTION("OpenCores tiny SPI driver");
MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRV_NAME);
