aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2014-09-06 09:44:11 -0400
committerMark Brown <broonie@linaro.org>2014-09-06 09:44:11 -0400
commit1ee0beb985e097aa07fa7feab4e11ecf251d763c (patch)
treeba8ec4cc49f932b4c95792dbcab5bfb553fc77b5
parent06cb1eb3de5c905da60ab91dbf99aaf96a43d043 (diff)
parentc815dbb47758bd469927849fdd45fed3ce206e73 (diff)
Merge branch 'topic/component' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-intel
-rw-r--r--include/sound/soc.h87
-rw-r--r--sound/soc/samsung/speyside.c6
-rw-r--r--sound/soc/soc-core.c669
-rw-r--r--sound/soc/soc-generic-dmaengine-pcm.c4
-rw-r--r--sound/soc/soc-io.c28
5 files changed, 373 insertions, 421 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index be6ecae247b0..f8b23dd7c3a7 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -690,6 +690,17 @@ struct snd_soc_compr_ops {
690struct snd_soc_component_driver { 690struct snd_soc_component_driver {
691 const char *name; 691 const char *name;
692 692
693 /* Default control and setup, added after probe() is run */
694 const struct snd_kcontrol_new *controls;
695 unsigned int num_controls;
696 const struct snd_soc_dapm_widget *dapm_widgets;
697 unsigned int num_dapm_widgets;
698 const struct snd_soc_dapm_route *dapm_routes;
699 unsigned int num_dapm_routes;
700
701 int (*probe)(struct snd_soc_component *);
702 void (*remove)(struct snd_soc_component *);
703
693 /* DT */ 704 /* DT */
694 int (*of_xlate_dai_name)(struct snd_soc_component *component, 705 int (*of_xlate_dai_name)(struct snd_soc_component *component,
695 struct of_phandle_args *args, 706 struct of_phandle_args *args,
@@ -697,6 +708,10 @@ struct snd_soc_component_driver {
697 void (*seq_notifier)(struct snd_soc_component *, enum snd_soc_dapm_type, 708 void (*seq_notifier)(struct snd_soc_component *, enum snd_soc_dapm_type,
698 int subseq); 709 int subseq);
699 int (*stream_event)(struct snd_soc_component *, int event); 710 int (*stream_event)(struct snd_soc_component *, int event);
711
712 /* probe ordering - for components with runtime dependencies */
713 int probe_order;
714 int remove_order;
700}; 715};
701 716
702struct snd_soc_component { 717struct snd_soc_component {
@@ -710,6 +725,7 @@ struct snd_soc_component {
710 725
711 unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */ 726 unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
712 unsigned int registered_as_component:1; 727 unsigned int registered_as_component:1;
728 unsigned int probed:1;
713 729
714 struct list_head list; 730 struct list_head list;
715 731
@@ -728,9 +744,36 @@ struct snd_soc_component {
728 744
729 struct mutex io_mutex; 745 struct mutex io_mutex;
730 746
747#ifdef CONFIG_DEBUG_FS
748 struct dentry *debugfs_root;
749#endif
750
751 /*
752 * DO NOT use any of the fields below in drivers, they are temporary and
753 * are going to be removed again soon. If you use them in driver code the
754 * driver will be marked as BROKEN when these fields are removed.
755 */
756
731 /* Don't use these, use snd_soc_component_get_dapm() */ 757 /* Don't use these, use snd_soc_component_get_dapm() */
732 struct snd_soc_dapm_context dapm; 758 struct snd_soc_dapm_context dapm;
733 struct snd_soc_dapm_context *dapm_ptr; 759 struct snd_soc_dapm_context *dapm_ptr;
760
761 const struct snd_kcontrol_new *controls;
762 unsigned int num_controls;
763 const struct snd_soc_dapm_widget *dapm_widgets;
764 unsigned int num_dapm_widgets;
765 const struct snd_soc_dapm_route *dapm_routes;
766 unsigned int num_dapm_routes;
767 bool steal_sibling_dai_widgets;
768 struct snd_soc_codec *codec;
769
770 int (*probe)(struct snd_soc_component *);
771 void (*remove)(struct snd_soc_component *);
772
773#ifdef CONFIG_DEBUG_FS
774 void (*init_debugfs)(struct snd_soc_component *component);
775 const char *debugfs_prefix;
776#endif
734}; 777};
735 778
736/* SoC Audio Codec device */ 779/* SoC Audio Codec device */
@@ -746,11 +789,9 @@ struct snd_soc_codec {
746 struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ 789 struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */
747 unsigned int cache_bypass:1; /* Suppress access to the cache */ 790 unsigned int cache_bypass:1; /* Suppress access to the cache */
748 unsigned int suspended:1; /* Codec is in suspend PM state */ 791 unsigned int suspended:1; /* Codec is in suspend PM state */
749 unsigned int probed:1; /* Codec has been probed */
750 unsigned int ac97_registered:1; /* Codec has been AC97 registered */ 792 unsigned int ac97_registered:1; /* Codec has been AC97 registered */
751 unsigned int ac97_created:1; /* Codec has been created by SoC */ 793 unsigned int ac97_created:1; /* Codec has been created by SoC */
752 unsigned int cache_init:1; /* codec cache has been initialized */ 794 unsigned int cache_init:1; /* codec cache has been initialized */
753 u32 cache_only; /* Suppress writes to hardware */
754 u32 cache_sync; /* Cache needs to be synced to hardware */ 795 u32 cache_sync; /* Cache needs to be synced to hardware */
755 796
756 /* codec IO */ 797 /* codec IO */
@@ -766,7 +807,6 @@ struct snd_soc_codec {
766 struct snd_soc_dapm_context dapm; 807 struct snd_soc_dapm_context dapm;
767 808
768#ifdef CONFIG_DEBUG_FS 809#ifdef CONFIG_DEBUG_FS
769 struct dentry *debugfs_codec_root;
770 struct dentry *debugfs_reg; 810 struct dentry *debugfs_reg;
771#endif 811#endif
772}; 812};
@@ -813,10 +853,6 @@ struct snd_soc_codec_driver {
813 enum snd_soc_dapm_type, int); 853 enum snd_soc_dapm_type, int);
814 854
815 bool ignore_pmdown_time; /* Doesn't benefit from pmdown delay */ 855 bool ignore_pmdown_time; /* Doesn't benefit from pmdown delay */
816
817 /* probe ordering - for components with runtime dependencies */
818 int probe_order;
819 int remove_order;
820}; 856};
821 857
822/* SoC platform interface */ 858/* SoC platform interface */
@@ -853,13 +889,6 @@ struct snd_soc_platform_driver {
853 /* platform stream compress ops */ 889 /* platform stream compress ops */
854 const struct snd_compr_ops *compr_ops; 890 const struct snd_compr_ops *compr_ops;
855 891
856 /* probe ordering - for components with runtime dependencies */
857 int probe_order;
858 int remove_order;
859
860 /* platform IO - used for platform DAPM */
861 unsigned int (*read)(struct snd_soc_platform *, unsigned int);
862 int (*write)(struct snd_soc_platform *, unsigned int, unsigned int);
863 int (*bespoke_trigger)(struct snd_pcm_substream *, int); 892 int (*bespoke_trigger)(struct snd_pcm_substream *, int);
864}; 893};
865 894
@@ -874,15 +903,10 @@ struct snd_soc_platform {
874 const struct snd_soc_platform_driver *driver; 903 const struct snd_soc_platform_driver *driver;
875 904
876 unsigned int suspended:1; /* platform is suspended */ 905 unsigned int suspended:1; /* platform is suspended */
877 unsigned int probed:1;
878 906
879 struct list_head list; 907 struct list_head list;
880 908
881 struct snd_soc_component component; 909 struct snd_soc_component component;
882
883#ifdef CONFIG_DEBUG_FS
884 struct dentry *debugfs_platform_root;
885#endif
886}; 910};
887 911
888struct snd_soc_dai_link { 912struct snd_soc_dai_link {
@@ -994,7 +1018,7 @@ struct snd_soc_aux_dev {
994 const struct device_node *codec_of_node; 1018 const struct device_node *codec_of_node;
995 1019
996 /* codec/machine specific init - e.g. add machine controls */ 1020 /* codec/machine specific init - e.g. add machine controls */
997 int (*init)(struct snd_soc_dapm_context *dapm); 1021 int (*init)(struct snd_soc_component *component);
998}; 1022};
999 1023
1000/* SoC card */ 1024/* SoC card */
@@ -1112,6 +1136,7 @@ struct snd_soc_pcm_runtime {
1112 struct snd_soc_platform *platform; 1136 struct snd_soc_platform *platform;
1113 struct snd_soc_dai *codec_dai; 1137 struct snd_soc_dai *codec_dai;
1114 struct snd_soc_dai *cpu_dai; 1138 struct snd_soc_dai *cpu_dai;
1139 struct snd_soc_component *component; /* Only valid for AUX dev rtds */
1115 1140
1116 struct snd_soc_dai **codec_dais; 1141 struct snd_soc_dai **codec_dais;
1117 unsigned int num_codecs; 1142 unsigned int num_codecs;
@@ -1260,9 +1285,6 @@ void snd_soc_component_async_complete(struct snd_soc_component *component);
1260int snd_soc_component_test_bits(struct snd_soc_component *component, 1285int snd_soc_component_test_bits(struct snd_soc_component *component,
1261 unsigned int reg, unsigned int mask, unsigned int value); 1286 unsigned int reg, unsigned int mask, unsigned int value);
1262 1287
1263int snd_soc_component_init_io(struct snd_soc_component *component,
1264 struct regmap *regmap);
1265
1266/* device driver data */ 1288/* device driver data */
1267 1289
1268static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card, 1290static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card,
@@ -1276,26 +1298,37 @@ static inline void *snd_soc_card_get_drvdata(struct snd_soc_card *card)
1276 return card->drvdata; 1298 return card->drvdata;
1277} 1299}
1278 1300
1301static inline void snd_soc_component_set_drvdata(struct snd_soc_component *c,
1302 void *data)
1303{
1304 dev_set_drvdata(c->dev, data);
1305}
1306
1307static inline void *snd_soc_component_get_drvdata(struct snd_soc_component *c)
1308{
1309 return dev_get_drvdata(c->dev);
1310}
1311
1279static inline void snd_soc_codec_set_drvdata(struct snd_soc_codec *codec, 1312static inline void snd_soc_codec_set_drvdata(struct snd_soc_codec *codec,
1280 void *data) 1313 void *data)
1281{ 1314{
1282 dev_set_drvdata(codec->dev, data); 1315 snd_soc_component_set_drvdata(&codec->component, data);
1283} 1316}
1284 1317
1285static inline void *snd_soc_codec_get_drvdata(struct snd_soc_codec *codec) 1318static inline void *snd_soc_codec_get_drvdata(struct snd_soc_codec *codec)
1286{ 1319{
1287 return dev_get_drvdata(codec->dev); 1320 return snd_soc_component_get_drvdata(&codec->component);
1288} 1321}
1289 1322
1290static inline void snd_soc_platform_set_drvdata(struct snd_soc_platform *platform, 1323static inline void snd_soc_platform_set_drvdata(struct snd_soc_platform *platform,
1291 void *data) 1324 void *data)
1292{ 1325{
1293 dev_set_drvdata(platform->dev, data); 1326 snd_soc_component_set_drvdata(&platform->component, data);
1294} 1327}
1295 1328
1296static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platform) 1329static inline void *snd_soc_platform_get_drvdata(struct snd_soc_platform *platform)
1297{ 1330{
1298 return dev_get_drvdata(platform->dev); 1331 return snd_soc_component_get_drvdata(&platform->component);
1299} 1332}
1300 1333
1301static inline void snd_soc_pcm_set_drvdata(struct snd_soc_pcm_runtime *rtd, 1334static inline void snd_soc_pcm_set_drvdata(struct snd_soc_pcm_runtime *rtd,
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c
index 9902efcb8ea1..a05482651aae 100644
--- a/sound/soc/samsung/speyside.c
+++ b/sound/soc/samsung/speyside.c
@@ -228,10 +228,12 @@ static struct snd_soc_dai_link speyside_dai[] = {
228 }, 228 },
229}; 229};
230 230
231static int speyside_wm9081_init(struct snd_soc_dapm_context *dapm) 231static int speyside_wm9081_init(struct snd_soc_component *component)
232{ 232{
233 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
234
233 /* At any time the WM9081 is active it will have this clock */ 235 /* At any time the WM9081 is active it will have this clock */
234 return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 0, 236 return snd_soc_codec_set_sysclk(codec, WM9081_SYSCLK_MCLK, 0,
235 MCLK_AUDIO_RATE, 0); 237 MCLK_AUDIO_RATE, 0);
236} 238}
237 239
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d4bfd4a9076f..1b422c5c36c8 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
@@ -835,10 +804,8 @@ int snd_soc_resume(struct device *dev)
835 struct snd_soc_card *card = dev_get_drvdata(dev); 804 struct snd_soc_card *card = dev_get_drvdata(dev);
836 int i, ac97_control = 0; 805 int i, ac97_control = 0;
837 806
838 /* If the initialization of this soc device failed, there is no codec 807 /* If the card is not initialized yet there is nothing to do */
839 * associated with it. Just bail out in this case. 808 if (!card->instantiated)
840 */
841 if (list_empty(&card->codec_dev_list))
842 return 0; 809 return 0;
843 810
844 /* activate pins from sleep state */ 811 /* activate pins from sleep state */
@@ -887,35 +854,40 @@ EXPORT_SYMBOL_GPL(snd_soc_resume);
887static const struct snd_soc_dai_ops null_dai_ops = { 854static const struct snd_soc_dai_ops null_dai_ops = {
888}; 855};
889 856
890static struct snd_soc_codec *soc_find_codec( 857static struct snd_soc_component *soc_find_component(
891 const struct device_node *codec_of_node, 858 const struct device_node *of_node, const char *name)
892 const char *codec_name)
893{ 859{
894 struct snd_soc_codec *codec; 860 struct snd_soc_component *component;
895 861
896 list_for_each_entry(codec, &codec_list, list) { 862 list_for_each_entry(component, &component_list, list) {
897 if (codec_of_node) { 863 if (of_node) {
898 if (codec->dev->of_node != codec_of_node) 864 if (component->dev->of_node == of_node)
899 continue; 865 return component;
900 } else { 866 } else if (strcmp(component->name, name) == 0) {
901 if (strcmp(codec->component.name, codec_name)) 867 return component;
902 continue;
903 } 868 }
904
905 return codec;
906 } 869 }
907 870
908 return NULL; 871 return NULL;
909} 872}
910 873
911static struct snd_soc_dai *soc_find_codec_dai(struct snd_soc_codec *codec, 874static struct snd_soc_dai *snd_soc_find_dai(
912 const char *codec_dai_name) 875 const struct snd_soc_dai_link_component *dlc)
913{ 876{
914 struct snd_soc_dai *codec_dai; 877 struct snd_soc_component *component;
878 struct snd_soc_dai *dai;
915 879
916 list_for_each_entry(codec_dai, &codec->component.dai_list, list) { 880 /* Find CPU DAI from registered DAIs*/
917 if (!strcmp(codec_dai->name, codec_dai_name)) { 881 list_for_each_entry(component, &component_list, list) {
918 return codec_dai; 882 if (dlc->of_node && component->dev->of_node != dlc->of_node)
883 continue;
884 if (dlc->name && strcmp(dev_name(component->dev), dlc->name))
885 continue;
886 list_for_each_entry(dai, &component->dai_list, list) {
887 if (dlc->dai_name && strcmp(dai->name, dlc->dai_name))
888 continue;
889
890 return dai;
919 } 891 }
920 } 892 }
921 893
@@ -926,33 +898,19 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
926{ 898{
927 struct snd_soc_dai_link *dai_link = &card->dai_link[num]; 899 struct snd_soc_dai_link *dai_link = &card->dai_link[num];
928 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 900 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; 901 struct snd_soc_dai_link_component *codecs = dai_link->codecs;
902 struct snd_soc_dai_link_component cpu_dai_component;
931 struct snd_soc_dai **codec_dais = rtd->codec_dais; 903 struct snd_soc_dai **codec_dais = rtd->codec_dais;
932 struct snd_soc_platform *platform; 904 struct snd_soc_platform *platform;
933 struct snd_soc_dai *cpu_dai;
934 const char *platform_name; 905 const char *platform_name;
935 int i; 906 int i;
936 907
937 dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num); 908 dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num);
938 909
939 /* Find CPU DAI from registered DAIs*/ 910 cpu_dai_component.name = dai_link->cpu_name;
940 list_for_each_entry(component, &component_list, list) { 911 cpu_dai_component.of_node = dai_link->cpu_of_node;
941 if (dai_link->cpu_of_node && 912 cpu_dai_component.dai_name = dai_link->cpu_dai_name;
942 component->dev->of_node != dai_link->cpu_of_node) 913 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) { 914 if (!rtd->cpu_dai) {
957 dev_err(card->dev, "ASoC: CPU DAI %s not registered\n", 915 dev_err(card->dev, "ASoC: CPU DAI %s not registered\n",
958 dai_link->cpu_dai_name); 916 dai_link->cpu_dai_name);
@@ -963,15 +921,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
963 921
964 /* Find CODEC from registered CODECs */ 922 /* Find CODEC from registered CODECs */
965 for (i = 0; i < rtd->num_codecs; i++) { 923 for (i = 0; i < rtd->num_codecs; i++) {
966 struct snd_soc_codec *codec; 924 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]) { 925 if (!codec_dais[i]) {
976 dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n", 926 dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n",
977 codecs[i].dai_name); 927 codecs[i].dai_name);
@@ -1012,68 +962,46 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
1012 return 0; 962 return 0;
1013} 963}
1014 964
1015static int soc_remove_platform(struct snd_soc_platform *platform) 965static void soc_remove_component(struct snd_soc_component *component)
1016{ 966{
1017 int ret; 967 if (!component->probed)
1018 968 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 969
1036static void soc_remove_codec(struct snd_soc_codec *codec) 970 /* This is a HACK and will be removed soon */
1037{ 971 if (component->codec)
1038 int err; 972 list_del(&component->codec->card_list);
1039 973
1040 if (codec->driver->remove) { 974 if (component->remove)
1041 err = codec->driver->remove(codec); 975 component->remove(component);
1042 if (err < 0)
1043 dev_err(codec->dev, "ASoC: failed to remove %d\n", err);
1044 }
1045 976
1046 /* Make sure all DAPM widgets are freed */ 977 snd_soc_dapm_free(snd_soc_component_get_dapm(component));
1047 snd_soc_dapm_free(&codec->dapm);
1048 978
1049 soc_cleanup_codec_debugfs(codec); 979 soc_cleanup_component_debugfs(component);
1050 codec->probed = 0; 980 component->probed = 0;
1051 list_del(&codec->card_list); 981 module_put(component->dev->driver->owner);
1052 module_put(codec->dev->driver->owner);
1053} 982}
1054 983
1055static void soc_remove_codec_dai(struct snd_soc_dai *codec_dai, int order) 984static void soc_remove_dai(struct snd_soc_dai *dai, int order)
1056{ 985{
1057 int err; 986 int err;
1058 987
1059 if (codec_dai && codec_dai->probed && 988 if (dai && dai->probed &&
1060 codec_dai->driver->remove_order == order) { 989 dai->driver->remove_order == order) {
1061 if (codec_dai->driver->remove) { 990 if (dai->driver->remove) {
1062 err = codec_dai->driver->remove(codec_dai); 991 err = dai->driver->remove(dai);
1063 if (err < 0) 992 if (err < 0)
1064 dev_err(codec_dai->dev, 993 dev_err(dai->dev,
1065 "ASoC: failed to remove %s: %d\n", 994 "ASoC: failed to remove %s: %d\n",
1066 codec_dai->name, err); 995 dai->name, err);
1067 } 996 }
1068 codec_dai->probed = 0; 997 dai->probed = 0;
1069 } 998 }
1070} 999}
1071 1000
1072static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) 1001static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order)
1073{ 1002{
1074 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 1003 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1075 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1004 int i;
1076 int i, err;
1077 1005
1078 /* unregister the rtd device */ 1006 /* unregister the rtd device */
1079 if (rtd->dev_registered) { 1007 if (rtd->dev_registered) {
@@ -1085,22 +1013,9 @@ static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order)
1085 1013
1086 /* remove the CODEC DAI */ 1014 /* remove the CODEC DAI */
1087 for (i = 0; i < rtd->num_codecs; i++) 1015 for (i = 0; i < rtd->num_codecs; i++)
1088 soc_remove_codec_dai(rtd->codec_dais[i], order); 1016 soc_remove_dai(rtd->codec_dais[i], order);
1089 1017
1090 /* remove the cpu_dai */ 1018 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} 1019}
1105 1020
1106static void soc_remove_link_components(struct snd_soc_card *card, int num, 1021static void soc_remove_link_components(struct snd_soc_card *card, int num,
@@ -1109,29 +1024,24 @@ static void soc_remove_link_components(struct snd_soc_card *card, int num,
1109 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 1024 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1110 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 1025 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1111 struct snd_soc_platform *platform = rtd->platform; 1026 struct snd_soc_platform *platform = rtd->platform;
1112 struct snd_soc_codec *codec; 1027 struct snd_soc_component *component;
1113 int i; 1028 int i;
1114 1029
1115 /* remove the platform */ 1030 /* remove the platform */
1116 if (platform && platform->probed && 1031 if (platform && platform->component.driver->remove_order == order)
1117 platform->driver->remove_order == order) { 1032 soc_remove_component(&platform->component);
1118 soc_remove_platform(platform);
1119 }
1120 1033
1121 /* remove the CODEC-side CODEC */ 1034 /* remove the CODEC-side CODEC */
1122 for (i = 0; i < rtd->num_codecs; i++) { 1035 for (i = 0; i < rtd->num_codecs; i++) {
1123 codec = rtd->codec_dais[i]->codec; 1036 component = rtd->codec_dais[i]->component;
1124 if (codec && codec->probed && 1037 if (component->driver->remove_order == order)
1125 codec->driver->remove_order == order) 1038 soc_remove_component(component);
1126 soc_remove_codec(codec);
1127 } 1039 }
1128 1040
1129 /* remove any CPU-side CODEC */ 1041 /* remove any CPU-side CODEC */
1130 if (cpu_dai) { 1042 if (cpu_dai) {
1131 codec = cpu_dai->codec; 1043 if (cpu_dai->component->driver->remove_order == order)
1132 if (codec && codec->probed && 1044 soc_remove_component(cpu_dai->component);
1133 codec->driver->remove_order == order)
1134 soc_remove_codec(codec);
1135 } 1045 }
1136} 1046}
1137 1047
@@ -1173,137 +1083,111 @@ static void soc_set_name_prefix(struct snd_soc_card *card,
1173 } 1083 }
1174} 1084}
1175 1085
1176static int soc_probe_codec(struct snd_soc_card *card, 1086static int soc_probe_component(struct snd_soc_card *card,
1177 struct snd_soc_codec *codec) 1087 struct snd_soc_component *component)
1178{ 1088{
1179 int ret = 0; 1089 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
1180 const struct snd_soc_codec_driver *driver = codec->driver; 1090 struct snd_soc_component *dai_component, *component2;
1181 struct snd_soc_dai *dai; 1091 struct snd_soc_dai *dai;
1092 int ret;
1093
1094 if (component->probed)
1095 return 0;
1182 1096
1183 codec->component.card = card; 1097 component->card = card;
1184 codec->dapm.card = card; 1098 dapm->card = card;
1185 soc_set_name_prefix(card, &codec->component); 1099 soc_set_name_prefix(card, component);
1186 1100
1187 if (!try_module_get(codec->dev->driver->owner)) 1101 if (!try_module_get(component->dev->driver->owner))
1188 return -ENODEV; 1102 return -ENODEV;
1189 1103
1190 soc_init_codec_debugfs(codec); 1104 soc_init_component_debugfs(component);
1191 1105
1192 if (driver->dapm_widgets) { 1106 if (component->dapm_widgets) {
1193 ret = snd_soc_dapm_new_controls(&codec->dapm, 1107 ret = snd_soc_dapm_new_controls(dapm, component->dapm_widgets,
1194 driver->dapm_widgets, 1108 component->num_dapm_widgets);
1195 driver->num_dapm_widgets);
1196 1109
1197 if (ret != 0) { 1110 if (ret != 0) {
1198 dev_err(codec->dev, 1111 dev_err(component->dev,
1199 "Failed to create new controls %d\n", ret); 1112 "Failed to create new controls %d\n", ret);
1200 goto err_probe; 1113 goto err_probe;
1201 } 1114 }
1202 } 1115 }
1203 1116
1204 /* Create DAPM widgets for each DAI stream */ 1117 /*
1205 list_for_each_entry(dai, &codec->component.dai_list, list) { 1118 * This is rather ugly, but certain platforms expect that the DAPM
1206 ret = snd_soc_dapm_new_dai_widgets(&codec->dapm, dai); 1119 * widgets for the DAIs for components with the same parent device are
1120 * created in the platforms DAPM context. Until that is fixed we need to
1121 * keep this.
1122 */
1123 if (component->steal_sibling_dai_widgets) {
1124 dai_component = NULL;
1125 list_for_each_entry(component2, &component_list, list) {
1126 if (component == component2)
1127 continue;
1207 1128
1208 if (ret != 0) { 1129 if (component2->dev == component->dev &&
1209 dev_err(codec->dev, 1130 !list_empty(&component2->dai_list)) {
1210 "Failed to create DAI widgets %d\n", ret); 1131 dai_component = component2;
1211 goto err_probe; 1132 break;
1133 }
1212 } 1134 }
1213 } 1135 } else {
1214 1136 dai_component = component;
1215 codec->dapm.idle_bias_off = driver->idle_bias_off; 1137 list_for_each_entry(component2, &component_list, list) {
1216 1138 if (component2->dev == component->dev &&
1217 if (driver->probe) { 1139 component2->steal_sibling_dai_widgets) {
1218 ret = driver->probe(codec); 1140 dai_component = NULL;
1219 if (ret < 0) { 1141 break;
1220 dev_err(codec->dev, 1142 }
1221 "ASoC: failed to probe CODEC %d\n", ret);
1222 goto err_probe;
1223 } 1143 }
1224 WARN(codec->dapm.idle_bias_off &&
1225 codec->dapm.bias_level != SND_SOC_BIAS_OFF,
1226 "codec %s can not start from non-off bias with idle_bias_off==1\n",
1227 codec->component.name);
1228 } 1144 }
1229 1145
1230 if (driver->controls) 1146 if (dai_component) {
1231 snd_soc_add_codec_controls(codec, driver->controls, 1147 list_for_each_entry(dai, &dai_component->dai_list, list) {
1232 driver->num_controls); 1148 snd_soc_dapm_new_dai_widgets(dapm, dai);
1233 if (driver->dapm_routes) 1149 if (ret != 0) {
1234 snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes, 1150 dev_err(component->dev,
1235 driver->num_dapm_routes); 1151 "Failed to create DAI widgets %d\n",
1236 1152 ret);
1237 /* mark codec as probed and add to card codec list */ 1153 goto err_probe;
1238 codec->probed = 1; 1154 }
1239 list_add(&codec->card_list, &card->codec_dev_list); 1155 }
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
1262 if (!try_module_get(platform->dev->driver->owner))
1263 return -ENODEV;
1264
1265 soc_init_platform_debugfs(platform);
1266
1267 if (driver->dapm_widgets)
1268 snd_soc_dapm_new_controls(&platform->component.dapm,
1269 driver->dapm_widgets, driver->num_dapm_widgets);
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 } 1156 }
1279 1157
1280 platform->component.dapm.idle_bias_off = 1; 1158 if (component->probe) {
1281 1159 ret = component->probe(component);
1282 if (driver->probe) {
1283 ret = driver->probe(platform);
1284 if (ret < 0) { 1160 if (ret < 0) {
1285 dev_err(platform->dev, 1161 dev_err(component->dev,
1286 "ASoC: failed to probe platform %d\n", ret); 1162 "ASoC: failed to probe component %d\n", ret);
1287 goto err_probe; 1163 goto err_probe;
1288 } 1164 }
1165
1166 WARN(dapm->idle_bias_off &&
1167 dapm->bias_level != SND_SOC_BIAS_OFF,
1168 "codec %s can not start from non-off bias with idle_bias_off==1\n",
1169 component->name);
1289 } 1170 }
1290 1171
1291 if (driver->controls) 1172 if (component->controls)
1292 snd_soc_add_platform_controls(platform, driver->controls, 1173 snd_soc_add_component_controls(component, component->controls,
1293 driver->num_controls); 1174 component->num_controls);
1294 if (driver->dapm_routes) 1175 if (component->dapm_routes)
1295 snd_soc_dapm_add_routes(&platform->component.dapm, 1176 snd_soc_dapm_add_routes(dapm, component->dapm_routes,
1296 driver->dapm_routes, driver->num_dapm_routes); 1177 component->num_dapm_routes);
1297 1178
1298 /* mark platform as probed and add to card platform list */ 1179 component->probed = 1;
1299 platform->probed = 1; 1180 list_add(&dapm->list, &card->dapm_list);
1300 list_add(&platform->component.dapm.list, &card->dapm_list); 1181
1182 /* This is a HACK and will be removed soon */
1183 if (component->codec)
1184 list_add(&component->codec->card_list, &card->codec_dev_list);
1301 1185
1302 return 0; 1186 return 0;
1303 1187
1304err_probe: 1188err_probe:
1305 soc_cleanup_platform_debugfs(platform); 1189 soc_cleanup_component_debugfs(component);
1306 module_put(platform->dev->driver->owner); 1190 module_put(component->dev->driver->owner);
1307 1191
1308 return ret; 1192 return ret;
1309} 1193}
@@ -1342,17 +1226,21 @@ static int soc_post_component_init(struct snd_soc_pcm_runtime *rtd,
1342 } 1226 }
1343 rtd->dev_registered = 1; 1227 rtd->dev_registered = 1;
1344 1228
1345 /* add DAPM sysfs entries for this codec */ 1229 if (rtd->codec) {
1346 ret = snd_soc_dapm_sys_add(rtd->dev); 1230 /* add DAPM sysfs entries for this codec */
1347 if (ret < 0) 1231 ret = snd_soc_dapm_sys_add(rtd->dev);
1348 dev_err(rtd->dev, 1232 if (ret < 0)
1349 "ASoC: failed to add codec dapm sysfs entries: %d\n", ret); 1233 dev_err(rtd->dev,
1234 "ASoC: failed to add codec dapm sysfs entries: %d\n",
1235 ret);
1350 1236
1351 /* add codec sysfs entries */ 1237 /* add codec sysfs entries */
1352 ret = device_create_file(rtd->dev, &dev_attr_codec_reg); 1238 ret = device_create_file(rtd->dev, &dev_attr_codec_reg);
1353 if (ret < 0) 1239 if (ret < 0)
1354 dev_err(rtd->dev, 1240 dev_err(rtd->dev,
1355 "ASoC: failed to add codec sysfs files: %d\n", ret); 1241 "ASoC: failed to add codec sysfs files: %d\n",
1242 ret);
1243 }
1356 1244
1357 return 0; 1245 return 0;
1358} 1246}
@@ -1361,33 +1249,31 @@ static int soc_probe_link_components(struct snd_soc_card *card, int num,
1361 int order) 1249 int order)
1362{ 1250{
1363 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 1251 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; 1252 struct snd_soc_platform *platform = rtd->platform;
1253 struct snd_soc_component *component;
1366 int i, ret; 1254 int i, ret;
1367 1255
1368 /* probe the CPU-side component, if it is a CODEC */ 1256 /* probe the CPU-side component, if it is a CODEC */
1369 if (cpu_dai->codec && 1257 component = rtd->cpu_dai->component;
1370 !cpu_dai->codec->probed && 1258 if (component->driver->probe_order == order) {
1371 cpu_dai->codec->driver->probe_order == order) { 1259 ret = soc_probe_component(card, component);
1372 ret = soc_probe_codec(card, cpu_dai->codec);
1373 if (ret < 0) 1260 if (ret < 0)
1374 return ret; 1261 return ret;
1375 } 1262 }
1376 1263
1377 /* probe the CODEC-side components */ 1264 /* probe the CODEC-side components */
1378 for (i = 0; i < rtd->num_codecs; i++) { 1265 for (i = 0; i < rtd->num_codecs; i++) {
1379 if (!rtd->codec_dais[i]->codec->probed && 1266 component = rtd->codec_dais[i]->component;
1380 rtd->codec_dais[i]->codec->driver->probe_order == order) { 1267 if (component->driver->probe_order == order) {
1381 ret = soc_probe_codec(card, rtd->codec_dais[i]->codec); 1268 ret = soc_probe_component(card, component);
1382 if (ret < 0) 1269 if (ret < 0)
1383 return ret; 1270 return ret;
1384 } 1271 }
1385 } 1272 }
1386 1273
1387 /* probe the platform */ 1274 /* probe the platform */
1388 if (!platform->probed && 1275 if (platform->component.driver->probe_order == order) {
1389 platform->driver->probe_order == order) { 1276 ret = soc_probe_component(card, &platform->component);
1390 ret = soc_probe_platform(card, platform);
1391 if (ret < 0) 1277 if (ret < 0)
1392 return ret; 1278 return ret;
1393 } 1279 }
@@ -1482,18 +1368,12 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
1482 /* probe the cpu_dai */ 1368 /* probe the cpu_dai */
1483 if (!cpu_dai->probed && 1369 if (!cpu_dai->probed &&
1484 cpu_dai->driver->probe_order == order) { 1370 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) { 1371 if (cpu_dai->driver->probe) {
1491 ret = cpu_dai->driver->probe(cpu_dai); 1372 ret = cpu_dai->driver->probe(cpu_dai);
1492 if (ret < 0) { 1373 if (ret < 0) {
1493 dev_err(cpu_dai->dev, 1374 dev_err(cpu_dai->dev,
1494 "ASoC: failed to probe CPU DAI %s: %d\n", 1375 "ASoC: failed to probe CPU DAI %s: %d\n",
1495 cpu_dai->name, ret); 1376 cpu_dai->name, ret);
1496 module_put(cpu_dai->dev->driver->owner);
1497 return ret; 1377 return ret;
1498 } 1378 }
1499 } 1379 }
@@ -1654,17 +1534,24 @@ static int soc_bind_aux_dev(struct snd_soc_card *card, int num)
1654{ 1534{
1655 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; 1535 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
1656 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; 1536 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1657 const char *codecname = aux_dev->codec_name; 1537 const char *name = aux_dev->codec_name;
1658 1538
1659 rtd->codec = soc_find_codec(aux_dev->codec_of_node, codecname); 1539 rtd->component = soc_find_component(aux_dev->codec_of_node, name);
1660 if (!rtd->codec) { 1540 if (!rtd->component) {
1661 if (aux_dev->codec_of_node) 1541 if (aux_dev->codec_of_node)
1662 codecname = of_node_full_name(aux_dev->codec_of_node); 1542 name = of_node_full_name(aux_dev->codec_of_node);
1663 1543
1664 dev_err(card->dev, "ASoC: %s not registered\n", codecname); 1544 dev_err(card->dev, "ASoC: %s not registered\n", name);
1665 return -EPROBE_DEFER; 1545 return -EPROBE_DEFER;
1666 } 1546 }
1667 1547
1548 /*
1549 * Some places still reference rtd->codec, so we have to keep that
1550 * initialized if the component is a CODEC. Once all those references
1551 * have been removed, this code can be removed as well.
1552 */
1553 rtd->codec = rtd->component->codec;
1554
1668 return 0; 1555 return 0;
1669} 1556}
1670 1557
@@ -1674,18 +1561,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]; 1561 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1675 int ret; 1562 int ret;
1676 1563
1677 if (rtd->codec->probed) { 1564 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) 1565 if (ret < 0)
1684 return ret; 1566 return ret;
1685 1567
1686 /* do machine specific initialization */ 1568 /* do machine specific initialization */
1687 if (aux_dev->init) { 1569 if (aux_dev->init) {
1688 ret = aux_dev->init(&rtd->codec->dapm); 1570 ret = aux_dev->init(rtd->component);
1689 if (ret < 0) { 1571 if (ret < 0) {
1690 dev_err(card->dev, "ASoC: failed to init %s: %d\n", 1572 dev_err(card->dev, "ASoC: failed to init %s: %d\n",
1691 aux_dev->name, ret); 1573 aux_dev->name, ret);
@@ -1699,7 +1581,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) 1581static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
1700{ 1582{
1701 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; 1583 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
1702 struct snd_soc_codec *codec = rtd->codec; 1584 struct snd_soc_component *component = rtd->component;
1703 1585
1704 /* unregister the rtd device */ 1586 /* unregister the rtd device */
1705 if (rtd->dev_registered) { 1587 if (rtd->dev_registered) {
@@ -1708,8 +1590,8 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
1708 rtd->dev_registered = 0; 1590 rtd->dev_registered = 0;
1709 } 1591 }
1710 1592
1711 if (codec && codec->probed) 1593 if (component && component->probed)
1712 soc_remove_codec(codec); 1594 soc_remove_component(component);
1713} 1595}
1714 1596
1715static int snd_soc_init_codec_cache(struct snd_soc_codec *codec) 1597static int snd_soc_init_codec_cache(struct snd_soc_codec *codec)
@@ -4116,6 +3998,8 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
4116 3998
4117 component->dev = dev; 3999 component->dev = dev;
4118 component->driver = driver; 4000 component->driver = driver;
4001 component->probe = component->driver->probe;
4002 component->remove = component->driver->remove;
4119 4003
4120 if (!component->dapm_ptr) 4004 if (!component->dapm_ptr)
4121 component->dapm_ptr = &component->dapm; 4005 component->dapm_ptr = &component->dapm;
@@ -4124,19 +4008,42 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
4124 dapm->dev = dev; 4008 dapm->dev = dev;
4125 dapm->component = component; 4009 dapm->component = component;
4126 dapm->bias_level = SND_SOC_BIAS_OFF; 4010 dapm->bias_level = SND_SOC_BIAS_OFF;
4011 dapm->idle_bias_off = true;
4127 if (driver->seq_notifier) 4012 if (driver->seq_notifier)
4128 dapm->seq_notifier = snd_soc_component_seq_notifier; 4013 dapm->seq_notifier = snd_soc_component_seq_notifier;
4129 if (driver->stream_event) 4014 if (driver->stream_event)
4130 dapm->stream_event = snd_soc_component_stream_event; 4015 dapm->stream_event = snd_soc_component_stream_event;
4131 4016
4017 component->controls = driver->controls;
4018 component->num_controls = driver->num_controls;
4019 component->dapm_widgets = driver->dapm_widgets;
4020 component->num_dapm_widgets = driver->num_dapm_widgets;
4021 component->dapm_routes = driver->dapm_routes;
4022 component->num_dapm_routes = driver->num_dapm_routes;
4023
4132 INIT_LIST_HEAD(&component->dai_list); 4024 INIT_LIST_HEAD(&component->dai_list);
4133 mutex_init(&component->io_mutex); 4025 mutex_init(&component->io_mutex);
4134 4026
4135 return 0; 4027 return 0;
4136} 4028}
4137 4029
4030static void snd_soc_component_init_regmap(struct snd_soc_component *component)
4031{
4032 if (!component->regmap)
4033 component->regmap = dev_get_regmap(component->dev, NULL);
4034 if (component->regmap) {
4035 int val_bytes = regmap_get_val_bytes(component->regmap);
4036 /* Errors are legitimate for non-integer byte multiples */
4037 if (val_bytes > 0)
4038 component->val_bytes = val_bytes;
4039 }
4040}
4041
4138static void snd_soc_component_add_unlocked(struct snd_soc_component *component) 4042static void snd_soc_component_add_unlocked(struct snd_soc_component *component)
4139{ 4043{
4044 if (!component->write && !component->read)
4045 snd_soc_component_init_regmap(component);
4046
4140 list_add(&component->list, &component_list); 4047 list_add(&component->list, &component_list);
4141} 4048}
4142 4049
@@ -4225,22 +4132,18 @@ found:
4225} 4132}
4226EXPORT_SYMBOL_GPL(snd_soc_unregister_component); 4133EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
4227 4134
4228static int snd_soc_platform_drv_write(struct snd_soc_component *component, 4135static int snd_soc_platform_drv_probe(struct snd_soc_component *component)
4229 unsigned int reg, unsigned int val)
4230{ 4136{
4231 struct snd_soc_platform *platform = snd_soc_component_to_platform(component); 4137 struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
4232 4138
4233 return platform->driver->write(platform, reg, val); 4139 return platform->driver->probe(platform);
4234} 4140}
4235 4141
4236static int snd_soc_platform_drv_read(struct snd_soc_component *component, 4142static void snd_soc_platform_drv_remove(struct snd_soc_component *component)
4237 unsigned int reg, unsigned int *val)
4238{ 4143{
4239 struct snd_soc_platform *platform = snd_soc_component_to_platform(component); 4144 struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
4240 4145
4241 *val = platform->driver->read(platform, reg); 4146 platform->driver->remove(platform);
4242
4243 return 0;
4244} 4147}
4245 4148
4246/** 4149/**
@@ -4261,10 +4164,28 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
4261 4164
4262 platform->dev = dev; 4165 platform->dev = dev;
4263 platform->driver = platform_drv; 4166 platform->driver = platform_drv;
4264 if (platform_drv->write) 4167 if (platform_drv->controls) {
4265 platform->component.write = snd_soc_platform_drv_write; 4168 platform->component.controls = platform_drv->controls;
4266 if (platform_drv->read) 4169 platform->component.num_controls = platform_drv->num_controls;
4267 platform->component.read = snd_soc_platform_drv_read; 4170 }
4171 if (platform_drv->dapm_widgets) {
4172 platform->component.dapm_widgets = platform_drv->dapm_widgets;
4173 platform->component.num_dapm_widgets = platform_drv->num_dapm_widgets;
4174 platform->component.steal_sibling_dai_widgets = true;
4175 }
4176 if (platform_drv->dapm_routes) {
4177 platform->component.dapm_routes = platform_drv->dapm_routes;
4178 platform->component.num_dapm_routes = platform_drv->num_dapm_routes;
4179 }
4180
4181 if (platform_drv->probe)
4182 platform->component.probe = snd_soc_platform_drv_probe;
4183 if (platform_drv->remove)
4184 platform->component.remove = snd_soc_platform_drv_remove;
4185
4186#ifdef CONFIG_DEBUG_FS
4187 platform->component.debugfs_prefix = "platform";
4188#endif
4268 4189
4269 mutex_lock(&client_mutex); 4190 mutex_lock(&client_mutex);
4270 snd_soc_component_add_unlocked(&platform->component); 4191 snd_soc_component_add_unlocked(&platform->component);
@@ -4386,6 +4307,20 @@ static void fixup_codec_formats(struct snd_soc_pcm_stream *stream)
4386 stream->formats |= codec_format_map[i]; 4307 stream->formats |= codec_format_map[i];
4387} 4308}
4388 4309
4310static int snd_soc_codec_drv_probe(struct snd_soc_component *component)
4311{
4312 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
4313
4314 return codec->driver->probe(codec);
4315}
4316
4317static void snd_soc_codec_drv_remove(struct snd_soc_component *component)
4318{
4319 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
4320
4321 codec->driver->remove(codec);
4322}
4323
4389static int snd_soc_codec_drv_write(struct snd_soc_component *component, 4324static int snd_soc_codec_drv_write(struct snd_soc_component *component,
4390 unsigned int reg, unsigned int val) 4325 unsigned int reg, unsigned int val)
4391{ 4326{
@@ -4424,7 +4359,6 @@ int snd_soc_register_codec(struct device *dev,
4424{ 4359{
4425 struct snd_soc_codec *codec; 4360 struct snd_soc_codec *codec;
4426 struct snd_soc_dai *dai; 4361 struct snd_soc_dai *dai;
4427 struct regmap *regmap;
4428 int ret, i; 4362 int ret, i;
4429 4363
4430 dev_dbg(dev, "codec register %s\n", dev_name(dev)); 4364 dev_dbg(dev, "codec register %s\n", dev_name(dev));
@@ -4434,18 +4368,37 @@ int snd_soc_register_codec(struct device *dev,
4434 return -ENOMEM; 4368 return -ENOMEM;
4435 4369
4436 codec->component.dapm_ptr = &codec->dapm; 4370 codec->component.dapm_ptr = &codec->dapm;
4371 codec->component.codec = codec;
4437 4372
4438 ret = snd_soc_component_initialize(&codec->component, 4373 ret = snd_soc_component_initialize(&codec->component,
4439 &codec_drv->component_driver, dev); 4374 &codec_drv->component_driver, dev);
4440 if (ret) 4375 if (ret)
4441 goto err_free; 4376 goto err_free;
4442 4377
4378 if (codec_drv->controls) {
4379 codec->component.controls = codec_drv->controls;
4380 codec->component.num_controls = codec_drv->num_controls;
4381 }
4382 if (codec_drv->dapm_widgets) {
4383 codec->component.dapm_widgets = codec_drv->dapm_widgets;
4384 codec->component.num_dapm_widgets = codec_drv->num_dapm_widgets;
4385 }
4386 if (codec_drv->dapm_routes) {
4387 codec->component.dapm_routes = codec_drv->dapm_routes;
4388 codec->component.num_dapm_routes = codec_drv->num_dapm_routes;
4389 }
4390
4391 if (codec_drv->probe)
4392 codec->component.probe = snd_soc_codec_drv_probe;
4393 if (codec_drv->remove)
4394 codec->component.remove = snd_soc_codec_drv_remove;
4443 if (codec_drv->write) 4395 if (codec_drv->write)
4444 codec->component.write = snd_soc_codec_drv_write; 4396 codec->component.write = snd_soc_codec_drv_write;
4445 if (codec_drv->read) 4397 if (codec_drv->read)
4446 codec->component.read = snd_soc_codec_drv_read; 4398 codec->component.read = snd_soc_codec_drv_read;
4447 codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time; 4399 codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time;
4448 codec->dapm.codec = codec; 4400 codec->dapm.codec = codec;
4401 codec->dapm.idle_bias_off = codec_drv->idle_bias_off;
4449 if (codec_drv->seq_notifier) 4402 if (codec_drv->seq_notifier)
4450 codec->dapm.seq_notifier = codec_drv->seq_notifier; 4403 codec->dapm.seq_notifier = codec_drv->seq_notifier;
4451 if (codec_drv->set_bias_level) 4404 if (codec_drv->set_bias_level)
@@ -4455,23 +4408,13 @@ int snd_soc_register_codec(struct device *dev,
4455 codec->component.val_bytes = codec_drv->reg_word_size; 4408 codec->component.val_bytes = codec_drv->reg_word_size;
4456 mutex_init(&codec->mutex); 4409 mutex_init(&codec->mutex);
4457 4410
4458 if (!codec->component.write) { 4411#ifdef CONFIG_DEBUG_FS
4459 if (codec_drv->get_regmap) 4412 codec->component.init_debugfs = soc_init_codec_debugfs;
4460 regmap = codec_drv->get_regmap(dev); 4413 codec->component.debugfs_prefix = "codec";
4461 else 4414#endif
4462 regmap = dev_get_regmap(dev, NULL); 4415
4463 4416 if (codec_drv->get_regmap)
4464 if (regmap) { 4417 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 4418
4476 for (i = 0; i < num_dai; i++) { 4419 for (i = 0; i < num_dai; i++) {
4477 fixup_codec_formats(&dai_drv[i].playback); 4420 fixup_codec_formats(&dai_drv[i].playback);
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c b/sound/soc/soc-generic-dmaengine-pcm.c
index 6307f85e871b..b329b84bc5af 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -336,10 +336,12 @@ static const struct snd_pcm_ops dmaengine_pcm_ops = {
336}; 336};
337 337
338static const struct snd_soc_platform_driver dmaengine_pcm_platform = { 338static const struct snd_soc_platform_driver dmaengine_pcm_platform = {
339 .component_driver = {
340 .probe_order = SND_SOC_COMP_ORDER_LATE,
341 },
339 .ops = &dmaengine_pcm_ops, 342 .ops = &dmaengine_pcm_ops,
340 .pcm_new = dmaengine_pcm_new, 343 .pcm_new = dmaengine_pcm_new,
341 .pcm_free = dmaengine_pcm_free, 344 .pcm_free = dmaengine_pcm_free,
342 .probe_order = SND_SOC_COMP_ORDER_LATE,
343}; 345};
344 346
345static const char * const dmaengine_pcm_dma_channel_names[] = { 347static const char * const dmaengine_pcm_dma_channel_names[] = {
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index 7767fbd73eb7..9b3939049cef 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -271,31 +271,3 @@ int snd_soc_platform_write(struct snd_soc_platform *platform,
271 return snd_soc_component_write(&platform->component, reg, val); 271 return snd_soc_component_write(&platform->component, reg, val);
272} 272}
273EXPORT_SYMBOL_GPL(snd_soc_platform_write); 273EXPORT_SYMBOL_GPL(snd_soc_platform_write);
274
275/**
276 * snd_soc_component_init_io() - Initialize regmap IO
277 *
278 * @component: component to initialize
279 * @regmap: regmap instance to use for IO operations
280 *
281 * Return: 0 on success, a negative error code otherwise
282 */
283int snd_soc_component_init_io(struct snd_soc_component *component,
284 struct regmap *regmap)
285{
286 int ret;
287
288 if (!regmap)
289 return -EINVAL;
290
291 ret = regmap_get_val_bytes(regmap);
292 /* Errors are legitimate for non-integer byte
293 * multiples */
294 if (ret > 0)
295 component->val_bytes = ret;
296
297 component->regmap = regmap;
298
299 return 0;
300}
301EXPORT_SYMBOL_GPL(snd_soc_component_init_io);