/**
 * Copyright (C) 2017 Axis Communications AB
 *
 * Driver for Texas Instruments' ADC084S021 ADC chip.
 * Datasheets can be found here:
 * http://www.ti.com/lit/ds/symlink/adc084s021.pdf
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

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

#define ADC084S021_DRIVER_NAME "adc084s021"

struct adc084s021 {
	struct spi_device *spi;
	struct spi_message message;
	struct spi_transfer spi_trans;
	struct regulator *reg;
	struct mutex lock;
	/*
	 * DMA (thus cache coherency maintenance) requires the
	 * transfer buffers to live in their own cache line.
	 */
	u16 tx_buf[4] ____cacheline_aligned;
	__be16 rx_buf[5]; /* First 16-bits are trash */
};

#define ADC084S021_VOLTAGE_CHANNEL(num)                  \
	{                                                      \
		.type = IIO_VOLTAGE,                                 \
		.channel = (num),                                    \
		.indexed = 1,                                        \
		.scan_index = (num),                                 \
		.scan_type = {                                       \
			.sign = 'u',                                       \
			.realbits = 8,                                     \
			.storagebits = 16,                                 \
			.shift = 4,                                        \
			.endianness = IIO_BE,                              \
		},                                                   \
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),        \
		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),\
	}

static const struct iio_chan_spec adc084s021_channels[] = {
	ADC084S021_VOLTAGE_CHANNEL(0),
	ADC084S021_VOLTAGE_CHANNEL(1),
	ADC084S021_VOLTAGE_CHANNEL(2),
	ADC084S021_VOLTAGE_CHANNEL(3),
	IIO_CHAN_SOFT_TIMESTAMP(4),
};

/**
 * Read an ADC channel and return its value.
 *
 * @adc: The ADC SPI data.
 * @data: Buffer for converted data.
 */
static int adc084s021_adc_conversion(struct adc084s021 *adc, void *data)
{
	int n_words = (adc->spi_trans.len >> 1) - 1; /* Discard first word */
	int ret, i = 0;
	u16 *p = data;

	/* Do the transfer */
	ret = spi_sync(adc->spi, &adc->message);
	if (ret < 0)
		return ret;

	for (; i < n_words; i++)
		*(p + i) = adc->rx_buf[i + 1];

	return ret;
}

static int adc084s021_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *channel, int *val,
			   int *val2, long mask)
{
	struct adc084s021 *adc = iio_priv(indio_dev);
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		ret = iio_device_claim_direct_mode(indio_dev);
		if (ret < 0)
			return ret;

		ret = regulator_enable(adc->reg);
		if (ret) {
			iio_device_release_direct_mode(indio_dev);
			return ret;
		}

		adc->tx_buf[0] = channel->channel << 3;
		ret = adc084s021_adc_conversion(adc, val);
		iio_device_release_direct_mode(indio_dev);
		regulator_disable(adc->reg);
		if (ret < 0)
			return ret;

		*val = be16_to_cpu(*val);
		*val = (*val >> channel->scan_type.shift) & 0xff;

		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		ret = regulator_enable(adc->reg);
		if (ret)
			return ret;

		ret = regulator_get_voltage(adc->reg);
		regulator_disable(adc->reg);
		if (ret < 0)
			return ret;

		*val = ret / 1000;

		return IIO_VAL_INT;
	default:
		return -EINVAL;
	}
}

/**
 * Read enabled ADC channels and push data to the buffer.
 *
 * @irq: The interrupt number (not used).
 * @pollfunc: Pointer to the poll func.
 */
static irqreturn_t adc084s021_buffer_trigger_handler(int irq, void *pollfunc)
{
	struct iio_poll_func *pf = pollfunc;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct adc084s021 *adc = iio_priv(indio_dev);
	__be16 data[8] = {0}; /* 4 * 16-bit words of data + 8 bytes timestamp */

	mutex_lock(&adc->lock);

	if (adc084s021_adc_conversion(adc, &data) < 0)
		dev_err(&adc->spi->dev, "Failed to read data\n");

	iio_push_to_buffers_with_timestamp(indio_dev, data,
					   iio_get_time_ns(indio_dev));
	mutex_unlock(&adc->lock);
	iio_trigger_notify_done(indio_dev->trig);

	return IRQ_HANDLED;
}

static int adc084s021_buffer_preenable(struct iio_dev *indio_dev)
{
	struct adc084s021 *adc = iio_priv(indio_dev);
	int scan_index;
	int i = 0;

	for_each_set_bit(scan_index, indio_dev->active_scan_mask,
			 indio_dev->masklength) {
		const struct iio_chan_spec *channel =
			&indio_dev->channels[scan_index];
		adc->tx_buf[i++] = channel->channel << 3;
	}
	adc->spi_trans.len = 2 + (i * sizeof(__be16)); /* Trash + channels */

	return regulator_enable(adc->reg);
}

static int adc084s021_buffer_postdisable(struct iio_dev *indio_dev)
{
	struct adc084s021 *adc = iio_priv(indio_dev);

	adc->spi_trans.len = 4; /* Trash + single channel */

	return regulator_disable(adc->reg);
}

static const struct iio_info adc084s021_info = {
	.read_raw = adc084s021_read_raw,
};

static const struct iio_buffer_setup_ops adc084s021_buffer_setup_ops = {
	.preenable = adc084s021_buffer_preenable,
	.postenable = iio_triggered_buffer_postenable,
	.predisable = iio_triggered_buffer_predisable,
	.postdisable = adc084s021_buffer_postdisable,
};

static int adc084s021_probe(struct spi_device *spi)
{
	struct iio_dev *indio_dev;
	struct adc084s021 *adc;
	int ret;

	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adc));
	if (!indio_dev) {
		dev_err(&spi->dev, "Failed to allocate IIO device\n");
		return -ENOMEM;
	}

	adc = iio_priv(indio_dev);
	adc->spi = spi;

	/* Connect the SPI device and the iio dev */
	spi_set_drvdata(spi, indio_dev);

	/* Initiate the Industrial I/O device */
	indio_dev->dev.parent = &spi->dev;
	indio_dev->dev.of_node = spi->dev.of_node;
	indio_dev->name = spi_get_device_id(spi)->name;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->info = &adc084s021_info;
	indio_dev->channels = adc084s021_channels;
	indio_dev->num_channels = ARRAY_SIZE(adc084s021_channels);

	/* Create SPI transfer for channel reads */
	adc->spi_trans.tx_buf = adc->tx_buf;
	adc->spi_trans.rx_buf = adc->rx_buf;
	adc->spi_trans.len = 4; /* Trash + single channel */
	spi_message_init_with_transfers(&adc->message, &adc->spi_trans, 1);

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

	mutex_init(&adc->lock);

	/* Setup triggered buffer with pollfunction */
	ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, NULL,
					    adc084s021_buffer_trigger_handler,
					    &adc084s021_buffer_setup_ops);
	if (ret) {
		dev_err(&spi->dev, "Failed to setup triggered buffer\n");
		return ret;
	}

	return devm_iio_device_register(&spi->dev, indio_dev);
}

static const struct of_device_id adc084s021_of_match[] = {
	{ .compatible = "ti,adc084s021", },
	{},
};
MODULE_DEVICE_TABLE(of, adc084s021_of_match);

static const struct spi_device_id adc084s021_id[] = {
	{ ADC084S021_DRIVER_NAME, 0},
	{}
};
MODULE_DEVICE_TABLE(spi, adc084s021_id);

static struct spi_driver adc084s021_driver = {
	.driver = {
		.name = ADC084S021_DRIVER_NAME,
		.of_match_table = of_match_ptr(adc084s021_of_match),
	},
	.probe = adc084s021_probe,
	.id_table = adc084s021_id,
};
module_spi_driver(adc084s021_driver);

MODULE_AUTHOR("Mårten Lindahl <martenli@axis.com>");
MODULE_DESCRIPTION("Texas Instruments ADC084S021");
MODULE_LICENSE("GPL v2");
MODULE_VERSION("1.0");
