Skip to content

Commit da68b84

Browse files
committed
ASoC: SOF: add DAI_HW_FREE IPC command
There is an STREAM_PCM_FREE IPC command which is sent to a SOF pipeline in trigger stop. Here we add an new DAI_HW_FREE command which will be sent to SOF DAI component. The command is sent from BE DAI link so codec driver has chance to run code in the mute_stream() callback before the DAI_HW_FREE IPC command is sent. This is the call flow of pcm playback: DROP: sof's trigger() => send STREAM_TRIG_STOP => send STREAM_PCM_FREE HW_FREE: sof's hw_free() (FE) codec's mute_stream() sof's hw_free() (BE) => send DAI_HW_FREE codec's hw_free() Signed-off-by: Brent Lu <brent.lu@intel.com>
1 parent 0cc90aa commit da68b84

File tree

4 files changed

+44
-2
lines changed

4 files changed

+44
-2
lines changed

include/sound/sof/dai.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,11 @@ struct sof_ipc_dai_config {
8585
};
8686
} __packed;
8787

88+
/* DAI hardware free */
89+
struct sof_ipc_dai_hw_free {
90+
struct sof_ipc_cmd_hdr hdr;
91+
uint32_t type; /**< DAI type - enum sof_ipc_dai_type */
92+
uint32_t dai_index; /**< index of this type dai */
93+
} __packed;
94+
8895
#endif

include/sound/sof/header.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
/* DAI messages */
9090
#define SOF_IPC_DAI_CONFIG SOF_CMD_TYPE(0x001)
9191
#define SOF_IPC_DAI_LOOPBACK SOF_CMD_TYPE(0x002)
92+
#define SOF_IPC_DAI_HW_FREE SOF_CMD_TYPE(0x004)
9293

9394
/* stream */
9495
#define SOF_IPC_STREAM_PCM_PARAMS SOF_CMD_TYPE(0x001)

sound/soc/sof/ipc.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ static void ipc_log_header(struct device *dev, u8 *text, u32 cmd)
168168
str2 = "CONFIG"; break;
169169
case SOF_IPC_DAI_LOOPBACK:
170170
str2 = "LOOPBACK"; break;
171+
case SOF_IPC_DAI_HW_FREE:
172+
str2 = "HW_FREE"; break;
171173
default:
172174
str2 = "unknown type"; break;
173175
}

sound/soc/sof/pcm.c

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,9 +288,41 @@ static int sof_pcm_hw_free(struct snd_soc_component *component,
288288
struct snd_sof_pcm *spcm;
289289
int ret, err = 0;
290290

291-
/* nothing to do for BE */
292-
if (rtd->dai_link->no_pcm)
291+
if (rtd->dai_link->no_pcm) {
292+
struct snd_sof_dai *sdai;
293+
struct sof_ipc_dai_config *dai_config;
294+
struct sof_ipc_dai_hw_free dai_hw_free;
295+
struct sof_ipc_reply reply;
296+
297+
sdai = snd_sof_find_dai(component, rtd->dai_link->name);
298+
if (!sdai)
299+
return -EINVAL;
300+
301+
dai_config = sdai->dai_config;
302+
303+
dev_dbg(component->dev, "dai: free dai type %d index %d\n",
304+
dai_config->type, dai_config->dai_index);
305+
306+
memset(&dai_hw_free, 0, sizeof(dai_hw_free));
307+
308+
dai_hw_free.hdr.size = sizeof(dai_hw_free);
309+
dai_hw_free.hdr.cmd = SOF_IPC_GLB_DAI_MSG | SOF_IPC_DAI_HW_FREE;
310+
dai_hw_free.type = dai_config->type;
311+
dai_hw_free.dai_index = dai_config->dai_index;
312+
313+
/* send IPC to the DSP */
314+
ret = sof_ipc_tx_message(sdev->ipc, dai_hw_free.hdr.cmd,
315+
&dai_hw_free, sizeof(dai_hw_free),
316+
&reply, sizeof(reply));
317+
if (ret < 0) {
318+
dev_err(component->dev,
319+
"error: hw free ipc failed for dai type %d index %d\n",
320+
dai_config->type, dai_config->dai_index);
321+
return ret;
322+
}
323+
293324
return 0;
325+
}
294326

295327
spcm = snd_sof_find_spcm_dai(component, rtd);
296328
if (!spcm)

0 commit comments

Comments
 (0)