ASoC: core: Allow DAIs to specify a base address
[deliverable/linux.git] / sound / soc / codecs / wm5100.c
CommitLineData
6d4baf08
MB
1/*
2 * wm5100.c -- WM5100 ALSA SoC Audio driver
3 *
4 * Copyright 2011 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/gcd.h>
19#include <linux/gpio.h>
20#include <linux/i2c.h>
62c1c401 21#include <linux/pm_runtime.h>
6d4baf08
MB
22#include <linux/regulator/consumer.h>
23#include <linux/regulator/fixed.h>
24#include <linux/slab.h>
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
ba896ede 29#include <sound/jack.h>
6d4baf08
MB
30#include <sound/initval.h>
31#include <sound/tlv.h>
32#include <sound/wm5100.h>
33
34#include "wm5100.h"
35
36#define WM5100_NUM_CORE_SUPPLIES 2
37static const char *wm5100_core_supply_names[WM5100_NUM_CORE_SUPPLIES] = {
38 "DBVDD1",
39 "LDOVDD", /* If DCVDD is supplied externally specify as LDOVDD */
40};
41
42#define WM5100_AIFS 3
43#define WM5100_SYNC_SRS 3
44
45struct wm5100_fll {
46 int fref;
47 int fout;
48 int src;
49 struct completion lock;
50};
51
52/* codec private data */
53struct wm5100_priv {
46c1a877 54 struct device *dev;
bd132ec5 55 struct regmap *regmap;
6d4baf08
MB
56 struct snd_soc_codec *codec;
57
58 struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES];
6d4baf08
MB
59
60 int rev;
61
62 int sysclk;
63 int asyncclk;
64
65 bool aif_async[WM5100_AIFS];
66 bool aif_symmetric[WM5100_AIFS];
67 int sr_ref[WM5100_SYNC_SRS];
68
69 bool out_ena[2];
70
ba896ede
MB
71 struct snd_soc_jack *jack;
72 bool jack_detecting;
73 bool jack_mic;
74 int jack_mode;
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
1cf73356
MB
851SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
852SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0),
853SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0),
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
15b52f10 1236static const __devinitdata 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_dai_to_base(struct snd_soc_dai *dai)
1269{
1270 switch (dai->id) {
1271 case 0:
1272 return WM5100_AUDIO_IF_1_1 - 1;
1273 case 1:
1274 return WM5100_AUDIO_IF_2_1 - 1;
1275 case 2:
1276 return WM5100_AUDIO_IF_3_1 - 1;
1277 default:
1278 BUG();
1279 return -EINVAL;
1280 }
1281}
1282
1283static int wm5100_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1284{
1285 struct snd_soc_codec *codec = dai->codec;
1286 int lrclk, bclk, mask, base;
1287
1288 base = wm5100_dai_to_base(dai);
1289 if (base < 0)
1290 return base;
1291
1292 lrclk = 0;
1293 bclk = 0;
1294
1295 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1296 case SND_SOC_DAIFMT_DSP_A:
1297 mask = 0;
1298 break;
1299 case SND_SOC_DAIFMT_DSP_B:
1300 mask = 1;
1301 break;
1302 case SND_SOC_DAIFMT_I2S:
1303 mask = 2;
1304 break;
1305 case SND_SOC_DAIFMT_LEFT_J:
1306 mask = 3;
1307 break;
1308 default:
1309 dev_err(codec->dev, "Unsupported DAI format %d\n",
1310 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1311 return -EINVAL;
1312 }
1313
1314 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1315 case SND_SOC_DAIFMT_CBS_CFS:
1316 break;
1317 case SND_SOC_DAIFMT_CBS_CFM:
1318 lrclk |= WM5100_AIF1TX_LRCLK_MSTR;
1319 break;
1320 case SND_SOC_DAIFMT_CBM_CFS:
1321 bclk |= WM5100_AIF1_BCLK_MSTR;
1322 break;
1323 case SND_SOC_DAIFMT_CBM_CFM:
1324 lrclk |= WM5100_AIF1TX_LRCLK_MSTR;
1325 bclk |= WM5100_AIF1_BCLK_MSTR;
1326 break;
1327 default:
1328 dev_err(codec->dev, "Unsupported master mode %d\n",
1329 fmt & SND_SOC_DAIFMT_MASTER_MASK);
1330 return -EINVAL;
1331 }
1332
1333 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1334 case SND_SOC_DAIFMT_NB_NF:
1335 break;
1336 case SND_SOC_DAIFMT_IB_IF:
1337 bclk |= WM5100_AIF1_BCLK_INV;
1338 lrclk |= WM5100_AIF1TX_LRCLK_INV;
1339 break;
1340 case SND_SOC_DAIFMT_IB_NF:
1341 bclk |= WM5100_AIF1_BCLK_INV;
1342 break;
1343 case SND_SOC_DAIFMT_NB_IF:
1344 lrclk |= WM5100_AIF1TX_LRCLK_INV;
1345 break;
1346 default:
1347 return -EINVAL;
1348 }
1349
1350 snd_soc_update_bits(codec, base + 1, WM5100_AIF1_BCLK_MSTR |
1351 WM5100_AIF1_BCLK_INV, bclk);
1352 snd_soc_update_bits(codec, base + 2, WM5100_AIF1TX_LRCLK_MSTR |
1353 WM5100_AIF1TX_LRCLK_INV, lrclk);
1354 snd_soc_update_bits(codec, base + 3, WM5100_AIF1TX_LRCLK_MSTR |
1355 WM5100_AIF1TX_LRCLK_INV, lrclk);
1356 snd_soc_update_bits(codec, base + 5, WM5100_AIF1_FMT_MASK, mask);
1357
1358 return 0;
1359}
1360
1361#define WM5100_NUM_BCLK_RATES 19
1362
1363static int wm5100_bclk_rates_dat[WM5100_NUM_BCLK_RATES] = {
1364 32000,
1365 48000,
1366 64000,
1367 96000,
1368 128000,
1369 192000,
d73ec75c 1370 256000,
6d4baf08
MB
1371 384000,
1372 512000,
1373 768000,
1374 1024000,
1375 1536000,
1376 2048000,
1377 3072000,
1378 4096000,
1379 6144000,
1380 8192000,
1381 12288000,
1382 24576000,
1383};
1384
1385static int wm5100_bclk_rates_cd[WM5100_NUM_BCLK_RATES] = {
1386 29400,
1387 44100,
1388 58800,
1389 88200,
1390 117600,
1391 176400,
1392 235200,
1393 352800,
1394 470400,
1395 705600,
1396 940800,
1397 1411200,
1398 1881600,
1399 2882400,
1400 3763200,
1401 5644800,
1402 7526400,
1403 11289600,
1404 22579600,
1405};
1406
1407static int wm5100_hw_params(struct snd_pcm_substream *substream,
1408 struct snd_pcm_hw_params *params,
1409 struct snd_soc_dai *dai)
1410{
1411 struct snd_soc_codec *codec = dai->codec;
1412 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1413 bool async = wm5100->aif_async[dai->id];
1414 int i, base, bclk, aif_rate, lrclk, wl, fl, sr;
1415 int *bclk_rates;
1416
1417 base = wm5100_dai_to_base(dai);
1418 if (base < 0)
1419 return base;
1420
1421 /* Data sizes if not using TDM */
1422 wl = snd_pcm_format_width(params_format(params));
1423 if (wl < 0)
1424 return wl;
1425 fl = snd_soc_params_to_frame_size(params);
1426 if (fl < 0)
1427 return fl;
1428
1429 dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n",
1430 wl, fl);
1431
1432 /* Target BCLK rate */
1433 bclk = snd_soc_params_to_bclk(params);
1434 if (bclk < 0)
1435 return bclk;
1436
1437 /* Root for BCLK depends on SYS/ASYNCCLK */
1438 if (!async) {
1439 aif_rate = wm5100->sysclk;
1440 sr = wm5100_alloc_sr(codec, params_rate(params));
1441 if (sr < 0)
1442 return sr;
1443 } else {
1444 /* If we're in ASYNCCLK set the ASYNC sample rate */
1445 aif_rate = wm5100->asyncclk;
1446 sr = 3;
1447
1448 for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
1449 if (params_rate(params) == wm5100_sr_code[i])
1450 break;
1451 if (i == ARRAY_SIZE(wm5100_sr_code)) {
1452 dev_err(codec->dev, "Invalid rate %dHzn",
1453 params_rate(params));
1454 return -EINVAL;
1455 }
1456
1457 /* TODO: We should really check for symmetry */
1458 snd_soc_update_bits(codec, WM5100_CLOCKING_8,
1459 WM5100_ASYNC_SAMPLE_RATE_MASK, i);
1460 }
1461
1462 if (!aif_rate) {
1463 dev_err(codec->dev, "%s has no rate set\n",
1464 async ? "ASYNCCLK" : "SYSCLK");
1465 return -EINVAL;
1466 }
1467
1468 dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz %s\n",
1469 bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK");
1470
1471 if (aif_rate % 4000)
1472 bclk_rates = wm5100_bclk_rates_cd;
1473 else
1474 bclk_rates = wm5100_bclk_rates_dat;
1475
1476 for (i = 0; i < WM5100_NUM_BCLK_RATES; i++)
1477 if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0))
1478 break;
1479 if (i == WM5100_NUM_BCLK_RATES) {
1480 dev_err(codec->dev,
1481 "No valid BCLK for %dHz found from %dHz %s\n",
1482 bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK");
1483 return -EINVAL;
1484 }
1485
1486 bclk = i;
1487 dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
1488 snd_soc_update_bits(codec, base + 1, WM5100_AIF1_BCLK_FREQ_MASK, bclk);
1489
1490 lrclk = bclk_rates[bclk] / params_rate(params);
1491 dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
1492 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
1493 wm5100->aif_symmetric[dai->id])
1494 snd_soc_update_bits(codec, base + 7,
1495 WM5100_AIF1RX_BCPF_MASK, lrclk);
1496 else
1497 snd_soc_update_bits(codec, base + 6,
1498 WM5100_AIF1TX_BCPF_MASK, lrclk);
1499
1500 i = (wl << WM5100_AIF1TX_WL_SHIFT) | fl;
1501 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1502 snd_soc_update_bits(codec, base + 9,
1503 WM5100_AIF1RX_WL_MASK |
1504 WM5100_AIF1RX_SLOT_LEN_MASK, i);
1505 else
1506 snd_soc_update_bits(codec, base + 8,
1507 WM5100_AIF1TX_WL_MASK |
1508 WM5100_AIF1TX_SLOT_LEN_MASK, i);
1509
1510 snd_soc_update_bits(codec, base + 4, WM5100_AIF1_RATE_MASK, sr);
1511
1512 return 0;
1513}
1514
85e7652d 1515static const struct snd_soc_dai_ops wm5100_dai_ops = {
6d4baf08
MB
1516 .set_fmt = wm5100_set_fmt,
1517 .hw_params = wm5100_hw_params,
1518};
1519
1520static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1521 int source, unsigned int freq, int dir)
1522{
1523 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1524 int *rate_store;
1525 int fval, audio_rate, ret, reg;
1526
1527 switch (clk_id) {
1528 case WM5100_CLK_SYSCLK:
1529 reg = WM5100_CLOCKING_3;
1530 rate_store = &wm5100->sysclk;
1531 break;
1532 case WM5100_CLK_ASYNCCLK:
1533 reg = WM5100_CLOCKING_7;
1534 rate_store = &wm5100->asyncclk;
1535 break;
1536 case WM5100_CLK_32KHZ:
1537 /* The 32kHz clock is slightly different to the others */
1538 switch (source) {
1539 case WM5100_CLKSRC_MCLK1:
1540 case WM5100_CLKSRC_MCLK2:
1541 case WM5100_CLKSRC_SYSCLK:
1542 snd_soc_update_bits(codec, WM5100_CLOCKING_1,
1543 WM5100_CLK_32K_SRC_MASK,
1544 source);
1545 break;
1546 default:
1547 return -EINVAL;
1548 }
1549 return 0;
1550
1551 case WM5100_CLK_AIF1:
1552 case WM5100_CLK_AIF2:
1553 case WM5100_CLK_AIF3:
1554 /* Not real clocks, record which clock domain they're in */
1555 switch (source) {
1556 case WM5100_CLKSRC_SYSCLK:
1557 wm5100->aif_async[clk_id - 1] = false;
1558 break;
1559 case WM5100_CLKSRC_ASYNCCLK:
1560 wm5100->aif_async[clk_id - 1] = true;
1561 break;
1562 default:
1563 dev_err(codec->dev, "Invalid source %d\n", source);
1564 return -EINVAL;
1565 }
1566 return 0;
1567
1568 case WM5100_CLK_OPCLK:
1569 switch (freq) {
1570 case 5644800:
1571 case 6144000:
1572 snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
1573 WM5100_OPCLK_SEL_MASK, 0);
1574 break;
1575 case 11289600:
1576 case 12288000:
1577 snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
1578 WM5100_OPCLK_SEL_MASK, 0);
1579 break;
1580 case 22579200:
1581 case 24576000:
1582 snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
1583 WM5100_OPCLK_SEL_MASK, 0);
1584 break;
1585 default:
1586 dev_err(codec->dev, "Unsupported OPCLK %dHz\n",
1587 freq);
1588 return -EINVAL;
1589 }
1590 return 0;
1591
1592 default:
1593 dev_err(codec->dev, "Unknown clock %d\n", clk_id);
1594 return -EINVAL;
1595 }
1596
1597 switch (source) {
1598 case WM5100_CLKSRC_SYSCLK:
1599 case WM5100_CLKSRC_ASYNCCLK:
1600 dev_err(codec->dev, "Invalid source %d\n", source);
1601 return -EINVAL;
1602 }
1603
1604 switch (freq) {
1605 case 5644800:
1606 case 6144000:
1607 fval = 0;
1608 break;
1609 case 11289600:
1610 case 12288000:
1611 fval = 1;
1612 break;
1613 case 22579200:
11c2b5f2 1614 case 24576000:
6d4baf08
MB
1615 fval = 2;
1616 break;
1617 default:
1618 dev_err(codec->dev, "Invalid clock rate: %d\n", freq);
1619 return -EINVAL;
1620 }
1621
1622 switch (freq) {
1623 case 5644800:
1624 case 11289600:
1625 case 22579200:
1626 audio_rate = 44100;
1627 break;
1628
1629 case 6144000:
1630 case 12288000:
11c2b5f2 1631 case 24576000:
6d4baf08
MB
1632 audio_rate = 48000;
1633 break;
1634
1635 default:
1636 BUG();
1637 audio_rate = 0;
1638 break;
1639 }
1640
1641 /* TODO: Check if MCLKs are in use and enable/disable pulls to
1642 * match.
1643 */
1644
1645 snd_soc_update_bits(codec, reg, WM5100_SYSCLK_FREQ_MASK |
1646 WM5100_SYSCLK_SRC_MASK,
1647 fval << WM5100_SYSCLK_FREQ_SHIFT | source);
1648
1649 /* If this is SYSCLK then configure the clock rate for the
1650 * internal audio functions to the natural sample rate for
1651 * this clock rate.
1652 */
1653 if (clk_id == WM5100_CLK_SYSCLK) {
1654 dev_dbg(codec->dev, "Setting primary audio rate to %dHz",
1655 audio_rate);
1656 if (0 && *rate_store)
1657 wm5100_free_sr(codec, audio_rate);
1658 ret = wm5100_alloc_sr(codec, audio_rate);
1659 if (ret != 0)
1660 dev_warn(codec->dev, "Primary audio slot is %d\n",
1661 ret);
1662 }
1663
1664 *rate_store = freq;
1665
1666 return 0;
1667}
1668
1669struct _fll_div {
1670 u16 fll_fratio;
1671 u16 fll_outdiv;
1672 u16 fll_refclk_div;
1673 u16 n;
1674 u16 theta;
1675 u16 lambda;
1676};
1677
1678static struct {
1679 unsigned int min;
1680 unsigned int max;
1681 u16 fll_fratio;
1682 int ratio;
1683} fll_fratios[] = {
1684 { 0, 64000, 4, 16 },
1685 { 64000, 128000, 3, 8 },
1686 { 128000, 256000, 2, 4 },
1687 { 256000, 1000000, 1, 2 },
1688 { 1000000, 13500000, 0, 1 },
1689};
1690
1691static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1692 unsigned int Fout)
1693{
1694 unsigned int target;
1695 unsigned int div;
1696 unsigned int fratio, gcd_fll;
1697 int i;
1698
1699 /* Fref must be <=13.5MHz */
1700 div = 1;
1701 fll_div->fll_refclk_div = 0;
1702 while ((Fref / div) > 13500000) {
1703 div *= 2;
1704 fll_div->fll_refclk_div++;
1705
1706 if (div > 8) {
1707 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1708 Fref);
1709 return -EINVAL;
1710 }
1711 }
1712
1713 pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
1714
1715 /* Apply the division for our remaining calculations */
1716 Fref /= div;
1717
1718 /* Fvco should be 90-100MHz; don't check the upper bound */
1719 div = 2;
1720 while (Fout * div < 90000000) {
1721 div++;
1722 if (div > 64) {
1723 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1724 Fout);
1725 return -EINVAL;
1726 }
1727 }
1728 target = Fout * div;
1729 fll_div->fll_outdiv = div - 1;
1730
1731 pr_debug("FLL Fvco=%dHz\n", target);
1732
1733 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1734 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1735 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1736 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1737 fratio = fll_fratios[i].ratio;
1738 break;
1739 }
1740 }
1741 if (i == ARRAY_SIZE(fll_fratios)) {
1742 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1743 return -EINVAL;
1744 }
1745
1746 fll_div->n = target / (fratio * Fref);
1747
1748 if (target % Fref == 0) {
1749 fll_div->theta = 0;
1750 fll_div->lambda = 0;
1751 } else {
1752 gcd_fll = gcd(target, fratio * Fref);
1753
1754 fll_div->theta = (target - (fll_div->n * fratio * Fref))
1755 / gcd_fll;
1756 fll_div->lambda = (fratio * Fref) / gcd_fll;
1757 }
1758
1759 pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
1760 fll_div->n, fll_div->theta, fll_div->lambda);
1761 pr_debug("FLL_FRATIO=%x(%d) FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
1762 fll_div->fll_fratio, fratio, fll_div->fll_outdiv,
1763 fll_div->fll_refclk_div);
1764
1765 return 0;
1766}
1767
1768static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1769 unsigned int Fref, unsigned int Fout)
1770{
1771 struct i2c_client *i2c = to_i2c_client(codec->dev);
1772 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1773 struct _fll_div factors;
1774 struct wm5100_fll *fll;
1775 int ret, base, lock, i, timeout;
1776
1777 switch (fll_id) {
1778 case WM5100_FLL1:
1779 fll = &wm5100->fll[0];
1780 base = WM5100_FLL1_CONTROL_1 - 1;
1781 lock = WM5100_FLL1_LOCK_STS;
1782 break;
1783 case WM5100_FLL2:
1784 fll = &wm5100->fll[1];
1785 base = WM5100_FLL2_CONTROL_2 - 1;
1786 lock = WM5100_FLL2_LOCK_STS;
1787 break;
1788 default:
1789 dev_err(codec->dev, "Unknown FLL %d\n",fll_id);
1790 return -EINVAL;
1791 }
1792
1793 if (!Fout) {
1794 dev_dbg(codec->dev, "FLL%d disabled", fll_id);
62c1c401
MB
1795 if (fll->fout)
1796 pm_runtime_put(codec->dev);
6d4baf08
MB
1797 fll->fout = 0;
1798 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
1799 return 0;
1800 }
1801
1802 switch (source) {
1803 case WM5100_FLL_SRC_MCLK1:
1804 case WM5100_FLL_SRC_MCLK2:
1805 case WM5100_FLL_SRC_FLL1:
1806 case WM5100_FLL_SRC_FLL2:
1807 case WM5100_FLL_SRC_AIF1BCLK:
1808 case WM5100_FLL_SRC_AIF2BCLK:
1809 case WM5100_FLL_SRC_AIF3BCLK:
1810 break;
1811 default:
1812 dev_err(codec->dev, "Invalid FLL source %d\n", source);
1813 return -EINVAL;
1814 }
1815
1816 ret = fll_factors(&factors, Fref, Fout);
1817 if (ret < 0)
1818 return ret;
1819
1820 /* Disable the FLL while we reconfigure */
1821 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
1822
1823 snd_soc_update_bits(codec, base + 2,
1824 WM5100_FLL1_OUTDIV_MASK | WM5100_FLL1_FRATIO_MASK,
1825 (factors.fll_outdiv << WM5100_FLL1_OUTDIV_SHIFT) |
1826 factors.fll_fratio);
1827 snd_soc_update_bits(codec, base + 3, WM5100_FLL1_THETA_MASK,
1828 factors.theta);
1829 snd_soc_update_bits(codec, base + 5, WM5100_FLL1_N_MASK, factors.n);
1830 snd_soc_update_bits(codec, base + 6,
1831 WM5100_FLL1_REFCLK_DIV_MASK |
1832 WM5100_FLL1_REFCLK_SRC_MASK,
1833 (factors.fll_refclk_div
1834 << WM5100_FLL1_REFCLK_DIV_SHIFT) | source);
1835 snd_soc_update_bits(codec, base + 7, WM5100_FLL1_LAMBDA_MASK,
1836 factors.lambda);
1837
1838 /* Clear any pending completions */
1839 try_wait_for_completion(&fll->lock);
1840
62c1c401
MB
1841 pm_runtime_get_sync(codec->dev);
1842
6d4baf08
MB
1843 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA);
1844
1845 if (i2c->irq)
1846 timeout = 2;
1847 else
1848 timeout = 50;
1849
bd132ec5
MB
1850 snd_soc_update_bits(codec, WM5100_CLOCKING_3, WM5100_SYSCLK_ENA,
1851 WM5100_SYSCLK_ENA);
1852
6d4baf08
MB
1853 /* Poll for the lock; will use interrupt when we can test */
1854 for (i = 0; i < timeout; i++) {
1855 if (i2c->irq) {
1856 ret = wait_for_completion_timeout(&fll->lock,
1857 msecs_to_jiffies(25));
1858 if (ret > 0)
1859 break;
1860 } else {
1861 msleep(1);
1862 }
1863
1864 ret = snd_soc_read(codec,
1865 WM5100_INTERRUPT_RAW_STATUS_3);
1866 if (ret < 0) {
1867 dev_err(codec->dev,
1868 "Failed to read FLL status: %d\n",
1869 ret);
1870 continue;
1871 }
1872 if (ret & lock)
1873 break;
1874 }
1875 if (i == timeout) {
1876 dev_err(codec->dev, "FLL%d lock timed out\n", fll_id);
62c1c401 1877 pm_runtime_put(codec->dev);
6d4baf08
MB
1878 return -ETIMEDOUT;
1879 }
1880
1881 fll->src = source;
1882 fll->fref = Fref;
1883 fll->fout = Fout;
1884
1885 dev_dbg(codec->dev, "FLL%d running %dHz->%dHz\n", fll_id,
1886 Fref, Fout);
1887
1888 return 0;
1889}
1890
1891/* Actually go much higher */
1892#define WM5100_RATES SNDRV_PCM_RATE_8000_192000
1893
1894#define WM5100_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1895 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1896
1897static struct snd_soc_dai_driver wm5100_dai[] = {
1898 {
1899 .name = "wm5100-aif1",
1900 .playback = {
1901 .stream_name = "AIF1 Playback",
1902 .channels_min = 2,
1903 .channels_max = 2,
1904 .rates = WM5100_RATES,
1905 .formats = WM5100_FORMATS,
1906 },
1907 .capture = {
1908 .stream_name = "AIF1 Capture",
1909 .channels_min = 2,
1910 .channels_max = 2,
1911 .rates = WM5100_RATES,
1912 .formats = WM5100_FORMATS,
1913 },
1914 .ops = &wm5100_dai_ops,
1915 },
1916 {
1917 .name = "wm5100-aif2",
1918 .id = 1,
1919 .playback = {
1920 .stream_name = "AIF2 Playback",
1921 .channels_min = 2,
1922 .channels_max = 2,
1923 .rates = WM5100_RATES,
1924 .formats = WM5100_FORMATS,
1925 },
1926 .capture = {
1927 .stream_name = "AIF2 Capture",
1928 .channels_min = 2,
1929 .channels_max = 2,
1930 .rates = WM5100_RATES,
1931 .formats = WM5100_FORMATS,
1932 },
1933 .ops = &wm5100_dai_ops,
1934 },
1935 {
1936 .name = "wm5100-aif3",
1937 .id = 2,
1938 .playback = {
1939 .stream_name = "AIF3 Playback",
1940 .channels_min = 2,
1941 .channels_max = 2,
1942 .rates = WM5100_RATES,
1943 .formats = WM5100_FORMATS,
1944 },
1945 .capture = {
1946 .stream_name = "AIF3 Capture",
1947 .channels_min = 2,
1948 .channels_max = 2,
1949 .rates = WM5100_RATES,
1950 .formats = WM5100_FORMATS,
1951 },
1952 .ops = &wm5100_dai_ops,
1953 },
1954};
1955
1956static int wm5100_dig_vu[] = {
1957 WM5100_ADC_DIGITAL_VOLUME_1L,
1958 WM5100_ADC_DIGITAL_VOLUME_1R,
1959 WM5100_ADC_DIGITAL_VOLUME_2L,
1960 WM5100_ADC_DIGITAL_VOLUME_2R,
1961 WM5100_ADC_DIGITAL_VOLUME_3L,
1962 WM5100_ADC_DIGITAL_VOLUME_3R,
1963 WM5100_ADC_DIGITAL_VOLUME_4L,
1964 WM5100_ADC_DIGITAL_VOLUME_4R,
1965
1966 WM5100_DAC_DIGITAL_VOLUME_1L,
1967 WM5100_DAC_DIGITAL_VOLUME_1R,
1968 WM5100_DAC_DIGITAL_VOLUME_2L,
1969 WM5100_DAC_DIGITAL_VOLUME_2R,
1970 WM5100_DAC_DIGITAL_VOLUME_3L,
1971 WM5100_DAC_DIGITAL_VOLUME_3R,
1972 WM5100_DAC_DIGITAL_VOLUME_4L,
1973 WM5100_DAC_DIGITAL_VOLUME_4R,
1974 WM5100_DAC_DIGITAL_VOLUME_5L,
1975 WM5100_DAC_DIGITAL_VOLUME_5R,
1976 WM5100_DAC_DIGITAL_VOLUME_6L,
1977 WM5100_DAC_DIGITAL_VOLUME_6R,
1978};
1979
46c1a877 1980static void wm5100_set_detect_mode(struct wm5100_priv *wm5100, int the_mode)
ba896ede 1981{
ba896ede
MB
1982 struct wm5100_jack_mode *mode = &wm5100->pdata.jack_modes[the_mode];
1983
1984 BUG_ON(the_mode >= ARRAY_SIZE(wm5100->pdata.jack_modes));
1985
1986 gpio_set_value_cansleep(wm5100->pdata.hp_pol, mode->hp_pol);
46c1a877
MB
1987 regmap_update_bits(wm5100->regmap, WM5100_ACCESSORY_DETECT_MODE_1,
1988 WM5100_ACCDET_BIAS_SRC_MASK |
1989 WM5100_ACCDET_SRC,
1990 (mode->bias << WM5100_ACCDET_BIAS_SRC_SHIFT) |
1991 mode->micd_src << WM5100_ACCDET_SRC_SHIFT);
1992 regmap_update_bits(wm5100->regmap, WM5100_MISC_CONTROL,
1993 WM5100_HPCOM_SRC,
1994 mode->micd_src << WM5100_HPCOM_SRC_SHIFT);
ba896ede
MB
1995
1996 wm5100->jack_mode = the_mode;
1997
46c1a877 1998 dev_dbg(wm5100->dev, "Set microphone polarity to %d\n",
ba896ede
MB
1999 wm5100->jack_mode);
2000}
2001
2633f736
MB
2002static void wm5100_report_headphone(struct wm5100_priv *wm5100)
2003{
2004 dev_dbg(wm5100->dev, "Headphone detected\n");
2005 wm5100->jack_detecting = false;
2006 snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE,
2007 SND_JACK_HEADPHONE);
2008
2009 /* Increase the detection rate a bit for responsiveness. */
2010 regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1,
2011 WM5100_ACCDET_RATE_MASK,
2012 7 << WM5100_ACCDET_RATE_SHIFT);
2013}
2014
46c1a877 2015static void wm5100_micd_irq(struct wm5100_priv *wm5100)
ba896ede 2016{
46c1a877
MB
2017 unsigned int val;
2018 int ret;
ba896ede 2019
46c1a877
MB
2020 ret = regmap_read(wm5100->regmap, WM5100_MIC_DETECT_3, &val);
2021 if (ret != 0) {
2022 dev_err(wm5100->dev, "Failed to read micropone status: %d\n",
2023 ret);
2024 return;
2025 }
ba896ede 2026
46c1a877 2027 dev_dbg(wm5100->dev, "Microphone event: %x\n", val);
ba896ede
MB
2028
2029 if (!(val & WM5100_ACCDET_VALID)) {
46c1a877 2030 dev_warn(wm5100->dev, "Microphone detection state invalid\n");
ba896ede
MB
2031 return;
2032 }
2033
2034 /* No accessory, reset everything and report removal */
2035 if (!(val & WM5100_ACCDET_STS)) {
46c1a877 2036 dev_dbg(wm5100->dev, "Jack removal detected\n");
ba896ede
MB
2037 wm5100->jack_mic = false;
2038 wm5100->jack_detecting = true;
2633f736 2039 wm5100->jack_flips = 0;
ba896ede
MB
2040 snd_soc_jack_report(wm5100->jack, 0,
2041 SND_JACK_LINEOUT | SND_JACK_HEADSET |
2042 SND_JACK_BTN_0);
2043
46c1a877
MB
2044 regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1,
2045 WM5100_ACCDET_RATE_MASK,
2046 WM5100_ACCDET_RATE_MASK);
ba896ede
MB
2047 return;
2048 }
2049
2050 /* If the measurement is very high we've got a microphone,
2051 * either we just detected one or if we already reported then
2052 * we've got a button release event.
2053 */
2054 if (val & 0x400) {
2055 if (wm5100->jack_detecting) {
46c1a877 2056 dev_dbg(wm5100->dev, "Microphone detected\n");
ba896ede 2057 wm5100->jack_mic = true;
9fb83526 2058 wm5100->jack_detecting = false;
ba896ede
MB
2059 snd_soc_jack_report(wm5100->jack,
2060 SND_JACK_HEADSET,
2061 SND_JACK_HEADSET | SND_JACK_BTN_0);
2062
2063 /* Increase poll rate to give better responsiveness
2064 * for buttons */
46c1a877
MB
2065 regmap_update_bits(wm5100->regmap, WM5100_MIC_DETECT_1,
2066 WM5100_ACCDET_RATE_MASK,
2067 5 << WM5100_ACCDET_RATE_SHIFT);
ba896ede 2068 } else {
46c1a877 2069 dev_dbg(wm5100->dev, "Mic button up\n");
ba896ede
MB
2070 snd_soc_jack_report(wm5100->jack, 0, SND_JACK_BTN_0);
2071 }
2072
2073 return;
2074 }
2075
2076 /* If we detected a lower impedence during initial startup
2077 * then we probably have the wrong polarity, flip it. Don't
2078 * do this for the lowest impedences to speed up detection of
2633f736
MB
2079 * plain headphones and give up if neither polarity looks
2080 * sensible.
ba896ede
MB
2081 */
2082 if (wm5100->jack_detecting && (val & 0x3f8)) {
2633f736
MB
2083 wm5100->jack_flips++;
2084
2085 if (wm5100->jack_flips > 1)
2086 wm5100_report_headphone(wm5100);
2087 else
2088 wm5100_set_detect_mode(wm5100, !wm5100->jack_mode);
ba896ede
MB
2089
2090 return;
2091 }
2092
2093 /* Don't distinguish between buttons, just report any low
2094 * impedence as BTN_0.
2095 */
2096 if (val & 0x3fc) {
2097 if (wm5100->jack_mic) {
46c1a877 2098 dev_dbg(wm5100->dev, "Mic button detected\n");
ba896ede
MB
2099 snd_soc_jack_report(wm5100->jack, SND_JACK_BTN_0,
2100 SND_JACK_BTN_0);
2101 } else if (wm5100->jack_detecting) {
2633f736 2102 wm5100_report_headphone(wm5100);
ba896ede
MB
2103 }
2104 }
2105}
2106
2107int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack)
2108{
2109 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2110
2111 if (jack) {
2112 wm5100->jack = jack;
2113 wm5100->jack_detecting = true;
2633f736 2114 wm5100->jack_flips = 0;
ba896ede 2115
46c1a877 2116 wm5100_set_detect_mode(wm5100, 0);
ba896ede
MB
2117
2118 /* Slowest detection rate, gives debounce for initial
2119 * detection */
2120 snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
2121 WM5100_ACCDET_BIAS_STARTTIME_MASK |
2122 WM5100_ACCDET_RATE_MASK,
2123 (7 << WM5100_ACCDET_BIAS_STARTTIME_SHIFT) |
2124 WM5100_ACCDET_RATE_MASK);
2125
2126 /* We need the charge pump to power MICBIAS */
2127 snd_soc_dapm_force_enable_pin(&codec->dapm, "CP2");
2128 snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK");
2129 snd_soc_dapm_sync(&codec->dapm);
2130
2131 /* We start off just enabling microphone detection - even a
2132 * plain headphone will trigger detection.
2133 */
2134 snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
2135 WM5100_ACCDET_ENA, WM5100_ACCDET_ENA);
2136
2137 snd_soc_update_bits(codec, WM5100_INTERRUPT_STATUS_3_MASK,
2138 WM5100_IM_ACCDET_EINT, 0);
2139 } else {
2140 snd_soc_update_bits(codec, WM5100_INTERRUPT_STATUS_3_MASK,
2141 WM5100_IM_HPDET_EINT |
2142 WM5100_IM_ACCDET_EINT,
2143 WM5100_IM_HPDET_EINT |
2144 WM5100_IM_ACCDET_EINT);
2145 snd_soc_update_bits(codec, WM5100_MIC_DETECT_1,
2146 WM5100_ACCDET_ENA, 0);
2147 wm5100->jack = NULL;
2148 }
2149
2150 return 0;
2151}
2152
6d4baf08
MB
2153static irqreturn_t wm5100_irq(int irq, void *data)
2154{
46c1a877 2155 struct wm5100_priv *wm5100 = data;
6d4baf08 2156 irqreturn_t status = IRQ_NONE;
46c1a877
MB
2157 unsigned int irq_val, mask_val;
2158 int ret;
6d4baf08 2159
46c1a877
MB
2160 ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_3, &irq_val);
2161 if (ret < 0) {
2162 dev_err(wm5100->dev, "Failed to read IRQ status 3: %d\n",
2163 ret);
6d4baf08
MB
2164 irq_val = 0;
2165 }
6d4baf08 2166
46c1a877
MB
2167 ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_3_MASK,
2168 &mask_val);
2169 if (ret < 0) {
2170 dev_err(wm5100->dev, "Failed to read IRQ mask 3: %d\n",
2171 ret);
2172 mask_val = 0xffff;
2173 }
2174
2175 irq_val &= ~mask_val;
2176
2177 regmap_write(wm5100->regmap, WM5100_INTERRUPT_STATUS_3, irq_val);
6d4baf08
MB
2178
2179 if (irq_val)
2180 status = IRQ_HANDLED;
2181
46c1a877 2182 wm5100_log_status3(wm5100, irq_val);
6d4baf08
MB
2183
2184 if (irq_val & WM5100_FLL1_LOCK_EINT) {
46c1a877 2185 dev_dbg(wm5100->dev, "FLL1 locked\n");
6d4baf08
MB
2186 complete(&wm5100->fll[0].lock);
2187 }
2188 if (irq_val & WM5100_FLL2_LOCK_EINT) {
46c1a877 2189 dev_dbg(wm5100->dev, "FLL2 locked\n");
6d4baf08
MB
2190 complete(&wm5100->fll[1].lock);
2191 }
2192
ba896ede 2193 if (irq_val & WM5100_ACCDET_EINT)
46c1a877 2194 wm5100_micd_irq(wm5100);
ba896ede 2195
46c1a877
MB
2196 ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_4, &irq_val);
2197 if (ret < 0) {
2198 dev_err(wm5100->dev, "Failed to read IRQ status 4: %d\n",
2199 ret);
6d4baf08
MB
2200 irq_val = 0;
2201 }
46c1a877
MB
2202
2203 ret = regmap_read(wm5100->regmap, WM5100_INTERRUPT_STATUS_4_MASK,
2204 &mask_val);
2205 if (ret < 0) {
2206 dev_err(wm5100->dev, "Failed to read IRQ mask 4: %d\n",
2207 ret);
2208 mask_val = 0xffff;
2209 }
2210
2211 irq_val &= ~mask_val;
6d4baf08
MB
2212
2213 if (irq_val)
2214 status = IRQ_HANDLED;
2215
46c1a877 2216 regmap_write(wm5100->regmap, WM5100_INTERRUPT_STATUS_4, irq_val);
6d4baf08 2217
46c1a877 2218 wm5100_log_status4(wm5100, irq_val);
6d4baf08
MB
2219
2220 return status;
2221}
2222
2223static irqreturn_t wm5100_edge_irq(int irq, void *data)
2224{
2225 irqreturn_t ret = IRQ_NONE;
2226 irqreturn_t val;
2227
2228 do {
2229 val = wm5100_irq(irq, data);
2230 if (val != IRQ_NONE)
2231 ret = val;
2232 } while (val != IRQ_NONE);
2233
2234 return ret;
2235}
2236
2237#ifdef CONFIG_GPIOLIB
2238static inline struct wm5100_priv *gpio_to_wm5100(struct gpio_chip *chip)
2239{
2240 return container_of(chip, struct wm5100_priv, gpio_chip);
2241}
2242
2243static void wm5100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
2244{
2245 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
6d4baf08 2246
9db16e4c
MB
2247 regmap_update_bits(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset,
2248 WM5100_GP1_LVL, !!value << WM5100_GP1_LVL_SHIFT);
6d4baf08
MB
2249}
2250
2251static int wm5100_gpio_direction_out(struct gpio_chip *chip,
2252 unsigned offset, int value)
2253{
2254 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
64964e82 2255 int val, ret;
6d4baf08
MB
2256
2257 val = (1 << WM5100_GP1_FN_SHIFT) | (!!value << WM5100_GP1_LVL_SHIFT);
2258
9db16e4c
MB
2259 ret = regmap_update_bits(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset,
2260 WM5100_GP1_FN_MASK | WM5100_GP1_DIR |
2261 WM5100_GP1_LVL, val);
64964e82
MB
2262 if (ret < 0)
2263 return ret;
2264 else
2265 return 0;
6d4baf08
MB
2266}
2267
2268static int wm5100_gpio_get(struct gpio_chip *chip, unsigned offset)
2269{
2270 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
9db16e4c 2271 unsigned int reg;
6d4baf08
MB
2272 int ret;
2273
9db16e4c 2274 ret = regmap_read(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset, &reg);
6d4baf08
MB
2275 if (ret < 0)
2276 return ret;
2277
9db16e4c 2278 return (reg & WM5100_GP1_LVL) != 0;
6d4baf08
MB
2279}
2280
2281static int wm5100_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
2282{
2283 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
6d4baf08 2284
9db16e4c
MB
2285 return regmap_update_bits(wm5100->regmap, WM5100_GPIO_CTRL_1 + offset,
2286 WM5100_GP1_FN_MASK | WM5100_GP1_DIR,
2287 (1 << WM5100_GP1_FN_SHIFT) |
2288 (1 << WM5100_GP1_DIR_SHIFT));
6d4baf08
MB
2289}
2290
2291static struct gpio_chip wm5100_template_chip = {
2292 .label = "wm5100",
2293 .owner = THIS_MODULE,
2294 .direction_output = wm5100_gpio_direction_out,
2295 .set = wm5100_gpio_set,
2296 .direction_input = wm5100_gpio_direction_in,
2297 .get = wm5100_gpio_get,
2298 .can_sleep = 1,
2299};
2300
9db16e4c 2301static void wm5100_init_gpio(struct i2c_client *i2c)
6d4baf08 2302{
9db16e4c 2303 struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c);
6d4baf08
MB
2304 int ret;
2305
2306 wm5100->gpio_chip = wm5100_template_chip;
2307 wm5100->gpio_chip.ngpio = 6;
9db16e4c 2308 wm5100->gpio_chip.dev = &i2c->dev;
6d4baf08
MB
2309
2310 if (wm5100->pdata.gpio_base)
2311 wm5100->gpio_chip.base = wm5100->pdata.gpio_base;
2312 else
2313 wm5100->gpio_chip.base = -1;
2314
2315 ret = gpiochip_add(&wm5100->gpio_chip);
2316 if (ret != 0)
9db16e4c 2317 dev_err(&i2c->dev, "Failed to add GPIOs: %d\n", ret);
6d4baf08
MB
2318}
2319
9db16e4c 2320static void wm5100_free_gpio(struct i2c_client *i2c)
6d4baf08 2321{
9db16e4c 2322 struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c);
6d4baf08
MB
2323 int ret;
2324
2325 ret = gpiochip_remove(&wm5100->gpio_chip);
2326 if (ret != 0)
9db16e4c 2327 dev_err(&i2c->dev, "Failed to remove GPIOs: %d\n", ret);
6d4baf08
MB
2328}
2329#else
9db16e4c 2330static void wm5100_init_gpio(struct i2c_client *i2c)
6d4baf08
MB
2331{
2332}
2333
9db16e4c 2334static void wm5100_free_gpio(struct i2c_client *i2c)
6d4baf08
MB
2335{
2336}
2337#endif
2338
2339static int wm5100_probe(struct snd_soc_codec *codec)
2340{
2341 struct i2c_client *i2c = to_i2c_client(codec->dev);
2342 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
09452f23 2343 int ret, i;
6d4baf08
MB
2344
2345 wm5100->codec = codec;
bd132ec5 2346 codec->control_data = wm5100->regmap;
6d4baf08 2347
bd132ec5 2348 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
6d4baf08
MB
2349 if (ret != 0) {
2350 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2351 return ret;
2352 }
2353
6d4baf08
MB
2354 for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++)
2355 snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU,
2356 WM5100_OUT_VU);
2357
6d4baf08
MB
2358 /* Don't debounce interrupts to support use of SYSCLK only */
2359 snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_1, 0);
2360 snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_2, 0);
2361
2362 /* TODO: check if we're symmetric */
2363
09452f23 2364 if (i2c->irq)
6d4baf08
MB
2365 snd_soc_dapm_new_controls(&codec->dapm,
2366 wm5100_dapm_widgets_noirq,
2367 ARRAY_SIZE(wm5100_dapm_widgets_noirq));
6d4baf08
MB
2368
2369 if (wm5100->pdata.hp_pol) {
2370 ret = gpio_request_one(wm5100->pdata.hp_pol,
2371 GPIOF_OUT_INIT_HIGH, "WM5100 HP_POL");
2372 if (ret < 0) {
2373 dev_err(&i2c->dev, "Failed to request HP_POL %d: %d\n",
2374 wm5100->pdata.hp_pol, ret);
2375 goto err_gpio;
2376 }
2377 }
2378
6d4baf08
MB
2379 return 0;
2380
2381err_gpio:
6d4baf08
MB
2382
2383 return ret;
2384}
2385
2386static int wm5100_remove(struct snd_soc_codec *codec)
2387{
2388 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2389
6d4baf08
MB
2390 if (wm5100->pdata.hp_pol) {
2391 gpio_free(wm5100->pdata.hp_pol);
2392 }
46c1a877 2393
6d4baf08
MB
2394 return 0;
2395}
2396
1b39bf34
MB
2397static int wm5100_soc_volatile(struct snd_soc_codec *codec,
2398 unsigned int reg)
2399{
2400 return true;
2401}
2402
2403
6d4baf08
MB
2404static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
2405 .probe = wm5100_probe,
2406 .remove = wm5100_remove,
2407
2408 .set_sysclk = wm5100_set_sysclk,
2409 .set_pll = wm5100_set_fll,
6d4baf08 2410 .idle_bias_off = 1,
1b39bf34
MB
2411 .reg_cache_size = WM5100_MAX_REGISTER,
2412 .volatile_register = wm5100_soc_volatile,
6d4baf08
MB
2413
2414 .seq_notifier = wm5100_seq_notifier,
2415 .controls = wm5100_snd_controls,
2416 .num_controls = ARRAY_SIZE(wm5100_snd_controls),
2417 .dapm_widgets = wm5100_dapm_widgets,
2418 .num_dapm_widgets = ARRAY_SIZE(wm5100_dapm_widgets),
2419 .dapm_routes = wm5100_dapm_routes,
2420 .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes),
bd132ec5 2421};
6d4baf08 2422
bd132ec5
MB
2423static const struct regmap_config wm5100_regmap = {
2424 .reg_bits = 16,
2425 .val_bits = 16,
6d4baf08 2426
bd132ec5
MB
2427 .max_register = WM5100_MAX_REGISTER,
2428 .reg_defaults = wm5100_reg_defaults,
2429 .num_reg_defaults = ARRAY_SIZE(wm5100_reg_defaults),
2430 .volatile_reg = wm5100_volatile_register,
2431 .readable_reg = wm5100_readable_register,
2432 .cache_type = REGCACHE_RBTREE,
6d4baf08
MB
2433};
2434
a188fcba
MB
2435static const unsigned int wm5100_mic_ctrl_reg[] = {
2436 WM5100_IN1L_CONTROL,
2437 WM5100_IN2L_CONTROL,
2438 WM5100_IN3L_CONTROL,
2439 WM5100_IN4L_CONTROL,
2440};
2441
6d4baf08
MB
2442static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2443 const struct i2c_device_id *id)
2444{
2445 struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev);
2446 struct wm5100_priv *wm5100;
588ac5e0 2447 unsigned int reg;
09452f23 2448 int ret, i, irq_flags;
6d4baf08 2449
a81b82c0
MB
2450 wm5100 = devm_kzalloc(&i2c->dev, sizeof(struct wm5100_priv),
2451 GFP_KERNEL);
6d4baf08
MB
2452 if (wm5100 == NULL)
2453 return -ENOMEM;
2454
46c1a877
MB
2455 wm5100->dev = &i2c->dev;
2456
77caabaa 2457 wm5100->regmap = devm_regmap_init_i2c(i2c, &wm5100_regmap);
bd132ec5
MB
2458 if (IS_ERR(wm5100->regmap)) {
2459 ret = PTR_ERR(wm5100->regmap);
2460 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
2461 ret);
a81b82c0 2462 goto err;
bd132ec5
MB
2463 }
2464
6d4baf08
MB
2465 for (i = 0; i < ARRAY_SIZE(wm5100->fll); i++)
2466 init_completion(&wm5100->fll[i].lock);
2467
2468 if (pdata)
2469 wm5100->pdata = *pdata;
2470
2471 i2c_set_clientdata(i2c, wm5100);
2472
588ac5e0
MB
2473 for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++)
2474 wm5100->core_supplies[i].supply = wm5100_core_supply_names[i];
2475
17e3e57b
MB
2476 ret = devm_regulator_bulk_get(&i2c->dev,
2477 ARRAY_SIZE(wm5100->core_supplies),
2478 wm5100->core_supplies);
588ac5e0
MB
2479 if (ret != 0) {
2480 dev_err(&i2c->dev, "Failed to request core supplies: %d\n",
2481 ret);
77caabaa 2482 goto err;
588ac5e0
MB
2483 }
2484
588ac5e0
MB
2485 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
2486 wm5100->core_supplies);
2487 if (ret != 0) {
2488 dev_err(&i2c->dev, "Failed to enable core supplies: %d\n",
2489 ret);
77caabaa 2490 goto err;
588ac5e0
MB
2491 }
2492
2493 if (wm5100->pdata.ldo_ena) {
2494 ret = gpio_request_one(wm5100->pdata.ldo_ena,
2495 GPIOF_OUT_INIT_HIGH, "WM5100 LDOENA");
2496 if (ret < 0) {
2497 dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n",
2498 wm5100->pdata.ldo_ena, ret);
2499 goto err_enable;
2500 }
2501 msleep(2);
2502 }
2503
2504 if (wm5100->pdata.reset) {
2505 ret = gpio_request_one(wm5100->pdata.reset,
2506 GPIOF_OUT_INIT_HIGH, "WM5100 /RESET");
2507 if (ret < 0) {
2508 dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n",
2509 wm5100->pdata.reset, ret);
2510 goto err_ldo;
2511 }
2512 }
2513
2514 ret = regmap_read(wm5100->regmap, WM5100_SOFTWARE_RESET, &reg);
2515 if (ret < 0) {
0132615d 2516 dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
588ac5e0
MB
2517 goto err_reset;
2518 }
2519 switch (reg) {
2520 case 0x8997:
2521 case 0x5100:
2522 break;
2523
2524 default:
2525 dev_err(&i2c->dev, "Device is not a WM5100, ID is %x\n", reg);
2526 ret = -EINVAL;
2527 goto err_reset;
2528 }
2529
2530 ret = regmap_read(wm5100->regmap, WM5100_DEVICE_REVISION, &reg);
2531 if (ret < 0) {
2532 dev_err(&i2c->dev, "Failed to read revision register\n");
2533 goto err_reset;
2534 }
2535 wm5100->rev = reg & WM5100_DEVICE_REVISION_MASK;
2536
2537 dev_info(&i2c->dev, "revision %c\n", wm5100->rev + 'A');
2538
2539 ret = wm5100_reset(wm5100);
2540 if (ret < 0) {
2541 dev_err(&i2c->dev, "Failed to issue reset\n");
2542 goto err_reset;
2543 }
2544
15b52f10
MB
2545 switch (wm5100->rev) {
2546 case 0:
2547 ret = regmap_register_patch(wm5100->regmap,
2548 wm5100_reva_patches,
2549 ARRAY_SIZE(wm5100_reva_patches));
2550 if (ret != 0) {
2551 dev_err(&i2c->dev, "Failed to register patches: %d\n",
2552 ret);
2553 goto err_reset;
2554 }
2555 break;
2556 default:
2557 break;
2558 }
2559
2560
9db16e4c
MB
2561 wm5100_init_gpio(i2c);
2562
d9b5e9c6
MB
2563 for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) {
2564 if (!wm5100->pdata.gpio_defaults[i])
2565 continue;
2566
2567 regmap_write(wm5100->regmap, WM5100_GPIO_CTRL_1 + i,
2568 wm5100->pdata.gpio_defaults[i]);
2569 }
2570
2571 for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) {
a188fcba 2572 regmap_update_bits(wm5100->regmap, wm5100_mic_ctrl_reg[i],
d9b5e9c6
MB
2573 WM5100_IN1_MODE_MASK |
2574 WM5100_IN1_DMIC_SUP_MASK,
2575 (wm5100->pdata.in_mode[i] <<
2576 WM5100_IN1_MODE_SHIFT) |
2577 (wm5100->pdata.dmic_sup[i] <<
2578 WM5100_IN1_DMIC_SUP_SHIFT));
2579 }
2580
09452f23
MB
2581 if (i2c->irq) {
2582 if (wm5100->pdata.irq_flags)
2583 irq_flags = wm5100->pdata.irq_flags;
2584 else
2585 irq_flags = IRQF_TRIGGER_LOW;
2586
2587 irq_flags |= IRQF_ONESHOT;
2588
2589 if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
2590 ret = request_threaded_irq(i2c->irq, NULL,
2591 wm5100_edge_irq, irq_flags,
2592 "wm5100", wm5100);
2593 else
2594 ret = request_threaded_irq(i2c->irq, NULL, wm5100_irq,
2595 irq_flags, "wm5100",
2596 wm5100);
2597
2598 if (ret != 0) {
2599 dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
2600 i2c->irq, ret);
2601 } else {
2602 /* Enable default interrupts */
2603 regmap_update_bits(wm5100->regmap,
2604 WM5100_INTERRUPT_STATUS_3_MASK,
2605 WM5100_IM_SPK_SHUTDOWN_WARN_EINT |
2606 WM5100_IM_SPK_SHUTDOWN_EINT |
2607 WM5100_IM_ASRC2_LOCK_EINT |
2608 WM5100_IM_ASRC1_LOCK_EINT |
2609 WM5100_IM_FLL2_LOCK_EINT |
2610 WM5100_IM_FLL1_LOCK_EINT |
2611 WM5100_CLKGEN_ERR_EINT |
2612 WM5100_CLKGEN_ERR_ASYNC_EINT, 0);
2613
2614 regmap_update_bits(wm5100->regmap,
2615 WM5100_INTERRUPT_STATUS_4_MASK,
2616 WM5100_AIF3_ERR_EINT |
2617 WM5100_AIF2_ERR_EINT |
2618 WM5100_AIF1_ERR_EINT |
2619 WM5100_CTRLIF_ERR_EINT |
2620 WM5100_ISRC2_UNDERCLOCKED_EINT |
2621 WM5100_ISRC1_UNDERCLOCKED_EINT |
2622 WM5100_FX_UNDERCLOCKED_EINT |
2623 WM5100_AIF3_UNDERCLOCKED_EINT |
2624 WM5100_AIF2_UNDERCLOCKED_EINT |
2625 WM5100_AIF1_UNDERCLOCKED_EINT |
2626 WM5100_ASRC_UNDERCLOCKED_EINT |
2627 WM5100_DAC_UNDERCLOCKED_EINT |
2628 WM5100_ADC_UNDERCLOCKED_EINT |
2629 WM5100_MIXER_UNDERCLOCKED_EINT, 0);
2630 }
2631 }
2632
62c1c401
MB
2633 pm_runtime_set_active(&i2c->dev);
2634 pm_runtime_enable(&i2c->dev);
2635 pm_request_idle(&i2c->dev);
2636
6d4baf08
MB
2637 ret = snd_soc_register_codec(&i2c->dev,
2638 &soc_codec_dev_wm5100, wm5100_dai,
2639 ARRAY_SIZE(wm5100_dai));
2640 if (ret < 0) {
2641 dev_err(&i2c->dev, "Failed to register WM5100: %d\n", ret);
588ac5e0 2642 goto err_reset;
6d4baf08
MB
2643 }
2644
2645 return ret;
bd132ec5 2646
588ac5e0 2647err_reset:
09452f23
MB
2648 if (i2c->irq)
2649 free_irq(i2c->irq, wm5100);
9db16e4c 2650 wm5100_free_gpio(i2c);
588ac5e0 2651 if (wm5100->pdata.reset) {
2688738e 2652 gpio_set_value_cansleep(wm5100->pdata.reset, 0);
588ac5e0
MB
2653 gpio_free(wm5100->pdata.reset);
2654 }
2655err_ldo:
2656 if (wm5100->pdata.ldo_ena) {
2657 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2658 gpio_free(wm5100->pdata.ldo_ena);
2659 }
2660err_enable:
2661 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2662 wm5100->core_supplies);
a81b82c0 2663err:
bd132ec5 2664 return ret;
6d4baf08
MB
2665}
2666
09452f23 2667static __devexit int wm5100_i2c_remove(struct i2c_client *i2c)
6d4baf08 2668{
09452f23 2669 struct wm5100_priv *wm5100 = i2c_get_clientdata(i2c);
bd132ec5 2670
09452f23
MB
2671 snd_soc_unregister_codec(&i2c->dev);
2672 if (i2c->irq)
2673 free_irq(i2c->irq, wm5100);
2674 wm5100_free_gpio(i2c);
588ac5e0 2675 if (wm5100->pdata.reset) {
2688738e 2676 gpio_set_value_cansleep(wm5100->pdata.reset, 0);
588ac5e0
MB
2677 gpio_free(wm5100->pdata.reset);
2678 }
2679 if (wm5100->pdata.ldo_ena) {
2680 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2681 gpio_free(wm5100->pdata.ldo_ena);
2682 }
bd132ec5 2683
6d4baf08
MB
2684 return 0;
2685}
2686
62c1c401
MB
2687#ifdef CONFIG_PM_RUNTIME
2688static int wm5100_runtime_suspend(struct device *dev)
2689{
2690 struct wm5100_priv *wm5100 = dev_get_drvdata(dev);
2691
2692 regcache_cache_only(wm5100->regmap, true);
2693 regcache_mark_dirty(wm5100->regmap);
2694 if (wm5100->pdata.ldo_ena)
2695 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2696 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2697 wm5100->core_supplies);
2698
2699 return 0;
2700}
2701
2702static int wm5100_runtime_resume(struct device *dev)
2703{
2704 struct wm5100_priv *wm5100 = dev_get_drvdata(dev);
2705 int ret;
2706
2707 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
2708 wm5100->core_supplies);
2709 if (ret != 0) {
2710 dev_err(dev, "Failed to enable supplies: %d\n",
2711 ret);
2712 return ret;
2713 }
2714
2715 if (wm5100->pdata.ldo_ena) {
2716 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 1);
2717 msleep(2);
2718 }
2719
2720 regcache_cache_only(wm5100->regmap, false);
2721 regcache_sync(wm5100->regmap);
2722
2723 return 0;
2724}
2725#endif
2726
2727static struct dev_pm_ops wm5100_pm = {
2728 SET_RUNTIME_PM_OPS(wm5100_runtime_suspend, wm5100_runtime_resume,
2729 NULL)
2730};
2731
6d4baf08
MB
2732static const struct i2c_device_id wm5100_i2c_id[] = {
2733 { "wm5100", 0 },
2734 { }
2735};
2736MODULE_DEVICE_TABLE(i2c, wm5100_i2c_id);
2737
2738static struct i2c_driver wm5100_i2c_driver = {
2739 .driver = {
2740 .name = "wm5100",
2741 .owner = THIS_MODULE,
62c1c401 2742 .pm = &wm5100_pm,
6d4baf08
MB
2743 },
2744 .probe = wm5100_i2c_probe,
2745 .remove = __devexit_p(wm5100_i2c_remove),
2746 .id_table = wm5100_i2c_id,
2747};
2748
2749static int __init wm5100_modinit(void)
2750{
2751 return i2c_add_driver(&wm5100_i2c_driver);
2752}
2753module_init(wm5100_modinit);
2754
2755static void __exit wm5100_exit(void)
2756{
2757 i2c_del_driver(&wm5100_i2c_driver);
2758}
2759module_exit(wm5100_exit);
2760
2761MODULE_DESCRIPTION("ASoC WM5100 driver");
2762MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2763MODULE_LICENSE("GPL");
This page took 0.176061 seconds and 5 git commands to generate.