Commit bc05f30f authored by Olivier Moysan's avatar Olivier Moysan Committed by Jonathan Cameron
Browse files

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



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: 0e346b2c ("iio: adc: stm32-adc: add vrefint calibration support")
Signed-off-by: default avatarOlivier Moysan <olivier.moysan@foss.st.com>
Reviewed-by: default avatarFabrice 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: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 106b391e
Loading
Loading
Loading
Loading
+17 −10
Original line number Diff line number Diff line
@@ -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);
@@ -1969,10 +1969,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)) {
			if (stm32_adc_ic[i].idx != STM32_ADC_INT_CH_VREFINT) {
				adc->int_ch[i] = chan;

			if (stm32_adc_ic[i].idx != STM32_ADC_INT_CH_VREFINT)
				continue;
				break;
			}

			/* Get calibration data for vrefint channel */
			ret = nvmem_cell_read_u16(&indio_dev->dev, "vrefint", &vrefint);
@@ -1980,9 +1980,14 @@ 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
			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;
		}
	}
@@ -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);