Skip to content

Commit

Permalink
iio: adc: stm32: fix vrefint wrong calibration value handling
Browse files Browse the repository at this point in the history
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: 0e346b2 ("iio: adc: stm32-adc: add vrefint calibration support")
Signed-off-by: Olivier Moysan <olivier.moysan@foss.st.com>
Reviewed-by: Fabrice Gasnier <fabrice.gasnier@foss.st.com>
Link: https://lore.kernel.org/r/20220609095856.376961-1-olivier.moysan@foss.st.com
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
  • Loading branch information
Olivier Moysan authored and Jonathan Cameron committed Jun 19, 2022
1 parent 106b391 commit bc05f30
Showing 1 changed file with 17 additions and 10 deletions.
27 changes: 17 additions & 10 deletions drivers/iio/adc/stm32-adc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -1969,21 +1969,26 @@ 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);
if (ret && ret != -ENOENT) {
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;
}
}

Expand Down Expand Up @@ -2020,7 +2025,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);
Expand Down

0 comments on commit bc05f30

Please sign in to comment.