/*
 * AD5421 Digital to analog converters  driver
 *
 * Copyright 2011 Analog Devices Inc.
 *
 * Licensed under the GPL-2.
 */

#include <linux/device.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/sysfs.h>

#include "../iio.h"
#include "../sysfs.h"
#include "../events.h"
#include "dac.h"
#include "ad5421.h"


#define AD5421_REG_DAC_DATA		0x1
#define AD5421_REG_CTRL			0x2
#define AD5421_REG_OFFSET		0x3
#define AD5421_REG_GAIN			0x4
/* load dac and fault shared the same register number. Writing to it will cause
 * a dac load command, reading from it will return the fault status register */
#define AD5421_REG_LOAD_DAC		0x5
#define AD5421_REG_FAULT		0x5
#define AD5421_REG_FORCE_ALARM_CURRENT	0x6
#define AD5421_REG_RESET		0x7
#define AD5421_REG_START_CONVERSION	0x8
#define AD5421_REG_NOOP			0x9

#define AD5421_CTRL_WATCHDOG_DISABLE	BIT(12)
#define AD5421_CTRL_AUTO_FAULT_READBACK	BIT(11)
#define AD5421_CTRL_MIN_CURRENT		BIT(9)
#define AD5421_CTRL_ADC_SOURCE_TEMP	BIT(8)
#define AD5421_CTRL_ADC_ENABLE		BIT(7)
#define AD5421_CTRL_PWR_DOWN_INT_VREF	BIT(6)

#define AD5421_FAULT_SPI			BIT(15)
#define AD5421_FAULT_PEC			BIT(14)
#define AD5421_FAULT_OVER_CURRENT		BIT(13)
#define AD5421_FAULT_UNDER_CURRENT		BIT(12)
#define AD5421_FAULT_TEMP_OVER_140		BIT(11)
#define AD5421_FAULT_TEMP_OVER_100		BIT(10)
#define AD5421_FAULT_UNDER_VOLTAGE_6V		BIT(9)
#define AD5421_FAULT_UNDER_VOLTAGE_12V		BIT(8)

/* These bits will cause the fault pin to go high */
#define AD5421_FAULT_TRIGGER_IRQ \
	(AD5421_FAULT_SPI | AD5421_FAULT_PEC | AD5421_FAULT_OVER_CURRENT | \
	AD5421_FAULT_UNDER_CURRENT | AD5421_FAULT_TEMP_OVER_140)

/**
 * struct ad5421_state - driver instance specific data
 * @spi:		spi_device
 * @ctrl:		control register cache
 * @current_range:	current range which the device is configured for
 * @data:		spi transfer buffers
 * @fault_mask:		software masking of events
 */
struct ad5421_state {
	struct spi_device		*spi;
	unsigned int			ctrl;
	enum ad5421_current_range	current_range;
	unsigned int			fault_mask;

	/*
	 * DMA (thus cache coherency maintenance) requires the
	 * transfer buffers to live in their own cache lines.
	 */
	union {
		u32 d32;
		u8 d8[4];
	} data[2] ____cacheline_aligned;
};

static const struct iio_chan_spec ad5421_channels[] = {
	{
		.type = IIO_CURRENT,
		.indexed = 1,
		.output = 1,
		.channel = 0,
		.info_mask = IIO_CHAN_INFO_SCALE_SHARED_BIT |
			IIO_CHAN_INFO_OFFSET_SHARED_BIT |
			IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |
			IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,
		.scan_type = IIO_ST('u', 16, 16, 0),
		.event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
			IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING),
	},
	{
		.type = IIO_TEMP,
		.channel = -1,
		.event_mask = IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING),
	},
};

static int ad5421_write_unlocked(struct iio_dev *indio_dev,
	unsigned int reg, unsigned int val)
{
	struct ad5421_state *st = iio_priv(indio_dev);

	st->data[0].d32 = cpu_to_be32((reg << 16) | val);

	return spi_write(st->spi, &st->data[0].d8[1], 3);
}

static int ad5421_write(struct iio_dev *indio_dev, unsigned int reg,
	unsigned int val)
{
	int ret;

	mutex_lock(&indio_dev->mlock);
	ret = ad5421_write_unlocked(indio_dev, reg, val);
	mutex_unlock(&indio_dev->mlock);

	return ret;
}

static int ad5421_read(struct iio_dev *indio_dev, unsigned int reg)
{
	struct ad5421_state *st = iio_priv(indio_dev);
	struct spi_message m;
	int ret;
	struct spi_transfer t[] = {
		{
			.tx_buf = &st->data[0].d8[1],
			.len = 3,
			.cs_change = 1,
		}, {
			.rx_buf = &st->data[1].d8[1],
			.len = 3,
		},
	};

	spi_message_init(&m);
	spi_message_add_tail(&t[0], &m);
	spi_message_add_tail(&t[1], &m);

	mutex_lock(&indio_dev->mlock);

	st->data[0].d32 = cpu_to_be32((1 << 23) | (reg << 16));

	ret = spi_sync(st->spi, &m);
	if (ret >= 0)
		ret = be32_to_cpu(st->data[1].d32) & 0xffff;

	mutex_unlock(&indio_dev->mlock);

	return ret;
}

static int ad5421_update_ctrl(struct iio_dev *indio_dev, unsigned int set,
	unsigned int clr)
{
	struct ad5421_state *st = iio_priv(indio_dev);
	unsigned int ret;

	mutex_lock(&indio_dev->mlock);

	st->ctrl &= ~clr;
	st->ctrl |= set;

	ret = ad5421_write_unlocked(indio_dev, AD5421_REG_CTRL, st->ctrl);

	mutex_unlock(&indio_dev->mlock);

	return ret;
}

static irqreturn_t ad5421_fault_handler(int irq, void *data)
{
	struct iio_dev *indio_dev = data;
	struct ad5421_state *st = iio_priv(indio_dev);
	unsigned int fault;
	unsigned int old_fault = 0;
	unsigned int events;

	fault = ad5421_read(indio_dev, AD5421_REG_FAULT);
	if (!fault)
		return IRQ_NONE;

	/* If we had a fault, this might mean that the DAC has lost its state
	 * and has been reset. Make sure that the control register actually
	 * contains what we expect it to contain. Otherwise the watchdog might
	 * be enabled and we get watchdog timeout faults, which will render the
	 * DAC unusable. */
	ad5421_update_ctrl(indio_dev, 0, 0);


	/* The fault pin stays high as long as a fault condition is present and
	 * it is not possible to mask fault conditions. For certain fault
	 * conditions for example like over-temperature it takes some time
	 * until the fault condition disappears. If we would exit the interrupt
	 * handler immediately after handling the event it would be entered
	 * again instantly. Thus we fall back to polling in case we detect that
	 * a interrupt condition is still present.
	 */
	do {
		/* 0xffff is a invalid value for the register and will only be
		 * read if there has been a communication error */
		if (fault == 0xffff)
			fault = 0;

		/* we are only interested in new events */
		events = (old_fault ^ fault) & fault;
		events &= st->fault_mask;

		if (events & AD5421_FAULT_OVER_CURRENT) {
			iio_push_event(indio_dev,
				IIO_UNMOD_EVENT_CODE(IIO_CURRENT,
					0,
					IIO_EV_TYPE_THRESH,
					IIO_EV_DIR_RISING),
			iio_get_time_ns());
		}

		if (events & AD5421_FAULT_UNDER_CURRENT) {
			iio_push_event(indio_dev,
				IIO_UNMOD_EVENT_CODE(IIO_CURRENT,
					0,
					IIO_EV_TYPE_THRESH,
					IIO_EV_DIR_FALLING),
				iio_get_time_ns());
		}

		if (events & AD5421_FAULT_TEMP_OVER_140) {
			iio_push_event(indio_dev,
				IIO_UNMOD_EVENT_CODE(IIO_TEMP,
					0,
					IIO_EV_TYPE_MAG,
					IIO_EV_DIR_RISING),
				iio_get_time_ns());
		}

		old_fault = fault;
		fault = ad5421_read(indio_dev, AD5421_REG_FAULT);

		/* still active? go to sleep for some time */
		if (fault & AD5421_FAULT_TRIGGER_IRQ)
			msleep(1000);

	} while (fault & AD5421_FAULT_TRIGGER_IRQ);


	return IRQ_HANDLED;
}

static void ad5421_get_current_min_max(struct ad5421_state *st,
	unsigned int *min, unsigned int *max)
{
	/* The current range is configured using external pins, which are
	 * usually hard-wired and not run-time switchable. */
	switch (st->current_range) {
	case AD5421_CURRENT_RANGE_4mA_20mA:
		*min = 4000;
		*max = 20000;
		break;
	case AD5421_CURRENT_RANGE_3mA8_21mA:
		*min = 3800;
		*max = 21000;
		break;
	case AD5421_CURRENT_RANGE_3mA2_24mA:
		*min = 3200;
		*max = 24000;
		break;
	default:
		*min = 0;
		*max = 1;
		break;
	}
}

static inline unsigned int ad5421_get_offset(struct ad5421_state *st)
{
	unsigned int min, max;

	ad5421_get_current_min_max(st, &min, &max);
	return (min * (1 << 16)) / (max - min);
}

static inline unsigned int ad5421_get_scale(struct ad5421_state *st)
{
	unsigned int min, max;

	ad5421_get_current_min_max(st, &min, &max);
	return ((max - min) * 1000) / (1 << 16);
}

static int ad5421_read_raw(struct iio_dev *indio_dev,
	struct iio_chan_spec const *chan, int *val, int *val2, long m)
{
	struct ad5421_state *st = iio_priv(indio_dev);
	int ret;

	if (chan->type != IIO_CURRENT)
		return -EINVAL;

	switch (m) {
	case 0:
		ret = ad5421_read(indio_dev, AD5421_REG_DAC_DATA);
		if (ret < 0)
			return ret;
		*val = ret;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		*val = 0;
		*val2 = ad5421_get_scale(st);
		return IIO_VAL_INT_PLUS_MICRO;
	case IIO_CHAN_INFO_OFFSET:
		*val = ad5421_get_offset(st);
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_CALIBBIAS:
		ret = ad5421_read(indio_dev, AD5421_REG_OFFSET);
		if (ret < 0)
			return ret;
		*val = ret - 32768;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_CALIBSCALE:
		ret = ad5421_read(indio_dev, AD5421_REG_GAIN);
		if (ret < 0)
			return ret;
		*val = ret;
		return IIO_VAL_INT;
	}

	return -EINVAL;
}

static int ad5421_write_raw(struct iio_dev *indio_dev,
	struct iio_chan_spec const *chan, int val, int val2, long mask)
{
	const unsigned int max_val = 1 << 16;

	switch (mask) {
	case 0:
		if (val >= max_val || val < 0)
			return -EINVAL;

		return ad5421_write(indio_dev, AD5421_REG_DAC_DATA, val);
	case IIO_CHAN_INFO_CALIBBIAS:
		val += 32768;
		if (val >= max_val || val < 0)
			return -EINVAL;

		return ad5421_write(indio_dev, AD5421_REG_OFFSET, val);
	case IIO_CHAN_INFO_CALIBSCALE:
		if (val >= max_val || val < 0)
			return -EINVAL;

		return ad5421_write(indio_dev, AD5421_REG_GAIN, val);
	default:
		break;
	}

	return -EINVAL;
}

static int ad5421_write_event_config(struct iio_dev *indio_dev,
	u64 event_code, int state)
{
	struct ad5421_state *st = iio_priv(indio_dev);
	unsigned int mask;

	switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
	case IIO_CURRENT:
		if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
			IIO_EV_DIR_RISING)
			mask = AD5421_FAULT_OVER_CURRENT;
		else
			mask = AD5421_FAULT_UNDER_CURRENT;
		break;
	case IIO_TEMP:
		mask = AD5421_FAULT_TEMP_OVER_140;
		break;
	default:
		return -EINVAL;
	}

	mutex_lock(&indio_dev->mlock);
	if (state)
		st->fault_mask |= mask;
	else
		st->fault_mask &= ~mask;
	mutex_unlock(&indio_dev->mlock);

	return 0;
}

static int ad5421_read_event_config(struct iio_dev *indio_dev,
	u64 event_code)
{
	struct ad5421_state *st = iio_priv(indio_dev);
	unsigned int mask;

	switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
	case IIO_CURRENT:
		if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
			IIO_EV_DIR_RISING)
			mask = AD5421_FAULT_OVER_CURRENT;
		else
			mask = AD5421_FAULT_UNDER_CURRENT;
		break;
	case IIO_TEMP:
		mask = AD5421_FAULT_TEMP_OVER_140;
		break;
	default:
		return -EINVAL;
	}

	return (bool)(st->fault_mask & mask);
}

static int ad5421_read_event_value(struct iio_dev *indio_dev, u64 event_code,
	int *val)
{
	int ret;

	switch (IIO_EVENT_CODE_EXTRACT_CHAN_TYPE(event_code)) {
	case IIO_CURRENT:
		ret = ad5421_read(indio_dev, AD5421_REG_DAC_DATA);
		if (ret < 0)
			return ret;
		*val = ret;
		break;
	case IIO_TEMP:
		*val = 140000;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static const struct iio_info ad5421_info = {
	.read_raw =		ad5421_read_raw,
	.write_raw =		ad5421_write_raw,
	.read_event_config =	ad5421_read_event_config,
	.write_event_config =	ad5421_write_event_config,
	.read_event_value =	ad5421_read_event_value,
	.driver_module =	THIS_MODULE,
};

static int __devinit ad5421_probe(struct spi_device *spi)
{
	struct ad5421_platform_data *pdata = dev_get_platdata(&spi->dev);
	struct iio_dev *indio_dev;
	struct ad5421_state *st;
	int ret;

	indio_dev = iio_allocate_device(sizeof(*st));
	if (indio_dev == NULL) {
		dev_err(&spi->dev, "Failed to allocate iio device\n");
		return  -ENOMEM;
	}

	st = iio_priv(indio_dev);
	spi_set_drvdata(spi, indio_dev);

	st->spi = spi;

	indio_dev->dev.parent = &spi->dev;
	indio_dev->name = "ad5421";
	indio_dev->info = &ad5421_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = ad5421_channels;
	indio_dev->num_channels = ARRAY_SIZE(ad5421_channels);

	st->ctrl = AD5421_CTRL_WATCHDOG_DISABLE |
			AD5421_CTRL_AUTO_FAULT_READBACK;

	if (pdata) {
		st->current_range = pdata->current_range;
		if (pdata->external_vref)
			st->ctrl |= AD5421_CTRL_PWR_DOWN_INT_VREF;
	} else {
		st->current_range = AD5421_CURRENT_RANGE_4mA_20mA;
	}

	/* write initial ctrl register value */
	ad5421_update_ctrl(indio_dev, 0, 0);

	if (spi->irq) {
		ret = request_threaded_irq(spi->irq,
					   NULL,
					   ad5421_fault_handler,
					   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
					   "ad5421 fault",
					   indio_dev);
		if (ret)
			goto error_free;
	}

	ret = iio_device_register(indio_dev);
	if (ret) {
		dev_err(&spi->dev, "Failed to register iio device: %d\n", ret);
		goto error_free_irq;
	}

	return 0;

error_free_irq:
	if (spi->irq)
		free_irq(spi->irq, indio_dev);
error_free:
	iio_free_device(indio_dev);

	return ret;
}

static int __devexit ad5421_remove(struct spi_device *spi)
{
	struct iio_dev *indio_dev = spi_get_drvdata(spi);

	iio_device_unregister(indio_dev);
	if (spi->irq)
		free_irq(spi->irq, indio_dev);
	iio_free_device(indio_dev);

	return 0;
}

static struct spi_driver ad5421_driver = {
	.driver = {
		   .name = "ad5421",
		   .owner = THIS_MODULE,
	},
	.probe = ad5421_probe,
	.remove = __devexit_p(ad5421_remove),
};

static __init int ad5421_init(void)
{
	return spi_register_driver(&ad5421_driver);
}
module_init(ad5421_init);

static __exit void ad5421_exit(void)
{
	spi_unregister_driver(&ad5421_driver);
}
module_exit(ad5421_exit);

MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("Analog Devices AD5421 DAC");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("spi:ad5421");
