Audio: delete codec_set_spk, update rk616 codec driver
[firefly-linux-kernel-4.4.55.git] / sound / soc / rockchip / rk_wm8994.c
1 /*
2  * rk29_wm8994.c  --  SoC audio for rockchip
3  *
4  * Driver for rockchip wm8994 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 #include <linux/module.h>
16 #include <linux/device.h>
17 #include <linux/of.h>
18 #include <linux/of_gpio.h>
19 #include <sound/core.h>
20 #include <sound/pcm.h>
21 #include <sound/soc.h>
22 #include <sound/soc-dapm.h>
23
24 #include "../codecs/wm8994.h"
25 #include "card_info.h"
26 #include "rk_pcm.h"
27 #include "rk_i2s.h"
28 #include <linux/clk.h>
29
30 #if 0
31 #define DBG(x...)       printk(KERN_INFO x)
32 #else
33 #define DBG(x...)
34 #endif
35
36 static int rk29_aif1_hw_params(struct snd_pcm_substream *substream,
37         struct snd_pcm_hw_params *params)
38 {
39         struct snd_soc_pcm_runtime *rtd = substream->private_data;
40         struct snd_soc_dai *codec_dai = rtd->codec_dai;
41         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
42         unsigned int pll_out = 0, dai_fmt = rtd->dai_link->dai_fmt;
43         int div_bclk,div_mclk;
44         int ret;
45         struct clk      *general_pll;
46
47         DBG("Enter::%s----%d\n", __FUNCTION__, __LINE__);
48
49         /* set codec DAI configuration */
50         ret = snd_soc_dai_set_fmt(codec_dai, dai_fmt);
51         if (ret < 0) {
52                 printk("%s():failed to set the format for codec side\n", __FUNCTION__);
53                 return ret;
54         }
55
56         /* set cpu DAI configuration */
57         ret = snd_soc_dai_set_fmt(cpu_dai, dai_fmt);
58         if (ret < 0) {
59                 printk("%s():failed to set the format for cpu side\n", __FUNCTION__);
60                 return ret;
61         }
62
63         switch(params_rate(params)) {
64                 case 8000:
65                 case 16000:
66                 case 24000:
67                 case 32000:
68                 case 48000:
69                         pll_out = 12288000;
70                         break;
71                 case 11025:
72                 case 22050:
73                 case 44100:
74                         pll_out = 11289600;
75                         break;
76                 default:
77                         DBG("Enter:%s, %d, Error rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
78                         return -EINVAL;
79         }
80
81 //      DBG("Enter:%s, %d, rate=%d,pll_out = %d\n",__FUNCTION__,__LINE__,params_rate(params),pll_out);  
82 #ifdef CONFIG_ARCH_RK29
83         general_pll=clk_get(NULL, "general_pll");
84         if(clk_get_rate(general_pll)>260000000)
85         {
86                 div_bclk=(pll_out/4)/params_rate(params)-1;
87                 div_mclk=3;
88         }
89         else if(clk_get_rate(general_pll)>130000000)
90         {
91                 div_bclk=(pll_out/2)/params_rate(params)-1;
92                 div_mclk=1;
93         }
94         else
95         {//96M
96                 pll_out=pll_out/4;
97                 div_bclk=(pll_out)/params_rate(params)-1;
98                 div_mclk=0;
99         }
100 #else
101         div_bclk=(pll_out/4)/params_rate(params)-1;
102         div_mclk=3;
103 #endif
104
105         DBG("func is%s,gpll=%ld,pll_out=%d,div_mclk=%d\n",__FUNCTION__,clk_get_rate(general_pll),pll_out,div_mclk);
106         ret = snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
107         if(ret < 0)
108         {
109                 DBG("rk29_hw_params_wm8994:failed to set the cpu sysclk for codec side\n"); 
110                 return ret;
111         }
112         snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK,div_bclk);
113         snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, div_mclk);
114         DBG("Enter:%s, %d, LRCK=%d\n",__FUNCTION__,__LINE__,(pll_out/4)/params_rate(params));
115
116         if(div_mclk== 3)
117         {//MCLK == 11289600 or 12288000
118                 ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1, pll_out, 0);
119                 if (ret < 0) {
120                         DBG("rk29_hw_params_wm8994:failed to set the sysclk for codec side\n"); 
121                         return ret;
122                 }
123         }
124         else
125         {
126                 /* set the codec FLL */
127                 ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1, pll_out,
128                                 params_rate(params) * 256);
129                 if (ret < 0)
130                 {
131                         printk("%s: snd_soc_dai_set_pll err =%d\n",__FUNCTION__,ret);
132                         return ret;
133                 }
134                 /* set the codec system clock */
135                 ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1,
136                                 params_rate(params) * 256, SND_SOC_CLOCK_IN);
137                 if (ret < 0)
138                 {
139                         printk("%s: snd_soc_dai_set_sysclk err =%d\n",__FUNCTION__,ret);
140                         return ret;
141                 }
142         }
143
144         return 0;
145 }
146
147 static int rk29_aif2_hw_params(struct snd_pcm_substream *substream,
148         struct snd_pcm_hw_params *params)
149 {
150         struct snd_soc_pcm_runtime *rtd = substream->private_data;
151         struct snd_soc_dai *codec_dai = rtd->codec_dai;
152         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
153         unsigned int pll_out = 0; 
154         int div_bclk,div_mclk;
155         int ret;
156         struct clk      *general_pll;
157
158         //change to 8Khz
159 //      params->intervals[SNDRV_PCM_HW_PARAM_RATE - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL].min = 8000;      
160
161         DBG("Enter:%s, %d, rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
162         
163 //      if (params_rate(params) != 8000)
164 //              return -EINVAL;
165
166         /* set codec DAI configuration */
167         ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A |
168                         SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBM_CFM);
169         if (ret < 0)
170         {
171                 printk("%s: snd_soc_dai_set_fmt err =%d\n",__FUNCTION__,ret);
172                 return ret;
173         }
174         switch(params_rate(params)) {
175                 case 8000:
176                 case 16000:
177                 case 24000:
178                 case 32000:
179                 case 48000:
180                         pll_out = 12288000;
181                         break;
182                 case 11025:
183                 case 22050:
184                 case 44100:
185                         pll_out = 11289600;
186                         break;
187                 default:
188                         DBG("Enter:%s, %d, Error rate=%d\n",__FUNCTION__,__LINE__,params_rate(params));
189                         return -EINVAL;
190         }
191         
192         general_pll=clk_get(NULL, "general_pll");
193         if(clk_get_rate(general_pll)>260000000)
194         {
195                 div_bclk=(pll_out/4)/params_rate(params)-1;
196                 div_mclk=3;
197         }
198         else if(clk_get_rate(general_pll)>130000000)
199         {
200                 div_bclk=(pll_out/2)/params_rate(params)-1;
201                 div_mclk=1;
202         }
203         else
204         {//96M
205                 pll_out=pll_out/4;
206                 div_bclk=(pll_out)/params_rate(params)-1;
207                 div_mclk=0;
208         }
209
210         DBG("func is%s,gpll=%ld,pll_out=%d,div_mclk=%d\n",
211                         __FUNCTION__,clk_get_rate(general_pll),pll_out,div_mclk);
212         
213         ret = snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
214         if(ret < 0)
215         {
216                 DBG("rk29_hw_params_wm8994:failed to set the cpu sysclk for codec side\n"); 
217                 return ret;
218         }
219         snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK,div_bclk);
220         snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, div_mclk);
221         DBG("Enter:%s, %d, LRCK=%d\n",__FUNCTION__,__LINE__,(pll_out/4)/params_rate(params));
222
223         /* set the codec FLL */
224         ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, WM8994_FLL_SRC_MCLK1, pll_out,
225                         8000 * 256);
226         if (ret < 0)
227         {
228                 printk("%s: snd_soc_dai_set_pll err =%d\n",__FUNCTION__,ret);
229                 return ret;
230         }
231         /* set the codec system clock */
232         ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2,
233                         8000 * 256, SND_SOC_CLOCK_IN);
234         if (ret < 0)
235         {
236                 printk("%s: snd_soc_dai_set_sysclk err =%d\n",__FUNCTION__,ret);
237                 return ret;
238         }
239
240         return ret;
241 }
242
243
244 static const struct snd_soc_dapm_widget rk29_dapm_widgets[] = {
245         SND_SOC_DAPM_SPK("Ext Left Spk", NULL),
246         SND_SOC_DAPM_SPK("Ext Right Spk", NULL),
247         SND_SOC_DAPM_SPK("Ext Rcv", NULL),
248         SND_SOC_DAPM_HP("Headset Stereophone", NULL),
249         SND_SOC_DAPM_MIC("Headset Mic", NULL),
250         SND_SOC_DAPM_MIC("Main Mic", NULL),
251         SND_SOC_DAPM_MIC("2nd Mic", NULL),
252 //      SND_SOC_DAPM_LINE("Radio In", NULL),
253         SND_SOC_DAPM_LINE("Line In", NULL),
254         SND_SOC_DAPM_LINE("Line Out", NULL),    
255
256 };
257
258 static const struct snd_soc_dapm_route rk29_dapm_routes[] = {
259         {"Ext Left Spk", NULL, "SPKOUTLP"},
260         {"Ext Left Spk", NULL, "SPKOUTLN"},
261
262         {"Ext Right Spk", NULL, "SPKOUTRP"},
263         {"Ext Right Spk", NULL, "SPKOUTRN"},
264
265         {"Ext Rcv", NULL, "HPOUT2N"},
266         {"Ext Rcv", NULL, "HPOUT2P"},
267
268         {"Headset Stereophone", NULL, "HPOUT1L"},
269         {"Headset Stereophone", NULL, "HPOUT1R"},
270
271         {"IN1LN", NULL, "Headset Mic"},
272         {"IN1LP", NULL, "Headset Mic"},
273
274         {"IN1LN", NULL, "2nd Mic"},
275         {"IN1LP", NULL, "2nd Mic"},
276
277         {"IN1RN", NULL, "Main Mic"},
278         {"IN1RP", NULL, "Main Mic"},
279
280 //      {"IN2LN", NULL, "Radio In"},
281 //      {"IN2RN", NULL, "Radio In"},
282
283         {"IN2LP:VXRN", NULL, "Line In"},
284         {"IN2RP:VXRP", NULL, "Line In"},
285         
286         {"Line Out", NULL, "LINEOUT1N"},
287         {"Line Out", NULL, "LINEOUT1P"},
288
289 };
290
291 static int rk29_wm8994_init(struct snd_soc_pcm_runtime *rtd)
292 {
293         struct snd_soc_codec *codec = rtd->codec;
294         struct snd_soc_dapm_context *dapm = &codec->dapm;
295 //      int ret;
296         DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
297
298         /* add goni specific widgets */
299         snd_soc_dapm_new_controls(dapm, rk29_dapm_widgets,
300                         ARRAY_SIZE(rk29_dapm_widgets));
301
302         /* set up goni specific audio routes */
303         snd_soc_dapm_add_routes(dapm, rk29_dapm_routes,
304                         ARRAY_SIZE(rk29_dapm_routes));
305
306         /* set endpoints to not connected */
307 //      snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN");
308 //      snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP");
309         snd_soc_dapm_nc_pin(dapm, "IN2LN");
310         snd_soc_dapm_nc_pin(dapm, "IN2RN");
311 //      snd_soc_dapm_nc_pin(dapm, "LINEOUT1N");
312 //      snd_soc_dapm_nc_pin(dapm, "LINEOUT1P");
313         snd_soc_dapm_nc_pin(dapm, "LINEOUT2N");
314         snd_soc_dapm_nc_pin(dapm, "LINEOUT2P");
315
316         snd_soc_dapm_sync(dapm);
317
318         /* Headset jack detection */
319 /*      ret = snd_soc_jack_new(codec, "Headset Jack",
320                         SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT,
321                         &jack);
322         if (ret)
323                 return ret;
324
325         ret = snd_soc_jack_add_pins(&jack, ARRAY_SIZE(jack_pins), jack_pins);
326         if (ret)
327                 return ret;
328
329         ret = snd_soc_jack_add_gpios(&jack, ARRAY_SIZE(jack_gpios), jack_gpios);
330         if (ret)
331                 return ret;
332 */
333         return 0;
334 }
335
336
337 static struct snd_soc_ops rk29_aif1_ops = {
338           .hw_params = rk29_aif1_hw_params,
339 };
340
341 static struct snd_soc_ops rk29_aif2_ops = {
342           .hw_params = rk29_aif2_hw_params,
343 };
344
345 static struct snd_soc_dai_driver voice_dai = {
346         .name = "rk29-voice-dai",
347         .id = 0,
348         .playback = {
349                 .channels_min = 1,
350                 .channels_max = 2,
351                 .rates = SNDRV_PCM_RATE_8000,
352                 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
353         .capture = {
354                 .channels_min = 1,
355                 .channels_max = 2,
356                 .rates = SNDRV_PCM_RATE_8000,
357                 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
358 };
359
360 static struct snd_soc_dai_link rk29_dai[] = {
361         {
362                 .name = "WM8994 I2S1",
363                 .stream_name = "WM8994 PCM",
364                 .codec_dai_name = "wm8994-aif1",
365                 .ops = &rk29_aif1_ops,
366                 .init = rk29_wm8994_init,
367         },
368         {
369                 .name = "WM8994 I2S2",
370                 .stream_name = "WM8994 PCM",
371                 .codec_dai_name = "wm8994-aif2",
372                 .ops = &rk29_aif2_ops,
373         },
374 };
375
376 static struct snd_soc_card rockchip_wm8994_snd_card = {
377         .name = "RK_WM8994",
378         .dai_link = rk29_dai,
379         .num_links = ARRAY_SIZE(rk29_dai),
380 };
381
382 static int rockchip_wm8994_audio_probe(struct platform_device *pdev)
383 {
384         int ret;
385         struct snd_soc_card *card = &rockchip_wm8994_snd_card;
386
387         card->dev = &pdev->dev;
388
389         ret = rockchip_of_get_sound_card_info(card);
390         if (ret) {
391                 printk("%s() get sound card info failed:%d\n", __FUNCTION__, ret);
392                 return ret;
393         }
394
395         ret = snd_soc_register_card(card);
396         if (ret)
397                 printk("%s() register card failed:%d\n", __FUNCTION__, ret);
398
399         return ret;
400 }
401
402 static int rockchip_wm8994_audio_remove(struct platform_device *pdev)
403 {
404         struct snd_soc_card *card = platform_get_drvdata(pdev);
405
406         snd_soc_unregister_card(card);
407
408         return 0;
409 }
410
411 #ifdef CONFIG_OF
412 static const struct of_device_id rockchip_wm8994_of_match[] = {
413         { .compatible = "rockchip-wm8994", },
414         {},
415 };
416 MODULE_DEVICE_TABLE(of, rockchip_wm8994_of_match);
417 #endif /* CONFIG_OF */
418
419 static struct platform_driver rockchip_wm8994_audio_driver = {
420         .driver         = {
421                 .name   = "rockchip-wm8994",
422                 .owner  = THIS_MODULE,
423                 .of_match_table = of_match_ptr(rockchip_wm8994_of_match),
424         },
425         .probe          = rockchip_wm8994_audio_probe,
426         .remove         = rockchip_wm8994_audio_remove,
427 };
428
429 module_platform_driver(rockchip_wm8994_audio_driver);
430
431 /* Module information */
432 MODULE_AUTHOR("rockchip");
433 MODULE_DESCRIPTION("ROCKCHIP i2s ASoC Interface");
434 MODULE_LICENSE("GPL");