i2s: Remove compiler warnings
[firefly-linux-kernel-4.4.55.git] / sound / soc / rk29 / rk30_i2s.c
1 /*
2  * rk29_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
22 #include <asm/dma.h>
23 #include <sound/core.h>
24 #include <sound/pcm.h>
25 #include <sound/pcm_params.h>
26 #include <sound/initval.h>
27 #include <sound/soc.h>
28 #include <asm/io.h>
29
30 #include <mach/board.h>
31 #include <mach/hardware.h>
32 #include <mach/io.h>
33 #include <mach/gpio.h>
34 #include <mach/iomux.h>
35 #include <mach/dma-pl330.h>
36
37 #include "rk29_pcm.h"
38 #include "rk29_i2s.h"
39
40
41 #if 0
42 #define I2S_DBG(x...) printk(KERN_INFO x)
43 #else
44 #define I2S_DBG(x...) do { } while (0)
45 #endif
46
47 #define pheadi2s  ((pI2S_REG)(i2s->regs))
48
49 #define MAX_I2S          3
50
51 struct rk29_i2s_info {
52         struct device   *dev;
53         void __iomem    *regs;
54         
55         u32     feature;
56
57         struct clk      *iis_clk;
58         struct clk      *iis_pclk;
59
60         unsigned char   master;
61
62         struct rockchip_pcm_dma_params  *dma_playback;
63         struct rockchip_pcm_dma_params  *dma_capture;
64
65         u32              suspend_iismod;
66         u32              suspend_iiscon;
67         u32              suspend_iispsr;
68 };
69
70 static struct rk29_dma_client rk29_dma_client_out = {
71         .name = "I2S PCM Stereo Out"
72 };
73
74 static struct rk29_dma_client rk29_dma_client_in = {
75         .name = "I2S PCM Stereo In"
76 };
77
78 static inline struct rk29_i2s_info *to_info(struct snd_soc_dai *cpu_dai)
79 {
80         return snd_soc_dai_get_drvdata(cpu_dai);
81 }
82
83 static struct rockchip_pcm_dma_params rk29_i2s_pcm_stereo_out[MAX_I2S];
84 static struct rockchip_pcm_dma_params rk29_i2s_pcm_stereo_in[MAX_I2S];
85 static struct rk29_i2s_info rk29_i2s[MAX_I2S];
86
87 struct snd_soc_dai_driver rk29_i2s_dai[MAX_I2S];
88 EXPORT_SYMBOL_GPL(rk29_i2s_dai);
89
90 static u32 i2s0_clk_enter(void)
91 {
92   return 0;
93 }
94
95 static void i2s0_clk_exit(u32 clk)
96 {
97 }
98
99 /* 
100  *Turn on or off the transmission path. 
101  */
102  
103 static int flag_i2s_tx = 0;
104 static int flag_i2s_rx = 0;
105 static void rockchip_snd_txctrl(struct rk29_i2s_info *i2s, int on, bool stopI2S)
106 {
107         u32 opr,xfer;
108         u32 clk;
109
110         opr  = readl(&(pheadi2s->I2S_DMACR));
111         xfer = readl(&(pheadi2s->I2S_XFER));
112
113         if (on) 
114         {         
115                 I2S_DBG("rockchip_snd_txctrl: on\n");
116
117                 //start tx
118                 //if ((flag_i2s_tx == 0) && (flag_i2s_rx == 0))
119                 if ((xfer&I2S_TX_TRAN_START)==0 || (xfer&I2S_RX_TRAN_START)==0)
120                 {
121                         clk = i2s0_clk_enter();
122                         
123                         //if start tx & rx clk, need reset i2s
124                         xfer |= I2S_TX_TRAN_START;
125                         xfer |= I2S_RX_TRAN_START;
126                         writel(xfer, &(pheadi2s->I2S_XFER));
127                         
128                         i2s0_clk_exit(clk);
129                 }
130
131                 if ((opr & I2S_TRAN_DMA_ENABLE) == 0)
132                 {
133                         opr  |= I2S_TRAN_DMA_ENABLE;
134                         writel(opr, &(pheadi2s->I2S_DMACR));         
135                 }
136
137                 flag_i2s_tx = 1;
138         }
139         else
140         {
141                 //stop tx
142                 flag_i2s_tx = 0;
143                 if ((flag_i2s_rx == 0) && (flag_i2s_tx == 0))
144                 {
145                         opr  &= ~I2S_TRAN_DMA_ENABLE;        
146                         writel(opr, &(pheadi2s->I2S_DMACR));  
147                         if(stopI2S)     
148                         {
149                                 clk = i2s0_clk_enter();
150         
151                                 xfer &= ~I2S_RX_TRAN_START;
152                                 xfer &= ~I2S_TX_TRAN_START;
153                                 writel(xfer, &(pheadi2s->I2S_XFER));
154                                 
155                                 i2s0_clk_exit(clk);
156                         }
157
158                         //after stop rx & tx clk, reset i2s
159                         //writel(0x001,&(pheadi2s->I2S_TXRST));
160                         //writel(0x001,&(pheadi2s->I2S_RXRST));
161                 }
162
163                 I2S_DBG("rockchip_snd_txctrl: off\n");
164         } 
165 }
166
167
168 static void rockchip_snd_rxctrl(struct rk29_i2s_info *i2s, int on, bool stopI2S)
169 {
170         u32 opr,xfer;
171         u32 clk;
172
173         opr  = readl(&(pheadi2s->I2S_DMACR));
174         xfer = readl(&(pheadi2s->I2S_XFER));
175
176         if (on) 
177         {                                
178             I2S_DBG("rockchip_snd_rxctrl: on\n");
179             
180                 //start rx
181                 //if ((flag_i2s_tx == 0) && (flag_i2s_rx == 0))
182                 if ((xfer&I2S_TX_TRAN_START)==0 || (xfer&I2S_RX_TRAN_START)==0)
183                 {
184                         clk = i2s0_clk_enter();
185                         
186                         xfer |= I2S_TX_TRAN_START;
187                         xfer |= I2S_RX_TRAN_START;
188                         writel(xfer, &(pheadi2s->I2S_XFER));
189                         
190                         i2s0_clk_exit(clk);
191                 }
192
193                 if ((opr & I2S_RECE_DMA_ENABLE) == 0)
194                 {
195                         opr  |= I2S_RECE_DMA_ENABLE;
196                         writel(opr, &(pheadi2s->I2S_DMACR));
197                 }
198
199           flag_i2s_rx = 1;
200 #ifdef CONFIG_SND_SOC_RT5631
201 //bard 7-16 s
202                 schedule_delayed_work(&rt5631_delay_cap,HZ/4);
203 //bard 7-16 e
204 #endif
205         }
206         else
207         {
208                 //stop rx
209                 flag_i2s_rx = 0;
210                 if ((flag_i2s_rx == 0) && (flag_i2s_tx == 0))
211                 {
212                         opr  &= ~I2S_RECE_DMA_ENABLE;
213                         writel(opr, &(pheadi2s->I2S_DMACR));
214                 
215                         if(stopI2S)     
216                         {
217                                 clk = i2s0_clk_enter();
218                         
219                                 xfer &= ~I2S_RX_TRAN_START;
220                                 xfer &= ~I2S_TX_TRAN_START;
221                                 writel(xfer, &(pheadi2s->I2S_XFER));
222                                 
223                                 i2s0_clk_exit(clk);
224                         } 
225
226                         //after stop rx & tx clk, reset i2s
227                         //writel(0x001,&(pheadi2s->I2S_TXRST));
228                         //writel(0x001,&(pheadi2s->I2S_RXRST));
229                 }               
230                     
231                 I2S_DBG("rockchip_snd_rxctrl: off\n");
232         }
233 }
234
235 /*
236  * Set Rockchip I2S DAI format
237  */
238 static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
239                                                 unsigned int fmt)
240 {
241         struct rk29_i2s_info *i2s = to_info(cpu_dai);   
242         u32 tx_ctl,rx_ctl;
243         u32 iis_ckr_value;//clock generation register
244         
245         I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
246
247         tx_ctl = readl(&(pheadi2s->I2S_TXCR));
248         iis_ckr_value = readl(&(pheadi2s->I2S_CKR));
249         
250         switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
251                 case SND_SOC_DAIFMT_CBM_CFM:    
252                         iis_ckr_value &= ~I2S_MODE_MASK;  
253                         iis_ckr_value |= I2S_MASTER_MODE;
254                         break;
255                 case SND_SOC_DAIFMT_CBS_CFS:
256                         iis_ckr_value &= ~I2S_MODE_MASK;   
257                         iis_ckr_value |= I2S_SLAVE_MODE;
258                         break;
259                 default:
260                         I2S_DBG("unknwon master/slave format\n");
261                         return -EINVAL;
262         }       
263         writel(iis_ckr_value, &(pheadi2s->I2S_CKR));
264         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
265                 case SND_SOC_DAIFMT_RIGHT_J:
266                         tx_ctl &= ~I2S_BUS_MODE_MASK;    //I2S Bus Mode
267                         tx_ctl |= I2S_BUS_MODE_RSJM;
268                         break;
269                 case SND_SOC_DAIFMT_LEFT_J:
270                         tx_ctl &= ~I2S_BUS_MODE_MASK;    //I2S Bus Mode
271                         tx_ctl |= I2S_BUS_MODE_LSJM;
272                         break;
273                 case SND_SOC_DAIFMT_I2S:
274                         tx_ctl &= ~I2S_BUS_MODE_MASK;    //I2S Bus Mode
275                         tx_ctl |= I2S_BUS_MODE_NOR;
276                         break;
277                 default:
278                         I2S_DBG("Unknown data format\n");
279                         return -EINVAL;
280         }
281         I2S_DBG("Enter::%s----%d, I2S_TXCR=0x%X\n",__FUNCTION__,__LINE__,tx_ctl);
282 #if 0//defined(CONFIG_SND_RK29_SOC_alc5631) || defined(CONFIG_SND_RK29_SOC_alc5621)
283         rx_ctl = tx_ctl;
284         rx_ctl &= ~I2S_MODE_MASK;   
285         rx_ctl |= I2S_SLAVE_MODE;  // set tx slave, rx master
286         writel(rx_ctl, &(pheadi2s->I2S_TXCR));
287 #else
288         writel(tx_ctl, &(pheadi2s->I2S_TXCR));
289 #endif
290         rx_ctl = tx_ctl & 0x00007FFF;
291         writel(rx_ctl, &(pheadi2s->I2S_RXCR));
292         return 0;
293 }
294
295 static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
296                                 struct snd_pcm_hw_params *params, struct snd_soc_dai *socdai)
297 {
298         struct rk29_i2s_info *i2s = to_info(socdai);
299         u32 iismod;
300         u32 dmarc;
301         u32 iis_ckr_value;//clock generation register
302                 
303         I2S_DBG("Enter %s, %d >>>>>>>>>>>\n", __func__, __LINE__);
304
305         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
306                 snd_soc_dai_set_dma_data(socdai, substream, i2s->dma_playback);
307         else
308                 snd_soc_dai_set_dma_data(socdai, substream, i2s->dma_capture);
309
310         /* Working copies of register */
311         iismod = readl(&(pheadi2s->I2S_TXCR));
312         
313 //      iismod &= (~((1<<5)-1));
314         switch (params_format(params)) {
315         case SNDRV_PCM_FORMAT_S8:
316                 iismod |= SAMPLE_DATA_8bit;
317                 break;
318         case SNDRV_PCM_FORMAT_S16_LE:
319                 iismod |= I2S_DATA_WIDTH(15);
320                 break;
321         case SNDRV_PCM_FORMAT_S20_3LE:
322                         iismod |= I2S_DATA_WIDTH(19);
323                         break;
324         case SNDRV_PCM_FORMAT_S24_LE:
325                         iismod |= I2S_DATA_WIDTH(23);
326                         break;
327         case SNDRV_PCM_FORMAT_S32_LE:
328                         iismod |= I2S_DATA_WIDTH(31);
329                         break;
330         }
331         
332         iis_ckr_value = readl(&(pheadi2s->I2S_CKR));
333         #if defined (CONFIG_SND_RK29_CODEC_SOC_SLAVE) 
334         iis_ckr_value &= ~I2S_SLAVE_MODE;
335         #endif
336         #if defined (CONFIG_SND_RK29_CODEC_SOC_MASTER) 
337         iis_ckr_value |= I2S_SLAVE_MODE;
338         #endif
339         writel(iis_ckr_value, &(pheadi2s->I2S_CKR));   
340         
341 //      writel((16<<24) |(16<<18)|(16<<12)|(16<<6)|16, &(pheadi2s->I2S_FIFOLR));
342         dmarc = readl(&(pheadi2s->I2S_DMACR));
343
344         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
345                 dmarc = ((dmarc & 0xFFFFFE00) | 16);
346         else
347                 dmarc = ((dmarc & 0xFE00FFFF) | 16<<16);
348
349         writel(dmarc, &(pheadi2s->I2S_DMACR));
350         I2S_DBG("Enter %s, %d I2S_TXCR=0x%08X\n", __func__, __LINE__, iismod);  
351 #if 0//defined(CONFIG_SND_RK29_SOC_alc5631) || defined(CONFIG_SND_RK29_SOC_alc5621)
352         dmarc = iismod;
353         dmarc &= ~I2S_MODE_MASK;   
354         dmarc |= I2S_SLAVE_MODE;     // set tx slave, rx master
355         writel(dmarc, &(pheadi2s->I2S_TXCR));
356 #else
357         writel(iismod, &(pheadi2s->I2S_TXCR));
358 #endif
359         iismod = iismod & 0x00007FFF;
360         writel(iismod, &(pheadi2s->I2S_RXCR));   
361
362         return 0;
363 }
364
365 static int rockchip_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
366 {    
367         int ret = 0;
368         struct snd_soc_pcm_runtime *rtd = substream->private_data;
369         struct rk29_i2s_info *i2s = to_info(rtd->cpu_dai);
370         bool stopI2S = false;
371
372         I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
373         switch (cmd) {
374         case SNDRV_PCM_TRIGGER_START:
375         case SNDRV_PCM_TRIGGER_RESUME:
376         case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:   
377                 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
378                         rockchip_snd_rxctrl(i2s, 1, stopI2S);
379                 else
380                         rockchip_snd_txctrl(i2s, 1, stopI2S);
381                 break;
382         
383         case SNDRV_PCM_TRIGGER_SUSPEND:
384                 stopI2S = true;
385         case SNDRV_PCM_TRIGGER_STOP:
386         case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
387                 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
388                         rockchip_snd_rxctrl(i2s, 0, stopI2S);
389                 else
390                         rockchip_snd_txctrl(i2s, 0, stopI2S);
391                 break;
392         default:
393                 ret = -EINVAL;
394                 break;
395         }
396
397         return ret;
398 }
399
400 /*
401  * Set Rockchip I2S MCLK source
402  */
403 static int rockchip_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
404         int clk_id, unsigned int freq, int dir)
405 {
406         struct rk29_i2s_info *i2s;        
407
408         i2s = to_info(cpu_dai);
409         
410         I2S_DBG("Enter:%s, %d, i2s=0x%p, freq=%d\n", __FUNCTION__, __LINE__, i2s, freq);
411         /*add scu clk source and enable clk*/
412         clk_set_rate(i2s->iis_clk, freq);
413         return 0;
414 }
415
416 /*
417  * Set Rockchip Clock dividers
418  */
419 static int rockchip_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
420         int div_id, int div)
421 {
422         struct rk29_i2s_info *i2s;
423         u32 reg;
424
425         i2s = to_info(cpu_dai);
426         
427         //stereo mode MCLK/SCK=4  
428         reg = readl(&(pheadi2s->I2S_CKR));
429
430         I2S_DBG("Enter:%s, %d, div_id=0x%08X, div=0x%08X\n", __FUNCTION__, __LINE__, div_id, div);
431         
432         //when i2s in master mode ,must set codec pll div
433         switch (div_id) {
434         case ROCKCHIP_DIV_BCLK:
435             reg &= ~I2S_TX_SCLK_DIV_MASK;
436             reg |= I2S_TX_SCLK_DIV(div);
437             reg &= ~I2S_RX_SCLK_DIV_MASK;
438             reg |= I2S_RX_SCLK_DIV(div);                        
439             break;
440         case ROCKCHIP_DIV_MCLK:
441             reg &= ~I2S_MCLK_DIV_MASK;
442             reg |= I2S_MCLK_DIV(div);
443             break;
444         case ROCKCHIP_DIV_PRESCALER:
445             break;
446         default:
447                         return -EINVAL;
448         }
449         writel(reg, &(pheadi2s->I2S_CKR));
450
451         return 0;
452 }
453
454 #ifdef CONFIG_PM
455 int rockchip_i2s_suspend(struct snd_soc_dai *cpu_dai)
456 {
457         I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
458 //      clk_disable(clk);
459         return 0;
460 }
461
462 int rockchip_i2s_resume(struct snd_soc_dai *cpu_dai)
463 {
464         I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
465 //      clk_enable(clk);
466         return 0;
467 }               
468 #else
469 #define rockchip_i2s_suspend NULL
470 #define rockchip_i2s_resume NULL
471 #endif
472
473 #if defined(CONFIG_SND_RK29_SOC_alc5631) || defined(CONFIG_SND_RK29_SOC_alc5621)
474 #define ROCKCHIP_I2S_RATES (SNDRV_PCM_RATE_44100)  //zyy 20110704, playback and record use same sample rate
475 #else
476 #define ROCKCHIP_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
477                             SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
478                             SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
479 #endif
480
481 static struct snd_soc_dai_ops rockchip_i2s_dai_ops = {
482         .trigger = rockchip_i2s_trigger,
483         .hw_params = rockchip_i2s_hw_params,
484         .set_fmt = rockchip_i2s_set_fmt,
485         .set_clkdiv = rockchip_i2s_set_clkdiv,
486         .set_sysclk = rockchip_i2s_set_sysclk,
487 };
488
489 static int rockchip_i2s_dai_probe(struct snd_soc_dai *dai)
490 {       
491         I2S_DBG("Enter %s, %d >>>>>>>>>>>\n", __func__, __LINE__);
492         switch(dai->id) {
493 #if defined(CONFIG_ARCH_RK3066B)
494         case 1:
495                         rk30_mux_api_set(GPIO1C0_I2SCLK_NAME, GPIO1C_I2SCLK);
496                         rk30_mux_api_set(GPIO1C1_I2SSCLK_NAME, GPIO1C_I2SSCLK);
497                         rk30_mux_api_set(GPIO1C2_I2SLRCLKRX_NAME, GPIO1C_I2SLRCLKRX);
498                         rk30_mux_api_set(GPIO1C3_I2SLRCLKTX_NAME, GPIO1C_I2SLRCLKTX);
499                         rk30_mux_api_set(GPIO1C4_I2SSDI_NAME, GPIO1C_I2SSDI);
500                         rk30_mux_api_set(GPIO1C5_I2SSDO_NAME, GPIO1C_I2SSDO);
501                         break;
502 #elif defined(CONFIG_ARCH_RK30)
503         case 0:
504                         rk30_mux_api_set(GPIO0A7_I2S8CHSDI_NAME, GPIO0A_I2S_8CH_SDI);           
505                         rk30_mux_api_set(GPIO0B0_I2S8CHCLK_NAME, GPIO0B_I2S_8CH_CLK);                
506                         rk30_mux_api_set(GPIO0B1_I2S8CHSCLK_NAME, GPIO0B_I2S_8CH_SCLK);
507                         rk30_mux_api_set(GPIO0B2_I2S8CHLRCKRX_NAME, GPIO0B_I2S_8CH_LRCK_RX);
508                         rk30_mux_api_set(GPIO0B3_I2S8CHLRCKTX_NAME, GPIO0B_I2S_8CH_LRCK_TX);    
509                         rk30_mux_api_set(GPIO0B4_I2S8CHSDO0_NAME, GPIO0B_I2S_8CH_SDO0);
510                         //rk30_mux_api_set(GPIO0B5_I2S8CHSDO1_NAME, GPIO0B_I2S_8CH_SDO1);
511                         //rk30_mux_api_set(GPIO0B6_I2S8CHSDO2_NAME, GPIO0B_I2S_8CH_SDO2);
512                         //rk30_mux_api_set(GPIO0B7_I2S8CHSDO3_NAME, GPIO0B_I2S_8CH_SDO3);        
513                         break;
514         case 1:
515                         rk30_mux_api_set(GPIO0C0_I2S12CHCLK_NAME, GPIO0C_I2S1_2CH_CLK);
516                         rk30_mux_api_set(GPIO0C1_I2S12CHSCLK_NAME, GPIO0C_I2S1_2CH_SCLK);
517                         rk30_mux_api_set(GPIO0C2_I2S12CHLRCKRX_NAME, GPIO0C_I2S1_2CH_LRCK_RX);
518                         rk30_mux_api_set(GPIO0C3_I2S12CHLRCKTX_NAME, GPIO0C_I2S1_2CH_LRCK_TX);                          
519                         rk30_mux_api_set(GPIO0C4_I2S12CHSDI_NAME, GPIO0C_I2S1_2CH_SDI);
520                         rk30_mux_api_set(GPIO0C5_I2S12CHSDO_NAME, GPIO0C_I2S1_2CH_SDO);
521                         break;
522         case 2:
523                         rk30_mux_api_set(GPIO0D0_I2S22CHCLK_SMCCSN0_NAME, GPIO0D_I2S2_2CH_CLK);
524                         rk30_mux_api_set(GPIO0D1_I2S22CHSCLK_SMCWEN_NAME, GPIO0D_I2S2_2CH_SCLK);
525                         rk30_mux_api_set(GPIO0D2_I2S22CHLRCKRX_SMCOEN_NAME, GPIO0D_I2S2_2CH_LRCK_RX);
526                         rk30_mux_api_set(GPIO0D3_I2S22CHLRCKTX_SMCADVN_NAME, GPIO0D_I2S2_2CH_LRCK_TX);                          
527                         rk30_mux_api_set(GPIO0D4_I2S22CHSDI_SMCADDR0_NAME, GPIO0D_I2S2_2CH_SDI);
528                         rk30_mux_api_set(GPIO0D5_I2S22CHSDO_SMCADDR1_NAME, GPIO0D_I2S2_2CH_SDO);
529                         break;                          
530 #endif
531 #ifdef CONFIG_ARCH_RK2928
532         case 0:
533         #if 0 //iomux --> gps(.ko)
534                 rk30_mux_api_set(GPIO1A0_I2S_MCLK_NAME, GPIO1A_I2S_MCLK);
535                 rk30_mux_api_set(GPIO1A1_I2S_SCLK_NAME, GPIO1A_I2S_SCLK);
536                 rk30_mux_api_set(GPIO1A2_I2S_LRCKRX_GPS_CLK_NAME, GPIO1A_I2S_LRCKRX);
537                 rk30_mux_api_set(GPIO1A3_I2S_LRCKTX_NAME, GPIO1A_I2S_LRCKTX);
538                 rk30_mux_api_set(GPIO1A4_I2S_SDO_GPS_MAG_NAME, GPIO1A_I2S_SDO);
539                 rk30_mux_api_set(GPIO1A5_I2S_SDI_GPS_SIGN_NAME, GPIO1A_I2S_SDI);
540         #endif
541                 break;
542 #endif
543         default:
544             I2S_DBG("Enter:%s, %d, Error For DevId!!!", __FUNCTION__, __LINE__);
545             return -EINVAL;
546         }
547         return 0;
548 }
549
550 static int rk29_i2s_probe(struct platform_device *pdev,
551                           struct snd_soc_dai_driver *dai,
552                           struct rk29_i2s_info *i2s,
553                           unsigned long base)
554 {
555         struct device *dev = &pdev->dev;
556         struct resource *res;
557
558         I2S_DBG("Enter %s, %d >>>>>>>>>>>\n", __func__, __LINE__);
559
560         i2s->dev = dev;
561
562         /* record our i2s structure for later use in the callbacks */
563         dev_set_drvdata(&pdev->dev, i2s);
564
565         if (!base) {
566                 res = platform_get_resource(pdev,
567                                              IORESOURCE_MEM,
568                                              0);
569                 if (!res) {
570                         dev_err(dev, "Unable to get register resource\n");
571                         return -ENXIO;
572                 }
573
574                 if (!request_mem_region(res->start, resource_size(res),
575                                         "rk29_i2s")) {
576                         dev_err(dev, "Unable to request register region\n");
577                         return -EBUSY;
578                 }
579
580                 base = res->start;
581         }
582
583         i2s->regs = ioremap(base, (res->end - res->start) + 1); ////res));
584         if (i2s->regs == NULL) {
585                 dev_err(dev, "cannot ioremap registers\n");
586                 return -ENXIO;
587         }
588
589         i2s->iis_pclk = clk_get(dev, "hclk_i2s");
590         if (IS_ERR(i2s->iis_pclk)) {
591                 dev_err(dev, "failed to get iis_clock\n");
592                 iounmap(i2s->regs);
593                 return -ENOENT;
594         }
595         clk_enable(i2s->iis_pclk);
596
597
598         /* Mark ourselves as in TXRX mode so we can run through our cleanup
599          * process without warnings. */
600         rockchip_snd_txctrl(i2s, 0, true);
601         rockchip_snd_rxctrl(i2s, 0, true);
602
603         return 0;
604 }
605
606 static int __devinit rockchip_i2s_probe(struct platform_device *pdev)
607 {
608         struct rk29_i2s_info *i2s;
609         struct snd_soc_dai_driver *dai;
610         int    ret;
611
612         I2S_DBG("Enter %s, %d pdev->id = %d >>>>>>>>>>>\n", __func__, __LINE__, pdev->id);
613
614         if(pdev->id >= MAX_I2S) {
615                 dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
616                 return -EINVAL;        
617         }
618
619         i2s = &rk29_i2s[pdev->id];
620         dai = &rk29_i2s_dai[pdev->id];
621         dai->id = pdev->id;
622         dai->symmetric_rates = 1;
623         
624         switch(pdev->id)
625         {
626         case 0:
627                 dai->name = "rk29_i2s.0";
628                 dai->playback.channels_min = 2;
629                 dai->playback.channels_max = 8;
630                 break;
631         case 1:
632                 dai->name = "rk29_i2s.1";
633                 dai->playback.channels_min = 2;
634                 dai->playback.channels_max = 2; 
635                 break;
636         case 2:
637                 dai->name = "rk29_i2s.2";
638                 dai->playback.channels_min = 2;
639                 dai->playback.channels_max = 2;                 
640                 break;
641         }       
642
643         dai->playback.rates = ROCKCHIP_I2S_RATES;
644         dai->playback.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE;
645         dai->capture.channels_min = 2;
646         dai->capture.channels_max = 2;
647         dai->capture.rates = ROCKCHIP_I2S_RATES;//;SNDRV_PCM_RATE_44100
648         dai->capture.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE;
649         dai->probe = rockchip_i2s_dai_probe; 
650         dai->ops = &rockchip_i2s_dai_ops;
651         dai->suspend = rockchip_i2s_suspend;
652         dai->resume = rockchip_i2s_resume;
653
654         i2s->dma_capture = &rk29_i2s_pcm_stereo_in[pdev->id];
655         i2s->dma_playback = &rk29_i2s_pcm_stereo_out[pdev->id];
656         
657         switch(pdev->id)
658         {
659 #ifdef CONFIG_ARCH_RK30
660         case 0:
661                 i2s->dma_capture->channel = DMACH_I2S0_8CH_RX;
662                 i2s->dma_capture->dma_addr = RK30_I2S0_8CH_PHYS + I2S_RXR_BUFF;
663                 i2s->dma_playback->channel = DMACH_I2S0_8CH_TX;
664                 i2s->dma_playback->dma_addr = RK30_I2S0_8CH_PHYS + I2S_TXR_BUFF;                
665                 break;
666         case 1:
667                 i2s->dma_capture->channel = DMACH_I2S1_2CH_RX;
668                 i2s->dma_capture->dma_addr = RK30_I2S1_2CH_PHYS + I2S_RXR_BUFF;
669                 i2s->dma_playback->channel = DMACH_I2S1_2CH_TX;
670                 i2s->dma_playback->dma_addr = RK30_I2S1_2CH_PHYS + I2S_TXR_BUFF;                
671                 break;
672         case 2:
673                 i2s->dma_capture->channel = DMACH_I2S2_2CH_RX;
674                 i2s->dma_capture->dma_addr = RK30_I2S2_2CH_PHYS + I2S_RXR_BUFF;
675                 i2s->dma_playback->channel = DMACH_I2S2_2CH_TX;
676                 i2s->dma_playback->dma_addr = RK30_I2S2_2CH_PHYS + I2S_TXR_BUFF;        
677                 break;
678 #endif
679 #ifdef CONFIG_ARCH_RK2928
680         case 0:
681                 i2s->dma_capture->channel = DMACH_I2S0_8CH_RX;
682                 i2s->dma_capture->dma_addr = RK2928_I2S_PHYS + I2S_RXR_BUFF;
683                 i2s->dma_playback->channel = DMACH_I2S0_8CH_TX;
684                 i2s->dma_playback->dma_addr = RK2928_I2S_PHYS + I2S_TXR_BUFF;           
685                 break;
686 #endif
687         }
688
689         i2s->dma_capture->client = &rk29_dma_client_in;
690         i2s->dma_capture->dma_size = 4;
691         i2s->dma_capture->flag = 0;                     //add by sxj, used for burst change
692         i2s->dma_playback->client = &rk29_dma_client_out;
693         i2s->dma_playback->dma_size = 4;
694         i2s->dma_playback->flag = 0;                    //add by sxj, used for burst change
695 #ifdef CONFIG_SND_I2S_DMA_EVENT_STATIC
696          WARN_ON(rk29_dma_request(i2s->dma_playback->channel, i2s->dma_playback->client, NULL));
697          WARN_ON(rk29_dma_request(i2s->dma_capture->channel, i2s->dma_capture->client, NULL));
698 #endif
699
700         i2s->iis_clk = clk_get(&pdev->dev, "i2s");
701         I2S_DBG("Enter:%s, %d, iis_clk=%p\n", __FUNCTION__, __LINE__, i2s->iis_clk);
702         if (IS_ERR(i2s->iis_clk)) {
703                 dev_err(&pdev->dev, "failed to get i2s clk\n");
704                 ret = PTR_ERR(i2s->iis_clk);
705                 goto err;
706         }
707
708         clk_enable(i2s->iis_clk);
709         clk_set_rate(i2s->iis_clk, 11289600);
710
711         ret = rk29_i2s_probe(pdev, dai, i2s, 0);
712         if (ret)
713                 goto err_clk;
714
715         ret = snd_soc_register_dai(&pdev->dev, dai);
716         if (ret != 0)
717                 goto err_i2sv2;
718 #if 0
719                 writel(0x0000000F, &(pheadi2s->I2S_TXCR));
720                 writel(0x0000000F, &(pheadi2s->I2S_RXCR));
721                 writel(0x00071f1F, &(pheadi2s->I2S_CKR));
722                 writel(0x001F0110, &(pheadi2s->I2S_DMACR));
723                 writel(0x00000003, &(pheadi2s->I2S_XFER));
724                 while(1)
725                 {
726                         writel(0x5555aaaa, &(pheadi2s->I2S_TXDR));
727                 //      msleep(1);
728                 //      printk("-----------------------\n");
729                 }               
730 #endif
731         
732
733
734         return 0;
735
736 err_i2sv2:
737         /* Not implemented for I2Sv2 core yet */
738 err_clk:
739         clk_put(i2s->iis_clk);
740 err:
741         return ret;
742 }
743
744 static int __devexit rockchip_i2s_remove(struct platform_device *pdev)
745 {
746         snd_soc_unregister_dai(&pdev->dev);
747         return 0;
748 }
749
750 static struct platform_driver rockchip_i2s_driver = {
751         .probe  = rockchip_i2s_probe,
752         .remove = __devexit_p(rockchip_i2s_remove),
753         .driver = {
754                 .name   = "rk29_i2s",
755                 .owner  = THIS_MODULE,
756         },
757 };
758
759 static int __init rockchip_i2s_init(void)
760 {
761         I2S_DBG("Enter %s, %d >>>>>>>>>>>\n", __func__, __LINE__);
762         
763         return  platform_driver_register(&rockchip_i2s_driver);
764 }
765 module_init(rockchip_i2s_init);
766
767 static void __exit rockchip_i2s_exit(void)
768 {
769         platform_driver_unregister(&rockchip_i2s_driver);
770 }
771 module_exit(rockchip_i2s_exit);
772
773 /* Module information */
774 MODULE_AUTHOR("rockchip");
775 MODULE_DESCRIPTION("ROCKCHIP IIS ASoC Interface");
776 MODULE_LICENSE("GPL");
777
778
779 #ifdef CONFIG_PROC_FS
780 #include <linux/proc_fs.h>
781 #include <linux/seq_file.h>
782 static int proc_i2s_show(struct seq_file *s, void *v)
783 {
784 #ifdef CONFIG_SND_RK29_SOC_I2S_8CH
785         struct rk29_i2s_info *i2s=&rk29_i2s[0];
786 #else 
787 #ifdef CONFIG_SND_RK29_SOC_I2S_2CH
788         struct rk29_i2s_info *i2s=&rk29_i2s[1];
789 #else
790         struct rk29_i2s_info *i2s=&rk29_i2s[2];
791 #endif
792 #endif
793         printk("========Show I2S reg========\n");
794         
795         printk("I2S_TXCR = 0x%08X\n", readl(&(pheadi2s->I2S_TXCR)));
796         printk("I2S_RXCR = 0x%08X\n", readl(&(pheadi2s->I2S_RXCR)));
797         printk("I2S_CKR = 0x%08X\n", readl(&(pheadi2s->I2S_CKR)));
798         printk("I2S_DMACR = 0x%08X\n", readl(&(pheadi2s->I2S_DMACR)));
799         printk("I2S_INTCR = 0x%08X\n", readl(&(pheadi2s->I2S_INTCR)));
800         printk("I2S_INTSR = 0x%08X\n", readl(&(pheadi2s->I2S_INTSR)));
801         printk("I2S_XFER = 0x%08X\n", readl(&(pheadi2s->I2S_XFER)));
802
803         printk("========Show I2S reg========\n");
804         return 0;
805 }
806
807 static int proc_i2s_open(struct inode *inode, struct file *file)
808 {
809         return single_open(file, proc_i2s_show, NULL);
810 }
811
812 static const struct file_operations proc_i2s_fops = {
813         .open           = proc_i2s_open,
814         .read           = seq_read,
815         .llseek         = seq_lseek,
816         .release        = single_release,
817 };
818
819 static int __init i2s_proc_init(void)
820 {
821         proc_create("i2s_reg", 0, NULL, &proc_i2s_fops);
822         return 0;
823 }
824 late_initcall(i2s_proc_init);
825 #endif /* CONFIG_PROC_FS */
826