/*
 * Freescale/Motorola Coldfire Queued SPI driver
 *
 * Copyright 2010 Steven King <sfking@fdwdc.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 St - Fifth Floor, Boston, MA 02110-1301 USA
 *
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/spi/spi.h>
#include <linux/pm_runtime.h>

#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#include <asm/mcfqspi.h>

#define	DRIVER_NAME "mcfqspi"

#define	MCFQSPI_BUSCLK			(MCF_BUSCLK / 2)

#define	MCFQSPI_QMR			0x00
#define		MCFQSPI_QMR_MSTR	0x8000
#define		MCFQSPI_QMR_CPOL	0x0200
#define		MCFQSPI_QMR_CPHA	0x0100
#define	MCFQSPI_QDLYR			0x04
#define		MCFQSPI_QDLYR_SPE	0x8000
#define	MCFQSPI_QWR			0x08
#define		MCFQSPI_QWR_HALT	0x8000
#define		MCFQSPI_QWR_WREN	0x4000
#define		MCFQSPI_QWR_CSIV	0x1000
#define	MCFQSPI_QIR			0x0C
#define		MCFQSPI_QIR_WCEFB	0x8000
#define		MCFQSPI_QIR_ABRTB	0x4000
#define		MCFQSPI_QIR_ABRTL	0x1000
#define		MCFQSPI_QIR_WCEFE	0x0800
#define		MCFQSPI_QIR_ABRTE	0x0400
#define		MCFQSPI_QIR_SPIFE	0x0100
#define		MCFQSPI_QIR_WCEF	0x0008
#define		MCFQSPI_QIR_ABRT	0x0004
#define		MCFQSPI_QIR_SPIF	0x0001
#define	MCFQSPI_QAR			0x010
#define		MCFQSPI_QAR_TXBUF	0x00
#define		MCFQSPI_QAR_RXBUF	0x10
#define		MCFQSPI_QAR_CMDBUF	0x20
#define	MCFQSPI_QDR			0x014
#define	MCFQSPI_QCR			0x014
#define		MCFQSPI_QCR_CONT	0x8000
#define		MCFQSPI_QCR_BITSE	0x4000
#define		MCFQSPI_QCR_DT		0x2000

struct mcfqspi {
	void __iomem *iobase;
	int irq;
	struct clk *clk;
	struct mcfqspi_cs_control *cs_control;

	wait_queue_head_t waitq;

	struct device *dev;
};

static void mcfqspi_wr_qmr(struct mcfqspi *mcfqspi, u16 val)
{
	writew(val, mcfqspi->iobase + MCFQSPI_QMR);
}

static void mcfqspi_wr_qdlyr(struct mcfqspi *mcfqspi, u16 val)
{
	writew(val, mcfqspi->iobase + MCFQSPI_QDLYR);
}

static u16 mcfqspi_rd_qdlyr(struct mcfqspi *mcfqspi)
{
	return readw(mcfqspi->iobase + MCFQSPI_QDLYR);
}

static void mcfqspi_wr_qwr(struct mcfqspi *mcfqspi, u16 val)
{
	writew(val, mcfqspi->iobase + MCFQSPI_QWR);
}

static void mcfqspi_wr_qir(struct mcfqspi *mcfqspi, u16 val)
{
	writew(val, mcfqspi->iobase + MCFQSPI_QIR);
}

static void mcfqspi_wr_qar(struct mcfqspi *mcfqspi, u16 val)
{
	writew(val, mcfqspi->iobase + MCFQSPI_QAR);
}

static void mcfqspi_wr_qdr(struct mcfqspi *mcfqspi, u16 val)
{
	writew(val, mcfqspi->iobase + MCFQSPI_QDR);
}

static u16 mcfqspi_rd_qdr(struct mcfqspi *mcfqspi)
{
	return readw(mcfqspi->iobase + MCFQSPI_QDR);
}

static void mcfqspi_cs_select(struct mcfqspi *mcfqspi, u8 chip_select,
			    bool cs_high)
{
	mcfqspi->cs_control->select(mcfqspi->cs_control, chip_select, cs_high);
}

static void mcfqspi_cs_deselect(struct mcfqspi *mcfqspi, u8 chip_select,
				bool cs_high)
{
	mcfqspi->cs_control->deselect(mcfqspi->cs_control, chip_select, cs_high);
}

static int mcfqspi_cs_setup(struct mcfqspi *mcfqspi)
{
	return (mcfqspi->cs_control && mcfqspi->cs_control->setup) ?
		mcfqspi->cs_control->setup(mcfqspi->cs_control) : 0;
}

static void mcfqspi_cs_teardown(struct mcfqspi *mcfqspi)
{
	if (mcfqspi->cs_control && mcfqspi->cs_control->teardown)
		mcfqspi->cs_control->teardown(mcfqspi->cs_control);
}

static u8 mcfqspi_qmr_baud(u32 speed_hz)
{
	return clamp((MCFQSPI_BUSCLK + speed_hz - 1) / speed_hz, 2u, 255u);
}

static bool mcfqspi_qdlyr_spe(struct mcfqspi *mcfqspi)
{
	return mcfqspi_rd_qdlyr(mcfqspi) & MCFQSPI_QDLYR_SPE;
}

static irqreturn_t mcfqspi_irq_handler(int this_irq, void *dev_id)
{
	struct mcfqspi *mcfqspi = dev_id;

	/* clear interrupt */
	mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE | MCFQSPI_QIR_SPIF);
	wake_up(&mcfqspi->waitq);

	return IRQ_HANDLED;
}

static void mcfqspi_transfer_msg8(struct mcfqspi *mcfqspi, unsigned count,
				  const u8 *txbuf, u8 *rxbuf)
{
	unsigned i, n, offset = 0;

	n = min(count, 16u);

	mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_CMDBUF);
	for (i = 0; i < n; ++i)
		mcfqspi_wr_qdr(mcfqspi, MCFQSPI_QCR_BITSE);

	mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_TXBUF);
	if (txbuf)
		for (i = 0; i < n; ++i)
			mcfqspi_wr_qdr(mcfqspi, *txbuf++);
	else
		for (i = 0; i < count; ++i)
			mcfqspi_wr_qdr(mcfqspi, 0);

	count -= n;
	if (count) {
		u16 qwr = 0xf08;
		mcfqspi_wr_qwr(mcfqspi, 0x700);
		mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);

		do {
			wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
			mcfqspi_wr_qwr(mcfqspi, qwr);
			mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
			if (rxbuf) {
				mcfqspi_wr_qar(mcfqspi,
					       MCFQSPI_QAR_RXBUF + offset);
				for (i = 0; i < 8; ++i)
					*rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
			}
			n = min(count, 8u);
			if (txbuf) {
				mcfqspi_wr_qar(mcfqspi,
					       MCFQSPI_QAR_TXBUF + offset);
				for (i = 0; i < n; ++i)
					mcfqspi_wr_qdr(mcfqspi, *txbuf++);
			}
			qwr = (offset ? 0x808 : 0) + ((n - 1) << 8);
			offset ^= 8;
			count -= n;
		} while (count);
		wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
		mcfqspi_wr_qwr(mcfqspi, qwr);
		mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
		if (rxbuf) {
			mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
			for (i = 0; i < 8; ++i)
				*rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
			offset ^= 8;
		}
	} else {
		mcfqspi_wr_qwr(mcfqspi, (n - 1) << 8);
		mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
	}
	wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
	if (rxbuf) {
		mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
		for (i = 0; i < n; ++i)
			*rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
	}
}

static void mcfqspi_transfer_msg16(struct mcfqspi *mcfqspi, unsigned count,
				   const u16 *txbuf, u16 *rxbuf)
{
	unsigned i, n, offset = 0;

	n = min(count, 16u);

	mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_CMDBUF);
	for (i = 0; i < n; ++i)
		mcfqspi_wr_qdr(mcfqspi, MCFQSPI_QCR_BITSE);

	mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_TXBUF);
	if (txbuf)
		for (i = 0; i < n; ++i)
			mcfqspi_wr_qdr(mcfqspi, *txbuf++);
	else
		for (i = 0; i < count; ++i)
			mcfqspi_wr_qdr(mcfqspi, 0);

	count -= n;
	if (count) {
		u16 qwr = 0xf08;
		mcfqspi_wr_qwr(mcfqspi, 0x700);
		mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);

		do {
			wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
			mcfqspi_wr_qwr(mcfqspi, qwr);
			mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
			if (rxbuf) {
				mcfqspi_wr_qar(mcfqspi,
					       MCFQSPI_QAR_RXBUF + offset);
				for (i = 0; i < 8; ++i)
					*rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
			}
			n = min(count, 8u);
			if (txbuf) {
				mcfqspi_wr_qar(mcfqspi,
					       MCFQSPI_QAR_TXBUF + offset);
				for (i = 0; i < n; ++i)
					mcfqspi_wr_qdr(mcfqspi, *txbuf++);
			}
			qwr = (offset ? 0x808 : 0x000) + ((n - 1) << 8);
			offset ^= 8;
			count -= n;
		} while (count);
		wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
		mcfqspi_wr_qwr(mcfqspi, qwr);
		mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
		if (rxbuf) {
			mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
			for (i = 0; i < 8; ++i)
				*rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
			offset ^= 8;
		}
	} else {
		mcfqspi_wr_qwr(mcfqspi, (n - 1) << 8);
		mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
	}
	wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
	if (rxbuf) {
		mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
		for (i = 0; i < n; ++i)
			*rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
	}
}

static int mcfqspi_transfer_one_message(struct spi_master *master,
					 struct spi_message *msg)
{
	struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
	struct spi_device *spi = msg->spi;
	struct spi_transfer *t;
	int status = 0;

	list_for_each_entry(t, &msg->transfers, transfer_list) {
		bool cs_high = spi->mode & SPI_CS_HIGH;
		u16 qmr = MCFQSPI_QMR_MSTR;

		if (t->bits_per_word)
			qmr |= t->bits_per_word << 10;
		else
			qmr |= spi->bits_per_word << 10;
		if (spi->mode & SPI_CPHA)
			qmr |= MCFQSPI_QMR_CPHA;
		if (spi->mode & SPI_CPOL)
			qmr |= MCFQSPI_QMR_CPOL;
		if (t->speed_hz)
			qmr |= mcfqspi_qmr_baud(t->speed_hz);
		else
			qmr |= mcfqspi_qmr_baud(spi->max_speed_hz);
		mcfqspi_wr_qmr(mcfqspi, qmr);

		mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high);

		mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE);
		if ((t->bits_per_word ? t->bits_per_word :
					spi->bits_per_word) == 8)
			mcfqspi_transfer_msg8(mcfqspi, t->len, t->tx_buf,
					t->rx_buf);
		else
			mcfqspi_transfer_msg16(mcfqspi, t->len / 2, t->tx_buf,
					t->rx_buf);
		mcfqspi_wr_qir(mcfqspi, 0);

		if (t->delay_usecs)
			udelay(t->delay_usecs);
		if (t->cs_change) {
			if (!list_is_last(&t->transfer_list, &msg->transfers))
				mcfqspi_cs_deselect(mcfqspi, spi->chip_select,
						cs_high);
		} else {
			if (list_is_last(&t->transfer_list, &msg->transfers))
				mcfqspi_cs_deselect(mcfqspi, spi->chip_select,
						cs_high);
		}
		msg->actual_length += t->len;
	}
	msg->status = status;
	spi_finalize_current_message(master);

	return status;

}

static int mcfqspi_prepare_transfer_hw(struct spi_master *master)
{
	struct mcfqspi *mcfqspi = spi_master_get_devdata(master);

	pm_runtime_get_sync(mcfqspi->dev);

	return 0;
}

static int mcfqspi_unprepare_transfer_hw(struct spi_master *master)
{
	struct mcfqspi *mcfqspi = spi_master_get_devdata(master);

	pm_runtime_put_sync(mcfqspi->dev);

	return 0;
}

static int mcfqspi_setup(struct spi_device *spi)
{
	if ((spi->bits_per_word < 8) || (spi->bits_per_word > 16)) {
		dev_dbg(&spi->dev, "%d bits per word is not supported\n",
			spi->bits_per_word);
		return -EINVAL;
	}
	if (spi->chip_select >= spi->master->num_chipselect) {
		dev_dbg(&spi->dev, "%d chip select is out of range\n",
			spi->chip_select);
		return -EINVAL;
	}

	mcfqspi_cs_deselect(spi_master_get_devdata(spi->master),
			    spi->chip_select, spi->mode & SPI_CS_HIGH);

	dev_dbg(&spi->dev,
			"bits per word %d, chip select %d, speed %d KHz\n",
			spi->bits_per_word, spi->chip_select,
			(MCFQSPI_BUSCLK / mcfqspi_qmr_baud(spi->max_speed_hz))
			/ 1000);

	return 0;
}

static int mcfqspi_probe(struct platform_device *pdev)
{
	struct spi_master *master;
	struct mcfqspi *mcfqspi;
	struct resource *res;
	struct mcfqspi_platform_data *pdata;
	int status;

	master = spi_alloc_master(&pdev->dev, sizeof(*mcfqspi));
	if (master == NULL) {
		dev_dbg(&pdev->dev, "spi_alloc_master failed\n");
		return -ENOMEM;
	}

	mcfqspi = spi_master_get_devdata(master);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_dbg(&pdev->dev, "platform_get_resource failed\n");
		status = -ENXIO;
		goto fail0;
	}

	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
		dev_dbg(&pdev->dev, "request_mem_region failed\n");
		status = -EBUSY;
		goto fail0;
	}

	mcfqspi->iobase = ioremap(res->start, resource_size(res));
	if (!mcfqspi->iobase) {
		dev_dbg(&pdev->dev, "ioremap failed\n");
		status = -ENOMEM;
		goto fail1;
	}

	mcfqspi->irq = platform_get_irq(pdev, 0);
	if (mcfqspi->irq < 0) {
		dev_dbg(&pdev->dev, "platform_get_irq failed\n");
		status = -ENXIO;
		goto fail2;
	}

	status = request_irq(mcfqspi->irq, mcfqspi_irq_handler, 0,
			     pdev->name, mcfqspi);
	if (status) {
		dev_dbg(&pdev->dev, "request_irq failed\n");
		goto fail2;
	}

	mcfqspi->clk = clk_get(&pdev->dev, "qspi_clk");
	if (IS_ERR(mcfqspi->clk)) {
		dev_dbg(&pdev->dev, "clk_get failed\n");
		status = PTR_ERR(mcfqspi->clk);
		goto fail3;
	}
	clk_enable(mcfqspi->clk);

	pdata = pdev->dev.platform_data;
	if (!pdata) {
		dev_dbg(&pdev->dev, "platform data is missing\n");
		goto fail4;
	}
	master->bus_num = pdata->bus_num;
	master->num_chipselect = pdata->num_chipselect;

	mcfqspi->cs_control = pdata->cs_control;
	status = mcfqspi_cs_setup(mcfqspi);
	if (status) {
		dev_dbg(&pdev->dev, "error initializing cs_control\n");
		goto fail4;
	}

	init_waitqueue_head(&mcfqspi->waitq);
	mcfqspi->dev = &pdev->dev;

	master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA;
	master->setup = mcfqspi_setup;
	master->transfer_one_message = mcfqspi_transfer_one_message;
	master->prepare_transfer_hardware = mcfqspi_prepare_transfer_hw;
	master->unprepare_transfer_hardware = mcfqspi_unprepare_transfer_hw;

	platform_set_drvdata(pdev, master);

	status = spi_register_master(master);
	if (status) {
		dev_dbg(&pdev->dev, "spi_register_master failed\n");
		goto fail5;
	}
	pm_runtime_enable(mcfqspi->dev);

	dev_info(&pdev->dev, "Coldfire QSPI bus driver\n");

	return 0;

fail5:
	mcfqspi_cs_teardown(mcfqspi);
fail4:
	clk_disable(mcfqspi->clk);
	clk_put(mcfqspi->clk);
fail3:
	free_irq(mcfqspi->irq, mcfqspi);
fail2:
	iounmap(mcfqspi->iobase);
fail1:
	release_mem_region(res->start, resource_size(res));
fail0:
	spi_master_put(master);

	dev_dbg(&pdev->dev, "Coldfire QSPI probe failed\n");

	return status;
}

static int mcfqspi_remove(struct platform_device *pdev)
{
	struct spi_master *master = platform_get_drvdata(pdev);
	struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	pm_runtime_disable(mcfqspi->dev);
	/* disable the hardware (set the baud rate to 0) */
	mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR);

	platform_set_drvdata(pdev, NULL);
	mcfqspi_cs_teardown(mcfqspi);
	clk_disable(mcfqspi->clk);
	clk_put(mcfqspi->clk);
	free_irq(mcfqspi->irq, mcfqspi);
	iounmap(mcfqspi->iobase);
	release_mem_region(res->start, resource_size(res));
	spi_unregister_master(master);

	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int mcfqspi_suspend(struct device *dev)
{
	struct spi_master *master = dev_get_drvdata(dev);
	struct mcfqspi *mcfqspi = spi_master_get_devdata(master);

	spi_master_suspend(master);

	clk_disable(mcfqspi->clk);

	return 0;
}

static int mcfqspi_resume(struct device *dev)
{
	struct spi_master *master = dev_get_drvdata(dev);
	struct mcfqspi *mcfqspi = spi_master_get_devdata(master);

	spi_master_resume(master);

	clk_enable(mcfqspi->clk);

	return 0;
}
#endif

#ifdef CONFIG_PM_RUNTIME
static int mcfqspi_runtime_suspend(struct device *dev)
{
	struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev));

	clk_disable(mcfqspi->clk);

	return 0;
}

static int mcfqspi_runtime_resume(struct device *dev)
{
	struct mcfqspi *mcfqspi = platform_get_drvdata(to_platform_device(dev));

	clk_enable(mcfqspi->clk);

	return 0;
}
#endif

static const struct dev_pm_ops mcfqspi_pm = {
	SET_SYSTEM_SLEEP_PM_OPS(mcfqspi_suspend, mcfqspi_resume)
	SET_RUNTIME_PM_OPS(mcfqspi_runtime_suspend, mcfqspi_runtime_resume,
			NULL)
};

static struct platform_driver mcfqspi_driver = {
	.driver.name	= DRIVER_NAME,
	.driver.owner	= THIS_MODULE,
	.driver.pm	= &mcfqspi_pm,
	.probe		= mcfqspi_probe,
	.remove		= mcfqspi_remove,
};
module_platform_driver(mcfqspi_driver);

MODULE_AUTHOR("Steven King <sfking@fdwdc.com>");
MODULE_DESCRIPTION("Coldfire QSPI Controller Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRIVER_NAME);
