ASoC: Instantiate DAPM widgets before we do the DAI link init
[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,
d73ec75c 1514 256000,
6d4baf08
MB
1515 384000,
1516 512000,
1517 768000,
1518 1024000,
1519 1536000,
1520 2048000,
1521 3072000,
1522 4096000,
1523 6144000,
1524 8192000,
1525 12288000,
1526 24576000,
1527};
1528
1529static int wm5100_bclk_rates_cd[WM5100_NUM_BCLK_RATES] = {
1530 29400,
1531 44100,
1532 58800,
1533 88200,
1534 117600,
1535 176400,
1536 235200,
1537 352800,
1538 470400,
1539 705600,
1540 940800,
1541 1411200,
1542 1881600,
1543 2882400,
1544 3763200,
1545 5644800,
1546 7526400,
1547 11289600,
1548 22579600,
1549};
1550
1551static int wm5100_hw_params(struct snd_pcm_substream *substream,
1552 struct snd_pcm_hw_params *params,
1553 struct snd_soc_dai *dai)
1554{
1555 struct snd_soc_codec *codec = dai->codec;
1556 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1557 bool async = wm5100->aif_async[dai->id];
1558 int i, base, bclk, aif_rate, lrclk, wl, fl, sr;
1559 int *bclk_rates;
1560
1561 base = wm5100_dai_to_base(dai);
1562 if (base < 0)
1563 return base;
1564
1565 /* Data sizes if not using TDM */
1566 wl = snd_pcm_format_width(params_format(params));
1567 if (wl < 0)
1568 return wl;
1569 fl = snd_soc_params_to_frame_size(params);
1570 if (fl < 0)
1571 return fl;
1572
1573 dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n",
1574 wl, fl);
1575
1576 /* Target BCLK rate */
1577 bclk = snd_soc_params_to_bclk(params);
1578 if (bclk < 0)
1579 return bclk;
1580
1581 /* Root for BCLK depends on SYS/ASYNCCLK */
1582 if (!async) {
1583 aif_rate = wm5100->sysclk;
1584 sr = wm5100_alloc_sr(codec, params_rate(params));
1585 if (sr < 0)
1586 return sr;
1587 } else {
1588 /* If we're in ASYNCCLK set the ASYNC sample rate */
1589 aif_rate = wm5100->asyncclk;
1590 sr = 3;
1591
1592 for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
1593 if (params_rate(params) == wm5100_sr_code[i])
1594 break;
1595 if (i == ARRAY_SIZE(wm5100_sr_code)) {
1596 dev_err(codec->dev, "Invalid rate %dHzn",
1597 params_rate(params));
1598 return -EINVAL;
1599 }
1600
1601 /* TODO: We should really check for symmetry */
1602 snd_soc_update_bits(codec, WM5100_CLOCKING_8,
1603 WM5100_ASYNC_SAMPLE_RATE_MASK, i);
1604 }
1605
1606 if (!aif_rate) {
1607 dev_err(codec->dev, "%s has no rate set\n",
1608 async ? "ASYNCCLK" : "SYSCLK");
1609 return -EINVAL;
1610 }
1611
1612 dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz %s\n",
1613 bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK");
1614
1615 if (aif_rate % 4000)
1616 bclk_rates = wm5100_bclk_rates_cd;
1617 else
1618 bclk_rates = wm5100_bclk_rates_dat;
1619
1620 for (i = 0; i < WM5100_NUM_BCLK_RATES; i++)
1621 if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0))
1622 break;
1623 if (i == WM5100_NUM_BCLK_RATES) {
1624 dev_err(codec->dev,
1625 "No valid BCLK for %dHz found from %dHz %s\n",
1626 bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK");
1627 return -EINVAL;
1628 }
1629
1630 bclk = i;
1631 dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
1632 snd_soc_update_bits(codec, base + 1, WM5100_AIF1_BCLK_FREQ_MASK, bclk);
1633
1634 lrclk = bclk_rates[bclk] / params_rate(params);
1635 dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
1636 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
1637 wm5100->aif_symmetric[dai->id])
1638 snd_soc_update_bits(codec, base + 7,
1639 WM5100_AIF1RX_BCPF_MASK, lrclk);
1640 else
1641 snd_soc_update_bits(codec, base + 6,
1642 WM5100_AIF1TX_BCPF_MASK, lrclk);
1643
1644 i = (wl << WM5100_AIF1TX_WL_SHIFT) | fl;
1645 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1646 snd_soc_update_bits(codec, base + 9,
1647 WM5100_AIF1RX_WL_MASK |
1648 WM5100_AIF1RX_SLOT_LEN_MASK, i);
1649 else
1650 snd_soc_update_bits(codec, base + 8,
1651 WM5100_AIF1TX_WL_MASK |
1652 WM5100_AIF1TX_SLOT_LEN_MASK, i);
1653
1654 snd_soc_update_bits(codec, base + 4, WM5100_AIF1_RATE_MASK, sr);
1655
1656 return 0;
1657}
1658
1659static struct snd_soc_dai_ops wm5100_dai_ops = {
1660 .set_fmt = wm5100_set_fmt,
1661 .hw_params = wm5100_hw_params,
1662};
1663
1664static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1665 int source, unsigned int freq, int dir)
1666{
1667 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1668 int *rate_store;
1669 int fval, audio_rate, ret, reg;
1670
1671 switch (clk_id) {
1672 case WM5100_CLK_SYSCLK:
1673 reg = WM5100_CLOCKING_3;
1674 rate_store = &wm5100->sysclk;
1675 break;
1676 case WM5100_CLK_ASYNCCLK:
1677 reg = WM5100_CLOCKING_7;
1678 rate_store = &wm5100->asyncclk;
1679 break;
1680 case WM5100_CLK_32KHZ:
1681 /* The 32kHz clock is slightly different to the others */
1682 switch (source) {
1683 case WM5100_CLKSRC_MCLK1:
1684 case WM5100_CLKSRC_MCLK2:
1685 case WM5100_CLKSRC_SYSCLK:
1686 snd_soc_update_bits(codec, WM5100_CLOCKING_1,
1687 WM5100_CLK_32K_SRC_MASK,
1688 source);
1689 break;
1690 default:
1691 return -EINVAL;
1692 }
1693 return 0;
1694
1695 case WM5100_CLK_AIF1:
1696 case WM5100_CLK_AIF2:
1697 case WM5100_CLK_AIF3:
1698 /* Not real clocks, record which clock domain they're in */
1699 switch (source) {
1700 case WM5100_CLKSRC_SYSCLK:
1701 wm5100->aif_async[clk_id - 1] = false;
1702 break;
1703 case WM5100_CLKSRC_ASYNCCLK:
1704 wm5100->aif_async[clk_id - 1] = true;
1705 break;
1706 default:
1707 dev_err(codec->dev, "Invalid source %d\n", source);
1708 return -EINVAL;
1709 }
1710 return 0;
1711
1712 case WM5100_CLK_OPCLK:
1713 switch (freq) {
1714 case 5644800:
1715 case 6144000:
1716 snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
1717 WM5100_OPCLK_SEL_MASK, 0);
1718 break;
1719 case 11289600:
1720 case 12288000:
1721 snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
1722 WM5100_OPCLK_SEL_MASK, 0);
1723 break;
1724 case 22579200:
1725 case 24576000:
1726 snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
1727 WM5100_OPCLK_SEL_MASK, 0);
1728 break;
1729 default:
1730 dev_err(codec->dev, "Unsupported OPCLK %dHz\n",
1731 freq);
1732 return -EINVAL;
1733 }
1734 return 0;
1735
1736 default:
1737 dev_err(codec->dev, "Unknown clock %d\n", clk_id);
1738 return -EINVAL;
1739 }
1740
1741 switch (source) {
1742 case WM5100_CLKSRC_SYSCLK:
1743 case WM5100_CLKSRC_ASYNCCLK:
1744 dev_err(codec->dev, "Invalid source %d\n", source);
1745 return -EINVAL;
1746 }
1747
1748 switch (freq) {
1749 case 5644800:
1750 case 6144000:
1751 fval = 0;
1752 break;
1753 case 11289600:
1754 case 12288000:
1755 fval = 1;
1756 break;
1757 case 22579200:
1758 case 2457600:
1759 fval = 2;
1760 break;
1761 default:
1762 dev_err(codec->dev, "Invalid clock rate: %d\n", freq);
1763 return -EINVAL;
1764 }
1765
1766 switch (freq) {
1767 case 5644800:
1768 case 11289600:
1769 case 22579200:
1770 audio_rate = 44100;
1771 break;
1772
1773 case 6144000:
1774 case 12288000:
1775 case 2457600:
1776 audio_rate = 48000;
1777 break;
1778
1779 default:
1780 BUG();
1781 audio_rate = 0;
1782 break;
1783 }
1784
1785 /* TODO: Check if MCLKs are in use and enable/disable pulls to
1786 * match.
1787 */
1788
1789 snd_soc_update_bits(codec, reg, WM5100_SYSCLK_FREQ_MASK |
1790 WM5100_SYSCLK_SRC_MASK,
1791 fval << WM5100_SYSCLK_FREQ_SHIFT | source);
1792
1793 /* If this is SYSCLK then configure the clock rate for the
1794 * internal audio functions to the natural sample rate for
1795 * this clock rate.
1796 */
1797 if (clk_id == WM5100_CLK_SYSCLK) {
1798 dev_dbg(codec->dev, "Setting primary audio rate to %dHz",
1799 audio_rate);
1800 if (0 && *rate_store)
1801 wm5100_free_sr(codec, audio_rate);
1802 ret = wm5100_alloc_sr(codec, audio_rate);
1803 if (ret != 0)
1804 dev_warn(codec->dev, "Primary audio slot is %d\n",
1805 ret);
1806 }
1807
1808 *rate_store = freq;
1809
1810 return 0;
1811}
1812
1813struct _fll_div {
1814 u16 fll_fratio;
1815 u16 fll_outdiv;
1816 u16 fll_refclk_div;
1817 u16 n;
1818 u16 theta;
1819 u16 lambda;
1820};
1821
1822static struct {
1823 unsigned int min;
1824 unsigned int max;
1825 u16 fll_fratio;
1826 int ratio;
1827} fll_fratios[] = {
1828 { 0, 64000, 4, 16 },
1829 { 64000, 128000, 3, 8 },
1830 { 128000, 256000, 2, 4 },
1831 { 256000, 1000000, 1, 2 },
1832 { 1000000, 13500000, 0, 1 },
1833};
1834
1835static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1836 unsigned int Fout)
1837{
1838 unsigned int target;
1839 unsigned int div;
1840 unsigned int fratio, gcd_fll;
1841 int i;
1842
1843 /* Fref must be <=13.5MHz */
1844 div = 1;
1845 fll_div->fll_refclk_div = 0;
1846 while ((Fref / div) > 13500000) {
1847 div *= 2;
1848 fll_div->fll_refclk_div++;
1849
1850 if (div > 8) {
1851 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1852 Fref);
1853 return -EINVAL;
1854 }
1855 }
1856
1857 pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
1858
1859 /* Apply the division for our remaining calculations */
1860 Fref /= div;
1861
1862 /* Fvco should be 90-100MHz; don't check the upper bound */
1863 div = 2;
1864 while (Fout * div < 90000000) {
1865 div++;
1866 if (div > 64) {
1867 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1868 Fout);
1869 return -EINVAL;
1870 }
1871 }
1872 target = Fout * div;
1873 fll_div->fll_outdiv = div - 1;
1874
1875 pr_debug("FLL Fvco=%dHz\n", target);
1876
1877 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1878 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1879 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1880 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1881 fratio = fll_fratios[i].ratio;
1882 break;
1883 }
1884 }
1885 if (i == ARRAY_SIZE(fll_fratios)) {
1886 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1887 return -EINVAL;
1888 }
1889
1890 fll_div->n = target / (fratio * Fref);
1891
1892 if (target % Fref == 0) {
1893 fll_div->theta = 0;
1894 fll_div->lambda = 0;
1895 } else {
1896 gcd_fll = gcd(target, fratio * Fref);
1897
1898 fll_div->theta = (target - (fll_div->n * fratio * Fref))
1899 / gcd_fll;
1900 fll_div->lambda = (fratio * Fref) / gcd_fll;
1901 }
1902
1903 pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
1904 fll_div->n, fll_div->theta, fll_div->lambda);
1905 pr_debug("FLL_FRATIO=%x(%d) FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
1906 fll_div->fll_fratio, fratio, fll_div->fll_outdiv,
1907 fll_div->fll_refclk_div);
1908
1909 return 0;
1910}
1911
1912static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1913 unsigned int Fref, unsigned int Fout)
1914{
1915 struct i2c_client *i2c = to_i2c_client(codec->dev);
1916 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1917 struct _fll_div factors;
1918 struct wm5100_fll *fll;
1919 int ret, base, lock, i, timeout;
1920
1921 switch (fll_id) {
1922 case WM5100_FLL1:
1923 fll = &wm5100->fll[0];
1924 base = WM5100_FLL1_CONTROL_1 - 1;
1925 lock = WM5100_FLL1_LOCK_STS;
1926 break;
1927 case WM5100_FLL2:
1928 fll = &wm5100->fll[1];
1929 base = WM5100_FLL2_CONTROL_2 - 1;
1930 lock = WM5100_FLL2_LOCK_STS;
1931 break;
1932 default:
1933 dev_err(codec->dev, "Unknown FLL %d\n",fll_id);
1934 return -EINVAL;
1935 }
1936
1937 if (!Fout) {
1938 dev_dbg(codec->dev, "FLL%d disabled", fll_id);
1939 fll->fout = 0;
1940 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
1941 return 0;
1942 }
1943
1944 switch (source) {
1945 case WM5100_FLL_SRC_MCLK1:
1946 case WM5100_FLL_SRC_MCLK2:
1947 case WM5100_FLL_SRC_FLL1:
1948 case WM5100_FLL_SRC_FLL2:
1949 case WM5100_FLL_SRC_AIF1BCLK:
1950 case WM5100_FLL_SRC_AIF2BCLK:
1951 case WM5100_FLL_SRC_AIF3BCLK:
1952 break;
1953 default:
1954 dev_err(codec->dev, "Invalid FLL source %d\n", source);
1955 return -EINVAL;
1956 }
1957
1958 ret = fll_factors(&factors, Fref, Fout);
1959 if (ret < 0)
1960 return ret;
1961
1962 /* Disable the FLL while we reconfigure */
1963 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
1964
1965 snd_soc_update_bits(codec, base + 2,
1966 WM5100_FLL1_OUTDIV_MASK | WM5100_FLL1_FRATIO_MASK,
1967 (factors.fll_outdiv << WM5100_FLL1_OUTDIV_SHIFT) |
1968 factors.fll_fratio);
1969 snd_soc_update_bits(codec, base + 3, WM5100_FLL1_THETA_MASK,
1970 factors.theta);
1971 snd_soc_update_bits(codec, base + 5, WM5100_FLL1_N_MASK, factors.n);
1972 snd_soc_update_bits(codec, base + 6,
1973 WM5100_FLL1_REFCLK_DIV_MASK |
1974 WM5100_FLL1_REFCLK_SRC_MASK,
1975 (factors.fll_refclk_div
1976 << WM5100_FLL1_REFCLK_DIV_SHIFT) | source);
1977 snd_soc_update_bits(codec, base + 7, WM5100_FLL1_LAMBDA_MASK,
1978 factors.lambda);
1979
1980 /* Clear any pending completions */
1981 try_wait_for_completion(&fll->lock);
1982
1983 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA);
1984
1985 if (i2c->irq)
1986 timeout = 2;
1987 else
1988 timeout = 50;
1989
1990 /* Poll for the lock; will use interrupt when we can test */
1991 for (i = 0; i < timeout; i++) {
1992 if (i2c->irq) {
1993 ret = wait_for_completion_timeout(&fll->lock,
1994 msecs_to_jiffies(25));
1995 if (ret > 0)
1996 break;
1997 } else {
1998 msleep(1);
1999 }
2000
2001 ret = snd_soc_read(codec,
2002 WM5100_INTERRUPT_RAW_STATUS_3);
2003 if (ret < 0) {
2004 dev_err(codec->dev,
2005 "Failed to read FLL status: %d\n",
2006 ret);
2007 continue;
2008 }
2009 if (ret & lock)
2010 break;
2011 }
2012 if (i == timeout) {
2013 dev_err(codec->dev, "FLL%d lock timed out\n", fll_id);
2014 return -ETIMEDOUT;
2015 }
2016
2017 fll->src = source;
2018 fll->fref = Fref;
2019 fll->fout = Fout;
2020
2021 dev_dbg(codec->dev, "FLL%d running %dHz->%dHz\n", fll_id,
2022 Fref, Fout);
2023
2024 return 0;
2025}
2026
2027/* Actually go much higher */
2028#define WM5100_RATES SNDRV_PCM_RATE_8000_192000
2029
2030#define WM5100_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2031 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
2032
2033static struct snd_soc_dai_driver wm5100_dai[] = {
2034 {
2035 .name = "wm5100-aif1",
2036 .playback = {
2037 .stream_name = "AIF1 Playback",
2038 .channels_min = 2,
2039 .channels_max = 2,
2040 .rates = WM5100_RATES,
2041 .formats = WM5100_FORMATS,
2042 },
2043 .capture = {
2044 .stream_name = "AIF1 Capture",
2045 .channels_min = 2,
2046 .channels_max = 2,
2047 .rates = WM5100_RATES,
2048 .formats = WM5100_FORMATS,
2049 },
2050 .ops = &wm5100_dai_ops,
2051 },
2052 {
2053 .name = "wm5100-aif2",
2054 .id = 1,
2055 .playback = {
2056 .stream_name = "AIF2 Playback",
2057 .channels_min = 2,
2058 .channels_max = 2,
2059 .rates = WM5100_RATES,
2060 .formats = WM5100_FORMATS,
2061 },
2062 .capture = {
2063 .stream_name = "AIF2 Capture",
2064 .channels_min = 2,
2065 .channels_max = 2,
2066 .rates = WM5100_RATES,
2067 .formats = WM5100_FORMATS,
2068 },
2069 .ops = &wm5100_dai_ops,
2070 },
2071 {
2072 .name = "wm5100-aif3",
2073 .id = 2,
2074 .playback = {
2075 .stream_name = "AIF3 Playback",
2076 .channels_min = 2,
2077 .channels_max = 2,
2078 .rates = WM5100_RATES,
2079 .formats = WM5100_FORMATS,
2080 },
2081 .capture = {
2082 .stream_name = "AIF3 Capture",
2083 .channels_min = 2,
2084 .channels_max = 2,
2085 .rates = WM5100_RATES,
2086 .formats = WM5100_FORMATS,
2087 },
2088 .ops = &wm5100_dai_ops,
2089 },
2090};
2091
2092static int wm5100_dig_vu[] = {
2093 WM5100_ADC_DIGITAL_VOLUME_1L,
2094 WM5100_ADC_DIGITAL_VOLUME_1R,
2095 WM5100_ADC_DIGITAL_VOLUME_2L,
2096 WM5100_ADC_DIGITAL_VOLUME_2R,
2097 WM5100_ADC_DIGITAL_VOLUME_3L,
2098 WM5100_ADC_DIGITAL_VOLUME_3R,
2099 WM5100_ADC_DIGITAL_VOLUME_4L,
2100 WM5100_ADC_DIGITAL_VOLUME_4R,
2101
2102 WM5100_DAC_DIGITAL_VOLUME_1L,
2103 WM5100_DAC_DIGITAL_VOLUME_1R,
2104 WM5100_DAC_DIGITAL_VOLUME_2L,
2105 WM5100_DAC_DIGITAL_VOLUME_2R,
2106 WM5100_DAC_DIGITAL_VOLUME_3L,
2107 WM5100_DAC_DIGITAL_VOLUME_3R,
2108 WM5100_DAC_DIGITAL_VOLUME_4L,
2109 WM5100_DAC_DIGITAL_VOLUME_4R,
2110 WM5100_DAC_DIGITAL_VOLUME_5L,
2111 WM5100_DAC_DIGITAL_VOLUME_5R,
2112 WM5100_DAC_DIGITAL_VOLUME_6L,
2113 WM5100_DAC_DIGITAL_VOLUME_6R,
2114};
2115
2116static irqreturn_t wm5100_irq(int irq, void *data)
2117{
2118 struct snd_soc_codec *codec = data;
2119 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2120 irqreturn_t status = IRQ_NONE;
2121 int irq_val;
2122
2123 irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3);
2124 if (irq_val < 0) {
2125 dev_err(codec->dev, "Failed to read IRQ status 3: %d\n",
2126 irq_val);
2127 irq_val = 0;
2128 }
2129 irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3_MASK);
2130
2131 snd_soc_write(codec, WM5100_INTERRUPT_STATUS_3, irq_val);
2132
2133 if (irq_val)
2134 status = IRQ_HANDLED;
2135
2136 wm5100_log_status3(codec, irq_val);
2137
2138 if (irq_val & WM5100_FLL1_LOCK_EINT) {
2139 dev_dbg(codec->dev, "FLL1 locked\n");
2140 complete(&wm5100->fll[0].lock);
2141 }
2142 if (irq_val & WM5100_FLL2_LOCK_EINT) {
2143 dev_dbg(codec->dev, "FLL2 locked\n");
2144 complete(&wm5100->fll[1].lock);
2145 }
2146
2147 irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4);
2148 if (irq_val < 0) {
2149 dev_err(codec->dev, "Failed to read IRQ status 4: %d\n",
2150 irq_val);
2151 irq_val = 0;
2152 }
2153 irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4_MASK);
2154
2155 if (irq_val)
2156 status = IRQ_HANDLED;
2157
2158 snd_soc_write(codec, WM5100_INTERRUPT_STATUS_4, irq_val);
2159
2160 wm5100_log_status4(codec, irq_val);
2161
2162 return status;
2163}
2164
2165static irqreturn_t wm5100_edge_irq(int irq, void *data)
2166{
2167 irqreturn_t ret = IRQ_NONE;
2168 irqreturn_t val;
2169
2170 do {
2171 val = wm5100_irq(irq, data);
2172 if (val != IRQ_NONE)
2173 ret = val;
2174 } while (val != IRQ_NONE);
2175
2176 return ret;
2177}
2178
2179#ifdef CONFIG_GPIOLIB
2180static inline struct wm5100_priv *gpio_to_wm5100(struct gpio_chip *chip)
2181{
2182 return container_of(chip, struct wm5100_priv, gpio_chip);
2183}
2184
2185static void wm5100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
2186{
2187 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2188 struct snd_soc_codec *codec = wm5100->codec;
2189
2190 snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
2191 WM5100_GP1_LVL, !!value << WM5100_GP1_LVL_SHIFT);
2192}
2193
2194static int wm5100_gpio_direction_out(struct gpio_chip *chip,
2195 unsigned offset, int value)
2196{
2197 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2198 struct snd_soc_codec *codec = wm5100->codec;
2199 int val;
2200
2201 val = (1 << WM5100_GP1_FN_SHIFT) | (!!value << WM5100_GP1_LVL_SHIFT);
2202
2203 return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
2204 WM5100_GP1_FN_MASK | WM5100_GP1_DIR |
2205 WM5100_GP1_LVL, val);
2206}
2207
2208static int wm5100_gpio_get(struct gpio_chip *chip, unsigned offset)
2209{
2210 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2211 struct snd_soc_codec *codec = wm5100->codec;
2212 int ret;
2213
2214 ret = snd_soc_read(codec, WM5100_GPIO_CTRL_1 + offset);
2215 if (ret < 0)
2216 return ret;
2217
2218 return (ret & WM5100_GP1_LVL) != 0;
2219}
2220
2221static int wm5100_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
2222{
2223 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2224 struct snd_soc_codec *codec = wm5100->codec;
2225
2226 return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
2227 WM5100_GP1_FN_MASK | WM5100_GP1_DIR,
2228 (1 << WM5100_GP1_FN_SHIFT) |
2229 (1 << WM5100_GP1_DIR_SHIFT));
2230}
2231
2232static struct gpio_chip wm5100_template_chip = {
2233 .label = "wm5100",
2234 .owner = THIS_MODULE,
2235 .direction_output = wm5100_gpio_direction_out,
2236 .set = wm5100_gpio_set,
2237 .direction_input = wm5100_gpio_direction_in,
2238 .get = wm5100_gpio_get,
2239 .can_sleep = 1,
2240};
2241
2242static void wm5100_init_gpio(struct snd_soc_codec *codec)
2243{
2244 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2245 int ret;
2246
2247 wm5100->gpio_chip = wm5100_template_chip;
2248 wm5100->gpio_chip.ngpio = 6;
2249 wm5100->gpio_chip.dev = codec->dev;
2250
2251 if (wm5100->pdata.gpio_base)
2252 wm5100->gpio_chip.base = wm5100->pdata.gpio_base;
2253 else
2254 wm5100->gpio_chip.base = -1;
2255
2256 ret = gpiochip_add(&wm5100->gpio_chip);
2257 if (ret != 0)
2258 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
2259}
2260
2261static void wm5100_free_gpio(struct snd_soc_codec *codec)
2262{
2263 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2264 int ret;
2265
2266 ret = gpiochip_remove(&wm5100->gpio_chip);
2267 if (ret != 0)
2268 dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
2269}
2270#else
2271static void wm5100_init_gpio(struct snd_soc_codec *codec)
2272{
2273}
2274
2275static void wm5100_free_gpio(struct snd_soc_codec *codec)
2276{
2277}
2278#endif
2279
2280static int wm5100_probe(struct snd_soc_codec *codec)
2281{
2282 struct i2c_client *i2c = to_i2c_client(codec->dev);
2283 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2284 int ret, i, irq_flags;
2285
2286 wm5100->codec = codec;
2287
6d4baf08
MB
2288 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
2289 if (ret != 0) {
2290 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2291 return ret;
2292 }
2293
2294 for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++)
2295 wm5100->core_supplies[i].supply = wm5100_core_supply_names[i];
2296
2297 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm5100->core_supplies),
2298 wm5100->core_supplies);
2299 if (ret != 0) {
2300 dev_err(codec->dev, "Failed to request core supplies: %d\n",
2301 ret);
2302 return ret;
2303 }
2304
2305 wm5100->cpvdd = regulator_get(&i2c->dev, "CPVDD");
2306 if (IS_ERR(wm5100->cpvdd)) {
2307 ret = PTR_ERR(wm5100->cpvdd);
2308 dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
2309 goto err_core;
2310 }
2311
7aefb086
MB
2312 wm5100->dbvdd2 = regulator_get(&i2c->dev, "DBVDD2");
2313 if (IS_ERR(wm5100->dbvdd2)) {
2314 ret = PTR_ERR(wm5100->dbvdd2);
2315 dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
2316 goto err_cpvdd;
2317 }
2318
2319 wm5100->dbvdd3 = regulator_get(&i2c->dev, "DBVDD3");
2320 if (IS_ERR(wm5100->dbvdd3)) {
2321 ret = PTR_ERR(wm5100->dbvdd3);
2322 dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
2323 goto err_dbvdd2;
2324 }
2325
6d4baf08
MB
2326 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
2327 wm5100->core_supplies);
2328 if (ret != 0) {
2329 dev_err(codec->dev, "Failed to enable core supplies: %d\n",
2330 ret);
7aefb086 2331 goto err_dbvdd3;
6d4baf08
MB
2332 }
2333
2334 if (wm5100->pdata.ldo_ena) {
2335 ret = gpio_request_one(wm5100->pdata.ldo_ena,
2336 GPIOF_OUT_INIT_HIGH, "WM5100 LDOENA");
2337 if (ret < 0) {
2338 dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n",
2339 wm5100->pdata.ldo_ena, ret);
2340 goto err_enable;
2341 }
2342 msleep(2);
2343 }
2344
2345 if (wm5100->pdata.reset) {
2346 ret = gpio_request_one(wm5100->pdata.reset,
2347 GPIOF_OUT_INIT_HIGH, "WM5100 /RESET");
2348 if (ret < 0) {
2349 dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n",
2350 wm5100->pdata.reset, ret);
2351 goto err_ldo;
2352 }
2353 }
2354
2355 ret = snd_soc_read(codec, WM5100_SOFTWARE_RESET);
2356 if (ret < 0) {
2357 dev_err(codec->dev, "Failed to read ID register\n");
2358 goto err_reset;
2359 }
2360 switch (ret) {
2361 case 0x8997:
2362 case 0x5100:
2363 break;
2364
2365 default:
2366 dev_err(codec->dev, "Device is not a WM5100, ID is %x\n", ret);
2367 ret = -EINVAL;
2368 goto err_reset;
2369 }
2370
2371 ret = snd_soc_read(codec, WM5100_DEVICE_REVISION);
2372 if (ret < 0) {
2373 dev_err(codec->dev, "Failed to read revision register\n");
2374 goto err_reset;
2375 }
2376 wm5100->rev = ret & WM5100_DEVICE_REVISION_MASK;
2377
2378 dev_info(codec->dev, "revision %c\n", wm5100->rev + 'A');
2379
2380 ret = wm5100_reset(codec);
2381 if (ret < 0) {
2382 dev_err(codec->dev, "Failed to issue reset\n");
2383 goto err_reset;
2384 }
2385
2386 codec->cache_only = true;
2387
2388 wm5100_init_gpio(codec);
2389
2390 for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++)
2391 snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU,
2392 WM5100_OUT_VU);
2393
2394 for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) {
2395 snd_soc_update_bits(codec, WM5100_IN1L_CONTROL,
2396 WM5100_IN1_MODE_MASK |
2397 WM5100_IN1_DMIC_SUP_MASK,
2398 (wm5100->pdata.in_mode[i] <<
2399 WM5100_IN1_MODE_SHIFT) |
2400 (wm5100->pdata.dmic_sup[i] <<
2401 WM5100_IN1_DMIC_SUP_SHIFT));
2402 }
2403
2404 for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) {
2405 if (!wm5100->pdata.gpio_defaults[i])
2406 continue;
2407
2408 snd_soc_write(codec, WM5100_GPIO_CTRL_1 + i,
2409 wm5100->pdata.gpio_defaults[i]);
2410 }
2411
2412 /* Don't debounce interrupts to support use of SYSCLK only */
2413 snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_1, 0);
2414 snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_2, 0);
2415
2416 /* TODO: check if we're symmetric */
2417
2418 if (i2c->irq) {
2419 if (wm5100->pdata.irq_flags)
2420 irq_flags = wm5100->pdata.irq_flags;
2421 else
2422 irq_flags = IRQF_TRIGGER_LOW;
2423
2424 irq_flags |= IRQF_ONESHOT;
2425
2426 if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
2427 ret = request_threaded_irq(i2c->irq, NULL,
2428 wm5100_edge_irq,
2429 irq_flags, "wm5100", codec);
2430 else
2431 ret = request_threaded_irq(i2c->irq, NULL, wm5100_irq,
2432 irq_flags, "wm5100", codec);
2433
2434 if (ret != 0) {
2435 dev_err(codec->dev, "Failed to request IRQ %d: %d\n",
2436 i2c->irq, ret);
2437 } else {
2438 /* Enable default interrupts */
2439 snd_soc_update_bits(codec,
2440 WM5100_INTERRUPT_STATUS_3_MASK,
2441 WM5100_IM_SPK_SHUTDOWN_WARN_EINT |
2442 WM5100_IM_SPK_SHUTDOWN_EINT |
2443 WM5100_IM_ASRC2_LOCK_EINT |
2444 WM5100_IM_ASRC1_LOCK_EINT |
2445 WM5100_IM_FLL2_LOCK_EINT |
2446 WM5100_IM_FLL1_LOCK_EINT |
2447 WM5100_CLKGEN_ERR_EINT |
2448 WM5100_CLKGEN_ERR_ASYNC_EINT, 0);
2449
2450 snd_soc_update_bits(codec,
2451 WM5100_INTERRUPT_STATUS_4_MASK,
2452 WM5100_AIF3_ERR_EINT |
2453 WM5100_AIF2_ERR_EINT |
2454 WM5100_AIF1_ERR_EINT |
2455 WM5100_CTRLIF_ERR_EINT |
2456 WM5100_ISRC2_UNDERCLOCKED_EINT |
2457 WM5100_ISRC1_UNDERCLOCKED_EINT |
2458 WM5100_FX_UNDERCLOCKED_EINT |
2459 WM5100_AIF3_UNDERCLOCKED_EINT |
2460 WM5100_AIF2_UNDERCLOCKED_EINT |
2461 WM5100_AIF1_UNDERCLOCKED_EINT |
2462 WM5100_ASRC_UNDERCLOCKED_EINT |
2463 WM5100_DAC_UNDERCLOCKED_EINT |
2464 WM5100_ADC_UNDERCLOCKED_EINT |
2465 WM5100_MIXER_UNDERCLOCKED_EINT, 0);
2466 }
2467 } else {
2468 snd_soc_dapm_new_controls(&codec->dapm,
2469 wm5100_dapm_widgets_noirq,
2470 ARRAY_SIZE(wm5100_dapm_widgets_noirq));
2471 }
2472
2473 if (wm5100->pdata.hp_pol) {
2474 ret = gpio_request_one(wm5100->pdata.hp_pol,
2475 GPIOF_OUT_INIT_HIGH, "WM5100 HP_POL");
2476 if (ret < 0) {
2477 dev_err(&i2c->dev, "Failed to request HP_POL %d: %d\n",
2478 wm5100->pdata.hp_pol, ret);
2479 goto err_gpio;
2480 }
2481 }
2482
2483 /* We'll get woken up again when the system has something useful
2484 * for us to do.
2485 */
2486 if (wm5100->pdata.ldo_ena)
2487 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2488 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2489 wm5100->core_supplies);
2490
2491 return 0;
2492
2493err_gpio:
0a742681
AL
2494 if (i2c->irq)
2495 free_irq(i2c->irq, codec);
6d4baf08
MB
2496 wm5100_free_gpio(codec);
2497err_reset:
2498 if (wm5100->pdata.reset) {
2499 gpio_set_value_cansleep(wm5100->pdata.reset, 1);
2500 gpio_free(wm5100->pdata.reset);
2501 }
2502err_ldo:
2503 if (wm5100->pdata.ldo_ena) {
2504 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2505 gpio_free(wm5100->pdata.ldo_ena);
2506 }
2507err_enable:
2508 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2509 wm5100->core_supplies);
7aefb086
MB
2510err_dbvdd3:
2511 regulator_put(wm5100->dbvdd3);
2512err_dbvdd2:
2513 regulator_put(wm5100->dbvdd2);
6d4baf08
MB
2514err_cpvdd:
2515 regulator_put(wm5100->cpvdd);
2516err_core:
2517 regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
2518 wm5100->core_supplies);
2519
2520 return ret;
2521}
2522
2523static int wm5100_remove(struct snd_soc_codec *codec)
2524{
2525 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
0a742681 2526 struct i2c_client *i2c = to_i2c_client(codec->dev);
6d4baf08
MB
2527
2528 wm5100_set_bias_level(codec, SND_SOC_BIAS_OFF);
2529 if (wm5100->pdata.hp_pol) {
2530 gpio_free(wm5100->pdata.hp_pol);
2531 }
0a742681
AL
2532 if (i2c->irq)
2533 free_irq(i2c->irq, codec);
6d4baf08
MB
2534 wm5100_free_gpio(codec);
2535 if (wm5100->pdata.reset) {
2536 gpio_set_value_cansleep(wm5100->pdata.reset, 1);
2537 gpio_free(wm5100->pdata.reset);
2538 }
2539 if (wm5100->pdata.ldo_ena) {
2540 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2541 gpio_free(wm5100->pdata.ldo_ena);
2542 }
7aefb086
MB
2543 regulator_put(wm5100->dbvdd3);
2544 regulator_put(wm5100->dbvdd2);
6d4baf08
MB
2545 regulator_put(wm5100->cpvdd);
2546 regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
2547 wm5100->core_supplies);
2548 return 0;
2549}
2550
2551static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
2552 .probe = wm5100_probe,
2553 .remove = wm5100_remove,
2554
2555 .set_sysclk = wm5100_set_sysclk,
2556 .set_pll = wm5100_set_fll,
2557 .set_bias_level = wm5100_set_bias_level,
2558 .idle_bias_off = 1,
2559
2560 .seq_notifier = wm5100_seq_notifier,
2561 .controls = wm5100_snd_controls,
2562 .num_controls = ARRAY_SIZE(wm5100_snd_controls),
2563 .dapm_widgets = wm5100_dapm_widgets,
2564 .num_dapm_widgets = ARRAY_SIZE(wm5100_dapm_widgets),
2565 .dapm_routes = wm5100_dapm_routes,
2566 .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes),
2567
2568 .reg_cache_size = ARRAY_SIZE(wm5100_reg_defaults),
2569 .reg_word_size = sizeof(u16),
2570 .compress_type = SND_SOC_RBTREE_COMPRESSION,
2571 .reg_cache_default = wm5100_reg_defaults,
2572
2573 .volatile_register = wm5100_volatile_register,
2574 .readable_register = wm5100_readable_register,
2575};
2576
2577static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2578 const struct i2c_device_id *id)
2579{
2580 struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev);
2581 struct wm5100_priv *wm5100;
2582 int ret, i;
2583
2584 wm5100 = kzalloc(sizeof(struct wm5100_priv), GFP_KERNEL);
2585 if (wm5100 == NULL)
2586 return -ENOMEM;
2587
2588 for (i = 0; i < ARRAY_SIZE(wm5100->fll); i++)
2589 init_completion(&wm5100->fll[i].lock);
2590
2591 if (pdata)
2592 wm5100->pdata = *pdata;
2593
2594 i2c_set_clientdata(i2c, wm5100);
2595
2596 ret = snd_soc_register_codec(&i2c->dev,
2597 &soc_codec_dev_wm5100, wm5100_dai,
2598 ARRAY_SIZE(wm5100_dai));
2599 if (ret < 0) {
2600 dev_err(&i2c->dev, "Failed to register WM5100: %d\n", ret);
2601 kfree(wm5100);
2602 }
2603
2604 return ret;
2605}
2606
2607static __devexit int wm5100_i2c_remove(struct i2c_client *client)
2608{
2609 snd_soc_unregister_codec(&client->dev);
2610 kfree(i2c_get_clientdata(client));
2611 return 0;
2612}
2613
2614static const struct i2c_device_id wm5100_i2c_id[] = {
2615 { "wm5100", 0 },
2616 { }
2617};
2618MODULE_DEVICE_TABLE(i2c, wm5100_i2c_id);
2619
2620static struct i2c_driver wm5100_i2c_driver = {
2621 .driver = {
2622 .name = "wm5100",
2623 .owner = THIS_MODULE,
2624 },
2625 .probe = wm5100_i2c_probe,
2626 .remove = __devexit_p(wm5100_i2c_remove),
2627 .id_table = wm5100_i2c_id,
2628};
2629
2630static int __init wm5100_modinit(void)
2631{
2632 return i2c_add_driver(&wm5100_i2c_driver);
2633}
2634module_init(wm5100_modinit);
2635
2636static void __exit wm5100_exit(void)
2637{
2638 i2c_del_driver(&wm5100_i2c_driver);
2639}
2640module_exit(wm5100_exit);
2641
2642MODULE_DESCRIPTION("ASoC WM5100 driver");
2643MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2644MODULE_LICENSE("GPL");
This page took 0.12773 seconds and 5 git commands to generate.