/*
 * TI ADC MFD driver
 *
 * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
 *
 * 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 version 2.
 *
 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
 * kind, whether express or implied; without even the implied warranty
 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/iio/iio.h>

#include <linux/mfd/ti_am335x_tscadc.h>
#include <linux/platform_data/ti_am335x_adc.h>

struct tiadc_device {
	struct ti_tscadc_dev *mfd_tscadc;
	int channels;
};

static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg)
{
	return readl(adc->mfd_tscadc->tscadc_base + reg);
}

static void tiadc_writel(struct tiadc_device *adc, unsigned int reg,
					unsigned int val)
{
	writel(val, adc->mfd_tscadc->tscadc_base + reg);
}

static void tiadc_step_config(struct tiadc_device *adc_dev)
{
	unsigned int stepconfig;
	int i, channels = 0, steps;

	/*
	 * There are 16 configurable steps and 8 analog input
	 * lines available which are shared between Touchscreen and ADC.
	 *
	 * Steps backwards i.e. from 16 towards 0 are used by ADC
	 * depending on number of input lines needed.
	 * Channel would represent which analog input
	 * needs to be given to ADC to digitalize data.
	 */

	steps = TOTAL_STEPS - adc_dev->channels;
	channels = TOTAL_CHANNELS - adc_dev->channels;

	stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;

	for (i = (steps + 1); i <= TOTAL_STEPS; i++) {
		tiadc_writel(adc_dev, REG_STEPCONFIG(i),
				stepconfig | STEPCONFIG_INP(channels));
		tiadc_writel(adc_dev, REG_STEPDELAY(i),
				STEPCONFIG_OPENDLY);
		channels++;
	}
	tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB);
}

static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
{
	struct iio_chan_spec *chan_array;
	int i;

	indio_dev->num_channels = channels;
	chan_array = kcalloc(indio_dev->num_channels,
			sizeof(struct iio_chan_spec), GFP_KERNEL);

	if (chan_array == NULL)
		return -ENOMEM;

	for (i = 0; i < (indio_dev->num_channels); i++) {
		struct iio_chan_spec *chan = chan_array + i;
		chan->type = IIO_VOLTAGE;
		chan->indexed = 1;
		chan->channel = i;
		chan->info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT;
	}

	indio_dev->channels = chan_array;

	return indio_dev->num_channels;
}

static void tiadc_channels_remove(struct iio_dev *indio_dev)
{
	kfree(indio_dev->channels);
}

static int tiadc_read_raw(struct iio_dev *indio_dev,
		struct iio_chan_spec const *chan,
		int *val, int *val2, long mask)
{
	struct tiadc_device *adc_dev = iio_priv(indio_dev);
	int i;
	unsigned int fifo1count, readx1;

	/*
	 * When the sub-system is first enabled,
	 * the sequencer will always start with the
	 * lowest step (1) and continue until step (16).
	 * For ex: If we have enabled 4 ADC channels and
	 * currently use only 1 out of them, the
	 * sequencer still configures all the 4 steps,
	 * leading to 3 unwanted data.
	 * Hence we need to flush out this data.
	 */

	fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
	for (i = 0; i < fifo1count; i++) {
		readx1 = tiadc_readl(adc_dev, REG_FIFO1);
		if (i == chan->channel)
			*val = readx1 & 0xfff;
	}
	tiadc_writel(adc_dev, REG_SE, STPENB_STEPENB);

	return IIO_VAL_INT;
}

static const struct iio_info tiadc_info = {
	.read_raw = &tiadc_read_raw,
};

static int __devinit tiadc_probe(struct platform_device *pdev)
{
	struct iio_dev		*indio_dev;
	struct tiadc_device	*adc_dev;
	struct ti_tscadc_dev	*tscadc_dev = pdev->dev.platform_data;
	struct mfd_tscadc_board	*pdata;
	int			err;

	pdata = tscadc_dev->dev->platform_data;
	if (!pdata || !pdata->adc_init) {
		dev_err(&pdev->dev, "Could not find platform data\n");
		return -EINVAL;
	}

	indio_dev = iio_device_alloc(sizeof(struct tiadc_device));
	if (indio_dev == NULL) {
		dev_err(&pdev->dev, "failed to allocate iio device\n");
		err = -ENOMEM;
		goto err_ret;
	}
	adc_dev = iio_priv(indio_dev);

	adc_dev->mfd_tscadc = tscadc_dev;
	adc_dev->channels = pdata->adc_init->adc_channels;

	indio_dev->dev.parent = &pdev->dev;
	indio_dev->name = dev_name(&pdev->dev);
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->info = &tiadc_info;

	tiadc_step_config(adc_dev);

	err = tiadc_channel_init(indio_dev, adc_dev->channels);
	if (err < 0)
		goto err_free_device;

	err = iio_device_register(indio_dev);
	if (err)
		goto err_free_channels;

	platform_set_drvdata(pdev, indio_dev);

	return 0;

err_free_channels:
	tiadc_channels_remove(indio_dev);
err_free_device:
	iio_device_free(indio_dev);
err_ret:
	return err;
}

static int __devexit tiadc_remove(struct platform_device *pdev)
{
	struct iio_dev *indio_dev = platform_get_drvdata(pdev);

	iio_device_unregister(indio_dev);
	tiadc_channels_remove(indio_dev);

	iio_device_free(indio_dev);

	return 0;
}

#ifdef CONFIG_PM
static int tiadc_suspend(struct device *dev)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct tiadc_device *adc_dev = iio_priv(indio_dev);
	struct ti_tscadc_dev *tscadc_dev = dev->platform_data;
	unsigned int idle;

	if (!device_may_wakeup(tscadc_dev->dev)) {
		idle = tiadc_readl(adc_dev, REG_CTRL);
		idle &= ~(CNTRLREG_TSCSSENB);
		tiadc_writel(adc_dev, REG_CTRL, (idle |
				CNTRLREG_POWERDOWN));
	}

	return 0;
}

static int tiadc_resume(struct device *dev)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct tiadc_device *adc_dev = iio_priv(indio_dev);
	unsigned int restore;

	/* Make sure ADC is powered up */
	restore = tiadc_readl(adc_dev, REG_CTRL);
	restore &= ~(CNTRLREG_POWERDOWN);
	tiadc_writel(adc_dev, REG_CTRL, restore);

	tiadc_step_config(adc_dev);

	return 0;
}

static const struct dev_pm_ops tiadc_pm_ops = {
	.suspend = tiadc_suspend,
	.resume = tiadc_resume,
};
#define TIADC_PM_OPS (&tiadc_pm_ops)
#else
#define TIADC_PM_OPS NULL
#endif

static struct platform_driver tiadc_driver = {
	.driver = {
		.name   = "tiadc",
		.owner	= THIS_MODULE,
		.pm	= TIADC_PM_OPS,
	},
	.probe	= tiadc_probe,
	.remove	= __devexit_p(tiadc_remove),
};

module_platform_driver(tiadc_driver);

MODULE_DESCRIPTION("TI ADC controller driver");
MODULE_AUTHOR("Rachna Patil <rachna@ti.com>");
MODULE_LICENSE("GPL");
