diff --git a/src/audio/dai-legacy.c b/src/audio/dai-legacy.c index 278690036..2bea70627 100644 --- a/src/audio/dai-legacy.c +++ b/src/audio/dai-legacy.c @@ -234,6 +234,8 @@ static void dai_free(struct comp_dev *dev) dma_put(dd->dma); + dai_release_llp_slot(dev); + dai_put(dd->dai); if (dd->dai_spec_config) diff --git a/src/audio/dai-zephyr.c b/src/audio/dai-zephyr.c index aaef5eca6..3d097c4a4 100644 --- a/src/audio/dai-zephyr.c +++ b/src/audio/dai-zephyr.c @@ -367,6 +367,8 @@ static void dai_free(struct comp_dev *dev) dma_put(dd->dma); + dai_release_llp_slot(dev); + dai_put(dd->dai); rfree(dd->dai_spec_config); diff --git a/src/include/sof/lib/dai-legacy.h b/src/include/sof/lib/dai-legacy.h index c040a3cc6..995c1d52e 100644 --- a/src/include/sof/lib/dai-legacy.h +++ b/src/include/sof/lib/dai-legacy.h @@ -570,6 +570,11 @@ int dai_position(struct comp_dev *dev, struct sof_ipc_stream_posn *posn); * \brief update dai dma position for host driver. */ void dai_dma_position_update(struct comp_dev *dev); + +/** + * \brief release llp slot + */ +void dai_release_llp_slot(struct comp_dev *dev); /** @}*/ #endif /* __SOF_LIB_DAI_LEGACY_H__ */ diff --git a/src/include/sof/lib/dai-zephyr.h b/src/include/sof/lib/dai-zephyr.h index 60a6d3804..cca91170b 100644 --- a/src/include/sof/lib/dai-zephyr.h +++ b/src/include/sof/lib/dai-zephyr.h @@ -278,6 +278,11 @@ int dai_position(struct comp_dev *dev, struct sof_ipc_stream_posn *posn); * \brief update dai dma position for host driver. */ void dai_dma_position_update(struct comp_dev *dev); + +/** + * \brief release llp slot + */ +void dai_release_llp_slot(struct comp_dev *dev); /** @}*/ #endif /* __SOF_LIB_DAI_ZEPHYR_H__ */ diff --git a/src/ipc/ipc3/dai.c b/src/ipc/ipc3/dai.c index 335b6a0f1..ad6e23650 100644 --- a/src/ipc/ipc3/dai.c +++ b/src/ipc/ipc3/dai.c @@ -397,3 +397,5 @@ int dai_position(struct comp_dev *dev, struct sof_ipc_stream_posn *posn) } void dai_dma_position_update(struct comp_dev *dev) { } + +void dai_release_llp_slot(struct comp_dev *dev) { } diff --git a/src/ipc/ipc4/dai.c b/src/ipc/ipc4/dai.c index b7fc4f993..244076b80 100644 --- a/src/ipc/ipc4/dai.c +++ b/src/ipc/ipc4/dai.c @@ -158,12 +158,9 @@ void dai_dma_release(struct comp_dev *dev) if (dd->slot_info.node_id) { k_spinlock_key_t key; - /* reset llp position to 0 in memory window for reset state. - * clear node id and llp position to 0 when dai is free - */ + /* reset llp position to 0 in memory window for reset state. */ memset_s(&slot, sizeof(slot), 0, sizeof(slot)); - if (dev->state == COMP_STATE_PAUSED) - slot.node_id = dd->slot_info.node_id; + slot.node_id = dd->slot_info.node_id; key = k_spin_lock(&sof_get()->fw_reg_lock); mailbox_sw_regs_write(dd->slot_info.reg_offset, &slot, sizeof(slot)); @@ -193,6 +190,26 @@ void dai_dma_release(struct comp_dev *dev) } } +void dai_release_llp_slot(struct comp_dev *dev) +{ + struct dai_data *dd = comp_get_drvdata(dev); + struct ipc4_llp_reading_slot slot; + k_spinlock_key_t key; + + if (!dd->slot_info.node_id) + return; + + memset_s(&slot, sizeof(slot), 0, sizeof(slot)); + + /* clear node id for released llp slot */ + key = k_spin_lock(&sof_get()->fw_reg_lock); + mailbox_sw_regs_write(dd->slot_info.reg_offset, &slot, sizeof(slot)); + k_spin_unlock(&sof_get()->fw_reg_lock, key); + + dd->slot_info.reg_offset = 0; + dd->slot_info.node_id = 0; +} + static int dai_get_unused_llp_slot(struct comp_dev *dev, union ipc4_connector_node_id *node) {