/*
 * IIO DAC driver for Analog Devices AD8801 DAC
 *
 * Copyright (C) 2016 Gwenhael Goavec-Merou
 * 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.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 */

#include <linux/iio/iio.h>
#include <linux/module.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
#include <linux/sysfs.h>

#define AD8801_CFG_ADDR_OFFSET 8

enum ad8801_device_ids {
	ID_AD8801,
	ID_AD8803,
};

struct ad8801_state {
	struct spi_device *spi;
	unsigned char dac_cache[8]; /* Value write on each channel */
	unsigned int vrefh_mv;
	unsigned int vrefl_mv;
	struct regulator *vrefh_reg;
	struct regulator *vrefl_reg;

	__be16 data ____cacheline_aligned;
};

static int ad8801_spi_write(struct ad8801_state *state,
	u8 channel, unsigned char value)
{
	state->data = cpu_to_be16((channel << AD8801_CFG_ADDR_OFFSET) | value);
	return spi_write(state->spi, &state->data, sizeof(state->data));
}

static int ad8801_write_raw(struct iio_dev *indio_dev,
	struct iio_chan_spec const *chan, int val, int val2, long mask)
{
	struct ad8801_state *state = iio_priv(indio_dev);
	int ret;

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

		ret = ad8801_spi_write(state, chan->channel, val);
		if (ret == 0)
			state->dac_cache[chan->channel] = val;
		break;
	default:
		ret = -EINVAL;
	}

	return ret;
}

static int ad8801_read_raw(struct iio_dev *indio_dev,
	struct iio_chan_spec const *chan, int *val, int *val2, long info)
{
	struct ad8801_state *state = iio_priv(indio_dev);

	switch (info) {
	case IIO_CHAN_INFO_RAW:
		*val = state->dac_cache[chan->channel];
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		*val = state->vrefh_mv - state->vrefl_mv;
		*val2 = 8;
		return IIO_VAL_FRACTIONAL_LOG2;
	case IIO_CHAN_INFO_OFFSET:
		*val = state->vrefl_mv;
		return IIO_VAL_INT;
	default:
		return -EINVAL;
	}

	return -EINVAL;
}

static const struct iio_info ad8801_info = {
	.read_raw = ad8801_read_raw,
	.write_raw = ad8801_write_raw,
	.driver_module = THIS_MODULE,
};

#define AD8801_CHANNEL(chan) {		\
	.type = IIO_VOLTAGE,			\
	.indexed = 1,				\
	.output = 1,				\
	.channel = chan,			\
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
		BIT(IIO_CHAN_INFO_OFFSET), \
}

static const struct iio_chan_spec ad8801_channels[] = {
	AD8801_CHANNEL(0),
	AD8801_CHANNEL(1),
	AD8801_CHANNEL(2),
	AD8801_CHANNEL(3),
	AD8801_CHANNEL(4),
	AD8801_CHANNEL(5),
	AD8801_CHANNEL(6),
	AD8801_CHANNEL(7),
};

static int ad8801_probe(struct spi_device *spi)
{
	struct iio_dev *indio_dev;
	struct ad8801_state *state;
	const struct spi_device_id *id;
	int ret;

	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*state));
	if (indio_dev == NULL)
		return -ENOMEM;

	state = iio_priv(indio_dev);
	state->spi = spi;
	id = spi_get_device_id(spi);

	state->vrefh_reg = devm_regulator_get(&spi->dev, "vrefh");
	if (IS_ERR(state->vrefh_reg)) {
		dev_err(&spi->dev, "Vrefh regulator not specified\n");
		return PTR_ERR(state->vrefh_reg);
	}

	ret = regulator_enable(state->vrefh_reg);
	if (ret) {
		dev_err(&spi->dev, "Failed to enable vrefh regulator: %d\n",
				ret);
		return ret;
	}

	ret = regulator_get_voltage(state->vrefh_reg);
	if (ret < 0) {
		dev_err(&spi->dev, "Failed to read vrefh regulator: %d\n",
				ret);
		goto error_disable_vrefh_reg;
	}
	state->vrefh_mv = ret / 1000;

	if (id->driver_data == ID_AD8803) {
		state->vrefl_reg = devm_regulator_get(&spi->dev, "vrefl");
		if (IS_ERR(state->vrefl_reg)) {
			dev_err(&spi->dev, "Vrefl regulator not specified\n");
			ret = PTR_ERR(state->vrefl_reg);
			goto error_disable_vrefh_reg;
		}

		ret = regulator_enable(state->vrefl_reg);
		if (ret) {
			dev_err(&spi->dev, "Failed to enable vrefl regulator: %d\n",
					ret);
			goto error_disable_vrefh_reg;
		}

		ret = regulator_get_voltage(state->vrefl_reg);
		if (ret < 0) {
			dev_err(&spi->dev, "Failed to read vrefl regulator: %d\n",
					ret);
			goto error_disable_vrefl_reg;
		}
		state->vrefl_mv = ret / 1000;
	} else {
		state->vrefl_mv = 0;
		state->vrefl_reg = NULL;
	}

	spi_set_drvdata(spi, indio_dev);
	indio_dev->dev.parent = &spi->dev;
	indio_dev->info = &ad8801_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = ad8801_channels;
	indio_dev->num_channels = ARRAY_SIZE(ad8801_channels);
	indio_dev->name = id->name;

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

	return 0;

error_disable_vrefl_reg:
	if (state->vrefl_reg)
		regulator_disable(state->vrefl_reg);
error_disable_vrefh_reg:
	regulator_disable(state->vrefh_reg);
	return ret;
}

static int ad8801_remove(struct spi_device *spi)
{
	struct iio_dev *indio_dev = spi_get_drvdata(spi);
	struct ad8801_state *state = iio_priv(indio_dev);

	iio_device_unregister(indio_dev);
	if (state->vrefl_reg)
		regulator_disable(state->vrefl_reg);
	regulator_disable(state->vrefh_reg);

	return 0;
}

static const struct spi_device_id ad8801_ids[] = {
	{"ad8801", ID_AD8801},
	{"ad8803", ID_AD8803},
	{}
};
MODULE_DEVICE_TABLE(spi, ad8801_ids);

static struct spi_driver ad8801_driver = {
	.driver = {
		.name	= "ad8801",
	},
	.probe		= ad8801_probe,
	.remove		= ad8801_remove,
	.id_table	= ad8801_ids,
};
module_spi_driver(ad8801_driver);

MODULE_AUTHOR("Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>");
MODULE_DESCRIPTION("Analog Devices AD8801/AD8803 DAC");
MODULE_LICENSE("GPL v2");
