diff mbox series

[3/3] iio: adc: stm32-adc: skip adc-channels setup if none is present

Message ID 20230327083449.1098174-3-sean@geanix.com (mailing list archive)
State Changes Requested
Headers show
Series [1/3] iio: adc: stm32-adc: warn if dt uses legacy channel config | expand

Commit Message

Sean Nyekjaer March 27, 2023, 8:34 a.m. UTC
If only adc differential channels are defined driver will fail with
stm32-adc: probe of 48003000.adc:adc@0 failed with error -22

Fix this by skipping the initialization if no channels are defined.

This applies only to the legacy way of initializing adc channels.

Fixes: d7705f35448a ("iio: adc: stm32-adc: convert to device properties")
Signed-off-by: Sean Nyekjaer <sean@geanix.com>
---
 drivers/iio/adc/stm32-adc.c | 38 +++++++++++++++++++------------------
 1 file changed, 20 insertions(+), 18 deletions(-)

Comments

Olivier Moysan April 3, 2023, 9:29 a.m. UTC | #1
Hi Sean,

Thanks for your patch.
You're right. The DT updates to use the generic bindings are not yet 
upstreamed, and there are some regressions on legacy bindings support.
Please, find here after some comments.

BRs
Olivier

On 3/27/23 10:34, Sean Nyekjaer wrote:
> If only adc differential channels are defined driver will fail with
> stm32-adc: probe of 48003000.adc:adc@0 failed with error -22
> 
> Fix this by skipping the initialization if no channels are defined.
> 
> This applies only to the legacy way of initializing adc channels.
> 
> Fixes: d7705f35448a ("iio: adc: stm32-adc: convert to device properties")
> Signed-off-by: Sean Nyekjaer <sean@geanix.com>
> ---
>   drivers/iio/adc/stm32-adc.c | 38 +++++++++++++++++++------------------
>   1 file changed, 20 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c
> index a04fcb2dc80a..6d87cfaadb5d 100644
> --- a/drivers/iio/adc/stm32-adc.c
> +++ b/drivers/iio/adc/stm32-adc.c
> @@ -2065,28 +2065,30 @@ static int stm32_adc_legacy_chan_init(struct iio_dev *indio_dev,
>   		}
>   	}
>   

In PIO mode an extra channel channel is defined for timestamps. This 
additional channel must be ignored in channel count when initializing 
single and diff channels.

This can be handled in stm32_adc_legacy_chan_init() call from 
stm32_adc_legacy_chan_init() function:

         ret = stm32_adc_legacy_chan_init(indio_dev, adc, channels, 
timestamping ? num_channels - 1 : num_channels);

> -	ret = device_property_read_u32_array(dev, "st,adc-channels", chans,
> -					     nchans);
> -	if (ret)
> -		return ret;
> -
> -	for (c = 0; c < nchans; c++) {
> -		if (chans[c] >= adc_info->max_channels) {
> -			dev_err(&indio_dev->dev, "Invalid channel %d\n",
> -				chans[c]);
> -			return -EINVAL;
> -		}
> +	if (nchans - num_diff > 0) {
> +		ret = device_property_read_u32_array(dev, "st,adc-channels", chans,
> +				nchans);

num_se = nchans - num_diff represents single ended channels number.
single ended count has to be used also in 
device_property_read_u32_array() call:
ret = device_property_read_u32_array(dev, "st,adc-channels", chans, 
num_se);

> +		if (ret)
> +			return ret;
> 
> -		/* Channel can't be configured both as single-ended & diff */
> -		for (i = 0; i < num_diff; i++) {
> -			if (chans[c] == diff[i].vinp) {
> -				dev_err(&indio_dev->dev, "channel %d misconfigured\n",	chans[c]);
> +		for (c = 0; c < nchans; c++) {

and also in this for loop:
for (c = 0; c < num_se; c++) {

> +			if (chans[c] >= adc_info->max_channels) {
> +				dev_err(&indio_dev->dev, "Invalid channel %d\n",
> +						chans[c]);
>   				return -EINVAL;
>   			}
> -		}
> -		stm32_adc_chan_init_one(indio_dev, &channels[scan_index],
> +
> +			/* Channel can't be configured both as single-ended & diff */
> +			for (i = 0; i < num_diff; i++) {
> +				if (chans[c] == diff[i].vinp) {
> +					dev_err(&indio_dev->dev, "channel %d misconfigured\n",	chans[c]);
> +					return -EINVAL;
> +				}
> +			}
> +			stm32_adc_chan_init_one(indio_dev, &channels[scan_index],
>   					chans[c], 0, scan_index, false);
> -		scan_index++;
> +			scan_index++;
> +		}
>   	}
>   
>   	if (adc->nsmps > 0) {
diff mbox series

Patch

diff --git a/drivers/iio/adc/stm32-adc.c b/drivers/iio/adc/stm32-adc.c
index a04fcb2dc80a..6d87cfaadb5d 100644
--- a/drivers/iio/adc/stm32-adc.c
+++ b/drivers/iio/adc/stm32-adc.c
@@ -2065,28 +2065,30 @@  static int stm32_adc_legacy_chan_init(struct iio_dev *indio_dev,
 		}
 	}
 
-	ret = device_property_read_u32_array(dev, "st,adc-channels", chans,
-					     nchans);
-	if (ret)
-		return ret;
-
-	for (c = 0; c < nchans; c++) {
-		if (chans[c] >= adc_info->max_channels) {
-			dev_err(&indio_dev->dev, "Invalid channel %d\n",
-				chans[c]);
-			return -EINVAL;
-		}
+	if (nchans - num_diff > 0) {
+		ret = device_property_read_u32_array(dev, "st,adc-channels", chans,
+				nchans);
+		if (ret)
+			return ret;
 
-		/* Channel can't be configured both as single-ended & diff */
-		for (i = 0; i < num_diff; i++) {
-			if (chans[c] == diff[i].vinp) {
-				dev_err(&indio_dev->dev, "channel %d misconfigured\n",	chans[c]);
+		for (c = 0; c < nchans; c++) {
+			if (chans[c] >= adc_info->max_channels) {
+				dev_err(&indio_dev->dev, "Invalid channel %d\n",
+						chans[c]);
 				return -EINVAL;
 			}
-		}
-		stm32_adc_chan_init_one(indio_dev, &channels[scan_index],
+
+			/* Channel can't be configured both as single-ended & diff */
+			for (i = 0; i < num_diff; i++) {
+				if (chans[c] == diff[i].vinp) {
+					dev_err(&indio_dev->dev, "channel %d misconfigured\n",	chans[c]);
+					return -EINVAL;
+				}
+			}
+			stm32_adc_chan_init_one(indio_dev, &channels[scan_index],
 					chans[c], 0, scan_index, false);
-		scan_index++;
+			scan_index++;
+		}
 	}
 
 	if (adc->nsmps > 0) {