Merge branch 'x86-amd-nb-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[deliverable/linux.git] / sound / soc / codecs / wm8753.c
CommitLineData
1f53aee0
LG
1/*
2 * wm8753.c -- WM8753 ALSA Soc Audio driver
3 *
4 * Copyright 2003 Wolfson Microelectronics PLC.
d331124d 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
1f53aee0
LG
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 * Notes:
13 * The WM8753 is a low power, high quality stereo codec with integrated PCM
14 * codec designed for portable digital telephony applications.
15 *
16 * Dual DAI:-
17 *
18 * This driver support 2 DAI PCM's. This makes the default PCM available for
19 * HiFi audio (e.g. MP3, ogg) playback/capture and the other PCM available for
20 * voice.
21 *
22 * Please note that the voice PCM can be connected directly to a Bluetooth
23 * codec or GSM modem and thus cannot be read or written to, although it is
24 * available to be configured with snd_hw_params(), etc and kcontrols in the
25 * normal alsa manner.
26 *
27 * Fast DAI switching:-
28 *
29 * The driver can now fast switch between the DAI configurations via a
30 * an alsa kcontrol. This allows the PCM to remain open.
31 *
32 */
33
34#include <linux/module.h>
35#include <linux/moduleparam.h>
1f53aee0
LG
36#include <linux/kernel.h>
37#include <linux/init.h>
38#include <linux/delay.h>
39#include <linux/pm.h>
40#include <linux/i2c.h>
41#include <linux/platform_device.h>
dd0c0c80 42#include <linux/spi/spi.h>
5a0e3ad6 43#include <linux/slab.h>
1f53aee0
LG
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>
2d6a4ac9 50#include <sound/tlv.h>
1f53aee0
LG
51#include <asm/div64.h>
52
53#include "wm8753.h"
54
1f53aee0
LG
55static int caps_charge = 2000;
56module_param(caps_charge, int, 0);
57MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)");
58
59static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
f0fba2ad 60 struct snd_soc_dai *dai, unsigned int hifi);
1f53aee0 61
1f53aee0
LG
62/*
63 * wm8753 register cache
64 * We can't read the WM8753 register space when we
65 * are using 2 wire for device control, so we cache them instead.
66 */
67static const u16 wm8753_reg[] = {
776065e3
LPC
68 0x0000, 0x0008, 0x0000, 0x000a,
69 0x000a, 0x0033, 0x0000, 0x0007,
70 0x00ff, 0x00ff, 0x000f, 0x000f,
71 0x007b, 0x0000, 0x0032, 0x0000,
72 0x00c3, 0x00c3, 0x00c0, 0x0000,
1f53aee0
LG
73 0x0000, 0x0000, 0x0000, 0x0000,
74 0x0000, 0x0000, 0x0000, 0x0000,
1f53aee0 75 0x0000, 0x0000, 0x0000, 0x0000,
776065e3
LPC
76 0x0055, 0x0005, 0x0050, 0x0055,
77 0x0050, 0x0055, 0x0050, 0x0055,
78 0x0079, 0x0079, 0x0079, 0x0079,
79 0x0079, 0x0000, 0x0000, 0x0000,
80 0x0000, 0x0097, 0x0097, 0x0000,
81 0x0004, 0x0000, 0x0083, 0x0024,
82 0x01ba, 0x0000, 0x0083, 0x0024,
83 0x01ba, 0x0000, 0x0000, 0x0000
1f53aee0
LG
84};
85
c2bac160
MB
86/* codec private data */
87struct wm8753_priv {
f0fba2ad 88 enum snd_soc_control_type control_type;
c2bac160
MB
89 unsigned int sysclk;
90 unsigned int pcmclk;
f0fba2ad 91 int dai_func;
c2bac160
MB
92};
93
776065e3 94#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0)
1f53aee0
LG
95
96/*
97 * WM8753 Controls
98 */
99static const char *wm8753_base[] = {"Linear Control", "Adaptive Boost"};
100static const char *wm8753_base_filter[] =
101 {"130Hz @ 48kHz", "200Hz @ 48kHz", "100Hz @ 16kHz", "400Hz @ 48kHz",
102 "100Hz @ 8kHz", "200Hz @ 8kHz"};
103static const char *wm8753_treble[] = {"8kHz", "4kHz"};
104static const char *wm8753_alc_func[] = {"Off", "Right", "Left", "Stereo"};
105static const char *wm8753_ng_type[] = {"Constant PGA Gain", "Mute ADC Output"};
106static const char *wm8753_3d_func[] = {"Capture", "Playback"};
107static const char *wm8753_3d_uc[] = {"2.2kHz", "1.5kHz"};
108static const char *wm8753_3d_lc[] = {"200Hz", "500Hz"};
109static const char *wm8753_deemp[] = {"None", "32kHz", "44.1kHz", "48kHz"};
110static const char *wm8753_mono_mix[] = {"Stereo", "Left", "Right", "Mono"};
111static const char *wm8753_dac_phase[] = {"Non Inverted", "Inverted"};
112static const char *wm8753_line_mix[] = {"Line 1 + 2", "Line 1 - 2",
113 "Line 1", "Line 2"};
114static const char *wm8753_mono_mux[] = {"Line Mix", "Rx Mix"};
115static const char *wm8753_right_mux[] = {"Line 2", "Rx Mix"};
116static const char *wm8753_left_mux[] = {"Line 1", "Rx Mix"};
117static const char *wm8753_rxmsel[] = {"RXP - RXN", "RXP + RXN", "RXP", "RXN"};
118static const char *wm8753_sidetone_mux[] = {"Left PGA", "Mic 1", "Mic 2",
119 "Right PGA"};
120static const char *wm8753_mono2_src[] = {"Inverted Mono 1", "Left", "Right",
121 "Left + Right"};
122static const char *wm8753_out3[] = {"VREF", "ROUT2", "Left + Right"};
123static const char *wm8753_out4[] = {"VREF", "Capture ST", "LOUT2"};
124static const char *wm8753_radcsel[] = {"PGA", "Line or RXP-RXN", "Sidetone"};
125static const char *wm8753_ladcsel[] = {"PGA", "Line or RXP-RXN", "Line"};
126static const char *wm8753_mono_adc[] = {"Stereo", "Analogue Mix Left",
127 "Analogue Mix Right", "Digital Mono Mix"};
128static const char *wm8753_adc_hp[] = {"3.4Hz @ 48kHz", "82Hz @ 16k",
129 "82Hz @ 8kHz", "170Hz @ 8kHz"};
130static const char *wm8753_adc_filter[] = {"HiFi", "Voice"};
131static const char *wm8753_mic_sel[] = {"Mic 1", "Mic 2", "Mic 3"};
132static const char *wm8753_dai_mode[] = {"DAI 0", "DAI 1", "DAI 2", "DAI 3"};
133static const char *wm8753_dat_sel[] = {"Stereo", "Left ADC", "Right ADC",
134 "Channel Swap"};
ae092c9e 135static const char *wm8753_rout2_phase[] = {"Non Inverted", "Inverted"};
1f53aee0
LG
136
137static const struct soc_enum wm8753_enum[] = {
138SOC_ENUM_SINGLE(WM8753_BASS, 7, 2, wm8753_base),
139SOC_ENUM_SINGLE(WM8753_BASS, 4, 6, wm8753_base_filter),
140SOC_ENUM_SINGLE(WM8753_TREBLE, 6, 2, wm8753_treble),
141SOC_ENUM_SINGLE(WM8753_ALC1, 7, 4, wm8753_alc_func),
142SOC_ENUM_SINGLE(WM8753_NGATE, 1, 2, wm8753_ng_type),
143SOC_ENUM_SINGLE(WM8753_3D, 7, 2, wm8753_3d_func),
144SOC_ENUM_SINGLE(WM8753_3D, 6, 2, wm8753_3d_uc),
145SOC_ENUM_SINGLE(WM8753_3D, 5, 2, wm8753_3d_lc),
146SOC_ENUM_SINGLE(WM8753_DAC, 1, 4, wm8753_deemp),
147SOC_ENUM_SINGLE(WM8753_DAC, 4, 4, wm8753_mono_mix),
148SOC_ENUM_SINGLE(WM8753_DAC, 6, 2, wm8753_dac_phase),
149SOC_ENUM_SINGLE(WM8753_INCTL1, 3, 4, wm8753_line_mix),
150SOC_ENUM_SINGLE(WM8753_INCTL1, 2, 2, wm8753_mono_mux),
151SOC_ENUM_SINGLE(WM8753_INCTL1, 1, 2, wm8753_right_mux),
152SOC_ENUM_SINGLE(WM8753_INCTL1, 0, 2, wm8753_left_mux),
153SOC_ENUM_SINGLE(WM8753_INCTL2, 6, 4, wm8753_rxmsel),
154SOC_ENUM_SINGLE(WM8753_INCTL2, 4, 4, wm8753_sidetone_mux),
155SOC_ENUM_SINGLE(WM8753_OUTCTL, 7, 4, wm8753_mono2_src),
156SOC_ENUM_SINGLE(WM8753_OUTCTL, 0, 3, wm8753_out3),
157SOC_ENUM_SINGLE(WM8753_ADCTL2, 7, 3, wm8753_out4),
158SOC_ENUM_SINGLE(WM8753_ADCIN, 2, 3, wm8753_radcsel),
159SOC_ENUM_SINGLE(WM8753_ADCIN, 0, 3, wm8753_ladcsel),
160SOC_ENUM_SINGLE(WM8753_ADCIN, 4, 4, wm8753_mono_adc),
161SOC_ENUM_SINGLE(WM8753_ADC, 2, 4, wm8753_adc_hp),
162SOC_ENUM_SINGLE(WM8753_ADC, 4, 2, wm8753_adc_filter),
163SOC_ENUM_SINGLE(WM8753_MICBIAS, 6, 3, wm8753_mic_sel),
164SOC_ENUM_SINGLE(WM8753_IOCTL, 2, 4, wm8753_dai_mode),
165SOC_ENUM_SINGLE(WM8753_ADC, 7, 4, wm8753_dat_sel),
ae092c9e 166SOC_ENUM_SINGLE(WM8753_OUTCTL, 2, 2, wm8753_rout2_phase),
1f53aee0
LG
167};
168
169
170static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
171 struct snd_ctl_elem_value *ucontrol)
172{
173 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
776065e3 174 int mode = snd_soc_read(codec, WM8753_IOCTL);
1f53aee0
LG
175
176 ucontrol->value.integer.value[0] = (mode & 0xc) >> 2;
177 return 0;
178}
179
180static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
181 struct snd_ctl_elem_value *ucontrol)
182{
183 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
776065e3 184 int mode = snd_soc_read(codec, WM8753_IOCTL);
f0fba2ad 185 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1f53aee0 186
60fc684a 187 if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0])
1f53aee0
LG
188 return 0;
189
190 mode &= 0xfff3;
191 mode |= (ucontrol->value.integer.value[0] << 2);
192
f0fba2ad 193 wm8753->dai_func = ucontrol->value.integer.value[0];
1f53aee0
LG
194 return 1;
195}
196
2cc8c609
MM
197static const DECLARE_TLV_DB_SCALE(rec_mix_tlv, -1500, 300, 0);
198static const DECLARE_TLV_DB_SCALE(mic_preamp_tlv, 1200, 600, 0);
199static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1);
200static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
201static const unsigned int out_tlv[] = {
202 TLV_DB_RANGE_HEAD(2),
203 /* 0000000 - 0101111 = "Analogue mute" */
204 0, 48, TLV_DB_SCALE_ITEM(-25500, 0, 0),
205 48, 127, TLV_DB_SCALE_ITEM(-7300, 100, 0),
206};
207static const DECLARE_TLV_DB_SCALE(mix_tlv, -1500, 300, 0);
208static const DECLARE_TLV_DB_SCALE(voice_mix_tlv, -1200, 300, 0);
209static const DECLARE_TLV_DB_SCALE(pga_tlv, -1725, 75, 0);
2d6a4ac9 210
1f53aee0 211static const struct snd_kcontrol_new wm8753_snd_controls[] = {
2cc8c609
MM
212SOC_DOUBLE_R_TLV("PCM Volume", WM8753_LDAC, WM8753_RDAC, 0, 255, 0, dac_tlv),
213
214SOC_DOUBLE_R_TLV("ADC Capture Volume", WM8753_LADC, WM8753_RADC, 0, 255, 0,
215 adc_tlv),
216
217SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8753_LOUT1V, WM8753_ROUT1V,
218 0, 127, 0, out_tlv),
219SOC_DOUBLE_R_TLV("Speaker Playback Volume", WM8753_LOUT2V, WM8753_ROUT2V, 0,
220 127, 0, out_tlv),
221
222SOC_SINGLE_TLV("Mono Playback Volume", WM8753_MOUTV, 0, 127, 0, out_tlv),
223
224SOC_DOUBLE_R_TLV("Bypass Playback Volume", WM8753_LOUTM1, WM8753_ROUTM1, 4, 7,
225 1, mix_tlv),
226SOC_DOUBLE_R_TLV("Sidetone Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 4,
227 7, 1, mix_tlv),
228SOC_DOUBLE_R_TLV("Voice Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 0, 7,
229 1, voice_mix_tlv),
230
231SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8753_LOUT1V, WM8753_ROUT1V, 7,
232 1, 0),
233SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8753_LOUT2V, WM8753_ROUT2V, 7,
234 1, 0),
235
236SOC_SINGLE_TLV("Mono Bypass Playback Volume", WM8753_MOUTM1, 4, 7, 1, mix_tlv),
237SOC_SINGLE_TLV("Mono Sidetone Playback Volume", WM8753_MOUTM2, 4, 7, 1,
238 mix_tlv),
239SOC_SINGLE_TLV("Mono Voice Playback Volume", WM8753_MOUTM2, 0, 7, 1,
240 voice_mix_tlv),
1f53aee0
LG
241SOC_SINGLE("Mono Playback ZC Switch", WM8753_MOUTV, 7, 1, 0),
242
243SOC_ENUM("Bass Boost", wm8753_enum[0]),
244SOC_ENUM("Bass Filter", wm8753_enum[1]),
245SOC_SINGLE("Bass Volume", WM8753_BASS, 0, 15, 1),
246
247SOC_SINGLE("Treble Volume", WM8753_TREBLE, 0, 15, 1),
248SOC_ENUM("Treble Cut-off", wm8753_enum[2]),
249
2cc8c609
MM
250SOC_DOUBLE_TLV("Sidetone Capture Volume", WM8753_RECMIX1, 0, 4, 7, 1,
251 rec_mix_tlv),
252SOC_SINGLE_TLV("Voice Sidetone Capture Volume", WM8753_RECMIX2, 0, 7, 1,
253 rec_mix_tlv),
1f53aee0 254
2cc8c609
MM
255SOC_DOUBLE_R_TLV("Capture Volume", WM8753_LINVOL, WM8753_RINVOL, 0, 63, 0,
256 pga_tlv),
1f53aee0
LG
257SOC_DOUBLE_R("Capture ZC Switch", WM8753_LINVOL, WM8753_RINVOL, 6, 1, 0),
258SOC_DOUBLE_R("Capture Switch", WM8753_LINVOL, WM8753_RINVOL, 7, 1, 1),
259
260SOC_ENUM("Capture Filter Select", wm8753_enum[23]),
261SOC_ENUM("Capture Filter Cut-off", wm8753_enum[24]),
262SOC_SINGLE("Capture Filter Switch", WM8753_ADC, 0, 1, 1),
263
264SOC_SINGLE("ALC Capture Target Volume", WM8753_ALC1, 0, 7, 0),
265SOC_SINGLE("ALC Capture Max Volume", WM8753_ALC1, 4, 7, 0),
266SOC_ENUM("ALC Capture Function", wm8753_enum[3]),
267SOC_SINGLE("ALC Capture ZC Switch", WM8753_ALC2, 8, 1, 0),
268SOC_SINGLE("ALC Capture Hold Time", WM8753_ALC2, 0, 15, 1),
269SOC_SINGLE("ALC Capture Decay Time", WM8753_ALC3, 4, 15, 1),
270SOC_SINGLE("ALC Capture Attack Time", WM8753_ALC3, 0, 15, 0),
271SOC_SINGLE("ALC Capture NG Threshold", WM8753_NGATE, 3, 31, 0),
272SOC_ENUM("ALC Capture NG Type", wm8753_enum[4]),
273SOC_SINGLE("ALC Capture NG Switch", WM8753_NGATE, 0, 1, 0),
274
275SOC_ENUM("3D Function", wm8753_enum[5]),
276SOC_ENUM("3D Upper Cut-off", wm8753_enum[6]),
277SOC_ENUM("3D Lower Cut-off", wm8753_enum[7]),
278SOC_SINGLE("3D Volume", WM8753_3D, 1, 15, 0),
279SOC_SINGLE("3D Switch", WM8753_3D, 0, 1, 0),
280
281SOC_SINGLE("Capture 6dB Attenuate", WM8753_ADCTL1, 2, 1, 0),
282SOC_SINGLE("Playback 6dB Attenuate", WM8753_ADCTL1, 1, 1, 0),
283
284SOC_ENUM("De-emphasis", wm8753_enum[8]),
285SOC_ENUM("Playback Mono Mix", wm8753_enum[9]),
286SOC_ENUM("Playback Phase", wm8753_enum[10]),
287
2cc8c609
MM
288SOC_SINGLE_TLV("Mic2 Capture Volume", WM8753_INCTL1, 7, 3, 0, mic_preamp_tlv),
289SOC_SINGLE_TLV("Mic1 Capture Volume", WM8753_INCTL1, 5, 3, 0, mic_preamp_tlv),
1f53aee0
LG
290
291SOC_ENUM_EXT("DAI Mode", wm8753_enum[26], wm8753_get_dai, wm8753_set_dai),
292
293SOC_ENUM("ADC Data Select", wm8753_enum[27]),
ae092c9e 294SOC_ENUM("ROUT2 Phase", wm8753_enum[28]),
1f53aee0
LG
295};
296
1f53aee0
LG
297/*
298 * _DAPM_ Controls
299 */
300
301/* Left Mixer */
302static const struct snd_kcontrol_new wm8753_left_mixer_controls[] = {
303SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_LOUTM2, 8, 1, 0),
304SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_LOUTM2, 7, 1, 0),
305SOC_DAPM_SINGLE("Left Playback Switch", WM8753_LOUTM1, 8, 1, 0),
306SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_LOUTM1, 7, 1, 0),
307};
308
309/* Right mixer */
310static const struct snd_kcontrol_new wm8753_right_mixer_controls[] = {
311SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_ROUTM2, 8, 1, 0),
312SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_ROUTM2, 7, 1, 0),
313SOC_DAPM_SINGLE("Right Playback Switch", WM8753_ROUTM1, 8, 1, 0),
314SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_ROUTM1, 7, 1, 0),
315};
316
317/* Mono mixer */
318static const struct snd_kcontrol_new wm8753_mono_mixer_controls[] = {
319SOC_DAPM_SINGLE("Left Playback Switch", WM8753_MOUTM1, 8, 1, 0),
320SOC_DAPM_SINGLE("Right Playback Switch", WM8753_MOUTM2, 8, 1, 0),
321SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_MOUTM2, 3, 1, 0),
322SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_MOUTM2, 7, 1, 0),
323SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_MOUTM1, 7, 1, 0),
324};
325
326/* Mono 2 Mux */
327static const struct snd_kcontrol_new wm8753_mono2_controls =
328SOC_DAPM_ENUM("Route", wm8753_enum[17]);
329
330/* Out 3 Mux */
331static const struct snd_kcontrol_new wm8753_out3_controls =
332SOC_DAPM_ENUM("Route", wm8753_enum[18]);
333
334/* Out 4 Mux */
335static const struct snd_kcontrol_new wm8753_out4_controls =
336SOC_DAPM_ENUM("Route", wm8753_enum[19]);
337
338/* ADC Mono Mix */
339static const struct snd_kcontrol_new wm8753_adc_mono_controls =
340SOC_DAPM_ENUM("Route", wm8753_enum[22]);
341
342/* Record mixer */
343static const struct snd_kcontrol_new wm8753_record_mixer_controls[] = {
344SOC_DAPM_SINGLE("Voice Capture Switch", WM8753_RECMIX2, 3, 1, 0),
345SOC_DAPM_SINGLE("Left Capture Switch", WM8753_RECMIX1, 3, 1, 0),
346SOC_DAPM_SINGLE("Right Capture Switch", WM8753_RECMIX1, 7, 1, 0),
347};
348
349/* Left ADC mux */
350static const struct snd_kcontrol_new wm8753_adc_left_controls =
351SOC_DAPM_ENUM("Route", wm8753_enum[21]);
352
353/* Right ADC mux */
354static const struct snd_kcontrol_new wm8753_adc_right_controls =
355SOC_DAPM_ENUM("Route", wm8753_enum[20]);
356
357/* MIC mux */
358static const struct snd_kcontrol_new wm8753_mic_mux_controls =
359SOC_DAPM_ENUM("Route", wm8753_enum[16]);
360
361/* ALC mixer */
362static const struct snd_kcontrol_new wm8753_alc_mixer_controls[] = {
363SOC_DAPM_SINGLE("Line Capture Switch", WM8753_INCTL2, 3, 1, 0),
364SOC_DAPM_SINGLE("Mic2 Capture Switch", WM8753_INCTL2, 2, 1, 0),
365SOC_DAPM_SINGLE("Mic1 Capture Switch", WM8753_INCTL2, 1, 1, 0),
366SOC_DAPM_SINGLE("Rx Capture Switch", WM8753_INCTL2, 0, 1, 0),
367};
368
369/* Left Line mux */
370static const struct snd_kcontrol_new wm8753_line_left_controls =
371SOC_DAPM_ENUM("Route", wm8753_enum[14]);
372
373/* Right Line mux */
374static const struct snd_kcontrol_new wm8753_line_right_controls =
375SOC_DAPM_ENUM("Route", wm8753_enum[13]);
376
377/* Mono Line mux */
378static const struct snd_kcontrol_new wm8753_line_mono_controls =
379SOC_DAPM_ENUM("Route", wm8753_enum[12]);
380
381/* Line mux and mixer */
382static const struct snd_kcontrol_new wm8753_line_mux_mix_controls =
383SOC_DAPM_ENUM("Route", wm8753_enum[11]);
384
385/* Rx mux and mixer */
386static const struct snd_kcontrol_new wm8753_rx_mux_mix_controls =
387SOC_DAPM_ENUM("Route", wm8753_enum[15]);
388
389/* Mic Selector Mux */
390static const struct snd_kcontrol_new wm8753_mic_sel_mux_controls =
391SOC_DAPM_ENUM("Route", wm8753_enum[25]);
392
393static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = {
394SND_SOC_DAPM_MICBIAS("Mic Bias", WM8753_PWR1, 5, 0),
395SND_SOC_DAPM_MIXER("Left Mixer", WM8753_PWR4, 0, 0,
396 &wm8753_left_mixer_controls[0], ARRAY_SIZE(wm8753_left_mixer_controls)),
397SND_SOC_DAPM_PGA("Left Out 1", WM8753_PWR3, 8, 0, NULL, 0),
398SND_SOC_DAPM_PGA("Left Out 2", WM8753_PWR3, 6, 0, NULL, 0),
399SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", WM8753_PWR1, 3, 0),
400SND_SOC_DAPM_OUTPUT("LOUT1"),
401SND_SOC_DAPM_OUTPUT("LOUT2"),
402SND_SOC_DAPM_MIXER("Right Mixer", WM8753_PWR4, 1, 0,
403 &wm8753_right_mixer_controls[0], ARRAY_SIZE(wm8753_right_mixer_controls)),
404SND_SOC_DAPM_PGA("Right Out 1", WM8753_PWR3, 7, 0, NULL, 0),
405SND_SOC_DAPM_PGA("Right Out 2", WM8753_PWR3, 5, 0, NULL, 0),
406SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", WM8753_PWR1, 2, 0),
407SND_SOC_DAPM_OUTPUT("ROUT1"),
408SND_SOC_DAPM_OUTPUT("ROUT2"),
409SND_SOC_DAPM_MIXER("Mono Mixer", WM8753_PWR4, 2, 0,
410 &wm8753_mono_mixer_controls[0], ARRAY_SIZE(wm8753_mono_mixer_controls)),
411SND_SOC_DAPM_PGA("Mono Out 1", WM8753_PWR3, 2, 0, NULL, 0),
412SND_SOC_DAPM_PGA("Mono Out 2", WM8753_PWR3, 1, 0, NULL, 0),
413SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", WM8753_PWR1, 4, 0),
414SND_SOC_DAPM_OUTPUT("MONO1"),
415SND_SOC_DAPM_MUX("Mono 2 Mux", SND_SOC_NOPM, 0, 0, &wm8753_mono2_controls),
416SND_SOC_DAPM_OUTPUT("MONO2"),
417SND_SOC_DAPM_MIXER("Out3 Left + Right", -1, 0, 0, NULL, 0),
418SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out3_controls),
419SND_SOC_DAPM_PGA("Out 3", WM8753_PWR3, 4, 0, NULL, 0),
420SND_SOC_DAPM_OUTPUT("OUT3"),
421SND_SOC_DAPM_MUX("Out4 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out4_controls),
422SND_SOC_DAPM_PGA("Out 4", WM8753_PWR3, 3, 0, NULL, 0),
423SND_SOC_DAPM_OUTPUT("OUT4"),
424SND_SOC_DAPM_MIXER("Playback Mixer", WM8753_PWR4, 3, 0,
425 &wm8753_record_mixer_controls[0],
426 ARRAY_SIZE(wm8753_record_mixer_controls)),
427SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8753_PWR2, 3, 0),
428SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8753_PWR2, 2, 0),
429SND_SOC_DAPM_MUX("Capture Left Mixer", SND_SOC_NOPM, 0, 0,
430 &wm8753_adc_mono_controls),
431SND_SOC_DAPM_MUX("Capture Right Mixer", SND_SOC_NOPM, 0, 0,
432 &wm8753_adc_mono_controls),
433SND_SOC_DAPM_MUX("Capture Left Mux", SND_SOC_NOPM, 0, 0,
434 &wm8753_adc_left_controls),
435SND_SOC_DAPM_MUX("Capture Right Mux", SND_SOC_NOPM, 0, 0,
436 &wm8753_adc_right_controls),
437SND_SOC_DAPM_MUX("Mic Sidetone Mux", SND_SOC_NOPM, 0, 0,
438 &wm8753_mic_mux_controls),
439SND_SOC_DAPM_PGA("Left Capture Volume", WM8753_PWR2, 5, 0, NULL, 0),
440SND_SOC_DAPM_PGA("Right Capture Volume", WM8753_PWR2, 4, 0, NULL, 0),
441SND_SOC_DAPM_MIXER("ALC Mixer", WM8753_PWR2, 6, 0,
442 &wm8753_alc_mixer_controls[0], ARRAY_SIZE(wm8753_alc_mixer_controls)),
443SND_SOC_DAPM_MUX("Line Left Mux", SND_SOC_NOPM, 0, 0,
444 &wm8753_line_left_controls),
445SND_SOC_DAPM_MUX("Line Right Mux", SND_SOC_NOPM, 0, 0,
446 &wm8753_line_right_controls),
447SND_SOC_DAPM_MUX("Line Mono Mux", SND_SOC_NOPM, 0, 0,
448 &wm8753_line_mono_controls),
449SND_SOC_DAPM_MUX("Line Mixer", WM8753_PWR2, 0, 0,
450 &wm8753_line_mux_mix_controls),
451SND_SOC_DAPM_MUX("Rx Mixer", WM8753_PWR2, 1, 0,
452 &wm8753_rx_mux_mix_controls),
453SND_SOC_DAPM_PGA("Mic 1 Volume", WM8753_PWR2, 8, 0, NULL, 0),
454SND_SOC_DAPM_PGA("Mic 2 Volume", WM8753_PWR2, 7, 0, NULL, 0),
455SND_SOC_DAPM_MUX("Mic Selection Mux", SND_SOC_NOPM, 0, 0,
456 &wm8753_mic_sel_mux_controls),
457SND_SOC_DAPM_INPUT("LINE1"),
458SND_SOC_DAPM_INPUT("LINE2"),
459SND_SOC_DAPM_INPUT("RXP"),
460SND_SOC_DAPM_INPUT("RXN"),
461SND_SOC_DAPM_INPUT("ACIN"),
462SND_SOC_DAPM_OUTPUT("ACOP"),
463SND_SOC_DAPM_INPUT("MIC1N"),
464SND_SOC_DAPM_INPUT("MIC1"),
465SND_SOC_DAPM_INPUT("MIC2N"),
466SND_SOC_DAPM_INPUT("MIC2"),
467SND_SOC_DAPM_VMID("VREF"),
468};
469
a65f0568 470static const struct snd_soc_dapm_route audio_map[] = {
1f53aee0
LG
471 /* left mixer */
472 {"Left Mixer", "Left Playback Switch", "Left DAC"},
473 {"Left Mixer", "Voice Playback Switch", "Voice DAC"},
474 {"Left Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
475 {"Left Mixer", "Bypass Playback Switch", "Line Left Mux"},
476
477 /* right mixer */
478 {"Right Mixer", "Right Playback Switch", "Right DAC"},
479 {"Right Mixer", "Voice Playback Switch", "Voice DAC"},
480 {"Right Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
481 {"Right Mixer", "Bypass Playback Switch", "Line Right Mux"},
482
483 /* mono mixer */
484 {"Mono Mixer", "Voice Playback Switch", "Voice DAC"},
485 {"Mono Mixer", "Left Playback Switch", "Left DAC"},
486 {"Mono Mixer", "Right Playback Switch", "Right DAC"},
487 {"Mono Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
488 {"Mono Mixer", "Bypass Playback Switch", "Line Mono Mux"},
489
490 /* left out */
491 {"Left Out 1", NULL, "Left Mixer"},
492 {"Left Out 2", NULL, "Left Mixer"},
493 {"LOUT1", NULL, "Left Out 1"},
494 {"LOUT2", NULL, "Left Out 2"},
495
496 /* right out */
497 {"Right Out 1", NULL, "Right Mixer"},
498 {"Right Out 2", NULL, "Right Mixer"},
499 {"ROUT1", NULL, "Right Out 1"},
500 {"ROUT2", NULL, "Right Out 2"},
501
502 /* mono 1 out */
503 {"Mono Out 1", NULL, "Mono Mixer"},
504 {"MONO1", NULL, "Mono Out 1"},
505
506 /* mono 2 out */
507 {"Mono 2 Mux", "Left + Right", "Out3 Left + Right"},
508 {"Mono 2 Mux", "Inverted Mono 1", "MONO1"},
509 {"Mono 2 Mux", "Left", "Left Mixer"},
510 {"Mono 2 Mux", "Right", "Right Mixer"},
511 {"Mono Out 2", NULL, "Mono 2 Mux"},
512 {"MONO2", NULL, "Mono Out 2"},
513
514 /* out 3 */
515 {"Out3 Left + Right", NULL, "Left Mixer"},
516 {"Out3 Left + Right", NULL, "Right Mixer"},
517 {"Out3 Mux", "VREF", "VREF"},
518 {"Out3 Mux", "Left + Right", "Out3 Left + Right"},
519 {"Out3 Mux", "ROUT2", "ROUT2"},
520 {"Out 3", NULL, "Out3 Mux"},
521 {"OUT3", NULL, "Out 3"},
522
523 /* out 4 */
524 {"Out4 Mux", "VREF", "VREF"},
4037314a 525 {"Out4 Mux", "Capture ST", "Playback Mixer"},
1f53aee0
LG
526 {"Out4 Mux", "LOUT2", "LOUT2"},
527 {"Out 4", NULL, "Out4 Mux"},
528 {"OUT4", NULL, "Out 4"},
529
530 /* record mixer */
531 {"Playback Mixer", "Left Capture Switch", "Left Mixer"},
532 {"Playback Mixer", "Voice Capture Switch", "Mono Mixer"},
533 {"Playback Mixer", "Right Capture Switch", "Right Mixer"},
534
535 /* Mic/SideTone Mux */
536 {"Mic Sidetone Mux", "Left PGA", "Left Capture Volume"},
537 {"Mic Sidetone Mux", "Right PGA", "Right Capture Volume"},
538 {"Mic Sidetone Mux", "Mic 1", "Mic 1 Volume"},
539 {"Mic Sidetone Mux", "Mic 2", "Mic 2 Volume"},
540
541 /* Capture Left Mux */
542 {"Capture Left Mux", "PGA", "Left Capture Volume"},
543 {"Capture Left Mux", "Line or RXP-RXN", "Line Left Mux"},
544 {"Capture Left Mux", "Line", "LINE1"},
545
546 /* Capture Right Mux */
547 {"Capture Right Mux", "PGA", "Right Capture Volume"},
548 {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"},
4037314a 549 {"Capture Right Mux", "Sidetone", "Playback Mixer"},
1f53aee0
LG
550
551 /* Mono Capture mixer-mux */
552 {"Capture Right Mixer", "Stereo", "Capture Right Mux"},
877ae707 553 {"Capture Left Mixer", "Stereo", "Capture Left Mux"},
1f53aee0
LG
554 {"Capture Left Mixer", "Analogue Mix Left", "Capture Left Mux"},
555 {"Capture Left Mixer", "Analogue Mix Left", "Capture Right Mux"},
556 {"Capture Right Mixer", "Analogue Mix Right", "Capture Left Mux"},
557 {"Capture Right Mixer", "Analogue Mix Right", "Capture Right Mux"},
558 {"Capture Left Mixer", "Digital Mono Mix", "Capture Left Mux"},
559 {"Capture Left Mixer", "Digital Mono Mix", "Capture Right Mux"},
560 {"Capture Right Mixer", "Digital Mono Mix", "Capture Left Mux"},
561 {"Capture Right Mixer", "Digital Mono Mix", "Capture Right Mux"},
562
563 /* ADC */
564 {"Left ADC", NULL, "Capture Left Mixer"},
565 {"Right ADC", NULL, "Capture Right Mixer"},
566
567 /* Left Capture Volume */
568 {"Left Capture Volume", NULL, "ACIN"},
569
570 /* Right Capture Volume */
571 {"Right Capture Volume", NULL, "Mic 2 Volume"},
572
573 /* ALC Mixer */
574 {"ALC Mixer", "Line Capture Switch", "Line Mixer"},
575 {"ALC Mixer", "Mic2 Capture Switch", "Mic 2 Volume"},
576 {"ALC Mixer", "Mic1 Capture Switch", "Mic 1 Volume"},
577 {"ALC Mixer", "Rx Capture Switch", "Rx Mixer"},
578
579 /* Line Left Mux */
580 {"Line Left Mux", "Line 1", "LINE1"},
581 {"Line Left Mux", "Rx Mix", "Rx Mixer"},
582
583 /* Line Right Mux */
584 {"Line Right Mux", "Line 2", "LINE2"},
585 {"Line Right Mux", "Rx Mix", "Rx Mixer"},
586
587 /* Line Mono Mux */
588 {"Line Mono Mux", "Line Mix", "Line Mixer"},
589 {"Line Mono Mux", "Rx Mix", "Rx Mixer"},
590
591 /* Line Mixer/Mux */
592 {"Line Mixer", "Line 1 + 2", "LINE1"},
593 {"Line Mixer", "Line 1 - 2", "LINE1"},
594 {"Line Mixer", "Line 1 + 2", "LINE2"},
595 {"Line Mixer", "Line 1 - 2", "LINE2"},
596 {"Line Mixer", "Line 1", "LINE1"},
597 {"Line Mixer", "Line 2", "LINE2"},
598
599 /* Rx Mixer/Mux */
600 {"Rx Mixer", "RXP - RXN", "RXP"},
601 {"Rx Mixer", "RXP + RXN", "RXP"},
602 {"Rx Mixer", "RXP - RXN", "RXN"},
603 {"Rx Mixer", "RXP + RXN", "RXN"},
604 {"Rx Mixer", "RXP", "RXP"},
605 {"Rx Mixer", "RXN", "RXN"},
606
607 /* Mic 1 Volume */
608 {"Mic 1 Volume", NULL, "MIC1N"},
609 {"Mic 1 Volume", NULL, "Mic Selection Mux"},
610
611 /* Mic 2 Volume */
612 {"Mic 2 Volume", NULL, "MIC2N"},
613 {"Mic 2 Volume", NULL, "MIC2"},
614
615 /* Mic Selector Mux */
616 {"Mic Selection Mux", "Mic 1", "MIC1"},
617 {"Mic Selection Mux", "Mic 2", "MIC2N"},
618 {"Mic Selection Mux", "Mic 3", "MIC2"},
619
620 /* ACOP */
621 {"ACOP", NULL, "ALC Mixer"},
1f53aee0
LG
622};
623
624static int wm8753_add_widgets(struct snd_soc_codec *codec)
625{
a65f0568
MB
626 snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets,
627 ARRAY_SIZE(wm8753_dapm_widgets));
1f53aee0 628
a65f0568 629 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
1f53aee0 630
1f53aee0
LG
631 return 0;
632}
633
634/* PLL divisors */
635struct _pll_div {
636 u32 div2:1;
637 u32 n:4;
638 u32 k:24;
639};
640
641/* The size in bits of the pll divide multiplied by 10
642 * to allow rounding later */
643#define FIXED_PLL_SIZE ((1 << 22) * 10)
644
645static void pll_factors(struct _pll_div *pll_div, unsigned int target,
646 unsigned int source)
647{
648 u64 Kpart;
649 unsigned int K, Ndiv, Nmod;
650
651 Ndiv = target / source;
652 if (Ndiv < 6) {
653 source >>= 1;
654 pll_div->div2 = 1;
655 Ndiv = target / source;
656 } else
657 pll_div->div2 = 0;
658
659 if ((Ndiv < 6) || (Ndiv > 12))
660 printk(KERN_WARNING
449bd54d 661 "wm8753: unsupported N = %u\n", Ndiv);
1f53aee0
LG
662
663 pll_div->n = Ndiv;
664 Nmod = target % source;
665 Kpart = FIXED_PLL_SIZE * (long long)Nmod;
666
667 do_div(Kpart, source);
668
669 K = Kpart & 0xFFFFFFFF;
670
671 /* Check if we need to round */
672 if ((K % 10) >= 5)
673 K += 5;
674
675 /* Move down to proper range now rounding is done */
676 K /= 10;
677
678 pll_div->k = K;
679}
680
85488037
MB
681static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
682 int source, unsigned int freq_in, unsigned int freq_out)
1f53aee0
LG
683{
684 u16 reg, enable;
685 int offset;
686 struct snd_soc_codec *codec = codec_dai->codec;
687
688 if (pll_id < WM8753_PLL1 || pll_id > WM8753_PLL2)
689 return -ENODEV;
690
691 if (pll_id == WM8753_PLL1) {
692 offset = 0;
693 enable = 0x10;
776065e3 694 reg = snd_soc_read(codec, WM8753_CLOCK) & 0xffef;
1f53aee0
LG
695 } else {
696 offset = 4;
697 enable = 0x8;
776065e3 698 reg = snd_soc_read(codec, WM8753_CLOCK) & 0xfff7;
1f53aee0
LG
699 }
700
701 if (!freq_in || !freq_out) {
702 /* disable PLL */
776065e3
LPC
703 snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0026);
704 snd_soc_write(codec, WM8753_CLOCK, reg);
1f53aee0
LG
705 return 0;
706 } else {
707 u16 value = 0;
708 struct _pll_div pll_div;
709
710 pll_factors(&pll_div, freq_out * 8, freq_in);
711
712 /* set up N and K PLL divisor ratios */
713 /* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */
714 value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18);
776065e3 715 snd_soc_write(codec, WM8753_PLL1CTL2 + offset, value);
1f53aee0
LG
716
717 /* bits 8:0 = PLL_K[17:9] */
718 value = (pll_div.k & 0x03fe00) >> 9;
776065e3 719 snd_soc_write(codec, WM8753_PLL1CTL3 + offset, value);
1f53aee0
LG
720
721 /* bits 8:0 = PLL_K[8:0] */
722 value = pll_div.k & 0x0001ff;
776065e3 723 snd_soc_write(codec, WM8753_PLL1CTL4 + offset, value);
1f53aee0
LG
724
725 /* set PLL as input and enable */
776065e3 726 snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 |
1f53aee0 727 (pll_div.div2 << 3));
776065e3 728 snd_soc_write(codec, WM8753_CLOCK, reg | enable);
1f53aee0
LG
729 }
730 return 0;
731}
732
733struct _coeff_div {
734 u32 mclk;
735 u32 rate;
736 u8 sr:5;
737 u8 usb:1;
738};
739
740/* codec hifi mclk (after PLL) clock divider coefficients */
741static const struct _coeff_div coeff_div[] = {
742 /* 8k */
743 {12288000, 8000, 0x6, 0x0},
744 {11289600, 8000, 0x16, 0x0},
745 {18432000, 8000, 0x7, 0x0},
746 {16934400, 8000, 0x17, 0x0},
747 {12000000, 8000, 0x6, 0x1},
748
749 /* 11.025k */
750 {11289600, 11025, 0x18, 0x0},
751 {16934400, 11025, 0x19, 0x0},
752 {12000000, 11025, 0x19, 0x1},
753
754 /* 16k */
755 {12288000, 16000, 0xa, 0x0},
756 {18432000, 16000, 0xb, 0x0},
757 {12000000, 16000, 0xa, 0x1},
758
759 /* 22.05k */
760 {11289600, 22050, 0x1a, 0x0},
761 {16934400, 22050, 0x1b, 0x0},
762 {12000000, 22050, 0x1b, 0x1},
763
764 /* 32k */
765 {12288000, 32000, 0xc, 0x0},
766 {18432000, 32000, 0xd, 0x0},
767 {12000000, 32000, 0xa, 0x1},
768
769 /* 44.1k */
770 {11289600, 44100, 0x10, 0x0},
771 {16934400, 44100, 0x11, 0x0},
772 {12000000, 44100, 0x11, 0x1},
773
774 /* 48k */
775 {12288000, 48000, 0x0, 0x0},
776 {18432000, 48000, 0x1, 0x0},
777 {12000000, 48000, 0x0, 0x1},
778
779 /* 88.2k */
780 {11289600, 88200, 0x1e, 0x0},
781 {16934400, 88200, 0x1f, 0x0},
782 {12000000, 88200, 0x1f, 0x1},
783
784 /* 96k */
785 {12288000, 96000, 0xe, 0x0},
786 {18432000, 96000, 0xf, 0x0},
787 {12000000, 96000, 0xe, 0x1},
788};
789
790static int get_coeff(int mclk, int rate)
791{
792 int i;
793
794 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
795 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
796 return i;
797 }
798 return -EINVAL;
799}
800
801/*
802 * Clock after PLL and dividers
803 */
e550e17f 804static int wm8753_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1f53aee0
LG
805 int clk_id, unsigned int freq, int dir)
806{
807 struct snd_soc_codec *codec = codec_dai->codec;
b2c812e2 808 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1f53aee0
LG
809
810 switch (freq) {
811 case 11289600:
812 case 12000000:
813 case 12288000:
814 case 16934400:
815 case 18432000:
816 if (clk_id == WM8753_MCLK) {
817 wm8753->sysclk = freq;
818 return 0;
819 } else if (clk_id == WM8753_PCMCLK) {
820 wm8753->pcmclk = freq;
821 return 0;
822 }
823 break;
824 }
825 return -EINVAL;
826}
827
828/*
829 * Set's ADC and Voice DAC format.
830 */
e550e17f 831static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
1f53aee0
LG
832 unsigned int fmt)
833{
834 struct snd_soc_codec *codec = codec_dai->codec;
776065e3 835 u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec;
1f53aee0
LG
836
837 /* interface format */
838 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
839 case SND_SOC_DAIFMT_I2S:
840 voice |= 0x0002;
841 break;
842 case SND_SOC_DAIFMT_RIGHT_J:
843 break;
844 case SND_SOC_DAIFMT_LEFT_J:
845 voice |= 0x0001;
846 break;
847 case SND_SOC_DAIFMT_DSP_A:
848 voice |= 0x0003;
849 break;
850 case SND_SOC_DAIFMT_DSP_B:
851 voice |= 0x0013;
852 break;
853 default:
854 return -EINVAL;
855 }
856
776065e3 857 snd_soc_write(codec, WM8753_PCM, voice);
1f53aee0
LG
858 return 0;
859}
860
f0fba2ad
LG
861static int wm8753_pcm_startup(struct snd_pcm_substream *substream,
862 struct snd_soc_dai *dai)
863{
864 wm8753_set_dai_mode(dai->codec, dai, 0);
865 return 0;
866}
867
1f53aee0
LG
868/*
869 * Set PCM DAI bit size and sample rate.
870 */
871static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
dee89c4d
MB
872 struct snd_pcm_hw_params *params,
873 struct snd_soc_dai *dai)
1f53aee0
LG
874{
875 struct snd_soc_pcm_runtime *rtd = substream->private_data;
f0fba2ad 876 struct snd_soc_codec *codec = rtd->codec;
b2c812e2 877 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
776065e3
LPC
878 u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01f3;
879 u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x017f;
1f53aee0
LG
880
881 /* bit size */
882 switch (params_format(params)) {
883 case SNDRV_PCM_FORMAT_S16_LE:
884 break;
885 case SNDRV_PCM_FORMAT_S20_3LE:
886 voice |= 0x0004;
887 break;
888 case SNDRV_PCM_FORMAT_S24_LE:
889 voice |= 0x0008;
890 break;
891 case SNDRV_PCM_FORMAT_S32_LE:
892 voice |= 0x000c;
893 break;
894 }
895
896 /* sample rate */
897 if (params_rate(params) * 384 == wm8753->pcmclk)
898 srate |= 0x80;
776065e3 899 snd_soc_write(codec, WM8753_SRATE1, srate);
1f53aee0 900
776065e3 901 snd_soc_write(codec, WM8753_PCM, voice);
1f53aee0
LG
902 return 0;
903}
904
905/*
906 * Set's PCM dai fmt and BCLK.
907 */
e550e17f 908static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai,
1f53aee0
LG
909 unsigned int fmt)
910{
911 struct snd_soc_codec *codec = codec_dai->codec;
912 u16 voice, ioctl;
913
776065e3
LPC
914 voice = snd_soc_read(codec, WM8753_PCM) & 0x011f;
915 ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x015d;
1f53aee0
LG
916
917 /* set master/slave audio interface */
918 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
919 case SND_SOC_DAIFMT_CBS_CFS:
920 break;
921 case SND_SOC_DAIFMT_CBM_CFM:
922 ioctl |= 0x2;
923 case SND_SOC_DAIFMT_CBM_CFS:
924 voice |= 0x0040;
925 break;
926 default:
927 return -EINVAL;
928 }
929
930 /* clock inversion */
931 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
932 case SND_SOC_DAIFMT_DSP_A:
933 case SND_SOC_DAIFMT_DSP_B:
934 /* frame inversion not valid for DSP modes */
935 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
936 case SND_SOC_DAIFMT_NB_NF:
937 break;
938 case SND_SOC_DAIFMT_IB_NF:
939 voice |= 0x0080;
940 break;
941 default:
942 return -EINVAL;
943 }
944 break;
945 case SND_SOC_DAIFMT_I2S:
946 case SND_SOC_DAIFMT_RIGHT_J:
947 case SND_SOC_DAIFMT_LEFT_J:
948 voice &= ~0x0010;
949 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
950 case SND_SOC_DAIFMT_NB_NF:
951 break;
952 case SND_SOC_DAIFMT_IB_IF:
953 voice |= 0x0090;
954 break;
955 case SND_SOC_DAIFMT_IB_NF:
956 voice |= 0x0080;
957 break;
958 case SND_SOC_DAIFMT_NB_IF:
959 voice |= 0x0010;
960 break;
961 default:
962 return -EINVAL;
963 }
964 break;
965 default:
966 return -EINVAL;
967 }
968
776065e3
LPC
969 snd_soc_write(codec, WM8753_PCM, voice);
970 snd_soc_write(codec, WM8753_IOCTL, ioctl);
1f53aee0
LG
971 return 0;
972}
973
e550e17f 974static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1f53aee0
LG
975 int div_id, int div)
976{
977 struct snd_soc_codec *codec = codec_dai->codec;
978 u16 reg;
979
980 switch (div_id) {
981 case WM8753_PCMDIV:
776065e3
LPC
982 reg = snd_soc_read(codec, WM8753_CLOCK) & 0x003f;
983 snd_soc_write(codec, WM8753_CLOCK, reg | div);
1f53aee0
LG
984 break;
985 case WM8753_BCLKDIV:
776065e3
LPC
986 reg = snd_soc_read(codec, WM8753_SRATE2) & 0x01c7;
987 snd_soc_write(codec, WM8753_SRATE2, reg | div);
1f53aee0
LG
988 break;
989 case WM8753_VXCLKDIV:
776065e3
LPC
990 reg = snd_soc_read(codec, WM8753_SRATE2) & 0x003f;
991 snd_soc_write(codec, WM8753_SRATE2, reg | div);
1f53aee0
LG
992 break;
993 default:
994 return -EINVAL;
995 }
996 return 0;
997}
998
999/*
1000 * Set's HiFi DAC format.
1001 */
e550e17f 1002static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai,
1f53aee0
LG
1003 unsigned int fmt)
1004{
1005 struct snd_soc_codec *codec = codec_dai->codec;
776065e3 1006 u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0;
1f53aee0
LG
1007
1008 /* interface format */
1009 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1010 case SND_SOC_DAIFMT_I2S:
1011 hifi |= 0x0002;
1012 break;
1013 case SND_SOC_DAIFMT_RIGHT_J:
1014 break;
1015 case SND_SOC_DAIFMT_LEFT_J:
1016 hifi |= 0x0001;
1017 break;
1018 case SND_SOC_DAIFMT_DSP_A:
1019 hifi |= 0x0003;
1020 break;
1021 case SND_SOC_DAIFMT_DSP_B:
1022 hifi |= 0x0013;
1023 break;
1024 default:
1025 return -EINVAL;
1026 }
1027
776065e3 1028 snd_soc_write(codec, WM8753_HIFI, hifi);
1f53aee0
LG
1029 return 0;
1030}
1031
1032/*
1033 * Set's I2S DAI format.
1034 */
e550e17f 1035static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
1f53aee0
LG
1036 unsigned int fmt)
1037{
1038 struct snd_soc_codec *codec = codec_dai->codec;
1039 u16 ioctl, hifi;
1040
776065e3
LPC
1041 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f;
1042 ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x00ae;
1f53aee0
LG
1043
1044 /* set master/slave audio interface */
1045 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1046 case SND_SOC_DAIFMT_CBS_CFS:
1047 break;
1048 case SND_SOC_DAIFMT_CBM_CFM:
1049 ioctl |= 0x1;
1050 case SND_SOC_DAIFMT_CBM_CFS:
1051 hifi |= 0x0040;
1052 break;
1053 default:
1054 return -EINVAL;
1055 }
1056
1057 /* clock inversion */
1058 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1059 case SND_SOC_DAIFMT_DSP_A:
1060 case SND_SOC_DAIFMT_DSP_B:
1061 /* frame inversion not valid for DSP modes */
1062 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1063 case SND_SOC_DAIFMT_NB_NF:
1064 break;
1065 case SND_SOC_DAIFMT_IB_NF:
1066 hifi |= 0x0080;
1067 break;
1068 default:
1069 return -EINVAL;
1070 }
1071 break;
1072 case SND_SOC_DAIFMT_I2S:
1073 case SND_SOC_DAIFMT_RIGHT_J:
1074 case SND_SOC_DAIFMT_LEFT_J:
1075 hifi &= ~0x0010;
1076 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1077 case SND_SOC_DAIFMT_NB_NF:
1078 break;
1079 case SND_SOC_DAIFMT_IB_IF:
1080 hifi |= 0x0090;
1081 break;
1082 case SND_SOC_DAIFMT_IB_NF:
1083 hifi |= 0x0080;
1084 break;
1085 case SND_SOC_DAIFMT_NB_IF:
1086 hifi |= 0x0010;
1087 break;
1088 default:
1089 return -EINVAL;
1090 }
1091 break;
1092 default:
1093 return -EINVAL;
1094 }
1095
776065e3
LPC
1096 snd_soc_write(codec, WM8753_HIFI, hifi);
1097 snd_soc_write(codec, WM8753_IOCTL, ioctl);
1f53aee0
LG
1098 return 0;
1099}
1100
f0fba2ad
LG
1101static int wm8753_i2s_startup(struct snd_pcm_substream *substream,
1102 struct snd_soc_dai *dai)
1103{
1104 wm8753_set_dai_mode(dai->codec, dai, 1);
1105 return 0;
1106}
1107
1f53aee0
LG
1108/*
1109 * Set PCM DAI bit size and sample rate.
1110 */
1111static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
dee89c4d
MB
1112 struct snd_pcm_hw_params *params,
1113 struct snd_soc_dai *dai)
1f53aee0
LG
1114{
1115 struct snd_soc_pcm_runtime *rtd = substream->private_data;
f0fba2ad 1116 struct snd_soc_codec *codec = rtd->codec;
b2c812e2 1117 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
776065e3
LPC
1118 u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x01c0;
1119 u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01f3;
1f53aee0
LG
1120 int coeff;
1121
1122 /* is digital filter coefficient valid ? */
1123 coeff = get_coeff(wm8753->sysclk, params_rate(params));
1124 if (coeff < 0) {
1125 printk(KERN_ERR "wm8753 invalid MCLK or rate\n");
1126 return coeff;
1127 }
776065e3 1128 snd_soc_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) |
1f53aee0
LG
1129 coeff_div[coeff].usb);
1130
1131 /* bit size */
1132 switch (params_format(params)) {
1133 case SNDRV_PCM_FORMAT_S16_LE:
1134 break;
1135 case SNDRV_PCM_FORMAT_S20_3LE:
1136 hifi |= 0x0004;
1137 break;
1138 case SNDRV_PCM_FORMAT_S24_LE:
1139 hifi |= 0x0008;
1140 break;
1141 case SNDRV_PCM_FORMAT_S32_LE:
1142 hifi |= 0x000c;
1143 break;
1144 }
1145
776065e3 1146 snd_soc_write(codec, WM8753_HIFI, hifi);
1f53aee0
LG
1147 return 0;
1148}
1149
e550e17f 1150static int wm8753_mode1v_set_dai_fmt(struct snd_soc_dai *codec_dai,
1f53aee0
LG
1151 unsigned int fmt)
1152{
1153 struct snd_soc_codec *codec = codec_dai->codec;
1154 u16 clock;
1155
1156 /* set clk source as pcmclk */
776065e3
LPC
1157 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
1158 snd_soc_write(codec, WM8753_CLOCK, clock);
1f53aee0
LG
1159
1160 if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
1161 return -EINVAL;
1162 return wm8753_pcm_set_dai_fmt(codec_dai, fmt);
1163}
1164
e550e17f 1165static int wm8753_mode1h_set_dai_fmt(struct snd_soc_dai *codec_dai,
1f53aee0
LG
1166 unsigned int fmt)
1167{
1168 if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0)
1169 return -EINVAL;
1170 return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
1171}
1172
e550e17f 1173static int wm8753_mode2_set_dai_fmt(struct snd_soc_dai *codec_dai,
1f53aee0
LG
1174 unsigned int fmt)
1175{
1176 struct snd_soc_codec *codec = codec_dai->codec;
1177 u16 clock;
1178
1179 /* set clk source as pcmclk */
776065e3
LPC
1180 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
1181 snd_soc_write(codec, WM8753_CLOCK, clock);
1f53aee0
LG
1182
1183 if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
1184 return -EINVAL;
1185 return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
1186}
1187
e550e17f 1188static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai,
1f53aee0
LG
1189 unsigned int fmt)
1190{
1191 struct snd_soc_codec *codec = codec_dai->codec;
1192 u16 clock;
1193
1194 /* set clk source as mclk */
776065e3
LPC
1195 clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb;
1196 snd_soc_write(codec, WM8753_CLOCK, clock | 0x4);
1f53aee0
LG
1197
1198 if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0)
1199 return -EINVAL;
1200 if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0)
1201 return -EINVAL;
1202 return wm8753_i2s_set_dai_fmt(codec_dai, fmt);
1203}
1204
e550e17f 1205static int wm8753_mute(struct snd_soc_dai *dai, int mute)
1f53aee0
LG
1206{
1207 struct snd_soc_codec *codec = dai->codec;
776065e3 1208 u16 mute_reg = snd_soc_read(codec, WM8753_DAC) & 0xfff7;
f0fba2ad 1209 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1f53aee0
LG
1210
1211 /* the digital mute covers the HiFi and Voice DAC's on the WM8753.
1212 * make sure we check if they are not both active when we mute */
f0fba2ad
LG
1213 if (mute && wm8753->dai_func == 1) {
1214 if (!codec->active)
776065e3 1215 snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
1f53aee0
LG
1216 } else {
1217 if (mute)
776065e3 1218 snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8);
1f53aee0 1219 else
776065e3 1220 snd_soc_write(codec, WM8753_DAC, mute_reg);
1f53aee0
LG
1221 }
1222
1223 return 0;
1224}
1225
0be9898a
MB
1226static int wm8753_set_bias_level(struct snd_soc_codec *codec,
1227 enum snd_soc_bias_level level)
1f53aee0 1228{
776065e3 1229 u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e;
1f53aee0 1230
0be9898a
MB
1231 switch (level) {
1232 case SND_SOC_BIAS_ON:
1f53aee0 1233 /* set vmid to 50k and unmute dac */
776065e3 1234 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0);
1f53aee0 1235 break;
0be9898a 1236 case SND_SOC_BIAS_PREPARE:
1f53aee0 1237 /* set vmid to 5k for quick power up */
776065e3 1238 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1);
1f53aee0 1239 break;
0be9898a 1240 case SND_SOC_BIAS_STANDBY:
1f53aee0 1241 /* mute dac and set vmid to 500k, enable VREF */
776065e3 1242 snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141);
1f53aee0 1243 break;
0be9898a 1244 case SND_SOC_BIAS_OFF:
776065e3 1245 snd_soc_write(codec, WM8753_PWR1, 0x0001);
1f53aee0
LG
1246 break;
1247 }
0be9898a 1248 codec->bias_level = level;
1f53aee0
LG
1249 return 0;
1250}
1251
1252#define WM8753_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
60fc684a
MB
1253 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
1254 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
1255 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
1f53aee0
LG
1256
1257#define WM8753_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1258 SNDRV_PCM_FMTBIT_S24_LE)
1259
1260/*
1261 * The WM8753 supports upto 4 different and mutually exclusive DAI
1262 * configurations. This gives 2 PCM's available for use, hifi and voice.
1263 * NOTE: The Voice PCM cannot play or capture audio to the CPU as it's DAI
1264 * is connected between the wm8753 and a BT codec or GSM modem.
1265 *
1266 * 1. Voice over PCM DAI - HIFI DAC over HIFI DAI
1267 * 2. Voice over HIFI DAI - HIFI disabled
1268 * 3. Voice disabled - HIFI over HIFI
1269 * 4. Voice disabled - HIFI over HIFI, uses voice DAI LRC for capture
1270 */
6335d055 1271static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode1 = {
f0fba2ad 1272 .startup = wm8753_i2s_startup,
6335d055
EM
1273 .hw_params = wm8753_i2s_hw_params,
1274 .digital_mute = wm8753_mute,
1275 .set_fmt = wm8753_mode1h_set_dai_fmt,
1276 .set_clkdiv = wm8753_set_dai_clkdiv,
1277 .set_pll = wm8753_set_dai_pll,
1278 .set_sysclk = wm8753_set_dai_sysclk,
1279};
1280
1281static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode1 = {
f0fba2ad 1282 .startup = wm8753_pcm_startup,
6335d055
EM
1283 .hw_params = wm8753_pcm_hw_params,
1284 .digital_mute = wm8753_mute,
1285 .set_fmt = wm8753_mode1v_set_dai_fmt,
1286 .set_clkdiv = wm8753_set_dai_clkdiv,
1287 .set_pll = wm8753_set_dai_pll,
1288 .set_sysclk = wm8753_set_dai_sysclk,
1289};
1290
1291static struct snd_soc_dai_ops wm8753_dai_ops_voice_mode2 = {
f0fba2ad 1292 .startup = wm8753_pcm_startup,
6335d055
EM
1293 .hw_params = wm8753_pcm_hw_params,
1294 .digital_mute = wm8753_mute,
1295 .set_fmt = wm8753_mode2_set_dai_fmt,
1296 .set_clkdiv = wm8753_set_dai_clkdiv,
1297 .set_pll = wm8753_set_dai_pll,
1298 .set_sysclk = wm8753_set_dai_sysclk,
1299};
1300
1301static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode3 = {
f0fba2ad 1302 .startup = wm8753_i2s_startup,
6335d055
EM
1303 .hw_params = wm8753_i2s_hw_params,
1304 .digital_mute = wm8753_mute,
1305 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1306 .set_clkdiv = wm8753_set_dai_clkdiv,
1307 .set_pll = wm8753_set_dai_pll,
1308 .set_sysclk = wm8753_set_dai_sysclk,
1309};
1310
1311static struct snd_soc_dai_ops wm8753_dai_ops_hifi_mode4 = {
f0fba2ad 1312 .startup = wm8753_i2s_startup,
6335d055
EM
1313 .hw_params = wm8753_i2s_hw_params,
1314 .digital_mute = wm8753_mute,
1315 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1316 .set_clkdiv = wm8753_set_dai_clkdiv,
1317 .set_pll = wm8753_set_dai_pll,
1318 .set_sysclk = wm8753_set_dai_sysclk,
1319};
1320
f0fba2ad 1321static struct snd_soc_dai_driver wm8753_all_dai[] = {
1f53aee0 1322/* DAI HiFi mode 1 */
f0fba2ad 1323{ .name = "wm8753-hifi",
1f53aee0
LG
1324 .playback = {
1325 .stream_name = "HiFi Playback",
1326 .channels_min = 1,
1327 .channels_max = 2,
1328 .rates = WM8753_RATES,
dee89c4d 1329 .formats = WM8753_FORMATS},
1f53aee0
LG
1330 .capture = { /* dummy for fast DAI switching */
1331 .stream_name = "Capture",
1332 .channels_min = 1,
1333 .channels_max = 2,
1334 .rates = WM8753_RATES,
dee89c4d 1335 .formats = WM8753_FORMATS},
6335d055 1336 .ops = &wm8753_dai_ops_hifi_mode1,
1f53aee0
LG
1337},
1338/* DAI Voice mode 1 */
f0fba2ad 1339{ .name = "wm8753-voice",
1f53aee0
LG
1340 .playback = {
1341 .stream_name = "Voice Playback",
1342 .channels_min = 1,
1343 .channels_max = 1,
1344 .rates = WM8753_RATES,
1345 .formats = WM8753_FORMATS,},
1346 .capture = {
1347 .stream_name = "Capture",
1348 .channels_min = 1,
1349 .channels_max = 2,
1350 .rates = WM8753_RATES,
1351 .formats = WM8753_FORMATS,},
6335d055 1352 .ops = &wm8753_dai_ops_voice_mode1,
1f53aee0
LG
1353},
1354/* DAI HiFi mode 2 - dummy */
f0fba2ad 1355{ .name = "wm8753-hifi",
1f53aee0
LG
1356},
1357/* DAI Voice mode 2 */
f0fba2ad 1358{ .name = "wm8753-voice",
1f53aee0
LG
1359 .playback = {
1360 .stream_name = "Voice Playback",
1361 .channels_min = 1,
1362 .channels_max = 1,
1363 .rates = WM8753_RATES,
1364 .formats = WM8753_FORMATS,},
1365 .capture = {
1366 .stream_name = "Capture",
1367 .channels_min = 1,
1368 .channels_max = 2,
1369 .rates = WM8753_RATES,
1370 .formats = WM8753_FORMATS,},
6335d055 1371 .ops = &wm8753_dai_ops_voice_mode2,
1f53aee0
LG
1372},
1373/* DAI HiFi mode 3 */
f0fba2ad 1374{ .name = "wm8753-hifi",
1f53aee0
LG
1375 .playback = {
1376 .stream_name = "HiFi Playback",
1377 .channels_min = 1,
1378 .channels_max = 2,
1379 .rates = WM8753_RATES,
1380 .formats = WM8753_FORMATS,},
1381 .capture = {
1382 .stream_name = "Capture",
1383 .channels_min = 1,
1384 .channels_max = 2,
1385 .rates = WM8753_RATES,
1386 .formats = WM8753_FORMATS,},
6335d055 1387 .ops = &wm8753_dai_ops_hifi_mode3,
1f53aee0
LG
1388},
1389/* DAI Voice mode 3 - dummy */
f0fba2ad 1390{ .name = "wm8753-voice",
1f53aee0
LG
1391},
1392/* DAI HiFi mode 4 */
f0fba2ad 1393{ .name = "wm8753-hifi",
1f53aee0
LG
1394 .playback = {
1395 .stream_name = "HiFi Playback",
1396 .channels_min = 1,
1397 .channels_max = 2,
1398 .rates = WM8753_RATES,
1399 .formats = WM8753_FORMATS,},
1400 .capture = {
1401 .stream_name = "Capture",
1402 .channels_min = 1,
1403 .channels_max = 2,
1404 .rates = WM8753_RATES,
1405 .formats = WM8753_FORMATS,},
6335d055 1406 .ops = &wm8753_dai_ops_hifi_mode4,
1f53aee0
LG
1407},
1408/* DAI Voice mode 4 - dummy */
f0fba2ad 1409{ .name = "wm8753-voice",
1f53aee0
LG
1410},
1411};
1412
f0fba2ad 1413static struct snd_soc_dai_driver wm8753_dai[] = {
9e70c1f0 1414 {
f0fba2ad 1415 .name = "wm8753-aif0",
9e70c1f0
MB
1416 },
1417 {
f0fba2ad 1418 .name = "wm8753-aif1",
9e70c1f0
MB
1419 },
1420};
1f53aee0 1421
f0fba2ad
LG
1422static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
1423 struct snd_soc_dai *dai, unsigned int hifi)
1f53aee0 1424{
f0fba2ad
LG
1425 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1426
1427 if (wm8753->dai_func < 4) {
1428 if (hifi)
1429 dai->driver = &wm8753_all_dai[wm8753->dai_func << 1];
1430 else
1431 dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1];
1f53aee0 1432 }
776065e3 1433 snd_soc_write(codec, WM8753_IOCTL, wm8753->dai_func);
1f53aee0
LG
1434}
1435
1436static void wm8753_work(struct work_struct *work)
1437{
1438 struct snd_soc_codec *codec =
1439 container_of(work, struct snd_soc_codec, delayed_work.work);
0be9898a 1440 wm8753_set_bias_level(codec, codec->bias_level);
1f53aee0
LG
1441}
1442
f0fba2ad 1443static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state)
1f53aee0 1444{
0be9898a 1445 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1f53aee0
LG
1446 return 0;
1447}
1448
f0fba2ad 1449static int wm8753_resume(struct snd_soc_codec *codec)
1f53aee0 1450{
776065e3 1451 u16 *reg_cache = codec->reg_cache;
1f53aee0 1452 int i;
1f53aee0 1453
1f53aee0 1454 /* Sync reg_cache with the hardware */
776065e3
LPC
1455 for (i = 1; i < ARRAY_SIZE(wm8753_reg); i++) {
1456 if (i == WM8753_RESET)
1f53aee0 1457 continue;
e611bd82
MB
1458
1459 /* No point in writing hardware default values back */
776065e3 1460 if (reg_cache[i] == wm8753_reg[i])
e611bd82
MB
1461 continue;
1462
776065e3 1463 snd_soc_write(codec, i, reg_cache[i]);
1f53aee0
LG
1464 }
1465
0be9898a 1466 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1f53aee0
LG
1467
1468 /* charge wm8753 caps */
0be9898a
MB
1469 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) {
1470 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1471 codec->bias_level = SND_SOC_BIAS_ON;
1f53aee0
LG
1472 schedule_delayed_work(&codec->delayed_work,
1473 msecs_to_jiffies(caps_charge));
1474 }
1475
1476 return 0;
1477}
1478
1f53aee0
LG
1479/*
1480 * This function forces any delayed work to be queued and run.
1481 */
1482static int run_delayed_work(struct delayed_work *dwork)
1483{
1484 int ret;
1485
1486 /* cancel any work waiting to be queued. */
1487 ret = cancel_delayed_work(dwork);
1488
1489 /* if there was any work waiting then we run it now and
1490 * wait for it's completion */
1491 if (ret) {
1492 schedule_delayed_work(dwork, 0);
1493 flush_scheduled_work();
1494 }
1495 return ret;
1496}
1497
f0fba2ad 1498static int wm8753_probe(struct snd_soc_codec *codec)
1f53aee0 1499{
f0fba2ad 1500 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
776065e3 1501 int ret;
1f53aee0 1502
f0fba2ad 1503 INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work);
c2bac160 1504
f0fba2ad
LG
1505 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8753->control_type);
1506 if (ret < 0) {
1507 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1508 return ret;
c2bac160
MB
1509 }
1510
c2bac160
MB
1511 ret = wm8753_reset(codec);
1512 if (ret < 0) {
f0fba2ad
LG
1513 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
1514 return ret;
c2bac160
MB
1515 }
1516
f0fba2ad
LG
1517 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1518 wm8753->dai_func = 0;
1519
c2bac160
MB
1520 /* charge output caps */
1521 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1522 schedule_delayed_work(&codec->delayed_work,
1523 msecs_to_jiffies(caps_charge));
1524
1525 /* set the update bits */
776065e3
LPC
1526 snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
1527 snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
1528 snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
1529 snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
1530 snd_soc_update_bits(codec, WM8753_LOUT1V, 0x0100, 0x0100);
1531 snd_soc_update_bits(codec, WM8753_ROUT1V, 0x0100, 0x0100);
1532 snd_soc_update_bits(codec, WM8753_LOUT2V, 0x0100, 0x0100);
1533 snd_soc_update_bits(codec, WM8753_ROUT2V, 0x0100, 0x0100);
1534 snd_soc_update_bits(codec, WM8753_LINVOL, 0x0100, 0x0100);
1535 snd_soc_update_bits(codec, WM8753_RINVOL, 0x0100, 0x0100);
c2bac160 1536
f0fba2ad
LG
1537 snd_soc_add_controls(codec, wm8753_snd_controls,
1538 ARRAY_SIZE(wm8753_snd_controls));
1539 wm8753_add_widgets(codec);
c2bac160
MB
1540
1541 return 0;
c2bac160
MB
1542}
1543
f0fba2ad
LG
1544/* power down chip */
1545static int wm8753_remove(struct snd_soc_codec *codec)
c2bac160 1546{
f0fba2ad
LG
1547 run_delayed_work(&codec->delayed_work);
1548 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1549
1550 return 0;
c2bac160
MB
1551}
1552
f0fba2ad
LG
1553static struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
1554 .probe = wm8753_probe,
1555 .remove = wm8753_remove,
1556 .suspend = wm8753_suspend,
1557 .resume = wm8753_resume,
1558 .set_bias_level = wm8753_set_bias_level,
e5eec34c 1559 .reg_cache_size = ARRAY_SIZE(wm8753_reg),
f0fba2ad
LG
1560 .reg_word_size = sizeof(u16),
1561 .reg_cache_default = wm8753_reg,
1562};
69e169da 1563
f0fba2ad
LG
1564#if defined(CONFIG_SPI_MASTER)
1565static int __devinit wm8753_spi_probe(struct spi_device *spi)
69e169da 1566{
c2bac160 1567 struct wm8753_priv *wm8753;
f0fba2ad 1568 int ret;
69e169da 1569
c2bac160
MB
1570 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL);
1571 if (wm8753 == NULL)
1572 return -ENOMEM;
69e169da 1573
f0fba2ad
LG
1574 wm8753->control_type = SND_SOC_SPI;
1575 spi_set_drvdata(spi, wm8753);
c2bac160 1576
f0fba2ad
LG
1577 ret = snd_soc_register_codec(&spi->dev,
1578 &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai));
1579 if (ret < 0)
1580 kfree(wm8753);
1581 return ret;
69e169da
MB
1582}
1583
f0fba2ad 1584static int __devexit wm8753_spi_remove(struct spi_device *spi)
69e169da 1585{
f0fba2ad
LG
1586 snd_soc_unregister_codec(&spi->dev);
1587 kfree(spi_get_drvdata(spi));
1588 return 0;
69e169da
MB
1589}
1590
f0fba2ad 1591static struct spi_driver wm8753_spi_driver = {
69e169da 1592 .driver = {
f0fba2ad 1593 .name = "wm8753-codec",
f0fba2ad 1594 .owner = THIS_MODULE,
69e169da 1595 },
f0fba2ad
LG
1596 .probe = wm8753_spi_probe,
1597 .remove = __devexit_p(wm8753_spi_remove),
69e169da 1598};
f0fba2ad 1599#endif /* CONFIG_SPI_MASTER */
69e169da 1600
f0fba2ad
LG
1601#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1602static __devinit int wm8753_i2c_probe(struct i2c_client *i2c,
1603 const struct i2c_device_id *id)
69e169da 1604{
c2bac160 1605 struct wm8753_priv *wm8753;
f0fba2ad 1606 int ret;
c2bac160
MB
1607
1608 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL);
1609 if (wm8753 == NULL)
1610 return -ENOMEM;
69e169da 1611
f0fba2ad 1612 i2c_set_clientdata(i2c, wm8753);
f0fba2ad 1613 wm8753->control_type = SND_SOC_I2C;
69e169da 1614
f0fba2ad
LG
1615 ret = snd_soc_register_codec(&i2c->dev,
1616 &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai));
1617 if (ret < 0)
1618 kfree(wm8753);
1619 return ret;
69e169da
MB
1620}
1621
f0fba2ad 1622static __devexit int wm8753_i2c_remove(struct i2c_client *client)
69e169da 1623{
f0fba2ad
LG
1624 snd_soc_unregister_codec(&client->dev);
1625 kfree(i2c_get_clientdata(client));
69e169da
MB
1626 return 0;
1627}
1628
f0fba2ad
LG
1629static const struct i2c_device_id wm8753_i2c_id[] = {
1630 { "wm8753", 0 },
1631 { }
1632};
1633MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
1634
1635static struct i2c_driver wm8753_i2c_driver = {
69e169da 1636 .driver = {
f0fba2ad
LG
1637 .name = "wm8753-codec",
1638 .owner = THIS_MODULE,
69e169da 1639 },
f0fba2ad
LG
1640 .probe = wm8753_i2c_probe,
1641 .remove = __devexit_p(wm8753_i2c_remove),
1642 .id_table = wm8753_i2c_id,
69e169da
MB
1643};
1644#endif
1645
c9b3a40f 1646static int __init wm8753_modinit(void)
64089b84 1647{
f0fba2ad 1648 int ret = 0;
c2bac160
MB
1649#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1650 ret = i2c_add_driver(&wm8753_i2c_driver);
f0fba2ad
LG
1651 if (ret != 0) {
1652 printk(KERN_ERR "Failed to register wm8753 I2C driver: %d\n",
1653 ret);
1654 }
c2bac160
MB
1655#endif
1656#if defined(CONFIG_SPI_MASTER)
1657 ret = spi_register_driver(&wm8753_spi_driver);
f0fba2ad
LG
1658 if (ret != 0) {
1659 printk(KERN_ERR "Failed to register wm8753 SPI driver: %d\n",
1660 ret);
1661 }
c2bac160 1662#endif
f0fba2ad 1663 return ret;
64089b84
MB
1664}
1665module_init(wm8753_modinit);
1666
1667static void __exit wm8753_exit(void)
1668{
c2bac160
MB
1669#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1670 i2c_del_driver(&wm8753_i2c_driver);
1671#endif
1672#if defined(CONFIG_SPI_MASTER)
1673 spi_unregister_driver(&wm8753_spi_driver);
1674#endif
64089b84
MB
1675}
1676module_exit(wm8753_exit);
1677
1f53aee0
LG
1678MODULE_DESCRIPTION("ASoC WM8753 driver");
1679MODULE_AUTHOR("Liam Girdwood");
1680MODULE_LICENSE("GPL");
This page took 0.430401 seconds and 5 git commands to generate.