diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2008-11-28 08:29:45 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2008-12-09 05:49:26 -0500 |
commit | c5af3a2e192d333997d1e191f3eba7fd2f869681 (patch) | |
tree | bd63c16c657b473ea3823faae5644642d9ae88db | |
parent | ca4513fe06c483bf0111c990059d42f97288605d (diff) |
ASoC: Add card registration API
ASoC v2 allows cards, codecs and platforms to instantiate separately,
with the overall ASoC device only being instantiated once all the
required components have registered. As part of backporting Liam's work
introduce an initial version of the card registration functions. At
present these do nothing active and are internal only, they will be
exposed to machine drivers after further backporting. Adding this now
allows the datastructures used for dynamic card instantiation to be
built up gradually.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r-- | include/sound/soc.h | 5 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 62 |
2 files changed, 67 insertions, 0 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h index 79d855d2bddd..4a578b5d855c 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -333,6 +333,11 @@ struct snd_soc_dai_link { | |||
333 | /* SoC card */ | 333 | /* SoC card */ |
334 | struct snd_soc_card { | 334 | struct snd_soc_card { |
335 | char *name; | 335 | char *name; |
336 | struct device *dev; | ||
337 | |||
338 | struct list_head list; | ||
339 | |||
340 | int instantiated; | ||
336 | 341 | ||
337 | int (*probe)(struct platform_device *pdev); | 342 | int (*probe)(struct platform_device *pdev); |
338 | int (*remove)(struct platform_device *pdev); | 343 | int (*remove)(struct platform_device *pdev); |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 2f2a8d93bbf0..44fbd71ce80f 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -43,6 +43,12 @@ static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq); | |||
43 | static struct dentry *debugfs_root; | 43 | static struct dentry *debugfs_root; |
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | static DEFINE_MUTEX(client_mutex); | ||
47 | static LIST_HEAD(card_list); | ||
48 | |||
49 | static int snd_soc_register_card(struct snd_soc_card *card); | ||
50 | static int snd_soc_unregister_card(struct snd_soc_card *card); | ||
51 | |||
46 | /* | 52 | /* |
47 | * This is a timeout to do a DAPM powerdown after a stream is closed(). | 53 | * This is a timeout to do a DAPM powerdown after a stream is closed(). |
48 | * It can be used to eliminate pops between different playback streams, e.g. | 54 | * It can be used to eliminate pops between different playback streams, e.g. |
@@ -784,6 +790,14 @@ static int soc_probe(struct platform_device *pdev) | |||
784 | /* Bodge while we push things out of socdev */ | 790 | /* Bodge while we push things out of socdev */ |
785 | card->socdev = socdev; | 791 | card->socdev = socdev; |
786 | 792 | ||
793 | /* Bodge while we unpick instantiation */ | ||
794 | card->dev = &pdev->dev; | ||
795 | ret = snd_soc_register_card(card); | ||
796 | if (ret != 0) { | ||
797 | dev_err(&pdev->dev, "Failed to register card\n"); | ||
798 | return ret; | ||
799 | } | ||
800 | |||
787 | if (card->probe) { | 801 | if (card->probe) { |
788 | ret = card->probe(pdev); | 802 | ret = card->probe(pdev); |
789 | if (ret < 0) | 803 | if (ret < 0) |
@@ -863,6 +877,8 @@ static int soc_remove(struct platform_device *pdev) | |||
863 | if (card->remove) | 877 | if (card->remove) |
864 | card->remove(pdev); | 878 | card->remove(pdev); |
865 | 879 | ||
880 | snd_soc_unregister_card(card); | ||
881 | |||
866 | return 0; | 882 | return 0; |
867 | } | 883 | } |
868 | 884 | ||
@@ -1957,6 +1973,52 @@ int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute) | |||
1957 | } | 1973 | } |
1958 | EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute); | 1974 | EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute); |
1959 | 1975 | ||
1976 | /** | ||
1977 | * snd_soc_register_card - Register a card with the ASoC core | ||
1978 | * | ||
1979 | * @param card Card to register | ||
1980 | * | ||
1981 | * Note that currently this is an internal only function: it will be | ||
1982 | * exposed to machine drivers after further backporting of ASoC v2 | ||
1983 | * registration APIs. | ||
1984 | */ | ||
1985 | static int snd_soc_register_card(struct snd_soc_card *card) | ||
1986 | { | ||
1987 | if (!card->name || !card->dev) | ||
1988 | return -EINVAL; | ||
1989 | |||
1990 | INIT_LIST_HEAD(&card->list); | ||
1991 | card->instantiated = 0; | ||
1992 | |||
1993 | mutex_lock(&client_mutex); | ||
1994 | list_add(&card->list, &card_list); | ||
1995 | mutex_unlock(&client_mutex); | ||
1996 | |||
1997 | dev_dbg(card->dev, "Registered card '%s'\n", card->name); | ||
1998 | |||
1999 | return 0; | ||
2000 | } | ||
2001 | |||
2002 | /** | ||
2003 | * snd_soc_unregister_card - Unregister a card with the ASoC core | ||
2004 | * | ||
2005 | * @param card Card to unregister | ||
2006 | * | ||
2007 | * Note that currently this is an internal only function: it will be | ||
2008 | * exposed to machine drivers after further backporting of ASoC v2 | ||
2009 | * registration APIs. | ||
2010 | */ | ||
2011 | static int snd_soc_unregister_card(struct snd_soc_card *card) | ||
2012 | { | ||
2013 | mutex_lock(&client_mutex); | ||
2014 | list_del(&card->list); | ||
2015 | mutex_unlock(&client_mutex); | ||
2016 | |||
2017 | dev_dbg(card->dev, "Unregistered card '%s'\n", card->name); | ||
2018 | |||
2019 | return 0; | ||
2020 | } | ||
2021 | |||
1960 | static int __devinit snd_soc_init(void) | 2022 | static int __devinit snd_soc_init(void) |
1961 | { | 2023 | { |
1962 | #ifdef CONFIG_DEBUG_FS | 2024 | #ifdef CONFIG_DEBUG_FS |