2 * rk29_i2s.c -- ALSA SoC ROCKCHIP IIS Audio Layer Platform driver
4 * Driver for rockchip iis audio
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.
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>
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>
30 #include <mach/board.h>
31 #include <mach/hardware.h>
33 #include <mach/gpio.h>
34 #include <mach/iomux.h>
35 #include <mach/dma-pl330.h>
36 #include <linux/spinlock.h>
43 #define I2S_DBG(x...) printk(KERN_INFO x)
45 #define I2S_DBG(x...) do { } while (0)
48 #define pheadi2s ((pI2S_REG)(i2s->regs))
52 struct rk29_i2s_info {
63 struct rockchip_pcm_dma_params *dma_playback;
64 struct rockchip_pcm_dma_params *dma_capture;
70 bool i2s_tx_status;//active = true;
72 spinlock_t spinlock_wr;//write read reg spin_lock
75 static struct snd_soc_dai *rk_cpu_dai=NULL;
76 static struct rk29_dma_client rk29_dma_client_out = {
77 .name = "I2S PCM Stereo Out"
80 static struct rk29_dma_client rk29_dma_client_in = {
81 .name = "I2S PCM Stereo In"
84 static inline struct rk29_i2s_info *to_info(struct snd_soc_dai *cpu_dai)
86 return snd_soc_dai_get_drvdata(cpu_dai);
89 static struct rockchip_pcm_dma_params rk29_i2s_pcm_stereo_out[MAX_I2S];
90 static struct rockchip_pcm_dma_params rk29_i2s_pcm_stereo_in[MAX_I2S];
91 static struct rk29_i2s_info rk29_i2s[MAX_I2S];
93 struct snd_soc_dai_driver rk29_i2s_dai[MAX_I2S];
94 EXPORT_SYMBOL_GPL(rk29_i2s_dai);
95 #if defined (CONFIG_RK_HDMI) && defined (CONFIG_SND_RK_SOC_HDMI_I2S)
96 extern int hdmi_get_hotplug(void);
99 *Turn on or off the transmission path.
101 static void rockchip_snd_txctrl(struct rk29_i2s_info *i2s, int on)
104 spin_lock(&i2s->spinlock_wr);
105 opr = readl(&(pheadi2s->I2S_DMACR));
106 xfer = readl(&(pheadi2s->I2S_XFER));
107 clr = readl(&(pheadi2s->I2S_CLR));
110 I2S_DBG("rockchip_snd_txctrl: on\n");
111 if ((opr & I2S_TRAN_DMA_ENABLE) == 0)
113 opr |= I2S_TRAN_DMA_ENABLE;
114 writel(opr, &(pheadi2s->I2S_DMACR));
116 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));
122 i2s->i2s_tx_status = true;
123 spin_unlock(&i2s->spinlock_wr);
128 i2s->i2s_tx_status = false;
129 I2S_DBG("rockchip_snd_txctrl: off\n");
130 opr &= ~I2S_TRAN_DMA_ENABLE;
131 writel(opr, &(pheadi2s->I2S_DMACR));
132 if(!i2s->i2s_tx_status && !i2s->i2s_rx_status//sync stop i2s rx tx lcrk
133 #if defined (CONFIG_RK_HDMI) && defined (CONFIG_SND_RK_SOC_HDMI_I2S)
134 && hdmi_get_hotplug() == 0 //HDMI_HPD_REMOVED
138 xfer &= ~I2S_TX_TRAN_START;
139 xfer &= ~I2S_RX_TRAN_START;
140 writel(xfer, &(pheadi2s->I2S_XFER));
143 writel(clr, &(pheadi2s->I2S_CLR));
144 spin_unlock(&i2s->spinlock_wr);
146 I2S_DBG("rockchip_snd_txctrl: stop xfer\n");
149 spin_unlock(&i2s->spinlock_wr);
153 static void rockchip_snd_rxctrl(struct rk29_i2s_info *i2s, int on)
156 spin_lock(&i2s->spinlock_wr);
157 opr = readl(&(pheadi2s->I2S_DMACR));
158 xfer = readl(&(pheadi2s->I2S_XFER));
159 clr = readl(&(pheadi2s->I2S_CLR));
162 I2S_DBG("rockchip_snd_rxctrl: on\n");
163 if ((opr & I2S_RECE_DMA_ENABLE) == 0)
165 opr |= I2S_RECE_DMA_ENABLE;
166 writel(opr, &(pheadi2s->I2S_DMACR));
168 if ((xfer&I2S_TX_TRAN_START)==0 || (xfer&I2S_RX_TRAN_START)==0)
170 xfer |= I2S_RX_TRAN_START;
171 xfer |= I2S_TX_TRAN_START;
172 writel(xfer, &(pheadi2s->I2S_XFER));
174 i2s->i2s_rx_status = true;
175 spin_unlock(&i2s->spinlock_wr);
176 #ifdef CONFIG_SND_SOC_RT5631
178 schedule_delayed_work(&rt5631_delay_cap,HZ/4);
184 i2s->i2s_rx_status = false;
185 I2S_DBG("rockchip_snd_rxctrl: off\n");
186 opr &= ~I2S_RECE_DMA_ENABLE;
187 writel(opr, &(pheadi2s->I2S_DMACR));
188 if(!i2s->i2s_tx_status && !i2s->i2s_rx_status //sync stop i2s rx tx lcrk
189 #if defined (CONFIG_RK_HDMI) && defined (CONFIG_SND_RK_SOC_HDMI_I2S)
190 && hdmi_get_hotplug() == 0 //HDMI_HPD_REMOVED
194 xfer &= ~I2S_RX_TRAN_START;
195 xfer &= ~I2S_TX_TRAN_START;
196 writel(xfer, &(pheadi2s->I2S_XFER));
199 writel(clr, &(pheadi2s->I2S_CLR));
200 spin_unlock(&i2s->spinlock_wr);
202 I2S_DBG("rockchip_snd_rxctrl: stop xfer\n");
205 spin_unlock(&i2s->spinlock_wr);
210 * Set Rockchip I2S DAI format
212 static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
215 struct rk29_i2s_info *i2s = to_info(cpu_dai);
217 u32 iis_ckr_value;//clock generation register
219 I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
220 spin_lock(&i2s->spinlock_wr);
221 tx_ctl = readl(&(pheadi2s->I2S_TXCR));
222 iis_ckr_value = readl(&(pheadi2s->I2S_CKR));
224 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
225 case SND_SOC_DAIFMT_CBM_CFM:
226 iis_ckr_value &= ~I2S_MODE_MASK;
227 iis_ckr_value |= I2S_MASTER_MODE;
229 case SND_SOC_DAIFMT_CBS_CFS:
230 iis_ckr_value &= ~I2S_MODE_MASK;
231 iis_ckr_value |= I2S_SLAVE_MODE;
234 I2S_DBG("unknwon master/slave format\n");
237 writel(iis_ckr_value, &(pheadi2s->I2S_CKR));
238 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
239 case SND_SOC_DAIFMT_RIGHT_J:
240 tx_ctl &= ~I2S_BUS_MODE_MASK; //I2S Bus Mode
241 tx_ctl |= I2S_BUS_MODE_RSJM;
243 case SND_SOC_DAIFMT_LEFT_J:
244 tx_ctl &= ~I2S_BUS_MODE_MASK; //I2S Bus Mode
245 tx_ctl |= I2S_BUS_MODE_LSJM;
247 case SND_SOC_DAIFMT_I2S:
248 tx_ctl &= ~I2S_BUS_MODE_MASK; //I2S Bus Mode
249 tx_ctl |= I2S_BUS_MODE_NOR;
252 I2S_DBG("Unknown data format\n");
255 I2S_DBG("Enter::%s----%d, I2S_TXCR=0x%X\n",__FUNCTION__,__LINE__,tx_ctl);
257 writel(tx_ctl, &(pheadi2s->I2S_TXCR));
259 rx_ctl = tx_ctl & 0x00007FFF;
260 writel(rx_ctl, &(pheadi2s->I2S_RXCR));
261 spin_unlock(&i2s->spinlock_wr);
265 static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
266 struct snd_pcm_hw_params *params, struct snd_soc_dai *socdai)
268 struct rk29_i2s_info *i2s = to_info(socdai);
271 u32 iis_ckr_value;//clock generation register
273 I2S_DBG("Enter %s, %d >>>>>>>>>>>\n", __func__, __LINE__);
275 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
276 snd_soc_dai_set_dma_data(socdai, substream, i2s->dma_playback);
278 snd_soc_dai_set_dma_data(socdai, substream, i2s->dma_capture);
280 /* Working copies of register */
281 spin_lock(&i2s->spinlock_wr);
282 iismod = readl(&(pheadi2s->I2S_TXCR));
284 iismod &= (~((1<<5)-1));
285 switch (params_format(params)) {
286 case SNDRV_PCM_FORMAT_S8:
287 iismod |= SAMPLE_DATA_8bit;
289 case SNDRV_PCM_FORMAT_S16_LE:
290 iismod |= I2S_DATA_WIDTH(15);
292 case SNDRV_PCM_FORMAT_S20_3LE:
293 iismod |= I2S_DATA_WIDTH(19);
295 case SNDRV_PCM_FORMAT_S24_LE:
296 iismod |= I2S_DATA_WIDTH(23);
298 case SNDRV_PCM_FORMAT_S32_LE:
299 iismod |= I2S_DATA_WIDTH(31);
303 iis_ckr_value = readl(&(pheadi2s->I2S_CKR));
304 #if defined (CONFIG_SND_RK_CODEC_SOC_SLAVE)
305 iis_ckr_value &= ~I2S_SLAVE_MODE;
307 #if defined (CONFIG_SND_RK_CODEC_SOC_MASTER)
308 iis_ckr_value |= I2S_SLAVE_MODE;
310 writel(iis_ckr_value, &(pheadi2s->I2S_CKR));
312 // writel((16<<24) |(16<<18)|(16<<12)|(16<<6)|16, &(pheadi2s->I2S_FIFOLR));
313 dmarc = readl(&(pheadi2s->I2S_DMACR));
315 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
316 dmarc = ((dmarc & 0xFFFFFE00) | 16);
318 dmarc = ((dmarc & 0xFE00FFFF) | 16<<16);
320 writel(dmarc, &(pheadi2s->I2S_DMACR));
321 I2S_DBG("Enter %s, %d I2S_TXCR=0x%08X\n", __func__, __LINE__, iismod);
323 writel(iismod, &(pheadi2s->I2S_TXCR));
325 iismod = iismod & 0x00007FFF;
326 writel(iismod, &(pheadi2s->I2S_RXCR));
327 spin_unlock(&i2s->spinlock_wr);
331 static int rockchip_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai)
334 struct snd_soc_pcm_runtime *rtd = substream->private_data;
335 struct rk29_i2s_info *i2s = to_info(rtd->cpu_dai);
337 I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
339 case SNDRV_PCM_TRIGGER_START:
340 case SNDRV_PCM_TRIGGER_RESUME:
341 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
342 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
343 rockchip_snd_rxctrl(i2s, 1);
345 rockchip_snd_txctrl(i2s, 1);
348 case SNDRV_PCM_TRIGGER_SUSPEND:
349 case SNDRV_PCM_TRIGGER_STOP:
350 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
351 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
352 rockchip_snd_rxctrl(i2s, 0);
354 rockchip_snd_txctrl(i2s, 0);
365 * Set Rockchip I2S MCLK source
367 static int rockchip_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
368 int clk_id, unsigned int freq, int dir)
370 struct rk29_i2s_info *i2s;
372 i2s = to_info(cpu_dai);
374 I2S_DBG("Enter:%s, %d, i2s=0x%p, freq=%d\n", __FUNCTION__, __LINE__, i2s, freq);
375 /*add scu clk source and enable clk*/
376 clk_set_rate(i2s->iis_clk, freq);
381 * Set Rockchip Clock dividers
383 static int rockchip_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
386 struct rk29_i2s_info *i2s;
389 i2s = to_info(cpu_dai);
391 //stereo mode MCLK/SCK=4
392 spin_lock(&i2s->spinlock_wr);
393 reg = readl(&(pheadi2s->I2S_CKR));
395 I2S_DBG("Enter:%s, %d, div_id=0x%08X, div=0x%08X\n", __FUNCTION__, __LINE__, div_id, div);
397 //when i2s in master mode ,must set codec pll div
399 case ROCKCHIP_DIV_BCLK:
400 reg &= ~I2S_TX_SCLK_DIV_MASK;
401 reg |= I2S_TX_SCLK_DIV(div);
402 reg &= ~I2S_RX_SCLK_DIV_MASK;
403 reg |= I2S_RX_SCLK_DIV(div);
405 case ROCKCHIP_DIV_MCLK:
406 reg &= ~I2S_MCLK_DIV_MASK;
407 reg |= I2S_MCLK_DIV(div);
409 case ROCKCHIP_DIV_PRESCALER:
414 writel(reg, &(pheadi2s->I2S_CKR));
415 spin_unlock(&i2s->spinlock_wr);
419 static int i2s_set_gpio_mode(struct snd_soc_dai *dai)
421 I2S_DBG("Enter %s, %d >>>>>>>>>>>\n", __func__, __LINE__);
423 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
425 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_MCLK));
426 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_SCLK));
427 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_LRCKRX));
428 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_LRCKTX));
429 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_SDI));
430 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_SDO));
432 #elif defined(CONFIG_ARCH_RK30)
434 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_MCLK));
435 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_SCLK));
436 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_LRCKRX));
437 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_LRCKTX));
438 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_SDI));
439 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_SDO0));
440 #ifdef CONFIG_SND_I2SO_USE_EIGHT_CHANNELS
441 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_SDO1));
442 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_SDO2));
443 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_SDO3));
447 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S1_MCLK));
448 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S1_SCLK));
449 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S1_LRCKRX));
450 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S1_LRCKTX));
451 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S1_SDI));
452 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S1_SDO));
455 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S2_MCLK));
456 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S2_SCLK));
457 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S2_LRCKRX));
458 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S2_LRCKTX));
459 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S2_SDI));
460 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S2_SDO));
463 #if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026)
465 #if 0 //iomux --> gps(.ko)
466 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_MCLK));
467 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_SCLK));
468 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_LRCKRX));
469 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_LRCKTX));
470 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_SDI));
471 iomux_set_gpio_mode(iomux_mode_to_gpio(I2S0_SDO));
476 I2S_DBG("Enter:%s, %d, Error For DevId!!!", __FUNCTION__, __LINE__);
482 static int rockchip_i2s_dai_probe(struct snd_soc_dai *dai)
484 I2S_DBG("Enter %s, %d >>>>>>>>>>>\n", __func__, __LINE__);
485 if(rk_cpu_dai == NULL)
488 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
490 iomux_set(I2S0_MCLK);
491 iomux_set(I2S0_SCLK);
492 iomux_set(I2S0_LRCKRX);
493 iomux_set(I2S0_LRCKTX);
497 #elif defined(CONFIG_ARCH_RK30)
499 rk30_mux_api_set(GPIO0A7_I2S8CHSDI_NAME, GPIO0A_I2S_8CH_SDI);
500 rk30_mux_api_set(GPIO0B0_I2S8CHCLK_NAME, GPIO0B_I2S_8CH_CLK);
501 rk30_mux_api_set(GPIO0B1_I2S8CHSCLK_NAME, GPIO0B_I2S_8CH_SCLK);
502 rk30_mux_api_set(GPIO0B2_I2S8CHLRCKRX_NAME, GPIO0B_I2S_8CH_LRCK_RX);
503 rk30_mux_api_set(GPIO0B3_I2S8CHLRCKTX_NAME, GPIO0B_I2S_8CH_LRCK_TX);
504 rk30_mux_api_set(GPIO0B4_I2S8CHSDO0_NAME, GPIO0B_I2S_8CH_SDO0);
505 #ifdef CONFIG_SND_I2SO_USE_EIGHT_CHANNELS
506 rk30_mux_api_set(GPIO0B5_I2S8CHSDO1_NAME, GPIO0B_I2S_8CH_SDO1);
507 rk30_mux_api_set(GPIO0B6_I2S8CHSDO2_NAME, GPIO0B_I2S_8CH_SDO2);
508 rk30_mux_api_set(GPIO0B7_I2S8CHSDO3_NAME, GPIO0B_I2S_8CH_SDO3);
512 rk30_mux_api_set(GPIO0C0_I2S12CHCLK_NAME, GPIO0C_I2S1_2CH_CLK);
513 rk30_mux_api_set(GPIO0C1_I2S12CHSCLK_NAME, GPIO0C_I2S1_2CH_SCLK);
514 rk30_mux_api_set(GPIO0C2_I2S12CHLRCKRX_NAME, GPIO0C_I2S1_2CH_LRCK_RX);
515 rk30_mux_api_set(GPIO0C3_I2S12CHLRCKTX_NAME, GPIO0C_I2S1_2CH_LRCK_TX);
516 rk30_mux_api_set(GPIO0C4_I2S12CHSDI_NAME, GPIO0C_I2S1_2CH_SDI);
517 rk30_mux_api_set(GPIO0C5_I2S12CHSDO_NAME, GPIO0C_I2S1_2CH_SDO);
520 rk30_mux_api_set(GPIO0D0_I2S22CHCLK_SMCCSN0_NAME, GPIO0D_I2S2_2CH_CLK);
521 rk30_mux_api_set(GPIO0D1_I2S22CHSCLK_SMCWEN_NAME, GPIO0D_I2S2_2CH_SCLK);
522 rk30_mux_api_set(GPIO0D2_I2S22CHLRCKRX_SMCOEN_NAME, GPIO0D_I2S2_2CH_LRCK_RX);
523 rk30_mux_api_set(GPIO0D3_I2S22CHLRCKTX_SMCADVN_NAME, GPIO0D_I2S2_2CH_LRCK_TX);
524 rk30_mux_api_set(GPIO0D4_I2S22CHSDI_SMCADDR0_NAME, GPIO0D_I2S2_2CH_SDI);
525 rk30_mux_api_set(GPIO0D5_I2S22CHSDO_SMCADDR1_NAME, GPIO0D_I2S2_2CH_SDO);
528 #if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026)
530 #if 0 //iomux --> gps(.ko)
531 rk30_mux_api_set(GPIO1A0_I2S_MCLK_NAME, GPIO1A_I2S_MCLK);
532 rk30_mux_api_set(GPIO1A1_I2S_SCLK_NAME, GPIO1A_I2S_SCLK);
533 rk30_mux_api_set(GPIO1A2_I2S_LRCKRX_GPS_CLK_NAME, GPIO1A_I2S_LRCKRX);
534 rk30_mux_api_set(GPIO1A3_I2S_LRCKTX_NAME, GPIO1A_I2S_LRCKTX);
535 rk30_mux_api_set(GPIO1A4_I2S_SDO_GPS_MAG_NAME, GPIO1A_I2S_SDO);
536 rk30_mux_api_set(GPIO1A5_I2S_SDI_GPS_SIGN_NAME, GPIO1A_I2S_SDI);
541 I2S_DBG("Enter:%s, %d, Error For DevId!!!", __FUNCTION__, __LINE__);
548 int rockchip_i2s_suspend(struct snd_soc_dai *cpu_dai)
550 I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
555 int rockchip_i2s_resume(struct snd_soc_dai *cpu_dai)
557 I2S_DBG("Enter::%s----%d\n",__FUNCTION__,__LINE__);
562 #define rockchip_i2s_suspend NULL
563 #define rockchip_i2s_resume NULL
567 #define ROCKCHIP_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
569 #define ROCKCHIP_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
570 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
571 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
574 static struct snd_soc_dai_ops rockchip_i2s_dai_ops = {
575 .trigger = rockchip_i2s_trigger,
576 .hw_params = rockchip_i2s_hw_params,
577 .set_fmt = rockchip_i2s_set_fmt,
578 .set_clkdiv = rockchip_i2s_set_clkdiv,
579 .set_sysclk = rockchip_i2s_set_sysclk,
582 static int rk29_i2s_probe(struct platform_device *pdev,
583 struct snd_soc_dai_driver *dai,
584 struct rk29_i2s_info *i2s,
587 struct device *dev = &pdev->dev;
588 struct resource *res;
590 I2S_DBG("Enter %s, %d >>>>>>>>>>>\n", __func__, __LINE__);
594 /* record our i2s structure for later use in the callbacks */
595 dev_set_drvdata(&pdev->dev, i2s);
598 res = platform_get_resource(pdev,
602 dev_err(dev, "Unable to get register resource\n");
606 if (!request_mem_region(res->start, resource_size(res),
608 dev_err(dev, "Unable to request register region\n");
615 i2s->regs = ioremap(base, (res->end - res->start) + 1); ////res));
616 if (i2s->regs == NULL) {
617 dev_err(dev, "cannot ioremap registers\n");
621 i2s->iis_pclk = clk_get(dev, "hclk_i2s");
622 if (IS_ERR(i2s->iis_pclk)) {
623 dev_err(dev, "failed to get iis_clock\n");
627 clk_enable(i2s->iis_pclk);
630 /* Mark ourselves as in TXRX mode so we can run through our cleanup
631 * process without warnings. */
632 rockchip_snd_txctrl(i2s, 0);
633 rockchip_snd_rxctrl(i2s, 0);
638 static int __devinit rockchip_i2s_probe(struct platform_device *pdev)
640 struct rk29_i2s_info *i2s;
641 struct snd_soc_dai_driver *dai;
644 #if defined(CONFIG_SND_I2S_USE_18V)
645 writel_relaxed(0x2000200,RK30_GRF_BASE + GRF_IO_CON4);//bit9: 1,1.8v;0,3.3v
646 #elif defined(CONFIG_SND_I2S_USE_33V)
647 writel_relaxed(0x2000000,RK30_GRF_BASE + GRF_IO_CON4);
650 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
651 //default 8ma 0xF000F = 12ma 0xF0005=4ma 0xF0000=2ma
652 writel_relaxed(0xF000A,RK30_GRF_BASE + GRF_IO_CON1);
654 I2S_DBG("Enter %s, %d pdev->id = %d >>>>>>>>>>>\n", __func__, __LINE__, pdev->id);
656 if(pdev->id >= MAX_I2S) {
657 dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
661 i2s = &rk29_i2s[pdev->id];
662 dai = &rk29_i2s_dai[pdev->id];
664 dai->symmetric_rates = 1;
669 dai->name = "rk_i2s.0";
670 dai->playback.channels_min = 2;
671 dai->playback.channels_max = 8;
674 dai->name = "rk_i2s.1";
675 dai->playback.channels_min = 2;
676 dai->playback.channels_max = 2;
679 dai->name = "rk_i2s.2";
680 dai->playback.channels_min = 2;
681 dai->playback.channels_max = 2;
685 spin_lock_init(&i2s->spinlock_wr);
686 dai->playback.rates = SNDRV_PCM_RATE_8000_192000;
687 dai->playback.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |
688 SNDRV_PCM_FMTBIT_S24_LE| SNDRV_PCM_FMTBIT_S32_LE;
689 dai->capture.channels_min = 2;
690 dai->capture.channels_max = 2;
691 dai->capture.rates = ROCKCHIP_I2S_RATES;
692 dai->capture.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE;
693 dai->probe = rockchip_i2s_dai_probe;
694 dai->ops = &rockchip_i2s_dai_ops;
695 dai->suspend = rockchip_i2s_suspend;
696 dai->resume = rockchip_i2s_resume;
698 i2s->dma_capture = &rk29_i2s_pcm_stereo_in[pdev->id];
699 i2s->dma_playback = &rk29_i2s_pcm_stereo_out[pdev->id];
703 #ifdef CONFIG_ARCH_RK30
705 i2s->dma_capture->channel = DMACH_I2S0_8CH_RX;
706 i2s->dma_capture->dma_addr = RK30_I2S0_8CH_PHYS + I2S_RXR_BUFF;
707 i2s->dma_playback->channel = DMACH_I2S0_8CH_TX;
708 i2s->dma_playback->dma_addr = RK30_I2S0_8CH_PHYS + I2S_TXR_BUFF;
711 i2s->dma_capture->channel = DMACH_I2S1_2CH_RX;
712 i2s->dma_capture->dma_addr = RK30_I2S1_2CH_PHYS + I2S_RXR_BUFF;
713 i2s->dma_playback->channel = DMACH_I2S1_2CH_TX;
714 i2s->dma_playback->dma_addr = RK30_I2S1_2CH_PHYS + I2S_TXR_BUFF;
717 i2s->dma_capture->channel = DMACH_I2S2_2CH_RX;
718 i2s->dma_capture->dma_addr = RK30_I2S2_2CH_PHYS + I2S_RXR_BUFF;
719 i2s->dma_playback->channel = DMACH_I2S2_2CH_TX;
720 i2s->dma_playback->dma_addr = RK30_I2S2_2CH_PHYS + I2S_TXR_BUFF;
723 #if defined(CONFIG_ARCH_RK3188)
725 i2s->dma_capture->channel = DMACH_I2S1_2CH_RX;
726 i2s->dma_capture->dma_addr = RK30_I2S1_2CH_PHYS + I2S_RXR_BUFF;
727 i2s->dma_playback->channel = DMACH_I2S1_2CH_TX;
728 i2s->dma_playback->dma_addr = RK30_I2S1_2CH_PHYS + I2S_TXR_BUFF;
731 #if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026)
733 i2s->dma_capture->channel = DMACH_I2S0_8CH_RX;
734 i2s->dma_capture->dma_addr = RK2928_I2S_PHYS + I2S_RXR_BUFF;
735 i2s->dma_playback->channel = DMACH_I2S0_8CH_TX;
736 i2s->dma_playback->dma_addr = RK2928_I2S_PHYS + I2S_TXR_BUFF;
741 i2s->dma_capture->client = &rk29_dma_client_in;
742 i2s->dma_capture->dma_size = 4;
743 i2s->dma_capture->flag = 0; //add by sxj, used for burst change
744 i2s->dma_playback->client = &rk29_dma_client_out;
745 i2s->dma_playback->dma_size = 4;
746 i2s->dma_playback->flag = 0; //add by sxj, used for burst change
747 i2s->i2s_tx_status = false;
748 i2s->i2s_rx_status = false;
749 #ifdef CONFIG_SND_I2S_DMA_EVENT_STATIC
750 WARN_ON(rk29_dma_request(i2s->dma_playback->channel, i2s->dma_playback->client, NULL));
751 WARN_ON(rk29_dma_request(i2s->dma_capture->channel, i2s->dma_capture->client, NULL));
754 i2s->iis_clk = clk_get(&pdev->dev, "i2s");
755 I2S_DBG("Enter:%s, %d, iis_clk=%p\n", __FUNCTION__, __LINE__, i2s->iis_clk);
756 if (IS_ERR(i2s->iis_clk)) {
757 dev_err(&pdev->dev, "failed to get i2s clk\n");
758 ret = PTR_ERR(i2s->iis_clk);
762 clk_enable(i2s->iis_clk);
763 clk_set_rate(i2s->iis_clk, 11289600);
765 ret = rk29_i2s_probe(pdev, dai, i2s, 0);
769 ret = snd_soc_register_dai(&pdev->dev, dai);
776 /* Not implemented for I2Sv2 core yet */
778 clk_put(i2s->iis_clk);
783 static int rockchip_i2s_suspend_noirq(struct device *dev)
785 struct snd_soc_dai *dai = rk_cpu_dai;
786 I2S_DBG("Enter %s, %d\n", __func__, __LINE__);
788 return i2s_set_gpio_mode(dai);
791 static int rockchip_i2s_resume_noirq(struct device *dev)
793 struct snd_soc_dai *dai = rk_cpu_dai;
794 I2S_DBG("Enter %s, %d\n", __func__, __LINE__);
796 return rockchip_i2s_dai_probe(dai);
799 static const struct dev_pm_ops rockchip_i2s_pm_ops = {
800 .suspend_noirq = rockchip_i2s_suspend_noirq,
801 .resume_noirq = rockchip_i2s_resume_noirq,
804 static int __devexit rockchip_i2s_remove(struct platform_device *pdev)
806 snd_soc_unregister_dai(&pdev->dev);
810 static struct platform_driver rockchip_i2s_driver = {
811 .probe = rockchip_i2s_probe,
812 .remove = __devexit_p(rockchip_i2s_remove),
815 .owner = THIS_MODULE,
816 .pm = &rockchip_i2s_pm_ops,
820 static int __init rockchip_i2s_init(void)
822 I2S_DBG("Enter %s, %d >>>>>>>>>>>\n", __func__, __LINE__);
824 return platform_driver_register(&rockchip_i2s_driver);
826 module_init(rockchip_i2s_init);
828 static void __exit rockchip_i2s_exit(void)
830 platform_driver_unregister(&rockchip_i2s_driver);
832 module_exit(rockchip_i2s_exit);
834 /* Module information */
835 MODULE_AUTHOR("rockchip");
836 MODULE_DESCRIPTION("ROCKCHIP IIS ASoC Interface");
837 MODULE_LICENSE("GPL");
840 #ifdef CONFIG_PROC_FS
841 #include <linux/proc_fs.h>
842 #include <linux/seq_file.h>
843 static int proc_i2s_show(struct seq_file *s, void *v)
845 #ifdef CONFIG_SND_RK_SOC_I2S_8CH
846 struct rk29_i2s_info *i2s=&rk29_i2s[0];
848 #ifdef CONFIG_SND_RK_SOC_I2S_2CH
849 struct rk29_i2s_info *i2s=&rk29_i2s[1];
851 struct rk29_i2s_info *i2s=&rk29_i2s[2];
854 printk("========Show I2S reg========\n");
856 printk("I2S_TXCR = 0x%08X\n", readl(&(pheadi2s->I2S_TXCR)));
857 printk("I2S_RXCR = 0x%08X\n", readl(&(pheadi2s->I2S_RXCR)));
858 printk("I2S_CKR = 0x%08X\n", readl(&(pheadi2s->I2S_CKR)));
859 printk("I2S_DMACR = 0x%08X\n", readl(&(pheadi2s->I2S_DMACR)));
860 printk("I2S_INTCR = 0x%08X\n", readl(&(pheadi2s->I2S_INTCR)));
861 printk("I2S_INTSR = 0x%08X\n", readl(&(pheadi2s->I2S_INTSR)));
862 printk("I2S_XFER = 0x%08X\n", readl(&(pheadi2s->I2S_XFER)));
864 printk("========Show I2S reg========\n");
866 writel(0x0000000F, &(pheadi2s->I2S_TXCR));
867 writel(0x0000000F, &(pheadi2s->I2S_RXCR));
868 writel(0x00071f1F, &(pheadi2s->I2S_CKR));
869 writel(0x001F0110, &(pheadi2s->I2S_DMACR));
870 writel(0x00000003, &(pheadi2s->I2S_XFER));
873 writel(0x5555aaaa, &(pheadi2s->I2S_TXDR));
879 static ssize_t i2s_reg_write(struct file *file,
880 const char __user *user_buf, size_t count, loff_t *ppos)
882 #ifdef CONFIG_SND_RK_SOC_I2S_8CH
883 struct rk29_i2s_info *i2s=&rk29_i2s[0];
885 #ifdef CONFIG_SND_RK_SOC_I2S_2CH
886 struct rk29_i2s_info *i2s=&rk29_i2s[1];
888 struct rk29_i2s_info *i2s=&rk29_i2s[2];
896 buf_size = min(count, (sizeof(buf)-1));
897 if (copy_from_user(buf, user_buf, buf_size))
901 while (*start == ' ')
903 value = simple_strtoul(start, &start, 10);
905 printk("test --- freq = %ld ret=%d\n",value,clk_set_rate(i2s->iis_clk, value));
909 static int proc_i2s_open(struct inode *inode, struct file *file)
911 return single_open(file, proc_i2s_show, NULL);
914 static const struct file_operations proc_i2s_fops = {
915 .open = proc_i2s_open,
917 .write = i2s_reg_write,
919 .release = single_release,
922 static int __init i2s_proc_init(void)
924 proc_create("i2s_reg", 0, NULL, &proc_i2s_fops);
927 late_initcall(i2s_proc_init);
928 #endif /* CONFIG_PROC_FS */