aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-01-19 17:49:43 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-01-21 07:04:08 -0500
commita96ca3387382498ec8b501db5acef3ed9eb1bd36 (patch)
tree3bc8d76f8796b0e555585802576fc2fed574587a
parentb91b8fa02482a5a18f598ee5d2cd42970051731b (diff)
ASoC: Support turning off bias when the CODEC is idle
Currently ASoC always maintains the bias of the CODEC while the system is active. With older mobile CODECs this is required since the outputs are referenced to a non-zero voltage and enabling or disabling this voltage without audible pops or clicks in the output takes too long to do when starting or stopping audio. As a result of features such as ground referenced outputs and class D speaker drivers current generation devices are able to power on and off much more quickly without these system level issues so provide a new flag idle_bias_off in snd_soc_codec which will cause the core to turn off the CODEC bias. The distinction between STANDBY and OFF is still maintained. This is partly for consistency but also allows for potential future extensions such as per-machine overrides or deferring the bias removal. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
-rw-r--r--include/sound/soc.h2
-rw-r--r--sound/soc/soc-dapm.c25
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,