ASoC: Add another DAPM stat for neighbour checks
[deliverable/linux.git] / sound / soc / codecs / wm5100.c
CommitLineData
6d4baf08
MB
1/*
2 * wm5100.c -- WM5100 ALSA SoC Audio driver
3 *
4 * Copyright 2011 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/gcd.h>
19#include <linux/gpio.h>
20#include <linux/i2c.h>
21#include <linux/platform_device.h>
22#include <linux/regulator/consumer.h>
23#include <linux/regulator/fixed.h>
24#include <linux/slab.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#include <sound/tlv.h>
31#include <sound/wm5100.h>
32
33#include "wm5100.h"
34
35#define WM5100_NUM_CORE_SUPPLIES 2
36static const char *wm5100_core_supply_names[WM5100_NUM_CORE_SUPPLIES] = {
37 "DBVDD1",
38 "LDOVDD", /* If DCVDD is supplied externally specify as LDOVDD */
39};
40
41#define WM5100_AIFS 3
42#define WM5100_SYNC_SRS 3
43
44struct wm5100_fll {
45 int fref;
46 int fout;
47 int src;
48 struct completion lock;
49};
50
51/* codec private data */
52struct wm5100_priv {
53 struct snd_soc_codec *codec;
54
55 struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES];
56 struct regulator *cpvdd;
7aefb086
MB
57 struct regulator *dbvdd2;
58 struct regulator *dbvdd3;
6d4baf08
MB
59
60 int rev;
61
62 int sysclk;
63 int asyncclk;
64
65 bool aif_async[WM5100_AIFS];
66 bool aif_symmetric[WM5100_AIFS];
67 int sr_ref[WM5100_SYNC_SRS];
68
69 bool out_ena[2];
70
71 struct wm5100_fll fll[2];
72
73 struct wm5100_pdata pdata;
74
75#ifdef CONFIG_GPIOLIB
76 struct gpio_chip gpio_chip;
77#endif
78};
79
80static int wm5100_sr_code[] = {
81 0,
82 12000,
83 24000,
84 48000,
85 96000,
86 192000,
87 384000,
88 768000,
89 0,
90 11025,
91 22050,
92 44100,
93 88200,
94 176400,
95 352800,
96 705600,
97 4000,
98 8000,
99 16000,
100 32000,
101 64000,
102 128000,
103 256000,
104 512000,
105};
106
107static int wm5100_sr_regs[WM5100_SYNC_SRS] = {
108 WM5100_CLOCKING_4,
109 WM5100_CLOCKING_5,
110 WM5100_CLOCKING_6,
111};
112
113static int wm5100_alloc_sr(struct snd_soc_codec *codec, int rate)
114{
115 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
116 int sr_code, sr_free, i;
117
118 for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
119 if (wm5100_sr_code[i] == rate)
120 break;
121 if (i == ARRAY_SIZE(wm5100_sr_code)) {
122 dev_err(codec->dev, "Unsupported sample rate: %dHz\n", rate);
123 return -EINVAL;
124 }
125 sr_code = i;
126
127 if ((wm5100->sysclk % rate) == 0) {
128 /* Is this rate already in use? */
129 sr_free = -1;
130 for (i = 0; i < ARRAY_SIZE(wm5100_sr_regs); i++) {
131 if (!wm5100->sr_ref[i] && sr_free == -1) {
132 sr_free = i;
133 continue;
134 }
135 if ((snd_soc_read(codec, wm5100_sr_regs[i]) &
136 WM5100_SAMPLE_RATE_1_MASK) == sr_code)
137 break;
138 }
139
140 if (i < ARRAY_SIZE(wm5100_sr_regs)) {
141 wm5100->sr_ref[i]++;
142 dev_dbg(codec->dev, "SR %dHz, slot %d, ref %d\n",
143 rate, i, wm5100->sr_ref[i]);
144 return i;
145 }
146
147 if (sr_free == -1) {
148 dev_err(codec->dev, "All SR slots already in use\n");
149 return -EBUSY;
150 }
151
152 dev_dbg(codec->dev, "Allocating SR slot %d for %dHz\n",
153 sr_free, rate);
154 wm5100->sr_ref[sr_free]++;
155 snd_soc_update_bits(codec, wm5100_sr_regs[sr_free],
156 WM5100_SAMPLE_RATE_1_MASK,
157 sr_code);
158
159 return sr_free;
160
161 } else {
162 dev_err(codec->dev,
163 "SR %dHz incompatible with %dHz SYSCLK and %dHz ASYNCCLK\n",
164 rate, wm5100->sysclk, wm5100->asyncclk);
165 return -EINVAL;
166 }
167}
168
169static void wm5100_free_sr(struct snd_soc_codec *codec, int rate)
170{
171 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
172 int i, sr_code;
173
174 for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
175 if (wm5100_sr_code[i] == rate)
176 break;
177 if (i == ARRAY_SIZE(wm5100_sr_code)) {
178 dev_err(codec->dev, "Unsupported sample rate: %dHz\n", rate);
179 return;
180 }
181 sr_code = wm5100_sr_code[i];
182
183 for (i = 0; i < ARRAY_SIZE(wm5100_sr_regs); i++) {
184 if (!wm5100->sr_ref[i])
185 continue;
186
187 if ((snd_soc_read(codec, wm5100_sr_regs[i]) &
188 WM5100_SAMPLE_RATE_1_MASK) == sr_code)
189 break;
190 }
191 if (i < ARRAY_SIZE(wm5100_sr_regs)) {
192 wm5100->sr_ref[i]--;
193 dev_dbg(codec->dev, "Dereference SR %dHz, count now %d\n",
194 rate, wm5100->sr_ref[i]);
195 } else {
196 dev_warn(codec->dev, "Freeing unreferenced sample rate %dHz\n",
197 rate);
198 }
199}
200
201static int wm5100_reset(struct snd_soc_codec *codec)
202{
203 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
204
205 if (wm5100->pdata.reset) {
206 gpio_set_value_cansleep(wm5100->pdata.reset, 0);
207 gpio_set_value_cansleep(wm5100->pdata.reset, 1);
208
209 return 0;
210 } else {
211 return snd_soc_write(codec, WM5100_SOFTWARE_RESET, 0);
212 }
213}
214
215static DECLARE_TLV_DB_SCALE(in_tlv, -6300, 100, 0);
216static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
217static DECLARE_TLV_DB_SCALE(mixer_tlv, -3200, 100, 0);
218static DECLARE_TLV_DB_SCALE(out_tlv, -6400, 100, 0);
219static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
220
221static const char *wm5100_mixer_texts[] = {
222 "None",
223 "Tone Generator 1",
224 "Tone Generator 2",
225 "AEC loopback",
226 "IN1L",
227 "IN1R",
228 "IN2L",
229 "IN2R",
230 "IN3L",
231 "IN3R",
232 "IN4L",
233 "IN4R",
234 "AIF1RX1",
235 "AIF1RX2",
236 "AIF1RX3",
237 "AIF1RX4",
238 "AIF1RX5",
239 "AIF1RX6",
240 "AIF1RX7",
241 "AIF1RX8",
242 "AIF2RX1",
243 "AIF2RX2",
244 "AIF3RX1",
245 "AIF3RX2",
246 "EQ1",
247 "EQ2",
248 "EQ3",
249 "EQ4",
250 "DRC1L",
251 "DRC1R",
252 "LHPF1",
253 "LHPF2",
254 "LHPF3",
255 "LHPF4",
256 "DSP1.1",
257 "DSP1.2",
258 "DSP1.3",
259 "DSP1.4",
260 "DSP1.5",
261 "DSP1.6",
262 "DSP2.1",
263 "DSP2.2",
264 "DSP2.3",
265 "DSP2.4",
266 "DSP2.5",
267 "DSP2.6",
268 "DSP3.1",
269 "DSP3.2",
270 "DSP3.3",
271 "DSP3.4",
272 "DSP3.5",
273 "DSP3.6",
274 "ASRC1L",
275 "ASRC1R",
276 "ASRC2L",
277 "ASRC2R",
278 "ISRC1INT1",
279 "ISRC1INT2",
280 "ISRC1INT3",
281 "ISRC1INT4",
282 "ISRC2INT1",
283 "ISRC2INT2",
284 "ISRC2INT3",
285 "ISRC2INT4",
286 "ISRC1DEC1",
287 "ISRC1DEC2",
288 "ISRC1DEC3",
289 "ISRC1DEC4",
290 "ISRC2DEC1",
291 "ISRC2DEC2",
292 "ISRC2DEC3",
293 "ISRC2DEC4",
294};
295
296static int wm5100_mixer_values[] = {
297 0x00,
298 0x04, /* Tone */
299 0x05,
300 0x08, /* AEC */
301 0x10, /* Input */
302 0x11,
303 0x12,
304 0x13,
305 0x14,
306 0x15,
307 0x16,
308 0x17,
309 0x20, /* AIF */
310 0x21,
311 0x22,
312 0x23,
313 0x24,
314 0x25,
315 0x26,
316 0x27,
317 0x28,
318 0x29,
319 0x30, /* AIF3 - check */
320 0x31,
321 0x50, /* EQ */
322 0x51,
323 0x52,
324 0x53,
325 0x54,
326 0x58, /* DRC */
327 0x59,
328 0x60, /* LHPF1 */
329 0x61, /* LHPF2 */
330 0x62, /* LHPF3 */
331 0x63, /* LHPF4 */
332 0x68, /* DSP1 */
333 0x69,
334 0x6a,
335 0x6b,
336 0x6c,
337 0x6d,
338 0x70, /* DSP2 */
339 0x71,
340 0x72,
341 0x73,
342 0x74,
343 0x75,
344 0x78, /* DSP3 */
345 0x79,
346 0x7a,
347 0x7b,
348 0x7c,
349 0x7d,
350 0x90, /* ASRC1 */
351 0x91,
352 0x92, /* ASRC2 */
353 0x93,
354 0xa0, /* ISRC1DEC1 */
355 0xa1,
356 0xa2,
357 0xa3,
358 0xa4, /* ISRC1INT1 */
359 0xa5,
360 0xa6,
361 0xa7,
362 0xa8, /* ISRC2DEC1 */
363 0xa9,
364 0xaa,
365 0xab,
366 0xac, /* ISRC2INT1 */
367 0xad,
368 0xae,
369 0xaf,
370};
371
372#define WM5100_MIXER_CONTROLS(name, base) \
373 SOC_SINGLE_TLV(name " Input 1 Volume", base + 1 , \
374 WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
375 SOC_SINGLE_TLV(name " Input 2 Volume", base + 3 , \
376 WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
377 SOC_SINGLE_TLV(name " Input 3 Volume", base + 5 , \
378 WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
379 SOC_SINGLE_TLV(name " Input 4 Volume", base + 7 , \
380 WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv)
381
382#define WM5100_MUX_ENUM_DECL(name, reg) \
383 SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, \
384 wm5100_mixer_texts, wm5100_mixer_values)
385
386#define WM5100_MUX_CTL_DECL(name) \
387 const struct snd_kcontrol_new name##_mux = \
388 SOC_DAPM_VALUE_ENUM("Route", name##_enum)
389
390#define WM5100_MIXER_ENUMS(name, base_reg) \
391 static WM5100_MUX_ENUM_DECL(name##_in1_enum, base_reg); \
392 static WM5100_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \
393 static WM5100_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \
394 static WM5100_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \
395 static WM5100_MUX_CTL_DECL(name##_in1); \
396 static WM5100_MUX_CTL_DECL(name##_in2); \
397 static WM5100_MUX_CTL_DECL(name##_in3); \
398 static WM5100_MUX_CTL_DECL(name##_in4)
399
400WM5100_MIXER_ENUMS(HPOUT1L, WM5100_OUT1LMIX_INPUT_1_SOURCE);
401WM5100_MIXER_ENUMS(HPOUT1R, WM5100_OUT1RMIX_INPUT_1_SOURCE);
402WM5100_MIXER_ENUMS(HPOUT2L, WM5100_OUT2LMIX_INPUT_1_SOURCE);
403WM5100_MIXER_ENUMS(HPOUT2R, WM5100_OUT2RMIX_INPUT_1_SOURCE);
404WM5100_MIXER_ENUMS(HPOUT3L, WM5100_OUT3LMIX_INPUT_1_SOURCE);
405WM5100_MIXER_ENUMS(HPOUT3R, WM5100_OUT3RMIX_INPUT_1_SOURCE);
406
407WM5100_MIXER_ENUMS(SPKOUTL, WM5100_OUT4LMIX_INPUT_1_SOURCE);
408WM5100_MIXER_ENUMS(SPKOUTR, WM5100_OUT4RMIX_INPUT_1_SOURCE);
409WM5100_MIXER_ENUMS(SPKDAT1L, WM5100_OUT5LMIX_INPUT_1_SOURCE);
410WM5100_MIXER_ENUMS(SPKDAT1R, WM5100_OUT5RMIX_INPUT_1_SOURCE);
411WM5100_MIXER_ENUMS(SPKDAT2L, WM5100_OUT6LMIX_INPUT_1_SOURCE);
412WM5100_MIXER_ENUMS(SPKDAT2R, WM5100_OUT6RMIX_INPUT_1_SOURCE);
413
414WM5100_MIXER_ENUMS(PWM1, WM5100_PWM1MIX_INPUT_1_SOURCE);
415WM5100_MIXER_ENUMS(PWM2, WM5100_PWM1MIX_INPUT_1_SOURCE);
416
417WM5100_MIXER_ENUMS(AIF1TX1, WM5100_AIF1TX1MIX_INPUT_1_SOURCE);
418WM5100_MIXER_ENUMS(AIF1TX2, WM5100_AIF1TX2MIX_INPUT_1_SOURCE);
419WM5100_MIXER_ENUMS(AIF1TX3, WM5100_AIF1TX3MIX_INPUT_1_SOURCE);
420WM5100_MIXER_ENUMS(AIF1TX4, WM5100_AIF1TX4MIX_INPUT_1_SOURCE);
421WM5100_MIXER_ENUMS(AIF1TX5, WM5100_AIF1TX5MIX_INPUT_1_SOURCE);
422WM5100_MIXER_ENUMS(AIF1TX6, WM5100_AIF1TX6MIX_INPUT_1_SOURCE);
423WM5100_MIXER_ENUMS(AIF1TX7, WM5100_AIF1TX7MIX_INPUT_1_SOURCE);
424WM5100_MIXER_ENUMS(AIF1TX8, WM5100_AIF1TX8MIX_INPUT_1_SOURCE);
425
426WM5100_MIXER_ENUMS(AIF2TX1, WM5100_AIF2TX1MIX_INPUT_1_SOURCE);
427WM5100_MIXER_ENUMS(AIF2TX2, WM5100_AIF2TX2MIX_INPUT_1_SOURCE);
428
429WM5100_MIXER_ENUMS(AIF3TX1, WM5100_AIF1TX1MIX_INPUT_1_SOURCE);
430WM5100_MIXER_ENUMS(AIF3TX2, WM5100_AIF1TX2MIX_INPUT_1_SOURCE);
431
432WM5100_MIXER_ENUMS(EQ1, WM5100_EQ1MIX_INPUT_1_SOURCE);
433WM5100_MIXER_ENUMS(EQ2, WM5100_EQ2MIX_INPUT_1_SOURCE);
434WM5100_MIXER_ENUMS(EQ3, WM5100_EQ3MIX_INPUT_1_SOURCE);
435WM5100_MIXER_ENUMS(EQ4, WM5100_EQ4MIX_INPUT_1_SOURCE);
436
437WM5100_MIXER_ENUMS(DRC1L, WM5100_DRC1LMIX_INPUT_1_SOURCE);
438WM5100_MIXER_ENUMS(DRC1R, WM5100_DRC1RMIX_INPUT_1_SOURCE);
439
440WM5100_MIXER_ENUMS(LHPF1, WM5100_HPLP1MIX_INPUT_1_SOURCE);
441WM5100_MIXER_ENUMS(LHPF2, WM5100_HPLP2MIX_INPUT_1_SOURCE);
442WM5100_MIXER_ENUMS(LHPF3, WM5100_HPLP3MIX_INPUT_1_SOURCE);
443WM5100_MIXER_ENUMS(LHPF4, WM5100_HPLP4MIX_INPUT_1_SOURCE);
444
445#define WM5100_MUX(name, ctrl) \
446 SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
447
448#define WM5100_MIXER_WIDGETS(name, name_str) \
449 WM5100_MUX(name_str " Input 1", &name##_in1_mux), \
450 WM5100_MUX(name_str " Input 2", &name##_in2_mux), \
451 WM5100_MUX(name_str " Input 3", &name##_in3_mux), \
452 WM5100_MUX(name_str " Input 4", &name##_in4_mux), \
453 SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
454
455#define WM5100_MIXER_INPUT_ROUTES(name) \
456 { name, "Tone Generator 1", "Tone Generator 1" }, \
457 { name, "Tone Generator 2", "Tone Generator 2" }, \
458 { name, "IN1L", "IN1L PGA" }, \
459 { name, "IN1R", "IN1R PGA" }, \
460 { name, "IN2L", "IN2L PGA" }, \
461 { name, "IN2R", "IN2R PGA" }, \
462 { name, "IN3L", "IN3L PGA" }, \
463 { name, "IN3R", "IN3R PGA" }, \
464 { name, "IN4L", "IN4L PGA" }, \
465 { name, "IN4R", "IN4R PGA" }, \
466 { name, "AIF1RX1", "AIF1RX1" }, \
467 { name, "AIF1RX2", "AIF1RX2" }, \
468 { name, "AIF1RX3", "AIF1RX3" }, \
469 { name, "AIF1RX4", "AIF1RX4" }, \
470 { name, "AIF1RX5", "AIF1RX5" }, \
471 { name, "AIF1RX6", "AIF1RX6" }, \
472 { name, "AIF1RX7", "AIF1RX7" }, \
473 { name, "AIF1RX8", "AIF1RX8" }, \
474 { name, "AIF2RX1", "AIF2RX1" }, \
475 { name, "AIF2RX2", "AIF2RX2" }, \
476 { name, "AIF3RX1", "AIF3RX1" }, \
477 { name, "AIF3RX2", "AIF3RX2" }, \
478 { name, "EQ1", "EQ1" }, \
479 { name, "EQ2", "EQ2" }, \
480 { name, "EQ3", "EQ3" }, \
481 { name, "EQ4", "EQ4" }, \
482 { name, "DRC1L", "DRC1L" }, \
483 { name, "DRC1R", "DRC1R" }, \
484 { name, "LHPF1", "LHPF1" }, \
485 { name, "LHPF2", "LHPF2" }, \
486 { name, "LHPF3", "LHPF3" }, \
487 { name, "LHPF4", "LHPF4" }
488
489#define WM5100_MIXER_ROUTES(widget, name) \
490 { widget, NULL, name " Mixer" }, \
491 { name " Mixer", NULL, name " Input 1" }, \
492 { name " Mixer", NULL, name " Input 2" }, \
493 { name " Mixer", NULL, name " Input 3" }, \
494 { name " Mixer", NULL, name " Input 4" }, \
495 WM5100_MIXER_INPUT_ROUTES(name " Input 1"), \
496 WM5100_MIXER_INPUT_ROUTES(name " Input 2"), \
497 WM5100_MIXER_INPUT_ROUTES(name " Input 3"), \
498 WM5100_MIXER_INPUT_ROUTES(name " Input 4")
499
500static const char *wm5100_lhpf_mode_text[] = {
501 "Low-pass", "High-pass"
502};
503
504static const struct soc_enum wm5100_lhpf1_mode =
505 SOC_ENUM_SINGLE(WM5100_HPLPF1_1, WM5100_LHPF1_MODE_SHIFT, 2,
506 wm5100_lhpf_mode_text);
507
508static const struct soc_enum wm5100_lhpf2_mode =
509 SOC_ENUM_SINGLE(WM5100_HPLPF2_1, WM5100_LHPF2_MODE_SHIFT, 2,
510 wm5100_lhpf_mode_text);
511
512static const struct soc_enum wm5100_lhpf3_mode =
513 SOC_ENUM_SINGLE(WM5100_HPLPF3_1, WM5100_LHPF3_MODE_SHIFT, 2,
514 wm5100_lhpf_mode_text);
515
516static const struct soc_enum wm5100_lhpf4_mode =
517 SOC_ENUM_SINGLE(WM5100_HPLPF4_1, WM5100_LHPF4_MODE_SHIFT, 2,
518 wm5100_lhpf_mode_text);
519
520static const struct snd_kcontrol_new wm5100_snd_controls[] = {
521SOC_SINGLE("IN1 High Performance Switch", WM5100_IN1L_CONTROL,
522 WM5100_IN1_OSR_SHIFT, 1, 0),
523SOC_SINGLE("IN2 High Performance Switch", WM5100_IN2L_CONTROL,
524 WM5100_IN2_OSR_SHIFT, 1, 0),
525SOC_SINGLE("IN3 High Performance Switch", WM5100_IN3L_CONTROL,
526 WM5100_IN3_OSR_SHIFT, 1, 0),
527SOC_SINGLE("IN4 High Performance Switch", WM5100_IN4L_CONTROL,
528 WM5100_IN4_OSR_SHIFT, 1, 0),
529
530/* Only applicable for analogue inputs */
531SOC_DOUBLE_R_TLV("IN1 Volume", WM5100_IN1L_CONTROL, WM5100_IN1R_CONTROL,
532 WM5100_IN1L_PGA_VOL_SHIFT, 94, 0, in_tlv),
533SOC_DOUBLE_R_TLV("IN2 Volume", WM5100_IN2L_CONTROL, WM5100_IN2R_CONTROL,
534 WM5100_IN2L_PGA_VOL_SHIFT, 94, 0, in_tlv),
535SOC_DOUBLE_R_TLV("IN3 Volume", WM5100_IN3L_CONTROL, WM5100_IN3R_CONTROL,
536 WM5100_IN3L_PGA_VOL_SHIFT, 94, 0, in_tlv),
537SOC_DOUBLE_R_TLV("IN4 Volume", WM5100_IN4L_CONTROL, WM5100_IN4R_CONTROL,
538 WM5100_IN4L_PGA_VOL_SHIFT, 94, 0, in_tlv),
539
540SOC_DOUBLE_R_TLV("IN1 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_1L,
541 WM5100_ADC_DIGITAL_VOLUME_1R, WM5100_IN1L_VOL_SHIFT, 191,
542 0, digital_tlv),
543SOC_DOUBLE_R_TLV("IN2 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_2L,
544 WM5100_ADC_DIGITAL_VOLUME_2R, WM5100_IN2L_VOL_SHIFT, 191,
545 0, digital_tlv),
546SOC_DOUBLE_R_TLV("IN3 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_3L,
547 WM5100_ADC_DIGITAL_VOLUME_3R, WM5100_IN3L_VOL_SHIFT, 191,
548 0, digital_tlv),
549SOC_DOUBLE_R_TLV("IN4 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_4L,
550 WM5100_ADC_DIGITAL_VOLUME_4R, WM5100_IN4L_VOL_SHIFT, 191,
551 0, digital_tlv),
552
553SOC_DOUBLE_R("IN1 Switch", WM5100_ADC_DIGITAL_VOLUME_1L,
554 WM5100_ADC_DIGITAL_VOLUME_1R, WM5100_IN1L_MUTE_SHIFT, 1, 1),
555SOC_DOUBLE_R("IN2 Switch", WM5100_ADC_DIGITAL_VOLUME_2L,
556 WM5100_ADC_DIGITAL_VOLUME_2R, WM5100_IN2L_MUTE_SHIFT, 1, 1),
557SOC_DOUBLE_R("IN3 Switch", WM5100_ADC_DIGITAL_VOLUME_3L,
558 WM5100_ADC_DIGITAL_VOLUME_3R, WM5100_IN3L_MUTE_SHIFT, 1, 1),
559SOC_DOUBLE_R("IN4 Switch", WM5100_ADC_DIGITAL_VOLUME_4L,
560 WM5100_ADC_DIGITAL_VOLUME_4R, WM5100_IN4L_MUTE_SHIFT, 1, 1),
561
562SOC_SINGLE("HPOUT1 High Performance Switch", WM5100_OUT_VOLUME_1L,
563 WM5100_OUT1_OSR_SHIFT, 1, 0),
564SOC_SINGLE("HPOUT2 High Performance Switch", WM5100_OUT_VOLUME_2L,
565 WM5100_OUT2_OSR_SHIFT, 1, 0),
566SOC_SINGLE("HPOUT3 High Performance Switch", WM5100_OUT_VOLUME_3L,
567 WM5100_OUT3_OSR_SHIFT, 1, 0),
568SOC_SINGLE("SPKOUT High Performance Switch", WM5100_OUT_VOLUME_4L,
569 WM5100_OUT4_OSR_SHIFT, 1, 0),
570SOC_SINGLE("SPKDAT1 High Performance Switch", WM5100_DAC_VOLUME_LIMIT_5L,
571 WM5100_OUT5_OSR_SHIFT, 1, 0),
572SOC_SINGLE("SPKDAT2 High Performance Switch", WM5100_DAC_VOLUME_LIMIT_6L,
573 WM5100_OUT6_OSR_SHIFT, 1, 0),
574
575SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_1L,
576 WM5100_DAC_DIGITAL_VOLUME_1R, WM5100_OUT1L_VOL_SHIFT, 159, 0,
577 digital_tlv),
578SOC_DOUBLE_R_TLV("HPOUT2 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_2L,
579 WM5100_DAC_DIGITAL_VOLUME_2R, WM5100_OUT2L_VOL_SHIFT, 159, 0,
580 digital_tlv),
581SOC_DOUBLE_R_TLV("HPOUT3 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_3L,
582 WM5100_DAC_DIGITAL_VOLUME_3R, WM5100_OUT3L_VOL_SHIFT, 159, 0,
583 digital_tlv),
584SOC_DOUBLE_R_TLV("SPKOUT Digital Volume", WM5100_DAC_DIGITAL_VOLUME_4L,
585 WM5100_DAC_DIGITAL_VOLUME_4R, WM5100_OUT4L_VOL_SHIFT, 159, 0,
586 digital_tlv),
587SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_5L,
588 WM5100_DAC_DIGITAL_VOLUME_5R, WM5100_OUT5L_VOL_SHIFT, 159, 0,
589 digital_tlv),
590SOC_DOUBLE_R_TLV("SPKDAT2 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_6L,
591 WM5100_DAC_DIGITAL_VOLUME_6R, WM5100_OUT6L_VOL_SHIFT, 159, 0,
592 digital_tlv),
593
594SOC_DOUBLE_R("HPOUT1 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_1L,
595 WM5100_DAC_DIGITAL_VOLUME_1R, WM5100_OUT1L_MUTE_SHIFT, 1, 1),
596SOC_DOUBLE_R("HPOUT2 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_2L,
597 WM5100_DAC_DIGITAL_VOLUME_2R, WM5100_OUT2L_MUTE_SHIFT, 1, 1),
598SOC_DOUBLE_R("HPOUT3 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_3L,
599 WM5100_DAC_DIGITAL_VOLUME_3R, WM5100_OUT3L_MUTE_SHIFT, 1, 1),
600SOC_DOUBLE_R("SPKOUT Digital Switch", WM5100_DAC_DIGITAL_VOLUME_4L,
601 WM5100_DAC_DIGITAL_VOLUME_4R, WM5100_OUT4L_MUTE_SHIFT, 1, 1),
602SOC_DOUBLE_R("SPKDAT1 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_5L,
603 WM5100_DAC_DIGITAL_VOLUME_5R, WM5100_OUT5L_MUTE_SHIFT, 1, 1),
604SOC_DOUBLE_R("SPKDAT2 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_6L,
605 WM5100_DAC_DIGITAL_VOLUME_6R, WM5100_OUT6L_MUTE_SHIFT, 1, 1),
606
607/* FIXME: Only valid from -12dB to 0dB (52-64) */
608SOC_DOUBLE_R_TLV("HPOUT1 Volume", WM5100_OUT_VOLUME_1L, WM5100_OUT_VOLUME_1R,
609 WM5100_OUT1L_PGA_VOL_SHIFT, 64, 0, out_tlv),
610SOC_DOUBLE_R_TLV("HPOUT2 Volume", WM5100_OUT_VOLUME_2L, WM5100_OUT_VOLUME_2R,
611 WM5100_OUT2L_PGA_VOL_SHIFT, 64, 0, out_tlv),
612SOC_DOUBLE_R_TLV("HPOUT3 Volume", WM5100_OUT_VOLUME_3L, WM5100_OUT_VOLUME_3R,
613 WM5100_OUT2L_PGA_VOL_SHIFT, 64, 0, out_tlv),
614
615SOC_DOUBLE("SPKDAT1 Switch", WM5100_PDM_SPK1_CTRL_1, WM5100_SPK1L_MUTE_SHIFT,
616 WM5100_SPK1R_MUTE_SHIFT, 1, 1),
617SOC_DOUBLE("SPKDAT2 Switch", WM5100_PDM_SPK2_CTRL_1, WM5100_SPK2L_MUTE_SHIFT,
618 WM5100_SPK2R_MUTE_SHIFT, 1, 1),
619
620SOC_SINGLE_TLV("EQ1 Band 1 Volume", WM5100_EQ1_1, WM5100_EQ1_B1_GAIN_SHIFT,
621 24, 0, eq_tlv),
622SOC_SINGLE_TLV("EQ1 Band 2 Volume", WM5100_EQ1_1, WM5100_EQ1_B2_GAIN_SHIFT,
623 24, 0, eq_tlv),
624SOC_SINGLE_TLV("EQ1 Band 3 Volume", WM5100_EQ1_1, WM5100_EQ1_B3_GAIN_SHIFT,
625 24, 0, eq_tlv),
626SOC_SINGLE_TLV("EQ1 Band 4 Volume", WM5100_EQ1_2, WM5100_EQ1_B4_GAIN_SHIFT,
627 24, 0, eq_tlv),
628SOC_SINGLE_TLV("EQ1 Band 5 Volume", WM5100_EQ1_2, WM5100_EQ1_B5_GAIN_SHIFT,
629 24, 0, eq_tlv),
630
631SOC_SINGLE_TLV("EQ2 Band 1 Volume", WM5100_EQ2_1, WM5100_EQ2_B1_GAIN_SHIFT,
632 24, 0, eq_tlv),
633SOC_SINGLE_TLV("EQ2 Band 2 Volume", WM5100_EQ2_1, WM5100_EQ2_B2_GAIN_SHIFT,
634 24, 0, eq_tlv),
635SOC_SINGLE_TLV("EQ2 Band 3 Volume", WM5100_EQ2_1, WM5100_EQ2_B3_GAIN_SHIFT,
636 24, 0, eq_tlv),
637SOC_SINGLE_TLV("EQ2 Band 4 Volume", WM5100_EQ2_2, WM5100_EQ2_B4_GAIN_SHIFT,
638 24, 0, eq_tlv),
639SOC_SINGLE_TLV("EQ2 Band 5 Volume", WM5100_EQ2_2, WM5100_EQ2_B5_GAIN_SHIFT,
640 24, 0, eq_tlv),
641
642SOC_SINGLE_TLV("EQ3 Band 1 Volume", WM5100_EQ1_1, WM5100_EQ3_B1_GAIN_SHIFT,
643 24, 0, eq_tlv),
644SOC_SINGLE_TLV("EQ3 Band 2 Volume", WM5100_EQ3_1, WM5100_EQ3_B2_GAIN_SHIFT,
645 24, 0, eq_tlv),
646SOC_SINGLE_TLV("EQ3 Band 3 Volume", WM5100_EQ3_1, WM5100_EQ3_B3_GAIN_SHIFT,
647 24, 0, eq_tlv),
648SOC_SINGLE_TLV("EQ3 Band 4 Volume", WM5100_EQ3_2, WM5100_EQ3_B4_GAIN_SHIFT,
649 24, 0, eq_tlv),
650SOC_SINGLE_TLV("EQ3 Band 5 Volume", WM5100_EQ3_2, WM5100_EQ3_B5_GAIN_SHIFT,
651 24, 0, eq_tlv),
652
653SOC_SINGLE_TLV("EQ4 Band 1 Volume", WM5100_EQ4_1, WM5100_EQ4_B1_GAIN_SHIFT,
654 24, 0, eq_tlv),
655SOC_SINGLE_TLV("EQ4 Band 2 Volume", WM5100_EQ4_1, WM5100_EQ4_B2_GAIN_SHIFT,
656 24, 0, eq_tlv),
657SOC_SINGLE_TLV("EQ4 Band 3 Volume", WM5100_EQ4_1, WM5100_EQ4_B3_GAIN_SHIFT,
658 24, 0, eq_tlv),
659SOC_SINGLE_TLV("EQ4 Band 4 Volume", WM5100_EQ4_2, WM5100_EQ4_B4_GAIN_SHIFT,
660 24, 0, eq_tlv),
661SOC_SINGLE_TLV("EQ4 Band 5 Volume", WM5100_EQ4_2, WM5100_EQ4_B5_GAIN_SHIFT,
662 24, 0, eq_tlv),
663
664SOC_ENUM("LHPF1 Mode", wm5100_lhpf1_mode),
665SOC_ENUM("LHPF2 Mode", wm5100_lhpf2_mode),
666SOC_ENUM("LHPF3 Mode", wm5100_lhpf3_mode),
667SOC_ENUM("LHPF4 Mode", wm5100_lhpf4_mode),
668
669WM5100_MIXER_CONTROLS("HPOUT1L", WM5100_OUT1LMIX_INPUT_1_SOURCE),
670WM5100_MIXER_CONTROLS("HPOUT1R", WM5100_OUT1RMIX_INPUT_1_SOURCE),
671WM5100_MIXER_CONTROLS("HPOUT2L", WM5100_OUT2LMIX_INPUT_1_SOURCE),
672WM5100_MIXER_CONTROLS("HPOUT2R", WM5100_OUT2RMIX_INPUT_1_SOURCE),
673WM5100_MIXER_CONTROLS("HPOUT3L", WM5100_OUT3LMIX_INPUT_1_SOURCE),
674WM5100_MIXER_CONTROLS("HPOUT3R", WM5100_OUT3RMIX_INPUT_1_SOURCE),
675
676WM5100_MIXER_CONTROLS("SPKOUTL", WM5100_OUT4LMIX_INPUT_1_SOURCE),
677WM5100_MIXER_CONTROLS("SPKOUTR", WM5100_OUT4RMIX_INPUT_1_SOURCE),
678WM5100_MIXER_CONTROLS("SPKDAT1L", WM5100_OUT5LMIX_INPUT_1_SOURCE),
679WM5100_MIXER_CONTROLS("SPKDAT1R", WM5100_OUT5RMIX_INPUT_1_SOURCE),
680WM5100_MIXER_CONTROLS("SPKDAT2L", WM5100_OUT6LMIX_INPUT_1_SOURCE),
681WM5100_MIXER_CONTROLS("SPKDAT2R", WM5100_OUT6RMIX_INPUT_1_SOURCE),
682
683WM5100_MIXER_CONTROLS("PWM1", WM5100_PWM1MIX_INPUT_1_SOURCE),
684WM5100_MIXER_CONTROLS("PWM2", WM5100_PWM2MIX_INPUT_1_SOURCE),
685
686WM5100_MIXER_CONTROLS("AIF1TX1", WM5100_AIF1TX1MIX_INPUT_1_SOURCE),
687WM5100_MIXER_CONTROLS("AIF1TX2", WM5100_AIF1TX2MIX_INPUT_1_SOURCE),
688WM5100_MIXER_CONTROLS("AIF1TX3", WM5100_AIF1TX3MIX_INPUT_1_SOURCE),
689WM5100_MIXER_CONTROLS("AIF1TX4", WM5100_AIF1TX4MIX_INPUT_1_SOURCE),
690WM5100_MIXER_CONTROLS("AIF1TX5", WM5100_AIF1TX5MIX_INPUT_1_SOURCE),
691WM5100_MIXER_CONTROLS("AIF1TX6", WM5100_AIF1TX6MIX_INPUT_1_SOURCE),
692WM5100_MIXER_CONTROLS("AIF1TX7", WM5100_AIF1TX7MIX_INPUT_1_SOURCE),
693WM5100_MIXER_CONTROLS("AIF1TX8", WM5100_AIF1TX8MIX_INPUT_1_SOURCE),
694
695WM5100_MIXER_CONTROLS("AIF2TX1", WM5100_AIF2TX1MIX_INPUT_1_SOURCE),
696WM5100_MIXER_CONTROLS("AIF2TX2", WM5100_AIF2TX2MIX_INPUT_1_SOURCE),
697
698WM5100_MIXER_CONTROLS("AIF3TX1", WM5100_AIF3TX1MIX_INPUT_1_SOURCE),
699WM5100_MIXER_CONTROLS("AIF3TX2", WM5100_AIF3TX2MIX_INPUT_1_SOURCE),
700
701WM5100_MIXER_CONTROLS("EQ1", WM5100_EQ1MIX_INPUT_1_SOURCE),
702WM5100_MIXER_CONTROLS("EQ2", WM5100_EQ2MIX_INPUT_1_SOURCE),
703WM5100_MIXER_CONTROLS("EQ3", WM5100_EQ3MIX_INPUT_1_SOURCE),
704WM5100_MIXER_CONTROLS("EQ4", WM5100_EQ4MIX_INPUT_1_SOURCE),
705
706WM5100_MIXER_CONTROLS("DRC1L", WM5100_DRC1LMIX_INPUT_1_SOURCE),
707WM5100_MIXER_CONTROLS("DRC1R", WM5100_DRC1RMIX_INPUT_1_SOURCE),
708
709WM5100_MIXER_CONTROLS("LHPF1", WM5100_HPLP1MIX_INPUT_1_SOURCE),
710WM5100_MIXER_CONTROLS("LHPF2", WM5100_HPLP2MIX_INPUT_1_SOURCE),
711WM5100_MIXER_CONTROLS("LHPF3", WM5100_HPLP3MIX_INPUT_1_SOURCE),
712WM5100_MIXER_CONTROLS("LHPF4", WM5100_HPLP4MIX_INPUT_1_SOURCE),
713};
714
715static void wm5100_seq_notifier(struct snd_soc_dapm_context *dapm,
716 enum snd_soc_dapm_type event, int subseq)
717{
718 struct snd_soc_codec *codec = container_of(dapm,
719 struct snd_soc_codec, dapm);
720 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
721 u16 val, expect, i;
722
723 /* Wait for the outputs to flag themselves as enabled */
724 if (wm5100->out_ena[0]) {
725 expect = snd_soc_read(codec, WM5100_CHANNEL_ENABLES_1);
726 for (i = 0; i < 200; i++) {
727 val = snd_soc_read(codec, WM5100_OUTPUT_STATUS_1);
728 if (val == expect) {
729 wm5100->out_ena[0] = false;
730 break;
731 }
732 }
733 if (i == 200) {
734 dev_err(codec->dev, "Timeout waiting for OUTPUT1 %x\n",
735 expect);
736 }
737 }
738
739 if (wm5100->out_ena[1]) {
740 expect = snd_soc_read(codec, WM5100_OUTPUT_ENABLES_2);
741 for (i = 0; i < 200; i++) {
742 val = snd_soc_read(codec, WM5100_OUTPUT_STATUS_2);
743 if (val == expect) {
744 wm5100->out_ena[1] = false;
745 break;
746 }
747 }
748 if (i == 200) {
749 dev_err(codec->dev, "Timeout waiting for OUTPUT2 %x\n",
750 expect);
751 }
752 }
753}
754
755static int wm5100_out_ev(struct snd_soc_dapm_widget *w,
756 struct snd_kcontrol *kcontrol,
757 int event)
758{
759 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(w->codec);
760
761 switch (w->reg) {
762 case WM5100_CHANNEL_ENABLES_1:
763 wm5100->out_ena[0] = true;
764 break;
765 case WM5100_OUTPUT_ENABLES_2:
766 wm5100->out_ena[0] = true;
767 break;
768 default:
769 break;
770 }
771
772 return 0;
773}
774
775static int wm5100_cp_ev(struct snd_soc_dapm_widget *w,
776 struct snd_kcontrol *kcontrol,
777 int event)
778{
779 struct snd_soc_codec *codec = w->codec;
780 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
781 int ret;
782
783 switch (event) {
784 case SND_SOC_DAPM_PRE_PMU:
785 ret = regulator_enable(wm5100->cpvdd);
786 if (ret != 0) {
787 dev_err(codec->dev, "Failed to enable CPVDD: %d\n",
788 ret);
789 return ret;
790 }
791 return ret;
792
793 case SND_SOC_DAPM_POST_PMD:
794 ret = regulator_disable_deferred(wm5100->cpvdd, 20);
795 if (ret != 0) {
796 dev_err(codec->dev, "Failed to disable CPVDD: %d\n",
797 ret);
798 return ret;
799 }
800 return ret;
801
802 default:
803 BUG();
804 return 0;
805 }
806}
807
7aefb086
MB
808static int wm5100_dbvdd_ev(struct snd_soc_dapm_widget *w,
809 struct snd_kcontrol *kcontrol,
810 int event)
811{
812 struct snd_soc_codec *codec = w->codec;
813 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
814 struct regulator *regulator;
815 int ret;
816
817 switch (w->shift) {
818 case 2:
819 regulator = wm5100->dbvdd2;
820 break;
821 case 3:
822 regulator = wm5100->dbvdd3;
823 break;
824 default:
825 BUG();
826 return 0;
827 }
828
829 switch (event) {
830 case SND_SOC_DAPM_PRE_PMU:
831 ret = regulator_enable(regulator);
832 if (ret != 0) {
833 dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n",
834 w->shift, ret);
835 return ret;
836 }
837 return ret;
838
839 case SND_SOC_DAPM_POST_PMD:
840 ret = regulator_disable(regulator);
841 if (ret != 0) {
842 dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n",
843 w->shift, ret);
844 return ret;
845 }
846 return ret;
847
848 default:
849 BUG();
850 return 0;
851 }
852}
853
6d4baf08
MB
854static void wm5100_log_status3(struct snd_soc_codec *codec, int val)
855{
856 if (val & WM5100_SPK_SHUTDOWN_WARN_EINT)
857 dev_crit(codec->dev, "Speaker shutdown warning\n");
858 if (val & WM5100_SPK_SHUTDOWN_EINT)
859 dev_crit(codec->dev, "Speaker shutdown\n");
860 if (val & WM5100_CLKGEN_ERR_EINT)
861 dev_crit(codec->dev, "SYSCLK underclocked\n");
862 if (val & WM5100_CLKGEN_ERR_ASYNC_EINT)
863 dev_crit(codec->dev, "ASYNCCLK underclocked\n");
864}
865
866static void wm5100_log_status4(struct snd_soc_codec *codec, int val)
867{
868 if (val & WM5100_AIF3_ERR_EINT)
869 dev_err(codec->dev, "AIF3 configuration error\n");
870 if (val & WM5100_AIF2_ERR_EINT)
871 dev_err(codec->dev, "AIF2 configuration error\n");
872 if (val & WM5100_AIF1_ERR_EINT)
873 dev_err(codec->dev, "AIF1 configuration error\n");
874 if (val & WM5100_CTRLIF_ERR_EINT)
875 dev_err(codec->dev, "Control interface error\n");
876 if (val & WM5100_ISRC2_UNDERCLOCKED_EINT)
877 dev_err(codec->dev, "ISRC2 underclocked\n");
878 if (val & WM5100_ISRC1_UNDERCLOCKED_EINT)
879 dev_err(codec->dev, "ISRC1 underclocked\n");
880 if (val & WM5100_FX_UNDERCLOCKED_EINT)
881 dev_err(codec->dev, "FX underclocked\n");
882 if (val & WM5100_AIF3_UNDERCLOCKED_EINT)
883 dev_err(codec->dev, "AIF3 underclocked\n");
884 if (val & WM5100_AIF2_UNDERCLOCKED_EINT)
885 dev_err(codec->dev, "AIF2 underclocked\n");
886 if (val & WM5100_AIF1_UNDERCLOCKED_EINT)
887 dev_err(codec->dev, "AIF1 underclocked\n");
888 if (val & WM5100_ASRC_UNDERCLOCKED_EINT)
889 dev_err(codec->dev, "ASRC underclocked\n");
890 if (val & WM5100_DAC_UNDERCLOCKED_EINT)
891 dev_err(codec->dev, "DAC underclocked\n");
892 if (val & WM5100_ADC_UNDERCLOCKED_EINT)
893 dev_err(codec->dev, "ADC underclocked\n");
894 if (val & WM5100_MIXER_UNDERCLOCKED_EINT)
895 dev_err(codec->dev, "Mixer underclocked\n");
896}
897
898static int wm5100_post_ev(struct snd_soc_dapm_widget *w,
899 struct snd_kcontrol *kcontrol,
900 int event)
901{
902 struct snd_soc_codec *codec = w->codec;
903 int ret;
904
905 ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_3);
906 ret &= WM5100_SPK_SHUTDOWN_WARN_STS |
907 WM5100_SPK_SHUTDOWN_STS | WM5100_CLKGEN_ERR_STS |
908 WM5100_CLKGEN_ERR_ASYNC_STS;
909 wm5100_log_status3(codec, ret);
910
911 ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_4);
912 wm5100_log_status4(codec, ret);
913
914 return 0;
915}
916
917static const struct snd_soc_dapm_widget wm5100_dapm_widgets[] = {
918SND_SOC_DAPM_SUPPLY("SYSCLK", WM5100_CLOCKING_3, WM5100_SYSCLK_ENA_SHIFT, 0,
919 NULL, 0),
920SND_SOC_DAPM_SUPPLY("ASYNCCLK", WM5100_CLOCKING_6, WM5100_ASYNC_CLK_ENA_SHIFT,
921 0, NULL, 0),
922
923SND_SOC_DAPM_SUPPLY("CP1", WM5100_HP_CHARGE_PUMP_1, WM5100_CP1_ENA_SHIFT, 0,
924 wm5100_cp_ev,
925 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
926SND_SOC_DAPM_SUPPLY("CP2", WM5100_MIC_CHARGE_PUMP_1, WM5100_CP2_ENA_SHIFT, 0,
927 NULL, 0),
928SND_SOC_DAPM_SUPPLY("CP2 Active", WM5100_MIC_CHARGE_PUMP_1,
929 WM5100_CP2_BYPASS_SHIFT, 1, wm5100_cp_ev,
930 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
7aefb086
MB
931SND_SOC_DAPM_SUPPLY("DBVDD2", SND_SOC_NOPM, 2, 0, wm5100_dbvdd_ev,
932 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
933SND_SOC_DAPM_SUPPLY("DBVDD3", SND_SOC_NOPM, 3, 0, wm5100_dbvdd_ev,
934 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
6d4baf08
MB
935
936SND_SOC_DAPM_SUPPLY("MICBIAS1", WM5100_MIC_BIAS_CTRL_1, WM5100_MICB1_ENA_SHIFT,
937 0, NULL, 0),
938SND_SOC_DAPM_SUPPLY("MICBIAS2", WM5100_MIC_BIAS_CTRL_2, WM5100_MICB2_ENA_SHIFT,
939 0, NULL, 0),
940SND_SOC_DAPM_SUPPLY("MICBIAS3", WM5100_MIC_BIAS_CTRL_3, WM5100_MICB3_ENA_SHIFT,
941 0, NULL, 0),
942
943SND_SOC_DAPM_INPUT("IN1L"),
944SND_SOC_DAPM_INPUT("IN1R"),
945SND_SOC_DAPM_INPUT("IN2L"),
946SND_SOC_DAPM_INPUT("IN2R"),
947SND_SOC_DAPM_INPUT("IN3L"),
948SND_SOC_DAPM_INPUT("IN3R"),
949SND_SOC_DAPM_INPUT("IN4L"),
950SND_SOC_DAPM_INPUT("IN4R"),
951SND_SOC_DAPM_INPUT("TONE"),
952
953SND_SOC_DAPM_PGA_E("IN1L PGA", WM5100_INPUT_ENABLES, WM5100_IN1L_ENA_SHIFT, 0,
954 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
955SND_SOC_DAPM_PGA_E("IN1R PGA", WM5100_INPUT_ENABLES, WM5100_IN1R_ENA_SHIFT, 0,
956 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
957SND_SOC_DAPM_PGA_E("IN2L PGA", WM5100_INPUT_ENABLES, WM5100_IN2L_ENA_SHIFT, 0,
958 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
959SND_SOC_DAPM_PGA_E("IN2R PGA", WM5100_INPUT_ENABLES, WM5100_IN2R_ENA_SHIFT, 0,
960 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
961SND_SOC_DAPM_PGA_E("IN3L PGA", WM5100_INPUT_ENABLES, WM5100_IN3L_ENA_SHIFT, 0,
962 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
963SND_SOC_DAPM_PGA_E("IN3R PGA", WM5100_INPUT_ENABLES, WM5100_IN3R_ENA_SHIFT, 0,
964 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
965SND_SOC_DAPM_PGA_E("IN4L PGA", WM5100_INPUT_ENABLES, WM5100_IN4L_ENA_SHIFT, 0,
966 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
967SND_SOC_DAPM_PGA_E("IN4R PGA", WM5100_INPUT_ENABLES, WM5100_IN4R_ENA_SHIFT, 0,
968 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
969
970SND_SOC_DAPM_PGA("Tone Generator 1", WM5100_TONE_GENERATOR_1,
971 WM5100_TONE1_ENA_SHIFT, 0, NULL, 0),
972SND_SOC_DAPM_PGA("Tone Generator 2", WM5100_TONE_GENERATOR_1,
973 WM5100_TONE2_ENA_SHIFT, 0, NULL, 0),
974
975SND_SOC_DAPM_AIF_IN("AIF1RX1", "AIF1 Playback", 0,
976 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX1_ENA_SHIFT, 0),
977SND_SOC_DAPM_AIF_IN("AIF1RX2", "AIF1 Playback", 1,
978 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX2_ENA_SHIFT, 0),
979SND_SOC_DAPM_AIF_IN("AIF1RX3", "AIF1 Playback", 2,
980 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX3_ENA_SHIFT, 0),
981SND_SOC_DAPM_AIF_IN("AIF1RX4", "AIF1 Playback", 3,
982 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX4_ENA_SHIFT, 0),
983SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 4,
984 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX5_ENA_SHIFT, 0),
985SND_SOC_DAPM_AIF_IN("AIF1RX6", "AIF1 Playback", 5,
986 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX6_ENA_SHIFT, 0),
987SND_SOC_DAPM_AIF_IN("AIF1RX7", "AIF1 Playback", 6,
988 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX7_ENA_SHIFT, 0),
989SND_SOC_DAPM_AIF_IN("AIF1RX8", "AIF1 Playback", 7,
990 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX8_ENA_SHIFT, 0),
991
992SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 0,
993 WM5100_AUDIO_IF_2_27, WM5100_AIF2RX1_ENA_SHIFT, 0),
994SND_SOC_DAPM_AIF_IN("AIF2RX2", "AIF2 Playback", 1,
995 WM5100_AUDIO_IF_2_27, WM5100_AIF2RX2_ENA_SHIFT, 0),
996
997SND_SOC_DAPM_AIF_IN("AIF3RX1", "AIF3 Playback", 0,
998 WM5100_AUDIO_IF_3_27, WM5100_AIF3RX1_ENA_SHIFT, 0),
999SND_SOC_DAPM_AIF_IN("AIF3RX2", "AIF3 Playback", 1,
1000 WM5100_AUDIO_IF_3_27, WM5100_AIF3RX2_ENA_SHIFT, 0),
1001
1002SND_SOC_DAPM_AIF_OUT("AIF1TX1", "AIF1 Capture", 0,
1003 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX1_ENA_SHIFT, 0),
1004SND_SOC_DAPM_AIF_OUT("AIF1TX2", "AIF1 Capture", 1,
1005 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX2_ENA_SHIFT, 0),
1006SND_SOC_DAPM_AIF_OUT("AIF1TX3", "AIF1 Capture", 2,
1007 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX3_ENA_SHIFT, 0),
1008SND_SOC_DAPM_AIF_OUT("AIF1TX4", "AIF1 Capture", 3,
1009 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX4_ENA_SHIFT, 0),
1010SND_SOC_DAPM_AIF_OUT("AIF1TX5", "AIF1 Capture", 4,
1011 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX5_ENA_SHIFT, 0),
1012SND_SOC_DAPM_AIF_OUT("AIF1TX6", "AIF1 Capture", 5,
1013 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX6_ENA_SHIFT, 0),
1014SND_SOC_DAPM_AIF_OUT("AIF1TX7", "AIF1 Capture", 6,
1015 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX7_ENA_SHIFT, 0),
1016SND_SOC_DAPM_AIF_OUT("AIF1TX8", "AIF1 Capture", 7,
1017 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX8_ENA_SHIFT, 0),
1018
1019SND_SOC_DAPM_AIF_OUT("AIF2TX1", "AIF2 Capture", 0,
1020 WM5100_AUDIO_IF_2_26, WM5100_AIF2TX1_ENA_SHIFT, 0),
1021SND_SOC_DAPM_AIF_OUT("AIF2TX2", "AIF2 Capture", 1,
1022 WM5100_AUDIO_IF_2_26, WM5100_AIF2TX2_ENA_SHIFT, 0),
1023
1024SND_SOC_DAPM_AIF_OUT("AIF3TX1", "AIF3 Capture", 0,
1025 WM5100_AUDIO_IF_3_26, WM5100_AIF3TX1_ENA_SHIFT, 0),
1026SND_SOC_DAPM_AIF_OUT("AIF3TX2", "AIF3 Capture", 1,
1027 WM5100_AUDIO_IF_3_26, WM5100_AIF3TX2_ENA_SHIFT, 0),
1028
1029SND_SOC_DAPM_PGA_E("OUT6L", WM5100_OUTPUT_ENABLES_2, WM5100_OUT6L_ENA_SHIFT, 0,
1030 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1031SND_SOC_DAPM_PGA_E("OUT6R", WM5100_OUTPUT_ENABLES_2, WM5100_OUT6R_ENA_SHIFT, 0,
1032 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1033SND_SOC_DAPM_PGA_E("OUT5L", WM5100_OUTPUT_ENABLES_2, WM5100_OUT5L_ENA_SHIFT, 0,
1034 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1035SND_SOC_DAPM_PGA_E("OUT5R", WM5100_OUTPUT_ENABLES_2, WM5100_OUT5R_ENA_SHIFT, 0,
1036 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1037SND_SOC_DAPM_PGA_E("OUT4L", WM5100_OUTPUT_ENABLES_2, WM5100_OUT4L_ENA_SHIFT, 0,
1038 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1039SND_SOC_DAPM_PGA_E("OUT4R", WM5100_OUTPUT_ENABLES_2, WM5100_OUT4R_ENA_SHIFT, 0,
1040 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1041SND_SOC_DAPM_PGA_E("OUT3L", WM5100_CHANNEL_ENABLES_1, WM5100_HP3L_ENA_SHIFT, 0,
1042 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1043SND_SOC_DAPM_PGA_E("OUT3R", WM5100_CHANNEL_ENABLES_1, WM5100_HP3R_ENA_SHIFT, 0,
1044 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1045SND_SOC_DAPM_PGA_E("OUT2L", WM5100_CHANNEL_ENABLES_1, WM5100_HP2L_ENA_SHIFT, 0,
1046 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1047SND_SOC_DAPM_PGA_E("OUT2R", WM5100_CHANNEL_ENABLES_1, WM5100_HP2R_ENA_SHIFT, 0,
1048 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1049SND_SOC_DAPM_PGA_E("OUT1L", WM5100_CHANNEL_ENABLES_1, WM5100_HP1L_ENA_SHIFT, 0,
1050 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1051SND_SOC_DAPM_PGA_E("OUT1R", WM5100_CHANNEL_ENABLES_1, WM5100_HP1R_ENA_SHIFT, 0,
1052 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1053SND_SOC_DAPM_PGA_E("PWM1 Driver", WM5100_PWM_DRIVE_1, WM5100_PWM1_ENA_SHIFT, 0,
1054 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1055SND_SOC_DAPM_PGA_E("PWM2 Driver", WM5100_PWM_DRIVE_1, WM5100_PWM2_ENA_SHIFT, 0,
1056 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1057
1058SND_SOC_DAPM_PGA("EQ1", WM5100_EQ1_1, WM5100_EQ1_ENA_SHIFT, 0, NULL, 0),
1059SND_SOC_DAPM_PGA("EQ2", WM5100_EQ2_1, WM5100_EQ2_ENA_SHIFT, 0, NULL, 0),
1060SND_SOC_DAPM_PGA("EQ3", WM5100_EQ3_1, WM5100_EQ3_ENA_SHIFT, 0, NULL, 0),
1061SND_SOC_DAPM_PGA("EQ4", WM5100_EQ4_1, WM5100_EQ4_ENA_SHIFT, 0, NULL, 0),
1062
1063SND_SOC_DAPM_PGA("DRC1L", WM5100_DRC1_CTRL1, WM5100_DRCL_ENA_SHIFT, 0,
1064 NULL, 0),
1065SND_SOC_DAPM_PGA("DRC1R", WM5100_DRC1_CTRL1, WM5100_DRCR_ENA_SHIFT, 0,
1066 NULL, 0),
1067
1068SND_SOC_DAPM_PGA("LHPF1", WM5100_HPLPF1_1, WM5100_LHPF1_ENA_SHIFT, 0,
1069 NULL, 0),
1070SND_SOC_DAPM_PGA("LHPF2", WM5100_HPLPF2_1, WM5100_LHPF2_ENA_SHIFT, 0,
1071 NULL, 0),
1072SND_SOC_DAPM_PGA("LHPF3", WM5100_HPLPF3_1, WM5100_LHPF3_ENA_SHIFT, 0,
1073 NULL, 0),
1074SND_SOC_DAPM_PGA("LHPF4", WM5100_HPLPF4_1, WM5100_LHPF4_ENA_SHIFT, 0,
1075 NULL, 0),
1076
1077WM5100_MIXER_WIDGETS(EQ1, "EQ1"),
1078WM5100_MIXER_WIDGETS(EQ2, "EQ2"),
1079WM5100_MIXER_WIDGETS(EQ3, "EQ3"),
1080WM5100_MIXER_WIDGETS(EQ4, "EQ4"),
1081
1082WM5100_MIXER_WIDGETS(DRC1L, "DRC1L"),
1083WM5100_MIXER_WIDGETS(DRC1R, "DRC1R"),
1084
1085WM5100_MIXER_WIDGETS(LHPF1, "LHPF1"),
1086WM5100_MIXER_WIDGETS(LHPF2, "LHPF2"),
1087WM5100_MIXER_WIDGETS(LHPF3, "LHPF3"),
1088WM5100_MIXER_WIDGETS(LHPF4, "LHPF4"),
1089
1090WM5100_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
1091WM5100_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
1092WM5100_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
1093WM5100_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
1094WM5100_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
1095WM5100_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
1096WM5100_MIXER_WIDGETS(AIF1TX7, "AIF1TX7"),
1097WM5100_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"),
1098
1099WM5100_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
1100WM5100_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
1101
1102WM5100_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
1103WM5100_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
1104
1105WM5100_MIXER_WIDGETS(HPOUT1L, "HPOUT1L"),
1106WM5100_MIXER_WIDGETS(HPOUT1R, "HPOUT1R"),
1107WM5100_MIXER_WIDGETS(HPOUT2L, "HPOUT2L"),
1108WM5100_MIXER_WIDGETS(HPOUT2R, "HPOUT2R"),
1109WM5100_MIXER_WIDGETS(HPOUT3L, "HPOUT3L"),
1110WM5100_MIXER_WIDGETS(HPOUT3R, "HPOUT3R"),
1111
1112WM5100_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"),
1113WM5100_MIXER_WIDGETS(SPKOUTR, "SPKOUTR"),
1114WM5100_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"),
1115WM5100_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"),
1116WM5100_MIXER_WIDGETS(SPKDAT2L, "SPKDAT2L"),
1117WM5100_MIXER_WIDGETS(SPKDAT2R, "SPKDAT2R"),
1118
1119WM5100_MIXER_WIDGETS(PWM1, "PWM1"),
1120WM5100_MIXER_WIDGETS(PWM2, "PWM2"),
1121
1122SND_SOC_DAPM_OUTPUT("HPOUT1L"),
1123SND_SOC_DAPM_OUTPUT("HPOUT1R"),
1124SND_SOC_DAPM_OUTPUT("HPOUT2L"),
1125SND_SOC_DAPM_OUTPUT("HPOUT2R"),
1126SND_SOC_DAPM_OUTPUT("HPOUT3L"),
1127SND_SOC_DAPM_OUTPUT("HPOUT3R"),
1128SND_SOC_DAPM_OUTPUT("SPKOUTL"),
1129SND_SOC_DAPM_OUTPUT("SPKOUTR"),
1130SND_SOC_DAPM_OUTPUT("SPKDAT1"),
1131SND_SOC_DAPM_OUTPUT("SPKDAT2"),
1132SND_SOC_DAPM_OUTPUT("PWM1"),
1133SND_SOC_DAPM_OUTPUT("PWM2"),
1134};
1135
1136/* We register a _POST event if we don't have IRQ support so we can
1137 * look at the error status from the CODEC - if we've got the IRQ
1138 * hooked up then we will get prompted to look by an interrupt.
1139 */
1140static const struct snd_soc_dapm_widget wm5100_dapm_widgets_noirq[] = {
1141SND_SOC_DAPM_POST("Post", wm5100_post_ev),
1142};
1143
1144static const struct snd_soc_dapm_route wm5100_dapm_routes[] = {
1145 { "IN1L", NULL, "SYSCLK" },
1146 { "IN1R", NULL, "SYSCLK" },
1147 { "IN2L", NULL, "SYSCLK" },
1148 { "IN2R", NULL, "SYSCLK" },
1149 { "IN3L", NULL, "SYSCLK" },
1150 { "IN3R", NULL, "SYSCLK" },
1151 { "IN4L", NULL, "SYSCLK" },
1152 { "IN4R", NULL, "SYSCLK" },
1153
1154 { "OUT1L", NULL, "SYSCLK" },
1155 { "OUT1R", NULL, "SYSCLK" },
1156 { "OUT2L", NULL, "SYSCLK" },
1157 { "OUT2R", NULL, "SYSCLK" },
1158 { "OUT3L", NULL, "SYSCLK" },
1159 { "OUT3R", NULL, "SYSCLK" },
1160 { "OUT4L", NULL, "SYSCLK" },
1161 { "OUT4R", NULL, "SYSCLK" },
1162 { "OUT5L", NULL, "SYSCLK" },
1163 { "OUT5R", NULL, "SYSCLK" },
1164 { "OUT6L", NULL, "SYSCLK" },
1165 { "OUT6R", NULL, "SYSCLK" },
1166
1167 { "AIF1RX1", NULL, "SYSCLK" },
1168 { "AIF1RX2", NULL, "SYSCLK" },
1169 { "AIF1RX3", NULL, "SYSCLK" },
1170 { "AIF1RX4", NULL, "SYSCLK" },
1171 { "AIF1RX5", NULL, "SYSCLK" },
1172 { "AIF1RX6", NULL, "SYSCLK" },
1173 { "AIF1RX7", NULL, "SYSCLK" },
1174 { "AIF1RX8", NULL, "SYSCLK" },
1175
1176 { "AIF2RX1", NULL, "SYSCLK" },
7aefb086 1177 { "AIF2RX1", NULL, "DBVDD2" },
6d4baf08 1178 { "AIF2RX2", NULL, "SYSCLK" },
7aefb086 1179 { "AIF2RX2", NULL, "DBVDD2" },
6d4baf08
MB
1180
1181 { "AIF3RX1", NULL, "SYSCLK" },
7aefb086 1182 { "AIF3RX1", NULL, "DBVDD3" },
6d4baf08 1183 { "AIF3RX2", NULL, "SYSCLK" },
7aefb086 1184 { "AIF3RX2", NULL, "DBVDD3" },
6d4baf08
MB
1185
1186 { "AIF1TX1", NULL, "SYSCLK" },
1187 { "AIF1TX2", NULL, "SYSCLK" },
1188 { "AIF1TX3", NULL, "SYSCLK" },
1189 { "AIF1TX4", NULL, "SYSCLK" },
1190 { "AIF1TX5", NULL, "SYSCLK" },
1191 { "AIF1TX6", NULL, "SYSCLK" },
1192 { "AIF1TX7", NULL, "SYSCLK" },
1193 { "AIF1TX8", NULL, "SYSCLK" },
1194
1195 { "AIF2TX1", NULL, "SYSCLK" },
7aefb086 1196 { "AIF2TX1", NULL, "DBVDD2" },
6d4baf08 1197 { "AIF2TX2", NULL, "SYSCLK" },
7aefb086 1198 { "AIF2TX2", NULL, "DBVDD2" },
6d4baf08
MB
1199
1200 { "AIF3TX1", NULL, "SYSCLK" },
7aefb086 1201 { "AIF3TX1", NULL, "DBVDD3" },
6d4baf08 1202 { "AIF3TX2", NULL, "SYSCLK" },
7aefb086 1203 { "AIF3TX2", NULL, "DBVDD3" },
6d4baf08
MB
1204
1205 { "MICBIAS1", NULL, "CP2" },
1206 { "MICBIAS2", NULL, "CP2" },
1207 { "MICBIAS3", NULL, "CP2" },
1208
1209 { "IN1L PGA", NULL, "CP2" },
1210 { "IN1R PGA", NULL, "CP2" },
1211 { "IN2L PGA", NULL, "CP2" },
1212 { "IN2R PGA", NULL, "CP2" },
1213 { "IN3L PGA", NULL, "CP2" },
1214 { "IN3R PGA", NULL, "CP2" },
1215 { "IN4L PGA", NULL, "CP2" },
1216 { "IN4R PGA", NULL, "CP2" },
1217
1218 { "IN1L PGA", NULL, "CP2 Active" },
1219 { "IN1R PGA", NULL, "CP2 Active" },
1220 { "IN2L PGA", NULL, "CP2 Active" },
1221 { "IN2R PGA", NULL, "CP2 Active" },
1222 { "IN3L PGA", NULL, "CP2 Active" },
1223 { "IN3R PGA", NULL, "CP2 Active" },
1224 { "IN4L PGA", NULL, "CP2 Active" },
1225 { "IN4R PGA", NULL, "CP2 Active" },
1226
1227 { "OUT1L", NULL, "CP1" },
1228 { "OUT1R", NULL, "CP1" },
1229 { "OUT2L", NULL, "CP1" },
1230 { "OUT2R", NULL, "CP1" },
1231 { "OUT3L", NULL, "CP1" },
1232 { "OUT3R", NULL, "CP1" },
1233
1234 { "Tone Generator 1", NULL, "TONE" },
1235 { "Tone Generator 2", NULL, "TONE" },
1236
1237 { "IN1L PGA", NULL, "IN1L" },
1238 { "IN1R PGA", NULL, "IN1R" },
1239 { "IN2L PGA", NULL, "IN2L" },
1240 { "IN2R PGA", NULL, "IN2R" },
1241 { "IN3L PGA", NULL, "IN3L" },
1242 { "IN3R PGA", NULL, "IN3R" },
1243 { "IN4L PGA", NULL, "IN4L" },
1244 { "IN4R PGA", NULL, "IN4R" },
1245
1246 WM5100_MIXER_ROUTES("OUT1L", "HPOUT1L"),
1247 WM5100_MIXER_ROUTES("OUT1R", "HPOUT1R"),
1248 WM5100_MIXER_ROUTES("OUT2L", "HPOUT2L"),
1249 WM5100_MIXER_ROUTES("OUT2R", "HPOUT2R"),
1250 WM5100_MIXER_ROUTES("OUT3L", "HPOUT3L"),
1251 WM5100_MIXER_ROUTES("OUT3R", "HPOUT3R"),
1252
1253 WM5100_MIXER_ROUTES("OUT4L", "SPKOUTL"),
1254 WM5100_MIXER_ROUTES("OUT4R", "SPKOUTR"),
1255 WM5100_MIXER_ROUTES("OUT5L", "SPKDAT1L"),
1256 WM5100_MIXER_ROUTES("OUT5R", "SPKDAT1R"),
1257 WM5100_MIXER_ROUTES("OUT6L", "SPKDAT2L"),
1258 WM5100_MIXER_ROUTES("OUT6R", "SPKDAT2R"),
1259
1260 WM5100_MIXER_ROUTES("PWM1 Driver", "PWM1"),
1261 WM5100_MIXER_ROUTES("PWM2 Driver", "PWM2"),
1262
1263 WM5100_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
1264 WM5100_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
1265 WM5100_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
1266 WM5100_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
1267 WM5100_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
1268 WM5100_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
1269 WM5100_MIXER_ROUTES("AIF1TX7", "AIF1TX7"),
1270 WM5100_MIXER_ROUTES("AIF1TX8", "AIF1TX8"),
1271
1272 WM5100_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
1273 WM5100_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
1274
1275 WM5100_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
1276 WM5100_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
1277
1278 WM5100_MIXER_ROUTES("EQ1", "EQ1"),
1279 WM5100_MIXER_ROUTES("EQ2", "EQ2"),
1280 WM5100_MIXER_ROUTES("EQ3", "EQ3"),
1281 WM5100_MIXER_ROUTES("EQ4", "EQ4"),
1282
1283 WM5100_MIXER_ROUTES("DRC1L", "DRC1L"),
1284 WM5100_MIXER_ROUTES("DRC1R", "DRC1R"),
1285
1286 WM5100_MIXER_ROUTES("LHPF1", "LHPF1"),
1287 WM5100_MIXER_ROUTES("LHPF2", "LHPF2"),
1288 WM5100_MIXER_ROUTES("LHPF3", "LHPF3"),
1289 WM5100_MIXER_ROUTES("LHPF4", "LHPF4"),
1290
1291 { "HPOUT1L", NULL, "OUT1L" },
1292 { "HPOUT1R", NULL, "OUT1R" },
1293 { "HPOUT2L", NULL, "OUT2L" },
1294 { "HPOUT2R", NULL, "OUT2R" },
1295 { "HPOUT3L", NULL, "OUT3L" },
1296 { "HPOUT3R", NULL, "OUT3R" },
1297 { "SPKOUTL", NULL, "OUT4L" },
1298 { "SPKOUTR", NULL, "OUT4R" },
1299 { "SPKDAT1", NULL, "OUT5L" },
1300 { "SPKDAT1", NULL, "OUT5R" },
1301 { "SPKDAT2", NULL, "OUT6L" },
1302 { "SPKDAT2", NULL, "OUT6R" },
1303 { "PWM1", NULL, "PWM1 Driver" },
1304 { "PWM2", NULL, "PWM2 Driver" },
1305};
1306
1307static struct {
1308 int reg;
1309 int val;
1310} wm5100_reva_patches[] = {
1311 { WM5100_AUDIO_IF_1_10, 0 },
1312 { WM5100_AUDIO_IF_1_11, 1 },
1313 { WM5100_AUDIO_IF_1_12, 2 },
1314 { WM5100_AUDIO_IF_1_13, 3 },
1315 { WM5100_AUDIO_IF_1_14, 4 },
1316 { WM5100_AUDIO_IF_1_15, 5 },
1317 { WM5100_AUDIO_IF_1_16, 6 },
1318 { WM5100_AUDIO_IF_1_17, 7 },
1319
1320 { WM5100_AUDIO_IF_1_18, 0 },
1321 { WM5100_AUDIO_IF_1_19, 1 },
1322 { WM5100_AUDIO_IF_1_20, 2 },
1323 { WM5100_AUDIO_IF_1_21, 3 },
1324 { WM5100_AUDIO_IF_1_22, 4 },
1325 { WM5100_AUDIO_IF_1_23, 5 },
1326 { WM5100_AUDIO_IF_1_24, 6 },
1327 { WM5100_AUDIO_IF_1_25, 7 },
1328
1329 { WM5100_AUDIO_IF_2_10, 0 },
1330 { WM5100_AUDIO_IF_2_11, 1 },
1331
1332 { WM5100_AUDIO_IF_2_18, 0 },
1333 { WM5100_AUDIO_IF_2_19, 1 },
1334
1335 { WM5100_AUDIO_IF_3_10, 0 },
1336 { WM5100_AUDIO_IF_3_11, 1 },
1337
1338 { WM5100_AUDIO_IF_3_18, 0 },
1339 { WM5100_AUDIO_IF_3_19, 1 },
1340};
1341
1342static int wm5100_set_bias_level(struct snd_soc_codec *codec,
1343 enum snd_soc_bias_level level)
1344{
1345 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1346 int ret, i;
1347
1348 switch (level) {
1349 case SND_SOC_BIAS_ON:
1350 break;
1351
1352 case SND_SOC_BIAS_PREPARE:
1353 break;
1354
1355 case SND_SOC_BIAS_STANDBY:
1356 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1357 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
1358 wm5100->core_supplies);
1359 if (ret != 0) {
1360 dev_err(codec->dev,
1361 "Failed to enable supplies: %d\n",
1362 ret);
1363 return ret;
1364 }
1365
1366 if (wm5100->pdata.ldo_ena) {
1367 gpio_set_value_cansleep(wm5100->pdata.ldo_ena,
1368 1);
1369 msleep(2);
1370 }
1371
1372 codec->cache_only = false;
1373
1374 switch (wm5100->rev) {
1375 case 0:
1376 snd_soc_write(codec, 0x11, 0x3);
1377 snd_soc_write(codec, 0x203, 0xc);
1378 snd_soc_write(codec, 0x206, 0);
1379 snd_soc_write(codec, 0x207, 0xf0);
1380 snd_soc_write(codec, 0x208, 0x3c);
1381 snd_soc_write(codec, 0x209, 0);
1382 snd_soc_write(codec, 0x211, 0x20d8);
1383 snd_soc_write(codec, 0x11, 0);
1384
1385 for (i = 0;
1386 i < ARRAY_SIZE(wm5100_reva_patches);
1387 i++)
1388 snd_soc_write(codec,
1389 wm5100_reva_patches[i].reg,
1390 wm5100_reva_patches[i].val);
1391 break;
1392 default:
1393 break;
1394 }
1395
1396 snd_soc_cache_sync(codec);
1397 }
1398 break;
1399
1400 case SND_SOC_BIAS_OFF:
1401 if (wm5100->pdata.ldo_ena)
1402 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
1403 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
1404 wm5100->core_supplies);
1405 break;
1406 }
1407 codec->dapm.bias_level = level;
1408
1409 return 0;
1410}
1411
1412static int wm5100_dai_to_base(struct snd_soc_dai *dai)
1413{
1414 switch (dai->id) {
1415 case 0:
1416 return WM5100_AUDIO_IF_1_1 - 1;
1417 case 1:
1418 return WM5100_AUDIO_IF_2_1 - 1;
1419 case 2:
1420 return WM5100_AUDIO_IF_3_1 - 1;
1421 default:
1422 BUG();
1423 return -EINVAL;
1424 }
1425}
1426
1427static int wm5100_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1428{
1429 struct snd_soc_codec *codec = dai->codec;
1430 int lrclk, bclk, mask, base;
1431
1432 base = wm5100_dai_to_base(dai);
1433 if (base < 0)
1434 return base;
1435
1436 lrclk = 0;
1437 bclk = 0;
1438
1439 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1440 case SND_SOC_DAIFMT_DSP_A:
1441 mask = 0;
1442 break;
1443 case SND_SOC_DAIFMT_DSP_B:
1444 mask = 1;
1445 break;
1446 case SND_SOC_DAIFMT_I2S:
1447 mask = 2;
1448 break;
1449 case SND_SOC_DAIFMT_LEFT_J:
1450 mask = 3;
1451 break;
1452 default:
1453 dev_err(codec->dev, "Unsupported DAI format %d\n",
1454 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1455 return -EINVAL;
1456 }
1457
1458 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1459 case SND_SOC_DAIFMT_CBS_CFS:
1460 break;
1461 case SND_SOC_DAIFMT_CBS_CFM:
1462 lrclk |= WM5100_AIF1TX_LRCLK_MSTR;
1463 break;
1464 case SND_SOC_DAIFMT_CBM_CFS:
1465 bclk |= WM5100_AIF1_BCLK_MSTR;
1466 break;
1467 case SND_SOC_DAIFMT_CBM_CFM:
1468 lrclk |= WM5100_AIF1TX_LRCLK_MSTR;
1469 bclk |= WM5100_AIF1_BCLK_MSTR;
1470 break;
1471 default:
1472 dev_err(codec->dev, "Unsupported master mode %d\n",
1473 fmt & SND_SOC_DAIFMT_MASTER_MASK);
1474 return -EINVAL;
1475 }
1476
1477 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1478 case SND_SOC_DAIFMT_NB_NF:
1479 break;
1480 case SND_SOC_DAIFMT_IB_IF:
1481 bclk |= WM5100_AIF1_BCLK_INV;
1482 lrclk |= WM5100_AIF1TX_LRCLK_INV;
1483 break;
1484 case SND_SOC_DAIFMT_IB_NF:
1485 bclk |= WM5100_AIF1_BCLK_INV;
1486 break;
1487 case SND_SOC_DAIFMT_NB_IF:
1488 lrclk |= WM5100_AIF1TX_LRCLK_INV;
1489 break;
1490 default:
1491 return -EINVAL;
1492 }
1493
1494 snd_soc_update_bits(codec, base + 1, WM5100_AIF1_BCLK_MSTR |
1495 WM5100_AIF1_BCLK_INV, bclk);
1496 snd_soc_update_bits(codec, base + 2, WM5100_AIF1TX_LRCLK_MSTR |
1497 WM5100_AIF1TX_LRCLK_INV, lrclk);
1498 snd_soc_update_bits(codec, base + 3, WM5100_AIF1TX_LRCLK_MSTR |
1499 WM5100_AIF1TX_LRCLK_INV, lrclk);
1500 snd_soc_update_bits(codec, base + 5, WM5100_AIF1_FMT_MASK, mask);
1501
1502 return 0;
1503}
1504
1505#define WM5100_NUM_BCLK_RATES 19
1506
1507static int wm5100_bclk_rates_dat[WM5100_NUM_BCLK_RATES] = {
1508 32000,
1509 48000,
1510 64000,
1511 96000,
1512 128000,
1513 192000,
1514 384000,
1515 512000,
1516 768000,
1517 1024000,
1518 1536000,
1519 2048000,
1520 3072000,
1521 4096000,
1522 6144000,
1523 8192000,
1524 12288000,
1525 24576000,
1526};
1527
1528static int wm5100_bclk_rates_cd[WM5100_NUM_BCLK_RATES] = {
1529 29400,
1530 44100,
1531 58800,
1532 88200,
1533 117600,
1534 176400,
1535 235200,
1536 352800,
1537 470400,
1538 705600,
1539 940800,
1540 1411200,
1541 1881600,
1542 2882400,
1543 3763200,
1544 5644800,
1545 7526400,
1546 11289600,
1547 22579600,
1548};
1549
1550static int wm5100_hw_params(struct snd_pcm_substream *substream,
1551 struct snd_pcm_hw_params *params,
1552 struct snd_soc_dai *dai)
1553{
1554 struct snd_soc_codec *codec = dai->codec;
1555 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1556 bool async = wm5100->aif_async[dai->id];
1557 int i, base, bclk, aif_rate, lrclk, wl, fl, sr;
1558 int *bclk_rates;
1559
1560 base = wm5100_dai_to_base(dai);
1561 if (base < 0)
1562 return base;
1563
1564 /* Data sizes if not using TDM */
1565 wl = snd_pcm_format_width(params_format(params));
1566 if (wl < 0)
1567 return wl;
1568 fl = snd_soc_params_to_frame_size(params);
1569 if (fl < 0)
1570 return fl;
1571
1572 dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n",
1573 wl, fl);
1574
1575 /* Target BCLK rate */
1576 bclk = snd_soc_params_to_bclk(params);
1577 if (bclk < 0)
1578 return bclk;
1579
1580 /* Root for BCLK depends on SYS/ASYNCCLK */
1581 if (!async) {
1582 aif_rate = wm5100->sysclk;
1583 sr = wm5100_alloc_sr(codec, params_rate(params));
1584 if (sr < 0)
1585 return sr;
1586 } else {
1587 /* If we're in ASYNCCLK set the ASYNC sample rate */
1588 aif_rate = wm5100->asyncclk;
1589 sr = 3;
1590
1591 for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
1592 if (params_rate(params) == wm5100_sr_code[i])
1593 break;
1594 if (i == ARRAY_SIZE(wm5100_sr_code)) {
1595 dev_err(codec->dev, "Invalid rate %dHzn",
1596 params_rate(params));
1597 return -EINVAL;
1598 }
1599
1600 /* TODO: We should really check for symmetry */
1601 snd_soc_update_bits(codec, WM5100_CLOCKING_8,
1602 WM5100_ASYNC_SAMPLE_RATE_MASK, i);
1603 }
1604
1605 if (!aif_rate) {
1606 dev_err(codec->dev, "%s has no rate set\n",
1607 async ? "ASYNCCLK" : "SYSCLK");
1608 return -EINVAL;
1609 }
1610
1611 dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz %s\n",
1612 bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK");
1613
1614 if (aif_rate % 4000)
1615 bclk_rates = wm5100_bclk_rates_cd;
1616 else
1617 bclk_rates = wm5100_bclk_rates_dat;
1618
1619 for (i = 0; i < WM5100_NUM_BCLK_RATES; i++)
1620 if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0))
1621 break;
1622 if (i == WM5100_NUM_BCLK_RATES) {
1623 dev_err(codec->dev,
1624 "No valid BCLK for %dHz found from %dHz %s\n",
1625 bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK");
1626 return -EINVAL;
1627 }
1628
1629 bclk = i;
1630 dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
1631 snd_soc_update_bits(codec, base + 1, WM5100_AIF1_BCLK_FREQ_MASK, bclk);
1632
1633 lrclk = bclk_rates[bclk] / params_rate(params);
1634 dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
1635 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
1636 wm5100->aif_symmetric[dai->id])
1637 snd_soc_update_bits(codec, base + 7,
1638 WM5100_AIF1RX_BCPF_MASK, lrclk);
1639 else
1640 snd_soc_update_bits(codec, base + 6,
1641 WM5100_AIF1TX_BCPF_MASK, lrclk);
1642
1643 i = (wl << WM5100_AIF1TX_WL_SHIFT) | fl;
1644 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1645 snd_soc_update_bits(codec, base + 9,
1646 WM5100_AIF1RX_WL_MASK |
1647 WM5100_AIF1RX_SLOT_LEN_MASK, i);
1648 else
1649 snd_soc_update_bits(codec, base + 8,
1650 WM5100_AIF1TX_WL_MASK |
1651 WM5100_AIF1TX_SLOT_LEN_MASK, i);
1652
1653 snd_soc_update_bits(codec, base + 4, WM5100_AIF1_RATE_MASK, sr);
1654
1655 return 0;
1656}
1657
1658static struct snd_soc_dai_ops wm5100_dai_ops = {
1659 .set_fmt = wm5100_set_fmt,
1660 .hw_params = wm5100_hw_params,
1661};
1662
1663static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1664 int source, unsigned int freq, int dir)
1665{
1666 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1667 int *rate_store;
1668 int fval, audio_rate, ret, reg;
1669
1670 switch (clk_id) {
1671 case WM5100_CLK_SYSCLK:
1672 reg = WM5100_CLOCKING_3;
1673 rate_store = &wm5100->sysclk;
1674 break;
1675 case WM5100_CLK_ASYNCCLK:
1676 reg = WM5100_CLOCKING_7;
1677 rate_store = &wm5100->asyncclk;
1678 break;
1679 case WM5100_CLK_32KHZ:
1680 /* The 32kHz clock is slightly different to the others */
1681 switch (source) {
1682 case WM5100_CLKSRC_MCLK1:
1683 case WM5100_CLKSRC_MCLK2:
1684 case WM5100_CLKSRC_SYSCLK:
1685 snd_soc_update_bits(codec, WM5100_CLOCKING_1,
1686 WM5100_CLK_32K_SRC_MASK,
1687 source);
1688 break;
1689 default:
1690 return -EINVAL;
1691 }
1692 return 0;
1693
1694 case WM5100_CLK_AIF1:
1695 case WM5100_CLK_AIF2:
1696 case WM5100_CLK_AIF3:
1697 /* Not real clocks, record which clock domain they're in */
1698 switch (source) {
1699 case WM5100_CLKSRC_SYSCLK:
1700 wm5100->aif_async[clk_id - 1] = false;
1701 break;
1702 case WM5100_CLKSRC_ASYNCCLK:
1703 wm5100->aif_async[clk_id - 1] = true;
1704 break;
1705 default:
1706 dev_err(codec->dev, "Invalid source %d\n", source);
1707 return -EINVAL;
1708 }
1709 return 0;
1710
1711 case WM5100_CLK_OPCLK:
1712 switch (freq) {
1713 case 5644800:
1714 case 6144000:
1715 snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
1716 WM5100_OPCLK_SEL_MASK, 0);
1717 break;
1718 case 11289600:
1719 case 12288000:
1720 snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
1721 WM5100_OPCLK_SEL_MASK, 0);
1722 break;
1723 case 22579200:
1724 case 24576000:
1725 snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
1726 WM5100_OPCLK_SEL_MASK, 0);
1727 break;
1728 default:
1729 dev_err(codec->dev, "Unsupported OPCLK %dHz\n",
1730 freq);
1731 return -EINVAL;
1732 }
1733 return 0;
1734
1735 default:
1736 dev_err(codec->dev, "Unknown clock %d\n", clk_id);
1737 return -EINVAL;
1738 }
1739
1740 switch (source) {
1741 case WM5100_CLKSRC_SYSCLK:
1742 case WM5100_CLKSRC_ASYNCCLK:
1743 dev_err(codec->dev, "Invalid source %d\n", source);
1744 return -EINVAL;
1745 }
1746
1747 switch (freq) {
1748 case 5644800:
1749 case 6144000:
1750 fval = 0;
1751 break;
1752 case 11289600:
1753 case 12288000:
1754 fval = 1;
1755 break;
1756 case 22579200:
1757 case 2457600:
1758 fval = 2;
1759 break;
1760 default:
1761 dev_err(codec->dev, "Invalid clock rate: %d\n", freq);
1762 return -EINVAL;
1763 }
1764
1765 switch (freq) {
1766 case 5644800:
1767 case 11289600:
1768 case 22579200:
1769 audio_rate = 44100;
1770 break;
1771
1772 case 6144000:
1773 case 12288000:
1774 case 2457600:
1775 audio_rate = 48000;
1776 break;
1777
1778 default:
1779 BUG();
1780 audio_rate = 0;
1781 break;
1782 }
1783
1784 /* TODO: Check if MCLKs are in use and enable/disable pulls to
1785 * match.
1786 */
1787
1788 snd_soc_update_bits(codec, reg, WM5100_SYSCLK_FREQ_MASK |
1789 WM5100_SYSCLK_SRC_MASK,
1790 fval << WM5100_SYSCLK_FREQ_SHIFT | source);
1791
1792 /* If this is SYSCLK then configure the clock rate for the
1793 * internal audio functions to the natural sample rate for
1794 * this clock rate.
1795 */
1796 if (clk_id == WM5100_CLK_SYSCLK) {
1797 dev_dbg(codec->dev, "Setting primary audio rate to %dHz",
1798 audio_rate);
1799 if (0 && *rate_store)
1800 wm5100_free_sr(codec, audio_rate);
1801 ret = wm5100_alloc_sr(codec, audio_rate);
1802 if (ret != 0)
1803 dev_warn(codec->dev, "Primary audio slot is %d\n",
1804 ret);
1805 }
1806
1807 *rate_store = freq;
1808
1809 return 0;
1810}
1811
1812struct _fll_div {
1813 u16 fll_fratio;
1814 u16 fll_outdiv;
1815 u16 fll_refclk_div;
1816 u16 n;
1817 u16 theta;
1818 u16 lambda;
1819};
1820
1821static struct {
1822 unsigned int min;
1823 unsigned int max;
1824 u16 fll_fratio;
1825 int ratio;
1826} fll_fratios[] = {
1827 { 0, 64000, 4, 16 },
1828 { 64000, 128000, 3, 8 },
1829 { 128000, 256000, 2, 4 },
1830 { 256000, 1000000, 1, 2 },
1831 { 1000000, 13500000, 0, 1 },
1832};
1833
1834static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1835 unsigned int Fout)
1836{
1837 unsigned int target;
1838 unsigned int div;
1839 unsigned int fratio, gcd_fll;
1840 int i;
1841
1842 /* Fref must be <=13.5MHz */
1843 div = 1;
1844 fll_div->fll_refclk_div = 0;
1845 while ((Fref / div) > 13500000) {
1846 div *= 2;
1847 fll_div->fll_refclk_div++;
1848
1849 if (div > 8) {
1850 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1851 Fref);
1852 return -EINVAL;
1853 }
1854 }
1855
1856 pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
1857
1858 /* Apply the division for our remaining calculations */
1859 Fref /= div;
1860
1861 /* Fvco should be 90-100MHz; don't check the upper bound */
1862 div = 2;
1863 while (Fout * div < 90000000) {
1864 div++;
1865 if (div > 64) {
1866 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1867 Fout);
1868 return -EINVAL;
1869 }
1870 }
1871 target = Fout * div;
1872 fll_div->fll_outdiv = div - 1;
1873
1874 pr_debug("FLL Fvco=%dHz\n", target);
1875
1876 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1877 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1878 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1879 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1880 fratio = fll_fratios[i].ratio;
1881 break;
1882 }
1883 }
1884 if (i == ARRAY_SIZE(fll_fratios)) {
1885 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1886 return -EINVAL;
1887 }
1888
1889 fll_div->n = target / (fratio * Fref);
1890
1891 if (target % Fref == 0) {
1892 fll_div->theta = 0;
1893 fll_div->lambda = 0;
1894 } else {
1895 gcd_fll = gcd(target, fratio * Fref);
1896
1897 fll_div->theta = (target - (fll_div->n * fratio * Fref))
1898 / gcd_fll;
1899 fll_div->lambda = (fratio * Fref) / gcd_fll;
1900 }
1901
1902 pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
1903 fll_div->n, fll_div->theta, fll_div->lambda);
1904 pr_debug("FLL_FRATIO=%x(%d) FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
1905 fll_div->fll_fratio, fratio, fll_div->fll_outdiv,
1906 fll_div->fll_refclk_div);
1907
1908 return 0;
1909}
1910
1911static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1912 unsigned int Fref, unsigned int Fout)
1913{
1914 struct i2c_client *i2c = to_i2c_client(codec->dev);
1915 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1916 struct _fll_div factors;
1917 struct wm5100_fll *fll;
1918 int ret, base, lock, i, timeout;
1919
1920 switch (fll_id) {
1921 case WM5100_FLL1:
1922 fll = &wm5100->fll[0];
1923 base = WM5100_FLL1_CONTROL_1 - 1;
1924 lock = WM5100_FLL1_LOCK_STS;
1925 break;
1926 case WM5100_FLL2:
1927 fll = &wm5100->fll[1];
1928 base = WM5100_FLL2_CONTROL_2 - 1;
1929 lock = WM5100_FLL2_LOCK_STS;
1930 break;
1931 default:
1932 dev_err(codec->dev, "Unknown FLL %d\n",fll_id);
1933 return -EINVAL;
1934 }
1935
1936 if (!Fout) {
1937 dev_dbg(codec->dev, "FLL%d disabled", fll_id);
1938 fll->fout = 0;
1939 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
1940 return 0;
1941 }
1942
1943 switch (source) {
1944 case WM5100_FLL_SRC_MCLK1:
1945 case WM5100_FLL_SRC_MCLK2:
1946 case WM5100_FLL_SRC_FLL1:
1947 case WM5100_FLL_SRC_FLL2:
1948 case WM5100_FLL_SRC_AIF1BCLK:
1949 case WM5100_FLL_SRC_AIF2BCLK:
1950 case WM5100_FLL_SRC_AIF3BCLK:
1951 break;
1952 default:
1953 dev_err(codec->dev, "Invalid FLL source %d\n", source);
1954 return -EINVAL;
1955 }
1956
1957 ret = fll_factors(&factors, Fref, Fout);
1958 if (ret < 0)
1959 return ret;
1960
1961 /* Disable the FLL while we reconfigure */
1962 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
1963
1964 snd_soc_update_bits(codec, base + 2,
1965 WM5100_FLL1_OUTDIV_MASK | WM5100_FLL1_FRATIO_MASK,
1966 (factors.fll_outdiv << WM5100_FLL1_OUTDIV_SHIFT) |
1967 factors.fll_fratio);
1968 snd_soc_update_bits(codec, base + 3, WM5100_FLL1_THETA_MASK,
1969 factors.theta);
1970 snd_soc_update_bits(codec, base + 5, WM5100_FLL1_N_MASK, factors.n);
1971 snd_soc_update_bits(codec, base + 6,
1972 WM5100_FLL1_REFCLK_DIV_MASK |
1973 WM5100_FLL1_REFCLK_SRC_MASK,
1974 (factors.fll_refclk_div
1975 << WM5100_FLL1_REFCLK_DIV_SHIFT) | source);
1976 snd_soc_update_bits(codec, base + 7, WM5100_FLL1_LAMBDA_MASK,
1977 factors.lambda);
1978
1979 /* Clear any pending completions */
1980 try_wait_for_completion(&fll->lock);
1981
1982 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA);
1983
1984 if (i2c->irq)
1985 timeout = 2;
1986 else
1987 timeout = 50;
1988
1989 /* Poll for the lock; will use interrupt when we can test */
1990 for (i = 0; i < timeout; i++) {
1991 if (i2c->irq) {
1992 ret = wait_for_completion_timeout(&fll->lock,
1993 msecs_to_jiffies(25));
1994 if (ret > 0)
1995 break;
1996 } else {
1997 msleep(1);
1998 }
1999
2000 ret = snd_soc_read(codec,
2001 WM5100_INTERRUPT_RAW_STATUS_3);
2002 if (ret < 0) {
2003 dev_err(codec->dev,
2004 "Failed to read FLL status: %d\n",
2005 ret);
2006 continue;
2007 }
2008 if (ret & lock)
2009 break;
2010 }
2011 if (i == timeout) {
2012 dev_err(codec->dev, "FLL%d lock timed out\n", fll_id);
2013 return -ETIMEDOUT;
2014 }
2015
2016 fll->src = source;
2017 fll->fref = Fref;
2018 fll->fout = Fout;
2019
2020 dev_dbg(codec->dev, "FLL%d running %dHz->%dHz\n", fll_id,
2021 Fref, Fout);
2022
2023 return 0;
2024}
2025
2026/* Actually go much higher */
2027#define WM5100_RATES SNDRV_PCM_RATE_8000_192000
2028
2029#define WM5100_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2030 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
2031
2032static struct snd_soc_dai_driver wm5100_dai[] = {
2033 {
2034 .name = "wm5100-aif1",
2035 .playback = {
2036 .stream_name = "AIF1 Playback",
2037 .channels_min = 2,
2038 .channels_max = 2,
2039 .rates = WM5100_RATES,
2040 .formats = WM5100_FORMATS,
2041 },
2042 .capture = {
2043 .stream_name = "AIF1 Capture",
2044 .channels_min = 2,
2045 .channels_max = 2,
2046 .rates = WM5100_RATES,
2047 .formats = WM5100_FORMATS,
2048 },
2049 .ops = &wm5100_dai_ops,
2050 },
2051 {
2052 .name = "wm5100-aif2",
2053 .id = 1,
2054 .playback = {
2055 .stream_name = "AIF2 Playback",
2056 .channels_min = 2,
2057 .channels_max = 2,
2058 .rates = WM5100_RATES,
2059 .formats = WM5100_FORMATS,
2060 },
2061 .capture = {
2062 .stream_name = "AIF2 Capture",
2063 .channels_min = 2,
2064 .channels_max = 2,
2065 .rates = WM5100_RATES,
2066 .formats = WM5100_FORMATS,
2067 },
2068 .ops = &wm5100_dai_ops,
2069 },
2070 {
2071 .name = "wm5100-aif3",
2072 .id = 2,
2073 .playback = {
2074 .stream_name = "AIF3 Playback",
2075 .channels_min = 2,
2076 .channels_max = 2,
2077 .rates = WM5100_RATES,
2078 .formats = WM5100_FORMATS,
2079 },
2080 .capture = {
2081 .stream_name = "AIF3 Capture",
2082 .channels_min = 2,
2083 .channels_max = 2,
2084 .rates = WM5100_RATES,
2085 .formats = WM5100_FORMATS,
2086 },
2087 .ops = &wm5100_dai_ops,
2088 },
2089};
2090
2091static int wm5100_dig_vu[] = {
2092 WM5100_ADC_DIGITAL_VOLUME_1L,
2093 WM5100_ADC_DIGITAL_VOLUME_1R,
2094 WM5100_ADC_DIGITAL_VOLUME_2L,
2095 WM5100_ADC_DIGITAL_VOLUME_2R,
2096 WM5100_ADC_DIGITAL_VOLUME_3L,
2097 WM5100_ADC_DIGITAL_VOLUME_3R,
2098 WM5100_ADC_DIGITAL_VOLUME_4L,
2099 WM5100_ADC_DIGITAL_VOLUME_4R,
2100
2101 WM5100_DAC_DIGITAL_VOLUME_1L,
2102 WM5100_DAC_DIGITAL_VOLUME_1R,
2103 WM5100_DAC_DIGITAL_VOLUME_2L,
2104 WM5100_DAC_DIGITAL_VOLUME_2R,
2105 WM5100_DAC_DIGITAL_VOLUME_3L,
2106 WM5100_DAC_DIGITAL_VOLUME_3R,
2107 WM5100_DAC_DIGITAL_VOLUME_4L,
2108 WM5100_DAC_DIGITAL_VOLUME_4R,
2109 WM5100_DAC_DIGITAL_VOLUME_5L,
2110 WM5100_DAC_DIGITAL_VOLUME_5R,
2111 WM5100_DAC_DIGITAL_VOLUME_6L,
2112 WM5100_DAC_DIGITAL_VOLUME_6R,
2113};
2114
2115static irqreturn_t wm5100_irq(int irq, void *data)
2116{
2117 struct snd_soc_codec *codec = data;
2118 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2119 irqreturn_t status = IRQ_NONE;
2120 int irq_val;
2121
2122 irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3);
2123 if (irq_val < 0) {
2124 dev_err(codec->dev, "Failed to read IRQ status 3: %d\n",
2125 irq_val);
2126 irq_val = 0;
2127 }
2128 irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3_MASK);
2129
2130 snd_soc_write(codec, WM5100_INTERRUPT_STATUS_3, irq_val);
2131
2132 if (irq_val)
2133 status = IRQ_HANDLED;
2134
2135 wm5100_log_status3(codec, irq_val);
2136
2137 if (irq_val & WM5100_FLL1_LOCK_EINT) {
2138 dev_dbg(codec->dev, "FLL1 locked\n");
2139 complete(&wm5100->fll[0].lock);
2140 }
2141 if (irq_val & WM5100_FLL2_LOCK_EINT) {
2142 dev_dbg(codec->dev, "FLL2 locked\n");
2143 complete(&wm5100->fll[1].lock);
2144 }
2145
2146 irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4);
2147 if (irq_val < 0) {
2148 dev_err(codec->dev, "Failed to read IRQ status 4: %d\n",
2149 irq_val);
2150 irq_val = 0;
2151 }
2152 irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4_MASK);
2153
2154 if (irq_val)
2155 status = IRQ_HANDLED;
2156
2157 snd_soc_write(codec, WM5100_INTERRUPT_STATUS_4, irq_val);
2158
2159 wm5100_log_status4(codec, irq_val);
2160
2161 return status;
2162}
2163
2164static irqreturn_t wm5100_edge_irq(int irq, void *data)
2165{
2166 irqreturn_t ret = IRQ_NONE;
2167 irqreturn_t val;
2168
2169 do {
2170 val = wm5100_irq(irq, data);
2171 if (val != IRQ_NONE)
2172 ret = val;
2173 } while (val != IRQ_NONE);
2174
2175 return ret;
2176}
2177
2178#ifdef CONFIG_GPIOLIB
2179static inline struct wm5100_priv *gpio_to_wm5100(struct gpio_chip *chip)
2180{
2181 return container_of(chip, struct wm5100_priv, gpio_chip);
2182}
2183
2184static void wm5100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
2185{
2186 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2187 struct snd_soc_codec *codec = wm5100->codec;
2188
2189 snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
2190 WM5100_GP1_LVL, !!value << WM5100_GP1_LVL_SHIFT);
2191}
2192
2193static int wm5100_gpio_direction_out(struct gpio_chip *chip,
2194 unsigned offset, int value)
2195{
2196 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2197 struct snd_soc_codec *codec = wm5100->codec;
2198 int val;
2199
2200 val = (1 << WM5100_GP1_FN_SHIFT) | (!!value << WM5100_GP1_LVL_SHIFT);
2201
2202 return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
2203 WM5100_GP1_FN_MASK | WM5100_GP1_DIR |
2204 WM5100_GP1_LVL, val);
2205}
2206
2207static int wm5100_gpio_get(struct gpio_chip *chip, unsigned offset)
2208{
2209 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2210 struct snd_soc_codec *codec = wm5100->codec;
2211 int ret;
2212
2213 ret = snd_soc_read(codec, WM5100_GPIO_CTRL_1 + offset);
2214 if (ret < 0)
2215 return ret;
2216
2217 return (ret & WM5100_GP1_LVL) != 0;
2218}
2219
2220static int wm5100_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
2221{
2222 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2223 struct snd_soc_codec *codec = wm5100->codec;
2224
2225 return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
2226 WM5100_GP1_FN_MASK | WM5100_GP1_DIR,
2227 (1 << WM5100_GP1_FN_SHIFT) |
2228 (1 << WM5100_GP1_DIR_SHIFT));
2229}
2230
2231static struct gpio_chip wm5100_template_chip = {
2232 .label = "wm5100",
2233 .owner = THIS_MODULE,
2234 .direction_output = wm5100_gpio_direction_out,
2235 .set = wm5100_gpio_set,
2236 .direction_input = wm5100_gpio_direction_in,
2237 .get = wm5100_gpio_get,
2238 .can_sleep = 1,
2239};
2240
2241static void wm5100_init_gpio(struct snd_soc_codec *codec)
2242{
2243 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2244 int ret;
2245
2246 wm5100->gpio_chip = wm5100_template_chip;
2247 wm5100->gpio_chip.ngpio = 6;
2248 wm5100->gpio_chip.dev = codec->dev;
2249
2250 if (wm5100->pdata.gpio_base)
2251 wm5100->gpio_chip.base = wm5100->pdata.gpio_base;
2252 else
2253 wm5100->gpio_chip.base = -1;
2254
2255 ret = gpiochip_add(&wm5100->gpio_chip);
2256 if (ret != 0)
2257 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
2258}
2259
2260static void wm5100_free_gpio(struct snd_soc_codec *codec)
2261{
2262 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2263 int ret;
2264
2265 ret = gpiochip_remove(&wm5100->gpio_chip);
2266 if (ret != 0)
2267 dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
2268}
2269#else
2270static void wm5100_init_gpio(struct snd_soc_codec *codec)
2271{
2272}
2273
2274static void wm5100_free_gpio(struct snd_soc_codec *codec)
2275{
2276}
2277#endif
2278
2279static int wm5100_probe(struct snd_soc_codec *codec)
2280{
2281 struct i2c_client *i2c = to_i2c_client(codec->dev);
2282 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2283 int ret, i, irq_flags;
2284
2285 wm5100->codec = codec;
2286
2287 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
2288
2289 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
2290 if (ret != 0) {
2291 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2292 return ret;
2293 }
2294
2295 for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++)
2296 wm5100->core_supplies[i].supply = wm5100_core_supply_names[i];
2297
2298 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm5100->core_supplies),
2299 wm5100->core_supplies);
2300 if (ret != 0) {
2301 dev_err(codec->dev, "Failed to request core supplies: %d\n",
2302 ret);
2303 return ret;
2304 }
2305
2306 wm5100->cpvdd = regulator_get(&i2c->dev, "CPVDD");
2307 if (IS_ERR(wm5100->cpvdd)) {
2308 ret = PTR_ERR(wm5100->cpvdd);
2309 dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
2310 goto err_core;
2311 }
2312
7aefb086
MB
2313 wm5100->dbvdd2 = regulator_get(&i2c->dev, "DBVDD2");
2314 if (IS_ERR(wm5100->dbvdd2)) {
2315 ret = PTR_ERR(wm5100->dbvdd2);
2316 dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
2317 goto err_cpvdd;
2318 }
2319
2320 wm5100->dbvdd3 = regulator_get(&i2c->dev, "DBVDD3");
2321 if (IS_ERR(wm5100->dbvdd3)) {
2322 ret = PTR_ERR(wm5100->dbvdd3);
2323 dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
2324 goto err_dbvdd2;
2325 }
2326
6d4baf08
MB
2327 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
2328 wm5100->core_supplies);
2329 if (ret != 0) {
2330 dev_err(codec->dev, "Failed to enable core supplies: %d\n",
2331 ret);
7aefb086 2332 goto err_dbvdd3;
6d4baf08
MB
2333 }
2334
2335 if (wm5100->pdata.ldo_ena) {
2336 ret = gpio_request_one(wm5100->pdata.ldo_ena,
2337 GPIOF_OUT_INIT_HIGH, "WM5100 LDOENA");
2338 if (ret < 0) {
2339 dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n",
2340 wm5100->pdata.ldo_ena, ret);
2341 goto err_enable;
2342 }
2343 msleep(2);
2344 }
2345
2346 if (wm5100->pdata.reset) {
2347 ret = gpio_request_one(wm5100->pdata.reset,
2348 GPIOF_OUT_INIT_HIGH, "WM5100 /RESET");
2349 if (ret < 0) {
2350 dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n",
2351 wm5100->pdata.reset, ret);
2352 goto err_ldo;
2353 }
2354 }
2355
2356 ret = snd_soc_read(codec, WM5100_SOFTWARE_RESET);
2357 if (ret < 0) {
2358 dev_err(codec->dev, "Failed to read ID register\n");
2359 goto err_reset;
2360 }
2361 switch (ret) {
2362 case 0x8997:
2363 case 0x5100:
2364 break;
2365
2366 default:
2367 dev_err(codec->dev, "Device is not a WM5100, ID is %x\n", ret);
2368 ret = -EINVAL;
2369 goto err_reset;
2370 }
2371
2372 ret = snd_soc_read(codec, WM5100_DEVICE_REVISION);
2373 if (ret < 0) {
2374 dev_err(codec->dev, "Failed to read revision register\n");
2375 goto err_reset;
2376 }
2377 wm5100->rev = ret & WM5100_DEVICE_REVISION_MASK;
2378
2379 dev_info(codec->dev, "revision %c\n", wm5100->rev + 'A');
2380
2381 ret = wm5100_reset(codec);
2382 if (ret < 0) {
2383 dev_err(codec->dev, "Failed to issue reset\n");
2384 goto err_reset;
2385 }
2386
2387 codec->cache_only = true;
2388
2389 wm5100_init_gpio(codec);
2390
2391 for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++)
2392 snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU,
2393 WM5100_OUT_VU);
2394
2395 for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) {
2396 snd_soc_update_bits(codec, WM5100_IN1L_CONTROL,
2397 WM5100_IN1_MODE_MASK |
2398 WM5100_IN1_DMIC_SUP_MASK,
2399 (wm5100->pdata.in_mode[i] <<
2400 WM5100_IN1_MODE_SHIFT) |
2401 (wm5100->pdata.dmic_sup[i] <<
2402 WM5100_IN1_DMIC_SUP_SHIFT));
2403 }
2404
2405 for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) {
2406 if (!wm5100->pdata.gpio_defaults[i])
2407 continue;
2408
2409 snd_soc_write(codec, WM5100_GPIO_CTRL_1 + i,
2410 wm5100->pdata.gpio_defaults[i]);
2411 }
2412
2413 /* Don't debounce interrupts to support use of SYSCLK only */
2414 snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_1, 0);
2415 snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_2, 0);
2416
2417 /* TODO: check if we're symmetric */
2418
2419 if (i2c->irq) {
2420 if (wm5100->pdata.irq_flags)
2421 irq_flags = wm5100->pdata.irq_flags;
2422 else
2423 irq_flags = IRQF_TRIGGER_LOW;
2424
2425 irq_flags |= IRQF_ONESHOT;
2426
2427 if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
2428 ret = request_threaded_irq(i2c->irq, NULL,
2429 wm5100_edge_irq,
2430 irq_flags, "wm5100", codec);
2431 else
2432 ret = request_threaded_irq(i2c->irq, NULL, wm5100_irq,
2433 irq_flags, "wm5100", codec);
2434
2435 if (ret != 0) {
2436 dev_err(codec->dev, "Failed to request IRQ %d: %d\n",
2437 i2c->irq, ret);
2438 } else {
2439 /* Enable default interrupts */
2440 snd_soc_update_bits(codec,
2441 WM5100_INTERRUPT_STATUS_3_MASK,
2442 WM5100_IM_SPK_SHUTDOWN_WARN_EINT |
2443 WM5100_IM_SPK_SHUTDOWN_EINT |
2444 WM5100_IM_ASRC2_LOCK_EINT |
2445 WM5100_IM_ASRC1_LOCK_EINT |
2446 WM5100_IM_FLL2_LOCK_EINT |
2447 WM5100_IM_FLL1_LOCK_EINT |
2448 WM5100_CLKGEN_ERR_EINT |
2449 WM5100_CLKGEN_ERR_ASYNC_EINT, 0);
2450
2451 snd_soc_update_bits(codec,
2452 WM5100_INTERRUPT_STATUS_4_MASK,
2453 WM5100_AIF3_ERR_EINT |
2454 WM5100_AIF2_ERR_EINT |
2455 WM5100_AIF1_ERR_EINT |
2456 WM5100_CTRLIF_ERR_EINT |
2457 WM5100_ISRC2_UNDERCLOCKED_EINT |
2458 WM5100_ISRC1_UNDERCLOCKED_EINT |
2459 WM5100_FX_UNDERCLOCKED_EINT |
2460 WM5100_AIF3_UNDERCLOCKED_EINT |
2461 WM5100_AIF2_UNDERCLOCKED_EINT |
2462 WM5100_AIF1_UNDERCLOCKED_EINT |
2463 WM5100_ASRC_UNDERCLOCKED_EINT |
2464 WM5100_DAC_UNDERCLOCKED_EINT |
2465 WM5100_ADC_UNDERCLOCKED_EINT |
2466 WM5100_MIXER_UNDERCLOCKED_EINT, 0);
2467 }
2468 } else {
2469 snd_soc_dapm_new_controls(&codec->dapm,
2470 wm5100_dapm_widgets_noirq,
2471 ARRAY_SIZE(wm5100_dapm_widgets_noirq));
2472 }
2473
2474 if (wm5100->pdata.hp_pol) {
2475 ret = gpio_request_one(wm5100->pdata.hp_pol,
2476 GPIOF_OUT_INIT_HIGH, "WM5100 HP_POL");
2477 if (ret < 0) {
2478 dev_err(&i2c->dev, "Failed to request HP_POL %d: %d\n",
2479 wm5100->pdata.hp_pol, ret);
2480 goto err_gpio;
2481 }
2482 }
2483
2484 /* We'll get woken up again when the system has something useful
2485 * for us to do.
2486 */
2487 if (wm5100->pdata.ldo_ena)
2488 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2489 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2490 wm5100->core_supplies);
2491
2492 return 0;
2493
2494err_gpio:
2495 wm5100_free_gpio(codec);
2496err_reset:
2497 if (wm5100->pdata.reset) {
2498 gpio_set_value_cansleep(wm5100->pdata.reset, 1);
2499 gpio_free(wm5100->pdata.reset);
2500 }
2501err_ldo:
2502 if (wm5100->pdata.ldo_ena) {
2503 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2504 gpio_free(wm5100->pdata.ldo_ena);
2505 }
2506err_enable:
2507 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2508 wm5100->core_supplies);
7aefb086
MB
2509err_dbvdd3:
2510 regulator_put(wm5100->dbvdd3);
2511err_dbvdd2:
2512 regulator_put(wm5100->dbvdd2);
6d4baf08
MB
2513err_cpvdd:
2514 regulator_put(wm5100->cpvdd);
2515err_core:
2516 regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
2517 wm5100->core_supplies);
2518
2519 return ret;
2520}
2521
2522static int wm5100_remove(struct snd_soc_codec *codec)
2523{
2524 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2525
2526 wm5100_set_bias_level(codec, SND_SOC_BIAS_OFF);
2527 if (wm5100->pdata.hp_pol) {
2528 gpio_free(wm5100->pdata.hp_pol);
2529 }
2530 wm5100_free_gpio(codec);
2531 if (wm5100->pdata.reset) {
2532 gpio_set_value_cansleep(wm5100->pdata.reset, 1);
2533 gpio_free(wm5100->pdata.reset);
2534 }
2535 if (wm5100->pdata.ldo_ena) {
2536 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2537 gpio_free(wm5100->pdata.ldo_ena);
2538 }
7aefb086
MB
2539 regulator_put(wm5100->dbvdd3);
2540 regulator_put(wm5100->dbvdd2);
6d4baf08
MB
2541 regulator_put(wm5100->cpvdd);
2542 regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
2543 wm5100->core_supplies);
2544 return 0;
2545}
2546
2547static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
2548 .probe = wm5100_probe,
2549 .remove = wm5100_remove,
2550
2551 .set_sysclk = wm5100_set_sysclk,
2552 .set_pll = wm5100_set_fll,
2553 .set_bias_level = wm5100_set_bias_level,
2554 .idle_bias_off = 1,
2555
2556 .seq_notifier = wm5100_seq_notifier,
2557 .controls = wm5100_snd_controls,
2558 .num_controls = ARRAY_SIZE(wm5100_snd_controls),
2559 .dapm_widgets = wm5100_dapm_widgets,
2560 .num_dapm_widgets = ARRAY_SIZE(wm5100_dapm_widgets),
2561 .dapm_routes = wm5100_dapm_routes,
2562 .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes),
2563
2564 .reg_cache_size = ARRAY_SIZE(wm5100_reg_defaults),
2565 .reg_word_size = sizeof(u16),
2566 .compress_type = SND_SOC_RBTREE_COMPRESSION,
2567 .reg_cache_default = wm5100_reg_defaults,
2568
2569 .volatile_register = wm5100_volatile_register,
2570 .readable_register = wm5100_readable_register,
2571};
2572
2573static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2574 const struct i2c_device_id *id)
2575{
2576 struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev);
2577 struct wm5100_priv *wm5100;
2578 int ret, i;
2579
2580 wm5100 = kzalloc(sizeof(struct wm5100_priv), GFP_KERNEL);
2581 if (wm5100 == NULL)
2582 return -ENOMEM;
2583
2584 for (i = 0; i < ARRAY_SIZE(wm5100->fll); i++)
2585 init_completion(&wm5100->fll[i].lock);
2586
2587 if (pdata)
2588 wm5100->pdata = *pdata;
2589
2590 i2c_set_clientdata(i2c, wm5100);
2591
2592 ret = snd_soc_register_codec(&i2c->dev,
2593 &soc_codec_dev_wm5100, wm5100_dai,
2594 ARRAY_SIZE(wm5100_dai));
2595 if (ret < 0) {
2596 dev_err(&i2c->dev, "Failed to register WM5100: %d\n", ret);
2597 kfree(wm5100);
2598 }
2599
2600 return ret;
2601}
2602
2603static __devexit int wm5100_i2c_remove(struct i2c_client *client)
2604{
2605 snd_soc_unregister_codec(&client->dev);
2606 kfree(i2c_get_clientdata(client));
2607 return 0;
2608}
2609
2610static const struct i2c_device_id wm5100_i2c_id[] = {
2611 { "wm5100", 0 },
2612 { }
2613};
2614MODULE_DEVICE_TABLE(i2c, wm5100_i2c_id);
2615
2616static struct i2c_driver wm5100_i2c_driver = {
2617 .driver = {
2618 .name = "wm5100",
2619 .owner = THIS_MODULE,
2620 },
2621 .probe = wm5100_i2c_probe,
2622 .remove = __devexit_p(wm5100_i2c_remove),
2623 .id_table = wm5100_i2c_id,
2624};
2625
2626static int __init wm5100_modinit(void)
2627{
2628 return i2c_add_driver(&wm5100_i2c_driver);
2629}
2630module_init(wm5100_modinit);
2631
2632static void __exit wm5100_exit(void)
2633{
2634 i2c_del_driver(&wm5100_i2c_driver);
2635}
2636module_exit(wm5100_exit);
2637
2638MODULE_DESCRIPTION("ASoC WM5100 driver");
2639MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2640MODULE_LICENSE("GPL");
This page took 0.12219 seconds and 5 git commands to generate.