fcbc065a3ee15d760ba2d46f565c5b95ce3f9072
[linux-3.10.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-2013, NVIDIA CORPORATION.  All rights reserved.
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 #include <linux/of.h>
29 #include <linux/clk/tegra.h>
30
31 #include <mach/pinmux.h>
32 #ifdef CONFIG_ARCH_TEGRA_2x_SOC
33 #include <mach/pinmux-tegra20.h>
34 #endif
35 #ifdef CONFIG_ARCH_TEGRA_3x_SOC
36 #include <mach/pinmux-tegra30.h>
37 #endif
38 #ifdef CONFIG_ARCH_TEGRA_11x_SOC
39 #include <mach/pinmux-t11.h>
40 #endif
41 #ifdef CONFIG_ARCH_TEGRA_12x_SOC
42 #include <mach/pinmux-t12.h>
43 #endif
44 #ifdef CONFIG_ARCH_TEGRA_14x_SOC
45 #include <mach/pinmux-t14.h>
46 #endif
47
48 #include <sound/soc.h>
49 #include <sound/dmaengine_pcm.h>
50
51 #include "tegra_pcm.h"
52 #include "tegra_asoc_utils.h"
53
54 int g_is_call_mode;
55 static atomic_t dap_ref_count[5];
56
57 #ifdef CONFIG_SWITCH
58 static bool is_switch_registered;
59 struct switch_dev *psdev;
60 /* These values are copied from WiredAccessoryObserver */
61 enum headset_state {
62         BIT_NO_HEADSET = 0,
63         BIT_HEADSET = (1 << 0),
64         BIT_HEADSET_NO_MIC = (1 << 1),
65 };
66 #endif
67
68 #define TRISTATE_DAP_PORT(n) \
69 static void tristate_dap_##n(bool tristate) \
70 { \
71         enum tegra_pingroup fs, sclk, din, dout; \
72         fs = TEGRA_PINGROUP_DAP##n##_FS; \
73         sclk = TEGRA_PINGROUP_DAP##n##_SCLK; \
74         din = TEGRA_PINGROUP_DAP##n##_DIN; \
75         dout = TEGRA_PINGROUP_DAP##n##_DOUT; \
76         if (tristate) { \
77                 if (atomic_dec_return(&dap_ref_count[n-1]) == 0) {\
78                         tegra_pinmux_set_tristate(fs, TEGRA_TRI_TRISTATE); \
79                         tegra_pinmux_set_tristate(sclk, TEGRA_TRI_TRISTATE); \
80                         tegra_pinmux_set_tristate(din, TEGRA_TRI_TRISTATE); \
81                         tegra_pinmux_set_tristate(dout, TEGRA_TRI_TRISTATE); \
82                 } \
83         } else { \
84                 if (atomic_inc_return(&dap_ref_count[n-1]) == 1) {\
85                         tegra_pinmux_set_tristate(fs, TEGRA_TRI_NORMAL); \
86                         tegra_pinmux_set_tristate(sclk, TEGRA_TRI_NORMAL); \
87                         tegra_pinmux_set_tristate(din, TEGRA_TRI_NORMAL); \
88                         tegra_pinmux_set_tristate(dout, TEGRA_TRI_NORMAL); \
89                 } \
90         } \
91 }
92
93 TRISTATE_DAP_PORT(1)
94 TRISTATE_DAP_PORT(2)
95 /*I2S2 and I2S3 for other chips do not map to DAP3 and DAP4 (also
96 these pinmux dont exist for other chips), they map to some
97 other pinmux*/
98 #if defined(CONFIG_ARCH_TEGRA_11x_SOC)\
99                 || defined(CONFIG_ARCH_TEGRA_12x_SOC)\
100                 || defined(CONFIG_ARCH_TEGRA_3x_SOC)
101         TRISTATE_DAP_PORT(3)
102         TRISTATE_DAP_PORT(4)
103 #endif
104
105 int tegra_asoc_utils_tristate_dap(int id, bool tristate)
106 {
107         switch (id) {
108         case 0:
109                 tristate_dap_1(tristate);
110                 break;
111         case 1:
112                 tristate_dap_2(tristate);
113                 break;
114 /*I2S2 and I2S3 for other chips do not map to DAP3 and DAP4 (also
115 these pinmux dont exist for other chips), they map to some
116 other pinmux*/
117 #if defined(CONFIG_ARCH_TEGRA_11x_SOC)\
118         || defined(CONFIG_ARCH_TEGRA_12x_SOC)\
119         || defined(CONFIG_ARCH_TEGRA_3x_SOC)
120         case 2:
121                 tristate_dap_3(tristate);
122                 break;
123         case 3:
124                 tristate_dap_4(tristate);
125                 break;
126 #endif
127         default:
128                 pr_warn("Invalid DAP port\n");
129                 break;
130         }
131         return 0;
132 }
133 EXPORT_SYMBOL_GPL(tegra_asoc_utils_tristate_dap);
134
135 bool tegra_is_voice_call_active(void)
136 {
137         if (g_is_call_mode)
138                 return true;
139         else
140                 return false;
141 }
142 EXPORT_SYMBOL_GPL(tegra_is_voice_call_active);
143
144 static int tegra_get_avp_device(struct snd_kcontrol *kcontrol,
145                                 struct snd_ctl_elem_value *ucontrol)
146 {
147         struct  tegra_asoc_utils_data *data = snd_kcontrol_chip(kcontrol);
148
149         ucontrol->value.integer.value[0] = data->avp_device_id;
150         return 0;
151 }
152
153 static int tegra_set_avp_device(struct snd_kcontrol *kcontrol,
154                                 struct snd_ctl_elem_value *ucontrol)
155 {
156         struct  tegra_asoc_utils_data *data = snd_kcontrol_chip(kcontrol);
157         struct snd_soc_card *card = data->card;
158         struct snd_soc_pcm_runtime *rtd;
159         struct snd_pcm_substream *substream;
160         struct tegra_runtime_data *prtd;
161         int id, old_id = data->avp_device_id;
162
163         id = ucontrol->value.integer.value[0];
164         if ((id >= card->num_rtd) || (id < 0))
165                 id = -1;
166
167         if (old_id >= 0) {
168                 rtd = &card->rtd[old_id];
169                 substream =
170                         rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
171                 if (substream && substream->runtime) {
172                         prtd = substream->runtime->private_data;
173                         if (!prtd)
174                                 return -EINVAL;
175                         if (prtd->running)
176                                 return -EBUSY;
177                         prtd->disable_intr = false;
178                 }
179         }
180
181         if (id >= 0) {
182                 rtd = &card->rtd[id];
183                 substream =
184                         rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
185                 if (substream && substream->runtime) {
186                         prtd = substream->runtime->private_data;
187                         if (!prtd)
188                                 return -EINVAL;
189                         if (prtd->running)
190                                 return -EBUSY;
191                         prtd->disable_intr = true;
192                         if (data->avp_dma_addr || prtd->avp_dma_addr)
193                                 prtd->avp_dma_addr = data->avp_dma_addr;
194                 }
195         }
196         data->avp_device_id = id;
197         return 1;
198 }
199
200 static int tegra_get_dma_ch_id(struct snd_kcontrol *kcontrol,
201                                struct snd_ctl_elem_value *ucontrol)
202 {
203         struct  tegra_asoc_utils_data *data = snd_kcontrol_chip(kcontrol);
204         struct snd_soc_card *card = data->card;
205         struct snd_soc_pcm_runtime *rtd;
206         struct snd_pcm_substream *substream;
207         struct tegra_runtime_data *prtd;
208         struct dma_chan *chan;
209
210         if (data->avp_device_id < 0)
211                 return 0;
212
213         rtd = &card->rtd[data->avp_device_id];
214         substream = rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
215
216         if (!substream || !substream->runtime)
217                 return 0;
218
219         prtd = substream->runtime->private_data;
220
221         if (!prtd)
222                 return 0;
223
224         chan = snd_dmaengine_pcm_get_chan(substream);
225
226         ucontrol->value.integer.value[0] = -1;
227
228         return 0;
229 }
230
231 static int tegra_set_dma_addr(struct snd_kcontrol *kcontrol,
232                               struct snd_ctl_elem_value *ucontrol)
233 {
234         struct tegra_asoc_utils_data *data = snd_kcontrol_chip(kcontrol);
235         struct snd_soc_card *card = data->card;
236         struct snd_soc_pcm_runtime *rtd;
237         struct snd_pcm_substream *substream;
238         struct tegra_runtime_data *prtd;
239
240         if (data->avp_device_id < 0)
241                 return 0;
242
243         rtd = &card->rtd[data->avp_device_id];
244         substream =
245         rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
246
247         if (!substream || !substream->runtime)
248                 return 0;
249
250         prtd = substream->runtime->private_data;
251         if (!prtd)
252                 return 0;
253
254         data->avp_dma_addr = (dma_addr_t)ucontrol->value.integer.value[0];
255         prtd->avp_dma_addr = data->avp_dma_addr;
256         return 1;
257 }
258
259 static int tegra_get_dma_addr(struct snd_kcontrol *kcontrol,
260                               struct snd_ctl_elem_value *ucontrol)
261 {
262         struct  tegra_asoc_utils_data *data = snd_kcontrol_chip(kcontrol);
263         struct snd_soc_card *card = data->card;
264         struct snd_soc_pcm_runtime *rtd;
265         struct snd_pcm_substream *substream;
266         struct tegra_runtime_data *prtd;
267
268         if (data->avp_device_id < 0)
269                 return 0;
270
271         rtd = &card->rtd[data->avp_device_id];
272         substream = rtd->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
273
274         if (!substream || !substream->runtime)
275                 return 0;
276
277         prtd = substream->runtime->private_data;
278
279         if (!prtd)
280                 return 0;
281
282         ucontrol->value.integer.value[0] = 0;
283         ucontrol->value.integer.value[0] = prtd->avp_dma_addr ?
284                                            (long)prtd->avp_dma_addr :
285                                            (long)substream->runtime->dma_addr;
286
287         return 0;
288 }
289
290 struct snd_kcontrol_new tegra_avp_controls[] = {
291         SOC_SINGLE_EXT("AVP alsa device select", 0, 0, TEGRA_ALSA_MAX_DEVICES, \
292                         0, tegra_get_avp_device, tegra_set_avp_device),
293         SOC_SINGLE_EXT("AVP DMA channel id", 0, 0, TEGRA_DMA_MAX_CHANNELS, \
294                         0, tegra_get_dma_ch_id, NULL),
295         SOC_SINGLE_EXT("AVP DMA address", 0, 0, 0xFFFFFFFF, \
296                         0, tegra_get_dma_addr, tegra_set_dma_addr),
297 };
298
299 static int tegra_set_headset_plug_state(struct snd_kcontrol *kcontrol,
300                               struct snd_ctl_elem_value *ucontrol)
301 {
302         struct tegra_asoc_utils_data *data = snd_kcontrol_chip(kcontrol);
303         int switch_state;
304
305         data->headset_plug_state = ucontrol->value.integer.value[0];
306         switch_state = data->headset_plug_state == 1 ? BIT_HEADSET
307                 : BIT_NO_HEADSET;
308         if (psdev)
309                 switch_set_state(psdev, switch_state);
310
311         return 1;
312 }
313
314 static int tegra_get_headset_plug_state(struct snd_kcontrol *kcontrol,
315                               struct snd_ctl_elem_value *ucontrol)
316 {
317         struct  tegra_asoc_utils_data *data = snd_kcontrol_chip(kcontrol);
318
319         ucontrol->value.integer.value[0] = data->headset_plug_state;
320
321         return 0;
322 }
323
324 struct snd_kcontrol_new tegra_switch_controls =
325         SOC_SINGLE_EXT("Headset Plug State", 0, 0, 1, \
326         0, tegra_get_headset_plug_state, tegra_set_headset_plug_state);
327
328
329 int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
330                               int mclk)
331 {
332         int new_baseclock;
333         bool clk_change;
334         int err;
335         bool reenable_clock;
336
337         switch (srate) {
338         case 11025:
339         case 22050:
340         case 44100:
341         case 88200:
342                 if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
343                         new_baseclock = 56448000;
344                 else if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA30)
345                         new_baseclock = 564480000;
346                 else
347                         new_baseclock = 282240000;
348                 break;
349         case 8000:
350         case 16000:
351         case 32000:
352         case 48000:
353         case 64000:
354         case 96000:
355                 if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
356                         new_baseclock = 73728000;
357                 else if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA30)
358                         new_baseclock = 552960000;
359                 else
360                         new_baseclock = 368640000;
361                 break;
362         default:
363                 return -EINVAL;
364         }
365
366         clk_change = ((new_baseclock != data->set_baseclock) ||
367                         (mclk != data->set_mclk));
368         if (!clk_change)
369                 return 0;
370
371         /* Don't change rate if already one dai-link is using it */
372         if (data->lock_count)
373                 return -EINVAL;
374
375         data->set_baseclock = 0;
376         data->set_mclk = 0;
377
378         reenable_clock = false;
379         if(tegra_is_clk_enabled(data->clk_pll_a)) {
380                 clk_disable_unprepare(data->clk_pll_a);
381                 reenable_clock = true;
382         }
383
384         err = clk_set_rate(data->clk_pll_a, new_baseclock);
385         if (err) {
386                 dev_err(data->dev, "Can't set pll_a rate: %d\n", err);
387                 return err;
388         }
389         if(reenable_clock)
390                 clk_prepare_enable(data->clk_pll_a);
391
392         reenable_clock = false;
393         if(tegra_is_clk_enabled(data->clk_pll_a_out0)) {
394                 clk_disable_unprepare(data->clk_pll_a_out0);
395                 reenable_clock = true;
396         }
397         err = clk_set_rate(data->clk_pll_a_out0, mclk);
398         if (err) {
399                 dev_err(data->dev, "Can't set clk_pll_a_out0 rate: %d\n", err);
400                 return err;
401         }
402         if(reenable_clock)
403                 clk_prepare_enable(data->clk_pll_a_out0);
404
405         data->set_baseclock = new_baseclock;
406         data->set_mclk = mclk;
407
408         return 0;
409 }
410 EXPORT_SYMBOL_GPL(tegra_asoc_utils_set_rate);
411
412 void tegra_asoc_utils_lock_clk_rate(struct tegra_asoc_utils_data *data,
413                                     int lock)
414 {
415         if (lock)
416                 data->lock_count++;
417         else if (data->lock_count)
418                 data->lock_count--;
419 }
420 EXPORT_SYMBOL_GPL(tegra_asoc_utils_lock_clk_rate);
421
422 int tegra_asoc_utils_clk_enable(struct tegra_asoc_utils_data *data)
423 {
424         int err;
425
426         err = clk_prepare_enable(data->clk_cdev1);
427         if (err) {
428                 dev_err(data->dev, "Can't enable cdev1: %d\n", err);
429                 return err;
430         }
431
432         return 0;
433 }
434 EXPORT_SYMBOL_GPL(tegra_asoc_utils_clk_enable);
435
436 int tegra_asoc_utils_clk_disable(struct tegra_asoc_utils_data *data)
437 {
438         clk_disable_unprepare(data->clk_cdev1);
439         return 0;
440 }
441 EXPORT_SYMBOL_GPL(tegra_asoc_utils_clk_disable);
442
443 int tegra_asoc_utils_register_ctls(struct tegra_asoc_utils_data *data)
444 {
445         int ret = 0;
446         int i;
447
448         /* Add AVP related alsa controls */
449         data->avp_device_id = -1;
450         for (i = 0; i < ARRAY_SIZE(tegra_avp_controls); i++) {
451                 ret = snd_ctl_add(data->card->snd_card,
452                                 snd_ctl_new1(&tegra_avp_controls[i], data));
453                 if (ret < 0) {
454                         dev_err(data->dev, "Can't add avp alsa controls");
455                         return ret;
456                 }
457         }
458
459         ret = snd_ctl_add(data->card->snd_card,
460                         snd_ctl_new1(&tegra_switch_controls, data));
461         if (ret < 0) {
462                 dev_err(data->dev, "Can't add switch alsa control");
463                 return ret;
464         }
465
466         return ret;
467 }
468 EXPORT_SYMBOL_GPL(tegra_asoc_utils_register_ctls);
469
470 int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
471                           struct device *dev, struct snd_soc_card *card)
472 {
473         int ret;
474
475         data->dev = dev;
476         data->card = card;
477
478         data->clk_pll_p_out1 = clk_get_sys(NULL, "pll_p_out1");
479         if (IS_ERR(data->clk_pll_p_out1)) {
480                 dev_err(data->dev, "Can't retrieve clk pll_p_out1\n");
481                 ret = PTR_ERR(data->clk_pll_p_out1);
482                 goto err;
483         }
484
485         if (of_machine_is_compatible("nvidia,tegra20"))
486                 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20;
487         else if (of_machine_is_compatible("nvidia,tegra30"))
488                 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30;
489         else if (of_machine_is_compatible("nvidia,tegra114"))
490                 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA11x;
491         else if (of_machine_is_compatible("nvidia,tegra148"))
492                 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA14x;
493         else if (of_machine_is_compatible("nvidia,tegra124"))
494                 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA12x;
495         else if (!dev->of_node) {
496                 /* non-DT is always Tegra20 */
497 #if defined(CONFIG_ARCH_TEGRA_2x_SOC)
498                 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA20;
499 #elif defined(CONFIG_ARCH_TEGRA_3x_SOC)
500                 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA30;
501 #elif defined(CONFIG_ARCH_TEGRA_11x_SOC)
502                 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA11x;
503 #elif defined(CONFIG_ARCH_TEGRA_14x_SOC)
504                 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA14x;
505 #elif defined(CONFIG_ARCH_TEGRA_12x_SOC)
506                 data->soc = TEGRA_ASOC_UTILS_SOC_TEGRA12x;
507 #endif
508         } else
509                 /* DT boot, but unknown SoC */
510                 return -EINVAL;
511
512         data->clk_pll_a = clk_get_sys(NULL, "pll_a");
513         if (IS_ERR(data->clk_pll_a)) {
514                 dev_err(data->dev, "Can't retrieve clk pll_a\n");
515                 ret = PTR_ERR(data->clk_pll_a);
516                 goto err_put_pll_p_out1;
517         }
518
519         data->clk_pll_a_out0 = clk_get_sys(NULL, "pll_a_out0");
520         if (IS_ERR(data->clk_pll_a_out0)) {
521                 dev_err(data->dev, "Can't retrieve clk pll_a_out0\n");
522                 ret = PTR_ERR(data->clk_pll_a_out0);
523                 goto err_put_pll_a;
524         }
525
526         data->clk_m = clk_get_sys(NULL, "clk_m");
527         if (IS_ERR(data->clk_m)) {
528                 dev_err(data->dev, "Can't retrieve clk clk_m\n");
529                 ret = PTR_ERR(data->clk_m);
530                 goto err;
531         }
532
533         if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
534                 data->clk_cdev1 = clk_get_sys(NULL, "cdev1");
535         else
536                 data->clk_cdev1 = clk_get_sys("extern1", NULL);
537
538         if (IS_ERR(data->clk_cdev1)) {
539                 dev_err(data->dev, "Can't retrieve clk cdev1\n");
540                 ret = PTR_ERR(data->clk_cdev1);
541                 goto err_put_pll_a_out0;
542         }
543
544         if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
545                 data->clk_out1 = ERR_PTR(-ENOENT);
546         else {
547                 data->clk_out1 = clk_get_sys("clk_out_1", "extern1");
548                 if (IS_ERR(data->clk_out1)) {
549                         dev_err(data->dev, "Can't retrieve clk out1\n");
550                         ret = PTR_ERR(data->clk_out1);
551                         goto err_put_cdev1;
552                 }
553         }
554
555         ret = clk_prepare_enable(data->clk_cdev1);
556         if (ret) {
557                 dev_err(data->dev, "Can't enable clk cdev1/extern1");
558                 goto err_put_out1;
559         }
560
561         if (!IS_ERR(data->clk_out1)) {
562                 ret = clk_prepare_enable(data->clk_out1);
563                 if (ret) {
564                         dev_err(data->dev, "Can't enable clk out1");
565                         goto err_put_out1;
566                 }
567         }
568
569         ret = tegra_asoc_utils_set_rate(data, 48000, 256 * 48000);
570         if (ret)
571                 goto err_put_out1;
572
573         return 0;
574
575 err_put_out1:
576         if (!IS_ERR(data->clk_out1))
577                 clk_put(data->clk_out1);
578 err_put_cdev1:
579         clk_put(data->clk_cdev1);
580 err_put_pll_a_out0:
581         clk_put(data->clk_pll_a_out0);
582 err_put_pll_a:
583         clk_put(data->clk_pll_a);
584 err_put_pll_p_out1:
585         clk_put(data->clk_pll_p_out1);
586 err:
587         return ret;
588 }
589 EXPORT_SYMBOL_GPL(tegra_asoc_utils_init);
590
591 int tegra_asoc_utils_set_parent (struct tegra_asoc_utils_data *data,
592                                 int is_i2s_master)
593 {
594         int ret = -ENODEV;
595
596         if (data->soc == TEGRA_ASOC_UTILS_SOC_TEGRA20)
597                 return ret;
598
599         if (is_i2s_master) {
600                 ret = clk_set_parent(data->clk_cdev1, data->clk_pll_a_out0);
601                 if (ret) {
602                         dev_err(data->dev, "Can't set clk cdev1/extern1 parent");
603                         return ret;
604                 }
605         } else {
606                 if(clk_get_rate(data->clk_m) == 26000000)
607                         clk_set_rate(data->clk_cdev1, 13000000);
608
609                 ret = clk_set_parent(data->clk_cdev1, data->clk_m);
610                 if (ret) {
611                         dev_err(data->dev, "Can't set clk cdev1/extern1 parent");
612                         return ret;
613                 }
614         }
615
616         return 0;
617 }
618 EXPORT_SYMBOL_GPL(tegra_asoc_utils_set_parent);
619
620 void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data)
621 {
622         if (!IS_ERR(data->clk_out1))
623                 clk_put(data->clk_out1);
624
625         clk_put(data->clk_cdev1);
626         /* Just to make sure that clk_cdev1 should turn off in case if it is
627          * switched on by some codec whose hw switch is not registered.*/
628         if (tegra_is_clk_enabled(data->clk_cdev1))
629                 clk_disable(data->clk_cdev1);
630
631         if (!IS_ERR(data->clk_pll_a_out0))
632                 clk_put(data->clk_pll_a_out0);
633
634         if (!IS_ERR(data->clk_pll_a))
635                 clk_put(data->clk_pll_a);
636
637         if (!IS_ERR(data->clk_pll_p_out1))
638                 clk_put(data->clk_pll_p_out1);
639 }
640 EXPORT_SYMBOL_GPL(tegra_asoc_utils_fini);
641
642 #ifdef CONFIG_SWITCH
643 int tegra_asoc_switch_register(struct switch_dev *sdev)
644 {
645         int ret;
646
647         if (is_switch_registered)
648                 return -EBUSY;
649
650         ret = switch_dev_register(sdev);
651
652         if (ret >= 0) {
653                 psdev = sdev;
654                 is_switch_registered = true;
655         }
656
657         return ret;
658 }
659 EXPORT_SYMBOL_GPL(tegra_asoc_switch_register);
660
661 void tegra_asoc_switch_unregister(struct switch_dev *sdev)
662 {
663         if (!is_switch_registered)
664                 return;
665
666         switch_dev_unregister(sdev);
667         is_switch_registered = false;
668         psdev = NULL;
669 }
670 EXPORT_SYMBOL_GPL(tegra_asoc_switch_unregister);
671 #endif
672
673
674 MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
675 MODULE_DESCRIPTION("Tegra ASoC utility code");
676 MODULE_LICENSE("GPL");