/*
 * MPC83xx SPI controller driver.
 *
 * Maintainer: Kumar Gala
 *
 * Copyright (C) 2006 Polycom, 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.
 */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/completion.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/platform_device.h>
#include <linux/fsl_devices.h>

#include <asm/irq.h>
#include <asm/io.h>

/* SPI Controller registers */
struct mpc83xx_spi_reg {
	u8 res1[0x20];
	__be32 mode;
	__be32 event;
	__be32 mask;
	__be32 command;
	__be32 transmit;
	__be32 receive;
};

/* SPI Controller mode register definitions */
#define	SPMODE_LOOP		(1 << 30)
#define	SPMODE_CI_INACTIVEHIGH	(1 << 29)
#define	SPMODE_CP_BEGIN_EDGECLK	(1 << 28)
#define	SPMODE_DIV16		(1 << 27)
#define	SPMODE_REV		(1 << 26)
#define	SPMODE_MS		(1 << 25)
#define	SPMODE_ENABLE		(1 << 24)
#define	SPMODE_LEN(x)		((x) << 20)
#define	SPMODE_PM(x)		((x) << 16)
#define	SPMODE_OP		(1 << 14)

/*
 * Default for SPI Mode:
 * 	SPI MODE 0 (inactive low, phase middle, MSB, 8-bit length, slow clk
 */
#define	SPMODE_INIT_VAL (SPMODE_CI_INACTIVEHIGH | SPMODE_DIV16 | SPMODE_REV | \
			 SPMODE_MS | SPMODE_LEN(7) | SPMODE_PM(0xf))

/* SPIE register values */
#define	SPIE_NE		0x00000200	/* Not empty */
#define	SPIE_NF		0x00000100	/* Not full */

/* SPIM register values */
#define	SPIM_NE		0x00000200	/* Not empty */
#define	SPIM_NF		0x00000100	/* Not full */

/* SPI Controller driver's private data. */
struct mpc83xx_spi {
	/* bitbang has to be first */
	struct spi_bitbang bitbang;
	struct completion done;

	struct mpc83xx_spi_reg __iomem *base;

	/* rx & tx bufs from the spi_transfer */
	const void *tx;
	void *rx;

	/* functions to deal with different sized buffers */
	void (*get_rx) (u32 rx_data, struct mpc83xx_spi *);
	u32(*get_tx) (struct mpc83xx_spi *);

	unsigned int count;
	u32 irq;

	unsigned nsecs;		/* (clock cycle time)/2 */

	u32 spibrg;		/* SPIBRG input clock */
	u32 rx_shift;		/* RX data reg shift when in qe mode */
	u32 tx_shift;		/* TX data reg shift when in qe mode */

	bool qe_mode;

	void (*activate_cs) (u8 cs, u8 polarity);
	void (*deactivate_cs) (u8 cs, u8 polarity);
};

static inline void mpc83xx_spi_write_reg(__be32 __iomem * reg, u32 val)
{
	out_be32(reg, val);
}

static inline u32 mpc83xx_spi_read_reg(__be32 __iomem * reg)
{
	return in_be32(reg);
}

#define MPC83XX_SPI_RX_BUF(type) 					  \
void mpc83xx_spi_rx_buf_##type(u32 data, struct mpc83xx_spi *mpc83xx_spi) \
{									  \
	type * rx = mpc83xx_spi->rx;					  \
	*rx++ = (type)(data >> mpc83xx_spi->rx_shift);			  \
	mpc83xx_spi->rx = rx;						  \
}

#define MPC83XX_SPI_TX_BUF(type)				\
u32 mpc83xx_spi_tx_buf_##type(struct mpc83xx_spi *mpc83xx_spi)	\
{								\
	u32 data;						\
	const type * tx = mpc83xx_spi->tx;			\
	if (!tx)						\
		return 0;					\
	data = *tx++ << mpc83xx_spi->tx_shift;			\
	mpc83xx_spi->tx = tx;					\
	return data;						\
}

MPC83XX_SPI_RX_BUF(u8)
MPC83XX_SPI_RX_BUF(u16)
MPC83XX_SPI_RX_BUF(u32)
MPC83XX_SPI_TX_BUF(u8)
MPC83XX_SPI_TX_BUF(u16)
MPC83XX_SPI_TX_BUF(u32)

static void mpc83xx_spi_chipselect(struct spi_device *spi, int value)
{
	struct mpc83xx_spi *mpc83xx_spi;
	u8 pol = spi->mode & SPI_CS_HIGH ? 1 : 0;

	mpc83xx_spi = spi_master_get_devdata(spi->master);

	if (value == BITBANG_CS_INACTIVE) {
		if (mpc83xx_spi->deactivate_cs)
			mpc83xx_spi->deactivate_cs(spi->chip_select, pol);
	}

	if (value == BITBANG_CS_ACTIVE) {
		u32 regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
		u32 len = spi->bits_per_word;
		u8 pm;

		if (len == 32)
			len = 0;
		else
			len = len - 1;

		/* mask out bits we are going to set */
		regval &= ~(SPMODE_CP_BEGIN_EDGECLK | SPMODE_CI_INACTIVEHIGH
				| SPMODE_LEN(0xF) | SPMODE_DIV16
				| SPMODE_PM(0xF) | SPMODE_REV | SPMODE_LOOP);

		if (spi->mode & SPI_CPHA)
			regval |= SPMODE_CP_BEGIN_EDGECLK;
		if (spi->mode & SPI_CPOL)
			regval |= SPMODE_CI_INACTIVEHIGH;
		if (!(spi->mode & SPI_LSB_FIRST))
			regval |= SPMODE_REV;
		if (spi->mode & SPI_LOOP)
			regval |= SPMODE_LOOP;

		regval |= SPMODE_LEN(len);

		if ((mpc83xx_spi->spibrg / spi->max_speed_hz) >= 64) {
			pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 64) - 1;
			if (pm > 0x0f) {
				dev_err(&spi->dev, "Requested speed is too "
					"low: %d Hz. Will use %d Hz instead.\n",
					spi->max_speed_hz,
					mpc83xx_spi->spibrg / 1024);
				pm = 0x0f;
			}
			regval |= SPMODE_PM(pm) | SPMODE_DIV16;
		} else {
			pm = mpc83xx_spi->spibrg / (spi->max_speed_hz * 4);
			if (pm)
				pm--;
			regval |= SPMODE_PM(pm);
		}

		/* Turn off SPI unit prior changing mode */
		mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0);
		mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);
		if (mpc83xx_spi->activate_cs)
			mpc83xx_spi->activate_cs(spi->chip_select, pol);
	}
}

static
int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
{
	struct mpc83xx_spi *mpc83xx_spi;
	u32 regval;
	u8 bits_per_word;
	u32 hz;

	mpc83xx_spi = spi_master_get_devdata(spi->master);

	if (t) {
		bits_per_word = t->bits_per_word;
		hz = t->speed_hz;
	} else {
		bits_per_word = 0;
		hz = 0;
	}

	/* spi_transfer level calls that work per-word */
	if (!bits_per_word)
		bits_per_word = spi->bits_per_word;

	/* Make sure its a bit width we support [4..16, 32] */
	if ((bits_per_word < 4)
	    || ((bits_per_word > 16) && (bits_per_word != 32)))
		return -EINVAL;

	mpc83xx_spi->rx_shift = 0;
	mpc83xx_spi->tx_shift = 0;
	if (bits_per_word <= 8) {
		mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8;
		mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8;
		if (mpc83xx_spi->qe_mode) {
			mpc83xx_spi->rx_shift = 16;
			mpc83xx_spi->tx_shift = 24;
		}
	} else if (bits_per_word <= 16) {
		mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u16;
		mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u16;
		if (mpc83xx_spi->qe_mode) {
			mpc83xx_spi->rx_shift = 16;
			mpc83xx_spi->tx_shift = 16;
		}
	} else if (bits_per_word <= 32) {
		mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u32;
		mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u32;
	} else
		return -EINVAL;

	if (mpc83xx_spi->qe_mode && spi->mode & SPI_LSB_FIRST) {
		mpc83xx_spi->tx_shift = 0;
		if (bits_per_word <= 8)
			mpc83xx_spi->rx_shift = 8;
		else
			mpc83xx_spi->rx_shift = 0;
	}

	/* nsecs = (clock period)/2 */
	if (!hz)
		hz = spi->max_speed_hz;
	mpc83xx_spi->nsecs = (1000000000 / 2) / hz;
	if (mpc83xx_spi->nsecs > MAX_UDELAY_MS * 1000)
		return -EINVAL;

	if (bits_per_word == 32)
		bits_per_word = 0;
	else
		bits_per_word = bits_per_word - 1;

	regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);

	/* mask out bits we are going to set */
	regval &= ~(SPMODE_LEN(0xF) | SPMODE_REV);
	regval |= SPMODE_LEN(bits_per_word);
	if (!(spi->mode & SPI_LSB_FIRST))
		regval |= SPMODE_REV;

	/* Turn off SPI unit prior changing mode */
	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0);
	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);

	return 0;
}

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

static int mpc83xx_spi_setup(struct spi_device *spi)
{
	struct spi_bitbang *bitbang;
	struct mpc83xx_spi *mpc83xx_spi;
	int retval;

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

	if (!spi->max_speed_hz)
		return -EINVAL;

	bitbang = spi_master_get_devdata(spi->master);
	mpc83xx_spi = spi_master_get_devdata(spi->master);

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

	retval = mpc83xx_spi_setup_transfer(spi, NULL);
	if (retval < 0)
		return retval;

	dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec\n",
		__FUNCTION__, spi->mode & (SPI_CPOL | SPI_CPHA),
		spi->bits_per_word, 2 * mpc83xx_spi->nsecs);

	/* NOTE we _need_ to call chipselect() early, ideally with adapter
	 * setup, unless the hardware defaults cooperate to avoid confusion
	 * between normal (active low) and inverted chipselects.
	 */

	/* deselect chip (low or high) */
	spin_lock(&bitbang->lock);
	if (!bitbang->busy) {
		bitbang->chipselect(spi, BITBANG_CS_INACTIVE);
		ndelay(mpc83xx_spi->nsecs);
	}
	spin_unlock(&bitbang->lock);

	return 0;
}

static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
{
	struct mpc83xx_spi *mpc83xx_spi;
	u32 word;

	mpc83xx_spi = spi_master_get_devdata(spi->master);

	mpc83xx_spi->tx = t->tx_buf;
	mpc83xx_spi->rx = t->rx_buf;
	mpc83xx_spi->count = t->len;
	INIT_COMPLETION(mpc83xx_spi->done);

	/* enable rx ints */
	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, SPIM_NE);

	/* transmit word */
	word = mpc83xx_spi->get_tx(mpc83xx_spi);
	mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word);

	wait_for_completion(&mpc83xx_spi->done);

	/* disable rx ints */
	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0);

	return t->len - mpc83xx_spi->count;
}

irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data)
{
	struct mpc83xx_spi *mpc83xx_spi = context_data;
	u32 event;
	irqreturn_t ret = IRQ_NONE;

	/* Get interrupt events(tx/rx) */
	event = mpc83xx_spi_read_reg(&mpc83xx_spi->base->event);

	/* We need handle RX first */
	if (event & SPIE_NE) {
		u32 rx_data = mpc83xx_spi_read_reg(&mpc83xx_spi->base->receive);

		if (mpc83xx_spi->rx)
			mpc83xx_spi->get_rx(rx_data, mpc83xx_spi);

		ret = IRQ_HANDLED;
	}

	if ((event & SPIE_NF) == 0)
		/* spin until TX is done */
		while (((event =
			 mpc83xx_spi_read_reg(&mpc83xx_spi->base->event)) &
						SPIE_NF) == 0)
			 cpu_relax();

	mpc83xx_spi->count -= 1;
	if (mpc83xx_spi->count) {
		u32 word = mpc83xx_spi->get_tx(mpc83xx_spi);
		mpc83xx_spi_write_reg(&mpc83xx_spi->base->transmit, word);
	} else {
		complete(&mpc83xx_spi->done);
	}

	/* Clear the events */
	mpc83xx_spi_write_reg(&mpc83xx_spi->base->event, event);

	return ret;
}

static int __init mpc83xx_spi_probe(struct platform_device *dev)
{
	struct spi_master *master;
	struct mpc83xx_spi *mpc83xx_spi;
	struct fsl_spi_platform_data *pdata;
	struct resource *r;
	u32 regval;
	int ret = 0;

	/* Get resources(memory, IRQ) associated with the device */
	master = spi_alloc_master(&dev->dev, sizeof(struct mpc83xx_spi));

	if (master == NULL) {
		ret = -ENOMEM;
		goto err;
	}

	platform_set_drvdata(dev, master);
	pdata = dev->dev.platform_data;

	if (pdata == NULL) {
		ret = -ENODEV;
		goto free_master;
	}

	r = platform_get_resource(dev, IORESOURCE_MEM, 0);
	if (r == NULL) {
		ret = -ENODEV;
		goto free_master;
	}
	mpc83xx_spi = spi_master_get_devdata(master);
	mpc83xx_spi->bitbang.master = spi_master_get(master);
	mpc83xx_spi->bitbang.chipselect = mpc83xx_spi_chipselect;
	mpc83xx_spi->bitbang.setup_transfer = mpc83xx_spi_setup_transfer;
	mpc83xx_spi->bitbang.txrx_bufs = mpc83xx_spi_bufs;
	mpc83xx_spi->activate_cs = pdata->activate_cs;
	mpc83xx_spi->deactivate_cs = pdata->deactivate_cs;
	mpc83xx_spi->qe_mode = pdata->qe_mode;
	mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8;
	mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8;
	mpc83xx_spi->spibrg = pdata->sysclk;

	mpc83xx_spi->rx_shift = 0;
	mpc83xx_spi->tx_shift = 0;
	if (mpc83xx_spi->qe_mode) {
		mpc83xx_spi->rx_shift = 16;
		mpc83xx_spi->tx_shift = 24;
	}

	mpc83xx_spi->bitbang.master->setup = mpc83xx_spi_setup;
	init_completion(&mpc83xx_spi->done);

	mpc83xx_spi->base = ioremap(r->start, r->end - r->start + 1);
	if (mpc83xx_spi->base == NULL) {
		ret = -ENOMEM;
		goto put_master;
	}

	mpc83xx_spi->irq = platform_get_irq(dev, 0);

	if (mpc83xx_spi->irq < 0) {
		ret = -ENXIO;
		goto unmap_io;
	}

	/* Register for SPI Interrupt */
	ret = request_irq(mpc83xx_spi->irq, mpc83xx_spi_irq,
			  0, "mpc83xx_spi", mpc83xx_spi);

	if (ret != 0)
		goto unmap_io;

	master->bus_num = pdata->bus_num;
	master->num_chipselect = pdata->max_chipselect;

	/* SPI controller initializations */
	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, 0);
	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mask, 0);
	mpc83xx_spi_write_reg(&mpc83xx_spi->base->command, 0);
	mpc83xx_spi_write_reg(&mpc83xx_spi->base->event, 0xffffffff);

	/* Enable SPI interface */
	regval = pdata->initial_spmode | SPMODE_INIT_VAL | SPMODE_ENABLE;
	if (pdata->qe_mode)
		regval |= SPMODE_OP;

	mpc83xx_spi_write_reg(&mpc83xx_spi->base->mode, regval);

	ret = spi_bitbang_start(&mpc83xx_spi->bitbang);

	if (ret != 0)
		goto free_irq;

	printk(KERN_INFO
	       "%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n",
	       dev->dev.bus_id, mpc83xx_spi->base, mpc83xx_spi->irq);

	return ret;

free_irq:
	free_irq(mpc83xx_spi->irq, mpc83xx_spi);
unmap_io:
	iounmap(mpc83xx_spi->base);
put_master:
	spi_master_put(master);
free_master:
	kfree(master);
err:
	return ret;
}

static int __exit mpc83xx_spi_remove(struct platform_device *dev)
{
	struct mpc83xx_spi *mpc83xx_spi;
	struct spi_master *master;

	master = platform_get_drvdata(dev);
	mpc83xx_spi = spi_master_get_devdata(master);

	spi_bitbang_stop(&mpc83xx_spi->bitbang);
	free_irq(mpc83xx_spi->irq, mpc83xx_spi);
	iounmap(mpc83xx_spi->base);
	spi_master_put(mpc83xx_spi->bitbang.master);

	return 0;
}

MODULE_ALIAS("mpc83xx_spi");			/* for platform bus hotplug */
static struct platform_driver mpc83xx_spi_driver = {
	.remove = __exit_p(mpc83xx_spi_remove),
	.driver = {
		   .name = "mpc83xx_spi",
	},
};

static int __init mpc83xx_spi_init(void)
{
	return platform_driver_probe(&mpc83xx_spi_driver, mpc83xx_spi_probe);
}

static void __exit mpc83xx_spi_exit(void)
{
	platform_driver_unregister(&mpc83xx_spi_driver);
}

module_init(mpc83xx_spi_init);
module_exit(mpc83xx_spi_exit);

MODULE_AUTHOR("Kumar Gala");
MODULE_DESCRIPTION("Simple MPC83xx SPI Driver");
MODULE_LICENSE("GPL");
