aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/wm8904.c52
1 files changed, 39 insertions, 13 deletions
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 992a7f23df5..dc782c43a7c 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -2033,11 +2033,37 @@ static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
return 0;
}
+static void wm8904_sync_cache(struct snd_soc_codec *codec)
+{
+ struct wm8904_priv *wm8904 = codec->private_data;
+ int i;
+
+ if (!codec->cache_sync)
+ return;
+
+ codec->cache_only = 0;
+
+ /* Sync back cached values if they're different from the
+ * hardware default.
+ */
+ for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) {
+ if (!wm8904_access[i].writable)
+ continue;
+
+ if (wm8904->reg_cache[i] == wm8904_reg[i])
+ continue;
+
+ snd_soc_write(codec, i, wm8904->reg_cache[i]);
+ }
+
+ codec->cache_sync = 0;
+}
+
static int wm8904_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
struct wm8904_priv *wm8904 = codec->private_data;
- int ret, i;
+ int ret;
switch (level) {
case SND_SOC_BIAS_ON:
@@ -2065,18 +2091,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
return ret;
}
- /* Sync back cached values if they're
- * different from the hardware default.
- */
- for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) {
- if (!wm8904_access[i].writable)
- continue;
-
- if (wm8904->reg_cache[i] == wm8904_reg[i])
- continue;
-
- snd_soc_write(codec, i, wm8904->reg_cache[i]);
- }
+ wm8904_sync_cache(codec);
/* Enable bias */
snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
@@ -2112,6 +2127,15 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
WM8904_BIAS_ENA, 0);
+#ifdef CONFIG_REGULATOR
+ /* Post 2.6.34 we will be able to get a callback when
+ * the regulators are disabled which we can use but
+ * for now just assume that the power will be cut if
+ * the regulator API is in use.
+ */
+ codec->cache_sync = 1;
+#endif
+
regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies),
wm8904->supplies);
break;
@@ -2365,6 +2389,8 @@ static int wm8904_register(struct wm8904_priv *wm8904,
codec->reg_cache_size = WM8904_MAX_REGISTER;
codec->reg_cache = &wm8904->reg_cache;
codec->volatile_register = wm8904_volatile_register;
+ codec->cache_sync = 1;
+ codec->idle_bias_off = 1;
memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg));