Audio:
[firefly-linux-kernel-4.4.55.git] / sound / soc / rockchip / rk_aic3262.c
1 /*
2  * rk29_aic3262.c  --  SoC audio for rockchip
3  *
4  * Driver for rockchip aic3262 audio
5  *  Copyright (C) 2009 lhh
6  *
7  *  This program is free software; you can redistribute  it and/or modify it
8  *  under  the terms of  the GNU General  Public License as published by the
9  *  Free Software Foundation;  either version 2 of the  License, or (at your
10  *  option) any later version.
11  *
12  *
13  */
14
15 #define DEBUG 1
16 #include <linux/clk.h>
17 #include <linux/platform_device.h>
18 #include <linux/i2c.h>
19 #include <linux/i2c/twl.h>
20 #include <linux/regulator/consumer.h>
21 #include <sound/core.h>
22 #include <sound/pcm.h>
23 #include <sound/pcm_params.h>
24 #include <sound/soc.h>
25 #include <sound/soc-dapm.h>
26 #include <sound/jack.h>
27 #include <linux/switch.h>
28 #include <linux/irq.h>
29 #include <linux/interrupt.h>
30 #include <linux/gpio.h>
31 #include <linux/of.h>
32 #include <linux/of_gpio.h>
33
34 #include <asm/mach-types.h>
35 #include <linux/module.h>
36 #include <linux/device.h>
37
38 #include "../codecs/wm8994.h"
39 #include "card_info.h"
40 #include "rk_pcm.h"
41 #include "rk_i2s.h"
42 #include <linux/clk.h>
43 #include <linux/mfd/tlv320aic3262-registers.h>
44 #include "../codecs/tlv320aic326x.h"
45
46 #if 0
47 #define DBG_AIC3262(x...)       printk(KERN_INFO x)
48 #else
49 #define DBG_AIC3262(x...)
50 #endif
51
52 //struct regulator *vddhf_reg=NULL;
53
54 /* Headset jack */
55 //static struct snd_soc_jack hs_jack;
56
57 /*Headset jack detection DAPM pins */
58 /*static struct snd_soc_jack_pin hs_jack_pins[] = {
59         {
60                 .pin = "Headset Mic",
61                 .mask = SND_JACK_MICROPHONE,
62         },
63         {
64                 .pin = "Headset Stereophone",
65                 .mask = SND_JACK_HEADPHONE,
66         },
67 };
68
69 static int spk_event(struct snd_soc_dapm_widget *w,
70                 struct snd_kcontrol *kcontrol, int event)
71 {
72         //struct snd_soc_codec *codec = w->codec;
73         int ret;
74         if (SND_SOC_DAPM_EVENT_ON(event)) {
75
76                         printk(" I am NULL is %d event is %d\n",vddhf_reg,event);
77
78                         if (vddhf_reg) {
79                             ret = regulator_enable(vddhf_reg);
80                             if(ret) {
81                                     printk("failed to enable vddhf \n");
82                                     return ret;
83                             }
84                         }
85         }
86         else {
87
88             if (vddhf_reg) {
89                 ret = regulator_disable(vddhf_reg);
90                 if (ret) {
91                         printk("failed to disable "
92                                 "VDDHF regulator %d\n", ret);
93                         return ret;
94                 }
95             }
96         }
97         return 0;
98 }*/
99
100
101
102 /* rk29 machine DAPM */
103 static const struct snd_soc_dapm_widget rk29_aic3262_dapm_widgets[] = {
104         SND_SOC_DAPM_MIC("Ext Mic", NULL),
105         SND_SOC_DAPM_SPK("Ext Spk", NULL),
106         SND_SOC_DAPM_MIC("Headset Mic", NULL),
107         SND_SOC_DAPM_HP("Headset Stereophone", NULL),
108         SND_SOC_DAPM_SPK("Earphone Spk", NULL),
109         SND_SOC_DAPM_INPUT("FM Stereo In"),
110         SND_SOC_DAPM_LINE("FM Stereo Out",NULL),
111 };
112
113 static const struct snd_soc_dapm_route audio_map[] = {
114         /* External Mics: MAINMIC, SUBMIC with bias*/
115         {"IN1L", NULL, "Mic Bias Int"},
116         {"IN1R", NULL, "Mic Bias Int"},
117         {"IN4L", NULL, "Mic Bias Int"},
118         {"IN4R", NULL, "Mic Bias Int"},
119         {"Mic Bias Int", NULL, "Ext Mic"},
120
121         /* External Speakers: HFL, HFR */
122         {"Ext Spk", NULL, "SPKL"},
123         {"Ext Spk", NULL, "SPKR"},
124
125         /* Headset Mic: HSMIC with bias */
126         {"IN2L", NULL, "Mic Bias Ext"},
127         {"IN2R", NULL, "Mic Bias Ext"},
128         {"Mic Bias Ext", NULL, "Headset Mic"},
129
130         /* Headset Stereophone (Headphone): HPL, HPR */
131         {"Headset Stereophone", NULL, "HPL"},
132         {"Headset Stereophone", NULL, "HPR"},
133
134         /* Earphone speaker */
135         {"Earphone Spk", NULL, "RECP"},
136         {"Earphone Spk", NULL, "RECM"},
137
138         /* Aux/FM Stereo In: IN4L, IN4R */
139         {"IN3L", NULL, "FM Stereo In"},
140         {"IN3R", NULL, "FM Stereo In"},
141         
142         /* Aux/FM Stereo Out: LOL, LOR */
143         {"FM Stereo Out", NULL, "LOL"},
144         {"FM Stereo Out", NULL, "LOR"},
145 };
146
147 static const struct snd_kcontrol_new rk29_aic326x_controls[] = {
148         SOC_DAPM_PIN_SWITCH("Ext Mic"),
149         SOC_DAPM_PIN_SWITCH("Ext Spk"),
150         SOC_DAPM_PIN_SWITCH("Headset Mic"),
151         SOC_DAPM_PIN_SWITCH("Headset Stereophone"),
152         SOC_DAPM_PIN_SWITCH("Earphone Spk"),
153         SOC_DAPM_PIN_SWITCH("FM Stereo In"),
154         SOC_DAPM_PIN_SWITCH("FM Stereo Out"),
155 };
156
157 static int rk29_aic3262_init(struct snd_soc_pcm_runtime *rtd)
158 {
159         struct snd_soc_codec *codec = rtd->codec;
160         struct snd_soc_dapm_context *dapm = &codec->dapm;
161         int ret;
162
163         DBG_AIC3262("rk29_aic3262_init\n");
164
165         /* Headset jack detection */
166         /*ret = snd_soc_jack_new(codec, "Headset Jack",
167                                 SND_JACK_HEADSET, &hs_jack);
168         if (ret)
169                 return ret;
170
171     ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
172                             hs_jack_pins);  
173     aic3262_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET);*/
174        
175     /* don't wait before switching of HS power */
176         rtd->pmdown_time = 0;
177         return ret;
178 }
179
180 static int rk29_aif1_hw_params(struct snd_pcm_substream *substream,
181         struct snd_pcm_hw_params *params)
182 {
183         struct snd_soc_pcm_runtime *rtd = substream->private_data;
184         struct snd_soc_dai *codec_dai = rtd->codec_dai;
185         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
186         unsigned int pll_out = 0, dai_fmt = rtd->dai_link->dai_fmt;
187         int div_bclk,div_mclk;
188         int ret;
189
190         DBG("Enter::%s----%d\n", __FUNCTION__, __LINE__);
191
192         /* set codec DAI configuration */
193         ret = snd_soc_dai_set_fmt(codec_dai, dai_fmt);
194         if (ret < 0) {
195                 printk("%s():failed to set the format for codec side\n", __FUNCTION__);
196                 return ret;
197         }
198
199         /* set cpu DAI configuration */
200         ret = snd_soc_dai_set_fmt(cpu_dai, dai_fmt);
201         if (ret < 0) {
202                 printk("%s():failed to set the format for cpu side\n", __FUNCTION__);
203                 return ret;
204         }
205
206         switch(params_rate(params)) {
207                 case 8000:
208                 case 16000:
209                 case 24000:
210                 case 32000:
211                 case 48000:
212                         pll_out = 12288000;
213                         break;
214                 case 11025:
215                 case 22050:
216                 case 44100:
217                         pll_out = 11289600;
218                         break;
219                 default:
220                         DBG_AIC3262("Enter:%s, %d, Error rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
221                         return -EINVAL;
222         }
223
224  
225         div_bclk=(pll_out/4)/params_rate(params)-1;
226         div_mclk=3;
227         
228         DBG_AIC3262(" %s, pll_out=%d, div_bclk=%d, div_mclk=%d\n",__FUNCTION__,pll_out,div_bclk,div_mclk);
229         ret = snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
230         if(ret < 0)
231         {
232                 DBG_AIC3262("rk29_hw_params_aic3262:failed to set the cpu sysclk for codec side\n"); 
233                 return ret;
234         }
235         snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK, div_bclk);
236         snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, div_mclk);
237         DBG_AIC3262("Enter:%s, %d, LRCK=%d\n",__FUNCTION__,__LINE__,(pll_out/4)/params_rate(params));
238
239         //MCLK == 11289600 or 12288000
240         ret = snd_soc_dai_set_sysclk(codec_dai, 0, pll_out, 0);
241         if (ret < 0) {
242                 DBG_AIC3262("rk29_hw_params_aic3262:failed to set the sysclk for codec side\n"); 
243                 return ret;
244         }
245         
246         return ret;
247 }
248
249 static int rk29_aif2_hw_params(struct snd_pcm_substream *substream,
250         struct snd_pcm_hw_params *params)
251 {
252         struct snd_soc_pcm_runtime *rtd = substream->private_data;
253         struct snd_soc_dai *codec_dai = rtd->codec_dai;
254         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
255         unsigned int pll_out = 0; 
256         int div_bclk,div_mclk;
257         int ret;        
258
259         DBG("Enter:%s, %d, rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
260
261         /* set codec DAI configuration */
262         ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J |
263                         SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
264         if (ret < 0)
265         {
266                 printk("%s: snd_soc_dai_set_fmt err =%d\n",__FUNCTION__,ret);
267                 return ret;
268         }
269         switch(params_rate(params)) {
270                 case 8000:
271                 case 16000:
272                 case 24000:
273                 case 32000:
274                 case 48000:
275                         pll_out = 12288000;
276                         break;
277                 case 11025:
278                 case 22050:
279                 case 44100:
280                         pll_out = 11289600;
281                         break;
282                 default:
283                         DBG("Enter:%s, %d, Error rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
284                         return -EINVAL;
285         }
286                 
287         div_bclk=(pll_out/4)/params_rate(params)-1;
288         div_mclk=3;
289         
290         DBG_AIC3262(" %s, pll_out=%d, div_bclk=%d, div_mclk=%d\n",__FUNCTION__,pll_out,div_bclk,div_mclk);
291         
292         ret = snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
293         if(ret < 0)
294         {
295                 DBG("rk29_hw_params_aic3262:failed to set the cpu sysclk for codec side\n"); 
296                 return ret;
297         }
298         snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK, div_bclk);
299         snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, div_mclk);
300         DBG("Enter:%s, %d, LRCK=%d\n",__FUNCTION__,__LINE__,(pll_out/4)/params_rate(params));
301
302         /* set the codec system clock */
303         ret = snd_soc_dai_set_sysclk(codec_dai, 0, pll_out, 0);
304         if (ret < 0)
305         {
306                 printk("%s: snd_soc_dai_set_sysclk err =%d\n",__FUNCTION__,ret);
307                 return ret;
308         }
309
310         /* set the codec FLL */
311         ret = snd_soc_dai_set_pll(codec_dai, 0, AIC3262_PLL_CLKIN_MCLK1 , pll_out, 8000*256);
312         if (ret < 0)
313         {
314                 printk("%s: snd_soc_dai_set_pll err =%d\n",__FUNCTION__,ret);
315                 return ret;
316         }
317
318         return ret;
319 }
320
321 static int rk29_aif3_hw_params(struct snd_pcm_substream *substream,
322         struct snd_pcm_hw_params *params)
323 {
324         struct snd_soc_pcm_runtime *rtd = substream->private_data;
325         struct snd_soc_dai *codec_dai = rtd->codec_dai;
326         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
327         unsigned int pll_out = 0; 
328         int div_bclk,div_mclk;
329         int ret;        
330
331         DBG("Enter:%s, %d, rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
332
333         /* set codec DAI configuration */
334         ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J |
335                         SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
336         if (ret < 0)
337         {
338                 printk("%s: snd_soc_dai_set_fmt err =%d\n",__FUNCTION__,ret);
339                 return ret;
340         }
341         switch(params_rate(params)) {
342                 case 8000:
343                 case 16000:
344                 case 24000:
345                 case 32000:
346                 case 48000:
347                         pll_out = 12288000;
348                         break;
349                 case 11025:
350                 case 22050:
351                 case 44100:
352                         pll_out = 11289600;
353                         break;
354                 default:
355                         DBG("Enter:%s, %d, Error rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
356                         return -EINVAL;
357         }
358                 
359         div_bclk=(pll_out/4)/params_rate(params)-1;
360         div_mclk=3;
361         
362         DBG_AIC3262(" %s, pll_out=%d, div_bclk=%d, div_mclk=%d\n",__FUNCTION__,pll_out,div_bclk,div_mclk);
363         
364         ret = snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
365         if(ret < 0)
366         {
367                 DBG("rk29_hw_params_aic3262:failed to set the cpu sysclk for codec side\n"); 
368                 return ret;
369         }
370         snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK, div_bclk);
371         snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, div_mclk);
372         DBG("Enter:%s, %d, LRCK=%d\n",__FUNCTION__,__LINE__,(pll_out/4)/params_rate(params));
373
374         /* set the codec system clock */
375         ret = snd_soc_dai_set_sysclk(codec_dai, 0, pll_out, 0);
376         if (ret < 0)
377         {
378                 printk("%s: snd_soc_dai_set_sysclk err =%d\n",__FUNCTION__,ret);
379                 return ret;
380         }
381
382         /* set the codec FLL */
383         ret = snd_soc_dai_set_pll(codec_dai, 0, AIC3262_PLL_CLKIN_MCLK1 , pll_out, 8000*256);
384         if (ret < 0)
385         {
386                 printk("%s: snd_soc_dai_set_pll err =%d\n",__FUNCTION__,ret);
387                 return ret;
388         }
389
390         return ret;
391 }
392
393 static struct snd_soc_ops rk29_aif1_ops = {
394           .hw_params = rk29_aif1_hw_params,
395 };
396
397 static struct snd_soc_ops rk29_aif2_ops = {
398           .hw_params = rk29_aif2_hw_params,
399 };
400
401 static struct snd_soc_ops rk29_aif3_ops = {
402           .hw_params = rk29_aif3_hw_params,
403 };
404
405 static struct snd_soc_dai_link rk29_dai[] = {
406
407         {
408                 .name = "AIC3262 I2S1",
409                 .stream_name = "AIC3262 PCM",
410                 .codec_dai_name = "aic326x-asi1",
411                 .ops = &rk29_aif1_ops,
412                 .init = rk29_aic3262_init,
413         },
414         
415         {
416                 .name = "AIC3262 I2S2",
417                 .stream_name = "AIC3262 PCM",
418                 .codec_dai_name = "aic326x-asi2",
419                 .ops = &rk29_aif2_ops,
420         },
421
422         
423         {
424                 .name = "AIC3262 I2S3",
425                 .stream_name = "AIC3262 PCM",
426                 .codec_dai_name = "aic326x-asi3",
427                 .ops = &rk29_aif3_ops,
428         },
429
430 };
431
432
433 static struct snd_soc_card rockchip_aic3262_snd_card = {
434         .name = "RK_AIC3262",
435         .dai_link = rk29_dai,
436         .num_links = ARRAY_SIZE(rk29_dai),
437         .controls = rk29_aic326x_controls,
438         .num_controls = ARRAY_SIZE(rk29_aic326x_controls),
439         .dapm_widgets    = rk29_aic3262_dapm_widgets,
440         .num_dapm_widgets = ARRAY_SIZE(rk29_aic3262_dapm_widgets),
441         .dapm_routes    = audio_map,
442         .num_dapm_routes = ARRAY_SIZE(audio_map),
443 };
444
445 static int rockchip_aic3262_audio_probe(struct platform_device *pdev)
446 {
447         int ret;
448         struct snd_soc_card *card = &rockchip_aic3262_snd_card;
449
450         card->dev = &pdev->dev;
451
452         ret = rockchip_of_get_sound_card_info(card);
453         if (ret) {
454                 printk("%s() get sound card info failed:%d\n", __FUNCTION__, ret);
455                 return ret;
456         }
457
458         ret = snd_soc_register_card(card);
459         if (ret)
460                 printk("%s() register card failed:%d\n", __FUNCTION__, ret);
461
462         return ret;
463 }
464
465 static int rockchip_aic3262_audio_remove(struct platform_device *pdev)
466 {
467         struct snd_soc_card *card = platform_get_drvdata(pdev);
468
469         snd_soc_unregister_card(card);
470
471         return 0;
472 }
473
474 #ifdef CONFIG_OF
475 static const struct of_device_id rockchip_aic3262_of_match[] = {
476         { .compatible = "rockchip-aic3262", },
477         {},
478 };
479 MODULE_DEVICE_TABLE(of, rockchip_aic3262_of_match);
480 #endif /* CONFIG_OF */
481
482 static struct platform_driver rockchip_aic3262_audio_driver = {
483         .driver         = {
484                 .name   = "rockchip-aic3262",
485                 .owner  = THIS_MODULE,
486                 .pm = &snd_soc_pm_ops,
487                 .of_match_table = of_match_ptr(rockchip_aic3262_of_match),
488         },
489         .probe          = rockchip_aic3262_audio_probe,
490         .remove         = rockchip_aic3262_audio_remove,
491 };
492
493 module_platform_driver(rockchip_aic3262_audio_driver);
494
495 /* Module information */
496 MODULE_AUTHOR("rockchip");
497 MODULE_DESCRIPTION("ROCKCHIP i2s ASoC Interface");
498 MODULE_LICENSE("GPL");
499