asoc:tegra: Support I2S slave mode
[linux-2.6.git] / sound / soc / tegra / tegra30_dam.c
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
37 static struct tegra30_dam_context       *dams_cont_info[TEGRA30_NR_DAM_IFC];
38
39 enum {
40         dam_ch_in0 = 0x0,
41         dam_ch_in1,
42         dam_ch_out,
43         dam_ch_maxnum
44 } tegra30_dam_chtype;
45
46 struct 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
57 static void tegra30_dam_set_output_samplerate(struct tegra30_dam_context *dam,
58                 int fsout);
59 static void tegra30_dam_set_input_samplerate(struct tegra30_dam_context *dam,
60                 int fsin);
61 static int tegra30_dam_set_step_reset(struct tegra30_dam_context *dam,
62                 int insample, int outsample);
63 static void tegra30_dam_ch0_set_step(struct tegra30_dam_context *dam, int step);
64
65 static 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
74 static 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
82 int 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
111 void 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
123 int 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
138 static 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
173 static 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
178 static 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
185 static 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
194 static void tegra30_dam_debug_remove(struct tegra30_dam_context *dam)
195 {
196         if (dam->debug)
197                 debugfs_remove(dam->debug);
198 }
199 #else
200 static inline void tegra30_dam_debug_add(struct tegra30_dam_context *dam,
201                                                 int id)
202 {
203 }
204
205 static inline void tegra30_dam_debug_remove(struct tegra30_dam_context *dam)
206 {
207 }
208 #endif
209
210 int 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
228 int 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
245 int 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
262 int 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
280 void 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
307 void 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
335 void 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
362 int 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
379 void 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
389 int 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
411 int 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
455 void 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
494 void 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
504 void 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
514 void 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
524 static 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
606 err_clk_put_dam:
607         clk_put(dam->dam_clk);
608 err_free:
609         dams_cont_info[pdev->id] = NULL;
610 exit:
611         return ret;
612 }
613
614 static 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
626 static 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
635 static int __init tegra30_dam_modinit(void)
636 {
637         return platform_driver_register(&tegra30_dam_driver);
638 }
639 module_init(tegra30_dam_modinit);
640
641 static void __exit tegra30_dam_modexit(void)
642 {
643         platform_driver_unregister(&tegra30_dam_driver);
644 }
645 module_exit(tegra30_dam_modexit);
646
647 MODULE_AUTHOR("Nikesh Oswal <noswal@nvidia.com>");
648 MODULE_DESCRIPTION("Tegra 30 DAM driver");
649 MODULE_LICENSE("GPL");
650 MODULE_ALIAS("platform:" DRV_NAME);