Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
wm8737.c
Go to the documentation of this file.
1 /*
2  * wm8737.c -- WM8737 ALSA SoC Audio driver
3  *
4  * Copyright 2010 Wolfson Microelectronics plc
5  *
6  * Author: Mark Brown <[email protected]>
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>
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;
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[] = {
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 const struct soc_enum micbias_enum =
103  SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 0, 4, micbias_enum_text);
104 
105 static const char *low_cutoff_text[] = {
106  "Low", "High"
107 };
108 
109 static const struct soc_enum low_3d =
110  SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 6, 2, low_cutoff_text);
111 
112 static const char *high_cutoff_text[] = {
113  "High", "Low"
114 };
115 
116 static const struct soc_enum high_3d =
117  SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 5, 2, high_cutoff_text);
118 
119 static const char *alc_fn_text[] = {
120  "Disabled", "Right", "Left", "Stereo"
121 };
122 
123 static const struct soc_enum alc_fn =
124  SOC_ENUM_SINGLE(WM8737_ALC1, 7, 4, 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 const struct soc_enum alc_hold =
133  SOC_ENUM_SINGLE(WM8737_ALC2, 0, 16, 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 const struct soc_enum alc_atk =
141  SOC_ENUM_SINGLE(WM8737_ALC3, 0, 11, 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 const struct soc_enum alc_dcy =
149  SOC_ENUM_SINGLE(WM8737_ALC3, 4, 11, alc_dcy_text);
150 
151 static const struct snd_kcontrol_new wm8737_snd_controls[] = {
153  6, 3, 0, micboost_tlv),
155  4, 1, 0),
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),
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 const struct soc_enum linsel_enum =
195  SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_L, 7, 4, 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 const struct soc_enum rinsel_enum =
206  SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_R, 7, 4, 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 const struct soc_enum lbypass_enum =
216  SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 2, 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 const struct soc_enum rbypass_enum =
223  SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 3, 2, 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 
246 
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 static int wm8737_add_widgets(struct snd_soc_codec *codec)
281 {
282  struct snd_soc_dapm_context *dapm = &codec->dapm;
283 
284  snd_soc_dapm_new_controls(dapm, wm8737_dapm_widgets,
285  ARRAY_SIZE(wm8737_dapm_widgets));
286  snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
287 
288  return 0;
289 }
290 
291 /* codec mclk clock divider coefficients */
292 static const struct {
297 } coeff_div[] = {
298  { 12288000, 8000, 0, 0x4 },
299  { 12288000, 12000, 0, 0x8 },
300  { 12288000, 16000, 0, 0xa },
301  { 12288000, 24000, 0, 0x1c },
302  { 12288000, 32000, 0, 0xc },
303  { 12288000, 48000, 0, 0 },
304  { 12288000, 96000, 0, 0xe },
305 
306  { 11289600, 8000, 0, 0x14 },
307  { 11289600, 11025, 0, 0x18 },
308  { 11289600, 22050, 0, 0x1a },
309  { 11289600, 44100, 0, 0x10 },
310  { 11289600, 88200, 0, 0x1e },
311 
312  { 18432000, 8000, 0, 0x5 },
313  { 18432000, 12000, 0, 0x9 },
314  { 18432000, 16000, 0, 0xb },
315  { 18432000, 24000, 0, 0x1b },
316  { 18432000, 32000, 0, 0xd },
317  { 18432000, 48000, 0, 0x1 },
318  { 18432000, 96000, 0, 0x1f },
319 
320  { 16934400, 8000, 0, 0x15 },
321  { 16934400, 11025, 0, 0x19 },
322  { 16934400, 22050, 0, 0x1b },
323  { 16934400, 44100, 0, 0x11 },
324  { 16934400, 88200, 0, 0x1f },
325 
326  { 12000000, 8000, 1, 0x4 },
327  { 12000000, 11025, 1, 0x19 },
328  { 12000000, 12000, 1, 0x8 },
329  { 12000000, 16000, 1, 0xa },
330  { 12000000, 22050, 1, 0x1b },
331  { 12000000, 24000, 1, 0x1c },
332  { 12000000, 32000, 1, 0xc },
333  { 12000000, 44100, 1, 0x11 },
334  { 12000000, 48000, 1, 0x0 },
335  { 12000000, 88200, 1, 0x1f },
336  { 12000000, 96000, 1, 0xe },
337 };
338 
339 static int wm8737_hw_params(struct snd_pcm_substream *substream,
340  struct snd_pcm_hw_params *params,
341  struct snd_soc_dai *dai)
342 {
343  struct snd_soc_codec *codec = dai->codec;
344  struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
345  int i;
346  u16 clocking = 0;
347  u16 af = 0;
348 
349  for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
350  if (coeff_div[i].rate != params_rate(params))
351  continue;
352 
353  if (coeff_div[i].mclk == wm8737->mclk)
354  break;
355 
356  if (coeff_div[i].mclk == wm8737->mclk * 2) {
357  clocking |= WM8737_CLKDIV2;
358  break;
359  }
360  }
361 
362  if (i == ARRAY_SIZE(coeff_div)) {
363  dev_err(codec->dev, "%dHz MCLK can't support %dHz\n",
364  wm8737->mclk, params_rate(params));
365  return -EINVAL;
366  }
367 
368  clocking |= coeff_div[i].usb | (coeff_div[i].sr << WM8737_SR_SHIFT);
369 
370  switch (params_format(params)) {
372  break;
374  af |= 0x8;
375  break;
377  af |= 0x10;
378  break;
380  af |= 0x18;
381  break;
382  default:
383  return -EINVAL;
384  }
385 
389  clocking);
390 
391  return 0;
392 }
393 
394 static int wm8737_set_dai_sysclk(struct snd_soc_dai *codec_dai,
395  int clk_id, unsigned int freq, int dir)
396 {
397  struct snd_soc_codec *codec = codec_dai->codec;
398  struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
399  int i;
400 
401  for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
402  if (freq == coeff_div[i].mclk ||
403  freq == coeff_div[i].mclk * 2) {
404  wm8737->mclk = freq;
405  return 0;
406  }
407  }
408 
409  dev_err(codec->dev, "MCLK rate %dHz not supported\n", freq);
410 
411  return -EINVAL;
412 }
413 
414 
415 static int wm8737_set_dai_fmt(struct snd_soc_dai *codec_dai,
416  unsigned int fmt)
417 {
418  struct snd_soc_codec *codec = codec_dai->codec;
419  u16 af = 0;
420 
421  switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
423  af |= WM8737_MS;
424  break;
426  break;
427  default:
428  return -EINVAL;
429  }
430 
431  switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
432  case SND_SOC_DAIFMT_I2S:
433  af |= 0x2;
434  break;
436  break;
438  af |= 0x1;
439  break;
441  af |= 0x3;
442  break;
444  af |= 0x13;
445  break;
446  default:
447  return -EINVAL;
448  }
449 
450  switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
452  break;
454  af |= WM8737_LRP;
455  break;
456  default:
457  return -EINVAL;
458  }
459 
462 
463  return 0;
464 }
465 
466 static int wm8737_set_bias_level(struct snd_soc_codec *codec,
468 {
469  struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
470  int ret;
471 
472  switch (level) {
473  case SND_SOC_BIAS_ON:
474  break;
475 
477  /* VMID at 2*75k */
480  break;
481 
483  if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
485  wm8737->supplies);
486  if (ret != 0) {
487  dev_err(codec->dev,
488  "Failed to enable supplies: %d\n",
489  ret);
490  return ret;
491  }
492 
493  regcache_sync(wm8737->regmap);
494 
495  /* Fast VMID ramp at 2*2.5k */
497  WM8737_VMIDSEL_MASK, 0x4);
498 
499  /* Bring VMID up */
505 
506  msleep(500);
507  }
508 
509  /* VMID at 2*300k */
512 
513  break;
514 
515  case SND_SOC_BIAS_OFF:
518 
520  wm8737->supplies);
521  break;
522  }
523 
524  codec->dapm.bias_level = level;
525  return 0;
526 }
527 
528 #define WM8737_RATES SNDRV_PCM_RATE_8000_96000
529 
530 #define WM8737_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
531  SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
532 
533 static const struct snd_soc_dai_ops wm8737_dai_ops = {
534  .hw_params = wm8737_hw_params,
535  .set_sysclk = wm8737_set_dai_sysclk,
536  .set_fmt = wm8737_set_dai_fmt,
537 };
538 
539 static struct snd_soc_dai_driver wm8737_dai = {
540  .name = "wm8737",
541  .capture = {
542  .stream_name = "Capture",
543  .channels_min = 2, /* Mono modes not yet supported */
544  .channels_max = 2,
545  .rates = WM8737_RATES,
546  .formats = WM8737_FORMATS,
547  },
548  .ops = &wm8737_dai_ops,
549 };
550 
551 #ifdef CONFIG_PM
552 static int wm8737_suspend(struct snd_soc_codec *codec)
553 {
554  wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF);
555  return 0;
556 }
557 
558 static int wm8737_resume(struct snd_soc_codec *codec)
559 {
560  wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
561  return 0;
562 }
563 #else
564 #define wm8737_suspend NULL
565 #define wm8737_resume NULL
566 #endif
567 
568 static int wm8737_probe(struct snd_soc_codec *codec)
569 {
570  struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
571  int ret;
572 
573  ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_REGMAP);
574  if (ret != 0) {
575  dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
576  return ret;
577  }
578 
580  wm8737->supplies);
581  if (ret != 0) {
582  dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
583  goto err_get;
584  }
585 
586  ret = wm8737_reset(codec);
587  if (ret < 0) {
588  dev_err(codec->dev, "Failed to issue reset\n");
589  goto err_enable;
590  }
591 
593  WM8737_LVU);
595  WM8737_RVU);
596 
597  wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
598 
599  /* Bias level configuration will have done an extra enable */
601 
602  snd_soc_add_codec_controls(codec, wm8737_snd_controls,
603  ARRAY_SIZE(wm8737_snd_controls));
604  wm8737_add_widgets(codec);
605 
606  return 0;
607 
608 err_enable:
610 err_get:
611  return ret;
612 }
613 
614 static int wm8737_remove(struct snd_soc_codec *codec)
615 {
616  wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF);
617  return 0;
618 }
619 
620 static struct snd_soc_codec_driver soc_codec_dev_wm8737 = {
621  .probe = wm8737_probe,
622  .remove = wm8737_remove,
623  .suspend = wm8737_suspend,
624  .resume = wm8737_resume,
625  .set_bias_level = wm8737_set_bias_level,
626 };
627 
628 static const struct of_device_id wm8737_of_match[] = {
629  { .compatible = "wlf,wm8737", },
630  { }
631 };
632 
633 MODULE_DEVICE_TABLE(of, wm8737_of_match);
634 
635 static const struct regmap_config wm8737_regmap = {
636  .reg_bits = 7,
637  .val_bits = 9,
638  .max_register = WM8737_MAX_REGISTER,
639 
640  .reg_defaults = wm8737_reg_defaults,
641  .num_reg_defaults = ARRAY_SIZE(wm8737_reg_defaults),
642  .cache_type = REGCACHE_RBTREE,
643 
644  .volatile_reg = wm8737_volatile,
645 };
646 
647 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
648 static __devinit int wm8737_i2c_probe(struct i2c_client *i2c,
649  const struct i2c_device_id *id)
650 {
651  struct wm8737_priv *wm8737;
652  int ret, i;
653 
654  wm8737 = devm_kzalloc(&i2c->dev, sizeof(struct wm8737_priv),
655  GFP_KERNEL);
656  if (wm8737 == NULL)
657  return -ENOMEM;
658 
659  for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++)
660  wm8737->supplies[i].supply = wm8737_supply_names[i];
661 
662  ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8737->supplies),
663  wm8737->supplies);
664  if (ret != 0) {
665  dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
666  return ret;
667  }
668 
669  wm8737->regmap = devm_regmap_init_i2c(i2c, &wm8737_regmap);
670  if (IS_ERR(wm8737->regmap))
671  return PTR_ERR(wm8737->regmap);
672 
673  i2c_set_clientdata(i2c, wm8737);
674 
675  ret = snd_soc_register_codec(&i2c->dev,
676  &soc_codec_dev_wm8737, &wm8737_dai, 1);
677 
678  return ret;
679 
680 }
681 
682 static __devexit int wm8737_i2c_remove(struct i2c_client *client)
683 {
684  snd_soc_unregister_codec(&client->dev);
685 
686  return 0;
687 }
688 
689 static const struct i2c_device_id wm8737_i2c_id[] = {
690  { "wm8737", 0 },
691  { }
692 };
693 MODULE_DEVICE_TABLE(i2c, wm8737_i2c_id);
694 
695 static struct i2c_driver wm8737_i2c_driver = {
696  .driver = {
697  .name = "wm8737",
698  .owner = THIS_MODULE,
699  .of_match_table = wm8737_of_match,
700  },
701  .probe = wm8737_i2c_probe,
702  .remove = __devexit_p(wm8737_i2c_remove),
703  .id_table = wm8737_i2c_id,
704 };
705 #endif
706 
707 #if defined(CONFIG_SPI_MASTER)
708 static int __devinit wm8737_spi_probe(struct spi_device *spi)
709 {
710  struct wm8737_priv *wm8737;
711  int ret, i;
712 
713  wm8737 = devm_kzalloc(&spi->dev, sizeof(struct wm8737_priv),
714  GFP_KERNEL);
715  if (wm8737 == NULL)
716  return -ENOMEM;
717 
718  for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++)
719  wm8737->supplies[i].supply = wm8737_supply_names[i];
720 
721  ret = devm_regulator_bulk_get(&spi->dev, ARRAY_SIZE(wm8737->supplies),
722  wm8737->supplies);
723  if (ret != 0) {
724  dev_err(&spi->dev, "Failed to request supplies: %d\n", ret);
725  return ret;
726  }
727 
728  wm8737->regmap = devm_regmap_init_spi(spi, &wm8737_regmap);
729  if (IS_ERR(wm8737->regmap))
730  return PTR_ERR(wm8737->regmap);
731 
732  spi_set_drvdata(spi, wm8737);
733 
734  ret = snd_soc_register_codec(&spi->dev,
735  &soc_codec_dev_wm8737, &wm8737_dai, 1);
736 
737  return ret;
738 }
739 
740 static int __devexit wm8737_spi_remove(struct spi_device *spi)
741 {
743 
744  return 0;
745 }
746 
747 static struct spi_driver wm8737_spi_driver = {
748  .driver = {
749  .name = "wm8737",
750  .owner = THIS_MODULE,
751  .of_match_table = wm8737_of_match,
752  },
753  .probe = wm8737_spi_probe,
754  .remove = __devexit_p(wm8737_spi_remove),
755 };
756 #endif /* CONFIG_SPI_MASTER */
757 
758 static int __init wm8737_modinit(void)
759 {
760  int ret;
761 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
762  ret = i2c_add_driver(&wm8737_i2c_driver);
763  if (ret != 0) {
764  printk(KERN_ERR "Failed to register WM8737 I2C driver: %d\n",
765  ret);
766  }
767 #endif
768 #if defined(CONFIG_SPI_MASTER)
769  ret = spi_register_driver(&wm8737_spi_driver);
770  if (ret != 0) {
771  printk(KERN_ERR "Failed to register WM8737 SPI driver: %d\n",
772  ret);
773  }
774 #endif
775  return 0;
776 }
777 module_init(wm8737_modinit);
778 
779 static void __exit wm8737_exit(void)
780 {
781 #if defined(CONFIG_SPI_MASTER)
782  spi_unregister_driver(&wm8737_spi_driver);
783 #endif
784 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
785  i2c_del_driver(&wm8737_i2c_driver);
786 #endif
787 }
788 module_exit(wm8737_exit);
789 
790 MODULE_DESCRIPTION("ASoC WM8737 driver");
791 MODULE_AUTHOR("Mark Brown <[email protected]>");
792 MODULE_LICENSE("GPL");