Contributors: 3
Author Tokens Token Proportion Commits Commit Proportion
Ana-Maria Cusco 6867 52.19% 1 9.09%
Marcelo Schmitt 6289 47.80% 9 81.82%
Bartosz Golaszewski 1 0.01% 1 9.09%
Total 13157 11


// SPDX-License-Identifier: GPL-2.0+
/*
 * Analog Devices AD4170-4 ADC driver
 *
 * Copyright (C) 2025 Analog Devices, Inc.
 * Author: Ana-Maria Cusco <ana-maria.cusco@analog.com>
 * Author: Marcelo Schmitt <marcelo.schmitt@analog.com>
 */

#include <linux/array_size.h>
#include <linux/bitfield.h>
#include <linux/bitmap.h>
#include <linux/bitops.h>
#include <linux/bits.h>
#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/gpio/driver.h>
#include <linux/iio/buffer.h>
#include <linux/iio/iio.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/math64.h>
#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
#include <linux/time.h>
#include <linux/types.h>
#include <linux/unaligned.h>
#include <linux/units.h>
#include <linux/util_macros.h>

/*
 * AD4170 registers
 * Multibyte register addresses point to the most significant byte which is the
 * address to use to get the most significant byte first (address accessed is
 * decremented by one for each data byte)
 *
 * Each register address define follows the AD4170_<REG_NAME>_REG format.
 * Each mask follows the AD4170_<REG_NAME>_<FIELD_NAME> format.
 * E.g. AD4170_PIN_MUXING_DIG_AUX1_CTRL_MSK is for accessing DIG_AUX1_CTRL field
 * of PIN_MUXING_REG.
 * Each constant follows the AD4170_<REG_NAME>_<FIELD_NAME>_<FUNCTION> format.
 * E.g. AD4170_PIN_MUXING_DIG_AUX1_DISABLED is the value written to
 * DIG_AUX1_CTRL field of PIN_MUXING register to disable DIG_AUX1 pin.
 * Some register names and register field names are shortened versions of
 * their datasheet counterpart names to provide better code readability.
 */
#define AD4170_CONFIG_A_REG				0x00
#define AD4170_DATA_24B_REG				0x1E
#define AD4170_PIN_MUXING_REG				0x69
#define AD4170_CLOCK_CTRL_REG				0x6B
#define AD4170_ADC_CTRL_REG				0x71
#define AD4170_CHAN_EN_REG				0x79
#define AD4170_CHAN_SETUP_REG(x)			(0x81 + 4 * (x))
#define AD4170_CHAN_MAP_REG(x)				(0x83 + 4 * (x))
#define AD4170_MISC_REG(x)				(0xC1 + 14 * (x))
#define AD4170_AFE_REG(x)				(0xC3 + 14 * (x))
#define AD4170_FILTER_REG(x)				(0xC5 + 14 * (x))
#define AD4170_FILTER_FS_REG(x)				(0xC7 + 14 * (x))
#define AD4170_OFFSET_REG(x)				(0xCA + 14 * (x))
#define AD4170_GAIN_REG(x)				(0xCD + 14 * (x))
#define AD4170_V_BIAS_REG				0x135
#define AD4170_CURRENT_SRC_REG(x)			(0x139 + 2 * (x))
#define AD4170_GPIO_MODE_REG				0x191
#define AD4170_GPIO_OUTPUT_REG				0x193
#define AD4170_GPIO_INPUT_REG				0x195
#define AD4170_ADC_CTRL_CONT_READ_EXIT_REG		0x200 /* virtual reg */

#define AD4170_REG_READ_MASK				BIT(14)

/* AD4170_CONFIG_A_REG - INTERFACE_CONFIG_A REGISTER */
#define AD4170_SW_RESET_MSK				(BIT(7) | BIT(0))

/* AD4170_PIN_MUXING_REG */
#define AD4170_PIN_MUXING_DIG_AUX1_CTRL_MSK		GENMASK(5, 4)

/* AD4170_CLOCK_CTRL_REG */
#define AD4170_CLOCK_CTRL_CLOCKSEL_MSK			GENMASK(1, 0)

/* AD4170_ADC_CTRL_REG */
#define AD4170_ADC_CTRL_MULTI_DATA_REG_SEL_MSK		BIT(7)
#define AD4170_ADC_CTRL_CONT_READ_MSK			GENMASK(5, 4)
#define AD4170_ADC_CTRL_MODE_MSK			GENMASK(3, 0)

/* AD4170_CHAN_EN_REG */
#define AD4170_CHAN_EN(ch)				BIT(ch)

/* AD4170_CHAN_SETUP_REG */
#define AD4170_CHAN_SETUP_SETUP_MSK			GENMASK(2, 0)

/* AD4170_CHAN_MAP_REG */
#define AD4170_CHAN_MAP_AINP_MSK			GENMASK(12, 8)
#define AD4170_CHAN_MAP_AINM_MSK			GENMASK(4, 0)

/* AD4170_MISC_REG */
#define AD4170_MISC_CHOP_IEXC_MSK			GENMASK(15, 14)
#define AD4170_MISC_CHOP_ADC_MSK			GENMASK(9, 8)

/* AD4170_AFE_REG */
#define AD4170_AFE_REF_BUF_M_MSK			GENMASK(11, 10)
#define AD4170_AFE_REF_BUF_P_MSK			GENMASK(9, 8)
#define AD4170_AFE_REF_SELECT_MSK			GENMASK(6, 5)
#define AD4170_AFE_BIPOLAR_MSK				BIT(4)
#define AD4170_AFE_PGA_GAIN_MSK				GENMASK(3, 0)

/* AD4170_FILTER_REG */
#define AD4170_FILTER_FILTER_TYPE_MSK			GENMASK(3, 0)

/* AD4170_CURRENT_SRC_REG */
#define AD4170_CURRENT_SRC_I_OUT_PIN_MSK		GENMASK(12, 8)
#define AD4170_CURRENT_SRC_I_OUT_VAL_MSK		GENMASK(2, 0)

/* AD4170_GPIO_MODE_REG */
#define AD4170_GPIO_MODE_GPIO0_MSK			GENMASK(1, 0)
#define AD4170_GPIO_MODE_GPIO1_MSK			GENMASK(3, 2)
#define AD4170_GPIO_MODE_GPIO2_MSK			GENMASK(5, 4)
#define AD4170_GPIO_MODE_GPIO3_MSK			GENMASK(7, 6)

/* AD4170_GPIO_OUTPUT_REG */
#define AD4170_GPIO_OUTPUT_GPIO_MSK(x)			BIT(x)

/* AD4170 register constants */

/* AD4170_CLOCK_CTRL_REG constants */
#define AD4170_CLOCK_CTRL_CLOCKSEL_INT			0x0
#define AD4170_CLOCK_CTRL_CLOCKSEL_INT_OUT		0x1
#define AD4170_CLOCK_CTRL_CLOCKSEL_EXT			0x2
#define AD4170_CLOCK_CTRL_CLOCKSEL_EXT_XTAL		0x3

/* AD4170_CHAN_MAP_REG constants */
#define AD4170_CHAN_MAP_AIN(x)			(x)
#define AD4170_CHAN_MAP_TEMP_SENSOR		17
#define AD4170_CHAN_MAP_AVDD_AVSS_P		18
#define AD4170_CHAN_MAP_AVDD_AVSS_N		18
#define AD4170_CHAN_MAP_IOVDD_DGND_P		19
#define AD4170_CHAN_MAP_IOVDD_DGND_N		19
#define AD4170_CHAN_MAP_AVSS			23
#define AD4170_CHAN_MAP_DGND			24
#define AD4170_CHAN_MAP_REFIN1_P		25
#define AD4170_CHAN_MAP_REFIN1_N		26
#define AD4170_CHAN_MAP_REFIN2_P		27
#define AD4170_CHAN_MAP_REFIN2_N		28
#define AD4170_CHAN_MAP_REFOUT			29

/* AD4170_MISC_REG constants */
#define AD4170_MISC_CHOP_IEXC_PAIR1			0x1
#define AD4170_MISC_CHOP_IEXC_PAIR2			0x2
#define AD4170_MISC_CHOP_IEXC_BOTH			0x3

/* AD4170_PIN_MUXING_REG constants */
#define AD4170_PIN_MUXING_DIG_AUX1_DISABLED		0x0
#define AD4170_PIN_MUXING_DIG_AUX1_RDY			0x1

/* AD4170_ADC_CTRL_REG constants */
#define AD4170_ADC_CTRL_MODE_CONT			0x0
#define AD4170_ADC_CTRL_MODE_SINGLE			0x4
#define AD4170_ADC_CTRL_MODE_IDLE			0x7

#define AD4170_ADC_CTRL_CONT_READ_DISABLE		0x0
#define AD4170_ADC_CTRL_CONT_READ_ENABLE		0x1

/* AD4170_FILTER_REG constants */
#define AD4170_FILTER_FILTER_TYPE_SINC5_AVG		0x0
#define AD4170_FILTER_FILTER_TYPE_SINC5			0x4
#define AD4170_FILTER_FILTER_TYPE_SINC3			0x6

/* AD4170_CURRENT_SRC_REG constants */
#define AD4170_CURRENT_SRC_I_OUT_PIN_AIN(x)		(x)
#define AD4170_CURRENT_SRC_I_OUT_PIN_GPIO(x)		((x) + 17)

/* AD4170_GPIO_MODE_REG constants */
#define AD4170_GPIO_MODE_GPIO_INPUT			1
#define AD4170_GPIO_MODE_GPIO_OUTPUT			2

/* Device properties and auxiliary constants */

#define AD4170_NUM_ANALOG_PINS				9
#define AD4170_NUM_GPIO_PINS				4
#define AD4170_MAX_ADC_CHANNELS				16
#define AD4170_MAX_IIO_CHANNELS				(AD4170_MAX_ADC_CHANNELS + 1)
#define AD4170_MAX_ANALOG_PINS				8
#define AD4170_MAX_SETUPS				8
#define AD4170_INVALID_SETUP				9
#define AD4170_SPI_INST_PHASE_LEN			2
#define AD4170_SPI_MAX_XFER_LEN				6
#define AD4170_NUM_CURRENT_SRC				4
#define AD4170_DEFAULT_SAMP_RATE			(125 * HZ_PER_KHZ)

#define AD4170_INT_REF_2_5V				2500000

/* Internal and external clock properties */
#define AD4170_INT_CLOCK_16MHZ				(16 * HZ_PER_MHZ)
#define AD4170_EXT_CLOCK_MHZ_MIN			(1 * HZ_PER_MHZ)
#define AD4170_EXT_CLOCK_MHZ_MAX			(17 * HZ_PER_MHZ)

#define AD4170_NUM_PGA_OPTIONS				10

/* Digital filter properties */
#define AD4170_SINC3_MIN_FS				4
#define AD4170_SINC3_MAX_FS				65532
#define AD4170_SINC5_MIN_FS				1
#define AD4170_SINC5_MAX_FS				256

#define AD4170_GAIN_REG_DEFAULT				0x555555

#define AD4170_ADC_CTRL_CONT_READ_EXIT			0xA5

/* Analog pin functions  */
#define AD4170_PIN_UNASSIGNED				0x00
#define AD4170_PIN_ANALOG_IN				0x01
#define AD4170_PIN_CURRENT_OUT				0x02
#define AD4170_PIN_VBIAS				0x04

/* GPIO pin functions  */
#define AD4170_GPIO_UNASSIGNED				0x00
#define AD4170_GPIO_AC_EXCITATION			0x02
#define AD4170_GPIO_OUTPUT				0x04

/* Current source */
#define AD4170_CURRENT_SRC_DISABLED			0xFF

static const unsigned int ad4170_reg_size[] = {
	[AD4170_CONFIG_A_REG] = 1,
	[AD4170_DATA_24B_REG] = 3,
	[AD4170_PIN_MUXING_REG] = 2,
	[AD4170_CLOCK_CTRL_REG] = 2,
	[AD4170_ADC_CTRL_REG] = 2,
	[AD4170_CHAN_EN_REG] = 2,
	/*
	 * CHANNEL_SETUP and CHANNEL_MAP register are all 2 byte size each and
	 * their addresses are interleaved such that we have CHANNEL_SETUP0
	 * address followed by CHANNEL_MAP0 address, followed by CHANNEL_SETUP1,
	 * and so on until CHANNEL_MAP15.
	 * Thus, initialize the register size for them only once.
	 */
	[AD4170_CHAN_SETUP_REG(0) ... AD4170_CHAN_MAP_REG(AD4170_MAX_ADC_CHANNELS - 1)] = 2,
	/*
	 * MISC, AFE, FILTER, FILTER_FS, OFFSET, and GAIN register addresses are
	 * also interleaved but MISC, AFE, FILTER, FILTER_FS, OFFSET are 16-bit
	 * while OFFSET, GAIN are 24-bit registers so we can't init them all to
	 * the same size.
	 */
	[AD4170_MISC_REG(0) ... AD4170_FILTER_FS_REG(0)] = 2,
	[AD4170_MISC_REG(1) ... AD4170_FILTER_FS_REG(1)] = 2,
	[AD4170_MISC_REG(2) ... AD4170_FILTER_FS_REG(2)] = 2,
	[AD4170_MISC_REG(3) ... AD4170_FILTER_FS_REG(3)] = 2,
	[AD4170_MISC_REG(4) ... AD4170_FILTER_FS_REG(4)] = 2,
	[AD4170_MISC_REG(5) ... AD4170_FILTER_FS_REG(5)] = 2,
	[AD4170_MISC_REG(6) ... AD4170_FILTER_FS_REG(6)] = 2,
	[AD4170_MISC_REG(7) ... AD4170_FILTER_FS_REG(7)] = 2,
	[AD4170_OFFSET_REG(0) ... AD4170_GAIN_REG(0)] = 3,
	[AD4170_OFFSET_REG(1) ... AD4170_GAIN_REG(1)] = 3,
	[AD4170_OFFSET_REG(2) ... AD4170_GAIN_REG(2)] = 3,
	[AD4170_OFFSET_REG(3) ... AD4170_GAIN_REG(3)] = 3,
	[AD4170_OFFSET_REG(4) ... AD4170_GAIN_REG(4)] = 3,
	[AD4170_OFFSET_REG(5) ... AD4170_GAIN_REG(5)] = 3,
	[AD4170_OFFSET_REG(6) ... AD4170_GAIN_REG(6)] = 3,
	[AD4170_OFFSET_REG(7) ... AD4170_GAIN_REG(7)] = 3,
	[AD4170_V_BIAS_REG] = 2,
	[AD4170_CURRENT_SRC_REG(0) ... AD4170_CURRENT_SRC_REG(3)] = 2,
	[AD4170_GPIO_MODE_REG] = 2,
	[AD4170_GPIO_OUTPUT_REG] = 2,
	[AD4170_GPIO_INPUT_REG] = 2,
	[AD4170_ADC_CTRL_CONT_READ_EXIT_REG] = 0,
};

enum ad4170_ref_buf {
	AD4170_REF_BUF_PRE,	/* Pre-charge referrence buffer */
	AD4170_REF_BUF_FULL,	/* Full referrence buffering */
	AD4170_REF_BUF_BYPASS,	/* Bypass referrence buffering */
};

/* maps adi,positive/negative-reference-buffer property values to enum */
static const char * const ad4170_ref_buf_str[] = {
	[AD4170_REF_BUF_PRE] = "precharge",
	[AD4170_REF_BUF_FULL] = "full",
	[AD4170_REF_BUF_BYPASS] = "disabled",
};

enum ad4170_ref_select {
	AD4170_REF_REFIN1,
	AD4170_REF_REFIN2,
	AD4170_REF_REFOUT,
	AD4170_REF_AVDD,
};

enum ad4170_filter_type {
	AD4170_SINC5_AVG,
	AD4170_SINC5,
	AD4170_SINC3,
};

enum ad4170_regulator {
	AD4170_AVDD_SUP,
	AD4170_AVSS_SUP,
	AD4170_IOVDD_SUP,
	AD4170_REFIN1P_SUP,
	AD4170_REFIN1N_SUP,
	AD4170_REFIN2P_SUP,
	AD4170_REFIN2N_SUP,
	AD4170_MAX_SUP,
};

static const char *const ad4170_clk_sel[] = {
	"ext-clk", "xtal",
};

enum ad4170_int_pin_sel {
	AD4170_INT_PIN_SDO,
	AD4170_INT_PIN_DIG_AUX1,
};

static const char * const ad4170_int_pin_names[] = {
	[AD4170_INT_PIN_SDO] = "sdo",
	[AD4170_INT_PIN_DIG_AUX1] = "dig_aux1",
};

static const unsigned int ad4170_sinc3_filt_fs_tbl[] = {
	4, 8, 12, 16, 20, 40, 48, 80,			/*  0 -  7 */
	100, 256, 500, 1000, 5000, 8332, 10000, 25000,	/*  8 - 15 */
	50000, 65532,					/* 16 - 17 */
};

#define AD4170_MAX_FS_TBL_SIZE		ARRAY_SIZE(ad4170_sinc3_filt_fs_tbl)

static const unsigned int ad4170_sinc5_filt_fs_tbl[] = {
	1, 2, 4, 8, 12, 16, 20, 40, 48, 80, 100, 256,
};

static const unsigned int ad4170_iout_pin_tbl[] = {
	AD4170_CURRENT_SRC_I_OUT_PIN_AIN(0),
	AD4170_CURRENT_SRC_I_OUT_PIN_AIN(1),
	AD4170_CURRENT_SRC_I_OUT_PIN_AIN(2),
	AD4170_CURRENT_SRC_I_OUT_PIN_AIN(3),
	AD4170_CURRENT_SRC_I_OUT_PIN_AIN(4),
	AD4170_CURRENT_SRC_I_OUT_PIN_AIN(5),
	AD4170_CURRENT_SRC_I_OUT_PIN_AIN(6),
	AD4170_CURRENT_SRC_I_OUT_PIN_AIN(7),
	AD4170_CURRENT_SRC_I_OUT_PIN_AIN(8),
	AD4170_CURRENT_SRC_I_OUT_PIN_GPIO(0),
	AD4170_CURRENT_SRC_I_OUT_PIN_GPIO(1),
	AD4170_CURRENT_SRC_I_OUT_PIN_GPIO(2),
	AD4170_CURRENT_SRC_I_OUT_PIN_GPIO(3),
};

static const unsigned int ad4170_iout_current_ua_tbl[] = {
	0, 10, 50, 100, 250, 500, 1000, 1500,
};

enum ad4170_sensor_enum {
	AD4170_ADC_SENSOR = 0,
	AD4170_WEIGH_SCALE_SENSOR = 1,
	AD4170_RTD_SENSOR = 2,
	AD4170_THERMOCOUPLE_SENSOR = 3,
};

/* maps adi,sensor-type property value to enum */
static const char * const ad4170_sensor_type[] = {
	[AD4170_ADC_SENSOR] = "adc",
	[AD4170_WEIGH_SCALE_SENSOR] = "weighscale",
	[AD4170_RTD_SENSOR] = "rtd",
	[AD4170_THERMOCOUPLE_SENSOR] = "thermocouple",
};

struct ad4170_chip_info {
	const char *name;
};

static const struct ad4170_chip_info ad4170_chip_info = {
	.name = "ad4170-4",
};

static const struct ad4170_chip_info ad4190_chip_info = {
	.name = "ad4190-4",
};

static const struct ad4170_chip_info ad4195_chip_info = {
	.name = "ad4195-4",
};

/*
 * There are 8 of each MISC, AFE, FILTER, FILTER_FS, OFFSET, and GAIN
 * configuration registers. That is, there are 8 miscellaneous registers, MISC0
 * to MISC7. Each MISC register is associated with a setup; MISCN is associated
 * with setup number N. The other 5 above mentioned types of registers have
 * analogous structure. A setup is a set of those registers. For example,
 * setup 1 comprises of MISC1, AFE1, FILTER1, FILTER_FS1, OFFSET1, and GAIN1
 * registers. Also, there are 16 CHANNEL_SETUP registers (CHANNEL_SETUP0 to
 * CHANNEL_SETUP15). Each channel setup is associated with one of the 8 possible
 * setups. Thus, AD4170 can support up to 16 channels but, since there are only
 * 8 available setups, channels must share settings if more than 8 channels are
 * configured.
 *
 * If this struct is modified, ad4170_setup_eq() will probably need to be
 * updated too.
 */
struct ad4170_setup {
	u16 misc;
	u16 afe;
	u16 filter;
	u16 filter_fs;
	u32 offset; /* For calibration purposes */
	u32 gain; /* For calibration purposes */
};

struct ad4170_setup_info {
	struct ad4170_setup setup;
	unsigned int enabled_channels;
	unsigned int channels;
};

struct ad4170_chan_info {
	unsigned int input_range_uv;
	unsigned int setup_num; /* Index to access state setup_infos array */
	struct ad4170_setup setup; /* cached setup */
	int offset_tbl[10];
	u32 scale_tbl[10][2];
	bool initialized;
	bool enabled;
};

static const char * const ad4170_filt_names[] = {
	[AD4170_SINC5_AVG] = "sinc5+avg",
	[AD4170_SINC5] = "sinc5",
	[AD4170_SINC3] = "sinc3",
};

struct ad4170_state {
	struct mutex lock; /* Protect read-modify-write and multi write sequences */
	int vrefs_uv[AD4170_MAX_SUP];
	u32 mclk_hz;
	struct ad4170_setup_info setup_infos[AD4170_MAX_SETUPS];
	struct ad4170_chan_info chan_infos[AD4170_MAX_ADC_CHANNELS];
	struct completion completion;
	struct iio_chan_spec chans[AD4170_MAX_IIO_CHANNELS];
	struct spi_device *spi;
	struct regmap *regmap;
	int sps_tbl[ARRAY_SIZE(ad4170_filt_names)][AD4170_MAX_FS_TBL_SIZE][2];
	__be32 bounce_buffer[AD4170_MAX_ADC_CHANNELS];
	struct spi_message msg;
	struct spi_transfer xfer;
	struct iio_trigger *trig;
	struct clk_hw int_clk_hw;
	unsigned int clock_ctrl;
	unsigned int pins_fn[AD4170_NUM_ANALOG_PINS];
	int gpio_fn[AD4170_NUM_GPIO_PINS];
	unsigned int cur_src_pins[AD4170_NUM_CURRENT_SRC];
	struct gpio_chip gpiochip;
	/*
	 * DMA (thus cache coherency maintenance) requires the transfer buffers
	 * to live in their own cache lines.
	 */
	u8 rx_buf[4] __aligned(IIO_DMA_MINALIGN);
};

static void ad4170_fill_sps_tbl(struct ad4170_state *st)
{
	unsigned int tmp0, tmp1, i;

	/*
	 * The ODR can be calculated the same way for sinc5+avg, sinc5, and
	 * sinc3 filter types with the exception that sinc5 filter has a
	 * narrowed range of allowed FILTER_FS values.
	 */
	for (i = 0; i < ARRAY_SIZE(ad4170_sinc3_filt_fs_tbl); i++) {
		tmp0 = div_u64_rem(st->mclk_hz, 32 * ad4170_sinc3_filt_fs_tbl[i],
				   &tmp1);
		tmp1 = mult_frac(tmp1, MICRO, 32 * ad4170_sinc3_filt_fs_tbl[i]);
		/* Fill sinc5+avg filter SPS table */
		st->sps_tbl[AD4170_SINC5_AVG][i][0] = tmp0; /* Integer part */
		st->sps_tbl[AD4170_SINC5_AVG][i][1] = tmp1; /* Fractional part */

		/* Fill sinc3 filter SPS table */
		st->sps_tbl[AD4170_SINC3][i][0] = tmp0; /* Integer part */
		st->sps_tbl[AD4170_SINC3][i][1] = tmp1; /* Fractional part */
	}
	/* Sinc5 filter ODR doesn't use all FILTER_FS bits */
	for (i = 0; i < ARRAY_SIZE(ad4170_sinc5_filt_fs_tbl); i++) {
		tmp0 = div_u64_rem(st->mclk_hz, 32 * ad4170_sinc5_filt_fs_tbl[i],
				   &tmp1);
		tmp1 = mult_frac(tmp1, MICRO, 32 * ad4170_sinc5_filt_fs_tbl[i]);
		/* Fill sinc5 filter SPS table */
		st->sps_tbl[AD4170_SINC5][i][0] = tmp0; /* Integer part */
		st->sps_tbl[AD4170_SINC5][i][1] = tmp1; /* Fractional part */
	}
}

static int ad4170_debugfs_reg_access(struct iio_dev *indio_dev,
				     unsigned int reg, unsigned int writeval,
				     unsigned int *readval)
{
	struct ad4170_state *st = iio_priv(indio_dev);

	if (readval)
		return regmap_read(st->regmap, reg, readval);

	return regmap_write(st->regmap, reg, writeval);
}

static int ad4170_get_reg_size(struct ad4170_state *st, unsigned int reg,
			       unsigned int *size)
{
	if (reg >= ARRAY_SIZE(ad4170_reg_size))
		return -EINVAL;

	*size = ad4170_reg_size[reg];

	return 0;
}

static int ad4170_reg_write(void *context, unsigned int reg, unsigned int val)
{
	struct ad4170_state *st = context;
	u8 tx_buf[AD4170_SPI_MAX_XFER_LEN];
	unsigned int size;
	int ret;

	ret = ad4170_get_reg_size(st, reg, &size);
	if (ret)
		return ret;

	put_unaligned_be16(reg, tx_buf);
	switch (size) {
	case 3:
		put_unaligned_be24(val, &tx_buf[AD4170_SPI_INST_PHASE_LEN]);
		break;
	case 2:
		put_unaligned_be16(val, &tx_buf[AD4170_SPI_INST_PHASE_LEN]);
		break;
	case 1:
		tx_buf[AD4170_SPI_INST_PHASE_LEN] = val;
		break;
	case 0:
		/* Write continuous read exit code */
		tx_buf[0] = AD4170_ADC_CTRL_CONT_READ_EXIT;
		return spi_write_then_read(st->spi, tx_buf, 1, NULL, 0);
	default:
		return -EINVAL;
	}

	return spi_write_then_read(st->spi, tx_buf,
				   AD4170_SPI_INST_PHASE_LEN + size, NULL, 0);
}

static int ad4170_reg_read(void *context, unsigned int reg, unsigned int *val)
{
	struct ad4170_state *st = context;
	u8 tx_buf[AD4170_SPI_INST_PHASE_LEN];
	unsigned int size;
	int ret;

	put_unaligned_be16(AD4170_REG_READ_MASK | reg, tx_buf);

	ret = ad4170_get_reg_size(st, reg, &size);
	if (ret)
		return ret;

	ret = spi_write_then_read(st->spi, tx_buf, ARRAY_SIZE(tx_buf),
				  st->rx_buf, size);
	if (ret)
		return ret;

	switch (size) {
	case 3:
		*val = get_unaligned_be24(st->rx_buf);
		return 0;
	case 2:
		*val = get_unaligned_be16(st->rx_buf);
		return 0;
	case 1:
		*val = st->rx_buf[0];
		return 0;
	default:
		return -EINVAL;
	}
}

static const struct regmap_config ad4170_regmap_config = {
	.reg_read = ad4170_reg_read,
	.reg_write = ad4170_reg_write,
};

static bool ad4170_setup_eq(struct ad4170_setup *a, struct ad4170_setup *b)
{
	if (a->misc != b->misc ||
	    a->afe != b->afe ||
	    a->filter != b->filter ||
	    a->filter_fs != b->filter_fs ||
	    a->offset != b->offset ||
	    a->gain != b->gain)
		return false;

	return true;
}

static int ad4170_find_setup(struct ad4170_state *st,
			     struct ad4170_setup *target_setup,
			     unsigned int *setup_num, bool *overwrite)
{
	unsigned int i;

	*setup_num = AD4170_INVALID_SETUP;
	*overwrite = false;

	for (i = 0; i < AD4170_MAX_SETUPS; i++) {
		struct ad4170_setup_info *setup_info = &st->setup_infos[i];

		/* Immediately accept a matching setup. */
		if (ad4170_setup_eq(target_setup, &setup_info->setup)) {
			*setup_num = i;
			return 0;
		}

		/* Ignore all setups which are used by enabled channels. */
		if (setup_info->enabled_channels)
			continue;

		/* Find the least used slot. */
		if (*setup_num == AD4170_INVALID_SETUP ||
		    setup_info->channels < st->setup_infos[*setup_num].channels)
			*setup_num = i;
	}

	if (*setup_num == AD4170_INVALID_SETUP)
		return -EINVAL;

	*overwrite = true;
	return 0;
}

static void ad4170_unlink_channel(struct ad4170_state *st, unsigned int channel)
{
	struct ad4170_chan_info *chan_info = &st->chan_infos[channel];
	struct ad4170_setup_info *setup_info = &st->setup_infos[chan_info->setup_num];

	chan_info->setup_num = AD4170_INVALID_SETUP;
	setup_info->channels--;
}

static int ad4170_unlink_setup(struct ad4170_state *st, unsigned int setup_num)
{
	unsigned int i;

	for (i = 0; i < AD4170_MAX_ADC_CHANNELS; i++) {
		struct ad4170_chan_info *chan_info = &st->chan_infos[i];

		if (!chan_info->initialized || chan_info->setup_num != setup_num)
			continue;

		ad4170_unlink_channel(st, i);
	}
	return 0;
}

static int ad4170_link_channel_setup(struct ad4170_state *st,
				     unsigned int chan_addr,
				     unsigned int setup_num)
{
	struct ad4170_setup_info *setup_info = &st->setup_infos[setup_num];
	struct ad4170_chan_info *chan_info = &st->chan_infos[chan_addr];
	int ret;

	ret = regmap_update_bits(st->regmap, AD4170_CHAN_SETUP_REG(chan_addr),
				 AD4170_CHAN_SETUP_SETUP_MSK,
				 FIELD_PREP(AD4170_CHAN_SETUP_SETUP_MSK, setup_num));
	if (ret)
		return ret;

	chan_info->setup_num = setup_num;
	setup_info->channels++;
	return 0;
}

static int ad4170_write_setup(struct ad4170_state *st, unsigned int setup_num,
			      struct ad4170_setup *setup)
{
	int ret;

	/*
	 * It is recommended to place the ADC in standby mode or idle mode to
	 * write to OFFSET and GAIN registers.
	 */
	ret = regmap_update_bits(st->regmap, AD4170_ADC_CTRL_REG,
				 AD4170_ADC_CTRL_MODE_MSK,
				 FIELD_PREP(AD4170_ADC_CTRL_MODE_MSK,
					    AD4170_ADC_CTRL_MODE_IDLE));
	if (ret)
		return ret;

	ret = regmap_write(st->regmap, AD4170_MISC_REG(setup_num), setup->misc);
	if (ret)
		return ret;

	ret = regmap_write(st->regmap, AD4170_AFE_REG(setup_num), setup->afe);
	if (ret)
		return ret;

	ret = regmap_write(st->regmap, AD4170_FILTER_REG(setup_num),
			   setup->filter);
	if (ret)
		return ret;

	ret = regmap_write(st->regmap, AD4170_FILTER_FS_REG(setup_num),
			   setup->filter_fs);
	if (ret)
		return ret;

	ret = regmap_write(st->regmap, AD4170_OFFSET_REG(setup_num),
			   setup->offset);
	if (ret)
		return ret;

	ret = regmap_write(st->regmap, AD4170_GAIN_REG(setup_num), setup->gain);
	if (ret)
		return ret;

	memcpy(&st->setup_infos[setup_num].setup, setup, sizeof(*setup));
	return 0;
}

static int ad4170_write_channel_setup(struct ad4170_state *st,
				      unsigned int chan_addr, bool on_enable)
{
	struct ad4170_chan_info *chan_info = &st->chan_infos[chan_addr];
	bool overwrite;
	int setup_num;
	int ret;

	/*
	 * Similar to AD4130 driver, the following cases need to be handled.
	 *
	 * 1. Enabled and linked channel with setup changes:
	 *    - Find a setup. If not possible, return error.
	 *    - Unlink channel from current setup.
	 *    - If the setup found has only disabled channels linked to it,
	 *      unlink all channels, and write the new setup to it.
	 *    - Link channel to new setup.
	 *
	 * 2. Soon to be enabled and unlinked channel:
	 *    - Find a setup. If not possible, return error.
	 *    - If the setup found has only disabled channels linked to it,
	 *      unlink all channels, and write the new setup to it.
	 *    - Link channel to the setup.
	 *
	 * 3. Disabled and linked channel with setup changes:
	 *    - Unlink channel from current setup.
	 *
	 * 4. Soon to be enabled and linked channel:
	 * 5. Disabled and unlinked channel with setup changes:
	 *    - Do nothing.
	 */

	/* Cases 3, 4, and 5 */
	if (chan_info->setup_num != AD4170_INVALID_SETUP) {
		/* Case 4 */
		if (on_enable)
			return 0;

		/* Case 3 */
		if (!chan_info->enabled) {
			ad4170_unlink_channel(st, chan_addr);
			return 0;
		}
	} else if (!on_enable && !chan_info->enabled) {
		/* Case 5 */
		return 0;
	}

	/* Cases 1 & 2 */
	ret = ad4170_find_setup(st, &chan_info->setup, &setup_num, &overwrite);
	if (ret)
		return ret;

	if (chan_info->setup_num != AD4170_INVALID_SETUP)
		/* Case 1 */
		ad4170_unlink_channel(st, chan_addr);

	if (overwrite) {
		ret = ad4170_unlink_setup(st, setup_num);
		if (ret)
			return ret;

		ret = ad4170_write_setup(st, setup_num, &chan_info->setup);
		if (ret)
			return ret;
	}

	return ad4170_link_channel_setup(st, chan_addr, setup_num);
}

static int ad4170_set_channel_enable(struct ad4170_state *st,
				     unsigned int chan_addr, bool status)
{
	struct ad4170_chan_info *chan_info = &st->chan_infos[chan_addr];
	struct ad4170_setup_info *setup_info;
	int ret;

	if (chan_info->enabled == status)
		return 0;

	if (status) {
		ret = ad4170_write_channel_setup(st, chan_addr, true);
		if (ret)
			return ret;
	}

	setup_info = &st->setup_infos[chan_info->setup_num];

	ret = regmap_update_bits(st->regmap, AD4170_CHAN_EN_REG,
				 AD4170_CHAN_EN(chan_addr),
				 status ? AD4170_CHAN_EN(chan_addr) : 0);
	if (ret)
		return ret;

	setup_info->enabled_channels += status ? 1 : -1;
	chan_info->enabled = status;
	return 0;
}

static int __ad4170_get_filter_type(unsigned int filter)
{
	u16 f_conf = FIELD_GET(AD4170_FILTER_FILTER_TYPE_MSK, filter);

	switch (f_conf) {
	case AD4170_FILTER_FILTER_TYPE_SINC5_AVG:
		return AD4170_SINC5_AVG;
	case AD4170_FILTER_FILTER_TYPE_SINC5:
		return AD4170_SINC5;
	case AD4170_FILTER_FILTER_TYPE_SINC3:
		return AD4170_SINC3;
	default:
		return -EINVAL;
	}
}

static int ad4170_set_filter_type(struct iio_dev *indio_dev,
				  struct iio_chan_spec const *chan,
				  unsigned int val)
{
	struct ad4170_state *st = iio_priv(indio_dev);
	struct ad4170_chan_info *chan_info = &st->chan_infos[chan->address];
	struct ad4170_setup *setup = &chan_info->setup;
	unsigned int filter_type_conf;
	int ret;

	switch (val) {
	case AD4170_SINC5_AVG:
		filter_type_conf = AD4170_FILTER_FILTER_TYPE_SINC5_AVG;
		break;
	case AD4170_SINC5:
		filter_type_conf = AD4170_FILTER_FILTER_TYPE_SINC5;
		break;
	case AD4170_SINC3:
		filter_type_conf = AD4170_FILTER_FILTER_TYPE_SINC3;
		break;
	default:
		return -EINVAL;
	}

	/*
	 * The filters provide the same ODR for a given filter_fs value but
	 * there are different minimum and maximum filter_fs limits for each
	 * filter. The filter_fs value will be adjusted if the current filter_fs
	 * is out of the limits of the just requested filter. Since the
	 * filter_fs value affects the ODR (sampling_frequency), changing the
	 * filter may lead to a change in the sampling frequency.
	 */
	scoped_guard(mutex, &st->lock) {
		if (!iio_device_claim_direct(indio_dev))
			return -EBUSY;

		if (val == AD4170_SINC5_AVG || val == AD4170_SINC3)
			setup->filter_fs = clamp(val, AD4170_SINC3_MIN_FS,
						 AD4170_SINC3_MAX_FS);
		else
			setup->filter_fs = clamp(val, AD4170_SINC5_MIN_FS,
						 AD4170_SINC5_MAX_FS);

		setup->filter &= ~AD4170_FILTER_FILTER_TYPE_MSK;
		setup->filter |= FIELD_PREP(AD4170_FILTER_FILTER_TYPE_MSK,
					    filter_type_conf);

		ret = ad4170_write_channel_setup(st, chan->address, false);
		iio_device_release_direct(indio_dev);
	}

	return ret;
}

static int ad4170_get_filter_type(struct iio_dev *indio_dev,
				  struct iio_chan_spec const *chan)
{
	struct ad4170_state *st = iio_priv(indio_dev);
	struct ad4170_chan_info *chan_info = &st->chan_infos[chan->address];
	struct ad4170_setup *setup = &chan_info->setup;

	return __ad4170_get_filter_type(setup->filter);
}

static const struct iio_enum ad4170_filter_type_enum = {
	.items = ad4170_filt_names,
	.num_items = ARRAY_SIZE(ad4170_filt_names),
	.get = ad4170_get_filter_type,
	.set = ad4170_set_filter_type,
};

static const struct iio_chan_spec_ext_info ad4170_filter_type_ext_info[] = {
	IIO_ENUM("filter_type", IIO_SEPARATE, &ad4170_filter_type_enum),
	IIO_ENUM_AVAILABLE("filter_type", IIO_SHARED_BY_TYPE,
			   &ad4170_filter_type_enum),
	{ }
};

static const struct iio_chan_spec ad4170_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_CALIBBIAS) |
			      BIT(IIO_CHAN_INFO_CALIBSCALE) |
			      BIT(IIO_CHAN_INFO_SAMP_FREQ) |
			      BIT(IIO_CHAN_INFO_OFFSET),
	.info_mask_separate_available = BIT(IIO_CHAN_INFO_SCALE) |
					BIT(IIO_CHAN_INFO_SAMP_FREQ),
	.ext_info = ad4170_filter_type_ext_info,
	.scan_type = {
		.realbits = 24,
		.storagebits = 32,
		.shift = 8,
		.endianness = IIO_BE,
	},
};

static const struct iio_chan_spec ad4170_temp_channel_template = {
	.type = IIO_TEMP,
	.indexed = 0,
	.channel = 17,
	.channel2 = 17,
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
			      BIT(IIO_CHAN_INFO_SCALE) |
			      BIT(IIO_CHAN_INFO_OFFSET) |
			      BIT(IIO_CHAN_INFO_CALIBSCALE) |
			      BIT(IIO_CHAN_INFO_CALIBBIAS) |
			      BIT(IIO_CHAN_INFO_SAMP_FREQ),
	.info_mask_separate_available = BIT(IIO_CHAN_INFO_SAMP_FREQ),
	.scan_type = {
		.sign = 's',
		.realbits = 24,
		.storagebits = 32,
		.shift = 8,
		.endianness = IIO_BE,
	},
};

/*
 * Receives the number of a multiplexed AD4170 input (ain_n), and stores the
 * voltage (in µV) of the specified input into ain_voltage. If the input number
 * is a ordinary analog input (AIN0 to AIN8), stores zero into ain_voltage.
 * If a voltage regulator required by a special input is unavailable, return
 * error code. Return 0 on success.
 */
static int ad4170_get_ain_voltage_uv(struct ad4170_state *st, int ain_n,
				     int *ain_voltage)
{
	struct device *dev = &st->spi->dev;
	int v_diff;

	*ain_voltage = 0;
	/*
	 * The voltage bias (vbias) sets the common-mode voltage of the channel
	 * to (AVDD + AVSS)/2. If provided, AVSS supply provides the magnitude
	 * (absolute value) of the negative voltage supplied to the AVSS pin.
	 * So, we do AVDD - AVSS to compute the DC voltage generated by the bias
	 * voltage generator.
	 */
	if (st->pins_fn[ain_n] & AD4170_PIN_VBIAS) {
		int v_diff = st->vrefs_uv[AD4170_AVDD_SUP] - st->vrefs_uv[AD4170_AVSS_SUP];
		*ain_voltage = v_diff / 2;
		return 0;
	}

	if (ain_n <= AD4170_CHAN_MAP_TEMP_SENSOR)
		return 0;

	switch (ain_n) {
	case AD4170_CHAN_MAP_AVDD_AVSS_N:
		v_diff = st->vrefs_uv[AD4170_AVDD_SUP] - st->vrefs_uv[AD4170_AVSS_SUP];
		*ain_voltage = v_diff / 5;
		return 0;
	case AD4170_CHAN_MAP_IOVDD_DGND_N:
		*ain_voltage = st->vrefs_uv[AD4170_IOVDD_SUP] / 5;
		return 0;
	case AD4170_CHAN_MAP_AVSS:
		*ain_voltage = st->vrefs_uv[AD4170_AVSS_SUP];
		return 0;
	case AD4170_CHAN_MAP_DGND:
		*ain_voltage = 0;
		return 0;
	case AD4170_CHAN_MAP_REFIN1_P:
		if (st->vrefs_uv[AD4170_REFIN1P_SUP] == -ENODEV)
			return dev_err_probe(dev, -ENODEV,
					     "input set to REFIN+ but ref not provided\n");

		*ain_voltage = st->vrefs_uv[AD4170_REFIN1P_SUP];
		return 0;
	case AD4170_CHAN_MAP_REFIN1_N:
		if (st->vrefs_uv[AD4170_REFIN1N_SUP] == -ENODEV)
			return dev_err_probe(dev, -ENODEV,
					     "input set to REFIN- but ref not provided\n");

		*ain_voltage = st->vrefs_uv[AD4170_REFIN1N_SUP];
		return 0;
	case AD4170_CHAN_MAP_REFIN2_P:
		if (st->vrefs_uv[AD4170_REFIN2P_SUP] == -ENODEV)
			return dev_err_probe(dev, -ENODEV,
					     "input set to REFIN2+ but ref not provided\n");

		*ain_voltage = st->vrefs_uv[AD4170_REFIN2P_SUP];
		return 0;
	case AD4170_CHAN_MAP_REFIN2_N:
		if (st->vrefs_uv[AD4170_REFIN2N_SUP] == -ENODEV)
			return dev_err_probe(dev, -ENODEV,
					     "input set to REFIN2- but ref not provided\n");

		*ain_voltage = st->vrefs_uv[AD4170_REFIN2N_SUP];
		return 0;
	case AD4170_CHAN_MAP_REFOUT:
		/* REFOUT is 2.5V relative to AVSS so take that into account */
		*ain_voltage = st->vrefs_uv[AD4170_AVSS_SUP] + AD4170_INT_REF_2_5V;
		return 0;
	default:
		return -EINVAL;
	}
}

static int ad4170_validate_analog_input(struct ad4170_state *st, int pin)
{
	if (pin <= AD4170_MAX_ANALOG_PINS) {
		if (st->pins_fn[pin] & AD4170_PIN_CURRENT_OUT)
			return dev_err_probe(&st->spi->dev, -EINVAL,
					     "Pin %d already used with fn %u.\n",
					     pin, st->pins_fn[pin]);

		st->pins_fn[pin] |= AD4170_PIN_ANALOG_IN;
	}
	return 0;
}

static int ad4170_validate_channel_input(struct ad4170_state *st, int pin, bool com)
{
	/* Check common-mode input pin is mapped to a special input. */
	if (com && (pin < AD4170_CHAN_MAP_AVDD_AVSS_P || pin > AD4170_CHAN_MAP_REFOUT))
		return dev_err_probe(&st->spi->dev, -EINVAL,
				     "Invalid common-mode input pin number. %d\n",
				     pin);

	/* Check differential input pin is mapped to a analog input pin. */
	if (!com && pin > AD4170_MAX_ANALOG_PINS)
		return dev_err_probe(&st->spi->dev, -EINVAL,
				     "Invalid analog input pin number. %d\n",
				     pin);

	return ad4170_validate_analog_input(st, pin);
}

/*
 * Verifies whether the channel input configuration is valid by checking the
 * input numbers.
 * Returns 0 on valid channel input configuration. -EINVAL otherwise.
 */
static int ad4170_validate_channel(struct ad4170_state *st,
				   struct iio_chan_spec const *chan)
{
	int ret;

	ret = ad4170_validate_channel_input(st, chan->channel, false);
	if (ret)
		return ret;

	return ad4170_validate_channel_input(st, chan->channel2,
					     !chan->differential);
}

/*
 * Verifies whether the channel configuration is valid by checking the provided
 * input type, polarity, and voltage references result in a sane input range.
 * Returns negative error code on failure.
 */
static int ad4170_get_input_range(struct ad4170_state *st,
				  struct iio_chan_spec const *chan,
				  unsigned int ch_reg, unsigned int ref_sel)
{
	bool bipolar = chan->scan_type.sign == 's';
	struct device *dev = &st->spi->dev;
	int refp, refn, ain_voltage, ret;

	switch (ref_sel) {
	case AD4170_REF_REFIN1:
		if (st->vrefs_uv[AD4170_REFIN1P_SUP] == -ENODEV ||
		    st->vrefs_uv[AD4170_REFIN1N_SUP] == -ENODEV)
			return dev_err_probe(dev, -ENODEV,
					     "REFIN± selected but not provided\n");

		refp = st->vrefs_uv[AD4170_REFIN1P_SUP];
		refn = st->vrefs_uv[AD4170_REFIN1N_SUP];
		break;
	case AD4170_REF_REFIN2:
		if (st->vrefs_uv[AD4170_REFIN2P_SUP] == -ENODEV ||
		    st->vrefs_uv[AD4170_REFIN2N_SUP] == -ENODEV)
			return dev_err_probe(dev, -ENODEV,
					     "REFIN2± selected but not provided\n");

		refp = st->vrefs_uv[AD4170_REFIN2P_SUP];
		refn = st->vrefs_uv[AD4170_REFIN2N_SUP];
		break;
	case AD4170_REF_AVDD:
		refp = st->vrefs_uv[AD4170_AVDD_SUP];
		refn = st->vrefs_uv[AD4170_AVSS_SUP];
		break;
	case AD4170_REF_REFOUT:
		/* REFOUT is 2.5 V relative to AVSS */
		refp = st->vrefs_uv[AD4170_AVSS_SUP] + AD4170_INT_REF_2_5V;
		refn = st->vrefs_uv[AD4170_AVSS_SUP];
		break;
	default:
		return -EINVAL;
	}

	/*
	 * Find out the analog input range from the channel type, polarity, and
	 * voltage reference selection.
	 * AD4170 channels are either differential or pseudo-differential.
	 * Diff input voltage range: −VREF/gain to +VREF/gain (datasheet page 6)
	 * Pseudo-diff input voltage range: 0 to VREF/gain (datasheet page 6)
	 */
	if (chan->differential) {
		if (!bipolar)
			return dev_err_probe(dev, -EINVAL,
					     "Channel %u differential unipolar\n",
					     ch_reg);

		/*
		 * Differential bipolar channel.
		 * avss-supply is never above 0V.
		 * Assuming refin1n-supply not above 0V.
		 * Assuming refin2n-supply not above 0V.
		 */
		return refp + abs(refn);
	}
	/*
	 * Some configurations can lead to invalid setups.
	 * For example, if AVSS = -2.5V, REF_SELECT set to REFOUT (REFOUT/AVSS),
	 * and pseudo-diff channel configuration set, then the input range
	 * should go from 0V to +VREF (single-ended - datasheet pg 10), but
	 * REFOUT/AVSS range would be -2.5V to 0V.
	 * Check the positive reference is higher than 0V for pseudo-diff
	 * channels.
	 * Note that at this point in the code, refp can only be >= 0 since all
	 * error codes from reading the regulator voltage have been checked
	 * either at ad4170_regulator_setup() or above in this function.
	 */
	if (refp == 0)
		return dev_err_probe(dev, -EINVAL,
				     "REF+ == GND for pseudo-diff chan %u\n",
				     ch_reg);

	if (bipolar)
		return refp;

	/*
	 * Pseudo-differential unipolar channel.
	 * Input expected to swing from IN- to +VREF.
	 */
	ret = ad4170_get_ain_voltage_uv(st, chan->channel2, &ain_voltage);
	if (ret)
		return ret;

	if (refp - ain_voltage <= 0)
		return dev_err_probe(dev, -EINVAL,
				     "Negative input >= REF+ for pseudo-diff chan %u\n",
				     ch_reg);

	return refp - ain_voltage;
}

static int __ad4170_read_sample(struct iio_dev *indio_dev,
				struct iio_chan_spec const *chan, int *val)
{
	struct ad4170_state *st = iio_priv(indio_dev);
	unsigned long settling_time_ms;
	int ret;

	reinit_completion(&st->completion);
	ret = regmap_update_bits(st->regmap, AD4170_ADC_CTRL_REG,
				 AD4170_ADC_CTRL_MODE_MSK,
				 FIELD_PREP(AD4170_ADC_CTRL_MODE_MSK,
					    AD4170_ADC_CTRL_MODE_SINGLE));
	if (ret)
		return ret;

	/*
	 * When a channel is manually selected by the user, the ADC needs an
	 * extra time to provide the first stable conversion. The ADC settling
	 * time depends on the filter type, filter frequency, and ADC clock
	 * frequency (see datasheet page 53). The maximum settling time among
	 * all filter configurations is 6291164 / fCLK. Use that formula to wait
	 * for sufficient time whatever the filter configuration may be.
	 */
	settling_time_ms = DIV_ROUND_UP(6291164 * MILLI, st->mclk_hz);
	ret = wait_for_completion_timeout(&st->completion,
					  msecs_to_jiffies(settling_time_ms));
	if (!ret)
		dev_dbg(&st->spi->dev,
			"No Data Ready signal. Reading after delay.\n");

	ret = regmap_read(st->regmap, AD4170_DATA_24B_REG, val);
	if (ret)
		return ret;

	if (chan->scan_type.sign == 's')
		*val = sign_extend32(*val, chan->scan_type.realbits - 1);

	return 0;
}

static int ad4170_read_sample(struct iio_dev *indio_dev,
			      struct iio_chan_spec const *chan, int *val)
{
	struct ad4170_state *st = iio_priv(indio_dev);
	struct device *dev = &st->spi->dev;
	int ret, ret2;

	/*
	 * The ADC sequences through all enabled channels. That can lead to
	 * incorrect channel being sampled if a previous read would have left a
	 * different channel enabled. Thus, always enable and disable the
	 * channel on single-shot read.
	 */
	ret = ad4170_set_channel_enable(st, chan->address, true);
	if (ret)
		return ret;

	ret = __ad4170_read_sample(indio_dev, chan, val);
	if (ret) {
		dev_err(dev, "failed to read sample: %d\n", ret);

		ret2 = ad4170_set_channel_enable(st, chan->address, false);
		if (ret2)
			dev_err(dev, "failed to disable channel: %d\n", ret2);

		return ret;
	}

	ret = ad4170_set_channel_enable(st, chan->address, false);
	if (ret)
		return ret;

	return IIO_VAL_INT;
}

static int ad4170_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan,
			   int *val, int *val2, long info)
{
	struct ad4170_state *st = iio_priv(indio_dev);
	struct ad4170_chan_info *chan_info = &st->chan_infos[chan->address];
	struct ad4170_setup *setup = &chan_info->setup;
	enum ad4170_filter_type f_type;
	unsigned int pga, fs_idx;
	int ret;

	guard(mutex)(&st->lock);
	switch (info) {
	case IIO_CHAN_INFO_RAW:
		if (!iio_device_claim_direct(indio_dev))
			return -EBUSY;

		ret = ad4170_read_sample(indio_dev, chan, val);
		iio_device_release_direct(indio_dev);
		return ret;
	case IIO_CHAN_INFO_SCALE:
		pga = FIELD_GET(AD4170_AFE_PGA_GAIN_MSK, setup->afe);
		switch (chan->type) {
		case IIO_VOLTAGE:
			*val = chan_info->scale_tbl[pga][0];
			*val2 = chan_info->scale_tbl[pga][1];
			return IIO_VAL_INT_PLUS_NANO;
		case IIO_TEMP:
			/*
			 * The scale_tbl converts output codes to mV units so
			 * multiply by MILLI to make the factor convert to µV.
			 * Then, apply the temperature sensor change sensitivity
			 * of 477 μV/K. Finally, multiply the result by MILLI
			 * again to comply with milli degrees Celsius IIO ABI.
			 */
			*val = 0;
			*val2 = DIV_ROUND_CLOSEST(chan_info->scale_tbl[pga][1] * MILLI, 477) *
						  MILLI;
			return IIO_VAL_INT_PLUS_NANO;
		default:
			return -EINVAL;
		}
	case IIO_CHAN_INFO_OFFSET:
		pga = FIELD_GET(AD4170_AFE_PGA_GAIN_MSK, setup->afe);
		*val = chan_info->offset_tbl[pga];
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SAMP_FREQ:
		f_type = __ad4170_get_filter_type(setup->filter);
		switch (f_type) {
		case AD4170_SINC5_AVG:
		case AD4170_SINC3:
			fs_idx = find_closest(setup->filter_fs,
					      ad4170_sinc3_filt_fs_tbl,
					      ARRAY_SIZE(ad4170_sinc3_filt_fs_tbl));
			*val = st->sps_tbl[f_type][fs_idx][0];
			*val2 = st->sps_tbl[f_type][fs_idx][1];
			return IIO_VAL_INT_PLUS_MICRO;
		case AD4170_SINC5:
			fs_idx = find_closest(setup->filter_fs,
					      ad4170_sinc5_filt_fs_tbl,
					      ARRAY_SIZE(ad4170_sinc5_filt_fs_tbl));
			*val = st->sps_tbl[f_type][fs_idx][0];
			*val2 = st->sps_tbl[f_type][fs_idx][1];
			return IIO_VAL_INT_PLUS_MICRO;
		default:
			return -EINVAL;
		}
	case IIO_CHAN_INFO_CALIBBIAS:
		*val = setup->offset;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_CALIBSCALE:
		*val = setup->gain;
		return IIO_VAL_INT;
	default:
		return -EINVAL;
	}
}

static int ad4170_fill_scale_tbl(struct iio_dev *indio_dev,
				 struct iio_chan_spec const *chan)
{
	struct ad4170_state *st = iio_priv(indio_dev);
	struct ad4170_chan_info *chan_info = &st->chan_infos[chan->address];
	struct device *dev = &st->spi->dev;
	int bipolar = chan->scan_type.sign == 's' ? 1 : 0;
	int precision_bits = chan->scan_type.realbits;
	int pga, ainm_voltage, ret;
	unsigned long long offset;

	ainm_voltage = 0;
	ret = ad4170_get_ain_voltage_uv(st, chan->channel2, &ainm_voltage);
	if (ret < 0)
		return dev_err_probe(dev, ret, "Failed to fill scale table\n");

	for (pga = 0; pga < AD4170_NUM_PGA_OPTIONS; pga++) {
		u64 nv;
		unsigned int lshift, rshift;

		/*
		 * The PGA options are numbered from 0 to 9, with option 0 being
		 * a gain of 2^0 (no actual gain), and 7 meaning a gain of 2^7.
		 * Option 8, though, sets a gain of 0.5, so the input signal can
		 * be attenuated by 2 rather than amplified. Option 9, allows
		 * the signal to bypass the PGA circuitry (no gain).
		 *
		 * The scale factor to get ADC output codes to values in mV
		 * units is given by:
		 * _scale = (input_range / gain) / 2^precision
		 * AD4170 gain is a power of 2 so the above can be written as
		 * _scale = input_range / 2^(precision + gain)
		 * Keep the input range in µV to avoid truncating the less
		 * significant bits when right shifting it so to preserve scale
		 * precision.
		 */
		nv = (u64)chan_info->input_range_uv * NANO;
		lshift = !!(pga & BIT(3)); /* handle PGA options 8 and 9 */
		rshift = precision_bits - bipolar + (pga & GENMASK(2, 0)) - lshift;
		chan_info->scale_tbl[pga][0] = 0;
		chan_info->scale_tbl[pga][1] = div_u64(nv >> rshift, MILLI);

		/*
		 * If the negative input is not at GND, the conversion result
		 * (which is relative to IN-) will be offset by the level at IN-.
		 * Use the scale factor the other way around to go from a known
		 * voltage to the corresponding ADC output code.
		 * With that, we are able to get to what would be the output
		 * code for the voltage at the negative input.
		 * If the negative input is not fixed, there is no offset.
		 */
		offset = ((unsigned long long)abs(ainm_voltage)) * MICRO;
		offset = DIV_ROUND_CLOSEST_ULL(offset, chan_info->scale_tbl[pga][1]);

		/*
		 * After divided by the scale, offset will always fit into 31
		 * bits. For _raw + _offset to be relative to GND, the value
		 * provided as _offset is of opposite sign than the real offset.
		 */
		if (ainm_voltage > 0)
			chan_info->offset_tbl[pga] = -(int)(offset);
		else
			chan_info->offset_tbl[pga] = (int)(offset);
	}
	return 0;
}

static int ad4170_read_avail(struct iio_dev *indio_dev,
			     struct iio_chan_spec const *chan,
			     const int **vals, int *type, int *length,
			     long info)
{
	struct ad4170_state *st = iio_priv(indio_dev);
	struct ad4170_chan_info *chan_info = &st->chan_infos[chan->address];
	enum ad4170_filter_type f_type;

	switch (info) {
	case IIO_CHAN_INFO_SCALE:
		*vals = (int *)chan_info->scale_tbl;
		*length = ARRAY_SIZE(chan_info->scale_tbl) * 2;
		*type = IIO_VAL_INT_PLUS_NANO;
		return IIO_AVAIL_LIST;
	case IIO_CHAN_INFO_SAMP_FREQ:
		*type = IIO_VAL_INT_PLUS_MICRO;
		f_type = ad4170_get_filter_type(indio_dev, chan);
		switch (f_type) {
		case AD4170_SINC5_AVG:
		case AD4170_SINC3:
			/* Read sps_tbl here to ensure in bounds array access */
			*vals = (int *)st->sps_tbl[f_type];
			*length = ARRAY_SIZE(ad4170_sinc3_filt_fs_tbl) * 2;
			return IIO_AVAIL_LIST;
		case AD4170_SINC5:
			/* Read sps_tbl here to ensure in bounds array access */
			*vals = (int *)st->sps_tbl[f_type];
			*length = ARRAY_SIZE(ad4170_sinc5_filt_fs_tbl) * 2;
			return IIO_AVAIL_LIST;
		default:
			return -EINVAL;
		}
	default:
		return -EINVAL;
	}
}

static int ad4170_set_pga(struct ad4170_state *st,
			  struct iio_chan_spec const *chan, int val, int val2)
{
	struct ad4170_chan_info *chan_info = &st->chan_infos[chan->address];
	struct ad4170_setup *setup = &chan_info->setup;
	unsigned int pga;

	for (pga = 0; pga < AD4170_NUM_PGA_OPTIONS; pga++) {
		if (val == chan_info->scale_tbl[pga][0] &&
		    val2 == chan_info->scale_tbl[pga][1])
			break;
	}

	if (pga == AD4170_NUM_PGA_OPTIONS)
		return -EINVAL;

	guard(mutex)(&st->lock);
	setup->afe &= ~AD4170_AFE_PGA_GAIN_MSK;
	setup->afe |= FIELD_PREP(AD4170_AFE_PGA_GAIN_MSK, pga);

	return ad4170_write_channel_setup(st, chan->address, false);
}

static int ad4170_set_channel_freq(struct ad4170_state *st,
				   struct iio_chan_spec const *chan, int val,
				   int val2)
{
	struct ad4170_chan_info *chan_info = &st->chan_infos[chan->address];
	struct ad4170_setup *setup = &chan_info->setup;
	enum ad4170_filter_type f_type = __ad4170_get_filter_type(setup->filter);
	unsigned int filt_fs_tbl_size, i;

	switch (f_type) {
	case AD4170_SINC5_AVG:
	case AD4170_SINC3:
		filt_fs_tbl_size = ARRAY_SIZE(ad4170_sinc3_filt_fs_tbl);
		break;
	case AD4170_SINC5:
		filt_fs_tbl_size = ARRAY_SIZE(ad4170_sinc5_filt_fs_tbl);
		break;
	}

	for (i = 0; i < filt_fs_tbl_size; i++) {
		if (st->sps_tbl[f_type][i][0] == val &&
		    st->sps_tbl[f_type][i][1] == val2)
			break;
	}
	if (i == filt_fs_tbl_size)
		return -EINVAL;

	guard(mutex)(&st->lock);
	if (f_type == AD4170_SINC5)
		setup->filter_fs = ad4170_sinc5_filt_fs_tbl[i];
	else
		setup->filter_fs = ad4170_sinc3_filt_fs_tbl[i];

	return ad4170_write_channel_setup(st, chan->address, false);
}

static int ad4170_set_calib_offset(struct ad4170_state *st,
				   struct iio_chan_spec const *chan, int val)
{
	struct ad4170_chan_info *chan_info = &st->chan_infos[chan->address];
	struct ad4170_setup *setup = &chan_info->setup;

	guard(mutex)(&st->lock);
	setup->offset = val;

	return ad4170_write_channel_setup(st, chan->address, false);
}

static int ad4170_set_calib_gain(struct ad4170_state *st,
				 struct iio_chan_spec const *chan, int val)
{
	struct ad4170_chan_info *chan_info = &st->chan_infos[chan->address];
	struct ad4170_setup *setup = &chan_info->setup;

	guard(mutex)(&st->lock);
	setup->gain = val;

	return ad4170_write_channel_setup(st, chan->address, false);
}

static int __ad4170_write_raw(struct iio_dev *indio_dev,
			      struct iio_chan_spec const *chan, int val,
			      int val2, long info)
{
	struct ad4170_state *st = iio_priv(indio_dev);

	switch (info) {
	case IIO_CHAN_INFO_SCALE:
		return ad4170_set_pga(st, chan, val, val2);
	case IIO_CHAN_INFO_SAMP_FREQ:
		return ad4170_set_channel_freq(st, chan, val, val2);
	case IIO_CHAN_INFO_CALIBBIAS:
		return ad4170_set_calib_offset(st, chan, val);
	case IIO_CHAN_INFO_CALIBSCALE:
		return ad4170_set_calib_gain(st, chan, val);
	default:
		return -EINVAL;
	}
}

static int ad4170_write_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan, int val,
			    int val2, long info)
{
	int ret;

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

	ret = __ad4170_write_raw(indio_dev, chan, val, val2, info);
	iio_device_release_direct(indio_dev);
	return ret;
}

static int ad4170_write_raw_get_fmt(struct iio_dev *indio_dev,
				    struct iio_chan_spec const *chan,
				    long info)
{
	switch (info) {
	case IIO_CHAN_INFO_SCALE:
		return IIO_VAL_INT_PLUS_NANO;
	case IIO_CHAN_INFO_SAMP_FREQ:
		return IIO_VAL_INT_PLUS_MICRO;
	case IIO_CHAN_INFO_CALIBBIAS:
	case IIO_CHAN_INFO_CALIBSCALE:
		return IIO_VAL_INT;
	default:
		return -EINVAL;
	}
}

static int ad4170_update_scan_mode(struct iio_dev *indio_dev,
				   const unsigned long *active_scan_mask)
{
	struct ad4170_state *st = iio_priv(indio_dev);
	unsigned int chan_index;
	int ret;

	iio_for_each_active_channel(indio_dev, chan_index) {
		ret = ad4170_set_channel_enable(st, chan_index, true);
		if (ret)
			return ret;
	}
	return 0;
}

static const struct iio_info ad4170_info = {
	.read_raw = ad4170_read_raw,
	.read_avail = ad4170_read_avail,
	.write_raw = ad4170_write_raw,
	.write_raw_get_fmt = ad4170_write_raw_get_fmt,
	.update_scan_mode = ad4170_update_scan_mode,
	.debugfs_reg_access = ad4170_debugfs_reg_access,
};

static int ad4170_soft_reset(struct ad4170_state *st)
{
	int ret;

	ret = regmap_write(st->regmap, AD4170_CONFIG_A_REG,
			   AD4170_SW_RESET_MSK);
	if (ret)
		return ret;

	/* AD4170-4 requires 1 ms between reset and any register access. */
	fsleep(1 * USEC_PER_MSEC);

	return 0;
}

static int ad4170_gpio_get(struct gpio_chip *gc, unsigned int offset)
{
	struct iio_dev *indio_dev = gpiochip_get_data(gc);
	struct ad4170_state *st = iio_priv(indio_dev);
	unsigned int val;
	int ret;

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

	ret = regmap_read(st->regmap, AD4170_GPIO_MODE_REG, &val);
	if (ret)
		goto err_release;

	/*
	 * If the GPIO is configured as an input, read the current value from
	 * AD4170_GPIO_INPUT_REG. Otherwise, read the input value from
	 * AD4170_GPIO_OUTPUT_REG.
	 */
	if (val & BIT(offset * 2))
		ret = regmap_read(st->regmap, AD4170_GPIO_INPUT_REG, &val);
	else
		ret = regmap_read(st->regmap, AD4170_GPIO_OUTPUT_REG, &val);
	if (ret)
		goto err_release;

	ret = !!(val & BIT(offset));
err_release:
	iio_device_release_direct(indio_dev);

	return ret;
}

static int ad4170_gpio_set(struct gpio_chip *gc, unsigned int offset, int value)
{
	struct iio_dev *indio_dev = gpiochip_get_data(gc);
	struct ad4170_state *st = iio_priv(indio_dev);
	int ret;

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

	ret = regmap_assign_bits(st->regmap, AD4170_GPIO_OUTPUT_REG,
				 BIT(offset), !!value);

	iio_device_release_direct(indio_dev);
	return ret;
}

static int ad4170_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
{
	struct iio_dev *indio_dev = gpiochip_get_data(gc);
	struct ad4170_state *st = iio_priv(indio_dev);
	unsigned int val;
	int ret;

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

	ret = regmap_read(st->regmap, AD4170_GPIO_MODE_REG, &val);
	if (ret)
		goto err_release;

	if (val & BIT(offset * 2 + 1))
		ret = GPIO_LINE_DIRECTION_OUT;
	else
		ret = GPIO_LINE_DIRECTION_IN;

err_release:
	iio_device_release_direct(indio_dev);

	return ret;
}

static int ad4170_gpio_direction_input(struct gpio_chip *gc, unsigned int offset)
{
	struct iio_dev *indio_dev = gpiochip_get_data(gc);
	struct ad4170_state *st = iio_priv(indio_dev);
	unsigned long gpio_mask;
	int ret;

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

	switch (offset) {
	case 0:
		gpio_mask = AD4170_GPIO_MODE_GPIO0_MSK;
		break;
	case 1:
		gpio_mask = AD4170_GPIO_MODE_GPIO1_MSK;
		break;
	case 2:
		gpio_mask = AD4170_GPIO_MODE_GPIO2_MSK;
		break;
	case 3:
		gpio_mask = AD4170_GPIO_MODE_GPIO3_MSK;
		break;
	default:
		ret = -EINVAL;
		goto err_release;
	}
	ret = regmap_update_bits(st->regmap, AD4170_GPIO_MODE_REG, gpio_mask,
				 AD4170_GPIO_MODE_GPIO_INPUT << (2 * offset));

err_release:
	iio_device_release_direct(indio_dev);

	return ret;
}

static int ad4170_gpio_direction_output(struct gpio_chip *gc,
					unsigned int offset, int value)
{
	struct iio_dev *indio_dev = gpiochip_get_data(gc);
	struct ad4170_state *st = iio_priv(indio_dev);
	unsigned long gpio_mask;
	int ret;

	ret = ad4170_gpio_set(gc, offset, value);
	if (ret)
		return ret;

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

	switch (offset) {
	case 0:
		gpio_mask = AD4170_GPIO_MODE_GPIO0_MSK;
		break;
	case 1:
		gpio_mask = AD4170_GPIO_MODE_GPIO1_MSK;
		break;
	case 2:
		gpio_mask = AD4170_GPIO_MODE_GPIO2_MSK;
		break;
	case 3:
		gpio_mask = AD4170_GPIO_MODE_GPIO3_MSK;
		break;
	default:
		ret = -EINVAL;
		goto err_release;
	}
	ret = regmap_update_bits(st->regmap, AD4170_GPIO_MODE_REG, gpio_mask,
				 AD4170_GPIO_MODE_GPIO_OUTPUT << (2 * offset));

err_release:
	iio_device_release_direct(indio_dev);

	return ret;
}

static int ad4170_gpio_init_valid_mask(struct gpio_chip *gc,
				       unsigned long *valid_mask,
				       unsigned int ngpios)
{
	struct ad4170_state *st = gpiochip_get_data(gc);
	unsigned int i;

	/* Only expose GPIOs that were not assigned any other function. */
	for (i = 0; i < ngpios; i++) {
		bool valid = st->gpio_fn[i] == AD4170_GPIO_UNASSIGNED;

		__assign_bit(i, valid_mask, valid);
	}

	return 0;
}

static int ad4170_gpio_init(struct iio_dev *indio_dev)
{
	struct ad4170_state *st = iio_priv(indio_dev);

	st->gpiochip.label = "ad4170_gpios";
	st->gpiochip.base = -1;
	st->gpiochip.ngpio = AD4170_NUM_GPIO_PINS;
	st->gpiochip.parent = &st->spi->dev;
	st->gpiochip.can_sleep = true;
	st->gpiochip.init_valid_mask = ad4170_gpio_init_valid_mask;
	st->gpiochip.get_direction = ad4170_gpio_get_direction;
	st->gpiochip.direction_input = ad4170_gpio_direction_input;
	st->gpiochip.direction_output = ad4170_gpio_direction_output;
	st->gpiochip.get = ad4170_gpio_get;
	st->gpiochip.set = ad4170_gpio_set;
	st->gpiochip.owner = THIS_MODULE;

	return devm_gpiochip_add_data(&st->spi->dev, &st->gpiochip, indio_dev);
}

static int ad4170_validate_excitation_pin(struct ad4170_state *st, u32 pin)
{
	struct device *dev = &st->spi->dev;
	unsigned int i;

	/* Check the pin number is valid */
	for (i = 0; i < ARRAY_SIZE(ad4170_iout_pin_tbl); i++)
		if (ad4170_iout_pin_tbl[i] == pin)
			break;

	if (i == ARRAY_SIZE(ad4170_iout_pin_tbl))
		return dev_err_probe(dev, -EINVAL,
				     "Invalid excitation pin: %u\n",
				     pin);

	/* Check the pin is available */
	if (pin <= AD4170_MAX_ANALOG_PINS) {
		if (st->pins_fn[pin] != AD4170_PIN_UNASSIGNED)
			return dev_err_probe(dev, -EINVAL,
					     "Pin %u already used with fn %u\n",
					     pin, st->pins_fn[pin]);

		st->pins_fn[pin] |= AD4170_PIN_CURRENT_OUT;
	} else {
		unsigned int gpio = pin - AD4170_CURRENT_SRC_I_OUT_PIN_GPIO(0);

		if (st->gpio_fn[gpio] != AD4170_GPIO_UNASSIGNED)
			return dev_err_probe(dev, -EINVAL,
					     "GPIO %u already used with fn %u\n",
					     gpio, st->gpio_fn[gpio]);

		st->gpio_fn[gpio] |= AD4170_GPIO_AC_EXCITATION;
	}

	return 0;
}

static int ad4170_validate_excitation_pins(struct ad4170_state *st,
					   u32 *exc_pins, int num_exc_pins)
{
	unsigned int i;
	int ret;

	for (i = 0; i < num_exc_pins; i++) {
		ret = ad4170_validate_excitation_pin(st, exc_pins[i]);
		if (ret)
			return ret;
	}
	return 0;
}

static const char *const ad4170_i_out_pin_dt_props[] = {
	"adi,excitation-pin-0",
	"adi,excitation-pin-1",
	"adi,excitation-pin-2",
	"adi,excitation-pin-3",
};

static const char *const ad4170_i_out_val_dt_props[] = {
	"adi,excitation-current-0-microamp",
	"adi,excitation-current-1-microamp",
	"adi,excitation-current-2-microamp",
	"adi,excitation-current-3-microamp",
};

/*
 * Parses firmware data describing output current source setup. There are 4
 * excitation currents (IOUT0 to IOUT3) that can be configured independently.
 * Excitation currents are added if they are output on the same pin.
 */
static int ad4170_parse_exc_current(struct ad4170_state *st,
				    struct fwnode_handle *child,
				    unsigned int *exc_pins,
				    unsigned int *exc_curs,
				    unsigned int *num_exc_pins)
{
	struct device *dev = &st->spi->dev;
	unsigned int num_pins, i, j;
	u32 pin, val;
	int ret;

	num_pins = 0;
	for (i = 0; i < AD4170_NUM_CURRENT_SRC; i++) {
		/* Parse excitation current output pin properties. */
		pin = AD4170_CURRENT_SRC_I_OUT_PIN_AIN(0);
		ret = fwnode_property_read_u32(child, ad4170_i_out_pin_dt_props[i],
					       &pin);
		if (ret)
			continue;

		exc_pins[num_pins] = pin;

		/* Parse excitation current value properties. */
		val = ad4170_iout_current_ua_tbl[0];
		fwnode_property_read_u32(child,
					 ad4170_i_out_val_dt_props[i], &val);

		for (j = 0; j < ARRAY_SIZE(ad4170_iout_current_ua_tbl); j++)
			if (ad4170_iout_current_ua_tbl[j] == val)
				break;

		if (j == ARRAY_SIZE(ad4170_iout_current_ua_tbl))
			return dev_err_probe(dev, -EINVAL, "Invalid %s: %uuA\n",
					     ad4170_i_out_val_dt_props[i], val);

		exc_curs[num_pins] = j;
		num_pins++;
	}
	*num_exc_pins = num_pins;

	return 0;
}

static int ad4170_setup_current_src(struct ad4170_state *st,
				    struct fwnode_handle *child,
				    struct ad4170_setup *setup, u32 *exc_pins,
				    unsigned int *exc_curs, int num_exc_pins,
				    bool ac_excited)
{
	unsigned int exc_cur_pair, i, j;
	int ret;

	for (i = 0; i < num_exc_pins; i++) {
		unsigned int exc_cur = exc_curs[i];
		unsigned int pin = exc_pins[i];
		unsigned int current_src = 0;

		for (j = 0; j < AD4170_NUM_CURRENT_SRC; j++)
			if (st->cur_src_pins[j] == AD4170_CURRENT_SRC_DISABLED)
				break;

		if (j == AD4170_NUM_CURRENT_SRC)
			return dev_err_probe(&st->spi->dev, -EINVAL,
					     "Too many excitation current sources\n");

		current_src |= FIELD_PREP(AD4170_CURRENT_SRC_I_OUT_PIN_MSK, pin);
		current_src |= FIELD_PREP(AD4170_CURRENT_SRC_I_OUT_VAL_MSK, exc_cur);
		st->cur_src_pins[j] = pin;
		ret = regmap_write(st->regmap, AD4170_CURRENT_SRC_REG(j),
				   current_src);
		if (ret)
			return ret;
	}

	if (!ac_excited)
		return 0;

	if (num_exc_pins < 2)
		return dev_err_probe(&st->spi->dev, -EINVAL,
			"Current chopping requested but only one pin provided: %u\n",
			exc_pins[0]);

	/*
	 * Two use cases to handle here:
	 * - 2 pairs of excitation currents;
	 * - 1 pair of excitation currents.
	 */
	if (num_exc_pins == 4) {
		for (i = 0; i < AD4170_NUM_CURRENT_SRC; i++)
			if (st->cur_src_pins[i] != exc_pins[i])
				return dev_err_probe(&st->spi->dev, -EINVAL,
						     "Unable to use 4 exc pins\n");
	} else {
		/*
		 * Excitation current chopping is configured in pairs. Current
		 * sources IOUT0 and IOUT1 form pair 1, IOUT2 and IOUT3 make up
		 * pair 2. So, if current chopping was requested, check if the
		 * first end of the first pair of excitation currents is
		 * available. Try the next pair if IOUT0 has already been
		 * configured for another channel.
		 */
		i = st->cur_src_pins[0] == exc_pins[0] ? 0 : 2;

		if (st->cur_src_pins[i] != exc_pins[0] ||
		    st->cur_src_pins[i + 1] != exc_pins[1])
			return dev_err_probe(&st->spi->dev, -EINVAL,
					     "Failed to setup current chopping\n");

		st->cur_src_pins[i] = exc_pins[0];
		st->cur_src_pins[i + 1] = exc_pins[1];

		if (i == 0)
			exc_cur_pair = AD4170_MISC_CHOP_IEXC_PAIR1;
		else
			exc_cur_pair = AD4170_MISC_CHOP_IEXC_PAIR2;
	}

	/*
	 * Configure excitation current chopping.
	 * Chop both pairs if using four excitation pins.
	 */
	setup->misc |= FIELD_PREP(AD4170_MISC_CHOP_IEXC_MSK,
				  num_exc_pins == 2 ?
				  exc_cur_pair :
				  AD4170_MISC_CHOP_IEXC_BOTH);

	return 0;
}

static int ad4170_setup_bridge(struct ad4170_state *st,
			       struct fwnode_handle *child,
			       struct ad4170_setup *setup, u32 *exc_pins,
			       unsigned int *exc_curs, int num_exc_pins,
			       bool ac_excited)
{
	unsigned long gpio_mask;
	unsigned int i;
	int ret;

	/*
	 * If a specific current is provided through
	 * adi,excitation-current-n-microamp, set excitation pins provided
	 * through adi,excitation-pin-n to excite the bridge circuit.
	 */
	for (i = 0; i < num_exc_pins; i++)
		if (exc_curs[i] > 0)
			return ad4170_setup_current_src(st, child, setup, exc_pins,
							exc_curs, num_exc_pins,
							ac_excited);

	/*
	 * Else, use predefined ACX1, ACX1 negated, ACX2, ACX2 negated signals
	 * to AC excite the bridge. Those signals are output on GPIO2, GPIO0,
	 * GPIO3, and GPIO1, respectively. If only two pins are specified for AC
	 * excitation, use ACX1 and ACX2 (GPIO2 and GPIO3).
	 *
	 * Also, to avoid any short-circuit condition when more than one channel
	 * is enabled, set GPIO2 and GPIO0 high, and set GPIO1 and GPIO3 low to
	 * DC excite the bridge whenever a channel without AC excitation is
	 * selected. That is needed because GPIO pins are controlled by the next
	 * highest priority GPIO function when a channel doesn't enable AC
	 * excitation. See datasheet Figure 113 Weigh Scale (AC Excitation) for
	 * the reference circuit diagram.
	 */
	if (num_exc_pins == 2) {
		setup->misc |= FIELD_PREP(AD4170_MISC_CHOP_ADC_MSK, 0x3);

		gpio_mask = AD4170_GPIO_MODE_GPIO3_MSK | AD4170_GPIO_MODE_GPIO2_MSK;
		ret = regmap_update_bits(st->regmap, AD4170_GPIO_MODE_REG, gpio_mask,
					 FIELD_PREP(AD4170_GPIO_MODE_GPIO3_MSK,
						    AD4170_GPIO_MODE_GPIO_OUTPUT) |
					 FIELD_PREP(AD4170_GPIO_MODE_GPIO2_MSK,
						    AD4170_GPIO_MODE_GPIO_OUTPUT));
		if (ret)
			return ret;

		/*
		 * Set GPIO2 high and GPIO3 low to DC excite the bridge when
		 * a different channel is selected.
		 */
		gpio_mask = AD4170_GPIO_OUTPUT_GPIO_MSK(3) |
			    AD4170_GPIO_OUTPUT_GPIO_MSK(2);
		ret = regmap_update_bits(st->regmap, AD4170_GPIO_OUTPUT_REG, gpio_mask,
					 FIELD_PREP(AD4170_GPIO_OUTPUT_GPIO_MSK(3), 0) |
					 FIELD_PREP(AD4170_GPIO_OUTPUT_GPIO_MSK(2), 1));
		if (ret)
			return ret;

		st->gpio_fn[3] |= AD4170_GPIO_OUTPUT;
		st->gpio_fn[2] |= AD4170_GPIO_OUTPUT;
	} else {
		setup->misc |= FIELD_PREP(AD4170_MISC_CHOP_ADC_MSK, 0x2);

		gpio_mask = AD4170_GPIO_MODE_GPIO3_MSK | AD4170_GPIO_MODE_GPIO2_MSK |
			    AD4170_GPIO_MODE_GPIO1_MSK | AD4170_GPIO_MODE_GPIO0_MSK;
		ret = regmap_update_bits(st->regmap, AD4170_GPIO_MODE_REG, gpio_mask,
					 FIELD_PREP(AD4170_GPIO_MODE_GPIO3_MSK,
						    AD4170_GPIO_MODE_GPIO_OUTPUT) |
					 FIELD_PREP(AD4170_GPIO_MODE_GPIO2_MSK,
						    AD4170_GPIO_MODE_GPIO_OUTPUT) |
					 FIELD_PREP(AD4170_GPIO_MODE_GPIO1_MSK,
						    AD4170_GPIO_MODE_GPIO_OUTPUT) |
					 FIELD_PREP(AD4170_GPIO_MODE_GPIO0_MSK,
						    AD4170_GPIO_MODE_GPIO_OUTPUT));
		if (ret)
			return ret;

		/*
		 * Set GPIO2 and GPIO0 high, and set GPIO1 and GPIO3 low to DC
		 * excite the bridge when a different channel is selected.
		 */
		gpio_mask = AD4170_GPIO_OUTPUT_GPIO_MSK(3) |
			    AD4170_GPIO_OUTPUT_GPIO_MSK(2) |
			    AD4170_GPIO_OUTPUT_GPIO_MSK(1) |
			    AD4170_GPIO_OUTPUT_GPIO_MSK(0);
		ret = regmap_update_bits(st->regmap, AD4170_GPIO_OUTPUT_REG, gpio_mask,
					 FIELD_PREP(AD4170_GPIO_OUTPUT_GPIO_MSK(3), 0) |
					 FIELD_PREP(AD4170_GPIO_OUTPUT_GPIO_MSK(2), 1) |
					 FIELD_PREP(AD4170_GPIO_OUTPUT_GPIO_MSK(1), 0) |
					 FIELD_PREP(AD4170_GPIO_OUTPUT_GPIO_MSK(0), 1));
		if (ret)
			return ret;

		st->gpio_fn[3] |= AD4170_GPIO_OUTPUT;
		st->gpio_fn[2] |= AD4170_GPIO_OUTPUT;
		st->gpio_fn[1] |= AD4170_GPIO_OUTPUT;
		st->gpio_fn[0] |= AD4170_GPIO_OUTPUT;
	}

	return 0;
}

static int ad4170_setup_rtd(struct ad4170_state *st,
			    struct fwnode_handle *child,
			    struct ad4170_setup *setup, u32 *exc_pins,
			    unsigned int *exc_curs, int num_exc_pins, bool ac_excited)
{
	return ad4170_setup_current_src(st, child, setup, exc_pins,
					exc_curs, num_exc_pins, ac_excited);
}

static int ad4170_parse_external_sensor(struct ad4170_state *st,
					struct fwnode_handle *child,
					struct ad4170_setup *setup,
					struct iio_chan_spec *chan,
					unsigned int s_type)
{
	unsigned int num_exc_pins, reg_val;
	struct device *dev = &st->spi->dev;
	u32 pins[2], exc_pins[4], exc_curs[4];
	bool ac_excited;
	int ret;

	ret = fwnode_property_read_u32_array(child, "diff-channels", pins,
					     ARRAY_SIZE(pins));
	if (ret)
		return dev_err_probe(dev, ret,
				     "Failed to read sensor diff-channels\n");

	chan->differential = true;
	chan->channel = pins[0];
	chan->channel2 = pins[1];

	ret = ad4170_parse_exc_current(st, child, exc_pins, exc_curs, &num_exc_pins);
	if (ret)
		return ret;

	/* The external sensor may not need excitation from the ADC chip. */
	if (num_exc_pins == 0)
		return 0;

	ret = ad4170_validate_excitation_pins(st, exc_pins, num_exc_pins);
	if (ret)
		return ret;

	ac_excited = fwnode_property_read_bool(child, "adi,excitation-ac");

	if (s_type == AD4170_THERMOCOUPLE_SENSOR) {
		if (st->pins_fn[chan->channel2] & AD4170_PIN_VBIAS) {
			reg_val = BIT(chan->channel2);
			ret = regmap_write(st->regmap, AD4170_V_BIAS_REG, reg_val);
			if (ret)
				dev_err_probe(dev, ret, "Failed to set vbias\n");
		}
	}
	if (s_type == AD4170_WEIGH_SCALE_SENSOR)
		ret = ad4170_setup_bridge(st, child, setup, exc_pins, exc_curs,
					  num_exc_pins, ac_excited);
	else
		ret = ad4170_setup_rtd(st, child, setup, exc_pins, exc_curs,
				       num_exc_pins, ac_excited);

	return ret;
}

static int ad4170_parse_reference(struct ad4170_state *st,
				  struct fwnode_handle *child,
				  struct ad4170_setup *setup)
{
	struct device *dev = &st->spi->dev;
	const char *propname;
	u32 aux;
	int ret;

	/* Optional positive reference buffering */
	propname = "adi,positive-reference-buffer";
	ret = device_property_match_property_string(dev, propname,
						    ad4170_ref_buf_str,
						    ARRAY_SIZE(ad4170_ref_buf_str));

	/* Default to full precharge buffer enabled. */
	setup->afe |= FIELD_PREP(AD4170_AFE_REF_BUF_P_MSK,
				 ret >= 0 ? ret : AD4170_REF_BUF_FULL);

	/* Optional negative reference buffering */
	propname = "adi,negative-reference-buffer";
	ret = device_property_match_property_string(dev, propname,
						    ad4170_ref_buf_str,
						    ARRAY_SIZE(ad4170_ref_buf_str));

	/* Default to full precharge buffer enabled. */
	setup->afe |= FIELD_PREP(AD4170_AFE_REF_BUF_M_MSK,
				 ret >= 0 ? ret : AD4170_REF_BUF_FULL);

	/* Optional voltage reference selection */
	propname = "adi,reference-select";
	aux = AD4170_REF_REFOUT; /* Default reference selection. */
	fwnode_property_read_u32(child, propname, &aux);
	if (aux > AD4170_REF_AVDD)
		return dev_err_probe(dev, -EINVAL, "Invalid %s: %u\n",
				     propname, aux);

	setup->afe |= FIELD_PREP(AD4170_AFE_REF_SELECT_MSK, aux);

	return 0;
}

static int ad4170_parse_adc_channel_type(struct device *dev,
					 struct fwnode_handle *child,
					 struct iio_chan_spec *chan)
{
	const char *propname, *propname2;
	int ret, ret2;
	u32 pins[2];

	propname = "single-channel";
	propname2 = "diff-channels";
	if (!fwnode_property_present(child, propname) &&
	    !fwnode_property_present(child, propname2))
		return dev_err_probe(dev, -EINVAL,
				     "Channel must define one of %s or %s.\n",
				     propname, propname2);

	/* Parse differential channel configuration */
	ret = fwnode_property_read_u32_array(child, propname2, pins,
					     ARRAY_SIZE(pins));
	if (!ret) {
		chan->differential = true;
		chan->channel = pins[0];
		chan->channel2 = pins[1];
		return 0;
	}
	/* Failed to parse diff chan so try pseudo-diff chan props */

	propname2 = "common-mode-channel";
	if (fwnode_property_present(child, propname) &&
	    !fwnode_property_present(child, propname2))
		return dev_err_probe(dev, -EINVAL,
				     "When %s is defined, %s must be defined too\n",
				     propname, propname2);

	/* Parse pseudo-differential channel configuration */
	ret = fwnode_property_read_u32(child, propname, &pins[0]);
	ret2 = fwnode_property_read_u32(child, propname2, &pins[1]);

	if (!ret && !ret2) {
		chan->differential = false;
		chan->channel = pins[0];
		chan->channel2 = pins[1];
		return 0;
	}
	return dev_err_probe(dev, -EINVAL,
			     "Failed to parse channel %lu input. %d, %d\n",
			     chan->address, ret, ret2);
}

static int ad4170_parse_channel_node(struct iio_dev *indio_dev,
				     struct fwnode_handle *child,
				     unsigned int chan_num)
{
	struct ad4170_state *st = iio_priv(indio_dev);
	unsigned int s_type = AD4170_ADC_SENSOR;
	struct device *dev = &st->spi->dev;
	struct ad4170_chan_info *chan_info;
	struct ad4170_setup *setup;
	struct iio_chan_spec *chan;
	unsigned int ref_select;
	unsigned int ch_reg;
	bool bipolar;
	int ret;

	ret = fwnode_property_read_u32(child, "reg", &ch_reg);
	if (ret)
		return dev_err_probe(dev, ret, "Failed to read channel reg\n");

	if (ch_reg >= AD4170_MAX_ADC_CHANNELS)
		return dev_err_probe(dev, -EINVAL,
				     "Channel idx greater than no of channels\n");

	chan = &st->chans[chan_num];
	*chan = ad4170_channel_template;

	chan->address = ch_reg;
	chan->scan_index = ch_reg;
	chan_info = &st->chan_infos[chan->address];

	chan_info->setup_num = AD4170_INVALID_SETUP;
	chan_info->initialized = true;

	setup = &chan_info->setup;
	ret = ad4170_parse_reference(st, child, setup);
	if (ret)
		return ret;

	ret = fwnode_property_match_property_string(child, "adi,sensor-type",
						    ad4170_sensor_type,
						    ARRAY_SIZE(ad4170_sensor_type));

	/* Default to conventional ADC channel if sensor type not present */
	s_type = ret < 0 ? AD4170_ADC_SENSOR : ret;
	switch (s_type) {
	case AD4170_ADC_SENSOR:
		ret = ad4170_parse_adc_channel_type(dev, child, chan);
		if (ret)
			return ret;

		break;
	case AD4170_WEIGH_SCALE_SENSOR:
	case AD4170_THERMOCOUPLE_SENSOR:
	case AD4170_RTD_SENSOR:
		ret = ad4170_parse_external_sensor(st, child, setup, chan, s_type);
		if (ret)
			return ret;

		break;
	default:
		return -EINVAL;
	}

	bipolar = fwnode_property_read_bool(child, "bipolar");
	setup->afe |= FIELD_PREP(AD4170_AFE_BIPOLAR_MSK, bipolar);
	if (bipolar)
		chan->scan_type.sign = 's';
	else
		chan->scan_type.sign = 'u';

	ret = ad4170_validate_channel(st, chan);
	if (ret)
		return ret;

	ref_select = FIELD_GET(AD4170_AFE_REF_SELECT_MSK, setup->afe);
	ret = ad4170_get_input_range(st, chan, ch_reg, ref_select);
	if (ret < 0)
		return dev_err_probe(dev, ret, "Invalid input config\n");

	chan_info->input_range_uv = ret;
	return 0;
}

static int ad4170_parse_channels(struct iio_dev *indio_dev)
{
	struct ad4170_state *st = iio_priv(indio_dev);
	struct device *dev = &st->spi->dev;
	unsigned int num_channels;
	unsigned int chan_num;
	int ret;

	num_channels = device_get_child_node_count(dev);

	if (num_channels > AD4170_MAX_ADC_CHANNELS)
		return dev_err_probe(dev, -EINVAL, "Too many channels\n");

	/* Add one for temperature */
	num_channels = min(num_channels + 1, AD4170_MAX_ADC_CHANNELS);

	chan_num = 0;
	device_for_each_child_node_scoped(dev, child) {
		ret = ad4170_parse_channel_node(indio_dev, child, chan_num++);
		if (ret)
			return ret;
	}

	/*
	 * Add internal temperature sensor channel if the maximum number of
	 * channels has not been reached.
	 */
	if (num_channels < AD4170_MAX_ADC_CHANNELS) {
		struct ad4170_setup *setup = &st->chan_infos[chan_num].setup;

		st->chans[chan_num] = ad4170_temp_channel_template;
		st->chans[chan_num].address = chan_num;
		st->chans[chan_num].scan_index = chan_num;

		st->chan_infos[chan_num].setup_num = AD4170_INVALID_SETUP;
		st->chan_infos[chan_num].initialized = true;

		setup->afe |= FIELD_PREP(AD4170_AFE_REF_SELECT_MSK,
					 AD4170_REF_AVDD);

		ret = ad4170_get_input_range(st, &st->chans[chan_num], chan_num,
					     AD4170_REF_AVDD);
		if (ret < 0)
			return dev_err_probe(dev, ret, "Invalid input config\n");

		st->chan_infos[chan_num].input_range_uv = ret;
		chan_num++;
	}

	/* Add timestamp channel */
	struct iio_chan_spec ts_chan = IIO_CHAN_SOFT_TIMESTAMP(chan_num);

	st->chans[chan_num] = ts_chan;
	num_channels = num_channels + 1;

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

	return 0;
}

static struct ad4170_state *clk_hw_to_ad4170(struct clk_hw *hw)
{
	return container_of(hw, struct ad4170_state, int_clk_hw);
}

static unsigned long ad4170_sel_clk(struct ad4170_state *st,
				    unsigned int clk_sel)
{
	st->clock_ctrl &= ~AD4170_CLOCK_CTRL_CLOCKSEL_MSK;
	st->clock_ctrl |= FIELD_PREP(AD4170_CLOCK_CTRL_CLOCKSEL_MSK, clk_sel);
	return regmap_write(st->regmap, AD4170_CLOCK_CTRL_REG, st->clock_ctrl);
}

static unsigned long ad4170_clk_recalc_rate(struct clk_hw *hw,
					    unsigned long parent_rate)
{
	return AD4170_INT_CLOCK_16MHZ;
}

static int ad4170_clk_output_is_enabled(struct clk_hw *hw)
{
	struct ad4170_state *st = clk_hw_to_ad4170(hw);
	u32 clk_sel;

	clk_sel = FIELD_GET(AD4170_CLOCK_CTRL_CLOCKSEL_MSK, st->clock_ctrl);
	return clk_sel == AD4170_CLOCK_CTRL_CLOCKSEL_INT_OUT;
}

static int ad4170_clk_output_prepare(struct clk_hw *hw)
{
	struct ad4170_state *st = clk_hw_to_ad4170(hw);

	return ad4170_sel_clk(st, AD4170_CLOCK_CTRL_CLOCKSEL_INT_OUT);
}

static void ad4170_clk_output_unprepare(struct clk_hw *hw)
{
	struct ad4170_state *st = clk_hw_to_ad4170(hw);

	ad4170_sel_clk(st, AD4170_CLOCK_CTRL_CLOCKSEL_INT);
}

static const struct clk_ops ad4170_int_clk_ops = {
	.recalc_rate = ad4170_clk_recalc_rate,
	.is_enabled = ad4170_clk_output_is_enabled,
	.prepare = ad4170_clk_output_prepare,
	.unprepare = ad4170_clk_output_unprepare,
};

static int ad4170_register_clk_provider(struct iio_dev *indio_dev)
{
	struct ad4170_state *st = iio_priv(indio_dev);
	struct device *dev = indio_dev->dev.parent;
	struct clk_init_data init = {};
	int ret;

	if (device_property_read_string(dev, "clock-output-names", &init.name)) {
		init.name = devm_kasprintf(dev, GFP_KERNEL, "%pfw",
					   dev_fwnode(dev));
		if (!init.name)
			return -ENOMEM;
	}

	init.ops = &ad4170_int_clk_ops;

	st->int_clk_hw.init = &init;
	ret = devm_clk_hw_register(dev, &st->int_clk_hw);
	if (ret)
		return ret;

	return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
					   &st->int_clk_hw);
}

static int ad4170_clock_select(struct iio_dev *indio_dev)
{
	struct ad4170_state *st = iio_priv(indio_dev);
	struct device *dev = &st->spi->dev;
	struct clk *ext_clk;
	int ret;

	ext_clk = devm_clk_get_optional_enabled(dev, NULL);
	if (IS_ERR(ext_clk))
		return dev_err_probe(dev, PTR_ERR(ext_clk),
				     "Failed to get external clock\n");

	if (!ext_clk) {
		/* Use internal clock reference */
		st->mclk_hz = AD4170_INT_CLOCK_16MHZ;
		st->clock_ctrl |= FIELD_PREP(AD4170_CLOCK_CTRL_CLOCKSEL_MSK,
					     AD4170_CLOCK_CTRL_CLOCKSEL_INT_OUT);

		if (!device_property_present(&st->spi->dev, "#clock-cells"))
			return 0;

		return ad4170_register_clk_provider(indio_dev);
	}

	/* Read optional clock-names prop to specify the external clock type */
	ret = device_property_match_property_string(dev, "clock-names",
						    ad4170_clk_sel,
						    ARRAY_SIZE(ad4170_clk_sel));

	ret = ret < 0 ? 0 : ret; /* Default to external clock if no clock-names */
	st->clock_ctrl |= FIELD_PREP(AD4170_CLOCK_CTRL_CLOCKSEL_MSK,
				     AD4170_CLOCK_CTRL_CLOCKSEL_EXT + ret);

	st->mclk_hz = clk_get_rate(ext_clk);
	if (st->mclk_hz < AD4170_EXT_CLOCK_MHZ_MIN ||
	    st->mclk_hz > AD4170_EXT_CLOCK_MHZ_MAX) {
		return dev_err_probe(dev, -EINVAL,
				     "Invalid external clock frequency %u\n",
				     st->mclk_hz);
	}

	return 0;
}

static int ad4170_parse_firmware(struct iio_dev *indio_dev)
{
	unsigned int vbias_pins[AD4170_MAX_ANALOG_PINS];
	struct ad4170_state *st = iio_priv(indio_dev);
	struct device *dev = &st->spi->dev;
	unsigned int num_vbias_pins;
	int reg_data, ret;
	u32 int_pin_sel;
	unsigned int i;

	ret = ad4170_clock_select(indio_dev);
	if (ret)
		return dev_err_probe(dev, ret, "Failed to setup device clock\n");

	ret = regmap_write(st->regmap, AD4170_CLOCK_CTRL_REG, st->clock_ctrl);
	if (ret)
		return ret;

	for (i = 0; i < AD4170_NUM_CURRENT_SRC; i++)
		st->cur_src_pins[i] = AD4170_CURRENT_SRC_DISABLED;

	/* On power on, device defaults to using SDO pin for data ready signal */
	int_pin_sel = AD4170_INT_PIN_SDO;
	ret = device_property_match_property_string(dev, "interrupt-names",
						    ad4170_int_pin_names,
						    ARRAY_SIZE(ad4170_int_pin_names));
	if (ret >= 0)
		int_pin_sel = ret;

	reg_data = FIELD_PREP(AD4170_PIN_MUXING_DIG_AUX1_CTRL_MSK,
			      int_pin_sel == AD4170_INT_PIN_DIG_AUX1 ?
			      AD4170_PIN_MUXING_DIG_AUX1_RDY :
			      AD4170_PIN_MUXING_DIG_AUX1_DISABLED);

	ret = regmap_update_bits(st->regmap, AD4170_PIN_MUXING_REG,
				 AD4170_PIN_MUXING_DIG_AUX1_CTRL_MSK, reg_data);
	if (ret)
		return ret;

	ret = device_property_count_u32(dev, "adi,vbias-pins");
	if (ret > 0) {
		if (ret > AD4170_MAX_ANALOG_PINS)
			return dev_err_probe(dev, -EINVAL,
					     "Too many vbias pins %u\n", ret);

		num_vbias_pins = ret;

		ret = device_property_read_u32_array(dev, "adi,vbias-pins",
						     vbias_pins,
						     num_vbias_pins);
		if (ret)
			return dev_err_probe(dev, ret,
					     "Failed to read vbias pins\n");

		for (i = 0; i < num_vbias_pins; i++)
			st->pins_fn[vbias_pins[i]] |= AD4170_PIN_VBIAS;
	}

	ret = ad4170_parse_channels(indio_dev);
	if (ret)
		return ret;

	/* Only create a GPIO chip if flagged for it */
	if (device_property_read_bool(dev, "gpio-controller")) {
		ret = ad4170_gpio_init(indio_dev);
		if (ret)
			return ret;
	}

	return 0;
}

static int ad4170_initial_config(struct iio_dev *indio_dev)
{
	struct ad4170_state *st = iio_priv(indio_dev);
	struct device *dev = &st->spi->dev;
	unsigned int i;
	int ret;

	ad4170_fill_sps_tbl(st);

	ret = regmap_update_bits(st->regmap, AD4170_ADC_CTRL_REG,
				 AD4170_ADC_CTRL_MODE_MSK,
				 FIELD_PREP(AD4170_ADC_CTRL_MODE_MSK,
					    AD4170_ADC_CTRL_MODE_IDLE));
	if (ret)
		return dev_err_probe(dev, ret,
				     "Failed to set ADC mode to idle\n");

	for (i = 0; i < indio_dev->num_channels; i++) {
		struct ad4170_chan_info *chan_info;
		struct iio_chan_spec const *chan;
		struct ad4170_setup *setup;
		unsigned int val;

		chan = &indio_dev->channels[i];
		if (chan->type == IIO_TIMESTAMP)
			continue;

		chan_info = &st->chan_infos[chan->address];

		setup = &chan_info->setup;
		setup->gain = AD4170_GAIN_REG_DEFAULT;
		ret = ad4170_write_channel_setup(st, chan->address, false);
		if (ret)
			return dev_err_probe(dev, ret,
					     "Failed to write channel setup\n");

		val = FIELD_PREP(AD4170_CHAN_MAP_AINP_MSK, chan->channel) |
		      FIELD_PREP(AD4170_CHAN_MAP_AINM_MSK, chan->channel2);

		ret = regmap_write(st->regmap, AD4170_CHAN_MAP_REG(i), val);
		if (ret)
			return dev_err_probe(dev, ret,
					     "Failed to write CHAN_MAP_REG\n");

		ret = ad4170_set_channel_freq(st, chan,
					      AD4170_DEFAULT_SAMP_RATE, 0);
		if (ret)
			return dev_err_probe(dev, ret,
					     "Failed to set channel freq\n");

		ret = ad4170_fill_scale_tbl(indio_dev, chan);
		if (ret)
			return dev_err_probe(dev, ret,
					     "Failed to fill scale tbl\n");
	}

	/* Disable all channels to avoid reading from unexpected channel */
	ret = regmap_write(st->regmap, AD4170_CHAN_EN_REG, 0);
	if (ret)
		return dev_err_probe(dev, ret,
				     "Failed to disable channels\n");

	/*
	 * Configure channels to share the same data output register, i.e. data
	 * can be read from the same register address regardless of channel
	 * number.
	 */
	return regmap_update_bits(st->regmap, AD4170_ADC_CTRL_REG,
				 AD4170_ADC_CTRL_MULTI_DATA_REG_SEL_MSK,
				 AD4170_ADC_CTRL_MULTI_DATA_REG_SEL_MSK);
}

static int ad4170_prepare_spi_message(struct ad4170_state *st)
{
	/*
	 * Continuous data register read is enabled on buffer postenable so
	 * no instruction phase is needed meaning we don't need to send the
	 * register address to read data. Transfer only needs the read buffer.
	 */
	st->xfer.rx_buf = &st->rx_buf;
	st->xfer.len = BITS_TO_BYTES(ad4170_channel_template.scan_type.realbits);

	spi_message_init_with_transfers(&st->msg, &st->xfer, 1);

	return devm_spi_optimize_message(&st->spi->dev, st->spi, &st->msg);
}

static int ad4170_buffer_postenable(struct iio_dev *indio_dev)
{
	struct ad4170_state *st = iio_priv(indio_dev);
	int ret;

	ret = regmap_update_bits(st->regmap, AD4170_ADC_CTRL_REG,
				 AD4170_ADC_CTRL_MODE_MSK,
				 FIELD_PREP(AD4170_ADC_CTRL_MODE_MSK,
					    AD4170_ADC_CTRL_MODE_CONT));
	if (ret)
		return ret;

	/*
	 * This enables continuous read of the ADC data register. The ADC must
	 * be in continuous conversion mode.
	 */
	return regmap_update_bits(st->regmap, AD4170_ADC_CTRL_REG,
				  AD4170_ADC_CTRL_CONT_READ_MSK,
				  FIELD_PREP(AD4170_ADC_CTRL_CONT_READ_MSK,
					     AD4170_ADC_CTRL_CONT_READ_ENABLE));
}

static int ad4170_buffer_predisable(struct iio_dev *indio_dev)
{
	struct ad4170_state *st = iio_priv(indio_dev);
	unsigned int i;
	int ret;

	/*
	 * Use a high register address (virtual register) to request a write of
	 * 0xA5 to the ADC during the first 8 SCLKs of the ADC data read cycle,
	 * thus exiting continuous read.
	 */
	ret = regmap_write(st->regmap, AD4170_ADC_CTRL_CONT_READ_EXIT_REG, 0);
	if (ret)
		return ret;

	ret = regmap_update_bits(st->regmap, AD4170_ADC_CTRL_REG,
				 AD4170_ADC_CTRL_CONT_READ_MSK,
				 FIELD_PREP(AD4170_ADC_CTRL_CONT_READ_MSK,
					    AD4170_ADC_CTRL_CONT_READ_DISABLE));
	if (ret)
		return ret;

	ret = regmap_update_bits(st->regmap, AD4170_ADC_CTRL_REG,
				 AD4170_ADC_CTRL_MODE_MSK,
				 FIELD_PREP(AD4170_ADC_CTRL_MODE_MSK,
					    AD4170_ADC_CTRL_MODE_IDLE));
	if (ret)
		return ret;

	/*
	 * The ADC sequences through all the enabled channels (see datasheet
	 * page 95). That can lead to incorrect channel being read if a
	 * single-shot read (or buffered read with different active_scan_mask)
	 * is done after buffer disable. Disable all channels so only requested
	 * channels will be read.
	 */
	for (i = 0; i < indio_dev->num_channels; i++) {
		if (indio_dev->channels[i].type == IIO_TIMESTAMP)
			continue;

		ret = ad4170_set_channel_enable(st, i, false);
		if (ret)
			return ret;
	}

	return 0;
}

static bool ad4170_validate_scan_mask(struct iio_dev *indio_dev,
				      const unsigned long *scan_mask)
{
	unsigned int masklength = iio_get_masklength(indio_dev);
	unsigned int enabled;

	/*
	 * The channel sequencer cycles through the enabled channels in
	 * sequential order, from channel 0 to channel 15, bypassing disabled
	 * channels. When more than one channel is enabled, channel 0 must
	 * always be enabled. See datasheet channel_en register description at
	 * page 95.
	 */
	enabled = bitmap_weight(scan_mask, masklength);
	if (enabled > 1)
		return test_bit(0, scan_mask);

	return enabled == 1;
}

static const struct iio_buffer_setup_ops ad4170_buffer_ops = {
	.postenable = ad4170_buffer_postenable,
	.predisable = ad4170_buffer_predisable,
	.validate_scan_mask = ad4170_validate_scan_mask,
};

static irqreturn_t ad4170_trigger_handler(int irq, void *p)
{
	struct iio_poll_func *pf = p;
	struct iio_dev *indio_dev = pf->indio_dev;
	struct ad4170_state *st = iio_priv(indio_dev);
	unsigned int chan_index;
	unsigned int i = 0;
	int ret;

	iio_for_each_active_channel(indio_dev, chan_index) {
		ret = spi_sync(st->spi, &st->msg);
		if (ret)
			goto err_out;

		memcpy(&st->bounce_buffer[i++], st->rx_buf, ARRAY_SIZE(st->rx_buf));
	}

	iio_push_to_buffers_with_ts(indio_dev, st->bounce_buffer,
				    sizeof(st->bounce_buffer),
				    iio_get_time_ns(indio_dev));
err_out:
	iio_trigger_notify_done(indio_dev->trig);
	return IRQ_HANDLED;
}

static const struct iio_trigger_ops ad4170_trigger_ops = {
	.validate_device = iio_trigger_validate_own_device,
};

static irqreturn_t ad4170_irq_handler(int irq, void *dev_id)
{
	struct iio_dev *indio_dev = dev_id;
	struct ad4170_state *st = iio_priv(indio_dev);

	if (iio_buffer_enabled(indio_dev))
		iio_trigger_poll(st->trig);
	else
		complete(&st->completion);

	return IRQ_HANDLED;
};

static int ad4170_trigger_setup(struct iio_dev *indio_dev)
{
	struct ad4170_state *st = iio_priv(indio_dev);
	struct device *dev = &st->spi->dev;
	int ret;

	st->trig = devm_iio_trigger_alloc(dev, "%s-trig%d",
					  indio_dev->name,
					  iio_device_id(indio_dev));
	if (!st->trig)
		return -ENOMEM;

	st->trig->ops = &ad4170_trigger_ops;

	iio_trigger_set_drvdata(st->trig, indio_dev);
	ret = devm_iio_trigger_register(dev, st->trig);
	if (ret)
		return dev_err_probe(dev, ret, "Failed to register trigger\n");

	indio_dev->trig = iio_trigger_get(st->trig);

	return 0;
}

static int ad4170_regulator_setup(struct ad4170_state *st)
{
	struct device *dev = &st->spi->dev;
	int ret;

	/* Required regulators */
	ret = devm_regulator_get_enable_read_voltage(dev, "avdd");
	if (ret < 0)
		return dev_err_probe(dev, ret, "Failed to get AVDD voltage.\n");

	st->vrefs_uv[AD4170_AVDD_SUP] = ret;

	ret = devm_regulator_get_enable_read_voltage(dev, "iovdd");
	if (ret < 0)
		return dev_err_probe(dev, ret, "Failed to get IOVDD voltage.\n");

	st->vrefs_uv[AD4170_IOVDD_SUP] = ret;

	/* Optional regulators */
	ret = devm_regulator_get_enable_read_voltage(dev, "avss");
	if (ret < 0 && ret != -ENODEV)
		return dev_err_probe(dev, ret, "Failed to get AVSS voltage.\n");

	/*
	 * Assume AVSS at GND (0V) if not provided.
	 * REVISIT: AVSS is never above system ground level (i.e. AVSS is either
	 * GND or a negative voltage). But we currently don't have support for
	 * reading negative voltages with the regulator framework. So, the
	 * current AD4170 support reads a positive value from the regulator,
	 * then inverts sign to make that negative.
	 */
	st->vrefs_uv[AD4170_AVSS_SUP] = ret == -ENODEV ? 0 : -ret;

	ret = devm_regulator_get_enable_read_voltage(dev, "refin1p");
	if (ret < 0 && ret != -ENODEV)
		return dev_err_probe(dev, ret, "Failed to get REFIN+ voltage.\n");

	st->vrefs_uv[AD4170_REFIN1P_SUP] = ret;

	ret = devm_regulator_get_enable_read_voltage(dev, "refin1n");
	if (ret < 0 && ret != -ENODEV)
		return dev_err_probe(dev, ret, "Failed to get REFIN- voltage.\n");

	/*
	 * Negative supplies are assumed to provide negative voltage.
	 * REVISIT when support for negative regulator voltage read be available
	 * in the regulator framework.
	 */
	st->vrefs_uv[AD4170_REFIN1N_SUP] = ret == -ENODEV ? -ENODEV : -ret;

	ret = devm_regulator_get_enable_read_voltage(dev, "refin2p");
	if (ret < 0 && ret != -ENODEV)
		return dev_err_probe(dev, ret, "Failed to get REFIN2+ voltage.\n");

	st->vrefs_uv[AD4170_REFIN2P_SUP] = ret;

	ret = devm_regulator_get_enable_read_voltage(dev, "refin2n");
	if (ret < 0 && ret != -ENODEV)
		return dev_err_probe(dev, ret, "Failed to get REFIN2- voltage.\n");

	/*
	 * Negative supplies are assumed to provide negative voltage.
	 * REVISIT when support for negative regulator voltage read be available
	 * in the regulator framework.
	 */
	st->vrefs_uv[AD4170_REFIN2N_SUP] = ret == -ENODEV ? -ENODEV : -ret;

	return 0;
}

static int ad4170_probe(struct spi_device *spi)
{
	const struct ad4170_chip_info *chip;
	struct device *dev = &spi->dev;
	struct iio_dev *indio_dev;
	struct ad4170_state *st;
	int ret;

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

	st = iio_priv(indio_dev);
	st->spi = spi;

	ret = devm_mutex_init(dev, &st->lock);
	if (ret)
		return ret;

	chip = spi_get_device_match_data(spi);
	if (!chip)
		return -EINVAL;

	indio_dev->name = chip->name;
	indio_dev->info = &ad4170_info;

	st->regmap = devm_regmap_init(dev, NULL, st, &ad4170_regmap_config);
	if (IS_ERR(st->regmap))
		return dev_err_probe(dev, PTR_ERR(st->regmap),
				     "Failed to initialize regmap\n");

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

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

	ret = ad4170_parse_firmware(indio_dev);
	if (ret)
		return dev_err_probe(dev, ret, "Failed to parse firmware\n");

	ret = ad4170_initial_config(indio_dev);
	if (ret)
		return dev_err_probe(dev, ret, "Failed to setup device\n");

	init_completion(&st->completion);

	if (spi->irq) {
		ret = devm_request_irq(dev, spi->irq, &ad4170_irq_handler,
				       IRQF_ONESHOT, indio_dev->name, indio_dev);
		if (ret)
			return ret;

		ret = ad4170_trigger_setup(indio_dev);
		if (ret)
			return ret;
	}

	ret = ad4170_prepare_spi_message(st);
	if (ret)
		return dev_err_probe(dev, ret, "Failed to prepare SPI message\n");

	ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
					      &ad4170_trigger_handler,
					      &ad4170_buffer_ops);
	if (ret)
		return dev_err_probe(dev, ret, "Failed to setup read buffer\n");

	return devm_iio_device_register(dev, indio_dev);
}

static const struct spi_device_id ad4170_id_table[] = {
	{ "ad4170-4", (kernel_ulong_t)&ad4170_chip_info },
	{ "ad4190-4", (kernel_ulong_t)&ad4190_chip_info },
	{ "ad4195-4", (kernel_ulong_t)&ad4195_chip_info },
	{ }
};
MODULE_DEVICE_TABLE(spi, ad4170_id_table);

static const struct of_device_id ad4170_of_match[] = {
	{ .compatible = "adi,ad4170-4", .data = &ad4170_chip_info },
	{ .compatible = "adi,ad4190-4", .data = &ad4190_chip_info },
	{ .compatible = "adi,ad4195-4", .data = &ad4195_chip_info },
	{ }
};
MODULE_DEVICE_TABLE(of, ad4170_of_match);

static struct spi_driver ad4170_driver = {
	.driver = {
		.name = "ad4170-4",
		.of_match_table = ad4170_of_match,
	},
	.probe = ad4170_probe,
	.id_table = ad4170_id_table,
};
module_spi_driver(ad4170_driver);

MODULE_AUTHOR("Ana-Maria Cusco <ana-maria.cusco@analog.com>");
MODULE_AUTHOR("Marcelo Schmitt <marcelo.schmitt@analog.com>");
MODULE_DESCRIPTION("Analog Devices AD4170 SPI driver");
MODULE_LICENSE("GPL");