Unverified Commit 7de9a47c authored by Kai Vehmanen's avatar Kai Vehmanen Committed by Mark Brown
Browse files

ASoC: Intel: skl-hda-dsp-generic: use snd-hda-codec-hdmi



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: default avatarKai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: default avatarTakashi Iwai <tiwai@suse.de>
Reviewed-by: default avatarPierre-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: default avatarMark Brown <broonie@kernel.org>
parent 608b8c36
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -60,12 +60,14 @@ static inline struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg)
 * @acpi_ipc_irq_index: used for BYT-CR detection
 * @platform: string used for HDaudio codec support
 * @codec_mask: used for HDAudio support
 * @common_hdmi_codec_drv: use commom HDAudio HDMI codec driver
 */
struct snd_soc_acpi_mach_params {
	u32 acpi_ipc_irq_index;
	const char *platform;
	u32 codec_mask;
	u32 dmic_num;
	bool common_hdmi_codec_drv;
};

/**
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ snd-soc-kbl_rt5663_max98927-objs := kbl_rt5663_max98927.o
snd-soc-kbl_rt5663_rt5514_max98927-objs := kbl_rt5663_rt5514_max98927.o
snd-soc-kbl_rt5660-objs := kbl_rt5660.o
snd-soc-skl_rt286-objs := skl_rt286.o
snd-soc-skl_hda_dsp-objs := skl_hda_dsp_generic.o skl_hda_dsp_common.o
snd-soc-skl_hda_dsp-objs := skl_hda_dsp_generic.o skl_hda_dsp_common.o hda_dsp_common.o
snd-skl_nau88l25_max98357a-objs := skl_nau88l25_max98357a.o
snd-soc-skl_nau88l25_ssm4567-objs := skl_nau88l25_ssm4567.o

+85 −0
Original line number Diff line number Diff line
// 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
+32 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright(c) 2019 Intel Corporation.
 */

/*
 * This file defines helper functions used by multiple
 * Intel HDA based machine drivers.
 */

#ifndef __HDA_DSP_COMMON_H
#define __HDA_DSP_COMMON_H

#include <sound/hda_codec.h>
#include <sound/hda_i915.h>
#include "../../codecs/hdac_hda.h"

struct snd_pcm *hda_dsp_hdmi_pcm_handle(struct snd_soc_card *card,
					int hdmi_idx);

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
int hda_dsp_hdmi_build_controls(struct snd_soc_card *card,
				struct snd_soc_component *comp);
#else
static inline int hda_dsp_hdmi_build_controls(struct snd_soc_card *card,
					      struct snd_soc_component *comp)
{
	return -EINVAL;
}
#endif

#endif /* __HDA_DSP_COMMON_H */
+6 −0
Original line number Diff line number Diff line
@@ -14,6 +14,9 @@
#include "../../codecs/hdac_hdmi.h"
#include "skl_hda_dsp_common.h"

#include <sound/hda_codec.h>
#include "../../codecs/hdac_hda.h"

#define NAME_SIZE	32

int skl_hda_hdmi_add_pcm(struct snd_soc_card *card, int device)
@@ -136,6 +139,9 @@ int skl_hda_hdmi_jack_init(struct snd_soc_card *card)
	char jack_name[NAME_SIZE];
	int err;

	if (ctx->common_hdmi_codec_drv)
		return skl_hda_hdmi_build_controls(card);

	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
		component = pcm->codec_dai->component;
		snprintf(jack_name, sizeof(jack_name),
Loading