@@ -197,9 +197,9 @@ static int hda_link_dai_widget_update(struct sof_intel_hda_stream *hda_stream,
197197
198198 /* set up/free DAI widget and send DAI_CONFIG IPC */
199199 if (widget_setup )
200- return hda_ctrl_dai_widget_setup (w );
200+ return hda_ctrl_dai_widget_setup (w , SOF_DAI_CONFIG_FLAGS_2_STEP_STOP );
201201
202- return hda_ctrl_dai_widget_free (w );
202+ return hda_ctrl_dai_widget_free (w , SOF_DAI_CONFIG_FLAGS_NONE );
203203}
204204
205205static int hda_link_hw_params (struct snd_pcm_substream * substream ,
@@ -287,6 +287,36 @@ static int hda_link_pcm_prepare(struct snd_pcm_substream *substream,
287287 dai );
288288}
289289
290+ static int hda_link_dai_config_pause_push_ipc (struct snd_soc_dapm_widget * w )
291+ {
292+ struct snd_sof_widget * swidget = w -> dobj .private ;
293+ struct snd_soc_component * component = swidget -> scomp ;
294+ struct snd_sof_dev * sdev = snd_soc_component_get_drvdata (component );
295+ struct sof_ipc_dai_config * config ;
296+ struct snd_sof_dai * sof_dai ;
297+ struct sof_ipc_reply reply ;
298+ int ret ;
299+
300+ sof_dai = swidget -> private ;
301+
302+ if (!sof_dai || !sof_dai -> dai_config ) {
303+ dev_err (sdev -> dev , "No config for DAI %s\n" , w -> name );
304+ return - EINVAL ;
305+ }
306+
307+ config = & sof_dai -> dai_config [sof_dai -> current_config ];
308+
309+ /* set PAUSE command flag */
310+ config -> flags = FIELD_PREP (SOF_DAI_CONFIG_FLAGS_CMD_MASK , SOF_DAI_CONFIG_FLAGS_PAUSE );
311+
312+ ret = sof_ipc_tx_message (sdev -> ipc , config -> hdr .cmd , config , config -> hdr .size ,
313+ & reply , sizeof (reply ));
314+ if (ret < 0 )
315+ dev_err (sdev -> dev , "DAI config for %s failed during pause push\n" , w -> name );
316+
317+ return ret ;
318+ }
319+
290320static int hda_link_pcm_trigger (struct snd_pcm_substream * substream ,
291321 int cmd , struct snd_soc_dai * dai )
292322{
@@ -312,6 +342,9 @@ static int hda_link_pcm_trigger(struct snd_pcm_substream *substream,
312342 hda_stream = hstream_to_sof_hda_stream (link_dev );
313343
314344 dev_dbg (dai -> dev , "In %s cmd=%d\n" , __func__ , cmd );
345+
346+ w = snd_soc_dai_get_widget (dai , substream -> stream );
347+
315348 switch (cmd ) {
316349 case SNDRV_PCM_TRIGGER_RESUME :
317350 /* set up hw_params */
@@ -329,10 +362,7 @@ static int hda_link_pcm_trigger(struct snd_pcm_substream *substream,
329362 break ;
330363 case SNDRV_PCM_TRIGGER_SUSPEND :
331364 case SNDRV_PCM_TRIGGER_STOP :
332- if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK )
333- w = dai -> playback_widget ;
334- else
335- w = dai -> capture_widget ;
365+ snd_hdac_ext_link_stream_clear (link_dev );
336366
337367 /*
338368 * free DAI widget during stop/suspend to keep widget use_count's balanced.
@@ -347,10 +377,13 @@ static int hda_link_pcm_trigger(struct snd_pcm_substream *substream,
347377 }
348378
349379 link_dev -> link_prepared = 0 ;
350-
351- fallthrough ;
380+ break ;
352381 case SNDRV_PCM_TRIGGER_PAUSE_PUSH :
353382 snd_hdac_ext_link_stream_clear (link_dev );
383+
384+ ret = hda_link_dai_config_pause_push_ipc (w );
385+ if (ret < 0 )
386+ return ret ;
354387 break ;
355388 default :
356389 return - EINVAL ;
@@ -451,9 +484,9 @@ static int ssp_dai_setup_or_free(struct snd_pcm_substream *substream, struct snd
451484 return 0 ;
452485
453486 if (setup )
454- return hda_ctrl_dai_widget_setup (w );
487+ return hda_ctrl_dai_widget_setup (w , SOF_DAI_CONFIG_FLAGS_NONE );
455488
456- return hda_ctrl_dai_widget_free (w );
489+ return hda_ctrl_dai_widget_free (w , SOF_DAI_CONFIG_FLAGS_NONE );
457490}
458491
459492static int ssp_dai_startup (struct snd_pcm_substream * substream ,
0 commit comments