Revert "asoc: tegra: integration of slave mode support."
[linux-2.6.git] / sound / soc / tegra / tegra_asoc_utils.c
1 /*
2  * tegra_asoc_utils.c - Harmony machine ASoC driver
3  *
4  * Author: Stephen Warren <swarren@nvidia.com>
5  * Copyright (C) 2010 - NVIDIA, Inc.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * version 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19  * 02110-1301 USA
20  *
21  */
22
23 #include <linux/clk.h>
24 #include <linux/device.h>
25 #include <linux/err.h>
26 #include <linux/kernel.h>
27 #include <linux/module.h>
28
29 #include <mach/clk.h>
30
31 #include <sound/soc.h>
32
33 #include "tegra_pcm.h"
34 #include "tegra_asoc_utils.h"
35
36 int g_is_call_mode;
37
38 bool tegra_is_voice_call_active(void)
39 {
40         if (g_is_call_mode)
41                 return true;
42         else
43                 return false;
44 }
45 EXPORT_SYMBOL_GPL(tegra_is_voice_call_active);
46
47 static int tegra_get_avp_device(struct snd_kcontrol *kcontrol,
48                                 struct snd_ctl_elem_value *ucontrol)
49 {
50         struct  tegra_asoc_utils_data *data = snd_kcontrol_chip(kcontrol);
51
52         ucontrol->value.integer.value[0] = data->avp_device_id;
53         return 0;
54 }
55
56 static int tegra_set_avp_device(struct snd_kcontrol *kcontrol,
57                                 struct snd_ctl_elem_value *ucontrol)
58 {
59         struct  tegra_asoc_utils_data *data = snd_kcontrol_chip(kcontrol);
60         struct snd_soc_card *card = data->card;
61         struct snd_soc_pcm_runtime *rtd;
62         struct snd_pcm_substream *substream;
63         struct tegra_runtime_data *prtd;
64         int id, old_id = data->avp_device_id;
65
66         id = ucontrol->value.integer.value[0];
67         if ((id >= card->num_rtd) || (id < 0))
68                 id = -1;
69
70         if (old_id >= 0) {
71                 rtd = &card->rtd[old_id];
72                 substream =
73                         rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
74                 if (substream && substream->runtime) {
75                         prtd = substream->runtime->private_data;
76                         if (prtd->running)
77                                 return -EBUSY;
78                         if (prtd)
79                                 prtd->disable_intr = false;
80                 }
81         }
82
83         if (id >= 0) {
84                 rtd = &card->rtd[id];
85                 substream =
86                         rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
87                 if (substream && substream->runtime) {
88                         prtd = substream->runtime->private_data;
89                         if (prtd->running)
90                                 return -EBUSY;
91                         if (prtd)
92                                 prtd->disable_intr = true;
93                 }
94         }
95         data->avp_device_id = id;
96         return 1;
97 }
98
99 static int tegra_get_dma_ch_id(struct snd_kcontrol *kcontrol,
100                                struct snd_ctl_elem_value *ucontrol)
101 {
102         struct  tegra_asoc_utils_data *data = snd_kcontrol_chip(kcontrol);
103         struct snd_soc_card *card = data->card;
104         struct snd_soc_pcm_runtime *rtd;
105         struct snd_pcm_substream *substream;
106         struct tegra_runtime_data *prtd;
107
108         ucontrol->value.integer.value[0] = -1;
109         if (data->avp_device_id < 0)
110                 return 0;
111
112         rtd = &card->rtd[data->avp_device_id];
113         substream = rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
114         if (!substream || !substream->runtime)
115                 return 0;
116
117         prtd = substream->runtime->private_data;
118         if (!prtd || !prtd->dma_chan)
119                 return 0;
120
121         ucontrol->value.integer.value[0] =
122                 tegra_dma_get_channel_id(prtd->dma_chan);
123         return 0;
124 }
125
126 static int tegra_get_dma_addr(struct snd_kcontrol *kcontrol,
127                               struct snd_ctl_elem_value *ucontrol)
128 {
129         struct  tegra_asoc_utils_data *data = snd_kcontrol_chip(kcontrol);
130         struct snd_soc_card *card = data->card;
131         struct snd_soc_pcm_runtime *rtd;
132         struct snd_pcm_substream *substream;
133
134         ucontrol->value.integer.value[0] = 0;
135         if (data->avp_device_id < 0)
136                 return 0;
137
138         rtd = &card->rtd[data->avp_device_id];
139         substream = rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
140         if (!substream || !substream->runtime)
141                 return 0;
142
143         ucontrol->value.integer.value[0] = substream->runtime->dma_addr;
144         return 0;
145 }
146
147 struct snd_kcontrol_new tegra_avp_controls[] = {
148         SOC_SINGLE_EXT("AVP alsa device select", 0, 0, TEGRA_ALSA_MAX_DEVICES, \
149                         0, tegra_get_avp_device, tegra_set_avp_device),
150         SOC_SINGLE_EXT("AVP DMA channel id", 0, 0, TEGRA_DMA_MAX_CHANNELS, \
151                         0, tegra_get_dma_ch_id, NULL),
152         SOC_SINGLE_EXT("AVP DMA address", 0, 0, 0xFFFFFFFF, \
153                         0, tegra_get_dma_addr, NULL),
154 };
155
156 int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
157                               int mclk)
158 {
159         int new_baseclock;
160         bool clk_change;
161         int err;
162         bool reenable_clock;
163
164         switch (srate) {
165         case 11025:
166         case 22050:
167         case 44100:
168         case 88200:
169 #if defined(CONFIG_ARCH_TEGRA_2x_SOC)
170                 new_baseclock = 56448000;
171 #else
172                 new_baseclock = 564480000;
173 #endif
174                 break;
175         case 8000:
176         case 16000:
177         case 32000:
178         case 48000:
179         case 64000:
180         case 96000:
181 #if defined(CONFIG_ARCH_TEGRA_2x_SOC)
182                 new_baseclock = 73728000;
183 #else
184                 new_baseclock = 552960000;
185 #endif
186                 break;
187         default:
188                 return -EINVAL;
189         }
190
191         clk_change = ((new_baseclock != data->set_baseclock) ||
192                         (mclk != data->set_mclk));
193         if (!clk_change)
194                 return 0;
195
196         /* Don't change rate if already one dai-link is using it */
197         if (data->lock_count)
198                 return -EINVAL;
199
200         data->set_baseclock = 0;
201         data->set_mclk = 0;
202
203         reenable_clock = false;
204         if(tegra_is_clk_enabled(data->clk_pll_a)) {
205                 clk_disable(data->clk_pll_a);
206                 reenable_clock = true;
207         }
208         err = clk_set_rate(data->clk_pll_a, new_baseclock);
209         if (err) {
210                 dev_err(data->dev, "Can't set pll_a rate: %d\n", err);
211                 return err;
212         }
213         if(reenable_clock)
214                 clk_enable(data->clk_pll_a);
215
216         reenable_clock = false;
217         if(tegra_is_clk_enabled(data->clk_pll_a_out0)) {
218                 clk_disable(data->clk_pll_a_out0);
219                 reenable_clock = true;
220         }
221         err = clk_set_rate(data->clk_pll_a_out0, mclk);
222         if (err) {
223                 dev_err(data->dev, "Can't set clk_pll_a_out0 rate: %d\n", err);
224                 return err;
225         }
226         if(reenable_clock)
227                 clk_enable(data->clk_pll_a_out0);
228
229
230         data->set_baseclock = new_baseclock;
231         data->set_mclk = mclk;
232
233         return 0;
234 }
235 EXPORT_SYMBOL_GPL(tegra_asoc_utils_set_rate);
236
237 void tegra_asoc_utils_lock_clk_rate(struct tegra_asoc_utils_data *data,
238                                     int lock)
239 {
240         if (lock)
241                 data->lock_count++;
242         else if (data->lock_count)
243                 data->lock_count--;
244 }
245 EXPORT_SYMBOL_GPL(tegra_asoc_utils_lock_clk_rate);
246
247 int tegra_asoc_utils_clk_enable(struct tegra_asoc_utils_data *data)
248 {
249         int err;
250
251         err = clk_enable(data->clk_cdev1);
252         if (err) {
253                 dev_err(data->dev, "Can't enable cdev1: %d\n", err);
254                 return err;
255         }
256
257         return 0;
258 }
259 EXPORT_SYMBOL_GPL(tegra_asoc_utils_clk_enable);
260
261 int tegra_asoc_utils_clk_disable(struct tegra_asoc_utils_data *data)
262 {
263         clk_disable(data->clk_cdev1);
264         return 0;
265 }
266 EXPORT_SYMBOL_GPL(tegra_asoc_utils_clk_disable);
267
268 int tegra_asoc_utils_register_ctls(struct tegra_asoc_utils_data *data)
269 {
270         int i;
271         int ret = 0;
272
273         /* Add AVP related alsa controls */
274         data->avp_device_id = -1;
275         for (i = 0; i < ARRAY_SIZE(tegra_avp_controls); i++) {
276                 ret = snd_ctl_add(data->card->snd_card,
277                                 snd_ctl_new1(&tegra_avp_controls[i], data));
278                 if (ret < 0) {
279                         dev_err(data->dev, "Can't add avp alsa controls");
280                         return ret;
281                 }
282         }
283
284         return ret;
285 }
286 EXPORT_SYMBOL_GPL(tegra_asoc_utils_register_ctls);
287
288 int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
289                           struct device *dev, struct snd_soc_card *card)
290 {
291         int ret;
292
293         data->dev = dev;
294         data->card = card;
295
296         data->clk_pll_p_out1 = clk_get_sys(NULL, "pll_p_out1");
297         if (IS_ERR(data->clk_pll_p_out1)) {
298                 dev_err(data->dev, "Can't retrieve clk pll_p_out1\n");
299                 ret = PTR_ERR(data->clk_pll_p_out1);
300                 goto err;
301         }
302
303         data->clk_pll_a = clk_get_sys(NULL, "pll_a");
304         if (IS_ERR(data->clk_pll_a)) {
305                 dev_err(data->dev, "Can't retrieve clk pll_a\n");
306                 ret = PTR_ERR(data->clk_pll_a);
307                 goto err_put_pll_p_out1;
308         }
309
310         data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0");
311         if (IS_ERR(data->clk_pll_a_out0)) {
312                 dev_err(data->dev, "Can't retrieve clk pll_a_out0\n");
313                 ret = PTR_ERR(data->clk_pll_a_out0);
314                 goto err_put_pll_a;
315         }
316
317         data->clk_m = clk_get_sys(NULL, "clk_m");
318         if (IS_ERR(data->clk_m)) {
319                 dev_err(data->dev, "Can't retrieve clk clk_m\n");
320                 ret = PTR_ERR(data->clk_m);
321                 goto err;
322         }
323
324 #if defined(CONFIG_ARCH_TEGRA_2x_SOC)
325         data->clk_cdev1 = clk_get_sys(NULL, "cdev1");
326 #else
327         data->clk_cdev1 = clk_get_sys("extern1", NULL);
328 #endif
329         if (IS_ERR(data->clk_cdev1)) {
330                 dev_err(data->dev, "Can't retrieve clk cdev1\n");
331                 ret = PTR_ERR(data->clk_cdev1);
332                 goto err_put_pll_a_out0;
333         }
334
335 #if defined(CONFIG_ARCH_TEGRA_2x_SOC)
336         data->clk_out1 = ERR_PTR(-ENOENT);
337 #else
338         data->clk_out1 = clk_get_sys("clk_out_1", "extern1");
339         if (IS_ERR(data->clk_out1)) {
340                 dev_err(data->dev, "Can't retrieve clk out1\n");
341                 ret = PTR_ERR(data->clk_out1);
342                 goto err_put_cdev1;
343         }
344 #endif
345
346 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
347 #if TEGRA30_I2S_MASTER_PLAYBACK
348         ret = clk_set_parent(data->clk_cdev1, data->clk_pll_a_out0);
349         if (ret) {
350                 dev_err(data->dev, "Can't set clk cdev1/extern1 parent");
351                 goto err_put_out1;
352         }
353 #else
354         rate = clk_get_rate(data->clk_m);
355
356         if(rate == 26000000)
357                 clk_set_rate(data->clk_cdev1, 13000000);
358
359         ret = clk_set_parent(data->clk_cdev1, data->clk_m);
360         if (ret) {
361                 dev_err(data->dev, "Can't set clk cdev1/extern1 parent");
362                 goto err_put_out1;
363         }
364 #endif
365
366 #endif
367
368         ret = clk_enable(data->clk_cdev1);
369         if (ret) {
370                 dev_err(data->dev, "Can't enable clk cdev1/extern1");
371                 goto err_put_out1;
372         }
373
374         if (!IS_ERR(data->clk_out1)) {
375                 ret = clk_enable(data->clk_out1);
376                 if (ret) {
377                         dev_err(data->dev, "Can't enable clk out1");
378                         goto err_put_out1;
379                 }
380         }
381
382         ret = tegra_asoc_utils_set_rate(data, 48000, 256 * 48000);
383         if (ret)
384                 goto err_put_out1;
385
386         return 0;
387
388 err_put_out1:
389         if (!IS_ERR(data->clk_out1))
390                 clk_put(data->clk_out1);
391 #if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
392 err_put_cdev1:
393 #endif
394         clk_put(data->clk_cdev1);
395 err_put_pll_a_out0:
396         clk_put(data->clk_pll_a_out0);
397 err_put_pll_a:
398         clk_put(data->clk_pll_a);
399 err_put_pll_p_out1:
400         clk_put(data->clk_pll_p_out1);
401 err:
402         return ret;
403 }
404 EXPORT_SYMBOL_GPL(tegra_asoc_utils_init);
405
406 void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data)
407 {
408         if (!IS_ERR(data->clk_out1))
409                 clk_put(data->clk_out1);
410
411         clk_put(data->clk_cdev1);
412         /* Just to make sure that clk_cdev1 should turn off in case if it is
413          * switched on by some codec whose hw switch is not registered.*/
414         if (tegra_is_clk_enabled(data->clk_cdev1))
415                 clk_disable(data->clk_cdev1);
416
417         if (!IS_ERR(data->clk_pll_a_out0))
418                 clk_put(data->clk_pll_a_out0);
419
420         if (!IS_ERR(data->clk_pll_a))
421                 clk_put(data->clk_pll_a);
422
423         if (!IS_ERR(data->clk_pll_p_out1))
424                 clk_put(data->clk_pll_p_out1);
425 }
426 EXPORT_SYMBOL_GPL(tegra_asoc_utils_fini);
427
428 MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
429 MODULE_DESCRIPTION("Tegra ASoC utility code");
430 MODULE_LICENSE("GPL");