aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2012-05-25 20:22:11 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-06-03 08:06:41 -0400
commitbc92657a11c0982783979bbb84ceaf58ba222124 (patch)
tree473fa6b2b4624dc255a1db98ddcfac9fd1bc9bd6
parent210cb67cb5b9f9a23b7ce91de50bab357440ba9d (diff)
ASoC: make snd_soc_dai_link more symmetrical
Prior to this patch, the CPU side of a DAI link was specified using a single name. Often, this was the result of calling dev_name() on the device providing the DAI, but in the case of a CPU DAI driver that provided multiple DAIs, it needed to mix together both the device name and some device-relative name, in order to form a single globally unique name. However, the CODEC side of the DAI link was specified using separate fields for device (name or OF node) and device-relative DAI name. This patch allows the CPU side of a DAI link to be specified in the same way as the CODEC side, separating concepts of device and device-relative DAI name. I believe this will be important in multi-codec and/or dynamic PCM scenarios, where a single CPU driver provides multiple DAIs, while also booting using device tree, with accompanying desire not to hard-code the CPU side device's name into the original .cpu_dai_name field. Ideally, both the CPU DAI and CODEC DAI loops in soc_bind_dai_link() would now be identical. However, two things prevent that at present: 1) The need to save rtd->codec for the CODEC side, which means we have to search for the CODEC explicitly, and not just the CODEC side DAI. 2) Since we know the CODEC side DAI is part of a codec, and not just a standalone DAI, it's slightly more efficient to convert .codec_name/ .codec_of_node into a codec first, and then compare each DAI's .codec field, since this avoids strcmp() on each DAI's CODEC's name within the loop. However, the two loops are essentially semantically equivalent. Signed-off-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--include/sound/soc.h33
-rw-r--r--sound/soc/mxs/mxs-sgtl5000.c2
-rw-r--r--sound/soc/soc-core.c42
-rw-r--r--sound/soc/tegra/tegra_alc5632.c6
-rw-r--r--sound/soc/tegra/tegra_wm8753.c6
-rw-r--r--sound/soc/tegra/tegra_wm8903.c6
-rw-r--r--sound/soc/tegra/trimslice.c6
7 files changed, 72 insertions, 29 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index c703871f5f65..23c4efbe13a6 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -785,13 +785,36 @@ struct snd_soc_dai_link {
785 /* config - must be set by machine driver */ 785 /* config - must be set by machine driver */
786 const char *name; /* Codec name */ 786 const char *name; /* Codec name */
787 const char *stream_name; /* Stream name */ 787 const char *stream_name; /* Stream name */
788 const char *codec_name; /* for multi-codec */ 788 /*
789 const struct device_node *codec_of_node; 789 * You MAY specify the link's CPU-side device, either by device name,
790 const char *platform_name; /* for multi-platform */ 790 * or by DT/OF node, but not both. If this information is omitted,
791 const struct device_node *platform_of_node; 791 * the CPU-side DAI is matched using .cpu_dai_name only, which hence
792 * must be globally unique. These fields are currently typically used
793 * only for codec to codec links, or systems using device tree.
794 */
795 const char *cpu_name;
796 const struct device_node *cpu_of_node;
797 /*
798 * You MAY specify the DAI name of the CPU DAI. If this information is
799 * omitted, the CPU-side DAI is matched using .cpu_name/.cpu_of_node
800 * only, which only works well when that device exposes a single DAI.
801 */
792 const char *cpu_dai_name; 802 const char *cpu_dai_name;
793 const struct device_node *cpu_dai_of_node; 803 /*
804 * You MUST specify the link's codec, either by device name, or by
805 * DT/OF node, but not both.
806 */
807 const char *codec_name;
808 const struct device_node *codec_of_node;
809 /* You MUST specify the DAI name within the codec */
794 const char *codec_dai_name; 810 const char *codec_dai_name;
811 /*
812 * You MAY specify the link's platform/PCM/DMA driver, either by
813 * device name, or by DT/OF node, but not both. Some forms of link
814 * do not need a platform.
815 */
816 const char *platform_name;
817 const struct device_node *platform_of_node;
795 int be_id; /* optional ID for machine driver BE identification */ 818 int be_id; /* optional ID for machine driver BE identification */
796 819
797 const struct snd_soc_pcm_stream *params; 820 const struct snd_soc_pcm_stream *params;
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c
index 3e6e8764b2e6..215113b05f7d 100644
--- a/sound/soc/mxs/mxs-sgtl5000.c
+++ b/sound/soc/mxs/mxs-sgtl5000.c
@@ -133,7 +133,7 @@ static int __devinit mxs_sgtl5000_probe_dt(struct platform_device *pdev)
133 mxs_sgtl5000_dai[i].codec_name = NULL; 133 mxs_sgtl5000_dai[i].codec_name = NULL;
134 mxs_sgtl5000_dai[i].codec_of_node = codec_np; 134 mxs_sgtl5000_dai[i].codec_of_node = codec_np;
135 mxs_sgtl5000_dai[i].cpu_dai_name = NULL; 135 mxs_sgtl5000_dai[i].cpu_dai_name = NULL;
136 mxs_sgtl5000_dai[i].cpu_dai_of_node = saif_np[i]; 136 mxs_sgtl5000_dai[i].cpu_of_node = saif_np[i];
137 mxs_sgtl5000_dai[i].platform_name = NULL; 137 mxs_sgtl5000_dai[i].platform_name = NULL;
138 mxs_sgtl5000_dai[i].platform_of_node = saif_np[i]; 138 mxs_sgtl5000_dai[i].platform_of_node = saif_np[i];
139 } 139 }
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index b37ee8077ed1..ec8350570346 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -812,13 +812,15 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
812 812
813 /* Find CPU DAI from registered DAIs*/ 813 /* Find CPU DAI from registered DAIs*/
814 list_for_each_entry(cpu_dai, &dai_list, list) { 814 list_for_each_entry(cpu_dai, &dai_list, list) {
815 if (dai_link->cpu_dai_of_node) { 815 if (dai_link->cpu_of_node &&
816 if (cpu_dai->dev->of_node != dai_link->cpu_dai_of_node) 816 (cpu_dai->dev->of_node != dai_link->cpu_of_node))
817 continue; 817 continue;
818 } else { 818 if (dai_link->cpu_name &&
819 if (strcmp(cpu_dai->name, dai_link->cpu_dai_name)) 819 strcmp(dev_name(cpu_dai->dev), dai_link->cpu_name))
820 continue; 820 continue;
821 } 821 if (dai_link->cpu_dai_name &&
822 strcmp(cpu_dai->name, dai_link->cpu_dai_name))
823 continue;
822 824
823 rtd->cpu_dai = cpu_dai; 825 rtd->cpu_dai = cpu_dai;
824 } 826 }
@@ -3346,6 +3348,12 @@ int snd_soc_register_card(struct snd_soc_card *card)
3346 link->name); 3348 link->name);
3347 return -EINVAL; 3349 return -EINVAL;
3348 } 3350 }
3351 /* Codec DAI name must be specified */
3352 if (!link->codec_dai_name) {
3353 dev_err(card->dev, "codec_dai_name not set for %s\n",
3354 link->name);
3355 return -EINVAL;
3356 }
3349 3357
3350 /* 3358 /*
3351 * Platform may be specified by either name or OF node, but 3359 * Platform may be specified by either name or OF node, but
@@ -3358,12 +3366,24 @@ int snd_soc_register_card(struct snd_soc_card *card)
3358 } 3366 }
3359 3367
3360 /* 3368 /*
3361 * CPU DAI must be specified by 1 of name or OF node, 3369 * CPU device may be specified by either name or OF node, but
3362 * not both or neither. 3370 * can be left unspecified, and will be matched based on DAI
3371 * name alone..
3372 */
3373 if (link->cpu_name && link->cpu_of_node) {
3374 dev_err(card->dev,
3375 "Neither/both cpu name/of_node are set for %s\n",
3376 link->name);
3377 return -EINVAL;
3378 }
3379 /*
3380 * At least one of CPU DAI name or CPU device name/node must be
3381 * specified
3363 */ 3382 */
3364 if (!!link->cpu_dai_name == !!link->cpu_dai_of_node) { 3383 if (!link->cpu_dai_name &&
3384 !(link->cpu_name || link->cpu_of_node)) {
3365 dev_err(card->dev, 3385 dev_err(card->dev,
3366 "Neither/both cpu_dai name/of_node are set for %s\n", 3386 "Neither cpu_dai_name nor cpu_name/of_node are set for %s\n",
3367 link->name); 3387 link->name);
3368 return -EINVAL; 3388 return -EINVAL;
3369 } 3389 }
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index 15669570ae31..417b09b83fdf 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -197,16 +197,16 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
197 goto err; 197 goto err;
198 } 198 }
199 199
200 tegra_alc5632_dai.cpu_dai_of_node = of_parse_phandle( 200 tegra_alc5632_dai.cpu_of_node = of_parse_phandle(
201 pdev->dev.of_node, "nvidia,i2s-controller", 0); 201 pdev->dev.of_node, "nvidia,i2s-controller", 0);
202 if (!tegra_alc5632_dai.cpu_dai_of_node) { 202 if (!tegra_alc5632_dai.cpu_of_node) {
203 dev_err(&pdev->dev, 203 dev_err(&pdev->dev,
204 "Property 'nvidia,i2s-controller' missing or invalid\n"); 204 "Property 'nvidia,i2s-controller' missing or invalid\n");
205 ret = -EINVAL; 205 ret = -EINVAL;
206 goto err; 206 goto err;
207 } 207 }
208 208
209 tegra_alc5632_dai.platform_of_node = tegra_alc5632_dai.cpu_dai_of_node; 209 tegra_alc5632_dai.platform_of_node = tegra_alc5632_dai.cpu_of_node;
210 210
211 ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev); 211 ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev);
212 if (ret) 212 if (ret)
diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c
index 4e77026807a2..02bd5a8e8544 100644
--- a/sound/soc/tegra/tegra_wm8753.c
+++ b/sound/soc/tegra/tegra_wm8753.c
@@ -157,9 +157,9 @@ static __devinit int tegra_wm8753_driver_probe(struct platform_device *pdev)
157 goto err; 157 goto err;
158 } 158 }
159 159
160 tegra_wm8753_dai.cpu_dai_of_node = of_parse_phandle( 160 tegra_wm8753_dai.cpu_of_node = of_parse_phandle(
161 pdev->dev.of_node, "nvidia,i2s-controller", 0); 161 pdev->dev.of_node, "nvidia,i2s-controller", 0);
162 if (!tegra_wm8753_dai.cpu_dai_of_node) { 162 if (!tegra_wm8753_dai.cpu_of_node) {
163 dev_err(&pdev->dev, 163 dev_err(&pdev->dev,
164 "Property 'nvidia,i2s-controller' missing or invalid\n"); 164 "Property 'nvidia,i2s-controller' missing or invalid\n");
165 ret = -EINVAL; 165 ret = -EINVAL;
@@ -167,7 +167,7 @@ static __devinit int tegra_wm8753_driver_probe(struct platform_device *pdev)
167 } 167 }
168 168
169 tegra_wm8753_dai.platform_of_node = 169 tegra_wm8753_dai.platform_of_node =
170 tegra_wm8753_dai.cpu_dai_of_node; 170 tegra_wm8753_dai.cpu_of_node;
171 171
172 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); 172 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
173 if (ret) 173 if (ret)
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index b75e0e8db1d0..1fd71e5a9eb9 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -331,9 +331,9 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
331 } 331 }
332 332
333 tegra_wm8903_dai.cpu_dai_name = NULL; 333 tegra_wm8903_dai.cpu_dai_name = NULL;
334 tegra_wm8903_dai.cpu_dai_of_node = of_parse_phandle(np, 334 tegra_wm8903_dai.cpu_of_node = of_parse_phandle(np,
335 "nvidia,i2s-controller", 0); 335 "nvidia,i2s-controller", 0);
336 if (!tegra_wm8903_dai.cpu_dai_of_node) { 336 if (!tegra_wm8903_dai.cpu_of_node) {
337 dev_err(&pdev->dev, 337 dev_err(&pdev->dev,
338 "Property 'nvidia,i2s-controller' missing or invalid\n"); 338 "Property 'nvidia,i2s-controller' missing or invalid\n");
339 ret = -EINVAL; 339 ret = -EINVAL;
@@ -342,7 +342,7 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
342 342
343 tegra_wm8903_dai.platform_name = NULL; 343 tegra_wm8903_dai.platform_name = NULL;
344 tegra_wm8903_dai.platform_of_node = 344 tegra_wm8903_dai.platform_of_node =
345 tegra_wm8903_dai.cpu_dai_of_node; 345 tegra_wm8903_dai.cpu_of_node;
346 } else { 346 } else {
347 card->dapm_routes = harmony_audio_map; 347 card->dapm_routes = harmony_audio_map;
348 card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map); 348 card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map);
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c
index 4a8d5b672c9f..5815430e8521 100644
--- a/sound/soc/tegra/trimslice.c
+++ b/sound/soc/tegra/trimslice.c
@@ -162,9 +162,9 @@ static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev)
162 } 162 }
163 163
164 trimslice_tlv320aic23_dai.cpu_dai_name = NULL; 164 trimslice_tlv320aic23_dai.cpu_dai_name = NULL;
165 trimslice_tlv320aic23_dai.cpu_dai_of_node = of_parse_phandle( 165 trimslice_tlv320aic23_dai.cpu_of_node = of_parse_phandle(
166 pdev->dev.of_node, "nvidia,i2s-controller", 0); 166 pdev->dev.of_node, "nvidia,i2s-controller", 0);
167 if (!trimslice_tlv320aic23_dai.cpu_dai_of_node) { 167 if (!trimslice_tlv320aic23_dai.cpu_of_node) {
168 dev_err(&pdev->dev, 168 dev_err(&pdev->dev,
169 "Property 'nvidia,i2s-controller' missing or invalid\n"); 169 "Property 'nvidia,i2s-controller' missing or invalid\n");
170 ret = -EINVAL; 170 ret = -EINVAL;
@@ -173,7 +173,7 @@ static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev)
173 173
174 trimslice_tlv320aic23_dai.platform_name = NULL; 174 trimslice_tlv320aic23_dai.platform_name = NULL;
175 trimslice_tlv320aic23_dai.platform_of_node = 175 trimslice_tlv320aic23_dai.platform_of_node =
176 trimslice_tlv320aic23_dai.cpu_dai_of_node; 176 trimslice_tlv320aic23_dai.cpu_of_node;
177 } 177 }
178 178
179 ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev); 179 ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev);