~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to sound/soc/codecs/wm8750.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * wm8750.c -- WM8750 ALSA SoC audio driver
 
3
 *
 
4
 * Copyright 2005 Openedhand Ltd.
 
5
 *
 
6
 * Author: Richard Purdie <richard@openedhand.com>
 
7
 *
 
8
 * Based on WM8753.c
 
9
 *
 
10
 * This program is free software; you can redistribute it and/or modify
 
11
 * it under the terms of the GNU General Public License version 2 as
 
12
 * published by the Free Software Foundation.
 
13
 */
 
14
 
 
15
#include <linux/module.h>
 
16
#include <linux/moduleparam.h>
 
17
#include <linux/init.h>
 
18
#include <linux/delay.h>
 
19
#include <linux/pm.h>
 
20
#include <linux/i2c.h>
 
21
#include <linux/platform_device.h>
 
22
#include <linux/spi/spi.h>
 
23
#include <linux/slab.h>
 
24
#include <linux/of_device.h>
 
25
#include <sound/core.h>
 
26
#include <sound/pcm.h>
 
27
#include <sound/pcm_params.h>
 
28
#include <sound/soc.h>
 
29
#include <sound/initval.h>
 
30
 
 
31
#include "wm8750.h"
 
32
 
 
33
/*
 
34
 * wm8750 register cache
 
35
 * We can't read the WM8750 register space when we
 
36
 * are using 2 wire for device control, so we cache them instead.
 
37
 */
 
38
static const u16 wm8750_reg[] = {
 
39
        0x0097, 0x0097, 0x0079, 0x0079,  /*  0 */
 
40
        0x0000, 0x0008, 0x0000, 0x000a,  /*  4 */
 
41
        0x0000, 0x0000, 0x00ff, 0x00ff,  /*  8 */
 
42
        0x000f, 0x000f, 0x0000, 0x0000,  /* 12 */
 
43
        0x0000, 0x007b, 0x0000, 0x0032,  /* 16 */
 
44
        0x0000, 0x00c3, 0x00c3, 0x00c0,  /* 20 */
 
45
        0x0000, 0x0000, 0x0000, 0x0000,  /* 24 */
 
46
        0x0000, 0x0000, 0x0000, 0x0000,  /* 28 */
 
47
        0x0000, 0x0000, 0x0050, 0x0050,  /* 32 */
 
48
        0x0050, 0x0050, 0x0050, 0x0050,  /* 36 */
 
49
        0x0079, 0x0079, 0x0079,          /* 40 */
 
50
};
 
51
 
 
52
/* codec private data */
 
53
struct wm8750_priv {
 
54
        unsigned int sysclk;
 
55
        enum snd_soc_control_type control_type;
 
56
};
 
57
 
 
58
#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0)
 
59
 
 
60
/*
 
61
 * WM8750 Controls
 
62
 */
 
63
static const char *wm8750_bass[] = {"Linear Control", "Adaptive Boost"};
 
64
static const char *wm8750_bass_filter[] = { "130Hz @ 48kHz", "200Hz @ 48kHz" };
 
65
static const char *wm8750_treble[] = {"8kHz", "4kHz"};
 
66
static const char *wm8750_3d_lc[] = {"200Hz", "500Hz"};
 
67
static const char *wm8750_3d_uc[] = {"2.2kHz", "1.5kHz"};
 
68
static const char *wm8750_3d_func[] = {"Capture", "Playback"};
 
69
static const char *wm8750_alc_func[] = {"Off", "Right", "Left", "Stereo"};
 
70
static const char *wm8750_ng_type[] = {"Constant PGA Gain",
 
71
        "Mute ADC Output"};
 
72
static const char *wm8750_line_mux[] = {"Line 1", "Line 2", "Line 3", "PGA",
 
73
        "Differential"};
 
74
static const char *wm8750_pga_sel[] = {"Line 1", "Line 2", "Line 3",
 
75
        "Differential"};
 
76
static const char *wm8750_out3[] = {"VREF", "ROUT1 + Vol", "MonoOut",
 
77
        "ROUT1"};
 
78
static const char *wm8750_diff_sel[] = {"Line 1", "Line 2"};
 
79
static const char *wm8750_adcpol[] = {"Normal", "L Invert", "R Invert",
 
80
        "L + R Invert"};
 
81
static const char *wm8750_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
 
82
static const char *wm8750_mono_mux[] = {"Stereo", "Mono (Left)",
 
83
        "Mono (Right)", "Digital Mono"};
 
84
 
 
85
static const struct soc_enum wm8750_enum[] = {
 
86
SOC_ENUM_SINGLE(WM8750_BASS, 7, 2, wm8750_bass),
 
87
SOC_ENUM_SINGLE(WM8750_BASS, 6, 2, wm8750_bass_filter),
 
88
SOC_ENUM_SINGLE(WM8750_TREBLE, 6, 2, wm8750_treble),
 
89
SOC_ENUM_SINGLE(WM8750_3D, 5, 2, wm8750_3d_lc),
 
90
SOC_ENUM_SINGLE(WM8750_3D, 6, 2, wm8750_3d_uc),
 
91
SOC_ENUM_SINGLE(WM8750_3D, 7, 2, wm8750_3d_func),
 
92
SOC_ENUM_SINGLE(WM8750_ALC1, 7, 4, wm8750_alc_func),
 
93
SOC_ENUM_SINGLE(WM8750_NGATE, 1, 2, wm8750_ng_type),
 
94
SOC_ENUM_SINGLE(WM8750_LOUTM1, 0, 5, wm8750_line_mux),
 
95
SOC_ENUM_SINGLE(WM8750_ROUTM1, 0, 5, wm8750_line_mux),
 
96
SOC_ENUM_SINGLE(WM8750_LADCIN, 6, 4, wm8750_pga_sel), /* 10 */
 
97
SOC_ENUM_SINGLE(WM8750_RADCIN, 6, 4, wm8750_pga_sel),
 
98
SOC_ENUM_SINGLE(WM8750_ADCTL2, 7, 4, wm8750_out3),
 
99
SOC_ENUM_SINGLE(WM8750_ADCIN, 8, 2, wm8750_diff_sel),
 
100
SOC_ENUM_SINGLE(WM8750_ADCDAC, 5, 4, wm8750_adcpol),
 
101
SOC_ENUM_SINGLE(WM8750_ADCDAC, 1, 4, wm8750_deemph),
 
102
SOC_ENUM_SINGLE(WM8750_ADCIN, 6, 4, wm8750_mono_mux), /* 16 */
 
103
 
 
104
};
 
105
 
 
106
static const struct snd_kcontrol_new wm8750_snd_controls[] = {
 
107
 
 
108
SOC_DOUBLE_R("Capture Volume", WM8750_LINVOL, WM8750_RINVOL, 0, 63, 0),
 
109
SOC_DOUBLE_R("Capture ZC Switch", WM8750_LINVOL, WM8750_RINVOL, 6, 1, 0),
 
110
SOC_DOUBLE_R("Capture Switch", WM8750_LINVOL, WM8750_RINVOL, 7, 1, 1),
 
111
 
 
112
SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8750_LOUT1V,
 
113
        WM8750_ROUT1V, 7, 1, 0),
 
114
SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8750_LOUT2V,
 
115
        WM8750_ROUT2V, 7, 1, 0),
 
116
 
 
117
SOC_ENUM("Playback De-emphasis", wm8750_enum[15]),
 
118
 
 
119
SOC_ENUM("Capture Polarity", wm8750_enum[14]),
 
120
SOC_SINGLE("Playback 6dB Attenuate", WM8750_ADCDAC, 7, 1, 0),
 
121
SOC_SINGLE("Capture 6dB Attenuate", WM8750_ADCDAC, 8, 1, 0),
 
122
 
 
123
SOC_DOUBLE_R("PCM Volume", WM8750_LDAC, WM8750_RDAC, 0, 255, 0),
 
124
 
 
125
SOC_ENUM("Bass Boost", wm8750_enum[0]),
 
126
SOC_ENUM("Bass Filter", wm8750_enum[1]),
 
127
SOC_SINGLE("Bass Volume", WM8750_BASS, 0, 15, 1),
 
128
 
 
129
SOC_SINGLE("Treble Volume", WM8750_TREBLE, 0, 15, 1),
 
130
SOC_ENUM("Treble Cut-off", wm8750_enum[2]),
 
131
 
 
132
SOC_SINGLE("3D Switch", WM8750_3D, 0, 1, 0),
 
133
SOC_SINGLE("3D Volume", WM8750_3D, 1, 15, 0),
 
134
SOC_ENUM("3D Lower Cut-off", wm8750_enum[3]),
 
135
SOC_ENUM("3D Upper Cut-off", wm8750_enum[4]),
 
136
SOC_ENUM("3D Mode", wm8750_enum[5]),
 
137
 
 
138
SOC_SINGLE("ALC Capture Target Volume", WM8750_ALC1, 0, 7, 0),
 
139
SOC_SINGLE("ALC Capture Max Volume", WM8750_ALC1, 4, 7, 0),
 
140
SOC_ENUM("ALC Capture Function", wm8750_enum[6]),
 
141
SOC_SINGLE("ALC Capture ZC Switch", WM8750_ALC2, 7, 1, 0),
 
142
SOC_SINGLE("ALC Capture Hold Time", WM8750_ALC2, 0, 15, 0),
 
143
SOC_SINGLE("ALC Capture Decay Time", WM8750_ALC3, 4, 15, 0),
 
144
SOC_SINGLE("ALC Capture Attack Time", WM8750_ALC3, 0, 15, 0),
 
145
SOC_SINGLE("ALC Capture NG Threshold", WM8750_NGATE, 3, 31, 0),
 
146
SOC_ENUM("ALC Capture NG Type", wm8750_enum[4]),
 
147
SOC_SINGLE("ALC Capture NG Switch", WM8750_NGATE, 0, 1, 0),
 
148
 
 
149
SOC_SINGLE("Left ADC Capture Volume", WM8750_LADC, 0, 255, 0),
 
150
SOC_SINGLE("Right ADC Capture Volume", WM8750_RADC, 0, 255, 0),
 
151
 
 
152
SOC_SINGLE("ZC Timeout Switch", WM8750_ADCTL1, 0, 1, 0),
 
153
SOC_SINGLE("Playback Invert Switch", WM8750_ADCTL1, 1, 1, 0),
 
154
 
 
155
SOC_SINGLE("Right Speaker Playback Invert Switch", WM8750_ADCTL2, 4, 1, 0),
 
156
 
 
157
/* Unimplemented */
 
158
/* ADCDAC Bit 0 - ADCHPD */
 
159
/* ADCDAC Bit 4 - HPOR */
 
160
/* ADCTL1 Bit 2,3 - DATSEL */
 
161
/* ADCTL1 Bit 4,5 - DMONOMIX */
 
162
/* ADCTL1 Bit 6,7 - VSEL */
 
163
/* ADCTL2 Bit 2 - LRCM */
 
164
/* ADCTL2 Bit 3 - TRI */
 
165
/* ADCTL3 Bit 5 - HPFLREN */
 
166
/* ADCTL3 Bit 6 - VROI */
 
167
/* ADCTL3 Bit 7,8 - ADCLRM */
 
168
/* ADCIN Bit 4 - LDCM */
 
169
/* ADCIN Bit 5 - RDCM */
 
170
 
 
171
SOC_DOUBLE_R("Mic Boost", WM8750_LADCIN, WM8750_RADCIN, 4, 3, 0),
 
172
 
 
173
SOC_DOUBLE_R("Bypass Left Playback Volume", WM8750_LOUTM1,
 
174
        WM8750_LOUTM2, 4, 7, 1),
 
175
SOC_DOUBLE_R("Bypass Right Playback Volume", WM8750_ROUTM1,
 
176
        WM8750_ROUTM2, 4, 7, 1),
 
177
SOC_DOUBLE_R("Bypass Mono Playback Volume", WM8750_MOUTM1,
 
178
        WM8750_MOUTM2, 4, 7, 1),
 
179
 
 
180
SOC_SINGLE("Mono Playback ZC Switch", WM8750_MOUTV, 7, 1, 0),
 
181
 
 
182
SOC_DOUBLE_R("Headphone Playback Volume", WM8750_LOUT1V, WM8750_ROUT1V,
 
183
        0, 127, 0),
 
184
SOC_DOUBLE_R("Speaker Playback Volume", WM8750_LOUT2V, WM8750_ROUT2V,
 
185
        0, 127, 0),
 
186
 
 
187
SOC_SINGLE("Mono Playback Volume", WM8750_MOUTV, 0, 127, 0),
 
188
 
 
189
};
 
190
 
 
191
/*
 
192
 * DAPM Controls
 
193
 */
 
194
 
 
195
/* Left Mixer */
 
196
static const struct snd_kcontrol_new wm8750_left_mixer_controls[] = {
 
197
SOC_DAPM_SINGLE("Playback Switch", WM8750_LOUTM1, 8, 1, 0),
 
198
SOC_DAPM_SINGLE("Left Bypass Switch", WM8750_LOUTM1, 7, 1, 0),
 
199
SOC_DAPM_SINGLE("Right Playback Switch", WM8750_LOUTM2, 8, 1, 0),
 
200
SOC_DAPM_SINGLE("Right Bypass Switch", WM8750_LOUTM2, 7, 1, 0),
 
201
};
 
202
 
 
203
/* Right Mixer */
 
204
static const struct snd_kcontrol_new wm8750_right_mixer_controls[] = {
 
205
SOC_DAPM_SINGLE("Left Playback Switch", WM8750_ROUTM1, 8, 1, 0),
 
206
SOC_DAPM_SINGLE("Left Bypass Switch", WM8750_ROUTM1, 7, 1, 0),
 
207
SOC_DAPM_SINGLE("Playback Switch", WM8750_ROUTM2, 8, 1, 0),
 
208
SOC_DAPM_SINGLE("Right Bypass Switch", WM8750_ROUTM2, 7, 1, 0),
 
209
};
 
210
 
 
211
/* Mono Mixer */
 
212
static const struct snd_kcontrol_new wm8750_mono_mixer_controls[] = {
 
213
SOC_DAPM_SINGLE("Left Playback Switch", WM8750_MOUTM1, 8, 1, 0),
 
214
SOC_DAPM_SINGLE("Left Bypass Switch", WM8750_MOUTM1, 7, 1, 0),
 
215
SOC_DAPM_SINGLE("Right Playback Switch", WM8750_MOUTM2, 8, 1, 0),
 
216
SOC_DAPM_SINGLE("Right Bypass Switch", WM8750_MOUTM2, 7, 1, 0),
 
217
};
 
218
 
 
219
/* Left Line Mux */
 
220
static const struct snd_kcontrol_new wm8750_left_line_controls =
 
221
SOC_DAPM_ENUM("Route", wm8750_enum[8]);
 
222
 
 
223
/* Right Line Mux */
 
224
static const struct snd_kcontrol_new wm8750_right_line_controls =
 
225
SOC_DAPM_ENUM("Route", wm8750_enum[9]);
 
226
 
 
227
/* Left PGA Mux */
 
228
static const struct snd_kcontrol_new wm8750_left_pga_controls =
 
229
SOC_DAPM_ENUM("Route", wm8750_enum[10]);
 
230
 
 
231
/* Right PGA Mux */
 
232
static const struct snd_kcontrol_new wm8750_right_pga_controls =
 
233
SOC_DAPM_ENUM("Route", wm8750_enum[11]);
 
234
 
 
235
/* Out 3 Mux */
 
236
static const struct snd_kcontrol_new wm8750_out3_controls =
 
237
SOC_DAPM_ENUM("Route", wm8750_enum[12]);
 
238
 
 
239
/* Differential Mux */
 
240
static const struct snd_kcontrol_new wm8750_diffmux_controls =
 
241
SOC_DAPM_ENUM("Route", wm8750_enum[13]);
 
242
 
 
243
/* Mono ADC Mux */
 
244
static const struct snd_kcontrol_new wm8750_monomux_controls =
 
245
SOC_DAPM_ENUM("Route", wm8750_enum[16]);
 
246
 
 
247
static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = {
 
248
        SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,
 
249
                &wm8750_left_mixer_controls[0],
 
250
                ARRAY_SIZE(wm8750_left_mixer_controls)),
 
251
        SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,
 
252
                &wm8750_right_mixer_controls[0],
 
253
                ARRAY_SIZE(wm8750_right_mixer_controls)),
 
254
        SND_SOC_DAPM_MIXER("Mono Mixer", WM8750_PWR2, 2, 0,
 
255
                &wm8750_mono_mixer_controls[0],
 
256
                ARRAY_SIZE(wm8750_mono_mixer_controls)),
 
257
 
 
258
        SND_SOC_DAPM_PGA("Right Out 2", WM8750_PWR2, 3, 0, NULL, 0),
 
259
        SND_SOC_DAPM_PGA("Left Out 2", WM8750_PWR2, 4, 0, NULL, 0),
 
260
        SND_SOC_DAPM_PGA("Right Out 1", WM8750_PWR2, 5, 0, NULL, 0),
 
261
        SND_SOC_DAPM_PGA("Left Out 1", WM8750_PWR2, 6, 0, NULL, 0),
 
262
        SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8750_PWR2, 7, 0),
 
263
        SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8750_PWR2, 8, 0),
 
264
 
 
265
        SND_SOC_DAPM_MICBIAS("Mic Bias", WM8750_PWR1, 1, 0),
 
266
        SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8750_PWR1, 2, 0),
 
267
        SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8750_PWR1, 3, 0),
 
268
 
 
269
        SND_SOC_DAPM_MUX("Left PGA Mux", WM8750_PWR1, 5, 0,
 
270
                &wm8750_left_pga_controls),
 
271
        SND_SOC_DAPM_MUX("Right PGA Mux", WM8750_PWR1, 4, 0,
 
272
                &wm8750_right_pga_controls),
 
273
        SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0,
 
274
                &wm8750_left_line_controls),
 
275
        SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0,
 
276
                &wm8750_right_line_controls),
 
277
 
 
278
        SND_SOC_DAPM_MUX("Out3 Mux", SND_SOC_NOPM, 0, 0, &wm8750_out3_controls),
 
279
        SND_SOC_DAPM_PGA("Out 3", WM8750_PWR2, 1, 0, NULL, 0),
 
280
        SND_SOC_DAPM_PGA("Mono Out 1", WM8750_PWR2, 2, 0, NULL, 0),
 
281
 
 
282
        SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0,
 
283
                &wm8750_diffmux_controls),
 
284
        SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0,
 
285
                &wm8750_monomux_controls),
 
286
        SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0,
 
287
                &wm8750_monomux_controls),
 
288
 
 
289
        SND_SOC_DAPM_OUTPUT("LOUT1"),
 
290
        SND_SOC_DAPM_OUTPUT("ROUT1"),
 
291
        SND_SOC_DAPM_OUTPUT("LOUT2"),
 
292
        SND_SOC_DAPM_OUTPUT("ROUT2"),
 
293
        SND_SOC_DAPM_OUTPUT("MONO1"),
 
294
        SND_SOC_DAPM_OUTPUT("OUT3"),
 
295
        SND_SOC_DAPM_OUTPUT("VREF"),
 
296
 
 
297
        SND_SOC_DAPM_INPUT("LINPUT1"),
 
298
        SND_SOC_DAPM_INPUT("LINPUT2"),
 
299
        SND_SOC_DAPM_INPUT("LINPUT3"),
 
300
        SND_SOC_DAPM_INPUT("RINPUT1"),
 
301
        SND_SOC_DAPM_INPUT("RINPUT2"),
 
302
        SND_SOC_DAPM_INPUT("RINPUT3"),
 
303
};
 
304
 
 
305
static const struct snd_soc_dapm_route audio_map[] = {
 
306
        /* left mixer */
 
307
        {"Left Mixer", "Playback Switch", "Left DAC"},
 
308
        {"Left Mixer", "Left Bypass Switch", "Left Line Mux"},
 
309
        {"Left Mixer", "Right Playback Switch", "Right DAC"},
 
310
        {"Left Mixer", "Right Bypass Switch", "Right Line Mux"},
 
311
 
 
312
        /* right mixer */
 
313
        {"Right Mixer", "Left Playback Switch", "Left DAC"},
 
314
        {"Right Mixer", "Left Bypass Switch", "Left Line Mux"},
 
315
        {"Right Mixer", "Playback Switch", "Right DAC"},
 
316
        {"Right Mixer", "Right Bypass Switch", "Right Line Mux"},
 
317
 
 
318
        /* left out 1 */
 
319
        {"Left Out 1", NULL, "Left Mixer"},
 
320
        {"LOUT1", NULL, "Left Out 1"},
 
321
 
 
322
        /* left out 2 */
 
323
        {"Left Out 2", NULL, "Left Mixer"},
 
324
        {"LOUT2", NULL, "Left Out 2"},
 
325
 
 
326
        /* right out 1 */
 
327
        {"Right Out 1", NULL, "Right Mixer"},
 
328
        {"ROUT1", NULL, "Right Out 1"},
 
329
 
 
330
        /* right out 2 */
 
331
        {"Right Out 2", NULL, "Right Mixer"},
 
332
        {"ROUT2", NULL, "Right Out 2"},
 
333
 
 
334
        /* mono mixer */
 
335
        {"Mono Mixer", "Left Playback Switch", "Left DAC"},
 
336
        {"Mono Mixer", "Left Bypass Switch", "Left Line Mux"},
 
337
        {"Mono Mixer", "Right Playback Switch", "Right DAC"},
 
338
        {"Mono Mixer", "Right Bypass Switch", "Right Line Mux"},
 
339
 
 
340
        /* mono out */
 
341
        {"Mono Out 1", NULL, "Mono Mixer"},
 
342
        {"MONO1", NULL, "Mono Out 1"},
 
343
 
 
344
        /* out 3 */
 
345
        {"Out3 Mux", "VREF", "VREF"},
 
346
        {"Out3 Mux", "ROUT1 + Vol", "ROUT1"},
 
347
        {"Out3 Mux", "ROUT1", "Right Mixer"},
 
348
        {"Out3 Mux", "MonoOut", "MONO1"},
 
349
        {"Out 3", NULL, "Out3 Mux"},
 
350
        {"OUT3", NULL, "Out 3"},
 
351
 
 
352
        /* Left Line Mux */
 
353
        {"Left Line Mux", "Line 1", "LINPUT1"},
 
354
        {"Left Line Mux", "Line 2", "LINPUT2"},
 
355
        {"Left Line Mux", "Line 3", "LINPUT3"},
 
356
        {"Left Line Mux", "PGA", "Left PGA Mux"},
 
357
        {"Left Line Mux", "Differential", "Differential Mux"},
 
358
 
 
359
        /* Right Line Mux */
 
360
        {"Right Line Mux", "Line 1", "RINPUT1"},
 
361
        {"Right Line Mux", "Line 2", "RINPUT2"},
 
362
        {"Right Line Mux", "Line 3", "RINPUT3"},
 
363
        {"Right Line Mux", "PGA", "Right PGA Mux"},
 
364
        {"Right Line Mux", "Differential", "Differential Mux"},
 
365
 
 
366
        /* Left PGA Mux */
 
367
        {"Left PGA Mux", "Line 1", "LINPUT1"},
 
368
        {"Left PGA Mux", "Line 2", "LINPUT2"},
 
369
        {"Left PGA Mux", "Line 3", "LINPUT3"},
 
370
        {"Left PGA Mux", "Differential", "Differential Mux"},
 
371
 
 
372
        /* Right PGA Mux */
 
373
        {"Right PGA Mux", "Line 1", "RINPUT1"},
 
374
        {"Right PGA Mux", "Line 2", "RINPUT2"},
 
375
        {"Right PGA Mux", "Line 3", "RINPUT3"},
 
376
        {"Right PGA Mux", "Differential", "Differential Mux"},
 
377
 
 
378
        /* Differential Mux */
 
379
        {"Differential Mux", "Line 1", "LINPUT1"},
 
380
        {"Differential Mux", "Line 1", "RINPUT1"},
 
381
        {"Differential Mux", "Line 2", "LINPUT2"},
 
382
        {"Differential Mux", "Line 2", "RINPUT2"},
 
383
 
 
384
        /* Left ADC Mux */
 
385
        {"Left ADC Mux", "Stereo", "Left PGA Mux"},
 
386
        {"Left ADC Mux", "Mono (Left)", "Left PGA Mux"},
 
387
        {"Left ADC Mux", "Digital Mono", "Left PGA Mux"},
 
388
 
 
389
        /* Right ADC Mux */
 
390
        {"Right ADC Mux", "Stereo", "Right PGA Mux"},
 
391
        {"Right ADC Mux", "Mono (Right)", "Right PGA Mux"},
 
392
        {"Right ADC Mux", "Digital Mono", "Right PGA Mux"},
 
393
 
 
394
        /* ADC */
 
395
        {"Left ADC", NULL, "Left ADC Mux"},
 
396
        {"Right ADC", NULL, "Right ADC Mux"},
 
397
};
 
398
 
 
399
static int wm8750_add_widgets(struct snd_soc_codec *codec)
 
400
{
 
401
        struct snd_soc_dapm_context *dapm = &codec->dapm;
 
402
 
 
403
        snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
 
404
                                  ARRAY_SIZE(wm8750_dapm_widgets));
 
405
        snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
 
406
 
 
407
        return 0;
 
408
}
 
409
 
 
410
struct _coeff_div {
 
411
        u32 mclk;
 
412
        u32 rate;
 
413
        u16 fs;
 
414
        u8 sr:5;
 
415
        u8 usb:1;
 
416
};
 
417
 
 
418
/* codec hifi mclk clock divider coefficients */
 
419
static const struct _coeff_div coeff_div[] = {
 
420
        /* 8k */
 
421
        {12288000, 8000, 1536, 0x6, 0x0},
 
422
        {11289600, 8000, 1408, 0x16, 0x0},
 
423
        {18432000, 8000, 2304, 0x7, 0x0},
 
424
        {16934400, 8000, 2112, 0x17, 0x0},
 
425
        {12000000, 8000, 1500, 0x6, 0x1},
 
426
 
 
427
        /* 11.025k */
 
428
        {11289600, 11025, 1024, 0x18, 0x0},
 
429
        {16934400, 11025, 1536, 0x19, 0x0},
 
430
        {12000000, 11025, 1088, 0x19, 0x1},
 
431
 
 
432
        /* 16k */
 
433
        {12288000, 16000, 768, 0xa, 0x0},
 
434
        {18432000, 16000, 1152, 0xb, 0x0},
 
435
        {12000000, 16000, 750, 0xa, 0x1},
 
436
 
 
437
        /* 22.05k */
 
438
        {11289600, 22050, 512, 0x1a, 0x0},
 
439
        {16934400, 22050, 768, 0x1b, 0x0},
 
440
        {12000000, 22050, 544, 0x1b, 0x1},
 
441
 
 
442
        /* 32k */
 
443
        {12288000, 32000, 384, 0xc, 0x0},
 
444
        {18432000, 32000, 576, 0xd, 0x0},
 
445
        {12000000, 32000, 375, 0xa, 0x1},
 
446
 
 
447
        /* 44.1k */
 
448
        {11289600, 44100, 256, 0x10, 0x0},
 
449
        {16934400, 44100, 384, 0x11, 0x0},
 
450
        {12000000, 44100, 272, 0x11, 0x1},
 
451
 
 
452
        /* 48k */
 
453
        {12288000, 48000, 256, 0x0, 0x0},
 
454
        {18432000, 48000, 384, 0x1, 0x0},
 
455
        {12000000, 48000, 250, 0x0, 0x1},
 
456
 
 
457
        /* 88.2k */
 
458
        {11289600, 88200, 128, 0x1e, 0x0},
 
459
        {16934400, 88200, 192, 0x1f, 0x0},
 
460
        {12000000, 88200, 136, 0x1f, 0x1},
 
461
 
 
462
        /* 96k */
 
463
        {12288000, 96000, 128, 0xe, 0x0},
 
464
        {18432000, 96000, 192, 0xf, 0x0},
 
465
        {12000000, 96000, 125, 0xe, 0x1},
 
466
};
 
467
 
 
468
static inline int get_coeff(int mclk, int rate)
 
469
{
 
470
        int i;
 
471
 
 
472
        for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
 
473
                if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
 
474
                        return i;
 
475
        }
 
476
 
 
477
        printk(KERN_ERR "wm8750: could not get coeff for mclk %d @ rate %d\n",
 
478
                mclk, rate);
 
479
        return -EINVAL;
 
480
}
 
481
 
 
482
static int wm8750_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 
483
                int clk_id, unsigned int freq, int dir)
 
484
{
 
485
        struct snd_soc_codec *codec = codec_dai->codec;
 
486
        struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
 
487
 
 
488
        switch (freq) {
 
489
        case 11289600:
 
490
        case 12000000:
 
491
        case 12288000:
 
492
        case 16934400:
 
493
        case 18432000:
 
494
                wm8750->sysclk = freq;
 
495
                return 0;
 
496
        }
 
497
        return -EINVAL;
 
498
}
 
499
 
 
500
static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai,
 
501
                unsigned int fmt)
 
502
{
 
503
        struct snd_soc_codec *codec = codec_dai->codec;
 
504
        u16 iface = 0;
 
505
 
 
506
        /* set master/slave audio interface */
 
507
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
 
508
        case SND_SOC_DAIFMT_CBM_CFM:
 
509
                iface = 0x0040;
 
510
                break;
 
511
        case SND_SOC_DAIFMT_CBS_CFS:
 
512
                break;
 
513
        default:
 
514
                return -EINVAL;
 
515
        }
 
516
 
 
517
        /* interface format */
 
518
        switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 
519
        case SND_SOC_DAIFMT_I2S:
 
520
                iface |= 0x0002;
 
521
                break;
 
522
        case SND_SOC_DAIFMT_RIGHT_J:
 
523
                break;
 
524
        case SND_SOC_DAIFMT_LEFT_J:
 
525
                iface |= 0x0001;
 
526
                break;
 
527
        case SND_SOC_DAIFMT_DSP_A:
 
528
                iface |= 0x0003;
 
529
                break;
 
530
        case SND_SOC_DAIFMT_DSP_B:
 
531
                iface |= 0x0013;
 
532
                break;
 
533
        default:
 
534
                return -EINVAL;
 
535
        }
 
536
 
 
537
        /* clock inversion */
 
538
        switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 
539
        case SND_SOC_DAIFMT_NB_NF:
 
540
                break;
 
541
        case SND_SOC_DAIFMT_IB_IF:
 
542
                iface |= 0x0090;
 
543
                break;
 
544
        case SND_SOC_DAIFMT_IB_NF:
 
545
                iface |= 0x0080;
 
546
                break;
 
547
        case SND_SOC_DAIFMT_NB_IF:
 
548
                iface |= 0x0010;
 
549
                break;
 
550
        default:
 
551
                return -EINVAL;
 
552
        }
 
553
 
 
554
        snd_soc_write(codec, WM8750_IFACE, iface);
 
555
        return 0;
 
556
}
 
557
 
 
558
static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
 
559
                                struct snd_pcm_hw_params *params,
 
560
                                struct snd_soc_dai *dai)
 
561
{
 
562
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
 
563
        struct snd_soc_codec *codec = rtd->codec;
 
564
        struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
 
565
        u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3;
 
566
        u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0;
 
567
        int coeff = get_coeff(wm8750->sysclk, params_rate(params));
 
568
 
 
569
        /* bit size */
 
570
        switch (params_format(params)) {
 
571
        case SNDRV_PCM_FORMAT_S16_LE:
 
572
                break;
 
573
        case SNDRV_PCM_FORMAT_S20_3LE:
 
574
                iface |= 0x0004;
 
575
                break;
 
576
        case SNDRV_PCM_FORMAT_S24_LE:
 
577
                iface |= 0x0008;
 
578
                break;
 
579
        case SNDRV_PCM_FORMAT_S32_LE:
 
580
                iface |= 0x000c;
 
581
                break;
 
582
        }
 
583
 
 
584
        /* set iface & srate */
 
585
        snd_soc_write(codec, WM8750_IFACE, iface);
 
586
        if (coeff >= 0)
 
587
                snd_soc_write(codec, WM8750_SRATE, srate |
 
588
                        (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
 
589
 
 
590
        return 0;
 
591
}
 
592
 
 
593
static int wm8750_mute(struct snd_soc_dai *dai, int mute)
 
594
{
 
595
        struct snd_soc_codec *codec = dai->codec;
 
596
        u16 mute_reg = snd_soc_read(codec, WM8750_ADCDAC) & 0xfff7;
 
597
 
 
598
        if (mute)
 
599
                snd_soc_write(codec, WM8750_ADCDAC, mute_reg | 0x8);
 
600
        else
 
601
                snd_soc_write(codec, WM8750_ADCDAC, mute_reg);
 
602
        return 0;
 
603
}
 
604
 
 
605
static int wm8750_set_bias_level(struct snd_soc_codec *codec,
 
606
                                 enum snd_soc_bias_level level)
 
607
{
 
608
        u16 pwr_reg = snd_soc_read(codec, WM8750_PWR1) & 0xfe3e;
 
609
 
 
610
        switch (level) {
 
611
        case SND_SOC_BIAS_ON:
 
612
                /* set vmid to 50k and unmute dac */
 
613
                snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0);
 
614
                break;
 
615
        case SND_SOC_BIAS_PREPARE:
 
616
                break;
 
617
        case SND_SOC_BIAS_STANDBY:
 
618
                if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
 
619
                        snd_soc_cache_sync(codec);
 
620
 
 
621
                        /* Set VMID to 5k */
 
622
                        snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
 
623
 
 
624
                        /* ...and ramp */
 
625
                        msleep(1000);
 
626
                }
 
627
 
 
628
                /* mute dac and set vmid to 500k, enable VREF */
 
629
                snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141);
 
630
                break;
 
631
        case SND_SOC_BIAS_OFF:
 
632
                snd_soc_write(codec, WM8750_PWR1, 0x0001);
 
633
                break;
 
634
        }
 
635
        codec->dapm.bias_level = level;
 
636
        return 0;
 
637
}
 
638
 
 
639
#define WM8750_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
 
640
        SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_44100 | \
 
641
        SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
 
642
 
 
643
#define WM8750_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
 
644
        SNDRV_PCM_FMTBIT_S24_LE)
 
645
 
 
646
static struct snd_soc_dai_ops wm8750_dai_ops = {
 
647
        .hw_params      = wm8750_pcm_hw_params,
 
648
        .digital_mute   = wm8750_mute,
 
649
        .set_fmt        = wm8750_set_dai_fmt,
 
650
        .set_sysclk     = wm8750_set_dai_sysclk,
 
651
};
 
652
 
 
653
static struct snd_soc_dai_driver wm8750_dai = {
 
654
        .name = "wm8750-hifi",
 
655
        .playback = {
 
656
                .stream_name = "Playback",
 
657
                .channels_min = 1,
 
658
                .channels_max = 2,
 
659
                .rates = WM8750_RATES,
 
660
                .formats = WM8750_FORMATS,},
 
661
        .capture = {
 
662
                .stream_name = "Capture",
 
663
                .channels_min = 1,
 
664
                .channels_max = 2,
 
665
                .rates = WM8750_RATES,
 
666
                .formats = WM8750_FORMATS,},
 
667
        .ops = &wm8750_dai_ops,
 
668
};
 
669
 
 
670
static int wm8750_suspend(struct snd_soc_codec *codec, pm_message_t state)
 
671
{
 
672
        wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
 
673
        return 0;
 
674
}
 
675
 
 
676
static int wm8750_resume(struct snd_soc_codec *codec)
 
677
{
 
678
        wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
679
        return 0;
 
680
}
 
681
 
 
682
static int wm8750_probe(struct snd_soc_codec *codec)
 
683
{
 
684
        struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec);
 
685
        int ret;
 
686
 
 
687
        ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8750->control_type);
 
688
        if (ret < 0) {
 
689
                printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret);
 
690
                return ret;
 
691
        }
 
692
 
 
693
        ret = wm8750_reset(codec);
 
694
        if (ret < 0) {
 
695
                printk(KERN_ERR "wm8750: failed to reset: %d\n", ret);
 
696
                return ret;
 
697
        }
 
698
 
 
699
        /* charge output caps */
 
700
        wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
701
 
 
702
        /* set the update bits */
 
703
        snd_soc_update_bits(codec, WM8750_LDAC, 0x0100, 0x0100);
 
704
        snd_soc_update_bits(codec, WM8750_RDAC, 0x0100, 0x0100);
 
705
        snd_soc_update_bits(codec, WM8750_LOUT1V, 0x0100, 0x0100);
 
706
        snd_soc_update_bits(codec, WM8750_ROUT1V, 0x0100, 0x0100);
 
707
        snd_soc_update_bits(codec, WM8750_LOUT2V, 0x0100, 0x0100);
 
708
        snd_soc_update_bits(codec, WM8750_ROUT2V, 0x0100, 0x0100);
 
709
        snd_soc_update_bits(codec, WM8750_LINVOL, 0x0100, 0x0100);
 
710
        snd_soc_update_bits(codec, WM8750_RINVOL, 0x0100, 0x0100);
 
711
 
 
712
        snd_soc_add_controls(codec, wm8750_snd_controls,
 
713
                                ARRAY_SIZE(wm8750_snd_controls));
 
714
        wm8750_add_widgets(codec);
 
715
        return ret;
 
716
}
 
717
 
 
718
static int wm8750_remove(struct snd_soc_codec *codec)
 
719
{
 
720
        wm8750_set_bias_level(codec, SND_SOC_BIAS_OFF);
 
721
        return 0;
 
722
}
 
723
 
 
724
static struct snd_soc_codec_driver soc_codec_dev_wm8750 = {
 
725
        .probe =        wm8750_probe,
 
726
        .remove =       wm8750_remove,
 
727
        .suspend =      wm8750_suspend,
 
728
        .resume =       wm8750_resume,
 
729
        .set_bias_level = wm8750_set_bias_level,
 
730
        .reg_cache_size = ARRAY_SIZE(wm8750_reg),
 
731
        .reg_word_size = sizeof(u16),
 
732
        .reg_cache_default = wm8750_reg,
 
733
};
 
734
 
 
735
static const struct of_device_id wm8750_of_match[] = {
 
736
        { .compatible = "wlf,wm8750", },
 
737
        { .compatible = "wlf,wm8987", },
 
738
        { }
 
739
};
 
740
MODULE_DEVICE_TABLE(of, wm8750_of_match);
 
741
 
 
742
#if defined(CONFIG_SPI_MASTER)
 
743
static int __devinit wm8750_spi_probe(struct spi_device *spi)
 
744
{
 
745
        struct wm8750_priv *wm8750;
 
746
        int ret;
 
747
 
 
748
        wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
 
749
        if (wm8750 == NULL)
 
750
                return -ENOMEM;
 
751
 
 
752
        wm8750->control_type = SND_SOC_SPI;
 
753
        spi_set_drvdata(spi, wm8750);
 
754
 
 
755
        ret = snd_soc_register_codec(&spi->dev,
 
756
                        &soc_codec_dev_wm8750, &wm8750_dai, 1);
 
757
        if (ret < 0)
 
758
                kfree(wm8750);
 
759
        return ret;
 
760
}
 
761
 
 
762
static int __devexit wm8750_spi_remove(struct spi_device *spi)
 
763
{
 
764
        snd_soc_unregister_codec(&spi->dev);
 
765
        kfree(spi_get_drvdata(spi));
 
766
        return 0;
 
767
}
 
768
 
 
769
static const struct spi_device_id wm8750_spi_ids[] = {
 
770
        { "wm8750", 0 },
 
771
        { "wm8987", 0 },
 
772
        { },
 
773
};
 
774
MODULE_DEVICE_TABLE(spi, wm8750_spi_ids);
 
775
 
 
776
static struct spi_driver wm8750_spi_driver = {
 
777
        .driver = {
 
778
                .name   = "wm8750",
 
779
                .owner  = THIS_MODULE,
 
780
                .of_match_table = wm8750_of_match,
 
781
        },
 
782
        .id_table       = wm8750_spi_ids,
 
783
        .probe          = wm8750_spi_probe,
 
784
        .remove         = __devexit_p(wm8750_spi_remove),
 
785
};
 
786
#endif /* CONFIG_SPI_MASTER */
 
787
 
 
788
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 
789
static __devinit int wm8750_i2c_probe(struct i2c_client *i2c,
 
790
                                      const struct i2c_device_id *id)
 
791
{
 
792
        struct wm8750_priv *wm8750;
 
793
        int ret;
 
794
 
 
795
        wm8750 = kzalloc(sizeof(struct wm8750_priv), GFP_KERNEL);
 
796
        if (wm8750 == NULL)
 
797
                return -ENOMEM;
 
798
 
 
799
        i2c_set_clientdata(i2c, wm8750);
 
800
        wm8750->control_type = SND_SOC_I2C;
 
801
 
 
802
        ret =  snd_soc_register_codec(&i2c->dev,
 
803
                        &soc_codec_dev_wm8750, &wm8750_dai, 1);
 
804
        if (ret < 0)
 
805
                kfree(wm8750);
 
806
        return ret;
 
807
}
 
808
 
 
809
static __devexit int wm8750_i2c_remove(struct i2c_client *client)
 
810
{
 
811
        snd_soc_unregister_codec(&client->dev);
 
812
        kfree(i2c_get_clientdata(client));
 
813
        return 0;
 
814
}
 
815
 
 
816
static const struct i2c_device_id wm8750_i2c_id[] = {
 
817
        { "wm8750", 0 },
 
818
        { "wm8987", 0 },
 
819
        { }
 
820
};
 
821
MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id);
 
822
 
 
823
static struct i2c_driver wm8750_i2c_driver = {
 
824
        .driver = {
 
825
                .name = "wm8750",
 
826
                .owner = THIS_MODULE,
 
827
                .of_match_table = wm8750_of_match,
 
828
        },
 
829
        .probe =    wm8750_i2c_probe,
 
830
        .remove =   __devexit_p(wm8750_i2c_remove),
 
831
        .id_table = wm8750_i2c_id,
 
832
};
 
833
#endif
 
834
 
 
835
static int __init wm8750_modinit(void)
 
836
{
 
837
        int ret = 0;
 
838
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 
839
        ret = i2c_add_driver(&wm8750_i2c_driver);
 
840
        if (ret != 0) {
 
841
                printk(KERN_ERR "Failed to register wm8750 I2C driver: %d\n",
 
842
                       ret);
 
843
        }
 
844
#endif
 
845
#if defined(CONFIG_SPI_MASTER)
 
846
        ret = spi_register_driver(&wm8750_spi_driver);
 
847
        if (ret != 0) {
 
848
                printk(KERN_ERR "Failed to register wm8750 SPI driver: %d\n",
 
849
                       ret);
 
850
        }
 
851
#endif
 
852
        return ret;
 
853
}
 
854
module_init(wm8750_modinit);
 
855
 
 
856
static void __exit wm8750_exit(void)
 
857
{
 
858
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
 
859
        i2c_del_driver(&wm8750_i2c_driver);
 
860
#endif
 
861
#if defined(CONFIG_SPI_MASTER)
 
862
        spi_unregister_driver(&wm8750_spi_driver);
 
863
#endif
 
864
}
 
865
module_exit(wm8750_exit);
 
866
 
 
867
MODULE_DESCRIPTION("ASoC WM8750 driver");
 
868
MODULE_AUTHOR("Liam Girdwood");
 
869
MODULE_LICENSE("GPL");