Merge tag 'lsk-v3.10-android-14.12'
[firefly-linux-kernel-4.4.55.git] / sound / soc / rockchip / rk30_i2s.c
1 /*
2  * rk30_i2s.c  --  ALSA SoC ROCKCHIP IIS Audio Layer Platform driver
3  *
4  * Driver for rockchip iis audio
5  *
6  *
7  *  This program is free software; you can redistribute  it and/or modify it
8  *  under  the terms of  the GNU General  Public License as published by the
9  *  Free Software Foundation;  either version 2 of the  License, or (at your
10  *  option) any later version.
11  *
12  */
13
14 #include <linux/init.h>
15 #include <linux/module.h>
16 #include <linux/interrupt.h>
17 #include <linux/device.h>
18 #include <linux/delay.h>
19 #include <linux/clk.h>
20 #include <linux/version.h>
21 #include <linux/of.h>
22 #include <linux/of_gpio.h>
23 #include <linux/clk.h>
24 #include <linux/io.h>
25 #include <linux/platform_device.h>
26 #include <linux/pm_runtime.h>
27 #include <linux/regmap.h>
28 #include <linux/rockchip/cpu.h>
29 #include <linux/rockchip/cru.h>
30 #include <linux/rockchip/grf.h>
31 #include <linux/slab.h>
32 #include <asm/dma.h>
33 #include <sound/core.h>
34 #include <sound/pcm.h>
35 #include <sound/pcm_params.h>
36 #include <sound/initval.h>
37 #include <sound/soc.h>
38 #include <sound/dmaengine_pcm.h>
39 #include <asm/io.h>
40 #include <linux/spinlock.h>
41 #include <linux/workqueue.h>
42
43 #define CLK_SET_lATER
44
45 #include "rk_pcm.h"
46 #include "rk_i2s.h"
47
48 #if 0
49 #define I2S_DBG(x...) printk(KERN_INFO x)
50 #else
51 #define I2S_DBG(x...) do { } while (0)
52 #endif
53
54 #define pheadi2s  ((pI2S_REG)(i2s->regs))
55
56 #define MAX_I2S 3
57
58 static DEFINE_SPINLOCK(lock);
59
60 struct rk30_i2s_info {
61         void __iomem    *regs;
62
63         struct clk *i2s_clk;// i2s clk ,is bclk lrck
64         struct clk *i2s_mclk;//i2s mclk,rk32xx can different i2s clk.
65         struct clk *i2s_hclk;
66         struct snd_dmaengine_dai_dma_data capture_dma_data;
67         struct snd_dmaengine_dai_dma_data playback_dma_data;
68
69         bool i2s_tx_status;//active = true;
70         bool i2s_rx_status;
71 #ifdef CLK_SET_lATER
72         struct delayed_work clk_delayed_work;
73 #endif  
74 };
75
76 #define I2S_CLR_ERROR_COUNT 10// check I2S_CLR reg 
77 static struct rk30_i2s_info *rk30_i2s;
78
79 #if defined (CONFIG_RK_HDMI) && defined (CONFIG_SND_RK_SOC_HDMI_I2S)
80 extern int hdmi_get_hotplug(void);
81 #else
82 #define hdmi_get_hotplug() 0
83 #endif
84
85 static inline struct rk30_i2s_info *to_info(struct snd_soc_dai *dai)
86 {
87         return snd_soc_dai_get_drvdata(dai);
88 }
89
90 /* 
91  *Turn on or off the transmission path. 
92  */
93 static void rockchip_snd_txctrl(struct rk30_i2s_info *i2s, int on)
94 {
95         u32 opr, xfer, clr;
96         unsigned long flags;
97         bool is_need_delay = false;
98         int clr_error_count = I2S_CLR_ERROR_COUNT;
99
100         spin_lock_irqsave(&lock, flags);
101
102         opr  = readl(&(pheadi2s->I2S_DMACR));
103         xfer = readl(&(pheadi2s->I2S_XFER));
104         clr  = readl(&(pheadi2s->I2S_CLR));
105
106         I2S_DBG("rockchip_snd_txctrl: %s\n", on ? "on" : "off");
107
108         if (on) {
109                 if ((opr & I2S_TRAN_DMA_ENABLE) == 0) {
110                         opr  |= I2S_TRAN_DMA_ENABLE;
111                         writel(opr, &(pheadi2s->I2S_DMACR));
112                 }
113
114                 if ((xfer & I2S_TX_TRAN_START) == 0 || (xfer & I2S_RX_TRAN_START) == 0) {
115                         xfer |= I2S_TX_TRAN_START;
116                         xfer |= I2S_RX_TRAN_START;
117                         writel(xfer, &(pheadi2s->I2S_XFER));
118                 }
119
120                 i2s->i2s_tx_status = 1;
121
122         } else { //stop tx
123                 i2s->i2s_tx_status = 0;
124                 opr  &= ~I2S_TRAN_DMA_ENABLE;
125                 writel(opr, &(pheadi2s->I2S_DMACR));
126
127                 if (i2s->i2s_rx_status == 0 && hdmi_get_hotplug() == 0) {
128                         xfer &= ~I2S_TX_TRAN_START;
129                         xfer &= ~I2S_RX_TRAN_START;
130                         writel(xfer, &(pheadi2s->I2S_XFER));    
131
132                         clr |= I2S_TX_CLEAR;
133                         clr |= I2S_RX_CLEAR;
134                         writel(clr, &(pheadi2s->I2S_CLR));
135
136                         is_need_delay = true;
137
138                         I2S_DBG("rockchip_snd_txctrl: stop xfer\n");
139                 }
140         }
141
142         spin_unlock_irqrestore(&lock, flags);
143
144         if (is_need_delay){
145                 while(readl(&(pheadi2s->I2S_CLR)) && clr_error_count){
146                         udelay(1);
147                         clr_error_count --;
148                         if(clr_error_count == 0)
149                                 printk("%s: i2s clr reg warning =%d\n",__FUNCTION__,readl(&(pheadi2s->I2S_CLR)));
150                 }
151         }       
152 }
153
154 static void rockchip_snd_rxctrl(struct rk30_i2s_info *i2s, int on)
155 {
156         u32 opr, xfer, clr;
157         unsigned long flags;
158         bool is_need_delay = false;
159         int clr_error_count = I2S_CLR_ERROR_COUNT;
160
161         spin_lock_irqsave(&lock, flags);
162
163         opr  = readl(&(pheadi2s->I2S_DMACR));
164         xfer = readl(&(pheadi2s->I2S_XFER));
165         clr  = readl(&(pheadi2s->I2S_CLR));
166
167         I2S_DBG("rockchip_snd_rxctrl: %s\n", on ? "on" : "off");
168
169         if (on) {
170                 if ((opr & I2S_RECE_DMA_ENABLE) == 0) {
171                         opr  |= I2S_RECE_DMA_ENABLE;
172                         writel(opr, &(pheadi2s->I2S_DMACR));
173                 }
174
175                 if ((xfer & I2S_TX_TRAN_START)==0 || (xfer & I2S_RX_TRAN_START) == 0) {
176                         xfer |= I2S_RX_TRAN_START;
177                         xfer |= I2S_TX_TRAN_START;
178                         writel(xfer, &(pheadi2s->I2S_XFER));
179                 }
180
181                 i2s->i2s_rx_status = 1;
182         } else {
183                 i2s->i2s_rx_status = 0;
184
185                 opr  &= ~I2S_RECE_DMA_ENABLE;
186                 writel(opr, &(pheadi2s->I2S_DMACR));
187
188                 if (i2s->i2s_tx_status == 0 && hdmi_get_hotplug() == 0) {
189                         xfer &= ~I2S_RX_TRAN_START;
190                         xfer &= ~I2S_TX_TRAN_START;
191                         writel(xfer, &(pheadi2s->I2S_XFER));
192
193                         clr |= I2S_RX_CLEAR;
194                         clr |= I2S_TX_CLEAR;
195                         writel(clr, &(pheadi2s->I2S_CLR));
196
197                         is_need_delay = true;
198
199                         I2S_DBG("rockchip_snd_rxctrl: stop xfer\n");
200                 }
201         }
202
203         spin_unlock_irqrestore(&lock, flags);
204
205         if (is_need_delay){
206                 while(readl(&(pheadi2s->I2S_CLR)) && clr_error_count){
207                         udelay(1);
208                         clr_error_count --;
209                         if(clr_error_count == 0)
210                                 printk("%s: i2s clr reg warning =%d\n",__FUNCTION__,readl(&(pheadi2s->I2S_CLR)));
211                 }
212         }
213 }
214
215 /*
216  * Set Rockchip I2S DAI format
217  */
218 static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
219                                                 unsigned int fmt)
220 {
221         struct rk30_i2s_info *i2s = to_info(cpu_dai);
222         u32 tx_ctl,rx_ctl;
223         u32 iis_ckr_value;//clock generation register
224         unsigned long flags;
225         int ret = 0;
226
227         I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
228
229         spin_lock_irqsave(&lock, flags);
230
231         tx_ctl = readl(&(pheadi2s->I2S_TXCR));
232         iis_ckr_value = readl(&(pheadi2s->I2S_CKR));
233
234         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
235         case SND_SOC_DAIFMT_CBM_CFM:
236                 //Codec is master, so set cpu slave.
237                 iis_ckr_value &= ~I2S_MODE_MASK;
238                 iis_ckr_value |= I2S_SLAVE_MODE;
239                 break;
240         case SND_SOC_DAIFMT_CBS_CFS:
241                 //Codec is slave, so set cpu master.
242                 iis_ckr_value &= ~I2S_MODE_MASK;
243                 iis_ckr_value |= I2S_MASTER_MODE;
244                 break;
245         default:
246                 I2S_DBG("unknwon master/slave format\n");
247                 ret = -EINVAL;
248                 goto out_;
249         }
250
251         writel(iis_ckr_value, &(pheadi2s->I2S_CKR));
252
253         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
254         case SND_SOC_DAIFMT_RIGHT_J:
255                 tx_ctl &= ~I2S_BUS_MODE_MASK;    //I2S Bus Mode
256                 tx_ctl |= I2S_BUS_MODE_RSJM;
257                 break;
258         case SND_SOC_DAIFMT_LEFT_J:
259                 tx_ctl &= ~I2S_BUS_MODE_MASK;    //I2S Bus Mode
260                 tx_ctl |= I2S_BUS_MODE_LSJM;
261                 break;
262         case SND_SOC_DAIFMT_I2S:
263                 tx_ctl &= ~I2S_BUS_MODE_MASK;    //I2S Bus Mode
264                 tx_ctl |= I2S_BUS_MODE_NOR;
265                 break;
266         default:
267                 I2S_DBG("Unknown data format\n");
268                 ret = -EINVAL;
269                 goto out_;
270         }
271
272         I2S_DBG("Enter::%s----%d, I2S_TXCR=0x%X\n",__FUNCTION__,__LINE__,tx_ctl);
273
274         writel(tx_ctl, &(pheadi2s->I2S_TXCR));
275
276         rx_ctl = tx_ctl & 0x00007FFF;
277         writel(rx_ctl, &(pheadi2s->I2S_RXCR));
278
279 out_:
280
281         spin_unlock_irqrestore(&lock, flags);
282
283         return ret;
284 }
285
286 static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
287                                 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
288 {
289         struct rk30_i2s_info *i2s = to_info(dai);
290         u32 iismod;
291         u32 dmarc;
292         unsigned long flags;
293
294         I2S_DBG("Enter %s, %d \n", __func__, __LINE__);
295
296         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
297                 dai->playback_dma_data = &i2s->playback_dma_data;
298         else
299                 dai->capture_dma_data = &i2s->capture_dma_data;
300
301         spin_lock_irqsave(&lock, flags);
302
303         /* Working copies of register */
304         iismod = readl(&(pheadi2s->I2S_TXCR));
305
306         iismod &= (~((1<<5)-1));
307         switch (params_format(params)) {
308         case SNDRV_PCM_FORMAT_S8:
309                 iismod |= SAMPLE_DATA_8bit;
310                 break;
311         case SNDRV_PCM_FORMAT_S16_LE:
312                 iismod |= I2S_DATA_WIDTH(15);
313                 break;
314         case SNDRV_PCM_FORMAT_S20_3LE:
315                 iismod |= I2S_DATA_WIDTH(19);
316                 break;
317         case SNDRV_PCM_FORMAT_S24_LE:
318                 iismod |= I2S_DATA_WIDTH(23);
319                 break;
320         case SNDRV_PCM_FORMAT_S32_LE:
321                 iismod |= I2S_DATA_WIDTH(31);
322                 break;
323         }
324
325 //      writel((16<<24) |(16<<18)|(16<<12)|(16<<6)|16, &(pheadi2s->I2S_FIFOLR));
326         dmarc = readl(&(pheadi2s->I2S_DMACR));
327
328         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
329                 dmarc = ((dmarc & 0xFFFFFE00) | 16);
330         else
331                 dmarc = ((dmarc & 0xFE00FFFF) | 16<<16);
332
333         writel(dmarc, &(pheadi2s->I2S_DMACR));
334
335         I2S_DBG("Enter %s, %d I2S_TXCR=0x%08X\n", __func__, __LINE__, iismod);
336
337         writel(iismod, &(pheadi2s->I2S_TXCR));
338
339         iismod = iismod & 0x00007FFF;
340         writel(iismod, &(pheadi2s->I2S_RXCR));
341
342         spin_unlock_irqrestore(&lock, flags);
343
344         return 0;
345 }
346
347 static int rockchip_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
348 {
349         struct rk30_i2s_info *i2s = to_info(dai);
350         int ret = 0;
351
352         I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
353
354         switch (cmd) {
355         case SNDRV_PCM_TRIGGER_START:
356         case SNDRV_PCM_TRIGGER_RESUME:
357         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
358                 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
359                         rockchip_snd_rxctrl(i2s, 1);
360                 else
361                         rockchip_snd_txctrl(i2s, 1);
362                 break;
363         case SNDRV_PCM_TRIGGER_SUSPEND:
364         case SNDRV_PCM_TRIGGER_STOP:
365         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
366                 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
367                         rockchip_snd_rxctrl(i2s, 0);
368                 else
369                         rockchip_snd_txctrl(i2s, 0);
370                 break;
371         default:
372                 ret = -EINVAL;
373                 break;
374         }
375
376         return ret;
377 }
378
379 /*
380  * Set Rockchip I2S MCLK source
381  */
382 static int rockchip_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
383         int clk_id, unsigned int freq, int dir)
384 {
385         struct rk30_i2s_info *i2s = to_info(cpu_dai);
386
387         I2S_DBG("Enter:%s, %d, i2s=0x%p, freq=%d\n", __FUNCTION__, __LINE__, i2s, freq);
388
389         /*add scu clk source and enable clk*/
390         clk_set_rate(i2s->i2s_clk, freq);
391         return 0;
392 }
393
394 /*
395  * Set Rockchip Clock dividers
396  */
397 static int rockchip_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
398         int div_id, int div)
399 {
400         struct rk30_i2s_info *i2s;
401         u32 reg;
402         unsigned long flags;
403         int ret = 0;
404
405         i2s = to_info(cpu_dai);
406
407         spin_lock_irqsave(&lock, flags);
408
409         //stereo mode MCLK/SCK=4  
410         reg = readl(&(pheadi2s->I2S_CKR));
411
412         I2S_DBG("Enter:%s, %d, div_id=0x%08X, div=0x%08X\n", __FUNCTION__, __LINE__, div_id, div);
413         
414         //when i2s in master mode ,must set codec pll div
415         switch (div_id) {
416         case ROCKCHIP_DIV_BCLK:
417                 reg &= ~I2S_TX_SCLK_DIV_MASK;
418                 reg |= I2S_TX_SCLK_DIV(div);
419                 reg &= ~I2S_RX_SCLK_DIV_MASK;
420                 reg |= I2S_RX_SCLK_DIV(div);
421                 break;
422         case ROCKCHIP_DIV_MCLK:
423                 reg &= ~I2S_MCLK_DIV_MASK;
424                 reg |= I2S_MCLK_DIV(div);
425                 break;
426         case ROCKCHIP_DIV_PRESCALER:
427                 break;
428         default:
429                 ret = -EINVAL;
430                 goto out_;
431         }
432         writel(reg, &(pheadi2s->I2S_CKR));
433
434 out_:
435         spin_unlock_irqrestore(&lock, flags);
436
437         return ret;
438 }
439
440 static struct snd_soc_dai_ops rockchip_i2s_dai_ops = {
441         .trigger = rockchip_i2s_trigger,
442         .hw_params = rockchip_i2s_hw_params,
443         .set_fmt = rockchip_i2s_set_fmt,
444         .set_clkdiv = rockchip_i2s_set_clkdiv,
445         .set_sysclk = rockchip_i2s_set_sysclk,
446 };
447
448 #define ROCKCHIP_I2S_STEREO_RATES SNDRV_PCM_RATE_8000_96000
449 #define ROCKCHIP_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
450                         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
451
452 struct snd_soc_dai_driver rockchip_i2s_dai[] = {
453         {
454                 .name = "rockchip-i2s.0",
455                 .id = 0,
456                 .playback = {
457                         .channels_min = 2,
458                         .channels_max = 8,
459                         .rates = ROCKCHIP_I2S_STEREO_RATES,
460                         .formats = ROCKCHIP_I2S_FORMATS,
461                 },
462                 .capture = {
463                         .channels_min = 2,
464                         .channels_max = 2,
465                         .rates = ROCKCHIP_I2S_STEREO_RATES,
466                         .formats = ROCKCHIP_I2S_FORMATS,
467                 },
468                 .ops = &rockchip_i2s_dai_ops,
469                 .symmetric_rates = 1,
470         },
471         {
472                 .name = "rockchip-i2s.1",
473                 .id = 1,
474                 .playback = {
475                         .channels_min = 2,
476                         .channels_max = 2,
477                         .rates = ROCKCHIP_I2S_STEREO_RATES,
478                         .formats = ROCKCHIP_I2S_FORMATS,
479                 },
480                 .capture = {
481                         .channels_min = 2,
482                         .channels_max = 2,
483                         .rates = ROCKCHIP_I2S_STEREO_RATES,
484                         .formats = ROCKCHIP_I2S_FORMATS,
485                 },
486                 .ops = &rockchip_i2s_dai_ops,
487                 .symmetric_rates = 1,
488         },
489 };
490
491 static const struct snd_soc_component_driver rockchip_i2s_component = {
492         .name           = "rockchip-i2s",
493 };
494
495 #ifdef CONFIG_PM
496 static int rockchip_i2s_suspend_noirq(struct device *dev)
497 {
498         I2S_DBG("Enter %s, %d\n", __func__, __LINE__);
499
500         return pinctrl_pm_select_sleep_state(dev);
501 }
502
503 static int rockchip_i2s_resume_noirq(struct device *dev)
504 {
505         I2S_DBG("Enter %s, %d\n", __func__, __LINE__);
506
507         return pinctrl_pm_select_default_state(dev);
508 }
509 #else
510 #define rockchip_i2s_suspend_noirq NULL
511 #define rockchip_i2s_resume_noirq NULL
512 #endif
513
514 #ifdef CLK_SET_lATER
515 static void set_clk_later_work(struct work_struct *work)
516 {
517         struct rk30_i2s_info *i2s = rk30_i2s;
518         clk_set_rate(i2s->i2s_clk, 11289600);
519         if(!IS_ERR(i2s->i2s_mclk) )
520                 clk_set_rate(i2s->i2s_mclk, 11289600);
521 }
522 #endif
523
524 static int rockchip_i2s_probe(struct platform_device *pdev)
525 {
526         struct device_node *node = pdev->dev.of_node;
527         struct rk30_i2s_info *i2s;
528         struct resource *mem, *memregion;
529         u32 regs_base;
530         int ret;
531
532         I2S_DBG("%s()\n", __FUNCTION__);
533
534         ret = of_property_read_u32(node, "i2s-id", &pdev->id);
535         if (ret < 0) {
536                 dev_err(&pdev->dev, "%s() Can not read property: id\n", __FUNCTION__);
537                 ret = -ENOMEM;
538                 goto err;
539         }
540
541         if (soc_is_rk3126b()) {
542                 int sdi_src = 0;
543
544                 /* rk3126b has no i2s1 controller(i2s_8ch) */
545                 if (1 == pdev->id) {
546                         pr_info("rk3126b has no i2s1 controller\n");
547                         ret = -ENODEV;
548                         goto err;
549                 }
550
551                 ret = of_property_read_u32(node, "sdi_source",
552                                            &sdi_src);
553                 if (ret < 0)
554                         sdi_src = 0;
555
556                 if (1 == sdi_src) {
557                         int val;
558
559                         /*GRF_SOC_CON*/
560                         val = readl_relaxed(RK_GRF_VIRT + 0x0140);
561                         val = val | 0x04000400;
562                         writel_relaxed(val, RK_GRF_VIRT + 0x0140);
563                 }
564         }
565
566         if(pdev->id >= MAX_I2S) {
567                 dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
568                 ret = -ENOMEM;
569                 goto err;
570         }
571
572         i2s = devm_kzalloc(&pdev->dev, sizeof(struct rk30_i2s_info), GFP_KERNEL);
573         if (!i2s) {
574                 dev_err(&pdev->dev, "Can't allocate i2s info\n");
575                 ret = -ENOMEM;
576                 goto err;
577         }
578
579         rk30_i2s = i2s;
580
581         i2s->i2s_hclk = clk_get(&pdev->dev, "i2s_hclk");
582         if(IS_ERR(i2s->i2s_hclk) ) {
583                 dev_err(&pdev->dev, "get i2s_hclk failed.\n");
584         } else{
585                 clk_prepare_enable(i2s->i2s_hclk);
586         }
587
588         i2s->i2s_clk= clk_get(&pdev->dev, "i2s_clk");
589         if (IS_ERR(i2s->i2s_clk)) {
590                 dev_err(&pdev->dev, "Can't retrieve i2s clock\n");
591                 ret = PTR_ERR(i2s->i2s_clk);
592                 goto err;
593         }
594 #ifdef CLK_SET_lATER
595         INIT_DELAYED_WORK(&i2s->clk_delayed_work, set_clk_later_work);
596         schedule_delayed_work(&i2s->clk_delayed_work, msecs_to_jiffies(10));
597 #else
598         clk_set_rate(i2s->iis_clk, 11289600);
599 #endif  
600         clk_prepare_enable(i2s->i2s_clk);
601
602         i2s->i2s_mclk= clk_get(&pdev->dev, "i2s_mclk");
603         if(IS_ERR(i2s->i2s_mclk) ) {
604                 printk("This platfrom have not i2s_mclk,no need to set i2s_mclk.\n");
605         }else{
606         #ifdef CLK_SET_lATER
607                 
608         #else
609                 clk_set_rate(i2s->i2s_mclk, 11289600);
610         #endif
611                 clk_prepare_enable(i2s->i2s_mclk);
612         }
613
614         mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
615         if (!mem) {
616                 dev_err(&pdev->dev, "No memory resource\n");
617                 ret = -ENODEV;
618                 goto err_clk_put;
619         }
620
621         memregion = devm_request_mem_region(&pdev->dev, mem->start,
622                                             resource_size(mem), "rockchip-i2s");
623         if (!memregion) {
624                 dev_err(&pdev->dev, "Memory region already claimed\n");
625                 ret = -EBUSY;
626                 goto err_clk_put;
627         }
628
629         i2s->regs = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
630         if (!i2s->regs) {
631                 dev_err(&pdev->dev, "ioremap failed\n");
632                 ret = -ENOMEM;
633                 goto err_clk_put;
634         }
635
636         regs_base = mem->start;
637
638         i2s->playback_dma_data.addr = regs_base + I2S_TXR_BUFF;
639         i2s->playback_dma_data.addr_width = 4;
640         i2s->playback_dma_data.maxburst = 1;
641
642         i2s->capture_dma_data.addr = regs_base + I2S_RXR_BUFF;
643         i2s->capture_dma_data.addr_width = 4;
644         i2s->capture_dma_data.maxburst = 1;
645
646         i2s->i2s_tx_status = false;
647         i2s->i2s_rx_status = false;
648
649         pm_runtime_enable(&pdev->dev);
650         if (!pm_runtime_enabled(&pdev->dev)) {
651                 ret = rockchip_i2s_resume_noirq(&pdev->dev);
652                 if (ret)
653                         goto err_pm_disable;
654         }
655
656         //set dev name to driver->name.id for sound card register
657         dev_set_name(&pdev->dev, "%s.%d", pdev->dev.driver->name, pdev->id);
658
659         ret = snd_soc_register_component(&pdev->dev, &rockchip_i2s_component,
660                 &rockchip_i2s_dai[pdev->id], 1);
661
662         if (ret) {
663                 dev_err(&pdev->dev, "Could not register DAI: %d\n", ret);
664                 ret = -ENOMEM;
665                 goto err_suspend;
666         }
667
668         ret = rockchip_pcm_platform_register(&pdev->dev);
669         if (ret) {
670                 dev_err(&pdev->dev, "Could not register PCM: %d\n", ret);
671                 goto err_unregister_component;
672         }
673
674         /* Mark ourselves as in TXRX mode so we can run through our cleanup
675          * process without warnings. */
676         rockchip_snd_txctrl(i2s, 0);
677         rockchip_snd_rxctrl(i2s, 0);
678
679         dev_set_drvdata(&pdev->dev, i2s);
680         return 0;
681
682 err_unregister_component:
683         snd_soc_unregister_component(&pdev->dev);
684 err_suspend:
685         if (!pm_runtime_status_suspended(&pdev->dev))
686                 rockchip_i2s_suspend_noirq(&pdev->dev);
687 err_pm_disable:
688         pm_runtime_disable(&pdev->dev);
689 err_clk_put:
690         clk_put(i2s->i2s_clk);
691 err:
692         return ret;
693
694 }
695
696 static int rockchip_i2s_remove(struct platform_device *pdev)
697 {
698         rockchip_pcm_platform_unregister(&pdev->dev);
699         snd_soc_unregister_component(&pdev->dev);
700
701         return 0;
702 }
703
704 #ifdef CONFIG_OF
705 static const struct of_device_id exynos_i2s_match[] = {
706         { .compatible = "rockchip-i2s"},
707         {},
708 };
709 MODULE_DEVICE_TABLE(of, exynos_i2s_match);
710 #endif
711
712 static const struct dev_pm_ops rockchip_i2s_pm_ops = {
713         .suspend_noirq = rockchip_i2s_suspend_noirq,
714         .resume_noirq  = rockchip_i2s_resume_noirq,
715 };
716
717 static struct platform_driver rockchip_i2s_driver = {
718         .probe  = rockchip_i2s_probe,
719         .remove = rockchip_i2s_remove,
720         .driver = {
721                 .name   = "rockchip-i2s",
722                 .owner  = THIS_MODULE,
723                 .of_match_table = of_match_ptr(exynos_i2s_match),
724                 .pm     = &rockchip_i2s_pm_ops,
725         },
726 };
727 module_platform_driver(rockchip_i2s_driver);
728
729 /* Module information */
730 MODULE_AUTHOR("rockchip");
731 MODULE_DESCRIPTION("ROCKCHIP IIS ASoC Interface");
732 MODULE_LICENSE("GPL");
733
734
735 #ifdef CONFIG_PROC_FS
736 #include <linux/proc_fs.h>
737 #include <linux/seq_file.h>
738 static int proc_i2s_show(struct seq_file *s, void *v)
739 {
740
741         struct rk30_i2s_info *i2s = rk30_i2s;
742
743         printk("========Show I2S reg========\n");
744         
745         printk("I2S_TXCR = 0x%08X\n", readl(&(pheadi2s->I2S_TXCR)));
746         printk("I2S_RXCR = 0x%08X\n", readl(&(pheadi2s->I2S_RXCR)));
747         printk("I2S_CKR = 0x%08X\n", readl(&(pheadi2s->I2S_CKR)));
748         printk("I2S_DMACR = 0x%08X\n", readl(&(pheadi2s->I2S_DMACR)));
749         printk("I2S_INTCR = 0x%08X\n", readl(&(pheadi2s->I2S_INTCR)));
750         printk("I2S_INTSR = 0x%08X\n", readl(&(pheadi2s->I2S_INTSR)));
751         printk("I2S_XFER = 0x%08X\n", readl(&(pheadi2s->I2S_XFER)));
752
753         printk("========Show I2S reg========\n");
754 #if 0
755         writel(0x0000000F, &(pheadi2s->I2S_TXCR));
756         writel(0x0000000F, &(pheadi2s->I2S_RXCR));
757         writel(0x00071f1F, &(pheadi2s->I2S_CKR));
758         writel(0x001F0110, &(pheadi2s->I2S_DMACR));
759         writel(0x00000003, &(pheadi2s->I2S_XFER));
760         while(1)
761         {
762                 writel(0x5555aaaa, &(pheadi2s->I2S_TXDR));
763         }               
764 #endif  
765         return 0;
766 }
767
768 static ssize_t i2s_reg_write(struct file *file,
769                 const char __user *user_buf, size_t count, loff_t *ppos)
770 {
771         struct rk30_i2s_info *i2s=rk30_i2s;
772
773         char buf[32];
774         size_t buf_size;
775         char *start = buf;
776         unsigned long value;
777
778         buf_size = min(count, (sizeof(buf)-1));
779         if (copy_from_user(buf, user_buf, buf_size))
780                 return -EFAULT;
781         buf[buf_size] = 0;
782
783         while (*start == ' ')
784                 start++;
785         value = simple_strtoul(start, &start, 10);
786
787         printk("test --- freq = %ld ret=%d\n",value,clk_set_rate(i2s->i2s_clk, value));
788         return buf_size;
789 }
790
791 static int proc_i2s_open(struct inode *inode, struct file *file)
792 {
793         return single_open(file, proc_i2s_show, NULL);
794 }
795
796 static const struct file_operations proc_i2s_fops = {
797         .open           = proc_i2s_open,
798         .read           = seq_read,
799         .write = i2s_reg_write, 
800         .llseek         = seq_lseek,
801         .release        = single_release,
802 };
803
804 static int __init i2s_proc_init(void)
805 {
806         proc_create("i2s_reg", 0, NULL, &proc_i2s_fops);
807         return 0;
808 }
809 late_initcall(i2s_proc_init);
810 #endif /* CONFIG_PROC_FS */
811