From: Felix Fietkau Date: Mon, 18 Jan 2016 13:40:15 +0000 (+0000) Subject: ramips: delete the broken sound driver X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=3c3fb1dfc0bdd2edb2cd49054c49af79487b79ce;p=openwrt%2Fstaging%2Fzorun.git ramips: delete the broken sound driver Signed-off-by: Felix Fietkau SVN-Revision: 48318 --- diff --git a/target/linux/ramips/modules.mk b/target/linux/ramips/modules.mk index 2db8093df5..665dc41ae8 100644 --- a/target/linux/ramips/modules.mk +++ b/target/linux/ramips/modules.mk @@ -73,61 +73,3 @@ define KernelPackage/sound-mt7620/description endef $(eval $(call KernelPackage,sound-mt7620)) - - -define KernelPackage/sound-mtk-mt7620 - TITLE:=Mediatek I2S Alsa Driver (MT7620) - HIDDEN:=1 - KCONFIG:= \ - CONFIG_SND_MT76XX_SOC \ - CONFIG_SND_MT76XX_SOC_MT7620=y \ - CONFIG_SND_MT76XX_SOC_MT7628=n - FILES:= \ - $(LINUX_DIR)/sound/soc/mtk/ralink_gdma.ko - AUTOLOAD:=$(call AutoLoad,90,ralink_gdma) - $(call AddDepends/sound) -endef -$(eval $(call KernelPackage,sound-mtk-mt7620)) - -define KernelPackage/sound-mtk-mt7628 - TITLE:=Mediatek I2S Alsa Driver (MT7628) - HIDDEN:=1 - KCONFIG:= \ - CONFIG_SND_MT76XX_SOC \ - CONFIG_SND_MT76XX_SOC_MT7620=n \ - CONFIG_SND_MT76XX_SOC_MT7628=y - FILES:= \ - $(LINUX_DIR)/sound/soc/mtk/ralink_gdma.ko - AUTOLOAD:=$(call AutoLoad,90,ralink_gdma) - $(call AddDepends/sound) -endef -$(eval $(call KernelPackage,sound-mtk-mt7628)) - -define KernelPackage/sound-mtk - TITLE:=Mediatek I2S Alsa Driver - DEPENDS:= @BROKEN \ - +kmod-sound-soc-core +kmod-regmap +kmod-i2c-ralink \ - @(TARGET_ramips_mt7628||TARGET_ramips_mt7688||TARGET_ramips_mt7620) \ - +TARGET_ramips_mt7620:kmod-sound-mtk-mt7620 \ - +TARGET_ramips_mt7628:kmod-sound-mtk-mt7628 \ - +TARGET_ramips_mt7688:kmod-sound-mtk-mt7628 - KCONFIG:= \ - CONFIG_SND_MT76XX_I2S \ - CONFIG_SND_MT76XX_PCM \ - CONFIG_SND_SOC_WM8960 - FILES:= \ - $(LINUX_DIR)/sound/soc/mtk/snd-soc-mt76xx-i2s-ctl.ko \ - $(LINUX_DIR)/sound/soc/mtk/snd-soc-mt76xx-i2s.ko \ - $(LINUX_DIR)/sound/soc/mtk/snd-soc-mt76xx-pcm.ko \ - $(LINUX_DIR)/sound/soc/mtk/snd-soc-mt76xx-machine.ko \ - $(LINUX_DIR)/sound/soc/mtk/i2c_wm8960.ko \ - $(LINUX_DIR)/sound/soc/codecs/snd-soc-wm8960.ko - AUTOLOAD:=$(call AutoLoad,90,snd-soc-wm8960 i2c_wm8960 snd-soc-mt76xx-i2s-ctl snd-soc-mt76xx-i2s snd-soc-mt76xx-pcm snd-soc-mt76xx-machine) - $(call AddDepends/sound) -endef - -define KernelPackage/sound-mtk/description - Alsa modules for ralink i2s controller. -endef - -$(eval $(call KernelPackage,sound-mtk)) diff --git a/target/linux/ramips/patches-4.3/0050-alsa-add-ralink-sdk-driver.patch b/target/linux/ramips/patches-4.3/0050-alsa-add-ralink-sdk-driver.patch deleted file mode 100644 index c6fe92c158..0000000000 --- a/target/linux/ramips/patches-4.3/0050-alsa-add-ralink-sdk-driver.patch +++ /dev/null @@ -1,8430 +0,0 @@ -From f98ffa1f01240407e39c1b53135312db73f044c6 Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Mon, 7 Dec 2015 17:30:48 +0100 -Subject: [PATCH 50/53] alsa: add ralink sdk driver - -Signed-off-by: John Crispin ---- - sound/soc/Kconfig | 1 + - sound/soc/Makefile | 1 + - sound/soc/codecs/Kconfig | 2 +- - sound/soc/codecs/wm8960.c | 120 +- - sound/soc/codecs/wm8960.h | 64 + - sound/soc/mtk/Kconfig | 35 + - sound/soc/mtk/Makefile | 39 + - sound/soc/mtk/i2c_wm8960.c | 492 ++++++ - sound/soc/mtk/i2c_wm8960.h | 288 ++++ - sound/soc/mtk/i2s_ctrl.c | 3524 ++++++++++++++++++++++++++++++++++++++++ - sound/soc/mtk/i2s_ctrl.h | 523 ++++++ - sound/soc/mtk/i2s_debug.c | 698 ++++++++ - sound/soc/mtk/mt76xx_i2s.c | 304 ++++ - sound/soc/mtk/mt76xx_i2s.h | 18 + - sound/soc/mtk/mt76xx_machine.c | 317 ++++ - sound/soc/mtk/mt76xx_machine.h | 21 + - sound/soc/mtk/mt76xx_pcm.c | 499 ++++++ - sound/soc/mtk/ralink_gdma.c | 918 +++++++++++ - sound/soc/mtk/ralink_gdma.h | 326 ++++ - sound/soc/soc-core.c | 3 +- - 20 files changed, 8174 insertions(+), 19 deletions(-) - create mode 100644 sound/soc/mtk/Kconfig - create mode 100644 sound/soc/mtk/Makefile - create mode 100644 sound/soc/mtk/i2c_wm8960.c - create mode 100644 sound/soc/mtk/i2c_wm8960.h - create mode 100644 sound/soc/mtk/i2s_ctrl.c - create mode 100644 sound/soc/mtk/i2s_ctrl.h - create mode 100644 sound/soc/mtk/i2s_debug.c - create mode 100644 sound/soc/mtk/mt76xx_i2s.c - create mode 100644 sound/soc/mtk/mt76xx_i2s.h - create mode 100644 sound/soc/mtk/mt76xx_machine.c - create mode 100644 sound/soc/mtk/mt76xx_machine.h - create mode 100644 sound/soc/mtk/mt76xx_pcm.c - create mode 100644 sound/soc/mtk/ralink_gdma.c - create mode 100644 sound/soc/mtk/ralink_gdma.h - ---- a/sound/soc/Kconfig -+++ b/sound/soc/Kconfig -@@ -64,6 +64,7 @@ source "sound/soc/txx9/Kconfig" - source "sound/soc/ux500/Kconfig" - source "sound/soc/xtensa/Kconfig" - source "sound/soc/zte/Kconfig" -+source "sound/soc/mtk/Kconfig" - - # Supported codecs - source "sound/soc/codecs/Kconfig" ---- a/sound/soc/Makefile -+++ b/sound/soc/Makefile -@@ -46,3 +46,4 @@ obj-$(CONFIG_SND_SOC) += txx9/ - obj-$(CONFIG_SND_SOC) += ux500/ - obj-$(CONFIG_SND_SOC) += xtensa/ - obj-$(CONFIG_SND_SOC) += zte/ -+obj-$(CONFIG_SND_SOC) += mtk/ ---- a/sound/soc/codecs/Kconfig -+++ b/sound/soc/codecs/Kconfig -@@ -816,7 +816,7 @@ config SND_SOC_WM8955 - tristate - - config SND_SOC_WM8960 -- tristate -+ tristate "WM8960" - - config SND_SOC_WM8961 - tristate ---- a/sound/soc/codecs/wm8960.c -+++ b/sound/soc/codecs/wm8960.c -@@ -27,6 +27,7 @@ - #include - - #include "wm8960.h" -+#include "../mtk/i2c_wm8960.h" - - /* R25 - Power 1 */ - #define WM8960_VMID_MASK 0x180 -@@ -57,10 +58,10 @@ static int wm8960_set_pll(struct snd_soc - * 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 }, -@@ -92,8 +93,8 @@ static const struct reg_default wm8960_r - { 0x25, 0x0050 }, - { 0x26, 0x0000 }, - { 0x27, 0x0000 }, -- { 0x28, 0x0000 }, -- { 0x29, 0x0000 }, -+ { 0x28, 0x007b }, -+ { 0x29, 0x007b }, - { 0x2a, 0x0040 }, - { 0x2b, 0x0000 }, - { 0x2c, 0x0000 }, -@@ -138,7 +139,15 @@ struct wm8960_priv { - struct wm8960_data pdata; - }; - -+#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) regmap_write(c, WM8960_RESET, 0) -+#endif - - /* enumerated controls */ - static const char *wm8960_polarity[] = {"No Inversion", "Left Inverted", -@@ -192,8 +201,8 @@ static int wm8960_get_deemph(struct snd_ - 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, -@@ -211,6 +220,71 @@ static int wm8960_put_deemph(struct snd_ - 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, -9750, 50, 1); - static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1725, 75, 0); - static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1); -@@ -563,6 +637,7 @@ static int wm8960_set_dai_fmt(struct snd - - /* set iface */ - snd_soc_write(codec, WM8960_IFACE1, iface); -+ wm8960_postinit(codec); - return 0; - } - -@@ -809,9 +884,10 @@ static int wm8960_set_bias_level_out3(st - ret = wm8960_configure_clocking(codec); - if (ret) - return ret; -- -+#if 0 - /* Set VMID to 2x50k */ - snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x80); -+#endif - break; - - case SND_SOC_BIAS_ON: -@@ -852,12 +928,16 @@ static int wm8960_set_bias_level_out3(st - /* Disable anti-pop features */ - snd_soc_write(codec, WM8960_APOP1, WM8960_BUFIOEN); - } -- -+#if 0 - /* 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 | -@@ -866,6 +946,7 @@ static int wm8960_set_bias_level_out3(st - /* Disable VMID and VREF, let them discharge */ - snd_soc_write(codec, WM8960_POWER1, 0); - msleep(600); -+#endif - break; - } - -@@ -1101,10 +1182,15 @@ static int wm8960_set_pll(struct snd_soc - - 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); - -@@ -1150,7 +1236,11 @@ static int wm8960_set_dai_clkdiv(struct - snd_soc_write(codec, WM8960_PLL1, reg | div); - break; - case WM8960_DCLKDIV: -+#if 1 - 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: -@@ -1285,7 +1375,7 @@ static int wm8960_i2c_probe(struct i2c_c - { - struct wm8960_data *pdata = dev_get_platdata(&i2c->dev); - struct wm8960_priv *wm8960; -- int ret; -+ int ret - 0; - - wm8960 = devm_kzalloc(&i2c->dev, sizeof(struct wm8960_priv), - GFP_KERNEL); -@@ -1307,11 +1397,7 @@ static int wm8960_i2c_probe(struct i2c_c - else if (i2c->dev.of_node) - wm8960_set_pdata_from_of(i2c, &wm8960->pdata); - -- ret = wm8960_reset(wm8960->regmap); -- if (ret != 0) { -- dev_err(&i2c->dev, "Failed to issue reset\n"); -- return ret; -- } -+ wm8960_reset(wm8960->regmap); - - if (wm8960->pdata.shared_lrclk) { - ret = regmap_update_bits(wm8960->regmap, WM8960_ADDCTL2, ---- a/sound/soc/codecs/wm8960.h -+++ b/sound/soc/codecs/wm8960.h -@@ -111,4 +111,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 ---- /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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if defined(CONFIG_ARCH_MT7623) -+#include -+#include -+#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 "); -+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 -+#include -+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) -+#include -+#endif -+#include -+#include /* _printk() */ -+#include /* kmalloc() */ -+#include /* everything... */ -+#include /* error codes */ -+#include /* size_t */ -+#include -+#include /* O_ACCMODE */ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,14) -+#include /* cli(), *_flags */ -+#endif -+#include /* copy_from/to_user */ -+#include -+#include -+#include -+#include -+#include -+#include "ralink_gdma.h" -+#if defined(CONFIG_I2S_WITH_AEC) -+#include "../aec/aec_api.h" -+#endif -+ -+#ifdef CONFIG_DEVFS_FS -+#include -+static devfs_handle_t devfs_handle; -+#endif -+ -+#include "i2s_ctrl.h" -+ -+#if defined(CONFIG_SND_MT76XX_SOC) -+#include -+#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; immap_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<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<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<rx_unmask_ch |= (1<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; ilock, 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)||(argsrate = 48000; -+ spin_unlock(&ptri2s_config->lock); -+ break; -+ } -+#elif defined(CONFIG_I2S_WM8750) -+ if((arg>MAX_SRATE_HZ)||(argsrate = 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 "); -+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 -+#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/i2s_debug.c -@@ -0,0 +1,698 @@ -+#include -+#include -+#include -+#include /* printk() */ -+#include "i2s_ctrl.h" -+#include -+#include -+#include -+#include -+#include /* copy_from/to_user */ -+ -+#if defined(CONFIG_SND_RALINK_SOC) -+#include -+#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>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; -+} ---- /dev/null -+++ b/sound/soc/mtk/mt76xx_i2s.c -@@ -0,0 +1,304 @@ -+/* -+ * mtk_audio_drv.c -+ * -+ * Created on: 2013/8/20 -+ * Author: MTK04880 -+ */ -+#include -+#include -+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) -+#include -+#endif -+#include -+#include /* printk() */ -+#include /* kmalloc() */ -+#include /* everything... */ -+#include /* error codes */ -+#include /* size_t */ -+#include -+#include /* O_ACCMODE */ -+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36) -+#include /* cli(), *_flags */ -+#endif -+#include /* copy_from/to_user */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#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 *******\n", __func__); -+ switch(params_rate(params)){ -+ case 8000: -+ srate = 8000; -+ break; -+ case 16000: -+ srate = 16000; -+ break; -+ case 32000: -+ srate = 32000; -+ break; -+ case 44100: -+ 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){ -+ if((rtd->bRxDMAEnable != GDMA_I2S_EN) && (rtd->bTxDMAEnable != GDMA_I2S_EN)){ -+ 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__); -+ 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 -+#include -+#endif -+ -+#include "i2s_ctrl.h" -+#endif /* MTK_I2S_H_ */ ---- /dev/null -+++ b/sound/soc/mtk/mt76xx_machine.c -@@ -0,0 +1,317 @@ -+/* -+ * mt76xx_machine.c -+ * -+ */ -+#include -+#include -+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) -+#include -+#endif -+#include -+#include /* printk() */ -+#include /* kmalloc() */ -+#include /* everything... */ -+#include /* error codes */ -+#include /* size_t */ -+#include -+#include /* O_ACCMODE */ -+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36) -+#include /* cli(), *_flags */ -+#endif -+#include /* copy_from/to_user */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#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; -+ -+ /*For duplex mode, avoid setting twice.*/ -+ if((rtd->bRxDMAEnable == GDMA_I2S_EN) || (rtd->bTxDMAEnable == GDMA_I2S_EN)) -+ return 0; -+#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); -+ -+ 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; -+ } -+#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. -+ * */ -+ 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("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 -+ 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)); -+#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("codec_wm8960", (0x34)), -+ }, { -+ I2C_BOARD_INFO("wm8960", (0x34 >> 1)), -+#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[0]); -+ if (!client) -+ return -ENODEV; -+ i2c_get_clientdata(client); -+ -+ client = i2c_new_device(adapter, &i2c_board_info[1]); -+ if (!client) -+ return -ENODEV; -+ i2c_get_clientdata(client); -+ -+ i2c_put_adapter(adapter); -+ -+ 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 -+#include -+#include -+#include -+ -+#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 -+#include -+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) -+#include -+#endif -+#include -+#include /* printk() */ -+#include /* kmalloc() */ -+#include /* everything... */ -+#include /* error codes */ -+#include /* size_t */ -+#include -+#include /* O_ACCMODE */ -+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36) -+#include /* cli(), *_flags */ -+#endif -+#include /* copy_from/to_user */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#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 -+#include -+#include -+#include -+#include -+#include -+#if defined (CONFIG_MIPS) -+ #include -+ #include -+#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> 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<> ===\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<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<ChNum] = NewEntry->DoneIntCallback; -+ } -+ -+ if(NewEntry->SoftMode) { -+ Data |= (0x01<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<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<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 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 "); -+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 -+ -+/* -+ * 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 -+#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 -@@ -1758,7 +1758,8 @@ static int soc_probe(struct platform_dev - /* 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)