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