Reading the regulator voltage via regulator_get_voltage() can be a slow
operation. Since the reference voltages for this ADC are not expected to
change at runtime, it is inefficient to query the regulator API every
time userspace reads the IIO_CHAN_INFO_SCALE attribute.
Cache the VCC and VREF voltages in the state structure during probe().
This improves the performance of ad799x_read_raw() and removes the
dependency on the regulator pointers during fast-path reads.
Suggested-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Archit Anant <architanant5@gmail.com>
---
drivers/iio/adc/ad799x.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c
index 7775be874081..35e0589428d0 100644
--- a/drivers/iio/adc/ad799x.c
+++ b/drivers/iio/adc/ad799x.c
@@ -135,6 +135,10 @@ struct ad799x_state {
u16 config;
unsigned int transfer_size;
+
+ int vcc_uv;
+ int vref_uv;
+
IIO_DECLARE_DMA_BUFFER_WITH_TS(__be16, rx_buf, AD799X_MAX_CHANNELS);
};
@@ -303,9 +307,9 @@ static int ad799x_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
if (st->vref)
- ret = regulator_get_voltage(st->vref);
+ ret = st->vref_uv;
else
- ret = regulator_get_voltage(st->reg);
+ ret = st->vcc_uv;
if (ret < 0)
return ret;
@@ -809,6 +813,10 @@ static int ad799x_probe(struct i2c_client *client)
ret = regulator_enable(st->reg);
if (ret)
return ret;
+ ret = regulator_get_voltage(st->reg);
+ if (ret < 0)
+ goto error_disable_reg;
+ st->vcc_uv = ret;
/* check if an external reference is supplied */
if (chip_info->has_vref) {
@@ -827,6 +835,11 @@ static int ad799x_probe(struct i2c_client *client)
ret = regulator_enable(st->vref);
if (ret)
goto error_disable_reg;
+
+ ret = regulator_get_voltage(st->vref);
+ if (ret < 0)
+ goto error_disable_vref;
+ st->vref_uv = ret;
}
}
--
2.39.5
On 3/2/26 7:06 AM, Archit Anant wrote:
> Reading the regulator voltage via regulator_get_voltage() can be a slow
> operation. Since the reference voltages for this ADC are not expected to
> change at runtime, it is inefficient to query the regulator API every
> time userspace reads the IIO_CHAN_INFO_SCALE attribute.
>
> Cache the VCC and VREF voltages in the state structure during probe().
> This improves the performance of ad799x_read_raw() and removes the
> dependency on the regulator pointers during fast-path reads.
>
> Suggested-by: Jonathan Cameron <jic23@kernel.org>
> Signed-off-by: Archit Anant <architanant5@gmail.com>
> ---
> drivers/iio/adc/ad799x.c | 17 +++++++++++++++--
> 1 file changed, 15 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c
> index 7775be874081..35e0589428d0 100644
> --- a/drivers/iio/adc/ad799x.c
> +++ b/drivers/iio/adc/ad799x.c
> @@ -135,6 +135,10 @@ struct ad799x_state {
> u16 config;
>
> unsigned int transfer_size;
> +
> + int vcc_uv;
> + int vref_uv;
> +
> IIO_DECLARE_DMA_BUFFER_WITH_TS(__be16, rx_buf, AD799X_MAX_CHANNELS);
> };
>
> @@ -303,9 +307,9 @@ static int ad799x_read_raw(struct iio_dev *indio_dev,
> return IIO_VAL_INT;
> case IIO_CHAN_INFO_SCALE:
> if (st->vref)
> - ret = regulator_get_voltage(st->vref);
> + ret = st->vref_uv;
> else
> - ret = regulator_get_voltage(st->reg);
> + ret = st->vcc_uv;
>
> if (ret < 0)
> return ret;
This can be simplified even more. See reply to v2.
We could even move the if statement to probe and only
add one state variable.
On Mon, Mar 02, 2026 at 06:36:30PM +0530, Archit Anant wrote: > Reading the regulator voltage via regulator_get_voltage() can be a slow > operation. Since the reference voltages for this ADC are not expected to > change at runtime, it is inefficient to query the regulator API every > time userspace reads the IIO_CHAN_INFO_SCALE attribute. > > Cache the VCC and VREF voltages in the state structure during probe(). > This improves the performance of ad799x_read_raw() and removes the > dependency on the regulator pointers during fast-path reads. ... > + int vcc_uv; > + int vref_uv; _uV in both cases, please. It's a unit suffix. ... > case IIO_CHAN_INFO_SCALE: > if (st->vref) > - ret = regulator_get_voltage(st->vref); > + ret = st->vref_uv; > else > - ret = regulator_get_voltage(st->reg); > + ret = st->vcc_uv; > if (ret < 0) > return ret; Isn't it a dead check now? -- With Best Regards, Andy Shevchenko
© 2016 - 2026 Red Hat, Inc.