aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc-dapm.h1
-rw-r--r--sound/soc/soc-core.c16
-rw-r--r--sound/soc/soc-dapm.c29
3 files changed, 46 insertions, 0 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index ec8a45f9a069..35814ced2d22 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -279,6 +279,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
279/* dapm events */ 279/* dapm events */
280int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream, 280int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream,
281 int event); 281 int event);
282void snd_soc_dapm_shutdown(struct snd_soc_device *socdev);
282 283
283/* dapm sys fs - used by the core */ 284/* dapm sys fs - used by the core */
284int snd_soc_dapm_sys_add(struct device *dev); 285int snd_soc_dapm_sys_add(struct device *dev);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 44141178ff4a..55d45c43ba16 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1020,6 +1020,21 @@ static int soc_remove(struct platform_device *pdev)
1020 return 0; 1020 return 0;
1021} 1021}
1022 1022
1023static void soc_shutdown(struct platform_device *pdev)
1024{
1025 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1026 struct snd_soc_card *card = socdev->card;
1027
1028 if (!card->instantiated)
1029 return;
1030
1031 /* Flush out pmdown_time work - we actually do want to run it
1032 * now, we're shutting down so no imminent restart. */
1033 run_delayed_work(&card->delayed_work);
1034
1035 snd_soc_dapm_shutdown(socdev);
1036}
1037
1023/* ASoC platform driver */ 1038/* ASoC platform driver */
1024static struct platform_driver soc_driver = { 1039static struct platform_driver soc_driver = {
1025 .driver = { 1040 .driver = {
@@ -1030,6 +1045,7 @@ static struct platform_driver soc_driver = {
1030 .remove = soc_remove, 1045 .remove = soc_remove,
1031 .suspend = soc_suspend, 1046 .suspend = soc_suspend,
1032 .resume = soc_resume, 1047 .resume = soc_resume,
1048 .shutdown = soc_shutdown,
1033}; 1049};
1034 1050
1035/* create a new pcm */ 1051/* create a new pcm */
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 653435930ad8..b9129efeedf3 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -2032,6 +2032,35 @@ void snd_soc_dapm_free(struct snd_soc_device *socdev)
2032} 2032}
2033EXPORT_SYMBOL_GPL(snd_soc_dapm_free); 2033EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
2034 2034
2035/*
2036 * snd_soc_dapm_shutdown - callback for system shutdown
2037 */
2038void snd_soc_dapm_shutdown(struct snd_soc_device *socdev)
2039{
2040 struct snd_soc_codec *codec = socdev->card->codec;
2041 struct snd_soc_dapm_widget *w;
2042 LIST_HEAD(down_list);
2043 int powerdown = 0;
2044
2045 list_for_each_entry(w, &codec->dapm_widgets, list) {
2046 if (w->power) {
2047 dapm_seq_insert(w, &down_list, dapm_down_seq);
2048 powerdown = 1;
2049 }
2050 }
2051
2052 /* If there were no widgets to power down we're already in
2053 * standby.
2054 */
2055 if (powerdown) {
2056 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_PREPARE);
2057 dapm_seq_run(codec, &down_list, 0, dapm_down_seq);
2058 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_STANDBY);
2059 }
2060
2061 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_OFF);
2062}
2063
2035/* Module information */ 2064/* Module information */
2036MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk"); 2065MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
2037MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC"); 2066MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC");