/*
 * Sequencer Serial Port (SSP) driver for Texas Instruments' SoCs
 *
 * 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/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/clk.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <linux/spinlock.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/mfd/core.h>
#include <linux/mfd/ti_ssp.h>

/* Register Offsets */
#define REG_REV		0x00
#define REG_IOSEL_1	0x04
#define REG_IOSEL_2	0x08
#define REG_PREDIV	0x0c
#define REG_INTR_ST	0x10
#define REG_INTR_EN	0x14
#define REG_TEST_CTRL	0x18

/* Per port registers */
#define PORT_CFG_2	0x00
#define PORT_ADDR	0x04
#define PORT_DATA	0x08
#define PORT_CFG_1	0x0c
#define PORT_STATE	0x10

#define SSP_PORT_CONFIG_MASK	(SSP_EARLY_DIN | SSP_DELAY_DOUT)
#define SSP_PORT_CLKRATE_MASK	0x0f

#define SSP_SEQRAM_WR_EN	BIT(4)
#define SSP_SEQRAM_RD_EN	BIT(5)
#define SSP_START		BIT(15)
#define SSP_BUSY		BIT(10)
#define SSP_PORT_ASL		BIT(7)
#define SSP_PORT_CFO1		BIT(6)

#define SSP_PORT_SEQRAM_SIZE	32

static const int ssp_port_base[]   = {0x040, 0x080};
static const int ssp_port_seqram[] = {0x100, 0x180};

struct ti_ssp {
	struct resource		*res;
	struct device		*dev;
	void __iomem		*regs;
	spinlock_t		lock;
	struct clk		*clk;
	int			irq;
	wait_queue_head_t	wqh;

	/*
	 * Some of the iosel2 register bits always read-back as 0, we need to
	 * remember these values so that we don't clobber previously set
	 * values.
	 */
	u32			iosel2;
};

static inline struct ti_ssp *dev_to_ssp(struct device *dev)
{
	return dev_get_drvdata(dev->parent);
}

static inline int dev_to_port(struct device *dev)
{
	return to_platform_device(dev)->id;
}

/* Register Access Helpers, rmw() functions need to run locked */
static inline u32 ssp_read(struct ti_ssp *ssp, int reg)
{
	return __raw_readl(ssp->regs + reg);
}

static inline void ssp_write(struct ti_ssp *ssp, int reg, u32 val)
{
	__raw_writel(val, ssp->regs + reg);
}

static inline void ssp_rmw(struct ti_ssp *ssp, int reg, u32 mask, u32 bits)
{
	ssp_write(ssp, reg, (ssp_read(ssp, reg) & ~mask) | bits);
}

static inline u32 ssp_port_read(struct ti_ssp *ssp, int port, int reg)
{
	return ssp_read(ssp, ssp_port_base[port] + reg);
}

static inline void ssp_port_write(struct ti_ssp *ssp, int port, int reg,
				  u32 val)
{
	ssp_write(ssp, ssp_port_base[port] + reg, val);
}

static inline void ssp_port_rmw(struct ti_ssp *ssp, int port, int reg,
				u32 mask, u32 bits)
{
	ssp_rmw(ssp, ssp_port_base[port] + reg, mask, bits);
}

static inline void ssp_port_clr_bits(struct ti_ssp *ssp, int port, int reg,
				     u32 bits)
{
	ssp_port_rmw(ssp, port, reg, bits, 0);
}

static inline void ssp_port_set_bits(struct ti_ssp *ssp, int port, int reg,
				     u32 bits)
{
	ssp_port_rmw(ssp, port, reg, 0, bits);
}

/* Called to setup port clock mode, caller must hold ssp->lock */
static int __set_mode(struct ti_ssp *ssp, int port, int mode)
{
	mode &= SSP_PORT_CONFIG_MASK;
	ssp_port_rmw(ssp, port, PORT_CFG_1, SSP_PORT_CONFIG_MASK, mode);

	return 0;
}

int ti_ssp_set_mode(struct device *dev, int mode)
{
	struct ti_ssp *ssp = dev_to_ssp(dev);
	int port = dev_to_port(dev);
	int ret;

	spin_lock(&ssp->lock);
	ret = __set_mode(ssp, port, mode);
	spin_unlock(&ssp->lock);

	return ret;
}
EXPORT_SYMBOL(ti_ssp_set_mode);

/* Called to setup iosel2, caller must hold ssp->lock */
static void __set_iosel2(struct ti_ssp *ssp, u32 mask, u32 val)
{
	ssp->iosel2 = (ssp->iosel2 & ~mask) | val;
	ssp_write(ssp, REG_IOSEL_2, ssp->iosel2);
}

/* Called to setup port iosel, caller must hold ssp->lock */
static void __set_iosel(struct ti_ssp *ssp, int port, u32 iosel)
{
	unsigned val, shift = port ? 16 : 0;

	/* IOSEL1 gets the least significant 16 bits */
	val = ssp_read(ssp, REG_IOSEL_1);
	val &= 0xffff << (port ? 0 : 16);
	val |= (iosel & 0xffff) << (port ? 16 : 0);
	ssp_write(ssp, REG_IOSEL_1, val);

	/* IOSEL2 gets the most significant 16 bits */
	val = (iosel >> 16) & 0x7;
	__set_iosel2(ssp, 0x7 << shift, val << shift);
}

int ti_ssp_set_iosel(struct device *dev, u32 iosel)
{
	struct ti_ssp *ssp = dev_to_ssp(dev);
	int port = dev_to_port(dev);

	spin_lock(&ssp->lock);
	__set_iosel(ssp, port, iosel);
	spin_unlock(&ssp->lock);

	return 0;
}
EXPORT_SYMBOL(ti_ssp_set_iosel);

int ti_ssp_load(struct device *dev, int offs, u32* prog, int len)
{
	struct ti_ssp *ssp = dev_to_ssp(dev);
	int port = dev_to_port(dev);
	int i;

	if (len > SSP_PORT_SEQRAM_SIZE)
		return -ENOSPC;

	spin_lock(&ssp->lock);

	/* Enable SeqRAM access */
	ssp_port_set_bits(ssp, port, PORT_CFG_2, SSP_SEQRAM_WR_EN);

	/* Copy code */
	for (i = 0; i < len; i++) {
		__raw_writel(prog[i], ssp->regs + offs + 4*i +
			     ssp_port_seqram[port]);
	}

	/* Disable SeqRAM access */
	ssp_port_clr_bits(ssp, port, PORT_CFG_2, SSP_SEQRAM_WR_EN);

	spin_unlock(&ssp->lock);

	return 0;
}
EXPORT_SYMBOL(ti_ssp_load);

int ti_ssp_raw_read(struct device *dev)
{
	struct ti_ssp *ssp = dev_to_ssp(dev);
	int port = dev_to_port(dev);
	int shift = port ? 27 : 11;

	return (ssp_read(ssp, REG_IOSEL_2) >> shift) & 0xf;
}
EXPORT_SYMBOL(ti_ssp_raw_read);

int ti_ssp_raw_write(struct device *dev, u32 val)
{
	struct ti_ssp *ssp = dev_to_ssp(dev);
	int port = dev_to_port(dev), shift;

	spin_lock(&ssp->lock);

	shift = port ? 22 : 6;
	val &= 0xf;
	__set_iosel2(ssp, 0xf << shift, val << shift);

	spin_unlock(&ssp->lock);

	return 0;
}
EXPORT_SYMBOL(ti_ssp_raw_write);

static inline int __xfer_done(struct ti_ssp *ssp, int port)
{
	return !(ssp_port_read(ssp, port, PORT_CFG_1) & SSP_BUSY);
}

int ti_ssp_run(struct device *dev, u32 pc, u32 input, u32 *output)
{
	struct ti_ssp *ssp = dev_to_ssp(dev);
	int port = dev_to_port(dev);
	int ret;

	if (pc & ~(0x3f))
		return -EINVAL;

	/* Grab ssp->lock to serialize rmw on ssp registers */
	spin_lock(&ssp->lock);

	ssp_port_write(ssp, port, PORT_ADDR, input >> 16);
	ssp_port_write(ssp, port, PORT_DATA, input & 0xffff);
	ssp_port_rmw(ssp, port, PORT_CFG_1, 0x3f, pc);

	/* grab wait queue head lock to avoid race with the isr */
	spin_lock_irq(&ssp->wqh.lock);

	/* kick off sequence execution in hardware */
	ssp_port_set_bits(ssp, port, PORT_CFG_1, SSP_START);

	/* drop ssp lock; no register writes beyond this */
	spin_unlock(&ssp->lock);

	ret = wait_event_interruptible_locked_irq(ssp->wqh,
						  __xfer_done(ssp, port));
	spin_unlock_irq(&ssp->wqh.lock);

	if (ret < 0)
		return ret;

	if (output) {
		*output = (ssp_port_read(ssp, port, PORT_ADDR) << 16) |
			  (ssp_port_read(ssp, port, PORT_DATA) &  0xffff);
	}

	ret = ssp_port_read(ssp, port, PORT_STATE) & 0x3f; /* stop address */

	return ret;
}
EXPORT_SYMBOL(ti_ssp_run);

static irqreturn_t ti_ssp_interrupt(int irq, void *dev_data)
{
	struct ti_ssp *ssp = dev_data;

	spin_lock(&ssp->wqh.lock);

	ssp_write(ssp, REG_INTR_ST, 0x3);
	wake_up_locked(&ssp->wqh);

	spin_unlock(&ssp->wqh.lock);

	return IRQ_HANDLED;
}

static int __devinit ti_ssp_probe(struct platform_device *pdev)
{
	static struct ti_ssp *ssp;
	const struct ti_ssp_data *pdata = pdev->dev.platform_data;
	int error = 0, prediv = 0xff, id;
	unsigned long sysclk;
	struct device *dev = &pdev->dev;
	struct mfd_cell cells[2];

	ssp = kzalloc(sizeof(*ssp), GFP_KERNEL);
	if (!ssp) {
		dev_err(dev, "cannot allocate device info\n");
		return -ENOMEM;
	}

	ssp->dev = dev;
	dev_set_drvdata(dev, ssp);

	ssp->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!ssp->res) {
		error = -ENODEV;
		dev_err(dev, "cannot determine register area\n");
		goto error_res;
	}

	if (!request_mem_region(ssp->res->start, resource_size(ssp->res),
				pdev->name)) {
		error = -ENOMEM;
		dev_err(dev, "cannot claim register memory\n");
		goto error_res;
	}

	ssp->regs = ioremap(ssp->res->start, resource_size(ssp->res));
	if (!ssp->regs) {
		error = -ENOMEM;
		dev_err(dev, "cannot map register memory\n");
		goto error_map;
	}

	ssp->clk = clk_get(dev, NULL);
	if (IS_ERR(ssp->clk)) {
		error = PTR_ERR(ssp->clk);
		dev_err(dev, "cannot claim device clock\n");
		goto error_clk;
	}

	ssp->irq = platform_get_irq(pdev, 0);
	if (ssp->irq < 0) {
		error = -ENODEV;
		dev_err(dev, "unknown irq\n");
		goto error_irq;
	}

	error = request_threaded_irq(ssp->irq, NULL, ti_ssp_interrupt, 0,
				     dev_name(dev), ssp);
	if (error < 0) {
		dev_err(dev, "cannot acquire irq\n");
		goto error_irq;
	}

	spin_lock_init(&ssp->lock);
	init_waitqueue_head(&ssp->wqh);

	/* Power on and initialize SSP */
	error = clk_enable(ssp->clk);
	if (error) {
		dev_err(dev, "cannot enable device clock\n");
		goto error_enable;
	}

	/* Reset registers to a sensible known state */
	ssp_write(ssp, REG_IOSEL_1, 0);
	ssp_write(ssp, REG_IOSEL_2, 0);
	ssp_write(ssp, REG_INTR_EN, 0x3);
	ssp_write(ssp, REG_INTR_ST, 0x3);
	ssp_write(ssp, REG_TEST_CTRL, 0);
	ssp_port_write(ssp, 0, PORT_CFG_1, SSP_PORT_ASL);
	ssp_port_write(ssp, 1, PORT_CFG_1, SSP_PORT_ASL);
	ssp_port_write(ssp, 0, PORT_CFG_2, SSP_PORT_CFO1);
	ssp_port_write(ssp, 1, PORT_CFG_2, SSP_PORT_CFO1);

	sysclk = clk_get_rate(ssp->clk);
	if (pdata && pdata->out_clock)
		prediv = (sysclk / pdata->out_clock) - 1;
	prediv = clamp(prediv, 0, 0xff);
	ssp_rmw(ssp, REG_PREDIV, 0xff, prediv);

	memset(cells, 0, sizeof(cells));
	for (id = 0; id < 2; id++) {
		const struct ti_ssp_dev_data *data = &pdata->dev_data[id];

		cells[id].id		= id;
		cells[id].name		= data->dev_name;
		cells[id].platform_data	= data->pdata;
		cells[id].data_size	= data->pdata_size;
	}

	error = mfd_add_devices(dev, 0, cells, 2, NULL, 0);
	if (error < 0) {
		dev_err(dev, "cannot add mfd cells\n");
		goto error_enable;
	}

	return 0;

error_enable:
	free_irq(ssp->irq, ssp);
error_irq:
	clk_put(ssp->clk);
error_clk:
	iounmap(ssp->regs);
error_map:
	release_mem_region(ssp->res->start, resource_size(ssp->res));
error_res:
	kfree(ssp);
	return error;
}

static int __devexit ti_ssp_remove(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct ti_ssp *ssp = dev_get_drvdata(dev);

	mfd_remove_devices(dev);
	clk_disable(ssp->clk);
	free_irq(ssp->irq, ssp);
	clk_put(ssp->clk);
	iounmap(ssp->regs);
	release_mem_region(ssp->res->start, resource_size(ssp->res));
	kfree(ssp);
	dev_set_drvdata(dev, NULL);
	return 0;
}

static struct platform_driver ti_ssp_driver = {
	.probe		= ti_ssp_probe,
	.remove		= __devexit_p(ti_ssp_remove),
	.driver		= {
		.name	= "ti-ssp",
		.owner	= THIS_MODULE,
	}
};

static int __init ti_ssp_init(void)
{
	return platform_driver_register(&ti_ssp_driver);
}
module_init(ti_ssp_init);

static void __exit ti_ssp_exit(void)
{
	platform_driver_unregister(&ti_ssp_driver);
}
module_exit(ti_ssp_exit);

MODULE_DESCRIPTION("Sequencer Serial Port (SSP) Driver");
MODULE_AUTHOR("Cyril Chemparathy");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:ti-ssp");
