diff mbox series

[01/21] ASoC: Intel: board_helpers: support DAI link ID customization

Message ID 20240325221059.206042-2-pierre-louis.bossart@linux.intel.com (mailing list archive)
State Accepted
Commit b020aff0ec6ec089bd3e07bd6b58623826752ff7
Headers show
Series ASoC: Intel: boards: updates for 6.10 - part1 | expand

Commit Message

Pierre-Louis Bossart March 25, 2024, 10:10 p.m. UTC
From: Brent Lu <brent.lu@intel.com>

Add an new field link_id_overwrite to sof_card_private structure to
support machine drivers which DAI link ID is fixed number or
discontinue (i.e. no-codec boards). If this field is zero, DAI array
index will be used as link ID. Otherwise the value extracted from
link_id_overwrite will be used.

The field link_id_overwrite is supposed to be initialized by
SOF_LINK_IDS macro like following example.

ctx->link_id_overwrite = SOF_LINK_IDS(HEADPHONE_BE_ID,  \
				      DMIC01_BE_ID,     \
				      DMIC16K_BE_ID,    \
				      IDISP_HDMI_BE_ID, \
				      SPK_BE_ID,        \
				      BT_OFFLOAD_BE_ID, \
				      HDMI_IN_BE_ID)

An exception is that, if you use link_order_overwrite to overwrite
DAI link order, then you need to use the same order to build
link_id_overwrite variable as well.

Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: Brent Lu <brent.lu@intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
---
 sound/soc/intel/boards/sof_board_helpers.c | 36 ++++++++++++++++------
 sound/soc/intel/boards/sof_board_helpers.h | 18 +++++++++++
 2 files changed, 45 insertions(+), 9 deletions(-)
diff mbox series

Patch

diff --git a/sound/soc/intel/boards/sof_board_helpers.c b/sound/soc/intel/boards/sof_board_helpers.c
index 088894ff4165..e853dc851c42 100644
--- a/sound/soc/intel/boards/sof_board_helpers.c
+++ b/sound/soc/intel/boards/sof_board_helpers.c
@@ -427,6 +427,7 @@  int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
 	int ret;
 	int ssp_hdmi_in = 0;
 	unsigned long link_order, link;
+	unsigned long link_ids, be_id;
 
 	num_links = calculate_num_links(ctx);
 
@@ -440,12 +441,26 @@  int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
 	else
 		link_order = DEFAULT_LINK_ORDER;
 
-	dev_dbg(dev, "create dai links, link_order 0x%lx\n", link_order);
+	if (ctx->link_id_overwrite)
+		link_ids = ctx->link_id_overwrite;
+	else
+		link_ids = 0;
+
+	dev_dbg(dev, "create dai links, link_order 0x%lx, id_overwrite 0x%lx\n",
+		link_order, link_ids);
 
 	while (link_order) {
 		link = link_order & SOF_LINK_ORDER_MASK;
 		link_order >>= SOF_LINK_ORDER_SHIFT;
 
+		if (ctx->link_id_overwrite) {
+			be_id = link_ids & SOF_LINK_IDS_MASK;
+			link_ids >>= SOF_LINK_IDS_SHIFT;
+		} else {
+			/* use array index as link id */
+			be_id = idx;
+		}
+
 		switch (link) {
 		case SOF_LINK_CODEC:
 			/* headphone codec */
@@ -453,7 +468,7 @@  int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
 				continue;
 
 			ret = sof_intel_board_set_codec_link(dev, &links[idx],
-							     idx,
+							     be_id,
 							     ctx->codec_type,
 							     ctx->ssp_codec);
 			if (ret) {
@@ -472,7 +487,7 @@  int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
 
 			/* at least we have dmic01 */
 			ret = sof_intel_board_set_dmic_link(dev, &links[idx],
-							    idx, SOF_DMIC_01);
+							    be_id, SOF_DMIC_01);
 			if (ret) {
 				dev_err(dev, "fail to set dmic01 link, ret %d\n",
 					ret);
@@ -488,7 +503,7 @@  int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
 
 			/* set up 2 BE links at most */
 			ret = sof_intel_board_set_dmic_link(dev, &links[idx],
-							    idx, SOF_DMIC_16K);
+							    be_id, SOF_DMIC_16K);
 			if (ret) {
 				dev_err(dev, "fail to set dmic16k link, ret %d\n",
 					ret);
@@ -502,7 +517,8 @@  int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
 			for (i = 1; i <= ctx->hdmi_num; i++) {
 				ret = sof_intel_board_set_intel_hdmi_link(dev,
 									  &links[idx],
-									  idx, i,
+									  be_id,
+									  i,
 									  ctx->hdmi.idisp_codec);
 				if (ret) {
 					dev_err(dev, "fail to set hdmi link, ret %d\n",
@@ -511,6 +527,7 @@  int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
 				}
 
 				idx++;
+				be_id++;
 			}
 			break;
 		case SOF_LINK_AMP:
@@ -519,7 +536,7 @@  int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
 				continue;
 
 			ret = sof_intel_board_set_ssp_amp_link(dev, &links[idx],
-							       idx,
+							       be_id,
 							       ctx->amp_type,
 							       ctx->ssp_amp);
 			if (ret) {
@@ -536,8 +553,8 @@  int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
 			if (!ctx->bt_offload_present)
 				continue;
 
-			ret = sof_intel_board_set_bt_link(dev, &links[idx], idx,
-							  ctx->ssp_bt);
+			ret = sof_intel_board_set_bt_link(dev, &links[idx],
+							  be_id, ctx->ssp_bt);
 			if (ret) {
 				dev_err(dev, "fail to set bt link, ret %d\n",
 					ret);
@@ -551,7 +568,7 @@  int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
 			for_each_set_bit(ssp_hdmi_in, &ctx->ssp_mask_hdmi_in, 32) {
 				ret = sof_intel_board_set_hdmi_in_link(dev,
 								       &links[idx],
-								       idx,
+								       be_id,
 								       ssp_hdmi_in);
 				if (ret) {
 					dev_err(dev, "fail to set hdmi-in link, ret %d\n",
@@ -560,6 +577,7 @@  int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
 				}
 
 				idx++;
+				be_id++;
 			}
 			break;
 		case SOF_LINK_NONE:
diff --git a/sound/soc/intel/boards/sof_board_helpers.h b/sound/soc/intel/boards/sof_board_helpers.h
index f42d5d640321..162a5f4841da 100644
--- a/sound/soc/intel/boards/sof_board_helpers.h
+++ b/sound/soc/intel/boards/sof_board_helpers.h
@@ -33,6 +33,18 @@  enum {
 	 (((k6) & SOF_LINK_ORDER_MASK) << (SOF_LINK_ORDER_SHIFT * 5)) | \
 	 (((k7) & SOF_LINK_ORDER_MASK) << (SOF_LINK_ORDER_SHIFT * 6)))
 
+#define SOF_LINK_IDS_MASK	(0xF)
+#define SOF_LINK_IDS_SHIFT	(4)
+
+#define SOF_LINK_IDS(k1, k2, k3, k4, k5, k6, k7) \
+	((((k1) & SOF_LINK_IDS_MASK) << (SOF_LINK_IDS_SHIFT * 0)) | \
+	 (((k2) & SOF_LINK_IDS_MASK) << (SOF_LINK_IDS_SHIFT * 1)) | \
+	 (((k3) & SOF_LINK_IDS_MASK) << (SOF_LINK_IDS_SHIFT * 2)) | \
+	 (((k4) & SOF_LINK_IDS_MASK) << (SOF_LINK_IDS_SHIFT * 3)) | \
+	 (((k5) & SOF_LINK_IDS_MASK) << (SOF_LINK_IDS_SHIFT * 4)) | \
+	 (((k6) & SOF_LINK_IDS_MASK) << (SOF_LINK_IDS_SHIFT * 5)) | \
+	 (((k7) & SOF_LINK_IDS_MASK) << (SOF_LINK_IDS_SHIFT * 6)))
+
 /*
  * sof_rt5682_private: private data for rt5682 machine driver
  *
@@ -61,6 +73,7 @@  struct sof_rt5682_private {
  * @codec_link: pointer to headset codec dai link
  * @amp_link: pointer to speaker amplifier dai link
  * @link_order_overwrite: custom DAI link order
+ * @link_id_overwrite: custom DAI link ID
  * @rt5682: private data for rt5682 machine driver
  */
 struct sof_card_private {
@@ -84,6 +97,11 @@  struct sof_card_private {
 	struct snd_soc_dai_link *amp_link;
 
 	unsigned long link_order_overwrite;
+	/*
+	 * A variable stores id for all BE DAI links, use SOF_LINK_IDS macro to
+	 * build the value; use DAI link array index as id if zero.
+	 */
+	unsigned long link_id_overwrite;
 
 	union {
 		struct sof_rt5682_private rt5682;