aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8962.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-08-05 08:20:59 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-08-05 08:38:57 -0400
commit9a76f1ff6e299fbb04149fe15aff061351fd0dab (patch)
treea9101f20804588022dd6f3307663f58104ceb150 /sound/soc/codecs/wm8962.c
parentbda7d2a862e6b788bca2d02d38a07966a9c92e48 (diff)
ASoC: Add initial WM8962 CODEC driver
The WM8962 is a low power, high performance stereo CODEC designed for portable digital audio applications. This initial driver release supports the key audio paths of the WM8962. Extended functionality, such as microphone detection, digital microphones and the advanced DSP signal enhancements provided by the device are not yet supported. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/wm8962.c')
-rw-r--r--sound/soc/codecs/wm8962.c1933
1 files changed, 1933 insertions, 0 deletions
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
new file mode 100644
index 000000000000..ea8940e80263
--- /dev/null
+++ b/sound/soc/codecs/wm8962.c
@@ -0,0 +1,1933 @@
1/*
2 * wm8962.c -- WM8962 ALSA SoC Audio driver
3 *
4 * Copyright 2010 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/pm.h>
19#include <linux/gcd.h>
20#include <linux/i2c.h>
21#include <linux/input.h>
22#include <linux/platform_device.h>
23#include <linux/regulator/consumer.h>
24#include <linux/slab.h>
25#include <linux/workqueue.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/soc.h>
30#include <sound/soc-dapm.h>
31#include <sound/initval.h>
32#include <sound/tlv.h>
33#include <sound/wm8962.h>
34
35#include "wm8962.h"
36
37static struct snd_soc_codec *wm8962_codec;
38struct snd_soc_codec_device soc_codec_dev_wm8962;
39
40#define WM8962_NUM_SUPPLIES 8
41static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = {
42 "DCVDD",
43 "DBVDD",
44 "AVDD",
45 "CPVDD",
46 "MICVDD",
47 "PLLVDD",
48 "SPKVDD1",
49 "SPKVDD2",
50};
51
52/* codec private data */
53struct wm8962_priv {
54 struct snd_soc_codec codec;
55 u16 reg_cache[WM8962_MAX_REGISTER + 1];
56
57 int sysclk;
58 int sysclk_rate;
59
60 int bclk; /* Desired BCLK */
61 int lrclk;
62
63 int fll_src;
64 int fll_fref;
65 int fll_fout;
66
67 struct regulator_bulk_data supplies[WM8962_NUM_SUPPLIES];
68 struct notifier_block disable_nb[WM8962_NUM_SUPPLIES];
69
70#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
71 struct input_dev *beep;
72 struct work_struct beep_work;
73 int beep_rate;
74#endif
75};
76
77/* We can't use the same notifier block for more than one supply and
78 * there's no way I can see to get from a callback to the caller
79 * except container_of().
80 */
81#define WM8962_REGULATOR_EVENT(n) \
82static int wm8962_regulator_event_##n(struct notifier_block *nb, \
83 unsigned long event, void *data) \
84{ \
85 struct wm8962_priv *wm8962 = container_of(nb, struct wm8962_priv, \
86 disable_nb[n]); \
87 if (event & REGULATOR_EVENT_DISABLE) { \
88 wm8962->codec.cache_sync = 1; \
89 } \
90 return 0; \
91}
92
93WM8962_REGULATOR_EVENT(0)
94WM8962_REGULATOR_EVENT(1)
95WM8962_REGULATOR_EVENT(2)
96WM8962_REGULATOR_EVENT(3)
97WM8962_REGULATOR_EVENT(4)
98WM8962_REGULATOR_EVENT(5)
99WM8962_REGULATOR_EVENT(6)
100WM8962_REGULATOR_EVENT(7)
101
102static int wm8962_volatile_register(unsigned int reg)
103{
104 if (wm8962_reg_access[reg].vol)
105 return 1;
106 else
107 return 0;
108}
109
110static int wm8962_readable(unsigned int reg)
111{
112 if (wm8962_reg_access[reg].read)
113 return 1;
114 else
115 return 0;
116}
117
118static int wm8962_reset(struct snd_soc_codec *codec)
119{
120 return snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0);
121}
122
123static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0);
124static const DECLARE_TLV_DB_SCALE(mixin_tlv, -1500, 300, 0);
125static const unsigned int mixinpga_tlv[] = {
126 TLV_DB_RANGE_HEAD(7),
127 0, 1, TLV_DB_SCALE_ITEM(0, 600, 0),
128 2, 2, TLV_DB_SCALE_ITEM(1300, 1300, 0),
129 3, 4, TLV_DB_SCALE_ITEM(1800, 200, 0),
130 5, 5, TLV_DB_SCALE_ITEM(2400, 0, 0),
131 6, 7, TLV_DB_SCALE_ITEM(2700, 300, 0),
132};
133static const DECLARE_TLV_DB_SCALE(beep_tlv, -9600, 600, 1);
134static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
135static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0);
136static const DECLARE_TLV_DB_SCALE(inmix_tlv, -600, 600, 0);
137static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
138static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
139static const DECLARE_TLV_DB_SCALE(hp_tlv, -700, 100, 0);
140static const unsigned int classd_tlv[] = {
141 TLV_DB_RANGE_HEAD(7),
142 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0),
143 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0),
144};
145
146/* The VU bits for the headphones are in a different register to the mute
147 * bits and only take effect on the PGA if it is actually powered.
148 */
149static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol,
150 struct snd_ctl_elem_value *ucontrol)
151{
152 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
153 u16 *reg_cache = codec->reg_cache;
154 int ret;
155
156 /* Apply the update (if any) */
157 ret = snd_soc_put_volsw(kcontrol, ucontrol);
158 if (ret == 0)
159 return 0;
160
161 /* If the left PGA is enabled hit that VU bit... */
162 if (reg_cache[WM8962_PWR_MGMT_2] & WM8962_HPOUTL_PGA_ENA)
163 return snd_soc_write(codec, WM8962_HPOUTL_VOLUME,
164 reg_cache[WM8962_HPOUTL_VOLUME]);
165
166 /* ...otherwise the right. The VU is stereo. */
167 if (reg_cache[WM8962_PWR_MGMT_2] & WM8962_HPOUTR_PGA_ENA)
168 return snd_soc_write(codec, WM8962_HPOUTR_VOLUME,
169 reg_cache[WM8962_HPOUTR_VOLUME]);
170
171 return 0;
172}
173
174/* The VU bits for the speakers are in a different register to the mute
175 * bits and only take effect on the PGA if it is actually powered.
176 */
177static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol,
178 struct snd_ctl_elem_value *ucontrol)
179{
180 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
181 u16 *reg_cache = codec->reg_cache;
182 int ret;
183
184 /* Apply the update (if any) */
185 ret = snd_soc_put_volsw(kcontrol, ucontrol);
186 if (ret == 0)
187 return 0;
188
189 /* If the left PGA is enabled hit that VU bit... */
190 if (reg_cache[WM8962_PWR_MGMT_2] & WM8962_SPKOUTL_PGA_ENA)
191 return snd_soc_write(codec, WM8962_SPKOUTL_VOLUME,
192 reg_cache[WM8962_SPKOUTL_VOLUME]);
193
194 /* ...otherwise the right. The VU is stereo. */
195 if (reg_cache[WM8962_PWR_MGMT_2] & WM8962_SPKOUTR_PGA_ENA)
196 return snd_soc_write(codec, WM8962_SPKOUTR_VOLUME,
197 reg_cache[WM8962_SPKOUTR_VOLUME]);
198
199 return 0;
200}
201
202static const struct snd_kcontrol_new wm8962_snd_controls[] = {
203SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1),
204
205SOC_SINGLE_TLV("MIXINL IN2L Volume", WM8962_LEFT_INPUT_MIXER_VOLUME, 6, 7, 0,
206 mixin_tlv),
207SOC_SINGLE_TLV("MIXINL PGA Volume", WM8962_LEFT_INPUT_MIXER_VOLUME, 3, 7, 0,
208 mixinpga_tlv),
209SOC_SINGLE_TLV("MIXINL IN3L Volume", WM8962_LEFT_INPUT_MIXER_VOLUME, 0, 7, 0,
210 mixin_tlv),
211
212SOC_SINGLE_TLV("MIXINR IN2R Volume", WM8962_RIGHT_INPUT_MIXER_VOLUME, 6, 7, 0,
213 mixin_tlv),
214SOC_SINGLE_TLV("MIXINR PGA Volume", WM8962_RIGHT_INPUT_MIXER_VOLUME, 3, 7, 0,
215 mixinpga_tlv),
216SOC_SINGLE_TLV("MIXINR IN3R Volume", WM8962_RIGHT_INPUT_MIXER_VOLUME, 0, 7, 0,
217 mixin_tlv),
218
219SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8962_LEFT_ADC_VOLUME,
220 WM8962_RIGHT_ADC_VOLUME, 1, 127, 0, digital_tlv),
221SOC_DOUBLE_R_TLV("Capture Volume", WM8962_LEFT_INPUT_VOLUME,
222 WM8962_RIGHT_INPUT_VOLUME, 0, 63, 0, inpga_tlv),
223SOC_DOUBLE_R("Capture Switch", WM8962_LEFT_INPUT_VOLUME,
224 WM8962_RIGHT_INPUT_VOLUME, 7, 1, 1),
225SOC_DOUBLE_R("Capture ZC Switch", WM8962_LEFT_INPUT_VOLUME,
226 WM8962_RIGHT_INPUT_VOLUME, 6, 1, 1),
227
228SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1,
229 WM8962_DAC_DSP_MIXING_2, 4, 12, 0, st_tlv),
230
231SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8962_LEFT_DAC_VOLUME,
232 WM8962_RIGHT_DAC_VOLUME, 1, 127, 0, digital_tlv),
233SOC_SINGLE("DAC High Performance Switch", WM8962_ADC_DAC_CONTROL_2, 0, 1, 0),
234
235SOC_SINGLE("ADC High Performance Switch", WM8962_ADDITIONAL_CONTROL_1,
236 5, 1, 0),
237
238SOC_SINGLE_TLV("Beep Volume", WM8962_BEEP_GENERATOR_1, 4, 15, 0, beep_tlv),
239
240SOC_DOUBLE_R_TLV("Headphone Volume", WM8962_HPOUTL_VOLUME,
241 WM8962_HPOUTR_VOLUME, 0, 127, 0, out_tlv),
242SOC_DOUBLE_EXT("Headphone Switch", WM8962_PWR_MGMT_2, 1, 0, 1, 1,
243 snd_soc_get_volsw, wm8962_put_hp_sw),
244SOC_DOUBLE_R("Headphone ZC Switch", WM8962_HPOUTL_VOLUME, WM8962_HPOUTR_VOLUME,
245 7, 1, 0),
246SOC_DOUBLE_TLV("Headphone Aux Volume", WM8962_ANALOGUE_HP_2, 3, 6, 7, 0,
247 hp_tlv),
248
249SOC_DOUBLE_R("Headphone Mixer Switch", WM8962_HEADPHONE_MIXER_3,
250 WM8962_HEADPHONE_MIXER_4, 8, 1, 1),
251
252SOC_SINGLE_TLV("HPMIXL IN4L Volume", WM8962_HEADPHONE_MIXER_3,
253 3, 7, 0, bypass_tlv),
254SOC_SINGLE_TLV("HPMIXL IN4R Volume", WM8962_HEADPHONE_MIXER_3,
255 0, 7, 0, bypass_tlv),
256SOC_SINGLE_TLV("HPMIXL MIXINL Volume", WM8962_HEADPHONE_MIXER_3,
257 7, 1, 1, inmix_tlv),
258SOC_SINGLE_TLV("HPMIXL MIXINR Volume", WM8962_HEADPHONE_MIXER_3,
259 6, 1, 1, inmix_tlv),
260
261SOC_SINGLE_TLV("HPMIXR IN4L Volume", WM8962_HEADPHONE_MIXER_4,
262 3, 7, 0, bypass_tlv),
263SOC_SINGLE_TLV("HPMIXR IN4R Volume", WM8962_HEADPHONE_MIXER_4,
264 0, 7, 0, bypass_tlv),
265SOC_SINGLE_TLV("HPMIXR MIXINL Volume", WM8962_HEADPHONE_MIXER_4,
266 7, 1, 1, inmix_tlv),
267SOC_SINGLE_TLV("HPMIXR MIXINR Volume", WM8962_HEADPHONE_MIXER_4,
268 6, 1, 1, inmix_tlv),
269
270SOC_SINGLE_TLV("Speaker Boost Volume", WM8962_CLASS_D_CONTROL_2, 0, 7, 0,
271 classd_tlv),
272};
273
274static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = {
275SOC_SINGLE_TLV("Speaker Volume", WM8962_SPKOUTL_VOLUME, 0, 127, 0, out_tlv),
276SOC_SINGLE_EXT("Speaker Switch", WM8962_CLASS_D_CONTROL_1, 1, 1, 1,
277 snd_soc_get_volsw, wm8962_put_spk_sw),
278SOC_SINGLE("Speaker ZC Switch", WM8962_SPKOUTL_VOLUME, 7, 1, 0),
279
280SOC_SINGLE("Speaker Mixer Switch", WM8962_SPEAKER_MIXER_3, 8, 1, 1),
281SOC_SINGLE_TLV("Speaker Mixer IN4L Volume", WM8962_SPEAKER_MIXER_3,
282 3, 7, 0, bypass_tlv),
283SOC_SINGLE_TLV("Speaker Mixer IN4R Volume", WM8962_SPEAKER_MIXER_3,
284 0, 7, 0, bypass_tlv),
285SOC_SINGLE_TLV("Speaker Mixer MIXINL Volume", WM8962_SPEAKER_MIXER_3,
286 7, 1, 1, inmix_tlv),
287SOC_SINGLE_TLV("Speaker Mixer MIXINR Volume", WM8962_SPEAKER_MIXER_3,
288 6, 1, 1, inmix_tlv),
289SOC_SINGLE_TLV("Speaker Mixer DACL Volume", WM8962_SPEAKER_MIXER_5,
290 7, 1, 0, inmix_tlv),
291SOC_SINGLE_TLV("Speaker Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
292 6, 1, 0, inmix_tlv),
293};
294
295static const struct snd_kcontrol_new wm8962_spk_stereo_controls[] = {
296SOC_DOUBLE_R_TLV("Speaker Volume", WM8962_SPKOUTL_VOLUME,
297 WM8962_SPKOUTR_VOLUME, 0, 127, 0, out_tlv),
298SOC_DOUBLE_EXT("Speaker Switch", WM8962_CLASS_D_CONTROL_1, 1, 0, 1, 1,
299 snd_soc_get_volsw, wm8962_put_spk_sw),
300SOC_DOUBLE_R("Speaker ZC Switch", WM8962_SPKOUTL_VOLUME, WM8962_SPKOUTR_VOLUME,
301 7, 1, 0),
302
303SOC_DOUBLE_R("Speaker Mixer Switch", WM8962_SPEAKER_MIXER_3,
304 WM8962_SPEAKER_MIXER_4, 8, 1, 1),
305
306SOC_SINGLE_TLV("SPKOUTL Mixer IN4L Volume", WM8962_SPEAKER_MIXER_3,
307 3, 7, 0, bypass_tlv),
308SOC_SINGLE_TLV("SPKOUTL Mixer IN4R Volume", WM8962_SPEAKER_MIXER_3,
309 0, 7, 0, bypass_tlv),
310SOC_SINGLE_TLV("SPKOUTL Mixer MIXINL Volume", WM8962_SPEAKER_MIXER_3,
311 7, 1, 1, inmix_tlv),
312SOC_SINGLE_TLV("SPKOUTL Mixer MIXINR Volume", WM8962_SPEAKER_MIXER_3,
313 6, 1, 1, inmix_tlv),
314SOC_SINGLE_TLV("SPKOUTL Mixer DACL Volume", WM8962_SPEAKER_MIXER_5,
315 7, 1, 0, inmix_tlv),
316SOC_SINGLE_TLV("SPKOUTL Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
317 6, 1, 0, inmix_tlv),
318
319SOC_SINGLE_TLV("SPKOUTR Mixer IN4L Volume", WM8962_SPEAKER_MIXER_4,
320 3, 7, 0, bypass_tlv),
321SOC_SINGLE_TLV("SPKOUTR Mixer IN4R Volume", WM8962_SPEAKER_MIXER_4,
322 0, 7, 0, bypass_tlv),
323SOC_SINGLE_TLV("SPKOUTR Mixer MIXINL Volume", WM8962_SPEAKER_MIXER_4,
324 7, 1, 1, inmix_tlv),
325SOC_SINGLE_TLV("SPKOUTR Mixer MIXINR Volume", WM8962_SPEAKER_MIXER_4,
326 6, 1, 1, inmix_tlv),
327SOC_SINGLE_TLV("SPKOUTR Mixer DACL Volume", WM8962_SPEAKER_MIXER_5,
328 5, 1, 0, inmix_tlv),
329SOC_SINGLE_TLV("SPKOUTR Mixer DACR Volume", WM8962_SPEAKER_MIXER_5,
330 4, 1, 0, inmix_tlv),
331};
332
333static int sysclk_event(struct snd_soc_dapm_widget *w,
334 struct snd_kcontrol *kcontrol, int event)
335{
336 struct snd_soc_codec *codec = w->codec;
337 int src;
338 int fll;
339
340 src = snd_soc_read(codec, WM8962_CLOCKING2) & WM8962_SYSCLK_SRC_MASK;
341
342 switch (src) {
343 case 0: /* MCLK */
344 fll = 0;
345 break;
346 case 0x200: /* FLL */
347 fll = 1;
348 break;
349 default:
350 dev_err(codec->dev, "Unknown SYSCLK source %x\n", src);
351 return -EINVAL;
352 }
353
354 switch (event) {
355 case SND_SOC_DAPM_PRE_PMU:
356 if (fll)
357 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
358 WM8962_FLL_ENA, WM8962_FLL_ENA);
359 break;
360
361 case SND_SOC_DAPM_POST_PMD:
362 if (fll)
363 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
364 WM8962_FLL_ENA, 0);
365 break;
366
367 default:
368 BUG();
369 return -EINVAL;
370 }
371
372 return 0;
373}
374
375static int cp_event(struct snd_soc_dapm_widget *w,
376 struct snd_kcontrol *kcontrol, int event)
377{
378 switch (event) {
379 case SND_SOC_DAPM_POST_PMU:
380 msleep(5);
381 break;
382
383 default:
384 BUG();
385 return -EINVAL;
386 }
387
388 return 0;
389}
390
391static int hp_event(struct snd_soc_dapm_widget *w,
392 struct snd_kcontrol *kcontrol, int event)
393{
394 struct snd_soc_codec *codec = w->codec;
395 int timeout;
396 int reg;
397 int expected = (WM8962_DCS_STARTUP_DONE_HP1L |
398 WM8962_DCS_STARTUP_DONE_HP1R);
399
400 switch (event) {
401 case SND_SOC_DAPM_POST_PMU:
402 snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
403 WM8962_HP1L_ENA | WM8962_HP1R_ENA,
404 WM8962_HP1L_ENA | WM8962_HP1R_ENA);
405 udelay(20);
406
407 snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
408 WM8962_HP1L_ENA_DLY | WM8962_HP1R_ENA_DLY,
409 WM8962_HP1L_ENA_DLY | WM8962_HP1R_ENA_DLY);
410
411 /* Start the DC servo */
412 snd_soc_update_bits(codec, WM8962_DC_SERVO_1,
413 WM8962_HP1L_DCS_ENA | WM8962_HP1R_DCS_ENA |
414 WM8962_HP1L_DCS_STARTUP |
415 WM8962_HP1R_DCS_STARTUP,
416 WM8962_HP1L_DCS_ENA | WM8962_HP1R_DCS_ENA |
417 WM8962_HP1L_DCS_STARTUP |
418 WM8962_HP1R_DCS_STARTUP);
419
420 /* Wait for it to complete, should be well under 100ms */
421 timeout = 0;
422 do {
423 msleep(1);
424 reg = snd_soc_read(codec, WM8962_DC_SERVO_6);
425 if (reg < 0) {
426 dev_err(codec->dev,
427 "Failed to read DCS status: %d\n",
428 reg);
429 continue;
430 }
431 dev_dbg(codec->dev, "DCS status: %x\n", reg);
432 } while (++timeout < 200 && (reg & expected) != expected);
433
434 if ((reg & expected) != expected)
435 dev_err(codec->dev, "DC servo timed out\n");
436 else
437 dev_dbg(codec->dev, "DC servo complete after %dms\n",
438 timeout);
439
440 snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
441 WM8962_HP1L_ENA_OUTP |
442 WM8962_HP1R_ENA_OUTP,
443 WM8962_HP1L_ENA_OUTP |
444 WM8962_HP1R_ENA_OUTP);
445 udelay(20);
446
447 snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
448 WM8962_HP1L_RMV_SHORT |
449 WM8962_HP1R_RMV_SHORT,
450 WM8962_HP1L_RMV_SHORT |
451 WM8962_HP1R_RMV_SHORT);
452 break;
453
454 case SND_SOC_DAPM_PRE_PMD:
455 snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
456 WM8962_HP1L_RMV_SHORT |
457 WM8962_HP1R_RMV_SHORT, 0);
458
459 udelay(20);
460
461 snd_soc_update_bits(codec, WM8962_DC_SERVO_1,
462 WM8962_HP1L_DCS_ENA | WM8962_HP1R_DCS_ENA |
463 WM8962_HP1L_DCS_STARTUP |
464 WM8962_HP1R_DCS_STARTUP,
465 0);
466
467 snd_soc_update_bits(codec, WM8962_ANALOGUE_HP_0,
468 WM8962_HP1L_ENA | WM8962_HP1R_ENA |
469 WM8962_HP1L_ENA_DLY | WM8962_HP1R_ENA_DLY |
470 WM8962_HP1L_ENA_OUTP |
471 WM8962_HP1R_ENA_OUTP, 0);
472
473 break;
474
475 default:
476 BUG();
477 return -EINVAL;
478
479 }
480
481 return 0;
482}
483
484/* VU bits for the output PGAs only take effect while the PGA is powered */
485static int out_pga_event(struct snd_soc_dapm_widget *w,
486 struct snd_kcontrol *kcontrol, int event)
487{
488 struct snd_soc_codec *codec = w->codec;
489 u16 *reg_cache = codec->reg_cache;
490 int reg;
491
492 switch (w->shift) {
493 case WM8962_HPOUTR_PGA_ENA_SHIFT:
494 reg = WM8962_HPOUTR_VOLUME;
495 break;
496 case WM8962_HPOUTL_PGA_ENA_SHIFT:
497 reg = WM8962_HPOUTL_VOLUME;
498 break;
499 case WM8962_SPKOUTR_PGA_ENA_SHIFT:
500 reg = WM8962_SPKOUTR_VOLUME;
501 break;
502 case WM8962_SPKOUTL_PGA_ENA_SHIFT:
503 reg = WM8962_SPKOUTL_VOLUME;
504 break;
505 default:
506 BUG();
507 return -EINVAL;
508 }
509
510 switch (event) {
511 case SND_SOC_DAPM_POST_PMU:
512 return snd_soc_write(codec, reg, reg_cache[reg]);
513 default:
514 BUG();
515 return -EINVAL;
516 }
517}
518
519static const char *st_text[] = { "None", "Right", "Left" };
520
521static const struct soc_enum str_enum =
522 SOC_ENUM_SINGLE(WM8962_DAC_DSP_MIXING_1, 2, 3, st_text);
523
524static const struct snd_kcontrol_new str_mux =
525 SOC_DAPM_ENUM("Right Sidetone", str_enum);
526
527static const struct soc_enum stl_enum =
528 SOC_ENUM_SINGLE(WM8962_DAC_DSP_MIXING_2, 2, 3, st_text);
529
530static const struct snd_kcontrol_new stl_mux =
531 SOC_DAPM_ENUM("Left Sidetone", stl_enum);
532
533static const char *outmux_text[] = { "DAC", "Mixer" };
534
535static const struct soc_enum spkoutr_enum =
536 SOC_ENUM_SINGLE(WM8962_SPEAKER_MIXER_2, 7, 2, outmux_text);
537
538static const struct snd_kcontrol_new spkoutr_mux =
539 SOC_DAPM_ENUM("SPKOUTR Mux", spkoutr_enum);
540
541static const struct soc_enum spkoutl_enum =
542 SOC_ENUM_SINGLE(WM8962_SPEAKER_MIXER_1, 7, 2, outmux_text);
543
544static const struct snd_kcontrol_new spkoutl_mux =
545 SOC_DAPM_ENUM("SPKOUTL Mux", spkoutl_enum);
546
547static const struct soc_enum hpoutr_enum =
548 SOC_ENUM_SINGLE(WM8962_HEADPHONE_MIXER_2, 7, 2, outmux_text);
549
550static const struct snd_kcontrol_new hpoutr_mux =
551 SOC_DAPM_ENUM("HPOUTR Mux", hpoutr_enum);
552
553static const struct soc_enum hpoutl_enum =
554 SOC_ENUM_SINGLE(WM8962_HEADPHONE_MIXER_1, 7, 2, outmux_text);
555
556static const struct snd_kcontrol_new hpoutl_mux =
557 SOC_DAPM_ENUM("HPOUTL Mux", hpoutl_enum);
558
559static const struct snd_kcontrol_new inpgal[] = {
560SOC_DAPM_SINGLE("IN1L Switch", WM8962_LEFT_INPUT_PGA_CONTROL, 3, 1, 0),
561SOC_DAPM_SINGLE("IN2L Switch", WM8962_LEFT_INPUT_PGA_CONTROL, 2, 1, 0),
562SOC_DAPM_SINGLE("IN3L Switch", WM8962_LEFT_INPUT_PGA_CONTROL, 1, 1, 0),
563SOC_DAPM_SINGLE("IN4L Switch", WM8962_LEFT_INPUT_PGA_CONTROL, 0, 1, 0),
564};
565
566static const struct snd_kcontrol_new inpgar[] = {
567SOC_DAPM_SINGLE("IN1R Switch", WM8962_RIGHT_INPUT_PGA_CONTROL, 3, 1, 0),
568SOC_DAPM_SINGLE("IN2R Switch", WM8962_RIGHT_INPUT_PGA_CONTROL, 2, 1, 0),
569SOC_DAPM_SINGLE("IN3R Switch", WM8962_RIGHT_INPUT_PGA_CONTROL, 1, 1, 0),
570SOC_DAPM_SINGLE("IN4R Switch", WM8962_RIGHT_INPUT_PGA_CONTROL, 0, 1, 0),
571};
572
573static const struct snd_kcontrol_new mixinl[] = {
574SOC_DAPM_SINGLE("IN2L Switch", WM8962_INPUT_MIXER_CONTROL_2, 5, 1, 0),
575SOC_DAPM_SINGLE("IN3L Switch", WM8962_INPUT_MIXER_CONTROL_2, 4, 1, 0),
576SOC_DAPM_SINGLE("PGA Switch", WM8962_INPUT_MIXER_CONTROL_2, 3, 1, 0),
577};
578
579static const struct snd_kcontrol_new mixinr[] = {
580SOC_DAPM_SINGLE("IN2R Switch", WM8962_INPUT_MIXER_CONTROL_2, 2, 1, 0),
581SOC_DAPM_SINGLE("IN3R Switch", WM8962_INPUT_MIXER_CONTROL_2, 1, 1, 0),
582SOC_DAPM_SINGLE("PGA Switch", WM8962_INPUT_MIXER_CONTROL_2, 0, 1, 0),
583};
584
585static const struct snd_kcontrol_new hpmixl[] = {
586SOC_DAPM_SINGLE("DACL Switch", WM8962_HEADPHONE_MIXER_1, 5, 1, 0),
587SOC_DAPM_SINGLE("DACR Switch", WM8962_HEADPHONE_MIXER_1, 4, 1, 0),
588SOC_DAPM_SINGLE("MIXINL Switch", WM8962_HEADPHONE_MIXER_1, 3, 1, 0),
589SOC_DAPM_SINGLE("MIXINR Switch", WM8962_HEADPHONE_MIXER_1, 2, 1, 0),
590SOC_DAPM_SINGLE("IN4L Switch", WM8962_HEADPHONE_MIXER_1, 1, 1, 0),
591SOC_DAPM_SINGLE("IN4R Switch", WM8962_HEADPHONE_MIXER_1, 0, 1, 0),
592};
593
594static const struct snd_kcontrol_new hpmixr[] = {
595SOC_DAPM_SINGLE("DACL Switch", WM8962_HEADPHONE_MIXER_2, 5, 1, 0),
596SOC_DAPM_SINGLE("DACR Switch", WM8962_HEADPHONE_MIXER_2, 4, 1, 0),
597SOC_DAPM_SINGLE("MIXINL Switch", WM8962_HEADPHONE_MIXER_2, 3, 1, 0),
598SOC_DAPM_SINGLE("MIXINR Switch", WM8962_HEADPHONE_MIXER_2, 2, 1, 0),
599SOC_DAPM_SINGLE("IN4L Switch", WM8962_HEADPHONE_MIXER_2, 1, 1, 0),
600SOC_DAPM_SINGLE("IN4R Switch", WM8962_HEADPHONE_MIXER_2, 0, 1, 0),
601};
602
603static const struct snd_kcontrol_new spkmixl[] = {
604SOC_DAPM_SINGLE("DACL Switch", WM8962_SPEAKER_MIXER_1, 5, 1, 0),
605SOC_DAPM_SINGLE("DACR Switch", WM8962_SPEAKER_MIXER_1, 4, 1, 0),
606SOC_DAPM_SINGLE("MIXINL Switch", WM8962_SPEAKER_MIXER_1, 3, 1, 0),
607SOC_DAPM_SINGLE("MIXINR Switch", WM8962_SPEAKER_MIXER_1, 2, 1, 0),
608SOC_DAPM_SINGLE("IN4L Switch", WM8962_SPEAKER_MIXER_1, 1, 1, 0),
609SOC_DAPM_SINGLE("IN4R Switch", WM8962_SPEAKER_MIXER_1, 0, 1, 0),
610};
611
612static const struct snd_kcontrol_new spkmixr[] = {
613SOC_DAPM_SINGLE("DACL Switch", WM8962_SPEAKER_MIXER_2, 5, 1, 0),
614SOC_DAPM_SINGLE("DACR Switch", WM8962_SPEAKER_MIXER_2, 4, 1, 0),
615SOC_DAPM_SINGLE("MIXINL Switch", WM8962_SPEAKER_MIXER_2, 3, 1, 0),
616SOC_DAPM_SINGLE("MIXINR Switch", WM8962_SPEAKER_MIXER_2, 2, 1, 0),
617SOC_DAPM_SINGLE("IN4L Switch", WM8962_SPEAKER_MIXER_2, 1, 1, 0),
618SOC_DAPM_SINGLE("IN4R Switch", WM8962_SPEAKER_MIXER_2, 0, 1, 0),
619};
620
621static const struct snd_soc_dapm_widget wm8962_dapm_widgets[] = {
622SND_SOC_DAPM_INPUT("IN1L"),
623SND_SOC_DAPM_INPUT("IN1R"),
624SND_SOC_DAPM_INPUT("IN2L"),
625SND_SOC_DAPM_INPUT("IN2R"),
626SND_SOC_DAPM_INPUT("IN3L"),
627SND_SOC_DAPM_INPUT("IN3R"),
628SND_SOC_DAPM_INPUT("IN4L"),
629SND_SOC_DAPM_INPUT("IN4R"),
630SND_SOC_DAPM_INPUT("Beep"),
631
632SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0),
633SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event,
634 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
635SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event,
636 SND_SOC_DAPM_POST_PMU),
637SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0),
638
639SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0,
640 inpgal, ARRAY_SIZE(inpgal)),
641SND_SOC_DAPM_MIXER("INPGAR", WM8962_RIGHT_INPUT_PGA_CONTROL, 4, 0,
642 inpgar, ARRAY_SIZE(inpgar)),
643SND_SOC_DAPM_MIXER("MIXINL", WM8962_PWR_MGMT_1, 5, 0,
644 mixinl, ARRAY_SIZE(mixinl)),
645SND_SOC_DAPM_MIXER("MIXINR", WM8962_PWR_MGMT_1, 4, 0,
646 mixinr, ARRAY_SIZE(mixinr)),
647
648SND_SOC_DAPM_ADC("ADCL", "Capture", WM8962_PWR_MGMT_1, 3, 0),
649SND_SOC_DAPM_ADC("ADCR", "Capture", WM8962_PWR_MGMT_1, 2, 0),
650
651SND_SOC_DAPM_MUX("STL", SND_SOC_NOPM, 0, 0, &stl_mux),
652SND_SOC_DAPM_MUX("STR", SND_SOC_NOPM, 0, 0, &str_mux),
653
654SND_SOC_DAPM_DAC("DACL", "Playback", WM8962_PWR_MGMT_2, 8, 0),
655SND_SOC_DAPM_DAC("DACR", "Playback", WM8962_PWR_MGMT_2, 7, 0),
656
657SND_SOC_DAPM_PGA("Left Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
658SND_SOC_DAPM_PGA("Right Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
659
660SND_SOC_DAPM_MIXER("HPMIXL", WM8962_MIXER_ENABLES, 3, 0,
661 hpmixl, ARRAY_SIZE(hpmixl)),
662SND_SOC_DAPM_MIXER("HPMIXR", WM8962_MIXER_ENABLES, 2, 0,
663 hpmixr, ARRAY_SIZE(hpmixr)),
664
665SND_SOC_DAPM_MUX_E("HPOUTL PGA", WM8962_PWR_MGMT_2, 6, 0, &hpoutl_mux,
666 out_pga_event, SND_SOC_DAPM_POST_PMU),
667SND_SOC_DAPM_MUX_E("HPOUTR PGA", WM8962_PWR_MGMT_2, 5, 0, &hpoutr_mux,
668 out_pga_event, SND_SOC_DAPM_POST_PMU),
669
670SND_SOC_DAPM_PGA_E("HPOUT", SND_SOC_NOPM, 0, 0, NULL, 0, hp_event,
671 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
672
673SND_SOC_DAPM_OUTPUT("HPOUTL"),
674SND_SOC_DAPM_OUTPUT("HPOUTR"),
675};
676
677static const struct snd_soc_dapm_widget wm8962_dapm_spk_mono_widgets[] = {
678SND_SOC_DAPM_MIXER("Speaker Mixer", WM8962_MIXER_ENABLES, 1, 0,
679 spkmixl, ARRAY_SIZE(spkmixl)),
680SND_SOC_DAPM_MUX_E("Speaker PGA", WM8962_PWR_MGMT_2, 4, 0, &spkoutl_mux,
681 out_pga_event, SND_SOC_DAPM_POST_PMU),
682SND_SOC_DAPM_PGA("Speaker Output", WM8962_CLASS_D_CONTROL_1, 7, 0, NULL, 0),
683SND_SOC_DAPM_OUTPUT("SPKOUT"),
684};
685
686static const struct snd_soc_dapm_widget wm8962_dapm_spk_stereo_widgets[] = {
687SND_SOC_DAPM_MIXER("SPKOUTL Mixer", WM8962_MIXER_ENABLES, 1, 0,
688 spkmixl, ARRAY_SIZE(spkmixl)),
689SND_SOC_DAPM_MIXER("SPKOUTR Mixer", WM8962_MIXER_ENABLES, 0, 0,
690 spkmixr, ARRAY_SIZE(spkmixr)),
691
692SND_SOC_DAPM_MUX_E("SPKOUTL PGA", WM8962_PWR_MGMT_2, 4, 0, &spkoutl_mux,
693 out_pga_event, SND_SOC_DAPM_POST_PMU),
694SND_SOC_DAPM_MUX_E("SPKOUTR PGA", WM8962_PWR_MGMT_2, 3, 0, &spkoutr_mux,
695 out_pga_event, SND_SOC_DAPM_POST_PMU),
696
697SND_SOC_DAPM_PGA("SPKOUTR Output", WM8962_CLASS_D_CONTROL_1, 7, 0, NULL, 0),
698SND_SOC_DAPM_PGA("SPKOUTL Output", WM8962_CLASS_D_CONTROL_1, 6, 0, NULL, 0),
699
700SND_SOC_DAPM_OUTPUT("SPKOUTL"),
701SND_SOC_DAPM_OUTPUT("SPKOUTR"),
702};
703
704static const struct snd_soc_dapm_route wm8962_intercon[] = {
705 { "INPGAL", "IN1L Switch", "IN1L" },
706 { "INPGAL", "IN2L Switch", "IN2L" },
707 { "INPGAL", "IN3L Switch", "IN3L" },
708 { "INPGAL", "IN4L Switch", "IN4L" },
709
710 { "INPGAR", "IN1R Switch", "IN1R" },
711 { "INPGAR", "IN2R Switch", "IN2R" },
712 { "INPGAR", "IN3R Switch", "IN3R" },
713 { "INPGAR", "IN4R Switch", "IN4R" },
714
715 { "MIXINL", "IN2L Switch", "IN2L" },
716 { "MIXINL", "IN3L Switch", "IN3L" },
717 { "MIXINL", "PGA Switch", "INPGAL" },
718
719 { "MIXINR", "IN2R Switch", "IN2R" },
720 { "MIXINR", "IN3R Switch", "IN3R" },
721 { "MIXINR", "PGA Switch", "INPGAR" },
722
723 { "ADCL", NULL, "SYSCLK" },
724 { "ADCL", NULL, "TOCLK" },
725 { "ADCL", NULL, "MIXINL" },
726
727 { "ADCR", NULL, "SYSCLK" },
728 { "ADCR", NULL, "TOCLK" },
729 { "ADCR", NULL, "MIXINR" },
730
731 { "STL", "Left", "ADCL" },
732 { "STL", "Right", "ADCR" },
733
734 { "STR", "Left", "ADCL" },
735 { "STR", "Right", "ADCR" },
736
737 { "DACL", NULL, "SYSCLK" },
738 { "DACL", NULL, "TOCLK" },
739 { "DACL", NULL, "Beep" },
740 { "DACL", NULL, "STL" },
741
742 { "DACR", NULL, "SYSCLK" },
743 { "DACR", NULL, "TOCLK" },
744 { "DACR", NULL, "Beep" },
745 { "DACR", NULL, "STR" },
746
747 { "HPMIXL", "IN4L Switch", "IN4L" },
748 { "HPMIXL", "IN4R Switch", "IN4R" },
749 { "HPMIXL", "DACL Switch", "DACL" },
750 { "HPMIXL", "DACR Switch", "DACR" },
751 { "HPMIXL", "MIXINL Switch", "MIXINL" },
752 { "HPMIXL", "MIXINR Switch", "MIXINR" },
753
754 { "HPMIXR", "IN4L Switch", "IN4L" },
755 { "HPMIXR", "IN4R Switch", "IN4R" },
756 { "HPMIXR", "DACL Switch", "DACL" },
757 { "HPMIXR", "DACR Switch", "DACR" },
758 { "HPMIXR", "MIXINL Switch", "MIXINL" },
759 { "HPMIXR", "MIXINR Switch", "MIXINR" },
760
761 { "Left Bypass", NULL, "HPMIXL" },
762 { "Left Bypass", NULL, "Class G" },
763
764 { "Right Bypass", NULL, "HPMIXR" },
765 { "Right Bypass", NULL, "Class G" },
766
767 { "HPOUTL PGA", "Mixer", "Left Bypass" },
768 { "HPOUTL PGA", "DAC", "DACL" },
769
770 { "HPOUTR PGA", "Mixer", "Right Bypass" },
771 { "HPOUTR PGA", "DAC", "DACR" },
772
773 { "HPOUT", NULL, "HPOUTL PGA" },
774 { "HPOUT", NULL, "HPOUTR PGA" },
775 { "HPOUT", NULL, "Charge Pump" },
776 { "HPOUT", NULL, "SYSCLK" },
777 { "HPOUT", NULL, "TOCLK" },
778
779 { "HPOUTL", NULL, "HPOUT" },
780 { "HPOUTR", NULL, "HPOUT" },
781};
782
783static const struct snd_soc_dapm_route wm8962_spk_mono_intercon[] = {
784 { "Speaker Mixer", "IN4L Switch", "IN4L" },
785 { "Speaker Mixer", "IN4R Switch", "IN4R" },
786 { "Speaker Mixer", "DACL Switch", "DACL" },
787 { "Speaker Mixer", "DACR Switch", "DACR" },
788 { "Speaker Mixer", "MIXINL Switch", "MIXINL" },
789 { "Speaker Mixer", "MIXINR Switch", "MIXINR" },
790
791 { "Speaker PGA", "Mixer", "Speaker Mixer" },
792 { "Speaker PGA", "DAC", "DACL" },
793
794 { "Speaker Output", NULL, "Speaker PGA" },
795 { "Speaker Output", NULL, "SYSCLK" },
796 { "Speaker Output", NULL, "TOCLK" },
797
798 { "SPKOUT", NULL, "Speaker Output" },
799};
800
801static const struct snd_soc_dapm_route wm8962_spk_stereo_intercon[] = {
802 { "SPKOUTL Mixer", "IN4L Switch", "IN4L" },
803 { "SPKOUTL Mixer", "IN4R Switch", "IN4R" },
804 { "SPKOUTL Mixer", "DACL Switch", "DACL" },
805 { "SPKOUTL Mixer", "DACR Switch", "DACR" },
806 { "SPKOUTL Mixer", "MIXINL Switch", "MIXINL" },
807 { "SPKOUTL Mixer", "MIXINR Switch", "MIXINR" },
808
809 { "SPKOUTR Mixer", "IN4L Switch", "IN4L" },
810 { "SPKOUTR Mixer", "IN4R Switch", "IN4R" },
811 { "SPKOUTR Mixer", "DACL Switch", "DACL" },
812 { "SPKOUTR Mixer", "DACR Switch", "DACR" },
813 { "SPKOUTR Mixer", "MIXINL Switch", "MIXINL" },
814 { "SPKOUTR Mixer", "MIXINR Switch", "MIXINR" },
815
816 { "SPKOUTL PGA", "Mixer", "SPKOUTL Mixer" },
817 { "SPKOUTL PGA", "DAC", "DACL" },
818
819 { "SPKOUTR PGA", "Mixer", "SPKOUTR Mixer" },
820 { "SPKOUTR PGA", "DAC", "DACR" },
821
822 { "SPKOUTL Output", NULL, "SPKOUTL PGA" },
823 { "SPKOUTL Output", NULL, "SYSCLK" },
824 { "SPKOUTL Output", NULL, "TOCLK" },
825
826 { "SPKOUTR Output", NULL, "SPKOUTR PGA" },
827 { "SPKOUTR Output", NULL, "SYSCLK" },
828 { "SPKOUTR Output", NULL, "TOCLK" },
829
830 { "SPKOUTL", NULL, "SPKOUTL Output" },
831 { "SPKOUTR", NULL, "SPKOUTR Output" },
832};
833
834static int wm8962_add_widgets(struct snd_soc_codec *codec)
835{
836 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
837
838 snd_soc_add_controls(codec, wm8962_snd_controls,
839 ARRAY_SIZE(wm8962_snd_controls));
840 if (pdata && pdata->spk_mono)
841 snd_soc_add_controls(codec, wm8962_spk_mono_controls,
842 ARRAY_SIZE(wm8962_spk_mono_controls));
843 else
844 snd_soc_add_controls(codec, wm8962_spk_stereo_controls,
845 ARRAY_SIZE(wm8962_spk_stereo_controls));
846
847
848 snd_soc_dapm_new_controls(codec, wm8962_dapm_widgets,
849 ARRAY_SIZE(wm8962_dapm_widgets));
850 if (pdata && pdata->spk_mono)
851 snd_soc_dapm_new_controls(codec, wm8962_dapm_spk_mono_widgets,
852 ARRAY_SIZE(wm8962_dapm_spk_mono_widgets));
853 else
854 snd_soc_dapm_new_controls(codec, wm8962_dapm_spk_stereo_widgets,
855 ARRAY_SIZE(wm8962_dapm_spk_stereo_widgets));
856
857 snd_soc_dapm_add_routes(codec, wm8962_intercon,
858 ARRAY_SIZE(wm8962_intercon));
859 if (pdata && pdata->spk_mono)
860 snd_soc_dapm_add_routes(codec, wm8962_spk_mono_intercon,
861 ARRAY_SIZE(wm8962_spk_mono_intercon));
862 else
863 snd_soc_dapm_add_routes(codec, wm8962_spk_stereo_intercon,
864 ARRAY_SIZE(wm8962_spk_stereo_intercon));
865
866
867 snd_soc_dapm_disable_pin(codec, "Beep");
868
869 return 0;
870}
871
872static void wm8962_sync_cache(struct snd_soc_codec *codec)
873{
874 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
875 int i;
876
877 if (!codec->cache_sync)
878 return;
879
880 dev_dbg(codec->dev, "Syncing cache\n");
881
882 codec->cache_only = 0;
883
884 /* Sync back cached values if they're different from the
885 * hardware default.
886 */
887 for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) {
888 if (i == WM8962_SOFTWARE_RESET)
889 continue;
890 if (wm8962->reg_cache[i] == wm8962_reg[i])
891 continue;
892
893 snd_soc_write(codec, i, wm8962->reg_cache[i]);
894 }
895
896 codec->cache_sync = 0;
897}
898
899/* -1 for reserved values */
900static const int bclk_divs[] = {
901 1, -1, 2, 3, 4, -1, 6, 8, -1, 12, 16, 24, -1, 32, 32, 32
902};
903
904static void wm8962_configure_bclk(struct snd_soc_codec *codec)
905{
906 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
907 int dspclk, i;
908 int clocking2 = 0;
909 int aif2 = 0;
910
911 /* If the CODEC is powered on we can configure BCLK */
912 if (codec->bias_level != SND_SOC_BIAS_OFF) {
913 dev_dbg(codec->dev, "Bias is off, can't configure BCLK\n");
914 return;
915 }
916
917 if (!wm8962->bclk) {
918 dev_dbg(codec->dev, "No BCLK rate configured\n");
919 return;
920 }
921
922 dspclk = snd_soc_read(codec, WM8962_CLOCKING1);
923 if (dspclk < 0) {
924 dev_err(codec->dev, "Failed to read DSPCLK: %d\n", dspclk);
925 return;
926 }
927
928 dspclk = (dspclk & WM8962_DSPCLK_DIV_MASK) >> WM8962_DSPCLK_DIV_SHIFT;
929 switch (dspclk) {
930 case 0:
931 dspclk = wm8962->sysclk_rate;
932 break;
933 case 1:
934 dspclk = wm8962->sysclk_rate / 2;
935 break;
936 case 2:
937 dspclk = wm8962->sysclk_rate / 4;
938 break;
939 default:
940 dev_warn(codec->dev, "Unknown DSPCLK divisor read back\n");
941 dspclk = wm8962->sysclk;
942 }
943
944 dev_dbg(codec->dev, "DSPCLK is %dHz, BCLK %d\n", dspclk, wm8962->bclk);
945
946 /* We're expecting an exact match */
947 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
948 if (bclk_divs[i] < 0)
949 continue;
950
951 if (dspclk / bclk_divs[i] == wm8962->bclk) {
952 dev_dbg(codec->dev, "Selected BCLK_DIV %d for %dHz\n",
953 bclk_divs[i], wm8962->bclk);
954 clocking2 |= i;
955 break;
956 }
957 }
958 if (i == ARRAY_SIZE(bclk_divs)) {
959 dev_err(codec->dev, "Unsupported BCLK ratio %d\n",
960 dspclk / wm8962->bclk);
961 return;
962 }
963
964 aif2 |= wm8962->bclk / wm8962->lrclk;
965 dev_dbg(codec->dev, "Selected LRCLK divisor %d for %dHz\n",
966 wm8962->bclk / wm8962->lrclk, wm8962->lrclk);
967
968 snd_soc_update_bits(codec, WM8962_CLOCKING2,
969 WM8962_BCLK_DIV_MASK, clocking2);
970 snd_soc_update_bits(codec, WM8962_AUDIO_INTERFACE_2,
971 WM8962_AIF_RATE_MASK, aif2);
972}
973
974static int wm8962_set_bias_level(struct snd_soc_codec *codec,
975 enum snd_soc_bias_level level)
976{
977 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
978 int ret;
979
980 if (level == codec->bias_level)
981 return 0;
982
983 switch (level) {
984 case SND_SOC_BIAS_ON:
985 break;
986
987 case SND_SOC_BIAS_PREPARE:
988 /* VMID 2*50k */
989 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
990 WM8962_VMID_SEL_MASK, 0x80);
991 break;
992
993 case SND_SOC_BIAS_STANDBY:
994 if (codec->bias_level == SND_SOC_BIAS_OFF) {
995 ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
996 wm8962->supplies);
997 if (ret != 0) {
998 dev_err(codec->dev,
999 "Failed to enable supplies: %d\n",
1000 ret);
1001 return ret;
1002 }
1003
1004 wm8962_sync_cache(codec);
1005
1006 snd_soc_update_bits(codec, WM8962_ANTI_POP,
1007 WM8962_STARTUP_BIAS_ENA |
1008 WM8962_VMID_BUF_ENA,
1009 WM8962_STARTUP_BIAS_ENA |
1010 WM8962_VMID_BUF_ENA);
1011
1012 /* Bias enable at 2*50k for ramp */
1013 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
1014 WM8962_VMID_SEL_MASK |
1015 WM8962_BIAS_ENA,
1016 WM8962_BIAS_ENA | 0x180);
1017
1018 msleep(5);
1019
1020 snd_soc_update_bits(codec, WM8962_CLOCKING2,
1021 WM8962_CLKREG_OVD,
1022 WM8962_CLKREG_OVD);
1023
1024 wm8962_configure_bclk(codec);
1025 }
1026
1027 /* VMID 2*250k */
1028 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
1029 WM8962_VMID_SEL_MASK, 0x100);
1030 break;
1031
1032 case SND_SOC_BIAS_OFF:
1033 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1,
1034 WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, 0);
1035
1036 snd_soc_update_bits(codec, WM8962_ANTI_POP,
1037 WM8962_STARTUP_BIAS_ENA |
1038 WM8962_VMID_BUF_ENA, 0);
1039
1040 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies),
1041 wm8962->supplies);
1042 break;
1043 }
1044 codec->bias_level = level;
1045 return 0;
1046}
1047
1048static const struct {
1049 int rate;
1050 int reg;
1051} sr_vals[] = {
1052 { 48000, 0 },
1053 { 44100, 0 },
1054 { 32000, 1 },
1055 { 22050, 2 },
1056 { 24000, 2 },
1057 { 16000, 3 },
1058 { 11025, 4 },
1059 { 12000, 4 },
1060 { 8000, 5 },
1061 { 88200, 6 },
1062 { 96000, 6 },
1063};
1064
1065static const int sysclk_rates[] = {
1066 64, 128, 192, 256, 384, 512, 768, 1024, 1408, 1536,
1067};
1068
1069static int wm8962_hw_params(struct snd_pcm_substream *substream,
1070 struct snd_pcm_hw_params *params,
1071 struct snd_soc_dai *dai)
1072{
1073 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1074 struct snd_soc_device *socdev = rtd->socdev;
1075 struct snd_soc_codec *codec = socdev->card->codec;
1076 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
1077 int rate = params_rate(params);
1078 int i;
1079 int aif0 = 0;
1080 int adctl3 = 0;
1081 int clocking4 = 0;
1082
1083 wm8962->bclk = snd_soc_params_to_bclk(params);
1084 wm8962->lrclk = params_rate(params);
1085
1086 for (i = 0; i < ARRAY_SIZE(sr_vals); i++) {
1087 if (sr_vals[i].rate == rate) {
1088 adctl3 |= sr_vals[i].reg;
1089 break;
1090 }
1091 }
1092 if (i == ARRAY_SIZE(sr_vals)) {
1093 dev_err(codec->dev, "Unsupported rate %dHz\n", rate);
1094 return -EINVAL;
1095 }
1096
1097 if (rate % 8000 == 0)
1098 adctl3 |= WM8962_SAMPLE_RATE_INT_MODE;
1099
1100 for (i = 0; i < ARRAY_SIZE(sysclk_rates); i++) {
1101 if (sysclk_rates[i] == wm8962->sysclk_rate / rate) {
1102 clocking4 |= i << WM8962_SYSCLK_RATE_SHIFT;
1103 break;
1104 }
1105 }
1106 if (i == ARRAY_SIZE(sysclk_rates)) {
1107 dev_err(codec->dev, "Unsupported sysclk ratio %d\n",
1108 wm8962->sysclk_rate / rate);
1109 return -EINVAL;
1110 }
1111
1112 switch (params_format(params)) {
1113 case SNDRV_PCM_FORMAT_S16_LE:
1114 break;
1115 case SNDRV_PCM_FORMAT_S20_3LE:
1116 aif0 |= 0x40;
1117 break;
1118 case SNDRV_PCM_FORMAT_S24_LE:
1119 aif0 |= 0x80;
1120 break;
1121 case SNDRV_PCM_FORMAT_S32_LE:
1122 aif0 |= 0xc0;
1123 break;
1124 default:
1125 return -EINVAL;
1126 }
1127
1128 snd_soc_update_bits(codec, WM8962_AUDIO_INTERFACE_0,
1129 WM8962_WL_MASK, aif0);
1130 snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_3,
1131 WM8962_SAMPLE_RATE_INT_MODE |
1132 WM8962_SAMPLE_RATE_MASK, adctl3);
1133 snd_soc_update_bits(codec, WM8962_CLOCKING_4,
1134 WM8962_SYSCLK_RATE_MASK, clocking4);
1135
1136 wm8962_configure_bclk(codec);
1137
1138 return 0;
1139}
1140
1141static int wm8962_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
1142 unsigned int freq, int dir)
1143{
1144 struct snd_soc_codec *codec = dai->codec;
1145 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
1146 int src;
1147
1148 switch (clk_id) {
1149 case WM8962_SYSCLK_MCLK:
1150 wm8962->sysclk = WM8962_SYSCLK_MCLK;
1151 src = 0;
1152 break;
1153 case WM8962_SYSCLK_FLL:
1154 wm8962->sysclk = WM8962_SYSCLK_FLL;
1155 src = 1 << WM8962_SYSCLK_SRC_SHIFT;
1156 WARN_ON(freq != wm8962->fll_fout);
1157 break;
1158 default:
1159 return -EINVAL;
1160 }
1161
1162 snd_soc_update_bits(codec, WM8962_CLOCKING2, WM8962_SYSCLK_SRC_MASK,
1163 src);
1164
1165 wm8962->sysclk_rate = freq;
1166
1167 return 0;
1168}
1169
1170static int wm8962_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1171{
1172 struct snd_soc_codec *codec = dai->codec;
1173 int aif0 = 0;
1174
1175 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1176 case SND_SOC_DAIFMT_DSP_A:
1177 aif0 |= WM8962_LRCLK_INV;
1178 case SND_SOC_DAIFMT_DSP_B:
1179 aif0 |= 3;
1180
1181 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1182 case SND_SOC_DAIFMT_NB_NF:
1183 case SND_SOC_DAIFMT_IB_NF:
1184 break;
1185 default:
1186 return -EINVAL;
1187 }
1188 break;
1189
1190 case SND_SOC_DAIFMT_RIGHT_J:
1191 break;
1192 case SND_SOC_DAIFMT_LEFT_J:
1193 aif0 |= 1;
1194 break;
1195 case SND_SOC_DAIFMT_I2S:
1196 aif0 |= 2;
1197 break;
1198 default:
1199 return -EINVAL;
1200 }
1201
1202 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1203 case SND_SOC_DAIFMT_NB_NF:
1204 break;
1205 case SND_SOC_DAIFMT_IB_NF:
1206 aif0 |= WM8962_BCLK_INV;
1207 break;
1208 case SND_SOC_DAIFMT_NB_IF:
1209 aif0 |= WM8962_LRCLK_INV;
1210 break;
1211 case SND_SOC_DAIFMT_IB_IF:
1212 aif0 |= WM8962_BCLK_INV | WM8962_LRCLK_INV;
1213 break;
1214 default:
1215 return -EINVAL;
1216 }
1217
1218 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1219 case SND_SOC_DAIFMT_CBM_CFM:
1220 aif0 |= WM8962_MSTR;
1221 break;
1222 case SND_SOC_DAIFMT_CBS_CFS:
1223 break;
1224 default:
1225 return -EINVAL;
1226 }
1227
1228 snd_soc_update_bits(codec, WM8962_AUDIO_INTERFACE_0,
1229 WM8962_FMT_MASK | WM8962_BCLK_INV | WM8962_MSTR |
1230 WM8962_LRCLK_INV, aif0);
1231
1232 return 0;
1233}
1234
1235struct _fll_div {
1236 u16 fll_fratio;
1237 u16 fll_outdiv;
1238 u16 fll_refclk_div;
1239 u16 n;
1240 u16 theta;
1241 u16 lambda;
1242};
1243
1244/* The size in bits of the FLL divide multiplied by 10
1245 * to allow rounding later */
1246#define FIXED_FLL_SIZE ((1 << 16) * 10)
1247
1248static struct {
1249 unsigned int min;
1250 unsigned int max;
1251 u16 fll_fratio;
1252 int ratio;
1253} fll_fratios[] = {
1254 { 0, 64000, 4, 16 },
1255 { 64000, 128000, 3, 8 },
1256 { 128000, 256000, 2, 4 },
1257 { 256000, 1000000, 1, 2 },
1258 { 1000000, 13500000, 0, 1 },
1259};
1260
1261static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1262 unsigned int Fout)
1263{
1264 unsigned int target;
1265 unsigned int div;
1266 unsigned int fratio, gcd_fll;
1267 int i;
1268
1269 /* Fref must be <=13.5MHz */
1270 div = 1;
1271 fll_div->fll_refclk_div = 0;
1272 while ((Fref / div) > 13500000) {
1273 div *= 2;
1274 fll_div->fll_refclk_div++;
1275
1276 if (div > 4) {
1277 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1278 Fref);
1279 return -EINVAL;
1280 }
1281 }
1282
1283 pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
1284
1285 /* Apply the division for our remaining calculations */
1286 Fref /= div;
1287
1288 /* Fvco should be 90-100MHz; don't check the upper bound */
1289 div = 2;
1290 while (Fout * div < 90000000) {
1291 div++;
1292 if (div > 64) {
1293 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1294 Fout);
1295 return -EINVAL;
1296 }
1297 }
1298 target = Fout * div;
1299 fll_div->fll_outdiv = div - 1;
1300
1301 pr_debug("FLL Fvco=%dHz\n", target);
1302
1303 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1304 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1305 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1306 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1307 fratio = fll_fratios[i].ratio;
1308 break;
1309 }
1310 }
1311 if (i == ARRAY_SIZE(fll_fratios)) {
1312 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1313 return -EINVAL;
1314 }
1315
1316 fll_div->n = target / (fratio * Fref);
1317
1318 if (target % Fref == 0) {
1319 fll_div->theta = 0;
1320 fll_div->lambda = 0;
1321 } else {
1322 gcd_fll = gcd(target, fratio * Fref);
1323
1324 fll_div->theta = (target - (fll_div->n * fratio * Fref))
1325 / gcd_fll;
1326 fll_div->lambda = (fratio * Fref) / gcd_fll;
1327 }
1328
1329 pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
1330 fll_div->n, fll_div->theta, fll_div->lambda);
1331 pr_debug("FLL_FRATIO=%x FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
1332 fll_div->fll_fratio, fll_div->fll_outdiv,
1333 fll_div->fll_refclk_div);
1334
1335 return 0;
1336}
1337
1338static int wm8962_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
1339 unsigned int Fref, unsigned int Fout)
1340{
1341 struct snd_soc_codec *codec = dai->codec;
1342 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
1343 struct _fll_div fll_div;
1344 int ret;
1345 int fll1 = snd_soc_read(codec, WM8962_FLL_CONTROL_1);
1346
1347 /* Any change? */
1348 if (source == wm8962->fll_src && Fref == wm8962->fll_fref &&
1349 Fout == wm8962->fll_fout)
1350 return 0;
1351
1352 if (Fout == 0) {
1353 dev_dbg(codec->dev, "FLL disabled\n");
1354
1355 wm8962->fll_fref = 0;
1356 wm8962->fll_fout = 0;
1357
1358 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
1359 WM8962_FLL_ENA, 0);
1360
1361 return 0;
1362 }
1363
1364 ret = fll_factors(&fll_div, Fref, Fout);
1365 if (ret != 0)
1366 return ret;
1367
1368 switch (fll_id) {
1369 case WM8962_FLL_MCLK:
1370 case WM8962_FLL_BCLK:
1371 case WM8962_FLL_OSC:
1372 fll1 |= (fll_id - 1) << WM8962_FLL_REFCLK_SRC_SHIFT;
1373 break;
1374 case WM8962_FLL_INT:
1375 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
1376 WM8962_FLL_OSC_ENA, WM8962_FLL_OSC_ENA);
1377 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_5,
1378 WM8962_FLL_FRC_NCO, WM8962_FLL_FRC_NCO);
1379 break;
1380 default:
1381 dev_err(codec->dev, "Unknown FLL source %d\n", ret);
1382 return -EINVAL;
1383 }
1384
1385 if (fll_div.theta || fll_div.lambda)
1386 fll1 |= WM8962_FLL_FRAC;
1387
1388 /* Stop the FLL while we reconfigure */
1389 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1, WM8962_FLL_ENA, 0);
1390
1391 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_2,
1392 WM8962_FLL_OUTDIV_MASK |
1393 WM8962_FLL_REFCLK_DIV_MASK,
1394 (fll_div.fll_outdiv << WM8962_FLL_OUTDIV_SHIFT) |
1395 (fll_div.fll_refclk_div));
1396
1397 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_3,
1398 WM8962_FLL_FRATIO_MASK, fll_div.fll_fratio);
1399
1400 snd_soc_write(codec, WM8962_FLL_CONTROL_6, fll_div.theta);
1401 snd_soc_write(codec, WM8962_FLL_CONTROL_7, fll_div.lambda);
1402 snd_soc_write(codec, WM8962_FLL_CONTROL_8, fll_div.n);
1403
1404 snd_soc_update_bits(codec, WM8962_FLL_CONTROL_1,
1405 WM8962_FLL_FRAC | WM8962_FLL_REFCLK_SRC_MASK |
1406 WM8962_FLL_ENA, fll1);
1407
1408 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
1409
1410 wm8962->fll_fref = Fref;
1411 wm8962->fll_fout = Fout;
1412 wm8962->fll_src = source;
1413
1414 return 0;
1415}
1416
1417static int wm8962_mute(struct snd_soc_dai *dai, int mute)
1418{
1419 struct snd_soc_codec *codec = dai->codec;
1420 int val;
1421
1422 if (mute)
1423 val = WM8962_DAC_MUTE;
1424 else
1425 val = 0;
1426
1427 return snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1,
1428 WM8962_DAC_MUTE, val);
1429}
1430
1431#define WM8962_RATES SNDRV_PCM_RATE_8000_96000
1432
1433#define WM8962_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1434 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1435
1436static struct snd_soc_dai_ops wm8962_dai_ops = {
1437 .hw_params = wm8962_hw_params,
1438 .set_sysclk = wm8962_set_dai_sysclk,
1439 .set_fmt = wm8962_set_dai_fmt,
1440 .set_pll = wm8962_set_fll,
1441 .digital_mute = wm8962_mute,
1442};
1443
1444struct snd_soc_dai wm8962_dai = {
1445 .name = "WM8962",
1446 .playback = {
1447 .stream_name = "Playback",
1448 .channels_min = 2,
1449 .channels_max = 2,
1450 .rates = WM8962_RATES,
1451 .formats = WM8962_FORMATS,
1452 },
1453 .capture = {
1454 .stream_name = "Capture",
1455 .channels_min = 2,
1456 .channels_max = 2,
1457 .rates = WM8962_RATES,
1458 .formats = WM8962_FORMATS,
1459 },
1460 .ops = &wm8962_dai_ops,
1461 .symmetric_rates = 1,
1462};
1463EXPORT_SYMBOL_GPL(wm8962_dai);
1464
1465static int wm8962_probe(struct platform_device *pdev)
1466{
1467 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1468 struct snd_soc_codec *codec;
1469 int ret = 0;
1470
1471 if (wm8962_codec == NULL) {
1472 dev_err(&pdev->dev, "Codec device not registered\n");
1473 return -ENODEV;
1474 }
1475
1476 socdev->card->codec = wm8962_codec;
1477 codec = wm8962_codec;
1478
1479 /* register pcms */
1480 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1481 if (ret < 0) {
1482 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
1483 goto pcm_err;
1484 }
1485
1486 wm8962_add_widgets(codec);
1487
1488 return ret;
1489
1490pcm_err:
1491 return ret;
1492}
1493
1494static int wm8962_remove(struct platform_device *pdev)
1495{
1496 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1497
1498 snd_soc_free_pcms(socdev);
1499 snd_soc_dapm_free(socdev);
1500
1501 return 0;
1502}
1503
1504#ifdef CONFIG_PM
1505static int wm8962_resume(struct platform_device *pdev)
1506{
1507 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1508 struct snd_soc_codec *codec = socdev->card->codec;
1509 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
1510 u16 *reg_cache = codec->reg_cache;
1511 int i;
1512
1513 /* Restore the registers */
1514 for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) {
1515 switch (i) {
1516 case WM8962_SOFTWARE_RESET:
1517 continue;
1518 default:
1519 break;
1520 }
1521
1522 if (reg_cache[i] != wm8962_reg[i])
1523 snd_soc_write(codec, i, reg_cache[i]);
1524 }
1525
1526 return 0;
1527}
1528#else
1529#define wm8962_resume NULL
1530#endif
1531
1532struct snd_soc_codec_device soc_codec_dev_wm8962 = {
1533 .probe = wm8962_probe,
1534 .remove = wm8962_remove,
1535 .resume = wm8962_resume,
1536};
1537EXPORT_SYMBOL_GPL(soc_codec_dev_wm8962);
1538
1539#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1540static int beep_rates[] = {
1541 500, 1000, 2000, 4000,
1542};
1543
1544static void wm8962_beep_work(struct work_struct *work)
1545{
1546 struct wm8962_priv *wm8962 =
1547 container_of(work, struct wm8962_priv, beep_work);
1548 struct snd_soc_codec *codec = &wm8962->codec;
1549 int i;
1550 int reg = 0;
1551 int best = 0;
1552
1553 if (wm8962->beep_rate) {
1554 for (i = 0; i < ARRAY_SIZE(beep_rates); i++) {
1555 if (abs(wm8962->beep_rate - beep_rates[i]) <
1556 abs(wm8962->beep_rate - beep_rates[best]))
1557 best = i;
1558 }
1559
1560 dev_dbg(codec->dev, "Set beep rate %dHz for requested %dHz\n",
1561 beep_rates[best], wm8962->beep_rate);
1562
1563 reg = WM8962_BEEP_ENA | (best << WM8962_BEEP_RATE_SHIFT);
1564
1565 snd_soc_dapm_enable_pin(codec, "Beep");
1566 } else {
1567 dev_dbg(codec->dev, "Disabling beep\n");
1568 snd_soc_dapm_disable_pin(codec, "Beep");
1569 }
1570
1571 snd_soc_update_bits(codec, WM8962_BEEP_GENERATOR_1,
1572 WM8962_BEEP_ENA | WM8962_BEEP_RATE_MASK, reg);
1573
1574 snd_soc_dapm_sync(codec);
1575}
1576
1577/* For usability define a way of injecting beep events for the device -
1578 * many systems will not have a keyboard.
1579 */
1580static int wm8962_beep_event(struct input_dev *dev, unsigned int type,
1581 unsigned int code, int hz)
1582{
1583 struct snd_soc_codec *codec = input_get_drvdata(dev);
1584 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
1585
1586 dev_dbg(codec->dev, "Beep event %x %x\n", code, hz);
1587
1588 switch (code) {
1589 case SND_BELL:
1590 if (hz)
1591 hz = 1000;
1592 case SND_TONE:
1593 break;
1594 default:
1595 return -1;
1596 }
1597
1598 /* Kick the beep from a workqueue */
1599 wm8962->beep_rate = hz;
1600 schedule_work(&wm8962->beep_work);
1601 return 0;
1602}
1603
1604static ssize_t wm8962_beep_set(struct device *dev,
1605 struct device_attribute *attr,
1606 const char *buf, size_t count)
1607{
1608 struct wm8962_priv *wm8962 = dev_get_drvdata(dev);
1609 long int time;
1610
1611 strict_strtol(buf, 10, &time);
1612
1613 input_event(wm8962->beep, EV_SND, SND_TONE, time);
1614
1615 return count;
1616}
1617
1618static DEVICE_ATTR(beep, 0200, NULL, wm8962_beep_set);
1619
1620static void wm8962_init_beep(struct snd_soc_codec *codec)
1621{
1622 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
1623 int ret;
1624
1625 wm8962->beep = input_allocate_device();
1626 if (!wm8962->beep) {
1627 dev_err(codec->dev, "Failed to allocate beep device\n");
1628 return;
1629 }
1630
1631 INIT_WORK(&wm8962->beep_work, wm8962_beep_work);
1632 wm8962->beep_rate = 0;
1633
1634 wm8962->beep->name = "WM8962 Beep Generator";
1635 wm8962->beep->phys = dev_name(codec->dev);
1636 wm8962->beep->id.bustype = BUS_I2C;
1637
1638 wm8962->beep->evbit[0] = BIT_MASK(EV_SND);
1639 wm8962->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
1640 wm8962->beep->event = wm8962_beep_event;
1641 wm8962->beep->dev.parent = codec->dev;
1642 input_set_drvdata(wm8962->beep, codec);
1643
1644 ret = input_register_device(wm8962->beep);
1645 if (ret != 0) {
1646 input_free_device(wm8962->beep);
1647 wm8962->beep = NULL;
1648 dev_err(codec->dev, "Failed to register beep device\n");
1649 }
1650
1651 ret = device_create_file(codec->dev, &dev_attr_beep);
1652 if (ret != 0) {
1653 dev_err(codec->dev, "Failed to create keyclick file: %d\n",
1654 ret);
1655 }
1656}
1657
1658static void wm8962_free_beep(struct snd_soc_codec *codec)
1659{
1660 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
1661
1662 device_remove_file(codec->dev, &dev_attr_beep);
1663 input_unregister_device(wm8962->beep);
1664 cancel_work_sync(&wm8962->beep_work);
1665 wm8962->beep = NULL;
1666
1667 snd_soc_update_bits(codec, WM8962_BEEP_GENERATOR_1, WM8962_BEEP_ENA,0);
1668}
1669#else
1670static void wm8962_init_beep(struct snd_soc_codec *codec)
1671{
1672}
1673
1674static void wm8962_free_beep(struct snd_soc_codec *codec)
1675{
1676}
1677#endif
1678
1679static int wm8962_register(struct wm8962_priv *wm8962,
1680 enum snd_soc_control_type control)
1681{
1682 int ret;
1683 struct snd_soc_codec *codec = &wm8962->codec;
1684 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
1685 int i;
1686
1687 if (wm8962_codec) {
1688 dev_err(codec->dev, "Another WM8962 is registered\n");
1689 return -EINVAL;
1690 }
1691
1692 mutex_init(&codec->mutex);
1693 INIT_LIST_HEAD(&codec->dapm_widgets);
1694 INIT_LIST_HEAD(&codec->dapm_paths);
1695
1696 snd_soc_codec_set_drvdata(codec, wm8962);
1697 codec->name = "WM8962";
1698 codec->owner = THIS_MODULE;
1699 codec->bias_level = SND_SOC_BIAS_OFF;
1700 codec->set_bias_level = wm8962_set_bias_level;
1701 codec->dai = &wm8962_dai;
1702 codec->num_dai = 1;
1703 codec->reg_cache_size = WM8962_MAX_REGISTER;
1704 codec->reg_cache = &wm8962->reg_cache;
1705 codec->volatile_register = wm8962_volatile_register;
1706 codec->cache_sync = 1;
1707 codec->idle_bias_off = 1;
1708 codec->readable_register = wm8962_readable;
1709
1710 memcpy(codec->reg_cache, wm8962_reg, sizeof(wm8962_reg));
1711
1712 ret = snd_soc_codec_set_cache_io(codec, 16, 16, control);
1713 if (ret != 0) {
1714 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1715 goto err;
1716 }
1717
1718 for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
1719 wm8962->supplies[i].supply = wm8962_supply_names[i];
1720
1721 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8962->supplies),
1722 wm8962->supplies);
1723 if (ret != 0) {
1724 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1725 goto err;
1726 }
1727
1728 wm8962->disable_nb[0].notifier_call = wm8962_regulator_event_0;
1729 wm8962->disable_nb[1].notifier_call = wm8962_regulator_event_1;
1730 wm8962->disable_nb[2].notifier_call = wm8962_regulator_event_2;
1731 wm8962->disable_nb[3].notifier_call = wm8962_regulator_event_3;
1732 wm8962->disable_nb[4].notifier_call = wm8962_regulator_event_4;
1733 wm8962->disable_nb[5].notifier_call = wm8962_regulator_event_5;
1734 wm8962->disable_nb[6].notifier_call = wm8962_regulator_event_6;
1735 wm8962->disable_nb[7].notifier_call = wm8962_regulator_event_7;
1736
1737 /* This should really be moved into the regulator core */
1738 for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) {
1739 ret = regulator_register_notifier(wm8962->supplies[i].consumer,
1740 &wm8962->disable_nb[i]);
1741 if (ret != 0) {
1742 dev_err(codec->dev,
1743 "Failed to register regulator notifier: %d\n",
1744 ret);
1745 }
1746 }
1747
1748 ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
1749 wm8962->supplies);
1750 if (ret != 0) {
1751 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1752 goto err_get;
1753 }
1754
1755 ret = snd_soc_read(codec, WM8962_SOFTWARE_RESET);
1756 if (ret < 0) {
1757 dev_err(codec->dev, "Failed to read ID register\n");
1758 goto err_enable;
1759 }
1760 if (ret != wm8962_reg[WM8962_SOFTWARE_RESET]) {
1761 dev_err(codec->dev, "Device is not a WM8962, ID %x != %x\n",
1762 ret, wm8962_reg[WM8962_SOFTWARE_RESET]);
1763 ret = -EINVAL;
1764 goto err_enable;
1765 }
1766
1767 ret = snd_soc_read(codec, WM8962_RIGHT_INPUT_VOLUME);
1768 if (ret < 0) {
1769 dev_err(codec->dev, "Failed to read device revision: %d\n",
1770 ret);
1771 goto err_enable;
1772 }
1773
1774 dev_info(codec->dev, "customer id %x revision %c\n",
1775 (ret & WM8962_CUST_ID_MASK) >> WM8962_CUST_ID_SHIFT,
1776 ((ret & WM8962_CHIP_REV_MASK) >> WM8962_CHIP_REV_SHIFT)
1777 + 'A');
1778
1779 ret = wm8962_reset(codec);
1780 if (ret < 0) {
1781 dev_err(codec->dev, "Failed to issue reset\n");
1782 goto err_enable;
1783 }
1784
1785 /* SYSCLK defaults to on; make sure it is off so we can safely
1786 * write to registers if the device is declocked.
1787 */
1788 snd_soc_update_bits(codec, WM8962_CLOCKING2, WM8962_SYSCLK_ENA, 0);
1789
1790 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
1791
1792 if (pdata) {
1793 /* Apply static configuration for GPIOs */
1794 for (i = 0; i < ARRAY_SIZE(pdata->gpio_init); i++)
1795 if (pdata->gpio_init[i])
1796 snd_soc_write(codec, 0x200 + i,
1797 pdata->gpio_init[i] & 0xffff);
1798
1799 /* Put the speakers into mono mode? */
1800 if (pdata->spk_mono)
1801 wm8962->reg_cache[WM8962_CLASS_D_CONTROL_2]
1802 |= WM8962_SPK_MONO;
1803 }
1804
1805 /* Latch volume update bits */
1806 wm8962->reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU;
1807 wm8962->reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU;
1808 wm8962->reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU;
1809 wm8962->reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU;
1810 wm8962->reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU;
1811 wm8962->reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU;
1812 wm8962->reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU;
1813 wm8962->reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU;
1814 wm8962->reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU;
1815 wm8962->reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU;
1816
1817 wm8962_dai.dev = codec->dev;
1818
1819 wm8962_codec = codec;
1820
1821 ret = snd_soc_register_codec(codec);
1822 if (ret != 0) {
1823 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1824 return ret;
1825 }
1826
1827 ret = snd_soc_register_dai(&wm8962_dai);
1828 if (ret != 0) {
1829 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1830 snd_soc_unregister_codec(codec);
1831 return ret;
1832 }
1833
1834 wm8962_init_beep(codec);
1835
1836 return 0;
1837
1838err_enable:
1839 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
1840err_get:
1841 regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
1842err:
1843 kfree(wm8962);
1844 return ret;
1845}
1846
1847static void wm8962_unregister(struct wm8962_priv *wm8962)
1848{
1849 int i;
1850
1851 wm8962_free_beep(&wm8962->codec);
1852 wm8962_set_bias_level(&wm8962->codec, SND_SOC_BIAS_OFF);
1853 for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++)
1854 regulator_unregister_notifier(wm8962->supplies[i].consumer,
1855 &wm8962->disable_nb[i]);
1856 regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
1857 snd_soc_unregister_dai(&wm8962_dai);
1858 snd_soc_unregister_codec(&wm8962->codec);
1859 kfree(wm8962);
1860 wm8962_codec = NULL;
1861}
1862
1863#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1864static __devinit int wm8962_i2c_probe(struct i2c_client *i2c,
1865 const struct i2c_device_id *id)
1866{
1867 struct wm8962_priv *wm8962;
1868 struct snd_soc_codec *codec;
1869
1870 wm8962 = kzalloc(sizeof(struct wm8962_priv), GFP_KERNEL);
1871 if (wm8962 == NULL)
1872 return -ENOMEM;
1873
1874 codec = &wm8962->codec;
1875 codec->hw_write = (hw_write_t)i2c_master_send;
1876
1877 i2c_set_clientdata(i2c, wm8962);
1878 codec->control_data = i2c;
1879
1880 codec->dev = &i2c->dev;
1881
1882 return wm8962_register(wm8962, SND_SOC_I2C);
1883}
1884
1885static __devexit int wm8962_i2c_remove(struct i2c_client *client)
1886{
1887 struct wm8962_priv *wm8962 = i2c_get_clientdata(client);
1888 wm8962_unregister(wm8962);
1889 return 0;
1890}
1891
1892static const struct i2c_device_id wm8962_i2c_id[] = {
1893 { "wm8962", 0 },
1894 { }
1895};
1896MODULE_DEVICE_TABLE(i2c, wm8962_i2c_id);
1897
1898static struct i2c_driver wm8962_i2c_driver = {
1899 .driver = {
1900 .name = "WM8962",
1901 .owner = THIS_MODULE,
1902 },
1903 .probe = wm8962_i2c_probe,
1904 .remove = __devexit_p(wm8962_i2c_remove),
1905 .id_table = wm8962_i2c_id,
1906};
1907#endif
1908
1909static int __init wm8962_modinit(void)
1910{
1911 int ret;
1912#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1913 ret = i2c_add_driver(&wm8962_i2c_driver);
1914 if (ret != 0) {
1915 printk(KERN_ERR "Failed to register WM8962 I2C driver: %d\n",
1916 ret);
1917 }
1918#endif
1919 return 0;
1920}
1921module_init(wm8962_modinit);
1922
1923static void __exit wm8962_exit(void)
1924{
1925#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1926 i2c_del_driver(&wm8962_i2c_driver);
1927#endif
1928}
1929module_exit(wm8962_exit);
1930
1931MODULE_DESCRIPTION("ASoC WM8962 driver");
1932MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1933MODULE_LICENSE("GPL");