/*
 * ADC12130/ADC12132/ADC12138 12-bit plus sign ADC driver
 *
 * Copyright (c) 2016 Akinobu Mita <akinobu.mita@gmail.com>
 *
 * This file is subject to the terms and conditions of version 2 of
 * the GNU General Public License.  See the file COPYING in the main
 * directory of this archive for more details.
 *
 * Datasheet: http://www.ti.com/lit/ds/symlink/adc12138.pdf
 */

#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/completion.h>
#include <linux/clk.h>
#include <linux/spi/spi.h>
#include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/regulator/consumer.h>

#define ADC12138_MODE_AUTO_CAL			0x08
#define ADC12138_MODE_READ_STATUS		0x0c
#define ADC12138_MODE_ACQUISITION_TIME_6	0x0e
#define ADC12138_MODE_ACQUISITION_TIME_10	0x4e
#define ADC12138_MODE_ACQUISITION_TIME_18	0x8e
#define ADC12138_MODE_ACQUISITION_TIME_34	0xce

#define ADC12138_STATUS_CAL			BIT(6)

enum {
	adc12130,
	adc12132,
	adc12138,
};

struct adc12138 {
	struct spi_device *spi;
	unsigned int id;
	/* conversion clock */
	struct clk *cclk;
	/* positive analog voltage reference */
	struct regulator *vref_p;
	/* negative analog voltage reference */
	struct regulator *vref_n;
	struct mutex lock;
	struct completion complete;
	/* The number of cclk periods for the S/H's acquisition time */
	unsigned int acquisition_time;
	/*
	 * Maximum size needed: 16x 2 bytes ADC data + 8 bytes timestamp.
	 * Less may be need if not all channels are enabled, as long as
	 * the 8 byte alignment of the timestamp is maintained.
	 */
	__be16 data[20] __aligned(8);

	u8 tx_buf[2] ____cacheline_aligned;
	u8 rx_buf[2];
};

#define ADC12138_VOLTAGE_CHANNEL(chan)					\
	{								\
		.type = IIO_VOLTAGE,					\
		.indexed = 1,						\
		.channel = chan,					\
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE)	\
					| BIT(IIO_CHAN_INFO_OFFSET),	\
		.scan_index = chan,					\
		.scan_type = {						\
			.sign = 's',					\
			.realbits = 13,					\
			.storagebits = 16,				\
			.shift = 3,					\
			.endianness = IIO_BE,				\
		},							\
	}

#define ADC12138_VOLTAGE_CHANNEL_DIFF(chan1, chan2, si)			\
	{								\
		.type = IIO_VOLTAGE,					\
		.indexed = 1,						\
		.channel = (chan1),					\
		.channel2 = (chan2),					\
		.differential = 1,					\
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE)	\
					| BIT(IIO_CHAN_INFO_OFFSET),	\
		.scan_index = si,					\
		.scan_type = {						\
			.sign = 's',					\
			.realbits = 13,					\
			.storagebits = 16,				\
			.shift = 3,					\
			.endianness = IIO_BE,				\
		},							\
	}

static const struct iio_chan_spec adc12132_channels[] = {
	ADC12138_VOLTAGE_CHANNEL(0),
	ADC12138_VOLTAGE_CHANNEL(1),
	ADC12138_VOLTAGE_CHANNEL_DIFF(0, 1, 2),
	ADC12138_VOLTAGE_CHANNEL_DIFF(1, 0, 3),
	IIO_CHAN_SOFT_TIMESTAMP(4),
};

static const struct iio_chan_spec adc12138_channels[] = {
	ADC12138_VOLTAGE_CHANNEL(0),
	ADC12138_VOLTAGE_CHANNEL(1),
	ADC12138_VOLTAGE_CHANNEL(2),
	ADC12138_VOLTAGE_CHANNEL(3),
	ADC12138_VOLTAGE_CHANNEL(4),
	ADC12138_VOLTAGE_CHANNEL(5),
	ADC12138_VOLTAGE_CHANNEL(6),
	ADC12138_VOLTAGE_CHANNEL(7),
	ADC12138_VOLTAGE_CHANNEL_DIFF(0, 1, 8),
	ADC12138_VOLTAGE_CHANNEL_DIFF(1, 0, 9),
	ADC12138_VOLTAGE_CHANNEL_DIFF(2, 3, 10),
	ADC12138_VOLTAGE_CHANNEL_DIFF(3, 2, 11),
	ADC12138_VOLTAGE_CHANNEL_DIFF(4, 5, 12),
	ADC12138_VOLTAGE_CHANNEL_DIFF(5, 4, 13),
	ADC12138_VOLTAGE_CHANNEL_DIFF(6, 7, 14),
	ADC12138_VOLTAGE_CHANNEL_DIFF(7, 6, 15),
	IIO_CHAN_SOFT_TIMESTAMP(16),
};

static int adc12138_mode_programming(struct adc12138 *adc, u8 mode,
				     void *rx_buf, int len)
{
	struct spi_transfer xfer = {
		.tx_buf = adc->tx_buf,
		.rx_buf = adc->rx_buf,
		.len = len,
	};
	int ret;

	/* Skip unused bits for ADC12130 and ADC12132 */
	if (adc->id != adc12138)
		mode = (mode & 0xc0) | ((mode & 0x0f) << 2);

	adc->tx_buf[0] = mode;

	ret = spi_sync_transfer(adc->spi, &xfer, 1);
	if (ret)
		return ret;

	memcpy(rx_buf, adc->rx_buf, len);

	return 0;
}

static int adc12138_read_status(struct adc12138 *adc)
{
	u8 rx_buf[2];
	int ret;

	ret = adc12138_mode_programming(adc, ADC12138_MODE_READ_STATUS,
					rx_buf, 2);
	if (ret)
		return ret;

	return (rx_buf[0] << 1) | (rx_buf[1] >> 7);
}

static int __adc12138_start_conv(struct adc12138 *adc,
				 struct iio_chan_spec const *channel,
				 void *data, int len)

{
	const u8 ch_to_mux[] = { 0, 4, 1, 5, 2, 6, 3, 7 };
	u8 mode = (ch_to_mux[channel->channel] << 4) |
		  (channel->differential ? 0 : 0x80);

	return adc12138_mode_programming(adc, mode, data, len);
}

static int adc12138_start_conv(struct adc12138 *adc,
			       struct iio_chan_spec const *channel)
{
	u8 trash;

	return __adc12138_start_conv(adc, channel, &trash, 1);
}

static int adc12138_start_and_read_conv(struct adc12138 *adc,
					struct iio_chan_spec const *channel,
					__be16 *data)
{
	return __adc12138_start_conv(adc, channel, data, 2);
}

static int adc12138_read_conv_data(struct adc12138 *adc, __be16 *value)
{
	/* Issue a read status instruction and read previous conversion data */
	return adc12138_mode_programming(adc, ADC12138_MODE_READ_STATUS,
					 value, sizeof(*value));
}

static int adc12138_wait_eoc(struct adc12138 *adc, unsigned long timeout)
{
	if (!wait_for_completion_timeout(&adc->complete, timeout))
		return -ETIMEDOUT;

	return 0;
}

static int adc12138_adc_conversion(struct adc12138 *adc,
				   struct iio_chan_spec const *channel,
				   __be16 *value)
{
	int ret;

	reinit_completion(&adc->complete);

	ret = adc12138_start_conv(adc, channel);
	if (ret)
		return ret;

	ret = adc12138_wait_eoc(adc, msecs_to_jiffies(100));
	if (ret)
		return ret;

	return adc12138_read_conv_data(adc, value);
}

static int adc12138_read_raw(struct iio_dev *iio,
			     struct iio_chan_spec const *channel, int *value,
			     int *shift, long mask)
{
	struct adc12138 *adc = iio_priv(iio);
	int ret;
	__be16 data;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		mutex_lock(&adc->lock);
		ret = adc12138_adc_conversion(adc, channel, &data);
		mutex_unlock(&adc->lock);
		if (ret)
			return ret;

		*value = sign_extend32(be16_to_cpu(data) >> 3, 12);

		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		ret = regulator_get_voltage(adc->vref_p);
		if (ret < 0)
			return ret;
		*value = ret;

		if (!IS_ERR(adc->vref_n)) {
			ret = regulator_get_voltage(adc->vref_n);
			if (ret < 0)
				return ret;
			*value -= ret;
		}

		/* convert regulator output voltage to mV */
		*value /= 1000;
		*shift = channel->scan_type.realbits - 1;

		return IIO_VAL_FRACTIONAL_LOG2;
	case IIO_CHAN_INFO_OFFSET:
		if (!IS_ERR(adc->vref_n)) {
			*value = regulator_get_voltage(adc->vref_n);
			if (*value < 0)
				return *value;
		} else {
			*value = 0;
		}

		/* convert regulator output voltage to mV */
		*value /= 1000;

		return IIO_VAL_INT;
	}

	return -EINVAL;
}

static const struct iio_info adc12138_info = {
	.read_raw = adc12138_read_raw,
	.driver_module = THIS_MODULE,
};

static int adc12138_init(struct adc12138 *adc)
{
	int ret;
	int status;
	u8 mode;
	u8 trash;

	reinit_completion(&adc->complete);

	ret = adc12138_mode_programming(adc, ADC12138_MODE_AUTO_CAL, &trash, 1);
	if (ret)
		return ret;

	/* data output at this time has no significance */
	status = adc12138_read_status(adc);
	if (status < 0)
		return status;

	adc12138_wait_eoc(adc, msecs_to_jiffies(100));

	status = adc12138_read_status(adc);
	if (status & ADC12138_STATUS_CAL) {
		dev_warn(&adc->spi->dev,
			"Auto Cal sequence is still in progress: %#x\n",
			status);
		return -EIO;
	}

	switch (adc->acquisition_time) {
	case 6:
		mode = ADC12138_MODE_ACQUISITION_TIME_6;
		break;
	case 10:
		mode = ADC12138_MODE_ACQUISITION_TIME_10;
		break;
	case 18:
		mode = ADC12138_MODE_ACQUISITION_TIME_18;
		break;
	case 34:
		mode = ADC12138_MODE_ACQUISITION_TIME_34;
		break;
	default:
		return -EINVAL;
	}

	return adc12138_mode_programming(adc, mode, &trash, 1);
}

static irqreturn_t adc12138_trigger_handler(int irq, void *p)
{
	struct iio_poll_func *pf = p;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct adc12138 *adc = iio_priv(indio_dev);
	__be16 trash;
	int ret;
	int scan_index;
	int i = 0;

	mutex_lock(&adc->lock);

	for_each_set_bit(scan_index, indio_dev->active_scan_mask,
			 indio_dev->masklength) {
		const struct iio_chan_spec *scan_chan =
				&indio_dev->channels[scan_index];

		reinit_completion(&adc->complete);

		ret = adc12138_start_and_read_conv(adc, scan_chan,
					i ? &adc->data[i - 1] : &trash);
		if (ret) {
			dev_warn(&adc->spi->dev,
				 "failed to start conversion\n");
			goto out;
		}

		ret = adc12138_wait_eoc(adc, msecs_to_jiffies(100));
		if (ret) {
			dev_warn(&adc->spi->dev, "wait eoc timeout\n");
			goto out;
		}

		i++;
	}

	if (i) {
		ret = adc12138_read_conv_data(adc, &adc->data[i - 1]);
		if (ret) {
			dev_warn(&adc->spi->dev,
				 "failed to get conversion data\n");
			goto out;
		}
	}

	iio_push_to_buffers_with_timestamp(indio_dev, adc->data,
					   iio_get_time_ns(indio_dev));
out:
	mutex_unlock(&adc->lock);

	iio_trigger_notify_done(indio_dev->trig);

	return IRQ_HANDLED;
}

static irqreturn_t adc12138_eoc_handler(int irq, void *p)
{
	struct iio_dev *indio_dev = p;
	struct adc12138 *adc = iio_priv(indio_dev);

	complete(&adc->complete);

	return IRQ_HANDLED;
}

static int adc12138_probe(struct spi_device *spi)
{
	struct iio_dev *indio_dev;
	struct adc12138 *adc;
	int ret;

	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
	if (!indio_dev)
		return -ENOMEM;

	adc = iio_priv(indio_dev);
	adc->spi = spi;
	adc->id = spi_get_device_id(spi)->driver_data;
	mutex_init(&adc->lock);
	init_completion(&adc->complete);

	indio_dev->name = spi_get_device_id(spi)->name;
	indio_dev->dev.parent = &spi->dev;
	indio_dev->info = &adc12138_info;
	indio_dev->modes = INDIO_DIRECT_MODE;

	switch (adc->id) {
	case adc12130:
	case adc12132:
		indio_dev->channels = adc12132_channels;
		indio_dev->num_channels = ARRAY_SIZE(adc12132_channels);
		break;
	case adc12138:
		indio_dev->channels = adc12138_channels;
		indio_dev->num_channels = ARRAY_SIZE(adc12138_channels);
		break;
	default:
		return -EINVAL;
	}

	ret = of_property_read_u32(spi->dev.of_node, "ti,acquisition-time",
				   &adc->acquisition_time);
	if (ret)
		adc->acquisition_time = 10;

	adc->cclk = devm_clk_get(&spi->dev, NULL);
	if (IS_ERR(adc->cclk))
		return PTR_ERR(adc->cclk);

	adc->vref_p = devm_regulator_get(&spi->dev, "vref-p");
	if (IS_ERR(adc->vref_p))
		return PTR_ERR(adc->vref_p);

	adc->vref_n = devm_regulator_get_optional(&spi->dev, "vref-n");
	if (IS_ERR(adc->vref_n)) {
		/*
		 * Assume vref_n is 0V if an optional regulator is not
		 * specified, otherwise return the error code.
		 */
		ret = PTR_ERR(adc->vref_n);
		if (ret != -ENODEV)
			return ret;
	}

	ret = devm_request_irq(&spi->dev, spi->irq, adc12138_eoc_handler,
			       IRQF_TRIGGER_RISING, indio_dev->name, indio_dev);
	if (ret)
		return ret;

	ret = clk_prepare_enable(adc->cclk);
	if (ret)
		return ret;

	ret = regulator_enable(adc->vref_p);
	if (ret)
		goto err_clk_disable;

	if (!IS_ERR(adc->vref_n)) {
		ret = regulator_enable(adc->vref_n);
		if (ret)
			goto err_vref_p_disable;
	}

	ret = adc12138_init(adc);
	if (ret)
		goto err_vref_n_disable;

	spi_set_drvdata(spi, indio_dev);

	ret = iio_triggered_buffer_setup(indio_dev, NULL,
					 adc12138_trigger_handler, NULL);
	if (ret)
		goto err_vref_n_disable;

	ret = iio_device_register(indio_dev);
	if (ret)
		goto err_buffer_cleanup;

	return 0;
err_buffer_cleanup:
	iio_triggered_buffer_cleanup(indio_dev);
err_vref_n_disable:
	if (!IS_ERR(adc->vref_n))
		regulator_disable(adc->vref_n);
err_vref_p_disable:
	regulator_disable(adc->vref_p);
err_clk_disable:
	clk_disable_unprepare(adc->cclk);

	return ret;
}

static int adc12138_remove(struct spi_device *spi)
{
	struct iio_dev *indio_dev = spi_get_drvdata(spi);
	struct adc12138 *adc = iio_priv(indio_dev);

	iio_device_unregister(indio_dev);
	iio_triggered_buffer_cleanup(indio_dev);
	if (!IS_ERR(adc->vref_n))
		regulator_disable(adc->vref_n);
	regulator_disable(adc->vref_p);
	clk_disable_unprepare(adc->cclk);

	return 0;
}

#ifdef CONFIG_OF

static const struct of_device_id adc12138_dt_ids[] = {
	{ .compatible = "ti,adc12130", },
	{ .compatible = "ti,adc12132", },
	{ .compatible = "ti,adc12138", },
	{}
};
MODULE_DEVICE_TABLE(of, adc12138_dt_ids);

#endif

static const struct spi_device_id adc12138_id[] = {
	{ "adc12130", adc12130 },
	{ "adc12132", adc12132 },
	{ "adc12138", adc12138 },
	{}
};
MODULE_DEVICE_TABLE(spi, adc12138_id);

static struct spi_driver adc12138_driver = {
	.driver = {
		.name = "adc12138",
		.of_match_table = of_match_ptr(adc12138_dt_ids),
	},
	.probe = adc12138_probe,
	.remove = adc12138_remove,
	.id_table = adc12138_id,
};
module_spi_driver(adc12138_driver);

MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");
MODULE_DESCRIPTION("ADC12130/ADC12132/ADC12138 driver");
MODULE_LICENSE("GPL v2");
