diff mbox series

iio: adc: stm32: fix vrefint wrong calibration value handling

Message ID 20220609095856.376961-1-olivier.moysan@foss.st.com (mailing list archive)
State Accepted
Headers show
Series iio: adc: stm32: fix vrefint wrong calibration value handling | expand

Commit Message

Olivier Moysan June 9, 2022, 9:58 a.m. UTC
If the vrefint calibration is zero, the vrefint channel output value
cannot be computed. Currently, in such case, the raw conversion value
is returned, which is not relevant.
Do not expose the vrefint channel when the output value cannot be
computed, instead.

Fixes: 0e346b2cfa85 ("iio: adc: stm32-adc: add vrefint calibration support")

Signed-off-by: Olivier Moysan <olivier.moysan@foss.st.com>
---
 drivers/iio/adc/stm32-adc.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

Comments

Fabrice Gasnier June 9, 2022, 12:14 p.m. UTC | #1
On 6/9/22 11:58, Olivier Moysan wrote:
> If the vrefint calibration is zero, the vrefint channel output value
> cannot be computed. Currently, in such case, the raw conversion value
> is returned, which is not relevant.
> Do not expose the vrefint channel when the output value cannot be
> computed, instead.
> 
> Fixes: 0e346b2cfa85 ("iio: adc: stm32-adc: add vrefint calibration support")
> 
> Signed-off-by: Olivier Moysan <olivier.moysan@foss.st.com>

Hi Olivier,

You can add my:
Reviewed-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>

Thanks,
Fabrice
> ---
>  drivers/iio/adc/stm32-adc.c | 27 +++++++++++++++++----------
>  1 file changed, 17 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c
> index a68ecbda6480..f13c112f540f 100644
> --- a/drivers/iio/adc/stm32-adc.c
> +++ b/drivers/iio/adc/stm32-adc.c
> @@ -1365,7 +1365,7 @@ static int stm32_adc_read_raw(struct iio_dev *indio_dev,
>  		else
>  			ret = -EINVAL;
>  
> -		if (mask == IIO_CHAN_INFO_PROCESSED && adc->vrefint.vrefint_cal)
> +		if (mask == IIO_CHAN_INFO_PROCESSED)
>  			*val = STM32_ADC_VREFINT_VOLTAGE * adc->vrefint.vrefint_cal / *val;
>  
>  		iio_device_release_direct_mode(indio_dev);
> @@ -1979,10 +1979,10 @@ static int stm32_adc_populate_int_ch(struct iio_dev *indio_dev, const char *ch_n
>  
>  	for (i = 0; i < STM32_ADC_INT_CH_NB; i++) {
>  		if (!strncmp(stm32_adc_ic[i].name, ch_name, STM32_ADC_CH_SZ)) {
> -			adc->int_ch[i] = chan;
> -
> -			if (stm32_adc_ic[i].idx != STM32_ADC_INT_CH_VREFINT)
> -				continue;
> +			if (stm32_adc_ic[i].idx != STM32_ADC_INT_CH_VREFINT) {
> +				adc->int_ch[i] = chan;
> +				break;
> +			}
>  
>  			/* Get calibration data for vrefint channel */
>  			ret = nvmem_cell_read_u16(&indio_dev->dev, "vrefint", &vrefint);
> @@ -1990,10 +1990,15 @@ static int stm32_adc_populate_int_ch(struct iio_dev *indio_dev, const char *ch_n
>  				return dev_err_probe(indio_dev->dev.parent, ret,
>  						     "nvmem access error\n");
>  			}
> -			if (ret == -ENOENT)
> -				dev_dbg(&indio_dev->dev, "vrefint calibration not found\n");
> -			else
> -				adc->vrefint.vrefint_cal = vrefint;
> +			if (ret == -ENOENT) {
> +				dev_dbg(&indio_dev->dev, "vrefint calibration not found. Skip vrefint channel\n");
> +				return ret;
> +			} else if (!vrefint) {
> +				dev_dbg(&indio_dev->dev, "Null vrefint calibration value. Skip vrefint channel\n");
> +				return -ENOENT;
> +			}
> +			adc->int_ch[i] = chan;
> +			adc->vrefint.vrefint_cal = vrefint;
>  		}
>  	}
>  
> @@ -2030,7 +2035,9 @@ static int stm32_adc_generic_chan_init(struct iio_dev *indio_dev,
>  			}
>  			strncpy(adc->chan_name[val], name, STM32_ADC_CH_SZ);
>  			ret = stm32_adc_populate_int_ch(indio_dev, name, val);
> -			if (ret)
> +			if (ret == -ENOENT)
> +				continue;
> +			else if (ret)
>  				goto err;
>  		} else if (ret != -EINVAL) {
>  			dev_err(&indio_dev->dev, "Invalid label %d\n", ret);
Jonathan Cameron June 11, 2022, 4:12 p.m. UTC | #2
On Thu, 9 Jun 2022 11:58:56 +0200
Olivier Moysan <olivier.moysan@foss.st.com> wrote:

> If the vrefint calibration is zero, the vrefint channel output value
> cannot be computed. Currently, in such case, the raw conversion value
> is returned, which is not relevant.
> Do not expose the vrefint channel when the output value cannot be
> computed, instead.
> 
> Fixes: 0e346b2cfa85 ("iio: adc: stm32-adc: add vrefint calibration support")
> 
No line break here. Fixes is part of the tag block (and a pull request sent with
this gap will get rejected). Fixed up whilst applying.
> Signed-off-by: Olivier Moysan <olivier.moysan@foss.st.com>

Applied to the fixes-togreg branch of iiogit.

I initially wondered if using -ENOENT for this was safe in that it couldn't
come from anywhere else.  Looks like it is given how little this function does
so fair enough.

Thanks,

Jonathan

> ---
>  drivers/iio/adc/stm32-adc.c | 27 +++++++++++++++++----------
>  1 file changed, 17 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c
> index a68ecbda6480..f13c112f540f 100644
> --- a/drivers/iio/adc/stm32-adc.c
> +++ b/drivers/iio/adc/stm32-adc.c
> @@ -1365,7 +1365,7 @@ static int stm32_adc_read_raw(struct iio_dev *indio_dev,
>  		else
>  			ret = -EINVAL;
>  
> -		if (mask == IIO_CHAN_INFO_PROCESSED && adc->vrefint.vrefint_cal)
> +		if (mask == IIO_CHAN_INFO_PROCESSED)
>  			*val = STM32_ADC_VREFINT_VOLTAGE * adc->vrefint.vrefint_cal / *val;
>  
>  		iio_device_release_direct_mode(indio_dev);
> @@ -1979,10 +1979,10 @@ static int stm32_adc_populate_int_ch(struct iio_dev *indio_dev, const char *ch_n
>  
>  	for (i = 0; i < STM32_ADC_INT_CH_NB; i++) {
>  		if (!strncmp(stm32_adc_ic[i].name, ch_name, STM32_ADC_CH_SZ)) {
> -			adc->int_ch[i] = chan;
> -
> -			if (stm32_adc_ic[i].idx != STM32_ADC_INT_CH_VREFINT)
> -				continue;
> +			if (stm32_adc_ic[i].idx != STM32_ADC_INT_CH_VREFINT) {
> +				adc->int_ch[i] = chan;
> +				break;
> +			}
>  
>  			/* Get calibration data for vrefint channel */
>  			ret = nvmem_cell_read_u16(&indio_dev->dev, "vrefint", &vrefint);
> @@ -1990,10 +1990,15 @@ static int stm32_adc_populate_int_ch(struct iio_dev *indio_dev, const char *ch_n
>  				return dev_err_probe(indio_dev->dev.parent, ret,
>  						     "nvmem access error\n");
>  			}
> -			if (ret == -ENOENT)
> -				dev_dbg(&indio_dev->dev, "vrefint calibration not found\n");
> -			else
> -				adc->vrefint.vrefint_cal = vrefint;
> +			if (ret == -ENOENT) {
> +				dev_dbg(&indio_dev->dev, "vrefint calibration not found. Skip vrefint channel\n");
> +				return ret;
> +			} else if (!vrefint) {
> +				dev_dbg(&indio_dev->dev, "Null vrefint calibration value. Skip vrefint channel\n");
> +				return -ENOENT;
> +			}
> +			adc->int_ch[i] = chan;
> +			adc->vrefint.vrefint_cal = vrefint;
>  		}
>  	}
>  
> @@ -2030,7 +2035,9 @@ static int stm32_adc_generic_chan_init(struct iio_dev *indio_dev,
>  			}
>  			strncpy(adc->chan_name[val], name, STM32_ADC_CH_SZ);
>  			ret = stm32_adc_populate_int_ch(indio_dev, name, val);
> -			if (ret)
> +			if (ret == -ENOENT)
> +				continue;
> +			else if (ret)
>  				goto err;
>  		} else if (ret != -EINVAL) {
>  			dev_err(&indio_dev->dev, "Invalid label %d\n", ret);
diff mbox series

Patch

diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c
index a68ecbda6480..f13c112f540f 100644
--- a/drivers/iio/adc/stm32-adc.c
+++ b/drivers/iio/adc/stm32-adc.c
@@ -1365,7 +1365,7 @@  static int stm32_adc_read_raw(struct iio_dev *indio_dev,
 		else
 			ret = -EINVAL;
 
-		if (mask == IIO_CHAN_INFO_PROCESSED && adc->vrefint.vrefint_cal)
+		if (mask == IIO_CHAN_INFO_PROCESSED)
 			*val = STM32_ADC_VREFINT_VOLTAGE * adc->vrefint.vrefint_cal / *val;
 
 		iio_device_release_direct_mode(indio_dev);
@@ -1979,10 +1979,10 @@  static int stm32_adc_populate_int_ch(struct iio_dev *indio_dev, const char *ch_n
 
 	for (i = 0; i < STM32_ADC_INT_CH_NB; i++) {
 		if (!strncmp(stm32_adc_ic[i].name, ch_name, STM32_ADC_CH_SZ)) {
-			adc->int_ch[i] = chan;
-
-			if (stm32_adc_ic[i].idx != STM32_ADC_INT_CH_VREFINT)
-				continue;
+			if (stm32_adc_ic[i].idx != STM32_ADC_INT_CH_VREFINT) {
+				adc->int_ch[i] = chan;
+				break;
+			}
 
 			/* Get calibration data for vrefint channel */
 			ret = nvmem_cell_read_u16(&indio_dev->dev, "vrefint", &vrefint);
@@ -1990,10 +1990,15 @@  static int stm32_adc_populate_int_ch(struct iio_dev *indio_dev, const char *ch_n
 				return dev_err_probe(indio_dev->dev.parent, ret,
 						     "nvmem access error\n");
 			}
-			if (ret == -ENOENT)
-				dev_dbg(&indio_dev->dev, "vrefint calibration not found\n");
-			else
-				adc->vrefint.vrefint_cal = vrefint;
+			if (ret == -ENOENT) {
+				dev_dbg(&indio_dev->dev, "vrefint calibration not found. Skip vrefint channel\n");
+				return ret;
+			} else if (!vrefint) {
+				dev_dbg(&indio_dev->dev, "Null vrefint calibration value. Skip vrefint channel\n");
+				return -ENOENT;
+			}
+			adc->int_ch[i] = chan;
+			adc->vrefint.vrefint_cal = vrefint;
 		}
 	}
 
@@ -2030,7 +2035,9 @@  static int stm32_adc_generic_chan_init(struct iio_dev *indio_dev,
 			}
 			strncpy(adc->chan_name[val], name, STM32_ADC_CH_SZ);
 			ret = stm32_adc_populate_int_ch(indio_dev, name, val);
-			if (ret)
+			if (ret == -ENOENT)
+				continue;
+			else if (ret)
 				goto err;
 		} else if (ret != -EINVAL) {
 			dev_err(&indio_dev->dev, "Invalid label %d\n", ret);