]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ASoC: sdw_utils/intel: move soundwire endpoint parsing helper functions
authorVijendar Mukunda <Vijendar.Mukunda@amd.com>
Fri, 13 Sep 2024 09:06:30 +0000 (14:36 +0530)
committerMark Brown <broonie@kernel.org>
Fri, 13 Sep 2024 14:11:32 +0000 (15:11 +0100)
Move SoundWire endpoint parsing helper functions to common place holder.
These functions will be used by other platform machine driver code.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Link: https://patch.msgid.link/20240913090631.1834543-5-Vijendar.Mukunda@amd.com
Signed-off-by: Mark Brown <broonie@kernel.org>
include/sound/soc_sdw_utils.h
sound/soc/intel/boards/sof_sdw.c
sound/soc/sdw_utils/soc_sdw_utils.c

index e3482720a3eb0c86eb6cc042a01283c7b92b84c8..f68c1f193b3b460438f50e872759ba690531d664 100644 (file)
@@ -161,6 +161,16 @@ int asoc_sdw_init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *d
                                  int (*init)(struct snd_soc_pcm_runtime *rtd),
                                  const struct snd_soc_ops *ops);
 
+int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int *num_ends);
+
+struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks,
+                                              const struct snd_soc_acpi_endpoint *new);
+
+int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
+                                struct asoc_sdw_dailink *soc_dais,
+                                struct asoc_sdw_endpoint *soc_ends,
+                                int *num_devs);
+
 int asoc_sdw_rtd_init(struct snd_soc_pcm_runtime *rtd);
 
 /* DMIC support */
index 6b30659f0e25764643e6d12d3c6c186242f5f9ec..5196d96f5c0e86e0cf9a6ffd4668def886ab1b47 100644 (file)
@@ -619,164 +619,6 @@ static const struct snd_soc_ops sdw_ops = {
 
 static const char * const type_strings[] = {"SimpleJack", "SmartAmp", "SmartMic"};
 
-static int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int *num_ends)
-{
-       struct device *dev = card->dev;
-       struct snd_soc_acpi_mach *mach = dev_get_platdata(dev);
-       struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
-       const struct snd_soc_acpi_link_adr *adr_link;
-       int i;
-
-       for (adr_link = mach_params->links; adr_link->num_adr; adr_link++) {
-               *num_devs += adr_link->num_adr;
-
-               for (i = 0; i < adr_link->num_adr; i++)
-                       *num_ends += adr_link->adr_d[i].num_endpoints;
-       }
-
-       dev_dbg(dev, "Found %d devices with %d endpoints\n", *num_devs, *num_ends);
-
-       return 0;
-}
-
-static struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks,
-                                                     const struct snd_soc_acpi_endpoint *new)
-{
-       while (dailinks->initialised) {
-               if (new->aggregated && dailinks->group_id == new->group_id)
-                       return dailinks;
-
-               dailinks++;
-       }
-
-       INIT_LIST_HEAD(&dailinks->endpoints);
-       dailinks->group_id = new->group_id;
-       dailinks->initialised = true;
-
-       return dailinks;
-}
-
-static int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
-                                       struct asoc_sdw_dailink *sof_dais,
-                                       struct asoc_sdw_endpoint *sof_ends,
-                                       int *num_devs)
-{
-       struct device *dev = card->dev;
-       struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
-       struct snd_soc_acpi_mach *mach = dev_get_platdata(dev);
-       struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
-       const struct snd_soc_acpi_link_adr *adr_link;
-       struct asoc_sdw_endpoint *sof_end = sof_ends;
-       int num_dais = 0;
-       int i, j;
-       int ret;
-
-       for (adr_link = mach_params->links; adr_link->num_adr; adr_link++) {
-               int num_link_dailinks = 0;
-
-               if (!is_power_of_2(adr_link->mask)) {
-                       dev_err(dev, "link with multiple mask bits: 0x%x\n",
-                               adr_link->mask);
-                       return -EINVAL;
-               }
-
-               for (i = 0; i < adr_link->num_adr; i++) {
-                       const struct snd_soc_acpi_adr_device *adr_dev = &adr_link->adr_d[i];
-                       struct asoc_sdw_codec_info *codec_info;
-                       const char *codec_name;
-
-                       if (!adr_dev->name_prefix) {
-                               dev_err(dev, "codec 0x%llx does not have a name prefix\n",
-                                       adr_dev->adr);
-                               return -EINVAL;
-                       }
-
-                       codec_info = asoc_sdw_find_codec_info_part(adr_dev->adr);
-                       if (!codec_info)
-                               return -EINVAL;
-
-                       ctx->ignore_internal_dmic |= codec_info->ignore_internal_dmic;
-
-                       codec_name = asoc_sdw_get_codec_name(dev, codec_info, adr_link, i);
-                       if (!codec_name)
-                               return -ENOMEM;
-
-                       dev_dbg(dev, "Adding prefix %s for %s\n",
-                               adr_dev->name_prefix, codec_name);
-
-                       sof_end->name_prefix = adr_dev->name_prefix;
-
-                       if (codec_info->count_sidecar && codec_info->add_sidecar) {
-                               ret = codec_info->count_sidecar(card, &num_dais, num_devs);
-                               if (ret)
-                                       return ret;
-
-                               sof_end->include_sidecar = true;
-                       }
-
-                       for (j = 0; j < adr_dev->num_endpoints; j++) {
-                               const struct snd_soc_acpi_endpoint *adr_end;
-                               const struct asoc_sdw_dai_info *dai_info;
-                               struct asoc_sdw_dailink *sof_dai;
-                               int stream;
-
-                               adr_end = &adr_dev->endpoints[j];
-                               dai_info = &codec_info->dais[adr_end->num];
-                               sof_dai = asoc_sdw_find_dailink(sof_dais, adr_end);
-
-                               if (dai_info->quirk && !(dai_info->quirk & sof_sdw_quirk))
-                                       continue;
-
-                               dev_dbg(dev,
-                                       "Add dev: %d, 0x%llx end: %d, %s, %c/%c to %s: %d\n",
-                                       ffs(adr_link->mask) - 1, adr_dev->adr,
-                                       adr_end->num, type_strings[dai_info->dai_type],
-                                       dai_info->direction[SNDRV_PCM_STREAM_PLAYBACK] ? 'P' : '-',
-                                       dai_info->direction[SNDRV_PCM_STREAM_CAPTURE] ? 'C' : '-',
-                                       adr_end->aggregated ? "group" : "solo",
-                                       adr_end->group_id);
-
-                               if (adr_end->num >= codec_info->dai_num) {
-                                       dev_err(dev,
-                                               "%d is too many endpoints for codec: 0x%x\n",
-                                               adr_end->num, codec_info->part_id);
-                                       return -EINVAL;
-                               }
-
-                               for_each_pcm_streams(stream) {
-                                       if (dai_info->direction[stream] &&
-                                           dai_info->dailink[stream] < 0) {
-                                               dev_err(dev,
-                                                       "Invalid dailink id %d for codec: 0x%x\n",
-                                                       dai_info->dailink[stream],
-                                                       codec_info->part_id);
-                                               return -EINVAL;
-                                       }
-
-                                       if (dai_info->direction[stream]) {
-                                               num_dais += !sof_dai->num_devs[stream];
-                                               sof_dai->num_devs[stream]++;
-                                               sof_dai->link_mask[stream] |= adr_link->mask;
-                                       }
-                               }
-
-                               num_link_dailinks += !!list_empty(&sof_dai->endpoints);
-                               list_add_tail(&sof_end->list, &sof_dai->endpoints);
-
-                               sof_end->link_mask = adr_link->mask;
-                               sof_end->codec_name = codec_name;
-                               sof_end->codec_info = codec_info;
-                               sof_end->dai_info = dai_info;
-                               sof_end++;
-                       }
-               }
-
-               ctx->append_dai_type |= (num_link_dailinks > 1);
-       }
-
-       return num_dais;
-}
-
 static int create_sdw_dailink(struct snd_soc_card *card,
                              struct asoc_sdw_dailink *sof_dai,
                              struct snd_soc_dai_link **dai_links,
index d59ccb56642c79d9dc87eea4916b878da1f664f4..a6070f822eb9e41b12138358f570469d0248366c 100644 (file)
@@ -1005,5 +1005,166 @@ int asoc_sdw_init_simple_dai_link(struct device *dev, struct snd_soc_dai_link *d
 }
 EXPORT_SYMBOL_NS(asoc_sdw_init_simple_dai_link, SND_SOC_SDW_UTILS);
 
+int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int *num_ends)
+{
+       struct device *dev = card->dev;
+       struct snd_soc_acpi_mach *mach = dev_get_platdata(dev);
+       struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
+       const struct snd_soc_acpi_link_adr *adr_link;
+       int i;
+
+       for (adr_link = mach_params->links; adr_link->num_adr; adr_link++) {
+               *num_devs += adr_link->num_adr;
+
+               for (i = 0; i < adr_link->num_adr; i++)
+                       *num_ends += adr_link->adr_d[i].num_endpoints;
+       }
+
+       dev_dbg(dev, "Found %d devices with %d endpoints\n", *num_devs, *num_ends);
+
+       return 0;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_count_sdw_endpoints, SND_SOC_SDW_UTILS);
+
+struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks,
+                                              const struct snd_soc_acpi_endpoint *new)
+{
+       while (dailinks->initialised) {
+               if (new->aggregated && dailinks->group_id == new->group_id)
+                       return dailinks;
+
+               dailinks++;
+       }
+
+       INIT_LIST_HEAD(&dailinks->endpoints);
+       dailinks->group_id = new->group_id;
+       dailinks->initialised = true;
+
+       return dailinks;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_find_dailink, SND_SOC_SDW_UTILS);
+
+int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
+                                struct asoc_sdw_dailink *soc_dais,
+                                struct asoc_sdw_endpoint *soc_ends,
+                                int *num_devs)
+{
+       struct device *dev = card->dev;
+       struct asoc_sdw_mc_private *ctx = snd_soc_card_get_drvdata(card);
+       struct snd_soc_acpi_mach *mach = dev_get_platdata(dev);
+       struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
+       const struct snd_soc_acpi_link_adr *adr_link;
+       struct asoc_sdw_endpoint *soc_end = soc_ends;
+       int num_dais = 0;
+       int i, j;
+       int ret;
+
+       for (adr_link = mach_params->links; adr_link->num_adr; adr_link++) {
+               int num_link_dailinks = 0;
+
+               if (!is_power_of_2(adr_link->mask)) {
+                       dev_err(dev, "link with multiple mask bits: 0x%x\n",
+                               adr_link->mask);
+                       return -EINVAL;
+               }
+
+               for (i = 0; i < adr_link->num_adr; i++) {
+                       const struct snd_soc_acpi_adr_device *adr_dev = &adr_link->adr_d[i];
+                       struct asoc_sdw_codec_info *codec_info;
+                       const char *codec_name;
+
+                       if (!adr_dev->name_prefix) {
+                               dev_err(dev, "codec 0x%llx does not have a name prefix\n",
+                                       adr_dev->adr);
+                               return -EINVAL;
+                       }
+
+                       codec_info = asoc_sdw_find_codec_info_part(adr_dev->adr);
+                       if (!codec_info)
+                               return -EINVAL;
+
+                       ctx->ignore_internal_dmic |= codec_info->ignore_internal_dmic;
+
+                       codec_name = asoc_sdw_get_codec_name(dev, codec_info, adr_link, i);
+                       if (!codec_name)
+                               return -ENOMEM;
+
+                       dev_dbg(dev, "Adding prefix %s for %s\n",
+                               adr_dev->name_prefix, codec_name);
+
+                       soc_end->name_prefix = adr_dev->name_prefix;
+
+                       if (codec_info->count_sidecar && codec_info->add_sidecar) {
+                               ret = codec_info->count_sidecar(card, &num_dais, num_devs);
+                               if (ret)
+                                       return ret;
+
+                               soc_end->include_sidecar = true;
+                       }
+
+                       for (j = 0; j < adr_dev->num_endpoints; j++) {
+                               const struct snd_soc_acpi_endpoint *adr_end;
+                               const struct asoc_sdw_dai_info *dai_info;
+                               struct asoc_sdw_dailink *soc_dai;
+                               int stream;
+
+                               adr_end = &adr_dev->endpoints[j];
+                               dai_info = &codec_info->dais[adr_end->num];
+                               soc_dai = asoc_sdw_find_dailink(soc_dais, adr_end);
+
+                               if (dai_info->quirk && !(dai_info->quirk & ctx->mc_quirk))
+                                       continue;
+
+                               dev_dbg(dev,
+                                       "Add dev: %d, 0x%llx end: %d, dai: %d, %c/%c to %s: %d\n",
+                                       ffs(adr_link->mask) - 1, adr_dev->adr,
+                                       adr_end->num, dai_info->dai_type,
+                                       dai_info->direction[SNDRV_PCM_STREAM_PLAYBACK] ? 'P' : '-',
+                                       dai_info->direction[SNDRV_PCM_STREAM_CAPTURE] ? 'C' : '-',
+                                       adr_end->aggregated ? "group" : "solo",
+                                       adr_end->group_id);
+
+                               if (adr_end->num >= codec_info->dai_num) {
+                                       dev_err(dev,
+                                               "%d is too many endpoints for codec: 0x%x\n",
+                                               adr_end->num, codec_info->part_id);
+                                       return -EINVAL;
+                               }
+
+                               for_each_pcm_streams(stream) {
+                                       if (dai_info->direction[stream] &&
+                                           dai_info->dailink[stream] < 0) {
+                                               dev_err(dev,
+                                                       "Invalid dailink id %d for codec: 0x%x\n",
+                                                       dai_info->dailink[stream],
+                                                       codec_info->part_id);
+                                               return -EINVAL;
+                                       }
+
+                                       if (dai_info->direction[stream]) {
+                                               num_dais += !soc_dai->num_devs[stream];
+                                               soc_dai->num_devs[stream]++;
+                                               soc_dai->link_mask[stream] |= adr_link->mask;
+                                       }
+                               }
+
+                               num_link_dailinks += !!list_empty(&soc_dai->endpoints);
+                               list_add_tail(&soc_end->list, &soc_dai->endpoints);
+
+                               soc_end->link_mask = adr_link->mask;
+                               soc_end->codec_name = codec_name;
+                               soc_end->codec_info = codec_info;
+                               soc_end->dai_info = dai_info;
+                               soc_end++;
+                       }
+               }
+
+               ctx->append_dai_type |= (num_link_dailinks > 1);
+       }
+
+       return num_dais;
+}
+EXPORT_SYMBOL_NS(asoc_sdw_parse_sdw_endpoints, SND_SOC_SDW_UTILS);
+
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("SoundWire ASoC helpers");