/*
 * Sequencer Serial Port (SSP) based SPI master driver
 *
 * Copyright (C) 2010 Texas Instruments Inc
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/mfd/ti_ssp.h>

#define MODE_BITS	(SPI_CPHA | SPI_CPOL | SPI_CS_HIGH)

struct ti_ssp_spi {
	struct spi_master		*master;
	struct device			*dev;
	spinlock_t			lock;
	struct list_head		msg_queue;
	struct completion		complete;
	bool				shutdown;
	struct workqueue_struct		*workqueue;
	struct work_struct		work;
	u8				mode, bpw;
	int				cs_active;
	u32				pc_en, pc_dis, pc_wr, pc_rd;
	void				(*select)(int cs);
};

static u32 ti_ssp_spi_rx(struct ti_ssp_spi *hw)
{
	u32 ret;

	ti_ssp_run(hw->dev, hw->pc_rd, 0, &ret);
	return ret;
}

static void ti_ssp_spi_tx(struct ti_ssp_spi *hw, u32 data)
{
	ti_ssp_run(hw->dev, hw->pc_wr, data << (32 - hw->bpw), NULL);
}

static int ti_ssp_spi_txrx(struct ti_ssp_spi *hw, struct spi_message *msg,
		       struct spi_transfer *t)
{
	int count;

	if (hw->bpw <= 8) {
		u8		*rx = t->rx_buf;
		const u8	*tx = t->tx_buf;

		for (count = 0; count < t->len; count += 1) {
			if (t->tx_buf)
				ti_ssp_spi_tx(hw, *tx++);
			if (t->rx_buf)
				*rx++ = ti_ssp_spi_rx(hw);
		}
	} else if (hw->bpw <= 16) {
		u16		*rx = t->rx_buf;
		const u16	*tx = t->tx_buf;

		for (count = 0; count < t->len; count += 2) {
			if (t->tx_buf)
				ti_ssp_spi_tx(hw, *tx++);
			if (t->rx_buf)
				*rx++ = ti_ssp_spi_rx(hw);
		}
	} else {
		u32		*rx = t->rx_buf;
		const u32	*tx = t->tx_buf;

		for (count = 0; count < t->len; count += 4) {
			if (t->tx_buf)
				ti_ssp_spi_tx(hw, *tx++);
			if (t->rx_buf)
				*rx++ = ti_ssp_spi_rx(hw);
		}
	}

	msg->actual_length += count; /* bytes transferred */

	dev_dbg(&msg->spi->dev, "xfer %s%s, %d bytes, %d bpw, count %d%s\n",
		t->tx_buf ? "tx" : "", t->rx_buf ? "rx" : "", t->len,
		hw->bpw, count, (count < t->len) ? " (under)" : "");

	return (count < t->len) ? -EIO : 0; /* left over data */
}

static void ti_ssp_spi_chip_select(struct ti_ssp_spi *hw, int cs_active)
{
	cs_active = !!cs_active;
	if (cs_active == hw->cs_active)
		return;
	ti_ssp_run(hw->dev, cs_active ? hw->pc_en : hw->pc_dis, 0, NULL);
	hw->cs_active = cs_active;
}

#define __SHIFT_OUT(bits)	(SSP_OPCODE_SHIFT | SSP_OUT_MODE | \
				 cs_en | clk | SSP_COUNT((bits) * 2 - 1))
#define __SHIFT_IN(bits)	(SSP_OPCODE_SHIFT | SSP_IN_MODE  | \
				 cs_en | clk | SSP_COUNT((bits) * 2 - 1))

static int ti_ssp_spi_setup_transfer(struct ti_ssp_spi *hw, u8 bpw, u8 mode)
{
	int error, idx = 0;
	u32 seqram[16];
	u32 cs_en, cs_dis, clk;
	u32 topbits, botbits;

	mode &= MODE_BITS;
	if (mode == hw->mode && bpw == hw->bpw)
		return 0;

	cs_en  = (mode & SPI_CS_HIGH) ? SSP_CS_HIGH : SSP_CS_LOW;
	cs_dis = (mode & SPI_CS_HIGH) ? SSP_CS_LOW  : SSP_CS_HIGH;
	clk    = (mode & SPI_CPOL)    ? SSP_CLK_HIGH : SSP_CLK_LOW;

	/* Construct instructions */

	/* Disable Chip Select */
	hw->pc_dis = idx;
	seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_dis | clk;
	seqram[idx++] = SSP_OPCODE_STOP   | SSP_OUT_MODE | cs_dis | clk;

	/* Enable Chip Select */
	hw->pc_en = idx;
	seqram[idx++] = SSP_OPCODE_DIRECT | SSP_OUT_MODE | cs_en | clk;
	seqram[idx++] = SSP_OPCODE_STOP   | SSP_OUT_MODE | cs_en | clk;

	/* Reads and writes need to be split for bpw > 16 */
	topbits = (bpw > 16) ? 16 : bpw;
	botbits = bpw - topbits;

	/* Write */
	hw->pc_wr = idx;
	seqram[idx++] = __SHIFT_OUT(topbits) | SSP_ADDR_REG;
	if (botbits)
		seqram[idx++] = __SHIFT_OUT(botbits)  | SSP_DATA_REG;
	seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk;

	/* Read */
	hw->pc_rd = idx;
	if (botbits)
		seqram[idx++] = __SHIFT_IN(botbits) | SSP_ADDR_REG;
	seqram[idx++] = __SHIFT_IN(topbits) | SSP_DATA_REG;
	seqram[idx++] = SSP_OPCODE_STOP | SSP_OUT_MODE | cs_en | clk;

	error = ti_ssp_load(hw->dev, 0, seqram, idx);
	if (error < 0)
		return error;

	error = ti_ssp_set_mode(hw->dev, ((mode & SPI_CPHA) ?
					  0 : SSP_EARLY_DIN));
	if (error < 0)
		return error;

	hw->bpw = bpw;
	hw->mode = mode;

	return error;
}

static void ti_ssp_spi_work(struct work_struct *work)
{
	struct ti_ssp_spi *hw = container_of(work, struct ti_ssp_spi, work);

	spin_lock(&hw->lock);

	 while (!list_empty(&hw->msg_queue)) {
		struct spi_message	*m;
		struct spi_device	*spi;
		struct spi_transfer	*t = NULL;
		int			status = 0;

		m = container_of(hw->msg_queue.next, struct spi_message,
				 queue);

		list_del_init(&m->queue);

		spin_unlock(&hw->lock);

		spi = m->spi;

		if (hw->select)
			hw->select(spi->chip_select);

		list_for_each_entry(t, &m->transfers, transfer_list) {
			int bpw = spi->bits_per_word;
			int xfer_status;

			if (t->bits_per_word)
				bpw = t->bits_per_word;

			if (ti_ssp_spi_setup_transfer(hw, bpw, spi->mode) < 0)
				break;

			ti_ssp_spi_chip_select(hw, 1);

			xfer_status = ti_ssp_spi_txrx(hw, m, t);
			if (xfer_status < 0)
				status = xfer_status;

			if (t->delay_usecs)
				udelay(t->delay_usecs);

			if (t->cs_change)
				ti_ssp_spi_chip_select(hw, 0);
		}

		ti_ssp_spi_chip_select(hw, 0);
		m->status = status;
		m->complete(m->context);

		spin_lock(&hw->lock);
	}

	if (hw->shutdown)
		complete(&hw->complete);

	spin_unlock(&hw->lock);
}

static int ti_ssp_spi_setup(struct spi_device *spi)
{
	if (spi->bits_per_word > 32)
		return -EINVAL;

	return 0;
}

static int ti_ssp_spi_transfer(struct spi_device *spi, struct spi_message *m)
{
	struct ti_ssp_spi	*hw;
	struct spi_transfer	*t;
	int			error = 0;

	m->actual_length = 0;
	m->status = -EINPROGRESS;

	hw = spi_master_get_devdata(spi->master);

	if (list_empty(&m->transfers) || !m->complete)
		return -EINVAL;

	list_for_each_entry(t, &m->transfers, transfer_list) {
		if (t->len && !(t->rx_buf || t->tx_buf)) {
			dev_err(&spi->dev, "invalid xfer, no buffer\n");
			return -EINVAL;
		}

		if (t->len && t->rx_buf && t->tx_buf) {
			dev_err(&spi->dev, "invalid xfer, full duplex\n");
			return -EINVAL;
		}

		if (t->bits_per_word > 32) {
			dev_err(&spi->dev, "invalid xfer width %d\n",
				t->bits_per_word);
			return -EINVAL;
		}
	}

	spin_lock(&hw->lock);
	if (hw->shutdown) {
		error = -ESHUTDOWN;
		goto error_unlock;
	}
	list_add_tail(&m->queue, &hw->msg_queue);
	queue_work(hw->workqueue, &hw->work);
error_unlock:
	spin_unlock(&hw->lock);
	return error;
}

static int __devinit ti_ssp_spi_probe(struct platform_device *pdev)
{
	const struct ti_ssp_spi_data *pdata;
	struct ti_ssp_spi *hw;
	struct spi_master *master;
	struct device *dev = &pdev->dev;
	int error = 0;

	pdata = dev->platform_data;
	if (!pdata) {
		dev_err(dev, "platform data not found\n");
		return -EINVAL;
	}

	master = spi_alloc_master(dev, sizeof(struct ti_ssp_spi));
	if (!master) {
		dev_err(dev, "cannot allocate SPI master\n");
		return -ENOMEM;
	}

	hw = spi_master_get_devdata(master);
	platform_set_drvdata(pdev, hw);

	hw->master = master;
	hw->dev = dev;
	hw->select = pdata->select;

	spin_lock_init(&hw->lock);
	init_completion(&hw->complete);
	INIT_LIST_HEAD(&hw->msg_queue);
	INIT_WORK(&hw->work, ti_ssp_spi_work);

	hw->workqueue = create_singlethread_workqueue(dev_name(dev));
	if (!hw->workqueue) {
		error = -ENOMEM;
		dev_err(dev, "work queue creation failed\n");
		goto error_wq;
	}

	error = ti_ssp_set_iosel(hw->dev, pdata->iosel);
	if (error < 0) {
		dev_err(dev, "io setup failed\n");
		goto error_iosel;
	}

	master->bus_num		= pdev->id;
	master->num_chipselect	= pdata->num_cs;
	master->mode_bits	= MODE_BITS;
	master->flags		= SPI_MASTER_HALF_DUPLEX;
	master->setup		= ti_ssp_spi_setup;
	master->transfer	= ti_ssp_spi_transfer;

	error = spi_register_master(master);
	if (error) {
		dev_err(dev, "master registration failed\n");
		goto error_reg;
	}

	return 0;

error_reg:
error_iosel:
	destroy_workqueue(hw->workqueue);
error_wq:
	spi_master_put(master);
	return error;
}

static int __devexit ti_ssp_spi_remove(struct platform_device *pdev)
{
	struct ti_ssp_spi *hw = platform_get_drvdata(pdev);
	int error;

	hw->shutdown = 1;
	while (!list_empty(&hw->msg_queue)) {
		error = wait_for_completion_interruptible(&hw->complete);
		if (error < 0) {
			hw->shutdown = 0;
			return error;
		}
	}
	destroy_workqueue(hw->workqueue);
	spi_unregister_master(hw->master);

	return 0;
}

static struct platform_driver ti_ssp_spi_driver = {
	.probe		= ti_ssp_spi_probe,
	.remove		= __devexit_p(ti_ssp_spi_remove),
	.driver		= {
		.name	= "ti-ssp-spi",
		.owner	= THIS_MODULE,
	},
};
module_platform_driver(ti_ssp_spi_driver);

MODULE_DESCRIPTION("SSP SPI Master");
MODULE_AUTHOR("Cyril Chemparathy");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:ti-ssp-spi");
