diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/soc-core.c | 32 | ||||
-rw-r--r-- | sound/soc/soc-dapm.c | 31 |
2 files changed, 58 insertions, 5 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 95739767ec45..8661e5b4adb1 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -927,8 +927,19 @@ static int soc_suspend(struct device *dev) | |||
927 | SND_SOC_DAPM_STREAM_SUSPEND); | 927 | SND_SOC_DAPM_STREAM_SUSPEND); |
928 | } | 928 | } |
929 | 929 | ||
930 | if (codec_dev->suspend) | 930 | /* If there are paths active then the CODEC will be held with |
931 | codec_dev->suspend(pdev, PMSG_SUSPEND); | 931 | * bias _ON and should not be suspended. */ |
932 | if (codec_dev->suspend) { | ||
933 | switch (codec->bias_level) { | ||
934 | case SND_SOC_BIAS_STANDBY: | ||
935 | case SND_SOC_BIAS_OFF: | ||
936 | codec_dev->suspend(pdev, PMSG_SUSPEND); | ||
937 | break; | ||
938 | default: | ||
939 | dev_dbg(socdev->dev, "CODEC is on over suspend\n"); | ||
940 | break; | ||
941 | } | ||
942 | } | ||
932 | 943 | ||
933 | for (i = 0; i < card->num_links; i++) { | 944 | for (i = 0; i < card->num_links; i++) { |
934 | struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; | 945 | struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; |
@@ -975,8 +986,21 @@ static void soc_resume_deferred(struct work_struct *work) | |||
975 | cpu_dai->resume(cpu_dai); | 986 | cpu_dai->resume(cpu_dai); |
976 | } | 987 | } |
977 | 988 | ||
978 | if (codec_dev->resume) | 989 | /* If the CODEC was idle over suspend then it will have been |
979 | codec_dev->resume(pdev); | 990 | * left with bias OFF or STANDBY and suspended so we must now |
991 | * resume. Otherwise the suspend was suppressed. | ||
992 | */ | ||
993 | if (codec_dev->resume) { | ||
994 | switch (codec->bias_level) { | ||
995 | case SND_SOC_BIAS_STANDBY: | ||
996 | case SND_SOC_BIAS_OFF: | ||
997 | codec_dev->resume(pdev); | ||
998 | break; | ||
999 | default: | ||
1000 | dev_dbg(socdev->dev, "CODEC was on over suspend\n"); | ||
1001 | break; | ||
1002 | } | ||
1003 | } | ||
980 | 1004 | ||
981 | for (i = 0; i < codec->num_dai; i++) { | 1005 | for (i = 0; i < codec->num_dai; i++) { |
982 | char *stream = codec->dai[i].playback.stream_name; | 1006 | char *stream = codec->dai[i].playback.stream_name; |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 8c8b291320a8..fefb6c44fc81 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -441,7 +441,9 @@ static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) | |||
441 | switch (snd_power_get_state(codec->card)) { | 441 | switch (snd_power_get_state(codec->card)) { |
442 | case SNDRV_CTL_POWER_D3hot: | 442 | case SNDRV_CTL_POWER_D3hot: |
443 | case SNDRV_CTL_POWER_D3cold: | 443 | case SNDRV_CTL_POWER_D3cold: |
444 | return 0; | 444 | if (widget->ignore_suspend) |
445 | pr_debug("%s ignoring suspend\n", widget->name); | ||
446 | return widget->ignore_suspend; | ||
445 | default: | 447 | default: |
446 | return 1; | 448 | return 1; |
447 | } | 449 | } |
@@ -2137,6 +2139,33 @@ int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin) | |||
2137 | EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status); | 2139 | EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status); |
2138 | 2140 | ||
2139 | /** | 2141 | /** |
2142 | * snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint | ||
2143 | * @codec: audio codec | ||
2144 | * @pin: audio signal pin endpoint (or start point) | ||
2145 | * | ||
2146 | * Mark the given endpoint or pin as ignoring suspend. When the | ||
2147 | * system is disabled a path between two endpoints flagged as ignoring | ||
2148 | * suspend will not be disabled. The path must already be enabled via | ||
2149 | * normal means at suspend time, it will not be turned on if it was not | ||
2150 | * already enabled. | ||
2151 | */ | ||
2152 | int snd_soc_dapm_ignore_suspend(struct snd_soc_codec *codec, const char *pin) | ||
2153 | { | ||
2154 | struct snd_soc_dapm_widget *w; | ||
2155 | |||
2156 | list_for_each_entry(w, &codec->dapm_widgets, list) { | ||
2157 | if (!strcmp(w->name, pin)) { | ||
2158 | w->ignore_suspend = 1; | ||
2159 | return 0; | ||
2160 | } | ||
2161 | } | ||
2162 | |||
2163 | pr_err("Unknown DAPM pin: %s\n", pin); | ||
2164 | return -EINVAL; | ||
2165 | } | ||
2166 | EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); | ||
2167 | |||
2168 | /** | ||
2140 | * snd_soc_dapm_free - free dapm resources | 2169 | * snd_soc_dapm_free - free dapm resources |
2141 | * @socdev: SoC device | 2170 | * @socdev: SoC device |
2142 | * | 2171 | * |