[PATCH v3 2/4] iio: adc: ad799x: cache regulator voltages during probe

Archit Anant posted 4 patches 1 month, 1 week ago
There is a newer version of this series
[PATCH v3 2/4] iio: adc: ad799x: cache regulator voltages during probe
Posted by Archit Anant 1 month, 1 week ago
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
Re: [PATCH v3 2/4] iio: adc: ad799x: cache regulator voltages during probe
Posted by David Lechner 1 month, 1 week ago
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.
Re: [PATCH v3 2/4] iio: adc: ad799x: cache regulator voltages during probe
Posted by Andy Shevchenko 1 month, 1 week ago
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