aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2010-12-28 15:38:01 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-12-28 18:20:12 -0500
commit7f87e30ef29951f4509a7f86acf00e1ba48af54a (patch)
tree5237425ee669f6016510897157794a94305fd7e5
parent715920d04c787ed718327da53cf51689e51ef3ce (diff)
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)
-rw-r--r--sound/soc/codecs/wm8962.c45
1 files changed, 20 insertions, 25 deletions
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 1304ca91a11c..7c421cc837bd 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] = {
52struct wm8962_priv { 52struct wm8962_priv {
53 struct snd_soc_codec *codec; 53 struct snd_soc_codec *codec;
54 54
55 u16 reg_cache[WM8962_MAX_REGISTER + 1];
56
57 int sysclk; 55 int sysclk;
58 int sysclk_rate; 56 int sysclk_rate;
59 57
@@ -1991,8 +1989,7 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol,
1991 struct snd_ctl_elem_value *ucontrol) 1989 struct snd_ctl_elem_value *ucontrol)
1992{ 1990{
1993 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1991 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1994 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 1992 u16 *reg_cache = codec->reg_cache;
1995 u16 *reg_cache = wm8962->reg_cache;
1996 int ret; 1993 int ret;
1997 1994
1998 /* Apply the update (if any) */ 1995 /* Apply the update (if any) */
@@ -2020,8 +2017,7 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol,
2020 struct snd_ctl_elem_value *ucontrol) 2017 struct snd_ctl_elem_value *ucontrol)
2021{ 2018{
2022 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2019 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2023 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 2020 u16 *reg_cache = codec->reg_cache;
2024 u16 *reg_cache = wm8962->reg_cache;
2025 int ret; 2021 int ret;
2026 2022
2027 /* Apply the update (if any) */ 2023 /* Apply the update (if any) */
@@ -2329,8 +2325,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w,
2329 struct snd_kcontrol *kcontrol, int event) 2325 struct snd_kcontrol *kcontrol, int event)
2330{ 2326{
2331 struct snd_soc_codec *codec = w->codec; 2327 struct snd_soc_codec *codec = w->codec;
2332 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 2328 u16 *reg_cache = codec->reg_cache;
2333 u16 *reg_cache = wm8962->reg_cache;
2334 int reg; 2329 int reg;
2335 2330
2336 switch (w->shift) { 2331 switch (w->shift) {
@@ -2719,7 +2714,7 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec)
2719 2714
2720static void wm8962_sync_cache(struct snd_soc_codec *codec) 2715static void wm8962_sync_cache(struct snd_soc_codec *codec)
2721{ 2716{
2722 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 2717 u16 *reg_cache = codec->reg_cache;
2723 int i; 2718 int i;
2724 2719
2725 if (!codec->cache_sync) 2720 if (!codec->cache_sync)
@@ -2732,13 +2727,13 @@ static void wm8962_sync_cache(struct snd_soc_codec *codec)
2732 /* Sync back cached values if they're different from the 2727 /* Sync back cached values if they're different from the
2733 * hardware default. 2728 * hardware default.
2734 */ 2729 */
2735 for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) { 2730 for (i = 1; i < codec->driver->reg_cache_size; i++) {
2736 if (i == WM8962_SOFTWARE_RESET) 2731 if (i == WM8962_SOFTWARE_RESET)
2737 continue; 2732 continue;
2738 if (wm8962->reg_cache[i] == wm8962_reg[i]) 2733 if (reg_cache[i] == wm8962_reg[i])
2739 continue; 2734 continue;
2740 2735
2741 snd_soc_write(codec, i, wm8962->reg_cache[i]); 2736 snd_soc_write(codec, i, reg_cache[i]);
2742 } 2737 }
2743 2738
2744 codec->cache_sync = 0; 2739 codec->cache_sync = 0;
@@ -3406,12 +3401,11 @@ EXPORT_SYMBOL_GPL(wm8962_mic_detect);
3406#ifdef CONFIG_PM 3401#ifdef CONFIG_PM
3407static int wm8962_resume(struct snd_soc_codec *codec) 3402static int wm8962_resume(struct snd_soc_codec *codec)
3408{ 3403{
3409 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
3410 u16 *reg_cache = codec->reg_cache; 3404 u16 *reg_cache = codec->reg_cache;
3411 int i; 3405 int i;
3412 3406
3413 /* Restore the registers */ 3407 /* Restore the registers */
3414 for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) { 3408 for (i = 1; i < codec->driver->reg_cache_size; i++) {
3415 switch (i) { 3409 switch (i) {
3416 case WM8962_SOFTWARE_RESET: 3410 case WM8962_SOFTWARE_RESET:
3417 continue; 3411 continue;
@@ -3705,6 +3699,7 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3705 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); 3699 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
3706 struct i2c_client *i2c = container_of(codec->dev, struct i2c_client, 3700 struct i2c_client *i2c = container_of(codec->dev, struct i2c_client,
3707 dev); 3701 dev);
3702 u16 *reg_cache = codec->reg_cache;
3708 int i, trigger, irq_pol; 3703 int i, trigger, irq_pol;
3709 3704
3710 wm8962->codec = codec; 3705 wm8962->codec = codec;
@@ -3804,7 +3799,7 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3804 3799
3805 /* Put the speakers into mono mode? */ 3800 /* Put the speakers into mono mode? */
3806 if (pdata->spk_mono) 3801 if (pdata->spk_mono)
3807 wm8962->reg_cache[WM8962_CLASS_D_CONTROL_2] 3802 reg_cache[WM8962_CLASS_D_CONTROL_2]
3808 |= WM8962_SPK_MONO; 3803 |= WM8962_SPK_MONO;
3809 3804
3810 /* Micbias setup, detection enable and detection 3805 /* Micbias setup, detection enable and detection
@@ -3819,16 +3814,16 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3819 } 3814 }
3820 3815
3821 /* Latch volume update bits */ 3816 /* Latch volume update bits */
3822 wm8962->reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU; 3817 reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU;
3823 wm8962->reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU; 3818 reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU;
3824 wm8962->reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU; 3819 reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU;
3825 wm8962->reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU; 3820 reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU;
3826 wm8962->reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU; 3821 reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU;
3827 wm8962->reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU; 3822 reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU;
3828 wm8962->reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU; 3823 reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU;
3829 wm8962->reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU; 3824 reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU;
3830 wm8962->reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU; 3825 reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU;
3831 wm8962->reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU; 3826 reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU;
3832 3827
3833 wm8962_add_widgets(codec); 3828 wm8962_add_widgets(codec);
3834 3829