/*
 * Broadcom BCM63xx SPI controller support
 *
 * Copyright (C) 2009-2012 Florian Fainelli <florian@openwrt.org>
 * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/spi/spi.h>
#include <linux/completion.h>
#include <linux/err.h>
#include <linux/workqueue.h>
#include <linux/pm_runtime.h>

#include <bcm63xx_dev_spi.h>

#define PFX		KBUILD_MODNAME

#define BCM63XX_SPI_MAX_PREPEND		15

struct bcm63xx_spi {
	struct completion	done;

	void __iomem		*regs;
	int			irq;

	/* Platform data */
	u32			speed_hz;
	unsigned		fifo_size;
	unsigned int		msg_type_shift;
	unsigned int		msg_ctl_width;

	/* data iomem */
	u8 __iomem		*tx_io;
	const u8 __iomem	*rx_io;

	struct clk		*clk;
	struct platform_device	*pdev;
};

static inline u8 bcm_spi_readb(struct bcm63xx_spi *bs,
				unsigned int offset)
{
	return bcm_readb(bs->regs + bcm63xx_spireg(offset));
}

static inline u16 bcm_spi_readw(struct bcm63xx_spi *bs,
				unsigned int offset)
{
	return bcm_readw(bs->regs + bcm63xx_spireg(offset));
}

static inline void bcm_spi_writeb(struct bcm63xx_spi *bs,
				  u8 value, unsigned int offset)
{
	bcm_writeb(value, bs->regs + bcm63xx_spireg(offset));
}

static inline void bcm_spi_writew(struct bcm63xx_spi *bs,
				  u16 value, unsigned int offset)
{
	bcm_writew(value, bs->regs + bcm63xx_spireg(offset));
}

static const unsigned bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = {
	{ 20000000, SPI_CLK_20MHZ },
	{ 12500000, SPI_CLK_12_50MHZ },
	{  6250000, SPI_CLK_6_250MHZ },
	{  3125000, SPI_CLK_3_125MHZ },
	{  1563000, SPI_CLK_1_563MHZ },
	{   781000, SPI_CLK_0_781MHZ },
	{   391000, SPI_CLK_0_391MHZ }
};

static int bcm63xx_spi_check_transfer(struct spi_device *spi,
					struct spi_transfer *t)
{
	u8 bits_per_word;

	bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word;
	if (bits_per_word != 8) {
		dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n",
			__func__, bits_per_word);
		return -EINVAL;
	}

	if (spi->chip_select > spi->master->num_chipselect) {
		dev_err(&spi->dev, "%s, unsupported slave %d\n",
			__func__, spi->chip_select);
		return -EINVAL;
	}

	return 0;
}

static void bcm63xx_spi_setup_transfer(struct spi_device *spi,
				      struct spi_transfer *t)
{
	struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
	u32 hz;
	u8 clk_cfg, reg;
	int i;

	hz = (t) ? t->speed_hz : spi->max_speed_hz;

	/* Find the closest clock configuration */
	for (i = 0; i < SPI_CLK_MASK; i++) {
		if (hz >= bcm63xx_spi_freq_table[i][0]) {
			clk_cfg = bcm63xx_spi_freq_table[i][1];
			break;
		}
	}

	/* No matching configuration found, default to lowest */
	if (i == SPI_CLK_MASK)
		clk_cfg = SPI_CLK_0_391MHZ;

	/* clear existing clock configuration bits of the register */
	reg = bcm_spi_readb(bs, SPI_CLK_CFG);
	reg &= ~SPI_CLK_MASK;
	reg |= clk_cfg;

	bcm_spi_writeb(bs, reg, SPI_CLK_CFG);
	dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n",
		clk_cfg, hz);
}

/* the spi->mode bits understood by this driver: */
#define MODEBITS (SPI_CPOL | SPI_CPHA)

static int bcm63xx_spi_setup(struct spi_device *spi)
{
	struct bcm63xx_spi *bs;
	int ret;

	bs = spi_master_get_devdata(spi->master);

	if (!spi->bits_per_word)
		spi->bits_per_word = 8;

	if (spi->mode & ~MODEBITS) {
		dev_err(&spi->dev, "%s, unsupported mode bits %x\n",
			__func__, spi->mode & ~MODEBITS);
		return -EINVAL;
	}

	dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec/bit\n",
		__func__, spi->mode & MODEBITS, spi->bits_per_word, 0);

	return 0;
}

static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
				unsigned int num_transfers)
{
	struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
	u16 msg_ctl;
	u16 cmd;
	u8 rx_tail;
	unsigned int i, timeout = 0, prepend_len = 0, len = 0;
	struct spi_transfer *t = first;
	bool do_rx = false;
	bool do_tx = false;

	/* Disable the CMD_DONE interrupt */
	bcm_spi_writeb(bs, 0, SPI_INT_MASK);

	dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
		t->tx_buf, t->rx_buf, t->len);

	if (num_transfers > 1 && t->tx_buf && t->len <= BCM63XX_SPI_MAX_PREPEND)
		prepend_len = t->len;

	/* prepare the buffer */
	for (i = 0; i < num_transfers; i++) {
		if (t->tx_buf) {
			do_tx = true;
			memcpy_toio(bs->tx_io + len, t->tx_buf, t->len);

			/* don't prepend more than one tx */
			if (t != first)
				prepend_len = 0;
		}

		if (t->rx_buf) {
			do_rx = true;
			/* prepend is half-duplex write only */
			if (t == first)
				prepend_len = 0;
		}

		len += t->len;

		t = list_entry(t->transfer_list.next, struct spi_transfer,
			       transfer_list);
	}

	len -= prepend_len;

	init_completion(&bs->done);

	/* Fill in the Message control register */
	msg_ctl = (len << SPI_BYTE_CNT_SHIFT);

	if (do_rx && do_tx && prepend_len == 0)
		msg_ctl |= (SPI_FD_RW << bs->msg_type_shift);
	else if (do_rx)
		msg_ctl |= (SPI_HD_R << bs->msg_type_shift);
	else if (do_tx)
		msg_ctl |= (SPI_HD_W << bs->msg_type_shift);

	switch (bs->msg_ctl_width) {
	case 8:
		bcm_spi_writeb(bs, msg_ctl, SPI_MSG_CTL);
		break;
	case 16:
		bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL);
		break;
	}

	/* Issue the transfer */
	cmd = SPI_CMD_START_IMMEDIATE;
	cmd |= (prepend_len << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
	cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT);
	bcm_spi_writew(bs, cmd, SPI_CMD);

	/* Enable the CMD_DONE interrupt */
	bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);

	timeout = wait_for_completion_timeout(&bs->done, HZ);
	if (!timeout)
		return -ETIMEDOUT;

	/* read out all data */
	rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);

	if (do_rx && rx_tail != len)
		return -EIO;

	if (!rx_tail)
		return 0;

	len = 0;
	t = first;
	/* Read out all the data */
	for (i = 0; i < num_transfers; i++) {
		if (t->rx_buf)
			memcpy_fromio(t->rx_buf, bs->rx_io + len, t->len);

		if (t != first || prepend_len == 0)
			len += t->len;

		t = list_entry(t->transfer_list.next, struct spi_transfer,
			       transfer_list);
	}

	return 0;
}

static int bcm63xx_spi_prepare_transfer(struct spi_master *master)
{
	struct bcm63xx_spi *bs = spi_master_get_devdata(master);

	pm_runtime_get_sync(&bs->pdev->dev);

	return 0;
}

static int bcm63xx_spi_unprepare_transfer(struct spi_master *master)
{
	struct bcm63xx_spi *bs = spi_master_get_devdata(master);

	pm_runtime_put(&bs->pdev->dev);

	return 0;
}

static int bcm63xx_spi_transfer_one(struct spi_master *master,
					struct spi_message *m)
{
	struct bcm63xx_spi *bs = spi_master_get_devdata(master);
	struct spi_transfer *t, *first = NULL;
	struct spi_device *spi = m->spi;
	int status = 0;
	unsigned int n_transfers = 0, total_len = 0;
	bool can_use_prepend = false;

	/*
	 * This SPI controller does not support keeping CS active after a
	 * transfer.
	 * Work around this by merging as many transfers we can into one big
	 * full-duplex transfers.
	 */
	list_for_each_entry(t, &m->transfers, transfer_list) {
		status = bcm63xx_spi_check_transfer(spi, t);
		if (status < 0)
			goto exit;

		if (!first)
			first = t;

		n_transfers++;
		total_len += t->len;

		if (n_transfers == 2 && !first->rx_buf && !t->tx_buf &&
		    first->len <= BCM63XX_SPI_MAX_PREPEND)
			can_use_prepend = true;
		else if (can_use_prepend && t->tx_buf)
			can_use_prepend = false;

		/* we can only transfer one fifo worth of data */
		if ((can_use_prepend &&
		     total_len > (bs->fifo_size + BCM63XX_SPI_MAX_PREPEND)) ||
		    (!can_use_prepend && total_len > bs->fifo_size)) {
			dev_err(&spi->dev, "unable to do transfers larger than FIFO size (%i > %i)\n",
				total_len, bs->fifo_size);
			status = -EINVAL;
			goto exit;
		}

		/* all combined transfers have to have the same speed */
		if (t->speed_hz != first->speed_hz) {
			dev_err(&spi->dev, "unable to change speed between transfers\n");
			status = -EINVAL;
			goto exit;
		}

		/* CS will be deasserted directly after transfer */
		if (t->delay_usecs) {
			dev_err(&spi->dev, "unable to keep CS asserted after transfer\n");
			status = -EINVAL;
			goto exit;
		}

		if (t->cs_change ||
		    list_is_last(&t->transfer_list, &m->transfers)) {
			/* configure adapter for a new transfer */
			bcm63xx_spi_setup_transfer(spi, first);

			/* send the data */
			status = bcm63xx_txrx_bufs(spi, first, n_transfers);
			if (status)
				goto exit;

			m->actual_length += total_len;

			first = NULL;
			n_transfers = 0;
			total_len = 0;
			can_use_prepend = false;
		}
	}
exit:
	m->status = status;
	spi_finalize_current_message(master);

	return 0;
}

/* This driver supports single master mode only. Hence
 * CMD_DONE is the only interrupt we care about
 */
static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id)
{
	struct spi_master *master = (struct spi_master *)dev_id;
	struct bcm63xx_spi *bs = spi_master_get_devdata(master);
	u8 intr;

	/* Read interupts and clear them immediately */
	intr = bcm_spi_readb(bs, SPI_INT_STATUS);
	bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);
	bcm_spi_writeb(bs, 0, SPI_INT_MASK);

	/* A transfer completed */
	if (intr & SPI_INTR_CMD_DONE)
		complete(&bs->done);

	return IRQ_HANDLED;
}


static int bcm63xx_spi_probe(struct platform_device *pdev)
{
	struct resource *r;
	struct device *dev = &pdev->dev;
	struct bcm63xx_spi_pdata *pdata = pdev->dev.platform_data;
	int irq;
	struct spi_master *master;
	struct clk *clk;
	struct bcm63xx_spi *bs;
	int ret;

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!r) {
		dev_err(dev, "no iomem\n");
		ret = -ENXIO;
		goto out;
	}

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		dev_err(dev, "no irq\n");
		ret = -ENXIO;
		goto out;
	}

	clk = clk_get(dev, "spi");
	if (IS_ERR(clk)) {
		dev_err(dev, "no clock for device\n");
		ret = PTR_ERR(clk);
		goto out;
	}

	master = spi_alloc_master(dev, sizeof(*bs));
	if (!master) {
		dev_err(dev, "out of memory\n");
		ret = -ENOMEM;
		goto out_clk;
	}

	bs = spi_master_get_devdata(master);

	platform_set_drvdata(pdev, master);
	bs->pdev = pdev;

	if (!devm_request_mem_region(&pdev->dev, r->start,
					resource_size(r), PFX)) {
		dev_err(dev, "iomem request failed\n");
		ret = -ENXIO;
		goto out_err;
	}

	bs->regs = devm_ioremap_nocache(&pdev->dev, r->start,
							resource_size(r));
	if (!bs->regs) {
		dev_err(dev, "unable to ioremap regs\n");
		ret = -ENOMEM;
		goto out_err;
	}

	bs->irq = irq;
	bs->clk = clk;
	bs->fifo_size = pdata->fifo_size;

	ret = devm_request_irq(&pdev->dev, irq, bcm63xx_spi_interrupt, 0,
							pdev->name, master);
	if (ret) {
		dev_err(dev, "unable to request irq\n");
		goto out_err;
	}

	master->bus_num = pdata->bus_num;
	master->num_chipselect = pdata->num_chipselect;
	master->setup = bcm63xx_spi_setup;
	master->prepare_transfer_hardware = bcm63xx_spi_prepare_transfer;
	master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer;
	master->transfer_one_message = bcm63xx_spi_transfer_one;
	master->mode_bits = MODEBITS;
	bs->speed_hz = pdata->speed_hz;
	bs->msg_type_shift = pdata->msg_type_shift;
	bs->msg_ctl_width = pdata->msg_ctl_width;
	bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA));
	bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA));

	switch (bs->msg_ctl_width) {
	case 8:
	case 16:
		break;
	default:
		dev_err(dev, "unsupported MSG_CTL width: %d\n",
			 bs->msg_ctl_width);
		goto out_clk_disable;
	}

	/* Initialize hardware */
	clk_enable(bs->clk);
	bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS);

	/* register and we are done */
	ret = spi_register_master(master);
	if (ret) {
		dev_err(dev, "spi register failed\n");
		goto out_clk_disable;
	}

	dev_info(dev, "at 0x%08x (irq %d, FIFOs size %d)\n",
		 r->start, irq, bs->fifo_size);

	return 0;

out_clk_disable:
	clk_disable(clk);
out_err:
	platform_set_drvdata(pdev, NULL);
	spi_master_put(master);
out_clk:
	clk_put(clk);
out:
	return ret;
}

static int bcm63xx_spi_remove(struct platform_device *pdev)
{
	struct spi_master *master = spi_master_get(platform_get_drvdata(pdev));
	struct bcm63xx_spi *bs = spi_master_get_devdata(master);

	spi_unregister_master(master);

	/* reset spi block */
	bcm_spi_writeb(bs, 0, SPI_INT_MASK);

	/* HW shutdown */
	clk_disable(bs->clk);
	clk_put(bs->clk);

	platform_set_drvdata(pdev, 0);

	spi_master_put(master);

	return 0;
}

#ifdef CONFIG_PM
static int bcm63xx_spi_suspend(struct device *dev)
{
	struct spi_master *master =
			platform_get_drvdata(to_platform_device(dev));
	struct bcm63xx_spi *bs = spi_master_get_devdata(master);

	spi_master_suspend(master);

	clk_disable(bs->clk);

	return 0;
}

static int bcm63xx_spi_resume(struct device *dev)
{
	struct spi_master *master =
			platform_get_drvdata(to_platform_device(dev));
	struct bcm63xx_spi *bs = spi_master_get_devdata(master);

	clk_enable(bs->clk);

	spi_master_resume(master);

	return 0;
}

static const struct dev_pm_ops bcm63xx_spi_pm_ops = {
	.suspend	= bcm63xx_spi_suspend,
	.resume		= bcm63xx_spi_resume,
};

#define BCM63XX_SPI_PM_OPS	(&bcm63xx_spi_pm_ops)
#else
#define BCM63XX_SPI_PM_OPS	NULL
#endif

static struct platform_driver bcm63xx_spi_driver = {
	.driver = {
		.name	= "bcm63xx-spi",
		.owner	= THIS_MODULE,
		.pm	= BCM63XX_SPI_PM_OPS,
	},
	.probe		= bcm63xx_spi_probe,
	.remove		= bcm63xx_spi_remove,
};

module_platform_driver(bcm63xx_spi_driver);

MODULE_ALIAS("platform:bcm63xx_spi");
MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
MODULE_AUTHOR("Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>");
MODULE_DESCRIPTION("Broadcom BCM63xx SPI Controller driver");
MODULE_LICENSE("GPL");
