aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/soc-core.c')
-rw-r--r--sound/soc/soc-core.c673
1 files changed, 286 insertions, 387 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d074aa91b023..4c8f8a23a0e9 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -270,79 +270,54 @@ static const struct file_operations codec_reg_fops = {
270 .llseek = default_llseek, 270 .llseek = default_llseek,
271}; 271};
272 272
273static struct dentry *soc_debugfs_create_dir(struct dentry *parent, 273static void soc_init_component_debugfs(struct snd_soc_component *component)
274 const char *fmt, ...)
275{ 274{
276 struct dentry *de; 275 if (component->debugfs_prefix) {
277 va_list ap; 276 char *name;
278 char *s;
279 277
280 va_start(ap, fmt); 278 name = kasprintf(GFP_KERNEL, "%s:%s",
281 s = kvasprintf(GFP_KERNEL, fmt, ap); 279 component->debugfs_prefix, component->name);
282 va_end(ap); 280 if (name) {
281 component->debugfs_root = debugfs_create_dir(name,
282 component->card->debugfs_card_root);
283 kfree(name);
284 }
285 } else {
286 component->debugfs_root = debugfs_create_dir(component->name,
287 component->card->debugfs_card_root);
288 }
283 289
284 if (!s) 290 if (!component->debugfs_root) {
285 return NULL; 291 dev_warn(component->dev,
292 "ASoC: Failed to create component debugfs directory\n");
293 return;
294 }
286 295
287 de = debugfs_create_dir(s, parent); 296 snd_soc_dapm_debugfs_init(snd_soc_component_get_dapm(component),
288 kfree(s); 297 component->debugfs_root);
289 298
290 return de; 299 if (component->init_debugfs)
300 component->init_debugfs(component);
291} 301}
292 302
293static void soc_init_codec_debugfs(struct snd_soc_codec *codec) 303static void soc_cleanup_component_debugfs(struct snd_soc_component *component)
294{ 304{
295 struct dentry *debugfs_card_root = codec->component.card->debugfs_card_root; 305 debugfs_remove_recursive(component->debugfs_root);
306}
296 307
297 codec->debugfs_codec_root = soc_debugfs_create_dir(debugfs_card_root, 308static void soc_init_codec_debugfs(struct snd_soc_component *component)
298 "codec:%s", 309{
299 codec->component.name); 310 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
300 if (!codec->debugfs_codec_root) {
301 dev_warn(codec->dev,
302 "ASoC: Failed to create codec debugfs directory\n");
303 return;
304 }
305 311
306 debugfs_create_bool("cache_sync", 0444, codec->debugfs_codec_root, 312 debugfs_create_bool("cache_sync", 0444, codec->component.debugfs_root,
307 &codec->cache_sync); 313 &codec->cache_sync);
308 debugfs_create_bool("cache_only", 0444, codec->debugfs_codec_root,
309 &codec->cache_only);
310 314
311 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644, 315 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
312 codec->debugfs_codec_root, 316 codec->component.debugfs_root,
313 codec, &codec_reg_fops); 317 codec, &codec_reg_fops);
314 if (!codec->debugfs_reg) 318 if (!codec->debugfs_reg)
315 dev_warn(codec->dev, 319 dev_warn(codec->dev,
316 "ASoC: Failed to create codec register debugfs file\n"); 320 "ASoC: Failed to create codec register debugfs file\n");
317
318 snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root);
319}
320
321static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
322{
323 debugfs_remove_recursive(codec->debugfs_codec_root);
324}
325
326static void soc_init_platform_debugfs(struct snd_soc_platform *platform)
327{
328 struct dentry *debugfs_card_root = platform->component.card->debugfs_card_root;
329
330 platform->debugfs_platform_root = soc_debugfs_create_dir(debugfs_card_root,
331 "platform:%s",
332 platform->component.name);
333 if (!platform->debugfs_platform_root) {
334 dev_warn(platform->dev,
335 "ASoC: Failed to create platform debugfs directory\n");
336 return;
337 }
338
339 snd_soc_dapm_debugfs_init(&platform->component.dapm,
340 platform->debugfs_platform_root);
341}
342
343static void soc_cleanup_platform_debugfs(struct snd_soc_platform *platform)
344{
345 debugfs_remove_recursive(platform->debugfs_platform_root);
346} 321}
347 322
348static ssize_t codec_list_read_file(struct file *file, char __user *user_buf, 323static ssize_t codec_list_read_file(struct file *file, char __user *user_buf,
@@ -474,19 +449,15 @@ static void soc_cleanup_card_debugfs(struct snd_soc_card *card)
474 449
475#else 450#else
476 451
477static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec) 452#define soc_init_codec_debugfs NULL
478{
479}
480 453
481static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) 454static inline void soc_init_component_debugfs(
455 struct snd_soc_component *component)
482{ 456{
483} 457}
484 458
485static inline void soc_init_platform_debugfs(struct snd_soc_platform *platform) 459static inline void soc_cleanup_component_debugfs(
486{ 460 struct snd_soc_component *component)
487}
488
489static inline void soc_cleanup_platform_debugfs(struct snd_soc_platform *platform)
490{ 461{
491} 462}
492 463
@@ -579,10 +550,8 @@ int snd_soc_suspend(struct device *dev)
579 struct snd_soc_codec *codec; 550 struct snd_soc_codec *codec;
580 int i, j; 551 int i, j;
581 552
582 /* If the initialization of this soc device failed, there is no codec 553 /* If the card is not initialized yet there is nothing to do */
583 * associated with it. Just bail out in this case. 554 if (!card->instantiated)
584 */
585 if (list_empty(&card->codec_dev_list))
586 return 0; 555 return 0;
587 556
588 /* Due to the resume being scheduled into a workqueue we could 557 /* Due to the resume being scheduled into a workqueue we could
@@ -668,7 +637,7 @@ int snd_soc_suspend(struct device *dev)
668 list_for_each_entry(codec, &card->codec_dev_list, card_list) { 637 list_for_each_entry(codec, &card->codec_dev_list, card_list) {
669 /* If there are paths active then the CODEC will be held with 638 /* If there are paths active then the CODEC will be held with
670 * bias _ON and should not be suspended. */ 639 * bias _ON and should not be suspended. */
671 if (!codec->suspended && codec->driver->suspend) { 640 if (!codec->suspended) {
672 switch (codec->dapm.bias_level) { 641 switch (codec->dapm.bias_level) {
673 case SND_SOC_BIAS_STANDBY: 642 case SND_SOC_BIAS_STANDBY:
674 /* 643 /*
@@ -682,8 +651,10 @@ int snd_soc_suspend(struct device *dev)
682 "ASoC: idle_bias_off CODEC on over suspend\n"); 651 "ASoC: idle_bias_off CODEC on over suspend\n");
683 break; 652 break;
684 } 653 }
654
685 case SND_SOC_BIAS_OFF: 655 case SND_SOC_BIAS_OFF:
686 codec->driver->suspend(codec); 656 if (codec->driver->suspend)
657 codec->driver->suspend(codec);
687 codec->suspended = 1; 658 codec->suspended = 1;
688 codec->cache_sync = 1; 659 codec->cache_sync = 1;
689 if (codec->component.regmap) 660 if (codec->component.regmap)
@@ -757,11 +728,12 @@ static void soc_resume_deferred(struct work_struct *work)
757 * left with bias OFF or STANDBY and suspended so we must now 728 * left with bias OFF or STANDBY and suspended so we must now
758 * resume. Otherwise the suspend was suppressed. 729 * resume. Otherwise the suspend was suppressed.
759 */ 730 */
760 if (codec->driver->resume && codec->suspended) { 731 if (codec->suspended) {
761 switch (codec->dapm.bias_level) { 732 switch (codec->dapm.bias_level) {
762 case SND_SOC_BIAS_STANDBY: 733 case SND_SOC_BIAS_STANDBY:
763 case SND_SOC_BIAS_OFF: 734 case SND_SOC_BIAS_OFF:
764 codec->driver->resume(codec); 735 if (codec->driver->resume)
736 codec->driver->resume(codec);
765 codec->suspended = 0; 737 codec->suspended = 0;
766 break; 738 break;
767 default: 739 default:
@@ -835,10 +807,8 @@ int snd_soc_resume(struct device *dev)
835 struct snd_soc_card *card = dev_get_drvdata(dev); 807 struct snd_soc_card *card = dev_get_drvdata(dev);
836 int i, ac97_control = 0; 808 int i, ac97_control = 0;
837 809
838 /* If the initialization of this soc device failed, there is no codec 810 /* If the card is not initialized yet there is nothing to do */
839 * associated with it. Just bail out in this case. 811 if (!card->instantiated)
840 */
841 if (list_empty(&card->codec_dev_list))
842 return 0; 812 return 0;
843 813
844 /* activate pins from sleep state */ 814 /* activate pins from sleep state */
@@ -887,35 +857,40 @@ EXPORT_SYMBOL_GPL(snd_soc_resume);
887static const struct snd_soc_dai_ops null_dai_ops = { 857static const struct snd_soc_dai_ops null_dai_ops = {
888}; 858};
889 859
890static struct snd_soc_codec *soc_find_codec( 860static struct snd_soc_component *soc_find_component(
891 const struct device_node *codec_of_node, 861 const struct device_node *of_node, const char *name)
892 const char *codec_name)
893{ 862{
894 struct snd_soc_codec *codec; 863 struct snd_soc_component *component;
895 864
896 list_for_each_entry(codec, &codec_list, list) { 865 list_for_each_entry(component, &component_list, list) {
897 if (codec_of_node) { 866 if (of_node) {
898 if (codec->dev->of_node != codec_of_node) 867 if (component->dev->of_node == of_node)
899 continue; 868 return component;
900 } else { 869 } else if (strcmp(component->name, name) == 0) {
901 if (strcmp(codec->component.name, codec_name)) 870 return component;
902 continue;
903 } 871 }
904
905 return codec;
906 } 872 }
907 873
908 return NULL; 874 return NULL;
909} 875}
910 876
911static struct snd_soc_dai *soc_find_codec_dai(struct snd_soc_codec *codec, 877static struct snd_soc_dai *snd_soc_find_dai(
912 const char *codec_dai_name) 878 const struct snd_soc_dai_link_component *dlc)
913{ 879{
914 struct snd_soc_dai *codec_dai; 880 struct snd_soc_component *component;
881 struct snd_soc_dai *dai;
915 882
916 list_for_each_entry(codec_dai, &codec->component.dai_list, list) { 883 /* Find CPU DAI from registered DAIs*/
917 if (!strcmp(codec_dai->name, codec_dai_name)) { 884 list_for_each_entry(component, &component_list, list) {
918 return codec_dai; 885 if (dlc->of_node && component->dev->of_node != dlc->of_node)
886 continue;
887 if (dlc->name && strcmp(dev_name(component->dev), dlc->name))
888 continue;
889 list_for_each_entry(dai, &component->dai_list, list) {
890 if (dlc->dai_name && strcmp(dai->name, dlc->dai_name))
891 continue;
892
893 return dai;
919 } 894 }
920 } 895 }
921 896
@@ -926,33 +901,19 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
926{ 901{
927 struct snd_soc_dai_link *dai_link = &card->dai_link[num]; 902 struct snd_soc_dai_link *dai_link = &card->dai_link[num];
928 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 903 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
929 struct snd_soc_component *component;
930 struct snd_soc_dai_link_component *codecs = dai_link->codecs; 904 struct snd_soc_dai_link_component *codecs = dai_link->codecs;
905 struct snd_soc_dai_link_component cpu_dai_component;
931 struct snd_soc_dai **codec_dais = rtd->codec_dais; 906 struct snd_soc_dai **codec_dais = rtd->codec_dais;
932 struct snd_soc_platform *platform; 907 struct snd_soc_platform *platform;
933 struct snd_soc_dai *cpu_dai;
934 const char *platform_name; 908 const char *platform_name;
935 int i; 909 int i;
936 910
937 dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num); 911 dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num);
938 912
939 /* Find CPU DAI from registered DAIs*/ 913 cpu_dai_component.name = dai_link->cpu_name;
940 list_for_each_entry(component, &component_list, list) { 914 cpu_dai_component.of_node = dai_link->cpu_of_node;
941 if (dai_link->cpu_of_node && 915 cpu_dai_component.dai_name = dai_link->cpu_dai_name;
942 component->dev->of_node != dai_link->cpu_of_node) 916 rtd->cpu_dai = snd_soc_find_dai(&cpu_dai_component);
943 continue;
944 if (dai_link->cpu_name &&
945 strcmp(dev_name(component->dev), dai_link->cpu_name))
946 continue;
947 list_for_each_entry(cpu_dai, &component->dai_list, list) {
948 if (dai_link->cpu_dai_name &&
949 strcmp(cpu_dai->name, dai_link->cpu_dai_name))
950 continue;
951
952 rtd->cpu_dai = cpu_dai;
953 }
954 }
955
956 if (!rtd->cpu_dai) { 917 if (!rtd->cpu_dai) {
957 dev_err(card->dev, "ASoC: CPU DAI %s not registered\n", 918 dev_err(card->dev, "ASoC: CPU DAI %s not registered\n",
958 dai_link->cpu_dai_name); 919 dai_link->cpu_dai_name);
@@ -963,15 +924,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
963 924
964 /* Find CODEC from registered CODECs */ 925 /* Find CODEC from registered CODECs */
965 for (i = 0; i < rtd->num_codecs; i++) { 926 for (i = 0; i < rtd->num_codecs; i++) {
966 struct snd_soc_codec *codec; 927 codec_dais[i] = snd_soc_find_dai(&codecs[i]);
967 codec = soc_find_codec(codecs[i].of_node, codecs[i].name);
968 if (!codec) {
969 dev_err(card->dev, "ASoC: CODEC %s not registered\n",
970 codecs[i].name);
971 return -EPROBE_DEFER;
972 }
973
974 codec_dais[i] = soc_find_codec_dai(codec, codecs[i].dai_name);
975 if (!codec_dais[i]) { 928 if (!codec_dais[i]) {
976 dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n", 929 dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n",
977 codecs[i].dai_name); 930 codecs[i].dai_name);
@@ -1012,68 +965,46 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
1012 return 0; 965 return 0;
1013} 966}
1014 967
1015static int soc_remove_platform(struct snd_soc_platform *platform) 968static void soc_remove_component(struct snd_soc_component *component)
1016{ 969{
1017 int ret; 970 if (!component->probed)
1018 971 return;
1019 if (platform->driver->remove) {
1020 ret = platform->driver->remove(platform);
1021 if (ret < 0)
1022 dev_err(platform->dev, "ASoC: failed to remove %d\n",
1023 ret);
1024 }
1025
1026 /* Make sure all DAPM widgets are freed */
1027 snd_soc_dapm_free(&platform->component.dapm);
1028
1029 soc_cleanup_platform_debugfs(platform);
1030 platform->probed = 0;
1031 module_put(platform->dev->driver->owner);
1032
1033 return 0;
1034}
1035 972
1036static void soc_remove_codec(struct snd_soc_codec *codec) 973 /* This is a HACK and will be removed soon */
1037{ 974 if (component->codec)
1038 int err; 975 list_del(&component->codec->card_list);
1039 976
1040 if (codec->driver->remove) { 977 if (component->remove)
1041 err = codec->driver->remove(codec); 978 component->remove(component);
1042 if (err < 0)
1043 dev_err(codec->dev, "ASoC: failed to remove %d\n", err);
1044 }
1045 979
1046 /* Make sure all DAPM widgets are freed */ 980 snd_soc_dapm_free(snd_soc_component_get_dapm(component));
1047 snd_soc_dapm_free(&codec->dapm);
1048 981
1049 soc_cleanup_codec_debugfs(codec); 982 soc_cleanup_component_debugfs(component);
1050 codec->probed = 0; 983 component->probed = 0;
1051 list_del(&codec->card_list); 984 module_put(component->dev->driver->owner);
1052 module_put(codec->dev->driver->owner);
1053} 985}
1054 986
1055static void soc_remove_codec_dai(struct snd_soc_dai *codec_dai, int order) 987static void soc_remove_dai(struct snd_soc_dai *dai, int order)
1056{ 988{
1057 int err; 989 int err;
1058 990
1059 if (codec_dai && codec_dai->probed && 991 if (dai && dai->probed &&
1060 codec_dai->driver->remove_order == order) { 992 dai->driver->remove_order == order) {
1061 if (codec_dai->driver->remove) { 993 if (dai->driver->remove) {
1062 err = codec_dai->driver->remove(codec_dai); 994 err = dai->driver->remove(dai);
1063 if (err < 0) 995 if (err < 0)
1064 dev_err(codec_dai->dev, 996 dev_err(dai->dev,
1065 "ASoC: failed to remove %s: %d\n", 997 "ASoC: failed to remove %s: %d\n",
1066 codec_dai->name, err); 998 dai->name, err);
1067 } 999 }
1068 codec_dai->probed = 0; 1000 dai->probed = 0;
1069 } 1001 }
1070} 1002}
1071 1003
1072static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) 1004static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order)
1073{ 1005{
1074 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 1006 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1075 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1007 int i;
1076 int i, err;
1077 1008
1078 /* unregister the rtd device */ 1009 /* unregister the rtd device */
1079 if (rtd->dev_registered) { 1010 if (rtd->dev_registered) {
@@ -1085,22 +1016,9 @@ static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order)
1085 1016
1086 /* remove the CODEC DAI */ 1017 /* remove the CODEC DAI */
1087 for (i = 0; i < rtd->num_codecs; i++) 1018 for (i = 0; i < rtd->num_codecs; i++)
1088 soc_remove_codec_dai(rtd->codec_dais[i], order); 1019 soc_remove_dai(rtd->codec_dais[i], order);
1089 1020
1090 /* remove the cpu_dai */ 1021 soc_remove_dai(rtd->cpu_dai, order);
1091 if (cpu_dai && cpu_dai->probed &&
1092 cpu_dai->driver->remove_order == order) {
1093 if (cpu_dai->driver->remove) {
1094 err = cpu_dai->driver->remove(cpu_dai);
1095 if (err < 0)
1096 dev_err(cpu_dai->dev,
1097 "ASoC: failed to remove %s: %d\n",
1098 cpu_dai->name, err);
1099 }
1100 cpu_dai->probed = 0;
1101 if (!cpu_dai->codec)
1102 module_put(cpu_dai->dev->driver->owner);
1103 }
1104} 1022}
1105 1023
1106static void soc_remove_link_components(struct snd_soc_card *card, int num, 1024static void soc_remove_link_components(struct snd_soc_card *card, int num,
@@ -1109,29 +1027,24 @@ static void soc_remove_link_components(struct snd_soc_card *card, int num,
1109 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 1027 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1110 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1028 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1111 struct snd_soc_platform *platform = rtd->platform; 1029 struct snd_soc_platform *platform = rtd->platform;
1112 struct snd_soc_codec *codec; 1030 struct snd_soc_component *component;
1113 int i; 1031 int i;
1114 1032
1115 /* remove the platform */ 1033 /* remove the platform */
1116 if (platform && platform->probed && 1034 if (platform && platform->component.driver->remove_order == order)
1117 platform->driver->remove_order == order) { 1035 soc_remove_component(&platform->component);
1118 soc_remove_platform(platform);
1119 }
1120 1036
1121 /* remove the CODEC-side CODEC */ 1037 /* remove the CODEC-side CODEC */
1122 for (i = 0; i < rtd->num_codecs; i++) { 1038 for (i = 0; i < rtd->num_codecs; i++) {
1123 codec = rtd->codec_dais[i]->codec; 1039 component = rtd->codec_dais[i]->component;
1124 if (codec && codec->probed && 1040 if (component->driver->remove_order == order)
1125 codec->driver->remove_order == order) 1041 soc_remove_component(component);
1126 soc_remove_codec(codec);
1127 } 1042 }
1128 1043
1129 /* remove any CPU-side CODEC */ 1044 /* remove any CPU-side CODEC */
1130 if (cpu_dai) { 1045 if (cpu_dai) {
1131 codec = cpu_dai->codec; 1046 if (cpu_dai->component->driver->remove_order == order)
1132 if (codec && codec->probed && 1047 soc_remove_component(cpu_dai->component);
1133 codec->driver->remove_order == order)
1134 soc_remove_codec(codec);
1135 } 1048 }
1136} 1049}
1137 1050
@@ -1173,137 +1086,78 @@ static void soc_set_name_prefix(struct snd_soc_card *card,
1173 } 1086 }
1174} 1087}
1175 1088
1176static int soc_probe_codec(struct snd_soc_card *card, 1089static int soc_probe_component(struct snd_soc_card *card,
1177 struct snd_soc_codec *codec) 1090 struct snd_soc_component *component)
1178{ 1091{
1179 int ret = 0; 1092 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
1180 const struct snd_soc_codec_driver *driver = codec->driver;
1181 struct snd_soc_dai *dai; 1093 struct snd_soc_dai *dai;
1094 int ret;
1182 1095
1183 codec->component.card = card; 1096 if (component->probed)
1184 codec->dapm.card = card; 1097 return 0;
1185 soc_set_name_prefix(card, &codec->component); 1098
1099 component->card = card;
1100 dapm->card = card;
1101 soc_set_name_prefix(card, component);
1186 1102
1187 if (!try_module_get(codec->dev->driver->owner)) 1103 if (!try_module_get(component->dev->driver->owner))
1188 return -ENODEV; 1104 return -ENODEV;
1189 1105
1190 soc_init_codec_debugfs(codec); 1106 soc_init_component_debugfs(component);
1191 1107
1192 if (driver->dapm_widgets) { 1108 if (component->dapm_widgets) {
1193 ret = snd_soc_dapm_new_controls(&codec->dapm, 1109 ret = snd_soc_dapm_new_controls(dapm, component->dapm_widgets,
1194 driver->dapm_widgets, 1110 component->num_dapm_widgets);
1195 driver->num_dapm_widgets);
1196 1111
1197 if (ret != 0) { 1112 if (ret != 0) {
1198 dev_err(codec->dev, 1113 dev_err(component->dev,
1199 "Failed to create new controls %d\n", ret); 1114 "Failed to create new controls %d\n", ret);
1200 goto err_probe; 1115 goto err_probe;
1201 } 1116 }
1202 } 1117 }
1203 1118
1204 /* Create DAPM widgets for each DAI stream */ 1119 list_for_each_entry(dai, &component->dai_list, list) {
1205 list_for_each_entry(dai, &codec->component.dai_list, list) { 1120 ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
1206 ret = snd_soc_dapm_new_dai_widgets(&codec->dapm, dai);
1207
1208 if (ret != 0) { 1121 if (ret != 0) {
1209 dev_err(codec->dev, 1122 dev_err(component->dev,
1210 "Failed to create DAI widgets %d\n", ret); 1123 "Failed to create DAI widgets %d\n", ret);
1211 goto err_probe; 1124 goto err_probe;
1212 } 1125 }
1213 } 1126 }
1214 1127
1215 codec->dapm.idle_bias_off = driver->idle_bias_off; 1128 if (component->probe) {
1216 1129 ret = component->probe(component);
1217 if (driver->probe) {
1218 ret = driver->probe(codec);
1219 if (ret < 0) { 1130 if (ret < 0) {
1220 dev_err(codec->dev, 1131 dev_err(component->dev,
1221 "ASoC: failed to probe CODEC %d\n", ret); 1132 "ASoC: failed to probe component %d\n", ret);
1222 goto err_probe; 1133 goto err_probe;
1223 } 1134 }
1224 WARN(codec->dapm.idle_bias_off && 1135
1225 codec->dapm.bias_level != SND_SOC_BIAS_OFF, 1136 WARN(dapm->idle_bias_off &&
1137 dapm->bias_level != SND_SOC_BIAS_OFF,
1226 "codec %s can not start from non-off bias with idle_bias_off==1\n", 1138 "codec %s can not start from non-off bias with idle_bias_off==1\n",
1227 codec->component.name); 1139 component->name);
1228 } 1140 }
1229 1141
1230 if (driver->controls) 1142 if (component->controls)
1231 snd_soc_add_codec_controls(codec, driver->controls, 1143 snd_soc_add_component_controls(component, component->controls,
1232 driver->num_controls); 1144 component->num_controls);
1233 if (driver->dapm_routes) 1145 if (component->dapm_routes)
1234 snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes, 1146 snd_soc_dapm_add_routes(dapm, component->dapm_routes,
1235 driver->num_dapm_routes); 1147 component->num_dapm_routes);
1236
1237 /* mark codec as probed and add to card codec list */
1238 codec->probed = 1;
1239 list_add(&codec->card_list, &card->codec_dev_list);
1240 list_add(&codec->dapm.list, &card->dapm_list);
1241
1242 return 0;
1243
1244err_probe:
1245 soc_cleanup_codec_debugfs(codec);
1246 module_put(codec->dev->driver->owner);
1247
1248 return ret;
1249}
1250
1251static int soc_probe_platform(struct snd_soc_card *card,
1252 struct snd_soc_platform *platform)
1253{
1254 int ret = 0;
1255 const struct snd_soc_platform_driver *driver = platform->driver;
1256 struct snd_soc_component *component;
1257 struct snd_soc_dai *dai;
1258
1259 platform->component.card = card;
1260 platform->component.dapm.card = card;
1261 1148
1262 if (!try_module_get(platform->dev->driver->owner)) 1149 component->probed = 1;
1263 return -ENODEV; 1150 list_add(&dapm->list, &card->dapm_list);
1264
1265 soc_init_platform_debugfs(platform);
1266 1151
1267 if (driver->dapm_widgets) 1152 /* This is a HACK and will be removed soon */
1268 snd_soc_dapm_new_controls(&platform->component.dapm, 1153 if (component->codec)
1269 driver->dapm_widgets, driver->num_dapm_widgets); 1154 list_add(&component->codec->card_list, &card->codec_dev_list);
1270
1271 /* Create DAPM widgets for each DAI stream */
1272 list_for_each_entry(component, &component_list, list) {
1273 if (component->dev != platform->dev)
1274 continue;
1275 list_for_each_entry(dai, &component->dai_list, list)
1276 snd_soc_dapm_new_dai_widgets(&platform->component.dapm,
1277 dai);
1278 }
1279
1280 platform->component.dapm.idle_bias_off = 1;
1281
1282 if (driver->probe) {
1283 ret = driver->probe(platform);
1284 if (ret < 0) {
1285 dev_err(platform->dev,
1286 "ASoC: failed to probe platform %d\n", ret);
1287 goto err_probe;
1288 }
1289 }
1290
1291 if (driver->controls)
1292 snd_soc_add_platform_controls(platform, driver->controls,
1293 driver->num_controls);
1294 if (driver->dapm_routes)
1295 snd_soc_dapm_add_routes(&platform->component.dapm,
1296 driver->dapm_routes, driver->num_dapm_routes);
1297
1298 /* mark platform as probed and add to card platform list */
1299 platform->probed = 1;
1300 list_add(&platform->component.dapm.list, &card->dapm_list);
1301 1155
1302 return 0; 1156 return 0;
1303 1157
1304err_probe: 1158err_probe:
1305 soc_cleanup_platform_debugfs(platform); 1159 soc_cleanup_component_debugfs(component);
1306 module_put(platform->dev->driver->owner); 1160 module_put(component->dev->driver->owner);
1307 1161
1308 return ret; 1162 return ret;
1309} 1163}
@@ -1342,17 +1196,21 @@ static int soc_post_component_init(struct snd_soc_pcm_runtime *rtd,
1342 } 1196 }
1343 rtd->dev_registered = 1; 1197 rtd->dev_registered = 1;
1344 1198
1345 /* add DAPM sysfs entries for this codec */ 1199 if (rtd->codec) {
1346 ret = snd_soc_dapm_sys_add(rtd->dev); 1200 /* add DAPM sysfs entries for this codec */
1347 if (ret < 0) 1201 ret = snd_soc_dapm_sys_add(rtd->dev);
1348 dev_err(rtd->dev, 1202 if (ret < 0)
1349 "ASoC: failed to add codec dapm sysfs entries: %d\n", ret); 1203 dev_err(rtd->dev,
1204 "ASoC: failed to add codec dapm sysfs entries: %d\n",
1205 ret);
1350 1206
1351 /* add codec sysfs entries */ 1207 /* add codec sysfs entries */
1352 ret = device_create_file(rtd->dev, &dev_attr_codec_reg); 1208 ret = device_create_file(rtd->dev, &dev_attr_codec_reg);
1353 if (ret < 0) 1209 if (ret < 0)
1354 dev_err(rtd->dev, 1210 dev_err(rtd->dev,
1355 "ASoC: failed to add codec sysfs files: %d\n", ret); 1211 "ASoC: failed to add codec sysfs files: %d\n",
1212 ret);
1213 }
1356 1214
1357 return 0; 1215 return 0;
1358} 1216}
@@ -1361,33 +1219,31 @@ static int soc_probe_link_components(struct snd_soc_card *card, int num,
1361 int order) 1219 int order)
1362{ 1220{
1363 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 1221 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1364 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1365 struct snd_soc_platform *platform = rtd->platform; 1222 struct snd_soc_platform *platform = rtd->platform;
1223 struct snd_soc_component *component;
1366 int i, ret; 1224 int i, ret;
1367 1225
1368 /* probe the CPU-side component, if it is a CODEC */ 1226 /* probe the CPU-side component, if it is a CODEC */
1369 if (cpu_dai->codec && 1227 component = rtd->cpu_dai->component;
1370 !cpu_dai->codec->probed && 1228 if (component->driver->probe_order == order) {
1371 cpu_dai->codec->driver->probe_order == order) { 1229 ret = soc_probe_component(card, component);
1372 ret = soc_probe_codec(card, cpu_dai->codec);
1373 if (ret < 0) 1230 if (ret < 0)
1374 return ret; 1231 return ret;
1375 } 1232 }
1376 1233
1377 /* probe the CODEC-side components */ 1234 /* probe the CODEC-side components */
1378 for (i = 0; i < rtd->num_codecs; i++) { 1235 for (i = 0; i < rtd->num_codecs; i++) {
1379 if (!rtd->codec_dais[i]->codec->probed && 1236 component = rtd->codec_dais[i]->component;
1380 rtd->codec_dais[i]->codec->driver->probe_order == order) { 1237 if (component->driver->probe_order == order) {
1381 ret = soc_probe_codec(card, rtd->codec_dais[i]->codec); 1238 ret = soc_probe_component(card, component);
1382 if (ret < 0) 1239 if (ret < 0)
1383 return ret; 1240 return ret;
1384 } 1241 }
1385 } 1242 }
1386 1243
1387 /* probe the platform */ 1244 /* probe the platform */
1388 if (!platform->probed && 1245 if (platform->component.driver->probe_order == order) {
1389 platform->driver->probe_order == order) { 1246 ret = soc_probe_component(card, &platform->component);
1390 ret = soc_probe_platform(card, platform);
1391 if (ret < 0) 1247 if (ret < 0)
1392 return ret; 1248 return ret;
1393 } 1249 }
@@ -1482,18 +1338,12 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
1482 /* probe the cpu_dai */ 1338 /* probe the cpu_dai */
1483 if (!cpu_dai->probed && 1339 if (!cpu_dai->probed &&
1484 cpu_dai->driver->probe_order == order) { 1340 cpu_dai->driver->probe_order == order) {
1485 if (!cpu_dai->codec) {
1486 if (!try_module_get(cpu_dai->dev->driver->owner))
1487 return -ENODEV;
1488 }
1489
1490 if (cpu_dai->driver->probe) { 1341 if (cpu_dai->driver->probe) {
1491 ret = cpu_dai->driver->probe(cpu_dai); 1342 ret = cpu_dai->driver->probe(cpu_dai);
1492 if (ret < 0) { 1343 if (ret < 0) {
1493 dev_err(cpu_dai->dev, 1344 dev_err(cpu_dai->dev,
1494 "ASoC: failed to probe CPU DAI %s: %d\n", 1345 "ASoC: failed to probe CPU DAI %s: %d\n",
1495 cpu_dai->name, ret); 1346 cpu_dai->name, ret);
1496 module_put(cpu_dai->dev->driver->owner);
1497 return ret; 1347 return ret;
1498 } 1348 }
1499 } 1349 }
@@ -1654,17 +1504,24 @@ static int soc_bind_aux_dev(struct snd_soc_card *card, int num)
1654{ 1504{
1655 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; 1505 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
1656 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; 1506 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1657 const char *codecname = aux_dev->codec_name; 1507 const char *name = aux_dev->codec_name;
1658 1508
1659 rtd->codec = soc_find_codec(aux_dev->codec_of_node, codecname); 1509 rtd->component = soc_find_component(aux_dev->codec_of_node, name);
1660 if (!rtd->codec) { 1510 if (!rtd->component) {
1661 if (aux_dev->codec_of_node) 1511 if (aux_dev->codec_of_node)
1662 codecname = of_node_full_name(aux_dev->codec_of_node); 1512 name = of_node_full_name(aux_dev->codec_of_node);
1663 1513
1664 dev_err(card->dev, "ASoC: %s not registered\n", codecname); 1514 dev_err(card->dev, "ASoC: %s not registered\n", name);
1665 return -EPROBE_DEFER; 1515 return -EPROBE_DEFER;
1666 } 1516 }
1667 1517
1518 /*
1519 * Some places still reference rtd->codec, so we have to keep that
1520 * initialized if the component is a CODEC. Once all those references
1521 * have been removed, this code can be removed as well.
1522 */
1523 rtd->codec = rtd->component->codec;
1524
1668 return 0; 1525 return 0;
1669} 1526}
1670 1527
@@ -1674,18 +1531,13 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
1674 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; 1531 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1675 int ret; 1532 int ret;
1676 1533
1677 if (rtd->codec->probed) { 1534 ret = soc_probe_component(card, rtd->component);
1678 dev_err(rtd->codec->dev, "ASoC: codec already probed\n");
1679 return -EBUSY;
1680 }
1681
1682 ret = soc_probe_codec(card, rtd->codec);
1683 if (ret < 0) 1535 if (ret < 0)
1684 return ret; 1536 return ret;
1685 1537
1686 /* do machine specific initialization */ 1538 /* do machine specific initialization */
1687 if (aux_dev->init) { 1539 if (aux_dev->init) {
1688 ret = aux_dev->init(&rtd->codec->dapm); 1540 ret = aux_dev->init(rtd->component);
1689 if (ret < 0) { 1541 if (ret < 0) {
1690 dev_err(card->dev, "ASoC: failed to init %s: %d\n", 1542 dev_err(card->dev, "ASoC: failed to init %s: %d\n",
1691 aux_dev->name, ret); 1543 aux_dev->name, ret);
@@ -1699,7 +1551,7 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
1699static void soc_remove_aux_dev(struct snd_soc_card *card, int num) 1551static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
1700{ 1552{
1701 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; 1553 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
1702 struct snd_soc_codec *codec = rtd->codec; 1554 struct snd_soc_component *component = rtd->component;
1703 1555
1704 /* unregister the rtd device */ 1556 /* unregister the rtd device */
1705 if (rtd->dev_registered) { 1557 if (rtd->dev_registered) {
@@ -1708,8 +1560,8 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
1708 rtd->dev_registered = 0; 1560 rtd->dev_registered = 0;
1709 } 1561 }
1710 1562
1711 if (codec && codec->probed) 1563 if (component && component->probed)
1712 soc_remove_codec(codec); 1564 soc_remove_component(component);
1713} 1565}
1714 1566
1715static int snd_soc_init_codec_cache(struct snd_soc_codec *codec) 1567static int snd_soc_init_codec_cache(struct snd_soc_codec *codec)
@@ -2107,19 +1959,14 @@ static struct platform_driver soc_driver = {
2107int snd_soc_new_ac97_codec(struct snd_soc_codec *codec, 1959int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
2108 struct snd_ac97_bus_ops *ops, int num) 1960 struct snd_ac97_bus_ops *ops, int num)
2109{ 1961{
2110 mutex_lock(&codec->mutex);
2111
2112 codec->ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL); 1962 codec->ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL);
2113 if (codec->ac97 == NULL) { 1963 if (codec->ac97 == NULL)
2114 mutex_unlock(&codec->mutex);
2115 return -ENOMEM; 1964 return -ENOMEM;
2116 }
2117 1965
2118 codec->ac97->bus = kzalloc(sizeof(struct snd_ac97_bus), GFP_KERNEL); 1966 codec->ac97->bus = kzalloc(sizeof(struct snd_ac97_bus), GFP_KERNEL);
2119 if (codec->ac97->bus == NULL) { 1967 if (codec->ac97->bus == NULL) {
2120 kfree(codec->ac97); 1968 kfree(codec->ac97);
2121 codec->ac97 = NULL; 1969 codec->ac97 = NULL;
2122 mutex_unlock(&codec->mutex);
2123 return -ENOMEM; 1970 return -ENOMEM;
2124 } 1971 }
2125 1972
@@ -2132,7 +1979,6 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
2132 */ 1979 */
2133 codec->ac97_created = 1; 1980 codec->ac97_created = 1;
2134 1981
2135 mutex_unlock(&codec->mutex);
2136 return 0; 1982 return 0;
2137} 1983}
2138EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec); 1984EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
@@ -2302,7 +2148,6 @@ EXPORT_SYMBOL_GPL(snd_soc_set_ac97_ops_of_reset);
2302 */ 2148 */
2303void snd_soc_free_ac97_codec(struct snd_soc_codec *codec) 2149void snd_soc_free_ac97_codec(struct snd_soc_codec *codec)
2304{ 2150{
2305 mutex_lock(&codec->mutex);
2306#ifdef CONFIG_SND_SOC_AC97_BUS 2151#ifdef CONFIG_SND_SOC_AC97_BUS
2307 soc_unregister_ac97_codec(codec); 2152 soc_unregister_ac97_codec(codec);
2308#endif 2153#endif
@@ -2310,7 +2155,6 @@ void snd_soc_free_ac97_codec(struct snd_soc_codec *codec)
2310 kfree(codec->ac97); 2155 kfree(codec->ac97);
2311 codec->ac97 = NULL; 2156 codec->ac97 = NULL;
2312 codec->ac97_created = 0; 2157 codec->ac97_created = 0;
2313 mutex_unlock(&codec->mutex);
2314} 2158}
2315EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec); 2159EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec);
2316 2160
@@ -3027,9 +2871,10 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
3027 unsigned int val, val_mask; 2871 unsigned int val, val_mask;
3028 int ret; 2872 int ret;
3029 2873
3030 val = ((ucontrol->value.integer.value[0] + min) & mask);
3031 if (invert) 2874 if (invert)
3032 val = max - val; 2875 val = (max - ucontrol->value.integer.value[0]) & mask;
2876 else
2877 val = ((ucontrol->value.integer.value[0] + min) & mask);
3033 val_mask = mask << shift; 2878 val_mask = mask << shift;
3034 val = val << shift; 2879 val = val << shift;
3035 2880
@@ -3038,9 +2883,10 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
3038 return ret; 2883 return ret;
3039 2884
3040 if (snd_soc_volsw_is_stereo(mc)) { 2885 if (snd_soc_volsw_is_stereo(mc)) {
3041 val = ((ucontrol->value.integer.value[1] + min) & mask);
3042 if (invert) 2886 if (invert)
3043 val = max - val; 2887 val = (max - ucontrol->value.integer.value[1]) & mask;
2888 else
2889 val = ((ucontrol->value.integer.value[1] + min) & mask);
3044 val_mask = mask << shift; 2890 val_mask = mask << shift;
3045 val = val << shift; 2891 val = val << shift;
3046 2892
@@ -3085,8 +2931,9 @@ int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol,
3085 if (invert) 2931 if (invert)
3086 ucontrol->value.integer.value[0] = 2932 ucontrol->value.integer.value[0] =
3087 max - ucontrol->value.integer.value[0]; 2933 max - ucontrol->value.integer.value[0];
3088 ucontrol->value.integer.value[0] = 2934 else
3089 ucontrol->value.integer.value[0] - min; 2935 ucontrol->value.integer.value[0] =
2936 ucontrol->value.integer.value[0] - min;
3090 2937
3091 if (snd_soc_volsw_is_stereo(mc)) { 2938 if (snd_soc_volsw_is_stereo(mc)) {
3092 ret = snd_soc_component_read(component, rreg, &val); 2939 ret = snd_soc_component_read(component, rreg, &val);
@@ -3097,8 +2944,9 @@ int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol,
3097 if (invert) 2944 if (invert)
3098 ucontrol->value.integer.value[1] = 2945 ucontrol->value.integer.value[1] =
3099 max - ucontrol->value.integer.value[1]; 2946 max - ucontrol->value.integer.value[1];
3100 ucontrol->value.integer.value[1] = 2947 else
3101 ucontrol->value.integer.value[1] - min; 2948 ucontrol->value.integer.value[1] =
2949 ucontrol->value.integer.value[1] - min;
3102 } 2950 }
3103 2951
3104 return 0; 2952 return 0;
@@ -3928,8 +3776,11 @@ EXPORT_SYMBOL_GPL(snd_soc_register_card);
3928 */ 3776 */
3929int snd_soc_unregister_card(struct snd_soc_card *card) 3777int snd_soc_unregister_card(struct snd_soc_card *card)
3930{ 3778{
3931 if (card->instantiated) 3779 if (card->instantiated) {
3780 card->instantiated = false;
3781 snd_soc_dapm_shutdown(card);
3932 soc_cleanup_card_resources(card); 3782 soc_cleanup_card_resources(card);
3783 }
3933 dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card->name); 3784 dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card->name);
3934 3785
3935 return 0; 3786 return 0;
@@ -4116,6 +3967,8 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
4116 3967
4117 component->dev = dev; 3968 component->dev = dev;
4118 component->driver = driver; 3969 component->driver = driver;
3970 component->probe = component->driver->probe;
3971 component->remove = component->driver->remove;
4119 3972
4120 if (!component->dapm_ptr) 3973 if (!component->dapm_ptr)
4121 component->dapm_ptr = &component->dapm; 3974 component->dapm_ptr = &component->dapm;
@@ -4124,19 +3977,42 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
4124 dapm->dev = dev; 3977 dapm->dev = dev;
4125 dapm->component = component; 3978 dapm->component = component;
4126 dapm->bias_level = SND_SOC_BIAS_OFF; 3979 dapm->bias_level = SND_SOC_BIAS_OFF;
3980 dapm->idle_bias_off = true;
4127 if (driver->seq_notifier) 3981 if (driver->seq_notifier)
4128 dapm->seq_notifier = snd_soc_component_seq_notifier; 3982 dapm->seq_notifier = snd_soc_component_seq_notifier;
4129 if (driver->stream_event) 3983 if (driver->stream_event)
4130 dapm->stream_event = snd_soc_component_stream_event; 3984 dapm->stream_event = snd_soc_component_stream_event;
4131 3985
3986 component->controls = driver->controls;
3987 component->num_controls = driver->num_controls;
3988 component->dapm_widgets = driver->dapm_widgets;
3989 component->num_dapm_widgets = driver->num_dapm_widgets;
3990 component->dapm_routes = driver->dapm_routes;
3991 component->num_dapm_routes = driver->num_dapm_routes;
3992
4132 INIT_LIST_HEAD(&component->dai_list); 3993 INIT_LIST_HEAD(&component->dai_list);
4133 mutex_init(&component->io_mutex); 3994 mutex_init(&component->io_mutex);
4134 3995
4135 return 0; 3996 return 0;
4136} 3997}
4137 3998
3999static void snd_soc_component_init_regmap(struct snd_soc_component *component)
4000{
4001 if (!component->regmap)
4002 component->regmap = dev_get_regmap(component->dev, NULL);
4003 if (component->regmap) {
4004 int val_bytes = regmap_get_val_bytes(component->regmap);
4005 /* Errors are legitimate for non-integer byte multiples */
4006 if (val_bytes > 0)
4007 component->val_bytes = val_bytes;
4008 }
4009}
4010
4138static void snd_soc_component_add_unlocked(struct snd_soc_component *component) 4011static void snd_soc_component_add_unlocked(struct snd_soc_component *component)
4139{ 4012{
4013 if (!component->write && !component->read)
4014 snd_soc_component_init_regmap(component);
4015
4140 list_add(&component->list, &component_list); 4016 list_add(&component->list, &component_list);
4141} 4017}
4142 4018
@@ -4225,22 +4101,18 @@ found:
4225} 4101}
4226EXPORT_SYMBOL_GPL(snd_soc_unregister_component); 4102EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
4227 4103
4228static int snd_soc_platform_drv_write(struct snd_soc_component *component, 4104static int snd_soc_platform_drv_probe(struct snd_soc_component *component)
4229 unsigned int reg, unsigned int val)
4230{ 4105{
4231 struct snd_soc_platform *platform = snd_soc_component_to_platform(component); 4106 struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
4232 4107
4233 return platform->driver->write(platform, reg, val); 4108 return platform->driver->probe(platform);
4234} 4109}
4235 4110
4236static int snd_soc_platform_drv_read(struct snd_soc_component *component, 4111static void snd_soc_platform_drv_remove(struct snd_soc_component *component)
4237 unsigned int reg, unsigned int *val)
4238{ 4112{
4239 struct snd_soc_platform *platform = snd_soc_component_to_platform(component); 4113 struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
4240 4114
4241 *val = platform->driver->read(platform, reg); 4115 platform->driver->remove(platform);
4242
4243 return 0;
4244} 4116}
4245 4117
4246/** 4118/**
@@ -4261,10 +4133,15 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
4261 4133
4262 platform->dev = dev; 4134 platform->dev = dev;
4263 platform->driver = platform_drv; 4135 platform->driver = platform_drv;
4264 if (platform_drv->write) 4136
4265 platform->component.write = snd_soc_platform_drv_write; 4137 if (platform_drv->probe)
4266 if (platform_drv->read) 4138 platform->component.probe = snd_soc_platform_drv_probe;
4267 platform->component.read = snd_soc_platform_drv_read; 4139 if (platform_drv->remove)
4140 platform->component.remove = snd_soc_platform_drv_remove;
4141
4142#ifdef CONFIG_DEBUG_FS
4143 platform->component.debugfs_prefix = "platform";
4144#endif
4268 4145
4269 mutex_lock(&client_mutex); 4146 mutex_lock(&client_mutex);
4270 snd_soc_component_add_unlocked(&platform->component); 4147 snd_soc_component_add_unlocked(&platform->component);
@@ -4315,10 +4192,10 @@ void snd_soc_remove_platform(struct snd_soc_platform *platform)
4315 snd_soc_component_del_unlocked(&platform->component); 4192 snd_soc_component_del_unlocked(&platform->component);
4316 mutex_unlock(&client_mutex); 4193 mutex_unlock(&client_mutex);
4317 4194
4318 snd_soc_component_cleanup(&platform->component);
4319
4320 dev_dbg(platform->dev, "ASoC: Unregistered platform '%s'\n", 4195 dev_dbg(platform->dev, "ASoC: Unregistered platform '%s'\n",
4321 platform->component.name); 4196 platform->component.name);
4197
4198 snd_soc_component_cleanup(&platform->component);
4322} 4199}
4323EXPORT_SYMBOL_GPL(snd_soc_remove_platform); 4200EXPORT_SYMBOL_GPL(snd_soc_remove_platform);
4324 4201
@@ -4386,6 +4263,20 @@ static void fixup_codec_formats(struct snd_soc_pcm_stream *stream)
4386 stream->formats |= codec_format_map[i]; 4263 stream->formats |= codec_format_map[i];
4387} 4264}
4388 4265
4266static int snd_soc_codec_drv_probe(struct snd_soc_component *component)
4267{
4268 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
4269
4270 return codec->driver->probe(codec);
4271}
4272
4273static void snd_soc_codec_drv_remove(struct snd_soc_component *component)
4274{
4275 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
4276
4277 codec->driver->remove(codec);
4278}
4279
4389static int snd_soc_codec_drv_write(struct snd_soc_component *component, 4280static int snd_soc_codec_drv_write(struct snd_soc_component *component,
4390 unsigned int reg, unsigned int val) 4281 unsigned int reg, unsigned int val)
4391{ 4282{
@@ -4424,7 +4315,6 @@ int snd_soc_register_codec(struct device *dev,
4424{ 4315{
4425 struct snd_soc_codec *codec; 4316 struct snd_soc_codec *codec;
4426 struct snd_soc_dai *dai; 4317 struct snd_soc_dai *dai;
4427 struct regmap *regmap;
4428 int ret, i; 4318 int ret, i;
4429 4319
4430 dev_dbg(dev, "codec register %s\n", dev_name(dev)); 4320 dev_dbg(dev, "codec register %s\n", dev_name(dev));
@@ -4434,18 +4324,37 @@ int snd_soc_register_codec(struct device *dev,
4434 return -ENOMEM; 4324 return -ENOMEM;
4435 4325
4436 codec->component.dapm_ptr = &codec->dapm; 4326 codec->component.dapm_ptr = &codec->dapm;
4327 codec->component.codec = codec;
4437 4328
4438 ret = snd_soc_component_initialize(&codec->component, 4329 ret = snd_soc_component_initialize(&codec->component,
4439 &codec_drv->component_driver, dev); 4330 &codec_drv->component_driver, dev);
4440 if (ret) 4331 if (ret)
4441 goto err_free; 4332 goto err_free;
4442 4333
4334 if (codec_drv->controls) {
4335 codec->component.controls = codec_drv->controls;
4336 codec->component.num_controls = codec_drv->num_controls;
4337 }
4338 if (codec_drv->dapm_widgets) {
4339 codec->component.dapm_widgets = codec_drv->dapm_widgets;
4340 codec->component.num_dapm_widgets = codec_drv->num_dapm_widgets;
4341 }
4342 if (codec_drv->dapm_routes) {
4343 codec->component.dapm_routes = codec_drv->dapm_routes;
4344 codec->component.num_dapm_routes = codec_drv->num_dapm_routes;
4345 }
4346
4347 if (codec_drv->probe)
4348 codec->component.probe = snd_soc_codec_drv_probe;
4349 if (codec_drv->remove)
4350 codec->component.remove = snd_soc_codec_drv_remove;
4443 if (codec_drv->write) 4351 if (codec_drv->write)
4444 codec->component.write = snd_soc_codec_drv_write; 4352 codec->component.write = snd_soc_codec_drv_write;
4445 if (codec_drv->read) 4353 if (codec_drv->read)
4446 codec->component.read = snd_soc_codec_drv_read; 4354 codec->component.read = snd_soc_codec_drv_read;
4447 codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time; 4355 codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time;
4448 codec->dapm.codec = codec; 4356 codec->dapm.idle_bias_off = codec_drv->idle_bias_off;
4357 codec->dapm.suspend_bias_off = codec_drv->suspend_bias_off;
4449 if (codec_drv->seq_notifier) 4358 if (codec_drv->seq_notifier)
4450 codec->dapm.seq_notifier = codec_drv->seq_notifier; 4359 codec->dapm.seq_notifier = codec_drv->seq_notifier;
4451 if (codec_drv->set_bias_level) 4360 if (codec_drv->set_bias_level)
@@ -4455,23 +4364,13 @@ int snd_soc_register_codec(struct device *dev,
4455 codec->component.val_bytes = codec_drv->reg_word_size; 4364 codec->component.val_bytes = codec_drv->reg_word_size;
4456 mutex_init(&codec->mutex); 4365 mutex_init(&codec->mutex);
4457 4366
4458 if (!codec->component.write) { 4367#ifdef CONFIG_DEBUG_FS
4459 if (codec_drv->get_regmap) 4368 codec->component.init_debugfs = soc_init_codec_debugfs;
4460 regmap = codec_drv->get_regmap(dev); 4369 codec->component.debugfs_prefix = "codec";
4461 else 4370#endif
4462 regmap = dev_get_regmap(dev, NULL); 4371
4463 4372 if (codec_drv->get_regmap)
4464 if (regmap) { 4373 codec->component.regmap = codec_drv->get_regmap(dev);
4465 ret = snd_soc_component_init_io(&codec->component,
4466 regmap);
4467 if (ret) {
4468 dev_err(codec->dev,
4469 "Failed to set cache I/O:%d\n",
4470 ret);
4471 goto err_cleanup;
4472 }
4473 }
4474 }
4475 4374
4476 for (i = 0; i < num_dai; i++) { 4375 for (i = 0; i < num_dai; i++) {
4477 fixup_codec_formats(&dai_drv[i].playback); 4376 fixup_codec_formats(&dai_drv[i].playback);