0113e74529425d5f43cee46386fd7c33519473a0
[firefly-linux-kernel-4.4.55.git] / sound / soc / rockchip / rk_spdif.c
1 /*$_FOR_ROCKCHIP_RBOX_$*/
2 /*$_rbox_$_modify_$_huangzhibao for spdif output*/
3
4 /* sound/soc/rockchip/rk_spdif.c
5  *
6  * ALSA SoC Audio Layer - rockchip S/PDIF Controller driver
7  *
8  * Copyright (c) 2010 rockchip Electronics Co. Ltd
9  *              http://www.rockchip.com/
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License version 2 as
13  * published by the Free Software Foundation.
14  */
15
16 #include <linux/init.h>
17 #include <linux/module.h>
18 #include <linux/interrupt.h>
19 #include <linux/device.h>
20 #include <linux/delay.h>
21 #include <linux/clk.h>
22 #include <linux/version.h>
23 #include <linux/of.h>
24 #include <linux/of_gpio.h>
25 #include <linux/clk.h>
26 #include <linux/io.h>
27 #include <linux/platform_device.h>
28 #include <linux/pm_runtime.h>
29 #include <linux/regmap.h>
30 #include <linux/slab.h>
31
32 #include <linux/rockchip/iomap.h>
33 #include <linux/rockchip/grf.h>
34
35 #include <asm/dma.h>
36 #include <sound/core.h>
37 #include <sound/pcm.h>
38 #include <sound/pcm_params.h>
39 #include <sound/initval.h>
40 #include <sound/soc.h>
41 #include <sound/dmaengine_pcm.h>
42 #include <linux/spinlock.h>
43 #include "rk_pcm.h"
44
45 #undef  DEBUG_SPDIF
46 #define DEBUG_SPDIF 0
47
48 #if DEBUG_SPDIF
49 #define RK_SPDIF_DBG(x...) pr_info("rk_spdif:"x)
50 #else
51 #define RK_SPDIF_DBG(x...) do { } while (0)
52 #endif
53
54 /* Registers */
55 #define CFGR                  0x00
56 #define SDBLR                 0x04
57 #define DMACR                 0x08
58 #define INTCR                 0x0C
59 #define INTSR                 0x10
60 #define XFER                  0x18
61 #define SMPDR                 0x20
62
63 #define SPDIF_CHNSR00_ADDR    0xC0
64 #define SPDIF_CHNSR01_ADDR    0xC4
65 #define SPDIF_CHNSR02_ADDR    0xC8
66 #define SPDIF_CHNSR03_ADDR    0xCC
67 #define SPDIF_CHNSR04_ADDR    0xD0
68 #define SPDIF_CHNSR05_ADDR    0xD4
69 #define SPDIF_CHNSR06_ADDR    0xD8
70 #define SPDIF_CHNSR07_ADDR    0xDC
71 #define SPDIF_CHNSR08_ADDR    0xE0
72 #define SPDIF_CHNSR09_ADDR    0xE4
73 #define SPDIF_CHNSR10_ADDR    0xE8
74 #define SPDIF_CHNSR11_ADDR    0xEC
75
76 #define SPDIF_BURST_INFO       0x100
77 #define SPDIF_REPETTION       0x104
78
79 #define DATA_OUTBUF           0x20
80
81 #define SPDIF_CHANNEL_SEL_8CH   ((0x2<<16)|(0x0<<0))
82 #define SPDIF_CHANNEL_SEL_2CH   ((0x2<<16)|(0x2<<0))
83
84 /* burst_info bit0:6 AC-3:0x01, DTS-I -II -III:11,12,13 */
85 #define burst_info_DATA_TYPE_AC3     0x01
86 #define burst_info_DATA_TYPE_EAC3    0x15
87 #define BURST_INFO_DATA_TYPE_DTS_I   0x0b
88
89 #define CFGR_MASK                   0x0ffffff
90 #define CFGR_VALID_DATA_16bit       (00)
91 #define CFGR_VALID_DATA_20bit       (01)
92 #define CFGR_VALID_DATA_24bit       (10)
93 #define CFGR_VALID_DATA_MASK        (11)
94
95 #define CFGR_HALFWORD_TX_ENABLE     (0x1<<2)
96 #define CFGR_HALFWORD_TX_DISABLE    (0x0<<2)
97 #define CFGR_HALFWORD_TX_MASK       (0x1<<2)
98
99 #define CFGR_CLK_RATE_MASK          (0xFF<<16)
100
101 #define CFGR_JUSTIFIED_RIGHT        (0<<3)
102 #define CFGR_JUSTIFIED_LEFT         (1<<3)
103 #define CFGR_JUSTIFIED_MASK         (1<<3)
104
105 /* CSE:channel status enable */
106 /* The bit should be set to 1 when the channel conveys non-linear PCM */
107 #define CFGR_CSE_DISABLE            (0<<6)
108 #define CFGR_CSE_ENABLE             (1<<6)
109 #define CFGR_CSE_MASK               (1<<6)
110
111 #define CFGR_MCLK_CLR               (1<<7)
112
113 #define CFGR_LINEAR_PCM             (0<<8)
114 #define CFGR_NON_LINEAR_PCM         (1<<8)
115 #define CFGR_LINEAR_MASK            (1<<8)
116
117 /* support 7.1 amplifier,new */
118 #define CFGR_PRE_CHANGE_ENALBLE     (1<<9)
119 #define CFGR_PRE_CHANGE_DISABLE     (0<<9)
120 #define CFGR_PRE_CHANGE_MASK        (1<<9)
121
122 #define XFER_TRAN_STOP              (0)
123 #define XFER_TRAN_START             (1)
124 #define XFER_MASK                   (1)
125
126 #define DMACR_TRAN_DMA_DISABLE      (0<<5)
127 #define DMACR_TRAN_DMA_ENABLE       (1<<5)
128 #define DMACR_TRAN_DMA_CTL_MASK     (1<<5)
129
130 #define DMACR_TRAN_DATA_LEVEL       0x10
131 #define DMACR_TRAN_DATA_LEVEL_MASK  0x1F
132 #define DMACR_TRAN_DMA_MASK         0x3F
133
134 /* Sample Date Buffer empty interrupt enable, new */
135 #define INTCR_SDBEIE_DISABLE        (0<<4)
136 #define INTCR_SDBEIE_ENABLE         (1<<4)
137 #define INTCR_SDBEIE_MASK           (1<<4)
138
139 struct rockchip_spdif_info {
140         spinlock_t      lock;/*lock parmeter setting.*/
141         void __iomem    *regs;
142         unsigned long   clk_rate;
143         struct clk      *hclk;
144         struct clk      *clk;
145         struct snd_dmaengine_dai_dma_data       dma_playback;
146 };
147
148 static inline struct rockchip_spdif_info *to_info(struct snd_soc_dai *cpu_dai)
149 {
150         return snd_soc_dai_get_drvdata(cpu_dai);
151 }
152
153 static void spdif_snd_txctrl(struct rockchip_spdif_info *spdif, int on)
154 {
155         void __iomem *regs = spdif->regs;
156         u32 opr, xfer;
157
158         RK_SPDIF_DBG("Entered %s\n", __func__);
159
160         xfer = readl(regs + XFER) & XFER_MASK;
161         opr = readl(regs + DMACR) & DMACR_TRAN_DMA_MASK
162                 & (~DMACR_TRAN_DMA_CTL_MASK);
163
164         if (on) {
165                 xfer |= XFER_TRAN_START;
166                 opr |= DMACR_TRAN_DMA_ENABLE;
167                 writel(xfer, regs + XFER);
168                 writel(opr, regs + DMACR);
169                 RK_SPDIF_DBG("on xfer=0x%x,opr=0x%x\n", readl(
170                         regs + XFER), readl(regs + DMACR));
171         } else {
172                 xfer &= ~XFER_TRAN_START;
173                 opr &= ~DMACR_TRAN_DMA_ENABLE;
174                 writel(xfer, regs + XFER);
175                 writel(opr, regs + DMACR);
176                 writel(1<<7, regs + CFGR);
177                 RK_SPDIF_DBG("off xfer=0x%x,opr=0x%x\n", readl(
178                         regs + XFER), readl(regs + DMACR));
179         }
180 }
181
182 static int spdif_set_syclk(struct snd_soc_dai *
183         cpu_dai, int clk_id, unsigned int freq, int dir)
184 {
185         struct rockchip_spdif_info *spdif = to_info(cpu_dai);
186
187         RK_SPDIF_DBG("Entered %s sysclk=%d\n", __func__, freq);
188
189         spdif->clk_rate = freq;
190         clk_set_rate(spdif->clk, freq);
191
192         return 0;
193 }
194
195 static int spdif_trigger(struct snd_pcm_substream *
196                 substream, int cmd, struct snd_soc_dai *dai)
197 {
198         struct snd_soc_pcm_runtime *rtd = substream->private_data;
199         struct rockchip_spdif_info *spdif = to_info(rtd->cpu_dai);
200         unsigned long flags;
201
202         RK_SPDIF_DBG("Entered %s\n", __func__);
203
204         switch (cmd) {
205         case SNDRV_PCM_TRIGGER_START:
206         case SNDRV_PCM_TRIGGER_RESUME:
207         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
208                 spin_lock_irqsave(&spdif->lock, flags);
209                 spdif_snd_txctrl(spdif, 1);
210                 spin_unlock_irqrestore(&spdif->lock, flags);
211                 break;
212         case SNDRV_PCM_TRIGGER_STOP:
213         case SNDRV_PCM_TRIGGER_SUSPEND:
214         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
215                 spin_lock_irqsave(&spdif->lock, flags);
216                 spdif_snd_txctrl(spdif, 0);
217                 spin_unlock_irqrestore(&spdif->lock, flags);
218                 break;
219         default:
220                 return -EINVAL;
221         }
222
223         return 0;
224 }
225
226 static int spdif_hw_params(struct snd_pcm_substream *
227                 substream, struct snd_pcm_hw_params *params,
228                 struct snd_soc_dai *dai)
229 {
230         struct rockchip_spdif_info *spdif = to_info(dai);
231         void __iomem *regs = spdif->regs;
232         unsigned long flags;
233         int cfgr, dmac, intcr, chnsr_byte[5] = {0};
234         int data_type, err_flag, data_len, data_info;
235         int bs_num, repetition, burst_info;
236
237         RK_SPDIF_DBG("Entered %s\n", __func__);
238
239         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
240                 dai->playback_dma_data = &spdif->dma_playback;
241         } else {
242                 pr_err("spdif:Capture is not supported\n");
243                 return -EINVAL;
244         }
245
246         spin_lock_irqsave(&spdif->lock, flags);
247
248         cfgr = readl(regs + CFGR) & CFGR_VALID_DATA_MASK;
249
250         cfgr &= ~CFGR_VALID_DATA_MASK;
251         switch (params_format(params)) {
252         case SNDRV_PCM_FORMAT_S16_LE:
253                 cfgr |= CFGR_VALID_DATA_16bit;
254                 break;
255         case SNDRV_PCM_FORMAT_S20_3LE:
256                 cfgr |= CFGR_VALID_DATA_20bit;
257                 break;
258         case SNDRV_PCM_FORMAT_S24_LE:
259                 cfgr |= CFGR_VALID_DATA_24bit;
260                 break;
261         default:
262                 goto err;
263         }
264
265         cfgr &= ~CFGR_HALFWORD_TX_MASK;
266         cfgr |= CFGR_HALFWORD_TX_ENABLE;
267
268         /* set most MCLK:192kHz */
269         cfgr &= ~CFGR_CLK_RATE_MASK;
270         cfgr |= (1<<16);
271
272         cfgr &= ~CFGR_JUSTIFIED_MASK;
273         cfgr |= CFGR_JUSTIFIED_RIGHT;
274
275         cfgr &= ~CFGR_CSE_MASK;
276         cfgr |= CFGR_CSE_DISABLE;
277
278         cfgr &= ~CFGR_LINEAR_MASK;
279         cfgr |= CFGR_LINEAR_PCM;
280
281         /* stream type*/
282         if (!snd_pcm_format_linear(params_format(params)))
283                 cfgr |= CFGR_NON_LINEAR_PCM;
284
285         cfgr &= ~CFGR_PRE_CHANGE_MASK;
286         cfgr |= CFGR_PRE_CHANGE_ENALBLE;
287
288         writel(cfgr, regs + CFGR);
289
290         intcr = readl(regs + INTCR) & INTCR_SDBEIE_MASK;
291         intcr |= INTCR_SDBEIE_ENABLE;
292         writel(intcr, regs + INTCR);
293
294         dmac = readl(regs + DMACR) & DMACR_TRAN_DMA_MASK &
295                 (~DMACR_TRAN_DATA_LEVEL_MASK);
296         dmac |= 0x10;
297         writel(dmac, regs + DMACR);
298
299         /*
300         * channel byte 0:
301         * Bit 1
302         * 1 Main data field represents linear PCM samples.
303         * 0 Main data field used for purposes other purposes.
304         */
305         chnsr_byte[0] = (0x0) | (0x0 << 1) |
306                 (0x0 << 2) | (0x0 << 3) |
307                 (0x00 << 6);
308         chnsr_byte[1] = (0x0);
309         chnsr_byte[2] = (0x0) | (0x0 << 4) | (0x0 << 6);
310         chnsr_byte[3] = (0x00) | (0x00);
311         chnsr_byte[4] = (0x0 << 4) | (0x01 << 1 | 0x0);
312
313         /* set stream type */
314         if (!snd_pcm_format_linear(params_format(params))) {
315                 chnsr_byte[0] |= (0x1<<1);
316                 chnsr_byte[4] = (0x0<<4)|(0x00<<1|0x0);
317         }
318         writel((chnsr_byte[4] << 16)
319                         | (chnsr_byte[4]),
320                         regs + SPDIF_CHNSR02_ADDR);
321         writel((chnsr_byte[3] << 24) | (chnsr_byte[2] << 16) |
322                 (chnsr_byte[3] << 8) | (chnsr_byte[2]),
323                 regs + SPDIF_CHNSR01_ADDR);
324         writel((chnsr_byte[1] << 24) | (chnsr_byte[0] << 16) |
325                 (chnsr_byte[1] << 8) | (chnsr_byte[0]),
326                 regs + SPDIF_CHNSR00_ADDR);
327
328         /* set non-linear params */
329         if (!snd_pcm_format_linear(params_format(params))) {
330                 switch (params_format(params)) {
331                 case SNDRV_NON_LINEAR_PCM_FORMAT_AC3:
332                         /* bit0:6 AC-3:0x01, DTS-I -II -III:11,12,13 */
333                         data_type = burst_info_DATA_TYPE_AC3;
334                         /*
335                         * repetition:AC-3:1536
336                         * DTS-I -II -III:512,1024,2048 EAC3:6144
337                         */
338                         repetition = 1536;
339                         break;
340                 case SNDRV_NON_LINEAR_PCM_FORMAT_DTS_I:
341                         data_type = BURST_INFO_DATA_TYPE_DTS_I;
342                         repetition = 512;
343                         break;
344                 case SNDRV_NON_LINEAR_PCM_FORMAT_EAC3:
345                         data_type = burst_info_DATA_TYPE_EAC3;
346                         repetition = 6144;
347                         break;
348                 default:
349                         return -EINVAL;
350                 }
351                 err_flag = 0x0;
352                 data_len = params_period_size(params) * 2 * 16;
353                 data_info = 0;
354                 bs_num = 0x0;
355                 burst_info = (data_len << 16) | (bs_num << 13) |
356                         (data_info << 8) | (err_flag << 7) | data_type;
357                 writel(burst_info, regs + SPDIF_BURST_INFO);
358                 writel(repetition, regs + SPDIF_REPETTION);
359         }
360         spin_unlock_irqrestore(&spdif->lock, flags);
361
362         return 0;
363 err:
364         spin_unlock_irqrestore(&spdif->lock, flags);
365         return -EINVAL;
366 }
367
368 #ifdef CONFIG_PM
369 static int spdif_suspend(struct snd_soc_dai *cpu_dai)
370 {
371         RK_SPDIF_DBG("spdif:Entered %s\n", __func__);
372
373         return 0;
374 }
375
376 static int spdif_resume(struct snd_soc_dai *cpu_dai)
377 {
378         RK_SPDIF_DBG("spdif:Entered %s\n", __func__);
379
380         return 0;
381 }
382 #else
383 #define spdif_suspend NULL
384 #define spdif_resume NULL
385 #endif
386
387 static struct snd_soc_dai_ops spdif_dai_ops = {
388         .set_sysclk     = spdif_set_syclk,
389         .trigger        = spdif_trigger,
390         .hw_params      = spdif_hw_params,
391 };
392
393 struct snd_soc_dai_driver rockchip_spdif_dai = {
394         .name = "rockchip-spdif",
395         .playback = {
396                 .stream_name = "SPDIF Playback",
397                 .channels_min = 2,
398                 .channels_max = 2,
399                 .rates = (SNDRV_PCM_RATE_32000 |
400                                 SNDRV_PCM_RATE_44100 |
401                                 SNDRV_PCM_RATE_48000 |
402                                 SNDRV_PCM_RATE_96000),
403                 .formats = SNDRV_PCM_FMTBIT_S16_LE|
404                 SNDRV_PCM_FMTBIT_S20_3LE|
405                 SNDRV_PCM_FMTBIT_S24_LE, },
406         .ops = &spdif_dai_ops,
407         .suspend = spdif_suspend,
408         .resume = spdif_resume,
409 };
410
411 static const struct snd_soc_component_driver rockchip_spdif_component = {
412         .name = "rockchip-spdif",
413 };
414
415 static int spdif_probe(struct platform_device *pdev)
416 {
417         /*struct device_node *spdif_np = pdev->dev.of_node;*/
418         struct resource *memregion;
419         struct resource *mem_res;
420         struct rockchip_spdif_info *spdif;
421         int ret;
422
423         RK_SPDIF_DBG("Entered %s\n", __func__);
424
425         spdif = devm_kzalloc(&pdev->dev, sizeof(
426                 struct rockchip_spdif_info), GFP_KERNEL);
427         if (!spdif) {
428                 dev_err(&pdev->dev, "Can't allocate spdif info\n");
429                 return -ENOMEM;
430         }
431         platform_set_drvdata(pdev, spdif);
432
433         spin_lock_init(&spdif->lock);
434
435         /* get spdif register regoin. */
436         mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
437         if (!mem_res) {
438                 dev_err(&pdev->dev, "No memory resource\n");
439                 ret = -ENOENT;
440                 goto err_;
441         }
442         memregion = devm_request_mem_region(&pdev->
443                         dev, mem_res->start,
444                         resource_size(mem_res), "rockchip-spdif");
445         if (!memregion) {
446                 dev_err(&pdev->dev, "Memory region already claimed\n");
447                 ret = -EBUSY;
448                 goto err_;
449         }
450         spdif->regs = devm_ioremap(&pdev->dev, memregion->
451                         start, resource_size(memregion));
452         if (!spdif->regs) {
453                 dev_err(&pdev->dev, "ioremap failed\n");
454                 ret = -ENOMEM;
455                 goto err_;
456         }
457
458         /* get spdif clock and init. */
459         spdif->hclk = devm_clk_get(&pdev->dev, "spdif_hclk");
460         if (IS_ERR(spdif->hclk)) {
461                 dev_err(&pdev->dev, "Can't retrieve spdif hclock\n");
462                 spdif->hclk = NULL;
463         }
464         clk_prepare_enable(spdif->hclk);
465
466         /* get spdif clock and init. */
467         spdif->clk = devm_clk_get(&pdev->dev, "spdif_mclk");
468         if (IS_ERR(spdif->clk)) {
469                 dev_err(&pdev->dev, "Can't retrieve spdif clock\n");
470                 ret = -ENOMEM;
471                 goto err_;
472         }
473         clk_set_rate(spdif->clk, 12288000);
474         clk_set_rate(spdif->clk, 11289600);
475         clk_prepare_enable(spdif->clk);
476
477         spdif->dma_playback.addr = mem_res->start + DATA_OUTBUF;
478         spdif->dma_playback.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
479         spdif->dma_playback.maxburst = 4;
480
481         /* set dev name to driver->name for sound card register */
482         dev_set_name(&pdev->dev, "%s", pdev->dev.driver->name);
483
484         ret = snd_soc_register_component(&pdev->
485                 dev, &rockchip_spdif_component, &rockchip_spdif_dai, 1);
486         if (ret) {
487                 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
488                 ret = -ENOMEM;
489                 goto err_;
490         }
491
492         ret = rockchip_pcm_platform_register(&pdev->dev);
493         if (ret) {
494                 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
495                 goto err_;
496         }
497
498         RK_SPDIF_DBG("spdif:spdif probe ok!\n");
499
500         return 0;
501
502 err_:
503         platform_set_drvdata(pdev, NULL);
504
505         return ret;
506 }
507
508 static int spdif_remove(struct platform_device *pdev)
509 {
510         RK_SPDIF_DBG("Entered %s\n", __func__);
511
512         rockchip_pcm_platform_unregister(&pdev->dev);
513         snd_soc_unregister_component(&pdev->dev);
514
515         return 0;
516 }
517
518 #ifdef CONFIG_OF
519 static const struct of_device_id exynos_spdif_match[] = {
520         { .compatible = "rockchip-spdif"},
521         {},
522 };
523 MODULE_DEVICE_TABLE(of, exynos_spdif_match);
524 #endif
525
526 static struct platform_driver rockchip_spdif_driver = {
527         .probe  = spdif_probe,
528         .remove = spdif_remove,
529         .driver = {
530                 .name   = "rockchip-spdif",
531                 .owner  = THIS_MODULE,
532                 .of_match_table = of_match_ptr(exynos_spdif_match),
533         },
534 };
535 module_platform_driver(rockchip_spdif_driver);
536
537 MODULE_AUTHOR("Seungwhan Youn, <sw.youn@rockchip.com>");
538 MODULE_DESCRIPTION("rockchip S/PDIF Controller Driver");
539 MODULE_LICENSE("GPL");
540 MODULE_ALIAS("platform:rockchip-spdif");