/*
 * Copyright (C) ST-Ericsson AB 2010
 * Contact: Sjur Brendeland / sjur.brandeland@stericsson.com
 * Author:  Daniel Martensson / Daniel.Martensson@stericsson.com
 * License terms: GNU General Public License (GPL) version 2.
 */
#include <linux/version.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/string.h>
#include <linux/semaphore.h>
#include <linux/workqueue.h>
#include <linux/completion.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/debugfs.h>
#include <net/caif/caif_spi.h>

#ifndef CONFIG_CAIF_SPI_SYNC
#define SPI_DATA_POS 0
static inline int forward_to_spi_cmd(struct cfspi *cfspi)
{
	return cfspi->rx_cpck_len;
}
#else
#define SPI_DATA_POS SPI_CMD_SZ
static inline int forward_to_spi_cmd(struct cfspi *cfspi)
{
	return 0;
}
#endif

int spi_frm_align = 2;
int spi_up_head_align = 1;
int spi_up_tail_align;
int spi_down_head_align = 3;
int spi_down_tail_align = 1;

#ifdef CONFIG_DEBUG_FS
static inline void debugfs_store_prev(struct cfspi *cfspi)
{
	/* Store previous command for debugging reasons.*/
	cfspi->pcmd = cfspi->cmd;
	/* Store previous transfer. */
	cfspi->tx_ppck_len = cfspi->tx_cpck_len;
	cfspi->rx_ppck_len = cfspi->rx_cpck_len;
}
#else
static inline void debugfs_store_prev(struct cfspi *cfspi)
{
}
#endif

void cfspi_xfer(struct work_struct *work)
{
	struct cfspi *cfspi;
	u8 *ptr = NULL;
	unsigned long flags;
	int ret;
	cfspi = container_of(work, struct cfspi, work);

	/* Initialize state. */
	cfspi->cmd = SPI_CMD_EOT;

	for (;;) {

		cfspi_dbg_state(cfspi, CFSPI_STATE_WAITING);

		/* Wait for master talk or transmit event. */
		wait_event_interruptible(cfspi->wait,
				 test_bit(SPI_XFER, &cfspi->state) ||
				 test_bit(SPI_TERMINATE, &cfspi->state));

		if (test_bit(SPI_TERMINATE, &cfspi->state))
			return;

#if CFSPI_DBG_PREFILL
		/* Prefill buffers for easier debugging. */
		memset(cfspi->xfer.va_tx, 0xFF, SPI_DMA_BUF_LEN);
		memset(cfspi->xfer.va_rx, 0xFF, SPI_DMA_BUF_LEN);
#endif	/* CFSPI_DBG_PREFILL */

		cfspi_dbg_state(cfspi, CFSPI_STATE_AWAKE);

	/* Check whether we have a committed frame. */
		if (cfspi->tx_cpck_len) {
			int len;

			cfspi_dbg_state(cfspi, CFSPI_STATE_FETCH_PKT);

			/* Copy commited SPI frames after the SPI indication. */
			ptr = (u8 *) cfspi->xfer.va_tx;
			ptr += SPI_IND_SZ;
			len = cfspi_xmitfrm(cfspi, ptr, cfspi->tx_cpck_len);
			WARN_ON(len != cfspi->tx_cpck_len);
	}

		cfspi_dbg_state(cfspi, CFSPI_STATE_GET_NEXT);

		/* Get length of next frame to commit. */
		cfspi->tx_npck_len = cfspi_xmitlen(cfspi);

		WARN_ON(cfspi->tx_npck_len > SPI_DMA_BUF_LEN);

		/*
		 * Add indication and length at the beginning of the frame,
		 * using little endian.
		 */
		ptr = (u8 *) cfspi->xfer.va_tx;
		*ptr++ = SPI_CMD_IND;
		*ptr++ = (SPI_CMD_IND  & 0xFF00) >> 8;
		*ptr++ = cfspi->tx_npck_len & 0x00FF;
		*ptr++ = (cfspi->tx_npck_len & 0xFF00) >> 8;

		/* Calculate length of DMAs. */
		cfspi->xfer.tx_dma_len = cfspi->tx_cpck_len + SPI_IND_SZ;
		cfspi->xfer.rx_dma_len = cfspi->rx_cpck_len + SPI_CMD_SZ;

		/* Add SPI TX frame alignment padding, if necessary. */
		if (cfspi->tx_cpck_len &&
			(cfspi->xfer.tx_dma_len % spi_frm_align)) {

			cfspi->xfer.tx_dma_len += spi_frm_align -
			    (cfspi->xfer.tx_dma_len % spi_frm_align);
		}

		/* Add SPI RX frame alignment padding, if necessary. */
		if (cfspi->rx_cpck_len &&
			(cfspi->xfer.rx_dma_len % spi_frm_align)) {

			cfspi->xfer.rx_dma_len += spi_frm_align -
			    (cfspi->xfer.rx_dma_len % spi_frm_align);
		}

		cfspi_dbg_state(cfspi, CFSPI_STATE_INIT_XFER);

		/* Start transfer. */
		ret = cfspi->dev->init_xfer(&cfspi->xfer, cfspi->dev);
		WARN_ON(ret);

		cfspi_dbg_state(cfspi, CFSPI_STATE_WAIT_ACTIVE);

		/*
		 * TODO: We might be able to make an assumption if this is the
		 * first loop. Make sure that minimum toggle time is respected.
		 */
		udelay(MIN_TRANSITION_TIME_USEC);

		cfspi_dbg_state(cfspi, CFSPI_STATE_SIG_ACTIVE);

		/* Signal that we are ready to recieve data. */
		cfspi->dev->sig_xfer(true, cfspi->dev);

		cfspi_dbg_state(cfspi, CFSPI_STATE_WAIT_XFER_DONE);

		/* Wait for transfer completion. */
		wait_for_completion(&cfspi->comp);

		cfspi_dbg_state(cfspi, CFSPI_STATE_XFER_DONE);

		if (cfspi->cmd == SPI_CMD_EOT) {
			/*
			 * Clear the master talk bit. A xfer is always at
			 *  least two bursts.
			 */
			clear_bit(SPI_SS_ON, &cfspi->state);
		}

		cfspi_dbg_state(cfspi, CFSPI_STATE_WAIT_INACTIVE);

		/* Make sure that the minimum toggle time is respected. */
		if (SPI_XFER_TIME_USEC(cfspi->xfer.tx_dma_len,
					cfspi->dev->clk_mhz) <
			MIN_TRANSITION_TIME_USEC) {

			udelay(MIN_TRANSITION_TIME_USEC -
				SPI_XFER_TIME_USEC
				(cfspi->xfer.tx_dma_len, cfspi->dev->clk_mhz));
		}

		cfspi_dbg_state(cfspi, CFSPI_STATE_SIG_INACTIVE);

		/* De-assert transfer signal. */
		cfspi->dev->sig_xfer(false, cfspi->dev);

		/* Check whether we received a CAIF packet. */
		if (cfspi->rx_cpck_len) {
			int len;

			cfspi_dbg_state(cfspi, CFSPI_STATE_DELIVER_PKT);

			/* Parse SPI frame. */
			ptr = ((u8 *)(cfspi->xfer.va_rx + SPI_DATA_POS));

			len = cfspi_rxfrm(cfspi, ptr, cfspi->rx_cpck_len);
			WARN_ON(len != cfspi->rx_cpck_len);
		}

		/* Check the next SPI command and length. */
		ptr = (u8 *) cfspi->xfer.va_rx;

		ptr += forward_to_spi_cmd(cfspi);

		cfspi->cmd = *ptr++;
		cfspi->cmd |= ((*ptr++) << 8) & 0xFF00;
		cfspi->rx_npck_len = *ptr++;
		cfspi->rx_npck_len |= ((*ptr++) << 8) & 0xFF00;

		WARN_ON(cfspi->rx_npck_len > SPI_DMA_BUF_LEN);
		WARN_ON(cfspi->cmd > SPI_CMD_EOT);

		debugfs_store_prev(cfspi);

		/* Check whether the master issued an EOT command. */
		if (cfspi->cmd == SPI_CMD_EOT) {
			/* Reset state. */
			cfspi->tx_cpck_len = 0;
			cfspi->rx_cpck_len = 0;
		} else {
			/* Update state. */
			cfspi->tx_cpck_len = cfspi->tx_npck_len;
			cfspi->rx_cpck_len = cfspi->rx_npck_len;
		}

		/*
		 * Check whether we need to clear the xfer bit.
		 * Spin lock needed for packet insertion.
		 * Test and clear of different bits
		 * are not supported.
		 */
		spin_lock_irqsave(&cfspi->lock, flags);
		if (cfspi->cmd == SPI_CMD_EOT && !cfspi_xmitlen(cfspi)
			&& !test_bit(SPI_SS_ON, &cfspi->state))
			clear_bit(SPI_XFER, &cfspi->state);

		spin_unlock_irqrestore(&cfspi->lock, flags);
	}
}

struct platform_driver cfspi_spi_driver = {
	.probe = cfspi_spi_probe,
	.remove = cfspi_spi_remove,
	.driver = {
		   .name = "cfspi_sspi",
		   .owner = THIS_MODULE,
		   },
};
