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