Audio: update dai_fmt setting, fix i2s unlock error, rename codec-of-node and cpu...
[firefly-linux-kernel-4.4.55.git] / sound / soc / rockchip / rk_rk3026.c
1 /*
2  * rk_rk3026.c  --  SoC audio for rockchip
3  *
4  * Driver for rockchip rk3026 audio
5  *
6  *  This program is free software; you can redistribute  it and/or modify it
7  *  under  the terms of  the GNU General  Public License as published by the
8  *  Free Software Foundation;  either version 2 of the  License, or (at your
9  *  option) any later version.
10  *
11  *
12  */
13
14 #include <linux/module.h>
15 #include <linux/device.h>
16 #include <linux/of.h>
17 #include <linux/of_gpio.h>
18 #include <sound/core.h>
19 #include <sound/pcm.h>
20 #include <sound/soc.h>
21 #include <sound/soc-dapm.h>
22
23 #include "../codecs/rk3026_codec.h"
24 #include "card_info.h"
25 #include "rk_pcm.h"
26 #include "rk_i2s.h"
27
28 #if 0
29 #define DBG(x...)       printk(KERN_INFO x)
30 #else
31 #define DBG(x...)
32 #endif
33
34 static const struct snd_soc_dapm_widget rk_dapm_widgets[] = {
35         SND_SOC_DAPM_MIC("Mic Jack", NULL),
36         SND_SOC_DAPM_MIC("Headset Jack", NULL),
37         SND_SOC_DAPM_SPK("Ext Spk", NULL),
38         SND_SOC_DAPM_HP("Headphone Jack", NULL),
39 };
40
41 static const struct snd_soc_dapm_route rk_audio_map[]={
42
43         /* Mic Jack --> MIC_IN*/
44         {"Mic Bias", NULL, "Mic Jack"},
45         {"MICP", NULL, "Mic Bias"},
46         {"MICN", NULL, "Mic Bias"},
47
48         // HP MIC
49         {"Mic Bias", NULL, "Headset Jack"},
50
51         {"Ext Spk", NULL, "HPOUTR"},
52         {"Ext Spk", NULL, "HPOUTL"},
53
54         {"Headphone Jack", NULL, "HPOUTR"},
55         {"Headphone Jack", NULL, "HPOUTL"},
56 } ;
57
58 static const struct snd_kcontrol_new rk_controls[] = {
59         SOC_DAPM_PIN_SWITCH("Mic Jack"),
60         SOC_DAPM_PIN_SWITCH("Headset Jack"),
61         SOC_DAPM_PIN_SWITCH("Ext Spk"),
62         SOC_DAPM_PIN_SWITCH("Headphone Jack"),
63 };
64
65 static int rk3026_init(struct snd_soc_pcm_runtime *rtd)
66 {
67         struct snd_soc_codec *codec = rtd->codec;
68         struct snd_soc_dapm_context *dapm = &codec->dapm;
69
70         DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
71
72         snd_soc_add_codec_controls(codec, rk_controls,
73                         ARRAY_SIZE(rk_controls));
74
75         /* Add specific widgets */
76         snd_soc_dapm_new_controls(dapm, rk_dapm_widgets,
77                                   ARRAY_SIZE(rk_dapm_widgets));
78         /* Set up specific audio path audio_mapnects */
79         snd_soc_dapm_add_routes(dapm, rk_audio_map, ARRAY_SIZE(rk_audio_map));
80
81         snd_soc_dapm_enable_pin(dapm, "Mic Jack");
82         snd_soc_dapm_enable_pin(dapm, "Headset Jack");
83         snd_soc_dapm_enable_pin(dapm, "Ext Spk");
84         snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
85
86         snd_soc_dapm_sync(dapm);
87
88         return 0;
89 }
90
91 static int rk_hifi_hw_params(struct snd_pcm_substream *substream,
92         struct snd_pcm_hw_params *params)
93 {
94         struct snd_soc_pcm_runtime *rtd = substream->private_data;
95         struct snd_soc_dai *codec_dai = rtd->codec_dai;
96         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
97         unsigned int pll_out = 0, dai_fmt = rtd->dai_link->dai_fmt;
98         int ret;
99
100         DBG("Enter::%s----%d\n", __FUNCTION__, __LINE__);
101
102         /* set codec DAI configuration */
103         ret = snd_soc_dai_set_fmt(codec_dai, dai_fmt);
104         if (ret < 0) {
105                 printk("%s():failed to set the format for codec side\n", __FUNCTION__);
106                 return ret;
107         }
108
109         /* set cpu DAI configuration */
110         ret = snd_soc_dai_set_fmt(cpu_dai, dai_fmt);
111         if (ret < 0) {
112                 printk("%s():failed to set the format for cpu side\n", __FUNCTION__);
113                 return ret;
114         }
115
116         switch(params_rate(params)) {
117                 case 8000:
118                 case 16000:
119                 case 24000:
120                 case 32000:
121                 case 48000:
122                         pll_out = 12288000;
123                         break;
124                 case 11025:
125                 case 22050:
126                 case 44100:
127                         pll_out = 11289600;
128                         break;
129                 default:
130                         DBG("Enter:%s, %d, Error rate=%d\n", __FUNCTION__, __LINE__, params_rate(params));
131                         return -EINVAL;
132                         break;
133         }
134
135         DBG("Enter:%s, %d, rate=%d\n", __FUNCTION__, __LINE__, params_rate(params));
136
137         /*Set the system clk for codec*/
138         ret = snd_soc_dai_set_sysclk(codec_dai, 0, pll_out, SND_SOC_CLOCK_IN);
139         if (ret < 0) {
140                 DBG("rk_hifi_hw_params:failed to set the sysclk for codec side\n");
141                 return ret;
142         }
143
144         snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
145         snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_BCLK, (pll_out/4)/params_rate(params)-1);
146         snd_soc_dai_set_clkdiv(cpu_dai, ROCKCHIP_DIV_MCLK, 3);
147
148         DBG("Enter:%s, %d, pll_out/4/params_rate(params) = %d \n", __FUNCTION__, __LINE__, (pll_out/4)/params_rate(params));
149
150         return 0;
151 }
152
153 static int rk_voice_hw_params(struct snd_pcm_substream *substream,
154         struct snd_pcm_hw_params *params)
155 {
156         struct snd_soc_pcm_runtime *rtd = substream->private_data;
157         struct snd_soc_dai *codec_dai = rtd->codec_dai;
158         struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
159         unsigned int pll_out = 0, dai_fmt = rtd->dai_link->dai_fmt;
160         int ret;
161
162         DBG("Enter::%s----%d\n", __FUNCTION__, __LINE__);
163
164         /* set codec DAI configuration */
165         ret = snd_soc_dai_set_fmt(codec_dai, dai_fmt);
166         if (ret < 0) {
167                 printk("%s():failed to set the format for codec side\n", __FUNCTION__);
168                 return ret;
169         }
170
171         /* set codec DAI configuration */
172         ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A |
173                                 SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS);
174
175         switch(params_rate(params)) {
176                 case 8000:
177                 case 16000:
178                 case 24000:
179                 case 32000:
180                 case 48000:
181                         pll_out = 12288000;
182                         break;
183                 case 11025:
184                 case 22050:
185                 case 44100:
186                         pll_out = 11289600;
187                         break;
188                 default:
189                         DBG("Enter:%s, %d, Error rate=%d\n", __FUNCTION__, __LINE__, params_rate(params));
190                         return -EINVAL;
191                         break;
192         }
193
194         /*Set the system clk for codec*/
195         ret = snd_soc_dai_set_sysclk(codec_dai, 0, pll_out, SND_SOC_CLOCK_IN);
196
197         if (ret < 0) {
198                 printk("rk_voice_hw_params:failed to set the sysclk for codec side\n");
199                 return ret;
200         }
201
202         ret = snd_soc_dai_set_sysclk(cpu_dai, 0, pll_out, 0);
203
204         return 0;
205 }
206
207 static struct snd_soc_ops rk3026_hifi_ops = {
208         .hw_params = rk_hifi_hw_params,
209 };
210
211 static struct snd_soc_ops rk3026_voice_ops = {
212         .hw_params = rk_voice_hw_params,
213 };
214
215 static struct snd_soc_dai_link rk_dai[] = {
216         {
217                 .name = "RK3026 I2S1",
218                 .stream_name = "RK3026 PCM",
219                 .codec_dai_name = "rk3026-hifi",
220                 .init = rk3026_init,
221                 .ops = &rk3026_hifi_ops,
222         },
223         {
224                 .name = "RK3026 I2S2",
225                 .stream_name = "RK3026 PCM",
226                 .codec_dai_name = "rk3026-voice",
227                 .ops = &rk3026_voice_ops,
228         },
229 };
230
231 static struct snd_soc_card rockchip_rk3026_snd_card = {
232         .name = "RK_RK3026",
233         .dai_link = rk_dai,
234         .num_links = 2,
235 };
236
237 static int rockchip_rk3026_audio_probe(struct platform_device *pdev)
238 {
239         int ret;
240         struct snd_soc_card *card = &rockchip_rk3026_snd_card;
241
242         card->dev = &pdev->dev;
243
244         ret = rockchip_of_get_sound_card_info(card);
245         if (ret) {
246                 printk("%s() get sound card info failed:%d\n", __FUNCTION__, ret);
247                 return ret;
248         }
249
250         ret = snd_soc_register_card(card);
251         if (ret)
252                 printk("%s() register card failed:%d\n", __FUNCTION__, ret);
253
254         return ret;
255 }
256
257 static int rockchip_rk3026_audio_remove(struct platform_device *pdev)
258 {
259         struct snd_soc_card *card = platform_get_drvdata(pdev);
260
261         snd_soc_unregister_card(card);
262
263         return 0;
264 }
265
266 #ifdef CONFIG_OF
267 static const struct of_device_id rockchip_rk3026_of_match[] = {
268         { .compatible = "rockchip-rk3026", },
269         {},
270 };
271 MODULE_DEVICE_TABLE(of, rockchip_rk3026_of_match);
272 #endif /* CONFIG_OF */
273
274 static struct platform_driver rockchip_rk3026_audio_driver = {
275         .driver         = {
276                 .name   = "rockchip-rk3026",
277                 .owner  = THIS_MODULE,
278                 .of_match_table = of_match_ptr(rockchip_rk3026_of_match),
279         },
280         .probe          = rockchip_rk3026_audio_probe,
281         .remove         = rockchip_rk3026_audio_remove,
282 };
283
284 module_platform_driver(rockchip_rk3026_audio_driver);
285
286 /* Module information */
287 MODULE_AUTHOR("rockchip");
288 MODULE_DESCRIPTION("ROCKCHIP i2s ASoC Interface");
289 MODULE_LICENSE("GPL");