1 --- a/sound/soc/Kconfig
2 +++ b/sound/soc/Kconfig
4 source "sound/soc/tegra/Kconfig"
5 source "sound/soc/txx9/Kconfig"
6 source "sound/soc/ux500/Kconfig"
7 +source "sound/soc/mtk/Kconfig"
10 source "sound/soc/codecs/Kconfig"
11 --- a/sound/soc/Makefile
12 +++ b/sound/soc/Makefile
14 obj-$(CONFIG_SND_SOC) += tegra/
15 obj-$(CONFIG_SND_SOC) += txx9/
16 obj-$(CONFIG_SND_SOC) += ux500/
17 +obj-$(CONFIG_SND_SOC) += mtk/
18 --- a/sound/soc/codecs/Kconfig
19 +++ b/sound/soc/codecs/Kconfig
30 +++ b/sound/soc/mtk/Kconfig
32 +config SND_MT76XX_SOC
33 + tristate "SoC Audio for MT76XX APSoC Machine"
34 + depends on SND_SOC && (SOC_MT7620 || SOC_MT7621)
37 + Say Y or M if you want to add support for codecs attached to
38 + the MTK I2S interface.
41 + prompt "Selected SoC type"
42 + depends on SND_MT76XX_SOC
43 + default SND_MT76XX_SOC_MT7620
45 +config SND_MT76XX_SOC_MT7620
47 + depends on SOC_MT7620
49 +config SND_MT76XX_SOC_MT7628
51 + depends on SOC_MT7620
53 +config SND_MT76XX_SOC_MT7621
55 + depends on SOC_MT7621
59 +config SND_MT76XX_PCM
60 + tristate "MTK SoC Audio PCM Platform"
61 + depends on SND_MT76XX_SOC
63 +config SND_MT76XX_I2S
64 + tristate "MTK SoC I2S Support"
65 + depends on SND_MT76XX_SOC
68 +++ b/sound/soc/mtk/Makefile
70 +KBUILD_CFLAGS += -I$(srctree)
72 +ifeq ($(CONFIG_SND_MT76XX_SOC_MT7620),y)
73 +KBUILD_CFLAGS += -DCONFIG_MT7620 -DCONFIG_RALINK_MT7620
75 +ifeq ($(CONFIG_SND_MT76XX_SOC_MT7628),y)
76 +KBUILD_CFLAGS += -DCONFIG_MT7628 -DCONFIG_RALINK_MT7628
78 +ifeq ($(CONFIG_SOC_MT7620),y)
79 +KBUILD_CFLAGS += -DRALINK_SYSCTL_BASE=0xB0000000
80 +KBUILD_CFLAGS += -DRALINK_INTCL_BASE=0xB0000200
81 +KBUILD_CFLAGS += -DRALINK_PIO_BASE=0xB0000600
82 +KBUILD_CFLAGS += -DRALINK_I2S_BASE=0xB0000A00
83 +KBUILD_CFLAGS += -DRALINK_GDMA_BASE=0xB0002800
84 +KBUILD_CFLAGS += -DCONFIG_GDMA_EVERYBODY
85 +KBUILD_CFLAGS += -DCONFIG_SND_MT76XX_SOC
86 +KBUILD_CFLAGS += -DCONFIG_I2S_WM8960
87 +KBUILD_CFLAGS += -DCONFIG_I2S_MCLK_12P288MHZ
88 +KBUILD_CFLAGS += -DCONFIG_GDMA_EVERYBODY
89 +KBUILD_CFLAGS += -DSURFBOARDINT_DMA=15
90 +KBUILD_CFLAGS += -DRALINK_INTCTL_DMA=128
91 +KBUILD_CFLAGS += -DCONFIG_SND_SOC_WM8960
94 +# MTK APSoC Platform Support
95 +snd-soc-mt76xx-i2s-ctl-objs := i2s_ctrl.o i2s_debug.o #i2c_wm8960.o
96 +snd-soc-mt76xx-pcm-objs := mt76xx_pcm.o
97 +snd-soc-mt76xx-i2s-objs := mt76xx_i2s.o
99 +obj-$(CONFIG_SND_MT76XX_PCM) += snd-soc-mt76xx-pcm.o
100 +obj-$(CONFIG_SND_MT76XX_I2S) += snd-soc-mt76xx-i2s-ctl.o snd-soc-mt76xx-i2s.o
102 +# MTK APSoC Machine Support
103 +snd-soc-mt76xx-machine-objs := mt76xx_machine.o
105 +obj-$(CONFIG_SND_MT76XX_SOC) += i2c_wm8960.o ralink_gdma.o snd-soc-mt76xx-machine.o
110 +++ b/sound/soc/mtk/i2c_wm8960.c
112 +#include <linux/kernel.h>
113 +#include <linux/version.h>
114 +#include <linux/init.h>
115 +#include <linux/module.h>
116 +#include <linux/slab.h>
117 +#include <linux/i2c.h>
118 +#include <linux/delay.h>
119 +#include <linux/interrupt.h>
120 +#include <linux/fs.h>
121 +#include <linux/fcntl.h>
122 +#include <linux/cdev.h>
123 +#if defined(CONFIG_ARCH_MT7623)
125 +#include <mach/mt_gpio.h>
127 +#include "i2c_wm8960.h"
128 +#include "i2s_ctrl.h"
137 +#if defined(CONFIG_ARCH_MT7623)
139 +//static struct i2c_board_info __initdata i2c_devs1 = { I2C_BOARD_INFO("codec_wm8960", (0X34>>1))};
140 +static struct i2c_board_info __initdata i2c_devs1 = { I2C_BOARD_INFO("codec_wm8960", (0X34))};
143 +unsigned long wm_reg_data[56];
144 +struct wm8960_data *wmio;
146 +struct wm8960_data {
147 + struct i2c_client *client;
148 + struct device *dev;
153 +void i2c_WM8960_write(u32 reg, u32 data)
156 + struct i2c_msg msg;
159 +#if defined(CONFIG_ARCH_MT7623)
160 + unsigned int ext_flag = 0;
162 + ext_flag &= 0x7FFFFFFF;
163 + ext_flag |= I2C_A_FILTER_MSG;
164 + ext_flag |= I2C_POLLING_FLAG;
167 + wm_reg_data[reg] = data;
169 + buf[0]= (reg<<1)|(0x01&(data>>8));
170 + buf[1]= (data&0xFF);
172 +#if defined(CONFIG_ARCH_MT7623)
174 + //msg.addr = wmio->client->addr;
175 + msg.addr = wmio->client->addr>>1;
178 + msg.addr = wmio->client->addr>>1;
181 + msg.buf = (char *)buf;
183 +#if defined(CONFIG_ARCH_MT7623)
185 + msg.ext_flag = ext_flag & 0x7FFFFFFF;
188 + ret = i2c_transfer(wmio->client->adapter, &msg, 1);
189 + MSG("[WM8960(%02X)=0x%08X]\n",(unsigned int)reg,(unsigned int)data);
192 + printk("%s: i2c write error!\n", __func__);
197 +// Reset and power up the WM8960
198 +void audiohw_preinit(void)
200 + memset(wm_reg_data, 0 , sizeof(unsigned long)*55);
202 + i2c_WM8960_write(RESET, RESET_RESET); // Reset (0x0F)
205 + wm_reg_data[RESET] = 0xFFFF;
209 +void audiohw_set_apll(int srate)
211 + unsigned long data;
213 + if((srate==8000) || (srate==12000) || (srate==16000) || (srate==24000) || (srate==32000) || (srate==48000))
215 + // Provide 12.288MHz SYSCLK
216 + data = wm_reg_data[PLL1];
217 + i2c_WM8960_write(PLL1, data | PLL1_OPCLKDIV_1 | PLL1_SDM_FRACTIONAL | PLL1_PLLPRESCALE_1 | PLL1_PLLN(0x8)); // PLL1 (0x34)
219 + i2c_WM8960_write(PLL2, PLL2_PLLK_23_16(0x31)); // PLL2 (0x35)
220 + i2c_WM8960_write(PLL3, PLL3_PLLK_15_8(0x26)); // PLL3 (0x36)
221 + i2c_WM8960_write(PLL4, PLL4_PLLK_7_0(0xe9)); // PLL4 (0x37)
223 + else if ((srate==11025) || (srate==22050) || (srate==44100))
225 + //Provide 11.2896MHz SYSCLK
226 + data = wm_reg_data[PLL1];
227 + i2c_WM8960_write(PLL1, data | PLL1_OPCLKDIV_1 | PLL1_SDM_FRACTIONAL | PLL1_PLLPRESCALE_1 | PLL1_PLLN(0x7)); //PLL1 (0x34)
229 + i2c_WM8960_write(PLL2, PLL2_PLLK_23_16(0x86)); //PLL2 (0x35)
230 + i2c_WM8960_write(PLL3, PLL3_PLLK_15_8(0xc2)); //PLL3 (0x36)
231 + i2c_WM8960_write(PLL4, PLL4_PLLK_7_0(0x26)); //PLL4 (0x37)
235 + printk("Not support this srate\n");
241 +void audiohw_set_frequency(int fsel, int pll_en)
243 + MSG("audiohw_set_frequency_=0x%08X\n",fsel);
247 + printk("PLL enable\n");
248 + i2c_WM8960_write(CLOCKING1, (fsel<<3) | CLOCKING1_SYSCLKDIV_2 | CLOCKING1_CLKSEL_PLL); //CLOCKING (0x04)=>0x05
253 + printk("PLL disable\n");
254 + i2c_WM8960_write(CLOCKING1, (fsel<<3));//| CLOCKING1_SYSCLKDIV_2); //CLOCKING (0x04)
260 +int audiohw_set_lineout_vol(int Aout, int vol_l, int vol_r)
262 + MSG("audiohw_set_lineout_vol_\n");
266 + //i2c_WM8960_write(LOUT1, LOUT1_LO1VU|LOUT1_LO1ZC|LOUT1_LOUT1VOL(0x7f)); //LOUT1(0x02)
267 + //i2c_WM8960_write(ROUT1, ROUT1_RO1VU|ROUT1_RO1ZC|ROUT1_ROUT1VOL(0x7f)); //ROUT1(0x03)
268 + i2c_WM8960_write(LOUT1, LOUT1_LO1VU|LOUT1_LO1ZC|LOUT1_LOUT1VOL(vol_l)); //LOUT1(0x02)
269 + i2c_WM8960_write(ROUT1, ROUT1_RO1VU|ROUT1_RO1ZC|ROUT1_ROUT1VOL(vol_r)); //ROUT1(0x03)
272 + i2c_WM8960_write(LSPK, LSPK_SPKLVU|LSPK_SPKLZC| LSPK_SPKLVOL(vol_l));
273 + i2c_WM8960_write(RSPK, RSPK_SPKRVU|RSPK_SPKRZC| RSPK_SPKRVOL(vol_r));
282 +int audiohw_set_linein_vol(int vol_l, int vol_r)
284 + MSG("audiohw_set_linein_vol_\n");
286 + i2c_WM8960_write(LINV, LINV_IPVU|LINV_LINVOL(vol_l)); //LINV(0x00)=>0x12b
287 + i2c_WM8960_write(RINV, RINV_IPVU|RINV_RINVOL(vol_r)); //LINV(0x01)=>0x12b
293 +int audiohw_postinit(int bSlave, int AIn, int AOut, int pll_en, int wordLen24b)
297 + unsigned long data;
299 + if(wm_reg_data[RESET]!=0xFFFF)
304 + MSG("WM8960 slave.....\n");
307 + printk("24 bit word length\n");
308 + i2c_WM8960_write(AINTFCE1, AINTFCE1_WL_24 | AINTFCE1_FORMAT_I2S); //AINTFCE1(0x07)
312 + printk("16 bit word length\n");
313 + i2c_WM8960_write(AINTFCE1, AINTFCE1_WL_16 | AINTFCE1_FORMAT_I2S); //AINTFCE1(0x07)
318 + MSG("WM8960 master.....\n");
319 + i2c_WM8960_write(CLOCKING2, 0x1c4);//CLOCKING2_BCLKDIV(0x1c4)); //CLOCKING2(0x08)
323 + printk("24 bit word length\n");
324 + i2c_WM8960_write(AINTFCE1, AINTFCE1_MS | AINTFCE1_WL_24 | AINTFCE1_FORMAT_I2S); //AINTFCE1(0x07)
328 + printk("16 bit word length\n");
329 + i2c_WM8960_write(AINTFCE1, AINTFCE1_MS | AINTFCE1_WL_16 | AINTFCE1_FORMAT_I2S); //AINTFCE1(0x07)
335 + //From app notes: allow Vref to stabilize to reduce clicks
336 + for(i = 0; i < 1000*HZ; i++);
340 + data = wm_reg_data[PWRMGMT1];
341 + i2c_WM8960_write(PWRMGMT1, data|PWRMGMT1_ADCL|PWRMGMT1_ADCR|PWRMGMT1_AINL |PWRMGMT1_AINR);//|PWRMGMT1_MICB);//PWRMGMT1(0x19)
343 + data = wm_reg_data[ADDITIONAL1];
344 + i2c_WM8960_write(ADDITIONAL1, data|ADDITIONAL1_DATSEL(0x01)); //ADDITIONAL1(0x17)
345 + i2c_WM8960_write(LADCVOL, LADCVOL_LAVU_EN|LADCVOL_LADCVOL(0xc3)); //LADCVOL(0x15)
346 + i2c_WM8960_write(RADCVOL, RADCVOL_RAVU_EN|RADCVOL_RADCVOL(0xc3)); //RADCVOL(0x16)
347 + i2c_WM8960_write(ADCLPATH, ADCLPATH_LMN1|ADCLPATH_LMIC2B);//|ADCLPATH_LMICBOOST_13DB); //ADCLPATH(0x20)=>(0x108)
348 + i2c_WM8960_write(ADCRPATH, ADCRPATH_RMN1|ADCRPATH_RMIC2B);//|ADCRPATH_RMICBOOST_13DB); //ADCRPATH(0x21)=>(0x108)
349 + i2c_WM8960_write(PWRMGMT3, PWRMGMT3_LMIC|PWRMGMT3_RMIC); //PWRMGMT3(0x2f)
351 + //i2c_WM8960_write(LINBMIX, 0x000); //LINBMIX(0x2B)
355 + i2c_WM8960_write(AINTFCE2, 0x40); //FIXME:(0x09)
357 + data = wm_reg_data[PWRMGMT2];
360 + i2c_WM8960_write(PWRMGMT2, data|PWRMGMT2_PLL_EN|PWRMGMT2_DACL|PWRMGMT2_DACR); //PWRMGMT2(0x1a)
364 + i2c_WM8960_write(PWRMGMT2, data|PWRMGMT2_DACL|PWRMGMT2_DACR); //PWRMGMT2(0x1a)
371 + //Power management 2 setting
372 + data = wm_reg_data[PWRMGMT2];
376 + i2c_WM8960_write(PWRMGMT2, data|PWRMGMT2_PLL_EN|PWRMGMT2_DACL|PWRMGMT2_DACR|PWRMGMT2_LOUT1|PWRMGMT2_ROUT1|PWRMGMT2_SPKL|PWRMGMT2_SPKR); //PWRMGMT2(0x1a)
380 + i2c_WM8960_write(PWRMGMT2, data|PWRMGMT2_DACL|PWRMGMT2_DACR|PWRMGMT2_LOUT1|PWRMGMT2_ROUT1|PWRMGMT2_SPKL|PWRMGMT2_SPKR); //PWRMGMT2(0x1a)
386 + i2c_WM8960_write(AINTFCE2, 0x40); //FIXME:(0x09)
388 + i2c_WM8960_write(LEFTGAIN, LEFTGAIN_LDVU|LEFTGAIN_LDACVOL(0xff)); //LEFTGAIN(0x0a)
389 + i2c_WM8960_write(RIGHTGAIN, RIGHTGAIN_RDVU|RIGHTGAIN_RDACVOL(0xff)); //RIGHTGAIN(0x0b)
391 + i2c_WM8960_write(LEFTMIX1, 0x100); //LEFTMIX1(0x22)
392 + i2c_WM8960_write(RIGHTMIX2, 0x100); //RIGHTMIX2(0x25)
394 + data = wm_reg_data[PWRMGMT3]; //FIXME
395 + i2c_WM8960_write(PWRMGMT3, data|PWRMGMT3_ROMIX|PWRMGMT3_LOMIX); //PWRMGMT3(0x2f)
397 + data = wm_reg_data[CLASSDCTRL1]; //CLASSDCTRL1(0x31) SPEAKER FIXME
398 + i2c_WM8960_write(CLASSDCTRL1, 0xf7);//data|CLASSDCTRL1_OP_LRSPK);
400 + data = wm_reg_data[CLASSDCTRL3]; //CLASSDCTRL3(0x33)
401 + i2c_WM8960_write(CLASSDCTRL3, 0xad);//data|(0x1b));
404 + i2c_WM8960_write(DACCTRL1, 0x000); //DACCTRL1(0x05)
406 + data = wm_reg_data[PWRMGMT1];
407 + i2c_WM8960_write(PWRMGMT1, data|0x1c0); //FIXME:PWRMGMT1(0x19)
410 + printk("WM8960 All initial ok!\n");
416 +void audiohw_micboost(int boostgain)
418 + unsigned long data;
420 + data = wm_reg_data[ADCLPATH];
421 + i2c_WM8960_write(ADCLPATH, data|(boostgain << 4));
423 + data = wm_reg_data[ADCRPATH];
424 + i2c_WM8960_write(ADCRPATH, data|(boostgain << 4));
427 +void audiohw_micin(int enableMic)
429 + unsigned long data;
433 + data = wm_reg_data[PWRMGMT1];
434 + i2c_WM8960_write(PWRMGMT1, data|PWRMGMT1_MICB);
439 + data = wm_reg_data[PWRMGMT1];
440 + i2c_WM8960_write(PWRMGMT1, data & (~(PWRMGMT1_MICB)));
445 +void audiohw_mute( bool mute)
447 + //Mute: Set DACMU = 1 to soft-mute the audio DACs.
448 + //Unmute: Set DACMU = 0 to soft-un-mute the audio DACs.
449 + i2c_WM8960_write(DACCTRL1, mute ? DACCTRL1_DACMU : 0);
453 +//Nice shutdown of WM8960 codec
454 +void audiohw_close(void)
456 + i2c_WM8960_write(DACCTRL1,DACCTRL1_DACMU); //0x05->0x08
457 + i2c_WM8960_write(PWRMGMT1, 0x000); //0x19->0x000
459 + i2c_WM8960_write(PWRMGMT2, 0x000); //0x1a->0x000
463 +void audiohw_loopback(int fsel)
467 +void audiohw_codec_exlbk(void)
469 + memset(wm_reg_data, 0 , sizeof(unsigned long)*55);
471 + i2c_WM8960_write(LINV, 0x117); //0x00->0x117
472 + i2c_WM8960_write(RINV, 0x117); //0x01->0x117
473 + i2c_WM8960_write(LOUT1, 0x179); //0x02->0x179
474 + i2c_WM8960_write(ROUT1, 0x179); //0x03->0x179
475 + i2c_WM8960_write(CLOCKING1, 0x00); //0x04->0x00
476 + //i2c_WM8960_write(CLOCKING1, 0x40); //0x04->0x00
477 + i2c_WM8960_write(DACCTRL1, 0x00); //0x05->0x00
478 + i2c_WM8960_write(AINTFCE2, 0x41); //0x09->0x41
479 + i2c_WM8960_write(LADCVOL, 0x1c3); //0x15->0x1c3
480 + i2c_WM8960_write(RADCVOL, 0x1c3); //0x16->0x1c3
481 + i2c_WM8960_write(PWRMGMT1, 0xfc); //0x19->0xfc
482 + i2c_WM8960_write(PWRMGMT2, 0x1e0); //0x1a->0x1e0
483 + i2c_WM8960_write(ADCLPATH, 0x108); //0x20->0x108
484 + i2c_WM8960_write(ADCRPATH, 0x108); //0x21->0x108
485 + i2c_WM8960_write(LEFTMIX1, 0x150); //0x22->0x150
486 + i2c_WM8960_write(RIGHTMIX2, 0x150); //0x25->0x150
487 + i2c_WM8960_write(BYPASS1, 0x00); //0x2d->0x00
488 + i2c_WM8960_write(BYPASS2, 0x00); //0x2e->0x00
489 + i2c_WM8960_write(PWRMGMT3, 0x3c); //0x2f->0x3c
492 +void audiohw_bypass(void)
496 + memset(wm_reg_data, 0 , sizeof(unsigned long)*55);
497 + i2c_WM8960_write(RESET, 0x000); //0x0f(R15)->0x000
499 + for(i = 0; i < 1000*HZ; i++);
501 + i2c_WM8960_write(PWRMGMT1, 0xf0); //0x19(R25)->0xf0
502 + i2c_WM8960_write(PWRMGMT2, 0x60); //0x1a(R26)->0x60
503 + i2c_WM8960_write(PWRMGMT3, 0x3c); //0x2f(R47)->0x3c
504 + i2c_WM8960_write(LINV, 0x117); // 0x00(R0)->0x117
505 + i2c_WM8960_write(RINV, 0x117); // 0x01(R1)->0x117
506 + i2c_WM8960_write(ADCLPATH, 0x108); //0x20(R32)->0x108
507 + i2c_WM8960_write(ADCRPATH, 0x108); //0x21(R33)->0x108
508 + i2c_WM8960_write(BYPASS1, 0x80); //0x2d(R45)->0x80
509 + i2c_WM8960_write(BYPASS2, 0x80); //0x2e(R46)->0x80
510 + i2c_WM8960_write(LOUT1, 0x179); // 0x02(R2)->0x179
511 + i2c_WM8960_write(ROUT1, 0x179); // 0x03(R3)->0x179
513 +EXPORT_SYMBOL(audiohw_set_frequency);
514 +EXPORT_SYMBOL(audiohw_close);
515 +EXPORT_SYMBOL(audiohw_postinit);
516 +EXPORT_SYMBOL(audiohw_preinit);
517 +EXPORT_SYMBOL(audiohw_set_apll);
518 +EXPORT_SYMBOL(audiohw_codec_exlbk);
519 +EXPORT_SYMBOL(audiohw_bypass);
520 +EXPORT_SYMBOL(audiohw_set_lineout_vol);
521 +EXPORT_SYMBOL(audiohw_set_linein_vol);
522 +EXPORT_SYMBOL(audiohw_micin);
523 +EXPORT_SYMBOL(audiohw_mute);
524 +EXPORT_SYMBOL(audiohw_loopback);
525 +EXPORT_SYMBOL(audiohw_micboost);
527 +static int codec_wm8960_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
529 + struct wm8960_data *wm;
531 +printk("*******Enter %s********\n", __func__);
533 + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
536 + wm = devm_kzalloc(&client->dev, sizeof(struct wm8960_data), GFP_KERNEL);
540 +#if defined(CONFIG_ARCH_MT7623)
541 + mt_set_gpio_mode(GPIO242, GPIO_MODE_04);
542 + mt_set_gpio_mode(GPIO243, GPIO_MODE_04);
544 + wm->client = client;
545 + wm->dev = &client->dev;
546 + wm->name = id->name;
547 + i2c_set_clientdata(client, wm);
550 + memset(wm_reg_data, 0 , sizeof(unsigned long)*55);
555 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
556 +static int codec_wm8960_i2c_remove(struct i2c_client *client)
558 +static int __devexit codec_wm8960_i2c_remove(struct i2c_client *client)
561 + struct wm8960_data *wm = i2c_get_clientdata(client);
567 +static const struct i2c_device_id wm8960_id[] = {
568 + { "codec_wm8960", 0 },
572 +static struct i2c_driver codec_wm8960_i2c_driver = {
574 + .name = "codec_wm8960"
576 + .probe = codec_wm8960_i2c_probe,
577 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
578 + .remove = codec_wm8960_i2c_remove,
580 + .remove = __devexit_p(codec_wm8960_i2c_remove),
582 + .id_table = wm8960_id,
584 +static int __init wm8960_i2c_init(void)
586 +#if defined(CONFIG_ARCH_MT7623)
587 + i2c_register_board_info(1, &i2c_devs1, 1);
589 + return i2c_add_driver(&codec_wm8960_i2c_driver);;
592 +static void __exit wm8960_i2c_exit(void)
594 + i2c_del_driver(&codec_wm8960_i2c_driver);
597 +module_init(wm8960_i2c_init);
598 +module_exit(wm8960_i2c_exit);
600 +MODULE_AUTHOR("Ryder Lee <ryder.lee@mediatek.com>");
601 +MODULE_DESCRIPTION("WM8960 I2C client driver");
602 +MODULE_LICENSE("GPL");
605 +++ b/sound/soc/mtk/i2c_wm8960.h
607 +/* wm8960.h -- WM8960 Soc Audio driver */
611 +#define bool unsigned char
615 +/* volume/balance/treble/bass interdependency */
616 +#define VOLUME_MIN -730
617 +#define VOLUME_MAX 60
620 +/* Register addresses and bits */
621 +#define OUTPUT_MUTED 0x2f
622 +#define OUTPUT_0DB 0x79
625 +#define LINV_IPVU (1 << 8) /* FIXME */
626 +#define LINV_LINMUTE (1 << 7)
627 +#define LINV_LIZC (1 << 6)
628 +#define LINV_LINVOL(x) ((x) & 0x3f)
631 +#define RINV_IPVU (1 << 8) /* FIXME */
632 +#define RINV_RINMUTE (1 << 7)
633 +#define RINV_RIZC (1 << 6)
634 +#define RINV_RINVOL(x) ((x) & 0x3f)
637 +#define LOUT1_LO1VU (1 << 8)
638 +#define LOUT1_LO1ZC (1 << 7)
639 +#define LOUT1_LOUT1VOL(x) ((x) & 0x7f)
642 +#define ROUT1_RO1VU (1 << 8)
643 +#define ROUT1_RO1ZC (1 << 7)
644 +#define ROUT1_ROUT1VOL(x) ((x) & 0x7f)
646 +#define CLOCKING1 0x04 /* FIXME */
647 +#define CLOCKING1_ADCDIV(x) (((x) & 0x7) << 6)
648 +#define CLOCKING1_DACDIV(x) (((x) & 0x7) << 3)
649 +#define CLOCKING1_SYSCLKDIV_1 (0 << 1)
650 +#define CLOCKING1_SYSCLKDIV_2 (2 << 1)
651 +#define CLOCKING1_CLKSEL_MCLK (0 << 0)
652 +#define CLOCKING1_CLKSEL_PLL (1 << 0)
654 +#define DACCTRL1 0x05
655 +#define DACCTRL1_DATTENUATE (1 << 7)
656 +#define DACCTRL1_DACMU (1 << 3)
657 +#define DACCTRL1_DEEMPH_48 (3 << 1)
658 +#define DACCTRL1_DEEMPH_44 (2 << 1)
659 +#define DACCTRL1_DEEMPH_32 (1 << 1)
660 +#define DACCTRL1_DEEMPH_NONE (0 << 1)
661 +#define DACCTRL1_DEEMPH(x) ((x) & (0x3 << 1))
663 +#define DACCTRL2 0x06
665 +#define AINTFCE1 0x07
666 +#define AINTFCE1_BCLKINV (1 << 7)
667 +#define AINTFCE1_MS (1 << 6)
668 +#define AINTFCE1_LRSWAP (1 << 5)
669 +#define AINTFCE1_LRP (1 << 4)
670 +#define AINTFCE1_WL_32 (3 << 2)
671 +#define AINTFCE1_WL_24 (2 << 2)
672 +#define AINTFCE1_WL_20 (1 << 2)
673 +#define AINTFCE1_WL_16 (0 << 2)
674 +#define AINTFCE1_WL(x) (((x) & 0x3) << 2)
675 +#define AINTFCE1_FORMAT_DSP (3 << 0)
676 +#define AINTFCE1_FORMAT_I2S (2 << 0)
677 +#define AINTFCE1_FORMAT_LJUST (1 << 0)
678 +#define AINTFCE1_FORMAT_RJUST (0 << 0)
679 +#define AINTFCE1_FORMAT(x) ((x) & 0x3)
682 +#define CLOCKING2 0x08
683 +#define CLOCKING2_DCLKDIV(x) (((x) & 0x7) << 6)
684 +#define CLOCKING2_BCLKDIV(x) (((x) & 0xf) << 0)
686 +#define AINTFCE2 0x09
687 +#define AINTFCE2_ALRCGPIO_ALRC (0 << 6)
688 +#define AINTFCE2_ALRCGPIO_GPIO (1 << 6)
689 +#define AINTFCE2_LOOPBACK (1 << 0)
691 +#define LEFTGAIN 0x0a
692 +#define LEFTGAIN_LDVU (1 << 8)
693 +#define LEFTGAIN_LDACVOL(x) ((x) & 0xff)
695 +#define RIGHTGAIN 0x0b
696 +#define RIGHTGAIN_RDVU (1 << 8)
697 +#define RIGHTGAIN_RDACVOL(x) ((x) & 0xff)
700 +#define RESET_RESET 0x000
703 +#define ALC1_ALCOFF (0x0 << 7)
704 +#define ALC1_ALCRONLY (0x1 << 7)
705 +#define ALC1_ALCLONLY (0x2 << 7)
706 +#define ALC1_ALCSTEREO (0x3 << 7)
707 +#define ALC1_ALCSEL(x) (((x) & 0x3) << 7)
708 +#define ALC1_SET_MAXGAIN(x) ((x & 0x7) << 4)
709 +#define ALC1_GET_MAXGAIN(x) ((x) & (0x7 << 4))
710 +#define ALC1_ALCL(x) ((x) & 0x0f)
713 +#define ALC2_MINGAIN(x) ((x & 0x7) << 4)
714 +#define ALC2_HLD(x) ((x) & 0x0f)
717 +#define ALC3_SET_DCY(x) ((x & 0x0f) << 4)
718 +#define ALC3_GET_DCY(x) ((x) & (0x0f << 4))
719 +#define ALC3_ATK(x) ((x) & 0x0f)
721 +#define NOISEGATE 0x14
722 +#define NOISEGATE_SET_NGTH(x) ((x & 0x1f) << 3)
723 +#define NOISEGATE_GET_NGTH(x) ((x) & (0x1f << 3))
724 +#define NOISEGATE_NGAT_ENABLE 1
726 +#define LADCVOL 0x15
727 +#define LADCVOL_LAVU_EN (1 << 8)
728 +#define LADCVOL_LADCVOL(x) ((x) & 0x0ff)
730 +#define RADCVOL 0x16
731 +#define RADCVOL_RAVU_EN (1 << 8)
732 +#define RADCVOL_RADCVOL(x) ((x) & 0x0ff)
734 +#define ADDITIONAL1 0x17
735 +#define ADDITIONAL1_TSDEN (1 << 8)
736 +#define ADDITIONAL1_VSEL_LOWEST (0 << 6)
737 +#define ADDITIONAL1_VSEL_LOW (1 << 6)
738 +#define ADDITIONAL1_VSEL_DEFAULT2 (2 << 6)
739 +#define ADDITIONAL1_VSEL_DEFAULT (3 << 6)
740 +#define ADDITIONAL1_VSEL(x) (((x) & 0x3) << 6)
741 +#define ADDITIONAL1_DMONOMIX_STEREO (0 << 4)
742 +#define ADDITIONAL1_DMONOMIX_MONO (1 << 4)
743 +#define ADDITIONAL1_DATSEL(x) (((x) & 0x3) << 2)
744 +#define ADDITIONAL1_TOCLKSEL (1 << 1)
745 +#define ADDITIONAL1_TOEN (1 << 0)
747 +#define ADDITIONAL2 0x18
748 +#define ADDITIONAL2_HPSWEN (1 << 6)
749 +#define ADDITIONAL2_HPSWPOL (1 << 5)
750 +#define ADDITIONAL2_TRIS (1 << 3)
751 +#define ADDITIONAL2_LRCM_ON (1 << 2)
753 +#define PWRMGMT1 0x19
754 +#define PWRMGMT1_VMIDSEL_DISABLED (0 << 7)
755 +#define PWRMGMT1_VMIDSEL_50K (1 << 7)
756 +#define PWRMGMT1_VMIDSEL_250K (2 << 7)
757 +#define PWRMGMT1_VMIDSEL_5K (3 << 7)
758 +#define PWRMGMT1_VREF (1 << 6)
759 +#define PWRMGMT1_AINL (1 << 5)
760 +#define PWRMGMT1_AINR (1 << 4)
761 +#define PWRMGMT1_ADCL (1 << 3)
762 +#define PWRMGMT1_ADCR (1 << 2)
763 +#define PWRMGMT1_MICB (1 << 1)
764 +#define PWRMGMT1_DIGENB (1 << 0)
766 +#define PWRMGMT2 0x1a
767 +#define PWRMGMT2_DACL (1 << 8)
768 +#define PWRMGMT2_DACR (1 << 7)
769 +#define PWRMGMT2_LOUT1 (1 << 6)
770 +#define PWRMGMT2_ROUT1 (1 << 5)
771 +#define PWRMGMT2_SPKL (1 << 4)
772 +#define PWRMGMT2_SPKR (1 << 3)
773 +#define PWRMGMT2_OUT3 (1 << 1)
774 +#define PWRMGMT2_PLL_EN (1 << 0)
776 +#define ADDITIONAL3 0x1b
777 +#define ADDITIONAL3_VROI (1 << 6)
778 +#define ADDITIONAL3_OUT3CAP (1 << 3)
779 +#define ADDITIONAL3_ADC_ALC_SR(x) ((x) & 0x7)
781 +#define ANTIPOP1 0x1c
782 +#define ANTIPOP2 0x1d
784 +#define ADCLPATH 0x20
785 +#define ADCLPATH_LMN1 (1 << 8)
786 +#define ADCLPATH_LMP3 (1 << 7)
787 +#define ADCLPATH_LMP2 (1 << 6)
788 +#define ADCLPATH_LMICBOOST_29DB (0x3 << 4)
789 +#define ADCLPATH_LMICBOOST_20DB (0x2 << 4)
790 +#define ADCLPATH_LMICBOOST_13DB (0x1 << 4)
791 +#define ADCLPATH_SET_LMICBOOST(x) ((x & 0x3) << 4)
792 +#define ADCLPATH_LMIC2B (1 << 3)
795 +#define ADCRPATH 0x21
796 +#define ADCRPATH_RMN1 (1 << 8)
797 +#define ADCRPATH_RMP3 (1 << 7)
798 +#define ADCRPATH_RMP2 (1 << 6)
799 +#define ADCRPATH_RMICBOOST_29DB (0x3 << 4)
800 +#define ADCRPATH_RMICBOOST_20DB (0x2 << 4)
801 +#define ADCRPATH_RMICBOOST_13DB (0x1 << 4)
802 +#define ADCRPATH_SET_RMICBOOST(x) ((x & 0x3) << 4)
803 +#define ADCRPATH_RMIC2B (1 << 3)
806 +#define LEFTMIX1 0x22
807 +#define LEFTMIX1_LD2LO (1 << 8)
808 +#define LEFTMIX1_LI2LO (1 << 7)
809 +#define LEFTMIX1_LI2LO_DEFAULT (5 << 4)
810 +#define LEFTMIX1_LI2LOVOL(x) (((x) & 0x7) << 4)
812 +#define RIGHTMIX2 0x25
813 +#define RIGHTMIX2_RD2RO (1 << 8)
814 +#define RIGHTMIX2_RI2RO (1 << 7)
815 +#define RIGHTMIX2_RI2RO_DEFAULT (5 << 4)
816 +#define RIGHTMIX2_RI2ROVOL(x) (((x) & 0x7) << 4)
818 +#define MONOMIX1 0x26
819 +#define MONOMIX1_L2MO (1 << 7)
821 +#define MONOMIX2 0x27
822 +#define MONOMIX2_R2MO (1 << 7)
825 +#define LSPK_SPKLVU (1 << 8)
826 +#define LSPK_SPKLZC (1 << 7)
827 +#define LSPK_SPKLVOL(x) ((x) & 0x7f)
830 +#define RSPK_SPKRVU (1 << 8)
831 +#define RSPK_SPKRZC (1 << 7)
832 +#define RSPK_SPKRVOL(x) ((x) & 0x7f)
835 +#define LINBMIX 0x2b
836 +#define RINBMIX 0x2c
837 +#define BYPASS1 0x2d
838 +#define BYPASS2 0x2e
840 +#define PWRMGMT3 0x2f
841 +#define PWRMGMT3_LMIC (1<<5)
842 +#define PWRMGMT3_RMIC (1<<4)
843 +#define PWRMGMT3_LOMIX (1<<3)
844 +#define PWRMGMT3_ROMIX (1<<2)
846 +#define ADDITIONAL4 0x30
848 +#define CLASSDCTRL1 0x31
849 +#define CLASSDCTRL1_OP_OFF (0<<6)
850 +#define CLASSDCTRL1_OP_LSPK (1<<6)
851 +#define CLASSDCTRL1_OP_RSPK (2<<6)
852 +#define CLASSDCTRL1_OP_LRSPK (3<<6)
854 +#define CLASSDCTRL3 0x33
857 +#define PLL1_OPCLKDIV_1 (0<<6)
858 +#define PLL1_OPCLKDIV_2 (1<<6)
859 +#define PLL1_OPCLKDIV_3 (2<<6)
860 +#define PLL1_OPCLKDIV_4 (3<<6)
861 +#define PLL1_OPCLKDIV_5p5 (4<<6)
862 +#define PLL1_OPCLKDIV_6 (5<<6)
863 +#define PLL1_SDM_INTERGER (0<<5)
864 +#define PLL1_SDM_FRACTIONAL (1<<5)
865 +#define PLL1_PLLPRESCALE_1 (0<<4)
866 +#define PLL1_PLLPRESCALE_2 (1<<4)
867 +#define PLL1_PLLN(x) ((x) & 0xf)
870 +#define PLL2_PLLK_23_16(x) ((x) & 0x1ff)
873 +#define PLL3_PLLK_15_8(x) ((x) & 0x1ff)
876 +#define PLL4_PLLK_7_0(x) ((x) & 0x1ff)
879 +void audiohw_preinit(void);
880 +int audiohw_postinit(int bSlave, int AIn, int AOut, int pll_en, int wordLen24b);
881 +void audiohw_close(void);
882 +void audiohw_set_frequency(int fsel, int pll_en);
883 +void audiohw_mute(bool mute);
884 +void audiohw_micboost(int boostgain);
885 +void audiohw_micin(int enableMic);
886 +void audiohw_set_apll(int srate);
887 +int audiohw_set_lineout_vol(int Aout, int vol_l, int vol_r);
888 +int audiohw_set_linein_vol(int vol_l, int vol_r);
889 +void audiohw_mute( bool mute);
890 +void audiohw_loopback(int fsel);
891 +void audiohw_codec_exlbk(void);
892 +void audiohw_bypass(void);
894 +#endif /* _WM875x_H */
896 +++ b/sound/soc/mtk/i2s_ctrl.c
898 +#include <linux/init.h>
899 +#include <linux/version.h>
900 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
901 +#include <linux/sched.h>
903 +#include <linux/module.h>
904 +#include <linux/kernel.h> /* _printk() */
905 +#include <linux/slab.h> /* kmalloc() */
906 +#include <linux/fs.h> /* everything... */
907 +#include <linux/errno.h> /* error codes */
908 +#include <linux/types.h> /* size_t */
909 +#include <linux/proc_fs.h>
910 +#include <linux/fcntl.h> /* O_ACCMODE */
911 +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,14)
912 +#include <asm/system.h> /* cli(), *_flags */
914 +#include <asm/uaccess.h> /* copy_from/to_user */
915 +#include <linux/interrupt.h>
916 +#include <linux/mm.h>
917 +#include <linux/mm_types.h>
918 +#include <linux/pci.h>
919 +#include <linux/delay.h>
920 +#include "ralink_gdma.h"
921 +#if defined(CONFIG_I2S_WITH_AEC)
922 +#include "../aec/aec_api.h"
925 +#ifdef CONFIG_DEVFS_FS
926 +#include <linux/devfs_fs_kernel.h>
927 +static devfs_handle_t devfs_handle;
930 +#include "i2s_ctrl.h"
932 +#if defined(CONFIG_SND_MT76XX_SOC)
933 +#include <sound/soc/mtk/mt76xx_machine.h>
936 +#if defined(CONFIG_I2S_WM8750)
937 +#include "../codec/i2c_wm8750.h"
939 +#if defined(CONFIG_I2S_WM8751)
940 +#include "../codec/i2c_wm8751.h"
942 +#if defined(CONFIG_I2S_WM8960)
943 +#include "i2c_wm8960.h"
946 +static int i2sdrv_major = 191;
947 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
949 +static struct class *i2smodule_class;
952 +static int _printk(char *fmt, ...)
957 +/* external functions declarations */
958 +#if defined(CONFIG_I2S_WM8960)
959 +extern void audiohw_set_frequency(int fsel, int codec_pll_en);
960 +void audiohw_set_apll(int srate);
961 +#elif defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
962 +extern void audiohw_set_frequency(int fsel);
964 +#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
965 +extern int audiohw_set_lineout_vol(int Aout, int vol_l, int vol_r);
966 +extern int audiohw_set_master_vol(int vol_l, int vol_r);
967 +extern int audiohw_set_linein_vol(int vol_l, int vol_r);
970 +extern void audiohw_micboost(int boostgain);
972 +extern int GdmaI2sTx(uint32_t Src, uint32_t Dst, uint8_t TxNo, uint16_t TransCount,
973 + void (*DoneIntCallback)(uint32_t data),
974 + void (*UnMaskIntCallback)(uint32_t data));
976 +extern int GdmaI2sRx(uint32_t Src, uint32_t Dst, uint8_t RxNo, uint16_t TransCount,
977 + void (*DoneIntCallback)(uint32_t data),
978 + void (*UnMaskIntCallback)(uint32_t data));
980 +extern int GdmaMaskChannel(uint32_t ChNum);
982 +extern int GdmaUnMaskChannel(uint32_t ChNum);
984 +/* internal functions declarations */
985 +irqreturn_t i2s_irq_isr(int irq, void *irqaction);
986 +int i2s_debug_cmd(unsigned int cmd, unsigned long arg);
988 +/* forward declarations for _fops */
989 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
990 +static long i2s_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
992 +static int i2s_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
994 +static int i2s_mmap(struct file *file, struct vm_area_struct *vma);
995 +static int i2s_open(struct inode *inode, struct file *file);
996 +static int i2s_release(struct inode *inode, struct file *file);
997 +int i2s_mmap_alloc(unsigned long size);
998 +int i2s_mmap_remap(struct vm_area_struct *vma, unsigned long size);
1000 +/* global varable definitions */
1001 +i2s_config_type i2s_config;
1002 +i2s_status_type i2s_status;
1003 +i2s_config_type* pi2s_config = &i2s_config;;
1004 +i2s_status_type* pi2s_status = &i2s_status;;
1007 +ugly_hack_sleep_on_timeout(wait_queue_head_t *q, long timeout)
1009 + unsigned long flags;
1010 + wait_queue_t wait;
1012 + init_waitqueue_entry(&wait, current);
1014 + __set_current_state(TASK_INTERRUPTIBLE);
1015 + spin_lock_irqsave(&q->lock, flags);
1016 + __add_wait_queue(q, &wait);
1017 + spin_unlock(&q->lock);
1019 + timeout = schedule_timeout(timeout);
1021 + spin_lock_irq(&q->lock);
1022 + __remove_wait_queue(q, &wait);
1023 + spin_unlock_irqrestore(&q->lock, flags);
1028 +#define interruptible_sleep_on(x) \
1029 + ugly_hack_sleep_on_timeout(x, MAX_SCHEDULE_TIMEOUT);
1032 +#if defined(ARM_ARCH)
1033 +static dma_addr_t i2s_txdma_addr0, i2s_txdma_addr1;
1034 +static dma_addr_t i2s_rxdma_addr0, i2s_rxdma_addr1;
1035 +#define I2S_TX_FIFO_WREG_PHY (I2S_TX_FIFO_WREG & 0x1FFFFFFF)
1036 +#define I2S_RX_FIFO_RREG_PHY (I2S_RX_FIFO_RREG & 0x1FFFFFFF)
1038 +static dma_addr_t i2s_txdma_addr, i2s_rxdma_addr;
1040 +static dma_addr_t i2s_mmap_addr[MAX_I2S_PAGE*2];
1041 + /* 8khz 11.025khz 12khz 16khz 22.05khz 24Khz 32khz 44.1khz 48khz 88.2khz 96khz*/
1042 +unsigned long i2s_inclk_15p625Mhz[11] = {60<<8, 43<<8, 40<<8, 30<<8, 21<<8, 19<<8, 14<<8, 10<<8, 9<<8, 7<<8, 4<<8};
1043 +unsigned long i2s_exclk_12p288Mhz[11] = {47<<8, 34<<8, 31<<8, 23<<8, 16<<8, 15<<8, 11<<8, 8<<8, 7<<8, 5<<8, 3<<8};
1044 +unsigned long i2s_exclk_12Mhz[11] = {46<<8, 33<<8, 30<<8, 22<<8, 16<<8, 15<<8, 11<<8, 8<<8, 7<<8, 5<<8, 3<<8};
1045 +#if defined(CONFIG_I2S_WM8750) || defined(CONFIG_SND_SOC_WM8750)
1046 + /* 8k 11.025k 12k 16k 22.05k 24k 32k 44.1k 48k 88.2k 96k*/
1047 +unsigned long i2s_codec_12p288Mhz[11] = {0x0C, 0x00, 0x10, 0x14, 0x38, 0x38, 0x18, 0x20, 0x00, 0x00, 0x1C};
1048 +unsigned long i2s_codec_12Mhz[11] = {0x0C, 0x32, 0x10, 0x14, 0x37, 0x38, 0x18, 0x22, 0x00, 0x3E, 0x1C};
1049 +unsigned long i2s_codec_24p576Mhz[11] = {0x4C, 0x00, 0x50, 0x54, 0x00, 0x78, 0x58, 0x00, 0x40, 0x00, 0x5C};
1050 +unsigned long i2s_codec_18p432Mhz[11] = {0x0e, 0x32, 0x12, 0x16, 0x36, 0x3a, 0x1a, 0x22, 0x02, 0x3e, 0x1e};
1052 +#if defined(CONFIG_I2S_WM8751) || defined(CONFIG_SND_SOC_WM8751)
1053 +unsigned long i2s_codec_12p288Mhz[11] = {0x04, 0x00, 0x10, 0x14, 0x38, 0x38, 0x18, 0x20, 0x00, 0x00, 0x1C};
1054 +unsigned long i2s_codec_12Mhz[11] = {0x04, 0x32, 0x10, 0x14, 0x37, 0x38, 0x18, 0x22, 0x00, 0x3E, 0x1C};
1056 +#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_SND_SOC_WM8960)
1057 +unsigned long i2s_codec_12p288Mhz[11] = {0x36, 0x24, 0x24, 0x1b, 0x12, 0x12, 0x09, 0x00, 0x00, 0x00, 0x00};
1058 +unsigned long i2s_codec_12Mhz[11] = {0x36, 0x24, 0x24, 0x1b, 0x12, 0x12, 0x09, 0x00, 0x00, 0x00, 0x00};
1060 +EXPORT_SYMBOL(i2s_codec_12p288Mhz);
1061 +EXPORT_SYMBOL(i2s_codec_12Mhz);
1063 +#if defined(CONFIG_RALINK_RT6855A)
1064 + /* 8K 11.025k 12k 16k 22.05k 24k 32k 44.1K 48k 88.2k 96k */
1065 +unsigned long i2s_inclk_int[11] = { 97, 70, 65, 48, 35, 32, 24, 17, 16, 12, 8};
1066 +unsigned long i2s_inclk_comp[11] = { 336, 441, 53, 424, 220, 282, 212, 366, 141, 185, 70};
1067 +#elif defined (CONFIG_RALINK_MT7621)
1068 +#ifdef MT7621_ASIC_BOARD
1069 +#if defined (CONFIG_I2S_MCLK_12P288MHZ)
1070 +unsigned long i2s_inclk_int[11] = { 576, 384, 0, 288, 192, 192, 144, 96, 96, 48, 48};
1071 +unsigned long i2s_inclk_comp[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1072 +#elif defined(CONFIG_I2S_MCLK_12MHZ)
1073 +unsigned long i2s_inclk_int[11] = {1171, 850, 0, 585, 425, 390, 292, 212, 195, 106, 97};
1074 +unsigned long i2s_inclk_comp[11] = { 448, 174, 0, 480, 87, 320, 496, 299, 160, 149, 336};
1076 +#else //MT7621_FPGA_BOARD
1077 +unsigned long i2s_inclk_int[11] = { 529, 384, 0, 264, 192, 176, 132, 96, 88, 48, 44};
1078 +unsigned long i2s_inclk_comp[11] = { 102, 0, 0, 307, 0, 204, 153, 0, 102, 0, 51};
1080 +#elif defined (CONFIG_RALINK_MT7628)
1081 +#ifdef MT7628_ASIC_BOARD
1082 + /* 8K 11.025k 12k 16k 22.05k 24k 32k 44.1K 48k 88.2k 96k 176k 192k */
1083 +unsigned long i2s_inclk_int_16bit[13] = {937, 680, 0, 468, 340, 312, 234, 170, 156, 85, 78, 42, 39};
1084 +unsigned long i2s_inclk_comp_16bit[13]= {256, 139, 0, 384, 69, 256, 192, 34, 128, 17, 64, 267, 32};
1085 +unsigned long i2s_inclk_int_24bit[13] = {625, 404, 0, 312, 226, 208, 156, 113, 104, 56, 52, 28, 26};
1086 +unsigned long i2s_inclk_comp_24bit[13]= { 0, 404, 0, 256, 387, 170, 128, 193, 85, 352, 42, 176, 21};
1088 + /* 8K 11.025k 12k 16k 22.05k 24k 32k 44.1K 48k 88.2k 96k 176k 192k */
1089 +unsigned long i2s_inclk_int_16bit[13] = {468, 340, 0, 234, 170, 156, 117, 85, 78, 42, 39, 21, 19};
1090 +unsigned long i2s_inclk_comp_16bit[13]= {384, 69, 0, 192, 34, 128, 96, 17, 64, 264, 32, 133, 272};
1091 +unsigned long i2s_inclk_int_24bit[13] = {312, 202, 0, 156, 113, 104, 78, 56, 52, 28, 26, 14, 13};
1092 +unsigned long i2s_inclk_comp_24bit[13]= {256, 202, 0, 128, 193, 85, 64, 352, 42, 176, 21, 88, 10};
1094 +#elif defined (CONFIG_ARCH_MT7623)
1095 +#if defined MT7623_ASIC_BOARD
1096 + /* 8K 11.025k 12k 16k 22.05k 24k 32k 44.1K 48k 88.2k 96k 176k 192k */
1097 +unsigned long i2s_inclk_int_16bit[13] = {576, 384, 0, 288, 192, 192, 144, 96, 96, 48, 48, 24, 24};
1098 +unsigned long i2s_inclk_comp_16bit[13]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1099 +unsigned long i2s_inclk_int_24bit[13] = {384, 256, 0, 192, 128, 128, 96, 64, 64, 32, 32, 16, 16};
1100 +unsigned long i2s_inclk_comp_24bit[13]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1102 + /* 8K 11.025k 12k 16k 22.05k 24k 32k 44.1K 48k 88.2k 96k 176k 192k */
1103 +unsigned long i2s_inclk_int_16bit[13] = {72, 48, 0, 36, 24, 24, 18, 12, 12, 6, 6, 3, 3};
1104 +unsigned long i2s_inclk_comp_16bit[13]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1105 +unsigned long i2s_inclk_int_24bit[13] = {48, 32, 0, 24, 16, 16, 12, 8, 8, 4, 4, 2, 2};
1106 +unsigned long i2s_inclk_comp_24bit[13]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1109 + /* 8K 11.025k 12k 16k 22.05k 24k 32k 44.1K 48k 88.2k 96k */
1110 +unsigned long i2s_inclk_int[11] = { 78, 56, 52, 39, 28, 26, 19, 14, 13, 9, 6};
1111 +unsigned long i2s_inclk_comp[11] = { 64, 352, 42, 32, 176, 21, 272, 88, 10, 455, 261};
1114 +#if defined(CONFIG_I2S_WITH_AEC)
1115 +aecFuncTbl_t *aecFuncP;
1117 +/* USB mode 22.05Khz register value in datasheet is 0x36 but will cause slow clock, 0x37 is correct value */
1118 +/* USB mode 44.1Khz register value in datasheet is 0x22 but will cause slow clock, 0x23 is correct value */
1120 +struct tasklet_struct i2s_tx_tasklet;
1121 +struct tasklet_struct i2s_rx_tasklet;
1122 +EXPORT_SYMBOL(i2s_tx_tasklet);
1123 +EXPORT_SYMBOL(i2s_rx_tasklet);
1125 +char test_buf[I2S_PAGE_SIZE];
1126 +char test_buf_1[I2S_PAGE_SIZE];
1127 +char test_buf_2[I2S_PAGE_SIZE];
1129 +static const struct file_operations i2s_fops = {
1130 + owner : THIS_MODULE,
1133 + release : i2s_release,
1134 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
1135 + unlocked_ioctl: i2s_ioctl,
1137 + ioctl : i2s_ioctl,
1141 +int __init i2s_mod_init(void)
1145 + _printk("******* i2s module init **********\n");
1146 + /* register device with kernel */
1147 +#ifdef CONFIG_DEVFS_FS
1148 + if(devfs_register_chrdev(i2sdrv_major, I2SDRV_DEVNAME , &i2s_fops)) {
1149 + _printk(KERN_WARNING " i2s: can't create device node - %s\n", I2SDRV_DEVNAME);
1153 + devfs_handle = devfs_register(NULL, I2SDRV_DEVNAME, DEVFS_FL_DEFAULT, i2sdrv_major, 0,
1154 + S_IFCHR | S_IRUGO | S_IWUGO, &i2s_fops, NULL);
1156 + result = register_chrdev(i2sdrv_major, I2SDRV_DEVNAME, &i2s_fops);
1158 + _printk(KERN_WARNING "i2s: can't get major %d\n",i2sdrv_major);
1162 + if (i2sdrv_major == 0) {
1163 + i2sdrv_major = result; /* dynamic */
1167 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
1169 + i2smodule_class=class_create(THIS_MODULE, I2SDRV_DEVNAME);
1170 + if (IS_ERR(i2smodule_class))
1172 + device_create(i2smodule_class, NULL, MKDEV(i2sdrv_major, 0), I2SDRV_DEVNAME);
1175 +#if defined(CONFIG_I2S_WITH_AEC)
1176 + _printk("AEC FuncP init \n");
1177 + /*Add by mtk04880*/
1178 + aecFuncP = kmalloc(sizeof(aecFuncTbl_t), GFP_KERNEL);
1179 + /*If aecFuncP cannot request memory,it will be ignored in I2S module. Since AEC & I2S are independent
1180 + * when AEC module is inserted,It will return err message (but I2S will keep running without AEC support)
1183 + memset(aecFuncP,0,sizeof(aecFuncTbl_t));
1190 +void i2s_mod_exit(void)
1192 + _printk("************ i2s module exit *************\n");
1193 +#ifdef CONFIG_DEVFS_FS
1194 + devfs_unregister_chrdev(i2sdrv_major, I2SDRV_DEVNAME);
1195 + devfs_unregister(devfs_handle);
1197 + unregister_chrdev(i2sdrv_major, I2SDRV_DEVNAME);
1199 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
1201 + device_destroy(i2smodule_class,MKDEV(i2sdrv_major, 0));
1202 + class_destroy(i2smodule_class);
1208 +int i2s_open(struct inode *inode, struct file *filp)
1210 +#if defined(I2S_HW_INTERRUPT_EN)&&(I2S_SW_IRQ_EN)
1213 + int minor = iminor(inode);
1215 + if (minor >= I2S_MAX_DEV)
1218 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
1219 + MOD_INC_USE_COUNT;
1221 + try_module_get(THIS_MODULE);
1224 + if (filp->f_flags & O_NONBLOCK) {
1225 + MSG("filep->f_flags O_NONBLOCK set\n");
1229 + /* set i2s_config */
1230 + filp->private_data = pi2s_config;
1231 + memset(pi2s_config, 0, sizeof(i2s_config_type));
1232 +#ifdef I2S_STATISTIC
1233 + memset(pi2s_status, 0, sizeof(i2s_status_type));
1235 + i2s_param_init(pi2s_config);
1237 +#if defined(I2S_HW_INTERRUPT_EN)&&(I2S_SW_IRQ_EN)
1238 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
1239 + Ret = request_irq(SURFBOARDINT_I2S, i2s_irq_isr, IRQF_DISABLED, "Ralink_I2S", NULL);
1241 + Ret = request_irq(SURFBOARDINT_I2S, i2s_irq_isr, SA_INTERRUPT, "Ralink_I2S", NULL);
1245 + MSG("IRQ %d is not free.\n", SURFBOARDINT_I2S);
1246 + i2s_release(inode, filp);
1251 + init_waitqueue_head(&(pi2s_config->i2s_tx_qh));
1252 + init_waitqueue_head(&(pi2s_config->i2s_rx_qh));
1253 + spin_lock_init(&pi2s_config->lock);
1259 +static int i2s_release(struct inode *inode, struct file *filp)
1261 + i2s_config_type* ptri2s_config;
1263 + /* decrement usage count */
1264 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
1265 + MOD_DEC_USE_COUNT;
1267 + module_put(THIS_MODULE);
1270 +#if defined(I2S_HW_INTERRUPT_EN)&&(I2S_SW_IRQ_EN)
1271 + free_irq(SURFBOARDINT_I2S, NULL);
1274 + ptri2s_config = filp->private_data;
1275 + if(ptri2s_config==NULL)
1277 +#ifdef CONFIG_I2S_MMAP
1278 + i2s_mem_unmap(ptri2s_config);
1280 + i2s_txbuf_free(ptri2s_config);
1281 + i2s_rxbuf_free(ptri2s_config);
1284 + i2s_txPagebuf_free(ptri2s_config);
1285 + i2s_rxPagebuf_free(ptri2s_config);
1287 + MSG("i2s_release succeeds\n");
1291 +int i2s_mmap_alloc(unsigned long size)
1297 + page_size = I2S_PAGE_SIZE;
1299 + if ((pi2s_config->mmap_index == 0) || (pi2s_config->mmap_index == MAX_I2S_PAGE))
1301 + MSG("mmap_index=%d\n", pi2s_config->mmap_index);
1303 + first_index = pi2s_config->mmap_index;
1304 + pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index] = kmalloc(size, GFP_DMA);
1305 + i2s_mmap_addr[pi2s_config->mmap_index] = (dma_addr_t)dma_map_single(NULL, pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index], size, DMA_BIDIRECTIONAL);
1307 + if( pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index] == NULL )
1309 + MSG("i2s_mmap failed\n");
1315 + _printk("illegal index:%d\n", pi2s_config->mmap_index);
1319 + _printk("MMAP[%d]=0x%08X, i2s_mmap_addr[%d]=0x%08x\n",
1320 + pi2s_config->mmap_index, (u32)pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index],
1321 + pi2s_config->mmap_index, i2s_mmap_addr[pi2s_config->mmap_index]);
1323 + memset(pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index], 0, size);
1324 + pi2s_config->mmap_index++;
1326 + for (i=1; i<MAX_I2S_PAGE; i++)
1328 + i2s_mmap_addr[pi2s_config->mmap_index] = i2s_mmap_addr[first_index] + i*page_size;
1329 + pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index] = pi2s_config->pMMAPBufPtr[first_index] + i*page_size;
1331 + _printk("MMAP[%d]=0x%08X, i2s_mmap_addr[%d]=0x%08x\n",pi2s_config->mmap_index, (u32)pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index], pi2s_config->mmap_index, i2s_mmap_addr[pi2s_config->mmap_index]);
1333 + /* Notice: The last mmap_index's value should be MAX_I2S_PAGE or MAX_I2S_PAGE*2 */
1334 + pi2s_config->mmap_index++;
1340 +int i2s_mmap_remap(struct vm_area_struct *vma, unsigned long size)
1344 + if((pi2s_config->pMMAPBufPtr[0]!=NULL) && (pi2s_config->mmap_index == MAX_I2S_PAGE))
1346 + MSG("i2s_mmap_remap:0\n");
1347 + nRet = remap_pfn_range(vma, vma->vm_start, virt_to_phys((void *)pi2s_config->pMMAPBufPtr[0]) >> PAGE_SHIFT, size, vma->vm_page_prot);
1351 + _printk("i2s_mmap->remap_pfn_range failed\n");
1356 + if((pi2s_config->pMMAPBufPtr[MAX_I2S_PAGE]!=NULL) && (pi2s_config->mmap_index == MAX_I2S_PAGE*2))
1358 + MSG("i2s_mmap_remap:%d\n", MAX_I2S_PAGE);
1360 + nRet = remap_pfn_range(vma, vma->vm_start, virt_to_phys((void *)pi2s_config->pMMAPBufPtr[MAX_I2S_PAGE]) >> PAGE_SHIFT, size, vma->vm_page_prot);
1364 + _printk("i2s_mmap->remap_pfn_range failed\n");
1372 +static int i2s_mmap(struct file *filp, struct vm_area_struct *vma)
1374 + unsigned long size = vma->vm_end-vma->vm_start;
1375 + _printk("page_size=%d, ksize=%lu\n", I2S_PAGE_SIZE, size);
1377 + if((pi2s_config->pMMAPBufPtr[0]==NULL)&&(pi2s_config->mmap_index!=0))
1378 + pi2s_config->mmap_index = 0;
1380 + _printk("%s: vm_start=%08X,vm_end=%08X\n", __func__, (u32)vma->vm_start, (u32)vma->vm_end);
1382 + /* Do memory allocate and dma sync */
1383 + i2s_mmap_alloc(size);
1385 + i2s_mmap_remap(vma, size);
1391 +int i2s_mem_unmap(i2s_config_type* ptri2s_config)
1395 + page_size = I2S_PAGE_SIZE;
1397 + if(ptri2s_config->pMMAPBufPtr[0])
1399 + _printk("ummap MMAP[0]=0x%08X\n", (u32)ptri2s_config->pMMAPBufPtr[0]);
1400 + dma_unmap_single(NULL, i2s_mmap_addr[0], MAX_I2S_PAGE*page_size, DMA_BIDIRECTIONAL);
1401 + kfree(ptri2s_config->pMMAPBufPtr[0]);
1404 + if(ptri2s_config->pMMAPBufPtr[MAX_I2S_PAGE])
1406 + _printk("ummap MMAP[%d]=0x%08X\n", MAX_I2S_PAGE, (u32)ptri2s_config->pMMAPBufPtr[MAX_I2S_PAGE]);
1407 + dma_unmap_single(NULL, i2s_mmap_addr[MAX_I2S_PAGE], MAX_I2S_PAGE*page_size, DMA_BIDIRECTIONAL);
1408 + kfree(ptri2s_config->pMMAPBufPtr[MAX_I2S_PAGE]);
1411 + ptri2s_config->mmap_index = 0;
1416 +int i2s_param_init(i2s_config_type* ptri2s_config)
1418 + ptri2s_config->dmach = GDMA_I2S_TX0;
1419 + ptri2s_config->tx_ff_thres = CONFIG_I2S_TFF_THRES;
1420 + ptri2s_config->tx_ch_swap = CONFIG_I2S_CH_SWAP;
1421 + ptri2s_config->rx_ff_thres = CONFIG_I2S_TFF_THRES;
1422 + ptri2s_config->rx_ch_swap = CONFIG_I2S_CH_SWAP;
1423 + ptri2s_config->slave_en = CONFIG_I2S_SLAVE_EN;
1424 + ptri2s_config->codec_pll_en = CONFIG_I2S_CODEC_PLL_EN;
1426 + ptri2s_config->bRxDMAEnable = 0;
1427 + ptri2s_config->bTxDMAEnable = 0;
1428 + //ptri2s_config->bALSAEnable = 0;
1429 + ptri2s_config->srate = 44100;
1430 + ptri2s_config->txvol = 0;
1431 + ptri2s_config->rxvol = 0;
1432 + ptri2s_config->lbk = 0;
1433 + ptri2s_config->extlbk = 0;
1434 + ptri2s_config->txrx_coexist = 0;
1435 + ptri2s_config->wordlen_24b = 0;
1436 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
1437 + ptri2s_config->sys_endian = 0;
1438 + ptri2s_config->fmt = 0;
1440 + ptri2s_config->micboost = 0;
1441 + ptri2s_config->micin = 0;
1446 +int i2s_txbuf_alloc(i2s_config_type* ptri2s_config)
1450 + for( i = 0 ; i < MAX_I2S_PAGE ; i ++ )
1452 +#if defined(CONFIG_I2S_MMAP)
1453 + ptri2s_config->pMMAPTxBufPtr[i] = ptri2s_config->pMMAPBufPtr[i];
1455 + if(ptri2s_config->pMMAPTxBufPtr[i]==NULL)
1456 + ptri2s_config->pMMAPTxBufPtr[i] = kmalloc(I2S_PAGE_SIZE, GFP_KERNEL);
1458 + memset(ptri2s_config->pMMAPTxBufPtr[i], 0, I2S_PAGE_SIZE);
1464 +int i2s_rxbuf_alloc(i2s_config_type* ptri2s_config)
1468 + for( i = 0 ; i < MAX_I2S_PAGE ; i ++ )
1470 +#if defined(CONFIG_I2S_MMAP)
1471 + ptri2s_config->pMMAPRxBufPtr[i] = ptri2s_config->pMMAPBufPtr[i+(ptri2s_config->mmap_index-MAX_I2S_PAGE)];
1473 + if(ptri2s_config->pMMAPRxBufPtr[i]==NULL)
1474 + ptri2s_config->pMMAPRxBufPtr[i] = kmalloc(I2S_PAGE_SIZE, GFP_KERNEL);
1476 + memset(ptri2s_config->pMMAPRxBufPtr[i], 0, I2S_PAGE_SIZE);
1482 +int i2s_txPagebuf_alloc(i2s_config_type* ptri2s_config)
1484 +#if defined(ARM_ARCH)
1485 + ptri2s_config->pPage0TxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE , &i2s_txdma_addr0);
1486 + ptri2s_config->pPage1TxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE , &i2s_txdma_addr1);
1487 + if(ptri2s_config->pPage0TxBuf8ptr==NULL)
1489 + MSG("Allocate Tx Page0 Buffer Failed\n");
1492 + if(ptri2s_config->pPage1TxBuf8ptr==NULL)
1494 + MSG("Allocate Tx Page1 Buffer Failed\n");
1498 + ptri2s_config->pPage0TxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE*2 , &i2s_txdma_addr);
1499 + if(ptri2s_config->pPage0TxBuf8ptr==NULL)
1501 + MSG("Allocate Tx Page Buffer Failed\n");
1504 + ptri2s_config->pPage1TxBuf8ptr = ptri2s_config->pPage0TxBuf8ptr + I2S_PAGE_SIZE;
1509 +int i2s_rxPagebuf_alloc(i2s_config_type* ptri2s_config)
1511 +#if defined(ARM_ARCH)
1512 + ptri2s_config->pPage0RxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE, &i2s_rxdma_addr0);
1513 + ptri2s_config->pPage1RxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE, &i2s_rxdma_addr1);
1514 + if(ptri2s_config->pPage0RxBuf8ptr==NULL)
1516 + MSG("Allocate Rx Page Buffer Failed\n");
1519 + if(ptri2s_config->pPage1RxBuf8ptr==NULL)
1521 + MSG("Allocate Rx Page Buffer Failed\n");
1525 + ptri2s_config->pPage0RxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE*2 , &i2s_rxdma_addr);
1526 + if(ptri2s_config->pPage0RxBuf8ptr==NULL)
1528 + MSG("Allocate Rx Page Buffer Failed\n");
1531 + ptri2s_config->pPage1RxBuf8ptr = ptri2s_config->pPage0RxBuf8ptr + I2S_PAGE_SIZE;
1536 +int i2s_txbuf_free(i2s_config_type* ptri2s_config)
1540 + for(i = 0 ; i < MAX_I2S_PAGE ; i ++)
1542 + if(ptri2s_config->pMMAPTxBufPtr[i] != NULL)
1544 +#if defined(CONFIG_I2S_MMAP)
1545 + ptri2s_config->pMMAPTxBufPtr[i] = NULL;
1547 + kfree(ptri2s_config->pMMAPTxBufPtr[i]);
1548 + ptri2s_config->pMMAPTxBufPtr[i] = NULL;
1555 +int i2s_rxbuf_free(i2s_config_type* ptri2s_config)
1559 + for(i = 0 ; i < MAX_I2S_PAGE ; i ++)
1561 + if(ptri2s_config->pMMAPRxBufPtr[i] != NULL)
1563 +#if defined(CONFIG_I2S_MMAP)
1564 + ptri2s_config->pMMAPRxBufPtr[i] = NULL;
1566 + kfree(ptri2s_config->pMMAPRxBufPtr[i]);
1567 + ptri2s_config->pMMAPRxBufPtr[i] = NULL;
1575 +int i2s_txPagebuf_free(i2s_config_type* ptri2s_config)
1577 +#if defined(ARM_ARCH)
1578 + if (ptri2s_config->pPage0TxBuf8ptr)
1580 + pci_free_consistent(NULL, I2S_PAGE_SIZE, ptri2s_config->pPage0TxBuf8ptr, i2s_txdma_addr0);
1581 + ptri2s_config->pPage0TxBuf8ptr = NULL;
1584 + if (ptri2s_config->pPage1TxBuf8ptr)
1586 + pci_free_consistent(NULL, I2S_PAGE_SIZE, ptri2s_config->pPage1TxBuf8ptr, i2s_txdma_addr1);
1587 + ptri2s_config->pPage1TxBuf8ptr = NULL;
1589 + _printk("Free tx page buffer\n");
1591 + if (ptri2s_config->pPage0TxBuf8ptr)
1593 + pci_free_consistent(NULL, I2S_PAGE_SIZE*2, ptri2s_config->pPage0TxBuf8ptr, i2s_txdma_addr);
1594 + ptri2s_config->pPage0TxBuf8ptr = NULL;
1601 +int i2s_rxPagebuf_free(i2s_config_type* ptri2s_config)
1603 +#if defined(ARM_ARCH)
1604 + if (ptri2s_config->pPage0RxBuf8ptr)
1606 + pci_free_consistent(NULL, I2S_PAGE_SIZE, ptri2s_config->pPage0RxBuf8ptr, i2s_rxdma_addr0);
1607 + ptri2s_config->pPage0RxBuf8ptr = NULL;
1609 + if (ptri2s_config->pPage1RxBuf8ptr)
1611 + pci_free_consistent(NULL, I2S_PAGE_SIZE, ptri2s_config->pPage1RxBuf8ptr, i2s_rxdma_addr1);
1612 + ptri2s_config->pPage1RxBuf8ptr = NULL;
1614 + _printk("Free rx page buffer\n");
1616 + if (ptri2s_config->pPage0RxBuf8ptr)
1618 + pci_free_consistent(NULL, I2S_PAGE_SIZE*2, ptri2s_config->pPage0RxBuf8ptr, i2s_rxdma_addr);
1619 + ptri2s_config->pPage0RxBuf8ptr = NULL;
1625 +int i2s_reset_tx_param(i2s_config_type* ptri2s_config)
1627 + ptri2s_config->tx_isr_cnt = 0;
1628 + ptri2s_config->tx_w_idx = 0;
1629 + ptri2s_config->tx_r_idx = 0;
1630 + ptri2s_config->enLable = 0;
1631 + ptri2s_config->tx_pause_en = 0;
1632 + ptri2s_config->end_cnt = 0;
1633 + ptri2s_config->tx_stop_cnt = 0;
1635 +#ifdef I2S_STATISTIC
1636 + pi2s_status->txbuffer_unrun = 0;
1637 + pi2s_status->txbuffer_ovrun = 0;
1638 + pi2s_status->txdmafault = 0;
1639 + pi2s_status->txovrun = 0;
1640 + pi2s_status->txunrun = 0;
1641 + pi2s_status->txthres = 0;
1642 + pi2s_status->txbuffer_len = 0;
1648 +int i2s_reset_rx_param(i2s_config_type* ptri2s_config)
1650 + ptri2s_config->rx_isr_cnt = 0;
1651 + ptri2s_config->rx_w_idx = 0;
1652 + ptri2s_config->rx_r_idx = 0;
1653 + ptri2s_config->enLable = 0;
1654 + ptri2s_config->rx_pause_en = 0;
1655 + ptri2s_config->rx_stop_cnt = 0;
1657 +#ifdef I2S_STATISTIC
1658 + pi2s_status->rxbuffer_unrun = 0;
1659 + pi2s_status->rxbuffer_ovrun = 0;
1660 + pi2s_status->rxdmafault = 0;
1661 + pi2s_status->rxovrun = 0;
1662 + pi2s_status->rxunrun = 0;
1663 + pi2s_status->rxthres = 0;
1664 + pi2s_status->rxbuffer_len = 0;
1669 +#ifdef MT7621_ASIC_BOARD
1670 +int i2s_pll_config_mt7621(unsigned long index)
1672 + unsigned long data;
1673 + unsigned long regValue;
1674 + bool xtal_20M_en = 0;
1675 +// bool xtal_25M_en = 0;
1676 + bool xtal_40M_en = 0;
1678 + regValue = i2s_inw(RALINK_SYSCTL_BASE + 0x10);
1679 + regValue = (regValue >> 6) & 0x7;
1683 + MSG("Xtal is 20MHz. \n");
1685 + else if (regValue < 6)
1688 + MSG("Xtal is 40M.\n");
1692 + //xtal_25M_en = 1;
1693 + MSG("Xtal is 25M.\n");
1696 +#if defined (CONFIG_I2S_MCLK_12P288MHZ)
1697 + _printk("MT7621 provide 12.288M/11.298MHz REFCLK\n");
1698 + /* Firstly, reset all required register to default value */
1699 + i2s_outw(RALINK_ANA_CTRL_BASE, 0x00008000);
1700 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, 0x01001d61);//0x01401d61);
1701 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, 0x38233d0e);
1702 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, 0x80100004);//0x80120004);
1703 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x1c7dbf48);
1705 + /* toggle RG_XPTL_CHG */
1706 + i2s_outw(RALINK_ANA_CTRL_BASE, 0x00008800);
1707 + i2s_outw(RALINK_ANA_CTRL_BASE, 0x00008c00);
1709 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
1710 + data &= ~(0x0000ffc0);
1711 + if ((xtal_40M_en) || (xtal_20M_en))
1713 + data |= REGBIT(0x1d, 8); /* for 40M or 20M */
1717 + data |= REGBIT(0x17, 8); /* for 25M */
1722 + data |= REGBIT(0x1, 6); /* for 40M */
1724 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
1727 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0018);
1728 + data &= ~(0xf0773f00);
1729 + data |= REGBIT(0x3, 28);
1730 + data |= REGBIT(0x2, 20);
1731 + if ((xtal_40M_en) || (xtal_20M_en))
1733 + data |= REGBIT(0x3, 16); /* for 40M or 20M */
1737 + data |= REGBIT(0x2, 16); /* for 25M */
1739 + data |= REGBIT(0x3, 12);
1740 + if ((xtal_40M_en) || (xtal_20M_en))
1742 + data |= REGBIT(0xd, 8); /* for 40M or 20M */
1746 + data |= REGBIT(0x7, 8); /* for 25M */
1748 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, data);
1750 + if((index==1)|(index==4)|(index==7)|(index==9))// 270 MHz for 22.05K, 44.1K, 88.2K, 176.4K
1752 + if ((xtal_40M_en) || (xtal_20M_en))
1754 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x1a18548a); /* for 40M or 20M */
1758 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x14ad106e); /* for 25M */
1761 + else if ((index==0)|(index==3)|(index==5)|(index==6)|(index==8)|(index==10))// 294 MHZ for 24K, 48K, 96K, 192K
1763 + if ((xtal_40M_en) || (xtal_20M_en))
1765 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x1c7dbf48); /* for 40M or 20M */
1769 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x1697cc39); /* for 25M */
1772 + else if (index==2)
1774 + _printk("Not support 12KHz sampling rate!\n");
1779 + _printk("Wrong sampling rate!\n");
1783 + //*Common setting - Set PLLGP_CTRL_4 *//
1785 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
1786 + data &= ~(REGBIT(0x1, 31));
1787 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
1791 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
1792 + data |= REGBIT(0x1, 0);
1793 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
1797 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
1798 + data |= REGBIT(0x1, 3);
1799 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
1803 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
1804 + data |= REGBIT(0x1, 8);
1805 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
1809 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
1810 + data |= REGBIT(0x1, 6);
1811 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
1814 + /* 6. Bit 5 & Bit 7*/
1815 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
1816 + data |= REGBIT(0x1, 5);
1817 + data |= REGBIT(0x1, 7);
1818 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
1822 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
1823 + data |= REGBIT(0x1, 17);
1824 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
1826 +#elif defined(CONFIG_I2S_MCLK_12MHZ)
1827 + _printk("MT7621 provide 12MHz REFCLK\n");
1828 + /* Firstly, reset all required register to default value */
1829 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, 0x01401d61);//0x01401d61);
1830 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, 0x80120004);//0x80100004);
1831 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, 0x38233d0e);
1835 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
1836 + data &= ~REGBIT(0x1, 17);
1837 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
1839 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
1840 + data &= ~REGBIT(0x3, 4);
1841 + data |= REGBIT(0x1, 4);
1842 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
1844 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
1845 + data &= ~REGBIT(0x1, 31);
1846 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
1848 + else if (xtal_20M_en)
1850 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
1851 + data &= ~REGBIT(0x1, 17);
1852 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
1854 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
1855 + data &= ~REGBIT(0x3, 6);
1856 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
1858 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
1859 + data &= ~REGBIT(0x3, 4);
1860 + data |= REGBIT(0x1, 4);
1861 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
1863 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
1864 + data &= ~REGBIT(0x1, 31);
1865 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
1869 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
1870 + data &= ~REGBIT(0x1, 17);
1871 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
1873 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
1874 + data &= ~REGBIT(0x7f, 8);
1875 + data |= REGBIT(0x17, 8);
1876 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
1878 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
1879 + data &= ~REGBIT(0x3, 6);
1880 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
1882 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0018);
1883 + data &= ~REGBIT(0x7, 16);
1884 + data |= REGBIT(0x2, 16);
1885 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, data);
1887 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0018);
1888 + data &= ~REGBIT(0xf, 8);
1889 + data |= REGBIT(0x7, 8);
1890 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, data);
1893 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
1894 + data &= ~REGBIT(0x3, 4);
1895 + data |= REGBIT(0x1, 4);
1896 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
1898 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
1899 + data &= ~REGBIT(0x1, 31);
1900 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
1906 +#if defined(CONFIG_I2S_IN_MCLK)
1907 +int i2s_pll_refclk_set(void)
1909 + unsigned long data;
1911 + /* Set APLL register for REFCLK */
1912 + data = i2s_inw(RALINK_SYSCTL_BASE+0x90);
1913 + data &= ~(0x0000f000);
1914 + data |= REGBIT(0x1, 12);
1915 + i2s_outw(RALINK_SYSCTL_BASE+0x0090, data);
1917 + data = i2s_inw(RALINK_SYSCTL_BASE+0x0090);
1918 + data &= ~(0x00000300);
1919 + i2s_outw(RALINK_SYSCTL_BASE+0x0090, data);
1920 + MSG("Set 0x90 register\n");
1927 +#ifdef MT7623_ASIC_BOARD
1928 +int i2s_pll_config_mt7623(unsigned long index)
1930 + unsigned long data;
1933 + data = i2s_inw(AUD2PLL_PWR_CON0);
1935 + i2s_outw(AUD2PLL_PWR_CON0, data);
1938 + /* xPLL ISO Disable */
1939 + data = i2s_inw(AUD2PLL_PWR_CON0);
1941 + i2s_outw(AUD2PLL_PWR_CON0, data);
1943 + /* xPLL Frequency Set */
1944 + data = i2s_inw(AUD2PLL_CON0);
1946 + i2s_outw(AUD2PLL_CON0, data);
1948 + /* AUD1PLL Frequency Set(change from 98.304MHz to 294.912MHz) */
1949 + i2s_outw(AUD1PLL_CON0, 0x121);
1950 + i2s_outw(AUD1PLL_CON1, 0xad5efee6);
1953 + /* Audio clock setting */
1954 + if((index==1)|(index==4)|(index==7)|(index==9)|(index==11))// for 22.05K, 44.1K, 88.2K, 176.4K
1956 + _printk("\n*****%s:index=%d(270MHz)*****\n", __func__, (int)index);
1957 + data = i2s_inw(0xFB00002c);
1958 + //data &= ~REGBIT(0x8, 1);
1960 + i2s_outw(0xFB00002C, data); /* AUD1PLL 270.9204MHz */
1962 + else if ((index==0)|(index==3)|(index==5)|(index==6)|(index==8)|(index==10)|(index==12)) //for 24K, 48K, 96K, 192K
1964 + _printk("\n*****%s:index=%d(294MHz)*****\n", __func__, (int)index);
1965 + data = i2s_inw(0xFB00002c);
1966 + //data |= REGBIT(0x8, 1);
1968 + i2s_outw(0xFB00002c, data); /* AUD1PLL 294.912MHz */
1970 + else if (index==2)
1972 + _printk("Not support 12KHz sampling rate!\n");
1977 + _printk("Wrong sampling rate!\n");
1984 +#if defined(MT7628_ASIC_BOARD) || defined(CONFIG_ARCH_MT7623)
1985 +int i2s_driving_strength_adjust(void)
1987 +#if defined(MT7628_ASIC_BOARD)
1988 + unsigned long data;
1990 + MSG("Adjust MT7628 current's driving strngth\n");
1991 + /* Adjust REFCLK0's driving strength of current which can avoid
1992 + * the glitch of REFCKL0
1993 + * E4 = 0xb0001354[5]; E8 = 0xb0001364[5]
1994 + * (E4,E8)=(0,0)-> 4 mA;
1997 + * =(1,1)-> 16 mA*/
2000 + data = i2s_inw(0xb0001354);
2001 + data &= ~(0x1<<5);
2002 + i2s_outw(0xb0001354, data);
2004 + data = i2s_inw(0xb0001364);
2006 + i2s_outw(0xb0001364, data);
2008 +#if defined(CONFIG_ARCH_MT7623)
2009 + MSG("Adjust MT7623 current's driving strngth\n");
2011 + i2s_outw(0xF0005F80, 0x7777);
2018 +#if defined(CONFIG_I2S_IN_MCLK)
2019 +#if defined(CONFIG_I2S_MCLK_12MHZ)
2020 +int i2s_refclk_12m_enable(void)
2022 + unsigned long data;
2024 + MSG("Enable SoC MCLK 12Mhz\n");
2026 +#if defined(CONFIG_RALINK_RT6855A)
2027 + data = i2s_inw(RALINK_SYSCTL_BASE+0x860);
2028 + data |= (0x1<<17);
2029 + data &= ~(0x7<<18);
2030 + data |= (0x1<<18);
2031 + i2s_outw(RALINK_SYSCTL_BASE+0x860, data);
2032 +#elif defined(CONFIG_RALINK_RT3350)
2033 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2035 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2036 +#elif defined(CONFIG_RALINK_RT3883)
2037 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2038 + data &= ~(0x03<<13);
2039 + data |= (0x1<<13);
2040 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2041 +#elif defined(CONFIG_RALINK_RT3352)||defined(CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855)
2042 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2043 + data &= ~(0x0F<<8);
2045 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2046 +#elif defined(CONFIG_RALINK_MT7620)
2047 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2048 + data &= ~(0x07<<9);
2050 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2051 +#elif defined(CONFIG_RALINK_MT7621)
2052 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2053 + data &= ~(0x1f<<18);
2054 + data |= REGBIT(0x19, 18);
2055 + data &= ~(0x1f<<12);
2056 + data |= REGBIT(0x1, 12);
2057 + data &= ~(0x7<<9);
2058 + data |= REGBIT(0x5, 9);
2059 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2060 +#elif defined(CONFIG_RALINK_MT7628)
2061 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2062 + MSG("turn on REFCLK output for MCLK1\n");
2063 + data &= ~(0x7<<9);
2064 + data |= (0x1<<9); /* output for MCLK */
2065 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2067 + #error "This SoC does not provide 12MHz clock to audio codec\n");
2069 + i2s_refclk_gpio_out_config();
2075 +#if defined(CONFIG_I2S_MCLK_12P288MHZ)
2076 +int i2s_refclk_12p288m_enable(void)
2078 + unsigned long data;
2079 + MSG("Enable SoC MCLK 12.288Mhz\n");
2081 +#if defined(CONFIG_RALINK_RT3352)||defined(CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855)
2082 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2083 + data &= ~(0x01F<<18);
2085 + data &= ~(0x01F<<12);
2088 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2089 +#elif defined(CONFIG_RALINK_MT7621)
2090 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2091 + data &= ~(0x1f<<18);
2092 + data |= REGBIT(0xc, 18);
2093 + data &= ~(0x1f<<12);
2094 + data |= REGBIT(0x1, 12);
2095 + data &= ~(0x7<<9);
2096 + data |= REGBIT(0x5, 9);
2097 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2098 + _printk("MT7621 provide REFCLK 12.288MHz/11.289MHz\n");
2099 +#elif defined(CONFIG_ARCH_MT7623)
2100 + /* MT7623 does not need to set divider for REFCLK */
2101 + /* GPIO126 - I2S0_MCLK */
2102 + data = i2s_inw(0xF00058F0);
2103 + data &= ~(0x7<<3);
2105 + i2s_outw(0xF00058F0, data);
2106 + /* GPIO_DIR8: OUT */
2107 + data = i2s_inw(0xF0005070);
2108 + data |= (0x1<<14);
2109 + i2s_outw(0xF0005070, data);
2111 + #error "This SoC does not provide 12.288Mhz clock to audio codec\n");
2118 +#if defined(CONFIG_I2S_MCLK_18P432MHZ)
2119 +int i2s_refclk_18p432m_enable(unsigned long index)
2121 + unsigned long data;
2122 + MSG("Enable SoC MCLK 18.432MHz/16.934MHz");
2124 + if((index==1)|(index==4)|(index==7)|(index==9))// 16.934MHz for 22.05K, 44.1K, 88.2K, 176.4K
2126 + data = i2s_inw(ETHDMASYS_SYSCTL_BASE+0x2c);
2127 + data &= ~(0x1<<7);
2128 + i2s_outw(ETHDMASYS_SYSCTL_BASE+0x2c, data);
2130 + else if((index==0)|(index==3)|(index==5)|(index==6)|(index==8)|(index==10))// 18.432MHZ for 24K, 48K, 96K, 192K
2132 + data = i2s_inw(ETHDMASYS_SYSCTL_BASE+0x2c);
2134 + i2s_outw(ETHDMASYS_SYSCTL_BASE+0x2c, data);
2137 + data = i2s_inw(ETHDMASYS_SYSCTL_BASE+0x30);
2138 + data |= (0x1<<17);
2139 + i2s_outw(ETHDMASYS_SYSCTL_BASE+0x30, data);
2146 +int i2s_refclk_disable(void)
2148 + unsigned long data;
2150 +#if defined(CONFIG_RALINK_RT6855A)
2151 + data = i2s_inw(RALINK_SYSCTL_BASE+0x860);
2153 + i2s_outw(RALINK_SYSCTL_BASE+0x860, data);
2154 +#elif defined(CONFIG_RALINK_RT3350)
2155 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2156 + data &= ~(0x1<<8);
2157 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2158 +#elif defined(CONFIG_RALINK_RT3883)
2159 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2160 + data &= ~(0x0F<<13);
2161 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2162 +#elif defined(CONFIG_RALINK_RT3352)||defined(CONFIG_RALINK_RT5350)||defined (CONFIG_RALINK_RT6855)
2163 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2164 + data &= ~(0x0F<<8);
2165 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2166 +#elif defined (CONFIG_RALINK_MT7620)||defined (CONFIG_RALINK_MT7621)||defined (CONFIG_RALINK_MT7628)
2167 + _printk("turn off REFCLK output from internal CLK\n");
2168 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2169 + data &= ~(0x07<<9);
2170 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2171 +#elif defined (CONFIG_ARCH_MT7623) /*FIXME:2*/
2172 +#ifdef MT7623_ASIC_BOARD
2173 + _printk("turn off REFCLK output from internal CLK\n");
2174 + /* GPIO126 - I2S0_MCLK */
2175 + data = i2s_inw(0xF00058F0);
2176 + data &= ~(0x7<<3);
2177 + //data |= (0x2<<3);
2178 + i2s_outw(0xF00058F0, data);
2179 + /* GPIO126 => GPIO_DIR8: IN */
2180 + data = i2s_inw(0xF0005070);
2181 + data &= ~(0x1<<14);
2182 + i2s_outw(0xF0005070, data);
2184 + _printk("turn off REFCLK output from internal CLK\n");
2185 + data = i2s_inw(ETHDMASYS_SYSCTL_BASE+0x30);
2186 + data &= ~(0x1<<17);
2187 + i2s_outw(ETHDMASYS_SYSCTL_BASE+0x30, data);
2193 +int i2s_refclk_gpio_out_config(void)
2195 +#ifndef CONFIG_ARCH_MT7623
2196 + unsigned long data; /* FIXME */
2199 + /* Set REFCLK GPIO pin as REFCLK mode*/
2200 +#if defined(CONFIG_RALINK_MT7620)
2201 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2202 + data &= ~(0x03<<21); /* WDT */
2204 + //data &= ~(0x03<<16); /* PERST */
2205 + //data |= (1<<16);
2206 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2208 +#if defined(CONFIG_RALINK_MT7621)
2209 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2210 + //data &= ~(0x3<<10); /* PERST */
2211 + //data |= (0x2<<10);
2212 + data &= ~(0x3<<8); /* WDT */
2214 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2215 + MSG("Set 0x60 register\n");
2217 +#if defined(CONFIG_RALINK_MT7628)
2218 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2219 + data &= ~(0x1<<18);
2220 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2226 +int i2s_refclk_gpio_in_config(void)
2228 +#ifndef CONFIG_ARCH_MT7623
2229 + unsigned long data; /* FIXME */
2232 +#if defined (CONFIG_RALINK_MT7620)
2233 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2234 + data &= ~(0x03<<21); /* WDT */
2236 + //data &= ~(0x03<<16); /* PERST */
2237 + //data |= (1<<16);
2238 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2240 + data = i2s_inw(RALINK_PIO_BASE);
2241 + data &= ~(0x1<<17); /* GPIO share ping 17 for WDT */
2242 + i2s_outw(RALINK_PIO_BASE, data);
2244 + //data = i2s_inw(RALINK_PIO_BASE+0x04);
2245 + //data &= ~(0x1<<4); /* GPIO share ping 36 for PERST */
2246 + //i2s_outw(RALINK_PIO_BASE+0x04, data);
2248 +#if defined (CONFIG_RALINK_MT7621)
2249 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2250 + //data &= ~(0x3<<10); /* PERST */
2251 + //data |= (0x1<<10);
2252 + data &= ~(0x3<<8); /* WDT */
2254 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2256 + data = i2s_inw(RALINK_PIO_BASE);
2257 + //data &= ~(0x1<<19); /* GPIO share ping 19 for RERST */
2258 + data &= ~(0x1<<18); /* GPIO share ping 18 for WDT */
2259 + i2s_outw(RALINK_PIO_BASE, data);
2261 +#if defined (CONFIG_RALINK_MT7628)
2262 + /* To use external OSC, set REFCLK_GPIO ping as GPIO mode and set it as input direction */
2263 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2264 + data |= (0x1<<18);
2265 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2267 + data = i2s_inw(RALINK_PIO_BASE+0x04);
2268 + data &= ~(0x1<<5); /* GPIO share ping 37*/
2269 + i2s_outw(RALINK_PIO_BASE+0x04, data);
2275 +int i2s_slave_clock_gpio_in_mt7623(void)
2277 + unsigned long data;
2279 + /* GPIO74(I2S0_BCLK)=>GPIO_DIR5: IN */
2280 + data = i2s_inw(0xF0005040);
2281 + data &= ~(0x1<<10);
2282 + i2s_outw(0xF0005040, data);
2284 + /* GPIO73(I2S0_LRCK)=>GPIO_DIR5: IN */
2285 + data = i2s_inw(0xF0005040);
2286 + data &= ~(0x1<<9);
2287 + i2s_outw(0xF0005040, data);
2289 + _printk("i2s_slave_clock_gpio_in_mt7623\n");
2294 +int i2s_master_clock_gpio_out_mt7623(void)
2296 + unsigned long data;
2298 + /* GPIO74(I2S0_BCLK)=>GPIO_DIR5: OUT */
2299 + data = i2s_inw(0xF0005040);
2300 + data |= (0x1<<10);
2301 + i2s_outw(0xF0005040, data);
2303 + /* GPIO73(I2S0_LRCK)=>GPIO_DIR5: OUT */
2304 + data = i2s_inw(0xF0005040);
2306 + i2s_outw(0xF0005040, data);
2308 + _printk("i2s_master_clock_gpio_out_mt7623\n");
2313 +int i2s_share_pin_mt7623(i2s_config_type* ptri2s_config)
2315 + unsigned long data;
2317 + _printk("\nConfig MT7623 I2S pinmux\n");
2318 + /* GPIO74 - I2S0_BCLK */
2319 + data = i2s_inw(0xF0005840);
2320 + data &= ~(0x7<<12);
2321 + data |= (0x6<<12);
2322 + i2s_outw(0xF0005840, data);
2324 + /* GPIO73 - I2S0_LRCK */
2325 + data = i2s_inw(0xF0005840);
2326 + data &= ~(0x7<<9);
2328 + i2s_outw(0xF0005840, data);
2330 + if(ptri2s_config->slave_en==0)
2331 + i2s_master_clock_gpio_out_mt7623();
2333 + i2s_slave_clock_gpio_in_mt7623();
2335 + /* GPIO49 - I2S0_DATA */
2336 + data = i2s_inw(0xF00057F0);
2337 + data &= ~(0x7<<12);
2338 + data |= (0x6<<12);
2339 + i2s_outw(0xF00057F0, data);
2340 + /* GPIO_DIR4: OUT */
2341 + data = i2s_inw(0xF0005030);
2343 + i2s_outw(0xF0005030, data);
2345 + /* GPIO72 - I2S0_DATA_IN */
2346 + data = i2s_inw(0xF0005840);
2347 + data &= ~(0x7<<6);
2349 + i2s_outw(0xF0005840, data);
2350 + /* GPIO_DIR5: IN */
2351 + data = i2s_inw(0xF0005040);
2352 + data &= ~(0x1<<8);
2353 + i2s_outw(0xF0005040, data);
2358 +int i2s_share_pin_config(i2s_config_type* ptri2s_config)
2360 +#ifndef CONFIG_ARCH_MT7623
2361 + unsigned long data; /*FIXME*/
2364 + /* set share pins to i2s/gpio mode and i2c mode */
2365 +#if defined(CONFIG_RALINK_RT6855A)
2366 + data = i2s_inw(RALINK_SYSCTL_BASE+0x860);
2367 + data |= 0x00008080;
2368 + i2s_outw(RALINK_SYSCTL_BASE+0x860, data);
2369 +#elif defined(CONFIG_RALINK_MT7621)
2370 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2371 + data &= 0xFFFFFFE3;
2372 + data |= 0x00000010;
2373 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2374 +#elif defined(CONFIG_RALINK_MT7628)
2375 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2376 + data &= ~(0x3<<6); /* I2S_MODE */
2377 + data &= ~(0x3<<20); /* I2C_MODE */
2378 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2379 +#elif defined(CONFIG_ARCH_MT7623)
2380 + i2s_share_pin_mt7623(ptri2s_config);
2382 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2383 + data &= 0xFFFFFFE2;
2384 + data |= 0x00000018;
2385 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2390 +int i2s_ws_config(i2s_config_type* ptri2s_config, unsigned long index)
2392 + unsigned long data;
2393 + unsigned long* pTable;
2395 +#if defined(CONFIG_I2S_IN_CLK)
2396 + /* REFCLK is 15.625Mhz or 40Mhz(fractional division) */
2397 +#if defined(CONFIG_I2S_FRAC_DIV)
2398 + MSG("Internal REFCLK with fractional division\n");
2399 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
2400 + if (ptri2s_config->wordlen_24b == 1)
2402 + MSG("24 bit int table\n");
2403 + pTable = i2s_inclk_int_24bit;
2407 + MSG("16 bit int table\n");
2408 + pTable = i2s_inclk_int_16bit;
2411 + pTable = i2s_inclk_int;
2412 +#endif /* CONFIG_RALINK_MT7628 */
2414 + data = (unsigned long)(pTable[index]);
2415 + i2s_outw(I2S_DIVINT_CFG, data);
2417 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
2418 + if (ptri2s_config->wordlen_24b == 1)
2420 + MSG("24 bit comp table\n");
2421 + pTable = i2s_inclk_comp_24bit;
2425 + MSG("16 bit comp table\n");
2426 + pTable = i2s_inclk_comp_16bit;
2429 + pTable = i2s_inclk_comp;
2430 +#endif /* CONFIG_RALINK_MT7628 */
2432 + data = (unsigned long)(pTable[index]);
2433 + data |= REGBIT(1, I2S_CLKDIV_EN);
2434 + i2s_outw(I2S_DIVCOMP_CFG, data);
2436 + MSG("Internal REFCLK 15.625Mhz \n");
2437 + pTable = i2s_inclk_15p625Mhz;
2438 + data = i2s_inw(RALINK_SYSCTL_BASE+0x30);
2439 + data &= 0xFFFF00FF;
2440 + data |= (unsigned long)(pTable[index]);
2441 + data |= 0x00008000;
2442 + i2s_outw(RALINK_SYSCTL_BASE+0x30, data);
2443 +#endif /* CONFIG_I2S_FRAC_DIV */
2445 +#if defined(CONFIG_I2S_MCLK_12MHZ)
2446 + /* REFCLK = MCLK = 12Mhz */
2447 + MSG("External REFCLK 12Mhz \n");
2448 + pTable = i2s_exclk_12Mhz;
2449 + data = i2s_inw(RALINK_SYSCTL_BASE+0x30);
2450 + data &= 0xFFFF00FF;
2451 + data |= (unsigned long)(pTable[index]);
2452 + data |= 0x0000C000;
2453 + i2s_outw(RALINK_SYSCTL_BASE+0x30, data);
2455 + /* REFCLK = MCLK = 12.288Mhz */
2456 + pTable = i2s_exclk_12p288Mhz;
2457 + MSG("External REFCLK 12.288Mhz \n");
2458 + data = i2s_inw(RALINK_SYSCTL_BASE+0x30);
2459 + data &= 0xFFFF00FF;
2460 + data |= (unsigned long)(pTable[index]);
2461 + data |= 0x0000C000;
2462 + i2s_outw(RALINK_SYSCTL_BASE+0x30, data);
2463 +#endif /* CONFIG_I2S_MCLK_12MHZ */
2464 +#endif /* Not CONFIG_I2S_IN_CLK */
2466 +#if defined(CONFIG_I2S_WS_EDGE)
2467 + data = i2s_inw(I2S_I2SCFG);
2468 + data |= REGBIT(0x1, I2S_WS_INV);
2469 + i2s_outw(I2S_I2SCFG, data);
2475 +int i2s_mode_config(u32 slave_en)
2477 + unsigned long data;
2482 + _printk("This SoC is in Master mode\n");
2483 +#if defined(CONFIG_RALINK_RT3052)
2484 + data = i2s_inw(I2S_I2SCFG);
2485 + data &= ~REGBIT(0x1, I2S_SLAVE_EN);
2486 + data &= ~REGBIT(0x1, I2S_CLK_OUT_DIS);
2487 + i2s_outw(I2S_I2SCFG, data);
2488 +#elif defined(CONFIG_RALINK_RT3883)||defined(CONFIG_RALINK_RT3352)||\
2489 + defined(CONFIG_RALINK_RT5350)||defined(CONFIG_RALINK_RT6855)||\
2490 + defined(CONFIG_RALINK_MT7620)||defined(CONFIG_RALINK_RT6855A)||\
2491 + defined(CONFIG_RALINK_MT7621)||defined(CONFIG_RALINK_MT7628)||\
2492 + defined(CONFIG_ARCH_MT7623)
2493 + data = i2s_inw(I2S_I2SCFG);
2494 + data &= ~REGBIT(0x1, I2S_SLAVE_MODE);
2495 + i2s_outw(I2S_I2SCFG, data);
2497 + #error "a strange clock mode"
2503 + _printk("This SoC is in Slave mode\n");
2504 +#if defined(CONFIG_RALINK_RT3052)
2505 + data = i2s_inw(I2S_I2SCFG);
2506 + data |= REGBIT(0x1, I2S_SLAVE_EN);
2507 + data |= REGBIT(0x1, I2S_CLK_OUT_DIS);
2508 + i2s_outw(I2S_I2SCFG, data);
2509 +#elif defined(CONFIG_RALINK_RT3883)||defined(CONFIG_RALINK_RT3352)||\
2510 + defined(CONFIG_RALINK_RT5350)||defined(CONFIG_RALINK_RT6855)||\
2511 + defined(CONFIG_RALINK_MT7620)||defined(CONFIG_RALINK_RT6855A)||\
2512 + defined(CONFIG_RALINK_MT7621)||defined(CONFIG_RALINK_MT7628)||\
2513 + defined(CONFIG_ARCH_MT7623)
2514 + data = i2s_inw(I2S_I2SCFG);
2515 + data |= REGBIT(0x1, I2S_SLAVE_MODE);
2516 + i2s_outw(I2S_I2SCFG, data);
2518 + #error "a strange clock mode "
2525 +int i2s_codec_frequency_config(i2s_config_type* ptri2s_config, unsigned long index)
2527 +#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
2528 + unsigned long data;
2529 + unsigned long* pTable;
2532 +#if defined(CONFIG_I2S_MCLK_12MHZ)
2533 +#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
2534 + pTable = i2s_codec_12Mhz;
2535 + data = pTable[index];
2537 +#if defined(CONFIG_I2S_WM8960)
2538 + audiohw_set_frequency(data, ptri2s_config->codec_pll_en);
2539 +#elif defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
2540 + audiohw_set_frequency(data|0x01);
2543 +#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
2544 +#if defined(MT7623_FPGA_BOARD) && defined(CONFIG_I2S_WM8750)
2545 + pTable = i2s_codec_18p432Mhz;
2547 + pTable = i2s_codec_12p288Mhz;
2549 + data = pTable[index];
2551 +#if defined(CONFIG_I2S_WM8960)
2552 + audiohw_set_frequency(data, ptri2s_config->codec_pll_en);
2553 +#elif defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
2554 + audiohw_set_frequency(data);
2561 + * Ralink Audio System Clock Enable
2563 + * I2S_WS : signal direction opposite to/same as I2S_CLK
2565 + * I2S_CLK : Integer division or fractional division
2566 + * REFCLK from Internal or External (external REFCLK not support for fractional division)
2567 + * Suppose external REFCLK always be the same as external MCLK
2569 + * MCLK : External OSC or internal generation
2572 +int i2s_clock_enable(i2s_config_type* ptri2s_config)
2574 + unsigned long index;
2575 + /* audio sampling rate decision */
2576 + switch(ptri2s_config->srate)
2611 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
2622 +#ifdef MT7621_ASIC_BOARD
2623 + /* Set pll config */
2624 + i2s_pll_config_mt7621(index);
2626 +#ifdef MT7623_ASIC_BOARD
2627 + /* Set pll config */
2628 + i2s_pll_config_mt7623(index);
2631 + /* enable internal MCLK */
2632 +#if defined(CONFIG_I2S_IN_MCLK)
2633 +#if defined(CONFIG_RALINK_MT7621)
2634 + i2s_pll_refclk_set();
2636 +#if defined(CONFIG_I2S_MCLK_12MHZ)
2637 +#if defined(MT7628_ASIC_BOARD) || defined(CONFIG_ARCH_MT7623)
2638 + i2s_driving_strength_adjust();
2640 + i2s_refclk_12m_enable();
2641 +#endif /* MCLK_12MHZ */
2642 +#if defined(CONFIG_I2S_MCLK_12P288MHZ)
2643 + i2s_refclk_12p288m_enable();
2644 +#endif /* MCLK_12P288MHZ */
2645 +#if defined(CONFIG_I2S_MCLK_18P432MHZ)
2646 + i2s_refclk_18p432m_enable(index);
2648 + i2s_refclk_gpio_out_config();
2651 + MSG("Disable SoC MCLK, use external OSC\n");
2652 + i2s_refclk_disable();
2653 + i2s_refclk_gpio_in_config();
2654 +#endif /* CONFIG_I2S_IN_MCLK */
2656 + i2s_share_pin_config(ptri2s_config);
2658 + if(ptri2s_config->slave_en==0)
2660 + /* Setup I2S_WS and I2S_CLK */
2661 + i2s_ws_config(ptri2s_config, index);
2664 + i2s_mode_config(ptri2s_config->slave_en);
2666 + if(!ptri2s_config->bALSAEnable)
2668 +#if defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)|| defined(CONFIG_I2S_WM8960)
2669 + i2s_codec_enable(ptri2s_config);
2671 + i2s_codec_frequency_config(ptri2s_config,index);
2677 +int i2s_clock_disable(i2s_config_type* ptri2s_config)
2679 + if(!ptri2s_config->bALSAEnable)
2681 +#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
2682 + i2s_codec_disable(ptri2s_config);
2686 + /* disable internal MCLK */
2687 +#if defined(CONFIG_I2S_IN_MCLK)
2688 + i2s_refclk_disable();
2689 + i2s_refclk_gpio_in_config();
2695 +int i2s_codec_enable(i2s_config_type* ptri2s_config)
2698 + int AIn = 0, AOut = 0;
2700 +#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
2701 + /* Codec initialization */
2702 + audiohw_preinit();
2706 +#if defined(CONFIG_I2S_WM8960)
2707 + if(ptri2s_config->codec_pll_en)
2709 + MSG("Codec PLL EN = %d\n", pi2s_config->codec_pll_en);
2710 + audiohw_set_apll(ptri2s_config->srate);
2714 +#if defined(CONFIG_I2S_TXRX)
2715 + if((ptri2s_config->bTxDMAEnable) || (ptri2s_config->txrx_coexist))
2717 + if((ptri2s_config->bRxDMAEnable) || (ptri2s_config->txrx_coexist))
2719 +#if defined(CONFIG_I2S_WM8960)
2720 + audiohw_postinit(!(ptri2s_config->slave_en), AIn, AOut, ptri2s_config->codec_pll_en, ptri2s_config->wordlen_24b);
2721 + audiohw_micboost(ptri2s_config->micboost);
2722 + audiohw_micin(ptri2s_config->micin);
2723 +#elif defined(CONFIG_I2S_WM8750)
2724 + audiohw_postinit(!(ptri2s_config->slave_en), AIn, AOut, ptri2s_config->wordlen_24b);
2726 + MSG("AOut=%d, AIn=%d\n", AOut, AIn);
2728 +#if defined(CONFIG_I2S_WM8750)
2729 + audiohw_postinit(!(ptri2s_config->slave_en), 0, 1);
2730 +#elif defined(CONFIG_I2S_WM8960)
2731 + audiohw_postinit(!(ptri2s_config->slave_en), 1, 1, ptri2s_config->codec_pll_en);
2732 +#elif defined(CONFIG_I2S_WM8751)
2733 + if(ptri2s_config->slave_en==0)
2734 + audiohw_postinit(1,1);
2736 + audiohw_postinit(0,1);
2742 +int i2s_codec_disable(i2s_config_type* ptri2s_config)
2744 +#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
2750 +int i2s_reset_config(i2s_config_type* ptri2s_config)
2752 + unsigned long data;
2754 + /* RESET bit: write 1 clear */
2755 +#if defined(CONFIG_RALINK_RT6855A)
2756 + data = i2s_inw(RALINK_SYSCTL_BASE+0x834);
2758 + i2s_outw(RALINK_SYSCTL_BASE+0x834, data);
2760 + data = i2s_inw(RALINK_SYSCTL_BASE+0x834);
2762 + i2s_outw(RALINK_SYSCTL_BASE+0x834, data);
2763 +#elif defined(CONFIG_ARCH_MT7623)
2764 + data = i2s_inw(0xFB000000+0x34);
2766 + i2s_outw(0xFB000000+0x34, data);
2768 + data = i2s_inw(0xFB000000+0x34);
2770 + i2s_outw(0xFB000000+0x34, data);
2772 + data = i2s_inw(RALINK_SYSCTL_BASE+0x34);
2774 + i2s_outw(RALINK_SYSCTL_BASE+0x34, data);
2776 + data = i2s_inw(RALINK_SYSCTL_BASE+0x34);
2778 + i2s_outw(RALINK_SYSCTL_BASE+0x34, data);
2780 +#if 0 /* Reset GDMA */
2781 + data = i2s_inw(RALINK_SYSCTL_BASE+0x34);
2783 + i2s_outw(RALINK_SYSCTL_BASE+0x34, data);
2785 + data = i2s_inw(RALINK_SYSCTL_BASE+0x34);
2787 + i2s_outw(RALINK_SYSCTL_BASE+0x34, data);
2790 + _printk("I2S reset complete!!\n");
2794 +int i2s_tx_config(i2s_config_type* ptri2s_config)
2796 + unsigned long data;
2797 + /* set I2S_I2SCFG */
2798 + data = i2s_inw(I2S_I2SCFG);
2799 + data &= 0xFFFFFF81;
2800 + data |= REGBIT(ptri2s_config->tx_ff_thres, I2S_TX_FF_THRES);
2801 + data |= REGBIT(ptri2s_config->tx_ch_swap, I2S_TX_CH_SWAP);
2802 +#if defined(CONFIG_RALINK_RT6855A)
2803 + data |= REGBIT(1, I2S_BYTE_SWAP);
2805 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
2806 + MSG("TX:wordLen=%d, sysEndian=%d\n", ptri2s_config->wordlen_24b, ptri2s_config->sys_endian);
2807 + data |= REGBIT(ptri2s_config->wordlen_24b, I2S_DATA_24BIT);
2808 + data |= REGBIT(ptri2s_config->sys_endian, I2S_SYS_ENDIAN);
2809 + data |= REGBIT(ptri2s_config->little_edn, I2S_LITTLE_ENDIAN);
2811 + data &= ~REGBIT(1, I2S_TX_CH0_OFF);
2812 + data &= ~REGBIT(1, I2S_TX_CH1_OFF);
2813 + i2s_outw(I2S_I2SCFG, data);
2815 + /* set I2S_I2SCFG1 */
2816 + MSG("internal loopback: %d\n", ptri2s_config->lbk);
2817 + data = i2s_inw(I2S_I2SCFG1);
2818 + data |= REGBIT(ptri2s_config->lbk, I2S_LBK_EN);
2819 + data |= REGBIT(ptri2s_config->extlbk, I2S_EXT_LBK_EN);
2820 + data &= 0xFFFFFFFC;
2821 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
2822 + data |= REGBIT(ptri2s_config->fmt, I2S_DATA_FMT);
2824 + i2s_outw(I2S_I2SCFG1, data);
2829 +int i2s_rx_config(i2s_config_type* ptri2s_config)
2831 + unsigned long data;
2832 + /* set I2S_I2SCFG */
2833 + data = i2s_inw(I2S_I2SCFG);
2834 + data &= 0xFFFF81FF;
2835 + data |= REGBIT(ptri2s_config->rx_ff_thres, I2S_RX_FF_THRES);
2836 + data |= REGBIT(ptri2s_config->rx_ch_swap, I2S_RX_CH_SWAP);
2837 + data &= ~REGBIT(1, I2S_RX_CH0_OFF);
2838 + data &= ~REGBIT(1, I2S_RX_CH1_OFF);
2839 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
2840 + MSG("RX:wordLen=%d, sysEndian=%d\n", ptri2s_config->wordlen_24b, ptri2s_config->sys_endian);
2841 + data |= REGBIT(ptri2s_config->wordlen_24b, I2S_DATA_24BIT);
2842 + data |= REGBIT(ptri2s_config->sys_endian, I2S_SYS_ENDIAN);
2843 + data |= REGBIT(ptri2s_config->little_edn, I2S_LITTLE_ENDIAN);
2845 + i2s_outw(I2S_I2SCFG, data);
2847 + /* set I2S_I2SCFG1 */
2848 + data = i2s_inw(I2S_I2SCFG1);
2849 + data |= REGBIT(ptri2s_config->lbk, I2S_LBK_EN);
2850 + data |= REGBIT(ptri2s_config->extlbk, I2S_EXT_LBK_EN);
2851 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
2852 + data &= 0xFFFFFFFC;
2853 + data |= REGBIT(ptri2s_config->fmt, I2S_DATA_FMT);
2855 + i2s_outw(I2S_I2SCFG1, data);
2860 +/* Turn On Tx DMA and INT */
2861 +int i2s_tx_enable(i2s_config_type* ptri2s_config)
2863 + unsigned long data;
2865 +#if defined(I2S_HW_INTERRUPT_EN)
2866 + data = i2s_inw(I2S_INT_EN);
2867 + data |= REGBIT(0x1, I2S_TX_INT3_EN); /* FIFO DMA fault */
2868 + data |= REGBIT(0x1, I2S_TX_INT2_EN); /* FIFO overrun */
2869 + data |= REGBIT(0x1, I2S_TX_INT1_EN); /* FIFO underrun */
2870 + data |= REGBIT(0x1, I2S_TX_INT0_EN); /* FIFO below threshold */
2871 + i2s_outw(I2S_INT_EN, data);
2874 + data = i2s_inw(I2S_I2SCFG);
2875 +#if defined(CONFIG_I2S_TXRX)
2876 + data |= REGBIT(0x1, I2S_TX_EN);
2878 + data |= REGBIT(0x1, I2S_DMA_EN);
2879 + i2s_outw(I2S_I2SCFG, data);
2881 + data = i2s_inw(I2S_I2SCFG);
2882 + data |= REGBIT(0x1, I2S_EN);
2883 + i2s_outw(I2S_I2SCFG, data);
2885 + MSG("i2s_tx_enable done\n");
2889 +/* Turn On Rx DMA and INT */
2890 +int i2s_rx_enable(i2s_config_type* ptri2s_config)
2892 + unsigned long data;
2894 +#if defined(I2S_HW_INTERRUPT_EN)
2895 + data = i2s_inw(I2S_INT_EN);
2896 + data |= REGBIT(0x1, I2S_RX_INT3_EN); /* FIFO DMA fault */
2897 + data |= REGBIT(0x1, I2S_RX_INT2_EN); /* FIFO overrun */
2898 + data |= REGBIT(0x1, I2S_RX_INT1_EN); /* FIFO underrun */
2899 + data |= REGBIT(0x1, I2S_RX_INT0_EN); /* FIFO below threshold */
2900 + i2s_outw(I2S_INT_EN, data);
2903 + data = i2s_inw(I2S_I2SCFG);
2904 +#if defined(CONFIG_I2S_TXRX)
2905 + data |= REGBIT(0x1, I2S_RX_EN);
2907 + data |= REGBIT(0x1, I2S_DMA_EN);
2908 + i2s_outw(I2S_I2SCFG, data);
2910 + data = i2s_inw(I2S_I2SCFG);
2911 + data |= REGBIT(0x1, I2S_EN);
2912 + i2s_outw(I2S_I2SCFG, data);
2914 + MSG("i2s_rx_enable done\n");
2917 +/* Turn Off Tx DMA and INT */
2918 +int i2s_tx_disable(i2s_config_type* ptri2s_config)
2920 + unsigned long data;
2922 +#if defined(I2S_HW_INTERRUPT_EN)
2923 + data = i2s_inw(I2S_INT_EN);
2924 + data &= ~REGBIT(0x1, I2S_TX_INT3_EN);
2925 + data &= ~REGBIT(0x1, I2S_TX_INT2_EN);
2926 + data &= ~REGBIT(0x1, I2S_TX_INT1_EN);
2927 + data &= ~REGBIT(0x1, I2S_TX_INT0_EN);
2928 + i2s_outw(I2S_INT_EN, data);
2931 + data = i2s_inw(I2S_I2SCFG);
2932 +#if defined(CONFIG_I2S_TXRX)
2933 + data &= ~REGBIT(0x1, I2S_TX_EN);
2935 + if(ptri2s_config->bRxDMAEnable==0)
2937 + ptri2s_config->bTxDMAEnable = 0;
2938 + data &= ~REGBIT(0x1, I2S_DMA_EN);
2939 + data &= ~REGBIT(0x1, I2S_EN);
2941 + i2s_outw(I2S_I2SCFG, data);
2944 +/* Turn Off Rx DMA and INT */
2945 +int i2s_rx_disable(i2s_config_type* ptri2s_config)
2947 + unsigned long data;
2949 +#if defined(I2S_HW_INTERRUPT_EN)
2950 + data = i2s_inw(I2S_INT_EN);
2951 + data &= ~REGBIT(0x1, I2S_RX_INT3_EN);
2952 + data &= ~REGBIT(0x1, I2S_RX_INT2_EN);
2953 + data &= ~REGBIT(0x1, I2S_RX_INT1_EN);
2954 + data &= ~REGBIT(0x1, I2S_RX_INT0_EN);
2955 + i2s_outw(I2S_INT_EN, data);
2958 + data = i2s_inw(I2S_I2SCFG);
2959 +#if defined(CONFIG_I2S_TXRX)
2960 + data &= ~REGBIT(0x1, I2S_RX_EN);
2962 + if(ptri2s_config->bTxDMAEnable==0)
2964 + ptri2s_config->bRxDMAEnable = 0;
2965 + data &= ~REGBIT(0x1, I2S_DMA_EN);
2966 + data &= ~REGBIT(0x1, I2S_EN);
2968 + i2s_outw(I2S_I2SCFG, data);
2972 +int i2s_dma_tx_transf_data(i2s_config_type* ptri2s_config, u32 dma_ch)
2976 + if ((pi2s_config->bALSAEnable==1) && (pi2s_config->bALSAMMAPEnable==1))
2977 + tx_r_idx = (pi2s_config->tx_r_idx + ALSA_MMAP_IDX_SHIFT)%MAX_I2S_PAGE;
2979 + tx_r_idx = pi2s_config->tx_r_idx;
2981 + if(dma_ch==GDMA_I2S_TX0)
2983 +#if defined(CONFIG_I2S_MMAP)
2984 + dma_sync_single_for_device(NULL, i2s_mmap_addr[tx_r_idx], I2S_PAGE_SIZE, DMA_TO_DEVICE);
2985 +#if defined(ARM_ARCH)
2986 + GdmaI2sTx(i2s_mmap_addr[tx_r_idx], I2S_TX_FIFO_WREG_PHY, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
2988 + GdmaI2sTx((u32)(pi2s_config->pMMAPTxBufPtr[tx_r_idx]), I2S_TX_FIFO_WREG, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
2991 + memcpy(pi2s_config->pPage0TxBuf8ptr, pi2s_config->pMMAPTxBufPtr[tx_r_idx], I2S_PAGE_SIZE);
2992 +#if defined(ARM_ARCH)
2993 + GdmaI2sTx(i2s_txdma_addr0, I2S_TX_FIFO_WREG_PHY, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
2995 + GdmaI2sTx((u32)(pi2s_config->pPage0TxBuf8ptr), I2S_TX_FIFO_WREG, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
2998 + pi2s_config->dmach = GDMA_I2S_TX0;
2999 + pi2s_config->tx_r_idx = (pi2s_config->tx_r_idx+1)%MAX_I2S_PAGE;
3003 +#if defined(CONFIG_I2S_MMAP)
3004 + dma_sync_single_for_device(NULL, i2s_mmap_addr[tx_r_idx], I2S_PAGE_SIZE, DMA_TO_DEVICE);
3005 +#if defined(ARM_ARCH)
3006 + GdmaI2sTx(i2s_mmap_addr[tx_r_idx], I2S_TX_FIFO_WREG_PHY, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3008 + GdmaI2sTx((u32)(pi2s_config->pMMAPTxBufPtr[tx_r_idx]), I2S_TX_FIFO_WREG, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3011 + memcpy(pi2s_config->pPage1TxBuf8ptr, pi2s_config->pMMAPTxBufPtr[tx_r_idx], I2S_PAGE_SIZE);
3012 +#if defined(ARM_ARCH)
3013 + GdmaI2sTx(i2s_txdma_addr1, I2S_TX_FIFO_WREG_PHY, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3015 + GdmaI2sTx((u32)(pi2s_config->pPage1TxBuf8ptr), I2S_TX_FIFO_WREG, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3018 + pi2s_config->dmach = GDMA_I2S_TX1;
3019 + pi2s_config->tx_r_idx = (pi2s_config->tx_r_idx+1)%MAX_I2S_PAGE;
3021 +#if defined(CONFIG_I2S_WITH_AEC)
3022 + if(aecFuncP->AECFeEnq){
3023 + aecFuncP->AECFeEnq(0,pi2s_config->pMMAPTxBufPtr[pi2s_config->tx_r_idx],I2S_PAGE_SIZE);
3029 +int i2s_dma_tx_transf_zero(i2s_config_type* ptri2s_config, u32 dma_ch)
3031 + if(dma_ch==GDMA_I2S_TX0)
3033 + memset(pi2s_config->pPage0TxBuf8ptr, 0, I2S_PAGE_SIZE);
3034 +#if defined(ARM_ARCH)
3035 + GdmaI2sTx(i2s_txdma_addr0, I2S_TX_FIFO_WREG_PHY, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3037 + GdmaI2sTx((u32)pi2s_config->pPage0TxBuf8ptr, I2S_TX_FIFO_WREG, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3042 + memset(pi2s_config->pPage1TxBuf8ptr, 0, I2S_PAGE_SIZE);
3043 +#if defined(ARM_ARCH)
3044 + GdmaI2sTx(i2s_txdma_addr1, I2S_TX_FIFO_WREG_PHY, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3046 + GdmaI2sTx((u32)pi2s_config->pPage1TxBuf8ptr, I2S_TX_FIFO_WREG, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3052 +int i2s_dma_rx_transf_data(i2s_config_type* ptri2s_config, u32 dma_ch)
3056 + pi2s_config->rx_w_idx = (pi2s_config->rx_w_idx+1)%MAX_I2S_PAGE;
3058 + if ((pi2s_config->bALSAEnable==1) && (pi2s_config->bALSAMMAPEnable==1))
3059 + rx_w_idx = (pi2s_config->rx_w_idx+ALSA_MMAP_IDX_SHIFT)%MAX_I2S_PAGE;
3061 + rx_w_idx = (pi2s_config->rx_w_idx)%MAX_I2S_PAGE;
3063 + if(dma_ch==GDMA_I2S_RX0)
3066 +#ifdef CONFIG_I2S_MMAP
3067 + dma_sync_single_for_device(NULL, i2s_mmap_addr[rx_w_idx+(pi2s_config->mmap_index-MAX_I2S_PAGE)], I2S_PAGE_SIZE, DMA_FROM_DEVICE);
3068 +#if defined(ARM_ARCH)
3069 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, (u32)i2s_mmap_addr[rx_w_idx+(pi2s_config->mmap_index-MAX_I2S_PAGE)], 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3071 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)(pi2s_config->pMMAPRxBufPtr[rx_w_idx]), 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3074 + memcpy(pi2s_config->pMMAPRxBufPtr[rx_w_idx], pi2s_config->pPage0RxBuf8ptr, I2S_PAGE_SIZE);
3075 +#if defined(ARM_ARCH)
3076 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr0, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3078 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)(pi2s_config->pPage0RxBuf8ptr), 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3081 + pi2s_config->dmach = GDMA_I2S_RX0;
3086 +#ifdef CONFIG_I2S_MMAP
3087 + dma_sync_single_for_device(NULL, i2s_mmap_addr[rx_w_idx+(pi2s_config->mmap_index-MAX_I2S_PAGE)], I2S_PAGE_SIZE, DMA_FROM_DEVICE);
3088 +#if defined(ARM_ARCH)
3089 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, (u32)i2s_mmap_addr[rx_w_idx+(pi2s_config->mmap_index-MAX_I2S_PAGE)], 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3091 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)(pi2s_config->pMMAPRxBufPtr[rx_w_idx]), 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3094 + memcpy(pi2s_config->pMMAPRxBufPtr[rx_w_idx], pi2s_config->pPage1RxBuf8ptr, I2S_PAGE_SIZE);
3095 +#if defined(ARM_ARCH)
3096 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr1, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3098 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)(pi2s_config->pPage1RxBuf8ptr), 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3101 + pi2s_config->dmach = GDMA_I2S_RX1;
3104 +#if defined(CONFIG_I2S_WITH_AEC)
3105 + if(aecFuncP->AECNeEnq){
3106 + aecFuncP->AECNeEnq(0,pi2s_config->pMMAPRxBufPtr[rx_w_idx],I2S_PAGE_SIZE);
3112 +int i2s_dma_rx_transf_zero(i2s_config_type* ptri2s_config, u32 dma_ch)
3114 + if(dma_ch==GDMA_I2S_RX0)
3116 + memset(pi2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE);
3117 +#if defined(ARM_ARCH)
3118 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr0, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3120 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)pi2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3125 + memset(pi2s_config->pPage1RxBuf8ptr, 0, I2S_PAGE_SIZE);
3126 +#if defined(ARM_ARCH)
3127 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr1, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3129 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)pi2s_config->pPage1RxBuf8ptr, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3135 +void i2s_dma_tx_handler(u32 dma_ch)
3137 + pi2s_config->enLable = 1; /* TX:enLabel=1; RX:enLabel=2 */
3139 + if(pi2s_config->bTxDMAEnable==0)
3141 + if(pi2s_config->end_cnt != 0)
3143 + i2s_dma_tx_transf_data(pi2s_config, dma_ch);
3144 + pi2s_config->end_cnt --;
3145 + MSG("end_cnt = %d, r_idx = %d\n", pi2s_config->end_cnt, pi2s_config->tx_r_idx);
3149 + pi2s_config->tx_stop_cnt++;
3150 + i2s_dma_tx_soft_stop(pi2s_config, dma_ch);
3151 + MSG("tx_stop=%d, ch=%d\n", pi2s_config->tx_stop_cnt, dma_ch);
3152 + if (pi2s_config->tx_stop_cnt == 3)
3154 + wake_up_interruptible(&(pi2s_config->i2s_tx_qh));
3155 + _printk("T:wake up!!\n");
3161 + pi2s_config->tx_isr_cnt++;
3163 +#ifdef I2S_STATISTIC
3164 + i2s_int_status(dma_ch);
3167 + if(pi2s_config->bALSAEnable)
3169 + if(pi2s_config->dmaStat[STREAM_PLAYBACK])
3171 + if(!pi2s_config->bTrigger[STREAM_PLAYBACK]){
3172 + //_printk("trigger stop: rIdx:%d widx:%d\n", pi2s_config->tx_r_idx,pi2s_config->tx_w_idx);
3173 + i2s_dma_tx_transf_zero(pi2s_config, dma_ch);
3174 + if(pi2s_config->bPreTrigger[STREAM_PLAYBACK]){
3175 + /* mtk04880 commented:
3176 + * for corner case, there are cases which ALSA Trigger stop before disabling DMA.
3177 + * For which case, it needs to keep call snd_pcm_elapased to keep ALSA hw ptr updating.
3178 + * It is so called post stop handlment.
3180 + //_printk("post-stop\n");
3184 + //_printk("pre-stop\n");
3185 + wake_up_interruptible(&(pi2s_config->i2s_tx_qh));
3190 + if(!pi2s_config->bPreTrigger[STREAM_PLAYBACK])
3191 + pi2s_config->bPreTrigger[STREAM_PLAYBACK] = 1;
3198 + if(pi2s_config->tx_r_idx==pi2s_config->tx_w_idx)
3200 + /* Buffer Empty */
3201 + MSG("TXBE r=%d w=%d[i=%u,c=%u]\n",pi2s_config->tx_r_idx,pi2s_config->tx_w_idx,pi2s_config->tx_isr_cnt,dma_ch);
3202 +#ifdef I2S_STATISTIC
3203 + pi2s_status->txbuffer_unrun++;
3205 + i2s_dma_tx_transf_zero(pi2s_config, dma_ch);
3210 + if(pi2s_config->pMMAPTxBufPtr[pi2s_config->tx_r_idx]==NULL)
3212 + MSG("mmap buf NULL [%d]\n",pi2s_config->tx_r_idx);
3213 + i2s_dma_tx_transf_zero(pi2s_config, dma_ch);
3218 + if(pi2s_config->tx_pause_en == 1)
3220 + /* Enable PAUSE */
3221 + MSG("TX pause now\n");
3222 + i2s_dma_tx_transf_zero(pi2s_config, dma_ch);
3227 +#ifdef I2S_STATISTIC
3228 + pi2s_status->txbuffer_len--;
3230 + i2s_dma_tx_transf_data(pi2s_config, dma_ch);
3233 +#if defined(CONFIG_SND_MT76XX_SOC)
3234 + if(pi2s_config->bALSAEnable == 1){
3235 + if(pi2s_config->pss[STREAM_PLAYBACK])
3236 + snd_pcm_period_elapsed(pi2s_config->pss[STREAM_PLAYBACK]);
3239 + wake_up_interruptible(&(pi2s_config->i2s_tx_qh));
3243 +void i2s_dma_rx_handler(u32 dma_ch)
3245 + pi2s_config->enLable = 2; /* TX:enLabel=1; RX:enLabel=2 */
3246 +#if defined(CONFIG_I2S_TXRX)
3247 + if(pi2s_config->rx_isr_cnt==0)
3249 + pi2s_config->next_p0_idx = 0;
3250 + pi2s_config->next_p1_idx = 1;
3252 + pi2s_config->rx_isr_cnt++;
3254 +#ifdef I2S_STATISTIC
3255 + i2s_int_status(dma_ch);
3258 + if (pi2s_config->bRxDMAEnable==0)
3260 + pi2s_config->rx_stop_cnt++;
3261 + i2s_dma_rx_soft_stop(pi2s_config, dma_ch);
3262 + MSG("rx_stop=%d\n", pi2s_config->rx_stop_cnt);
3264 + if(pi2s_config->rx_stop_cnt == 2)
3266 + wake_up_interruptible(&(pi2s_config->i2s_rx_qh));
3267 + _printk("R:wake up!!\n");
3272 + if(pi2s_config->bALSAEnable)
3274 + if(pi2s_config->dmaStat[STREAM_CAPTURE]){
3275 + if(!pi2s_config->bTrigger[STREAM_CAPTURE]){
3276 + MSG("trigger stop: rIdx:%d widx:%d\n", pi2s_config->rx_r_idx,pi2s_config->rx_w_idx);
3277 + i2s_dma_rx_transf_zero(pi2s_config, dma_ch);
3278 + wake_up_interruptible(&(pi2s_config->i2s_rx_qh));
3285 + if(((pi2s_config->rx_w_idx+1)%MAX_I2S_PAGE)==pi2s_config->rx_r_idx){
3287 + MSG("RXBF r=%d w=%d[i=%u,c=%u]\n",pi2s_config->rx_r_idx,pi2s_config->rx_w_idx,pi2s_config->rx_isr_cnt,dma_ch);
3288 +#ifdef I2S_STATISTIC
3289 + pi2s_status->rxbuffer_unrun++;
3291 + i2s_dma_rx_transf_zero(pi2s_config, dma_ch);
3296 + if(pi2s_config->rx_pause_en == 1)
3298 + /* Enable PAUSE */
3299 + i2s_dma_rx_transf_zero(pi2s_config, dma_ch);
3304 +#ifdef I2S_STATISTIC
3305 + pi2s_status->rxbuffer_len++;
3307 + i2s_dma_rx_transf_data(pi2s_config, dma_ch);
3310 +#if defined(CONFIG_SND_MT76XX_SOC)
3311 + if(pi2s_config->bALSAEnable == 1){
3312 + if(pi2s_config->pss[STREAM_CAPTURE])
3313 + snd_pcm_period_elapsed(pi2s_config->pss[STREAM_CAPTURE]);
3316 + wake_up_interruptible(&(pi2s_config->i2s_rx_qh));
3321 +#ifdef I2S_STATISTIC
3322 +void i2s_int_status(u32 dma_ch)
3326 + if((pi2s_config->tx_isr_cnt>0)||(pi2s_config->rx_isr_cnt>0))
3328 + i2s_status = i2s_inw(I2S_INT_STATUS);
3330 + if(i2s_status®BIT(1, I2S_TX_DMA_FAULT))
3332 + pi2s_status->txdmafault++;
3334 + if(i2s_status®BIT(1, I2S_TX_OVRUN))
3336 + pi2s_status->txovrun++;
3338 + if(i2s_status®BIT(1, I2S_TX_UNRUN))
3340 + pi2s_status->txunrun++;
3342 + if(i2s_status®BIT(1, I2S_TX_THRES))
3344 + pi2s_status->txthres++;
3346 + if(i2s_status®BIT(1, I2S_RX_DMA_FAULT))
3348 + pi2s_status->rxdmafault++;
3350 + if(i2s_status®BIT(1, I2S_RX_OVRUN))
3352 + pi2s_status->rxovrun++;
3354 + if(i2s_status®BIT(1, I2S_RX_UNRUN))
3356 + pi2s_status->rxunrun++;
3358 + if(i2s_status®BIT(1, I2S_RX_THRES))
3360 + pi2s_status->rxthres++;
3364 + if(pi2s_config->enLable == 1)
3366 + if((pi2s_config->tx_isr_cnt>0) && (pi2s_config->tx_isr_cnt%40==0))
3368 + MSG("tisr i=%u,ch=%u,o=%u,u=%d,s=%X [r=%d,w=%d]\n",\
3369 + pi2s_config->tx_isr_cnt,dma_ch,pi2s_status->txovrun,pi2s_status->txunrun,\
3370 + i2s_inw(I2S_INT_STATUS),pi2s_config->tx_r_idx,pi2s_config->tx_w_idx);
3374 + if(pi2s_config->enLable == 2)
3376 + if((pi2s_config->rx_isr_cnt>0) && (pi2s_config->rx_isr_cnt%40==0))
3378 + MSG("risr i=%u,ch=%u,o=%u,u=%d,s=%X [r=%d,w=%d]\n",\
3379 + pi2s_config->rx_isr_cnt,dma_ch,pi2s_status->rxovrun,pi2s_status->rxunrun,\
3380 + i2s_inw(I2S_INT_STATUS),pi2s_config->rx_r_idx,pi2s_config->rx_w_idx);
3385 + *(unsigned long*)(I2S_INT_STATUS) = 0xFFFFFFFF;
3389 +#if defined(I2S_HW_INTERRUPT_EN)&&(I2S_SW_IRQ_EN)
3390 +irqreturn_t i2s_irq_isr(int irq, void *irqaction)
3394 + //MSG("i2s_irq_isr [0x%08X]\n",i2s_inw(I2S_INT_STATUS));
3395 + if((pi2s_config->tx_isr_cnt>0)||(pi2s_config->rx_isr_cnt>0))
3397 + i2s_status = i2s_inw(I2S_INT_STATUS);
3398 + MSG("i2s_irq_isr [0x%08X]\n",i2s_status);
3401 + return IRQ_HANDLED;
3403 + if(i2s_status®BIT(1, I2S_TX_DMA_FAULT))
3405 +#ifdef I2S_STATISTIC
3406 + pi2s_status->txdmafault++;
3409 + if(i2s_status®BIT(1, I2S_TX_OVRUN))
3411 +#ifdef I2S_STATISTIC
3412 + pi2s_status->txovrun++;
3415 + if(i2s_status®BIT(1, I2S_TX_UNRUN))
3417 +#ifdef I2S_STATISTIC
3418 + pi2s_status->txunrun++;
3421 + if(i2s_status®BIT(1, I2S_TX_THRES))
3423 +#ifdef I2S_STATISTIC
3424 + pi2s_status->txthres++;
3427 + if(i2s_status®BIT(1, I2S_RX_DMA_FAULT))
3429 +#ifdef I2S_STATISTIC
3430 + pi2s_status->rxdmafault++;
3433 + if(i2s_status®BIT(1, I2S_RX_OVRUN))
3435 +#ifdef I2S_STATISTIC
3436 + pi2s_status->rxovrun++;
3439 + if(i2s_status®BIT(1, I2S_RX_UNRUN))
3441 +#ifdef I2S_STATISTIC
3442 + pi2s_status->rxunrun++;
3445 + if(i2s_status®BIT(1, I2S_RX_THRES))
3447 +#ifdef I2S_STATISTIC
3448 + pi2s_status->rxthres++;
3451 + i2s_outw(I2S_INT_STATUS, 0xFFFFFFFF);
3452 + return IRQ_HANDLED;
3456 +void i2s_tx_task(unsigned long pData)
3458 + unsigned long flags;
3459 + spin_lock_irqsave(&pi2s_config->lock, flags);
3460 + //if (pi2s_config->bTxDMAEnable!=0)
3462 + if (pi2s_config->tx_unmask_ch!=0)
3464 + u32 dmach = pi2s_config->tx_unmask_ch;
3466 + for (ch = 0; ch < 16; ch++)
3468 + if (dmach& (1<<ch))
3470 + MSG("do unmask ch%d tisr=%d in tx_isr\n",ch,pi2s_config->tx_isr_cnt);
3471 + GdmaUnMaskChannel(ch);
3474 + pi2s_config->tx_unmask_ch = 0;
3477 + spin_unlock_irqrestore(&pi2s_config->lock, flags);
3480 +void i2s_rx_task(unsigned long pData)
3482 + unsigned long flags;
3483 + spin_lock_irqsave(&pi2s_config->lock, flags);
3484 + //if (pi2s_config->bRxDMAEnable!=0)
3486 + if (pi2s_config->rx_unmask_ch!=0)
3488 + u32 dmach = pi2s_config->rx_unmask_ch;
3490 + for (ch = 0; ch < 16; ch++)
3492 + if (dmach& (1<<ch))
3494 + MSG("do unmask ch%d risr=%d in rx_isr\n",ch,pi2s_config->rx_isr_cnt);
3495 + GdmaUnMaskChannel(ch);
3498 + pi2s_config->rx_unmask_ch = 0;
3502 + spin_unlock_irqrestore(&pi2s_config->lock, flags);
3506 +void i2s_dma_unmask_handler(u32 dma_ch)
3508 + MSG("i2s_dma_unmask_handler ch=%d\n",dma_ch);
3510 + GdmaUnMaskChannel(dma_ch);
3515 +void i2s_dma_tx_unmask_handler(u32 dma_ch)
3517 + MSG("i2s_dma_tx_unmask_handler ch=%d\n",dma_ch);
3518 + pi2s_config->tx_unmask_ch |= (1<<dma_ch);
3519 + tasklet_hi_schedule(&i2s_tx_tasklet);
3523 +void i2s_dma_rx_unmask_handler(u32 dma_ch)
3525 + MSG("i2s_dma_rx_unmask_handler ch=%d\n",dma_ch);
3526 + pi2s_config->rx_unmask_ch |= (1<<dma_ch);
3527 + tasklet_hi_schedule(&i2s_rx_tasklet);
3531 +void i2s_dma_mask_handler(u32 dma_ch)
3533 + MSG("i2s_dma_mask_handler ch=%d\n", dma_ch);
3534 + GdmaMaskChannel(dma_ch);
3538 +void i2s_dma_tx_init(i2s_config_type* ptri2s_config)
3540 + memset(pi2s_config->pPage0TxBuf8ptr, 0, I2S_PAGE_SIZE);
3541 + memset(pi2s_config->pPage1TxBuf8ptr, 0, I2S_PAGE_SIZE);
3542 +#if defined(ARM_ARCH)
3543 + GdmaI2sTx(i2s_txdma_addr0, I2S_TX_FIFO_WREG_PHY, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3544 + GdmaI2sTx(i2s_txdma_addr1, I2S_TX_FIFO_WREG_PHY, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3546 + GdmaI2sTx((u32)ptri2s_config->pPage0TxBuf8ptr, I2S_FIFO_WREG, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3547 + GdmaI2sTx((u32)ptri2s_config->pPage1TxBuf8ptr, I2S_FIFO_WREG, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3553 +void i2s_dma_rx_init(i2s_config_type* ptri2s_config)
3555 + memset(pi2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE);
3556 + memset(pi2s_config->pPage1RxBuf8ptr, 0, I2S_PAGE_SIZE);
3558 +#if defined(ARM_ARCH)
3559 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr0, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3560 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr1, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3562 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)ptri2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3563 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)ptri2s_config->pPage1RxBuf8ptr, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3569 +void i2s_dma_tx_end_handle(i2s_config_type* ptri2s_config)
3571 + if (ptri2s_config->tx_w_idx < ptri2s_config->tx_r_idx)
3573 + ptri2s_config->end_cnt = (ptri2s_config->tx_w_idx + MAX_I2S_PAGE)-ptri2s_config->tx_r_idx;
3574 + _printk("case1: w=%d, r=%d, end=%d\n", ptri2s_config->tx_w_idx, ptri2s_config->tx_r_idx, ptri2s_config->end_cnt);
3576 + else if (ptri2s_config->tx_w_idx > ptri2s_config->tx_r_idx)
3578 + ptri2s_config->end_cnt = ptri2s_config->tx_w_idx-ptri2s_config->tx_r_idx;
3579 + _printk("case2: w=%d, r=%d, end=%d\n", ptri2s_config->tx_w_idx, ptri2s_config->tx_r_idx, ptri2s_config->end_cnt);
3583 + _printk("case3: w=%d, r=%d, end=%d\n", ptri2s_config->tx_w_idx, ptri2s_config->tx_r_idx, ptri2s_config->end_cnt);
3587 + if (ptri2s_config->end_cnt > 0)
3589 + interruptible_sleep_on(&(ptri2s_config->i2s_tx_qh));
3595 +void i2s_tx_end_sleep_on(i2s_config_type* ptri2s_config)
3597 + while(ptri2s_config->tx_stop_cnt<3)
3598 + interruptible_sleep_on(&(ptri2s_config->i2s_tx_qh));
3603 +void i2s_rx_end_sleep_on(i2s_config_type* ptri2s_config)
3605 + while(ptri2s_config->rx_stop_cnt<2)
3606 + interruptible_sleep_on(&(ptri2s_config->i2s_rx_qh));
3610 +int i2s_dma_tx_soft_stop(i2s_config_type* ptri2s_config, u32 dma_ch)
3612 + if(dma_ch==GDMA_I2S_TX0)
3614 +#if defined(ARM_ARCH)
3615 + GdmaI2sTx(i2s_txdma_addr0, I2S_TX_FIFO_WREG_PHY, 0, 4, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3617 + GdmaI2sTx((u32)pi2s_config->pPage0TxBuf8ptr, I2S_TX_FIFO_WREG, 0, 4, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3622 +#if defined(ARM_ARCH)
3623 + GdmaI2sTx(i2s_txdma_addr1, I2S_TX_FIFO_WREG_PHY, 1, 4, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3625 + GdmaI2sTx((u32)pi2s_config->pPage1TxBuf8ptr, I2S_TX_FIFO_WREG, 1, 4, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3632 +int i2s_dma_rx_soft_stop(i2s_config_type* ptri2s_config, u32 dma_ch)
3634 + if(dma_ch==GDMA_I2S_RX0)
3636 + memset(pi2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE);
3637 +#if defined(ARM_ARCH)
3638 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr0, 0, 4, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3640 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)pi2s_config->pPage0RxBuf8ptr, 0, 4, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3645 + memset(pi2s_config->pPage1RxBuf8ptr, 0, I2S_PAGE_SIZE);
3646 +#if defined(ARM_ARCH)
3647 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr1, 1, 4, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3649 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)pi2s_config->pPage1RxBuf8ptr, 1, 4, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3656 +void i2s_gen_test_pattern(void)
3659 + for (i=0; i<I2S_PAGE_SIZE; i++)
3661 + test_buf[i] = 0x5A;
3662 + test_buf_1[i] = 0x11;
3663 + test_buf_2[i] = 0x22;
3668 +int i2s_put_audio(i2s_config_type* ptri2s_config, unsigned long arg)
3670 + unsigned long flags;
3674 + spin_lock_irqsave(&ptri2s_config->lock, flags);
3676 + if(((ptri2s_config->tx_w_idx+4)%MAX_I2S_PAGE)!=ptri2s_config->tx_r_idx)
3678 + ptri2s_config->tx_w_idx = (ptri2s_config->tx_w_idx+1)%MAX_I2S_PAGE;
3679 + tx_w_idx = ptri2s_config->tx_w_idx;
3680 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3681 + //_printk("put TB[%d] for user write\n",ptri2s_config->tx_w_idx);
3682 +#if defined(CONFIG_I2S_MMAP)
3683 + put_user(tx_w_idx, (int*)arg);
3685 + copy_from_user(ptri2s_config->pMMAPTxBufPtr[tx_w_idx], (char*)arg, I2S_PAGE_SIZE);
3687 + pi2s_status->txbuffer_len++;
3688 + //spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3694 + //_printk("TBF tr=%d, tw=%d\n", ptri2s_config->tx_r_idx, ptri2s_config->tx_w_idx);
3695 + pi2s_status->txbuffer_ovrun++;
3696 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3697 + interruptible_sleep_on(&(ptri2s_config->i2s_tx_qh));
3698 + if (ptri2s_config->bTxDMAEnable==0 && ptri2s_config->end_cnt==0)
3700 + _printk("wake up for exit i2s driver\n");
3701 + put_user(-1, (int*)arg);
3710 +int i2s_get_audio(i2s_config_type* ptri2s_config, unsigned long arg)
3712 + unsigned long flags;
3716 + spin_lock_irqsave(&ptri2s_config->lock, flags);
3717 + //_printk("GA rr=%d, rw=%d,i=%d\n", ptri2s_config->rx_r_idx, ptri2s_config->rx_w_idx,ptri2s_config->rx_isr_cnt);
3718 + if(((ptri2s_config->rx_r_idx+2)%MAX_I2S_PAGE)!=ptri2s_config->rx_w_idx)
3720 + rx_r_idx = ptri2s_config->rx_r_idx;
3721 + ptri2s_config->rx_r_idx = (ptri2s_config->rx_r_idx+1)%MAX_I2S_PAGE;
3722 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3723 +#if defined(CONFIG_I2S_MMAP)
3724 + put_user(rx_r_idx, (int*)arg);
3726 + copy_to_user((char*)arg, ptri2s_config->pMMAPRxBufPtr[rx_r_idx], I2S_PAGE_SIZE);
3728 + //_printk("rx_r_idx=%d\n", ptri2s_config->rx_r_idx);
3729 + //ptri2s_config->rx_r_idx = (ptri2s_config->rx_r_idx+1)%MAX_I2S_PAGE;
3730 + pi2s_status->rxbuffer_len--;
3731 + //spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3737 + //_printk("RBF rr=%d, rw=%d\n", ptri2s_config->rx_r_idx, ptri2s_config->rx_w_idx);
3738 + pi2s_status->rxbuffer_ovrun++;
3739 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3740 + interruptible_sleep_on(&(ptri2s_config->i2s_rx_qh));
3742 +#if defined(CONFIG_I2S_WITH_AEC)
3743 + if(aecFuncP->AECECDeq){
3744 + aecFuncP->AECECDeq(0,pi2s_config->pMMAPRxBufPtr[ptri2s_config->rx_r_idx],I2S_PAGE_SIZE);
3752 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
3753 +long i2s_ioctl (struct file *filp, unsigned int cmd, unsigned long arg)
3755 +int i2s_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
3759 + i2s_config_type* ptri2s_config;
3760 + unsigned long flags;
3762 + ptri2s_config = filp->private_data;
3765 + spin_lock_irqsave(&ptri2s_config->lock, flags);
3766 + i2s_reset_config(ptri2s_config);
3767 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3770 + spin_lock_irqsave(&ptri2s_config->lock, flags);
3771 +#if defined(CONFIG_I2S_WM8960)
3772 + if((arg>MAX_SRATE_HZ)||(arg<MIN_SRATE_HZ))
3774 + MSG("Audio sampling rate %u should be %d ~ %d Hz. Set SRate to 48000Hz\n", (u32)arg, MIN_SRATE_HZ, MAX_SRATE_HZ);
3775 + ptri2s_config->srate = 48000;
3776 + spin_unlock(&ptri2s_config->lock);
3779 +#elif defined(CONFIG_I2S_WM8750)
3780 + if((arg>MAX_SRATE_HZ)||(arg<MIN_SRATE_HZ))
3782 + MSG("Audio sampling rate %u should be %d ~ %d Hz. Set SRate to 96000Hz\n", (u32)arg, MIN_SRATE_HZ, MAX_SRATE_HZ);
3783 + ptri2s_config->srate = 96000;
3784 + spin_unlock(&ptri2s_config->lock);
3788 + ptri2s_config->srate = arg;
3789 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3790 + MSG("set audio sampling rate to %d Hz\n", ptri2s_config->srate);
3793 + spin_lock_irqsave(&ptri2s_config->lock, flags);
3795 + if((int)arg > 127)
3796 + ptri2s_config->txvol = 127;
3797 + else if((int)arg < 48)
3798 + ptri2s_config->txvol = 48;
3800 + ptri2s_config->txvol = arg;
3802 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3804 + spin_lock_irqsave(&ptri2s_config->lock, flags);
3805 +#if (defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751))
3806 + audiohw_set_master_vol(arg,arg);
3807 +#elif defined(CONFIG_I2S_WM8960)
3808 + audiohw_set_lineout_vol(1, ptri2s_config->txvol, ptri2s_config->txvol);
3810 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3813 + spin_lock_irqsave(&ptri2s_config->lock, flags);
3816 + ptri2s_config->rxvol = 63;
3817 + else if((int)arg < 0)
3818 + ptri2s_config->rxvol = 0;
3820 + ptri2s_config->rxvol = arg;
3822 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3824 +#if defined (CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
3825 + case I2S_WORD_LEN:
3826 + spin_lock_irqsave(&ptri2s_config->lock, flags);
3827 + if((int)arg == 16)
3829 + ptri2s_config->wordlen_24b = 0;
3830 + MSG("Enable 16 bit word length.\n");
3832 + else if ((int)arg == 24)
3834 + ptri2s_config->wordlen_24b = 1;
3835 + MSG("Enable 24 bit word length.\n");
3839 + MSG("MT7628 only support 16bit/24bit word length.\n");
3840 + spin_unlock(&ptri2s_config->lock);
3843 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3845 + case I2S_ENDIAN_FMT:
3846 + spin_lock_irqsave(&ptri2s_config->lock, flags);
3849 + ptri2s_config->little_edn = 1;
3850 + MSG("Little endian format.\n");
3854 + ptri2s_config->little_edn = 0;
3855 + MSG("Big endian format.\n");
3857 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3860 + case I2S_INTERNAL_LBK:
3861 + spin_lock_irqsave(&ptri2s_config->lock, flags);
3864 + ptri2s_config->lbk = 1;
3865 + MSG("Enable internal loopback.\n");
3869 + ptri2s_config->lbk = 0;
3870 + MSG("Disable internal loopback.\n");
3872 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3874 + case I2S_EXTERNAL_LBK:
3875 + spin_lock_irqsave(&ptri2s_config->lock, flags);
3878 + ptri2s_config->extlbk = 1;
3879 + MSG("Enable external loopback.\n");
3883 + ptri2s_config->extlbk = 0;
3884 + MSG("Disable external loopback.\n");
3886 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3888 + case I2S_TXRX_COEXIST:
3889 + spin_lock_irqsave(&ptri2s_config->lock, flags);
3892 + ptri2s_config->txrx_coexist = 1;
3893 + MSG("TX/RX coexist.\n");
3897 + ptri2s_config->txrx_coexist = 0;
3898 + MSG("TX/RX coexist.\n");
3900 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3903 + case I2S_TX_ENABLE:
3904 + spin_lock_irqsave(&ptri2s_config->lock, flags);
3905 + MSG("I2S_TXENABLE\n");
3907 + pi2s_config->tx_unmask_ch = 0;
3908 + tasklet_init(&i2s_tx_tasklet, i2s_tx_task, (u32)pi2s_config);
3910 + pi2s_config->dis_match = 0;
3911 + pi2s_config->start_cnt = 0;
3912 + i2s_gen_test_pattern();
3914 + /* allocate tx buffer */
3915 + i2s_txPagebuf_alloc(ptri2s_config);
3916 + i2s_txbuf_alloc(ptri2s_config);
3918 + /* Init two dma channels */
3919 + i2s_dma_tx_init(ptri2s_config);
3920 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3922 + spin_lock_irqsave(&ptri2s_config->lock, flags);
3923 + /* Init & config all tx param */
3924 + i2s_reset_tx_param(ptri2s_config);
3925 + ptri2s_config->bTxDMAEnable = 1;
3926 + /* Clear all ALSA related config */
3927 + ptri2s_config->bALSAEnable = 0;
3928 + ptri2s_config->bALSAMMAPEnable = 0;
3930 + i2s_tx_config(ptri2s_config);
3932 + if(ptri2s_config->bRxDMAEnable==0)
3933 + i2s_clock_enable(ptri2s_config);
3934 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3936 + spin_lock_irqsave(&ptri2s_config->lock, flags);
3937 +#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
3938 + audiohw_set_lineout_vol(1, ptri2s_config->txvol, ptri2s_config->txvol);
3940 + GdmaUnMaskChannel(GDMA_I2S_TX0);
3942 + i2s_tx_enable(ptri2s_config);
3944 + /* Kick off dma channel */
3945 + //GdmaUnMaskChannel(GDMA_I2S_TX0);
3947 + MSG("I2S_TXENABLE done\n");
3948 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3950 + case I2S_TX_DISABLE:
3951 + spin_lock_irqsave(&ptri2s_config->lock, flags);
3952 + MSG("I2S_TXDISABLE\n");
3954 + //tasklet_kill(&i2s_tx_tasklet);
3956 + /* Handle tx end data */
3957 + ptri2s_config->bTxDMAEnable = 0;
3958 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3960 + i2s_tx_end_sleep_on(ptri2s_config);
3962 + tasklet_kill(&i2s_tx_tasklet);
3964 + spin_lock_irqsave(&ptri2s_config->lock, flags);
3965 + i2s_reset_tx_param(ptri2s_config);
3966 + i2s_tx_disable(ptri2s_config);
3967 + if((ptri2s_config->bRxDMAEnable==0)&&(ptri2s_config->bTxDMAEnable==0))
3968 + i2s_clock_disable(ptri2s_config);
3970 + i2s_txbuf_free(ptri2s_config);
3971 + if(ptri2s_config->mmap_index <= MAX_I2S_PAGE)
3972 + ptri2s_config->mmap_index = 0;
3974 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3976 + case I2S_RX_ENABLE:
3977 + spin_lock_irqsave(&ptri2s_config->lock, flags);
3978 + MSG("I2S_RXENABLE\n");
3979 + pi2s_config->rx_unmask_ch = 0;
3980 + tasklet_init(&i2s_rx_tasklet, i2s_rx_task, (u32)pi2s_config);
3982 + /* allocate rx buffer */
3983 + i2s_rxPagebuf_alloc(ptri2s_config);
3984 + i2s_rxbuf_alloc(ptri2s_config);
3986 + /* Init two dma channels */
3987 + i2s_dma_rx_init(ptri2s_config);
3988 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
3990 + spin_lock_irqsave(&ptri2s_config->lock, flags);
3991 + /* Init & config all rx param */
3992 + i2s_reset_rx_param(ptri2s_config);
3993 + ptri2s_config->bRxDMAEnable = 1;
3994 + ptri2s_config->bALSAEnable = 0;
3995 + ptri2s_config->bALSAMMAPEnable = 0;
3997 + i2s_rx_config(ptri2s_config);
3999 + if(ptri2s_config->bTxDMAEnable==0)
4000 + i2s_clock_enable(ptri2s_config);
4002 +#if defined(CONFIG_I2S_TXRX)
4003 +#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
4004 + audiohw_set_linein_vol(ptri2s_config->rxvol, ptri2s_config->rxvol);
4007 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4009 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4010 + /* Kick off dma channel */
4011 + GdmaUnMaskChannel(GDMA_I2S_RX0);
4013 + i2s_rx_enable(ptri2s_config);
4014 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4016 + case I2S_RX_DISABLE:
4017 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4018 + MSG("I2S_RXDISABLE\n");
4019 + //tasklet_kill(&i2s_rx_tasklet);
4021 + ptri2s_config->bRxDMAEnable = 0;
4022 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4024 + i2s_rx_end_sleep_on(ptri2s_config);
4025 + tasklet_kill(&i2s_rx_tasklet);
4027 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4028 + i2s_reset_rx_param(ptri2s_config);
4029 + i2s_rx_disable(ptri2s_config);
4030 + if((ptri2s_config->bRxDMAEnable==0)&&(ptri2s_config->bTxDMAEnable==0))
4031 + i2s_clock_disable(ptri2s_config);
4033 + i2s_rxbuf_free(ptri2s_config);
4034 + if(ptri2s_config->mmap_index <= MAX_I2S_PAGE)
4035 + ptri2s_config->mmap_index = 0;
4036 + //i2s_rxPagebuf_free(ptri2s_config);
4037 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4039 + case I2S_PUT_AUDIO:
4040 + i2s_put_audio(ptri2s_config, arg);
4042 + case I2S_GET_AUDIO:
4043 + i2s_get_audio(ptri2s_config, arg);
4046 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4047 + MSG("TxGDMA STOP\n");
4048 + ptri2s_config->bTxDMAEnable = 0;
4049 + ptri2s_config->end_cnt = 0;
4050 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4052 + while(ptri2s_config->tx_stop_cnt<3)
4053 + interruptible_sleep_on(&(ptri2s_config->i2s_tx_qh));
4055 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4056 + i2s_reset_tx_param(ptri2s_config);
4057 + i2s_tx_disable(ptri2s_config);
4058 + if((ptri2s_config->bRxDMAEnable==0)&&(ptri2s_config->bTxDMAEnable==0))
4059 + i2s_clock_disable(ptri2s_config);
4061 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4063 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4064 + i2s_txbuf_free(ptri2s_config);
4065 + if(ptri2s_config->mmap_index <= MAX_I2S_PAGE)
4066 + ptri2s_config->mmap_index = 0;
4067 + //i2s_txPagebuf_free(ptri2s_config);
4068 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4070 + case I2S_TX_PAUSE:
4071 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4072 + ptri2s_config->tx_pause_en = 1;
4073 + MSG("* tx_pause_en = 1 *\n");
4074 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4076 + case I2S_TX_RESUME:
4077 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4078 + ptri2s_config->tx_pause_en = 0;
4079 + MSG("# tx_pause_en = 0 #\n");
4080 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4083 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4084 + MSG("I2S_RX_STOP\n");
4085 + ptri2s_config->bRxDMAEnable = 0;
4086 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4088 + while(ptri2s_config->rx_stop_cnt<2)
4089 + interruptible_sleep_on(&(ptri2s_config->i2s_rx_qh));
4091 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4092 + i2s_reset_rx_param(ptri2s_config);
4093 + i2s_rx_disable(ptri2s_config);
4094 + if((ptri2s_config->bRxDMAEnable==0)&&(ptri2s_config->bTxDMAEnable==0))
4095 + i2s_clock_disable(ptri2s_config);
4096 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4098 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4099 + i2s_rxbuf_free(ptri2s_config);
4100 + if(ptri2s_config->mmap_index <= MAX_I2S_PAGE)
4101 + ptri2s_config->mmap_index = 0;
4102 + //i2s_rxPagebuf_free(ptri2s_config);
4103 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4105 + case I2S_RX_PAUSE:
4106 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4107 + ptri2s_config->rx_pause_en = 1;
4108 + MSG("* rx_pause_en = 1 *\n");
4109 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4111 + case I2S_RX_RESUME:
4112 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4113 + ptri2s_config->rx_pause_en = 0;
4114 + MSG("# rx_pause_en = 0 #\n");
4115 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4117 + case I2S_CODEC_MIC_BOOST:
4118 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4120 + ptri2s_config->micboost = 3;
4121 + else if((int)arg < 0)
4122 + ptri2s_config->micboost = 0;
4124 + ptri2s_config->micboost = arg;
4125 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4127 + case I2S_CODEC_MIC_IN:
4128 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4130 + ptri2s_config->micin = 1;
4132 + ptri2s_config->micin = 0;
4133 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4135 + case I2S_CLOCK_ENABLE:
4136 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4137 + i2s_clock_disable(ptri2s_config);
4138 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4139 + ptri2s_config->wordlen_24b = 1;
4141 + i2s_tx_config(ptri2s_config);
4142 + i2s_clock_enable(ptri2s_config);
4143 + i2s_tx_enable(ptri2s_config);
4144 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4146 + case I2S_DEBUG_CODEC:
4147 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4148 + for (i=0; i<10; i++)
4150 + _printk("### i=%d ###\n", i);
4151 + i2s_clock_enable(ptri2s_config);
4152 + i2s_clock_disable(ptri2s_config);
4154 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4156 +#if defined(CONFIG_I2S_MS_CTRL)
4157 + case I2S_MS_MODE_CTRL:
4158 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4161 + ptri2s_config->slave_en = 1;
4162 + _printk("I2S in slave mode.\n");
4166 + ptri2s_config->slave_en = 0;
4167 + _printk("I2S in master mode.\n");
4169 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4172 + case I2S_DEBUG_CLKGEN:
4173 + case I2S_DEBUG_INLBK:
4174 + case I2S_DEBUG_EXLBK:
4175 + case I2S_DEBUG_CODECBYPASS:
4176 + case I2S_DEBUG_FMT:
4177 +#if defined(CONFIG_I2S_WM8960)
4178 + case I2S_DEBUG_CODEC_EXLBK:
4180 + case I2S_DEBUG_RESET:
4181 + i2s_debug_cmd(cmd, arg);
4184 + MSG("i2s_ioctl: command format error\n");
4190 +/************************
4193 + ************************/
4194 +char* i2s_memPool_Alloc(i2s_config_type* ptri2s_config,int dir)
4196 + //_printk("%s\n",__func__);
4197 + if(!ptri2s_config)
4199 + if(dir == STREAM_PLAYBACK){
4200 +#if defined(CONFIG_I2S_MMAP)
4201 + i2s_mmap_alloc(I2S_TOTAL_PAGE_SIZE);
4203 + i2s_txbuf_alloc(ptri2s_config);
4204 + return ptri2s_config->pMMAPTxBufPtr[0];
4206 +#if defined(CONFIG_I2S_MMAP)
4207 + i2s_mmap_alloc(I2S_TOTAL_PAGE_SIZE);
4209 + i2s_rxbuf_alloc(ptri2s_config);
4210 + return ptri2s_config->pMMAPRxBufPtr[0];
4215 +void i2s_memPool_free(i2s_config_type* ptri2s_config,int dir)
4217 + if(!ptri2s_config)
4219 + if(dir == STREAM_PLAYBACK){
4220 +#if defined(CONFIG_I2S_MMAP)
4221 + i2s_mem_unmap(ptri2s_config);
4223 + i2s_txbuf_free(ptri2s_config);
4225 +#if defined(CONFIG_I2S_MMAP)
4226 + i2s_mem_unmap(ptri2s_config);
4228 + i2s_rxbuf_free(ptri2s_config);
4234 +int i2s_page_prepare(i2s_config_type* ptri2s_config,int dir)
4236 + if(dir == STREAM_PLAYBACK){
4237 + /* allocate tx buffer */
4238 + i2s_txPagebuf_alloc(ptri2s_config);
4239 + i2s_dma_tx_init(ptri2s_config);
4241 + /* allocate rx buffer */
4242 + i2s_rxPagebuf_alloc(ptri2s_config);
4243 + i2s_dma_rx_init(ptri2s_config);
4248 +int i2s_page_release(i2s_config_type* ptri2s_config,int dir)
4250 + if(!ptri2s_config)
4252 + if(dir == STREAM_PLAYBACK)
4253 + i2s_txPagebuf_free(ptri2s_config);
4255 + i2s_rxPagebuf_free(ptri2s_config);
4260 +int i2s_startup(void)
4262 + memset(pi2s_config, 0, sizeof(i2s_config_type));
4264 +#ifdef I2S_STATISTIC
4265 + memset(pi2s_status, 0, sizeof(i2s_status_type));
4268 + i2s_param_init(pi2s_config);
4269 + pi2s_config->bALSAEnable = 1;
4270 +#if defined(CONFIG_I2S_MMAP)
4271 + pi2s_config->bALSAMMAPEnable = 1;
4274 +#if defined (CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4275 + pi2s_config->little_edn = 1;
4278 + init_waitqueue_head(&(pi2s_config->i2s_tx_qh));
4279 + init_waitqueue_head(&(pi2s_config->i2s_rx_qh));
4280 + spin_lock_init(&pi2s_config->lock);
4285 +int gdma_En_Switch(i2s_config_type* ptri2s_config,int dir,int enabled){
4286 + if(!ptri2s_config)
4288 + if(dir == STREAM_PLAYBACK){
4289 + ptri2s_config->bTxDMAEnable = enabled;
4290 + //MSG("%s:%d\n",__func__,ptri2s_config->bTxDMAEnable);
4292 + ptri2s_config->bRxDMAEnable = enabled;
4297 +int i2s_audio_exchange(i2s_config_type* ptri2s_config,int dir,unsigned long arg)
4299 + //MSG("I2S_PUT_AUDIO\n");
4300 + if(!ptri2s_config)
4302 + if(dir == STREAM_PLAYBACK){
4303 + i2s_put_audio(ptri2s_config, arg);
4305 + i2s_get_audio(ptri2s_config, arg);
4310 +void gdma_mask_handler(u32 dma_ch)
4312 + i2s_dma_mask_handler(dma_ch);
4316 +void gdma_unmask_handler(u32 dma_ch)
4318 + i2s_dma_unmask_handler(dma_ch);
4322 +u32 i2s_mmap_phys_addr(i2s_config_type* ptri2s_config)
4324 + if((ptri2s_config->pMMAPBufPtr[0]!=NULL) && (ptri2s_config->mmap_index == MAX_I2S_PAGE))
4325 + return (dma_addr_t)i2s_mmap_addr[0];
4326 + else if((ptri2s_config->pMMAPBufPtr[MAX_I2S_PAGE]!=NULL) && (ptri2s_config->mmap_index == MAX_I2S_PAGE*2))
4327 + return (dma_addr_t)i2s_mmap_addr[MAX_I2S_PAGE];
4332 +EXPORT_SYMBOL(i2s_startup);
4333 +EXPORT_SYMBOL(i2s_mem_unmap);
4334 +EXPORT_SYMBOL(i2s_mmap_alloc);
4335 +EXPORT_SYMBOL(i2s_mmap_remap);
4336 +EXPORT_SYMBOL(i2s_param_init);
4337 +EXPORT_SYMBOL(i2s_txbuf_alloc);
4338 +EXPORT_SYMBOL(i2s_rxbuf_alloc);
4339 +EXPORT_SYMBOL(i2s_txPagebuf_alloc);
4340 +EXPORT_SYMBOL(i2s_rxPagebuf_alloc);
4341 +EXPORT_SYMBOL(i2s_txbuf_free);
4342 +EXPORT_SYMBOL(i2s_rxbuf_free);
4343 +EXPORT_SYMBOL(i2s_txPagebuf_free);
4344 +EXPORT_SYMBOL(i2s_rxPagebuf_free);
4345 +EXPORT_SYMBOL(i2s_rx_disable);
4346 +EXPORT_SYMBOL(i2s_tx_disable);
4347 +EXPORT_SYMBOL(i2s_rx_enable);
4348 +EXPORT_SYMBOL(i2s_tx_enable);
4349 +EXPORT_SYMBOL(i2s_rx_config);
4350 +EXPORT_SYMBOL(i2s_tx_config);
4351 +EXPORT_SYMBOL(i2s_reset_config);
4352 +EXPORT_SYMBOL(i2s_clock_disable);
4353 +EXPORT_SYMBOL(i2s_clock_enable);
4354 +EXPORT_SYMBOL(i2s_reset_rx_param);
4355 +EXPORT_SYMBOL(i2s_reset_tx_param);
4356 +EXPORT_SYMBOL(i2s_dma_rx_handler);
4357 +EXPORT_SYMBOL(i2s_dma_tx_handler);
4358 +EXPORT_SYMBOL(i2s_dma_unmask_handler);
4359 +EXPORT_SYMBOL(i2s_dma_tx_unmask_handler);
4360 +EXPORT_SYMBOL(i2s_dma_rx_unmask_handler);
4361 +EXPORT_SYMBOL(i2s_dma_mask_handler);
4362 +EXPORT_SYMBOL(i2s_dma_tx_init);
4363 +EXPORT_SYMBOL(i2s_dma_rx_init);
4364 +EXPORT_SYMBOL(i2s_tx_end_sleep_on);
4365 +EXPORT_SYMBOL(i2s_rx_end_sleep_on);
4366 +EXPORT_SYMBOL(i2s_mmap_phys_addr);
4367 +EXPORT_SYMBOL(i2s_open);
4368 +EXPORT_SYMBOL(pi2s_config);
4369 +#if defined(CONFIG_I2S_IN_MCLK)
4370 +#if defined(CONFIG_I2S_MCLK_12MHZ)
4371 +EXPORT_SYMBOL(i2s_refclk_12m_enable);
4373 +#if defined(CONFIG_I2S_MCLK_12P288MHZ)
4374 +EXPORT_SYMBOL(i2s_refclk_12p288m_enable);
4377 +#if defined(MT7628_ASIC_BOARD) || defined(CONFIG_ARCH_MT7623)
4378 +EXPORT_SYMBOL(i2s_driving_strength_adjust);
4380 +EXPORT_SYMBOL(i2s_refclk_disable);
4381 +EXPORT_SYMBOL(i2s_refclk_gpio_out_config);
4382 +EXPORT_SYMBOL(i2s_refclk_gpio_in_config);
4383 +EXPORT_SYMBOL(i2s_share_pin_config);
4384 +EXPORT_SYMBOL(i2s_share_pin_mt7623);
4385 +EXPORT_SYMBOL(i2s_ws_config);
4386 +EXPORT_SYMBOL(i2s_mode_config);
4387 +EXPORT_SYMBOL(i2s_codec_frequency_config);
4388 +EXPORT_SYMBOL(i2s_dma_tx_transf_data);
4389 +EXPORT_SYMBOL(i2s_dma_tx_transf_zero);
4390 +EXPORT_SYMBOL(i2s_dma_rx_transf_data);
4391 +EXPORT_SYMBOL(i2s_dma_rx_transf_zero);
4392 +EXPORT_SYMBOL(i2s_dma_tx_end_handle);
4393 +EXPORT_SYMBOL(i2s_dma_tx_soft_stop);
4394 +EXPORT_SYMBOL(i2s_dma_rx_soft_stop);
4395 +EXPORT_SYMBOL(i2s_tx_task);
4396 +EXPORT_SYMBOL(i2s_rx_task);
4398 +EXPORT_SYMBOL(i2s_memPool_Alloc);
4399 +EXPORT_SYMBOL(i2s_memPool_free);
4400 +EXPORT_SYMBOL(i2s_page_prepare);
4401 +EXPORT_SYMBOL(i2s_page_release);
4402 +EXPORT_SYMBOL(gdma_En_Switch);
4403 +EXPORT_SYMBOL(i2s_audio_exchange);
4404 +EXPORT_SYMBOL(gdma_mask_handler);
4405 +EXPORT_SYMBOL(gdma_unmask_handler);
4406 +#if defined(CONFIG_I2S_WITH_AEC)
4407 +EXPORT_SYMBOL(aecFuncP);
4409 +module_init(i2s_mod_init);
4410 +module_exit(i2s_mod_exit);
4412 +MODULE_DESCRIPTION("Ralink SoC I2S Controller Module");
4413 +MODULE_AUTHOR("Qwert Chin <qwert.chin@ralinktech.com.tw>");
4414 +MODULE_SUPPORTED_DEVICE("I2S");
4415 +MODULE_VERSION(I2S_MOD_VERSION);
4416 +MODULE_LICENSE("GPL");
4417 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
4418 +MODULE_PARM (i2sdrv_major, "i");
4420 +module_param (i2sdrv_major, int, 0);
4423 +++ b/sound/soc/mtk/i2s_ctrl.h
4425 +#ifndef __RALINK_I2S_H_
4426 +#define __RALINK_I2S_H_
4429 +//#include <asm/rt2880/rt_mmap.h>
4432 +#if defined(CONFIG_I2S_WITH_AEC)
4433 +#include "aec/aec_api.h"
4436 +#define I2S_MAX_DEV 1
4437 +#define I2S_MOD_VERSION "0.1"
4438 +#define phys_to_bus(a) (a & 0x1FFFFFFF)
4441 +#define u32 unsigned int
4445 +#define u16 unsigned short
4449 +#define u8 unsigned char
4453 +#define REGBIT(x, n) (x << n)
4456 +#define Virtual2Physical(x) (((int)x) & 0x1fffffff)
4457 +#define Physical2Virtual(x) (((int)x) | 0x80000000)
4458 +#define Virtual2NonCache(x) (((int)x) | 0x20000000)
4459 +#define Physical2NonCache(x) (((int)x) | 0xa0000000)
4460 +#define NonCache2Virtual(x) (((int)x) & 0xDFFFFFFF)
4462 +#if defined(CONFIG_I2S_MCLK_12MHZ)
4463 +#define CONFIG_I2S_CODEC_PLL_EN 1
4465 +#define CONFIG_I2S_CODEC_PLL_EN 0
4468 +//#define CONFIG_I2S_MS_CTRL
4469 +//#define CONFIG_I2S_MS_MODE
4470 +//#define memory_test
4472 +#if defined (CONFIG_ARCH_MT7623)
4473 +#define MT7623_ASIC_BOARD
4477 +#if defined (CONFIG_RALINK_MT7621)
4478 +#define MT7621_ASIC_BOARD
4481 +#if defined (CONFIG_RALINK_MT7628)
4482 +#define MT7628_ASIC_BOARD
4485 +//#define I2S_DEBUG_PRN
4486 +#ifdef I2S_DEBUG_PRN
4487 +#define MSG(fmt, args...) printk("I2S: " fmt, ## args)
4489 +#define MSG(fmt, args...) { }
4492 +#ifdef I2S_DEBUG_PRN
4493 +#define i2s_outw(address, value) do{printk("0x%08X = 0x%08X\n",(u32)address,(u32)value);*((volatile uint32_t *)(address)) = cpu_to_le32(value);}while(0)
4495 +#define i2s_outw(address, value) *((volatile uint32_t *)(address)) = cpu_to_le32(value)
4497 +#define i2s_inw(address) le32_to_cpu(*(volatile u32 *)(address))
4499 +/* HW feature definiations */
4500 +#if defined(CONFIG_RALINK_RT3883)
4501 +#define CONFIG_I2S_TXRX 1
4502 +#define CONFIG_I2S_IN_MCLK 1
4503 +//#define CONFIG_I2S_WS_EDGE 1
4504 +#define CONFIG_I2S_FRAC_DIV 1
4505 +#define CONFIG_I2S_IN_CLK 1
4506 +#define CONFIG_I2S_MS_MODE 1
4509 +#if defined(CONFIG_RALINK_RT3352)||defined(CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) \
4510 + || defined(CONFIG_RALINK_RT6855A) || defined(CONFIG_RALINK_MT7620) || defined(CONFIG_RALINK_MT7621) \
4511 + || defined (CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4512 +#define CONFIG_I2S_TXRX 1
4513 +//#define CONFIG_I2S_WS_EDGE 1
4514 +#define CONFIG_I2S_FRAC_DIV 1
4515 +#define CONFIG_I2S_IN_CLK 1
4518 +#if defined(CONFIG_RALINK_RT3350)
4519 +#define CONFIG_I2S_IN_MCLK 1
4522 +#if defined(CONFIG_RALINK_RT3052)
4523 +#define CONFIG_I2S_MS_MODE 1
4526 +/* This is decided in menuconfig */
4527 +#define CONFIG_I2S_MMAP 1
4529 +/* For MT7623 ASIC PLL Setting */
4530 +#if defined(CONFIG_ARCH_MT7623)
4531 +#define AUD1PLL_CON0 (0xF0209270)
4532 +#define AUD1PLL_CON1 (0xF0209274)
4533 +#define AUD1PLL_CON2 (0xF0209278)
4534 +#define AUD1PLL_PWR_CON0 (0xF020927C)
4535 +#define AUD2PLL_CON0 (0xF02092C0)
4536 +#define AUD2PLL_CON1 (0xF02092C4)
4537 +#define AUD2PLL_CON2 (0xF02092C8)
4538 +#define AUD2PLL_PWR_CON0 (0xF02092CC)
4541 +/* Register Map, Ref to RT3052 Data Sheet */
4543 +/* Register Map Detail */
4544 +#if defined(CONFIG_ARCH_MT7623)
4545 +#define I2S_I2SCFG (ETHDMASYS_I2S_BASE+0x0000)
4546 +#define I2S_INT_STATUS (ETHDMASYS_I2S_BASE+0x0004)
4547 +#define I2S_INT_EN (ETHDMASYS_I2S_BASE+0x0008)
4548 +#define I2S_FF_STATUS (ETHDMASYS_I2S_BASE+0x000c)
4549 +#define I2S_FIFO_WREG (ETHDMASYS_I2S_BASE+0x0010)
4550 +#define I2S_TX_FIFO_WREG I2S_FIFO_WREG
4551 +#define I2S_RX_FIFO_RREG (ETHDMASYS_I2S_BASE+0x0014)
4552 +#define I2S_I2SCFG1 (ETHDMASYS_I2S_BASE+0x0018)
4553 +#define I2S_DIVINT_CFG (ETHDMASYS_I2S_BASE+0x0024)
4554 +#define I2S_DIVCOMP_CFG (ETHDMASYS_I2S_BASE+0x0020)
4556 +#define I2S_I2SCFG (RALINK_I2S_BASE+0x0000)
4557 +#define I2S_INT_STATUS (RALINK_I2S_BASE+0x0004)
4558 +#define I2S_INT_EN (RALINK_I2S_BASE+0x0008)
4559 +#define I2S_FF_STATUS (RALINK_I2S_BASE+0x000c)
4560 +#define I2S_FIFO_WREG (RALINK_I2S_BASE+0x0010)
4561 +#define I2S_TX_FIFO_WREG I2S_FIFO_WREG
4562 +#define I2S_RX_FIFO_RREG (RALINK_I2S_BASE+0x0014)
4563 +#define I2S_I2SCFG1 (RALINK_I2S_BASE+0x0018)
4564 +#define I2S_DIVINT_CFG (RALINK_I2S_BASE+0x0024)
4565 +#define I2S_DIVCOMP_CFG (RALINK_I2S_BASE+0x0020)
4569 +/* I2SCFG bit field */
4571 +#define I2S_DMA_EN 30
4572 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4573 +#define I2S_LITTLE_ENDIAN 29
4574 +#define I2S_SYS_ENDIAN 28
4575 +#elif defined(CONFIG_RALINK_RT6855A)
4576 +#define I2S_BYTE_SWAP 28
4578 +#define I2S_TX_EN 24
4579 +#define I2S_RX_EN 20
4580 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4581 +#define I2S_NORM_24BIT 18
4582 +#define I2S_DATA_24BIT 17
4584 +#define I2S_SLAVE_MODE 16
4585 +#define I2S_RX_FF_THRES 12
4586 +#define I2S_RX_CH_SWAP 11
4587 +#define I2S_RX_CH1_OFF 10
4588 +#define I2S_RX_CH0_OFF 9
4589 +#if defined(CONFIG_RALINK_RT3052)
4590 +#define I2S_CLK_OUT_DIS 8
4592 +#define I2S_TX_FF_THRES 4
4593 +#define I2S_TX_CH_SWAP 3
4594 +#define I2S_TX_CH1_OFF 2
4595 +#define I2S_TX_CH0_OFF 1
4596 +#if defined(CONFIG_RALINK_RT3052)
4597 +#define I2S_SLAVE_EN 0
4599 +#define I2S_WS_INV 0
4601 +/* INT_EN bit field */
4602 +#define I2S_RX_INT3_EN 7
4603 +#define I2S_RX_INT2_EN 6
4604 +#define I2S_RX_INT1_EN 5
4605 +#define I2S_RX_INT0_EN 4
4606 +#define I2S_TX_INT3_EN 3
4607 +#define I2S_TX_INT2_EN 2
4608 +#define I2S_TX_INT1_EN 1
4609 +#define I2S_TX_INT0_EN 0
4611 +/* INT_STATUS bit field */
4612 +#define I2S_RX_DMA_FAULT 7
4613 +#define I2S_RX_OVRUN 6
4614 +#define I2S_RX_UNRUN 5
4615 +#define I2S_RX_THRES 4
4616 +#define I2S_TX_DMA_FAULT 3
4617 +#define I2S_TX_OVRUN 2
4618 +#define I2S_TX_UNRUN 1
4619 +#define I2S_TX_THRES 0
4621 +/* FF_STATUS bit field */
4622 +#define I2S_RX_EPCNT 4
4623 +#define I2S_TX_EPCNT 0
4624 +/* I2S_DIVCOMP_CFG bit field */
4625 +#define I2S_CLKDIV_EN 31
4627 +/* I2S_CFG1 bit field */
4628 +#define I2S_LBK_EN 31
4629 +#define I2S_EXT_LBK_EN 30
4630 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4631 +#define I2S_DATA_FMT 0
4634 +/* FIFO_WREG bit field */
4635 +#define I2S_FIFO_WDATA 0
4637 +/* Constant definition */
4638 +#define NFF_THRES 4
4639 +#define I2S_PAGE_SIZE 3072//(3*4096)//(1152*2*2*2)
4640 +#define I2S_MIN_PAGE_SIZE 4096
4641 +#define MAX_I2S_PAGE 8
4642 +#define I2S_TOTAL_PAGE_SIZE (I2S_PAGE_SIZE*MAX_I2S_PAGE)
4644 +#if defined(CONFIG_I2S_WM8960)
4645 +#define MAX_SRATE_HZ 48000
4646 +#define MIN_SRATE_HZ 8000
4647 +#elif defined(CONFIG_I2S_WM8750)
4648 +#define MAX_SRATE_HZ 96000
4649 +#define MIN_SRATE_HZ 8000
4652 +#define MAX_VOL_DB +0
4653 +#define MIN_VOL_DB -127
4655 +#define ALSA_MMAP_IDX_SHIFT 2
4656 +#if defined(CONFIG_SND_MT76XX_SOC)
4657 +#define STREAM_PLAYBACK SNDRV_PCM_STREAM_PLAYBACK
4658 +#define STREAM_CAPTURE SNDRV_PCM_STREAM_CAPTURE
4660 +#define STREAM_PLAYBACK 0
4661 +#define STREAM_CAPTURE 1
4664 +/* I2S I/O command */
4665 +#define I2S_SRATE 0
4667 +#define I2S_ENABLE 2
4668 +#define I2S_DISABLE 3
4669 +#define I2S_TX_ENABLE 27
4670 +#define I2S_TX_DISABLE 3
4671 +#define I2S_GET_WBUF 4
4672 +#define I2S_PUT_WBUF 5
4673 +#define I2S_RX_ENABLE 6
4674 +#define I2S_RX_DISABLE 7
4675 +#define I2S_PUT_AUDIO 4
4676 +#define I2S_GET_AUDIO 5
4677 +#define I2S_TX_VOL 1
4678 +#define I2S_RX_VOL 8
4679 +#define I2S_WORD_LEN 9
4680 +#define I2S_ENDIAN_FMT 10
4681 +#define I2S_INTERNAL_LBK 11
4682 +#define I2S_TX_STOP 12
4683 +#define I2S_DEBUG_CODEC 13
4684 +#define I2S_MS_MODE_CTRL 14
4685 +#define I2S_TX_PAUSE 15
4686 +#define I2S_TX_RESUME 16
4687 +#define I2S_RESET 17
4688 +#define I2S_RX_STOP 18
4689 +#define I2S_EXTERNAL_LBK 19
4690 +#define I2S_TXRX_COEXIST 20
4691 +#define I2S_RX_PAUSE 21
4692 +#define I2S_RX_RESUME 22
4693 +#define I2S_CODEC_MIC_BOOST 23
4694 +#define I2S_CODEC_MIC_IN 24
4695 +#define I2S_CLOCK_ENABLE 25
4696 +#define I2S_TEST_TEST 26
4698 +#define I2S_DEBUG 30
4699 +#define I2S_DEBUG_CLKGEN 30
4700 +#define I2S_DEBUG_INLBK 31
4701 +#define I2S_DEBUG_EXLBK 32
4702 +#define I2S_DEBUG_FMT 33
4703 +#define I2S_DEBUG_RESET 34
4704 +#define I2S_DEBUG_CODECBYPASS 35
4705 +#if defined(CONFIG_I2S_WM8960)
4706 +#define I2S_DEBUG_CODEC_EXLBK 36
4709 +/* configuration */
4710 +#define CONFIG_I2S_TFF_THRES NFF_THRES
4711 +#define CONFIG_I2S_CH_SWAP 0
4712 +#if defined(CONFIG_I2S_MS_MODE)
4713 +#define CONFIG_I2S_SLAVE_EN 0
4715 +#define CONFIG_I2S_SLAVE_EN 1
4718 +/* driver status definition */
4720 +#define I2S_OUTOFMEM 0x01
4721 +#define I2S_GDMAFAILED 0x02
4722 +#define I2S_REQUEST_IRQ_FAILED 0x04
4723 +#define I2S_REG_SETUP_FAILED 0x08
4725 +#define I2S_STATISTIC
4726 +//#define I2S_HW_INTERRUPT_EN
4727 +//#define I2S_SW_IRQ_EN
4728 +#define I2S_MAJOR 234
4730 +/* parameter for ALSA */
4731 +/*GDMA for I2S Status*/
4732 +#define GDMA_I2S_DIS (0)
4733 +#define GDMA_I2S_EN (1)
4736 +typedef struct i2s_status_t
4742 + int txbuffer_unrun;
4743 + int txbuffer_ovrun;
4750 + int rxbuffer_unrun;
4751 + int rxbuffer_ovrun;
4756 +typedef struct i2s_config_t
4772 + /* parameters fo ALSA */
4774 + int bALSAMMAPEnable;
4775 + unsigned char bTrigger[2];
4776 + unsigned char bPreTrigger[2];
4777 + unsigned char dmaStat[2];
4778 + unsigned char i2sStat[2];
4779 + unsigned int hw_base_frame[2];
4780 + struct snd_pcm_substream *pss[2];
4784 + wait_queue_head_t i2s_tx_qh, i2s_rx_qh;
4789 + u32 dma_unmask_status;
4790 + u32 dma_done_status;
4799 +#if defined (CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4800 + int little_edn; /* test file's fmt: little endian->1; big endian->0 */
4801 + int sys_endian; /* kernal' system fmt: little endian->0; big endian->1 */
4812 + /* for I2S_CFG1 */
4829 + char* pMMAPBufPtr[MAX_I2S_PAGE*2];
4830 + char* pMMAPTxBufPtr[MAX_I2S_PAGE];
4831 + char* pMMAPRxBufPtr[MAX_I2S_PAGE];
4834 + u16* pPage0TxBuf16Ptr;
4835 + u8* pPage0TxBuf8ptr;
4838 + u16* pPage1TxBuf16Ptr;
4839 + u8* pPage1TxBuf8ptr;
4843 + u16* pPage0RxBuf16Ptr;
4844 + u8* pPage0RxBuf8ptr;
4847 + u16* pPage1RxBuf16Ptr;
4848 + u8* pPage1RxBuf8ptr;
4854 +void i2s_gen_test_pattern(void);
4855 +int i2s_mem_unmap(i2s_config_type* ptri2s_config);
4856 +int i2s_param_init(i2s_config_type* ptri2s_config);
4857 +int i2s_txbuf_alloc(i2s_config_type* ptri2s_config);
4858 +int i2s_rxbuf_alloc(i2s_config_type* ptri2s_config);
4859 +int i2s_txPagebuf_alloc(i2s_config_type* ptri2s_config);
4860 +int i2s_rxPagebuf_alloc(i2s_config_type* ptri2s_config);
4861 +int i2s_txbuf_free(i2s_config_type* ptri2s_config);
4862 +int i2s_rxbuf_free(i2s_config_type* ptri2s_config);
4863 +int i2s_txPagebuf_free(i2s_config_type* ptri2s_config);
4864 +int i2s_rxPagebuf_free(i2s_config_type* ptri2s_config);
4865 +int i2s_reset_tx_param(i2s_config_type* ptri2s_config);
4866 +int i2s_reset_rx_param(i2s_config_type* ptri2s_config);
4867 +int i2s_tx_config(i2s_config_type* ptri2s_config);
4868 +int i2s_rx_config(i2s_config_type* ptri2s_config);
4869 +int i2s_tx_enable(i2s_config_type* ptri2s_config);
4870 +int i2s_tx_disable(i2s_config_type* ptri2s_config);
4871 +int i2s_rx_enable(i2s_config_type* ptri2s_config);
4872 +int i2s_rx_disable(i2s_config_type* ptri2s_config);
4873 +int i2s_codec_enable(i2s_config_type* ptri2s_config);
4874 +int i2s_codec_disable(i2s_config_type* ptri2s_config);
4875 +int i2s_clock_enable(i2s_config_type* ptri2s_config);
4876 +int i2s_clock_disable(i2s_config_type* ptri2s_config);
4877 +int i2s_reset_config(i2s_config_type* ptri2s_config);
4878 +int i2s_refclk_disable(void);
4879 +int i2s_refclk_gpio_out_config(void);
4880 +int i2s_refclk_gpio_in_config(void);
4881 +int i2s_share_pin_config(i2s_config_type* ptri2s_config);
4882 +int i2s_share_pin_mt7623(i2s_config_type* ptri2s_config);
4883 +int i2s_master_clock_gpio_out_mt7623(void);
4884 +int i2s_slave_clock_gpio_in_mt7623(void);
4885 +int i2s_ws_config(i2s_config_type* ptri2s_config, unsigned long index);
4886 +int i2s_mode_config(u32 slave_en);
4887 +int i2s_codec_frequency_config(i2s_config_type* ptri2s_config, unsigned long index);
4888 +void i2s_tx_end_sleep_on(i2s_config_type* ptri2s_config);
4889 +void i2s_rx_end_sleep_on(i2s_config_type* ptri2s_config);
4891 +#if defined(CONFIG_I2S_MCLK_12MHZ)
4892 +int i2s_refclk_12m_enable(void);
4894 +#if defined(CONFIG_I2S_MCLK_12P288MHZ)
4895 +int i2s_refclk_12p288m_enable(void);
4898 +#if defined(MT7621_ASIC_BOARD)
4899 +int i2s_pll_config_mt7621(unsigned long index);
4900 +int i2s_pll_refclk_set(void);
4902 +#if defined(MT7623_ASIC_BOARD)
4903 +int i2s_pll_config_mt7623(unsigned long index);
4905 +#if defined(MT7628_ASIC_BOARD) || defined(CONFIG_ARCH_MT7623)
4906 +int i2s_driving_strength_adjust(void);
4908 +#if defined(I2S_STATISTIC)
4909 +void i2s_int_status(u32 dma_ch);
4911 +void i2s_dma_tx_handler(u32 dma_ch);
4912 +void i2s_dma_rx_handler(u32 dma_ch);
4913 +void i2s_dma_unmask_handler(u32 dma_ch);
4914 +void i2s_dma_mask_handler(u32 dma_ch);
4915 +void i2s_dma_tx_init(i2s_config_type* ptri2s_config);
4916 +void i2s_dma_rx_init(i2s_config_type* ptri2s_config);
4917 +void i2s_tx_task(unsigned long pData);
4918 +void i2s_rx_task(unsigned long pData);
4919 +void i2s_dma_tx_unmask_handler(u32 dma_ch);
4920 +void i2s_dma_rx_unmask_handler(u32 dma_ch);
4921 +int i2s_dma_tx_transf_data(i2s_config_type* ptri2s_config, u32 dma_ch);
4922 +int i2s_dma_tx_transf_zero(i2s_config_type* ptri2s_config, u32 dma_ch);
4923 +int i2s_dma_rx_transf_data(i2s_config_type* ptri2s_config, u32 dma_ch);
4924 +int i2s_dma_rx_transf_zero(i2s_config_type* ptri2s_config, u32 dma_ch);
4925 +void i2s_dma_tx_end_handle(i2s_config_type* ptri2s_config);
4926 +int i2s_dma_tx_soft_stop(i2s_config_type* ptri2s_config, u32 dma_ch);
4927 +int i2s_dma_rx_soft_stop(i2s_config_type* ptri2s_config, u32 dma_ch);
4929 +int i2s_page_prepare(i2s_config_type* ptri2s_config,int dir);
4930 +int i2s_page_release(i2s_config_type* ptri2s_config,int dir);
4931 +int gdma_En_Switch(i2s_config_type* ptri2s_config,int dir,int enabled);
4932 +int i2s_startup(void);
4933 +int i2s_audio_exchange(i2s_config_type* ptri2s_config,int dir,unsigned long arg);
4934 +void gdma_unmask_handler(u32 dma_ch);
4935 +char* i2s_memPool_Alloc(i2s_config_type* ptri2s_config,int dir);
4936 +void i2s_memPool_free(i2s_config_type* ptri2s_config,int dir);
4937 +u32 i2s_mmap_phys_addr(i2s_config_type* ptri2s_config);
4939 +#if !defined(CONFIG_I2S_TXRX)
4940 +#define GdmaI2sRx //GdmaI2sRx
4943 +#define RALINK_I2S_VERSION "1.0"
4944 +#define I2SDRV_DEVNAME "i2s0"
4946 +#endif /* __RALINK_I2S_H_ */
4949 +++ b/sound/soc/mtk/mt76xx_i2s.c
4954 + * Created on: 2013/8/20
4955 + * Author: MTK04880
4957 +#include <linux/init.h>
4958 +#include <linux/version.h>
4959 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
4960 +#include <linux/sched.h>
4962 +#include <linux/module.h>
4963 +#include <linux/kernel.h> /* printk() */
4964 +#include <linux/slab.h> /* kmalloc() */
4965 +#include <linux/fs.h> /* everything... */
4966 +#include <linux/errno.h> /* error codes */
4967 +#include <linux/types.h> /* size_t */
4968 +#include <linux/proc_fs.h>
4969 +#include <linux/fcntl.h> /* O_ACCMODE */
4970 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36)
4971 +#include <asm/system.h> /* cli(), *_flags */
4973 +#include <asm/uaccess.h> /* copy_from/to_user */
4974 +#include <linux/interrupt.h>
4975 +#include <linux/mm.h>
4976 +#include <linux/dma-mapping.h>
4977 +#include <sound/core.h>
4978 +#include <linux/pci.h>
4979 +#include <sound/pcm.h>
4980 +#include <sound/pcm_params.h>
4981 +#include <sound/soc.h>
4982 +#include <sound/soc-dapm.h>
4983 +#include <sound/initval.h>
4984 +#include "ralink_gdma.h"
4985 +#include "mt76xx_i2s.h"
4987 +/****************************/
4988 +/*GLOBAL VARIABLE DEFINITION*/
4989 +/****************************/
4990 +extern i2s_config_type* pi2s_config;
4992 +/****************************/
4993 +/*FUNCTION DECLRATION */
4994 +/****************************/
4995 +static int mt76xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai,\
4996 + unsigned int fmt);
4998 +//static int mt76xx_i2s_shutdown(struct snd_pcm_substream *substream,
4999 +// struct snd_soc_dai *dai);
5000 +static int mt76xx_i2s_startup(struct snd_pcm_substream *substream,
5001 + struct snd_soc_dai *dai);
5002 +static int mt76xx_i2s_hw_params(struct snd_pcm_substream *substream,\
5003 + struct snd_pcm_hw_params *params,\
5004 + struct snd_soc_dai *dai);
5005 +static int mt76xx_i2s_play_prepare(struct snd_pcm_substream *substream,struct snd_soc_dai *dai);
5006 +static int mt76xx_i2s_rec_prepare(struct snd_pcm_substream *substream,struct snd_soc_dai *dai);
5007 +static int mt76xx_i2s_hw_free(struct snd_pcm_substream *substream,struct snd_soc_dai *dai);
5008 +static int mt76xx_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai);
5010 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,20)
5011 +static int mt76xx_i2s_drv_probe(struct platform_device *pdev);
5012 +static int mt76xx_i2s_drv_remove(struct platform_device *pdev);
5014 +/****************************/
5015 +/*STRUCTURE DEFINITION */
5016 +/****************************/
5019 +static struct snd_soc_dai_ops mt76xx_i2s_dai_ops = {
5020 + .startup = mt76xx_i2s_startup,
5021 + .hw_params = mt76xx_i2s_hw_params,
5022 + .hw_free = mt76xx_i2s_hw_free,
5023 + //.shutdown = mt76xx_i2s_shutdown,
5024 + .prepare = mt76xx_i2s_prepare,
5025 + .set_fmt = mt76xx_i2s_set_fmt,
5026 + //.set_sysclk = mt76xx_i2s_set_sysclk,
5029 +const struct snd_soc_component_driver mt76xx_i2s_component = {
5030 + .name = "mt76xx-i2s",
5033 +struct snd_soc_dai_driver mt76xx_i2s_dai = {
5035 + .channels_min = 1,
5036 + .channels_max = 2,
5037 + .rates = (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_11025|\
5038 + SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_22050|SNDRV_PCM_RATE_32000|\
5039 + SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000),
5041 + .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
5042 + SNDRV_PCM_FMTBIT_S24_LE),
5045 + .channels_min = 1,
5046 + .channels_max = 2,
5047 + .rates = (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_11025|\
5048 + SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_22050|SNDRV_PCM_RATE_32000|\
5049 + SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000),
5050 + .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
5051 + SNDRV_PCM_FMTBIT_S24_LE),
5053 + .ops = &mt76xx_i2s_dai_ops,
5054 + .symmetric_rates = 1,
5057 +/****************************/
5059 +/****************************/
5061 +static int mt76xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
5065 + //printk("******* %s *******\n", __func__);
5069 +static int mt76xx_i2s_play_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
5071 + //printk("******* %s *******\n", __func__);
5072 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
5073 + rtd->pss[SNDRV_PCM_STREAM_PLAYBACK] = substream;
5074 + if(! rtd->i2sStat[SNDRV_PCM_STREAM_PLAYBACK]){
5075 + i2s_reset_tx_param( rtd);
5076 + i2s_tx_config( rtd);
5077 + gdma_En_Switch(rtd, STREAM_PLAYBACK, GDMA_I2S_EN);
5079 + if( rtd->bRxDMAEnable==0)
5080 + i2s_clock_enable( rtd);
5082 + i2s_tx_enable( rtd);
5083 + rtd->i2sStat[SNDRV_PCM_STREAM_PLAYBACK] = 1;
5084 + MSG("I2S_TXENABLE done\n");
5090 +static int mt76xx_i2s_rec_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
5093 + //printk("******* %s *******\n", __func__);
5094 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
5095 + rtd->pss[SNDRV_PCM_STREAM_CAPTURE] = substream;
5096 + if(! rtd->i2sStat[SNDRV_PCM_STREAM_CAPTURE]) {
5097 + i2s_reset_rx_param(rtd);
5098 + i2s_rx_config(rtd);
5099 + gdma_En_Switch(rtd, STREAM_CAPTURE, GDMA_I2S_EN);
5101 + if(rtd->bTxDMAEnable==0)
5102 + i2s_clock_enable(rtd);
5104 + i2s_rx_enable(rtd);
5105 + rtd->i2sStat[SNDRV_PCM_STREAM_CAPTURE] = 1;
5110 +/*static int mt76xx_i2s_shutdown(struct snd_pcm_substream *substream,
5111 + struct snd_soc_dai *dai)
5113 + //i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
5114 + //printk("******* %s *******\n", __func__);
5118 +static int mt76xx_i2s_startup(struct snd_pcm_substream *substream,
5119 + struct snd_soc_dai *dai)
5122 + //printk("******* %s *******\n", __func__);
5123 + if((!pi2s_config->i2sStat[SNDRV_PCM_STREAM_PLAYBACK]) && (!pi2s_config->i2sStat[SNDRV_PCM_STREAM_CAPTURE])){
5127 + i2s_reset_config(pi2s_config);
5129 + substream->runtime->private_data = pi2s_config;
5133 +static int mt76xx_i2s_hw_params(struct snd_pcm_substream *substream,\
5134 + struct snd_pcm_hw_params *params,\
5135 + struct snd_soc_dai *dai){
5136 + unsigned int srate = 0;
5137 + //unsigned long data;
5138 + struct snd_pcm_runtime *runtime = substream->runtime;
5139 + i2s_config_type* rtd = runtime->private_data;
5141 + //printk("******* %s *******\n", __func__);
5142 + switch(params_rate(params)){
5160 + //MSG("audio sampling rate %u should be %d ~ %d Hz\n", (u32)params_rate(params), MIN_SRATE_HZ, MAX_SRATE_HZ);
5164 + if((rtd->bRxDMAEnable != GDMA_I2S_EN) && (rtd->bTxDMAEnable != GDMA_I2S_EN)){
5165 + rtd->srate = srate;
5166 + MSG("set audio sampling rate to %d Hz\n", rtd->srate);
5172 +static int mt76xx_i2s_hw_free(struct snd_pcm_substream *substream,struct snd_soc_dai *dai){
5174 + //printk("******* %s *******\n", __func__);
5175 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
5176 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
5177 + if(rtd->i2sStat[SNDRV_PCM_STREAM_PLAYBACK]){
5178 + MSG("I2S_TXDISABLE\n");
5179 + i2s_reset_tx_param(rtd);
5181 + if((rtd->bRxDMAEnable==0)&&(rtd->bTxDMAEnable==0)){
5182 + i2s_clock_disable(rtd);
5184 + rtd->i2sStat[SNDRV_PCM_STREAM_PLAYBACK] = 0;
5188 + if(rtd->i2sStat[SNDRV_PCM_STREAM_CAPTURE]){
5189 + MSG("I2S_RXDISABLE\n");
5190 + i2s_reset_rx_param(rtd);
5192 + if((rtd->bRxDMAEnable==0)&&(rtd->bTxDMAEnable==0)){
5193 + i2s_clock_disable(rtd);
5195 + rtd->i2sStat[SNDRV_PCM_STREAM_CAPTURE] = 0;
5200 +static int mt76xx_i2s_prepare(struct snd_pcm_substream *substream,struct snd_soc_dai *dai)
5203 + //printk("******* %s *******\n", __func__);
5204 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
5205 + return mt76xx_i2s_play_prepare(substream, dai);
5207 + return mt76xx_i2s_rec_prepare(substream, dai);
5212 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,20)
5213 +static int mt76xx_i2s_drv_probe(struct platform_device *pdev)
5215 + //printk("****** %s ******\n", __func__);
5216 + return snd_soc_register_component(&pdev->dev, &mt76xx_i2s_component,
5217 + &mt76xx_i2s_dai, 1);
5220 +static int mt76xx_i2s_drv_remove(struct platform_device *pdev)
5222 + snd_soc_unregister_component(&pdev->dev);
5226 +static struct platform_driver mt76xx_i2s_driver = {
5227 + .probe = mt76xx_i2s_drv_probe,
5228 + .remove = mt76xx_i2s_drv_remove,
5230 + .name = "mt76xx-i2s",
5231 + .owner = THIS_MODULE,
5235 +static int __init mt76xx_i2s_init(void)
5238 + //printk("****** %s ******\n", __func__);
5239 + return platform_driver_register(&mt76xx_i2s_driver);
5242 +static void __exit mt76xx_i2s_exit(void)
5244 + //printk("****** %s ******\n", __func__);
5245 + platform_driver_unregister(&mt76xx_i2s_driver);
5248 +module_init(mt76xx_i2s_init);
5249 +module_exit(mt76xx_i2s_exit);
5251 +MODULE_AUTHOR("Dora Chen");
5252 +MODULE_DESCRIPTION("Stretch MT76xx I2S Interface");
5253 +MODULE_LICENSE("GPL");
5256 +++ b/sound/soc/mtk/mt76xx_i2s.h
5261 + * Created on: 2013/8/20
5262 + * Author: MTK04880
5270 +//#include <asm/rt2880/rt_mmap.h>
5271 +#include <linux/fs.h>
5274 +#include "i2s_ctrl.h"
5275 +#endif /* MTK_I2S_H_ */
5277 +++ b/sound/soc/mtk/mt76xx_machine.c
5280 + * mt76xx_machine.c
5283 +#include <linux/init.h>
5284 +#include <linux/version.h>
5285 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
5286 +#include <linux/sched.h>
5288 +#include <linux/module.h>
5289 +#include <linux/kernel.h> /* printk() */
5290 +#include <linux/slab.h> /* kmalloc() */
5291 +#include <linux/fs.h> /* everything... */
5292 +#include <linux/errno.h> /* error codes */
5293 +#include <linux/types.h> /* size_t */
5294 +#include <linux/proc_fs.h>
5295 +#include <linux/fcntl.h> /* O_ACCMODE */
5296 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36)
5297 +#include <asm/system.h> /* cli(), *_flags */
5299 +#include <asm/uaccess.h> /* copy_from/to_user */
5300 +#include <linux/interrupt.h>
5301 +#include <linux/mm.h>
5302 +#include <linux/dma-mapping.h>
5303 +#include <sound/core.h>
5304 +#include <linux/pci.h>
5305 +#include <sound/pcm.h>
5306 +#include <sound/pcm_params.h>
5307 +#include <sound/soc.h>
5308 +#include <sound/soc-dapm.h>
5309 +#include <sound/initval.h>
5310 +#include <linux/i2c.h>
5311 +#include <linux/ioport.h>
5312 +#include <linux/delay.h>
5313 +#include "ralink_gdma.h"
5314 +#include "mt76xx_i2s.h"
5315 +#include "mt76xx_machine.h"
5316 +#if defined(CONFIG_SND_SOC_WM8960)
5317 +#include "../codecs/wm8960.h"
5320 +#define I2C_AUDIO_DEV_ID (0)
5321 +/****************************/
5322 +/*FUNCTION DECLRATION */
5323 +/****************************/
5324 +extern unsigned long i2s_codec_12p288Mhz[11];
5325 +extern unsigned long i2s_codec_12Mhz[11];
5328 +static int mt76xx_codec_clock_hwparams(struct snd_pcm_substream *substream,\
5329 + struct snd_pcm_hw_params *params);
5330 +static int mt76xx_codec_startup(struct snd_pcm_substream *substream);
5331 +static int mt76xx_codec_init(struct snd_soc_pcm_runtime *rtd);
5332 +extern struct snd_soc_dai_driver mt76xx_i2s_dai;
5333 +extern struct snd_soc_platform_driver mt76xx_soc_platform;
5334 +struct platform_device *mt76xx_audio_device;
5336 +#if defined(CONFIG_SND_SOC_WM8960)
5337 +extern struct snd_soc_dai wm8960_dai;
5338 +extern struct snd_soc_codec_device soc_codec_dev_wm8960;
5341 +static struct snd_soc_ops mtk_audio_ops = {
5342 + .hw_params = mt76xx_codec_clock_hwparams,
5343 + .startup = mt76xx_codec_startup,
5346 +static struct snd_soc_dai_link mtk_audio_dai = {
5347 + .name = "mtk_dai",
5348 + .stream_name = "WMserious PCM",
5349 + .cpu_dai_name = "mt76xx-i2s",
5350 + .codec_dai_name = "wm8960-hifi",
5351 + .codec_name = "wm8960.0-001a",
5352 + .platform_name = "mt76xx-pcm",
5353 + .ignore_pmdown_time = true,
5354 + .init = mt76xx_codec_init,
5355 + .ops = &mtk_audio_ops,
5358 +static struct snd_soc_card mtk_audio_card = {
5359 + .name = "MTK APSoC I2S",
5360 + .owner = THIS_MODULE,
5361 + .dai_link = &mtk_audio_dai,//I2S/Codec
5365 +static int mt76xx_codec_clock_hwparams(struct snd_pcm_substream *substream,
5366 + struct snd_pcm_hw_params *params)
5368 + struct snd_soc_pcm_runtime *p = substream->private_data;
5369 + struct snd_soc_dai *codec_dai = p->codec_dai;
5370 + struct snd_pcm_runtime *runtime = substream->runtime;
5371 + i2s_config_type* rtd = runtime->private_data;
5372 + unsigned long data,index = 0;
5373 + unsigned long* pTable;
5374 + int mclk,ret,targetClk = 0;
5376 + /*For duplex mode, avoid setting twice.*/
5377 + if((rtd->bRxDMAEnable == GDMA_I2S_EN) || (rtd->bTxDMAEnable == GDMA_I2S_EN))
5379 +#if defined(CONFIG_I2S_MCLK_12MHZ)
5381 +#elif defined(CONFIG_I2S_MCLK_12P288MHZ)
5386 + //snd_soc_dai_set_sysclk(codec_dai,0,mclk, SND_SOC_CLOCK_IN);
5388 + switch(params_rate(params)){
5391 + targetClk = 12288000;
5395 + targetClk = 12288000;
5399 + targetClk = 12288000;
5403 + targetClk = 12288000;
5407 + targetClk = 12288000;
5411 + targetClk = 12288000;
5415 + targetClk = 11289600;
5419 + targetClk = 11289600;
5423 + targetClk = 11289600;
5427 + targetClk = 11289600;
5431 + targetClk = 11289600;
5435 + targetClk = 12288000;
5436 + //MSG("audio sampling rate %u should be %d ~ %d Hz\n", (u32)params_rate(params), MIN_SRATE_HZ, MAX_SRATE_HZ);
5439 +#if defined(CONFIG_SND_SOC_WM8960)
5441 + * There is a fixed divide by 4 in the PLL and a selectable
5442 + * divide by N after the PLL which should be set to divide by 2 to meet this requirement.
5444 + ret = snd_soc_dai_set_pll(codec_dai, 0, 0,mclk, targetClk*2);
5445 + /* From app notes: allow Vref to stabilize to reduce clicks */
5446 + if(rtd->slave_en){
5447 + //printk("WM8960 is in master mode\n");
5448 + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_DCLKDIV, 0x1c4);
5449 + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_SYSCLKDIV, 0x5);
5453 + if(!rtd->slave_en)
5454 + snd_soc_dai_set_fmt(codec_dai,SND_SOC_DAIFMT_CBS_CFS|SND_SOC_DAIFMT_I2S|SND_SOC_DAIFMT_NB_NF);
5456 + snd_soc_dai_set_fmt(codec_dai,SND_SOC_DAIFMT_CBM_CFM|SND_SOC_DAIFMT_I2S|SND_SOC_DAIFMT_NB_NF);
5460 +#if defined(CONFIG_SND_SOC_WM8960)
5461 +#if defined(CONFIG_I2S_MCLK_12MHZ)
5462 + pTable = i2s_codec_12Mhz;
5463 + data = pTable[index];
5465 + pTable = i2s_codec_12p288Mhz;
5466 + data = pTable[index];
5468 + if(rtd->codec_pll_en)
5469 + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_DACDIV, (data<<3)|0x5);
5471 + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_DACDIV, (data<<3|0x4));
5477 +static int mt76xx_codec_startup(struct snd_pcm_substream *substream)
5479 + //printk("******* %s *******\n", __func__);
5482 +static int mt76xx_codec_init(struct snd_soc_pcm_runtime *rtd)
5485 + //printk("******* %s *******\n", __func__);
5489 +static struct i2c_board_info i2c_board_info[] = {
5491 +#if defined(CONFIG_SND_SOC_WM8750)
5492 + I2C_BOARD_INFO("wm8750", (0x36 >> 1)),
5493 +#elif defined(CONFIG_SND_SOC_WM8960)
5494 + I2C_BOARD_INFO("codec_wm8960", (0x34)),
5496 + I2C_BOARD_INFO("wm8960", (0x34 >> 1)),
5501 +static struct platform_device *soc_mtk_i2s_dev;
5502 +static struct platform_device *soc_mtk_pcm_dev;
5504 +static int __init mt76xx_machine_init(void)
5506 + //struct snd_soc_device *socdev = &mtk_audio_devdata;
5507 + //struct i2c_adapter *adapter = NULL;
5508 + //struct i2c_client *client = NULL;
5510 + struct i2c_adapter *adapter = NULL;
5511 + struct i2c_client *client = NULL;
5513 + adapter = i2c_get_adapter(I2C_AUDIO_DEV_ID);
5516 + client = i2c_new_device(adapter, &i2c_board_info[0]);
5519 + i2c_get_clientdata(client);
5521 + client = i2c_new_device(adapter, &i2c_board_info[1]);
5524 + i2c_get_clientdata(client);
5526 + i2c_put_adapter(adapter);
5529 + platform_device_register_simple("mt76xx-i2s", -1, NULL, 0);
5530 + if (IS_ERR(soc_mtk_i2s_dev))
5531 + return PTR_ERR(soc_mtk_i2s_dev);
5534 + platform_device_register_simple("mt76xx-pcm", -1, NULL, 0);
5535 + if (IS_ERR(soc_mtk_pcm_dev))
5536 + return PTR_ERR(soc_mtk_pcm_dev);
5538 + mt76xx_audio_device = platform_device_alloc("soc-audio",-1);
5539 + if (mt76xx_audio_device == NULL) {
5541 + goto err_device_alloc;
5543 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
5544 + platform_set_drvdata(mt76xx_audio_device, &mtk_audio_card);
5546 + platform_set_drvdata(mt76xx_audio_device, &mtk_audio_devdata);
5547 + mtk_audio_devdata.dev = &mt76xx_audio_device->dev;
5550 + /*Ralink I2S register process end*/
5551 + ret = platform_device_add(mt76xx_audio_device);
5553 + printk("mtk audio device : platform_device_add failed (%d)\n",ret);
5554 + goto err_device_add;
5557 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
5559 + snd_soc_register_dai(&mt76xx_i2s_dai);
5565 + if (mt76xx_audio_device!= NULL) {
5566 + platform_device_put(mt76xx_audio_device);
5567 + mt76xx_audio_device = NULL;
5574 +static void __exit mt76xx_machine_exit(void)
5577 + platform_device_unregister(mt76xx_audio_device);
5578 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,20)
5580 +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
5581 + snd_soc_unregister_platform(&mt76xx_audio_device->dev);
5583 + snd_soc_unregister_platform(&mt76xx_soc_platform);
5585 + platform_device_unregister(soc_mtk_i2s_dev);
5586 + platform_device_unregister(soc_mtk_pcm_dev);
5588 + mt76xx_audio_device = NULL;
5591 +//module_init(mt76xx_machine_init);
5592 +late_initcall(mt76xx_machine_init);
5593 +module_exit(mt76xx_machine_exit);
5594 +//EXPORT_SYMBOL_GPL(mt76xx_soc_platform);
5595 +MODULE_LICENSE("GPL");
5597 +++ b/sound/soc/mtk/mt76xx_machine.h
5600 + * mtk_audio_device.h
5602 + * Created on: 2013/10/23
5603 + * Author: MTK04880
5606 +#ifndef MT76XX_MACHINE_H_
5607 +#define MT76XX_MACHINE_H_
5608 +#include <sound/pcm.h>
5609 +#include <sound/pcm_params.h>
5610 +#include <sound/soc.h>
5611 +#include <sound/soc-dapm.h>
5614 +#ifdef CONFIG_I2S_MMAP
5615 +#undef CONFIG_I2S_MMAP
5619 +#endif /* MT76XX_MACHINE_H_ */
5621 +++ b/sound/soc/mtk/mt76xx_pcm.c
5626 + * Created on: 2013/9/6
5627 + * Author: MTK04880
5630 +#include <linux/init.h>
5631 +#include <linux/version.h>
5632 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
5633 +#include <linux/sched.h>
5635 +#include <linux/module.h>
5636 +#include <linux/kernel.h> /* printk() */
5637 +#include <linux/slab.h> /* kmalloc() */
5638 +#include <linux/fs.h> /* everything... */
5639 +#include <linux/errno.h> /* error codes */
5640 +#include <linux/types.h> /* size_t */
5641 +#include <linux/proc_fs.h>
5642 +#include <linux/fcntl.h> /* O_ACCMODE */
5643 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36)
5644 +#include <asm/system.h> /* cli(), *_flags */
5646 +#include <asm/uaccess.h> /* copy_from/to_user */
5647 +#include <linux/interrupt.h>
5648 +#include <linux/mm.h>
5649 +#include <linux/dma-mapping.h>
5650 +#include <sound/core.h>
5651 +#include <linux/pci.h>
5652 +#include <sound/pcm.h>
5653 +#include <sound/pcm_params.h>
5654 +#include <sound/soc.h>
5655 +#include <sound/soc-dapm.h>
5656 +#include <sound/initval.h>
5657 +#include "ralink_gdma.h"
5658 +#include "mt76xx_i2s.h"
5660 +#define GDMA_PAGE_SIZE I2S_PAGE_SIZE
5661 +#define GDMA_PAGE_NUM MAX_I2S_PAGE
5662 +#define GDMA_TOTAL_PAGE_SIZE I2S_TOTAL_PAGE_SIZE
5664 +dma_addr_t i2s_txdma_addr, i2s_rxdma_addr;
5665 +dma_addr_t i2s_mmap_addr[GDMA_PAGE_NUM*2];
5667 +extern struct tasklet_struct i2s_tx_tasklet;
5668 +extern struct tasklet_struct i2s_rx_tasklet;
5669 +extern int i2s_mmap_remap(struct vm_area_struct *vma, unsigned long size);
5670 +extern void i2s_tx_end_sleep_on(i2s_config_type* ptri2s_config);
5671 +extern void i2s_rx_end_sleep_on(i2s_config_type* ptri2s_config);
5673 +static int mt76xx_pcm_open(struct snd_pcm_substream *substream);
5674 +static int mt76xx_pcm_new(struct snd_soc_pcm_runtime *rtd);
5675 +static void mt76xx_pcm_free(struct snd_pcm *pcm);
5676 +static int mt76xx_pcm_close(struct snd_pcm_substream *substream);
5677 +static snd_pcm_uframes_t mt76xx_pcm_pointer(struct snd_pcm_substream *substream);
5678 +static int mt76xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
5679 +static int mt76xx_pcm_prepare(struct snd_pcm_substream *substream);
5680 +static int mt76xx_pcm_hw_params(struct snd_pcm_substream *substream,\
5681 + struct snd_pcm_hw_params *hw_params);
5682 +static int mt76xx_pcm_copy(struct snd_pcm_substream *substream, int channel,\
5683 + snd_pcm_uframes_t pos,void __user *buf, snd_pcm_uframes_t count);
5684 +static int mt76xx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma);
5685 +static int mt76xx_pcm_hw_free(struct snd_pcm_substream *substream);
5687 +static int mt76xx_pcm_free_dma_buffer(struct snd_pcm_substream *substream,int stream);
5688 +static int mt76xx_pcm_allocate_dma_buffer(struct snd_pcm_substream *substream,int stream);
5690 +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,10,20)
5691 +static int mt76xx_platform_drv_probe(struct platform_device *pdev);
5692 +static int mt76xx_platform_drv_remove(struct platform_device *pdev);
5695 +static const struct snd_pcm_hardware mt76xx_pcm_hwparam = {
5696 +#if defined(CONFIG_I2S_MMAP)
5697 + .info = (SNDRV_PCM_INFO_INTERLEAVED |
5698 + SNDRV_PCM_INFO_PAUSE |
5699 + SNDRV_PCM_INFO_RESUME |
5700 + SNDRV_PCM_INFO_MMAP |
5701 + SNDRV_PCM_INFO_MMAP_VALID),
5703 + .info = (SNDRV_PCM_INFO_INTERLEAVED |
5704 + SNDRV_PCM_INFO_PAUSE |
5705 + SNDRV_PCM_INFO_RESUME),
5707 + .formats = SNDRV_PCM_FMTBIT_S16_LE,
5708 + .period_bytes_min = GDMA_PAGE_SIZE,
5709 + .period_bytes_max = GDMA_PAGE_SIZE,
5711 + .periods_max = GDMA_PAGE_NUM,
5712 + .buffer_bytes_max = GDMA_TOTAL_PAGE_SIZE,
5715 +static struct snd_pcm_ops mt76xx_pcm_ops = {
5717 + .open = mt76xx_pcm_open,
5718 + .ioctl = snd_pcm_lib_ioctl,
5719 + .hw_params = mt76xx_pcm_hw_params,
5720 + .hw_free = mt76xx_pcm_hw_free,
5721 + .trigger = mt76xx_pcm_trigger,
5722 + .prepare = mt76xx_pcm_prepare,
5723 + .pointer = mt76xx_pcm_pointer,
5724 + .close = mt76xx_pcm_close,
5725 +#if defined(CONFIG_I2S_MMAP)
5726 + .mmap = mt76xx_pcm_mmap,
5728 + .copy = mt76xx_pcm_copy,
5730 +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,10,0)
5731 +struct snd_soc_platform_driver mt76xx_soc_platform = {
5732 + .ops = &mt76xx_pcm_ops,
5733 + .pcm_new = mt76xx_pcm_new,
5734 + .pcm_free = mt76xx_pcm_free,
5737 +struct snd_soc_platform mt76xx_soc_platform = {
5738 + .name = "mtk-dma",
5739 + .pcm_ops = &mt76xx_pcm_ops,
5740 + .pcm_new = mt76xx_pcm_new,
5741 + .pcm_free = mt76xx_pcm_free,
5745 +static int mt76xx_pcm_close(struct snd_pcm_substream *substream){
5747 + //printk("******* %s *********\n", __func__);
5751 +static snd_pcm_uframes_t mt76xx_pcm_pointer(struct snd_pcm_substream *substream)
5753 + struct snd_pcm_runtime *runtime = substream->runtime;
5754 + i2s_config_type* rtd = runtime->private_data;
5755 + unsigned int offset = 0;
5756 + //int buff_frame_bond = bytes_to_frames(runtime, GDMA_PAGE_SIZE);
5757 + //printk("\n******* %s *********\n", __func__);
5759 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
5760 + offset = bytes_to_frames(runtime, GDMA_PAGE_SIZE*rtd->tx_r_idx);
5761 + //printk("r:%d w:%d (%d) \n",rtd->tx_r_idx,rtd->tx_w_idx,(runtime->control->appl_ptr/buff_frame_bond)%GDMA_PAGE_NUM);
5764 + offset = bytes_to_frames(runtime, GDMA_PAGE_SIZE*rtd->rx_w_idx);
5765 + //printk("w:%d r:%d appl_ptr:%x\n",rtd->rx_w_idx,rtd->rx_r_idx,(runtime->control->appl_ptr/buff_frame_bond)%GDMA_PAGE_NUM);
5771 +static int mt76xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
5774 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
5775 + //struct snd_pcm_runtime *runtime= substream->runtime;
5777 + //printk("******* %s *********\n", __func__);
5778 +/* printk("trigger cmd:%s\n",(cmd==SNDRV_PCM_TRIGGER_START)?"START":\
5779 + (cmd==SNDRV_PCM_TRIGGER_RESUME)?"RESUME":\
5780 + (cmd==SNDRV_PCM_TRIGGER_PAUSE_RELEASE)?"PAUSE_RELEASE":\
5781 + (cmd==SNDRV_PCM_TRIGGER_STOP)?"STOP":\
5782 + (cmd==SNDRV_PCM_TRIGGER_SUSPEND)?"SUSPEND":\
5783 + (cmd==SNDRV_PCM_TRIGGER_PAUSE_PUSH)?"PAUSE_PUSH":"default");
5786 + case SNDRV_PCM_TRIGGER_START:
5787 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
5788 + rtd->bTrigger[SNDRV_PCM_STREAM_PLAYBACK] = 1;
5790 + rtd->bTrigger[SNDRV_PCM_STREAM_CAPTURE] = 1;
5793 + case SNDRV_PCM_TRIGGER_STOP:
5794 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
5795 + rtd->bTrigger[SNDRV_PCM_STREAM_PLAYBACK] = 0;
5797 + rtd->bTrigger[SNDRV_PCM_STREAM_CAPTURE] = 0;
5800 + case SNDRV_PCM_TRIGGER_RESUME:
5801 + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
5802 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
5803 + rtd->tx_pause_en = 0;
5805 + rtd->rx_pause_en = 0;
5809 + case SNDRV_PCM_TRIGGER_SUSPEND:
5810 + case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
5811 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
5812 + rtd->tx_pause_en = 1;
5814 + rtd->rx_pause_en = 1;
5824 +static int mt76xx_pcm_copy(struct snd_pcm_substream *substream, int channel,\
5825 + snd_pcm_uframes_t pos,void __user *buf, snd_pcm_uframes_t count)
5827 + struct snd_pcm_runtime *runtime= substream->runtime;
5828 + i2s_config_type* rtd = runtime->private_data;
5831 + char *hwbuf = NULL;
5833 + //printk("******* %s *********\n", __func__);
5834 + hwbuf = runtime->dma_area + frames_to_bytes(runtime, pos);
5835 + //MSG("%s bur:%x\n",__func__,hwbuf);
5836 + //printk("hw_ptr:%d, buffer_size:%d, appl_prt:%d, boundary:%d\n",
5837 + // runtime->status->hw_ptr, runtime->buffer_size, runtime->control->appl_ptr, runtime->boundary);
5839 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
5840 + rtd->tx_w_idx = (rtd->tx_w_idx+1)%MAX_I2S_PAGE;
5841 + tx_w_idx = rtd->tx_w_idx;
5842 + //printk("put TB[%d - %x] for user write\n",rtd->tx_w_idx,pos);
5843 + copy_from_user(rtd->pMMAPTxBufPtr[tx_w_idx], (char*)buf, I2S_PAGE_SIZE);
5846 + rx_r_idx = rtd->rx_r_idx;
5847 + rtd->rx_r_idx = (rtd->rx_r_idx+1)%MAX_I2S_PAGE;
5848 + copy_to_user((char*)buf, rtd->pMMAPRxBufPtr[rx_r_idx], I2S_PAGE_SIZE);
5853 +static int mt76xx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma)
5856 + unsigned long size;
5858 + size = vma->vm_end-vma->vm_start;
5859 + printk("******* %s: size :%lx end:%lx start:%lx *******\n", __func__,size,vma->vm_end,vma->vm_start);
5860 + ret = i2s_mmap_remap(vma, size);
5866 +static int mt76xx_pcm_prepare(struct snd_pcm_substream *substream)
5868 + struct snd_pcm_runtime *runtime= substream->runtime;
5869 + i2s_config_type *rtd = (i2s_config_type*)runtime->private_data;
5870 + //runtime->buffer_size = GDMA_PAGE_NUM*GDMA_PAGE_SIZE;
5871 + //runtime->boundary = (GDMA_PAGE_NUM*GDMA_PAGE_SIZE)/4;
5873 + //printk("******* %s *******\n", __func__);
5874 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
5875 + //printk("===== %s:%s:%d =====\n", __FILE__, __func__, __LINE__);
5876 + mt76xx_pcm_allocate_dma_buffer(substream,SNDRV_PCM_STREAM_PLAYBACK);
5878 + if(! rtd->dmaStat[SNDRV_PCM_STREAM_PLAYBACK]){
5879 + i2s_page_prepare(rtd,STREAM_PLAYBACK);
5880 + tasklet_init(&i2s_tx_tasklet, i2s_tx_task, (u32)rtd);
5881 + rtd->dmaStat[SNDRV_PCM_STREAM_PLAYBACK] = 1;
5882 + gdma_unmask_handler(GDMA_I2S_TX0);
5885 + mt76xx_pcm_allocate_dma_buffer(substream,SNDRV_PCM_STREAM_CAPTURE);
5887 + if(! rtd->dmaStat[SNDRV_PCM_STREAM_CAPTURE]){
5888 + i2s_page_prepare(rtd,STREAM_CAPTURE); /* TX:enLabel=1; RX:enLabel=2 */
5889 + tasklet_init(&i2s_rx_tasklet, i2s_rx_task, (u32)rtd);
5890 + rtd->dmaStat[SNDRV_PCM_STREAM_CAPTURE] = 1;
5891 + gdma_unmask_handler(GDMA_I2S_RX0);
5899 +static int mt76xx_pcm_hw_params(struct snd_pcm_substream *substream,
5900 + struct snd_pcm_hw_params *hw_params)
5902 + /*struct snd_pcm_runtime *runtime = substream->runtime;
5903 + i2s_config_type *rtd = (i2s_config_type*)runtime->private_data;
5908 + //printk("******* %s *******\n", __func__);
5909 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
5910 + //i2s_page_prepare(rtd,STREAM_PLAYBACK);
5912 + //i2s_page_prepare(rtd,STREAM_CAPTURE);
5918 +static int mt76xx_pcm_hw_free(struct snd_pcm_substream *substream)
5920 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
5921 + //struct snd_dma_buffer *buf = &substream->dma_buffer;
5923 + //printk("******* %s *******\n", __func__);
5924 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
5925 + if(rtd->dmaStat[SNDRV_PCM_STREAM_PLAYBACK]){
5927 + gdma_En_Switch(rtd,STREAM_PLAYBACK,GDMA_I2S_DIS);
5928 + i2s_tx_end_sleep_on(rtd);
5929 + tasklet_kill(&i2s_tx_tasklet);
5930 + i2s_tx_disable(rtd);
5931 + //mt76xx_pcm_free_dma_buffer(substream,substream->stream);
5932 + i2s_page_release(rtd,STREAM_PLAYBACK);
5933 + rtd->dmaStat[SNDRV_PCM_STREAM_PLAYBACK] = 0;
5935 + mt76xx_pcm_free_dma_buffer(substream,substream->stream);
5938 + if(rtd->dmaStat[SNDRV_PCM_STREAM_CAPTURE]){
5940 + gdma_En_Switch(rtd,STREAM_CAPTURE,GDMA_I2S_DIS);
5941 + i2s_tx_end_sleep_on(rtd);
5942 + tasklet_kill(&i2s_rx_tasklet);
5943 + i2s_rx_disable(rtd);
5944 + //mt76xx_pcm_free_dma_buffer(substream,substream->stream);
5945 + i2s_page_release(rtd,STREAM_CAPTURE);
5946 + rtd->dmaStat[SNDRV_PCM_STREAM_CAPTURE] = 0;
5948 + mt76xx_pcm_free_dma_buffer(substream,substream->stream);
5953 +static int mt76xx_pcm_free_dma_buffer(struct snd_pcm_substream *substream,
5957 + //struct snd_pcm_substream *substream = pcm->streams[stream].substream;
5958 + struct snd_dma_buffer *buf = &substream->dma_buffer;
5959 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
5961 + //printk("******* %s *******\n", __func__);
5964 + if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
5965 + i2s_memPool_free(rtd,STREAM_PLAYBACK);
5967 + i2s_memPool_free(rtd,STREAM_CAPTURE);
5969 + snd_pcm_set_runtime_buffer(substream, NULL);
5973 +static int mt76xx_pcm_allocate_dma_buffer(struct snd_pcm_substream *substream,
5976 + //struct snd_pcm_substream *substream = pcm->streams[stream].substream;
5977 + struct snd_dma_buffer *buf = &substream->dma_buffer;
5978 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
5980 + //printk("******* %s *******\n", __func__);
5982 +#if defined(CONFIG_I2S_MMAP)
5983 + printk("\n############## MMAP ##############\n");
5984 + buf->dev.type = SNDRV_DMA_TYPE_DEV;
5986 + buf->dev.type = SNDRV_DMA_TYPE_UNKNOWN;
5988 + buf->dev.dev = NULL;
5989 + buf->private_data = NULL;
5990 + if(stream == SNDRV_PCM_STREAM_PLAYBACK)
5991 + buf->area = i2s_memPool_Alloc(rtd,STREAM_PLAYBACK);
5993 + buf->area = i2s_memPool_Alloc(rtd,STREAM_CAPTURE);
5997 + buf->bytes = GDMA_TOTAL_PAGE_SIZE;
5998 +#if defined(CONFIG_I2S_MMAP)
5999 + buf->addr = i2s_mmap_phys_addr(rtd);
6001 + snd_pcm_set_runtime_buffer(substream, buf);
6003 + //printk("Buffer have been allocated!\n");
6009 +static int mt76xx_pcm_open(struct snd_pcm_substream *substream)
6011 + struct snd_pcm_runtime *runtime= substream->runtime;
6012 + struct snd_dma_buffer *buf = &substream->dma_buffer;
6013 + int stream = substream->stream;
6016 + //printk("******* %s *******\n", __func__);
6017 + snd_soc_set_runtime_hwparams(substream, &mt76xx_pcm_hwparam);
6018 + /* ensure that buffer size is a multiple of period size */
6019 + ret = snd_pcm_hw_constraint_integer(runtime,
6020 + SNDRV_PCM_HW_PARAM_PERIODS);
6025 + if(stream == SNDRV_PCM_STREAM_PLAYBACK){
6026 + ret = mt76xx_pcm_allocate_dma_buffer(substream,
6027 + SNDRV_PCM_STREAM_PLAYBACK);
6030 + ret = mt76xx_pcm_allocate_dma_buffer(substream,
6031 + SNDRV_PCM_STREAM_CAPTURE);
6039 + memset(buf->area,0,sizeof(I2S_PAGE_SIZE*MAX_I2S_PAGE));
6047 +static int mt76xx_pcm_new(struct snd_soc_pcm_runtime *rtd)
6051 + //printk("******* %s *******\n", __func__);
6055 +static void mt76xx_pcm_free(struct snd_pcm *pcm)
6057 + /*struct snd_pcm_substream *substream;
6058 + struct snd_dma_buffer *buf;
6059 + i2s_config_type* rtd;
6062 + //printk("******* %s *******\n", __func__);
6066 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,20)
6067 +static int mt76xx_platform_drv_probe(struct platform_device *pdev)
6069 + //printk("******* %s *******\n", __func__);
6070 + return snd_soc_register_platform(&pdev->dev, &mt76xx_soc_platform);
6073 +static int mt76xx_platform_drv_remove(struct platform_device *pdev)
6075 + //printk("******* %s *******\n", __func__);
6076 + snd_soc_unregister_platform(&pdev->dev);
6080 +static struct platform_driver mt76xx_pcm_driver = {
6082 + .name = "mt76xx-pcm",
6083 + .owner = THIS_MODULE,
6086 + .probe = mt76xx_platform_drv_probe,
6087 + .remove = mt76xx_platform_drv_remove,
6090 +static int __init mt76xx_pcm_init(void)
6093 + printk("******* %s *******\n", __func__);
6094 + return platform_driver_register(&mt76xx_pcm_driver);
6097 +static void __exit mt76xx_pcm_exit(void)
6099 + platform_driver_unregister(&mt76xx_pcm_driver);
6102 +static int __init mt76xx_pcm_init(void)
6105 + printk("******* %s *******\n", __func__);
6106 + return snd_soc_register_platform(&mt76xx_soc_platform);
6109 +static void __exit mt76xx_pcm_exit(void)
6111 + printk("******* %s *******\n", __func__);
6112 + snd_soc_unregister_platform(&mt76xx_soc_platform);
6115 +module_init(mt76xx_pcm_init);
6116 +module_exit(mt76xx_pcm_exit);
6118 +MODULE_AUTHOR("Dora Chen");
6119 +MODULE_DESCRIPTION("MTK APSoC I2S DMA driver");
6120 +MODULE_LICENSE("GPL");
6123 +++ b/sound/soc/mtk/ralink_gdma.c
6126 + ***************************************************************************
6127 + * Ralink Tech Inc.
6128 + * 5F., No.36, Taiyuan St., Jhubei City,
6129 + * Hsinchu County 302,
6132 + * (c) Copyright, Ralink Technology, Inc.
6134 + * This program is free software; you can redistribute it and/or modify it
6135 + * under the terms of the GNU General Public License as published by the
6136 + * Free Software Foundation; either version 2 of the License, or (at your
6137 + * option) any later version.
6139 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
6140 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
6141 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
6142 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
6143 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
6144 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
6145 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
6146 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6147 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
6148 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6150 + * You should have received a copy of the GNU General Public License along
6151 + * with this program; if not, write to the Free Software Foundation, Inc.,
6152 + * 675 Mass Ave, Cambridge, MA 02139, USA.
6155 + ***************************************************************************
6164 + -------- ---------- ----------------------------------------------
6165 + Name Date Modification logs
6166 + Steven Liu 2009-03-24 Support RT3883
6169 +#include <linux/init.h>
6170 +#include <linux/version.h>
6171 +#include <linux/module.h>
6172 +#include <linux/kernel.h>
6173 +#include <linux/interrupt.h>
6174 +#include <linux/fs.h>
6175 +#if defined (CONFIG_MIPS)
6176 + #include <asm/uaccess.h>
6177 + #include <asm/addrspace.h>
6180 +#include "ralink_gdma.h"
6184 + * Ch0 : Pcm0_Rx0 | Pcm0_Rx0 | ALL
6185 + * Ch1 : Pcm0_Rx1 | Pcm0_Rx1 | ALL
6186 + * Ch2 : Pcm0_Tx0 | Pcm0_Tx0 | ALL
6187 + * Ch3 : Pcm0_Tx1 | Pcm0_Tx1 | ALL
6188 + * Ch4 : Pcm1_Rx0 | I2S_Tx0 | ALL
6189 + * Ch5 : Pcm1_Rx1 | I2S_Tx1 | ALL
6190 + * Ch6 : Pcm1_Tx0 | ALL | ALL
6191 + * Ch7 : Pcm1_Tx1 | ALL | ALL
6194 + * Ch0 : Pcm0_Rx0 | Pcm0_Rx0 | ALL
6195 + * Ch1 : Pcm0_Rx1 | Pcm0_Rx1 | ALL
6196 + * Ch2 : Pcm0_Tx0 | Pcm0_Tx0 | ALL
6197 + * Ch3 : Pcm0_Tx1 | Pcm0_Tx1 | ALL
6198 + * Ch4 : Pcm1_Rx0 | I2S_Tx0 | ALL
6199 + * Ch5 : Pcm1_Rx1 | I2S_Tx1 | ALL
6200 + * Ch6 : Pcm1_Tx0 | I2S_Rx0 | ALL
6201 + * Ch7 : Pcm1_Tx1 | I2S_Rx1 | ALL
6202 + * Ch8 : ALL | ALL | ALL
6203 + * Ch9 : ALL | ALL | ALL
6204 + * Ch10 : ALL | ALL | ALL
6205 + * Ch11 : ALL | ALL | ALL
6206 + * Ch12 : ALL | ALL | ALL PCI TX
6207 + * Ch13 : ALL | ALL | ALL PCI RX
6208 + * Ch14 : ALL | ALL | ALL
6209 + * Ch15 : ALL | ALL | ALL
6213 +spinlock_t gdma_lock;
6214 +spinlock_t gdma_lock_mem;
6215 +spinlock_t gdma_int_lock;
6216 +void (*GdmaDoneIntCallback[MAX_GDMA_CHANNEL])(uint32_t);
6217 +void (*GdmaUnMaskIntCallback[MAX_GDMA_CHANNEL])(uint32_t);
6221 + * @brief Get free GDMA channel
6223 + * @param ChNum GDMA channel number
6224 + * @retval 1 channel is available
6225 + * @retval 0 channels are all busy
6227 +int _GdmaGetFreeCh(uint32_t *ChNum)
6229 + unsigned long flags;
6232 +#if defined (CONFIG_GDMA_DEBUG)
6233 + static uint32_t Ch_RR=0;
6236 + spin_lock_irqsave(&gdma_lock, flags);
6238 +#if defined (CONFIG_GDMA_PCM_ONLY)
6239 +#if defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) || defined (CONFIG_RALINK_RT6855A) || defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
6240 + for(Ch=14; Ch<MAX_GDMA_CHANNEL;Ch++) //channel 14~max_channe, channel 0~13 be usedl
6242 + for(Ch=MAX_GDMA_CHANNEL; Ch<MAX_GDMA_CHANNEL;Ch++) //no free channel
6244 +#elif defined (CONFIG_GDMA_PCM_I2S_OTHERS)
6245 +#if defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) || defined (CONFIG_RALINK_RT6855A) || defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
6246 + for(Ch=14; Ch<MAX_GDMA_CHANNEL;Ch++) //channel 14~max_channe, channel 0~13 be usedl
6248 + for(Ch=6; Ch<MAX_GDMA_CHANNEL;Ch++) //channel 6~max_channel
6250 +#elif defined (CONFIG_GDMA_EVERYBODY)
6251 + for(Ch=0; Ch<MAX_GDMA_CHANNEL;Ch++) //all channel
6252 +#elif defined (CONFIG_GDMA_DEBUG)
6253 + for(Ch=(Ch_RR++)%MAX_GDMA_CHANNEL; Ch<MAX_GDMA_CHANNEL;Ch++) //round robin
6256 + Data=GDMA_READ_REG(GDMA_CTRL_REG(Ch));
6258 + /* hardware will reset this bit if transaction is done.
6259 + * It means channel is free */
6260 + if((Data & (0x01<<CH_EBL_OFFSET))==0) {
6262 + spin_unlock_irqrestore(&gdma_lock, flags);
6263 + return 1; //Channel is free
6267 + spin_unlock_irqrestore(&gdma_lock, flags);
6268 + return 0; // Channels are all busy
6273 + * @brief Set channel is masked
6275 + * When channel is masked, the GDMA transaction will stop.
6276 + * When GDMA controller comes back from another channel (chain feature)
6278 + * >> Channel Mask=0: It's strange, and turns on related bit in GDMA interrupt
6279 + * status register (16:23 Unmasked)
6281 + * >> Channel Mask=1: It'll start GDMA transation, and clear this bit.
6283 + * @param ChNum GDMA channel number
6284 + * @retval 1 success
6287 +int GdmaMaskChannel(uint32_t ChNum)
6291 + Data=GDMA_READ_REG(GDMA_CTRL_REG1(ChNum));
6292 + Data |= ( 0x01 << CH_MASK_OFFSET);
6293 + GDMA_WRITE_REG(GDMA_CTRL_REG1(ChNum), Data);
6294 + GDMA_PRINT("%s: Write %0X to %X\n", __FUNCTION__, Data, GDMA_CTRL_REG1(ChNum));
6300 + * @brief Set channel is unmasked
6302 + * You can unmask the channel to start GDMA transaction.
6304 + * When GDMA controller comes back from another channel (chain feature)
6306 + * >> Channel Mask=0: It's strange, and turns on related bit in GDMA interrupt
6307 + * status register (16:23 Unmasked)
6309 + * >> Channel Mask=1: It'll start GDMA transation, and clear this bit.
6311 + * @param ChNum GDMA channel number
6312 + * @retval 1 success
6315 +int GdmaUnMaskChannel(uint32_t ChNum)
6319 + Data=GDMA_READ_REG(GDMA_CTRL_REG1(ChNum));
6320 + Data &= ~( 0x01 << CH_MASK_OFFSET);
6321 + GDMA_WRITE_REG(GDMA_CTRL_REG1(ChNum), Data);
6322 + GDMA_PRINT("%s: Write %0X to %X\n", __FUNCTION__, Data, GDMA_CTRL_REG1(ChNum));
6328 + * @brief Insert new GDMA entry to start GDMA transaction
6330 + * @param ChNum GDMA channel number
6331 + * @retval 1 success
6334 +int GdmaReqQuickIns(uint32_t ChNum)
6339 + Data = GDMA_READ_REG(GDMA_CTRL_REG1(ChNum));
6340 + Data |= ( 0x1 << CH_MASK_OFFSET);
6341 + GDMA_WRITE_REG(GDMA_CTRL_REG1(ChNum), Data);
6344 + Data = GDMA_READ_REG(GDMA_CTRL_REG(ChNum));
6345 + Data |= (0x01<<CH_EBL_OFFSET);
6346 + GDMA_WRITE_REG(GDMA_CTRL_REG(ChNum), Data);
6352 +int _GdmaReqEntryIns(GdmaReqEntry *NewEntry)
6356 + GDMA_PRINT("== << GDMA Control Reg (Channel=%d) >> ===\n", NewEntry->ChNum);
6357 + GDMA_PRINT(" Channel Source Addr = %x \n", NewEntry->Src);
6358 + GDMA_PRINT(" Channel Dest Addr = %x \n", NewEntry->Dst);
6359 + GDMA_PRINT(" Transfer Count=%d\n", NewEntry->TransCount);
6360 + GDMA_PRINT(" Source DMA Req= DMA_REQ%d\n", NewEntry->SrcReqNum);
6361 + GDMA_PRINT(" Dest DMA Req= DMA_REQ%d\n", NewEntry->DstReqNum);
6362 + GDMA_PRINT(" Source Burst Mode=%s\n", NewEntry->SrcBurstMode ? "Fix" : "Inc");
6363 + GDMA_PRINT(" Dest Burst Mode=%s\n", NewEntry->DstBurstMode ? "Fix" : "Inc");
6364 + GDMA_PRINT(" Burst Size=%s\n", NewEntry->BurstSize ==0 ? "1 transfer" : \
6365 + NewEntry->BurstSize ==1 ? "2 transfer" :\
6366 + NewEntry->BurstSize ==2 ? "4 transfer" :\
6367 + NewEntry->BurstSize ==3 ? "8 transfer" :\
6368 + NewEntry->BurstSize ==4 ? "16 transfer" :\
6370 + GDMA_PRINT(" Hardware/Software Mode = %s\n", NewEntry->SoftMode ?
6372 + GDMA_PRINT("== << GDMA Control Reg1 (Channel=%d) >> =\n", NewEntry->ChNum);
6373 + GDMA_PRINT("Channel Done Interrput=%s\n", (NewEntry->DoneIntCallback!=NULL) ?
6374 + "Enable" : "Disable");
6375 + GDMA_PRINT("Channel Unmasked Int=%s\n", (NewEntry->UnMaskIntCallback!=NULL) ?
6376 + "Enable" : "Disable");
6377 +#if !defined (CONFIG_RALINK_RT3052) && !defined (CONFIG_RALINK_RT3883)
6378 + GDMA_PRINT("Coherent Interrupt =%s\n", (NewEntry->CoherentIntEbl==1)?
6379 + "Enable" : "Disable");
6381 + GDMA_PRINT("Next Unmasked Channel=%d\n", NewEntry->NextUnMaskCh);
6382 + GDMA_PRINT("Channel Mask=%d\n", NewEntry->ChMask);
6383 + GDMA_PRINT("========================================\n");
6385 + GDMA_WRITE_REG(GDMA_SRC_REG(NewEntry->ChNum), NewEntry->Src);
6386 + GDMA_PRINT("SrcAddr: Write %0X to %X\n", \
6387 + NewEntry->Src, GDMA_SRC_REG(NewEntry->ChNum));
6389 + GDMA_WRITE_REG(GDMA_DST_REG(NewEntry->ChNum), NewEntry->Dst);
6390 + GDMA_PRINT("DstAddr: Write %0X to %X\n", \
6391 + NewEntry->Dst, GDMA_DST_REG(NewEntry->ChNum));
6393 + Data |= ( (NewEntry->NextUnMaskCh) << NEXT_UNMASK_CH_OFFSET);
6394 + Data |= ( NewEntry->ChMask << CH_MASK_OFFSET);
6395 +#if !defined (CONFIG_RALINK_RT3052) && !defined (CONFIG_RALINK_RT3883)
6396 + Data |= ( NewEntry->CoherentIntEbl << COHERENT_INT_EBL_OFFSET);
6399 + if(NewEntry->UnMaskIntCallback!=NULL) {
6400 + Data |= (0x01<<CH_UNMASKINT_EBL_OFFSET);
6401 + GdmaUnMaskIntCallback[NewEntry->ChNum] = NewEntry->UnMaskIntCallback;
6404 +#if defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) || defined (CONFIG_RALINK_RT6855A) || defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
6405 + Data |= (NewEntry->SrcReqNum << SRC_DMA_REQ_OFFSET);
6406 + Data |= (NewEntry->DstReqNum << DST_DMA_REQ_OFFSET);
6409 + GDMA_WRITE_REG(GDMA_CTRL_REG1(NewEntry->ChNum), Data);
6410 + GDMA_PRINT("CTRL1: Write %08X to %8X\n", Data, GDMA_CTRL_REG1(NewEntry->ChNum));
6412 + Data = ((NewEntry->TransCount) << TRANS_CNT_OFFSET);
6413 +#if defined (CONFIG_RALINK_RT3052)
6414 + Data |= (NewEntry->SrcReqNum << SRC_DMA_REQ_OFFSET);
6415 + Data |= (NewEntry->DstReqNum << DST_DMA_REQ_OFFSET);
6417 + Data |= (NewEntry->SrcBurstMode << SRC_BRST_MODE_OFFSET);
6418 + Data |= (NewEntry->DstBurstMode << DST_BRST_MODE_OFFSET);
6419 + Data |= (NewEntry->BurstSize << BRST_SIZE_OFFSET);
6421 + if(NewEntry->DoneIntCallback!=NULL) {
6422 + Data |= (0x01<<CH_DONEINT_EBL_OFFSET);
6423 + GdmaDoneIntCallback[NewEntry->ChNum] = NewEntry->DoneIntCallback;
6426 + if(NewEntry->SoftMode) {
6427 + Data |= (0x01<<MODE_SEL_OFFSET);
6430 + Data |= (0x01<<CH_EBL_OFFSET);
6431 + GDMA_WRITE_REG(GDMA_CTRL_REG(NewEntry->ChNum), Data);
6432 + //GDMA_READ_REG(GDMA_CTRL_REG(NewEntry->ChNum));
6433 + GDMA_PRINT("CTRL: Write %08X to %8X\n", Data, GDMA_CTRL_REG(NewEntry->ChNum));
6434 + //if there is no interrupt handler, this function will
6435 + //return 1 until GDMA done.
6436 + if(NewEntry->DoneIntCallback==NULL) {
6437 + //wait for GDMA processing done
6438 +#if defined (CONFIG_RALINK_RT3052)
6439 + while((GDMA_READ_REG(RALINK_GDMAISTS) &
6440 + (0x1<<NewEntry->ChNum))==0);
6442 + GDMA_WRITE_REG(RALINK_GDMAISTS, 1<< NewEntry->ChNum);
6443 +#elif defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) || defined (CONFIG_RALINK_RT6855A) || defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
6444 + while((GDMA_READ_REG(RALINK_GDMA_DONEINT) &
6445 + (0x1<<NewEntry->ChNum))==0);
6447 + GDMA_WRITE_REG(RALINK_GDMA_DONEINT, 1<< NewEntry->ChNum);
6455 +#if defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
6457 + * @brief Start GDMA transaction for sending data to SPI
6459 + * @param *Src source address
6460 + * @param *Dst destination address
6462 + * @param TransCount data length
6463 + * @param *DoneIntCallback callback function when transcation is done
6464 + * @param *UnMaskIntCallback callback func when ch mask field is incorrect
6465 + * @retval 1 success
6471 + uint16_t TransCount,
6472 + void (*DoneIntCallback)(uint32_t data),
6473 + void (*UnMaskIntCallback)(uint32_t data)
6476 + GdmaReqEntry Entry;
6478 + #if defined (CONFIG_MIPS)
6479 + Entry.Src= (Src & 0x1FFFFFFF);
6480 + Entry.Dst= (Dst & 0x1FFFFFFF);
6485 + Entry.TransCount = TransCount;
6486 + Entry.SrcBurstMode=INC_MODE;
6487 + Entry.DstBurstMode=FIX_MODE;
6488 + Entry.BurstSize=BUSTER_SIZE_4B;
6489 + Entry.SrcReqNum=DMA_MEM_REQ;
6490 + Entry.DstReqNum=DMA_SPI_TX_REQ;
6491 + Entry.DoneIntCallback=DoneIntCallback;
6492 + Entry.UnMaskIntCallback=UnMaskIntCallback;
6495 + Entry.CoherentIntEbl=0;
6497 + //enable chain feature
6498 + Entry.ChNum = GDMA_SPI_TX;
6499 + Entry.NextUnMaskCh = GDMA_SPI_TX;
6501 + return _GdmaReqEntryIns(&Entry);
6507 + uint16_t TransCount,
6508 + void (*DoneIntCallback)(uint32_t data),
6509 + void (*UnMaskIntCallback)(uint32_t data)
6512 + GdmaReqEntry Entry;
6514 + #if defined (CONFIG_MIPS)
6515 + Entry.Src= (Src & 0x1FFFFFFF);
6516 + Entry.Dst= (Dst & 0x1FFFFFFF);
6521 + Entry.TransCount = TransCount;
6522 + Entry.SrcBurstMode=FIX_MODE;
6523 + Entry.DstBurstMode=INC_MODE;
6524 + Entry.BurstSize=BUSTER_SIZE_4B;
6525 + Entry.SrcReqNum=DMA_SPI_RX_REQ;
6526 + Entry.DstReqNum=DMA_MEM_REQ;
6527 + Entry.DoneIntCallback=DoneIntCallback;
6528 + Entry.UnMaskIntCallback=UnMaskIntCallback;
6531 + Entry.CoherentIntEbl=1;
6534 + //enable chain feature
6535 + Entry.ChNum=GDMA_SPI_RX;
6536 + Entry.NextUnMaskCh=GDMA_SPI_RX;
6539 + return _GdmaReqEntryIns(&Entry);
6546 + * @brief Start GDMA transaction for sending data to I2S
6548 + * @param *Src source address
6549 + * @param *Dst destination address
6550 + * @param TxNo I2S Tx number
6551 + * @param TransCount data length
6552 + * @param *DoneIntCallback callback function when transcation is done
6553 + * @param *UnMaskIntCallback callback func when ch mask field is incorrect
6554 + * @retval 1 success
6561 + uint16_t TransCount,
6562 + void (*DoneIntCallback)(uint32_t data),
6563 + void (*UnMaskIntCallback)(uint32_t data)
6566 + GdmaReqEntry Entry;
6568 + #if defined (CONFIG_MIPS)
6569 + Entry.Src= (Src & 0x1FFFFFFF);
6570 + Entry.Dst= (Dst & 0x1FFFFFFF);
6575 + Entry.TransCount = TransCount;
6576 + Entry.SrcBurstMode=INC_MODE;
6577 + Entry.DstBurstMode=FIX_MODE;
6578 + Entry.BurstSize=BUSTER_SIZE_4B;
6579 + Entry.SrcReqNum=DMA_MEM_REQ;
6580 + Entry.DstReqNum=DMA_I2S_TX_REQ;
6581 + Entry.DoneIntCallback=DoneIntCallback;
6582 + Entry.UnMaskIntCallback=UnMaskIntCallback;
6585 + Entry.CoherentIntEbl=0;
6587 + if(TxNo==0) { //TX0
6588 + //enable chain feature
6589 + Entry.ChNum=GDMA_I2S_TX0;
6590 + Entry.NextUnMaskCh= (TransCount==4) ? GDMA_I2S_TX0 : GDMA_I2S_TX1;
6591 + }else if(TxNo==1) { //TX1
6592 + //enable chain feature
6593 + Entry.ChNum=GDMA_I2S_TX1;
6594 + Entry.NextUnMaskCh= (TransCount==4) ? GDMA_I2S_TX1 : GDMA_I2S_TX0;
6596 + GDMA_PRINT("I2S Tx Number %x is invalid\n", TxNo);
6600 + return _GdmaReqEntryIns(&Entry);
6605 +#if defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) || defined (CONFIG_RALINK_RT6855A) || defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
6607 + * @brief Start GDMA transaction for receiving data to I2S
6609 + * @param *Src source address
6610 + * @param *Dst destination address
6611 + * @param TxNo I2S Tx number
6612 + * @param TransCount data length
6613 + * @param *DoneIntCallback callback function when transcation is done
6614 + * @param *UnMaskIntCallback callback func when ch mask field is incorrect
6615 + * @retval 1 success
6622 + uint16_t TransCount,
6623 + void (*DoneIntCallback)(uint32_t data),
6624 + void (*UnMaskIntCallback)(uint32_t data)
6627 + GdmaReqEntry Entry;
6628 + #if defined (CONFIG_MIPS)
6629 + Entry.Src= (Src & 0x1FFFFFFF);
6630 + Entry.Dst= (Dst & 0x1FFFFFFF);
6635 + Entry.TransCount = TransCount;
6636 + Entry.SrcBurstMode=FIX_MODE;
6637 + Entry.DstBurstMode=INC_MODE;
6638 + Entry.BurstSize=BUSTER_SIZE_4B;
6639 + Entry.SrcReqNum=DMA_I2S_RX_REQ;
6640 + Entry.DstReqNum=DMA_MEM_REQ;
6641 + Entry.DoneIntCallback=DoneIntCallback;
6642 + Entry.UnMaskIntCallback=UnMaskIntCallback;
6645 + Entry.CoherentIntEbl=1;
6647 + if(RxNo==0) { //RX0
6648 + //enable chain feature
6649 + Entry.ChNum=GDMA_I2S_RX0;
6650 + Entry.NextUnMaskCh=(TransCount==4) ? GDMA_I2S_RX0 : GDMA_I2S_RX1;
6651 + }else if(RxNo==1) { //RX1
6652 + //enable chain feature
6653 + Entry.ChNum=GDMA_I2S_RX1;
6654 + Entry.NextUnMaskCh=(TransCount==4) ? GDMA_I2S_RX1 : GDMA_I2S_RX0;
6656 + GDMA_PRINT("I2S Rx Number %x is invalid\n", RxNo);
6660 + return _GdmaReqEntryIns(&Entry);
6667 + * @brief Start GDMA transaction for receiving data from PCM
6669 + * @param *Src source address
6670 + * @param *Dst destination address
6671 + * @param TransCount data length
6672 + * @param PcmNo PCM channel
6673 + * @param RxNo PCM Rx number
6674 + * @param *DoneIntCallback callback function when transcation is done
6675 + * @param *UnMaskIntCallback callback func when ch mask field is incorrect
6676 + * @retval 1 success
6684 + uint16_t TransCount,
6685 + void (*DoneIntCallback)(uint32_t data),
6686 + void (*UnMaskIntCallback)(uint32_t data)
6689 + GdmaReqEntry Entry;
6691 + #if defined (CONFIG_MIPS)
6692 + Entry.Src= (Src & 0x1FFFFFFF);
6693 + Entry.Dst= (Dst & 0x1FFFFFFF);
6698 + Entry.TransCount = TransCount;
6699 + Entry.SrcBurstMode=FIX_MODE;
6700 + Entry.DstBurstMode=INC_MODE;
6701 + Entry.BurstSize=BUSTER_SIZE_4B;
6702 + Entry.DstReqNum=DMA_MEM_REQ;
6703 + Entry.DoneIntCallback=DoneIntCallback;
6704 + Entry.UnMaskIntCallback=UnMaskIntCallback;
6707 + Entry.CoherentIntEbl=1;
6710 + GDMA_PRINT("PCM Rx Number %x is invalid\n", RxNo);
6717 + Entry.SrcReqNum=DMA_PCM_RX0_REQ;
6720 + Entry.SrcReqNum=DMA_PCM_RX1_REQ;
6722 +#if defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
6724 + Entry.SrcReqNum=DMA_PCM_RX2_REQ;
6727 + Entry.SrcReqNum=DMA_PCM_RX3_REQ;
6731 + GDMA_PRINT("PCM Channel %x is invalid\n", PcmNo);
6734 + Entry.ChNum=GDMA_PCM_RX(PcmNo,RxNo);
6735 + Entry.NextUnMaskCh=GDMA_PCM_RX(PcmNo,1-RxNo);
6737 + return _GdmaReqEntryIns(&Entry);
6742 + * @brief Start GDMA transaction for sending data to PCM
6744 + * @param *Src source address
6745 + * @param *Dst destination address
6746 + * @param TransCount data length
6747 + * @param PcmNo PCM channel
6748 + * @param TxNo PCM Tx number
6749 + * @param *DoneIntCallback callback func when transcation is done
6750 + * @param *UnMaskIntCallback callback func when ch mask field is incorrect
6751 + * @retval 1 success
6759 + uint16_t TransCount,
6760 + void (*DoneIntCallback)(uint32_t data),
6761 + void (*UnMaskIntCallback)(uint32_t data)
6764 + GdmaReqEntry Entry;
6766 + #if defined (CONFIG_MIPS)
6767 + Entry.Src= (Src & 0x1FFFFFFF);
6768 + Entry.Dst= (Dst & 0x1FFFFFFF);
6773 + Entry.TransCount = TransCount;
6774 + Entry.SrcBurstMode=INC_MODE;
6775 + Entry.DstBurstMode=FIX_MODE;
6776 + Entry.BurstSize=BUSTER_SIZE_4B;
6777 + Entry.SrcReqNum=DMA_MEM_REQ;
6778 + Entry.DoneIntCallback=DoneIntCallback;
6779 + Entry.UnMaskIntCallback=UnMaskIntCallback;
6780 + Entry.SoftMode=0; //Hardware Mode
6782 + Entry.CoherentIntEbl=0;
6785 + GDMA_PRINT("PCM Tx Number %x is invalid\n", TxNo);
6791 + Entry.DstReqNum=DMA_PCM_TX0_REQ;
6794 + Entry.DstReqNum=DMA_PCM_TX1_REQ;
6796 +#if defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
6798 + Entry.DstReqNum=DMA_PCM_TX2_REQ;
6801 + Entry.DstReqNum=DMA_PCM_TX3_REQ;
6805 + GDMA_PRINT("PCM Channel %x is invalid\n", PcmNo);
6808 + Entry.ChNum=GDMA_PCM_TX(PcmNo,TxNo);
6809 + Entry.NextUnMaskCh=GDMA_PCM_TX(PcmNo,1-TxNo);
6811 + return _GdmaReqEntryIns(&Entry);
6817 + * @brief Start GDMA transaction for memory to memory copy
6819 + * @param *Src source address
6820 + * @param *Dst destination address
6821 + * @param TransCount data length
6822 + * @param *DoneIntCallback callback function when transcation is done
6823 + * @retval 1 success
6829 + uint16_t TransCount,
6830 + void (*DoneIntCallback)(uint32_t data)
6835 + GdmaReqEntry Entry;
6836 + #if defined (CONFIG_MIPS)
6837 + Entry.Src= (Src & 0x1FFFFFFF);
6838 + Entry.Dst= (Dst & 0x1FFFFFFF);
6844 + //Entry.Src= virt_to_phys(Src);
6845 + //Entry.Dst= virt_to_phys(Dst);
6849 + Entry.TransCount = TransCount;
6850 + Entry.SrcBurstMode=INC_MODE;
6851 + Entry.DstBurstMode=INC_MODE;
6852 + Entry.BurstSize=BUSTER_SIZE_64B;
6853 + Entry.SrcReqNum=DMA_MEM_REQ;
6854 + Entry.DstReqNum=DMA_MEM_REQ;
6855 + Entry.DoneIntCallback=DoneIntCallback;
6856 + Entry.UnMaskIntCallback=NULL;
6860 + Entry.CoherentIntEbl=1;
6862 + //No reserved channel for Memory to Memory GDMA,
6863 + //get free channel on demand
6864 + if(!_GdmaGetFreeCh(&Entry.ChNum)) {
6865 + GDMA_PRINT("GDMA Channels are all busy\n");
6870 + //set next channel to their own channel
6871 + //to disable chain feature
6872 + Entry.NextUnMaskCh= Entry.ChNum;
6873 + //printk ("ChNum = %d\n", Entry.ChNum);
6874 + //set next channel to another channel
6875 + //to enable chain feature
6876 + //Entry.NextUnMaskCh= (Entry.ChNum+1) % MAX_GDMA_CHANNEL;
6878 + return _GdmaReqEntryIns(&Entry);
6884 + * @brief GDMA interrupt handler
6886 + * When GDMA transcation is done, call related handler
6887 + * to do the remain job.
6890 +irqreturn_t GdmaIrqHandler(
6897 + unsigned long flags;
6898 +#if defined (CONFIG_RALINK_RT3052)
6899 + u32 GdmaUnMaskStatus=GDMA_READ_REG(RALINK_GDMAISTS) & 0xFF0000;
6900 + u32 GdmaDoneStatus=GDMA_READ_REG(RALINK_GDMAISTS) & 0xFF;
6901 +#elif defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) || defined (CONFIG_RALINK_RT6855A) || defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
6902 + u32 GdmaUnMaskStatus=GDMA_READ_REG(RALINK_GDMA_UNMASKINT);
6903 + u32 GdmaDoneStatus=GDMA_READ_REG(RALINK_GDMA_DONEINT);
6905 + //printk("********GDMA Interrupt*******************\n");
6907 + //GDMA_PRINT("========================================\n");
6908 + //GDMA_PRINT("GdmaUnMask Interrupt=%x\n",GdmaUnMaskStatus);
6909 + //GDMA_PRINT("GdmaDone Interrupt=%x\n",GdmaDoneStatus);
6910 + //GDMA_PRINT("========================================\n");
6912 + spin_lock_irqsave(&gdma_int_lock, flags);
6915 +#if defined (CONFIG_RALINK_RT3052)
6916 + GDMA_WRITE_REG(RALINK_GDMAISTS, GdmaUnMaskStatus);
6917 +#elif defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) || defined (CONFIG_RALINK_RT6855A) || defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
6918 + GDMA_WRITE_REG(RALINK_GDMA_UNMASKINT, GdmaUnMaskStatus);
6922 + for(Ch=0;Ch<MAX_GDMA_CHANNEL;Ch++) {
6924 + if(GdmaUnMaskStatus & (0x1 << (UNMASK_INT_STATUS(Ch))) ) {
6925 + if(GdmaUnMaskIntCallback[Ch] != NULL) {
6926 + GdmaUnMaskIntCallback[Ch](Ch);
6927 + // printk("GdmaUnMaskIntCallback \n");
6933 +#if defined (CONFIG_RALINK_RT3052)
6934 + GDMA_WRITE_REG(RALINK_GDMAISTS, GdmaDoneStatus);
6935 +#elif defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) || defined (CONFIG_RALINK_RT6855A) || defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
6936 + GDMA_WRITE_REG(RALINK_GDMA_DONEINT, GdmaDoneStatus);
6939 + //printk("interrupt status = %x \n", GdmaDoneStatus);
6941 + for(Ch=0;Ch<MAX_GDMA_CHANNEL;Ch++) {
6942 + if(GdmaDoneStatus & (0x1<<Ch)) {
6943 + if(GdmaDoneIntCallback[Ch] != NULL) {
6944 + //printk("*************Interrupt Ch=%d***********\n", Ch);
6945 + GdmaDoneIntCallback[Ch](Ch);
6950 +//printk("interrupt status clear = %x \n", GDMA_READ_REG(RALINK_GDMA_DONEINT));
6951 + spin_unlock_irqrestore(&gdma_int_lock, flags);
6953 + return IRQ_HANDLED;
6957 +static int RalinkGdmaInit(void)
6962 + printk("Enable Ralink GDMA Controller Module \n");
6963 +#if defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) || defined (CONFIG_RALINK_RT6855A) || defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
6964 + printk("GDMA IP Version=%d\n", GET_GDMA_IP_VER);
6966 +spin_lock_init(&gdma_int_lock);
6967 +spin_lock_init(&gdma_lock);
6968 +//spin_lock_init(&gdma_lock_mem);
6970 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
6971 + #if defined (CONFIG_MIPS)
6972 + Ret = request_irq(SURFBOARDINT_DMA, GdmaIrqHandler, \
6973 + IRQF_DISABLED, "Ralink_DMA", NULL);
6975 + Ret = request_irq(SURFBOARDINT_DMA, GdmaIrqHandler, \
6976 + IRQF_TRIGGER_LOW, "Ralink_DMA", NULL);
6979 + Ret = request_irq(SURFBOARDINT_DMA, GdmaIrqHandler, \
6980 + SA_INTERRUPT, "Ralink_DMA", NULL);
6984 + Ret = request_irq(131, GdmaIrqHandler, \
6985 + IRQF_TRIGGER_LOW, "Ralink_DMA", NULL);
6988 + GDMA_PRINT("IRQ %d is not free.\n", SURFBOARDINT_DMA);
6992 +#if defined (CONFIG_MIPS)
6993 + //Enable GDMA interrupt
6994 + val = le32_to_cpu(*(volatile u32 *)(RALINK_REG_INTENA));
6995 + val |= RALINK_INTCTL_DMA;
6996 + GDMA_WRITE_REG(RALINK_REG_INTENA, val);
6999 + //Channel0~Channel7 are round-robin
7000 +#if defined (CONFIG_RALINK_RT3052)
7001 + GDMA_WRITE_REG(RALINK_GDMAGCT, 0x01);
7002 +#elif defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) || defined (CONFIG_RALINK_RT6855A) || defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
7003 + GDMA_WRITE_REG(RALINK_GDMA_GCT, 0x01);
7005 +#error Please Choose System Type
7011 +static void __exit RalinkGdmaExit(void)
7014 + printk("Disable Ralink GDMA Controller Module\n");
7015 +#if defined (CONFIG_MIPS)
7016 + //Disable GDMA interrupt
7017 + GDMA_WRITE_REG(RALINK_REG_INTDIS, RALINK_INTCTL_DMA);
7019 + free_irq(SURFBOARDINT_DMA, NULL);
7022 +module_init(RalinkGdmaInit);
7023 +module_exit(RalinkGdmaExit);
7025 +EXPORT_SYMBOL(GdmaI2sRx);
7026 +EXPORT_SYMBOL(GdmaI2sTx);
7027 +EXPORT_SYMBOL(GdmaPcmRx);
7028 +EXPORT_SYMBOL(GdmaPcmTx);
7029 +#if defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
7030 +EXPORT_SYMBOL(GdmaSpiRx);
7031 +EXPORT_SYMBOL(GdmaSpiTx);
7033 +EXPORT_SYMBOL(GdmaMem2Mem);
7034 +EXPORT_SYMBOL(GdmaReqQuickIns);
7035 +EXPORT_SYMBOL(GdmaMaskChannel);
7036 +EXPORT_SYMBOL(GdmaUnMaskChannel);
7039 +MODULE_DESCRIPTION("Ralink SoC GDMA Controller API Module");
7040 +MODULE_AUTHOR("Steven Liu <steven_liu@ralinktech.com.tw>");
7041 +MODULE_LICENSE("GPL");
7042 +MODULE_VERSION(MOD_VERSION);
7044 +++ b/sound/soc/mtk/ralink_gdma.h
7047 + ***************************************************************************
7048 + * Ralink Tech Inc.
7049 + * 5F., No.36, Taiyuan St., Jhubei City,
7050 + * Hsinchu County 302,
7053 + * (c) Copyright, Ralink Technology, Inc.
7055 + * This program is free software; you can redistribute it and/or modify it
7056 + * under the terms of the GNU General Public License as published by the
7057 + * Free Software Foundation; either version 2 of the License, or (at your
7058 + * option) any later version.
7060 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
7061 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
7062 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
7063 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
7064 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
7065 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
7066 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
7067 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7068 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
7069 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7071 + * You should have received a copy of the GNU General Public License along
7072 + * with this program; if not, write to the Free Software Foundation, Inc.,
7073 + * 675 Mass Ave, Cambridge, MA 02139, USA.
7076 + ***************************************************************************
7079 +#ifndef __RALINK_DMA_CTRL_H__
7080 +#define __RALINK_DMA_CTRL_H__
7082 +//#include <asm/rt2880/rt_mmap.h>
7085 + * DEFINITIONS AND MACROS
7087 +#define MOD_VERSION "0.4"
7089 +#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623)
7090 +#define MAX_GDMA_CHANNEL 16
7091 +#elif defined (CONFIG_RALINK_RT3052)
7092 +#define MAX_GDMA_CHANNEL 8
7093 +#elif defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) || defined (CONFIG_RALINK_RT6855A) || defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7628)
7094 +#define MAX_GDMA_CHANNEL 16
7096 +#error Please Choose System Type
7100 +#define RALINK_GDMA_CTRL_BASE (RALINK_GDMA_BASE)
7101 +#if defined (CONFIG_RALINK_RT3052)
7102 +#define RALINK_GDMAISTS (RALINK_GDMA_BASE + 0x80)
7103 +#define RALINK_GDMAGCT (RALINK_GDMA_BASE + 0x88)
7104 +#elif defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) || defined (CONFIG_RALINK_RT6855A) || defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
7105 +#define RALINK_GDMA_UNMASKINT (RALINK_GDMA_BASE + 0x200)
7106 +#define RALINK_GDMA_DONEINT (RALINK_GDMA_BASE + 0x204)
7107 +#define RALINK_GDMA_GCT (RALINK_GDMA_BASE + 0x220)
7110 +#define KSEG1 0xa0000000
7111 +#define PHYS_TO_VIRT(x) ((void *)((x) | KSEG1))
7112 +#define VIRT_TO_PHYS(x) ((unsigned long)(x) & ~KSEG1)
7117 +#if defined (CONFIG_ARCH_MT7623)
7118 +#include <mach/sync_write.h>
7119 +#define GDMA_READ_REG(phys) (*(volatile unsigned int *)((phys)))
7120 +#define GDMA_WRITE_REG(phys, val) mt65xx_reg_sync_writel((val), (phys))
7123 +#define GDMA_READ_REG(addr) (le32_to_cpu(*(volatile u32 *)(addr)))
7124 +#define GDMA_WRITE_REG(addr, val) *((volatile uint32_t *)(addr)) = cpu_to_le32(val)
7131 +#define GET_GDMA_IP_VER (GDMA_READ_REG(RALINK_GDMA_GCT) & 0x6) >> 1 //GDMA_GCT[2:1]
7133 +#define RALINK_IRQ_ADDR RALINK_INTCL_BASE
7134 +#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7628)
7135 +#define RALINK_REG_INTENA (RALINK_IRQ_ADDR + 0x80)
7136 +#define RALINK_REG_INTDIS (RALINK_IRQ_ADDR + 0x78)
7138 +#define RALINK_REG_INTENA (RALINK_IRQ_ADDR + 0x34)
7139 +#define RALINK_REG_INTDIS (RALINK_IRQ_ADDR + 0x38)
7143 + * 12bytes=GDMA Channel n Source Address(4) +
7144 + * GDMA Channel n Destination Address(4) +
7145 + * GDMA Channel n Control Register(4)
7148 +#define GDMA_SRC_REG(ch) (RALINK_GDMA_BASE + ch*16)
7149 +#define GDMA_DST_REG(ch) (GDMA_SRC_REG(ch) + 4)
7150 +#define GDMA_CTRL_REG(ch) (GDMA_DST_REG(ch) + 4)
7151 +#define GDMA_CTRL_REG1(ch) (GDMA_CTRL_REG(ch) + 4)
7153 +//GDMA Interrupt Status Register
7154 +#if defined (CONFIG_RALINK_RT3052)
7155 +#define UNMASK_INT_STATUS(ch) (ch+16)
7156 +#elif defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) || defined (CONFIG_RALINK_RT6855A) || defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
7157 +#define UNMASK_INT_STATUS(ch) (ch)
7159 +#define TXDONE_INT_STATUS(ch) (ch)
7162 +#define MODE_SEL_OFFSET 0
7163 +#define CH_EBL_OFFSET 1
7164 +#define CH_DONEINT_EBL_OFFSET 2
7165 +#define BRST_SIZE_OFFSET 3
7166 +#define DST_BRST_MODE_OFFSET 6
7167 +#define SRC_BRST_MODE_OFFSET 7
7168 +#define TRANS_CNT_OFFSET 16
7171 +#if defined (CONFIG_RALINK_RT3052)
7172 +#define CH_UNMASKINT_EBL_OFFSET 4
7173 +#define NEXT_UNMASK_CH_OFFSET 1
7174 +#elif defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) || defined (CONFIG_RALINK_RT6855A) || defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
7175 +#define CH_UNMASKINT_EBL_OFFSET 1
7176 +#define NEXT_UNMASK_CH_OFFSET 3
7178 +#define COHERENT_INT_EBL_OFFSET 2
7179 +#define CH_MASK_OFFSET 0
7182 +#if defined (CONFIG_RALINK_RT3052)
7184 +#define DST_DMA_REQ_OFFSET 8
7185 +#define SRC_DMA_REQ_OFFSET 12
7186 +#elif defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) || defined (CONFIG_RALINK_RT6855A) || defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
7188 +#define DST_DMA_REQ_OFFSET 8
7189 +#define SRC_DMA_REQ_OFFSET 16
7192 +#define GDMA_PCM0_RX0 0
7193 +#define GDMA_PCM0_RX1 1
7194 +#define GDMA_PCM0_TX0 2
7195 +#define GDMA_PCM0_TX1 3
7197 +#define GDMA_PCM1_RX0 4
7198 +#define GDMA_PCM1_RX1 5
7199 +#define GDMA_PCM1_TX0 6
7200 +#define GDMA_PCM1_TX1 7
7202 +#define GDMA_PCM_RX(i,j) (0+((i)<<2)+j)
7203 +#define GDMA_PCM_TX(i,j) (2+((i)<<2)+j)
7205 +#define GDMA_I2S_TX0 4
7206 +#define GDMA_I2S_TX1 5
7207 +#define GDMA_I2S_RX0 6
7208 +#define GDMA_I2S_RX1 7
7210 +#define GDMA_SPI_TX 13
7211 +#define GDMA_SPI_RX 12
7214 +//#define GDMA_DEBUG
7216 +#define GDMA_PRINT(fmt, args...) printk(KERN_INFO "GDMA: " fmt, ## args)
7218 +#define GDMA_PRINT(fmt, args...) { }
7222 + * TYPEDEFS AND STRUCTURES
7225 +enum GdmaBusterMode {
7230 +enum GdmaBusterSize {
7231 + BUSTER_SIZE_4B=0, /* 1 transfer */
7232 + BUSTER_SIZE_8B=1, /* 2 transfer */
7233 + BUSTER_SIZE_16B=2, /* 4 transfer */
7234 + BUSTER_SIZE_32B=3, /* 8 transfer */
7235 + BUSTER_SIZE_64B=4 /* 16 transfer */
7238 +enum GdmaDmaReqNum {
7239 +#if defined (CONFIG_RALINK_RT3052)
7243 + DMA_PCM_RX0_REQ=3,
7244 + DMA_PCM_RX1_REQ=4,
7245 + DMA_PCM_TX0_REQ=5,
7246 + DMA_PCM_TX1_REQ=6,
7249 +#elif defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855)
7254 + DMA_PCM_RX0_REQ=4,
7255 + DMA_PCM_RX1_REQ=5,
7256 + DMA_PCM_TX0_REQ=6,
7257 + DMA_PCM_TX1_REQ=7,
7258 + DMA_CODEC0_REQ8=8,
7259 + DMA_CODEC1_REQ9=9,
7267 + #if defined (CONFIG_RALINK_RT3883)
7269 + #elif defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855)
7273 +#elif defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
7278 + DMA_PCM_RX0_REQ=4,
7279 + DMA_PCM_RX1_REQ=5,
7280 + DMA_PCM_TX0_REQ=6,
7281 + DMA_PCM_TX1_REQ=7,
7282 + DMA_PCM_RX2_REQ=8,
7283 + DMA_PCM_RX3_REQ=9,
7284 + DMA_PCM_TX2_REQ=10,
7285 + DMA_PCM_TX3_REQ=11,
7286 + DMA_SPI_RX_REQ=12,
7287 + DMA_SPI_TX_REQ=13,
7290 +#elif defined (CONFIG_RALINK_RT6855A)
7295 + DMA_PCM_RX0_REQ=4,
7296 + DMA_PCM_RX1_REQ=5,
7297 + DMA_PCM_TX0_REQ=6,
7298 + DMA_PCM_TX1_REQ=7,
7299 + DMA_CODEC0_REQ8=8,
7300 + DMA_CODEC1_REQ9=9,
7309 +#error Please Choose System Type
7318 + uint16_t TransCount;
7320 + uint8_t NextUnMaskCh;
7322 + uint8_t CoherentIntEbl;
7324 + enum GdmaDmaReqNum SrcReqNum;
7325 + enum GdmaDmaReqNum DstReqNum;
7326 + enum GdmaBusterMode SrcBurstMode;
7327 + enum GdmaBusterMode DstBurstMode;
7328 + enum GdmaBusterSize BurstSize;
7329 + void (*DoneIntCallback)(uint32_t);
7330 + void (*UnMaskIntCallback)(uint32_t);
7336 +int GdmaI2sTx(uint32_t Src, uint32_t Dst, uint8_t TxNo, uint16_t TransCount,
7337 + void (*DoneIntCallback)(uint32_t data),
7338 + void (*UnMaskIntCallback)(uint32_t data));
7340 +int GdmaI2sRx(uint32_t Src, uint32_t Dst, uint8_t RxNo, uint16_t TransCount,
7341 + void (*DoneIntCallback)(uint32_t data),
7342 + void (*UnMaskIntCallback)(uint32_t data));
7344 +int GdmaPcmRx(uint32_t Src, uint32_t Dst, uint8_t PcmNo, uint8_t RxNo, uint16_t TransCount,
7345 + void (*DoneIntCallback)(uint32_t data),
7346 + void (*UnMaskIntCallback)(uint32_t data));
7348 +int GdmaPcmTx(uint32_t Src, uint32_t Dst, uint8_t PcmNo, uint8_t TxNo, uint16_t TransCount,
7349 + void (*DoneIntCallback)(uint32_t data),
7350 + void (*UnMaskIntCallback)(uint32_t data));
7352 +int GdmaSpiTx(uint32_t Src, uint32_t Dst, uint16_t TransCount,
7353 + void (*DoneIntCallback)(uint32_t data),
7354 + void (*UnMaskIntCallback)(uint32_t data));
7356 +int GdmaSpiRx(uint32_t Src, uint32_t Dst, uint16_t TransCount,
7357 + void (*DoneIntCallback)(uint32_t data),
7358 + void (*UnMaskIntCallback)(uint32_t data));
7361 +int GdmaMem2Mem(uint32_t Src, uint32_t Dst, uint16_t TransCount,
7362 + void (*DoneIntCallback)(uint32_t data));
7364 +int GdmaMaskChannel(uint32_t ChNum);
7366 +int GdmaUnMaskChannel(uint32_t ChNum);
7368 +int GdmaReqQuickIns(uint32_t ChNum);
7372 --- a/sound/soc/soc-core.c
7373 +++ b/sound/soc/soc-core.c
7374 @@ -1851,7 +1851,8 @@
7375 /* Bodge while we unpick instantiation */
7376 card->dev = &pdev->dev;
7378 - return snd_soc_register_card(card);
7379 + snd_soc_register_card(card);
7383 static int soc_cleanup_card_resources(struct snd_soc_card *card)
7385 +++ b/sound/soc/mtk/i2s_debug.c
7387 +#include <linux/init.h>
7388 +#include <linux/version.h>
7389 +#include <linux/module.h>
7390 +#include <linux/kernel.h> /* printk() */
7391 +#include "i2s_ctrl.h"
7392 +#include <linux/delay.h>
7393 +#include <linux/jiffies.h>
7394 +#include <linux/random.h>
7395 +#include <linux/slab.h>
7396 +#include <asm/uaccess.h> /* copy_from/to_user */
7398 +#if defined(CONFIG_SND_RALINK_SOC)
7399 +#include <sound/soc/mtk/mtk_audio_device.h>
7402 +#if defined(CONFIG_I2S_WM8750)
7403 +#include "../codec/i2c_wm8750.h"
7405 +#if defined(CONFIG_I2S_WM8751)
7406 +#include "../codec/i2c_wm8751.h"
7408 +#if defined(CONFIG_I2S_WM8960)
7409 +#include "i2c_wm8960.h"
7413 +//#define INTERNAL_LOOPBACK_DEBUG
7415 +extern unsigned long i2s_codec_12p288Mhz[11];
7416 +extern unsigned long i2s_codec_12Mhz[11];
7417 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
7418 +extern unsigned long i2s_inclk_int_16bit[13];
7419 +extern unsigned long i2s_inclk_comp_16bit[13];
7420 +extern unsigned long i2s_inclk_int_24bit[13];
7421 +extern unsigned long i2s_inclk_comp_24bit[13];
7423 +extern unsigned long i2s_inclk_int[11];
7424 +extern unsigned long i2s_inclk_comp[11];
7426 +extern int i2s_pll_config_mt7621(unsigned long index);
7427 +extern int i2s_pll_config_mt7623(unsigned long index);
7429 +#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
7430 +extern void audiohw_loopback(int fsel);
7431 +extern void audiohw_bypass(void);
7432 +extern int audiohw_set_lineout_vol(int Aout, int vol_l, int vol_r);
7433 +extern int audiohw_set_linein_vol(int vol_l, int vol_r);
7436 +#if defined(CONFIG_I2S_WM8960)
7437 +extern void audiohw_codec_exlbk(void);
7440 +unsigned long txbuffer[512] = {
7441 + 0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
7442 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
7443 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
7444 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
7445 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
7446 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
7447 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
7448 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 1
7449 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
7450 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
7451 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
7452 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
7453 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
7454 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
7455 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
7456 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 2
7457 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
7458 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
7459 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
7460 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
7461 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
7462 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
7463 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
7464 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 3
7465 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
7466 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
7467 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
7468 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
7469 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
7470 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
7471 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
7472 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 4
7473 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
7474 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
7475 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
7476 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
7477 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
7478 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
7479 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
7480 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 5
7481 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
7482 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
7483 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
7484 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
7485 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
7486 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
7487 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
7488 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 6
7489 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
7490 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
7491 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
7492 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
7493 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
7494 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
7495 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
7496 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 7
7497 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
7498 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
7499 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
7500 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
7501 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
7502 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
7503 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
7504 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00 //round 8
7507 +int i2s_debug_cmd(unsigned int cmd, unsigned long arg)
7509 + unsigned long data, index;
7510 + unsigned long *pTable;
7515 + case I2S_DEBUG_CLKGEN:
7516 + MSG("I2S_DEBUG_CLKGEN\n");
7517 +#if defined(CONFIG_RALINK_RT3052)
7518 + *(volatile unsigned long*)(0xB0000060) = 0x00000016;
7519 + *(volatile unsigned long*)(0xB0000030) = 0x00009E00;
7520 + *(volatile unsigned long*)(0xB0000A00) = 0xC0000040;
7521 +#elif defined(CONFIG_RALINK_RT3350)
7522 + *(volatile unsigned long*)(0xB0000060) = 0x00000018;
7523 + *(volatile unsigned long*)(0xB000002C) = 0x00000100;
7524 + *(volatile unsigned long*)(0xB0000030) = 0x00009E00;
7525 + *(volatile unsigned long*)(0xB0000A00) = 0xC0000040;
7526 +#elif defined(CONFIG_RALINK_RT3883)
7527 + *(volatile unsigned long*)(0xB0000060) = 0x00000018;
7528 + *(volatile unsigned long*)(0xB000002C) = 0x00003000;
7529 + *(volatile unsigned long*)(0xB0000A00) = 0xC1104040;
7530 + *(volatile unsigned long*)(0xB0000A24) = 0x00000027;
7531 + *(volatile unsigned long*)(0xB0000A20) = 0x80000020;
7532 +#elif (defined(CONFIG_RALINK_RT3352)||defined(CONFIG_RALINK_RT5350)) || defined (CONFIG_RALINK_RT6855)
7533 + *(volatile unsigned long*)(0xB0000060) = 0x00000018;
7534 + *(volatile unsigned long*)(0xB000002C) = 0x00000300;
7535 + *(volatile unsigned long*)(0xB0000A00) = 0xC1104040;
7536 + *(volatile unsigned long*)(0xB0000A24) = 0x00000027;
7537 + *(volatile unsigned long*)(0xB0000A20) = 0x80000020;
7538 +#elif defined(CONFIG_RALINK_RT6855A)
7539 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x860) = 0x00008080;
7540 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x82C) = 0x00000300;
7541 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0xC1104040;
7542 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x24) = 0x00000027;
7543 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x20) = 0x80000020;
7545 +//#error "I2S debug mode not support this Chip"
7548 + case I2S_DEBUG_INLBK:
7549 + MSG("I2S_DEBUG_INLBK\n");
7550 +#if defined(CONFIG_RALINK_MT7621)
7592 + i2s_pll_config_mt7621(index);
7593 +#elif defined(CONFIG_ARCH_MT7623)
7594 + i2s_pll_config_mt7623(11);
7598 +#if defined(CONFIG_RALINK_RT3052)
7601 +#if defined(CONFIG_RALINK_RT6855A)
7602 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x834) |= 0x00020000;
7603 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x834) &= 0xFFFDFFFF;
7604 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x0) &= 0x7FFFFFFF; //Rest I2S to default vaule
7605 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x860) |= 0x00008080;
7606 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x82C) = 0x00000300;
7607 +#elif defined(CONFIG_RALINK_MT7621)
7608 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x34) |= 0x00020000;
7609 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x34) &= 0xFFFDFFFF;
7610 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x0) &= 0x7FFFFFFF; //Rest I2S to default vaule
7611 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x60) = 0x00000010; //GPIO purpose selection
7612 +#elif defined(CONFIG_RALINK_MT7628)
7613 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x34) |= 0x00020000;
7614 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x34) &= 0xFFFDFFFF;
7615 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x0) &= 0x7FFFFFFF; //Rest I2S to default vaule
7616 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x60) &= ~((0x3)<<6); //GPIO purpose selection /*FIXME*/
7617 +#elif defined(CONFIG_ARCH_MT7623)
7618 + *(volatile unsigned long*)(0xFB000034) |= 0x00020000;
7619 + *(volatile unsigned long*)(0xFB000034) &= 0xFFFDFFFF;
7620 + *(volatile unsigned long*)(ETHDMASYS_I2S_BASE+0x0) &= 0x7FFFFFFF; //Rest I2S to default vaule
7622 + *(volatile unsigned long*)(0xF0005840) &= ~((0x7)<<12);
7623 + *(volatile unsigned long*)(0xF0005840) |= ((0x6)<<12);
7624 + *(volatile unsigned long*)(0xF0005840) &= ~((0x7)<<9);
7625 + *(volatile unsigned long*)(0xF0005840) |= ((0x6)<<9);
7626 + *(volatile unsigned long*)(0xF0005040) |= ((0x1)<<10);
7627 + *(volatile unsigned long*)(0xF0005040) |= ((0x1)<<9);
7629 + *(volatile unsigned long*)(0xF00057F0) &= ~((0x7)<<12);
7630 + *(volatile unsigned long*)(0xF00057F0) |= ((0x6)<<12);
7631 + *(volatile unsigned long*)(0xF0005030) |= ((0x1)<<1);
7633 + *(volatile unsigned long*)(0xF0005840) &= ~((0x7)<<6);
7634 + *(volatile unsigned long*)(0xF0005840) |= ((0x6)<<6);
7635 + *(volatile unsigned long*)(0xF0005040) &= ~((0x1)<<8);
7637 + *(volatile unsigned long*)(0xF00058F0) &= ~((0x7)<<3);
7638 + *(volatile unsigned long*)(0xF00058F0) |= ((0x6)<<3);
7639 + *(volatile unsigned long*)(0xF0005070) |= ((0x1)<<14);
7643 + *(volatile unsigned long*)(0xB0000034) |= 0x00020000;
7644 + *(volatile unsigned long*)(0xB0000034) &= 0xFFFDFFFF;
7645 + *(volatile unsigned long*)(0xB0000A00) &= 0x7FFFFFFF; //Rest I2S to default vaule
7646 + *(volatile unsigned long*)(0xB0000060) = 0x00000018;
7648 +#if defined(CONFIG_RALINK_RT3883)
7649 + *(volatile unsigned long*)(0xB000002C) = 0x00003000;
7650 +#elif defined(CONFIG_ARCH_MT7623)
7653 + *(volatile unsigned long*)(0xB000002C) = 0x00000300;
7656 +#if defined(CONFIG_RALINK_MT7621)
7657 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x18) = 0x80000000;
7658 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0xc1104040;
7660 + pTable = i2s_inclk_int;
7661 + data = pTable[index];
7662 + //*(volatile unsigned long*)(RALINK_I2S_BASE+0x24) = data;
7663 + i2s_outw(RALINK_I2S_BASE+0x24, data);
7665 + pTable = i2s_inclk_comp;
7666 + data = pTable[index];
7667 + //*(volatile unsigned long*)(RALINK_I2S_BASE+0x20) = data;
7668 + i2s_outw(RALINK_I2S_BASE+0x20, (data|0x80000000));
7669 +#elif defined(CONFIG_RALINK_MT7628)
7670 + index =11; /* SR: 192k */
7671 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x18) = 0x80000000;
7672 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0xc1104040;
7674 + pTable = i2s_inclk_int_16bit;
7675 + //pTable = i2s_inclk_int_24bit;
7676 + data = pTable[index];
7677 + //*(volatile unsigned long*)(RALINK_I2S_BASE+0x24) = data;
7678 + i2s_outw(RALINK_I2S_BASE+0x24, data);
7680 + pTable = i2s_inclk_comp_16bit;
7681 + //pTable = i2s_inclk_comp_24bit;
7682 + data = pTable[index];
7683 + //*(volatile unsigned long*)(RALINK_I2S_BASE+0x20) = data;
7684 + i2s_outw(RALINK_I2S_BASE+0x20, (data|0x80000000));
7686 +#elif defined(CONFIG_ARCH_MT7623)
7688 + *(volatile unsigned long*)(I2S_I2SCFG1) = 0x80000000;
7689 + *(volatile unsigned long*)(I2S_I2SCFG) = 0xE1104040;
7690 + *(volatile unsigned long*)(ETHDMASYS_SYSCTL_BASE+0x30) |= 0x00020000;
7691 + *(volatile unsigned long*)(ETHDMASYS_SYSCTL_BASE+0x2c) |= 0x00000080;
7693 + pTable = i2s_inclk_int_16bit;
7694 + //pTable = i2s_inclk_int_24bit;
7695 + data = pTable[index];
7696 + i2s_outw(I2S_DIVINT_CFG, data);
7698 + pTable = i2s_inclk_comp_16bit;
7699 + //pTable = i2s_inclk_comp_24bit;
7700 + data = pTable[index];
7701 + i2s_outw(I2S_DIVCOMP_CFG, (data|0x80000000));
7704 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x18) = 0x80000000;
7705 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0xC1104040;
7706 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x24) = 0x00000006;
7707 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x20) = 0x80000105;
7713 + unsigned long param[4];
7714 + unsigned long data;
7715 + //unsigned long data_tmp;
7716 + unsigned long ff_status;
7717 + //unsigned long* txbuffer;
7722 +#if defined (INTERNAL_LOOPBACK_DEBUG)
7725 + memset(param, 0, 4*sizeof(unsigned long) );
7726 + copy_from_user(param, (unsigned long*)arg, sizeof(long)*2);
7728 + txbuffer = (unsigned long*)kcalloc(param[0], sizeof(unsigned long), GFP_KERNEL);
7729 + if(txbuffer == NULL)
7733 + //ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C);
7734 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
7735 + printk("ff status=[0x%08X]\n",(u32)ff_status);
7738 + for(i = 0; i < param[0]; i++)
7742 + txbuffer[i] = 0x555A555A;
7743 + printk("%d: 0x%8lx\n", i, txbuffer[i]);
7747 + #if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,14)
7748 + srandom32(jiffies);
7749 + txbuffer[i] = random32()%(0x555A555A)+1;
7750 + //printk("%d: 0x%8x\n", i, txbuffer[i]);
7752 + //TODO:do we need to implement random32()
7753 + txbuffer[i] = 0x01010101;
7759 + for( i = 0 ; i < param[0] ; i ++ )
7761 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
7762 + #if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
7763 + if((ff_status&0xFF) > 0)
7765 + if((ff_status&0x0F) > 0)
7768 + *(volatile unsigned long*)(I2S_TX_FIFO_WREG) = txbuffer[i];
7774 + printk("[%d]NO TX FREE FIFO ST=[0x%08X]\n", i, (u32)ff_status);
7781 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
7782 + #if defined(CONFIG_RALINK_MT7628)
7783 + if(((ff_status>>8)&0xFF) > 0)
7785 + if(((ff_status>>4)&0x0F) > 0)
7788 + data = *(volatile unsigned long*)(I2S_RX_FIFO_RREG);
7789 + //data_tmp = *(volatile unsigned long*)(I2S_RX_FIFO_RREG);
7790 + //MSG("[0x%08X] vs [0x%08X]\n", (u32)data, (u32)data_tmp);
7794 + printk("*[%d]NO RX FREE FIFO ST=[0x%08X]\n", i, (u32)ff_status);
7798 + if (data == txbuffer[0])
7803 + if (enable_cnt==1)
7805 + if(data!= txbuffer[i-k])
7807 + MSG("[%d][0x%08X] vs [0x%08X]\n", (i-k), (u32)data, (u32)txbuffer[i-k]);
7811 + //MSG("**[%d][0x%08X] vs [0x%08X]\n" ,(i-k), (u32)data , (u32)txbuffer[i-k]);
7821 + for (j=0; j<k; j++)
7824 + //ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C);
7825 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
7826 + #if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
7827 + if(((ff_status>>8)&0xFF) > 0)
7829 + if(((ff_status>>4)&0x0F) > 0)
7832 + //data = *(volatile unsigned long*)(RALINK_I2S_BASE+0x14);
7833 + data = *(volatile unsigned long*)(I2S_RX_FIFO_RREG);
7837 + printk("*NO RX FREE FIFO ST=[0x%08X]\n", (u32)ff_status);
7841 + if(data!= txbuffer[temp+j])
7843 + MSG("[%d][0x%08X] vs [0x%08X]\n", (temp+j), (u32)data, (u32)txbuffer[temp+j]);
7847 + //MSG("&&[%d][0x%08X] vs [0x%08X]\n" ,(temp+j), (u32)data , (u32)txbuffer[temp+j]);
7851 + if ((temp+j)==128)
7853 + //ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C);
7854 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
7855 + //printk("[%d]FIFO ST=[0x%08X]\n", (temp+j), (u32)ff_status);
7860 +#if defined (INTERNAL_LOOPBACK_DEBUG)
7861 + for( i = 0 ; i < param[0] ; i ++ )
7863 + //ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C);
7864 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
7865 + #if defined(CONFIG_RALINK_MT7628)|| defined(CONFIG_ARCH_MT7623)
7866 + if((ff_status&0xFF) > 0)
7868 + if((ff_status&0x0F) > 0)
7871 + //*(volatile unsigned long*)(RALINK_I2S_BASE+0x10) = txbuffer[i];
7872 + *(volatile unsigned long*)(I2S_TX_FIFO_WREG) = txbuffer[i];
7878 + printk("[%d]NO TX FREE FIFO ST=[0x%08X]\n", i, (u32)ff_status);
7885 + //ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C);
7886 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
7887 + #if defined(CONFIG_RALINK_MT7628)|| defined(CONFIG_ARCH_MT7623)
7888 + if(((ff_status>>8)&0xFF) > 0)
7890 + if(((ff_status>>4)&0x0F) > 0)
7893 + //data = *(volatile unsigned long*)(RALINK_I2S_BASE+0x14);
7894 + data = *(volatile unsigned long*)(I2S_RX_FIFO_RREG);
7898 + printk("*[%d]NO RX FREE FIFO ST=[0x%08X]\n", i, (u32)ff_status);
7903 + if(data!= txbuffer[i])
7905 + MSG("[%d][0x%08X] vs [0x%08X]\n", (i), (u32)data, (u32)txbuffer[i]);
7909 + MSG("**[%d][0x%08X] vs [0x%08X]\n" ,(i), (u32)data , (u32)txbuffer[i]);
7917 + printk("Pattern match done count2=%d.\n", count2);
7919 + printk("Pattern match done count=%d.\n", count);
7922 +#if defined(CONFIG_ARCH_MT7623)
7923 + *(volatile unsigned long*)(0xFB000034) |= 0x00020000;
7924 + *(volatile unsigned long*)(0xFB000034) &= 0xFFFDFFFF;
7925 + *(volatile unsigned long*)(ETHDMASYS_I2S_BASE+0x0) &= 0x7FFFFFFF; //Rest I2S to default vaule
7928 +#if !defined(CONFIG_RALINK_RT3052)
7931 + case I2S_DEBUG_EXLBK:
7932 + MSG("I2S_DEBUG_EXLBK\n");
7933 +#if !defined(CONFIG_ARCH_MT7623)
7972 +#if defined(CONFIG_RALINK_RT3052)
7975 +#if defined(CONFIG_RALINK_RT6855A)
7976 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x860) = 0x00008080;
7977 + //*(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x82C) = 0x00000300;
7979 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x60) = 0x00000018;
7980 +#if defined(CONFIG_RALINK_RT3883)
7981 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x2C) = 0x00003000;
7983 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x2C) = 0x00000300;
7987 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x18) = 0x40000000;
7988 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0x81104040;
7989 +#if defined(CONFIG_RALINK_MT7628)
7990 + pTable = i2s_inclk_int_16bit;
7992 + pTable = i2s_inclk_int;
7994 + data = (volatile unsigned long)(pTable[index]);
7995 + i2s_outw(I2S_DIVINT_CFG, data);
7996 +#if defined(CONFIG_RALINK_MT7628)
7997 + pTable = i2s_inclk_comp_16bit;
7999 + pTable = i2s_inclk_comp;
8001 + data = (volatile unsigned long)(pTable[index]);
8002 + data |= REGBIT(1, I2S_CLKDIV_EN);
8003 + i2s_outw(I2S_DIVCOMP_CFG, data);
8005 + #if defined(CONFIG_I2S_MCLK_12MHZ)
8006 + pTable = i2s_codec_12Mhz;
8007 + #if defined(CONFIG_I2S_WM8960)
8008 + data = pTable[index];
8010 + data = pTable[index]|0x01;
8013 + pTable = i2s_codec_12p288Mhz;
8014 + data = pTable[index];
8017 + #if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
8018 + audiohw_preinit();
8022 + #if defined (CONFIG_I2S_WM8960)
8023 + audiohw_postinit(1, 1, 1, 1, 0); // for codec apll enable, 16 bit word length
8024 + #elif defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
8025 + audiohw_postinit(1, 1, 1, 0); // for 16 bit word length
8029 + #if defined (CONFIG_I2S_WM8960)
8030 + audiohw_set_frequency(data, 1); // for codec apll enable
8031 + #elif defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
8032 + audiohw_set_frequency(data|0x1);
8036 + #if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
8037 + audiohw_set_lineout_vol(1, 100, 100);
8038 + audiohw_set_linein_vol(100, 100);
8042 + #if defined(CONFIG_I2S_TXRX)
8043 + //audiohw_loopback(data);
8045 + #if !defined(CONFIG_RALINK_RT3052)
8049 + case I2S_DEBUG_CODECBYPASS:
8050 + #if defined(CONFIG_I2S_TXRX)
8051 + #if defined(CONFIG_RALINK_MT7628)
8052 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
8053 + //data &= ~(0x3<<4);
8054 + data &= ~(0x3<<6);
8055 + data &= ~(0x3<<16);
8056 + data &= ~(0x1<<14);
8057 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
8059 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
8060 + data &= ~(0x07<<9);
8061 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
8064 + #if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
8065 + audiohw_bypass(); /* did not work */
8069 + case I2S_DEBUG_FMT:
8071 + case I2S_DEBUG_RESET:
8073 +#if defined(CONFIG_I2S_WM8960)
8074 + case I2S_DEBUG_CODEC_EXLBK:
8075 + audiohw_codec_exlbk();
8079 + MSG("Not support this debug cmd [%d]\n", cmd);
8085 --- a/sound/soc/codecs/wm8960.c
8086 +++ b/sound/soc/codecs/wm8960.c
8088 #include <sound/wm8960.h>
8091 +#include "../mtk/i2c_wm8960.h"
8094 #define WM8960_VMID_MASK 0x180
8096 * using 2 wire for device control, so we cache them instead.
8098 static const struct reg_default wm8960_reg_defaults[] = {
8121 @@ -127,8 +128,15 @@
8126 +#define wm8960_reset(c) do{ \
8128 + snd_soc_write(c, WM8960_RESET, 0);\
8129 + for(i = 0; i < 1000*HZ; i++);\
8132 #define wm8960_reset(c) snd_soc_write(c, WM8960_RESET, 0)
8135 /* enumerated controls */
8136 static const char *wm8960_polarity[] = {"No Inversion", "Left Inverted",
8137 "Right Inverted", "Stereo Inversion"};
8139 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
8140 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
8142 - ucontrol->value.integer.value[0] = wm8960->deemph;
8144 + //ucontrol->value.integer.value[0] = wm8960->deemph;
8145 + return wm8960->deemph;
8148 static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
8149 @@ -200,6 +208,70 @@
8150 return wm8960_set_deemph(codec);
8153 +static int wm8960_preinit(struct snd_soc_codec *codec)
8155 + //printk("****** %s ******\n", __func__);
8156 + snd_soc_write(codec, WM8960_RESET, 0);
8162 +static int wm8960_postinit(struct snd_soc_codec *codec)
8165 + //printk("****** %s ******\n", __func__);
8167 + data = snd_soc_read(codec, WM8960_POWER1);
8168 + snd_soc_write(codec, WM8960_POWER1, data|WM8960_PWR1_ADCL|WM8960_PWR1_ADCR|WM8960_PWR1_AINL |WM8960_PWR1_AINR|WM8960_PWR1_MICB);//0x19
8169 + data = snd_soc_read(codec, WM8960_ADDCTL1);
8170 + snd_soc_write(codec, WM8960_ADDCTL1, data|ADDITIONAL1_DATSEL(0x01));//0x17
8171 + snd_soc_write(codec, WM8960_LADC, LEFTGAIN_LDVU|LEFTGAIN_LDACVOL(0xc3));//0x15
8172 + snd_soc_write(codec, WM8960_RADC, LEFTGAIN_LDVU|LEFTGAIN_LDACVOL(0xc3));//0x16
8173 + snd_soc_write(codec, WM8960_LINPATH, 0x148);//0x20
8174 + snd_soc_write(codec, WM8960_RINPATH, 0x148);//0x21
8175 + snd_soc_write(codec, WM8960_POWER3, WM8960_PWR3_LMIC|WM8960_PWR3_RMIC);//0x2f
8178 + data = snd_soc_read(codec, WM8960_POWER2);
8179 + snd_soc_write(codec, WM8960_POWER2, data|WM8960_PWR2_DACL|WM8960_PWR2_DACR|WM8960_PWR2_LOUT1|WM8960_PWR2_ROUT1|WM8960_PWR2_SPKL|WM8960_PWR2_SPKR);//0x1a
8181 + snd_soc_write(codec, WM8960_IFACE2, 0x40);
8182 + snd_soc_write(codec, WM8960_LDAC, LEFTGAIN_LDVU|LEFTGAIN_LDACVOL(0xff));//0x0a
8183 + snd_soc_write(codec, WM8960_RDAC, RIGHTGAIN_RDVU|RIGHTGAIN_RDACVOL(0xff));//0x0b
8184 + snd_soc_write(codec, WM8960_LOUTMIX, 0x100);//0x22
8185 + snd_soc_write(codec, WM8960_ROUTMIX, 0x100);//0x25
8187 + data = snd_soc_read(codec, WM8960_POWER3);
8188 + snd_soc_write(codec, WM8960_POWER3, data|WM8960_PWR3_ROMIX|WM8960_PWR3_LOMIX);//0x2f
8190 + snd_soc_write(codec, WM8960_CLASSD1, 0xf7);//0x31
8191 + snd_soc_write(codec, WM8960_CLASSD3, 0xad);//0x33
8192 + snd_soc_write(codec, WM8960_DACCTL1, 0x000);//0x05
8194 + data = snd_soc_read(codec, WM8960_POWER1);
8195 + snd_soc_write(codec, WM8960_POWER1, data|0x1c0);//0x19
8198 + snd_soc_write(codec, WM8960_LOUT1, LOUT1_LO1VU|LOUT1_LO1ZC|LOUT1_LOUT1VOL(115));//0x02
8199 + snd_soc_write(codec, WM8960_ROUT1, ROUT1_RO1VU|ROUT1_RO1ZC|ROUT1_ROUT1VOL(115));//0x03
8201 + snd_soc_write(codec, WM8960_LINVOL, LINV_IPVU|LINV_LINVOL(110)); //LINV(0x00)=>0x12b
8202 + snd_soc_write(codec, WM8960_RINVOL, RINV_IPVU|RINV_RINVOL(110)); //LINV(0x01)=>0x12b
8207 +static int wm8960_close(struct snd_soc_codec *codec)
8209 + snd_soc_write(codec, WM8960_DACCTL1,0x8); //0x05->0x08
8210 + snd_soc_write(codec, WM8960_POWER1, 0x000); //0x19->0x000
8212 + snd_soc_write(codec, WM8960_POWER2, 0x000); //0x1a->0x000
8217 static const DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 50, 0);
8218 static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1);
8219 static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0);
8223 snd_soc_write(codec, WM8960_IFACE1, iface);
8224 + wm8960_postinit(codec);
8228 @@ -623,11 +696,16 @@
8231 case SND_SOC_BIAS_PREPARE:
8233 /* Set VMID to 2x50k */
8234 snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x80);
8238 case SND_SOC_BIAS_STANDBY:
8240 + wm8960_preinit(codec);
8242 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
8243 regcache_sync(wm8960->regmap);
8245 @@ -650,9 +728,13 @@
8247 /* Set VMID to 2x250k */
8248 snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x100);
8252 case SND_SOC_BIAS_OFF:
8254 + wm8960_close(codec);
8256 /* Enable anti-pop features */
8257 snd_soc_write(codec, WM8960_APOP1,
8258 WM8960_POBCTRL | WM8960_SOFT_ST |
8260 /* Disable VMID and VREF, let them discharge */
8261 snd_soc_write(codec, WM8960_POWER1, 0);
8267 @@ -853,10 +936,15 @@
8273 snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 16) & 0xff);
8274 snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 8) & 0xff);
8275 snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0xff);
8277 + snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 16) & 0xff);
8278 + snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 8) & 0xff);
8279 + snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0xff);
8282 snd_soc_write(codec, WM8960_PLL1, reg);
8284 @@ -888,7 +976,11 @@
8285 snd_soc_write(codec, WM8960_PLL1, reg | div);
8287 case WM8960_DCLKDIV:
8289 reg = snd_soc_read(codec, WM8960_CLOCK2) & 0x03f;
8291 + reg = snd_soc_read(codec, WM8960_CLOCK2) & 0x03f;
8293 snd_soc_write(codec, WM8960_CLOCK2, reg | div);
8295 case WM8960_TOCLKSEL:
8296 @@ -962,7 +1054,7 @@
8298 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
8299 struct wm8960_data *pdata = dev_get_platdata(codec->dev);
8303 wm8960->set_bias_level = wm8960_set_bias_level_out3;
8305 @@ -973,11 +1065,7 @@
8306 wm8960->set_bias_level = wm8960_set_bias_level_capless;
8309 - ret = wm8960_reset(codec);
8311 - dev_err(codec->dev, "Failed to issue reset\n");
8314 + wm8960_reset(codec);
8316 wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
8318 --- a/sound/soc/codecs/wm8960.h
8319 +++ b/sound/soc/codecs/wm8960.h
8320 @@ -110,4 +110,68 @@
8321 #define WM8960_OPCLK_DIV_5_5 (4 << 0)
8322 #define WM8960_OPCLK_DIV_6 (5 << 0)
8325 + * WM8960 Power management
8327 +#define WM8960_PWR1_VMIDSEL_DISABLED (0 << 7)
8328 +#define WM8960_PWR1_VMIDSEL_50K (1 << 7)
8329 +#define WM8960_PWR1_VMIDSEL_250K (2 << 7)
8330 +#define WM8960_PWR1_VMIDSEL_5K (3 << 7)
8331 +#define WM8960_PWR1_VREF (1 << 6)
8332 +#define WM8960_PWR1_AINL (1 << 5)
8333 +#define WM8960_PWR1_AINR (1 << 4)
8334 +#define WM8960_PWR1_ADCL (1 << 3)
8335 +#define WM8960_PWR1_ADCR (1 << 2)
8336 +#define WM8960_PWR1_MICB (1 << 1)
8337 +#define WM8960_PWR1_DIGENB (1 << 0)
8339 +#define WM8960_PWR2_DACL (1 << 8)
8340 +#define WM8960_PWR2_DACR (1 << 7)
8341 +//#define WM8960_PWR2_LOUT1 (1 << 6)
8342 +//#define WM8960_PWR2_ROUT1 (1 << 5)
8343 +#define WM8960_PWR2_SPKL (1 << 4)
8344 +#define WM8960_PWR2_SPKR (1 << 3)
8345 +//#define WM8960_PWR2_OUT3 (1 << 1)
8346 +#define WM8960_PWR2_PLL_EN (1 << 0)
8348 +#define WM8960_PWR3_LMIC (1 << 5)
8349 +#define WM8960_PWR3_RMIC (1 << 4)
8350 +#define WM8960_PWR3_LOMIX (1 << 3)
8351 +#define WM8960_PWR3_ROMIX (1 << 2)
8353 +#define LEFTGAIN 0x0a
8354 +#define LEFTGAIN_LDVU (1 << 8)
8355 +#define LEFTGAIN_LDACVOL(x) ((x) & 0xff)
8357 +#define RIGHTGAIN 0x0b
8358 +#define RIGHTGAIN_RDVU (1 << 8)
8359 +#define RIGHTGAIN_RDACVOL(x) ((x) & 0xff)
8361 +#define ADDITIONAL1_DATSEL(x) (((x) & 0x3) << 2)
8363 +#define AINTFCE1_WL_32 (3 << 2)
8364 +#define AINTFCE1_WL_24 (2 << 2)
8365 +#define AINTFCE1_WL_20 (1 << 2)
8366 +#define AINTFCE1_WL_16 (0 << 2)
8367 +#define AINTFCE1_FORMAT_I2S (2 << 0)
8369 +#define LOUT1_LO1VU (1 << 8)
8370 +#define LOUT1_LO1ZC (1 << 7)
8371 +#define LOUT1_LOUT1VOL(x) ((x) & 0x7f)
8373 +#define ROUT1_RO1VU (1 << 8)
8374 +#define ROUT1_RO1ZC (1 << 7)
8375 +#define ROUT1_ROUT1VOL(x) ((x) & 0x7f)
8377 +#define LINV_IPVU (1 << 8) /* FIXME */
8379 +#define LINV_LINMUTE (1 << 7)
8380 +#define LINV_LIZC (1 << 6)
8381 +#define LINV_LINVOL(x) ((x) & 0x3f)
8383 +#define RINV_IPVU (1 << 8) /* FIXME */
8384 +#define RINV_RINMUTE (1 << 7)
8385 +#define RINV_RIZC (1 << 6)
8386 +#define RINV_RINVOL(x) ((x) & 0x3f)