ASoC: mid-x86: Fix dependency on intel_sst driver
[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>
1f53aee0 48#include <sound/initval.h>
2d6a4ac9 49#include <sound/tlv.h>
1f53aee0
LG
50#include <asm/div64.h>
51
52#include "wm8753.h"
53
1f53aee0
LG
54static int caps_charge = 2000;
55module_param(caps_charge, int, 0);
56MODULE_PARM_DESC(caps_charge, "WM8753 cap charge time (msecs)");
57
58static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
f0fba2ad 59 struct snd_soc_dai *dai, unsigned int hifi);
1f53aee0 60
1f53aee0
LG
61/*
62 * wm8753 register cache
63 * We can't read the WM8753 register space when we
64 * are using 2 wire for device control, so we cache them instead.
65 */
66static const u16 wm8753_reg[] = {
776065e3
LPC
67 0x0000, 0x0008, 0x0000, 0x000a,
68 0x000a, 0x0033, 0x0000, 0x0007,
69 0x00ff, 0x00ff, 0x000f, 0x000f,
70 0x007b, 0x0000, 0x0032, 0x0000,
71 0x00c3, 0x00c3, 0x00c0, 0x0000,
1f53aee0
LG
72 0x0000, 0x0000, 0x0000, 0x0000,
73 0x0000, 0x0000, 0x0000, 0x0000,
1f53aee0 74 0x0000, 0x0000, 0x0000, 0x0000,
776065e3
LPC
75 0x0055, 0x0005, 0x0050, 0x0055,
76 0x0050, 0x0055, 0x0050, 0x0055,
77 0x0079, 0x0079, 0x0079, 0x0079,
78 0x0079, 0x0000, 0x0000, 0x0000,
79 0x0000, 0x0097, 0x0097, 0x0000,
80 0x0004, 0x0000, 0x0083, 0x0024,
81 0x01ba, 0x0000, 0x0083, 0x0024,
82 0x01ba, 0x0000, 0x0000, 0x0000
1f53aee0
LG
83};
84
c2bac160
MB
85/* codec private data */
86struct wm8753_priv {
f0fba2ad 87 enum snd_soc_control_type control_type;
c2bac160
MB
88 unsigned int sysclk;
89 unsigned int pcmclk;
f0fba2ad 90 int dai_func;
c2bac160
MB
91};
92
776065e3 93#define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0)
1f53aee0
LG
94
95/*
96 * WM8753 Controls
97 */
98static const char *wm8753_base[] = {"Linear Control", "Adaptive Boost"};
99static const char *wm8753_base_filter[] =
100 {"130Hz @ 48kHz", "200Hz @ 48kHz", "100Hz @ 16kHz", "400Hz @ 48kHz",
101 "100Hz @ 8kHz", "200Hz @ 8kHz"};
102static const char *wm8753_treble[] = {"8kHz", "4kHz"};
103static const char *wm8753_alc_func[] = {"Off", "Right", "Left", "Stereo"};
104static const char *wm8753_ng_type[] = {"Constant PGA Gain", "Mute ADC Output"};
105static const char *wm8753_3d_func[] = {"Capture", "Playback"};
106static const char *wm8753_3d_uc[] = {"2.2kHz", "1.5kHz"};
107static const char *wm8753_3d_lc[] = {"200Hz", "500Hz"};
108static const char *wm8753_deemp[] = {"None", "32kHz", "44.1kHz", "48kHz"};
109static const char *wm8753_mono_mix[] = {"Stereo", "Left", "Right", "Mono"};
110static const char *wm8753_dac_phase[] = {"Non Inverted", "Inverted"};
111static const char *wm8753_line_mix[] = {"Line 1 + 2", "Line 1 - 2",
112 "Line 1", "Line 2"};
113static const char *wm8753_mono_mux[] = {"Line Mix", "Rx Mix"};
114static const char *wm8753_right_mux[] = {"Line 2", "Rx Mix"};
115static const char *wm8753_left_mux[] = {"Line 1", "Rx Mix"};
116static const char *wm8753_rxmsel[] = {"RXP - RXN", "RXP + RXN", "RXP", "RXN"};
117static const char *wm8753_sidetone_mux[] = {"Left PGA", "Mic 1", "Mic 2",
118 "Right PGA"};
119static const char *wm8753_mono2_src[] = {"Inverted Mono 1", "Left", "Right",
120 "Left + Right"};
121static const char *wm8753_out3[] = {"VREF", "ROUT2", "Left + Right"};
122static const char *wm8753_out4[] = {"VREF", "Capture ST", "LOUT2"};
123static const char *wm8753_radcsel[] = {"PGA", "Line or RXP-RXN", "Sidetone"};
124static const char *wm8753_ladcsel[] = {"PGA", "Line or RXP-RXN", "Line"};
125static const char *wm8753_mono_adc[] = {"Stereo", "Analogue Mix Left",
126 "Analogue Mix Right", "Digital Mono Mix"};
127static const char *wm8753_adc_hp[] = {"3.4Hz @ 48kHz", "82Hz @ 16k",
128 "82Hz @ 8kHz", "170Hz @ 8kHz"};
129static const char *wm8753_adc_filter[] = {"HiFi", "Voice"};
130static const char *wm8753_mic_sel[] = {"Mic 1", "Mic 2", "Mic 3"};
131static const char *wm8753_dai_mode[] = {"DAI 0", "DAI 1", "DAI 2", "DAI 3"};
132static const char *wm8753_dat_sel[] = {"Stereo", "Left ADC", "Right ADC",
133 "Channel Swap"};
ae092c9e 134static const char *wm8753_rout2_phase[] = {"Non Inverted", "Inverted"};
1f53aee0
LG
135
136static const struct soc_enum wm8753_enum[] = {
137SOC_ENUM_SINGLE(WM8753_BASS, 7, 2, wm8753_base),
138SOC_ENUM_SINGLE(WM8753_BASS, 4, 6, wm8753_base_filter),
139SOC_ENUM_SINGLE(WM8753_TREBLE, 6, 2, wm8753_treble),
140SOC_ENUM_SINGLE(WM8753_ALC1, 7, 4, wm8753_alc_func),
141SOC_ENUM_SINGLE(WM8753_NGATE, 1, 2, wm8753_ng_type),
142SOC_ENUM_SINGLE(WM8753_3D, 7, 2, wm8753_3d_func),
143SOC_ENUM_SINGLE(WM8753_3D, 6, 2, wm8753_3d_uc),
144SOC_ENUM_SINGLE(WM8753_3D, 5, 2, wm8753_3d_lc),
145SOC_ENUM_SINGLE(WM8753_DAC, 1, 4, wm8753_deemp),
146SOC_ENUM_SINGLE(WM8753_DAC, 4, 4, wm8753_mono_mix),
147SOC_ENUM_SINGLE(WM8753_DAC, 6, 2, wm8753_dac_phase),
148SOC_ENUM_SINGLE(WM8753_INCTL1, 3, 4, wm8753_line_mix),
149SOC_ENUM_SINGLE(WM8753_INCTL1, 2, 2, wm8753_mono_mux),
150SOC_ENUM_SINGLE(WM8753_INCTL1, 1, 2, wm8753_right_mux),
151SOC_ENUM_SINGLE(WM8753_INCTL1, 0, 2, wm8753_left_mux),
152SOC_ENUM_SINGLE(WM8753_INCTL2, 6, 4, wm8753_rxmsel),
153SOC_ENUM_SINGLE(WM8753_INCTL2, 4, 4, wm8753_sidetone_mux),
154SOC_ENUM_SINGLE(WM8753_OUTCTL, 7, 4, wm8753_mono2_src),
155SOC_ENUM_SINGLE(WM8753_OUTCTL, 0, 3, wm8753_out3),
156SOC_ENUM_SINGLE(WM8753_ADCTL2, 7, 3, wm8753_out4),
157SOC_ENUM_SINGLE(WM8753_ADCIN, 2, 3, wm8753_radcsel),
158SOC_ENUM_SINGLE(WM8753_ADCIN, 0, 3, wm8753_ladcsel),
159SOC_ENUM_SINGLE(WM8753_ADCIN, 4, 4, wm8753_mono_adc),
160SOC_ENUM_SINGLE(WM8753_ADC, 2, 4, wm8753_adc_hp),
161SOC_ENUM_SINGLE(WM8753_ADC, 4, 2, wm8753_adc_filter),
162SOC_ENUM_SINGLE(WM8753_MICBIAS, 6, 3, wm8753_mic_sel),
163SOC_ENUM_SINGLE(WM8753_IOCTL, 2, 4, wm8753_dai_mode),
164SOC_ENUM_SINGLE(WM8753_ADC, 7, 4, wm8753_dat_sel),
ae092c9e 165SOC_ENUM_SINGLE(WM8753_OUTCTL, 2, 2, wm8753_rout2_phase),
1f53aee0
LG
166};
167
168
169static int wm8753_get_dai(struct snd_kcontrol *kcontrol,
170 struct snd_ctl_elem_value *ucontrol)
171{
172 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
776065e3 173 int mode = snd_soc_read(codec, WM8753_IOCTL);
1f53aee0
LG
174
175 ucontrol->value.integer.value[0] = (mode & 0xc) >> 2;
176 return 0;
177}
178
179static int wm8753_set_dai(struct snd_kcontrol *kcontrol,
180 struct snd_ctl_elem_value *ucontrol)
181{
182 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
776065e3 183 int mode = snd_soc_read(codec, WM8753_IOCTL);
f0fba2ad 184 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1f53aee0 185
60fc684a 186 if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0])
1f53aee0
LG
187 return 0;
188
189 mode &= 0xfff3;
190 mode |= (ucontrol->value.integer.value[0] << 2);
191
f0fba2ad 192 wm8753->dai_func = ucontrol->value.integer.value[0];
1f53aee0
LG
193 return 1;
194}
195
2cc8c609
MM
196static const DECLARE_TLV_DB_SCALE(rec_mix_tlv, -1500, 300, 0);
197static const DECLARE_TLV_DB_SCALE(mic_preamp_tlv, 1200, 600, 0);
198static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1);
199static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
200static const unsigned int out_tlv[] = {
201 TLV_DB_RANGE_HEAD(2),
202 /* 0000000 - 0101111 = "Analogue mute" */
203 0, 48, TLV_DB_SCALE_ITEM(-25500, 0, 0),
204 48, 127, TLV_DB_SCALE_ITEM(-7300, 100, 0),
205};
206static const DECLARE_TLV_DB_SCALE(mix_tlv, -1500, 300, 0);
207static const DECLARE_TLV_DB_SCALE(voice_mix_tlv, -1200, 300, 0);
208static const DECLARE_TLV_DB_SCALE(pga_tlv, -1725, 75, 0);
2d6a4ac9 209
1f53aee0 210static const struct snd_kcontrol_new wm8753_snd_controls[] = {
2cc8c609
MM
211SOC_DOUBLE_R_TLV("PCM Volume", WM8753_LDAC, WM8753_RDAC, 0, 255, 0, dac_tlv),
212
213SOC_DOUBLE_R_TLV("ADC Capture Volume", WM8753_LADC, WM8753_RADC, 0, 255, 0,
214 adc_tlv),
215
216SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8753_LOUT1V, WM8753_ROUT1V,
217 0, 127, 0, out_tlv),
218SOC_DOUBLE_R_TLV("Speaker Playback Volume", WM8753_LOUT2V, WM8753_ROUT2V, 0,
219 127, 0, out_tlv),
220
221SOC_SINGLE_TLV("Mono Playback Volume", WM8753_MOUTV, 0, 127, 0, out_tlv),
222
223SOC_DOUBLE_R_TLV("Bypass Playback Volume", WM8753_LOUTM1, WM8753_ROUTM1, 4, 7,
224 1, mix_tlv),
225SOC_DOUBLE_R_TLV("Sidetone Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 4,
226 7, 1, mix_tlv),
227SOC_DOUBLE_R_TLV("Voice Playback Volume", WM8753_LOUTM2, WM8753_ROUTM2, 0, 7,
228 1, voice_mix_tlv),
229
230SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8753_LOUT1V, WM8753_ROUT1V, 7,
231 1, 0),
232SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8753_LOUT2V, WM8753_ROUT2V, 7,
233 1, 0),
234
235SOC_SINGLE_TLV("Mono Bypass Playback Volume", WM8753_MOUTM1, 4, 7, 1, mix_tlv),
236SOC_SINGLE_TLV("Mono Sidetone Playback Volume", WM8753_MOUTM2, 4, 7, 1,
237 mix_tlv),
238SOC_SINGLE_TLV("Mono Voice Playback Volume", WM8753_MOUTM2, 0, 7, 1,
239 voice_mix_tlv),
1f53aee0
LG
240SOC_SINGLE("Mono Playback ZC Switch", WM8753_MOUTV, 7, 1, 0),
241
242SOC_ENUM("Bass Boost", wm8753_enum[0]),
243SOC_ENUM("Bass Filter", wm8753_enum[1]),
244SOC_SINGLE("Bass Volume", WM8753_BASS, 0, 15, 1),
245
246SOC_SINGLE("Treble Volume", WM8753_TREBLE, 0, 15, 1),
247SOC_ENUM("Treble Cut-off", wm8753_enum[2]),
248
2cc8c609
MM
249SOC_DOUBLE_TLV("Sidetone Capture Volume", WM8753_RECMIX1, 0, 4, 7, 1,
250 rec_mix_tlv),
251SOC_SINGLE_TLV("Voice Sidetone Capture Volume", WM8753_RECMIX2, 0, 7, 1,
252 rec_mix_tlv),
1f53aee0 253
2cc8c609
MM
254SOC_DOUBLE_R_TLV("Capture Volume", WM8753_LINVOL, WM8753_RINVOL, 0, 63, 0,
255 pga_tlv),
1f53aee0
LG
256SOC_DOUBLE_R("Capture ZC Switch", WM8753_LINVOL, WM8753_RINVOL, 6, 1, 0),
257SOC_DOUBLE_R("Capture Switch", WM8753_LINVOL, WM8753_RINVOL, 7, 1, 1),
258
259SOC_ENUM("Capture Filter Select", wm8753_enum[23]),
260SOC_ENUM("Capture Filter Cut-off", wm8753_enum[24]),
261SOC_SINGLE("Capture Filter Switch", WM8753_ADC, 0, 1, 1),
262
263SOC_SINGLE("ALC Capture Target Volume", WM8753_ALC1, 0, 7, 0),
264SOC_SINGLE("ALC Capture Max Volume", WM8753_ALC1, 4, 7, 0),
265SOC_ENUM("ALC Capture Function", wm8753_enum[3]),
266SOC_SINGLE("ALC Capture ZC Switch", WM8753_ALC2, 8, 1, 0),
267SOC_SINGLE("ALC Capture Hold Time", WM8753_ALC2, 0, 15, 1),
268SOC_SINGLE("ALC Capture Decay Time", WM8753_ALC3, 4, 15, 1),
269SOC_SINGLE("ALC Capture Attack Time", WM8753_ALC3, 0, 15, 0),
270SOC_SINGLE("ALC Capture NG Threshold", WM8753_NGATE, 3, 31, 0),
271SOC_ENUM("ALC Capture NG Type", wm8753_enum[4]),
272SOC_SINGLE("ALC Capture NG Switch", WM8753_NGATE, 0, 1, 0),
273
274SOC_ENUM("3D Function", wm8753_enum[5]),
275SOC_ENUM("3D Upper Cut-off", wm8753_enum[6]),
276SOC_ENUM("3D Lower Cut-off", wm8753_enum[7]),
277SOC_SINGLE("3D Volume", WM8753_3D, 1, 15, 0),
278SOC_SINGLE("3D Switch", WM8753_3D, 0, 1, 0),
279
280SOC_SINGLE("Capture 6dB Attenuate", WM8753_ADCTL1, 2, 1, 0),
281SOC_SINGLE("Playback 6dB Attenuate", WM8753_ADCTL1, 1, 1, 0),
282
283SOC_ENUM("De-emphasis", wm8753_enum[8]),
284SOC_ENUM("Playback Mono Mix", wm8753_enum[9]),
285SOC_ENUM("Playback Phase", wm8753_enum[10]),
286
2cc8c609
MM
287SOC_SINGLE_TLV("Mic2 Capture Volume", WM8753_INCTL1, 7, 3, 0, mic_preamp_tlv),
288SOC_SINGLE_TLV("Mic1 Capture Volume", WM8753_INCTL1, 5, 3, 0, mic_preamp_tlv),
1f53aee0
LG
289
290SOC_ENUM_EXT("DAI Mode", wm8753_enum[26], wm8753_get_dai, wm8753_set_dai),
291
292SOC_ENUM("ADC Data Select", wm8753_enum[27]),
ae092c9e 293SOC_ENUM("ROUT2 Phase", wm8753_enum[28]),
1f53aee0
LG
294};
295
1f53aee0
LG
296/*
297 * _DAPM_ Controls
298 */
299
300/* Left Mixer */
301static const struct snd_kcontrol_new wm8753_left_mixer_controls[] = {
302SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_LOUTM2, 8, 1, 0),
303SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_LOUTM2, 7, 1, 0),
304SOC_DAPM_SINGLE("Left Playback Switch", WM8753_LOUTM1, 8, 1, 0),
305SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_LOUTM1, 7, 1, 0),
306};
307
308/* Right mixer */
309static const struct snd_kcontrol_new wm8753_right_mixer_controls[] = {
310SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_ROUTM2, 8, 1, 0),
311SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_ROUTM2, 7, 1, 0),
312SOC_DAPM_SINGLE("Right Playback Switch", WM8753_ROUTM1, 8, 1, 0),
313SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_ROUTM1, 7, 1, 0),
314};
315
316/* Mono mixer */
317static const struct snd_kcontrol_new wm8753_mono_mixer_controls[] = {
318SOC_DAPM_SINGLE("Left Playback Switch", WM8753_MOUTM1, 8, 1, 0),
319SOC_DAPM_SINGLE("Right Playback Switch", WM8753_MOUTM2, 8, 1, 0),
320SOC_DAPM_SINGLE("Voice Playback Switch", WM8753_MOUTM2, 3, 1, 0),
321SOC_DAPM_SINGLE("Sidetone Playback Switch", WM8753_MOUTM2, 7, 1, 0),
322SOC_DAPM_SINGLE("Bypass Playback Switch", WM8753_MOUTM1, 7, 1, 0),
323};
324
325/* Mono 2 Mux */
326static const struct snd_kcontrol_new wm8753_mono2_controls =
327SOC_DAPM_ENUM("Route", wm8753_enum[17]);
328
329/* Out 3 Mux */
330static const struct snd_kcontrol_new wm8753_out3_controls =
331SOC_DAPM_ENUM("Route", wm8753_enum[18]);
332
333/* Out 4 Mux */
334static const struct snd_kcontrol_new wm8753_out4_controls =
335SOC_DAPM_ENUM("Route", wm8753_enum[19]);
336
337/* ADC Mono Mix */
338static const struct snd_kcontrol_new wm8753_adc_mono_controls =
339SOC_DAPM_ENUM("Route", wm8753_enum[22]);
340
341/* Record mixer */
342static const struct snd_kcontrol_new wm8753_record_mixer_controls[] = {
343SOC_DAPM_SINGLE("Voice Capture Switch", WM8753_RECMIX2, 3, 1, 0),
344SOC_DAPM_SINGLE("Left Capture Switch", WM8753_RECMIX1, 3, 1, 0),
345SOC_DAPM_SINGLE("Right Capture Switch", WM8753_RECMIX1, 7, 1, 0),
346};
347
348/* Left ADC mux */
349static const struct snd_kcontrol_new wm8753_adc_left_controls =
350SOC_DAPM_ENUM("Route", wm8753_enum[21]);
351
352/* Right ADC mux */
353static const struct snd_kcontrol_new wm8753_adc_right_controls =
354SOC_DAPM_ENUM("Route", wm8753_enum[20]);
355
356/* MIC mux */
357static const struct snd_kcontrol_new wm8753_mic_mux_controls =
358SOC_DAPM_ENUM("Route", wm8753_enum[16]);
359
360/* ALC mixer */
361static const struct snd_kcontrol_new wm8753_alc_mixer_controls[] = {
362SOC_DAPM_SINGLE("Line Capture Switch", WM8753_INCTL2, 3, 1, 0),
363SOC_DAPM_SINGLE("Mic2 Capture Switch", WM8753_INCTL2, 2, 1, 0),
364SOC_DAPM_SINGLE("Mic1 Capture Switch", WM8753_INCTL2, 1, 1, 0),
365SOC_DAPM_SINGLE("Rx Capture Switch", WM8753_INCTL2, 0, 1, 0),
366};
367
368/* Left Line mux */
369static const struct snd_kcontrol_new wm8753_line_left_controls =
370SOC_DAPM_ENUM("Route", wm8753_enum[14]);
371
372/* Right Line mux */
373static const struct snd_kcontrol_new wm8753_line_right_controls =
374SOC_DAPM_ENUM("Route", wm8753_enum[13]);
375
376/* Mono Line mux */
377static const struct snd_kcontrol_new wm8753_line_mono_controls =
378SOC_DAPM_ENUM("Route", wm8753_enum[12]);
379
380/* Line mux and mixer */
381static const struct snd_kcontrol_new wm8753_line_mux_mix_controls =
382SOC_DAPM_ENUM("Route", wm8753_enum[11]);
383
384/* Rx mux and mixer */
385static const struct snd_kcontrol_new wm8753_rx_mux_mix_controls =
386SOC_DAPM_ENUM("Route", wm8753_enum[15]);
387
388/* Mic Selector Mux */
389static const struct snd_kcontrol_new wm8753_mic_sel_mux_controls =
390SOC_DAPM_ENUM("Route", wm8753_enum[25]);
391
392static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = {
393SND_SOC_DAPM_MICBIAS("Mic Bias", WM8753_PWR1, 5, 0),
394SND_SOC_DAPM_MIXER("Left Mixer", WM8753_PWR4, 0, 0,
395 &wm8753_left_mixer_controls[0], ARRAY_SIZE(wm8753_left_mixer_controls)),
396SND_SOC_DAPM_PGA("Left Out 1", WM8753_PWR3, 8, 0, NULL, 0),
397SND_SOC_DAPM_PGA("Left Out 2", WM8753_PWR3, 6, 0, NULL, 0),
398SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", WM8753_PWR1, 3, 0),
399SND_SOC_DAPM_OUTPUT("LOUT1"),
400SND_SOC_DAPM_OUTPUT("LOUT2"),
401SND_SOC_DAPM_MIXER("Right Mixer", WM8753_PWR4, 1, 0,
402 &wm8753_right_mixer_controls[0], ARRAY_SIZE(wm8753_right_mixer_controls)),
403SND_SOC_DAPM_PGA("Right Out 1", WM8753_PWR3, 7, 0, NULL, 0),
404SND_SOC_DAPM_PGA("Right Out 2", WM8753_PWR3, 5, 0, NULL, 0),
405SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", WM8753_PWR1, 2, 0),
406SND_SOC_DAPM_OUTPUT("ROUT1"),
407SND_SOC_DAPM_OUTPUT("ROUT2"),
408SND_SOC_DAPM_MIXER("Mono Mixer", WM8753_PWR4, 2, 0,
409 &wm8753_mono_mixer_controls[0], ARRAY_SIZE(wm8753_mono_mixer_controls)),
410SND_SOC_DAPM_PGA("Mono Out 1", WM8753_PWR3, 2, 0, NULL, 0),
411SND_SOC_DAPM_PGA("Mono Out 2", WM8753_PWR3, 1, 0, NULL, 0),
412SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", WM8753_PWR1, 4, 0),
413SND_SOC_DAPM_OUTPUT("MONO1"),
414SND_SOC_DAPM_MUX("Mono 2 Mux", SND_SOC_NOPM, 0, 0, &wm8753_mono2_controls),
415SND_SOC_DAPM_OUTPUT("MONO2"),
416SND_SOC_DAPM_MIXER("Out3 Left + Right", -1, 0, 0, NULL, 0),
417SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out3_controls),
418SND_SOC_DAPM_PGA("Out 3", WM8753_PWR3, 4, 0, NULL, 0),
419SND_SOC_DAPM_OUTPUT("OUT3"),
420SND_SOC_DAPM_MUX("Out4 Mux", SND_SOC_NOPM, 0, 0, &wm8753_out4_controls),
421SND_SOC_DAPM_PGA("Out 4", WM8753_PWR3, 3, 0, NULL, 0),
422SND_SOC_DAPM_OUTPUT("OUT4"),
423SND_SOC_DAPM_MIXER("Playback Mixer", WM8753_PWR4, 3, 0,
424 &wm8753_record_mixer_controls[0],
425 ARRAY_SIZE(wm8753_record_mixer_controls)),
426SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8753_PWR2, 3, 0),
427SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8753_PWR2, 2, 0),
428SND_SOC_DAPM_MUX("Capture Left Mixer", SND_SOC_NOPM, 0, 0,
429 &wm8753_adc_mono_controls),
430SND_SOC_DAPM_MUX("Capture Right Mixer", SND_SOC_NOPM, 0, 0,
431 &wm8753_adc_mono_controls),
432SND_SOC_DAPM_MUX("Capture Left Mux", SND_SOC_NOPM, 0, 0,
433 &wm8753_adc_left_controls),
434SND_SOC_DAPM_MUX("Capture Right Mux", SND_SOC_NOPM, 0, 0,
435 &wm8753_adc_right_controls),
436SND_SOC_DAPM_MUX("Mic Sidetone Mux", SND_SOC_NOPM, 0, 0,
437 &wm8753_mic_mux_controls),
438SND_SOC_DAPM_PGA("Left Capture Volume", WM8753_PWR2, 5, 0, NULL, 0),
439SND_SOC_DAPM_PGA("Right Capture Volume", WM8753_PWR2, 4, 0, NULL, 0),
440SND_SOC_DAPM_MIXER("ALC Mixer", WM8753_PWR2, 6, 0,
441 &wm8753_alc_mixer_controls[0], ARRAY_SIZE(wm8753_alc_mixer_controls)),
442SND_SOC_DAPM_MUX("Line Left Mux", SND_SOC_NOPM, 0, 0,
443 &wm8753_line_left_controls),
444SND_SOC_DAPM_MUX("Line Right Mux", SND_SOC_NOPM, 0, 0,
445 &wm8753_line_right_controls),
446SND_SOC_DAPM_MUX("Line Mono Mux", SND_SOC_NOPM, 0, 0,
447 &wm8753_line_mono_controls),
448SND_SOC_DAPM_MUX("Line Mixer", WM8753_PWR2, 0, 0,
449 &wm8753_line_mux_mix_controls),
450SND_SOC_DAPM_MUX("Rx Mixer", WM8753_PWR2, 1, 0,
451 &wm8753_rx_mux_mix_controls),
452SND_SOC_DAPM_PGA("Mic 1 Volume", WM8753_PWR2, 8, 0, NULL, 0),
453SND_SOC_DAPM_PGA("Mic 2 Volume", WM8753_PWR2, 7, 0, NULL, 0),
454SND_SOC_DAPM_MUX("Mic Selection Mux", SND_SOC_NOPM, 0, 0,
455 &wm8753_mic_sel_mux_controls),
456SND_SOC_DAPM_INPUT("LINE1"),
457SND_SOC_DAPM_INPUT("LINE2"),
458SND_SOC_DAPM_INPUT("RXP"),
459SND_SOC_DAPM_INPUT("RXN"),
460SND_SOC_DAPM_INPUT("ACIN"),
461SND_SOC_DAPM_OUTPUT("ACOP"),
462SND_SOC_DAPM_INPUT("MIC1N"),
463SND_SOC_DAPM_INPUT("MIC1"),
464SND_SOC_DAPM_INPUT("MIC2N"),
465SND_SOC_DAPM_INPUT("MIC2"),
466SND_SOC_DAPM_VMID("VREF"),
467};
468
a65f0568 469static const struct snd_soc_dapm_route audio_map[] = {
1f53aee0
LG
470 /* left mixer */
471 {"Left Mixer", "Left Playback Switch", "Left DAC"},
472 {"Left Mixer", "Voice Playback Switch", "Voice DAC"},
473 {"Left Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
474 {"Left Mixer", "Bypass Playback Switch", "Line Left Mux"},
475
476 /* right mixer */
477 {"Right Mixer", "Right Playback Switch", "Right DAC"},
478 {"Right Mixer", "Voice Playback Switch", "Voice DAC"},
479 {"Right Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
480 {"Right Mixer", "Bypass Playback Switch", "Line Right Mux"},
481
482 /* mono mixer */
483 {"Mono Mixer", "Voice Playback Switch", "Voice DAC"},
484 {"Mono Mixer", "Left Playback Switch", "Left DAC"},
485 {"Mono Mixer", "Right Playback Switch", "Right DAC"},
486 {"Mono Mixer", "Sidetone Playback Switch", "Mic Sidetone Mux"},
487 {"Mono Mixer", "Bypass Playback Switch", "Line Mono Mux"},
488
489 /* left out */
490 {"Left Out 1", NULL, "Left Mixer"},
491 {"Left Out 2", NULL, "Left Mixer"},
492 {"LOUT1", NULL, "Left Out 1"},
493 {"LOUT2", NULL, "Left Out 2"},
494
495 /* right out */
496 {"Right Out 1", NULL, "Right Mixer"},
497 {"Right Out 2", NULL, "Right Mixer"},
498 {"ROUT1", NULL, "Right Out 1"},
499 {"ROUT2", NULL, "Right Out 2"},
500
501 /* mono 1 out */
502 {"Mono Out 1", NULL, "Mono Mixer"},
503 {"MONO1", NULL, "Mono Out 1"},
504
505 /* mono 2 out */
506 {"Mono 2 Mux", "Left + Right", "Out3 Left + Right"},
507 {"Mono 2 Mux", "Inverted Mono 1", "MONO1"},
508 {"Mono 2 Mux", "Left", "Left Mixer"},
509 {"Mono 2 Mux", "Right", "Right Mixer"},
510 {"Mono Out 2", NULL, "Mono 2 Mux"},
511 {"MONO2", NULL, "Mono Out 2"},
512
513 /* out 3 */
514 {"Out3 Left + Right", NULL, "Left Mixer"},
515 {"Out3 Left + Right", NULL, "Right Mixer"},
516 {"Out3 Mux", "VREF", "VREF"},
517 {"Out3 Mux", "Left + Right", "Out3 Left + Right"},
518 {"Out3 Mux", "ROUT2", "ROUT2"},
519 {"Out 3", NULL, "Out3 Mux"},
520 {"OUT3", NULL, "Out 3"},
521
522 /* out 4 */
523 {"Out4 Mux", "VREF", "VREF"},
4037314a 524 {"Out4 Mux", "Capture ST", "Playback Mixer"},
1f53aee0
LG
525 {"Out4 Mux", "LOUT2", "LOUT2"},
526 {"Out 4", NULL, "Out4 Mux"},
527 {"OUT4", NULL, "Out 4"},
528
529 /* record mixer */
530 {"Playback Mixer", "Left Capture Switch", "Left Mixer"},
531 {"Playback Mixer", "Voice Capture Switch", "Mono Mixer"},
532 {"Playback Mixer", "Right Capture Switch", "Right Mixer"},
533
534 /* Mic/SideTone Mux */
535 {"Mic Sidetone Mux", "Left PGA", "Left Capture Volume"},
536 {"Mic Sidetone Mux", "Right PGA", "Right Capture Volume"},
537 {"Mic Sidetone Mux", "Mic 1", "Mic 1 Volume"},
538 {"Mic Sidetone Mux", "Mic 2", "Mic 2 Volume"},
539
540 /* Capture Left Mux */
541 {"Capture Left Mux", "PGA", "Left Capture Volume"},
542 {"Capture Left Mux", "Line or RXP-RXN", "Line Left Mux"},
543 {"Capture Left Mux", "Line", "LINE1"},
544
545 /* Capture Right Mux */
546 {"Capture Right Mux", "PGA", "Right Capture Volume"},
547 {"Capture Right Mux", "Line or RXP-RXN", "Line Right Mux"},
4037314a 548 {"Capture Right Mux", "Sidetone", "Playback Mixer"},
1f53aee0
LG
549
550 /* Mono Capture mixer-mux */
551 {"Capture Right Mixer", "Stereo", "Capture Right Mux"},
877ae707 552 {"Capture Left Mixer", "Stereo", "Capture Left Mux"},
1f53aee0
LG
553 {"Capture Left Mixer", "Analogue Mix Left", "Capture Left Mux"},
554 {"Capture Left Mixer", "Analogue Mix Left", "Capture Right Mux"},
555 {"Capture Right Mixer", "Analogue Mix Right", "Capture Left Mux"},
556 {"Capture Right Mixer", "Analogue Mix Right", "Capture Right Mux"},
557 {"Capture Left Mixer", "Digital Mono Mix", "Capture Left Mux"},
558 {"Capture Left Mixer", "Digital Mono Mix", "Capture Right Mux"},
559 {"Capture Right Mixer", "Digital Mono Mix", "Capture Left Mux"},
560 {"Capture Right Mixer", "Digital Mono Mix", "Capture Right Mux"},
561
562 /* ADC */
563 {"Left ADC", NULL, "Capture Left Mixer"},
564 {"Right ADC", NULL, "Capture Right Mixer"},
565
566 /* Left Capture Volume */
567 {"Left Capture Volume", NULL, "ACIN"},
568
569 /* Right Capture Volume */
570 {"Right Capture Volume", NULL, "Mic 2 Volume"},
571
572 /* ALC Mixer */
573 {"ALC Mixer", "Line Capture Switch", "Line Mixer"},
574 {"ALC Mixer", "Mic2 Capture Switch", "Mic 2 Volume"},
575 {"ALC Mixer", "Mic1 Capture Switch", "Mic 1 Volume"},
576 {"ALC Mixer", "Rx Capture Switch", "Rx Mixer"},
577
578 /* Line Left Mux */
579 {"Line Left Mux", "Line 1", "LINE1"},
580 {"Line Left Mux", "Rx Mix", "Rx Mixer"},
581
582 /* Line Right Mux */
583 {"Line Right Mux", "Line 2", "LINE2"},
584 {"Line Right Mux", "Rx Mix", "Rx Mixer"},
585
586 /* Line Mono Mux */
587 {"Line Mono Mux", "Line Mix", "Line Mixer"},
588 {"Line Mono Mux", "Rx Mix", "Rx Mixer"},
589
590 /* Line Mixer/Mux */
591 {"Line Mixer", "Line 1 + 2", "LINE1"},
592 {"Line Mixer", "Line 1 - 2", "LINE1"},
593 {"Line Mixer", "Line 1 + 2", "LINE2"},
594 {"Line Mixer", "Line 1 - 2", "LINE2"},
595 {"Line Mixer", "Line 1", "LINE1"},
596 {"Line Mixer", "Line 2", "LINE2"},
597
598 /* Rx Mixer/Mux */
599 {"Rx Mixer", "RXP - RXN", "RXP"},
600 {"Rx Mixer", "RXP + RXN", "RXP"},
601 {"Rx Mixer", "RXP - RXN", "RXN"},
602 {"Rx Mixer", "RXP + RXN", "RXN"},
603 {"Rx Mixer", "RXP", "RXP"},
604 {"Rx Mixer", "RXN", "RXN"},
605
606 /* Mic 1 Volume */
607 {"Mic 1 Volume", NULL, "MIC1N"},
608 {"Mic 1 Volume", NULL, "Mic Selection Mux"},
609
610 /* Mic 2 Volume */
611 {"Mic 2 Volume", NULL, "MIC2N"},
612 {"Mic 2 Volume", NULL, "MIC2"},
613
614 /* Mic Selector Mux */
615 {"Mic Selection Mux", "Mic 1", "MIC1"},
616 {"Mic Selection Mux", "Mic 2", "MIC2N"},
617 {"Mic Selection Mux", "Mic 3", "MIC2"},
618
619 /* ACOP */
620 {"ACOP", NULL, "ALC Mixer"},
1f53aee0
LG
621};
622
623static int wm8753_add_widgets(struct snd_soc_codec *codec)
624{
ce6120cc 625 struct snd_soc_dapm_context *dapm = &codec->dapm;
1f53aee0 626
ce6120cc
LG
627 snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets,
628 ARRAY_SIZE(wm8753_dapm_widgets));
629 snd_soc_dapm_add_routes(dapm, 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 }
ce6120cc 1248 codec->dapm.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{
ce6120cc
LG
1438 struct snd_soc_dapm_context *dapm =
1439 container_of(work, struct snd_soc_dapm_context,
1440 delayed_work.work);
1441 struct snd_soc_codec *codec = dapm->codec;
1442 wm8753_set_bias_level(codec, dapm->bias_level);
1f53aee0
LG
1443}
1444
f0fba2ad 1445static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state)
1f53aee0 1446{
0be9898a 1447 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1f53aee0
LG
1448 return 0;
1449}
1450
f0fba2ad 1451static int wm8753_resume(struct snd_soc_codec *codec)
1f53aee0 1452{
776065e3 1453 u16 *reg_cache = codec->reg_cache;
1f53aee0 1454 int i;
1f53aee0 1455
1f53aee0 1456 /* Sync reg_cache with the hardware */
776065e3
LPC
1457 for (i = 1; i < ARRAY_SIZE(wm8753_reg); i++) {
1458 if (i == WM8753_RESET)
1f53aee0 1459 continue;
e611bd82
MB
1460
1461 /* No point in writing hardware default values back */
776065e3 1462 if (reg_cache[i] == wm8753_reg[i])
e611bd82
MB
1463 continue;
1464
776065e3 1465 snd_soc_write(codec, i, reg_cache[i]);
1f53aee0
LG
1466 }
1467
0be9898a 1468 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1f53aee0
LG
1469
1470 /* charge wm8753 caps */
ce6120cc 1471 if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
0be9898a 1472 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
ce6120cc
LG
1473 codec->dapm.bias_level = SND_SOC_BIAS_ON;
1474 schedule_delayed_work(&codec->dapm.delayed_work,
1f53aee0
LG
1475 msecs_to_jiffies(caps_charge));
1476 }
1477
1478 return 0;
1479}
1480
f0fba2ad 1481static int wm8753_probe(struct snd_soc_codec *codec)
1f53aee0 1482{
f0fba2ad 1483 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
776065e3 1484 int ret;
1f53aee0 1485
ce6120cc 1486 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work);
c2bac160 1487
f0fba2ad
LG
1488 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8753->control_type);
1489 if (ret < 0) {
1490 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1491 return ret;
c2bac160
MB
1492 }
1493
c2bac160
MB
1494 ret = wm8753_reset(codec);
1495 if (ret < 0) {
f0fba2ad
LG
1496 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
1497 return ret;
c2bac160
MB
1498 }
1499
f0fba2ad
LG
1500 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1501 wm8753->dai_func = 0;
1502
c2bac160
MB
1503 /* charge output caps */
1504 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
ce6120cc 1505 schedule_delayed_work(&codec->dapm.delayed_work,
c2bac160
MB
1506 msecs_to_jiffies(caps_charge));
1507
1508 /* set the update bits */
776065e3
LPC
1509 snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
1510 snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
1511 snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100);
1512 snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100);
1513 snd_soc_update_bits(codec, WM8753_LOUT1V, 0x0100, 0x0100);
1514 snd_soc_update_bits(codec, WM8753_ROUT1V, 0x0100, 0x0100);
1515 snd_soc_update_bits(codec, WM8753_LOUT2V, 0x0100, 0x0100);
1516 snd_soc_update_bits(codec, WM8753_ROUT2V, 0x0100, 0x0100);
1517 snd_soc_update_bits(codec, WM8753_LINVOL, 0x0100, 0x0100);
1518 snd_soc_update_bits(codec, WM8753_RINVOL, 0x0100, 0x0100);
c2bac160 1519
f0fba2ad
LG
1520 snd_soc_add_controls(codec, wm8753_snd_controls,
1521 ARRAY_SIZE(wm8753_snd_controls));
1522 wm8753_add_widgets(codec);
c2bac160
MB
1523
1524 return 0;
c2bac160
MB
1525}
1526
f0fba2ad
LG
1527/* power down chip */
1528static int wm8753_remove(struct snd_soc_codec *codec)
c2bac160 1529{
fdea0571 1530 flush_delayed_work_sync(&codec->dapm.delayed_work);
f0fba2ad
LG
1531 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1532
1533 return 0;
c2bac160
MB
1534}
1535
f0fba2ad
LG
1536static struct snd_soc_codec_driver soc_codec_dev_wm8753 = {
1537 .probe = wm8753_probe,
1538 .remove = wm8753_remove,
1539 .suspend = wm8753_suspend,
1540 .resume = wm8753_resume,
1541 .set_bias_level = wm8753_set_bias_level,
e5eec34c 1542 .reg_cache_size = ARRAY_SIZE(wm8753_reg),
f0fba2ad
LG
1543 .reg_word_size = sizeof(u16),
1544 .reg_cache_default = wm8753_reg,
1545};
69e169da 1546
f0fba2ad
LG
1547#if defined(CONFIG_SPI_MASTER)
1548static int __devinit wm8753_spi_probe(struct spi_device *spi)
69e169da 1549{
c2bac160 1550 struct wm8753_priv *wm8753;
f0fba2ad 1551 int ret;
69e169da 1552
c2bac160
MB
1553 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL);
1554 if (wm8753 == NULL)
1555 return -ENOMEM;
69e169da 1556
f0fba2ad
LG
1557 wm8753->control_type = SND_SOC_SPI;
1558 spi_set_drvdata(spi, wm8753);
c2bac160 1559
f0fba2ad
LG
1560 ret = snd_soc_register_codec(&spi->dev,
1561 &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai));
1562 if (ret < 0)
1563 kfree(wm8753);
1564 return ret;
69e169da
MB
1565}
1566
f0fba2ad 1567static int __devexit wm8753_spi_remove(struct spi_device *spi)
69e169da 1568{
f0fba2ad
LG
1569 snd_soc_unregister_codec(&spi->dev);
1570 kfree(spi_get_drvdata(spi));
1571 return 0;
69e169da
MB
1572}
1573
f0fba2ad 1574static struct spi_driver wm8753_spi_driver = {
69e169da 1575 .driver = {
f0fba2ad 1576 .name = "wm8753-codec",
f0fba2ad 1577 .owner = THIS_MODULE,
69e169da 1578 },
f0fba2ad
LG
1579 .probe = wm8753_spi_probe,
1580 .remove = __devexit_p(wm8753_spi_remove),
69e169da 1581};
f0fba2ad 1582#endif /* CONFIG_SPI_MASTER */
69e169da 1583
f0fba2ad
LG
1584#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1585static __devinit int wm8753_i2c_probe(struct i2c_client *i2c,
1586 const struct i2c_device_id *id)
69e169da 1587{
c2bac160 1588 struct wm8753_priv *wm8753;
f0fba2ad 1589 int ret;
c2bac160
MB
1590
1591 wm8753 = kzalloc(sizeof(struct wm8753_priv), GFP_KERNEL);
1592 if (wm8753 == NULL)
1593 return -ENOMEM;
69e169da 1594
f0fba2ad 1595 i2c_set_clientdata(i2c, wm8753);
f0fba2ad 1596 wm8753->control_type = SND_SOC_I2C;
69e169da 1597
f0fba2ad
LG
1598 ret = snd_soc_register_codec(&i2c->dev,
1599 &soc_codec_dev_wm8753, wm8753_dai, ARRAY_SIZE(wm8753_dai));
1600 if (ret < 0)
1601 kfree(wm8753);
1602 return ret;
69e169da
MB
1603}
1604
f0fba2ad 1605static __devexit int wm8753_i2c_remove(struct i2c_client *client)
69e169da 1606{
f0fba2ad
LG
1607 snd_soc_unregister_codec(&client->dev);
1608 kfree(i2c_get_clientdata(client));
69e169da
MB
1609 return 0;
1610}
1611
f0fba2ad
LG
1612static const struct i2c_device_id wm8753_i2c_id[] = {
1613 { "wm8753", 0 },
1614 { }
1615};
1616MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id);
1617
1618static struct i2c_driver wm8753_i2c_driver = {
69e169da 1619 .driver = {
f0fba2ad
LG
1620 .name = "wm8753-codec",
1621 .owner = THIS_MODULE,
69e169da 1622 },
f0fba2ad
LG
1623 .probe = wm8753_i2c_probe,
1624 .remove = __devexit_p(wm8753_i2c_remove),
1625 .id_table = wm8753_i2c_id,
69e169da
MB
1626};
1627#endif
1628
c9b3a40f 1629static int __init wm8753_modinit(void)
64089b84 1630{
f0fba2ad 1631 int ret = 0;
c2bac160
MB
1632#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1633 ret = i2c_add_driver(&wm8753_i2c_driver);
f0fba2ad
LG
1634 if (ret != 0) {
1635 printk(KERN_ERR "Failed to register wm8753 I2C driver: %d\n",
1636 ret);
1637 }
c2bac160
MB
1638#endif
1639#if defined(CONFIG_SPI_MASTER)
1640 ret = spi_register_driver(&wm8753_spi_driver);
f0fba2ad
LG
1641 if (ret != 0) {
1642 printk(KERN_ERR "Failed to register wm8753 SPI driver: %d\n",
1643 ret);
1644 }
c2bac160 1645#endif
f0fba2ad 1646 return ret;
64089b84
MB
1647}
1648module_init(wm8753_modinit);
1649
1650static void __exit wm8753_exit(void)
1651{
c2bac160
MB
1652#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1653 i2c_del_driver(&wm8753_i2c_driver);
1654#endif
1655#if defined(CONFIG_SPI_MASTER)
1656 spi_unregister_driver(&wm8753_spi_driver);
1657#endif
64089b84
MB
1658}
1659module_exit(wm8753_exit);
1660
1f53aee0
LG
1661MODULE_DESCRIPTION("ASoC WM8753 driver");
1662MODULE_AUTHOR("Liam Girdwood");
1663MODULE_LICENSE("GPL");
This page took 0.324855 seconds and 5 git commands to generate.