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