diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-02-10 09:01:38 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-02-11 06:13:56 -0500 |
commit | 22f226dd1496a0fa470e64a66e2da474f34eebf8 (patch) | |
tree | 786da18ee0aa1337349575cff7e1f69801f05527 /sound/soc/codecs/wm8903.c | |
parent | 66daaa59d5f0310238de183918e13062428fb59f (diff) |
ASoC: Don't use write sequencer to power up WM8903
The write sequencer sequencer sequence takes longer than is desirable
as it brings up a full playback path which is not required at this
point. Open coding the sequence cuts the startup time by two thirds.
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'sound/soc/codecs/wm8903.c')
-rw-r--r-- | sound/soc/codecs/wm8903.c | 73 |
1 files changed, 54 insertions, 19 deletions
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index b88c6165dd25..e203a3ec655a 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c | |||
@@ -297,15 +297,6 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start) | |||
297 | return 0; | 297 | return 0; |
298 | } | 298 | } |
299 | 299 | ||
300 | static void wm8903_sync_reg_cache(struct snd_soc_codec *codec, u16 *cache) | ||
301 | { | ||
302 | int i; | ||
303 | |||
304 | /* There really ought to be something better we can do here :/ */ | ||
305 | for (i = 0; i < ARRAY_SIZE(wm8903_reg_defaults); i++) | ||
306 | cache[i] = codec->hw_read(codec, i); | ||
307 | } | ||
308 | |||
309 | static void wm8903_reset(struct snd_soc_codec *codec) | 300 | static void wm8903_reset(struct snd_soc_codec *codec) |
310 | { | 301 | { |
311 | snd_soc_write(codec, WM8903_SW_RESET_AND_ID, 0); | 302 | snd_soc_write(codec, WM8903_SW_RESET_AND_ID, 0); |
@@ -1142,6 +1133,7 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec, | |||
1142 | switch (level) { | 1133 | switch (level) { |
1143 | case SND_SOC_BIAS_ON: | 1134 | case SND_SOC_BIAS_ON: |
1144 | break; | 1135 | break; |
1136 | |||
1145 | case SND_SOC_BIAS_PREPARE: | 1137 | case SND_SOC_BIAS_PREPARE: |
1146 | snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, | 1138 | snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, |
1147 | WM8903_VMID_RES_MASK, | 1139 | WM8903_VMID_RES_MASK, |
@@ -1150,16 +1142,59 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec, | |||
1150 | 1142 | ||
1151 | case SND_SOC_BIAS_STANDBY: | 1143 | case SND_SOC_BIAS_STANDBY: |
1152 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 1144 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
1153 | snd_soc_write(codec, WM8903_CLOCK_RATES_2, | 1145 | snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0, |
1154 | WM8903_CLK_SYS_ENA); | 1146 | WM8903_POBCTRL | WM8903_ISEL_MASK | |
1155 | 1147 | WM8903_STARTUP_BIAS_ENA | | |
1156 | /* Change DC servo dither level in startup sequence */ | 1148 | WM8903_BIAS_ENA, |
1157 | snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, 0x11); | 1149 | WM8903_POBCTRL | |
1158 | snd_soc_write(codec, WM8903_WRITE_SEQUENCER_1, 0x1257); | 1150 | (2 << WM8903_ISEL_SHIFT) | |
1159 | snd_soc_write(codec, WM8903_WRITE_SEQUENCER_2, 0x2); | 1151 | WM8903_STARTUP_BIAS_ENA); |
1160 | 1152 | ||
1161 | wm8903_run_sequence(codec, 0); | 1153 | snd_soc_update_bits(codec, |
1162 | wm8903_sync_reg_cache(codec, codec->reg_cache); | 1154 | WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0, |
1155 | WM8903_SPK_DISCHARGE, | ||
1156 | WM8903_SPK_DISCHARGE); | ||
1157 | |||
1158 | msleep(33); | ||
1159 | |||
1160 | snd_soc_update_bits(codec, WM8903_POWER_MANAGEMENT_5, | ||
1161 | WM8903_SPKL_ENA | WM8903_SPKR_ENA, | ||
1162 | WM8903_SPKL_ENA | WM8903_SPKR_ENA); | ||
1163 | |||
1164 | snd_soc_update_bits(codec, | ||
1165 | WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0, | ||
1166 | WM8903_SPK_DISCHARGE, 0); | ||
1167 | |||
1168 | snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, | ||
1169 | WM8903_VMID_TIE_ENA | | ||
1170 | WM8903_BUFIO_ENA | | ||
1171 | WM8903_VMID_IO_ENA | | ||
1172 | WM8903_VMID_SOFT_MASK | | ||
1173 | WM8903_VMID_RES_MASK | | ||
1174 | WM8903_VMID_BUF_ENA, | ||
1175 | WM8903_VMID_TIE_ENA | | ||
1176 | WM8903_BUFIO_ENA | | ||
1177 | WM8903_VMID_IO_ENA | | ||
1178 | (2 << WM8903_VMID_SOFT_SHIFT) | | ||
1179 | WM8903_VMID_RES_250K | | ||
1180 | WM8903_VMID_BUF_ENA); | ||
1181 | |||
1182 | msleep(129); | ||
1183 | |||
1184 | snd_soc_update_bits(codec, WM8903_POWER_MANAGEMENT_5, | ||
1185 | WM8903_SPKL_ENA | WM8903_SPKR_ENA, | ||
1186 | 0); | ||
1187 | |||
1188 | snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, | ||
1189 | WM8903_VMID_SOFT_MASK, 0); | ||
1190 | |||
1191 | snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, | ||
1192 | WM8903_VMID_RES_MASK, | ||
1193 | WM8903_VMID_RES_50K); | ||
1194 | |||
1195 | snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0, | ||
1196 | WM8903_BIAS_ENA | WM8903_POBCTRL, | ||
1197 | WM8903_BIAS_ENA); | ||
1163 | 1198 | ||
1164 | /* By default no bypass paths are enabled so | 1199 | /* By default no bypass paths are enabled so |
1165 | * enable Class W support. | 1200 | * enable Class W support. |