aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8904.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8904.c')
-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 992a7f23df5c..dc782c43a7cb 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)
2033 return 0; 2033 return 0;
2034} 2034}
2035 2035
2036static void wm8904_sync_cache(struct snd_soc_codec *codec)
2037{
2038 struct wm8904_priv *wm8904 = codec->private_data;
2039 int i;
2040
2041 if (!codec->cache_sync)
2042 return;
2043
2044 codec->cache_only = 0;
2045
2046 /* Sync back cached values if they're different from the
2047 * hardware default.
2048 */
2049 for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) {
2050 if (!wm8904_access[i].writable)
2051 continue;
2052
2053 if (wm8904->reg_cache[i] == wm8904_reg[i])
2054 continue;
2055
2056 snd_soc_write(codec, i, wm8904->reg_cache[i]);
2057 }
2058
2059 codec->cache_sync = 0;
2060}
2061
2036static int wm8904_set_bias_level(struct snd_soc_codec *codec, 2062static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2037 enum snd_soc_bias_level level) 2063 enum snd_soc_bias_level level)
2038{ 2064{
2039 struct wm8904_priv *wm8904 = codec->private_data; 2065 struct wm8904_priv *wm8904 = codec->private_data;
2040 int ret, i; 2066 int ret;
2041 2067
2042 switch (level) { 2068 switch (level) {
2043 case SND_SOC_BIAS_ON: 2069 case SND_SOC_BIAS_ON:
@@ -2065,18 +2091,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2065 return ret; 2091 return ret;
2066 } 2092 }
2067 2093
2068 /* Sync back cached values if they're 2094 wm8904_sync_cache(codec);
2069 * different from the hardware default.
2070 */
2071 for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) {
2072 if (!wm8904_access[i].writable)
2073 continue;
2074
2075 if (wm8904->reg_cache[i] == wm8904_reg[i])
2076 continue;
2077
2078 snd_soc_write(codec, i, wm8904->reg_cache[i]);
2079 }
2080 2095
2081 /* Enable bias */ 2096 /* Enable bias */
2082 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, 2097 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
@@ -2112,6 +2127,15 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2112 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, 2127 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2113 WM8904_BIAS_ENA, 0); 2128 WM8904_BIAS_ENA, 0);
2114 2129
2130#ifdef CONFIG_REGULATOR
2131 /* Post 2.6.34 we will be able to get a callback when
2132 * the regulators are disabled which we can use but
2133 * for now just assume that the power will be cut if
2134 * the regulator API is in use.
2135 */
2136 codec->cache_sync = 1;
2137#endif
2138
2115 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), 2139 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies),
2116 wm8904->supplies); 2140 wm8904->supplies);
2117 break; 2141 break;
@@ -2365,6 +2389,8 @@ static int wm8904_register(struct wm8904_priv *wm8904,
2365 codec->reg_cache_size = WM8904_MAX_REGISTER; 2389 codec->reg_cache_size = WM8904_MAX_REGISTER;
2366 codec->reg_cache = &wm8904->reg_cache; 2390 codec->reg_cache = &wm8904->reg_cache;
2367 codec->volatile_register = wm8904_volatile_register; 2391 codec->volatile_register = wm8904_volatile_register;
2392 codec->cache_sync = 1;
2393 codec->idle_bias_off = 1;
2368 2394
2369 memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg)); 2395 memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg));
2370 2396