1
0
Fork 0

iio: adc: stm32-dfsdm: move dma enable from start_conv() to start_dma()

Move DMA enable (e.g. set RDMAEN bit) away from start_conv() that is used
for both buffer and single conversions. Thus, single conv rely on
interrupt, not dma.
Note: take care to prepare all DMA stuff and set RDMAEN before starting
filter (can be set only when DFEN=0).

This is precursor patch to ease support of triggered buffer mode.

Signed-off-by: Fabrice Gasnier <fabrice.gasnier@st.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
hifive-unleashed-5.2
Fabrice Gasnier 2019-03-21 17:47:24 +01:00 committed by Jonathan Cameron
parent 6f2c4a59d9
commit caf9c1e598
1 changed files with 38 additions and 39 deletions

View File

@ -429,12 +429,10 @@ static ssize_t dfsdm_adc_audio_set_spiclk(struct iio_dev *indio_dev,
}
static int stm32_dfsdm_start_conv(struct stm32_dfsdm_adc *adc,
const struct iio_chan_spec *chan,
bool dma)
const struct iio_chan_spec *chan)
{
struct regmap *regmap = adc->dfsdm->regmap;
int ret;
unsigned int dma_en = 0;
ret = stm32_dfsdm_start_channel(adc->dfsdm, chan->channel);
if (ret < 0)
@ -444,25 +442,12 @@ static int stm32_dfsdm_start_conv(struct stm32_dfsdm_adc *adc,
if (ret < 0)
goto stop_channels;
if (dma) {
/* Enable DMA transfer*/
dma_en = DFSDM_CR1_RDMAEN(1);
}
/* Enable DMA transfer*/
ret = regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
DFSDM_CR1_RDMAEN_MASK, dma_en);
ret = stm32_dfsdm_start_filter(adc->dfsdm, adc->fl_id);
if (ret < 0)
goto filter_unconfigure;
ret = stm32_dfsdm_start_filter(adc->dfsdm, adc->fl_id);
if (ret < 0)
goto stop_dma;
return 0;
stop_dma:
regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
DFSDM_CR1_RDMAEN_MASK, 0);
filter_unconfigure:
regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
DFSDM_CR1_CFG_MASK, 0);
@ -479,10 +464,6 @@ static void stm32_dfsdm_stop_conv(struct stm32_dfsdm_adc *adc,
stm32_dfsdm_stop_filter(adc->dfsdm, adc->fl_id);
/* Clean conversion options */
regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
DFSDM_CR1_RDMAEN_MASK, 0);
regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id),
DFSDM_CR1_CFG_MASK, 0);
@ -599,15 +580,36 @@ static int stm32_dfsdm_adc_dma_start(struct iio_dev *indio_dev)
cookie = dmaengine_submit(desc);
ret = dma_submit_error(cookie);
if (ret) {
dmaengine_terminate_all(adc->dma_chan);
return ret;
}
if (ret)
goto err_stop_dma;
/* Issue pending DMA requests */
dma_async_issue_pending(adc->dma_chan);
/* Enable DMA transfer*/
ret = regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR1(adc->fl_id),
DFSDM_CR1_RDMAEN_MASK, DFSDM_CR1_RDMAEN_MASK);
if (ret < 0)
goto err_stop_dma;
return 0;
err_stop_dma:
dmaengine_terminate_all(adc->dma_chan);
return ret;
}
static void stm32_dfsdm_adc_dma_stop(struct iio_dev *indio_dev)
{
struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
if (!adc->dma_chan)
return;
regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR1(adc->fl_id),
DFSDM_CR1_RDMAEN_MASK, 0);
dmaengine_terminate_all(adc->dma_chan);
}
static int stm32_dfsdm_postenable(struct iio_dev *indio_dev)
@ -623,24 +625,22 @@ static int stm32_dfsdm_postenable(struct iio_dev *indio_dev)
if (ret < 0)
return ret;
ret = stm32_dfsdm_start_conv(adc, chan, true);
ret = stm32_dfsdm_adc_dma_start(indio_dev);
if (ret) {
dev_err(&indio_dev->dev, "Can't start conversion\n");
dev_err(&indio_dev->dev, "Can't start DMA\n");
goto stop_dfsdm;
}
if (adc->dma_chan) {
ret = stm32_dfsdm_adc_dma_start(indio_dev);
if (ret) {
dev_err(&indio_dev->dev, "Can't start DMA\n");
goto err_stop_conv;
}
ret = stm32_dfsdm_start_conv(adc, chan);
if (ret) {
dev_err(&indio_dev->dev, "Can't start conversion\n");
goto err_stop_dma;
}
return 0;
err_stop_conv:
stm32_dfsdm_stop_conv(adc, chan);
err_stop_dma:
stm32_dfsdm_adc_dma_stop(indio_dev);
stop_dfsdm:
stm32_dfsdm_stop_dfsdm(adc->dfsdm);
@ -652,11 +652,10 @@ static int stm32_dfsdm_predisable(struct iio_dev *indio_dev)
struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
const struct iio_chan_spec *chan = &indio_dev->channels[0];
if (adc->dma_chan)
dmaengine_terminate_all(adc->dma_chan);
stm32_dfsdm_stop_conv(adc, chan);
stm32_dfsdm_adc_dma_stop(indio_dev);
stm32_dfsdm_stop_dfsdm(adc->dfsdm);
return 0;
@ -736,7 +735,7 @@ static int stm32_dfsdm_single_conv(struct iio_dev *indio_dev,
if (ret < 0)
goto stop_dfsdm;
ret = stm32_dfsdm_start_conv(adc, chan, false);
ret = stm32_dfsdm_start_conv(adc, chan);
if (ret < 0) {
regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR2(adc->fl_id),
DFSDM_CR2_REOCIE_MASK, DFSDM_CR2_REOCIE(0));