diff --git a/src/include/ipc/dai.h b/src/include/ipc/dai.h index d376da385..147afca22 100644 --- a/src/include/ipc/dai.h +++ b/src/include/ipc/dai.h @@ -73,6 +73,9 @@ */ #define SOF_DAI_CONFIG_FLAGS_2_STEP_STOP BIT(0) +#define SOF_DAI_QUIRK_IS_SET(flags, quirk) \ + (((flags & SOF_DAI_CONFIG_FLAGS_QUIRK_MASK) >> SOF_DAI_CONFIG_FLAGS_QUIRK_SHIFT) & quirk) + /** \brief Types of DAI */ enum sof_ipc_dai_type { SOF_DAI_INTEL_NONE = 0, /**< None */ diff --git a/src/include/sof/lib/dai.h b/src/include/sof/lib/dai.h index 5f4efd287..7ce7f1181 100644 --- a/src/include/sof/lib/dai.h +++ b/src/include/sof/lib/dai.h @@ -179,6 +179,15 @@ struct dai_data { void *dai_spec_config; /* dai specific config from the host */ uint64_t wallclock; /* wall clock at stream start */ + + /* + * flag indicating two-step stop/pause for DAI comp and DAI DMA. + * DAI stop occurs during STREAM_TRIG_STOP IPC and DMA stop during DAI_CONFIG IPC with + * the SOF_DAI_CONFIG_FLAGS_HW_FREE flag. + * DAI pause occurs during STREAM_TRIG_PAUSE IPC and DMA pause during DAI_CONFIG IPC with + * the SOF_DAI_CONFIG_FLAGS_PAUSE flag. + */ + bool delayed_dma_stop; }; struct dai { diff --git a/src/ipc/ipc3/dai.c b/src/ipc/ipc3/dai.c index 588910c86..384eae062 100644 --- a/src/ipc/ipc3/dai.c +++ b/src/ipc/ipc3/dai.c @@ -288,6 +288,16 @@ int dai_config(struct comp_dev *dev, struct ipc_config_dai *common_config, return 0; } + switch (config->flags & SOF_DAI_CONFIG_FLAGS_CMD_MASK) { + case SOF_DAI_CONFIG_FLAGS_HW_PARAMS: + /* set the delayed_dma_stop flag */ + if (SOF_DAI_QUIRK_IS_SET(config->flags, SOF_DAI_CONFIG_FLAGS_2_STEP_STOP)) + dd->delayed_dma_stop = true; + break; + default: + break; + } + if (dd->chan) { comp_info(dev, "dai_config(): Configured. dma channel index %d, ignore...", dd->chan->index);