Commit 715920d0 authored by Lars-Peter Clausen's avatar Lars-Peter Clausen Committed by Mark Brown

ASoC: codecs: wm8955: Fix register cache incoherency

The multi-component patch(commit f0fba2ad) moved the allocation of the
register cache from the driver to the ASoC core. Most drivers where adjusted to
this, but the wm8955 driver still uses its own register cache for its
private functions, while functions from the ASoC core use the generic cache.
Thus we end up with two from each other incoherent caches, which can lead to
undefined behaviour.
This patch fixes the issue by changing the wm8955 driver to use the
generic register cache in its private functions.
Signed-off-by: default avatarLars-Peter Clausen <lars@metafoo.de>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
Cc: stable@kernel.org (for 2.6.37 only)
parent f578a188
...@@ -42,8 +42,6 @@ static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = { ...@@ -42,8 +42,6 @@ static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = {
struct wm8955_priv { struct wm8955_priv {
enum snd_soc_control_type control_type; enum snd_soc_control_type control_type;
u16 reg_cache[WM8955_MAX_REGISTER + 1];
unsigned int mclk_rate; unsigned int mclk_rate;
int deemph; int deemph;
...@@ -768,6 +766,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec, ...@@ -768,6 +766,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level) enum snd_soc_bias_level level)
{ {
struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
u16 *reg_cache = codec->reg_cache;
int ret, i; int ret, i;
switch (level) { switch (level) {
...@@ -800,14 +799,14 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec, ...@@ -800,14 +799,14 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
/* Sync back cached values if they're /* Sync back cached values if they're
* different from the hardware default. * different from the hardware default.
*/ */
for (i = 0; i < ARRAY_SIZE(wm8955->reg_cache); i++) { for (i = 0; i < codec->driver->reg_cache_size; i++) {
if (i == WM8955_RESET) if (i == WM8955_RESET)
continue; continue;
if (wm8955->reg_cache[i] == wm8955_reg[i]) if (reg_cache[i] == wm8955_reg[i])
continue; continue;
snd_soc_write(codec, i, wm8955->reg_cache[i]); snd_soc_write(codec, i, reg_cache[i]);
} }
/* Enable VREF and VMID */ /* Enable VREF and VMID */
...@@ -902,6 +901,7 @@ static int wm8955_probe(struct snd_soc_codec *codec) ...@@ -902,6 +901,7 @@ static int wm8955_probe(struct snd_soc_codec *codec)
{ {
struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec);
struct wm8955_pdata *pdata = dev_get_platdata(codec->dev); struct wm8955_pdata *pdata = dev_get_platdata(codec->dev);
u16 *reg_cache = codec->reg_cache;
int ret, i; int ret, i;
ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8955->control_type); ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8955->control_type);
...@@ -934,25 +934,25 @@ static int wm8955_probe(struct snd_soc_codec *codec) ...@@ -934,25 +934,25 @@ static int wm8955_probe(struct snd_soc_codec *codec)
} }
/* Change some default settings - latch VU and enable ZC */ /* Change some default settings - latch VU and enable ZC */
wm8955->reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU; reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU;
wm8955->reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU; reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU;
wm8955->reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC; reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC;
wm8955->reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC; reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC;
wm8955->reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC; reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC;
wm8955->reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC; reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC;
wm8955->reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC; reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC;
/* Also enable adaptive bass boost by default */ /* Also enable adaptive bass boost by default */
wm8955->reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB; reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB;
/* Set platform data values */ /* Set platform data values */
if (pdata) { if (pdata) {
if (pdata->out2_speaker) if (pdata->out2_speaker)
wm8955->reg_cache[WM8955_ADDITIONAL_CONTROL_2] reg_cache[WM8955_ADDITIONAL_CONTROL_2]
|= WM8955_ROUT2INV; |= WM8955_ROUT2INV;
if (pdata->monoin_diff) if (pdata->monoin_diff)
wm8955->reg_cache[WM8955_MONO_OUT_MIX_1] reg_cache[WM8955_MONO_OUT_MIX_1]
|= WM8955_DMEN; |= WM8955_DMEN;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment