diff --git a/src/audio/dai-zephyr.c b/src/audio/dai-zephyr.c index 3d097c4a42a5..0a8d618a4e9e 100644 --- a/src/audio/dai-zephyr.c +++ b/src/audio/dai-zephyr.c @@ -1014,9 +1014,11 @@ static int dai_comp_trigger_internal(struct comp_dev *dev, int cmd) /* only start the DAI if we are not XRUN handling */ if (dd->xrun == 0) { /* recover valid start position */ - ret = dma_stop(dd->chan->dma->z_dev, dd->chan->index); - if (ret < 0) - return ret; + if (dev->state == COMP_STATE_ACTIVE) { + ret = dma_stop(dd->chan->dma->z_dev, dd->chan->index); + if (ret < 0) + return ret; + } /* dma_config needed after stop */ ret = dma_config(dd->chan->dma->z_dev, dd->chan->index, dd->z_config); @@ -1054,12 +1056,23 @@ static int dai_comp_trigger_internal(struct comp_dev *dev, int cmd) dai_trigger_op(dd->dai, cmd, dev->direction); #else dai_trigger_op(dd->dai, cmd, dev->direction); - ret = dma_stop(dd->chan->dma->z_dev, dd->chan->index); + if (dev->state == COMP_STATE_ACTIVE) { + ret = dma_stop(dd->chan->dma->z_dev, dd->chan->index); + } else { + comp_warn(dev, "dma was stopped earlier"); + ret = 0; + } #endif break; case COMP_TRIGGER_PAUSE: comp_dbg(dev, "dai_comp_trigger_internal(), PAUSE"); - ret = dma_suspend(dd->chan->dma->z_dev, dd->chan->index); + if (dev->state == COMP_STATE_ACTIVE) { + ret = dma_suspend(dd->chan->dma->z_dev, dd->chan->index); + } else { + comp_warn(dev, "dma was stopped earlier"); + ret = 0; + } + dai_trigger_op(dd->dai, cmd, dev->direction); break; case COMP_TRIGGER_PRE_START: diff --git a/src/audio/host-zephyr.c b/src/audio/host-zephyr.c index 54f73e45cb1f..c01cb18bd39d 100644 --- a/src/audio/host-zephyr.c +++ b/src/audio/host-zephyr.c @@ -627,10 +627,13 @@ static int host_trigger(struct comp_dev *dev, int cmd) break; case COMP_TRIGGER_STOP: case COMP_TRIGGER_XRUN: - ret = dma_stop(hd->chan->dma->z_dev, hd->chan->index); - if (ret < 0) - comp_err(dev, "host_trigger(): dma stop failed: %d", - ret); + if (dev->state == COMP_STATE_ACTIVE) { + ret = dma_stop(hd->chan->dma->z_dev, hd->chan->index); + if (ret < 0) + comp_err(dev, "host_trigger(): dma stop failed: %d", + ret); + } + break; default: break; @@ -1048,7 +1051,8 @@ static int host_reset(struct comp_dev *dev) comp_dbg(dev, "host_reset()"); if (hd->chan) { - dma_stop(hd->chan->dma->z_dev, hd->chan->index); + if (dev->state == COMP_STATE_ACTIVE) + dma_stop(hd->chan->dma->z_dev, hd->chan->index); /* remove callback */ notifier_unregister(dev, hd->chan, NOTIFIER_ID_DMA_COPY); diff --git a/src/ipc/ipc4/dai.c b/src/ipc/ipc4/dai.c index 5be3ff8dc140..1f9ff09c8558 100644 --- a/src/ipc/ipc4/dai.c +++ b/src/ipc/ipc4/dai.c @@ -172,7 +172,9 @@ void dai_dma_release(struct comp_dev *dev) * TODO: refine power management when stream is paused */ #if CONFIG_ZEPHYR_NATIVE_DRIVERS - dma_stop(dd->chan->dma->z_dev, dd->chan->index); + /* if reset is after pause dma has already been stopped */ + if (dev->state != COMP_STATE_PAUSED) + dma_stop(dd->chan->dma->z_dev, dd->chan->index); /* remove callback */ notifier_unregister(dev, dd->chan, NOTIFIER_ID_DMA_COPY);