ASoC: Add missed free_irq in wm5100_remove and wm5100_probe error path
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / sound / soc / codecs / wm5100.c
blobf6039890edfd0e1a28bf0c3e2fc0bfba8b739414
1 /*
2 * wm5100.c -- WM5100 ALSA SoC Audio driver
4 * Copyright 2011 Wolfson Microelectronics plc
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
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.
13 #include <linux/module.h>
14 #include <linux/moduleparam.h>
15 #include <linux/init.h>
16 #include <linux/delay.h>
17 #include <linux/pm.h>
18 #include <linux/gcd.h>
19 #include <linux/gpio.h>
20 #include <linux/i2c.h>
21 #include <linux/platform_device.h>
22 #include <linux/regulator/consumer.h>
23 #include <linux/regulator/fixed.h>
24 #include <linux/slab.h>
25 #include <sound/core.h>
26 #include <sound/pcm.h>
27 #include <sound/pcm_params.h>
28 #include <sound/soc.h>
29 #include <sound/initval.h>
30 #include <sound/tlv.h>
31 #include <sound/wm5100.h>
33 #include "wm5100.h"
35 #define WM5100_NUM_CORE_SUPPLIES 2
36 static const char *wm5100_core_supply_names[WM5100_NUM_CORE_SUPPLIES] = {
37 "DBVDD1",
38 "LDOVDD", /* If DCVDD is supplied externally specify as LDOVDD */
41 #define WM5100_AIFS 3
42 #define WM5100_SYNC_SRS 3
44 struct wm5100_fll {
45 int fref;
46 int fout;
47 int src;
48 struct completion lock;
51 /* codec private data */
52 struct wm5100_priv {
53 struct snd_soc_codec *codec;
55 struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES];
56 struct regulator *cpvdd;
57 struct regulator *dbvdd2;
58 struct regulator *dbvdd3;
60 int rev;
62 int sysclk;
63 int asyncclk;
65 bool aif_async[WM5100_AIFS];
66 bool aif_symmetric[WM5100_AIFS];
67 int sr_ref[WM5100_SYNC_SRS];
69 bool out_ena[2];
71 struct wm5100_fll fll[2];
73 struct wm5100_pdata pdata;
75 #ifdef CONFIG_GPIOLIB
76 struct gpio_chip gpio_chip;
77 #endif
80 static int wm5100_sr_code[] = {
82 12000,
83 24000,
84 48000,
85 96000,
86 192000,
87 384000,
88 768000,
90 11025,
91 22050,
92 44100,
93 88200,
94 176400,
95 352800,
96 705600,
97 4000,
98 8000,
99 16000,
100 32000,
101 64000,
102 128000,
103 256000,
104 512000,
107 static int wm5100_sr_regs[WM5100_SYNC_SRS] = {
108 WM5100_CLOCKING_4,
109 WM5100_CLOCKING_5,
110 WM5100_CLOCKING_6,
113 static int wm5100_alloc_sr(struct snd_soc_codec *codec, int rate)
115 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
116 int sr_code, sr_free, i;
118 for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
119 if (wm5100_sr_code[i] == rate)
120 break;
121 if (i == ARRAY_SIZE(wm5100_sr_code)) {
122 dev_err(codec->dev, "Unsupported sample rate: %dHz\n", rate);
123 return -EINVAL;
125 sr_code = i;
127 if ((wm5100->sysclk % rate) == 0) {
128 /* Is this rate already in use? */
129 sr_free = -1;
130 for (i = 0; i < ARRAY_SIZE(wm5100_sr_regs); i++) {
131 if (!wm5100->sr_ref[i] && sr_free == -1) {
132 sr_free = i;
133 continue;
135 if ((snd_soc_read(codec, wm5100_sr_regs[i]) &
136 WM5100_SAMPLE_RATE_1_MASK) == sr_code)
137 break;
140 if (i < ARRAY_SIZE(wm5100_sr_regs)) {
141 wm5100->sr_ref[i]++;
142 dev_dbg(codec->dev, "SR %dHz, slot %d, ref %d\n",
143 rate, i, wm5100->sr_ref[i]);
144 return i;
147 if (sr_free == -1) {
148 dev_err(codec->dev, "All SR slots already in use\n");
149 return -EBUSY;
152 dev_dbg(codec->dev, "Allocating SR slot %d for %dHz\n",
153 sr_free, rate);
154 wm5100->sr_ref[sr_free]++;
155 snd_soc_update_bits(codec, wm5100_sr_regs[sr_free],
156 WM5100_SAMPLE_RATE_1_MASK,
157 sr_code);
159 return sr_free;
161 } else {
162 dev_err(codec->dev,
163 "SR %dHz incompatible with %dHz SYSCLK and %dHz ASYNCCLK\n",
164 rate, wm5100->sysclk, wm5100->asyncclk);
165 return -EINVAL;
169 static void wm5100_free_sr(struct snd_soc_codec *codec, int rate)
171 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
172 int i, sr_code;
174 for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
175 if (wm5100_sr_code[i] == rate)
176 break;
177 if (i == ARRAY_SIZE(wm5100_sr_code)) {
178 dev_err(codec->dev, "Unsupported sample rate: %dHz\n", rate);
179 return;
181 sr_code = wm5100_sr_code[i];
183 for (i = 0; i < ARRAY_SIZE(wm5100_sr_regs); i++) {
184 if (!wm5100->sr_ref[i])
185 continue;
187 if ((snd_soc_read(codec, wm5100_sr_regs[i]) &
188 WM5100_SAMPLE_RATE_1_MASK) == sr_code)
189 break;
191 if (i < ARRAY_SIZE(wm5100_sr_regs)) {
192 wm5100->sr_ref[i]--;
193 dev_dbg(codec->dev, "Dereference SR %dHz, count now %d\n",
194 rate, wm5100->sr_ref[i]);
195 } else {
196 dev_warn(codec->dev, "Freeing unreferenced sample rate %dHz\n",
197 rate);
201 static int wm5100_reset(struct snd_soc_codec *codec)
203 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
205 if (wm5100->pdata.reset) {
206 gpio_set_value_cansleep(wm5100->pdata.reset, 0);
207 gpio_set_value_cansleep(wm5100->pdata.reset, 1);
209 return 0;
210 } else {
211 return snd_soc_write(codec, WM5100_SOFTWARE_RESET, 0);
215 static DECLARE_TLV_DB_SCALE(in_tlv, -6300, 100, 0);
216 static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
217 static DECLARE_TLV_DB_SCALE(mixer_tlv, -3200, 100, 0);
218 static DECLARE_TLV_DB_SCALE(out_tlv, -6400, 100, 0);
219 static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
221 static const char *wm5100_mixer_texts[] = {
222 "None",
223 "Tone Generator 1",
224 "Tone Generator 2",
225 "AEC loopback",
226 "IN1L",
227 "IN1R",
228 "IN2L",
229 "IN2R",
230 "IN3L",
231 "IN3R",
232 "IN4L",
233 "IN4R",
234 "AIF1RX1",
235 "AIF1RX2",
236 "AIF1RX3",
237 "AIF1RX4",
238 "AIF1RX5",
239 "AIF1RX6",
240 "AIF1RX7",
241 "AIF1RX8",
242 "AIF2RX1",
243 "AIF2RX2",
244 "AIF3RX1",
245 "AIF3RX2",
246 "EQ1",
247 "EQ2",
248 "EQ3",
249 "EQ4",
250 "DRC1L",
251 "DRC1R",
252 "LHPF1",
253 "LHPF2",
254 "LHPF3",
255 "LHPF4",
256 "DSP1.1",
257 "DSP1.2",
258 "DSP1.3",
259 "DSP1.4",
260 "DSP1.5",
261 "DSP1.6",
262 "DSP2.1",
263 "DSP2.2",
264 "DSP2.3",
265 "DSP2.4",
266 "DSP2.5",
267 "DSP2.6",
268 "DSP3.1",
269 "DSP3.2",
270 "DSP3.3",
271 "DSP3.4",
272 "DSP3.5",
273 "DSP3.6",
274 "ASRC1L",
275 "ASRC1R",
276 "ASRC2L",
277 "ASRC2R",
278 "ISRC1INT1",
279 "ISRC1INT2",
280 "ISRC1INT3",
281 "ISRC1INT4",
282 "ISRC2INT1",
283 "ISRC2INT2",
284 "ISRC2INT3",
285 "ISRC2INT4",
286 "ISRC1DEC1",
287 "ISRC1DEC2",
288 "ISRC1DEC3",
289 "ISRC1DEC4",
290 "ISRC2DEC1",
291 "ISRC2DEC2",
292 "ISRC2DEC3",
293 "ISRC2DEC4",
296 static int wm5100_mixer_values[] = {
297 0x00,
298 0x04, /* Tone */
299 0x05,
300 0x08, /* AEC */
301 0x10, /* Input */
302 0x11,
303 0x12,
304 0x13,
305 0x14,
306 0x15,
307 0x16,
308 0x17,
309 0x20, /* AIF */
310 0x21,
311 0x22,
312 0x23,
313 0x24,
314 0x25,
315 0x26,
316 0x27,
317 0x28,
318 0x29,
319 0x30, /* AIF3 - check */
320 0x31,
321 0x50, /* EQ */
322 0x51,
323 0x52,
324 0x53,
325 0x54,
326 0x58, /* DRC */
327 0x59,
328 0x60, /* LHPF1 */
329 0x61, /* LHPF2 */
330 0x62, /* LHPF3 */
331 0x63, /* LHPF4 */
332 0x68, /* DSP1 */
333 0x69,
334 0x6a,
335 0x6b,
336 0x6c,
337 0x6d,
338 0x70, /* DSP2 */
339 0x71,
340 0x72,
341 0x73,
342 0x74,
343 0x75,
344 0x78, /* DSP3 */
345 0x79,
346 0x7a,
347 0x7b,
348 0x7c,
349 0x7d,
350 0x90, /* ASRC1 */
351 0x91,
352 0x92, /* ASRC2 */
353 0x93,
354 0xa0, /* ISRC1DEC1 */
355 0xa1,
356 0xa2,
357 0xa3,
358 0xa4, /* ISRC1INT1 */
359 0xa5,
360 0xa6,
361 0xa7,
362 0xa8, /* ISRC2DEC1 */
363 0xa9,
364 0xaa,
365 0xab,
366 0xac, /* ISRC2INT1 */
367 0xad,
368 0xae,
369 0xaf,
372 #define WM5100_MIXER_CONTROLS(name, base) \
373 SOC_SINGLE_TLV(name " Input 1 Volume", base + 1 , \
374 WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
375 SOC_SINGLE_TLV(name " Input 2 Volume", base + 3 , \
376 WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
377 SOC_SINGLE_TLV(name " Input 3 Volume", base + 5 , \
378 WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \
379 SOC_SINGLE_TLV(name " Input 4 Volume", base + 7 , \
380 WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv)
382 #define WM5100_MUX_ENUM_DECL(name, reg) \
383 SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, \
384 wm5100_mixer_texts, wm5100_mixer_values)
386 #define WM5100_MUX_CTL_DECL(name) \
387 const struct snd_kcontrol_new name##_mux = \
388 SOC_DAPM_VALUE_ENUM("Route", name##_enum)
390 #define WM5100_MIXER_ENUMS(name, base_reg) \
391 static WM5100_MUX_ENUM_DECL(name##_in1_enum, base_reg); \
392 static WM5100_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \
393 static WM5100_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \
394 static WM5100_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \
395 static WM5100_MUX_CTL_DECL(name##_in1); \
396 static WM5100_MUX_CTL_DECL(name##_in2); \
397 static WM5100_MUX_CTL_DECL(name##_in3); \
398 static WM5100_MUX_CTL_DECL(name##_in4)
400 WM5100_MIXER_ENUMS(HPOUT1L, WM5100_OUT1LMIX_INPUT_1_SOURCE);
401 WM5100_MIXER_ENUMS(HPOUT1R, WM5100_OUT1RMIX_INPUT_1_SOURCE);
402 WM5100_MIXER_ENUMS(HPOUT2L, WM5100_OUT2LMIX_INPUT_1_SOURCE);
403 WM5100_MIXER_ENUMS(HPOUT2R, WM5100_OUT2RMIX_INPUT_1_SOURCE);
404 WM5100_MIXER_ENUMS(HPOUT3L, WM5100_OUT3LMIX_INPUT_1_SOURCE);
405 WM5100_MIXER_ENUMS(HPOUT3R, WM5100_OUT3RMIX_INPUT_1_SOURCE);
407 WM5100_MIXER_ENUMS(SPKOUTL, WM5100_OUT4LMIX_INPUT_1_SOURCE);
408 WM5100_MIXER_ENUMS(SPKOUTR, WM5100_OUT4RMIX_INPUT_1_SOURCE);
409 WM5100_MIXER_ENUMS(SPKDAT1L, WM5100_OUT5LMIX_INPUT_1_SOURCE);
410 WM5100_MIXER_ENUMS(SPKDAT1R, WM5100_OUT5RMIX_INPUT_1_SOURCE);
411 WM5100_MIXER_ENUMS(SPKDAT2L, WM5100_OUT6LMIX_INPUT_1_SOURCE);
412 WM5100_MIXER_ENUMS(SPKDAT2R, WM5100_OUT6RMIX_INPUT_1_SOURCE);
414 WM5100_MIXER_ENUMS(PWM1, WM5100_PWM1MIX_INPUT_1_SOURCE);
415 WM5100_MIXER_ENUMS(PWM2, WM5100_PWM1MIX_INPUT_1_SOURCE);
417 WM5100_MIXER_ENUMS(AIF1TX1, WM5100_AIF1TX1MIX_INPUT_1_SOURCE);
418 WM5100_MIXER_ENUMS(AIF1TX2, WM5100_AIF1TX2MIX_INPUT_1_SOURCE);
419 WM5100_MIXER_ENUMS(AIF1TX3, WM5100_AIF1TX3MIX_INPUT_1_SOURCE);
420 WM5100_MIXER_ENUMS(AIF1TX4, WM5100_AIF1TX4MIX_INPUT_1_SOURCE);
421 WM5100_MIXER_ENUMS(AIF1TX5, WM5100_AIF1TX5MIX_INPUT_1_SOURCE);
422 WM5100_MIXER_ENUMS(AIF1TX6, WM5100_AIF1TX6MIX_INPUT_1_SOURCE);
423 WM5100_MIXER_ENUMS(AIF1TX7, WM5100_AIF1TX7MIX_INPUT_1_SOURCE);
424 WM5100_MIXER_ENUMS(AIF1TX8, WM5100_AIF1TX8MIX_INPUT_1_SOURCE);
426 WM5100_MIXER_ENUMS(AIF2TX1, WM5100_AIF2TX1MIX_INPUT_1_SOURCE);
427 WM5100_MIXER_ENUMS(AIF2TX2, WM5100_AIF2TX2MIX_INPUT_1_SOURCE);
429 WM5100_MIXER_ENUMS(AIF3TX1, WM5100_AIF1TX1MIX_INPUT_1_SOURCE);
430 WM5100_MIXER_ENUMS(AIF3TX2, WM5100_AIF1TX2MIX_INPUT_1_SOURCE);
432 WM5100_MIXER_ENUMS(EQ1, WM5100_EQ1MIX_INPUT_1_SOURCE);
433 WM5100_MIXER_ENUMS(EQ2, WM5100_EQ2MIX_INPUT_1_SOURCE);
434 WM5100_MIXER_ENUMS(EQ3, WM5100_EQ3MIX_INPUT_1_SOURCE);
435 WM5100_MIXER_ENUMS(EQ4, WM5100_EQ4MIX_INPUT_1_SOURCE);
437 WM5100_MIXER_ENUMS(DRC1L, WM5100_DRC1LMIX_INPUT_1_SOURCE);
438 WM5100_MIXER_ENUMS(DRC1R, WM5100_DRC1RMIX_INPUT_1_SOURCE);
440 WM5100_MIXER_ENUMS(LHPF1, WM5100_HPLP1MIX_INPUT_1_SOURCE);
441 WM5100_MIXER_ENUMS(LHPF2, WM5100_HPLP2MIX_INPUT_1_SOURCE);
442 WM5100_MIXER_ENUMS(LHPF3, WM5100_HPLP3MIX_INPUT_1_SOURCE);
443 WM5100_MIXER_ENUMS(LHPF4, WM5100_HPLP4MIX_INPUT_1_SOURCE);
445 #define WM5100_MUX(name, ctrl) \
446 SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
448 #define WM5100_MIXER_WIDGETS(name, name_str) \
449 WM5100_MUX(name_str " Input 1", &name##_in1_mux), \
450 WM5100_MUX(name_str " Input 2", &name##_in2_mux), \
451 WM5100_MUX(name_str " Input 3", &name##_in3_mux), \
452 WM5100_MUX(name_str " Input 4", &name##_in4_mux), \
453 SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
455 #define WM5100_MIXER_INPUT_ROUTES(name) \
456 { name, "Tone Generator 1", "Tone Generator 1" }, \
457 { name, "Tone Generator 2", "Tone Generator 2" }, \
458 { name, "IN1L", "IN1L PGA" }, \
459 { name, "IN1R", "IN1R PGA" }, \
460 { name, "IN2L", "IN2L PGA" }, \
461 { name, "IN2R", "IN2R PGA" }, \
462 { name, "IN3L", "IN3L PGA" }, \
463 { name, "IN3R", "IN3R PGA" }, \
464 { name, "IN4L", "IN4L PGA" }, \
465 { name, "IN4R", "IN4R PGA" }, \
466 { name, "AIF1RX1", "AIF1RX1" }, \
467 { name, "AIF1RX2", "AIF1RX2" }, \
468 { name, "AIF1RX3", "AIF1RX3" }, \
469 { name, "AIF1RX4", "AIF1RX4" }, \
470 { name, "AIF1RX5", "AIF1RX5" }, \
471 { name, "AIF1RX6", "AIF1RX6" }, \
472 { name, "AIF1RX7", "AIF1RX7" }, \
473 { name, "AIF1RX8", "AIF1RX8" }, \
474 { name, "AIF2RX1", "AIF2RX1" }, \
475 { name, "AIF2RX2", "AIF2RX2" }, \
476 { name, "AIF3RX1", "AIF3RX1" }, \
477 { name, "AIF3RX2", "AIF3RX2" }, \
478 { name, "EQ1", "EQ1" }, \
479 { name, "EQ2", "EQ2" }, \
480 { name, "EQ3", "EQ3" }, \
481 { name, "EQ4", "EQ4" }, \
482 { name, "DRC1L", "DRC1L" }, \
483 { name, "DRC1R", "DRC1R" }, \
484 { name, "LHPF1", "LHPF1" }, \
485 { name, "LHPF2", "LHPF2" }, \
486 { name, "LHPF3", "LHPF3" }, \
487 { name, "LHPF4", "LHPF4" }
489 #define WM5100_MIXER_ROUTES(widget, name) \
490 { widget, NULL, name " Mixer" }, \
491 { name " Mixer", NULL, name " Input 1" }, \
492 { name " Mixer", NULL, name " Input 2" }, \
493 { name " Mixer", NULL, name " Input 3" }, \
494 { name " Mixer", NULL, name " Input 4" }, \
495 WM5100_MIXER_INPUT_ROUTES(name " Input 1"), \
496 WM5100_MIXER_INPUT_ROUTES(name " Input 2"), \
497 WM5100_MIXER_INPUT_ROUTES(name " Input 3"), \
498 WM5100_MIXER_INPUT_ROUTES(name " Input 4")
500 static const char *wm5100_lhpf_mode_text[] = {
501 "Low-pass", "High-pass"
504 static const struct soc_enum wm5100_lhpf1_mode =
505 SOC_ENUM_SINGLE(WM5100_HPLPF1_1, WM5100_LHPF1_MODE_SHIFT, 2,
506 wm5100_lhpf_mode_text);
508 static const struct soc_enum wm5100_lhpf2_mode =
509 SOC_ENUM_SINGLE(WM5100_HPLPF2_1, WM5100_LHPF2_MODE_SHIFT, 2,
510 wm5100_lhpf_mode_text);
512 static const struct soc_enum wm5100_lhpf3_mode =
513 SOC_ENUM_SINGLE(WM5100_HPLPF3_1, WM5100_LHPF3_MODE_SHIFT, 2,
514 wm5100_lhpf_mode_text);
516 static const struct soc_enum wm5100_lhpf4_mode =
517 SOC_ENUM_SINGLE(WM5100_HPLPF4_1, WM5100_LHPF4_MODE_SHIFT, 2,
518 wm5100_lhpf_mode_text);
520 static const struct snd_kcontrol_new wm5100_snd_controls[] = {
521 SOC_SINGLE("IN1 High Performance Switch", WM5100_IN1L_CONTROL,
522 WM5100_IN1_OSR_SHIFT, 1, 0),
523 SOC_SINGLE("IN2 High Performance Switch", WM5100_IN2L_CONTROL,
524 WM5100_IN2_OSR_SHIFT, 1, 0),
525 SOC_SINGLE("IN3 High Performance Switch", WM5100_IN3L_CONTROL,
526 WM5100_IN3_OSR_SHIFT, 1, 0),
527 SOC_SINGLE("IN4 High Performance Switch", WM5100_IN4L_CONTROL,
528 WM5100_IN4_OSR_SHIFT, 1, 0),
530 /* Only applicable for analogue inputs */
531 SOC_DOUBLE_R_TLV("IN1 Volume", WM5100_IN1L_CONTROL, WM5100_IN1R_CONTROL,
532 WM5100_IN1L_PGA_VOL_SHIFT, 94, 0, in_tlv),
533 SOC_DOUBLE_R_TLV("IN2 Volume", WM5100_IN2L_CONTROL, WM5100_IN2R_CONTROL,
534 WM5100_IN2L_PGA_VOL_SHIFT, 94, 0, in_tlv),
535 SOC_DOUBLE_R_TLV("IN3 Volume", WM5100_IN3L_CONTROL, WM5100_IN3R_CONTROL,
536 WM5100_IN3L_PGA_VOL_SHIFT, 94, 0, in_tlv),
537 SOC_DOUBLE_R_TLV("IN4 Volume", WM5100_IN4L_CONTROL, WM5100_IN4R_CONTROL,
538 WM5100_IN4L_PGA_VOL_SHIFT, 94, 0, in_tlv),
540 SOC_DOUBLE_R_TLV("IN1 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_1L,
541 WM5100_ADC_DIGITAL_VOLUME_1R, WM5100_IN1L_VOL_SHIFT, 191,
542 0, digital_tlv),
543 SOC_DOUBLE_R_TLV("IN2 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_2L,
544 WM5100_ADC_DIGITAL_VOLUME_2R, WM5100_IN2L_VOL_SHIFT, 191,
545 0, digital_tlv),
546 SOC_DOUBLE_R_TLV("IN3 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_3L,
547 WM5100_ADC_DIGITAL_VOLUME_3R, WM5100_IN3L_VOL_SHIFT, 191,
548 0, digital_tlv),
549 SOC_DOUBLE_R_TLV("IN4 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_4L,
550 WM5100_ADC_DIGITAL_VOLUME_4R, WM5100_IN4L_VOL_SHIFT, 191,
551 0, digital_tlv),
553 SOC_DOUBLE_R("IN1 Switch", WM5100_ADC_DIGITAL_VOLUME_1L,
554 WM5100_ADC_DIGITAL_VOLUME_1R, WM5100_IN1L_MUTE_SHIFT, 1, 1),
555 SOC_DOUBLE_R("IN2 Switch", WM5100_ADC_DIGITAL_VOLUME_2L,
556 WM5100_ADC_DIGITAL_VOLUME_2R, WM5100_IN2L_MUTE_SHIFT, 1, 1),
557 SOC_DOUBLE_R("IN3 Switch", WM5100_ADC_DIGITAL_VOLUME_3L,
558 WM5100_ADC_DIGITAL_VOLUME_3R, WM5100_IN3L_MUTE_SHIFT, 1, 1),
559 SOC_DOUBLE_R("IN4 Switch", WM5100_ADC_DIGITAL_VOLUME_4L,
560 WM5100_ADC_DIGITAL_VOLUME_4R, WM5100_IN4L_MUTE_SHIFT, 1, 1),
562 SOC_SINGLE("HPOUT1 High Performance Switch", WM5100_OUT_VOLUME_1L,
563 WM5100_OUT1_OSR_SHIFT, 1, 0),
564 SOC_SINGLE("HPOUT2 High Performance Switch", WM5100_OUT_VOLUME_2L,
565 WM5100_OUT2_OSR_SHIFT, 1, 0),
566 SOC_SINGLE("HPOUT3 High Performance Switch", WM5100_OUT_VOLUME_3L,
567 WM5100_OUT3_OSR_SHIFT, 1, 0),
568 SOC_SINGLE("SPKOUT High Performance Switch", WM5100_OUT_VOLUME_4L,
569 WM5100_OUT4_OSR_SHIFT, 1, 0),
570 SOC_SINGLE("SPKDAT1 High Performance Switch", WM5100_DAC_VOLUME_LIMIT_5L,
571 WM5100_OUT5_OSR_SHIFT, 1, 0),
572 SOC_SINGLE("SPKDAT2 High Performance Switch", WM5100_DAC_VOLUME_LIMIT_6L,
573 WM5100_OUT6_OSR_SHIFT, 1, 0),
575 SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_1L,
576 WM5100_DAC_DIGITAL_VOLUME_1R, WM5100_OUT1L_VOL_SHIFT, 159, 0,
577 digital_tlv),
578 SOC_DOUBLE_R_TLV("HPOUT2 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_2L,
579 WM5100_DAC_DIGITAL_VOLUME_2R, WM5100_OUT2L_VOL_SHIFT, 159, 0,
580 digital_tlv),
581 SOC_DOUBLE_R_TLV("HPOUT3 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_3L,
582 WM5100_DAC_DIGITAL_VOLUME_3R, WM5100_OUT3L_VOL_SHIFT, 159, 0,
583 digital_tlv),
584 SOC_DOUBLE_R_TLV("SPKOUT Digital Volume", WM5100_DAC_DIGITAL_VOLUME_4L,
585 WM5100_DAC_DIGITAL_VOLUME_4R, WM5100_OUT4L_VOL_SHIFT, 159, 0,
586 digital_tlv),
587 SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_5L,
588 WM5100_DAC_DIGITAL_VOLUME_5R, WM5100_OUT5L_VOL_SHIFT, 159, 0,
589 digital_tlv),
590 SOC_DOUBLE_R_TLV("SPKDAT2 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_6L,
591 WM5100_DAC_DIGITAL_VOLUME_6R, WM5100_OUT6L_VOL_SHIFT, 159, 0,
592 digital_tlv),
594 SOC_DOUBLE_R("HPOUT1 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_1L,
595 WM5100_DAC_DIGITAL_VOLUME_1R, WM5100_OUT1L_MUTE_SHIFT, 1, 1),
596 SOC_DOUBLE_R("HPOUT2 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_2L,
597 WM5100_DAC_DIGITAL_VOLUME_2R, WM5100_OUT2L_MUTE_SHIFT, 1, 1),
598 SOC_DOUBLE_R("HPOUT3 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_3L,
599 WM5100_DAC_DIGITAL_VOLUME_3R, WM5100_OUT3L_MUTE_SHIFT, 1, 1),
600 SOC_DOUBLE_R("SPKOUT Digital Switch", WM5100_DAC_DIGITAL_VOLUME_4L,
601 WM5100_DAC_DIGITAL_VOLUME_4R, WM5100_OUT4L_MUTE_SHIFT, 1, 1),
602 SOC_DOUBLE_R("SPKDAT1 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_5L,
603 WM5100_DAC_DIGITAL_VOLUME_5R, WM5100_OUT5L_MUTE_SHIFT, 1, 1),
604 SOC_DOUBLE_R("SPKDAT2 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_6L,
605 WM5100_DAC_DIGITAL_VOLUME_6R, WM5100_OUT6L_MUTE_SHIFT, 1, 1),
607 /* FIXME: Only valid from -12dB to 0dB (52-64) */
608 SOC_DOUBLE_R_TLV("HPOUT1 Volume", WM5100_OUT_VOLUME_1L, WM5100_OUT_VOLUME_1R,
609 WM5100_OUT1L_PGA_VOL_SHIFT, 64, 0, out_tlv),
610 SOC_DOUBLE_R_TLV("HPOUT2 Volume", WM5100_OUT_VOLUME_2L, WM5100_OUT_VOLUME_2R,
611 WM5100_OUT2L_PGA_VOL_SHIFT, 64, 0, out_tlv),
612 SOC_DOUBLE_R_TLV("HPOUT3 Volume", WM5100_OUT_VOLUME_3L, WM5100_OUT_VOLUME_3R,
613 WM5100_OUT2L_PGA_VOL_SHIFT, 64, 0, out_tlv),
615 SOC_DOUBLE("SPKDAT1 Switch", WM5100_PDM_SPK1_CTRL_1, WM5100_SPK1L_MUTE_SHIFT,
616 WM5100_SPK1R_MUTE_SHIFT, 1, 1),
617 SOC_DOUBLE("SPKDAT2 Switch", WM5100_PDM_SPK2_CTRL_1, WM5100_SPK2L_MUTE_SHIFT,
618 WM5100_SPK2R_MUTE_SHIFT, 1, 1),
620 SOC_SINGLE_TLV("EQ1 Band 1 Volume", WM5100_EQ1_1, WM5100_EQ1_B1_GAIN_SHIFT,
621 24, 0, eq_tlv),
622 SOC_SINGLE_TLV("EQ1 Band 2 Volume", WM5100_EQ1_1, WM5100_EQ1_B2_GAIN_SHIFT,
623 24, 0, eq_tlv),
624 SOC_SINGLE_TLV("EQ1 Band 3 Volume", WM5100_EQ1_1, WM5100_EQ1_B3_GAIN_SHIFT,
625 24, 0, eq_tlv),
626 SOC_SINGLE_TLV("EQ1 Band 4 Volume", WM5100_EQ1_2, WM5100_EQ1_B4_GAIN_SHIFT,
627 24, 0, eq_tlv),
628 SOC_SINGLE_TLV("EQ1 Band 5 Volume", WM5100_EQ1_2, WM5100_EQ1_B5_GAIN_SHIFT,
629 24, 0, eq_tlv),
631 SOC_SINGLE_TLV("EQ2 Band 1 Volume", WM5100_EQ2_1, WM5100_EQ2_B1_GAIN_SHIFT,
632 24, 0, eq_tlv),
633 SOC_SINGLE_TLV("EQ2 Band 2 Volume", WM5100_EQ2_1, WM5100_EQ2_B2_GAIN_SHIFT,
634 24, 0, eq_tlv),
635 SOC_SINGLE_TLV("EQ2 Band 3 Volume", WM5100_EQ2_1, WM5100_EQ2_B3_GAIN_SHIFT,
636 24, 0, eq_tlv),
637 SOC_SINGLE_TLV("EQ2 Band 4 Volume", WM5100_EQ2_2, WM5100_EQ2_B4_GAIN_SHIFT,
638 24, 0, eq_tlv),
639 SOC_SINGLE_TLV("EQ2 Band 5 Volume", WM5100_EQ2_2, WM5100_EQ2_B5_GAIN_SHIFT,
640 24, 0, eq_tlv),
642 SOC_SINGLE_TLV("EQ3 Band 1 Volume", WM5100_EQ1_1, WM5100_EQ3_B1_GAIN_SHIFT,
643 24, 0, eq_tlv),
644 SOC_SINGLE_TLV("EQ3 Band 2 Volume", WM5100_EQ3_1, WM5100_EQ3_B2_GAIN_SHIFT,
645 24, 0, eq_tlv),
646 SOC_SINGLE_TLV("EQ3 Band 3 Volume", WM5100_EQ3_1, WM5100_EQ3_B3_GAIN_SHIFT,
647 24, 0, eq_tlv),
648 SOC_SINGLE_TLV("EQ3 Band 4 Volume", WM5100_EQ3_2, WM5100_EQ3_B4_GAIN_SHIFT,
649 24, 0, eq_tlv),
650 SOC_SINGLE_TLV("EQ3 Band 5 Volume", WM5100_EQ3_2, WM5100_EQ3_B5_GAIN_SHIFT,
651 24, 0, eq_tlv),
653 SOC_SINGLE_TLV("EQ4 Band 1 Volume", WM5100_EQ4_1, WM5100_EQ4_B1_GAIN_SHIFT,
654 24, 0, eq_tlv),
655 SOC_SINGLE_TLV("EQ4 Band 2 Volume", WM5100_EQ4_1, WM5100_EQ4_B2_GAIN_SHIFT,
656 24, 0, eq_tlv),
657 SOC_SINGLE_TLV("EQ4 Band 3 Volume", WM5100_EQ4_1, WM5100_EQ4_B3_GAIN_SHIFT,
658 24, 0, eq_tlv),
659 SOC_SINGLE_TLV("EQ4 Band 4 Volume", WM5100_EQ4_2, WM5100_EQ4_B4_GAIN_SHIFT,
660 24, 0, eq_tlv),
661 SOC_SINGLE_TLV("EQ4 Band 5 Volume", WM5100_EQ4_2, WM5100_EQ4_B5_GAIN_SHIFT,
662 24, 0, eq_tlv),
664 SOC_ENUM("LHPF1 Mode", wm5100_lhpf1_mode),
665 SOC_ENUM("LHPF2 Mode", wm5100_lhpf2_mode),
666 SOC_ENUM("LHPF3 Mode", wm5100_lhpf3_mode),
667 SOC_ENUM("LHPF4 Mode", wm5100_lhpf4_mode),
669 WM5100_MIXER_CONTROLS("HPOUT1L", WM5100_OUT1LMIX_INPUT_1_SOURCE),
670 WM5100_MIXER_CONTROLS("HPOUT1R", WM5100_OUT1RMIX_INPUT_1_SOURCE),
671 WM5100_MIXER_CONTROLS("HPOUT2L", WM5100_OUT2LMIX_INPUT_1_SOURCE),
672 WM5100_MIXER_CONTROLS("HPOUT2R", WM5100_OUT2RMIX_INPUT_1_SOURCE),
673 WM5100_MIXER_CONTROLS("HPOUT3L", WM5100_OUT3LMIX_INPUT_1_SOURCE),
674 WM5100_MIXER_CONTROLS("HPOUT3R", WM5100_OUT3RMIX_INPUT_1_SOURCE),
676 WM5100_MIXER_CONTROLS("SPKOUTL", WM5100_OUT4LMIX_INPUT_1_SOURCE),
677 WM5100_MIXER_CONTROLS("SPKOUTR", WM5100_OUT4RMIX_INPUT_1_SOURCE),
678 WM5100_MIXER_CONTROLS("SPKDAT1L", WM5100_OUT5LMIX_INPUT_1_SOURCE),
679 WM5100_MIXER_CONTROLS("SPKDAT1R", WM5100_OUT5RMIX_INPUT_1_SOURCE),
680 WM5100_MIXER_CONTROLS("SPKDAT2L", WM5100_OUT6LMIX_INPUT_1_SOURCE),
681 WM5100_MIXER_CONTROLS("SPKDAT2R", WM5100_OUT6RMIX_INPUT_1_SOURCE),
683 WM5100_MIXER_CONTROLS("PWM1", WM5100_PWM1MIX_INPUT_1_SOURCE),
684 WM5100_MIXER_CONTROLS("PWM2", WM5100_PWM2MIX_INPUT_1_SOURCE),
686 WM5100_MIXER_CONTROLS("AIF1TX1", WM5100_AIF1TX1MIX_INPUT_1_SOURCE),
687 WM5100_MIXER_CONTROLS("AIF1TX2", WM5100_AIF1TX2MIX_INPUT_1_SOURCE),
688 WM5100_MIXER_CONTROLS("AIF1TX3", WM5100_AIF1TX3MIX_INPUT_1_SOURCE),
689 WM5100_MIXER_CONTROLS("AIF1TX4", WM5100_AIF1TX4MIX_INPUT_1_SOURCE),
690 WM5100_MIXER_CONTROLS("AIF1TX5", WM5100_AIF1TX5MIX_INPUT_1_SOURCE),
691 WM5100_MIXER_CONTROLS("AIF1TX6", WM5100_AIF1TX6MIX_INPUT_1_SOURCE),
692 WM5100_MIXER_CONTROLS("AIF1TX7", WM5100_AIF1TX7MIX_INPUT_1_SOURCE),
693 WM5100_MIXER_CONTROLS("AIF1TX8", WM5100_AIF1TX8MIX_INPUT_1_SOURCE),
695 WM5100_MIXER_CONTROLS("AIF2TX1", WM5100_AIF2TX1MIX_INPUT_1_SOURCE),
696 WM5100_MIXER_CONTROLS("AIF2TX2", WM5100_AIF2TX2MIX_INPUT_1_SOURCE),
698 WM5100_MIXER_CONTROLS("AIF3TX1", WM5100_AIF3TX1MIX_INPUT_1_SOURCE),
699 WM5100_MIXER_CONTROLS("AIF3TX2", WM5100_AIF3TX2MIX_INPUT_1_SOURCE),
701 WM5100_MIXER_CONTROLS("EQ1", WM5100_EQ1MIX_INPUT_1_SOURCE),
702 WM5100_MIXER_CONTROLS("EQ2", WM5100_EQ2MIX_INPUT_1_SOURCE),
703 WM5100_MIXER_CONTROLS("EQ3", WM5100_EQ3MIX_INPUT_1_SOURCE),
704 WM5100_MIXER_CONTROLS("EQ4", WM5100_EQ4MIX_INPUT_1_SOURCE),
706 WM5100_MIXER_CONTROLS("DRC1L", WM5100_DRC1LMIX_INPUT_1_SOURCE),
707 WM5100_MIXER_CONTROLS("DRC1R", WM5100_DRC1RMIX_INPUT_1_SOURCE),
709 WM5100_MIXER_CONTROLS("LHPF1", WM5100_HPLP1MIX_INPUT_1_SOURCE),
710 WM5100_MIXER_CONTROLS("LHPF2", WM5100_HPLP2MIX_INPUT_1_SOURCE),
711 WM5100_MIXER_CONTROLS("LHPF3", WM5100_HPLP3MIX_INPUT_1_SOURCE),
712 WM5100_MIXER_CONTROLS("LHPF4", WM5100_HPLP4MIX_INPUT_1_SOURCE),
715 static void wm5100_seq_notifier(struct snd_soc_dapm_context *dapm,
716 enum snd_soc_dapm_type event, int subseq)
718 struct snd_soc_codec *codec = container_of(dapm,
719 struct snd_soc_codec, dapm);
720 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
721 u16 val, expect, i;
723 /* Wait for the outputs to flag themselves as enabled */
724 if (wm5100->out_ena[0]) {
725 expect = snd_soc_read(codec, WM5100_CHANNEL_ENABLES_1);
726 for (i = 0; i < 200; i++) {
727 val = snd_soc_read(codec, WM5100_OUTPUT_STATUS_1);
728 if (val == expect) {
729 wm5100->out_ena[0] = false;
730 break;
733 if (i == 200) {
734 dev_err(codec->dev, "Timeout waiting for OUTPUT1 %x\n",
735 expect);
739 if (wm5100->out_ena[1]) {
740 expect = snd_soc_read(codec, WM5100_OUTPUT_ENABLES_2);
741 for (i = 0; i < 200; i++) {
742 val = snd_soc_read(codec, WM5100_OUTPUT_STATUS_2);
743 if (val == expect) {
744 wm5100->out_ena[1] = false;
745 break;
748 if (i == 200) {
749 dev_err(codec->dev, "Timeout waiting for OUTPUT2 %x\n",
750 expect);
755 static int wm5100_out_ev(struct snd_soc_dapm_widget *w,
756 struct snd_kcontrol *kcontrol,
757 int event)
759 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(w->codec);
761 switch (w->reg) {
762 case WM5100_CHANNEL_ENABLES_1:
763 wm5100->out_ena[0] = true;
764 break;
765 case WM5100_OUTPUT_ENABLES_2:
766 wm5100->out_ena[0] = true;
767 break;
768 default:
769 break;
772 return 0;
775 static int wm5100_cp_ev(struct snd_soc_dapm_widget *w,
776 struct snd_kcontrol *kcontrol,
777 int event)
779 struct snd_soc_codec *codec = w->codec;
780 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
781 int ret;
783 switch (event) {
784 case SND_SOC_DAPM_PRE_PMU:
785 ret = regulator_enable(wm5100->cpvdd);
786 if (ret != 0) {
787 dev_err(codec->dev, "Failed to enable CPVDD: %d\n",
788 ret);
789 return ret;
791 return ret;
793 case SND_SOC_DAPM_POST_PMD:
794 ret = regulator_disable_deferred(wm5100->cpvdd, 20);
795 if (ret != 0) {
796 dev_err(codec->dev, "Failed to disable CPVDD: %d\n",
797 ret);
798 return ret;
800 return ret;
802 default:
803 BUG();
804 return 0;
808 static int wm5100_dbvdd_ev(struct snd_soc_dapm_widget *w,
809 struct snd_kcontrol *kcontrol,
810 int event)
812 struct snd_soc_codec *codec = w->codec;
813 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
814 struct regulator *regulator;
815 int ret;
817 switch (w->shift) {
818 case 2:
819 regulator = wm5100->dbvdd2;
820 break;
821 case 3:
822 regulator = wm5100->dbvdd3;
823 break;
824 default:
825 BUG();
826 return 0;
829 switch (event) {
830 case SND_SOC_DAPM_PRE_PMU:
831 ret = regulator_enable(regulator);
832 if (ret != 0) {
833 dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n",
834 w->shift, ret);
835 return ret;
837 return ret;
839 case SND_SOC_DAPM_POST_PMD:
840 ret = regulator_disable(regulator);
841 if (ret != 0) {
842 dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n",
843 w->shift, ret);
844 return ret;
846 return ret;
848 default:
849 BUG();
850 return 0;
854 static void wm5100_log_status3(struct snd_soc_codec *codec, int val)
856 if (val & WM5100_SPK_SHUTDOWN_WARN_EINT)
857 dev_crit(codec->dev, "Speaker shutdown warning\n");
858 if (val & WM5100_SPK_SHUTDOWN_EINT)
859 dev_crit(codec->dev, "Speaker shutdown\n");
860 if (val & WM5100_CLKGEN_ERR_EINT)
861 dev_crit(codec->dev, "SYSCLK underclocked\n");
862 if (val & WM5100_CLKGEN_ERR_ASYNC_EINT)
863 dev_crit(codec->dev, "ASYNCCLK underclocked\n");
866 static void wm5100_log_status4(struct snd_soc_codec *codec, int val)
868 if (val & WM5100_AIF3_ERR_EINT)
869 dev_err(codec->dev, "AIF3 configuration error\n");
870 if (val & WM5100_AIF2_ERR_EINT)
871 dev_err(codec->dev, "AIF2 configuration error\n");
872 if (val & WM5100_AIF1_ERR_EINT)
873 dev_err(codec->dev, "AIF1 configuration error\n");
874 if (val & WM5100_CTRLIF_ERR_EINT)
875 dev_err(codec->dev, "Control interface error\n");
876 if (val & WM5100_ISRC2_UNDERCLOCKED_EINT)
877 dev_err(codec->dev, "ISRC2 underclocked\n");
878 if (val & WM5100_ISRC1_UNDERCLOCKED_EINT)
879 dev_err(codec->dev, "ISRC1 underclocked\n");
880 if (val & WM5100_FX_UNDERCLOCKED_EINT)
881 dev_err(codec->dev, "FX underclocked\n");
882 if (val & WM5100_AIF3_UNDERCLOCKED_EINT)
883 dev_err(codec->dev, "AIF3 underclocked\n");
884 if (val & WM5100_AIF2_UNDERCLOCKED_EINT)
885 dev_err(codec->dev, "AIF2 underclocked\n");
886 if (val & WM5100_AIF1_UNDERCLOCKED_EINT)
887 dev_err(codec->dev, "AIF1 underclocked\n");
888 if (val & WM5100_ASRC_UNDERCLOCKED_EINT)
889 dev_err(codec->dev, "ASRC underclocked\n");
890 if (val & WM5100_DAC_UNDERCLOCKED_EINT)
891 dev_err(codec->dev, "DAC underclocked\n");
892 if (val & WM5100_ADC_UNDERCLOCKED_EINT)
893 dev_err(codec->dev, "ADC underclocked\n");
894 if (val & WM5100_MIXER_UNDERCLOCKED_EINT)
895 dev_err(codec->dev, "Mixer underclocked\n");
898 static int wm5100_post_ev(struct snd_soc_dapm_widget *w,
899 struct snd_kcontrol *kcontrol,
900 int event)
902 struct snd_soc_codec *codec = w->codec;
903 int ret;
905 ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_3);
906 ret &= WM5100_SPK_SHUTDOWN_WARN_STS |
907 WM5100_SPK_SHUTDOWN_STS | WM5100_CLKGEN_ERR_STS |
908 WM5100_CLKGEN_ERR_ASYNC_STS;
909 wm5100_log_status3(codec, ret);
911 ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_4);
912 wm5100_log_status4(codec, ret);
914 return 0;
917 static const struct snd_soc_dapm_widget wm5100_dapm_widgets[] = {
918 SND_SOC_DAPM_SUPPLY("SYSCLK", WM5100_CLOCKING_3, WM5100_SYSCLK_ENA_SHIFT, 0,
919 NULL, 0),
920 SND_SOC_DAPM_SUPPLY("ASYNCCLK", WM5100_CLOCKING_6, WM5100_ASYNC_CLK_ENA_SHIFT,
921 0, NULL, 0),
923 SND_SOC_DAPM_SUPPLY("CP1", WM5100_HP_CHARGE_PUMP_1, WM5100_CP1_ENA_SHIFT, 0,
924 wm5100_cp_ev,
925 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
926 SND_SOC_DAPM_SUPPLY("CP2", WM5100_MIC_CHARGE_PUMP_1, WM5100_CP2_ENA_SHIFT, 0,
927 NULL, 0),
928 SND_SOC_DAPM_SUPPLY("CP2 Active", WM5100_MIC_CHARGE_PUMP_1,
929 WM5100_CP2_BYPASS_SHIFT, 1, wm5100_cp_ev,
930 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
931 SND_SOC_DAPM_SUPPLY("DBVDD2", SND_SOC_NOPM, 2, 0, wm5100_dbvdd_ev,
932 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
933 SND_SOC_DAPM_SUPPLY("DBVDD3", SND_SOC_NOPM, 3, 0, wm5100_dbvdd_ev,
934 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
936 SND_SOC_DAPM_SUPPLY("MICBIAS1", WM5100_MIC_BIAS_CTRL_1, WM5100_MICB1_ENA_SHIFT,
937 0, NULL, 0),
938 SND_SOC_DAPM_SUPPLY("MICBIAS2", WM5100_MIC_BIAS_CTRL_2, WM5100_MICB2_ENA_SHIFT,
939 0, NULL, 0),
940 SND_SOC_DAPM_SUPPLY("MICBIAS3", WM5100_MIC_BIAS_CTRL_3, WM5100_MICB3_ENA_SHIFT,
941 0, NULL, 0),
943 SND_SOC_DAPM_INPUT("IN1L"),
944 SND_SOC_DAPM_INPUT("IN1R"),
945 SND_SOC_DAPM_INPUT("IN2L"),
946 SND_SOC_DAPM_INPUT("IN2R"),
947 SND_SOC_DAPM_INPUT("IN3L"),
948 SND_SOC_DAPM_INPUT("IN3R"),
949 SND_SOC_DAPM_INPUT("IN4L"),
950 SND_SOC_DAPM_INPUT("IN4R"),
951 SND_SOC_DAPM_INPUT("TONE"),
953 SND_SOC_DAPM_PGA_E("IN1L PGA", WM5100_INPUT_ENABLES, WM5100_IN1L_ENA_SHIFT, 0,
954 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
955 SND_SOC_DAPM_PGA_E("IN1R PGA", WM5100_INPUT_ENABLES, WM5100_IN1R_ENA_SHIFT, 0,
956 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
957 SND_SOC_DAPM_PGA_E("IN2L PGA", WM5100_INPUT_ENABLES, WM5100_IN2L_ENA_SHIFT, 0,
958 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
959 SND_SOC_DAPM_PGA_E("IN2R PGA", WM5100_INPUT_ENABLES, WM5100_IN2R_ENA_SHIFT, 0,
960 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
961 SND_SOC_DAPM_PGA_E("IN3L PGA", WM5100_INPUT_ENABLES, WM5100_IN3L_ENA_SHIFT, 0,
962 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
963 SND_SOC_DAPM_PGA_E("IN3R PGA", WM5100_INPUT_ENABLES, WM5100_IN3R_ENA_SHIFT, 0,
964 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
965 SND_SOC_DAPM_PGA_E("IN4L PGA", WM5100_INPUT_ENABLES, WM5100_IN4L_ENA_SHIFT, 0,
966 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
967 SND_SOC_DAPM_PGA_E("IN4R PGA", WM5100_INPUT_ENABLES, WM5100_IN4R_ENA_SHIFT, 0,
968 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
970 SND_SOC_DAPM_PGA("Tone Generator 1", WM5100_TONE_GENERATOR_1,
971 WM5100_TONE1_ENA_SHIFT, 0, NULL, 0),
972 SND_SOC_DAPM_PGA("Tone Generator 2", WM5100_TONE_GENERATOR_1,
973 WM5100_TONE2_ENA_SHIFT, 0, NULL, 0),
975 SND_SOC_DAPM_AIF_IN("AIF1RX1", "AIF1 Playback", 0,
976 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX1_ENA_SHIFT, 0),
977 SND_SOC_DAPM_AIF_IN("AIF1RX2", "AIF1 Playback", 1,
978 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX2_ENA_SHIFT, 0),
979 SND_SOC_DAPM_AIF_IN("AIF1RX3", "AIF1 Playback", 2,
980 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX3_ENA_SHIFT, 0),
981 SND_SOC_DAPM_AIF_IN("AIF1RX4", "AIF1 Playback", 3,
982 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX4_ENA_SHIFT, 0),
983 SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 4,
984 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX5_ENA_SHIFT, 0),
985 SND_SOC_DAPM_AIF_IN("AIF1RX6", "AIF1 Playback", 5,
986 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX6_ENA_SHIFT, 0),
987 SND_SOC_DAPM_AIF_IN("AIF1RX7", "AIF1 Playback", 6,
988 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX7_ENA_SHIFT, 0),
989 SND_SOC_DAPM_AIF_IN("AIF1RX8", "AIF1 Playback", 7,
990 WM5100_AUDIO_IF_1_27, WM5100_AIF1RX8_ENA_SHIFT, 0),
992 SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 0,
993 WM5100_AUDIO_IF_2_27, WM5100_AIF2RX1_ENA_SHIFT, 0),
994 SND_SOC_DAPM_AIF_IN("AIF2RX2", "AIF2 Playback", 1,
995 WM5100_AUDIO_IF_2_27, WM5100_AIF2RX2_ENA_SHIFT, 0),
997 SND_SOC_DAPM_AIF_IN("AIF3RX1", "AIF3 Playback", 0,
998 WM5100_AUDIO_IF_3_27, WM5100_AIF3RX1_ENA_SHIFT, 0),
999 SND_SOC_DAPM_AIF_IN("AIF3RX2", "AIF3 Playback", 1,
1000 WM5100_AUDIO_IF_3_27, WM5100_AIF3RX2_ENA_SHIFT, 0),
1002 SND_SOC_DAPM_AIF_OUT("AIF1TX1", "AIF1 Capture", 0,
1003 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX1_ENA_SHIFT, 0),
1004 SND_SOC_DAPM_AIF_OUT("AIF1TX2", "AIF1 Capture", 1,
1005 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX2_ENA_SHIFT, 0),
1006 SND_SOC_DAPM_AIF_OUT("AIF1TX3", "AIF1 Capture", 2,
1007 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX3_ENA_SHIFT, 0),
1008 SND_SOC_DAPM_AIF_OUT("AIF1TX4", "AIF1 Capture", 3,
1009 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX4_ENA_SHIFT, 0),
1010 SND_SOC_DAPM_AIF_OUT("AIF1TX5", "AIF1 Capture", 4,
1011 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX5_ENA_SHIFT, 0),
1012 SND_SOC_DAPM_AIF_OUT("AIF1TX6", "AIF1 Capture", 5,
1013 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX6_ENA_SHIFT, 0),
1014 SND_SOC_DAPM_AIF_OUT("AIF1TX7", "AIF1 Capture", 6,
1015 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX7_ENA_SHIFT, 0),
1016 SND_SOC_DAPM_AIF_OUT("AIF1TX8", "AIF1 Capture", 7,
1017 WM5100_AUDIO_IF_1_26, WM5100_AIF1TX8_ENA_SHIFT, 0),
1019 SND_SOC_DAPM_AIF_OUT("AIF2TX1", "AIF2 Capture", 0,
1020 WM5100_AUDIO_IF_2_26, WM5100_AIF2TX1_ENA_SHIFT, 0),
1021 SND_SOC_DAPM_AIF_OUT("AIF2TX2", "AIF2 Capture", 1,
1022 WM5100_AUDIO_IF_2_26, WM5100_AIF2TX2_ENA_SHIFT, 0),
1024 SND_SOC_DAPM_AIF_OUT("AIF3TX1", "AIF3 Capture", 0,
1025 WM5100_AUDIO_IF_3_26, WM5100_AIF3TX1_ENA_SHIFT, 0),
1026 SND_SOC_DAPM_AIF_OUT("AIF3TX2", "AIF3 Capture", 1,
1027 WM5100_AUDIO_IF_3_26, WM5100_AIF3TX2_ENA_SHIFT, 0),
1029 SND_SOC_DAPM_PGA_E("OUT6L", WM5100_OUTPUT_ENABLES_2, WM5100_OUT6L_ENA_SHIFT, 0,
1030 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1031 SND_SOC_DAPM_PGA_E("OUT6R", WM5100_OUTPUT_ENABLES_2, WM5100_OUT6R_ENA_SHIFT, 0,
1032 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1033 SND_SOC_DAPM_PGA_E("OUT5L", WM5100_OUTPUT_ENABLES_2, WM5100_OUT5L_ENA_SHIFT, 0,
1034 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1035 SND_SOC_DAPM_PGA_E("OUT5R", WM5100_OUTPUT_ENABLES_2, WM5100_OUT5R_ENA_SHIFT, 0,
1036 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1037 SND_SOC_DAPM_PGA_E("OUT4L", WM5100_OUTPUT_ENABLES_2, WM5100_OUT4L_ENA_SHIFT, 0,
1038 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1039 SND_SOC_DAPM_PGA_E("OUT4R", WM5100_OUTPUT_ENABLES_2, WM5100_OUT4R_ENA_SHIFT, 0,
1040 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1041 SND_SOC_DAPM_PGA_E("OUT3L", WM5100_CHANNEL_ENABLES_1, WM5100_HP3L_ENA_SHIFT, 0,
1042 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1043 SND_SOC_DAPM_PGA_E("OUT3R", WM5100_CHANNEL_ENABLES_1, WM5100_HP3R_ENA_SHIFT, 0,
1044 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1045 SND_SOC_DAPM_PGA_E("OUT2L", WM5100_CHANNEL_ENABLES_1, WM5100_HP2L_ENA_SHIFT, 0,
1046 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1047 SND_SOC_DAPM_PGA_E("OUT2R", WM5100_CHANNEL_ENABLES_1, WM5100_HP2R_ENA_SHIFT, 0,
1048 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1049 SND_SOC_DAPM_PGA_E("OUT1L", WM5100_CHANNEL_ENABLES_1, WM5100_HP1L_ENA_SHIFT, 0,
1050 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1051 SND_SOC_DAPM_PGA_E("OUT1R", WM5100_CHANNEL_ENABLES_1, WM5100_HP1R_ENA_SHIFT, 0,
1052 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1053 SND_SOC_DAPM_PGA_E("PWM1 Driver", WM5100_PWM_DRIVE_1, WM5100_PWM1_ENA_SHIFT, 0,
1054 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1055 SND_SOC_DAPM_PGA_E("PWM2 Driver", WM5100_PWM_DRIVE_1, WM5100_PWM2_ENA_SHIFT, 0,
1056 NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU),
1058 SND_SOC_DAPM_PGA("EQ1", WM5100_EQ1_1, WM5100_EQ1_ENA_SHIFT, 0, NULL, 0),
1059 SND_SOC_DAPM_PGA("EQ2", WM5100_EQ2_1, WM5100_EQ2_ENA_SHIFT, 0, NULL, 0),
1060 SND_SOC_DAPM_PGA("EQ3", WM5100_EQ3_1, WM5100_EQ3_ENA_SHIFT, 0, NULL, 0),
1061 SND_SOC_DAPM_PGA("EQ4", WM5100_EQ4_1, WM5100_EQ4_ENA_SHIFT, 0, NULL, 0),
1063 SND_SOC_DAPM_PGA("DRC1L", WM5100_DRC1_CTRL1, WM5100_DRCL_ENA_SHIFT, 0,
1064 NULL, 0),
1065 SND_SOC_DAPM_PGA("DRC1R", WM5100_DRC1_CTRL1, WM5100_DRCR_ENA_SHIFT, 0,
1066 NULL, 0),
1068 SND_SOC_DAPM_PGA("LHPF1", WM5100_HPLPF1_1, WM5100_LHPF1_ENA_SHIFT, 0,
1069 NULL, 0),
1070 SND_SOC_DAPM_PGA("LHPF2", WM5100_HPLPF2_1, WM5100_LHPF2_ENA_SHIFT, 0,
1071 NULL, 0),
1072 SND_SOC_DAPM_PGA("LHPF3", WM5100_HPLPF3_1, WM5100_LHPF3_ENA_SHIFT, 0,
1073 NULL, 0),
1074 SND_SOC_DAPM_PGA("LHPF4", WM5100_HPLPF4_1, WM5100_LHPF4_ENA_SHIFT, 0,
1075 NULL, 0),
1077 WM5100_MIXER_WIDGETS(EQ1, "EQ1"),
1078 WM5100_MIXER_WIDGETS(EQ2, "EQ2"),
1079 WM5100_MIXER_WIDGETS(EQ3, "EQ3"),
1080 WM5100_MIXER_WIDGETS(EQ4, "EQ4"),
1082 WM5100_MIXER_WIDGETS(DRC1L, "DRC1L"),
1083 WM5100_MIXER_WIDGETS(DRC1R, "DRC1R"),
1085 WM5100_MIXER_WIDGETS(LHPF1, "LHPF1"),
1086 WM5100_MIXER_WIDGETS(LHPF2, "LHPF2"),
1087 WM5100_MIXER_WIDGETS(LHPF3, "LHPF3"),
1088 WM5100_MIXER_WIDGETS(LHPF4, "LHPF4"),
1090 WM5100_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
1091 WM5100_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
1092 WM5100_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
1093 WM5100_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
1094 WM5100_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
1095 WM5100_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
1096 WM5100_MIXER_WIDGETS(AIF1TX7, "AIF1TX7"),
1097 WM5100_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"),
1099 WM5100_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
1100 WM5100_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
1102 WM5100_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
1103 WM5100_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
1105 WM5100_MIXER_WIDGETS(HPOUT1L, "HPOUT1L"),
1106 WM5100_MIXER_WIDGETS(HPOUT1R, "HPOUT1R"),
1107 WM5100_MIXER_WIDGETS(HPOUT2L, "HPOUT2L"),
1108 WM5100_MIXER_WIDGETS(HPOUT2R, "HPOUT2R"),
1109 WM5100_MIXER_WIDGETS(HPOUT3L, "HPOUT3L"),
1110 WM5100_MIXER_WIDGETS(HPOUT3R, "HPOUT3R"),
1112 WM5100_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"),
1113 WM5100_MIXER_WIDGETS(SPKOUTR, "SPKOUTR"),
1114 WM5100_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"),
1115 WM5100_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"),
1116 WM5100_MIXER_WIDGETS(SPKDAT2L, "SPKDAT2L"),
1117 WM5100_MIXER_WIDGETS(SPKDAT2R, "SPKDAT2R"),
1119 WM5100_MIXER_WIDGETS(PWM1, "PWM1"),
1120 WM5100_MIXER_WIDGETS(PWM2, "PWM2"),
1122 SND_SOC_DAPM_OUTPUT("HPOUT1L"),
1123 SND_SOC_DAPM_OUTPUT("HPOUT1R"),
1124 SND_SOC_DAPM_OUTPUT("HPOUT2L"),
1125 SND_SOC_DAPM_OUTPUT("HPOUT2R"),
1126 SND_SOC_DAPM_OUTPUT("HPOUT3L"),
1127 SND_SOC_DAPM_OUTPUT("HPOUT3R"),
1128 SND_SOC_DAPM_OUTPUT("SPKOUTL"),
1129 SND_SOC_DAPM_OUTPUT("SPKOUTR"),
1130 SND_SOC_DAPM_OUTPUT("SPKDAT1"),
1131 SND_SOC_DAPM_OUTPUT("SPKDAT2"),
1132 SND_SOC_DAPM_OUTPUT("PWM1"),
1133 SND_SOC_DAPM_OUTPUT("PWM2"),
1136 /* We register a _POST event if we don't have IRQ support so we can
1137 * look at the error status from the CODEC - if we've got the IRQ
1138 * hooked up then we will get prompted to look by an interrupt.
1140 static const struct snd_soc_dapm_widget wm5100_dapm_widgets_noirq[] = {
1141 SND_SOC_DAPM_POST("Post", wm5100_post_ev),
1144 static const struct snd_soc_dapm_route wm5100_dapm_routes[] = {
1145 { "IN1L", NULL, "SYSCLK" },
1146 { "IN1R", NULL, "SYSCLK" },
1147 { "IN2L", NULL, "SYSCLK" },
1148 { "IN2R", NULL, "SYSCLK" },
1149 { "IN3L", NULL, "SYSCLK" },
1150 { "IN3R", NULL, "SYSCLK" },
1151 { "IN4L", NULL, "SYSCLK" },
1152 { "IN4R", NULL, "SYSCLK" },
1154 { "OUT1L", NULL, "SYSCLK" },
1155 { "OUT1R", NULL, "SYSCLK" },
1156 { "OUT2L", NULL, "SYSCLK" },
1157 { "OUT2R", NULL, "SYSCLK" },
1158 { "OUT3L", NULL, "SYSCLK" },
1159 { "OUT3R", NULL, "SYSCLK" },
1160 { "OUT4L", NULL, "SYSCLK" },
1161 { "OUT4R", NULL, "SYSCLK" },
1162 { "OUT5L", NULL, "SYSCLK" },
1163 { "OUT5R", NULL, "SYSCLK" },
1164 { "OUT6L", NULL, "SYSCLK" },
1165 { "OUT6R", NULL, "SYSCLK" },
1167 { "AIF1RX1", NULL, "SYSCLK" },
1168 { "AIF1RX2", NULL, "SYSCLK" },
1169 { "AIF1RX3", NULL, "SYSCLK" },
1170 { "AIF1RX4", NULL, "SYSCLK" },
1171 { "AIF1RX5", NULL, "SYSCLK" },
1172 { "AIF1RX6", NULL, "SYSCLK" },
1173 { "AIF1RX7", NULL, "SYSCLK" },
1174 { "AIF1RX8", NULL, "SYSCLK" },
1176 { "AIF2RX1", NULL, "SYSCLK" },
1177 { "AIF2RX1", NULL, "DBVDD2" },
1178 { "AIF2RX2", NULL, "SYSCLK" },
1179 { "AIF2RX2", NULL, "DBVDD2" },
1181 { "AIF3RX1", NULL, "SYSCLK" },
1182 { "AIF3RX1", NULL, "DBVDD3" },
1183 { "AIF3RX2", NULL, "SYSCLK" },
1184 { "AIF3RX2", NULL, "DBVDD3" },
1186 { "AIF1TX1", NULL, "SYSCLK" },
1187 { "AIF1TX2", NULL, "SYSCLK" },
1188 { "AIF1TX3", NULL, "SYSCLK" },
1189 { "AIF1TX4", NULL, "SYSCLK" },
1190 { "AIF1TX5", NULL, "SYSCLK" },
1191 { "AIF1TX6", NULL, "SYSCLK" },
1192 { "AIF1TX7", NULL, "SYSCLK" },
1193 { "AIF1TX8", NULL, "SYSCLK" },
1195 { "AIF2TX1", NULL, "SYSCLK" },
1196 { "AIF2TX1", NULL, "DBVDD2" },
1197 { "AIF2TX2", NULL, "SYSCLK" },
1198 { "AIF2TX2", NULL, "DBVDD2" },
1200 { "AIF3TX1", NULL, "SYSCLK" },
1201 { "AIF3TX1", NULL, "DBVDD3" },
1202 { "AIF3TX2", NULL, "SYSCLK" },
1203 { "AIF3TX2", NULL, "DBVDD3" },
1205 { "MICBIAS1", NULL, "CP2" },
1206 { "MICBIAS2", NULL, "CP2" },
1207 { "MICBIAS3", NULL, "CP2" },
1209 { "IN1L PGA", NULL, "CP2" },
1210 { "IN1R PGA", NULL, "CP2" },
1211 { "IN2L PGA", NULL, "CP2" },
1212 { "IN2R PGA", NULL, "CP2" },
1213 { "IN3L PGA", NULL, "CP2" },
1214 { "IN3R PGA", NULL, "CP2" },
1215 { "IN4L PGA", NULL, "CP2" },
1216 { "IN4R PGA", NULL, "CP2" },
1218 { "IN1L PGA", NULL, "CP2 Active" },
1219 { "IN1R PGA", NULL, "CP2 Active" },
1220 { "IN2L PGA", NULL, "CP2 Active" },
1221 { "IN2R PGA", NULL, "CP2 Active" },
1222 { "IN3L PGA", NULL, "CP2 Active" },
1223 { "IN3R PGA", NULL, "CP2 Active" },
1224 { "IN4L PGA", NULL, "CP2 Active" },
1225 { "IN4R PGA", NULL, "CP2 Active" },
1227 { "OUT1L", NULL, "CP1" },
1228 { "OUT1R", NULL, "CP1" },
1229 { "OUT2L", NULL, "CP1" },
1230 { "OUT2R", NULL, "CP1" },
1231 { "OUT3L", NULL, "CP1" },
1232 { "OUT3R", NULL, "CP1" },
1234 { "Tone Generator 1", NULL, "TONE" },
1235 { "Tone Generator 2", NULL, "TONE" },
1237 { "IN1L PGA", NULL, "IN1L" },
1238 { "IN1R PGA", NULL, "IN1R" },
1239 { "IN2L PGA", NULL, "IN2L" },
1240 { "IN2R PGA", NULL, "IN2R" },
1241 { "IN3L PGA", NULL, "IN3L" },
1242 { "IN3R PGA", NULL, "IN3R" },
1243 { "IN4L PGA", NULL, "IN4L" },
1244 { "IN4R PGA", NULL, "IN4R" },
1246 WM5100_MIXER_ROUTES("OUT1L", "HPOUT1L"),
1247 WM5100_MIXER_ROUTES("OUT1R", "HPOUT1R"),
1248 WM5100_MIXER_ROUTES("OUT2L", "HPOUT2L"),
1249 WM5100_MIXER_ROUTES("OUT2R", "HPOUT2R"),
1250 WM5100_MIXER_ROUTES("OUT3L", "HPOUT3L"),
1251 WM5100_MIXER_ROUTES("OUT3R", "HPOUT3R"),
1253 WM5100_MIXER_ROUTES("OUT4L", "SPKOUTL"),
1254 WM5100_MIXER_ROUTES("OUT4R", "SPKOUTR"),
1255 WM5100_MIXER_ROUTES("OUT5L", "SPKDAT1L"),
1256 WM5100_MIXER_ROUTES("OUT5R", "SPKDAT1R"),
1257 WM5100_MIXER_ROUTES("OUT6L", "SPKDAT2L"),
1258 WM5100_MIXER_ROUTES("OUT6R", "SPKDAT2R"),
1260 WM5100_MIXER_ROUTES("PWM1 Driver", "PWM1"),
1261 WM5100_MIXER_ROUTES("PWM2 Driver", "PWM2"),
1263 WM5100_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
1264 WM5100_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
1265 WM5100_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
1266 WM5100_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
1267 WM5100_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
1268 WM5100_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
1269 WM5100_MIXER_ROUTES("AIF1TX7", "AIF1TX7"),
1270 WM5100_MIXER_ROUTES("AIF1TX8", "AIF1TX8"),
1272 WM5100_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
1273 WM5100_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
1275 WM5100_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
1276 WM5100_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
1278 WM5100_MIXER_ROUTES("EQ1", "EQ1"),
1279 WM5100_MIXER_ROUTES("EQ2", "EQ2"),
1280 WM5100_MIXER_ROUTES("EQ3", "EQ3"),
1281 WM5100_MIXER_ROUTES("EQ4", "EQ4"),
1283 WM5100_MIXER_ROUTES("DRC1L", "DRC1L"),
1284 WM5100_MIXER_ROUTES("DRC1R", "DRC1R"),
1286 WM5100_MIXER_ROUTES("LHPF1", "LHPF1"),
1287 WM5100_MIXER_ROUTES("LHPF2", "LHPF2"),
1288 WM5100_MIXER_ROUTES("LHPF3", "LHPF3"),
1289 WM5100_MIXER_ROUTES("LHPF4", "LHPF4"),
1291 { "HPOUT1L", NULL, "OUT1L" },
1292 { "HPOUT1R", NULL, "OUT1R" },
1293 { "HPOUT2L", NULL, "OUT2L" },
1294 { "HPOUT2R", NULL, "OUT2R" },
1295 { "HPOUT3L", NULL, "OUT3L" },
1296 { "HPOUT3R", NULL, "OUT3R" },
1297 { "SPKOUTL", NULL, "OUT4L" },
1298 { "SPKOUTR", NULL, "OUT4R" },
1299 { "SPKDAT1", NULL, "OUT5L" },
1300 { "SPKDAT1", NULL, "OUT5R" },
1301 { "SPKDAT2", NULL, "OUT6L" },
1302 { "SPKDAT2", NULL, "OUT6R" },
1303 { "PWM1", NULL, "PWM1 Driver" },
1304 { "PWM2", NULL, "PWM2 Driver" },
1307 static struct {
1308 int reg;
1309 int val;
1310 } wm5100_reva_patches[] = {
1311 { WM5100_AUDIO_IF_1_10, 0 },
1312 { WM5100_AUDIO_IF_1_11, 1 },
1313 { WM5100_AUDIO_IF_1_12, 2 },
1314 { WM5100_AUDIO_IF_1_13, 3 },
1315 { WM5100_AUDIO_IF_1_14, 4 },
1316 { WM5100_AUDIO_IF_1_15, 5 },
1317 { WM5100_AUDIO_IF_1_16, 6 },
1318 { WM5100_AUDIO_IF_1_17, 7 },
1320 { WM5100_AUDIO_IF_1_18, 0 },
1321 { WM5100_AUDIO_IF_1_19, 1 },
1322 { WM5100_AUDIO_IF_1_20, 2 },
1323 { WM5100_AUDIO_IF_1_21, 3 },
1324 { WM5100_AUDIO_IF_1_22, 4 },
1325 { WM5100_AUDIO_IF_1_23, 5 },
1326 { WM5100_AUDIO_IF_1_24, 6 },
1327 { WM5100_AUDIO_IF_1_25, 7 },
1329 { WM5100_AUDIO_IF_2_10, 0 },
1330 { WM5100_AUDIO_IF_2_11, 1 },
1332 { WM5100_AUDIO_IF_2_18, 0 },
1333 { WM5100_AUDIO_IF_2_19, 1 },
1335 { WM5100_AUDIO_IF_3_10, 0 },
1336 { WM5100_AUDIO_IF_3_11, 1 },
1338 { WM5100_AUDIO_IF_3_18, 0 },
1339 { WM5100_AUDIO_IF_3_19, 1 },
1342 static int wm5100_set_bias_level(struct snd_soc_codec *codec,
1343 enum snd_soc_bias_level level)
1345 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1346 int ret, i;
1348 switch (level) {
1349 case SND_SOC_BIAS_ON:
1350 break;
1352 case SND_SOC_BIAS_PREPARE:
1353 break;
1355 case SND_SOC_BIAS_STANDBY:
1356 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1357 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
1358 wm5100->core_supplies);
1359 if (ret != 0) {
1360 dev_err(codec->dev,
1361 "Failed to enable supplies: %d\n",
1362 ret);
1363 return ret;
1366 if (wm5100->pdata.ldo_ena) {
1367 gpio_set_value_cansleep(wm5100->pdata.ldo_ena,
1369 msleep(2);
1372 codec->cache_only = false;
1374 switch (wm5100->rev) {
1375 case 0:
1376 snd_soc_write(codec, 0x11, 0x3);
1377 snd_soc_write(codec, 0x203, 0xc);
1378 snd_soc_write(codec, 0x206, 0);
1379 snd_soc_write(codec, 0x207, 0xf0);
1380 snd_soc_write(codec, 0x208, 0x3c);
1381 snd_soc_write(codec, 0x209, 0);
1382 snd_soc_write(codec, 0x211, 0x20d8);
1383 snd_soc_write(codec, 0x11, 0);
1385 for (i = 0;
1386 i < ARRAY_SIZE(wm5100_reva_patches);
1387 i++)
1388 snd_soc_write(codec,
1389 wm5100_reva_patches[i].reg,
1390 wm5100_reva_patches[i].val);
1391 break;
1392 default:
1393 break;
1396 snd_soc_cache_sync(codec);
1398 break;
1400 case SND_SOC_BIAS_OFF:
1401 if (wm5100->pdata.ldo_ena)
1402 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
1403 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
1404 wm5100->core_supplies);
1405 break;
1407 codec->dapm.bias_level = level;
1409 return 0;
1412 static int wm5100_dai_to_base(struct snd_soc_dai *dai)
1414 switch (dai->id) {
1415 case 0:
1416 return WM5100_AUDIO_IF_1_1 - 1;
1417 case 1:
1418 return WM5100_AUDIO_IF_2_1 - 1;
1419 case 2:
1420 return WM5100_AUDIO_IF_3_1 - 1;
1421 default:
1422 BUG();
1423 return -EINVAL;
1427 static int wm5100_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1429 struct snd_soc_codec *codec = dai->codec;
1430 int lrclk, bclk, mask, base;
1432 base = wm5100_dai_to_base(dai);
1433 if (base < 0)
1434 return base;
1436 lrclk = 0;
1437 bclk = 0;
1439 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1440 case SND_SOC_DAIFMT_DSP_A:
1441 mask = 0;
1442 break;
1443 case SND_SOC_DAIFMT_DSP_B:
1444 mask = 1;
1445 break;
1446 case SND_SOC_DAIFMT_I2S:
1447 mask = 2;
1448 break;
1449 case SND_SOC_DAIFMT_LEFT_J:
1450 mask = 3;
1451 break;
1452 default:
1453 dev_err(codec->dev, "Unsupported DAI format %d\n",
1454 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
1455 return -EINVAL;
1458 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1459 case SND_SOC_DAIFMT_CBS_CFS:
1460 break;
1461 case SND_SOC_DAIFMT_CBS_CFM:
1462 lrclk |= WM5100_AIF1TX_LRCLK_MSTR;
1463 break;
1464 case SND_SOC_DAIFMT_CBM_CFS:
1465 bclk |= WM5100_AIF1_BCLK_MSTR;
1466 break;
1467 case SND_SOC_DAIFMT_CBM_CFM:
1468 lrclk |= WM5100_AIF1TX_LRCLK_MSTR;
1469 bclk |= WM5100_AIF1_BCLK_MSTR;
1470 break;
1471 default:
1472 dev_err(codec->dev, "Unsupported master mode %d\n",
1473 fmt & SND_SOC_DAIFMT_MASTER_MASK);
1474 return -EINVAL;
1477 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1478 case SND_SOC_DAIFMT_NB_NF:
1479 break;
1480 case SND_SOC_DAIFMT_IB_IF:
1481 bclk |= WM5100_AIF1_BCLK_INV;
1482 lrclk |= WM5100_AIF1TX_LRCLK_INV;
1483 break;
1484 case SND_SOC_DAIFMT_IB_NF:
1485 bclk |= WM5100_AIF1_BCLK_INV;
1486 break;
1487 case SND_SOC_DAIFMT_NB_IF:
1488 lrclk |= WM5100_AIF1TX_LRCLK_INV;
1489 break;
1490 default:
1491 return -EINVAL;
1494 snd_soc_update_bits(codec, base + 1, WM5100_AIF1_BCLK_MSTR |
1495 WM5100_AIF1_BCLK_INV, bclk);
1496 snd_soc_update_bits(codec, base + 2, WM5100_AIF1TX_LRCLK_MSTR |
1497 WM5100_AIF1TX_LRCLK_INV, lrclk);
1498 snd_soc_update_bits(codec, base + 3, WM5100_AIF1TX_LRCLK_MSTR |
1499 WM5100_AIF1TX_LRCLK_INV, lrclk);
1500 snd_soc_update_bits(codec, base + 5, WM5100_AIF1_FMT_MASK, mask);
1502 return 0;
1505 #define WM5100_NUM_BCLK_RATES 19
1507 static int wm5100_bclk_rates_dat[WM5100_NUM_BCLK_RATES] = {
1508 32000,
1509 48000,
1510 64000,
1511 96000,
1512 128000,
1513 192000,
1514 256000,
1515 384000,
1516 512000,
1517 768000,
1518 1024000,
1519 1536000,
1520 2048000,
1521 3072000,
1522 4096000,
1523 6144000,
1524 8192000,
1525 12288000,
1526 24576000,
1529 static int wm5100_bclk_rates_cd[WM5100_NUM_BCLK_RATES] = {
1530 29400,
1531 44100,
1532 58800,
1533 88200,
1534 117600,
1535 176400,
1536 235200,
1537 352800,
1538 470400,
1539 705600,
1540 940800,
1541 1411200,
1542 1881600,
1543 2882400,
1544 3763200,
1545 5644800,
1546 7526400,
1547 11289600,
1548 22579600,
1551 static int wm5100_hw_params(struct snd_pcm_substream *substream,
1552 struct snd_pcm_hw_params *params,
1553 struct snd_soc_dai *dai)
1555 struct snd_soc_codec *codec = dai->codec;
1556 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1557 bool async = wm5100->aif_async[dai->id];
1558 int i, base, bclk, aif_rate, lrclk, wl, fl, sr;
1559 int *bclk_rates;
1561 base = wm5100_dai_to_base(dai);
1562 if (base < 0)
1563 return base;
1565 /* Data sizes if not using TDM */
1566 wl = snd_pcm_format_width(params_format(params));
1567 if (wl < 0)
1568 return wl;
1569 fl = snd_soc_params_to_frame_size(params);
1570 if (fl < 0)
1571 return fl;
1573 dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n",
1574 wl, fl);
1576 /* Target BCLK rate */
1577 bclk = snd_soc_params_to_bclk(params);
1578 if (bclk < 0)
1579 return bclk;
1581 /* Root for BCLK depends on SYS/ASYNCCLK */
1582 if (!async) {
1583 aif_rate = wm5100->sysclk;
1584 sr = wm5100_alloc_sr(codec, params_rate(params));
1585 if (sr < 0)
1586 return sr;
1587 } else {
1588 /* If we're in ASYNCCLK set the ASYNC sample rate */
1589 aif_rate = wm5100->asyncclk;
1590 sr = 3;
1592 for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++)
1593 if (params_rate(params) == wm5100_sr_code[i])
1594 break;
1595 if (i == ARRAY_SIZE(wm5100_sr_code)) {
1596 dev_err(codec->dev, "Invalid rate %dHzn",
1597 params_rate(params));
1598 return -EINVAL;
1601 /* TODO: We should really check for symmetry */
1602 snd_soc_update_bits(codec, WM5100_CLOCKING_8,
1603 WM5100_ASYNC_SAMPLE_RATE_MASK, i);
1606 if (!aif_rate) {
1607 dev_err(codec->dev, "%s has no rate set\n",
1608 async ? "ASYNCCLK" : "SYSCLK");
1609 return -EINVAL;
1612 dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz %s\n",
1613 bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK");
1615 if (aif_rate % 4000)
1616 bclk_rates = wm5100_bclk_rates_cd;
1617 else
1618 bclk_rates = wm5100_bclk_rates_dat;
1620 for (i = 0; i < WM5100_NUM_BCLK_RATES; i++)
1621 if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0))
1622 break;
1623 if (i == WM5100_NUM_BCLK_RATES) {
1624 dev_err(codec->dev,
1625 "No valid BCLK for %dHz found from %dHz %s\n",
1626 bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK");
1627 return -EINVAL;
1630 bclk = i;
1631 dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]);
1632 snd_soc_update_bits(codec, base + 1, WM5100_AIF1_BCLK_FREQ_MASK, bclk);
1634 lrclk = bclk_rates[bclk] / params_rate(params);
1635 dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk);
1636 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
1637 wm5100->aif_symmetric[dai->id])
1638 snd_soc_update_bits(codec, base + 7,
1639 WM5100_AIF1RX_BCPF_MASK, lrclk);
1640 else
1641 snd_soc_update_bits(codec, base + 6,
1642 WM5100_AIF1TX_BCPF_MASK, lrclk);
1644 i = (wl << WM5100_AIF1TX_WL_SHIFT) | fl;
1645 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1646 snd_soc_update_bits(codec, base + 9,
1647 WM5100_AIF1RX_WL_MASK |
1648 WM5100_AIF1RX_SLOT_LEN_MASK, i);
1649 else
1650 snd_soc_update_bits(codec, base + 8,
1651 WM5100_AIF1TX_WL_MASK |
1652 WM5100_AIF1TX_SLOT_LEN_MASK, i);
1654 snd_soc_update_bits(codec, base + 4, WM5100_AIF1_RATE_MASK, sr);
1656 return 0;
1659 static struct snd_soc_dai_ops wm5100_dai_ops = {
1660 .set_fmt = wm5100_set_fmt,
1661 .hw_params = wm5100_hw_params,
1664 static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id,
1665 int source, unsigned int freq, int dir)
1667 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1668 int *rate_store;
1669 int fval, audio_rate, ret, reg;
1671 switch (clk_id) {
1672 case WM5100_CLK_SYSCLK:
1673 reg = WM5100_CLOCKING_3;
1674 rate_store = &wm5100->sysclk;
1675 break;
1676 case WM5100_CLK_ASYNCCLK:
1677 reg = WM5100_CLOCKING_7;
1678 rate_store = &wm5100->asyncclk;
1679 break;
1680 case WM5100_CLK_32KHZ:
1681 /* The 32kHz clock is slightly different to the others */
1682 switch (source) {
1683 case WM5100_CLKSRC_MCLK1:
1684 case WM5100_CLKSRC_MCLK2:
1685 case WM5100_CLKSRC_SYSCLK:
1686 snd_soc_update_bits(codec, WM5100_CLOCKING_1,
1687 WM5100_CLK_32K_SRC_MASK,
1688 source);
1689 break;
1690 default:
1691 return -EINVAL;
1693 return 0;
1695 case WM5100_CLK_AIF1:
1696 case WM5100_CLK_AIF2:
1697 case WM5100_CLK_AIF3:
1698 /* Not real clocks, record which clock domain they're in */
1699 switch (source) {
1700 case WM5100_CLKSRC_SYSCLK:
1701 wm5100->aif_async[clk_id - 1] = false;
1702 break;
1703 case WM5100_CLKSRC_ASYNCCLK:
1704 wm5100->aif_async[clk_id - 1] = true;
1705 break;
1706 default:
1707 dev_err(codec->dev, "Invalid source %d\n", source);
1708 return -EINVAL;
1710 return 0;
1712 case WM5100_CLK_OPCLK:
1713 switch (freq) {
1714 case 5644800:
1715 case 6144000:
1716 snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
1717 WM5100_OPCLK_SEL_MASK, 0);
1718 break;
1719 case 11289600:
1720 case 12288000:
1721 snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
1722 WM5100_OPCLK_SEL_MASK, 0);
1723 break;
1724 case 22579200:
1725 case 24576000:
1726 snd_soc_update_bits(codec, WM5100_MISC_GPIO_1,
1727 WM5100_OPCLK_SEL_MASK, 0);
1728 break;
1729 default:
1730 dev_err(codec->dev, "Unsupported OPCLK %dHz\n",
1731 freq);
1732 return -EINVAL;
1734 return 0;
1736 default:
1737 dev_err(codec->dev, "Unknown clock %d\n", clk_id);
1738 return -EINVAL;
1741 switch (source) {
1742 case WM5100_CLKSRC_SYSCLK:
1743 case WM5100_CLKSRC_ASYNCCLK:
1744 dev_err(codec->dev, "Invalid source %d\n", source);
1745 return -EINVAL;
1748 switch (freq) {
1749 case 5644800:
1750 case 6144000:
1751 fval = 0;
1752 break;
1753 case 11289600:
1754 case 12288000:
1755 fval = 1;
1756 break;
1757 case 22579200:
1758 case 2457600:
1759 fval = 2;
1760 break;
1761 default:
1762 dev_err(codec->dev, "Invalid clock rate: %d\n", freq);
1763 return -EINVAL;
1766 switch (freq) {
1767 case 5644800:
1768 case 11289600:
1769 case 22579200:
1770 audio_rate = 44100;
1771 break;
1773 case 6144000:
1774 case 12288000:
1775 case 2457600:
1776 audio_rate = 48000;
1777 break;
1779 default:
1780 BUG();
1781 audio_rate = 0;
1782 break;
1785 /* TODO: Check if MCLKs are in use and enable/disable pulls to
1786 * match.
1789 snd_soc_update_bits(codec, reg, WM5100_SYSCLK_FREQ_MASK |
1790 WM5100_SYSCLK_SRC_MASK,
1791 fval << WM5100_SYSCLK_FREQ_SHIFT | source);
1793 /* If this is SYSCLK then configure the clock rate for the
1794 * internal audio functions to the natural sample rate for
1795 * this clock rate.
1797 if (clk_id == WM5100_CLK_SYSCLK) {
1798 dev_dbg(codec->dev, "Setting primary audio rate to %dHz",
1799 audio_rate);
1800 if (0 && *rate_store)
1801 wm5100_free_sr(codec, audio_rate);
1802 ret = wm5100_alloc_sr(codec, audio_rate);
1803 if (ret != 0)
1804 dev_warn(codec->dev, "Primary audio slot is %d\n",
1805 ret);
1808 *rate_store = freq;
1810 return 0;
1813 struct _fll_div {
1814 u16 fll_fratio;
1815 u16 fll_outdiv;
1816 u16 fll_refclk_div;
1817 u16 n;
1818 u16 theta;
1819 u16 lambda;
1822 static struct {
1823 unsigned int min;
1824 unsigned int max;
1825 u16 fll_fratio;
1826 int ratio;
1827 } fll_fratios[] = {
1828 { 0, 64000, 4, 16 },
1829 { 64000, 128000, 3, 8 },
1830 { 128000, 256000, 2, 4 },
1831 { 256000, 1000000, 1, 2 },
1832 { 1000000, 13500000, 0, 1 },
1835 static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1836 unsigned int Fout)
1838 unsigned int target;
1839 unsigned int div;
1840 unsigned int fratio, gcd_fll;
1841 int i;
1843 /* Fref must be <=13.5MHz */
1844 div = 1;
1845 fll_div->fll_refclk_div = 0;
1846 while ((Fref / div) > 13500000) {
1847 div *= 2;
1848 fll_div->fll_refclk_div++;
1850 if (div > 8) {
1851 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1852 Fref);
1853 return -EINVAL;
1857 pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);
1859 /* Apply the division for our remaining calculations */
1860 Fref /= div;
1862 /* Fvco should be 90-100MHz; don't check the upper bound */
1863 div = 2;
1864 while (Fout * div < 90000000) {
1865 div++;
1866 if (div > 64) {
1867 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1868 Fout);
1869 return -EINVAL;
1872 target = Fout * div;
1873 fll_div->fll_outdiv = div - 1;
1875 pr_debug("FLL Fvco=%dHz\n", target);
1877 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1878 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1879 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1880 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1881 fratio = fll_fratios[i].ratio;
1882 break;
1885 if (i == ARRAY_SIZE(fll_fratios)) {
1886 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1887 return -EINVAL;
1890 fll_div->n = target / (fratio * Fref);
1892 if (target % Fref == 0) {
1893 fll_div->theta = 0;
1894 fll_div->lambda = 0;
1895 } else {
1896 gcd_fll = gcd(target, fratio * Fref);
1898 fll_div->theta = (target - (fll_div->n * fratio * Fref))
1899 / gcd_fll;
1900 fll_div->lambda = (fratio * Fref) / gcd_fll;
1903 pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",
1904 fll_div->n, fll_div->theta, fll_div->lambda);
1905 pr_debug("FLL_FRATIO=%x(%d) FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",
1906 fll_div->fll_fratio, fratio, fll_div->fll_outdiv,
1907 fll_div->fll_refclk_div);
1909 return 0;
1912 static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
1913 unsigned int Fref, unsigned int Fout)
1915 struct i2c_client *i2c = to_i2c_client(codec->dev);
1916 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
1917 struct _fll_div factors;
1918 struct wm5100_fll *fll;
1919 int ret, base, lock, i, timeout;
1921 switch (fll_id) {
1922 case WM5100_FLL1:
1923 fll = &wm5100->fll[0];
1924 base = WM5100_FLL1_CONTROL_1 - 1;
1925 lock = WM5100_FLL1_LOCK_STS;
1926 break;
1927 case WM5100_FLL2:
1928 fll = &wm5100->fll[1];
1929 base = WM5100_FLL2_CONTROL_2 - 1;
1930 lock = WM5100_FLL2_LOCK_STS;
1931 break;
1932 default:
1933 dev_err(codec->dev, "Unknown FLL %d\n",fll_id);
1934 return -EINVAL;
1937 if (!Fout) {
1938 dev_dbg(codec->dev, "FLL%d disabled", fll_id);
1939 fll->fout = 0;
1940 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
1941 return 0;
1944 switch (source) {
1945 case WM5100_FLL_SRC_MCLK1:
1946 case WM5100_FLL_SRC_MCLK2:
1947 case WM5100_FLL_SRC_FLL1:
1948 case WM5100_FLL_SRC_FLL2:
1949 case WM5100_FLL_SRC_AIF1BCLK:
1950 case WM5100_FLL_SRC_AIF2BCLK:
1951 case WM5100_FLL_SRC_AIF3BCLK:
1952 break;
1953 default:
1954 dev_err(codec->dev, "Invalid FLL source %d\n", source);
1955 return -EINVAL;
1958 ret = fll_factors(&factors, Fref, Fout);
1959 if (ret < 0)
1960 return ret;
1962 /* Disable the FLL while we reconfigure */
1963 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0);
1965 snd_soc_update_bits(codec, base + 2,
1966 WM5100_FLL1_OUTDIV_MASK | WM5100_FLL1_FRATIO_MASK,
1967 (factors.fll_outdiv << WM5100_FLL1_OUTDIV_SHIFT) |
1968 factors.fll_fratio);
1969 snd_soc_update_bits(codec, base + 3, WM5100_FLL1_THETA_MASK,
1970 factors.theta);
1971 snd_soc_update_bits(codec, base + 5, WM5100_FLL1_N_MASK, factors.n);
1972 snd_soc_update_bits(codec, base + 6,
1973 WM5100_FLL1_REFCLK_DIV_MASK |
1974 WM5100_FLL1_REFCLK_SRC_MASK,
1975 (factors.fll_refclk_div
1976 << WM5100_FLL1_REFCLK_DIV_SHIFT) | source);
1977 snd_soc_update_bits(codec, base + 7, WM5100_FLL1_LAMBDA_MASK,
1978 factors.lambda);
1980 /* Clear any pending completions */
1981 try_wait_for_completion(&fll->lock);
1983 snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA);
1985 if (i2c->irq)
1986 timeout = 2;
1987 else
1988 timeout = 50;
1990 /* Poll for the lock; will use interrupt when we can test */
1991 for (i = 0; i < timeout; i++) {
1992 if (i2c->irq) {
1993 ret = wait_for_completion_timeout(&fll->lock,
1994 msecs_to_jiffies(25));
1995 if (ret > 0)
1996 break;
1997 } else {
1998 msleep(1);
2001 ret = snd_soc_read(codec,
2002 WM5100_INTERRUPT_RAW_STATUS_3);
2003 if (ret < 0) {
2004 dev_err(codec->dev,
2005 "Failed to read FLL status: %d\n",
2006 ret);
2007 continue;
2009 if (ret & lock)
2010 break;
2012 if (i == timeout) {
2013 dev_err(codec->dev, "FLL%d lock timed out\n", fll_id);
2014 return -ETIMEDOUT;
2017 fll->src = source;
2018 fll->fref = Fref;
2019 fll->fout = Fout;
2021 dev_dbg(codec->dev, "FLL%d running %dHz->%dHz\n", fll_id,
2022 Fref, Fout);
2024 return 0;
2027 /* Actually go much higher */
2028 #define WM5100_RATES SNDRV_PCM_RATE_8000_192000
2030 #define WM5100_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2031 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
2033 static struct snd_soc_dai_driver wm5100_dai[] = {
2035 .name = "wm5100-aif1",
2036 .playback = {
2037 .stream_name = "AIF1 Playback",
2038 .channels_min = 2,
2039 .channels_max = 2,
2040 .rates = WM5100_RATES,
2041 .formats = WM5100_FORMATS,
2043 .capture = {
2044 .stream_name = "AIF1 Capture",
2045 .channels_min = 2,
2046 .channels_max = 2,
2047 .rates = WM5100_RATES,
2048 .formats = WM5100_FORMATS,
2050 .ops = &wm5100_dai_ops,
2053 .name = "wm5100-aif2",
2054 .id = 1,
2055 .playback = {
2056 .stream_name = "AIF2 Playback",
2057 .channels_min = 2,
2058 .channels_max = 2,
2059 .rates = WM5100_RATES,
2060 .formats = WM5100_FORMATS,
2062 .capture = {
2063 .stream_name = "AIF2 Capture",
2064 .channels_min = 2,
2065 .channels_max = 2,
2066 .rates = WM5100_RATES,
2067 .formats = WM5100_FORMATS,
2069 .ops = &wm5100_dai_ops,
2072 .name = "wm5100-aif3",
2073 .id = 2,
2074 .playback = {
2075 .stream_name = "AIF3 Playback",
2076 .channels_min = 2,
2077 .channels_max = 2,
2078 .rates = WM5100_RATES,
2079 .formats = WM5100_FORMATS,
2081 .capture = {
2082 .stream_name = "AIF3 Capture",
2083 .channels_min = 2,
2084 .channels_max = 2,
2085 .rates = WM5100_RATES,
2086 .formats = WM5100_FORMATS,
2088 .ops = &wm5100_dai_ops,
2092 static int wm5100_dig_vu[] = {
2093 WM5100_ADC_DIGITAL_VOLUME_1L,
2094 WM5100_ADC_DIGITAL_VOLUME_1R,
2095 WM5100_ADC_DIGITAL_VOLUME_2L,
2096 WM5100_ADC_DIGITAL_VOLUME_2R,
2097 WM5100_ADC_DIGITAL_VOLUME_3L,
2098 WM5100_ADC_DIGITAL_VOLUME_3R,
2099 WM5100_ADC_DIGITAL_VOLUME_4L,
2100 WM5100_ADC_DIGITAL_VOLUME_4R,
2102 WM5100_DAC_DIGITAL_VOLUME_1L,
2103 WM5100_DAC_DIGITAL_VOLUME_1R,
2104 WM5100_DAC_DIGITAL_VOLUME_2L,
2105 WM5100_DAC_DIGITAL_VOLUME_2R,
2106 WM5100_DAC_DIGITAL_VOLUME_3L,
2107 WM5100_DAC_DIGITAL_VOLUME_3R,
2108 WM5100_DAC_DIGITAL_VOLUME_4L,
2109 WM5100_DAC_DIGITAL_VOLUME_4R,
2110 WM5100_DAC_DIGITAL_VOLUME_5L,
2111 WM5100_DAC_DIGITAL_VOLUME_5R,
2112 WM5100_DAC_DIGITAL_VOLUME_6L,
2113 WM5100_DAC_DIGITAL_VOLUME_6R,
2116 static irqreturn_t wm5100_irq(int irq, void *data)
2118 struct snd_soc_codec *codec = data;
2119 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2120 irqreturn_t status = IRQ_NONE;
2121 int irq_val;
2123 irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3);
2124 if (irq_val < 0) {
2125 dev_err(codec->dev, "Failed to read IRQ status 3: %d\n",
2126 irq_val);
2127 irq_val = 0;
2129 irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3_MASK);
2131 snd_soc_write(codec, WM5100_INTERRUPT_STATUS_3, irq_val);
2133 if (irq_val)
2134 status = IRQ_HANDLED;
2136 wm5100_log_status3(codec, irq_val);
2138 if (irq_val & WM5100_FLL1_LOCK_EINT) {
2139 dev_dbg(codec->dev, "FLL1 locked\n");
2140 complete(&wm5100->fll[0].lock);
2142 if (irq_val & WM5100_FLL2_LOCK_EINT) {
2143 dev_dbg(codec->dev, "FLL2 locked\n");
2144 complete(&wm5100->fll[1].lock);
2147 irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4);
2148 if (irq_val < 0) {
2149 dev_err(codec->dev, "Failed to read IRQ status 4: %d\n",
2150 irq_val);
2151 irq_val = 0;
2153 irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4_MASK);
2155 if (irq_val)
2156 status = IRQ_HANDLED;
2158 snd_soc_write(codec, WM5100_INTERRUPT_STATUS_4, irq_val);
2160 wm5100_log_status4(codec, irq_val);
2162 return status;
2165 static irqreturn_t wm5100_edge_irq(int irq, void *data)
2167 irqreturn_t ret = IRQ_NONE;
2168 irqreturn_t val;
2170 do {
2171 val = wm5100_irq(irq, data);
2172 if (val != IRQ_NONE)
2173 ret = val;
2174 } while (val != IRQ_NONE);
2176 return ret;
2179 #ifdef CONFIG_GPIOLIB
2180 static inline struct wm5100_priv *gpio_to_wm5100(struct gpio_chip *chip)
2182 return container_of(chip, struct wm5100_priv, gpio_chip);
2185 static void wm5100_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
2187 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2188 struct snd_soc_codec *codec = wm5100->codec;
2190 snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
2191 WM5100_GP1_LVL, !!value << WM5100_GP1_LVL_SHIFT);
2194 static int wm5100_gpio_direction_out(struct gpio_chip *chip,
2195 unsigned offset, int value)
2197 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2198 struct snd_soc_codec *codec = wm5100->codec;
2199 int val;
2201 val = (1 << WM5100_GP1_FN_SHIFT) | (!!value << WM5100_GP1_LVL_SHIFT);
2203 return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
2204 WM5100_GP1_FN_MASK | WM5100_GP1_DIR |
2205 WM5100_GP1_LVL, val);
2208 static int wm5100_gpio_get(struct gpio_chip *chip, unsigned offset)
2210 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2211 struct snd_soc_codec *codec = wm5100->codec;
2212 int ret;
2214 ret = snd_soc_read(codec, WM5100_GPIO_CTRL_1 + offset);
2215 if (ret < 0)
2216 return ret;
2218 return (ret & WM5100_GP1_LVL) != 0;
2221 static int wm5100_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
2223 struct wm5100_priv *wm5100 = gpio_to_wm5100(chip);
2224 struct snd_soc_codec *codec = wm5100->codec;
2226 return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset,
2227 WM5100_GP1_FN_MASK | WM5100_GP1_DIR,
2228 (1 << WM5100_GP1_FN_SHIFT) |
2229 (1 << WM5100_GP1_DIR_SHIFT));
2232 static struct gpio_chip wm5100_template_chip = {
2233 .label = "wm5100",
2234 .owner = THIS_MODULE,
2235 .direction_output = wm5100_gpio_direction_out,
2236 .set = wm5100_gpio_set,
2237 .direction_input = wm5100_gpio_direction_in,
2238 .get = wm5100_gpio_get,
2239 .can_sleep = 1,
2242 static void wm5100_init_gpio(struct snd_soc_codec *codec)
2244 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2245 int ret;
2247 wm5100->gpio_chip = wm5100_template_chip;
2248 wm5100->gpio_chip.ngpio = 6;
2249 wm5100->gpio_chip.dev = codec->dev;
2251 if (wm5100->pdata.gpio_base)
2252 wm5100->gpio_chip.base = wm5100->pdata.gpio_base;
2253 else
2254 wm5100->gpio_chip.base = -1;
2256 ret = gpiochip_add(&wm5100->gpio_chip);
2257 if (ret != 0)
2258 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret);
2261 static void wm5100_free_gpio(struct snd_soc_codec *codec)
2263 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2264 int ret;
2266 ret = gpiochip_remove(&wm5100->gpio_chip);
2267 if (ret != 0)
2268 dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret);
2270 #else
2271 static void wm5100_init_gpio(struct snd_soc_codec *codec)
2275 static void wm5100_free_gpio(struct snd_soc_codec *codec)
2278 #endif
2280 static int wm5100_probe(struct snd_soc_codec *codec)
2282 struct i2c_client *i2c = to_i2c_client(codec->dev);
2283 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2284 int ret, i, irq_flags;
2286 wm5100->codec = codec;
2288 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
2290 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
2291 if (ret != 0) {
2292 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2293 return ret;
2296 for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++)
2297 wm5100->core_supplies[i].supply = wm5100_core_supply_names[i];
2299 ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm5100->core_supplies),
2300 wm5100->core_supplies);
2301 if (ret != 0) {
2302 dev_err(codec->dev, "Failed to request core supplies: %d\n",
2303 ret);
2304 return ret;
2307 wm5100->cpvdd = regulator_get(&i2c->dev, "CPVDD");
2308 if (IS_ERR(wm5100->cpvdd)) {
2309 ret = PTR_ERR(wm5100->cpvdd);
2310 dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
2311 goto err_core;
2314 wm5100->dbvdd2 = regulator_get(&i2c->dev, "DBVDD2");
2315 if (IS_ERR(wm5100->dbvdd2)) {
2316 ret = PTR_ERR(wm5100->dbvdd2);
2317 dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
2318 goto err_cpvdd;
2321 wm5100->dbvdd3 = regulator_get(&i2c->dev, "DBVDD3");
2322 if (IS_ERR(wm5100->dbvdd3)) {
2323 ret = PTR_ERR(wm5100->dbvdd3);
2324 dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret);
2325 goto err_dbvdd2;
2328 ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies),
2329 wm5100->core_supplies);
2330 if (ret != 0) {
2331 dev_err(codec->dev, "Failed to enable core supplies: %d\n",
2332 ret);
2333 goto err_dbvdd3;
2336 if (wm5100->pdata.ldo_ena) {
2337 ret = gpio_request_one(wm5100->pdata.ldo_ena,
2338 GPIOF_OUT_INIT_HIGH, "WM5100 LDOENA");
2339 if (ret < 0) {
2340 dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n",
2341 wm5100->pdata.ldo_ena, ret);
2342 goto err_enable;
2344 msleep(2);
2347 if (wm5100->pdata.reset) {
2348 ret = gpio_request_one(wm5100->pdata.reset,
2349 GPIOF_OUT_INIT_HIGH, "WM5100 /RESET");
2350 if (ret < 0) {
2351 dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n",
2352 wm5100->pdata.reset, ret);
2353 goto err_ldo;
2357 ret = snd_soc_read(codec, WM5100_SOFTWARE_RESET);
2358 if (ret < 0) {
2359 dev_err(codec->dev, "Failed to read ID register\n");
2360 goto err_reset;
2362 switch (ret) {
2363 case 0x8997:
2364 case 0x5100:
2365 break;
2367 default:
2368 dev_err(codec->dev, "Device is not a WM5100, ID is %x\n", ret);
2369 ret = -EINVAL;
2370 goto err_reset;
2373 ret = snd_soc_read(codec, WM5100_DEVICE_REVISION);
2374 if (ret < 0) {
2375 dev_err(codec->dev, "Failed to read revision register\n");
2376 goto err_reset;
2378 wm5100->rev = ret & WM5100_DEVICE_REVISION_MASK;
2380 dev_info(codec->dev, "revision %c\n", wm5100->rev + 'A');
2382 ret = wm5100_reset(codec);
2383 if (ret < 0) {
2384 dev_err(codec->dev, "Failed to issue reset\n");
2385 goto err_reset;
2388 codec->cache_only = true;
2390 wm5100_init_gpio(codec);
2392 for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++)
2393 snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU,
2394 WM5100_OUT_VU);
2396 for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) {
2397 snd_soc_update_bits(codec, WM5100_IN1L_CONTROL,
2398 WM5100_IN1_MODE_MASK |
2399 WM5100_IN1_DMIC_SUP_MASK,
2400 (wm5100->pdata.in_mode[i] <<
2401 WM5100_IN1_MODE_SHIFT) |
2402 (wm5100->pdata.dmic_sup[i] <<
2403 WM5100_IN1_DMIC_SUP_SHIFT));
2406 for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) {
2407 if (!wm5100->pdata.gpio_defaults[i])
2408 continue;
2410 snd_soc_write(codec, WM5100_GPIO_CTRL_1 + i,
2411 wm5100->pdata.gpio_defaults[i]);
2414 /* Don't debounce interrupts to support use of SYSCLK only */
2415 snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_1, 0);
2416 snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_2, 0);
2418 /* TODO: check if we're symmetric */
2420 if (i2c->irq) {
2421 if (wm5100->pdata.irq_flags)
2422 irq_flags = wm5100->pdata.irq_flags;
2423 else
2424 irq_flags = IRQF_TRIGGER_LOW;
2426 irq_flags |= IRQF_ONESHOT;
2428 if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))
2429 ret = request_threaded_irq(i2c->irq, NULL,
2430 wm5100_edge_irq,
2431 irq_flags, "wm5100", codec);
2432 else
2433 ret = request_threaded_irq(i2c->irq, NULL, wm5100_irq,
2434 irq_flags, "wm5100", codec);
2436 if (ret != 0) {
2437 dev_err(codec->dev, "Failed to request IRQ %d: %d\n",
2438 i2c->irq, ret);
2439 } else {
2440 /* Enable default interrupts */
2441 snd_soc_update_bits(codec,
2442 WM5100_INTERRUPT_STATUS_3_MASK,
2443 WM5100_IM_SPK_SHUTDOWN_WARN_EINT |
2444 WM5100_IM_SPK_SHUTDOWN_EINT |
2445 WM5100_IM_ASRC2_LOCK_EINT |
2446 WM5100_IM_ASRC1_LOCK_EINT |
2447 WM5100_IM_FLL2_LOCK_EINT |
2448 WM5100_IM_FLL1_LOCK_EINT |
2449 WM5100_CLKGEN_ERR_EINT |
2450 WM5100_CLKGEN_ERR_ASYNC_EINT, 0);
2452 snd_soc_update_bits(codec,
2453 WM5100_INTERRUPT_STATUS_4_MASK,
2454 WM5100_AIF3_ERR_EINT |
2455 WM5100_AIF2_ERR_EINT |
2456 WM5100_AIF1_ERR_EINT |
2457 WM5100_CTRLIF_ERR_EINT |
2458 WM5100_ISRC2_UNDERCLOCKED_EINT |
2459 WM5100_ISRC1_UNDERCLOCKED_EINT |
2460 WM5100_FX_UNDERCLOCKED_EINT |
2461 WM5100_AIF3_UNDERCLOCKED_EINT |
2462 WM5100_AIF2_UNDERCLOCKED_EINT |
2463 WM5100_AIF1_UNDERCLOCKED_EINT |
2464 WM5100_ASRC_UNDERCLOCKED_EINT |
2465 WM5100_DAC_UNDERCLOCKED_EINT |
2466 WM5100_ADC_UNDERCLOCKED_EINT |
2467 WM5100_MIXER_UNDERCLOCKED_EINT, 0);
2469 } else {
2470 snd_soc_dapm_new_controls(&codec->dapm,
2471 wm5100_dapm_widgets_noirq,
2472 ARRAY_SIZE(wm5100_dapm_widgets_noirq));
2475 if (wm5100->pdata.hp_pol) {
2476 ret = gpio_request_one(wm5100->pdata.hp_pol,
2477 GPIOF_OUT_INIT_HIGH, "WM5100 HP_POL");
2478 if (ret < 0) {
2479 dev_err(&i2c->dev, "Failed to request HP_POL %d: %d\n",
2480 wm5100->pdata.hp_pol, ret);
2481 goto err_gpio;
2485 /* We'll get woken up again when the system has something useful
2486 * for us to do.
2488 if (wm5100->pdata.ldo_ena)
2489 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2490 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2491 wm5100->core_supplies);
2493 return 0;
2495 err_gpio:
2496 if (i2c->irq)
2497 free_irq(i2c->irq, codec);
2498 wm5100_free_gpio(codec);
2499 err_reset:
2500 if (wm5100->pdata.reset) {
2501 gpio_set_value_cansleep(wm5100->pdata.reset, 1);
2502 gpio_free(wm5100->pdata.reset);
2504 err_ldo:
2505 if (wm5100->pdata.ldo_ena) {
2506 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2507 gpio_free(wm5100->pdata.ldo_ena);
2509 err_enable:
2510 regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies),
2511 wm5100->core_supplies);
2512 err_dbvdd3:
2513 regulator_put(wm5100->dbvdd3);
2514 err_dbvdd2:
2515 regulator_put(wm5100->dbvdd2);
2516 err_cpvdd:
2517 regulator_put(wm5100->cpvdd);
2518 err_core:
2519 regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
2520 wm5100->core_supplies);
2522 return ret;
2525 static int wm5100_remove(struct snd_soc_codec *codec)
2527 struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec);
2528 struct i2c_client *i2c = to_i2c_client(codec->dev);
2530 wm5100_set_bias_level(codec, SND_SOC_BIAS_OFF);
2531 if (wm5100->pdata.hp_pol) {
2532 gpio_free(wm5100->pdata.hp_pol);
2534 if (i2c->irq)
2535 free_irq(i2c->irq, codec);
2536 wm5100_free_gpio(codec);
2537 if (wm5100->pdata.reset) {
2538 gpio_set_value_cansleep(wm5100->pdata.reset, 1);
2539 gpio_free(wm5100->pdata.reset);
2541 if (wm5100->pdata.ldo_ena) {
2542 gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0);
2543 gpio_free(wm5100->pdata.ldo_ena);
2545 regulator_put(wm5100->dbvdd3);
2546 regulator_put(wm5100->dbvdd2);
2547 regulator_put(wm5100->cpvdd);
2548 regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies),
2549 wm5100->core_supplies);
2550 return 0;
2553 static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
2554 .probe = wm5100_probe,
2555 .remove = wm5100_remove,
2557 .set_sysclk = wm5100_set_sysclk,
2558 .set_pll = wm5100_set_fll,
2559 .set_bias_level = wm5100_set_bias_level,
2560 .idle_bias_off = 1,
2562 .seq_notifier = wm5100_seq_notifier,
2563 .controls = wm5100_snd_controls,
2564 .num_controls = ARRAY_SIZE(wm5100_snd_controls),
2565 .dapm_widgets = wm5100_dapm_widgets,
2566 .num_dapm_widgets = ARRAY_SIZE(wm5100_dapm_widgets),
2567 .dapm_routes = wm5100_dapm_routes,
2568 .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes),
2570 .reg_cache_size = ARRAY_SIZE(wm5100_reg_defaults),
2571 .reg_word_size = sizeof(u16),
2572 .compress_type = SND_SOC_RBTREE_COMPRESSION,
2573 .reg_cache_default = wm5100_reg_defaults,
2575 .volatile_register = wm5100_volatile_register,
2576 .readable_register = wm5100_readable_register,
2579 static __devinit int wm5100_i2c_probe(struct i2c_client *i2c,
2580 const struct i2c_device_id *id)
2582 struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev);
2583 struct wm5100_priv *wm5100;
2584 int ret, i;
2586 wm5100 = kzalloc(sizeof(struct wm5100_priv), GFP_KERNEL);
2587 if (wm5100 == NULL)
2588 return -ENOMEM;
2590 for (i = 0; i < ARRAY_SIZE(wm5100->fll); i++)
2591 init_completion(&wm5100->fll[i].lock);
2593 if (pdata)
2594 wm5100->pdata = *pdata;
2596 i2c_set_clientdata(i2c, wm5100);
2598 ret = snd_soc_register_codec(&i2c->dev,
2599 &soc_codec_dev_wm5100, wm5100_dai,
2600 ARRAY_SIZE(wm5100_dai));
2601 if (ret < 0) {
2602 dev_err(&i2c->dev, "Failed to register WM5100: %d\n", ret);
2603 kfree(wm5100);
2606 return ret;
2609 static __devexit int wm5100_i2c_remove(struct i2c_client *client)
2611 snd_soc_unregister_codec(&client->dev);
2612 kfree(i2c_get_clientdata(client));
2613 return 0;
2616 static const struct i2c_device_id wm5100_i2c_id[] = {
2617 { "wm5100", 0 },
2620 MODULE_DEVICE_TABLE(i2c, wm5100_i2c_id);
2622 static struct i2c_driver wm5100_i2c_driver = {
2623 .driver = {
2624 .name = "wm5100",
2625 .owner = THIS_MODULE,
2627 .probe = wm5100_i2c_probe,
2628 .remove = __devexit_p(wm5100_i2c_remove),
2629 .id_table = wm5100_i2c_id,
2632 static int __init wm5100_modinit(void)
2634 return i2c_add_driver(&wm5100_i2c_driver);
2636 module_init(wm5100_modinit);
2638 static void __exit wm5100_exit(void)
2640 i2c_del_driver(&wm5100_i2c_driver);
2642 module_exit(wm5100_exit);
2644 MODULE_DESCRIPTION("ASoC WM5100 driver");
2645 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2646 MODULE_LICENSE("GPL");