diff options
Diffstat (limited to 'extras/recipes-kernel/linux/linux-omap/linus/0023-ASoC-codecs-wm8962-Fix-register-cache-incoherency.patch')
-rw-r--r-- | extras/recipes-kernel/linux/linux-omap/linus/0023-ASoC-codecs-wm8962-Fix-register-cache-incoherency.patch | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/extras/recipes-kernel/linux/linux-omap/linus/0023-ASoC-codecs-wm8962-Fix-register-cache-incoherency.patch b/extras/recipes-kernel/linux/linux-omap/linus/0023-ASoC-codecs-wm8962-Fix-register-cache-incoherency.patch new file mode 100644 index 00000000..3e7aa10c --- /dev/null +++ b/extras/recipes-kernel/linux/linux-omap/linus/0023-ASoC-codecs-wm8962-Fix-register-cache-incoherency.patch @@ -0,0 +1,151 @@ +From 9760063610bb4890c0f88c1dd839ec1531706f33 Mon Sep 17 00:00:00 2001 +From: Lars-Peter Clausen <lars@metafoo.de> +Date: Tue, 28 Dec 2010 21:38:01 +0100 +Subject: [PATCH 23/65] ASoC: codecs: wm8962: Fix register cache incoherency + +The multi-component patch(commit f0fba2ad1) moved the allocation of the +register cache from the driver to the ASoC core. Most drivers where adjusted to +this, but the wm8962 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 wm8962 driver to use the +generic register cache in its private functions. + +Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> +Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> +Cc: stable@kernel.org (for 2.6.37 only) +--- + sound/soc/codecs/wm8962.c | 45 ++++++++++++++++++++------------------------- + 1 files changed, 20 insertions(+), 25 deletions(-) + +diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c +index 1304ca9..7c421cc 100644 +--- a/sound/soc/codecs/wm8962.c ++++ b/sound/soc/codecs/wm8962.c +@@ -52,8 +52,6 @@ static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = { + struct wm8962_priv { + struct snd_soc_codec *codec; + +- u16 reg_cache[WM8962_MAX_REGISTER + 1]; +- + int sysclk; + int sysclk_rate; + +@@ -1991,8 +1989,7 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) + { + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); +- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); +- u16 *reg_cache = wm8962->reg_cache; ++ u16 *reg_cache = codec->reg_cache; + int ret; + + /* Apply the update (if any) */ +@@ -2020,8 +2017,7 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) + { + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); +- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); +- u16 *reg_cache = wm8962->reg_cache; ++ u16 *reg_cache = codec->reg_cache; + int ret; + + /* Apply the update (if any) */ +@@ -2329,8 +2325,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) + { + struct snd_soc_codec *codec = w->codec; +- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); +- u16 *reg_cache = wm8962->reg_cache; ++ u16 *reg_cache = codec->reg_cache; + int reg; + + switch (w->shift) { +@@ -2719,7 +2714,7 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec) + + static void wm8962_sync_cache(struct snd_soc_codec *codec) + { +- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); ++ u16 *reg_cache = codec->reg_cache; + int i; + + if (!codec->cache_sync) +@@ -2732,13 +2727,13 @@ static void wm8962_sync_cache(struct snd_soc_codec *codec) + /* Sync back cached values if they're different from the + * hardware default. + */ +- for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) { ++ for (i = 1; i < codec->driver->reg_cache_size; i++) { + if (i == WM8962_SOFTWARE_RESET) + continue; +- if (wm8962->reg_cache[i] == wm8962_reg[i]) ++ if (reg_cache[i] == wm8962_reg[i]) + continue; + +- snd_soc_write(codec, i, wm8962->reg_cache[i]); ++ snd_soc_write(codec, i, reg_cache[i]); + } + + codec->cache_sync = 0; +@@ -3406,12 +3401,11 @@ EXPORT_SYMBOL_GPL(wm8962_mic_detect); + #ifdef CONFIG_PM + static int wm8962_resume(struct snd_soc_codec *codec) + { +- struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); + u16 *reg_cache = codec->reg_cache; + int i; + + /* Restore the registers */ +- for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) { ++ for (i = 1; i < codec->driver->reg_cache_size; i++) { + switch (i) { + case WM8962_SOFTWARE_RESET: + continue; +@@ -3705,6 +3699,7 @@ static int wm8962_probe(struct snd_soc_codec *codec) + struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); + struct i2c_client *i2c = container_of(codec->dev, struct i2c_client, + dev); ++ u16 *reg_cache = codec->reg_cache; + int i, trigger, irq_pol; + + wm8962->codec = codec; +@@ -3804,7 +3799,7 @@ static int wm8962_probe(struct snd_soc_codec *codec) + + /* Put the speakers into mono mode? */ + if (pdata->spk_mono) +- wm8962->reg_cache[WM8962_CLASS_D_CONTROL_2] ++ reg_cache[WM8962_CLASS_D_CONTROL_2] + |= WM8962_SPK_MONO; + + /* Micbias setup, detection enable and detection +@@ -3819,16 +3814,16 @@ static int wm8962_probe(struct snd_soc_codec *codec) + } + + /* Latch volume update bits */ +- wm8962->reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU; +- wm8962->reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU; +- wm8962->reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU; +- wm8962->reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU; +- wm8962->reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU; +- wm8962->reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU; +- wm8962->reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU; +- wm8962->reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU; +- wm8962->reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU; +- wm8962->reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU; ++ reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU; ++ reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU; ++ reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU; ++ reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU; ++ reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU; ++ reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU; ++ reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU; ++ reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU; ++ reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU; ++ reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU; + + wm8962_add_widgets(codec); + +-- +1.6.6.1 + |