Unverified Commit 6e38a7e0 authored by Ranjani Sridharan's avatar Ranjani Sridharan Committed by Mark Brown
Browse files

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: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: default avatarPéter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: default avatarKai Vehmanen <kai.vehmanen@linux.intel.com>
Signed-off-by: default avatarBard 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: default avatarMark Brown <broonie@kernel.org>
parent 9822b4c9
Loading
Loading
Loading
Loading
+32 −4
Original line number Diff line number Diff line
@@ -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;