[PATCH v1 06/13] iio: adc: ad4134: Add support for digital filter type selection
From: Marcelo Schmitt
Date: Wed Sep 02 2026 - 13:35:11 EST
AD4134 supports four types of programmable digital filters that allow users
to choose between different output data rates and input bandwidths. Enable
basic digital filter configuration by providing a way to select which
filter type is activated for each channel.
Signed-off-by: Marcelo Schmitt <marcelo.schmitt@xxxxxxxxxx>
---
drivers/iio/adc/ad4134.c | 80 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 80 insertions(+)
diff --git a/drivers/iio/adc/ad4134.c b/drivers/iio/adc/ad4134.c
index 7da6734d4609..a1474316e330 100644
--- a/drivers/iio/adc/ad4134.c
+++ b/drivers/iio/adc/ad4134.c
@@ -64,6 +64,9 @@
#define AD4134_PW_DOWN_CTRL_REG 0x13
#define AD4134_DEVICE_STATUS_REG 0x15
#define AD4134_ODR_VAL_INT_LSB_REG 0x16
+#define AD4134_CHAN_DIG_FILTER_SEL_REG 0x1E
+#define AD4134_CHAN_DIG_FILTER_SEL_CH_MASK(ch) (GENMASK(1, 0) << 2 * (ch))
+
#define AD4134_CH3_OFFSET_MSB_REG 0x3E
#define AD4134_AIN_OR_ERROR_REG 0x48
@@ -81,12 +84,48 @@
#define AD4134_SPI_CRC_INIT_VALUE 0xA5
static unsigned char ad4134_spi_crc_table[CRC8_TABLE_SIZE];
+enum ad4134_filter_type {
+ AD4134_WIDEBAND,
+ AD4134_SINC6,
+ AD4134_SINC3,
+ AD4134_SINC3_REJ60,
+};
+
+static const char * const ad4134_filt_names[] = {
+ [AD4134_WIDEBAND] = "wideband",
+ [AD4134_SINC6] = "sinc6",
+ [AD4134_SINC3] = "sinc3",
+ [AD4134_SINC3_REJ60] = "sinc3+rej60",
+};
+
+static int ad4134_get_filter_type(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan);
+
+static int ad4134_set_filter_type(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ unsigned int val);
+
+static const struct iio_enum ad4134_filter_type_enum = {
+ .items = ad4134_filt_names,
+ .num_items = ARRAY_SIZE(ad4134_filt_names),
+ .get = ad4134_get_filter_type,
+ .set = ad4134_set_filter_type,
+};
+
+static const struct iio_chan_spec_ext_info ad4134_filter_type_ext_info[] = {
+ IIO_ENUM("filter_type", IIO_SEPARATE, &ad4134_filter_type_enum),
+ IIO_ENUM_AVAILABLE("filter_type", IIO_SEPARATE,
+ &ad4134_filter_type_enum),
+ { }
+};
+
#define AD4134_CHANNEL(_index) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = (_index), \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .ext_info = ad4134_filter_type_ext_info, \
}
static const struct iio_chan_spec ad4134_chan_set[] = {
@@ -116,6 +155,47 @@ struct ad4134_state {
u8 tx_buf[AD4134_SPI_MAX_XFER_LEN];
};
+static int ad4134_set_filter_type(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ unsigned int val)
+{
+ struct ad4134_state *st = iio_priv(indio_dev);
+ unsigned int mask, reg_val;
+
+ IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim);
+ if (IIO_DEV_ACQUIRE_FAILED(claim))
+ return -EBUSY;
+
+ guard(mutex)(&st->lock);
+
+ mask = AD4134_CHAN_DIG_FILTER_SEL_CH_MASK(chan->channel);
+ reg_val = field_prep(mask, val);
+ return regmap_update_bits(st->regmap, AD4134_CHAN_DIG_FILTER_SEL_REG,
+ mask, reg_val);
+}
+
+static int ad4134_get_filter_type(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan)
+{
+ struct ad4134_state *st = iio_priv(indio_dev);
+ enum ad4134_filter_type f_type;
+ unsigned int mask, reg_val;
+ int ret;
+
+ IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim);
+ if (IIO_DEV_ACQUIRE_FAILED(claim))
+ return -EBUSY;
+
+ ret = regmap_read(st->regmap, AD4134_CHAN_DIG_FILTER_SEL_REG, ®_val);
+ if (ret)
+ return ret;
+
+ mask = AD4134_CHAN_DIG_FILTER_SEL_CH_MASK(chan->channel);
+ f_type = field_get(mask, reg_val);
+
+ return f_type;
+}
+
static const struct regmap_range ad4134_regmap_rd_range[] = {
regmap_reg_range(AD4134_IFACE_CONFIG_A_REG, AD4134_SILICON_REV_REG),
regmap_reg_range(AD4134_SCRATCH_PAD_REG, AD4134_PW_DOWN_CTRL_REG),
--
2.53.0