// SPDX-License-Identifier: GPL-2.0 // // Copyright(c) 2019 Intel Corporation. All rights reserved. #include #include #include #include #include "../../codecs/hdac_hda.h" #include "hda_dsp_common.h" /* * Search card topology and return PCM device number * matching Nth HDMI device (zero-based index). */ struct snd_pcm *hda_dsp_hdmi_pcm_handle(struct snd_soc_card *card, int hdmi_idx) { struct snd_soc_pcm_runtime *rtd; struct snd_pcm *spcm; int i = 0; for_each_card_rtds(card, rtd) { spcm = rtd->pcm ? rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].pcm : NULL; if (spcm && strstr(spcm->id, "HDMI")) { if (i == hdmi_idx) return rtd->pcm; ++i; } } return NULL; } #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) /* * Search card topology and register HDMI PCM related controls * to codec driver. */ int hda_dsp_hdmi_build_controls(struct snd_soc_card *card, struct snd_soc_component *comp) { struct hdac_hda_priv *hda_pvt; struct hda_codec *hcodec; struct snd_pcm *spcm; struct hda_pcm *hpcm; int err = 0, i = 0; if (!comp) return -EINVAL; hda_pvt = snd_soc_component_get_drvdata(comp); hcodec = &hda_pvt->codec; list_for_each_entry(hpcm, &hcodec->pcm_list_head, list) { spcm = hda_dsp_hdmi_pcm_handle(card, i); if (spcm) { hpcm->pcm = spcm; hpcm->device = spcm->device; dev_dbg(card->dev, "%s: mapping HDMI converter %d to PCM %d (%p)\n", __func__, i, hpcm->device, spcm); } else { hpcm->pcm = NULL; hpcm->device = SNDRV_PCM_INVALID_DEVICE; dev_warn(card->dev, "%s: no PCM in topology for HDMI converter %d\n\n", __func__, i); } i++; } snd_hdac_display_power(hcodec->core.bus, HDA_CODEC_IDX_CONTROLLER, true); err = snd_hda_codec_build_controls(hcodec); if (err < 0) dev_err(card->dev, "unable to create controls %d\n", err); snd_hdac_display_power(hcodec->core.bus, HDA_CODEC_IDX_CONTROLLER, false); return err; } #endif