diff options
-rw-r--r-- | include/sound/soc.h | 2 | ||||
-rw-r--r-- | sound/soc/soc-dapm.c | 25 |
2 files changed, 26 insertions, 1 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h index 08909ccd235b..a8768ea7571a 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -405,6 +405,8 @@ struct snd_soc_codec { | |||
405 | short reg_cache_size; | 405 | short reg_cache_size; |
406 | short reg_cache_step; | 406 | short reg_cache_step; |
407 | 407 | ||
408 | unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */ | ||
409 | |||
408 | /* dapm */ | 410 | /* dapm */ |
409 | u32 pop_time; | 411 | u32 pop_time; |
410 | struct list_head dapm_widgets; | 412 | struct list_head dapm_widgets; |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index d8e93749321e..6c3351095786 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -1012,13 +1012,28 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | |||
1012 | sys_power = 0; | 1012 | sys_power = 0; |
1013 | break; | 1013 | break; |
1014 | case SND_SOC_DAPM_STREAM_NOP: | 1014 | case SND_SOC_DAPM_STREAM_NOP: |
1015 | sys_power = codec->bias_level != SND_SOC_BIAS_STANDBY; | 1015 | switch (codec->bias_level) { |
1016 | case SND_SOC_BIAS_STANDBY: | ||
1017 | case SND_SOC_BIAS_OFF: | ||
1018 | sys_power = 0; | ||
1019 | break; | ||
1020 | default: | ||
1021 | sys_power = 1; | ||
1022 | break; | ||
1023 | } | ||
1016 | break; | 1024 | break; |
1017 | default: | 1025 | default: |
1018 | break; | 1026 | break; |
1019 | } | 1027 | } |
1020 | } | 1028 | } |
1021 | 1029 | ||
1030 | if (sys_power && codec->bias_level == SND_SOC_BIAS_OFF) { | ||
1031 | ret = snd_soc_dapm_set_bias_level(socdev, | ||
1032 | SND_SOC_BIAS_STANDBY); | ||
1033 | if (ret != 0) | ||
1034 | pr_err("Failed to turn on bias: %d\n", ret); | ||
1035 | } | ||
1036 | |||
1022 | /* If we're changing to all on or all off then prepare */ | 1037 | /* If we're changing to all on or all off then prepare */ |
1023 | if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) || | 1038 | if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) || |
1024 | (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) { | 1039 | (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) { |
@@ -1042,6 +1057,14 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | |||
1042 | pr_err("Failed to apply standby bias: %d\n", ret); | 1057 | pr_err("Failed to apply standby bias: %d\n", ret); |
1043 | } | 1058 | } |
1044 | 1059 | ||
1060 | /* If we're in standby and can support bias off then do that */ | ||
1061 | if (codec->bias_level == SND_SOC_BIAS_STANDBY && | ||
1062 | codec->idle_bias_off) { | ||
1063 | ret = snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_OFF); | ||
1064 | if (ret != 0) | ||
1065 | pr_err("Failed to turn off bias: %d\n", ret); | ||
1066 | } | ||
1067 | |||
1045 | /* If we just powered up then move to active bias */ | 1068 | /* If we just powered up then move to active bias */ |
1046 | if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { | 1069 | if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { |
1047 | ret = snd_soc_dapm_set_bias_level(socdev, | 1070 | ret = snd_soc_dapm_set_bias_level(socdev, |