/**
 * 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;
	/* Buffer used to align data */
	struct {
		__be16 channels[4];
		s64 ts __aligned(8);
	} scan;
	/*
	 * 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);

	mutex_lock(&adc->lock);

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

	iio_push_to_buffers_with_timestamp(indio_dev, &adc->scan,
					   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");
