/*
 * 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_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;
		}
	}

	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 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_get_platdata(dev);
	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->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
	master->flags		= SPI_MASTER_HALF_DUPLEX;
	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 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		= 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");
