@@ -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
@@ -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;
@@ -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 *