Unverified Commit 2960ee5c authored by Pierre-Louis Bossart's avatar Pierre-Louis Bossart Committed by Mark Brown
Browse files

ASoC: SOF: Intel: hda-dai: add helpers for SoundWire callbacks



During the hw_params and hw_free stages, we need to map the stream tag
and channels in the PCMSyCM registers.

The trigger callback is just a wrapper.

Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: default avatarBard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: default avatarRander Wang <rander.wang@intel.com>
Link: https://lore.kernel.org/r/20230807210959.506849-15-pierre-louis.bossart@linux.intel.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent bb0b992c
Loading
Loading
Loading
Loading
+72 −0
Original line number Diff line number Diff line
@@ -429,6 +429,78 @@ static const struct snd_soc_dai_ops dmic_dai_ops = {
	.prepare = non_hda_dai_prepare,
};

int sdw_hda_dai_hw_params(struct snd_pcm_substream *substream,
			  struct snd_pcm_hw_params *params,
			  struct snd_soc_dai *cpu_dai,
			  int link_id)
{
	struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(cpu_dai, substream->stream);
	const struct hda_dai_widget_dma_ops *ops;
	struct hdac_ext_stream *hext_stream;
	struct snd_sof_dev *sdev;
	int ret;

	ret = non_hda_dai_hw_params(substream, params, cpu_dai);
	if (ret < 0) {
		dev_err(cpu_dai->dev, "%s: non_hda_dai_hw_params failed %d\n", __func__, ret);
		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;

	/* in the case of SoundWire we need to program the PCMSyCM registers */
	ret = hdac_bus_eml_sdw_map_stream_ch(sof_to_bus(sdev), link_id, cpu_dai->id,
					     GENMASK(params_channels(params) - 1, 0),
					     hdac_stream(hext_stream)->stream_tag,
					     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;
	}

	return 0;
}

int sdw_hda_dai_hw_free(struct snd_pcm_substream *substream,
			struct snd_soc_dai *cpu_dai,
			int link_id)
{
	struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(cpu_dai, substream->stream);
	struct snd_sof_dev *sdev;
	int ret;

	ret = hda_dai_hw_free(substream, cpu_dai);
	if (ret < 0) {
		dev_err(cpu_dai->dev, "%s: non_hda_dai_hw_free failed %d\n", __func__, ret);
		return ret;
	}

	sdev = widget_to_sdev(w);

	/* in the case of SoundWire we need to reset the PCMSyCM registers */
	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;
	}

	return 0;
}

int sdw_hda_dai_trigger(struct snd_pcm_substream *substream, int cmd,
			struct snd_soc_dai *cpu_dai)
{
	return hda_dai_trigger(substream, cmd, cpu_dai);
}

static int hda_dai_suspend(struct hdac_bus *bus)
{
	struct snd_soc_pcm_runtime *rtd;
+12 −0
Original line number Diff line number Diff line
@@ -824,6 +824,18 @@ static inline bool hda_common_check_sdw_irq(struct snd_sof_dev *sdev)

#endif

int sdw_hda_dai_hw_params(struct snd_pcm_substream *substream,
			  struct snd_pcm_hw_params *params,
			  struct snd_soc_dai *cpu_dai,
			  int link_id);

int sdw_hda_dai_hw_free(struct snd_pcm_substream *substream,
			struct snd_soc_dai *cpu_dai,
			int link_id);

int sdw_hda_dai_trigger(struct snd_pcm_substream *substream, int cmd,
			struct snd_soc_dai *cpu_dai);

/* common dai driver */
extern struct snd_soc_dai_driver skl_dai[];
int hda_dsp_dais_suspend(struct snd_sof_dev *sdev);