mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
7de9a47c89
Add support for using snd-hda-codec-hdmi driver for HDMI/DP instead of ASoC hdac-hdmi. This is aligned with how other HDA codecs are already handled. When snd-hda-codec-hdmi is used, the PCM device numbers are parsed from card topology and passed to the codec driver. This needs to be done at runtime as topology changes may affect PCM device allocation. Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Reviewed-by: Takashi Iwai <tiwai@suse.de> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://lore.kernel.org/r/20191029134017.18901-4-kai.vehmanen@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
86 lines
2.0 KiB
C
86 lines
2.0 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
//
|
|
// Copyright(c) 2019 Intel Corporation. All rights reserved.
|
|
|
|
#include <sound/pcm.h>
|
|
#include <sound/soc.h>
|
|
#include <sound/hda_codec.h>
|
|
#include <sound/hda_i915.h>
|
|
#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 = 0;
|
|
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
|