Browse Source

drivers: audio: dmic_mcux: init active_buf_idx when setting up dma

In case the dmic had previous been run and stopped,
make sure active_buf_idx is initialized to 0 when
setting up dma on start, otherwise the dma callback
can return the wrong buffer.

Also purge the rx_queue before freeing the slab buffers,
to minimize risk of any async read request getting
back a slab buffer that is freed.

Signed-off-by: Mike J. Chen <mjchen@google.com>
pull/92498/head
Mike J. Chen 7 months ago committed by Daniel DeGrasse
parent
commit
9eaed805c1
  1. 12
      drivers/audio/dmic_mcux.c

12
drivers/audio/dmic_mcux.c

@ -125,6 +125,8 @@ static int dmic_mcux_enable_dma(struct mcux_dmic_drv_data *drv_data, bool enable @@ -125,6 +125,8 @@ static int dmic_mcux_enable_dma(struct mcux_dmic_drv_data *drv_data, bool enable
}
} else {
if (dma_stop(pdm_channel->dma, pdm_channel->dma_chan)) {
LOG_ERR("Error stopping DMA for HW channel %d",
hw_chan);
ret = -EIO;
}
}
@ -181,14 +183,17 @@ static int dmic_mcux_stop(struct mcux_dmic_drv_data *drv_data) @@ -181,14 +183,17 @@ static int dmic_mcux_stop(struct mcux_dmic_drv_data *drv_data)
/* Disable DMA */
dmic_mcux_enable_dma(drv_data, false);
/* Purge the RX queue first, to minimize possibility of
* an async read request returning a ptr to a buffer we're
* about to free.
*/
k_msgq_purge(drv_data->rx_queue);
/* Free all memory slabs */
for (uint32_t i = 0; i < CONFIG_DMIC_MCUX_DMA_BUFFERS; i++) {
k_mem_slab_free(drv_data->mem_slab, drv_data->dma_bufs[i]);
}
/* Purge the RX queue as well. */
k_msgq_purge(drv_data->rx_queue);
drv_data->dmic_state = DMIC_STATE_CONFIGURED;
return 0;
@ -283,6 +288,7 @@ static int dmic_mcux_setup_dma(const struct device *dev) @@ -283,6 +288,7 @@ static int dmic_mcux_setup_dma(const struct device *dev)
uint8_t hw_chan;
int ret = 0;
drv_data->active_buf_idx = 0;
/* Setup DMA configuration common between all channels */
dma_cfg.user_data = drv_data;

Loading…
Cancel
Save