Skip to content

Commit a609676

Browse files
Fabrice Gasnierjic23
authored andcommitted
iio: adc: stm32-dfsdm: add support for scan mode
In order to support multiple channels in buffer mode, add support for scan mode. This is precursor patch to ease support of triggered buffer mode. Currently, only audio uses buffer mode: Regular continuous conversions with a single channel (per filter). DFSDM hardware supports scan mode (only) with injected conversions. Conversions can be launched by software (JSWSTART), trigger or synchronously with filter 0 (e.g. JSYNC). Continuous conversion mode isn't available for injected. Signed-off-by: Fabrice Gasnier <[email protected]> Signed-off-by: Jonathan Cameron <[email protected]>
1 parent 9491f75 commit a609676

File tree

1 file changed

+142
-40
lines changed

1 file changed

+142
-40
lines changed

drivers/iio/adc/stm32-dfsdm-adc.c

Lines changed: 142 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040

4141
/* Filter configuration */
4242
#define DFSDM_CR1_CFG_MASK (DFSDM_CR1_RCH_MASK | DFSDM_CR1_RCONT_MASK | \
43-
DFSDM_CR1_RSYNC_MASK)
43+
DFSDM_CR1_RSYNC_MASK | DFSDM_CR1_JSYNC_MASK | \
44+
DFSDM_CR1_JSCAN_MASK)
4445

4546
enum sd_converter_type {
4647
DFSDM_AUDIO,
@@ -58,6 +59,8 @@ struct stm32_dfsdm_adc {
5859
struct stm32_dfsdm *dfsdm;
5960
const struct stm32_dfsdm_dev_data *dev_data;
6061
unsigned int fl_id;
62+
unsigned int nconv;
63+
unsigned long smask;
6164

6265
/* ADC specific */
6366
unsigned int oversamp;
@@ -204,19 +207,39 @@ static int stm32_dfsdm_set_osrs(struct stm32_dfsdm_filter *fl,
204207
return 0;
205208
}
206209

207-
static int stm32_dfsdm_start_channel(struct stm32_dfsdm *dfsdm,
208-
unsigned int ch_id)
210+
static int stm32_dfsdm_start_channel(struct stm32_dfsdm_adc *adc)
209211
{
210-
return regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(ch_id),
211-
DFSDM_CHCFGR1_CHEN_MASK,
212-
DFSDM_CHCFGR1_CHEN(1));
212+
struct iio_dev *indio_dev = iio_priv_to_dev(adc);
213+
struct regmap *regmap = adc->dfsdm->regmap;
214+
const struct iio_chan_spec *chan;
215+
unsigned int bit;
216+
int ret;
217+
218+
for_each_set_bit(bit, &adc->smask, sizeof(adc->smask) * BITS_PER_BYTE) {
219+
chan = indio_dev->channels + bit;
220+
ret = regmap_update_bits(regmap, DFSDM_CHCFGR1(chan->channel),
221+
DFSDM_CHCFGR1_CHEN_MASK,
222+
DFSDM_CHCFGR1_CHEN(1));
223+
if (ret < 0)
224+
return ret;
225+
}
226+
227+
return 0;
213228
}
214229

215-
static void stm32_dfsdm_stop_channel(struct stm32_dfsdm *dfsdm,
216-
unsigned int ch_id)
230+
static void stm32_dfsdm_stop_channel(struct stm32_dfsdm_adc *adc)
217231
{
218-
regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(ch_id),
219-
DFSDM_CHCFGR1_CHEN_MASK, DFSDM_CHCFGR1_CHEN(0));
232+
struct iio_dev *indio_dev = iio_priv_to_dev(adc);
233+
struct regmap *regmap = adc->dfsdm->regmap;
234+
const struct iio_chan_spec *chan;
235+
unsigned int bit;
236+
237+
for_each_set_bit(bit, &adc->smask, sizeof(adc->smask) * BITS_PER_BYTE) {
238+
chan = indio_dev->channels + bit;
239+
regmap_update_bits(regmap, DFSDM_CHCFGR1(chan->channel),
240+
DFSDM_CHCFGR1_CHEN_MASK,
241+
DFSDM_CHCFGR1_CHEN(0));
242+
}
220243
}
221244

222245
static int stm32_dfsdm_chan_configure(struct stm32_dfsdm *dfsdm,
@@ -241,9 +264,10 @@ static int stm32_dfsdm_chan_configure(struct stm32_dfsdm *dfsdm,
241264
DFSDM_CHCFGR1_CHINSEL(ch->alt_si));
242265
}
243266

244-
static int stm32_dfsdm_start_filter(struct stm32_dfsdm *dfsdm,
267+
static int stm32_dfsdm_start_filter(struct stm32_dfsdm_adc *adc,
245268
unsigned int fl_id)
246269
{
270+
struct stm32_dfsdm *dfsdm = adc->dfsdm;
247271
int ret;
248272

249273
/* Enable filter */
@@ -252,7 +276,11 @@ static int stm32_dfsdm_start_filter(struct stm32_dfsdm *dfsdm,
252276
if (ret < 0)
253277
return ret;
254278

255-
/* Start conversion */
279+
/* Nothing more to do for injected (scan mode/triggered) conversions */
280+
if (adc->nconv > 1)
281+
return 0;
282+
283+
/* Software start (single or continuous) regular conversion */
256284
return regmap_update_bits(dfsdm->regmap, DFSDM_CR1(fl_id),
257285
DFSDM_CR1_RSWSTART_MASK,
258286
DFSDM_CR1_RSWSTART(1));
@@ -267,12 +295,14 @@ static void stm32_dfsdm_stop_filter(struct stm32_dfsdm *dfsdm,
267295
}
268296

269297
static int stm32_dfsdm_filter_configure(struct stm32_dfsdm_adc *adc,
270-
unsigned int fl_id, unsigned int ch_id)
298+
unsigned int fl_id)
271299
{
272300
struct iio_dev *indio_dev = iio_priv_to_dev(adc);
273301
struct regmap *regmap = adc->dfsdm->regmap;
274302
struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[fl_id];
275303
u32 cr1;
304+
const struct iio_chan_spec *chan;
305+
unsigned int bit, jchg = 0;
276306
int ret;
277307

278308
/* Average integrator oversampling */
@@ -292,14 +322,59 @@ static int stm32_dfsdm_filter_configure(struct stm32_dfsdm_adc *adc,
292322
if (ret)
293323
return ret;
294324

295-
/* No scan mode supported for the moment */
296-
cr1 = DFSDM_CR1_RCH(ch_id);
325+
/*
326+
* DFSDM modes configuration W.R.T audio/iio type modes
327+
* ----------------------------------------------------------------
328+
* Modes | regular | regular | injected | injected |
329+
* | | continuous | | + scan |
330+
* --------------|---------|--------------|----------|------------|
331+
* single conv | x | | | |
332+
* (1 chan) | | | | |
333+
* --------------|---------|--------------|----------|------------|
334+
* 1 Audio chan | | sample freq | | |
335+
* | | or sync_mode | | |
336+
* --------------|---------|--------------|----------|------------|
337+
* 1 IIO chan | | sample freq | trigger | |
338+
* | | or sync_mode | | |
339+
* --------------|---------|--------------|----------|------------|
340+
* 2+ IIO chans | | | | trigger or |
341+
* | | | | sync_mode |
342+
* ----------------------------------------------------------------
343+
*/
344+
if (adc->nconv == 1) {
345+
bit = __ffs(adc->smask);
346+
chan = indio_dev->channels + bit;
297347

298-
/* Continuous conversions triggered by SPI clock in buffer mode */
299-
if (indio_dev->currentmode & INDIO_BUFFER_SOFTWARE)
300-
cr1 |= DFSDM_CR1_RCONT(1);
348+
/* Use regular conversion for single channel without trigger */
349+
cr1 = DFSDM_CR1_RCH(chan->channel);
301350

302-
cr1 |= DFSDM_CR1_RSYNC(fl->sync_mode);
351+
/* Continuous conversions triggered by SPI clk in buffer mode */
352+
if (indio_dev->currentmode & INDIO_BUFFER_SOFTWARE)
353+
cr1 |= DFSDM_CR1_RCONT(1);
354+
355+
cr1 |= DFSDM_CR1_RSYNC(fl->sync_mode);
356+
} else {
357+
/* Use injected conversion for multiple channels */
358+
for_each_set_bit(bit, &adc->smask,
359+
sizeof(adc->smask) * BITS_PER_BYTE) {
360+
chan = indio_dev->channels + bit;
361+
jchg |= BIT(chan->channel);
362+
}
363+
ret = regmap_write(regmap, DFSDM_JCHGR(fl_id), jchg);
364+
if (ret < 0)
365+
return ret;
366+
367+
/* Use scan mode for multiple channels */
368+
cr1 = DFSDM_CR1_JSCAN(1);
369+
370+
/*
371+
* Continuous conversions not supported in injected mode:
372+
* - use conversions in sync with filter 0
373+
*/
374+
if (!fl->sync_mode)
375+
return -EINVAL;
376+
cr1 |= DFSDM_CR1_JSYNC(fl->sync_mode);
377+
}
303378

304379
return regmap_update_bits(regmap, DFSDM_CR1(fl_id), DFSDM_CR1_CFG_MASK,
305380
cr1);
@@ -428,21 +503,20 @@ static ssize_t dfsdm_adc_audio_set_spiclk(struct iio_dev *indio_dev,
428503
return len;
429504
}
430505

431-
static int stm32_dfsdm_start_conv(struct stm32_dfsdm_adc *adc,
432-
const struct iio_chan_spec *chan)
506+
static int stm32_dfsdm_start_conv(struct stm32_dfsdm_adc *adc)
433507
{
434508
struct regmap *regmap = adc->dfsdm->regmap;
435509
int ret;
436510

437-
ret = stm32_dfsdm_start_channel(adc->dfsdm, chan->channel);
511+
ret = stm32_dfsdm_start_channel(adc);
438512
if (ret < 0)
439513
return ret;
440514

441-
ret = stm32_dfsdm_filter_configure(adc, adc->fl_id, chan->channel);
515+
ret = stm32_dfsdm_filter_configure(adc, adc->fl_id);
442516
if (ret < 0)
443517
goto stop_channels;
444518

445-
ret = stm32_dfsdm_start_filter(adc->dfsdm, adc->fl_id);
519+
ret = stm32_dfsdm_start_filter(adc, adc->fl_id);
446520
if (ret < 0)
447521
goto filter_unconfigure;
448522

@@ -452,13 +526,12 @@ static int stm32_dfsdm_start_conv(struct stm32_dfsdm_adc *adc,
452526
regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
453527
DFSDM_CR1_CFG_MASK, 0);
454528
stop_channels:
455-
stm32_dfsdm_stop_channel(adc->dfsdm, chan->channel);
529+
stm32_dfsdm_stop_channel(adc);
456530

457531
return ret;
458532
}
459533

460-
static void stm32_dfsdm_stop_conv(struct stm32_dfsdm_adc *adc,
461-
const struct iio_chan_spec *chan)
534+
static void stm32_dfsdm_stop_conv(struct stm32_dfsdm_adc *adc)
462535
{
463536
struct regmap *regmap = adc->dfsdm->regmap;
464537

@@ -467,7 +540,7 @@ static void stm32_dfsdm_stop_conv(struct stm32_dfsdm_adc *adc,
467540
regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
468541
DFSDM_CR1_CFG_MASK, 0);
469542

470-
stm32_dfsdm_stop_channel(adc->dfsdm, chan->channel);
543+
stm32_dfsdm_stop_channel(adc);
471544
}
472545

473546
static int stm32_dfsdm_set_watermark(struct iio_dev *indio_dev,
@@ -557,8 +630,7 @@ static int stm32_dfsdm_adc_dma_start(struct iio_dev *indio_dev)
557630
{
558631
struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
559632
struct dma_slave_config config = {
560-
.src_addr = (dma_addr_t)adc->dfsdm->phys_base +
561-
DFSDM_RDATAR(adc->fl_id),
633+
.src_addr = (dma_addr_t)adc->dfsdm->phys_base,
562634
.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES,
563635
};
564636
struct dma_async_tx_descriptor *desc;
@@ -571,6 +643,10 @@ static int stm32_dfsdm_adc_dma_start(struct iio_dev *indio_dev)
571643
dev_dbg(&indio_dev->dev, "%s size=%d watermark=%d\n", __func__,
572644
adc->buf_sz, adc->buf_sz / 2);
573645

646+
if (adc->nconv == 1)
647+
config.src_addr += DFSDM_RDATAR(adc->fl_id);
648+
else
649+
config.src_addr += DFSDM_JDATAR(adc->fl_id);
574650
ret = dmaengine_slave_config(adc->dma_chan, &config);
575651
if (ret)
576652
return ret;
@@ -595,9 +671,20 @@ static int stm32_dfsdm_adc_dma_start(struct iio_dev *indio_dev)
595671
/* Issue pending DMA requests */
596672
dma_async_issue_pending(adc->dma_chan);
597673

598-
/* Enable DMA transfer*/
599-
ret = regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR1(adc->fl_id),
600-
DFSDM_CR1_RDMAEN_MASK, DFSDM_CR1_RDMAEN_MASK);
674+
if (adc->nconv == 1) {
675+
/* Enable regular DMA transfer*/
676+
ret = regmap_update_bits(adc->dfsdm->regmap,
677+
DFSDM_CR1(adc->fl_id),
678+
DFSDM_CR1_RDMAEN_MASK,
679+
DFSDM_CR1_RDMAEN_MASK);
680+
} else {
681+
/* Enable injected DMA transfer*/
682+
ret = regmap_update_bits(adc->dfsdm->regmap,
683+
DFSDM_CR1(adc->fl_id),
684+
DFSDM_CR1_JDMAEN_MASK,
685+
DFSDM_CR1_JDMAEN_MASK);
686+
}
687+
601688
if (ret < 0)
602689
goto err_stop_dma;
603690

@@ -617,14 +704,26 @@ static void stm32_dfsdm_adc_dma_stop(struct iio_dev *indio_dev)
617704
return;
618705

619706
regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR1(adc->fl_id),
620-
DFSDM_CR1_RDMAEN_MASK, 0);
707+
DFSDM_CR1_RDMAEN_MASK | DFSDM_CR1_JDMAEN_MASK, 0);
621708
dmaengine_terminate_all(adc->dma_chan);
622709
}
623710

711+
static int stm32_dfsdm_update_scan_mode(struct iio_dev *indio_dev,
712+
const unsigned long *scan_mask)
713+
{
714+
struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
715+
716+
adc->nconv = bitmap_weight(scan_mask, indio_dev->masklength);
717+
adc->smask = *scan_mask;
718+
719+
dev_dbg(&indio_dev->dev, "nconv=%d mask=%lx\n", adc->nconv, *scan_mask);
720+
721+
return 0;
722+
}
723+
624724
static int stm32_dfsdm_postenable(struct iio_dev *indio_dev)
625725
{
626726
struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
627-
const struct iio_chan_spec *chan = &indio_dev->channels[0];
628727
int ret;
629728

630729
/* Reset adc buffer index */
@@ -646,7 +745,7 @@ static int stm32_dfsdm_postenable(struct iio_dev *indio_dev)
646745
goto stop_dfsdm;
647746
}
648747

649-
ret = stm32_dfsdm_start_conv(adc, chan);
748+
ret = stm32_dfsdm_start_conv(adc);
650749
if (ret) {
651750
dev_err(&indio_dev->dev, "Can't start conversion\n");
652751
goto err_stop_dma;
@@ -668,9 +767,8 @@ static int stm32_dfsdm_postenable(struct iio_dev *indio_dev)
668767
static int stm32_dfsdm_predisable(struct iio_dev *indio_dev)
669768
{
670769
struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
671-
const struct iio_chan_spec *chan = &indio_dev->channels[0];
672770

673-
stm32_dfsdm_stop_conv(adc, chan);
771+
stm32_dfsdm_stop_conv(adc);
674772

675773
stm32_dfsdm_adc_dma_stop(indio_dev);
676774

@@ -756,7 +854,9 @@ static int stm32_dfsdm_single_conv(struct iio_dev *indio_dev,
756854
if (ret < 0)
757855
goto stop_dfsdm;
758856

759-
ret = stm32_dfsdm_start_conv(adc, chan);
857+
adc->nconv = 1;
858+
adc->smask = BIT(chan->scan_index);
859+
ret = stm32_dfsdm_start_conv(adc);
760860
if (ret < 0) {
761861
regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR2(adc->fl_id),
762862
DFSDM_CR2_REOCIE_MASK, DFSDM_CR2_REOCIE(0));
@@ -777,7 +877,7 @@ static int stm32_dfsdm_single_conv(struct iio_dev *indio_dev,
777877
else
778878
ret = IIO_VAL_INT;
779879

780-
stm32_dfsdm_stop_conv(adc, chan);
880+
stm32_dfsdm_stop_conv(adc);
781881

782882
stop_dfsdm:
783883
stm32_dfsdm_stop_dfsdm(adc->dfsdm);
@@ -882,11 +982,13 @@ static const struct iio_info stm32_dfsdm_info_audio = {
882982
.hwfifo_set_watermark = stm32_dfsdm_set_watermark,
883983
.read_raw = stm32_dfsdm_read_raw,
884984
.write_raw = stm32_dfsdm_write_raw,
985+
.update_scan_mode = stm32_dfsdm_update_scan_mode,
885986
};
886987

887988
static const struct iio_info stm32_dfsdm_info_adc = {
888989
.read_raw = stm32_dfsdm_read_raw,
889990
.write_raw = stm32_dfsdm_write_raw,
991+
.update_scan_mode = stm32_dfsdm_update_scan_mode,
890992
};
891993

892994
static irqreturn_t stm32_dfsdm_irq(int irq, void *arg)

0 commit comments

Comments
 (0)