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