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