2 * wm8753.c -- WM8753 ALSA Soc Audio driver
4 * Copyright 2003 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
14 * The WM8753 is a low power, high quality stereo codec with integrated PCM
15 * codec designed for portable digital telephony applications.
19 * This driver support 2 DAI PCM's. This makes the default PCM available for
20 * HiFi audio (e.g. MP3, ogg) playback/capture and the other PCM available for
23 * Please note that the voice PCM can be connected directly to a Bluetooth
24 * codec or GSM modem and thus cannot be read or written to, although it is
25 * available to be configured with snd_hw_params(), etc and kcontrols in the
28 * Fast DAI switching:-
30 * The driver can now fast switch between the DAI configurations via a
31 * an alsa kcontrol. This allows the PCM to remain open.
35 #include <linux/module.h>
36 #include <linux/moduleparam.h>
37 #include <linux/version.h>
38 #include <linux/kernel.h>
39 #include <linux/init.h>
40 #include <linux/delay.h>
42 #include <linux/i2c.h>
43 #include <linux/platform_device.h>
44 #include <sound/core.h>
45 #include <sound/pcm.h>
46 #include <sound/pcm_params.h>
47 #include <sound/soc.h>
48 #include <sound/soc-dapm.h>
49 #include <sound/initval.h>
50 #include <sound/tlv.h>
51 #include <asm/div64.h>
55 #define AUDIO_NAME "wm8753"
56 #define WM8753_VERSION "0.16"
62 #define WM8753_DEBUG 0
65 #define dbg(format, arg...) \
66 printk(KERN_DEBUG AUDIO_NAME ": " format "\n" , ## arg)
68 #define dbg(format, arg...) do {} while (0)
70 #define err(format, arg...) \
71 printk(KERN_ERR AUDIO_NAME ": " format "\n" , ## arg)
72 #define info(format, arg...) \
73 printk(KERN_INFO AUDIO_NAME ": " format "\n" , ## arg)
74 #define warn(format, arg...) \
75 printk(KERN_WARNING AUDIO_NAME ": " format "\n" , ## arg)
77 static int caps_charge
= 2000;
78 module_param(caps_charge
, int, 0);
79 MODULE_PARM_DESC(caps_charge
, "WM8753 cap charge time (msecs)");
81 static void wm8753_set_dai_mode(struct snd_soc_codec
*codec
,
84 /* codec private data */
91 * wm8753 register cache
92 * We can't read the WM8753 register space when we
93 * are using 2 wire for device control, so we cache them instead.
95 static const u16 wm8753_reg
[] = {
96 0x0008, 0x0000, 0x000a, 0x000a,
97 0x0033, 0x0000, 0x0007, 0x00ff,
98 0x00ff, 0x000f, 0x000f, 0x007b,
99 0x0000, 0x0032, 0x0000, 0x00c3,
100 0x00c3, 0x00c0, 0x0000, 0x0000,
101 0x0000, 0x0000, 0x0000, 0x0000,
102 0x0000, 0x0000, 0x0000, 0x0000,
103 0x0000, 0x0000, 0x0000, 0x0055,
104 0x0005, 0x0050, 0x0055, 0x0050,
105 0x0055, 0x0050, 0x0055, 0x0079,
106 0x0079, 0x0079, 0x0079, 0x0079,
107 0x0000, 0x0000, 0x0000, 0x0000,
108 0x0097, 0x0097, 0x0000, 0x0004,
109 0x0000, 0x0083, 0x0024, 0x01ba,
110 0x0000, 0x0083, 0x0024, 0x01ba,
115 * read wm8753 register cache
117 static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec
*codec
,
120 u16
*cache
= codec
->reg_cache
;
121 if (reg
< 1 || reg
> (ARRAY_SIZE(wm8753_reg
) + 1))
123 return cache
[reg
- 1];
127 * write wm8753 register cache
129 static inline void wm8753_write_reg_cache(struct snd_soc_codec
*codec
,
130 unsigned int reg
, unsigned int value
)
132 u16
*cache
= codec
->reg_cache
;
133 if (reg
< 1 || reg
> 0x3f)
135 cache
[reg
- 1] = value
;
139 * write to the WM8753 register space
141 static int wm8753_write(struct snd_soc_codec
*codec
, unsigned int reg
,
147 * D15..D9 WM8753 register offset
148 * D8...D0 register data
150 data
[0] = (reg
<< 1) | ((value
>> 8) & 0x0001);
151 data
[1] = value
& 0x00ff;
153 wm8753_write_reg_cache (codec
, reg
, value
);
154 if (codec
->hw_write(codec
->control_data
, data
, 2) == 2)
160 #define wm8753_reset(c) wm8753_write(c, WM8753_RESET, 0)
165 static const char *wm8753_base
[] = {"Linear Control", "Adaptive Boost"};
166 static const char *wm8753_base_filter
[] =
167 {"130Hz @ 48kHz", "200Hz @ 48kHz", "100Hz @ 16kHz", "400Hz @ 48kHz",
168 "100Hz @ 8kHz", "200Hz @ 8kHz"};
169 static const char *wm8753_treble
[] = {"8kHz", "4kHz"};
170 static const char *wm8753_alc_func
[] = {"Off", "Right", "Left", "Stereo"};
171 static const char *wm8753_ng_type
[] = {"Constant PGA Gain", "Mute ADC Output"};
172 static const char *wm8753_3d_func
[] = {"Capture", "Playback"};
173 static const char *wm8753_3d_uc
[] = {"2.2kHz", "1.5kHz"};
174 static const char *wm8753_3d_lc
[] = {"200Hz", "500Hz"};
175 static const char *wm8753_deemp
[] = {"None", "32kHz", "44.1kHz", "48kHz"};
176 static const char *wm8753_mono_mix
[] = {"Stereo", "Left", "Right", "Mono"};
177 static const char *wm8753_dac_phase
[] = {"Non Inverted", "Inverted"};
178 static const char *wm8753_line_mix
[] = {"Line 1 + 2", "Line 1 - 2",
180 static const char *wm8753_mono_mux
[] = {"Line Mix", "Rx Mix"};
181 static const char *wm8753_right_mux
[] = {"Line 2", "Rx Mix"};
182 static const char *wm8753_left_mux
[] = {"Line 1", "Rx Mix"};
183 static const char *wm8753_rxmsel
[] = {"RXP - RXN", "RXP + RXN", "RXP", "RXN"};
184 static const char *wm8753_sidetone_mux
[] = {"Left PGA", "Mic 1", "Mic 2",
186 static const char *wm8753_mono2_src
[] = {"Inverted Mono 1", "Left", "Right",
188 static const char *wm8753_out3
[] = {"VREF", "ROUT2", "Left + Right"};
189 static const char *wm8753_out4
[] = {"VREF", "Capture ST", "LOUT2"};
190 static const char *wm8753_radcsel
[] = {"PGA", "Line or RXP-RXN", "Sidetone"};
191 static const char *wm8753_ladcsel
[] = {"PGA", "Line or RXP-RXN", "Line"};
192 static const char *wm8753_mono_adc
[] = {"Stereo", "Analogue Mix Left",
193 "Analogue Mix Right", "Digital Mono Mix"};
194 static const char *wm8753_adc_hp
[] = {"3.4Hz @ 48kHz", "82Hz @ 16k",
195 "82Hz @ 8kHz", "170Hz @ 8kHz"};
196 static const char *wm8753_adc_filter
[] = {"HiFi", "Voice"};
197 static const char *wm8753_mic_sel
[] = {"Mic 1", "Mic 2", "Mic 3"};
198 static const char *wm8753_dai_mode
[] = {"DAI 0", "DAI 1", "DAI 2", "DAI 3"};
199 static const char *wm8753_dat_sel
[] = {"Stereo", "Left ADC", "Right ADC",
202 static const struct soc_enum wm8753_enum
[] = {
203 SOC_ENUM_SINGLE(WM8753_BASS
, 7, 2, wm8753_base
),
204 SOC_ENUM_SINGLE(WM8753_BASS
, 4, 6, wm8753_base_filter
),
205 SOC_ENUM_SINGLE(WM8753_TREBLE
, 6, 2, wm8753_treble
),
206 SOC_ENUM_SINGLE(WM8753_ALC1
, 7, 4, wm8753_alc_func
),
207 SOC_ENUM_SINGLE(WM8753_NGATE
, 1, 2, wm8753_ng_type
),
208 SOC_ENUM_SINGLE(WM8753_3D
, 7, 2, wm8753_3d_func
),
209 SOC_ENUM_SINGLE(WM8753_3D
, 6, 2, wm8753_3d_uc
),
210 SOC_ENUM_SINGLE(WM8753_3D
, 5, 2, wm8753_3d_lc
),
211 SOC_ENUM_SINGLE(WM8753_DAC
, 1, 4, wm8753_deemp
),
212 SOC_ENUM_SINGLE(WM8753_DAC
, 4, 4, wm8753_mono_mix
),
213 SOC_ENUM_SINGLE(WM8753_DAC
, 6, 2, wm8753_dac_phase
),
214 SOC_ENUM_SINGLE(WM8753_INCTL1
, 3, 4, wm8753_line_mix
),
215 SOC_ENUM_SINGLE(WM8753_INCTL1
, 2, 2, wm8753_mono_mux
),
216 SOC_ENUM_SINGLE(WM8753_INCTL1
, 1, 2, wm8753_right_mux
),
217 SOC_ENUM_SINGLE(WM8753_INCTL1
, 0, 2, wm8753_left_mux
),
218 SOC_ENUM_SINGLE(WM8753_INCTL2
, 6, 4, wm8753_rxmsel
),
219 SOC_ENUM_SINGLE(WM8753_INCTL2
, 4, 4, wm8753_sidetone_mux
),
220 SOC_ENUM_SINGLE(WM8753_OUTCTL
, 7, 4, wm8753_mono2_src
),
221 SOC_ENUM_SINGLE(WM8753_OUTCTL
, 0, 3, wm8753_out3
),
222 SOC_ENUM_SINGLE(WM8753_ADCTL2
, 7, 3, wm8753_out4
),
223 SOC_ENUM_SINGLE(WM8753_ADCIN
, 2, 3, wm8753_radcsel
),
224 SOC_ENUM_SINGLE(WM8753_ADCIN
, 0, 3, wm8753_ladcsel
),
225 SOC_ENUM_SINGLE(WM8753_ADCIN
, 4, 4, wm8753_mono_adc
),
226 SOC_ENUM_SINGLE(WM8753_ADC
, 2, 4, wm8753_adc_hp
),
227 SOC_ENUM_SINGLE(WM8753_ADC
, 4, 2, wm8753_adc_filter
),
228 SOC_ENUM_SINGLE(WM8753_MICBIAS
, 6, 3, wm8753_mic_sel
),
229 SOC_ENUM_SINGLE(WM8753_IOCTL
, 2, 4, wm8753_dai_mode
),
230 SOC_ENUM_SINGLE(WM8753_ADC
, 7, 4, wm8753_dat_sel
),
234 static int wm8753_get_dai(struct snd_kcontrol
*kcontrol
,
235 struct snd_ctl_elem_value
*ucontrol
)
237 struct snd_soc_codec
*codec
= snd_kcontrol_chip(kcontrol
);
238 int mode
= wm8753_read_reg_cache(codec
, WM8753_IOCTL
);
240 ucontrol
->value
.integer
.value
[0] = (mode
& 0xc) >> 2;
244 static int wm8753_set_dai(struct snd_kcontrol
*kcontrol
,
245 struct snd_ctl_elem_value
*ucontrol
)
247 struct snd_soc_codec
*codec
= snd_kcontrol_chip(kcontrol
);
248 int mode
= wm8753_read_reg_cache(codec
, WM8753_IOCTL
);
250 if (((mode
&0xc) >> 2) == ucontrol
->value
.integer
.value
[0])
254 mode
|= (ucontrol
->value
.integer
.value
[0] << 2);
256 wm8753_write(codec
, WM8753_IOCTL
, mode
);
257 wm8753_set_dai_mode(codec
, ucontrol
->value
.integer
.value
[0]);
261 static const DECLARE_TLV_DB_LINEAR(rec_mix_tlv
, -1500, 600);
263 static const struct snd_kcontrol_new wm8753_snd_controls
[] = {
264 SOC_DOUBLE_R("PCM Volume", WM8753_LDAC
, WM8753_RDAC
, 0, 255, 0),
266 SOC_DOUBLE_R("ADC Capture Volume", WM8753_LADC
, WM8753_RADC
, 0, 255, 0),
268 SOC_DOUBLE_R("Headphone Playback Volume", WM8753_LOUT1V
, WM8753_ROUT1V
, 0, 127, 0),
269 SOC_DOUBLE_R("Speaker Playback Volume", WM8753_LOUT2V
, WM8753_ROUT2V
, 0, 127, 0),
271 SOC_SINGLE("Mono Playback Volume", WM8753_MOUTV
, 0, 127, 0),
273 SOC_DOUBLE_R("Bypass Playback Volume", WM8753_LOUTM1
, WM8753_ROUTM1
, 4, 7, 1),
274 SOC_DOUBLE_R("Sidetone Playback Volume", WM8753_LOUTM2
, WM8753_ROUTM2
, 4, 7, 1),
275 SOC_DOUBLE_R("Voice Playback Volume", WM8753_LOUTM2
, WM8753_ROUTM2
, 0, 7, 1),
277 SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8753_LOUT1V
, WM8753_ROUT1V
, 7, 1, 0),
278 SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8753_LOUT2V
, WM8753_ROUT2V
, 7, 1, 0),
280 SOC_SINGLE("Mono Bypass Playback Volume", WM8753_MOUTM1
, 4, 7, 1),
281 SOC_SINGLE("Mono Sidetone Playback Volume", WM8753_MOUTM2
, 4, 7, 1),
282 SOC_SINGLE("Mono Voice Playback Volume", WM8753_MOUTM2
, 4, 7, 1),
283 SOC_SINGLE("Mono Playback ZC Switch", WM8753_MOUTV
, 7, 1, 0),
285 SOC_ENUM("Bass Boost", wm8753_enum
[0]),
286 SOC_ENUM("Bass Filter", wm8753_enum
[1]),
287 SOC_SINGLE("Bass Volume", WM8753_BASS
, 0, 15, 1),
289 SOC_SINGLE("Treble Volume", WM8753_TREBLE
, 0, 15, 1),
290 SOC_ENUM("Treble Cut-off", wm8753_enum
[2]),
292 SOC_DOUBLE_TLV("Sidetone Capture Volume", WM8753_RECMIX1
, 0, 4, 7, 1, rec_mix_tlv
),
293 SOC_SINGLE_TLV("Voice Sidetone Capture Volume", WM8753_RECMIX2
, 0, 7, 1, rec_mix_tlv
),
295 SOC_DOUBLE_R("Capture Volume", WM8753_LINVOL
, WM8753_RINVOL
, 0, 63, 0),
296 SOC_DOUBLE_R("Capture ZC Switch", WM8753_LINVOL
, WM8753_RINVOL
, 6, 1, 0),
297 SOC_DOUBLE_R("Capture Switch", WM8753_LINVOL
, WM8753_RINVOL
, 7, 1, 1),
299 SOC_ENUM("Capture Filter Select", wm8753_enum
[23]),
300 SOC_ENUM("Capture Filter Cut-off", wm8753_enum
[24]),
301 SOC_SINGLE("Capture Filter Switch", WM8753_ADC
, 0, 1, 1),
303 SOC_SINGLE("ALC Capture Target Volume", WM8753_ALC1
, 0, 7, 0),
304 SOC_SINGLE("ALC Capture Max Volume", WM8753_ALC1
, 4, 7, 0),
305 SOC_ENUM("ALC Capture Function", wm8753_enum
[3]),
306 SOC_SINGLE("ALC Capture ZC Switch", WM8753_ALC2
, 8, 1, 0),
307 SOC_SINGLE("ALC Capture Hold Time", WM8753_ALC2
, 0, 15, 1),
308 SOC_SINGLE("ALC Capture Decay Time", WM8753_ALC3
, 4, 15, 1),
309 SOC_SINGLE("ALC Capture Attack Time", WM8753_ALC3
, 0, 15, 0),
310 SOC_SINGLE("ALC Capture NG Threshold", WM8753_NGATE
, 3, 31, 0),
311 SOC_ENUM("ALC Capture NG Type", wm8753_enum
[4]),
312 SOC_SINGLE("ALC Capture NG Switch", WM8753_NGATE
, 0, 1, 0),
314 SOC_ENUM("3D Function", wm8753_enum
[5]),
315 SOC_ENUM("3D Upper Cut-off", wm8753_enum
[6]),
316 SOC_ENUM("3D Lower Cut-off", wm8753_enum
[7]),
317 SOC_SINGLE("3D Volume", WM8753_3D
, 1, 15, 0),
318 SOC_SINGLE("3D Switch", WM8753_3D
, 0, 1, 0),
320 SOC_SINGLE("Capture 6dB Attenuate", WM8753_ADCTL1
, 2, 1, 0),
321 SOC_SINGLE("Playback 6dB Attenuate", WM8753_ADCTL1
, 1, 1, 0),
323 SOC_ENUM("De-emphasis", wm8753_enum
[8]),
324 SOC_ENUM("Playback Mono Mix", wm8753_enum
[9]),
325 SOC_ENUM("Playback Phase", wm8753_enum
[10]),
327 SOC_SINGLE("Mic2 Capture Volume", WM8753_INCTL1
, 7, 3, 0),
328 SOC_SINGLE("Mic1 Capture Volume", WM8753_INCTL1
, 5, 3, 0),
330 SOC_ENUM_EXT("DAI Mode", wm8753_enum
[26], wm8753_get_dai
, wm8753_set_dai
),
332 SOC_ENUM("ADC Data Select", wm8753_enum
[27]),
335 /* add non dapm controls */
336 static int wm8753_add_controls(struct snd_soc_codec
*codec
)
340 for (i
= 0; i
< ARRAY_SIZE(wm8753_snd_controls
); i
++) {
341 err
= snd_ctl_add(codec
->card
,
342 snd_soc_cnew(&wm8753_snd_controls
[i
],codec
, NULL
));
354 static const struct snd_kcontrol_new wm8753_left_mixer_controls
[] = {
355 SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_LOUTM2
, 8, 1, 0),
356 SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_LOUTM2
, 7, 1, 0),
357 SOC_DAPM_SINGLE("Left Playback Switch", WM8753_LOUTM1
, 8, 1, 0),
358 SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_LOUTM1
, 7, 1, 0),
362 static const struct snd_kcontrol_new wm8753_right_mixer_controls
[] = {
363 SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_ROUTM2
, 8, 1, 0),
364 SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_ROUTM2
, 7, 1, 0),
365 SOC_DAPM_SINGLE("Right Playback Switch", WM8753_ROUTM1
, 8, 1, 0),
366 SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_ROUTM1
, 7, 1, 0),
370 static const struct snd_kcontrol_new wm8753_mono_mixer_controls
[] = {
371 SOC_DAPM_SINGLE("Left Playback Switch", WM8753_MOUTM1
, 8, 1, 0),
372 SOC_DAPM_SINGLE("Right Playback Switch", WM8753_MOUTM2
, 8, 1, 0),
373 SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_MOUTM2
, 3, 1, 0),
374 SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_MOUTM2
, 7, 1, 0),
375 SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_MOUTM1
, 7, 1, 0),
379 static const struct snd_kcontrol_new wm8753_mono2_controls
=
380 SOC_DAPM_ENUM("Route", wm8753_enum
[17]);
383 static const struct snd_kcontrol_new wm8753_out3_controls
=
384 SOC_DAPM_ENUM("Route", wm8753_enum
[18]);
387 static const struct snd_kcontrol_new wm8753_out4_controls
=
388 SOC_DAPM_ENUM("Route", wm8753_enum
[19]);
391 static const struct snd_kcontrol_new wm8753_adc_mono_controls
=
392 SOC_DAPM_ENUM("Route", wm8753_enum
[22]);
395 static const struct snd_kcontrol_new wm8753_record_mixer_controls
[] = {
396 SOC_DAPM_SINGLE("Voice Capture Switch", WM8753_RECMIX2
, 3, 1, 0),
397 SOC_DAPM_SINGLE("Left Capture Switch", WM8753_RECMIX1
, 3, 1, 0),
398 SOC_DAPM_SINGLE("Right Capture Switch", WM8753_RECMIX1
, 7, 1, 0),
402 static const struct snd_kcontrol_new wm8753_adc_left_controls
=
403 SOC_DAPM_ENUM("Route", wm8753_enum
[21]);
406 static const struct snd_kcontrol_new wm8753_adc_right_controls
=
407 SOC_DAPM_ENUM("Route", wm8753_enum
[20]);
410 static const struct snd_kcontrol_new wm8753_mic_mux_controls
=
411 SOC_DAPM_ENUM("Route", wm8753_enum
[16]);
414 static const struct snd_kcontrol_new wm8753_alc_mixer_controls
[] = {
415 SOC_DAPM_SINGLE("Line Capture Switch", WM8753_INCTL2
, 3, 1, 0),
416 SOC_DAPM_SINGLE("Mic2 Capture Switch", WM8753_INCTL2
, 2, 1, 0),
417 SOC_DAPM_SINGLE("Mic1 Capture Switch", WM8753_INCTL2
, 1, 1, 0),
418 SOC_DAPM_SINGLE("Rx Capture Switch", WM8753_INCTL2
, 0, 1, 0),
422 static const struct snd_kcontrol_new wm8753_line_left_controls
=
423 SOC_DAPM_ENUM("Route", wm8753_enum
[14]);
426 static const struct snd_kcontrol_new wm8753_line_right_controls
=
427 SOC_DAPM_ENUM("Route", wm8753_enum
[13]);
430 static const struct snd_kcontrol_new wm8753_line_mono_controls
=
431 SOC_DAPM_ENUM("Route", wm8753_enum
[12]);
433 /* Line mux and mixer */
434 static const struct snd_kcontrol_new wm8753_line_mux_mix_controls
=
435 SOC_DAPM_ENUM("Route", wm8753_enum
[11]);
437 /* Rx mux and mixer */
438 static const struct snd_kcontrol_new wm8753_rx_mux_mix_controls
=
439 SOC_DAPM_ENUM("Route", wm8753_enum
[15]);
441 /* Mic Selector Mux */
442 static const struct snd_kcontrol_new wm8753_mic_sel_mux_controls
=
443 SOC_DAPM_ENUM("Route", wm8753_enum
[25]);
445 static const struct snd_soc_dapm_widget wm8753_dapm_widgets
[] = {
446 SND_SOC_DAPM_MICBIAS("Mic Bias", WM8753_PWR1
, 5, 0),
447 SND_SOC_DAPM_MIXER("Left Mixer", WM8753_PWR4
, 0, 0,
448 &wm8753_left_mixer_controls
[0], ARRAY_SIZE(wm8753_left_mixer_controls
)),
449 SND_SOC_DAPM_PGA("Left Out 1", WM8753_PWR3
, 8, 0, NULL
, 0),
450 SND_SOC_DAPM_PGA("Left Out 2", WM8753_PWR3
, 6, 0, NULL
, 0),
451 SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", WM8753_PWR1
, 3, 0),
452 SND_SOC_DAPM_OUTPUT("LOUT1"),
453 SND_SOC_DAPM_OUTPUT("LOUT2"),
454 SND_SOC_DAPM_MIXER("Right Mixer", WM8753_PWR4
, 1, 0,
455 &wm8753_right_mixer_controls
[0], ARRAY_SIZE(wm8753_right_mixer_controls
)),
456 SND_SOC_DAPM_PGA("Right Out 1", WM8753_PWR3
, 7, 0, NULL
, 0),
457 SND_SOC_DAPM_PGA("Right Out 2", WM8753_PWR3
, 5, 0, NULL
, 0),
458 SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", WM8753_PWR1
, 2, 0),
459 SND_SOC_DAPM_OUTPUT("ROUT1"),
460 SND_SOC_DAPM_OUTPUT("ROUT2"),
461 SND_SOC_DAPM_MIXER("Mono Mixer", WM8753_PWR4
, 2, 0,
462 &wm8753_mono_mixer_controls
[0], ARRAY_SIZE(wm8753_mono_mixer_controls
)),
463 SND_SOC_DAPM_PGA("Mono Out 1", WM8753_PWR3
, 2, 0, NULL
, 0),
464 SND_SOC_DAPM_PGA("Mono Out 2", WM8753_PWR3
, 1, 0, NULL
, 0),
465 SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", WM8753_PWR1
, 4, 0),
466 SND_SOC_DAPM_OUTPUT("MONO1"),
467 SND_SOC_DAPM_MUX("Mono 2 Mux", SND_SOC_NOPM
, 0, 0, &wm8753_mono2_controls
),
468 SND_SOC_DAPM_OUTPUT("MONO2"),
469 SND_SOC_DAPM_MIXER("Out3 Left + Right", -1, 0, 0, NULL
, 0),
470 SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM
, 0, 0, &wm8753_out3_controls
),
471 SND_SOC_DAPM_PGA("Out 3", WM8753_PWR3
, 4, 0, NULL
, 0),
472 SND_SOC_DAPM_OUTPUT("OUT3"),
473 SND_SOC_DAPM_MUX("Out4 Mux", SND_SOC_NOPM
, 0, 0, &wm8753_out4_controls
),
474 SND_SOC_DAPM_PGA("Out 4", WM8753_PWR3
, 3, 0, NULL
, 0),
475 SND_SOC_DAPM_OUTPUT("OUT4"),
476 SND_SOC_DAPM_MIXER("Playback Mixer", WM8753_PWR4
, 3, 0,
477 &wm8753_record_mixer_controls
[0],
478 ARRAY_SIZE(wm8753_record_mixer_controls
)),
479 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8753_PWR2
, 3, 0),
480 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8753_PWR2
, 2, 0),
481 SND_SOC_DAPM_MUX("Capture Left Mixer", SND_SOC_NOPM
, 0, 0,
482 &wm8753_adc_mono_controls
),
483 SND_SOC_DAPM_MUX("Capture Right Mixer", SND_SOC_NOPM
, 0, 0,
484 &wm8753_adc_mono_controls
),
485 SND_SOC_DAPM_MUX("Capture Left Mux", SND_SOC_NOPM
, 0, 0,
486 &wm8753_adc_left_controls
),
487 SND_SOC_DAPM_MUX("Capture Right Mux", SND_SOC_NOPM
, 0, 0,
488 &wm8753_adc_right_controls
),
489 SND_SOC_DAPM_MUX("Mic Sidetone Mux", SND_SOC_NOPM
, 0, 0,
490 &wm8753_mic_mux_controls
),
491 SND_SOC_DAPM_PGA("Left Capture Volume", WM8753_PWR2
, 5, 0, NULL
, 0),
492 SND_SOC_DAPM_PGA("Right Capture Volume", WM8753_PWR2
, 4, 0, NULL
, 0),
493 SND_SOC_DAPM_MIXER("ALC Mixer", WM8753_PWR2
, 6, 0,
494 &wm8753_alc_mixer_controls
[0], ARRAY_SIZE(wm8753_alc_mixer_controls
)),
495 SND_SOC_DAPM_MUX("Line Left Mux", SND_SOC_NOPM
, 0, 0,
496 &wm8753_line_left_controls
),
497 SND_SOC_DAPM_MUX("Line Right Mux", SND_SOC_NOPM
, 0, 0,
498 &wm8753_line_right_controls
),
499 SND_SOC_DAPM_MUX("Line Mono Mux", SND_SOC_NOPM
, 0, 0,
500 &wm8753_line_mono_controls
),
501 SND_SOC_DAPM_MUX("Line Mixer", WM8753_PWR2
, 0, 0,
502 &wm8753_line_mux_mix_controls
),
503 SND_SOC_DAPM_MUX("Rx Mixer", WM8753_PWR2
, 1, 0,
504 &wm8753_rx_mux_mix_controls
),
505 SND_SOC_DAPM_PGA("Mic 1 Volume", WM8753_PWR2
, 8, 0, NULL
, 0),
506 SND_SOC_DAPM_PGA("Mic 2 Volume", WM8753_PWR2
, 7, 0, NULL
, 0),
507 SND_SOC_DAPM_MUX("Mic Selection Mux", SND_SOC_NOPM
, 0, 0,
508 &wm8753_mic_sel_mux_controls
),
509 SND_SOC_DAPM_INPUT("LINE1"),
510 SND_SOC_DAPM_INPUT("LINE2"),
511 SND_SOC_DAPM_INPUT("RXP"),
512 SND_SOC_DAPM_INPUT("RXN"),
513 SND_SOC_DAPM_INPUT("ACIN"),
514 SND_SOC_DAPM_OUTPUT("ACOP"),
515 SND_SOC_DAPM_INPUT("MIC1N"),
516 SND_SOC_DAPM_INPUT("MIC1"),
517 SND_SOC_DAPM_INPUT("MIC2N"),
518 SND_SOC_DAPM_INPUT("MIC2"),
519 SND_SOC_DAPM_VMID("VREF"),
522 static const char *audio_map
[][3] = {
524 {"Left Mixer", "Left Playback Switch", "Left DAC"},
525 {"Left Mixer", "Voice Playback Switch", "Voice DAC"},
526 {"Left Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
527 {"Left Mixer", "Bypass Playback Switch", "Line Left Mux"},
530 {"Right Mixer", "Right Playback Switch", "Right DAC"},
531 {"Right Mixer", "Voice Playback Switch", "Voice DAC"},
532 {"Right Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
533 {"Right Mixer", "Bypass Playback Switch", "Line Right Mux"},
536 {"Mono Mixer", "Voice Playback Switch", "Voice DAC"},
537 {"Mono Mixer", "Left Playback Switch", "Left DAC"},
538 {"Mono Mixer", "Right Playback Switch", "Right DAC"},
539 {"Mono Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
540 {"Mono Mixer", "Bypass Playback Switch", "Line Mono Mux"},
543 {"Left Out 1", NULL
, "Left Mixer"},
544 {"Left Out 2", NULL
, "Left Mixer"},
545 {"LOUT1", NULL
, "Left Out 1"},
546 {"LOUT2", NULL
, "Left Out 2"},
549 {"Right Out 1", NULL
, "Right Mixer"},
550 {"Right Out 2", NULL
, "Right Mixer"},
551 {"ROUT1", NULL
, "Right Out 1"},
552 {"ROUT2", NULL
, "Right Out 2"},
555 {"Mono Out 1", NULL
, "Mono Mixer"},
556 {"MONO1", NULL
, "Mono Out 1"},
559 {"Mono 2 Mux", "Left + Right", "Out3 Left + Right"},
560 {"Mono 2 Mux", "Inverted Mono 1", "MONO1"},
561 {"Mono 2 Mux", "Left", "Left Mixer"},
562 {"Mono 2 Mux", "Right", "Right Mixer"},
563 {"Mono Out 2", NULL
, "Mono 2 Mux"},
564 {"MONO2", NULL
, "Mono Out 2"},
567 {"Out3 Left + Right", NULL
, "Left Mixer"},
568 {"Out3 Left + Right", NULL
, "Right Mixer"},
569 {"Out3 Mux", "VREF", "VREF"},
570 {"Out3 Mux", "Left + Right", "Out3 Left + Right"},
571 {"Out3 Mux", "ROUT2", "ROUT2"},
572 {"Out 3", NULL
, "Out3 Mux"},
573 {"OUT3", NULL
, "Out 3"},
576 {"Out4 Mux", "VREF", "VREF"},
577 {"Out4 Mux", "Capture ST", "Capture ST Mixer"},
578 {"Out4 Mux", "LOUT2", "LOUT2"},
579 {"Out 4", NULL
, "Out4 Mux"},
580 {"OUT4", NULL
, "Out 4"},
583 {"Playback Mixer", "Left Capture Switch", "Left Mixer"},
584 {"Playback Mixer", "Voice Capture Switch", "Mono Mixer"},
585 {"Playback Mixer", "Right Capture Switch", "Right Mixer"},
587 /* Mic/SideTone Mux */
588 {"Mic Sidetone Mux", "Left PGA", "Left Capture Volume"},
589 {"Mic Sidetone Mux", "Right PGA", "Right Capture Volume"},
590 {"Mic Sidetone Mux", "Mic 1", "Mic 1 Volume"},
591 {"Mic Sidetone Mux", "Mic 2", "Mic 2 Volume"},
593 /* Capture Left Mux */
594 {"Capture Left Mux", "PGA", "Left Capture Volume"},
595 {"Capture Left Mux", "Line or RXP-RXN", "Line Left Mux"},
596 {"Capture Left Mux", "Line", "LINE1"},
598 /* Capture Right Mux */
599 {"Capture Right Mux", "PGA", "Right Capture Volume"},
600 {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"},
601 {"Capture Right Mux", "Sidetone", "Capture ST Mixer"},
603 /* Mono Capture mixer-mux */
604 {"Capture Right Mixer", "Stereo", "Capture Right Mux"},
605 {"Capture Left Mixer", "Analogue Mix Left", "Capture Left Mux"},
606 {"Capture Left Mixer", "Analogue Mix Left", "Capture Right Mux"},
607 {"Capture Right Mixer", "Analogue Mix Right", "Capture Left Mux"},
608 {"Capture Right Mixer", "Analogue Mix Right", "Capture Right Mux"},
609 {"Capture Left Mixer", "Digital Mono Mix", "Capture Left Mux"},
610 {"Capture Left Mixer", "Digital Mono Mix", "Capture Right Mux"},
611 {"Capture Right Mixer", "Digital Mono Mix", "Capture Left Mux"},
612 {"Capture Right Mixer", "Digital Mono Mix", "Capture Right Mux"},
615 {"Left ADC", NULL
, "Capture Left Mixer"},
616 {"Right ADC", NULL
, "Capture Right Mixer"},
618 /* Left Capture Volume */
619 {"Left Capture Volume", NULL
, "ACIN"},
621 /* Right Capture Volume */
622 {"Right Capture Volume", NULL
, "Mic 2 Volume"},
625 {"ALC Mixer", "Line Capture Switch", "Line Mixer"},
626 {"ALC Mixer", "Mic2 Capture Switch", "Mic 2 Volume"},
627 {"ALC Mixer", "Mic1 Capture Switch", "Mic 1 Volume"},
628 {"ALC Mixer", "Rx Capture Switch", "Rx Mixer"},
631 {"Line Left Mux", "Line 1", "LINE1"},
632 {"Line Left Mux", "Rx Mix", "Rx Mixer"},
635 {"Line Right Mux", "Line 2", "LINE2"},
636 {"Line Right Mux", "Rx Mix", "Rx Mixer"},
639 {"Line Mono Mux", "Line Mix", "Line Mixer"},
640 {"Line Mono Mux", "Rx Mix", "Rx Mixer"},
643 {"Line Mixer", "Line 1 + 2", "LINE1"},
644 {"Line Mixer", "Line 1 - 2", "LINE1"},
645 {"Line Mixer", "Line 1 + 2", "LINE2"},
646 {"Line Mixer", "Line 1 - 2", "LINE2"},
647 {"Line Mixer", "Line 1", "LINE1"},
648 {"Line Mixer", "Line 2", "LINE2"},
651 {"Rx Mixer", "RXP - RXN", "RXP"},
652 {"Rx Mixer", "RXP + RXN", "RXP"},
653 {"Rx Mixer", "RXP - RXN", "RXN"},
654 {"Rx Mixer", "RXP + RXN", "RXN"},
655 {"Rx Mixer", "RXP", "RXP"},
656 {"Rx Mixer", "RXN", "RXN"},
659 {"Mic 1 Volume", NULL
, "MIC1N"},
660 {"Mic 1 Volume", NULL
, "Mic Selection Mux"},
663 {"Mic 2 Volume", NULL
, "MIC2N"},
664 {"Mic 2 Volume", NULL
, "MIC2"},
666 /* Mic Selector Mux */
667 {"Mic Selection Mux", "Mic 1", "MIC1"},
668 {"Mic Selection Mux", "Mic 2", "MIC2N"},
669 {"Mic Selection Mux", "Mic 3", "MIC2"},
672 {"ACOP", NULL
, "ALC Mixer"},
678 static int wm8753_add_widgets(struct snd_soc_codec
*codec
)
682 for (i
= 0; i
< ARRAY_SIZE(wm8753_dapm_widgets
); i
++)
683 snd_soc_dapm_new_control(codec
, &wm8753_dapm_widgets
[i
]);
685 /* set up the WM8753 audio map */
686 for (i
= 0; audio_map
[i
][0] != NULL
; i
++) {
687 snd_soc_dapm_connect_input(codec
, audio_map
[i
][0],
688 audio_map
[i
][1], audio_map
[i
][2]);
691 snd_soc_dapm_new_widgets(codec
);
702 /* The size in bits of the pll divide multiplied by 10
703 * to allow rounding later */
704 #define FIXED_PLL_SIZE ((1 << 22) * 10)
706 static void pll_factors(struct _pll_div
*pll_div
, unsigned int target
,
710 unsigned int K
, Ndiv
, Nmod
;
712 Ndiv
= target
/ source
;
716 Ndiv
= target
/ source
;
720 if ((Ndiv
< 6) || (Ndiv
> 12))
722 "WM8753 N value outwith recommended range! N = %d\n",Ndiv
);
725 Nmod
= target
% source
;
726 Kpart
= FIXED_PLL_SIZE
* (long long)Nmod
;
728 do_div(Kpart
, source
);
730 K
= Kpart
& 0xFFFFFFFF;
732 /* Check if we need to round */
736 /* Move down to proper range now rounding is done */
742 static int wm8753_set_dai_pll(struct snd_soc_codec_dai
*codec_dai
,
743 int pll_id
, unsigned int freq_in
, unsigned int freq_out
)
747 struct snd_soc_codec
*codec
= codec_dai
->codec
;
749 if (pll_id
< WM8753_PLL1
|| pll_id
> WM8753_PLL2
)
752 if (pll_id
== WM8753_PLL1
) {
755 reg
= wm8753_read_reg_cache(codec
, WM8753_CLOCK
) & 0xffef;
759 reg
= wm8753_read_reg_cache(codec
, WM8753_CLOCK
) & 0xfff7;
762 if (!freq_in
|| !freq_out
) {
764 wm8753_write(codec
, WM8753_PLL1CTL1
+ offset
, 0x0026);
765 wm8753_write(codec
, WM8753_CLOCK
, reg
);
769 struct _pll_div pll_div
;
771 pll_factors(&pll_div
, freq_out
* 8, freq_in
);
773 /* set up N and K PLL divisor ratios */
774 /* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
775 value
= (pll_div
.n
<< 5) + ((pll_div
.k
& 0x3c0000) >> 18);
776 wm8753_write(codec
, WM8753_PLL1CTL2
+ offset
, value
);
778 /* bits 8:0 = PLL_K[17:9] */
779 value
= (pll_div
.k
& 0x03fe00) >> 9;
780 wm8753_write(codec
, WM8753_PLL1CTL3
+ offset
, value
);
782 /* bits 8:0 = PLL_K[8:0] */
783 value
= pll_div
.k
& 0x0001ff;
784 wm8753_write(codec
, WM8753_PLL1CTL4
+ offset
, value
);
786 /* set PLL as input and enable */
787 wm8753_write(codec
, WM8753_PLL1CTL1
+ offset
, 0x0027 |
788 (pll_div
.div2
<< 3));
789 wm8753_write(codec
, WM8753_CLOCK
, reg
| enable
);
801 /* codec hifi mclk (after PLL) clock divider coefficients */
802 static const struct _coeff_div coeff_div
[] = {
804 {12288000, 8000, 0x6, 0x0},
805 {11289600, 8000, 0x16, 0x0},
806 {18432000, 8000, 0x7, 0x0},
807 {16934400, 8000, 0x17, 0x0},
808 {12000000, 8000, 0x6, 0x1},
811 {11289600, 11025, 0x18, 0x0},
812 {16934400, 11025, 0x19, 0x0},
813 {12000000, 11025, 0x19, 0x1},
816 {12288000, 16000, 0xa, 0x0},
817 {18432000, 16000, 0xb, 0x0},
818 {12000000, 16000, 0xa, 0x1},
821 {11289600, 22050, 0x1a, 0x0},
822 {16934400, 22050, 0x1b, 0x0},
823 {12000000, 22050, 0x1b, 0x1},
826 {12288000, 32000, 0xc, 0x0},
827 {18432000, 32000, 0xd, 0x0},
828 {12000000, 32000, 0xa, 0x1},
831 {11289600, 44100, 0x10, 0x0},
832 {16934400, 44100, 0x11, 0x0},
833 {12000000, 44100, 0x11, 0x1},
836 {12288000, 48000, 0x0, 0x0},
837 {18432000, 48000, 0x1, 0x0},
838 {12000000, 48000, 0x0, 0x1},
841 {11289600, 88200, 0x1e, 0x0},
842 {16934400, 88200, 0x1f, 0x0},
843 {12000000, 88200, 0x1f, 0x1},
846 {12288000, 96000, 0xe, 0x0},
847 {18432000, 96000, 0xf, 0x0},
848 {12000000, 96000, 0xe, 0x1},
851 static int get_coeff(int mclk
, int rate
)
855 for (i
= 0; i
< ARRAY_SIZE(coeff_div
); i
++) {
856 if (coeff_div
[i
].rate
== rate
&& coeff_div
[i
].mclk
== mclk
)
863 * Clock after PLL and dividers
865 static int wm8753_set_dai_sysclk(struct snd_soc_codec_dai
*codec_dai
,
866 int clk_id
, unsigned int freq
, int dir
)
868 struct snd_soc_codec
*codec
= codec_dai
->codec
;
869 struct wm8753_priv
*wm8753
= codec
->private_data
;
877 if (clk_id
== WM8753_MCLK
) {
878 wm8753
->sysclk
= freq
;
880 } else if (clk_id
== WM8753_PCMCLK
) {
881 wm8753
->pcmclk
= freq
;
890 * Set's ADC and Voice DAC format.
892 static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_codec_dai
*codec_dai
,
895 struct snd_soc_codec
*codec
= codec_dai
->codec
;
896 u16 voice
= wm8753_read_reg_cache(codec
, WM8753_PCM
) & 0x01ec;
898 /* interface format */
899 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
900 case SND_SOC_DAIFMT_I2S
:
903 case SND_SOC_DAIFMT_RIGHT_J
:
905 case SND_SOC_DAIFMT_LEFT_J
:
908 case SND_SOC_DAIFMT_DSP_A
:
911 case SND_SOC_DAIFMT_DSP_B
:
918 wm8753_write(codec
, WM8753_PCM
, voice
);
923 * Set PCM DAI bit size and sample rate.
925 static int wm8753_pcm_hw_params(struct snd_pcm_substream
*substream
,
926 struct snd_pcm_hw_params
*params
)
928 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
929 struct snd_soc_device
*socdev
= rtd
->socdev
;
930 struct snd_soc_codec
*codec
= socdev
->codec
;
931 struct wm8753_priv
*wm8753
= codec
->private_data
;
932 u16 voice
= wm8753_read_reg_cache(codec
, WM8753_PCM
) & 0x01f3;
933 u16 srate
= wm8753_read_reg_cache(codec
, WM8753_SRATE1
) & 0x017f;
936 switch (params_format(params
)) {
937 case SNDRV_PCM_FORMAT_S16_LE
:
939 case SNDRV_PCM_FORMAT_S20_3LE
:
942 case SNDRV_PCM_FORMAT_S24_LE
:
945 case SNDRV_PCM_FORMAT_S32_LE
:
951 if (params_rate(params
) * 384 == wm8753
->pcmclk
)
953 wm8753_write(codec
, WM8753_SRATE1
, srate
);
955 wm8753_write(codec
, WM8753_PCM
, voice
);
960 * Set's PCM dai fmt and BCLK.
962 static int wm8753_pcm_set_dai_fmt(struct snd_soc_codec_dai
*codec_dai
,
965 struct snd_soc_codec
*codec
= codec_dai
->codec
;
968 voice
= wm8753_read_reg_cache(codec
, WM8753_PCM
) & 0x011f;
969 ioctl
= wm8753_read_reg_cache(codec
, WM8753_IOCTL
) & 0x015d;
971 /* set master/slave audio interface */
972 switch (fmt
& SND_SOC_DAIFMT_MASTER_MASK
) {
973 case SND_SOC_DAIFMT_CBS_CFS
:
975 case SND_SOC_DAIFMT_CBM_CFM
:
977 case SND_SOC_DAIFMT_CBM_CFS
:
984 /* clock inversion */
985 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
986 case SND_SOC_DAIFMT_DSP_A
:
987 case SND_SOC_DAIFMT_DSP_B
:
988 /* frame inversion not valid for DSP modes */
989 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
990 case SND_SOC_DAIFMT_NB_NF
:
992 case SND_SOC_DAIFMT_IB_NF
:
999 case SND_SOC_DAIFMT_I2S
:
1000 case SND_SOC_DAIFMT_RIGHT_J
:
1001 case SND_SOC_DAIFMT_LEFT_J
:
1003 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
1004 case SND_SOC_DAIFMT_NB_NF
:
1006 case SND_SOC_DAIFMT_IB_IF
:
1009 case SND_SOC_DAIFMT_IB_NF
:
1012 case SND_SOC_DAIFMT_NB_IF
:
1023 wm8753_write(codec
, WM8753_PCM
, voice
);
1024 wm8753_write(codec
, WM8753_IOCTL
, ioctl
);
1028 static int wm8753_set_dai_clkdiv(struct snd_soc_codec_dai
*codec_dai
,
1029 int div_id
, int div
)
1031 struct snd_soc_codec
*codec
= codec_dai
->codec
;
1036 reg
= wm8753_read_reg_cache(codec
, WM8753_CLOCK
) & 0x003f;
1037 wm8753_write(codec
, WM8753_CLOCK
, reg
| div
);
1039 case WM8753_BCLKDIV
:
1040 reg
= wm8753_read_reg_cache(codec
, WM8753_SRATE2
) & 0x01c7;
1041 wm8753_write(codec
, WM8753_SRATE2
, reg
| div
);
1043 case WM8753_VXCLKDIV
:
1044 reg
= wm8753_read_reg_cache(codec
, WM8753_SRATE2
) & 0x003f;
1045 wm8753_write(codec
, WM8753_SRATE2
, reg
| div
);
1054 * Set's HiFi DAC format.
1056 static int wm8753_hdac_set_dai_fmt(struct snd_soc_codec_dai
*codec_dai
,
1059 struct snd_soc_codec
*codec
= codec_dai
->codec
;
1060 u16 hifi
= wm8753_read_reg_cache(codec
, WM8753_HIFI
) & 0x01e0;
1062 /* interface format */
1063 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
1064 case SND_SOC_DAIFMT_I2S
:
1067 case SND_SOC_DAIFMT_RIGHT_J
:
1069 case SND_SOC_DAIFMT_LEFT_J
:
1072 case SND_SOC_DAIFMT_DSP_A
:
1075 case SND_SOC_DAIFMT_DSP_B
:
1082 wm8753_write(codec
, WM8753_HIFI
, hifi
);
1087 * Set's I2S DAI format.
1089 static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec_dai
*codec_dai
,
1092 struct snd_soc_codec
*codec
= codec_dai
->codec
;
1095 hifi
= wm8753_read_reg_cache(codec
, WM8753_HIFI
) & 0x011f;
1096 ioctl
= wm8753_read_reg_cache(codec
, WM8753_IOCTL
) & 0x00ae;
1098 /* set master/slave audio interface */
1099 switch (fmt
& SND_SOC_DAIFMT_MASTER_MASK
) {
1100 case SND_SOC_DAIFMT_CBS_CFS
:
1102 case SND_SOC_DAIFMT_CBM_CFM
:
1104 case SND_SOC_DAIFMT_CBM_CFS
:
1111 /* clock inversion */
1112 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
1113 case SND_SOC_DAIFMT_DSP_A
:
1114 case SND_SOC_DAIFMT_DSP_B
:
1115 /* frame inversion not valid for DSP modes */
1116 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
1117 case SND_SOC_DAIFMT_NB_NF
:
1119 case SND_SOC_DAIFMT_IB_NF
:
1126 case SND_SOC_DAIFMT_I2S
:
1127 case SND_SOC_DAIFMT_RIGHT_J
:
1128 case SND_SOC_DAIFMT_LEFT_J
:
1130 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
1131 case SND_SOC_DAIFMT_NB_NF
:
1133 case SND_SOC_DAIFMT_IB_IF
:
1136 case SND_SOC_DAIFMT_IB_NF
:
1139 case SND_SOC_DAIFMT_NB_IF
:
1150 wm8753_write(codec
, WM8753_HIFI
, hifi
);
1151 wm8753_write(codec
, WM8753_IOCTL
, ioctl
);
1156 * Set PCM DAI bit size and sample rate.
1158 static int wm8753_i2s_hw_params(struct snd_pcm_substream
*substream
,
1159 struct snd_pcm_hw_params
*params
)
1161 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
1162 struct snd_soc_device
*socdev
= rtd
->socdev
;
1163 struct snd_soc_codec
*codec
= socdev
->codec
;
1164 struct wm8753_priv
*wm8753
= codec
->private_data
;
1165 u16 srate
= wm8753_read_reg_cache(codec
, WM8753_SRATE1
) & 0x01c0;
1166 u16 hifi
= wm8753_read_reg_cache(codec
, WM8753_HIFI
) & 0x01f3;
1169 /* is digital filter coefficient valid ? */
1170 coeff
= get_coeff(wm8753
->sysclk
, params_rate(params
));
1172 printk(KERN_ERR
"wm8753 invalid MCLK or rate\n");
1175 wm8753_write(codec
, WM8753_SRATE1
, srate
| (coeff_div
[coeff
].sr
<< 1) |
1176 coeff_div
[coeff
].usb
);
1179 switch (params_format(params
)) {
1180 case SNDRV_PCM_FORMAT_S16_LE
:
1182 case SNDRV_PCM_FORMAT_S20_3LE
:
1185 case SNDRV_PCM_FORMAT_S24_LE
:
1188 case SNDRV_PCM_FORMAT_S32_LE
:
1193 wm8753_write(codec
, WM8753_HIFI
, hifi
);
1197 static int wm8753_mode1v_set_dai_fmt(struct snd_soc_codec_dai
*codec_dai
,
1200 struct snd_soc_codec
*codec
= codec_dai
->codec
;
1203 /* set clk source as pcmclk */
1204 clock
= wm8753_read_reg_cache(codec
, WM8753_CLOCK
) & 0xfffb;
1205 wm8753_write(codec
, WM8753_CLOCK
, clock
);
1207 if (wm8753_vdac_adc_set_dai_fmt(codec_dai
, fmt
) < 0)
1209 return wm8753_pcm_set_dai_fmt(codec_dai
, fmt
);
1212 static int wm8753_mode1h_set_dai_fmt(struct snd_soc_codec_dai
*codec_dai
,
1215 if (wm8753_hdac_set_dai_fmt(codec_dai
, fmt
) < 0)
1217 return wm8753_i2s_set_dai_fmt(codec_dai
, fmt
);
1220 static int wm8753_mode2_set_dai_fmt(struct snd_soc_codec_dai
*codec_dai
,
1223 struct snd_soc_codec
*codec
= codec_dai
->codec
;
1226 /* set clk source as pcmclk */
1227 clock
= wm8753_read_reg_cache(codec
, WM8753_CLOCK
) & 0xfffb;
1228 wm8753_write(codec
, WM8753_CLOCK
, clock
);
1230 if (wm8753_vdac_adc_set_dai_fmt(codec_dai
, fmt
) < 0)
1232 return wm8753_i2s_set_dai_fmt(codec_dai
, fmt
);
1235 static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_codec_dai
*codec_dai
,
1238 struct snd_soc_codec
*codec
= codec_dai
->codec
;
1241 /* set clk source as mclk */
1242 clock
= wm8753_read_reg_cache(codec
, WM8753_CLOCK
) & 0xfffb;
1243 wm8753_write(codec
, WM8753_CLOCK
, clock
| 0x4);
1245 if (wm8753_hdac_set_dai_fmt(codec_dai
, fmt
) < 0)
1247 if (wm8753_vdac_adc_set_dai_fmt(codec_dai
, fmt
) < 0)
1249 return wm8753_i2s_set_dai_fmt(codec_dai
, fmt
);
1252 static int wm8753_mute(struct snd_soc_codec_dai
*dai
, int mute
)
1254 struct snd_soc_codec
*codec
= dai
->codec
;
1255 u16 mute_reg
= wm8753_read_reg_cache(codec
, WM8753_DAC
) & 0xfff7;
1257 /* the digital mute covers the HiFi and Voice DAC's on the WM8753.
1258 * make sure we check if they are not both active when we mute */
1259 if (mute
&& dai
->id
== 1) {
1260 if (!wm8753_dai
[WM8753_DAI_VOICE
].playback
.active
||
1261 !wm8753_dai
[WM8753_DAI_HIFI
].playback
.active
)
1262 wm8753_write(codec
, WM8753_DAC
, mute_reg
| 0x8);
1265 wm8753_write(codec
, WM8753_DAC
, mute_reg
| 0x8);
1267 wm8753_write(codec
, WM8753_DAC
, mute_reg
);
1273 static int wm8753_dapm_event(struct snd_soc_codec
*codec
, int event
)
1275 u16 pwr_reg
= wm8753_read_reg_cache(codec
, WM8753_PWR1
) & 0xfe3e;
1278 case SNDRV_CTL_POWER_D0
: /* full On */
1279 /* set vmid to 50k and unmute dac */
1280 wm8753_write(codec
, WM8753_PWR1
, pwr_reg
| 0x00c0);
1282 case SNDRV_CTL_POWER_D1
: /* partial On */
1283 case SNDRV_CTL_POWER_D2
: /* partial On */
1284 /* set vmid to 5k for quick power up */
1285 wm8753_write(codec
, WM8753_PWR1
, pwr_reg
| 0x01c1);
1287 case SNDRV_CTL_POWER_D3hot
: /* Off, with power */
1288 /* mute dac and set vmid to 500k, enable VREF */
1289 wm8753_write(codec
, WM8753_PWR1
, pwr_reg
| 0x0141);
1291 case SNDRV_CTL_POWER_D3cold
: /* Off, without power */
1292 wm8753_write(codec
, WM8753_PWR1
, 0x0001);
1295 codec
->dapm_state
= event
;
1299 #define WM8753_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
1300 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
1301 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
1303 #define WM8753_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1304 SNDRV_PCM_FMTBIT_S24_LE)
1307 * The WM8753 supports upto 4 different and mutually exclusive DAI
1308 * configurations. This gives 2 PCM's available for use, hifi and voice.
1309 * NOTE: The Voice PCM cannot play or capture audio to the CPU as it's DAI
1310 * is connected between the wm8753 and a BT codec or GSM modem.
1312 * 1. Voice over PCM DAI - HIFI DAC over HIFI DAI
1313 * 2. Voice over HIFI DAI - HIFI disabled
1314 * 3. Voice disabled - HIFI over HIFI
1315 * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture
1317 static const struct snd_soc_codec_dai wm8753_all_dai
[] = {
1318 /* DAI HiFi mode 1 */
1319 { .name
= "WM8753 HiFi",
1322 .stream_name
= "HiFi Playback",
1325 .rates
= WM8753_RATES
,
1326 .formats
= WM8753_FORMATS
,},
1327 .capture
= { /* dummy for fast DAI switching */
1328 .stream_name
= "Capture",
1331 .rates
= WM8753_RATES
,
1332 .formats
= WM8753_FORMATS
,},
1334 .hw_params
= wm8753_i2s_hw_params
,},
1336 .digital_mute
= wm8753_mute
,
1337 .set_fmt
= wm8753_mode1h_set_dai_fmt
,
1338 .set_clkdiv
= wm8753_set_dai_clkdiv
,
1339 .set_pll
= wm8753_set_dai_pll
,
1340 .set_sysclk
= wm8753_set_dai_sysclk
,
1343 /* DAI Voice mode 1 */
1344 { .name
= "WM8753 Voice",
1347 .stream_name
= "Voice Playback",
1350 .rates
= WM8753_RATES
,
1351 .formats
= WM8753_FORMATS
,},
1353 .stream_name
= "Capture",
1356 .rates
= WM8753_RATES
,
1357 .formats
= WM8753_FORMATS
,},
1359 .hw_params
= wm8753_pcm_hw_params
,},
1361 .digital_mute
= wm8753_mute
,
1362 .set_fmt
= wm8753_mode1v_set_dai_fmt
,
1363 .set_clkdiv
= wm8753_set_dai_clkdiv
,
1364 .set_pll
= wm8753_set_dai_pll
,
1365 .set_sysclk
= wm8753_set_dai_sysclk
,
1368 /* DAI HiFi mode 2 - dummy */
1369 { .name
= "WM8753 HiFi",
1372 /* DAI Voice mode 2 */
1373 { .name
= "WM8753 Voice",
1376 .stream_name
= "Voice Playback",
1379 .rates
= WM8753_RATES
,
1380 .formats
= WM8753_FORMATS
,},
1382 .stream_name
= "Capture",
1385 .rates
= WM8753_RATES
,
1386 .formats
= WM8753_FORMATS
,},
1388 .hw_params
= wm8753_pcm_hw_params
,},
1390 .digital_mute
= wm8753_mute
,
1391 .set_fmt
= wm8753_mode2_set_dai_fmt
,
1392 .set_clkdiv
= wm8753_set_dai_clkdiv
,
1393 .set_pll
= wm8753_set_dai_pll
,
1394 .set_sysclk
= wm8753_set_dai_sysclk
,
1397 /* DAI HiFi mode 3 */
1398 { .name
= "WM8753 HiFi",
1401 .stream_name
= "HiFi Playback",
1404 .rates
= WM8753_RATES
,
1405 .formats
= WM8753_FORMATS
,},
1407 .stream_name
= "Capture",
1410 .rates
= WM8753_RATES
,
1411 .formats
= WM8753_FORMATS
,},
1413 .hw_params
= wm8753_i2s_hw_params
,},
1415 .digital_mute
= wm8753_mute
,
1416 .set_fmt
= wm8753_mode3_4_set_dai_fmt
,
1417 .set_clkdiv
= wm8753_set_dai_clkdiv
,
1418 .set_pll
= wm8753_set_dai_pll
,
1419 .set_sysclk
= wm8753_set_dai_sysclk
,
1422 /* DAI Voice mode 3 - dummy */
1423 { .name
= "WM8753 Voice",
1426 /* DAI HiFi mode 4 */
1427 { .name
= "WM8753 HiFi",
1430 .stream_name
= "HiFi Playback",
1433 .rates
= WM8753_RATES
,
1434 .formats
= WM8753_FORMATS
,},
1436 .stream_name
= "Capture",
1439 .rates
= WM8753_RATES
,
1440 .formats
= WM8753_FORMATS
,},
1442 .hw_params
= wm8753_i2s_hw_params
,},
1444 .digital_mute
= wm8753_mute
,
1445 .set_fmt
= wm8753_mode3_4_set_dai_fmt
,
1446 .set_clkdiv
= wm8753_set_dai_clkdiv
,
1447 .set_pll
= wm8753_set_dai_pll
,
1448 .set_sysclk
= wm8753_set_dai_sysclk
,
1451 /* DAI Voice mode 4 - dummy */
1452 { .name
= "WM8753 Voice",
1457 struct snd_soc_codec_dai wm8753_dai
[2];
1458 EXPORT_SYMBOL_GPL(wm8753_dai
);
1460 static void wm8753_set_dai_mode(struct snd_soc_codec
*codec
, unsigned int mode
)
1463 int playback_active
, capture_active
, codec_active
, pop_wait
;
1466 playback_active
= wm8753_dai
[0].playback
.active
;
1467 capture_active
= wm8753_dai
[0].capture
.active
;
1468 codec_active
= wm8753_dai
[0].active
;
1469 private_data
= wm8753_dai
[0].private_data
;
1470 pop_wait
= wm8753_dai
[0].pop_wait
;
1471 wm8753_dai
[0] = wm8753_all_dai
[mode
<< 1];
1472 wm8753_dai
[0].playback
.active
= playback_active
;
1473 wm8753_dai
[0].capture
.active
= capture_active
;
1474 wm8753_dai
[0].active
= codec_active
;
1475 wm8753_dai
[0].private_data
= private_data
;
1476 wm8753_dai
[0].pop_wait
= pop_wait
;
1478 playback_active
= wm8753_dai
[1].playback
.active
;
1479 capture_active
= wm8753_dai
[1].capture
.active
;
1480 codec_active
= wm8753_dai
[1].active
;
1481 private_data
= wm8753_dai
[1].private_data
;
1482 pop_wait
= wm8753_dai
[1].pop_wait
;
1483 wm8753_dai
[1] = wm8753_all_dai
[(mode
<< 1) + 1];
1484 wm8753_dai
[1].playback
.active
= playback_active
;
1485 wm8753_dai
[1].capture
.active
= capture_active
;
1486 wm8753_dai
[1].active
= codec_active
;
1487 wm8753_dai
[1].private_data
= private_data
;
1488 wm8753_dai
[1].pop_wait
= pop_wait
;
1490 wm8753_dai
[0].codec
= codec
;
1491 wm8753_dai
[1].codec
= codec
;
1494 static void wm8753_work(struct work_struct
*work
)
1496 struct snd_soc_codec
*codec
=
1497 container_of(work
, struct snd_soc_codec
, delayed_work
.work
);
1498 wm8753_dapm_event(codec
, codec
->dapm_state
);
1501 static int wm8753_suspend(struct platform_device
*pdev
, pm_message_t state
)
1503 struct snd_soc_device
*socdev
= platform_get_drvdata(pdev
);
1504 struct snd_soc_codec
*codec
= socdev
->codec
;
1506 /* we only need to suspend if we are a valid card */
1510 wm8753_dapm_event(codec
, SNDRV_CTL_POWER_D3cold
);
1514 static int wm8753_resume(struct platform_device
*pdev
)
1516 struct snd_soc_device
*socdev
= platform_get_drvdata(pdev
);
1517 struct snd_soc_codec
*codec
= socdev
->codec
;
1520 u16
*cache
= codec
->reg_cache
;
1522 /* we only need to resume if we are a valid card */
1526 /* Sync reg_cache with the hardware */
1527 for (i
= 0; i
< ARRAY_SIZE(wm8753_reg
); i
++) {
1528 if (i
+ 1 == WM8753_RESET
)
1530 data
[0] = ((i
+ 1) << 1) | ((cache
[i
] >> 8) & 0x0001);
1531 data
[1] = cache
[i
] & 0x00ff;
1532 codec
->hw_write(codec
->control_data
, data
, 2);
1535 wm8753_dapm_event(codec
, SNDRV_CTL_POWER_D3hot
);
1537 /* charge wm8753 caps */
1538 if (codec
->suspend_dapm_state
== SNDRV_CTL_POWER_D0
) {
1539 wm8753_dapm_event(codec
, SNDRV_CTL_POWER_D2
);
1540 codec
->dapm_state
= SNDRV_CTL_POWER_D0
;
1541 schedule_delayed_work(&codec
->delayed_work
,
1542 msecs_to_jiffies(caps_charge
));
1549 * initialise the WM8753 driver
1550 * register the mixer and dsp interfaces with the kernel
1552 static int wm8753_init(struct snd_soc_device
*socdev
)
1554 struct snd_soc_codec
*codec
= socdev
->codec
;
1557 codec
->name
= "WM8753";
1558 codec
->owner
= THIS_MODULE
;
1559 codec
->read
= wm8753_read_reg_cache
;
1560 codec
->write
= wm8753_write
;
1561 codec
->dapm_event
= wm8753_dapm_event
;
1562 codec
->dai
= wm8753_dai
;
1564 codec
->reg_cache_size
= sizeof(wm8753_reg
);
1565 codec
->reg_cache
= kmemdup(wm8753_reg
, sizeof(wm8753_reg
), GFP_KERNEL
);
1567 if (codec
->reg_cache
== NULL
)
1570 wm8753_set_dai_mode(codec
, 0);
1572 wm8753_reset(codec
);
1575 ret
= snd_soc_new_pcms(socdev
, SNDRV_DEFAULT_IDX1
, SNDRV_DEFAULT_STR1
);
1577 printk(KERN_ERR
"wm8753: failed to create pcms\n");
1581 /* charge output caps */
1582 wm8753_dapm_event(codec
, SNDRV_CTL_POWER_D2
);
1583 codec
->dapm_state
= SNDRV_CTL_POWER_D3hot
;
1584 schedule_delayed_work(&codec
->delayed_work
,
1585 msecs_to_jiffies(caps_charge
));
1587 /* set the update bits */
1588 reg
= wm8753_read_reg_cache(codec
, WM8753_LDAC
);
1589 wm8753_write(codec
, WM8753_LDAC
, reg
| 0x0100);
1590 reg
= wm8753_read_reg_cache(codec
, WM8753_RDAC
);
1591 wm8753_write(codec
, WM8753_RDAC
, reg
| 0x0100);
1592 reg
= wm8753_read_reg_cache(codec
, WM8753_LADC
);
1593 wm8753_write(codec
, WM8753_LADC
, reg
| 0x0100);
1594 reg
= wm8753_read_reg_cache(codec
, WM8753_RADC
);
1595 wm8753_write(codec
, WM8753_RADC
, reg
| 0x0100);
1596 reg
= wm8753_read_reg_cache(codec
, WM8753_LOUT1V
);
1597 wm8753_write(codec
, WM8753_LOUT1V
, reg
| 0x0100);
1598 reg
= wm8753_read_reg_cache(codec
, WM8753_ROUT1V
);
1599 wm8753_write(codec
, WM8753_ROUT1V
, reg
| 0x0100);
1600 reg
= wm8753_read_reg_cache(codec
, WM8753_LOUT2V
);
1601 wm8753_write(codec
, WM8753_LOUT2V
, reg
| 0x0100);
1602 reg
= wm8753_read_reg_cache(codec
, WM8753_ROUT2V
);
1603 wm8753_write(codec
, WM8753_ROUT2V
, reg
| 0x0100);
1604 reg
= wm8753_read_reg_cache(codec
, WM8753_LINVOL
);
1605 wm8753_write(codec
, WM8753_LINVOL
, reg
| 0x0100);
1606 reg
= wm8753_read_reg_cache(codec
, WM8753_RINVOL
);
1607 wm8753_write(codec
, WM8753_RINVOL
, reg
| 0x0100);
1609 wm8753_add_controls(codec
);
1610 wm8753_add_widgets(codec
);
1611 ret
= snd_soc_register_card(socdev
);
1613 printk(KERN_ERR
"wm8753: failed to register card\n");
1619 snd_soc_free_pcms(socdev
);
1620 snd_soc_dapm_free(socdev
);
1622 kfree(codec
->reg_cache
);
1626 /* If the i2c layer weren't so broken, we could pass this kind of data
1628 static struct snd_soc_device
*wm8753_socdev
;
1630 #if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
1633 * WM8753 2 wire address is determined by GPIO5
1634 * state during powerup.
1638 static unsigned short normal_i2c
[] = { 0, I2C_CLIENT_END
};
1640 /* Magic definition of all other variables and things */
1643 static struct i2c_driver wm8753_i2c_driver
;
1644 static struct i2c_client client_template
;
1646 static int wm8753_codec_probe(struct i2c_adapter
*adap
, int addr
, int kind
)
1648 struct snd_soc_device
*socdev
= wm8753_socdev
;
1649 struct wm8753_setup_data
*setup
= socdev
->codec_data
;
1650 struct snd_soc_codec
*codec
= socdev
->codec
;
1651 struct i2c_client
*i2c
;
1654 if (addr
!= setup
->i2c_address
)
1657 client_template
.adapter
= adap
;
1658 client_template
.addr
= addr
;
1660 i2c
= kmemdup(&client_template
, sizeof(client_template
), GFP_KERNEL
);
1665 i2c_set_clientdata(i2c
, codec
);
1666 codec
->control_data
= i2c
;
1668 ret
= i2c_attach_client(i2c
);
1670 err("failed to attach codec at addr %x\n", addr
);
1674 ret
= wm8753_init(socdev
);
1676 err("failed to initialise WM8753\n");
1688 static int wm8753_i2c_detach(struct i2c_client
*client
)
1690 struct snd_soc_codec
*codec
= i2c_get_clientdata(client
);
1691 i2c_detach_client(client
);
1692 kfree(codec
->reg_cache
);
1697 static int wm8753_i2c_attach(struct i2c_adapter
*adap
)
1699 return i2c_probe(adap
, &addr_data
, wm8753_codec_probe
);
1702 /* corgi i2c codec control layer */
1703 static struct i2c_driver wm8753_i2c_driver
= {
1705 .name
= "WM8753 I2C Codec",
1706 .owner
= THIS_MODULE
,
1708 .id
= I2C_DRIVERID_WM8753
,
1709 .attach_adapter
= wm8753_i2c_attach
,
1710 .detach_client
= wm8753_i2c_detach
,
1714 static struct i2c_client client_template
= {
1716 .driver
= &wm8753_i2c_driver
,
1720 static int wm8753_probe(struct platform_device
*pdev
)
1722 struct snd_soc_device
*socdev
= platform_get_drvdata(pdev
);
1723 struct wm8753_setup_data
*setup
;
1724 struct snd_soc_codec
*codec
;
1725 struct wm8753_priv
*wm8753
;
1728 info("WM8753 Audio Codec %s", WM8753_VERSION
);
1730 setup
= socdev
->codec_data
;
1731 codec
= kzalloc(sizeof(struct snd_soc_codec
), GFP_KERNEL
);
1735 wm8753
= kzalloc(sizeof(struct wm8753_priv
), GFP_KERNEL
);
1736 if (wm8753
== NULL
) {
1741 codec
->private_data
= wm8753
;
1742 socdev
->codec
= codec
;
1743 mutex_init(&codec
->mutex
);
1744 INIT_LIST_HEAD(&codec
->dapm_widgets
);
1745 INIT_LIST_HEAD(&codec
->dapm_paths
);
1746 wm8753_socdev
= socdev
;
1747 INIT_DELAYED_WORK(&codec
->delayed_work
, wm8753_work
);
1749 #if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
1750 if (setup
->i2c_address
) {
1751 normal_i2c
[0] = setup
->i2c_address
;
1752 codec
->hw_write
= (hw_write_t
)i2c_master_send
;
1753 ret
= i2c_add_driver(&wm8753_i2c_driver
);
1755 printk(KERN_ERR
"can't add i2c driver");
1758 /* Add other interfaces here */
1764 * This function forces any delayed work to be queued and run.
1766 static int run_delayed_work(struct delayed_work
*dwork
)
1770 /* cancel any work waiting to be queued. */
1771 ret
= cancel_delayed_work(dwork
);
1773 /* if there was any work waiting then we run it now and
1774 * wait for it's completion */
1776 schedule_delayed_work(dwork
, 0);
1777 flush_scheduled_work();
1782 /* power down chip */
1783 static int wm8753_remove(struct platform_device
*pdev
)
1785 struct snd_soc_device
*socdev
= platform_get_drvdata(pdev
);
1786 struct snd_soc_codec
*codec
= socdev
->codec
;
1788 if (codec
->control_data
)
1789 wm8753_dapm_event(codec
, SNDRV_CTL_POWER_D3cold
);
1790 run_delayed_work(&codec
->delayed_work
);
1791 snd_soc_free_pcms(socdev
);
1792 snd_soc_dapm_free(socdev
);
1793 #if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
1794 i2c_del_driver(&wm8753_i2c_driver
);
1796 kfree(codec
->private_data
);
1802 struct snd_soc_codec_device soc_codec_dev_wm8753
= {
1803 .probe
= wm8753_probe
,
1804 .remove
= wm8753_remove
,
1805 .suspend
= wm8753_suspend
,
1806 .resume
= wm8753_resume
,
1809 EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753
);
1811 MODULE_DESCRIPTION("ASoC WM8753 driver");
1812 MODULE_AUTHOR("Liam Girdwood");
1813 MODULE_LICENSE("GPL");