/*
 * 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 <linux/iio/iio.h>
#include <linux/iio/sysfs.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 = IIO_CHAN_INFO_RAW_SEPARATE_BIT |		\
		IIO_CHAN_INFO_SCALE_SEPARATE_BIT |		\
		IIO_CHAN_INFO_OFFSET_SEPARATE_BIT |		\
		IIO_CHAN_INFO_CALIBSCALE_SEPARATE_BIT |	\
		IIO_CHAN_INFO_CALIBBIAS_SEPARATE_BIT,	\
	.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_to_iio_dev(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_to_iio_dev(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 IIO_CHAN_INFO_RAW:
		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 IIO_CHAN_INFO_CALIBBIAS:
		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 IIO_CHAN_INFO_CALIBSCALE:
		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 IIO_CHAN_INFO_OFFSET:
		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 int ofs_index;
	int scale_uv;
	int ret;

	switch (m) {
	case IIO_CHAN_INFO_RAW:
		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 IIO_CHAN_INFO_SCALE:
		/* 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 IIO_CHAN_INFO_CALIBBIAS:
		ret = ad5360_read(indio_dev, AD5360_READBACK_OFFSET,
			chan->address);
		if (ret < 0)
			return ret;
		*val = ret;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_CALIBSCALE:
		ret = ad5360_read(indio_dev, AD5360_READBACK_GAIN,
			chan->address);
		if (ret < 0)
			return ret;
		*val = ret;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_OFFSET:
		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(st->chip_info->num_channels,
			   sizeof(struct iio_chan_spec), 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_device_alloc(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_device_free(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_device_free(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,
};
module_spi_driver(ad5360_driver);

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