]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
iio: adc: ad4130: add new supported parts
authorJonathan Santos <Jonathan.Santos@analog.com>
Wed, 1 Apr 2026 11:58:50 +0000 (08:58 -0300)
committerJonathan Cameron <jic23@kernel.org>
Mon, 27 Apr 2026 08:58:23 +0000 (09:58 +0100)
Add support for AD4129-4/8, AD4130-4, and AD4131-4/8 variants.

The AD4129 series supports the same FIFO interface as the AD4130 but with
reduced resolution (16-bit). The AD4131 series lacks FIFO support, so
triggered buffer functionality is introduced.

The 4-channel variants feature fewer analog inputs, GPIOs, and sparse pin
mappings for VBIAS, analog inputs, and excitation currents. The driver now
handles these differences with chip-specific configurations, including pin
mappings and GPIO counts.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Jonathan Santos <Jonathan.Santos@analog.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
drivers/iio/adc/ad4130.c

index b064744e8da8cc1e6525da3a9b617120e6c1d5de..7f39f3484062a550cd22a15b4547188b6e19b41a 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/cleanup.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/err.h>
@@ -21,6 +22,7 @@
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/spi/spi.h>
+#include <linux/types.h>
 #include <linux/units.h>
 
 #include <asm/div64.h>
@@ -30,6 +32,9 @@
 #include <linux/iio/iio.h>
 #include <linux/iio/kfifo_buf.h>
 #include <linux/iio/sysfs.h>
+#include <linux/iio/trigger.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
 
 #define AD4130_NAME                            "ad4130"
 
@@ -40,6 +45,7 @@
 #define AD4130_ADC_CONTROL_REG                 0x01
 #define AD4130_ADC_CONTROL_BIPOLAR_MASK                BIT(14)
 #define AD4130_ADC_CONTROL_INT_REF_VAL_MASK    BIT(13)
+#define AD4130_ADC_CONTROL_CONT_READ_MASK      BIT(11)
 #define AD4130_INT_REF_2_5V                    2500000
 #define AD4130_INT_REF_1_25V                   1250000
 #define AD4130_ADC_CONTROL_CSB_EN_MASK         BIT(9)
@@ -54,7 +60,9 @@
 #define AD4130_IO_CONTROL_REG                  0x03
 #define AD4130_IO_CONTROL_INT_PIN_SEL_MASK     GENMASK(9, 8)
 #define AD4130_IO_CONTROL_GPIO_DATA_MASK       GENMASK(7, 4)
+#define AD4130_4_IO_CONTROL_GPIO_DATA_MASK     GENMASK(7, 6)
 #define AD4130_IO_CONTROL_GPIO_CTRL_MASK       GENMASK(3, 0)
+#define AD4130_4_IO_CONTROL_GPIO_CTRL_MASK     GENMASK(3, 2)
 
 #define AD4130_VBIAS_REG                       0x04
 
 
 #define AD4130_INVALID_SLOT                    -1
 
+static const unsigned int ad4129_reg_size[] = {
+       [AD4130_STATUS_REG] = 1,
+       [AD4130_ADC_CONTROL_REG] = 2,
+       [AD4130_DATA_REG] = 2,
+       [AD4130_IO_CONTROL_REG] = 2,
+       [AD4130_VBIAS_REG] = 2,
+       [AD4130_ID_REG] = 1,
+       [AD4130_ERROR_REG] = 2,
+       [AD4130_ERROR_EN_REG] = 2,
+       [AD4130_MCLK_COUNT_REG] = 1,
+       [AD4130_CHANNEL_X_REG(0) ... AD4130_CHANNEL_X_REG(AD4130_MAX_CHANNELS - 1)] = 3,
+       [AD4130_CONFIG_X_REG(0) ... AD4130_CONFIG_X_REG(AD4130_MAX_SETUPS - 1)] = 2,
+       [AD4130_FILTER_X_REG(0) ... AD4130_FILTER_X_REG(AD4130_MAX_SETUPS - 1)] = 3,
+       [AD4130_OFFSET_X_REG(0) ... AD4130_OFFSET_X_REG(AD4130_MAX_SETUPS - 1)] = 2,
+       [AD4130_GAIN_X_REG(0) ... AD4130_GAIN_X_REG(AD4130_MAX_SETUPS - 1)] = 2,
+       [AD4130_MISC_REG] = 2,
+       [AD4130_FIFO_CONTROL_REG] = 3,
+       [AD4130_FIFO_STATUS_REG] = 1,
+       [AD4130_FIFO_THRESHOLD_REG] = 3,
+       [AD4130_FIFO_DATA_REG] = 2,
+};
+
 static const unsigned int ad4130_reg_size[] = {
        [AD4130_STATUS_REG] = 1,
        [AD4130_ADC_CONTROL_REG] = 2,
@@ -147,6 +177,24 @@ static const unsigned int ad4130_reg_size[] = {
        [AD4130_FIFO_DATA_REG] = 3,
 };
 
+static const unsigned int ad4131_reg_size[] = {
+       [AD4130_STATUS_REG] = 1,
+       [AD4130_ADC_CONTROL_REG] = 2,
+       [AD4130_DATA_REG] = 2,
+       [AD4130_IO_CONTROL_REG] = 2,
+       [AD4130_VBIAS_REG] = 2,
+       [AD4130_ID_REG] = 1,
+       [AD4130_ERROR_REG] = 2,
+       [AD4130_ERROR_EN_REG] = 2,
+       [AD4130_MCLK_COUNT_REG] = 1,
+       [AD4130_CHANNEL_X_REG(0) ... AD4130_CHANNEL_X_REG(AD4130_MAX_CHANNELS - 1)] = 3,
+       [AD4130_CONFIG_X_REG(0) ... AD4130_CONFIG_X_REG(AD4130_MAX_SETUPS - 1)] = 2,
+       [AD4130_FILTER_X_REG(0) ... AD4130_FILTER_X_REG(AD4130_MAX_SETUPS - 1)] = 3,
+       [AD4130_OFFSET_X_REG(0) ... AD4130_OFFSET_X_REG(AD4130_MAX_SETUPS - 1)] = 2,
+       [AD4130_GAIN_X_REG(0) ... AD4130_GAIN_X_REG(AD4130_MAX_SETUPS - 1)] = 2,
+       [AD4130_MISC_REG] = 2,
+};
+
 enum ad4130_int_ref_val {
        AD4130_INT_REF_VAL_2_5V,
        AD4130_INT_REF_VAL_1_25V,
@@ -224,12 +272,26 @@ enum ad4130_pin_function {
        AD4130_PIN_FN_VBIAS = BIT(3),
 };
 
+/* Pin mapping for AIN0..AIN7, VBIAS_0..VBIAS_7 */
+static const u8 ad4130_4_pin_map[] = {
+       0x00, 0x01, 0x04, 0x05, 0x0A, 0x0B, 0x0E, 0x0F, /* 0 - 7 */
+};
+
+/* Pin mapping for AIN0..AIN15, VBIAS_0..VBIAS_15 */
+static const u8 ad4130_8_pin_map[] = {
+       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0 - 7 */
+       0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 8 - 15 */
+};
+
 struct ad4130_chip_info {
        const char *name;
        unsigned int max_analog_pins;
+       unsigned int num_gpios;
        const struct iio_info *info;
        const unsigned int *reg_size;
        const unsigned int reg_size_length;
+       const u8 *pin_map;
+       bool has_fifo;
 };
 
 /*
@@ -303,6 +365,7 @@ struct ad4130_state {
        u32                     mclk_sel;
        bool                    int_ref_en;
        bool                    bipolar;
+       bool                    buffer_wait_for_irq;
 
        unsigned int            num_enabled_channels;
        unsigned int            effective_watermark;
@@ -310,6 +373,7 @@ struct ad4130_state {
 
        struct spi_message      fifo_msg;
        struct spi_transfer     fifo_xfer[2];
+       struct iio_trigger      *trig;
 
        /*
         * DMA (thus cache coherency maintenance) requires any transfer
@@ -321,9 +385,13 @@ struct ad4130_state {
        u8                      reg_write_tx_buf[4];
        u8                      reg_read_tx_buf[1];
        u8                      reg_read_rx_buf[3];
-       u8                      fifo_tx_buf[2];
-       u8                      fifo_rx_buf[AD4130_FIFO_SIZE *
-                                           AD4130_FIFO_MAX_SAMPLE_SIZE];
+       union {
+               struct {
+                       u8 fifo_tx_buf[2];
+                       u8 fifo_rx_buf[AD4130_FIFO_SIZE * AD4130_FIFO_MAX_SAMPLE_SIZE];
+               };
+               IIO_DECLARE_BUFFER_WITH_TS(u32, scan_channels, AD4130_MAX_CHANNELS);
+       };
 };
 
 static const char * const ad4130_int_pin_names[] = {
@@ -514,7 +582,8 @@ static int ad4130_gpio_init_valid_mask(struct gpio_chip *gc,
 
        /*
         * Output-only GPIO functionality is available on pins AIN2 through
-        * AIN5. If these pins are used for anything else, do not expose them.
+        * AIN5 for some parts and AIN2 through AIN3 for others. If these pins
+        * are used for anything else, do not expose them.
         */
        for (i = 0; i < ngpios; i++) {
                unsigned int pin = i + AD4130_AIN2_P1;
@@ -535,8 +604,14 @@ static int ad4130_gpio_set(struct gpio_chip *gc, unsigned int offset,
                           int value)
 {
        struct ad4130_state *st = gpiochip_get_data(gc);
-       unsigned int mask = FIELD_PREP(AD4130_IO_CONTROL_GPIO_DATA_MASK,
-                                      BIT(offset));
+       unsigned int mask;
+
+       if (st->chip_info->num_gpios == AD4130_MAX_GPIOS)
+               mask = FIELD_PREP(AD4130_IO_CONTROL_GPIO_DATA_MASK,
+                                 BIT(offset));
+       else
+               mask = FIELD_PREP(AD4130_4_IO_CONTROL_GPIO_DATA_MASK,
+                                 BIT(offset));
 
        return regmap_update_bits(st->regmap, AD4130_IO_CONTROL_REG, mask,
                                  value ? mask : 0);
@@ -597,10 +672,43 @@ static irqreturn_t ad4130_irq_handler(int irq, void *private)
        struct iio_dev *indio_dev = private;
        struct ad4130_state *st = iio_priv(indio_dev);
 
-       if (iio_buffer_enabled(indio_dev))
-               ad4130_push_fifo_data(indio_dev);
-       else
+       if (iio_buffer_enabled(indio_dev)) {
+               if (st->chip_info->has_fifo)
+                       ad4130_push_fifo_data(indio_dev);
+               else if (st->buffer_wait_for_irq)
+                       complete(&st->completion);
+               else
+                       iio_trigger_poll(st->trig);
+       } else {
                complete(&st->completion);
+       }
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t ad4130_trigger_handler(int irq, void *p)
+{
+       struct iio_poll_func *pf = p;
+       struct iio_dev *indio_dev = pf->indio_dev;
+       struct ad4130_state *st = iio_priv(indio_dev);
+       unsigned int data_reg_size = ad4130_data_reg_size(st);
+       struct spi_transfer xfer = { };
+       unsigned int num_en_chn;
+       int ret;
+
+       num_en_chn = bitmap_weight(indio_dev->active_scan_mask,
+                                  iio_get_masklength(indio_dev));
+       xfer.rx_buf = st->scan_channels;
+       xfer.len = data_reg_size * num_en_chn;
+       ret = spi_sync_transfer(st->spi, &xfer, 1);
+       if (ret < 0)
+               goto err_out;
+
+       iio_push_to_buffers_with_timestamp(indio_dev, &st->scan_channels,
+                                          iio_get_time_ns(indio_dev));
+
+err_out:
+       iio_trigger_notify_done(indio_dev->trig);
 
        return IRQ_HANDLED;
 }
@@ -1300,12 +1408,77 @@ static const struct iio_info ad4130_info = {
        .debugfs_reg_access = ad4130_reg_access,
 };
 
+static const struct iio_info ad4131_info = {
+       .read_raw = ad4130_read_raw,
+       .read_avail = ad4130_read_avail,
+       .write_raw_get_fmt = ad4130_write_raw_get_fmt,
+       .write_raw = ad4130_write_raw,
+       .update_scan_mode = ad4130_update_scan_mode,
+       .debugfs_reg_access = ad4130_reg_access,
+};
+
+static const struct ad4130_chip_info ad4129_4_chip_info = {
+       .name = "ad4129-4",
+       .max_analog_pins = 8,
+       .num_gpios = 2,
+       .info = &ad4130_info,
+       .reg_size = ad4129_reg_size,
+       .reg_size_length = ARRAY_SIZE(ad4129_reg_size),
+       .has_fifo = true,
+       .pin_map = ad4130_4_pin_map,
+};
+
+static const struct ad4130_chip_info ad4129_8_chip_info = {
+       .name = "ad4129-8",
+       .max_analog_pins = 16,
+       .num_gpios = 4,
+       .info = &ad4130_info,
+       .reg_size = ad4129_reg_size,
+       .reg_size_length = ARRAY_SIZE(ad4129_reg_size),
+       .has_fifo = true,
+       .pin_map = ad4130_8_pin_map,
+};
+
+static const struct ad4130_chip_info ad4130_4_chip_info = {
+       .name = "ad4130-4",
+       .max_analog_pins = 16,
+       .num_gpios = 2,
+       .info = &ad4130_info,
+       .reg_size = ad4130_reg_size,
+       .reg_size_length = ARRAY_SIZE(ad4130_reg_size),
+       .has_fifo = true,
+       .pin_map = ad4130_4_pin_map,
+};
+
 static const struct ad4130_chip_info ad4130_8_chip_info = {
        .name = "ad4130-8",
        .max_analog_pins = 16,
+       .num_gpios = 4,
        .info = &ad4130_info,
        .reg_size = ad4130_reg_size,
        .reg_size_length = ARRAY_SIZE(ad4130_reg_size),
+       .has_fifo = true,
+       .pin_map = ad4130_8_pin_map,
+};
+
+static const struct ad4130_chip_info ad4131_4_chip_info = {
+       .name = "ad4131-4",
+       .max_analog_pins = 8,
+       .num_gpios = 2,
+       .info = &ad4131_info,
+       .reg_size = ad4131_reg_size,
+       .reg_size_length = ARRAY_SIZE(ad4131_reg_size),
+       .pin_map = ad4130_4_pin_map,
+};
+
+static const struct ad4130_chip_info ad4131_8_chip_info = {
+       .name = "ad4131-8",
+       .max_analog_pins = 16,
+       .num_gpios = 4,
+       .info = &ad4131_info,
+       .reg_size = ad4131_reg_size,
+       .reg_size_length = ARRAY_SIZE(ad4131_reg_size),
+       .pin_map = ad4130_8_pin_map,
 };
 
 static int ad4130_buffer_postenable(struct iio_dev *indio_dev)
@@ -1315,44 +1488,89 @@ static int ad4130_buffer_postenable(struct iio_dev *indio_dev)
 
        guard(mutex)(&st->lock);
 
-       ret = ad4130_set_watermark_interrupt_en(st, true);
-       if (ret)
-               return ret;
+       if (st->chip_info->has_fifo) {
+               ret = ad4130_set_watermark_interrupt_en(st, true);
+               if (ret)
+                       return ret;
 
-       ret = irq_set_irq_type(st->spi->irq, st->inv_irq_trigger);
-       if (ret)
-               return ret;
+               ret = irq_set_irq_type(st->spi->irq, st->inv_irq_trigger);
+               if (ret)
+                       return ret;
+
+               ret = ad4130_set_fifo_mode(st, AD4130_FIFO_MODE_WM);
+               if (ret)
+                       return ret;
+       }
 
-       ret = ad4130_set_fifo_mode(st, AD4130_FIFO_MODE_WM);
+       ret = ad4130_set_mode(st, AD4130_MODE_CONTINUOUS);
        if (ret)
                return ret;
 
-       return ad4130_set_mode(st, AD4130_MODE_CONTINUOUS);
+       /*
+        * When using triggered buffer, Entering continuous read mode must
+        * be the last command sent. No configuration changes are allowed until
+        * exiting this mode.
+        */
+       if (!st->chip_info->has_fifo) {
+               ret = regmap_update_bits(st->regmap, AD4130_ADC_CONTROL_REG,
+                                        AD4130_ADC_CONTROL_CONT_READ_MASK,
+                                        FIELD_PREP(AD4130_ADC_CONTROL_CONT_READ_MASK, 1));
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
 }
 
 static int ad4130_buffer_predisable(struct iio_dev *indio_dev)
 {
        struct ad4130_state *st = iio_priv(indio_dev);
        unsigned int i;
+       u32 temp;
        int ret;
 
        guard(mutex)(&st->lock);
 
+       if (!st->chip_info->has_fifo) {
+               temp = 0x42;
+               reinit_completion(&st->completion);
+
+               /*
+                * In continuous read mode, when all samples are read, the data
+                * ready signal returns high until the next conversion result is
+                * ready. To exit this mode, the command must be sent when data
+                * ready is low. In order to ensure that condition, wait for the
+                * next interrupt (when the new conversion is finished), allowing
+                * data ready to return low before sending the exit command.
+                */
+               st->buffer_wait_for_irq = true;
+               if (!wait_for_completion_timeout(&st->completion, msecs_to_jiffies(1000)))
+                       dev_warn(&st->spi->dev, "Conversion timed out\n");
+               st->buffer_wait_for_irq = false;
+
+               /* Perform a read data command to exit continuous read mode (0x42) */
+               ret = spi_write(st->spi, &temp, 1);
+               if (ret)
+                       return ret;
+       }
+
        ret = ad4130_set_mode(st, AD4130_MODE_IDLE);
        if (ret)
                return ret;
 
-       ret = irq_set_irq_type(st->spi->irq, st->irq_trigger);
-       if (ret)
-               return ret;
+       if (st->chip_info->has_fifo) {
+               ret = irq_set_irq_type(st->spi->irq, st->irq_trigger);
+               if (ret)
+                       return ret;
 
-       ret = ad4130_set_fifo_mode(st, AD4130_FIFO_MODE_DISABLED);
-       if (ret)
-               return ret;
+               ret = ad4130_set_fifo_mode(st, AD4130_FIFO_MODE_DISABLED);
+               if (ret)
+                       return ret;
 
-       ret = ad4130_set_watermark_interrupt_en(st, false);
-       if (ret)
-               return ret;
+               ret = ad4130_set_watermark_interrupt_en(st, false);
+               if (ret)
+                       return ret;
+       }
 
        /*
         * update_scan_mode() is not called in the disable path, disable all
@@ -1427,6 +1645,34 @@ static const struct iio_dev_attr *ad4130_fifo_attributes[] = {
        NULL
 };
 
+static const struct iio_trigger_ops ad4130_trigger_ops = {
+       .validate_device = iio_trigger_validate_own_device,
+};
+
+static int ad4130_triggered_buffer_setup(struct iio_dev *indio_dev)
+{
+       struct ad4130_state *st = iio_priv(indio_dev);
+       int ret;
+
+       st->trig = devm_iio_trigger_alloc(indio_dev->dev.parent, "%s-dev%d",
+                                         indio_dev->name, iio_device_id(indio_dev));
+       if (!st->trig)
+               return -ENOMEM;
+
+       st->trig->ops = &ad4130_trigger_ops;
+       iio_trigger_set_drvdata(st->trig, indio_dev);
+       ret = devm_iio_trigger_register(indio_dev->dev.parent, st->trig);
+       if (ret)
+               return ret;
+
+       indio_dev->trig = iio_trigger_get(st->trig);
+
+       return devm_iio_triggered_buffer_setup(indio_dev->dev.parent, indio_dev,
+                                              &iio_pollfunc_store_time,
+                                              &ad4130_trigger_handler,
+                                              &ad4130_buffer_ops);
+}
+
 static int _ad4130_find_table_index(const unsigned int *tbl, size_t len,
                                    unsigned int val)
 {
@@ -1513,6 +1759,17 @@ static int ad4130_parse_fw_setup(struct ad4130_state *st,
        return 0;
 }
 
+static unsigned int ad4130_translate_pin(struct ad4130_state *st,
+                                        unsigned int logical_pin)
+{
+       /* For analog input pins, use the chip-specific pin mapping */
+       if (logical_pin < st->chip_info->max_analog_pins)
+               return st->chip_info->pin_map[logical_pin];
+
+       /* For internal channels, pass through unchanged */
+       return logical_pin;
+}
+
 static int ad4130_validate_diff_channel(struct ad4130_state *st, u32 pin)
 {
        struct device *dev = &st->spi->dev;
@@ -1931,9 +2188,14 @@ static int ad4130_setup(struct iio_dev *indio_dev)
         * function of P2 takes priority over the GPIO out function.
         */
        val = 0;
-       for (i = 0; i < AD4130_MAX_GPIOS; i++)
-               if (st->pins_fn[i + AD4130_AIN2_P1] == AD4130_PIN_FN_NONE)
-                       val |= FIELD_PREP(AD4130_IO_CONTROL_GPIO_CTRL_MASK, BIT(i));
+       for (i = 0; i < st->chip_info->num_gpios; i++) {
+               if (st->pins_fn[i + AD4130_AIN2_P1] == AD4130_PIN_FN_NONE) {
+                       if (st->chip_info->num_gpios == 2)
+                               val |= FIELD_PREP(AD4130_4_IO_CONTROL_GPIO_CTRL_MASK, BIT(i));
+                       else
+                               val |= FIELD_PREP(AD4130_IO_CONTROL_GPIO_CTRL_MASK, BIT(i));
+               }
+       }
 
        val |= FIELD_PREP(AD4130_IO_CONTROL_INT_PIN_SEL_MASK, st->int_pin_sel);
 
@@ -1943,21 +2205,23 @@ static int ad4130_setup(struct iio_dev *indio_dev)
 
        val = 0;
        for (i = 0; i < st->num_vbias_pins; i++)
-               val |= BIT(st->vbias_pins[i]);
+               val |= BIT(ad4130_translate_pin(st, st->vbias_pins[i]));
 
        ret = regmap_write(st->regmap, AD4130_VBIAS_REG, val);
        if (ret)
                return ret;
 
-       ret = regmap_clear_bits(st->regmap, AD4130_FIFO_CONTROL_REG,
-                               AD4130_FIFO_CONTROL_HEADER_MASK);
-       if (ret)
-               return ret;
+       if (st->chip_info->has_fifo) {
+               ret = regmap_clear_bits(st->regmap, AD4130_FIFO_CONTROL_REG,
+                                       AD4130_FIFO_CONTROL_HEADER_MASK);
+               if (ret)
+                       return ret;
 
-       /* FIFO watermark interrupt starts out as enabled, disable it. */
-       ret = ad4130_set_watermark_interrupt_en(st, false);
-       if (ret)
-               return ret;
+               /* FIFO watermark interrupt starts out as enabled, disable it. */
+               ret = ad4130_set_watermark_interrupt_en(st, false);
+               if (ret)
+                       return ret;
+       }
 
        /* Setup channels. */
        for (i = 0; i < indio_dev->num_channels; i++) {
@@ -1965,10 +2229,14 @@ static int ad4130_setup(struct iio_dev *indio_dev)
                struct iio_chan_spec *chan = &st->chans[i];
                unsigned int val;
 
-               val = FIELD_PREP(AD4130_CHANNEL_AINP_MASK, chan->channel) |
-                     FIELD_PREP(AD4130_CHANNEL_AINM_MASK, chan->channel2) |
-                     FIELD_PREP(AD4130_CHANNEL_IOUT1_MASK, chan_info->iout0) |
-                     FIELD_PREP(AD4130_CHANNEL_IOUT2_MASK, chan_info->iout1);
+               val = FIELD_PREP(AD4130_CHANNEL_AINP_MASK,
+                                ad4130_translate_pin(st, chan->channel)) |
+                     FIELD_PREP(AD4130_CHANNEL_AINM_MASK,
+                                ad4130_translate_pin(st, chan->channel2)) |
+                     FIELD_PREP(AD4130_CHANNEL_IOUT1_MASK,
+                                ad4130_translate_pin(st, chan_info->iout0)) |
+                     FIELD_PREP(AD4130_CHANNEL_IOUT2_MASK,
+                                ad4130_translate_pin(st, chan_info->iout1));
 
                ret = regmap_write(st->regmap, AD4130_CHANNEL_X_REG(i), val);
                if (ret)
@@ -2018,17 +2286,19 @@ static int ad4130_probe(struct spi_device *spi)
        mutex_init(&st->lock);
        st->spi = spi;
 
-       /*
-        * Xfer:   [ XFR1 ] [         XFR2         ]
-        * Master:  0x7D N   ......................
-        * Slave:   ......   DATA1 DATA2 ... DATAN
-        */
-       st->fifo_tx_buf[0] = AD4130_COMMS_READ_MASK | AD4130_FIFO_DATA_REG;
-       st->fifo_xfer[0].tx_buf = st->fifo_tx_buf;
-       st->fifo_xfer[0].len = sizeof(st->fifo_tx_buf);
-       st->fifo_xfer[1].rx_buf = st->fifo_rx_buf;
-       spi_message_init_with_transfers(&st->fifo_msg, st->fifo_xfer,
-                                       ARRAY_SIZE(st->fifo_xfer));
+       if (st->chip_info->has_fifo) {
+               /*
+                * Xfer:   [ XFR1 ] [         XFR2         ]
+                * Master:  0x7D N   ......................
+                * Slave:   ......   DATA1 DATA2 ... DATAN
+                */
+               st->fifo_tx_buf[0] = AD4130_COMMS_READ_MASK | AD4130_FIFO_DATA_REG;
+               st->fifo_xfer[0].tx_buf = st->fifo_tx_buf;
+               st->fifo_xfer[0].len = sizeof(st->fifo_tx_buf);
+               st->fifo_xfer[1].rx_buf = st->fifo_rx_buf;
+               spi_message_init_with_transfers(&st->fifo_msg, st->fifo_xfer,
+                                               ARRAY_SIZE(st->fifo_xfer));
+       }
 
        indio_dev->name = st->chip_info->name;
        indio_dev->modes = INDIO_DIRECT_MODE;
@@ -2077,7 +2347,7 @@ static int ad4130_probe(struct spi_device *spi)
        st->gc.owner = THIS_MODULE;
        st->gc.label = st->chip_info->name;
        st->gc.base = -1;
-       st->gc.ngpio = AD4130_MAX_GPIOS;
+       st->gc.ngpio = st->chip_info->num_gpios;
        st->gc.parent = dev;
        st->gc.can_sleep = true;
        st->gc.init_valid_mask = ad4130_gpio_init_valid_mask;
@@ -2088,9 +2358,12 @@ static int ad4130_probe(struct spi_device *spi)
        if (ret)
                return ret;
 
-       ret = devm_iio_kfifo_buffer_setup_ext(dev, indio_dev,
-                                             &ad4130_buffer_ops,
-                                             ad4130_fifo_attributes);
+       if (st->chip_info->has_fifo)
+               ret = devm_iio_kfifo_buffer_setup_ext(dev, indio_dev,
+                                                     &ad4130_buffer_ops,
+                                                     ad4130_fifo_attributes);
+       else
+               ret = ad4130_triggered_buffer_setup(indio_dev);
        if (ret)
                return ret;
 
@@ -2100,37 +2373,64 @@ static int ad4130_probe(struct spi_device *spi)
        if (ret)
                return dev_err_probe(dev, ret, "Failed to request irq\n");
 
-       /*
-        * When the chip enters FIFO mode, IRQ polarity is inverted.
-        * When the chip exits FIFO mode, IRQ polarity returns to normal.
-        * See datasheet pages: 65, FIFO Watermark Interrupt section,
-        * and 71, Bit Descriptions for STATUS Register, RDYB.
-        * Cache the normal and inverted IRQ triggers to set them when
-        * entering and exiting FIFO mode.
-        */
-       st->irq_trigger = irq_get_trigger_type(spi->irq);
-       if (st->irq_trigger & IRQF_TRIGGER_RISING)
-               st->inv_irq_trigger = IRQF_TRIGGER_FALLING;
-       else if (st->irq_trigger & IRQF_TRIGGER_FALLING)
-               st->inv_irq_trigger = IRQF_TRIGGER_RISING;
-       else
-               return dev_err_probe(dev, -EINVAL, "Invalid irq flags: %u\n",
-                                    st->irq_trigger);
+       if (st->chip_info->has_fifo) {
+               /*
+                * When the chip enters FIFO mode, IRQ polarity is inverted.
+                * When the chip exits FIFO mode, IRQ polarity returns to normal.
+                * See datasheet pages: 65, FIFO Watermark Interrupt section,
+                * and 71, Bit Descriptions for STATUS Register, RDYB.
+                * Cache the normal and inverted IRQ triggers to set them when
+                * entering and exiting FIFO mode.
+                */
+               st->irq_trigger = irq_get_trigger_type(spi->irq);
+               if (st->irq_trigger & IRQF_TRIGGER_RISING)
+                       st->inv_irq_trigger = IRQF_TRIGGER_FALLING;
+               else if (st->irq_trigger & IRQF_TRIGGER_FALLING)
+                       st->inv_irq_trigger = IRQF_TRIGGER_RISING;
+               else
+                       return dev_err_probe(dev, -EINVAL, "Invalid irq flags: %u\n",
+                                            st->irq_trigger);
+       }
 
        return devm_iio_device_register(dev, indio_dev);
 }
 
 static const struct of_device_id ad4130_of_match[] = {
+       {
+               .compatible = "adi,ad4129-4",
+               .data = &ad4129_4_chip_info
+       },
+       {
+               .compatible = "adi,ad4129-8",
+               .data = &ad4129_8_chip_info
+       },
+       {
+               .compatible = "adi,ad4130-4",
+               .data = &ad4130_4_chip_info
+       },
        {
                .compatible = "adi,ad4130",
                .data = &ad4130_8_chip_info
        },
+       {
+               .compatible = "adi,ad4131-4",
+               .data = &ad4131_4_chip_info
+       },
+       {
+               .compatible = "adi,ad4131-8",
+               .data = &ad4131_8_chip_info
+       },
        { }
 };
 MODULE_DEVICE_TABLE(of, ad4130_of_match);
 
 static const struct spi_device_id ad4130_id_table[] = {
+       { "ad4129-4", (kernel_ulong_t)&ad4129_4_chip_info },
+       { "ad4129-8", (kernel_ulong_t)&ad4129_8_chip_info },
+       { "ad4130-4", (kernel_ulong_t)&ad4130_4_chip_info },
        { "ad4130", (kernel_ulong_t)&ad4130_8_chip_info },
+       { "ad4131-4", (kernel_ulong_t)&ad4131_4_chip_info },
+       { "ad4131-8", (kernel_ulong_t)&ad4131_8_chip_info },
        { }
 };
 MODULE_DEVICE_TABLE(spi, ad4130_id_table);