aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/tegra
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /sound/soc/tegra
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'sound/soc/tegra')
-rw-r--r--sound/soc/tegra/tegra30_dam.c650
-rw-r--r--sound/soc/tegra/tegra30_dam.h163
-rw-r--r--sound/soc/tegra/tegra30_spdif.c505
-rw-r--r--sound/soc/tegra/tegra30_spdif.h777
-rw-r--r--sound/soc/tegra/tegra_aic326x.c1281
-rw-r--r--sound/soc/tegra/tegra_max98088.c1233
-rw-r--r--sound/soc/tegra/tegra_max98095.c723
-rw-r--r--sound/soc/tegra/tegra_p1852.c272
-rw-r--r--sound/soc/tegra/tegra_rt5640.c738
9 files changed, 6342 insertions, 0 deletions
diff --git a/sound/soc/tegra/tegra30_dam.c b/sound/soc/tegra/tegra30_dam.c
new file mode 100644
index 00000000000..d308179110c
--- /dev/null
+++ b/sound/soc/tegra/tegra30_dam.c
@@ -0,0 +1,650 @@
1/*
2 * tegra30_dam.c - Tegra 30 DAM driver
3 *
4 * Author: Nikesh Oswal <noswal@nvidia.com>
5 * Copyright (C) 2011 - 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/module.h>
25#include <linux/debugfs.h>
26#include <linux/device.h>
27#include <linux/platform_device.h>
28#include <linux/seq_file.h>
29#include <linux/slab.h>
30#include <linux/io.h>
31#include <sound/soc.h>
32#include "tegra30_dam.h"
33#include "tegra30_ahub.h"
34
35#define DRV_NAME "tegra30-dam"
36
37static struct tegra30_dam_context *dams_cont_info[TEGRA30_NR_DAM_IFC];
38
39enum {
40 dam_ch_in0 = 0x0,
41 dam_ch_in1,
42 dam_ch_out,
43 dam_ch_maxnum
44} tegra30_dam_chtype;
45
46struct tegra30_dam_src_step_table step_table[] = {
47 { 8000, 44100, 80 },
48 { 8000, 48000, 1 },
49 { 16000, 44100, 160 },
50 { 16000, 48000, 1 },
51 { 44100, 8000, 441 },
52 { 48000, 8000, 0 },
53 { 44100, 16000, 441 },
54 { 48000, 16000, 0 },
55};
56
57static void tegra30_dam_set_output_samplerate(struct tegra30_dam_context *dam,
58 int fsout);
59static void tegra30_dam_set_input_samplerate(struct tegra30_dam_context *dam,
60 int fsin);
61static int tegra30_dam_set_step_reset(struct tegra30_dam_context *dam,
62 int insample, int outsample);
63static void tegra30_dam_ch0_set_step(struct tegra30_dam_context *dam, int step);
64
65static inline void tegra30_dam_writel(struct tegra30_dam_context *dam,
66 u32 val, u32 reg)
67{
68#ifdef CONFIG_PM
69 dam->reg_cache[reg >> 2] = val;
70#endif
71 __raw_writel(val, dam->damregs + reg);
72}
73
74static inline u32 tegra30_dam_readl(struct tegra30_dam_context *dam, u32 reg)
75{
76 u32 val = __raw_readl(dam->damregs + reg);
77
78 return val;
79}
80
81#ifdef CONFIG_PM
82int tegra30_dam_resume(int ifc)
83{
84 int i = 0;
85 struct tegra30_dam_context *dam;
86
87 if (ifc >= TEGRA30_NR_DAM_IFC)
88 return -EINVAL;
89
90 dam = dams_cont_info[ifc];
91
92 if (dam->in_use) {
93 tegra30_dam_enable_clock(ifc);
94
95 for (i = 0; i <= TEGRA30_DAM_CTRL_REGINDEX; i++) {
96 if ((i == TEGRA30_DAM_CTRL_RSVD_6) ||
97 (i == TEGRA30_DAM_CTRL_RSVD_10))
98 continue;
99
100 tegra30_dam_writel(dam, dam->reg_cache[i],
101 (i << 2));
102 }
103
104 tegra30_dam_disable_clock(ifc);
105 }
106
107 return 0;
108}
109#endif
110
111void tegra30_dam_disable_clock(int ifc)
112{
113 struct tegra30_dam_context *dam;
114
115 if (ifc >= TEGRA30_NR_DAM_IFC)
116 return;
117
118 dam = dams_cont_info[ifc];
119 clk_disable(dam->dam_clk);
120 tegra30_ahub_disable_clocks();
121}
122
123int tegra30_dam_enable_clock(int ifc)
124{
125 struct tegra30_dam_context *dam;
126
127 if (ifc >= TEGRA30_NR_DAM_IFC)
128 return -EINVAL;
129
130 dam = dams_cont_info[ifc];
131 tegra30_ahub_enable_clocks();
132 clk_enable(dam->dam_clk);
133
134 return 0;
135}
136
137#ifdef CONFIG_DEBUG_FS
138static int tegra30_dam_show(struct seq_file *s, void *unused)
139{
140#define REG(r) { r, #r }
141 static const struct {
142 int offset;
143 const char *name;
144 } regs[] = {
145 REG(TEGRA30_DAM_CTRL),
146 REG(TEGRA30_DAM_CLIP),
147 REG(TEGRA30_DAM_CLIP_THRESHOLD),
148 REG(TEGRA30_DAM_AUDIOCIF_OUT_CTRL),
149 REG(TEGRA30_DAM_CH0_CTRL),
150 REG(TEGRA30_DAM_CH0_CONV),
151 REG(TEGRA30_DAM_AUDIOCIF_CH0_CTRL),
152 REG(TEGRA30_DAM_CH1_CTRL),
153 REG(TEGRA30_DAM_CH1_CONV),
154 REG(TEGRA30_DAM_AUDIOCIF_CH1_CTRL),
155 };
156#undef REG
157
158 struct tegra30_dam_context *dam = s->private;
159 int i;
160
161 clk_enable(dam->dam_clk);
162
163 for (i = 0; i < ARRAY_SIZE(regs); i++) {
164 u32 val = tegra30_dam_readl(dam, regs[i].offset);
165 seq_printf(s, "%s = %08x\n", regs[i].name, val);
166 }
167
168 clk_disable(dam->dam_clk);
169
170 return 0;
171}
172
173static int tegra30_dam_debug_open(struct inode *inode, struct file *file)
174{
175 return single_open(file, tegra30_dam_show, inode->i_private);
176}
177
178static const struct file_operations tegra30_dam_debug_fops = {
179 .open = tegra30_dam_debug_open,
180 .read = seq_read,
181 .llseek = seq_lseek,
182 .release = single_release,
183};
184
185static void tegra30_dam_debug_add(struct tegra30_dam_context *dam, int id)
186{
187 char name[] = DRV_NAME ".0";
188
189 snprintf(name, sizeof(name), DRV_NAME".%1d", id);
190 dam->debug = debugfs_create_file(name, S_IRUGO, snd_soc_debugfs_root,
191 dam, &tegra30_dam_debug_fops);
192}
193
194static void tegra30_dam_debug_remove(struct tegra30_dam_context *dam)
195{
196 if (dam->debug)
197 debugfs_remove(dam->debug);
198}
199#else
200static inline void tegra30_dam_debug_add(struct tegra30_dam_context *dam,
201 int id)
202{
203}
204
205static inline void tegra30_dam_debug_remove(struct tegra30_dam_context *dam)
206{
207}
208#endif
209
210int tegra30_dam_allocate_controller()
211{
212 int i = 0;
213 struct tegra30_dam_context *dam = NULL;
214
215 for (i = 0; i < TEGRA30_NR_DAM_IFC; i++) {
216
217 dam = dams_cont_info[i];
218
219 if (!dam->in_use) {
220 dam->in_use = true;
221 return i;
222 }
223 }
224
225 return -ENOENT;
226}
227
228int tegra30_dam_allocate_channel(int ifc, int chid)
229{
230 struct tegra30_dam_context *dam = NULL;
231
232 if (ifc >= TEGRA30_NR_DAM_IFC)
233 return -EINVAL;
234
235 dam = dams_cont_info[ifc];
236
237 if (!dam->ch_alloc[chid]) {
238 dam->ch_alloc[chid] = true;
239 return 0;
240 }
241
242 return -ENOENT;
243}
244
245int tegra30_dam_free_channel(int ifc, int chid)
246{
247 struct tegra30_dam_context *dam = NULL;
248
249 if (ifc >= TEGRA30_NR_DAM_IFC)
250 return -EINVAL;
251
252 dam = dams_cont_info[ifc];
253
254 if (dam->ch_alloc[chid]) {
255 dam->ch_alloc[chid] = false;
256 return 0;
257 }
258
259 return -EINVAL;
260}
261
262int tegra30_dam_free_controller(int ifc)
263{
264 struct tegra30_dam_context *dam = NULL;
265
266 if (ifc >= TEGRA30_NR_DAM_IFC)
267 return -EINVAL;
268
269 dam = dams_cont_info[ifc];
270
271 if (!dam->ch_alloc[dam_ch_in0] &&
272 !dam->ch_alloc[dam_ch_in1]) {
273 dam->in_use = false;
274 return 0;
275 }
276
277 return -EINVAL;
278}
279
280void tegra30_dam_set_samplerate(int ifc, int chid, int samplerate)
281{
282 struct tegra30_dam_context *dam = dams_cont_info[ifc];
283
284 if (ifc >= TEGRA30_NR_DAM_IFC)
285 return;
286
287 switch (chid) {
288 case dam_ch_in0:
289 tegra30_dam_set_input_samplerate(dam, samplerate);
290 dam->ch_insamplerate[dam_ch_in0] = samplerate;
291 tegra30_dam_set_step_reset(dam, samplerate, dam->outsamplerate);
292 break;
293 case dam_ch_in1:
294 if (samplerate != dam->outsamplerate)
295 return;
296 dam->ch_insamplerate[dam_ch_in1] = samplerate;
297 break;
298 case dam_ch_out:
299 tegra30_dam_set_output_samplerate(dam, samplerate);
300 dam->outsamplerate = samplerate;
301 break;
302 default:
303 break;
304 }
305}
306
307void tegra30_dam_set_output_samplerate(struct tegra30_dam_context *dam,
308 int fsout)
309{
310 u32 val;
311
312 val = tegra30_dam_readl(dam, TEGRA30_DAM_CTRL);
313 val &= ~TEGRA30_DAM_CTRL_FSOUT_MASK;
314
315 switch (fsout) {
316 case TEGRA30_AUDIO_SAMPLERATE_8000:
317 val |= TEGRA30_DAM_CTRL_FSOUT_FS8;
318 break;
319 case TEGRA30_AUDIO_SAMPLERATE_16000:
320 val |= TEGRA30_DAM_CTRL_FSOUT_FS16;
321 break;
322 case TEGRA30_AUDIO_SAMPLERATE_44100:
323 val |= TEGRA30_DAM_CTRL_FSOUT_FS44;
324 break;
325 case TEGRA30_AUDIO_SAMPLERATE_48000:
326 val |= TEGRA30_DAM_CTRL_FSOUT_FS48;
327 break;
328 default:
329 break;
330 }
331
332 tegra30_dam_writel(dam, val, TEGRA30_DAM_CTRL);
333}
334
335void tegra30_dam_set_input_samplerate(struct tegra30_dam_context *dam, int fsin)
336{
337 u32 val;
338
339 val = tegra30_dam_readl(dam, TEGRA30_DAM_CH0_CTRL);
340 val &= ~TEGRA30_DAM_CH0_CTRL_FSIN_MASK;
341
342 switch (fsin) {
343 case TEGRA30_AUDIO_SAMPLERATE_8000:
344 val |= TEGRA30_DAM_CH0_CTRL_FSIN_FS8;
345 break;
346 case TEGRA30_AUDIO_SAMPLERATE_16000:
347 val |= TEGRA30_DAM_CH0_CTRL_FSIN_FS16;
348 break;
349 case TEGRA30_AUDIO_SAMPLERATE_44100:
350 val |= TEGRA30_DAM_CH0_CTRL_FSIN_FS44;
351 break;
352 case TEGRA30_AUDIO_SAMPLERATE_48000:
353 val |= TEGRA30_DAM_CH0_CTRL_FSIN_FS48;
354 break;
355 default:
356 break;
357 }
358
359 tegra30_dam_writel(dam, val, TEGRA30_DAM_CH0_CTRL);
360}
361
362int tegra30_dam_set_step_reset(struct tegra30_dam_context *dam,
363 int insample, int outsample)
364{
365 int step_reset = 0;
366 int i = 0;
367
368 for (i = 0; i < ARRAY_SIZE(step_table); i++) {
369 if ((insample == step_table[i].insample) &&
370 (outsample == step_table[i].outsample))
371 step_reset = step_table[i].stepreset;
372 }
373
374 tegra30_dam_ch0_set_step(dam, step_reset);
375
376 return 0;
377}
378
379void tegra30_dam_ch0_set_step(struct tegra30_dam_context *dam, int step)
380{
381 u32 val;
382
383 val = tegra30_dam_readl(dam, TEGRA30_DAM_CH0_CTRL);
384 val &= ~TEGRA30_DAM_CH0_CTRL_STEP_MASK;
385 val |= step << TEGRA30_DAM_CH0_CTRL_STEP_SHIFT;
386 tegra30_dam_writel(dam, val, TEGRA30_DAM_CH0_CTRL);
387}
388
389int tegra30_dam_set_gain(int ifc, int chid, int gain)
390{
391
392 if (ifc >= TEGRA30_NR_DAM_IFC)
393 return -EINVAL;
394
395 switch (chid) {
396 case dam_ch_in0:
397 tegra30_dam_writel(dams_cont_info[ifc], gain,
398 TEGRA30_DAM_CH0_CONV);
399 break;
400 case dam_ch_in1:
401 tegra30_dam_writel(dams_cont_info[ifc], gain,
402 TEGRA30_DAM_CH1_CONV);
403 break;
404 default:
405 break;
406 }
407
408 return 0;
409}
410
411int tegra30_dam_set_acif(int ifc, int chid, unsigned int audio_channels,
412 unsigned int audio_bits, unsigned int client_channels,
413 unsigned int client_bits)
414{
415 unsigned int reg;
416 unsigned int value = 0;
417
418 if (ifc >= TEGRA30_NR_DAM_IFC)
419 return -EINVAL;
420
421 /*ch0 takes input as mono/16bit always*/
422 if ((chid == dam_ch_in0) &&
423 ((client_channels != 1) || (client_bits != 16)))
424 return -EINVAL;
425
426 value |= TEGRA30_CIF_MONOCONV_COPY;
427 value |= TEGRA30_CIF_STEREOCONV_CH0;
428 value |= (audio_channels-1) << TEGRA30_AUDIO_CHANNELS_SHIFT;
429 value |= (((audio_bits>>2)-1)<<TEGRA30_AUDIO_BITS_SHIFT);
430 value |= (client_channels-1) << TEGRA30_CLIENT_CHANNELS_SHIFT;
431 value |= (((client_bits>>2)-1)<<TEGRA30_CLIENT_BITS_SHIFT);
432
433 switch (chid) {
434 case dam_ch_out:
435 value |= TEGRA30_CIF_DIRECTION_TX;
436 reg = TEGRA30_DAM_AUDIOCIF_OUT_CTRL;
437 break;
438 case dam_ch_in0:
439 value |= TEGRA30_CIF_DIRECTION_RX;
440 reg = TEGRA30_DAM_AUDIOCIF_CH0_CTRL;
441 break;
442 case dam_ch_in1:
443 value |= TEGRA30_CIF_DIRECTION_RX;
444 reg = TEGRA30_DAM_AUDIOCIF_CH1_CTRL;
445 break;
446 default:
447 return -EINVAL;
448 }
449
450 tegra30_dam_writel(dams_cont_info[ifc], value, reg);
451
452 return 0;
453}
454
455void tegra30_dam_enable(int ifc, int on, int chid)
456{
457 u32 old_val, val, enreg;
458 struct tegra30_dam_context *dam = dams_cont_info[ifc];
459
460 if (ifc >= TEGRA30_NR_DAM_IFC)
461 return;
462
463 if (chid == dam_ch_in0)
464 enreg = TEGRA30_DAM_CH0_CTRL;
465 else
466 enreg = TEGRA30_DAM_CH1_CTRL;
467
468 old_val = val = tegra30_dam_readl(dam, enreg);
469
470 if (on) {
471 if (!dam->ch_enable_refcnt[chid]++)
472 val |= TEGRA30_DAM_CH0_CTRL_EN;
473 } else if (dam->ch_enable_refcnt[chid]) {
474 dam->ch_enable_refcnt[chid]--;
475 if (!dam->ch_enable_refcnt[chid])
476 val &= ~TEGRA30_DAM_CH0_CTRL_EN;
477 }
478
479 if (val != old_val)
480 tegra30_dam_writel(dam, val, enreg);
481
482 old_val = val = tegra30_dam_readl(dam, TEGRA30_DAM_CTRL);
483
484 if (dam->ch_enable_refcnt[dam_ch_in0] ||
485 dam->ch_enable_refcnt[dam_ch_in1])
486 val |= TEGRA30_DAM_CTRL_DAM_EN;
487 else
488 val &= ~TEGRA30_DAM_CTRL_DAM_EN;
489
490 if (old_val != val)
491 tegra30_dam_writel(dam, val, TEGRA30_DAM_CTRL);
492}
493
494void tegra30_dam_ch0_set_datasync(struct tegra30_dam_context *dam, int datasync)
495{
496 u32 val;
497
498 val = tegra30_dam_readl(dam, TEGRA30_DAM_CH0_CTRL);
499 val &= ~TEGRA30_DAM_CH0_CTRL_DATA_SYNC_MASK;
500 val |= datasync << TEGRA30_DAM_DATA_SYNC_SHIFT;
501 tegra30_dam_writel(dam, val, TEGRA30_DAM_CH0_CTRL);
502}
503
504void tegra30_dam_ch1_set_datasync(struct tegra30_dam_context *dam, int datasync)
505{
506 u32 val;
507
508 val = tegra30_dam_readl(dam, TEGRA30_DAM_CH1_CTRL);
509 val &= ~TEGRA30_DAM_CH1_CTRL_DATA_SYNC_MASK;
510 val |= datasync << TEGRA30_DAM_DATA_SYNC_SHIFT;
511 tegra30_dam_writel(dam, val, TEGRA30_DAM_CH1_CTRL);
512}
513
514void tegra30_dam_enable_clip_counter(struct tegra30_dam_context *dam, int on)
515{
516 u32 val;
517
518 val = tegra30_dam_readl(dam, TEGRA30_DAM_CLIP);
519 val &= ~TEGRA30_DAM_CLIP_COUNTER_ENABLE;
520 val |= on ? TEGRA30_DAM_CLIP_COUNTER_ENABLE : 0;
521 tegra30_dam_writel(dam, val, TEGRA30_DAM_CLIP);
522}
523
524static int __devinit tegra30_dam_probe(struct platform_device *pdev)
525{
526 struct resource *res, *region;
527 struct tegra30_dam_context *dam;
528 int ret = 0;
529#ifdef CONFIG_PM
530 int i;
531#endif
532 int clkm_rate;
533
534 if ((pdev->id < 0) ||
535 (pdev->id >= TEGRA30_NR_DAM_IFC)) {
536 dev_err(&pdev->dev, "ID %d out of range\n", pdev->id);
537 return -EINVAL;
538 }
539
540 dams_cont_info[pdev->id] = devm_kzalloc(&pdev->dev,
541 sizeof(struct tegra30_dam_context),
542 GFP_KERNEL);
543 if (!dams_cont_info[pdev->id]) {
544 dev_err(&pdev->dev, "Can't allocate dam context\n");
545 ret = -ENOMEM;
546 goto exit;
547 }
548 dam = dams_cont_info[pdev->id];
549
550 dam->dam_clk = clk_get(&pdev->dev, NULL);
551 if (IS_ERR(dam->dam_clk)) {
552 dev_err(&pdev->dev, "Can't retrieve dam clock\n");
553 ret = PTR_ERR(dam->dam_clk);
554 goto err_free;
555 }
556 clkm_rate = clk_get_rate(clk_get_parent(dam->dam_clk));
557 while (clkm_rate > 12000000)
558 clkm_rate >>= 1;
559
560 clk_set_rate(dam->dam_clk,clkm_rate);
561
562 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
563 if (!res) {
564 dev_err(&pdev->dev, "No memory 0 resource\n");
565 ret = -ENODEV;
566 goto err_clk_put_dam;
567 }
568
569 region = devm_request_mem_region(&pdev->dev, res->start,
570 resource_size(res), pdev->name);
571 if (!region) {
572 dev_err(&pdev->dev, "Memory region 0 already claimed\n");
573 ret = -EBUSY;
574 goto err_clk_put_dam;
575 }
576
577 dam->damregs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
578 if (!dam->damregs) {
579 dev_err(&pdev->dev, "ioremap 0 failed\n");
580 ret = -ENOMEM;
581 goto err_clk_put_dam;
582 }
583
584#ifdef CONFIG_PM
585 /* cache the POR values of DAM regs*/
586 tegra30_dam_enable_clock(pdev->id);
587
588 for (i = 0; i <= TEGRA30_DAM_CTRL_REGINDEX; i++) {
589 if ((i == TEGRA30_DAM_CTRL_RSVD_6) ||
590 (i == TEGRA30_DAM_CTRL_RSVD_10))
591 continue;
592
593 dam->reg_cache[i] =
594 tegra30_dam_readl(dam, i << 2);
595 }
596
597 tegra30_dam_disable_clock(pdev->id);
598#endif
599
600 platform_set_drvdata(pdev, dam);
601
602 tegra30_dam_debug_add(dam, pdev->id);
603
604 return 0;
605
606err_clk_put_dam:
607 clk_put(dam->dam_clk);
608err_free:
609 dams_cont_info[pdev->id] = NULL;
610exit:
611 return ret;
612}
613
614static int __devexit tegra30_dam_remove(struct platform_device *pdev)
615{
616 struct tegra30_dam_context *dam;
617
618 dam = platform_get_drvdata(pdev);
619 clk_put(dam->dam_clk);
620 tegra30_dam_debug_remove(dam);
621 dams_cont_info[pdev->id] = NULL;
622
623 return 0;
624}
625
626static struct platform_driver tegra30_dam_driver = {
627 .probe = tegra30_dam_probe,
628 .remove = __devexit_p(tegra30_dam_remove),
629 .driver = {
630 .name = DRV_NAME,
631 .owner = THIS_MODULE,
632 },
633};
634
635static int __init tegra30_dam_modinit(void)
636{
637 return platform_driver_register(&tegra30_dam_driver);
638}
639module_init(tegra30_dam_modinit);
640
641static void __exit tegra30_dam_modexit(void)
642{
643 platform_driver_unregister(&tegra30_dam_driver);
644}
645module_exit(tegra30_dam_modexit);
646
647MODULE_AUTHOR("Nikesh Oswal <noswal@nvidia.com>");
648MODULE_DESCRIPTION("Tegra 30 DAM driver");
649MODULE_LICENSE("GPL");
650MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra30_dam.h b/sound/soc/tegra/tegra30_dam.h
new file mode 100644
index 00000000000..371e8139eec
--- /dev/null
+++ b/sound/soc/tegra/tegra30_dam.h
@@ -0,0 +1,163 @@
1/*
2 * tegra30_dam.h - Tegra 30 DAM driver.
3 *
4 * Author: Nikesh Oswal <noswal@nvidia.com>
5 * Copyright (C) 2011 - 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#ifndef __TEGRA30_DAM_H
24#define __TEGRA30_DAM_H
25
26/* Register offsets from TEGRA30_DAM*_BASE */
27#define TEGRA30_DAM_CTRL 0
28#define TEGRA30_DAM_CLIP 4
29#define TEGRA30_DAM_CLIP_THRESHOLD 8
30#define TEGRA30_DAM_AUDIOCIF_OUT_CTRL 0x0C
31#define TEGRA30_DAM_CH0_CTRL 0x10
32#define TEGRA30_DAM_CH0_CONV 0x14
33#define TEGRA30_DAM_AUDIOCIF_CH0_CTRL 0x1C
34#define TEGRA30_DAM_CH1_CTRL 0x20
35#define TEGRA30_DAM_CH1_CONV 0x24
36#define TEGRA30_DAM_AUDIOCIF_CH1_CTRL 0x2C
37#define TEGRA30_DAM_CTRL_REGINDEX (TEGRA30_DAM_AUDIOCIF_CH1_CTRL >> 2)
38#define TEGRA30_DAM_CTRL_RSVD_6 6
39#define TEGRA30_DAM_CTRL_RSVD_10 10
40
41#define TEGRA30_NR_DAM_IFC 3
42
43#define TEGRA30_DAM_NUM_INPUT_CHANNELS 2
44
45/* Fields in TEGRA30_DAM_CTRL */
46#define TEGRA30_DAM_CTRL_SOFT_RESET_ENABLE (1 << 31)
47#define TEGRA30_DAM_CTRL_FSOUT_SHIFT 4
48#define TEGRA30_DAM_CTRL_FSOUT_MASK (0xf << TEGRA30_DAM_CTRL_FSOUT_SHIFT)
49#define TEGRA30_DAM_FS_8KHZ 0
50#define TEGRA30_DAM_FS_16KHZ 1
51#define TEGRA30_DAM_FS_44KHZ 2
52#define TEGRA30_DAM_FS_48KHZ 3
53#define TEGRA30_DAM_CTRL_FSOUT_FS8 (TEGRA30_DAM_FS_8KHZ << TEGRA30_DAM_CTRL_FSOUT_SHIFT)
54#define TEGRA30_DAM_CTRL_FSOUT_FS16 (TEGRA30_DAM_FS_16KHZ << TEGRA30_DAM_CTRL_FSOUT_SHIFT)
55#define TEGRA30_DAM_CTRL_FSOUT_FS44 (TEGRA30_DAM_FS_44KHZ << TEGRA30_DAM_CTRL_FSOUT_SHIFT)
56#define TEGRA30_DAM_CTRL_FSOUT_FS48 (TEGRA30_DAM_FS_48KHZ << TEGRA30_DAM_CTRL_FSOUT_SHIFT)
57#define TEGRA30_DAM_CTRL_CG_EN (1 << 1)
58#define TEGRA30_DAM_CTRL_DAM_EN (1 << 0)
59
60
61/* Fields in TEGRA30_DAM_CLIP */
62#define TEGRA30_DAM_CLIP_COUNTER_ENABLE (1 << 31)
63#define TEGRA30_DAM_CLIP_COUNT_MASK 0x7fffffff
64
65
66/* Fields in TEGRA30_DAM_CH0_CTRL */
67#define TEGRA30_STEP_RESET 1
68#define TEGRA30_DAM_DATA_SYNC 1
69#define TEGRA30_DAM_DATA_SYNC_SHIFT 4
70#define TEGRA30_DAM_CH0_CTRL_FSIN_SHIFT 8
71#define TEGRA30_DAM_CH0_CTRL_STEP_SHIFT 16
72#define TEGRA30_DAM_CH0_CTRL_STEP_MASK (0xffff << 16)
73#define TEGRA30_DAM_CH0_CTRL_STEP_RESET (TEGRA30_STEP_RESET << 16)
74#define TEGRA30_DAM_CH0_CTRL_FSIN_MASK (0xf << 8)
75#define TEGRA30_DAM_CH0_CTRL_FSIN_FS8 (TEGRA30_DAM_FS_8KHZ << 8)
76#define TEGRA30_DAM_CH0_CTRL_FSIN_FS16 (TEGRA30_DAM_FS_16KHZ << 8)
77#define TEGRA30_DAM_CH0_CTRL_FSIN_FS44 (TEGRA30_DAM_FS_44KHZ << 8)
78#define TEGRA30_DAM_CH0_CTRL_FSIN_FS48 (TEGRA30_DAM_FS_48KHZ << 8)
79#define TEGRA30_DAM_CH0_CTRL_DATA_SYNC_MASK (0xf << TEGRA30_DAM_DATA_SYNC_SHIFT)
80#define TEGRA30_DAM_CH0_CTRL_DATA_SYNC (TEGRA30_DAM_DATA_SYNC << TEGRA30_DAM_DATA_SYNC_SHIFT)
81#define TEGRA30_DAM_CH0_CTRL_EN (1 << 0)
82
83
84/* Fields in TEGRA30_DAM_CH0_CONV */
85#define TEGRA30_DAM_GAIN 1
86#define TEGRA30_DAM_GAIN_SHIFT 0
87#define TEGRA30_DAM_CH0_CONV_GAIN (TEGRA30_DAM_GAIN << TEGRA30_DAM_GAIN_SHIFT)
88
89/* Fields in TEGRA30_DAM_CH1_CTRL */
90#define TEGRA30_DAM_CH1_CTRL_DATA_SYNC_MASK (0xf << TEGRA30_DAM_DATA_SYNC_SHIFT)
91#define TEGRA30_DAM_CH1_CTRL_DATA_SYNC (TEGRA30_DAM_DATA_SYNC << TEGRA30_DAM_DATA_SYNC_SHIFT)
92#define TEGRA30_DAM_CH1_CTRL_EN (1 << 0)
93
94/* Fields in TEGRA30_DAM_CH1_CONV */
95#define TEGRA30_DAM_CH1_CONV_GAIN (TEGRA30_DAM_GAIN << TEGRA30_DAM_GAIN_SHIFT)
96
97#define TEGRA30_AUDIO_CHANNELS_SHIFT 24
98#define TEGRA30_AUDIO_CHANNELS_MASK (7 << TEGRA30_AUDIO_CHANNELS_SHIFT)
99#define TEGRA30_CLIENT_CHANNELS_SHIFT 16
100#define TEGRA30_CLIENT_CHANNELS_MASK (7 << TEGRA30_CLIENT_CHANNELS_SHIFT)
101#define TEGRA30_AUDIO_BITS_SHIFT 12
102#define TEGRA30_AUDIO_BITS_MASK (7 << TEGRA30_AUDIO_BITS_SHIFT)
103#define TEGRA30_CLIENT_BITS_SHIFT 8
104#define TEGRA30_CLIENT_BITS_MASK (7 << TEGRA30_CLIENT_BITS_SHIFT)
105#define TEGRA30_CIF_DIRECTION_TX (0 << 2)
106#define TEGRA30_CIF_DIRECTION_RX (1 << 2)
107#define TEGRA30_CIF_BIT24 5
108#define TEGRA30_CIF_BIT16 3
109#define TEGRA30_CIF_CH1 0
110#define TEGRA30_CIF_MONOCONV_COPY (1<<0)
111#define TEGRA30_CIF_STEREOCONV_CH0 (0<<4)
112
113/*
114* Audio Samplerates
115*/
116#define TEGRA30_AUDIO_SAMPLERATE_8000 8000
117#define TEGRA30_AUDIO_SAMPLERATE_16000 16000
118#define TEGRA30_AUDIO_SAMPLERATE_44100 44100
119#define TEGRA30_AUDIO_SAMPLERATE_48000 48000
120
121#define TEGRA30_DAM_CHIN0_SRC 0
122#define TEGRA30_DAM_CHIN1 1
123#define TEGRA30_DAM_CHOUT 2
124#define TEGRA30_DAM_ENABLE 1
125#define TEGRA30_DAM_DISABLE 0
126
127struct tegra30_dam_context {
128 int outsamplerate;
129 bool ch_alloc[TEGRA30_DAM_NUM_INPUT_CHANNELS];
130 int ch_enable_refcnt[TEGRA30_DAM_NUM_INPUT_CHANNELS];
131 int ch_insamplerate[TEGRA30_DAM_NUM_INPUT_CHANNELS];
132#ifdef CONFIG_PM
133 int reg_cache[TEGRA30_DAM_CTRL_REGINDEX + 1];
134#endif
135 struct clk *dam_clk;
136 bool in_use;
137 void __iomem *damregs;
138 struct dentry *debug;
139};
140
141struct tegra30_dam_src_step_table {
142 int insample;
143 int outsample;
144 int stepreset;
145};
146
147#ifdef CONFIG_PM
148int tegra30_dam_resume(int ifc);
149#endif
150void tegra30_dam_disable_clock(int ifc);
151int tegra30_dam_enable_clock(int ifc);
152int tegra30_dam_allocate_controller(void);
153int tegra30_dam_allocate_channel(int ifc, int chid);
154int tegra30_dam_free_channel(int ifc, int chid);
155int tegra30_dam_free_controller(int ifc);
156void tegra30_dam_set_samplerate(int ifc, int chtype, int samplerate);
157int tegra30_dam_set_gain(int ifc, int chtype, int gain);
158int tegra30_dam_set_acif(int ifc, int chtype, unsigned int audio_channels,
159 unsigned int audio_bits, unsigned int client_channels,
160 unsigned int client_bits);
161void tegra30_dam_enable(int ifc, int on, int chtype);
162
163#endif
diff --git a/sound/soc/tegra/tegra30_spdif.c b/sound/soc/tegra/tegra30_spdif.c
new file mode 100644
index 00000000000..038127c0afb
--- /dev/null
+++ b/sound/soc/tegra/tegra30_spdif.c
@@ -0,0 +1,505 @@
1/*
2 * tegra30_spdif.c - Tegra30 SPDIF driver
3 *
4 * Author: Sumit Bhattacharya <sumitb@nvidia.com>
5 * Copyright (C) 2011 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * Copyright (c) 2009-2011, NVIDIA Corporation.
10 * Scott Peterson <speterson@nvidia.com>
11 *
12 * Copyright (C) 2010 Google, Inc.
13 * Iliyan Malchev <malchev@google.com>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2 as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 *
29 */
30
31#include <linux/clk.h>
32#include <linux/module.h>
33#include <linux/debugfs.h>
34#include <linux/device.h>
35#include <linux/platform_device.h>
36#include <linux/seq_file.h>
37#include <linux/slab.h>
38#include <linux/io.h>
39#include <mach/iomap.h>
40#include <mach/hdmi-audio.h>
41#include <sound/core.h>
42#include <sound/pcm.h>
43#include <sound/pcm_params.h>
44#include <sound/soc.h>
45
46#include "tegra30_spdif.h"
47
48#define DRV_NAME "tegra30-spdif"
49
50static inline void tegra30_spdif_write(struct tegra30_spdif *spdif,
51 u32 reg, u32 val)
52{
53 __raw_writel(val, spdif->regs + reg);
54}
55
56static inline u32 tegra30_spdif_read(struct tegra30_spdif *spdif, u32 reg)
57{
58 return __raw_readl(spdif->regs + reg);
59}
60
61static void tegra30_spdif_enable_clocks(struct tegra30_spdif *spdif)
62{
63 clk_enable(spdif->clk_spdif_out);
64 tegra30_ahub_enable_clocks();
65}
66
67static void tegra30_spdif_disable_clocks(struct tegra30_spdif *spdif)
68{
69 tegra30_ahub_disable_clocks();
70 clk_disable(spdif->clk_spdif_out);
71}
72
73#ifdef CONFIG_DEBUG_FS
74static int tegra30_spdif_show(struct seq_file *s, void *unused)
75{
76#define REG(r) { r, #r }
77 static const struct {
78 int offset;
79 const char *name;
80 } regs[] = {
81 REG(TEGRA30_SPDIF_CTRL),
82 REG(TEGRA30_SPDIF_STROBE_CTRL),
83 REG(TEGRA30_SPDIF_CIF_TXD_CTRL),
84 REG(TEGRA30_SPDIF_CIF_RXD_CTRL),
85 REG(TEGRA30_SPDIF_CIF_TXU_CTRL),
86 REG(TEGRA30_SPDIF_CIF_RXU_CTRL),
87 REG(TEGRA30_SPDIF_CH_STA_RX_A),
88 REG(TEGRA30_SPDIF_CH_STA_RX_B),
89 REG(TEGRA30_SPDIF_CH_STA_RX_C),
90 REG(TEGRA30_SPDIF_CH_STA_RX_D),
91 REG(TEGRA30_SPDIF_CH_STA_RX_E),
92 REG(TEGRA30_SPDIF_CH_STA_RX_F),
93 REG(TEGRA30_SPDIF_CH_STA_TX_A),
94 REG(TEGRA30_SPDIF_CH_STA_TX_B),
95 REG(TEGRA30_SPDIF_CH_STA_TX_C),
96 REG(TEGRA30_SPDIF_CH_STA_TX_D),
97 REG(TEGRA30_SPDIF_CH_STA_TX_E),
98 REG(TEGRA30_SPDIF_CH_STA_TX_F),
99 REG(TEGRA30_SPDIF_FLOWCTL_CTRL),
100 REG(TEGRA30_SPDIF_TX_STEP),
101 REG(TEGRA30_SPDIF_FLOW_STATUS),
102 REG(TEGRA30_SPDIF_FLOW_TOTAL),
103 REG(TEGRA30_SPDIF_FLOW_OVER),
104 REG(TEGRA30_SPDIF_FLOW_UNDER),
105 REG(TEGRA30_SPDIF_LCOEF_1_4_0),
106 REG(TEGRA30_SPDIF_LCOEF_1_4_1),
107 REG(TEGRA30_SPDIF_LCOEF_1_4_2),
108 REG(TEGRA30_SPDIF_LCOEF_1_4_3),
109 REG(TEGRA30_SPDIF_LCOEF_1_4_4),
110 REG(TEGRA30_SPDIF_LCOEF_1_4_5),
111 REG(TEGRA30_SPDIF_LCOEF_2_4_0),
112 REG(TEGRA30_SPDIF_LCOEF_2_4_1),
113 REG(TEGRA30_SPDIF_LCOEF_2_4_2),
114 };
115#undef REG
116
117 struct tegra30_spdif *spdif = s->private;
118 int i;
119
120 tegra30_spdif_enable_clocks(spdif);
121
122 for (i = 0; i < ARRAY_SIZE(regs); i++) {
123 u32 val = tegra30_spdif_read(spdif, regs[i].offset);
124 seq_printf(s, "%s = %08x\n", regs[i].name, val);
125 }
126
127 tegra30_spdif_disable_clocks(spdif);
128
129 return 0;
130}
131
132static int tegra30_spdif_debug_open(struct inode *inode, struct file *file)
133{
134 return single_open(file, tegra30_spdif_show, inode->i_private);
135}
136
137static const struct file_operations tegra30_spdif_debug_fops = {
138 .open = tegra30_spdif_debug_open,
139 .read = seq_read,
140 .llseek = seq_lseek,
141 .release = single_release,
142};
143
144static void tegra30_spdif_debug_add(struct tegra30_spdif *spdif)
145{
146 char name[] = DRV_NAME;
147
148 spdif->debug = debugfs_create_file(name, S_IRUGO, snd_soc_debugfs_root,
149 spdif, &tegra30_spdif_debug_fops);
150}
151
152static void tegra30_spdif_debug_remove(struct tegra30_spdif *spdif)
153{
154 if (spdif->debug)
155 debugfs_remove(spdif->debug);
156}
157#else
158static inline void tegra30_spdif_debug_add(struct tegra30_spdif *spdif)
159{
160}
161
162static inline void tegra30_spdif_debug_remove(struct tegra30_spdif *spdif)
163{
164}
165#endif
166
167int tegra30_spdif_startup(struct snd_pcm_substream *substream,
168 struct snd_soc_dai *dai)
169{
170 struct tegra30_spdif *spdif = snd_soc_dai_get_drvdata(dai);
171 int ret = 0;
172
173 tegra30_spdif_enable_clocks(spdif);
174
175 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
176 ret = tegra30_ahub_allocate_tx_fifo(&spdif->txcif,
177 &spdif->playback_dma_data.addr,
178 &spdif->playback_dma_data.req_sel);
179 spdif->playback_dma_data.wrap = 4;
180 spdif->playback_dma_data.width = 32;
181 tegra30_ahub_set_rx_cif_source(TEGRA30_AHUB_RXCIF_SPDIF_RX0,
182 spdif->txcif);
183 }
184
185 tegra30_spdif_disable_clocks(spdif);
186
187 return ret;
188}
189
190void tegra30_spdif_shutdown(struct snd_pcm_substream *substream,
191 struct snd_soc_dai *dai)
192{
193 struct tegra30_spdif *spdif = snd_soc_dai_get_drvdata(dai);
194
195 tegra30_spdif_enable_clocks(spdif);
196
197 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
198 tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_SPDIF_RX0);
199 tegra30_ahub_free_tx_fifo(spdif->txcif);
200 }
201
202 tegra30_spdif_disable_clocks(spdif);
203}
204
205static int tegra30_spdif_hw_params(struct snd_pcm_substream *substream,
206 struct snd_pcm_hw_params *params,
207 struct snd_soc_dai *dai)
208{
209 struct device *dev = substream->pcm->card->dev;
210 struct tegra30_spdif *spdif = snd_soc_dai_get_drvdata(dai);
211 int ret, srate, spdifclock;
212
213 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) {
214 dev_err(dev, "spdif capture is not supported\n");
215 return -EINVAL;
216 }
217
218 spdif->reg_ctrl &= ~TEGRA30_SPDIF_CTRL_BIT_MODE_MASK;
219 switch (params_format(params)) {
220 case SNDRV_PCM_FORMAT_S16_LE:
221 spdif->reg_ctrl |= TEGRA30_SPDIF_CTRL_PACK_ENABLE;
222 spdif->reg_ctrl |= TEGRA30_SPDIF_CTRL_BIT_MODE_16BIT;
223 break;
224 default:
225 return -EINVAL;
226 }
227
228 srate = params_rate(params);
229 spdif->reg_ch_sta_a &= ~TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_MASK;
230 spdif->reg_ch_sta_b &= ~TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_MASK;
231 switch (srate) {
232 case 32000:
233 spdifclock = 4096000;
234 spdif->reg_ch_sta_a |=
235 TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_32000;
236 spdif->reg_ch_sta_b |=
237 TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_32000;
238 break;
239 case 44100:
240 spdifclock = 5644800;
241 spdif->reg_ch_sta_a |=
242 TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_44100;
243 spdif->reg_ch_sta_b |=
244 TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_44100;
245 break;
246 case 48000:
247 spdifclock = 6144000;
248 spdif->reg_ch_sta_a |=
249 TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_48000;
250 spdif->reg_ch_sta_b |=
251 TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_48000;
252 break;
253 case 88200:
254 spdifclock = 11289600;
255 spdif->reg_ch_sta_a |=
256 TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_88200;
257 spdif->reg_ch_sta_b |=
258 TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_88200;
259 break;
260 case 96000:
261 spdifclock = 12288000;
262 spdif->reg_ch_sta_a |=
263 TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_96000;
264 spdif->reg_ch_sta_b |=
265 TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_96000;
266 break;
267 case 176400:
268 spdifclock = 22579200;
269 spdif->reg_ch_sta_a |=
270 TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_176400;
271 spdif->reg_ch_sta_b |=
272 TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_176400;
273 break;
274 case 192000:
275 spdifclock = 24576000;
276 spdif->reg_ch_sta_a |=
277 TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_192000;
278 spdif->reg_ch_sta_b |=
279 TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_192000;
280 break;
281 default:
282 return -EINVAL;
283 }
284
285 ret = clk_set_rate(spdif->clk_spdif_out, spdifclock);
286 if (ret) {
287 dev_err(dev, "Can't set SPDIF clock rate: %d\n", ret);
288 return ret;
289 }
290
291 tegra30_spdif_enable_clocks(spdif);
292
293 tegra30_spdif_write(spdif, TEGRA30_SPDIF_CH_STA_TX_A,
294 spdif->reg_ch_sta_a);
295 tegra30_spdif_write(spdif, TEGRA30_SPDIF_CH_STA_TX_B,
296 spdif->reg_ch_sta_b);
297
298 tegra30_spdif_disable_clocks(spdif);
299
300 ret = tegra_hdmi_setup_audio_freq_source(srate, SPDIF);
301 if (ret) {
302 dev_err(dev, "Can't set HDMI audio freq source: %d\n", ret);
303 return ret;
304 }
305
306 return 0;
307}
308
309static void tegra30_spdif_start_playback(struct tegra30_spdif *spdif)
310{
311 tegra30_ahub_enable_tx_fifo(spdif->txcif);
312 spdif->reg_ctrl |= TEGRA30_SPDIF_CTRL_TX_EN_ENABLE |
313 TEGRA30_SPDIF_CTRL_TC_EN_ENABLE;
314 tegra30_spdif_write(spdif, TEGRA30_SPDIF_CTRL, spdif->reg_ctrl);
315}
316
317static void tegra30_spdif_stop_playback(struct tegra30_spdif *spdif)
318{
319 tegra30_ahub_disable_tx_fifo(spdif->txcif);
320 spdif->reg_ctrl &= ~(TEGRA30_SPDIF_CTRL_TX_EN_ENABLE |
321 TEGRA30_SPDIF_CTRL_TC_EN_ENABLE);
322 tegra30_spdif_write(spdif, TEGRA30_SPDIF_CTRL, spdif->reg_ctrl);
323}
324
325static int tegra30_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
326 struct snd_soc_dai *dai)
327{
328 struct tegra30_spdif *spdif = snd_soc_dai_get_drvdata(dai);
329
330 switch (cmd) {
331 case SNDRV_PCM_TRIGGER_START:
332 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
333 case SNDRV_PCM_TRIGGER_RESUME:
334 tegra30_spdif_enable_clocks(spdif);
335 tegra30_spdif_start_playback(spdif);
336 break;
337 case SNDRV_PCM_TRIGGER_STOP:
338 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
339 case SNDRV_PCM_TRIGGER_SUSPEND:
340 tegra30_spdif_stop_playback(spdif);
341 tegra30_spdif_disable_clocks(spdif);
342 break;
343 default:
344 return -EINVAL;
345 }
346
347 return 0;
348}
349
350static int tegra30_spdif_probe(struct snd_soc_dai *dai)
351{
352 struct tegra30_spdif *spdif = snd_soc_dai_get_drvdata(dai);
353
354 dai->playback_dma_data = &spdif->playback_dma_data;
355 dai->capture_dma_data = NULL;
356
357 return 0;
358}
359
360static struct snd_soc_dai_ops tegra30_spdif_dai_ops = {
361 .startup = tegra30_spdif_startup,
362 .shutdown = tegra30_spdif_shutdown,
363 .hw_params = tegra30_spdif_hw_params,
364 .trigger = tegra30_spdif_trigger,
365};
366
367struct snd_soc_dai_driver tegra30_spdif_dai = {
368 .name = DRV_NAME,
369 .probe = tegra30_spdif_probe,
370 .playback = {
371 .channels_min = 2,
372 .channels_max = 2,
373 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
374 SNDRV_PCM_RATE_48000,
375 .formats = SNDRV_PCM_FMTBIT_S16_LE,
376 },
377 .ops = &tegra30_spdif_dai_ops,
378};
379
380static __devinit int tegra30_spdif_platform_probe(struct platform_device *pdev)
381{
382 struct tegra30_spdif *spdif;
383 struct resource *mem, *memregion;
384 int ret;
385 u32 reg_val;
386
387 spdif = kzalloc(sizeof(struct tegra30_spdif), GFP_KERNEL);
388 if (!spdif) {
389 dev_err(&pdev->dev, "Can't allocate tegra30_spdif\n");
390 ret = -ENOMEM;
391 goto exit;
392 }
393 dev_set_drvdata(&pdev->dev, spdif);
394
395 spdif->clk_spdif_out = clk_get(&pdev->dev, "spdif_out");
396 if (IS_ERR(spdif->clk_spdif_out)) {
397 dev_err(&pdev->dev, "Can't retrieve spdif clock\n");
398 ret = PTR_ERR(spdif->clk_spdif_out);
399 goto err_free;
400 }
401
402 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
403 if (!mem) {
404 dev_err(&pdev->dev, "No memory resource\n");
405 ret = -ENODEV;
406 goto err_clk_put_spdif;
407 }
408
409 memregion = request_mem_region(mem->start, resource_size(mem),
410 DRV_NAME);
411 if (!memregion) {
412 dev_err(&pdev->dev, "Memory region already claimed\n");
413 ret = -EBUSY;
414 goto err_clk_put_spdif;
415 }
416
417 spdif->regs = ioremap(mem->start, resource_size(mem));
418 if (!spdif->regs) {
419 dev_err(&pdev->dev, "ioremap failed\n");
420 ret = -ENOMEM;
421 goto err_release;
422 }
423
424 tegra30_spdif_enable_clocks(spdif);
425
426 reg_val = TEGRA30_SPDIF_CIF_TXD_CTRL_DIRECTION_RXCIF |
427 TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BIT16 |
428 TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BIT16 |
429 TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH2 |
430 TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH2 |
431 (3 << TEGRA30_SPDIF_CIF_TXD_CTRL_FIFO_TH_SHIFT);
432
433 tegra30_spdif_write(spdif, TEGRA30_SPDIF_CIF_TXD_CTRL, reg_val);
434
435 tegra30_spdif_disable_clocks(spdif);
436
437 ret = snd_soc_register_dai(&pdev->dev, &tegra30_spdif_dai);
438 if (ret) {
439 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
440 ret = -ENOMEM;
441 goto err_unmap;
442 }
443
444 tegra30_spdif_debug_add(spdif);
445
446 return 0;
447
448err_unmap:
449 iounmap(spdif->regs);
450err_release:
451 release_mem_region(mem->start, resource_size(mem));
452err_clk_put_spdif:
453 clk_put(spdif->clk_spdif_out);
454err_free:
455 kfree(spdif);
456exit:
457 return ret;
458}
459
460static int __devexit tegra30_spdif_platform_remove(struct platform_device *pdev)
461{
462 struct tegra30_spdif *spdif = dev_get_drvdata(&pdev->dev);
463 struct resource *res;
464
465 snd_soc_unregister_dai(&pdev->dev);
466
467 tegra30_spdif_debug_remove(spdif);
468
469 iounmap(spdif->regs);
470
471 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
472 release_mem_region(res->start, resource_size(res));
473
474 clk_put(spdif->clk_spdif_out);
475
476 kfree(spdif);
477
478 return 0;
479}
480
481static struct platform_driver tegra30_spdif_driver = {
482 .driver = {
483 .name = DRV_NAME,
484 .owner = THIS_MODULE,
485 },
486 .probe = tegra30_spdif_platform_probe,
487 .remove = __devexit_p(tegra30_spdif_platform_remove),
488};
489
490static int __init snd_tegra30_spdif_init(void)
491{
492 return platform_driver_register(&tegra30_spdif_driver);
493}
494module_init(snd_tegra30_spdif_init);
495
496static void __exit snd_tegra30_spdif_exit(void)
497{
498 platform_driver_unregister(&tegra30_spdif_driver);
499}
500module_exit(snd_tegra30_spdif_exit);
501
502MODULE_AUTHOR("Sumit Bhattacharya <sumitb@nvidia.com>");
503MODULE_DESCRIPTION("Tegra30 SPDIF ASoC driver");
504MODULE_LICENSE("GPL");
505MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra30_spdif.h b/sound/soc/tegra/tegra30_spdif.h
new file mode 100644
index 00000000000..c4763c31b25
--- /dev/null
+++ b/sound/soc/tegra/tegra30_spdif.h
@@ -0,0 +1,777 @@
1/*
2 * tegra30_spdif.h - Definitions for Tegra30 SPDIF driver
3 *
4 * Author: Sumit Bhattacharya <sumitb@nvidia.com>
5 * Copyright (C) 2011 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * Copyright (c) 2009-2011, NVIDIA Corporation.
10 * Scott Peterson <speterson@nvidia.com>
11 *
12 * Copyright (C) 2010 Google, Inc.
13 * Iliyan Malchev <malchev@google.com>
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2 as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 *
29 */
30
31#ifndef __TEGRA30_SPDIF_H__
32#define __TEGRA30_SPDIF_H__
33
34#include "tegra_pcm.h"
35#include "tegra30_ahub.h"
36
37/* Register offsets from TEGRA_SPDIF_BASE */
38
39#define TEGRA30_SPDIF_CTRL 0x0
40#define TEGRA30_SPDIF_STROBE_CTRL 0x4
41#define TEGRA30_SPDIF_CIF_TXD_CTRL 0x08
42#define TEGRA30_SPDIF_CIF_RXD_CTRL 0x0C
43#define TEGRA30_SPDIF_CIF_TXU_CTRL 0x10
44#define TEGRA30_SPDIF_CIF_RXU_CTRL 0x14
45#define TEGRA30_SPDIF_CH_STA_RX_A 0x18
46#define TEGRA30_SPDIF_CH_STA_RX_B 0x1C
47#define TEGRA30_SPDIF_CH_STA_RX_C 0x20
48#define TEGRA30_SPDIF_CH_STA_RX_D 0x24
49#define TEGRA30_SPDIF_CH_STA_RX_E 0x28
50#define TEGRA30_SPDIF_CH_STA_RX_F 0x2C
51#define TEGRA30_SPDIF_CH_STA_TX_A 0x30
52#define TEGRA30_SPDIF_CH_STA_TX_B 0x34
53#define TEGRA30_SPDIF_CH_STA_TX_C 0x38
54#define TEGRA30_SPDIF_CH_STA_TX_D 0x3C
55#define TEGRA30_SPDIF_CH_STA_TX_E 0x40
56#define TEGRA30_SPDIF_CH_STA_TX_F 0x44
57#define TEGRA30_SPDIF_FLOWCTL_CTRL 0x70
58#define TEGRA30_SPDIF_TX_STEP 0x74
59#define TEGRA30_SPDIF_FLOW_STATUS 0x78
60#define TEGRA30_SPDIF_FLOW_TOTAL 0x7c
61#define TEGRA30_SPDIF_FLOW_OVER 0x80
62#define TEGRA30_SPDIF_FLOW_UNDER 0x84
63#define TEGRA30_SPDIF_LCOEF_1_4_0 0x88
64#define TEGRA30_SPDIF_LCOEF_1_4_1 0x8c
65#define TEGRA30_SPDIF_LCOEF_1_4_2 0x90
66#define TEGRA30_SPDIF_LCOEF_1_4_3 0x94
67#define TEGRA30_SPDIF_LCOEF_1_4_4 0x98
68#define TEGRA30_SPDIF_LCOEF_1_4_5 0x9c
69#define TEGRA30_SPDIF_LCOEF_2_4_0 0xa0
70#define TEGRA30_SPDIF_LCOEF_2_4_1 0xa4
71#define TEGRA30_SPDIF_LCOEF_2_4_2 0xa8
72
73/* Fields in TEGRA30_SPDIF_CTRL */
74#define TEGRA30_SPDIF_CTRL_FLOWCTL_EN_ENABLE (1<<31)
75#define TEGRA30_SPDIF_CTRL_CAP_LC_LEFT_CH (1<<30)
76#define TEGRA30_SPDIF_CTRL_RX_EN_ENABLE (1<<29)
77#define TEGRA30_SPDIF_CTRL_TX_EN_ENABLE (1<<28)
78#define TEGRA30_SPDIF_CTRL_TC_EN_ENABLE (1<<27)
79#define TEGRA30_SPDIF_CTRL_TU_EN_ENABLE (1<<26)
80#define TEGRA30_SPDIF_CTRL_IE_P_RSVD_ENABLE (1<<23)
81#define TEGRA30_SPDIF_CTRL_IE_B_RSVD_ENABLE (1<<22)
82#define TEGRA30_SPDIF_CTRL_IE_C_RSVD_ENABLE (1<<21)
83#define TEGRA30_SPDIF_CTRL_IE_U_RSVD_ENABLE (1<<20)
84#define TEGRA30_SPDIF_CTRL_LBK_EN_ENABLE (1<<15)
85#define TEGRA30_SPDIF_CTRL_PACK_ENABLE (1<<14)
86
87#define TEGRA30_SPDIF_BIT_MODE16 0
88#define TEGRA30_SPDIF_BIT_MODE20 1
89#define TEGRA30_SPDIF_BIT_MODE24 2
90#define TEGRA30_SPDIF_BIT_MODERAW 3
91
92#define TEGRA30_SPDIF_CTRL_BIT_MODE_SHIFT 12
93#define TEGRA30_SPDIF_CTRL_BIT_MODE_MASK (3 << TEGRA30_SPDIF_CTRL_BIT_MODE_SHIFT)
94#define TEGRA30_SPDIF_CTRL_BIT_MODE_16BIT (TEGRA30_SPDIF_BIT_MODE16 << TEGRA30_SPDIF_CTRL_BIT_MODE_SHIFT)
95#define TEGRA30_SPDIF_CTRL_BIT_MODE_20BIT (TEGRA30_SPDIF_BIT_MODE20 << TEGRA30_SPDIF_CTRL_BIT_MODE_SHIFT)
96#define TEGRA30_SPDIF_CTRL_BIT_MODE_24BIT (TEGRA30_SPDIF_BIT_MODE24 << TEGRA30_SPDIF_CTRL_BIT_MODE_SHIFT)
97#define TEGRA30_SPDIF_CTRL_BIT_MODE_RAW (TEGRA30_SPDIF_BIT_MODERAW << TEGRA30_SPDIF_CTRL_BIT_MODE_SHIFT)
98
99#define TEGRA30_SPDIF_CTRL_CG_EN_ENABLE (1<<11)
100
101#define TEGRA30_SPDIF_CTRL_OBS_SEL_SHIFT 8
102#define TEGRA30_SPDIF_CTRL_OBS_SEL_NASK (0x7 << TEGRA30_SPDIF_CTRL_OBS_SEL_SHIFT)
103
104#define TEGRA30_SPDIF_CTRL_SOFT_RESET_ENABLE (1<<7)
105
106/* Fields in TEGRA30_SPDIF_STROBE_CTRL */
107#define TEGRA30_SPDIF_STROBE_CTRL_PERIOD_SHIFT 16
108#define TEGRA30_SPDIF_STROBE_CTRL_PERIOD_MASK (0xff << TEGRA30_SPDIF_STROBE_CTRL_PERIOD_SHIFT)
109
110#define TEGRA30_SPDIF_STROBE_CTRL_STROBE (1<<15)
111
112#define TEGRA30_SPDIF_STROBE_CTRL_DATA_STROBES_SHIFT 8
113#define TEGRA30_SPDIF_STROBE_CTRL_DATA_STROBES_MASK (0x1f << TEGRA30_SPDIF_STROBE_CTRL_DATA_STROBES_SHIFT)
114
115#define TEGRA30_SPDIF_STROBE_CTRL_CLOCK_PERIOD_SHIFT 0
116#define TEGRA30_SPDIF_STROBE_CTRL_CLOCK_PERIOD_MASK (0x3f << TEGRA30_SPDIF_STROBE_CTRL_CLOCK_PERIOD_SHIFT)
117
118/* Fields in TEGRA30_SPDIF_CIF_TXD_CTRL */
119#define TEGRA30_SPDIF_CIF_TXD_CTRL_MONO_CONV_COPY (1<<0)
120#define TEGRA30_SPDIF_CIF_TXD_CTRL_TRUNCATE_CHOP (1<<1)
121#define TEGRA30_SPDIF_CIF_TXD_CTRL_DIRECTION_RXCIF (1<<2)
122#define TEGRA30_SPDIF_CIF_TXD_CTRL_REPLICATE_ENABLE (1<<3)
123
124#define TEGRA30_SPDIF_CIF_STEREO_CH0 0
125#define TEGRA30_SPDIF_CIF_STEREO_CH1 1
126#define TEGRA30_SPDIF_CIF_STEREO_AVG 2
127#define TEGRA30_SPDIF_CIF_STEREO_RSVD 3
128
129#define TEGRA30_SPDIF_CIF_TXD_CTRL_STEREO_CONV_SHIFT 4
130#define TEGRA30_SPDIF_CIF_TXD_CTRL_STEREO_CONV_MASK \
131 (0x3 << TEGRA30_SPDIF_CIF_TXD_CTRL_STEREO_CONV_SHIFT)
132#define TEGRA30_SPDIF_CIF_TXD_CTRL_STEREO_CONV_CH0 \
133 (TEGRA30_SPDIF_CIF_STEREO_CH0 << TEGRA30_SPDIF_CIF_TXD_CTRL_STEREO_CONV_SHIFT)
134#define TEGRA30_SPDIF_CIF_TXD_CTRL_STEREO_CONV_CH1 \
135 (TEGRA30_SPDIF_CIF_STEREO_CH1 << TEGRA30_SPDIF_CIF_TXD_CTRL_STEREO_CONV_SHIFT)
136#define TEGRA30_SPDIF_CIF_TXD_CTRL_STEREO_CONV_AVG \
137 (TEGRA30_SPDIF_CIF_STEREO_AVG << TEGRA30_SPDIF_CIF_TXD_CTRL_STEREO_CONV_SHIFT)
138#define TEGRA30_SPDIF_CIF_TXD_CTRL_STEREO_CONV_RSVD \
139 (TEGRA30_SPDIF_CIF_STEREO_RSVD << TEGRA30_SPDIF_CIF_TXD_CTRL_STEREO_CONV_SHIFT)
140
141#define TEGRA30_SPDIF_CIF_EXPAND_ZERO 0
142#define TEGRA30_SPDIF_CIF_EXPAND_ONE 1
143#define TEGRA30_SPDIF_CIF_EXPAND_LFSR 2
144#define TEGRA30_SPDIF_CIF_EXPAND_RSVD 3
145
146#define TEGRA30_SPDIF_CIF_TXD_CTRL_EXPAND_SHIFT 6
147#define TEGRA30_SPDIF_CIF_TXD_CTRL_EXPAND_MASK \
148 (0x3 << TEGRA30_SPDIF_CIF_TXD_CTRL_EXPAND_SHIFT)
149#define TEGRA30_SPDIF_CIF_TXD_CTRL_EXPAND_ZERO \
150 (TEGRA30_SPDIF_CIF_EXPAND_ZERO << TEGRA30_SPDIF_CIF_TXD_CTRL_EXPAND_SHIFT)
151#define TEGRA30_SPDIF_CIF_TXD_CTRL_EXPAND_ONE \
152 (TEGRA30_SPDIF_CIF_EXPAND_ONE << TEGRA30_SPDIF_CIF_TXD_CTRL_EXPAND_SHIFT)
153#define TEGRA30_SPDIF_CIF_TXD_CTRL_EXPAND_LFSR \
154 (TEGRA30_SPDIF_CIF_EXPAND_LFSR << TEGRA30_SPDIF_CIF_TXD_CTRL_EXPAND_SHIFT)
155#define TEGRA30_SPDIF_CIF_TXD_CTRL_EXPAND_RSVD \
156 (TEGRA30_SPDIF_CIF_EXPAND_RSVD << TEGRA30_SPDIF_CIF_TXD_CTRL_EXPAND_SHIFT)
157
158#define TEGRA30_SPDIF_CIF_BIT4 0
159#define TEGRA30_SPDIF_CIF_BIT8 1
160#define TEGRA30_SPDIF_CIF_BIT12 2
161#define TEGRA30_SPDIF_CIF_BIT16 3
162#define TEGRA30_SPDIF_CIF_BIT20 4
163#define TEGRA30_SPDIF_CIF_BIT24 5
164#define TEGRA30_SPDIF_CIF_BIT28 6
165#define TEGRA30_SPDIF_CIF_BIT32 7
166
167#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BITS_SHIFT 8
168#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BITS_MASK \
169 (0x7 << TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BITS_SHIFT)
170#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BIT4 \
171 (TEGRA30_SPDIF_CIF_BIT4 << TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BITS_SHIFT)
172#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BIT8 \
173 (TEGRA30_SPDIF_CIF_BIT8 << TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BITS_SHIFT)
174#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BIT12 \
175 (TEGRA30_SPDIF_CIF_BIT12 << TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BITS_SHIFT)
176#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BIT16 \
177 (TEGRA30_SPDIF_CIF_BIT16 << TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BITS_SHIFT)
178#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BIT20 \
179 (TEGRA30_SPDIF_CIF_BIT20 << TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BITS_SHIFT)
180#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BIT24 \
181 (TEGRA30_SPDIF_CIF_BIT24 << TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BITS_SHIFT)
182#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BIT28 \
183 (TEGRA30_SPDIF_CIF_BIT28 << TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BITS_SHIFT)
184#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BIT32 \
185 (TEGRA30_SPDIF_CIF_BIT32 << TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_BITS_SHIFT)
186
187
188#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BITS_SHIFT 12
189#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BITS_MASK \
190 (0x7 << TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BITS_SHIFT)
191#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BIT4 \
192 (TEGRA30_SPDIF_CIF_BIT4 << TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BITS_SHIFT)
193#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BIT8 \
194 (TEGRA30_SPDIF_CIF_BIT8 << TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BITS_SHIFT)
195#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BIT12 \
196 (TEGRA30_SPDIF_CIF_BIT12 << TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BITS_SHIFT)
197#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BIT16 \
198 (TEGRA30_SPDIF_CIF_BIT16 << TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BITS_SHIFT)
199#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BIT20 \
200 (TEGRA30_SPDIF_CIF_BIT20 << TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BITS_SHIFT)
201#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BIT24 \
202 (TEGRA30_SPDIF_CIF_BIT24 << TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BITS_SHIFT)
203#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BIT28 \
204 (TEGRA30_SPDIF_CIF_BIT28 << TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BITS_SHIFT)
205#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BIT32 \
206 (TEGRA30_SPDIF_CIF_BIT32 << TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_BITS_SHIFT)
207
208#define TEGRA30_SPDIF_CIF_CH1 0
209#define TEGRA30_SPDIF_CIF_CH2 1
210#define TEGRA30_SPDIF_CIF_CH3 2
211#define TEGRA30_SPDIF_CIF_CH4 3
212#define TEGRA30_SPDIF_CIF_CH5 4
213#define TEGRA30_SPDIF_CIF_CH6 5
214#define TEGRA30_SPDIF_CIF_CH7 6
215#define TEGRA30_SPDIF_CIF_CH8 7
216
217#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH_SHIFT 16
218#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH_MASK \
219 (0x7 << TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH_SHIFT)
220#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH1 \
221 (TEGRA30_SPDIF_CIF_CH1 << TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH_SHIFT)
222#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH2 \
223 (TEGRA30_SPDIF_CIF_CH2 << TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH_SHIFT)
224#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH3 \
225 (TEGRA30_SPDIF_CIF_CH3 << TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH_SHIFT)
226#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH4 \
227 (TEGRA30_SPDIF_CIF_CH4 << TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH_SHIFT)
228#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH5 \
229 (TEGRA30_SPDIF_CIF_CH5 << TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH_SHIFT)
230#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH6 \
231 (TEGRA30_SPDIF_CIF_CH6 << TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH_SHIFT)
232#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH7 \
233 (TEGRA30_SPDIF_CIF_CH7 << TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH_SHIFT)
234#define TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH8 \
235 (TEGRA30_SPDIF_CIF_CH8 << TEGRA30_SPDIF_CIF_TXD_CTRL_CLIENT_CH_SHIFT)
236
237
238#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH_SHIFT 24
239#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH_MASK \
240 (0x7 << TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH_SHIFT)
241#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH1 \
242 (TEGRA30_SPDIF_CIF_CH1 << TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH_SHIFT)
243#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH2 \
244 (TEGRA30_SPDIF_CIF_CH2 << TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH_SHIFT)
245#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH3 \
246 (TEGRA30_SPDIF_CIF_CH3 << TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH_SHIFT)
247#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH4 \
248 (TEGRA30_SPDIF_CIF_CH4 << TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH_SHIFT)
249#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH5 \
250 (TEGRA30_SPDIF_CIF_CH5 << TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH_SHIFT)
251#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH6 \
252 (TEGRA30_SPDIF_CIF_CH6 << TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH_SHIFT)
253#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH7 \
254 (TEGRA30_SPDIF_CIF_CH7 << TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH_SHIFT)
255#define TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH8 \
256 (TEGRA30_SPDIF_CIF_CH8 << TEGRA30_SPDIF_CIF_TXD_CTRL_AUDIO_CH_SHIFT)
257
258#define TEGRA30_SPDIF_CIF_TXD_CTRL_FIFO_TH_SHIFT 28
259#define TEGRA30_SPDIF_CIF_TXD_CTRL_FIFO_TH_MASK (0x7 << TEGRA30_SPDIF_CIF_TXD_CTRL_FIFO_TH_SHIFT)
260
261/* Fields in TEGRA30_TEGRA30_SPDIF_CIF_RXD_CTRL */
262#define TEGRA30_SPDIF_CIF_RXD_CTRL_MONO_CONV_COPY (1<<0)
263#define TEGRA30_SPDIF_CIF_RXD_CTRL_TRUNCATE_CHOP (1<<1)
264#define TEGRA30_SPDIF_CIF_RXD_CTRL_DIRECTION_RXCIF (1<<2)
265#define TEGRA30_SPDIF_CIF_RXD_CTRL_REPLICATE_ENABLE (1<<3)
266
267#define TEGRA30_SPDIF_CIF_RXD_CTRL_STEREO_CONV_SHIFT 4
268#define TEGRA30_SPDIF_CIF_RXD_CTRL_STEREO_CONV_MASK \
269 (0x3 << TEGRA30_SPDIF_CIF_RXD_CTRL_STEREO_CONV_SHIFT)
270#define TEGRA30_SPDIF_CIF_RXD_CTRL_STEREO_CONV_CH0 \
271 (TEGRA30_SPDIF_CIF_STEREO_CH0 << TEGRA30_SPDIF_CIF_RXD_CTRL_STEREO_CONV_SHIFT)
272#define TEGRA30_SPDIF_CIF_RXD_CTRL_STEREO_CONV_CH1 \
273 (TEGRA30_SPDIF_CIF_STEREO_CH1 << TEGRA30_SPDIF_CIF_RXD_CTRL_STEREO_CONV_SHIFT)
274#define TEGRA30_SPDIF_CIF_RXD_CTRL_STEREO_CONV_AVG \
275 (TEGRA30_SPDIF_CIF_STEREO_AVG << TEGRA30_SPDIF_CIF_RXD_CTRL_STEREO_CONV_SHIFT)
276#define TEGRA30_SPDIF_CIF_RXD_CTRL_STEREO_CONV_RSVD \
277 (TEGRA30_SPDIF_CIF_STEREO_RSVD << TEGRA30_SPDIF_CIF_RXD_CTRL_STEREO_CONV_SHIFT)
278
279
280#define TEGRA30_SPDIF_CIF_RXD_CTRL_EXPAND_SHIFT 6
281#define TEGRA30_SPDIF_CIF_RXD_CTRL_EXPAND_MASK \
282 (0x3 << TEGRA30_SPDIF_CIF_RXD_CTRL_EXPAND_SHIFT)
283#define TEGRA30_SPDIF_CIF_RXD_CTRL_EXPAND_ZERO \
284 (TEGRA30_SPDIF_CIF_EXPAND_ZERO << TEGRA30_SPDIF_CIF_RXD_CTRL_EXPAND_SHIFT)
285#define TEGRA30_SPDIF_CIF_RXD_CTRL_EXPAND_ONE \
286 (TEGRA30_SPDIF_CIF_EXPAND_ONE << TEGRA30_SPDIF_CIF_RXD_CTRL_EXPAND_SHIFT)
287#define TEGRA30_SPDIF_CIF_RXD_CTRL_EXPAND_LFSR \
288 (TEGRA30_SPDIF_CIF_EXPAND_LFSR << TEGRA30_SPDIF_CIF_RXD_CTRL_EXPAND_SHIFT)
289#define TEGRA30_SPDIF_CIF_RXD_CTRL_EXPAND_RSVD \
290
291
292#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_BITS_SHIFT 8
293#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_BITS_MASK \
294 (0x7 << TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_BITS_SHIFT)
295#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_BIT4 \
296 (TEGRA30_SPDIF_CIF_BIT4 << TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_BITS_SHIFT)
297#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_BIT8 \
298 (TEGRA30_SPDIF_CIF_BIT8 << TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_BITS_SHIFT)
299#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_BIT12 \
300 (TEGRA30_SPDIF_CIF_BIT12 << TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_BITS_SHIFT)
301#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_BIT16 \
302 (TEGRA30_SPDIF_CIF_BIT16 << TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_BITS_SHIFT)
303#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_BIT20 \
304 (TEGRA30_SPDIF_CIF_BIT20 << TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_BITS_SHIFT)
305#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_BIT24 \
306 (TEGRA30_SPDIF_CIF_BIT24 << TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_BITS_SHIFT)
307#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_BIT28 \
308 (TEGRA30_SPDIF_CIF_BIT28 << TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_BITS_SHIFT)
309#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_BIT32 \
310 (TEGRA30_SPDIF_CIF_BIT32 << TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_BITS_SHIFT)
311
312#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_BITS_SHIFT 12
313#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_BITS_MASK \
314 (0x7 << TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_BITS_SHIFT)
315#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_BIT4 \
316 (TEGRA30_SPDIF_CIF_BIT4 << TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_BITS_SHIFT)
317#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_BIT8 \
318 (TEGRA30_SPDIF_CIF_BIT8 << TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_BITS_SHIFT)
319#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_BIT12 \
320 (TEGRA30_SPDIF_CIF_BIT12 << TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_BITS_SHIFT)
321#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_BIT16 \
322 (TEGRA30_SPDIF_CIF_BIT16 << TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_BITS_SHIFT)
323#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_BIT20 \
324 (TEGRA30_SPDIF_CIF_BIT20 << TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_BITS_SHIFT)
325#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_BIT24 \
326 (TEGRA30_SPDIF_CIF_BIT24 << TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_BITS_SHIFT)
327#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_BIT28 \
328 (TEGRA30_SPDIF_CIF_BIT28 << TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_BITS_SHIFT)
329#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_BIT32 \
330 (TEGRA30_SPDIF_CIF_BIT32 << TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_BITS_SHIFT)
331
332
333#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_CH_SHIFT 16
334#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_CH_MASK \
335 (0x7 << TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_CH_SHIFT)
336#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_CH1 \
337 (TEGRA30_SPDIF_CIF_CH1 << TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_CH_SHIFT)
338#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_CH2 \
339 (TEGRA30_SPDIF_CIF_CH2 << TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_CH_SHIFT)
340#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_CH3 \
341 (TEGRA30_SPDIF_CIF_CH3 << TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_CH_SHIFT)
342#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_CH4 \
343 (TEGRA30_SPDIF_CIF_CH4 << TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_CH_SHIFT)
344#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_CH5 \
345 (TEGRA30_SPDIF_CIF_CH5 << TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_CH_SHIFT)
346#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_CH6 \
347 (TEGRA30_SPDIF_CIF_CH6 << TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_CH_SHIFT)
348#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_CH7 \
349 (TEGRA30_SPDIF_CIF_CH7 << TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_CH_SHIFT)
350#define TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_CH8 \
351 (TEGRA30_SPDIF_CIF_CH8 << TEGRA30_SPDIF_CIF_RXD_CTRL_CLIENT_CH_SHIFT)
352
353
354#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_CHANNELS_SHIFT 24
355#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_CHANNELS_MASK \
356 (0x7 << TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_CHANNELS_SHIFT)
357#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_CH1 \
358 (TEGRA30_SPDIF_CIF_CH1 << TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_CHANNELS_SHIFT)
359#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_CH2 \
360 (TEGRA30_SPDIF_CIF_CH2 << TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_CHANNELS_SHIFT)
361#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_CH3 \
362 (TEGRA30_SPDIF_CIF_CH3 << TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_CHANNELS_SHIFT)
363#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_CH4 \
364 (TEGRA30_SPDIF_CIF_CH4 << TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_CHANNELS_SHIFT)
365#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_CH5 \
366 (TEGRA30_SPDIF_CIF_CH5 << TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_CHANNELS_SHIFT)
367#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_CH6 \
368 (TEGRA30_SPDIF_CIF_CH6 << TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_CHANNELS_SHIFT)
369#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_CH7 \
370 (TEGRA30_SPDIF_CIF_CH7 << TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_CHANNELS_SHIFT)
371#define TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_CH8 \
372 (TEGRA30_SPDIF_CIF_CH8 << TEGRA30_SPDIF_CIF_RXD_CTRL_AUDIO_CHANNELS_SHIFT)
373
374#define TEGRA30_SPDIF_CIF_RXD_CTRL_FIFO_TH_SHIFT 28
375#define TEGRA30_SPDIF_CIF_RXD_CTRL_FIFO_TH_MASK (0x7 << TEGRA30_SPDIF_CIF_RXD_CTRL_FIFO_TH_SHIFT)
376
377/* Fields in TEGRA30_TEGRA30_SPDIF_CIF_TXU_CTRL */
378#define TEGRA30_SPDIF_CIF_TXU_CTRL_MONO_CONV_COPY (1<<0)
379#define TEGRA30_SPDIF_CIF_TXU_CTRL_TRUNCATE_CHOP (1<<1)
380#define TEGRA30_SPDIF_CIF_TXU_CTRL_DIRECTION_RXCIF (1<<2)
381#define TEGRA30_SPDIF_CIF_TXU_CTRL_REPLICATE_ENABLE (1<<3)
382
383
384#define TEGRA30_SPDIF_CIF_TXU_CTRL_STEREO_CONV_SHIFT 4
385#define TEGRA30_SPDIF_CIF_TXU_CTRL_STEREO_CONV_MASK \
386 (0x3 << TEGRA30_SPDIF_CIF_TXU_CTRL_0_STEREO_CONV_SHIFT)
387#define TEGRA30_SPDIF_CIF_TXU_CTRL_STEREO_CONV_CH0 \
388 (TEGRA30_SPDIF_CIF_STEREO_CH0 << TEGRA30_SPDIF_CIF_TXU_CTRL_0_STEREO_CONV_SHIFT)
389#define TEGRA30_SPDIF_CIF_TXU_CTRL_STEREO_CONV_CH1 \
390 (TEGRA30_SPDIF_CIF_STEREO_CH1 << TEGRA30_SPDIF_CIF_TXU_CTRL_0_STEREO_CONV_SHIFT)
391#define TEGRA30_SPDIF_CIF_TXU_CTRL_STEREO_CONV_AVG \
392 (TEGRA30_SPDIF_CIF_STEREO_AVG << TEGRA30_SPDIF_CIF_TXU_CTRL_0_STEREO_CONV_SHIFT)
393#define TEGRA30_SPDIF_CIF_TXU_CTRL_STEREO_CONV_RSVD \
394 (TEGRA30_SPDIF_CIF_STEREO_RSVD << TEGRA30_SPDIF_CIF_TXU_CTRL_0_STEREO_CONV_SHIFT)
395
396
397#define TEGRA30_SPDIF_CIF_TXU_CTRL_EXPAND_SHIFT 6
398#define TEGRA30_SPDIF_CIF_TXU_CTRL_EXPAND_MASK \
399 (0x3 << TEGRA30_SPDIF_CIF_TXU_CTRL_EXPAND_SHIFT)
400#define TEGRA30_SPDIF_CIF_TXU_CTRL_EXPAND_ZERO \
401 (TEGRA30_SPDIF_CIF_EXPAND_ZERO << TEGRA30_SPDIF_CIF_TXU_CTRL_EXPAND_SHIFT)
402#define TEGRA30_SPDIF_CIF_TXU_CTRL_EXPAND_ONE \
403 (TEGRA30_SPDIF_CIF_EXPAND_ONE << TEGRA30_SPDIF_CIF_TXU_CTRL_EXPAND_SHIFT)
404#define TEGRA30_SPDIF_CIF_TXU_CTRL_EXPAND_LFSR \
405 (TEGRA30_SPDIF_CIF_EXPAND_LFSR << TEGRA30_SPDIF_CIF_TXU_CTRL_EXPAND_SHIFT)
406#define TEGRA30_SPDIF_CIF_TXU_CTRL_EXPAND_RSVD \
407 (TEGRA30_SPDIF_CIF_EXPAND_RSVD << TEGRA30_SPDIF_CIF_TXU_CTRL_EXPAND_SHIFT)
408
409
410#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_BITS_SHIFT 8
411#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_BITS_MASK \
412 (0x7 << TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_BITS_SHIFT)
413#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_BIT4 \
414 (TEGRA30_SPDIF_CIF_BIT4 << TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_BITS_SHIFT)
415#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_BIT8 \
416 (TEGRA30_SPDIF_CIF_BIT8 << TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_BITS_SHIFT)
417#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_BIT12 \
418 (TEGRA30_SPDIF_CIF_BIT12 << TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_BITS_SHIFT)
419#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_BIT16 \
420 (TEGRA30_SPDIF_CIF_BIT16 << TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_BITS_SHIFT)
421#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_BIT20 \
422 (TEGRA30_SPDIF_CIF_BIT20 << TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_BITS_SHIFT)
423#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_BIT24 \
424 (TEGRA30_SPDIF_CIF_BIT24 << TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_BITS_SHIFT)
425#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_BIT28 \
426 (TEGRA30_SPDIF_CIF_BIT28 << TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_BITS_SHIFT)
427#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_BIT32 \
428 (TEGRA30_SPDIF_CIF_BIT32 << TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_BITS_SHIFT)
429
430
431#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_BITS_SHIFT 12
432#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_BITS_MASK \
433 (0x7 << TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_BITS_SHIFT)
434#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_BIT4 \
435 (TEGRA30_SPDIF_CIF_BIT4 << TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_BITS_SHIFT)
436#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_BIT8 \
437 (TEGRA30_SPDIF_CIF_BIT8 << TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_BITS_SHIFT)
438#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_BIT12 \
439 (TEGRA30_SPDIF_CIF_BIT12 << TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_BITS_SHIFT)
440#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_BIT16 \
441 (TEGRA30_SPDIF_CIF_BIT16 << TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_BITS_SHIFT)
442#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_BIT20 \
443 (TEGRA30_SPDIF_CIF_BIT20 << TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_BITS_SHIFT)
444#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_BIT24 \
445 (TEGRA30_SPDIF_CIF_BIT24 << TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_BITS_SHIFT)
446#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_BIT28 \
447 (TEGRA30_SPDIF_CIF_BIT28 << TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_BITS_SHIFT)
448#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_BIT32 \
449 (TEGRA30_SPDIF_CIF_BIT32 << TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_BITS_SHIFT)
450
451
452#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_CH_SHIFT 16
453#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_CH_MASK \
454 (0x7 << TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_CH_SHIFT)
455#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_CH1 \
456 (TEGRA30_SPDIF_CIF_CH1 << TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_CH_SHIFT)
457#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_CH2 \
458 (TEGRA30_SPDIF_CIF_CH2 << TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_CH_SHIFT)
459#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_CH3 \
460 (TEGRA30_SPDIF_CIF_CH3 << TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_CH_SHIFT)
461#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_CH4 \
462 (TEGRA30_SPDIF_CIF_CH4 << TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_CH_SHIFT)
463#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_CH5 \
464 (TEGRA30_SPDIF_CIF_CH5 << TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_CH_SHIFT)
465#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_CH6 \
466 (TEGRA30_SPDIF_CIF_CH6 << TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_CH_SHIFT)
467#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_CH7 \
468 (TEGRA30_SPDIF_CIF_CH7 << TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_CH_SHIFT)
469#define TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_CH8 \
470 (TEGRA30_SPDIF_CIF_CH8 << TEGRA30_SPDIF_CIF_TXU_CTRL_CLIENT_CH_SHIFT)
471
472
473#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_CH_SHIFT 24
474#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_CH_MASK \
475 (0x7 << TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_CH_SHIFT)
476#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_CH1 \
477 (TEGRA30_SPDIF_CIF_CH1 << TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_CH_SHIFT)
478#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_CH2 \
479 (TEGRA30_SPDIF_CIF_CH2 << TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_CH_SHIFT)
480#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_CH3 \
481 (TEGRA30_SPDIF_CIF_CH3 << TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_CH_SHIFT)
482#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_CH4 \
483 (TEGRA30_SPDIF_CIF_CH4 << TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_CH_SHIFT)
484#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_CH5 \
485 (TEGRA30_SPDIF_CIF_CH5 << TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_CH_SHIFT)
486#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_CH6 \
487 (TEGRA30_SPDIF_CIF_CH6 << TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_CH_SHIFT)
488#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_CH7 \
489 (TEGRA30_SPDIF_CIF_CH7 << TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_CH_SHIFT)
490#define TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_CH8 \
491 (TEGRA30_SPDIF_CIF_CH8 << TEGRA30_SPDIF_CIF_TXU_CTRL_AUDIO_CH_SHIFT)
492
493#define TEGRA30_SPDIF_CIF_TXU_CTRL_FIFO_TH_SHIFT 28
494#define TEGRA30_SPDIF_CIF_TXU_CTRL_FIFO_TH_MASK (0x7 << TEGRA30_SPDIF_CIF_TXU_CTRL_FIFO_TH_SHIFT)
495
496/* Fields in TEGRA30_TEGRA30_SPDIF_CIF_RXU_CTRL */
497#define TEGRA30_SPDIF_CIF_RXU_CTRL_MONO_CONV_COPY (1<<0)
498#define TEGRA30_SPDIF_CIF_RXU_CTRL_TRUNCATE_CHOP (1<<1)
499#define TEGRA30_SPDIF_CIF_RXU_CTRL_DIRECTION_RXCIF (1<<2)
500#define TEGRA30_SPDIF_CIF_RXU_CTRL_REPLICATE_ENABLE (1<<3)
501
502
503#define TEGRA30_SPDIF_CIF_RXU_CTRL_STEREO_CONV_SHIFT 4
504#define TEGRA30_SPDIF_CIF_RXU_CTRL_STEREO_CONV_MASK \
505 (0x3 << TEGRA30_SPDIF_CIF_RXU_CTRL_0_STEREO_CONV_SHIFT)
506#define TEGRA30_SPDIF_CIF_RXU_CTRL_STEREO_CONV_CH0 \
507 (TEGRA30_SPDIF_CIF_STEREO_CH0 << TEGRA30_SPDIF_CIF_RXU_CTRL_0_STEREO_CONV_SHIFT)
508#define TEGRA30_SPDIF_CIF_RXU_CTRL_STEREO_CONV_CH1 \
509 (TEGRA30_SPDIF_CIF_STEREO_CH1 << TEGRA30_SPDIF_CIF_RXU_CTRL_0_STEREO_CONV_SHIFT)
510#define TEGRA30_SPDIF_CIF_RXU_CTRL_STEREO_CONV_AVG \
511 (TEGRA30_SPDIF_CIF_STEREO_AVG << TEGRA30_SPDIF_CIF_RXU_CTRL_0_STEREO_CONV_SHIFT)
512#define TEGRA30_SPDIF_CIF_RXU_CTRL_STEREO_CONV_RSVD \
513 (TEGRA30_SPDIF_CIF_STEREO_RSVD << TEGRA30_SPDIF_CIF_RXU_CTRL_0_STEREO_CONV_SHIFT)
514
515
516#define TEGRA30_SPDIF_CIF_RXU_CTRL_EXPAND_SHIFT 6
517#define TEGRA30_SPDIF_CIF_RXU_CTRL_EXPAND_MASK \
518 (0x3 << TEGRA30_SPDIF_CIF_RXU_CTRL_EXPAND_SHIFT)
519#define TEGRA30_SPDIF_CIF_RXU_CTRL_EXPAND_ZERO \
520 (TEGRA30_SPDIF_CIF_EXPAND_ZERO << TEGRA30_SPDIF_CIF_RXU_CTRL_EXPAND_SHIFT)
521#define TEGRA30_SPDIF_CIF_RXU_CTRL_EXPAND_ONE \
522 (TEGRA30_SPDIF_CIF_EXPAND_ONE << TEGRA30_SPDIF_CIF_RXU_CTRL_EXPAND_SHIFT)
523#define TEGRA30_SPDIF_CIF_RXU_CTRL_EXPAND_LFSR \
524 (TEGRA30_SPDIF_CIF_EXPAND_LFSR << TEGRA30_SPDIF_CIF_RXU_CTRL_EXPAND_SHIFT)
525#define TEGRA30_SPDIF_CIF_RXU_CTRL_EXPAND_RSVD \
526 (TEGRA30_SPDIF_CIF_EXPAND_RSVD << TEGRA30_SPDIF_CIF_RXU_CTRL_EXPAND_SHIFT)
527
528
529#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_BITS_SHIFT 8
530#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_BITS_MASK \
531 (0x7 << TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_BITS_SHIFT)
532#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_BIT4 \
533 (TEGRA30_SPDIF_CIF_BIT4 << TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_BITS_SHIFT)
534#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_BIT8 \
535 (TEGRA30_SPDIF_CIF_BIT8 << TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_BITS_SHIFT)
536#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_BIT12 \
537 (TEGRA30_SPDIF_CIF_BIT12 << TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_BITS_SHIFT)
538#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_BIT16 \
539 (TEGRA30_SPDIF_CIF_BIT16 << TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_BITS_SHIFT)
540#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_BIT20 \
541 (TEGRA30_SPDIF_CIF_BIT20 << TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_BITS_SHIFT)
542#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_BIT24 \
543 (TEGRA30_SPDIF_CIF_BIT24 << TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_BITS_SHIFT)
544#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_BIT28 \
545 (TEGRA30_SPDIF_CIF_BIT28 << TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_BITS_SHIFT)
546#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_BIT32 \
547 (TEGRA30_SPDIF_CIF_BIT32 << TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_BITS_SHIFT)
548
549
550#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_BITS_SHIFT 12
551#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_BITS_MASK \
552 (0x7 << TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_BITS_SHIFT)
553#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_BIT4 \
554 (TEGRA30_SPDIF_CIF_BIT4 << TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_BITS_SHIFT)
555#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_BIT8 \
556 (TEGRA30_SPDIF_CIF_BIT8 << TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_BITS_SHIFT)
557#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_BIT12 \
558 (TEGRA30_SPDIF_CIF_BIT12 << TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_BITS_SHIFT)
559#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_BIT16 \
560 (TEGRA30_SPDIF_CIF_BIT16 << TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_BITS_SHIFT)
561#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_BIT20 \
562 (TEGRA30_SPDIF_CIF_BIT20 << TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_BITS_SHIFT)
563#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_BIT24 \
564 (TEGRA30_SPDIF_CIF_BIT24 << TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_BITS_SHIFT)
565#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_BIT28 \
566 (TEGRA30_SPDIF_CIF_BIT28 << TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_BITS_SHIFT)
567#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_BIT32 \
568 (TEGRA30_SPDIF_CIF_BIT32 << TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_BITS_SHIFT)
569
570
571#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_CH_SHIFT 16
572#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_CH_MASK \
573 (0x7 << TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_CH_SHIFT)
574#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_CH1 \
575 (TEGRA30_SPDIF_CIF_CH1 << TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_CH_SHIFT)
576#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_CH2 \
577 (TEGRA30_SPDIF_CIF_CH2 << TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_CH_SHIFT)
578#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_CH3 \
579 (TEGRA30_SPDIF_CIF_CH3 << TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_CH_SHIFT)
580#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_CH4 \
581 (TEGRA30_SPDIF_CIF_CH4 << TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_CH_SHIFT)
582#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_CH5 \
583 (TEGRA30_SPDIF_CIF_CH5 << TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_CH_SHIFT)
584#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_CH6 \
585 (TEGRA30_SPDIF_CIF_CH6 << TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_CH_SHIFT)
586#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_CH7 \
587 (TEGRA30_SPDIF_CIF_CH7 << TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_CH_SHIFT)
588#define TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_CH8 \
589 (TEGRA30_SPDIF_CIF_CH8 << TEGRA30_SPDIF_CIF_RXU_CTRL_CLIENT_CH_SHIFT)
590
591
592#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_CH_SHIFT 24
593#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_CH_MASK \
594 (0x7 << TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_CH_SHIFT)
595#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_CH1 \
596 (TEGRA30_SPDIF_CIF_CH1 << TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_CH_SHIFT)
597#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_CH2 \
598 (TEGRA30_SPDIF_CIF_CH2 << TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_CH_SHIFT)
599#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_CH3 \
600 (TEGRA30_SPDIF_CIF_CH3 << TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_CH_SHIFT)
601#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_CH4 \
602 (TEGRA30_SPDIF_CIF_CH4 << TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_CH_SHIFT)
603#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_CH5 \
604 (TEGRA30_SPDIF_CIF_CH5 << TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_CH_SHIFT)
605#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_CH6 \
606 (TEGRA30_SPDIF_CIF_CH6 << TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_CH_SHIFT)
607#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_CH7 \
608 (TEGRA30_SPDIF_CIF_CH7 << TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_CH_SHIFT)
609#define TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_CH8 \
610 (TEGRA30_SPDIF_CIF_CH8 << TEGRA30_SPDIF_CIF_RXU_CTRL_AUDIO_CH_SHIFT)
611
612#define TEGRA30_SPDIF_CIF_RXU_CTRL_FIFO_TH_SHIFT 28
613#define TEGRA30_SPDIF_CIF_RXU_CTRL_FIFO_TH_MASK (0x7 << TEGRA30_SPDIF_CIF_RXU_CTRL_FIFO_TH_SHIFT)
614
615/* Fields in TEGRA30_SPDIF_CH_STA_RX_A */
616/* Fields in TEGRA30_SPDIF_CH_STA_RX_B */
617/* Fields in TEGRA30_SPDIF_CH_STA_RX_C */
618/* Fields in TEGRA30_SPDIF_CH_STA_RX_D */
619/* Fields in TEGRA30_SPDIF_CH_STA_RX_E */
620/* Fields in TEGRA30_SPDIF_CH_STA_RX_F */
621
622/*
623 * The 6-word receive channel data page buffer holds a block (192 frames) of
624 * channel status information. The order of receive is from LSB to MSB
625 * bit, and from CH_STA_RX_A to CH_STA_RX_F then back to CH_STA_RX_A.
626 */
627
628/* Fields in TEGRA30_SPDIF_CH_STA_TX_A */
629#define TEGRA30_SPDIF_CH_STA_TX_A_SF_22050 0x4
630#define TEGRA30_SPDIF_CH_STA_TX_A_SF_24000 0x6
631#define TEGRA30_SPDIF_CH_STA_TX_A_SF_32000 0x3
632#define TEGRA30_SPDIF_CH_STA_TX_A_SF_44100 0x0
633#define TEGRA30_SPDIF_CH_STA_TX_A_SF_48000 0x2
634#define TEGRA30_SPDIF_CH_STA_TX_A_SF_88200 0x8
635#define TEGRA30_SPDIF_CH_STA_TX_A_SF_96000 0xA
636#define TEGRA30_SPDIF_CH_STA_TX_A_SF_176400 0xC
637#define TEGRA30_SPDIF_CH_STA_TX_A_SF_192000 0xE
638
639#define TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT 24
640#define TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_MASK \
641 (0xF << TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT)
642#define TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_22050 \
643 (TEGRA30_SPDIF_CH_STA_TX_A_SF_22050 << TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT)
644#define TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_24000 \
645 (TEGRA30_SPDIF_CH_STA_TX_A_SF_24000 << TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT)
646#define TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_32000 \
647 (TEGRA30_SPDIF_CH_STA_TX_A_SF_32000 << TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT)
648#define TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_44100 \
649 (TEGRA30_SPDIF_CH_STA_TX_A_SF_44100 << TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT)
650#define TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_48000 \
651 (TEGRA30_SPDIF_CH_STA_TX_A_SF_48000 << TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT)
652#define TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_88200 \
653 (TEGRA30_SPDIF_CH_STA_TX_A_SF_88200 << TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT)
654#define TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_96000 \
655 (TEGRA30_SPDIF_CH_STA_TX_A_SF_96000 << TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT)
656#define TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_176400 \
657 (TEGRA30_SPDIF_CH_STA_TX_A_SF_176400 << TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT)
658#define TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_192000 \
659 (TEGRA30_SPDIF_CH_STA_TX_A_SF_192000 << TEGRA30_SPDIF_CH_STA_TX_A_SAMP_FREQ_SHIFT)
660
661/* Fields in TEGRA30_SPDIF_CH_STA_TX_B */
662#define TEGRA30_SPDIF_CH_STA_TX_B_SF_8000 0x6
663#define TEGRA30_SPDIF_CH_STA_TX_B_SF_11025 0xA
664#define TEGRA30_SPDIF_CH_STA_TX_B_SF_12000 0x2
665#define TEGRA30_SPDIF_CH_STA_TX_B_SF_16000 0x8
666#define TEGRA30_SPDIF_CH_STA_TX_B_SF_22050 0xB
667#define TEGRA30_SPDIF_CH_STA_TX_B_SF_24000 0x9
668#define TEGRA30_SPDIF_CH_STA_TX_B_SF_32000 0xC
669#define TEGRA30_SPDIF_CH_STA_TX_B_SF_44100 0xF
670#define TEGRA30_SPDIF_CH_STA_TX_B_SF_48000 0xD
671#define TEGRA30_SPDIF_CH_STA_TX_B_SF_88200 0x7
672#define TEGRA30_SPDIF_CH_STA_TX_B_SF_96000 0x5
673#define TEGRA30_SPDIF_CH_STA_TX_B_SF_176400 0x3
674#define TEGRA30_SPDIF_CH_STA_TX_B_SF_192000 0x1
675
676#define TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT 4
677#define TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_MASK \
678 (0xF << TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT)
679#define TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_8000 \
680 (TEGRA30_SPDIF_CH_STA_TX_B_SF_8000 << TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT)
681#define TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_11025 \
682 (TEGRA30_SPDIF_CH_STA_TX_B_SF_11025 << TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT)
683#define TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_12000 \
684 (TEGRA30_SPDIF_CH_STA_TX_B_SF_12000 << TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT)
685#define TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_16000 \
686 (TEGRA30_SPDIF_CH_STA_TX_B_SF_16000 << TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT)
687#define TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_22050 \
688 (TEGRA30_SPDIF_CH_STA_TX_B_SF_22025 << TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT)
689#define TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_24000 \
690 (TEGRA30_SPDIF_CH_STA_TX_B_SF_24000 << TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT)
691#define TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_32000 \
692 (TEGRA30_SPDIF_CH_STA_TX_B_SF_32000 << TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT)
693#define TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_44100 \
694 (TEGRA30_SPDIF_CH_STA_TX_B_SF_44100 << TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT)
695#define TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_48000 \
696 (TEGRA30_SPDIF_CH_STA_TX_B_SF_48000 << TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT)
697#define TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_88200 \
698 (TEGRA30_SPDIF_CH_STA_TX_B_SF_88200 << TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT)
699#define TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_96000 \
700 (TEGRA30_SPDIF_CH_STA_TX_B_SF_96000 << TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT)
701#define TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_176400 \
702 (TEGRA30_SPDIF_CH_STA_TX_B_SF_176400 << TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT)
703#define TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_192000 \
704 (TEGRA30_SPDIF_CH_STA_TX_B_SF_192000 << TEGRA30_SPDIF_CH_STA_TX_B_ORIG_SAMP_FREQ_SHIFT)
705
706/* Fields in TEGRA30_SPDIF_CH_STA_TX_C */
707/* Fields in TEGRA30_SPDIF_CH_STA_TX_D */
708/* Fields in TEGRA30_SPDIF_CH_STA_TX_E */
709/* Fields in TEGRA30_SPDIF_CH_STA_TX_F */
710
711/* Fields in TEGRA30_SPDIF_FLOWCTL_CTRL */
712#define TEGRA30_SPDIF_FLOWCTL_CTRL_FILTER_QUAD (1<<31)
713
714/* Fields in TEGRA30_SPDIF_TX_STEP */
715#define TEGRA30_SPDIF_TX_STEP_STEP_SIZE_SHIFT 0
716#define TEGRA30_SPDIF_TX_STEP_STEP_SIZE_MASK (0xffff << TEGRA30_SPDIF_TX_STEP_STEP_SIZE_SHIFT)
717
718/* Fields in TEGRA30_SPDIF_FLOW_STATUS */
719#define TEGRA30_SPDIF_FLOW_STATUS_COUNTER_EN_ENABLE (1<<1)
720#define TEGRA30_SPDIF_FLOW_STATUS_MONITOR_CLR_CLEAR (1<<2)
721#define TEGRA30_SPDIF_FLOW_STATUS_COUNTER_CLR_CLEAR (1<<3)
722#define TEGRA30_SPDIF_FLOW_STATUS_MONITOR_INT_EN_ENABLE (1<<4)
723#define TEGRA30_SPDIF_FLOW_STATUS_FLOW_OVERFLOW_OVER (1<<30)
724#define TEGRA30_SPDIF_FLOW_STATUS_FLOW_UNDERFLOW_UNDER (1<<31)
725
726/* Fields in TEGRA30_SPDIF_FLOW_TOTAL */
727/* Fields in TEGRA30_SPDIF_FLOW_OVER */
728/* Fields in TEGRA30_SPDIF_FLOW_UNDER */
729
730/* Fields in TEGRA30_SPDIF_LCOEF_1_4_0 */
731#define TEGRA30_SPDIF_LCOEF_1_4_0_COEF_SHIFT 0
732#define TEGRA30_SPDIF_LCOEF_1_4_0_COEF_MASK (0xffff << TEGRA30_TEGRA30_SPDIF_LCOEF_1_4_0_COEF_SHIFT)
733
734/* Fields in TEGRA30_SPDIF_LCOEF_1_4_1 */
735#define TEGRA30_SPDIF_LCOEF_1_4_1_COEF_SHIFT 0
736#define TEGRA30_SPDIF_LCOEF_1_4_1_COEF_MASK (0xffff << TEGRA30_SPDIF_LCOEF_1_4_1_COEF_SHIFT)
737
738/* Fields in TEGRA30_SPDIF_LCOEF_1_4_2 */
739#define TEGRA30_SPDIF_LCOEF_1_4_2_COEF_SHIFT 0
740#define TEGRA30_SPDIF_LCOEF_1_4_2_COEF_MASK (0xffff << TEGRA30_SPDIF_LCOEF_1_4_2_COEF_SHIFT)
741
742/* Fields in TEGRA30_SPDIF_LCOEF_1_4_3 */
743#define TEGRA30_SPDIF_LCOEF_1_4_3_COEF_SHIFT 0
744#define TEGRA30_SPDIF_LCOEF_1_4_3_COEF_MASK (0xffff << TEGRA30_SPDIF_LCOEF_1_4_3_COEF_SHIFT)
745
746/* Fields in TEGRA30_SPDIF_LCOEF_1_4_4 */
747#define TEGRA30_SPDIF_LCOEF_1_4_4_COEF_SHIFT 0
748#define TEGRA30_SPDIF_LCOEF_1_4_4_COEF_MASK (0xffff << TEGRA30_SPDIF_LCOEF_1_4_4_COEF_SHIFT)
749
750/* Fields in TEGRA30_SPDIF_LCOEF_1_4_5 */
751#define TEGRA30_SPDIF_LCOEF_1_4_5_COEF_SHIFT 0
752#define TEGRA30_SPDIF_LCOEF_1_4_5_COEF_MASK (0xffff << TEGRA30_SPDIF_LCOEF_1_4_5_COEF_SHIFT)
753
754/* Fields in TEGRA30_SPDIF_LCOEF_2_4_0 */
755#define TEGRA30_SPDIF_LCOEF_2_4_0_COEF_SHIFT 0
756#define TEGRA30_SPDIF_LCOEF_2_4_0_COEF_MASK (0xffff << TEGRA30_SPDIF_LCOEF_2_4_0_COEF_SHIFT)
757
758/* Fields in TEGRA30_SPDIF_LCOEF_2_4_1 */
759#define TEGRA30_SPDIF_LCOEF_2_4_1_COEF_SHIFT 0
760#define TEGRA30_SPDIF_LCOEF_2_4_1_COEF_MASK (0xffff << TEGRA30_SPDIF_LCOEF_2_4_1_COEF_SHIFT)
761
762/* Fields in TEGRA30_SPDIF_LCOEF_2_4_2 */
763#define TEGRA30_SPDIF_LCOEF_2_4_2_COEF_SHIFT 0
764#define TEGRA30_SPDIF_LCOEF_2_4_2_COEF_MASK (0xffff << SPDIF_LCOEF_2_4_2_COEF_SHIFT)
765
766struct tegra30_spdif {
767 struct clk *clk_spdif_out;
768 enum tegra30_ahub_txcif txcif;
769 struct tegra_pcm_dma_params playback_dma_data;
770 void __iomem *regs;
771 struct dentry *debug;
772 u32 reg_ctrl;
773 u32 reg_ch_sta_a;
774 u32 reg_ch_sta_b;
775};
776
777#endif
diff --git a/sound/soc/tegra/tegra_aic326x.c b/sound/soc/tegra/tegra_aic326x.c
new file mode 100644
index 00000000000..6d38934138b
--- /dev/null
+++ b/sound/soc/tegra/tegra_aic326x.c
@@ -0,0 +1,1281 @@
1/*
2 * tegra_aic326x.c - Tegra machine ASoC driver for boards using TI 3262 codec.
3 *
4 * Author: Vinod G. <vinodg@nvidia.com>
5 * Copyright (C) 2011 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * (c) 2010, 2011 Nvidia Graphics Pvt. Ltd.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 *
25 */
26
27#include <asm/mach-types.h>
28
29#include <linux/module.h>
30#include <linux/platform_device.h>
31#include <linux/slab.h>
32#include <linux/gpio.h>
33#include <linux/regulator/consumer.h>
34#ifdef CONFIG_SWITCH
35#include <linux/switch.h>
36#endif
37
38#include <mach/tegra_aic326x_pdata.h>
39
40#include <sound/core.h>
41#include <sound/jack.h>
42#include <sound/pcm.h>
43#include <sound/pcm_params.h>
44#include <sound/soc.h>
45
46#include "../codecs/tlv320aic326x.h"
47
48#include "tegra_pcm.h"
49#include "tegra_asoc_utils.h"
50
51#ifdef CONFIG_ARCH_TEGRA_2x_SOC
52#include "tegra20_das.h"
53#else
54#include "tegra30_ahub.h"
55#include "tegra30_i2s.h"
56#include "tegra30_dam.h"
57#endif
58
59
60#define DRV_NAME "tegra-snd-aic326x"
61
62#define GPIO_SPKR_EN BIT(0)
63#define GPIO_HP_MUTE BIT(1)
64#define GPIO_INT_MIC_EN BIT(2)
65#define GPIO_EXT_MIC_EN BIT(3)
66
67#define DAI_LINK_HIFI 0
68#define DAI_LINK_SPDIF 1
69#define DAI_LINK_BTSCO 2
70#define DAI_LINK_VOICE_CALL 3
71#define DAI_LINK_BT_VOICE_CALL 4
72#define NUM_DAI_LINKS 5
73
74extern int g_is_call_mode;
75
76#ifndef CONFIG_ARCH_TEGRA_2x_SOC
77const char *tegra_i2s_dai_name[TEGRA30_NR_I2S_IFC] = {
78 "tegra30-i2s.0",
79 "tegra30-i2s.1",
80 "tegra30-i2s.2",
81 "tegra30-i2s.3",
82 "tegra30-i2s.4",
83};
84#endif
85
86struct tegra_aic326x {
87 struct tegra_asoc_utils_data util_data;
88 struct tegra_aic326x_platform_data *pdata;
89 struct regulator *audio_reg;
90 int gpio_requested;
91 bool init_done;
92 int is_call_mode;
93 int is_device_bt;
94#ifndef CONFIG_ARCH_TEGRA_2x_SOC
95 struct codec_config codec_info[NUM_I2S_DEVICES];
96 struct snd_soc_card *pcard;
97#endif
98};
99
100static int tegra_aic326x_call_mode_info(struct snd_kcontrol *kcontrol,
101 struct snd_ctl_elem_info *uinfo)
102{
103 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
104 uinfo->count = 1;
105 uinfo->value.integer.min = 0;
106 uinfo->value.integer.max = 1;
107 return 0;
108}
109
110static int tegra_aic326x_call_mode_get(struct snd_kcontrol *kcontrol,
111 struct snd_ctl_elem_value *ucontrol)
112{
113 struct tegra_aic326x *machine = snd_kcontrol_chip(kcontrol);
114
115 ucontrol->value.integer.value[0] = machine->is_call_mode;
116
117 return 0;
118}
119
120static int tegra_aic326x_call_mode_put(struct snd_kcontrol *kcontrol,
121 struct snd_ctl_elem_value *ucontrol)
122{
123 struct tegra_aic326x *machine = snd_kcontrol_chip(kcontrol);
124 int is_call_mode_new = ucontrol->value.integer.value[0];
125#ifdef CONFIG_ARCH_TEGRA_2x_SOC
126 int codec_dap_id, codec_dap_sel, bb_dap_id, bb_dap_sel;
127#else /*assumes tegra3*/
128 int codec_index;
129 unsigned int i;
130#endif
131
132 if (machine->is_call_mode == is_call_mode_new)
133 return 0;
134
135#ifdef CONFIG_ARCH_TEGRA_2x_SOC
136 bb_dap_id = TEGRA20_DAS_DAP_ID_3;
137 bb_dap_sel = TEGRA20_DAS_DAP_SEL_DAP3;
138
139 if (machine->is_device_bt) {
140 codec_dap_id = TEGRA20_DAS_DAP_ID_4;
141 codec_dap_sel = TEGRA20_DAS_DAP_SEL_DAP4;
142 }
143 else {
144 codec_dap_id = TEGRA20_DAS_DAP_ID_2;
145 codec_dap_sel = TEGRA20_DAS_DAP_SEL_DAP2;
146 }
147#else /*assumes tegra3*/
148 if (machine->is_device_bt)
149 codec_index = BT_SCO;
150 else
151 codec_index = HIFI_CODEC;
152#endif
153
154 if (is_call_mode_new) {
155#ifdef CONFIG_ARCH_TEGRA_2x_SOC
156 tegra20_das_set_tristate(codec_dap_id, 1);
157 tegra20_das_set_tristate(bb_dap_id, 1);
158 tegra20_das_connect_dap_to_dap(codec_dap_id,
159 bb_dap_sel, 0, 0, 0);
160 tegra20_das_connect_dap_to_dap(bb_dap_id,
161 codec_dap_sel, 1, 0, 0);
162 tegra20_das_set_tristate(codec_dap_id, 0);
163 tegra20_das_set_tristate(bb_dap_id, 0);
164#else /*assumes tegra3*/
165 if (machine->codec_info[codec_index].rate == 0 ||
166 machine->codec_info[codec_index].channels == 0)
167 return -EINVAL;
168
169 for (i = 0; i < machine->pcard->num_links; i++)
170 machine->pcard->dai_link[i].ignore_suspend = 1;
171
172 tegra30_make_voice_call_connections(
173 &machine->codec_info[codec_index],
174 &machine->codec_info[BASEBAND]);
175#endif
176 } else {
177#ifdef CONFIG_ARCH_TEGRA_2x_SOC
178 tegra20_das_set_tristate(codec_dap_id, 1);
179 tegra20_das_set_tristate(bb_dap_id, 1);
180 tegra20_das_connect_dap_to_dap(bb_dap_id,
181 bb_dap_sel, 0, 0, 0);
182 tegra20_das_connect_dap_to_dap(codec_dap_id,
183 codec_dap_sel, 0, 0, 0);
184 tegra20_das_set_tristate(codec_dap_id, 0);
185 tegra20_das_set_tristate(bb_dap_id, 0);
186#else /*assumes tegra3*/
187 tegra30_break_voice_call_connections(
188 &machine->codec_info[codec_index],
189 &machine->codec_info[BASEBAND]);
190
191 for (i = 0; i < machine->pcard->num_links; i++)
192 machine->pcard->dai_link[i].ignore_suspend = 0;
193#endif
194 }
195
196 machine->is_call_mode = is_call_mode_new;
197 g_is_call_mode = machine->is_call_mode;
198
199 return 1;
200}
201
202struct snd_kcontrol_new tegra_aic326x_call_mode_control = {
203 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
204 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
205 .name = "Call Mode Switch",
206 .private_value = 0xffff,
207 .info = tegra_aic326x_call_mode_info,
208 .get = tegra_aic326x_call_mode_get,
209 .put = tegra_aic326x_call_mode_put
210};
211
212static int tegra_aic326x_get_mclk(int srate)
213{
214 int mclk = 0;
215 switch (srate) {
216 case 8000:
217 case 16000:
218 case 24000:
219 case 32000:
220 case 48000:
221 case 64000:
222 case 96000:
223 mclk = 12288000;
224 break;
225 case 11025:
226 case 22050:
227 case 44100:
228 case 88200:
229 mclk = 11289600;
230 break;
231 default:
232 mclk = -EINVAL;
233 break;
234 }
235
236 return mclk;
237}
238
239#ifndef CONFIG_ARCH_TEGRA_2x_SOC
240static int tegra_aic326x_set_dam_cif(int dam_ifc, int srate,
241 int channels, int bit_size, int src_on, int src_srate,
242 int src_channels, int src_bit_size)
243{
244 tegra30_dam_set_gain(dam_ifc, TEGRA30_DAM_CHIN1, 0x1000);
245 tegra30_dam_set_samplerate(dam_ifc, TEGRA30_DAM_CHOUT,
246 srate);
247 tegra30_dam_set_samplerate(dam_ifc, TEGRA30_DAM_CHIN1,
248 srate);
249 tegra30_dam_set_acif(dam_ifc, TEGRA30_DAM_CHIN1,
250 channels, bit_size, channels,
251 bit_size);
252 tegra30_dam_set_acif(dam_ifc, TEGRA30_DAM_CHOUT,
253 channels, bit_size, channels,
254 bit_size);
255
256 if (src_on) {
257 tegra30_dam_set_gain(dam_ifc, TEGRA30_DAM_CHIN0_SRC, 0x1000);
258 tegra30_dam_set_samplerate(dam_ifc, TEGRA30_DAM_CHIN0_SRC,
259 src_srate);
260 tegra30_dam_set_acif(dam_ifc, TEGRA30_DAM_CHIN0_SRC,
261 src_channels, src_bit_size, 1, 16);
262 }
263
264 return 0;
265}
266#endif
267
268static int tegra_aic326x_hw_params(struct snd_pcm_substream *substream,
269 struct snd_pcm_hw_params *params)
270{
271 struct snd_soc_pcm_runtime *rtd = substream->private_data;
272 struct snd_soc_dai *codec_dai = rtd->codec_dai;
273 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
274 struct snd_soc_codec *codec = rtd->codec;
275 struct snd_soc_card *card = codec->card;
276 struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card);
277 int srate, mclk, sample_size, daifmt;
278 int err;
279#ifndef CONFIG_ARCH_TEGRA_2x_SOC
280 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai);
281#endif
282
283 switch (params_format(params)) {
284 case SNDRV_PCM_FORMAT_S16_LE:
285 sample_size = 16;
286 break;
287 default:
288 return -EINVAL;
289 }
290
291 srate = params_rate(params);
292
293 mclk = tegra_aic326x_get_mclk(srate);
294 if (mclk < 0)
295 return mclk;
296
297 daifmt = SND_SOC_DAIFMT_I2S |
298 SND_SOC_DAIFMT_NB_NF |
299 SND_SOC_DAIFMT_CBS_CFS;
300
301 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
302 if (err < 0) {
303 if (!(machine->util_data.set_mclk % mclk))
304 mclk = machine->util_data.set_mclk;
305 else {
306 dev_err(card->dev, "Can't configure clocks\n");
307 return err;
308 }
309 }
310
311 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
312
313 err = snd_soc_dai_set_fmt(codec_dai, daifmt);
314 if (err < 0) {
315 dev_err(card->dev, "codec_dai fmt not set\n");
316 return err;
317 }
318
319 err = snd_soc_dai_set_fmt(cpu_dai, daifmt);
320 if (err < 0) {
321 dev_err(card->dev, "cpu_dai fmt not set\n");
322 return err;
323 }
324
325 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
326 SND_SOC_CLOCK_IN);
327 if (err < 0) {
328 dev_err(card->dev, "codec_dai clock not set\n");
329 return err;
330 }
331
332#ifdef CONFIG_ARCH_TEGRA_2x_SOC
333 err = tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAP_SEL_DAC1,
334 TEGRA20_DAS_DAP_ID_1);
335 if (err < 0) {
336 dev_err(card->dev, "failed to set dap-dac path\n");
337 return err;
338 }
339
340 err = tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_1,
341 TEGRA20_DAS_DAP_SEL_DAC1);
342 if (err < 0) {
343 dev_err(card->dev, "failed to set dac-dap path\n");
344 return err;
345 }
346#else /*assumes tegra3*/
347 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && i2s->is_dam_used)
348 tegra_aic326x_set_dam_cif(i2s->dam_ifc, srate,
349 params_channels(params), sample_size, 0, 0, 0, 0);
350#endif
351
352 return 0;
353}
354
355static int tegra_aic326x_spdif_hw_params(struct snd_pcm_substream *substream,
356 struct snd_pcm_hw_params *params)
357{
358 struct snd_soc_pcm_runtime *rtd = substream->private_data;
359 struct snd_soc_card *card = rtd->card;
360 struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card);
361 int srate, mclk, min_mclk;
362 int err;
363
364 srate = params_rate(params);
365
366 mclk = tegra_aic326x_get_mclk(srate);
367 if (mclk < 0)
368 return mclk;
369
370 min_mclk = 128 * srate;
371
372 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
373 if (err < 0) {
374 if (!(machine->util_data.set_mclk % min_mclk))
375 mclk = machine->util_data.set_mclk;
376 else {
377 dev_err(card->dev, "Can't configure clocks\n");
378 return err;
379 }
380 }
381
382 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
383
384 return 0;
385}
386
387static int tegra_aic326x_bt_hw_params(struct snd_pcm_substream *substream,
388 struct snd_pcm_hw_params *params)
389{
390 struct snd_soc_pcm_runtime *rtd = substream->private_data;
391 struct snd_soc_card *card = rtd->card;
392 struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card);
393 int err, srate, mclk, min_mclk, sample_size;
394#ifndef CONFIG_ARCH_TEGRA_2x_SOC
395 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(rtd->cpu_dai);
396#endif
397
398 switch (params_format(params)) {
399 case SNDRV_PCM_FORMAT_S16_LE:
400 sample_size = 16;
401 break;
402 default:
403 return -EINVAL;
404 }
405
406 srate = params_rate(params);
407
408 mclk = tegra_aic326x_get_mclk(srate);
409 if (mclk < 0)
410 return mclk;
411
412 min_mclk = 64 * srate;
413
414 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
415 if (err < 0) {
416 if (!(machine->util_data.set_mclk % min_mclk))
417 mclk = machine->util_data.set_mclk;
418 else {
419 dev_err(card->dev, "Can't configure clocks\n");
420 return err;
421 }
422 }
423
424 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
425
426 err = snd_soc_dai_set_fmt(rtd->cpu_dai,
427 SND_SOC_DAIFMT_DSP_A |
428 SND_SOC_DAIFMT_NB_NF |
429 SND_SOC_DAIFMT_CBS_CFS);
430
431 if (err < 0) {
432 dev_err(rtd->codec->card->dev, "cpu_dai fmt not set\n");
433 return err;
434 }
435
436#ifdef CONFIG_ARCH_TEGRA_2x_SOC
437 err = tegra20_das_connect_dac_to_dap(TEGRA20_DAS_DAP_SEL_DAC2,
438 TEGRA20_DAS_DAP_ID_4);
439 if (err < 0) {
440 dev_err(card->dev, "failed to set dac-dap path\n");
441 return err;
442 }
443
444 err = tegra20_das_connect_dap_to_dac(TEGRA20_DAS_DAP_ID_4,
445 TEGRA20_DAS_DAP_SEL_DAC2);
446 if (err < 0) {
447 dev_err(card->dev, "failed to set dac-dap path\n");
448 return err;
449 }
450#else
451 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && i2s->is_dam_used)
452 tegra_aic326x_set_dam_cif(i2s->dam_ifc, params_rate(params),
453 params_channels(params), sample_size, 0, 0, 0, 0);
454#endif
455
456 return 0;
457}
458
459#ifndef CONFIG_ARCH_TEGRA_2x_SOC
460static int tegra_aic326x_startup(struct snd_pcm_substream *substream)
461{
462 struct snd_soc_pcm_runtime *rtd = substream->private_data;
463 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
464 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai);
465 struct tegra_aic326x *machine = snd_soc_card_get_drvdata(rtd->card);
466 struct codec_config *codec_info;
467 struct codec_config *bb_info;
468 int codec_index;
469
470 if (!i2s->is_dam_used)
471 return 0;
472
473 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
474 /*dam configuration*/
475 if (!i2s->dam_ch_refcount)
476 i2s->dam_ifc = tegra30_dam_allocate_controller();
477
478 tegra30_dam_allocate_channel(i2s->dam_ifc, TEGRA30_DAM_CHIN1);
479 i2s->dam_ch_refcount++;
480 tegra30_dam_enable_clock(i2s->dam_ifc);
481
482 tegra30_ahub_set_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX1 +
483 (i2s->dam_ifc*2), i2s->txcif);
484
485 /*
486 *make the dam tx to i2s rx connection if this is the only client
487 *using i2s for playback
488 */
489 if (i2s->playback_ref_count == 1)
490 tegra30_ahub_set_rx_cif_source(
491 TEGRA30_AHUB_RXCIF_I2S0_RX0 + i2s->id,
492 TEGRA30_AHUB_TXCIF_DAM0_TX0 + i2s->dam_ifc);
493
494 /* enable the dam*/
495 tegra30_dam_enable(i2s->dam_ifc, TEGRA30_DAM_ENABLE,
496 TEGRA30_DAM_CHIN1);
497 } else {
498
499 i2s->is_call_mode_rec = machine->is_call_mode;
500
501 if (!i2s->is_call_mode_rec)
502 return 0;
503
504 if (machine->is_device_bt)
505 codec_index = BT_SCO;
506 else
507 codec_index = HIFI_CODEC;
508
509 codec_info = &machine->codec_info[codec_index];
510 bb_info = &machine->codec_info[BASEBAND];
511
512 /* allocate a dam for voice call recording */
513
514 i2s->call_record_dam_ifc = tegra30_dam_allocate_controller();
515 tegra30_dam_allocate_channel(i2s->call_record_dam_ifc,
516 TEGRA30_DAM_CHIN0_SRC);
517 tegra30_dam_allocate_channel(i2s->call_record_dam_ifc,
518 TEGRA30_DAM_CHIN1);
519 tegra30_dam_enable_clock(i2s->call_record_dam_ifc);
520
521 /* configure the dam */
522 tegra_aic326x_set_dam_cif(i2s->call_record_dam_ifc,
523 codec_info->rate, codec_info->channels,
524 codec_info->bitsize, 1, bb_info->rate,
525 bb_info->channels, bb_info->bitsize);
526
527 /* setup the connections for voice call record */
528
529 tegra30_ahub_unset_rx_cif_source(i2s->rxcif);
530 tegra30_ahub_set_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX0 +
531 (i2s->call_record_dam_ifc*2),
532 TEGRA30_AHUB_TXCIF_I2S0_TX0 + bb_info->i2s_id);
533 tegra30_ahub_set_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX1 +
534 (i2s->call_record_dam_ifc*2),
535 TEGRA30_AHUB_TXCIF_I2S0_TX0 + codec_info->i2s_id);
536 tegra30_ahub_set_rx_cif_source(i2s->rxcif,
537 TEGRA30_AHUB_TXCIF_DAM0_TX0 + i2s->call_record_dam_ifc);
538
539 /* enable the dam*/
540
541 tegra30_dam_enable(i2s->call_record_dam_ifc, TEGRA30_DAM_ENABLE,
542 TEGRA30_DAM_CHIN1);
543 tegra30_dam_enable(i2s->call_record_dam_ifc, TEGRA30_DAM_ENABLE,
544 TEGRA30_DAM_CHIN0_SRC);
545 }
546
547 return 0;
548}
549
550static void tegra_aic326x_shutdown(struct snd_pcm_substream *substream)
551{
552 struct snd_soc_pcm_runtime *rtd = substream->private_data;
553 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
554 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai);
555
556 if (!i2s->is_dam_used)
557 return;
558
559 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
560 /* disable the dam*/
561 tegra30_dam_enable(i2s->dam_ifc, TEGRA30_DAM_DISABLE,
562 TEGRA30_DAM_CHIN1);
563
564 /* disconnect the ahub connections*/
565 tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX1 +
566 (i2s->dam_ifc*2));
567
568 /* disable the dam and free the controller */
569 tegra30_dam_disable_clock(i2s->dam_ifc);
570 tegra30_dam_free_channel(i2s->dam_ifc, TEGRA30_DAM_CHIN1);
571 i2s->dam_ch_refcount--;
572 if (!i2s->dam_ch_refcount)
573 tegra30_dam_free_controller(i2s->dam_ifc);
574 } else {
575
576 if (!i2s->is_call_mode_rec)
577 return 0;
578
579 i2s->is_call_mode_rec = 0;
580
581 /* disable the dam*/
582 tegra30_dam_enable(i2s->call_record_dam_ifc,
583 TEGRA30_DAM_DISABLE, TEGRA30_DAM_CHIN1);
584 tegra30_dam_enable(i2s->call_record_dam_ifc,
585 TEGRA30_DAM_DISABLE, TEGRA30_DAM_CHIN0_SRC);
586
587 /* disconnect the ahub connections*/
588 tegra30_ahub_unset_rx_cif_source(i2s->rxcif);
589 tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX0 +
590 (i2s->call_record_dam_ifc*2));
591 tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX1 +
592 (i2s->call_record_dam_ifc*2));
593
594 /* free the dam channels and dam controller */
595 tegra30_dam_disable_clock(i2s->call_record_dam_ifc);
596 tegra30_dam_free_channel(i2s->call_record_dam_ifc,
597 TEGRA30_DAM_CHIN1);
598 tegra30_dam_free_channel(i2s->call_record_dam_ifc,
599 TEGRA30_DAM_CHIN0_SRC);
600 tegra30_dam_free_controller(i2s->call_record_dam_ifc);
601 }
602
603 return;
604}
605#endif
606
607
608static int tegra_aic326x_hw_free(struct snd_pcm_substream *substream)
609{
610 struct snd_soc_pcm_runtime *rtd = substream->private_data;
611 struct tegra_aic326x *machine = snd_soc_card_get_drvdata(rtd->card);
612
613 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 0);
614
615 return 0;
616}
617
618static int tegra_aic326x_voice_call_hw_params(
619 struct snd_pcm_substream *substream,
620 struct snd_pcm_hw_params *params)
621{
622 struct snd_soc_pcm_runtime *rtd = substream->private_data;
623 struct snd_soc_dai *codec_dai = rtd->codec_dai;
624 struct snd_soc_codec *codec = rtd->codec;
625 struct snd_soc_card *card = codec->card;
626 struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card);
627 int srate, mclk;
628 int err, pcmdiv, vxclkdiv;;
629
630 srate = params_rate(params);
631 mclk = tegra_aic326x_get_mclk(srate);
632 if (mclk < 0)
633 return mclk;
634
635 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
636 if (err < 0) {
637 if (!(machine->util_data.set_mclk % mclk))
638 mclk = machine->util_data.set_mclk;
639 else {
640 dev_err(card->dev, "Can't configure clocks\n");
641 return err;
642 }
643 }
644
645 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
646
647 if(machine_is_tegra_enterprise()) {
648 err = snd_soc_dai_set_fmt(codec_dai,
649 SND_SOC_DAIFMT_I2S |
650 SND_SOC_DAIFMT_NB_NF |
651 SND_SOC_DAIFMT_CBS_CFS);
652 } else {
653 err = snd_soc_dai_set_fmt(codec_dai,
654 SND_SOC_DAIFMT_DSP_B |
655 SND_SOC_DAIFMT_NB_NF |
656 SND_SOC_DAIFMT_CBS_CFS);
657 }
658
659 if (err < 0) {
660 dev_err(card->dev, "codec_dai fmt not set\n");
661 return err;
662 }
663
664 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
665 SND_SOC_CLOCK_IN);
666 if (err < 0) {
667 dev_err(card->dev, "codec_dai clock not set\n");
668 return err;
669 }
670
671 if(!machine_is_tegra_enterprise()) {
672 if (params_rate(params) == 8000) {
673 /* Change these Settings for 8KHz*/
674 pcmdiv = 1;
675 /* BB expecting 2048Khz bclk */
676 vxclkdiv = 27;
677 } else if (params_rate(params) == 16000) {
678 pcmdiv = 1;
679 /* BB expecting 2048Khz bclk */
680 vxclkdiv = 27;
681 } else {
682 dev_err(card->dev, "codec_dai unsupported voice rate\n");
683 return -EINVAL;
684 }
685 }
686
687 //snd_soc_dai_set_clkdiv(codec_dai, ASI2_BCLK_N, vxclkdiv);
688 //snd_soc_dai_set_clkdiv(codec_dai, ASI2_WCLK_N, pcmdiv);
689
690#ifndef CONFIG_ARCH_TEGRA_2x_SOC
691 /* codec configuration */
692 machine->codec_info[HIFI_CODEC].rate = params_rate(params);
693 machine->codec_info[HIFI_CODEC].channels = params_channels(params);
694 machine->codec_info[HIFI_CODEC].bitsize = 16;
695 machine->codec_info[HIFI_CODEC].is_i2smaster = 1;
696 machine->codec_info[HIFI_CODEC].is_format_dsp = 0;
697
698 /* baseband configuration */
699 machine->codec_info[BASEBAND].bitsize = 16;
700 machine->codec_info[BASEBAND].is_i2smaster = 1;
701 machine->codec_info[BASEBAND].is_format_dsp = 1;
702#endif
703
704 machine->is_device_bt = 0;
705
706 return 0;
707}
708
709static void tegra_aic326x_voice_call_shutdown(
710 struct snd_pcm_substream *substream)
711{
712 struct snd_soc_pcm_runtime *rtd = substream->private_data;
713 struct tegra_aic326x *machine =
714 snd_soc_card_get_drvdata(rtd->codec->card);
715
716#ifndef CONFIG_ARCH_TEGRA_2x_SOC
717 machine->codec_info[HIFI_CODEC].rate = 0;
718 machine->codec_info[HIFI_CODEC].channels = 0;
719#endif
720
721 machine->is_device_bt = 0;
722}
723
724static int tegra_aic326x_bt_voice_call_hw_params(
725 struct snd_pcm_substream *substream,
726 struct snd_pcm_hw_params *params)
727{
728 struct snd_soc_pcm_runtime *rtd = substream->private_data;
729 struct snd_soc_card *card = rtd->card;
730 struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card);
731 int err, srate, mclk, min_mclk;
732
733 srate = params_rate(params);
734
735 mclk = tegra_aic326x_get_mclk(srate);
736 if (mclk < 0)
737 return mclk;
738
739 min_mclk = 64 * srate;
740
741 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
742 if (err < 0) {
743 if (!(machine->util_data.set_mclk % min_mclk))
744 mclk = machine->util_data.set_mclk;
745 else {
746 dev_err(card->dev, "Can't configure clocks\n");
747 return err;
748 }
749 }
750
751 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
752
753#ifndef CONFIG_ARCH_TEGRA_2x_SOC
754 /* codec configuration */
755 machine->codec_info[BT_SCO].rate = params_rate(params);
756 machine->codec_info[BT_SCO].channels = params_channels(params);
757 machine->codec_info[BT_SCO].bitsize = 16;
758 machine->codec_info[BT_SCO].is_i2smaster = 1;
759 machine->codec_info[BT_SCO].is_format_dsp = 1;
760
761 /* baseband configuration */
762 machine->codec_info[BASEBAND].bitsize = 16;
763 machine->codec_info[BASEBAND].is_i2smaster = 1;
764 machine->codec_info[BASEBAND].is_format_dsp = 1;
765#endif
766
767 machine->is_device_bt = 1;
768
769 return 0;
770}
771
772static void tegra_aic326x_bt_voice_call_shutdown(
773 struct snd_pcm_substream *substream)
774{
775 struct snd_soc_pcm_runtime *rtd = substream->private_data;
776 struct tegra_aic326x *machine =
777 snd_soc_card_get_drvdata(rtd->codec->card);
778
779#ifndef CONFIG_ARCH_TEGRA_2x_SOC
780 machine->codec_info[BT_SCO].rate = 0;
781 machine->codec_info[BT_SCO].channels = 0;
782#endif
783
784 machine->is_device_bt = 0;
785}
786
787static struct snd_soc_ops tegra_aic326x_hifi_ops = {
788 .hw_params = tegra_aic326x_hw_params,
789 .hw_free = tegra_aic326x_hw_free,
790#ifndef CONFIG_ARCH_TEGRA_2x_SOC
791 .startup = tegra_aic326x_startup,
792 .shutdown = tegra_aic326x_shutdown,
793#endif
794};
795
796static struct snd_soc_ops tegra_aic326x_spdif_ops = {
797 .hw_params = tegra_aic326x_spdif_hw_params,
798 .hw_free = tegra_aic326x_hw_free,
799};
800
801static struct snd_soc_ops tegra_aic326x_voice_call_ops = {
802 .hw_params = tegra_aic326x_voice_call_hw_params,
803 .shutdown = tegra_aic326x_voice_call_shutdown,
804 .hw_free = tegra_aic326x_hw_free,
805};
806
807static struct snd_soc_ops tegra_aic326x_bt_voice_call_ops = {
808 .hw_params = tegra_aic326x_bt_voice_call_hw_params,
809 .shutdown = tegra_aic326x_bt_voice_call_shutdown,
810 .hw_free = tegra_aic326x_hw_free,
811};
812
813static struct snd_soc_ops tegra_aic326x_bt_ops = {
814 .hw_params = tegra_aic326x_bt_hw_params,
815 .hw_free = tegra_aic326x_hw_free,
816#ifndef CONFIG_ARCH_TEGRA_2x_SOC
817 .startup = tegra_aic326x_startup,
818 .shutdown = tegra_aic326x_shutdown,
819#endif
820};
821
822static struct snd_soc_jack tegra_aic326x_hp_jack;
823
824#ifdef CONFIG_SWITCH
825static struct switch_dev aic326x_wired_switch_dev = {
826 .name = "h2w",
827};
828
829/* These values are copied from WiredAccessoryObserver */
830enum headset_state {
831 BIT_NO_HEADSET = 0,
832 BIT_HEADSET = (1 << 0),
833 BIT_HEADSET_NO_MIC = (1 << 1),
834};
835
836static int aic326x_headset_switch_notify(struct notifier_block *self,
837 unsigned long action, void *dev)
838{
839 int state = 0;
840
841 switch (action) {
842 case SND_JACK_HEADPHONE:
843 state |= BIT_HEADSET_NO_MIC;
844 break;
845 case SND_JACK_HEADSET:
846 state |= BIT_HEADSET;
847 break;
848 default:
849 state |= BIT_NO_HEADSET;
850 }
851
852 switch_set_state(&aic326x_wired_switch_dev, state);
853
854 return NOTIFY_OK;
855}
856
857static struct notifier_block aic326x_headset_switch_nb = {
858 .notifier_call = aic326x_headset_switch_notify,
859};
860#else
861static struct snd_soc_jack_pin tegra_aic326x_hp_jack_pins[] = {
862 {
863 .pin = "Headphone Jack",
864 .mask = SND_JACK_HEADPHONE,
865 },
866};
867#endif
868
869static int tegra_aic326x_event_int_spk(struct snd_soc_dapm_widget *w,
870 struct snd_kcontrol *k, int event)
871{
872 struct snd_soc_dapm_context *dapm = w->dapm;
873 struct snd_soc_card *card = dapm->card;
874 struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card);
875 struct tegra_aic326x_platform_data *pdata = machine->pdata;
876
877 if (!(machine->gpio_requested & GPIO_SPKR_EN))
878 return 0;
879
880 gpio_set_value_cansleep(pdata->gpio_spkr_en,
881 SND_SOC_DAPM_EVENT_ON(event));
882
883 return 0;
884}
885
886static int tegra_aic326x_event_hp(struct snd_soc_dapm_widget *w,
887 struct snd_kcontrol *k, int event)
888{
889 struct snd_soc_dapm_context *dapm = w->dapm;
890 struct snd_soc_card *card = dapm->card;
891 struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card);
892 struct tegra_aic326x_platform_data *pdata = machine->pdata;
893
894 if (!(machine->gpio_requested & GPIO_HP_MUTE))
895 return 0;
896
897 gpio_set_value_cansleep(pdata->gpio_hp_mute,
898 !SND_SOC_DAPM_EVENT_ON(event));
899
900 return 0;
901}
902
903static const struct snd_soc_dapm_widget tegra_aic326x_dapm_widgets[] = {
904 SND_SOC_DAPM_SPK("Int Spk", tegra_aic326x_event_int_spk),
905 SND_SOC_DAPM_HP("Earpiece", NULL),
906 SND_SOC_DAPM_HP("Headphone Jack", tegra_aic326x_event_hp),
907 SND_SOC_DAPM_MIC("Mic Jack", NULL),
908 SND_SOC_DAPM_INPUT("Ext Mic"),
909 SND_SOC_DAPM_LINE("Linein", NULL),
910 SND_SOC_DAPM_MIC("Int Mic", NULL),
911};
912
913static const struct snd_soc_dapm_route aic326x_audio_map[] = {
914 {"Int Spk", NULL, "SPKL"},
915 {"Int Spk", NULL, "SPKR"},
916 {"Earpiece", NULL, "RECP"},
917 {"Earpiece", NULL, "RECM"},
918 {"Headphone Jack", NULL, "HPL"},
919 {"Headphone Jack", NULL, "HPR"},
920 /* internal (IN2L/IN2R) mic is stero */
921 {"Mic Bias Int" ,NULL, "Int Mic"},
922 {"IN2L", NULL, "Mic Bias Int"},
923 {"Mic Bias Int" ,NULL, "Int Mic"},
924 {"IN2R", NULL, "Mic Bias Int"},
925 {"Mic Bias Ext" ,NULL, "Mic Jack"},
926 {"CM1L" ,NULL, "Mic Jack"},
927 {"IN1L", NULL, "Mic Bias Ext"},
928 {"IN1L", NULL, "CM1L"},
929};
930
931static const struct snd_kcontrol_new tegra_aic326x_controls[] = {
932 SOC_DAPM_PIN_SWITCH("Int Spk"),
933 SOC_DAPM_PIN_SWITCH("Earpiece"),
934 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
935 SOC_DAPM_PIN_SWITCH("Mic Jack"),
936 SOC_DAPM_PIN_SWITCH("Ext Mic"),
937 SOC_DAPM_PIN_SWITCH("Linein"),
938 SOC_DAPM_PIN_SWITCH("Int Mic"),
939};
940
941static int tegra_aic326x_init(struct snd_soc_pcm_runtime *rtd)
942{
943 struct snd_soc_codec *codec = rtd->codec;
944 struct snd_soc_dapm_context *dapm = &codec->dapm;
945 struct snd_soc_card *card = codec->card;
946 struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card);
947 struct tegra_aic326x_platform_data *pdata = machine->pdata;
948#ifndef CONFIG_ARCH_TEGRA_2x_SOC
949 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(rtd->cpu_dai);
950#endif
951 int ret;
952
953#ifndef CONFIG_ARCH_TEGRA_2x_SOC
954 if (machine->codec_info[BASEBAND].i2s_id != -1)
955 i2s->is_dam_used = true;
956#endif
957
958 if (machine->init_done)
959 return 0;
960
961 machine->init_done = true;
962
963#ifndef CONFIG_ARCH_TEGRA_2x_SOC
964 machine->pcard = card;
965#endif
966
967 if (machine_is_whistler()) {
968 machine->audio_reg = regulator_get(NULL, "avddio_audio");
969 if (IS_ERR(machine->audio_reg)) {
970 dev_err(card->dev, "cannot get avddio_audio reg\n");
971 ret = PTR_ERR(machine->audio_reg);
972 return ret;
973 }
974
975 ret = regulator_enable(machine->audio_reg);
976 if (ret) {
977 dev_err(card->dev, "cannot enable avddio_audio reg\n");
978 regulator_put(machine->audio_reg);
979 machine->audio_reg = NULL;
980 return ret;
981 }
982 }
983
984 if (gpio_is_valid(pdata->gpio_spkr_en)) {
985 ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
986 if (ret) {
987 dev_err(card->dev, "cannot get spkr_en gpio\n");
988 return ret;
989 }
990 machine->gpio_requested |= GPIO_SPKR_EN;
991
992 gpio_direction_output(pdata->gpio_spkr_en, 0);
993 }
994
995 if (gpio_is_valid(pdata->gpio_hp_mute)) {
996 ret = gpio_request(pdata->gpio_hp_mute, "hp_mute");
997 if (ret) {
998 dev_err(card->dev, "cannot get hp_mute gpio\n");
999 return ret;
1000 }
1001 machine->gpio_requested |= GPIO_HP_MUTE;
1002
1003 gpio_direction_output(pdata->gpio_hp_mute, 0);
1004 }
1005
1006 if (gpio_is_valid(pdata->gpio_int_mic_en)) {
1007 ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
1008 if (ret) {
1009 dev_err(card->dev, "cannot get int_mic_en gpio\n");
1010 return ret;
1011 }
1012 machine->gpio_requested |= GPIO_INT_MIC_EN;
1013
1014 /* Disable int mic; enable signal is active-high */
1015 gpio_direction_output(pdata->gpio_int_mic_en, 0);
1016 }
1017
1018 if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
1019 ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
1020 if (ret) {
1021 dev_err(card->dev, "cannot get ext_mic_en gpio\n");
1022 return ret;
1023 }
1024 machine->gpio_requested |= GPIO_EXT_MIC_EN;
1025
1026 /* Enable ext mic; enable signal is active-low */
1027 gpio_direction_output(pdata->gpio_ext_mic_en, 0);
1028 }
1029
1030 ret = snd_soc_add_controls(codec, tegra_aic326x_controls,
1031 ARRAY_SIZE(tegra_aic326x_controls));
1032 if (ret < 0)
1033 return ret;
1034
1035 snd_soc_dapm_new_controls(dapm, tegra_aic326x_dapm_widgets,
1036 ARRAY_SIZE(tegra_aic326x_dapm_widgets));
1037
1038 snd_soc_dapm_add_routes(dapm, aic326x_audio_map,
1039 ARRAY_SIZE(aic326x_audio_map));
1040
1041 ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
1042 &tegra_aic326x_hp_jack);
1043 if (ret < 0)
1044 return ret;
1045
1046#ifdef CONFIG_SWITCH
1047 snd_soc_jack_notifier_register(&tegra_aic326x_hp_jack,
1048 &aic326x_headset_switch_nb);
1049#else /*gpio based headset detection*/
1050 snd_soc_jack_add_pins(&tegra_aic326x_hp_jack,
1051 ARRAY_SIZE(tegra_aic326x_hp_jack_pins),
1052 tegra_aic326x_hp_jack_pins);
1053#endif
1054
1055 aic326x_headset_detect(codec, &tegra_aic326x_hp_jack,
1056 SND_JACK_HEADSET);
1057
1058 /* Add call mode switch control */
1059 ret = snd_ctl_add(codec->card->snd_card,
1060 snd_ctl_new1(&tegra_aic326x_call_mode_control,
1061 machine));
1062 if (ret < 0)
1063 return ret;
1064
1065 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS_EXT ON");
1066 snd_soc_dapm_force_enable_pin(dapm,"MICBIAS_INT ON");
1067 snd_soc_dapm_sync(dapm);
1068
1069 return 0;
1070}
1071
1072static struct snd_soc_dai_link tegra_aic326x_dai[] = {
1073 [DAI_LINK_HIFI] = {
1074 .name = "AIC3262",
1075 .stream_name = "AIC3262 PCM HIFI",
1076 .codec_name = "aic3262-codec.4-0018",
1077 .platform_name = "tegra-pcm-audio",
1078#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1079 .cpu_dai_name = "tegra20-i2s.0",
1080#else
1081 .cpu_dai_name = "tegra30-i2s.0",
1082#endif
1083 .codec_dai_name = "aic3262-asi1",
1084 .init = tegra_aic326x_init,
1085 .ops = &tegra_aic326x_hifi_ops,
1086 },
1087 [DAI_LINK_SPDIF] = {
1088 .name = "SPDIF",
1089 .stream_name = "SPDIF PCM",
1090 .codec_name = "spdif-dit.0",
1091 .platform_name = "tegra-pcm-audio",
1092#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1093 .cpu_dai_name = "tegra20-spdif",
1094#else
1095 .cpu_dai_name = "tegra30-spdif",
1096#endif
1097 .codec_dai_name = "dit-hifi",
1098 .ops = &tegra_aic326x_spdif_ops,
1099 },
1100 [DAI_LINK_BTSCO] = {
1101 .name = "BT-SCO",
1102 .stream_name = "BT SCO PCM",
1103 .codec_name = "spdif-dit.1",
1104 .platform_name = "tegra-pcm-audio",
1105#ifdef CONFIG_ARCH_TEGRA_2x_SOC
1106 .cpu_dai_name = "tegra20-i2s.1",
1107#else
1108 .cpu_dai_name = "tegra30-i2s.3",
1109#endif
1110 .codec_dai_name = "dit-hifi",
1111 .init = tegra_aic326x_init,
1112 .ops = &tegra_aic326x_bt_ops,
1113 },
1114 [DAI_LINK_VOICE_CALL] = {
1115 .name = "VOICE CALL",
1116 .stream_name = "VOICE CALL PCM",
1117 .codec_name = "aic3262-codec.4-0018",
1118 .platform_name = "tegra-pcm-audio",
1119 .cpu_dai_name = "dit-hifi",
1120 .codec_dai_name = "aic3262-asi2",
1121 .ops = &tegra_aic326x_voice_call_ops,
1122 },
1123 [DAI_LINK_BT_VOICE_CALL] = {
1124 .name = "BT VOICE CALL",
1125 .stream_name = "BT VOICE CALL PCM",
1126 .codec_name = "spdif-dit.2",
1127 .platform_name = "tegra-pcm-audio",
1128 .cpu_dai_name = "dit-hifi",
1129 .codec_dai_name = "dit-hifi",
1130 .ops = &tegra_aic326x_bt_voice_call_ops,
1131 },
1132};
1133
1134static struct snd_soc_card snd_soc_tegra_aic326x = {
1135 .name = "tegra-aic326x",
1136 .dai_link = tegra_aic326x_dai,
1137 .num_links = ARRAY_SIZE(tegra_aic326x_dai),
1138};
1139
1140static __devinit int tegra_aic326x_driver_probe(struct platform_device *pdev)
1141{
1142 struct snd_soc_card *card = &snd_soc_tegra_aic326x;
1143 struct tegra_aic326x *machine;
1144 struct tegra_aic326x_platform_data *pdata;
1145 int ret, i;
1146
1147 pdata = pdev->dev.platform_data;
1148 if (!pdata) {
1149 dev_err(&pdev->dev, "No platform data supplied\n");
1150 return -EINVAL;
1151 }
1152
1153 machine = kzalloc(sizeof(struct tegra_aic326x), GFP_KERNEL);
1154 if (!machine) {
1155 dev_err(&pdev->dev, "Can't allocate tegra_aic326x struct\n");
1156 return -ENOMEM;
1157 }
1158
1159 machine->pdata = pdata;
1160
1161 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
1162 if (ret)
1163 goto err_free_machine;
1164
1165 card->dev = &pdev->dev;
1166 platform_set_drvdata(pdev, card);
1167 snd_soc_card_set_drvdata(card, machine);
1168
1169#ifdef CONFIG_SWITCH
1170 /* Add h2w switch class support */
1171 ret = switch_dev_register(&aic326x_wired_switch_dev);
1172 if (ret < 0) {
1173 dev_err(&pdev->dev, "not able to register switch device %d\n",
1174 ret);
1175 goto err_fini_utils;
1176 }
1177#endif
1178
1179#ifndef CONFIG_ARCH_TEGRA_2x_SOC
1180 for (i = 0; i < NUM_I2S_DEVICES ; i++)
1181 machine->codec_info[i].i2s_id = pdata->audio_port_id[i];
1182
1183 machine->codec_info[BASEBAND].rate = pdata->baseband_param.rate;
1184 machine->codec_info[BASEBAND].channels = pdata->baseband_param.channels;
1185
1186 tegra_aic326x_dai[DAI_LINK_HIFI].cpu_dai_name =
1187 tegra_i2s_dai_name[machine->codec_info[HIFI_CODEC].i2s_id];
1188
1189 tegra_aic326x_dai[DAI_LINK_BTSCO].cpu_dai_name =
1190 tegra_i2s_dai_name[machine->codec_info[BT_SCO].i2s_id];
1191#endif
1192
1193 if(machine_is_tegra_enterprise()) {
1194 tegra_aic326x_dai[DAI_LINK_HIFI].codec_name = "aic3262-codec.0-0018";
1195 tegra_aic326x_dai[DAI_LINK_VOICE_CALL].codec_name = "aic3262-codec.0-0018";
1196 tegra_aic326x_dai[DAI_LINK_VOICE_CALL].codec_dai_name = "aic3262-asi1";
1197 }
1198
1199 ret = snd_soc_register_card(card);
1200 if (ret) {
1201 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
1202 ret);
1203 goto err_switch_unregister;
1204 }
1205
1206 if (!card->instantiated) {
1207 dev_err(&pdev->dev, "No TI AIC3262 codec\n");
1208 goto err_unregister_card;
1209 }
1210
1211 return 0;
1212
1213err_unregister_card:
1214 snd_soc_unregister_card(card);
1215err_switch_unregister:
1216#ifdef CONFIG_SWITCH
1217 switch_dev_unregister(&aic326x_wired_switch_dev);
1218#endif
1219err_fini_utils:
1220 tegra_asoc_utils_fini(&machine->util_data);
1221err_free_machine:
1222 kfree(machine);
1223 return ret;
1224}
1225
1226static int __devexit tegra_aic326x_driver_remove(struct platform_device *pdev)
1227{
1228 struct snd_soc_card *card = platform_get_drvdata(pdev);
1229 struct tegra_aic326x *machine = snd_soc_card_get_drvdata(card);
1230 struct tegra_aic326x_platform_data *pdata = machine->pdata;
1231
1232 snd_soc_unregister_card(card);
1233
1234#ifdef CONFIG_SWITCH
1235 switch_dev_unregister(&aic326x_wired_switch_dev);
1236#endif
1237
1238 tegra_asoc_utils_fini(&machine->util_data);
1239
1240 if (machine->gpio_requested & GPIO_EXT_MIC_EN)
1241 gpio_free(pdata->gpio_ext_mic_en);
1242 if (machine->gpio_requested & GPIO_INT_MIC_EN)
1243 gpio_free(pdata->gpio_int_mic_en);
1244 if (machine->gpio_requested & GPIO_HP_MUTE)
1245 gpio_free(pdata->gpio_hp_mute);
1246 if (machine->gpio_requested & GPIO_SPKR_EN)
1247 gpio_free(pdata->gpio_spkr_en);
1248
1249 kfree(machine);
1250
1251 return 0;
1252}
1253
1254static struct platform_driver tegra_aic326x_driver = {
1255 .driver = {
1256 .name = DRV_NAME,
1257 .owner = THIS_MODULE,
1258 .pm = &snd_soc_pm_ops,
1259 },
1260 .probe = tegra_aic326x_driver_probe,
1261 .remove = __devexit_p(tegra_aic326x_driver_remove),
1262};
1263
1264static int __init tegra_aic326x_modinit(void)
1265{
1266 return platform_driver_register(&tegra_aic326x_driver);
1267}
1268module_init(tegra_aic326x_modinit);
1269
1270static void __exit tegra_aic326x_modexit(void)
1271{
1272 platform_driver_unregister(&tegra_aic326x_driver);
1273}
1274module_exit(tegra_aic326x_modexit);
1275
1276/* Module information */
1277MODULE_AUTHOR("Vinod G. <vinodg@nvidia.com>");
1278MODULE_DESCRIPTION("Tegra+AIC3262 machine ASoC driver");
1279MODULE_DESCRIPTION("Tegra ALSA SoC");
1280MODULE_LICENSE("GPL");
1281
diff --git a/sound/soc/tegra/tegra_max98088.c b/sound/soc/tegra/tegra_max98088.c
new file mode 100644
index 00000000000..bae2b783895
--- /dev/null
+++ b/sound/soc/tegra/tegra_max98088.c
@@ -0,0 +1,1233 @@
1/*
2 * tegra_max98088.c - Tegra machine ASoC driver for boards using MAX98088 codec.
3 *
4 * Author: Sumit Bhattacharya <sumitb@nvidia.com>
5 * Copyright (C) 2011 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * (c) 2010, 2011 Nvidia Graphics Pvt. Ltd.
10 *
11 * Copyright 2007 Wolfson Microelectronics PLC.
12 * Author: Graeme Gregory
13 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * version 2 as published by the Free Software Foundation.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 * 02110-1301 USA
28 *
29 */
30
31#include <asm/mach-types.h>
32
33#include <linux/clk.h>
34#include <linux/module.h>
35#include <linux/platform_device.h>
36#include <linux/slab.h>
37#include <linux/gpio.h>
38#include <linux/regulator/consumer.h>
39#ifdef CONFIG_SWITCH
40#include <linux/switch.h>
41#endif
42
43#include <mach/tegra_asoc_pdata.h>
44
45#include <sound/core.h>
46#include <sound/jack.h>
47#include <sound/pcm.h>
48#include <sound/pcm_params.h>
49#include <sound/soc.h>
50
51#include "../codecs/max98088.h"
52
53#include "tegra_pcm.h"
54#include "tegra_asoc_utils.h"
55#ifndef CONFIG_ARCH_TEGRA_2x_SOC
56#include "tegra30_ahub.h"
57#include "tegra30_i2s.h"
58#include "tegra30_dam.h"
59#endif
60
61#define DRV_NAME "tegra-snd-max98088"
62
63#define GPIO_SPKR_EN BIT(0)
64#define GPIO_HP_MUTE BIT(1)
65#define GPIO_INT_MIC_EN BIT(2)
66#define GPIO_EXT_MIC_EN BIT(3)
67
68#define DAI_LINK_HIFI 0
69#define DAI_LINK_SPDIF 1
70#define DAI_LINK_BTSCO 2
71#define DAI_LINK_VOICE_CALL 3
72#define DAI_LINK_BT_VOICE_CALL 4
73#define NUM_DAI_LINKS 5
74
75#ifndef CONFIG_ARCH_TEGRA_2x_SOC
76const char *tegra_max98088_i2s_dai_name[TEGRA30_NR_I2S_IFC] = {
77 "tegra30-i2s.0",
78 "tegra30-i2s.1",
79 "tegra30-i2s.2",
80 "tegra30-i2s.3",
81 "tegra30-i2s.4",
82};
83#endif
84
85extern int g_is_call_mode;
86
87struct tegra_max98088 {
88 struct tegra_asoc_utils_data util_data;
89 struct tegra_asoc_platform_data *pdata;
90 int gpio_requested;
91 bool init_done;
92 int is_call_mode;
93 int is_device_bt;
94#ifndef CONFIG_ARCH_TEGRA_2x_SOC
95 struct codec_config codec_info[NUM_I2S_DEVICES];
96#endif
97 enum snd_soc_bias_level bias_level;
98 struct snd_soc_card *pcard;
99};
100
101static int tegra_call_mode_info(struct snd_kcontrol *kcontrol,
102 struct snd_ctl_elem_info *uinfo)
103{
104 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
105 uinfo->count = 1;
106 uinfo->value.integer.min = 0;
107 uinfo->value.integer.max = 1;
108 return 0;
109}
110
111static int tegra_call_mode_get(struct snd_kcontrol *kcontrol,
112 struct snd_ctl_elem_value *ucontrol)
113{
114 struct tegra_max98088 *machine = snd_kcontrol_chip(kcontrol);
115
116 ucontrol->value.integer.value[0] = machine->is_call_mode;
117
118 return 0;
119}
120
121static int tegra_call_mode_put(struct snd_kcontrol *kcontrol,
122 struct snd_ctl_elem_value *ucontrol)
123{
124 struct tegra_max98088 *machine = snd_kcontrol_chip(kcontrol);
125 int is_call_mode_new = ucontrol->value.integer.value[0];
126 int codec_index;
127 unsigned int i;
128
129 if (machine->is_call_mode == is_call_mode_new)
130 return 0;
131
132 if (machine->is_device_bt)
133 codec_index = BT_SCO;
134 else
135 codec_index = HIFI_CODEC;
136
137 if (is_call_mode_new) {
138#ifndef CONFIG_ARCH_TEGRA_2x_SOC
139 if (machine->codec_info[codec_index].rate == 0 ||
140 machine->codec_info[codec_index].channels == 0)
141 return -EINVAL;
142
143 for (i = 0; i < machine->pcard->num_links; i++)
144 machine->pcard->dai_link[i].ignore_suspend = 1;
145
146 tegra30_make_voice_call_connections(
147 &machine->codec_info[codec_index],
148 &machine->codec_info[BASEBAND]);
149#endif
150 } else {
151#ifndef CONFIG_ARCH_TEGRA_2x_SOC
152 tegra30_break_voice_call_connections(
153 &machine->codec_info[codec_index],
154 &machine->codec_info[BASEBAND]);
155
156 for (i = 0; i < machine->pcard->num_links; i++)
157 machine->pcard->dai_link[i].ignore_suspend = 0;
158#endif
159 }
160
161 machine->is_call_mode = is_call_mode_new;
162 g_is_call_mode = machine->is_call_mode;
163
164 return 1;
165}
166
167struct snd_kcontrol_new tegra_call_mode_control = {
168 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
169 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
170 .name = "Call Mode Switch",
171 .private_value = 0xffff,
172 .info = tegra_call_mode_info,
173 .get = tegra_call_mode_get,
174 .put = tegra_call_mode_put
175};
176
177#ifndef CONFIG_ARCH_TEGRA_2x_SOC
178static int tegra_max98088_set_dam_cif(int dam_ifc, int srate,
179 int channels, int bit_size, int src_on, int src_srate,
180 int src_channels, int src_bit_size)
181{
182 tegra30_dam_set_gain(dam_ifc, TEGRA30_DAM_CHIN1, 0x1000);
183 tegra30_dam_set_samplerate(dam_ifc, TEGRA30_DAM_CHOUT,
184 srate);
185 tegra30_dam_set_samplerate(dam_ifc, TEGRA30_DAM_CHIN1,
186 srate);
187 tegra30_dam_set_acif(dam_ifc, TEGRA30_DAM_CHIN1,
188 channels, bit_size, channels,
189 bit_size);
190 tegra30_dam_set_acif(dam_ifc, TEGRA30_DAM_CHOUT,
191 channels, bit_size, channels,
192 bit_size);
193
194 if (src_on) {
195 tegra30_dam_set_gain(dam_ifc, TEGRA30_DAM_CHIN0_SRC, 0x1000);
196 tegra30_dam_set_samplerate(dam_ifc, TEGRA30_DAM_CHIN0_SRC,
197 src_srate);
198 tegra30_dam_set_acif(dam_ifc, TEGRA30_DAM_CHIN0_SRC,
199 src_channels, src_bit_size, 1, 16);
200 }
201
202 return 0;
203}
204#endif
205
206static int tegra_max98088_hw_params(struct snd_pcm_substream *substream,
207 struct snd_pcm_hw_params *params)
208{
209 struct snd_soc_pcm_runtime *rtd = substream->private_data;
210 struct snd_soc_dai *codec_dai = rtd->codec_dai;
211 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
212 struct snd_soc_codec *codec = rtd->codec;
213 struct snd_soc_card *card = codec->card;
214 struct tegra_max98088 *machine = snd_soc_card_get_drvdata(card);
215#ifndef CONFIG_ARCH_TEGRA_2x_SOC
216 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai);
217#endif
218 int srate, mclk, sample_size, i2s_daifmt;
219 int err;
220 struct clk *clk;
221 int rate;
222
223 switch (params_format(params)) {
224 case SNDRV_PCM_FORMAT_S16_LE:
225 sample_size = 16;
226 break;
227 default:
228 return -EINVAL;
229 }
230
231 srate = params_rate(params);
232 switch (srate) {
233 case 8000:
234 case 16000:
235 case 24000:
236 case 32000:
237 case 48000:
238 case 64000:
239 case 96000:
240 mclk = 12288000;
241 break;
242 case 11025:
243 case 22050:
244 case 44100:
245 case 88200:
246 mclk = 11289600;
247 break;
248 default:
249 mclk = 12000000;
250 break;
251 }
252
253
254#if defined(CONFIG_ARCH_TEGRA_2x_SOC)
255 clk = clk_get_sys(NULL, "cdev1");
256#else
257 clk = clk_get_sys("extern1", NULL);
258#endif
259 if (IS_ERR(clk)) {
260 dev_err(card->dev, "Can't retrieve clk cdev1\n");
261 err = PTR_ERR(clk);
262 return err;
263 }
264
265 rate = clk_get_rate(clk);
266 printk("extern1 rate=%d\n",rate);
267
268#if TEGRA30_I2S_MASTER_PLAYBACK
269 i2s_daifmt = SND_SOC_DAIFMT_I2S |
270 SND_SOC_DAIFMT_NB_NF |
271 SND_SOC_DAIFMT_CBS_CFS;
272#else
273 i2s_daifmt = SND_SOC_DAIFMT_I2S |
274 SND_SOC_DAIFMT_NB_NF |
275 SND_SOC_DAIFMT_CBM_CFM;
276 mclk = rate;
277#endif
278
279 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
280 if (err < 0) {
281 if (!(machine->util_data.set_mclk % mclk))
282 mclk = machine->util_data.set_mclk;
283 else {
284 dev_err(card->dev, "Can't configure clocks\n");
285 return err;
286 }
287 }
288
289 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
290
291 err = snd_soc_dai_set_fmt(codec_dai,i2s_daifmt);
292 if (err < 0) {
293 dev_err(card->dev, "codec_dai fmt not set\n");
294 return err;
295 }
296
297 err = snd_soc_dai_set_fmt(cpu_dai, i2s_daifmt);
298 if (err < 0) {
299 dev_err(card->dev, "cpu_dai fmt not set\n");
300 return err;
301 }
302
303 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
304 SND_SOC_CLOCK_IN);
305 if (err < 0) {
306 dev_err(card->dev, "codec_dai clock not set\n");
307 return err;
308 }
309
310#ifndef CONFIG_ARCH_TEGRA_2x_SOC
311 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
312 tegra_max98088_set_dam_cif(i2s->dam_ifc, srate,
313 params_channels(params), sample_size, 0, 0, 0, 0);
314#endif
315
316 return 0;
317}
318
319static int tegra_spdif_hw_params(struct snd_pcm_substream *substream,
320 struct snd_pcm_hw_params *params)
321{
322 struct snd_soc_pcm_runtime *rtd = substream->private_data;
323 struct snd_soc_card *card = rtd->card;
324 struct tegra_max98088 *machine = snd_soc_card_get_drvdata(card);
325 int srate, mclk, min_mclk;
326 int err;
327
328 srate = params_rate(params);
329 switch (srate) {
330 case 11025:
331 case 22050:
332 case 44100:
333 case 88200:
334 mclk = 11289600;
335 break;
336 case 8000:
337 case 16000:
338 case 32000:
339 case 48000:
340 case 64000:
341 case 96000:
342 mclk = 12288000;
343 break;
344 default:
345 return -EINVAL;
346 }
347 min_mclk = 128 * srate;
348
349 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
350 if (err < 0) {
351 if (!(machine->util_data.set_mclk % min_mclk))
352 mclk = machine->util_data.set_mclk;
353 else {
354 dev_err(card->dev, "Can't configure clocks\n");
355 return err;
356 }
357 }
358
359 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
360
361 return 0;
362}
363
364static int tegra_bt_hw_params(struct snd_pcm_substream *substream,
365 struct snd_pcm_hw_params *params)
366{
367 struct snd_soc_pcm_runtime *rtd = substream->private_data;
368#ifndef CONFIG_ARCH_TEGRA_2x_SOC
369 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(rtd->cpu_dai);
370#endif
371 struct snd_soc_card *card = rtd->card;
372 struct tegra_max98088 *machine = snd_soc_card_get_drvdata(card);
373 int err, srate, mclk, min_mclk, sample_size;
374
375 switch (params_format(params)) {
376 case SNDRV_PCM_FORMAT_S16_LE:
377 sample_size = 16;
378 break;
379 default:
380 return -EINVAL;
381 }
382
383 srate = params_rate(params);
384 switch (srate) {
385 case 11025:
386 case 22050:
387 case 44100:
388 case 88200:
389 mclk = 11289600;
390 break;
391 case 8000:
392 case 16000:
393 case 32000:
394 case 48000:
395 case 64000:
396 case 96000:
397 mclk = 12288000;
398 break;
399 default:
400 return -EINVAL;
401 }
402 min_mclk = 64 * srate;
403
404 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
405 if (err < 0) {
406 if (!(machine->util_data.set_mclk % min_mclk))
407 mclk = machine->util_data.set_mclk;
408 else {
409 dev_err(card->dev, "Can't configure clocks\n");
410 return err;
411 }
412 }
413
414 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
415
416 err = snd_soc_dai_set_fmt(rtd->cpu_dai,
417 SND_SOC_DAIFMT_DSP_A |
418 SND_SOC_DAIFMT_NB_NF |
419 SND_SOC_DAIFMT_CBS_CFS);
420 if (err < 0) {
421 dev_err(rtd->codec->card->dev, "cpu_dai fmt not set\n");
422 return err;
423 }
424
425#ifndef CONFIG_ARCH_TEGRA_2x_SOC
426 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
427 tegra_max98088_set_dam_cif(i2s->dam_ifc, params_rate(params),
428 params_channels(params), sample_size, 0, 0, 0, 0);
429#endif
430
431 return 0;
432}
433
434static int tegra_hw_free(struct snd_pcm_substream *substream)
435{
436 struct snd_soc_pcm_runtime *rtd = substream->private_data;
437 struct tegra_max98088 *machine = snd_soc_card_get_drvdata(rtd->card);
438
439 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 0);
440
441 return 0;
442}
443
444#ifndef CONFIG_ARCH_TEGRA_2x_SOC
445static int tegra_max98088_startup(struct snd_pcm_substream *substream)
446{
447 struct snd_soc_pcm_runtime *rtd = substream->private_data;
448 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
449 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai);
450 struct tegra_max98088 *machine = snd_soc_card_get_drvdata(rtd->card);
451 struct codec_config *codec_info;
452 struct codec_config *bb_info;
453 int codec_index;
454
455 if (!i2s->is_dam_used)
456 return 0;
457
458 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
459 /*dam configuration*/
460 if (!i2s->dam_ch_refcount)
461 i2s->dam_ifc = tegra30_dam_allocate_controller();
462
463 tegra30_dam_allocate_channel(i2s->dam_ifc, TEGRA30_DAM_CHIN1);
464 i2s->dam_ch_refcount++;
465 tegra30_dam_enable_clock(i2s->dam_ifc);
466
467 tegra30_ahub_set_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX1 +
468 (i2s->dam_ifc*2), i2s->txcif);
469
470 /*
471 *make the dam tx to i2s rx connection if this is the only client
472 *using i2s for playback
473 */
474 if (i2s->playback_ref_count == 1)
475 tegra30_ahub_set_rx_cif_source(
476 TEGRA30_AHUB_RXCIF_I2S0_RX0 + i2s->id,
477 TEGRA30_AHUB_TXCIF_DAM0_TX0 + i2s->dam_ifc);
478
479 /* enable the dam*/
480 tegra30_dam_enable(i2s->dam_ifc, TEGRA30_DAM_ENABLE,
481 TEGRA30_DAM_CHIN1);
482 } else {
483
484 i2s->is_call_mode_rec = machine->is_call_mode;
485
486 if (!i2s->is_call_mode_rec)
487 return 0;
488
489 if (machine->is_device_bt)
490 codec_index = BT_SCO;
491 else
492 codec_index = HIFI_CODEC;
493
494 codec_info = &machine->codec_info[codec_index];
495 bb_info = &machine->codec_info[BASEBAND];
496
497 /* allocate a dam for voice call recording */
498
499 i2s->call_record_dam_ifc = tegra30_dam_allocate_controller();
500 tegra30_dam_allocate_channel(i2s->call_record_dam_ifc,
501 TEGRA30_DAM_CHIN0_SRC);
502 tegra30_dam_allocate_channel(i2s->call_record_dam_ifc,
503 TEGRA30_DAM_CHIN1);
504 tegra30_dam_enable_clock(i2s->call_record_dam_ifc);
505
506 /* configure the dam */
507 tegra_max98088_set_dam_cif(i2s->call_record_dam_ifc,
508 codec_info->rate, codec_info->channels,
509 codec_info->bitsize, 1, bb_info->rate,
510 bb_info->channels, bb_info->bitsize);
511
512 /* setup the connections for voice call record */
513
514 tegra30_ahub_unset_rx_cif_source(i2s->rxcif);
515 tegra30_ahub_set_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX0 +
516 (i2s->call_record_dam_ifc*2),
517 TEGRA30_AHUB_TXCIF_I2S0_TX0 + bb_info->i2s_id);
518 tegra30_ahub_set_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX1 +
519 (i2s->call_record_dam_ifc*2),
520 TEGRA30_AHUB_TXCIF_I2S0_TX0 + codec_info->i2s_id);
521 tegra30_ahub_set_rx_cif_source(i2s->rxcif,
522 TEGRA30_AHUB_TXCIF_DAM0_TX0 + i2s->call_record_dam_ifc);
523
524 /* enable the dam*/
525
526 tegra30_dam_enable(i2s->call_record_dam_ifc, TEGRA30_DAM_ENABLE,
527 TEGRA30_DAM_CHIN1);
528 tegra30_dam_enable(i2s->call_record_dam_ifc, TEGRA30_DAM_ENABLE,
529 TEGRA30_DAM_CHIN0_SRC);
530 }
531
532 return 0;
533}
534
535static void tegra_max98088_shutdown(struct snd_pcm_substream *substream)
536{
537 struct snd_soc_pcm_runtime *rtd = substream->private_data;
538 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
539 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai);
540
541 if (!i2s->is_dam_used)
542 return;
543
544 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
545 /* disable the dam*/
546 tegra30_dam_enable(i2s->dam_ifc, TEGRA30_DAM_DISABLE,
547 TEGRA30_DAM_CHIN1);
548
549 /* disconnect the ahub connections*/
550 tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX1 +
551 (i2s->dam_ifc*2));
552
553 /* disable the dam and free the controller */
554 tegra30_dam_disable_clock(i2s->dam_ifc);
555 tegra30_dam_free_channel(i2s->dam_ifc, TEGRA30_DAM_CHIN1);
556 i2s->dam_ch_refcount--;
557 if (!i2s->dam_ch_refcount)
558 tegra30_dam_free_controller(i2s->dam_ifc);
559 } else {
560
561 if (!i2s->is_call_mode_rec)
562 return 0;
563
564 i2s->is_call_mode_rec = 0;
565
566 /* disable the dam*/
567 tegra30_dam_enable(i2s->call_record_dam_ifc,
568 TEGRA30_DAM_DISABLE, TEGRA30_DAM_CHIN1);
569 tegra30_dam_enable(i2s->call_record_dam_ifc,
570 TEGRA30_DAM_DISABLE, TEGRA30_DAM_CHIN0_SRC);
571
572 /* disconnect the ahub connections*/
573 tegra30_ahub_unset_rx_cif_source(i2s->rxcif);
574 tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX0 +
575 (i2s->call_record_dam_ifc*2));
576 tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX1 +
577 (i2s->call_record_dam_ifc*2));
578
579 /* free the dam channels and dam controller */
580 tegra30_dam_disable_clock(i2s->call_record_dam_ifc);
581 tegra30_dam_free_channel(i2s->call_record_dam_ifc,
582 TEGRA30_DAM_CHIN1);
583 tegra30_dam_free_channel(i2s->call_record_dam_ifc,
584 TEGRA30_DAM_CHIN0_SRC);
585 tegra30_dam_free_controller(i2s->call_record_dam_ifc);
586 }
587
588 return;
589}
590#endif
591
592static int tegra_voice_call_hw_params(struct snd_pcm_substream *substream,
593 struct snd_pcm_hw_params *params)
594{
595 struct snd_soc_pcm_runtime *rtd = substream->private_data;
596 struct snd_soc_dai *codec_dai = rtd->codec_dai;
597 struct snd_soc_codec *codec = rtd->codec;
598 struct snd_soc_card *card = codec->card;
599 struct tegra_max98088 *machine = snd_soc_card_get_drvdata(card);
600 int srate, mclk;
601 int err;
602
603 srate = params_rate(params);
604 switch (srate) {
605 case 8000:
606 case 16000:
607 case 24000:
608 case 32000:
609 case 48000:
610 case 64000:
611 case 96000:
612 mclk = 12288000;
613 break;
614 case 11025:
615 case 22050:
616 case 44100:
617 case 88200:
618 mclk = 11289600;
619 break;
620 default:
621 return -EINVAL;
622 break;
623 }
624
625 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
626 if (err < 0) {
627 if (!(machine->util_data.set_mclk % mclk))
628 mclk = machine->util_data.set_mclk;
629 else {
630 dev_err(card->dev, "Can't configure clocks\n");
631 return err;
632 }
633 }
634
635 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
636
637 err = snd_soc_dai_set_fmt(codec_dai,
638 SND_SOC_DAIFMT_I2S |
639 SND_SOC_DAIFMT_NB_NF |
640 SND_SOC_DAIFMT_CBS_CFS);
641 if (err < 0) {
642 dev_err(card->dev, "codec_dai fmt not set\n");
643 return err;
644 }
645
646 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
647 SND_SOC_CLOCK_IN);
648 if (err < 0) {
649 dev_err(card->dev, "codec_dai clock not set\n");
650 return err;
651 }
652
653#ifndef CONFIG_ARCH_TEGRA_2x_SOC
654 /* codec configuration */
655 machine->codec_info[HIFI_CODEC].rate = params_rate(params);
656 machine->codec_info[HIFI_CODEC].channels = params_channels(params);
657 machine->codec_info[HIFI_CODEC].bitsize = 16;
658 machine->codec_info[HIFI_CODEC].is_i2smaster = 1;
659 machine->codec_info[HIFI_CODEC].is_format_dsp = 0;
660
661 /* baseband configuration */
662 machine->codec_info[BASEBAND].bitsize = 16;
663 machine->codec_info[BASEBAND].is_i2smaster = 1;
664 machine->codec_info[BASEBAND].is_format_dsp = 1;
665#endif
666
667 machine->is_device_bt = 0;
668
669 return 0;
670}
671
672static void tegra_voice_call_shutdown(struct snd_pcm_substream *substream)
673{
674 struct snd_soc_pcm_runtime *rtd = substream->private_data;
675 struct tegra_max98088 *machine =
676 snd_soc_card_get_drvdata(rtd->codec->card);
677
678#ifndef CONFIG_ARCH_TEGRA_2x_SOC
679 machine->codec_info[HIFI_CODEC].rate = 0;
680 machine->codec_info[HIFI_CODEC].channels = 0;
681#endif
682
683 return;
684}
685
686static int tegra_bt_voice_call_hw_params(struct snd_pcm_substream *substream,
687 struct snd_pcm_hw_params *params)
688{
689 struct snd_soc_pcm_runtime *rtd = substream->private_data;
690 struct snd_soc_card *card = rtd->card;
691 struct tegra_max98088 *machine = snd_soc_card_get_drvdata(card);
692 int err, srate, mclk, min_mclk;
693
694 srate = params_rate(params);
695 switch (srate) {
696 case 11025:
697 case 22050:
698 case 44100:
699 case 88200:
700 mclk = 11289600;
701 break;
702 case 8000:
703 case 16000:
704 case 32000:
705 case 48000:
706 case 64000:
707 case 96000:
708 mclk = 12288000;
709 break;
710 default:
711 return -EINVAL;
712 }
713 min_mclk = 64 * srate;
714
715 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
716 if (err < 0) {
717 if (!(machine->util_data.set_mclk % min_mclk))
718 mclk = machine->util_data.set_mclk;
719 else {
720 dev_err(card->dev, "Can't configure clocks\n");
721 return err;
722 }
723 }
724
725 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
726
727#ifndef CONFIG_ARCH_TEGRA_2x_SOC
728 /* codec configuration */
729 machine->codec_info[BT_SCO].rate = params_rate(params);
730 machine->codec_info[BT_SCO].channels = params_channels(params);
731 machine->codec_info[BT_SCO].bitsize = 16;
732 machine->codec_info[BT_SCO].is_i2smaster = 1;
733 machine->codec_info[BT_SCO].is_format_dsp = 1;
734
735 /* baseband configuration */
736 machine->codec_info[BASEBAND].bitsize = 16;
737 machine->codec_info[BASEBAND].is_i2smaster = 1;
738 machine->codec_info[BASEBAND].is_format_dsp = 1;
739#endif
740
741 machine->is_device_bt = 1;
742
743 return 0;
744}
745
746static void tegra_bt_voice_call_shutdown(struct snd_pcm_substream *substream)
747{
748 struct snd_soc_pcm_runtime *rtd = substream->private_data;
749 struct tegra_max98088 *machine =
750 snd_soc_card_get_drvdata(rtd->codec->card);
751
752#ifndef CONFIG_ARCH_TEGRA_2x_SOC
753 machine->codec_info[BT_SCO].rate = 0;
754 machine->codec_info[BT_SCO].channels = 0;
755#endif
756
757 return;
758}
759
760static struct snd_soc_ops tegra_max98088_ops = {
761 .hw_params = tegra_max98088_hw_params,
762 .hw_free = tegra_hw_free,
763#ifndef CONFIG_ARCH_TEGRA_2x_SOC
764 .startup = tegra_max98088_startup,
765 .shutdown = tegra_max98088_shutdown,
766#endif
767};
768
769static struct snd_soc_ops tegra_spdif_ops = {
770 .hw_params = tegra_spdif_hw_params,
771 .hw_free = tegra_hw_free,
772};
773
774static struct snd_soc_ops tegra_voice_call_ops = {
775 .hw_params = tegra_voice_call_hw_params,
776 .shutdown = tegra_voice_call_shutdown,
777 .hw_free = tegra_hw_free,
778};
779
780static struct snd_soc_ops tegra_bt_voice_call_ops = {
781 .hw_params = tegra_bt_voice_call_hw_params,
782 .shutdown = tegra_bt_voice_call_shutdown,
783 .hw_free = tegra_hw_free,
784};
785
786static struct snd_soc_ops tegra_bt_ops = {
787 .hw_params = tegra_bt_hw_params,
788 .hw_free = tegra_hw_free,
789#ifndef CONFIG_ARCH_TEGRA_2x_SOC
790 .startup = tegra_max98088_startup,
791 .shutdown = tegra_max98088_shutdown,
792#endif
793};
794
795static struct snd_soc_jack tegra_max98088_hp_jack;
796
797#ifdef CONFIG_SWITCH
798static struct switch_dev wired_switch_dev = {
799 .name = "h2w",
800};
801
802/* These values are copied from WiredAccessoryObserver */
803enum headset_state {
804 BIT_NO_HEADSET = 0,
805 BIT_HEADSET = (1 << 0),
806 BIT_HEADSET_NO_MIC = (1 << 1),
807};
808
809static int headset_switch_notify(struct notifier_block *self,
810 unsigned long action, void *dev)
811{
812 int state = 0;
813
814 switch (action) {
815 case SND_JACK_HEADPHONE:
816 state |= BIT_HEADSET_NO_MIC;
817 break;
818 case SND_JACK_HEADSET:
819 state |= BIT_HEADSET;
820 break;
821 default:
822 state |= BIT_NO_HEADSET;
823 }
824
825 switch_set_state(&wired_switch_dev, state);
826
827 return NOTIFY_OK;
828}
829
830static struct notifier_block headset_switch_nb = {
831 .notifier_call = headset_switch_notify,
832};
833#else
834static struct snd_soc_jack_pin tegra_max98088_hp_jack_pins[] = {
835 {
836 .pin = "Headphone Jack",
837 .mask = SND_JACK_HEADPHONE,
838 },
839};
840#endif
841
842static int tegra_max98088_event_int_spk(struct snd_soc_dapm_widget *w,
843 struct snd_kcontrol *k, int event)
844{
845 struct snd_soc_dapm_context *dapm = w->dapm;
846 struct snd_soc_card *card = dapm->card;
847 struct tegra_max98088 *machine = snd_soc_card_get_drvdata(card);
848 struct tegra_asoc_platform_data *pdata = machine->pdata;
849
850 if (!(machine->gpio_requested & GPIO_SPKR_EN))
851 return 0;
852
853 gpio_set_value_cansleep(pdata->gpio_spkr_en,
854 SND_SOC_DAPM_EVENT_ON(event));
855
856 return 0;
857}
858
859static int tegra_max98088_event_hp(struct snd_soc_dapm_widget *w,
860 struct snd_kcontrol *k, int event)
861{
862 struct snd_soc_dapm_context *dapm = w->dapm;
863 struct snd_soc_card *card = dapm->card;
864 struct tegra_max98088 *machine = snd_soc_card_get_drvdata(card);
865 struct tegra_asoc_platform_data *pdata = machine->pdata;
866
867 if (!(machine->gpio_requested & GPIO_HP_MUTE))
868 return 0;
869
870 gpio_set_value_cansleep(pdata->gpio_hp_mute,
871 !SND_SOC_DAPM_EVENT_ON(event));
872
873 return 0;
874}
875
876static const struct snd_soc_dapm_widget tegra_max98088_dapm_widgets[] = {
877 SND_SOC_DAPM_SPK("Int Spk", tegra_max98088_event_int_spk),
878 SND_SOC_DAPM_OUTPUT("Earpiece"),
879 SND_SOC_DAPM_HP("Headphone Jack", tegra_max98088_event_hp),
880 SND_SOC_DAPM_MIC("Mic Jack", NULL),
881 SND_SOC_DAPM_INPUT("Int Mic"),
882};
883
884static const struct snd_soc_dapm_route enterprise_audio_map[] = {
885 {"Int Spk", NULL, "SPKL"},
886 {"Int Spk", NULL, "SPKR"},
887 {"Earpiece", NULL, "RECL"},
888 {"Earpiece", NULL, "RECR"},
889 {"Headphone Jack", NULL, "HPL"},
890 {"Headphone Jack", NULL, "HPR"},
891 {"MICBIAS", NULL, "Mic Jack"},
892 {"MIC2", NULL, "MICBIAS"},
893 {"MICBIAS", NULL, "Int Mic"},
894 {"MIC1", NULL, "MICBIAS"},
895};
896
897static const struct snd_kcontrol_new tegra_max98088_controls[] = {
898 SOC_DAPM_PIN_SWITCH("Int Spk"),
899 SOC_DAPM_PIN_SWITCH("Earpiece"),
900 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
901 SOC_DAPM_PIN_SWITCH("Mic Jack"),
902 SOC_DAPM_PIN_SWITCH("Int Mic"),
903};
904
905static int tegra_max98088_init(struct snd_soc_pcm_runtime *rtd)
906{
907 struct snd_soc_codec *codec = rtd->codec;
908 struct snd_soc_dapm_context *dapm = &codec->dapm;
909 struct snd_soc_card *card = codec->card;
910 struct tegra_max98088 *machine = snd_soc_card_get_drvdata(card);
911 struct tegra_asoc_platform_data *pdata = machine->pdata;
912#ifndef CONFIG_ARCH_TEGRA_2x_SOC
913 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(rtd->cpu_dai);
914#endif
915 int ret;
916
917#ifndef CONFIG_ARCH_TEGRA_2x_SOC
918 if (machine->codec_info[BASEBAND].i2s_id != -1)
919 i2s->is_dam_used = true;
920#endif
921
922 if (machine->init_done)
923 return 0;
924
925 machine->init_done = true;
926
927 machine->pcard = card;
928 machine->bias_level = SND_SOC_BIAS_STANDBY;
929
930 if (gpio_is_valid(pdata->gpio_spkr_en)) {
931 ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
932 if (ret) {
933 dev_err(card->dev, "cannot get spkr_en gpio\n");
934 return ret;
935 }
936 machine->gpio_requested |= GPIO_SPKR_EN;
937
938 gpio_direction_output(pdata->gpio_spkr_en, 0);
939 }
940
941 if (gpio_is_valid(pdata->gpio_hp_mute)) {
942 ret = gpio_request(pdata->gpio_hp_mute, "hp_mute");
943 if (ret) {
944 dev_err(card->dev, "cannot get hp_mute gpio\n");
945 return ret;
946 }
947 machine->gpio_requested |= GPIO_HP_MUTE;
948
949 gpio_direction_output(pdata->gpio_hp_mute, 0);
950 }
951
952 if (gpio_is_valid(pdata->gpio_int_mic_en)) {
953 ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
954 if (ret) {
955 dev_err(card->dev, "cannot get int_mic_en gpio\n");
956 return ret;
957 }
958 machine->gpio_requested |= GPIO_INT_MIC_EN;
959
960 /* Disable int mic; enable signal is active-high */
961 gpio_direction_output(pdata->gpio_int_mic_en, 0);
962 }
963
964 if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
965 ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
966 if (ret) {
967 dev_err(card->dev, "cannot get ext_mic_en gpio\n");
968 return ret;
969 }
970 machine->gpio_requested |= GPIO_EXT_MIC_EN;
971
972 /* Enable ext mic; enable signal is active-low */
973 gpio_direction_output(pdata->gpio_ext_mic_en, 0);
974 }
975
976 ret = snd_soc_add_controls(codec, tegra_max98088_controls,
977 ARRAY_SIZE(tegra_max98088_controls));
978 if (ret < 0)
979 return ret;
980
981 snd_soc_dapm_new_controls(dapm, tegra_max98088_dapm_widgets,
982 ARRAY_SIZE(tegra_max98088_dapm_widgets));
983
984 snd_soc_dapm_add_routes(dapm, enterprise_audio_map,
985 ARRAY_SIZE(enterprise_audio_map));
986
987 ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
988 &tegra_max98088_hp_jack);
989 if (ret < 0)
990 return ret;
991
992#ifdef CONFIG_SWITCH
993 snd_soc_jack_notifier_register(&tegra_max98088_hp_jack,
994 &headset_switch_nb);
995#else /*gpio based headset detection*/
996 snd_soc_jack_add_pins(&tegra_max98088_hp_jack,
997 ARRAY_SIZE(tegra_max98088_hp_jack_pins),
998 tegra_max98088_hp_jack_pins);
999#endif
1000
1001 max98088_headset_detect(codec, &tegra_max98088_hp_jack,
1002 SND_JACK_HEADSET);
1003
1004 /* Add call mode switch control */
1005 ret = snd_ctl_add(codec->card->snd_card,
1006 snd_ctl_new1(&tegra_call_mode_control, machine));
1007 if (ret < 0)
1008 return ret;
1009
1010 snd_soc_dapm_nc_pin(dapm, "INA1");
1011 snd_soc_dapm_nc_pin(dapm, "INA2");
1012 snd_soc_dapm_nc_pin(dapm, "INB1");
1013 snd_soc_dapm_nc_pin(dapm, "INB2");
1014 snd_soc_dapm_sync(dapm);
1015
1016 return 0;
1017}
1018
1019static struct snd_soc_dai_link tegra_max98088_dai[NUM_DAI_LINKS] = {
1020 [DAI_LINK_HIFI] = {
1021 .name = "MAX98088",
1022 .stream_name = "MAX98088 HIFI",
1023 .codec_name = "max98088.0-0010",
1024 .platform_name = "tegra-pcm-audio",
1025 .codec_dai_name = "HiFi",
1026 .init = tegra_max98088_init,
1027 .ops = &tegra_max98088_ops,
1028 },
1029 [DAI_LINK_SPDIF] = {
1030 .name = "SPDIF",
1031 .stream_name = "SPDIF PCM",
1032 .codec_name = "spdif-dit.0",
1033 .platform_name = "tegra-pcm-audio",
1034 .cpu_dai_name = "tegra30-spdif",
1035 .codec_dai_name = "dit-hifi",
1036 .ops = &tegra_spdif_ops,
1037 },
1038 [DAI_LINK_BTSCO] = {
1039 .name = "BT SCO",
1040 .stream_name = "BT SCO PCM",
1041 .codec_name = "spdif-dit.1",
1042 .platform_name = "tegra-pcm-audio",
1043 .codec_dai_name = "dit-hifi",
1044 .init = tegra_max98088_init,
1045 .ops = &tegra_bt_ops,
1046 },
1047 [DAI_LINK_VOICE_CALL] = {
1048 .name = "VOICE CALL",
1049 .stream_name = "VOICE CALL PCM",
1050 .codec_name = "max98088.0-0010",
1051 .platform_name = "tegra-pcm-audio",
1052 .cpu_dai_name = "dit-hifi",
1053 .codec_dai_name = "HiFi",
1054 .ops = &tegra_voice_call_ops,
1055 },
1056 [DAI_LINK_BT_VOICE_CALL] = {
1057 .name = "BT VOICE CALL",
1058 .stream_name = "BT VOICE CALL PCM",
1059 .codec_name = "spdif-dit.2",
1060 .platform_name = "tegra-pcm-audio",
1061 .cpu_dai_name = "dit-hifi",
1062 .codec_dai_name = "dit-hifi",
1063 .ops = &tegra_bt_voice_call_ops,
1064 },
1065};
1066
1067static int tegra30_soc_set_bias_level(struct snd_soc_card *card,
1068 enum snd_soc_bias_level level)
1069{
1070 struct tegra_max98088 *machine = snd_soc_card_get_drvdata(card);
1071
1072 if (machine->bias_level == SND_SOC_BIAS_OFF &&
1073 level != SND_SOC_BIAS_OFF)
1074 tegra_asoc_utils_clk_enable(&machine->util_data);
1075
1076 return 0;
1077}
1078
1079static int tegra30_soc_set_bias_level_post(struct snd_soc_card *card,
1080 enum snd_soc_bias_level level)
1081{
1082 struct tegra_max98088 *machine = snd_soc_card_get_drvdata(card);
1083
1084 if (machine->bias_level != SND_SOC_BIAS_OFF &&
1085 level == SND_SOC_BIAS_OFF)
1086 tegra_asoc_utils_clk_disable(&machine->util_data);
1087
1088 machine->bias_level = level;
1089
1090 return 0 ;
1091}
1092
1093static struct snd_soc_card snd_soc_tegra_max98088 = {
1094 .name = "tegra-max98088",
1095 .dai_link = tegra_max98088_dai,
1096 .num_links = ARRAY_SIZE(tegra_max98088_dai),
1097 .set_bias_level = tegra30_soc_set_bias_level,
1098 .set_bias_level_post = tegra30_soc_set_bias_level_post,
1099};
1100
1101static __devinit int tegra_max98088_driver_probe(struct platform_device *pdev)
1102{
1103 struct snd_soc_card *card = &snd_soc_tegra_max98088;
1104 struct tegra_max98088 *machine;
1105 struct tegra_asoc_platform_data *pdata;
1106 int ret, i;
1107
1108 pdata = pdev->dev.platform_data;
1109 if (!pdata) {
1110 dev_err(&pdev->dev, "No platform data supplied\n");
1111 return -EINVAL;
1112 }
1113
1114 machine = kzalloc(sizeof(struct tegra_max98088), GFP_KERNEL);
1115 if (!machine) {
1116 dev_err(&pdev->dev, "Can't allocate tegra_max98088 struct\n");
1117 return -ENOMEM;
1118 }
1119
1120 machine->pdata = pdata;
1121
1122 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
1123 if (ret)
1124 goto err_free_machine;
1125
1126 card->dev = &pdev->dev;
1127 platform_set_drvdata(pdev, card);
1128 snd_soc_card_set_drvdata(card, machine);
1129
1130#ifdef CONFIG_SWITCH
1131 /* Add h2w switch class support */
1132 ret = switch_dev_register(&wired_switch_dev);
1133 if (ret < 0) {
1134 dev_err(&pdev->dev, "not able to register switch device\n");
1135 goto err_fini_utils;
1136 }
1137#endif
1138
1139#ifndef CONFIG_ARCH_TEGRA_2x_SOC
1140 for (i = 0; i < NUM_I2S_DEVICES ; i++)
1141 machine->codec_info[i].i2s_id = pdata->audio_port_id[i];
1142
1143 machine->codec_info[BASEBAND].rate = pdata->baseband_param.rate;
1144 machine->codec_info[BASEBAND].channels = pdata->baseband_param.channels;
1145
1146 tegra_max98088_dai[DAI_LINK_HIFI].cpu_dai_name =
1147 tegra_max98088_i2s_dai_name[machine->codec_info[HIFI_CODEC].i2s_id];
1148
1149 tegra_max98088_dai[DAI_LINK_BTSCO].cpu_dai_name =
1150 tegra_max98088_i2s_dai_name[machine->codec_info[BT_SCO].i2s_id];
1151#endif
1152
1153 ret = snd_soc_register_card(card);
1154 if (ret) {
1155 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
1156 ret);
1157 goto err_switch_unregister;
1158 }
1159
1160 if (!card->instantiated) {
1161 dev_err(&pdev->dev, "No MAX98088 codec\n");
1162 goto err_unregister_card;
1163 }
1164
1165 return 0;
1166
1167err_unregister_card:
1168 snd_soc_unregister_card(card);
1169err_switch_unregister:
1170#ifdef CONFIG_SWITCH
1171 switch_dev_unregister(&wired_switch_dev);
1172#endif
1173err_fini_utils:
1174 tegra_asoc_utils_fini(&machine->util_data);
1175err_free_machine:
1176 kfree(machine);
1177 return ret;
1178}
1179
1180static int __devexit tegra_max98088_driver_remove(struct platform_device *pdev)
1181{
1182 struct snd_soc_card *card = platform_get_drvdata(pdev);
1183 struct tegra_max98088 *machine = snd_soc_card_get_drvdata(card);
1184 struct tegra_asoc_platform_data *pdata = machine->pdata;
1185
1186 snd_soc_unregister_card(card);
1187
1188#ifdef CONFIG_SWITCH
1189 switch_dev_unregister(&wired_switch_dev);
1190#endif
1191
1192 tegra_asoc_utils_fini(&machine->util_data);
1193
1194 if (machine->gpio_requested & GPIO_EXT_MIC_EN)
1195 gpio_free(pdata->gpio_ext_mic_en);
1196 if (machine->gpio_requested & GPIO_INT_MIC_EN)
1197 gpio_free(pdata->gpio_int_mic_en);
1198 if (machine->gpio_requested & GPIO_HP_MUTE)
1199 gpio_free(pdata->gpio_hp_mute);
1200 if (machine->gpio_requested & GPIO_SPKR_EN)
1201 gpio_free(pdata->gpio_spkr_en);
1202
1203 kfree(machine);
1204
1205 return 0;
1206}
1207
1208static struct platform_driver tegra_max98088_driver = {
1209 .driver = {
1210 .name = DRV_NAME,
1211 .owner = THIS_MODULE,
1212 .pm = &snd_soc_pm_ops,
1213 },
1214 .probe = tegra_max98088_driver_probe,
1215 .remove = __devexit_p(tegra_max98088_driver_remove),
1216};
1217
1218static int __init tegra_max98088_modinit(void)
1219{
1220 return platform_driver_register(&tegra_max98088_driver);
1221}
1222module_init(tegra_max98088_modinit);
1223
1224static void __exit tegra_max98088_modexit(void)
1225{
1226 platform_driver_unregister(&tegra_max98088_driver);
1227}
1228module_exit(tegra_max98088_modexit);
1229
1230MODULE_AUTHOR("Sumit Bhattacharya <sumitb@nvidia.com>");
1231MODULE_DESCRIPTION("Tegra+MAX98088 machine ASoC driver");
1232MODULE_LICENSE("GPL");
1233MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_max98095.c b/sound/soc/tegra/tegra_max98095.c
new file mode 100644
index 00000000000..2104ba849cd
--- /dev/null
+++ b/sound/soc/tegra/tegra_max98095.c
@@ -0,0 +1,723 @@
1/*
2 * tegra_max98095.c - Tegra machine ASoC driver for boards using MAX98095 codec.
3 *
4 * Author: Ravindra Lokhande <rlokhande@nvidia.com>
5 * Copyright (C) 2012 - NVIDIA, Inc.
6 *
7 * Based on version from Sumit Bhattacharya <sumitb@nvidia.com>
8 *
9 * Based on code copyright/by:
10 *
11 * (c) 2010, 2011, 2012 Nvidia Graphics Pvt. Ltd.
12 *
13 * Copyright 2007 Wolfson Microelectronics PLC.
14 * Author: Graeme Gregory
15 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
16 *
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * version 2 as published by the Free Software Foundation.
20 *
21 * This program is distributed in the hope that it will be useful, but
22 * WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
29 * 02110-1301 USA
30 *
31 */
32
33#include <asm/mach-types.h>
34
35#include <linux/module.h>
36#include <linux/platform_device.h>
37#include <linux/slab.h>
38#include <linux/gpio.h>
39#include <linux/regulator/consumer.h>
40#ifdef CONFIG_SWITCH
41#include <linux/switch.h>
42#endif
43
44#include <mach/tegra_asoc_pdata.h>
45
46#include <sound/core.h>
47#include <sound/jack.h>
48#include <sound/pcm.h>
49#include <sound/pcm_params.h>
50#include <sound/soc.h>
51
52#include "../codecs/max98095.h"
53
54#include "tegra_pcm.h"
55#include "tegra_asoc_utils.h"
56#ifndef CONFIG_ARCH_TEGRA_2x_SOC
57#include "tegra30_ahub.h"
58#include "tegra30_i2s.h"
59#include "tegra30_dam.h"
60#endif
61
62#define DRV_NAME "tegra-snd-max98095"
63
64#define GPIO_SPKR_EN BIT(0)
65#define GPIO_HP_MUTE BIT(1)
66#define GPIO_INT_MIC_EN BIT(2)
67#define GPIO_EXT_MIC_EN BIT(3)
68
69#ifndef CONFIG_ARCH_TEGRA_2x_SOC
70const char *tegra_max98095_i2s_dai_name[TEGRA30_NR_I2S_IFC] = {
71 "tegra30-i2s.0",
72 "tegra30-i2s.1",
73 "tegra30-i2s.2",
74 "tegra30-i2s.3",
75 "tegra30-i2s.4",
76};
77#endif
78
79struct tegra_max98095 {
80 struct tegra_asoc_utils_data util_data;
81 struct tegra_asoc_platform_data *pdata;
82 int gpio_requested;
83 bool init_done;
84 int is_call_mode;
85 int is_device_bt;
86#ifndef CONFIG_ARCH_TEGRA_2x_SOC
87 struct codec_config codec_info[NUM_I2S_DEVICES];
88#endif
89 enum snd_soc_bias_level bias_level;
90};
91
92
93#ifndef CONFIG_ARCH_TEGRA_2x_SOC
94static int tegra_max98095_set_dam_cif(int dam_ifc, int srate,
95 int channels, int bit_size)
96{
97 tegra30_dam_set_samplerate(dam_ifc, TEGRA30_DAM_CHOUT,
98 srate);
99 tegra30_dam_set_samplerate(dam_ifc, TEGRA30_DAM_CHIN1,
100 srate);
101 tegra30_dam_set_acif(dam_ifc, TEGRA30_DAM_CHIN1,
102 channels, bit_size, channels,
103 bit_size);
104 tegra30_dam_set_acif(dam_ifc, TEGRA30_DAM_CHOUT,
105 channels, bit_size, channels,
106 bit_size);
107
108 return 0;
109}
110#endif
111
112static int tegra_max98095_hw_params(struct snd_pcm_substream *substream,
113 struct snd_pcm_hw_params *params)
114{
115 struct snd_soc_pcm_runtime *rtd = substream->private_data;
116 struct snd_soc_dai *codec_dai = rtd->codec_dai;
117 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
118 struct snd_soc_codec *codec = rtd->codec;
119 struct snd_soc_card *card = codec->card;
120 struct tegra_max98095 *machine = snd_soc_card_get_drvdata(card);
121#ifndef CONFIG_ARCH_TEGRA_2x_SOC
122 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai);
123#endif
124 unsigned int srate, mclk, sample_size;
125 int err;
126
127 switch (params_format(params)) {
128 case SNDRV_PCM_FORMAT_S16_LE:
129 sample_size = 16;
130 break;
131 default:
132 return -EINVAL;
133 }
134
135 srate = params_rate(params);
136 switch (srate) {
137 case 8000:
138 case 16000:
139 case 24000:
140 case 32000:
141 case 48000:
142 case 64000:
143 case 96000:
144 mclk = 12288000;
145 break;
146 case 11025:
147 case 22050:
148 case 44100:
149 case 88200:
150 mclk = 11289600;
151 break;
152 default:
153 mclk = 12000000;
154 break;
155 }
156
157 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
158 if (err < 0) {
159 if (!(machine->util_data.set_mclk % mclk))
160 mclk = machine->util_data.set_mclk;
161 else {
162 dev_err(card->dev, "Can't configure clocks\n");
163 return err;
164 }
165 }
166
167 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
168
169 err = snd_soc_dai_set_fmt(codec_dai,
170 SND_SOC_DAIFMT_I2S |
171 SND_SOC_DAIFMT_NB_NF |
172 SND_SOC_DAIFMT_CBS_CFS);
173 if (err < 0) {
174 dev_err(card->dev, "codec_dai fmt not set\n");
175 return err;
176 }
177
178 err = snd_soc_dai_set_fmt(cpu_dai,
179 SND_SOC_DAIFMT_I2S |
180 SND_SOC_DAIFMT_NB_NF |
181 SND_SOC_DAIFMT_CBS_CFS);
182 if (err < 0) {
183 dev_err(card->dev, "cpu_dai fmt not set\n");
184 return err;
185 }
186
187 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
188 SND_SOC_CLOCK_IN);
189 if (err < 0) {
190 dev_err(card->dev, "codec_dai clock not set\n");
191 return err;
192 }
193
194#ifndef CONFIG_ARCH_TEGRA_2x_SOC
195 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
196 tegra_max98095_set_dam_cif(i2s->dam_ifc, srate,
197 params_channels(params), sample_size);
198#endif
199
200 return 0;
201}
202
203static int tegra_spdif_hw_params(struct snd_pcm_substream *substream,
204 struct snd_pcm_hw_params *params)
205{
206 struct snd_soc_pcm_runtime *rtd = substream->private_data;
207 struct snd_soc_card *card = rtd->card;
208 struct tegra_max98095 *machine = snd_soc_card_get_drvdata(card);
209 unsigned int srate, mclk, min_mclk;
210 int err;
211
212 srate = params_rate(params);
213 switch (srate) {
214 case 11025:
215 case 22050:
216 case 44100:
217 case 88200:
218 mclk = 11289600;
219 break;
220 case 8000:
221 case 16000:
222 case 32000:
223 case 48000:
224 case 64000:
225 case 96000:
226 mclk = 12288000;
227 break;
228 default:
229 return -EINVAL;
230 }
231 min_mclk = 128 * srate;
232
233 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
234 if (err < 0) {
235 if (!(machine->util_data.set_mclk % min_mclk))
236 mclk = machine->util_data.set_mclk;
237 else {
238 dev_err(card->dev, "Can't configure clocks\n");
239 return err;
240 }
241 }
242
243 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
244
245
246
247 return 0;
248}
249
250static int tegra_hw_free(struct snd_pcm_substream *substream)
251{
252 struct snd_soc_pcm_runtime *rtd = substream->private_data;
253 struct tegra_max98095 *machine = snd_soc_card_get_drvdata(rtd->card);
254
255 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 0);
256
257 return 0;
258}
259
260#ifndef CONFIG_ARCH_TEGRA_2x_SOC
261static int tegra_max98095_startup(struct snd_pcm_substream *substream)
262{
263 struct snd_soc_pcm_runtime *rtd = substream->private_data;
264 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
265 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai);
266
267 if ((substream->stream != SNDRV_PCM_STREAM_PLAYBACK) ||
268 !(i2s->is_dam_used))
269 return 0;
270
271 /*dam configuration*/
272 if (!i2s->dam_ch_refcount)
273 i2s->dam_ifc = tegra30_dam_allocate_controller();
274
275 tegra30_dam_allocate_channel(i2s->dam_ifc, TEGRA30_DAM_CHIN1);
276 i2s->dam_ch_refcount++;
277 tegra30_dam_enable_clock(i2s->dam_ifc);
278 tegra30_dam_set_gain(i2s->dam_ifc, TEGRA30_DAM_CHIN1, 0x1000);
279
280 tegra30_ahub_set_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX1 +
281 (i2s->dam_ifc*2), i2s->txcif);
282
283 /*
284 *make the dam tx to i2s rx connection if this is the only client
285 *using i2s for playback
286 */
287 if (i2s->playback_ref_count == 1)
288 tegra30_ahub_set_rx_cif_source(
289 TEGRA30_AHUB_RXCIF_I2S0_RX0 + i2s->id,
290 TEGRA30_AHUB_TXCIF_DAM0_TX0 + i2s->dam_ifc);
291
292 /* enable the dam*/
293 tegra30_dam_enable(i2s->dam_ifc, TEGRA30_DAM_ENABLE,
294 TEGRA30_DAM_CHIN1);
295
296 return 0;
297}
298
299static void tegra_max98095_shutdown(struct snd_pcm_substream *substream)
300{
301 struct snd_soc_pcm_runtime *rtd = substream->private_data;
302 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
303 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(cpu_dai);
304
305 if ((substream->stream != SNDRV_PCM_STREAM_PLAYBACK) ||
306 !(i2s->is_dam_used))
307 return;
308
309 /* disable the dam*/
310 tegra30_dam_enable(i2s->dam_ifc, TEGRA30_DAM_DISABLE,
311 TEGRA30_DAM_CHIN1);
312
313 /* disconnect the ahub connections*/
314 tegra30_ahub_unset_rx_cif_source(TEGRA30_AHUB_RXCIF_DAM0_RX1 +
315 (i2s->dam_ifc*2));
316
317 /* disable the dam and free the controller */
318 tegra30_dam_disable_clock(i2s->dam_ifc);
319 tegra30_dam_free_channel(i2s->dam_ifc, TEGRA30_DAM_CHIN1);
320 i2s->dam_ch_refcount--;
321 if (!i2s->dam_ch_refcount)
322 tegra30_dam_free_controller(i2s->dam_ifc);
323
324 return;
325}
326#endif
327
328static struct snd_soc_ops tegra_max98095_ops = {
329 .hw_params = tegra_max98095_hw_params,
330 .hw_free = tegra_hw_free,
331#ifndef CONFIG_ARCH_TEGRA_2x_SOC
332 .startup = tegra_max98095_startup,
333 .shutdown = tegra_max98095_shutdown,
334#endif
335};
336
337static struct snd_soc_ops tegra_spdif_ops = {
338 .hw_params = tegra_spdif_hw_params,
339 .hw_free = tegra_hw_free,
340};
341
342static struct snd_soc_jack tegra_max98095_hp_jack;
343
344#ifdef CONFIG_SWITCH
345static struct switch_dev wired_switch_dev = {
346 .name = "h2w",
347};
348
349/* These values are copied from WiredAccessoryObserver */
350enum headset_state {
351 BIT_NO_HEADSET = 0,
352 BIT_HEADSET = (1 << 0),
353 BIT_HEADSET_NO_MIC = (1 << 1),
354};
355
356static int headset_switch_notify(struct notifier_block *self,
357 unsigned long action, void *dev)
358{
359 int state = 0;
360
361 switch (action) {
362 case SND_JACK_HEADPHONE:
363 state |= BIT_HEADSET_NO_MIC;
364 break;
365 case SND_JACK_HEADSET:
366 state |= BIT_HEADSET;
367 break;
368 default:
369 state |= BIT_NO_HEADSET;
370 }
371
372 switch_set_state(&wired_switch_dev, state);
373
374 return NOTIFY_OK;
375}
376
377static struct notifier_block headset_switch_nb = {
378 .notifier_call = headset_switch_notify,
379};
380#else
381static struct snd_soc_jack_pin tegra_max98095_hp_jack_pins[] = {
382 {
383 .pin = "Headphone Jack",
384 .mask = SND_JACK_HEADPHONE,
385 },
386};
387#endif
388
389static int tegra_max98095_event_int_spk(struct snd_soc_dapm_widget *w,
390 struct snd_kcontrol *k, int event)
391{
392 struct snd_soc_dapm_context *dapm = w->dapm;
393 struct snd_soc_card *card = dapm->card;
394 struct tegra_max98095 *machine = snd_soc_card_get_drvdata(card);
395 struct tegra_asoc_platform_data *pdata = machine->pdata;
396
397 if (!(machine->gpio_requested & GPIO_SPKR_EN))
398 return 0;
399
400 gpio_set_value_cansleep(pdata->gpio_spkr_en,
401 SND_SOC_DAPM_EVENT_ON(event));
402
403 return 0;
404}
405
406static int tegra_max98095_event_hp(struct snd_soc_dapm_widget *w,
407 struct snd_kcontrol *k, int event)
408{
409 struct snd_soc_dapm_context *dapm = w->dapm;
410 struct snd_soc_card *card = dapm->card;
411 struct tegra_max98095 *machine = snd_soc_card_get_drvdata(card);
412 struct tegra_asoc_platform_data *pdata = machine->pdata;
413
414 if (!(machine->gpio_requested & GPIO_HP_MUTE))
415 return 0;
416
417 gpio_set_value_cansleep(pdata->gpio_hp_mute,
418 !SND_SOC_DAPM_EVENT_ON(event));
419
420 return 0;
421}
422
423static const struct snd_soc_dapm_widget tegra_max98095_dapm_widgets[] = {
424 SND_SOC_DAPM_SPK("Int Spk", tegra_max98095_event_int_spk),
425 SND_SOC_DAPM_HP("Headphone Jack", tegra_max98095_event_hp),
426 SND_SOC_DAPM_MIC("Mic Jack", NULL),
427 SND_SOC_DAPM_INPUT("Int Mic"),
428 SND_SOC_DAPM_LINE("Line In", NULL),
429};
430
431static const struct snd_soc_dapm_route enterprise_audio_map[] = {
432 {"Int Spk", NULL, "SPKL"},
433 {"Int Spk", NULL, "SPKR"},
434 {"Headphone Jack", NULL, "HPL"},
435 {"Headphone Jack", NULL, "HPR"},
436 {"MICBIAS2", NULL, "Mic Jack"},
437 {"MIC2", NULL, "MICBIAS2"},
438 {"MIC1", NULL, "Int Mic"},
439 {"MIC1", NULL, "MICBIAS1"},
440 {"INB1", NULL, "Line In"},
441 {"INB2", NULL, "Line In"},
442};
443
444static const struct snd_kcontrol_new tegra_max98095_controls[] = {
445 SOC_DAPM_PIN_SWITCH("Int Spk"),
446 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
447 SOC_DAPM_PIN_SWITCH("Mic Jack"),
448 SOC_DAPM_PIN_SWITCH("Int Mic"),
449 SOC_DAPM_PIN_SWITCH("LineIn"),
450};
451
452static int tegra_max98095_init(struct snd_soc_pcm_runtime *rtd)
453{
454 struct snd_soc_codec *codec = rtd->codec;
455 struct snd_soc_dapm_context *dapm = &codec->dapm;
456 struct snd_soc_card *card = codec->card;
457 struct tegra_max98095 *machine = snd_soc_card_get_drvdata(card);
458 struct tegra_asoc_platform_data *pdata = machine->pdata;
459#ifndef CONFIG_ARCH_TEGRA_2x_SOC
460 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(rtd->cpu_dai);
461#endif
462 int ret;
463
464#ifndef CONFIG_ARCH_TEGRA_2x_SOC
465 if (machine->codec_info[BASEBAND].i2s_id != -1)
466 i2s->is_dam_used = true;
467#endif
468
469 if (machine->init_done)
470 return 0;
471
472 machine->init_done = true;
473
474 if (gpio_is_valid(pdata->gpio_spkr_en)) {
475 ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
476 if (ret) {
477 dev_err(card->dev, "cannot get spkr_en gpio\n");
478 return ret;
479 }
480 machine->gpio_requested |= GPIO_SPKR_EN;
481
482 gpio_direction_output(pdata->gpio_spkr_en, 0);
483 }
484
485 if (gpio_is_valid(pdata->gpio_hp_mute)) {
486 ret = gpio_request(pdata->gpio_hp_mute, "hp_mute");
487 if (ret) {
488 dev_err(card->dev, "cannot get hp_mute gpio\n");
489 return ret;
490 }
491 machine->gpio_requested |= GPIO_HP_MUTE;
492
493 gpio_direction_output(pdata->gpio_hp_mute, 0);
494 }
495
496 if (gpio_is_valid(pdata->gpio_int_mic_en)) {
497 ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
498 if (ret) {
499 dev_err(card->dev, "cannot get int_mic_en gpio\n");
500 return ret;
501 }
502 machine->gpio_requested |= GPIO_INT_MIC_EN;
503
504 /* Disable int mic; enable signal is active-high */
505 gpio_direction_output(pdata->gpio_int_mic_en, 0);
506 }
507
508 if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
509 ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
510 if (ret) {
511 dev_err(card->dev, "cannot get ext_mic_en gpio\n");
512 return ret;
513 }
514 machine->gpio_requested |= GPIO_EXT_MIC_EN;
515
516 /* Enable ext mic; enable signal is active-low */
517 gpio_direction_output(pdata->gpio_ext_mic_en, 0);
518 }
519
520 ret = snd_soc_add_controls(codec, tegra_max98095_controls,
521 ARRAY_SIZE(tegra_max98095_controls));
522 if (ret < 0)
523 return ret;
524
525 snd_soc_dapm_new_controls(dapm, tegra_max98095_dapm_widgets,
526 ARRAY_SIZE(tegra_max98095_dapm_widgets));
527
528 snd_soc_dapm_add_routes(dapm, enterprise_audio_map,
529 ARRAY_SIZE(enterprise_audio_map));
530
531 ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
532 &tegra_max98095_hp_jack);
533 if (ret < 0)
534 return ret;
535
536#ifdef CONFIG_SWITCH
537 snd_soc_jack_notifier_register(&tegra_max98095_hp_jack,
538 &headset_switch_nb);
539#else /*gpio based headset detection*/
540 snd_soc_jack_add_pins(&tegra_max98095_hp_jack,
541 ARRAY_SIZE(tegra_max98095_hp_jack_pins),
542 tegra_max98095_hp_jack_pins);
543#endif
544
545 /* max98095_headset_detect(codec, &tegra_max98095_hp_jack,
546 SND_JACK_HEADSET); */
547
548 snd_soc_dapm_nc_pin(dapm, "INA1");
549 snd_soc_dapm_nc_pin(dapm, "INA2");
550 snd_soc_dapm_nc_pin(dapm, "INB1");
551 snd_soc_dapm_nc_pin(dapm, "INB2");
552 snd_soc_dapm_sync(dapm);
553
554 return 0;
555}
556
557static struct snd_soc_dai_link tegra_max98095_dai[] = {
558 {
559 .name = "MAX98095",
560 .stream_name = "MAX98095 HIFI",
561 .codec_name = "max98095.4-0010",
562 .platform_name = "tegra-pcm-audio",
563 .cpu_dai_name = "tegra30-i2s.1",
564 .codec_dai_name = "HiFi",
565 .init = tegra_max98095_init,
566 .ops = &tegra_max98095_ops,
567 },
568 {
569 .name = "SPDIF",
570 .stream_name = "SPDIF PCM",
571 .codec_name = "spdif-dit.0",
572 .platform_name = "tegra-pcm-audio",
573 .cpu_dai_name = "tegra30-spdif",
574 .codec_dai_name = "dit-hifi",
575 .ops = &tegra_spdif_ops,
576 },
577};
578
579static int tegra30_soc_set_bias_level(struct snd_soc_card *card,
580 enum snd_soc_bias_level level)
581{
582 struct tegra_max98095 *machine = snd_soc_card_get_drvdata(card);
583
584 if (machine->bias_level == SND_SOC_BIAS_OFF &&
585 level != SND_SOC_BIAS_OFF)
586 tegra_asoc_utils_clk_enable(&machine->util_data);
587
588 machine->bias_level = level;
589
590 return 0;
591}
592
593static int tegra30_soc_set_bias_level_post(struct snd_soc_card *card,
594 enum snd_soc_bias_level level)
595{
596 struct tegra_max98095 *machine = snd_soc_card_get_drvdata(card);
597
598 if (level == SND_SOC_BIAS_OFF)
599 tegra_asoc_utils_clk_disable(&machine->util_data);
600
601 return 0 ;
602}
603
604static struct snd_soc_card snd_soc_tegra_max98095 = {
605 .name = "tegra-max98095",
606 .dai_link = tegra_max98095_dai,
607 .num_links = ARRAY_SIZE(tegra_max98095_dai),
608 .set_bias_level = tegra30_soc_set_bias_level,
609 .set_bias_level_post = tegra30_soc_set_bias_level_post,
610};
611
612static __devinit int tegra_max98095_driver_probe(struct platform_device *pdev)
613{
614 struct snd_soc_card *card = &snd_soc_tegra_max98095;
615 struct tegra_max98095 *machine;
616 struct tegra_asoc_platform_data *pdata;
617 int ret;
618
619 pdata = pdev->dev.platform_data;
620 if (!pdata) {
621 dev_err(&pdev->dev, "No platform data supplied\n");
622 return -EINVAL;
623 }
624
625 machine = kzalloc(sizeof(struct tegra_max98095), GFP_KERNEL);
626 if (!machine) {
627 dev_err(&pdev->dev, "Can't allocate tegra_max98095 struct\n");
628 return -ENOMEM;
629 }
630
631 machine->pdata = pdata;
632
633 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
634 if (ret)
635 goto err_free_machine;
636
637 card->dev = &pdev->dev;
638 platform_set_drvdata(pdev, card);
639 snd_soc_card_set_drvdata(card, machine);
640
641#ifdef CONFIG_SWITCH
642 /* Add h2w switch class support */
643 ret = switch_dev_register(&wired_switch_dev);
644 if (ret < 0) {
645 dev_err(&pdev->dev, "not able to register switch device\n");
646 goto err_fini_utils;
647 }
648#endif
649
650 ret = snd_soc_register_card(card);
651 if (ret) {
652 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
653 ret);
654 goto err_switch_unregister;
655 }
656
657 return 0;
658
659err_switch_unregister:
660#ifdef CONFIG_SWITCH
661 switch_dev_unregister(&wired_switch_dev);
662#endif
663err_fini_utils:
664 tegra_asoc_utils_fini(&machine->util_data);
665err_free_machine:
666 kfree(machine);
667 return ret;
668}
669
670static int __devexit tegra_max98095_driver_remove(struct platform_device *pdev)
671{
672 struct snd_soc_card *card = platform_get_drvdata(pdev);
673 struct tegra_max98095 *machine = snd_soc_card_get_drvdata(card);
674 struct tegra_asoc_platform_data *pdata = machine->pdata;
675
676 snd_soc_unregister_card(card);
677
678#ifdef CONFIG_SWITCH
679 switch_dev_unregister(&wired_switch_dev);
680#endif
681
682 tegra_asoc_utils_fini(&machine->util_data);
683
684 if (machine->gpio_requested & GPIO_EXT_MIC_EN)
685 gpio_free(pdata->gpio_ext_mic_en);
686 if (machine->gpio_requested & GPIO_INT_MIC_EN)
687 gpio_free(pdata->gpio_int_mic_en);
688 if (machine->gpio_requested & GPIO_HP_MUTE)
689 gpio_free(pdata->gpio_hp_mute);
690 if (machine->gpio_requested & GPIO_SPKR_EN)
691 gpio_free(pdata->gpio_spkr_en);
692
693 kfree(machine);
694
695 return 0;
696}
697
698static struct platform_driver tegra_max98095_driver = {
699 .driver = {
700 .name = DRV_NAME,
701 .owner = THIS_MODULE,
702 .pm = &snd_soc_pm_ops,
703 },
704 .probe = tegra_max98095_driver_probe,
705 .remove = __devexit_p(tegra_max98095_driver_remove),
706};
707
708static int __init tegra_max98095_modinit(void)
709{
710 return platform_driver_register(&tegra_max98095_driver);
711}
712module_init(tegra_max98095_modinit);
713
714static void __exit tegra_max98095_modexit(void)
715{
716 platform_driver_unregister(&tegra_max98095_driver);
717}
718module_exit(tegra_max98095_modexit);
719
720MODULE_AUTHOR("Ravindra Lokhande <rlokhande@nvidia.com>");
721MODULE_DESCRIPTION("Tegra+MAX98095 machine ASoC driver");
722MODULE_LICENSE("GPL");
723MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_p1852.c b/sound/soc/tegra/tegra_p1852.c
new file mode 100644
index 00000000000..27a1ea59034
--- /dev/null
+++ b/sound/soc/tegra/tegra_p1852.c
@@ -0,0 +1,272 @@
1/*
2 * tegra_p1852.c - Tegra machine ASoC driver for P1852 Boards.
3 *
4 * Author: Nitin Pai <npai@nvidia.com>
5 * Copyright (C) 2010-2012 - NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 * Copyright (c) 2009-2010, NVIDIA Corporation.
9 * Stephen Warren <swarren@nvidia.com>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 *
25 */
26
27#include <asm/mach-types.h>
28
29#include <linux/clk.h>
30#include <linux/module.h>
31#include <linux/platform_device.h>
32#include <linux/slab.h>
33
34#include <mach/tegra_p1852_pdata.h>
35
36#include <sound/core.h>
37#include <sound/pcm.h>
38#include <sound/pcm_params.h>
39#include <sound/soc.h>
40
41#include "tegra_pcm.h"
42#include "tegra_asoc_utils.h"
43
44#define DRV_NAME "tegra-snd-p1852"
45
46struct tegra_p1852 {
47 struct tegra_asoc_utils_data util_data;
48 struct tegra_p1852_platform_data *pdata;
49};
50
51static int tegra_p1852_hw_params(struct snd_pcm_substream *substream,
52 struct snd_pcm_hw_params *params)
53{
54 struct snd_soc_pcm_runtime *rtd = substream->private_data;
55 struct snd_soc_dai *codec_dai = rtd->codec_dai;
56 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
57 struct snd_soc_codec *codec = rtd->codec;
58 struct snd_soc_card *card = codec->card;
59 struct tegra_p1852 *machine = snd_soc_card_get_drvdata(card);
60 int srate, mclk;
61 int i2s_daifmt = 0;
62 int err;
63 struct tegra_p1852_platform_data *pdata;
64 int codec_id = codec_dai->id;
65
66 pdata = machine->pdata;
67
68 srate = params_rate(params);
69 switch (srate) {
70 case 64000:
71 case 88200:
72 case 96000:
73 mclk = 128 * srate;
74 break;
75 default:
76 mclk = 256 * srate;
77 break;
78 }
79
80 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
81 if (err < 0) {
82 if (!(machine->util_data.set_mclk % mclk))
83 mclk = machine->util_data.set_mclk;
84 else {
85 dev_err(card->dev, "Can't configure clocks\n");
86 return err;
87 }
88 }
89
90 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
91
92 if (pdata->codec_info[codec_id].master)
93 i2s_daifmt |= SND_SOC_DAIFMT_CBM_CFM;
94 else
95 i2s_daifmt |= SND_SOC_DAIFMT_CBS_CFS;
96
97 switch (pdata->codec_info[codec_id].i2s_format) {
98 case format_tdm:
99 i2s_daifmt |= SND_SOC_DAIFMT_DSP_A;
100 break;
101 case format_i2s:
102 i2s_daifmt |= SND_SOC_DAIFMT_I2S;
103 break;
104 case format_rjm:
105 i2s_daifmt |= SND_SOC_DAIFMT_RIGHT_J;
106 break;
107 case format_ljm:
108 i2s_daifmt |= SND_SOC_DAIFMT_LEFT_J;
109 break;
110 default:
111 break;
112 }
113
114 err = snd_soc_dai_set_fmt(codec_dai, i2s_daifmt);
115 if (err < 0)
116 dev_info(card->dev, "codec_dai fmt not set\n");
117
118 err = snd_soc_dai_set_fmt(cpu_dai, i2s_daifmt);
119 if (err < 0) {
120 dev_err(card->dev, "cpu_dai fmt not set\n");
121 return err;
122 }
123
124 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
125 SND_SOC_CLOCK_IN);
126 if (err < 0)
127 dev_info(card->dev, "codec_dai clock not set\n");
128
129 return 0;
130}
131
132static int tegra_hw_free(struct snd_pcm_substream *substream)
133{
134 struct snd_soc_pcm_runtime *rtd = substream->private_data;
135 struct tegra_p1852 *machine = snd_soc_card_get_drvdata(rtd->card);
136
137 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 0);
138
139 return 0;
140}
141
142static struct snd_soc_ops tegra_p1852_ops = {
143 .hw_params = tegra_p1852_hw_params,
144 .hw_free = tegra_hw_free,
145};
146
147static struct snd_soc_dai_link tegra_p1852_dai_link[] = {
148 {
149 .name = "I2S-TDM-1",
150 .stream_name = "TEGRA PCM",
151 .platform_name = "tegra-pcm-audio",
152 .ops = &tegra_p1852_ops,
153 },
154 {
155 .name = "I2S-TDM-2",
156 .stream_name = "TEGRA PCM",
157 .platform_name = "tegra-pcm-audio",
158 .ops = &tegra_p1852_ops,
159 }
160};
161
162static struct snd_soc_card snd_soc_tegra_p1852 = {
163 .name = "tegra-p1852",
164 .dai_link = tegra_p1852_dai_link,
165 .num_links = ARRAY_SIZE(tegra_p1852_dai_link),
166};
167
168static __devinit int tegra_p1852_driver_probe(struct platform_device *pdev)
169{
170 struct snd_soc_card *card = &snd_soc_tegra_p1852;
171 struct tegra_p1852 *machine;
172 struct tegra_p1852_platform_data *pdata;
173 int ret;
174 int i;
175
176 pdata = pdev->dev.platform_data;
177 if (!pdata) {
178 dev_err(&pdev->dev, "No platform data supplied\n");
179 return -EINVAL;
180 }
181
182 machine = kzalloc(sizeof(struct tegra_p1852), GFP_KERNEL);
183 if (!machine) {
184 dev_err(&pdev->dev, "Can't allocate tegra_p1852 struct\n");
185 return -ENOMEM;
186 }
187
188 machine->pdata = pdata;
189
190 /* The codec driver and codec dai have to come from the system
191 * level board configuration file
192 * */
193 for (i = 0; i < ARRAY_SIZE(tegra_p1852_dai_link); i++) {
194 tegra_p1852_dai_link[i].codec_name =
195 pdata->codec_info[i].codec_name;
196 tegra_p1852_dai_link[i].cpu_dai_name =
197 pdata->codec_info[i].cpu_dai_name;
198 tegra_p1852_dai_link[i].codec_dai_name =
199 pdata->codec_info[i].codec_dai_name;
200 tegra_p1852_dai_link[i].name =
201 pdata->codec_info[i].name;
202 }
203
204 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
205 if (ret)
206 goto err_free_machine;
207
208 card->dev = &pdev->dev;
209 platform_set_drvdata(pdev, card);
210 snd_soc_card_set_drvdata(card, machine);
211
212 ret = snd_soc_register_card(card);
213 if (ret) {
214 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
215 ret);
216 }
217
218 if (!card->instantiated) {
219 ret = -ENODEV;
220 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
221 ret);
222 goto err_unregister_card;
223 }
224
225 return 0;
226
227err_unregister_card:
228 snd_soc_unregister_card(card);
229 tegra_asoc_utils_fini(&machine->util_data);
230err_free_machine:
231 kfree(machine);
232 return ret;
233}
234
235static int __devexit tegra_p1852_driver_remove(struct platform_device *pdev)
236{
237 struct snd_soc_card *card = platform_get_drvdata(pdev);
238 struct tegra_p1852 *machine = snd_soc_card_get_drvdata(card);
239
240 snd_soc_unregister_card(card);
241 tegra_asoc_utils_fini(&machine->util_data);
242 kfree(machine);
243
244 return 0;
245}
246
247static struct platform_driver tegra_p1852_driver = {
248 .driver = {
249 .name = DRV_NAME,
250 .owner = THIS_MODULE,
251 .pm = &snd_soc_pm_ops,
252 },
253 .probe = tegra_p1852_driver_probe,
254 .remove = __devexit_p(tegra_p1852_driver_remove),
255};
256
257static int __init tegra_p1852_modinit(void)
258{
259 return platform_driver_register(&tegra_p1852_driver);
260}
261module_init(tegra_p1852_modinit);
262
263static void __exit tegra_p1852_modexit(void)
264{
265 platform_driver_unregister(&tegra_p1852_driver);
266}
267module_exit(tegra_p1852_modexit);
268
269MODULE_AUTHOR("Nitin Pai <npai@nvidia.com>");
270MODULE_DESCRIPTION("Tegra+P1852 machine ASoC driver");
271MODULE_LICENSE("GPL");
272MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c
new file mode 100644
index 00000000000..f6f4ed3d421
--- /dev/null
+++ b/sound/soc/tegra/tegra_rt5640.c
@@ -0,0 +1,738 @@
1/*
2 * tegra_rt5640.c - Tegra machine ASoC driver for boards using ALC5640 codec.
3 *
4 * Author: Johnny Qiu <joqiu@nvidia.com>
5 * Copyright (C) 2011-2012, NVIDIA, Inc.
6 *
7 * Based on code copyright/by:
8 *
9 * Copyright 2007 Wolfson Microelectronics PLC.
10 * Author: Graeme Gregory
11 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * version 2 as published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 *
27 */
28
29#include <asm/mach-types.h>
30
31#include <linux/module.h>
32#include <linux/platform_device.h>
33#include <linux/slab.h>
34#include <linux/gpio.h>
35#include <linux/regulator/consumer.h>
36#ifdef CONFIG_SWITCH
37#include <linux/switch.h>
38#endif
39
40#include <mach/tegra_rt5640_pdata.h>
41
42#include <sound/core.h>
43#include <sound/jack.h>
44#include <sound/pcm.h>
45#include <sound/pcm_params.h>
46#include <sound/soc.h>
47
48#include "../codecs/rt5639.h"
49#include "../codecs/rt5640.h"
50
51#include "tegra_pcm.h"
52#include "tegra_asoc_utils.h"
53
54#define DRV_NAME "tegra-snd-rt5640"
55
56#define GPIO_SPKR_EN BIT(0)
57#define GPIO_HP_MUTE BIT(1)
58#define GPIO_INT_MIC_EN BIT(2)
59#define GPIO_EXT_MIC_EN BIT(3)
60#define GPIO_HP_DET BIT(4)
61
62struct tegra_rt5640 {
63 struct tegra_asoc_utils_data util_data;
64 struct tegra_rt5640_platform_data *pdata;
65 struct regulator *spk_reg;
66 struct regulator *dmic_reg;
67 struct regulator *cdc_en;
68 int gpio_requested;
69#ifdef CONFIG_SWITCH
70 int jack_status;
71#endif
72};
73
74static int tegra_rt5640_hw_params(struct snd_pcm_substream *substream,
75 struct snd_pcm_hw_params *params)
76{
77 struct snd_soc_pcm_runtime *rtd = substream->private_data;
78 struct snd_soc_dai *codec_dai = rtd->codec_dai;
79 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
80 struct snd_soc_codec *codec = rtd->codec;
81 struct snd_soc_card *card = codec->card;
82 struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card);
83 int srate, mclk, i2s_daifmt;
84 int err;
85
86 srate = params_rate(params);
87 mclk = 256 * srate;
88 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
89 if (err < 0) {
90 if (!(machine->util_data.set_mclk % mclk)) {
91 mclk = machine->util_data.set_mclk;
92 } else {
93 dev_err(card->dev, "Can't configure clocks\n");
94 return err;
95 }
96 }
97
98 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
99
100 i2s_daifmt = SND_SOC_DAIFMT_NB_NF |
101 SND_SOC_DAIFMT_CBS_CFS;
102
103 i2s_daifmt |= SND_SOC_DAIFMT_I2S;
104
105 err = snd_soc_dai_set_fmt(codec_dai, i2s_daifmt);
106 if (err < 0) {
107 dev_err(card->dev, "codec_dai fmt not set\n");
108 return err;
109 }
110
111 err = snd_soc_dai_set_fmt(cpu_dai, i2s_daifmt);
112 if (err < 0) {
113 dev_err(card->dev, "cpu_dai fmt not set\n");
114 return err;
115 }
116
117 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
118 SND_SOC_CLOCK_IN);
119 if (err < 0) {
120 dev_err(card->dev, "codec_dai clock not set\n");
121 return err;
122 }
123
124 return 0;
125}
126
127static int tegra_bt_sco_hw_params(struct snd_pcm_substream *substream,
128 struct snd_pcm_hw_params *params)
129{
130 struct snd_soc_pcm_runtime *rtd = substream->private_data;
131 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
132 struct snd_soc_card *card = rtd->card;
133 struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card);
134 int srate, mclk, min_mclk;
135 int err;
136
137 srate = params_rate(params);
138 switch (srate) {
139 case 11025:
140 case 22050:
141 case 44100:
142 case 88200:
143 mclk = 11289600;
144 break;
145 case 8000:
146 case 16000:
147 case 32000:
148 case 48000:
149 case 64000:
150 case 96000:
151 mclk = 12288000;
152 break;
153 default:
154 return -EINVAL;
155 }
156 min_mclk = 64 * srate;
157
158 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
159 if (err < 0) {
160 if (!(machine->util_data.set_mclk % min_mclk))
161 mclk = machine->util_data.set_mclk;
162 else {
163 dev_err(card->dev, "Can't configure clocks\n");
164 return err;
165 }
166 }
167
168 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
169
170 err = snd_soc_dai_set_fmt(cpu_dai,
171 SND_SOC_DAIFMT_DSP_A |
172 SND_SOC_DAIFMT_NB_NF |
173 SND_SOC_DAIFMT_CBS_CFS);
174 if (err < 0) {
175 dev_err(card->dev, "cpu_dai fmt not set\n");
176 return err;
177 }
178
179 return 0;
180}
181
182static int tegra_spdif_hw_params(struct snd_pcm_substream *substream,
183 struct snd_pcm_hw_params *params)
184{
185 struct snd_soc_pcm_runtime *rtd = substream->private_data;
186 struct snd_soc_card *card = rtd->card;
187 struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card);
188 int srate, mclk, min_mclk;
189 int err;
190
191 srate = params_rate(params);
192 switch (srate) {
193 case 11025:
194 case 22050:
195 case 44100:
196 case 88200:
197 mclk = 11289600;
198 break;
199 case 8000:
200 case 16000:
201 case 32000:
202 case 48000:
203 case 64000:
204 case 96000:
205 mclk = 12288000;
206 break;
207 default:
208 return -EINVAL;
209 }
210 min_mclk = 128 * srate;
211
212 err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
213 if (err < 0) {
214 if (!(machine->util_data.set_mclk % min_mclk))
215 mclk = machine->util_data.set_mclk;
216 else {
217 dev_err(card->dev, "Can't configure clocks\n");
218 return err;
219 }
220 }
221
222 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 1);
223
224 return 0;
225}
226
227static int tegra_hw_free(struct snd_pcm_substream *substream)
228{
229 struct snd_soc_pcm_runtime *rtd = substream->private_data;
230 struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(rtd->card);
231
232 tegra_asoc_utils_lock_clk_rate(&machine->util_data, 0);
233
234 return 0;
235}
236
237static struct snd_soc_ops tegra_rt5640_ops = {
238 .hw_params = tegra_rt5640_hw_params,
239 .hw_free = tegra_hw_free,
240};
241
242static struct snd_soc_ops tegra_rt5640_bt_sco_ops = {
243 .hw_params = tegra_bt_sco_hw_params,
244 .hw_free = tegra_hw_free,
245};
246
247static struct snd_soc_ops tegra_spdif_ops = {
248 .hw_params = tegra_spdif_hw_params,
249 .hw_free = tegra_hw_free,
250};
251
252static struct snd_soc_jack tegra_rt5640_hp_jack;
253
254static struct snd_soc_jack_gpio tegra_rt5640_hp_jack_gpio = {
255 .name = "headphone detect",
256 .report = SND_JACK_HEADPHONE,
257 .debounce_time = 150,
258 .invert = 1,
259};
260
261#ifdef CONFIG_SWITCH
262/* These values are copied from Android WiredAccessoryObserver */
263enum headset_state {
264 BIT_NO_HEADSET = 0,
265 BIT_HEADSET = (1 << 0),
266 BIT_HEADSET_NO_MIC = (1 << 1),
267};
268
269static struct switch_dev tegra_rt5640_headset_switch = {
270 .name = "h2w",
271};
272
273static int tegra_rt5640_jack_notifier(struct notifier_block *self,
274 unsigned long action, void *dev)
275{
276 struct snd_soc_jack *jack = dev;
277 struct snd_soc_codec *codec = jack->codec;
278 struct snd_soc_card *card = codec->card;
279 struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card);
280 enum headset_state state = BIT_NO_HEADSET;
281 unsigned char status_jack;
282
283 if (jack == &tegra_rt5640_hp_jack) {
284 if (action) {
285 if (!strncmp(machine->pdata->codec_name, "rt5639", 6))
286 status_jack = rt5639_headset_detect(codec, 1);
287 else if (!strncmp(machine->pdata->codec_name, "rt5640",
288 6))
289 status_jack = rt5640_headset_detect(codec, 1);
290
291 machine->jack_status &= ~SND_JACK_HEADPHONE;
292 machine->jack_status &= ~SND_JACK_MICROPHONE;
293 if (status_jack == RT5639_HEADPHO_DET ||
294 status_jack == RT5640_HEADPHO_DET)
295 machine->jack_status |=
296 SND_JACK_HEADPHONE;
297 else if (status_jack == RT5639_HEADSET_DET ||
298 status_jack == RT5640_HEADSET_DET) {
299 machine->jack_status |=
300 SND_JACK_HEADPHONE;
301 machine->jack_status |=
302 SND_JACK_MICROPHONE;
303 }
304 } else {
305 if (!strncmp(machine->pdata->codec_name, "rt5639", 6))
306 rt5639_headset_detect(codec, 0);
307 else if (!strncmp(machine->pdata->codec_name, "rt5640",
308 6))
309 rt5640_headset_detect(codec, 0);
310
311 machine->jack_status &= ~SND_JACK_HEADPHONE;
312 machine->jack_status &= ~SND_JACK_MICROPHONE;
313 }
314 }
315
316 switch (machine->jack_status) {
317 case SND_JACK_HEADPHONE:
318 state = BIT_HEADSET_NO_MIC;
319 break;
320 case SND_JACK_HEADSET:
321 state = BIT_HEADSET;
322 break;
323 case SND_JACK_MICROPHONE:
324 /* mic: would not report */
325 default:
326 state = BIT_NO_HEADSET;
327 }
328
329 switch_set_state(&tegra_rt5640_headset_switch, state);
330
331 return NOTIFY_OK;
332}
333
334static struct notifier_block tegra_rt5640_jack_detect_nb = {
335 .notifier_call = tegra_rt5640_jack_notifier,
336};
337#else
338static struct snd_soc_jack_pin tegra_rt5640_hp_jack_pins[] = {
339 {
340 .pin = "Headphone Jack",
341 .mask = SND_JACK_HEADPHONE,
342 },
343};
344
345#endif
346
347static int tegra_rt5640_event_int_spk(struct snd_soc_dapm_widget *w,
348 struct snd_kcontrol *k, int event)
349{
350 struct snd_soc_dapm_context *dapm = w->dapm;
351 struct snd_soc_card *card = dapm->card;
352 struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card);
353 struct tegra_rt5640_platform_data *pdata = machine->pdata;
354
355 if (machine->spk_reg) {
356 if (SND_SOC_DAPM_EVENT_ON(event))
357 regulator_enable(machine->spk_reg);
358 else
359 regulator_disable(machine->spk_reg);
360 }
361
362 if (!(machine->gpio_requested & GPIO_SPKR_EN))
363 return 0;
364
365 gpio_set_value_cansleep(pdata->gpio_spkr_en,
366 SND_SOC_DAPM_EVENT_ON(event));
367
368 return 0;
369}
370
371static int tegra_rt5640_event_hp(struct snd_soc_dapm_widget *w,
372 struct snd_kcontrol *k, int event)
373{
374 struct snd_soc_dapm_context *dapm = w->dapm;
375 struct snd_soc_card *card = dapm->card;
376 struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card);
377 struct tegra_rt5640_platform_data *pdata = machine->pdata;
378
379 if (!(machine->gpio_requested & GPIO_HP_MUTE))
380 return 0;
381
382 gpio_set_value_cansleep(pdata->gpio_hp_mute,
383 !SND_SOC_DAPM_EVENT_ON(event));
384
385 return 0;
386}
387
388static int tegra_rt5640_event_int_mic(struct snd_soc_dapm_widget *w,
389 struct snd_kcontrol *k, int event)
390{
391 struct snd_soc_dapm_context *dapm = w->dapm;
392 struct snd_soc_card *card = dapm->card;
393 struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card);
394 struct tegra_rt5640_platform_data *pdata = machine->pdata;
395
396 if (machine->dmic_reg) {
397 if (SND_SOC_DAPM_EVENT_ON(event))
398 regulator_enable(machine->dmic_reg);
399 else
400 regulator_disable(machine->dmic_reg);
401 }
402
403 if (!(machine->gpio_requested & GPIO_INT_MIC_EN))
404 return 0;
405
406 gpio_set_value_cansleep(pdata->gpio_int_mic_en,
407 SND_SOC_DAPM_EVENT_ON(event));
408
409 return 0;
410}
411
412static int tegra_rt5640_event_ext_mic(struct snd_soc_dapm_widget *w,
413 struct snd_kcontrol *k, int event)
414{
415 struct snd_soc_dapm_context *dapm = w->dapm;
416 struct snd_soc_card *card = dapm->card;
417 struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card);
418 struct tegra_rt5640_platform_data *pdata = machine->pdata;
419
420 if (!(machine->gpio_requested & GPIO_EXT_MIC_EN))
421 return 0;
422
423 gpio_set_value_cansleep(pdata->gpio_ext_mic_en,
424 !SND_SOC_DAPM_EVENT_ON(event));
425
426 return 0;
427}
428
429static const struct snd_soc_dapm_widget cardhu_dapm_widgets[] = {
430 SND_SOC_DAPM_SPK("Int Spk", tegra_rt5640_event_int_spk),
431 SND_SOC_DAPM_HP("Headphone Jack", tegra_rt5640_event_hp),
432 SND_SOC_DAPM_MIC("Mic Jack", tegra_rt5640_event_ext_mic),
433 SND_SOC_DAPM_MIC("Int Mic", tegra_rt5640_event_int_mic),
434};
435
436static const struct snd_soc_dapm_route cardhu_audio_map[] = {
437 {"Headphone Jack", NULL, "HPOR"},
438 {"Headphone Jack", NULL, "HPOL"},
439 {"Int Spk", NULL, "SPORP"},
440 {"Int Spk", NULL, "SPORN"},
441 {"Int Spk", NULL, "SPOLP"},
442 {"Int Spk", NULL, "SPOLN"},
443 {"micbias1", NULL, "Mic Jack"},
444 {"IN1P", NULL, "micbias1"},
445 {"IN1N", NULL, "micbias1"},
446 {"micbias1", NULL, "Int Mic"},
447 {"IN2P", NULL, "micbias1"},
448};
449
450static const struct snd_kcontrol_new cardhu_controls[] = {
451 SOC_DAPM_PIN_SWITCH("Int Spk"),
452 SOC_DAPM_PIN_SWITCH("Headphone Jack"),
453 SOC_DAPM_PIN_SWITCH("Mic Jack"),
454 SOC_DAPM_PIN_SWITCH("Int Mic"),
455};
456
457static int tegra_rt5640_init(struct snd_soc_pcm_runtime *rtd)
458{
459 struct snd_soc_codec *codec = rtd->codec;
460 struct snd_soc_dapm_context *dapm = &codec->dapm;
461 struct snd_soc_card *card = codec->card;
462 struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card);
463 struct tegra_rt5640_platform_data *pdata = machine->pdata;
464 int ret;
465
466 if (gpio_is_valid(pdata->gpio_spkr_en)) {
467 ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
468 if (ret) {
469 dev_err(card->dev, "cannot get spkr_en gpio\n");
470 return ret;
471 }
472 machine->gpio_requested |= GPIO_SPKR_EN;
473
474 gpio_direction_output(pdata->gpio_spkr_en, 0);
475 }
476
477 if (gpio_is_valid(pdata->gpio_hp_mute)) {
478 ret = gpio_request(pdata->gpio_hp_mute, "hp_mute");
479 if (ret) {
480 dev_err(card->dev, "cannot get hp_mute gpio\n");
481 return ret;
482 }
483 machine->gpio_requested |= GPIO_HP_MUTE;
484
485 gpio_direction_output(pdata->gpio_hp_mute, 0);
486 }
487
488 if (gpio_is_valid(pdata->gpio_int_mic_en)) {
489 ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
490 if (ret) {
491 dev_err(card->dev, "cannot get int_mic_en gpio\n");
492 return ret;
493 }
494 machine->gpio_requested |= GPIO_INT_MIC_EN;
495
496 /* Disable int mic; enable signal is active-high */
497 gpio_direction_output(pdata->gpio_int_mic_en, 0);
498 }
499
500 if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
501 ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
502 if (ret) {
503 dev_err(card->dev, "cannot get ext_mic_en gpio\n");
504 return ret;
505 }
506 machine->gpio_requested |= GPIO_EXT_MIC_EN;
507
508 /* Enable ext mic; enable signal is active-low */
509 gpio_direction_output(pdata->gpio_ext_mic_en, 0);
510 }
511
512 if (gpio_is_valid(pdata->gpio_hp_det)) {
513 tegra_rt5640_hp_jack_gpio.gpio = pdata->gpio_hp_det;
514 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
515 &tegra_rt5640_hp_jack);
516#ifndef CONFIG_SWITCH
517 snd_soc_jack_add_pins(&tegra_rt5640_hp_jack,
518 ARRAY_SIZE(tegra_rt5640_hp_jack_pins),
519 tegra_rt5640_hp_jack_pins);
520#else
521 snd_soc_jack_notifier_register(&tegra_rt5640_hp_jack,
522 &tegra_rt5640_jack_detect_nb);
523#endif
524 snd_soc_jack_add_gpios(&tegra_rt5640_hp_jack,
525 1,
526 &tegra_rt5640_hp_jack_gpio);
527 machine->gpio_requested |= GPIO_HP_DET;
528 }
529
530 ret = snd_soc_add_controls(codec, cardhu_controls,
531 ARRAY_SIZE(cardhu_controls));
532 if (ret < 0)
533 return ret;
534
535 snd_soc_dapm_new_controls(dapm, cardhu_dapm_widgets,
536 ARRAY_SIZE(cardhu_dapm_widgets));
537
538 snd_soc_dapm_add_routes(dapm, cardhu_audio_map,
539 ARRAY_SIZE(cardhu_audio_map));
540 /* FIXME: Calculate automatically based on DAPM routes? */
541 snd_soc_dapm_nc_pin(dapm, "LOUTL");
542 snd_soc_dapm_nc_pin(dapm, "LOUTR");
543
544 snd_soc_dapm_sync(dapm);
545
546 return 0;
547}
548
549static struct snd_soc_dai_link tegra_rt5640_dai[] = {
550 {
551 .name = "RT5640",
552 .stream_name = "RT5640 PCM",
553 .codec_name = "rt5640.4-001c",
554 .platform_name = "tegra-pcm-audio",
555 .cpu_dai_name = "tegra30-i2s.1",
556 .codec_dai_name = "rt5640-aif1",
557 .init = tegra_rt5640_init,
558 .ops = &tegra_rt5640_ops,
559 },
560 {
561 .name = "SPDIF",
562 .stream_name = "SPDIF PCM",
563 .codec_name = "spdif-dit.0",
564 .platform_name = "tegra-pcm-audio",
565 .cpu_dai_name = "tegra30-spdif",
566 .codec_dai_name = "dit-hifi",
567 .ops = &tegra_spdif_ops,
568 },
569 {
570 .name = "BT-SCO",
571 .stream_name = "BT SCO PCM",
572 .codec_name = "spdif-dit.1",
573 .platform_name = "tegra-pcm-audio",
574 .cpu_dai_name = "tegra30-i2s.3",
575 .codec_dai_name = "dit-hifi",
576 .ops = &tegra_rt5640_bt_sco_ops,
577 },
578};
579
580static struct snd_soc_card snd_soc_tegra_rt5640 = {
581 .name = "tegra-rt5640",
582 .dai_link = tegra_rt5640_dai,
583 .num_links = ARRAY_SIZE(tegra_rt5640_dai),
584};
585
586static __devinit int tegra_rt5640_driver_probe(struct platform_device *pdev)
587{
588 struct snd_soc_card *card = &snd_soc_tegra_rt5640;
589 struct tegra_rt5640 *machine;
590 struct tegra_rt5640_platform_data *pdata;
591 int ret;
592
593 pdata = pdev->dev.platform_data;
594 if (!pdata) {
595 dev_err(&pdev->dev, "No platform data supplied\n");
596 return -EINVAL;
597 }
598
599 if (pdata->codec_name)
600 card->dai_link->codec_name = pdata->codec_name;
601 if (pdata->codec_dai_name)
602 card->dai_link->codec_dai_name = pdata->codec_dai_name;
603
604 machine = kzalloc(sizeof(struct tegra_rt5640), GFP_KERNEL);
605 if (!machine) {
606 dev_err(&pdev->dev, "Can't allocate tegra_rt5640 struct\n");
607 return -ENOMEM;
608 }
609
610 machine->pdata = pdata;
611
612 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
613 if (ret)
614 goto err_free_machine;
615
616 machine->cdc_en = regulator_get(NULL, "cdc_en");
617 if (WARN_ON(IS_ERR(machine->cdc_en))) {
618 dev_err(&pdev->dev, "Couldn't get regulator cdc_en: %ld\n",
619 PTR_ERR(machine->cdc_en));
620 machine->cdc_en = 0;
621 } else {
622 regulator_enable(machine->cdc_en);
623 }
624
625 machine->spk_reg = regulator_get(&pdev->dev, "vdd_spk_amp");
626 if (IS_ERR(machine->spk_reg)) {
627 dev_info(&pdev->dev, "No speaker regulator found\n");
628 machine->spk_reg = 0;
629 }
630
631#ifdef CONFIG_SWITCH
632 /* Addd h2w swith class support */
633 ret = switch_dev_register(&tegra_rt5640_headset_switch);
634 if (ret < 0)
635 goto err_fini_utils;
636#endif
637
638 card->dev = &pdev->dev;
639 platform_set_drvdata(pdev, card);
640 snd_soc_card_set_drvdata(card, machine);
641
642 ret = snd_soc_register_card(card);
643 if (ret) {
644 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
645 ret);
646 goto err_unregister_switch;
647 }
648
649 if (!card->instantiated) {
650 ret = -ENODEV;
651 dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
652 ret);
653 goto err_unregister_card;
654 }
655
656 return 0;
657
658err_unregister_card:
659 snd_soc_unregister_card(card);
660err_unregister_switch:
661#ifdef CONFIG_SWITCH
662 switch_dev_unregister(&tegra_rt5640_headset_switch);
663err_fini_utils:
664#endif
665 tegra_asoc_utils_fini(&machine->util_data);
666err_free_machine:
667 kfree(machine);
668 return ret;
669}
670
671static int __devexit tegra_rt5640_driver_remove(struct platform_device *pdev)
672{
673 struct snd_soc_card *card = platform_get_drvdata(pdev);
674 struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card);
675 struct tegra_rt5640_platform_data *pdata = machine->pdata;
676
677 if (machine->gpio_requested & GPIO_HP_DET)
678 snd_soc_jack_free_gpios(&tegra_rt5640_hp_jack,
679 1,
680 &tegra_rt5640_hp_jack_gpio);
681 if (machine->gpio_requested & GPIO_EXT_MIC_EN)
682 gpio_free(pdata->gpio_ext_mic_en);
683 if (machine->gpio_requested & GPIO_INT_MIC_EN)
684 gpio_free(pdata->gpio_int_mic_en);
685 if (machine->gpio_requested & GPIO_HP_MUTE)
686 gpio_free(pdata->gpio_hp_mute);
687 if (machine->gpio_requested & GPIO_SPKR_EN)
688 gpio_free(pdata->gpio_spkr_en);
689 machine->gpio_requested = 0;
690
691 if (machine->spk_reg)
692 regulator_put(machine->spk_reg);
693 if (machine->dmic_reg)
694 regulator_put(machine->dmic_reg);
695
696 if (machine->cdc_en) {
697 regulator_disable(machine->cdc_en);
698 regulator_put(machine->cdc_en);
699 }
700
701 snd_soc_unregister_card(card);
702
703 tegra_asoc_utils_fini(&machine->util_data);
704
705#ifdef CONFIG_SWITCH
706 switch_dev_unregister(&tegra_rt5640_headset_switch);
707#endif
708 kfree(machine);
709
710 return 0;
711}
712
713static struct platform_driver tegra_rt5640_driver = {
714 .driver = {
715 .name = DRV_NAME,
716 .owner = THIS_MODULE,
717 .pm = &snd_soc_pm_ops,
718 },
719 .probe = tegra_rt5640_driver_probe,
720 .remove = __devexit_p(tegra_rt5640_driver_remove),
721};
722
723static int __init tegra_rt5640_modinit(void)
724{
725 return platform_driver_register(&tegra_rt5640_driver);
726}
727module_init(tegra_rt5640_modinit);
728
729static void __exit tegra_rt5640_modexit(void)
730{
731 platform_driver_unregister(&tegra_rt5640_driver);
732}
733module_exit(tegra_rt5640_modexit);
734
735MODULE_AUTHOR("Johnny Qiu <joqiu@nvidia.com>");
736MODULE_DESCRIPTION("Tegra+RT5640 machine ASoC driver");
737MODULE_LICENSE("GPL");
738MODULE_ALIAS("platform:" DRV_NAME);