// SPDX-License-Identifier: GPL-2.0-only
/*
 * ADC12130/ADC12132/ADC12138 12-bit plus sign ADC driver
 *
 * Copyright (c) 2016 Akinobu Mita <akinobu.mita@gmail.com>
 *
 * 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/property.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)

{
	static 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) >> channel->scan_type.shift,
				       channel->scan_type.realbits - 1);

		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,
};

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->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 = device_property_read_u32(&spi->dev, "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 void 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);
}

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);

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 = 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");
