From 567cafa8b06cbefdd73f7db856bf71560abeaf9d Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Thu, 16 Feb 2023 15:14:46 +0200 Subject: [PATCH 1/2] dai-zephyr: fix state dependent logic in trigger handling The component state dependent actions in dai_comp_trigger_internal() are not working as intended as dev->state is already updated to new target state at the start of the function. Update the logic to correctly evaluate previous state in trigger actions. Signed-off-by: Kai Vehmanen --- src/audio/dai-zephyr.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/audio/dai-zephyr.c b/src/audio/dai-zephyr.c index bbe0e7aec3dd..b1d2098dbf67 100644 --- a/src/audio/dai-zephyr.c +++ b/src/audio/dai-zephyr.c @@ -1014,6 +1014,7 @@ static void dai_update_start_position(struct comp_dev *dev) static int dai_comp_trigger_internal(struct comp_dev *dev, int cmd) { struct dai_data *dd = comp_get_drvdata(dev); + int prev_state = dev->state; int ret; comp_dbg(dev, "dai_comp_trigger_internal(), command = %u", cmd); @@ -1101,7 +1102,7 @@ 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); - if (dev->state == COMP_STATE_ACTIVE) { + if (prev_state == COMP_STATE_ACTIVE) { ret = dma_stop(dd->chan->dma->z_dev, dd->chan->index); } else { comp_warn(dev, "dma was stopped earlier"); @@ -1111,7 +1112,7 @@ static int dai_comp_trigger_internal(struct comp_dev *dev, int cmd) break; case COMP_TRIGGER_PAUSE: comp_dbg(dev, "dai_comp_trigger_internal(), PAUSE"); - if (dev->state == COMP_STATE_ACTIVE) { + if (prev_state == COMP_STATE_ACTIVE) { ret = dma_suspend(dd->chan->dma->z_dev, dd->chan->index); } else { comp_warn(dev, "dma was stopped earlier"); From f104114bc39497c4fcda62a4dd903e1038265dce Mon Sep 17 00:00:00 2001 From: Kai Vehmanen Date: Thu, 16 Feb 2023 16:14:14 +0200 Subject: [PATCH 2/2] dai-zephyr: call dma_stop() also if previous state is COMP_STATE_PAUSED To ensure DMA is stopped in all cases, we need to call dma_stop() also when the previous state is PAUSED. With Zephyr commit ec9d94e06d4a ("dma: Document expected behavior of start/stop") the dma interface semantics were clarified. Build on this and call dma_stop() in all cases and make the code simpler to follow. Signed-off-by: Kai Vehmanen --- src/audio/dai-zephyr.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/audio/dai-zephyr.c b/src/audio/dai-zephyr.c index b1d2098dbf67..bb2581af654c 100644 --- a/src/audio/dai-zephyr.c +++ b/src/audio/dai-zephyr.c @@ -1102,9 +1102,8 @@ 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); - if (prev_state == COMP_STATE_ACTIVE) { - ret = dma_stop(dd->chan->dma->z_dev, dd->chan->index); - } else { + ret = dma_stop(dd->chan->dma->z_dev, dd->chan->index); + if (ret) { comp_warn(dev, "dma was stopped earlier"); ret = 0; }