aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh/rcar/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sh/rcar/core.c')
-rw-r--r--sound/soc/sh/rcar/core.c122
1 files changed, 119 insertions, 3 deletions
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c
index 6a1b45df8101..e77f7716f1d7 100644
--- a/sound/soc/sh/rcar/core.c
+++ b/sound/soc/sh/rcar/core.c
@@ -100,6 +100,21 @@
100#define RSND_RATES SNDRV_PCM_RATE_8000_96000 100#define RSND_RATES SNDRV_PCM_RATE_8000_96000
101#define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) 101#define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
102 102
103static struct rsnd_of_data rsnd_of_data_gen1 = {
104 .flags = RSND_GEN1,
105};
106
107static struct rsnd_of_data rsnd_of_data_gen2 = {
108 .flags = RSND_GEN2,
109};
110
111static struct of_device_id rsnd_of_match[] = {
112 { .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 },
113 { .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 },
114 {},
115};
116MODULE_DEVICE_TABLE(of, rsnd_of_match);
117
103/* 118/*
104 * rsnd_platform functions 119 * rsnd_platform functions
105 */ 120 */
@@ -620,7 +635,92 @@ static int rsnd_path_init(struct rsnd_priv *priv,
620 return ret; 635 return ret;
621} 636}
622 637
638static void rsnd_of_parse_dai(struct platform_device *pdev,
639 const struct rsnd_of_data *of_data,
640 struct rsnd_priv *priv)
641{
642 struct device_node *dai_node, *dai_np;
643 struct device_node *ssi_node, *ssi_np;
644 struct device_node *src_node, *src_np;
645 struct device_node *playback, *capture;
646 struct rsnd_dai_platform_info *dai_info;
647 struct rcar_snd_info *info = rsnd_priv_to_info(priv);
648 struct device *dev = &pdev->dev;
649 int nr, i;
650 int dai_i, ssi_i, src_i;
651
652 if (!of_data)
653 return;
654
655 dai_node = of_get_child_by_name(dev->of_node, "rcar_sound,dai");
656 if (!dai_node)
657 return;
658
659 nr = of_get_child_count(dai_node);
660 if (!nr)
661 return;
662
663 dai_info = devm_kzalloc(dev,
664 sizeof(struct rsnd_dai_platform_info) * nr,
665 GFP_KERNEL);
666 if (!dai_info) {
667 dev_err(dev, "dai info allocation error\n");
668 return;
669 }
670
671 info->dai_info_nr = nr;
672 info->dai_info = dai_info;
673
674 ssi_node = of_get_child_by_name(dev->of_node, "rcar_sound,ssi");
675 src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src");
676
677#define mod_parse(name) \
678if (name##_node) { \
679 struct rsnd_##name##_platform_info *name##_info; \
680 \
681 name##_i = 0; \
682 for_each_child_of_node(name##_node, name##_np) { \
683 name##_info = info->name##_info + name##_i; \
684 \
685 if (name##_np == playback) \
686 dai_info->playback.name = name##_info; \
687 if (name##_np == capture) \
688 dai_info->capture.name = name##_info; \
689 \
690 name##_i++; \
691 } \
692}
693
694 /*
695 * parse all dai
696 */
697 dai_i = 0;
698 for_each_child_of_node(dai_node, dai_np) {
699 dai_info = info->dai_info + dai_i;
700
701 for (i = 0;; i++) {
702
703 playback = of_parse_phandle(dai_np, "playback", i);
704 capture = of_parse_phandle(dai_np, "capture", i);
705
706 if (!playback && !capture)
707 break;
708
709 mod_parse(ssi);
710 mod_parse(src);
711
712 if (playback)
713 of_node_put(playback);
714 if (capture)
715 of_node_put(capture);
716 }
717
718 dai_i++;
719 }
720}
721
623static int rsnd_dai_probe(struct platform_device *pdev, 722static int rsnd_dai_probe(struct platform_device *pdev,
723 const struct rsnd_of_data *of_data,
624 struct rsnd_priv *priv) 724 struct rsnd_priv *priv)
625{ 725{
626 struct snd_soc_dai_driver *drv; 726 struct snd_soc_dai_driver *drv;
@@ -628,13 +728,16 @@ static int rsnd_dai_probe(struct platform_device *pdev,
628 struct rsnd_dai *rdai; 728 struct rsnd_dai *rdai;
629 struct rsnd_mod *pmod, *cmod; 729 struct rsnd_mod *pmod, *cmod;
630 struct device *dev = rsnd_priv_to_dev(priv); 730 struct device *dev = rsnd_priv_to_dev(priv);
631 int dai_nr = info->dai_info_nr; 731 int dai_nr;
632 int i; 732 int i;
633 733
734 rsnd_of_parse_dai(pdev, of_data, priv);
735
634 /* 736 /*
635 * dai_nr should be set via dai_info_nr, 737 * dai_nr should be set via dai_info_nr,
636 * but allow it to keeping compatible 738 * but allow it to keeping compatible
637 */ 739 */
740 dai_nr = info->dai_info_nr;
638 if (!dai_nr) { 741 if (!dai_nr) {
639 /* get max dai nr */ 742 /* get max dai nr */
640 for (dai_nr = 0; dai_nr < 32; dai_nr++) { 743 for (dai_nr = 0; dai_nr < 32; dai_nr++) {
@@ -802,7 +905,10 @@ static int rsnd_probe(struct platform_device *pdev)
802 struct rsnd_priv *priv; 905 struct rsnd_priv *priv;
803 struct device *dev = &pdev->dev; 906 struct device *dev = &pdev->dev;
804 struct rsnd_dai *rdai; 907 struct rsnd_dai *rdai;
908 const struct of_device_id *of_id = of_match_device(rsnd_of_match, dev);
909 const struct rsnd_of_data *of_data;
805 int (*probe_func[])(struct platform_device *pdev, 910 int (*probe_func[])(struct platform_device *pdev,
911 const struct rsnd_of_data *of_data,
806 struct rsnd_priv *priv) = { 912 struct rsnd_priv *priv) = {
807 rsnd_gen_probe, 913 rsnd_gen_probe,
808 rsnd_ssi_probe, 914 rsnd_ssi_probe,
@@ -812,7 +918,16 @@ static int rsnd_probe(struct platform_device *pdev)
812 }; 918 };
813 int ret, i; 919 int ret, i;
814 920
815 info = pdev->dev.platform_data; 921 info = NULL;
922 of_data = NULL;
923 if (of_id) {
924 info = devm_kzalloc(&pdev->dev,
925 sizeof(struct rcar_snd_info), GFP_KERNEL);
926 of_data = of_id->data;
927 } else {
928 info = pdev->dev.platform_data;
929 }
930
816 if (!info) { 931 if (!info) {
817 dev_err(dev, "driver needs R-Car sound information\n"); 932 dev_err(dev, "driver needs R-Car sound information\n");
818 return -ENODEV; 933 return -ENODEV;
@@ -835,7 +950,7 @@ static int rsnd_probe(struct platform_device *pdev)
835 * init each module 950 * init each module
836 */ 951 */
837 for (i = 0; i < ARRAY_SIZE(probe_func); i++) { 952 for (i = 0; i < ARRAY_SIZE(probe_func); i++) {
838 ret = probe_func[i](pdev, priv); 953 ret = probe_func[i](pdev, of_data, priv);
839 if (ret) 954 if (ret)
840 return ret; 955 return ret;
841 } 956 }
@@ -903,6 +1018,7 @@ static int rsnd_remove(struct platform_device *pdev)
903static struct platform_driver rsnd_driver = { 1018static struct platform_driver rsnd_driver = {
904 .driver = { 1019 .driver = {
905 .name = "rcar_sound", 1020 .name = "rcar_sound",
1021 .of_match_table = rsnd_of_match,
906 }, 1022 },
907 .probe = rsnd_probe, 1023 .probe = rsnd_probe,
908 .remove = rsnd_remove, 1024 .remove = rsnd_remove,