ASoC: Intel: board_helpers: support DAI link ID customization
authorBrent Lu <brent.lu@intel.com>
Mon, 25 Mar 2024 22:10:39 +0000 (17:10 -0500)
committerMark Brown <broonie@kernel.org>
Mon, 25 Mar 2024 22:44:49 +0000 (22:44 +0000)
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>
Link: https://msgid.link/r/20240325221059.206042-2-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/boards/sof_board_helpers.c
sound/soc/intel/boards/sof_board_helpers.h

index 088894ff416578105975454e5a30acc766f38954..e853dc851c422f4a1a2e2046f6099d67925bf068 100644 (file)
@@ -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:
index f42d5d6403219e695d5da233d34aeb527dd3efcc..162a5f4841da0c1507f299d844283b16bc53ca1c 100644 (file)
@@ -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;