1 From f98ffa1f01240407e39c1b53135312db73f044c6 Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Mon, 7 Dec 2015 17:30:48 +0100
4 Subject: [PATCH 50/53] alsa: add ralink sdk driver
6 Signed-off-by: John Crispin <blogic@openwrt.org>
8 sound/soc/Kconfig | 1 +
9 sound/soc/Makefile | 1 +
10 sound/soc/codecs/Kconfig | 2 +-
11 sound/soc/codecs/wm8960.c | 120 +-
12 sound/soc/codecs/wm8960.h | 64 +
13 sound/soc/mtk/Kconfig | 35 +
14 sound/soc/mtk/Makefile | 39 +
15 sound/soc/mtk/i2c_wm8960.c | 492 ++++++
16 sound/soc/mtk/i2c_wm8960.h | 288 ++++
17 sound/soc/mtk/i2s_ctrl.c | 3524 ++++++++++++++++++++++++++++++++++++++++
18 sound/soc/mtk/i2s_ctrl.h | 523 ++++++
19 sound/soc/mtk/i2s_debug.c | 698 ++++++++
20 sound/soc/mtk/mt76xx_i2s.c | 304 ++++
21 sound/soc/mtk/mt76xx_i2s.h | 18 +
22 sound/soc/mtk/mt76xx_machine.c | 317 ++++
23 sound/soc/mtk/mt76xx_machine.h | 21 +
24 sound/soc/mtk/mt76xx_pcm.c | 499 ++++++
25 sound/soc/mtk/ralink_gdma.c | 918 +++++++++++
26 sound/soc/mtk/ralink_gdma.h | 326 ++++
27 sound/soc/soc-core.c | 3 +-
28 20 files changed, 8174 insertions(+), 19 deletions(-)
29 create mode 100644 sound/soc/mtk/Kconfig
30 create mode 100644 sound/soc/mtk/Makefile
31 create mode 100644 sound/soc/mtk/i2c_wm8960.c
32 create mode 100644 sound/soc/mtk/i2c_wm8960.h
33 create mode 100644 sound/soc/mtk/i2s_ctrl.c
34 create mode 100644 sound/soc/mtk/i2s_ctrl.h
35 create mode 100644 sound/soc/mtk/i2s_debug.c
36 create mode 100644 sound/soc/mtk/mt76xx_i2s.c
37 create mode 100644 sound/soc/mtk/mt76xx_i2s.h
38 create mode 100644 sound/soc/mtk/mt76xx_machine.c
39 create mode 100644 sound/soc/mtk/mt76xx_machine.h
40 create mode 100644 sound/soc/mtk/mt76xx_pcm.c
41 create mode 100644 sound/soc/mtk/ralink_gdma.c
42 create mode 100644 sound/soc/mtk/ralink_gdma.h
44 diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
45 index 76ce95c..09aa2c7 100644
46 --- a/sound/soc/Kconfig
47 +++ b/sound/soc/Kconfig
48 @@ -64,6 +64,7 @@ source "sound/soc/txx9/Kconfig"
49 source "sound/soc/ux500/Kconfig"
50 source "sound/soc/xtensa/Kconfig"
51 source "sound/soc/zte/Kconfig"
52 +source "sound/soc/mtk/Kconfig"
55 source "sound/soc/codecs/Kconfig"
56 diff --git a/sound/soc/Makefile b/sound/soc/Makefile
57 index e9d8e0e..a3c6b43 100644
58 --- a/sound/soc/Makefile
59 +++ b/sound/soc/Makefile
60 @@ -46,3 +46,4 @@ obj-$(CONFIG_SND_SOC) += txx9/
61 obj-$(CONFIG_SND_SOC) += ux500/
62 obj-$(CONFIG_SND_SOC) += xtensa/
63 obj-$(CONFIG_SND_SOC) += zte/
64 +obj-$(CONFIG_SND_SOC) += mtk/
65 diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
66 index 0c9733e..276a4c5 100644
67 --- a/sound/soc/codecs/Kconfig
68 +++ b/sound/soc/codecs/Kconfig
69 @@ -816,7 +816,7 @@ config SND_SOC_WM8955
78 diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
79 index dbd8840..3118f5c 100644
80 --- a/sound/soc/codecs/wm8960.c
81 +++ b/sound/soc/codecs/wm8960.c
83 #include <sound/wm8960.h>
86 +#include "../mtk/i2c_wm8960.h"
89 #define WM8960_VMID_MASK 0x180
90 @@ -57,10 +58,10 @@ static int wm8960_set_pll(struct snd_soc_codec *codec,
91 * using 2 wire for device control, so we cache them instead.
93 static const struct reg_default wm8960_reg_defaults[] = {
105 @@ -92,8 +93,8 @@ static const struct reg_default wm8960_reg_defaults[] = {
116 @@ -138,7 +139,15 @@ struct wm8960_priv {
117 struct wm8960_data pdata;
121 +#define wm8960_reset(c) do{ \
123 + snd_soc_write(c, WM8960_RESET, 0);\
124 + for(i = 0; i < 1000*HZ; i++);\
127 #define wm8960_reset(c) regmap_write(c, WM8960_RESET, 0)
130 /* enumerated controls */
131 static const char *wm8960_polarity[] = {"No Inversion", "Left Inverted",
132 @@ -192,8 +201,8 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol,
133 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
134 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
136 - ucontrol->value.integer.value[0] = wm8960->deemph;
138 + //ucontrol->value.integer.value[0] = wm8960->deemph;
139 + return wm8960->deemph;
142 static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
143 @@ -211,6 +220,71 @@ static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
144 return wm8960_set_deemph(codec);
147 +static int wm8960_preinit(struct snd_soc_codec *codec)
149 + //printk("****** %s ******\n", __func__);
150 + snd_soc_write(codec, WM8960_RESET, 0);
156 +static int wm8960_postinit(struct snd_soc_codec *codec)
159 + //printk("****** %s ******\n", __func__);
161 + data = snd_soc_read(codec, WM8960_POWER1);
162 + snd_soc_write(codec, WM8960_POWER1, data|WM8960_PWR1_ADCL|WM8960_PWR1_ADCR|WM8960_PWR1_AINL |WM8960_PWR1_AINR|WM8960_PWR1_MICB);//0x19
163 + data = snd_soc_read(codec, WM8960_ADDCTL1);
164 + snd_soc_write(codec, WM8960_ADDCTL1, data|ADDITIONAL1_DATSEL(0x01));//0x17
165 + snd_soc_write(codec, WM8960_LADC, LEFTGAIN_LDVU|LEFTGAIN_LDACVOL(0xc3));//0x15
166 + snd_soc_write(codec, WM8960_RADC, LEFTGAIN_LDVU|LEFTGAIN_LDACVOL(0xc3));//0x16
167 + snd_soc_write(codec, WM8960_LINPATH, 0x148);//0x20
168 + snd_soc_write(codec, WM8960_RINPATH, 0x148);//0x21
169 + snd_soc_write(codec, WM8960_POWER3, WM8960_PWR3_LMIC|WM8960_PWR3_RMIC);//0x2f
172 + data = snd_soc_read(codec, WM8960_POWER2);
173 + 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
175 + snd_soc_write(codec, WM8960_IFACE2, 0x40);
176 + snd_soc_write(codec, WM8960_LDAC, LEFTGAIN_LDVU|LEFTGAIN_LDACVOL(0xff));//0x0a
177 + snd_soc_write(codec, WM8960_RDAC, RIGHTGAIN_RDVU|RIGHTGAIN_RDACVOL(0xff));//0x0b
178 + snd_soc_write(codec, WM8960_LOUTMIX, 0x100);//0x22
179 + snd_soc_write(codec, WM8960_ROUTMIX, 0x100);//0x25
181 + data = snd_soc_read(codec, WM8960_POWER3);
182 + snd_soc_write(codec, WM8960_POWER3, data|WM8960_PWR3_ROMIX|WM8960_PWR3_LOMIX);//0x2f
184 + snd_soc_write(codec, WM8960_CLASSD1, 0xf7);//0x31
185 + snd_soc_write(codec, WM8960_CLASSD3, 0xad);//0x33
186 + snd_soc_write(codec, WM8960_DACCTL1, 0x000);//0x05
188 + data = snd_soc_read(codec, WM8960_POWER1);
189 + snd_soc_write(codec, WM8960_POWER1, data|0x1c0);//0x19
192 + snd_soc_write(codec, WM8960_LOUT1, LOUT1_LO1VU|LOUT1_LO1ZC|LOUT1_LOUT1VOL(115));//0x02
193 + snd_soc_write(codec, WM8960_ROUT1, ROUT1_RO1VU|ROUT1_RO1ZC|ROUT1_ROUT1VOL(115));//0x03
195 + snd_soc_write(codec, WM8960_LINVOL, LINV_IPVU|LINV_LINVOL(110)); //LINV(0x00)=>0x12b
196 + snd_soc_write(codec, WM8960_RINVOL, RINV_IPVU|RINV_RINVOL(110)); //LINV(0x01)=>0x12b
201 +static int wm8960_close(struct snd_soc_codec *codec)
203 + snd_soc_write(codec, WM8960_DACCTL1,0x8); //0x05->0x08
204 + snd_soc_write(codec, WM8960_POWER1, 0x000); //0x19->0x000
206 + snd_soc_write(codec, WM8960_POWER2, 0x000); //0x1a->0x000
212 static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1);
213 static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1725, 75, 0);
214 static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
215 @@ -563,6 +637,7 @@ static int wm8960_set_dai_fmt(struct snd_soc_dai *codec_dai,
218 snd_soc_write(codec, WM8960_IFACE1, iface);
219 + wm8960_postinit(codec);
223 @@ -809,9 +884,10 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
224 ret = wm8960_configure_clocking(codec);
229 /* Set VMID to 2x50k */
230 snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x80);
234 case SND_SOC_BIAS_ON:
235 @@ -852,12 +928,16 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
236 /* Disable anti-pop features */
237 snd_soc_write(codec, WM8960_APOP1, WM8960_BUFIOEN);
241 /* Set VMID to 2x250k */
242 snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x100);
246 case SND_SOC_BIAS_OFF:
248 + wm8960_close(codec);
250 /* Enable anti-pop features */
251 snd_soc_write(codec, WM8960_APOP1,
252 WM8960_POBCTRL | WM8960_SOFT_ST |
253 @@ -866,6 +946,7 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
254 /* Disable VMID and VREF, let them discharge */
255 snd_soc_write(codec, WM8960_POWER1, 0);
261 @@ -1101,10 +1182,15 @@ static int wm8960_set_pll(struct snd_soc_codec *codec,
267 snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 16) & 0xff);
268 snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 8) & 0xff);
269 snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0xff);
271 + snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 16) & 0xff);
272 + snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 8) & 0xff);
273 + snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0xff);
276 snd_soc_write(codec, WM8960_PLL1, reg);
278 @@ -1150,7 +1236,11 @@ static int wm8960_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
279 snd_soc_write(codec, WM8960_PLL1, reg | div);
283 reg = snd_soc_read(codec, WM8960_CLOCK2) & 0x03f;
285 + reg = snd_soc_read(codec, WM8960_CLOCK2) & 0x03f;
287 snd_soc_write(codec, WM8960_CLOCK2, reg | div);
289 case WM8960_TOCLKSEL:
290 @@ -1285,7 +1375,7 @@ static int wm8960_i2c_probe(struct i2c_client *i2c,
292 struct wm8960_data *pdata = dev_get_platdata(&i2c->dev);
293 struct wm8960_priv *wm8960;
297 wm8960 = devm_kzalloc(&i2c->dev, sizeof(struct wm8960_priv),
299 @@ -1307,11 +1397,7 @@ static int wm8960_i2c_probe(struct i2c_client *i2c,
300 else if (i2c->dev.of_node)
301 wm8960_set_pdata_from_of(i2c, &wm8960->pdata);
303 - ret = wm8960_reset(wm8960->regmap);
305 - dev_err(&i2c->dev, "Failed to issue reset\n");
308 + wm8960_reset(wm8960->regmap);
310 if (wm8960->pdata.shared_lrclk) {
311 ret = regmap_update_bits(wm8960->regmap, WM8960_ADDCTL2,
312 diff --git a/sound/soc/codecs/wm8960.h b/sound/soc/codecs/wm8960.h
313 index ab3220d..5205deb 100644
314 --- a/sound/soc/codecs/wm8960.h
315 +++ b/sound/soc/codecs/wm8960.h
317 #define WM8960_OPCLK_DIV_5_5 (4 << 0)
318 #define WM8960_OPCLK_DIV_6 (5 << 0)
321 + * WM8960 Power management
323 +#define WM8960_PWR1_VMIDSEL_DISABLED (0 << 7)
324 +#define WM8960_PWR1_VMIDSEL_50K (1 << 7)
325 +#define WM8960_PWR1_VMIDSEL_250K (2 << 7)
326 +#define WM8960_PWR1_VMIDSEL_5K (3 << 7)
327 +#define WM8960_PWR1_VREF (1 << 6)
328 +#define WM8960_PWR1_AINL (1 << 5)
329 +#define WM8960_PWR1_AINR (1 << 4)
330 +#define WM8960_PWR1_ADCL (1 << 3)
331 +#define WM8960_PWR1_ADCR (1 << 2)
332 +#define WM8960_PWR1_MICB (1 << 1)
333 +#define WM8960_PWR1_DIGENB (1 << 0)
335 +#define WM8960_PWR2_DACL (1 << 8)
336 +#define WM8960_PWR2_DACR (1 << 7)
337 +//#define WM8960_PWR2_LOUT1 (1 << 6)
338 +//#define WM8960_PWR2_ROUT1 (1 << 5)
339 +#define WM8960_PWR2_SPKL (1 << 4)
340 +#define WM8960_PWR2_SPKR (1 << 3)
341 +//#define WM8960_PWR2_OUT3 (1 << 1)
342 +#define WM8960_PWR2_PLL_EN (1 << 0)
344 +#define WM8960_PWR3_LMIC (1 << 5)
345 +#define WM8960_PWR3_RMIC (1 << 4)
346 +#define WM8960_PWR3_LOMIX (1 << 3)
347 +#define WM8960_PWR3_ROMIX (1 << 2)
349 +#define LEFTGAIN 0x0a
350 +#define LEFTGAIN_LDVU (1 << 8)
351 +#define LEFTGAIN_LDACVOL(x) ((x) & 0xff)
353 +#define RIGHTGAIN 0x0b
354 +#define RIGHTGAIN_RDVU (1 << 8)
355 +#define RIGHTGAIN_RDACVOL(x) ((x) & 0xff)
357 +#define ADDITIONAL1_DATSEL(x) (((x) & 0x3) << 2)
359 +#define AINTFCE1_WL_32 (3 << 2)
360 +#define AINTFCE1_WL_24 (2 << 2)
361 +#define AINTFCE1_WL_20 (1 << 2)
362 +#define AINTFCE1_WL_16 (0 << 2)
363 +#define AINTFCE1_FORMAT_I2S (2 << 0)
365 +#define LOUT1_LO1VU (1 << 8)
366 +#define LOUT1_LO1ZC (1 << 7)
367 +#define LOUT1_LOUT1VOL(x) ((x) & 0x7f)
369 +#define ROUT1_RO1VU (1 << 8)
370 +#define ROUT1_RO1ZC (1 << 7)
371 +#define ROUT1_ROUT1VOL(x) ((x) & 0x7f)
373 +#define LINV_IPVU (1 << 8) /* FIXME */
375 +#define LINV_LINMUTE (1 << 7)
376 +#define LINV_LIZC (1 << 6)
377 +#define LINV_LINVOL(x) ((x) & 0x3f)
379 +#define RINV_IPVU (1 << 8) /* FIXME */
380 +#define RINV_RINMUTE (1 << 7)
381 +#define RINV_RIZC (1 << 6)
382 +#define RINV_RINVOL(x) ((x) & 0x3f)
385 diff --git a/sound/soc/mtk/Kconfig b/sound/soc/mtk/Kconfig
387 index 0000000..26d2531
389 +++ b/sound/soc/mtk/Kconfig
391 +config SND_MT76XX_SOC
392 + tristate "SoC Audio for MT76XX APSoC Machine"
393 + depends on SND_SOC && (SOC_MT7620 || SOC_MT7621)
396 + Say Y or M if you want to add support for codecs attached to
397 + the MTK I2S interface.
400 + prompt "Selected SoC type"
401 + depends on SND_MT76XX_SOC
402 + default SND_MT76XX_SOC_MT7620
404 +config SND_MT76XX_SOC_MT7620
406 + depends on SOC_MT7620
408 +config SND_MT76XX_SOC_MT7628
410 + depends on SOC_MT7620
412 +config SND_MT76XX_SOC_MT7621
414 + depends on SOC_MT7621
418 +config SND_MT76XX_PCM
419 + tristate "MTK SoC Audio PCM Platform"
420 + depends on SND_MT76XX_SOC
422 +config SND_MT76XX_I2S
423 + tristate "MTK SoC I2S Support"
424 + depends on SND_MT76XX_SOC
426 diff --git a/sound/soc/mtk/Makefile b/sound/soc/mtk/Makefile
428 index 0000000..00b3dff
430 +++ b/sound/soc/mtk/Makefile
432 +KBUILD_CFLAGS += -I$(srctree)
434 +ifeq ($(CONFIG_SND_MT76XX_SOC_MT7620),y)
435 +KBUILD_CFLAGS += -DCONFIG_MT7620 -DCONFIG_RALINK_MT7620
437 +ifeq ($(CONFIG_SND_MT76XX_SOC_MT7628),y)
438 +KBUILD_CFLAGS += -DCONFIG_MT7628 -DCONFIG_RALINK_MT7628
440 +ifeq ($(CONFIG_SOC_MT7620),y)
441 +KBUILD_CFLAGS += -DRALINK_SYSCTL_BASE=0xB0000000
442 +KBUILD_CFLAGS += -DRALINK_INTCL_BASE=0xB0000200
443 +KBUILD_CFLAGS += -DRALINK_PIO_BASE=0xB0000600
444 +KBUILD_CFLAGS += -DRALINK_I2S_BASE=0xB0000A00
445 +KBUILD_CFLAGS += -DRALINK_GDMA_BASE=0xB0002800
446 +KBUILD_CFLAGS += -DCONFIG_GDMA_EVERYBODY
447 +KBUILD_CFLAGS += -DCONFIG_SND_MT76XX_SOC
448 +KBUILD_CFLAGS += -DCONFIG_I2S_WM8960
449 +KBUILD_CFLAGS += -DCONFIG_I2S_MCLK_12P288MHZ
450 +KBUILD_CFLAGS += -DCONFIG_GDMA_EVERYBODY
451 +KBUILD_CFLAGS += -DSURFBOARDINT_DMA=15
452 +KBUILD_CFLAGS += -DRALINK_INTCTL_DMA=128
453 +KBUILD_CFLAGS += -DCONFIG_SND_SOC_WM8960
456 +# MTK APSoC Platform Support
457 +snd-soc-mt76xx-i2s-ctl-objs := i2s_ctrl.o i2s_debug.o #i2c_wm8960.o
458 +snd-soc-mt76xx-pcm-objs := mt76xx_pcm.o
459 +snd-soc-mt76xx-i2s-objs := mt76xx_i2s.o
461 +obj-$(CONFIG_SND_MT76XX_PCM) += snd-soc-mt76xx-pcm.o
462 +obj-$(CONFIG_SND_MT76XX_I2S) += snd-soc-mt76xx-i2s-ctl.o snd-soc-mt76xx-i2s.o
464 +# MTK APSoC Machine Support
465 +snd-soc-mt76xx-machine-objs := mt76xx_machine.o
467 +obj-$(CONFIG_SND_MT76XX_SOC) += i2c_wm8960.o ralink_gdma.o snd-soc-mt76xx-machine.o
471 diff --git a/sound/soc/mtk/i2c_wm8960.c b/sound/soc/mtk/i2c_wm8960.c
473 index 0000000..70f16e1
475 +++ b/sound/soc/mtk/i2c_wm8960.c
477 +#include <linux/kernel.h>
478 +#include <linux/version.h>
479 +#include <linux/init.h>
480 +#include <linux/module.h>
481 +#include <linux/slab.h>
482 +#include <linux/i2c.h>
483 +#include <linux/delay.h>
484 +#include <linux/interrupt.h>
485 +#include <linux/fs.h>
486 +#include <linux/fcntl.h>
487 +#include <linux/cdev.h>
488 +#if defined(CONFIG_ARCH_MT7623)
490 +#include <mach/mt_gpio.h>
492 +#include "i2c_wm8960.h"
493 +#include "i2s_ctrl.h"
502 +#if defined(CONFIG_ARCH_MT7623)
504 +//static struct i2c_board_info __initdata i2c_devs1 = { I2C_BOARD_INFO("codec_wm8960", (0X34>>1))};
505 +static struct i2c_board_info __initdata i2c_devs1 = { I2C_BOARD_INFO("codec_wm8960", (0X34))};
508 +unsigned long wm_reg_data[56];
509 +struct wm8960_data *wmio;
511 +struct wm8960_data {
512 + struct i2c_client *client;
513 + struct device *dev;
518 +void i2c_WM8960_write(u32 reg, u32 data)
521 + struct i2c_msg msg;
524 +#if defined(CONFIG_ARCH_MT7623)
525 + unsigned int ext_flag = 0;
527 + ext_flag &= 0x7FFFFFFF;
528 + ext_flag |= I2C_A_FILTER_MSG;
529 + ext_flag |= I2C_POLLING_FLAG;
532 + wm_reg_data[reg] = data;
534 + buf[0]= (reg<<1)|(0x01&(data>>8));
535 + buf[1]= (data&0xFF);
537 +#if defined(CONFIG_ARCH_MT7623)
539 + //msg.addr = wmio->client->addr;
540 + msg.addr = wmio->client->addr>>1;
543 + msg.addr = wmio->client->addr>>1;
546 + msg.buf = (char *)buf;
548 +#if defined(CONFIG_ARCH_MT7623)
550 + msg.ext_flag = ext_flag & 0x7FFFFFFF;
553 + ret = i2c_transfer(wmio->client->adapter, &msg, 1);
554 + MSG("[WM8960(%02X)=0x%08X]\n",(unsigned int)reg,(unsigned int)data);
557 + printk("%s: i2c write error!\n", __func__);
562 +// Reset and power up the WM8960
563 +void audiohw_preinit(void)
565 + memset(wm_reg_data, 0 , sizeof(unsigned long)*55);
567 + i2c_WM8960_write(RESET, RESET_RESET); // Reset (0x0F)
570 + wm_reg_data[RESET] = 0xFFFF;
574 +void audiohw_set_apll(int srate)
576 + unsigned long data;
578 + if((srate==8000) || (srate==12000) || (srate==16000) || (srate==24000) || (srate==32000) || (srate==48000))
580 + // Provide 12.288MHz SYSCLK
581 + data = wm_reg_data[PLL1];
582 + i2c_WM8960_write(PLL1, data | PLL1_OPCLKDIV_1 | PLL1_SDM_FRACTIONAL | PLL1_PLLPRESCALE_1 | PLL1_PLLN(0x8)); // PLL1 (0x34)
584 + i2c_WM8960_write(PLL2, PLL2_PLLK_23_16(0x31)); // PLL2 (0x35)
585 + i2c_WM8960_write(PLL3, PLL3_PLLK_15_8(0x26)); // PLL3 (0x36)
586 + i2c_WM8960_write(PLL4, PLL4_PLLK_7_0(0xe9)); // PLL4 (0x37)
588 + else if ((srate==11025) || (srate==22050) || (srate==44100))
590 + //Provide 11.2896MHz SYSCLK
591 + data = wm_reg_data[PLL1];
592 + i2c_WM8960_write(PLL1, data | PLL1_OPCLKDIV_1 | PLL1_SDM_FRACTIONAL | PLL1_PLLPRESCALE_1 | PLL1_PLLN(0x7)); //PLL1 (0x34)
594 + i2c_WM8960_write(PLL2, PLL2_PLLK_23_16(0x86)); //PLL2 (0x35)
595 + i2c_WM8960_write(PLL3, PLL3_PLLK_15_8(0xc2)); //PLL3 (0x36)
596 + i2c_WM8960_write(PLL4, PLL4_PLLK_7_0(0x26)); //PLL4 (0x37)
600 + printk("Not support this srate\n");
606 +void audiohw_set_frequency(int fsel, int pll_en)
608 + MSG("audiohw_set_frequency_=0x%08X\n",fsel);
612 + printk("PLL enable\n");
613 + i2c_WM8960_write(CLOCKING1, (fsel<<3) | CLOCKING1_SYSCLKDIV_2 | CLOCKING1_CLKSEL_PLL); //CLOCKING (0x04)=>0x05
618 + printk("PLL disable\n");
619 + i2c_WM8960_write(CLOCKING1, (fsel<<3));//| CLOCKING1_SYSCLKDIV_2); //CLOCKING (0x04)
625 +int audiohw_set_lineout_vol(int Aout, int vol_l, int vol_r)
627 + MSG("audiohw_set_lineout_vol_\n");
631 + //i2c_WM8960_write(LOUT1, LOUT1_LO1VU|LOUT1_LO1ZC|LOUT1_LOUT1VOL(0x7f)); //LOUT1(0x02)
632 + //i2c_WM8960_write(ROUT1, ROUT1_RO1VU|ROUT1_RO1ZC|ROUT1_ROUT1VOL(0x7f)); //ROUT1(0x03)
633 + i2c_WM8960_write(LOUT1, LOUT1_LO1VU|LOUT1_LO1ZC|LOUT1_LOUT1VOL(vol_l)); //LOUT1(0x02)
634 + i2c_WM8960_write(ROUT1, ROUT1_RO1VU|ROUT1_RO1ZC|ROUT1_ROUT1VOL(vol_r)); //ROUT1(0x03)
637 + i2c_WM8960_write(LSPK, LSPK_SPKLVU|LSPK_SPKLZC| LSPK_SPKLVOL(vol_l));
638 + i2c_WM8960_write(RSPK, RSPK_SPKRVU|RSPK_SPKRZC| RSPK_SPKRVOL(vol_r));
647 +int audiohw_set_linein_vol(int vol_l, int vol_r)
649 + MSG("audiohw_set_linein_vol_\n");
651 + i2c_WM8960_write(LINV, LINV_IPVU|LINV_LINVOL(vol_l)); //LINV(0x00)=>0x12b
652 + i2c_WM8960_write(RINV, RINV_IPVU|RINV_RINVOL(vol_r)); //LINV(0x01)=>0x12b
658 +int audiohw_postinit(int bSlave, int AIn, int AOut, int pll_en, int wordLen24b)
662 + unsigned long data;
664 + if(wm_reg_data[RESET]!=0xFFFF)
669 + MSG("WM8960 slave.....\n");
672 + printk("24 bit word length\n");
673 + i2c_WM8960_write(AINTFCE1, AINTFCE1_WL_24 | AINTFCE1_FORMAT_I2S); //AINTFCE1(0x07)
677 + printk("16 bit word length\n");
678 + i2c_WM8960_write(AINTFCE1, AINTFCE1_WL_16 | AINTFCE1_FORMAT_I2S); //AINTFCE1(0x07)
683 + MSG("WM8960 master.....\n");
684 + i2c_WM8960_write(CLOCKING2, 0x1c4);//CLOCKING2_BCLKDIV(0x1c4)); //CLOCKING2(0x08)
688 + printk("24 bit word length\n");
689 + i2c_WM8960_write(AINTFCE1, AINTFCE1_MS | AINTFCE1_WL_24 | AINTFCE1_FORMAT_I2S); //AINTFCE1(0x07)
693 + printk("16 bit word length\n");
694 + i2c_WM8960_write(AINTFCE1, AINTFCE1_MS | AINTFCE1_WL_16 | AINTFCE1_FORMAT_I2S); //AINTFCE1(0x07)
700 + //From app notes: allow Vref to stabilize to reduce clicks
701 + for(i = 0; i < 1000*HZ; i++);
705 + data = wm_reg_data[PWRMGMT1];
706 + i2c_WM8960_write(PWRMGMT1, data|PWRMGMT1_ADCL|PWRMGMT1_ADCR|PWRMGMT1_AINL |PWRMGMT1_AINR);//|PWRMGMT1_MICB);//PWRMGMT1(0x19)
708 + data = wm_reg_data[ADDITIONAL1];
709 + i2c_WM8960_write(ADDITIONAL1, data|ADDITIONAL1_DATSEL(0x01)); //ADDITIONAL1(0x17)
710 + i2c_WM8960_write(LADCVOL, LADCVOL_LAVU_EN|LADCVOL_LADCVOL(0xc3)); //LADCVOL(0x15)
711 + i2c_WM8960_write(RADCVOL, RADCVOL_RAVU_EN|RADCVOL_RADCVOL(0xc3)); //RADCVOL(0x16)
712 + i2c_WM8960_write(ADCLPATH, ADCLPATH_LMN1|ADCLPATH_LMIC2B);//|ADCLPATH_LMICBOOST_13DB); //ADCLPATH(0x20)=>(0x108)
713 + i2c_WM8960_write(ADCRPATH, ADCRPATH_RMN1|ADCRPATH_RMIC2B);//|ADCRPATH_RMICBOOST_13DB); //ADCRPATH(0x21)=>(0x108)
714 + i2c_WM8960_write(PWRMGMT3, PWRMGMT3_LMIC|PWRMGMT3_RMIC); //PWRMGMT3(0x2f)
716 + //i2c_WM8960_write(LINBMIX, 0x000); //LINBMIX(0x2B)
720 + i2c_WM8960_write(AINTFCE2, 0x40); //FIXME:(0x09)
722 + data = wm_reg_data[PWRMGMT2];
725 + i2c_WM8960_write(PWRMGMT2, data|PWRMGMT2_PLL_EN|PWRMGMT2_DACL|PWRMGMT2_DACR); //PWRMGMT2(0x1a)
729 + i2c_WM8960_write(PWRMGMT2, data|PWRMGMT2_DACL|PWRMGMT2_DACR); //PWRMGMT2(0x1a)
736 + //Power management 2 setting
737 + data = wm_reg_data[PWRMGMT2];
741 + i2c_WM8960_write(PWRMGMT2, data|PWRMGMT2_PLL_EN|PWRMGMT2_DACL|PWRMGMT2_DACR|PWRMGMT2_LOUT1|PWRMGMT2_ROUT1|PWRMGMT2_SPKL|PWRMGMT2_SPKR); //PWRMGMT2(0x1a)
745 + i2c_WM8960_write(PWRMGMT2, data|PWRMGMT2_DACL|PWRMGMT2_DACR|PWRMGMT2_LOUT1|PWRMGMT2_ROUT1|PWRMGMT2_SPKL|PWRMGMT2_SPKR); //PWRMGMT2(0x1a)
751 + i2c_WM8960_write(AINTFCE2, 0x40); //FIXME:(0x09)
753 + i2c_WM8960_write(LEFTGAIN, LEFTGAIN_LDVU|LEFTGAIN_LDACVOL(0xff)); //LEFTGAIN(0x0a)
754 + i2c_WM8960_write(RIGHTGAIN, RIGHTGAIN_RDVU|RIGHTGAIN_RDACVOL(0xff)); //RIGHTGAIN(0x0b)
756 + i2c_WM8960_write(LEFTMIX1, 0x100); //LEFTMIX1(0x22)
757 + i2c_WM8960_write(RIGHTMIX2, 0x100); //RIGHTMIX2(0x25)
759 + data = wm_reg_data[PWRMGMT3]; //FIXME
760 + i2c_WM8960_write(PWRMGMT3, data|PWRMGMT3_ROMIX|PWRMGMT3_LOMIX); //PWRMGMT3(0x2f)
762 + data = wm_reg_data[CLASSDCTRL1]; //CLASSDCTRL1(0x31) SPEAKER FIXME
763 + i2c_WM8960_write(CLASSDCTRL1, 0xf7);//data|CLASSDCTRL1_OP_LRSPK);
765 + data = wm_reg_data[CLASSDCTRL3]; //CLASSDCTRL3(0x33)
766 + i2c_WM8960_write(CLASSDCTRL3, 0xad);//data|(0x1b));
769 + i2c_WM8960_write(DACCTRL1, 0x000); //DACCTRL1(0x05)
771 + data = wm_reg_data[PWRMGMT1];
772 + i2c_WM8960_write(PWRMGMT1, data|0x1c0); //FIXME:PWRMGMT1(0x19)
775 + printk("WM8960 All initial ok!\n");
781 +void audiohw_micboost(int boostgain)
783 + unsigned long data;
785 + data = wm_reg_data[ADCLPATH];
786 + i2c_WM8960_write(ADCLPATH, data|(boostgain << 4));
788 + data = wm_reg_data[ADCRPATH];
789 + i2c_WM8960_write(ADCRPATH, data|(boostgain << 4));
792 +void audiohw_micin(int enableMic)
794 + unsigned long data;
798 + data = wm_reg_data[PWRMGMT1];
799 + i2c_WM8960_write(PWRMGMT1, data|PWRMGMT1_MICB);
804 + data = wm_reg_data[PWRMGMT1];
805 + i2c_WM8960_write(PWRMGMT1, data & (~(PWRMGMT1_MICB)));
810 +void audiohw_mute( bool mute)
812 + //Mute: Set DACMU = 1 to soft-mute the audio DACs.
813 + //Unmute: Set DACMU = 0 to soft-un-mute the audio DACs.
814 + i2c_WM8960_write(DACCTRL1, mute ? DACCTRL1_DACMU : 0);
818 +//Nice shutdown of WM8960 codec
819 +void audiohw_close(void)
821 + i2c_WM8960_write(DACCTRL1,DACCTRL1_DACMU); //0x05->0x08
822 + i2c_WM8960_write(PWRMGMT1, 0x000); //0x19->0x000
824 + i2c_WM8960_write(PWRMGMT2, 0x000); //0x1a->0x000
828 +void audiohw_loopback(int fsel)
832 +void audiohw_codec_exlbk(void)
834 + memset(wm_reg_data, 0 , sizeof(unsigned long)*55);
836 + i2c_WM8960_write(LINV, 0x117); //0x00->0x117
837 + i2c_WM8960_write(RINV, 0x117); //0x01->0x117
838 + i2c_WM8960_write(LOUT1, 0x179); //0x02->0x179
839 + i2c_WM8960_write(ROUT1, 0x179); //0x03->0x179
840 + i2c_WM8960_write(CLOCKING1, 0x00); //0x04->0x00
841 + //i2c_WM8960_write(CLOCKING1, 0x40); //0x04->0x00
842 + i2c_WM8960_write(DACCTRL1, 0x00); //0x05->0x00
843 + i2c_WM8960_write(AINTFCE2, 0x41); //0x09->0x41
844 + i2c_WM8960_write(LADCVOL, 0x1c3); //0x15->0x1c3
845 + i2c_WM8960_write(RADCVOL, 0x1c3); //0x16->0x1c3
846 + i2c_WM8960_write(PWRMGMT1, 0xfc); //0x19->0xfc
847 + i2c_WM8960_write(PWRMGMT2, 0x1e0); //0x1a->0x1e0
848 + i2c_WM8960_write(ADCLPATH, 0x108); //0x20->0x108
849 + i2c_WM8960_write(ADCRPATH, 0x108); //0x21->0x108
850 + i2c_WM8960_write(LEFTMIX1, 0x150); //0x22->0x150
851 + i2c_WM8960_write(RIGHTMIX2, 0x150); //0x25->0x150
852 + i2c_WM8960_write(BYPASS1, 0x00); //0x2d->0x00
853 + i2c_WM8960_write(BYPASS2, 0x00); //0x2e->0x00
854 + i2c_WM8960_write(PWRMGMT3, 0x3c); //0x2f->0x3c
857 +void audiohw_bypass(void)
861 + memset(wm_reg_data, 0 , sizeof(unsigned long)*55);
862 + i2c_WM8960_write(RESET, 0x000); //0x0f(R15)->0x000
864 + for(i = 0; i < 1000*HZ; i++);
866 + i2c_WM8960_write(PWRMGMT1, 0xf0); //0x19(R25)->0xf0
867 + i2c_WM8960_write(PWRMGMT2, 0x60); //0x1a(R26)->0x60
868 + i2c_WM8960_write(PWRMGMT3, 0x3c); //0x2f(R47)->0x3c
869 + i2c_WM8960_write(LINV, 0x117); // 0x00(R0)->0x117
870 + i2c_WM8960_write(RINV, 0x117); // 0x01(R1)->0x117
871 + i2c_WM8960_write(ADCLPATH, 0x108); //0x20(R32)->0x108
872 + i2c_WM8960_write(ADCRPATH, 0x108); //0x21(R33)->0x108
873 + i2c_WM8960_write(BYPASS1, 0x80); //0x2d(R45)->0x80
874 + i2c_WM8960_write(BYPASS2, 0x80); //0x2e(R46)->0x80
875 + i2c_WM8960_write(LOUT1, 0x179); // 0x02(R2)->0x179
876 + i2c_WM8960_write(ROUT1, 0x179); // 0x03(R3)->0x179
878 +EXPORT_SYMBOL(audiohw_set_frequency);
879 +EXPORT_SYMBOL(audiohw_close);
880 +EXPORT_SYMBOL(audiohw_postinit);
881 +EXPORT_SYMBOL(audiohw_preinit);
882 +EXPORT_SYMBOL(audiohw_set_apll);
883 +EXPORT_SYMBOL(audiohw_codec_exlbk);
884 +EXPORT_SYMBOL(audiohw_bypass);
885 +EXPORT_SYMBOL(audiohw_set_lineout_vol);
886 +EXPORT_SYMBOL(audiohw_set_linein_vol);
887 +EXPORT_SYMBOL(audiohw_micin);
888 +EXPORT_SYMBOL(audiohw_mute);
889 +EXPORT_SYMBOL(audiohw_loopback);
890 +EXPORT_SYMBOL(audiohw_micboost);
892 +static int codec_wm8960_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
894 + struct wm8960_data *wm;
896 +printk("*******Enter %s********\n", __func__);
898 + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
901 + wm = devm_kzalloc(&client->dev, sizeof(struct wm8960_data), GFP_KERNEL);
905 +#if defined(CONFIG_ARCH_MT7623)
906 + mt_set_gpio_mode(GPIO242, GPIO_MODE_04);
907 + mt_set_gpio_mode(GPIO243, GPIO_MODE_04);
909 + wm->client = client;
910 + wm->dev = &client->dev;
911 + wm->name = id->name;
912 + i2c_set_clientdata(client, wm);
915 + memset(wm_reg_data, 0 , sizeof(unsigned long)*55);
920 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
921 +static int codec_wm8960_i2c_remove(struct i2c_client *client)
923 +static int __devexit codec_wm8960_i2c_remove(struct i2c_client *client)
926 + struct wm8960_data *wm = i2c_get_clientdata(client);
932 +static const struct i2c_device_id wm8960_id[] = {
933 + { "codec_wm8960", 0 },
937 +static struct i2c_driver codec_wm8960_i2c_driver = {
939 + .name = "codec_wm8960"
941 + .probe = codec_wm8960_i2c_probe,
942 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
943 + .remove = codec_wm8960_i2c_remove,
945 + .remove = __devexit_p(codec_wm8960_i2c_remove),
947 + .id_table = wm8960_id,
949 +static int __init wm8960_i2c_init(void)
951 +#if defined(CONFIG_ARCH_MT7623)
952 + i2c_register_board_info(1, &i2c_devs1, 1);
954 + return i2c_add_driver(&codec_wm8960_i2c_driver);;
957 +static void __exit wm8960_i2c_exit(void)
959 + i2c_del_driver(&codec_wm8960_i2c_driver);
962 +module_init(wm8960_i2c_init);
963 +module_exit(wm8960_i2c_exit);
965 +MODULE_AUTHOR("Ryder Lee <ryder.lee@mediatek.com>");
966 +MODULE_DESCRIPTION("WM8960 I2C client driver");
967 +MODULE_LICENSE("GPL");
969 diff --git a/sound/soc/mtk/i2c_wm8960.h b/sound/soc/mtk/i2c_wm8960.h
971 index 0000000..c769345
973 +++ b/sound/soc/mtk/i2c_wm8960.h
975 +/* wm8960.h -- WM8960 Soc Audio driver */
979 +#define bool unsigned char
983 +/* volume/balance/treble/bass interdependency */
984 +#define VOLUME_MIN -730
985 +#define VOLUME_MAX 60
988 +/* Register addresses and bits */
989 +#define OUTPUT_MUTED 0x2f
990 +#define OUTPUT_0DB 0x79
993 +#define LINV_IPVU (1 << 8) /* FIXME */
994 +#define LINV_LINMUTE (1 << 7)
995 +#define LINV_LIZC (1 << 6)
996 +#define LINV_LINVOL(x) ((x) & 0x3f)
999 +#define RINV_IPVU (1 << 8) /* FIXME */
1000 +#define RINV_RINMUTE (1 << 7)
1001 +#define RINV_RIZC (1 << 6)
1002 +#define RINV_RINVOL(x) ((x) & 0x3f)
1005 +#define LOUT1_LO1VU (1 << 8)
1006 +#define LOUT1_LO1ZC (1 << 7)
1007 +#define LOUT1_LOUT1VOL(x) ((x) & 0x7f)
1010 +#define ROUT1_RO1VU (1 << 8)
1011 +#define ROUT1_RO1ZC (1 << 7)
1012 +#define ROUT1_ROUT1VOL(x) ((x) & 0x7f)
1014 +#define CLOCKING1 0x04 /* FIXME */
1015 +#define CLOCKING1_ADCDIV(x) (((x) & 0x7) << 6)
1016 +#define CLOCKING1_DACDIV(x) (((x) & 0x7) << 3)
1017 +#define CLOCKING1_SYSCLKDIV_1 (0 << 1)
1018 +#define CLOCKING1_SYSCLKDIV_2 (2 << 1)
1019 +#define CLOCKING1_CLKSEL_MCLK (0 << 0)
1020 +#define CLOCKING1_CLKSEL_PLL (1 << 0)
1022 +#define DACCTRL1 0x05
1023 +#define DACCTRL1_DATTENUATE (1 << 7)
1024 +#define DACCTRL1_DACMU (1 << 3)
1025 +#define DACCTRL1_DEEMPH_48 (3 << 1)
1026 +#define DACCTRL1_DEEMPH_44 (2 << 1)
1027 +#define DACCTRL1_DEEMPH_32 (1 << 1)
1028 +#define DACCTRL1_DEEMPH_NONE (0 << 1)
1029 +#define DACCTRL1_DEEMPH(x) ((x) & (0x3 << 1))
1031 +#define DACCTRL2 0x06
1033 +#define AINTFCE1 0x07
1034 +#define AINTFCE1_BCLKINV (1 << 7)
1035 +#define AINTFCE1_MS (1 << 6)
1036 +#define AINTFCE1_LRSWAP (1 << 5)
1037 +#define AINTFCE1_LRP (1 << 4)
1038 +#define AINTFCE1_WL_32 (3 << 2)
1039 +#define AINTFCE1_WL_24 (2 << 2)
1040 +#define AINTFCE1_WL_20 (1 << 2)
1041 +#define AINTFCE1_WL_16 (0 << 2)
1042 +#define AINTFCE1_WL(x) (((x) & 0x3) << 2)
1043 +#define AINTFCE1_FORMAT_DSP (3 << 0)
1044 +#define AINTFCE1_FORMAT_I2S (2 << 0)
1045 +#define AINTFCE1_FORMAT_LJUST (1 << 0)
1046 +#define AINTFCE1_FORMAT_RJUST (0 << 0)
1047 +#define AINTFCE1_FORMAT(x) ((x) & 0x3)
1050 +#define CLOCKING2 0x08
1051 +#define CLOCKING2_DCLKDIV(x) (((x) & 0x7) << 6)
1052 +#define CLOCKING2_BCLKDIV(x) (((x) & 0xf) << 0)
1054 +#define AINTFCE2 0x09
1055 +#define AINTFCE2_ALRCGPIO_ALRC (0 << 6)
1056 +#define AINTFCE2_ALRCGPIO_GPIO (1 << 6)
1057 +#define AINTFCE2_LOOPBACK (1 << 0)
1059 +#define LEFTGAIN 0x0a
1060 +#define LEFTGAIN_LDVU (1 << 8)
1061 +#define LEFTGAIN_LDACVOL(x) ((x) & 0xff)
1063 +#define RIGHTGAIN 0x0b
1064 +#define RIGHTGAIN_RDVU (1 << 8)
1065 +#define RIGHTGAIN_RDACVOL(x) ((x) & 0xff)
1068 +#define RESET_RESET 0x000
1071 +#define ALC1_ALCOFF (0x0 << 7)
1072 +#define ALC1_ALCRONLY (0x1 << 7)
1073 +#define ALC1_ALCLONLY (0x2 << 7)
1074 +#define ALC1_ALCSTEREO (0x3 << 7)
1075 +#define ALC1_ALCSEL(x) (((x) & 0x3) << 7)
1076 +#define ALC1_SET_MAXGAIN(x) ((x & 0x7) << 4)
1077 +#define ALC1_GET_MAXGAIN(x) ((x) & (0x7 << 4))
1078 +#define ALC1_ALCL(x) ((x) & 0x0f)
1081 +#define ALC2_MINGAIN(x) ((x & 0x7) << 4)
1082 +#define ALC2_HLD(x) ((x) & 0x0f)
1085 +#define ALC3_SET_DCY(x) ((x & 0x0f) << 4)
1086 +#define ALC3_GET_DCY(x) ((x) & (0x0f << 4))
1087 +#define ALC3_ATK(x) ((x) & 0x0f)
1089 +#define NOISEGATE 0x14
1090 +#define NOISEGATE_SET_NGTH(x) ((x & 0x1f) << 3)
1091 +#define NOISEGATE_GET_NGTH(x) ((x) & (0x1f << 3))
1092 +#define NOISEGATE_NGAT_ENABLE 1
1094 +#define LADCVOL 0x15
1095 +#define LADCVOL_LAVU_EN (1 << 8)
1096 +#define LADCVOL_LADCVOL(x) ((x) & 0x0ff)
1098 +#define RADCVOL 0x16
1099 +#define RADCVOL_RAVU_EN (1 << 8)
1100 +#define RADCVOL_RADCVOL(x) ((x) & 0x0ff)
1102 +#define ADDITIONAL1 0x17
1103 +#define ADDITIONAL1_TSDEN (1 << 8)
1104 +#define ADDITIONAL1_VSEL_LOWEST (0 << 6)
1105 +#define ADDITIONAL1_VSEL_LOW (1 << 6)
1106 +#define ADDITIONAL1_VSEL_DEFAULT2 (2 << 6)
1107 +#define ADDITIONAL1_VSEL_DEFAULT (3 << 6)
1108 +#define ADDITIONAL1_VSEL(x) (((x) & 0x3) << 6)
1109 +#define ADDITIONAL1_DMONOMIX_STEREO (0 << 4)
1110 +#define ADDITIONAL1_DMONOMIX_MONO (1 << 4)
1111 +#define ADDITIONAL1_DATSEL(x) (((x) & 0x3) << 2)
1112 +#define ADDITIONAL1_TOCLKSEL (1 << 1)
1113 +#define ADDITIONAL1_TOEN (1 << 0)
1115 +#define ADDITIONAL2 0x18
1116 +#define ADDITIONAL2_HPSWEN (1 << 6)
1117 +#define ADDITIONAL2_HPSWPOL (1 << 5)
1118 +#define ADDITIONAL2_TRIS (1 << 3)
1119 +#define ADDITIONAL2_LRCM_ON (1 << 2)
1121 +#define PWRMGMT1 0x19
1122 +#define PWRMGMT1_VMIDSEL_DISABLED (0 << 7)
1123 +#define PWRMGMT1_VMIDSEL_50K (1 << 7)
1124 +#define PWRMGMT1_VMIDSEL_250K (2 << 7)
1125 +#define PWRMGMT1_VMIDSEL_5K (3 << 7)
1126 +#define PWRMGMT1_VREF (1 << 6)
1127 +#define PWRMGMT1_AINL (1 << 5)
1128 +#define PWRMGMT1_AINR (1 << 4)
1129 +#define PWRMGMT1_ADCL (1 << 3)
1130 +#define PWRMGMT1_ADCR (1 << 2)
1131 +#define PWRMGMT1_MICB (1 << 1)
1132 +#define PWRMGMT1_DIGENB (1 << 0)
1134 +#define PWRMGMT2 0x1a
1135 +#define PWRMGMT2_DACL (1 << 8)
1136 +#define PWRMGMT2_DACR (1 << 7)
1137 +#define PWRMGMT2_LOUT1 (1 << 6)
1138 +#define PWRMGMT2_ROUT1 (1 << 5)
1139 +#define PWRMGMT2_SPKL (1 << 4)
1140 +#define PWRMGMT2_SPKR (1 << 3)
1141 +#define PWRMGMT2_OUT3 (1 << 1)
1142 +#define PWRMGMT2_PLL_EN (1 << 0)
1144 +#define ADDITIONAL3 0x1b
1145 +#define ADDITIONAL3_VROI (1 << 6)
1146 +#define ADDITIONAL3_OUT3CAP (1 << 3)
1147 +#define ADDITIONAL3_ADC_ALC_SR(x) ((x) & 0x7)
1149 +#define ANTIPOP1 0x1c
1150 +#define ANTIPOP2 0x1d
1152 +#define ADCLPATH 0x20
1153 +#define ADCLPATH_LMN1 (1 << 8)
1154 +#define ADCLPATH_LMP3 (1 << 7)
1155 +#define ADCLPATH_LMP2 (1 << 6)
1156 +#define ADCLPATH_LMICBOOST_29DB (0x3 << 4)
1157 +#define ADCLPATH_LMICBOOST_20DB (0x2 << 4)
1158 +#define ADCLPATH_LMICBOOST_13DB (0x1 << 4)
1159 +#define ADCLPATH_SET_LMICBOOST(x) ((x & 0x3) << 4)
1160 +#define ADCLPATH_LMIC2B (1 << 3)
1163 +#define ADCRPATH 0x21
1164 +#define ADCRPATH_RMN1 (1 << 8)
1165 +#define ADCRPATH_RMP3 (1 << 7)
1166 +#define ADCRPATH_RMP2 (1 << 6)
1167 +#define ADCRPATH_RMICBOOST_29DB (0x3 << 4)
1168 +#define ADCRPATH_RMICBOOST_20DB (0x2 << 4)
1169 +#define ADCRPATH_RMICBOOST_13DB (0x1 << 4)
1170 +#define ADCRPATH_SET_RMICBOOST(x) ((x & 0x3) << 4)
1171 +#define ADCRPATH_RMIC2B (1 << 3)
1174 +#define LEFTMIX1 0x22
1175 +#define LEFTMIX1_LD2LO (1 << 8)
1176 +#define LEFTMIX1_LI2LO (1 << 7)
1177 +#define LEFTMIX1_LI2LO_DEFAULT (5 << 4)
1178 +#define LEFTMIX1_LI2LOVOL(x) (((x) & 0x7) << 4)
1180 +#define RIGHTMIX2 0x25
1181 +#define RIGHTMIX2_RD2RO (1 << 8)
1182 +#define RIGHTMIX2_RI2RO (1 << 7)
1183 +#define RIGHTMIX2_RI2RO_DEFAULT (5 << 4)
1184 +#define RIGHTMIX2_RI2ROVOL(x) (((x) & 0x7) << 4)
1186 +#define MONOMIX1 0x26
1187 +#define MONOMIX1_L2MO (1 << 7)
1189 +#define MONOMIX2 0x27
1190 +#define MONOMIX2_R2MO (1 << 7)
1193 +#define LSPK_SPKLVU (1 << 8)
1194 +#define LSPK_SPKLZC (1 << 7)
1195 +#define LSPK_SPKLVOL(x) ((x) & 0x7f)
1198 +#define RSPK_SPKRVU (1 << 8)
1199 +#define RSPK_SPKRZC (1 << 7)
1200 +#define RSPK_SPKRVOL(x) ((x) & 0x7f)
1203 +#define LINBMIX 0x2b
1204 +#define RINBMIX 0x2c
1205 +#define BYPASS1 0x2d
1206 +#define BYPASS2 0x2e
1208 +#define PWRMGMT3 0x2f
1209 +#define PWRMGMT3_LMIC (1<<5)
1210 +#define PWRMGMT3_RMIC (1<<4)
1211 +#define PWRMGMT3_LOMIX (1<<3)
1212 +#define PWRMGMT3_ROMIX (1<<2)
1214 +#define ADDITIONAL4 0x30
1216 +#define CLASSDCTRL1 0x31
1217 +#define CLASSDCTRL1_OP_OFF (0<<6)
1218 +#define CLASSDCTRL1_OP_LSPK (1<<6)
1219 +#define CLASSDCTRL1_OP_RSPK (2<<6)
1220 +#define CLASSDCTRL1_OP_LRSPK (3<<6)
1222 +#define CLASSDCTRL3 0x33
1225 +#define PLL1_OPCLKDIV_1 (0<<6)
1226 +#define PLL1_OPCLKDIV_2 (1<<6)
1227 +#define PLL1_OPCLKDIV_3 (2<<6)
1228 +#define PLL1_OPCLKDIV_4 (3<<6)
1229 +#define PLL1_OPCLKDIV_5p5 (4<<6)
1230 +#define PLL1_OPCLKDIV_6 (5<<6)
1231 +#define PLL1_SDM_INTERGER (0<<5)
1232 +#define PLL1_SDM_FRACTIONAL (1<<5)
1233 +#define PLL1_PLLPRESCALE_1 (0<<4)
1234 +#define PLL1_PLLPRESCALE_2 (1<<4)
1235 +#define PLL1_PLLN(x) ((x) & 0xf)
1238 +#define PLL2_PLLK_23_16(x) ((x) & 0x1ff)
1241 +#define PLL3_PLLK_15_8(x) ((x) & 0x1ff)
1244 +#define PLL4_PLLK_7_0(x) ((x) & 0x1ff)
1247 +void audiohw_preinit(void);
1248 +int audiohw_postinit(int bSlave, int AIn, int AOut, int pll_en, int wordLen24b);
1249 +void audiohw_close(void);
1250 +void audiohw_set_frequency(int fsel, int pll_en);
1251 +void audiohw_mute(bool mute);
1252 +void audiohw_micboost(int boostgain);
1253 +void audiohw_micin(int enableMic);
1254 +void audiohw_set_apll(int srate);
1255 +int audiohw_set_lineout_vol(int Aout, int vol_l, int vol_r);
1256 +int audiohw_set_linein_vol(int vol_l, int vol_r);
1257 +void audiohw_mute( bool mute);
1258 +void audiohw_loopback(int fsel);
1259 +void audiohw_codec_exlbk(void);
1260 +void audiohw_bypass(void);
1262 +#endif /* _WM875x_H */
1263 diff --git a/sound/soc/mtk/i2s_ctrl.c b/sound/soc/mtk/i2s_ctrl.c
1264 new file mode 100644
1265 index 0000000..05034b0
1267 +++ b/sound/soc/mtk/i2s_ctrl.c
1269 +#include <linux/init.h>
1270 +#include <linux/version.h>
1271 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
1272 +#include <linux/sched.h>
1274 +#include <linux/module.h>
1275 +#include <linux/kernel.h> /* _printk() */
1276 +#include <linux/slab.h> /* kmalloc() */
1277 +#include <linux/fs.h> /* everything... */
1278 +#include <linux/errno.h> /* error codes */
1279 +#include <linux/types.h> /* size_t */
1280 +#include <linux/proc_fs.h>
1281 +#include <linux/fcntl.h> /* O_ACCMODE */
1282 +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,14)
1283 +#include <asm/system.h> /* cli(), *_flags */
1285 +#include <asm/uaccess.h> /* copy_from/to_user */
1286 +#include <linux/interrupt.h>
1287 +#include <linux/mm.h>
1288 +#include <linux/mm_types.h>
1289 +#include <linux/pci.h>
1290 +#include <linux/delay.h>
1291 +#include "ralink_gdma.h"
1292 +#if defined(CONFIG_I2S_WITH_AEC)
1293 +#include "../aec/aec_api.h"
1296 +#ifdef CONFIG_DEVFS_FS
1297 +#include <linux/devfs_fs_kernel.h>
1298 +static devfs_handle_t devfs_handle;
1301 +#include "i2s_ctrl.h"
1303 +#if defined(CONFIG_SND_MT76XX_SOC)
1304 +#include <sound/soc/mtk/mt76xx_machine.h>
1307 +#if defined(CONFIG_I2S_WM8750)
1308 +#include "../codec/i2c_wm8750.h"
1310 +#if defined(CONFIG_I2S_WM8751)
1311 +#include "../codec/i2c_wm8751.h"
1313 +#if defined(CONFIG_I2S_WM8960)
1314 +#include "i2c_wm8960.h"
1317 +static int i2sdrv_major = 191;
1318 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
1320 +static struct class *i2smodule_class;
1323 +static int _printk(char *fmt, ...)
1328 +/* external functions declarations */
1329 +#if defined(CONFIG_I2S_WM8960)
1330 +extern void audiohw_set_frequency(int fsel, int codec_pll_en);
1331 +void audiohw_set_apll(int srate);
1332 +#elif defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
1333 +extern void audiohw_set_frequency(int fsel);
1335 +#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
1336 +extern int audiohw_set_lineout_vol(int Aout, int vol_l, int vol_r);
1337 +extern int audiohw_set_master_vol(int vol_l, int vol_r);
1338 +extern int audiohw_set_linein_vol(int vol_l, int vol_r);
1341 +extern void audiohw_micboost(int boostgain);
1343 +extern int GdmaI2sTx(uint32_t Src, uint32_t Dst, uint8_t TxNo, uint16_t TransCount,
1344 + void (*DoneIntCallback)(uint32_t data),
1345 + void (*UnMaskIntCallback)(uint32_t data));
1347 +extern int GdmaI2sRx(uint32_t Src, uint32_t Dst, uint8_t RxNo, uint16_t TransCount,
1348 + void (*DoneIntCallback)(uint32_t data),
1349 + void (*UnMaskIntCallback)(uint32_t data));
1351 +extern int GdmaMaskChannel(uint32_t ChNum);
1353 +extern int GdmaUnMaskChannel(uint32_t ChNum);
1355 +/* internal functions declarations */
1356 +irqreturn_t i2s_irq_isr(int irq, void *irqaction);
1357 +int i2s_debug_cmd(unsigned int cmd, unsigned long arg);
1359 +/* forward declarations for _fops */
1360 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
1361 +static long i2s_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
1363 +static int i2s_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
1365 +static int i2s_mmap(struct file *file, struct vm_area_struct *vma);
1366 +static int i2s_open(struct inode *inode, struct file *file);
1367 +static int i2s_release(struct inode *inode, struct file *file);
1368 +int i2s_mmap_alloc(unsigned long size);
1369 +int i2s_mmap_remap(struct vm_area_struct *vma, unsigned long size);
1371 +/* global varable definitions */
1372 +i2s_config_type i2s_config;
1373 +i2s_status_type i2s_status;
1374 +i2s_config_type* pi2s_config = &i2s_config;;
1375 +i2s_status_type* pi2s_status = &i2s_status;;
1378 +ugly_hack_sleep_on_timeout(wait_queue_head_t *q, long timeout)
1380 + unsigned long flags;
1381 + wait_queue_t wait;
1383 + init_waitqueue_entry(&wait, current);
1385 + __set_current_state(TASK_INTERRUPTIBLE);
1386 + spin_lock_irqsave(&q->lock, flags);
1387 + __add_wait_queue(q, &wait);
1388 + spin_unlock(&q->lock);
1390 + timeout = schedule_timeout(timeout);
1392 + spin_lock_irq(&q->lock);
1393 + __remove_wait_queue(q, &wait);
1394 + spin_unlock_irqrestore(&q->lock, flags);
1399 +#define interruptible_sleep_on(x) \
1400 + ugly_hack_sleep_on_timeout(x, MAX_SCHEDULE_TIMEOUT);
1403 +#if defined(ARM_ARCH)
1404 +static dma_addr_t i2s_txdma_addr0, i2s_txdma_addr1;
1405 +static dma_addr_t i2s_rxdma_addr0, i2s_rxdma_addr1;
1406 +#define I2S_TX_FIFO_WREG_PHY (I2S_TX_FIFO_WREG & 0x1FFFFFFF)
1407 +#define I2S_RX_FIFO_RREG_PHY (I2S_RX_FIFO_RREG & 0x1FFFFFFF)
1409 +static dma_addr_t i2s_txdma_addr, i2s_rxdma_addr;
1411 +static dma_addr_t i2s_mmap_addr[MAX_I2S_PAGE*2];
1412 + /* 8khz 11.025khz 12khz 16khz 22.05khz 24Khz 32khz 44.1khz 48khz 88.2khz 96khz*/
1413 +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};
1414 +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};
1415 +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};
1416 +#if defined(CONFIG_I2S_WM8750) || defined(CONFIG_SND_SOC_WM8750)
1417 + /* 8k 11.025k 12k 16k 22.05k 24k 32k 44.1k 48k 88.2k 96k*/
1418 +unsigned long i2s_codec_12p288Mhz[11] = {0x0C, 0x00, 0x10, 0x14, 0x38, 0x38, 0x18, 0x20, 0x00, 0x00, 0x1C};
1419 +unsigned long i2s_codec_12Mhz[11] = {0x0C, 0x32, 0x10, 0x14, 0x37, 0x38, 0x18, 0x22, 0x00, 0x3E, 0x1C};
1420 +unsigned long i2s_codec_24p576Mhz[11] = {0x4C, 0x00, 0x50, 0x54, 0x00, 0x78, 0x58, 0x00, 0x40, 0x00, 0x5C};
1421 +unsigned long i2s_codec_18p432Mhz[11] = {0x0e, 0x32, 0x12, 0x16, 0x36, 0x3a, 0x1a, 0x22, 0x02, 0x3e, 0x1e};
1423 +#if defined(CONFIG_I2S_WM8751) || defined(CONFIG_SND_SOC_WM8751)
1424 +unsigned long i2s_codec_12p288Mhz[11] = {0x04, 0x00, 0x10, 0x14, 0x38, 0x38, 0x18, 0x20, 0x00, 0x00, 0x1C};
1425 +unsigned long i2s_codec_12Mhz[11] = {0x04, 0x32, 0x10, 0x14, 0x37, 0x38, 0x18, 0x22, 0x00, 0x3E, 0x1C};
1427 +#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_SND_SOC_WM8960)
1428 +unsigned long i2s_codec_12p288Mhz[11] = {0x36, 0x24, 0x24, 0x1b, 0x12, 0x12, 0x09, 0x00, 0x00, 0x00, 0x00};
1429 +unsigned long i2s_codec_12Mhz[11] = {0x36, 0x24, 0x24, 0x1b, 0x12, 0x12, 0x09, 0x00, 0x00, 0x00, 0x00};
1431 +EXPORT_SYMBOL(i2s_codec_12p288Mhz);
1432 +EXPORT_SYMBOL(i2s_codec_12Mhz);
1434 +#if defined(CONFIG_RALINK_RT6855A)
1435 + /* 8K 11.025k 12k 16k 22.05k 24k 32k 44.1K 48k 88.2k 96k */
1436 +unsigned long i2s_inclk_int[11] = { 97, 70, 65, 48, 35, 32, 24, 17, 16, 12, 8};
1437 +unsigned long i2s_inclk_comp[11] = { 336, 441, 53, 424, 220, 282, 212, 366, 141, 185, 70};
1438 +#elif defined (CONFIG_RALINK_MT7621)
1439 +#ifdef MT7621_ASIC_BOARD
1440 +#if defined (CONFIG_I2S_MCLK_12P288MHZ)
1441 +unsigned long i2s_inclk_int[11] = { 576, 384, 0, 288, 192, 192, 144, 96, 96, 48, 48};
1442 +unsigned long i2s_inclk_comp[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1443 +#elif defined(CONFIG_I2S_MCLK_12MHZ)
1444 +unsigned long i2s_inclk_int[11] = {1171, 850, 0, 585, 425, 390, 292, 212, 195, 106, 97};
1445 +unsigned long i2s_inclk_comp[11] = { 448, 174, 0, 480, 87, 320, 496, 299, 160, 149, 336};
1447 +#else //MT7621_FPGA_BOARD
1448 +unsigned long i2s_inclk_int[11] = { 529, 384, 0, 264, 192, 176, 132, 96, 88, 48, 44};
1449 +unsigned long i2s_inclk_comp[11] = { 102, 0, 0, 307, 0, 204, 153, 0, 102, 0, 51};
1451 +#elif defined (CONFIG_RALINK_MT7628)
1452 +#ifdef MT7628_ASIC_BOARD
1453 + /* 8K 11.025k 12k 16k 22.05k 24k 32k 44.1K 48k 88.2k 96k 176k 192k */
1454 +unsigned long i2s_inclk_int_16bit[13] = {937, 680, 0, 468, 340, 312, 234, 170, 156, 85, 78, 42, 39};
1455 +unsigned long i2s_inclk_comp_16bit[13]= {256, 139, 0, 384, 69, 256, 192, 34, 128, 17, 64, 267, 32};
1456 +unsigned long i2s_inclk_int_24bit[13] = {625, 404, 0, 312, 226, 208, 156, 113, 104, 56, 52, 28, 26};
1457 +unsigned long i2s_inclk_comp_24bit[13]= { 0, 404, 0, 256, 387, 170, 128, 193, 85, 352, 42, 176, 21};
1459 + /* 8K 11.025k 12k 16k 22.05k 24k 32k 44.1K 48k 88.2k 96k 176k 192k */
1460 +unsigned long i2s_inclk_int_16bit[13] = {468, 340, 0, 234, 170, 156, 117, 85, 78, 42, 39, 21, 19};
1461 +unsigned long i2s_inclk_comp_16bit[13]= {384, 69, 0, 192, 34, 128, 96, 17, 64, 264, 32, 133, 272};
1462 +unsigned long i2s_inclk_int_24bit[13] = {312, 202, 0, 156, 113, 104, 78, 56, 52, 28, 26, 14, 13};
1463 +unsigned long i2s_inclk_comp_24bit[13]= {256, 202, 0, 128, 193, 85, 64, 352, 42, 176, 21, 88, 10};
1465 +#elif defined (CONFIG_ARCH_MT7623)
1466 +#if defined MT7623_ASIC_BOARD
1467 + /* 8K 11.025k 12k 16k 22.05k 24k 32k 44.1K 48k 88.2k 96k 176k 192k */
1468 +unsigned long i2s_inclk_int_16bit[13] = {576, 384, 0, 288, 192, 192, 144, 96, 96, 48, 48, 24, 24};
1469 +unsigned long i2s_inclk_comp_16bit[13]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1470 +unsigned long i2s_inclk_int_24bit[13] = {384, 256, 0, 192, 128, 128, 96, 64, 64, 32, 32, 16, 16};
1471 +unsigned long i2s_inclk_comp_24bit[13]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1473 + /* 8K 11.025k 12k 16k 22.05k 24k 32k 44.1K 48k 88.2k 96k 176k 192k */
1474 +unsigned long i2s_inclk_int_16bit[13] = {72, 48, 0, 36, 24, 24, 18, 12, 12, 6, 6, 3, 3};
1475 +unsigned long i2s_inclk_comp_16bit[13]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1476 +unsigned long i2s_inclk_int_24bit[13] = {48, 32, 0, 24, 16, 16, 12, 8, 8, 4, 4, 2, 2};
1477 +unsigned long i2s_inclk_comp_24bit[13]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1480 + /* 8K 11.025k 12k 16k 22.05k 24k 32k 44.1K 48k 88.2k 96k */
1481 +unsigned long i2s_inclk_int[11] = { 78, 56, 52, 39, 28, 26, 19, 14, 13, 9, 6};
1482 +unsigned long i2s_inclk_comp[11] = { 64, 352, 42, 32, 176, 21, 272, 88, 10, 455, 261};
1485 +#if defined(CONFIG_I2S_WITH_AEC)
1486 +aecFuncTbl_t *aecFuncP;
1488 +/* USB mode 22.05Khz register value in datasheet is 0x36 but will cause slow clock, 0x37 is correct value */
1489 +/* USB mode 44.1Khz register value in datasheet is 0x22 but will cause slow clock, 0x23 is correct value */
1491 +struct tasklet_struct i2s_tx_tasklet;
1492 +struct tasklet_struct i2s_rx_tasklet;
1493 +EXPORT_SYMBOL(i2s_tx_tasklet);
1494 +EXPORT_SYMBOL(i2s_rx_tasklet);
1496 +char test_buf[I2S_PAGE_SIZE];
1497 +char test_buf_1[I2S_PAGE_SIZE];
1498 +char test_buf_2[I2S_PAGE_SIZE];
1500 +static const struct file_operations i2s_fops = {
1501 + owner : THIS_MODULE,
1504 + release : i2s_release,
1505 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
1506 + unlocked_ioctl: i2s_ioctl,
1508 + ioctl : i2s_ioctl,
1512 +int __init i2s_mod_init(void)
1516 + _printk("******* i2s module init **********\n");
1517 + /* register device with kernel */
1518 +#ifdef CONFIG_DEVFS_FS
1519 + if(devfs_register_chrdev(i2sdrv_major, I2SDRV_DEVNAME , &i2s_fops)) {
1520 + _printk(KERN_WARNING " i2s: can't create device node - %s\n", I2SDRV_DEVNAME);
1524 + devfs_handle = devfs_register(NULL, I2SDRV_DEVNAME, DEVFS_FL_DEFAULT, i2sdrv_major, 0,
1525 + S_IFCHR | S_IRUGO | S_IWUGO, &i2s_fops, NULL);
1527 + result = register_chrdev(i2sdrv_major, I2SDRV_DEVNAME, &i2s_fops);
1529 + _printk(KERN_WARNING "i2s: can't get major %d\n",i2sdrv_major);
1533 + if (i2sdrv_major == 0) {
1534 + i2sdrv_major = result; /* dynamic */
1538 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
1540 + i2smodule_class=class_create(THIS_MODULE, I2SDRV_DEVNAME);
1541 + if (IS_ERR(i2smodule_class))
1543 + device_create(i2smodule_class, NULL, MKDEV(i2sdrv_major, 0), I2SDRV_DEVNAME);
1546 +#if defined(CONFIG_I2S_WITH_AEC)
1547 + _printk("AEC FuncP init \n");
1548 + /*Add by mtk04880*/
1549 + aecFuncP = kmalloc(sizeof(aecFuncTbl_t), GFP_KERNEL);
1550 + /*If aecFuncP cannot request memory,it will be ignored in I2S module. Since AEC & I2S are independent
1551 + * when AEC module is inserted,It will return err message (but I2S will keep running without AEC support)
1554 + memset(aecFuncP,0,sizeof(aecFuncTbl_t));
1561 +void i2s_mod_exit(void)
1563 + _printk("************ i2s module exit *************\n");
1564 +#ifdef CONFIG_DEVFS_FS
1565 + devfs_unregister_chrdev(i2sdrv_major, I2SDRV_DEVNAME);
1566 + devfs_unregister(devfs_handle);
1568 + unregister_chrdev(i2sdrv_major, I2SDRV_DEVNAME);
1570 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
1572 + device_destroy(i2smodule_class,MKDEV(i2sdrv_major, 0));
1573 + class_destroy(i2smodule_class);
1579 +int i2s_open(struct inode *inode, struct file *filp)
1581 +#if defined(I2S_HW_INTERRUPT_EN)&&(I2S_SW_IRQ_EN)
1584 + int minor = iminor(inode);
1586 + if (minor >= I2S_MAX_DEV)
1589 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
1590 + MOD_INC_USE_COUNT;
1592 + try_module_get(THIS_MODULE);
1595 + if (filp->f_flags & O_NONBLOCK) {
1596 + MSG("filep->f_flags O_NONBLOCK set\n");
1600 + /* set i2s_config */
1601 + filp->private_data = pi2s_config;
1602 + memset(pi2s_config, 0, sizeof(i2s_config_type));
1603 +#ifdef I2S_STATISTIC
1604 + memset(pi2s_status, 0, sizeof(i2s_status_type));
1606 + i2s_param_init(pi2s_config);
1608 +#if defined(I2S_HW_INTERRUPT_EN)&&(I2S_SW_IRQ_EN)
1609 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
1610 + Ret = request_irq(SURFBOARDINT_I2S, i2s_irq_isr, IRQF_DISABLED, "Ralink_I2S", NULL);
1612 + Ret = request_irq(SURFBOARDINT_I2S, i2s_irq_isr, SA_INTERRUPT, "Ralink_I2S", NULL);
1616 + MSG("IRQ %d is not free.\n", SURFBOARDINT_I2S);
1617 + i2s_release(inode, filp);
1622 + init_waitqueue_head(&(pi2s_config->i2s_tx_qh));
1623 + init_waitqueue_head(&(pi2s_config->i2s_rx_qh));
1624 + spin_lock_init(&pi2s_config->lock);
1630 +static int i2s_release(struct inode *inode, struct file *filp)
1632 + i2s_config_type* ptri2s_config;
1634 + /* decrement usage count */
1635 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
1636 + MOD_DEC_USE_COUNT;
1638 + module_put(THIS_MODULE);
1641 +#if defined(I2S_HW_INTERRUPT_EN)&&(I2S_SW_IRQ_EN)
1642 + free_irq(SURFBOARDINT_I2S, NULL);
1645 + ptri2s_config = filp->private_data;
1646 + if(ptri2s_config==NULL)
1648 +#ifdef CONFIG_I2S_MMAP
1649 + i2s_mem_unmap(ptri2s_config);
1651 + i2s_txbuf_free(ptri2s_config);
1652 + i2s_rxbuf_free(ptri2s_config);
1655 + i2s_txPagebuf_free(ptri2s_config);
1656 + i2s_rxPagebuf_free(ptri2s_config);
1658 + MSG("i2s_release succeeds\n");
1662 +int i2s_mmap_alloc(unsigned long size)
1668 + page_size = I2S_PAGE_SIZE;
1670 + if ((pi2s_config->mmap_index == 0) || (pi2s_config->mmap_index == MAX_I2S_PAGE))
1672 + MSG("mmap_index=%d\n", pi2s_config->mmap_index);
1674 + first_index = pi2s_config->mmap_index;
1675 + pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index] = kmalloc(size, GFP_DMA);
1676 + i2s_mmap_addr[pi2s_config->mmap_index] = (dma_addr_t)dma_map_single(NULL, pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index], size, DMA_BIDIRECTIONAL);
1678 + if( pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index] == NULL )
1680 + MSG("i2s_mmap failed\n");
1686 + _printk("illegal index:%d\n", pi2s_config->mmap_index);
1690 + _printk("MMAP[%d]=0x%08X, i2s_mmap_addr[%d]=0x%08x\n",
1691 + pi2s_config->mmap_index, (u32)pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index],
1692 + pi2s_config->mmap_index, i2s_mmap_addr[pi2s_config->mmap_index]);
1694 + memset(pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index], 0, size);
1695 + pi2s_config->mmap_index++;
1697 + for (i=1; i<MAX_I2S_PAGE; i++)
1699 + i2s_mmap_addr[pi2s_config->mmap_index] = i2s_mmap_addr[first_index] + i*page_size;
1700 + pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index] = pi2s_config->pMMAPBufPtr[first_index] + i*page_size;
1702 + _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]);
1704 + /* Notice: The last mmap_index's value should be MAX_I2S_PAGE or MAX_I2S_PAGE*2 */
1705 + pi2s_config->mmap_index++;
1711 +int i2s_mmap_remap(struct vm_area_struct *vma, unsigned long size)
1715 + if((pi2s_config->pMMAPBufPtr[0]!=NULL) && (pi2s_config->mmap_index == MAX_I2S_PAGE))
1717 + MSG("i2s_mmap_remap:0\n");
1718 + nRet = remap_pfn_range(vma, vma->vm_start, virt_to_phys((void *)pi2s_config->pMMAPBufPtr[0]) >> PAGE_SHIFT, size, vma->vm_page_prot);
1722 + _printk("i2s_mmap->remap_pfn_range failed\n");
1727 + if((pi2s_config->pMMAPBufPtr[MAX_I2S_PAGE]!=NULL) && (pi2s_config->mmap_index == MAX_I2S_PAGE*2))
1729 + MSG("i2s_mmap_remap:%d\n", MAX_I2S_PAGE);
1731 + 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);
1735 + _printk("i2s_mmap->remap_pfn_range failed\n");
1743 +static int i2s_mmap(struct file *filp, struct vm_area_struct *vma)
1745 + unsigned long size = vma->vm_end-vma->vm_start;
1746 + _printk("page_size=%d, ksize=%lu\n", I2S_PAGE_SIZE, size);
1748 + if((pi2s_config->pMMAPBufPtr[0]==NULL)&&(pi2s_config->mmap_index!=0))
1749 + pi2s_config->mmap_index = 0;
1751 + _printk("%s: vm_start=%08X,vm_end=%08X\n", __func__, (u32)vma->vm_start, (u32)vma->vm_end);
1753 + /* Do memory allocate and dma sync */
1754 + i2s_mmap_alloc(size);
1756 + i2s_mmap_remap(vma, size);
1762 +int i2s_mem_unmap(i2s_config_type* ptri2s_config)
1766 + page_size = I2S_PAGE_SIZE;
1768 + if(ptri2s_config->pMMAPBufPtr[0])
1770 + _printk("ummap MMAP[0]=0x%08X\n", (u32)ptri2s_config->pMMAPBufPtr[0]);
1771 + dma_unmap_single(NULL, i2s_mmap_addr[0], MAX_I2S_PAGE*page_size, DMA_BIDIRECTIONAL);
1772 + kfree(ptri2s_config->pMMAPBufPtr[0]);
1775 + if(ptri2s_config->pMMAPBufPtr[MAX_I2S_PAGE])
1777 + _printk("ummap MMAP[%d]=0x%08X\n", MAX_I2S_PAGE, (u32)ptri2s_config->pMMAPBufPtr[MAX_I2S_PAGE]);
1778 + dma_unmap_single(NULL, i2s_mmap_addr[MAX_I2S_PAGE], MAX_I2S_PAGE*page_size, DMA_BIDIRECTIONAL);
1779 + kfree(ptri2s_config->pMMAPBufPtr[MAX_I2S_PAGE]);
1782 + ptri2s_config->mmap_index = 0;
1787 +int i2s_param_init(i2s_config_type* ptri2s_config)
1789 + ptri2s_config->dmach = GDMA_I2S_TX0;
1790 + ptri2s_config->tx_ff_thres = CONFIG_I2S_TFF_THRES;
1791 + ptri2s_config->tx_ch_swap = CONFIG_I2S_CH_SWAP;
1792 + ptri2s_config->rx_ff_thres = CONFIG_I2S_TFF_THRES;
1793 + ptri2s_config->rx_ch_swap = CONFIG_I2S_CH_SWAP;
1794 + ptri2s_config->slave_en = CONFIG_I2S_SLAVE_EN;
1795 + ptri2s_config->codec_pll_en = CONFIG_I2S_CODEC_PLL_EN;
1797 + ptri2s_config->bRxDMAEnable = 0;
1798 + ptri2s_config->bTxDMAEnable = 0;
1799 + //ptri2s_config->bALSAEnable = 0;
1800 + ptri2s_config->srate = 44100;
1801 + ptri2s_config->txvol = 0;
1802 + ptri2s_config->rxvol = 0;
1803 + ptri2s_config->lbk = 0;
1804 + ptri2s_config->extlbk = 0;
1805 + ptri2s_config->txrx_coexist = 0;
1806 + ptri2s_config->wordlen_24b = 0;
1807 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
1808 + ptri2s_config->sys_endian = 0;
1809 + ptri2s_config->fmt = 0;
1811 + ptri2s_config->micboost = 0;
1812 + ptri2s_config->micin = 0;
1817 +int i2s_txbuf_alloc(i2s_config_type* ptri2s_config)
1821 + for( i = 0 ; i < MAX_I2S_PAGE ; i ++ )
1823 +#if defined(CONFIG_I2S_MMAP)
1824 + ptri2s_config->pMMAPTxBufPtr[i] = ptri2s_config->pMMAPBufPtr[i];
1826 + if(ptri2s_config->pMMAPTxBufPtr[i]==NULL)
1827 + ptri2s_config->pMMAPTxBufPtr[i] = kmalloc(I2S_PAGE_SIZE, GFP_KERNEL);
1829 + memset(ptri2s_config->pMMAPTxBufPtr[i], 0, I2S_PAGE_SIZE);
1835 +int i2s_rxbuf_alloc(i2s_config_type* ptri2s_config)
1839 + for( i = 0 ; i < MAX_I2S_PAGE ; i ++ )
1841 +#if defined(CONFIG_I2S_MMAP)
1842 + ptri2s_config->pMMAPRxBufPtr[i] = ptri2s_config->pMMAPBufPtr[i+(ptri2s_config->mmap_index-MAX_I2S_PAGE)];
1844 + if(ptri2s_config->pMMAPRxBufPtr[i]==NULL)
1845 + ptri2s_config->pMMAPRxBufPtr[i] = kmalloc(I2S_PAGE_SIZE, GFP_KERNEL);
1847 + memset(ptri2s_config->pMMAPRxBufPtr[i], 0, I2S_PAGE_SIZE);
1853 +int i2s_txPagebuf_alloc(i2s_config_type* ptri2s_config)
1855 +#if defined(ARM_ARCH)
1856 + ptri2s_config->pPage0TxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE , &i2s_txdma_addr0);
1857 + ptri2s_config->pPage1TxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE , &i2s_txdma_addr1);
1858 + if(ptri2s_config->pPage0TxBuf8ptr==NULL)
1860 + MSG("Allocate Tx Page0 Buffer Failed\n");
1863 + if(ptri2s_config->pPage1TxBuf8ptr==NULL)
1865 + MSG("Allocate Tx Page1 Buffer Failed\n");
1869 + ptri2s_config->pPage0TxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE*2 , &i2s_txdma_addr);
1870 + if(ptri2s_config->pPage0TxBuf8ptr==NULL)
1872 + MSG("Allocate Tx Page Buffer Failed\n");
1875 + ptri2s_config->pPage1TxBuf8ptr = ptri2s_config->pPage0TxBuf8ptr + I2S_PAGE_SIZE;
1880 +int i2s_rxPagebuf_alloc(i2s_config_type* ptri2s_config)
1882 +#if defined(ARM_ARCH)
1883 + ptri2s_config->pPage0RxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE, &i2s_rxdma_addr0);
1884 + ptri2s_config->pPage1RxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE, &i2s_rxdma_addr1);
1885 + if(ptri2s_config->pPage0RxBuf8ptr==NULL)
1887 + MSG("Allocate Rx Page Buffer Failed\n");
1890 + if(ptri2s_config->pPage1RxBuf8ptr==NULL)
1892 + MSG("Allocate Rx Page Buffer Failed\n");
1896 + ptri2s_config->pPage0RxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE*2 , &i2s_rxdma_addr);
1897 + if(ptri2s_config->pPage0RxBuf8ptr==NULL)
1899 + MSG("Allocate Rx Page Buffer Failed\n");
1902 + ptri2s_config->pPage1RxBuf8ptr = ptri2s_config->pPage0RxBuf8ptr + I2S_PAGE_SIZE;
1907 +int i2s_txbuf_free(i2s_config_type* ptri2s_config)
1911 + for(i = 0 ; i < MAX_I2S_PAGE ; i ++)
1913 + if(ptri2s_config->pMMAPTxBufPtr[i] != NULL)
1915 +#if defined(CONFIG_I2S_MMAP)
1916 + ptri2s_config->pMMAPTxBufPtr[i] = NULL;
1918 + kfree(ptri2s_config->pMMAPTxBufPtr[i]);
1919 + ptri2s_config->pMMAPTxBufPtr[i] = NULL;
1926 +int i2s_rxbuf_free(i2s_config_type* ptri2s_config)
1930 + for(i = 0 ; i < MAX_I2S_PAGE ; i ++)
1932 + if(ptri2s_config->pMMAPRxBufPtr[i] != NULL)
1934 +#if defined(CONFIG_I2S_MMAP)
1935 + ptri2s_config->pMMAPRxBufPtr[i] = NULL;
1937 + kfree(ptri2s_config->pMMAPRxBufPtr[i]);
1938 + ptri2s_config->pMMAPRxBufPtr[i] = NULL;
1946 +int i2s_txPagebuf_free(i2s_config_type* ptri2s_config)
1948 +#if defined(ARM_ARCH)
1949 + if (ptri2s_config->pPage0TxBuf8ptr)
1951 + pci_free_consistent(NULL, I2S_PAGE_SIZE, ptri2s_config->pPage0TxBuf8ptr, i2s_txdma_addr0);
1952 + ptri2s_config->pPage0TxBuf8ptr = NULL;
1955 + if (ptri2s_config->pPage1TxBuf8ptr)
1957 + pci_free_consistent(NULL, I2S_PAGE_SIZE, ptri2s_config->pPage1TxBuf8ptr, i2s_txdma_addr1);
1958 + ptri2s_config->pPage1TxBuf8ptr = NULL;
1960 + _printk("Free tx page buffer\n");
1962 + if (ptri2s_config->pPage0TxBuf8ptr)
1964 + pci_free_consistent(NULL, I2S_PAGE_SIZE*2, ptri2s_config->pPage0TxBuf8ptr, i2s_txdma_addr);
1965 + ptri2s_config->pPage0TxBuf8ptr = NULL;
1972 +int i2s_rxPagebuf_free(i2s_config_type* ptri2s_config)
1974 +#if defined(ARM_ARCH)
1975 + if (ptri2s_config->pPage0RxBuf8ptr)
1977 + pci_free_consistent(NULL, I2S_PAGE_SIZE, ptri2s_config->pPage0RxBuf8ptr, i2s_rxdma_addr0);
1978 + ptri2s_config->pPage0RxBuf8ptr = NULL;
1980 + if (ptri2s_config->pPage1RxBuf8ptr)
1982 + pci_free_consistent(NULL, I2S_PAGE_SIZE, ptri2s_config->pPage1RxBuf8ptr, i2s_rxdma_addr1);
1983 + ptri2s_config->pPage1RxBuf8ptr = NULL;
1985 + _printk("Free rx page buffer\n");
1987 + if (ptri2s_config->pPage0RxBuf8ptr)
1989 + pci_free_consistent(NULL, I2S_PAGE_SIZE*2, ptri2s_config->pPage0RxBuf8ptr, i2s_rxdma_addr);
1990 + ptri2s_config->pPage0RxBuf8ptr = NULL;
1996 +int i2s_reset_tx_param(i2s_config_type* ptri2s_config)
1998 + ptri2s_config->tx_isr_cnt = 0;
1999 + ptri2s_config->tx_w_idx = 0;
2000 + ptri2s_config->tx_r_idx = 0;
2001 + ptri2s_config->enLable = 0;
2002 + ptri2s_config->tx_pause_en = 0;
2003 + ptri2s_config->end_cnt = 0;
2004 + ptri2s_config->tx_stop_cnt = 0;
2006 +#ifdef I2S_STATISTIC
2007 + pi2s_status->txbuffer_unrun = 0;
2008 + pi2s_status->txbuffer_ovrun = 0;
2009 + pi2s_status->txdmafault = 0;
2010 + pi2s_status->txovrun = 0;
2011 + pi2s_status->txunrun = 0;
2012 + pi2s_status->txthres = 0;
2013 + pi2s_status->txbuffer_len = 0;
2019 +int i2s_reset_rx_param(i2s_config_type* ptri2s_config)
2021 + ptri2s_config->rx_isr_cnt = 0;
2022 + ptri2s_config->rx_w_idx = 0;
2023 + ptri2s_config->rx_r_idx = 0;
2024 + ptri2s_config->enLable = 0;
2025 + ptri2s_config->rx_pause_en = 0;
2026 + ptri2s_config->rx_stop_cnt = 0;
2028 +#ifdef I2S_STATISTIC
2029 + pi2s_status->rxbuffer_unrun = 0;
2030 + pi2s_status->rxbuffer_ovrun = 0;
2031 + pi2s_status->rxdmafault = 0;
2032 + pi2s_status->rxovrun = 0;
2033 + pi2s_status->rxunrun = 0;
2034 + pi2s_status->rxthres = 0;
2035 + pi2s_status->rxbuffer_len = 0;
2040 +#ifdef MT7621_ASIC_BOARD
2041 +int i2s_pll_config_mt7621(unsigned long index)
2043 + unsigned long data;
2044 + unsigned long regValue;
2045 + bool xtal_20M_en = 0;
2046 +// bool xtal_25M_en = 0;
2047 + bool xtal_40M_en = 0;
2049 + regValue = i2s_inw(RALINK_SYSCTL_BASE + 0x10);
2050 + regValue = (regValue >> 6) & 0x7;
2054 + MSG("Xtal is 20MHz. \n");
2056 + else if (regValue < 6)
2059 + MSG("Xtal is 40M.\n");
2063 + //xtal_25M_en = 1;
2064 + MSG("Xtal is 25M.\n");
2067 +#if defined (CONFIG_I2S_MCLK_12P288MHZ)
2068 + _printk("MT7621 provide 12.288M/11.298MHz REFCLK\n");
2069 + /* Firstly, reset all required register to default value */
2070 + i2s_outw(RALINK_ANA_CTRL_BASE, 0x00008000);
2071 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, 0x01001d61);//0x01401d61);
2072 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, 0x38233d0e);
2073 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, 0x80100004);//0x80120004);
2074 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x1c7dbf48);
2076 + /* toggle RG_XPTL_CHG */
2077 + i2s_outw(RALINK_ANA_CTRL_BASE, 0x00008800);
2078 + i2s_outw(RALINK_ANA_CTRL_BASE, 0x00008c00);
2080 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
2081 + data &= ~(0x0000ffc0);
2082 + if ((xtal_40M_en) || (xtal_20M_en))
2084 + data |= REGBIT(0x1d, 8); /* for 40M or 20M */
2088 + data |= REGBIT(0x17, 8); /* for 25M */
2093 + data |= REGBIT(0x1, 6); /* for 40M */
2095 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
2098 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0018);
2099 + data &= ~(0xf0773f00);
2100 + data |= REGBIT(0x3, 28);
2101 + data |= REGBIT(0x2, 20);
2102 + if ((xtal_40M_en) || (xtal_20M_en))
2104 + data |= REGBIT(0x3, 16); /* for 40M or 20M */
2108 + data |= REGBIT(0x2, 16); /* for 25M */
2110 + data |= REGBIT(0x3, 12);
2111 + if ((xtal_40M_en) || (xtal_20M_en))
2113 + data |= REGBIT(0xd, 8); /* for 40M or 20M */
2117 + data |= REGBIT(0x7, 8); /* for 25M */
2119 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, data);
2121 + if((index==1)|(index==4)|(index==7)|(index==9))// 270 MHz for 22.05K, 44.1K, 88.2K, 176.4K
2123 + if ((xtal_40M_en) || (xtal_20M_en))
2125 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x1a18548a); /* for 40M or 20M */
2129 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x14ad106e); /* for 25M */
2132 + else if ((index==0)|(index==3)|(index==5)|(index==6)|(index==8)|(index==10))// 294 MHZ for 24K, 48K, 96K, 192K
2134 + if ((xtal_40M_en) || (xtal_20M_en))
2136 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x1c7dbf48); /* for 40M or 20M */
2140 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x1697cc39); /* for 25M */
2143 + else if (index==2)
2145 + _printk("Not support 12KHz sampling rate!\n");
2150 + _printk("Wrong sampling rate!\n");
2154 + //*Common setting - Set PLLGP_CTRL_4 *//
2156 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2157 + data &= ~(REGBIT(0x1, 31));
2158 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2162 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2163 + data |= REGBIT(0x1, 0);
2164 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2168 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2169 + data |= REGBIT(0x1, 3);
2170 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2174 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2175 + data |= REGBIT(0x1, 8);
2176 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2180 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2181 + data |= REGBIT(0x1, 6);
2182 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2185 + /* 6. Bit 5 & Bit 7*/
2186 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2187 + data |= REGBIT(0x1, 5);
2188 + data |= REGBIT(0x1, 7);
2189 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2193 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2194 + data |= REGBIT(0x1, 17);
2195 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2197 +#elif defined(CONFIG_I2S_MCLK_12MHZ)
2198 + _printk("MT7621 provide 12MHz REFCLK\n");
2199 + /* Firstly, reset all required register to default value */
2200 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, 0x01401d61);//0x01401d61);
2201 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, 0x80120004);//0x80100004);
2202 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, 0x38233d0e);
2206 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2207 + data &= ~REGBIT(0x1, 17);
2208 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2210 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
2211 + data &= ~REGBIT(0x3, 4);
2212 + data |= REGBIT(0x1, 4);
2213 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
2215 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2216 + data &= ~REGBIT(0x1, 31);
2217 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2219 + else if (xtal_20M_en)
2221 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2222 + data &= ~REGBIT(0x1, 17);
2223 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2225 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
2226 + data &= ~REGBIT(0x3, 6);
2227 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
2229 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
2230 + data &= ~REGBIT(0x3, 4);
2231 + data |= REGBIT(0x1, 4);
2232 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
2234 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2235 + data &= ~REGBIT(0x1, 31);
2236 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2240 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2241 + data &= ~REGBIT(0x1, 17);
2242 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2244 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
2245 + data &= ~REGBIT(0x7f, 8);
2246 + data |= REGBIT(0x17, 8);
2247 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
2249 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
2250 + data &= ~REGBIT(0x3, 6);
2251 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
2253 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0018);
2254 + data &= ~REGBIT(0x7, 16);
2255 + data |= REGBIT(0x2, 16);
2256 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, data);
2258 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0018);
2259 + data &= ~REGBIT(0xf, 8);
2260 + data |= REGBIT(0x7, 8);
2261 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, data);
2264 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
2265 + data &= ~REGBIT(0x3, 4);
2266 + data |= REGBIT(0x1, 4);
2267 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
2269 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2270 + data &= ~REGBIT(0x1, 31);
2271 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2277 +#if defined(CONFIG_I2S_IN_MCLK)
2278 +int i2s_pll_refclk_set(void)
2280 + unsigned long data;
2282 + /* Set APLL register for REFCLK */
2283 + data = i2s_inw(RALINK_SYSCTL_BASE+0x90);
2284 + data &= ~(0x0000f000);
2285 + data |= REGBIT(0x1, 12);
2286 + i2s_outw(RALINK_SYSCTL_BASE+0x0090, data);
2288 + data = i2s_inw(RALINK_SYSCTL_BASE+0x0090);
2289 + data &= ~(0x00000300);
2290 + i2s_outw(RALINK_SYSCTL_BASE+0x0090, data);
2291 + MSG("Set 0x90 register\n");
2298 +#ifdef MT7623_ASIC_BOARD
2299 +int i2s_pll_config_mt7623(unsigned long index)
2301 + unsigned long data;
2304 + data = i2s_inw(AUD2PLL_PWR_CON0);
2306 + i2s_outw(AUD2PLL_PWR_CON0, data);
2309 + /* xPLL ISO Disable */
2310 + data = i2s_inw(AUD2PLL_PWR_CON0);
2312 + i2s_outw(AUD2PLL_PWR_CON0, data);
2314 + /* xPLL Frequency Set */
2315 + data = i2s_inw(AUD2PLL_CON0);
2317 + i2s_outw(AUD2PLL_CON0, data);
2319 + /* AUD1PLL Frequency Set(change from 98.304MHz to 294.912MHz) */
2320 + i2s_outw(AUD1PLL_CON0, 0x121);
2321 + i2s_outw(AUD1PLL_CON1, 0xad5efee6);
2324 + /* Audio clock setting */
2325 + if((index==1)|(index==4)|(index==7)|(index==9)|(index==11))// for 22.05K, 44.1K, 88.2K, 176.4K
2327 + _printk("\n*****%s:index=%d(270MHz)*****\n", __func__, (int)index);
2328 + data = i2s_inw(0xFB00002c);
2329 + //data &= ~REGBIT(0x8, 1);
2331 + i2s_outw(0xFB00002C, data); /* AUD1PLL 270.9204MHz */
2333 + else if ((index==0)|(index==3)|(index==5)|(index==6)|(index==8)|(index==10)|(index==12)) //for 24K, 48K, 96K, 192K
2335 + _printk("\n*****%s:index=%d(294MHz)*****\n", __func__, (int)index);
2336 + data = i2s_inw(0xFB00002c);
2337 + //data |= REGBIT(0x8, 1);
2339 + i2s_outw(0xFB00002c, data); /* AUD1PLL 294.912MHz */
2341 + else if (index==2)
2343 + _printk("Not support 12KHz sampling rate!\n");
2348 + _printk("Wrong sampling rate!\n");
2355 +#if defined(MT7628_ASIC_BOARD) || defined(CONFIG_ARCH_MT7623)
2356 +int i2s_driving_strength_adjust(void)
2358 +#if defined(MT7628_ASIC_BOARD)
2359 + unsigned long data;
2361 + MSG("Adjust MT7628 current's driving strngth\n");
2362 + /* Adjust REFCLK0's driving strength of current which can avoid
2363 + * the glitch of REFCKL0
2364 + * E4 = 0xb0001354[5]; E8 = 0xb0001364[5]
2365 + * (E4,E8)=(0,0)-> 4 mA;
2368 + * =(1,1)-> 16 mA*/
2371 + data = i2s_inw(0xb0001354);
2372 + data &= ~(0x1<<5);
2373 + i2s_outw(0xb0001354, data);
2375 + data = i2s_inw(0xb0001364);
2377 + i2s_outw(0xb0001364, data);
2379 +#if defined(CONFIG_ARCH_MT7623)
2380 + MSG("Adjust MT7623 current's driving strngth\n");
2382 + i2s_outw(0xF0005F80, 0x7777);
2389 +#if defined(CONFIG_I2S_IN_MCLK)
2390 +#if defined(CONFIG_I2S_MCLK_12MHZ)
2391 +int i2s_refclk_12m_enable(void)
2393 + unsigned long data;
2395 + MSG("Enable SoC MCLK 12Mhz\n");
2397 +#if defined(CONFIG_RALINK_RT6855A)
2398 + data = i2s_inw(RALINK_SYSCTL_BASE+0x860);
2399 + data |= (0x1<<17);
2400 + data &= ~(0x7<<18);
2401 + data |= (0x1<<18);
2402 + i2s_outw(RALINK_SYSCTL_BASE+0x860, data);
2403 +#elif defined(CONFIG_RALINK_RT3350)
2404 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2406 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2407 +#elif defined(CONFIG_RALINK_RT3883)
2408 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2409 + data &= ~(0x03<<13);
2410 + data |= (0x1<<13);
2411 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2412 +#elif defined(CONFIG_RALINK_RT3352)||defined(CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855)
2413 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2414 + data &= ~(0x0F<<8);
2416 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2417 +#elif defined(CONFIG_RALINK_MT7620)
2418 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2419 + data &= ~(0x07<<9);
2421 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2422 +#elif defined(CONFIG_RALINK_MT7621)
2423 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2424 + data &= ~(0x1f<<18);
2425 + data |= REGBIT(0x19, 18);
2426 + data &= ~(0x1f<<12);
2427 + data |= REGBIT(0x1, 12);
2428 + data &= ~(0x7<<9);
2429 + data |= REGBIT(0x5, 9);
2430 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2431 +#elif defined(CONFIG_RALINK_MT7628)
2432 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2433 + MSG("turn on REFCLK output for MCLK1\n");
2434 + data &= ~(0x7<<9);
2435 + data |= (0x1<<9); /* output for MCLK */
2436 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2438 + #error "This SoC does not provide 12MHz clock to audio codec\n");
2440 + i2s_refclk_gpio_out_config();
2446 +#if defined(CONFIG_I2S_MCLK_12P288MHZ)
2447 +int i2s_refclk_12p288m_enable(void)
2449 + unsigned long data;
2450 + MSG("Enable SoC MCLK 12.288Mhz\n");
2452 +#if defined(CONFIG_RALINK_RT3352)||defined(CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855)
2453 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2454 + data &= ~(0x01F<<18);
2456 + data &= ~(0x01F<<12);
2459 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2460 +#elif defined(CONFIG_RALINK_MT7621)
2461 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2462 + data &= ~(0x1f<<18);
2463 + data |= REGBIT(0xc, 18);
2464 + data &= ~(0x1f<<12);
2465 + data |= REGBIT(0x1, 12);
2466 + data &= ~(0x7<<9);
2467 + data |= REGBIT(0x5, 9);
2468 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2469 + _printk("MT7621 provide REFCLK 12.288MHz/11.289MHz\n");
2470 +#elif defined(CONFIG_ARCH_MT7623)
2471 + /* MT7623 does not need to set divider for REFCLK */
2472 + /* GPIO126 - I2S0_MCLK */
2473 + data = i2s_inw(0xF00058F0);
2474 + data &= ~(0x7<<3);
2476 + i2s_outw(0xF00058F0, data);
2477 + /* GPIO_DIR8: OUT */
2478 + data = i2s_inw(0xF0005070);
2479 + data |= (0x1<<14);
2480 + i2s_outw(0xF0005070, data);
2482 + #error "This SoC does not provide 12.288Mhz clock to audio codec\n");
2489 +#if defined(CONFIG_I2S_MCLK_18P432MHZ)
2490 +int i2s_refclk_18p432m_enable(unsigned long index)
2492 + unsigned long data;
2493 + MSG("Enable SoC MCLK 18.432MHz/16.934MHz");
2495 + if((index==1)|(index==4)|(index==7)|(index==9))// 16.934MHz for 22.05K, 44.1K, 88.2K, 176.4K
2497 + data = i2s_inw(ETHDMASYS_SYSCTL_BASE+0x2c);
2498 + data &= ~(0x1<<7);
2499 + i2s_outw(ETHDMASYS_SYSCTL_BASE+0x2c, data);
2501 + else if((index==0)|(index==3)|(index==5)|(index==6)|(index==8)|(index==10))// 18.432MHZ for 24K, 48K, 96K, 192K
2503 + data = i2s_inw(ETHDMASYS_SYSCTL_BASE+0x2c);
2505 + i2s_outw(ETHDMASYS_SYSCTL_BASE+0x2c, data);
2508 + data = i2s_inw(ETHDMASYS_SYSCTL_BASE+0x30);
2509 + data |= (0x1<<17);
2510 + i2s_outw(ETHDMASYS_SYSCTL_BASE+0x30, data);
2517 +int i2s_refclk_disable(void)
2519 + unsigned long data;
2521 +#if defined(CONFIG_RALINK_RT6855A)
2522 + data = i2s_inw(RALINK_SYSCTL_BASE+0x860);
2524 + i2s_outw(RALINK_SYSCTL_BASE+0x860, data);
2525 +#elif defined(CONFIG_RALINK_RT3350)
2526 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2527 + data &= ~(0x1<<8);
2528 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2529 +#elif defined(CONFIG_RALINK_RT3883)
2530 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2531 + data &= ~(0x0F<<13);
2532 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2533 +#elif defined(CONFIG_RALINK_RT3352)||defined(CONFIG_RALINK_RT5350)||defined (CONFIG_RALINK_RT6855)
2534 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2535 + data &= ~(0x0F<<8);
2536 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2537 +#elif defined (CONFIG_RALINK_MT7620)||defined (CONFIG_RALINK_MT7621)||defined (CONFIG_RALINK_MT7628)
2538 + _printk("turn off REFCLK output from internal CLK\n");
2539 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2540 + data &= ~(0x07<<9);
2541 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2542 +#elif defined (CONFIG_ARCH_MT7623) /*FIXME:2*/
2543 +#ifdef MT7623_ASIC_BOARD
2544 + _printk("turn off REFCLK output from internal CLK\n");
2545 + /* GPIO126 - I2S0_MCLK */
2546 + data = i2s_inw(0xF00058F0);
2547 + data &= ~(0x7<<3);
2548 + //data |= (0x2<<3);
2549 + i2s_outw(0xF00058F0, data);
2550 + /* GPIO126 => GPIO_DIR8: IN */
2551 + data = i2s_inw(0xF0005070);
2552 + data &= ~(0x1<<14);
2553 + i2s_outw(0xF0005070, data);
2555 + _printk("turn off REFCLK output from internal CLK\n");
2556 + data = i2s_inw(ETHDMASYS_SYSCTL_BASE+0x30);
2557 + data &= ~(0x1<<17);
2558 + i2s_outw(ETHDMASYS_SYSCTL_BASE+0x30, data);
2564 +int i2s_refclk_gpio_out_config(void)
2566 +#ifndef CONFIG_ARCH_MT7623
2567 + unsigned long data; /* FIXME */
2570 + /* Set REFCLK GPIO pin as REFCLK mode*/
2571 +#if defined(CONFIG_RALINK_MT7620)
2572 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2573 + data &= ~(0x03<<21); /* WDT */
2575 + //data &= ~(0x03<<16); /* PERST */
2576 + //data |= (1<<16);
2577 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2579 +#if defined(CONFIG_RALINK_MT7621)
2580 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2581 + //data &= ~(0x3<<10); /* PERST */
2582 + //data |= (0x2<<10);
2583 + data &= ~(0x3<<8); /* WDT */
2585 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2586 + MSG("Set 0x60 register\n");
2588 +#if defined(CONFIG_RALINK_MT7628)
2589 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2590 + data &= ~(0x1<<18);
2591 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2597 +int i2s_refclk_gpio_in_config(void)
2599 +#ifndef CONFIG_ARCH_MT7623
2600 + unsigned long data; /* FIXME */
2603 +#if defined (CONFIG_RALINK_MT7620)
2604 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2605 + data &= ~(0x03<<21); /* WDT */
2607 + //data &= ~(0x03<<16); /* PERST */
2608 + //data |= (1<<16);
2609 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2611 + data = i2s_inw(RALINK_PIO_BASE);
2612 + data &= ~(0x1<<17); /* GPIO share ping 17 for WDT */
2613 + i2s_outw(RALINK_PIO_BASE, data);
2615 + //data = i2s_inw(RALINK_PIO_BASE+0x04);
2616 + //data &= ~(0x1<<4); /* GPIO share ping 36 for PERST */
2617 + //i2s_outw(RALINK_PIO_BASE+0x04, data);
2619 +#if defined (CONFIG_RALINK_MT7621)
2620 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2621 + //data &= ~(0x3<<10); /* PERST */
2622 + //data |= (0x1<<10);
2623 + data &= ~(0x3<<8); /* WDT */
2625 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2627 + data = i2s_inw(RALINK_PIO_BASE);
2628 + //data &= ~(0x1<<19); /* GPIO share ping 19 for RERST */
2629 + data &= ~(0x1<<18); /* GPIO share ping 18 for WDT */
2630 + i2s_outw(RALINK_PIO_BASE, data);
2632 +#if defined (CONFIG_RALINK_MT7628)
2633 + /* To use external OSC, set REFCLK_GPIO ping as GPIO mode and set it as input direction */
2634 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2635 + data |= (0x1<<18);
2636 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2638 + data = i2s_inw(RALINK_PIO_BASE+0x04);
2639 + data &= ~(0x1<<5); /* GPIO share ping 37*/
2640 + i2s_outw(RALINK_PIO_BASE+0x04, data);
2646 +int i2s_slave_clock_gpio_in_mt7623(void)
2648 + unsigned long data;
2650 + /* GPIO74(I2S0_BCLK)=>GPIO_DIR5: IN */
2651 + data = i2s_inw(0xF0005040);
2652 + data &= ~(0x1<<10);
2653 + i2s_outw(0xF0005040, data);
2655 + /* GPIO73(I2S0_LRCK)=>GPIO_DIR5: IN */
2656 + data = i2s_inw(0xF0005040);
2657 + data &= ~(0x1<<9);
2658 + i2s_outw(0xF0005040, data);
2660 + _printk("i2s_slave_clock_gpio_in_mt7623\n");
2665 +int i2s_master_clock_gpio_out_mt7623(void)
2667 + unsigned long data;
2669 + /* GPIO74(I2S0_BCLK)=>GPIO_DIR5: OUT */
2670 + data = i2s_inw(0xF0005040);
2671 + data |= (0x1<<10);
2672 + i2s_outw(0xF0005040, data);
2674 + /* GPIO73(I2S0_LRCK)=>GPIO_DIR5: OUT */
2675 + data = i2s_inw(0xF0005040);
2677 + i2s_outw(0xF0005040, data);
2679 + _printk("i2s_master_clock_gpio_out_mt7623\n");
2684 +int i2s_share_pin_mt7623(i2s_config_type* ptri2s_config)
2686 + unsigned long data;
2688 + _printk("\nConfig MT7623 I2S pinmux\n");
2689 + /* GPIO74 - I2S0_BCLK */
2690 + data = i2s_inw(0xF0005840);
2691 + data &= ~(0x7<<12);
2692 + data |= (0x6<<12);
2693 + i2s_outw(0xF0005840, data);
2695 + /* GPIO73 - I2S0_LRCK */
2696 + data = i2s_inw(0xF0005840);
2697 + data &= ~(0x7<<9);
2699 + i2s_outw(0xF0005840, data);
2701 + if(ptri2s_config->slave_en==0)
2702 + i2s_master_clock_gpio_out_mt7623();
2704 + i2s_slave_clock_gpio_in_mt7623();
2706 + /* GPIO49 - I2S0_DATA */
2707 + data = i2s_inw(0xF00057F0);
2708 + data &= ~(0x7<<12);
2709 + data |= (0x6<<12);
2710 + i2s_outw(0xF00057F0, data);
2711 + /* GPIO_DIR4: OUT */
2712 + data = i2s_inw(0xF0005030);
2714 + i2s_outw(0xF0005030, data);
2716 + /* GPIO72 - I2S0_DATA_IN */
2717 + data = i2s_inw(0xF0005840);
2718 + data &= ~(0x7<<6);
2720 + i2s_outw(0xF0005840, data);
2721 + /* GPIO_DIR5: IN */
2722 + data = i2s_inw(0xF0005040);
2723 + data &= ~(0x1<<8);
2724 + i2s_outw(0xF0005040, data);
2729 +int i2s_share_pin_config(i2s_config_type* ptri2s_config)
2731 +#ifndef CONFIG_ARCH_MT7623
2732 + unsigned long data; /*FIXME*/
2735 + /* set share pins to i2s/gpio mode and i2c mode */
2736 +#if defined(CONFIG_RALINK_RT6855A)
2737 + data = i2s_inw(RALINK_SYSCTL_BASE+0x860);
2738 + data |= 0x00008080;
2739 + i2s_outw(RALINK_SYSCTL_BASE+0x860, data);
2740 +#elif defined(CONFIG_RALINK_MT7621)
2741 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2742 + data &= 0xFFFFFFE3;
2743 + data |= 0x00000010;
2744 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2745 +#elif defined(CONFIG_RALINK_MT7628)
2746 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2747 + data &= ~(0x3<<6); /* I2S_MODE */
2748 + data &= ~(0x3<<20); /* I2C_MODE */
2749 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2750 +#elif defined(CONFIG_ARCH_MT7623)
2751 + i2s_share_pin_mt7623(ptri2s_config);
2753 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2754 + data &= 0xFFFFFFE2;
2755 + data |= 0x00000018;
2756 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2761 +int i2s_ws_config(i2s_config_type* ptri2s_config, unsigned long index)
2763 + unsigned long data;
2764 + unsigned long* pTable;
2766 +#if defined(CONFIG_I2S_IN_CLK)
2767 + /* REFCLK is 15.625Mhz or 40Mhz(fractional division) */
2768 +#if defined(CONFIG_I2S_FRAC_DIV)
2769 + MSG("Internal REFCLK with fractional division\n");
2770 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
2771 + if (ptri2s_config->wordlen_24b == 1)
2773 + MSG("24 bit int table\n");
2774 + pTable = i2s_inclk_int_24bit;
2778 + MSG("16 bit int table\n");
2779 + pTable = i2s_inclk_int_16bit;
2782 + pTable = i2s_inclk_int;
2783 +#endif /* CONFIG_RALINK_MT7628 */
2785 + data = (unsigned long)(pTable[index]);
2786 + i2s_outw(I2S_DIVINT_CFG, data);
2788 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
2789 + if (ptri2s_config->wordlen_24b == 1)
2791 + MSG("24 bit comp table\n");
2792 + pTable = i2s_inclk_comp_24bit;
2796 + MSG("16 bit comp table\n");
2797 + pTable = i2s_inclk_comp_16bit;
2800 + pTable = i2s_inclk_comp;
2801 +#endif /* CONFIG_RALINK_MT7628 */
2803 + data = (unsigned long)(pTable[index]);
2804 + data |= REGBIT(1, I2S_CLKDIV_EN);
2805 + i2s_outw(I2S_DIVCOMP_CFG, data);
2807 + MSG("Internal REFCLK 15.625Mhz \n");
2808 + pTable = i2s_inclk_15p625Mhz;
2809 + data = i2s_inw(RALINK_SYSCTL_BASE+0x30);
2810 + data &= 0xFFFF00FF;
2811 + data |= (unsigned long)(pTable[index]);
2812 + data |= 0x00008000;
2813 + i2s_outw(RALINK_SYSCTL_BASE+0x30, data);
2814 +#endif /* CONFIG_I2S_FRAC_DIV */
2816 +#if defined(CONFIG_I2S_MCLK_12MHZ)
2817 + /* REFCLK = MCLK = 12Mhz */
2818 + MSG("External REFCLK 12Mhz \n");
2819 + pTable = i2s_exclk_12Mhz;
2820 + data = i2s_inw(RALINK_SYSCTL_BASE+0x30);
2821 + data &= 0xFFFF00FF;
2822 + data |= (unsigned long)(pTable[index]);
2823 + data |= 0x0000C000;
2824 + i2s_outw(RALINK_SYSCTL_BASE+0x30, data);
2826 + /* REFCLK = MCLK = 12.288Mhz */
2827 + pTable = i2s_exclk_12p288Mhz;
2828 + MSG("External REFCLK 12.288Mhz \n");
2829 + data = i2s_inw(RALINK_SYSCTL_BASE+0x30);
2830 + data &= 0xFFFF00FF;
2831 + data |= (unsigned long)(pTable[index]);
2832 + data |= 0x0000C000;
2833 + i2s_outw(RALINK_SYSCTL_BASE+0x30, data);
2834 +#endif /* CONFIG_I2S_MCLK_12MHZ */
2835 +#endif /* Not CONFIG_I2S_IN_CLK */
2837 +#if defined(CONFIG_I2S_WS_EDGE)
2838 + data = i2s_inw(I2S_I2SCFG);
2839 + data |= REGBIT(0x1, I2S_WS_INV);
2840 + i2s_outw(I2S_I2SCFG, data);
2846 +int i2s_mode_config(u32 slave_en)
2848 + unsigned long data;
2853 + _printk("This SoC is in Master mode\n");
2854 +#if defined(CONFIG_RALINK_RT3052)
2855 + data = i2s_inw(I2S_I2SCFG);
2856 + data &= ~REGBIT(0x1, I2S_SLAVE_EN);
2857 + data &= ~REGBIT(0x1, I2S_CLK_OUT_DIS);
2858 + i2s_outw(I2S_I2SCFG, data);
2859 +#elif defined(CONFIG_RALINK_RT3883)||defined(CONFIG_RALINK_RT3352)||\
2860 + defined(CONFIG_RALINK_RT5350)||defined(CONFIG_RALINK_RT6855)||\
2861 + defined(CONFIG_RALINK_MT7620)||defined(CONFIG_RALINK_RT6855A)||\
2862 + defined(CONFIG_RALINK_MT7621)||defined(CONFIG_RALINK_MT7628)||\
2863 + defined(CONFIG_ARCH_MT7623)
2864 + data = i2s_inw(I2S_I2SCFG);
2865 + data &= ~REGBIT(0x1, I2S_SLAVE_MODE);
2866 + i2s_outw(I2S_I2SCFG, data);
2868 + #error "a strange clock mode"
2874 + _printk("This SoC is in Slave mode\n");
2875 +#if defined(CONFIG_RALINK_RT3052)
2876 + data = i2s_inw(I2S_I2SCFG);
2877 + data |= REGBIT(0x1, I2S_SLAVE_EN);
2878 + data |= REGBIT(0x1, I2S_CLK_OUT_DIS);
2879 + i2s_outw(I2S_I2SCFG, data);
2880 +#elif defined(CONFIG_RALINK_RT3883)||defined(CONFIG_RALINK_RT3352)||\
2881 + defined(CONFIG_RALINK_RT5350)||defined(CONFIG_RALINK_RT6855)||\
2882 + defined(CONFIG_RALINK_MT7620)||defined(CONFIG_RALINK_RT6855A)||\
2883 + defined(CONFIG_RALINK_MT7621)||defined(CONFIG_RALINK_MT7628)||\
2884 + defined(CONFIG_ARCH_MT7623)
2885 + data = i2s_inw(I2S_I2SCFG);
2886 + data |= REGBIT(0x1, I2S_SLAVE_MODE);
2887 + i2s_outw(I2S_I2SCFG, data);
2889 + #error "a strange clock mode "
2896 +int i2s_codec_frequency_config(i2s_config_type* ptri2s_config, unsigned long index)
2898 +#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
2899 + unsigned long data;
2900 + unsigned long* pTable;
2903 +#if defined(CONFIG_I2S_MCLK_12MHZ)
2904 +#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
2905 + pTable = i2s_codec_12Mhz;
2906 + data = pTable[index];
2908 +#if defined(CONFIG_I2S_WM8960)
2909 + audiohw_set_frequency(data, ptri2s_config->codec_pll_en);
2910 +#elif defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
2911 + audiohw_set_frequency(data|0x01);
2914 +#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
2915 +#if defined(MT7623_FPGA_BOARD) && defined(CONFIG_I2S_WM8750)
2916 + pTable = i2s_codec_18p432Mhz;
2918 + pTable = i2s_codec_12p288Mhz;
2920 + data = pTable[index];
2922 +#if defined(CONFIG_I2S_WM8960)
2923 + audiohw_set_frequency(data, ptri2s_config->codec_pll_en);
2924 +#elif defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
2925 + audiohw_set_frequency(data);
2932 + * Ralink Audio System Clock Enable
2934 + * I2S_WS : signal direction opposite to/same as I2S_CLK
2936 + * I2S_CLK : Integer division or fractional division
2937 + * REFCLK from Internal or External (external REFCLK not support for fractional division)
2938 + * Suppose external REFCLK always be the same as external MCLK
2940 + * MCLK : External OSC or internal generation
2943 +int i2s_clock_enable(i2s_config_type* ptri2s_config)
2945 + unsigned long index;
2946 + /* audio sampling rate decision */
2947 + switch(ptri2s_config->srate)
2982 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
2993 +#ifdef MT7621_ASIC_BOARD
2994 + /* Set pll config */
2995 + i2s_pll_config_mt7621(index);
2997 +#ifdef MT7623_ASIC_BOARD
2998 + /* Set pll config */
2999 + i2s_pll_config_mt7623(index);
3002 + /* enable internal MCLK */
3003 +#if defined(CONFIG_I2S_IN_MCLK)
3004 +#if defined(CONFIG_RALINK_MT7621)
3005 + i2s_pll_refclk_set();
3007 +#if defined(CONFIG_I2S_MCLK_12MHZ)
3008 +#if defined(MT7628_ASIC_BOARD) || defined(CONFIG_ARCH_MT7623)
3009 + i2s_driving_strength_adjust();
3011 + i2s_refclk_12m_enable();
3012 +#endif /* MCLK_12MHZ */
3013 +#if defined(CONFIG_I2S_MCLK_12P288MHZ)
3014 + i2s_refclk_12p288m_enable();
3015 +#endif /* MCLK_12P288MHZ */
3016 +#if defined(CONFIG_I2S_MCLK_18P432MHZ)
3017 + i2s_refclk_18p432m_enable(index);
3019 + i2s_refclk_gpio_out_config();
3022 + MSG("Disable SoC MCLK, use external OSC\n");
3023 + i2s_refclk_disable();
3024 + i2s_refclk_gpio_in_config();
3025 +#endif /* CONFIG_I2S_IN_MCLK */
3027 + i2s_share_pin_config(ptri2s_config);
3029 + if(ptri2s_config->slave_en==0)
3031 + /* Setup I2S_WS and I2S_CLK */
3032 + i2s_ws_config(ptri2s_config, index);
3035 + i2s_mode_config(ptri2s_config->slave_en);
3037 + if(!ptri2s_config->bALSAEnable)
3039 +#if defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)|| defined(CONFIG_I2S_WM8960)
3040 + i2s_codec_enable(ptri2s_config);
3042 + i2s_codec_frequency_config(ptri2s_config,index);
3048 +int i2s_clock_disable(i2s_config_type* ptri2s_config)
3050 + if(!ptri2s_config->bALSAEnable)
3052 +#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
3053 + i2s_codec_disable(ptri2s_config);
3057 + /* disable internal MCLK */
3058 +#if defined(CONFIG_I2S_IN_MCLK)
3059 + i2s_refclk_disable();
3060 + i2s_refclk_gpio_in_config();
3066 +int i2s_codec_enable(i2s_config_type* ptri2s_config)
3069 + int AIn = 0, AOut = 0;
3071 +#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
3072 + /* Codec initialization */
3073 + audiohw_preinit();
3077 +#if defined(CONFIG_I2S_WM8960)
3078 + if(ptri2s_config->codec_pll_en)
3080 + MSG("Codec PLL EN = %d\n", pi2s_config->codec_pll_en);
3081 + audiohw_set_apll(ptri2s_config->srate);
3085 +#if defined(CONFIG_I2S_TXRX)
3086 + if((ptri2s_config->bTxDMAEnable) || (ptri2s_config->txrx_coexist))
3088 + if((ptri2s_config->bRxDMAEnable) || (ptri2s_config->txrx_coexist))
3090 +#if defined(CONFIG_I2S_WM8960)
3091 + audiohw_postinit(!(ptri2s_config->slave_en), AIn, AOut, ptri2s_config->codec_pll_en, ptri2s_config->wordlen_24b);
3092 + audiohw_micboost(ptri2s_config->micboost);
3093 + audiohw_micin(ptri2s_config->micin);
3094 +#elif defined(CONFIG_I2S_WM8750)
3095 + audiohw_postinit(!(ptri2s_config->slave_en), AIn, AOut, ptri2s_config->wordlen_24b);
3097 + MSG("AOut=%d, AIn=%d\n", AOut, AIn);
3099 +#if defined(CONFIG_I2S_WM8750)
3100 + audiohw_postinit(!(ptri2s_config->slave_en), 0, 1);
3101 +#elif defined(CONFIG_I2S_WM8960)
3102 + audiohw_postinit(!(ptri2s_config->slave_en), 1, 1, ptri2s_config->codec_pll_en);
3103 +#elif defined(CONFIG_I2S_WM8751)
3104 + if(ptri2s_config->slave_en==0)
3105 + audiohw_postinit(1,1);
3107 + audiohw_postinit(0,1);
3113 +int i2s_codec_disable(i2s_config_type* ptri2s_config)
3115 +#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
3121 +int i2s_reset_config(i2s_config_type* ptri2s_config)
3123 + unsigned long data;
3125 + /* RESET bit: write 1 clear */
3126 +#if defined(CONFIG_RALINK_RT6855A)
3127 + data = i2s_inw(RALINK_SYSCTL_BASE+0x834);
3129 + i2s_outw(RALINK_SYSCTL_BASE+0x834, data);
3131 + data = i2s_inw(RALINK_SYSCTL_BASE+0x834);
3133 + i2s_outw(RALINK_SYSCTL_BASE+0x834, data);
3134 +#elif defined(CONFIG_ARCH_MT7623)
3135 + data = i2s_inw(0xFB000000+0x34);
3137 + i2s_outw(0xFB000000+0x34, data);
3139 + data = i2s_inw(0xFB000000+0x34);
3141 + i2s_outw(0xFB000000+0x34, data);
3143 + data = i2s_inw(RALINK_SYSCTL_BASE+0x34);
3145 + i2s_outw(RALINK_SYSCTL_BASE+0x34, data);
3147 + data = i2s_inw(RALINK_SYSCTL_BASE+0x34);
3149 + i2s_outw(RALINK_SYSCTL_BASE+0x34, data);
3151 +#if 0 /* Reset GDMA */
3152 + data = i2s_inw(RALINK_SYSCTL_BASE+0x34);
3154 + i2s_outw(RALINK_SYSCTL_BASE+0x34, data);
3156 + data = i2s_inw(RALINK_SYSCTL_BASE+0x34);
3158 + i2s_outw(RALINK_SYSCTL_BASE+0x34, data);
3161 + _printk("I2S reset complete!!\n");
3165 +int i2s_tx_config(i2s_config_type* ptri2s_config)
3167 + unsigned long data;
3168 + /* set I2S_I2SCFG */
3169 + data = i2s_inw(I2S_I2SCFG);
3170 + data &= 0xFFFFFF81;
3171 + data |= REGBIT(ptri2s_config->tx_ff_thres, I2S_TX_FF_THRES);
3172 + data |= REGBIT(ptri2s_config->tx_ch_swap, I2S_TX_CH_SWAP);
3173 +#if defined(CONFIG_RALINK_RT6855A)
3174 + data |= REGBIT(1, I2S_BYTE_SWAP);
3176 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
3177 + MSG("TX:wordLen=%d, sysEndian=%d\n", ptri2s_config->wordlen_24b, ptri2s_config->sys_endian);
3178 + data |= REGBIT(ptri2s_config->wordlen_24b, I2S_DATA_24BIT);
3179 + data |= REGBIT(ptri2s_config->sys_endian, I2S_SYS_ENDIAN);
3180 + data |= REGBIT(ptri2s_config->little_edn, I2S_LITTLE_ENDIAN);
3182 + data &= ~REGBIT(1, I2S_TX_CH0_OFF);
3183 + data &= ~REGBIT(1, I2S_TX_CH1_OFF);
3184 + i2s_outw(I2S_I2SCFG, data);
3186 + /* set I2S_I2SCFG1 */
3187 + MSG("internal loopback: %d\n", ptri2s_config->lbk);
3188 + data = i2s_inw(I2S_I2SCFG1);
3189 + data |= REGBIT(ptri2s_config->lbk, I2S_LBK_EN);
3190 + data |= REGBIT(ptri2s_config->extlbk, I2S_EXT_LBK_EN);
3191 + data &= 0xFFFFFFFC;
3192 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
3193 + data |= REGBIT(ptri2s_config->fmt, I2S_DATA_FMT);
3195 + i2s_outw(I2S_I2SCFG1, data);
3200 +int i2s_rx_config(i2s_config_type* ptri2s_config)
3202 + unsigned long data;
3203 + /* set I2S_I2SCFG */
3204 + data = i2s_inw(I2S_I2SCFG);
3205 + data &= 0xFFFF81FF;
3206 + data |= REGBIT(ptri2s_config->rx_ff_thres, I2S_RX_FF_THRES);
3207 + data |= REGBIT(ptri2s_config->rx_ch_swap, I2S_RX_CH_SWAP);
3208 + data &= ~REGBIT(1, I2S_RX_CH0_OFF);
3209 + data &= ~REGBIT(1, I2S_RX_CH1_OFF);
3210 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
3211 + MSG("RX:wordLen=%d, sysEndian=%d\n", ptri2s_config->wordlen_24b, ptri2s_config->sys_endian);
3212 + data |= REGBIT(ptri2s_config->wordlen_24b, I2S_DATA_24BIT);
3213 + data |= REGBIT(ptri2s_config->sys_endian, I2S_SYS_ENDIAN);
3214 + data |= REGBIT(ptri2s_config->little_edn, I2S_LITTLE_ENDIAN);
3216 + i2s_outw(I2S_I2SCFG, data);
3218 + /* set I2S_I2SCFG1 */
3219 + data = i2s_inw(I2S_I2SCFG1);
3220 + data |= REGBIT(ptri2s_config->lbk, I2S_LBK_EN);
3221 + data |= REGBIT(ptri2s_config->extlbk, I2S_EXT_LBK_EN);
3222 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
3223 + data &= 0xFFFFFFFC;
3224 + data |= REGBIT(ptri2s_config->fmt, I2S_DATA_FMT);
3226 + i2s_outw(I2S_I2SCFG1, data);
3231 +/* Turn On Tx DMA and INT */
3232 +int i2s_tx_enable(i2s_config_type* ptri2s_config)
3234 + unsigned long data;
3236 +#if defined(I2S_HW_INTERRUPT_EN)
3237 + data = i2s_inw(I2S_INT_EN);
3238 + data |= REGBIT(0x1, I2S_TX_INT3_EN); /* FIFO DMA fault */
3239 + data |= REGBIT(0x1, I2S_TX_INT2_EN); /* FIFO overrun */
3240 + data |= REGBIT(0x1, I2S_TX_INT1_EN); /* FIFO underrun */
3241 + data |= REGBIT(0x1, I2S_TX_INT0_EN); /* FIFO below threshold */
3242 + i2s_outw(I2S_INT_EN, data);
3245 + data = i2s_inw(I2S_I2SCFG);
3246 +#if defined(CONFIG_I2S_TXRX)
3247 + data |= REGBIT(0x1, I2S_TX_EN);
3249 + data |= REGBIT(0x1, I2S_DMA_EN);
3250 + i2s_outw(I2S_I2SCFG, data);
3252 + data = i2s_inw(I2S_I2SCFG);
3253 + data |= REGBIT(0x1, I2S_EN);
3254 + i2s_outw(I2S_I2SCFG, data);
3256 + MSG("i2s_tx_enable done\n");
3260 +/* Turn On Rx DMA and INT */
3261 +int i2s_rx_enable(i2s_config_type* ptri2s_config)
3263 + unsigned long data;
3265 +#if defined(I2S_HW_INTERRUPT_EN)
3266 + data = i2s_inw(I2S_INT_EN);
3267 + data |= REGBIT(0x1, I2S_RX_INT3_EN); /* FIFO DMA fault */
3268 + data |= REGBIT(0x1, I2S_RX_INT2_EN); /* FIFO overrun */
3269 + data |= REGBIT(0x1, I2S_RX_INT1_EN); /* FIFO underrun */
3270 + data |= REGBIT(0x1, I2S_RX_INT0_EN); /* FIFO below threshold */
3271 + i2s_outw(I2S_INT_EN, data);
3274 + data = i2s_inw(I2S_I2SCFG);
3275 +#if defined(CONFIG_I2S_TXRX)
3276 + data |= REGBIT(0x1, I2S_RX_EN);
3278 + data |= REGBIT(0x1, I2S_DMA_EN);
3279 + i2s_outw(I2S_I2SCFG, data);
3281 + data = i2s_inw(I2S_I2SCFG);
3282 + data |= REGBIT(0x1, I2S_EN);
3283 + i2s_outw(I2S_I2SCFG, data);
3285 + MSG("i2s_rx_enable done\n");
3288 +/* Turn Off Tx DMA and INT */
3289 +int i2s_tx_disable(i2s_config_type* ptri2s_config)
3291 + unsigned long data;
3293 +#if defined(I2S_HW_INTERRUPT_EN)
3294 + data = i2s_inw(I2S_INT_EN);
3295 + data &= ~REGBIT(0x1, I2S_TX_INT3_EN);
3296 + data &= ~REGBIT(0x1, I2S_TX_INT2_EN);
3297 + data &= ~REGBIT(0x1, I2S_TX_INT1_EN);
3298 + data &= ~REGBIT(0x1, I2S_TX_INT0_EN);
3299 + i2s_outw(I2S_INT_EN, data);
3302 + data = i2s_inw(I2S_I2SCFG);
3303 +#if defined(CONFIG_I2S_TXRX)
3304 + data &= ~REGBIT(0x1, I2S_TX_EN);
3306 + if(ptri2s_config->bRxDMAEnable==0)
3308 + ptri2s_config->bTxDMAEnable = 0;
3309 + data &= ~REGBIT(0x1, I2S_DMA_EN);
3310 + data &= ~REGBIT(0x1, I2S_EN);
3312 + i2s_outw(I2S_I2SCFG, data);
3315 +/* Turn Off Rx DMA and INT */
3316 +int i2s_rx_disable(i2s_config_type* ptri2s_config)
3318 + unsigned long data;
3320 +#if defined(I2S_HW_INTERRUPT_EN)
3321 + data = i2s_inw(I2S_INT_EN);
3322 + data &= ~REGBIT(0x1, I2S_RX_INT3_EN);
3323 + data &= ~REGBIT(0x1, I2S_RX_INT2_EN);
3324 + data &= ~REGBIT(0x1, I2S_RX_INT1_EN);
3325 + data &= ~REGBIT(0x1, I2S_RX_INT0_EN);
3326 + i2s_outw(I2S_INT_EN, data);
3329 + data = i2s_inw(I2S_I2SCFG);
3330 +#if defined(CONFIG_I2S_TXRX)
3331 + data &= ~REGBIT(0x1, I2S_RX_EN);
3333 + if(ptri2s_config->bTxDMAEnable==0)
3335 + ptri2s_config->bRxDMAEnable = 0;
3336 + data &= ~REGBIT(0x1, I2S_DMA_EN);
3337 + data &= ~REGBIT(0x1, I2S_EN);
3339 + i2s_outw(I2S_I2SCFG, data);
3343 +int i2s_dma_tx_transf_data(i2s_config_type* ptri2s_config, u32 dma_ch)
3347 + if ((pi2s_config->bALSAEnable==1) && (pi2s_config->bALSAMMAPEnable==1))
3348 + tx_r_idx = (pi2s_config->tx_r_idx + ALSA_MMAP_IDX_SHIFT)%MAX_I2S_PAGE;
3350 + tx_r_idx = pi2s_config->tx_r_idx;
3352 + if(dma_ch==GDMA_I2S_TX0)
3354 +#if defined(CONFIG_I2S_MMAP)
3355 + dma_sync_single_for_device(NULL, i2s_mmap_addr[tx_r_idx], I2S_PAGE_SIZE, DMA_TO_DEVICE);
3356 +#if defined(ARM_ARCH)
3357 + 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);
3359 + 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);
3362 + memcpy(pi2s_config->pPage0TxBuf8ptr, pi2s_config->pMMAPTxBufPtr[tx_r_idx], I2S_PAGE_SIZE);
3363 +#if defined(ARM_ARCH)
3364 + GdmaI2sTx(i2s_txdma_addr0, I2S_TX_FIFO_WREG_PHY, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3366 + GdmaI2sTx((u32)(pi2s_config->pPage0TxBuf8ptr), I2S_TX_FIFO_WREG, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3369 + pi2s_config->dmach = GDMA_I2S_TX0;
3370 + pi2s_config->tx_r_idx = (pi2s_config->tx_r_idx+1)%MAX_I2S_PAGE;
3374 +#if defined(CONFIG_I2S_MMAP)
3375 + dma_sync_single_for_device(NULL, i2s_mmap_addr[tx_r_idx], I2S_PAGE_SIZE, DMA_TO_DEVICE);
3376 +#if defined(ARM_ARCH)
3377 + 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);
3379 + 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);
3382 + memcpy(pi2s_config->pPage1TxBuf8ptr, pi2s_config->pMMAPTxBufPtr[tx_r_idx], I2S_PAGE_SIZE);
3383 +#if defined(ARM_ARCH)
3384 + GdmaI2sTx(i2s_txdma_addr1, I2S_TX_FIFO_WREG_PHY, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3386 + GdmaI2sTx((u32)(pi2s_config->pPage1TxBuf8ptr), I2S_TX_FIFO_WREG, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3389 + pi2s_config->dmach = GDMA_I2S_TX1;
3390 + pi2s_config->tx_r_idx = (pi2s_config->tx_r_idx+1)%MAX_I2S_PAGE;
3392 +#if defined(CONFIG_I2S_WITH_AEC)
3393 + if(aecFuncP->AECFeEnq){
3394 + aecFuncP->AECFeEnq(0,pi2s_config->pMMAPTxBufPtr[pi2s_config->tx_r_idx],I2S_PAGE_SIZE);
3400 +int i2s_dma_tx_transf_zero(i2s_config_type* ptri2s_config, u32 dma_ch)
3402 + if(dma_ch==GDMA_I2S_TX0)
3404 + memset(pi2s_config->pPage0TxBuf8ptr, 0, I2S_PAGE_SIZE);
3405 +#if defined(ARM_ARCH)
3406 + GdmaI2sTx(i2s_txdma_addr0, I2S_TX_FIFO_WREG_PHY, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3408 + GdmaI2sTx((u32)pi2s_config->pPage0TxBuf8ptr, I2S_TX_FIFO_WREG, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3413 + memset(pi2s_config->pPage1TxBuf8ptr, 0, I2S_PAGE_SIZE);
3414 +#if defined(ARM_ARCH)
3415 + GdmaI2sTx(i2s_txdma_addr1, I2S_TX_FIFO_WREG_PHY, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3417 + GdmaI2sTx((u32)pi2s_config->pPage1TxBuf8ptr, I2S_TX_FIFO_WREG, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3423 +int i2s_dma_rx_transf_data(i2s_config_type* ptri2s_config, u32 dma_ch)
3427 + pi2s_config->rx_w_idx = (pi2s_config->rx_w_idx+1)%MAX_I2S_PAGE;
3429 + if ((pi2s_config->bALSAEnable==1) && (pi2s_config->bALSAMMAPEnable==1))
3430 + rx_w_idx = (pi2s_config->rx_w_idx+ALSA_MMAP_IDX_SHIFT)%MAX_I2S_PAGE;
3432 + rx_w_idx = (pi2s_config->rx_w_idx)%MAX_I2S_PAGE;
3434 + if(dma_ch==GDMA_I2S_RX0)
3437 +#ifdef CONFIG_I2S_MMAP
3438 + 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);
3439 +#if defined(ARM_ARCH)
3440 + 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);
3442 + 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);
3445 + memcpy(pi2s_config->pMMAPRxBufPtr[rx_w_idx], pi2s_config->pPage0RxBuf8ptr, I2S_PAGE_SIZE);
3446 +#if defined(ARM_ARCH)
3447 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr0, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3449 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)(pi2s_config->pPage0RxBuf8ptr), 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3452 + pi2s_config->dmach = GDMA_I2S_RX0;
3457 +#ifdef CONFIG_I2S_MMAP
3458 + 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);
3459 +#if defined(ARM_ARCH)
3460 + 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);
3462 + 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);
3465 + memcpy(pi2s_config->pMMAPRxBufPtr[rx_w_idx], pi2s_config->pPage1RxBuf8ptr, I2S_PAGE_SIZE);
3466 +#if defined(ARM_ARCH)
3467 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr1, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3469 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)(pi2s_config->pPage1RxBuf8ptr), 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3472 + pi2s_config->dmach = GDMA_I2S_RX1;
3475 +#if defined(CONFIG_I2S_WITH_AEC)
3476 + if(aecFuncP->AECNeEnq){
3477 + aecFuncP->AECNeEnq(0,pi2s_config->pMMAPRxBufPtr[rx_w_idx],I2S_PAGE_SIZE);
3483 +int i2s_dma_rx_transf_zero(i2s_config_type* ptri2s_config, u32 dma_ch)
3485 + if(dma_ch==GDMA_I2S_RX0)
3487 + memset(pi2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE);
3488 +#if defined(ARM_ARCH)
3489 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr0, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3491 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)pi2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3496 + memset(pi2s_config->pPage1RxBuf8ptr, 0, I2S_PAGE_SIZE);
3497 +#if defined(ARM_ARCH)
3498 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr1, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3500 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)pi2s_config->pPage1RxBuf8ptr, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3506 +void i2s_dma_tx_handler(u32 dma_ch)
3508 + pi2s_config->enLable = 1; /* TX:enLabel=1; RX:enLabel=2 */
3510 + if(pi2s_config->bTxDMAEnable==0)
3512 + if(pi2s_config->end_cnt != 0)
3514 + i2s_dma_tx_transf_data(pi2s_config, dma_ch);
3515 + pi2s_config->end_cnt --;
3516 + MSG("end_cnt = %d, r_idx = %d\n", pi2s_config->end_cnt, pi2s_config->tx_r_idx);
3520 + pi2s_config->tx_stop_cnt++;
3521 + i2s_dma_tx_soft_stop(pi2s_config, dma_ch);
3522 + MSG("tx_stop=%d, ch=%d\n", pi2s_config->tx_stop_cnt, dma_ch);
3523 + if (pi2s_config->tx_stop_cnt == 3)
3525 + wake_up_interruptible(&(pi2s_config->i2s_tx_qh));
3526 + _printk("T:wake up!!\n");
3532 + pi2s_config->tx_isr_cnt++;
3534 +#ifdef I2S_STATISTIC
3535 + i2s_int_status(dma_ch);
3538 + if(pi2s_config->bALSAEnable)
3540 + if(pi2s_config->dmaStat[STREAM_PLAYBACK])
3542 + if(!pi2s_config->bTrigger[STREAM_PLAYBACK]){
3543 + //_printk("trigger stop: rIdx:%d widx:%d\n", pi2s_config->tx_r_idx,pi2s_config->tx_w_idx);
3544 + i2s_dma_tx_transf_zero(pi2s_config, dma_ch);
3545 + if(pi2s_config->bPreTrigger[STREAM_PLAYBACK]){
3546 + /* mtk04880 commented:
3547 + * for corner case, there are cases which ALSA Trigger stop before disabling DMA.
3548 + * For which case, it needs to keep call snd_pcm_elapased to keep ALSA hw ptr updating.
3549 + * It is so called post stop handlment.
3551 + //_printk("post-stop\n");
3555 + //_printk("pre-stop\n");
3556 + wake_up_interruptible(&(pi2s_config->i2s_tx_qh));
3561 + if(!pi2s_config->bPreTrigger[STREAM_PLAYBACK])
3562 + pi2s_config->bPreTrigger[STREAM_PLAYBACK] = 1;
3569 + if(pi2s_config->tx_r_idx==pi2s_config->tx_w_idx)
3571 + /* Buffer Empty */
3572 + 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);
3573 +#ifdef I2S_STATISTIC
3574 + pi2s_status->txbuffer_unrun++;
3576 + i2s_dma_tx_transf_zero(pi2s_config, dma_ch);
3581 + if(pi2s_config->pMMAPTxBufPtr[pi2s_config->tx_r_idx]==NULL)
3583 + MSG("mmap buf NULL [%d]\n",pi2s_config->tx_r_idx);
3584 + i2s_dma_tx_transf_zero(pi2s_config, dma_ch);
3589 + if(pi2s_config->tx_pause_en == 1)
3591 + /* Enable PAUSE */
3592 + MSG("TX pause now\n");
3593 + i2s_dma_tx_transf_zero(pi2s_config, dma_ch);
3598 +#ifdef I2S_STATISTIC
3599 + pi2s_status->txbuffer_len--;
3601 + i2s_dma_tx_transf_data(pi2s_config, dma_ch);
3604 +#if defined(CONFIG_SND_MT76XX_SOC)
3605 + if(pi2s_config->bALSAEnable == 1){
3606 + if(pi2s_config->pss[STREAM_PLAYBACK])
3607 + snd_pcm_period_elapsed(pi2s_config->pss[STREAM_PLAYBACK]);
3610 + wake_up_interruptible(&(pi2s_config->i2s_tx_qh));
3614 +void i2s_dma_rx_handler(u32 dma_ch)
3616 + pi2s_config->enLable = 2; /* TX:enLabel=1; RX:enLabel=2 */
3617 +#if defined(CONFIG_I2S_TXRX)
3618 + if(pi2s_config->rx_isr_cnt==0)
3620 + pi2s_config->next_p0_idx = 0;
3621 + pi2s_config->next_p1_idx = 1;
3623 + pi2s_config->rx_isr_cnt++;
3625 +#ifdef I2S_STATISTIC
3626 + i2s_int_status(dma_ch);
3629 + if (pi2s_config->bRxDMAEnable==0)
3631 + pi2s_config->rx_stop_cnt++;
3632 + i2s_dma_rx_soft_stop(pi2s_config, dma_ch);
3633 + MSG("rx_stop=%d\n", pi2s_config->rx_stop_cnt);
3635 + if(pi2s_config->rx_stop_cnt == 2)
3637 + wake_up_interruptible(&(pi2s_config->i2s_rx_qh));
3638 + _printk("R:wake up!!\n");
3643 + if(pi2s_config->bALSAEnable)
3645 + if(pi2s_config->dmaStat[STREAM_CAPTURE]){
3646 + if(!pi2s_config->bTrigger[STREAM_CAPTURE]){
3647 + MSG("trigger stop: rIdx:%d widx:%d\n", pi2s_config->rx_r_idx,pi2s_config->rx_w_idx);
3648 + i2s_dma_rx_transf_zero(pi2s_config, dma_ch);
3649 + wake_up_interruptible(&(pi2s_config->i2s_rx_qh));
3656 + if(((pi2s_config->rx_w_idx+1)%MAX_I2S_PAGE)==pi2s_config->rx_r_idx){
3658 + 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);
3659 +#ifdef I2S_STATISTIC
3660 + pi2s_status->rxbuffer_unrun++;
3662 + i2s_dma_rx_transf_zero(pi2s_config, dma_ch);
3667 + if(pi2s_config->rx_pause_en == 1)
3669 + /* Enable PAUSE */
3670 + i2s_dma_rx_transf_zero(pi2s_config, dma_ch);
3675 +#ifdef I2S_STATISTIC
3676 + pi2s_status->rxbuffer_len++;
3678 + i2s_dma_rx_transf_data(pi2s_config, dma_ch);
3681 +#if defined(CONFIG_SND_MT76XX_SOC)
3682 + if(pi2s_config->bALSAEnable == 1){
3683 + if(pi2s_config->pss[STREAM_CAPTURE])
3684 + snd_pcm_period_elapsed(pi2s_config->pss[STREAM_CAPTURE]);
3687 + wake_up_interruptible(&(pi2s_config->i2s_rx_qh));
3692 +#ifdef I2S_STATISTIC
3693 +void i2s_int_status(u32 dma_ch)
3697 + if((pi2s_config->tx_isr_cnt>0)||(pi2s_config->rx_isr_cnt>0))
3699 + i2s_status = i2s_inw(I2S_INT_STATUS);
3701 + if(i2s_status®BIT(1, I2S_TX_DMA_FAULT))
3703 + pi2s_status->txdmafault++;
3705 + if(i2s_status®BIT(1, I2S_TX_OVRUN))
3707 + pi2s_status->txovrun++;
3709 + if(i2s_status®BIT(1, I2S_TX_UNRUN))
3711 + pi2s_status->txunrun++;
3713 + if(i2s_status®BIT(1, I2S_TX_THRES))
3715 + pi2s_status->txthres++;
3717 + if(i2s_status®BIT(1, I2S_RX_DMA_FAULT))
3719 + pi2s_status->rxdmafault++;
3721 + if(i2s_status®BIT(1, I2S_RX_OVRUN))
3723 + pi2s_status->rxovrun++;
3725 + if(i2s_status®BIT(1, I2S_RX_UNRUN))
3727 + pi2s_status->rxunrun++;
3729 + if(i2s_status®BIT(1, I2S_RX_THRES))
3731 + pi2s_status->rxthres++;
3735 + if(pi2s_config->enLable == 1)
3737 + if((pi2s_config->tx_isr_cnt>0) && (pi2s_config->tx_isr_cnt%40==0))
3739 + MSG("tisr i=%u,ch=%u,o=%u,u=%d,s=%X [r=%d,w=%d]\n",\
3740 + pi2s_config->tx_isr_cnt,dma_ch,pi2s_status->txovrun,pi2s_status->txunrun,\
3741 + i2s_inw(I2S_INT_STATUS),pi2s_config->tx_r_idx,pi2s_config->tx_w_idx);
3745 + if(pi2s_config->enLable == 2)
3747 + if((pi2s_config->rx_isr_cnt>0) && (pi2s_config->rx_isr_cnt%40==0))
3749 + MSG("risr i=%u,ch=%u,o=%u,u=%d,s=%X [r=%d,w=%d]\n",\
3750 + pi2s_config->rx_isr_cnt,dma_ch,pi2s_status->rxovrun,pi2s_status->rxunrun,\
3751 + i2s_inw(I2S_INT_STATUS),pi2s_config->rx_r_idx,pi2s_config->rx_w_idx);
3756 + *(unsigned long*)(I2S_INT_STATUS) = 0xFFFFFFFF;
3760 +#if defined(I2S_HW_INTERRUPT_EN)&&(I2S_SW_IRQ_EN)
3761 +irqreturn_t i2s_irq_isr(int irq, void *irqaction)
3765 + //MSG("i2s_irq_isr [0x%08X]\n",i2s_inw(I2S_INT_STATUS));
3766 + if((pi2s_config->tx_isr_cnt>0)||(pi2s_config->rx_isr_cnt>0))
3768 + i2s_status = i2s_inw(I2S_INT_STATUS);
3769 + MSG("i2s_irq_isr [0x%08X]\n",i2s_status);
3772 + return IRQ_HANDLED;
3774 + if(i2s_status®BIT(1, I2S_TX_DMA_FAULT))
3776 +#ifdef I2S_STATISTIC
3777 + pi2s_status->txdmafault++;
3780 + if(i2s_status®BIT(1, I2S_TX_OVRUN))
3782 +#ifdef I2S_STATISTIC
3783 + pi2s_status->txovrun++;
3786 + if(i2s_status®BIT(1, I2S_TX_UNRUN))
3788 +#ifdef I2S_STATISTIC
3789 + pi2s_status->txunrun++;
3792 + if(i2s_status®BIT(1, I2S_TX_THRES))
3794 +#ifdef I2S_STATISTIC
3795 + pi2s_status->txthres++;
3798 + if(i2s_status®BIT(1, I2S_RX_DMA_FAULT))
3800 +#ifdef I2S_STATISTIC
3801 + pi2s_status->rxdmafault++;
3804 + if(i2s_status®BIT(1, I2S_RX_OVRUN))
3806 +#ifdef I2S_STATISTIC
3807 + pi2s_status->rxovrun++;
3810 + if(i2s_status®BIT(1, I2S_RX_UNRUN))
3812 +#ifdef I2S_STATISTIC
3813 + pi2s_status->rxunrun++;
3816 + if(i2s_status®BIT(1, I2S_RX_THRES))
3818 +#ifdef I2S_STATISTIC
3819 + pi2s_status->rxthres++;
3822 + i2s_outw(I2S_INT_STATUS, 0xFFFFFFFF);
3823 + return IRQ_HANDLED;
3827 +void i2s_tx_task(unsigned long pData)
3829 + unsigned long flags;
3830 + spin_lock_irqsave(&pi2s_config->lock, flags);
3831 + //if (pi2s_config->bTxDMAEnable!=0)
3833 + if (pi2s_config->tx_unmask_ch!=0)
3835 + u32 dmach = pi2s_config->tx_unmask_ch;
3837 + for (ch = 0; ch < 16; ch++)
3839 + if (dmach& (1<<ch))
3841 + MSG("do unmask ch%d tisr=%d in tx_isr\n",ch,pi2s_config->tx_isr_cnt);
3842 + GdmaUnMaskChannel(ch);
3845 + pi2s_config->tx_unmask_ch = 0;
3848 + spin_unlock_irqrestore(&pi2s_config->lock, flags);
3851 +void i2s_rx_task(unsigned long pData)
3853 + unsigned long flags;
3854 + spin_lock_irqsave(&pi2s_config->lock, flags);
3855 + //if (pi2s_config->bRxDMAEnable!=0)
3857 + if (pi2s_config->rx_unmask_ch!=0)
3859 + u32 dmach = pi2s_config->rx_unmask_ch;
3861 + for (ch = 0; ch < 16; ch++)
3863 + if (dmach& (1<<ch))
3865 + MSG("do unmask ch%d risr=%d in rx_isr\n",ch,pi2s_config->rx_isr_cnt);
3866 + GdmaUnMaskChannel(ch);
3869 + pi2s_config->rx_unmask_ch = 0;
3873 + spin_unlock_irqrestore(&pi2s_config->lock, flags);
3877 +void i2s_dma_unmask_handler(u32 dma_ch)
3879 + MSG("i2s_dma_unmask_handler ch=%d\n",dma_ch);
3881 + GdmaUnMaskChannel(dma_ch);
3886 +void i2s_dma_tx_unmask_handler(u32 dma_ch)
3888 + MSG("i2s_dma_tx_unmask_handler ch=%d\n",dma_ch);
3889 + pi2s_config->tx_unmask_ch |= (1<<dma_ch);
3890 + tasklet_hi_schedule(&i2s_tx_tasklet);
3894 +void i2s_dma_rx_unmask_handler(u32 dma_ch)
3896 + MSG("i2s_dma_rx_unmask_handler ch=%d\n",dma_ch);
3897 + pi2s_config->rx_unmask_ch |= (1<<dma_ch);
3898 + tasklet_hi_schedule(&i2s_rx_tasklet);
3902 +void i2s_dma_mask_handler(u32 dma_ch)
3904 + MSG("i2s_dma_mask_handler ch=%d\n", dma_ch);
3905 + GdmaMaskChannel(dma_ch);
3909 +void i2s_dma_tx_init(i2s_config_type* ptri2s_config)
3911 + memset(pi2s_config->pPage0TxBuf8ptr, 0, I2S_PAGE_SIZE);
3912 + memset(pi2s_config->pPage1TxBuf8ptr, 0, I2S_PAGE_SIZE);
3913 +#if defined(ARM_ARCH)
3914 + GdmaI2sTx(i2s_txdma_addr0, I2S_TX_FIFO_WREG_PHY, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3915 + GdmaI2sTx(i2s_txdma_addr1, I2S_TX_FIFO_WREG_PHY, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3917 + GdmaI2sTx((u32)ptri2s_config->pPage0TxBuf8ptr, I2S_FIFO_WREG, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3918 + GdmaI2sTx((u32)ptri2s_config->pPage1TxBuf8ptr, I2S_FIFO_WREG, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3924 +void i2s_dma_rx_init(i2s_config_type* ptri2s_config)
3926 + memset(pi2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE);
3927 + memset(pi2s_config->pPage1RxBuf8ptr, 0, I2S_PAGE_SIZE);
3929 +#if defined(ARM_ARCH)
3930 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr0, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3931 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr1, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3933 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)ptri2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3934 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)ptri2s_config->pPage1RxBuf8ptr, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3940 +void i2s_dma_tx_end_handle(i2s_config_type* ptri2s_config)
3942 + if (ptri2s_config->tx_w_idx < ptri2s_config->tx_r_idx)
3944 + ptri2s_config->end_cnt = (ptri2s_config->tx_w_idx + MAX_I2S_PAGE)-ptri2s_config->tx_r_idx;
3945 + _printk("case1: w=%d, r=%d, end=%d\n", ptri2s_config->tx_w_idx, ptri2s_config->tx_r_idx, ptri2s_config->end_cnt);
3947 + else if (ptri2s_config->tx_w_idx > ptri2s_config->tx_r_idx)
3949 + ptri2s_config->end_cnt = ptri2s_config->tx_w_idx-ptri2s_config->tx_r_idx;
3950 + _printk("case2: w=%d, r=%d, end=%d\n", ptri2s_config->tx_w_idx, ptri2s_config->tx_r_idx, ptri2s_config->end_cnt);
3954 + _printk("case3: w=%d, r=%d, end=%d\n", ptri2s_config->tx_w_idx, ptri2s_config->tx_r_idx, ptri2s_config->end_cnt);
3958 + if (ptri2s_config->end_cnt > 0)
3960 + interruptible_sleep_on(&(ptri2s_config->i2s_tx_qh));
3966 +void i2s_tx_end_sleep_on(i2s_config_type* ptri2s_config)
3968 + while(ptri2s_config->tx_stop_cnt<3)
3969 + interruptible_sleep_on(&(ptri2s_config->i2s_tx_qh));
3974 +void i2s_rx_end_sleep_on(i2s_config_type* ptri2s_config)
3976 + while(ptri2s_config->rx_stop_cnt<2)
3977 + interruptible_sleep_on(&(ptri2s_config->i2s_rx_qh));
3981 +int i2s_dma_tx_soft_stop(i2s_config_type* ptri2s_config, u32 dma_ch)
3983 + if(dma_ch==GDMA_I2S_TX0)
3985 +#if defined(ARM_ARCH)
3986 + GdmaI2sTx(i2s_txdma_addr0, I2S_TX_FIFO_WREG_PHY, 0, 4, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3988 + GdmaI2sTx((u32)pi2s_config->pPage0TxBuf8ptr, I2S_TX_FIFO_WREG, 0, 4, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3993 +#if defined(ARM_ARCH)
3994 + GdmaI2sTx(i2s_txdma_addr1, I2S_TX_FIFO_WREG_PHY, 1, 4, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3996 + GdmaI2sTx((u32)pi2s_config->pPage1TxBuf8ptr, I2S_TX_FIFO_WREG, 1, 4, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
4003 +int i2s_dma_rx_soft_stop(i2s_config_type* ptri2s_config, u32 dma_ch)
4005 + if(dma_ch==GDMA_I2S_RX0)
4007 + memset(pi2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE);
4008 +#if defined(ARM_ARCH)
4009 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr0, 0, 4, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
4011 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)pi2s_config->pPage0RxBuf8ptr, 0, 4, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
4016 + memset(pi2s_config->pPage1RxBuf8ptr, 0, I2S_PAGE_SIZE);
4017 +#if defined(ARM_ARCH)
4018 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr1, 1, 4, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
4020 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)pi2s_config->pPage1RxBuf8ptr, 1, 4, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
4027 +void i2s_gen_test_pattern(void)
4030 + for (i=0; i<I2S_PAGE_SIZE; i++)
4032 + test_buf[i] = 0x5A;
4033 + test_buf_1[i] = 0x11;
4034 + test_buf_2[i] = 0x22;
4039 +int i2s_put_audio(i2s_config_type* ptri2s_config, unsigned long arg)
4041 + unsigned long flags;
4045 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4047 + if(((ptri2s_config->tx_w_idx+4)%MAX_I2S_PAGE)!=ptri2s_config->tx_r_idx)
4049 + ptri2s_config->tx_w_idx = (ptri2s_config->tx_w_idx+1)%MAX_I2S_PAGE;
4050 + tx_w_idx = ptri2s_config->tx_w_idx;
4051 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4052 + //_printk("put TB[%d] for user write\n",ptri2s_config->tx_w_idx);
4053 +#if defined(CONFIG_I2S_MMAP)
4054 + put_user(tx_w_idx, (int*)arg);
4056 + copy_from_user(ptri2s_config->pMMAPTxBufPtr[tx_w_idx], (char*)arg, I2S_PAGE_SIZE);
4058 + pi2s_status->txbuffer_len++;
4059 + //spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4065 + //_printk("TBF tr=%d, tw=%d\n", ptri2s_config->tx_r_idx, ptri2s_config->tx_w_idx);
4066 + pi2s_status->txbuffer_ovrun++;
4067 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4068 + interruptible_sleep_on(&(ptri2s_config->i2s_tx_qh));
4069 + if (ptri2s_config->bTxDMAEnable==0 && ptri2s_config->end_cnt==0)
4071 + _printk("wake up for exit i2s driver\n");
4072 + put_user(-1, (int*)arg);
4081 +int i2s_get_audio(i2s_config_type* ptri2s_config, unsigned long arg)
4083 + unsigned long flags;
4087 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4088 + //_printk("GA rr=%d, rw=%d,i=%d\n", ptri2s_config->rx_r_idx, ptri2s_config->rx_w_idx,ptri2s_config->rx_isr_cnt);
4089 + if(((ptri2s_config->rx_r_idx+2)%MAX_I2S_PAGE)!=ptri2s_config->rx_w_idx)
4091 + rx_r_idx = ptri2s_config->rx_r_idx;
4092 + ptri2s_config->rx_r_idx = (ptri2s_config->rx_r_idx+1)%MAX_I2S_PAGE;
4093 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4094 +#if defined(CONFIG_I2S_MMAP)
4095 + put_user(rx_r_idx, (int*)arg);
4097 + copy_to_user((char*)arg, ptri2s_config->pMMAPRxBufPtr[rx_r_idx], I2S_PAGE_SIZE);
4099 + //_printk("rx_r_idx=%d\n", ptri2s_config->rx_r_idx);
4100 + //ptri2s_config->rx_r_idx = (ptri2s_config->rx_r_idx+1)%MAX_I2S_PAGE;
4101 + pi2s_status->rxbuffer_len--;
4102 + //spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4108 + //_printk("RBF rr=%d, rw=%d\n", ptri2s_config->rx_r_idx, ptri2s_config->rx_w_idx);
4109 + pi2s_status->rxbuffer_ovrun++;
4110 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4111 + interruptible_sleep_on(&(ptri2s_config->i2s_rx_qh));
4113 +#if defined(CONFIG_I2S_WITH_AEC)
4114 + if(aecFuncP->AECECDeq){
4115 + aecFuncP->AECECDeq(0,pi2s_config->pMMAPRxBufPtr[ptri2s_config->rx_r_idx],I2S_PAGE_SIZE);
4123 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
4124 +long i2s_ioctl (struct file *filp, unsigned int cmd, unsigned long arg)
4126 +int i2s_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
4130 + i2s_config_type* ptri2s_config;
4131 + unsigned long flags;
4133 + ptri2s_config = filp->private_data;
4136 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4137 + i2s_reset_config(ptri2s_config);
4138 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4141 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4142 +#if defined(CONFIG_I2S_WM8960)
4143 + if((arg>MAX_SRATE_HZ)||(arg<MIN_SRATE_HZ))
4145 + MSG("Audio sampling rate %u should be %d ~ %d Hz. Set SRate to 48000Hz\n", (u32)arg, MIN_SRATE_HZ, MAX_SRATE_HZ);
4146 + ptri2s_config->srate = 48000;
4147 + spin_unlock(&ptri2s_config->lock);
4150 +#elif defined(CONFIG_I2S_WM8750)
4151 + if((arg>MAX_SRATE_HZ)||(arg<MIN_SRATE_HZ))
4153 + MSG("Audio sampling rate %u should be %d ~ %d Hz. Set SRate to 96000Hz\n", (u32)arg, MIN_SRATE_HZ, MAX_SRATE_HZ);
4154 + ptri2s_config->srate = 96000;
4155 + spin_unlock(&ptri2s_config->lock);
4159 + ptri2s_config->srate = arg;
4160 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4161 + MSG("set audio sampling rate to %d Hz\n", ptri2s_config->srate);
4164 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4166 + if((int)arg > 127)
4167 + ptri2s_config->txvol = 127;
4168 + else if((int)arg < 48)
4169 + ptri2s_config->txvol = 48;
4171 + ptri2s_config->txvol = arg;
4173 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4175 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4176 +#if (defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751))
4177 + audiohw_set_master_vol(arg,arg);
4178 +#elif defined(CONFIG_I2S_WM8960)
4179 + audiohw_set_lineout_vol(1, ptri2s_config->txvol, ptri2s_config->txvol);
4181 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4184 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4187 + ptri2s_config->rxvol = 63;
4188 + else if((int)arg < 0)
4189 + ptri2s_config->rxvol = 0;
4191 + ptri2s_config->rxvol = arg;
4193 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4195 +#if defined (CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4196 + case I2S_WORD_LEN:
4197 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4198 + if((int)arg == 16)
4200 + ptri2s_config->wordlen_24b = 0;
4201 + MSG("Enable 16 bit word length.\n");
4203 + else if ((int)arg == 24)
4205 + ptri2s_config->wordlen_24b = 1;
4206 + MSG("Enable 24 bit word length.\n");
4210 + MSG("MT7628 only support 16bit/24bit word length.\n");
4211 + spin_unlock(&ptri2s_config->lock);
4214 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4216 + case I2S_ENDIAN_FMT:
4217 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4220 + ptri2s_config->little_edn = 1;
4221 + MSG("Little endian format.\n");
4225 + ptri2s_config->little_edn = 0;
4226 + MSG("Big endian format.\n");
4228 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4231 + case I2S_INTERNAL_LBK:
4232 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4235 + ptri2s_config->lbk = 1;
4236 + MSG("Enable internal loopback.\n");
4240 + ptri2s_config->lbk = 0;
4241 + MSG("Disable internal loopback.\n");
4243 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4245 + case I2S_EXTERNAL_LBK:
4246 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4249 + ptri2s_config->extlbk = 1;
4250 + MSG("Enable external loopback.\n");
4254 + ptri2s_config->extlbk = 0;
4255 + MSG("Disable external loopback.\n");
4257 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4259 + case I2S_TXRX_COEXIST:
4260 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4263 + ptri2s_config->txrx_coexist = 1;
4264 + MSG("TX/RX coexist.\n");
4268 + ptri2s_config->txrx_coexist = 0;
4269 + MSG("TX/RX coexist.\n");
4271 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4274 + case I2S_TX_ENABLE:
4275 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4276 + MSG("I2S_TXENABLE\n");
4278 + pi2s_config->tx_unmask_ch = 0;
4279 + tasklet_init(&i2s_tx_tasklet, i2s_tx_task, (u32)pi2s_config);
4281 + pi2s_config->dis_match = 0;
4282 + pi2s_config->start_cnt = 0;
4283 + i2s_gen_test_pattern();
4285 + /* allocate tx buffer */
4286 + i2s_txPagebuf_alloc(ptri2s_config);
4287 + i2s_txbuf_alloc(ptri2s_config);
4289 + /* Init two dma channels */
4290 + i2s_dma_tx_init(ptri2s_config);
4291 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4293 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4294 + /* Init & config all tx param */
4295 + i2s_reset_tx_param(ptri2s_config);
4296 + ptri2s_config->bTxDMAEnable = 1;
4297 + /* Clear all ALSA related config */
4298 + ptri2s_config->bALSAEnable = 0;
4299 + ptri2s_config->bALSAMMAPEnable = 0;
4301 + i2s_tx_config(ptri2s_config);
4303 + if(ptri2s_config->bRxDMAEnable==0)
4304 + i2s_clock_enable(ptri2s_config);
4305 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4307 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4308 +#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
4309 + audiohw_set_lineout_vol(1, ptri2s_config->txvol, ptri2s_config->txvol);
4311 + GdmaUnMaskChannel(GDMA_I2S_TX0);
4313 + i2s_tx_enable(ptri2s_config);
4315 + /* Kick off dma channel */
4316 + //GdmaUnMaskChannel(GDMA_I2S_TX0);
4318 + MSG("I2S_TXENABLE done\n");
4319 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4321 + case I2S_TX_DISABLE:
4322 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4323 + MSG("I2S_TXDISABLE\n");
4325 + //tasklet_kill(&i2s_tx_tasklet);
4327 + /* Handle tx end data */
4328 + ptri2s_config->bTxDMAEnable = 0;
4329 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4331 + i2s_tx_end_sleep_on(ptri2s_config);
4333 + tasklet_kill(&i2s_tx_tasklet);
4335 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4336 + i2s_reset_tx_param(ptri2s_config);
4337 + i2s_tx_disable(ptri2s_config);
4338 + if((ptri2s_config->bRxDMAEnable==0)&&(ptri2s_config->bTxDMAEnable==0))
4339 + i2s_clock_disable(ptri2s_config);
4341 + i2s_txbuf_free(ptri2s_config);
4342 + if(ptri2s_config->mmap_index <= MAX_I2S_PAGE)
4343 + ptri2s_config->mmap_index = 0;
4345 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4347 + case I2S_RX_ENABLE:
4348 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4349 + MSG("I2S_RXENABLE\n");
4350 + pi2s_config->rx_unmask_ch = 0;
4351 + tasklet_init(&i2s_rx_tasklet, i2s_rx_task, (u32)pi2s_config);
4353 + /* allocate rx buffer */
4354 + i2s_rxPagebuf_alloc(ptri2s_config);
4355 + i2s_rxbuf_alloc(ptri2s_config);
4357 + /* Init two dma channels */
4358 + i2s_dma_rx_init(ptri2s_config);
4359 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4361 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4362 + /* Init & config all rx param */
4363 + i2s_reset_rx_param(ptri2s_config);
4364 + ptri2s_config->bRxDMAEnable = 1;
4365 + ptri2s_config->bALSAEnable = 0;
4366 + ptri2s_config->bALSAMMAPEnable = 0;
4368 + i2s_rx_config(ptri2s_config);
4370 + if(ptri2s_config->bTxDMAEnable==0)
4371 + i2s_clock_enable(ptri2s_config);
4373 +#if defined(CONFIG_I2S_TXRX)
4374 +#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
4375 + audiohw_set_linein_vol(ptri2s_config->rxvol, ptri2s_config->rxvol);
4378 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4380 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4381 + /* Kick off dma channel */
4382 + GdmaUnMaskChannel(GDMA_I2S_RX0);
4384 + i2s_rx_enable(ptri2s_config);
4385 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4387 + case I2S_RX_DISABLE:
4388 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4389 + MSG("I2S_RXDISABLE\n");
4390 + //tasklet_kill(&i2s_rx_tasklet);
4392 + ptri2s_config->bRxDMAEnable = 0;
4393 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4395 + i2s_rx_end_sleep_on(ptri2s_config);
4396 + tasklet_kill(&i2s_rx_tasklet);
4398 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4399 + i2s_reset_rx_param(ptri2s_config);
4400 + i2s_rx_disable(ptri2s_config);
4401 + if((ptri2s_config->bRxDMAEnable==0)&&(ptri2s_config->bTxDMAEnable==0))
4402 + i2s_clock_disable(ptri2s_config);
4404 + i2s_rxbuf_free(ptri2s_config);
4405 + if(ptri2s_config->mmap_index <= MAX_I2S_PAGE)
4406 + ptri2s_config->mmap_index = 0;
4407 + //i2s_rxPagebuf_free(ptri2s_config);
4408 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4410 + case I2S_PUT_AUDIO:
4411 + i2s_put_audio(ptri2s_config, arg);
4413 + case I2S_GET_AUDIO:
4414 + i2s_get_audio(ptri2s_config, arg);
4417 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4418 + MSG("TxGDMA STOP\n");
4419 + ptri2s_config->bTxDMAEnable = 0;
4420 + ptri2s_config->end_cnt = 0;
4421 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4423 + while(ptri2s_config->tx_stop_cnt<3)
4424 + interruptible_sleep_on(&(ptri2s_config->i2s_tx_qh));
4426 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4427 + i2s_reset_tx_param(ptri2s_config);
4428 + i2s_tx_disable(ptri2s_config);
4429 + if((ptri2s_config->bRxDMAEnable==0)&&(ptri2s_config->bTxDMAEnable==0))
4430 + i2s_clock_disable(ptri2s_config);
4432 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4434 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4435 + i2s_txbuf_free(ptri2s_config);
4436 + if(ptri2s_config->mmap_index <= MAX_I2S_PAGE)
4437 + ptri2s_config->mmap_index = 0;
4438 + //i2s_txPagebuf_free(ptri2s_config);
4439 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4441 + case I2S_TX_PAUSE:
4442 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4443 + ptri2s_config->tx_pause_en = 1;
4444 + MSG("* tx_pause_en = 1 *\n");
4445 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4447 + case I2S_TX_RESUME:
4448 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4449 + ptri2s_config->tx_pause_en = 0;
4450 + MSG("# tx_pause_en = 0 #\n");
4451 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4454 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4455 + MSG("I2S_RX_STOP\n");
4456 + ptri2s_config->bRxDMAEnable = 0;
4457 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4459 + while(ptri2s_config->rx_stop_cnt<2)
4460 + interruptible_sleep_on(&(ptri2s_config->i2s_rx_qh));
4462 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4463 + i2s_reset_rx_param(ptri2s_config);
4464 + i2s_rx_disable(ptri2s_config);
4465 + if((ptri2s_config->bRxDMAEnable==0)&&(ptri2s_config->bTxDMAEnable==0))
4466 + i2s_clock_disable(ptri2s_config);
4467 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4469 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4470 + i2s_rxbuf_free(ptri2s_config);
4471 + if(ptri2s_config->mmap_index <= MAX_I2S_PAGE)
4472 + ptri2s_config->mmap_index = 0;
4473 + //i2s_rxPagebuf_free(ptri2s_config);
4474 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4476 + case I2S_RX_PAUSE:
4477 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4478 + ptri2s_config->rx_pause_en = 1;
4479 + MSG("* rx_pause_en = 1 *\n");
4480 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4482 + case I2S_RX_RESUME:
4483 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4484 + ptri2s_config->rx_pause_en = 0;
4485 + MSG("# rx_pause_en = 0 #\n");
4486 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4488 + case I2S_CODEC_MIC_BOOST:
4489 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4491 + ptri2s_config->micboost = 3;
4492 + else if((int)arg < 0)
4493 + ptri2s_config->micboost = 0;
4495 + ptri2s_config->micboost = arg;
4496 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4498 + case I2S_CODEC_MIC_IN:
4499 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4501 + ptri2s_config->micin = 1;
4503 + ptri2s_config->micin = 0;
4504 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4506 + case I2S_CLOCK_ENABLE:
4507 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4508 + i2s_clock_disable(ptri2s_config);
4509 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4510 + ptri2s_config->wordlen_24b = 1;
4512 + i2s_tx_config(ptri2s_config);
4513 + i2s_clock_enable(ptri2s_config);
4514 + i2s_tx_enable(ptri2s_config);
4515 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4517 + case I2S_DEBUG_CODEC:
4518 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4519 + for (i=0; i<10; i++)
4521 + _printk("### i=%d ###\n", i);
4522 + i2s_clock_enable(ptri2s_config);
4523 + i2s_clock_disable(ptri2s_config);
4525 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4527 +#if defined(CONFIG_I2S_MS_CTRL)
4528 + case I2S_MS_MODE_CTRL:
4529 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4532 + ptri2s_config->slave_en = 1;
4533 + _printk("I2S in slave mode.\n");
4537 + ptri2s_config->slave_en = 0;
4538 + _printk("I2S in master mode.\n");
4540 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4543 + case I2S_DEBUG_CLKGEN:
4544 + case I2S_DEBUG_INLBK:
4545 + case I2S_DEBUG_EXLBK:
4546 + case I2S_DEBUG_CODECBYPASS:
4547 + case I2S_DEBUG_FMT:
4548 +#if defined(CONFIG_I2S_WM8960)
4549 + case I2S_DEBUG_CODEC_EXLBK:
4551 + case I2S_DEBUG_RESET:
4552 + i2s_debug_cmd(cmd, arg);
4555 + MSG("i2s_ioctl: command format error\n");
4561 +/************************
4564 + ************************/
4565 +char* i2s_memPool_Alloc(i2s_config_type* ptri2s_config,int dir)
4567 + //_printk("%s\n",__func__);
4568 + if(!ptri2s_config)
4570 + if(dir == STREAM_PLAYBACK){
4571 +#if defined(CONFIG_I2S_MMAP)
4572 + i2s_mmap_alloc(I2S_TOTAL_PAGE_SIZE);
4574 + i2s_txbuf_alloc(ptri2s_config);
4575 + return ptri2s_config->pMMAPTxBufPtr[0];
4577 +#if defined(CONFIG_I2S_MMAP)
4578 + i2s_mmap_alloc(I2S_TOTAL_PAGE_SIZE);
4580 + i2s_rxbuf_alloc(ptri2s_config);
4581 + return ptri2s_config->pMMAPRxBufPtr[0];
4586 +void i2s_memPool_free(i2s_config_type* ptri2s_config,int dir)
4588 + if(!ptri2s_config)
4590 + if(dir == STREAM_PLAYBACK){
4591 +#if defined(CONFIG_I2S_MMAP)
4592 + i2s_mem_unmap(ptri2s_config);
4594 + i2s_txbuf_free(ptri2s_config);
4596 +#if defined(CONFIG_I2S_MMAP)
4597 + i2s_mem_unmap(ptri2s_config);
4599 + i2s_rxbuf_free(ptri2s_config);
4605 +int i2s_page_prepare(i2s_config_type* ptri2s_config,int dir)
4607 + if(dir == STREAM_PLAYBACK){
4608 + /* allocate tx buffer */
4609 + i2s_txPagebuf_alloc(ptri2s_config);
4610 + i2s_dma_tx_init(ptri2s_config);
4612 + /* allocate rx buffer */
4613 + i2s_rxPagebuf_alloc(ptri2s_config);
4614 + i2s_dma_rx_init(ptri2s_config);
4619 +int i2s_page_release(i2s_config_type* ptri2s_config,int dir)
4621 + if(!ptri2s_config)
4623 + if(dir == STREAM_PLAYBACK)
4624 + i2s_txPagebuf_free(ptri2s_config);
4626 + i2s_rxPagebuf_free(ptri2s_config);
4631 +int i2s_startup(void)
4633 + memset(pi2s_config, 0, sizeof(i2s_config_type));
4635 +#ifdef I2S_STATISTIC
4636 + memset(pi2s_status, 0, sizeof(i2s_status_type));
4639 + i2s_param_init(pi2s_config);
4640 + pi2s_config->bALSAEnable = 1;
4641 +#if defined(CONFIG_I2S_MMAP)
4642 + pi2s_config->bALSAMMAPEnable = 1;
4645 +#if defined (CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4646 + pi2s_config->little_edn = 1;
4649 + init_waitqueue_head(&(pi2s_config->i2s_tx_qh));
4650 + init_waitqueue_head(&(pi2s_config->i2s_rx_qh));
4651 + spin_lock_init(&pi2s_config->lock);
4656 +int gdma_En_Switch(i2s_config_type* ptri2s_config,int dir,int enabled){
4657 + if(!ptri2s_config)
4659 + if(dir == STREAM_PLAYBACK){
4660 + ptri2s_config->bTxDMAEnable = enabled;
4661 + //MSG("%s:%d\n",__func__,ptri2s_config->bTxDMAEnable);
4663 + ptri2s_config->bRxDMAEnable = enabled;
4668 +int i2s_audio_exchange(i2s_config_type* ptri2s_config,int dir,unsigned long arg)
4670 + //MSG("I2S_PUT_AUDIO\n");
4671 + if(!ptri2s_config)
4673 + if(dir == STREAM_PLAYBACK){
4674 + i2s_put_audio(ptri2s_config, arg);
4676 + i2s_get_audio(ptri2s_config, arg);
4681 +void gdma_mask_handler(u32 dma_ch)
4683 + i2s_dma_mask_handler(dma_ch);
4687 +void gdma_unmask_handler(u32 dma_ch)
4689 + i2s_dma_unmask_handler(dma_ch);
4693 +u32 i2s_mmap_phys_addr(i2s_config_type* ptri2s_config)
4695 + if((ptri2s_config->pMMAPBufPtr[0]!=NULL) && (ptri2s_config->mmap_index == MAX_I2S_PAGE))
4696 + return (dma_addr_t)i2s_mmap_addr[0];
4697 + else if((ptri2s_config->pMMAPBufPtr[MAX_I2S_PAGE]!=NULL) && (ptri2s_config->mmap_index == MAX_I2S_PAGE*2))
4698 + return (dma_addr_t)i2s_mmap_addr[MAX_I2S_PAGE];
4703 +EXPORT_SYMBOL(i2s_startup);
4704 +EXPORT_SYMBOL(i2s_mem_unmap);
4705 +EXPORT_SYMBOL(i2s_mmap_alloc);
4706 +EXPORT_SYMBOL(i2s_mmap_remap);
4707 +EXPORT_SYMBOL(i2s_param_init);
4708 +EXPORT_SYMBOL(i2s_txbuf_alloc);
4709 +EXPORT_SYMBOL(i2s_rxbuf_alloc);
4710 +EXPORT_SYMBOL(i2s_txPagebuf_alloc);
4711 +EXPORT_SYMBOL(i2s_rxPagebuf_alloc);
4712 +EXPORT_SYMBOL(i2s_txbuf_free);
4713 +EXPORT_SYMBOL(i2s_rxbuf_free);
4714 +EXPORT_SYMBOL(i2s_txPagebuf_free);
4715 +EXPORT_SYMBOL(i2s_rxPagebuf_free);
4716 +EXPORT_SYMBOL(i2s_rx_disable);
4717 +EXPORT_SYMBOL(i2s_tx_disable);
4718 +EXPORT_SYMBOL(i2s_rx_enable);
4719 +EXPORT_SYMBOL(i2s_tx_enable);
4720 +EXPORT_SYMBOL(i2s_rx_config);
4721 +EXPORT_SYMBOL(i2s_tx_config);
4722 +EXPORT_SYMBOL(i2s_reset_config);
4723 +EXPORT_SYMBOL(i2s_clock_disable);
4724 +EXPORT_SYMBOL(i2s_clock_enable);
4725 +EXPORT_SYMBOL(i2s_reset_rx_param);
4726 +EXPORT_SYMBOL(i2s_reset_tx_param);
4727 +EXPORT_SYMBOL(i2s_dma_rx_handler);
4728 +EXPORT_SYMBOL(i2s_dma_tx_handler);
4729 +EXPORT_SYMBOL(i2s_dma_unmask_handler);
4730 +EXPORT_SYMBOL(i2s_dma_tx_unmask_handler);
4731 +EXPORT_SYMBOL(i2s_dma_rx_unmask_handler);
4732 +EXPORT_SYMBOL(i2s_dma_mask_handler);
4733 +EXPORT_SYMBOL(i2s_dma_tx_init);
4734 +EXPORT_SYMBOL(i2s_dma_rx_init);
4735 +EXPORT_SYMBOL(i2s_tx_end_sleep_on);
4736 +EXPORT_SYMBOL(i2s_rx_end_sleep_on);
4737 +EXPORT_SYMBOL(i2s_mmap_phys_addr);
4738 +EXPORT_SYMBOL(i2s_open);
4739 +EXPORT_SYMBOL(pi2s_config);
4740 +#if defined(CONFIG_I2S_IN_MCLK)
4741 +#if defined(CONFIG_I2S_MCLK_12MHZ)
4742 +EXPORT_SYMBOL(i2s_refclk_12m_enable);
4744 +#if defined(CONFIG_I2S_MCLK_12P288MHZ)
4745 +EXPORT_SYMBOL(i2s_refclk_12p288m_enable);
4748 +#if defined(MT7628_ASIC_BOARD) || defined(CONFIG_ARCH_MT7623)
4749 +EXPORT_SYMBOL(i2s_driving_strength_adjust);
4751 +EXPORT_SYMBOL(i2s_refclk_disable);
4752 +EXPORT_SYMBOL(i2s_refclk_gpio_out_config);
4753 +EXPORT_SYMBOL(i2s_refclk_gpio_in_config);
4754 +EXPORT_SYMBOL(i2s_share_pin_config);
4755 +EXPORT_SYMBOL(i2s_share_pin_mt7623);
4756 +EXPORT_SYMBOL(i2s_ws_config);
4757 +EXPORT_SYMBOL(i2s_mode_config);
4758 +EXPORT_SYMBOL(i2s_codec_frequency_config);
4759 +EXPORT_SYMBOL(i2s_dma_tx_transf_data);
4760 +EXPORT_SYMBOL(i2s_dma_tx_transf_zero);
4761 +EXPORT_SYMBOL(i2s_dma_rx_transf_data);
4762 +EXPORT_SYMBOL(i2s_dma_rx_transf_zero);
4763 +EXPORT_SYMBOL(i2s_dma_tx_end_handle);
4764 +EXPORT_SYMBOL(i2s_dma_tx_soft_stop);
4765 +EXPORT_SYMBOL(i2s_dma_rx_soft_stop);
4766 +EXPORT_SYMBOL(i2s_tx_task);
4767 +EXPORT_SYMBOL(i2s_rx_task);
4769 +EXPORT_SYMBOL(i2s_memPool_Alloc);
4770 +EXPORT_SYMBOL(i2s_memPool_free);
4771 +EXPORT_SYMBOL(i2s_page_prepare);
4772 +EXPORT_SYMBOL(i2s_page_release);
4773 +EXPORT_SYMBOL(gdma_En_Switch);
4774 +EXPORT_SYMBOL(i2s_audio_exchange);
4775 +EXPORT_SYMBOL(gdma_mask_handler);
4776 +EXPORT_SYMBOL(gdma_unmask_handler);
4777 +#if defined(CONFIG_I2S_WITH_AEC)
4778 +EXPORT_SYMBOL(aecFuncP);
4780 +module_init(i2s_mod_init);
4781 +module_exit(i2s_mod_exit);
4783 +MODULE_DESCRIPTION("Ralink SoC I2S Controller Module");
4784 +MODULE_AUTHOR("Qwert Chin <qwert.chin@ralinktech.com.tw>");
4785 +MODULE_SUPPORTED_DEVICE("I2S");
4786 +MODULE_VERSION(I2S_MOD_VERSION);
4787 +MODULE_LICENSE("GPL");
4788 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
4789 +MODULE_PARM (i2sdrv_major, "i");
4791 +module_param (i2sdrv_major, int, 0);
4793 diff --git a/sound/soc/mtk/i2s_ctrl.h b/sound/soc/mtk/i2s_ctrl.h
4794 new file mode 100644
4795 index 0000000..b762c9c
4797 +++ b/sound/soc/mtk/i2s_ctrl.h
4799 +#ifndef __RALINK_I2S_H_
4800 +#define __RALINK_I2S_H_
4803 +//#include <asm/rt2880/rt_mmap.h>
4806 +#if defined(CONFIG_I2S_WITH_AEC)
4807 +#include "aec/aec_api.h"
4810 +#define I2S_MAX_DEV 1
4811 +#define I2S_MOD_VERSION "0.1"
4812 +#define phys_to_bus(a) (a & 0x1FFFFFFF)
4815 +#define u32 unsigned int
4819 +#define u16 unsigned short
4823 +#define u8 unsigned char
4827 +#define REGBIT(x, n) (x << n)
4830 +#define Virtual2Physical(x) (((int)x) & 0x1fffffff)
4831 +#define Physical2Virtual(x) (((int)x) | 0x80000000)
4832 +#define Virtual2NonCache(x) (((int)x) | 0x20000000)
4833 +#define Physical2NonCache(x) (((int)x) | 0xa0000000)
4834 +#define NonCache2Virtual(x) (((int)x) & 0xDFFFFFFF)
4836 +#if defined(CONFIG_I2S_MCLK_12MHZ)
4837 +#define CONFIG_I2S_CODEC_PLL_EN 1
4839 +#define CONFIG_I2S_CODEC_PLL_EN 0
4842 +//#define CONFIG_I2S_MS_CTRL
4843 +//#define CONFIG_I2S_MS_MODE
4844 +//#define memory_test
4846 +#if defined (CONFIG_ARCH_MT7623)
4847 +#define MT7623_ASIC_BOARD
4851 +#if defined (CONFIG_RALINK_MT7621)
4852 +#define MT7621_ASIC_BOARD
4855 +#if defined (CONFIG_RALINK_MT7628)
4856 +#define MT7628_ASIC_BOARD
4859 +//#define I2S_DEBUG_PRN
4860 +#ifdef I2S_DEBUG_PRN
4861 +#define MSG(fmt, args...) printk("I2S: " fmt, ## args)
4863 +#define MSG(fmt, args...) { }
4866 +#ifdef I2S_DEBUG_PRN
4867 +#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)
4869 +#define i2s_outw(address, value) *((volatile uint32_t *)(address)) = cpu_to_le32(value)
4871 +#define i2s_inw(address) le32_to_cpu(*(volatile u32 *)(address))
4873 +/* HW feature definiations */
4874 +#if defined(CONFIG_RALINK_RT3883)
4875 +#define CONFIG_I2S_TXRX 1
4876 +#define CONFIG_I2S_IN_MCLK 1
4877 +//#define CONFIG_I2S_WS_EDGE 1
4878 +#define CONFIG_I2S_FRAC_DIV 1
4879 +#define CONFIG_I2S_IN_CLK 1
4880 +#define CONFIG_I2S_MS_MODE 1
4883 +#if defined(CONFIG_RALINK_RT3352)||defined(CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) \
4884 + || defined(CONFIG_RALINK_RT6855A) || defined(CONFIG_RALINK_MT7620) || defined(CONFIG_RALINK_MT7621) \
4885 + || defined (CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4886 +#define CONFIG_I2S_TXRX 1
4887 +//#define CONFIG_I2S_WS_EDGE 1
4888 +#define CONFIG_I2S_FRAC_DIV 1
4889 +#define CONFIG_I2S_IN_CLK 1
4892 +#if defined(CONFIG_RALINK_RT3350)
4893 +#define CONFIG_I2S_IN_MCLK 1
4896 +#if defined(CONFIG_RALINK_RT3052)
4897 +#define CONFIG_I2S_MS_MODE 1
4900 +/* This is decided in menuconfig */
4901 +#define CONFIG_I2S_MMAP 1
4903 +/* For MT7623 ASIC PLL Setting */
4904 +#if defined(CONFIG_ARCH_MT7623)
4905 +#define AUD1PLL_CON0 (0xF0209270)
4906 +#define AUD1PLL_CON1 (0xF0209274)
4907 +#define AUD1PLL_CON2 (0xF0209278)
4908 +#define AUD1PLL_PWR_CON0 (0xF020927C)
4909 +#define AUD2PLL_CON0 (0xF02092C0)
4910 +#define AUD2PLL_CON1 (0xF02092C4)
4911 +#define AUD2PLL_CON2 (0xF02092C8)
4912 +#define AUD2PLL_PWR_CON0 (0xF02092CC)
4915 +/* Register Map, Ref to RT3052 Data Sheet */
4917 +/* Register Map Detail */
4918 +#if defined(CONFIG_ARCH_MT7623)
4919 +#define I2S_I2SCFG (ETHDMASYS_I2S_BASE+0x0000)
4920 +#define I2S_INT_STATUS (ETHDMASYS_I2S_BASE+0x0004)
4921 +#define I2S_INT_EN (ETHDMASYS_I2S_BASE+0x0008)
4922 +#define I2S_FF_STATUS (ETHDMASYS_I2S_BASE+0x000c)
4923 +#define I2S_FIFO_WREG (ETHDMASYS_I2S_BASE+0x0010)
4924 +#define I2S_TX_FIFO_WREG I2S_FIFO_WREG
4925 +#define I2S_RX_FIFO_RREG (ETHDMASYS_I2S_BASE+0x0014)
4926 +#define I2S_I2SCFG1 (ETHDMASYS_I2S_BASE+0x0018)
4927 +#define I2S_DIVINT_CFG (ETHDMASYS_I2S_BASE+0x0024)
4928 +#define I2S_DIVCOMP_CFG (ETHDMASYS_I2S_BASE+0x0020)
4930 +#define I2S_I2SCFG (RALINK_I2S_BASE+0x0000)
4931 +#define I2S_INT_STATUS (RALINK_I2S_BASE+0x0004)
4932 +#define I2S_INT_EN (RALINK_I2S_BASE+0x0008)
4933 +#define I2S_FF_STATUS (RALINK_I2S_BASE+0x000c)
4934 +#define I2S_FIFO_WREG (RALINK_I2S_BASE+0x0010)
4935 +#define I2S_TX_FIFO_WREG I2S_FIFO_WREG
4936 +#define I2S_RX_FIFO_RREG (RALINK_I2S_BASE+0x0014)
4937 +#define I2S_I2SCFG1 (RALINK_I2S_BASE+0x0018)
4938 +#define I2S_DIVINT_CFG (RALINK_I2S_BASE+0x0024)
4939 +#define I2S_DIVCOMP_CFG (RALINK_I2S_BASE+0x0020)
4943 +/* I2SCFG bit field */
4945 +#define I2S_DMA_EN 30
4946 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4947 +#define I2S_LITTLE_ENDIAN 29
4948 +#define I2S_SYS_ENDIAN 28
4949 +#elif defined(CONFIG_RALINK_RT6855A)
4950 +#define I2S_BYTE_SWAP 28
4952 +#define I2S_TX_EN 24
4953 +#define I2S_RX_EN 20
4954 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4955 +#define I2S_NORM_24BIT 18
4956 +#define I2S_DATA_24BIT 17
4958 +#define I2S_SLAVE_MODE 16
4959 +#define I2S_RX_FF_THRES 12
4960 +#define I2S_RX_CH_SWAP 11
4961 +#define I2S_RX_CH1_OFF 10
4962 +#define I2S_RX_CH0_OFF 9
4963 +#if defined(CONFIG_RALINK_RT3052)
4964 +#define I2S_CLK_OUT_DIS 8
4966 +#define I2S_TX_FF_THRES 4
4967 +#define I2S_TX_CH_SWAP 3
4968 +#define I2S_TX_CH1_OFF 2
4969 +#define I2S_TX_CH0_OFF 1
4970 +#if defined(CONFIG_RALINK_RT3052)
4971 +#define I2S_SLAVE_EN 0
4973 +#define I2S_WS_INV 0
4975 +/* INT_EN bit field */
4976 +#define I2S_RX_INT3_EN 7
4977 +#define I2S_RX_INT2_EN 6
4978 +#define I2S_RX_INT1_EN 5
4979 +#define I2S_RX_INT0_EN 4
4980 +#define I2S_TX_INT3_EN 3
4981 +#define I2S_TX_INT2_EN 2
4982 +#define I2S_TX_INT1_EN 1
4983 +#define I2S_TX_INT0_EN 0
4985 +/* INT_STATUS bit field */
4986 +#define I2S_RX_DMA_FAULT 7
4987 +#define I2S_RX_OVRUN 6
4988 +#define I2S_RX_UNRUN 5
4989 +#define I2S_RX_THRES 4
4990 +#define I2S_TX_DMA_FAULT 3
4991 +#define I2S_TX_OVRUN 2
4992 +#define I2S_TX_UNRUN 1
4993 +#define I2S_TX_THRES 0
4995 +/* FF_STATUS bit field */
4996 +#define I2S_RX_EPCNT 4
4997 +#define I2S_TX_EPCNT 0
4998 +/* I2S_DIVCOMP_CFG bit field */
4999 +#define I2S_CLKDIV_EN 31
5001 +/* I2S_CFG1 bit field */
5002 +#define I2S_LBK_EN 31
5003 +#define I2S_EXT_LBK_EN 30
5004 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
5005 +#define I2S_DATA_FMT 0
5008 +/* FIFO_WREG bit field */
5009 +#define I2S_FIFO_WDATA 0
5011 +/* Constant definition */
5012 +#define NFF_THRES 4
5013 +#define I2S_PAGE_SIZE 3072//(3*4096)//(1152*2*2*2)
5014 +#define I2S_MIN_PAGE_SIZE 4096
5015 +#define MAX_I2S_PAGE 8
5016 +#define I2S_TOTAL_PAGE_SIZE (I2S_PAGE_SIZE*MAX_I2S_PAGE)
5018 +#if defined(CONFIG_I2S_WM8960)
5019 +#define MAX_SRATE_HZ 48000
5020 +#define MIN_SRATE_HZ 8000
5021 +#elif defined(CONFIG_I2S_WM8750)
5022 +#define MAX_SRATE_HZ 96000
5023 +#define MIN_SRATE_HZ 8000
5026 +#define MAX_VOL_DB +0
5027 +#define MIN_VOL_DB -127
5029 +#define ALSA_MMAP_IDX_SHIFT 2
5030 +#if defined(CONFIG_SND_MT76XX_SOC)
5031 +#define STREAM_PLAYBACK SNDRV_PCM_STREAM_PLAYBACK
5032 +#define STREAM_CAPTURE SNDRV_PCM_STREAM_CAPTURE
5034 +#define STREAM_PLAYBACK 0
5035 +#define STREAM_CAPTURE 1
5038 +/* I2S I/O command */
5039 +#define I2S_SRATE 0
5041 +#define I2S_ENABLE 2
5042 +#define I2S_DISABLE 3
5043 +#define I2S_TX_ENABLE 27
5044 +#define I2S_TX_DISABLE 3
5045 +#define I2S_GET_WBUF 4
5046 +#define I2S_PUT_WBUF 5
5047 +#define I2S_RX_ENABLE 6
5048 +#define I2S_RX_DISABLE 7
5049 +#define I2S_PUT_AUDIO 4
5050 +#define I2S_GET_AUDIO 5
5051 +#define I2S_TX_VOL 1
5052 +#define I2S_RX_VOL 8
5053 +#define I2S_WORD_LEN 9
5054 +#define I2S_ENDIAN_FMT 10
5055 +#define I2S_INTERNAL_LBK 11
5056 +#define I2S_TX_STOP 12
5057 +#define I2S_DEBUG_CODEC 13
5058 +#define I2S_MS_MODE_CTRL 14
5059 +#define I2S_TX_PAUSE 15
5060 +#define I2S_TX_RESUME 16
5061 +#define I2S_RESET 17
5062 +#define I2S_RX_STOP 18
5063 +#define I2S_EXTERNAL_LBK 19
5064 +#define I2S_TXRX_COEXIST 20
5065 +#define I2S_RX_PAUSE 21
5066 +#define I2S_RX_RESUME 22
5067 +#define I2S_CODEC_MIC_BOOST 23
5068 +#define I2S_CODEC_MIC_IN 24
5069 +#define I2S_CLOCK_ENABLE 25
5070 +#define I2S_TEST_TEST 26
5072 +#define I2S_DEBUG 30
5073 +#define I2S_DEBUG_CLKGEN 30
5074 +#define I2S_DEBUG_INLBK 31
5075 +#define I2S_DEBUG_EXLBK 32
5076 +#define I2S_DEBUG_FMT 33
5077 +#define I2S_DEBUG_RESET 34
5078 +#define I2S_DEBUG_CODECBYPASS 35
5079 +#if defined(CONFIG_I2S_WM8960)
5080 +#define I2S_DEBUG_CODEC_EXLBK 36
5083 +/* configuration */
5084 +#define CONFIG_I2S_TFF_THRES NFF_THRES
5085 +#define CONFIG_I2S_CH_SWAP 0
5086 +#if defined(CONFIG_I2S_MS_MODE)
5087 +#define CONFIG_I2S_SLAVE_EN 0
5089 +#define CONFIG_I2S_SLAVE_EN 1
5092 +/* driver status definition */
5094 +#define I2S_OUTOFMEM 0x01
5095 +#define I2S_GDMAFAILED 0x02
5096 +#define I2S_REQUEST_IRQ_FAILED 0x04
5097 +#define I2S_REG_SETUP_FAILED 0x08
5099 +#define I2S_STATISTIC
5100 +//#define I2S_HW_INTERRUPT_EN
5101 +//#define I2S_SW_IRQ_EN
5102 +#define I2S_MAJOR 234
5104 +/* parameter for ALSA */
5105 +/*GDMA for I2S Status*/
5106 +#define GDMA_I2S_DIS (0)
5107 +#define GDMA_I2S_EN (1)
5110 +typedef struct i2s_status_t
5116 + int txbuffer_unrun;
5117 + int txbuffer_ovrun;
5124 + int rxbuffer_unrun;
5125 + int rxbuffer_ovrun;
5130 +typedef struct i2s_config_t
5146 + /* parameters fo ALSA */
5148 + int bALSAMMAPEnable;
5149 + unsigned char bTrigger[2];
5150 + unsigned char bPreTrigger[2];
5151 + unsigned char dmaStat[2];
5152 + unsigned char i2sStat[2];
5153 + unsigned int hw_base_frame[2];
5154 + struct snd_pcm_substream *pss[2];
5158 + wait_queue_head_t i2s_tx_qh, i2s_rx_qh;
5163 + u32 dma_unmask_status;
5164 + u32 dma_done_status;
5173 +#if defined (CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
5174 + int little_edn; /* test file's fmt: little endian->1; big endian->0 */
5175 + int sys_endian; /* kernal' system fmt: little endian->0; big endian->1 */
5186 + /* for I2S_CFG1 */
5203 + char* pMMAPBufPtr[MAX_I2S_PAGE*2];
5204 + char* pMMAPTxBufPtr[MAX_I2S_PAGE];
5205 + char* pMMAPRxBufPtr[MAX_I2S_PAGE];
5208 + u16* pPage0TxBuf16Ptr;
5209 + u8* pPage0TxBuf8ptr;
5212 + u16* pPage1TxBuf16Ptr;
5213 + u8* pPage1TxBuf8ptr;
5217 + u16* pPage0RxBuf16Ptr;
5218 + u8* pPage0RxBuf8ptr;
5221 + u16* pPage1RxBuf16Ptr;
5222 + u8* pPage1RxBuf8ptr;
5228 +void i2s_gen_test_pattern(void);
5229 +int i2s_mem_unmap(i2s_config_type* ptri2s_config);
5230 +int i2s_param_init(i2s_config_type* ptri2s_config);
5231 +int i2s_txbuf_alloc(i2s_config_type* ptri2s_config);
5232 +int i2s_rxbuf_alloc(i2s_config_type* ptri2s_config);
5233 +int i2s_txPagebuf_alloc(i2s_config_type* ptri2s_config);
5234 +int i2s_rxPagebuf_alloc(i2s_config_type* ptri2s_config);
5235 +int i2s_txbuf_free(i2s_config_type* ptri2s_config);
5236 +int i2s_rxbuf_free(i2s_config_type* ptri2s_config);
5237 +int i2s_txPagebuf_free(i2s_config_type* ptri2s_config);
5238 +int i2s_rxPagebuf_free(i2s_config_type* ptri2s_config);
5239 +int i2s_reset_tx_param(i2s_config_type* ptri2s_config);
5240 +int i2s_reset_rx_param(i2s_config_type* ptri2s_config);
5241 +int i2s_tx_config(i2s_config_type* ptri2s_config);
5242 +int i2s_rx_config(i2s_config_type* ptri2s_config);
5243 +int i2s_tx_enable(i2s_config_type* ptri2s_config);
5244 +int i2s_tx_disable(i2s_config_type* ptri2s_config);
5245 +int i2s_rx_enable(i2s_config_type* ptri2s_config);
5246 +int i2s_rx_disable(i2s_config_type* ptri2s_config);
5247 +int i2s_codec_enable(i2s_config_type* ptri2s_config);
5248 +int i2s_codec_disable(i2s_config_type* ptri2s_config);
5249 +int i2s_clock_enable(i2s_config_type* ptri2s_config);
5250 +int i2s_clock_disable(i2s_config_type* ptri2s_config);
5251 +int i2s_reset_config(i2s_config_type* ptri2s_config);
5252 +int i2s_refclk_disable(void);
5253 +int i2s_refclk_gpio_out_config(void);
5254 +int i2s_refclk_gpio_in_config(void);
5255 +int i2s_share_pin_config(i2s_config_type* ptri2s_config);
5256 +int i2s_share_pin_mt7623(i2s_config_type* ptri2s_config);
5257 +int i2s_master_clock_gpio_out_mt7623(void);
5258 +int i2s_slave_clock_gpio_in_mt7623(void);
5259 +int i2s_ws_config(i2s_config_type* ptri2s_config, unsigned long index);
5260 +int i2s_mode_config(u32 slave_en);
5261 +int i2s_codec_frequency_config(i2s_config_type* ptri2s_config, unsigned long index);
5262 +void i2s_tx_end_sleep_on(i2s_config_type* ptri2s_config);
5263 +void i2s_rx_end_sleep_on(i2s_config_type* ptri2s_config);
5265 +#if defined(CONFIG_I2S_MCLK_12MHZ)
5266 +int i2s_refclk_12m_enable(void);
5268 +#if defined(CONFIG_I2S_MCLK_12P288MHZ)
5269 +int i2s_refclk_12p288m_enable(void);
5272 +#if defined(MT7621_ASIC_BOARD)
5273 +int i2s_pll_config_mt7621(unsigned long index);
5274 +int i2s_pll_refclk_set(void);
5276 +#if defined(MT7623_ASIC_BOARD)
5277 +int i2s_pll_config_mt7623(unsigned long index);
5279 +#if defined(MT7628_ASIC_BOARD) || defined(CONFIG_ARCH_MT7623)
5280 +int i2s_driving_strength_adjust(void);
5282 +#if defined(I2S_STATISTIC)
5283 +void i2s_int_status(u32 dma_ch);
5285 +void i2s_dma_tx_handler(u32 dma_ch);
5286 +void i2s_dma_rx_handler(u32 dma_ch);
5287 +void i2s_dma_unmask_handler(u32 dma_ch);
5288 +void i2s_dma_mask_handler(u32 dma_ch);
5289 +void i2s_dma_tx_init(i2s_config_type* ptri2s_config);
5290 +void i2s_dma_rx_init(i2s_config_type* ptri2s_config);
5291 +void i2s_tx_task(unsigned long pData);
5292 +void i2s_rx_task(unsigned long pData);
5293 +void i2s_dma_tx_unmask_handler(u32 dma_ch);
5294 +void i2s_dma_rx_unmask_handler(u32 dma_ch);
5295 +int i2s_dma_tx_transf_data(i2s_config_type* ptri2s_config, u32 dma_ch);
5296 +int i2s_dma_tx_transf_zero(i2s_config_type* ptri2s_config, u32 dma_ch);
5297 +int i2s_dma_rx_transf_data(i2s_config_type* ptri2s_config, u32 dma_ch);
5298 +int i2s_dma_rx_transf_zero(i2s_config_type* ptri2s_config, u32 dma_ch);
5299 +void i2s_dma_tx_end_handle(i2s_config_type* ptri2s_config);
5300 +int i2s_dma_tx_soft_stop(i2s_config_type* ptri2s_config, u32 dma_ch);
5301 +int i2s_dma_rx_soft_stop(i2s_config_type* ptri2s_config, u32 dma_ch);
5303 +int i2s_page_prepare(i2s_config_type* ptri2s_config,int dir);
5304 +int i2s_page_release(i2s_config_type* ptri2s_config,int dir);
5305 +int gdma_En_Switch(i2s_config_type* ptri2s_config,int dir,int enabled);
5306 +int i2s_startup(void);
5307 +int i2s_audio_exchange(i2s_config_type* ptri2s_config,int dir,unsigned long arg);
5308 +void gdma_unmask_handler(u32 dma_ch);
5309 +char* i2s_memPool_Alloc(i2s_config_type* ptri2s_config,int dir);
5310 +void i2s_memPool_free(i2s_config_type* ptri2s_config,int dir);
5311 +u32 i2s_mmap_phys_addr(i2s_config_type* ptri2s_config);
5313 +#if !defined(CONFIG_I2S_TXRX)
5314 +#define GdmaI2sRx //GdmaI2sRx
5317 +#define RALINK_I2S_VERSION "1.0"
5318 +#define I2SDRV_DEVNAME "i2s0"
5320 +#endif /* __RALINK_I2S_H_ */
5322 diff --git a/sound/soc/mtk/i2s_debug.c b/sound/soc/mtk/i2s_debug.c
5323 new file mode 100644
5324 index 0000000..9f61b14
5326 +++ b/sound/soc/mtk/i2s_debug.c
5328 +#include <linux/init.h>
5329 +#include <linux/version.h>
5330 +#include <linux/module.h>
5331 +#include <linux/kernel.h> /* printk() */
5332 +#include "i2s_ctrl.h"
5333 +#include <linux/delay.h>
5334 +#include <linux/jiffies.h>
5335 +#include <linux/random.h>
5336 +#include <linux/slab.h>
5337 +#include <asm/uaccess.h> /* copy_from/to_user */
5339 +#if defined(CONFIG_SND_RALINK_SOC)
5340 +#include <sound/soc/mtk/mtk_audio_device.h>
5343 +#if defined(CONFIG_I2S_WM8750)
5344 +#include "../codec/i2c_wm8750.h"
5346 +#if defined(CONFIG_I2S_WM8751)
5347 +#include "../codec/i2c_wm8751.h"
5349 +#if defined(CONFIG_I2S_WM8960)
5350 +#include "i2c_wm8960.h"
5354 +//#define INTERNAL_LOOPBACK_DEBUG
5356 +extern unsigned long i2s_codec_12p288Mhz[11];
5357 +extern unsigned long i2s_codec_12Mhz[11];
5358 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
5359 +extern unsigned long i2s_inclk_int_16bit[13];
5360 +extern unsigned long i2s_inclk_comp_16bit[13];
5361 +extern unsigned long i2s_inclk_int_24bit[13];
5362 +extern unsigned long i2s_inclk_comp_24bit[13];
5364 +extern unsigned long i2s_inclk_int[11];
5365 +extern unsigned long i2s_inclk_comp[11];
5367 +extern int i2s_pll_config_mt7621(unsigned long index);
5368 +extern int i2s_pll_config_mt7623(unsigned long index);
5370 +#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
5371 +extern void audiohw_loopback(int fsel);
5372 +extern void audiohw_bypass(void);
5373 +extern int audiohw_set_lineout_vol(int Aout, int vol_l, int vol_r);
5374 +extern int audiohw_set_linein_vol(int vol_l, int vol_r);
5377 +#if defined(CONFIG_I2S_WM8960)
5378 +extern void audiohw_codec_exlbk(void);
5381 +unsigned long txbuffer[512] = {
5382 + 0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
5383 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
5384 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
5385 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
5386 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
5387 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
5388 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
5389 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 1
5390 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
5391 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
5392 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
5393 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
5394 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
5395 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
5396 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
5397 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 2
5398 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
5399 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
5400 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
5401 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
5402 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
5403 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
5404 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
5405 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 3
5406 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
5407 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
5408 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
5409 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
5410 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
5411 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
5412 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
5413 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 4
5414 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
5415 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
5416 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
5417 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
5418 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
5419 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
5420 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
5421 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 5
5422 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
5423 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
5424 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
5425 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
5426 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
5427 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
5428 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
5429 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 6
5430 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
5431 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
5432 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
5433 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
5434 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
5435 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
5436 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
5437 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 7
5438 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
5439 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
5440 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
5441 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
5442 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
5443 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
5444 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
5445 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00 //round 8
5448 +int i2s_debug_cmd(unsigned int cmd, unsigned long arg)
5450 + unsigned long data, index;
5451 + unsigned long *pTable;
5456 + case I2S_DEBUG_CLKGEN:
5457 + MSG("I2S_DEBUG_CLKGEN\n");
5458 +#if defined(CONFIG_RALINK_RT3052)
5459 + *(volatile unsigned long*)(0xB0000060) = 0x00000016;
5460 + *(volatile unsigned long*)(0xB0000030) = 0x00009E00;
5461 + *(volatile unsigned long*)(0xB0000A00) = 0xC0000040;
5462 +#elif defined(CONFIG_RALINK_RT3350)
5463 + *(volatile unsigned long*)(0xB0000060) = 0x00000018;
5464 + *(volatile unsigned long*)(0xB000002C) = 0x00000100;
5465 + *(volatile unsigned long*)(0xB0000030) = 0x00009E00;
5466 + *(volatile unsigned long*)(0xB0000A00) = 0xC0000040;
5467 +#elif defined(CONFIG_RALINK_RT3883)
5468 + *(volatile unsigned long*)(0xB0000060) = 0x00000018;
5469 + *(volatile unsigned long*)(0xB000002C) = 0x00003000;
5470 + *(volatile unsigned long*)(0xB0000A00) = 0xC1104040;
5471 + *(volatile unsigned long*)(0xB0000A24) = 0x00000027;
5472 + *(volatile unsigned long*)(0xB0000A20) = 0x80000020;
5473 +#elif (defined(CONFIG_RALINK_RT3352)||defined(CONFIG_RALINK_RT5350)) || defined (CONFIG_RALINK_RT6855)
5474 + *(volatile unsigned long*)(0xB0000060) = 0x00000018;
5475 + *(volatile unsigned long*)(0xB000002C) = 0x00000300;
5476 + *(volatile unsigned long*)(0xB0000A00) = 0xC1104040;
5477 + *(volatile unsigned long*)(0xB0000A24) = 0x00000027;
5478 + *(volatile unsigned long*)(0xB0000A20) = 0x80000020;
5479 +#elif defined(CONFIG_RALINK_RT6855A)
5480 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x860) = 0x00008080;
5481 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x82C) = 0x00000300;
5482 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0xC1104040;
5483 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x24) = 0x00000027;
5484 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x20) = 0x80000020;
5486 +//#error "I2S debug mode not support this Chip"
5489 + case I2S_DEBUG_INLBK:
5490 + MSG("I2S_DEBUG_INLBK\n");
5491 +#if defined(CONFIG_RALINK_MT7621)
5533 + i2s_pll_config_mt7621(index);
5534 +#elif defined(CONFIG_ARCH_MT7623)
5535 + i2s_pll_config_mt7623(11);
5539 +#if defined(CONFIG_RALINK_RT3052)
5542 +#if defined(CONFIG_RALINK_RT6855A)
5543 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x834) |= 0x00020000;
5544 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x834) &= 0xFFFDFFFF;
5545 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x0) &= 0x7FFFFFFF; //Rest I2S to default vaule
5546 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x860) |= 0x00008080;
5547 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x82C) = 0x00000300;
5548 +#elif defined(CONFIG_RALINK_MT7621)
5549 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x34) |= 0x00020000;
5550 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x34) &= 0xFFFDFFFF;
5551 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x0) &= 0x7FFFFFFF; //Rest I2S to default vaule
5552 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x60) = 0x00000010; //GPIO purpose selection
5553 +#elif defined(CONFIG_RALINK_MT7628)
5554 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x34) |= 0x00020000;
5555 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x34) &= 0xFFFDFFFF;
5556 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x0) &= 0x7FFFFFFF; //Rest I2S to default vaule
5557 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x60) &= ~((0x3)<<6); //GPIO purpose selection /*FIXME*/
5558 +#elif defined(CONFIG_ARCH_MT7623)
5559 + *(volatile unsigned long*)(0xFB000034) |= 0x00020000;
5560 + *(volatile unsigned long*)(0xFB000034) &= 0xFFFDFFFF;
5561 + *(volatile unsigned long*)(ETHDMASYS_I2S_BASE+0x0) &= 0x7FFFFFFF; //Rest I2S to default vaule
5563 + *(volatile unsigned long*)(0xF0005840) &= ~((0x7)<<12);
5564 + *(volatile unsigned long*)(0xF0005840) |= ((0x6)<<12);
5565 + *(volatile unsigned long*)(0xF0005840) &= ~((0x7)<<9);
5566 + *(volatile unsigned long*)(0xF0005840) |= ((0x6)<<9);
5567 + *(volatile unsigned long*)(0xF0005040) |= ((0x1)<<10);
5568 + *(volatile unsigned long*)(0xF0005040) |= ((0x1)<<9);
5570 + *(volatile unsigned long*)(0xF00057F0) &= ~((0x7)<<12);
5571 + *(volatile unsigned long*)(0xF00057F0) |= ((0x6)<<12);
5572 + *(volatile unsigned long*)(0xF0005030) |= ((0x1)<<1);
5574 + *(volatile unsigned long*)(0xF0005840) &= ~((0x7)<<6);
5575 + *(volatile unsigned long*)(0xF0005840) |= ((0x6)<<6);
5576 + *(volatile unsigned long*)(0xF0005040) &= ~((0x1)<<8);
5578 + *(volatile unsigned long*)(0xF00058F0) &= ~((0x7)<<3);
5579 + *(volatile unsigned long*)(0xF00058F0) |= ((0x6)<<3);
5580 + *(volatile unsigned long*)(0xF0005070) |= ((0x1)<<14);
5584 + *(volatile unsigned long*)(0xB0000034) |= 0x00020000;
5585 + *(volatile unsigned long*)(0xB0000034) &= 0xFFFDFFFF;
5586 + *(volatile unsigned long*)(0xB0000A00) &= 0x7FFFFFFF; //Rest I2S to default vaule
5587 + *(volatile unsigned long*)(0xB0000060) = 0x00000018;
5589 +#if defined(CONFIG_RALINK_RT3883)
5590 + *(volatile unsigned long*)(0xB000002C) = 0x00003000;
5591 +#elif defined(CONFIG_ARCH_MT7623)
5594 + *(volatile unsigned long*)(0xB000002C) = 0x00000300;
5597 +#if defined(CONFIG_RALINK_MT7621)
5598 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x18) = 0x80000000;
5599 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0xc1104040;
5601 + pTable = i2s_inclk_int;
5602 + data = pTable[index];
5603 + //*(volatile unsigned long*)(RALINK_I2S_BASE+0x24) = data;
5604 + i2s_outw(RALINK_I2S_BASE+0x24, data);
5606 + pTable = i2s_inclk_comp;
5607 + data = pTable[index];
5608 + //*(volatile unsigned long*)(RALINK_I2S_BASE+0x20) = data;
5609 + i2s_outw(RALINK_I2S_BASE+0x20, (data|0x80000000));
5610 +#elif defined(CONFIG_RALINK_MT7628)
5611 + index =11; /* SR: 192k */
5612 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x18) = 0x80000000;
5613 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0xc1104040;
5615 + pTable = i2s_inclk_int_16bit;
5616 + //pTable = i2s_inclk_int_24bit;
5617 + data = pTable[index];
5618 + //*(volatile unsigned long*)(RALINK_I2S_BASE+0x24) = data;
5619 + i2s_outw(RALINK_I2S_BASE+0x24, data);
5621 + pTable = i2s_inclk_comp_16bit;
5622 + //pTable = i2s_inclk_comp_24bit;
5623 + data = pTable[index];
5624 + //*(volatile unsigned long*)(RALINK_I2S_BASE+0x20) = data;
5625 + i2s_outw(RALINK_I2S_BASE+0x20, (data|0x80000000));
5627 +#elif defined(CONFIG_ARCH_MT7623)
5629 + *(volatile unsigned long*)(I2S_I2SCFG1) = 0x80000000;
5630 + *(volatile unsigned long*)(I2S_I2SCFG) = 0xE1104040;
5631 + *(volatile unsigned long*)(ETHDMASYS_SYSCTL_BASE+0x30) |= 0x00020000;
5632 + *(volatile unsigned long*)(ETHDMASYS_SYSCTL_BASE+0x2c) |= 0x00000080;
5634 + pTable = i2s_inclk_int_16bit;
5635 + //pTable = i2s_inclk_int_24bit;
5636 + data = pTable[index];
5637 + i2s_outw(I2S_DIVINT_CFG, data);
5639 + pTable = i2s_inclk_comp_16bit;
5640 + //pTable = i2s_inclk_comp_24bit;
5641 + data = pTable[index];
5642 + i2s_outw(I2S_DIVCOMP_CFG, (data|0x80000000));
5645 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x18) = 0x80000000;
5646 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0xC1104040;
5647 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x24) = 0x00000006;
5648 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x20) = 0x80000105;
5654 + unsigned long param[4];
5655 + unsigned long data;
5656 + //unsigned long data_tmp;
5657 + unsigned long ff_status;
5658 + //unsigned long* txbuffer;
5663 +#if defined (INTERNAL_LOOPBACK_DEBUG)
5666 + memset(param, 0, 4*sizeof(unsigned long) );
5667 + copy_from_user(param, (unsigned long*)arg, sizeof(long)*2);
5669 + txbuffer = (unsigned long*)kcalloc(param[0], sizeof(unsigned long), GFP_KERNEL);
5670 + if(txbuffer == NULL)
5674 + //ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C);
5675 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
5676 + printk("ff status=[0x%08X]\n",(u32)ff_status);
5679 + for(i = 0; i < param[0]; i++)
5683 + txbuffer[i] = 0x555A555A;
5684 + printk("%d: 0x%8lx\n", i, txbuffer[i]);
5688 + #if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,14)
5689 + srandom32(jiffies);
5690 + txbuffer[i] = random32()%(0x555A555A)+1;
5691 + //printk("%d: 0x%8x\n", i, txbuffer[i]);
5693 + //TODO:do we need to implement random32()
5694 + txbuffer[i] = 0x01010101;
5700 + for( i = 0 ; i < param[0] ; i ++ )
5702 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
5703 + #if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
5704 + if((ff_status&0xFF) > 0)
5706 + if((ff_status&0x0F) > 0)
5709 + *(volatile unsigned long*)(I2S_TX_FIFO_WREG) = txbuffer[i];
5715 + printk("[%d]NO TX FREE FIFO ST=[0x%08X]\n", i, (u32)ff_status);
5722 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
5723 + #if defined(CONFIG_RALINK_MT7628)
5724 + if(((ff_status>>8)&0xFF) > 0)
5726 + if(((ff_status>>4)&0x0F) > 0)
5729 + data = *(volatile unsigned long*)(I2S_RX_FIFO_RREG);
5730 + //data_tmp = *(volatile unsigned long*)(I2S_RX_FIFO_RREG);
5731 + //MSG("[0x%08X] vs [0x%08X]\n", (u32)data, (u32)data_tmp);
5735 + printk("*[%d]NO RX FREE FIFO ST=[0x%08X]\n", i, (u32)ff_status);
5739 + if (data == txbuffer[0])
5744 + if (enable_cnt==1)
5746 + if(data!= txbuffer[i-k])
5748 + MSG("[%d][0x%08X] vs [0x%08X]\n", (i-k), (u32)data, (u32)txbuffer[i-k]);
5752 + //MSG("**[%d][0x%08X] vs [0x%08X]\n" ,(i-k), (u32)data , (u32)txbuffer[i-k]);
5762 + for (j=0; j<k; j++)
5765 + //ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C);
5766 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
5767 + #if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
5768 + if(((ff_status>>8)&0xFF) > 0)
5770 + if(((ff_status>>4)&0x0F) > 0)
5773 + //data = *(volatile unsigned long*)(RALINK_I2S_BASE+0x14);
5774 + data = *(volatile unsigned long*)(I2S_RX_FIFO_RREG);
5778 + printk("*NO RX FREE FIFO ST=[0x%08X]\n", (u32)ff_status);
5782 + if(data!= txbuffer[temp+j])
5784 + MSG("[%d][0x%08X] vs [0x%08X]\n", (temp+j), (u32)data, (u32)txbuffer[temp+j]);
5788 + //MSG("&&[%d][0x%08X] vs [0x%08X]\n" ,(temp+j), (u32)data , (u32)txbuffer[temp+j]);
5792 + if ((temp+j)==128)
5794 + //ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C);
5795 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
5796 + //printk("[%d]FIFO ST=[0x%08X]\n", (temp+j), (u32)ff_status);
5801 +#if defined (INTERNAL_LOOPBACK_DEBUG)
5802 + for( i = 0 ; i < param[0] ; i ++ )
5804 + //ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C);
5805 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
5806 + #if defined(CONFIG_RALINK_MT7628)|| defined(CONFIG_ARCH_MT7623)
5807 + if((ff_status&0xFF) > 0)
5809 + if((ff_status&0x0F) > 0)
5812 + //*(volatile unsigned long*)(RALINK_I2S_BASE+0x10) = txbuffer[i];
5813 + *(volatile unsigned long*)(I2S_TX_FIFO_WREG) = txbuffer[i];
5819 + printk("[%d]NO TX FREE FIFO ST=[0x%08X]\n", i, (u32)ff_status);
5826 + //ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C);
5827 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
5828 + #if defined(CONFIG_RALINK_MT7628)|| defined(CONFIG_ARCH_MT7623)
5829 + if(((ff_status>>8)&0xFF) > 0)
5831 + if(((ff_status>>4)&0x0F) > 0)
5834 + //data = *(volatile unsigned long*)(RALINK_I2S_BASE+0x14);
5835 + data = *(volatile unsigned long*)(I2S_RX_FIFO_RREG);
5839 + printk("*[%d]NO RX FREE FIFO ST=[0x%08X]\n", i, (u32)ff_status);
5844 + if(data!= txbuffer[i])
5846 + MSG("[%d][0x%08X] vs [0x%08X]\n", (i), (u32)data, (u32)txbuffer[i]);
5850 + MSG("**[%d][0x%08X] vs [0x%08X]\n" ,(i), (u32)data , (u32)txbuffer[i]);
5858 + printk("Pattern match done count2=%d.\n", count2);
5860 + printk("Pattern match done count=%d.\n", count);
5863 +#if defined(CONFIG_ARCH_MT7623)
5864 + *(volatile unsigned long*)(0xFB000034) |= 0x00020000;
5865 + *(volatile unsigned long*)(0xFB000034) &= 0xFFFDFFFF;
5866 + *(volatile unsigned long*)(ETHDMASYS_I2S_BASE+0x0) &= 0x7FFFFFFF; //Rest I2S to default vaule
5869 +#if !defined(CONFIG_RALINK_RT3052)
5872 + case I2S_DEBUG_EXLBK:
5873 + MSG("I2S_DEBUG_EXLBK\n");
5874 +#if !defined(CONFIG_ARCH_MT7623)
5913 +#if defined(CONFIG_RALINK_RT3052)
5916 +#if defined(CONFIG_RALINK_RT6855A)
5917 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x860) = 0x00008080;
5918 + //*(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x82C) = 0x00000300;
5920 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x60) = 0x00000018;
5921 +#if defined(CONFIG_RALINK_RT3883)
5922 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x2C) = 0x00003000;
5924 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x2C) = 0x00000300;
5928 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x18) = 0x40000000;
5929 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0x81104040;
5930 +#if defined(CONFIG_RALINK_MT7628)
5931 + pTable = i2s_inclk_int_16bit;
5933 + pTable = i2s_inclk_int;
5935 + data = (volatile unsigned long)(pTable[index]);
5936 + i2s_outw(I2S_DIVINT_CFG, data);
5937 +#if defined(CONFIG_RALINK_MT7628)
5938 + pTable = i2s_inclk_comp_16bit;
5940 + pTable = i2s_inclk_comp;
5942 + data = (volatile unsigned long)(pTable[index]);
5943 + data |= REGBIT(1, I2S_CLKDIV_EN);
5944 + i2s_outw(I2S_DIVCOMP_CFG, data);
5946 + #if defined(CONFIG_I2S_MCLK_12MHZ)
5947 + pTable = i2s_codec_12Mhz;
5948 + #if defined(CONFIG_I2S_WM8960)
5949 + data = pTable[index];
5951 + data = pTable[index]|0x01;
5954 + pTable = i2s_codec_12p288Mhz;
5955 + data = pTable[index];
5958 + #if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
5959 + audiohw_preinit();
5963 + #if defined (CONFIG_I2S_WM8960)
5964 + audiohw_postinit(1, 1, 1, 1, 0); // for codec apll enable, 16 bit word length
5965 + #elif defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
5966 + audiohw_postinit(1, 1, 1, 0); // for 16 bit word length
5970 + #if defined (CONFIG_I2S_WM8960)
5971 + audiohw_set_frequency(data, 1); // for codec apll enable
5972 + #elif defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
5973 + audiohw_set_frequency(data|0x1);
5977 + #if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
5978 + audiohw_set_lineout_vol(1, 100, 100);
5979 + audiohw_set_linein_vol(100, 100);
5983 + #if defined(CONFIG_I2S_TXRX)
5984 + //audiohw_loopback(data);
5986 + #if !defined(CONFIG_RALINK_RT3052)
5990 + case I2S_DEBUG_CODECBYPASS:
5991 + #if defined(CONFIG_I2S_TXRX)
5992 + #if defined(CONFIG_RALINK_MT7628)
5993 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
5994 + //data &= ~(0x3<<4);
5995 + data &= ~(0x3<<6);
5996 + data &= ~(0x3<<16);
5997 + data &= ~(0x1<<14);
5998 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
6000 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
6001 + data &= ~(0x07<<9);
6002 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
6005 + #if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
6006 + audiohw_bypass(); /* did not work */
6010 + case I2S_DEBUG_FMT:
6012 + case I2S_DEBUG_RESET:
6014 +#if defined(CONFIG_I2S_WM8960)
6015 + case I2S_DEBUG_CODEC_EXLBK:
6016 + audiohw_codec_exlbk();
6020 + MSG("Not support this debug cmd [%d]\n", cmd);
6026 diff --git a/sound/soc/mtk/mt76xx_i2s.c b/sound/soc/mtk/mt76xx_i2s.c
6027 new file mode 100644
6028 index 0000000..7615b51
6030 +++ b/sound/soc/mtk/mt76xx_i2s.c
6035 + * Created on: 2013/8/20
6036 + * Author: MTK04880
6038 +#include <linux/init.h>
6039 +#include <linux/version.h>
6040 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
6041 +#include <linux/sched.h>
6043 +#include <linux/module.h>
6044 +#include <linux/kernel.h> /* printk() */
6045 +#include <linux/slab.h> /* kmalloc() */
6046 +#include <linux/fs.h> /* everything... */
6047 +#include <linux/errno.h> /* error codes */
6048 +#include <linux/types.h> /* size_t */
6049 +#include <linux/proc_fs.h>
6050 +#include <linux/fcntl.h> /* O_ACCMODE */
6051 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36)
6052 +#include <asm/system.h> /* cli(), *_flags */
6054 +#include <asm/uaccess.h> /* copy_from/to_user */
6055 +#include <linux/interrupt.h>
6056 +#include <linux/mm.h>
6057 +#include <linux/dma-mapping.h>
6058 +#include <sound/core.h>
6059 +#include <linux/pci.h>
6060 +#include <sound/pcm.h>
6061 +#include <sound/pcm_params.h>
6062 +#include <sound/soc.h>
6063 +#include <sound/soc-dapm.h>
6064 +#include <sound/initval.h>
6065 +#include "ralink_gdma.h"
6066 +#include "mt76xx_i2s.h"
6068 +/****************************/
6069 +/*GLOBAL VARIABLE DEFINITION*/
6070 +/****************************/
6071 +extern i2s_config_type* pi2s_config;
6073 +/****************************/
6074 +/*FUNCTION DECLRATION */
6075 +/****************************/
6076 +static int mt76xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai,\
6077 + unsigned int fmt);
6079 +//static int mt76xx_i2s_shutdown(struct snd_pcm_substream *substream,
6080 +// struct snd_soc_dai *dai);
6081 +static int mt76xx_i2s_startup(struct snd_pcm_substream *substream,
6082 + struct snd_soc_dai *dai);
6083 +static int mt76xx_i2s_hw_params(struct snd_pcm_substream *substream,\
6084 + struct snd_pcm_hw_params *params,\
6085 + struct snd_soc_dai *dai);
6086 +static int mt76xx_i2s_play_prepare(struct snd_pcm_substream *substream,struct snd_soc_dai *dai);
6087 +static int mt76xx_i2s_rec_prepare(struct snd_pcm_substream *substream,struct snd_soc_dai *dai);
6088 +static int mt76xx_i2s_hw_free(struct snd_pcm_substream *substream,struct snd_soc_dai *dai);
6089 +static int mt76xx_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai);
6091 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,20)
6092 +static int mt76xx_i2s_drv_probe(struct platform_device *pdev);
6093 +static int mt76xx_i2s_drv_remove(struct platform_device *pdev);
6095 +/****************************/
6096 +/*STRUCTURE DEFINITION */
6097 +/****************************/
6100 +static struct snd_soc_dai_ops mt76xx_i2s_dai_ops = {
6101 + .startup = mt76xx_i2s_startup,
6102 + .hw_params = mt76xx_i2s_hw_params,
6103 + .hw_free = mt76xx_i2s_hw_free,
6104 + //.shutdown = mt76xx_i2s_shutdown,
6105 + .prepare = mt76xx_i2s_prepare,
6106 + .set_fmt = mt76xx_i2s_set_fmt,
6107 + //.set_sysclk = mt76xx_i2s_set_sysclk,
6110 +const struct snd_soc_component_driver mt76xx_i2s_component = {
6111 + .name = "mt76xx-i2s",
6114 +struct snd_soc_dai_driver mt76xx_i2s_dai = {
6116 + .channels_min = 1,
6117 + .channels_max = 2,
6118 + .rates = (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_11025|\
6119 + SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_22050|SNDRV_PCM_RATE_32000|\
6120 + SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000),
6122 + .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
6123 + SNDRV_PCM_FMTBIT_S24_LE),
6126 + .channels_min = 1,
6127 + .channels_max = 2,
6128 + .rates = (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_11025|\
6129 + SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_22050|SNDRV_PCM_RATE_32000|\
6130 + SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000),
6131 + .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
6132 + SNDRV_PCM_FMTBIT_S24_LE),
6134 + .ops = &mt76xx_i2s_dai_ops,
6135 + .symmetric_rates = 1,
6138 +/****************************/
6140 +/****************************/
6142 +static int mt76xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
6146 + //printk("******* %s *******\n", __func__);
6150 +static int mt76xx_i2s_play_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
6152 + //printk("******* %s *******\n", __func__);
6153 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
6154 + rtd->pss[SNDRV_PCM_STREAM_PLAYBACK] = substream;
6155 + if(! rtd->i2sStat[SNDRV_PCM_STREAM_PLAYBACK]){
6156 + i2s_reset_tx_param( rtd);
6157 + i2s_tx_config( rtd);
6158 + gdma_En_Switch(rtd, STREAM_PLAYBACK, GDMA_I2S_EN);
6160 + if( rtd->bRxDMAEnable==0)
6161 + i2s_clock_enable( rtd);
6163 + i2s_tx_enable( rtd);
6164 + rtd->i2sStat[SNDRV_PCM_STREAM_PLAYBACK] = 1;
6165 + MSG("I2S_TXENABLE done\n");
6171 +static int mt76xx_i2s_rec_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
6174 + //printk("******* %s *******\n", __func__);
6175 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
6176 + rtd->pss[SNDRV_PCM_STREAM_CAPTURE] = substream;
6177 + if(! rtd->i2sStat[SNDRV_PCM_STREAM_CAPTURE]) {
6178 + i2s_reset_rx_param(rtd);
6179 + i2s_rx_config(rtd);
6180 + gdma_En_Switch(rtd, STREAM_CAPTURE, GDMA_I2S_EN);
6182 + if(rtd->bTxDMAEnable==0)
6183 + i2s_clock_enable(rtd);
6185 + i2s_rx_enable(rtd);
6186 + rtd->i2sStat[SNDRV_PCM_STREAM_CAPTURE] = 1;
6191 +/*static int mt76xx_i2s_shutdown(struct snd_pcm_substream *substream,
6192 + struct snd_soc_dai *dai)
6194 + //i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
6195 + //printk("******* %s *******\n", __func__);
6199 +static int mt76xx_i2s_startup(struct snd_pcm_substream *substream,
6200 + struct snd_soc_dai *dai)
6203 + //printk("******* %s *******\n", __func__);
6204 + if((!pi2s_config->i2sStat[SNDRV_PCM_STREAM_PLAYBACK]) && (!pi2s_config->i2sStat[SNDRV_PCM_STREAM_CAPTURE])){
6208 + i2s_reset_config(pi2s_config);
6210 + substream->runtime->private_data = pi2s_config;
6214 +static int mt76xx_i2s_hw_params(struct snd_pcm_substream *substream,\
6215 + struct snd_pcm_hw_params *params,\
6216 + struct snd_soc_dai *dai){
6217 + unsigned int srate = 0;
6218 + //unsigned long data;
6219 + struct snd_pcm_runtime *runtime = substream->runtime;
6220 + i2s_config_type* rtd = runtime->private_data;
6222 + //printk("******* %s *******\n", __func__);
6223 + switch(params_rate(params)){
6241 + //MSG("audio sampling rate %u should be %d ~ %d Hz\n", (u32)params_rate(params), MIN_SRATE_HZ, MAX_SRATE_HZ);
6245 + if((rtd->bRxDMAEnable != GDMA_I2S_EN) && (rtd->bTxDMAEnable != GDMA_I2S_EN)){
6246 + rtd->srate = srate;
6247 + MSG("set audio sampling rate to %d Hz\n", rtd->srate);
6253 +static int mt76xx_i2s_hw_free(struct snd_pcm_substream *substream,struct snd_soc_dai *dai){
6255 + //printk("******* %s *******\n", __func__);
6256 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
6257 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
6258 + if(rtd->i2sStat[SNDRV_PCM_STREAM_PLAYBACK]){
6259 + MSG("I2S_TXDISABLE\n");
6260 + i2s_reset_tx_param(rtd);
6262 + if((rtd->bRxDMAEnable==0)&&(rtd->bTxDMAEnable==0)){
6263 + i2s_clock_disable(rtd);
6265 + rtd->i2sStat[SNDRV_PCM_STREAM_PLAYBACK] = 0;
6269 + if(rtd->i2sStat[SNDRV_PCM_STREAM_CAPTURE]){
6270 + MSG("I2S_RXDISABLE\n");
6271 + i2s_reset_rx_param(rtd);
6273 + if((rtd->bRxDMAEnable==0)&&(rtd->bTxDMAEnable==0)){
6274 + i2s_clock_disable(rtd);
6276 + rtd->i2sStat[SNDRV_PCM_STREAM_CAPTURE] = 0;
6281 +static int mt76xx_i2s_prepare(struct snd_pcm_substream *substream,struct snd_soc_dai *dai)
6284 + //printk("******* %s *******\n", __func__);
6285 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
6286 + return mt76xx_i2s_play_prepare(substream, dai);
6288 + return mt76xx_i2s_rec_prepare(substream, dai);
6293 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,20)
6294 +static int mt76xx_i2s_drv_probe(struct platform_device *pdev)
6296 + //printk("****** %s ******\n", __func__);
6297 + return snd_soc_register_component(&pdev->dev, &mt76xx_i2s_component,
6298 + &mt76xx_i2s_dai, 1);
6301 +static int mt76xx_i2s_drv_remove(struct platform_device *pdev)
6303 + snd_soc_unregister_component(&pdev->dev);
6307 +static struct platform_driver mt76xx_i2s_driver = {
6308 + .probe = mt76xx_i2s_drv_probe,
6309 + .remove = mt76xx_i2s_drv_remove,
6311 + .name = "mt76xx-i2s",
6312 + .owner = THIS_MODULE,
6316 +static int __init mt76xx_i2s_init(void)
6319 + //printk("****** %s ******\n", __func__);
6320 + return platform_driver_register(&mt76xx_i2s_driver);
6323 +static void __exit mt76xx_i2s_exit(void)
6325 + //printk("****** %s ******\n", __func__);
6326 + platform_driver_unregister(&mt76xx_i2s_driver);
6329 +module_init(mt76xx_i2s_init);
6330 +module_exit(mt76xx_i2s_exit);
6332 +MODULE_AUTHOR("Dora Chen");
6333 +MODULE_DESCRIPTION("Stretch MT76xx I2S Interface");
6334 +MODULE_LICENSE("GPL");
6336 diff --git a/sound/soc/mtk/mt76xx_i2s.h b/sound/soc/mtk/mt76xx_i2s.h
6337 new file mode 100644
6338 index 0000000..9ae0e50
6340 +++ b/sound/soc/mtk/mt76xx_i2s.h
6345 + * Created on: 2013/8/20
6346 + * Author: MTK04880
6354 +//#include <asm/rt2880/rt_mmap.h>
6355 +#include <linux/fs.h>
6358 +#include "i2s_ctrl.h"
6359 +#endif /* MTK_I2S_H_ */
6360 diff --git a/sound/soc/mtk/mt76xx_machine.c b/sound/soc/mtk/mt76xx_machine.c
6361 new file mode 100644
6362 index 0000000..00d2145
6364 +++ b/sound/soc/mtk/mt76xx_machine.c
6367 + * mt76xx_machine.c
6370 +#include <linux/init.h>
6371 +#include <linux/version.h>
6372 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
6373 +#include <linux/sched.h>
6375 +#include <linux/module.h>
6376 +#include <linux/kernel.h> /* printk() */
6377 +#include <linux/slab.h> /* kmalloc() */
6378 +#include <linux/fs.h> /* everything... */
6379 +#include <linux/errno.h> /* error codes */
6380 +#include <linux/types.h> /* size_t */
6381 +#include <linux/proc_fs.h>
6382 +#include <linux/fcntl.h> /* O_ACCMODE */
6383 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36)
6384 +#include <asm/system.h> /* cli(), *_flags */
6386 +#include <asm/uaccess.h> /* copy_from/to_user */
6387 +#include <linux/interrupt.h>
6388 +#include <linux/mm.h>
6389 +#include <linux/dma-mapping.h>
6390 +#include <sound/core.h>
6391 +#include <linux/pci.h>
6392 +#include <sound/pcm.h>
6393 +#include <sound/pcm_params.h>
6394 +#include <sound/soc.h>
6395 +#include <sound/soc-dapm.h>
6396 +#include <sound/initval.h>
6397 +#include <linux/i2c.h>
6398 +#include <linux/ioport.h>
6399 +#include <linux/delay.h>
6400 +#include "ralink_gdma.h"
6401 +#include "mt76xx_i2s.h"
6402 +#include "mt76xx_machine.h"
6403 +#if defined(CONFIG_SND_SOC_WM8960)
6404 +#include "../codecs/wm8960.h"
6407 +#define I2C_AUDIO_DEV_ID (0)
6408 +/****************************/
6409 +/*FUNCTION DECLRATION */
6410 +/****************************/
6411 +extern unsigned long i2s_codec_12p288Mhz[11];
6412 +extern unsigned long i2s_codec_12Mhz[11];
6415 +static int mt76xx_codec_clock_hwparams(struct snd_pcm_substream *substream,\
6416 + struct snd_pcm_hw_params *params);
6417 +static int mt76xx_codec_startup(struct snd_pcm_substream *substream);
6418 +static int mt76xx_codec_init(struct snd_soc_pcm_runtime *rtd);
6419 +extern struct snd_soc_dai_driver mt76xx_i2s_dai;
6420 +extern struct snd_soc_platform_driver mt76xx_soc_platform;
6421 +struct platform_device *mt76xx_audio_device;
6423 +#if defined(CONFIG_SND_SOC_WM8960)
6424 +extern struct snd_soc_dai wm8960_dai;
6425 +extern struct snd_soc_codec_device soc_codec_dev_wm8960;
6428 +static struct snd_soc_ops mtk_audio_ops = {
6429 + .hw_params = mt76xx_codec_clock_hwparams,
6430 + .startup = mt76xx_codec_startup,
6433 +static struct snd_soc_dai_link mtk_audio_dai = {
6434 + .name = "mtk_dai",
6435 + .stream_name = "WMserious PCM",
6436 + .cpu_dai_name = "mt76xx-i2s",
6437 + .codec_dai_name = "wm8960-hifi",
6438 + .codec_name = "wm8960.0-001a",
6439 + .platform_name = "mt76xx-pcm",
6440 + .ignore_pmdown_time = true,
6441 + .init = mt76xx_codec_init,
6442 + .ops = &mtk_audio_ops,
6445 +static struct snd_soc_card mtk_audio_card = {
6446 + .name = "MTK APSoC I2S",
6447 + .owner = THIS_MODULE,
6448 + .dai_link = &mtk_audio_dai,//I2S/Codec
6452 +static int mt76xx_codec_clock_hwparams(struct snd_pcm_substream *substream,
6453 + struct snd_pcm_hw_params *params)
6455 + struct snd_soc_pcm_runtime *p = substream->private_data;
6456 + struct snd_soc_dai *codec_dai = p->codec_dai;
6457 + struct snd_pcm_runtime *runtime = substream->runtime;
6458 + i2s_config_type* rtd = runtime->private_data;
6459 + unsigned long data,index = 0;
6460 + unsigned long* pTable;
6461 + int mclk,ret,targetClk = 0;
6463 + /*For duplex mode, avoid setting twice.*/
6464 + if((rtd->bRxDMAEnable == GDMA_I2S_EN) || (rtd->bTxDMAEnable == GDMA_I2S_EN))
6466 +#if defined(CONFIG_I2S_MCLK_12MHZ)
6468 +#elif defined(CONFIG_I2S_MCLK_12P288MHZ)
6473 + //snd_soc_dai_set_sysclk(codec_dai,0,mclk, SND_SOC_CLOCK_IN);
6475 + switch(params_rate(params)){
6478 + targetClk = 12288000;
6482 + targetClk = 12288000;
6486 + targetClk = 12288000;
6490 + targetClk = 12288000;
6494 + targetClk = 12288000;
6498 + targetClk = 12288000;
6502 + targetClk = 11289600;
6506 + targetClk = 11289600;
6510 + targetClk = 11289600;
6514 + targetClk = 11289600;
6518 + targetClk = 11289600;
6522 + targetClk = 12288000;
6523 + //MSG("audio sampling rate %u should be %d ~ %d Hz\n", (u32)params_rate(params), MIN_SRATE_HZ, MAX_SRATE_HZ);
6526 +#if defined(CONFIG_SND_SOC_WM8960)
6528 + * There is a fixed divide by 4 in the PLL and a selectable
6529 + * divide by N after the PLL which should be set to divide by 2 to meet this requirement.
6531 + ret = snd_soc_dai_set_pll(codec_dai, 0, 0,mclk, targetClk*2);
6532 + /* From app notes: allow Vref to stabilize to reduce clicks */
6533 + if(rtd->slave_en){
6534 + //printk("WM8960 is in master mode\n");
6535 + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_DCLKDIV, 0x1c4);
6536 + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_SYSCLKDIV, 0x5);
6540 + if(!rtd->slave_en)
6541 + snd_soc_dai_set_fmt(codec_dai,SND_SOC_DAIFMT_CBS_CFS|SND_SOC_DAIFMT_I2S|SND_SOC_DAIFMT_NB_NF);
6543 + snd_soc_dai_set_fmt(codec_dai,SND_SOC_DAIFMT_CBM_CFM|SND_SOC_DAIFMT_I2S|SND_SOC_DAIFMT_NB_NF);
6547 +#if defined(CONFIG_SND_SOC_WM8960)
6548 +#if defined(CONFIG_I2S_MCLK_12MHZ)
6549 + pTable = i2s_codec_12Mhz;
6550 + data = pTable[index];
6552 + pTable = i2s_codec_12p288Mhz;
6553 + data = pTable[index];
6555 + if(rtd->codec_pll_en)
6556 + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_DACDIV, (data<<3)|0x5);
6558 + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_DACDIV, (data<<3|0x4));
6564 +static int mt76xx_codec_startup(struct snd_pcm_substream *substream)
6566 + //printk("******* %s *******\n", __func__);
6569 +static int mt76xx_codec_init(struct snd_soc_pcm_runtime *rtd)
6572 + //printk("******* %s *******\n", __func__);
6576 +static struct i2c_board_info i2c_board_info[] = {
6578 +#if defined(CONFIG_SND_SOC_WM8750)
6579 + I2C_BOARD_INFO("wm8750", (0x36 >> 1)),
6580 +#elif defined(CONFIG_SND_SOC_WM8960)
6581 + I2C_BOARD_INFO("codec_wm8960", (0x34)),
6583 + I2C_BOARD_INFO("wm8960", (0x34 >> 1)),
6588 +static struct platform_device *soc_mtk_i2s_dev;
6589 +static struct platform_device *soc_mtk_pcm_dev;
6591 +static int __init mt76xx_machine_init(void)
6593 + //struct snd_soc_device *socdev = &mtk_audio_devdata;
6594 + //struct i2c_adapter *adapter = NULL;
6595 + //struct i2c_client *client = NULL;
6597 + struct i2c_adapter *adapter = NULL;
6598 + struct i2c_client *client = NULL;
6600 + adapter = i2c_get_adapter(I2C_AUDIO_DEV_ID);
6603 + client = i2c_new_device(adapter, &i2c_board_info[0]);
6606 + i2c_get_clientdata(client);
6608 + client = i2c_new_device(adapter, &i2c_board_info[1]);
6611 + i2c_get_clientdata(client);
6613 + i2c_put_adapter(adapter);
6616 + platform_device_register_simple("mt76xx-i2s", -1, NULL, 0);
6617 + if (IS_ERR(soc_mtk_i2s_dev))
6618 + return PTR_ERR(soc_mtk_i2s_dev);
6621 + platform_device_register_simple("mt76xx-pcm", -1, NULL, 0);
6622 + if (IS_ERR(soc_mtk_pcm_dev))
6623 + return PTR_ERR(soc_mtk_pcm_dev);
6625 + mt76xx_audio_device = platform_device_alloc("soc-audio",-1);
6626 + if (mt76xx_audio_device == NULL) {
6628 + goto err_device_alloc;
6630 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
6631 + platform_set_drvdata(mt76xx_audio_device, &mtk_audio_card);
6633 + platform_set_drvdata(mt76xx_audio_device, &mtk_audio_devdata);
6634 + mtk_audio_devdata.dev = &mt76xx_audio_device->dev;
6637 + /*Ralink I2S register process end*/
6638 + ret = platform_device_add(mt76xx_audio_device);
6640 + printk("mtk audio device : platform_device_add failed (%d)\n",ret);
6641 + goto err_device_add;
6644 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
6646 + snd_soc_register_dai(&mt76xx_i2s_dai);
6652 + if (mt76xx_audio_device!= NULL) {
6653 + platform_device_put(mt76xx_audio_device);
6654 + mt76xx_audio_device = NULL;
6661 +static void __exit mt76xx_machine_exit(void)
6664 + platform_device_unregister(mt76xx_audio_device);
6665 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,20)
6667 +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
6668 + snd_soc_unregister_platform(&mt76xx_audio_device->dev);
6670 + snd_soc_unregister_platform(&mt76xx_soc_platform);
6672 + platform_device_unregister(soc_mtk_i2s_dev);
6673 + platform_device_unregister(soc_mtk_pcm_dev);
6675 + mt76xx_audio_device = NULL;
6678 +//module_init(mt76xx_machine_init);
6679 +late_initcall(mt76xx_machine_init);
6680 +module_exit(mt76xx_machine_exit);
6681 +//EXPORT_SYMBOL_GPL(mt76xx_soc_platform);
6682 +MODULE_LICENSE("GPL");
6683 diff --git a/sound/soc/mtk/mt76xx_machine.h b/sound/soc/mtk/mt76xx_machine.h
6684 new file mode 100644
6685 index 0000000..79532b5
6687 +++ b/sound/soc/mtk/mt76xx_machine.h
6690 + * mtk_audio_device.h
6692 + * Created on: 2013/10/23
6693 + * Author: MTK04880
6696 +#ifndef MT76XX_MACHINE_H_
6697 +#define MT76XX_MACHINE_H_
6698 +#include <sound/pcm.h>
6699 +#include <sound/pcm_params.h>
6700 +#include <sound/soc.h>
6701 +#include <sound/soc-dapm.h>
6704 +#ifdef CONFIG_I2S_MMAP
6705 +#undef CONFIG_I2S_MMAP
6709 +#endif /* MT76XX_MACHINE_H_ */
6710 diff --git a/sound/soc/mtk/mt76xx_pcm.c b/sound/soc/mtk/mt76xx_pcm.c
6711 new file mode 100644
6712 index 0000000..1100ee0
6714 +++ b/sound/soc/mtk/mt76xx_pcm.c
6719 + * Created on: 2013/9/6
6720 + * Author: MTK04880
6723 +#include <linux/init.h>
6724 +#include <linux/version.h>
6725 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
6726 +#include <linux/sched.h>
6728 +#include <linux/module.h>
6729 +#include <linux/kernel.h> /* printk() */
6730 +#include <linux/slab.h> /* kmalloc() */
6731 +#include <linux/fs.h> /* everything... */
6732 +#include <linux/errno.h> /* error codes */
6733 +#include <linux/types.h> /* size_t */
6734 +#include <linux/proc_fs.h>
6735 +#include <linux/fcntl.h> /* O_ACCMODE */
6736 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36)
6737 +#include <asm/system.h> /* cli(), *_flags */
6739 +#include <asm/uaccess.h> /* copy_from/to_user */
6740 +#include <linux/interrupt.h>
6741 +#include <linux/mm.h>
6742 +#include <linux/dma-mapping.h>
6743 +#include <sound/core.h>
6744 +#include <linux/pci.h>
6745 +#include <sound/pcm.h>
6746 +#include <sound/pcm_params.h>
6747 +#include <sound/soc.h>
6748 +#include <sound/soc-dapm.h>
6749 +#include <sound/initval.h>
6750 +#include "ralink_gdma.h"
6751 +#include "mt76xx_i2s.h"
6753 +#define GDMA_PAGE_SIZE I2S_PAGE_SIZE
6754 +#define GDMA_PAGE_NUM MAX_I2S_PAGE
6755 +#define GDMA_TOTAL_PAGE_SIZE I2S_TOTAL_PAGE_SIZE
6757 +dma_addr_t i2s_txdma_addr, i2s_rxdma_addr;
6758 +dma_addr_t i2s_mmap_addr[GDMA_PAGE_NUM*2];
6760 +extern struct tasklet_struct i2s_tx_tasklet;
6761 +extern struct tasklet_struct i2s_rx_tasklet;
6762 +extern int i2s_mmap_remap(struct vm_area_struct *vma, unsigned long size);
6763 +extern void i2s_tx_end_sleep_on(i2s_config_type* ptri2s_config);
6764 +extern void i2s_rx_end_sleep_on(i2s_config_type* ptri2s_config);
6766 +static int mt76xx_pcm_open(struct snd_pcm_substream *substream);
6767 +static int mt76xx_pcm_new(struct snd_soc_pcm_runtime *rtd);
6768 +static void mt76xx_pcm_free(struct snd_pcm *pcm);
6769 +static int mt76xx_pcm_close(struct snd_pcm_substream *substream);
6770 +static snd_pcm_uframes_t mt76xx_pcm_pointer(struct snd_pcm_substream *substream);
6771 +static int mt76xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
6772 +static int mt76xx_pcm_prepare(struct snd_pcm_substream *substream);
6773 +static int mt76xx_pcm_hw_params(struct snd_pcm_substream *substream,\
6774 + struct snd_pcm_hw_params *hw_params);
6775 +static int mt76xx_pcm_copy(struct snd_pcm_substream *substream, int channel,\
6776 + snd_pcm_uframes_t pos,void __user *buf, snd_pcm_uframes_t count);
6777 +static int mt76xx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma);
6778 +static int mt76xx_pcm_hw_free(struct snd_pcm_substream *substream);
6780 +static int mt76xx_pcm_free_dma_buffer(struct snd_pcm_substream *substream,int stream);
6781 +static int mt76xx_pcm_allocate_dma_buffer(struct snd_pcm_substream *substream,int stream);
6783 +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,10,20)
6784 +static int mt76xx_platform_drv_probe(struct platform_device *pdev);
6785 +static int mt76xx_platform_drv_remove(struct platform_device *pdev);
6788 +static const struct snd_pcm_hardware mt76xx_pcm_hwparam = {
6789 +#if defined(CONFIG_I2S_MMAP)
6790 + .info = (SNDRV_PCM_INFO_INTERLEAVED |
6791 + SNDRV_PCM_INFO_PAUSE |
6792 + SNDRV_PCM_INFO_RESUME |
6793 + SNDRV_PCM_INFO_MMAP |
6794 + SNDRV_PCM_INFO_MMAP_VALID),
6796 + .info = (SNDRV_PCM_INFO_INTERLEAVED |
6797 + SNDRV_PCM_INFO_PAUSE |
6798 + SNDRV_PCM_INFO_RESUME),
6800 + .formats = SNDRV_PCM_FMTBIT_S16_LE,
6801 + .period_bytes_min = GDMA_PAGE_SIZE,
6802 + .period_bytes_max = GDMA_PAGE_SIZE,
6804 + .periods_max = GDMA_PAGE_NUM,
6805 + .buffer_bytes_max = GDMA_TOTAL_PAGE_SIZE,
6808 +static struct snd_pcm_ops mt76xx_pcm_ops = {
6810 + .open = mt76xx_pcm_open,
6811 + .ioctl = snd_pcm_lib_ioctl,
6812 + .hw_params = mt76xx_pcm_hw_params,
6813 + .hw_free = mt76xx_pcm_hw_free,
6814 + .trigger = mt76xx_pcm_trigger,
6815 + .prepare = mt76xx_pcm_prepare,
6816 + .pointer = mt76xx_pcm_pointer,
6817 + .close = mt76xx_pcm_close,
6818 +#if defined(CONFIG_I2S_MMAP)
6819 + .mmap = mt76xx_pcm_mmap,
6821 + .copy = mt76xx_pcm_copy,
6823 +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,10,0)
6824 +struct snd_soc_platform_driver mt76xx_soc_platform = {
6825 + .ops = &mt76xx_pcm_ops,
6826 + .pcm_new = mt76xx_pcm_new,
6827 + .pcm_free = mt76xx_pcm_free,
6830 +struct snd_soc_platform mt76xx_soc_platform = {
6831 + .name = "mtk-dma",
6832 + .pcm_ops = &mt76xx_pcm_ops,
6833 + .pcm_new = mt76xx_pcm_new,
6834 + .pcm_free = mt76xx_pcm_free,
6838 +static int mt76xx_pcm_close(struct snd_pcm_substream *substream){
6840 + //printk("******* %s *********\n", __func__);
6844 +static snd_pcm_uframes_t mt76xx_pcm_pointer(struct snd_pcm_substream *substream)
6846 + struct snd_pcm_runtime *runtime = substream->runtime;
6847 + i2s_config_type* rtd = runtime->private_data;
6848 + unsigned int offset = 0;
6849 + //int buff_frame_bond = bytes_to_frames(runtime, GDMA_PAGE_SIZE);
6850 + //printk("\n******* %s *********\n", __func__);
6852 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
6853 + offset = bytes_to_frames(runtime, GDMA_PAGE_SIZE*rtd->tx_r_idx);
6854 + //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);
6857 + offset = bytes_to_frames(runtime, GDMA_PAGE_SIZE*rtd->rx_w_idx);
6858 + //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);
6864 +static int mt76xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
6867 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
6868 + //struct snd_pcm_runtime *runtime= substream->runtime;
6870 + //printk("******* %s *********\n", __func__);
6871 +/* printk("trigger cmd:%s\n",(cmd==SNDRV_PCM_TRIGGER_START)?"START":\
6872 + (cmd==SNDRV_PCM_TRIGGER_RESUME)?"RESUME":\
6873 + (cmd==SNDRV_PCM_TRIGGER_PAUSE_RELEASE)?"PAUSE_RELEASE":\
6874 + (cmd==SNDRV_PCM_TRIGGER_STOP)?"STOP":\
6875 + (cmd==SNDRV_PCM_TRIGGER_SUSPEND)?"SUSPEND":\
6876 + (cmd==SNDRV_PCM_TRIGGER_PAUSE_PUSH)?"PAUSE_PUSH":"default");
6879 + case SNDRV_PCM_TRIGGER_START:
6880 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
6881 + rtd->bTrigger[SNDRV_PCM_STREAM_PLAYBACK] = 1;
6883 + rtd->bTrigger[SNDRV_PCM_STREAM_CAPTURE] = 1;
6886 + case SNDRV_PCM_TRIGGER_STOP:
6887 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
6888 + rtd->bTrigger[SNDRV_PCM_STREAM_PLAYBACK] = 0;
6890 + rtd->bTrigger[SNDRV_PCM_STREAM_CAPTURE] = 0;
6893 + case SNDRV_PCM_TRIGGER_RESUME:
6894 + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
6895 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
6896 + rtd->tx_pause_en = 0;
6898 + rtd->rx_pause_en = 0;
6902 + case SNDRV_PCM_TRIGGER_SUSPEND:
6903 + case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
6904 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
6905 + rtd->tx_pause_en = 1;
6907 + rtd->rx_pause_en = 1;
6917 +static int mt76xx_pcm_copy(struct snd_pcm_substream *substream, int channel,\
6918 + snd_pcm_uframes_t pos,void __user *buf, snd_pcm_uframes_t count)
6920 + struct snd_pcm_runtime *runtime= substream->runtime;
6921 + i2s_config_type* rtd = runtime->private_data;
6924 + char *hwbuf = NULL;
6926 + //printk("******* %s *********\n", __func__);
6927 + hwbuf = runtime->dma_area + frames_to_bytes(runtime, pos);
6928 + //MSG("%s bur:%x\n",__func__,hwbuf);
6929 + //printk("hw_ptr:%d, buffer_size:%d, appl_prt:%d, boundary:%d\n",
6930 + // runtime->status->hw_ptr, runtime->buffer_size, runtime->control->appl_ptr, runtime->boundary);
6932 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
6933 + rtd->tx_w_idx = (rtd->tx_w_idx+1)%MAX_I2S_PAGE;
6934 + tx_w_idx = rtd->tx_w_idx;
6935 + //printk("put TB[%d - %x] for user write\n",rtd->tx_w_idx,pos);
6936 + copy_from_user(rtd->pMMAPTxBufPtr[tx_w_idx], (char*)buf, I2S_PAGE_SIZE);
6939 + rx_r_idx = rtd->rx_r_idx;
6940 + rtd->rx_r_idx = (rtd->rx_r_idx+1)%MAX_I2S_PAGE;
6941 + copy_to_user((char*)buf, rtd->pMMAPRxBufPtr[rx_r_idx], I2S_PAGE_SIZE);
6946 +static int mt76xx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma)
6949 + unsigned long size;
6951 + size = vma->vm_end-vma->vm_start;
6952 + printk("******* %s: size :%lx end:%lx start:%lx *******\n", __func__,size,vma->vm_end,vma->vm_start);
6953 + ret = i2s_mmap_remap(vma, size);
6959 +static int mt76xx_pcm_prepare(struct snd_pcm_substream *substream)
6961 + struct snd_pcm_runtime *runtime= substream->runtime;
6962 + i2s_config_type *rtd = (i2s_config_type*)runtime->private_data;
6963 + //runtime->buffer_size = GDMA_PAGE_NUM*GDMA_PAGE_SIZE;
6964 + //runtime->boundary = (GDMA_PAGE_NUM*GDMA_PAGE_SIZE)/4;
6966 + //printk("******* %s *******\n", __func__);
6967 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
6968 + //printk("===== %s:%s:%d =====\n", __FILE__, __func__, __LINE__);
6969 + mt76xx_pcm_allocate_dma_buffer(substream,SNDRV_PCM_STREAM_PLAYBACK);
6971 + if(! rtd->dmaStat[SNDRV_PCM_STREAM_PLAYBACK]){
6972 + i2s_page_prepare(rtd,STREAM_PLAYBACK);
6973 + tasklet_init(&i2s_tx_tasklet, i2s_tx_task, (u32)rtd);
6974 + rtd->dmaStat[SNDRV_PCM_STREAM_PLAYBACK] = 1;
6975 + gdma_unmask_handler(GDMA_I2S_TX0);
6978 + mt76xx_pcm_allocate_dma_buffer(substream,SNDRV_PCM_STREAM_CAPTURE);
6980 + if(! rtd->dmaStat[SNDRV_PCM_STREAM_CAPTURE]){
6981 + i2s_page_prepare(rtd,STREAM_CAPTURE); /* TX:enLabel=1; RX:enLabel=2 */
6982 + tasklet_init(&i2s_rx_tasklet, i2s_rx_task, (u32)rtd);
6983 + rtd->dmaStat[SNDRV_PCM_STREAM_CAPTURE] = 1;
6984 + gdma_unmask_handler(GDMA_I2S_RX0);
6992 +static int mt76xx_pcm_hw_params(struct snd_pcm_substream *substream,
6993 + struct snd_pcm_hw_params *hw_params)
6995 + /*struct snd_pcm_runtime *runtime = substream->runtime;
6996 + i2s_config_type *rtd = (i2s_config_type*)runtime->private_data;
7001 + //printk("******* %s *******\n", __func__);
7002 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
7003 + //i2s_page_prepare(rtd,STREAM_PLAYBACK);
7005 + //i2s_page_prepare(rtd,STREAM_CAPTURE);
7011 +static int mt76xx_pcm_hw_free(struct snd_pcm_substream *substream)
7013 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
7014 + //struct snd_dma_buffer *buf = &substream->dma_buffer;
7016 + //printk("******* %s *******\n", __func__);
7017 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
7018 + if(rtd->dmaStat[SNDRV_PCM_STREAM_PLAYBACK]){
7020 + gdma_En_Switch(rtd,STREAM_PLAYBACK,GDMA_I2S_DIS);
7021 + i2s_tx_end_sleep_on(rtd);
7022 + tasklet_kill(&i2s_tx_tasklet);
7023 + i2s_tx_disable(rtd);
7024 + //mt76xx_pcm_free_dma_buffer(substream,substream->stream);
7025 + i2s_page_release(rtd,STREAM_PLAYBACK);
7026 + rtd->dmaStat[SNDRV_PCM_STREAM_PLAYBACK] = 0;
7028 + mt76xx_pcm_free_dma_buffer(substream,substream->stream);
7031 + if(rtd->dmaStat[SNDRV_PCM_STREAM_CAPTURE]){
7033 + gdma_En_Switch(rtd,STREAM_CAPTURE,GDMA_I2S_DIS);
7034 + i2s_tx_end_sleep_on(rtd);
7035 + tasklet_kill(&i2s_rx_tasklet);
7036 + i2s_rx_disable(rtd);
7037 + //mt76xx_pcm_free_dma_buffer(substream,substream->stream);
7038 + i2s_page_release(rtd,STREAM_CAPTURE);
7039 + rtd->dmaStat[SNDRV_PCM_STREAM_CAPTURE] = 0;
7041 + mt76xx_pcm_free_dma_buffer(substream,substream->stream);
7046 +static int mt76xx_pcm_free_dma_buffer(struct snd_pcm_substream *substream,
7050 + //struct snd_pcm_substream *substream = pcm->streams[stream].substream;
7051 + struct snd_dma_buffer *buf = &substream->dma_buffer;
7052 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
7054 + //printk("******* %s *******\n", __func__);
7057 + if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
7058 + i2s_memPool_free(rtd,STREAM_PLAYBACK);
7060 + i2s_memPool_free(rtd,STREAM_CAPTURE);
7062 + snd_pcm_set_runtime_buffer(substream, NULL);
7066 +static int mt76xx_pcm_allocate_dma_buffer(struct snd_pcm_substream *substream,
7069 + //struct snd_pcm_substream *substream = pcm->streams[stream].substream;
7070 + struct snd_dma_buffer *buf = &substream->dma_buffer;
7071 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
7073 + //printk("******* %s *******\n", __func__);
7075 +#if defined(CONFIG_I2S_MMAP)
7076 + printk("\n############## MMAP ##############\n");
7077 + buf->dev.type = SNDRV_DMA_TYPE_DEV;
7079 + buf->dev.type = SNDRV_DMA_TYPE_UNKNOWN;
7081 + buf->dev.dev = NULL;
7082 + buf->private_data = NULL;
7083 + if(stream == SNDRV_PCM_STREAM_PLAYBACK)
7084 + buf->area = i2s_memPool_Alloc(rtd,STREAM_PLAYBACK);
7086 + buf->area = i2s_memPool_Alloc(rtd,STREAM_CAPTURE);
7090 + buf->bytes = GDMA_TOTAL_PAGE_SIZE;
7091 +#if defined(CONFIG_I2S_MMAP)
7092 + buf->addr = i2s_mmap_phys_addr(rtd);
7094 + snd_pcm_set_runtime_buffer(substream, buf);
7096 + //printk("Buffer have been allocated!\n");
7102 +static int mt76xx_pcm_open(struct snd_pcm_substream *substream)
7104 + struct snd_pcm_runtime *runtime= substream->runtime;
7105 + struct snd_dma_buffer *buf = &substream->dma_buffer;
7106 + int stream = substream->stream;
7109 + //printk("******* %s *******\n", __func__);
7110 + snd_soc_set_runtime_hwparams(substream, &mt76xx_pcm_hwparam);
7111 + /* ensure that buffer size is a multiple of period size */
7112 + ret = snd_pcm_hw_constraint_integer(runtime,
7113 + SNDRV_PCM_HW_PARAM_PERIODS);
7118 + if(stream == SNDRV_PCM_STREAM_PLAYBACK){
7119 + ret = mt76xx_pcm_allocate_dma_buffer(substream,
7120 + SNDRV_PCM_STREAM_PLAYBACK);
7123 + ret = mt76xx_pcm_allocate_dma_buffer(substream,
7124 + SNDRV_PCM_STREAM_CAPTURE);
7132 + memset(buf->area,0,sizeof(I2S_PAGE_SIZE*MAX_I2S_PAGE));
7140 +static int mt76xx_pcm_new(struct snd_soc_pcm_runtime *rtd)
7144 + //printk("******* %s *******\n", __func__);
7148 +static void mt76xx_pcm_free(struct snd_pcm *pcm)
7150 + /*struct snd_pcm_substream *substream;
7151 + struct snd_dma_buffer *buf;
7152 + i2s_config_type* rtd;
7155 + //printk("******* %s *******\n", __func__);
7159 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,20)
7160 +static int mt76xx_platform_drv_probe(struct platform_device *pdev)
7162 + //printk("******* %s *******\n", __func__);
7163 + return snd_soc_register_platform(&pdev->dev, &mt76xx_soc_platform);
7166 +static int mt76xx_platform_drv_remove(struct platform_device *pdev)
7168 + //printk("******* %s *******\n", __func__);
7169 + snd_soc_unregister_platform(&pdev->dev);
7173 +static struct platform_driver mt76xx_pcm_driver = {
7175 + .name = "mt76xx-pcm",
7176 + .owner = THIS_MODULE,
7179 + .probe = mt76xx_platform_drv_probe,
7180 + .remove = mt76xx_platform_drv_remove,
7183 +static int __init mt76xx_pcm_init(void)
7186 + printk("******* %s *******\n", __func__);
7187 + return platform_driver_register(&mt76xx_pcm_driver);
7190 +static void __exit mt76xx_pcm_exit(void)
7192 + platform_driver_unregister(&mt76xx_pcm_driver);
7195 +static int __init mt76xx_pcm_init(void)
7198 + printk("******* %s *******\n", __func__);
7199 + return snd_soc_register_platform(&mt76xx_soc_platform);
7202 +static void __exit mt76xx_pcm_exit(void)
7204 + printk("******* %s *******\n", __func__);
7205 + snd_soc_unregister_platform(&mt76xx_soc_platform);
7208 +module_init(mt76xx_pcm_init);
7209 +module_exit(mt76xx_pcm_exit);
7211 +MODULE_AUTHOR("Dora Chen");
7212 +MODULE_DESCRIPTION("MTK APSoC I2S DMA driver");
7213 +MODULE_LICENSE("GPL");
7215 diff --git a/sound/soc/mtk/ralink_gdma.c b/sound/soc/mtk/ralink_gdma.c
7216 new file mode 100644
7217 index 0000000..b385f05
7219 +++ b/sound/soc/mtk/ralink_gdma.c
7222 + ***************************************************************************
7223 + * Ralink Tech Inc.
7224 + * 5F., No.36, Taiyuan St., Jhubei City,
7225 + * Hsinchu County 302,
7228 + * (c) Copyright, Ralink Technology, Inc.
7230 + * This program is free software; you can redistribute it and/or modify it
7231 + * under the terms of the GNU General Public License as published by the
7232 + * Free Software Foundation; either version 2 of the License, or (at your
7233 + * option) any later version.
7235 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
7236 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
7237 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
7238 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
7239 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
7240 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
7241 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
7242 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7243 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
7244 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7246 + * You should have received a copy of the GNU General Public License along
7247 + * with this program; if not, write to the Free Software Foundation, Inc.,
7248 + * 675 Mass Ave, Cambridge, MA 02139, USA.
7251 + ***************************************************************************
7260 + -------- ---------- ----------------------------------------------
7261 + Name Date Modification logs
7262 + Steven Liu 2009-03-24 Support RT3883
7265 +#include <linux/init.h>
7266 +#include <linux/version.h>
7267 +#include <linux/module.h>
7268 +#include <linux/kernel.h>
7269 +#include <linux/interrupt.h>
7270 +#include <linux/fs.h>
7271 +#if defined (CONFIG_MIPS)
7272 + #include <asm/uaccess.h>
7273 + #include <asm/addrspace.h>
7276 +#include "ralink_gdma.h"
7280 + * Ch0 : Pcm0_Rx0 | Pcm0_Rx0 | ALL
7281 + * Ch1 : Pcm0_Rx1 | Pcm0_Rx1 | ALL
7282 + * Ch2 : Pcm0_Tx0 | Pcm0_Tx0 | ALL
7283 + * Ch3 : Pcm0_Tx1 | Pcm0_Tx1 | ALL
7284 + * Ch4 : Pcm1_Rx0 | I2S_Tx0 | ALL
7285 + * Ch5 : Pcm1_Rx1 | I2S_Tx1 | ALL
7286 + * Ch6 : Pcm1_Tx0 | ALL | ALL
7287 + * Ch7 : Pcm1_Tx1 | ALL | ALL
7290 + * Ch0 : Pcm0_Rx0 | Pcm0_Rx0 | ALL
7291 + * Ch1 : Pcm0_Rx1 | Pcm0_Rx1 | ALL
7292 + * Ch2 : Pcm0_Tx0 | Pcm0_Tx0 | ALL
7293 + * Ch3 : Pcm0_Tx1 | Pcm0_Tx1 | ALL
7294 + * Ch4 : Pcm1_Rx0 | I2S_Tx0 | ALL
7295 + * Ch5 : Pcm1_Rx1 | I2S_Tx1 | ALL
7296 + * Ch6 : Pcm1_Tx0 | I2S_Rx0 | ALL
7297 + * Ch7 : Pcm1_Tx1 | I2S_Rx1 | ALL
7298 + * Ch8 : ALL | ALL | ALL
7299 + * Ch9 : ALL | ALL | ALL
7300 + * Ch10 : ALL | ALL | ALL
7301 + * Ch11 : ALL | ALL | ALL
7302 + * Ch12 : ALL | ALL | ALL PCI TX
7303 + * Ch13 : ALL | ALL | ALL PCI RX
7304 + * Ch14 : ALL | ALL | ALL
7305 + * Ch15 : ALL | ALL | ALL
7309 +spinlock_t gdma_lock;
7310 +spinlock_t gdma_lock_mem;
7311 +spinlock_t gdma_int_lock;
7312 +void (*GdmaDoneIntCallback[MAX_GDMA_CHANNEL])(uint32_t);
7313 +void (*GdmaUnMaskIntCallback[MAX_GDMA_CHANNEL])(uint32_t);
7317 + * @brief Get free GDMA channel
7319 + * @param ChNum GDMA channel number
7320 + * @retval 1 channel is available
7321 + * @retval 0 channels are all busy
7323 +int _GdmaGetFreeCh(uint32_t *ChNum)
7325 + unsigned long flags;
7328 +#if defined (CONFIG_GDMA_DEBUG)
7329 + static uint32_t Ch_RR=0;
7332 + spin_lock_irqsave(&gdma_lock, flags);
7334 +#if defined (CONFIG_GDMA_PCM_ONLY)
7335 +#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)
7336 + for(Ch=14; Ch<MAX_GDMA_CHANNEL;Ch++) //channel 14~max_channe, channel 0~13 be usedl
7338 + for(Ch=MAX_GDMA_CHANNEL; Ch<MAX_GDMA_CHANNEL;Ch++) //no free channel
7340 +#elif defined (CONFIG_GDMA_PCM_I2S_OTHERS)
7341 +#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)
7342 + for(Ch=14; Ch<MAX_GDMA_CHANNEL;Ch++) //channel 14~max_channe, channel 0~13 be usedl
7344 + for(Ch=6; Ch<MAX_GDMA_CHANNEL;Ch++) //channel 6~max_channel
7346 +#elif defined (CONFIG_GDMA_EVERYBODY)
7347 + for(Ch=0; Ch<MAX_GDMA_CHANNEL;Ch++) //all channel
7348 +#elif defined (CONFIG_GDMA_DEBUG)
7349 + for(Ch=(Ch_RR++)%MAX_GDMA_CHANNEL; Ch<MAX_GDMA_CHANNEL;Ch++) //round robin
7352 + Data=GDMA_READ_REG(GDMA_CTRL_REG(Ch));
7354 + /* hardware will reset this bit if transaction is done.
7355 + * It means channel is free */
7356 + if((Data & (0x01<<CH_EBL_OFFSET))==0) {
7358 + spin_unlock_irqrestore(&gdma_lock, flags);
7359 + return 1; //Channel is free
7363 + spin_unlock_irqrestore(&gdma_lock, flags);
7364 + return 0; // Channels are all busy
7369 + * @brief Set channel is masked
7371 + * When channel is masked, the GDMA transaction will stop.
7372 + * When GDMA controller comes back from another channel (chain feature)
7374 + * >> Channel Mask=0: It's strange, and turns on related bit in GDMA interrupt
7375 + * status register (16:23 Unmasked)
7377 + * >> Channel Mask=1: It'll start GDMA transation, and clear this bit.
7379 + * @param ChNum GDMA channel number
7380 + * @retval 1 success
7383 +int GdmaMaskChannel(uint32_t ChNum)
7387 + Data=GDMA_READ_REG(GDMA_CTRL_REG1(ChNum));
7388 + Data |= ( 0x01 << CH_MASK_OFFSET);
7389 + GDMA_WRITE_REG(GDMA_CTRL_REG1(ChNum), Data);
7390 + GDMA_PRINT("%s: Write %0X to %X\n", __FUNCTION__, Data, GDMA_CTRL_REG1(ChNum));
7396 + * @brief Set channel is unmasked
7398 + * You can unmask the channel to start GDMA transaction.
7400 + * When GDMA controller comes back from another channel (chain feature)
7402 + * >> Channel Mask=0: It's strange, and turns on related bit in GDMA interrupt
7403 + * status register (16:23 Unmasked)
7405 + * >> Channel Mask=1: It'll start GDMA transation, and clear this bit.
7407 + * @param ChNum GDMA channel number
7408 + * @retval 1 success
7411 +int GdmaUnMaskChannel(uint32_t ChNum)
7415 + Data=GDMA_READ_REG(GDMA_CTRL_REG1(ChNum));
7416 + Data &= ~( 0x01 << CH_MASK_OFFSET);
7417 + GDMA_WRITE_REG(GDMA_CTRL_REG1(ChNum), Data);
7418 + GDMA_PRINT("%s: Write %0X to %X\n", __FUNCTION__, Data, GDMA_CTRL_REG1(ChNum));
7424 + * @brief Insert new GDMA entry to start GDMA transaction
7426 + * @param ChNum GDMA channel number
7427 + * @retval 1 success
7430 +int GdmaReqQuickIns(uint32_t ChNum)
7435 + Data = GDMA_READ_REG(GDMA_CTRL_REG1(ChNum));
7436 + Data |= ( 0x1 << CH_MASK_OFFSET);
7437 + GDMA_WRITE_REG(GDMA_CTRL_REG1(ChNum), Data);
7440 + Data = GDMA_READ_REG(GDMA_CTRL_REG(ChNum));
7441 + Data |= (0x01<<CH_EBL_OFFSET);
7442 + GDMA_WRITE_REG(GDMA_CTRL_REG(ChNum), Data);
7448 +int _GdmaReqEntryIns(GdmaReqEntry *NewEntry)
7452 + GDMA_PRINT("== << GDMA Control Reg (Channel=%d) >> ===\n", NewEntry->ChNum);
7453 + GDMA_PRINT(" Channel Source Addr = %x \n", NewEntry->Src);
7454 + GDMA_PRINT(" Channel Dest Addr = %x \n", NewEntry->Dst);
7455 + GDMA_PRINT(" Transfer Count=%d\n", NewEntry->TransCount);
7456 + GDMA_PRINT(" Source DMA Req= DMA_REQ%d\n", NewEntry->SrcReqNum);
7457 + GDMA_PRINT(" Dest DMA Req= DMA_REQ%d\n", NewEntry->DstReqNum);
7458 + GDMA_PRINT(" Source Burst Mode=%s\n", NewEntry->SrcBurstMode ? "Fix" : "Inc");
7459 + GDMA_PRINT(" Dest Burst Mode=%s\n", NewEntry->DstBurstMode ? "Fix" : "Inc");
7460 + GDMA_PRINT(" Burst Size=%s\n", NewEntry->BurstSize ==0 ? "1 transfer" : \
7461 + NewEntry->BurstSize ==1 ? "2 transfer" :\
7462 + NewEntry->BurstSize ==2 ? "4 transfer" :\
7463 + NewEntry->BurstSize ==3 ? "8 transfer" :\
7464 + NewEntry->BurstSize ==4 ? "16 transfer" :\
7466 + GDMA_PRINT(" Hardware/Software Mode = %s\n", NewEntry->SoftMode ?
7468 + GDMA_PRINT("== << GDMA Control Reg1 (Channel=%d) >> =\n", NewEntry->ChNum);
7469 + GDMA_PRINT("Channel Done Interrput=%s\n", (NewEntry->DoneIntCallback!=NULL) ?
7470 + "Enable" : "Disable");
7471 + GDMA_PRINT("Channel Unmasked Int=%s\n", (NewEntry->UnMaskIntCallback!=NULL) ?
7472 + "Enable" : "Disable");
7473 +#if !defined (CONFIG_RALINK_RT3052) && !defined (CONFIG_RALINK_RT3883)
7474 + GDMA_PRINT("Coherent Interrupt =%s\n", (NewEntry->CoherentIntEbl==1)?
7475 + "Enable" : "Disable");
7477 + GDMA_PRINT("Next Unmasked Channel=%d\n", NewEntry->NextUnMaskCh);
7478 + GDMA_PRINT("Channel Mask=%d\n", NewEntry->ChMask);
7479 + GDMA_PRINT("========================================\n");
7481 + GDMA_WRITE_REG(GDMA_SRC_REG(NewEntry->ChNum), NewEntry->Src);
7482 + GDMA_PRINT("SrcAddr: Write %0X to %X\n", \
7483 + NewEntry->Src, GDMA_SRC_REG(NewEntry->ChNum));
7485 + GDMA_WRITE_REG(GDMA_DST_REG(NewEntry->ChNum), NewEntry->Dst);
7486 + GDMA_PRINT("DstAddr: Write %0X to %X\n", \
7487 + NewEntry->Dst, GDMA_DST_REG(NewEntry->ChNum));
7489 + Data |= ( (NewEntry->NextUnMaskCh) << NEXT_UNMASK_CH_OFFSET);
7490 + Data |= ( NewEntry->ChMask << CH_MASK_OFFSET);
7491 +#if !defined (CONFIG_RALINK_RT3052) && !defined (CONFIG_RALINK_RT3883)
7492 + Data |= ( NewEntry->CoherentIntEbl << COHERENT_INT_EBL_OFFSET);
7495 + if(NewEntry->UnMaskIntCallback!=NULL) {
7496 + Data |= (0x01<<CH_UNMASKINT_EBL_OFFSET);
7497 + GdmaUnMaskIntCallback[NewEntry->ChNum] = NewEntry->UnMaskIntCallback;
7500 +#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)
7501 + Data |= (NewEntry->SrcReqNum << SRC_DMA_REQ_OFFSET);
7502 + Data |= (NewEntry->DstReqNum << DST_DMA_REQ_OFFSET);
7505 + GDMA_WRITE_REG(GDMA_CTRL_REG1(NewEntry->ChNum), Data);
7506 + GDMA_PRINT("CTRL1: Write %08X to %8X\n", Data, GDMA_CTRL_REG1(NewEntry->ChNum));
7508 + Data = ((NewEntry->TransCount) << TRANS_CNT_OFFSET);
7509 +#if defined (CONFIG_RALINK_RT3052)
7510 + Data |= (NewEntry->SrcReqNum << SRC_DMA_REQ_OFFSET);
7511 + Data |= (NewEntry->DstReqNum << DST_DMA_REQ_OFFSET);
7513 + Data |= (NewEntry->SrcBurstMode << SRC_BRST_MODE_OFFSET);
7514 + Data |= (NewEntry->DstBurstMode << DST_BRST_MODE_OFFSET);
7515 + Data |= (NewEntry->BurstSize << BRST_SIZE_OFFSET);
7517 + if(NewEntry->DoneIntCallback!=NULL) {
7518 + Data |= (0x01<<CH_DONEINT_EBL_OFFSET);
7519 + GdmaDoneIntCallback[NewEntry->ChNum] = NewEntry->DoneIntCallback;
7522 + if(NewEntry->SoftMode) {
7523 + Data |= (0x01<<MODE_SEL_OFFSET);
7526 + Data |= (0x01<<CH_EBL_OFFSET);
7527 + GDMA_WRITE_REG(GDMA_CTRL_REG(NewEntry->ChNum), Data);
7528 + //GDMA_READ_REG(GDMA_CTRL_REG(NewEntry->ChNum));
7529 + GDMA_PRINT("CTRL: Write %08X to %8X\n", Data, GDMA_CTRL_REG(NewEntry->ChNum));
7530 + //if there is no interrupt handler, this function will
7531 + //return 1 until GDMA done.
7532 + if(NewEntry->DoneIntCallback==NULL) {
7533 + //wait for GDMA processing done
7534 +#if defined (CONFIG_RALINK_RT3052)
7535 + while((GDMA_READ_REG(RALINK_GDMAISTS) &
7536 + (0x1<<NewEntry->ChNum))==0);
7538 + GDMA_WRITE_REG(RALINK_GDMAISTS, 1<< NewEntry->ChNum);
7539 +#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)
7540 + while((GDMA_READ_REG(RALINK_GDMA_DONEINT) &
7541 + (0x1<<NewEntry->ChNum))==0);
7543 + GDMA_WRITE_REG(RALINK_GDMA_DONEINT, 1<< NewEntry->ChNum);
7551 +#if defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
7553 + * @brief Start GDMA transaction for sending data to SPI
7555 + * @param *Src source address
7556 + * @param *Dst destination address
7558 + * @param TransCount data length
7559 + * @param *DoneIntCallback callback function when transcation is done
7560 + * @param *UnMaskIntCallback callback func when ch mask field is incorrect
7561 + * @retval 1 success
7567 + uint16_t TransCount,
7568 + void (*DoneIntCallback)(uint32_t data),
7569 + void (*UnMaskIntCallback)(uint32_t data)
7572 + GdmaReqEntry Entry;
7574 + #if defined (CONFIG_MIPS)
7575 + Entry.Src= (Src & 0x1FFFFFFF);
7576 + Entry.Dst= (Dst & 0x1FFFFFFF);
7581 + Entry.TransCount = TransCount;
7582 + Entry.SrcBurstMode=INC_MODE;
7583 + Entry.DstBurstMode=FIX_MODE;
7584 + Entry.BurstSize=BUSTER_SIZE_4B;
7585 + Entry.SrcReqNum=DMA_MEM_REQ;
7586 + Entry.DstReqNum=DMA_SPI_TX_REQ;
7587 + Entry.DoneIntCallback=DoneIntCallback;
7588 + Entry.UnMaskIntCallback=UnMaskIntCallback;
7591 + Entry.CoherentIntEbl=0;
7593 + //enable chain feature
7594 + Entry.ChNum = GDMA_SPI_TX;
7595 + Entry.NextUnMaskCh = GDMA_SPI_TX;
7597 + return _GdmaReqEntryIns(&Entry);
7603 + uint16_t TransCount,
7604 + void (*DoneIntCallback)(uint32_t data),
7605 + void (*UnMaskIntCallback)(uint32_t data)
7608 + GdmaReqEntry Entry;
7610 + #if defined (CONFIG_MIPS)
7611 + Entry.Src= (Src & 0x1FFFFFFF);
7612 + Entry.Dst= (Dst & 0x1FFFFFFF);
7617 + Entry.TransCount = TransCount;
7618 + Entry.SrcBurstMode=FIX_MODE;
7619 + Entry.DstBurstMode=INC_MODE;
7620 + Entry.BurstSize=BUSTER_SIZE_4B;
7621 + Entry.SrcReqNum=DMA_SPI_RX_REQ;
7622 + Entry.DstReqNum=DMA_MEM_REQ;
7623 + Entry.DoneIntCallback=DoneIntCallback;
7624 + Entry.UnMaskIntCallback=UnMaskIntCallback;
7627 + Entry.CoherentIntEbl=1;
7630 + //enable chain feature
7631 + Entry.ChNum=GDMA_SPI_RX;
7632 + Entry.NextUnMaskCh=GDMA_SPI_RX;
7635 + return _GdmaReqEntryIns(&Entry);
7642 + * @brief Start GDMA transaction for sending data to I2S
7644 + * @param *Src source address
7645 + * @param *Dst destination address
7646 + * @param TxNo I2S Tx number
7647 + * @param TransCount data length
7648 + * @param *DoneIntCallback callback function when transcation is done
7649 + * @param *UnMaskIntCallback callback func when ch mask field is incorrect
7650 + * @retval 1 success
7657 + uint16_t TransCount,
7658 + void (*DoneIntCallback)(uint32_t data),
7659 + void (*UnMaskIntCallback)(uint32_t data)
7662 + GdmaReqEntry Entry;
7664 + #if defined (CONFIG_MIPS)
7665 + Entry.Src= (Src & 0x1FFFFFFF);
7666 + Entry.Dst= (Dst & 0x1FFFFFFF);
7671 + Entry.TransCount = TransCount;
7672 + Entry.SrcBurstMode=INC_MODE;
7673 + Entry.DstBurstMode=FIX_MODE;
7674 + Entry.BurstSize=BUSTER_SIZE_4B;
7675 + Entry.SrcReqNum=DMA_MEM_REQ;
7676 + Entry.DstReqNum=DMA_I2S_TX_REQ;
7677 + Entry.DoneIntCallback=DoneIntCallback;
7678 + Entry.UnMaskIntCallback=UnMaskIntCallback;
7681 + Entry.CoherentIntEbl=0;
7683 + if(TxNo==0) { //TX0
7684 + //enable chain feature
7685 + Entry.ChNum=GDMA_I2S_TX0;
7686 + Entry.NextUnMaskCh= (TransCount==4) ? GDMA_I2S_TX0 : GDMA_I2S_TX1;
7687 + }else if(TxNo==1) { //TX1
7688 + //enable chain feature
7689 + Entry.ChNum=GDMA_I2S_TX1;
7690 + Entry.NextUnMaskCh= (TransCount==4) ? GDMA_I2S_TX1 : GDMA_I2S_TX0;
7692 + GDMA_PRINT("I2S Tx Number %x is invalid\n", TxNo);
7696 + return _GdmaReqEntryIns(&Entry);
7701 +#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)
7703 + * @brief Start GDMA transaction for receiving data to I2S
7705 + * @param *Src source address
7706 + * @param *Dst destination address
7707 + * @param TxNo I2S Tx number
7708 + * @param TransCount data length
7709 + * @param *DoneIntCallback callback function when transcation is done
7710 + * @param *UnMaskIntCallback callback func when ch mask field is incorrect
7711 + * @retval 1 success
7718 + uint16_t TransCount,
7719 + void (*DoneIntCallback)(uint32_t data),
7720 + void (*UnMaskIntCallback)(uint32_t data)
7723 + GdmaReqEntry Entry;
7724 + #if defined (CONFIG_MIPS)
7725 + Entry.Src= (Src & 0x1FFFFFFF);
7726 + Entry.Dst= (Dst & 0x1FFFFFFF);
7731 + Entry.TransCount = TransCount;
7732 + Entry.SrcBurstMode=FIX_MODE;
7733 + Entry.DstBurstMode=INC_MODE;
7734 + Entry.BurstSize=BUSTER_SIZE_4B;
7735 + Entry.SrcReqNum=DMA_I2S_RX_REQ;
7736 + Entry.DstReqNum=DMA_MEM_REQ;
7737 + Entry.DoneIntCallback=DoneIntCallback;
7738 + Entry.UnMaskIntCallback=UnMaskIntCallback;
7741 + Entry.CoherentIntEbl=1;
7743 + if(RxNo==0) { //RX0
7744 + //enable chain feature
7745 + Entry.ChNum=GDMA_I2S_RX0;
7746 + Entry.NextUnMaskCh=(TransCount==4) ? GDMA_I2S_RX0 : GDMA_I2S_RX1;
7747 + }else if(RxNo==1) { //RX1
7748 + //enable chain feature
7749 + Entry.ChNum=GDMA_I2S_RX1;
7750 + Entry.NextUnMaskCh=(TransCount==4) ? GDMA_I2S_RX1 : GDMA_I2S_RX0;
7752 + GDMA_PRINT("I2S Rx Number %x is invalid\n", RxNo);
7756 + return _GdmaReqEntryIns(&Entry);
7763 + * @brief Start GDMA transaction for receiving data from PCM
7765 + * @param *Src source address
7766 + * @param *Dst destination address
7767 + * @param TransCount data length
7768 + * @param PcmNo PCM channel
7769 + * @param RxNo PCM Rx number
7770 + * @param *DoneIntCallback callback function when transcation is done
7771 + * @param *UnMaskIntCallback callback func when ch mask field is incorrect
7772 + * @retval 1 success
7780 + uint16_t TransCount,
7781 + void (*DoneIntCallback)(uint32_t data),
7782 + void (*UnMaskIntCallback)(uint32_t data)
7785 + GdmaReqEntry Entry;
7787 + #if defined (CONFIG_MIPS)
7788 + Entry.Src= (Src & 0x1FFFFFFF);
7789 + Entry.Dst= (Dst & 0x1FFFFFFF);
7794 + Entry.TransCount = TransCount;
7795 + Entry.SrcBurstMode=FIX_MODE;
7796 + Entry.DstBurstMode=INC_MODE;
7797 + Entry.BurstSize=BUSTER_SIZE_4B;
7798 + Entry.DstReqNum=DMA_MEM_REQ;
7799 + Entry.DoneIntCallback=DoneIntCallback;
7800 + Entry.UnMaskIntCallback=UnMaskIntCallback;
7803 + Entry.CoherentIntEbl=1;
7806 + GDMA_PRINT("PCM Rx Number %x is invalid\n", RxNo);
7813 + Entry.SrcReqNum=DMA_PCM_RX0_REQ;
7816 + Entry.SrcReqNum=DMA_PCM_RX1_REQ;
7818 +#if defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
7820 + Entry.SrcReqNum=DMA_PCM_RX2_REQ;
7823 + Entry.SrcReqNum=DMA_PCM_RX3_REQ;
7827 + GDMA_PRINT("PCM Channel %x is invalid\n", PcmNo);
7830 + Entry.ChNum=GDMA_PCM_RX(PcmNo,RxNo);
7831 + Entry.NextUnMaskCh=GDMA_PCM_RX(PcmNo,1-RxNo);
7833 + return _GdmaReqEntryIns(&Entry);
7838 + * @brief Start GDMA transaction for sending data to PCM
7840 + * @param *Src source address
7841 + * @param *Dst destination address
7842 + * @param TransCount data length
7843 + * @param PcmNo PCM channel
7844 + * @param TxNo PCM Tx number
7845 + * @param *DoneIntCallback callback func when transcation is done
7846 + * @param *UnMaskIntCallback callback func when ch mask field is incorrect
7847 + * @retval 1 success
7855 + uint16_t TransCount,
7856 + void (*DoneIntCallback)(uint32_t data),
7857 + void (*UnMaskIntCallback)(uint32_t data)
7860 + GdmaReqEntry Entry;
7862 + #if defined (CONFIG_MIPS)
7863 + Entry.Src= (Src & 0x1FFFFFFF);
7864 + Entry.Dst= (Dst & 0x1FFFFFFF);
7869 + Entry.TransCount = TransCount;
7870 + Entry.SrcBurstMode=INC_MODE;
7871 + Entry.DstBurstMode=FIX_MODE;
7872 + Entry.BurstSize=BUSTER_SIZE_4B;
7873 + Entry.SrcReqNum=DMA_MEM_REQ;
7874 + Entry.DoneIntCallback=DoneIntCallback;
7875 + Entry.UnMaskIntCallback=UnMaskIntCallback;
7876 + Entry.SoftMode=0; //Hardware Mode
7878 + Entry.CoherentIntEbl=0;
7881 + GDMA_PRINT("PCM Tx Number %x is invalid\n", TxNo);
7887 + Entry.DstReqNum=DMA_PCM_TX0_REQ;
7890 + Entry.DstReqNum=DMA_PCM_TX1_REQ;
7892 +#if defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
7894 + Entry.DstReqNum=DMA_PCM_TX2_REQ;
7897 + Entry.DstReqNum=DMA_PCM_TX3_REQ;
7901 + GDMA_PRINT("PCM Channel %x is invalid\n", PcmNo);
7904 + Entry.ChNum=GDMA_PCM_TX(PcmNo,TxNo);
7905 + Entry.NextUnMaskCh=GDMA_PCM_TX(PcmNo,1-TxNo);
7907 + return _GdmaReqEntryIns(&Entry);
7913 + * @brief Start GDMA transaction for memory to memory copy
7915 + * @param *Src source address
7916 + * @param *Dst destination address
7917 + * @param TransCount data length
7918 + * @param *DoneIntCallback callback function when transcation is done
7919 + * @retval 1 success
7925 + uint16_t TransCount,
7926 + void (*DoneIntCallback)(uint32_t data)
7931 + GdmaReqEntry Entry;
7932 + #if defined (CONFIG_MIPS)
7933 + Entry.Src= (Src & 0x1FFFFFFF);
7934 + Entry.Dst= (Dst & 0x1FFFFFFF);
7940 + //Entry.Src= virt_to_phys(Src);
7941 + //Entry.Dst= virt_to_phys(Dst);
7945 + Entry.TransCount = TransCount;
7946 + Entry.SrcBurstMode=INC_MODE;
7947 + Entry.DstBurstMode=INC_MODE;
7948 + Entry.BurstSize=BUSTER_SIZE_64B;
7949 + Entry.SrcReqNum=DMA_MEM_REQ;
7950 + Entry.DstReqNum=DMA_MEM_REQ;
7951 + Entry.DoneIntCallback=DoneIntCallback;
7952 + Entry.UnMaskIntCallback=NULL;
7956 + Entry.CoherentIntEbl=1;
7958 + //No reserved channel for Memory to Memory GDMA,
7959 + //get free channel on demand
7960 + if(!_GdmaGetFreeCh(&Entry.ChNum)) {
7961 + GDMA_PRINT("GDMA Channels are all busy\n");
7966 + //set next channel to their own channel
7967 + //to disable chain feature
7968 + Entry.NextUnMaskCh= Entry.ChNum;
7969 + //printk ("ChNum = %d\n", Entry.ChNum);
7970 + //set next channel to another channel
7971 + //to enable chain feature
7972 + //Entry.NextUnMaskCh= (Entry.ChNum+1) % MAX_GDMA_CHANNEL;
7974 + return _GdmaReqEntryIns(&Entry);
7980 + * @brief GDMA interrupt handler
7982 + * When GDMA transcation is done, call related handler
7983 + * to do the remain job.
7986 +irqreturn_t GdmaIrqHandler(
7993 + unsigned long flags;
7994 +#if defined (CONFIG_RALINK_RT3052)
7995 + u32 GdmaUnMaskStatus=GDMA_READ_REG(RALINK_GDMAISTS) & 0xFF0000;
7996 + u32 GdmaDoneStatus=GDMA_READ_REG(RALINK_GDMAISTS) & 0xFF;
7997 +#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)
7998 + u32 GdmaUnMaskStatus=GDMA_READ_REG(RALINK_GDMA_UNMASKINT);
7999 + u32 GdmaDoneStatus=GDMA_READ_REG(RALINK_GDMA_DONEINT);
8001 + //printk("********GDMA Interrupt*******************\n");
8003 + //GDMA_PRINT("========================================\n");
8004 + //GDMA_PRINT("GdmaUnMask Interrupt=%x\n",GdmaUnMaskStatus);
8005 + //GDMA_PRINT("GdmaDone Interrupt=%x\n",GdmaDoneStatus);
8006 + //GDMA_PRINT("========================================\n");
8008 + spin_lock_irqsave(&gdma_int_lock, flags);
8011 +#if defined (CONFIG_RALINK_RT3052)
8012 + GDMA_WRITE_REG(RALINK_GDMAISTS, GdmaUnMaskStatus);
8013 +#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)
8014 + GDMA_WRITE_REG(RALINK_GDMA_UNMASKINT, GdmaUnMaskStatus);
8018 + for(Ch=0;Ch<MAX_GDMA_CHANNEL;Ch++) {
8020 + if(GdmaUnMaskStatus & (0x1 << (UNMASK_INT_STATUS(Ch))) ) {
8021 + if(GdmaUnMaskIntCallback[Ch] != NULL) {
8022 + GdmaUnMaskIntCallback[Ch](Ch);
8023 + // printk("GdmaUnMaskIntCallback \n");
8029 +#if defined (CONFIG_RALINK_RT3052)
8030 + GDMA_WRITE_REG(RALINK_GDMAISTS, GdmaDoneStatus);
8031 +#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)
8032 + GDMA_WRITE_REG(RALINK_GDMA_DONEINT, GdmaDoneStatus);
8035 + //printk("interrupt status = %x \n", GdmaDoneStatus);
8037 + for(Ch=0;Ch<MAX_GDMA_CHANNEL;Ch++) {
8038 + if(GdmaDoneStatus & (0x1<<Ch)) {
8039 + if(GdmaDoneIntCallback[Ch] != NULL) {
8040 + //printk("*************Interrupt Ch=%d***********\n", Ch);
8041 + GdmaDoneIntCallback[Ch](Ch);
8046 +//printk("interrupt status clear = %x \n", GDMA_READ_REG(RALINK_GDMA_DONEINT));
8047 + spin_unlock_irqrestore(&gdma_int_lock, flags);
8049 + return IRQ_HANDLED;
8053 +static int RalinkGdmaInit(void)
8058 + printk("Enable Ralink GDMA Controller Module \n");
8059 +#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)
8060 + printk("GDMA IP Version=%d\n", GET_GDMA_IP_VER);
8062 +spin_lock_init(&gdma_int_lock);
8063 +spin_lock_init(&gdma_lock);
8064 +//spin_lock_init(&gdma_lock_mem);
8066 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
8067 + #if defined (CONFIG_MIPS)
8068 + Ret = request_irq(SURFBOARDINT_DMA, GdmaIrqHandler, \
8069 + IRQF_DISABLED, "Ralink_DMA", NULL);
8071 + Ret = request_irq(SURFBOARDINT_DMA, GdmaIrqHandler, \
8072 + IRQF_TRIGGER_LOW, "Ralink_DMA", NULL);
8075 + Ret = request_irq(SURFBOARDINT_DMA, GdmaIrqHandler, \
8076 + SA_INTERRUPT, "Ralink_DMA", NULL);
8080 + Ret = request_irq(131, GdmaIrqHandler, \
8081 + IRQF_TRIGGER_LOW, "Ralink_DMA", NULL);
8084 + GDMA_PRINT("IRQ %d is not free.\n", SURFBOARDINT_DMA);
8088 +#if defined (CONFIG_MIPS)
8089 + //Enable GDMA interrupt
8090 + val = le32_to_cpu(*(volatile u32 *)(RALINK_REG_INTENA));
8091 + val |= RALINK_INTCTL_DMA;
8092 + GDMA_WRITE_REG(RALINK_REG_INTENA, val);
8095 + //Channel0~Channel7 are round-robin
8096 +#if defined (CONFIG_RALINK_RT3052)
8097 + GDMA_WRITE_REG(RALINK_GDMAGCT, 0x01);
8098 +#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)
8099 + GDMA_WRITE_REG(RALINK_GDMA_GCT, 0x01);
8101 +#error Please Choose System Type
8107 +static void __exit RalinkGdmaExit(void)
8110 + printk("Disable Ralink GDMA Controller Module\n");
8111 +#if defined (CONFIG_MIPS)
8112 + //Disable GDMA interrupt
8113 + GDMA_WRITE_REG(RALINK_REG_INTDIS, RALINK_INTCTL_DMA);
8115 + free_irq(SURFBOARDINT_DMA, NULL);
8118 +module_init(RalinkGdmaInit);
8119 +module_exit(RalinkGdmaExit);
8121 +EXPORT_SYMBOL(GdmaI2sRx);
8122 +EXPORT_SYMBOL(GdmaI2sTx);
8123 +EXPORT_SYMBOL(GdmaPcmRx);
8124 +EXPORT_SYMBOL(GdmaPcmTx);
8125 +#if defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
8126 +EXPORT_SYMBOL(GdmaSpiRx);
8127 +EXPORT_SYMBOL(GdmaSpiTx);
8129 +EXPORT_SYMBOL(GdmaMem2Mem);
8130 +EXPORT_SYMBOL(GdmaReqQuickIns);
8131 +EXPORT_SYMBOL(GdmaMaskChannel);
8132 +EXPORT_SYMBOL(GdmaUnMaskChannel);
8135 +MODULE_DESCRIPTION("Ralink SoC GDMA Controller API Module");
8136 +MODULE_AUTHOR("Steven Liu <steven_liu@ralinktech.com.tw>");
8137 +MODULE_LICENSE("GPL");
8138 +MODULE_VERSION(MOD_VERSION);
8139 diff --git a/sound/soc/mtk/ralink_gdma.h b/sound/soc/mtk/ralink_gdma.h
8140 new file mode 100644
8141 index 0000000..95ce5f7
8143 +++ b/sound/soc/mtk/ralink_gdma.h
8146 + ***************************************************************************
8147 + * Ralink Tech Inc.
8148 + * 5F., No.36, Taiyuan St., Jhubei City,
8149 + * Hsinchu County 302,
8152 + * (c) Copyright, Ralink Technology, Inc.
8154 + * This program is free software; you can redistribute it and/or modify it
8155 + * under the terms of the GNU General Public License as published by the
8156 + * Free Software Foundation; either version 2 of the License, or (at your
8157 + * option) any later version.
8159 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
8160 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
8161 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
8162 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
8163 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
8164 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
8165 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
8166 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8167 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
8168 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8170 + * You should have received a copy of the GNU General Public License along
8171 + * with this program; if not, write to the Free Software Foundation, Inc.,
8172 + * 675 Mass Ave, Cambridge, MA 02139, USA.
8175 + ***************************************************************************
8178 +#ifndef __RALINK_DMA_CTRL_H__
8179 +#define __RALINK_DMA_CTRL_H__
8181 +//#include <asm/rt2880/rt_mmap.h>
8184 + * DEFINITIONS AND MACROS
8186 +#define MOD_VERSION "0.4"
8188 +#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623)
8189 +#define MAX_GDMA_CHANNEL 16
8190 +#elif defined (CONFIG_RALINK_RT3052)
8191 +#define MAX_GDMA_CHANNEL 8
8192 +#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)
8193 +#define MAX_GDMA_CHANNEL 16
8195 +#error Please Choose System Type
8199 +#define RALINK_GDMA_CTRL_BASE (RALINK_GDMA_BASE)
8200 +#if defined (CONFIG_RALINK_RT3052)
8201 +#define RALINK_GDMAISTS (RALINK_GDMA_BASE + 0x80)
8202 +#define RALINK_GDMAGCT (RALINK_GDMA_BASE + 0x88)
8203 +#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)
8204 +#define RALINK_GDMA_UNMASKINT (RALINK_GDMA_BASE + 0x200)
8205 +#define RALINK_GDMA_DONEINT (RALINK_GDMA_BASE + 0x204)
8206 +#define RALINK_GDMA_GCT (RALINK_GDMA_BASE + 0x220)
8209 +#define KSEG1 0xa0000000
8210 +#define PHYS_TO_VIRT(x) ((void *)((x) | KSEG1))
8211 +#define VIRT_TO_PHYS(x) ((unsigned long)(x) & ~KSEG1)
8216 +#if defined (CONFIG_ARCH_MT7623)
8217 +#include <mach/sync_write.h>
8218 +#define GDMA_READ_REG(phys) (*(volatile unsigned int *)((phys)))
8219 +#define GDMA_WRITE_REG(phys, val) mt65xx_reg_sync_writel((val), (phys))
8222 +#define GDMA_READ_REG(addr) (le32_to_cpu(*(volatile u32 *)(addr)))
8223 +#define GDMA_WRITE_REG(addr, val) *((volatile uint32_t *)(addr)) = cpu_to_le32(val)
8230 +#define GET_GDMA_IP_VER (GDMA_READ_REG(RALINK_GDMA_GCT) & 0x6) >> 1 //GDMA_GCT[2:1]
8232 +#define RALINK_IRQ_ADDR RALINK_INTCL_BASE
8233 +#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7628)
8234 +#define RALINK_REG_INTENA (RALINK_IRQ_ADDR + 0x80)
8235 +#define RALINK_REG_INTDIS (RALINK_IRQ_ADDR + 0x78)
8237 +#define RALINK_REG_INTENA (RALINK_IRQ_ADDR + 0x34)
8238 +#define RALINK_REG_INTDIS (RALINK_IRQ_ADDR + 0x38)
8242 + * 12bytes=GDMA Channel n Source Address(4) +
8243 + * GDMA Channel n Destination Address(4) +
8244 + * GDMA Channel n Control Register(4)
8247 +#define GDMA_SRC_REG(ch) (RALINK_GDMA_BASE + ch*16)
8248 +#define GDMA_DST_REG(ch) (GDMA_SRC_REG(ch) + 4)
8249 +#define GDMA_CTRL_REG(ch) (GDMA_DST_REG(ch) + 4)
8250 +#define GDMA_CTRL_REG1(ch) (GDMA_CTRL_REG(ch) + 4)
8252 +//GDMA Interrupt Status Register
8253 +#if defined (CONFIG_RALINK_RT3052)
8254 +#define UNMASK_INT_STATUS(ch) (ch+16)
8255 +#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)
8256 +#define UNMASK_INT_STATUS(ch) (ch)
8258 +#define TXDONE_INT_STATUS(ch) (ch)
8261 +#define MODE_SEL_OFFSET 0
8262 +#define CH_EBL_OFFSET 1
8263 +#define CH_DONEINT_EBL_OFFSET 2
8264 +#define BRST_SIZE_OFFSET 3
8265 +#define DST_BRST_MODE_OFFSET 6
8266 +#define SRC_BRST_MODE_OFFSET 7
8267 +#define TRANS_CNT_OFFSET 16
8270 +#if defined (CONFIG_RALINK_RT3052)
8271 +#define CH_UNMASKINT_EBL_OFFSET 4
8272 +#define NEXT_UNMASK_CH_OFFSET 1
8273 +#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)
8274 +#define CH_UNMASKINT_EBL_OFFSET 1
8275 +#define NEXT_UNMASK_CH_OFFSET 3
8277 +#define COHERENT_INT_EBL_OFFSET 2
8278 +#define CH_MASK_OFFSET 0
8281 +#if defined (CONFIG_RALINK_RT3052)
8283 +#define DST_DMA_REQ_OFFSET 8
8284 +#define SRC_DMA_REQ_OFFSET 12
8285 +#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)
8287 +#define DST_DMA_REQ_OFFSET 8
8288 +#define SRC_DMA_REQ_OFFSET 16
8291 +#define GDMA_PCM0_RX0 0
8292 +#define GDMA_PCM0_RX1 1
8293 +#define GDMA_PCM0_TX0 2
8294 +#define GDMA_PCM0_TX1 3
8296 +#define GDMA_PCM1_RX0 4
8297 +#define GDMA_PCM1_RX1 5
8298 +#define GDMA_PCM1_TX0 6
8299 +#define GDMA_PCM1_TX1 7
8301 +#define GDMA_PCM_RX(i,j) (0+((i)<<2)+j)
8302 +#define GDMA_PCM_TX(i,j) (2+((i)<<2)+j)
8304 +#define GDMA_I2S_TX0 4
8305 +#define GDMA_I2S_TX1 5
8306 +#define GDMA_I2S_RX0 6
8307 +#define GDMA_I2S_RX1 7
8309 +#define GDMA_SPI_TX 13
8310 +#define GDMA_SPI_RX 12
8313 +//#define GDMA_DEBUG
8315 +#define GDMA_PRINT(fmt, args...) printk(KERN_INFO "GDMA: " fmt, ## args)
8317 +#define GDMA_PRINT(fmt, args...) { }
8321 + * TYPEDEFS AND STRUCTURES
8324 +enum GdmaBusterMode {
8329 +enum GdmaBusterSize {
8330 + BUSTER_SIZE_4B=0, /* 1 transfer */
8331 + BUSTER_SIZE_8B=1, /* 2 transfer */
8332 + BUSTER_SIZE_16B=2, /* 4 transfer */
8333 + BUSTER_SIZE_32B=3, /* 8 transfer */
8334 + BUSTER_SIZE_64B=4 /* 16 transfer */
8337 +enum GdmaDmaReqNum {
8338 +#if defined (CONFIG_RALINK_RT3052)
8342 + DMA_PCM_RX0_REQ=3,
8343 + DMA_PCM_RX1_REQ=4,
8344 + DMA_PCM_TX0_REQ=5,
8345 + DMA_PCM_TX1_REQ=6,
8348 +#elif defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855)
8353 + DMA_PCM_RX0_REQ=4,
8354 + DMA_PCM_RX1_REQ=5,
8355 + DMA_PCM_TX0_REQ=6,
8356 + DMA_PCM_TX1_REQ=7,
8357 + DMA_CODEC0_REQ8=8,
8358 + DMA_CODEC1_REQ9=9,
8366 + #if defined (CONFIG_RALINK_RT3883)
8368 + #elif defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855)
8372 +#elif defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
8377 + DMA_PCM_RX0_REQ=4,
8378 + DMA_PCM_RX1_REQ=5,
8379 + DMA_PCM_TX0_REQ=6,
8380 + DMA_PCM_TX1_REQ=7,
8381 + DMA_PCM_RX2_REQ=8,
8382 + DMA_PCM_RX3_REQ=9,
8383 + DMA_PCM_TX2_REQ=10,
8384 + DMA_PCM_TX3_REQ=11,
8385 + DMA_SPI_RX_REQ=12,
8386 + DMA_SPI_TX_REQ=13,
8389 +#elif defined (CONFIG_RALINK_RT6855A)
8394 + DMA_PCM_RX0_REQ=4,
8395 + DMA_PCM_RX1_REQ=5,
8396 + DMA_PCM_TX0_REQ=6,
8397 + DMA_PCM_TX1_REQ=7,
8398 + DMA_CODEC0_REQ8=8,
8399 + DMA_CODEC1_REQ9=9,
8408 +#error Please Choose System Type
8417 + uint16_t TransCount;
8419 + uint8_t NextUnMaskCh;
8421 + uint8_t CoherentIntEbl;
8423 + enum GdmaDmaReqNum SrcReqNum;
8424 + enum GdmaDmaReqNum DstReqNum;
8425 + enum GdmaBusterMode SrcBurstMode;
8426 + enum GdmaBusterMode DstBurstMode;
8427 + enum GdmaBusterSize BurstSize;
8428 + void (*DoneIntCallback)(uint32_t);
8429 + void (*UnMaskIntCallback)(uint32_t);
8435 +int GdmaI2sTx(uint32_t Src, uint32_t Dst, uint8_t TxNo, uint16_t TransCount,
8436 + void (*DoneIntCallback)(uint32_t data),
8437 + void (*UnMaskIntCallback)(uint32_t data));
8439 +int GdmaI2sRx(uint32_t Src, uint32_t Dst, uint8_t RxNo, uint16_t TransCount,
8440 + void (*DoneIntCallback)(uint32_t data),
8441 + void (*UnMaskIntCallback)(uint32_t data));
8443 +int GdmaPcmRx(uint32_t Src, uint32_t Dst, uint8_t PcmNo, uint8_t RxNo, uint16_t TransCount,
8444 + void (*DoneIntCallback)(uint32_t data),
8445 + void (*UnMaskIntCallback)(uint32_t data));
8447 +int GdmaPcmTx(uint32_t Src, uint32_t Dst, uint8_t PcmNo, uint8_t TxNo, uint16_t TransCount,
8448 + void (*DoneIntCallback)(uint32_t data),
8449 + void (*UnMaskIntCallback)(uint32_t data));
8451 +int GdmaSpiTx(uint32_t Src, uint32_t Dst, uint16_t TransCount,
8452 + void (*DoneIntCallback)(uint32_t data),
8453 + void (*UnMaskIntCallback)(uint32_t data));
8455 +int GdmaSpiRx(uint32_t Src, uint32_t Dst, uint16_t TransCount,
8456 + void (*DoneIntCallback)(uint32_t data),
8457 + void (*UnMaskIntCallback)(uint32_t data));
8460 +int GdmaMem2Mem(uint32_t Src, uint32_t Dst, uint16_t TransCount,
8461 + void (*DoneIntCallback)(uint32_t data));
8463 +int GdmaMaskChannel(uint32_t ChNum);
8465 +int GdmaUnMaskChannel(uint32_t ChNum);
8467 +int GdmaReqQuickIns(uint32_t ChNum);
8471 diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
8472 index 6173d15..d9c52a7 100644
8473 --- a/sound/soc/soc-core.c
8474 +++ b/sound/soc/soc-core.c
8475 @@ -1758,7 +1758,8 @@ static int soc_probe(struct platform_device *pdev)
8476 /* Bodge while we unpick instantiation */
8477 card->dev = &pdev->dev;
8479 - return snd_soc_register_card(card);
8480 + snd_soc_register_card(card);
8484 static int soc_cleanup_card_resources(struct snd_soc_card *card)