> +static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) > +{ > + struct avs_dma_data *data; > + struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); > + struct hdac_ext_stream *estream; host_stream, estream, there seems to be multiple naming conventions for the same thing? > + struct hdac_ext_link *link; > + struct hda_codec *codec; > + > + dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); > + > + data = snd_soc_dai_get_dma_data(dai, substream); > + if (!data->path) > + return 0; > + > + estream = substream->runtime->private_data; > + estream->link_prepared = false; > + avs_path_free(data->path); > + data->path = NULL; > + > + /* clear link <-> stream mapping */ > + codec = dev_to_hda_codec(asoc_rtd_to_codec(rtd, 0)->dev); > + link = snd_hdac_ext_bus_link_at(&codec->bus->core, codec->core.addr); > + if (!link) > + return -EINVAL; > + > + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) > + snd_hdac_ext_link_clear_stream_id(link, estream->hstream.stream_tag); > + > + return 0; > +} > +static int avs_dai_hda_be_trigger(struct snd_pcm_substream *substream, int cmd, > + struct snd_soc_dai *dai) > +{ > + struct hdac_ext_stream *estream; > + struct avs_dma_data *data; > + int ret = 0; > + > + dev_dbg(dai->dev, "entry %s cmd=%d\n", __func__, cmd); > + > + data = snd_soc_dai_get_dma_data(dai, substream); > + estream = substream->runtime->private_data; > + > + switch (cmd) { > + case SNDRV_PCM_TRIGGER_START: > + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: > + snd_hdac_ext_link_stream_start(estream); > + > + ret = avs_path_run(data->path, AVS_TPLG_TRIGGER_AUTO); > + if (ret < 0) > + dev_err(dai->dev, "run BE path failed: %d\n", ret); > + break; > + > + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: > + case SNDRV_PCM_TRIGGER_STOP: > + ret = avs_path_pause(data->path); > + if (ret < 0) > + dev_err(dai->dev, "pause BE path failed: %d\n", ret); > + > + snd_hdac_ext_link_stream_clear(estream); > + > + if (cmd == SNDRV_PCM_TRIGGER_STOP) { > + ret = avs_path_reset(data->path); > + if (ret < 0) > + dev_err(dai->dev, "reset BE path failed: %d\n", ret); > + } > + break; > + > + default: > + ret = -EINVAL; TRIGGER_SUSPEND? > + break; > + } > + > + return ret; > +} > +static const struct snd_soc_component_driver avs_hda_component_driver = { > + .name = "avs-hda-pcm", > + .probe = avs_component_hda_probe, > + .remove = avs_component_hda_remove, > + .open = avs_component_hda_open, > + .close = avs_component_hda_close, > + .pointer = avs_component_pointer, > + .mmap = avs_component_mmap, > + .pcm_construct = avs_component_construct, > + /* > + * hda platform component's probe() is dependent on > + * codec->pcm_list_head, it needs to be initialized after codec > + * component. remove_order is here for completeness sake > + */ > + .probe_order = SND_SOC_COMP_ORDER_LATE, > + .remove_order = SND_SOC_COMP_ORDER_EARLY, > + .module_get_upon_open = 1, > + .topology_name_prefix = "intel/avs", > + .non_legacy_dai_naming = true, needed? > +}; > + > +int avs_hda_platform_register(struct avs_dev *adev, const char *name) > +{ > + return avs_soc_component_register(adev->dev, name, > + &avs_hda_component_driver, NULL, 0); > +}