Skip to content

Commit 6e38a7e

Browse files
ranj063broonie
authored andcommitted
ASoC: SOF: Intel: hda: Handle prepare without close for non-HDA DAI's
When a PCM is restarted after a snd_pcm_drain/snd_pcm_drop(), the prepare callback will be invoked and the hw_params will be set again. For the HDA DAI's, the hw_params function handles this case already but not for the non-HDA DAI's. So, add the check for link_prepared to verify if the hw_params should be done again or not. Additionally, for SDW DAI's reset the PCMSyCM registers as would be done in the case of a start after a hw_free. Signed-off-by: Ranjani Sridharan <[email protected]> Reviewed-by: Péter Ujfalusi <[email protected]> Reviewed-by: Kai Vehmanen <[email protected]> Signed-off-by: Bard Liao <[email protected]> All: [email protected] # 6.10.x 6.11.x Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 9822b4c commit 6e38a7e

File tree

1 file changed

+32
-4
lines changed

1 file changed

+32
-4
lines changed

sound/soc/sof/intel/hda-dai.c

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -370,14 +370,20 @@ static int non_hda_dai_hw_params_data(struct snd_pcm_substream *substream,
370370
return -EINVAL;
371371
}
372372

373+
sdev = widget_to_sdev(w);
374+
hext_stream = ops->get_hext_stream(sdev, cpu_dai, substream);
375+
376+
/* nothing more to do if the link is already prepared */
377+
if (hext_stream && hext_stream->link_prepared)
378+
return 0;
379+
373380
/* use HDaudio stream handling */
374381
ret = hda_dai_hw_params_data(substream, params, cpu_dai, data, flags);
375382
if (ret < 0) {
376383
dev_err(cpu_dai->dev, "%s: hda_dai_hw_params_data failed: %d\n", __func__, ret);
377384
return ret;
378385
}
379386

380-
sdev = widget_to_sdev(w);
381387
if (sdev->dspless_mode_selected)
382388
return 0;
383389

@@ -482,6 +488,31 @@ int sdw_hda_dai_hw_params(struct snd_pcm_substream *substream,
482488
int ret;
483489
int i;
484490

491+
ops = hda_dai_get_ops(substream, cpu_dai);
492+
if (!ops) {
493+
dev_err(cpu_dai->dev, "DAI widget ops not set\n");
494+
return -EINVAL;
495+
}
496+
497+
sdev = widget_to_sdev(w);
498+
hext_stream = ops->get_hext_stream(sdev, cpu_dai, substream);
499+
500+
/* nothing more to do if the link is already prepared */
501+
if (hext_stream && hext_stream->link_prepared)
502+
return 0;
503+
504+
/*
505+
* reset the PCMSyCM registers to handle a prepare callback when the PCM is restarted
506+
* due to xruns or after a call to snd_pcm_drain/drop()
507+
*/
508+
ret = hdac_bus_eml_sdw_map_stream_ch(sof_to_bus(sdev), link_id, cpu_dai->id,
509+
0, 0, substream->stream);
510+
if (ret < 0) {
511+
dev_err(cpu_dai->dev, "%s: hdac_bus_eml_sdw_map_stream_ch failed %d\n",
512+
__func__, ret);
513+
return ret;
514+
}
515+
485516
data.dai_index = (link_id << 8) | cpu_dai->id;
486517
data.dai_node_id = intel_alh_id;
487518
ret = non_hda_dai_hw_params_data(substream, params, cpu_dai, &data, flags);
@@ -490,10 +521,7 @@ int sdw_hda_dai_hw_params(struct snd_pcm_substream *substream,
490521
return ret;
491522
}
492523

493-
ops = hda_dai_get_ops(substream, cpu_dai);
494-
sdev = widget_to_sdev(w);
495524
hext_stream = ops->get_hext_stream(sdev, cpu_dai, substream);
496-
497525
if (!hext_stream)
498526
return -ENODEV;
499527

0 commit comments

Comments
 (0)