diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2014-03-09 12:41:47 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2014-03-10 08:17:54 -0400 |
commit | 1438c2f60ba955114cff3717f1a334878c7886a9 (patch) | |
tree | 838e16b20b2b89eee2d3f119fdec176c765919d5 | |
parent | 6cc240f39d393c5878bc6cf053aa0fe8e3fe4260 (diff) |
ASoC: Add a per component dai list
Now that every DAI has a component we can track the DAIs on a per component
basis. This simplifies the DAI lookup when we are only interested in DAIs of a
specific component and also makes it possible to have multiple components with
the same parent device and also register DAIs.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r-- | include/sound/soc.h | 2 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 76 |
2 files changed, 36 insertions, 42 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h index b14acd8228ab..37b470c1e127 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -671,6 +671,8 @@ struct snd_soc_component { | |||
671 | int num_dai; | 671 | int num_dai; |
672 | 672 | ||
673 | const struct snd_soc_component_driver *driver; | 673 | const struct snd_soc_component_driver *driver; |
674 | |||
675 | struct list_head dai_list; | ||
674 | }; | 676 | }; |
675 | 677 | ||
676 | /* SoC Audio Codec device */ | 678 | /* SoC Audio Codec device */ |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index cc522418e9c4..f34f1a01fce1 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -56,7 +56,6 @@ EXPORT_SYMBOL_GPL(snd_soc_debugfs_root); | |||
56 | #endif | 56 | #endif |
57 | 57 | ||
58 | static DEFINE_MUTEX(client_mutex); | 58 | static DEFINE_MUTEX(client_mutex); |
59 | static LIST_HEAD(dai_list); | ||
60 | static LIST_HEAD(platform_list); | 59 | static LIST_HEAD(platform_list); |
61 | static LIST_HEAD(codec_list); | 60 | static LIST_HEAD(codec_list); |
62 | static LIST_HEAD(component_list); | 61 | static LIST_HEAD(component_list); |
@@ -370,18 +369,22 @@ static ssize_t dai_list_read_file(struct file *file, char __user *user_buf, | |||
370 | { | 369 | { |
371 | char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | 370 | char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); |
372 | ssize_t len, ret = 0; | 371 | ssize_t len, ret = 0; |
372 | struct snd_soc_component *component; | ||
373 | struct snd_soc_dai *dai; | 373 | struct snd_soc_dai *dai; |
374 | 374 | ||
375 | if (!buf) | 375 | if (!buf) |
376 | return -ENOMEM; | 376 | return -ENOMEM; |
377 | 377 | ||
378 | list_for_each_entry(dai, &dai_list, list) { | 378 | list_for_each_entry(component, &component_list, list) { |
379 | len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", dai->name); | 379 | list_for_each_entry(dai, &component->dai_list, list) { |
380 | if (len >= 0) | 380 | len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", |
381 | ret += len; | 381 | dai->name); |
382 | if (ret > PAGE_SIZE) { | 382 | if (len >= 0) |
383 | ret = PAGE_SIZE; | 383 | ret += len; |
384 | break; | 384 | if (ret > PAGE_SIZE) { |
385 | ret = PAGE_SIZE; | ||
386 | break; | ||
387 | } | ||
385 | } | 388 | } |
386 | } | 389 | } |
387 | 390 | ||
@@ -855,6 +858,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
855 | { | 858 | { |
856 | struct snd_soc_dai_link *dai_link = &card->dai_link[num]; | 859 | struct snd_soc_dai_link *dai_link = &card->dai_link[num]; |
857 | struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; | 860 | struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; |
861 | struct snd_soc_component *component; | ||
858 | struct snd_soc_codec *codec; | 862 | struct snd_soc_codec *codec; |
859 | struct snd_soc_platform *platform; | 863 | struct snd_soc_platform *platform; |
860 | struct snd_soc_dai *codec_dai, *cpu_dai; | 864 | struct snd_soc_dai *codec_dai, *cpu_dai; |
@@ -863,18 +867,20 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
863 | dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num); | 867 | dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num); |
864 | 868 | ||
865 | /* Find CPU DAI from registered DAIs*/ | 869 | /* Find CPU DAI from registered DAIs*/ |
866 | list_for_each_entry(cpu_dai, &dai_list, list) { | 870 | list_for_each_entry(component, &component_list, list) { |
867 | if (dai_link->cpu_of_node && | 871 | if (dai_link->cpu_of_node && |
868 | (cpu_dai->dev->of_node != dai_link->cpu_of_node)) | 872 | component->dev->of_node != dai_link->cpu_of_node) |
869 | continue; | 873 | continue; |
870 | if (dai_link->cpu_name && | 874 | if (dai_link->cpu_name && |
871 | strcmp(dev_name(cpu_dai->dev), dai_link->cpu_name)) | 875 | strcmp(dev_name(component->dev), dai_link->cpu_name)) |
872 | continue; | ||
873 | if (dai_link->cpu_dai_name && | ||
874 | strcmp(cpu_dai->name, dai_link->cpu_dai_name)) | ||
875 | continue; | 876 | continue; |
877 | list_for_each_entry(cpu_dai, &component->dai_list, list) { | ||
878 | if (dai_link->cpu_dai_name && | ||
879 | strcmp(cpu_dai->name, dai_link->cpu_dai_name)) | ||
880 | continue; | ||
876 | 881 | ||
877 | rtd->cpu_dai = cpu_dai; | 882 | rtd->cpu_dai = cpu_dai; |
883 | } | ||
878 | } | 884 | } |
879 | 885 | ||
880 | if (!rtd->cpu_dai) { | 886 | if (!rtd->cpu_dai) { |
@@ -899,12 +905,10 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
899 | * CODEC found, so find CODEC DAI from registered DAIs from | 905 | * CODEC found, so find CODEC DAI from registered DAIs from |
900 | * this CODEC | 906 | * this CODEC |
901 | */ | 907 | */ |
902 | list_for_each_entry(codec_dai, &dai_list, list) { | 908 | list_for_each_entry(codec_dai, &codec->component.dai_list, list) { |
903 | if (codec->dev == codec_dai->dev && | 909 | if (!strcmp(codec_dai->name, dai_link->codec_dai_name)) { |
904 | !strcmp(codec_dai->name, | ||
905 | dai_link->codec_dai_name)) { | ||
906 | |||
907 | rtd->codec_dai = codec_dai; | 910 | rtd->codec_dai = codec_dai; |
911 | break; | ||
908 | } | 912 | } |
909 | } | 913 | } |
910 | 914 | ||
@@ -1128,12 +1132,8 @@ static int soc_probe_codec(struct snd_soc_card *card, | |||
1128 | driver->num_dapm_widgets); | 1132 | driver->num_dapm_widgets); |
1129 | 1133 | ||
1130 | /* Create DAPM widgets for each DAI stream */ | 1134 | /* Create DAPM widgets for each DAI stream */ |
1131 | list_for_each_entry(dai, &dai_list, list) { | 1135 | list_for_each_entry(dai, &codec->component.dai_list, list) |
1132 | if (dai->dev != codec->dev) | ||
1133 | continue; | ||
1134 | |||
1135 | snd_soc_dapm_new_dai_widgets(&codec->dapm, dai); | 1136 | snd_soc_dapm_new_dai_widgets(&codec->dapm, dai); |
1136 | } | ||
1137 | 1137 | ||
1138 | codec->dapm.idle_bias_off = driver->idle_bias_off; | 1138 | codec->dapm.idle_bias_off = driver->idle_bias_off; |
1139 | 1139 | ||
@@ -1180,6 +1180,7 @@ static int soc_probe_platform(struct snd_soc_card *card, | |||
1180 | { | 1180 | { |
1181 | int ret = 0; | 1181 | int ret = 0; |
1182 | const struct snd_soc_platform_driver *driver = platform->driver; | 1182 | const struct snd_soc_platform_driver *driver = platform->driver; |
1183 | struct snd_soc_component *component; | ||
1183 | struct snd_soc_dai *dai; | 1184 | struct snd_soc_dai *dai; |
1184 | 1185 | ||
1185 | platform->card = card; | 1186 | platform->card = card; |
@@ -1195,11 +1196,11 @@ static int soc_probe_platform(struct snd_soc_card *card, | |||
1195 | driver->dapm_widgets, driver->num_dapm_widgets); | 1196 | driver->dapm_widgets, driver->num_dapm_widgets); |
1196 | 1197 | ||
1197 | /* Create DAPM widgets for each DAI stream */ | 1198 | /* Create DAPM widgets for each DAI stream */ |
1198 | list_for_each_entry(dai, &dai_list, list) { | 1199 | list_for_each_entry(component, &component_list, list) { |
1199 | if (dai->dev != platform->dev) | 1200 | if (component->dev != platform->dev) |
1200 | continue; | 1201 | continue; |
1201 | 1202 | list_for_each_entry(dai, &component->dai_list, list) | |
1202 | snd_soc_dapm_new_dai_widgets(&platform->dapm, dai); | 1203 | snd_soc_dapm_new_dai_widgets(&platform->dapm, dai); |
1203 | } | 1204 | } |
1204 | 1205 | ||
1205 | platform->dapm.idle_bias_off = 1; | 1206 | platform->dapm.idle_bias_off = 1; |
@@ -3912,21 +3913,14 @@ static inline char *fmt_multiple_name(struct device *dev, | |||
3912 | */ | 3913 | */ |
3913 | static void snd_soc_unregister_dais(struct snd_soc_component *component) | 3914 | static void snd_soc_unregister_dais(struct snd_soc_component *component) |
3914 | { | 3915 | { |
3915 | struct snd_soc_dai *dai, *_dai; | 3916 | struct snd_soc_dai *dai; |
3916 | |||
3917 | mutex_lock(&client_mutex); | ||
3918 | list_for_each_entry_safe(dai, _dai, &dai_list, list) { | ||
3919 | if (dai->dev != component->dev) | ||
3920 | continue; | ||
3921 | |||
3922 | list_del(&dai->list); | ||
3923 | 3917 | ||
3918 | list_for_each_entry(dai, &component->dai_list, list) { | ||
3924 | dev_dbg(component->dev, "ASoC: Unregistered DAI '%s'\n", | 3919 | dev_dbg(component->dev, "ASoC: Unregistered DAI '%s'\n", |
3925 | dai->name); | 3920 | dai->name); |
3926 | kfree(dai->name); | 3921 | kfree(dai->name); |
3927 | kfree(dai); | 3922 | kfree(dai); |
3928 | } | 3923 | } |
3929 | mutex_unlock(&client_mutex); | ||
3930 | } | 3924 | } |
3931 | 3925 | ||
3932 | /** | 3926 | /** |
@@ -3990,13 +3984,10 @@ static int snd_soc_register_dais(struct snd_soc_component *component, | |||
3990 | if (!dai->driver->ops) | 3984 | if (!dai->driver->ops) |
3991 | dai->driver->ops = &null_dai_ops; | 3985 | dai->driver->ops = &null_dai_ops; |
3992 | 3986 | ||
3993 | |||
3994 | if (!dai->codec) | 3987 | if (!dai->codec) |
3995 | dai->dapm.idle_bias_off = 1; | 3988 | dai->dapm.idle_bias_off = 1; |
3996 | 3989 | ||
3997 | mutex_lock(&client_mutex); | 3990 | list_add(&dai->list, &component->dai_list); |
3998 | list_add(&dai->list, &dai_list); | ||
3999 | mutex_unlock(&client_mutex); | ||
4000 | 3991 | ||
4001 | dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name); | 3992 | dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name); |
4002 | } | 3993 | } |
@@ -4040,6 +4031,7 @@ __snd_soc_register_component(struct device *dev, | |||
4040 | cmpnt->driver = cmpnt_drv; | 4031 | cmpnt->driver = cmpnt_drv; |
4041 | cmpnt->dai_drv = dai_drv; | 4032 | cmpnt->dai_drv = dai_drv; |
4042 | cmpnt->num_dai = num_dai; | 4033 | cmpnt->num_dai = num_dai; |
4034 | INIT_LIST_HEAD(&cmpnt->dai_list); | ||
4043 | 4035 | ||
4044 | ret = snd_soc_register_dais(cmpnt, codec, dai_drv, num_dai, | 4036 | ret = snd_soc_register_dais(cmpnt, codec, dai_drv, num_dai, |
4045 | allow_single_dai); | 4037 | allow_single_dai); |