diff mbox series

[05/10] ASoC: Intel: sof_es8336: add support for HDMI_In capture

Message ID 20220725194909.145418-6-pierre-louis.bossart@linux.intel.com
State New
Headers show
Series None | expand

Commit Message

Pierre-Louis Bossart July 25, 2022, 7:49 p.m. UTC
From: Muralidhar Reddy <muralidhar.reddy@intel.com>

Adding support for 2 streams of HDMI-In capture via I2S in CBP_CFP
configuration (codec provides bit clock and frame sync).

Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Muralidhar Reddy <muralidhar.reddy@intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 sound/soc/intel/boards/sof_es8336.c           | 126 +++++++++++++++---
 .../intel/common/soc-acpi-intel-adl-match.c   |  12 ++
 2 files changed, 118 insertions(+), 20 deletions(-)
diff mbox series

Patch

diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c
index d70d8255b8c7..f6a003d2da29 100644
--- a/sound/soc/intel/boards/sof_es8336.c
+++ b/sound/soc/intel/boards/sof_es8336.c
@@ -28,6 +28,24 @@ 
 #define SOF_ES8336_SSP_CODEC_MASK		(GENMASK(3, 0))
 
 #define SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK	BIT(4)
+
+/* HDMI capture*/
+#define SOF_SSP_HDMI_CAPTURE_PRESENT		BIT(14)
+#define SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT		15
+#define SOF_NO_OF_HDMI_CAPTURE_SSP_MASK		(GENMASK(16, 15))
+#define SOF_NO_OF_HDMI_CAPTURE_SSP(quirk)	\
+	(((quirk) << SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT) & SOF_NO_OF_HDMI_CAPTURE_SSP_MASK)
+
+#define SOF_HDMI_CAPTURE_1_SSP_SHIFT		7
+#define SOF_HDMI_CAPTURE_1_SSP_MASK		(GENMASK(9, 7))
+#define SOF_HDMI_CAPTURE_1_SSP(quirk)	\
+	(((quirk) << SOF_HDMI_CAPTURE_1_SSP_SHIFT) & SOF_HDMI_CAPTURE_1_SSP_MASK)
+
+#define SOF_HDMI_CAPTURE_2_SSP_SHIFT		10
+#define SOF_HDMI_CAPTURE_2_SSP_MASK		(GENMASK(12, 10))
+#define SOF_HDMI_CAPTURE_2_SSP(quirk)	\
+	(((quirk) << SOF_HDMI_CAPTURE_2_SSP_SHIFT) & SOF_HDMI_CAPTURE_2_SSP_MASK)
+
 #define SOF_ES8336_ENABLE_DMIC			BIT(5)
 #define SOF_ES8336_JD_INVERTED			BIT(6)
 #define SOF_ES8336_HEADPHONE_GPIO		BIT(7)
@@ -345,6 +363,13 @@  static struct snd_soc_dai_link_component dmic_component[] = {
 	}
 };
 
+static struct snd_soc_dai_link_component dummy_component[] = {
+	{
+		.name = "snd-soc-dummy",
+		.dai_name = "snd-soc-dummy-dai",
+	}
+};
+
 static int sof_es8336_late_probe(struct snd_soc_card *card)
 {
 	struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card);
@@ -496,6 +521,37 @@  static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev,
 		id++;
 	}
 
+	/* HDMI-In SSP */
+	if (quirk & SOF_SSP_HDMI_CAPTURE_PRESENT) {
+		int num_of_hdmi_ssp = (quirk & SOF_NO_OF_HDMI_CAPTURE_SSP_MASK) >>
+				SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT;
+
+		for (i = 1; i <= num_of_hdmi_ssp; i++) {
+			int port = (i == 1 ? (quirk & SOF_HDMI_CAPTURE_1_SSP_MASK) >>
+						SOF_HDMI_CAPTURE_1_SSP_SHIFT :
+						(quirk & SOF_HDMI_CAPTURE_2_SSP_MASK) >>
+						SOF_HDMI_CAPTURE_2_SSP_SHIFT);
+
+			links[id].cpus = &cpus[id];
+			links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
+								  "SSP%d Pin", port);
+			if (!links[id].cpus->dai_name)
+				return NULL;
+			links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-HDMI", port);
+			if (!links[id].name)
+				return NULL;
+			links[id].id = id + hdmi_id_offset;
+			links[id].codecs = dummy_component;
+			links[id].num_codecs = ARRAY_SIZE(dummy_component);
+			links[id].platforms = platform_component;
+			links[id].num_platforms = ARRAY_SIZE(platform_component);
+			links[id].dpcm_capture = 1;
+			links[id].no_pcm = 1;
+			links[id].num_cpus = 1;
+			id++;
+		}
+	}
+
 	return links;
 
 devm_err:
@@ -531,29 +587,38 @@  static int sof_es8336_probe(struct platform_device *pdev)
 	card = &sof_es8336_card;
 	card->dev = dev;
 
+	if (pdev->id_entry && pdev->id_entry->driver_data)
+		quirk = (unsigned long)pdev->id_entry->driver_data;
+
 	/* check GPIO DMI quirks */
 	dmi_check_system(sof_es8336_quirk_table);
 
-	if (!mach->mach_params.i2s_link_mask) {
-		dev_warn(dev, "No I2S link information provided, using SSP0. This may need to be modified with the quirk module parameter\n");
-	} else {
-		/*
-		 * Set configuration based on platform NHLT.
-		 * In this machine driver, we can only support one SSP for the
-		 * ES8336 link, the else-if below are intentional.
-		 * In some cases multiple SSPs can be reported by NHLT, starting MSB-first
-		 * seems to pick the right connection.
-		 */
-		unsigned long ssp = 0;
-
-		if (mach->mach_params.i2s_link_mask & BIT(2))
-			ssp = SOF_ES8336_SSP_CODEC(2);
-		else if (mach->mach_params.i2s_link_mask & BIT(1))
-			ssp = SOF_ES8336_SSP_CODEC(1);
-		else  if (mach->mach_params.i2s_link_mask & BIT(0))
-			ssp = SOF_ES8336_SSP_CODEC(0);
-
-		quirk |= ssp;
+	/* Use NHLT configuration only for Non-HDMI capture use case.
+	 * Because more than one SSP will be enabled for HDMI capture hence wrong codec
+	 * SSP will be set.
+	 */
+	if (mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER) {
+		if (!mach->mach_params.i2s_link_mask) {
+			dev_warn(dev, "No I2S link information provided, using SSP0. This may need to be modified with the quirk module parameter\n");
+		} else {
+			/*
+			 * Set configuration based on platform NHLT.
+			 * In this machine driver, we can only support one SSP for the
+			 * ES8336 link, the else-if below are intentional.
+			 * In some cases multiple SSPs can be reported by NHLT, starting MSB-first
+			 * seems to pick the right connection.
+			 */
+			unsigned long ssp = 0;
+
+			if (mach->mach_params.i2s_link_mask & BIT(2))
+				ssp = SOF_ES8336_SSP_CODEC(2);
+			else if (mach->mach_params.i2s_link_mask & BIT(1))
+				ssp = SOF_ES8336_SSP_CODEC(1);
+			else  if (mach->mach_params.i2s_link_mask & BIT(0))
+				ssp = SOF_ES8336_SSP_CODEC(0);
+
+			quirk |= ssp;
+		}
 	}
 
 	if (mach->mach_params.dmic_num)
@@ -570,6 +635,11 @@  static int sof_es8336_probe(struct platform_device *pdev)
 		dmic_be_num = 2;
 
 	sof_es8336_card.num_links += dmic_be_num + hdmi_num;
+
+	if (quirk & SOF_SSP_HDMI_CAPTURE_PRESENT)
+		sof_es8336_card.num_links += (quirk & SOF_NO_OF_HDMI_CAPTURE_SSP_MASK) >>
+				SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT;
+
 	dai_links = sof_card_dai_links_create(dev,
 					      SOF_ES8336_SSP_CODEC(quirk),
 					      dmic_be_num, hdmi_num);
@@ -691,6 +761,21 @@  static int sof_es8336_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static const struct platform_device_id board_ids[] = {
+	{
+		.name = "adl_es83x6_c1_h02",
+		.driver_data = (kernel_ulong_t)(SOF_ES8336_SSP_CODEC(1) |
+					SOF_NO_OF_HDMI_CAPTURE_SSP(2) |
+					SOF_HDMI_CAPTURE_1_SSP(0) |
+					SOF_HDMI_CAPTURE_2_SSP(2) |
+					SOF_SSP_HDMI_CAPTURE_PRESENT |
+					SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK |
+					SOF_ES8336_JD_INVERTED),
+	},
+	{ }
+};
+MODULE_DEVICE_TABLE(platform, board_ids);
+
 static struct platform_driver sof_es8336_driver = {
 	.driver = {
 		.name = "sof-essx8336",
@@ -698,6 +783,7 @@  static struct platform_driver sof_es8336_driver = {
 	},
 	.probe = sof_es8336_probe,
 	.remove = sof_es8336_remove,
+	.id_table = board_ids,
 };
 module_platform_driver(sof_es8336_driver);
 
diff --git a/sound/soc/intel/common/soc-acpi-intel-adl-match.c b/sound/soc/intel/common/soc-acpi-intel-adl-match.c
index 8fccd22b5953..9990d5502d26 100644
--- a/sound/soc/intel/common/soc-acpi-intel-adl-match.c
+++ b/sound/soc/intel/common/soc-acpi-intel-adl-match.c
@@ -440,6 +440,11 @@  static const struct snd_soc_acpi_codecs adl_max98390_amp = {
 	.codecs = {"MX98390"}
 };
 
+static const struct snd_soc_acpi_codecs adl_lt6911_hdmi = {
+	.num_codecs = 1,
+	.codecs = {"INTC10B0"}
+};
+
 struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = {
 	{
 		.comp_ids = &adl_rt5682_rt5682s_hp,
@@ -520,6 +525,13 @@  struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = {
 		.drv_name = "adl_cs35l41",
 		.sof_tplg_filename = "sof-adl-cs35l41.tplg",
 	},
+	{
+		.comp_ids = &essx_83x6,
+		.drv_name = "adl_es83x6_c1_h02",
+		.machine_quirk = snd_soc_acpi_codec_list,
+		.quirk_data = &adl_lt6911_hdmi,
+		.sof_tplg_filename = "sof-adl-es83x6-ssp1-hdmi-ssp02.tplg",
+	},
 	{
 		.comp_ids = &essx_83x6,
 		.drv_name = "sof-essx8336",