aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2014-09-06 08:38:26 -0400
committerMark Brown <broonie@kernel.org>2014-09-06 08:38:26 -0400
commitbade5f09ca5bfd5a5f499a682509a9109472bca8 (patch)
tree04565ef0457ee2d3ee3705ca54936a227723be8d
parent75c3daaad5a2f791e0fbad732690130ce1bc55d2 (diff)
parent85362efb80070bed890602483f71cd103be303c2 (diff)
Merge branch 'topic/suspend' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into asoc-es8328
-rw-r--r--include/sound/soc-dapm.h3
-rw-r--r--include/sound/soc.h69
-rw-r--r--sound/soc/codecs/adau1373.c21
-rw-r--r--sound/soc/codecs/adau1761.c2
-rw-r--r--sound/soc/codecs/adau1781.c2
-rw-r--r--sound/soc/codecs/adau17x1.c8
-rw-r--r--sound/soc/codecs/adau17x1.h1
-rw-r--r--sound/soc/codecs/adav80x.c23
-rw-r--r--sound/soc/codecs/lm49453.c14
-rw-r--r--sound/soc/codecs/ssm2518.c13
-rw-r--r--sound/soc/codecs/ssm2602.c24
-rw-r--r--sound/soc/codecs/tlv320aic3x.c16
-rw-r--r--sound/soc/codecs/wm8804.c19
-rw-r--r--sound/soc/codecs/wm8995.c19
-rw-r--r--sound/soc/samsung/speyside.c6
-rw-r--r--sound/soc/soc-core.c686
-rw-r--r--sound/soc/soc-dapm.c20
-rw-r--r--sound/soc/soc-generic-dmaengine-pcm.c4
-rw-r--r--sound/soc/soc-io.c28
19 files changed, 397 insertions, 581 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index aac04ff84eea..f955d65c5656 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -587,7 +587,8 @@ struct snd_soc_dapm_context {
587 enum snd_soc_bias_level suspend_bias_level; 587 enum snd_soc_bias_level suspend_bias_level;
588 struct delayed_work delayed_work; 588 struct delayed_work delayed_work;
589 unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */ 589 unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */
590 590 /* Go to BIAS_OFF in suspend if the DAPM context is idle */
591 unsigned int suspend_bias_off:1;
591 void (*seq_notifier)(struct snd_soc_dapm_context *, 592 void (*seq_notifier)(struct snd_soc_dapm_context *,
592 enum snd_soc_dapm_type, int); 593 enum snd_soc_dapm_type, int);
593 594
diff --git a/include/sound/soc.h b/include/sound/soc.h
index be6ecae247b0..ac99fc083eec 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};
@@ -808,15 +848,12 @@ struct snd_soc_codec_driver {
808 int (*set_bias_level)(struct snd_soc_codec *, 848 int (*set_bias_level)(struct snd_soc_codec *,
809 enum snd_soc_bias_level level); 849 enum snd_soc_bias_level level);
810 bool idle_bias_off; 850 bool idle_bias_off;
851 bool suspend_bias_off;
811 852
812 void (*seq_notifier)(struct snd_soc_dapm_context *, 853 void (*seq_notifier)(struct snd_soc_dapm_context *,
813 enum snd_soc_dapm_type, int); 854 enum snd_soc_dapm_type, int);
814 855
815 bool ignore_pmdown_time; /* Doesn't benefit from pmdown delay */ 856 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}; 857};
821 858
822/* SoC platform interface */ 859/* SoC platform interface */
@@ -853,13 +890,6 @@ struct snd_soc_platform_driver {
853 /* platform stream compress ops */ 890 /* platform stream compress ops */
854 const struct snd_compr_ops *compr_ops; 891 const struct snd_compr_ops *compr_ops;
855 892
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); 893 int (*bespoke_trigger)(struct snd_pcm_substream *, int);
864}; 894};
865 895
@@ -874,15 +904,10 @@ struct snd_soc_platform {
874 const struct snd_soc_platform_driver *driver; 904 const struct snd_soc_platform_driver *driver;
875 905
876 unsigned int suspended:1; /* platform is suspended */ 906 unsigned int suspended:1; /* platform is suspended */
877 unsigned int probed:1;
878 907
879 struct list_head list; 908 struct list_head list;
880 909
881 struct snd_soc_component component; 910 struct snd_soc_component component;
882
883#ifdef CONFIG_DEBUG_FS
884 struct dentry *debugfs_platform_root;
885#endif
886}; 911};
887 912
888struct snd_soc_dai_link { 913struct snd_soc_dai_link {
@@ -994,7 +1019,7 @@ struct snd_soc_aux_dev {
994 const struct device_node *codec_of_node; 1019 const struct device_node *codec_of_node;
995 1020
996 /* codec/machine specific init - e.g. add machine controls */ 1021 /* codec/machine specific init - e.g. add machine controls */
997 int (*init)(struct snd_soc_dapm_context *dapm); 1022 int (*init)(struct snd_soc_component *component);
998}; 1023};
999 1024
1000/* SoC card */ 1025/* SoC card */
@@ -1112,6 +1137,7 @@ struct snd_soc_pcm_runtime {
1112 struct snd_soc_platform *platform; 1137 struct snd_soc_platform *platform;
1113 struct snd_soc_dai *codec_dai; 1138 struct snd_soc_dai *codec_dai;
1114 struct snd_soc_dai *cpu_dai; 1139 struct snd_soc_dai *cpu_dai;
1140 struct snd_soc_component *component; /* Only valid for AUX dev rtds */
1115 1141
1116 struct snd_soc_dai **codec_dais; 1142 struct snd_soc_dai **codec_dais;
1117 unsigned int num_codecs; 1143 unsigned int num_codecs;
@@ -1260,9 +1286,6 @@ void snd_soc_component_async_complete(struct snd_soc_component *component);
1260int snd_soc_component_test_bits(struct snd_soc_component *component, 1286int snd_soc_component_test_bits(struct snd_soc_component *component,
1261 unsigned int reg, unsigned int mask, unsigned int value); 1287 unsigned int reg, unsigned int mask, unsigned int value);
1262 1288
1263int snd_soc_component_init_io(struct snd_soc_component *component,
1264 struct regmap *regmap);
1265
1266/* device driver data */ 1289/* device driver data */
1267 1290
1268static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card, 1291static inline void snd_soc_card_set_drvdata(struct snd_soc_card *card,
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c
index 1ff7d4d027e9..7c784ad3e8b2 100644
--- a/sound/soc/codecs/adau1373.c
+++ b/sound/soc/codecs/adau1373.c
@@ -1448,29 +1448,10 @@ static int adau1373_set_bias_level(struct snd_soc_codec *codec,
1448 return 0; 1448 return 0;
1449} 1449}
1450 1450
1451static int adau1373_remove(struct snd_soc_codec *codec)
1452{
1453 adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF);
1454 return 0;
1455}
1456
1457static int adau1373_suspend(struct snd_soc_codec *codec)
1458{
1459 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
1460 int ret;
1461
1462 ret = adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF);
1463 regcache_cache_only(adau1373->regmap, true);
1464
1465 return ret;
1466}
1467
1468static int adau1373_resume(struct snd_soc_codec *codec) 1451static int adau1373_resume(struct snd_soc_codec *codec)
1469{ 1452{
1470 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec); 1453 struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec);
1471 1454
1472 regcache_cache_only(adau1373->regmap, false);
1473 adau1373_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1474 regcache_sync(adau1373->regmap); 1455 regcache_sync(adau1373->regmap);
1475 1456
1476 return 0; 1457 return 0;
@@ -1501,8 +1482,6 @@ static const struct regmap_config adau1373_regmap_config = {
1501 1482
1502static struct snd_soc_codec_driver adau1373_codec_driver = { 1483static struct snd_soc_codec_driver adau1373_codec_driver = {
1503 .probe = adau1373_probe, 1484 .probe = adau1373_probe,
1504 .remove = adau1373_remove,
1505 .suspend = adau1373_suspend,
1506 .resume = adau1373_resume, 1485 .resume = adau1373_resume,
1507 .set_bias_level = adau1373_set_bias_level, 1486 .set_bias_level = adau1373_set_bias_level,
1508 .idle_bias_off = true, 1487 .idle_bias_off = true,
diff --git a/sound/soc/codecs/adau1761.c b/sound/soc/codecs/adau1761.c
index 848cab839553..5518ebd6947c 100644
--- a/sound/soc/codecs/adau1761.c
+++ b/sound/soc/codecs/adau1761.c
@@ -714,9 +714,9 @@ static int adau1761_codec_probe(struct snd_soc_codec *codec)
714 714
715static const struct snd_soc_codec_driver adau1761_codec_driver = { 715static const struct snd_soc_codec_driver adau1761_codec_driver = {
716 .probe = adau1761_codec_probe, 716 .probe = adau1761_codec_probe,
717 .suspend = adau17x1_suspend,
718 .resume = adau17x1_resume, 717 .resume = adau17x1_resume,
719 .set_bias_level = adau1761_set_bias_level, 718 .set_bias_level = adau1761_set_bias_level,
719 .suspend_bias_off = true,
720 720
721 .controls = adau1761_controls, 721 .controls = adau1761_controls,
722 .num_controls = ARRAY_SIZE(adau1761_controls), 722 .num_controls = ARRAY_SIZE(adau1761_controls),
diff --git a/sound/soc/codecs/adau1781.c b/sound/soc/codecs/adau1781.c
index 045a61413840..e9fc00fb13dd 100644
--- a/sound/soc/codecs/adau1781.c
+++ b/sound/soc/codecs/adau1781.c
@@ -446,9 +446,9 @@ static int adau1781_codec_probe(struct snd_soc_codec *codec)
446 446
447static const struct snd_soc_codec_driver adau1781_codec_driver = { 447static const struct snd_soc_codec_driver adau1781_codec_driver = {
448 .probe = adau1781_codec_probe, 448 .probe = adau1781_codec_probe,
449 .suspend = adau17x1_suspend,
450 .resume = adau17x1_resume, 449 .resume = adau17x1_resume,
451 .set_bias_level = adau1781_set_bias_level, 450 .set_bias_level = adau1781_set_bias_level,
451 .suspend_bias_off = true,
452 452
453 .controls = adau1781_controls, 453 .controls = adau1781_controls,
454 .num_controls = ARRAY_SIZE(adau1781_controls), 454 .num_controls = ARRAY_SIZE(adau1781_controls),
diff --git a/sound/soc/codecs/adau17x1.c b/sound/soc/codecs/adau17x1.c
index 0b659704e60c..3e16c1c64115 100644
--- a/sound/soc/codecs/adau17x1.c
+++ b/sound/soc/codecs/adau17x1.c
@@ -815,13 +815,6 @@ int adau17x1_add_routes(struct snd_soc_codec *codec)
815} 815}
816EXPORT_SYMBOL_GPL(adau17x1_add_routes); 816EXPORT_SYMBOL_GPL(adau17x1_add_routes);
817 817
818int adau17x1_suspend(struct snd_soc_codec *codec)
819{
820 codec->driver->set_bias_level(codec, SND_SOC_BIAS_OFF);
821 return 0;
822}
823EXPORT_SYMBOL_GPL(adau17x1_suspend);
824
825int adau17x1_resume(struct snd_soc_codec *codec) 818int adau17x1_resume(struct snd_soc_codec *codec)
826{ 819{
827 struct adau *adau = snd_soc_codec_get_drvdata(codec); 820 struct adau *adau = snd_soc_codec_get_drvdata(codec);
@@ -829,7 +822,6 @@ int adau17x1_resume(struct snd_soc_codec *codec)
829 if (adau->switch_mode) 822 if (adau->switch_mode)
830 adau->switch_mode(codec->dev); 823 adau->switch_mode(codec->dev);
831 824
832 codec->driver->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
833 regcache_sync(adau->regmap); 825 regcache_sync(adau->regmap);
834 826
835 return 0; 827 return 0;
diff --git a/sound/soc/codecs/adau17x1.h b/sound/soc/codecs/adau17x1.h
index 3ffabaf4c7a8..e4a557fd7155 100644
--- a/sound/soc/codecs/adau17x1.h
+++ b/sound/soc/codecs/adau17x1.h
@@ -52,7 +52,6 @@ int adau17x1_set_micbias_voltage(struct snd_soc_codec *codec,
52 enum adau17x1_micbias_voltage micbias); 52 enum adau17x1_micbias_voltage micbias);
53bool adau17x1_readable_register(struct device *dev, unsigned int reg); 53bool adau17x1_readable_register(struct device *dev, unsigned int reg);
54bool adau17x1_volatile_register(struct device *dev, unsigned int reg); 54bool adau17x1_volatile_register(struct device *dev, unsigned int reg);
55int adau17x1_suspend(struct snd_soc_codec *codec);
56int adau17x1_resume(struct snd_soc_codec *codec); 55int adau17x1_resume(struct snd_soc_codec *codec);
57 56
58extern const struct snd_soc_dai_ops adau17x1_dai_ops; 57extern const struct snd_soc_dai_ops adau17x1_dai_ops;
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c
index c43b93fdf0df..ce3cdca9fc62 100644
--- a/sound/soc/codecs/adav80x.c
+++ b/sound/soc/codecs/adav80x.c
@@ -812,42 +812,23 @@ static int adav80x_probe(struct snd_soc_codec *codec)
812 /* Disable DAC zero flag */ 812 /* Disable DAC zero flag */
813 regmap_write(adav80x->regmap, ADAV80X_DAC_CTRL3, 0x6); 813 regmap_write(adav80x->regmap, ADAV80X_DAC_CTRL3, 0x6);
814 814
815 return adav80x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 815 return 0;
816}
817
818static int adav80x_suspend(struct snd_soc_codec *codec)
819{
820 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
821 int ret;
822
823 ret = adav80x_set_bias_level(codec, SND_SOC_BIAS_OFF);
824 regcache_cache_only(adav80x->regmap, true);
825
826 return ret;
827} 816}
828 817
829static int adav80x_resume(struct snd_soc_codec *codec) 818static int adav80x_resume(struct snd_soc_codec *codec)
830{ 819{
831 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); 820 struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec);
832 821
833 regcache_cache_only(adav80x->regmap, false);
834 adav80x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
835 regcache_sync(adav80x->regmap); 822 regcache_sync(adav80x->regmap);
836 823
837 return 0; 824 return 0;
838} 825}
839 826
840static int adav80x_remove(struct snd_soc_codec *codec)
841{
842 return adav80x_set_bias_level(codec, SND_SOC_BIAS_OFF);
843}
844
845static struct snd_soc_codec_driver adav80x_codec_driver = { 827static struct snd_soc_codec_driver adav80x_codec_driver = {
846 .probe = adav80x_probe, 828 .probe = adav80x_probe,
847 .remove = adav80x_remove,
848 .suspend = adav80x_suspend,
849 .resume = adav80x_resume, 829 .resume = adav80x_resume,
850 .set_bias_level = adav80x_set_bias_level, 830 .set_bias_level = adav80x_set_bias_level,
831 .suspend_bias_off = true,
851 832
852 .set_pll = adav80x_set_pll, 833 .set_pll = adav80x_set_pll,
853 .set_sysclk = adav80x_set_sysclk, 834 .set_sysclk = adav80x_set_sysclk,
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c
index 275b3f72f3f4..c1ae5764983f 100644
--- a/sound/soc/codecs/lm49453.c
+++ b/sound/soc/codecs/lm49453.c
@@ -1395,18 +1395,6 @@ static struct snd_soc_dai_driver lm49453_dai[] = {
1395 }, 1395 },
1396}; 1396};
1397 1397
1398static int lm49453_suspend(struct snd_soc_codec *codec)
1399{
1400 lm49453_set_bias_level(codec, SND_SOC_BIAS_OFF);
1401 return 0;
1402}
1403
1404static int lm49453_resume(struct snd_soc_codec *codec)
1405{
1406 lm49453_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1407 return 0;
1408}
1409
1410/* power down chip */ 1398/* power down chip */
1411static int lm49453_remove(struct snd_soc_codec *codec) 1399static int lm49453_remove(struct snd_soc_codec *codec)
1412{ 1400{
@@ -1416,8 +1404,6 @@ static int lm49453_remove(struct snd_soc_codec *codec)
1416 1404
1417static struct snd_soc_codec_driver soc_codec_dev_lm49453 = { 1405static struct snd_soc_codec_driver soc_codec_dev_lm49453 = {
1418 .remove = lm49453_remove, 1406 .remove = lm49453_remove,
1419 .suspend = lm49453_suspend,
1420 .resume = lm49453_resume,
1421 .set_bias_level = lm49453_set_bias_level, 1407 .set_bias_level = lm49453_set_bias_level,
1422 .controls = lm49453_snd_controls, 1408 .controls = lm49453_snd_controls,
1423 .num_controls = ARRAY_SIZE(lm49453_snd_controls), 1409 .num_controls = ARRAY_SIZE(lm49453_snd_controls),
diff --git a/sound/soc/codecs/ssm2518.c b/sound/soc/codecs/ssm2518.c
index e8680bea5f86..67ea55adb307 100644
--- a/sound/soc/codecs/ssm2518.c
+++ b/sound/soc/codecs/ssm2518.c
@@ -646,17 +646,6 @@ static struct snd_soc_dai_driver ssm2518_dai = {
646 .ops = &ssm2518_dai_ops, 646 .ops = &ssm2518_dai_ops,
647}; 647};
648 648
649static int ssm2518_probe(struct snd_soc_codec *codec)
650{
651 return ssm2518_set_bias_level(codec, SND_SOC_BIAS_OFF);
652}
653
654static int ssm2518_remove(struct snd_soc_codec *codec)
655{
656 ssm2518_set_bias_level(codec, SND_SOC_BIAS_OFF);
657 return 0;
658}
659
660static int ssm2518_set_sysclk(struct snd_soc_codec *codec, int clk_id, 649static int ssm2518_set_sysclk(struct snd_soc_codec *codec, int clk_id,
661 int source, unsigned int freq, int dir) 650 int source, unsigned int freq, int dir)
662{ 651{
@@ -727,8 +716,6 @@ static int ssm2518_set_sysclk(struct snd_soc_codec *codec, int clk_id,
727} 716}
728 717
729static struct snd_soc_codec_driver ssm2518_codec_driver = { 718static struct snd_soc_codec_driver ssm2518_codec_driver = {
730 .probe = ssm2518_probe,
731 .remove = ssm2518_remove,
732 .set_bias_level = ssm2518_set_bias_level, 719 .set_bias_level = ssm2518_set_bias_level,
733 .set_sysclk = ssm2518_set_sysclk, 720 .set_sysclk = ssm2518_set_sysclk,
734 .idle_bias_off = true, 721 .idle_bias_off = true,
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 484b3bbe8624..0dec13648563 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -502,18 +502,11 @@ static struct snd_soc_dai_driver ssm2602_dai = {
502 .symmetric_samplebits = 1, 502 .symmetric_samplebits = 1,
503}; 503};
504 504
505static int ssm2602_suspend(struct snd_soc_codec *codec)
506{
507 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
508 return 0;
509}
510
511static int ssm2602_resume(struct snd_soc_codec *codec) 505static int ssm2602_resume(struct snd_soc_codec *codec)
512{ 506{
513 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); 507 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
514 508
515 regcache_sync(ssm2602->regmap); 509 regcache_sync(ssm2602->regmap);
516 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
517 510
518 return 0; 511 return 0;
519} 512}
@@ -586,27 +579,14 @@ static int ssm260x_codec_probe(struct snd_soc_codec *codec)
586 break; 579 break;
587 } 580 }
588 581
589 if (ret) 582 return ret;
590 return ret;
591
592 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
593
594 return 0;
595}
596
597/* remove everything here */
598static int ssm2602_remove(struct snd_soc_codec *codec)
599{
600 ssm2602_set_bias_level(codec, SND_SOC_BIAS_OFF);
601 return 0;
602} 583}
603 584
604static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = { 585static struct snd_soc_codec_driver soc_codec_dev_ssm2602 = {
605 .probe = ssm260x_codec_probe, 586 .probe = ssm260x_codec_probe,
606 .remove = ssm2602_remove,
607 .suspend = ssm2602_suspend,
608 .resume = ssm2602_resume, 587 .resume = ssm2602_resume,
609 .set_bias_level = ssm2602_set_bias_level, 588 .set_bias_level = ssm2602_set_bias_level,
589 .suspend_bias_off = true,
610 590
611 .controls = ssm260x_snd_controls, 591 .controls = ssm260x_snd_controls,
612 .num_controls = ARRAY_SIZE(ssm260x_snd_controls), 592 .num_controls = ARRAY_SIZE(ssm260x_snd_controls),
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 64f179ee9834..f2c416d16b6c 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -1222,20 +1222,6 @@ static struct snd_soc_dai_driver aic3x_dai = {
1222 .symmetric_rates = 1, 1222 .symmetric_rates = 1,
1223}; 1223};
1224 1224
1225static int aic3x_suspend(struct snd_soc_codec *codec)
1226{
1227 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1228
1229 return 0;
1230}
1231
1232static int aic3x_resume(struct snd_soc_codec *codec)
1233{
1234 aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1235
1236 return 0;
1237}
1238
1239static void aic3x_mono_init(struct snd_soc_codec *codec) 1225static void aic3x_mono_init(struct snd_soc_codec *codec)
1240{ 1226{
1241 /* DAC to Mono Line Out default volume and route to Output mixer */ 1227 /* DAC to Mono Line Out default volume and route to Output mixer */
@@ -1429,8 +1415,6 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = {
1429 .idle_bias_off = true, 1415 .idle_bias_off = true,
1430 .probe = aic3x_probe, 1416 .probe = aic3x_probe,
1431 .remove = aic3x_remove, 1417 .remove = aic3x_remove,
1432 .suspend = aic3x_suspend,
1433 .resume = aic3x_resume,
1434 .controls = aic3x_snd_controls, 1418 .controls = aic3x_snd_controls,
1435 .num_controls = ARRAY_SIZE(aic3x_snd_controls), 1419 .num_controls = ARRAY_SIZE(aic3x_snd_controls),
1436 .dapm_widgets = aic3x_dapm_widgets, 1420 .dapm_widgets = aic3x_dapm_widgets,
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index 0ea01dfcb6e1..3addc5fe5cb2 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -518,23 +518,6 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec,
518 return 0; 518 return 0;
519} 519}
520 520
521#ifdef CONFIG_PM
522static int wm8804_suspend(struct snd_soc_codec *codec)
523{
524 wm8804_set_bias_level(codec, SND_SOC_BIAS_OFF);
525 return 0;
526}
527
528static int wm8804_resume(struct snd_soc_codec *codec)
529{
530 wm8804_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
531 return 0;
532}
533#else
534#define wm8804_suspend NULL
535#define wm8804_resume NULL
536#endif
537
538static int wm8804_remove(struct snd_soc_codec *codec) 521static int wm8804_remove(struct snd_soc_codec *codec)
539{ 522{
540 struct wm8804_priv *wm8804; 523 struct wm8804_priv *wm8804;
@@ -671,8 +654,6 @@ static struct snd_soc_dai_driver wm8804_dai = {
671static struct snd_soc_codec_driver soc_codec_dev_wm8804 = { 654static struct snd_soc_codec_driver soc_codec_dev_wm8804 = {
672 .probe = wm8804_probe, 655 .probe = wm8804_probe,
673 .remove = wm8804_remove, 656 .remove = wm8804_remove,
674 .suspend = wm8804_suspend,
675 .resume = wm8804_resume,
676 .set_bias_level = wm8804_set_bias_level, 657 .set_bias_level = wm8804_set_bias_level,
677 .idle_bias_off = true, 658 .idle_bias_off = true,
678 659
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
index cae4ac5a5730..1288edeb8c7d 100644
--- a/sound/soc/codecs/wm8995.c
+++ b/sound/soc/codecs/wm8995.c
@@ -1998,23 +1998,6 @@ static int wm8995_set_bias_level(struct snd_soc_codec *codec,
1998 return 0; 1998 return 0;
1999} 1999}
2000 2000
2001#ifdef CONFIG_PM
2002static int wm8995_suspend(struct snd_soc_codec *codec)
2003{
2004 wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF);
2005 return 0;
2006}
2007
2008static int wm8995_resume(struct snd_soc_codec *codec)
2009{
2010 wm8995_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2011 return 0;
2012}
2013#else
2014#define wm8995_suspend NULL
2015#define wm8995_resume NULL
2016#endif
2017
2018static int wm8995_remove(struct snd_soc_codec *codec) 2001static int wm8995_remove(struct snd_soc_codec *codec)
2019{ 2002{
2020 struct wm8995_priv *wm8995; 2003 struct wm8995_priv *wm8995;
@@ -2220,8 +2203,6 @@ static struct snd_soc_dai_driver wm8995_dai[] = {
2220static struct snd_soc_codec_driver soc_codec_dev_wm8995 = { 2203static struct snd_soc_codec_driver soc_codec_dev_wm8995 = {
2221 .probe = wm8995_probe, 2204 .probe = wm8995_probe,
2222 .remove = wm8995_remove, 2205 .remove = wm8995_remove,
2223 .suspend = wm8995_suspend,
2224 .resume = wm8995_resume,
2225 .set_bias_level = wm8995_set_bias_level, 2206 .set_bias_level = wm8995_set_bias_level,
2226 .idle_bias_off = true, 2207 .idle_bias_off = true,
2227}; 2208};
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..c612900c80ff 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;
882
883 /* Find CPU DAI from registered DAIs*/
884 list_for_each_entry(component, &component_list, list) {
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;
915 892
916 list_for_each_entry(codec_dai, &codec->component.dai_list, list) { 893 return dai;
917 if (!strcmp(codec_dai->name, codec_dai_name)) {
918 return codec_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,111 @@ 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; 1093 struct snd_soc_component *dai_component, *component2;
1181 struct snd_soc_dai *dai; 1094 struct snd_soc_dai *dai;
1095 int ret;
1096
1097 if (component->probed)
1098 return 0;
1182 1099
1183 codec->component.card = card; 1100 component->card = card;
1184 codec->dapm.card = card; 1101 dapm->card = card;
1185 soc_set_name_prefix(card, &codec->component); 1102 soc_set_name_prefix(card, component);
1186 1103
1187 if (!try_module_get(codec->dev->driver->owner)) 1104 if (!try_module_get(component->dev->driver->owner))
1188 return -ENODEV; 1105 return -ENODEV;
1189 1106
1190 soc_init_codec_debugfs(codec); 1107 soc_init_component_debugfs(component);
1191 1108
1192 if (driver->dapm_widgets) { 1109 if (component->dapm_widgets) {
1193 ret = snd_soc_dapm_new_controls(&codec->dapm, 1110 ret = snd_soc_dapm_new_controls(dapm, component->dapm_widgets,
1194 driver->dapm_widgets, 1111 component->num_dapm_widgets);
1195 driver->num_dapm_widgets);
1196 1112
1197 if (ret != 0) { 1113 if (ret != 0) {
1198 dev_err(codec->dev, 1114 dev_err(component->dev,
1199 "Failed to create new controls %d\n", ret); 1115 "Failed to create new controls %d\n", ret);
1200 goto err_probe; 1116 goto err_probe;
1201 } 1117 }
1202 } 1118 }
1203 1119
1204 /* Create DAPM widgets for each DAI stream */ 1120 /*
1205 list_for_each_entry(dai, &codec->component.dai_list, list) { 1121 * This is rather ugly, but certain platforms expect that the DAPM
1206 ret = snd_soc_dapm_new_dai_widgets(&codec->dapm, dai); 1122 * widgets for the DAIs for components with the same parent device are
1123 * created in the platforms DAPM context. Until that is fixed we need to
1124 * keep this.
1125 */
1126 if (component->steal_sibling_dai_widgets) {
1127 dai_component = NULL;
1128 list_for_each_entry(component2, &component_list, list) {
1129 if (component == component2)
1130 continue;
1207 1131
1208 if (ret != 0) { 1132 if (component2->dev == component->dev &&
1209 dev_err(codec->dev, 1133 !list_empty(&component2->dai_list)) {
1210 "Failed to create DAI widgets %d\n", ret); 1134 dai_component = component2;
1211 goto err_probe; 1135 break;
1136 }
1212 } 1137 }
1213 } 1138 } else {
1214 1139 dai_component = component;
1215 codec->dapm.idle_bias_off = driver->idle_bias_off; 1140 list_for_each_entry(component2, &component_list, list) {
1216 1141 if (component2->dev == component->dev &&
1217 if (driver->probe) { 1142 component2->steal_sibling_dai_widgets) {
1218 ret = driver->probe(codec); 1143 dai_component = NULL;
1219 if (ret < 0) { 1144 break;
1220 dev_err(codec->dev, 1145 }
1221 "ASoC: failed to probe CODEC %d\n", ret);
1222 goto err_probe;
1223 } 1146 }
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 } 1147 }
1229 1148
1230 if (driver->controls) 1149 if (dai_component) {
1231 snd_soc_add_codec_controls(codec, driver->controls, 1150 list_for_each_entry(dai, &dai_component->dai_list, list) {
1232 driver->num_controls); 1151 snd_soc_dapm_new_dai_widgets(dapm, dai);
1233 if (driver->dapm_routes) 1152 if (ret != 0) {
1234 snd_soc_dapm_add_routes(&codec->dapm, driver->dapm_routes, 1153 dev_err(component->dev,
1235 driver->num_dapm_routes); 1154 "Failed to create DAI widgets %d\n",
1236 1155 ret);
1237 /* mark codec as probed and add to card codec list */ 1156 goto err_probe;
1238 codec->probed = 1; 1157 }
1239 list_add(&codec->card_list, &card->codec_dev_list); 1158 }
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 } 1159 }
1279 1160
1280 platform->component.dapm.idle_bias_off = 1; 1161 if (component->probe) {
1281 1162 ret = component->probe(component);
1282 if (driver->probe) {
1283 ret = driver->probe(platform);
1284 if (ret < 0) { 1163 if (ret < 0) {
1285 dev_err(platform->dev, 1164 dev_err(component->dev,
1286 "ASoC: failed to probe platform %d\n", ret); 1165 "ASoC: failed to probe component %d\n", ret);
1287 goto err_probe; 1166 goto err_probe;
1288 } 1167 }
1168
1169 WARN(dapm->idle_bias_off &&
1170 dapm->bias_level != SND_SOC_BIAS_OFF,
1171 "codec %s can not start from non-off bias with idle_bias_off==1\n",
1172 component->name);
1289 } 1173 }
1290 1174
1291 if (driver->controls) 1175 if (component->controls)
1292 snd_soc_add_platform_controls(platform, driver->controls, 1176 snd_soc_add_component_controls(component, component->controls,
1293 driver->num_controls); 1177 component->num_controls);
1294 if (driver->dapm_routes) 1178 if (component->dapm_routes)
1295 snd_soc_dapm_add_routes(&platform->component.dapm, 1179 snd_soc_dapm_add_routes(dapm, component->dapm_routes,
1296 driver->dapm_routes, driver->num_dapm_routes); 1180 component->num_dapm_routes);
1297 1181
1298 /* mark platform as probed and add to card platform list */ 1182 component->probed = 1;
1299 platform->probed = 1; 1183 list_add(&dapm->list, &card->dapm_list);
1300 list_add(&platform->component.dapm.list, &card->dapm_list); 1184
1185 /* This is a HACK and will be removed soon */
1186 if (component->codec)
1187 list_add(&component->codec->card_list, &card->codec_dev_list);
1301 1188
1302 return 0; 1189 return 0;
1303 1190
1304err_probe: 1191err_probe:
1305 soc_cleanup_platform_debugfs(platform); 1192 soc_cleanup_component_debugfs(component);
1306 module_put(platform->dev->driver->owner); 1193 module_put(component->dev->driver->owner);
1307 1194
1308 return ret; 1195 return ret;
1309} 1196}
@@ -1342,17 +1229,21 @@ static int soc_post_component_init(struct snd_soc_pcm_runtime *rtd,
1342 } 1229 }
1343 rtd->dev_registered = 1; 1230 rtd->dev_registered = 1;
1344 1231
1345 /* add DAPM sysfs entries for this codec */ 1232 if (rtd->codec) {
1346 ret = snd_soc_dapm_sys_add(rtd->dev); 1233 /* add DAPM sysfs entries for this codec */
1347 if (ret < 0) 1234 ret = snd_soc_dapm_sys_add(rtd->dev);
1348 dev_err(rtd->dev, 1235 if (ret < 0)
1349 "ASoC: failed to add codec dapm sysfs entries: %d\n", ret); 1236 dev_err(rtd->dev,
1237 "ASoC: failed to add codec dapm sysfs entries: %d\n",
1238 ret);
1350 1239
1351 /* add codec sysfs entries */ 1240 /* add codec sysfs entries */
1352 ret = device_create_file(rtd->dev, &dev_attr_codec_reg); 1241 ret = device_create_file(rtd->dev, &dev_attr_codec_reg);
1353 if (ret < 0) 1242 if (ret < 0)
1354 dev_err(rtd->dev, 1243 dev_err(rtd->dev,
1355 "ASoC: failed to add codec sysfs files: %d\n", ret); 1244 "ASoC: failed to add codec sysfs files: %d\n",
1245 ret);
1246 }
1356 1247
1357 return 0; 1248 return 0;
1358} 1249}
@@ -1361,33 +1252,31 @@ static int soc_probe_link_components(struct snd_soc_card *card, int num,
1361 int order) 1252 int order)
1362{ 1253{
1363 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 1254 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; 1255 struct snd_soc_platform *platform = rtd->platform;
1256 struct snd_soc_component *component;
1366 int i, ret; 1257 int i, ret;
1367 1258
1368 /* probe the CPU-side component, if it is a CODEC */ 1259 /* probe the CPU-side component, if it is a CODEC */
1369 if (cpu_dai->codec && 1260 component = rtd->cpu_dai->component;
1370 !cpu_dai->codec->probed && 1261 if (component->driver->probe_order == order) {
1371 cpu_dai->codec->driver->probe_order == order) { 1262 ret = soc_probe_component(card, component);
1372 ret = soc_probe_codec(card, cpu_dai->codec);
1373 if (ret < 0) 1263 if (ret < 0)
1374 return ret; 1264 return ret;
1375 } 1265 }
1376 1266
1377 /* probe the CODEC-side components */ 1267 /* probe the CODEC-side components */
1378 for (i = 0; i < rtd->num_codecs; i++) { 1268 for (i = 0; i < rtd->num_codecs; i++) {
1379 if (!rtd->codec_dais[i]->codec->probed && 1269 component = rtd->codec_dais[i]->component;
1380 rtd->codec_dais[i]->codec->driver->probe_order == order) { 1270 if (component->driver->probe_order == order) {
1381 ret = soc_probe_codec(card, rtd->codec_dais[i]->codec); 1271 ret = soc_probe_component(card, component);
1382 if (ret < 0) 1272 if (ret < 0)
1383 return ret; 1273 return ret;
1384 } 1274 }
1385 } 1275 }
1386 1276
1387 /* probe the platform */ 1277 /* probe the platform */
1388 if (!platform->probed && 1278 if (platform->component.driver->probe_order == order) {
1389 platform->driver->probe_order == order) { 1279 ret = soc_probe_component(card, &platform->component);
1390 ret = soc_probe_platform(card, platform);
1391 if (ret < 0) 1280 if (ret < 0)
1392 return ret; 1281 return ret;
1393 } 1282 }
@@ -1482,18 +1371,12 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
1482 /* probe the cpu_dai */ 1371 /* probe the cpu_dai */
1483 if (!cpu_dai->probed && 1372 if (!cpu_dai->probed &&
1484 cpu_dai->driver->probe_order == order) { 1373 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) { 1374 if (cpu_dai->driver->probe) {
1491 ret = cpu_dai->driver->probe(cpu_dai); 1375 ret = cpu_dai->driver->probe(cpu_dai);
1492 if (ret < 0) { 1376 if (ret < 0) {
1493 dev_err(cpu_dai->dev, 1377 dev_err(cpu_dai->dev,
1494 "ASoC: failed to probe CPU DAI %s: %d\n", 1378 "ASoC: failed to probe CPU DAI %s: %d\n",
1495 cpu_dai->name, ret); 1379 cpu_dai->name, ret);
1496 module_put(cpu_dai->dev->driver->owner);
1497 return ret; 1380 return ret;
1498 } 1381 }
1499 } 1382 }
@@ -1654,17 +1537,24 @@ static int soc_bind_aux_dev(struct snd_soc_card *card, int num)
1654{ 1537{
1655 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; 1538 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
1656 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; 1539 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1657 const char *codecname = aux_dev->codec_name; 1540 const char *name = aux_dev->codec_name;
1658 1541
1659 rtd->codec = soc_find_codec(aux_dev->codec_of_node, codecname); 1542 rtd->component = soc_find_component(aux_dev->codec_of_node, name);
1660 if (!rtd->codec) { 1543 if (!rtd->component) {
1661 if (aux_dev->codec_of_node) 1544 if (aux_dev->codec_of_node)
1662 codecname = of_node_full_name(aux_dev->codec_of_node); 1545 name = of_node_full_name(aux_dev->codec_of_node);
1663 1546
1664 dev_err(card->dev, "ASoC: %s not registered\n", codecname); 1547 dev_err(card->dev, "ASoC: %s not registered\n", name);
1665 return -EPROBE_DEFER; 1548 return -EPROBE_DEFER;
1666 } 1549 }
1667 1550
1551 /*
1552 * Some places still reference rtd->codec, so we have to keep that
1553 * initialized if the component is a CODEC. Once all those references
1554 * have been removed, this code can be removed as well.
1555 */
1556 rtd->codec = rtd->component->codec;
1557
1668 return 0; 1558 return 0;
1669} 1559}
1670 1560
@@ -1674,18 +1564,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]; 1564 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1675 int ret; 1565 int ret;
1676 1566
1677 if (rtd->codec->probed) { 1567 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) 1568 if (ret < 0)
1684 return ret; 1569 return ret;
1685 1570
1686 /* do machine specific initialization */ 1571 /* do machine specific initialization */
1687 if (aux_dev->init) { 1572 if (aux_dev->init) {
1688 ret = aux_dev->init(&rtd->codec->dapm); 1573 ret = aux_dev->init(rtd->component);
1689 if (ret < 0) { 1574 if (ret < 0) {
1690 dev_err(card->dev, "ASoC: failed to init %s: %d\n", 1575 dev_err(card->dev, "ASoC: failed to init %s: %d\n",
1691 aux_dev->name, ret); 1576 aux_dev->name, ret);
@@ -1699,7 +1584,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) 1584static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
1700{ 1585{
1701 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; 1586 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
1702 struct snd_soc_codec *codec = rtd->codec; 1587 struct snd_soc_component *component = rtd->component;
1703 1588
1704 /* unregister the rtd device */ 1589 /* unregister the rtd device */
1705 if (rtd->dev_registered) { 1590 if (rtd->dev_registered) {
@@ -1708,8 +1593,8 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
1708 rtd->dev_registered = 0; 1593 rtd->dev_registered = 0;
1709 } 1594 }
1710 1595
1711 if (codec && codec->probed) 1596 if (component && component->probed)
1712 soc_remove_codec(codec); 1597 soc_remove_component(component);
1713} 1598}
1714 1599
1715static int snd_soc_init_codec_cache(struct snd_soc_codec *codec) 1600static int snd_soc_init_codec_cache(struct snd_soc_codec *codec)
@@ -3928,8 +3813,11 @@ EXPORT_SYMBOL_GPL(snd_soc_register_card);
3928 */ 3813 */
3929int snd_soc_unregister_card(struct snd_soc_card *card) 3814int snd_soc_unregister_card(struct snd_soc_card *card)
3930{ 3815{
3931 if (card->instantiated) 3816 if (card->instantiated) {
3817 card->instantiated = false;
3818 snd_soc_dapm_shutdown(card);
3932 soc_cleanup_card_resources(card); 3819 soc_cleanup_card_resources(card);
3820 }
3933 dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card->name); 3821 dev_dbg(card->dev, "ASoC: Unregistered card '%s'\n", card->name);
3934 3822
3935 return 0; 3823 return 0;
@@ -4116,6 +4004,8 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
4116 4004
4117 component->dev = dev; 4005 component->dev = dev;
4118 component->driver = driver; 4006 component->driver = driver;
4007 component->probe = component->driver->probe;
4008 component->remove = component->driver->remove;
4119 4009
4120 if (!component->dapm_ptr) 4010 if (!component->dapm_ptr)
4121 component->dapm_ptr = &component->dapm; 4011 component->dapm_ptr = &component->dapm;
@@ -4124,19 +4014,42 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
4124 dapm->dev = dev; 4014 dapm->dev = dev;
4125 dapm->component = component; 4015 dapm->component = component;
4126 dapm->bias_level = SND_SOC_BIAS_OFF; 4016 dapm->bias_level = SND_SOC_BIAS_OFF;
4017 dapm->idle_bias_off = true;
4127 if (driver->seq_notifier) 4018 if (driver->seq_notifier)
4128 dapm->seq_notifier = snd_soc_component_seq_notifier; 4019 dapm->seq_notifier = snd_soc_component_seq_notifier;
4129 if (driver->stream_event) 4020 if (driver->stream_event)
4130 dapm->stream_event = snd_soc_component_stream_event; 4021 dapm->stream_event = snd_soc_component_stream_event;
4131 4022
4023 component->controls = driver->controls;
4024 component->num_controls = driver->num_controls;
4025 component->dapm_widgets = driver->dapm_widgets;
4026 component->num_dapm_widgets = driver->num_dapm_widgets;
4027 component->dapm_routes = driver->dapm_routes;
4028 component->num_dapm_routes = driver->num_dapm_routes;
4029
4132 INIT_LIST_HEAD(&component->dai_list); 4030 INIT_LIST_HEAD(&component->dai_list);
4133 mutex_init(&component->io_mutex); 4031 mutex_init(&component->io_mutex);
4134 4032
4135 return 0; 4033 return 0;
4136} 4034}
4137 4035
4036static void snd_soc_component_init_regmap(struct snd_soc_component *component)
4037{
4038 if (!component->regmap)
4039 component->regmap = dev_get_regmap(component->dev, NULL);
4040 if (component->regmap) {
4041 int val_bytes = regmap_get_val_bytes(component->regmap);
4042 /* Errors are legitimate for non-integer byte multiples */
4043 if (val_bytes > 0)
4044 component->val_bytes = val_bytes;
4045 }
4046}
4047
4138static void snd_soc_component_add_unlocked(struct snd_soc_component *component) 4048static void snd_soc_component_add_unlocked(struct snd_soc_component *component)
4139{ 4049{
4050 if (!component->write && !component->read)
4051 snd_soc_component_init_regmap(component);
4052
4140 list_add(&component->list, &component_list); 4053 list_add(&component->list, &component_list);
4141} 4054}
4142 4055
@@ -4225,22 +4138,18 @@ found:
4225} 4138}
4226EXPORT_SYMBOL_GPL(snd_soc_unregister_component); 4139EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
4227 4140
4228static int snd_soc_platform_drv_write(struct snd_soc_component *component, 4141static int snd_soc_platform_drv_probe(struct snd_soc_component *component)
4229 unsigned int reg, unsigned int val)
4230{ 4142{
4231 struct snd_soc_platform *platform = snd_soc_component_to_platform(component); 4143 struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
4232 4144
4233 return platform->driver->write(platform, reg, val); 4145 return platform->driver->probe(platform);
4234} 4146}
4235 4147
4236static int snd_soc_platform_drv_read(struct snd_soc_component *component, 4148static void snd_soc_platform_drv_remove(struct snd_soc_component *component)
4237 unsigned int reg, unsigned int *val)
4238{ 4149{
4239 struct snd_soc_platform *platform = snd_soc_component_to_platform(component); 4150 struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
4240 4151
4241 *val = platform->driver->read(platform, reg); 4152 platform->driver->remove(platform);
4242
4243 return 0;
4244} 4153}
4245 4154
4246/** 4155/**
@@ -4261,10 +4170,28 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
4261 4170
4262 platform->dev = dev; 4171 platform->dev = dev;
4263 platform->driver = platform_drv; 4172 platform->driver = platform_drv;
4264 if (platform_drv->write) 4173 if (platform_drv->controls) {
4265 platform->component.write = snd_soc_platform_drv_write; 4174 platform->component.controls = platform_drv->controls;
4266 if (platform_drv->read) 4175 platform->component.num_controls = platform_drv->num_controls;
4267 platform->component.read = snd_soc_platform_drv_read; 4176 }
4177 if (platform_drv->dapm_widgets) {
4178 platform->component.dapm_widgets = platform_drv->dapm_widgets;
4179 platform->component.num_dapm_widgets = platform_drv->num_dapm_widgets;
4180 platform->component.steal_sibling_dai_widgets = true;
4181 }
4182 if (platform_drv->dapm_routes) {
4183 platform->component.dapm_routes = platform_drv->dapm_routes;
4184 platform->component.num_dapm_routes = platform_drv->num_dapm_routes;
4185 }
4186
4187 if (platform_drv->probe)
4188 platform->component.probe = snd_soc_platform_drv_probe;
4189 if (platform_drv->remove)
4190 platform->component.remove = snd_soc_platform_drv_remove;
4191
4192#ifdef CONFIG_DEBUG_FS
4193 platform->component.debugfs_prefix = "platform";
4194#endif
4268 4195
4269 mutex_lock(&client_mutex); 4196 mutex_lock(&client_mutex);
4270 snd_soc_component_add_unlocked(&platform->component); 4197 snd_soc_component_add_unlocked(&platform->component);
@@ -4386,6 +4313,20 @@ static void fixup_codec_formats(struct snd_soc_pcm_stream *stream)
4386 stream->formats |= codec_format_map[i]; 4313 stream->formats |= codec_format_map[i];
4387} 4314}
4388 4315
4316static int snd_soc_codec_drv_probe(struct snd_soc_component *component)
4317{
4318 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
4319
4320 return codec->driver->probe(codec);
4321}
4322
4323static void snd_soc_codec_drv_remove(struct snd_soc_component *component)
4324{
4325 struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
4326
4327 codec->driver->remove(codec);
4328}
4329
4389static int snd_soc_codec_drv_write(struct snd_soc_component *component, 4330static int snd_soc_codec_drv_write(struct snd_soc_component *component,
4390 unsigned int reg, unsigned int val) 4331 unsigned int reg, unsigned int val)
4391{ 4332{
@@ -4424,7 +4365,6 @@ int snd_soc_register_codec(struct device *dev,
4424{ 4365{
4425 struct snd_soc_codec *codec; 4366 struct snd_soc_codec *codec;
4426 struct snd_soc_dai *dai; 4367 struct snd_soc_dai *dai;
4427 struct regmap *regmap;
4428 int ret, i; 4368 int ret, i;
4429 4369
4430 dev_dbg(dev, "codec register %s\n", dev_name(dev)); 4370 dev_dbg(dev, "codec register %s\n", dev_name(dev));
@@ -4434,18 +4374,38 @@ int snd_soc_register_codec(struct device *dev,
4434 return -ENOMEM; 4374 return -ENOMEM;
4435 4375
4436 codec->component.dapm_ptr = &codec->dapm; 4376 codec->component.dapm_ptr = &codec->dapm;
4377 codec->component.codec = codec;
4437 4378
4438 ret = snd_soc_component_initialize(&codec->component, 4379 ret = snd_soc_component_initialize(&codec->component,
4439 &codec_drv->component_driver, dev); 4380 &codec_drv->component_driver, dev);
4440 if (ret) 4381 if (ret)
4441 goto err_free; 4382 goto err_free;
4442 4383
4384 if (codec_drv->controls) {
4385 codec->component.controls = codec_drv->controls;
4386 codec->component.num_controls = codec_drv->num_controls;
4387 }
4388 if (codec_drv->dapm_widgets) {
4389 codec->component.dapm_widgets = codec_drv->dapm_widgets;
4390 codec->component.num_dapm_widgets = codec_drv->num_dapm_widgets;
4391 }
4392 if (codec_drv->dapm_routes) {
4393 codec->component.dapm_routes = codec_drv->dapm_routes;
4394 codec->component.num_dapm_routes = codec_drv->num_dapm_routes;
4395 }
4396
4397 if (codec_drv->probe)
4398 codec->component.probe = snd_soc_codec_drv_probe;
4399 if (codec_drv->remove)
4400 codec->component.remove = snd_soc_codec_drv_remove;
4443 if (codec_drv->write) 4401 if (codec_drv->write)
4444 codec->component.write = snd_soc_codec_drv_write; 4402 codec->component.write = snd_soc_codec_drv_write;
4445 if (codec_drv->read) 4403 if (codec_drv->read)
4446 codec->component.read = snd_soc_codec_drv_read; 4404 codec->component.read = snd_soc_codec_drv_read;
4447 codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time; 4405 codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time;
4448 codec->dapm.codec = codec; 4406 codec->dapm.codec = codec;
4407 codec->dapm.idle_bias_off = codec_drv->idle_bias_off;
4408 codec->dapm.suspend_bias_off = codec_drv->suspend_bias_off;
4449 if (codec_drv->seq_notifier) 4409 if (codec_drv->seq_notifier)
4450 codec->dapm.seq_notifier = codec_drv->seq_notifier; 4410 codec->dapm.seq_notifier = codec_drv->seq_notifier;
4451 if (codec_drv->set_bias_level) 4411 if (codec_drv->set_bias_level)
@@ -4455,23 +4415,13 @@ int snd_soc_register_codec(struct device *dev,
4455 codec->component.val_bytes = codec_drv->reg_word_size; 4415 codec->component.val_bytes = codec_drv->reg_word_size;
4456 mutex_init(&codec->mutex); 4416 mutex_init(&codec->mutex);
4457 4417
4458 if (!codec->component.write) { 4418#ifdef CONFIG_DEBUG_FS
4459 if (codec_drv->get_regmap) 4419 codec->component.init_debugfs = soc_init_codec_debugfs;
4460 regmap = codec_drv->get_regmap(dev); 4420 codec->component.debugfs_prefix = "codec";
4461 else 4421#endif
4462 regmap = dev_get_regmap(dev, NULL); 4422
4463 4423 if (codec_drv->get_regmap)
4464 if (regmap) { 4424 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 4425
4476 for (i = 0; i < num_dai; i++) { 4426 for (i = 0; i < num_dai; i++) {
4477 fixup_codec_formats(&dai_drv[i].playback); 4427 fixup_codec_formats(&dai_drv[i].playback);
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 8348352dc2c6..a2025a6b6a29 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1683,6 +1683,22 @@ static void dapm_power_one_widget(struct snd_soc_dapm_widget *w,
1683 } 1683 }
1684} 1684}
1685 1685
1686static bool dapm_idle_bias_off(struct snd_soc_dapm_context *dapm)
1687{
1688 if (dapm->idle_bias_off)
1689 return true;
1690
1691 switch (snd_power_get_state(dapm->card->snd_card)) {
1692 case SNDRV_CTL_POWER_D3hot:
1693 case SNDRV_CTL_POWER_D3cold:
1694 return dapm->suspend_bias_off;
1695 default:
1696 break;
1697 }
1698
1699 return false;
1700}
1701
1686/* 1702/*
1687 * Scan each dapm widget for complete audio path. 1703 * Scan each dapm widget for complete audio path.
1688 * A complete path is a route that has valid endpoints i.e.:- 1704 * A complete path is a route that has valid endpoints i.e.:-
@@ -1706,7 +1722,7 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event)
1706 trace_snd_soc_dapm_start(card); 1722 trace_snd_soc_dapm_start(card);
1707 1723
1708 list_for_each_entry(d, &card->dapm_list, list) { 1724 list_for_each_entry(d, &card->dapm_list, list) {
1709 if (d->idle_bias_off) 1725 if (dapm_idle_bias_off(d))
1710 d->target_bias_level = SND_SOC_BIAS_OFF; 1726 d->target_bias_level = SND_SOC_BIAS_OFF;
1711 else 1727 else
1712 d->target_bias_level = SND_SOC_BIAS_STANDBY; 1728 d->target_bias_level = SND_SOC_BIAS_STANDBY;
@@ -1772,7 +1788,7 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event)
1772 if (d->target_bias_level > bias) 1788 if (d->target_bias_level > bias)
1773 bias = d->target_bias_level; 1789 bias = d->target_bias_level;
1774 list_for_each_entry(d, &card->dapm_list, list) 1790 list_for_each_entry(d, &card->dapm_list, list)
1775 if (!d->idle_bias_off) 1791 if (!dapm_idle_bias_off(d))
1776 d->target_bias_level = bias; 1792 d->target_bias_level = bias;
1777 1793
1778 trace_snd_soc_dapm_walk_done(card); 1794 trace_snd_soc_dapm_walk_done(card);
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);