Kernel bump from 4.1.3-rt to 4.1.7-rt.
[kvmfornfv.git] / kernel / sound / soc / codecs / wm8737.c
1 /*
2  * wm8737.c  --  WM8737 ALSA SoC Audio driver
3  *
4  * Copyright 2010 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/i2c.h>
19 #include <linux/regmap.h>
20 #include <linux/regulator/consumer.h>
21 #include <linux/spi/spi.h>
22 #include <linux/slab.h>
23 #include <linux/of_device.h>
24 #include <sound/core.h>
25 #include <sound/pcm.h>
26 #include <sound/pcm_params.h>
27 #include <sound/soc.h>
28 #include <sound/soc-dapm.h>
29 #include <sound/initval.h>
30 #include <sound/tlv.h>
31
32 #include "wm8737.h"
33
34 #define WM8737_NUM_SUPPLIES 4
35 static const char *wm8737_supply_names[WM8737_NUM_SUPPLIES] = {
36         "DCVDD",
37         "DBVDD",
38         "AVDD",
39         "MVDD",
40 };
41
42 /* codec private data */
43 struct wm8737_priv {
44         struct regmap *regmap;
45         struct regulator_bulk_data supplies[WM8737_NUM_SUPPLIES];
46         unsigned int mclk;
47 };
48
49 static const struct reg_default wm8737_reg_defaults[] = {
50         {  0, 0x00C3 },     /* R0  - Left PGA volume */
51         {  1, 0x00C3 },     /* R1  - Right PGA volume */
52         {  2, 0x0007 },     /* R2  - AUDIO path L */
53         {  3, 0x0007 },     /* R3  - AUDIO path R */
54         {  4, 0x0000 },     /* R4  - 3D Enhance */
55         {  5, 0x0000 },     /* R5  - ADC Control */
56         {  6, 0x0000 },     /* R6  - Power Management */
57         {  7, 0x000A },     /* R7  - Audio Format */
58         {  8, 0x0000 },     /* R8  - Clocking */
59         {  9, 0x000F },     /* R9  - MIC Preamp Control */
60         { 10, 0x0003 },     /* R10 - Misc Bias Control */
61         { 11, 0x0000 },     /* R11 - Noise Gate */
62         { 12, 0x007C },     /* R12 - ALC1 */
63         { 13, 0x0000 },     /* R13 - ALC2 */
64         { 14, 0x0032 },     /* R14 - ALC3 */
65 };
66
67 static bool wm8737_volatile(struct device *dev, unsigned int reg)
68 {
69         switch (reg) {
70         case WM8737_RESET:
71                 return true;
72         default:
73                 return false;
74         }
75 }
76
77 static int wm8737_reset(struct snd_soc_codec *codec)
78 {
79         return snd_soc_write(codec, WM8737_RESET, 0);
80 }
81
82 static const unsigned int micboost_tlv[] = {
83         TLV_DB_RANGE_HEAD(4),
84         0, 0, TLV_DB_SCALE_ITEM(1300, 0, 0),
85         1, 1, TLV_DB_SCALE_ITEM(1800, 0, 0),
86         2, 2, TLV_DB_SCALE_ITEM(2800, 0, 0),
87         3, 3, TLV_DB_SCALE_ITEM(3300, 0, 0),
88 };
89 static const DECLARE_TLV_DB_SCALE(pga_tlv, -9750, 50, 1);
90 static const DECLARE_TLV_DB_SCALE(adc_tlv, -600, 600, 0);
91 static const DECLARE_TLV_DB_SCALE(ng_tlv, -7800, 600, 0);
92 static const DECLARE_TLV_DB_SCALE(alc_max_tlv, -1200, 600, 0);
93 static const DECLARE_TLV_DB_SCALE(alc_target_tlv, -1800, 100, 0);
94
95 static const char *micbias_enum_text[] = {
96         "25%",
97         "50%",
98         "75%",
99         "100%",
100 };
101
102 static SOC_ENUM_SINGLE_DECL(micbias_enum,
103                             WM8737_MIC_PREAMP_CONTROL, 0, micbias_enum_text);
104
105 static const char *low_cutoff_text[] = {
106         "Low", "High"
107 };
108
109 static SOC_ENUM_SINGLE_DECL(low_3d,
110                             WM8737_3D_ENHANCE, 6, low_cutoff_text);
111
112 static const char *high_cutoff_text[] = {
113         "High", "Low"
114 };
115
116 static SOC_ENUM_SINGLE_DECL(high_3d,
117                             WM8737_3D_ENHANCE, 5, high_cutoff_text);
118
119 static const char *alc_fn_text[] = {
120         "Disabled", "Right", "Left", "Stereo"
121 };
122
123 static SOC_ENUM_SINGLE_DECL(alc_fn,
124                             WM8737_ALC1, 7, alc_fn_text);
125
126 static const char *alc_hold_text[] = {
127         "0", "2.67ms", "5.33ms", "10.66ms", "21.32ms", "42.64ms", "85.28ms",
128         "170.56ms", "341.12ms", "682.24ms", "1.364s", "2.728s", "5.458s",
129         "10.916s", "21.832s", "43.691s"
130 };
131
132 static SOC_ENUM_SINGLE_DECL(alc_hold,
133                             WM8737_ALC2, 0, alc_hold_text);
134
135 static const char *alc_atk_text[] = {
136         "8.4ms", "16.8ms", "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms",
137         "1.075s", "2.15s", "4.3s", "8.6s"
138 };
139
140 static SOC_ENUM_SINGLE_DECL(alc_atk,
141                             WM8737_ALC3, 0, alc_atk_text);
142
143 static const char *alc_dcy_text[] = {
144         "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms", "1.075s", "2.15s",
145         "4.3s", "8.6s", "17.2s", "34.41s"
146 };
147
148 static SOC_ENUM_SINGLE_DECL(alc_dcy,
149                             WM8737_ALC3, 4, alc_dcy_text);
150
151 static const struct snd_kcontrol_new wm8737_snd_controls[] = {
152 SOC_DOUBLE_R_TLV("Mic Boost Volume", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
153                  6, 3, 0, micboost_tlv),
154 SOC_DOUBLE_R("Mic Boost Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
155              4, 1, 0),
156 SOC_DOUBLE("Mic ZC Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
157            3, 1, 0),
158
159 SOC_DOUBLE_R_TLV("Capture Volume", WM8737_LEFT_PGA_VOLUME,
160                  WM8737_RIGHT_PGA_VOLUME, 0, 255, 0, pga_tlv),
161 SOC_DOUBLE("Capture ZC Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
162            2, 1, 0),
163
164 SOC_DOUBLE("INPUT1 DC Bias Switch", WM8737_MISC_BIAS_CONTROL, 0, 1, 1, 0),
165
166 SOC_ENUM("Mic PGA Bias", micbias_enum),
167 SOC_SINGLE("ADC Low Power Switch", WM8737_ADC_CONTROL, 2, 1, 0),
168 SOC_SINGLE("High Pass Filter Switch", WM8737_ADC_CONTROL, 0, 1, 1),
169 SOC_DOUBLE("Polarity Invert Switch", WM8737_ADC_CONTROL, 5, 6, 1, 0),
170
171 SOC_SINGLE("3D Switch", WM8737_3D_ENHANCE, 0, 1, 0),
172 SOC_SINGLE("3D Depth", WM8737_3D_ENHANCE, 1, 15, 0),
173 SOC_ENUM("3D Low Cut-off", low_3d),
174 SOC_ENUM("3D High Cut-off", low_3d),
175 SOC_SINGLE_TLV("3D ADC Volume", WM8737_3D_ENHANCE, 7, 1, 1, adc_tlv),
176
177 SOC_SINGLE("Noise Gate Switch", WM8737_NOISE_GATE, 0, 1, 0),
178 SOC_SINGLE_TLV("Noise Gate Threshold Volume", WM8737_NOISE_GATE, 2, 7, 0,
179                ng_tlv),
180
181 SOC_ENUM("ALC", alc_fn),
182 SOC_SINGLE_TLV("ALC Max Gain Volume", WM8737_ALC1, 4, 7, 0, alc_max_tlv),
183 SOC_SINGLE_TLV("ALC Target Volume", WM8737_ALC1, 0, 15, 0, alc_target_tlv),
184 SOC_ENUM("ALC Hold Time", alc_hold),
185 SOC_SINGLE("ALC ZC Switch", WM8737_ALC2, 4, 1, 0),
186 SOC_ENUM("ALC Attack Time", alc_atk),
187 SOC_ENUM("ALC Decay Time", alc_dcy),
188 };
189
190 static const char *linsel_text[] = {
191         "LINPUT1", "LINPUT2", "LINPUT3", "LINPUT1 DC",
192 };
193
194 static SOC_ENUM_SINGLE_DECL(linsel_enum,
195                             WM8737_AUDIO_PATH_L, 7, linsel_text);
196
197 static const struct snd_kcontrol_new linsel_mux =
198         SOC_DAPM_ENUM("LINSEL", linsel_enum);
199
200
201 static const char *rinsel_text[] = {
202         "RINPUT1", "RINPUT2", "RINPUT3", "RINPUT1 DC",
203 };
204
205 static SOC_ENUM_SINGLE_DECL(rinsel_enum,
206                             WM8737_AUDIO_PATH_R, 7, rinsel_text);
207
208 static const struct snd_kcontrol_new rinsel_mux =
209         SOC_DAPM_ENUM("RINSEL", rinsel_enum);
210
211 static const char *bypass_text[] = {
212         "Direct", "Preamp"
213 };
214
215 static SOC_ENUM_SINGLE_DECL(lbypass_enum,
216                             WM8737_MIC_PREAMP_CONTROL, 2, bypass_text);
217
218 static const struct snd_kcontrol_new lbypass_mux =
219         SOC_DAPM_ENUM("Left Bypass", lbypass_enum);
220
221
222 static SOC_ENUM_SINGLE_DECL(rbypass_enum,
223                             WM8737_MIC_PREAMP_CONTROL, 3, bypass_text);
224
225 static const struct snd_kcontrol_new rbypass_mux =
226         SOC_DAPM_ENUM("Left Bypass", rbypass_enum);
227
228 static const struct snd_soc_dapm_widget wm8737_dapm_widgets[] = {
229 SND_SOC_DAPM_INPUT("LINPUT1"),
230 SND_SOC_DAPM_INPUT("LINPUT2"),
231 SND_SOC_DAPM_INPUT("LINPUT3"),
232 SND_SOC_DAPM_INPUT("RINPUT1"),
233 SND_SOC_DAPM_INPUT("RINPUT2"),
234 SND_SOC_DAPM_INPUT("RINPUT3"),
235 SND_SOC_DAPM_INPUT("LACIN"),
236 SND_SOC_DAPM_INPUT("RACIN"),
237
238 SND_SOC_DAPM_MUX("LINSEL", SND_SOC_NOPM, 0, 0, &linsel_mux),
239 SND_SOC_DAPM_MUX("RINSEL", SND_SOC_NOPM, 0, 0, &rinsel_mux),
240
241 SND_SOC_DAPM_MUX("Left Preamp Mux", SND_SOC_NOPM, 0, 0, &lbypass_mux),
242 SND_SOC_DAPM_MUX("Right Preamp Mux", SND_SOC_NOPM, 0, 0, &rbypass_mux),
243
244 SND_SOC_DAPM_PGA("PGAL", WM8737_POWER_MANAGEMENT, 5, 0, NULL, 0),
245 SND_SOC_DAPM_PGA("PGAR", WM8737_POWER_MANAGEMENT, 4, 0, NULL, 0),
246
247 SND_SOC_DAPM_DAC("ADCL", NULL, WM8737_POWER_MANAGEMENT, 3, 0),
248 SND_SOC_DAPM_DAC("ADCR", NULL, WM8737_POWER_MANAGEMENT, 2, 0),
249
250 SND_SOC_DAPM_AIF_OUT("AIF", "Capture", 0, WM8737_POWER_MANAGEMENT, 6, 0),
251 };
252
253 static const struct snd_soc_dapm_route intercon[] = {
254         { "LINSEL", "LINPUT1", "LINPUT1" },
255         { "LINSEL", "LINPUT2", "LINPUT2" },
256         { "LINSEL", "LINPUT3", "LINPUT3" },
257         { "LINSEL", "LINPUT1 DC", "LINPUT1" },
258
259         { "RINSEL", "RINPUT1", "RINPUT1" },
260         { "RINSEL", "RINPUT2", "RINPUT2" },
261         { "RINSEL", "RINPUT3", "RINPUT3" },
262         { "RINSEL", "RINPUT1 DC", "RINPUT1" },
263
264         { "Left Preamp Mux", "Preamp", "LINSEL" },
265         { "Left Preamp Mux", "Direct", "LACIN" },
266
267         { "Right Preamp Mux", "Preamp", "RINSEL" },
268         { "Right Preamp Mux", "Direct", "RACIN" },
269
270         { "PGAL", NULL, "Left Preamp Mux" },
271         { "PGAR", NULL, "Right Preamp Mux" },
272
273         { "ADCL", NULL, "PGAL" },
274         { "ADCR", NULL, "PGAR" },
275
276         { "AIF", NULL, "ADCL" },
277         { "AIF", NULL, "ADCR" },
278 };
279
280 /* codec mclk clock divider coefficients */
281 static const struct {
282         u32 mclk;
283         u32 rate;
284         u8 usb;
285         u8 sr;
286 } coeff_div[] = {
287         { 12288000,  8000, 0,  0x4 },
288         { 12288000, 12000, 0,  0x8 },
289         { 12288000, 16000, 0,  0xa },
290         { 12288000, 24000, 0, 0x1c },
291         { 12288000, 32000, 0,  0xc },
292         { 12288000, 48000, 0,    0 },
293         { 12288000, 96000, 0,  0xe },
294
295         { 11289600,  8000, 0, 0x14 },
296         { 11289600, 11025, 0, 0x18 },
297         { 11289600, 22050, 0, 0x1a },
298         { 11289600, 44100, 0, 0x10 },
299         { 11289600, 88200, 0, 0x1e },
300
301         { 18432000,  8000, 0,  0x5 },
302         { 18432000, 12000, 0,  0x9 },
303         { 18432000, 16000, 0,  0xb },
304         { 18432000, 24000, 0, 0x1b },
305         { 18432000, 32000, 0,  0xd },
306         { 18432000, 48000, 0,  0x1 },
307         { 18432000, 96000, 0, 0x1f },
308
309         { 16934400,  8000, 0, 0x15 },
310         { 16934400, 11025, 0, 0x19 },
311         { 16934400, 22050, 0, 0x1b },
312         { 16934400, 44100, 0, 0x11 },
313         { 16934400, 88200, 0, 0x1f },
314
315         { 12000000,  8000, 1,  0x4 },
316         { 12000000, 11025, 1, 0x19 },
317         { 12000000, 12000, 1,  0x8 },
318         { 12000000, 16000, 1,  0xa },
319         { 12000000, 22050, 1, 0x1b },
320         { 12000000, 24000, 1, 0x1c },
321         { 12000000, 32000, 1,  0xc },
322         { 12000000, 44100, 1, 0x11 },
323         { 12000000, 48000, 1,  0x0 },
324         { 12000000, 88200, 1, 0x1f },
325         { 12000000, 96000, 1,  0xe },
326 };
327
328 static int wm8737_hw_params(struct snd_pcm_substream *substream,
329                             struct snd_pcm_hw_params *params,
330                             struct snd_soc_dai *dai)
331 {
332         struct snd_soc_codec *codec = dai->codec;
333         struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
334         int i;
335         u16 clocking = 0;
336         u16 af = 0;
337
338         for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
339                 if (coeff_div[i].rate != params_rate(params))
340                         continue;
341
342                 if (coeff_div[i].mclk == wm8737->mclk)
343                         break;
344
345                 if (coeff_div[i].mclk == wm8737->mclk * 2) {
346                         clocking |= WM8737_CLKDIV2;
347                         break;
348                 }
349         }
350
351         if (i == ARRAY_SIZE(coeff_div)) {
352                 dev_err(codec->dev, "%dHz MCLK can't support %dHz\n",
353                         wm8737->mclk, params_rate(params));
354                 return -EINVAL;
355         }
356
357         clocking |= coeff_div[i].usb | (coeff_div[i].sr << WM8737_SR_SHIFT);
358
359         switch (params_width(params)) {
360         case 16:
361                 break;
362         case 20:
363                 af |= 0x8;
364                 break;
365         case 24:
366                 af |= 0x10;
367                 break;
368         case 32:
369                 af |= 0x18;
370                 break;
371         default:
372                 return -EINVAL;
373         }
374
375         snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT, WM8737_WL_MASK, af);
376         snd_soc_update_bits(codec, WM8737_CLOCKING,
377                             WM8737_USB_MODE | WM8737_CLKDIV2 | WM8737_SR_MASK,
378                             clocking);
379
380         return 0;
381 }
382
383 static int wm8737_set_dai_sysclk(struct snd_soc_dai *codec_dai,
384                                  int clk_id, unsigned int freq, int dir)
385 {
386         struct snd_soc_codec *codec = codec_dai->codec;
387         struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
388         int i;
389
390         for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
391                 if (freq == coeff_div[i].mclk ||
392                     freq == coeff_div[i].mclk * 2) {
393                         wm8737->mclk = freq;
394                         return 0;
395                 }
396         }
397
398         dev_err(codec->dev, "MCLK rate %dHz not supported\n", freq);
399
400         return -EINVAL;
401 }
402
403
404 static int wm8737_set_dai_fmt(struct snd_soc_dai *codec_dai,
405                 unsigned int fmt)
406 {
407         struct snd_soc_codec *codec = codec_dai->codec;
408         u16 af = 0;
409
410         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
411         case SND_SOC_DAIFMT_CBM_CFM:
412                 af |= WM8737_MS;
413                 break;
414         case SND_SOC_DAIFMT_CBS_CFS:
415                 break;
416         default:
417                 return -EINVAL;
418         }
419
420         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
421         case SND_SOC_DAIFMT_I2S:
422                 af |= 0x2;
423                 break;
424         case SND_SOC_DAIFMT_RIGHT_J:
425                 break;
426         case SND_SOC_DAIFMT_LEFT_J:
427                 af |= 0x1;
428                 break;
429         case SND_SOC_DAIFMT_DSP_A:
430                 af |= 0x3;
431                 break;
432         case SND_SOC_DAIFMT_DSP_B:
433                 af |= 0x13;
434                 break;
435         default:
436                 return -EINVAL;
437         }
438
439         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
440         case SND_SOC_DAIFMT_NB_NF:
441                 break;
442         case SND_SOC_DAIFMT_NB_IF:
443                 af |= WM8737_LRP;
444                 break;
445         default:
446                 return -EINVAL;
447         }
448
449         snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT,
450                             WM8737_FORMAT_MASK | WM8737_LRP | WM8737_MS, af);
451
452         return 0;
453 }
454
455 static int wm8737_set_bias_level(struct snd_soc_codec *codec,
456                                  enum snd_soc_bias_level level)
457 {
458         struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
459         int ret;
460
461         switch (level) {
462         case SND_SOC_BIAS_ON:
463                 break;
464
465         case SND_SOC_BIAS_PREPARE:
466                 /* VMID at 2*75k */
467                 snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
468                                     WM8737_VMIDSEL_MASK, 0);
469                 break;
470
471         case SND_SOC_BIAS_STANDBY:
472                 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
473                         ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
474                                                     wm8737->supplies);
475                         if (ret != 0) {
476                                 dev_err(codec->dev,
477                                         "Failed to enable supplies: %d\n",
478                                         ret);
479                                 return ret;
480                         }
481
482                         regcache_sync(wm8737->regmap);
483
484                         /* Fast VMID ramp at 2*2.5k */
485                         snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
486                                             WM8737_VMIDSEL_MASK,
487                                             2 << WM8737_VMIDSEL_SHIFT);
488
489                         /* Bring VMID up */
490                         snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT,
491                                             WM8737_VMID_MASK |
492                                             WM8737_VREF_MASK,
493                                             WM8737_VMID_MASK |
494                                             WM8737_VREF_MASK);
495
496                         msleep(500);
497                 }
498
499                 /* VMID at 2*300k */
500                 snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
501                                     WM8737_VMIDSEL_MASK,
502                                     1 << WM8737_VMIDSEL_SHIFT);
503
504                 break;
505
506         case SND_SOC_BIAS_OFF:
507                 snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT,
508                                     WM8737_VMID_MASK | WM8737_VREF_MASK, 0);
509
510                 regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies),
511                                        wm8737->supplies);
512                 break;
513         }
514
515         codec->dapm.bias_level = level;
516         return 0;
517 }
518
519 #define WM8737_RATES SNDRV_PCM_RATE_8000_96000
520
521 #define WM8737_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
522                         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
523
524 static const struct snd_soc_dai_ops wm8737_dai_ops = {
525         .hw_params      = wm8737_hw_params,
526         .set_sysclk     = wm8737_set_dai_sysclk,
527         .set_fmt        = wm8737_set_dai_fmt,
528 };
529
530 static struct snd_soc_dai_driver wm8737_dai = {
531         .name = "wm8737",
532         .capture = {
533                 .stream_name = "Capture",
534                 .channels_min = 2,  /* Mono modes not yet supported */
535                 .channels_max = 2,
536                 .rates = WM8737_RATES,
537                 .formats = WM8737_FORMATS,
538         },
539         .ops = &wm8737_dai_ops,
540 };
541
542 static int wm8737_probe(struct snd_soc_codec *codec)
543 {
544         struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
545         int ret;
546
547         ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
548                                     wm8737->supplies);
549         if (ret != 0) {
550                 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
551                 goto err_get;
552         }
553
554         ret = wm8737_reset(codec);
555         if (ret < 0) {
556                 dev_err(codec->dev, "Failed to issue reset\n");
557                 goto err_enable;
558         }
559
560         snd_soc_update_bits(codec, WM8737_LEFT_PGA_VOLUME, WM8737_LVU,
561                             WM8737_LVU);
562         snd_soc_update_bits(codec, WM8737_RIGHT_PGA_VOLUME, WM8737_RVU,
563                             WM8737_RVU);
564
565         wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
566
567         /* Bias level configuration will have done an extra enable */
568         regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
569
570         return 0;
571
572 err_enable:
573         regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
574 err_get:
575         return ret;
576 }
577
578 static struct snd_soc_codec_driver soc_codec_dev_wm8737 = {
579         .probe          = wm8737_probe,
580         .set_bias_level = wm8737_set_bias_level,
581         .suspend_bias_off = true,
582
583         .controls = wm8737_snd_controls,
584         .num_controls = ARRAY_SIZE(wm8737_snd_controls),
585         .dapm_widgets = wm8737_dapm_widgets,
586         .num_dapm_widgets = ARRAY_SIZE(wm8737_dapm_widgets),
587         .dapm_routes = intercon,
588         .num_dapm_routes = ARRAY_SIZE(intercon),
589 };
590
591 static const struct of_device_id wm8737_of_match[] = {
592         { .compatible = "wlf,wm8737", },
593         { }
594 };
595
596 MODULE_DEVICE_TABLE(of, wm8737_of_match);
597
598 static const struct regmap_config wm8737_regmap = {
599         .reg_bits = 7,
600         .val_bits = 9,
601         .max_register = WM8737_MAX_REGISTER,
602
603         .reg_defaults = wm8737_reg_defaults,
604         .num_reg_defaults = ARRAY_SIZE(wm8737_reg_defaults),
605         .cache_type = REGCACHE_RBTREE,
606
607         .volatile_reg = wm8737_volatile,
608 };
609
610 #if IS_ENABLED(CONFIG_I2C)
611 static int wm8737_i2c_probe(struct i2c_client *i2c,
612                             const struct i2c_device_id *id)
613 {
614         struct wm8737_priv *wm8737;
615         int ret, i;
616
617         wm8737 = devm_kzalloc(&i2c->dev, sizeof(struct wm8737_priv),
618                               GFP_KERNEL);
619         if (wm8737 == NULL)
620                 return -ENOMEM;
621
622         for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++)
623                 wm8737->supplies[i].supply = wm8737_supply_names[i];
624
625         ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8737->supplies),
626                                       wm8737->supplies);
627         if (ret != 0) {
628                 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
629                 return ret;
630         }
631
632         wm8737->regmap = devm_regmap_init_i2c(i2c, &wm8737_regmap);
633         if (IS_ERR(wm8737->regmap))
634                 return PTR_ERR(wm8737->regmap);
635
636         i2c_set_clientdata(i2c, wm8737);
637
638         ret =  snd_soc_register_codec(&i2c->dev,
639                                       &soc_codec_dev_wm8737, &wm8737_dai, 1);
640
641         return ret;
642
643 }
644
645 static int wm8737_i2c_remove(struct i2c_client *client)
646 {
647         snd_soc_unregister_codec(&client->dev);
648
649         return 0;
650 }
651
652 static const struct i2c_device_id wm8737_i2c_id[] = {
653         { "wm8737", 0 },
654         { }
655 };
656 MODULE_DEVICE_TABLE(i2c, wm8737_i2c_id);
657
658 static struct i2c_driver wm8737_i2c_driver = {
659         .driver = {
660                 .name = "wm8737",
661                 .owner = THIS_MODULE,
662                 .of_match_table = wm8737_of_match,
663         },
664         .probe =    wm8737_i2c_probe,
665         .remove =   wm8737_i2c_remove,
666         .id_table = wm8737_i2c_id,
667 };
668 #endif
669
670 #if defined(CONFIG_SPI_MASTER)
671 static int wm8737_spi_probe(struct spi_device *spi)
672 {
673         struct wm8737_priv *wm8737;
674         int ret, i;
675
676         wm8737 = devm_kzalloc(&spi->dev, sizeof(struct wm8737_priv),
677                               GFP_KERNEL);
678         if (wm8737 == NULL)
679                 return -ENOMEM;
680
681         for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++)
682                 wm8737->supplies[i].supply = wm8737_supply_names[i];
683
684         ret = devm_regulator_bulk_get(&spi->dev, ARRAY_SIZE(wm8737->supplies),
685                                       wm8737->supplies);
686         if (ret != 0) {
687                 dev_err(&spi->dev, "Failed to request supplies: %d\n", ret);
688                 return ret;
689         }
690
691         wm8737->regmap = devm_regmap_init_spi(spi, &wm8737_regmap);
692         if (IS_ERR(wm8737->regmap))
693                 return PTR_ERR(wm8737->regmap);
694
695         spi_set_drvdata(spi, wm8737);
696
697         ret = snd_soc_register_codec(&spi->dev,
698                                      &soc_codec_dev_wm8737, &wm8737_dai, 1);
699
700         return ret;
701 }
702
703 static int wm8737_spi_remove(struct spi_device *spi)
704 {
705         snd_soc_unregister_codec(&spi->dev);
706
707         return 0;
708 }
709
710 static struct spi_driver wm8737_spi_driver = {
711         .driver = {
712                 .name   = "wm8737",
713                 .owner  = THIS_MODULE,
714                 .of_match_table = wm8737_of_match,
715         },
716         .probe          = wm8737_spi_probe,
717         .remove         = wm8737_spi_remove,
718 };
719 #endif /* CONFIG_SPI_MASTER */
720
721 static int __init wm8737_modinit(void)
722 {
723         int ret;
724 #if IS_ENABLED(CONFIG_I2C)
725         ret = i2c_add_driver(&wm8737_i2c_driver);
726         if (ret != 0) {
727                 printk(KERN_ERR "Failed to register WM8737 I2C driver: %d\n",
728                        ret);
729         }
730 #endif
731 #if defined(CONFIG_SPI_MASTER)
732         ret = spi_register_driver(&wm8737_spi_driver);
733         if (ret != 0) {
734                 printk(KERN_ERR "Failed to register WM8737 SPI driver: %d\n",
735                        ret);
736         }
737 #endif
738         return 0;
739 }
740 module_init(wm8737_modinit);
741
742 static void __exit wm8737_exit(void)
743 {
744 #if defined(CONFIG_SPI_MASTER)
745         spi_unregister_driver(&wm8737_spi_driver);
746 #endif
747 #if IS_ENABLED(CONFIG_I2C)
748         i2c_del_driver(&wm8737_i2c_driver);
749 #endif
750 }
751 module_exit(wm8737_exit);
752
753 MODULE_DESCRIPTION("ASoC WM8737 driver");
754 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
755 MODULE_LICENSE("GPL");