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