aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorFrank Mandarino <fmandarino@endrelia.com>2007-02-02 11:14:56 -0500
committerJaroslav Kysela <perex@suse.cz>2007-02-09 03:03:38 -0500
commitb36d61d45654104c04ff71055ef09c696fea5f89 (patch)
treeef75ab2261b5275ba2d601862d12807fd68fd835 /sound
parent11da21a79048472a14b201120c0c50b10060220b (diff)
[ALSA] soc - ASoC 0.13 WM8731 codec
This patch updates the WM8731 codec driver to the new API in ASoC 0.13. Changes:- o Removed DAI capabilities matching code in favour of manual matching in the machine drivers. o Added DAI operations for codec and CPU interfaces. o Removed config_sysclk() function and struct snd_soc_clock_info. No longer needed as clocking is now configured manually in the machine drivers. Also removed other clocking data from structures. Signed-off-by: Frank Mandarino <fmandarino@endrelia.com> Signed-off-by: Liam Girdwood <lg@opensource.wolfsonmicro.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/wm8731.c379
-rw-r--r--sound/soc/codecs/wm8731.h3
2 files changed, 127 insertions, 255 deletions
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 82f440fcf294..e6b990507df2 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -30,7 +30,7 @@
30#include "wm8731.h" 30#include "wm8731.h"
31 31
32#define AUDIO_NAME "wm8731" 32#define AUDIO_NAME "wm8731"
33#define WM8731_VERSION "0.12" 33#define WM8731_VERSION "0.13"
34 34
35/* 35/*
36 * Debug 36 * Debug
@@ -53,6 +53,11 @@
53 53
54struct snd_soc_codec_device soc_codec_dev_wm8731; 54struct snd_soc_codec_device soc_codec_dev_wm8731;
55 55
56/* codec private data */
57struct wm8731_priv {
58 unsigned int sysclk;
59};
60
56/* 61/*
57 * wm8731 register cache 62 * wm8731 register cache
58 * We can't read the WM8731 register space when we are 63 * We can't read the WM8731 register space when we are
@@ -65,191 +70,6 @@ static const u16 wm8731_reg[WM8731_CACHEREGNUM] = {
65 0x0000, 0x0000 70 0x0000, 0x0000
66}; 71};
67 72
68#define WM8731_DAIFMT \
69 (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_RIGHT_J | \
70 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_IB_NF | \
71 SND_SOC_DAIFMT_IB_IF)
72
73#define WM8731_DIR \
74 (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE)
75
76#define WM8731_RATES \
77 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
78 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
79 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
80
81#define WM8731_HIFI_BITS \
82 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
83 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
84
85static struct snd_soc_dai_mode wm8731_modes[] = {
86 /* codec frame and clock master modes */
87 /* 8k */
88 {
89 .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM,
90 .pcmfmt = WM8731_HIFI_BITS,
91 .pcmrate = SNDRV_PCM_RATE_8000,
92 .pcmdir = WM8731_DIR,
93 .flags = SND_SOC_DAI_BFS_RATE,
94 .fs = 1536,
95 .bfs = 64,
96 },
97 {
98 .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM,
99 .pcmfmt = WM8731_HIFI_BITS,
100 .pcmrate = SNDRV_PCM_RATE_8000,
101 .pcmdir = WM8731_DIR,
102 .flags = SND_SOC_DAI_BFS_RATE,
103 .fs = 2304,
104 .bfs = 64,
105 },
106 {
107 .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM,
108 .pcmfmt = WM8731_HIFI_BITS,
109 .pcmrate = SNDRV_PCM_RATE_8000,
110 .pcmdir = WM8731_DIR,
111 .flags = SND_SOC_DAI_BFS_RATE,
112 .fs = 1408,
113 .bfs = 64,
114 },
115 {
116 .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM,
117 .pcmfmt = WM8731_HIFI_BITS,
118 .pcmrate = SNDRV_PCM_RATE_8000,
119 .pcmdir = WM8731_DIR,
120 .flags = SND_SOC_DAI_BFS_RATE,
121 .fs = 2112,
122 .bfs = 64,
123 },
124
125 /* 32k */
126 {
127 .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM,
128 .pcmfmt = WM8731_HIFI_BITS,
129 .pcmrate = SNDRV_PCM_RATE_32000,
130 .pcmdir = WM8731_DIR,
131 .flags = SND_SOC_DAI_BFS_RATE,
132 .fs = 384,
133 .bfs = 64,
134 },
135 {
136 .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM,
137 .pcmfmt = WM8731_HIFI_BITS,
138 .pcmrate = SNDRV_PCM_RATE_32000,
139 .pcmdir = WM8731_DIR,
140 .flags = SND_SOC_DAI_BFS_RATE,
141 .fs = 576,
142 .bfs = 64,
143 },
144
145 /* 44.1k & 48k */
146 {
147 .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM,
148 .pcmfmt = WM8731_HIFI_BITS,
149 .pcmrate = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
150 .pcmdir = WM8731_DIR,
151 .flags = SND_SOC_DAI_BFS_RATE,
152 .fs = 256,
153 .bfs = 64,
154 },
155 {
156 .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM,
157 .pcmfmt = WM8731_HIFI_BITS,
158 .pcmrate = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
159 .pcmdir = WM8731_DIR,
160 .flags = SND_SOC_DAI_BFS_RATE,
161 .fs = 384,
162 .bfs = 64,
163 },
164
165 /* 88.2 & 96k */
166 {
167 .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM,
168 .pcmfmt = WM8731_HIFI_BITS,
169 .pcmrate = SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000,
170 .pcmdir = WM8731_DIR,
171 .flags = SND_SOC_DAI_BFS_RATE,
172 .fs = 128,
173 .bfs = 64,
174 },
175 {
176 .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM,
177 .pcmfmt = WM8731_HIFI_BITS,
178 .pcmrate = SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000,
179 .pcmdir = WM8731_DIR,
180 .flags = SND_SOC_DAI_BFS_RATE,
181 .fs = 192,
182 .bfs = 64,
183 },
184
185 /* USB codec frame and clock master modes */
186 /* 8k */
187 {
188 .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM,
189 .pcmfmt = WM8731_HIFI_BITS,
190 .pcmrate = SNDRV_PCM_RATE_8000,
191 .pcmdir = WM8731_DIR,
192 .flags = SND_SOC_DAI_BFS_DIV,
193 .fs = 1500,
194 .bfs = SND_SOC_FSBD(1),
195 },
196
197 /* 44.1k */
198 {
199 .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM,
200 .pcmfmt = WM8731_HIFI_BITS,
201 .pcmrate = SNDRV_PCM_RATE_44100,
202 .pcmdir = WM8731_DIR,
203 .flags = SND_SOC_DAI_BFS_DIV,
204 .fs = 272,
205 .bfs = SND_SOC_FSBD(1),
206 },
207
208 /* 48k */
209 {
210 .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM,
211 .pcmfmt = WM8731_HIFI_BITS,
212 .pcmrate = SNDRV_PCM_RATE_48000,
213 .pcmdir = WM8731_DIR,
214 .flags = SND_SOC_DAI_BFS_DIV,
215 .fs = 250,
216 .bfs = SND_SOC_FSBD(1),
217 },
218
219 /* 88.2k */
220 {
221 .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM,
222 .pcmfmt = WM8731_HIFI_BITS,
223 .pcmrate = SNDRV_PCM_RATE_88200,
224 .pcmdir = WM8731_DIR,
225 .flags = SND_SOC_DAI_BFS_DIV,
226 .fs = 136,
227 .bfs = SND_SOC_FSBD(1),
228 },
229
230 /* 96k */
231 {
232 .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBM_CFM,
233 .pcmfmt = WM8731_HIFI_BITS,
234 .pcmrate = SNDRV_PCM_RATE_96000,
235 .pcmdir = WM8731_DIR,
236 .flags = SND_SOC_DAI_BFS_DIV,
237 .fs = 125,
238 .bfs = SND_SOC_FSBD(1),
239 },
240
241 /* codec frame and clock slave modes */
242 {
243 .fmt = WM8731_DAIFMT | SND_SOC_DAIFMT_CBS_CFS,
244 .pcmfmt = WM8731_HIFI_BITS,
245 .pcmrate = WM8731_RATES,
246 .pcmdir = WM8731_DIR,
247 .flags = SND_SOC_DAI_BFS_DIV,
248 .fs = SND_SOC_FS_ALL,
249 .bfs = SND_SOC_FSB_ALL,
250 },
251};
252
253/* 73/*
254 * read wm8731 register cache 74 * read wm8731 register cache
255 */ 75 */
@@ -471,18 +291,34 @@ static inline int get_coeff(int mclk, int rate)
471 return 0; 291 return 0;
472} 292}
473 293
474/* WM8731 supports numerous clocks per sample rate */ 294static int wm8731_hw_params(struct snd_pcm_substream *substream,
475static unsigned int wm8731_config_sysclk(struct snd_soc_codec_dai *dai, 295 struct snd_pcm_hw_params *params)
476 struct snd_soc_clock_info *info, unsigned int clk)
477{ 296{
478 dai->mclk = 0; 297 struct snd_soc_pcm_runtime *rtd = substream->private_data;
298 struct snd_soc_device *socdev = rtd->socdev;
299 struct snd_soc_codec *codec = socdev->codec;
300 struct wm8731_priv *wm8731 = codec->private_data;
301 u16 iface = wm8731_read_reg_cache(codec, WM8731_IFACE) & 0xfff3;
302 int i = get_coeff(wm8731->sysclk, params_rate(params));
303 u16 srate = (coeff_div[i].sr << 2) |
304 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
479 305
480 /* check that the calculated FS and rate actually match a clock from 306 wm8731_write(codec, WM8731_SRATE, srate);
481 * the machine driver */ 307
482 if (info->fs * info->rate == clk) 308 /* bit size */
483 dai->mclk = clk; 309 switch (params_format(params)) {
310 case SNDRV_PCM_FORMAT_S16_LE:
311 break;
312 case SNDRV_PCM_FORMAT_S20_3LE:
313 iface |= 0x0004;
314 break;
315 case SNDRV_PCM_FORMAT_S24_LE:
316 iface |= 0x0008;
317 break;
318 }
484 319
485 return dai->mclk; 320 wm8731_write(codec, WM8731_IFACE, iface);
321 return 0;
486} 322}
487 323
488static int wm8731_pcm_prepare(struct snd_pcm_substream *substream) 324static int wm8731_pcm_prepare(struct snd_pcm_substream *substream)
@@ -490,24 +326,76 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream)
490 struct snd_soc_pcm_runtime *rtd = substream->private_data; 326 struct snd_soc_pcm_runtime *rtd = substream->private_data;
491 struct snd_soc_device *socdev = rtd->socdev; 327 struct snd_soc_device *socdev = rtd->socdev;
492 struct snd_soc_codec *codec = socdev->codec; 328 struct snd_soc_codec *codec = socdev->codec;
493 u16 iface = 0, srate; 329
494 int i = get_coeff(rtd->codec_dai->mclk, 330 /* set active */
495 snd_soc_get_rate(rtd->codec_dai->dai_runtime.pcmrate)); 331 wm8731_write(codec, WM8731_ACTIVE, 0x0001);
332
333 return 0;
334}
335
336static void wm8731_shutdown(struct snd_pcm_substream *substream)
337{
338 struct snd_soc_pcm_runtime *rtd = substream->private_data;
339 struct snd_soc_device *socdev = rtd->socdev;
340 struct snd_soc_codec *codec = socdev->codec;
341
342 /* deactivate */
343 if (!codec->active) {
344 udelay(50);
345 wm8731_write(codec, WM8731_ACTIVE, 0x0);
346 }
347}
348
349static int wm8731_mute(struct snd_soc_codec_dai *dai, int mute)
350{
351 struct snd_soc_codec *codec = dai->codec;
352 u16 mute_reg = wm8731_read_reg_cache(codec, WM8731_APDIGI) & 0xfff7;
353
354 if (mute)
355 wm8731_write(codec, WM8731_APDIGI, mute_reg | 0x8);
356 else
357 wm8731_write(codec, WM8731_APDIGI, mute_reg);
358 return 0;
359}
360
361static int wm8731_set_dai_sysclk(struct snd_soc_codec_dai *codec_dai,
362 int clk_id, unsigned int freq, int dir)
363{
364 struct snd_soc_codec *codec = codec_dai->codec;
365 struct wm8731_priv *wm8731 = codec->private_data;
366
367 switch (freq) {
368 case 11289600:
369 case 12000000:
370 case 12288000:
371 case 16934400:
372 case 18432000:
373 wm8731->sysclk = freq;
374 return 0;
375 }
376 return -EINVAL;
377}
378
379
380static int wm8731_set_dai_fmt(struct snd_soc_codec_dai *codec_dai,
381 unsigned int fmt)
382{
383 struct snd_soc_codec *codec = codec_dai->codec;
384 u16 iface = 0;
496 385
497 /* set master/slave audio interface */ 386 /* set master/slave audio interface */
498 switch (rtd->codec_dai->dai_runtime.fmt & SND_SOC_DAIFMT_CLOCK_MASK) { 387 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
499 case SND_SOC_DAIFMT_CBM_CFM: 388 case SND_SOC_DAIFMT_CBM_CFM:
500 iface |= 0x0040; 389 iface |= 0x0040;
501 break; 390 break;
502 case SND_SOC_DAIFMT_CBS_CFS: 391 case SND_SOC_DAIFMT_CBS_CFS:
503 break; 392 break;
393 default:
394 return -EINVAL;
504 } 395 }
505 srate = (coeff_div[i].sr << 2) |
506 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
507 wm8731_write(codec, WM8731_SRATE, srate);
508 396
509 /* interface format */ 397 /* interface format */
510 switch (rtd->codec_dai->dai_runtime.fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 398 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
511 case SND_SOC_DAIFMT_I2S: 399 case SND_SOC_DAIFMT_I2S:
512 iface |= 0x0002; 400 iface |= 0x0002;
513 break; 401 break;
@@ -522,25 +410,12 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream)
522 case SND_SOC_DAIFMT_DSP_B: 410 case SND_SOC_DAIFMT_DSP_B:
523 iface |= 0x0013; 411 iface |= 0x0013;
524 break; 412 break;
525 } 413 default:
526 414 return -EINVAL;
527 /* bit size */
528 switch (rtd->codec_dai->dai_runtime.pcmfmt) {
529 case SNDRV_PCM_FMTBIT_S16_LE:
530 break;
531 case SNDRV_PCM_FMTBIT_S20_3LE:
532 iface |= 0x0004;
533 break;
534 case SNDRV_PCM_FMTBIT_S24_LE:
535 iface |= 0x0008;
536 break;
537 case SNDRV_PCM_FMTBIT_S32_LE:
538 iface |= 0x000c;
539 break;
540 } 415 }
541 416
542 /* clock inversion */ 417 /* clock inversion */
543 switch (rtd->codec_dai->dai_runtime.fmt & SND_SOC_DAIFMT_INV_MASK) { 418 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
544 case SND_SOC_DAIFMT_NB_NF: 419 case SND_SOC_DAIFMT_NB_NF:
545 break; 420 break;
546 case SND_SOC_DAIFMT_IB_IF: 421 case SND_SOC_DAIFMT_IB_IF:
@@ -552,37 +427,12 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream)
552 case SND_SOC_DAIFMT_NB_IF: 427 case SND_SOC_DAIFMT_NB_IF:
553 iface |= 0x0010; 428 iface |= 0x0010;
554 break; 429 break;
430 default:
431 return -EINVAL;
555 } 432 }
556 433
557 /* set iface */ 434 /* set iface */
558 wm8731_write(codec, WM8731_IFACE, iface); 435 wm8731_write(codec, WM8731_IFACE, iface);
559
560 /* set active */
561 wm8731_write(codec, WM8731_ACTIVE, 0x0001);
562 return 0;
563}
564
565static void wm8731_shutdown(struct snd_pcm_substream *substream)
566{
567 struct snd_soc_pcm_runtime *rtd = substream->private_data;
568 struct snd_soc_device *socdev = rtd->socdev;
569 struct snd_soc_codec *codec = socdev->codec;
570
571 /* deactivate */
572 if (!codec->active) {
573 udelay(50);
574 wm8731_write(codec, WM8731_ACTIVE, 0x0);
575 }
576}
577
578static int wm8731_mute(struct snd_soc_codec *codec,
579 struct snd_soc_codec_dai *dai, int mute)
580{
581 u16 mute_reg = wm8731_read_reg_cache(codec, WM8731_APDIGI) & 0xfff7;
582 if (mute)
583 wm8731_write(codec, WM8731_APDIGI, mute_reg | 0x8);
584 else
585 wm8731_write(codec, WM8731_APDIGI, mute_reg);
586 return 0; 436 return 0;
587} 437}
588 438
@@ -612,28 +462,39 @@ static int wm8731_dapm_event(struct snd_soc_codec *codec, int event)
612 return 0; 462 return 0;
613} 463}
614 464
465#define WM8731_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
466 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
467 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
468 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
469 SNDRV_PCM_RATE_96000)
470
471#define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
472 SNDRV_PCM_FMTBIT_S24_LE)
473
615struct snd_soc_codec_dai wm8731_dai = { 474struct snd_soc_codec_dai wm8731_dai = {
616 .name = "WM8731", 475 .name = "WM8731",
617 .playback = { 476 .playback = {
618 .stream_name = "Playback", 477 .stream_name = "Playback",
619 .channels_min = 1, 478 .channels_min = 1,
620 .channels_max = 2, 479 .channels_max = 2,
621 }, 480 .rates = WM8731_RATES,
481 .formats = WM8731_FORMATS,},
622 .capture = { 482 .capture = {
623 .stream_name = "Capture", 483 .stream_name = "Capture",
624 .channels_min = 1, 484 .channels_min = 1,
625 .channels_max = 2, 485 .channels_max = 2,
626 }, 486 .rates = WM8731_RATES,
627 .config_sysclk = wm8731_config_sysclk, 487 .formats = WM8731_FORMATS,},
628 .digital_mute = wm8731_mute,
629 .ops = { 488 .ops = {
630 .prepare = wm8731_pcm_prepare, 489 .prepare = wm8731_pcm_prepare,
490 .hw_params = wm8731_hw_params,
631 .shutdown = wm8731_shutdown, 491 .shutdown = wm8731_shutdown,
632 }, 492 },
633 .caps = { 493 .dai_ops = {
634 .num_modes = ARRAY_SIZE(wm8731_modes), 494 .digital_mute = wm8731_mute,
635 .mode = wm8731_modes, 495 .set_sysclk = wm8731_set_dai_sysclk,
636 }, 496 .set_fmt = wm8731_set_dai_fmt,
497 }
637}; 498};
638EXPORT_SYMBOL_GPL(wm8731_dai); 499EXPORT_SYMBOL_GPL(wm8731_dai);
639 500
@@ -683,7 +544,6 @@ static int wm8731_init(struct snd_soc_device *socdev)
683 codec->dai = &wm8731_dai; 544 codec->dai = &wm8731_dai;
684 codec->num_dai = 1; 545 codec->num_dai = 1;
685 codec->reg_cache_size = ARRAY_SIZE(wm8731_reg); 546 codec->reg_cache_size = ARRAY_SIZE(wm8731_reg);
686
687 codec->reg_cache = 547 codec->reg_cache =
688 kzalloc(sizeof(u16) * ARRAY_SIZE(wm8731_reg), GFP_KERNEL); 548 kzalloc(sizeof(u16) * ARRAY_SIZE(wm8731_reg), GFP_KERNEL);
689 if (codec->reg_cache == NULL) 549 if (codec->reg_cache == NULL)
@@ -832,6 +692,7 @@ static int wm8731_probe(struct platform_device *pdev)
832 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 692 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
833 struct wm8731_setup_data *setup; 693 struct wm8731_setup_data *setup;
834 struct snd_soc_codec *codec; 694 struct snd_soc_codec *codec;
695 struct wm8731_priv *wm8731;
835 int ret = 0; 696 int ret = 0;
836 697
837 info("WM8731 Audio Codec %s", WM8731_VERSION); 698 info("WM8731 Audio Codec %s", WM8731_VERSION);
@@ -841,6 +702,13 @@ static int wm8731_probe(struct platform_device *pdev)
841 if (codec == NULL) 702 if (codec == NULL)
842 return -ENOMEM; 703 return -ENOMEM;
843 704
705 wm8731 = kzalloc(sizeof(struct wm8731_priv), GFP_KERNEL);
706 if (wm8731 == NULL) {
707 kfree(codec);
708 return -ENOMEM;
709 }
710
711 codec->private_data = wm8731;
844 socdev->codec = codec; 712 socdev->codec = codec;
845 mutex_init(&codec->mutex); 713 mutex_init(&codec->mutex);
846 INIT_LIST_HEAD(&codec->dapm_widgets); 714 INIT_LIST_HEAD(&codec->dapm_widgets);
@@ -875,6 +743,7 @@ static int wm8731_remove(struct platform_device *pdev)
875#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) 743#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
876 i2c_del_driver(&wm8731_i2c_driver); 744 i2c_del_driver(&wm8731_i2c_driver);
877#endif 745#endif
746 kfree(codec->private_data);
878 kfree(codec); 747 kfree(codec);
879 748
880 return 0; 749 return 0;
diff --git a/sound/soc/codecs/wm8731.h b/sound/soc/codecs/wm8731.h
index 8fa0f53bef1c..5bcab6a7afb4 100644
--- a/sound/soc/codecs/wm8731.h
+++ b/sound/soc/codecs/wm8731.h
@@ -31,6 +31,9 @@
31 31
32#define WM8731_CACHEREGNUM 10 32#define WM8731_CACHEREGNUM 10
33 33
34#define WM8731_SYSCLK 0
35#define WM8731_DAI 0
36
34struct wm8731_setup_data { 37struct wm8731_setup_data {
35 unsigned short i2c_address; 38 unsigned short i2c_address;
36}; 39};