2 * imx32ads-wm8350.c -- i.MX31ADS Driver for Wolfson WM8350 Codec
4 * Copyright 2007 Wolfson Microelectronics PLC.
6 * Author: Liam Girdwood
7 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
15 * 19th Jun 2007 Initial version.
19 #include <linux/module.h>
20 #include <linux/moduleparam.h>
21 #include <linux/init.h>
22 #include <linux/delay.h>
24 #include <linux/bitops.h>
25 #include <linux/platform_device.h>
26 #include <linux/i2c.h>
27 #include <linux/err.h>
28 #include <linux/regulator/regulator.h>
29 #include <linux/regulator/wm8350/audio.h>
30 #include <linux/regulator/wm8350/bus.h>
31 #include <sound/driver.h>
32 #include <sound/core.h>
33 #include <sound/pcm.h>
34 #include <sound/pcm_params.h>
35 #include <sound/soc.h>
36 #include <sound/soc-dapm.h>
37 #include <sound/initval.h>
39 #include <asm/arch/dma.h>
40 #include <asm/arch/spba.h>
41 #include <asm/arch/clock.h>
43 #include "../sound/soc/imx/imx-ssi.h"
44 #include "../sound/soc/imx/imx31-pcm.h"
46 /* SSI BCLK and LRC master */
47 #define WM8350_SSI_MASTER 1
48 /* clock select - either MCLK 0 or 32K 1 */
49 #define WM8350_USE_FLL_32K 1
51 #define IMX31ADS_AUDIO_VERSION "0.4"
53 #define WM8350_AVDD 3300000
55 struct imx31ads_pcm_state {
61 struct imx31ads_data {
62 struct regulator *analog_supply;
63 struct wm8350 *wm8350;
66 struct _wm8350_audio {
67 unsigned int channels;
68 snd_pcm_format_t format;
76 /* in order of power consumption per rate (lowest first) */
77 static const struct _wm8350_audio wm8350_audio[] = {
78 /* 16bit mono modes */
79 {1, SNDRV_PCM_FORMAT_S16_LE, 8000, 12288000 >> 1,
80 WM8350_BCLK_DIV_48, WM8350_DACDIV_3, 16,},
82 /* 16 bit stereo modes */
83 {2, SNDRV_PCM_FORMAT_S16_LE, 8000, 12288000,
84 WM8350_BCLK_DIV_48, WM8350_DACDIV_6, 32,},
85 {2, SNDRV_PCM_FORMAT_S16_LE, 16000, 12288000,
86 WM8350_BCLK_DIV_24, WM8350_DACDIV_3, 32,},
87 {2, SNDRV_PCM_FORMAT_S16_LE, 32000, 12288000,
88 WM8350_BCLK_DIV_12, WM8350_DACDIV_1_5, 32,},
89 {2, SNDRV_PCM_FORMAT_S16_LE, 48000, 12288000,
90 WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
91 {2, SNDRV_PCM_FORMAT_S16_LE, 96000, 24576000,
92 WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
93 {2, SNDRV_PCM_FORMAT_S16_LE, 11025, 11289600,
94 WM8350_BCLK_DIV_32, WM8350_DACDIV_4, 32,},
95 {2, SNDRV_PCM_FORMAT_S16_LE, 22050, 11289600,
96 WM8350_BCLK_DIV_16, WM8350_DACDIV_2, 32,},
97 {2, SNDRV_PCM_FORMAT_S16_LE, 44100, 11289600,
98 WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
99 {2, SNDRV_PCM_FORMAT_S16_LE, 88200, 22579200,
100 WM8350_BCLK_DIV_8, WM8350_DACDIV_1, 32,},
102 /* 24bit stereo modes */
103 {2, SNDRV_PCM_FORMAT_S24_LE, 48000, 12288000,
104 WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
105 {2, SNDRV_PCM_FORMAT_S24_LE, 96000, 24576000,
106 WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
107 {2, SNDRV_PCM_FORMAT_S24_LE, 44100, 11289600,
108 WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
109 {2, SNDRV_PCM_FORMAT_S24_LE, 88200, 22579200,
110 WM8350_BCLK_DIV_4, WM8350_DACDIV_1, 64,},
113 #if WM8350_SSI_MASTER
114 static int imx32ads_startup(struct snd_pcm_substream *substream)
116 struct snd_soc_pcm_runtime *pcm_runtime = substream->private_data;
117 struct snd_soc_codec *codec = pcm_runtime->codec;
118 struct wm8350 *wm8350 = codec->control_data;
119 struct imx31ads_pcm_state *state = pcm_runtime->private_data;
121 /* In master mode the LR clock can come from either the DAC or ADC.
122 * We use the LR clock from whatever stream is enabled first.
124 if (!state->lr_clk_active) {
125 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
126 wm8350_clear_bits(wm8350, WM8350_CLOCK_CONTROL_2,
129 wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_2,
132 state->lr_clk_active++;
133 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
134 state->capture_active = 1;
136 state->playback_active = 1;
140 #define imx32ads_startup NULL
143 static int imx32ads_hifi_hw_params(struct snd_pcm_substream *substream,
144 struct snd_pcm_hw_params *params)
146 struct snd_soc_pcm_runtime *pcm_runtime = substream->private_data;
147 struct snd_soc_dai *cpu_dai = pcm_runtime->cpu_dai;
148 struct snd_soc_dai *codec_dai = pcm_runtime->codec_dai;
149 struct imx31ads_pcm_state *state = pcm_runtime->private_data;
151 snd_pcm_format_t format = params_format(params);
152 unsigned int rate = params_rate(params);
153 unsigned int channels = params_channels(params);
156 /* only need to do this once as capture and playback are sync */
157 if (state->lr_clk_active > 1)
160 /* find the correct audio parameters */
161 for (i = 0; i < ARRAY_SIZE(wm8350_audio); i++) {
162 if (rate == wm8350_audio[i].rate &&
163 format == wm8350_audio[i].format &&
164 channels == wm8350_audio[i].channels) {
172 #if WM8350_SSI_MASTER
173 dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
174 SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_SYNC;
176 dai_format |= SND_SOC_DAIFMT_TDM;
178 /* set codec DAI configuration */
179 snd_soc_dai_set_fmt(codec_dai, dai_format);
181 /* set cpu DAI configuration */
182 snd_soc_dai_set_fmt(cpu_dai, dai_format);
184 #if WM8350_USE_FLL_32K
185 /* set 32K clock as the codec system clock for DAC and ADC */
186 snd_soc_dai_set_sysclk(codec_dai, WM8350_MCLK_SEL_PLL_32K,
187 wm8350_audio[i].sysclk, SND_SOC_CLOCK_IN);
189 /* set MCLK as the codec system clock for DAC and ADC */
190 snd_soc_dai_set_sysclk(codec_dai, WM8350_MCLK_SEL_PLL_MCLK,
191 wm8350_audio[i].sysclk, SND_SOC_CLOCK_IN);
196 dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
197 SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_SYNC;
199 format |= SND_SOC_DAIFMT_TDM;
201 /* set codec DAI configuration */
202 snd_soc_dai_set_fmt(codec_dai, dai_format);
204 /* set cpu DAI configuration */
205 snd_soc_dai_set_fmt(cpu_dai, dai_format);
207 /* set DAC LRC as the codec system clock for DAC and ADC */
208 snd_soc_dai_set_sysclk(codec_dai, WM8350_MCLK_SEL_PLL_DAC,
209 wm8350_audio[i].sysclk, SND_SOC_CLOCK_IN);
212 /* set i.MX active slot mask */
213 snd_soc_dai_set_tdm_slot(cpu_dai,
214 channels == 1 ? 0xfffffffe : 0xfffffffc,
217 /* set the SSI system clock as input (unused) */
218 snd_soc_dai_set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0, SND_SOC_CLOCK_IN);
220 /* set codec BCLK division for sample rate */
221 snd_soc_dai_set_clkdiv(codec_dai, WM8350_BCLK_CLKDIV,
222 wm8350_audio[i].bclkdiv);
224 /* DAI is synchronous and clocked with DAC LRCLK & ADC LRC */
225 snd_soc_dai_set_clkdiv(codec_dai,
226 WM8350_DACLR_CLKDIV, wm8350_audio[i].lr_rate);
227 snd_soc_dai_set_clkdiv(codec_dai,
228 WM8350_ADCLR_CLKDIV, wm8350_audio[i].lr_rate);
230 /* now configure DAC and ADC clocks */
231 snd_soc_dai_set_clkdiv(codec_dai,
232 WM8350_DAC_CLKDIV, wm8350_audio[i].clkdiv);
234 snd_soc_dai_set_clkdiv(codec_dai,
235 WM8350_ADC_CLKDIV, wm8350_audio[i].clkdiv);
237 #if WM8350_SSI_MASTER
238 #if WM8350_USE_FLL_32K
239 /* codec FLL input is 32 kHz from WM8350 */
240 snd_soc_dai_set_pll(codec_dai, 0, 32000, wm8350_audio[i].sysclk);
242 /* codec FLL input is 14.75 MHz from MCLK */
243 snd_soc_dai_set_pll(codec_dai, 0, 14750000, wm8350_audio[i].sysclk);
246 /* codec FLL input is rate from DAC LRC */
247 snd_soc_dai_set_pll(codec_dai, 0, rate, wm8350_audio[i].sysclk);
253 static void imx32ads_shutdown(struct snd_pcm_substream *substream)
255 struct snd_soc_pcm_runtime *pcm_runtime = substream->private_data;
256 struct snd_soc_dai *codec_dai = pcm_runtime->codec_dai;
257 struct snd_soc_codec *codec = pcm_runtime->codec;
258 struct imx31ads_pcm_state *state = pcm_runtime->private_data;
259 struct wm8350 *wm8350 = codec->control_data;
261 /* disable the PLL if there are no active Tx or Rx channels */
263 snd_soc_dai_set_pll(codec_dai, 0, 0, 0);
264 state->lr_clk_active--;
267 * We need to keep track of active streams in master mode and
268 * switch LRC source if necessary.
271 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
272 state->capture_active = 0;
274 state->playback_active = 0;
276 if (state->capture_active)
277 wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_2,
279 else if (state->playback_active)
280 wm8350_clear_bits(wm8350, WM8350_CLOCK_CONTROL_2,
285 * imx32ads WM8350 HiFi DAI opserations.
287 static struct snd_soc_ops imx32ads_hifi_ops = {
288 .startup = imx32ads_startup,
289 .shutdown = imx32ads_shutdown,
290 .hw_params = imx32ads_hifi_hw_params,
293 /* need to refine these */
294 static struct wm8350_audio_platform_data imx32ads_wm8350_setup = {
295 .vmid_discharge_msecs = 1000,
297 .cap_discharge_msecs = 700,
298 .vmid_charge_msecs = 700,
299 .vmid_s_curve = WM8350_S_CURVE_SLOW,
300 .dis_out4 = WM8350_DISCHARGE_SLOW,
301 .dis_out3 = WM8350_DISCHARGE_SLOW,
302 .dis_out2 = WM8350_DISCHARGE_SLOW,
303 .dis_out1 = WM8350_DISCHARGE_SLOW,
304 .vroi_out4 = WM8350_TIE_OFF_500R,
305 .vroi_out3 = WM8350_TIE_OFF_500R,
306 .vroi_out2 = WM8350_TIE_OFF_500R,
307 .vroi_out1 = WM8350_TIE_OFF_500R,
309 .codec_current_on = WM8350_CODEC_ISEL_1_0,
310 .codec_current_standby = WM8350_CODEC_ISEL_0_5,
311 .codec_current_charge = WM8350_CODEC_ISEL_1_5,
314 /* imx32ads soc_card dapm widgets */
315 static const struct snd_soc_dapm_widget imx32ads_dapm_widgets[] = {
316 SND_SOC_DAPM_MIC("SiMIC", NULL),
317 SND_SOC_DAPM_MIC("Mic1 Jack", NULL),
318 SND_SOC_DAPM_MIC("Mic2 Jack", NULL),
319 SND_SOC_DAPM_LINE("Line In Jack", NULL),
320 SND_SOC_DAPM_LINE("Line Out Jack", NULL),
321 SND_SOC_DAPM_HP("Headphone Jack", NULL),
324 /* imx32ads soc_card audio map */
325 static const struct snd_soc_dapm_route audio_map[] = {
327 /* SiMIC --> IN1LN (with automatic bias) via SP1 */
328 {"IN1LN", NULL, "Mic Bias"},
329 {"Mic Bias", NULL, "SiMIC"},
331 /* Mic 1 Jack --> IN1LN and IN1LP (with automatic bias) */
332 {"IN1LN", NULL, "Mic Bias"},
333 {"IN1LP", NULL, "Mic1 Jack"},
334 {"Mic Bias", NULL, "Mic1 Jack"},
336 /* Mic 2 Jack --> IN1RN and IN1RP (with automatic bias) */
337 {"IN1RN", NULL, "Mic Bias"},
338 {"IN1RP", NULL, "Mic1 Jack"},
339 {"Mic Bias", NULL, "Mic1 Jack"},
341 /* Line in Jack --> AUX (L+R) */
342 {"IN3R", NULL, "Line In Jack"},
343 {"IN3L", NULL, "Line In Jack"},
345 /* Out1 --> Headphone Jack */
346 {"Headphone Jack", NULL, "OUT1R"},
347 {"Headphone Jack", NULL, "OUT1L"},
349 /* Out1 --> Line Out Jack */
350 {"Line Out Jack", NULL, "OUT2R"},
351 {"Line Out Jack", NULL, "OUT2L"},
355 static int imx32ads_wm8350_audio_suspend(struct platform_device *pdev,
358 struct wm8350 *wm8350 = platform_get_drvdata(pdev);
359 struct snd_soc_card *soc_card = wm8350->audio;
361 return snd_soc_card_suspend_pcms(soc_card, state);
364 static int imx32ads_wm8350_audio_resume(struct platform_device *pdev)
366 struct wm8350 *wm8350 = platform_get_drvdata(pdev);
367 struct snd_soc_card *soc_card = wm8350->audio;
369 return snd_soc_card_resume_pcms(soc_card);
373 #define imx32ads_wm8350_audio_suspend NULL
374 #define imx32ads_wm8350_audio_resume NULL
377 static void imx32ads_jack_handler(struct wm8350 *wm8350, int irq, void *data)
379 struct snd_soc_card *soc_card = (struct snd_soc_card *)data;
382 /* debounce for 200ms */
383 schedule_timeout_interruptible(msecs_to_jiffies(200));
384 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
386 if (reg & WM8350_JACK_R_LVL) {
387 snd_soc_dapm_disable_pin(soc_card, "Line Out Jack");
388 snd_soc_dapm_enable_pin(soc_card, "Headphone Jack");
390 snd_soc_dapm_disable_pin(soc_card, "Headphone Jack");
391 snd_soc_dapm_enable_pin(soc_card, "Line Out Jack");
393 snd_soc_dapm_sync(soc_card);
396 int imx32_audio_init(struct snd_soc_card *soc_card)
398 struct snd_soc_codec *codec;
399 struct snd_soc_pcm_runtime *pcm_runtime;
400 struct imx31ads_data *audio_data = soc_card->private_data;
401 struct wm8350 *wm8350 = audio_data->wm8350;
402 struct imx31ads_pcm_state *state;
406 pcm_runtime = snd_soc_card_get_pcm(soc_card, "HiFi");
407 if (pcm_runtime == NULL)
410 codec = snd_soc_card_get_codec(soc_card, wm8350_codec_id);
414 state = kzalloc(sizeof(struct imx31ads_pcm_state), GFP_KERNEL);
417 pcm_runtime->private_data = state;
419 codec->platform_data = &imx32ads_wm8350_setup;
420 snd_soc_card_config_codec(codec, NULL, NULL, wm8350);
421 snd_soc_card_init_codec(codec, soc_card);
424 /* add imx32ads specific controls */
425 for (i = 0; i < ARRAY_SIZE(imx32ads_wm8350_audio_controls); i++) {
426 if ((err = snd_ctl_add(soc_card->card,
427 snd_soc_cnew(&imx32ads_wm8350_audio_controls[i],
433 /* Add imx32ads specific widgets */
434 ret = snd_soc_dapm_new_controls(soc_card, codec,
435 imx32ads_dapm_widgets,
436 ARRAY_SIZE(imx32ads_dapm_widgets));
440 /* set up imx32ads specific audio path audio map */
441 ret = snd_soc_dapm_add_routes(soc_card, audio_map,
442 ARRAY_SIZE(audio_map));
446 /* disable unused imx32ads WM8350 codec pins */
447 snd_soc_dapm_disable_pin(soc_card, "OUT3");
448 snd_soc_dapm_disable_pin(soc_card, "OUT4");
449 snd_soc_dapm_disable_pin(soc_card, "IN2R");
450 snd_soc_dapm_disable_pin(soc_card, "IN2L");
451 snd_soc_dapm_disable_pin(soc_card, "OUT2L");
452 snd_soc_dapm_disable_pin(soc_card, "OUT2R");
454 /* connect and enable all imx32ads WM8350 jacks (for now) */
455 snd_soc_dapm_enable_pin(soc_card, "SiMIC");
456 snd_soc_dapm_enable_pin(soc_card, "Mic1 Jack");
457 snd_soc_dapm_enable_pin(soc_card, "Mic2 Jack");
458 snd_soc_dapm_enable_pin(soc_card, "Line In Jack");
459 snd_soc_dapm_set_policy(soc_card, SND_SOC_DAPM_POLICY_AUTOMATIC);
460 snd_soc_dapm_sync(soc_card);
462 /* enable slow clock gen for jack detect */
463 reg = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_4);
464 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_4, reg | WM8350_TOCLK_ENA);
466 /* enable jack detect */
467 reg = wm8350_reg_read(wm8350, WM8350_JACK_DETECT);
468 wm8350_reg_write(wm8350, WM8350_JACK_DETECT, reg | WM8350_JDR_ENA);
469 wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R,
470 imx32ads_jack_handler, soc_card);
471 wm8350_unmask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R);
476 static void imx32_audio_exit(struct snd_soc_card *soc_card)
478 struct snd_soc_pcm_runtime *pcm_runtime;
480 pcm_runtime = snd_soc_card_get_pcm(soc_card, "HiFi");
482 kfree(pcm_runtime->private_data);
485 static struct snd_soc_pcm_config hifi_pcm_config = {
487 .codec = wm8350_codec_id,
488 .codec_dai = wm8350_codec_dai_id,
489 .platform = imx31_platform_id,
490 .cpu_dai = imx_ssi_id1_0,
491 .ops = &imx32ads_hifi_ops,
496 static int __devinit imx32ads_wm8350_audio_probe(struct platform_device *pdev)
498 struct snd_soc_card *soc_card;
499 struct imx31ads_data *audio_data;
500 struct wm8350 *wm8350 = platform_get_drvdata(pdev);
503 printk(KERN_INFO "i.MX32ADS WM8350 audio\n");
504 audio_data = kzalloc(sizeof(*audio_data), GFP_KERNEL);
505 if (audio_data == NULL)
508 ret = get_ssi_clk(0, &pdev->dev);
510 printk(KERN_ERR "%s: cant get ssi clock\n", __func__);
513 audio_data->analog_supply = regulator_get(&pdev->dev, "codec_avdd");
514 if (IS_ERR(audio_data->analog_supply)) {
515 printk(KERN_ERR "%s: cant get regulator\n", __func__);
518 ret = regulator_set_voltage(audio_data->analog_supply, WM8350_AVDD,
521 printk(KERN_ERR "%s: cant set voltage\n", __func__);
524 ret = regulator_enable(audio_data->analog_supply);
526 printk(KERN_ERR "%s: cant enable regulator\n", __func__);
530 soc_card = snd_soc_card_create("imx31ads", &pdev->dev,
533 if (soc_card == NULL) {
538 audio_data->wm8350 = wm8350;
539 soc_card->longname = "WM8350";
540 soc_card->init = imx32_audio_init,
541 soc_card->exit = imx32_audio_exit,
542 soc_card->private_data = audio_data;
543 soc_card->dev = &pdev->dev;
544 wm8350->audio = soc_card;
546 ret = snd_soc_card_create_pcms(soc_card, &hifi_pcm_config, 1);
550 /* WM8350 uses SSI1 via AUDMUX port 5 for audio */
552 /* reset port 1 & 5 */
558 /* set to synchronous */
559 DAM_PTCR1 |= AUDMUX_PTCR_SYN;
560 DAM_PTCR5 |= AUDMUX_PTCR_SYN;
562 #if WM8350_SSI_MASTER
563 /* set Rx sources 1 <--> 5 */
564 DAM_PDCR1 |= AUDMUX_PDCR_RXDSEL(5);
565 DAM_PDCR5 |= AUDMUX_PDCR_RXDSEL(1);
567 /* set Tx frame direction and source 5 --> 1 output */
568 DAM_PTCR1 |= AUDMUX_PTCR_TFSDIR;
569 DAM_PTCR1 |= AUDMUX_PTCR_TFSSEL(AUDMUX_FROM_TXFS, 5);
571 /* set Tx Clock direction and source 5--> 1 output */
572 DAM_PTCR1 |= AUDMUX_PTCR_TCLKDIR;
573 DAM_PTCR1 |= AUDMUX_PTCR_TCSEL(AUDMUX_FROM_TXFS, 5);
575 /* set Rx sources 1 <--> 5 */
576 DAM_PDCR1 |= AUDMUX_PDCR_RXDSEL(5);
577 DAM_PDCR5 |= AUDMUX_PDCR_RXDSEL(1);
579 /* set Tx frame direction and source 1 --> 5 output */
580 DAM_PTCR5 |= AUDMUX_PTCR_TFSDIR;
581 DAM_PTCR5 |= AUDMUX_PTCR_TFSSEL(AUDMUX_FROM_TXFS, 1);
583 /* set Tx Clock direction and source 1--> 5 output */
584 DAM_PTCR5 |= AUDMUX_PTCR_TCLKDIR;
585 DAM_PTCR5 |= AUDMUX_PTCR_TCSEL(AUDMUX_FROM_TXFS, 1);
587 ret = snd_soc_card_register(soc_card);
591 snd_soc_card_free(soc_card);
593 regulator_put(audio_data->analog_supply);
600 static int __devexit imx32ads_wm8350_audio_remove(struct platform_device *pdev)
602 struct wm8350 *wm8350 = platform_get_drvdata(pdev);
603 struct snd_soc_card *soc_card = wm8350->audio;
604 struct imx31ads_data *audio_data = soc_card->private_data;
606 wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R);
607 wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R);
608 snd_soc_card_free(soc_card);
610 regulator_disable(audio_data->analog_supply);
611 regulator_put(audio_data->analog_supply);
617 static struct platform_driver imx32ads_wm8350_audio_driver = {
618 .probe = imx32ads_wm8350_audio_probe,
619 .remove = __devexit_p(imx32ads_wm8350_audio_remove),
620 .suspend = imx32ads_wm8350_audio_suspend,
621 .resume = imx32ads_wm8350_audio_resume,
623 .name = "imx31ads-audio",
627 static int __init imx32ads_wm8350_audio_init(void)
629 return platform_driver_register(&imx32ads_wm8350_audio_driver);
632 static void __exit imx32ads_wm8350_audio_exit(void)
634 platform_driver_unregister(&imx32ads_wm8350_audio_driver);
637 module_init(imx32ads_wm8350_audio_init);
638 module_exit(imx32ads_wm8350_audio_exit);
640 MODULE_AUTHOR("Liam Girdwood");
641 MODULE_DESCRIPTION("PMIC WM8350 Driver for i.MX32ADS");
642 MODULE_LICENSE("GPL");