Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: adc: stm32-dfsdm: fix multiple channel initialization

When several channels are registered (e.g. via st,adc-channels property):
- channels array is wrongly filled in. Only 1st element in array is being
initialized with last registered channel.
Fix it by passing reference to relevant channel (e.g. array[index]).
- only last initialized channel can work properly (e.g. unique 'ch_id'
is used). Converting any other channel result in conversion timeout.
Fix it by getting rid of 'ch_id', use chan->channel instead.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
Acked-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Fabrice Gasnier and committed by
Jonathan Cameron
0645af1b 179858ef

+21 -18
+21 -18
drivers/iio/adc/stm32-dfsdm-adc.c
··· 54 54 struct stm32_dfsdm *dfsdm; 55 55 const struct stm32_dfsdm_dev_data *dev_data; 56 56 unsigned int fl_id; 57 - unsigned int ch_id; 58 57 59 58 /* ADC specific */ 60 59 unsigned int oversamp; ··· 383 384 { 384 385 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); 385 386 struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id]; 386 - struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[adc->ch_id]; 387 + struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[chan->channel]; 387 388 unsigned int sample_freq = adc->sample_freq; 388 389 unsigned int spi_freq; 389 390 int ret; ··· 418 419 return len; 419 420 } 420 421 421 - static int stm32_dfsdm_start_conv(struct stm32_dfsdm_adc *adc, bool dma) 422 + static int stm32_dfsdm_start_conv(struct stm32_dfsdm_adc *adc, 423 + const struct iio_chan_spec *chan, 424 + bool dma) 422 425 { 423 426 struct regmap *regmap = adc->dfsdm->regmap; 424 427 int ret; 425 428 unsigned int dma_en = 0, cont_en = 0; 426 429 427 - ret = stm32_dfsdm_start_channel(adc->dfsdm, adc->ch_id); 430 + ret = stm32_dfsdm_start_channel(adc->dfsdm, chan->channel); 428 431 if (ret < 0) 429 432 return ret; 430 433 431 434 ret = stm32_dfsdm_filter_configure(adc->dfsdm, adc->fl_id, 432 - adc->ch_id); 435 + chan->channel); 433 436 if (ret < 0) 434 437 goto stop_channels; 435 438 ··· 465 464 466 465 regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id), 467 466 DFSDM_CR1_RCONT_MASK, 0); 468 - stm32_dfsdm_stop_channel(adc->dfsdm, adc->ch_id); 467 + stm32_dfsdm_stop_channel(adc->dfsdm, chan->channel); 469 468 470 469 return ret; 471 470 } 472 471 473 - static void stm32_dfsdm_stop_conv(struct stm32_dfsdm_adc *adc) 472 + static void stm32_dfsdm_stop_conv(struct stm32_dfsdm_adc *adc, 473 + const struct iio_chan_spec *chan) 474 474 { 475 475 struct regmap *regmap = adc->dfsdm->regmap; 476 476 ··· 484 482 regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id), 485 483 DFSDM_CR1_RCONT_MASK, 0); 486 484 487 - stm32_dfsdm_stop_channel(adc->dfsdm, adc->ch_id); 485 + stm32_dfsdm_stop_channel(adc->dfsdm, chan->channel); 488 486 } 489 487 490 488 static int stm32_dfsdm_set_watermark(struct iio_dev *indio_dev, ··· 611 609 static int stm32_dfsdm_postenable(struct iio_dev *indio_dev) 612 610 { 613 611 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); 612 + const struct iio_chan_spec *chan = &indio_dev->channels[0]; 614 613 int ret; 615 614 616 615 /* Reset adc buffer index */ ··· 621 618 if (ret < 0) 622 619 return ret; 623 620 624 - ret = stm32_dfsdm_start_conv(adc, true); 621 + ret = stm32_dfsdm_start_conv(adc, chan, true); 625 622 if (ret) { 626 623 dev_err(&indio_dev->dev, "Can't start conversion\n"); 627 624 goto stop_dfsdm; ··· 638 635 return 0; 639 636 640 637 err_stop_conv: 641 - stm32_dfsdm_stop_conv(adc); 638 + stm32_dfsdm_stop_conv(adc, chan); 642 639 stop_dfsdm: 643 640 stm32_dfsdm_stop_dfsdm(adc->dfsdm); 644 641 ··· 648 645 static int stm32_dfsdm_predisable(struct iio_dev *indio_dev) 649 646 { 650 647 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); 648 + const struct iio_chan_spec *chan = &indio_dev->channels[0]; 651 649 652 650 if (adc->dma_chan) 653 651 dmaengine_terminate_all(adc->dma_chan); 654 652 655 - stm32_dfsdm_stop_conv(adc); 653 + stm32_dfsdm_stop_conv(adc, chan); 656 654 657 655 stm32_dfsdm_stop_dfsdm(adc->dfsdm); 658 656 ··· 734 730 if (ret < 0) 735 731 goto stop_dfsdm; 736 732 737 - ret = stm32_dfsdm_start_conv(adc, false); 733 + ret = stm32_dfsdm_start_conv(adc, chan, false); 738 734 if (ret < 0) { 739 735 regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR2(adc->fl_id), 740 736 DFSDM_CR2_REOCIE_MASK, DFSDM_CR2_REOCIE(0)); ··· 755 751 else 756 752 ret = IIO_VAL_INT; 757 753 758 - stm32_dfsdm_stop_conv(adc); 754 + stm32_dfsdm_stop_conv(adc, chan); 759 755 760 756 stop_dfsdm: 761 757 stm32_dfsdm_stop_dfsdm(adc->dfsdm); ··· 769 765 { 770 766 struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); 771 767 struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id]; 772 - struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[adc->ch_id]; 768 + struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[chan->channel]; 773 769 unsigned int spi_freq = adc->spi_freq; 774 770 int ret = -EINVAL; 775 771 ··· 976 972 } 977 973 ch->scan_type.realbits = 24; 978 974 ch->scan_type.storagebits = 32; 979 - adc->ch_id = ch->channel; 980 975 981 976 return stm32_dfsdm_chan_configure(adc->dfsdm, 982 977 &adc->dfsdm->ch_list[ch->channel]); ··· 1004 1001 } 1005 1002 ch->info_mask_separate = BIT(IIO_CHAN_INFO_SAMP_FREQ); 1006 1003 1007 - d_ch = &adc->dfsdm->ch_list[adc->ch_id]; 1004 + d_ch = &adc->dfsdm->ch_list[ch->channel]; 1008 1005 if (d_ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL) 1009 1006 adc->spi_freq = adc->dfsdm->spi_master_freq; 1010 1007 ··· 1045 1042 return -ENOMEM; 1046 1043 1047 1044 for (chan_idx = 0; chan_idx < num_ch; chan_idx++) { 1048 - ch->scan_index = chan_idx; 1049 - ret = stm32_dfsdm_adc_chan_init_one(indio_dev, ch); 1045 + ch[chan_idx].scan_index = chan_idx; 1046 + ret = stm32_dfsdm_adc_chan_init_one(indio_dev, &ch[chan_idx]); 1050 1047 if (ret < 0) { 1051 1048 dev_err(&indio_dev->dev, "Channels init failed\n"); 1052 1049 return ret;