ASoC: Intel: sof_sdw: remove hard-coded codec_conf table
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Wed, 23 Sep 2020 08:05:12 +0000 (11:05 +0300)
committerMark Brown <broonie@kernel.org>
Wed, 23 Sep 2020 17:13:14 +0000 (18:13 +0100)
Now that the ACPI machine params provide all the information needed,
allocate the card codec_conf dynamically and set .dlc and
.prefix_name.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/20200923080514.3242858-5-kai.vehmanen@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/intel/boards/sof_sdw.c

index 79c3c19..7c15a8d 100644 (file)
@@ -136,75 +136,6 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
        {}
 };
 
-static struct snd_soc_codec_conf codec_conf[] = {
-       {
-               .dlc = COMP_CODEC_CONF("sdw:0:25d:711:0"),
-               .name_prefix = "rt711",
-       },
-       {
-               .dlc = COMP_CODEC_CONF("sdw:0:25d:711:1"),
-               .name_prefix = "rt711",
-       },
-       /* rt1308 w/ I2S connection */
-       {
-               .dlc = COMP_CODEC_CONF("i2c-10EC1308:00"),
-               .name_prefix = "rt1308-1",
-       },
-       /* rt1308 left on link 1 */
-       {
-               .dlc = COMP_CODEC_CONF("sdw:1:25d:1308:0"),
-               .name_prefix = "rt1308-1",
-       },
-       /* two 1308s on link1 with different unique id */
-       {
-               .dlc = COMP_CODEC_CONF("sdw:1:25d:1308:0:0"),
-               .name_prefix = "rt1308-1",
-       },
-       {
-               .dlc = COMP_CODEC_CONF("sdw:1:25d:1308:0:2"),
-               .name_prefix = "rt1308-2",
-       },
-       /* rt1308 right on link 2 */
-       {
-               .dlc = COMP_CODEC_CONF("sdw:2:25d:1308:0"),
-               .name_prefix = "rt1308-2",
-       },
-       {
-               .dlc = COMP_CODEC_CONF("sdw:3:25d:715:0"),
-               .name_prefix = "rt715",
-       },
-       /* two MAX98373s on link1 with different unique id */
-       {
-               .dlc = COMP_CODEC_CONF("sdw:1:19f:8373:0:3"),
-               .name_prefix = "Right",
-       },
-       {
-               .dlc = COMP_CODEC_CONF("sdw:1:19f:8373:0:7"),
-               .name_prefix = "Left",
-       },
-       {
-               .dlc = COMP_CODEC_CONF("sdw:0:25d:5682:0"),
-               .name_prefix = "rt5682",
-       },
-       /* rt5682 on link2 */
-       {
-               .dlc = COMP_CODEC_CONF("sdw:2:25d:5682:0"),
-               .name_prefix = "rt5682",
-       },
-       {
-               .dlc = COMP_CODEC_CONF("sdw:1:25d:1316:1"),
-               .name_prefix = "rt1316-1",
-       },
-       {
-               .dlc = COMP_CODEC_CONF("sdw:2:25d:1316:1"),
-               .name_prefix = "rt1316-2",
-       },
-       {
-               .dlc = COMP_CODEC_CONF("sdw:3:25d:714:1"),
-               .name_prefix = "rt714",
-       },
-};
-
 static struct snd_soc_dai_link_component dmic_component[] = {
        {
                .name = "dmic-codec",
@@ -538,10 +469,19 @@ static bool is_unique_device(const struct snd_soc_acpi_link_adr *link,
 static int create_codec_dai_name(struct device *dev,
                                 const struct snd_soc_acpi_link_adr *link,
                                 struct snd_soc_dai_link_component *codec,
-                                int offset)
+                                int offset,
+                                struct snd_soc_codec_conf *codec_conf,
+                                int codec_count,
+                                int *codec_conf_index)
 {
        int i;
 
+       /* sanity check */
+       if (*codec_conf_index + link->num_adr > codec_count) {
+               dev_err(dev, "codec_conf: out-of-bounds access requested\n");
+               return -EINVAL;
+       }
+
        for (i = 0; i < link->num_adr; i++) {
                unsigned int sdw_version, unique_id, mfg_id;
                unsigned int link_id, part_id, class_id;
@@ -583,6 +523,11 @@ static int create_codec_dai_name(struct device *dev,
 
                codec[comp_index].dai_name =
                        codec_info_list[codec_index].dai_name;
+
+               codec_conf[*codec_conf_index].dlc = codec[comp_index];
+               codec_conf[*codec_conf_index].name_prefix = link->adr_d[i].name_prefix;
+
+               ++*codec_conf_index;
        }
 
        return 0;
@@ -701,7 +646,10 @@ static int create_sdw_dailink(struct device *dev, int *be_index,
                              int sdw_be_num, int sdw_cpu_dai_num,
                              struct snd_soc_dai_link_component *cpus,
                              const struct snd_soc_acpi_link_adr *link,
-                             int *cpu_id, bool *group_generated)
+                             int *cpu_id, bool *group_generated,
+                             struct snd_soc_codec_conf *codec_conf,
+                             int codec_count,
+                             int *codec_conf_index)
 {
        const struct snd_soc_acpi_link_adr *link_next;
        struct snd_soc_dai_link_component *codecs;
@@ -739,7 +687,8 @@ static int create_sdw_dailink(struct device *dev, int *be_index,
                if (cpu_dai_id[i] != ffs(link_next->mask) - 1)
                        continue;
 
-               ret = create_codec_dai_name(dev, link_next, codecs, codec_idx);
+               ret = create_codec_dai_name(dev, link_next, codecs, codec_idx,
+                                           codec_conf, codec_count, codec_conf_index);
                if (ret < 0)
                        return ret;
 
@@ -836,6 +785,42 @@ static inline int get_next_be_id(struct snd_soc_dai_link *links,
 
 #define IDISP_CODEC_MASK       0x4
 
+static int sof_card_codec_conf_alloc(struct device *dev,
+                                    struct snd_soc_acpi_mach_params *mach_params,
+                                    struct snd_soc_codec_conf **codec_conf,
+                                    int *codec_conf_count)
+{
+       const struct snd_soc_acpi_link_adr *adr_link;
+       struct snd_soc_codec_conf *c_conf;
+       int num_codecs = 0;
+       int i;
+
+       adr_link = mach_params->links;
+       if (!adr_link)
+               return -EINVAL;
+
+       /* generate DAI links by each sdw link */
+       for (; adr_link->num_adr; adr_link++) {
+               for (i = 0; i < adr_link->num_adr; i++) {
+                       if (!adr_link->adr_d[i].name_prefix) {
+                               dev_err(dev, "codec 0x%llx does not have a name prefix\n",
+                                       adr_link->adr_d[i].adr);
+                               return -EINVAL;
+                       }
+               }
+               num_codecs += adr_link->num_adr;
+       }
+
+       c_conf = devm_kzalloc(dev, num_codecs * sizeof(*c_conf), GFP_KERNEL);
+       if (!c_conf)
+               return -ENOMEM;
+
+       *codec_conf = c_conf;
+       *codec_conf_count = num_codecs;
+
+       return 0;
+}
+
 static int sof_card_dai_links_create(struct device *dev,
                                     struct snd_soc_acpi_mach *mach,
                                     struct snd_soc_card *card)
@@ -847,6 +832,9 @@ static int sof_card_dai_links_create(struct device *dev,
        struct snd_soc_acpi_mach_params *mach_params;
        const struct snd_soc_acpi_link_adr *adr_link;
        struct snd_soc_dai_link_component *cpus;
+       struct snd_soc_codec_conf *codec_conf;
+       int codec_conf_count;
+       int codec_conf_index = 0;
        bool group_generated[SDW_MAX_GROUPS];
        int ssp_codec_index, ssp_mask;
        struct snd_soc_dai_link *links;
@@ -859,6 +847,13 @@ static int sof_card_dai_links_create(struct device *dev,
        int comp_num;
        int ret;
 
+       mach_params = &mach->mach_params;
+
+       /* allocate codec conf, will be populated when dailinks are created */
+       ret = sof_card_codec_conf_alloc(dev, mach_params, &codec_conf, &codec_conf_count);
+       if (ret < 0)
+               return ret;
+
        /* reset amp_num to ensure amp_num++ starts from 0 in each probe */
        for (i = 0; i < ARRAY_SIZE(codec_info_list); i++)
                codec_info_list[i].amp_num = 0;
@@ -879,7 +874,6 @@ static int sof_card_dai_links_create(struct device *dev,
        ssp_num = ssp_codec_index >= 0 ? hweight_long(ssp_mask) : 0;
        comp_num = hdmi_num + ssp_num;
 
-       mach_params = &mach->mach_params;
        ret = get_sdw_dailink_info(mach_params->links,
                                   &sdw_be_num, &sdw_cpu_dai_num);
        if (ret < 0) {
@@ -943,7 +937,9 @@ static int sof_card_dai_links_create(struct device *dev,
 
                ret = create_sdw_dailink(dev, &be_id, links, sdw_be_num,
                                         sdw_cpu_dai_num, cpus, adr_link,
-                                        &cpu_id, group_generated);
+                                        &cpu_id, group_generated,
+                                        codec_conf, codec_conf_count,
+                                        &codec_conf_index);
                if (ret < 0) {
                        dev_err(dev, "failed to create dai link %d", be_id);
                        return -ENOMEM;
@@ -1074,6 +1070,9 @@ DMIC:
        card->dai_link = links;
        card->num_links = num_links;
 
+       card->codec_conf = codec_conf;
+       card->num_configs = codec_conf_count;
+
        return 0;
 }
 
@@ -1100,8 +1099,6 @@ static struct snd_soc_card card_sof_sdw = {
        .name = "soundwire",
        .owner = THIS_MODULE,
        .late_probe = sof_sdw_card_late_probe,
-       .codec_conf = codec_conf,
-       .num_configs = ARRAY_SIZE(codec_conf),
 };
 
 static int mc_probe(struct platform_device *pdev)