/*
 * Analog devices AD5360, AD5361, AD5362, AD5363, AD5370, AD5371, AD5373
 * multi-channel Digital to Analog Converters driver
 *
 * Copyright 2011 Analog Devices Inc.
 *
 * Licensed under the GPL-2.
 */

#include <linux/device.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/regulator/consumer.h>

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

#define AD5360_CMD(x)				((x) << 22)
#define AD5360_ADDR(x)				((x) << 16)

#define AD5360_READBACK_TYPE(x)			((x) << 13)
#define AD5360_READBACK_ADDR(x)			((x) << 7)

#define AD5360_CHAN_ADDR(chan)			((chan) + 0x8)

#define AD5360_CMD_WRITE_DATA			0x3
#define AD5360_CMD_WRITE_OFFSET			0x2
#define AD5360_CMD_WRITE_GAIN			0x1
#define AD5360_CMD_SPECIAL_FUNCTION		0x0

/* Special function register addresses */
#define AD5360_REG_SF_NOP			0x0
#define AD5360_REG_SF_CTRL			0x1
#define AD5360_REG_SF_OFS(x)			(0x2 + (x))
#define AD5360_REG_SF_READBACK			0x5

#define AD5360_SF_CTRL_PWR_DOWN			BIT(0)

#define AD5360_READBACK_X1A			0x0
#define AD5360_READBACK_X1B			0x1
#define AD5360_READBACK_OFFSET			0x2
#define AD5360_READBACK_GAIN			0x3
#define AD5360_READBACK_SF			0x4


/**
 * struct ad5360_chip_info - chip specific information
 * @channel_template:	channel specification template
 * @num_channels:	number of channels
 * @channels_per_group:	number of channels per group
 * @num_vrefs:		number of vref supplies for the chip
*/

struct ad5360_chip_info {
	struct iio_chan_spec	channel_template;
	unsigned int		num_channels;
	unsigned int		channels_per_group;
	unsigned int		num_vrefs;
};

/**
 * struct ad5360_state - driver instance specific data
 * @spi:		spi_device
 * @chip_info:		chip model specific constants, available modes etc
 * @vref_reg:		vref supply regulators
 * @ctrl:		control register cache
 * @data:		spi transfer buffers
 */

struct ad5360_state {
	struct spi_device		*spi;
	const struct ad5360_chip_info	*chip_info;
	struct regulator_bulk_data	vref_reg[3];
	unsigned int			ctrl;

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

enum ad5360_type {
	ID_AD5360,
	ID_AD5361,
	ID_AD5362,
	ID_AD5363,
	ID_AD5370,
	ID_AD5371,
	ID_AD5372,
	ID_AD5373,
};

#define AD5360_CHANNEL(bits) {					\
	.type = IIO_VOLTAGE,					\
	.indexed = 1,						\
	.output = 1,						\
	.info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |	\
		(1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |		\
		(1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |	\
		(1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),	\
	.scan_type = IIO_ST('u', (bits), 16, 16 - (bits))	\
}

static const struct ad5360_chip_info ad5360_chip_info_tbl[] = {
	[ID_AD5360] = {
		.channel_template = AD5360_CHANNEL(16),
		.num_channels = 16,
		.channels_per_group = 8,
		.num_vrefs = 2,
	},
	[ID_AD5361] = {
		.channel_template = AD5360_CHANNEL(14),
		.num_channels = 16,
		.channels_per_group = 8,
		.num_vrefs = 2,
	},
	[ID_AD5362] = {
		.channel_template = AD5360_CHANNEL(16),
		.num_channels = 8,
		.channels_per_group = 4,
		.num_vrefs = 2,
	},
	[ID_AD5363] = {
		.channel_template = AD5360_CHANNEL(14),
		.num_channels = 8,
		.channels_per_group = 4,
		.num_vrefs = 2,
	},
	[ID_AD5370] = {
		.channel_template = AD5360_CHANNEL(16),
		.num_channels = 40,
		.channels_per_group = 8,
		.num_vrefs = 2,
	},
	[ID_AD5371] = {
		.channel_template = AD5360_CHANNEL(14),
		.num_channels = 40,
		.channels_per_group = 8,
		.num_vrefs = 3,
	},
	[ID_AD5372] = {
		.channel_template = AD5360_CHANNEL(16),
		.num_channels = 32,
		.channels_per_group = 8,
		.num_vrefs = 2,
	},
	[ID_AD5373] = {
		.channel_template = AD5360_CHANNEL(14),
		.num_channels = 32,
		.channels_per_group = 8,
		.num_vrefs = 2,
	},
};

static unsigned int ad5360_get_channel_vref_index(struct ad5360_state *st,
	unsigned int channel)
{
	unsigned int i;

	/* The first groups have their own vref, while the remaining groups
	 * share the last vref */
	i = channel / st->chip_info->channels_per_group;
	if (i >= st->chip_info->num_vrefs)
		i = st->chip_info->num_vrefs - 1;

	return i;
}

static int ad5360_get_channel_vref(struct ad5360_state *st,
	unsigned int channel)
{
	unsigned int i = ad5360_get_channel_vref_index(st, channel);

	return regulator_get_voltage(st->vref_reg[i].consumer);
}


static int ad5360_write_unlocked(struct iio_dev *indio_dev,
	unsigned int cmd, unsigned int addr, unsigned int val,
	unsigned int shift)
{
	struct ad5360_state *st = iio_priv(indio_dev);

	val <<= shift;
	val |= AD5360_CMD(cmd) | AD5360_ADDR(addr);
	st->data[0].d32 = cpu_to_be32(val);

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

static int ad5360_write(struct iio_dev *indio_dev, unsigned int cmd,
	unsigned int addr, unsigned int val, unsigned int shift)
{
	int ret;

	mutex_lock(&indio_dev->mlock);
	ret = ad5360_write_unlocked(indio_dev, cmd, addr, val, shift);
	mutex_unlock(&indio_dev->mlock);

	return ret;
}

static int ad5360_read(struct iio_dev *indio_dev, unsigned int type,
	unsigned int addr)
{
	struct ad5360_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(AD5360_CMD(AD5360_CMD_SPECIAL_FUNCTION) |
		AD5360_ADDR(AD5360_REG_SF_READBACK) |
		AD5360_READBACK_TYPE(type) |
		AD5360_READBACK_ADDR(addr));

	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 ssize_t ad5360_read_dac_powerdown(struct device *dev,
					   struct device_attribute *attr,
					   char *buf)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct ad5360_state *st = iio_priv(indio_dev);

	return sprintf(buf, "%d\n", (bool)(st->ctrl & AD5360_SF_CTRL_PWR_DOWN));
}

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

	mutex_lock(&indio_dev->mlock);

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

	ret = ad5360_write_unlocked(indio_dev, AD5360_CMD_SPECIAL_FUNCTION,
			AD5360_REG_SF_CTRL, st->ctrl, 0);

	mutex_unlock(&indio_dev->mlock);

	return ret;
}

static ssize_t ad5360_write_dac_powerdown(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t len)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	bool pwr_down;
	int ret;

	ret = strtobool(buf, &pwr_down);
	if (ret)
		return ret;

	if (pwr_down)
		ret = ad5360_update_ctrl(indio_dev, AD5360_SF_CTRL_PWR_DOWN, 0);
	else
		ret = ad5360_update_ctrl(indio_dev, 0, AD5360_SF_CTRL_PWR_DOWN);

	return ret ? ret : len;
}

static IIO_DEVICE_ATTR(out_voltage_powerdown,
			S_IRUGO | S_IWUSR,
			ad5360_read_dac_powerdown,
			ad5360_write_dac_powerdown, 0);

static struct attribute *ad5360_attributes[] = {
	&iio_dev_attr_out_voltage_powerdown.dev_attr.attr,
	NULL,
};

static const struct attribute_group ad5360_attribute_group = {
	.attrs = ad5360_attributes,
};

static int ad5360_write_raw(struct iio_dev *indio_dev,
			       struct iio_chan_spec const *chan,
			       int val,
			       int val2,
			       long mask)
{
	struct ad5360_state *st = iio_priv(indio_dev);
	int max_val = (1 << chan->scan_type.realbits);
	unsigned int ofs_index;

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

		return ad5360_write(indio_dev, AD5360_CMD_WRITE_DATA,
				 chan->address, val, chan->scan_type.shift);

	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
		if (val >= max_val || val < 0)
			return -EINVAL;

		return ad5360_write(indio_dev, AD5360_CMD_WRITE_OFFSET,
				 chan->address, val, chan->scan_type.shift);

	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
		if (val >= max_val || val < 0)
			return -EINVAL;

		return ad5360_write(indio_dev, AD5360_CMD_WRITE_GAIN,
				 chan->address, val, chan->scan_type.shift);

	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
		if (val <= -max_val || val > 0)
			return -EINVAL;

		val = -val;

		/* offset is supposed to have the same scale as raw, but it
		 * is always 14bits wide, so on a chip where the raw value has
		 * more bits, we need to shift offset. */
		val >>= (chan->scan_type.realbits - 14);

		/* There is one DAC offset register per vref. Changing one
		 * channels offset will also change the offset for all other
		 * channels which share the same vref supply. */
		ofs_index = ad5360_get_channel_vref_index(st, chan->channel);
		return ad5360_write(indio_dev, AD5360_CMD_SPECIAL_FUNCTION,
				 AD5360_REG_SF_OFS(ofs_index), val, 0);
	default:
		break;
	}

	return -EINVAL;
}

static int ad5360_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan,
			   int *val,
			   int *val2,
			   long m)
{
	struct ad5360_state *st = iio_priv(indio_dev);
	unsigned long scale_uv;
	unsigned int ofs_index;
	int ret;

	switch (m) {
	case 0:
		ret = ad5360_read(indio_dev, AD5360_READBACK_X1A,
			chan->address);
		if (ret < 0)
			return ret;
		*val = ret >> chan->scan_type.shift;
		return IIO_VAL_INT;
	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
		/* vout = 4 * vref * dac_code */
		scale_uv = ad5360_get_channel_vref(st, chan->channel) * 4 * 100;
		if (scale_uv < 0)
			return scale_uv;

		scale_uv >>= (chan->scan_type.realbits);
		*val =  scale_uv / 100000;
		*val2 = (scale_uv % 100000) * 10;
		return IIO_VAL_INT_PLUS_MICRO;
	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
		ret = ad5360_read(indio_dev, AD5360_READBACK_OFFSET,
			chan->address);
		if (ret < 0)
			return ret;
		*val = ret;
		return IIO_VAL_INT;
	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
		ret = ad5360_read(indio_dev, AD5360_READBACK_GAIN,
			chan->address);
		if (ret < 0)
			return ret;
		*val = ret;
		return IIO_VAL_INT;
	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
		ofs_index = ad5360_get_channel_vref_index(st, chan->channel);
		ret = ad5360_read(indio_dev, AD5360_READBACK_SF,
			AD5360_REG_SF_OFS(ofs_index));
		if (ret < 0)
			return ret;

		ret <<= (chan->scan_type.realbits - 14);
		*val = -ret;
		return IIO_VAL_INT;
	}

	return -EINVAL;
}

static const struct iio_info ad5360_info = {
	.read_raw = ad5360_read_raw,
	.write_raw = ad5360_write_raw,
	.attrs = &ad5360_attribute_group,
	.driver_module = THIS_MODULE,
};

static const char * const ad5360_vref_name[] = {
	 "vref0", "vref1", "vref2"
};

static int __devinit ad5360_alloc_channels(struct iio_dev *indio_dev)
{
	struct ad5360_state *st = iio_priv(indio_dev);
	struct iio_chan_spec *channels;
	unsigned int i;

	channels = kcalloc(sizeof(struct iio_chan_spec),
			st->chip_info->num_channels, GFP_KERNEL);

	if (!channels)
		return -ENOMEM;

	for (i = 0; i < st->chip_info->num_channels; ++i) {
		channels[i] = st->chip_info->channel_template;
		channels[i].channel = i;
		channels[i].address = AD5360_CHAN_ADDR(i);
	}

	indio_dev->channels = channels;

	return 0;
}

static int __devinit ad5360_probe(struct spi_device *spi)
{
	enum ad5360_type type = spi_get_device_id(spi)->driver_data;
	struct iio_dev *indio_dev;
	struct ad5360_state *st;
	unsigned int i;
	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->chip_info = &ad5360_chip_info_tbl[type];
	st->spi = spi;

	indio_dev->dev.parent = &spi->dev;
	indio_dev->name = spi_get_device_id(spi)->name;
	indio_dev->info = &ad5360_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->num_channels = st->chip_info->num_channels;

	ret = ad5360_alloc_channels(indio_dev);
	if (ret) {
		dev_err(&spi->dev, "Failed to allocate channel spec: %d\n", ret);
		goto error_free;
	}

	for (i = 0; i < st->chip_info->num_vrefs; ++i)
		st->vref_reg[i].supply = ad5360_vref_name[i];

	ret = regulator_bulk_get(&st->spi->dev, st->chip_info->num_vrefs,
		st->vref_reg);
	if (ret) {
		dev_err(&spi->dev, "Failed to request vref regulators: %d\n", ret);
		goto error_free_channels;
	}

	ret = regulator_bulk_enable(st->chip_info->num_vrefs, st->vref_reg);
	if (ret) {
		dev_err(&spi->dev, "Failed to enable vref regulators: %d\n", ret);
		goto error_free_reg;
	}

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

	return 0;

error_disable_reg:
	regulator_bulk_disable(st->chip_info->num_vrefs, st->vref_reg);
error_free_reg:
	regulator_bulk_free(st->chip_info->num_vrefs, st->vref_reg);
error_free_channels:
	kfree(indio_dev->channels);
error_free:
	iio_free_device(indio_dev);

	return ret;
}

static int __devexit ad5360_remove(struct spi_device *spi)
{
	struct iio_dev *indio_dev = spi_get_drvdata(spi);
	struct ad5360_state *st = iio_priv(indio_dev);

	iio_device_unregister(indio_dev);

	kfree(indio_dev->channels);

	regulator_bulk_disable(st->chip_info->num_vrefs, st->vref_reg);
	regulator_bulk_free(st->chip_info->num_vrefs, st->vref_reg);

	iio_free_device(indio_dev);

	return 0;
}

static const struct spi_device_id ad5360_ids[] = {
	{ "ad5360", ID_AD5360 },
	{ "ad5361", ID_AD5361 },
	{ "ad5362", ID_AD5362 },
	{ "ad5363", ID_AD5363 },
	{ "ad5370", ID_AD5370 },
	{ "ad5371", ID_AD5371 },
	{ "ad5372", ID_AD5372 },
	{ "ad5373", ID_AD5373 },
	{}
};
MODULE_DEVICE_TABLE(spi, ad5360_ids);

static struct spi_driver ad5360_driver = {
	.driver = {
		   .name = "ad5360",
		   .owner = THIS_MODULE,
	},
	.probe = ad5360_probe,
	.remove = __devexit_p(ad5360_remove),
	.id_table = ad5360_ids,
};

static __init int ad5360_spi_init(void)
{
	return spi_register_driver(&ad5360_driver);
}
module_init(ad5360_spi_init);

static __exit void ad5360_spi_exit(void)
{
	spi_unregister_driver(&ad5360_driver);
}
module_exit(ad5360_spi_exit);

MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("Analog Devices AD5360/61/62/63/70/71/72/73 DAC");
MODULE_LICENSE("GPL v2");
