1 // SPDX-License-Identifier: GPL-2.0-only 2 // 3 // Copyright(c) 2019 Intel Corporation. All rights reserved. 4 5 #include <sound/pcm.h> 6 #include <sound/soc.h> 7 #include <sound/hda_codec.h> 8 #include <sound/hda_i915.h> 9 #include "../../codecs/hdac_hda.h" 10 11 #include "hda_dsp_common.h" 12 13 /* 14 * Search card topology and return PCM device number 15 * matching Nth HDMI device (zero-based index). 16 */ 17 struct snd_pcm *hda_dsp_hdmi_pcm_handle(struct snd_soc_card *card, 18 int hdmi_idx) 19 { 20 struct snd_soc_pcm_runtime *rtd; 21 struct snd_pcm *spcm; 22 int i = 0; 23 24 for_each_card_rtds(card, rtd) { 25 spcm = rtd->pcm ? 26 rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].pcm : NULL; 27 if (spcm && strstr(spcm->id, "HDMI")) { 28 if (i == hdmi_idx) 29 return rtd->pcm; 30 ++i; 31 } 32 } 33 34 return NULL; 35 } 36 37 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) 38 /* 39 * Search card topology and register HDMI PCM related controls 40 * to codec driver. 41 */ 42 int hda_dsp_hdmi_build_controls(struct snd_soc_card *card, 43 struct snd_soc_component *comp) 44 { 45 struct hdac_hda_priv *hda_pvt; 46 struct hda_codec *hcodec; 47 struct snd_pcm *spcm; 48 struct hda_pcm *hpcm; 49 int err = 0, i = 0; 50 51 if (!comp) 52 return -EINVAL; 53 54 hda_pvt = snd_soc_component_get_drvdata(comp); 55 hcodec = &hda_pvt->codec; 56 57 list_for_each_entry(hpcm, &hcodec->pcm_list_head, list) { 58 spcm = hda_dsp_hdmi_pcm_handle(card, i); 59 if (spcm) { 60 hpcm->pcm = spcm; 61 hpcm->device = spcm->device; 62 dev_dbg(card->dev, 63 "%s: mapping HDMI converter %d to PCM %d (%p)\n", 64 __func__, i, hpcm->device, spcm); 65 } else { 66 hpcm->pcm = NULL; 67 hpcm->device = SNDRV_PCM_INVALID_DEVICE; 68 dev_warn(card->dev, 69 "%s: no PCM in topology for HDMI converter %d\n\n", 70 __func__, i); 71 } 72 i++; 73 } 74 snd_hdac_display_power(hcodec->core.bus, 75 HDA_CODEC_IDX_CONTROLLER, true); 76 err = snd_hda_codec_build_controls(hcodec); 77 if (err < 0) 78 dev_err(card->dev, "unable to create controls %d\n", err); 79 snd_hdac_display_power(hcodec->core.bus, 80 HDA_CODEC_IDX_CONTROLLER, false); 81 82 return err; 83 } 84 85 #endif 86