/*
 * Altera SPI driver
 *
 * Copyright (C) 2008 Thomas Chou <thomas@wytron.com.tw>
 *
 * Based on spi_s3c24xx.c, which is:
 * Copyright (c) 2006 Ben Dooks
 * Copyright (c) 2006 Simtec Electronics
 *	Ben Dooks <ben@simtec.co.uk>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
#include <linux/io.h>
#include <linux/of.h>

#define DRV_NAME "spi_altera"

#define ALTERA_SPI_RXDATA	0
#define ALTERA_SPI_TXDATA	4
#define ALTERA_SPI_STATUS	8
#define ALTERA_SPI_CONTROL	12
#define ALTERA_SPI_SLAVE_SEL	20

#define ALTERA_SPI_STATUS_ROE_MSK	0x8
#define ALTERA_SPI_STATUS_TOE_MSK	0x10
#define ALTERA_SPI_STATUS_TMT_MSK	0x20
#define ALTERA_SPI_STATUS_TRDY_MSK	0x40
#define ALTERA_SPI_STATUS_RRDY_MSK	0x80
#define ALTERA_SPI_STATUS_E_MSK		0x100

#define ALTERA_SPI_CONTROL_IROE_MSK	0x8
#define ALTERA_SPI_CONTROL_ITOE_MSK	0x10
#define ALTERA_SPI_CONTROL_ITRDY_MSK	0x40
#define ALTERA_SPI_CONTROL_IRRDY_MSK	0x80
#define ALTERA_SPI_CONTROL_IE_MSK	0x100
#define ALTERA_SPI_CONTROL_SSO_MSK	0x400

struct altera_spi {
	/* bitbang has to be first */
	struct spi_bitbang bitbang;
	struct completion done;

	void __iomem *base;
	int irq;
	int len;
	int count;
	int bytes_per_word;
	unsigned long imr;

	/* data buffers */
	const unsigned char *tx;
	unsigned char *rx;
};

static inline struct altera_spi *altera_spi_to_hw(struct spi_device *sdev)
{
	return spi_master_get_devdata(sdev->master);
}

static void altera_spi_chipsel(struct spi_device *spi, int value)
{
	struct altera_spi *hw = altera_spi_to_hw(spi);

	if (spi->mode & SPI_CS_HIGH) {
		switch (value) {
		case BITBANG_CS_INACTIVE:
			writel(1 << spi->chip_select,
			       hw->base + ALTERA_SPI_SLAVE_SEL);
			hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK;
			writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
			break;

		case BITBANG_CS_ACTIVE:
			hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK;
			writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
			writel(0, hw->base + ALTERA_SPI_SLAVE_SEL);
			break;
		}
	} else {
		switch (value) {
		case BITBANG_CS_INACTIVE:
			hw->imr &= ~ALTERA_SPI_CONTROL_SSO_MSK;
			writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
			break;

		case BITBANG_CS_ACTIVE:
			writel(1 << spi->chip_select,
			       hw->base + ALTERA_SPI_SLAVE_SEL);
			hw->imr |= ALTERA_SPI_CONTROL_SSO_MSK;
			writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
			break;
		}
	}
}

static int altera_spi_setupxfer(struct spi_device *spi, struct spi_transfer *t)
{
	return 0;
}

static int altera_spi_setup(struct spi_device *spi)
{
	return 0;
}

static inline unsigned int hw_txbyte(struct altera_spi *hw, int count)
{
	if (hw->tx) {
		switch (hw->bytes_per_word) {
		case 1:
			return hw->tx[count];
		case 2:
			return (hw->tx[count * 2]
				| (hw->tx[count * 2 + 1] << 8));
		}
	}
	return 0;
}

static int altera_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
{
	struct altera_spi *hw = altera_spi_to_hw(spi);

	hw->tx = t->tx_buf;
	hw->rx = t->rx_buf;
	hw->count = 0;
	hw->bytes_per_word = (t->bits_per_word ? : spi->bits_per_word) / 8;
	hw->len = t->len / hw->bytes_per_word;

	if (hw->irq >= 0) {
		/* enable receive interrupt */
		hw->imr |= ALTERA_SPI_CONTROL_IRRDY_MSK;
		writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);

		/* send the first byte */
		writel(hw_txbyte(hw, 0), hw->base + ALTERA_SPI_TXDATA);

		wait_for_completion(&hw->done);
		/* disable receive interrupt */
		hw->imr &= ~ALTERA_SPI_CONTROL_IRRDY_MSK;
		writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
	} else {
		/* send the first byte */
		writel(hw_txbyte(hw, 0), hw->base + ALTERA_SPI_TXDATA);

		while (1) {
			unsigned int rxd;

			while (!(readl(hw->base + ALTERA_SPI_STATUS) &
				 ALTERA_SPI_STATUS_RRDY_MSK))
				cpu_relax();

			rxd = readl(hw->base + ALTERA_SPI_RXDATA);
			if (hw->rx) {
				switch (hw->bytes_per_word) {
				case 1:
					hw->rx[hw->count] = rxd;
					break;
				case 2:
					hw->rx[hw->count * 2] = rxd;
					hw->rx[hw->count * 2 + 1] = rxd >> 8;
					break;
				}
			}

			hw->count++;

			if (hw->count < hw->len)
				writel(hw_txbyte(hw, hw->count),
				       hw->base + ALTERA_SPI_TXDATA);
			else
				break;
		}

	}

	return hw->count * hw->bytes_per_word;
}

static irqreturn_t altera_spi_irq(int irq, void *dev)
{
	struct altera_spi *hw = dev;
	unsigned int rxd;

	rxd = readl(hw->base + ALTERA_SPI_RXDATA);
	if (hw->rx) {
		switch (hw->bytes_per_word) {
		case 1:
			hw->rx[hw->count] = rxd;
			break;
		case 2:
			hw->rx[hw->count * 2] = rxd;
			hw->rx[hw->count * 2 + 1] = rxd >> 8;
			break;
		}
	}

	hw->count++;

	if (hw->count < hw->len)
		writel(hw_txbyte(hw, hw->count), hw->base + ALTERA_SPI_TXDATA);
	else
		complete(&hw->done);

	return IRQ_HANDLED;
}

static int __devinit altera_spi_probe(struct platform_device *pdev)
{
	struct altera_spi_platform_data *platp = pdev->dev.platform_data;
	struct altera_spi *hw;
	struct spi_master *master;
	struct resource *res;
	int err = -ENODEV;

	master = spi_alloc_master(&pdev->dev, sizeof(struct altera_spi));
	if (!master)
		return err;

	/* setup the master state. */
	master->bus_num = pdev->id;
	master->num_chipselect = 16;
	master->mode_bits = SPI_CS_HIGH;
	master->setup = altera_spi_setup;

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

	/* setup the state for the bitbang driver */
	hw->bitbang.master = spi_master_get(master);
	if (!hw->bitbang.master)
		return err;
	hw->bitbang.setup_transfer = altera_spi_setupxfer;
	hw->bitbang.chipselect = altera_spi_chipsel;
	hw->bitbang.txrx_bufs = altera_spi_txrx;

	/* find and map our resources */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		goto exit_busy;
	if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
				     pdev->name))
		goto exit_busy;
	hw->base = devm_ioremap_nocache(&pdev->dev, res->start,
					resource_size(res));
	if (!hw->base)
		goto exit_busy;
	/* program defaults into the registers */
	hw->imr = 0;		/* disable spi interrupts */
	writel(hw->imr, hw->base + ALTERA_SPI_CONTROL);
	writel(0, hw->base + ALTERA_SPI_STATUS);	/* clear status reg */
	if (readl(hw->base + ALTERA_SPI_STATUS) & ALTERA_SPI_STATUS_RRDY_MSK)
		readl(hw->base + ALTERA_SPI_RXDATA);	/* flush rxdata */
	/* irq is optional */
	hw->irq = platform_get_irq(pdev, 0);
	if (hw->irq >= 0) {
		init_completion(&hw->done);
		err = devm_request_irq(&pdev->dev, hw->irq, altera_spi_irq, 0,
				       pdev->name, hw);
		if (err)
			goto exit;
	}
	/* find platform data */
	if (!platp)
		hw->bitbang.master->dev.of_node = pdev->dev.of_node;

	/* register our spi controller */
	err = spi_bitbang_start(&hw->bitbang);
	if (err)
		goto exit;
	dev_info(&pdev->dev, "base %p, irq %d\n", hw->base, hw->irq);

	return 0;

exit_busy:
	err = -EBUSY;
exit:
	platform_set_drvdata(pdev, NULL);
	spi_master_put(master);
	return err;
}

static int __devexit altera_spi_remove(struct platform_device *dev)
{
	struct altera_spi *hw = platform_get_drvdata(dev);
	struct spi_master *master = hw->bitbang.master;

	spi_bitbang_stop(&hw->bitbang);
	platform_set_drvdata(dev, NULL);
	spi_master_put(master);
	return 0;
}

#ifdef CONFIG_OF
static const struct of_device_id altera_spi_match[] = {
	{ .compatible = "ALTR,spi-1.0", },
	{},
};
MODULE_DEVICE_TABLE(of, altera_spi_match);
#else /* CONFIG_OF */
#define altera_spi_match NULL
#endif /* CONFIG_OF */

static struct platform_driver altera_spi_driver = {
	.probe = altera_spi_probe,
	.remove = __devexit_p(altera_spi_remove),
	.driver = {
		.name = DRV_NAME,
		.owner = THIS_MODULE,
		.pm = NULL,
		.of_match_table = altera_spi_match,
	},
};
module_platform_driver(altera_spi_driver);

MODULE_DESCRIPTION("Altera SPI driver");
MODULE_AUTHOR("Thomas Chou <thomas@wytron.com.tw>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRV_NAME);
