// SPDX-License-Identifier: GPL-2.0-only
/*
 * AD5592R Digital <-> Analog converters driver
 *
 * Copyright 2014-2016 Analog Devices Inc.
 * Author: Paul Cercueil <paul.cercueil@analog.com>
 */

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

			return 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:
		return -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,
};

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