/*
 * MPC52xx PSC in SPI mode driver.
 *
 * Maintainer: Dragos Carp
 *
 * Copyright (C) 2006 TOPTICA Photonics AG.
 *
 * 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/errno.h>
#include <linux/interrupt.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/workqueue.h>
#include <linux/completion.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/spi/spi.h>
#include <linux/fsl_devices.h>
#include <linux/slab.h>

#include <asm/mpc52xx.h>
#include <asm/mpc52xx_psc.h>

#define MCLK 20000000 /* PSC port MClk in hz */

struct mpc52xx_psc_spi {
	/* fsl_spi_platform data */
	void (*cs_control)(struct spi_device *spi, bool on);
	u32 sysclk;

	/* driver internal data */
	struct mpc52xx_psc __iomem *psc;
	struct mpc52xx_psc_fifo __iomem *fifo;
	unsigned int irq;
	u8 bits_per_word;
	u8 busy;

	struct workqueue_struct *workqueue;
	struct work_struct work;

	struct list_head queue;
	spinlock_t lock;

	struct completion done;
};

/* controller state */
struct mpc52xx_psc_spi_cs {
	int bits_per_word;
	int speed_hz;
};

/* set clock freq, clock ramp, bits per work
 * if t is NULL then reset the values to the default values
 */
static int mpc52xx_psc_spi_transfer_setup(struct spi_device *spi,
		struct spi_transfer *t)
{
	struct mpc52xx_psc_spi_cs *cs = spi->controller_state;

	cs->speed_hz = (t && t->speed_hz)
			? t->speed_hz : spi->max_speed_hz;
	cs->bits_per_word = (t && t->bits_per_word)
			? t->bits_per_word : spi->bits_per_word;
	cs->bits_per_word = ((cs->bits_per_word + 7) / 8) * 8;
	return 0;
}

static void mpc52xx_psc_spi_activate_cs(struct spi_device *spi)
{
	struct mpc52xx_psc_spi_cs *cs = spi->controller_state;
	struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master);
	struct mpc52xx_psc __iomem *psc = mps->psc;
	u32 sicr;
	u16 ccr;

	sicr = in_be32(&psc->sicr);

	/* Set clock phase and polarity */
	if (spi->mode & SPI_CPHA)
		sicr |= 0x00001000;
	else
		sicr &= ~0x00001000;
	if (spi->mode & SPI_CPOL)
		sicr |= 0x00002000;
	else
		sicr &= ~0x00002000;

	if (spi->mode & SPI_LSB_FIRST)
		sicr |= 0x10000000;
	else
		sicr &= ~0x10000000;
	out_be32(&psc->sicr, sicr);

	/* Set clock frequency and bits per word
	 * Because psc->ccr is defined as 16bit register instead of 32bit
	 * just set the lower byte of BitClkDiv
	 */
	ccr = in_be16((u16 __iomem *)&psc->ccr);
	ccr &= 0xFF00;
	if (cs->speed_hz)
		ccr |= (MCLK / cs->speed_hz - 1) & 0xFF;
	else /* by default SPI Clk 1MHz */
		ccr |= (MCLK / 1000000 - 1) & 0xFF;
	out_be16((u16 __iomem *)&psc->ccr, ccr);
	mps->bits_per_word = cs->bits_per_word;

	if (mps->cs_control)
		mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 1 : 0);
}

static void mpc52xx_psc_spi_deactivate_cs(struct spi_device *spi)
{
	struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master);

	if (mps->cs_control)
		mps->cs_control(spi, (spi->mode & SPI_CS_HIGH) ? 0 : 1);
}

#define MPC52xx_PSC_BUFSIZE (MPC52xx_PSC_RFNUM_MASK + 1)
/* wake up when 80% fifo full */
#define MPC52xx_PSC_RFALARM (MPC52xx_PSC_BUFSIZE * 20 / 100)

static int mpc52xx_psc_spi_transfer_rxtx(struct spi_device *spi,
						struct spi_transfer *t)
{
	struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master);
	struct mpc52xx_psc __iomem *psc = mps->psc;
	struct mpc52xx_psc_fifo __iomem *fifo = mps->fifo;
	unsigned rb = 0;	/* number of bytes receieved */
	unsigned sb = 0;	/* number of bytes sent */
	unsigned char *rx_buf = (unsigned char *)t->rx_buf;
	unsigned char *tx_buf = (unsigned char *)t->tx_buf;
	unsigned rfalarm;
	unsigned send_at_once = MPC52xx_PSC_BUFSIZE;
	unsigned recv_at_once;
	int last_block = 0;

	if (!t->tx_buf && !t->rx_buf && t->len)
		return -EINVAL;

	/* enable transmiter/receiver */
	out_8(&psc->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE);
	while (rb < t->len) {
		if (t->len - rb > MPC52xx_PSC_BUFSIZE) {
			rfalarm = MPC52xx_PSC_RFALARM;
			last_block = 0;
		} else {
			send_at_once = t->len - sb;
			rfalarm = MPC52xx_PSC_BUFSIZE - (t->len - rb);
			last_block = 1;
		}

		dev_dbg(&spi->dev, "send %d bytes...\n", send_at_once);
		for (; send_at_once; sb++, send_at_once--) {
			/* set EOF flag before the last word is sent */
			if (send_at_once == 1 && last_block)
				out_8(&psc->ircr2, 0x01);

			if (tx_buf)
				out_8(&psc->mpc52xx_psc_buffer_8, tx_buf[sb]);
			else
				out_8(&psc->mpc52xx_psc_buffer_8, 0);
		}


		/* enable interrupts and wait for wake up
		 * if just one byte is expected the Rx FIFO genererates no
		 * FFULL interrupt, so activate the RxRDY interrupt
		 */
		out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);
		if (t->len - rb == 1) {
			out_8(&psc->mode, 0);
		} else {
			out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL);
			out_be16(&fifo->rfalarm, rfalarm);
		}
		out_be16(&psc->mpc52xx_psc_imr, MPC52xx_PSC_IMR_RXRDY);
		wait_for_completion(&mps->done);
		recv_at_once = in_be16(&fifo->rfnum);
		dev_dbg(&spi->dev, "%d bytes received\n", recv_at_once);

		send_at_once = recv_at_once;
		if (rx_buf) {
			for (; recv_at_once; rb++, recv_at_once--)
				rx_buf[rb] = in_8(&psc->mpc52xx_psc_buffer_8);
		} else {
			for (; recv_at_once; rb++, recv_at_once--)
				in_8(&psc->mpc52xx_psc_buffer_8);
		}
	}
	/* disable transmiter/receiver */
	out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);

	return 0;
}

static void mpc52xx_psc_spi_work(struct work_struct *work)
{
	struct mpc52xx_psc_spi *mps =
		container_of(work, struct mpc52xx_psc_spi, work);

	spin_lock_irq(&mps->lock);
	mps->busy = 1;
	while (!list_empty(&mps->queue)) {
		struct spi_message *m;
		struct spi_device *spi;
		struct spi_transfer *t = NULL;
		unsigned cs_change;
		int status;

		m = container_of(mps->queue.next, struct spi_message, queue);
		list_del_init(&m->queue);
		spin_unlock_irq(&mps->lock);

		spi = m->spi;
		cs_change = 1;
		status = 0;
		list_for_each_entry (t, &m->transfers, transfer_list) {
			if (t->bits_per_word || t->speed_hz) {
				status = mpc52xx_psc_spi_transfer_setup(spi, t);
				if (status < 0)
					break;
			}

			if (cs_change)
				mpc52xx_psc_spi_activate_cs(spi);
			cs_change = t->cs_change;

			status = mpc52xx_psc_spi_transfer_rxtx(spi, t);
			if (status)
				break;
			m->actual_length += t->len;

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

			if (cs_change)
				mpc52xx_psc_spi_deactivate_cs(spi);
		}

		m->status = status;
		m->complete(m->context);

		if (status || !cs_change)
			mpc52xx_psc_spi_deactivate_cs(spi);

		mpc52xx_psc_spi_transfer_setup(spi, NULL);

		spin_lock_irq(&mps->lock);
	}
	mps->busy = 0;
	spin_unlock_irq(&mps->lock);
}

static int mpc52xx_psc_spi_setup(struct spi_device *spi)
{
	struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master);
	struct mpc52xx_psc_spi_cs *cs = spi->controller_state;
	unsigned long flags;

	if (spi->bits_per_word%8)
		return -EINVAL;

	if (!cs) {
		cs = kzalloc(sizeof *cs, GFP_KERNEL);
		if (!cs)
			return -ENOMEM;
		spi->controller_state = cs;
	}

	cs->bits_per_word = spi->bits_per_word;
	cs->speed_hz = spi->max_speed_hz;

	spin_lock_irqsave(&mps->lock, flags);
	if (!mps->busy)
		mpc52xx_psc_spi_deactivate_cs(spi);
	spin_unlock_irqrestore(&mps->lock, flags);

	return 0;
}

static int mpc52xx_psc_spi_transfer(struct spi_device *spi,
		struct spi_message *m)
{
	struct mpc52xx_psc_spi *mps = spi_master_get_devdata(spi->master);
	unsigned long flags;

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

	spin_lock_irqsave(&mps->lock, flags);
	list_add_tail(&m->queue, &mps->queue);
	queue_work(mps->workqueue, &mps->work);
	spin_unlock_irqrestore(&mps->lock, flags);

	return 0;
}

static void mpc52xx_psc_spi_cleanup(struct spi_device *spi)
{
	kfree(spi->controller_state);
}

static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
{
	struct mpc52xx_psc __iomem *psc = mps->psc;
	struct mpc52xx_psc_fifo __iomem *fifo = mps->fifo;
	u32 mclken_div;
	int ret;

	/* default sysclk is 512MHz */
	mclken_div = (mps->sysclk ? mps->sysclk : 512000000) / MCLK;
	ret = mpc52xx_set_psc_clkdiv(psc_id, mclken_div);
	if (ret)
		return ret;

	/* Reset the PSC into a known state */
	out_8(&psc->command, MPC52xx_PSC_RST_RX);
	out_8(&psc->command, MPC52xx_PSC_RST_TX);
	out_8(&psc->command, MPC52xx_PSC_TX_DISABLE | MPC52xx_PSC_RX_DISABLE);

	/* Disable interrupts, interrupts are based on alarm level */
	out_be16(&psc->mpc52xx_psc_imr, 0);
	out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);
	out_8(&fifo->rfcntl, 0);
	out_8(&psc->mode, MPC52xx_PSC_MODE_FFULL);

	/* Configure 8bit codec mode as a SPI master and use EOF flags */
	/* SICR_SIM_CODEC8|SICR_GENCLK|SICR_SPI|SICR_MSTR|SICR_USEEOF */
	out_be32(&psc->sicr, 0x0180C800);
	out_be16((u16 __iomem *)&psc->ccr, 0x070F); /* default SPI Clk 1MHz */

	/* Set 2ms DTL delay */
	out_8(&psc->ctur, 0x00);
	out_8(&psc->ctlr, 0x84);

	mps->bits_per_word = 8;

	return 0;
}

static irqreturn_t mpc52xx_psc_spi_isr(int irq, void *dev_id)
{
	struct mpc52xx_psc_spi *mps = (struct mpc52xx_psc_spi *)dev_id;
	struct mpc52xx_psc __iomem *psc = mps->psc;

	/* disable interrupt and wake up the work queue */
	if (in_be16(&psc->mpc52xx_psc_isr) & MPC52xx_PSC_IMR_RXRDY) {
		out_be16(&psc->mpc52xx_psc_imr, 0);
		complete(&mps->done);
		return IRQ_HANDLED;
	}
	return IRQ_NONE;
}

/* bus_num is used only for the case dev->platform_data == NULL */
static int __devinit mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
				u32 size, unsigned int irq, s16 bus_num)
{
	struct fsl_spi_platform_data *pdata = dev->platform_data;
	struct mpc52xx_psc_spi *mps;
	struct spi_master *master;
	int ret;

	master = spi_alloc_master(dev, sizeof *mps);
	if (master == NULL)
		return -ENOMEM;

	dev_set_drvdata(dev, master);
	mps = spi_master_get_devdata(master);

	/* the spi->mode bits understood by this driver: */
	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;

	mps->irq = irq;
	if (pdata == NULL) {
		dev_warn(dev, "probe called without platform data, no "
				"cs_control function will be called\n");
		mps->cs_control = NULL;
		mps->sysclk = 0;
		master->bus_num = bus_num;
		master->num_chipselect = 255;
	} else {
		mps->cs_control = pdata->cs_control;
		mps->sysclk = pdata->sysclk;
		master->bus_num = pdata->bus_num;
		master->num_chipselect = pdata->max_chipselect;
	}
	master->setup = mpc52xx_psc_spi_setup;
	master->transfer = mpc52xx_psc_spi_transfer;
	master->cleanup = mpc52xx_psc_spi_cleanup;
	master->dev.of_node = dev->of_node;

	mps->psc = ioremap(regaddr, size);
	if (!mps->psc) {
		dev_err(dev, "could not ioremap I/O port range\n");
		ret = -EFAULT;
		goto free_master;
	}
	/* On the 5200, fifo regs are immediately ajacent to the psc regs */
	mps->fifo = ((void __iomem *)mps->psc) + sizeof(struct mpc52xx_psc);

	ret = request_irq(mps->irq, mpc52xx_psc_spi_isr, 0, "mpc52xx-psc-spi",
				mps);
	if (ret)
		goto free_master;

	ret = mpc52xx_psc_spi_port_config(master->bus_num, mps);
	if (ret < 0) {
		dev_err(dev, "can't configure PSC! Is it capable of SPI?\n");
		goto free_irq;
	}

	spin_lock_init(&mps->lock);
	init_completion(&mps->done);
	INIT_WORK(&mps->work, mpc52xx_psc_spi_work);
	INIT_LIST_HEAD(&mps->queue);

	mps->workqueue = create_singlethread_workqueue(
		dev_name(master->dev.parent));
	if (mps->workqueue == NULL) {
		ret = -EBUSY;
		goto free_irq;
	}

	ret = spi_register_master(master);
	if (ret < 0)
		goto unreg_master;

	return ret;

unreg_master:
	destroy_workqueue(mps->workqueue);
free_irq:
	free_irq(mps->irq, mps);
free_master:
	if (mps->psc)
		iounmap(mps->psc);
	spi_master_put(master);

	return ret;
}

static int __devinit mpc52xx_psc_spi_of_probe(struct platform_device *op)
{
	const u32 *regaddr_p;
	u64 regaddr64, size64;
	s16 id = -1;

	regaddr_p = of_get_address(op->dev.of_node, 0, &size64, NULL);
	if (!regaddr_p) {
		dev_err(&op->dev, "Invalid PSC address\n");
		return -EINVAL;
	}
	regaddr64 = of_translate_address(op->dev.of_node, regaddr_p);

	/* get PSC id (1..6, used by port_config) */
	if (op->dev.platform_data == NULL) {
		const u32 *psc_nump;

		psc_nump = of_get_property(op->dev.of_node, "cell-index", NULL);
		if (!psc_nump || *psc_nump > 5) {
			dev_err(&op->dev, "Invalid cell-index property\n");
			return -EINVAL;
		}
		id = *psc_nump + 1;
	}

	return mpc52xx_psc_spi_do_probe(&op->dev, (u32)regaddr64, (u32)size64,
				irq_of_parse_and_map(op->dev.of_node, 0), id);
}

static int __devexit mpc52xx_psc_spi_of_remove(struct platform_device *op)
{
	struct spi_master *master = dev_get_drvdata(&op->dev);
	struct mpc52xx_psc_spi *mps = spi_master_get_devdata(master);

	flush_workqueue(mps->workqueue);
	destroy_workqueue(mps->workqueue);
	spi_unregister_master(master);
	free_irq(mps->irq, mps);
	if (mps->psc)
		iounmap(mps->psc);

	return 0;
}

static const struct of_device_id mpc52xx_psc_spi_of_match[] = {
	{ .compatible = "fsl,mpc5200-psc-spi", },
	{ .compatible = "mpc5200-psc-spi", }, /* old */
	{}
};

MODULE_DEVICE_TABLE(of, mpc52xx_psc_spi_of_match);

static struct platform_driver mpc52xx_psc_spi_of_driver = {
	.probe = mpc52xx_psc_spi_of_probe,
	.remove = __devexit_p(mpc52xx_psc_spi_of_remove),
	.driver = {
		.name = "mpc52xx-psc-spi",
		.owner = THIS_MODULE,
		.of_match_table = mpc52xx_psc_spi_of_match,
	},
};
module_platform_driver(mpc52xx_psc_spi_of_driver);

MODULE_AUTHOR("Dragos Carp");
MODULE_DESCRIPTION("MPC52xx PSC SPI Driver");
MODULE_LICENSE("GPL");
