diff options
-rw-r--r-- | sound/soc/samsung/Kconfig | 19 | ||||
-rw-r--r-- | sound/soc/samsung/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/samsung/neo1973_gta02_wm8753.c | 435 | ||||
-rw-r--r-- | sound/soc/samsung/neo1973_wm8753.c | 262 |
4 files changed, 196 insertions, 522 deletions
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index ba78e26e20f2..c3014e821570 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig | |||
@@ -35,24 +35,15 @@ config SND_SAMSUNG_I2S | |||
35 | tristate | 35 | tristate |
36 | 36 | ||
37 | config SND_SOC_SAMSUNG_NEO1973_WM8753 | 37 | config SND_SOC_SAMSUNG_NEO1973_WM8753 |
38 | tristate "SoC I2S Audio support for NEO1973 - WM8753" | 38 | tristate "Audio support for Openmoko Neo1973 Smartphones (GTA01/GTA02)" |
39 | depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA01 | 39 | depends on SND_SOC_SAMSUNG && (MACH_NEO1973_GTA01 || MACH_NEO1973_GTA02) |
40 | select SND_S3C24XX_I2S | 40 | select SND_S3C24XX_I2S |
41 | select SND_SOC_WM8753 | 41 | select SND_SOC_WM8753 |
42 | select SND_SOC_LM4857 | 42 | select SND_SOC_LM4857 if MACH_NEO1973_GTA01 |
43 | help | 43 | help |
44 | Say Y if you want to add support for SoC audio on smdk2440 | 44 | Say Y here to enable audio support for the Openmoko Neo1973 |
45 | with the WM8753. | 45 | Smartphones. |
46 | 46 | ||
47 | config SND_SOC_SAMSUNG_NEO1973_GTA02_WM8753 | ||
48 | tristate "Audio support for the Openmoko Neo FreeRunner (GTA02)" | ||
49 | depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA02 | ||
50 | select SND_S3C24XX_I2S | ||
51 | select SND_SOC_WM8753 | ||
52 | help | ||
53 | This driver provides audio support for the Openmoko Neo FreeRunner | ||
54 | smartphone. | ||
55 | |||
56 | config SND_SOC_SAMSUNG_JIVE_WM8750 | 47 | config SND_SOC_SAMSUNG_JIVE_WM8750 |
57 | tristate "SoC I2S Audio support for Jive" | 48 | tristate "SoC I2S Audio support for Jive" |
58 | depends on SND_SOC_SAMSUNG && MACH_JIVE | 49 | depends on SND_SOC_SAMSUNG && MACH_JIVE |
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 705d4e8a6724..294dec05c26d 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile | |||
@@ -20,7 +20,6 @@ obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-i2s.o | |||
20 | # S3C24XX Machine Support | 20 | # S3C24XX Machine Support |
21 | snd-soc-jive-wm8750-objs := jive_wm8750.o | 21 | snd-soc-jive-wm8750-objs := jive_wm8750.o |
22 | snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o | 22 | snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o |
23 | snd-soc-neo1973-gta02-wm8753-objs := neo1973_gta02_wm8753.o | ||
24 | snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o | 23 | snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o |
25 | snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o | 24 | snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o |
26 | snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o | 25 | snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o |
@@ -38,7 +37,6 @@ snd-soc-smdk-spdif-objs := smdk_spdif.o | |||
38 | 37 | ||
39 | obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o | 38 | obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o |
40 | obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o | 39 | obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o |
41 | obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm8753.o | ||
42 | obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o | 40 | obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o |
43 | obj-$(CONFIG_SND_SOC_SAMSUNG_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o | 41 | obj-$(CONFIG_SND_SOC_SAMSUNG_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o |
44 | obj-$(CONFIG_SND_SOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o | 42 | obj-$(CONFIG_SND_SOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o |
diff --git a/sound/soc/samsung/neo1973_gta02_wm8753.c b/sound/soc/samsung/neo1973_gta02_wm8753.c deleted file mode 100644 index 28d8448e959d..000000000000 --- a/sound/soc/samsung/neo1973_gta02_wm8753.c +++ /dev/null | |||
@@ -1,435 +0,0 @@ | |||
1 | /* | ||
2 | * neo1973_gta02_wm8753.c -- SoC audio for Openmoko Freerunner(GTA02) | ||
3 | * | ||
4 | * Copyright 2007 Openmoko Inc | ||
5 | * Author: Graeme Gregory <graeme@openmoko.org> | ||
6 | * Copyright 2007 Wolfson Microelectronics PLC. | ||
7 | * Author: Graeme Gregory <linux@wolfsonmicro.com> | ||
8 | * Copyright 2009 Wolfson Microelectronics | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | */ | ||
15 | |||
16 | #include <linux/gpio.h> | ||
17 | |||
18 | #include <sound/soc.h> | ||
19 | |||
20 | #include <asm/mach-types.h> | ||
21 | #include <plat/regs-iis.h> | ||
22 | #include <mach/gta02.h> | ||
23 | |||
24 | #include "../codecs/wm8753.h" | ||
25 | #include "s3c24xx-i2s.h" | ||
26 | |||
27 | static struct snd_soc_card neo1973_gta02; | ||
28 | |||
29 | static int neo1973_gta02_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; | ||
33 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
34 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
35 | 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 */ | ||
73 | ret = snd_soc_dai_set_fmt(codec_dai, | ||
74 | 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 */ | ||
80 | ret = snd_soc_dai_set_fmt(cpu_dai, | ||
81 | 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 */ | ||
87 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out, | ||
88 | SND_SOC_CLOCK_IN); | ||
89 | if (ret < 0) | ||
90 | return ret; | ||
91 | |||
92 | /* set MCLK division for sample rate */ | ||
93 | ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, | ||
94 | S3C2410_IISMOD_32FS); | ||
95 | if (ret < 0) | ||
96 | return ret; | ||
97 | |||
98 | /* set codec BCLK division for sample rate */ | ||
99 | ret = snd_soc_dai_set_clkdiv(codec_dai, | ||
100 | WM8753_BCLKDIV, bclk); | ||
101 | if (ret < 0) | ||
102 | return ret; | ||
103 | |||
104 | /* set prescaler division for sample rate */ | ||
105 | ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, | ||
106 | S3C24XX_PRESCALE(4, 4)); | ||
107 | if (ret < 0) | ||
108 | return ret; | ||
109 | |||
110 | /* codec PLL input is PCLK/4 */ | ||
111 | ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, | ||
112 | iis_clkrate / 4, pll_out); | ||
113 | if (ret < 0) | ||
114 | return ret; | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static int neo1973_gta02_hifi_hw_free(struct snd_pcm_substream *substream) | ||
120 | { | ||
121 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
122 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
123 | |||
124 | /* disable the PLL */ | ||
125 | return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0); | ||
126 | } | ||
127 | |||
128 | /* | ||
129 | * Neo1973 WM8753 HiFi DAI opserations. | ||
130 | */ | ||
131 | static struct snd_soc_ops neo1973_gta02_hifi_ops = { | ||
132 | .hw_params = neo1973_gta02_hifi_hw_params, | ||
133 | .hw_free = neo1973_gta02_hifi_hw_free, | ||
134 | }; | ||
135 | |||
136 | static int neo1973_gta02_voice_hw_params( | ||
137 | struct snd_pcm_substream *substream, | ||
138 | struct snd_pcm_hw_params *params) | ||
139 | { | ||
140 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
141 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
142 | unsigned int pcmdiv = 0; | ||
143 | int ret = 0; | ||
144 | unsigned long iis_clkrate; | ||
145 | |||
146 | iis_clkrate = s3c24xx_i2s_get_clockrate(); | ||
147 | |||
148 | if (params_rate(params) != 8000) | ||
149 | return -EINVAL; | ||
150 | if (params_channels(params) != 1) | ||
151 | return -EINVAL; | ||
152 | |||
153 | pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */ | ||
154 | |||
155 | /* todo: gg check mode (DSP_B) against CSR datasheet */ | ||
156 | /* set codec DAI configuration */ | ||
157 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | | ||
158 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); | ||
159 | if (ret < 0) | ||
160 | return ret; | ||
161 | |||
162 | /* set the codec system clock for DAC and ADC */ | ||
163 | ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK, | ||
164 | 12288000, SND_SOC_CLOCK_IN); | ||
165 | if (ret < 0) | ||
166 | return ret; | ||
167 | |||
168 | /* set codec PCM division for sample rate */ | ||
169 | ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV, | ||
170 | pcmdiv); | ||
171 | if (ret < 0) | ||
172 | return ret; | ||
173 | |||
174 | /* configure and enable PLL for 12.288MHz output */ | ||
175 | ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, | ||
176 | iis_clkrate / 4, 12288000); | ||
177 | if (ret < 0) | ||
178 | return ret; | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static int neo1973_gta02_voice_hw_free(struct snd_pcm_substream *substream) | ||
184 | { | ||
185 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
186 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
187 | |||
188 | /* disable the PLL */ | ||
189 | return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0); | ||
190 | } | ||
191 | |||
192 | static struct snd_soc_ops neo1973_gta02_voice_ops = { | ||
193 | .hw_params = neo1973_gta02_voice_hw_params, | ||
194 | .hw_free = neo1973_gta02_voice_hw_free, | ||
195 | }; | ||
196 | |||
197 | static int gta02_speaker_enabled; | ||
198 | |||
199 | static int lm4853_set_spk(struct snd_kcontrol *kcontrol, | ||
200 | struct snd_ctl_elem_value *ucontrol) | ||
201 | { | ||
202 | gta02_speaker_enabled = ucontrol->value.integer.value[0]; | ||
203 | |||
204 | gpio_set_value(GTA02_GPIO_HP_IN, !gta02_speaker_enabled); | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static int lm4853_get_spk(struct snd_kcontrol *kcontrol, | ||
210 | struct snd_ctl_elem_value *ucontrol) | ||
211 | { | ||
212 | ucontrol->value.integer.value[0] = gta02_speaker_enabled; | ||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | static int lm4853_event(struct snd_soc_dapm_widget *w, | ||
217 | struct snd_kcontrol *k, int event) | ||
218 | { | ||
219 | gpio_set_value(GTA02_GPIO_AMP_SHUT, SND_SOC_DAPM_EVENT_OFF(event)); | ||
220 | |||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = { | ||
225 | SND_SOC_DAPM_SPK("Stereo Out", lm4853_event), | ||
226 | SND_SOC_DAPM_LINE("GSM Line Out", NULL), | ||
227 | SND_SOC_DAPM_LINE("GSM Line In", NULL), | ||
228 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | ||
229 | SND_SOC_DAPM_MIC("Handset Mic", NULL), | ||
230 | SND_SOC_DAPM_SPK("Handset Spk", NULL), | ||
231 | }; | ||
232 | |||
233 | |||
234 | /* example machine audio_mapnections */ | ||
235 | static const struct snd_soc_dapm_route audio_map[] = { | ||
236 | |||
237 | /* Connections to the lm4853 amp */ | ||
238 | {"Stereo Out", NULL, "LOUT1"}, | ||
239 | {"Stereo Out", NULL, "ROUT1"}, | ||
240 | |||
241 | /* Connections to the GSM Module */ | ||
242 | {"GSM Line Out", NULL, "MONO1"}, | ||
243 | {"GSM Line Out", NULL, "MONO2"}, | ||
244 | {"RXP", NULL, "GSM Line In"}, | ||
245 | {"RXN", NULL, "GSM Line In"}, | ||
246 | |||
247 | /* Connections to Headset */ | ||
248 | {"MIC1", NULL, "Mic Bias"}, | ||
249 | {"Mic Bias", NULL, "Headset Mic"}, | ||
250 | |||
251 | /* Call Mic */ | ||
252 | {"MIC2", NULL, "Mic Bias"}, | ||
253 | {"MIC2N", NULL, "Mic Bias"}, | ||
254 | {"Mic Bias", NULL, "Handset Mic"}, | ||
255 | |||
256 | /* Call Speaker */ | ||
257 | {"Handset Spk", NULL, "LOUT2"}, | ||
258 | {"Handset Spk", NULL, "ROUT2"}, | ||
259 | |||
260 | /* Connect the ALC pins */ | ||
261 | {"ACIN", NULL, "ACOP"}, | ||
262 | }; | ||
263 | |||
264 | static const struct snd_kcontrol_new wm8753_neo1973_gta02_controls[] = { | ||
265 | SOC_DAPM_PIN_SWITCH("Stereo Out"), | ||
266 | SOC_DAPM_PIN_SWITCH("GSM Line Out"), | ||
267 | SOC_DAPM_PIN_SWITCH("GSM Line In"), | ||
268 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | ||
269 | SOC_DAPM_PIN_SWITCH("Handset Mic"), | ||
270 | SOC_DAPM_PIN_SWITCH("Handset Spk"), | ||
271 | |||
272 | SOC_SINGLE_BOOL_EXT("Amp Spk Switch", 0, | ||
273 | lm4853_get_spk, | ||
274 | lm4853_set_spk), | ||
275 | }; | ||
276 | |||
277 | /* | ||
278 | * This is an example machine initialisation for a wm8753 connected to a | ||
279 | * neo1973 GTA02. | ||
280 | */ | ||
281 | static int neo1973_gta02_wm8753_init(struct snd_soc_pcm_runtime *rtd) | ||
282 | { | ||
283 | struct snd_soc_codec *codec = rtd->codec; | ||
284 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
285 | int err; | ||
286 | |||
287 | /* set up NC codec pins */ | ||
288 | snd_soc_dapm_nc_pin(dapm, "OUT3"); | ||
289 | snd_soc_dapm_nc_pin(dapm, "OUT4"); | ||
290 | snd_soc_dapm_nc_pin(dapm, "LINE1"); | ||
291 | snd_soc_dapm_nc_pin(dapm, "LINE2"); | ||
292 | |||
293 | /* Add neo1973 gta02 specific widgets */ | ||
294 | snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets, | ||
295 | ARRAY_SIZE(wm8753_dapm_widgets)); | ||
296 | |||
297 | /* add neo1973 gta02 specific controls */ | ||
298 | err = snd_soc_add_controls(codec, wm8753_neo1973_gta02_controls, | ||
299 | ARRAY_SIZE(wm8753_neo1973_gta02_controls)); | ||
300 | |||
301 | if (err < 0) | ||
302 | return err; | ||
303 | |||
304 | /* set up neo1973 gta02 specific audio path audio_map */ | ||
305 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | ||
306 | |||
307 | /* set endpoints to default off mode */ | ||
308 | snd_soc_dapm_disable_pin(dapm, "Stereo Out"); | ||
309 | snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); | ||
310 | snd_soc_dapm_disable_pin(dapm, "GSM Line In"); | ||
311 | snd_soc_dapm_disable_pin(dapm, "Headset Mic"); | ||
312 | snd_soc_dapm_disable_pin(dapm, "Handset Mic"); | ||
313 | snd_soc_dapm_disable_pin(dapm, "Handset Spk"); | ||
314 | |||
315 | /* allow audio paths from the GSM modem to run during suspend */ | ||
316 | snd_soc_dapm_ignore_suspend(dapm, "Stereo Out"); | ||
317 | snd_soc_dapm_ignore_suspend(dapm, "GSM Line Out"); | ||
318 | snd_soc_dapm_ignore_suspend(dapm, "GSM Line In"); | ||
319 | snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); | ||
320 | snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); | ||
321 | snd_soc_dapm_ignore_suspend(dapm, "Handset Spk"); | ||
322 | |||
323 | snd_soc_dapm_sync(dapm); | ||
324 | |||
325 | return 0; | ||
326 | } | ||
327 | |||
328 | /* | ||
329 | * BT Codec DAI | ||
330 | */ | ||
331 | static struct snd_soc_dai_driver bt_dai = { | ||
332 | .name = "bluetooth-dai", | ||
333 | .playback = { | ||
334 | .channels_min = 1, | ||
335 | .channels_max = 1, | ||
336 | .rates = SNDRV_PCM_RATE_8000, | ||
337 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | ||
338 | .capture = { | ||
339 | .channels_min = 1, | ||
340 | .channels_max = 1, | ||
341 | .rates = SNDRV_PCM_RATE_8000, | ||
342 | .formats = SNDRV_PCM_FMTBIT_S16_LE,}, | ||
343 | }; | ||
344 | |||
345 | static struct snd_soc_dai_link neo1973_gta02_dai[] = { | ||
346 | { /* Hifi Playback - for similatious use with voice below */ | ||
347 | .name = "WM8753", | ||
348 | .stream_name = "WM8753 HiFi", | ||
349 | .cpu_dai_name = "s3c24xx-iis", | ||
350 | .codec_dai_name = "wm8753-hifi", | ||
351 | .init = neo1973_gta02_wm8753_init, | ||
352 | .platform_name = "samsung-audio", | ||
353 | .codec_name = "wm8753-codec.0-001a", | ||
354 | .ops = &neo1973_gta02_hifi_ops, | ||
355 | }, | ||
356 | { /* Voice via BT */ | ||
357 | .name = "Bluetooth", | ||
358 | .stream_name = "Voice", | ||
359 | .cpu_dai_name = "bluetooth-dai", | ||
360 | .codec_dai_name = "wm8753-voice", | ||
361 | .ops = &neo1973_gta02_voice_ops, | ||
362 | .codec_name = "wm8753-codec.0-001a", | ||
363 | .platform_name = "samsung-audio", | ||
364 | }, | ||
365 | }; | ||
366 | |||
367 | static struct snd_soc_card neo1973_gta02 = { | ||
368 | .name = "neo1973-gta02", | ||
369 | .dai_link = neo1973_gta02_dai, | ||
370 | .num_links = ARRAY_SIZE(neo1973_gta02_dai), | ||
371 | }; | ||
372 | |||
373 | static const struct gpio neo1973_gta02_gpios[] = { | ||
374 | { GTA02_GPIO_HP_IN, GPIOF_OUT_INIT_HIGH, "GTA02_HP_IN" }, | ||
375 | { GTA02_GPIO_AMP_SHUT, GPIOF_OUT_INIT_HIGH, "GTA02_AMP_SHUT" }, | ||
376 | }; | ||
377 | |||
378 | static struct platform_device *neo1973_gta02_snd_device; | ||
379 | |||
380 | static int __init neo1973_gta02_init(void) | ||
381 | { | ||
382 | int ret; | ||
383 | |||
384 | if (!machine_is_neo1973_gta02()) { | ||
385 | printk(KERN_INFO | ||
386 | "Only GTA02 is supported by this ASoC driver\n"); | ||
387 | return -ENODEV; | ||
388 | } | ||
389 | |||
390 | ret = gpio_request_array(neo1973_gta02_gpios, | ||
391 | ARRAY_SIZE(neo1973_gta02_gpios)); | ||
392 | if (ret) | ||
393 | return ret; | ||
394 | |||
395 | neo1973_gta02_snd_device = platform_device_alloc("soc-audio", -1); | ||
396 | if (!neo1973_gta02_snd_device) { | ||
397 | ret = -ENOMEM; | ||
398 | goto err_gpio_free; | ||
399 | } | ||
400 | |||
401 | /* register bluetooth DAI here */ | ||
402 | ret = snd_soc_register_dai(&neo1973_gta02_snd_device->dev, &bt_dai); | ||
403 | if (ret) | ||
404 | goto err_put_device; | ||
405 | |||
406 | platform_set_drvdata(neo1973_gta02_snd_device, &neo1973_gta02); | ||
407 | ret = platform_device_add(neo1973_gta02_snd_device); | ||
408 | |||
409 | if (ret) | ||
410 | goto err_unregister_dai; | ||
411 | |||
412 | return 0; | ||
413 | |||
414 | err_unregister_dai: | ||
415 | snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev); | ||
416 | err_put_device: | ||
417 | platform_device_put(neo1973_gta02_snd_device); | ||
418 | err_gpio_free: | ||
419 | gpio_free_array(neo1973_gta02_gpios, ARRAY_SIZE(neo1973_gta02_gpios)); | ||
420 | return ret; | ||
421 | } | ||
422 | module_init(neo1973_gta02_init); | ||
423 | |||
424 | static void __exit neo1973_gta02_exit(void) | ||
425 | { | ||
426 | snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev); | ||
427 | platform_device_unregister(neo1973_gta02_snd_device); | ||
428 | gpio_free_array(neo1973_gta02_gpios, ARRAY_SIZE(neo1973_gta02_gpios)); | ||
429 | } | ||
430 | module_exit(neo1973_gta02_exit); | ||
431 | |||
432 | /* Module information */ | ||
433 | MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org"); | ||
434 | MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973 GTA02"); | ||
435 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c index 7761827314b2..37cfbb8ca39f 100644 --- a/sound/soc/samsung/neo1973_wm8753.c +++ b/sound/soc/samsung/neo1973_wm8753.c | |||
@@ -1,41 +1,32 @@ | |||
1 | /* | 1 | /* |
2 | * neo1973_wm8753.c -- SoC audio for Neo1973 | 2 | * neo1973_wm8753.c -- SoC audio for Openmoko Neo1973 and Freerunner devices |
3 | * | 3 | * |
4 | * Copyright 2007 Openmoko Inc | ||
5 | * Author: Graeme Gregory <graeme@openmoko.org> | ||
4 | * Copyright 2007 Wolfson Microelectronics PLC. | 6 | * Copyright 2007 Wolfson Microelectronics PLC. |
5 | * Author: Graeme Gregory | 7 | * Author: Graeme Gregory |
6 | * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com | 8 | * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com |
9 | * Copyright 2009 Wolfson Microelectronics | ||
7 | * | 10 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 11 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of the GNU General Public License as published by the | 12 | * under the terms of the GNU General Public License as published by the |
10 | * Free Software Foundation; either version 2 of the License, or (at your | 13 | * Free Software Foundation; either version 2 of the License, or (at your |
11 | * option) any later version. | 14 | * option) any later version. |
12 | * | ||
13 | */ | 15 | */ |
14 | 16 | ||
15 | #include <linux/module.h> | 17 | #include <linux/module.h> |
16 | #include <linux/moduleparam.h> | ||
17 | #include <linux/timer.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
20 | #include <sound/core.h> | 19 | #include <linux/gpio.h> |
21 | #include <sound/pcm.h> | 20 | |
22 | #include <sound/soc.h> | 21 | #include <sound/soc.h> |
23 | 22 | ||
24 | #include <asm/mach-types.h> | 23 | #include <asm/mach-types.h> |
25 | #include <mach/regs-clock.h> | ||
26 | #include <mach/regs-gpio.h> | ||
27 | #include <mach/hardware.h> | ||
28 | #include <linux/io.h> | ||
29 | #include <mach/spi-gpio.h> | ||
30 | |||
31 | #include <plat/regs-iis.h> | 24 | #include <plat/regs-iis.h> |
25 | #include <mach/gta02.h> | ||
32 | 26 | ||
33 | #include "../codecs/wm8753.h" | 27 | #include "../codecs/wm8753.h" |
34 | #include "dma.h" | ||
35 | #include "s3c24xx-i2s.h" | 28 | #include "s3c24xx-i2s.h" |
36 | 29 | ||
37 | static struct snd_soc_card neo1973; | ||
38 | |||
39 | static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, | 30 | static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, |
40 | struct snd_pcm_hw_params *params) | 31 | struct snd_pcm_hw_params *params) |
41 | { | 32 | { |
@@ -46,8 +37,6 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, | |||
46 | int ret = 0; | 37 | int ret = 0; |
47 | unsigned long iis_clkrate; | 38 | unsigned long iis_clkrate; |
48 | 39 | ||
49 | pr_debug("Entered %s\n", __func__); | ||
50 | |||
51 | iis_clkrate = s3c24xx_i2s_get_clockrate(); | 40 | iis_clkrate = s3c24xx_i2s_get_clockrate(); |
52 | 41 | ||
53 | switch (params_rate(params)) { | 42 | switch (params_rate(params)) { |
@@ -132,8 +121,6 @@ static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream) | |||
132 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 121 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
133 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 122 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
134 | 123 | ||
135 | pr_debug("Entered %s\n", __func__); | ||
136 | |||
137 | /* disable the PLL */ | 124 | /* disable the PLL */ |
138 | return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0); | 125 | return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0); |
139 | } | 126 | } |
@@ -155,8 +142,6 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream, | |||
155 | int ret = 0; | 142 | int ret = 0; |
156 | unsigned long iis_clkrate; | 143 | unsigned long iis_clkrate; |
157 | 144 | ||
158 | pr_debug("Entered %s\n", __func__); | ||
159 | |||
160 | iis_clkrate = s3c24xx_i2s_get_clockrate(); | 145 | iis_clkrate = s3c24xx_i2s_get_clockrate(); |
161 | 146 | ||
162 | if (params_rate(params) != 8000) | 147 | if (params_rate(params) != 8000) |
@@ -198,8 +183,6 @@ static int neo1973_voice_hw_free(struct snd_pcm_substream *substream) | |||
198 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 183 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
199 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 184 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
200 | 185 | ||
201 | pr_debug("Entered %s\n", __func__); | ||
202 | |||
203 | /* disable the PLL */ | 186 | /* disable the PLL */ |
204 | return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0); | 187 | return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0); |
205 | } | 188 | } |
@@ -209,14 +192,15 @@ static struct snd_soc_ops neo1973_voice_ops = { | |||
209 | .hw_free = neo1973_voice_hw_free, | 192 | .hw_free = neo1973_voice_hw_free, |
210 | }; | 193 | }; |
211 | 194 | ||
212 | static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = { | 195 | /* Shared routes and controls */ |
196 | |||
197 | static const struct snd_soc_dapm_widget neo1973_wm8753_dapm_widgets[] = { | ||
213 | SND_SOC_DAPM_LINE("GSM Line Out", NULL), | 198 | SND_SOC_DAPM_LINE("GSM Line Out", NULL), |
214 | SND_SOC_DAPM_LINE("GSM Line In", NULL), | 199 | SND_SOC_DAPM_LINE("GSM Line In", NULL), |
215 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | 200 | SND_SOC_DAPM_MIC("Headset Mic", NULL), |
216 | SND_SOC_DAPM_MIC("Call Mic", NULL), | 201 | SND_SOC_DAPM_MIC("Handset Mic", NULL), |
217 | }; | 202 | }; |
218 | 203 | ||
219 | |||
220 | static const struct snd_soc_dapm_route neo1973_wm8753_routes[] = { | 204 | static const struct snd_soc_dapm_route neo1973_wm8753_routes[] = { |
221 | /* Connections to the GSM Module */ | 205 | /* Connections to the GSM Module */ |
222 | {"GSM Line Out", NULL, "MONO1"}, | 206 | {"GSM Line Out", NULL, "MONO1"}, |
@@ -231,7 +215,7 @@ static const struct snd_soc_dapm_route neo1973_wm8753_routes[] = { | |||
231 | /* Call Mic */ | 215 | /* Call Mic */ |
232 | {"MIC2", NULL, "Mic Bias"}, | 216 | {"MIC2", NULL, "Mic Bias"}, |
233 | {"MIC2N", NULL, "Mic Bias"}, | 217 | {"MIC2N", NULL, "Mic Bias"}, |
234 | {"Mic Bias", NULL, "Call Mic"}, | 218 | {"Mic Bias", NULL, "Handset Mic"}, |
235 | 219 | ||
236 | /* Connect the ALC pins */ | 220 | /* Connect the ALC pins */ |
237 | {"ACIN", NULL, "ACOP"}, | 221 | {"ACIN", NULL, "ACOP"}, |
@@ -241,55 +225,157 @@ static const struct snd_kcontrol_new neo1973_wm8753_controls[] = { | |||
241 | SOC_DAPM_PIN_SWITCH("GSM Line Out"), | 225 | SOC_DAPM_PIN_SWITCH("GSM Line Out"), |
242 | SOC_DAPM_PIN_SWITCH("GSM Line In"), | 226 | SOC_DAPM_PIN_SWITCH("GSM Line In"), |
243 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | 227 | SOC_DAPM_PIN_SWITCH("Headset Mic"), |
244 | SOC_DAPM_PIN_SWITCH("Call Mic"), | 228 | SOC_DAPM_PIN_SWITCH("Handset Mic"), |
245 | }; | 229 | }; |
246 | 230 | ||
231 | /* GTA02 specific routes and controlls */ | ||
232 | |||
233 | #ifdef CONFIG_MACH_NEO1973_GTA02 | ||
234 | |||
235 | static int gta02_speaker_enabled; | ||
236 | |||
237 | static int lm4853_set_spk(struct snd_kcontrol *kcontrol, | ||
238 | struct snd_ctl_elem_value *ucontrol) | ||
239 | { | ||
240 | gta02_speaker_enabled = ucontrol->value.integer.value[0]; | ||
241 | |||
242 | gpio_set_value(GTA02_GPIO_HP_IN, !gta02_speaker_enabled); | ||
243 | |||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | static int lm4853_get_spk(struct snd_kcontrol *kcontrol, | ||
248 | struct snd_ctl_elem_value *ucontrol) | ||
249 | { | ||
250 | ucontrol->value.integer.value[0] = gta02_speaker_enabled; | ||
251 | return 0; | ||
252 | } | ||
253 | |||
254 | static int lm4853_event(struct snd_soc_dapm_widget *w, | ||
255 | struct snd_kcontrol *k, int event) | ||
256 | { | ||
257 | gpio_set_value(GTA02_GPIO_AMP_SHUT, SND_SOC_DAPM_EVENT_OFF(event)); | ||
258 | |||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | static const struct snd_soc_dapm_route neo1973_gta02_routes[] = { | ||
263 | /* Connections to the amp */ | ||
264 | {"Stereo Out", NULL, "LOUT1"}, | ||
265 | {"Stereo Out", NULL, "ROUT1"}, | ||
266 | |||
267 | /* Call Speaker */ | ||
268 | {"Handset Spk", NULL, "LOUT2"}, | ||
269 | {"Handset Spk", NULL, "ROUT2"}, | ||
270 | }; | ||
271 | |||
272 | static const struct snd_kcontrol_new neo1973_gta02_wm8753_controls[] = { | ||
273 | SOC_DAPM_PIN_SWITCH("Handset Spk"), | ||
274 | SOC_DAPM_PIN_SWITCH("Stereo Out"), | ||
275 | |||
276 | SOC_SINGLE_BOOL_EXT("Amp Spk Switch", 0, | ||
277 | lm4853_get_spk, | ||
278 | lm4853_set_spk), | ||
279 | }; | ||
280 | |||
281 | static const struct snd_soc_dapm_widget neo1973_gta02_wm8753_dapm_widgets[] = { | ||
282 | SND_SOC_DAPM_SPK("Handset Spk", NULL), | ||
283 | SND_SOC_DAPM_SPK("Stereo Out", lm4853_event), | ||
284 | }; | ||
285 | |||
286 | static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec) | ||
287 | { | ||
288 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
289 | int ret; | ||
290 | |||
291 | ret = snd_soc_dapm_new_controls(dapm, neo1973_gta02_wm8753_dapm_widgets, | ||
292 | ARRAY_SIZE(neo1973_gta02_wm8753_dapm_widgets)); | ||
293 | if (ret) | ||
294 | return ret; | ||
295 | |||
296 | ret = snd_soc_dapm_add_routes(dapm, neo1973_gta02_routes, | ||
297 | ARRAY_SIZE(neo1973_gta02_routes)); | ||
298 | if (ret) | ||
299 | return ret; | ||
300 | |||
301 | ret = snd_soc_add_controls(codec, neo1973_gta02_wm8753_controls, | ||
302 | ARRAY_SIZE(neo1973_gta02_wm8753_controls)); | ||
303 | if (ret) | ||
304 | return ret; | ||
305 | |||
306 | snd_soc_dapm_disable_pin(dapm, "Stereo Out"); | ||
307 | snd_soc_dapm_disable_pin(dapm, "Handset Spk"); | ||
308 | snd_soc_dapm_ignore_suspend(dapm, "Stereo Out"); | ||
309 | snd_soc_dapm_ignore_suspend(dapm, "Handset Spk"); | ||
310 | |||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | #else | ||
315 | static int neo1973_gta02_wm8753_init(struct snd_soc_code *codec) { return 0; } | ||
316 | #endif | ||
247 | 317 | ||
248 | /* | ||
249 | * This is an example machine initialisation for a wm8753 connected to a | ||
250 | * neo1973 II. It is missing logic to detect hp/mic insertions and logic | ||
251 | * to re-route the audio in such an event. | ||
252 | */ | ||
253 | static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) | 318 | static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) |
254 | { | 319 | { |
255 | struct snd_soc_codec *codec = rtd->codec; | 320 | struct snd_soc_codec *codec = rtd->codec; |
256 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 321 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
257 | int err; | 322 | int ret; |
258 | |||
259 | pr_debug("Entered %s\n", __func__); | ||
260 | 323 | ||
261 | /* set up NC codec pins */ | 324 | /* set up NC codec pins */ |
262 | snd_soc_dapm_nc_pin(dapm, "LOUT2"); | 325 | if (machine_is_neo1973_gta01()) { |
263 | snd_soc_dapm_nc_pin(dapm, "ROUT2"); | 326 | snd_soc_dapm_nc_pin(dapm, "LOUT2"); |
327 | snd_soc_dapm_nc_pin(dapm, "ROUT2"); | ||
328 | } | ||
264 | snd_soc_dapm_nc_pin(dapm, "OUT3"); | 329 | snd_soc_dapm_nc_pin(dapm, "OUT3"); |
265 | snd_soc_dapm_nc_pin(dapm, "OUT4"); | 330 | snd_soc_dapm_nc_pin(dapm, "OUT4"); |
266 | snd_soc_dapm_nc_pin(dapm, "LINE1"); | 331 | snd_soc_dapm_nc_pin(dapm, "LINE1"); |
267 | snd_soc_dapm_nc_pin(dapm, "LINE2"); | 332 | snd_soc_dapm_nc_pin(dapm, "LINE2"); |
268 | 333 | ||
269 | /* Add neo1973 specific widgets */ | 334 | /* Add neo1973 specific widgets */ |
270 | snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets, | 335 | ret = snd_soc_dapm_new_controls(dapm, neo1973_wm8753_dapm_widgets, |
271 | ARRAY_SIZE(wm8753_dapm_widgets)); | 336 | ARRAY_SIZE(neo1973_wm8753_dapm_widgets)); |
272 | 337 | if (ret) | |
273 | /* set endpoints to default mode */ | 338 | return ret; |
274 | snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); | ||
275 | snd_soc_dapm_disable_pin(dapm, "GSM Line In"); | ||
276 | snd_soc_dapm_disable_pin(dapm, "Headset Mic"); | ||
277 | snd_soc_dapm_disable_pin(dapm, "Call Mic"); | ||
278 | 339 | ||
279 | /* add neo1973 specific controls */ | 340 | /* add neo1973 specific controls */ |
280 | err = snd_soc_add_controls(codec, neo1973_wm8753_controls, | 341 | ret = snd_soc_add_controls(codec, neo1973_wm8753_controls, |
281 | ARRAY_SIZE(neo1973_wm8753_controls)); | 342 | ARRAY_SIZE(neo1973_wm8753_controls)); |
282 | if (err < 0) | 343 | if (ret) |
283 | return err; | 344 | return ret; |
284 | 345 | ||
285 | /* set up neo1973 specific audio routes */ | 346 | /* set up neo1973 specific audio routes */ |
286 | err = snd_soc_dapm_add_routes(dapm, neo1973_wm8753_routes, | 347 | ret = snd_soc_dapm_add_routes(dapm, neo1973_wm8753_routes, |
287 | ARRAY_SIZE(neo1973_wm8753_routes)); | 348 | ARRAY_SIZE(neo1973_wm8753_routes)); |
349 | if (ret) | ||
350 | return ret; | ||
351 | |||
352 | /* set endpoints to default off mode */ | ||
353 | snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); | ||
354 | snd_soc_dapm_disable_pin(dapm, "GSM Line In"); | ||
355 | snd_soc_dapm_disable_pin(dapm, "Headset Mic"); | ||
356 | snd_soc_dapm_disable_pin(dapm, "Handset Mic"); | ||
357 | |||
358 | /* allow audio paths from the GSM modem to run during suspend */ | ||
359 | snd_soc_dapm_ignore_suspend(dapm, "GSM Line Out"); | ||
360 | snd_soc_dapm_ignore_suspend(dapm, "GSM Line In"); | ||
361 | snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); | ||
362 | snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); | ||
363 | |||
364 | if (machine_is_neo1973_gta02()) { | ||
365 | ret = neo1973_gta02_wm8753_init(codec); | ||
366 | if (ret) | ||
367 | return ret; | ||
368 | } | ||
288 | 369 | ||
289 | snd_soc_dapm_sync(dapm); | 370 | snd_soc_dapm_sync(dapm); |
371 | |||
290 | return 0; | 372 | return 0; |
291 | } | 373 | } |
292 | 374 | ||
375 | /* GTA01 specific controlls */ | ||
376 | |||
377 | #ifdef CONFIG_MACH_NEO1973_GTA01 | ||
378 | |||
293 | static const struct snd_soc_dapm_route neo1973_lm4857_routes[] = { | 379 | static const struct snd_soc_dapm_route neo1973_lm4857_routes[] = { |
294 | {"Amp IN", NULL, "ROUT1"}, | 380 | {"Amp IN", NULL, "ROUT1"}, |
295 | {"Amp IN", NULL, "LOUT1"}, | 381 | {"Amp IN", NULL, "LOUT1"}, |
@@ -328,10 +414,14 @@ static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm) | |||
328 | return 0; | 414 | return 0; |
329 | } | 415 | } |
330 | 416 | ||
417 | #else | ||
418 | static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm) { return 0; }; | ||
419 | #endif | ||
420 | |||
331 | /* | 421 | /* |
332 | * BT Codec DAI | 422 | * BT Codec DAI |
333 | */ | 423 | */ |
334 | static struct snd_soc_dai bt_dai = { | 424 | static struct snd_soc_dai_driver bt_dai = { |
335 | .name = "bluetooth-dai", | 425 | .name = "bluetooth-dai", |
336 | .playback = { | 426 | .playback = { |
337 | .channels_min = 1, | 427 | .channels_min = 1, |
@@ -382,6 +472,15 @@ static struct snd_soc_codec_conf neo1973_codec_conf[] = { | |||
382 | }, | 472 | }, |
383 | }; | 473 | }; |
384 | 474 | ||
475 | #ifdef CONFIG_MACH_NEO1973_GTA02 | ||
476 | static const struct gpio neo1973_gta02_gpios[] = { | ||
477 | { GTA02_GPIO_HP_IN, GPIOF_OUT_INIT_HIGH, "GTA02_HP_IN" }, | ||
478 | { GTA02_GPIO_AMP_SHUT, GPIOF_OUT_INIT_HIGH, "GTA02_AMP_SHUT" }, | ||
479 | }; | ||
480 | #else | ||
481 | static const struct gpio neo1973_gta02_gpios[] = {}; | ||
482 | #endif | ||
483 | |||
385 | static struct snd_soc_card neo1973 = { | 484 | static struct snd_soc_card neo1973 = { |
386 | .name = "neo1973", | 485 | .name = "neo1973", |
387 | .dai_link = neo1973_dai, | 486 | .dai_link = neo1973_dai, |
@@ -398,43 +497,64 @@ static int __init neo1973_init(void) | |||
398 | { | 497 | { |
399 | int ret; | 498 | int ret; |
400 | 499 | ||
401 | pr_debug("Entered %s\n", __func__); | 500 | if (!machine_is_neo1973_gta01() && !machine_is_neo1973_gta02()) |
402 | |||
403 | if (!machine_is_neo1973_gta01()) { | ||
404 | printk(KERN_INFO | ||
405 | "Only GTA01 hardware supported by ASoC driver\n"); | ||
406 | return -ENODEV; | 501 | return -ENODEV; |
502 | |||
503 | if (machine_is_neo1973_gta02()) { | ||
504 | neo1973.name = "neo1973gta02"; | ||
505 | neo1973.num_aux_devs = 0; | ||
506 | |||
507 | ret = gpio_request_array(neo1973_gta02_gpios, | ||
508 | ARRAY_SIZE(neo1973_gta02_gpios)); | ||
509 | if (ret) | ||
510 | return ret; | ||
407 | } | 511 | } |
408 | 512 | ||
409 | neo1973_snd_device = platform_device_alloc("soc-audio", -1); | 513 | neo1973_snd_device = platform_device_alloc("soc-audio", -1); |
410 | if (!neo1973_snd_device) | 514 | if (!neo1973_snd_device) { |
411 | return -ENOMEM; | 515 | ret = -ENOMEM; |
516 | goto err_gpio_free; | ||
517 | } | ||
518 | |||
519 | /* register bluetooth DAI here */ | ||
520 | ret = snd_soc_register_dai(&neo1973_snd_device->dev, &bt_dai); | ||
521 | if (ret) | ||
522 | goto err_put_device; | ||
412 | 523 | ||
413 | platform_set_drvdata(neo1973_snd_device, &neo1973); | 524 | platform_set_drvdata(neo1973_snd_device, &neo1973); |
414 | ret = platform_device_add(neo1973_snd_device); | 525 | ret = platform_device_add(neo1973_snd_device); |
415 | 526 | ||
416 | if (ret) { | 527 | if (ret) |
417 | platform_device_put(neo1973_snd_device); | 528 | goto err_unregister_dai; |
418 | return ret; | ||
419 | } | ||
420 | 529 | ||
421 | if (ret != 0) | 530 | return 0; |
422 | platform_device_unregister(neo1973_snd_device); | ||
423 | 531 | ||
532 | err_unregister_dai: | ||
533 | snd_soc_unregister_dai(&neo1973_snd_device->dev); | ||
534 | err_put_device: | ||
535 | platform_device_put(neo1973_snd_device); | ||
536 | err_gpio_free: | ||
537 | if (machine_is_neo1973_gta02()) { | ||
538 | gpio_free_array(neo1973_gta02_gpios, | ||
539 | ARRAY_SIZE(neo1973_gta02_gpios)); | ||
540 | } | ||
424 | return ret; | 541 | return ret; |
425 | } | 542 | } |
543 | module_init(neo1973_init); | ||
426 | 544 | ||
427 | static void __exit neo1973_exit(void) | 545 | static void __exit neo1973_exit(void) |
428 | { | 546 | { |
429 | pr_debug("Entered %s\n", __func__); | 547 | snd_soc_unregister_dai(&neo1973_snd_device->dev); |
430 | |||
431 | platform_device_unregister(neo1973_snd_device); | 548 | platform_device_unregister(neo1973_snd_device); |
432 | } | ||
433 | 549 | ||
434 | module_init(neo1973_init); | 550 | if (machine_is_neo1973_gta02()) { |
551 | gpio_free_array(neo1973_gta02_gpios, | ||
552 | ARRAY_SIZE(neo1973_gta02_gpios)); | ||
553 | } | ||
554 | } | ||
435 | module_exit(neo1973_exit); | 555 | module_exit(neo1973_exit); |
436 | 556 | ||
437 | /* Module information */ | 557 | /* Module information */ |
438 | MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org, www.openmoko.org"); | 558 | MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org, www.openmoko.org"); |
439 | MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973"); | 559 | MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973 and Frerunner"); |
440 | MODULE_LICENSE("GPL"); | 560 | MODULE_LICENSE("GPL"); |