// SPDX-License-Identifier: GPL-2.0+
/*
 * AD7124 SPI ADC driver
 *
 * Copyright 2018 Analog Devices Inc.
 */
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/kfifo.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>

#include <linux/iio/iio.h>
#include <linux/iio/adc/ad_sigma_delta.h>
#include <linux/iio/sysfs.h>

/* AD7124 registers */
#define AD7124_COMMS			0x00
#define AD7124_STATUS			0x00
#define AD7124_ADC_CONTROL		0x01
#define AD7124_DATA			0x02
#define AD7124_IO_CONTROL_1		0x03
#define AD7124_IO_CONTROL_2		0x04
#define AD7124_ID			0x05
#define AD7124_ERROR			0x06
#define AD7124_ERROR_EN			0x07
#define AD7124_MCLK_COUNT		0x08
#define AD7124_CHANNEL(x)		(0x09 + (x))
#define AD7124_CONFIG(x)		(0x19 + (x))
#define AD7124_FILTER(x)		(0x21 + (x))
#define AD7124_OFFSET(x)		(0x29 + (x))
#define AD7124_GAIN(x)			(0x31 + (x))

/* AD7124_STATUS */
#define AD7124_STATUS_POR_FLAG			BIT(4)

/* AD7124_ADC_CONTROL */
#define AD7124_ADC_CONTROL_MODE			GENMASK(5, 2)
#define AD7124_ADC_CONTROL_MODE_CONTINUOUS		0
#define AD7124_ADC_CONTROL_MODE_SINGLE			1
#define AD7124_ADC_CONTROL_MODE_STANDBY			2
#define AD7124_ADC_CONTROL_MODE_POWERDOWN		3
#define AD7124_ADC_CONTROL_MODE_IDLE			4
#define AD7124_ADC_CONTROL_MODE_INT_OFFSET_CALIB	5 /* Internal Zero-Scale Calibration */
#define AD7124_ADC_CONTROL_MODE_INT_GAIN_CALIB		6 /* Internal Full-Scale Calibration */
#define AD7124_ADC_CONTROL_MODE_SYS_OFFSET_CALIB	7 /* System Zero-Scale Calibration */
#define AD7124_ADC_CONTROL_MODE_SYS_GAIN_CALIB		8 /* System Full-Scale Calibration */
#define AD7124_ADC_CONTROL_POWER_MODE		GENMASK(7, 6)
#define AD7124_ADC_CONTROL_POWER_MODE_LOW		0
#define AD7124_ADC_CONTROL_POWER_MODE_MID		1
#define AD7124_ADC_CONTROL_POWER_MODE_FULL		2
#define AD7124_ADC_CONTROL_REF_EN		BIT(8)
#define AD7124_ADC_CONTROL_DATA_STATUS		BIT(10)

/* AD7124_ID */
#define AD7124_ID_SILICON_REVISION		GENMASK(3, 0)
#define AD7124_ID_DEVICE_ID			GENMASK(7, 4)
#define AD7124_ID_DEVICE_ID_AD7124_4			0x0
#define AD7124_ID_DEVICE_ID_AD7124_8			0x1

/* AD7124_CHANNEL_X */
#define AD7124_CHANNEL_ENABLE		BIT(15)
#define AD7124_CHANNEL_SETUP		GENMASK(14, 12)
#define AD7124_CHANNEL_AINP		GENMASK(9, 5)
#define AD7124_CHANNEL_AINM		GENMASK(4, 0)
#define AD7124_CHANNEL_AINx_TEMPSENSOR		16
#define AD7124_CHANNEL_AINx_AVSS		17

/* AD7124_CONFIG_X */
#define AD7124_CONFIG_BIPOLAR		BIT(11)
#define AD7124_CONFIG_IN_BUFF		GENMASK(6, 5)
#define AD7124_CONFIG_AIN_BUFP		BIT(6)
#define AD7124_CONFIG_AIN_BUFM		BIT(5)
#define AD7124_CONFIG_REF_SEL		GENMASK(4, 3)
#define AD7124_CONFIG_PGA		GENMASK(2, 0)

/* AD7124_FILTER_X */
#define AD7124_FILTER_FS		GENMASK(10, 0)
#define AD7124_FILTER_FILTER		GENMASK(23, 21)
#define AD7124_FILTER_FILTER_SINC4		0
#define AD7124_FILTER_FILTER_SINC3		2

#define AD7124_MAX_CONFIGS	8
#define AD7124_MAX_CHANNELS	16

/* AD7124 input sources */

enum ad7124_ref_sel {
	AD7124_REFIN1,
	AD7124_REFIN2,
	AD7124_INT_REF,
	AD7124_AVDD_REF,
};

enum ad7124_power_mode {
	AD7124_LOW_POWER,
	AD7124_MID_POWER,
	AD7124_FULL_POWER,
};

static const unsigned int ad7124_gain[8] = {
	1, 2, 4, 8, 16, 32, 64, 128
};

static const unsigned int ad7124_reg_size[] = {
	1, 2, 3, 3, 2, 1, 3, 3, 1, 2, 2, 2, 2,
	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
	2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3,
	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
	3, 3, 3, 3, 3
};

static const int ad7124_master_clk_freq_hz[3] = {
	[AD7124_LOW_POWER] = 76800,
	[AD7124_MID_POWER] = 153600,
	[AD7124_FULL_POWER] = 614400,
};

static const char * const ad7124_ref_names[] = {
	[AD7124_REFIN1] = "refin1",
	[AD7124_REFIN2] = "refin2",
	[AD7124_INT_REF] = "int",
	[AD7124_AVDD_REF] = "avdd",
};

struct ad7124_chip_info {
	const char *name;
	unsigned int chip_id;
	unsigned int num_inputs;
};

struct ad7124_channel_config {
	bool live;
	unsigned int cfg_slot;
	/*
	 * Following fields are used to compare for equality. If you
	 * make adaptations in it, you most likely also have to adapt
	 * ad7124_find_similar_live_cfg(), too.
	 */
	struct_group(config_props,
		enum ad7124_ref_sel refsel;
		bool bipolar;
		bool buf_positive;
		bool buf_negative;
		unsigned int vref_mv;
		unsigned int pga_bits;
		unsigned int odr;
		unsigned int odr_sel_bits;
		unsigned int filter_type;
		unsigned int calibration_offset;
		unsigned int calibration_gain;
	);
};

struct ad7124_channel {
	unsigned int nr;
	struct ad7124_channel_config cfg;
	unsigned int ain;
	unsigned int slot;
	u8 syscalib_mode;
};

struct ad7124_state {
	const struct ad7124_chip_info *chip_info;
	struct ad_sigma_delta sd;
	struct ad7124_channel *channels;
	struct regulator *vref[4];
	struct clk *mclk;
	unsigned int adc_control;
	unsigned int num_channels;
	struct mutex cfgs_lock; /* lock for configs access */
	unsigned long cfg_slots_status; /* bitmap with slot status (1 means it is used) */

	/*
	 * Stores the power-on reset value for the GAIN(x) registers which are
	 * needed for measurements at gain 1 (i.e. CONFIG(x).PGA == 0)
	 */
	unsigned int gain_default;
	DECLARE_KFIFO(live_cfgs_fifo, struct ad7124_channel_config *, AD7124_MAX_CONFIGS);
};

static const struct ad7124_chip_info ad7124_4_chip_info = {
	.name = "ad7124-4",
	.chip_id = AD7124_ID_DEVICE_ID_AD7124_4,
	.num_inputs = 8,
};

static const struct ad7124_chip_info ad7124_8_chip_info = {
	.name = "ad7124-8",
	.chip_id = AD7124_ID_DEVICE_ID_AD7124_8,
	.num_inputs = 16,
};

static int ad7124_find_closest_match(const int *array,
				     unsigned int size, int val)
{
	int i, idx;
	unsigned int diff_new, diff_old;

	diff_old = U32_MAX;
	idx = 0;

	for (i = 0; i < size; i++) {
		diff_new = abs(val - array[i]);
		if (diff_new < diff_old) {
			diff_old = diff_new;
			idx = i;
		}
	}

	return idx;
}

static int ad7124_spi_write_mask(struct ad7124_state *st,
				 unsigned int addr,
				 unsigned long mask,
				 unsigned int val,
				 unsigned int bytes)
{
	unsigned int readval;
	int ret;

	ret = ad_sd_read_reg(&st->sd, addr, bytes, &readval);
	if (ret < 0)
		return ret;

	readval &= ~mask;
	readval |= val;

	return ad_sd_write_reg(&st->sd, addr, bytes, readval);
}

static int ad7124_set_mode(struct ad_sigma_delta *sd,
			   enum ad_sigma_delta_mode mode)
{
	struct ad7124_state *st = container_of(sd, struct ad7124_state, sd);

	st->adc_control &= ~AD7124_ADC_CONTROL_MODE;
	st->adc_control |= FIELD_PREP(AD7124_ADC_CONTROL_MODE, mode);

	return ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, 2, st->adc_control);
}

static void ad7124_set_channel_odr(struct ad7124_state *st, unsigned int channel, unsigned int odr)
{
	unsigned int fclk, odr_sel_bits;

	fclk = clk_get_rate(st->mclk);
	/*
	 * FS[10:0] = fCLK / (fADC x 32) where:
	 * fADC is the output data rate
	 * fCLK is the master clock frequency
	 * FS[10:0] are the bits in the filter register
	 * FS[10:0] can have a value from 1 to 2047
	 */
	odr_sel_bits = DIV_ROUND_CLOSEST(fclk, odr * 32);
	if (odr_sel_bits < 1)
		odr_sel_bits = 1;
	else if (odr_sel_bits > 2047)
		odr_sel_bits = 2047;

	if (odr_sel_bits != st->channels[channel].cfg.odr_sel_bits)
		st->channels[channel].cfg.live = false;

	/* fADC = fCLK / (FS[10:0] x 32) */
	st->channels[channel].cfg.odr = DIV_ROUND_CLOSEST(fclk, odr_sel_bits * 32);
	st->channels[channel].cfg.odr_sel_bits = odr_sel_bits;
}

static int ad7124_get_3db_filter_freq(struct ad7124_state *st,
				      unsigned int channel)
{
	unsigned int fadc;

	fadc = st->channels[channel].cfg.odr;

	switch (st->channels[channel].cfg.filter_type) {
	case AD7124_FILTER_FILTER_SINC3:
		return DIV_ROUND_CLOSEST(fadc * 272, 1000);
	case AD7124_FILTER_FILTER_SINC4:
		return DIV_ROUND_CLOSEST(fadc * 230, 1000);
	default:
		return -EINVAL;
	}
}

static struct ad7124_channel_config *ad7124_find_similar_live_cfg(struct ad7124_state *st,
								  struct ad7124_channel_config *cfg)
{
	struct ad7124_channel_config *cfg_aux;
	int i;

	/*
	 * This is just to make sure that the comparison is adapted after
	 * struct ad7124_channel_config was changed.
	 */
	static_assert(sizeof_field(struct ad7124_channel_config, config_props) ==
		      sizeof(struct {
				     enum ad7124_ref_sel refsel;
				     bool bipolar;
				     bool buf_positive;
				     bool buf_negative;
				     unsigned int vref_mv;
				     unsigned int pga_bits;
				     unsigned int odr;
				     unsigned int odr_sel_bits;
				     unsigned int filter_type;
				     unsigned int calibration_offset;
				     unsigned int calibration_gain;
			     }));

	for (i = 0; i < st->num_channels; i++) {
		cfg_aux = &st->channels[i].cfg;

		if (cfg_aux->live &&
		    cfg->refsel == cfg_aux->refsel &&
		    cfg->bipolar == cfg_aux->bipolar &&
		    cfg->buf_positive == cfg_aux->buf_positive &&
		    cfg->buf_negative == cfg_aux->buf_negative &&
		    cfg->vref_mv == cfg_aux->vref_mv &&
		    cfg->pga_bits == cfg_aux->pga_bits &&
		    cfg->odr == cfg_aux->odr &&
		    cfg->odr_sel_bits == cfg_aux->odr_sel_bits &&
		    cfg->filter_type == cfg_aux->filter_type &&
		    cfg->calibration_offset == cfg_aux->calibration_offset &&
		    cfg->calibration_gain == cfg_aux->calibration_gain)
			return cfg_aux;
	}

	return NULL;
}

static int ad7124_find_free_config_slot(struct ad7124_state *st)
{
	unsigned int free_cfg_slot;

	free_cfg_slot = find_first_zero_bit(&st->cfg_slots_status, AD7124_MAX_CONFIGS);
	if (free_cfg_slot == AD7124_MAX_CONFIGS)
		return -1;

	return free_cfg_slot;
}

/* Only called during probe, so dev_err_probe() can be used */
static int ad7124_init_config_vref(struct ad7124_state *st, struct ad7124_channel_config *cfg)
{
	struct device *dev = &st->sd.spi->dev;
	unsigned int refsel = cfg->refsel;

	switch (refsel) {
	case AD7124_REFIN1:
	case AD7124_REFIN2:
	case AD7124_AVDD_REF:
		if (IS_ERR(st->vref[refsel]))
			return dev_err_probe(dev, PTR_ERR(st->vref[refsel]),
					     "Error, trying to use external voltage reference without a %s regulator.\n",
					     ad7124_ref_names[refsel]);

		cfg->vref_mv = regulator_get_voltage(st->vref[refsel]);
		/* Conversion from uV to mV */
		cfg->vref_mv /= 1000;
		return 0;
	case AD7124_INT_REF:
		cfg->vref_mv = 2500;
		st->adc_control |= AD7124_ADC_CONTROL_REF_EN;
		return 0;
	default:
		return dev_err_probe(dev, -EINVAL, "Invalid reference %d\n", refsel);
	}
}

static int ad7124_write_config(struct ad7124_state *st, struct ad7124_channel_config *cfg,
			       unsigned int cfg_slot)
{
	unsigned int tmp;
	unsigned int val;
	int ret;

	cfg->cfg_slot = cfg_slot;

	ret = ad_sd_write_reg(&st->sd, AD7124_OFFSET(cfg->cfg_slot), 3, cfg->calibration_offset);
	if (ret)
		return ret;

	ret = ad_sd_write_reg(&st->sd, AD7124_GAIN(cfg->cfg_slot), 3, cfg->calibration_gain);
	if (ret)
		return ret;

	val = FIELD_PREP(AD7124_CONFIG_BIPOLAR, cfg->bipolar) |
		FIELD_PREP(AD7124_CONFIG_REF_SEL, cfg->refsel) |
		(cfg->buf_positive ? AD7124_CONFIG_AIN_BUFP : 0) |
		(cfg->buf_negative ? AD7124_CONFIG_AIN_BUFM : 0) |
		FIELD_PREP(AD7124_CONFIG_PGA, cfg->pga_bits);

	ret = ad_sd_write_reg(&st->sd, AD7124_CONFIG(cfg->cfg_slot), 2, val);
	if (ret < 0)
		return ret;

	tmp = FIELD_PREP(AD7124_FILTER_FILTER, cfg->filter_type) |
		FIELD_PREP(AD7124_FILTER_FS, cfg->odr_sel_bits);
	return ad7124_spi_write_mask(st, AD7124_FILTER(cfg->cfg_slot),
				     AD7124_FILTER_FILTER | AD7124_FILTER_FS,
				     tmp, 3);
}

static struct ad7124_channel_config *ad7124_pop_config(struct ad7124_state *st)
{
	struct ad7124_channel_config *lru_cfg;
	struct ad7124_channel_config *cfg;
	int ret;
	int i;

	/*
	 * Pop least recently used config from the fifo
	 * in order to make room for the new one
	 */
	ret = kfifo_get(&st->live_cfgs_fifo, &lru_cfg);
	if (ret <= 0)
		return NULL;

	lru_cfg->live = false;

	/* mark slot as free */
	assign_bit(lru_cfg->cfg_slot, &st->cfg_slots_status, 0);

	/* invalidate all other configs that pointed to this one */
	for (i = 0; i < st->num_channels; i++) {
		cfg = &st->channels[i].cfg;

		if (cfg->cfg_slot == lru_cfg->cfg_slot)
			cfg->live = false;
	}

	return lru_cfg;
}

static int ad7124_push_config(struct ad7124_state *st, struct ad7124_channel_config *cfg)
{
	struct ad7124_channel_config *lru_cfg;
	int free_cfg_slot;

	free_cfg_slot = ad7124_find_free_config_slot(st);
	if (free_cfg_slot >= 0) {
		/* push the new config in configs queue */
		kfifo_put(&st->live_cfgs_fifo, cfg);
	} else {
		/* pop one config to make room for the new one */
		lru_cfg = ad7124_pop_config(st);
		if (!lru_cfg)
			return -EINVAL;

		/* push the new config in configs queue */
		free_cfg_slot = lru_cfg->cfg_slot;
		kfifo_put(&st->live_cfgs_fifo, cfg);
	}

	/* mark slot as used */
	assign_bit(free_cfg_slot, &st->cfg_slots_status, 1);

	return ad7124_write_config(st, cfg, free_cfg_slot);
}

static int ad7124_enable_channel(struct ad7124_state *st, struct ad7124_channel *ch)
{
	ch->cfg.live = true;
	return ad_sd_write_reg(&st->sd, AD7124_CHANNEL(ch->nr), 2, ch->ain |
			       FIELD_PREP(AD7124_CHANNEL_SETUP, ch->cfg.cfg_slot) |
			       AD7124_CHANNEL_ENABLE);
}

static int ad7124_prepare_read(struct ad7124_state *st, int address)
{
	struct ad7124_channel_config *cfg = &st->channels[address].cfg;
	struct ad7124_channel_config *live_cfg;

	/*
	 * Before doing any reads assign the channel a configuration.
	 * Check if channel's config is on the device
	 */
	if (!cfg->live) {
		/* check if config matches another one */
		live_cfg = ad7124_find_similar_live_cfg(st, cfg);
		if (!live_cfg)
			ad7124_push_config(st, cfg);
		else
			cfg->cfg_slot = live_cfg->cfg_slot;
	}

	/* point channel to the config slot and enable */
	return ad7124_enable_channel(st, &st->channels[address]);
}

static int __ad7124_set_channel(struct ad_sigma_delta *sd, unsigned int channel)
{
	struct ad7124_state *st = container_of(sd, struct ad7124_state, sd);

	return ad7124_prepare_read(st, channel);
}

static int ad7124_set_channel(struct ad_sigma_delta *sd, unsigned int channel)
{
	struct ad7124_state *st = container_of(sd, struct ad7124_state, sd);
	int ret;

	mutex_lock(&st->cfgs_lock);
	ret = __ad7124_set_channel(sd, channel);
	mutex_unlock(&st->cfgs_lock);

	return ret;
}

static int ad7124_append_status(struct ad_sigma_delta *sd, bool append)
{
	struct ad7124_state *st = container_of(sd, struct ad7124_state, sd);
	unsigned int adc_control = st->adc_control;
	int ret;

	if (append)
		adc_control |= AD7124_ADC_CONTROL_DATA_STATUS;
	else
		adc_control &= ~AD7124_ADC_CONTROL_DATA_STATUS;

	ret = ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, 2, adc_control);
	if (ret < 0)
		return ret;

	st->adc_control = adc_control;

	return 0;
}

static int ad7124_disable_one(struct ad_sigma_delta *sd, unsigned int chan)
{
	struct ad7124_state *st = container_of(sd, struct ad7124_state, sd);

	/* The relevant thing here is that AD7124_CHANNEL_ENABLE is cleared. */
	return ad_sd_write_reg(&st->sd, AD7124_CHANNEL(chan), 2, 0);
}

static int ad7124_disable_all(struct ad_sigma_delta *sd)
{
	int ret;
	int i;

	for (i = 0; i < 16; i++) {
		ret = ad7124_disable_one(sd, i);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static const struct ad_sigma_delta_info ad7124_sigma_delta_info = {
	.set_channel = ad7124_set_channel,
	.append_status = ad7124_append_status,
	.disable_all = ad7124_disable_all,
	.disable_one = ad7124_disable_one,
	.set_mode = ad7124_set_mode,
	.has_registers = true,
	.addr_shift = 0,
	.read_mask = BIT(6),
	.status_ch_mask = GENMASK(3, 0),
	.data_reg = AD7124_DATA,
	.num_slots = 8,
	.irq_flags = IRQF_TRIGGER_FALLING,
	.num_resetclks = 64,
};

static int ad7124_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan,
			   int *val, int *val2, long info)
{
	struct ad7124_state *st = iio_priv(indio_dev);
	int idx, ret;

	switch (info) {
	case IIO_CHAN_INFO_RAW:
		ret = ad_sigma_delta_single_conversion(indio_dev, chan, val);
		if (ret < 0)
			return ret;

		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		switch (chan->type) {
		case IIO_VOLTAGE:
			mutex_lock(&st->cfgs_lock);

			idx = st->channels[chan->address].cfg.pga_bits;
			*val = st->channels[chan->address].cfg.vref_mv;
			if (st->channels[chan->address].cfg.bipolar)
				*val2 = chan->scan_type.realbits - 1 + idx;
			else
				*val2 = chan->scan_type.realbits + idx;

			mutex_unlock(&st->cfgs_lock);
			return IIO_VAL_FRACTIONAL_LOG2;

		case IIO_TEMP:
			/*
			 * According to the data sheet
			 *   Temperature (°C)
			 * = ((Conversion − 0x800000)/13584) − 272.5
			 * = (Conversion − 0x800000 - 13584 * 272.5) / 13584
			 * = (Conversion − 12090248) / 13584
			 * So scale with 1000/13584 to yield °mC. Reduce by 8 to
			 * 125/1698.
			 */
			*val = 125;
			*val2 = 1698;
			return IIO_VAL_FRACTIONAL;

		default:
			return -EINVAL;
		}

	case IIO_CHAN_INFO_OFFSET:
		switch (chan->type) {
		case IIO_VOLTAGE:
			mutex_lock(&st->cfgs_lock);
			if (st->channels[chan->address].cfg.bipolar)
				*val = -(1 << (chan->scan_type.realbits - 1));
			else
				*val = 0;

			mutex_unlock(&st->cfgs_lock);
			return IIO_VAL_INT;

		case IIO_TEMP:
			/* see calculation above */
			*val = -12090248;
			return IIO_VAL_INT;

		default:
			return -EINVAL;
		}

	case IIO_CHAN_INFO_SAMP_FREQ:
		mutex_lock(&st->cfgs_lock);
		*val = st->channels[chan->address].cfg.odr;
		mutex_unlock(&st->cfgs_lock);

		return IIO_VAL_INT;
	case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
		mutex_lock(&st->cfgs_lock);
		*val = ad7124_get_3db_filter_freq(st, chan->scan_index);
		mutex_unlock(&st->cfgs_lock);

		return IIO_VAL_INT;
	default:
		return -EINVAL;
	}
}

static int ad7124_write_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan,
			    int val, int val2, long info)
{
	struct ad7124_state *st = iio_priv(indio_dev);
	unsigned int res, gain, full_scale, vref;
	int ret = 0;

	mutex_lock(&st->cfgs_lock);

	switch (info) {
	case IIO_CHAN_INFO_SAMP_FREQ:
		if (val2 != 0 || val == 0) {
			ret = -EINVAL;
			break;
		}

		ad7124_set_channel_odr(st, chan->address, val);
		break;
	case IIO_CHAN_INFO_SCALE:
		if (val != 0) {
			ret = -EINVAL;
			break;
		}

		if (st->channels[chan->address].cfg.bipolar)
			full_scale = 1 << (chan->scan_type.realbits - 1);
		else
			full_scale = 1 << chan->scan_type.realbits;

		vref = st->channels[chan->address].cfg.vref_mv * 1000000LL;
		res = DIV_ROUND_CLOSEST(vref, full_scale);
		gain = DIV_ROUND_CLOSEST(res, val2);
		res = ad7124_find_closest_match(ad7124_gain, ARRAY_SIZE(ad7124_gain), gain);

		if (st->channels[chan->address].cfg.pga_bits != res)
			st->channels[chan->address].cfg.live = false;

		st->channels[chan->address].cfg.pga_bits = res;
		break;
	default:
		ret = -EINVAL;
	}

	mutex_unlock(&st->cfgs_lock);
	return ret;
}

static int ad7124_reg_access(struct iio_dev *indio_dev,
			     unsigned int reg,
			     unsigned int writeval,
			     unsigned int *readval)
{
	struct ad7124_state *st = iio_priv(indio_dev);
	int ret;

	if (reg >= ARRAY_SIZE(ad7124_reg_size))
		return -EINVAL;

	if (readval)
		ret = ad_sd_read_reg(&st->sd, reg, ad7124_reg_size[reg],
				     readval);
	else
		ret = ad_sd_write_reg(&st->sd, reg, ad7124_reg_size[reg],
				      writeval);

	return ret;
}

static IIO_CONST_ATTR(in_voltage_scale_available,
	"0.000001164 0.000002328 0.000004656 0.000009313 0.000018626 0.000037252 0.000074505 0.000149011 0.000298023");

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

static const struct attribute_group ad7124_attrs_group = {
	.attrs = ad7124_attributes,
};

static int ad7124_update_scan_mode(struct iio_dev *indio_dev,
				   const unsigned long *scan_mask)
{
	struct ad7124_state *st = iio_priv(indio_dev);
	bool bit_set;
	int ret;
	int i;

	mutex_lock(&st->cfgs_lock);
	for (i = 0; i < st->num_channels; i++) {
		bit_set = test_bit(i, scan_mask);
		if (bit_set)
			ret = __ad7124_set_channel(&st->sd, i);
		else
			ret = ad7124_spi_write_mask(st, AD7124_CHANNEL(i), AD7124_CHANNEL_ENABLE,
						    0, 2);
		if (ret < 0) {
			mutex_unlock(&st->cfgs_lock);

			return ret;
		}
	}

	mutex_unlock(&st->cfgs_lock);

	return 0;
}

static const struct iio_info ad7124_info = {
	.read_raw = ad7124_read_raw,
	.write_raw = ad7124_write_raw,
	.debugfs_reg_access = &ad7124_reg_access,
	.validate_trigger = ad_sd_validate_trigger,
	.update_scan_mode = ad7124_update_scan_mode,
	.attrs = &ad7124_attrs_group,
};

/* Only called during probe, so dev_err_probe() can be used */
static int ad7124_soft_reset(struct ad7124_state *st)
{
	struct device *dev = &st->sd.spi->dev;
	unsigned int readval, timeout;
	int ret;

	ret = ad_sd_reset(&st->sd);
	if (ret < 0)
		return ret;

	fsleep(200);
	timeout = 100;
	do {
		ret = ad_sd_read_reg(&st->sd, AD7124_STATUS, 1, &readval);
		if (ret < 0)
			return dev_err_probe(dev, ret, "Error reading status register\n");

		if (!(readval & AD7124_STATUS_POR_FLAG))
			break;

		/* The AD7124 requires typically 2ms to power up and settle */
		usleep_range(100, 2000);
	} while (--timeout);

	if (readval & AD7124_STATUS_POR_FLAG)
		return dev_err_probe(dev, -EIO, "Soft reset failed\n");

	ret = ad_sd_read_reg(&st->sd, AD7124_GAIN(0), 3, &st->gain_default);
	if (ret < 0)
		return dev_err_probe(dev, ret, "Error reading gain register\n");

	dev_dbg(dev, "Reset value of GAIN register is 0x%x\n", st->gain_default);

	return 0;
}

static int ad7124_check_chip_id(struct ad7124_state *st)
{
	struct device *dev = &st->sd.spi->dev;
	unsigned int readval, chip_id, silicon_rev;
	int ret;

	ret = ad_sd_read_reg(&st->sd, AD7124_ID, 1, &readval);
	if (ret < 0)
		return dev_err_probe(dev, ret, "Failure to read ID register\n");

	chip_id = FIELD_GET(AD7124_ID_DEVICE_ID, readval);
	silicon_rev = FIELD_GET(AD7124_ID_SILICON_REVISION, readval);

	if (chip_id != st->chip_info->chip_id)
		return dev_err_probe(dev, -ENODEV,
				     "Chip ID mismatch: expected %u, got %u\n",
				     st->chip_info->chip_id, chip_id);

	if (silicon_rev == 0)
		return dev_err_probe(dev, -ENODEV,
				     "Silicon revision empty. Chip may not be present\n");

	return 0;
}

enum {
	AD7124_SYSCALIB_ZERO_SCALE,
	AD7124_SYSCALIB_FULL_SCALE,
};

static int ad7124_syscalib_locked(struct ad7124_state *st, const struct iio_chan_spec *chan)
{
	struct device *dev = &st->sd.spi->dev;
	struct ad7124_channel *ch = &st->channels[chan->address];
	int ret;

	if (ch->syscalib_mode == AD7124_SYSCALIB_ZERO_SCALE) {
		ch->cfg.calibration_offset = 0x800000;

		ret = ad_sd_calibrate(&st->sd, AD7124_ADC_CONTROL_MODE_SYS_OFFSET_CALIB,
				      chan->address);
		if (ret < 0)
			return ret;

		ret = ad_sd_read_reg(&st->sd, AD7124_OFFSET(ch->cfg.cfg_slot), 3,
				     &ch->cfg.calibration_offset);
		if (ret < 0)
			return ret;

		dev_dbg(dev, "offset for channel %lu after zero-scale calibration: 0x%x\n",
			chan->address, ch->cfg.calibration_offset);
	} else {
		ch->cfg.calibration_gain = st->gain_default;

		ret = ad_sd_calibrate(&st->sd, AD7124_ADC_CONTROL_MODE_SYS_GAIN_CALIB,
				      chan->address);
		if (ret < 0)
			return ret;

		ret = ad_sd_read_reg(&st->sd, AD7124_GAIN(ch->cfg.cfg_slot), 3,
				     &ch->cfg.calibration_gain);
		if (ret < 0)
			return ret;

		dev_dbg(dev, "gain for channel %lu after full-scale calibration: 0x%x\n",
			chan->address, ch->cfg.calibration_gain);
	}

	return 0;
}

static ssize_t ad7124_write_syscalib(struct iio_dev *indio_dev,
				     uintptr_t private,
				     const struct iio_chan_spec *chan,
				     const char *buf, size_t len)
{
	struct ad7124_state *st = iio_priv(indio_dev);
	bool sys_calib;
	int ret;

	ret = kstrtobool(buf, &sys_calib);
	if (ret)
		return ret;

	if (!sys_calib)
		return len;

	if (!iio_device_claim_direct(indio_dev))
		return -EBUSY;

	ret = ad7124_syscalib_locked(st, chan);

	iio_device_release_direct(indio_dev);

	return ret ?: len;
}

static const char * const ad7124_syscalib_modes[] = {
	[AD7124_SYSCALIB_ZERO_SCALE] = "zero_scale",
	[AD7124_SYSCALIB_FULL_SCALE] = "full_scale",
};

static int ad7124_set_syscalib_mode(struct iio_dev *indio_dev,
				    const struct iio_chan_spec *chan,
				    unsigned int mode)
{
	struct ad7124_state *st = iio_priv(indio_dev);

	st->channels[chan->address].syscalib_mode = mode;

	return 0;
}

static int ad7124_get_syscalib_mode(struct iio_dev *indio_dev,
				    const struct iio_chan_spec *chan)
{
	struct ad7124_state *st = iio_priv(indio_dev);

	return st->channels[chan->address].syscalib_mode;
}

static const struct iio_enum ad7124_syscalib_mode_enum = {
	.items = ad7124_syscalib_modes,
	.num_items = ARRAY_SIZE(ad7124_syscalib_modes),
	.set = ad7124_set_syscalib_mode,
	.get = ad7124_get_syscalib_mode
};

static const struct iio_chan_spec_ext_info ad7124_calibsys_ext_info[] = {
	{
		.name = "sys_calibration",
		.write = ad7124_write_syscalib,
		.shared = IIO_SEPARATE,
	},
	IIO_ENUM("sys_calibration_mode", IIO_SEPARATE,
		 &ad7124_syscalib_mode_enum),
	IIO_ENUM_AVAILABLE("sys_calibration_mode", IIO_SHARED_BY_TYPE,
			   &ad7124_syscalib_mode_enum),
	{ }
};

static const struct iio_chan_spec ad7124_channel_template = {
	.type = IIO_VOLTAGE,
	.indexed = 1,
	.differential = 1,
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
		BIT(IIO_CHAN_INFO_SCALE) |
		BIT(IIO_CHAN_INFO_OFFSET) |
		BIT(IIO_CHAN_INFO_SAMP_FREQ) |
		BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),
	.scan_type = {
		.sign = 'u',
		.realbits = 24,
		.storagebits = 32,
		.endianness = IIO_BE,
	},
	.ext_info = ad7124_calibsys_ext_info,
};

/*
 * Input specifiers 8 - 15 are explicitly reserved for ad7124-4
 * while they are fine for ad7124-8. Values above 31 don't fit
 * into the register field and so are invalid for sure.
 */
static bool ad7124_valid_input_select(unsigned int ain, const struct ad7124_chip_info *info)
{
	if (ain >= info->num_inputs && ain < 16)
		return false;

	return ain <= FIELD_MAX(AD7124_CHANNEL_AINM);
}

static int ad7124_parse_channel_config(struct iio_dev *indio_dev,
				       struct device *dev)
{
	struct ad7124_state *st = iio_priv(indio_dev);
	struct ad7124_channel_config *cfg;
	struct ad7124_channel *channels;
	struct iio_chan_spec *chan;
	unsigned int ain[2], channel = 0, tmp;
	unsigned int num_channels;
	int ret;

	num_channels = device_get_child_node_count(dev);

	/*
	 * The driver assigns each logical channel defined in the device tree
	 * statically one channel register. So only accept 16 such logical
	 * channels to not treat CONFIG_0 (i.e. the register following
	 * CHANNEL_15) as an additional channel register. The driver could be
	 * improved to lift this limitation.
	 */
	if (num_channels > AD7124_MAX_CHANNELS)
		return dev_err_probe(dev, -EINVAL, "Too many channels defined\n");

	/* Add one for temperature */
	st->num_channels = min(num_channels + 1, AD7124_MAX_CHANNELS);

	chan = devm_kcalloc(dev, st->num_channels,
			    sizeof(*chan), GFP_KERNEL);
	if (!chan)
		return -ENOMEM;

	channels = devm_kcalloc(dev, st->num_channels, sizeof(*channels),
				GFP_KERNEL);
	if (!channels)
		return -ENOMEM;

	indio_dev->channels = chan;
	indio_dev->num_channels = st->num_channels;
	st->channels = channels;

	device_for_each_child_node_scoped(dev, child) {
		ret = fwnode_property_read_u32(child, "reg", &channel);
		if (ret)
			return dev_err_probe(dev, ret,
					     "Failed to parse reg property of %pfwP\n", child);

		if (channel >= num_channels)
			return dev_err_probe(dev, -EINVAL,
					     "Channel index >= number of channels in %pfwP\n", child);

		ret = fwnode_property_read_u32_array(child, "diff-channels",
						     ain, 2);
		if (ret)
			return dev_err_probe(dev, ret,
					     "Failed to parse diff-channels property of %pfwP\n", child);

		if (!ad7124_valid_input_select(ain[0], st->chip_info) ||
		    !ad7124_valid_input_select(ain[1], st->chip_info))
			return dev_err_probe(dev, -EINVAL,
					     "diff-channels property of %pfwP contains invalid data\n", child);

		st->channels[channel].nr = channel;
		st->channels[channel].ain = FIELD_PREP(AD7124_CHANNEL_AINP, ain[0]) |
			FIELD_PREP(AD7124_CHANNEL_AINM, ain[1]);

		cfg = &st->channels[channel].cfg;
		cfg->bipolar = fwnode_property_read_bool(child, "bipolar");

		ret = fwnode_property_read_u32(child, "adi,reference-select", &tmp);
		if (ret)
			cfg->refsel = AD7124_INT_REF;
		else
			cfg->refsel = tmp;

		cfg->buf_positive =
			fwnode_property_read_bool(child, "adi,buffered-positive");
		cfg->buf_negative =
			fwnode_property_read_bool(child, "adi,buffered-negative");

		chan[channel] = ad7124_channel_template;
		chan[channel].address = channel;
		chan[channel].scan_index = channel;
		chan[channel].channel = ain[0];
		chan[channel].channel2 = ain[1];
	}

	if (num_channels < AD7124_MAX_CHANNELS) {
		st->channels[num_channels] = (struct ad7124_channel) {
			.nr = num_channels,
			.ain = FIELD_PREP(AD7124_CHANNEL_AINP, AD7124_CHANNEL_AINx_TEMPSENSOR) |
				FIELD_PREP(AD7124_CHANNEL_AINM, AD7124_CHANNEL_AINx_AVSS),
			.cfg = {
				.bipolar = true,
			},
		};

		chan[num_channels] = (struct iio_chan_spec) {
			.type = IIO_TEMP,
			.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET) |
				BIT(IIO_CHAN_INFO_SAMP_FREQ),
			.scan_type = {
				/*
				 * You might find it strange that a bipolar
				 * measurement yields an unsigned value, but
				 * this matches the device's manual.
				 */
				.sign = 'u',
				.realbits = 24,
				.storagebits = 32,
				.endianness = IIO_BE,
			},
			.address = num_channels,
			.scan_index = num_channels,
		};
	}

	return 0;
}

static int ad7124_setup(struct ad7124_state *st)
{
	struct device *dev = &st->sd.spi->dev;
	unsigned int fclk, power_mode;
	int i, ret;

	fclk = clk_get_rate(st->mclk);
	if (!fclk)
		return dev_err_probe(dev, -EINVAL, "Failed to get mclk rate\n");

	/* The power mode changes the master clock frequency */
	power_mode = ad7124_find_closest_match(ad7124_master_clk_freq_hz,
					ARRAY_SIZE(ad7124_master_clk_freq_hz),
					fclk);
	if (fclk != ad7124_master_clk_freq_hz[power_mode]) {
		ret = clk_set_rate(st->mclk, fclk);
		if (ret)
			return dev_err_probe(dev, ret, "Failed to set mclk rate\n");
	}

	/* Set the power mode */
	st->adc_control &= ~AD7124_ADC_CONTROL_POWER_MODE;
	st->adc_control |= FIELD_PREP(AD7124_ADC_CONTROL_POWER_MODE, power_mode);

	st->adc_control &= ~AD7124_ADC_CONTROL_MODE;
	st->adc_control |= FIELD_PREP(AD7124_ADC_CONTROL_MODE, AD_SD_MODE_IDLE);

	mutex_init(&st->cfgs_lock);
	INIT_KFIFO(st->live_cfgs_fifo);
	for (i = 0; i < st->num_channels; i++) {

		ret = ad7124_init_config_vref(st, &st->channels[i].cfg);
		if (ret < 0)
			return ret;

		/*
		 * 9.38 SPS is the minimum output data rate supported
		 * regardless of the selected power mode. Round it up to 10 and
		 * set all channels to this default value.
		 */
		ad7124_set_channel_odr(st, i, 10);
	}

	ad7124_disable_all(&st->sd);

	ret = ad_sd_write_reg(&st->sd, AD7124_ADC_CONTROL, 2, st->adc_control);
	if (ret < 0)
		return dev_err_probe(dev, ret, "Failed to setup CONTROL register\n");

	return ret;
}

static int __ad7124_calibrate_all(struct ad7124_state *st, struct iio_dev *indio_dev)
{
	struct device *dev = &st->sd.spi->dev;
	int ret, i;

	for (i = 0; i < st->num_channels; i++) {

		if (indio_dev->channels[i].type != IIO_VOLTAGE)
			continue;

		/*
		 * For calibration the OFFSET register should hold its reset default
		 * value. For the GAIN register there is no such requirement but
		 * for gain 1 it should hold the reset default value, too. So to
		 * simplify matters use the reset default value for both.
		 */
		st->channels[i].cfg.calibration_offset = 0x800000;
		st->channels[i].cfg.calibration_gain = st->gain_default;

		/*
		 * Full-scale calibration isn't supported at gain 1, so skip in
		 * that case. Note that untypically full-scale calibration has
		 * to happen before zero-scale calibration. This only applies to
		 * the internal calibration. For system calibration it's as
		 * usual: first zero-scale then full-scale calibration.
		 */
		if (st->channels[i].cfg.pga_bits > 0) {
			ret = ad_sd_calibrate(&st->sd, AD7124_ADC_CONTROL_MODE_INT_GAIN_CALIB, i);
			if (ret < 0)
				return ret;

			/*
			 * read out the resulting value of GAIN
			 * after full-scale calibration because the next
			 * ad_sd_calibrate() call overwrites this via
			 * ad_sigma_delta_set_channel() -> ad7124_set_channel()
			 * ... -> ad7124_enable_channel().
			 */
			ret = ad_sd_read_reg(&st->sd, AD7124_GAIN(st->channels[i].cfg.cfg_slot), 3,
					     &st->channels[i].cfg.calibration_gain);
			if (ret < 0)
				return ret;
		}

		ret = ad_sd_calibrate(&st->sd, AD7124_ADC_CONTROL_MODE_INT_OFFSET_CALIB, i);
		if (ret < 0)
			return ret;

		ret = ad_sd_read_reg(&st->sd, AD7124_OFFSET(st->channels[i].cfg.cfg_slot), 3,
				     &st->channels[i].cfg.calibration_offset);
		if (ret < 0)
			return ret;

		dev_dbg(dev, "offset and gain for channel %d = 0x%x + 0x%x\n", i,
			st->channels[i].cfg.calibration_offset,
			st->channels[i].cfg.calibration_gain);
	}

	return 0;
}

static int ad7124_calibrate_all(struct ad7124_state *st, struct iio_dev *indio_dev)
{
	int ret;
	unsigned int adc_control = st->adc_control;

	/*
	 * Calibration isn't supported at full power, so speed down a bit.
	 * Setting .adc_control is enough here because the control register is
	 * written as part of ad_sd_calibrate() -> ad_sigma_delta_set_mode().
	 * The resulting calibration is then also valid for high-speed, so just
	 * restore adc_control afterwards.
	 */
	if (FIELD_GET(AD7124_ADC_CONTROL_POWER_MODE, adc_control) >= AD7124_FULL_POWER) {
		st->adc_control &= ~AD7124_ADC_CONTROL_POWER_MODE;
		st->adc_control |= FIELD_PREP(AD7124_ADC_CONTROL_POWER_MODE, AD7124_MID_POWER);
	}

	ret = __ad7124_calibrate_all(st, indio_dev);

	st->adc_control = adc_control;

	return ret;
}

static void ad7124_reg_disable(void *r)
{
	regulator_disable(r);
}

static int ad7124_probe(struct spi_device *spi)
{
	const struct ad7124_chip_info *info;
	struct device *dev = &spi->dev;
	struct ad7124_state *st;
	struct iio_dev *indio_dev;
	int i, ret;

	info = spi_get_device_match_data(spi);
	if (!info)
		return dev_err_probe(dev, -ENODEV, "Failed to get match data\n");

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

	st = iio_priv(indio_dev);

	st->chip_info = info;

	indio_dev->name = st->chip_info->name;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->info = &ad7124_info;

	ret = ad_sd_init(&st->sd, indio_dev, spi, &ad7124_sigma_delta_info);
	if (ret < 0)
		return ret;

	ret = ad7124_parse_channel_config(indio_dev, &spi->dev);
	if (ret < 0)
		return ret;

	for (i = 0; i < ARRAY_SIZE(st->vref); i++) {
		if (i == AD7124_INT_REF)
			continue;

		st->vref[i] = devm_regulator_get_optional(&spi->dev,
						ad7124_ref_names[i]);
		if (PTR_ERR(st->vref[i]) == -ENODEV)
			continue;
		else if (IS_ERR(st->vref[i]))
			return PTR_ERR(st->vref[i]);

		ret = regulator_enable(st->vref[i]);
		if (ret)
			return dev_err_probe(dev, ret, "Failed to enable regulator #%d\n", i);

		ret = devm_add_action_or_reset(&spi->dev, ad7124_reg_disable,
					       st->vref[i]);
		if (ret)
			return dev_err_probe(dev, ret, "Failed to register disable handler for regulator #%d\n", i);
	}

	st->mclk = devm_clk_get_enabled(&spi->dev, "mclk");
	if (IS_ERR(st->mclk))
		return dev_err_probe(dev, PTR_ERR(st->mclk), "Failed to get mclk\n");

	ret = ad7124_soft_reset(st);
	if (ret < 0)
		return ret;

	ret = ad7124_check_chip_id(st);
	if (ret)
		return ret;

	ret = ad7124_setup(st);
	if (ret < 0)
		return ret;

	ret = devm_ad_sd_setup_buffer_and_trigger(&spi->dev, indio_dev);
	if (ret < 0)
		return dev_err_probe(dev, ret, "Failed to setup triggers\n");

	ret = ad7124_calibrate_all(st, indio_dev);
	if (ret)
		return ret;

	ret = devm_iio_device_register(&spi->dev, indio_dev);
	if (ret < 0)
		return dev_err_probe(dev, ret, "Failed to register iio device\n");

	return 0;
}

static const struct of_device_id ad7124_of_match[] = {
	{ .compatible = "adi,ad7124-4", .data = &ad7124_4_chip_info },
	{ .compatible = "adi,ad7124-8", .data = &ad7124_8_chip_info },
	{ }
};
MODULE_DEVICE_TABLE(of, ad7124_of_match);

static const struct spi_device_id ad71124_ids[] = {
	{ "ad7124-4", (kernel_ulong_t)&ad7124_4_chip_info },
	{ "ad7124-8", (kernel_ulong_t)&ad7124_8_chip_info },
	{ }
};
MODULE_DEVICE_TABLE(spi, ad71124_ids);

static struct spi_driver ad71124_driver = {
	.driver = {
		.name = "ad7124",
		.of_match_table = ad7124_of_match,
	},
	.probe = ad7124_probe,
	.id_table = ad71124_ids,
};
module_spi_driver(ad71124_driver);

MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
MODULE_DESCRIPTION("Analog Devices AD7124 SPI driver");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS("IIO_AD_SIGMA_DELTA");
