]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/meta-ti-glsdk.git/blob - recipes-bsp/linux/linux-omap/linus/0025-ASoC-codecs-wm8753-Fix-register-cache-incoherency.patch
574c76ea98a9d212c0e7f676989d024e7fc3c214
[glsdk/meta-ti-glsdk.git] / recipes-bsp / linux / linux-omap / linus / 0025-ASoC-codecs-wm8753-Fix-register-cache-incoherency.patch
1 From 0e07d2db08fa60b3e1bbc9837775feaf1cb8a381 Mon Sep 17 00:00:00 2001
2 From: Lars-Peter Clausen <lars@metafoo.de>
3 Date: Tue, 28 Dec 2010 21:38:03 +0100
4 Subject: [PATCH 25/65] ASoC: codecs: wm8753: Fix register cache incoherency
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 wm8753 driver still uses its own register cache for its
9 private functions, while functions from the ASoC core use the generic cache.
10 Furthermore the generic cache uses zero-based numbering while the wm8753 cache
11 uses one-based numbering.
12 Thus we end up with two from each other incoherent caches, which leads to undefined
13 behaviour and crashes.
14 This patch fixes the issue by changing the wm8753 driver to use the generic
15 register cache in its private functions.
17 Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
18 Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
19 ---
20  sound/soc/codecs/wm8753.c |  226 +++++++++++++++++----------------------------
21  1 files changed, 83 insertions(+), 143 deletions(-)
23 diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
24 index 8f679a1..87caae5 100644
25 --- a/sound/soc/codecs/wm8753.c
26 +++ b/sound/soc/codecs/wm8753.c
27 @@ -65,22 +65,22 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
28   * are using 2 wire for device control, so we cache them instead.
29   */
30  static const u16 wm8753_reg[] = {
31 -       0x0008, 0x0000, 0x000a, 0x000a,
32 -       0x0033, 0x0000, 0x0007, 0x00ff,
33 -       0x00ff, 0x000f, 0x000f, 0x007b,
34 -       0x0000, 0x0032, 0x0000, 0x00c3,
35 -       0x00c3, 0x00c0, 0x0000, 0x0000,
36 +       0x0000, 0x0008, 0x0000, 0x000a,
37 +       0x000a, 0x0033, 0x0000, 0x0007,
38 +       0x00ff, 0x00ff, 0x000f, 0x000f,
39 +       0x007b, 0x0000, 0x0032, 0x0000,
40 +       0x00c3, 0x00c3, 0x00c0, 0x0000,
41         0x0000, 0x0000, 0x0000, 0x0000,
42         0x0000, 0x0000, 0x0000, 0x0000,
43 -       0x0000, 0x0000, 0x0000, 0x0055,
44 -       0x0005, 0x0050, 0x0055, 0x0050,
45 -       0x0055, 0x0050, 0x0055, 0x0079,
46 -       0x0079, 0x0079, 0x0079, 0x0079,
47         0x0000, 0x0000, 0x0000, 0x0000,
48 -       0x0097, 0x0097, 0x0000, 0x0004,
49 -       0x0000, 0x0083, 0x0024, 0x01ba,
50 -       0x0000, 0x0083, 0x0024, 0x01ba,
51 -       0x0000, 0x0000, 0x0000
52 +       0x0055, 0x0005, 0x0050, 0x0055,
53 +       0x0050, 0x0055, 0x0050, 0x0055,
54 +       0x0079, 0x0079, 0x0079, 0x0079,
55 +       0x0079, 0x0000, 0x0000, 0x0000,
56 +       0x0000, 0x0097, 0x0097, 0x0000,
57 +       0x0004, 0x0000, 0x0083, 0x0024,
58 +       0x01ba, 0x0000, 0x0083, 0x0024,
59 +       0x01ba, 0x0000, 0x0000, 0x0000
60  };
61  
62  /* codec private data */
63 @@ -88,57 +88,10 @@ struct wm8753_priv {
64         enum snd_soc_control_type control_type;
65         unsigned int sysclk;
66         unsigned int pcmclk;
67 -       u16 reg_cache[ARRAY_SIZE(wm8753_reg)];
68         int dai_func;
69  };
70  
71 -/*
72 - * read wm8753 register cache
73 - */
74 -static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec,
75 -       unsigned int reg)
76 -{
77 -       u16 *cache = codec->reg_cache;
78 -       if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
79 -               return -1;
80 -       return cache[reg - 1];
81 -}
82 -
83 -/*
84 - * write wm8753 register cache
85 - */
86 -static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec,
87 -       unsigned int reg, unsigned int value)
88 -{
89 -       u16 *cache = codec->reg_cache;
90 -       if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1))
91 -               return;
92 -       cache[reg - 1] = value;
93 -}
94 -
95 -/*
96 - * write to the WM8753 register space
97 - */
98 -static int wm8753_write(struct snd_soc_codec *codec, unsigned int reg,
99 -       unsigned int value)
100 -{
101 -       u8 data[2];
103 -       /* data is
104 -        *   D15..D9 WM8753 register offset
105 -        *   D8...D0 register data
106 -        */
107 -       data[0] = (reg << 1) | ((value >> 8) & 0x0001);
108 -       data[1] = value & 0x00ff;
110 -       wm8753_write_reg_cache(codec, reg, value);
111 -       if (codec->hw_write(codec->control_data, data, 2) == 2)
112 -               return 0;
113 -       else
114 -               return -EIO;
115 -}
117 -#define wm8753_reset(c) wm8753_write(c, WM8753_RESET, 0)
118 +#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0)
119  
120  /*
121   * WM8753 Controls
122 @@ -218,7 +171,7 @@ static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
123         struct snd_ctl_elem_value *ucontrol)
124  {
125         struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
126 -       int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL);
127 +       int mode = snd_soc_read(codec, WM8753_IOCTL);
128  
129         ucontrol->value.integer.value[0] = (mode & 0xc) >> 2;
130         return 0;
131 @@ -228,7 +181,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
132         struct snd_ctl_elem_value *ucontrol)
133  {
134         struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
135 -       int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL);
136 +       int mode = snd_soc_read(codec, WM8753_IOCTL);
137         struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
138  
139         if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0])
140 @@ -738,17 +691,17 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
141         if (pll_id == WM8753_PLL1) {
142                 offset = 0;
143                 enable = 0x10;
144 -               reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xffef;
145 +               reg = snd_soc_read(codec, WM8753_CLOCK) & 0xffef;
146         } else {
147                 offset = 4;
148                 enable = 0x8;
149 -               reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfff7;
150 +               reg = snd_soc_read(codec, WM8753_CLOCK) & 0xfff7;
151         }
152  
153         if (!freq_in || !freq_out) {
154                 /* disable PLL  */
155 -               wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
156 -               wm8753_write(codec, WM8753_CLOCK, reg);
157 +               snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
158 +               snd_soc_write(codec, WM8753_CLOCK, reg);
159                 return 0;
160         } else {
161                 u16 value = 0;
162 @@ -759,20 +712,20 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
163                 /* set up N and K PLL divisor ratios */
164                 /* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
165                 value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18);
166 -               wm8753_write(codec, WM8753_PLL1CTL2 + offset, value);
167 +               snd_soc_write(codec, WM8753_PLL1CTL2 + offset, value);
168  
169                 /* bits 8:0 = PLL_K[17:9] */
170                 value = (pll_div.k & 0x03fe00) >> 9;
171 -               wm8753_write(codec, WM8753_PLL1CTL3 + offset, value);
172 +               snd_soc_write(codec, WM8753_PLL1CTL3 + offset, value);
173  
174                 /* bits 8:0 = PLL_K[8:0] */
175                 value = pll_div.k & 0x0001ff;
176 -               wm8753_write(codec, WM8753_PLL1CTL4 + offset, value);
177 +               snd_soc_write(codec, WM8753_PLL1CTL4 + offset, value);
178  
179                 /* set PLL as input and enable */
180 -               wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
181 +               snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
182                         (pll_div.div2 << 3));
183 -               wm8753_write(codec, WM8753_CLOCK, reg | enable);
184 +               snd_soc_write(codec, WM8753_CLOCK, reg | enable);
185         }
186         return 0;
187  }
188 @@ -879,7 +832,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
189                 unsigned int fmt)
190  {
191         struct snd_soc_codec *codec = codec_dai->codec;
192 -       u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01ec;
193 +       u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec;
194  
195         /* interface format */
196         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
197 @@ -901,7 +854,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
198                 return -EINVAL;
199         }
200  
201 -       wm8753_write(codec, WM8753_PCM, voice);
202 +       snd_soc_write(codec, WM8753_PCM, voice);
203         return 0;
204  }
205  
206 @@ -922,8 +875,8 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
207         struct snd_soc_pcm_runtime *rtd = substream->private_data;
208         struct snd_soc_codec *codec = rtd->codec;
209         struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
210 -       u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3;
211 -       u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f;
212 +       u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01f3;
213 +       u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x017f;
214  
215         /* bit size */
216         switch (params_format(params)) {
217 @@ -943,9 +896,9 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
218         /* sample rate */
219         if (params_rate(params) * 384 == wm8753->pcmclk)
220                 srate |= 0x80;
221 -       wm8753_write(codec, WM8753_SRATE1, srate);
222 +       snd_soc_write(codec, WM8753_SRATE1, srate);
223  
224 -       wm8753_write(codec, WM8753_PCM, voice);
225 +       snd_soc_write(codec, WM8753_PCM, voice);
226         return 0;
227  }
228  
229 @@ -958,8 +911,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
230         struct snd_soc_codec *codec = codec_dai->codec;
231         u16 voice, ioctl;
232  
233 -       voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x011f;
234 -       ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x015d;
235 +       voice = snd_soc_read(codec, WM8753_PCM) & 0x011f;
236 +       ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x015d;
237  
238         /* set master/slave audio interface */
239         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
240 @@ -1013,8 +966,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
241                 return -EINVAL;
242         }
243  
244 -       wm8753_write(codec, WM8753_PCM, voice);
245 -       wm8753_write(codec, WM8753_IOCTL, ioctl);
246 +       snd_soc_write(codec, WM8753_PCM, voice);
247 +       snd_soc_write(codec, WM8753_IOCTL, ioctl);
248         return 0;
249  }
250  
251 @@ -1026,16 +979,16 @@ static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
252  
253         switch (div_id) {
254         case WM8753_PCMDIV:
255 -               reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0x003f;
256 -               wm8753_write(codec, WM8753_CLOCK, reg | div);
257 +               reg = snd_soc_read(codec, WM8753_CLOCK) & 0x003f;
258 +               snd_soc_write(codec, WM8753_CLOCK, reg | div);
259                 break;
260         case WM8753_BCLKDIV:
261 -               reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x01c7;
262 -               wm8753_write(codec, WM8753_SRATE2, reg | div);
263 +               reg = snd_soc_read(codec, WM8753_SRATE2) & 0x01c7;
264 +               snd_soc_write(codec, WM8753_SRATE2, reg | div);
265                 break;
266         case WM8753_VXCLKDIV:
267 -               reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x003f;
268 -               wm8753_write(codec, WM8753_SRATE2, reg | div);
269 +               reg = snd_soc_read(codec, WM8753_SRATE2) & 0x003f;
270 +               snd_soc_write(codec, WM8753_SRATE2, reg | div);
271                 break;
272         default:
273                 return -EINVAL;
274 @@ -1050,7 +1003,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
275                 unsigned int fmt)
276  {
277         struct snd_soc_codec *codec = codec_dai->codec;
278 -       u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01e0;
279 +       u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0;
280  
281         /* interface format */
282         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
283 @@ -1072,7 +1025,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
284                 return -EINVAL;
285         }
286  
287 -       wm8753_write(codec, WM8753_HIFI, hifi);
288 +       snd_soc_write(codec, WM8753_HIFI, hifi);
289         return 0;
290  }
291  
292 @@ -1085,8 +1038,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
293         struct snd_soc_codec *codec = codec_dai->codec;
294         u16 ioctl, hifi;
295  
296 -       hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x011f;
297 -       ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x00ae;
298 +       hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f;
299 +       ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x00ae;
300  
301         /* set master/slave audio interface */
302         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
303 @@ -1140,8 +1093,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
304                 return -EINVAL;
305         }
306  
307 -       wm8753_write(codec, WM8753_HIFI, hifi);
308 -       wm8753_write(codec, WM8753_IOCTL, ioctl);
309 +       snd_soc_write(codec, WM8753_HIFI, hifi);
310 +       snd_soc_write(codec, WM8753_IOCTL, ioctl);
311         return 0;
312  }
313  
314 @@ -1162,8 +1115,8 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
315         struct snd_soc_pcm_runtime *rtd = substream->private_data;
316         struct snd_soc_codec *codec = rtd->codec;
317         struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
318 -       u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0;
319 -       u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3;
320 +       u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x01c0;
321 +       u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01f3;
322         int coeff;
323  
324         /* is digital filter coefficient valid ? */
325 @@ -1172,7 +1125,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
326                 printk(KERN_ERR "wm8753 invalid MCLK or rate\n");
327                 return coeff;
328         }
329 -       wm8753_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
330 +       snd_soc_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
331                 coeff_div[coeff].usb);
332  
333         /* bit size */
334 @@ -1190,7 +1143,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
335                 break;
336         }
337  
338 -       wm8753_write(codec, WM8753_HIFI, hifi);
339 +       snd_soc_write(codec, WM8753_HIFI, hifi);
340         return 0;
341  }
342  
343 @@ -1201,8 +1154,8 @@ static int wm8753_mode1v_set_dai_fmt(struct snd_soc_dai *codec_dai,
344         u16 clock;
345  
346         /* set clk source as pcmclk */
347 -       clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
348 -       wm8753_write(codec, WM8753_CLOCK, clock);
349 +       clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
350 +       snd_soc_write(codec, WM8753_CLOCK, clock);
351  
352         if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
353                 return -EINVAL;
354 @@ -1224,8 +1177,8 @@ static int wm8753_mode2_set_dai_fmt(struct snd_soc_dai *codec_dai,
355         u16 clock;
356  
357         /* set clk source as pcmclk */
358 -       clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
359 -       wm8753_write(codec, WM8753_CLOCK, clock);
360 +       clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
361 +       snd_soc_write(codec, WM8753_CLOCK, clock);
362  
363         if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
364                 return -EINVAL;
365 @@ -1239,8 +1192,8 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai,
366         u16 clock;
367  
368         /* set clk source as mclk */
369 -       clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb;
370 -       wm8753_write(codec, WM8753_CLOCK, clock | 0x4);
371 +       clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
372 +       snd_soc_write(codec, WM8753_CLOCK, clock | 0x4);
373  
374         if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0)
375                 return -EINVAL;
376 @@ -1252,19 +1205,19 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai,
377  static int wm8753_mute(struct snd_soc_dai *dai, int mute)
378  {
379         struct snd_soc_codec *codec = dai->codec;
380 -       u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7;
381 +       u16 mute_reg = snd_soc_read(codec, WM8753_DAC) & 0xfff7;
382         struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
383  
384         /* the digital mute covers the HiFi and Voice DAC's on the WM8753.
385          * make sure we check if they are not both active when we mute */
386         if (mute && wm8753->dai_func == 1) {
387                 if (!codec->active)
388 -                       wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
389 +                       snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
390         } else {
391                 if (mute)
392 -                       wm8753_write(codec, WM8753_DAC, mute_reg | 0x8);
393 +                       snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
394                 else
395 -                       wm8753_write(codec, WM8753_DAC, mute_reg);
396 +                       snd_soc_write(codec, WM8753_DAC, mute_reg);
397         }
398  
399         return 0;
400 @@ -1273,23 +1226,23 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute)
401  static int wm8753_set_bias_level(struct snd_soc_codec *codec,
402                                  enum snd_soc_bias_level level)
403  {
404 -       u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3e;
405 +       u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e;
406  
407         switch (level) {
408         case SND_SOC_BIAS_ON:
409                 /* set vmid to 50k and unmute dac */
410 -               wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
411 +               snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
412                 break;
413         case SND_SOC_BIAS_PREPARE:
414                 /* set vmid to 5k for quick power up */
415 -               wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
416 +               snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
417                 break;
418         case SND_SOC_BIAS_STANDBY:
419                 /* mute dac and set vmid to 500k, enable VREF */
420 -               wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
421 +               snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
422                 break;
423         case SND_SOC_BIAS_OFF:
424 -               wm8753_write(codec, WM8753_PWR1, 0x0001);
425 +               snd_soc_write(codec, WM8753_PWR1, 0x0001);
426                 break;
427         }
428         codec->bias_level = level;
429 @@ -1477,7 +1430,7 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
430                 else
431                         dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1];
432         }
433 -       wm8753_write(codec, WM8753_IOCTL, wm8753->dai_func);
434 +       snd_soc_write(codec, WM8753_IOCTL, wm8753->dai_func);
435  }
436  
437  static void wm8753_work(struct work_struct *work)
438 @@ -1495,22 +1448,19 @@ static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state)
439  
440  static int wm8753_resume(struct snd_soc_codec *codec)
441  {
442 +       u16 *reg_cache = codec->reg_cache;
443         int i;
444 -       u8 data[2];
445 -       u16 *cache = codec->reg_cache;
446  
447         /* Sync reg_cache with the hardware */
448 -       for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) {
449 -               if (i + 1 == WM8753_RESET)
450 +       for (i = 1; i < ARRAY_SIZE(wm8753_reg); i++) {
451 +               if (i == WM8753_RESET)
452                         continue;
453  
454                 /* No point in writing hardware default values back */
455 -               if (cache[i] == wm8753_reg[i])
456 +               if (reg_cache[i] == wm8753_reg[i])
457                         continue;
458  
459 -               data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001);
460 -               data[1] = cache[i] & 0x00ff;
461 -               codec->hw_write(codec->control_data, data, 2);
462 +               snd_soc_write(codec, i, reg_cache[i]);
463         }
464  
465         wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
466 @@ -1548,7 +1498,7 @@ static int run_delayed_work(struct delayed_work *dwork)
467  static int wm8753_probe(struct snd_soc_codec *codec)
468  {
469         struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
470 -       int ret = 0, reg;
471 +       int ret;
472  
473         INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
474  
475 @@ -1573,26 +1523,16 @@ static int wm8753_probe(struct snd_soc_codec *codec)
476                               msecs_to_jiffies(caps_charge));
477  
478         /* set the update bits */
479 -       reg = wm8753_read_reg_cache(codec, WM8753_LDAC);
480 -       wm8753_write(codec, WM8753_LDAC, reg | 0x0100);
481 -       reg = wm8753_read_reg_cache(codec, WM8753_RDAC);
482 -       wm8753_write(codec, WM8753_RDAC, reg | 0x0100);
483 -       reg = wm8753_read_reg_cache(codec, WM8753_LADC);
484 -       wm8753_write(codec, WM8753_LADC, reg | 0x0100);
485 -       reg = wm8753_read_reg_cache(codec, WM8753_RADC);
486 -       wm8753_write(codec, WM8753_RADC, reg | 0x0100);
487 -       reg = wm8753_read_reg_cache(codec, WM8753_LOUT1V);
488 -       wm8753_write(codec, WM8753_LOUT1V, reg | 0x0100);
489 -       reg = wm8753_read_reg_cache(codec, WM8753_ROUT1V);
490 -       wm8753_write(codec, WM8753_ROUT1V, reg | 0x0100);
491 -       reg = wm8753_read_reg_cache(codec, WM8753_LOUT2V);
492 -       wm8753_write(codec, WM8753_LOUT2V, reg | 0x0100);
493 -       reg = wm8753_read_reg_cache(codec, WM8753_ROUT2V);
494 -       wm8753_write(codec, WM8753_ROUT2V, reg | 0x0100);
495 -       reg = wm8753_read_reg_cache(codec, WM8753_LINVOL);
496 -       wm8753_write(codec, WM8753_LINVOL, reg | 0x0100);
497 -       reg = wm8753_read_reg_cache(codec, WM8753_RINVOL);
498 -       wm8753_write(codec, WM8753_RINVOL, reg | 0x0100);
499 +       snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
500 +       snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
501 +       snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
502 +       snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
503 +       snd_soc_update_bits(codec, WM8753_LOUT1V, 0x0100, 0x0100);
504 +       snd_soc_update_bits(codec, WM8753_ROUT1V, 0x0100, 0x0100);
505 +       snd_soc_update_bits(codec, WM8753_LOUT2V, 0x0100, 0x0100);
506 +       snd_soc_update_bits(codec, WM8753_ROUT2V, 0x0100, 0x0100);
507 +       snd_soc_update_bits(codec, WM8753_LINVOL, 0x0100, 0x0100);
508 +       snd_soc_update_bits(codec, WM8753_RINVOL, 0x0100, 0x0100);
509  
510         snd_soc_add_controls(codec, wm8753_snd_controls,
511                              ARRAY_SIZE(wm8753_snd_controls));
512 -- 
513 1.6.6.1