blob: 807db417d234a5d3571f6ff6be86893acad514d9 [file] [log] [blame]
Graeme Gregory74930bb2007-05-14 11:03:52 +02001/*
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +01002 * neo1973_wm8753.c -- SoC audio for Openmoko Neo1973 and Freerunner devices
Graeme Gregory74930bb2007-05-14 11:03:52 +02003 *
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +01004 * Copyright 2007 Openmoko Inc
5 * Author: Graeme Gregory <graeme@openmoko.org>
Graeme Gregory74930bb2007-05-14 11:03:52 +02006 * Copyright 2007 Wolfson Microelectronics PLC.
7 * Author: Graeme Gregory
8 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +01009 * Copyright 2009 Wolfson Microelectronics
Graeme Gregory74930bb2007-05-14 11:03:52 +020010 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
Graeme Gregory74930bb2007-05-14 11:03:52 +020015 */
16
17#include <linux/module.h>
Graeme Gregory74930bb2007-05-14 11:03:52 +020018#include <linux/platform_device.h>
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +010019#include <linux/gpio.h>
20
Graeme Gregory74930bb2007-05-14 11:03:52 +020021#include <sound/soc.h>
Graeme Gregory74930bb2007-05-14 11:03:52 +020022
Mark Brownfb2aa072008-10-08 13:02:20 +010023#include <asm/mach-types.h>
Arnd Bergmann5d229ce52013-04-11 19:08:42 +020024#include "regs-iis.h"
Harald Welteaa9673c2007-12-19 15:37:49 +010025
Graeme Gregory74930bb2007-05-14 11:03:52 +020026#include "../codecs/wm8753.h"
Graeme Gregory74930bb2007-05-14 11:03:52 +020027#include "s3c24xx-i2s.h"
28
Graeme Gregory74930bb2007-05-14 11:03:52 +020029static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
30 struct snd_pcm_hw_params *params)
31{
32 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +000033 struct snd_soc_dai *codec_dai = rtd->codec_dai;
34 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
Graeme Gregory74930bb2007-05-14 11:03:52 +020035 unsigned int pll_out = 0, bclk = 0;
36 int ret = 0;
37 unsigned long iis_clkrate;
38
39 iis_clkrate = s3c24xx_i2s_get_clockrate();
40
41 switch (params_rate(params)) {
42 case 8000:
43 case 16000:
44 pll_out = 12288000;
45 break;
46 case 48000:
47 bclk = WM8753_BCLK_DIV_4;
48 pll_out = 12288000;
49 break;
50 case 96000:
51 bclk = WM8753_BCLK_DIV_2;
52 pll_out = 12288000;
53 break;
54 case 11025:
55 bclk = WM8753_BCLK_DIV_16;
56 pll_out = 11289600;
57 break;
58 case 22050:
59 bclk = WM8753_BCLK_DIV_8;
60 pll_out = 11289600;
61 break;
62 case 44100:
63 bclk = WM8753_BCLK_DIV_4;
64 pll_out = 11289600;
65 break;
66 case 88200:
67 bclk = WM8753_BCLK_DIV_2;
68 pll_out = 11289600;
69 break;
70 }
71
72 /* set codec DAI configuration */
Liam Girdwood64105cf2008-07-08 13:19:18 +010073 ret = snd_soc_dai_set_fmt(codec_dai,
Graeme Gregory74930bb2007-05-14 11:03:52 +020074 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
75 SND_SOC_DAIFMT_CBM_CFM);
76 if (ret < 0)
77 return ret;
78
79 /* set cpu DAI configuration */
Liam Girdwood64105cf2008-07-08 13:19:18 +010080 ret = snd_soc_dai_set_fmt(cpu_dai,
Graeme Gregory74930bb2007-05-14 11:03:52 +020081 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
82 SND_SOC_DAIFMT_CBM_CFM);
83 if (ret < 0)
84 return ret;
85
86 /* set the codec system clock for DAC and ADC */
Liam Girdwood64105cf2008-07-08 13:19:18 +010087 ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out,
Graeme Gregory74930bb2007-05-14 11:03:52 +020088 SND_SOC_CLOCK_IN);
89 if (ret < 0)
90 return ret;
91
92 /* set MCLK division for sample rate */
Liam Girdwood64105cf2008-07-08 13:19:18 +010093 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
Graeme Gregory8ba02ac2008-04-30 20:24:54 +020094 S3C2410_IISMOD_32FS);
Graeme Gregory74930bb2007-05-14 11:03:52 +020095 if (ret < 0)
96 return ret;
97
98 /* set codec BCLK division for sample rate */
Liam Girdwood64105cf2008-07-08 13:19:18 +010099 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_BCLKDIV, bclk);
Graeme Gregory74930bb2007-05-14 11:03:52 +0200100 if (ret < 0)
101 return ret;
102
103 /* set prescaler division for sample rate */
Liam Girdwood64105cf2008-07-08 13:19:18 +0100104 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
Graeme Gregory8ba02ac2008-04-30 20:24:54 +0200105 S3C24XX_PRESCALE(4, 4));
Graeme Gregory74930bb2007-05-14 11:03:52 +0200106 if (ret < 0)
107 return ret;
108
109 /* codec PLL input is PCLK/4 */
Mark Brown85488032009-09-05 18:52:16 +0100110 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0,
Graeme Gregory74930bb2007-05-14 11:03:52 +0200111 iis_clkrate / 4, pll_out);
112 if (ret < 0)
113 return ret;
114
115 return 0;
116}
117
118static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream)
119{
120 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000121 struct snd_soc_dai *codec_dai = rtd->codec_dai;
Graeme Gregory74930bb2007-05-14 11:03:52 +0200122
123 /* disable the PLL */
Takashi Iwai140318a2009-10-01 08:40:32 +0200124 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0);
Graeme Gregory74930bb2007-05-14 11:03:52 +0200125}
126
127/*
128 * Neo1973 WM8753 HiFi DAI opserations.
129 */
130static struct snd_soc_ops neo1973_hifi_ops = {
131 .hw_params = neo1973_hifi_hw_params,
132 .hw_free = neo1973_hifi_hw_free,
133};
134
135static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
136 struct snd_pcm_hw_params *params)
137{
138 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000139 struct snd_soc_dai *codec_dai = rtd->codec_dai;
Graeme Gregory74930bb2007-05-14 11:03:52 +0200140 unsigned int pcmdiv = 0;
141 int ret = 0;
142 unsigned long iis_clkrate;
143
144 iis_clkrate = s3c24xx_i2s_get_clockrate();
145
146 if (params_rate(params) != 8000)
147 return -EINVAL;
148 if (params_channels(params) != 1)
149 return -EINVAL;
150
151 pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */
152
153 /* todo: gg check mode (DSP_B) against CSR datasheet */
154 /* set codec DAI configuration */
Liam Girdwood64105cf2008-07-08 13:19:18 +0100155 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B |
Graeme Gregory74930bb2007-05-14 11:03:52 +0200156 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
157 if (ret < 0)
158 return ret;
159
160 /* set the codec system clock for DAC and ADC */
Liam Girdwood64105cf2008-07-08 13:19:18 +0100161 ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK, 12288000,
Graeme Gregory74930bb2007-05-14 11:03:52 +0200162 SND_SOC_CLOCK_IN);
163 if (ret < 0)
164 return ret;
165
166 /* set codec PCM division for sample rate */
Liam Girdwood64105cf2008-07-08 13:19:18 +0100167 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV, pcmdiv);
Graeme Gregory74930bb2007-05-14 11:03:52 +0200168 if (ret < 0)
169 return ret;
170
Andrea Gelminifa2eb002010-10-16 15:19:20 +0200171 /* configure and enable PLL for 12.288MHz output */
Takashi Iwai140318a2009-10-01 08:40:32 +0200172 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0,
Graeme Gregory74930bb2007-05-14 11:03:52 +0200173 iis_clkrate / 4, 12288000);
174 if (ret < 0)
175 return ret;
176
177 return 0;
178}
179
180static int neo1973_voice_hw_free(struct snd_pcm_substream *substream)
181{
182 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000183 struct snd_soc_dai *codec_dai = rtd->codec_dai;
Graeme Gregory74930bb2007-05-14 11:03:52 +0200184
185 /* disable the PLL */
Takashi Iwai140318a2009-10-01 08:40:32 +0200186 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
Graeme Gregory74930bb2007-05-14 11:03:52 +0200187}
188
189static struct snd_soc_ops neo1973_voice_ops = {
190 .hw_params = neo1973_voice_hw_params,
191 .hw_free = neo1973_voice_hw_free,
192};
193
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100194/* Shared routes and controls */
195
196static const struct snd_soc_dapm_widget neo1973_wm8753_dapm_widgets[] = {
Graeme Gregory74930bb2007-05-14 11:03:52 +0200197 SND_SOC_DAPM_LINE("GSM Line Out", NULL),
198 SND_SOC_DAPM_LINE("GSM Line In", NULL),
199 SND_SOC_DAPM_MIC("Headset Mic", NULL),
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100200 SND_SOC_DAPM_MIC("Handset Mic", NULL),
Graeme Gregory74930bb2007-05-14 11:03:52 +0200201};
202
Lars-Peter Clausen9b0a25f2011-03-07 08:04:55 +0100203static const struct snd_soc_dapm_route neo1973_wm8753_routes[] = {
Graeme Gregory74930bb2007-05-14 11:03:52 +0200204 /* Connections to the GSM Module */
205 {"GSM Line Out", NULL, "MONO1"},
206 {"GSM Line Out", NULL, "MONO2"},
207 {"RXP", NULL, "GSM Line In"},
208 {"RXN", NULL, "GSM Line In"},
209
210 /* Connections to Headset */
211 {"MIC1", NULL, "Mic Bias"},
212 {"Mic Bias", NULL, "Headset Mic"},
213
214 /* Call Mic */
215 {"MIC2", NULL, "Mic Bias"},
216 {"MIC2N", NULL, "Mic Bias"},
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100217 {"Mic Bias", NULL, "Handset Mic"},
Graeme Gregory74930bb2007-05-14 11:03:52 +0200218
219 /* Connect the ALC pins */
220 {"ACIN", NULL, "ACOP"},
Graeme Gregory74930bb2007-05-14 11:03:52 +0200221};
222
Lars-Peter Clausen9b0a25f2011-03-07 08:04:55 +0100223static const struct snd_kcontrol_new neo1973_wm8753_controls[] = {
Lars-Peter Clausen004c52e2011-03-07 08:04:54 +0100224 SOC_DAPM_PIN_SWITCH("GSM Line Out"),
225 SOC_DAPM_PIN_SWITCH("GSM Line In"),
226 SOC_DAPM_PIN_SWITCH("Headset Mic"),
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100227 SOC_DAPM_PIN_SWITCH("Handset Mic"),
Graeme Gregory74930bb2007-05-14 11:03:52 +0200228};
229
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300230/* GTA02 specific routes and controls */
Lars-Peter Clausen9b0a25f2011-03-07 08:04:55 +0100231
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100232static int gta02_speaker_enabled;
233
234static int lm4853_set_spk(struct snd_kcontrol *kcontrol,
235 struct snd_ctl_elem_value *ucontrol)
236{
237 gta02_speaker_enabled = ucontrol->value.integer.value[0];
238
Kukjin Kimb2ca7872013-01-02 09:57:59 -0800239 gpio_set_value(S3C2410_GPJ(2), !gta02_speaker_enabled);
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100240
241 return 0;
242}
243
244static int lm4853_get_spk(struct snd_kcontrol *kcontrol,
245 struct snd_ctl_elem_value *ucontrol)
246{
247 ucontrol->value.integer.value[0] = gta02_speaker_enabled;
248 return 0;
249}
250
251static int lm4853_event(struct snd_soc_dapm_widget *w,
252 struct snd_kcontrol *k, int event)
253{
Kukjin Kimb2ca7872013-01-02 09:57:59 -0800254 gpio_set_value(S3C2410_GPJ(1), SND_SOC_DAPM_EVENT_OFF(event));
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100255
256 return 0;
257}
258
259static const struct snd_soc_dapm_route neo1973_gta02_routes[] = {
260 /* Connections to the amp */
261 {"Stereo Out", NULL, "LOUT1"},
262 {"Stereo Out", NULL, "ROUT1"},
263
264 /* Call Speaker */
265 {"Handset Spk", NULL, "LOUT2"},
266 {"Handset Spk", NULL, "ROUT2"},
267};
268
269static const struct snd_kcontrol_new neo1973_gta02_wm8753_controls[] = {
270 SOC_DAPM_PIN_SWITCH("Handset Spk"),
271 SOC_DAPM_PIN_SWITCH("Stereo Out"),
272
273 SOC_SINGLE_BOOL_EXT("Amp Spk Switch", 0,
274 lm4853_get_spk,
275 lm4853_set_spk),
276};
277
278static const struct snd_soc_dapm_widget neo1973_gta02_wm8753_dapm_widgets[] = {
279 SND_SOC_DAPM_SPK("Handset Spk", NULL),
280 SND_SOC_DAPM_SPK("Stereo Out", lm4853_event),
281};
282
283static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec)
284{
285 struct snd_soc_dapm_context *dapm = &codec->dapm;
286 int ret;
287
288 ret = snd_soc_dapm_new_controls(dapm, neo1973_gta02_wm8753_dapm_widgets,
289 ARRAY_SIZE(neo1973_gta02_wm8753_dapm_widgets));
290 if (ret)
291 return ret;
292
293 ret = snd_soc_dapm_add_routes(dapm, neo1973_gta02_routes,
294 ARRAY_SIZE(neo1973_gta02_routes));
295 if (ret)
296 return ret;
297
Liam Girdwood022658b2012-02-03 17:43:09 +0000298 ret = snd_soc_add_card_controls(codec->card, neo1973_gta02_wm8753_controls,
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100299 ARRAY_SIZE(neo1973_gta02_wm8753_controls));
300 if (ret)
301 return ret;
302
303 snd_soc_dapm_disable_pin(dapm, "Stereo Out");
304 snd_soc_dapm_disable_pin(dapm, "Handset Spk");
305 snd_soc_dapm_ignore_suspend(dapm, "Stereo Out");
306 snd_soc_dapm_ignore_suspend(dapm, "Handset Spk");
307
308 return 0;
309}
310
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000311static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
Graeme Gregory74930bb2007-05-14 11:03:52 +0200312{
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000313 struct snd_soc_codec *codec = rtd->codec;
Liam Girdwoodce6120c2010-11-05 15:53:46 +0200314 struct snd_soc_dapm_context *dapm = &codec->dapm;
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100315 int ret;
Tim Niemeyer1894c592008-05-05 14:16:12 +0200316
Graeme Gregory74930bb2007-05-14 11:03:52 +0200317 /* set up NC codec pins */
Liam Girdwoodce6120c2010-11-05 15:53:46 +0200318 snd_soc_dapm_nc_pin(dapm, "OUT3");
319 snd_soc_dapm_nc_pin(dapm, "OUT4");
320 snd_soc_dapm_nc_pin(dapm, "LINE1");
321 snd_soc_dapm_nc_pin(dapm, "LINE2");
Graeme Gregory74930bb2007-05-14 11:03:52 +0200322
Graeme Gregory74930bb2007-05-14 11:03:52 +0200323 /* Add neo1973 specific widgets */
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100324 ret = snd_soc_dapm_new_controls(dapm, neo1973_wm8753_dapm_widgets,
325 ARRAY_SIZE(neo1973_wm8753_dapm_widgets));
326 if (ret)
327 return ret;
Graeme Gregory74930bb2007-05-14 11:03:52 +0200328
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100329 /* add neo1973 specific controls */
Liam Girdwood022658b2012-02-03 17:43:09 +0000330 ret = snd_soc_add_card_controls(rtd->card, neo1973_wm8753_controls,
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100331 ARRAY_SIZE(neo1973_wm8753_controls));
332 if (ret)
333 return ret;
334
335 /* set up neo1973 specific audio routes */
336 ret = snd_soc_dapm_add_routes(dapm, neo1973_wm8753_routes,
337 ARRAY_SIZE(neo1973_wm8753_routes));
338 if (ret)
339 return ret;
340
341 /* set endpoints to default off mode */
Lars-Peter Clausen004c52e2011-03-07 08:04:54 +0100342 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
343 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
344 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100345 snd_soc_dapm_disable_pin(dapm, "Handset Mic");
Jonas Bonne8089942008-10-01 18:17:12 +0100346
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100347 /* allow audio paths from the GSM modem to run during suspend */
348 snd_soc_dapm_ignore_suspend(dapm, "GSM Line Out");
349 snd_soc_dapm_ignore_suspend(dapm, "GSM Line In");
350 snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
351 snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
Graeme Gregory74930bb2007-05-14 11:03:52 +0200352
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100353 if (machine_is_neo1973_gta02()) {
354 ret = neo1973_gta02_wm8753_init(codec);
355 if (ret)
356 return ret;
357 }
Graeme Gregory74930bb2007-05-14 11:03:52 +0200358
Graeme Gregory74930bb2007-05-14 11:03:52 +0200359 return 0;
360}
361
Graeme Gregory74930bb2007-05-14 11:03:52 +0200362static struct snd_soc_dai_link neo1973_dai[] = {
363{ /* Hifi Playback - for similatious use with voice below */
364 .name = "WM8753",
365 .stream_name = "WM8753 HiFi",
Padmavathi Vennaa08485d82012-12-07 13:59:21 +0530366 .platform_name = "s3c24xx-iis",
Lars-Peter Clausen518aa592011-01-24 22:12:42 +0100367 .cpu_dai_name = "s3c24xx-iis",
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000368 .codec_dai_name = "wm8753-hifi",
Denis 'GNUtoo' Cariklib2ccf062012-02-26 19:21:54 +0100369 .codec_name = "wm8753.0-001a",
Graeme Gregory74930bb2007-05-14 11:03:52 +0200370 .init = neo1973_wm8753_init,
371 .ops = &neo1973_hifi_ops,
372},
373{ /* Voice via BT */
374 .name = "Bluetooth",
375 .stream_name = "Voice",
Barry Song200ceb92013-05-18 20:25:00 +0800376 .cpu_dai_name = "bt-sco-pcm",
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000377 .codec_dai_name = "wm8753-voice",
Denis 'GNUtoo' Cariklib2ccf062012-02-26 19:21:54 +0100378 .codec_name = "wm8753.0-001a",
Graeme Gregory74930bb2007-05-14 11:03:52 +0200379 .ops = &neo1973_voice_ops,
380},
381};
382
Lars-Peter Clausen9b0a25f2011-03-07 08:04:55 +0100383static struct snd_soc_aux_dev neo1973_aux_devs[] = {
384 {
Lars-Peter Clausena077ff92011-03-07 08:04:59 +0100385 .name = "dfbmcs320",
386 .codec_name = "dfbmcs320.0",
387 },
Lars-Peter Clausen9b0a25f2011-03-07 08:04:55 +0100388};
389
390static struct snd_soc_codec_conf neo1973_codec_conf[] = {
391 {
392 .dev_name = "lm4857.0-007c",
393 .name_prefix = "Amp",
394 },
395};
396
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100397static const struct gpio neo1973_gta02_gpios[] = {
Kukjin Kimb2ca7872013-01-02 09:57:59 -0800398 { S3C2410_GPJ(2), GPIOF_OUT_INIT_HIGH, "GTA02_HP_IN" },
399 { S3C2410_GPJ(1), GPIOF_OUT_INIT_HIGH, "GTA02_AMP_SHUT" },
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100400};
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100401
Mark Brown87506542008-11-18 20:50:34 +0000402static struct snd_soc_card neo1973 = {
Graeme Gregory74930bb2007-05-14 11:03:52 +0200403 .name = "neo1973",
Axel Lin095d79d2011-12-22 10:53:15 +0800404 .owner = THIS_MODULE,
Graeme Gregory74930bb2007-05-14 11:03:52 +0200405 .dai_link = neo1973_dai,
406 .num_links = ARRAY_SIZE(neo1973_dai),
Lars-Peter Clausen9b0a25f2011-03-07 08:04:55 +0100407 .aux_dev = neo1973_aux_devs,
408 .num_aux_devs = ARRAY_SIZE(neo1973_aux_devs),
409 .codec_conf = neo1973_codec_conf,
410 .num_configs = ARRAY_SIZE(neo1973_codec_conf),
Graeme Gregory74930bb2007-05-14 11:03:52 +0200411};
412
413static struct platform_device *neo1973_snd_device;
414
415static int __init neo1973_init(void)
416{
417 int ret;
418
Denis 'GNUtoo' Carikli1ae5cbc2012-01-30 00:31:47 +0100419 if (!machine_is_neo1973_gta02())
Mark Brownfb2aa072008-10-08 13:02:20 +0100420 return -ENODEV;
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100421
422 if (machine_is_neo1973_gta02()) {
423 neo1973.name = "neo1973gta02";
Lars-Peter Clausena077ff92011-03-07 08:04:59 +0100424 neo1973.num_aux_devs = 1;
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100425
426 ret = gpio_request_array(neo1973_gta02_gpios,
427 ARRAY_SIZE(neo1973_gta02_gpios));
428 if (ret)
429 return ret;
Mark Brownfb2aa072008-10-08 13:02:20 +0100430 }
431
Graeme Gregory74930bb2007-05-14 11:03:52 +0200432 neo1973_snd_device = platform_device_alloc("soc-audio", -1);
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100433 if (!neo1973_snd_device) {
434 ret = -ENOMEM;
435 goto err_gpio_free;
436 }
437
Liam Girdwoodf0fba2a2010-03-17 20:15:21 +0000438 platform_set_drvdata(neo1973_snd_device, &neo1973);
Graeme Gregory74930bb2007-05-14 11:03:52 +0200439 ret = platform_device_add(neo1973_snd_device);
440
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100441 if (ret)
Lars-Peter Clausena077ff92011-03-07 08:04:59 +0100442 goto err_put_device;
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100443
444 return 0;
445
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100446err_put_device:
447 platform_device_put(neo1973_snd_device);
448err_gpio_free:
449 if (machine_is_neo1973_gta02()) {
450 gpio_free_array(neo1973_gta02_gpios,
451 ARRAY_SIZE(neo1973_gta02_gpios));
Jean Delvared2802892008-09-01 17:44:05 +0200452 }
Graeme Gregory74930bb2007-05-14 11:03:52 +0200453 return ret;
454}
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100455module_init(neo1973_init);
Graeme Gregory74930bb2007-05-14 11:03:52 +0200456
457static void __exit neo1973_exit(void)
458{
Graeme Gregory74930bb2007-05-14 11:03:52 +0200459 platform_device_unregister(neo1973_snd_device);
Graeme Gregory74930bb2007-05-14 11:03:52 +0200460
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100461 if (machine_is_neo1973_gta02()) {
462 gpio_free_array(neo1973_gta02_gpios,
463 ARRAY_SIZE(neo1973_gta02_gpios));
464 }
465}
Graeme Gregory74930bb2007-05-14 11:03:52 +0200466module_exit(neo1973_exit);
467
468/* Module information */
Graeme Gregory443590e2008-04-30 20:25:23 +0200469MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org, www.openmoko.org");
Lars-Peter Clausenf5c4ffb2011-03-07 08:04:58 +0100470MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973 and Frerunner");
Graeme Gregory74930bb2007-05-14 11:03:52 +0200471MODULE_LICENSE("GPL");