root/drivers/iio/adc/ad4170-4.c
// 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_NO_THREAD, 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");