/*
 * AD5592R Digital <-> Analog converters driver
 *
 * Copyright 2014-2016 Analog Devices Inc.
 * Author: Paul Cercueil <paul.cercueil@analog.com>
 *
 * Licensed under the GPL-2.
 */

#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/regulator/consumer.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h>
#include <linux/gpio.h>
#include <linux/property.h>

#include <dt-bindings/iio/adi,ad5592r.h>

#include "ad5592r-base.h"

static int ad5592r_gpio_get(struct gpio_chip *chip, unsigned offset)
{
	struct ad5592r_state *st = gpiochip_get_data(chip);
	int ret = 0;
	u8 val;

	mutex_lock(&st->gpio_lock);

	if (st->gpio_out & BIT(offset))
		val = st->gpio_val;
	else
		ret = st->ops->gpio_read(st, &val);

	mutex_unlock(&st->gpio_lock);

	if (ret < 0)
		return ret;

	return !!(val & BIT(offset));
}

static void ad5592r_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
	struct ad5592r_state *st = gpiochip_get_data(chip);

	mutex_lock(&st->gpio_lock);

	if (value)
		st->gpio_val |= BIT(offset);
	else
		st->gpio_val &= ~BIT(offset);

	st->ops->reg_write(st, AD5592R_REG_GPIO_SET, st->gpio_val);

	mutex_unlock(&st->gpio_lock);
}

static int ad5592r_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
{
	struct ad5592r_state *st = gpiochip_get_data(chip);
	int ret;

	mutex_lock(&st->gpio_lock);

	st->gpio_out &= ~BIT(offset);
	st->gpio_in |= BIT(offset);

	ret = st->ops->reg_write(st, AD5592R_REG_GPIO_OUT_EN, st->gpio_out);
	if (ret < 0)
		goto err_unlock;

	ret = st->ops->reg_write(st, AD5592R_REG_GPIO_IN_EN, st->gpio_in);

err_unlock:
	mutex_unlock(&st->gpio_lock);

	return ret;
}

static int ad5592r_gpio_direction_output(struct gpio_chip *chip,
					 unsigned offset, int value)
{
	struct ad5592r_state *st = gpiochip_get_data(chip);
	int ret;

	mutex_lock(&st->gpio_lock);

	if (value)
		st->gpio_val |= BIT(offset);
	else
		st->gpio_val &= ~BIT(offset);

	st->gpio_in &= ~BIT(offset);
	st->gpio_out |= BIT(offset);

	ret = st->ops->reg_write(st, AD5592R_REG_GPIO_SET, st->gpio_val);
	if (ret < 0)
		goto err_unlock;

	ret = st->ops->reg_write(st, AD5592R_REG_GPIO_OUT_EN, st->gpio_out);
	if (ret < 0)
		goto err_unlock;

	ret = st->ops->reg_write(st, AD5592R_REG_GPIO_IN_EN, st->gpio_in);

err_unlock:
	mutex_unlock(&st->gpio_lock);

	return ret;
}

static int ad5592r_gpio_request(struct gpio_chip *chip, unsigned offset)
{
	struct ad5592r_state *st = gpiochip_get_data(chip);

	if (!(st->gpio_map & BIT(offset))) {
		dev_err(st->dev, "GPIO %d is reserved by alternate function\n",
			offset);
		return -ENODEV;
	}

	return 0;
}

static int ad5592r_gpio_init(struct ad5592r_state *st)
{
	if (!st->gpio_map)
		return 0;

	st->gpiochip.label = dev_name(st->dev);
	st->gpiochip.base = -1;
	st->gpiochip.ngpio = 8;
	st->gpiochip.parent = st->dev;
	st->gpiochip.can_sleep = true;
	st->gpiochip.direction_input = ad5592r_gpio_direction_input;
	st->gpiochip.direction_output = ad5592r_gpio_direction_output;
	st->gpiochip.get = ad5592r_gpio_get;
	st->gpiochip.set = ad5592r_gpio_set;
	st->gpiochip.request = ad5592r_gpio_request;
	st->gpiochip.owner = THIS_MODULE;

	mutex_init(&st->gpio_lock);

	return gpiochip_add_data(&st->gpiochip, st);
}

static void ad5592r_gpio_cleanup(struct ad5592r_state *st)
{
	if (st->gpio_map)
		gpiochip_remove(&st->gpiochip);
}

static int ad5592r_reset(struct ad5592r_state *st)
{
	struct gpio_desc *gpio;
	struct iio_dev *iio_dev = iio_priv_to_dev(st);

	gpio = devm_gpiod_get_optional(st->dev, "reset", GPIOD_OUT_LOW);
	if (IS_ERR(gpio))
		return PTR_ERR(gpio);

	if (gpio) {
		udelay(1);
		gpiod_set_value(gpio, 1);
	} else {
		mutex_lock(&iio_dev->mlock);
		/* Writing this magic value resets the device */
		st->ops->reg_write(st, AD5592R_REG_RESET, 0xdac);
		mutex_unlock(&iio_dev->mlock);
	}

	udelay(250);

	return 0;
}

static int ad5592r_get_vref(struct ad5592r_state *st)
{
	int ret;

	if (st->reg) {
		ret = regulator_get_voltage(st->reg);
		if (ret < 0)
			return ret;

		return ret / 1000;
	} else {
		return 2500;
	}
}

static int ad5592r_set_channel_modes(struct ad5592r_state *st)
{
	const struct ad5592r_rw_ops *ops = st->ops;
	int ret;
	unsigned i;
	struct iio_dev *iio_dev = iio_priv_to_dev(st);
	u8 pulldown = 0, tristate = 0, dac = 0, adc = 0;
	u16 read_back;

	for (i = 0; i < st->num_channels; i++) {
		switch (st->channel_modes[i]) {
		case CH_MODE_DAC:
			dac |= BIT(i);
			break;

		case CH_MODE_ADC:
			adc |= BIT(i);
			break;

		case CH_MODE_DAC_AND_ADC:
			dac |= BIT(i);
			adc |= BIT(i);
			break;

		case CH_MODE_GPIO:
			st->gpio_map |= BIT(i);
			st->gpio_in |= BIT(i); /* Default to input */
			break;

		case CH_MODE_UNUSED:
			/* fall-through */
		default:
			switch (st->channel_offstate[i]) {
			case CH_OFFSTATE_OUT_TRISTATE:
				tristate |= BIT(i);
				break;

			case CH_OFFSTATE_OUT_LOW:
				st->gpio_out |= BIT(i);
				break;

			case CH_OFFSTATE_OUT_HIGH:
				st->gpio_out |= BIT(i);
				st->gpio_val |= BIT(i);
				break;

			case CH_OFFSTATE_PULLDOWN:
				/* fall-through */
			default:
				pulldown |= BIT(i);
				break;
			}
		}
	}

	mutex_lock(&iio_dev->mlock);

	/* Pull down unused pins to GND */
	ret = ops->reg_write(st, AD5592R_REG_PULLDOWN, pulldown);
	if (ret)
		goto err_unlock;

	ret = ops->reg_write(st, AD5592R_REG_TRISTATE, tristate);
	if (ret)
		goto err_unlock;

	/* Configure pins that we use */
	ret = ops->reg_write(st, AD5592R_REG_DAC_EN, dac);
	if (ret)
		goto err_unlock;

	ret = ops->reg_write(st, AD5592R_REG_ADC_EN, adc);
	if (ret)
		goto err_unlock;

	ret = ops->reg_write(st, AD5592R_REG_GPIO_SET, st->gpio_val);
	if (ret)
		goto err_unlock;

	ret = ops->reg_write(st, AD5592R_REG_GPIO_OUT_EN, st->gpio_out);
	if (ret)
		goto err_unlock;

	ret = ops->reg_write(st, AD5592R_REG_GPIO_IN_EN, st->gpio_in);
	if (ret)
		goto err_unlock;

	/* Verify that we can read back at least one register */
	ret = ops->reg_read(st, AD5592R_REG_ADC_EN, &read_back);
	if (!ret && (read_back & 0xff) != adc)
		ret = -EIO;

err_unlock:
	mutex_unlock(&iio_dev->mlock);
	return ret;
}

static int ad5592r_reset_channel_modes(struct ad5592r_state *st)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(st->channel_modes); i++)
		st->channel_modes[i] = CH_MODE_UNUSED;

	return ad5592r_set_channel_modes(st);
}

static int ad5592r_write_raw(struct iio_dev *iio_dev,
	struct iio_chan_spec const *chan, int val, int val2, long mask)
{
	struct ad5592r_state *st = iio_priv(iio_dev);
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:

		if (val >= (1 << chan->scan_type.realbits) || val < 0)
			return -EINVAL;

		if (!chan->output)
			return -EINVAL;

		mutex_lock(&iio_dev->mlock);
		ret = st->ops->write_dac(st, chan->channel, val);
		if (!ret)
			st->cached_dac[chan->channel] = val;
		mutex_unlock(&iio_dev->mlock);
		return ret;
	case IIO_CHAN_INFO_SCALE:
		if (chan->type == IIO_VOLTAGE) {
			bool gain;

			if (val == st->scale_avail[0][0] &&
				val2 == st->scale_avail[0][1])
				gain = false;
			else if (val == st->scale_avail[1][0] &&
				 val2 == st->scale_avail[1][1])
				gain = true;
			else
				return -EINVAL;

			mutex_lock(&iio_dev->mlock);

			ret = st->ops->reg_read(st, AD5592R_REG_CTRL,
						&st->cached_gp_ctrl);
			if (ret < 0) {
				mutex_unlock(&iio_dev->mlock);
				return ret;
			}

			if (chan->output) {
				if (gain)
					st->cached_gp_ctrl |=
						AD5592R_REG_CTRL_DAC_RANGE;
				else
					st->cached_gp_ctrl &=
						~AD5592R_REG_CTRL_DAC_RANGE;
			} else {
				if (gain)
					st->cached_gp_ctrl |=
						AD5592R_REG_CTRL_ADC_RANGE;
				else
					st->cached_gp_ctrl &=
						~AD5592R_REG_CTRL_ADC_RANGE;
			}

			ret = st->ops->reg_write(st, AD5592R_REG_CTRL,
						 st->cached_gp_ctrl);
			mutex_unlock(&iio_dev->mlock);

			return ret;
		}
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int ad5592r_read_raw(struct iio_dev *iio_dev,
			   struct iio_chan_spec const *chan,
			   int *val, int *val2, long m)
{
	struct ad5592r_state *st = iio_priv(iio_dev);
	u16 read_val;
	int ret;

	switch (m) {
	case IIO_CHAN_INFO_RAW:
		mutex_lock(&iio_dev->mlock);

		if (!chan->output) {
			ret = st->ops->read_adc(st, chan->channel, &read_val);
			if (ret)
				goto unlock;

			if ((read_val >> 12 & 0x7) != (chan->channel & 0x7)) {
				dev_err(st->dev, "Error while reading channel %u\n",
						chan->channel);
				ret = -EIO;
				goto unlock;
			}

			read_val &= GENMASK(11, 0);

		} else {
			read_val = st->cached_dac[chan->channel];
		}

		dev_dbg(st->dev, "Channel %u read: 0x%04hX\n",
				chan->channel, read_val);

		*val = (int) read_val;
		ret = IIO_VAL_INT;
		break;
	case IIO_CHAN_INFO_SCALE:
		*val = ad5592r_get_vref(st);

		if (chan->type == IIO_TEMP) {
			s64 tmp = *val * (3767897513LL / 25LL);
			*val = div_s64_rem(tmp, 1000000000LL, val2);

			ret = IIO_VAL_INT_PLUS_MICRO;
		} else {
			int mult;

			mutex_lock(&iio_dev->mlock);

			if (chan->output)
				mult = !!(st->cached_gp_ctrl &
					AD5592R_REG_CTRL_DAC_RANGE);
			else
				mult = !!(st->cached_gp_ctrl &
					AD5592R_REG_CTRL_ADC_RANGE);

			*val *= ++mult;

			*val2 = chan->scan_type.realbits;
			ret = IIO_VAL_FRACTIONAL_LOG2;
		}
		break;
	case IIO_CHAN_INFO_OFFSET:
		ret = ad5592r_get_vref(st);

		mutex_lock(&iio_dev->mlock);

		if (st->cached_gp_ctrl & AD5592R_REG_CTRL_ADC_RANGE)
			*val = (-34365 * 25) / ret;
		else
			*val = (-75365 * 25) / ret;
		ret =  IIO_VAL_INT;
		break;
	default:
		ret = -EINVAL;
	}

unlock:
	mutex_unlock(&iio_dev->mlock);
	return ret;
}

static int ad5592r_write_raw_get_fmt(struct iio_dev *indio_dev,
				 struct iio_chan_spec const *chan, long mask)
{
	switch (mask) {
	case IIO_CHAN_INFO_SCALE:
		return IIO_VAL_INT_PLUS_NANO;

	default:
		return IIO_VAL_INT_PLUS_MICRO;
	}

	return -EINVAL;
}

static const struct iio_info ad5592r_info = {
	.read_raw = ad5592r_read_raw,
	.write_raw = ad5592r_write_raw,
	.write_raw_get_fmt = ad5592r_write_raw_get_fmt,
	.driver_module = THIS_MODULE,
};

static ssize_t ad5592r_show_scale_available(struct iio_dev *iio_dev,
					   uintptr_t private,
					   const struct iio_chan_spec *chan,
					   char *buf)
{
	struct ad5592r_state *st = iio_priv(iio_dev);

	return sprintf(buf, "%d.%09u %d.%09u\n",
		st->scale_avail[0][0], st->scale_avail[0][1],
		st->scale_avail[1][0], st->scale_avail[1][1]);
}

static struct iio_chan_spec_ext_info ad5592r_ext_info[] = {
	{
	 .name = "scale_available",
	 .read = ad5592r_show_scale_available,
	 .shared = true,
	 },
	{},
};

static void ad5592r_setup_channel(struct iio_dev *iio_dev,
		struct iio_chan_spec *chan, bool output, unsigned id)
{
	chan->type = IIO_VOLTAGE;
	chan->indexed = 1;
	chan->output = output;
	chan->channel = id;
	chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
	chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE);
	chan->scan_type.sign = 'u';
	chan->scan_type.realbits = 12;
	chan->scan_type.storagebits = 16;
	chan->ext_info = ad5592r_ext_info;
}

static int ad5592r_alloc_channels(struct ad5592r_state *st)
{
	unsigned i, curr_channel = 0,
		 num_channels = st->num_channels;
	struct iio_dev *iio_dev = iio_priv_to_dev(st);
	struct iio_chan_spec *channels;
	struct fwnode_handle *child;
	u32 reg, tmp;
	int ret;

	device_for_each_child_node(st->dev, child) {
		ret = fwnode_property_read_u32(child, "reg", &reg);
		if (ret || reg >= ARRAY_SIZE(st->channel_modes))
			continue;

		ret = fwnode_property_read_u32(child, "adi,mode", &tmp);
		if (!ret)
			st->channel_modes[reg] = tmp;

		fwnode_property_read_u32(child, "adi,off-state", &tmp);
		if (!ret)
			st->channel_offstate[reg] = tmp;
	}

	channels = devm_kzalloc(st->dev,
			(1 + 2 * num_channels) * sizeof(*channels), GFP_KERNEL);
	if (!channels)
		return -ENOMEM;

	for (i = 0; i < num_channels; i++) {
		switch (st->channel_modes[i]) {
		case CH_MODE_DAC:
			ad5592r_setup_channel(iio_dev, &channels[curr_channel],
					true, i);
			curr_channel++;
			break;

		case CH_MODE_ADC:
			ad5592r_setup_channel(iio_dev, &channels[curr_channel],
					false, i);
			curr_channel++;
			break;

		case CH_MODE_DAC_AND_ADC:
			ad5592r_setup_channel(iio_dev, &channels[curr_channel],
					true, i);
			curr_channel++;
			ad5592r_setup_channel(iio_dev, &channels[curr_channel],
					false, i);
			curr_channel++;
			break;

		default:
			continue;
		}
	}

	channels[curr_channel].type = IIO_TEMP;
	channels[curr_channel].channel = 8;
	channels[curr_channel].info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				   BIT(IIO_CHAN_INFO_SCALE) |
				   BIT(IIO_CHAN_INFO_OFFSET);
	curr_channel++;

	iio_dev->num_channels = curr_channel;
	iio_dev->channels = channels;

	return 0;
}

static void ad5592r_init_scales(struct ad5592r_state *st, int vref_mV)
{
	s64 tmp = (s64)vref_mV * 1000000000LL >> 12;

	st->scale_avail[0][0] =
		div_s64_rem(tmp, 1000000000LL, &st->scale_avail[0][1]);
	st->scale_avail[1][0] =
		div_s64_rem(tmp * 2, 1000000000LL, &st->scale_avail[1][1]);
}

int ad5592r_probe(struct device *dev, const char *name,
		const struct ad5592r_rw_ops *ops)
{
	struct iio_dev *iio_dev;
	struct ad5592r_state *st;
	int ret;

	iio_dev = devm_iio_device_alloc(dev, sizeof(*st));
	if (!iio_dev)
		return -ENOMEM;

	st = iio_priv(iio_dev);
	st->dev = dev;
	st->ops = ops;
	st->num_channels = 8;
	dev_set_drvdata(dev, iio_dev);

	st->reg = devm_regulator_get_optional(dev, "vref");
	if (IS_ERR(st->reg)) {
		if ((PTR_ERR(st->reg) != -ENODEV) && dev->of_node)
			return PTR_ERR(st->reg);

		st->reg = NULL;
	} else {
		ret = regulator_enable(st->reg);
		if (ret)
			return ret;
	}

	iio_dev->dev.parent = dev;
	iio_dev->name = name;
	iio_dev->info = &ad5592r_info;
	iio_dev->modes = INDIO_DIRECT_MODE;

	ad5592r_init_scales(st, ad5592r_get_vref(st));

	ret = ad5592r_reset(st);
	if (ret)
		goto error_disable_reg;

	ret = ops->reg_write(st, AD5592R_REG_PD,
		     (st->reg == NULL) ? AD5592R_REG_PD_EN_REF : 0);
	if (ret)
		goto error_disable_reg;

	ret = ad5592r_alloc_channels(st);
	if (ret)
		goto error_disable_reg;

	ret = ad5592r_set_channel_modes(st);
	if (ret)
		goto error_reset_ch_modes;

	ret = iio_device_register(iio_dev);
	if (ret)
		goto error_reset_ch_modes;

	ret = ad5592r_gpio_init(st);
	if (ret)
		goto error_dev_unregister;

	return 0;

error_dev_unregister:
	iio_device_unregister(iio_dev);

error_reset_ch_modes:
	ad5592r_reset_channel_modes(st);

error_disable_reg:
	if (st->reg)
		regulator_disable(st->reg);

	return ret;
}
EXPORT_SYMBOL_GPL(ad5592r_probe);

int ad5592r_remove(struct device *dev)
{
	struct iio_dev *iio_dev = dev_get_drvdata(dev);
	struct ad5592r_state *st = iio_priv(iio_dev);

	iio_device_unregister(iio_dev);
	ad5592r_reset_channel_modes(st);
	ad5592r_gpio_cleanup(st);

	if (st->reg)
		regulator_disable(st->reg);

	return 0;
}
EXPORT_SYMBOL_GPL(ad5592r_remove);

MODULE_AUTHOR("Paul Cercueil <paul.cercueil@analog.com>");
MODULE_DESCRIPTION("Analog Devices AD5592R multi-channel converters");
MODULE_LICENSE("GPL v2");
