aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-core.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2008-12-04 10:32:53 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2008-12-09 08:30:04 -0500
commit435c5e2588893e3f7aba0bd4de67991bf00b3c9d (patch)
treeaa266a041709ae8a7a014162cf3564aca6c29d3c /sound/soc/soc-core.c
parent64089b84abfe2f26a864ebd968429302dcb071de (diff)
ASoC: Initial framework for dynamic card instantiation
Use the lists of platforms, platform DAIs and cards to check to see that everything has registered. Since relationships are still specified by direct references to the structures in the drivers and the drivers all register everything at modprobe there should be no practical effect yet. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/soc-core.c')
-rw-r--r--sound/soc/soc-core.c99
1 files changed, 79 insertions, 20 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index ffae370b45df..717db0e6499b 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -780,30 +780,54 @@ static int soc_resume(struct platform_device *pdev)
780#define soc_resume NULL 780#define soc_resume NULL
781#endif 781#endif
782 782
783/* probes a new socdev */ 783static void snd_soc_instantiate_card(struct snd_soc_card *card)
784static int soc_probe(struct platform_device *pdev) 784{
785{ 785 struct platform_device *pdev = container_of(card->dev,
786 int ret = 0, i; 786 struct platform_device,
787 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 787 dev);
788 struct snd_soc_card *card = socdev->card; 788 struct snd_soc_codec_device *codec_dev = card->socdev->codec_dev;
789 struct snd_soc_platform *platform = card->platform; 789 struct snd_soc_platform *platform;
790 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 790 struct snd_soc_dai *dai;
791 791 int i, found, ret;
792 /* Bodge while we push things out of socdev */ 792
793 card->socdev = socdev; 793 if (card->instantiated)
794 return;
795
796 found = 0;
797 list_for_each_entry(platform, &platform_list, list)
798 if (card->platform == platform) {
799 found = 1;
800 break;
801 }
802 if (!found) {
803 dev_dbg(card->dev, "Platform %s not registered\n",
804 card->platform->name);
805 return;
806 }
794 807
795 /* Bodge while we unpick instantiation */ 808 for (i = 0; i < card->num_links; i++) {
796 card->dev = &pdev->dev; 809 found = 0;
797 ret = snd_soc_register_card(card); 810 list_for_each_entry(dai, &dai_list, list)
798 if (ret != 0) { 811 if (card->dai_link[i].cpu_dai == dai) {
799 dev_err(&pdev->dev, "Failed to register card\n"); 812 found = 1;
800 return ret; 813 break;
814 }
815 if (!found) {
816 dev_dbg(card->dev, "DAI %s not registered\n",
817 card->dai_link[i].cpu_dai->name);
818 return;
819 }
801 } 820 }
802 821
822 /* Note that we do not current check for codec components */
823
824 dev_dbg(card->dev, "All components present, instantiating\n");
825
826 /* Found everything, bring it up */
803 if (card->probe) { 827 if (card->probe) {
804 ret = card->probe(pdev); 828 ret = card->probe(pdev);
805 if (ret < 0) 829 if (ret < 0)
806 return ret; 830 return;
807 } 831 }
808 832
809 for (i = 0; i < card->num_links; i++) { 833 for (i = 0; i < card->num_links; i++) {
@@ -834,7 +858,9 @@ static int soc_probe(struct platform_device *pdev)
834 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred); 858 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
835#endif 859#endif
836 860
837 return 0; 861 card->instantiated = 1;
862
863 return;
838 864
839platform_err: 865platform_err:
840 if (codec_dev->remove) 866 if (codec_dev->remove)
@@ -849,8 +875,38 @@ cpu_dai_err:
849 875
850 if (card->remove) 876 if (card->remove)
851 card->remove(pdev); 877 card->remove(pdev);
878}
852 879
853 return ret; 880/*
881 * Attempt to initialise any uninitalised cards. Must be called with
882 * client_mutex.
883 */
884static void snd_soc_instantiate_cards(void)
885{
886 struct snd_soc_card *card;
887 list_for_each_entry(card, &card_list, list)
888 snd_soc_instantiate_card(card);
889}
890
891/* probes a new socdev */
892static int soc_probe(struct platform_device *pdev)
893{
894 int ret = 0;
895 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
896 struct snd_soc_card *card = socdev->card;
897
898 /* Bodge while we push things out of socdev */
899 card->socdev = socdev;
900
901 /* Bodge while we unpick instantiation */
902 card->dev = &pdev->dev;
903 ret = snd_soc_register_card(card);
904 if (ret != 0) {
905 dev_err(&pdev->dev, "Failed to register card\n");
906 return ret;
907 }
908
909 return 0;
854} 910}
855 911
856/* removes a socdev */ 912/* removes a socdev */
@@ -1994,6 +2050,7 @@ static int snd_soc_register_card(struct snd_soc_card *card)
1994 2050
1995 mutex_lock(&client_mutex); 2051 mutex_lock(&client_mutex);
1996 list_add(&card->list, &card_list); 2052 list_add(&card->list, &card_list);
2053 snd_soc_instantiate_cards();
1997 mutex_unlock(&client_mutex); 2054 mutex_unlock(&client_mutex);
1998 2055
1999 dev_dbg(card->dev, "Registered card '%s'\n", card->name); 2056 dev_dbg(card->dev, "Registered card '%s'\n", card->name);
@@ -2039,6 +2096,7 @@ int snd_soc_register_dai(struct snd_soc_dai *dai)
2039 2096
2040 mutex_lock(&client_mutex); 2097 mutex_lock(&client_mutex);
2041 list_add(&dai->list, &dai_list); 2098 list_add(&dai->list, &dai_list);
2099 snd_soc_instantiate_cards();
2042 mutex_unlock(&client_mutex); 2100 mutex_unlock(&client_mutex);
2043 2101
2044 pr_debug("Registered DAI '%s'\n", dai->name); 2102 pr_debug("Registered DAI '%s'\n", dai->name);
@@ -2117,6 +2175,7 @@ int snd_soc_register_platform(struct snd_soc_platform *platform)
2117 2175
2118 mutex_lock(&client_mutex); 2176 mutex_lock(&client_mutex);
2119 list_add(&platform->list, &platform_list); 2177 list_add(&platform->list, &platform_list);
2178 snd_soc_instantiate_cards();
2120 mutex_unlock(&client_mutex); 2179 mutex_unlock(&client_mutex);
2121 2180
2122 pr_debug("Registered platform '%s'\n", platform->name); 2181 pr_debug("Registered platform '%s'\n", platform->name);