summaryrefslogtreecommitdiffstats
path: root/sound/soc/generic
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2018-12-19 20:47:23 -0500
committerMark Brown <broonie@kernel.org>2019-01-03 11:34:30 -0500
commitd947cdfd4be29c48c6c529c2b5ce7b1988387c67 (patch)
treebcfd44726edc95b58becb13908f339f212b81245 /sound/soc/generic
parent17029e494edc68337c9b99665e8f9b478f1d4ec5 (diff)
ASoC: simple-card: cleanup DAI link loop method - step1
Current simple-card is parsing DAI link for both "normal sound" and "DPCM sound". On this driver, it needs to count and parse DAIs/Links/Codec Conf from each links. Then, counting/parsing link loop are very similar, but using different implementation. Because of this background, the link loop code is very mysterious. Mystery code will be trouble in the future. This patch adds/modifies counting and parsing function for "normal sound" and "DPCM sound", and call it from link loop. This is prepare for cleanup DAI link loop method. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/generic')
-rw-r--r--sound/soc/generic/simple-card.c210
1 files changed, 137 insertions, 73 deletions
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 3820ad719059..4987db667165 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -187,32 +187,43 @@ static void asoc_simple_card_get_conversion(struct device *dev,
187 of_node_put(node); 187 of_node_put(node);
188} 188}
189 189
190static int asoc_simple_card_dai_link_of_dpcm(struct device_node *top, 190static int asoc_simple_card_dai_link_of_dpcm(struct simple_card_data *priv,
191 struct device_node *node,
192 struct device_node *np, 191 struct device_node *np,
193 struct device_node *codec, 192 struct device_node *codec,
194 struct simple_card_data *priv,
195 struct link_info *li, 193 struct link_info *li,
196 bool is_top_level_node) 194 bool is_top)
197{ 195{
198 struct device *dev = simple_priv_to_dev(priv); 196 struct device *dev = simple_priv_to_dev(priv);
199 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 197 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
200 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); 198 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
201 struct asoc_simple_dai *dai; 199 struct asoc_simple_dai *dai;
202 struct snd_soc_dai_link_component *codecs = dai_link->codecs; 200 struct snd_soc_dai_link_component *codecs = dai_link->codecs;
201 struct device_node *top = dev->of_node;
202 struct device_node *node = of_get_parent(np);
203 char prop[128]; 203 char prop[128];
204 char *prefix = ""; 204 char *prefix = "";
205 int ret; 205 int ret;
206 206
207 /*
208 * |CPU |Codec : turn
209 * CPU |Pass |return
210 * Codec |return|Pass
211 * np
212 */
213 if (li->cpu == (np == codec))
214 return 0;
215
207 dev_dbg(dev, "link_of DPCM (%pOF)\n", np); 216 dev_dbg(dev, "link_of DPCM (%pOF)\n", np);
208 217
209 li->link++; 218 li->link++;
210 219
220 of_node_put(node);
221
211 /* For single DAI link & old style of DT node */ 222 /* For single DAI link & old style of DT node */
212 if (is_top_level_node) 223 if (is_top)
213 prefix = PREFIX; 224 prefix = PREFIX;
214 225
215 if (np != codec) { 226 if (li->cpu) {
216 int is_single_links = 0; 227 int is_single_links = 0;
217 228
218 /* BE is dummy */ 229 /* BE is dummy */
@@ -312,53 +323,47 @@ static int asoc_simple_card_dai_link_of_dpcm(struct device_node *top,
312 return 0; 323 return 0;
313} 324}
314 325
315static int asoc_simple_card_dai_link_of(struct device_node *top, 326static int asoc_simple_card_dai_link_of(struct simple_card_data *priv,
316 struct device_node *node, 327 struct device_node *np,
317 struct simple_card_data *priv, 328 struct device_node *codec,
318 struct link_info *li, 329 struct link_info *li,
319 bool is_top_level_node) 330 bool is_top)
320{ 331{
321 struct device *dev = simple_priv_to_dev(priv); 332 struct device *dev = simple_priv_to_dev(priv);
322 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link); 333 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, li->link);
323 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link); 334 struct simple_dai_props *dai_props = simple_priv_to_props(priv, li->link);
324 struct asoc_simple_dai *cpu_dai; 335 struct asoc_simple_dai *cpu_dai;
325 struct asoc_simple_dai *codec_dai; 336 struct asoc_simple_dai *codec_dai;
337 struct device_node *top = dev->of_node;
326 struct device_node *cpu = NULL; 338 struct device_node *cpu = NULL;
339 struct device_node *node = NULL;
327 struct device_node *plat = NULL; 340 struct device_node *plat = NULL;
328 struct device_node *codec = NULL;
329 char prop[128]; 341 char prop[128];
330 char *prefix = ""; 342 char *prefix = "";
331 int ret, single_cpu; 343 int ret, single_cpu;
332 344
345 /*
346 * |CPU |Codec : turn
347 * CPU |Pass |return
348 * Codec |return|return
349 * np
350 */
351 if (!li->cpu || np == codec)
352 return 0;
353
354 cpu = np;
355 node = of_get_parent(np);
333 li->link++; 356 li->link++;
334 357
335 dev_dbg(dev, "link_of (%pOF)\n", node); 358 dev_dbg(dev, "link_of (%pOF)\n", node);
336 359
337 /* For single DAI link & old style of DT node */ 360 /* For single DAI link & old style of DT node */
338 if (is_top_level_node) 361 if (is_top)
339 prefix = PREFIX; 362 prefix = PREFIX;
340 363
341 snprintf(prop, sizeof(prop), "%scpu", prefix);
342 cpu = of_get_child_by_name(node, prop);
343
344 if (!cpu) {
345 ret = -EINVAL;
346 dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
347 goto dai_link_of_err;
348 }
349
350 snprintf(prop, sizeof(prop), "%splat", prefix); 364 snprintf(prop, sizeof(prop), "%splat", prefix);
351 plat = of_get_child_by_name(node, prop); 365 plat = of_get_child_by_name(node, prop);
352 366
353 snprintf(prop, sizeof(prop), "%scodec", prefix);
354 codec = of_get_child_by_name(node, prop);
355
356 if (!codec) {
357 ret = -EINVAL;
358 dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
359 goto dai_link_of_err;
360 }
361
362 cpu_dai = 367 cpu_dai =
363 dai_props->cpu_dai = &priv->dais[li->dais++]; 368 dai_props->cpu_dai = &priv->dais[li->dais++];
364 codec_dai = 369 codec_dai =
@@ -421,8 +426,7 @@ static int asoc_simple_card_dai_link_of(struct device_node *top,
421 asoc_simple_card_canonicalize_cpu(dai_link, single_cpu); 426 asoc_simple_card_canonicalize_cpu(dai_link, single_cpu);
422 427
423dai_link_of_err: 428dai_link_of_err:
424 of_node_put(cpu); 429 of_node_put(node);
425 of_node_put(codec);
426 430
427 return ret; 431 return ret;
428} 432}
@@ -464,9 +468,6 @@ static int asoc_simple_card_parse_of(struct simple_card_data *priv)
464 struct device_node *top = dev->of_node; 468 struct device_node *top = dev->of_node;
465 struct snd_soc_card *card = simple_priv_to_card(priv); 469 struct snd_soc_card *card = simple_priv_to_card(priv);
466 struct device_node *node; 470 struct device_node *node;
467 struct device_node *np;
468 struct device_node *codec;
469 struct asoc_simple_card_data adata;
470 struct link_info li; 471 struct link_info li;
471 int ret, loop; 472 int ret, loop;
472 473
@@ -483,6 +484,10 @@ static int asoc_simple_card_parse_of(struct simple_card_data *priv)
483 484
484 /* Single/Muti DAI link(s) & New style of DT node */ 485 /* Single/Muti DAI link(s) & New style of DT node */
485 memset(&li, 0, sizeof(li)); 486 memset(&li, 0, sizeof(li));
487
488 /* FIXME */
489 li.cpu = 1;
490parse_loop:
486 loop = 1; 491 loop = 1;
487 node = of_get_child_by_name(top, PREFIX "dai-link"); 492 node = of_get_child_by_name(top, PREFIX "dai-link");
488 if (!node) { 493 if (!node) {
@@ -491,37 +496,59 @@ static int asoc_simple_card_parse_of(struct simple_card_data *priv)
491 } 496 }
492 497
493 do { 498 do {
499 struct asoc_simple_card_data adata;
500 struct device_node *codec;
501 struct device_node *np;
502 int num = of_get_child_count(node);
503 int ret;
504
505 codec = of_get_child_by_name(node, !loop ?
506 PREFIX "codec" : "codec");
507 if (!codec)
508 return -ENODEV;
509
510 of_node_put(codec);
511
494 memset(&adata, 0, sizeof(adata)); 512 memset(&adata, 0, sizeof(adata));
495 for_each_child_of_node(node, np) 513 for_each_child_of_node(node, np)
496 asoc_simple_card_get_conversion(dev, np, &adata); 514 asoc_simple_card_get_conversion(dev, np, &adata);
497 515
498 /* DPCM */ 516 /*
499 if (of_get_child_count(node) > 2 || 517 * Detect all CPU first, and Detect all Codec 2nd.
500 adata.convert_rate || adata.convert_channels) { 518 *
501 for_each_child_of_node(node, np) { 519 * In Normal sound case, all DAIs are detected
502 codec = of_get_child_by_name(node, 520 * as "CPU-Codec".
503 loop ? "codec" : 521 *
504 PREFIX "codec"); 522 * In DPCM sound case,
505 if (!codec) 523 * all CPUs are detected as "CPU-dummy", and
506 return -ENODEV; 524 * all Codecs are detected as "dummy-Codec".
507 525 * To avoid random sub-device numbering,
526 * detect "dummy-Codec" in last;
527 */
528
529 /* loop for all CPU/Codec node */
530 for_each_child_of_node(node, np) {
531 if (num > 2 ||
532 adata.convert_rate || adata.convert_channels) {
508 ret = asoc_simple_card_dai_link_of_dpcm( 533 ret = asoc_simple_card_dai_link_of_dpcm(
509 top, node, np, codec, priv, 534 priv, np, codec, &li, !loop);
510 &li, !loop); 535 if (ret < 0)
536 return ret;
537 } else {
538 ret = asoc_simple_card_dai_link_of(
539 priv, np, codec, &li, !loop);
511 if (ret < 0) 540 if (ret < 0)
512 return ret; 541 return ret;
513 } 542 }
514 } else {
515 ret = asoc_simple_card_dai_link_of(
516 top, node, priv,
517 &li, !loop);
518 if (ret < 0)
519 return ret;
520 } 543 }
521
522 node = of_get_next_child(top, node); 544 node = of_get_next_child(top, node);
523 } while (loop && node); 545 } while (loop && node);
524 546
547 /* FIXME */
548 li.cpu--;
549 if (li.cpu >= 0)
550 goto parse_loop;
551
525 ret = asoc_simple_card_parse_card_name(card, PREFIX); 552 ret = asoc_simple_card_parse_card_name(card, PREFIX);
526 if (ret < 0) 553 if (ret < 0)
527 return ret; 554 return ret;
@@ -531,12 +558,39 @@ static int asoc_simple_card_parse_of(struct simple_card_data *priv)
531 return ret; 558 return ret;
532} 559}
533 560
534static void asoc_simple_card_get_dais_count(struct device *dev, 561static int asoc_simple_card_count_noml(struct simple_card_data *priv,
562 struct device_node *np,
563 struct device_node *codec,
564 struct link_info *li, bool is_top)
565{
566 li->dais++; /* CPU or Codec */
567 if (np != codec)
568 li->link++; /* CPU-Codec */
569
570 return 0;
571}
572
573static int asoc_simple_card_count_dpcm(struct simple_card_data *priv,
574 struct device_node *np,
575 struct device_node *codec,
576 struct link_info *li, bool is_top)
577{
578 li->dais++; /* CPU or Codec */
579 li->link++; /* CPU-dummy or dummy-Codec */
580 if (np == codec)
581 li->conf++;
582
583 return 0;
584}
585
586static void asoc_simple_card_get_dais_count(struct simple_card_data *priv,
535 struct link_info *li) 587 struct link_info *li)
536{ 588{
589 struct device *dev = simple_priv_to_dev(priv);
537 struct device_node *top = dev->of_node; 590 struct device_node *top = dev->of_node;
538 struct device_node *node; 591 struct device_node *node;
539 struct device_node *np; 592 struct device_node *np;
593 struct device_node *codec;
540 struct asoc_simple_card_data adata; 594 struct asoc_simple_card_data adata;
541 int loop; 595 int loop;
542 int num; 596 int num;
@@ -602,18 +656,28 @@ static void asoc_simple_card_get_dais_count(struct device *dev,
602 } 656 }
603 657
604 do { 658 do {
659 num = of_get_child_count(node);
660
661 codec = of_get_child_by_name(node, !loop ?
662 PREFIX "codec" : "codec");
663 if (!codec)
664 return;
665
666 of_node_put(codec);
667
605 memset(&adata, 0, sizeof(adata)); 668 memset(&adata, 0, sizeof(adata));
606 for_each_child_of_node(node, np) 669 for_each_child_of_node(node, np)
607 asoc_simple_card_get_conversion(dev, np, &adata); 670 asoc_simple_card_get_conversion(dev, np, &adata);
608 671
609 num = of_get_child_count(node); 672 for_each_child_of_node(node, np) {
610 li->dais += num; 673 if (num > 2 ||
611 if (num > 2 || 674 adata.convert_rate || adata.convert_channels) {
612 adata.convert_rate || adata.convert_channels) { 675 asoc_simple_card_count_dpcm(priv, np, codec,
613 li->link += num; 676 li, !loop);
614 li->conf++; 677 } else {
615 } else { 678 asoc_simple_card_count_noml(priv, np, codec,
616 li->link++; 679 li, !loop);
680 }
617 } 681 }
618 node = of_get_next_child(top, node); 682 node = of_get_next_child(top, node);
619 } while (loop && node); 683 } while (loop && node);
@@ -653,8 +717,13 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
653 if (!priv) 717 if (!priv)
654 return -ENOMEM; 718 return -ENOMEM;
655 719
720 card = simple_priv_to_card(priv);
721 card->owner = THIS_MODULE;
722 card->dev = dev;
723 card->probe = asoc_simple_soc_card_probe;
724
656 memset(&li, 0, sizeof(li)); 725 memset(&li, 0, sizeof(li));
657 asoc_simple_card_get_dais_count(dev, &li); 726 asoc_simple_card_get_dais_count(priv, &li);
658 if (!li.link || !li.dais) 727 if (!li.link || !li.dais)
659 return -EINVAL; 728 return -EINVAL;
660 729
@@ -677,20 +746,15 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
677 dai_link[i].platform = &dai_props[i].platform; 746 dai_link[i].platform = &dai_props[i].platform;
678 } 747 }
679 748
680 priv->dai_props = dai_props; 749 priv->dai_props = dai_props;
681 priv->dai_link = dai_link; 750 priv->dai_link = dai_link;
682 priv->dais = dais; 751 priv->dais = dais;
683 priv->codec_conf = cconf; 752 priv->codec_conf = cconf;
684 753
685 /* Init snd_soc_card */
686 card = simple_priv_to_card(priv);
687 card->owner = THIS_MODULE;
688 card->dev = dev;
689 card->dai_link = priv->dai_link; 754 card->dai_link = priv->dai_link;
690 card->num_links = li.link; 755 card->num_links = li.link;
691 card->codec_conf = cconf; 756 card->codec_conf = cconf;
692 card->num_configs = li.conf; 757 card->num_configs = li.conf;
693 card->probe = asoc_simple_soc_card_probe;
694 758
695 if (np && of_device_is_available(np)) { 759 if (np && of_device_is_available(np)) {
696 760