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 <ranjani.sridharan@linux.intel.com> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com> All: stable@vger.kernel.org # 6.10.x 6.11.x Link: https://patch.msgid.link/20241016032910.14601-3-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
9822b4c90d
commit
6e38a7e098
@ -370,6 +370,13 @@ static int non_hda_dai_hw_params_data(struct snd_pcm_substream *substream,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sdev = widget_to_sdev(w);
|
||||
hext_stream = ops->get_hext_stream(sdev, cpu_dai, substream);
|
||||
|
||||
/* nothing more to do if the link is already prepared */
|
||||
if (hext_stream && hext_stream->link_prepared)
|
||||
return 0;
|
||||
|
||||
/* use HDaudio stream handling */
|
||||
ret = hda_dai_hw_params_data(substream, params, cpu_dai, data, flags);
|
||||
if (ret < 0) {
|
||||
@ -377,7 +384,6 @@ static int non_hda_dai_hw_params_data(struct snd_pcm_substream *substream,
|
||||
return ret;
|
||||
}
|
||||
|
||||
sdev = widget_to_sdev(w);
|
||||
if (sdev->dspless_mode_selected)
|
||||
return 0;
|
||||
|
||||
@ -482,6 +488,31 @@ int sdw_hda_dai_hw_params(struct snd_pcm_substream *substream,
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
ops = hda_dai_get_ops(substream, cpu_dai);
|
||||
if (!ops) {
|
||||
dev_err(cpu_dai->dev, "DAI widget ops not set\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sdev = widget_to_sdev(w);
|
||||
hext_stream = ops->get_hext_stream(sdev, cpu_dai, substream);
|
||||
|
||||
/* nothing more to do if the link is already prepared */
|
||||
if (hext_stream && hext_stream->link_prepared)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* reset the PCMSyCM registers to handle a prepare callback when the PCM is restarted
|
||||
* due to xruns or after a call to snd_pcm_drain/drop()
|
||||
*/
|
||||
ret = hdac_bus_eml_sdw_map_stream_ch(sof_to_bus(sdev), link_id, cpu_dai->id,
|
||||
0, 0, substream->stream);
|
||||
if (ret < 0) {
|
||||
dev_err(cpu_dai->dev, "%s: hdac_bus_eml_sdw_map_stream_ch failed %d\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
data.dai_index = (link_id << 8) | cpu_dai->id;
|
||||
data.dai_node_id = intel_alh_id;
|
||||
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,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ops = hda_dai_get_ops(substream, cpu_dai);
|
||||
sdev = widget_to_sdev(w);
|
||||
hext_stream = ops->get_hext_stream(sdev, cpu_dai, substream);
|
||||
|
||||
if (!hext_stream)
|
||||
return -ENODEV;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user