aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-dapm.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2011-06-04 06:25:10 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-06-06 16:45:44 -0400
commit56fba41f8f6444f9e2db3bfe2c4cc5c5bac43d1d (patch)
treeac4e74a24720567d7babb1abbe1b92cc201b9f00 /sound/soc/soc-dapm.c
parent6dffdea70029f2e74c029eba3c24d07641fa4a77 (diff)
ASoC: Specify target bias state directly as a bias state
Rather than a simple flag to say if we want the DAPM context to be at full power specify the target bias state. This should have no current effect but is a bit more direct and so makes it easier to change our decisions about the which bias state to go into in future. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Acked-by: Liam Girdwood <lrg@ti.com>
Diffstat (limited to 'sound/soc/soc-dapm.c')
-rw-r--r--sound/soc/soc-dapm.c60
1 files changed, 33 insertions, 27 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 776e6f418306..0bbded43e213 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -1042,16 +1042,17 @@ static void dapm_pre_sequence_async(void *data, async_cookie_t cookie)
1042 struct snd_soc_dapm_context *d = data; 1042 struct snd_soc_dapm_context *d = data;
1043 int ret; 1043 int ret;
1044 1044
1045 if (d->dev_power && d->bias_level == SND_SOC_BIAS_OFF) { 1045 /* If we're off and we're not supposed to be go into STANDBY */
1046 if (d->bias_level == SND_SOC_BIAS_OFF &&
1047 d->target_bias_level != SND_SOC_BIAS_OFF) {
1046 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY); 1048 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
1047 if (ret != 0) 1049 if (ret != 0)
1048 dev_err(d->dev, 1050 dev_err(d->dev,
1049 "Failed to turn on bias: %d\n", ret); 1051 "Failed to turn on bias: %d\n", ret);
1050 } 1052 }
1051 1053
1052 /* If we're changing to all on or all off then prepare */ 1054 /* Prepare for a STADDBY->ON or ON->STANDBY transition */
1053 if ((d->dev_power && d->bias_level == SND_SOC_BIAS_STANDBY) || 1055 if (d->bias_level != d->target_bias_level) {
1054 (!d->dev_power && d->bias_level == SND_SOC_BIAS_ON)) {
1055 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE); 1056 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_PREPARE);
1056 if (ret != 0) 1057 if (ret != 0)
1057 dev_err(d->dev, 1058 dev_err(d->dev,
@@ -1068,7 +1069,9 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie)
1068 int ret; 1069 int ret;
1069 1070
1070 /* If we just powered the last thing off drop to standby bias */ 1071 /* If we just powered the last thing off drop to standby bias */
1071 if (d->bias_level == SND_SOC_BIAS_PREPARE && !d->dev_power) { 1072 if (d->bias_level == SND_SOC_BIAS_PREPARE &&
1073 (d->target_bias_level == SND_SOC_BIAS_STANDBY ||
1074 d->target_bias_level == SND_SOC_BIAS_OFF)) {
1072 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY); 1075 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_STANDBY);
1073 if (ret != 0) 1076 if (ret != 0)
1074 dev_err(d->dev, "Failed to apply standby bias: %d\n", 1077 dev_err(d->dev, "Failed to apply standby bias: %d\n",
@@ -1076,14 +1079,16 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie)
1076 } 1079 }
1077 1080
1078 /* If we're in standby and can support bias off then do that */ 1081 /* If we're in standby and can support bias off then do that */
1079 if (d->bias_level == SND_SOC_BIAS_STANDBY && d->idle_bias_off) { 1082 if (d->bias_level == SND_SOC_BIAS_STANDBY &&
1083 d->target_bias_level == SND_SOC_BIAS_OFF) {
1080 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF); 1084 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_OFF);
1081 if (ret != 0) 1085 if (ret != 0)
1082 dev_err(d->dev, "Failed to turn off bias: %d\n", ret); 1086 dev_err(d->dev, "Failed to turn off bias: %d\n", ret);
1083 } 1087 }
1084 1088
1085 /* If we just powered up then move to active bias */ 1089 /* If we just powered up then move to active bias */
1086 if (d->bias_level == SND_SOC_BIAS_PREPARE && d->dev_power) { 1090 if (d->bias_level == SND_SOC_BIAS_PREPARE &&
1091 d->target_bias_level == SND_SOC_BIAS_ON) {
1087 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_ON); 1092 ret = snd_soc_dapm_set_bias_level(d, SND_SOC_BIAS_ON);
1088 if (ret != 0) 1093 if (ret != 0)
1089 dev_err(d->dev, "Failed to apply active bias: %d\n", 1094 dev_err(d->dev, "Failed to apply active bias: %d\n",
@@ -1108,13 +1113,19 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1108 LIST_HEAD(up_list); 1113 LIST_HEAD(up_list);
1109 LIST_HEAD(down_list); 1114 LIST_HEAD(down_list);
1110 LIST_HEAD(async_domain); 1115 LIST_HEAD(async_domain);
1116 enum snd_soc_bias_level bias;
1111 int power; 1117 int power;
1112 1118
1113 trace_snd_soc_dapm_start(card); 1119 trace_snd_soc_dapm_start(card);
1114 1120
1115 list_for_each_entry(d, &card->dapm_list, list) 1121 list_for_each_entry(d, &card->dapm_list, list) {
1116 if (d->n_widgets || d->codec == NULL) 1122 if (d->n_widgets || d->codec == NULL) {
1117 d->dev_power = 0; 1123 if (d->idle_bias_off)
1124 d->target_bias_level = SND_SOC_BIAS_OFF;
1125 else
1126 d->target_bias_level = SND_SOC_BIAS_STANDBY;
1127 }
1128 }
1118 1129
1119 /* Check which widgets we need to power and store them in 1130 /* Check which widgets we need to power and store them in
1120 * lists indicating if they should be powered up or down. 1131 * lists indicating if they should be powered up or down.
@@ -1137,7 +1148,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1137 else 1148 else
1138 power = 1; 1149 power = 1;
1139 if (power) 1150 if (power)
1140 w->dapm->dev_power = 1; 1151 w->dapm->target_bias_level = SND_SOC_BIAS_ON;
1141 1152
1142 if (w->power == power) 1153 if (w->power == power)
1143 continue; 1154 continue;
@@ -1161,24 +1172,19 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1161 switch (event) { 1172 switch (event) {
1162 case SND_SOC_DAPM_STREAM_START: 1173 case SND_SOC_DAPM_STREAM_START:
1163 case SND_SOC_DAPM_STREAM_RESUME: 1174 case SND_SOC_DAPM_STREAM_RESUME:
1164 dapm->dev_power = 1; 1175 dapm->target_bias_level = SND_SOC_BIAS_ON;
1165 break; 1176 break;
1166 case SND_SOC_DAPM_STREAM_STOP: 1177 case SND_SOC_DAPM_STREAM_STOP:
1167 dapm->dev_power = !!dapm->codec->active; 1178 if (dapm->codec->active)
1179 dapm->target_bias_level = SND_SOC_BIAS_ON;
1180 else
1181 dapm->target_bias_level = SND_SOC_BIAS_STANDBY;
1168 break; 1182 break;
1169 case SND_SOC_DAPM_STREAM_SUSPEND: 1183 case SND_SOC_DAPM_STREAM_SUSPEND:
1170 dapm->dev_power = 0; 1184 dapm->target_bias_level = SND_SOC_BIAS_STANDBY;
1171 break; 1185 break;
1172 case SND_SOC_DAPM_STREAM_NOP: 1186 case SND_SOC_DAPM_STREAM_NOP:
1173 switch (dapm->bias_level) { 1187 dapm->target_bias_level = dapm->bias_level;
1174 case SND_SOC_BIAS_STANDBY:
1175 case SND_SOC_BIAS_OFF:
1176 dapm->dev_power = 0;
1177 break;
1178 default:
1179 dapm->dev_power = 1;
1180 break;
1181 }
1182 break; 1188 break;
1183 default: 1189 default:
1184 break; 1190 break;
@@ -1186,12 +1192,12 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1186 } 1192 }
1187 1193
1188 /* Force all contexts in the card to the same bias state */ 1194 /* Force all contexts in the card to the same bias state */
1189 power = 0; 1195 bias = SND_SOC_BIAS_OFF;
1190 list_for_each_entry(d, &card->dapm_list, list) 1196 list_for_each_entry(d, &card->dapm_list, list)
1191 if (d->dev_power) 1197 if (d->target_bias_level > bias)
1192 power = 1; 1198 bias = d->target_bias_level;
1193 list_for_each_entry(d, &card->dapm_list, list) 1199 list_for_each_entry(d, &card->dapm_list, list)
1194 d->dev_power = power; 1200 d->target_bias_level = bias;
1195 1201
1196 1202
1197 /* Run all the bias changes in parallel */ 1203 /* Run all the bias changes in parallel */