ADAQ4216 and ADAQ4224 are similar to AD4030, but feature a PGA circuitry
that scales the analog input signal prior to it reaching the ADC. The PGA
is controlled through a pair of pins (A0 and A1) whose state define the
gain that is applied to the input signal.
Add support for ADAQ4216 and ADAQ4224. Provide a list of PGA options
through the IIO device channel scale available interface and enable control
of the PGA through the channel scale interface.
Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
---
Change log v8 -> v9
- Use floats in ADAQ gain comments.
drivers/iio/adc/ad4030.c | 231 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 228 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/adc/ad4030.c b/drivers/iio/adc/ad4030.c
index 7c335557cf05..3427a6887920 100644
--- a/drivers/iio/adc/ad4030.c
+++ b/drivers/iio/adc/ad4030.c
@@ -48,6 +48,8 @@
#define AD4030_REG_CHIP_GRADE_AD4630_24_GRADE 0x00
#define AD4030_REG_CHIP_GRADE_AD4632_16_GRADE 0x05
#define AD4030_REG_CHIP_GRADE_AD4632_24_GRADE 0x02
+#define AD4030_REG_CHIP_GRADE_ADAQ4216_GRADE 0x1E
+#define AD4030_REG_CHIP_GRADE_ADAQ4224_GRADE 0x1C
#define AD4030_REG_CHIP_GRADE_MASK_CHIP_GRADE GENMASK(7, 3)
#define AD4030_REG_SCRATCH_PAD 0x0A
#define AD4030_REG_SPI_REVISION 0x0B
@@ -125,6 +127,10 @@
/* Datasheet says 9.8ns, so use the closest integer value */
#define AD4030_TQUIET_CNV_DELAY_NS 10
+/* HARDWARE_GAIN */
+#define ADAQ4616_PGA_PINS 2
+#define ADAQ4616_PGA_GAIN_MAX_NANO (NANO * 2 / 3)
+
enum ad4030_out_mode {
AD4030_OUT_DATA_MD_DIFF,
AD4030_OUT_DATA_MD_16_DIFF_8_COM,
@@ -145,6 +151,30 @@ enum {
AD4030_SCAN_TYPE_AVG,
};
+static const int adaq4216_hw_gains_db[] = {
+ -10, /* 1/3 V/V gain */
+ -5, /* 5/9 V/V gain */
+ 7, /* 20/9 V/V gain */
+ 16, /* 20/3 V/V gain */
+};
+
+/*
+ * Gains computed as fractions of 1000 so they can be expressed by integers.
+ */
+static const int adaq4216_hw_gains_vpv[] = {
+ 1 * MILLI / 3, /* 0.333 */
+ 5 * MILLI / 9, /* 0.555 */
+ 20 * MILLI / 9, /* 0.2222 */
+ 20 * MILLI / 3, /* 0.6666 */
+};
+
+static const int adaq4216_hw_gains_frac[][2] = {
+ { 1, 3 }, /* 1/3 V/V gain */
+ { 5, 9 }, /* 5/9 V/V gain */
+ { 20, 9 }, /* 20/9 V/V gain */
+ { 20, 3 }, /* 20/3 V/V gain */
+};
+
struct ad4030_chip_info {
const char *name;
const unsigned long *available_masks;
@@ -152,6 +182,7 @@ struct ad4030_chip_info {
const struct iio_chan_spec offload_channels[AD4030_MAX_IIO_CHANNEL_NB];
u8 grade;
u8 precision_bits;
+ bool has_pga;
/* Number of hardware channels */
int num_voltage_inputs;
unsigned int tcyc_ns;
@@ -175,7 +206,11 @@ struct ad4030_state {
struct spi_offload_trigger *offload_trigger;
struct spi_offload_trigger_config offload_trigger_config;
struct pwm_device *cnv_trigger;
+ size_t scale_avail_size;
struct pwm_waveform cnv_wf;
+ unsigned int scale_avail[ARRAY_SIZE(adaq4216_hw_gains_db)][2];
+ struct gpio_descs *pga_gpios;
+ unsigned int pga_index;
/*
* DMA (thus cache coherency maintenance) requires the transfer buffers
@@ -232,7 +267,7 @@ struct ad4030_state {
* - voltage0-voltage1
* - voltage2-voltage3
*/
-#define __AD4030_CHAN_DIFF(_idx, _scan_type, _offload) { \
+#define __AD4030_CHAN_DIFF(_idx, _scan_type, _offload, _pga) { \
.info_mask_shared_by_all = \
(_offload ? BIT(IIO_CHAN_INFO_SAMP_FREQ) : 0) | \
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
@@ -243,6 +278,7 @@ struct ad4030_state {
BIT(IIO_CHAN_INFO_CALIBBIAS) | \
BIT(IIO_CHAN_INFO_RAW), \
.info_mask_separate_available = BIT(IIO_CHAN_INFO_CALIBBIAS) | \
+ (_pga ? BIT(IIO_CHAN_INFO_SCALE) : 0) | \
BIT(IIO_CHAN_INFO_CALIBSCALE), \
.type = IIO_VOLTAGE, \
.indexed = 1, \
@@ -257,10 +293,16 @@ struct ad4030_state {
}
#define AD4030_CHAN_DIFF(_idx, _scan_type) \
- __AD4030_CHAN_DIFF(_idx, _scan_type, 0)
+ __AD4030_CHAN_DIFF(_idx, _scan_type, 0, 0)
#define AD4030_OFFLOAD_CHAN_DIFF(_idx, _scan_type) \
- __AD4030_CHAN_DIFF(_idx, _scan_type, 1)
+ __AD4030_CHAN_DIFF(_idx, _scan_type, 1, 0)
+
+#define ADAQ4216_CHAN_DIFF(_idx, _scan_type) \
+ __AD4030_CHAN_DIFF(_idx, _scan_type, 0, 1)
+
+#define ADAQ4216_OFFLOAD_CHAN_DIFF(_idx, _scan_type) \
+ __AD4030_CHAN_DIFF(_idx, _scan_type, 1, 1)
/*
* AD4030 can average over 2^N samples, where N = 1, 2, 3, ..., 16.
@@ -418,6 +460,64 @@ static const struct regmap_config ad4030_regmap_config = {
.max_register = AD4030_REG_DIG_ERR,
};
+static void ad4030_fill_scale_avail(struct ad4030_state *st)
+{
+ unsigned int mag_bits, int_part, fract_part, i;
+ u64 range;
+
+ /*
+ * The maximum precision of differential channels is retrieved from the
+ * chip properties. The output code of differential channels is in two's
+ * complement format (i.e. signed), so the MSB is the sign bit and only
+ * (precision_bits - 1) bits express voltage magnitude.
+ */
+ mag_bits = st->chip->precision_bits - 1;
+
+ for (i = 0; i < ARRAY_SIZE(adaq4216_hw_gains_frac); i++) {
+ range = mult_frac(st->vref_uv, adaq4216_hw_gains_frac[i][1],
+ adaq4216_hw_gains_frac[i][0]);
+ /*
+ * If range were in mV, we would multiply it by NANO below.
+ * Though, range is in µV so multiply it by MICRO only so the
+ * result after right shift and division scales output codes to
+ * millivolts.
+ */
+ int_part = div_u64_rem(((u64)range * MICRO) >> mag_bits, NANO, &fract_part);
+ st->scale_avail[i][0] = int_part;
+ st->scale_avail[i][1] = fract_part;
+ }
+}
+
+static int ad4030_set_pga_gain(struct ad4030_state *st)
+{
+ DECLARE_BITMAP(bitmap, ADAQ4616_PGA_PINS) = { };
+
+ bitmap_write(bitmap, st->pga_index, 0, ADAQ4616_PGA_PINS);
+
+ return gpiod_multi_set_value_cansleep(st->pga_gpios, bitmap);
+}
+
+static int ad4030_set_pga(struct iio_dev *indio_dev, int gain_int, int gain_fract)
+{
+ struct ad4030_state *st = iio_priv(indio_dev);
+ unsigned int mag_bits = st->chip->precision_bits - 1;
+ u64 gain_nano, tmp;
+
+ if (!st->pga_gpios)
+ return -EINVAL;
+
+ gain_nano = gain_int * NANO + gain_fract;
+ if (!in_range(gain_nano, 1, ADAQ4616_PGA_GAIN_MAX_NANO))
+ return -EINVAL;
+
+ tmp = DIV_ROUND_CLOSEST_ULL(gain_nano << mag_bits, NANO);
+ gain_nano = DIV_ROUND_CLOSEST_ULL(st->vref_uv, tmp);
+ st->pga_index = find_closest(gain_nano, adaq4216_hw_gains_vpv,
+ ARRAY_SIZE(adaq4216_hw_gains_vpv));
+
+ return ad4030_set_pga_gain(st);
+}
+
static int ad4030_get_chan_scale(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val,
@@ -430,6 +530,13 @@ static int ad4030_get_chan_scale(struct iio_dev *indio_dev,
if (IS_ERR(scan_type))
return PTR_ERR(scan_type);
+ /* The LSB of the 8-bit common-mode data is always vref/256. */
+ if (st->chip->has_pga && scan_type->realbits != 8) {
+ *val = st->scale_avail[st->pga_index][0];
+ *val2 = st->scale_avail[st->pga_index][1];
+ return IIO_VAL_INT_PLUS_NANO;
+ }
+
if (chan->differential)
*val = (st->vref_uv * 2) / MILLI;
else
@@ -895,6 +1002,15 @@ static int ad4030_read_avail(struct iio_dev *indio_dev,
*length = ARRAY_SIZE(ad4030_average_modes);
return IIO_AVAIL_LIST;
+ case IIO_CHAN_INFO_SCALE:
+ if (st->scale_avail_size == 1)
+ *vals = (int *)st->scale_avail[st->pga_index];
+ else
+ *vals = (int *)st->scale_avail;
+ *length = st->scale_avail_size * 2; /* print int and nano part */
+ *type = IIO_VAL_INT_PLUS_NANO;
+ return IIO_AVAIL_LIST;
+
default:
return -EINVAL;
}
@@ -967,6 +1083,9 @@ static int ad4030_write_raw_dispatch(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_SAMP_FREQ:
return ad4030_set_sampling_freq(indio_dev, val);
+ case IIO_CHAN_INFO_SCALE:
+ return ad4030_set_pga(indio_dev, val, val2);
+
default:
return -EINVAL;
}
@@ -988,6 +1107,17 @@ static int ad4030_write_raw(struct iio_dev *indio_dev,
return ret;
}
+static int ad4030_write_raw_get_fmt(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan, long mask)
+{
+ switch (mask) {
+ case IIO_CHAN_INFO_SCALE:
+ return IIO_VAL_INT_PLUS_NANO;
+ default:
+ return IIO_VAL_INT_PLUS_MICRO;
+ }
+}
+
static int ad4030_reg_access(struct iio_dev *indio_dev, unsigned int reg,
unsigned int writeval, unsigned int *readval)
{
@@ -1034,6 +1164,7 @@ static const struct iio_info ad4030_iio_info = {
.read_avail = ad4030_read_avail,
.read_raw = ad4030_read_raw,
.write_raw = ad4030_write_raw,
+ .write_raw_get_fmt = &ad4030_write_raw_get_fmt,
.debugfs_reg_access = ad4030_reg_access,
.read_label = ad4030_read_label,
.get_current_scan_type = ad4030_get_current_scan_type,
@@ -1275,6 +1406,50 @@ static int ad4030_spi_offload_setup(struct iio_dev *indio_dev,
IIO_BUFFER_DIRECTION_IN);
}
+static int ad4030_setup_pga(struct device *dev, struct iio_dev *indio_dev,
+ struct ad4030_state *st)
+{
+ unsigned int i;
+ int pga_gain_dB;
+ int ret;
+
+ ret = device_property_read_u32(dev, "adi,pga-gain-db", &pga_gain_dB);
+ if (ret == -EINVAL) {
+ /* Setup GPIOs for PGA control */
+ st->pga_gpios = devm_gpiod_get_array(dev, "pga", GPIOD_OUT_LOW);
+ if (IS_ERR(st->pga_gpios))
+ return dev_err_probe(dev, PTR_ERR(st->pga_gpios),
+ "Failed to get PGA gpios.\n");
+
+ if (st->pga_gpios->ndescs != ADAQ4616_PGA_PINS)
+ return dev_err_probe(dev, -EINVAL,
+ "Expected 2 GPIOs for PGA control.\n");
+
+ st->scale_avail_size = ARRAY_SIZE(adaq4216_hw_gains_db);
+ st->pga_index = 0;
+ return 0;
+ } else if (ret) {
+ return dev_err_probe(dev, ret, "Failed to get PGA value.\n");
+ }
+
+ /* Set ADC driver to handle pin-strapped PGA pins setup */
+ for (i = 0; i < ARRAY_SIZE(adaq4216_hw_gains_db); i++) {
+ if (pga_gain_dB != adaq4216_hw_gains_db[i])
+ continue;
+
+ st->pga_index = i;
+ break;
+ }
+ if (i == ARRAY_SIZE(adaq4216_hw_gains_db))
+ return dev_err_probe(dev, -EINVAL, "Invalid PGA gain: %d.\n",
+ pga_gain_dB);
+
+ st->scale_avail_size = 1;
+ st->pga_gpios = NULL;
+
+ return 0;
+}
+
static int ad4030_probe(struct spi_device *spi)
{
struct device *dev = &spi->dev;
@@ -1317,6 +1492,14 @@ static int ad4030_probe(struct spi_device *spi)
if (ret)
return ret;
+ if (st->chip->has_pga) {
+ ret = ad4030_setup_pga(dev, indio_dev, st);
+ if (ret)
+ return ret;
+
+ ad4030_fill_scale_avail(st);
+ }
+
ret = ad4030_config(st);
if (ret)
return ret;
@@ -1568,12 +1751,52 @@ static const struct ad4030_chip_info ad4632_24_chip_info = {
.max_sample_rate_hz = 500 * HZ_PER_KHZ,
};
+static const struct ad4030_chip_info adaq4216_chip_info = {
+ .name = "adaq4216",
+ .available_masks = ad4030_channel_masks,
+ .channels = {
+ ADAQ4216_CHAN_DIFF(0, ad4030_16_scan_types),
+ AD4030_CHAN_CMO(1, 0),
+ IIO_CHAN_SOFT_TIMESTAMP(2),
+ },
+ .offload_channels = {
+ ADAQ4216_OFFLOAD_CHAN_DIFF(0, ad4030_16_offload_scan_types),
+ },
+ .grade = AD4030_REG_CHIP_GRADE_ADAQ4216_GRADE,
+ .precision_bits = 16,
+ .has_pga = true,
+ .num_voltage_inputs = 1,
+ .tcyc_ns = AD4030_TCYC_ADJUSTED_NS,
+ .max_sample_rate_hz = 2 * HZ_PER_MHZ,
+};
+
+static const struct ad4030_chip_info adaq4224_chip_info = {
+ .name = "adaq4224",
+ .available_masks = ad4030_channel_masks,
+ .channels = {
+ ADAQ4216_CHAN_DIFF(0, ad4030_24_scan_types),
+ AD4030_CHAN_CMO(1, 0),
+ IIO_CHAN_SOFT_TIMESTAMP(2),
+ },
+ .offload_channels = {
+ ADAQ4216_OFFLOAD_CHAN_DIFF(0, ad4030_24_offload_scan_types),
+ },
+ .grade = AD4030_REG_CHIP_GRADE_ADAQ4224_GRADE,
+ .precision_bits = 24,
+ .has_pga = true,
+ .num_voltage_inputs = 1,
+ .tcyc_ns = AD4030_TCYC_ADJUSTED_NS,
+ .max_sample_rate_hz = 2 * HZ_PER_MHZ,
+};
+
static const struct spi_device_id ad4030_id_table[] = {
{ "ad4030-24", (kernel_ulong_t)&ad4030_24_chip_info },
{ "ad4630-16", (kernel_ulong_t)&ad4630_16_chip_info },
{ "ad4630-24", (kernel_ulong_t)&ad4630_24_chip_info },
{ "ad4632-16", (kernel_ulong_t)&ad4632_16_chip_info },
{ "ad4632-24", (kernel_ulong_t)&ad4632_24_chip_info },
+ { "adaq4216", (kernel_ulong_t)&adaq4216_chip_info },
+ { "adaq4224", (kernel_ulong_t)&adaq4224_chip_info },
{ }
};
MODULE_DEVICE_TABLE(spi, ad4030_id_table);
@@ -1584,6 +1807,8 @@ static const struct of_device_id ad4030_of_match[] = {
{ .compatible = "adi,ad4630-24", .data = &ad4630_24_chip_info },
{ .compatible = "adi,ad4632-16", .data = &ad4632_16_chip_info },
{ .compatible = "adi,ad4632-24", .data = &ad4632_24_chip_info },
+ { .compatible = "adi,adaq4216", .data = &adaq4216_chip_info },
+ { .compatible = "adi,adaq4224", .data = &adaq4224_chip_info },
{ }
};
MODULE_DEVICE_TABLE(of, ad4030_of_match);
--
2.39.2
On Mon, Feb 16, 2026 at 12:01:12PM -0300, Marcelo Schmitt wrote:
> ADAQ4216 and ADAQ4224 are similar to AD4030, but feature a PGA circuitry
> that scales the analog input signal prior to it reaching the ADC. The PGA
> is controlled through a pair of pins (A0 and A1) whose state define the
> gain that is applied to the input signal.
>
> Add support for ADAQ4216 and ADAQ4224. Provide a list of PGA options
> through the IIO device channel scale available interface and enable control
> of the PGA through the channel scale interface.
...
> +static void ad4030_fill_scale_avail(struct ad4030_state *st)
> +{
> + unsigned int mag_bits, int_part, fract_part, i;
> + u64 range;
> +
> + /*
> + * The maximum precision of differential channels is retrieved from the
> + * chip properties. The output code of differential channels is in two's
> + * complement format (i.e. signed), so the MSB is the sign bit and only
> + * (precision_bits - 1) bits express voltage magnitude.
> + */
> + mag_bits = st->chip->precision_bits - 1;
> +
> + for (i = 0; i < ARRAY_SIZE(adaq4216_hw_gains_frac); i++) {
Can be
for (unsigned int i = 0; i < ARRAY_SIZE(adaq4216_hw_gains_frac); i++) {
which is still under 80 and makes the top definition cleaner and code robust
by not exposing loop iterator out of the loop's scope.
> + range = mult_frac(st->vref_uv, adaq4216_hw_gains_frac[i][1],
> + adaq4216_hw_gains_frac[i][0]);
> + /*
> + * If range were in mV, we would multiply it by NANO below.
> + * Though, range is in µV so multiply it by MICRO only so the
> + * result after right shift and division scales output codes to
> + * millivolts.
> + */
> + int_part = div_u64_rem(((u64)range * MICRO) >> mag_bits, NANO, &fract_part);
> + st->scale_avail[i][0] = int_part;
> + st->scale_avail[i][1] = fract_part;
> + }
> +}
...
> +static int ad4030_set_pga(struct iio_dev *indio_dev, int gain_int, int gain_fract)
> +{
> + struct ad4030_state *st = iio_priv(indio_dev);
> + unsigned int mag_bits = st->chip->precision_bits - 1;
> + u64 gain_nano, tmp;
> +
> + if (!st->pga_gpios)
> + return -EINVAL;
> +
> + gain_nano = gain_int * NANO + gain_fract;
> + if (!in_range(gain_nano, 1, ADAQ4616_PGA_GAIN_MAX_NANO))
> + return -EINVAL;
> +
> + tmp = DIV_ROUND_CLOSEST_ULL(gain_nano << mag_bits, NANO);
> + gain_nano = DIV_ROUND_CLOSEST_ULL(st->vref_uv, tmp);
This (second one only) doesn't sound like a 64-bit division.
Can tmp be bigger than 32-bit?
> + st->pga_index = find_closest(gain_nano, adaq4216_hw_gains_vpv,
> + ARRAY_SIZE(adaq4216_hw_gains_vpv));
> +
> + return ad4030_set_pga_gain(st);
> +}
...
> +static int ad4030_setup_pga(struct device *dev, struct iio_dev *indio_dev,
> + struct ad4030_state *st)
> +{
> + unsigned int i;
> + int pga_gain_dB;
> + int ret;
> +
> + ret = device_property_read_u32(dev, "adi,pga-gain-db", &pga_gain_dB);
> + if (ret == -EINVAL) {
Actually instead of custom error hunting, this should be rather
if (device_property_present(dev, "adi,pga-gain-db")) {
ret = device_property_read_u32(dev, "adi,pga-gain-db", &pga_gain_dB);
if (ret)
return dev_err_probe(dev, ret, "Failed to get PGA value.\n");
} else {
> + /* Setup GPIOs for PGA control */
> + st->pga_gpios = devm_gpiod_get_array(dev, "pga", GPIOD_OUT_LOW);
> + if (IS_ERR(st->pga_gpios))
> + return dev_err_probe(dev, PTR_ERR(st->pga_gpios),
> + "Failed to get PGA gpios.\n");
> +
> + if (st->pga_gpios->ndescs != ADAQ4616_PGA_PINS)
> + return dev_err_probe(dev, -EINVAL,
> + "Expected 2 GPIOs for PGA control.\n");
> +
> + st->scale_avail_size = ARRAY_SIZE(adaq4216_hw_gains_db);
> + st->pga_index = 0;
> + return 0;
> + } else if (ret) {
> + return dev_err_probe(dev, ret, "Failed to get PGA value.\n");
> + }
(this goes above)
> + /* Set ADC driver to handle pin-strapped PGA pins setup */
> + for (i = 0; i < ARRAY_SIZE(adaq4216_hw_gains_db); i++) {
> + if (pga_gain_dB != adaq4216_hw_gains_db[i])
> + continue;
> +
> + st->pga_index = i;
> + break;
> + }
> + if (i == ARRAY_SIZE(adaq4216_hw_gains_db))
> + return dev_err_probe(dev, -EINVAL, "Invalid PGA gain: %d.\n",
> + pga_gain_dB);
> +
> + st->scale_avail_size = 1;
> + st->pga_gpios = NULL;
> +
> + return 0;
> +}
--
With Best Regards,
Andy Shevchenko
Hi Andy,
On 02/17, Andy Shevchenko wrote:
> On Mon, Feb 16, 2026 at 12:01:12PM -0300, Marcelo Schmitt wrote:
> > ADAQ4216 and ADAQ4224 are similar to AD4030, but feature a PGA circuitry
> > that scales the analog input signal prior to it reaching the ADC. The PGA
> > is controlled through a pair of pins (A0 and A1) whose state define the
> > gain that is applied to the input signal.
> >
> > Add support for ADAQ4216 and ADAQ4224. Provide a list of PGA options
> > through the IIO device channel scale available interface and enable control
> > of the PGA through the channel scale interface.
>
...
> > +static int ad4030_setup_pga(struct device *dev, struct iio_dev *indio_dev,
> > + struct ad4030_state *st)
> > +{
> > + unsigned int i;
> > + int pga_gain_dB;
> > + int ret;
> > +
> > + ret = device_property_read_u32(dev, "adi,pga-gain-db", &pga_gain_dB);
> > + if (ret == -EINVAL) {
>
> Actually instead of custom error hunting, this should be rather
Sorry, I messed up when preparing the patches. "adi,pga-gain-db" is not going
to be a dt property and this should have been just the 'GPIOs for PGA control'
below. Anyway, thanks for reviewing this. I'll hopefully recall this error
handling pattern in future contributions.
The other suggestions look good but I'll wait a bit more before sending v10.
>
> if (device_property_present(dev, "adi,pga-gain-db")) {
> ret = device_property_read_u32(dev, "adi,pga-gain-db", &pga_gain_dB);
> if (ret)
> return dev_err_probe(dev, ret, "Failed to get PGA value.\n");
> } else {
>
> > + /* Setup GPIOs for PGA control */
> > + st->pga_gpios = devm_gpiod_get_array(dev, "pga", GPIOD_OUT_LOW);
> > + if (IS_ERR(st->pga_gpios))
> > + return dev_err_probe(dev, PTR_ERR(st->pga_gpios),
> > + "Failed to get PGA gpios.\n");
> > +
> > + if (st->pga_gpios->ndescs != ADAQ4616_PGA_PINS)
> > + return dev_err_probe(dev, -EINVAL,
> > + "Expected 2 GPIOs for PGA control.\n");
> > +
> > + st->scale_avail_size = ARRAY_SIZE(adaq4216_hw_gains_db);
> > + st->pga_index = 0;
> > + return 0;
>
> > + } else if (ret) {
> > + return dev_err_probe(dev, ret, "Failed to get PGA value.\n");
> > + }
>
...
> --
> With Best Regards,
> Andy Shevchenko
>
Thanks,
Marcelo
© 2016 - 2026 Red Hat, Inc.