/*
 * Freescale MXS LRADC ADC driver
 *
 * Copyright (c) 2012 DENX Software Engineering, GmbH.
 * Copyright (c) 2017 Ksenija Stanojevic <ksenija.stanojevic@gmail.com>
 *
 * Authors:
 *  Marek Vasut <marex@denx.de>
 *  Ksenija Stanojevic <ksenija.stanojevic@gmail.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; 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.
 */

#include <linux/completion.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/mfd/core.h>
#include <linux/mfd/mxs-lradc.h>
#include <linux/module.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/sysfs.h>

#include <linux/iio/buffer.h>
#include <linux/iio/iio.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/sysfs.h>

/*
 * Make this runtime configurable if necessary. Currently, if the buffered mode
 * is enabled, the LRADC takes LRADC_DELAY_TIMER_LOOP samples of data before
 * triggering IRQ. The sampling happens every (LRADC_DELAY_TIMER_PER / 2000)
 * seconds. The result is that the samples arrive every 500mS.
 */
#define LRADC_DELAY_TIMER_PER	200
#define LRADC_DELAY_TIMER_LOOP	5

#define VREF_MV_BASE 1850

static const char *mx23_lradc_adc_irq_names[] = {
	"mxs-lradc-channel0",
	"mxs-lradc-channel1",
	"mxs-lradc-channel2",
	"mxs-lradc-channel3",
	"mxs-lradc-channel4",
	"mxs-lradc-channel5",
};

static const char *mx28_lradc_adc_irq_names[] = {
	"mxs-lradc-thresh0",
	"mxs-lradc-thresh1",
	"mxs-lradc-channel0",
	"mxs-lradc-channel1",
	"mxs-lradc-channel2",
	"mxs-lradc-channel3",
	"mxs-lradc-channel4",
	"mxs-lradc-channel5",
	"mxs-lradc-button0",
	"mxs-lradc-button1",
};

static const u32 mxs_lradc_adc_vref_mv[][LRADC_MAX_TOTAL_CHANS] = {
	[IMX23_LRADC] = {
		VREF_MV_BASE,		/* CH0 */
		VREF_MV_BASE,		/* CH1 */
		VREF_MV_BASE,		/* CH2 */
		VREF_MV_BASE,		/* CH3 */
		VREF_MV_BASE,		/* CH4 */
		VREF_MV_BASE,		/* CH5 */
		VREF_MV_BASE * 2,	/* CH6 VDDIO */
		VREF_MV_BASE * 4,	/* CH7 VBATT */
		VREF_MV_BASE,		/* CH8 Temp sense 0 */
		VREF_MV_BASE,		/* CH9 Temp sense 1 */
		VREF_MV_BASE,		/* CH10 */
		VREF_MV_BASE,		/* CH11 */
		VREF_MV_BASE,		/* CH12 USB_DP */
		VREF_MV_BASE,		/* CH13 USB_DN */
		VREF_MV_BASE,		/* CH14 VBG */
		VREF_MV_BASE * 4,	/* CH15 VDD5V */
	},
	[IMX28_LRADC] = {
		VREF_MV_BASE,		/* CH0 */
		VREF_MV_BASE,		/* CH1 */
		VREF_MV_BASE,		/* CH2 */
		VREF_MV_BASE,		/* CH3 */
		VREF_MV_BASE,		/* CH4 */
		VREF_MV_BASE,		/* CH5 */
		VREF_MV_BASE,		/* CH6 */
		VREF_MV_BASE * 4,	/* CH7 VBATT */
		VREF_MV_BASE,		/* CH8 Temp sense 0 */
		VREF_MV_BASE,		/* CH9 Temp sense 1 */
		VREF_MV_BASE * 2,	/* CH10 VDDIO */
		VREF_MV_BASE,		/* CH11 VTH */
		VREF_MV_BASE * 2,	/* CH12 VDDA */
		VREF_MV_BASE,		/* CH13 VDDD */
		VREF_MV_BASE,		/* CH14 VBG */
		VREF_MV_BASE * 4,	/* CH15 VDD5V */
	},
};

enum mxs_lradc_divbytwo {
	MXS_LRADC_DIV_DISABLED = 0,
	MXS_LRADC_DIV_ENABLED,
};

struct mxs_lradc_scale {
	unsigned int		integer;
	unsigned int		nano;
};

struct mxs_lradc_adc {
	struct mxs_lradc	*lradc;
	struct device		*dev;

	void __iomem		*base;
	/* Maximum of 8 channels + 8 byte ts */
	u32			buffer[10] __aligned(8);
	struct iio_trigger	*trig;
	struct completion	completion;
	spinlock_t		lock;

	const u32		*vref_mv;
	struct mxs_lradc_scale	scale_avail[LRADC_MAX_TOTAL_CHANS][2];
	unsigned long		is_divided;
};


/* Raw I/O operations */
static int mxs_lradc_adc_read_single(struct iio_dev *iio_dev, int chan,
				     int *val)
{
	struct mxs_lradc_adc *adc = iio_priv(iio_dev);
	struct mxs_lradc *lradc = adc->lradc;
	int ret;

	/*
	 * See if there is no buffered operation in progress. If there is simply
	 * bail out. This can be improved to support both buffered and raw IO at
	 * the same time, yet the code becomes horribly complicated. Therefore I
	 * applied KISS principle here.
	 */
	ret = iio_device_claim_direct_mode(iio_dev);
	if (ret)
		return ret;

	reinit_completion(&adc->completion);

	/*
	 * No buffered operation in progress, map the channel and trigger it.
	 * Virtual channel 0 is always used here as the others are always not
	 * used if doing raw sampling.
	 */
	if (lradc->soc == IMX28_LRADC)
		writel(LRADC_CTRL1_LRADC_IRQ_EN(0),
		       adc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
	writel(0x1, adc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);

	/* Enable / disable the divider per requirement */
	if (test_bit(chan, &adc->is_divided))
		writel(1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET,
		       adc->base + LRADC_CTRL2 + STMP_OFFSET_REG_SET);
	else
		writel(1 << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET,
		       adc->base + LRADC_CTRL2 + STMP_OFFSET_REG_CLR);

	/* Clean the slot's previous content, then set new one. */
	writel(LRADC_CTRL4_LRADCSELECT_MASK(0),
	       adc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
	writel(chan, adc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);

	writel(0, adc->base + LRADC_CH(0));

	/* Enable the IRQ and start sampling the channel. */
	writel(LRADC_CTRL1_LRADC_IRQ_EN(0),
	       adc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
	writel(BIT(0), adc->base + LRADC_CTRL0 + STMP_OFFSET_REG_SET);

	/* Wait for completion on the channel, 1 second max. */
	ret = wait_for_completion_killable_timeout(&adc->completion, HZ);
	if (!ret)
		ret = -ETIMEDOUT;
	if (ret < 0)
		goto err;

	/* Read the data. */
	*val = readl(adc->base + LRADC_CH(0)) & LRADC_CH_VALUE_MASK;
	ret = IIO_VAL_INT;

err:
	writel(LRADC_CTRL1_LRADC_IRQ_EN(0),
	       adc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);

	iio_device_release_direct_mode(iio_dev);

	return ret;
}

static int mxs_lradc_adc_read_temp(struct iio_dev *iio_dev, int *val)
{
	int ret, min, max;

	ret = mxs_lradc_adc_read_single(iio_dev, 8, &min);
	if (ret != IIO_VAL_INT)
		return ret;

	ret = mxs_lradc_adc_read_single(iio_dev, 9, &max);
	if (ret != IIO_VAL_INT)
		return ret;

	*val = max - min;

	return IIO_VAL_INT;
}

static int mxs_lradc_adc_read_raw(struct iio_dev *iio_dev,
			      const struct iio_chan_spec *chan,
			      int *val, int *val2, long m)
{
	struct mxs_lradc_adc *adc = iio_priv(iio_dev);

	switch (m) {
	case IIO_CHAN_INFO_RAW:
		if (chan->type == IIO_TEMP)
			return mxs_lradc_adc_read_temp(iio_dev, val);

		return mxs_lradc_adc_read_single(iio_dev, chan->channel, val);

	case IIO_CHAN_INFO_SCALE:
		if (chan->type == IIO_TEMP) {
			/*
			 * From the datasheet, we have to multiply by 1.012 and
			 * divide by 4
			 */
			*val = 0;
			*val2 = 253000;
			return IIO_VAL_INT_PLUS_MICRO;
		}

		*val = adc->vref_mv[chan->channel];
		*val2 = chan->scan_type.realbits -
			test_bit(chan->channel, &adc->is_divided);
		return IIO_VAL_FRACTIONAL_LOG2;

	case IIO_CHAN_INFO_OFFSET:
		if (chan->type == IIO_TEMP) {
			/*
			 * The calculated value from the ADC is in Kelvin, we
			 * want Celsius for hwmon so the offset is -273.15
			 * The offset is applied before scaling so it is
			 * actually -213.15 * 4 / 1.012 = -1079.644268
			 */
			*val = -1079;
			*val2 = 644268;

			return IIO_VAL_INT_PLUS_MICRO;
		}

		return -EINVAL;

	default:
		break;
	}

	return -EINVAL;
}

static int mxs_lradc_adc_write_raw(struct iio_dev *iio_dev,
				   const struct iio_chan_spec *chan,
				   int val, int val2, long m)
{
	struct mxs_lradc_adc *adc = iio_priv(iio_dev);
	struct mxs_lradc_scale *scale_avail =
			adc->scale_avail[chan->channel];
	int ret;

	ret = iio_device_claim_direct_mode(iio_dev);
	if (ret)
		return ret;

	switch (m) {
	case IIO_CHAN_INFO_SCALE:
		ret = -EINVAL;
		if (val == scale_avail[MXS_LRADC_DIV_DISABLED].integer &&
		    val2 == scale_avail[MXS_LRADC_DIV_DISABLED].nano) {
			/* divider by two disabled */
			clear_bit(chan->channel, &adc->is_divided);
			ret = 0;
		} else if (val == scale_avail[MXS_LRADC_DIV_ENABLED].integer &&
			   val2 == scale_avail[MXS_LRADC_DIV_ENABLED].nano) {
			/* divider by two enabled */
			set_bit(chan->channel, &adc->is_divided);
			ret = 0;
		}

		break;
	default:
		ret = -EINVAL;
		break;
	}

	iio_device_release_direct_mode(iio_dev);

	return ret;
}

static int mxs_lradc_adc_write_raw_get_fmt(struct iio_dev *iio_dev,
					   const struct iio_chan_spec *chan,
					   long m)
{
	return IIO_VAL_INT_PLUS_NANO;
}

static ssize_t mxs_lradc_adc_show_scale_avail(struct device *dev,
						 struct device_attribute *attr,
						 char *buf)
{
	struct iio_dev *iio = dev_to_iio_dev(dev);
	struct mxs_lradc_adc *adc = iio_priv(iio);
	struct iio_dev_attr *iio_attr = to_iio_dev_attr(attr);
	int i, ch, len = 0;

	ch = iio_attr->address;
	for (i = 0; i < ARRAY_SIZE(adc->scale_avail[ch]); i++)
		len += sprintf(buf + len, "%u.%09u ",
			       adc->scale_avail[ch][i].integer,
			       adc->scale_avail[ch][i].nano);

	len += sprintf(buf + len, "\n");

	return len;
}

#define SHOW_SCALE_AVAILABLE_ATTR(ch)\
	IIO_DEVICE_ATTR(in_voltage##ch##_scale_available, 0444,\
			mxs_lradc_adc_show_scale_avail, NULL, ch)

static SHOW_SCALE_AVAILABLE_ATTR(0);
static SHOW_SCALE_AVAILABLE_ATTR(1);
static SHOW_SCALE_AVAILABLE_ATTR(2);
static SHOW_SCALE_AVAILABLE_ATTR(3);
static SHOW_SCALE_AVAILABLE_ATTR(4);
static SHOW_SCALE_AVAILABLE_ATTR(5);
static SHOW_SCALE_AVAILABLE_ATTR(6);
static SHOW_SCALE_AVAILABLE_ATTR(7);
static SHOW_SCALE_AVAILABLE_ATTR(10);
static SHOW_SCALE_AVAILABLE_ATTR(11);
static SHOW_SCALE_AVAILABLE_ATTR(12);
static SHOW_SCALE_AVAILABLE_ATTR(13);
static SHOW_SCALE_AVAILABLE_ATTR(14);
static SHOW_SCALE_AVAILABLE_ATTR(15);

static struct attribute *mxs_lradc_adc_attributes[] = {
	&iio_dev_attr_in_voltage0_scale_available.dev_attr.attr,
	&iio_dev_attr_in_voltage1_scale_available.dev_attr.attr,
	&iio_dev_attr_in_voltage2_scale_available.dev_attr.attr,
	&iio_dev_attr_in_voltage3_scale_available.dev_attr.attr,
	&iio_dev_attr_in_voltage4_scale_available.dev_attr.attr,
	&iio_dev_attr_in_voltage5_scale_available.dev_attr.attr,
	&iio_dev_attr_in_voltage6_scale_available.dev_attr.attr,
	&iio_dev_attr_in_voltage7_scale_available.dev_attr.attr,
	&iio_dev_attr_in_voltage10_scale_available.dev_attr.attr,
	&iio_dev_attr_in_voltage11_scale_available.dev_attr.attr,
	&iio_dev_attr_in_voltage12_scale_available.dev_attr.attr,
	&iio_dev_attr_in_voltage13_scale_available.dev_attr.attr,
	&iio_dev_attr_in_voltage14_scale_available.dev_attr.attr,
	&iio_dev_attr_in_voltage15_scale_available.dev_attr.attr,
	NULL
};

static const struct attribute_group mxs_lradc_adc_attribute_group = {
	.attrs = mxs_lradc_adc_attributes,
};

static const struct iio_info mxs_lradc_adc_iio_info = {
	.driver_module		= THIS_MODULE,
	.read_raw		= mxs_lradc_adc_read_raw,
	.write_raw		= mxs_lradc_adc_write_raw,
	.write_raw_get_fmt	= mxs_lradc_adc_write_raw_get_fmt,
	.attrs			= &mxs_lradc_adc_attribute_group,
};

/* IRQ Handling */
static irqreturn_t mxs_lradc_adc_handle_irq(int irq, void *data)
{
	struct iio_dev *iio = data;
	struct mxs_lradc_adc *adc = iio_priv(iio);
	struct mxs_lradc *lradc = adc->lradc;
	unsigned long reg = readl(adc->base + LRADC_CTRL1);
	unsigned long flags;

	if (!(reg & mxs_lradc_irq_mask(lradc)))
		return IRQ_NONE;

	if (iio_buffer_enabled(iio)) {
		if (reg & lradc->buffer_vchans) {
			spin_lock_irqsave(&adc->lock, flags);
			iio_trigger_poll(iio->trig);
			spin_unlock_irqrestore(&adc->lock, flags);
		}
	} else if (reg & LRADC_CTRL1_LRADC_IRQ(0)) {
		complete(&adc->completion);
	}

	writel(reg & mxs_lradc_irq_mask(lradc),
	       adc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);

	return IRQ_HANDLED;
}


/* Trigger handling */
static irqreturn_t mxs_lradc_adc_trigger_handler(int irq, void *p)
{
	struct iio_poll_func *pf = p;
	struct iio_dev *iio = pf->indio_dev;
	struct mxs_lradc_adc *adc = iio_priv(iio);
	const u32 chan_value = LRADC_CH_ACCUMULATE |
		((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET);
	unsigned int i, j = 0;

	for_each_set_bit(i, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
		adc->buffer[j] = readl(adc->base + LRADC_CH(j));
		writel(chan_value, adc->base + LRADC_CH(j));
		adc->buffer[j] &= LRADC_CH_VALUE_MASK;
		adc->buffer[j] /= LRADC_DELAY_TIMER_LOOP;
		j++;
	}

	iio_push_to_buffers_with_timestamp(iio, adc->buffer, pf->timestamp);

	iio_trigger_notify_done(iio->trig);

	return IRQ_HANDLED;
}

static int mxs_lradc_adc_configure_trigger(struct iio_trigger *trig, bool state)
{
	struct iio_dev *iio = iio_trigger_get_drvdata(trig);
	struct mxs_lradc_adc *adc = iio_priv(iio);
	const u32 st = state ? STMP_OFFSET_REG_SET : STMP_OFFSET_REG_CLR;

	writel(LRADC_DELAY_KICK, adc->base + (LRADC_DELAY(0) + st));

	return 0;
}

static const struct iio_trigger_ops mxs_lradc_adc_trigger_ops = {
	.owner = THIS_MODULE,
	.set_trigger_state = &mxs_lradc_adc_configure_trigger,
};

static int mxs_lradc_adc_trigger_init(struct iio_dev *iio)
{
	int ret;
	struct iio_trigger *trig;
	struct mxs_lradc_adc *adc = iio_priv(iio);

	trig = devm_iio_trigger_alloc(&iio->dev, "%s-dev%i", iio->name,
				      iio->id);

	trig->dev.parent = adc->dev;
	iio_trigger_set_drvdata(trig, iio);
	trig->ops = &mxs_lradc_adc_trigger_ops;

	ret = iio_trigger_register(trig);
	if (ret)
		return ret;

	adc->trig = trig;

	return 0;
}

static void mxs_lradc_adc_trigger_remove(struct iio_dev *iio)
{
	struct mxs_lradc_adc *adc = iio_priv(iio);

	iio_trigger_unregister(adc->trig);
}

static int mxs_lradc_adc_buffer_preenable(struct iio_dev *iio)
{
	struct mxs_lradc_adc *adc = iio_priv(iio);
	struct mxs_lradc *lradc = adc->lradc;
	int chan, ofs = 0;
	unsigned long enable = 0;
	u32 ctrl4_set = 0;
	u32 ctrl4_clr = 0;
	u32 ctrl1_irq = 0;
	const u32 chan_value = LRADC_CH_ACCUMULATE |
		((LRADC_DELAY_TIMER_LOOP - 1) << LRADC_CH_NUM_SAMPLES_OFFSET);

	if (lradc->soc == IMX28_LRADC)
		writel(lradc->buffer_vchans << LRADC_CTRL1_LRADC_IRQ_EN_OFFSET,
		       adc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);
	writel(lradc->buffer_vchans,
	       adc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);

	for_each_set_bit(chan, iio->active_scan_mask, LRADC_MAX_TOTAL_CHANS) {
		ctrl4_set |= chan << LRADC_CTRL4_LRADCSELECT_OFFSET(ofs);
		ctrl4_clr |= LRADC_CTRL4_LRADCSELECT_MASK(ofs);
		ctrl1_irq |= LRADC_CTRL1_LRADC_IRQ_EN(ofs);
		writel(chan_value, adc->base + LRADC_CH(ofs));
		bitmap_set(&enable, ofs, 1);
		ofs++;
	}

	writel(LRADC_DELAY_TRIGGER_LRADCS_MASK | LRADC_DELAY_KICK,
	       adc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR);
	writel(ctrl4_clr, adc->base + LRADC_CTRL4 + STMP_OFFSET_REG_CLR);
	writel(ctrl4_set, adc->base + LRADC_CTRL4 + STMP_OFFSET_REG_SET);
	writel(ctrl1_irq, adc->base + LRADC_CTRL1 + STMP_OFFSET_REG_SET);
	writel(enable << LRADC_DELAY_TRIGGER_LRADCS_OFFSET,
	       adc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_SET);

	return 0;
}

static int mxs_lradc_adc_buffer_postdisable(struct iio_dev *iio)
{
	struct mxs_lradc_adc *adc = iio_priv(iio);
	struct mxs_lradc *lradc = adc->lradc;

	writel(LRADC_DELAY_TRIGGER_LRADCS_MASK | LRADC_DELAY_KICK,
	       adc->base + LRADC_DELAY(0) + STMP_OFFSET_REG_CLR);

	writel(lradc->buffer_vchans,
	       adc->base + LRADC_CTRL0 + STMP_OFFSET_REG_CLR);
	if (lradc->soc == IMX28_LRADC)
		writel(lradc->buffer_vchans << LRADC_CTRL1_LRADC_IRQ_EN_OFFSET,
		       adc->base + LRADC_CTRL1 + STMP_OFFSET_REG_CLR);

	return 0;
}

static bool mxs_lradc_adc_validate_scan_mask(struct iio_dev *iio,
					     const unsigned long *mask)
{
	struct mxs_lradc_adc *adc = iio_priv(iio);
	struct mxs_lradc *lradc = adc->lradc;
	const int map_chans = bitmap_weight(mask, LRADC_MAX_TOTAL_CHANS);
	int rsvd_chans = 0;
	unsigned long rsvd_mask = 0;

	if (lradc->use_touchbutton)
		rsvd_mask |= CHAN_MASK_TOUCHBUTTON;
	if (lradc->touchscreen_wire == MXS_LRADC_TOUCHSCREEN_4WIRE)
		rsvd_mask |= CHAN_MASK_TOUCHSCREEN_4WIRE;
	if (lradc->touchscreen_wire == MXS_LRADC_TOUCHSCREEN_5WIRE)
		rsvd_mask |= CHAN_MASK_TOUCHSCREEN_5WIRE;

	if (lradc->use_touchbutton)
		rsvd_chans++;
	if (lradc->touchscreen_wire)
		rsvd_chans += 2;

	/* Test for attempts to map channels with special mode of operation. */
	if (bitmap_intersects(mask, &rsvd_mask, LRADC_MAX_TOTAL_CHANS))
		return false;

	/* Test for attempts to map more channels then available slots. */
	if (map_chans + rsvd_chans > LRADC_MAX_MAPPED_CHANS)
		return false;

	return true;
}

static const struct iio_buffer_setup_ops mxs_lradc_adc_buffer_ops = {
	.preenable = &mxs_lradc_adc_buffer_preenable,
	.postenable = &iio_triggered_buffer_postenable,
	.predisable = &iio_triggered_buffer_predisable,
	.postdisable = &mxs_lradc_adc_buffer_postdisable,
	.validate_scan_mask = &mxs_lradc_adc_validate_scan_mask,
};

/* Driver initialization */
#define MXS_ADC_CHAN(idx, chan_type, name) {			\
	.type = (chan_type),					\
	.indexed = 1,						\
	.scan_index = (idx),					\
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |		\
			      BIT(IIO_CHAN_INFO_SCALE),		\
	.channel = (idx),					\
	.address = (idx),					\
	.scan_type = {						\
		.sign = 'u',					\
		.realbits = LRADC_RESOLUTION,			\
		.storagebits = 32,				\
	},							\
	.datasheet_name = (name),				\
}

static const struct iio_chan_spec mx23_lradc_chan_spec[] = {
	MXS_ADC_CHAN(0, IIO_VOLTAGE, "LRADC0"),
	MXS_ADC_CHAN(1, IIO_VOLTAGE, "LRADC1"),
	MXS_ADC_CHAN(2, IIO_VOLTAGE, "LRADC2"),
	MXS_ADC_CHAN(3, IIO_VOLTAGE, "LRADC3"),
	MXS_ADC_CHAN(4, IIO_VOLTAGE, "LRADC4"),
	MXS_ADC_CHAN(5, IIO_VOLTAGE, "LRADC5"),
	MXS_ADC_CHAN(6, IIO_VOLTAGE, "VDDIO"),
	MXS_ADC_CHAN(7, IIO_VOLTAGE, "VBATT"),
	/* Combined Temperature sensors */
	{
		.type = IIO_TEMP,
		.indexed = 1,
		.scan_index = 8,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				      BIT(IIO_CHAN_INFO_OFFSET) |
				      BIT(IIO_CHAN_INFO_SCALE),
		.channel = 8,
		.scan_type = {.sign = 'u', .realbits = 18, .storagebits = 32,},
		.datasheet_name = "TEMP_DIE",
	},
	/* Hidden channel to keep indexes */
	{
		.type = IIO_TEMP,
		.indexed = 1,
		.scan_index = -1,
		.channel = 9,
	},
	MXS_ADC_CHAN(10, IIO_VOLTAGE, NULL),
	MXS_ADC_CHAN(11, IIO_VOLTAGE, NULL),
	MXS_ADC_CHAN(12, IIO_VOLTAGE, "USB_DP"),
	MXS_ADC_CHAN(13, IIO_VOLTAGE, "USB_DN"),
	MXS_ADC_CHAN(14, IIO_VOLTAGE, "VBG"),
	MXS_ADC_CHAN(15, IIO_VOLTAGE, "VDD5V"),
};

static const struct iio_chan_spec mx28_lradc_chan_spec[] = {
	MXS_ADC_CHAN(0, IIO_VOLTAGE, "LRADC0"),
	MXS_ADC_CHAN(1, IIO_VOLTAGE, "LRADC1"),
	MXS_ADC_CHAN(2, IIO_VOLTAGE, "LRADC2"),
	MXS_ADC_CHAN(3, IIO_VOLTAGE, "LRADC3"),
	MXS_ADC_CHAN(4, IIO_VOLTAGE, "LRADC4"),
	MXS_ADC_CHAN(5, IIO_VOLTAGE, "LRADC5"),
	MXS_ADC_CHAN(6, IIO_VOLTAGE, "LRADC6"),
	MXS_ADC_CHAN(7, IIO_VOLTAGE, "VBATT"),
	/* Combined Temperature sensors */
	{
		.type = IIO_TEMP,
		.indexed = 1,
		.scan_index = 8,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				      BIT(IIO_CHAN_INFO_OFFSET) |
				      BIT(IIO_CHAN_INFO_SCALE),
		.channel = 8,
		.scan_type = {.sign = 'u', .realbits = 18, .storagebits = 32,},
		.datasheet_name = "TEMP_DIE",
	},
	/* Hidden channel to keep indexes */
	{
		.type = IIO_TEMP,
		.indexed = 1,
		.scan_index = -1,
		.channel = 9,
	},
	MXS_ADC_CHAN(10, IIO_VOLTAGE, "VDDIO"),
	MXS_ADC_CHAN(11, IIO_VOLTAGE, "VTH"),
	MXS_ADC_CHAN(12, IIO_VOLTAGE, "VDDA"),
	MXS_ADC_CHAN(13, IIO_VOLTAGE, "VDDD"),
	MXS_ADC_CHAN(14, IIO_VOLTAGE, "VBG"),
	MXS_ADC_CHAN(15, IIO_VOLTAGE, "VDD5V"),
};

static void mxs_lradc_adc_hw_init(struct mxs_lradc_adc *adc)
{
	/* The ADC always uses DELAY CHANNEL 0. */
	const u32 adc_cfg =
		(1 << (LRADC_DELAY_TRIGGER_DELAYS_OFFSET + 0)) |
		(LRADC_DELAY_TIMER_PER << LRADC_DELAY_DELAY_OFFSET);

	/* Configure DELAY CHANNEL 0 for generic ADC sampling. */
	writel(adc_cfg, adc->base + LRADC_DELAY(0));

	/*
	 * Start internal temperature sensing by clearing bit
	 * HW_LRADC_CTRL2_TEMPSENSE_PWD. This bit can be left cleared
	 * after power up.
	 */
	writel(0, adc->base + LRADC_CTRL2);
}

static void mxs_lradc_adc_hw_stop(struct mxs_lradc_adc *adc)
{
	writel(0, adc->base + LRADC_DELAY(0));
}

static int mxs_lradc_adc_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct mxs_lradc *lradc = dev_get_drvdata(dev->parent);
	struct mxs_lradc_adc *adc;
	struct iio_dev *iio;
	struct resource *iores;
	int ret, irq, virq, i, s, n;
	u64 scale_uv;
	const char **irq_name;

	/* Allocate the IIO device. */
	iio = devm_iio_device_alloc(dev, sizeof(*adc));
	if (!iio) {
		dev_err(dev, "Failed to allocate IIO device\n");
		return -ENOMEM;
	}

	adc = iio_priv(iio);
	adc->lradc = lradc;
	adc->dev = dev;

	iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!iores)
		return -EINVAL;

	adc->base = devm_ioremap(dev, iores->start, resource_size(iores));
	if (!adc->base)
		return -ENOMEM;

	init_completion(&adc->completion);
	spin_lock_init(&adc->lock);

	platform_set_drvdata(pdev, iio);

	iio->name = pdev->name;
	iio->dev.parent = dev;
	iio->dev.of_node = dev->parent->of_node;
	iio->info = &mxs_lradc_adc_iio_info;
	iio->modes = INDIO_DIRECT_MODE;
	iio->masklength = LRADC_MAX_TOTAL_CHANS;

	if (lradc->soc == IMX23_LRADC) {
		iio->channels = mx23_lradc_chan_spec;
		iio->num_channels = ARRAY_SIZE(mx23_lradc_chan_spec);
		irq_name = mx23_lradc_adc_irq_names;
		n = ARRAY_SIZE(mx23_lradc_adc_irq_names);
	} else {
		iio->channels = mx28_lradc_chan_spec;
		iio->num_channels = ARRAY_SIZE(mx28_lradc_chan_spec);
		irq_name = mx28_lradc_adc_irq_names;
		n = ARRAY_SIZE(mx28_lradc_adc_irq_names);
	}

	ret = stmp_reset_block(adc->base);
	if (ret)
		return ret;

	for (i = 0; i < n; i++) {
		irq = platform_get_irq_byname(pdev, irq_name[i]);
		if (irq < 0)
			return irq;

		virq = irq_of_parse_and_map(dev->parent->of_node, irq);

		ret = devm_request_irq(dev, virq, mxs_lradc_adc_handle_irq,
				       0, irq_name[i], iio);
		if (ret)
			return ret;
	}

	ret = mxs_lradc_adc_trigger_init(iio);
	if (ret)
		return ret;

	ret = iio_triggered_buffer_setup(iio, &iio_pollfunc_store_time,
					 &mxs_lradc_adc_trigger_handler,
					 &mxs_lradc_adc_buffer_ops);
	if (ret)
		goto err_trig;

	adc->vref_mv = mxs_lradc_adc_vref_mv[lradc->soc];

	/* Populate available ADC input ranges */
	for (i = 0; i < LRADC_MAX_TOTAL_CHANS; i++) {
		for (s = 0; s < ARRAY_SIZE(adc->scale_avail[i]); s++) {
			/*
			 * [s=0] = optional divider by two disabled (default)
			 * [s=1] = optional divider by two enabled
			 *
			 * The scale is calculated by doing:
			 *   Vref >> (realbits - s)
			 * which multiplies by two on the second component
			 * of the array.
			 */
			scale_uv = ((u64)adc->vref_mv[i] * 100000000) >>
				   (LRADC_RESOLUTION - s);
			adc->scale_avail[i][s].nano =
					do_div(scale_uv, 100000000) * 10;
			adc->scale_avail[i][s].integer = scale_uv;
		}
	}

	/* Configure the hardware. */
	mxs_lradc_adc_hw_init(adc);

	/* Register IIO device. */
	ret = iio_device_register(iio);
	if (ret) {
		dev_err(dev, "Failed to register IIO device\n");
		goto err_dev;
	}

	return 0;

err_dev:
	mxs_lradc_adc_hw_stop(adc);
	iio_triggered_buffer_cleanup(iio);
err_trig:
	mxs_lradc_adc_trigger_remove(iio);
	return ret;
}

static int mxs_lradc_adc_remove(struct platform_device *pdev)
{
	struct iio_dev *iio = platform_get_drvdata(pdev);
	struct mxs_lradc_adc *adc = iio_priv(iio);

	iio_device_unregister(iio);
	mxs_lradc_adc_hw_stop(adc);
	iio_triggered_buffer_cleanup(iio);
	mxs_lradc_adc_trigger_remove(iio);

	return 0;
}

static struct platform_driver mxs_lradc_adc_driver = {
	.driver = {
		.name	= "mxs-lradc-adc",
	},
	.probe	= mxs_lradc_adc_probe,
	.remove = mxs_lradc_adc_remove,
};
module_platform_driver(mxs_lradc_adc_driver);

MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
MODULE_DESCRIPTION("Freescale MXS LRADC driver general purpose ADC driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:mxs-lradc-adc");
