The existing code for HDAudio DAIs cannot be extended to other types of DAIs, specific programming sequences need to be abstracted away.
This patch hides the mechanism to determine the multi-link structure related to the DAI and program the LOSIDV register. An added benefit is that we can remove all references to the codec DAI from what should be a CPU dai configuration only.
Signed-off-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Ranjani Sridharan ranjani.sridharan@linux.intel.com Reviewed-by: Péter Ujfalusi peter.ujfalusi@linux.intel.com Reviewed-by: Bard Liao yung-chuan.liao@linux.intel.com --- sound/soc/sof/intel/hda-dai-ops.c | 14 ++++++++++++++ sound/soc/sof/intel/hda-dai.c | 28 ++++++---------------------- sound/soc/sof/intel/hda.h | 4 ++++ 3 files changed, 24 insertions(+), 22 deletions(-)
diff --git a/sound/soc/sof/intel/hda-dai-ops.c b/sound/soc/sof/intel/hda-dai-ops.c index 88fee1e256b0..f3513796c189 100644 --- a/sound/soc/sof/intel/hda-dai-ops.c +++ b/sound/soc/sof/intel/hda-dai-ops.c @@ -209,6 +209,16 @@ static unsigned int hda_calc_stream_format(struct snd_sof_dev *sdev, return format_val; }
+static struct hdac_ext_link *hda_get_hlink(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct hdac_bus *bus = sof_to_bus(sdev); + + return snd_hdac_ext_bus_get_hlink_by_name(bus, codec_dai->component->name); +} + static int hda_ipc4_pre_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai, struct snd_pcm_substream *substream, int cmd) { @@ -344,6 +354,7 @@ static const struct hda_dai_widget_dma_ops hda_ipc4_dma_ops = { .post_trigger = hda_ipc4_post_trigger, .codec_dai_set_stream = hda_codec_dai_set_stream, .calc_stream_format = hda_calc_stream_format, + .get_hlink = hda_get_hlink, };
static const struct hda_dai_widget_dma_ops hda_ipc4_chain_dma_ops = { @@ -355,6 +366,7 @@ static const struct hda_dai_widget_dma_ops hda_ipc4_chain_dma_ops = { .trigger = hda_trigger, .codec_dai_set_stream = hda_codec_dai_set_stream, .calc_stream_format = hda_calc_stream_format, + .get_hlink = hda_get_hlink, };
static int hda_ipc3_post_trigger(struct snd_sof_dev *sdev, struct snd_soc_dai *cpu_dai, @@ -390,6 +402,7 @@ static const struct hda_dai_widget_dma_ops hda_ipc3_dma_ops = { .post_trigger = hda_ipc3_post_trigger, .codec_dai_set_stream = hda_codec_dai_set_stream, .calc_stream_format = hda_calc_stream_format, + .get_hlink = hda_get_hlink, };
static struct hdac_ext_stream * @@ -418,6 +431,7 @@ static const struct hda_dai_widget_dma_ops hda_dspless_dma_ops = { .setup_hext_stream = hda_dspless_setup_hext_stream, .codec_dai_set_stream = hda_codec_dai_set_stream, .calc_stream_format = hda_calc_stream_format, + .get_hlink = hda_get_hlink, };
#endif diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index d9a77a253350..3297dea493aa 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -109,12 +109,9 @@ hda_dai_get_ops(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai
static int hda_link_dma_cleanup(struct snd_pcm_substream *substream, struct hdac_ext_stream *hext_stream, - struct snd_soc_dai *cpu_dai, - struct snd_soc_dai *codec_dai) + struct snd_soc_dai *cpu_dai) { const struct hda_dai_widget_dma_ops *ops = hda_dai_get_ops(substream, cpu_dai); - struct hdac_stream *hstream = &hext_stream->hstream; - struct hdac_bus *bus = hstream->bus; struct sof_intel_hda_stream *hda_stream; struct hdac_ext_link *hlink; struct snd_sof_dev *sdev; @@ -127,7 +124,7 @@ static int hda_link_dma_cleanup(struct snd_pcm_substream *substream,
sdev = dai_to_sdev(substream, cpu_dai);
- hlink = snd_hdac_ext_bus_get_hlink_by_name(bus, codec_dai->component->name); + hlink = ops->get_hlink(sdev, substream); if (!hlink) return -EINVAL;
@@ -152,13 +149,10 @@ static int hda_link_dma_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *cpu_dai) { const struct hda_dai_widget_dma_ops *ops = hda_dai_get_ops(substream, cpu_dai); - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); struct hdac_ext_stream *hext_stream; struct hdac_stream *hstream; struct hdac_ext_link *hlink; struct snd_sof_dev *sdev; - struct hdac_bus *bus; int stream_tag;
if (!ops) { @@ -167,9 +161,8 @@ static int hda_link_dma_hw_params(struct snd_pcm_substream *substream, }
sdev = dai_to_sdev(substream, cpu_dai); - bus = sof_to_bus(sdev);
- hlink = snd_hdac_ext_bus_get_hlink_by_name(bus, codec_dai->component->name); + hlink = ops->get_hlink(sdev, substream); if (!hlink) return -EINVAL;
@@ -211,8 +204,6 @@ static int __maybe_unused hda_dai_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { const struct hda_dai_widget_dma_ops *ops = hda_dai_get_ops(substream, cpu_dai); - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); struct hdac_ext_stream *hext_stream; struct snd_sof_dev *sdev = dai_to_sdev(substream, cpu_dai);
@@ -225,7 +216,7 @@ static int __maybe_unused hda_dai_hw_free(struct snd_pcm_substream *substream, if (!hext_stream) return 0;
- return hda_link_dma_cleanup(substream, hext_stream, cpu_dai, codec_dai); + return hda_link_dma_cleanup(substream, hext_stream, cpu_dai); }
static int __maybe_unused hda_dai_hw_params(struct snd_pcm_substream *substream, @@ -270,8 +261,6 @@ static int __maybe_unused hda_dai_trigger(struct snd_pcm_substream *substream, i { const struct hda_dai_widget_dma_ops *ops = hda_dai_get_ops(substream, dai); struct hdac_ext_stream *hext_stream; - struct snd_soc_pcm_runtime *rtd; - struct snd_soc_dai *codec_dai; struct snd_sof_dev *sdev; int ret;
@@ -289,9 +278,6 @@ static int __maybe_unused hda_dai_trigger(struct snd_pcm_substream *substream, i if (!hext_stream) return -EINVAL;
- rtd = asoc_substream_to_rtd(substream); - codec_dai = asoc_rtd_to_codec(rtd, 0); - if (ops->pre_trigger) { ret = ops->pre_trigger(sdev, dai, substream, cmd); if (ret < 0) @@ -312,7 +298,7 @@ static int __maybe_unused hda_dai_trigger(struct snd_pcm_substream *substream, i
switch (cmd) { case SNDRV_PCM_TRIGGER_SUSPEND: - ret = hda_link_dma_cleanup(substream, hext_stream, dai, codec_dai); + ret = hda_link_dma_cleanup(substream, hext_stream, dai); if (ret < 0) { dev_err(sdev->dev, "%s: failed to clean up link DMA\n", __func__); return ret; @@ -366,14 +352,12 @@ static int hda_dai_suspend(struct hdac_bus *bus) const struct hda_dai_widget_dma_ops *ops; struct snd_sof_widget *swidget; struct snd_soc_dapm_widget *w; - struct snd_soc_dai *codec_dai; struct snd_soc_dai *cpu_dai; struct snd_sof_dev *sdev; struct snd_sof_dai *sdai;
rtd = asoc_substream_to_rtd(hext_stream->link_substream); cpu_dai = asoc_rtd_to_cpu(rtd, 0); - codec_dai = asoc_rtd_to_codec(rtd, 0); w = snd_soc_dai_get_widget(cpu_dai, hdac_stream(hext_stream)->direction); swidget = w->dobj.private; sdev = widget_to_sdev(w); @@ -382,7 +366,7 @@ static int hda_dai_suspend(struct hdac_bus *bus)
ret = hda_link_dma_cleanup(hext_stream->link_substream, hext_stream, - cpu_dai, codec_dai); + cpu_dai); if (ret < 0) return ret;
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 7a3d202f970e..8ca43303d97f 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -922,6 +922,8 @@ int hda_dsp_ipc4_load_library(struct snd_sof_dev *sdev, * @codec_dai_set_stream: Function pointer to set codec-side stream information * @calc_stream_format: Function pointer to determine stream format from hw_params and * for HDaudio codec DAI from the .sig bits + * @get_hlink: Mandatory function pointer to retrieve hlink, mainly to program LOSIDV + * for legacy HDaudio links or program HDaudio Extended Link registers. */ struct hda_dai_widget_dma_ops { struct hdac_ext_stream *(*get_hext_stream)(struct snd_sof_dev *sdev, @@ -947,6 +949,8 @@ struct hda_dai_widget_dma_ops { unsigned int (*calc_stream_format)(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params); + struct hdac_ext_link * (*get_hlink)(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream); };
const struct hda_dai_widget_dma_ops *