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 |
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 --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) {
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(-)