Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / sound / soc / samsung / neo1973_wm8753.c
1 /*
2  * neo1973_wm8753.c  --  SoC audio for Openmoko Neo1973 and Freerunner devices
3  *
4  * Copyright 2007 Openmoko Inc
5  * Author: Graeme Gregory <graeme@openmoko.org>
6  * Copyright 2007 Wolfson Microelectronics PLC.
7  * Author: Graeme Gregory
8  *         graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
9  * Copyright 2009 Wolfson Microelectronics
10  *
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.
15  */
16
17 #include <linux/module.h>
18 #include <linux/platform_device.h>
19 #include <linux/gpio.h>
20
21 #include <sound/soc.h>
22
23 #include <mach/gpio-samsung.h>
24 #include <asm/mach-types.h>
25 #include "regs-iis.h"
26
27 #include "../codecs/wm8753.h"
28 #include "s3c24xx-i2s.h"
29
30 static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
31         struct snd_pcm_hw_params *params)
32 {
33         struct snd_soc_pcm_runtime *rtd = substream->private_data;
34         struct snd_soc_dai *codec_dai = rtd->codec_dai;
35         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
36         unsigned int pll_out = 0, bclk = 0;
37         int ret = 0;
38         unsigned long iis_clkrate;
39
40         iis_clkrate = s3c24xx_i2s_get_clockrate();
41
42         switch (params_rate(params)) {
43         case 8000:
44         case 16000:
45                 pll_out = 12288000;
46                 break;
47         case 48000:
48                 bclk = WM8753_BCLK_DIV_4;
49                 pll_out = 12288000;
50                 break;
51         case 96000:
52                 bclk = WM8753_BCLK_DIV_2;
53                 pll_out = 12288000;
54                 break;
55         case 11025:
56                 bclk = WM8753_BCLK_DIV_16;
57                 pll_out = 11289600;
58                 break;
59         case 22050:
60                 bclk = WM8753_BCLK_DIV_8;
61                 pll_out = 11289600;
62                 break;
63         case 44100:
64                 bclk = WM8753_BCLK_DIV_4;
65                 pll_out = 11289600;
66                 break;
67         case 88200:
68                 bclk = WM8753_BCLK_DIV_2;
69                 pll_out = 11289600;
70                 break;
71         }
72
73         /* set the codec system clock for DAC and ADC */
74         ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out,
75                 SND_SOC_CLOCK_IN);
76         if (ret < 0)
77                 return ret;
78
79         /* set MCLK division for sample rate */
80         ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
81                 S3C2410_IISMOD_32FS);
82         if (ret < 0)
83                 return ret;
84
85         /* set codec BCLK division for sample rate */
86         ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_BCLKDIV, bclk);
87         if (ret < 0)
88                 return ret;
89
90         /* set prescaler division for sample rate */
91         ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
92                 S3C24XX_PRESCALE(4, 4));
93         if (ret < 0)
94                 return ret;
95
96         /* codec PLL input is PCLK/4 */
97         ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0,
98                 iis_clkrate / 4, pll_out);
99         if (ret < 0)
100                 return ret;
101
102         return 0;
103 }
104
105 static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream)
106 {
107         struct snd_soc_pcm_runtime *rtd = substream->private_data;
108         struct snd_soc_dai *codec_dai = rtd->codec_dai;
109
110         /* disable the PLL */
111         return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0);
112 }
113
114 /*
115  * Neo1973 WM8753 HiFi DAI opserations.
116  */
117 static struct snd_soc_ops neo1973_hifi_ops = {
118         .hw_params = neo1973_hifi_hw_params,
119         .hw_free = neo1973_hifi_hw_free,
120 };
121
122 static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
123         struct snd_pcm_hw_params *params)
124 {
125         struct snd_soc_pcm_runtime *rtd = substream->private_data;
126         struct snd_soc_dai *codec_dai = rtd->codec_dai;
127         unsigned int pcmdiv = 0;
128         int ret = 0;
129         unsigned long iis_clkrate;
130
131         iis_clkrate = s3c24xx_i2s_get_clockrate();
132
133         if (params_rate(params) != 8000)
134                 return -EINVAL;
135         if (params_channels(params) != 1)
136                 return -EINVAL;
137
138         pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */
139
140         /* set the codec system clock for DAC and ADC */
141         ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK, 12288000,
142                 SND_SOC_CLOCK_IN);
143         if (ret < 0)
144                 return ret;
145
146         /* set codec PCM division for sample rate */
147         ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV, pcmdiv);
148         if (ret < 0)
149                 return ret;
150
151         /* configure and enable PLL for 12.288MHz output */
152         ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0,
153                 iis_clkrate / 4, 12288000);
154         if (ret < 0)
155                 return ret;
156
157         return 0;
158 }
159
160 static int neo1973_voice_hw_free(struct snd_pcm_substream *substream)
161 {
162         struct snd_soc_pcm_runtime *rtd = substream->private_data;
163         struct snd_soc_dai *codec_dai = rtd->codec_dai;
164
165         /* disable the PLL */
166         return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
167 }
168
169 static struct snd_soc_ops neo1973_voice_ops = {
170         .hw_params = neo1973_voice_hw_params,
171         .hw_free = neo1973_voice_hw_free,
172 };
173
174 static int gta02_speaker_enabled;
175
176 static int lm4853_set_spk(struct snd_kcontrol *kcontrol,
177         struct snd_ctl_elem_value *ucontrol)
178 {
179         gta02_speaker_enabled = ucontrol->value.integer.value[0];
180
181         gpio_set_value(S3C2410_GPJ(2), !gta02_speaker_enabled);
182
183         return 0;
184 }
185
186 static int lm4853_get_spk(struct snd_kcontrol *kcontrol,
187         struct snd_ctl_elem_value *ucontrol)
188 {
189         ucontrol->value.integer.value[0] = gta02_speaker_enabled;
190         return 0;
191 }
192
193 static int lm4853_event(struct snd_soc_dapm_widget *w,
194                         struct snd_kcontrol *k, int event)
195 {
196         gpio_set_value(S3C2410_GPJ(1), SND_SOC_DAPM_EVENT_OFF(event));
197
198         return 0;
199 }
200
201 static const struct snd_soc_dapm_widget neo1973_wm8753_dapm_widgets[] = {
202         SND_SOC_DAPM_LINE("GSM Line Out", NULL),
203         SND_SOC_DAPM_LINE("GSM Line In", NULL),
204         SND_SOC_DAPM_MIC("Headset Mic", NULL),
205         SND_SOC_DAPM_MIC("Handset Mic", NULL),
206         SND_SOC_DAPM_SPK("Handset Spk", NULL),
207         SND_SOC_DAPM_SPK("Stereo Out", lm4853_event),
208 };
209
210 static const struct snd_soc_dapm_route neo1973_wm8753_routes[] = {
211         /* Connections to the GSM Module */
212         {"GSM Line Out", NULL, "MONO1"},
213         {"GSM Line Out", NULL, "MONO2"},
214         {"RXP", NULL, "GSM Line In"},
215         {"RXN", NULL, "GSM Line In"},
216
217         /* Connections to Headset */
218         {"MIC1", NULL, "Mic Bias"},
219         {"Mic Bias", NULL, "Headset Mic"},
220
221         /* Call Mic */
222         {"MIC2", NULL, "Mic Bias"},
223         {"MIC2N", NULL, "Mic Bias"},
224         {"Mic Bias", NULL, "Handset Mic"},
225
226         /* Connect the ALC pins */
227         {"ACIN", NULL, "ACOP"},
228
229         /* Connections to the amp */
230         {"Stereo Out", NULL, "LOUT1"},
231         {"Stereo Out", NULL, "ROUT1"},
232
233         /* Call Speaker */
234         {"Handset Spk", NULL, "LOUT2"},
235         {"Handset Spk", NULL, "ROUT2"},
236 };
237
238 static const struct snd_kcontrol_new neo1973_wm8753_controls[] = {
239         SOC_DAPM_PIN_SWITCH("GSM Line Out"),
240         SOC_DAPM_PIN_SWITCH("GSM Line In"),
241         SOC_DAPM_PIN_SWITCH("Headset Mic"),
242         SOC_DAPM_PIN_SWITCH("Handset Mic"),
243         SOC_DAPM_PIN_SWITCH("Handset Spk"),
244         SOC_DAPM_PIN_SWITCH("Stereo Out"),
245
246         SOC_SINGLE_BOOL_EXT("Amp Spk Switch", 0,
247                 lm4853_get_spk,
248                 lm4853_set_spk),
249 };
250
251 static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
252 {
253         struct snd_soc_card *card = rtd->card;
254
255         /* set endpoints to default off mode */
256         snd_soc_dapm_disable_pin(&card->dapm, "GSM Line Out");
257         snd_soc_dapm_disable_pin(&card->dapm, "GSM Line In");
258         snd_soc_dapm_disable_pin(&card->dapm, "Headset Mic");
259         snd_soc_dapm_disable_pin(&card->dapm, "Handset Mic");
260         snd_soc_dapm_disable_pin(&card->dapm, "Stereo Out");
261         snd_soc_dapm_disable_pin(&card->dapm, "Handset Spk");
262
263         /* allow audio paths from the GSM modem to run during suspend */
264         snd_soc_dapm_ignore_suspend(&card->dapm, "GSM Line Out");
265         snd_soc_dapm_ignore_suspend(&card->dapm, "GSM Line In");
266         snd_soc_dapm_ignore_suspend(&card->dapm, "Headset Mic");
267         snd_soc_dapm_ignore_suspend(&card->dapm, "Handset Mic");
268         snd_soc_dapm_ignore_suspend(&card->dapm, "Stereo Out");
269         snd_soc_dapm_ignore_suspend(&card->dapm, "Handset Spk");
270
271         return 0;
272 }
273
274 static struct snd_soc_dai_link neo1973_dai[] = {
275 { /* Hifi Playback - for similatious use with voice below */
276         .name = "WM8753",
277         .stream_name = "WM8753 HiFi",
278         .platform_name = "s3c24xx-iis",
279         .cpu_dai_name = "s3c24xx-iis",
280         .codec_dai_name = "wm8753-hifi",
281         .codec_name = "wm8753.0-001a",
282         .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
283                    SND_SOC_DAIFMT_CBM_CFM,
284         .init = neo1973_wm8753_init,
285         .ops = &neo1973_hifi_ops,
286 },
287 { /* Voice via BT */
288         .name = "Bluetooth",
289         .stream_name = "Voice",
290         .cpu_dai_name = "bt-sco-pcm",
291         .codec_dai_name = "wm8753-voice",
292         .codec_name = "wm8753.0-001a",
293         .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF |
294                    SND_SOC_DAIFMT_CBS_CFS,
295         .ops = &neo1973_voice_ops,
296 },
297 };
298
299 static struct snd_soc_aux_dev neo1973_aux_devs[] = {
300         {
301                 .name = "dfbmcs320",
302                 .codec_name = "dfbmcs320.0",
303         },
304 };
305
306 static struct snd_soc_codec_conf neo1973_codec_conf[] = {
307         {
308                 .dev_name = "lm4857.0-007c",
309                 .name_prefix = "Amp",
310         },
311 };
312
313 static const struct gpio neo1973_gta02_gpios[] = {
314         { S3C2410_GPJ(2), GPIOF_OUT_INIT_HIGH, "GTA02_HP_IN" },
315         { S3C2410_GPJ(1), GPIOF_OUT_INIT_HIGH, "GTA02_AMP_SHUT" },
316 };
317
318 static struct snd_soc_card neo1973 = {
319         .name = "neo1973",
320         .owner = THIS_MODULE,
321         .dai_link = neo1973_dai,
322         .num_links = ARRAY_SIZE(neo1973_dai),
323         .aux_dev = neo1973_aux_devs,
324         .num_aux_devs = ARRAY_SIZE(neo1973_aux_devs),
325         .codec_conf = neo1973_codec_conf,
326         .num_configs = ARRAY_SIZE(neo1973_codec_conf),
327
328         .controls = neo1973_wm8753_controls,
329         .num_controls = ARRAY_SIZE(neo1973_wm8753_controls),
330         .dapm_widgets = neo1973_wm8753_dapm_widgets,
331         .num_dapm_widgets = ARRAY_SIZE(neo1973_wm8753_dapm_widgets),
332         .dapm_routes = neo1973_wm8753_routes,
333         .num_dapm_routes = ARRAY_SIZE(neo1973_wm8753_routes),
334         .fully_routed = true,
335 };
336
337 static struct platform_device *neo1973_snd_device;
338
339 static int __init neo1973_init(void)
340 {
341         int ret;
342
343         if (!machine_is_neo1973_gta02())
344                 return -ENODEV;
345
346         if (machine_is_neo1973_gta02()) {
347                 neo1973.name = "neo1973gta02";
348                 neo1973.num_aux_devs = 1;
349
350                 ret = gpio_request_array(neo1973_gta02_gpios,
351                                 ARRAY_SIZE(neo1973_gta02_gpios));
352                 if (ret)
353                         return ret;
354         }
355
356         neo1973_snd_device = platform_device_alloc("soc-audio", -1);
357         if (!neo1973_snd_device) {
358                 ret = -ENOMEM;
359                 goto err_gpio_free;
360         }
361
362         platform_set_drvdata(neo1973_snd_device, &neo1973);
363         ret = platform_device_add(neo1973_snd_device);
364
365         if (ret)
366                 goto err_put_device;
367
368         return 0;
369
370 err_put_device:
371         platform_device_put(neo1973_snd_device);
372 err_gpio_free:
373         if (machine_is_neo1973_gta02()) {
374                 gpio_free_array(neo1973_gta02_gpios,
375                                 ARRAY_SIZE(neo1973_gta02_gpios));
376         }
377         return ret;
378 }
379 module_init(neo1973_init);
380
381 static void __exit neo1973_exit(void)
382 {
383         platform_device_unregister(neo1973_snd_device);
384
385         if (machine_is_neo1973_gta02()) {
386                 gpio_free_array(neo1973_gta02_gpios,
387                                 ARRAY_SIZE(neo1973_gta02_gpios));
388         }
389 }
390 module_exit(neo1973_exit);
391
392 /* Module information */
393 MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org, www.openmoko.org");
394 MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973 and Frerunner");
395 MODULE_LICENSE("GPL");