204 lines
5.6 KiB
Diff
204 lines
5.6 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Guneshwor Singh <guneshwor.o.singh@intel.com>
|
|
Date: Sun, 18 Jun 2017 09:52:40 +0530
|
|
Subject: [PATCH] ASoC: Intel: board: Add support for HDMI in cnl_rt274
|
|
|
|
To enable HDMI/iDisp, corresponding BE DAI links are defined in the
|
|
machine driver. FE links will come topology with an assumption that the
|
|
dai link name will consist the string "HDMI". This assumption is made to
|
|
distinguish other dai links from hdmi dai links.
|
|
|
|
Special handling is needed for hdmi dai links because hdmi jack is
|
|
mapped for each hdmi BE dai link with the corresponding pcm device. And
|
|
since FE links come from topology, they can come in any order. Hence the
|
|
need to keep a track of pcm_count.
|
|
|
|
Change-Id: I6fbdfbdb61d5fa58691cfe84abbd859209ccfce5
|
|
Signed-off-by: Guneshwor Singh <guneshwor.o.singh@intel.com>
|
|
---
|
|
sound/soc/intel/boards/cnl_rt274.c | 129 ++++++++++++++++++++++++++++-
|
|
1 file changed, 126 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/sound/soc/intel/boards/cnl_rt274.c b/sound/soc/intel/boards/cnl_rt274.c
|
|
index ebfe74132da5..e9e5959e256a 100644
|
|
--- a/sound/soc/intel/boards/cnl_rt274.c
|
|
+++ b/sound/soc/intel/boards/cnl_rt274.c
|
|
@@ -33,11 +33,27 @@
|
|
#include <sound/jack.h>
|
|
#include <linux/input.h>
|
|
|
|
+#include "../../codecs/hdac_hdmi.h"
|
|
#include "../../codecs/rt274.h"
|
|
|
|
#define CNL_FREQ_OUT 19200000
|
|
#define CNL_BE_FIXUP_RATE 48000
|
|
#define RT274_CODEC_DAI "rt274-aif1"
|
|
+#define CNL_NAME_SIZE 32
|
|
+#define CNL_MAX_HDMI 3
|
|
+
|
|
+static struct snd_soc_jack cnl_hdmi[CNL_MAX_HDMI];
|
|
+
|
|
+struct cnl_hdmi_pcm {
|
|
+ struct list_head head;
|
|
+ struct snd_soc_dai *codec_dai;
|
|
+ int device;
|
|
+};
|
|
+
|
|
+struct cnl_rt274_private {
|
|
+ struct list_head hdmi_pcm_list;
|
|
+ int pcm_count;
|
|
+};
|
|
|
|
static struct snd_soc_dai *cnl_get_codec_dai(struct snd_soc_card *card,
|
|
const char *dai_name)
|
|
@@ -158,6 +174,13 @@ static const struct snd_soc_dapm_route cnl_map[] = {
|
|
|
|
{"Headphone Jack", NULL, "Platform Clock"},
|
|
{"MIC", NULL, "Platform Clock"},
|
|
+
|
|
+ {"hifi1", NULL, "iDisp1 Tx"},
|
|
+ {"iDisp1 Tx", NULL, "iDisp1_out"},
|
|
+ {"hifi2", NULL, "iDisp2 Tx"},
|
|
+ {"iDisp2 Tx", NULL, "iDisp2_out"},
|
|
+ {"hifi3", NULL, "iDisp3 Tx"},
|
|
+ {"iDisp3 Tx", NULL, "iDisp3_out"},
|
|
};
|
|
|
|
static int cnl_rt274_init(struct snd_soc_pcm_runtime *runtime)
|
|
@@ -307,6 +330,36 @@ static struct snd_soc_dai_link cnl_rt274_msic_dailink[] = {
|
|
.dpcm_capture = 1,
|
|
.be_hw_params_fixup = cnl_dmic_fixup,
|
|
},
|
|
+ {
|
|
+ .name = "iDisp1",
|
|
+ .id = 3,
|
|
+ .cpu_dai_name = "iDisp1 Pin",
|
|
+ .codec_name = "ehdaudio0D2",
|
|
+ .codec_dai_name = "intel-hdmi-hifi1",
|
|
+ .platform_name = pname,
|
|
+ .dpcm_playback = 1,
|
|
+ .no_pcm = 1,
|
|
+ },
|
|
+ {
|
|
+ .name = "iDisp2",
|
|
+ .id = 4,
|
|
+ .cpu_dai_name = "iDisp2 Pin",
|
|
+ .codec_name = "ehdaudio0D2",
|
|
+ .codec_dai_name = "intel-hdmi-hifi2",
|
|
+ .platform_name = pname,
|
|
+ .dpcm_playback = 1,
|
|
+ .no_pcm = 1,
|
|
+ },
|
|
+ {
|
|
+ .name = "iDisp3",
|
|
+ .id = 5,
|
|
+ .cpu_dai_name = "iDisp3 Pin",
|
|
+ .codec_name = "ehdaudio0D2",
|
|
+ .codec_dai_name = "intel-hdmi-hifi3",
|
|
+ .platform_name = pname,
|
|
+ .dpcm_playback = 1,
|
|
+ .no_pcm = 1,
|
|
+ },
|
|
/* codec-codec link */
|
|
{
|
|
.name = "CNL SSP0-Loop Port",
|
|
@@ -326,10 +379,67 @@ static struct snd_soc_dai_link cnl_rt274_msic_dailink[] = {
|
|
static int
|
|
cnl_add_dai_link(struct snd_soc_card *card, struct snd_soc_dai_link *link)
|
|
{
|
|
- link->platform_name = pname;
|
|
- link->nonatomic = 1;
|
|
+ struct cnl_rt274_private *ctx = snd_soc_card_get_drvdata(card);
|
|
+ char hdmi_dai_name[CNL_NAME_SIZE];
|
|
+ struct cnl_hdmi_pcm *pcm;
|
|
+
|
|
+ link->platform_name = pname;
|
|
+ link->nonatomic = 1;
|
|
+
|
|
+ /* Assuming HDMI dai link will consist the string "HDMI" */
|
|
+ if (strstr(link->name, "HDMI")) {
|
|
+ static int i = 1; /* hdmi codec dai name starts from index 1 */
|
|
+
|
|
+ pcm = devm_kzalloc(card->dev, sizeof(*pcm), GFP_KERNEL);
|
|
+ if (!pcm)
|
|
+ return -ENOMEM;
|
|
|
|
- return 0;
|
|
+ snprintf(hdmi_dai_name, sizeof(hdmi_dai_name), "intel-hdmi-hifi%d", i++);
|
|
+ pcm->codec_dai = cnl_get_codec_dai(card, hdmi_dai_name);
|
|
+ if (!pcm->codec_dai)
|
|
+ return -EINVAL;
|
|
+
|
|
+ pcm->device = ctx->pcm_count;
|
|
+ list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
|
|
+ }
|
|
+ ctx->pcm_count++;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int cnl_card_late_probe(struct snd_soc_card *card)
|
|
+{
|
|
+ struct cnl_rt274_private *ctx = snd_soc_card_get_drvdata(card);
|
|
+ struct snd_soc_component *component = NULL;
|
|
+ char jack_name[CNL_NAME_SIZE];
|
|
+ struct cnl_hdmi_pcm *pcm;
|
|
+ int err, i = 0;
|
|
+
|
|
+ if (list_empty(&ctx->hdmi_pcm_list))
|
|
+ return 0;
|
|
+
|
|
+ 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, &cnl_hdmi[i],
|
|
+ NULL, 0);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ err = hdac_hdmi_jack_init(pcm->codec_dai,
|
|
+ pcm->device, &cnl_hdmi[i]);
|
|
+ if (err < 0)
|
|
+ return err;
|
|
+
|
|
+ i++;
|
|
+ }
|
|
+
|
|
+ if (!component)
|
|
+ return -EINVAL;
|
|
+
|
|
+ return hdac_hdmi_jack_port_init(component, &card->dapm);
|
|
}
|
|
|
|
/* SoC card */
|
|
@@ -344,11 +454,24 @@ static struct snd_soc_card snd_soc_card_cnl = {
|
|
.controls = cnl_controls,
|
|
.num_controls = ARRAY_SIZE(cnl_controls),
|
|
.add_dai_link = cnl_add_dai_link,
|
|
+ .fully_routed = true,
|
|
+ .late_probe = cnl_card_late_probe,
|
|
};
|
|
|
|
static int snd_cnl_rt274_mc_probe(struct platform_device *pdev)
|
|
{
|
|
+ struct cnl_rt274_private *ctx;
|
|
+
|
|
+ ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
|
|
+ if (!ctx)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ ctx->pcm_count = ARRAY_SIZE(cnl_rt274_msic_dailink);
|
|
+ INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
|
|
+
|
|
snd_soc_card_cnl.dev = &pdev->dev;
|
|
+ snd_soc_card_set_drvdata(&snd_soc_card_cnl, ctx);
|
|
+
|
|
return devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_cnl);
|
|
}
|
|
|
|
--
|
|
https://clearlinux.org
|
|
|