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 @@ | |||
1 | From 9760063610bb4890c0f88c1dd839ec1531706f33 Mon Sep 17 00:00:00 2001 | ||
2 | From: Lars-Peter Clausen <lars@metafoo.de> | ||
3 | Date: Tue, 28 Dec 2010 21:38:01 +0100 | ||
4 | Subject: [PATCH 23/65] ASoC: codecs: wm8962: Fix register cache incoherency | ||
5 | |||
6 | The multi-component patch(commit f0fba2ad1) moved the allocation of the | ||
7 | register cache from the driver to the ASoC core. Most drivers where adjusted to | ||
8 | this, but the wm8962 driver still uses its own register cache for its | ||
9 | private functions, while functions from the ASoC core use the generic cache. | ||
10 | Thus we end up with two from each other incoherent caches, which can lead to | ||
11 | undefined behaviour. | ||
12 | This patch fixes the issue by changing the wm8962 driver to use the | ||
13 | generic register cache in its private functions. | ||
14 | |||
15 | Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> | ||
16 | Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
17 | Cc: stable@kernel.org (for 2.6.37 only) | ||
18 | --- | ||
19 | sound/soc/codecs/wm8962.c | 45 ++++++++++++++++++++------------------------- | ||
20 | 1 files changed, 20 insertions(+), 25 deletions(-) | ||
21 | |||
22 | diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c | ||
23 | index 1304ca9..7c421cc 100644 | ||
24 | --- a/sound/soc/codecs/wm8962.c | ||
25 | +++ b/sound/soc/codecs/wm8962.c | ||
26 | @@ -52,8 +52,6 @@ static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = { | ||
27 | struct wm8962_priv { | ||
28 | struct snd_soc_codec *codec; | ||
29 | |||
30 | - u16 reg_cache[WM8962_MAX_REGISTER + 1]; | ||
31 | - | ||
32 | int sysclk; | ||
33 | int sysclk_rate; | ||
34 | |||
35 | @@ -1991,8 +1989,7 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol, | ||
36 | struct snd_ctl_elem_value *ucontrol) | ||
37 | { | ||
38 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
39 | - struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | ||
40 | - u16 *reg_cache = wm8962->reg_cache; | ||
41 | + u16 *reg_cache = codec->reg_cache; | ||
42 | int ret; | ||
43 | |||
44 | /* Apply the update (if any) */ | ||
45 | @@ -2020,8 +2017,7 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol, | ||
46 | struct snd_ctl_elem_value *ucontrol) | ||
47 | { | ||
48 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
49 | - struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | ||
50 | - u16 *reg_cache = wm8962->reg_cache; | ||
51 | + u16 *reg_cache = codec->reg_cache; | ||
52 | int ret; | ||
53 | |||
54 | /* Apply the update (if any) */ | ||
55 | @@ -2329,8 +2325,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w, | ||
56 | struct snd_kcontrol *kcontrol, int event) | ||
57 | { | ||
58 | struct snd_soc_codec *codec = w->codec; | ||
59 | - struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | ||
60 | - u16 *reg_cache = wm8962->reg_cache; | ||
61 | + u16 *reg_cache = codec->reg_cache; | ||
62 | int reg; | ||
63 | |||
64 | switch (w->shift) { | ||
65 | @@ -2719,7 +2714,7 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec) | ||
66 | |||
67 | static void wm8962_sync_cache(struct snd_soc_codec *codec) | ||
68 | { | ||
69 | - struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | ||
70 | + u16 *reg_cache = codec->reg_cache; | ||
71 | int i; | ||
72 | |||
73 | if (!codec->cache_sync) | ||
74 | @@ -2732,13 +2727,13 @@ static void wm8962_sync_cache(struct snd_soc_codec *codec) | ||
75 | /* Sync back cached values if they're different from the | ||
76 | * hardware default. | ||
77 | */ | ||
78 | - for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) { | ||
79 | + for (i = 1; i < codec->driver->reg_cache_size; i++) { | ||
80 | if (i == WM8962_SOFTWARE_RESET) | ||
81 | continue; | ||
82 | - if (wm8962->reg_cache[i] == wm8962_reg[i]) | ||
83 | + if (reg_cache[i] == wm8962_reg[i]) | ||
84 | continue; | ||
85 | |||
86 | - snd_soc_write(codec, i, wm8962->reg_cache[i]); | ||
87 | + snd_soc_write(codec, i, reg_cache[i]); | ||
88 | } | ||
89 | |||
90 | codec->cache_sync = 0; | ||
91 | @@ -3406,12 +3401,11 @@ EXPORT_SYMBOL_GPL(wm8962_mic_detect); | ||
92 | #ifdef CONFIG_PM | ||
93 | static int wm8962_resume(struct snd_soc_codec *codec) | ||
94 | { | ||
95 | - struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | ||
96 | u16 *reg_cache = codec->reg_cache; | ||
97 | int i; | ||
98 | |||
99 | /* Restore the registers */ | ||
100 | - for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) { | ||
101 | + for (i = 1; i < codec->driver->reg_cache_size; i++) { | ||
102 | switch (i) { | ||
103 | case WM8962_SOFTWARE_RESET: | ||
104 | continue; | ||
105 | @@ -3705,6 +3699,7 @@ static int wm8962_probe(struct snd_soc_codec *codec) | ||
106 | struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); | ||
107 | struct i2c_client *i2c = container_of(codec->dev, struct i2c_client, | ||
108 | dev); | ||
109 | + u16 *reg_cache = codec->reg_cache; | ||
110 | int i, trigger, irq_pol; | ||
111 | |||
112 | wm8962->codec = codec; | ||
113 | @@ -3804,7 +3799,7 @@ static int wm8962_probe(struct snd_soc_codec *codec) | ||
114 | |||
115 | /* Put the speakers into mono mode? */ | ||
116 | if (pdata->spk_mono) | ||
117 | - wm8962->reg_cache[WM8962_CLASS_D_CONTROL_2] | ||
118 | + reg_cache[WM8962_CLASS_D_CONTROL_2] | ||
119 | |= WM8962_SPK_MONO; | ||
120 | |||
121 | /* Micbias setup, detection enable and detection | ||
122 | @@ -3819,16 +3814,16 @@ static int wm8962_probe(struct snd_soc_codec *codec) | ||
123 | } | ||
124 | |||
125 | /* Latch volume update bits */ | ||
126 | - wm8962->reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU; | ||
127 | - wm8962->reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU; | ||
128 | - wm8962->reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU; | ||
129 | - wm8962->reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU; | ||
130 | - wm8962->reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU; | ||
131 | - wm8962->reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU; | ||
132 | - wm8962->reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU; | ||
133 | - wm8962->reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU; | ||
134 | - wm8962->reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU; | ||
135 | - wm8962->reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU; | ||
136 | + reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU; | ||
137 | + reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU; | ||
138 | + reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU; | ||
139 | + reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU; | ||
140 | + reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU; | ||
141 | + reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU; | ||
142 | + reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU; | ||
143 | + reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU; | ||
144 | + reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU; | ||
145 | + reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU; | ||
146 | |||
147 | wm8962_add_widgets(codec); | ||
148 | |||
149 | -- | ||
150 | 1.6.6.1 | ||
151 | |||