summaryrefslogtreecommitdiff
path: root/sound/soc/intel/boards/sof_sdw_hdmi.c
diff options
context:
space:
mode:
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>2020-03-26 01:07:44 +0300
committerMark Brown <broonie@kernel.org>2020-03-27 20:11:54 +0300
commit52db12d193d45728e738df6119702cba08fd46a2 (patch)
treee4e107f3b3cc5f4af941e21ace6c83e94dbc8800 /sound/soc/intel/boards/sof_sdw_hdmi.c
parentba762e67c3f34660f6ac8299296dbc9e96720939 (diff)
downloadlinux-52db12d193d45728e738df6119702cba08fd46a2.tar.xz
ASoC: Intel: boards: add sof_sdw machine driver
This machine driver provides support for different configurations: RT700, RT711, RT1308 (1x and 2x, I2S or SoundWire mode), and RT715 CometLake, Icelake, TigerLake. PDM digital microphones HDMI To avoid introducing one driver per configuration, this common machine driver relies on platform-specific information, tables and quirks to dynamically create the relevant dailinks. Unlike a lot of machine drivers, we use different DAI links for SoundWire capture and playback since the Cadence PDIs can do capture OR playback, not both simultaneously. For each configuration, the card component string is updated so that UCM can select the relevant parts. Signed-off-by: Rander Wang <rander.wang@linux.intel.com> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com> Link: https://lore.kernel.org/r/20200325220746.29601-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/intel/boards/sof_sdw_hdmi.c')
-rw-r--r--sound/soc/intel/boards/sof_sdw_hdmi.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/sound/soc/intel/boards/sof_sdw_hdmi.c b/sound/soc/intel/boards/sof_sdw_hdmi.c
new file mode 100644
index 000000000000..c7b5612a39e6
--- /dev/null
+++ b/sound/soc/intel/boards/sof_sdw_hdmi.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2020 Intel Corporation
+
+/*
+ * sof_sdw_hdmi - Helpers to handle HDMI from generic machine driver
+ */
+
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <sound/soc.h>
+#include <sound/soc-acpi.h>
+#include <sound/jack.h>
+#include "sof_sdw_common.h"
+#include "../../codecs/hdac_hdmi.h"
+#include "hda_dsp_common.h"
+
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
+static struct snd_soc_jack hdmi[MAX_HDMI_NUM];
+
+struct hdmi_pcm {
+ struct list_head head;
+ struct snd_soc_dai *codec_dai;
+ int device;
+};
+
+int sof_sdw_hdmi_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct mc_private *ctx = snd_soc_card_get_drvdata(rtd->card);
+ struct snd_soc_dai *dai = rtd->codec_dai;
+ struct hdmi_pcm *pcm;
+
+ pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
+ if (!pcm)
+ return -ENOMEM;
+
+ /* dai_link id is 1:1 mapped to the PCM device */
+ pcm->device = rtd->dai_link->id;
+ pcm->codec_dai = dai;
+
+ list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
+
+ return 0;
+}
+
+#define NAME_SIZE 32
+int sof_sdw_hdmi_card_late_probe(struct snd_soc_card *card)
+{
+ struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+ struct hdmi_pcm *pcm;
+ struct snd_soc_component *component = NULL;
+ int err, i = 0;
+ char jack_name[NAME_SIZE];
+
+ pcm = list_first_entry(&ctx->hdmi_pcm_list, struct hdmi_pcm,
+ head);
+ component = pcm->codec_dai->component;
+
+ if (ctx->common_hdmi_codec_drv)
+ return hda_dsp_hdmi_build_controls(card, component);
+
+ list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
+ component = pcm->codec_dai->component;
+ snprintf(jack_name, sizeof(jack_name),
+ "HDMI/DP, pcm=%d Jack", pcm->device);
+ err = snd_soc_card_jack_new(card, jack_name,
+ SND_JACK_AVOUT, &hdmi[i],
+ NULL, 0);
+
+ if (err)
+ return err;
+
+ err = snd_jack_add_new_kctl(hdmi[i].jack,
+ jack_name, SND_JACK_AVOUT);
+ if (err)
+ dev_warn(component->dev, "failed creating Jack kctl\n");
+
+ err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
+ &hdmi[i]);
+ if (err < 0)
+ return err;
+
+ i++;
+ }
+
+ if (!component)
+ return -EINVAL;
+
+ return hdac_hdmi_jack_port_init(component, &card->dapm);
+}
+#else
+int hdmi_card_late_probe(struct snd_soc_card *card)
+{
+ return 0;
+}
+#endif