| 
					
				 | 
			
			
				@@ -0,0 +1,8411 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- a/sound/soc/Kconfig 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/Kconfig 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -56,6 +56,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ source "sound/soc/tegra/Kconfig" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ source "sound/soc/txx9/Kconfig" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ source "sound/soc/ux500/Kconfig" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++source "sound/soc/mtk/Kconfig" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ # Supported codecs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ source "sound/soc/codecs/Kconfig" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- a/sound/soc/Makefile 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/Makefile 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -33,3 +33,4 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ obj-$(CONFIG_SND_SOC)	+= tegra/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ obj-$(CONFIG_SND_SOC)	+= txx9/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ obj-$(CONFIG_SND_SOC)	+= ux500/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++obj-$(CONFIG_SND_SOC)   += mtk/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- a/sound/soc/codecs/Kconfig 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/codecs/Kconfig 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -725,7 +725,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	tristate 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ config SND_SOC_WM8960 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	tristate 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	tristate "WM8960" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ config SND_SOC_WM8961 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	tristate 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- /dev/null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/mtk/Kconfig 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -0,0 +1,35 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++config SND_MT76XX_SOC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	tristate "SoC Audio for MT76XX APSoC Machine" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	depends on SND_SOC && (SOC_MT7620 || SOC_MT7621) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	help 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	  Say Y or M if you want to add support for codecs attached to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	  the MTK I2S interface. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++choice 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	prompt "Selected SoC type" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	depends on SND_MT76XX_SOC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	default SND_MT76XX_SOC_MT7620 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++config SND_MT76XX_SOC_MT7620 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	bool "MT7620" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	depends on SOC_MT7620 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++config SND_MT76XX_SOC_MT7628 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	bool "MT7628" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	depends on SOC_MT7620 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++config SND_MT76XX_SOC_MT7621 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	bool "MT7621" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	depends on SOC_MT7621 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++endchoice 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++config SND_MT76XX_PCM 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	tristate "MTK SoC Audio PCM Platform" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	depends on SND_MT76XX_SOC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++config SND_MT76XX_I2S 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	tristate "MTK SoC I2S Support" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	depends on SND_MT76XX_SOC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- /dev/null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/mtk/Makefile 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -0,0 +1,39 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++KBUILD_CFLAGS += -I$(srctree) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ifeq ($(CONFIG_SND_MT76XX_SOC_MT7620),y) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++KBUILD_CFLAGS += -DCONFIG_MT7620 -DCONFIG_RALINK_MT7620 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ifeq ($(CONFIG_SND_MT76XX_SOC_MT7628),y) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++KBUILD_CFLAGS += -DCONFIG_MT7628 -DCONFIG_RALINK_MT7628 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ifeq ($(CONFIG_SOC_MT7620),y) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++KBUILD_CFLAGS += -DRALINK_SYSCTL_BASE=0xB0000000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++KBUILD_CFLAGS += -DRALINK_INTCL_BASE=0xB0000200 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++KBUILD_CFLAGS += -DRALINK_PIO_BASE=0xB0000600 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++KBUILD_CFLAGS += -DRALINK_I2S_BASE=0xB0000A00 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++KBUILD_CFLAGS += -DRALINK_GDMA_BASE=0xB0002800 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++KBUILD_CFLAGS += -DCONFIG_GDMA_EVERYBODY 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++KBUILD_CFLAGS += -DCONFIG_SND_MT76XX_SOC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++KBUILD_CFLAGS += -DCONFIG_I2S_WM8960 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++KBUILD_CFLAGS += -DCONFIG_I2S_MCLK_12P288MHZ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++KBUILD_CFLAGS += -DCONFIG_GDMA_EVERYBODY 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++KBUILD_CFLAGS += -DSURFBOARDINT_DMA=15 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++KBUILD_CFLAGS += -DRALINK_INTCTL_DMA=128 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++KBUILD_CFLAGS += -DCONFIG_SND_SOC_WM8960 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++# MTK APSoC Platform Support 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++snd-soc-mt76xx-i2s-ctl-objs := i2s_ctrl.o i2s_debug.o #i2c_wm8960.o 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++snd-soc-mt76xx-pcm-objs := mt76xx_pcm.o 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++snd-soc-mt76xx-i2s-objs := mt76xx_i2s.o 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++obj-$(CONFIG_SND_MT76XX_PCM) += snd-soc-mt76xx-pcm.o 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++obj-$(CONFIG_SND_MT76XX_I2S) += snd-soc-mt76xx-i2s-ctl.o snd-soc-mt76xx-i2s.o 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++# MTK APSoC Machine Support 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++snd-soc-mt76xx-machine-objs := mt76xx_machine.o 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++obj-$(CONFIG_SND_MT76XX_SOC) += i2c_wm8960.o ralink_gdma.o snd-soc-mt76xx-machine.o 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- /dev/null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/mtk/i2c_wm8960.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -0,0 +1,492 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/kernel.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/version.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/init.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/module.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/slab.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/i2c.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/delay.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/interrupt.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/fs.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/fcntl.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/cdev.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <mt_i2c.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <mach/mt_gpio.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "i2c_wm8960.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "i2s_ctrl.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define BUF_SIZE		20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#undef MSG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MSG printk 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/*FIXME*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//static struct i2c_board_info __initdata i2c_devs1 = { I2C_BOARD_INFO("codec_wm8960", (0X34>>1))}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static struct i2c_board_info __initdata i2c_devs1 = { I2C_BOARD_INFO("codec_wm8960", (0X34))}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long wm_reg_data[56]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++struct wm8960_data *wmio; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++struct wm8960_data { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct i2c_client	*client; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct device	    *dev; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	const char 			*name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2c_WM8960_write(u32 reg, u32 data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        struct i2c_msg msg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u8 buf[2]={0}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned int ext_flag = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ext_flag &= 0x7FFFFFFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ext_flag |= I2C_A_FILTER_MSG; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ext_flag |= I2C_POLLING_FLAG; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	wm_reg_data[reg] = data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	buf[0]= (reg<<1)|(0x01&(data>>8)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	buf[1]= (data&0xFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/*FIXME*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//msg.addr = wmio->client->addr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	msg.addr = wmio->client->addr>>1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        msg.addr = wmio->client->addr>>1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++     	msg.flags = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        msg.buf = (char *)buf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	msg.len = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	msg.timing = 80; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	msg.ext_flag = ext_flag & 0x7FFFFFFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        ret = i2c_transfer(wmio->client->adapter, &msg, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("[WM8960(%02X)=0x%08X]\n",(unsigned int)reg,(unsigned int)data);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        if (ret <= 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                printk("%s: i2c write error!\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++// Reset and power up the WM8960  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_preinit(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	memset(wm_reg_data, 0 , sizeof(unsigned long)*55); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(RESET, RESET_RESET);    // Reset (0x0F) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 	mdelay(50);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	wm_reg_data[RESET] = 0xFFFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	mdelay(50);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_set_apll(int srate) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if((srate==8000) || (srate==12000) || (srate==16000) || (srate==24000) || (srate==32000) || (srate==48000)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		// Provide 12.288MHz SYSCLK  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = wm_reg_data[PLL1];	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	i2c_WM8960_write(PLL1, data | PLL1_OPCLKDIV_1 | PLL1_SDM_FRACTIONAL | PLL1_PLLPRESCALE_1 | PLL1_PLLN(0x8));   // PLL1 (0x34) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(PLL2, PLL2_PLLK_23_16(0x31));  // PLL2 (0x35) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	i2c_WM8960_write(PLL3, PLL3_PLLK_15_8(0x26));  // PLL3 (0x36) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(PLL4, PLL4_PLLK_7_0(0xe9));  // PLL4 (0x37) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else if ((srate==11025) || (srate==22050) || (srate==44100)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//Provide 11.2896MHz SYSCLK  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = wm_reg_data[PLL1];	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	i2c_WM8960_write(PLL1, data | PLL1_OPCLKDIV_1 | PLL1_SDM_FRACTIONAL | PLL1_PLLPRESCALE_1 | PLL1_PLLN(0x7));   //PLL1 (0x34) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(PLL2, PLL2_PLLK_23_16(0x86));  //PLL2 (0x35)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	i2c_WM8960_write(PLL3, PLL3_PLLK_15_8(0xc2));  //PLL3 (0x36) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(PLL4, PLL4_PLLK_7_0(0x26));  //PLL4 (0x37) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		printk("Not support this srate\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	mdelay(3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_set_frequency(int fsel, int pll_en) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        MSG("audiohw_set_frequency_=0x%08X\n",fsel); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (pll_en) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		printk("PLL enable\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(CLOCKING1, (fsel<<3) | CLOCKING1_SYSCLKDIV_2 | CLOCKING1_CLKSEL_PLL);  //CLOCKING (0x04)=>0x05  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		printk("PLL disable\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(CLOCKING1, (fsel<<3));//| CLOCKING1_SYSCLKDIV_2);  //CLOCKING (0x04)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//FIXME  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int audiohw_set_lineout_vol(int Aout, int vol_l, int vol_r) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("audiohw_set_lineout_vol_\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	switch(Aout) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 1: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//i2c_WM8960_write(LOUT1, LOUT1_LO1VU|LOUT1_LO1ZC|LOUT1_LOUT1VOL(0x7f)); //LOUT1(0x02)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//i2c_WM8960_write(ROUT1, ROUT1_RO1VU|ROUT1_RO1ZC|ROUT1_ROUT1VOL(0x7f)); //ROUT1(0x03)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(LOUT1, LOUT1_LO1VU|LOUT1_LO1ZC|LOUT1_LOUT1VOL(vol_l)); //LOUT1(0x02)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(ROUT1, ROUT1_RO1VU|ROUT1_RO1ZC|ROUT1_ROUT1VOL(vol_r)); //ROUT1(0x03)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 2: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    		i2c_WM8960_write(LSPK, LSPK_SPKLVU|LSPK_SPKLZC| LSPK_SPKLVOL(vol_l)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    		i2c_WM8960_write(RSPK, RSPK_SPKRVU|RSPK_SPKRZC| RSPK_SPKRVOL(vol_r)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	}	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//FIXME  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int audiohw_set_linein_vol(int vol_l, int vol_r) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("audiohw_set_linein_vol_\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    i2c_WM8960_write(LINV, LINV_IPVU|LINV_LINVOL(vol_l)); //LINV(0x00)=>0x12b  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(RINV, RINV_IPVU|RINV_RINVOL(vol_r)); //LINV(0x01)=>0x12b  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//Set signal path 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int audiohw_postinit(int bSlave, int AIn, int AOut, int pll_en, int wordLen24b) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(wm_reg_data[RESET]!=0xFFFF) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(bSlave) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("WM8960 slave.....\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(wordLen24b) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			printk("24 bit word length\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2c_WM8960_write(AINTFCE1, AINTFCE1_WL_24 | AINTFCE1_FORMAT_I2S); //AINTFCE1(0x07)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			printk("16 bit word length\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2c_WM8960_write(AINTFCE1, AINTFCE1_WL_16 | AINTFCE1_FORMAT_I2S); //AINTFCE1(0x07)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	}	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("WM8960 master.....\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(CLOCKING2, 0x1c4);//CLOCKING2_BCLKDIV(0x1c4));  //CLOCKING2(0x08)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(wordLen24b) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			printk("24 bit word length\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2c_WM8960_write(AINTFCE1, AINTFCE1_MS | AINTFCE1_WL_24 | AINTFCE1_FORMAT_I2S); //AINTFCE1(0x07)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			printk("16 bit word length\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2c_WM8960_write(AINTFCE1, AINTFCE1_MS | AINTFCE1_WL_16 | AINTFCE1_FORMAT_I2S); //AINTFCE1(0x07)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		mdelay(5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//From app notes: allow Vref to stabilize to reduce clicks  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	for(i = 0; i < 1000*HZ; i++); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(AIn > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++       		data = wm_reg_data[PWRMGMT1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++   		i2c_WM8960_write(PWRMGMT1, data|PWRMGMT1_ADCL|PWRMGMT1_ADCR|PWRMGMT1_AINL |PWRMGMT1_AINR);//|PWRMGMT1_MICB);//PWRMGMT1(0x19)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = wm_reg_data[ADDITIONAL1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(ADDITIONAL1, data|ADDITIONAL1_DATSEL(0x01)); //ADDITIONAL1(0x17)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(LADCVOL, LADCVOL_LAVU_EN|LADCVOL_LADCVOL(0xc3)); //LADCVOL(0x15)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(RADCVOL, RADCVOL_RAVU_EN|RADCVOL_RADCVOL(0xc3)); //RADCVOL(0x16)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(ADCLPATH, ADCLPATH_LMN1|ADCLPATH_LMIC2B);//|ADCLPATH_LMICBOOST_13DB); //ADCLPATH(0x20)=>(0x108) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(ADCRPATH, ADCRPATH_RMN1|ADCRPATH_RMIC2B);//|ADCRPATH_RMICBOOST_13DB); //ADCRPATH(0x21)=>(0x108) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(PWRMGMT3, PWRMGMT3_LMIC|PWRMGMT3_RMIC); //PWRMGMT3(0x2f)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//i2c_WM8960_write(LINBMIX, 0x000); //LINBMIX(0x2B)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if (AOut<=0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2c_WM8960_write(AINTFCE2, 0x40); //FIXME:(0x09)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			data = wm_reg_data[PWRMGMT2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			if(pll_en) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				i2c_WM8960_write(PWRMGMT2, data|PWRMGMT2_PLL_EN|PWRMGMT2_DACL|PWRMGMT2_DACR); //PWRMGMT2(0x1a)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				i2c_WM8960_write(PWRMGMT2, data|PWRMGMT2_DACL|PWRMGMT2_DACR); //PWRMGMT2(0x1a)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(AOut>0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//Power management 2 setting  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = wm_reg_data[PWRMGMT2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(pll_en) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2c_WM8960_write(PWRMGMT2, data|PWRMGMT2_PLL_EN|PWRMGMT2_DACL|PWRMGMT2_DACR|PWRMGMT2_LOUT1|PWRMGMT2_ROUT1|PWRMGMT2_SPKL|PWRMGMT2_SPKR); //PWRMGMT2(0x1a)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2c_WM8960_write(PWRMGMT2, data|PWRMGMT2_DACL|PWRMGMT2_DACR|PWRMGMT2_LOUT1|PWRMGMT2_ROUT1|PWRMGMT2_SPKL|PWRMGMT2_SPKR); //PWRMGMT2(0x1a)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		mdelay(10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(AINTFCE2, 0x40); //FIXME:(0x09)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(LEFTGAIN, LEFTGAIN_LDVU|LEFTGAIN_LDACVOL(0xff)); //LEFTGAIN(0x0a)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(RIGHTGAIN, RIGHTGAIN_RDVU|RIGHTGAIN_RDACVOL(0xff)); //RIGHTGAIN(0x0b) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(LEFTMIX1, 0x100);  //LEFTMIX1(0x22)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(RIGHTMIX2, 0x100); //RIGHTMIX2(0x25)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = wm_reg_data[PWRMGMT3]; //FIXME 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(PWRMGMT3, data|PWRMGMT3_ROMIX|PWRMGMT3_LOMIX); //PWRMGMT3(0x2f)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = wm_reg_data[CLASSDCTRL1]; //CLASSDCTRL1(0x31) SPEAKER FIXME 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(CLASSDCTRL1, 0xf7);//data|CLASSDCTRL1_OP_LRSPK); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = wm_reg_data[CLASSDCTRL3];	//CLASSDCTRL3(0x33)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(CLASSDCTRL3, 0xad);//data|(0x1b)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(DACCTRL1, 0x000);  //DACCTRL1(0x05)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = wm_reg_data[PWRMGMT1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(PWRMGMT1, data|0x1c0); //FIXME:PWRMGMT1(0x19) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	printk("WM8960 All initial ok!\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_micboost(int boostgain) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data =  wm_reg_data[ADCLPATH]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(ADCLPATH, data|(boostgain << 4)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data =  wm_reg_data[ADCRPATH]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(ADCRPATH, data|(boostgain << 4)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_micin(int enableMic) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (enableMic==1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data =  wm_reg_data[PWRMGMT1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(PWRMGMT1, data|PWRMGMT1_MICB); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data =  wm_reg_data[PWRMGMT1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2c_WM8960_write(PWRMGMT1, data & (~(PWRMGMT1_MICB))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_mute( bool mute) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //Mute:   Set DACMU = 1 to soft-mute the audio DACs.  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //Unmute: Set DACMU = 0 to soft-un-mute the audio DACs.  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    i2c_WM8960_write(DACCTRL1, mute ? DACCTRL1_DACMU : 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//Nice shutdown of WM8960 codec  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_close(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(DACCTRL1,DACCTRL1_DACMU); //0x05->0x08  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(PWRMGMT1, 0x000); //0x19->0x000  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	mdelay(400); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(PWRMGMT2, 0x000); //0x1a->0x000  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_loopback(int fsel) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_codec_exlbk(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	memset(wm_reg_data, 0 , sizeof(unsigned long)*55); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(LINV, 0x117); //0x00->0x117  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(RINV, 0x117); //0x01->0x117  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(LOUT1, 0x179); //0x02->0x179  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(ROUT1, 0x179); //0x03->0x179  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(CLOCKING1, 0x00); //0x04->0x00  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//i2c_WM8960_write(CLOCKING1, 0x40); //0x04->0x00  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(DACCTRL1, 0x00); //0x05->0x00  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(AINTFCE2, 0x41); //0x09->0x41  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(LADCVOL, 0x1c3); //0x15->0x1c3  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(RADCVOL, 0x1c3); //0x16->0x1c3  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(PWRMGMT1, 0xfc); //0x19->0xfc  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(PWRMGMT2, 0x1e0); //0x1a->0x1e0  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(ADCLPATH, 0x108); //0x20->0x108  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(ADCRPATH, 0x108); //0x21->0x108  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(LEFTMIX1, 0x150); //0x22->0x150  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(RIGHTMIX2, 0x150); //0x25->0x150  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(BYPASS1, 0x00); //0x2d->0x00  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(BYPASS2, 0x00); //0x2e->0x00  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(PWRMGMT3, 0x3c); //0x2f->0x3c  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_bypass(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	memset(wm_reg_data, 0 , sizeof(unsigned long)*55); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(RESET, 0x000);    //0x0f(R15)->0x000  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	for(i = 0; i < 1000*HZ; i++); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(PWRMGMT1, 0xf0); //0x19(R25)->0xf0  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(PWRMGMT2, 0x60); //0x1a(R26)->0x60  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(PWRMGMT3, 0x3c); //0x2f(R47)->0x3c  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(LINV, 0x117); // 0x00(R0)->0x117  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(RINV, 0x117); // 0x01(R1)->0x117  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(ADCLPATH, 0x108); //0x20(R32)->0x108  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(ADCRPATH, 0x108); //0x21(R33)->0x108  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(BYPASS1, 0x80); //0x2d(R45)->0x80  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(BYPASS2, 0x80); //0x2e(R46)->0x80  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(LOUT1, 0x179); // 0x02(R2)->0x179  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_WM8960_write(ROUT1, 0x179); // 0x03(R3)->0x179  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(audiohw_set_frequency); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(audiohw_close); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(audiohw_postinit); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(audiohw_preinit); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(audiohw_set_apll); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(audiohw_codec_exlbk); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(audiohw_bypass); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(audiohw_set_lineout_vol); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(audiohw_set_linein_vol); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(audiohw_micin); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(audiohw_mute); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(audiohw_loopback); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(audiohw_micboost); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int codec_wm8960_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct wm8960_data *wm; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++printk("*******Enter %s********\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return -EIO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	wm = devm_kzalloc(&client->dev, sizeof(struct wm8960_data), GFP_KERNEL);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (!wm) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return -ENOMEM; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	mt_set_gpio_mode(GPIO242, GPIO_MODE_04); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        mt_set_gpio_mode(GPIO243, GPIO_MODE_04);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	wm->client = client; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	wm->dev = &client->dev; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	wm->name = id->name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_set_clientdata(client, wm); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	wmio = wm; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	memset(wm_reg_data, 0 , sizeof(unsigned long)*55); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int codec_wm8960_i2c_remove(struct i2c_client *client) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int __devexit codec_wm8960_i2c_remove(struct i2c_client *client) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct wm8960_data *wm = i2c_get_clientdata(client); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	kfree(wm); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static const struct i2c_device_id wm8960_id[] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ "codec_wm8960", 0 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static struct i2c_driver codec_wm8960_i2c_driver = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.driver = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		.name	= "codec_wm8960"                
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.probe	= codec_wm8960_i2c_probe, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        .remove = codec_wm8960_i2c_remove, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.remove	= __devexit_p(codec_wm8960_i2c_remove), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.id_table = wm8960_id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int __init wm8960_i2c_init(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_register_board_info(1, &i2c_devs1, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return i2c_add_driver(&codec_wm8960_i2c_driver);;  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static void __exit wm8960_i2c_exit(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_del_driver(&codec_wm8960_i2c_driver); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++module_init(wm8960_i2c_init); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++module_exit(wm8960_i2c_exit); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_AUTHOR("Ryder Lee <[email protected]>"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_DESCRIPTION("WM8960 I2C client driver"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_LICENSE("GPL"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- /dev/null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/mtk/i2c_wm8960.h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -0,0 +1,288 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* wm8960.h  --  WM8960 Soc Audio driver */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifndef _WM8960_H 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define _WM8960_H 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define bool	unsigned char 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define false 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define true 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* volume/balance/treble/bass interdependency */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define VOLUME_MIN 	-730 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define VOLUME_MAX  	60 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* Register addresses and bits */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define OUTPUT_MUTED                	0x2f 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define OUTPUT_0DB                  	0x79 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LINV			    	0x00 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LINV_IPVU		    	(1 << 8)  /* FIXME */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LINV_LINMUTE		    	(1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LINV_LIZC                       (1 << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LINV_LINVOL(x)              	((x) & 0x3f) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RINV			    	0x01 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RINV_IPVU		    	(1 << 8) /* FIXME */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RINV_RINMUTE		    	(1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RINV_RIZC                   	(1 << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RINV_RINVOL(x)              	((x) & 0x3f) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LOUT1                       	0x02 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LOUT1_LO1VU                 	(1 << 8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LOUT1_LO1ZC                 	(1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LOUT1_LOUT1VOL(x)           	((x) & 0x7f) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ROUT1                       	0x03 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ROUT1_RO1VU                 	(1 << 8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ROUT1_RO1ZC                 	(1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ROUT1_ROUT1VOL(x)           	((x) & 0x7f) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CLOCKING1			0x04  /* FIXME */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CLOCKING1_ADCDIV(x)		(((x) & 0x7) << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CLOCKING1_DACDIV(x)		(((x) & 0x7) << 3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CLOCKING1_SYSCLKDIV_1		(0 << 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CLOCKING1_SYSCLKDIV_2		(2 << 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CLOCKING1_CLKSEL_MCLK		(0 << 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CLOCKING1_CLKSEL_PLL		(1 << 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define DACCTRL1                     	0x05 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define DACCTRL1_DATTENUATE             (1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define DACCTRL1_DACMU               	(1 << 3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define DACCTRL1_DEEMPH_48           	(3 << 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define DACCTRL1_DEEMPH_44           	(2 << 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define DACCTRL1_DEEMPH_32           	(1 << 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define DACCTRL1_DEEMPH_NONE         	(0 << 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define DACCTRL1_DEEMPH(x)           	((x) & (0x3 << 1)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define DACCTRL2			0x06 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1                     	0x07 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1_BCLKINV             	(1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1_MS                  	(1 << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1_LRSWAP              	(1 << 5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1_LRP                 	(1 << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1_WL_32               	(3 << 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1_WL_24                  (2 << 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1_WL_20                  (1 << 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1_WL_16               	(0 << 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1_WL(x)               	(((x) & 0x3) << 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1_FORMAT_DSP             (3 << 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1_FORMAT_I2S             (2 << 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1_FORMAT_LJUST           (1 << 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1_FORMAT_RJUST        	(0 << 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1_FORMAT(x)           	((x) & 0x3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* FIXME */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CLOCKING2                    	0x08 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CLOCKING2_DCLKDIV(x)            (((x) & 0x7) << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CLOCKING2_BCLKDIV(x)		(((x) & 0xf) << 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE2			0x09 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE2_ALRCGPIO_ALRC		(0 << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define	AINTFCE2_ALRCGPIO_GPIO		(1 << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define	AINTFCE2_LOOPBACK		(1 << 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LEFTGAIN                    	0x0a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LEFTGAIN_LDVU                   (1 << 8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LEFTGAIN_LDACVOL(x)         	((x) & 0xff) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RIGHTGAIN                   	0x0b 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RIGHTGAIN_RDVU                  (1 << 8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RIGHTGAIN_RDACVOL(x)        	((x) & 0xff) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RESET                       	0x0f 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RESET_RESET                 	0x000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ALC1			    	0x11 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ALC1_ALCOFF		    	(0x0 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define	ALC1_ALCRONLY		    	(0x1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ALC1_ALCLONLY		    	(0x2 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ALC1_ALCSTEREO		    	(0x3 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ALC1_ALCSEL(x)		    	(((x) & 0x3) << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ALC1_SET_MAXGAIN(x)	    	((x & 0x7) << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ALC1_GET_MAXGAIN(x)	    	((x) & (0x7 << 4)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ALC1_ALCL(x)		    	((x) & 0x0f)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ALC2			    	0x12 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ALC2_MINGAIN(x)               	((x & 0x7) << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ALC2_HLD(x)		    	((x) & 0x0f) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ALC3			    	0x13 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ALC3_SET_DCY(x)		    	((x & 0x0f) << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ALC3_GET_DCY(x)		    	((x) & (0x0f << 4)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ALC3_ATK(x)		    	((x) & 0x0f) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define NOISEGATE		    	0x14 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define NOISEGATE_SET_NGTH(x)	    	((x & 0x1f) << 3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define NOISEGATE_GET_NGTH(x)	    	((x) & (0x1f << 3)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define NOISEGATE_NGAT_ENABLE	    	1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LADCVOL			    	0x15 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LADCVOL_LAVU_EN		    	(1 << 8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LADCVOL_LADCVOL(x)	    	((x) & 0x0ff) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RADCVOL			    	0x16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RADCVOL_RAVU_EN		    	(1 << 8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RADCVOL_RADCVOL(x)	    	((x) & 0x0ff) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL1                 	0x17 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL1_TSDEN               (1 << 8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL1_VSEL_LOWEST     	(0 << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL1_VSEL_LOW        	(1 << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL1_VSEL_DEFAULT2   	(2 << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL1_VSEL_DEFAULT    	(3 << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL1_VSEL(x)         	(((x) & 0x3) << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL1_DMONOMIX_STEREO   	(0 << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL1_DMONOMIX_MONO   	(1 << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL1_DATSEL(x)         	(((x) & 0x3) << 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL1_TOCLKSEL            (1 << 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL1_TOEN                (1 << 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL2                 	0x18 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL2_HPSWEN              (1 << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL2_HPSWPOL             (1 << 5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL2_TRIS                (1 << 3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL2_LRCM_ON         	(1 << 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT1                    	0x19 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT1_VMIDSEL_DISABLED   	(0 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT1_VMIDSEL_50K        	(1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT1_VMIDSEL_250K       	(2 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT1_VMIDSEL_5K         	(3 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT1_VREF                   (1 << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT1_AINL                   (1 << 5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT1_AINR                   (1 << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT1_ADCL                   (1 << 3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT1_ADCR                   (1 << 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT1_MICB                   (1 << 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT1_DIGENB                 (1 << 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT2                    	0x1a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT2_DACL               	(1 << 8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT2_DACR                   (1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT2_LOUT1                  (1 << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT2_ROUT1                  (1 << 5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT2_SPKL                   (1 << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT2_SPKR                   (1 << 3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT2_OUT3                   (1 << 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT2_PLL_EN                 (1 << 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL3                 	0x1b 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL3_VROI            	(1 << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL3_OUT3CAP             (1 << 3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL3_ADC_ALC_SR(x)       ((x) & 0x7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ANTIPOP1			0x1c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ANTIPOP2			0x1d 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADCLPATH			0x20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADCLPATH_LMN1			(1 << 8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADCLPATH_LMP3                   (1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADCLPATH_LMP2                   (1 << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADCLPATH_LMICBOOST_29DB         (0x3 << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADCLPATH_LMICBOOST_20DB         (0x2 << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADCLPATH_LMICBOOST_13DB         (0x1 << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADCLPATH_SET_LMICBOOST(x)       ((x & 0x3) << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADCLPATH_LMIC2B                 (1 << 3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADCRPATH			0x21 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADCRPATH_RMN1			(1 << 8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADCRPATH_RMP3                   (1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADCRPATH_RMP2                   (1 << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADCRPATH_RMICBOOST_29DB         (0x3 << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADCRPATH_RMICBOOST_20DB         (0x2 << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADCRPATH_RMICBOOST_13DB         (0x1 << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADCRPATH_SET_RMICBOOST(x)       ((x & 0x3) << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADCRPATH_RMIC2B                 (1 << 3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LEFTMIX1                    	0x22 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LEFTMIX1_LD2LO              	(1 << 8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LEFTMIX1_LI2LO                  (1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LEFTMIX1_LI2LO_DEFAULT          (5 << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LEFTMIX1_LI2LOVOL(x)            (((x) & 0x7) << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RIGHTMIX2                   	0x25 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RIGHTMIX2_RD2RO             	(1 << 8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RIGHTMIX2_RI2RO                 (1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RIGHTMIX2_RI2RO_DEFAULT         (5 << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RIGHTMIX2_RI2ROVOL(x)           (((x) & 0x7) << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MONOMIX1                    	0x26 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MONOMIX1_L2MO              	(1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MONOMIX2                    	0x27 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MONOMIX2_R2MO              	(1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LSPK                       	0x28 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LSPK_SPKLVU                 	(1 << 8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LSPK_SPKLZC                     (1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LSPK_SPKLVOL(x)                 ((x) & 0x7f) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RSPK                       	0x29 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RSPK_SPKRVU                 	(1 << 8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RSPK_SPKRZC                     (1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RSPK_SPKRVOL(x)                 ((x) & 0x7f) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define OUT3V                     	0x2a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LINBMIX				0x2b 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RINBMIX				0x2c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define BYPASS1 			0x2d 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define BYPASS2				0x2e 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT3 			0x2f 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT3_LMIC			(1<<5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT3_RMIC                   (1<<4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT3_LOMIX                  (1<<3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PWRMGMT3_ROMIX                  (1<<2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL4 			0x30 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CLASSDCTRL1 			0x31 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CLASSDCTRL1_OP_OFF		(0<<6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CLASSDCTRL1_OP_LSPK		(1<<6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CLASSDCTRL1_OP_RSPK		(2<<6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CLASSDCTRL1_OP_LRSPK		(3<<6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CLASSDCTRL3			0x33 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PLL1				0x34 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PLL1_OPCLKDIV_1			(0<<6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PLL1_OPCLKDIV_2			(1<<6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PLL1_OPCLKDIV_3			(2<<6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PLL1_OPCLKDIV_4			(3<<6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define	PLL1_OPCLKDIV_5p5		(4<<6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define	PLL1_OPCLKDIV_6			(5<<6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PLL1_SDM_INTERGER		(0<<5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PLL1_SDM_FRACTIONAL		(1<<5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PLL1_PLLPRESCALE_1		(0<<4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PLL1_PLLPRESCALE_2		(1<<4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PLL1_PLLN(x)			((x) & 0xf) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PLL2				0x35 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define	PLL2_PLLK_23_16(x)		((x) & 0x1ff) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PLL3				0x36 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PLL3_PLLK_15_8(x)		((x) & 0x1ff) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PLL4				0x37 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PLL4_PLLK_7_0(x) 		((x) & 0x1ff) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* codec API */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_preinit(void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int audiohw_postinit(int bSlave, int AIn, int AOut, int pll_en, int wordLen24b); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_close(void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_set_frequency(int fsel, int pll_en); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_mute(bool mute); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_micboost(int boostgain); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_micin(int enableMic); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_set_apll(int srate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int audiohw_set_lineout_vol(int Aout, int vol_l, int vol_r); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int audiohw_set_linein_vol(int vol_l, int vol_r); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_mute( bool mute); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_loopback(int fsel); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_codec_exlbk(void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_bypass(void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif /* _WM875x_H */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- /dev/null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/mtk/i2s_ctrl.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -0,0 +1,3524 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/init.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/version.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/sched.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/module.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/kernel.h> /* _printk() */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/slab.h> /* kmalloc() */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/fs.h> /* everything... */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/errno.h> /* error codes */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/types.h> /* size_t */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/proc_fs.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/fcntl.h> /* O_ACCMODE */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,14) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <asm/system.h> /* cli(), *_flags */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <asm/uaccess.h> /* copy_from/to_user */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/interrupt.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/mm.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/mm_types.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/pci.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/delay.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "ralink_gdma.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WITH_AEC) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "../aec/aec_api.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef  CONFIG_DEVFS_FS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/devfs_fs_kernel.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static	devfs_handle_t devfs_handle; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "i2s_ctrl.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_SND_MT76XX_SOC) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/soc/mtk/mt76xx_machine.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8750) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "../codec/i2c_wm8750.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "../codec/i2c_wm8751.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "i2c_wm8960.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int i2sdrv_major =  191; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static struct class *i2smodule_class; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int _printk(char *fmt, ...) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* external functions declarations */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern void audiohw_set_frequency(int fsel, int codec_pll_en); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void audiohw_set_apll(int srate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern void audiohw_set_frequency(int fsel); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern int audiohw_set_lineout_vol(int Aout, int vol_l, int vol_r); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern int audiohw_set_master_vol(int vol_l, int vol_r); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern int audiohw_set_linein_vol(int vol_l, int vol_r); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern void audiohw_micboost(int boostgain); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern int GdmaI2sTx(uint32_t Src, uint32_t Dst, uint8_t TxNo, uint16_t TransCount, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                void (*DoneIntCallback)(uint32_t data), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                void (*UnMaskIntCallback)(uint32_t data)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern int GdmaI2sRx(uint32_t Src, uint32_t Dst, uint8_t RxNo, uint16_t TransCount, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                void (*DoneIntCallback)(uint32_t data), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                void (*UnMaskIntCallback)(uint32_t data)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern int GdmaMaskChannel(uint32_t ChNum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern int GdmaUnMaskChannel(uint32_t ChNum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* internal functions declarations */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++irqreturn_t i2s_irq_isr(int irq, void *irqaction); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_debug_cmd(unsigned int cmd, unsigned long arg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* forward declarations for _fops */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static long i2s_ioctl(struct file *file, unsigned int cmd, unsigned long arg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int i2s_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int i2s_mmap(struct file *file, struct vm_area_struct *vma); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int i2s_open(struct inode *inode, struct file *file); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int i2s_release(struct inode *inode, struct file *file); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_mmap_alloc(unsigned long size); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_mmap_remap(struct vm_area_struct *vma, unsigned long size); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* global varable definitions */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++i2s_config_type i2s_config; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++i2s_status_type i2s_status;  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++i2s_config_type* pi2s_config = &i2s_config;; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++i2s_status_type* pi2s_status = &i2s_status;; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static inline long 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ugly_hack_sleep_on_timeout(wait_queue_head_t *q, long timeout) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long flags; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	wait_queue_t wait; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	init_waitqueue_entry(&wait, current); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	__set_current_state(TASK_INTERRUPTIBLE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	spin_lock_irqsave(&q->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	__add_wait_queue(q, &wait); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	spin_unlock(&q->lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	timeout = schedule_timeout(timeout); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	spin_lock_irq(&q->lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	__remove_wait_queue(q, &wait); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	spin_unlock_irqrestore(&q->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return timeout; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define interruptible_sleep_on(x) \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ugly_hack_sleep_on_timeout(x, MAX_SCHEDULE_TIMEOUT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static dma_addr_t i2s_txdma_addr0, i2s_txdma_addr1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static dma_addr_t i2s_rxdma_addr0, i2s_rxdma_addr1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_FIFO_WREG_PHY (I2S_TX_FIFO_WREG & 0x1FFFFFFF) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_FIFO_RREG_PHY (I2S_RX_FIFO_RREG & 0x1FFFFFFF) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static dma_addr_t i2s_txdma_addr, i2s_rxdma_addr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static dma_addr_t i2s_mmap_addr[MAX_I2S_PAGE*2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				      /* 8khz 11.025khz 12khz  16khz 22.05khz 24Khz  32khz 44.1khz 48khz 88.2khz 96khz*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++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}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++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}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++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}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8750) || defined(CONFIG_SND_SOC_WM8750) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					/* 8k  11.025k  12k   16k  22.05k  24k  32k   44.1k   48k  88.2k   96k*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_codec_12p288Mhz[11]  = {0x0C,  0x00, 0x10, 0x14,  0x38, 0x38, 0x18,  0x20, 0x00,  0x00, 0x1C}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_codec_12Mhz[11]      = {0x0C,  0x32, 0x10, 0x14,  0x37, 0x38, 0x18,  0x22, 0x00,  0x3E, 0x1C}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_codec_24p576Mhz[11]  = {0x4C,  0x00, 0x50, 0x54,  0x00, 0x78, 0x58,  0x00, 0x40,  0x00, 0x5C}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_codec_18p432Mhz[11]  = {0x0e,  0x32, 0x12, 0x16,  0x36, 0x3a, 0x1a,  0x22, 0x02,  0x3e, 0x1e}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8751) || defined(CONFIG_SND_SOC_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_codec_12p288Mhz[11]  = {0x04,  0x00, 0x10, 0x14,  0x38, 0x38, 0x18,  0x20, 0x00,  0x00, 0x1C}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_codec_12Mhz[11]      = {0x04,  0x32, 0x10, 0x14,  0x37, 0x38, 0x18,  0x22, 0x00,  0x3E, 0x1C}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_SND_SOC_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_codec_12p288Mhz[11]  = {0x36,  0x24, 0x24, 0x1b,  0x12, 0x12, 0x09,  0x00, 0x00,  0x00, 0x00}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_codec_12Mhz[11]      = {0x36,  0x24, 0x24, 0x1b,  0x12, 0x12, 0x09,  0x00, 0x00,  0x00, 0x00}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_codec_12p288Mhz); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_codec_12Mhz); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT6855A) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				   /* 8K  11.025k  12k   16k  22.05k   24k   32k  44.1K   48k  88.2k  96k */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_int[11]  = {  97,    70,    65,   48,    35,    32,   24,   17,    16,   12,    8}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_comp[11] = { 336,   441,    53,  424,   220,   282,  212,  366,   141,  185,   70}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined (CONFIG_RALINK_MT7621) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef MT7621_ASIC_BOARD 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_I2S_MCLK_12P288MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_int[11]  = { 576,   384,    0,   288,   192,   192,  144,   96,    96,   48,   48}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_comp[11] = {   0,     0,    0,     0,     0,     0,    0,    0,     0,    0,    0}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_I2S_MCLK_12MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_int[11] =  {1171,   850,    0,   585,   425,   390,  292,  212,   195,   106,   97}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_comp[11] = { 448,   174,    0,   480,    87,   320,  496,  299,   160,   149,  336}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else //MT7621_FPGA_BOARD 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_int[11] =  { 529,   384,    0,   264,   192,   176,  132,   96,    88,    48,   44}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_comp[11] = { 102,     0,    0,   307,     0,   204,  153,    0,   102,     0,   51}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined (CONFIG_RALINK_MT7628) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef MT7628_ASIC_BOARD 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                      /* 8K  11.025k 12k  16k 22.05k 24k  32k 44.1K  48k  88.2k 96k  176k 192k */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_int_16bit[13] = {937,  680,   0,  468,  340, 312, 234, 170,  156,   85, 78,   42,  39}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_comp_16bit[13]= {256,  139,   0,  384,   69, 256, 192,  34,  128,   17, 64,  267,  32}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_int_24bit[13] = {625,  404,   0,  312,  226, 208, 156, 113,  104,   56, 52,   28,  26}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_comp_24bit[13]= {  0,  404,   0,  256,  387, 170, 128, 193,   85,  352, 42,  176,  21}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				      /* 8K  11.025k 12k  16k 22.05k 24k  32k 44.1K  48k  88.2k 96k  176k 192k */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_int_16bit[13] = {468,  340,   0,  234,  170, 156, 117,  85,   78,   42, 39,   21,  19}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_comp_16bit[13]= {384,   69,   0,  192,   34, 128,  96,  17,   64,  264, 32,  133, 272}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_int_24bit[13] = {312,  202,   0,  156,  113, 104,  78,  56,   52,   28, 26,   14,  13}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_comp_24bit[13]= {256,  202,   0,  128,  193,  85,  64, 352,   42,  176,  21,  88,  10}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined (CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined MT7623_ASIC_BOARD 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				      /* 8K  11.025k 12k  16k 22.05k 24k  32k 44.1K  48k  88.2k 96k  176k 192k */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_int_16bit[13] = {576,  384,   0,  288,  192, 192, 144,  96,  96,    48, 48,   24,  24}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_comp_16bit[13]= { 0,    0,    0,    0,   0,    0,   0,   0,   0,     0,  0,    0,   0}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_int_24bit[13] = {384,  256,   0,  192,  128, 128,  96,  64,  64,    32, 32,   16,  16}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_comp_24bit[13]= { 0,    0,    0,    0,   0,    0,   0,   0,   0,     0,  0,    0,   0}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				      /* 8K  11.025k 12k  16k 22.05k 24k  32k 44.1K  48k  88.2k 96k  176k 192k */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_int_16bit[13] = {72,   48,    0,   36,  24,   24,  18,  12,   12,    6,  6,    3,   3}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_comp_16bit[13]= { 0,    0,    0,    0,   0,    0,   0,   0,    0,    0,  0,    0,   0}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_int_24bit[13] = {48,   32,    0,   24,  16,   16,  12,   8,    8,    4,  4,    2,   2}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_comp_24bit[13]= { 0,    0,    0,    0,   0,    0,   0,   0,    0,    0,  0,    0,   0}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				  /* 8K  11.025k 12k  16k  22.05k  24k  32k  44.1K  48k  88.2k  96k */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_int[11]  = { 78,    56,   52,  39,   28,    26,  19,   14,   13,   9,    6}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long i2s_inclk_comp[11] = { 64,   352,   42,  32,  176,    21, 272,   88,   10, 455,  261}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WITH_AEC) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++aecFuncTbl_t *aecFuncP; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* USB mode 22.05Khz register value in datasheet is 0x36 but will cause slow clock, 0x37 is correct value */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* USB mode 44.1Khz register value in datasheet is 0x22 but will cause slow clock, 0x23 is correct value */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++struct tasklet_struct i2s_tx_tasklet; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++struct tasklet_struct i2s_rx_tasklet; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_tx_tasklet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_rx_tasklet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++char test_buf[I2S_PAGE_SIZE]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++char test_buf_1[I2S_PAGE_SIZE]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++char test_buf_2[I2S_PAGE_SIZE]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static const struct file_operations i2s_fops = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	owner		: THIS_MODULE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	mmap		: i2s_mmap, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	open		: i2s_open, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	release		: i2s_release, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unlocked_ioctl:     i2s_ioctl, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ioctl		: i2s_ioctl, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int __init i2s_mod_init(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	_printk("******* i2s module init **********\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* register device with kernel */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef  CONFIG_DEVFS_FS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	if(devfs_register_chrdev(i2sdrv_major, I2SDRV_DEVNAME , &i2s_fops)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		_printk(KERN_WARNING " i2s: can't create device node - %s\n", I2SDRV_DEVNAME); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return -EIO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	devfs_handle = devfs_register(NULL, I2SDRV_DEVNAME, DEVFS_FL_DEFAULT, i2sdrv_major, 0,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    S_IFCHR | S_IRUGO | S_IWUGO, &i2s_fops, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	result = register_chrdev(i2sdrv_major, I2SDRV_DEVNAME, &i2s_fops); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	if (result < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		_printk(KERN_WARNING "i2s: can't get major %d\n",i2sdrv_major); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	return result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	if (i2sdrv_major == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2sdrv_major = result; /* dynamic */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2smodule_class=class_create(THIS_MODULE, I2SDRV_DEVNAME); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (IS_ERR(i2smodule_class))  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return -EFAULT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	device_create(i2smodule_class, NULL, MKDEV(i2sdrv_major, 0), I2SDRV_DEVNAME); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WITH_AEC) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	_printk("AEC FuncP init \n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/*Add by mtk04880*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	aecFuncP = kmalloc(sizeof(aecFuncTbl_t), GFP_KERNEL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/*If aecFuncP cannot request memory,it will be ignored in I2S module. Since AEC & I2S are independent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 * when AEC module is inserted,It will return err message (but I2S will keep running without AEC support) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 * */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(aecFuncP){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		memset(aecFuncP,0,sizeof(aecFuncTbl_t)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_mod_exit(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	_printk("************ i2s module exit *************\n");	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef  CONFIG_DEVFS_FS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	devfs_unregister_chrdev(i2sdrv_major, I2SDRV_DEVNAME); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	devfs_unregister(devfs_handle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	unregister_chrdev(i2sdrv_major, I2SDRV_DEVNAME); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	device_destroy(i2smodule_class,MKDEV(i2sdrv_major, 0)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	class_destroy(i2smodule_class);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_open(struct inode *inode, struct file *filp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(I2S_HW_INTERRUPT_EN)&&(I2S_SW_IRQ_EN) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int Ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int minor = iminor(inode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (minor >= I2S_MAX_DEV) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return -ENODEV; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MOD_INC_USE_COUNT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	try_module_get(THIS_MODULE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (filp->f_flags & O_NONBLOCK) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("filep->f_flags O_NONBLOCK set\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return -EAGAIN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* set i2s_config */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	filp->private_data = pi2s_config; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	memset(pi2s_config, 0, sizeof(i2s_config_type)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef I2S_STATISTIC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	memset(pi2s_status, 0, sizeof(i2s_status_type));	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_param_init(pi2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(I2S_HW_INTERRUPT_EN)&&(I2S_SW_IRQ_EN)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Ret = request_irq(SURFBOARDINT_I2S, i2s_irq_isr, IRQF_DISABLED, "Ralink_I2S", NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Ret = request_irq(SURFBOARDINT_I2S, i2s_irq_isr, SA_INTERRUPT, "Ralink_I2S", NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(Ret){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("IRQ %d is not free.\n", SURFBOARDINT_I2S); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_release(inode, filp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	init_waitqueue_head(&(pi2s_config->i2s_tx_qh)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	init_waitqueue_head(&(pi2s_config->i2s_rx_qh)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	spin_lock_init(&pi2s_config->lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int i2s_release(struct inode *inode, struct file *filp) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_config_type* ptri2s_config; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* decrement usage count */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MOD_DEC_USE_COUNT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	module_put(THIS_MODULE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(I2S_HW_INTERRUPT_EN)&&(I2S_SW_IRQ_EN) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	free_irq(SURFBOARDINT_I2S, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config = filp->private_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(ptri2s_config==NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		goto EXIT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef CONFIG_I2S_MMAP	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_mem_unmap(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_txbuf_free(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_rxbuf_free(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* free buffer */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_txPagebuf_free(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_rxPagebuf_free(ptri2s_config);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXIT:			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("i2s_release succeeds\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_mmap_alloc(unsigned long size) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 page_size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++       	int first_index; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	page_size = I2S_PAGE_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if ((pi2s_config->mmap_index == 0) || (pi2s_config->mmap_index == MAX_I2S_PAGE)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("mmap_index=%d\n", pi2s_config->mmap_index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		first_index = pi2s_config->mmap_index; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index] = kmalloc(size, GFP_DMA); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_mmap_addr[pi2s_config->mmap_index] = (dma_addr_t)dma_map_single(NULL, pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index], size, DMA_BIDIRECTIONAL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if( pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index] == NULL )  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("i2s_mmap failed\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		_printk("illegal index:%d\n", pi2s_config->mmap_index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return -1;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	_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]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	memset(pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index], 0, size); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_config->mmap_index++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	for (i=1; i<MAX_I2S_PAGE; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_mmap_addr[pi2s_config->mmap_index] = i2s_mmap_addr[first_index] + i*page_size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index] = pi2s_config->pMMAPBufPtr[first_index] + i*page_size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		_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]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		/* Notice: The last mmap_index's value should be MAX_I2S_PAGE or MAX_I2S_PAGE*2 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pi2s_config->mmap_index++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_mmap_remap(struct vm_area_struct *vma, unsigned long size) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int nRet; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if((pi2s_config->pMMAPBufPtr[0]!=NULL) && (pi2s_config->mmap_index == MAX_I2S_PAGE)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("i2s_mmap_remap:0\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		nRet = remap_pfn_range(vma, vma->vm_start, virt_to_phys((void *)pi2s_config->pMMAPBufPtr[0]) >> PAGE_SHIFT,  size, vma->vm_page_prot); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if( nRet != 0 ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			_printk("i2s_mmap->remap_pfn_range failed\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			return -EIO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if((pi2s_config->pMMAPBufPtr[MAX_I2S_PAGE]!=NULL) && (pi2s_config->mmap_index == MAX_I2S_PAGE*2)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("i2s_mmap_remap:%d\n", MAX_I2S_PAGE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if( nRet != 0 ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			_printk("i2s_mmap->remap_pfn_range failed\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			return -EIO; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int i2s_mmap(struct file *filp, struct vm_area_struct *vma) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long size = vma->vm_end-vma->vm_start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	_printk("page_size=%d, ksize=%lu\n", I2S_PAGE_SIZE, size); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if((pi2s_config->pMMAPBufPtr[0]==NULL)&&(pi2s_config->mmap_index!=0)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pi2s_config->mmap_index = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	_printk("%s: vm_start=%08X,vm_end=%08X\n", __func__, (u32)vma->vm_start, (u32)vma->vm_end); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* Do memory allocate and dma sync */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_mmap_alloc(size); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_mmap_remap(vma, size); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_mem_unmap(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 page_size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	page_size = I2S_PAGE_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(ptri2s_config->pMMAPBufPtr[0]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		_printk("ummap MMAP[0]=0x%08X\n", (u32)ptri2s_config->pMMAPBufPtr[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		dma_unmap_single(NULL, i2s_mmap_addr[0], MAX_I2S_PAGE*page_size, DMA_BIDIRECTIONAL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		kfree(ptri2s_config->pMMAPBufPtr[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(ptri2s_config->pMMAPBufPtr[MAX_I2S_PAGE]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		_printk("ummap MMAP[%d]=0x%08X\n", MAX_I2S_PAGE, (u32)ptri2s_config->pMMAPBufPtr[MAX_I2S_PAGE]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		dma_unmap_single(NULL, i2s_mmap_addr[MAX_I2S_PAGE], MAX_I2S_PAGE*page_size, DMA_BIDIRECTIONAL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		kfree(ptri2s_config->pMMAPBufPtr[MAX_I2S_PAGE]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->mmap_index = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_param_init(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->dmach = GDMA_I2S_TX0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->tx_ff_thres = CONFIG_I2S_TFF_THRES; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->tx_ch_swap = CONFIG_I2S_CH_SWAP; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->rx_ff_thres = CONFIG_I2S_TFF_THRES; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->rx_ch_swap = CONFIG_I2S_CH_SWAP; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->slave_en = CONFIG_I2S_SLAVE_EN;  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->codec_pll_en = CONFIG_I2S_CODEC_PLL_EN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->bRxDMAEnable = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->bTxDMAEnable = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//ptri2s_config->bALSAEnable = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->srate = 44100; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->txvol = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->rxvol = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->lbk = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->extlbk = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->txrx_coexist = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->wordlen_24b = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->sys_endian = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->fmt = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->micboost = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->micin = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_txbuf_alloc(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	for( i = 0 ; i < MAX_I2S_PAGE ; i ++ ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MMAP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->pMMAPTxBufPtr[i] = ptri2s_config->pMMAPBufPtr[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                if(ptri2s_config->pMMAPTxBufPtr[i]==NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                	ptri2s_config->pMMAPTxBufPtr[i] = kmalloc(I2S_PAGE_SIZE, GFP_KERNEL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		memset(ptri2s_config->pMMAPTxBufPtr[i], 0, I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_rxbuf_alloc(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	for( i = 0 ; i < MAX_I2S_PAGE ; i ++ ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MMAP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	ptri2s_config->pMMAPRxBufPtr[i] = ptri2s_config->pMMAPBufPtr[i+(ptri2s_config->mmap_index-MAX_I2S_PAGE)]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                if(ptri2s_config->pMMAPRxBufPtr[i]==NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->pMMAPRxBufPtr[i] = kmalloc(I2S_PAGE_SIZE, GFP_KERNEL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		memset(ptri2s_config->pMMAPRxBufPtr[i], 0, I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_txPagebuf_alloc(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->pPage0TxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE , &i2s_txdma_addr0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->pPage1TxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE , &i2s_txdma_addr1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(ptri2s_config->pPage0TxBuf8ptr==NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("Allocate Tx Page0 Buffer Failed\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(ptri2s_config->pPage1TxBuf8ptr==NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("Allocate Tx Page1 Buffer Failed\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->pPage0TxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE*2 , &i2s_txdma_addr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        if(ptri2s_config->pPage0TxBuf8ptr==NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("Allocate Tx Page Buffer Failed\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        ptri2s_config->pPage1TxBuf8ptr = ptri2s_config->pPage0TxBuf8ptr + I2S_PAGE_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_rxPagebuf_alloc(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->pPage0RxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE, &i2s_rxdma_addr0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->pPage1RxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE, &i2s_rxdma_addr1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(ptri2s_config->pPage0RxBuf8ptr==NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("Allocate Rx Page Buffer Failed\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(ptri2s_config->pPage1RxBuf8ptr==NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("Allocate Rx Page Buffer Failed\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->pPage0RxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE*2 , &i2s_rxdma_addr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(ptri2s_config->pPage0RxBuf8ptr==NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("Allocate Rx Page Buffer Failed\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->pPage1RxBuf8ptr = ptri2s_config->pPage0RxBuf8ptr + I2S_PAGE_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_txbuf_free(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	for(i = 0 ; i < MAX_I2S_PAGE ; i ++)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(ptri2s_config->pMMAPTxBufPtr[i] != NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MMAP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        ptri2s_config->pMMAPTxBufPtr[i] = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			kfree(ptri2s_config->pMMAPTxBufPtr[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->pMMAPTxBufPtr[i] = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_rxbuf_free(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	for(i = 0 ; i < MAX_I2S_PAGE ; i ++)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(ptri2s_config->pMMAPRxBufPtr[i] != NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MMAP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        ptri2s_config->pMMAPRxBufPtr[i] = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			kfree(ptri2s_config->pMMAPRxBufPtr[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->pMMAPRxBufPtr[i] = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_txPagebuf_free(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (ptri2s_config->pPage0TxBuf8ptr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pci_free_consistent(NULL, I2S_PAGE_SIZE, ptri2s_config->pPage0TxBuf8ptr, i2s_txdma_addr0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->pPage0TxBuf8ptr = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (ptri2s_config->pPage1TxBuf8ptr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pci_free_consistent(NULL, I2S_PAGE_SIZE, ptri2s_config->pPage1TxBuf8ptr, i2s_txdma_addr1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->pPage1TxBuf8ptr = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	_printk("Free tx page buffer\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (ptri2s_config->pPage0TxBuf8ptr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pci_free_consistent(NULL, I2S_PAGE_SIZE*2, ptri2s_config->pPage0TxBuf8ptr, i2s_txdma_addr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->pPage0TxBuf8ptr = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_rxPagebuf_free(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (ptri2s_config->pPage0RxBuf8ptr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pci_free_consistent(NULL, I2S_PAGE_SIZE, ptri2s_config->pPage0RxBuf8ptr, i2s_rxdma_addr0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->pPage0RxBuf8ptr = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (ptri2s_config->pPage1RxBuf8ptr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pci_free_consistent(NULL, I2S_PAGE_SIZE, ptri2s_config->pPage1RxBuf8ptr, i2s_rxdma_addr1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->pPage1RxBuf8ptr = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	_printk("Free rx page buffer\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (ptri2s_config->pPage0RxBuf8ptr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pci_free_consistent(NULL, I2S_PAGE_SIZE*2, ptri2s_config->pPage0RxBuf8ptr, i2s_rxdma_addr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->pPage0RxBuf8ptr = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_reset_tx_param(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->tx_isr_cnt = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->tx_w_idx = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->tx_r_idx = 0;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->enLable = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->tx_pause_en = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->end_cnt = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->tx_stop_cnt = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef I2S_STATISTIC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_status->txbuffer_unrun = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_status->txbuffer_ovrun = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_status->txdmafault = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_status->txovrun = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_status->txunrun = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_status->txthres = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_status->txbuffer_len = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_reset_rx_param(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->rx_isr_cnt = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->rx_w_idx = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->rx_r_idx = 0;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->enLable = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->rx_pause_en = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config->rx_stop_cnt = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef I2S_STATISTIC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_status->rxbuffer_unrun = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_status->rxbuffer_ovrun = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_status->rxdmafault = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_status->rxovrun = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_status->rxunrun = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_status->rxthres = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_status->rxbuffer_len = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef MT7621_ASIC_BOARD 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_pll_config_mt7621(unsigned long index) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long regValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	bool xtal_20M_en = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//	bool xtal_25M_en = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	bool xtal_40M_en = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	regValue = i2s_inw(RALINK_SYSCTL_BASE + 0x10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++       	regValue = (regValue >> 6) & 0x7; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (regValue < 3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		xtal_20M_en = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("Xtal is 20MHz. \n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else if (regValue < 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		xtal_40M_en = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("Xtal is 40M.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//xtal_25M_en = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("Xtal is 25M.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_I2S_MCLK_12P288MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	_printk("MT7621 provide 12.288M/11.298MHz REFCLK\n");	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* Firstly, reset all required register to default value */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_ANA_CTRL_BASE, 0x00008000); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, 0x01001d61);//0x01401d61); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, 0x38233d0e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, 0x80100004);//0x80120004); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x1c7dbf48); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        /* toggle RG_XPTL_CHG */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        i2s_outw(RALINK_ANA_CTRL_BASE, 0x00008800); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        i2s_outw(RALINK_ANA_CTRL_BASE, 0x00008c00); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data &= ~(0x0000ffc0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if ((xtal_40M_en) || (xtal_20M_en)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data |= REGBIT(0x1d, 8); /* for 40M or 20M */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data |= REGBIT(0x17, 8); /* for 25M */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (xtal_40M_en) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data |= REGBIT(0x1, 6);  /* for 40M */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0018); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data &= ~(0xf0773f00); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data |= REGBIT(0x3, 28); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data |= REGBIT(0x2, 20); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if ((xtal_40M_en) || (xtal_20M_en)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data |= REGBIT(0x3, 16); /* for 40M or 20M */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data |= REGBIT(0x2, 16); /* for 25M */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data |= REGBIT(0x3, 12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if ((xtal_40M_en) || (xtal_20M_en)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data |= REGBIT(0xd, 8);	/* for 40M or 20M */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data |= REGBIT(0x7, 8);	/* for 25M */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        if((index==1)|(index==4)|(index==7)|(index==9))// 270 MHz for 22.05K, 44.1K, 88.2K, 176.4K 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if ((xtal_40M_en) || (xtal_20M_en)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++         	       	i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x1a18548a); /* for 40M or 20M */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                	i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x14ad106e); /* for 25M */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        else if ((index==0)|(index==3)|(index==5)|(index==6)|(index==8)|(index==10))// 294 MHZ for 24K, 48K, 96K, 192K 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if ((xtal_40M_en) || (xtal_20M_en)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                	i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x1c7dbf48); /* for 40M or 20M */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                	i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x1697cc39); /* for 25M */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else if (index==2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		_printk("Not support 12KHz sampling rate!\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                _printk("Wrong sampling rate!\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        //*Common setting - Set PLLGP_CTRL_4 *// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* 1. Bit 31 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data &= ~(REGBIT(0x1, 31)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ndelay(10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        /* 2. Bit 0 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data |= REGBIT(0x1, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	udelay(200); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        /* 3. Bit 3 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data |= REGBIT(0x1, 3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	udelay(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        /* 4. Bit 8 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data |= REGBIT(0x1, 8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ndelay(40); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        /* 5. Bit 6 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data |= REGBIT(0x1, 6); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ndelay(40); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        /* 6. Bit 5 & Bit 7*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data |= REGBIT(0x1, 5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x1, 7); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	udelay(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        /* 7. Bit 17 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data |= REGBIT(0x1, 17); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_I2S_MCLK_12MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	_printk("MT7621 provide 12MHz REFCLK\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* Firstly, reset all required register to default value */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, 0x01401d61);//0x01401d61); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, 0x80120004);//0x80100004); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, 0x38233d0e); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (xtal_40M_en) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data &= ~REGBIT(0x1, 17); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data &= ~REGBIT(0x3, 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data |= REGBIT(0x1, 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data &= ~REGBIT(0x1, 31); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else if (xtal_20M_en) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data &= ~REGBIT(0x1, 17); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data &= ~REGBIT(0x3, 6); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data &= ~REGBIT(0x3, 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data |= REGBIT(0x1, 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data &= ~REGBIT(0x1, 31); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data &= ~REGBIT(0x1, 17); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data &= ~REGBIT(0x7f, 8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data |= REGBIT(0x17, 8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data &= ~REGBIT(0x3, 6); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0018); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data &= ~REGBIT(0x7, 16); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data |= REGBIT(0x2, 16); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0018); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data &= ~REGBIT(0xf, 8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data |= REGBIT(0x7, 8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data &= ~REGBIT(0x3, 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data |= REGBIT(0x1, 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data &= ~REGBIT(0x1, 31); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_IN_MCLK) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_pll_refclk_set(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* Set APLL register for REFCLK */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data = i2s_inw(RALINK_SYSCTL_BASE+0x90); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data &= ~(0x0000f000); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data |= REGBIT(0x1, 12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        i2s_outw(RALINK_SYSCTL_BASE+0x0090, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data = i2s_inw(RALINK_SYSCTL_BASE+0x0090); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data &= ~(0x00000300); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        i2s_outw(RALINK_SYSCTL_BASE+0x0090, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        MSG("Set 0x90 register\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef MT7623_ASIC_BOARD 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_pll_config_mt7623(unsigned long index) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* xPLL PWR ON */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(AUD2PLL_PWR_CON0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= 0x1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(AUD2PLL_PWR_CON0, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	udelay(5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* xPLL ISO Disable */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(AUD2PLL_PWR_CON0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(AUD2PLL_PWR_CON0, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* xPLL Frequency Set */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(AUD2PLL_CON0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= 0x1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(AUD2PLL_CON0, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* AUD1PLL Frequency Set(change from 98.304MHz to 294.912MHz) */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(AUD1PLL_CON0, 0x121); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(AUD1PLL_CON1, 0xad5efee6); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	udelay(40); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* Audio clock setting */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if((index==1)|(index==4)|(index==7)|(index==9)|(index==11))// for 22.05K, 44.1K, 88.2K, 176.4K 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		_printk("\n*****%s:index=%d(270MHz)*****\n", __func__, (int)index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(0xFB00002c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//data &= ~REGBIT(0x8, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data &= ~(0x80); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_outw(0xFB00002C, data); /* AUD1PLL 270.9204MHz */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	}	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else if ((index==0)|(index==3)|(index==5)|(index==6)|(index==8)|(index==10)|(index==12)) //for 24K, 48K, 96K, 192K 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		_printk("\n*****%s:index=%d(294MHz)*****\n", __func__, (int)index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(0xFB00002c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//data |= REGBIT(0x8, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	data |= (0x80); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_outw(0xFB00002c, data); /* AUD1PLL 294.912MHz */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else if (index==2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		_printk("Not support 12KHz sampling rate!\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                _printk("Wrong sampling rate!\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(MT7628_ASIC_BOARD) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_driving_strength_adjust(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(MT7628_ASIC_BOARD) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        MSG("Adjust MT7628 current's driving strngth\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        /* Adjust REFCLK0's driving strength of current which can avoid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++         * the glitch of REFCKL0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++         * E4 = 0xb0001354[5]; E8 = 0xb0001364[5] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++         * (E4,E8)=(0,0)-> 4 mA; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++         *        =(1,0)-> 8 mA; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++         *        =(0,1)-> 12 mA; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++         *        =(1,1)-> 16 mA*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        /* Set to 12mA */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data = i2s_inw(0xb0001354); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data &= ~(0x1<<5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        i2s_outw(0xb0001354, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data = i2s_inw(0xb0001364); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data |= (0x1<<5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        i2s_outw(0xb0001364, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("Adjust MT7623 current's driving strngth\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(0xF0005F80, 0x7777); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_IN_MCLK) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MCLK_12MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_refclk_12m_enable(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("Enable SoC MCLK 12Mhz\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT6855A) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x860); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0x1<<17); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x7<<18); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0x1<<18); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x860, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_RT3350) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x2c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0x1<<8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x2c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_RT3883) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x2c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x03<<13); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0x1<<13);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x2c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_RT3352)||defined(CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x2c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x0F<<8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0x3<<8);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x2c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_MT7620) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x2c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x07<<9); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	data |= (1<<9); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x2c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_MT7621) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x2c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x1f<<18); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x19, 18); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x1f<<12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x1, 12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x7<<9); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x5, 9); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x2c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_MT7628) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x2c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("turn on REFCLK output for MCLK1\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x7<<9); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0x1<<9);  /* output for MCLK */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x2c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	#error "This SoC does not provide 12MHz clock to audio codec\n");	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_refclk_gpio_out_config(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MCLK_12P288MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_refclk_12p288m_enable(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("Enable SoC MCLK 12.288Mhz\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT3352)||defined(CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x2c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x01F<<18); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= 31<<18; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x01F<<12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= 1<<12; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0xF<<8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x2c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_MT7621) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x2c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x1f<<18); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0xc, 18); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x1f<<12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x1, 12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x7<<9); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x5, 9); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x2c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	_printk("MT7621 provide REFCLK 12.288MHz/11.289MHz\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* MT7623 does not need to set divider for REFCLK */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* GPIO126 - I2S0_MCLK */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(0xF00058F0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x7<<3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0x6<<3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(0xF00058F0, data);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* GPIO_DIR8: OUT */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(0xF0005070); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0x1<<14); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(0xF0005070, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	#error "This SoC does not provide 12.288Mhz clock to audio codec\n");	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MCLK_18P432MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_refclk_18p432m_enable(unsigned long index) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("Enable SoC MCLK 18.432MHz/16.934MHz"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if((index==1)|(index==4)|(index==7)|(index==9))// 16.934MHz for 22.05K, 44.1K, 88.2K, 176.4K 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(ETHDMASYS_SYSCTL_BASE+0x2c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data &= ~(0x1<<7); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_outw(ETHDMASYS_SYSCTL_BASE+0x2c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else if((index==0)|(index==3)|(index==5)|(index==6)|(index==8)|(index==10))// 18.432MHZ for 24K, 48K, 96K, 192K 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(ETHDMASYS_SYSCTL_BASE+0x2c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data |= (0x1<<7); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_outw(ETHDMASYS_SYSCTL_BASE+0x2c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(ETHDMASYS_SYSCTL_BASE+0x30); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0x1<<17); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(ETHDMASYS_SYSCTL_BASE+0x30, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_refclk_disable(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT6855A) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	data = i2s_inw(RALINK_SYSCTL_BASE+0x860); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(1<<17); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x860, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_RT3350) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x2c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x1<<8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x2c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_RT3883) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x2c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 data &= ~(0x0F<<13);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_RT3352)||defined(CONFIG_RALINK_RT5350)||defined (CONFIG_RALINK_RT6855) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x2c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x0F<<8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x2c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined (CONFIG_RALINK_MT7620)||defined (CONFIG_RALINK_MT7621)||defined (CONFIG_RALINK_MT7628)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	_printk("turn off REFCLK output from internal CLK\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x2c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x07<<9); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x2c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined (CONFIG_ARCH_MT7623) /*FIXME:2*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef MT7623_ASIC_BOARD 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	_printk("turn off REFCLK output from internal CLK\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* GPIO126 - I2S0_MCLK */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data = i2s_inw(0xF00058F0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        data &= ~(0x7<<3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//data |= (0x2<<3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        i2s_outw(0xF00058F0, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* GPIO126 => GPIO_DIR8: IN */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(0xF0005070); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x1<<14); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(0xF0005070, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	_printk("turn off REFCLK output from internal CLK\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(ETHDMASYS_SYSCTL_BASE+0x30); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x1<<17); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(ETHDMASYS_SYSCTL_BASE+0x30, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_refclk_gpio_out_config(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifndef CONFIG_ARCH_MT7623 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; /* FIXME */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* Set REFCLK GPIO pin as REFCLK mode*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7620) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x60); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	data &= ~(0x03<<21);  /* WDT */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	data |= (1<<21); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//data &= ~(0x03<<16);  /* PERST */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//data |= (1<<16); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	i2s_outw(RALINK_SYSCTL_BASE+0x60, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7621) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x60); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//data &= ~(0x3<<10); /* PERST */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//data |= (0x2<<10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x3<<8); /* WDT */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0x2<<8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x60, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("Set 0x60 register\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7628) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x60); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x1<<18); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x60, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_refclk_gpio_in_config(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifndef CONFIG_ARCH_MT7623 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; /* FIXME */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_MT7620) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x60); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	data &= ~(0x03<<21);  /* WDT */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	data |= (1<<21); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//data &= ~(0x03<<16);  /* PERST */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//data |= (1<<16); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	i2s_outw(RALINK_SYSCTL_BASE+0x60, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_PIO_BASE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x1<<17); /* GPIO share ping 17 for WDT */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_PIO_BASE, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//data = i2s_inw(RALINK_PIO_BASE+0x04); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//data &= ~(0x1<<4); /* GPIO share ping 36 for PERST */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//i2s_outw(RALINK_PIO_BASE+0x04, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_MT7621) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x60); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//data &= ~(0x3<<10); /* PERST */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//data |= (0x1<<10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x3<<8); /* WDT */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0x1<<8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x60, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_PIO_BASE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//data &= ~(0x1<<19); /* GPIO share ping 19 for RERST */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x1<<18); /* GPIO share ping 18 for WDT */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_PIO_BASE, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_MT7628) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* To use external OSC, set REFCLK_GPIO ping as GPIO mode and set it as input direction */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x60); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0x1<<18); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x60, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_PIO_BASE+0x04); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x1<<5); /* GPIO share ping 37*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_PIO_BASE+0x04, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_slave_clock_gpio_in_mt7623(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* GPIO74(I2S0_BCLK)=>GPIO_DIR5: IN */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(0xF0005040); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x1<<10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(0xF0005040, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* GPIO73(I2S0_LRCK)=>GPIO_DIR5: IN */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(0xF0005040); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x1<<9); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(0xF0005040, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	_printk("i2s_slave_clock_gpio_in_mt7623\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_master_clock_gpio_out_mt7623(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* GPIO74(I2S0_BCLK)=>GPIO_DIR5: OUT */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(0xF0005040); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0x1<<10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(0xF0005040, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* GPIO73(I2S0_LRCK)=>GPIO_DIR5: OUT */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(0xF0005040); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0x1<<9); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(0xF0005040, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	_printk("i2s_master_clock_gpio_out_mt7623\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_share_pin_mt7623(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	_printk("\nConfig MT7623 I2S pinmux\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* GPIO74 - I2S0_BCLK */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(0xF0005840); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x7<<12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0x6<<12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(0xF0005840, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* GPIO73 - I2S0_LRCK */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(0xF0005840); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x7<<9); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0x6<<9); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(0xF0005840, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(ptri2s_config->slave_en==0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_master_clock_gpio_out_mt7623(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_slave_clock_gpio_in_mt7623(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* GPIO49 - I2S0_DATA */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(0xF00057F0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x7<<12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0x6<<12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(0xF00057F0, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* GPIO_DIR4: OUT */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(0xF0005030); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0x1<<1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(0xF0005030, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* GPIO72 - I2S0_DATA_IN */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(0xF0005840); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x7<<6); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (0x6<<6); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(0xF0005840, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* GPIO_DIR5: IN */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(0xF0005040); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x1<<8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(0xF0005040, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_share_pin_config(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifndef CONFIG_ARCH_MT7623 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; /*FIXME*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* set share pins to i2s/gpio mode and i2c mode */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT6855A) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x860); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= 0x00008080; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x860, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_MT7621)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x60);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= 0xFFFFFFE3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= 0x00000010; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x60, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_MT7628)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x60);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x3<<6);    /* I2S_MODE */  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(0x3<<20);   /* I2C_MODE */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x60, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_share_pin_mt7623(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x60);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= 0xFFFFFFE2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= 0x00000018; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x60, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_ws_config(i2s_config_type* ptri2s_config, unsigned long index) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long* pTable; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_IN_CLK) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* REFCLK is 15.625Mhz or 40Mhz(fractional division) */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_FRAC_DIV) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("Internal REFCLK with fractional division\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (ptri2s_config->wordlen_24b == 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("24 bit int table\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pTable = i2s_inclk_int_24bit; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("16 bit int table\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pTable = i2s_inclk_int_16bit; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pTable = i2s_inclk_int; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif /* CONFIG_RALINK_MT7628 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = (unsigned long)(pTable[index]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(I2S_DIVINT_CFG, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (ptri2s_config->wordlen_24b == 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("24 bit comp table\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pTable = i2s_inclk_comp_24bit; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("16 bit comp table\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pTable = i2s_inclk_comp_16bit; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pTable = i2s_inclk_comp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	/* CONFIG_RALINK_MT7628 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = (unsigned long)(pTable[index]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(1, I2S_CLKDIV_EN);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(I2S_DIVCOMP_CFG, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("Internal REFCLK 15.625Mhz \n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pTable = i2s_inclk_15p625Mhz; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x30);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= 0xFFFF00FF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (unsigned long)(pTable[index]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= 0x00008000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x30, data);   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif /* CONFIG_I2S_FRAC_DIV */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MCLK_12MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* REFCLK = MCLK = 12Mhz */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("External REFCLK 12Mhz \n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pTable = i2s_exclk_12Mhz; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x30); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= 0xFFFF00FF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (unsigned long)(pTable[index]);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= 0x0000C000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x30, data);  	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* REFCLK = MCLK = 12.288Mhz */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pTable = i2s_exclk_12p288Mhz; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("External REFCLK 12.288Mhz \n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x30); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= 0xFFFF00FF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (unsigned long)(pTable[index]);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= 0x0000C000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x30, data); 					  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif /* CONFIG_I2S_MCLK_12MHZ */		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif /* Not CONFIG_I2S_IN_CLK */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WS_EDGE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(I2S_I2SCFG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x1, I2S_WS_INV); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(I2S_I2SCFG, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_mode_config(u32 slave_en) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(slave_en==0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		/* Master mode*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		_printk("This SoC is in Master mode\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT3052) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(I2S_I2SCFG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data &= ~REGBIT(0x1, I2S_SLAVE_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data &= ~REGBIT(0x1, I2S_CLK_OUT_DIS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_outw(I2S_I2SCFG, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_RT3883)||defined(CONFIG_RALINK_RT3352)||\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	defined(CONFIG_RALINK_RT5350)||defined(CONFIG_RALINK_RT6855)||\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	defined(CONFIG_RALINK_MT7620)||defined(CONFIG_RALINK_RT6855A)||\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	defined(CONFIG_RALINK_MT7621)||defined(CONFIG_RALINK_MT7628)||\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(I2S_I2SCFG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data &= ~REGBIT(0x1, I2S_SLAVE_MODE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_outw(I2S_I2SCFG, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	#error "a strange clock mode"	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		/* Slave mode */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		_printk("This SoC is in Slave mode\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT3052) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(I2S_I2SCFG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data |= REGBIT(0x1, I2S_SLAVE_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data |= REGBIT(0x1, I2S_CLK_OUT_DIS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_outw(I2S_I2SCFG, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_RT3883)||defined(CONFIG_RALINK_RT3352)||\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	defined(CONFIG_RALINK_RT5350)||defined(CONFIG_RALINK_RT6855)||\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	defined(CONFIG_RALINK_MT7620)||defined(CONFIG_RALINK_RT6855A)||\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	defined(CONFIG_RALINK_MT7621)||defined(CONFIG_RALINK_MT7628)||\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data = i2s_inw(I2S_I2SCFG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data |= REGBIT(0x1, I2S_SLAVE_MODE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_outw(I2S_I2SCFG, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#error "a strange clock mode "	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_codec_frequency_config(i2s_config_type* ptri2s_config, unsigned long index) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long* pTable; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MCLK_12MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pTable = i2s_codec_12Mhz; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = pTable[index]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	audiohw_set_frequency(data, ptri2s_config->codec_pll_en); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	audiohw_set_frequency(data|0x01); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(MT7623_FPGA_BOARD) && defined(CONFIG_I2S_WM8750) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pTable = i2s_codec_18p432Mhz; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pTable = i2s_codec_12p288Mhz; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = pTable[index]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	audiohw_set_frequency(data, ptri2s_config->codec_pll_en); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	audiohw_set_frequency(data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  Ralink Audio System Clock Enable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  I2S_WS : signal direction opposite to/same as I2S_CLK  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  I2S_CLK : Integer division or fractional division 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *			  REFCLK from Internal or External (external REFCLK not support for fractional division) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *			  Suppose external REFCLK always be the same as external MCLK 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  MCLK : External OSC or internal generation 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_clock_enable(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long index; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* audio sampling rate decision */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	switch(ptri2s_config->srate) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		case 8000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			index = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		case 11025: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			index = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		case 12000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			index = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break;			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		case 16000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			index = 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		case 22050: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			index = 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	case 24000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			index = 5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		case 32000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			index = 6; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break;			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		case 44100: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			index = 7; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		case 48000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			index = 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		case 88200: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			index = 9; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		case 96000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			index = 10; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		case 176000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			index = 11; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		case 192000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			index = 12; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			index = 7; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef MT7621_ASIC_BOARD 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        /* Set pll config  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        i2s_pll_config_mt7621(index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef MT7623_ASIC_BOARD 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        /* Set pll config  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        i2s_pll_config_mt7623(index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* enable internal MCLK */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_IN_MCLK) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7621) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_pll_refclk_set(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MCLK_12MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(MT7628_ASIC_BOARD) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        i2s_driving_strength_adjust(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_refclk_12m_enable(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif /* MCLK_12MHZ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MCLK_12P288MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_refclk_12p288m_enable(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif /* MCLK_12P288MHZ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MCLK_18P432MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_refclk_18p432m_enable(index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_refclk_gpio_out_config(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("Disable SoC MCLK, use external OSC\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_refclk_disable(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_refclk_gpio_in_config(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif /* CONFIG_I2S_IN_MCLK */	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_share_pin_config(ptri2s_config);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(ptri2s_config->slave_en==0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		/* Setup I2S_WS and I2S_CLK */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_ws_config(ptri2s_config, index);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_mode_config(ptri2s_config->slave_en); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(!ptri2s_config->bALSAEnable) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)|| defined(CONFIG_I2S_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_codec_enable(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_codec_frequency_config(ptri2s_config,index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_clock_disable(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(!ptri2s_config->bALSAEnable) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_codec_disable(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* disable internal MCLK */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_IN_MCLK)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_refclk_disable(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_refclk_gpio_in_config(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_codec_enable(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int AIn = 0, AOut = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* Codec initialization */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	audiohw_preinit(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(ptri2s_config->codec_pll_en) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("Codec PLL EN = %d\n", pi2s_config->codec_pll_en); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		audiohw_set_apll(ptri2s_config->srate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_TXRX)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if((ptri2s_config->bTxDMAEnable) || (ptri2s_config->txrx_coexist)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		AOut = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if((ptri2s_config->bRxDMAEnable) || (ptri2s_config->txrx_coexist)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		AIn = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	audiohw_postinit(!(ptri2s_config->slave_en), AIn, AOut, ptri2s_config->codec_pll_en, ptri2s_config->wordlen_24b); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	audiohw_micboost(ptri2s_config->micboost);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	audiohw_micin(ptri2s_config->micin); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_I2S_WM8750) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	audiohw_postinit(!(ptri2s_config->slave_en), AIn, AOut, ptri2s_config->wordlen_24b); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("AOut=%d, AIn=%d\n", AOut, AIn); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8750) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	audiohw_postinit(!(ptri2s_config->slave_en), 0, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_I2S_WM8960)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	audiohw_postinit(!(ptri2s_config->slave_en), 1, 1, ptri2s_config->codec_pll_en); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_I2S_WM8751)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(ptri2s_config->slave_en==0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		audiohw_postinit(1,1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		audiohw_postinit(0,1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_codec_disable(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	audiohw_close(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_reset_config(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* RESET bit: write 1 clear */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT6855A) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x834); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (1<<17); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x834, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x834); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(1<<17); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x834, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(0xFB000000+0x34); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (1<<17); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(0xFB000000+0x34, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(0xFB000000+0x34); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(1<<17); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(0xFB000000+0x34, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x34); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (1<<17); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x34, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x34); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(1<<17); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x34, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if 0  /* Reset GDMA */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x34); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= (1<<14); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x34, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(RALINK_SYSCTL_BASE+0x34); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~(1<<14); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(RALINK_SYSCTL_BASE+0x34, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	_printk("I2S reset complete!!\n");	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_tx_config(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* set I2S_I2SCFG */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(I2S_I2SCFG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= 0xFFFFFF81; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(ptri2s_config->tx_ff_thres, I2S_TX_FF_THRES); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(ptri2s_config->tx_ch_swap, I2S_TX_CH_SWAP); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT6855A)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(1, I2S_BYTE_SWAP); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("TX:wordLen=%d, sysEndian=%d\n", ptri2s_config->wordlen_24b, ptri2s_config->sys_endian); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(ptri2s_config->wordlen_24b, I2S_DATA_24BIT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(ptri2s_config->sys_endian, I2S_SYS_ENDIAN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(ptri2s_config->little_edn, I2S_LITTLE_ENDIAN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~REGBIT(1, I2S_TX_CH0_OFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~REGBIT(1, I2S_TX_CH1_OFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(I2S_I2SCFG, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* set I2S_I2SCFG1 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("internal loopback: %d\n", ptri2s_config->lbk); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(I2S_I2SCFG1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(ptri2s_config->lbk, I2S_LBK_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(ptri2s_config->extlbk, I2S_EXT_LBK_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= 0xFFFFFFFC; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(ptri2s_config->fmt, I2S_DATA_FMT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(I2S_I2SCFG1, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_rx_config(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* set I2S_I2SCFG */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(I2S_I2SCFG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= 0xFFFF81FF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(ptri2s_config->rx_ff_thres, I2S_RX_FF_THRES); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(ptri2s_config->rx_ch_swap, I2S_RX_CH_SWAP); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~REGBIT(1, I2S_RX_CH0_OFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~REGBIT(1, I2S_RX_CH1_OFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("RX:wordLen=%d, sysEndian=%d\n", ptri2s_config->wordlen_24b, ptri2s_config->sys_endian); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(ptri2s_config->wordlen_24b, I2S_DATA_24BIT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(ptri2s_config->sys_endian, I2S_SYS_ENDIAN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(ptri2s_config->little_edn, I2S_LITTLE_ENDIAN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(I2S_I2SCFG, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* set I2S_I2SCFG1 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(I2S_I2SCFG1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(ptri2s_config->lbk, I2S_LBK_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(ptri2s_config->extlbk, I2S_EXT_LBK_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= 0xFFFFFFFC; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(ptri2s_config->fmt, I2S_DATA_FMT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(I2S_I2SCFG1, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* Turn On Tx DMA and INT */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_tx_enable(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(I2S_HW_INTERRUPT_EN)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(I2S_INT_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x1, I2S_TX_INT3_EN);  /* FIFO DMA fault */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x1, I2S_TX_INT2_EN);  /* FIFO overrun */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x1, I2S_TX_INT1_EN);  /* FIFO underrun */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x1, I2S_TX_INT0_EN);  /* FIFO below threshold */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(I2S_INT_EN, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(I2S_I2SCFG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_TXRX)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x1, I2S_TX_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x1, I2S_DMA_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(I2S_I2SCFG, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(I2S_I2SCFG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x1, I2S_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(I2S_I2SCFG, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("i2s_tx_enable done\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return I2S_OK; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* Turn On Rx DMA and INT */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_rx_enable(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(I2S_HW_INTERRUPT_EN)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(I2S_INT_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x1, I2S_RX_INT3_EN);  /* FIFO DMA fault */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x1, I2S_RX_INT2_EN);  /* FIFO overrun */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x1, I2S_RX_INT1_EN);  /* FIFO underrun */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x1, I2S_RX_INT0_EN);  /* FIFO below threshold */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(I2S_INT_EN, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(I2S_I2SCFG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_TXRX)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x1, I2S_RX_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x1, I2S_DMA_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(I2S_I2SCFG, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(I2S_I2SCFG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data |= REGBIT(0x1, I2S_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(I2S_I2SCFG, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("i2s_rx_enable done\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return I2S_OK; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* Turn Off Tx DMA and INT */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_tx_disable(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(I2S_HW_INTERRUPT_EN)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(I2S_INT_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~REGBIT(0x1, I2S_TX_INT3_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~REGBIT(0x1, I2S_TX_INT2_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~REGBIT(0x1, I2S_TX_INT1_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~REGBIT(0x1, I2S_TX_INT0_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(I2S_INT_EN, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(I2S_I2SCFG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_TXRX)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~REGBIT(0x1, I2S_TX_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(ptri2s_config->bRxDMAEnable==0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->bTxDMAEnable = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data &= ~REGBIT(0x1, I2S_DMA_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                data &= ~REGBIT(0x1, I2S_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(I2S_I2SCFG, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return I2S_OK; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* Turn Off Rx DMA and INT */	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_rx_disable(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(I2S_HW_INTERRUPT_EN)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(I2S_INT_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~REGBIT(0x1, I2S_RX_INT3_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~REGBIT(0x1, I2S_RX_INT2_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~REGBIT(0x1, I2S_RX_INT1_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~REGBIT(0x1, I2S_RX_INT0_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(I2S_INT_EN, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = i2s_inw(I2S_I2SCFG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_TXRX)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data &= ~REGBIT(0x1, I2S_RX_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(ptri2s_config->bTxDMAEnable==0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->bRxDMAEnable = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		data &= ~REGBIT(0x1, I2S_DMA_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                data &= ~REGBIT(0x1, I2S_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(I2S_I2SCFG, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return I2S_OK; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_dma_tx_transf_data(i2s_config_type* ptri2s_config, u32 dma_ch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int tx_r_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if ((pi2s_config->bALSAEnable==1) && (pi2s_config->bALSAMMAPEnable==1)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		tx_r_idx = (pi2s_config->tx_r_idx + ALSA_MMAP_IDX_SHIFT)%MAX_I2S_PAGE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		tx_r_idx = pi2s_config->tx_r_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(dma_ch==GDMA_I2S_TX0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MMAP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		dma_sync_single_for_device(NULL,  i2s_mmap_addr[tx_r_idx], I2S_PAGE_SIZE, DMA_TO_DEVICE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                memcpy(pi2s_config->pPage0TxBuf8ptr,  pi2s_config->pMMAPTxBufPtr[tx_r_idx], I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GdmaI2sTx(i2s_txdma_addr0, I2S_TX_FIFO_WREG_PHY, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                GdmaI2sTx((u32)(pi2s_config->pPage0TxBuf8ptr), I2S_TX_FIFO_WREG, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                pi2s_config->dmach = GDMA_I2S_TX0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                pi2s_config->tx_r_idx = (pi2s_config->tx_r_idx+1)%MAX_I2S_PAGE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MMAP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		dma_sync_single_for_device(NULL,  i2s_mmap_addr[tx_r_idx], I2S_PAGE_SIZE, DMA_TO_DEVICE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                memcpy(pi2s_config->pPage1TxBuf8ptr,  pi2s_config->pMMAPTxBufPtr[tx_r_idx], I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GdmaI2sTx(i2s_txdma_addr1, I2S_TX_FIFO_WREG_PHY, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                GdmaI2sTx((u32)(pi2s_config->pPage1TxBuf8ptr), I2S_TX_FIFO_WREG, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                pi2s_config->dmach = GDMA_I2S_TX1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                pi2s_config->tx_r_idx = (pi2s_config->tx_r_idx+1)%MAX_I2S_PAGE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WITH_AEC) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(aecFuncP->AECFeEnq){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		aecFuncP->AECFeEnq(0,pi2s_config->pMMAPTxBufPtr[pi2s_config->tx_r_idx],I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_dma_tx_transf_zero(i2s_config_type* ptri2s_config, u32 dma_ch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(dma_ch==GDMA_I2S_TX0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++         	memset(pi2s_config->pPage0TxBuf8ptr, 0, I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GdmaI2sTx(i2s_txdma_addr0, I2S_TX_FIFO_WREG_PHY, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                GdmaI2sTx((u32)pi2s_config->pPage0TxBuf8ptr, I2S_TX_FIFO_WREG, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                memset(pi2s_config->pPage1TxBuf8ptr, 0, I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GdmaI2sTx(i2s_txdma_addr1, I2S_TX_FIFO_WREG_PHY, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                GdmaI2sTx((u32)pi2s_config->pPage1TxBuf8ptr, I2S_TX_FIFO_WREG, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_dma_rx_transf_data(i2s_config_type* ptri2s_config, u32 dma_ch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int rx_w_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_config->rx_w_idx = (pi2s_config->rx_w_idx+1)%MAX_I2S_PAGE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if ((pi2s_config->bALSAEnable==1) && (pi2s_config->bALSAMMAPEnable==1)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		rx_w_idx = (pi2s_config->rx_w_idx+ALSA_MMAP_IDX_SHIFT)%MAX_I2S_PAGE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		rx_w_idx = (pi2s_config->rx_w_idx)%MAX_I2S_PAGE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(dma_ch==GDMA_I2S_RX0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef CONFIG_I2S_MMAP 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                memcpy(pi2s_config->pMMAPRxBufPtr[rx_w_idx], pi2s_config->pPage0RxBuf8ptr, I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr0, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)(pi2s_config->pPage0RxBuf8ptr), 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                pi2s_config->dmach = GDMA_I2S_RX0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef CONFIG_I2S_MMAP 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                memcpy(pi2s_config->pMMAPRxBufPtr[rx_w_idx], pi2s_config->pPage1RxBuf8ptr, I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr1, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)(pi2s_config->pPage1RxBuf8ptr), 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                pi2s_config->dmach = GDMA_I2S_RX1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WITH_AEC) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(aecFuncP->AECNeEnq){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			aecFuncP->AECNeEnq(0,pi2s_config->pMMAPRxBufPtr[rx_w_idx],I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_dma_rx_transf_zero(i2s_config_type* ptri2s_config, u32 dma_ch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(dma_ch==GDMA_I2S_RX0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        {	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		memset(pi2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr0, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)pi2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++       	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		memset(pi2s_config->pPage1RxBuf8ptr, 0, I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr1, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)pi2s_config->pPage1RxBuf8ptr, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_dma_tx_handler(u32 dma_ch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_config->enLable = 1; /* TX:enLabel=1; RX:enLabel=2 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(pi2s_config->bTxDMAEnable==0)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(pi2s_config->end_cnt != 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_dma_tx_transf_data(pi2s_config, dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pi2s_config->end_cnt --; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	        	MSG("end_cnt = %d, r_idx = %d\n", pi2s_config->end_cnt, pi2s_config->tx_r_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pi2s_config->tx_stop_cnt++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_dma_tx_soft_stop(pi2s_config, dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("tx_stop=%d, ch=%d\n", pi2s_config->tx_stop_cnt, dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			if (pi2s_config->tx_stop_cnt == 3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        	wake_up_interruptible(&(pi2s_config->i2s_tx_qh)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				_printk("T:wake up!!\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_config->tx_isr_cnt++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef 	I2S_STATISTIC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_int_status(dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* FIXME */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(pi2s_config->bALSAEnable) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(pi2s_config->dmaStat[STREAM_PLAYBACK]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			if(!pi2s_config->bTrigger[STREAM_PLAYBACK]){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				//_printk("trigger stop: rIdx:%d widx:%d\n", pi2s_config->tx_r_idx,pi2s_config->tx_w_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                i2s_dma_tx_transf_zero(pi2s_config, dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                if(pi2s_config->bPreTrigger[STREAM_PLAYBACK]){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        /* mtk04880 commented: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                         * for corner case, there are cases which ALSA Trigger stop before disabling DMA. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                         * For which case, it needs to keep call snd_pcm_elapased to keep ALSA hw ptr updating. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                         * It is so called post stop handlment. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                         */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        //_printk("post-stop\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        goto EXIT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        //_printk("pre-stop\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        wake_up_interruptible(&(pi2s_config->i2s_tx_qh)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                if(!pi2s_config->bPreTrigger[STREAM_PLAYBACK]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        pi2s_config->bPreTrigger[STREAM_PLAYBACK] = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		}	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(pi2s_config->tx_r_idx==pi2s_config->tx_w_idx) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			/* Buffer Empty */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef I2S_STATISTIC		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pi2s_status->txbuffer_unrun++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_dma_tx_transf_zero(pi2s_config, dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			goto EXIT;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(pi2s_config->pMMAPTxBufPtr[pi2s_config->tx_r_idx]==NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("mmap buf NULL [%d]\n",pi2s_config->tx_r_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_dma_tx_transf_zero(pi2s_config, dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		goto EXIT;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(pi2s_config->tx_pause_en == 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		/* Enable PAUSE */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("TX pause now\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_dma_tx_transf_zero(pi2s_config, dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		goto EXIT;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef I2S_STATISTIC	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_status->txbuffer_len--; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_dma_tx_transf_data(pi2s_config, dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXIT: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_SND_MT76XX_SOC) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(pi2s_config->bALSAEnable == 1){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(pi2s_config->pss[STREAM_PLAYBACK]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			snd_pcm_period_elapsed(pi2s_config->pss[STREAM_PLAYBACK]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	wake_up_interruptible(&(pi2s_config->i2s_tx_qh));		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_dma_rx_handler(u32 dma_ch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_config->enLable = 2; /* TX:enLabel=1; RX:enLabel=2 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_TXRX) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(pi2s_config->rx_isr_cnt==0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pi2s_config->next_p0_idx = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pi2s_config->next_p1_idx = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	}	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_config->rx_isr_cnt++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef  I2S_STATISTIC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_int_status(dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (pi2s_config->bRxDMAEnable==0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pi2s_config->rx_stop_cnt++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_dma_rx_soft_stop(pi2s_config, dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("rx_stop=%d\n", pi2s_config->rx_stop_cnt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(pi2s_config->rx_stop_cnt == 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			wake_up_interruptible(&(pi2s_config->i2s_rx_qh)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			_printk("R:wake up!!\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(pi2s_config->bALSAEnable) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 if(pi2s_config->dmaStat[STREAM_CAPTURE]){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			if(!pi2s_config->bTrigger[STREAM_CAPTURE]){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                MSG("trigger stop: rIdx:%d widx:%d\n", pi2s_config->rx_r_idx,pi2s_config->rx_w_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				i2s_dma_rx_transf_zero(pi2s_config, dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                wake_up_interruptible(&(pi2s_config->i2s_rx_qh)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(((pi2s_config->rx_w_idx+1)%MAX_I2S_PAGE)==pi2s_config->rx_r_idx){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			/* Buffer Full */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef I2S_STATISTIC		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pi2s_status->rxbuffer_unrun++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_dma_rx_transf_zero(pi2s_config, dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			goto EXIT;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(pi2s_config->rx_pause_en == 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		/* Enable PAUSE */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_dma_rx_transf_zero(pi2s_config, dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		goto EXIT;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef I2S_STATISTIC	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_status->rxbuffer_len++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_dma_rx_transf_data(pi2s_config, dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXIT: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_SND_MT76XX_SOC) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(pi2s_config->bALSAEnable == 1){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(pi2s_config->pss[STREAM_CAPTURE]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			snd_pcm_period_elapsed(pi2s_config->pss[STREAM_CAPTURE]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	wake_up_interruptible(&(pi2s_config->i2s_rx_qh)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef I2S_STATISTIC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_int_status(u32 dma_ch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 i2s_status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if((pi2s_config->tx_isr_cnt>0)||(pi2s_config->rx_isr_cnt>0)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_status = i2s_inw(I2S_INT_STATUS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(i2s_status®BIT(1, I2S_TX_DMA_FAULT)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pi2s_status->txdmafault++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(i2s_status®BIT(1, I2S_TX_OVRUN)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pi2s_status->txovrun++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(i2s_status®BIT(1, I2S_TX_UNRUN)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pi2s_status->txunrun++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(i2s_status®BIT(1, I2S_TX_THRES)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pi2s_status->txthres++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(i2s_status®BIT(1, I2S_RX_DMA_FAULT)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pi2s_status->rxdmafault++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(i2s_status®BIT(1, I2S_RX_OVRUN)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pi2s_status->rxovrun++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(i2s_status®BIT(1, I2S_RX_UNRUN)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pi2s_status->rxunrun++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(i2s_status®BIT(1, I2S_RX_THRES)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pi2s_status->rxthres++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(pi2s_config->enLable == 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if((pi2s_config->tx_isr_cnt>0) && (pi2s_config->tx_isr_cnt%40==0)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("tisr i=%u,ch=%u,o=%u,u=%d,s=%X [r=%d,w=%d]\n",\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				pi2s_config->tx_isr_cnt,dma_ch,pi2s_status->txovrun,pi2s_status->txunrun,\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				i2s_inw(I2S_INT_STATUS),pi2s_config->tx_r_idx,pi2s_config->tx_w_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(pi2s_config->enLable == 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if((pi2s_config->rx_isr_cnt>0) && (pi2s_config->rx_isr_cnt%40==0)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("risr i=%u,ch=%u,o=%u,u=%d,s=%X [r=%d,w=%d]\n",\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				pi2s_config->rx_isr_cnt,dma_ch,pi2s_status->rxovrun,pi2s_status->rxunrun,\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				i2s_inw(I2S_INT_STATUS),pi2s_config->rx_r_idx,pi2s_config->rx_w_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	*(unsigned long*)(I2S_INT_STATUS) = 0xFFFFFFFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(I2S_HW_INTERRUPT_EN)&&(I2S_SW_IRQ_EN) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++irqreturn_t i2s_irq_isr(int irq, void *irqaction) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 i2s_status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//MSG("i2s_irq_isr [0x%08X]\n",i2s_inw(I2S_INT_STATUS)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if((pi2s_config->tx_isr_cnt>0)||(pi2s_config->rx_isr_cnt>0)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_status = i2s_inw(I2S_INT_STATUS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("i2s_irq_isr [0x%08X]\n",i2s_status); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return IRQ_HANDLED; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(i2s_status®BIT(1, I2S_TX_DMA_FAULT)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef I2S_STATISTIC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pi2s_status->txdmafault++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(i2s_status®BIT(1, I2S_TX_OVRUN)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef I2S_STATISTIC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pi2s_status->txovrun++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(i2s_status®BIT(1, I2S_TX_UNRUN)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef I2S_STATISTIC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pi2s_status->txunrun++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(i2s_status®BIT(1, I2S_TX_THRES)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef I2S_STATISTIC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pi2s_status->txthres++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(i2s_status®BIT(1, I2S_RX_DMA_FAULT)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef I2S_STATISTIC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pi2s_status->rxdmafault++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(i2s_status®BIT(1, I2S_RX_OVRUN)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef I2S_STATISTIC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pi2s_status->rxovrun++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(i2s_status®BIT(1, I2S_RX_UNRUN)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef I2S_STATISTIC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pi2s_status->rxunrun++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(i2s_status®BIT(1, I2S_RX_THRES)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef I2S_STATISTIC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pi2s_status->rxthres++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_outw(I2S_INT_STATUS, 0xFFFFFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return IRQ_HANDLED; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_tx_task(unsigned long pData) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long flags; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	spin_lock_irqsave(&pi2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//if (pi2s_config->bTxDMAEnable!=0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if (pi2s_config->tx_unmask_ch!=0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			u32 dmach = pi2s_config->tx_unmask_ch; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			u32 ch; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			for (ch = 0; ch < 16; ch++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				if (dmach& (1<<ch)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					MSG("do unmask ch%d tisr=%d in tx_isr\n",ch,pi2s_config->tx_isr_cnt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					GdmaUnMaskChannel(ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				}	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pi2s_config->tx_unmask_ch = 0;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	}	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	spin_unlock_irqrestore(&pi2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_rx_task(unsigned long pData) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long flags; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	spin_lock_irqsave(&pi2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//if (pi2s_config->bRxDMAEnable!=0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if (pi2s_config->rx_unmask_ch!=0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			u32 dmach = pi2s_config->rx_unmask_ch; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			u32 ch; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			for (ch = 0; ch < 16; ch++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				if (dmach& (1<<ch)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					MSG("do unmask ch%d risr=%d in rx_isr\n",ch,pi2s_config->rx_isr_cnt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					GdmaUnMaskChannel(ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				}	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pi2s_config->rx_unmask_ch = 0;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	}	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	spin_unlock_irqrestore(&pi2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_dma_unmask_handler(u32 dma_ch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("i2s_dma_unmask_handler ch=%d\n",dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	GdmaUnMaskChannel(dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_dma_tx_unmask_handler(u32 dma_ch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("i2s_dma_tx_unmask_handler ch=%d\n",dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_config->tx_unmask_ch |= (1<<dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	tasklet_hi_schedule(&i2s_tx_tasklet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_dma_rx_unmask_handler(u32 dma_ch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	MSG("i2s_dma_rx_unmask_handler ch=%d\n",dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_config->rx_unmask_ch |= (1<<dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	tasklet_hi_schedule(&i2s_rx_tasklet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_dma_mask_handler(u32 dma_ch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        MSG("i2s_dma_mask_handler ch=%d\n", dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        GdmaMaskChannel(dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_dma_tx_init(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	memset(pi2s_config->pPage0TxBuf8ptr, 0, I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	memset(pi2s_config->pPage1TxBuf8ptr, 0, I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	GdmaI2sTx(i2s_txdma_addr0, I2S_TX_FIFO_WREG_PHY, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	GdmaI2sTx(i2s_txdma_addr1, I2S_TX_FIFO_WREG_PHY, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	GdmaI2sTx((u32)ptri2s_config->pPage0TxBuf8ptr, I2S_FIFO_WREG, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	GdmaI2sTx((u32)ptri2s_config->pPage1TxBuf8ptr, I2S_FIFO_WREG, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_dma_rx_init(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	memset(pi2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	memset(pi2s_config->pPage1RxBuf8ptr, 0, I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr0, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr1, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)ptri2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)ptri2s_config->pPage1RxBuf8ptr, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_dma_tx_end_handle(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (ptri2s_config->tx_w_idx < ptri2s_config->tx_r_idx) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	ptri2s_config->end_cnt = (ptri2s_config->tx_w_idx + MAX_I2S_PAGE)-ptri2s_config->tx_r_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                _printk("case1: w=%d, r=%d, end=%d\n", ptri2s_config->tx_w_idx, ptri2s_config->tx_r_idx, ptri2s_config->end_cnt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        else if (ptri2s_config->tx_w_idx > ptri2s_config->tx_r_idx) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                ptri2s_config->end_cnt = ptri2s_config->tx_w_idx-ptri2s_config->tx_r_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                _printk("case2: w=%d, r=%d, end=%d\n", ptri2s_config->tx_w_idx, ptri2s_config->tx_r_idx, ptri2s_config->end_cnt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		_printk("case3: w=%d, r=%d, end=%d\n", ptri2s_config->tx_w_idx, ptri2s_config->tx_r_idx, ptri2s_config->end_cnt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (ptri2s_config->end_cnt > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		interruptible_sleep_on(&(ptri2s_config->i2s_tx_qh)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_tx_end_sleep_on(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	while(ptri2s_config->tx_stop_cnt<3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		interruptible_sleep_on(&(ptri2s_config->i2s_tx_qh)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_rx_end_sleep_on(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	while(ptri2s_config->rx_stop_cnt<2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		interruptible_sleep_on(&(ptri2s_config->i2s_rx_qh)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_dma_tx_soft_stop(i2s_config_type* ptri2s_config, u32 dma_ch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(dma_ch==GDMA_I2S_TX0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GdmaI2sTx(i2s_txdma_addr0, I2S_TX_FIFO_WREG_PHY, 0, 4, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GdmaI2sTx((u32)pi2s_config->pPage0TxBuf8ptr, I2S_TX_FIFO_WREG, 0, 4, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GdmaI2sTx(i2s_txdma_addr1, I2S_TX_FIFO_WREG_PHY, 1, 4, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                GdmaI2sTx((u32)pi2s_config->pPage1TxBuf8ptr, I2S_TX_FIFO_WREG, 1, 4, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_dma_rx_soft_stop(i2s_config_type* ptri2s_config, u32 dma_ch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(dma_ch==GDMA_I2S_RX0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		memset(pi2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr0, 0, 4, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)pi2s_config->pPage0RxBuf8ptr, 0, 4, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		memset(pi2s_config->pPage1RxBuf8ptr, 0, I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(ARM_ARCH) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr1, 1, 4, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)pi2s_config->pPage1RxBuf8ptr, 1, 4, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_gen_test_pattern(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	for (i=0; i<I2S_PAGE_SIZE; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		test_buf[i] = 0x5A; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		test_buf_1[i] = 0x11; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		test_buf_2[i] = 0x22; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_put_audio(i2s_config_type* ptri2s_config, unsigned long arg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long flags; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int tx_w_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	do{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(((ptri2s_config->tx_w_idx+4)%MAX_I2S_PAGE)!=ptri2s_config->tx_r_idx) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->tx_w_idx = (ptri2s_config->tx_w_idx+1)%MAX_I2S_PAGE;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			tx_w_idx = ptri2s_config->tx_w_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			//_printk("put TB[%d] for user write\n",ptri2s_config->tx_w_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MMAP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			put_user(tx_w_idx, (int*)arg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			copy_from_user(ptri2s_config->pMMAPTxBufPtr[tx_w_idx], (char*)arg, I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pi2s_status->txbuffer_len++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			//spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			/* Buffer Full */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			//_printk("TBF tr=%d, tw=%d\n", ptri2s_config->tx_r_idx, ptri2s_config->tx_w_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pi2s_status->txbuffer_ovrun++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			interruptible_sleep_on(&(ptri2s_config->i2s_tx_qh)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			if (ptri2s_config->bTxDMAEnable==0 && ptri2s_config->end_cnt==0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				_printk("wake up for exit i2s driver\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				put_user(-1, (int*)arg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	}while(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_get_audio(i2s_config_type* ptri2s_config, unsigned long arg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long flags; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int rx_r_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	do{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//_printk("GA rr=%d, rw=%d,i=%d\n", ptri2s_config->rx_r_idx, ptri2s_config->rx_w_idx,ptri2s_config->rx_isr_cnt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(((ptri2s_config->rx_r_idx+2)%MAX_I2S_PAGE)!=ptri2s_config->rx_w_idx) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			rx_r_idx = ptri2s_config->rx_r_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->rx_r_idx = (ptri2s_config->rx_r_idx+1)%MAX_I2S_PAGE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MMAP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			put_user(rx_r_idx, (int*)arg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			copy_to_user((char*)arg, ptri2s_config->pMMAPRxBufPtr[rx_r_idx], I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			//_printk("rx_r_idx=%d\n", ptri2s_config->rx_r_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			//ptri2s_config->rx_r_idx = (ptri2s_config->rx_r_idx+1)%MAX_I2S_PAGE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pi2s_status->rxbuffer_len--; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			//spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			/* Buffer Full */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			//_printk("RBF rr=%d, rw=%d\n", ptri2s_config->rx_r_idx, ptri2s_config->rx_w_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pi2s_status->rxbuffer_ovrun++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			interruptible_sleep_on(&(ptri2s_config->i2s_rx_qh)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WITH_AEC) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(aecFuncP->AECECDeq){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			aecFuncP->AECECDeq(0,pi2s_config->pMMAPRxBufPtr[ptri2s_config->rx_r_idx],I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	}while(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++long i2s_ioctl (struct file *filp, unsigned int cmd, unsigned long arg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int i ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_config_type* ptri2s_config; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long flags; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ptri2s_config = filp->private_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	switch (cmd) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_RESET: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_reset_config(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_SRATE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if((arg>MAX_SRATE_HZ)||(arg<MIN_SRATE_HZ)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("Audio sampling rate %u should be %d ~ %d Hz. Set SRate to 48000Hz\n", (u32)arg, MIN_SRATE_HZ, MAX_SRATE_HZ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->srate = 48000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			spin_unlock(&ptri2s_config->lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		}	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_I2S_WM8750) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if((arg>MAX_SRATE_HZ)||(arg<MIN_SRATE_HZ)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("Audio sampling rate %u should be %d ~ %d Hz. Set SRate to 96000Hz\n", (u32)arg, MIN_SRATE_HZ, MAX_SRATE_HZ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->srate = 96000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			spin_unlock(&ptri2s_config->lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->srate = arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("set audio sampling rate to %d Hz\n", ptri2s_config->srate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_TX_VOL: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if((int)arg > 127) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->txvol = 127; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else if((int)arg < 48) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->txvol = 48; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->txvol = arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if (defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		audiohw_set_master_vol(arg,arg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_I2S_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		audiohw_set_lineout_vol(1, ptri2s_config->txvol, ptri2s_config->txvol); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_RX_VOL: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if((int)arg > 63) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->rxvol = 63; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else if((int)arg < 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->rxvol = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->rxvol = arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_WORD_LEN: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if((int)arg == 16) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->wordlen_24b = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("Enable 16 bit word length.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else if ((int)arg == 24) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->wordlen_24b = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("Enable 24 bit word length.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("MT7628 only support 16bit/24bit word length.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			spin_unlock(&ptri2s_config->lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_ENDIAN_FMT: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if((int)arg == 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->little_edn = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("Little endian format.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->little_edn = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("Big endian format.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_INTERNAL_LBK: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if((int)arg == 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->lbk = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("Enable internal loopback.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->lbk = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("Disable internal loopback.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_EXTERNAL_LBK: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if((int)arg == 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->extlbk = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("Enable external loopback.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->extlbk = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("Disable external loopback.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_TXRX_COEXIST: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if((int)arg == 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->txrx_coexist = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("TX/RX coexist.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->txrx_coexist = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("TX/RX coexist.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_TX_ENABLE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("I2S_TXENABLE\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pi2s_config->tx_unmask_ch = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		tasklet_init(&i2s_tx_tasklet, i2s_tx_task, (u32)pi2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pi2s_config->dis_match = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pi2s_config->start_cnt = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_gen_test_pattern(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		/* allocate tx buffer */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_txPagebuf_alloc(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_txbuf_alloc(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		/* Init two dma channels */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_dma_tx_init(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		/* Init & config all tx param */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_reset_tx_param(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->bTxDMAEnable = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		/* Clear all ALSA related config */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->bALSAEnable = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->bALSAMMAPEnable = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_tx_config(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(ptri2s_config->bRxDMAEnable==0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_clock_enable(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		audiohw_set_lineout_vol(1, ptri2s_config->txvol, ptri2s_config->txvol); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GdmaUnMaskChannel(GDMA_I2S_TX0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_tx_enable(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		/* Kick off dma channel */	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//GdmaUnMaskChannel(GDMA_I2S_TX0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("I2S_TXENABLE done\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_TX_DISABLE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("I2S_TXDISABLE\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//tasklet_kill(&i2s_tx_tasklet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		/* Handle tx end data */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->bTxDMAEnable = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_tx_end_sleep_on(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		tasklet_kill(&i2s_tx_tasklet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_reset_tx_param(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_tx_disable(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if((ptri2s_config->bRxDMAEnable==0)&&(ptri2s_config->bTxDMAEnable==0)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_clock_disable(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_txbuf_free(ptri2s_config);		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(ptri2s_config->mmap_index <= MAX_I2S_PAGE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->mmap_index = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_RX_ENABLE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("I2S_RXENABLE\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		pi2s_config->rx_unmask_ch = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		tasklet_init(&i2s_rx_tasklet, i2s_rx_task, (u32)pi2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		/* allocate rx buffer */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_rxPagebuf_alloc(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_rxbuf_alloc(ptri2s_config);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		/* Init two dma channels */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_dma_rx_init(ptri2s_config);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		/* Init & config all rx param */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_reset_rx_param(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->bRxDMAEnable = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->bALSAEnable = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->bALSAMMAPEnable = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_rx_config(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(ptri2s_config->bTxDMAEnable==0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_clock_enable(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_TXRX) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		audiohw_set_linein_vol(ptri2s_config->rxvol,  ptri2s_config->rxvol); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		/* Kick off dma channel */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GdmaUnMaskChannel(GDMA_I2S_RX0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_rx_enable(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_RX_DISABLE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("I2S_RXDISABLE\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//tasklet_kill(&i2s_rx_tasklet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->bRxDMAEnable = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_rx_end_sleep_on(ptri2s_config);		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		tasklet_kill(&i2s_rx_tasklet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_reset_rx_param(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_rx_disable(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if((ptri2s_config->bRxDMAEnable==0)&&(ptri2s_config->bTxDMAEnable==0)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_clock_disable(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_rxbuf_free(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(ptri2s_config->mmap_index <= MAX_I2S_PAGE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->mmap_index = 0;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//i2s_rxPagebuf_free(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_PUT_AUDIO: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_put_audio(ptri2s_config, arg);		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_GET_AUDIO: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_get_audio(ptri2s_config, arg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_TX_STOP: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("TxGDMA STOP\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->bTxDMAEnable = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->end_cnt = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		while(ptri2s_config->tx_stop_cnt<3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        interruptible_sleep_on(&(ptri2s_config->i2s_tx_qh)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_reset_tx_param(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_tx_disable(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if((ptri2s_config->bRxDMAEnable==0)&&(ptri2s_config->bTxDMAEnable==0)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_clock_disable(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_txbuf_free(ptri2s_config);		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(ptri2s_config->mmap_index <= MAX_I2S_PAGE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->mmap_index = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//i2s_txPagebuf_free(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_TX_PAUSE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                ptri2s_config->tx_pause_en = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("* tx_pause_en = 1 *\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_TX_RESUME: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                ptri2s_config->tx_pause_en = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("# tx_pause_en = 0 #\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_RX_STOP: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("I2S_RX_STOP\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ptri2s_config->bRxDMAEnable = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		while(ptri2s_config->rx_stop_cnt<2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        interruptible_sleep_on(&(ptri2s_config->i2s_rx_qh)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_reset_rx_param(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_rx_disable(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if((ptri2s_config->bRxDMAEnable==0)&&(ptri2s_config->bTxDMAEnable==0)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_clock_disable(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_rxbuf_free(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(ptri2s_config->mmap_index <= MAX_I2S_PAGE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->mmap_index = 0;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//i2s_rxPagebuf_free(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_RX_PAUSE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                ptri2s_config->rx_pause_en = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("* rx_pause_en = 1 *\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_RX_RESUME: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                ptri2s_config->rx_pause_en = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("# rx_pause_en = 0 #\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_CODEC_MIC_BOOST: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if((int)arg > 3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->micboost = 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else if((int)arg < 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->micboost = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->micboost = arg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_CODEC_MIC_IN: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if((int)arg == 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->micin = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->micin = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        case I2S_CLOCK_ENABLE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                i2s_clock_disable(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                ptri2s_config->wordlen_24b = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                i2s_tx_config(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                i2s_clock_enable(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                i2s_tx_enable(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_DEBUG_CODEC: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		for (i=0; i<10; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			_printk("### i=%d ###\n", i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_clock_enable(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_clock_disable(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	      	break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MS_CTRL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_MS_MODE_CTRL: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_lock_irqsave(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if((int)arg == 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->slave_en = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			_printk("I2S in slave mode.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			ptri2s_config->slave_en = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			_printk("I2S in master mode.\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		spin_unlock_irqrestore(&ptri2s_config->lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_DEBUG_CLKGEN: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_DEBUG_INLBK: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_DEBUG_EXLBK: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_DEBUG_CODECBYPASS:	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_DEBUG_FMT: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_DEBUG_CODEC_EXLBK: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case I2S_DEBUG_RESET: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_debug_cmd(cmd, arg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break;							 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	default : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("i2s_ioctl: command format error\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/************************ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *      API for ALSA    * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *                      * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ ************************/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++char* i2s_memPool_Alloc(i2s_config_type* ptri2s_config,int dir) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        //_printk("%s\n",__func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        if(!ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                return NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        if(dir == STREAM_PLAYBACK){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MMAP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                i2s_mmap_alloc(I2S_TOTAL_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                i2s_txbuf_alloc(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return ptri2s_config->pMMAPTxBufPtr[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        }else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MMAP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                i2s_mmap_alloc(I2S_TOTAL_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_rxbuf_alloc(ptri2s_config);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return ptri2s_config->pMMAPRxBufPtr[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        return NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_memPool_free(i2s_config_type* ptri2s_config,int dir) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        if(!ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        if(dir == STREAM_PLAYBACK){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MMAP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_mem_unmap(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_txbuf_free(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        }else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MMAP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_mem_unmap(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_rxbuf_free(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_page_prepare(i2s_config_type* ptri2s_config,int dir) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        if(dir == STREAM_PLAYBACK){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                /* allocate tx buffer */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                i2s_txPagebuf_alloc(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_dma_tx_init(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	}else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                /* allocate rx buffer */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_rxPagebuf_alloc(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_dma_rx_init(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_page_release(i2s_config_type* ptri2s_config,int dir) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        if(!ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                return (-1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        if(dir == STREAM_PLAYBACK) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_txPagebuf_free(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_rxPagebuf_free(ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++         
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_startup(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	memset(pi2s_config, 0, sizeof(i2s_config_type)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef I2S_STATISTIC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	memset(pi2s_status, 0, sizeof(i2s_status_type));	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_param_init(pi2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_config->bALSAEnable = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MMAP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_config->bALSAMMAPEnable = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pi2s_config->little_edn = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	init_waitqueue_head(&(pi2s_config->i2s_tx_qh)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	init_waitqueue_head(&(pi2s_config->i2s_rx_qh)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	spin_lock_init(&pi2s_config->lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int gdma_En_Switch(i2s_config_type* ptri2s_config,int dir,int enabled){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        if(!ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                return (-1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        if(dir == STREAM_PLAYBACK){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                ptri2s_config->bTxDMAEnable = enabled; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                //MSG("%s:%d\n",__func__,ptri2s_config->bTxDMAEnable); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        }else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                ptri2s_config->bRxDMAEnable = enabled; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_audio_exchange(i2s_config_type* ptri2s_config,int dir,unsigned long arg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        //MSG("I2S_PUT_AUDIO\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        if(!ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                return (-1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        if(dir == STREAM_PLAYBACK){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        	i2s_put_audio(ptri2s_config, arg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	}else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_get_audio(ptri2s_config, arg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void gdma_mask_handler(u32 dma_ch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_dma_mask_handler(dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void gdma_unmask_handler(u32 dma_ch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        i2s_dma_unmask_handler(dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++u32 i2s_mmap_phys_addr(i2s_config_type* ptri2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if((ptri2s_config->pMMAPBufPtr[0]!=NULL) && (ptri2s_config->mmap_index == MAX_I2S_PAGE)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return (dma_addr_t)i2s_mmap_addr[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else if((ptri2s_config->pMMAPBufPtr[MAX_I2S_PAGE]!=NULL) && (ptri2s_config->mmap_index == MAX_I2S_PAGE*2)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return (dma_addr_t)i2s_mmap_addr[MAX_I2S_PAGE]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_startup); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_mem_unmap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_mmap_alloc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_mmap_remap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_param_init); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_txbuf_alloc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_rxbuf_alloc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_txPagebuf_alloc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_rxPagebuf_alloc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_txbuf_free); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_rxbuf_free); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_txPagebuf_free); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_rxPagebuf_free); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_rx_disable); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_tx_disable); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_rx_enable); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_tx_enable); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_rx_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_tx_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_reset_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_clock_disable); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_clock_enable); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_reset_rx_param); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_reset_tx_param); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_dma_rx_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_dma_tx_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_dma_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_dma_tx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_dma_rx_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_dma_mask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_dma_tx_init); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_dma_rx_init); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_tx_end_sleep_on); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_rx_end_sleep_on); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_mmap_phys_addr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_open); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(pi2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_IN_MCLK) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MCLK_12MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_refclk_12m_enable); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MCLK_12P288MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_refclk_12p288m_enable); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(MT7628_ASIC_BOARD) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_driving_strength_adjust); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_refclk_disable); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_refclk_gpio_out_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_refclk_gpio_in_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_share_pin_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_share_pin_mt7623); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_ws_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_mode_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_codec_frequency_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_dma_tx_transf_data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_dma_tx_transf_zero); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_dma_rx_transf_data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_dma_rx_transf_zero); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_dma_tx_end_handle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_dma_tx_soft_stop); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_dma_rx_soft_stop); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_tx_task); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_rx_task); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_memPool_Alloc); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_memPool_free); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_page_prepare); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_page_release); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(gdma_En_Switch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(i2s_audio_exchange); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(gdma_mask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(gdma_unmask_handler); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WITH_AEC) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(aecFuncP); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++module_init(i2s_mod_init); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++module_exit(i2s_mod_exit); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_DESCRIPTION("Ralink SoC I2S Controller Module"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_AUTHOR("Qwert Chin <[email protected]>"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_SUPPORTED_DEVICE("I2S"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_VERSION(I2S_MOD_VERSION); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_LICENSE("GPL"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_PARM (i2sdrv_major, "i"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++module_param (i2sdrv_major, int, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- /dev/null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/mtk/i2s_ctrl.h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -0,0 +1,523 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifndef __RALINK_I2S_H_ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define __RALINK_I2S_H_ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef __KERNEL__ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//#include <asm/rt2880/rt_mmap.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WITH_AEC) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "aec/aec_api.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_MAX_DEV			1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_MOD_VERSION			"0.1" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define phys_to_bus(a) (a & 0x1FFFFFFF) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifndef u32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define u32 unsigned int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifndef u16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define u16 unsigned short 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifndef u8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define u8 unsigned char 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifndef REGBIT 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define REGBIT(x, n)		(x << n) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define Virtual2Physical(x)             (((int)x) & 0x1fffffff) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define Physical2Virtual(x)             (((int)x) | 0x80000000) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define Virtual2NonCache(x)             (((int)x) | 0x20000000) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define Physical2NonCache(x)            (((int)x) | 0xa0000000) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define NonCache2Virtual(x)             (((int)x) & 0xDFFFFFFF) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MCLK_12MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CONFIG_I2S_CODEC_PLL_EN		1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CONFIG_I2S_CODEC_PLL_EN		0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//#define CONFIG_I2S_MS_CTRL		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//#define CONFIG_I2S_MS_MODE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//#define memory_test 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MT7623_ASIC_BOARD 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ARM_ARCH 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_MT7621) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MT7621_ASIC_BOARD 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_MT7628) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MT7628_ASIC_BOARD 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//#define I2S_DEBUG_PRN 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef I2S_DEBUG_PRN 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MSG(fmt, args...) printk("I2S: " fmt, ## args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MSG(fmt, args...) { } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef I2S_DEBUG_PRN 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define i2s_outw(address, value)    	*((volatile uint32_t *)(address)) = cpu_to_le32(value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define i2s_inw(address)		le32_to_cpu(*(volatile u32 *)(address)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* HW feature definiations */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT3883) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CONFIG_I2S_TXRX			1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CONFIG_I2S_IN_MCLK		1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//#define CONFIG_I2S_WS_EDGE		1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CONFIG_I2S_FRAC_DIV		1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CONFIG_I2S_IN_CLK		1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CONFIG_I2S_MS_MODE		1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if 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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CONFIG_I2S_TXRX			1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//#define CONFIG_I2S_WS_EDGE		1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CONFIG_I2S_FRAC_DIV		1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CONFIG_I2S_IN_CLK		1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT3350) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CONFIG_I2S_IN_MCLK		1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT3052) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CONFIG_I2S_MS_MODE		1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* This is decided in menuconfig */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CONFIG_I2S_MMAP           	1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* For MT7623 ASIC PLL Setting */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AUD1PLL_CON0		(0xF0209270) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AUD1PLL_CON1		(0xF0209274) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AUD1PLL_CON2		(0xF0209278) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AUD1PLL_PWR_CON0	(0xF020927C) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AUD2PLL_CON0		(0xF02092C0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AUD2PLL_CON1		(0xF02092C4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AUD2PLL_CON2		(0xF02092C8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AUD2PLL_PWR_CON0	(0xF02092CC) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* Register Map, Ref to RT3052 Data Sheet */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* Register Map Detail */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_I2SCFG			(ETHDMASYS_I2S_BASE+0x0000) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_INT_STATUS			(ETHDMASYS_I2S_BASE+0x0004) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_INT_EN			(ETHDMASYS_I2S_BASE+0x0008) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_FF_STATUS			(ETHDMASYS_I2S_BASE+0x000c) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_FIFO_WREG			(ETHDMASYS_I2S_BASE+0x0010) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_FIFO_WREG		I2S_FIFO_WREG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_FIFO_RREG		(ETHDMASYS_I2S_BASE+0x0014) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_I2SCFG1			(ETHDMASYS_I2S_BASE+0x0018) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_DIVINT_CFG			(ETHDMASYS_I2S_BASE+0x0024) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_DIVCOMP_CFG			(ETHDMASYS_I2S_BASE+0x0020) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_I2SCFG			(RALINK_I2S_BASE+0x0000) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_INT_STATUS			(RALINK_I2S_BASE+0x0004) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_INT_EN			(RALINK_I2S_BASE+0x0008) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_FF_STATUS			(RALINK_I2S_BASE+0x000c) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_FIFO_WREG			(RALINK_I2S_BASE+0x0010) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_FIFO_WREG		I2S_FIFO_WREG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_FIFO_RREG		(RALINK_I2S_BASE+0x0014) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_I2SCFG1			(RALINK_I2S_BASE+0x0018) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_DIVINT_CFG			(RALINK_I2S_BASE+0x0024) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_DIVCOMP_CFG			(RALINK_I2S_BASE+0x0020) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* I2SCFG bit field */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_EN			31 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_DMA_EN		30 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_LITTLE_ENDIAN	29 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_SYS_ENDIAN		28 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_RT6855A) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_BYTE_SWAP		28 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_EN		24 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_EN		20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_NORM_24BIT		18 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_DATA_24BIT		17 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_SLAVE_MODE		16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_FF_THRES		12 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_CH_SWAP		11 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_CH1_OFF		10 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_CH0_OFF		9 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT3052) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_CLK_OUT_DIS		8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_FF_THRES		4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_CH_SWAP		3 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_CH1_OFF		2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_CH0_OFF		1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT3052) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_SLAVE_EN            0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_WS_INV		0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* INT_EN bit field */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_INT3_EN		7 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_INT2_EN		6 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_INT1_EN		5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_INT0_EN		4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_INT3_EN		3 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_INT2_EN		2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_INT1_EN		1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_INT0_EN		0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* INT_STATUS bit field */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_DMA_FAULT	7 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_OVRUN		6 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_UNRUN		5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_THRES		4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_DMA_FAULT	3 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_OVRUN		2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_UNRUN		1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_THRES		0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* FF_STATUS bit field */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_EPCNT		4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_EPCNT		0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* I2S_DIVCOMP_CFG bit field */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_CLKDIV_EN		31 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* I2S_CFG1 bit field */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_LBK_EN		31 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_EXT_LBK_EN		30 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_DATA_FMT		0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* FIFO_WREG bit field */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_FIFO_WDATA		0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* Constant definition */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define NFF_THRES		4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_PAGE_SIZE		3072//(3*4096)//(1152*2*2*2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_MIN_PAGE_SIZE	4096 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MAX_I2S_PAGE		8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TOTAL_PAGE_SIZE 	(I2S_PAGE_SIZE*MAX_I2S_PAGE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MAX_SRATE_HZ            48000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MIN_SRATE_HZ            8000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_I2S_WM8750) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MAX_SRATE_HZ		96000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MIN_SRATE_HZ		8000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MAX_VOL_DB		+0			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MIN_VOL_DB		-127 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ALSA_MMAP_IDX_SHIFT	2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_SND_MT76XX_SOC) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define STREAM_PLAYBACK		SNDRV_PCM_STREAM_PLAYBACK  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define STREAM_CAPTURE		SNDRV_PCM_STREAM_CAPTURE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define STREAM_PLAYBACK		0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define STREAM_CAPTURE		1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* I2S I/O command */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_SRATE		0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_VOL			1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_ENABLE		2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_DISABLE		3 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_ENABLE		27 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_DISABLE		3 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_GET_WBUF	 	4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_PUT_WBUF		5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_ENABLE		6 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_DISABLE		7 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_PUT_AUDIO		4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_GET_AUDIO		5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_VOL		1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_VOL		8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_WORD_LEN		9 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_ENDIAN_FMT		10 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_INTERNAL_LBK	11 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_STOP             12 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_DEBUG_CODEC		13 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_MS_MODE_CTRL	14 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_PAUSE		15 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TX_RESUME		16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RESET		17 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_STOP		18 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_EXTERNAL_LBK	19 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TXRX_COEXIST	20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_PAUSE		21 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_RX_RESUME		22 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_CODEC_MIC_BOOST	23 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_CODEC_MIC_IN	24 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_CLOCK_ENABLE	25 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_TEST_TEST		26 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_DEBUG		30 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_DEBUG_CLKGEN	30 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_DEBUG_INLBK		31 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_DEBUG_EXLBK		32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_DEBUG_FMT		33 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_DEBUG_RESET		34 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_DEBUG_CODECBYPASS	35 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_DEBUG_CODEC_EXLBK	36 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* configuration */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CONFIG_I2S_TFF_THRES	NFF_THRES 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CONFIG_I2S_CH_SWAP	0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MS_MODE)     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CONFIG_I2S_SLAVE_EN	0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CONFIG_I2S_SLAVE_EN	1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* driver status definition */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_OK			0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_OUTOFMEM		0x01 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_GDMAFAILED		0x02 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_REQUEST_IRQ_FAILED	0x04 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_REG_SETUP_FAILED	0x08 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_STATISTIC 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//#define I2S_HW_INTERRUPT_EN 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//#define I2S_SW_IRQ_EN 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2S_MAJOR		234 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* parameter for ALSA */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/*GDMA for I2S Status*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_I2S_DIS (0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_I2S_EN (1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++typedef struct i2s_status_t 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 txdmafault; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 txovrun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 txunrun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 txthres; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int txbuffer_unrun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int txbuffer_ovrun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int txbuffer_len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 rxdmafault; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 rxovrun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 rxunrun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 rxthres; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int rxbuffer_unrun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int rxbuffer_ovrun; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int rxbuffer_len; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}i2s_status_type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++typedef struct i2s_config_t 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int srate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int txvol; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int rxvol; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 pos; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 tx_isr_cnt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 rx_isr_cnt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int bSleep; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int bTxDMAEnable; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int bRxDMAEnable; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int enLable; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int micboost; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int micin; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* parameters fo ALSA */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int bALSAEnable; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int bALSAMMAPEnable; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned char bTrigger[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned char bPreTrigger[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned char dmaStat[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned char i2sStat[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned int hw_base_frame[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct snd_pcm_substream *pss[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef __KERNEL__		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	spinlock_t lock; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	wait_queue_head_t i2s_tx_qh, i2s_rx_qh; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 dmach; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 tx_unmask_ch; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 rx_unmask_ch; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 dma_unmask_status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 dma_done_status;    
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 tx_ff_thres; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 tx_ch_swap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 rx_ff_thres; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 rx_ch_swap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 slave_en; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 dis_match; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int start_cnt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int little_edn;  /* test file's fmt: little endian->1; big endian->0 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        int sys_endian;  /* kernal' system fmt: little endian->0; big endian->1 */	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int wordlen_24b; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int codec_pll_en; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int codec_num; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int tx_pause_en; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int rx_pause_en; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int end_cnt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int txrx_coexist; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int tx_stop_cnt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int rx_stop_cnt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* for I2S_CFG1 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 lbk; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 extlbk; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 fmt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int w_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int r_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int tx_w_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int tx_r_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int rx_w_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int rx_r_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int mmap_index; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int next_p0_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int next_p1_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u8* buf8ptr;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	char* pMMAPBufPtr[MAX_I2S_PAGE*2];	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	char* pMMAPTxBufPtr[MAX_I2S_PAGE]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	char* pMMAPRxBufPtr[MAX_I2S_PAGE]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	union { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		u16* pPage0TxBuf16Ptr;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		u8* pPage0TxBuf8ptr;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	union { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		u16* pPage1TxBuf16Ptr;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		u8* pPage1TxBuf8ptr;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	union { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		u16* pPage0RxBuf16Ptr;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		u8* pPage0RxBuf8ptr;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	union { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		u16* pPage1RxBuf16Ptr;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		u8* pPage1RxBuf8ptr;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}i2s_config_type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_gen_test_pattern(void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_mem_unmap(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_param_init(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_txbuf_alloc(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_rxbuf_alloc(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_txPagebuf_alloc(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_rxPagebuf_alloc(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_txbuf_free(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_rxbuf_free(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_txPagebuf_free(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_rxPagebuf_free(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_reset_tx_param(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_reset_rx_param(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_tx_config(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_rx_config(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_tx_enable(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_tx_disable(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_rx_enable(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_rx_disable(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_codec_enable(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_codec_disable(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_clock_enable(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_clock_disable(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_reset_config(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_refclk_disable(void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_refclk_gpio_out_config(void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_refclk_gpio_in_config(void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_share_pin_config(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_share_pin_mt7623(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_master_clock_gpio_out_mt7623(void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_slave_clock_gpio_in_mt7623(void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_ws_config(i2s_config_type* ptri2s_config, unsigned long index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_mode_config(u32 slave_en); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_codec_frequency_config(i2s_config_type* ptri2s_config, unsigned long index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_tx_end_sleep_on(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_rx_end_sleep_on(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MCLK_12MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_refclk_12m_enable(void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MCLK_12P288MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_refclk_12p288m_enable(void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(MT7621_ASIC_BOARD) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_pll_config_mt7621(unsigned long index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_pll_refclk_set(void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(MT7623_ASIC_BOARD) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_pll_config_mt7623(unsigned long index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(MT7628_ASIC_BOARD) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_driving_strength_adjust(void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(I2S_STATISTIC) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_int_status(u32 dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_dma_tx_handler(u32 dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_dma_rx_handler(u32 dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_dma_unmask_handler(u32 dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_dma_mask_handler(u32 dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_dma_tx_init(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_dma_rx_init(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_tx_task(unsigned long pData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_rx_task(unsigned long pData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_dma_tx_unmask_handler(u32 dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_dma_rx_unmask_handler(u32 dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_dma_tx_transf_data(i2s_config_type* ptri2s_config, u32 dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_dma_tx_transf_zero(i2s_config_type* ptri2s_config, u32 dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_dma_rx_transf_data(i2s_config_type* ptri2s_config, u32 dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_dma_rx_transf_zero(i2s_config_type* ptri2s_config, u32 dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_dma_tx_end_handle(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_dma_tx_soft_stop(i2s_config_type* ptri2s_config, u32 dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_dma_rx_soft_stop(i2s_config_type* ptri2s_config, u32 dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_page_prepare(i2s_config_type* ptri2s_config,int dir); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_page_release(i2s_config_type* ptri2s_config,int dir); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int gdma_En_Switch(i2s_config_type* ptri2s_config,int dir,int enabled); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_startup(void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_audio_exchange(i2s_config_type* ptri2s_config,int dir,unsigned long arg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void gdma_unmask_handler(u32 dma_ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++char* i2s_memPool_Alloc(i2s_config_type* ptri2s_config,int dir); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void i2s_memPool_free(i2s_config_type* ptri2s_config,int dir); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++u32 i2s_mmap_phys_addr(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if !defined(CONFIG_I2S_TXRX) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GdmaI2sRx	//GdmaI2sRx 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RALINK_I2S_VERSION	"1.0" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2SDRV_DEVNAME		"i2s0" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif /* __RALINK_I2S_H_ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- /dev/null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/mtk/mt76xx_i2s.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -0,0 +1,309 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * mtk_audio_drv.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  Created on: 2013/8/20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *      Author: MTK04880 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/init.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/version.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/sched.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/module.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/kernel.h> /* printk() */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/slab.h> /* kmalloc() */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/fs.h> /* everything... */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/errno.h> /* error codes */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/types.h> /* size_t */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/proc_fs.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/fcntl.h> /* O_ACCMODE */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <asm/system.h> /* cli(), *_flags */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <asm/uaccess.h> /* copy_from/to_user */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/interrupt.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/mm.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/dma-mapping.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/core.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/pci.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/pcm.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/pcm_params.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/soc.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/soc-dapm.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/initval.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "ralink_gdma.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "mt76xx_i2s.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/****************************/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/*GLOBAL VARIABLE DEFINITION*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/****************************/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern i2s_config_type* pi2s_config; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/****************************/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/*FUNCTION DECLRATION		*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/****************************/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai,\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		unsigned int fmt); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//static int  mt76xx_i2s_shutdown(struct snd_pcm_substream *substream, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//		       struct snd_soc_dai *dai); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int  mt76xx_i2s_startup(struct snd_pcm_substream *substream, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		       struct snd_soc_dai *dai); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_i2s_hw_params(struct snd_pcm_substream *substream,\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				struct snd_pcm_hw_params *params,\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				struct snd_soc_dai *dai); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_i2s_play_prepare(struct snd_pcm_substream *substream,struct snd_soc_dai *dai); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_i2s_rec_prepare(struct snd_pcm_substream *substream,struct snd_soc_dai *dai); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_i2s_hw_free(struct snd_pcm_substream *substream,struct snd_soc_dai *dai); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,20) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_i2s_drv_probe(struct platform_device *pdev); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_i2s_drv_remove(struct platform_device *pdev); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/****************************/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/*STRUCTURE DEFINITION		*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/****************************/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static struct snd_soc_dai_ops mt76xx_i2s_dai_ops = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.startup   = mt76xx_i2s_startup, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.hw_params = mt76xx_i2s_hw_params, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.hw_free   = mt76xx_i2s_hw_free, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//.shutdown = mt76xx_i2s_shutdown, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.prepare   = mt76xx_i2s_prepare, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.set_fmt   = mt76xx_i2s_set_fmt, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//.set_sysclk = mt76xx_i2s_set_sysclk, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++const struct snd_soc_component_driver mt76xx_i2s_component = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.name		= "mt76xx-i2s", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++struct snd_soc_dai_driver mt76xx_i2s_dai = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.playback = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		.channels_min = 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		.channels_max = 2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		.rates = (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_11025|\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_22050|SNDRV_PCM_RATE_32000|\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		.formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				SNDRV_PCM_FMTBIT_S24_LE), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.capture = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		.channels_min = 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		.channels_max = 2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		.rates = (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_11025|\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_22050|SNDRV_PCM_RATE_32000|\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		.formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				SNDRV_PCM_FMTBIT_S24_LE), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.ops = &mt76xx_i2s_dai_ops, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.symmetric_rates = 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/****************************/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/*FUNCTION BODY				*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/****************************/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		unsigned int fmt) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{//TODO 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_i2s_play_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	rtd->pss[SNDRV_PCM_STREAM_PLAYBACK] = substream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(! rtd->i2sStat[SNDRV_PCM_STREAM_PLAYBACK]){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_reset_tx_param( rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_tx_config( rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		gdma_En_Switch(rtd, STREAM_PLAYBACK, GDMA_I2S_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if( rtd->bRxDMAEnable==0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_clock_enable( rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_tx_enable( rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		rtd->i2sStat[SNDRV_PCM_STREAM_PLAYBACK] = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		MSG("I2S_TXENABLE done\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_i2s_rec_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	rtd->pss[SNDRV_PCM_STREAM_CAPTURE] = substream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(! rtd->i2sStat[SNDRV_PCM_STREAM_CAPTURE]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_reset_rx_param(rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_rx_config(rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		gdma_En_Switch(rtd, STREAM_CAPTURE, GDMA_I2S_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(rtd->bTxDMAEnable==0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_clock_enable(rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_rx_enable(rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		rtd->i2sStat[SNDRV_PCM_STREAM_CAPTURE] = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/*static int  mt76xx_i2s_shutdown(struct snd_pcm_substream *substream, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		       struct snd_soc_dai *dai) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int  mt76xx_i2s_startup(struct snd_pcm_substream *substream, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		       struct snd_soc_dai *dai) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	if((!pi2s_config->i2sStat[SNDRV_PCM_STREAM_PLAYBACK]) && (!pi2s_config->i2sStat[SNDRV_PCM_STREAM_CAPTURE])){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_startup(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    		if(!pi2s_config) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    			return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    		i2s_reset_config(pi2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	substream->runtime->private_data = pi2s_config; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_i2s_hw_params(struct snd_pcm_substream *substream,\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				struct snd_pcm_hw_params *params,\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				struct snd_soc_dai *dai){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned int srate = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct snd_pcm_runtime *runtime = substream->runtime; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_config_type* rtd = runtime->private_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	switch(params_rate(params)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 8000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		srate = 8000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 16000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		srate = 16000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 32000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		srate = 32000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 44100: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		srate = 44100; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 48000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		srate = 48000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		srate = 44100; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//MSG("audio sampling rate %u should be %d ~ %d Hz\n", (u32)params_rate(params), MIN_SRATE_HZ, MAX_SRATE_HZ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(srate){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if((rtd->bRxDMAEnable != GDMA_I2S_EN) && (rtd->bTxDMAEnable != GDMA_I2S_EN)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			rtd->srate = srate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("set audio sampling rate to %d Hz\n", rtd->srate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_i2s_hw_free(struct snd_pcm_substream *substream,struct snd_soc_dai *dai){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(rtd->i2sStat[SNDRV_PCM_STREAM_PLAYBACK]){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("I2S_TXDISABLE\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_reset_tx_param(rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			if((rtd->bRxDMAEnable==0)&&(rtd->bTxDMAEnable==0)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				i2s_clock_disable(rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			rtd->i2sStat[SNDRV_PCM_STREAM_PLAYBACK] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(rtd->i2sStat[SNDRV_PCM_STREAM_CAPTURE]){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("I2S_RXDISABLE\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_reset_rx_param(rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			if((rtd->bRxDMAEnable==0)&&(rtd->bTxDMAEnable==0)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				i2s_clock_disable(rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			rtd->i2sStat[SNDRV_PCM_STREAM_CAPTURE] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_i2s_prepare(struct snd_pcm_substream *substream,struct snd_soc_dai *dai) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return mt76xx_i2s_play_prepare(substream, dai); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return mt76xx_i2s_rec_prepare(substream, dai); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,20) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_i2s_drv_probe(struct platform_device *pdev) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("****** %s ******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return snd_soc_register_component(&pdev->dev, &mt76xx_i2s_component, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					&mt76xx_i2s_dai, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_i2s_drv_remove(struct platform_device *pdev) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_unregister_component(&pdev->dev);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static struct platform_driver mt76xx_i2s_driver = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.probe  = mt76xx_i2s_drv_probe, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.remove = mt76xx_i2s_drv_remove, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.driver = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		.name  = "mt76xx-i2s", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		.owner = THIS_MODULE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int __init mt76xx_i2s_init(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("****** %s ******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return platform_driver_register(&mt76xx_i2s_driver); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static void __exit mt76xx_i2s_exit(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("****** %s ******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	platform_driver_unregister(&mt76xx_i2s_driver); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++module_init(mt76xx_i2s_init); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++module_exit(mt76xx_i2s_exit); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_AUTHOR("Dora Chen"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_DESCRIPTION("Stretch MT76xx I2S Interface"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_LICENSE("GPL"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- /dev/null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/mtk/mt76xx_i2s.h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -0,0 +1,18 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * mtk_i2s.h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  Created on: 2013/8/20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *      Author: MTK04880 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifndef MTK_I2S_H_ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MTK_I2S_H_ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef __KERNEL__ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//#include <asm/rt2880/rt_mmap.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/fs.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "i2s_ctrl.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif /* MTK_I2S_H_ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- /dev/null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/mtk/mt76xx_machine.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -0,0 +1,319 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * mt76xx_machine.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/init.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/version.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/sched.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/module.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/kernel.h> /* printk() */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/slab.h> /* kmalloc() */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/fs.h> /* everything... */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/errno.h> /* error codes */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/types.h> /* size_t */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/proc_fs.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/fcntl.h> /* O_ACCMODE */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <asm/system.h> /* cli(), *_flags */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <asm/uaccess.h> /* copy_from/to_user */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/interrupt.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/mm.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/dma-mapping.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/core.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/pci.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/pcm.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/pcm_params.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/soc.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/soc-dapm.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/initval.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/i2c.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/ioport.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/delay.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "ralink_gdma.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "mt76xx_i2s.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "mt76xx_machine.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_SND_SOC_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "../codecs/wm8960.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define I2C_AUDIO_DEV_ID	(0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/****************************/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/*FUNCTION DECLRATION		*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/****************************/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern unsigned long i2s_codec_12p288Mhz[11]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern unsigned long i2s_codec_12Mhz[11]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_codec_clock_hwparams(struct snd_pcm_substream *substream,\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				struct snd_pcm_hw_params *params); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_codec_startup(struct snd_pcm_substream *substream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_codec_init(struct snd_soc_pcm_runtime *rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern struct snd_soc_dai_driver mt76xx_i2s_dai; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern struct snd_soc_platform_driver mt76xx_soc_platform; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++struct platform_device *mt76xx_audio_device; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_SND_SOC_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern struct snd_soc_dai wm8960_dai; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern struct snd_soc_codec_device soc_codec_dev_wm8960; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static struct snd_soc_ops mtk_audio_ops = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.hw_params = mt76xx_codec_clock_hwparams, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.startup = mt76xx_codec_startup, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static struct snd_soc_dai_link mtk_audio_dai = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.name = "mtk_dai", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.stream_name = "WMserious PCM", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.cpu_dai_name	= "mt76xx-i2s", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.codec_dai_name	= "wm8960-hifi", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.codec_name	= "wm8960.0-001a", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.platform_name	= "mt76xx-pcm", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.ignore_pmdown_time = true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.init = mt76xx_codec_init, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.ops = &mtk_audio_ops, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static struct snd_soc_card mtk_audio_card = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.name = "MTK APSoC I2S", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.owner = THIS_MODULE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.dai_link = &mtk_audio_dai,//I2S/Codec 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.num_links = 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_codec_clock_hwparams(struct snd_pcm_substream *substream, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				struct snd_pcm_hw_params *params) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct snd_soc_pcm_runtime *p = substream->private_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct snd_soc_dai *codec_dai = p->codec_dai; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct snd_pcm_runtime *runtime = substream->runtime; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_config_type* rtd = runtime->private_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data,index = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long* pTable; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int mclk,ret,targetClk = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/*For duplex mode, avoid setting twice.*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if((rtd->bRxDMAEnable == GDMA_I2S_EN) || (rtd->bTxDMAEnable == GDMA_I2S_EN)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("%s:%d \n",__func__,__LINE__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MCLK_12MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	mclk = 12000000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_I2S_MCLK_12P288MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	mclk = 12288000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	mclk = 12000000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//snd_soc_dai_set_sysclk(codec_dai,0,mclk, SND_SOC_CLOCK_IN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	printk("%s:%s[%d]%d\n", __FILE__, __func__, __LINE__, params_rate(params)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	switch(params_rate(params)){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 8000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		index = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		targetClk = 12288000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 12000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		index = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		targetClk = 12288000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 16000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		index = 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		targetClk = 12288000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 24000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		index = 5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		targetClk = 12288000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 32000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		index = 6; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		targetClk = 12288000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 48000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		index = 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		targetClk = 12288000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 11025: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		index = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		targetClk = 11289600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 22050: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		index = 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		targetClk = 11289600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 44100: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		index = 7; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		targetClk = 11289600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 88200: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		index = 9; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		targetClk = 11289600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 96000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		index = 10; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		targetClk = 11289600; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		index = 7; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		targetClk = 12288000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//MSG("audio sampling rate %u should be %d ~ %d Hz\n", (u32)params_rate(params), MIN_SRATE_HZ, MAX_SRATE_HZ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_SND_SOC_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 * There is a fixed divide by 4 in the PLL and a selectable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 * divide by N after the PLL which should be set to divide by 2 to meet this requirement. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 * */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ret = snd_soc_dai_set_pll(codec_dai, 0, 0,mclk, targetClk*2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* From app notes: allow Vref to stabilize to reduce clicks */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(rtd->slave_en){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//printk("WM8960 is in master mode\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_DCLKDIV, 0x1c4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_SYSCLKDIV, 0x5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(!rtd->slave_en) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		snd_soc_dai_set_fmt(codec_dai,SND_SOC_DAIFMT_CBS_CFS|SND_SOC_DAIFMT_I2S|SND_SOC_DAIFMT_NB_NF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		snd_soc_dai_set_fmt(codec_dai,SND_SOC_DAIFMT_CBM_CFM|SND_SOC_DAIFMT_I2S|SND_SOC_DAIFMT_NB_NF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	mdelay(5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_SND_SOC_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MCLK_12MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pTable = i2s_codec_12Mhz; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = pTable[index]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	pTable = i2s_codec_12p288Mhz; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = pTable[index]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(rtd->codec_pll_en) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_DACDIV, (data<<3)|0x5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_DACDIV, (data<<3|0x4)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_codec_startup(struct snd_pcm_substream *substream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_codec_init(struct snd_soc_pcm_runtime *rtd) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static struct i2c_board_info i2c_board_info[] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_SND_SOC_WM8750) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		I2C_BOARD_INFO("wm8750", (0x36 >> 1)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_SND_SOC_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//	I2C_BOARD_INFO("wm8960", (0x34 >> 1)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		I2C_BOARD_INFO("codec_wm8960", (0x34)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	}, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static struct platform_device *soc_mtk_i2s_dev; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static struct platform_device *soc_mtk_pcm_dev; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int __init mt76xx_machine_init(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//struct snd_soc_device *socdev = &mtk_audio_devdata; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//struct i2c_adapter *adapter = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//struct i2c_client *client = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int ret = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct i2c_adapter *adapter = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        struct i2c_client *client = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	adapter = i2c_get_adapter(I2C_AUDIO_DEV_ID); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (!adapter) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return -ENODEV; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	client = i2c_new_device(adapter, i2c_board_info); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (!client) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return -ENODEV; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_put_adapter(adapter); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2c_get_clientdata(client); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	soc_mtk_i2s_dev = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		platform_device_register_simple("mt76xx-i2s", -1, NULL, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (IS_ERR(soc_mtk_i2s_dev)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return PTR_ERR(soc_mtk_i2s_dev); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	soc_mtk_pcm_dev = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		platform_device_register_simple("mt76xx-pcm", -1, NULL, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (IS_ERR(soc_mtk_pcm_dev)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return PTR_ERR(soc_mtk_pcm_dev); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	mt76xx_audio_device = platform_device_alloc("soc-audio",-1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (mt76xx_audio_device == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ret = -ENOMEM; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		goto err_device_alloc; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	platform_set_drvdata(mt76xx_audio_device, &mtk_audio_card); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	platform_set_drvdata(mt76xx_audio_device, &mtk_audio_devdata); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	mtk_audio_devdata.dev = &mt76xx_audio_device->dev; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/*Ralink I2S register process end*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ret = platform_device_add(mt76xx_audio_device); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (ret) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		printk("mtk audio device : platform_device_add failed (%d)\n",ret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		goto err_device_add; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_register_dai(&mt76xx_i2s_dai); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++err_device_add: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (mt76xx_audio_device!= NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		platform_device_put(mt76xx_audio_device); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		mt76xx_audio_device = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++err_device_alloc: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static void __exit mt76xx_machine_exit(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	platform_device_unregister(mt76xx_audio_device); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,20) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* Do nothing */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_unregister_platform(&mt76xx_audio_device->dev); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_unregister_platform(&mt76xx_soc_platform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	platform_device_unregister(soc_mtk_i2s_dev); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	platform_device_unregister(soc_mtk_pcm_dev); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	mt76xx_audio_device = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//module_init(mt76xx_machine_init); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++late_initcall(mt76xx_machine_init); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++module_exit(mt76xx_machine_exit); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//EXPORT_SYMBOL_GPL(mt76xx_soc_platform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_LICENSE("GPL"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- /dev/null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/mtk/mt76xx_machine.h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -0,0 +1,21 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * mtk_audio_device.h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  Created on: 2013/10/23 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *      Author: MTK04880 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifndef MT76XX_MACHINE_H_ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MT76XX_MACHINE_H_ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/pcm.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/pcm_params.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/soc.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/soc-dapm.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef CONFIG_I2S_MMAP 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#undef CONFIG_I2S_MMAP 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif /* MT76XX_MACHINE_H_ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- /dev/null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/mtk/mt76xx_pcm.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -0,0 +1,499 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * mt76xx_pcm.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  Created on: 2013/9/6 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *      Author: MTK04880 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/init.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/version.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/sched.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/module.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/kernel.h> /* printk() */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/slab.h> /* kmalloc() */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/fs.h> /* everything... */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/errno.h> /* error codes */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/types.h> /* size_t */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/proc_fs.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/fcntl.h> /* O_ACCMODE */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <asm/system.h> /* cli(), *_flags */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <asm/uaccess.h> /* copy_from/to_user */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/interrupt.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/mm.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/dma-mapping.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/core.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/pci.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/pcm.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/pcm_params.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/soc.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/soc-dapm.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/initval.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "ralink_gdma.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "mt76xx_i2s.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_PAGE_SIZE 		I2S_PAGE_SIZE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_PAGE_NUM 		MAX_I2S_PAGE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_TOTAL_PAGE_SIZE	I2S_TOTAL_PAGE_SIZE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++dma_addr_t i2s_txdma_addr, i2s_rxdma_addr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++dma_addr_t i2s_mmap_addr[GDMA_PAGE_NUM*2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern struct tasklet_struct i2s_tx_tasklet; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern struct tasklet_struct i2s_rx_tasklet; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern int i2s_mmap_remap(struct vm_area_struct *vma, unsigned long size); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern void i2s_tx_end_sleep_on(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern void i2s_rx_end_sleep_on(i2s_config_type* ptri2s_config); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_open(struct snd_pcm_substream *substream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_new(struct snd_soc_pcm_runtime *rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static void mt76xx_pcm_free(struct snd_pcm *pcm); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_close(struct snd_pcm_substream *substream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static snd_pcm_uframes_t mt76xx_pcm_pointer(struct snd_pcm_substream *substream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_prepare(struct snd_pcm_substream *substream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_hw_params(struct snd_pcm_substream *substream,\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				 struct snd_pcm_hw_params *hw_params); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_copy(struct snd_pcm_substream *substream, int channel,\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		snd_pcm_uframes_t pos,void __user *buf, snd_pcm_uframes_t count); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_hw_free(struct snd_pcm_substream *substream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_free_dma_buffer(struct snd_pcm_substream *substream,int stream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_allocate_dma_buffer(struct snd_pcm_substream *substream,int stream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE > KERNEL_VERSION(3,10,20) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_platform_drv_probe(struct platform_device *pdev); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_platform_drv_remove(struct platform_device *pdev); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static const struct snd_pcm_hardware mt76xx_pcm_hwparam = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MMAP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.info			= (SNDRV_PCM_INFO_INTERLEAVED | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				SNDRV_PCM_INFO_PAUSE | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				SNDRV_PCM_INFO_RESUME | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				SNDRV_PCM_INFO_MMAP | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				SNDRV_PCM_INFO_MMAP_VALID), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.info			= (SNDRV_PCM_INFO_INTERLEAVED | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				SNDRV_PCM_INFO_PAUSE | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				SNDRV_PCM_INFO_RESUME), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.formats		= SNDRV_PCM_FMTBIT_S16_LE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.period_bytes_min	= GDMA_PAGE_SIZE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.period_bytes_max	= GDMA_PAGE_SIZE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.periods_min		= 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.periods_max		= GDMA_PAGE_NUM, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.buffer_bytes_max	= GDMA_TOTAL_PAGE_SIZE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static struct snd_pcm_ops mt76xx_pcm_ops = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.open = 	mt76xx_pcm_open, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.ioctl = 	snd_pcm_lib_ioctl, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.hw_params = 	mt76xx_pcm_hw_params, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.hw_free = 	mt76xx_pcm_hw_free, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.trigger =	mt76xx_pcm_trigger, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.prepare = 	mt76xx_pcm_prepare, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.pointer = 	mt76xx_pcm_pointer, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.close = 	mt76xx_pcm_close, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MMAP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.mmap = mt76xx_pcm_mmap, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.copy = mt76xx_pcm_copy, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE > KERNEL_VERSION(3,10,0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++struct snd_soc_platform_driver mt76xx_soc_platform = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.ops		= &mt76xx_pcm_ops, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.pcm_new	= mt76xx_pcm_new, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.pcm_free	= mt76xx_pcm_free, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++struct snd_soc_platform mt76xx_soc_platform = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.name		= "mtk-dma", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.pcm_ops	= &mt76xx_pcm_ops, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.pcm_new	= mt76xx_pcm_new, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.pcm_free	= mt76xx_pcm_free, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_close(struct snd_pcm_substream *substream){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *********\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static snd_pcm_uframes_t mt76xx_pcm_pointer(struct snd_pcm_substream *substream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct snd_pcm_runtime *runtime = substream->runtime; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_config_type* rtd = runtime->private_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned int offset = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//int buff_frame_bond = bytes_to_frames(runtime, GDMA_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("\n******* %s *********\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		offset = bytes_to_frames(runtime, GDMA_PAGE_SIZE*rtd->tx_r_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		offset = bytes_to_frames(runtime, GDMA_PAGE_SIZE*rtd->rx_w_idx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//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); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int ret = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//struct snd_pcm_runtime *runtime= substream->runtime; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *********\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/*	printk("trigger cmd:%s\n",(cmd==SNDRV_PCM_TRIGGER_START)?"START":\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			(cmd==SNDRV_PCM_TRIGGER_RESUME)?"RESUME":\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			(cmd==SNDRV_PCM_TRIGGER_PAUSE_RELEASE)?"PAUSE_RELEASE":\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			(cmd==SNDRV_PCM_TRIGGER_STOP)?"STOP":\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			(cmd==SNDRV_PCM_TRIGGER_SUSPEND)?"SUSPEND":\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			(cmd==SNDRV_PCM_TRIGGER_PAUSE_PUSH)?"PAUSE_PUSH":"default"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	switch (cmd) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case SNDRV_PCM_TRIGGER_START: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			rtd->bTrigger[SNDRV_PCM_STREAM_PLAYBACK] = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			rtd->bTrigger[SNDRV_PCM_STREAM_CAPTURE] = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case SNDRV_PCM_TRIGGER_STOP: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			rtd->bTrigger[SNDRV_PCM_STREAM_PLAYBACK] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			rtd->bTrigger[SNDRV_PCM_STREAM_CAPTURE] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case SNDRV_PCM_TRIGGER_RESUME: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			rtd->tx_pause_en = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			rtd->rx_pause_en = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case SNDRV_PCM_TRIGGER_SUSPEND: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			rtd->tx_pause_en = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			rtd->rx_pause_en = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ret = -EINVAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_copy(struct snd_pcm_substream *substream, int channel,\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		snd_pcm_uframes_t pos,void __user *buf, snd_pcm_uframes_t count) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct snd_pcm_runtime *runtime= substream->runtime; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_config_type* rtd = runtime->private_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int tx_w_idx = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        int rx_r_idx = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        char *hwbuf = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *********\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	hwbuf = runtime->dma_area + frames_to_bytes(runtime, pos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//MSG("%s bur:%x\n",__func__,hwbuf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("hw_ptr:%d, buffer_size:%d, appl_prt:%d, boundary:%d\n",  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//		runtime->status->hw_ptr, runtime->buffer_size, runtime->control->appl_ptr, runtime->boundary); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		rtd->tx_w_idx = (rtd->tx_w_idx+1)%MAX_I2S_PAGE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                tx_w_idx = rtd->tx_w_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                //printk("put TB[%d - %x] for user write\n",rtd->tx_w_idx,pos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                copy_from_user(rtd->pMMAPTxBufPtr[tx_w_idx], (char*)buf, I2S_PAGE_SIZE);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		rx_r_idx = rtd->rx_r_idx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                rtd->rx_r_idx = (rtd->rx_r_idx+1)%MAX_I2S_PAGE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                copy_to_user((char*)buf, rtd->pMMAPRxBufPtr[rx_r_idx], I2S_PAGE_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        int ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        unsigned long size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        size = vma->vm_end-vma->vm_start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        printk("******* %s: size :%lx end:%lx start:%lx *******\n", __func__,size,vma->vm_end,vma->vm_start); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        ret = i2s_mmap_remap(vma, size); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        return ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_prepare(struct snd_pcm_substream *substream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct snd_pcm_runtime *runtime= substream->runtime; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_config_type *rtd = (i2s_config_type*)runtime->private_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//runtime->buffer_size = GDMA_PAGE_NUM*GDMA_PAGE_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//runtime->boundary = (GDMA_PAGE_NUM*GDMA_PAGE_SIZE)/4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//printk("===== %s:%s:%d =====\n", __FILE__, __func__, __LINE__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		mt76xx_pcm_allocate_dma_buffer(substream,SNDRV_PCM_STREAM_PLAYBACK); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(! rtd->dmaStat[SNDRV_PCM_STREAM_PLAYBACK]){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_page_prepare(rtd,STREAM_PLAYBACK); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			tasklet_init(&i2s_tx_tasklet, i2s_tx_task, (u32)rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			rtd->dmaStat[SNDRV_PCM_STREAM_PLAYBACK] = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			gdma_unmask_handler(GDMA_I2S_TX0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		mt76xx_pcm_allocate_dma_buffer(substream,SNDRV_PCM_STREAM_CAPTURE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(! rtd->dmaStat[SNDRV_PCM_STREAM_CAPTURE]){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_page_prepare(rtd,STREAM_CAPTURE); /* TX:enLabel=1; RX:enLabel=2 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			tasklet_init(&i2s_rx_tasklet, i2s_rx_task, (u32)rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			rtd->dmaStat[SNDRV_PCM_STREAM_CAPTURE] = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			gdma_unmask_handler(GDMA_I2S_RX0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_hw_params(struct snd_pcm_substream *substream, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				 struct snd_pcm_hw_params *hw_params) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/*struct snd_pcm_runtime *runtime = substream->runtime; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_config_type *rtd = (i2s_config_type*)runtime->private_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int ret,i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ret = i = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//i2s_page_prepare(rtd,STREAM_PLAYBACK); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//i2s_page_prepare(rtd,STREAM_CAPTURE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_hw_free(struct snd_pcm_substream *substream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//struct snd_dma_buffer *buf = &substream->dma_buffer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(rtd->dmaStat[SNDRV_PCM_STREAM_PLAYBACK]){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			gdma_En_Switch(rtd,STREAM_PLAYBACK,GDMA_I2S_DIS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_tx_end_sleep_on(rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			tasklet_kill(&i2s_tx_tasklet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_tx_disable(rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			//mt76xx_pcm_free_dma_buffer(substream,substream->stream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_page_release(rtd,STREAM_PLAYBACK); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			rtd->dmaStat[SNDRV_PCM_STREAM_PLAYBACK] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		mt76xx_pcm_free_dma_buffer(substream,substream->stream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(rtd->dmaStat[SNDRV_PCM_STREAM_CAPTURE]){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			gdma_En_Switch(rtd,STREAM_CAPTURE,GDMA_I2S_DIS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_tx_end_sleep_on(rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			tasklet_kill(&i2s_rx_tasklet); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_rx_disable(rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			//mt76xx_pcm_free_dma_buffer(substream,substream->stream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_page_release(rtd,STREAM_CAPTURE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			rtd->dmaStat[SNDRV_PCM_STREAM_CAPTURE] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		mt76xx_pcm_free_dma_buffer(substream,substream->stream); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_free_dma_buffer(struct snd_pcm_substream *substream, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int stream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//struct snd_pcm_substream *substream = pcm->streams[stream].substream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct snd_dma_buffer *buf = &substream->dma_buffer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (!buf->area) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_memPool_free(rtd,STREAM_PLAYBACK); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		i2s_memPool_free(rtd,STREAM_CAPTURE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	buf->area = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_pcm_set_runtime_buffer(substream, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_allocate_dma_buffer(struct snd_pcm_substream *substream, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int stream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//struct snd_pcm_substream *substream = pcm->streams[stream].substream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct snd_dma_buffer *buf = &substream->dma_buffer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(!buf->area){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MMAP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		printk("\n############## MMAP ##############\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		buf->dev.type = SNDRV_DMA_TYPE_DEV; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		buf->dev.type = SNDRV_DMA_TYPE_UNKNOWN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		buf->dev.dev = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		buf->private_data = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if(stream == SNDRV_PCM_STREAM_PLAYBACK) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			buf->area = i2s_memPool_Alloc(rtd,STREAM_PLAYBACK); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			buf->area = i2s_memPool_Alloc(rtd,STREAM_CAPTURE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if (!buf->area) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			return -ENOMEM; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		buf->bytes = GDMA_TOTAL_PAGE_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_MMAP) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		buf->addr = i2s_mmap_phys_addr(rtd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		snd_pcm_set_runtime_buffer(substream, buf); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		//printk("Buffer have been allocated!\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_open(struct snd_pcm_substream *substream) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct snd_pcm_runtime *runtime= substream->runtime; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct snd_dma_buffer *buf = &substream->dma_buffer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int stream = substream->stream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int ret = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_set_runtime_hwparams(substream, &mt76xx_pcm_hwparam); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* ensure that buffer size is a multiple of period size */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	ret = snd_pcm_hw_constraint_integer(runtime, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						SNDRV_PCM_HW_PARAM_PERIODS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (ret < 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(stream == SNDRV_PCM_STREAM_PLAYBACK){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ret = mt76xx_pcm_allocate_dma_buffer(substream, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				SNDRV_PCM_STREAM_PLAYBACK); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	else{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		ret = mt76xx_pcm_allocate_dma_buffer(substream, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				SNDRV_PCM_STREAM_CAPTURE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (ret) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		goto out; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(buf) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		memset(buf->area,0,sizeof(I2S_PAGE_SIZE*MAX_I2S_PAGE)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ out: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_pcm_new(struct snd_soc_pcm_runtime *rtd) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//	int ret = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static void mt76xx_pcm_free(struct snd_pcm *pcm) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/*struct snd_pcm_substream *substream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	struct snd_dma_buffer *buf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	i2s_config_type* rtd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int stream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,20) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_platform_drv_probe(struct platform_device *pdev) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return snd_soc_register_platform(&pdev->dev, &mt76xx_soc_platform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int mt76xx_platform_drv_remove(struct platform_device *pdev) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_unregister_platform(&pdev->dev); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static struct platform_driver mt76xx_pcm_driver = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.driver = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		.name = "mt76xx-pcm", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		.owner = THIS_MODULE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	},	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.probe = mt76xx_platform_drv_probe, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	.remove = mt76xx_platform_drv_remove, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++};	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int __init mt76xx_pcm_init(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return platform_driver_register(&mt76xx_pcm_driver); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static void __exit mt76xx_pcm_exit(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	platform_driver_unregister(&mt76xx_pcm_driver); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int __init mt76xx_pcm_init(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return snd_soc_register_platform(&mt76xx_soc_platform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static void __exit mt76xx_pcm_exit(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	printk("******* %s *******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_unregister_platform(&mt76xx_soc_platform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++module_init(mt76xx_pcm_init); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++module_exit(mt76xx_pcm_exit); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_AUTHOR("Dora Chen"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_DESCRIPTION("MTK APSoC I2S DMA driver"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_LICENSE("GPL"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- /dev/null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/mtk/ralink_gdma.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -0,0 +1,918 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *************************************************************************** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ralink Tech Inc. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 5F., No.36, Taiyuan St., Jhubei City, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Hsinchu County 302, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Taiwan, R.O.C. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * (c) Copyright, Ralink Technology, Inc. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  This program is free software; you can redistribute  it and/or modify it 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  under  the terms of  the GNU General  Public License as published by the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  Free Software Foundation;  either version 2 of the  License, or (at your 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  option) any later version. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  You should have received a copy of the  GNU General Public License along 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  with this program; if not, write  to the Free Software Foundation, Inc., 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  675 Mass Ave, Cambridge, MA 02139, USA. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *************************************************************************** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  Module Name: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  ralink_gdma.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  Abstract: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  Revision History: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  Who         When            What 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  --------    ----------      ---------------------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  Name        Date            Modification logs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  Steven Liu  2009-03-24      Support RT3883 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/init.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/version.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/module.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/kernel.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/interrupt.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/fs.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_MIPS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  #include <asm/uaccess.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  #include <asm/addrspace.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "ralink_gdma.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * RT305x: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch0 : Pcm0_Rx0 | Pcm0_Rx0 | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch1 : Pcm0_Rx1 | Pcm0_Rx1 | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch2 : Pcm0_Tx0 | Pcm0_Tx0 | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch3 : Pcm0_Tx1 | Pcm0_Tx1 | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch4 : Pcm1_Rx0 | I2S_Tx0  | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch5 : Pcm1_Rx1 | I2S_Tx1  | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch6 : Pcm1_Tx0 |  ALL     | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch7 : Pcm1_Tx1 |  ALL     | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * RT3883: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch0  : Pcm0_Rx0 | Pcm0_Rx0 | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch1  : Pcm0_Rx1 | Pcm0_Rx1 | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch2  : Pcm0_Tx0 | Pcm0_Tx0 | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch3  : Pcm0_Tx1 | Pcm0_Tx1 | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch4  : Pcm1_Rx0 | I2S_Tx0  | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch5  : Pcm1_Rx1 | I2S_Tx1  | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch6  : Pcm1_Tx0 | I2S_Rx0  | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch7  : Pcm1_Tx1 | I2S_Rx1  | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch8  : ALL	   |  ALL     | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch9  : ALL	   |  ALL     | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch10 : ALL	   |  ALL     | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch11 : ALL	   |  ALL     | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch12 : ALL	   |  ALL     | ALL PCI TX 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch13 : ALL	   |  ALL     | ALL PCI RX 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch14 : ALL	   |  ALL     | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ch15 : ALL	   |  ALL     | ALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++spinlock_t  gdma_lock; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++spinlock_t  gdma_lock_mem; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++spinlock_t  gdma_int_lock; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void (*GdmaDoneIntCallback[MAX_GDMA_CHANNEL])(uint32_t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++void (*GdmaUnMaskIntCallback[MAX_GDMA_CHANNEL])(uint32_t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @brief Get free GDMA channel 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  ChNum   GDMA channel number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 1  	   channel is available 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 0  	   channels are all busy 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int _GdmaGetFreeCh(uint32_t *ChNum) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    unsigned long flags; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    uint32_t Data=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    uint32_t Ch=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_GDMA_DEBUG) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    static uint32_t Ch_RR=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    spin_lock_irqsave(&gdma_lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_GDMA_PCM_ONLY) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    for(Ch=14; Ch<MAX_GDMA_CHANNEL;Ch++)  //channel 14~max_channe, channel 0~13 be usedl 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    for(Ch=MAX_GDMA_CHANNEL; Ch<MAX_GDMA_CHANNEL;Ch++)  //no free channel 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined (CONFIG_GDMA_PCM_I2S_OTHERS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    for(Ch=14; Ch<MAX_GDMA_CHANNEL;Ch++)  //channel 14~max_channe, channel 0~13 be usedl 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    for(Ch=6; Ch<MAX_GDMA_CHANNEL;Ch++)  //channel 6~max_channel 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined (CONFIG_GDMA_EVERYBODY) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    for(Ch=0; Ch<MAX_GDMA_CHANNEL;Ch++)  //all channel 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined (CONFIG_GDMA_DEBUG) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    for(Ch=(Ch_RR++)%MAX_GDMA_CHANNEL; Ch<MAX_GDMA_CHANNEL;Ch++)  //round robin 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Data=GDMA_READ_REG(GDMA_CTRL_REG(Ch)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	/* hardware will reset this bit if transaction is done. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 * It means channel is free */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if((Data & (0x01<<CH_EBL_OFFSET))==0) {  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    *ChNum = Ch; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    spin_unlock_irqrestore(&gdma_lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    return 1; //Channel is free 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    spin_unlock_irqrestore(&gdma_lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    return 0; // Channels are all busy 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @brief Set channel is masked 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * When channel is masked, the GDMA transaction will stop.  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * When GDMA controller comes back from another channel (chain feature) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * >> Channel Mask=0: It's strange, and turns on related bit in GDMA interrupt 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * status register (16:23 Unmasked) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * >> Channel Mask=1: It'll start GDMA transation, and clear this bit.  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  ChNum   	GDMA channel number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 1  	   	success 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 0  	   	fail 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaMaskChannel(uint32_t ChNum) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    uint32_t Data=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data=GDMA_READ_REG(GDMA_CTRL_REG1(ChNum)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data |= ( 0x01 << CH_MASK_OFFSET);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_WRITE_REG(GDMA_CTRL_REG1(ChNum), Data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT("%s: Write %0X to %X\n", __FUNCTION__, Data, GDMA_CTRL_REG1(ChNum)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    return 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @brief Set channel is unmasked 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * You can unmask the channel to start GDMA transaction.  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * When GDMA controller comes back from another channel (chain feature) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * >> Channel Mask=0: It's strange, and turns on related bit in GDMA interrupt 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * status register (16:23 Unmasked) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * >> Channel Mask=1: It'll start GDMA transation, and clear this bit.  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  ChNum   	GDMA channel number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 1  	   	success 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 0  	   	fail 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaUnMaskChannel(uint32_t ChNum) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    uint32_t Data=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data=GDMA_READ_REG(GDMA_CTRL_REG1(ChNum)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data &= ~( 0x01 << CH_MASK_OFFSET);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_WRITE_REG(GDMA_CTRL_REG1(ChNum), Data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT("%s: Write %0X to %X\n", __FUNCTION__, Data, GDMA_CTRL_REG1(ChNum)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    return 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @brief Insert new GDMA entry to start GDMA transaction 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  ChNum   	GDMA channel number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 1  	   	success 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 0  	   	fail 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaReqQuickIns(uint32_t ChNum) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    uint32_t Data=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //Mask Channel 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data = GDMA_READ_REG(GDMA_CTRL_REG1(ChNum)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data |= ( 0x1 << CH_MASK_OFFSET);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_WRITE_REG(GDMA_CTRL_REG1(ChNum), Data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //Channel Enable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data = GDMA_READ_REG(GDMA_CTRL_REG(ChNum)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data |= (0x01<<CH_EBL_OFFSET);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_WRITE_REG(GDMA_CTRL_REG(ChNum), Data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    return 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int _GdmaReqEntryIns(GdmaReqEntry *NewEntry) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    uint32_t Data=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT("== << GDMA Control Reg (Channel=%d) >> ===\n", NewEntry->ChNum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT(" Channel Source Addr = %x \n", NewEntry->Src); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT(" Channel Dest Addr = %x \n", NewEntry->Dst); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT(" Transfer Count=%d\n", NewEntry->TransCount); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT(" Source DMA Req= DMA_REQ%d\n", NewEntry->SrcReqNum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT(" Dest DMA Req= DMA_REQ%d\n", NewEntry->DstReqNum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT(" Source Burst Mode=%s\n", NewEntry->SrcBurstMode ? "Fix" : "Inc"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT(" Dest Burst Mode=%s\n", NewEntry->DstBurstMode ? "Fix" : "Inc"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT(" Burst Size=%s\n", NewEntry->BurstSize ==0 ? "1 transfer" : \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    NewEntry->BurstSize ==1 ? "2 transfer" :\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    NewEntry->BurstSize ==2 ? "4 transfer" :\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    NewEntry->BurstSize ==3 ? "8 transfer" :\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    NewEntry->BurstSize ==4 ? "16 transfer" :\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    "Error"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT(" Hardware/Software Mode = %s\n", NewEntry->SoftMode ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    "Soft" : "Hw"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT("== << GDMA Control Reg1 (Channel=%d) >> =\n", NewEntry->ChNum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT("Channel Done Interrput=%s\n", (NewEntry->DoneIntCallback!=NULL) ?  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    "Enable" : "Disable"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT("Channel Unmasked Int=%s\n", (NewEntry->UnMaskIntCallback!=NULL) ?  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    "Enable" : "Disable"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if !defined (CONFIG_RALINK_RT3052) && !defined (CONFIG_RALINK_RT3883) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT("Coherent Interrupt =%s\n", (NewEntry->CoherentIntEbl==1)? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    "Enable" : "Disable"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT("Next Unmasked Channel=%d\n", NewEntry->NextUnMaskCh); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT("Channel Mask=%d\n", NewEntry->ChMask); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT("========================================\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_WRITE_REG(GDMA_SRC_REG(NewEntry->ChNum), NewEntry->Src); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT("SrcAddr: Write %0X to %X\n", \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    NewEntry->Src, GDMA_SRC_REG(NewEntry->ChNum)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_WRITE_REG(GDMA_DST_REG(NewEntry->ChNum), NewEntry->Dst); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT("DstAddr: Write %0X to %X\n", \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    NewEntry->Dst, GDMA_DST_REG(NewEntry->ChNum)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data |= ( (NewEntry->NextUnMaskCh) << NEXT_UNMASK_CH_OFFSET);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data |= ( NewEntry->ChMask << CH_MASK_OFFSET);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if !defined (CONFIG_RALINK_RT3052) && !defined (CONFIG_RALINK_RT3883) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data |= ( NewEntry->CoherentIntEbl << COHERENT_INT_EBL_OFFSET);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    if(NewEntry->UnMaskIntCallback!=NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Data |= (0x01<<CH_UNMASKINT_EBL_OFFSET);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	GdmaUnMaskIntCallback[NewEntry->ChNum] = NewEntry->UnMaskIntCallback; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data |= (NewEntry->SrcReqNum << SRC_DMA_REQ_OFFSET);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data |= (NewEntry->DstReqNum << DST_DMA_REQ_OFFSET);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_WRITE_REG(GDMA_CTRL_REG1(NewEntry->ChNum), Data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT("CTRL1: Write %08X to %8X\n", Data, GDMA_CTRL_REG1(NewEntry->ChNum)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data = ((NewEntry->TransCount) << TRANS_CNT_OFFSET);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_RT3052) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data |= (NewEntry->SrcReqNum << SRC_DMA_REQ_OFFSET);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data |= (NewEntry->DstReqNum << DST_DMA_REQ_OFFSET);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data |= (NewEntry->SrcBurstMode << SRC_BRST_MODE_OFFSET);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data |= (NewEntry->DstBurstMode << DST_BRST_MODE_OFFSET);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data |= (NewEntry->BurstSize << BRST_SIZE_OFFSET);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    if(NewEntry->DoneIntCallback!=NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Data |= (0x01<<CH_DONEINT_EBL_OFFSET);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	GdmaDoneIntCallback[NewEntry->ChNum] = NewEntry->DoneIntCallback; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    if(NewEntry->SoftMode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Data |= (0x01<<MODE_SEL_OFFSET);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Data |= (0x01<<CH_EBL_OFFSET);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_WRITE_REG(GDMA_CTRL_REG(NewEntry->ChNum), Data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //GDMA_READ_REG(GDMA_CTRL_REG(NewEntry->ChNum)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_PRINT("CTRL: Write %08X to %8X\n", Data, GDMA_CTRL_REG(NewEntry->ChNum));     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++     //if there is no interrupt handler, this function will  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //return 1 until GDMA done. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    if(NewEntry->DoneIntCallback==NULL) {  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//wait for GDMA processing done 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_RT3052)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	while((GDMA_READ_REG(RALINK_GDMAISTS) &  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		    (0x1<<NewEntry->ChNum))==0);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//write 1 clear 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	GDMA_WRITE_REG(RALINK_GDMAISTS, 1<< NewEntry->ChNum);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	while((GDMA_READ_REG(RALINK_GDMA_DONEINT) &  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		    (0x1<<NewEntry->ChNum))==0);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//write 1 clear 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	GDMA_WRITE_REG(RALINK_GDMA_DONEINT, 1<< NewEntry->ChNum);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    return 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @brief Start GDMA transaction for sending data to SPI 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *Src   	source address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *Dst    	destination address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  TransCount  	data length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *DoneIntCallback  callback function when transcation is done 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *UnMaskIntCallback  callback func when ch mask field is incorrect 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 1  	   	success 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 0  	   	fail 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaSpiTx( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint32_t Src,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint32_t Dst,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint16_t TransCount, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void (*DoneIntCallback)(uint32_t data), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void (*UnMaskIntCallback)(uint32_t data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GdmaReqEntry Entry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	#if defined (CONFIG_MIPS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Src= (Src & 0x1FFFFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Dst= (Dst & 0x1FFFFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  #else   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Src= Src; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Dst= Dst; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.TransCount = TransCount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SrcBurstMode=INC_MODE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DstBurstMode=FIX_MODE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.BurstSize=BUSTER_SIZE_4B;  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SrcReqNum=DMA_MEM_REQ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DstReqNum=DMA_SPI_TX_REQ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DoneIntCallback=DoneIntCallback; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.UnMaskIntCallback=UnMaskIntCallback; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SoftMode=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.ChMask=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.CoherentIntEbl=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//enable chain feature 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Entry.ChNum = GDMA_SPI_TX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Entry.NextUnMaskCh = GDMA_SPI_TX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    return _GdmaReqEntryIns(&Entry); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaSpiRx( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint32_t Src,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint32_t Dst,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint16_t TransCount, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void (*DoneIntCallback)(uint32_t data), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void (*UnMaskIntCallback)(uint32_t data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GdmaReqEntry Entry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	#if defined (CONFIG_MIPS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Src= (Src & 0x1FFFFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Dst= (Dst & 0x1FFFFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  #else   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Src= Src; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Dst= Dst; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.TransCount = TransCount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SrcBurstMode=FIX_MODE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DstBurstMode=INC_MODE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.BurstSize=BUSTER_SIZE_4B;  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SrcReqNum=DMA_SPI_RX_REQ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DstReqNum=DMA_MEM_REQ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DoneIntCallback=DoneIntCallback; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.UnMaskIntCallback=UnMaskIntCallback; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SoftMode=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.ChMask=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.CoherentIntEbl=1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//enable chain feature 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Entry.ChNum=GDMA_SPI_RX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Entry.NextUnMaskCh=GDMA_SPI_RX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    return _GdmaReqEntryIns(&Entry); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @brief Start GDMA transaction for sending data to I2S 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *Src   	source address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *Dst    	destination address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  TxNo    	I2S Tx number  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  TransCount  	data length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *DoneIntCallback  callback function when transcation is done 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *UnMaskIntCallback  callback func when ch mask field is incorrect 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 1  	   	success 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 0  	   	fail 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaI2sTx( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint32_t Src,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint32_t Dst,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint8_t TxNo, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint16_t TransCount, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void (*DoneIntCallback)(uint32_t data), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void (*UnMaskIntCallback)(uint32_t data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GdmaReqEntry Entry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	#if defined (CONFIG_MIPS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Src= (Src & 0x1FFFFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Dst= (Dst & 0x1FFFFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  #else   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Src= Src; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Dst= Dst; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.TransCount = TransCount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SrcBurstMode=INC_MODE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DstBurstMode=FIX_MODE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.BurstSize=BUSTER_SIZE_4B;  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SrcReqNum=DMA_MEM_REQ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DstReqNum=DMA_I2S_TX_REQ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DoneIntCallback=DoneIntCallback; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.UnMaskIntCallback=UnMaskIntCallback; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SoftMode=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.ChMask=1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.CoherentIntEbl=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    if(TxNo==0) { //TX0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//enable chain feature 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Entry.ChNum=GDMA_I2S_TX0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Entry.NextUnMaskCh= (TransCount==4) ?  GDMA_I2S_TX0 : GDMA_I2S_TX1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    }else if(TxNo==1) { //TX1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//enable chain feature 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Entry.ChNum=GDMA_I2S_TX1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Entry.NextUnMaskCh= (TransCount==4) ? GDMA_I2S_TX1 : GDMA_I2S_TX0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    }else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	GDMA_PRINT("I2S Tx Number %x is invalid\n", TxNo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    return _GdmaReqEntryIns(&Entry); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @brief Start GDMA transaction for receiving data to I2S 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *Src   	source address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *Dst    	destination address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  TxNo    	I2S Tx number  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  TransCount  	data length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *DoneIntCallback  callback function when transcation is done 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *UnMaskIntCallback  callback func when ch mask field is incorrect 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 1  	   	success 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 0  	   	fail 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaI2sRx( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint32_t Src,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint32_t Dst,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint8_t RxNo, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint16_t TransCount, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void (*DoneIntCallback)(uint32_t data), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void (*UnMaskIntCallback)(uint32_t data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GdmaReqEntry Entry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	#if defined (CONFIG_MIPS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Src= (Src & 0x1FFFFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Dst= (Dst & 0x1FFFFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  #else   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Src= Src; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Dst= Dst; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.TransCount = TransCount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SrcBurstMode=FIX_MODE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DstBurstMode=INC_MODE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.BurstSize=BUSTER_SIZE_4B;  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SrcReqNum=DMA_I2S_RX_REQ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DstReqNum=DMA_MEM_REQ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DoneIntCallback=DoneIntCallback; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.UnMaskIntCallback=UnMaskIntCallback; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SoftMode=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.ChMask=1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.CoherentIntEbl=1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    if(RxNo==0) { //RX0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//enable chain feature 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Entry.ChNum=GDMA_I2S_RX0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Entry.NextUnMaskCh=(TransCount==4) ? GDMA_I2S_RX0 : GDMA_I2S_RX1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    }else if(RxNo==1) { //RX1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//enable chain feature 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Entry.ChNum=GDMA_I2S_RX1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Entry.NextUnMaskCh=(TransCount==4) ? GDMA_I2S_RX1 : GDMA_I2S_RX0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    }else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	GDMA_PRINT("I2S Rx Number %x is invalid\n", RxNo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    return _GdmaReqEntryIns(&Entry); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @brief Start GDMA transaction for receiving data from PCM 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *Src   	source address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *Dst    	destination address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  TransCount   data length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  PcmNo    	PCM channel 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  RxNo    	PCM Rx number  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *DoneIntCallback  callback function when transcation is done 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *UnMaskIntCallback  callback func when ch mask field is incorrect 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 1  	   	success 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 0  	   	fail 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaPcmRx( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint32_t Src,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint32_t Dst,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint8_t PcmNo, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint8_t RxNo, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint16_t TransCount,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void (*DoneIntCallback)(uint32_t data), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void (*UnMaskIntCallback)(uint32_t data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GdmaReqEntry Entry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	#if defined (CONFIG_MIPS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Src= (Src & 0x1FFFFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Dst= (Dst & 0x1FFFFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  #else   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Src= Src; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Dst= Dst; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.TransCount = TransCount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SrcBurstMode=FIX_MODE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DstBurstMode=INC_MODE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.BurstSize=BUSTER_SIZE_4B;  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DstReqNum=DMA_MEM_REQ;  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DoneIntCallback=DoneIntCallback; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.UnMaskIntCallback=UnMaskIntCallback; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SoftMode=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.ChMask=1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.CoherentIntEbl=1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(RxNo > 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GDMA_PRINT("PCM Rx Number %x is invalid\n", RxNo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	switch(PcmNo) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 0: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		Entry.SrcReqNum=DMA_PCM_RX0_REQ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 1: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		Entry.SrcReqNum=DMA_PCM_RX1_REQ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 2: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		Entry.SrcReqNum=DMA_PCM_RX2_REQ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 3: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		Entry.SrcReqNum=DMA_PCM_RX3_REQ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GDMA_PRINT("PCM Channel %x is invalid\n", PcmNo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Entry.ChNum=GDMA_PCM_RX(PcmNo,RxNo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Entry.NextUnMaskCh=GDMA_PCM_RX(PcmNo,1-RxNo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    return _GdmaReqEntryIns(&Entry); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @brief Start GDMA transaction for sending data to PCM 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *Src		    source address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *Dst		    destination address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  TransCount	    data length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  PcmNo	    PCM channel 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  TxNo		    PCM Tx number  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *DoneIntCallback  callback func when transcation is done 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *UnMaskIntCallback  callback func when ch mask field is incorrect 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 1		    success 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 0		    fail 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaPcmTx( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint32_t Src,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint32_t Dst,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint8_t PcmNo, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint8_t TxNo, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint16_t TransCount,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void (*DoneIntCallback)(uint32_t data), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void (*UnMaskIntCallback)(uint32_t data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GdmaReqEntry Entry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	#if defined (CONFIG_MIPS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Src= (Src & 0x1FFFFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Dst= (Dst & 0x1FFFFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  #else   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Src= Src; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Dst= Dst; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.TransCount = TransCount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SrcBurstMode=INC_MODE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DstBurstMode=FIX_MODE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.BurstSize=BUSTER_SIZE_4B;  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SrcReqNum=DMA_MEM_REQ;  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DoneIntCallback=DoneIntCallback; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.UnMaskIntCallback=UnMaskIntCallback; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SoftMode=0; //Hardware Mode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.ChMask=1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.CoherentIntEbl=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(TxNo > 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++        GDMA_PRINT("PCM Tx Number %x is invalid\n", TxNo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	switch(PcmNo) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 0: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		Entry.DstReqNum=DMA_PCM_TX0_REQ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 1: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		Entry.DstReqNum=DMA_PCM_TX1_REQ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 2: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		Entry.DstReqNum=DMA_PCM_TX2_REQ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	case 3: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		Entry.DstReqNum=DMA_PCM_TX3_REQ; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GDMA_PRINT("PCM Channel %x is invalid\n", PcmNo);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Entry.ChNum=GDMA_PCM_TX(PcmNo,TxNo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	Entry.NextUnMaskCh=GDMA_PCM_TX(PcmNo,1-TxNo); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    return _GdmaReqEntryIns(&Entry); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @brief Start GDMA transaction for memory to memory copy 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *Src		    source address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *Dst		    destination address 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  TransCount	    data length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @param  *DoneIntCallback  callback function when transcation is done 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 1		    success 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @retval 0		    fail 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaMem2Mem( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint32_t Src,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint32_t Dst,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint16_t TransCount, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void (*DoneIntCallback)(uint32_t data) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GdmaReqEntry Entry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	#if defined (CONFIG_MIPS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Src= (Src & 0x1FFFFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Dst= (Dst & 0x1FFFFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  #else   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Src= Src; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.Dst= Dst; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  #endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //Entry.Src= virt_to_phys(Src); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //Entry.Dst= virt_to_phys(Dst);     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.TransCount = TransCount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SrcBurstMode=INC_MODE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DstBurstMode=INC_MODE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.BurstSize=BUSTER_SIZE_64B;  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SrcReqNum=DMA_MEM_REQ;  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DstReqNum=DMA_MEM_REQ;  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.DoneIntCallback=DoneIntCallback; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.UnMaskIntCallback=NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.SoftMode=1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.ChMask=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.CoherentIntEbl=1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //No reserved channel for Memory to Memory GDMA, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //get free channel on demand 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    if(!_GdmaGetFreeCh(&Entry.ChNum)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			GDMA_PRINT("GDMA Channels are all busy\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //set next channel to their own channel  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //to disable chain feature 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Entry.NextUnMaskCh= Entry.ChNum; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++      //printk ("ChNum = %d\n", Entry.ChNum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //set next channel to another channel 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //to enable chain feature 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //Entry.NextUnMaskCh= (Entry.ChNum+1) % MAX_GDMA_CHANNEL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    return _GdmaReqEntryIns(&Entry); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * @brief GDMA interrupt handler  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * When GDMA transcation is done, call related handler  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * to do the remain job. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++irqreturn_t GdmaIrqHandler( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int irq,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void *irqaction 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    u32 Ch=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    unsigned long flags; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_RT3052)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    u32 GdmaUnMaskStatus=GDMA_READ_REG(RALINK_GDMAISTS) & 0xFF0000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    u32 GdmaDoneStatus=GDMA_READ_REG(RALINK_GDMAISTS) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    u32 GdmaUnMaskStatus=GDMA_READ_REG(RALINK_GDMA_UNMASKINT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    u32 GdmaDoneStatus=GDMA_READ_REG(RALINK_GDMA_DONEINT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //printk("********GDMA Interrupt*******************\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //GDMA_PRINT("========================================\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //GDMA_PRINT("GdmaUnMask Interrupt=%x\n",GdmaUnMaskStatus); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //GDMA_PRINT("GdmaDone Interrupt=%x\n",GdmaDoneStatus); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //GDMA_PRINT("========================================\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    spin_lock_irqsave(&gdma_int_lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //write 1 clear 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_RT3052)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_WRITE_REG(RALINK_GDMAISTS, GdmaUnMaskStatus);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_WRITE_REG(RALINK_GDMA_UNMASKINT, GdmaUnMaskStatus);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //UnMask error 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    for(Ch=0;Ch<MAX_GDMA_CHANNEL;Ch++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if(GdmaUnMaskStatus & (0x1 << (UNMASK_INT_STATUS(Ch))) ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    if(GdmaUnMaskIntCallback[Ch] != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		GdmaUnMaskIntCallback[Ch](Ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	      // printk("GdmaUnMaskIntCallback \n");	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++     }	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++   
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //write 1 clear 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_RT3052)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++     GDMA_WRITE_REG(RALINK_GDMAISTS, GdmaDoneStatus);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++     GDMA_WRITE_REG(RALINK_GDMA_DONEINT, GdmaDoneStatus);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++     //printk("interrupt status = %x \n", GdmaDoneStatus); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++     //processing done 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++     for(Ch=0;Ch<MAX_GDMA_CHANNEL;Ch++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			if(GdmaDoneStatus & (0x1<<Ch)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    	if(GdmaDoneIntCallback[Ch] != NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    		//printk("*************Interrupt Ch=%d***********\n", Ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					GdmaDoneIntCallback[Ch](Ch);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//printk("interrupt status clear = %x \n", GDMA_READ_REG(RALINK_GDMA_DONEINT)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    spin_unlock_irqrestore(&gdma_int_lock, flags); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    return IRQ_HANDLED; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int RalinkGdmaInit(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    uint32_t Ret=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    uint32_t val = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    printk("Enable Ralink GDMA Controller Module \n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    printk("GDMA IP Version=%d\n", GET_GDMA_IP_VER); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++spin_lock_init(&gdma_int_lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++spin_lock_init(&gdma_lock); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//spin_lock_init(&gdma_lock_mem); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	#if defined (CONFIG_MIPS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    Ret = request_irq(SURFBOARDINT_DMA, GdmaIrqHandler, \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		    IRQF_DISABLED, "Ralink_DMA", NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    Ret = request_irq(SURFBOARDINT_DMA, GdmaIrqHandler, \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		    IRQF_TRIGGER_LOW, "Ralink_DMA", NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Ret = request_irq(SURFBOARDINT_DMA, GdmaIrqHandler, \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    SA_INTERRUPT, "Ralink_DMA", NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    Ret = request_irq(131, GdmaIrqHandler, \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    IRQF_TRIGGER_LOW, "Ralink_DMA", NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    if(Ret){ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	GDMA_PRINT("IRQ %d is not free.\n", SURFBOARDINT_DMA); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_MIPS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //Enable GDMA interrupt 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    val = le32_to_cpu(*(volatile u32 *)(RALINK_REG_INTENA)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    val |= RALINK_INTCTL_DMA; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_WRITE_REG(RALINK_REG_INTENA, val); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //Channel0~Channel7 are round-robin 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_RT3052) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_WRITE_REG(RALINK_GDMAGCT, 0x01); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_WRITE_REG(RALINK_GDMA_GCT, 0x01); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#error Please Choose System Type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static void __exit RalinkGdmaExit(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    printk("Disable Ralink GDMA Controller Module\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_MIPS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    //Disable GDMA interrupt 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    GDMA_WRITE_REG(RALINK_REG_INTDIS, RALINK_INTCTL_DMA); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    free_irq(SURFBOARDINT_DMA, NULL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++module_init(RalinkGdmaInit); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++module_exit(RalinkGdmaExit); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(GdmaI2sRx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(GdmaI2sTx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(GdmaPcmRx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(GdmaPcmTx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(GdmaSpiRx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(GdmaSpiTx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(GdmaMem2Mem); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(GdmaReqQuickIns); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(GdmaMaskChannel); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++EXPORT_SYMBOL(GdmaUnMaskChannel); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_DESCRIPTION("Ralink SoC GDMA Controller API Module"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_AUTHOR("Steven Liu <[email protected]>"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_LICENSE("GPL"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++MODULE_VERSION(MOD_VERSION); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- /dev/null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/mtk/ralink_gdma.h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -0,0 +1,326 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *************************************************************************** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Ralink Tech Inc. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 5F., No.36, Taiyuan St., Jhubei City, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Hsinchu County 302, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * Taiwan, R.O.C. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * (c) Copyright, Ralink Technology, Inc. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  This program is free software; you can redistribute  it and/or modify it 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  under  the terms of  the GNU General  Public License as published by the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  Free Software Foundation;  either version 2 of the  License, or (at your 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  option) any later version. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  You should have received a copy of the  GNU General Public License along 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  with this program; if not, write  to the Free Software Foundation, Inc., 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *  675 Mass Ave, Cambridge, MA 02139, USA. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *************************************************************************** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifndef __RALINK_DMA_CTRL_H__ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define __RALINK_DMA_CTRL_H__ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//#include <asm/rt2880/rt_mmap.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * DEFINITIONS AND MACROS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MOD_VERSION 			"0.4" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MAX_GDMA_CHANNEL		16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined (CONFIG_RALINK_RT3052) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MAX_GDMA_CHANNEL		8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MAX_GDMA_CHANNEL		16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#error Please Choose System Type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RALINK_GDMA_CTRL_BASE		(RALINK_GDMA_BASE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_RT3052) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RALINK_GDMAISTS			(RALINK_GDMA_BASE + 0x80) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RALINK_GDMAGCT			(RALINK_GDMA_BASE + 0x88) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RALINK_GDMA_UNMASKINT		(RALINK_GDMA_BASE + 0x200) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RALINK_GDMA_DONEINT		(RALINK_GDMA_BASE + 0x204) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RALINK_GDMA_GCT			(RALINK_GDMA_BASE + 0x220) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define KSEG1                   0xa0000000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define PHYS_TO_VIRT(x)         ((void *)((x) | KSEG1)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define VIRT_TO_PHYS(x)         ((unsigned long)(x) & ~KSEG1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <mach/sync_write.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_READ_REG(phys)            (*(volatile unsigned int *)((phys))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_WRITE_REG(phys, val)      mt65xx_reg_sync_writel((val), (phys)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_READ_REG(addr) 		(le32_to_cpu(*(volatile u32 *)(addr))) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_WRITE_REG(addr, val)  	*((volatile uint32_t *)(addr)) = cpu_to_le32(val) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GET_GDMA_IP_VER			(GDMA_READ_REG(RALINK_GDMA_GCT) & 0x6) >> 1 //GDMA_GCT[2:1] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RALINK_IRQ_ADDR                 RALINK_INTCL_BASE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7628) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RALINK_REG_INTENA               (RALINK_IRQ_ADDR + 0x80) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RALINK_REG_INTDIS               (RALINK_IRQ_ADDR + 0x78) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RALINK_REG_INTENA               (RALINK_IRQ_ADDR + 0x34) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RALINK_REG_INTDIS               (RALINK_IRQ_ADDR + 0x38) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/*  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 12bytes=GDMA Channel n Source Address(4) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *         GDMA Channel n Destination Address(4) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ *         GDMA Channel n Control Register(4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_SRC_REG(ch)		(RALINK_GDMA_BASE + ch*16) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_DST_REG(ch)		(GDMA_SRC_REG(ch) + 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_CTRL_REG(ch)		(GDMA_DST_REG(ch) + 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_CTRL_REG1(ch)		(GDMA_CTRL_REG(ch) + 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//GDMA Interrupt Status Register 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_RT3052) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define UNMASK_INT_STATUS(ch)           (ch+16) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define UNMASK_INT_STATUS(ch)           (ch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define TXDONE_INT_STATUS(ch)           (ch) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//Control Reg0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define MODE_SEL_OFFSET			0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CH_EBL_OFFSET			1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CH_DONEINT_EBL_OFFSET		2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define BRST_SIZE_OFFSET		3 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define DST_BRST_MODE_OFFSET		6 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define SRC_BRST_MODE_OFFSET		7 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define TRANS_CNT_OFFSET		16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//Control Reg1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_RT3052) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CH_UNMASKINT_EBL_OFFSET		4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define NEXT_UNMASK_CH_OFFSET		1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CH_UNMASKINT_EBL_OFFSET		1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define NEXT_UNMASK_CH_OFFSET		3 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define COHERENT_INT_EBL_OFFSET		2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define CH_MASK_OFFSET			0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_RT3052) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//Control Reg0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define DST_DMA_REQ_OFFSET		8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define SRC_DMA_REQ_OFFSET		12 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#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) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//Control Reg1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define DST_DMA_REQ_OFFSET		8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define SRC_DMA_REQ_OFFSET		16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_PCM0_RX0			0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_PCM0_RX1			1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_PCM0_TX0			2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_PCM0_TX1			3 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_PCM1_RX0			4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_PCM1_RX1			5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_PCM1_TX0			6 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_PCM1_TX1			7 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_PCM_RX(i,j)		(0+((i)<<2)+j) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_PCM_TX(i,j)        (2+((i)<<2)+j) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_I2S_TX0			4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_I2S_TX1			5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_I2S_RX0			6 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_I2S_RX1			7 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_SPI_TX       13 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_SPI_RX       12 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//#define GDMA_DEBUG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#ifdef GDMA_DEBUG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_PRINT(fmt, args...) printk(KERN_INFO "GDMA: " fmt, ## args) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define GDMA_PRINT(fmt, args...) { } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * TYPEDEFS AND STRUCTURES 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++enum GdmaBusterMode { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	INC_MODE=0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	FIX_MODE=1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++enum GdmaBusterSize { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	BUSTER_SIZE_4B=0, 	/* 1 transfer */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	BUSTER_SIZE_8B=1, 	/* 2 transfer */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	BUSTER_SIZE_16B=2,  	/* 4 transfer */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	BUSTER_SIZE_32B=3,  	/* 8 transfer */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	BUSTER_SIZE_64B=4  	/* 16 transfer */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++enum GdmaDmaReqNum { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (CONFIG_RALINK_RT3052) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_REQ0=0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_NAND_REQ=1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_I2S_TX_REQ=2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_RX0_REQ=3, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_RX1_REQ=4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_TX0_REQ=5, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_TX1_REQ=6, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_REG7=7, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_MEM_REQ=8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_REQ0=0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_NAND_REQ=1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_I2S_TX_REQ=2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_I2S_RX_REQ=3, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_RX0_REQ=4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_RX1_REQ=5, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_TX0_REQ=6, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_TX1_REQ=7, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_CODEC0_REQ8=8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_CODEC1_REQ9=9, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_REQ10=10, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_REQ11=11, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_REQ12=12, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_REQ13=13, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_REQ14=14, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_REQ15=15, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	#if defined (CONFIG_RALINK_RT3883) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		DMA_MEM_REQ=16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	#elif defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855)  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		DMA_MEM_REQ=32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_REQ0=0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_NAND_REQ=1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_I2S_TX_REQ=2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_I2S_RX_REQ=3, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_RX0_REQ=4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_RX1_REQ=5, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_TX0_REQ=6, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_TX1_REQ=7, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_RX2_REQ=8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_RX3_REQ=9, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_TX2_REQ=10, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_TX3_REQ=11, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_SPI_RX_REQ=12, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_SPI_TX_REQ=13,	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_MEM_REQ=32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined (CONFIG_RALINK_RT6855A) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_NAND_REQ=0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_I2S_TX_REQ=1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_I2S_RX_REQ=2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_REQ0=3, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_RX0_REQ=4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_RX1_REQ=5, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_TX0_REQ=6, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_PCM_TX1_REQ=7, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_CODEC0_REQ8=8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_CODEC1_REQ9=9, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_REQ10=10, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_REQ11=11, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_REQ12=12, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_REQ13=13, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_REQ14=14, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_REQ15=15, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	DMA_MEM_REQ=32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#error Please Choose System Type 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++typedef struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint32_t Src; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint32_t Dst; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint16_t TransCount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint8_t  SoftMode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint8_t  NextUnMaskCh; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint8_t  ChMask; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint8_t  CoherentIntEbl; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	uint32_t  ChNum; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	enum GdmaDmaReqNum SrcReqNum; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	enum GdmaDmaReqNum DstReqNum; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	enum GdmaBusterMode SrcBurstMode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	enum GdmaBusterMode DstBurstMode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	enum GdmaBusterSize BurstSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void (*DoneIntCallback)(uint32_t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void (*UnMaskIntCallback)(uint32_t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} GdmaReqEntry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * EXPORT FUNCTION 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaI2sTx(uint32_t Src, uint32_t Dst, uint8_t TxNo, uint16_t TransCount, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		void (*DoneIntCallback)(uint32_t data),  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		void (*UnMaskIntCallback)(uint32_t data)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaI2sRx(uint32_t Src, uint32_t Dst, uint8_t RxNo, uint16_t TransCount, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		void (*DoneIntCallback)(uint32_t data),  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		void (*UnMaskIntCallback)(uint32_t data)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaPcmRx(uint32_t Src, uint32_t Dst, uint8_t PcmNo, uint8_t RxNo, uint16_t TransCount, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		void (*DoneIntCallback)(uint32_t data),  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		void (*UnMaskIntCallback)(uint32_t data)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaPcmTx(uint32_t Src, uint32_t Dst, uint8_t PcmNo, uint8_t TxNo, uint16_t TransCount, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		void (*DoneIntCallback)(uint32_t data),  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		void (*UnMaskIntCallback)(uint32_t data)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaSpiTx(uint32_t Src, uint32_t Dst, uint16_t TransCount, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void (*DoneIntCallback)(uint32_t data), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void (*UnMaskIntCallback)(uint32_t data)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaSpiRx(uint32_t Src, uint32_t Dst, uint16_t TransCount, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void (*DoneIntCallback)(uint32_t data), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	void (*UnMaskIntCallback)(uint32_t data));	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaMem2Mem(uint32_t Src, uint32_t Dst, uint16_t TransCount,  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		void (*DoneIntCallback)(uint32_t data));  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaMaskChannel(uint32_t ChNum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaUnMaskChannel(uint32_t ChNum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int GdmaReqQuickIns(uint32_t ChNum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- a/sound/soc/soc-core.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/soc-core.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -1851,7 +1851,8 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	/* Bodge while we unpick instantiation */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	card->dev = &pdev->dev; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	return snd_soc_register_card(card); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_register_card(card); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ static int soc_cleanup_card_resources(struct snd_soc_card *card) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- /dev/null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/mtk/i2s_debug.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -0,0 +1,698 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/init.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/version.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/module.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/kernel.h> /* printk() */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "i2s_ctrl.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/delay.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/jiffies.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/random.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <linux/slab.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <asm/uaccess.h> /* copy_from/to_user */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_SND_RALINK_SOC) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include <sound/soc/mtk/mtk_audio_device.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8750) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "../codec/i2c_wm8750.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "../codec/i2c_wm8751.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "i2c_wm8960.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//#define INTERNAL_LOOPBACK_DEBUG 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern unsigned long i2s_codec_12p288Mhz[11]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern unsigned long i2s_codec_12Mhz[11];  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern unsigned long i2s_inclk_int_16bit[13]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern unsigned long i2s_inclk_comp_16bit[13]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern unsigned long i2s_inclk_int_24bit[13]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern unsigned long i2s_inclk_comp_24bit[13]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern unsigned long i2s_inclk_int[11]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern unsigned long i2s_inclk_comp[11]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern int i2s_pll_config_mt7621(unsigned long index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern int i2s_pll_config_mt7623(unsigned long index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern void audiohw_loopback(int fsel); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern void audiohw_bypass(void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern int audiohw_set_lineout_vol(int Aout, int vol_l, int vol_r); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern int audiohw_set_linein_vol(int vol_l, int vol_r); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++extern void audiohw_codec_exlbk(void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++unsigned long txbuffer[512] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			       	0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			       	0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			       	0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 3 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			       	0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 4 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			       	0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			       	0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 6 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			       	0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 7 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			       	0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00  //round 8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++int i2s_debug_cmd(unsigned int cmd, unsigned long arg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long data, index; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	unsigned long *pTable; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	switch(cmd) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		case I2S_DEBUG_CLKGEN: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("I2S_DEBUG_CLKGEN\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT3052) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB0000060) = 0x00000016; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB0000030) = 0x00009E00; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB0000A00) = 0xC0000040; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_RT3350)		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB0000060) = 0x00000018; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB000002C) = 0x00000100; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB0000030) = 0x00009E00; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB0000A00) = 0xC0000040;			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_RT3883)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB0000060) = 0x00000018; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB000002C) = 0x00003000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB0000A00) = 0xC1104040; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB0000A24) = 0x00000027; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB0000A20) = 0x80000020; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif (defined(CONFIG_RALINK_RT3352)||defined(CONFIG_RALINK_RT5350)) || defined (CONFIG_RALINK_RT6855) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB0000060) = 0x00000018; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB000002C) = 0x00000300; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB0000A00) = 0xC1104040; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB0000A24) = 0x00000027; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB0000A20) = 0x80000020;			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_RT6855A) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x860) = 0x00008080; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x82C) = 0x00000300; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0xC1104040; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_I2S_BASE+0x24) = 0x00000027; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_I2S_BASE+0x20) = 0x80000020;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//#error "I2S debug mode not support this Chip"			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		case I2S_DEBUG_INLBK: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("I2S_DEBUG_INLBK\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7621) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        switch(96000) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                case 8000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        index = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                case 11025: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        index = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                case 12000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        index = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                case 16000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        index = 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                case 22050: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        index = 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                case 24000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        index = 5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                case 32000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        index = 6; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                case 44100: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        index = 7; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                case 48000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        index = 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                case 88200: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        index = 9; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                case 96000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        index = 10; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				case 192000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        index = 11; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                                        index = 7; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        i2s_pll_config_mt7621(index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_pll_config_mt7623(11); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT3052) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT6855A) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x834) |= 0x00020000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x834) &= 0xFFFDFFFF;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_I2S_BASE+0x0) &= 0x7FFFFFFF;	//Rest I2S to default vaule	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x860) |= 0x00008080; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x82C) = 0x00000300; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_MT7621) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x34) |= 0x00020000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x34) &= 0xFFFDFFFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        *(volatile unsigned long*)(RALINK_I2S_BASE+0x0) &= 0x7FFFFFFF;   //Rest I2S to default vaule 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x60) = 0x00000010;     //GPIO purpose selection 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_MT7628) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x34) |= 0x00020000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x34) &= 0xFFFDFFFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        *(volatile unsigned long*)(RALINK_I2S_BASE+0x0) &= 0x7FFFFFFF;   //Rest I2S to default vaule 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x60) &= ~((0x3)<<6);     //GPIO purpose selection /*FIXME*/ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xFB000034) |= 0x00020000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xFB000034) &= 0xFFFDFFFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(ETHDMASYS_I2S_BASE+0x0) &= 0x7FFFFFFF;   //Rest I2S to default vaule 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xF0005840) &= ~((0x7)<<12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xF0005840) |= ((0x6)<<12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xF0005840) &= ~((0x7)<<9); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xF0005840) |= ((0x6)<<9); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xF0005040) |= ((0x1)<<10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xF0005040) |= ((0x1)<<9); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xF00057F0) &= ~((0x7)<<12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xF00057F0) |= ((0x6)<<12); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xF0005030) |= ((0x1)<<1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xF0005840) &= ~((0x7)<<6); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xF0005840) |= ((0x6)<<6); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xF0005040) &= ~((0x1)<<8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xF00058F0) &= ~((0x7)<<3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xF00058F0) |= ((0x6)<<3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xF0005070) |= ((0x1)<<14); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB0000034) |= 0x00020000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB0000034) &= 0xFFFDFFFF;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB0000A00) &= 0x7FFFFFFF;	//Rest I2S to default vaule 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB0000060) = 0x00000018; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT3883)			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB000002C) = 0x00003000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xB000002C) = 0x00000300; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7621) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        *(volatile unsigned long*)(RALINK_I2S_BASE+0x18) = 0x80000000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        *(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0xc1104040; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        pTable = i2s_inclk_int; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        data = pTable[index]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        //*(volatile unsigned long*)(RALINK_I2S_BASE+0x24) = data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        i2s_outw(RALINK_I2S_BASE+0x24, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        pTable = i2s_inclk_comp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        data = pTable[index]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        //*(volatile unsigned long*)(RALINK_I2S_BASE+0x20) = data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        i2s_outw(RALINK_I2S_BASE+0x20, (data|0x80000000)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_RALINK_MT7628) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			index =11;  /* SR: 192k */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_I2S_BASE+0x18) = 0x80000000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        *(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0xc1104040; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        pTable = i2s_inclk_int_16bit; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			//pTable = i2s_inclk_int_24bit; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        data = pTable[index]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        //*(volatile unsigned long*)(RALINK_I2S_BASE+0x24) = data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        i2s_outw(RALINK_I2S_BASE+0x24, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        pTable = i2s_inclk_comp_16bit; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			//pTable = i2s_inclk_comp_24bit; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        data = pTable[index]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        //*(volatile unsigned long*)(RALINK_I2S_BASE+0x20) = data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        i2s_outw(RALINK_I2S_BASE+0x20, (data|0x80000000)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			mdelay(5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#elif defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			index = 11; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(I2S_I2SCFG1) = 0x80000000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(I2S_I2SCFG) = 0xE1104040; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(ETHDMASYS_SYSCTL_BASE+0x30) |= 0x00020000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(ETHDMASYS_SYSCTL_BASE+0x2c) |= 0x00000080; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pTable = i2s_inclk_int_16bit; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			//pTable = i2s_inclk_int_24bit; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        data = pTable[index]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        i2s_outw(I2S_DIVINT_CFG, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        pTable = i2s_inclk_comp_16bit; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			//pTable = i2s_inclk_comp_24bit; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        data = pTable[index]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++                        i2s_outw(I2S_DIVCOMP_CFG, (data|0x80000000)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			mdelay(5); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_I2S_BASE+0x18) = 0x80000000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0xC1104040; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_I2S_BASE+0x24) = 0x00000006; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_I2S_BASE+0x20) = 0x80000105; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				int count = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				int k=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				int enable_cnt=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				unsigned long param[4]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				unsigned long data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				//unsigned long data_tmp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				unsigned long ff_status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			  	//unsigned long* txbuffer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				int j=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				int temp = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (INTERNAL_LOOPBACK_DEBUG) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				int count2 = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				memset(param, 0, 4*sizeof(unsigned long) );	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				copy_from_user(param, (unsigned long*)arg, sizeof(long)*2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				txbuffer = (unsigned long*)kcalloc(param[0], sizeof(unsigned long), GFP_KERNEL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				if(txbuffer == NULL) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				//ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				ff_status = *(volatile unsigned long*)(I2S_FF_STATUS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				printk("ff status=[0x%08X]\n",(u32)ff_status); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				for(i = 0; i < param[0]; i++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					if (i==0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						txbuffer[i] = 0x555A555A; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						printk("%d: 0x%8lx\n", i, txbuffer[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					else  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,14) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						srandom32(jiffies); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						txbuffer[i] = random32()%(0x555A555A)+1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						//printk("%d: 0x%8x\n", i, txbuffer[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						//TODO:do we need to implement random32() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						txbuffer[i] = 0x01010101;					 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				for( i = 0 ; i < param[0] ; i ++ ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					ff_status = *(volatile unsigned long*)(I2S_FF_STATUS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					if((ff_status&0xFF) > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					if((ff_status&0x0F) > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						*(volatile unsigned long*)(I2S_TX_FIFO_WREG) = txbuffer[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						mdelay(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						mdelay(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						printk("[%d]NO TX FREE FIFO ST=[0x%08X]\n", i, (u32)ff_status); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						continue;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					//if(i >= 16) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						ff_status = *(volatile unsigned long*)(I2S_FF_STATUS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					#if defined(CONFIG_RALINK_MT7628) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						if(((ff_status>>8)&0xFF) > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						if(((ff_status>>4)&0x0F) > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							data = *(volatile unsigned long*)(I2S_RX_FIFO_RREG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							//data_tmp = *(volatile unsigned long*)(I2S_RX_FIFO_RREG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							//MSG("[0x%08X] vs [0x%08X]\n", (u32)data, (u32)data_tmp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							printk("*[%d]NO RX FREE FIFO ST=[0x%08X]\n", i, (u32)ff_status); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						if (data == txbuffer[0]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							k = i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							enable_cnt = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						if (enable_cnt==1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							if(data!= txbuffer[i-k]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++								MSG("[%d][0x%08X] vs [0x%08X]\n", (i-k), (u32)data, (u32)txbuffer[i-k]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++								//MSG("**[%d][0x%08X] vs [0x%08X]\n" ,(i-k), (u32)data , (u32)txbuffer[i-k]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++								count++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++								data=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					}	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if 0	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				temp = i-k; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				for (j=0; j<k; j++) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					//ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					ff_status = *(volatile unsigned long*)(I2S_FF_STATUS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					if(((ff_status>>8)&0xFF) > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					if(((ff_status>>4)&0x0F) > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						//data = *(volatile unsigned long*)(RALINK_I2S_BASE+0x14); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						data = *(volatile unsigned long*)(I2S_RX_FIFO_RREG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						printk("*NO RX FREE FIFO ST=[0x%08X]\n", (u32)ff_status); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					if(data!= txbuffer[temp+j]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						MSG("[%d][0x%08X] vs [0x%08X]\n", (temp+j), (u32)data, (u32)txbuffer[temp+j]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						//MSG("&&[%d][0x%08X] vs [0x%08X]\n" ,(temp+j), (u32)data , (u32)txbuffer[temp+j]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						count++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						data=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					if ((temp+j)==128) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						//ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						ff_status = *(volatile unsigned long*)(I2S_FF_STATUS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						//printk("[%d]FIFO ST=[0x%08X]\n", (temp+j), (u32)ff_status); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined (INTERNAL_LOOPBACK_DEBUG) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				for( i = 0 ; i < param[0] ; i ++ ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					//ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					ff_status = *(volatile unsigned long*)(I2S_FF_STATUS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				#if defined(CONFIG_RALINK_MT7628)|| defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					if((ff_status&0xFF) > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					if((ff_status&0x0F) > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						//*(volatile unsigned long*)(RALINK_I2S_BASE+0x10) = txbuffer[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						*(volatile unsigned long*)(I2S_TX_FIFO_WREG) = txbuffer[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						mdelay(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						mdelay(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						printk("[%d]NO TX FREE FIFO ST=[0x%08X]\n", i, (u32)ff_status); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						continue;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					//if(i >= 16) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						//ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						ff_status = *(volatile unsigned long*)(I2S_FF_STATUS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					#if defined(CONFIG_RALINK_MT7628)|| defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						if(((ff_status>>8)&0xFF) > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						if(((ff_status>>4)&0x0F) > 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							//data = *(volatile unsigned long*)(RALINK_I2S_BASE+0x14); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							data = *(volatile unsigned long*)(I2S_RX_FIFO_RREG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							printk("*[%d]NO RX FREE FIFO ST=[0x%08X]\n", i, (u32)ff_status); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							if(data!= txbuffer[i]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++								MSG("[%d][0x%08X] vs [0x%08X]\n", (i), (u32)data, (u32)txbuffer[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++								MSG("**[%d][0x%08X] vs [0x%08X]\n" ,(i), (u32)data , (u32)txbuffer[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++								count2++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++								data=0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++							} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++						} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					}	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				printk("Pattern match done count2=%d.\n", count2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				printk("Pattern match done count=%d.\n", count); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			}	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xFB000034) |= 0x00020000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(0xFB000034) &= 0xFFFDFFFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(ETHDMASYS_I2S_BASE+0x0) &= 0x7FFFFFFF;   //Rest I2S to default vaule 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if !defined(CONFIG_RALINK_RT3052) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		case I2S_DEBUG_EXLBK: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("I2S_DEBUG_EXLBK\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if !defined(CONFIG_ARCH_MT7623) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			switch(arg) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				case 8000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					index = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				case 11025: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					index = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				case 12000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					index = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					break;			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				case 16000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					index = 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				case 22050: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					index = 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				case 24000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					index = 5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					break;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				case 32000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					index = 6; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					break;			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				case 44100: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					index = 7; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				case 48000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					index = 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				case 88200: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					index = 9; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					break;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				case 96000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					index = 10; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++					index = 7; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT3052) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT6855A) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x860) = 0x00008080; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			//*(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x82C) = 0x00000300; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x60) = 0x00000018; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_RT3883) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x2C) = 0x00003000;			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x2C) = 0x00000300; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_I2S_BASE+0x18) = 0x40000000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			*(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0x81104040; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7628) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pTable = i2s_inclk_int_16bit; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pTable = i2s_inclk_int; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			data = (volatile unsigned long)(pTable[index]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_outw(I2S_DIVINT_CFG, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_RALINK_MT7628) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pTable = i2s_inclk_comp_16bit; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pTable = i2s_inclk_comp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			data = (volatile unsigned long)(pTable[index]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			data |= REGBIT(1, I2S_CLKDIV_EN); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_outw(I2S_DIVCOMP_CFG, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#if defined(CONFIG_I2S_MCLK_12MHZ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pTable = i2s_codec_12Mhz; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			#if defined(CONFIG_I2S_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				data = pTable[index]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				data = pTable[index]|0x01; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			pTable = i2s_codec_12p288Mhz; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			data = pTable[index]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			audiohw_preinit(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#if defined (CONFIG_I2S_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			audiohw_postinit(1, 1, 1, 1, 0); // for codec apll enable, 16 bit word length  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#elif defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    			audiohw_postinit(1, 1, 1, 0); // for 16 bit word length  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#if defined (CONFIG_I2S_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			audiohw_set_frequency(data, 1);	// for codec apll enable 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#elif defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++            		audiohw_set_frequency(data|0x1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			audiohw_set_lineout_vol(1, 100, 100); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			audiohw_set_linein_vol(100, 100); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#if defined(CONFIG_I2S_TXRX)			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			//audiohw_loopback(data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#if !defined(CONFIG_RALINK_RT3052) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		case I2S_DEBUG_CODECBYPASS:			 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#if defined(CONFIG_I2S_TXRX) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#if defined(CONFIG_RALINK_MT7628)	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			data = i2s_inw(RALINK_SYSCTL_BASE+0x60);  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			//data &= ~(0x3<<4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			data &= ~(0x3<<6); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			data &= ~(0x3<<16); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			data &= ~(0x1<<14); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_outw(RALINK_SYSCTL_BASE+0x60, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			data = i2s_inw(RALINK_SYSCTL_BASE+0x2c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			data &= ~(0x07<<9); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			i2s_outw(RALINK_SYSCTL_BASE+0x2c, data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			audiohw_bypass();	/* did not work */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		case I2S_DEBUG_FMT: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		case I2S_DEBUG_RESET: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if defined(CONFIG_I2S_WM8960) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		case I2S_DEBUG_CODEC_EXLBK: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			audiohw_codec_exlbk(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			MSG("Not support this debug cmd [%d]\n", cmd);	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			break;				 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0;	 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- a/sound/soc/codecs/wm8960.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/codecs/wm8960.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -26,6 +26,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include <sound/wm8960.h> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #include "wm8960.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#include "../mtk/i2c_wm8960.h" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ /* R25 - Power 1 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #define WM8960_VMID_MASK 0x180 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -53,10 +54,10 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  * using 2 wire for device control, so we cache them instead. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ static const struct reg_default wm8960_reg_defaults[] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	{  0x0, 0x00a7 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	{  0x1, 0x00a7 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	{  0x2, 0x0000 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	{  0x3, 0x0000 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{  0x0, 0x002b }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{  0x1, 0x002b }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{  0x2, 0x00ff }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{  0x3, 0x00ff }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	{  0x4, 0x0000 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	{  0x5, 0x0008 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	{  0x6, 0x0000 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -88,8 +89,8 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	{ 0x25, 0x0050 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	{ 0x26, 0x0000 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	{ 0x27, 0x0000 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	{ 0x28, 0x0000 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	{ 0x29, 0x0000 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 0x28, 0x007b }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	{ 0x29, 0x007b }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	{ 0x2a, 0x0040 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	{ 0x2b, 0x0000 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	{ 0x2c, 0x0000 }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -127,8 +128,15 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	int playback_fs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define wm8960_reset(c)        do{ \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++       int i = 0;\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++       snd_soc_write(c, WM8960_RESET, 0);\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++       for(i = 0; i < 1000*HZ; i++);\ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++       }while(0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #define wm8960_reset(c)	snd_soc_write(c, WM8960_RESET, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ /* enumerated controls */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ static const char *wm8960_polarity[] = {"No Inversion", "Left Inverted", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	"Right Inverted", "Stereo Inversion"}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -181,8 +189,8 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	ucontrol->value.integer.value[0] = wm8960->deemph; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//ucontrol->value.integer.value[0] = wm8960->deemph; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return wm8960->deemph; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ static int wm8960_put_deemph(struct snd_kcontrol *kcontrol, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -200,6 +208,70 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	return wm8960_set_deemph(codec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int wm8960_preinit(struct snd_soc_codec *codec) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("****** %s ******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_RESET, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	mdelay(500); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int wm8960_postinit(struct snd_soc_codec *codec) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	u32 data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	//printk("****** %s ******\n", __func__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	// In 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = snd_soc_read(codec, WM8960_POWER1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_POWER1, data|WM8960_PWR1_ADCL|WM8960_PWR1_ADCR|WM8960_PWR1_AINL |WM8960_PWR1_AINR|WM8960_PWR1_MICB);//0x19 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = snd_soc_read(codec, WM8960_ADDCTL1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_ADDCTL1, data|ADDITIONAL1_DATSEL(0x01));//0x17 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_LADC, LEFTGAIN_LDVU|LEFTGAIN_LDACVOL(0xc3));//0x15 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_RADC, LEFTGAIN_LDVU|LEFTGAIN_LDACVOL(0xc3));//0x16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_LINPATH, 0x148);//0x20 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_RINPATH, 0x148);//0x21 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_POWER3, WM8960_PWR3_LMIC|WM8960_PWR3_RMIC);//0x2f 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	// Out 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = snd_soc_read(codec, WM8960_POWER2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	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 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	mdelay(10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_IFACE2, 0x40); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_LDAC, LEFTGAIN_LDVU|LEFTGAIN_LDACVOL(0xff));//0x0a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_RDAC, RIGHTGAIN_RDVU|RIGHTGAIN_RDACVOL(0xff));//0x0b 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_LOUTMIX, 0x100);//0x22 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_ROUTMIX, 0x100);//0x25 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = snd_soc_read(codec, WM8960_POWER3); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_POWER3, data|WM8960_PWR3_ROMIX|WM8960_PWR3_LOMIX);//0x2f 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_CLASSD1, 0xf7);//0x31 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_CLASSD3, 0xad);//0x33 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_DACCTL1,  0x000);//0x05 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	data = snd_soc_read(codec, WM8960_POWER1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_POWER1,  data|0x1c0);//0x19 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_LOUT1, LOUT1_LO1VU|LOUT1_LO1ZC|LOUT1_LOUT1VOL(115));//0x02 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_ROUT1, ROUT1_RO1VU|ROUT1_RO1ZC|ROUT1_ROUT1VOL(115));//0x03 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_LINVOL, LINV_IPVU|LINV_LINVOL(110)); //LINV(0x00)=>0x12b 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_RINVOL, RINV_IPVU|RINV_RINVOL(110)); //LINV(0x01)=>0x12b 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++static int wm8960_close(struct snd_soc_codec *codec) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_DACCTL1,0x8); //0x05->0x08 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_POWER1, 0x000); //0x19->0x000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	mdelay(300); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	snd_soc_write(codec, WM8960_POWER2, 0x000); //0x1a->0x000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ static const DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 50, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -542,6 +614,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	/* set iface */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	snd_soc_write(codec, WM8960_IFACE1, iface); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	wm8960_postinit(codec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -623,11 +696,16 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	case SND_SOC_BIAS_PREPARE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		/* Set VMID to 2x50k */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x80); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	case SND_SOC_BIAS_STANDBY: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		wm8960_preinit(codec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			regcache_sync(wm8960->regmap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -650,9 +728,13 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		/* Set VMID to 2x250k */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x100); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	case SND_SOC_BIAS_OFF: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		wm8960_close(codec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		/* Enable anti-pop features */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		snd_soc_write(codec, WM8960_APOP1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			     WM8960_POBCTRL | WM8960_SOFT_ST | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -661,6 +743,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		/* Disable VMID and VREF, let them discharge */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		snd_soc_write(codec, WM8960_POWER1, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		msleep(600); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -853,10 +936,15 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	if (pll_div.k) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		reg |= 0x20; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 16) & 0xff); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 8) & 0xff); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0xff); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 16) & 0xff); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 8) & 0xff); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0xff); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	snd_soc_write(codec, WM8960_PLL1, reg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -876,19 +964,27 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	switch (div_id) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	case WM8960_SYSCLKDIV: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1f9; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		snd_soc_write(codec, WM8960_CLOCK1, reg | div); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	case WM8960_DACDIV: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1c7; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		snd_soc_write(codec, WM8960_CLOCK1, reg | div); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	case WM8960_OPCLKDIV: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		reg = snd_soc_read(codec, WM8960_PLL1) & 0x03f; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		snd_soc_write(codec, WM8960_PLL1, reg | div); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	case WM8960_DCLKDIV: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#if 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		printk("%s:%s[%d]\n", __FILE__, __func__, __LINE__); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		reg = snd_soc_read(codec, WM8960_CLOCK2) & 0x03f; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		reg = snd_soc_read(codec, WM8960_CLOCK2) & 0x03f; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		snd_soc_write(codec, WM8960_CLOCK2, reg | div); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	case WM8960_TOCLKSEL: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -962,7 +1058,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	struct wm8960_data *pdata = dev_get_platdata(codec->dev); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	int ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	int ret = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	wm8960->set_bias_level = wm8960_set_bias_level_out3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -973,11 +1069,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			wm8960->set_bias_level = wm8960_set_bias_level_capless; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	ret = wm8960_reset(codec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	if (ret < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-		dev_err(codec->dev, "Failed to issue reset\n"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-		return ret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	wm8960_reset(codec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- a/sound/soc/codecs/wm8960.h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/sound/soc/codecs/wm8960.h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -110,4 +110,68 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #define WM8960_OPCLK_DIV_5_5		(4 << 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #define WM8960_OPCLK_DIV_6		(5 << 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ * WM8960 Power management 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++  */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR1_VMIDSEL_DISABLED    (0 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR1_VMIDSEL_50K         (1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR1_VMIDSEL_250K        (2 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR1_VMIDSEL_5K          (3 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR1_VREF                (1 << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR1_AINL                (1 << 5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR1_AINR                (1 << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR1_ADCL                (1 << 3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR1_ADCR                (1 << 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR1_MICB                (1 << 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR1_DIGENB              (1 << 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR2_DACL                (1 << 8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR2_DACR                (1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//#define WM8960_PWR2_LOUT1               (1 << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//#define WM8960_PWR2_ROUT1               (1 << 5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR2_SPKL                (1 << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR2_SPKR                (1 << 3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++//#define WM8960_PWR2_OUT3                (1 << 1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR2_PLL_EN              (1 << 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR3_LMIC                                (1 << 5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR3_RMIC                                (1 << 4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR3_LOMIX                               (1 << 3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define WM8960_PWR3_ROMIX                               (1 << 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LEFTGAIN                        0x0a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LEFTGAIN_LDVU                   (1 << 8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LEFTGAIN_LDACVOL(x)             ((x) & 0xff) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RIGHTGAIN                       0x0b 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RIGHTGAIN_RDVU                  (1 << 8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RIGHTGAIN_RDACVOL(x)            ((x) & 0xff) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ADDITIONAL1_DATSEL(x)           (((x) & 0x3) << 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1_WL_32                  (3 << 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1_WL_24                  (2 << 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1_WL_20                  (1 << 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1_WL_16                  (0 << 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define AINTFCE1_FORMAT_I2S             (2 << 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LOUT1_LO1VU                     (1 << 8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LOUT1_LO1ZC                     (1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LOUT1_LOUT1VOL(x)               ((x) & 0x7f) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ROUT1_RO1VU                     (1 << 8) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ROUT1_RO1ZC                     (1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define ROUT1_ROUT1VOL(x)               ((x) & 0x7f) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LINV_IPVU                       (1 << 8)  /* FIXME */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LINV_LINMUTE                    (1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LINV_LIZC                       (1 << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define LINV_LINVOL(x)                  ((x) & 0x3f) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RINV_IPVU                       (1 << 8) /* FIXME */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RINV_RINMUTE                    (1 << 7) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RINV_RIZC                       (1 << 6) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++#define RINV_RINVOL(x)                  ((x) & 0x3f) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ #endif 
			 |