c6fe92c1589235a36864b7b98b9d2aa80405dd1d
[openwrt/staging/chunkeey.git] / target / linux / ramips / patches-4.3 / 0050-alsa-add-ralink-sdk-driver.patch
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
5
6 Signed-off-by: John Crispin <blogic@openwrt.org>
7 ---
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
43
44 --- a/sound/soc/Kconfig
45 +++ b/sound/soc/Kconfig
46 @@ -64,6 +64,7 @@ source "sound/soc/txx9/Kconfig"
47 source "sound/soc/ux500/Kconfig"
48 source "sound/soc/xtensa/Kconfig"
49 source "sound/soc/zte/Kconfig"
50 +source "sound/soc/mtk/Kconfig"
51
52 # Supported codecs
53 source "sound/soc/codecs/Kconfig"
54 --- a/sound/soc/Makefile
55 +++ b/sound/soc/Makefile
56 @@ -46,3 +46,4 @@ obj-$(CONFIG_SND_SOC) += txx9/
57 obj-$(CONFIG_SND_SOC) += ux500/
58 obj-$(CONFIG_SND_SOC) += xtensa/
59 obj-$(CONFIG_SND_SOC) += zte/
60 +obj-$(CONFIG_SND_SOC) += mtk/
61 --- a/sound/soc/codecs/Kconfig
62 +++ b/sound/soc/codecs/Kconfig
63 @@ -816,7 +816,7 @@ config SND_SOC_WM8955
64 tristate
65
66 config SND_SOC_WM8960
67 - tristate
68 + tristate "WM8960"
69
70 config SND_SOC_WM8961
71 tristate
72 --- a/sound/soc/codecs/wm8960.c
73 +++ b/sound/soc/codecs/wm8960.c
74 @@ -27,6 +27,7 @@
75 #include <sound/wm8960.h>
76
77 #include "wm8960.h"
78 +#include "../mtk/i2c_wm8960.h"
79
80 /* R25 - Power 1 */
81 #define WM8960_VMID_MASK 0x180
82 @@ -57,10 +58,10 @@ static int wm8960_set_pll(struct snd_soc
83 * using 2 wire for device control, so we cache them instead.
84 */
85 static const struct reg_default wm8960_reg_defaults[] = {
86 - { 0x0, 0x00a7 },
87 - { 0x1, 0x00a7 },
88 - { 0x2, 0x0000 },
89 - { 0x3, 0x0000 },
90 + { 0x0, 0x002b },
91 + { 0x1, 0x002b },
92 + { 0x2, 0x00ff },
93 + { 0x3, 0x00ff },
94 { 0x4, 0x0000 },
95 { 0x5, 0x0008 },
96 { 0x6, 0x0000 },
97 @@ -92,8 +93,8 @@ static const struct reg_default wm8960_r
98 { 0x25, 0x0050 },
99 { 0x26, 0x0000 },
100 { 0x27, 0x0000 },
101 - { 0x28, 0x0000 },
102 - { 0x29, 0x0000 },
103 + { 0x28, 0x007b },
104 + { 0x29, 0x007b },
105 { 0x2a, 0x0040 },
106 { 0x2b, 0x0000 },
107 { 0x2c, 0x0000 },
108 @@ -138,7 +139,15 @@ struct wm8960_priv {
109 struct wm8960_data pdata;
110 };
111
112 +#if 1
113 +#define wm8960_reset(c) do{ \
114 + int i = 0;\
115 + snd_soc_write(c, WM8960_RESET, 0);\
116 + for(i = 0; i < 1000*HZ; i++);\
117 + }while(0)
118 +#else
119 #define wm8960_reset(c) regmap_write(c, WM8960_RESET, 0)
120 +#endif
121
122 /* enumerated controls */
123 static const char *wm8960_polarity[] = {"No Inversion", "Left Inverted",
124 @@ -192,8 +201,8 @@ static int wm8960_get_deemph(struct snd_
125 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
126 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
127
128 - ucontrol->value.integer.value[0] = wm8960->deemph;
129 - return 0;
130 + //ucontrol->value.integer.value[0] = wm8960->deemph;
131 + return wm8960->deemph;
132 }
133
134 static int wm8960_put_deemph(struct snd_kcontrol *kcontrol,
135 @@ -211,6 +220,71 @@ static int wm8960_put_deemph(struct snd_
136 return wm8960_set_deemph(codec);
137 }
138
139 +static int wm8960_preinit(struct snd_soc_codec *codec)
140 +{
141 + //printk("****** %s ******\n", __func__);
142 + snd_soc_write(codec, WM8960_RESET, 0);
143 + mdelay(500);
144 +
145 + return 0;
146 +}
147 +
148 +static int wm8960_postinit(struct snd_soc_codec *codec)
149 +{
150 + u32 data;
151 + //printk("****** %s ******\n", __func__);
152 + // In
153 + data = snd_soc_read(codec, WM8960_POWER1);
154 + snd_soc_write(codec, WM8960_POWER1, data|WM8960_PWR1_ADCL|WM8960_PWR1_ADCR|WM8960_PWR1_AINL |WM8960_PWR1_AINR|WM8960_PWR1_MICB);//0x19
155 + data = snd_soc_read(codec, WM8960_ADDCTL1);
156 + snd_soc_write(codec, WM8960_ADDCTL1, data|ADDITIONAL1_DATSEL(0x01));//0x17
157 + snd_soc_write(codec, WM8960_LADC, LEFTGAIN_LDVU|LEFTGAIN_LDACVOL(0xc3));//0x15
158 + snd_soc_write(codec, WM8960_RADC, LEFTGAIN_LDVU|LEFTGAIN_LDACVOL(0xc3));//0x16
159 + snd_soc_write(codec, WM8960_LINPATH, 0x148);//0x20
160 + snd_soc_write(codec, WM8960_RINPATH, 0x148);//0x21
161 + snd_soc_write(codec, WM8960_POWER3, WM8960_PWR3_LMIC|WM8960_PWR3_RMIC);//0x2f
162 +
163 + // Out
164 + data = snd_soc_read(codec, WM8960_POWER2);
165 + 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
166 + mdelay(10);
167 + snd_soc_write(codec, WM8960_IFACE2, 0x40);
168 + snd_soc_write(codec, WM8960_LDAC, LEFTGAIN_LDVU|LEFTGAIN_LDACVOL(0xff));//0x0a
169 + snd_soc_write(codec, WM8960_RDAC, RIGHTGAIN_RDVU|RIGHTGAIN_RDACVOL(0xff));//0x0b
170 + snd_soc_write(codec, WM8960_LOUTMIX, 0x100);//0x22
171 + snd_soc_write(codec, WM8960_ROUTMIX, 0x100);//0x25
172 +
173 + data = snd_soc_read(codec, WM8960_POWER3);
174 + snd_soc_write(codec, WM8960_POWER3, data|WM8960_PWR3_ROMIX|WM8960_PWR3_LOMIX);//0x2f
175 +
176 + snd_soc_write(codec, WM8960_CLASSD1, 0xf7);//0x31
177 + snd_soc_write(codec, WM8960_CLASSD3, 0xad);//0x33
178 + snd_soc_write(codec, WM8960_DACCTL1, 0x000);//0x05
179 +
180 + data = snd_soc_read(codec, WM8960_POWER1);
181 + snd_soc_write(codec, WM8960_POWER1, data|0x1c0);//0x19
182 +
183 +
184 + snd_soc_write(codec, WM8960_LOUT1, LOUT1_LO1VU|LOUT1_LO1ZC|LOUT1_LOUT1VOL(115));//0x02
185 + snd_soc_write(codec, WM8960_ROUT1, ROUT1_RO1VU|ROUT1_RO1ZC|ROUT1_ROUT1VOL(115));//0x03
186 +
187 + snd_soc_write(codec, WM8960_LINVOL, LINV_IPVU|LINV_LINVOL(110)); //LINV(0x00)=>0x12b
188 + snd_soc_write(codec, WM8960_RINVOL, RINV_IPVU|RINV_RINVOL(110)); //LINV(0x01)=>0x12b
189 +
190 + return 0;
191 +}
192 +
193 +static int wm8960_close(struct snd_soc_codec *codec)
194 +{
195 + snd_soc_write(codec, WM8960_DACCTL1,0x8); //0x05->0x08
196 + snd_soc_write(codec, WM8960_POWER1, 0x000); //0x19->0x000
197 + mdelay(300);
198 + snd_soc_write(codec, WM8960_POWER2, 0x000); //0x1a->0x000
199 +
200 + return 0;
201 +}
202 +
203 +
204 static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1);
205 static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1725, 75, 0);
206 static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
207 @@ -563,6 +637,7 @@ static int wm8960_set_dai_fmt(struct snd
208
209 /* set iface */
210 snd_soc_write(codec, WM8960_IFACE1, iface);
211 + wm8960_postinit(codec);
212 return 0;
213 }
214
215 @@ -809,9 +884,10 @@ static int wm8960_set_bias_level_out3(st
216 ret = wm8960_configure_clocking(codec);
217 if (ret)
218 return ret;
219 -
220 +#if 0
221 /* Set VMID to 2x50k */
222 snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x80);
223 +#endif
224 break;
225
226 case SND_SOC_BIAS_ON:
227 @@ -852,12 +928,16 @@ static int wm8960_set_bias_level_out3(st
228 /* Disable anti-pop features */
229 snd_soc_write(codec, WM8960_APOP1, WM8960_BUFIOEN);
230 }
231 -
232 +#if 0
233 /* Set VMID to 2x250k */
234 snd_soc_update_bits(codec, WM8960_POWER1, 0x180, 0x100);
235 +#endif
236 break;
237
238 case SND_SOC_BIAS_OFF:
239 +#if 1
240 + wm8960_close(codec);
241 +#else
242 /* Enable anti-pop features */
243 snd_soc_write(codec, WM8960_APOP1,
244 WM8960_POBCTRL | WM8960_SOFT_ST |
245 @@ -866,6 +946,7 @@ static int wm8960_set_bias_level_out3(st
246 /* Disable VMID and VREF, let them discharge */
247 snd_soc_write(codec, WM8960_POWER1, 0);
248 msleep(600);
249 +#endif
250 break;
251 }
252
253 @@ -1101,10 +1182,15 @@ static int wm8960_set_pll(struct snd_soc
254
255 if (pll_div.k) {
256 reg |= 0x20;
257 -
258 +#if 1
259 + snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 16) & 0xff);
260 + snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 8) & 0xff);
261 + snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0xff);
262 +#else
263 snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 16) & 0xff);
264 snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 8) & 0xff);
265 snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0xff);
266 +#endif
267 }
268 snd_soc_write(codec, WM8960_PLL1, reg);
269
270 @@ -1150,7 +1236,11 @@ static int wm8960_set_dai_clkdiv(struct
271 snd_soc_write(codec, WM8960_PLL1, reg | div);
272 break;
273 case WM8960_DCLKDIV:
274 +#if 1
275 reg = snd_soc_read(codec, WM8960_CLOCK2) & 0x03f;
276 +#else
277 + reg = snd_soc_read(codec, WM8960_CLOCK2) & 0x03f;
278 +#endif
279 snd_soc_write(codec, WM8960_CLOCK2, reg | div);
280 break;
281 case WM8960_TOCLKSEL:
282 @@ -1285,7 +1375,7 @@ static int wm8960_i2c_probe(struct i2c_c
283 {
284 struct wm8960_data *pdata = dev_get_platdata(&i2c->dev);
285 struct wm8960_priv *wm8960;
286 - int ret;
287 + int ret - 0;
288
289 wm8960 = devm_kzalloc(&i2c->dev, sizeof(struct wm8960_priv),
290 GFP_KERNEL);
291 @@ -1307,11 +1397,7 @@ static int wm8960_i2c_probe(struct i2c_c
292 else if (i2c->dev.of_node)
293 wm8960_set_pdata_from_of(i2c, &wm8960->pdata);
294
295 - ret = wm8960_reset(wm8960->regmap);
296 - if (ret != 0) {
297 - dev_err(&i2c->dev, "Failed to issue reset\n");
298 - return ret;
299 - }
300 + wm8960_reset(wm8960->regmap);
301
302 if (wm8960->pdata.shared_lrclk) {
303 ret = regmap_update_bits(wm8960->regmap, WM8960_ADDCTL2,
304 --- a/sound/soc/codecs/wm8960.h
305 +++ b/sound/soc/codecs/wm8960.h
306 @@ -111,4 +111,68 @@
307 #define WM8960_OPCLK_DIV_5_5 (4 << 0)
308 #define WM8960_OPCLK_DIV_6 (5 << 0)
309
310 +/*
311 + * WM8960 Power management
312 + */
313 +#define WM8960_PWR1_VMIDSEL_DISABLED (0 << 7)
314 +#define WM8960_PWR1_VMIDSEL_50K (1 << 7)
315 +#define WM8960_PWR1_VMIDSEL_250K (2 << 7)
316 +#define WM8960_PWR1_VMIDSEL_5K (3 << 7)
317 +#define WM8960_PWR1_VREF (1 << 6)
318 +#define WM8960_PWR1_AINL (1 << 5)
319 +#define WM8960_PWR1_AINR (1 << 4)
320 +#define WM8960_PWR1_ADCL (1 << 3)
321 +#define WM8960_PWR1_ADCR (1 << 2)
322 +#define WM8960_PWR1_MICB (1 << 1)
323 +#define WM8960_PWR1_DIGENB (1 << 0)
324 +
325 +#define WM8960_PWR2_DACL (1 << 8)
326 +#define WM8960_PWR2_DACR (1 << 7)
327 +//#define WM8960_PWR2_LOUT1 (1 << 6)
328 +//#define WM8960_PWR2_ROUT1 (1 << 5)
329 +#define WM8960_PWR2_SPKL (1 << 4)
330 +#define WM8960_PWR2_SPKR (1 << 3)
331 +//#define WM8960_PWR2_OUT3 (1 << 1)
332 +#define WM8960_PWR2_PLL_EN (1 << 0)
333 +
334 +#define WM8960_PWR3_LMIC (1 << 5)
335 +#define WM8960_PWR3_RMIC (1 << 4)
336 +#define WM8960_PWR3_LOMIX (1 << 3)
337 +#define WM8960_PWR3_ROMIX (1 << 2)
338 +
339 +#define LEFTGAIN 0x0a
340 +#define LEFTGAIN_LDVU (1 << 8)
341 +#define LEFTGAIN_LDACVOL(x) ((x) & 0xff)
342 +
343 +#define RIGHTGAIN 0x0b
344 +#define RIGHTGAIN_RDVU (1 << 8)
345 +#define RIGHTGAIN_RDACVOL(x) ((x) & 0xff)
346 +
347 +#define ADDITIONAL1_DATSEL(x) (((x) & 0x3) << 2)
348 +
349 +#define AINTFCE1_WL_32 (3 << 2)
350 +#define AINTFCE1_WL_24 (2 << 2)
351 +#define AINTFCE1_WL_20 (1 << 2)
352 +#define AINTFCE1_WL_16 (0 << 2)
353 +#define AINTFCE1_FORMAT_I2S (2 << 0)
354 +
355 +#define LOUT1_LO1VU (1 << 8)
356 +#define LOUT1_LO1ZC (1 << 7)
357 +#define LOUT1_LOUT1VOL(x) ((x) & 0x7f)
358 +
359 +#define ROUT1_RO1VU (1 << 8)
360 +#define ROUT1_RO1ZC (1 << 7)
361 +#define ROUT1_ROUT1VOL(x) ((x) & 0x7f)
362 +
363 +#define LINV_IPVU (1 << 8) /* FIXME */
364 +
365 +#define LINV_LINMUTE (1 << 7)
366 +#define LINV_LIZC (1 << 6)
367 +#define LINV_LINVOL(x) ((x) & 0x3f)
368 +
369 +#define RINV_IPVU (1 << 8) /* FIXME */
370 +#define RINV_RINMUTE (1 << 7)
371 +#define RINV_RIZC (1 << 6)
372 +#define RINV_RINVOL(x) ((x) & 0x3f)
373 +
374 #endif
375 --- /dev/null
376 +++ b/sound/soc/mtk/Kconfig
377 @@ -0,0 +1,35 @@
378 +config SND_MT76XX_SOC
379 + tristate "SoC Audio for MT76XX APSoC Machine"
380 + depends on SND_SOC && (SOC_MT7620 || SOC_MT7621)
381 +
382 + help
383 + Say Y or M if you want to add support for codecs attached to
384 + the MTK I2S interface.
385 +
386 +choice
387 + prompt "Selected SoC type"
388 + depends on SND_MT76XX_SOC
389 + default SND_MT76XX_SOC_MT7620
390 +
391 +config SND_MT76XX_SOC_MT7620
392 + bool "MT7620"
393 + depends on SOC_MT7620
394 +
395 +config SND_MT76XX_SOC_MT7628
396 + bool "MT7628"
397 + depends on SOC_MT7620
398 +
399 +config SND_MT76XX_SOC_MT7621
400 + bool "MT7621"
401 + depends on SOC_MT7621
402 +
403 +endchoice
404 +
405 +config SND_MT76XX_PCM
406 + tristate "MTK SoC Audio PCM Platform"
407 + depends on SND_MT76XX_SOC
408 +
409 +config SND_MT76XX_I2S
410 + tristate "MTK SoC I2S Support"
411 + depends on SND_MT76XX_SOC
412 +
413 --- /dev/null
414 +++ b/sound/soc/mtk/Makefile
415 @@ -0,0 +1,39 @@
416 +KBUILD_CFLAGS += -I$(srctree)
417 +
418 +ifeq ($(CONFIG_SND_MT76XX_SOC_MT7620),y)
419 +KBUILD_CFLAGS += -DCONFIG_MT7620 -DCONFIG_RALINK_MT7620
420 +endif
421 +ifeq ($(CONFIG_SND_MT76XX_SOC_MT7628),y)
422 +KBUILD_CFLAGS += -DCONFIG_MT7628 -DCONFIG_RALINK_MT7628
423 +endif
424 +ifeq ($(CONFIG_SOC_MT7620),y)
425 +KBUILD_CFLAGS += -DRALINK_SYSCTL_BASE=0xB0000000
426 +KBUILD_CFLAGS += -DRALINK_INTCL_BASE=0xB0000200
427 +KBUILD_CFLAGS += -DRALINK_PIO_BASE=0xB0000600
428 +KBUILD_CFLAGS += -DRALINK_I2S_BASE=0xB0000A00
429 +KBUILD_CFLAGS += -DRALINK_GDMA_BASE=0xB0002800
430 +KBUILD_CFLAGS += -DCONFIG_GDMA_EVERYBODY
431 +KBUILD_CFLAGS += -DCONFIG_SND_MT76XX_SOC
432 +KBUILD_CFLAGS += -DCONFIG_I2S_WM8960
433 +KBUILD_CFLAGS += -DCONFIG_I2S_MCLK_12P288MHZ
434 +KBUILD_CFLAGS += -DCONFIG_GDMA_EVERYBODY
435 +KBUILD_CFLAGS += -DSURFBOARDINT_DMA=15
436 +KBUILD_CFLAGS += -DRALINK_INTCTL_DMA=128
437 +KBUILD_CFLAGS += -DCONFIG_SND_SOC_WM8960
438 +endif
439 +
440 +# MTK APSoC Platform Support
441 +snd-soc-mt76xx-i2s-ctl-objs := i2s_ctrl.o i2s_debug.o #i2c_wm8960.o
442 +snd-soc-mt76xx-pcm-objs := mt76xx_pcm.o
443 +snd-soc-mt76xx-i2s-objs := mt76xx_i2s.o
444 +
445 +obj-$(CONFIG_SND_MT76XX_PCM) += snd-soc-mt76xx-pcm.o
446 +obj-$(CONFIG_SND_MT76XX_I2S) += snd-soc-mt76xx-i2s-ctl.o snd-soc-mt76xx-i2s.o
447 +
448 +# MTK APSoC Machine Support
449 +snd-soc-mt76xx-machine-objs := mt76xx_machine.o
450 +
451 +obj-$(CONFIG_SND_MT76XX_SOC) += i2c_wm8960.o ralink_gdma.o snd-soc-mt76xx-machine.o
452 +
453 +
454 +
455 --- /dev/null
456 +++ b/sound/soc/mtk/i2c_wm8960.c
457 @@ -0,0 +1,492 @@
458 +#include <linux/kernel.h>
459 +#include <linux/version.h>
460 +#include <linux/init.h>
461 +#include <linux/module.h>
462 +#include <linux/slab.h>
463 +#include <linux/i2c.h>
464 +#include <linux/delay.h>
465 +#include <linux/interrupt.h>
466 +#include <linux/fs.h>
467 +#include <linux/fcntl.h>
468 +#include <linux/cdev.h>
469 +#if defined(CONFIG_ARCH_MT7623)
470 +#include <mt_i2c.h>
471 +#include <mach/mt_gpio.h>
472 +#endif
473 +#include "i2c_wm8960.h"
474 +#include "i2s_ctrl.h"
475 +
476 +
477 +#define BUF_SIZE 20
478 +
479 +#undef MSG
480 +#define MSG printk
481 +
482 +
483 +#if defined(CONFIG_ARCH_MT7623)
484 +/*FIXME*/
485 +//static struct i2c_board_info __initdata i2c_devs1 = { I2C_BOARD_INFO("codec_wm8960", (0X34>>1))};
486 +static struct i2c_board_info __initdata i2c_devs1 = { I2C_BOARD_INFO("codec_wm8960", (0X34))};
487 +
488 +#endif
489 +unsigned long wm_reg_data[56];
490 +struct wm8960_data *wmio;
491 +
492 +struct wm8960_data {
493 + struct i2c_client *client;
494 + struct device *dev;
495 + const char *name;
496 +};
497 +
498 +
499 +void i2c_WM8960_write(u32 reg, u32 data)
500 +{
501 + int ret;
502 + struct i2c_msg msg;
503 + u8 buf[2]={0};
504 +
505 +#if defined(CONFIG_ARCH_MT7623)
506 + unsigned int ext_flag = 0;
507 +
508 + ext_flag &= 0x7FFFFFFF;
509 + ext_flag |= I2C_A_FILTER_MSG;
510 + ext_flag |= I2C_POLLING_FLAG;
511 +#endif
512 +
513 + wm_reg_data[reg] = data;
514 +
515 + buf[0]= (reg<<1)|(0x01&(data>>8));
516 + buf[1]= (data&0xFF);
517 +
518 +#if defined(CONFIG_ARCH_MT7623)
519 + /*FIXME*/
520 + //msg.addr = wmio->client->addr;
521 + msg.addr = wmio->client->addr>>1;
522 +
523 +#else
524 + msg.addr = wmio->client->addr>>1;
525 +#endif
526 + msg.flags = 0;
527 + msg.buf = (char *)buf;
528 + msg.len = 2;
529 +#if defined(CONFIG_ARCH_MT7623)
530 + msg.timing = 80;
531 + msg.ext_flag = ext_flag & 0x7FFFFFFF;
532 +#endif
533 +
534 + ret = i2c_transfer(wmio->client->adapter, &msg, 1);
535 + MSG("[WM8960(%02X)=0x%08X]\n",(unsigned int)reg,(unsigned int)data);
536 +
537 + if (ret <= 0)
538 + printk("%s: i2c write error!\n", __func__);
539 +}
540 +
541 +
542 +
543 +// Reset and power up the WM8960
544 +void audiohw_preinit(void)
545 +{
546 + memset(wm_reg_data, 0 , sizeof(unsigned long)*55);
547 +
548 + i2c_WM8960_write(RESET, RESET_RESET); // Reset (0x0F)
549 +
550 + mdelay(50);
551 + wm_reg_data[RESET] = 0xFFFF;
552 + mdelay(50);
553 +}
554 +
555 +void audiohw_set_apll(int srate)
556 +{
557 + unsigned long data;
558 +
559 + if((srate==8000) || (srate==12000) || (srate==16000) || (srate==24000) || (srate==32000) || (srate==48000))
560 + {
561 + // Provide 12.288MHz SYSCLK
562 + data = wm_reg_data[PLL1];
563 + i2c_WM8960_write(PLL1, data | PLL1_OPCLKDIV_1 | PLL1_SDM_FRACTIONAL | PLL1_PLLPRESCALE_1 | PLL1_PLLN(0x8)); // PLL1 (0x34)
564 +
565 + i2c_WM8960_write(PLL2, PLL2_PLLK_23_16(0x31)); // PLL2 (0x35)
566 + i2c_WM8960_write(PLL3, PLL3_PLLK_15_8(0x26)); // PLL3 (0x36)
567 + i2c_WM8960_write(PLL4, PLL4_PLLK_7_0(0xe9)); // PLL4 (0x37)
568 + }
569 + else if ((srate==11025) || (srate==22050) || (srate==44100))
570 + {
571 + //Provide 11.2896MHz SYSCLK
572 + data = wm_reg_data[PLL1];
573 + i2c_WM8960_write(PLL1, data | PLL1_OPCLKDIV_1 | PLL1_SDM_FRACTIONAL | PLL1_PLLPRESCALE_1 | PLL1_PLLN(0x7)); //PLL1 (0x34)
574 +
575 + i2c_WM8960_write(PLL2, PLL2_PLLK_23_16(0x86)); //PLL2 (0x35)
576 + i2c_WM8960_write(PLL3, PLL3_PLLK_15_8(0xc2)); //PLL3 (0x36)
577 + i2c_WM8960_write(PLL4, PLL4_PLLK_7_0(0x26)); //PLL4 (0x37)
578 + }
579 + else
580 + {
581 + printk("Not support this srate\n");
582 + }
583 + mdelay(3);
584 +}
585 +
586 +
587 +void audiohw_set_frequency(int fsel, int pll_en)
588 +{
589 + MSG("audiohw_set_frequency_=0x%08X\n",fsel);
590 +
591 + if (pll_en)
592 + {
593 + printk("PLL enable\n");
594 + i2c_WM8960_write(CLOCKING1, (fsel<<3) | CLOCKING1_SYSCLKDIV_2 | CLOCKING1_CLKSEL_PLL); //CLOCKING (0x04)=>0x05
595 +
596 + }
597 + else
598 + {
599 + printk("PLL disable\n");
600 + i2c_WM8960_write(CLOCKING1, (fsel<<3));//| CLOCKING1_SYSCLKDIV_2); //CLOCKING (0x04)
601 + }
602 +
603 +}
604 +
605 +//FIXME
606 +int audiohw_set_lineout_vol(int Aout, int vol_l, int vol_r)
607 +{
608 + MSG("audiohw_set_lineout_vol_\n");
609 + switch(Aout)
610 + {
611 + case 1:
612 + //i2c_WM8960_write(LOUT1, LOUT1_LO1VU|LOUT1_LO1ZC|LOUT1_LOUT1VOL(0x7f)); //LOUT1(0x02)
613 + //i2c_WM8960_write(ROUT1, ROUT1_RO1VU|ROUT1_RO1ZC|ROUT1_ROUT1VOL(0x7f)); //ROUT1(0x03)
614 + i2c_WM8960_write(LOUT1, LOUT1_LO1VU|LOUT1_LO1ZC|LOUT1_LOUT1VOL(vol_l)); //LOUT1(0x02)
615 + i2c_WM8960_write(ROUT1, ROUT1_RO1VU|ROUT1_RO1ZC|ROUT1_ROUT1VOL(vol_r)); //ROUT1(0x03)
616 + break;
617 + case 2:
618 + i2c_WM8960_write(LSPK, LSPK_SPKLVU|LSPK_SPKLZC| LSPK_SPKLVOL(vol_l));
619 + i2c_WM8960_write(RSPK, RSPK_SPKRVU|RSPK_SPKRZC| RSPK_SPKRVOL(vol_r));
620 + break;
621 + default:
622 + break;
623 + }
624 + return 0;
625 +}
626 +
627 +//FIXME
628 +int audiohw_set_linein_vol(int vol_l, int vol_r)
629 +{
630 + MSG("audiohw_set_linein_vol_\n");
631 +
632 + i2c_WM8960_write(LINV, LINV_IPVU|LINV_LINVOL(vol_l)); //LINV(0x00)=>0x12b
633 + i2c_WM8960_write(RINV, RINV_IPVU|RINV_RINVOL(vol_r)); //LINV(0x01)=>0x12b
634 +
635 + return 0;
636 +}
637 +
638 +//Set signal path
639 +int audiohw_postinit(int bSlave, int AIn, int AOut, int pll_en, int wordLen24b)
640 +{
641 +
642 + int i;
643 + unsigned long data;
644 +
645 + if(wm_reg_data[RESET]!=0xFFFF)
646 + return 0;
647 +
648 + if(bSlave)
649 + {
650 + MSG("WM8960 slave.....\n");
651 + if(wordLen24b)
652 + {
653 + printk("24 bit word length\n");
654 + i2c_WM8960_write(AINTFCE1, AINTFCE1_WL_24 | AINTFCE1_FORMAT_I2S); //AINTFCE1(0x07)
655 + }
656 + else
657 + {
658 + printk("16 bit word length\n");
659 + i2c_WM8960_write(AINTFCE1, AINTFCE1_WL_16 | AINTFCE1_FORMAT_I2S); //AINTFCE1(0x07)
660 + }
661 + }
662 + else
663 + {
664 + MSG("WM8960 master.....\n");
665 + i2c_WM8960_write(CLOCKING2, 0x1c4);//CLOCKING2_BCLKDIV(0x1c4)); //CLOCKING2(0x08)
666 +
667 + if(wordLen24b)
668 + {
669 + printk("24 bit word length\n");
670 + i2c_WM8960_write(AINTFCE1, AINTFCE1_MS | AINTFCE1_WL_24 | AINTFCE1_FORMAT_I2S); //AINTFCE1(0x07)
671 + }
672 + else
673 + {
674 + printk("16 bit word length\n");
675 + i2c_WM8960_write(AINTFCE1, AINTFCE1_MS | AINTFCE1_WL_16 | AINTFCE1_FORMAT_I2S); //AINTFCE1(0x07)
676 + }
677 + mdelay(5);
678 + }
679 +
680 +
681 + //From app notes: allow Vref to stabilize to reduce clicks
682 + for(i = 0; i < 1000*HZ; i++);
683 +
684 + if(AIn > 0)
685 + {
686 + data = wm_reg_data[PWRMGMT1];
687 + i2c_WM8960_write(PWRMGMT1, data|PWRMGMT1_ADCL|PWRMGMT1_ADCR|PWRMGMT1_AINL |PWRMGMT1_AINR);//|PWRMGMT1_MICB);//PWRMGMT1(0x19)
688 +
689 + data = wm_reg_data[ADDITIONAL1];
690 + i2c_WM8960_write(ADDITIONAL1, data|ADDITIONAL1_DATSEL(0x01)); //ADDITIONAL1(0x17)
691 + i2c_WM8960_write(LADCVOL, LADCVOL_LAVU_EN|LADCVOL_LADCVOL(0xc3)); //LADCVOL(0x15)
692 + i2c_WM8960_write(RADCVOL, RADCVOL_RAVU_EN|RADCVOL_RADCVOL(0xc3)); //RADCVOL(0x16)
693 + i2c_WM8960_write(ADCLPATH, ADCLPATH_LMN1|ADCLPATH_LMIC2B);//|ADCLPATH_LMICBOOST_13DB); //ADCLPATH(0x20)=>(0x108)
694 + i2c_WM8960_write(ADCRPATH, ADCRPATH_RMN1|ADCRPATH_RMIC2B);//|ADCRPATH_RMICBOOST_13DB); //ADCRPATH(0x21)=>(0x108)
695 + i2c_WM8960_write(PWRMGMT3, PWRMGMT3_LMIC|PWRMGMT3_RMIC); //PWRMGMT3(0x2f)
696 +
697 + //i2c_WM8960_write(LINBMIX, 0x000); //LINBMIX(0x2B)
698 +
699 + if (AOut<=0)
700 + {
701 + i2c_WM8960_write(AINTFCE2, 0x40); //FIXME:(0x09)
702 +
703 + data = wm_reg_data[PWRMGMT2];
704 + if(pll_en)
705 + {
706 + i2c_WM8960_write(PWRMGMT2, data|PWRMGMT2_PLL_EN|PWRMGMT2_DACL|PWRMGMT2_DACR); //PWRMGMT2(0x1a)
707 + }
708 + else
709 + {
710 + i2c_WM8960_write(PWRMGMT2, data|PWRMGMT2_DACL|PWRMGMT2_DACR); //PWRMGMT2(0x1a)
711 +
712 + }
713 + }
714 + }
715 + if(AOut>0)
716 + {
717 + //Power management 2 setting
718 + data = wm_reg_data[PWRMGMT2];
719 +
720 + if(pll_en)
721 + {
722 + i2c_WM8960_write(PWRMGMT2, data|PWRMGMT2_PLL_EN|PWRMGMT2_DACL|PWRMGMT2_DACR|PWRMGMT2_LOUT1|PWRMGMT2_ROUT1|PWRMGMT2_SPKL|PWRMGMT2_SPKR); //PWRMGMT2(0x1a)
723 + }
724 + else
725 + {
726 + i2c_WM8960_write(PWRMGMT2, data|PWRMGMT2_DACL|PWRMGMT2_DACR|PWRMGMT2_LOUT1|PWRMGMT2_ROUT1|PWRMGMT2_SPKL|PWRMGMT2_SPKR); //PWRMGMT2(0x1a)
727 +
728 + }
729 +
730 + mdelay(10);
731 +
732 + i2c_WM8960_write(AINTFCE2, 0x40); //FIXME:(0x09)
733 +
734 + i2c_WM8960_write(LEFTGAIN, LEFTGAIN_LDVU|LEFTGAIN_LDACVOL(0xff)); //LEFTGAIN(0x0a)
735 + i2c_WM8960_write(RIGHTGAIN, RIGHTGAIN_RDVU|RIGHTGAIN_RDACVOL(0xff)); //RIGHTGAIN(0x0b)
736 +
737 + i2c_WM8960_write(LEFTMIX1, 0x100); //LEFTMIX1(0x22)
738 + i2c_WM8960_write(RIGHTMIX2, 0x100); //RIGHTMIX2(0x25)
739 +
740 + data = wm_reg_data[PWRMGMT3]; //FIXME
741 + i2c_WM8960_write(PWRMGMT3, data|PWRMGMT3_ROMIX|PWRMGMT3_LOMIX); //PWRMGMT3(0x2f)
742 +
743 + data = wm_reg_data[CLASSDCTRL1]; //CLASSDCTRL1(0x31) SPEAKER FIXME
744 + i2c_WM8960_write(CLASSDCTRL1, 0xf7);//data|CLASSDCTRL1_OP_LRSPK);
745 +
746 + data = wm_reg_data[CLASSDCTRL3]; //CLASSDCTRL3(0x33)
747 + i2c_WM8960_write(CLASSDCTRL3, 0xad);//data|(0x1b));
748 + }
749 +
750 + i2c_WM8960_write(DACCTRL1, 0x000); //DACCTRL1(0x05)
751 +
752 + data = wm_reg_data[PWRMGMT1];
753 + i2c_WM8960_write(PWRMGMT1, data|0x1c0); //FIXME:PWRMGMT1(0x19)
754 +
755 +
756 + printk("WM8960 All initial ok!\n");
757 +
758 + return 0;
759 +
760 +}
761 +
762 +void audiohw_micboost(int boostgain)
763 +{
764 + unsigned long data;
765 +
766 + data = wm_reg_data[ADCLPATH];
767 + i2c_WM8960_write(ADCLPATH, data|(boostgain << 4));
768 +
769 + data = wm_reg_data[ADCRPATH];
770 + i2c_WM8960_write(ADCRPATH, data|(boostgain << 4));
771 +}
772 +
773 +void audiohw_micin(int enableMic)
774 +{
775 + unsigned long data;
776 +
777 + if (enableMic==1)
778 + {
779 + data = wm_reg_data[PWRMGMT1];
780 + i2c_WM8960_write(PWRMGMT1, data|PWRMGMT1_MICB);
781 + }
782 +#if 1
783 + else
784 + {
785 + data = wm_reg_data[PWRMGMT1];
786 + i2c_WM8960_write(PWRMGMT1, data & (~(PWRMGMT1_MICB)));
787 + }
788 +#endif
789 +}
790 +
791 +void audiohw_mute( bool mute)
792 +{
793 + //Mute: Set DACMU = 1 to soft-mute the audio DACs.
794 + //Unmute: Set DACMU = 0 to soft-un-mute the audio DACs.
795 + i2c_WM8960_write(DACCTRL1, mute ? DACCTRL1_DACMU : 0);
796 +}
797 +
798 +
799 +//Nice shutdown of WM8960 codec
800 +void audiohw_close(void)
801 +{
802 + i2c_WM8960_write(DACCTRL1,DACCTRL1_DACMU); //0x05->0x08
803 + i2c_WM8960_write(PWRMGMT1, 0x000); //0x19->0x000
804 + mdelay(400);
805 + i2c_WM8960_write(PWRMGMT2, 0x000); //0x1a->0x000
806 +
807 +}
808 +
809 +void audiohw_loopback(int fsel)
810 +{
811 +}
812 +
813 +void audiohw_codec_exlbk(void)
814 +{
815 + memset(wm_reg_data, 0 , sizeof(unsigned long)*55);
816 +
817 + i2c_WM8960_write(LINV, 0x117); //0x00->0x117
818 + i2c_WM8960_write(RINV, 0x117); //0x01->0x117
819 + i2c_WM8960_write(LOUT1, 0x179); //0x02->0x179
820 + i2c_WM8960_write(ROUT1, 0x179); //0x03->0x179
821 + i2c_WM8960_write(CLOCKING1, 0x00); //0x04->0x00
822 + //i2c_WM8960_write(CLOCKING1, 0x40); //0x04->0x00
823 + i2c_WM8960_write(DACCTRL1, 0x00); //0x05->0x00
824 + i2c_WM8960_write(AINTFCE2, 0x41); //0x09->0x41
825 + i2c_WM8960_write(LADCVOL, 0x1c3); //0x15->0x1c3
826 + i2c_WM8960_write(RADCVOL, 0x1c3); //0x16->0x1c3
827 + i2c_WM8960_write(PWRMGMT1, 0xfc); //0x19->0xfc
828 + i2c_WM8960_write(PWRMGMT2, 0x1e0); //0x1a->0x1e0
829 + i2c_WM8960_write(ADCLPATH, 0x108); //0x20->0x108
830 + i2c_WM8960_write(ADCRPATH, 0x108); //0x21->0x108
831 + i2c_WM8960_write(LEFTMIX1, 0x150); //0x22->0x150
832 + i2c_WM8960_write(RIGHTMIX2, 0x150); //0x25->0x150
833 + i2c_WM8960_write(BYPASS1, 0x00); //0x2d->0x00
834 + i2c_WM8960_write(BYPASS2, 0x00); //0x2e->0x00
835 + i2c_WM8960_write(PWRMGMT3, 0x3c); //0x2f->0x3c
836 +}
837 +
838 +void audiohw_bypass(void)
839 +{
840 + int i;
841 +
842 + memset(wm_reg_data, 0 , sizeof(unsigned long)*55);
843 + i2c_WM8960_write(RESET, 0x000); //0x0f(R15)->0x000
844 +
845 + for(i = 0; i < 1000*HZ; i++);
846 +
847 + i2c_WM8960_write(PWRMGMT1, 0xf0); //0x19(R25)->0xf0
848 + i2c_WM8960_write(PWRMGMT2, 0x60); //0x1a(R26)->0x60
849 + i2c_WM8960_write(PWRMGMT3, 0x3c); //0x2f(R47)->0x3c
850 + i2c_WM8960_write(LINV, 0x117); // 0x00(R0)->0x117
851 + i2c_WM8960_write(RINV, 0x117); // 0x01(R1)->0x117
852 + i2c_WM8960_write(ADCLPATH, 0x108); //0x20(R32)->0x108
853 + i2c_WM8960_write(ADCRPATH, 0x108); //0x21(R33)->0x108
854 + i2c_WM8960_write(BYPASS1, 0x80); //0x2d(R45)->0x80
855 + i2c_WM8960_write(BYPASS2, 0x80); //0x2e(R46)->0x80
856 + i2c_WM8960_write(LOUT1, 0x179); // 0x02(R2)->0x179
857 + i2c_WM8960_write(ROUT1, 0x179); // 0x03(R3)->0x179
858 +}
859 +EXPORT_SYMBOL(audiohw_set_frequency);
860 +EXPORT_SYMBOL(audiohw_close);
861 +EXPORT_SYMBOL(audiohw_postinit);
862 +EXPORT_SYMBOL(audiohw_preinit);
863 +EXPORT_SYMBOL(audiohw_set_apll);
864 +EXPORT_SYMBOL(audiohw_codec_exlbk);
865 +EXPORT_SYMBOL(audiohw_bypass);
866 +EXPORT_SYMBOL(audiohw_set_lineout_vol);
867 +EXPORT_SYMBOL(audiohw_set_linein_vol);
868 +EXPORT_SYMBOL(audiohw_micin);
869 +EXPORT_SYMBOL(audiohw_mute);
870 +EXPORT_SYMBOL(audiohw_loopback);
871 +EXPORT_SYMBOL(audiohw_micboost);
872 +
873 +static int codec_wm8960_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
874 +{
875 + struct wm8960_data *wm;
876 +
877 +printk("*******Enter %s********\n", __func__);
878 +
879 + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
880 + return -EIO;
881 +
882 + wm = devm_kzalloc(&client->dev, sizeof(struct wm8960_data), GFP_KERNEL);
883 + if (!wm)
884 + return -ENOMEM;
885 +
886 +#if defined(CONFIG_ARCH_MT7623)
887 + mt_set_gpio_mode(GPIO242, GPIO_MODE_04);
888 + mt_set_gpio_mode(GPIO243, GPIO_MODE_04);
889 +#endif
890 + wm->client = client;
891 + wm->dev = &client->dev;
892 + wm->name = id->name;
893 + i2c_set_clientdata(client, wm);
894 + wmio = wm;
895 +
896 + memset(wm_reg_data, 0 , sizeof(unsigned long)*55);
897 +
898 + return 0;
899 +}
900 +
901 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
902 +static int codec_wm8960_i2c_remove(struct i2c_client *client)
903 +#else
904 +static int __devexit codec_wm8960_i2c_remove(struct i2c_client *client)
905 +#endif
906 +{
907 + struct wm8960_data *wm = i2c_get_clientdata(client);
908 + kfree(wm);
909 +
910 + return 0;
911 +}
912 +
913 +static const struct i2c_device_id wm8960_id[] = {
914 + { "codec_wm8960", 0 },
915 + {}
916 +};
917 +
918 +static struct i2c_driver codec_wm8960_i2c_driver = {
919 + .driver = {
920 + .name = "codec_wm8960"
921 + },
922 + .probe = codec_wm8960_i2c_probe,
923 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
924 + .remove = codec_wm8960_i2c_remove,
925 +#else
926 + .remove = __devexit_p(codec_wm8960_i2c_remove),
927 +#endif
928 + .id_table = wm8960_id,
929 +};
930 +static int __init wm8960_i2c_init(void)
931 +{
932 +#if defined(CONFIG_ARCH_MT7623)
933 + i2c_register_board_info(1, &i2c_devs1, 1);
934 +#endif
935 + return i2c_add_driver(&codec_wm8960_i2c_driver);;
936 +}
937 +
938 +static void __exit wm8960_i2c_exit(void)
939 +{
940 + i2c_del_driver(&codec_wm8960_i2c_driver);
941 +}
942 +
943 +module_init(wm8960_i2c_init);
944 +module_exit(wm8960_i2c_exit);
945 +
946 +MODULE_AUTHOR("Ryder Lee <ryder.lee@mediatek.com>");
947 +MODULE_DESCRIPTION("WM8960 I2C client driver");
948 +MODULE_LICENSE("GPL");
949 +
950 --- /dev/null
951 +++ b/sound/soc/mtk/i2c_wm8960.h
952 @@ -0,0 +1,288 @@
953 +/* wm8960.h -- WM8960 Soc Audio driver */
954 +#ifndef _WM8960_H
955 +#define _WM8960_H
956 +
957 +#define bool unsigned char
958 +#define false 0
959 +#define true 1
960 +
961 +/* volume/balance/treble/bass interdependency */
962 +#define VOLUME_MIN -730
963 +#define VOLUME_MAX 60
964 +
965 +
966 +/* Register addresses and bits */
967 +#define OUTPUT_MUTED 0x2f
968 +#define OUTPUT_0DB 0x79
969 +
970 +#define LINV 0x00
971 +#define LINV_IPVU (1 << 8) /* FIXME */
972 +#define LINV_LINMUTE (1 << 7)
973 +#define LINV_LIZC (1 << 6)
974 +#define LINV_LINVOL(x) ((x) & 0x3f)
975 +
976 +#define RINV 0x01
977 +#define RINV_IPVU (1 << 8) /* FIXME */
978 +#define RINV_RINMUTE (1 << 7)
979 +#define RINV_RIZC (1 << 6)
980 +#define RINV_RINVOL(x) ((x) & 0x3f)
981 +
982 +#define LOUT1 0x02
983 +#define LOUT1_LO1VU (1 << 8)
984 +#define LOUT1_LO1ZC (1 << 7)
985 +#define LOUT1_LOUT1VOL(x) ((x) & 0x7f)
986 +
987 +#define ROUT1 0x03
988 +#define ROUT1_RO1VU (1 << 8)
989 +#define ROUT1_RO1ZC (1 << 7)
990 +#define ROUT1_ROUT1VOL(x) ((x) & 0x7f)
991 +
992 +#define CLOCKING1 0x04 /* FIXME */
993 +#define CLOCKING1_ADCDIV(x) (((x) & 0x7) << 6)
994 +#define CLOCKING1_DACDIV(x) (((x) & 0x7) << 3)
995 +#define CLOCKING1_SYSCLKDIV_1 (0 << 1)
996 +#define CLOCKING1_SYSCLKDIV_2 (2 << 1)
997 +#define CLOCKING1_CLKSEL_MCLK (0 << 0)
998 +#define CLOCKING1_CLKSEL_PLL (1 << 0)
999 +
1000 +#define DACCTRL1 0x05
1001 +#define DACCTRL1_DATTENUATE (1 << 7)
1002 +#define DACCTRL1_DACMU (1 << 3)
1003 +#define DACCTRL1_DEEMPH_48 (3 << 1)
1004 +#define DACCTRL1_DEEMPH_44 (2 << 1)
1005 +#define DACCTRL1_DEEMPH_32 (1 << 1)
1006 +#define DACCTRL1_DEEMPH_NONE (0 << 1)
1007 +#define DACCTRL1_DEEMPH(x) ((x) & (0x3 << 1))
1008 +
1009 +#define DACCTRL2 0x06
1010 +
1011 +#define AINTFCE1 0x07
1012 +#define AINTFCE1_BCLKINV (1 << 7)
1013 +#define AINTFCE1_MS (1 << 6)
1014 +#define AINTFCE1_LRSWAP (1 << 5)
1015 +#define AINTFCE1_LRP (1 << 4)
1016 +#define AINTFCE1_WL_32 (3 << 2)
1017 +#define AINTFCE1_WL_24 (2 << 2)
1018 +#define AINTFCE1_WL_20 (1 << 2)
1019 +#define AINTFCE1_WL_16 (0 << 2)
1020 +#define AINTFCE1_WL(x) (((x) & 0x3) << 2)
1021 +#define AINTFCE1_FORMAT_DSP (3 << 0)
1022 +#define AINTFCE1_FORMAT_I2S (2 << 0)
1023 +#define AINTFCE1_FORMAT_LJUST (1 << 0)
1024 +#define AINTFCE1_FORMAT_RJUST (0 << 0)
1025 +#define AINTFCE1_FORMAT(x) ((x) & 0x3)
1026 +
1027 +/* FIXME */
1028 +#define CLOCKING2 0x08
1029 +#define CLOCKING2_DCLKDIV(x) (((x) & 0x7) << 6)
1030 +#define CLOCKING2_BCLKDIV(x) (((x) & 0xf) << 0)
1031 +
1032 +#define AINTFCE2 0x09
1033 +#define AINTFCE2_ALRCGPIO_ALRC (0 << 6)
1034 +#define AINTFCE2_ALRCGPIO_GPIO (1 << 6)
1035 +#define AINTFCE2_LOOPBACK (1 << 0)
1036 +
1037 +#define LEFTGAIN 0x0a
1038 +#define LEFTGAIN_LDVU (1 << 8)
1039 +#define LEFTGAIN_LDACVOL(x) ((x) & 0xff)
1040 +
1041 +#define RIGHTGAIN 0x0b
1042 +#define RIGHTGAIN_RDVU (1 << 8)
1043 +#define RIGHTGAIN_RDACVOL(x) ((x) & 0xff)
1044 +
1045 +#define RESET 0x0f
1046 +#define RESET_RESET 0x000
1047 +
1048 +#define ALC1 0x11
1049 +#define ALC1_ALCOFF (0x0 << 7)
1050 +#define ALC1_ALCRONLY (0x1 << 7)
1051 +#define ALC1_ALCLONLY (0x2 << 7)
1052 +#define ALC1_ALCSTEREO (0x3 << 7)
1053 +#define ALC1_ALCSEL(x) (((x) & 0x3) << 7)
1054 +#define ALC1_SET_MAXGAIN(x) ((x & 0x7) << 4)
1055 +#define ALC1_GET_MAXGAIN(x) ((x) & (0x7 << 4))
1056 +#define ALC1_ALCL(x) ((x) & 0x0f)
1057 +
1058 +#define ALC2 0x12
1059 +#define ALC2_MINGAIN(x) ((x & 0x7) << 4)
1060 +#define ALC2_HLD(x) ((x) & 0x0f)
1061 +
1062 +#define ALC3 0x13
1063 +#define ALC3_SET_DCY(x) ((x & 0x0f) << 4)
1064 +#define ALC3_GET_DCY(x) ((x) & (0x0f << 4))
1065 +#define ALC3_ATK(x) ((x) & 0x0f)
1066 +
1067 +#define NOISEGATE 0x14
1068 +#define NOISEGATE_SET_NGTH(x) ((x & 0x1f) << 3)
1069 +#define NOISEGATE_GET_NGTH(x) ((x) & (0x1f << 3))
1070 +#define NOISEGATE_NGAT_ENABLE 1
1071 +
1072 +#define LADCVOL 0x15
1073 +#define LADCVOL_LAVU_EN (1 << 8)
1074 +#define LADCVOL_LADCVOL(x) ((x) & 0x0ff)
1075 +
1076 +#define RADCVOL 0x16
1077 +#define RADCVOL_RAVU_EN (1 << 8)
1078 +#define RADCVOL_RADCVOL(x) ((x) & 0x0ff)
1079 +
1080 +#define ADDITIONAL1 0x17
1081 +#define ADDITIONAL1_TSDEN (1 << 8)
1082 +#define ADDITIONAL1_VSEL_LOWEST (0 << 6)
1083 +#define ADDITIONAL1_VSEL_LOW (1 << 6)
1084 +#define ADDITIONAL1_VSEL_DEFAULT2 (2 << 6)
1085 +#define ADDITIONAL1_VSEL_DEFAULT (3 << 6)
1086 +#define ADDITIONAL1_VSEL(x) (((x) & 0x3) << 6)
1087 +#define ADDITIONAL1_DMONOMIX_STEREO (0 << 4)
1088 +#define ADDITIONAL1_DMONOMIX_MONO (1 << 4)
1089 +#define ADDITIONAL1_DATSEL(x) (((x) & 0x3) << 2)
1090 +#define ADDITIONAL1_TOCLKSEL (1 << 1)
1091 +#define ADDITIONAL1_TOEN (1 << 0)
1092 +
1093 +#define ADDITIONAL2 0x18
1094 +#define ADDITIONAL2_HPSWEN (1 << 6)
1095 +#define ADDITIONAL2_HPSWPOL (1 << 5)
1096 +#define ADDITIONAL2_TRIS (1 << 3)
1097 +#define ADDITIONAL2_LRCM_ON (1 << 2)
1098 +
1099 +#define PWRMGMT1 0x19
1100 +#define PWRMGMT1_VMIDSEL_DISABLED (0 << 7)
1101 +#define PWRMGMT1_VMIDSEL_50K (1 << 7)
1102 +#define PWRMGMT1_VMIDSEL_250K (2 << 7)
1103 +#define PWRMGMT1_VMIDSEL_5K (3 << 7)
1104 +#define PWRMGMT1_VREF (1 << 6)
1105 +#define PWRMGMT1_AINL (1 << 5)
1106 +#define PWRMGMT1_AINR (1 << 4)
1107 +#define PWRMGMT1_ADCL (1 << 3)
1108 +#define PWRMGMT1_ADCR (1 << 2)
1109 +#define PWRMGMT1_MICB (1 << 1)
1110 +#define PWRMGMT1_DIGENB (1 << 0)
1111 +
1112 +#define PWRMGMT2 0x1a
1113 +#define PWRMGMT2_DACL (1 << 8)
1114 +#define PWRMGMT2_DACR (1 << 7)
1115 +#define PWRMGMT2_LOUT1 (1 << 6)
1116 +#define PWRMGMT2_ROUT1 (1 << 5)
1117 +#define PWRMGMT2_SPKL (1 << 4)
1118 +#define PWRMGMT2_SPKR (1 << 3)
1119 +#define PWRMGMT2_OUT3 (1 << 1)
1120 +#define PWRMGMT2_PLL_EN (1 << 0)
1121 +
1122 +#define ADDITIONAL3 0x1b
1123 +#define ADDITIONAL3_VROI (1 << 6)
1124 +#define ADDITIONAL3_OUT3CAP (1 << 3)
1125 +#define ADDITIONAL3_ADC_ALC_SR(x) ((x) & 0x7)
1126 +
1127 +#define ANTIPOP1 0x1c
1128 +#define ANTIPOP2 0x1d
1129 +
1130 +#define ADCLPATH 0x20
1131 +#define ADCLPATH_LMN1 (1 << 8)
1132 +#define ADCLPATH_LMP3 (1 << 7)
1133 +#define ADCLPATH_LMP2 (1 << 6)
1134 +#define ADCLPATH_LMICBOOST_29DB (0x3 << 4)
1135 +#define ADCLPATH_LMICBOOST_20DB (0x2 << 4)
1136 +#define ADCLPATH_LMICBOOST_13DB (0x1 << 4)
1137 +#define ADCLPATH_SET_LMICBOOST(x) ((x & 0x3) << 4)
1138 +#define ADCLPATH_LMIC2B (1 << 3)
1139 +
1140 +
1141 +#define ADCRPATH 0x21
1142 +#define ADCRPATH_RMN1 (1 << 8)
1143 +#define ADCRPATH_RMP3 (1 << 7)
1144 +#define ADCRPATH_RMP2 (1 << 6)
1145 +#define ADCRPATH_RMICBOOST_29DB (0x3 << 4)
1146 +#define ADCRPATH_RMICBOOST_20DB (0x2 << 4)
1147 +#define ADCRPATH_RMICBOOST_13DB (0x1 << 4)
1148 +#define ADCRPATH_SET_RMICBOOST(x) ((x & 0x3) << 4)
1149 +#define ADCRPATH_RMIC2B (1 << 3)
1150 +
1151 +
1152 +#define LEFTMIX1 0x22
1153 +#define LEFTMIX1_LD2LO (1 << 8)
1154 +#define LEFTMIX1_LI2LO (1 << 7)
1155 +#define LEFTMIX1_LI2LO_DEFAULT (5 << 4)
1156 +#define LEFTMIX1_LI2LOVOL(x) (((x) & 0x7) << 4)
1157 +
1158 +#define RIGHTMIX2 0x25
1159 +#define RIGHTMIX2_RD2RO (1 << 8)
1160 +#define RIGHTMIX2_RI2RO (1 << 7)
1161 +#define RIGHTMIX2_RI2RO_DEFAULT (5 << 4)
1162 +#define RIGHTMIX2_RI2ROVOL(x) (((x) & 0x7) << 4)
1163 +
1164 +#define MONOMIX1 0x26
1165 +#define MONOMIX1_L2MO (1 << 7)
1166 +
1167 +#define MONOMIX2 0x27
1168 +#define MONOMIX2_R2MO (1 << 7)
1169 +
1170 +#define LSPK 0x28
1171 +#define LSPK_SPKLVU (1 << 8)
1172 +#define LSPK_SPKLZC (1 << 7)
1173 +#define LSPK_SPKLVOL(x) ((x) & 0x7f)
1174 +
1175 +#define RSPK 0x29
1176 +#define RSPK_SPKRVU (1 << 8)
1177 +#define RSPK_SPKRZC (1 << 7)
1178 +#define RSPK_SPKRVOL(x) ((x) & 0x7f)
1179 +
1180 +#define OUT3V 0x2a
1181 +#define LINBMIX 0x2b
1182 +#define RINBMIX 0x2c
1183 +#define BYPASS1 0x2d
1184 +#define BYPASS2 0x2e
1185 +
1186 +#define PWRMGMT3 0x2f
1187 +#define PWRMGMT3_LMIC (1<<5)
1188 +#define PWRMGMT3_RMIC (1<<4)
1189 +#define PWRMGMT3_LOMIX (1<<3)
1190 +#define PWRMGMT3_ROMIX (1<<2)
1191 +
1192 +#define ADDITIONAL4 0x30
1193 +
1194 +#define CLASSDCTRL1 0x31
1195 +#define CLASSDCTRL1_OP_OFF (0<<6)
1196 +#define CLASSDCTRL1_OP_LSPK (1<<6)
1197 +#define CLASSDCTRL1_OP_RSPK (2<<6)
1198 +#define CLASSDCTRL1_OP_LRSPK (3<<6)
1199 +
1200 +#define CLASSDCTRL3 0x33
1201 +
1202 +#define PLL1 0x34
1203 +#define PLL1_OPCLKDIV_1 (0<<6)
1204 +#define PLL1_OPCLKDIV_2 (1<<6)
1205 +#define PLL1_OPCLKDIV_3 (2<<6)
1206 +#define PLL1_OPCLKDIV_4 (3<<6)
1207 +#define PLL1_OPCLKDIV_5p5 (4<<6)
1208 +#define PLL1_OPCLKDIV_6 (5<<6)
1209 +#define PLL1_SDM_INTERGER (0<<5)
1210 +#define PLL1_SDM_FRACTIONAL (1<<5)
1211 +#define PLL1_PLLPRESCALE_1 (0<<4)
1212 +#define PLL1_PLLPRESCALE_2 (1<<4)
1213 +#define PLL1_PLLN(x) ((x) & 0xf)
1214 +
1215 +#define PLL2 0x35
1216 +#define PLL2_PLLK_23_16(x) ((x) & 0x1ff)
1217 +
1218 +#define PLL3 0x36
1219 +#define PLL3_PLLK_15_8(x) ((x) & 0x1ff)
1220 +
1221 +#define PLL4 0x37
1222 +#define PLL4_PLLK_7_0(x) ((x) & 0x1ff)
1223 +
1224 +/* codec API */
1225 +void audiohw_preinit(void);
1226 +int audiohw_postinit(int bSlave, int AIn, int AOut, int pll_en, int wordLen24b);
1227 +void audiohw_close(void);
1228 +void audiohw_set_frequency(int fsel, int pll_en);
1229 +void audiohw_mute(bool mute);
1230 +void audiohw_micboost(int boostgain);
1231 +void audiohw_micin(int enableMic);
1232 +void audiohw_set_apll(int srate);
1233 +int audiohw_set_lineout_vol(int Aout, int vol_l, int vol_r);
1234 +int audiohw_set_linein_vol(int vol_l, int vol_r);
1235 +void audiohw_mute( bool mute);
1236 +void audiohw_loopback(int fsel);
1237 +void audiohw_codec_exlbk(void);
1238 +void audiohw_bypass(void);
1239 +
1240 +#endif /* _WM875x_H */
1241 --- /dev/null
1242 +++ b/sound/soc/mtk/i2s_ctrl.c
1243 @@ -0,0 +1,3524 @@
1244 +#include <linux/init.h>
1245 +#include <linux/version.h>
1246 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
1247 +#include <linux/sched.h>
1248 +#endif
1249 +#include <linux/module.h>
1250 +#include <linux/kernel.h> /* _printk() */
1251 +#include <linux/slab.h> /* kmalloc() */
1252 +#include <linux/fs.h> /* everything... */
1253 +#include <linux/errno.h> /* error codes */
1254 +#include <linux/types.h> /* size_t */
1255 +#include <linux/proc_fs.h>
1256 +#include <linux/fcntl.h> /* O_ACCMODE */
1257 +#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,14)
1258 +#include <asm/system.h> /* cli(), *_flags */
1259 +#endif
1260 +#include <asm/uaccess.h> /* copy_from/to_user */
1261 +#include <linux/interrupt.h>
1262 +#include <linux/mm.h>
1263 +#include <linux/mm_types.h>
1264 +#include <linux/pci.h>
1265 +#include <linux/delay.h>
1266 +#include "ralink_gdma.h"
1267 +#if defined(CONFIG_I2S_WITH_AEC)
1268 +#include "../aec/aec_api.h"
1269 +#endif
1270 +
1271 +#ifdef CONFIG_DEVFS_FS
1272 +#include <linux/devfs_fs_kernel.h>
1273 +static devfs_handle_t devfs_handle;
1274 +#endif
1275 +
1276 +#include "i2s_ctrl.h"
1277 +
1278 +#if defined(CONFIG_SND_MT76XX_SOC)
1279 +#include <sound/soc/mtk/mt76xx_machine.h>
1280 +#endif
1281 +
1282 +#if defined(CONFIG_I2S_WM8750)
1283 +#include "../codec/i2c_wm8750.h"
1284 +#endif
1285 +#if defined(CONFIG_I2S_WM8751)
1286 +#include "../codec/i2c_wm8751.h"
1287 +#endif
1288 +#if defined(CONFIG_I2S_WM8960)
1289 +#include "i2c_wm8960.h"
1290 +#endif
1291 +
1292 +static int i2sdrv_major = 191;
1293 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
1294 +#else
1295 +static struct class *i2smodule_class;
1296 +#endif
1297 +
1298 +static int _printk(char *fmt, ...)
1299 +{
1300 + return 0;
1301 +}
1302 +
1303 +/* external functions declarations */
1304 +#if defined(CONFIG_I2S_WM8960)
1305 +extern void audiohw_set_frequency(int fsel, int codec_pll_en);
1306 +void audiohw_set_apll(int srate);
1307 +#elif defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
1308 +extern void audiohw_set_frequency(int fsel);
1309 +#endif
1310 +#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
1311 +extern int audiohw_set_lineout_vol(int Aout, int vol_l, int vol_r);
1312 +extern int audiohw_set_master_vol(int vol_l, int vol_r);
1313 +extern int audiohw_set_linein_vol(int vol_l, int vol_r);
1314 +#endif
1315 +
1316 +extern void audiohw_micboost(int boostgain);
1317 +
1318 +extern int GdmaI2sTx(uint32_t Src, uint32_t Dst, uint8_t TxNo, uint16_t TransCount,
1319 + void (*DoneIntCallback)(uint32_t data),
1320 + void (*UnMaskIntCallback)(uint32_t data));
1321 +
1322 +extern int GdmaI2sRx(uint32_t Src, uint32_t Dst, uint8_t RxNo, uint16_t TransCount,
1323 + void (*DoneIntCallback)(uint32_t data),
1324 + void (*UnMaskIntCallback)(uint32_t data));
1325 +
1326 +extern int GdmaMaskChannel(uint32_t ChNum);
1327 +
1328 +extern int GdmaUnMaskChannel(uint32_t ChNum);
1329 +
1330 +/* internal functions declarations */
1331 +irqreturn_t i2s_irq_isr(int irq, void *irqaction);
1332 +int i2s_debug_cmd(unsigned int cmd, unsigned long arg);
1333 +
1334 +/* forward declarations for _fops */
1335 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
1336 +static long i2s_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
1337 +#else
1338 +static int i2s_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
1339 +#endif
1340 +static int i2s_mmap(struct file *file, struct vm_area_struct *vma);
1341 +static int i2s_open(struct inode *inode, struct file *file);
1342 +static int i2s_release(struct inode *inode, struct file *file);
1343 +int i2s_mmap_alloc(unsigned long size);
1344 +int i2s_mmap_remap(struct vm_area_struct *vma, unsigned long size);
1345 +
1346 +/* global varable definitions */
1347 +i2s_config_type i2s_config;
1348 +i2s_status_type i2s_status;
1349 +i2s_config_type* pi2s_config = &i2s_config;;
1350 +i2s_status_type* pi2s_status = &i2s_status;;
1351 +
1352 +static inline long
1353 +ugly_hack_sleep_on_timeout(wait_queue_head_t *q, long timeout)
1354 +{
1355 + unsigned long flags;
1356 + wait_queue_t wait;
1357 +
1358 + init_waitqueue_entry(&wait, current);
1359 +
1360 + __set_current_state(TASK_INTERRUPTIBLE);
1361 + spin_lock_irqsave(&q->lock, flags);
1362 + __add_wait_queue(q, &wait);
1363 + spin_unlock(&q->lock);
1364 +
1365 + timeout = schedule_timeout(timeout);
1366 +
1367 + spin_lock_irq(&q->lock);
1368 + __remove_wait_queue(q, &wait);
1369 + spin_unlock_irqrestore(&q->lock, flags);
1370 +
1371 + return timeout;
1372 +}
1373 +
1374 +#define interruptible_sleep_on(x) \
1375 + ugly_hack_sleep_on_timeout(x, MAX_SCHEDULE_TIMEOUT);
1376 +
1377 +
1378 +#if defined(ARM_ARCH)
1379 +static dma_addr_t i2s_txdma_addr0, i2s_txdma_addr1;
1380 +static dma_addr_t i2s_rxdma_addr0, i2s_rxdma_addr1;
1381 +#define I2S_TX_FIFO_WREG_PHY (I2S_TX_FIFO_WREG & 0x1FFFFFFF)
1382 +#define I2S_RX_FIFO_RREG_PHY (I2S_RX_FIFO_RREG & 0x1FFFFFFF)
1383 +#else
1384 +static dma_addr_t i2s_txdma_addr, i2s_rxdma_addr;
1385 +#endif
1386 +static dma_addr_t i2s_mmap_addr[MAX_I2S_PAGE*2];
1387 + /* 8khz 11.025khz 12khz 16khz 22.05khz 24Khz 32khz 44.1khz 48khz 88.2khz 96khz*/
1388 +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};
1389 +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};
1390 +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};
1391 +#if defined(CONFIG_I2S_WM8750) || defined(CONFIG_SND_SOC_WM8750)
1392 + /* 8k 11.025k 12k 16k 22.05k 24k 32k 44.1k 48k 88.2k 96k*/
1393 +unsigned long i2s_codec_12p288Mhz[11] = {0x0C, 0x00, 0x10, 0x14, 0x38, 0x38, 0x18, 0x20, 0x00, 0x00, 0x1C};
1394 +unsigned long i2s_codec_12Mhz[11] = {0x0C, 0x32, 0x10, 0x14, 0x37, 0x38, 0x18, 0x22, 0x00, 0x3E, 0x1C};
1395 +unsigned long i2s_codec_24p576Mhz[11] = {0x4C, 0x00, 0x50, 0x54, 0x00, 0x78, 0x58, 0x00, 0x40, 0x00, 0x5C};
1396 +unsigned long i2s_codec_18p432Mhz[11] = {0x0e, 0x32, 0x12, 0x16, 0x36, 0x3a, 0x1a, 0x22, 0x02, 0x3e, 0x1e};
1397 +#endif
1398 +#if defined(CONFIG_I2S_WM8751) || defined(CONFIG_SND_SOC_WM8751)
1399 +unsigned long i2s_codec_12p288Mhz[11] = {0x04, 0x00, 0x10, 0x14, 0x38, 0x38, 0x18, 0x20, 0x00, 0x00, 0x1C};
1400 +unsigned long i2s_codec_12Mhz[11] = {0x04, 0x32, 0x10, 0x14, 0x37, 0x38, 0x18, 0x22, 0x00, 0x3E, 0x1C};
1401 +#endif
1402 +#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_SND_SOC_WM8960)
1403 +unsigned long i2s_codec_12p288Mhz[11] = {0x36, 0x24, 0x24, 0x1b, 0x12, 0x12, 0x09, 0x00, 0x00, 0x00, 0x00};
1404 +unsigned long i2s_codec_12Mhz[11] = {0x36, 0x24, 0x24, 0x1b, 0x12, 0x12, 0x09, 0x00, 0x00, 0x00, 0x00};
1405 +#endif
1406 +EXPORT_SYMBOL(i2s_codec_12p288Mhz);
1407 +EXPORT_SYMBOL(i2s_codec_12Mhz);
1408 +
1409 +#if defined(CONFIG_RALINK_RT6855A)
1410 + /* 8K 11.025k 12k 16k 22.05k 24k 32k 44.1K 48k 88.2k 96k */
1411 +unsigned long i2s_inclk_int[11] = { 97, 70, 65, 48, 35, 32, 24, 17, 16, 12, 8};
1412 +unsigned long i2s_inclk_comp[11] = { 336, 441, 53, 424, 220, 282, 212, 366, 141, 185, 70};
1413 +#elif defined (CONFIG_RALINK_MT7621)
1414 +#ifdef MT7621_ASIC_BOARD
1415 +#if defined (CONFIG_I2S_MCLK_12P288MHZ)
1416 +unsigned long i2s_inclk_int[11] = { 576, 384, 0, 288, 192, 192, 144, 96, 96, 48, 48};
1417 +unsigned long i2s_inclk_comp[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1418 +#elif defined(CONFIG_I2S_MCLK_12MHZ)
1419 +unsigned long i2s_inclk_int[11] = {1171, 850, 0, 585, 425, 390, 292, 212, 195, 106, 97};
1420 +unsigned long i2s_inclk_comp[11] = { 448, 174, 0, 480, 87, 320, 496, 299, 160, 149, 336};
1421 +#endif
1422 +#else //MT7621_FPGA_BOARD
1423 +unsigned long i2s_inclk_int[11] = { 529, 384, 0, 264, 192, 176, 132, 96, 88, 48, 44};
1424 +unsigned long i2s_inclk_comp[11] = { 102, 0, 0, 307, 0, 204, 153, 0, 102, 0, 51};
1425 +#endif
1426 +#elif defined (CONFIG_RALINK_MT7628)
1427 +#ifdef MT7628_ASIC_BOARD
1428 + /* 8K 11.025k 12k 16k 22.05k 24k 32k 44.1K 48k 88.2k 96k 176k 192k */
1429 +unsigned long i2s_inclk_int_16bit[13] = {937, 680, 0, 468, 340, 312, 234, 170, 156, 85, 78, 42, 39};
1430 +unsigned long i2s_inclk_comp_16bit[13]= {256, 139, 0, 384, 69, 256, 192, 34, 128, 17, 64, 267, 32};
1431 +unsigned long i2s_inclk_int_24bit[13] = {625, 404, 0, 312, 226, 208, 156, 113, 104, 56, 52, 28, 26};
1432 +unsigned long i2s_inclk_comp_24bit[13]= { 0, 404, 0, 256, 387, 170, 128, 193, 85, 352, 42, 176, 21};
1433 +#else
1434 + /* 8K 11.025k 12k 16k 22.05k 24k 32k 44.1K 48k 88.2k 96k 176k 192k */
1435 +unsigned long i2s_inclk_int_16bit[13] = {468, 340, 0, 234, 170, 156, 117, 85, 78, 42, 39, 21, 19};
1436 +unsigned long i2s_inclk_comp_16bit[13]= {384, 69, 0, 192, 34, 128, 96, 17, 64, 264, 32, 133, 272};
1437 +unsigned long i2s_inclk_int_24bit[13] = {312, 202, 0, 156, 113, 104, 78, 56, 52, 28, 26, 14, 13};
1438 +unsigned long i2s_inclk_comp_24bit[13]= {256, 202, 0, 128, 193, 85, 64, 352, 42, 176, 21, 88, 10};
1439 +#endif
1440 +#elif defined (CONFIG_ARCH_MT7623)
1441 +#if defined MT7623_ASIC_BOARD
1442 + /* 8K 11.025k 12k 16k 22.05k 24k 32k 44.1K 48k 88.2k 96k 176k 192k */
1443 +unsigned long i2s_inclk_int_16bit[13] = {576, 384, 0, 288, 192, 192, 144, 96, 96, 48, 48, 24, 24};
1444 +unsigned long i2s_inclk_comp_16bit[13]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1445 +unsigned long i2s_inclk_int_24bit[13] = {384, 256, 0, 192, 128, 128, 96, 64, 64, 32, 32, 16, 16};
1446 +unsigned long i2s_inclk_comp_24bit[13]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1447 +#else
1448 + /* 8K 11.025k 12k 16k 22.05k 24k 32k 44.1K 48k 88.2k 96k 176k 192k */
1449 +unsigned long i2s_inclk_int_16bit[13] = {72, 48, 0, 36, 24, 24, 18, 12, 12, 6, 6, 3, 3};
1450 +unsigned long i2s_inclk_comp_16bit[13]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1451 +unsigned long i2s_inclk_int_24bit[13] = {48, 32, 0, 24, 16, 16, 12, 8, 8, 4, 4, 2, 2};
1452 +unsigned long i2s_inclk_comp_24bit[13]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1453 +#endif
1454 +#else
1455 + /* 8K 11.025k 12k 16k 22.05k 24k 32k 44.1K 48k 88.2k 96k */
1456 +unsigned long i2s_inclk_int[11] = { 78, 56, 52, 39, 28, 26, 19, 14, 13, 9, 6};
1457 +unsigned long i2s_inclk_comp[11] = { 64, 352, 42, 32, 176, 21, 272, 88, 10, 455, 261};
1458 +#endif
1459 +
1460 +#if defined(CONFIG_I2S_WITH_AEC)
1461 +aecFuncTbl_t *aecFuncP;
1462 +#endif
1463 +/* USB mode 22.05Khz register value in datasheet is 0x36 but will cause slow clock, 0x37 is correct value */
1464 +/* USB mode 44.1Khz register value in datasheet is 0x22 but will cause slow clock, 0x23 is correct value */
1465 +
1466 +struct tasklet_struct i2s_tx_tasklet;
1467 +struct tasklet_struct i2s_rx_tasklet;
1468 +EXPORT_SYMBOL(i2s_tx_tasklet);
1469 +EXPORT_SYMBOL(i2s_rx_tasklet);
1470 +
1471 +char test_buf[I2S_PAGE_SIZE];
1472 +char test_buf_1[I2S_PAGE_SIZE];
1473 +char test_buf_2[I2S_PAGE_SIZE];
1474 +
1475 +static const struct file_operations i2s_fops = {
1476 + owner : THIS_MODULE,
1477 + mmap : i2s_mmap,
1478 + open : i2s_open,
1479 + release : i2s_release,
1480 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
1481 + unlocked_ioctl: i2s_ioctl,
1482 +#else
1483 + ioctl : i2s_ioctl,
1484 +#endif
1485 +};
1486 +
1487 +int __init i2s_mod_init(void)
1488 +{
1489 + int result;
1490 +
1491 + _printk("******* i2s module init **********\n");
1492 + /* register device with kernel */
1493 +#ifdef CONFIG_DEVFS_FS
1494 + if(devfs_register_chrdev(i2sdrv_major, I2SDRV_DEVNAME , &i2s_fops)) {
1495 + _printk(KERN_WARNING " i2s: can't create device node - %s\n", I2SDRV_DEVNAME);
1496 + return -EIO;
1497 + }
1498 +
1499 + devfs_handle = devfs_register(NULL, I2SDRV_DEVNAME, DEVFS_FL_DEFAULT, i2sdrv_major, 0,
1500 + S_IFCHR | S_IRUGO | S_IWUGO, &i2s_fops, NULL);
1501 +#else
1502 + result = register_chrdev(i2sdrv_major, I2SDRV_DEVNAME, &i2s_fops);
1503 + if (result < 0) {
1504 + _printk(KERN_WARNING "i2s: can't get major %d\n",i2sdrv_major);
1505 + return result;
1506 + }
1507 +
1508 + if (i2sdrv_major == 0) {
1509 + i2sdrv_major = result; /* dynamic */
1510 + }
1511 +#endif
1512 +
1513 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
1514 +#else
1515 + i2smodule_class=class_create(THIS_MODULE, I2SDRV_DEVNAME);
1516 + if (IS_ERR(i2smodule_class))
1517 + return -EFAULT;
1518 + device_create(i2smodule_class, NULL, MKDEV(i2sdrv_major, 0), I2SDRV_DEVNAME);
1519 +#endif
1520 +
1521 +#if defined(CONFIG_I2S_WITH_AEC)
1522 + _printk("AEC FuncP init \n");
1523 + /*Add by mtk04880*/
1524 + aecFuncP = kmalloc(sizeof(aecFuncTbl_t), GFP_KERNEL);
1525 + /*If aecFuncP cannot request memory,it will be ignored in I2S module. Since AEC & I2S are independent
1526 + * when AEC module is inserted,It will return err message (but I2S will keep running without AEC support)
1527 + * */
1528 + if(aecFuncP){
1529 + memset(aecFuncP,0,sizeof(aecFuncTbl_t));
1530 + }
1531 +#endif
1532 +
1533 + return 0;
1534 +}
1535 +
1536 +void i2s_mod_exit(void)
1537 +{
1538 + _printk("************ i2s module exit *************\n");
1539 +#ifdef CONFIG_DEVFS_FS
1540 + devfs_unregister_chrdev(i2sdrv_major, I2SDRV_DEVNAME);
1541 + devfs_unregister(devfs_handle);
1542 +#else
1543 + unregister_chrdev(i2sdrv_major, I2SDRV_DEVNAME);
1544 +#endif
1545 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
1546 +#else
1547 + device_destroy(i2smodule_class,MKDEV(i2sdrv_major, 0));
1548 + class_destroy(i2smodule_class);
1549 +#endif
1550 + return ;
1551 +}
1552 +
1553 +
1554 +int i2s_open(struct inode *inode, struct file *filp)
1555 +{
1556 +#if defined(I2S_HW_INTERRUPT_EN)&&(I2S_SW_IRQ_EN)
1557 + int Ret;
1558 +#endif
1559 + int minor = iminor(inode);
1560 +
1561 + if (minor >= I2S_MAX_DEV)
1562 + return -ENODEV;
1563 +
1564 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
1565 + MOD_INC_USE_COUNT;
1566 +#else
1567 + try_module_get(THIS_MODULE);
1568 +#endif
1569 +
1570 + if (filp->f_flags & O_NONBLOCK) {
1571 + MSG("filep->f_flags O_NONBLOCK set\n");
1572 + return -EAGAIN;
1573 + }
1574 +
1575 + /* set i2s_config */
1576 + filp->private_data = pi2s_config;
1577 + memset(pi2s_config, 0, sizeof(i2s_config_type));
1578 +#ifdef I2S_STATISTIC
1579 + memset(pi2s_status, 0, sizeof(i2s_status_type));
1580 +#endif
1581 + i2s_param_init(pi2s_config);
1582 +
1583 +#if defined(I2S_HW_INTERRUPT_EN)&&(I2S_SW_IRQ_EN)
1584 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
1585 + Ret = request_irq(SURFBOARDINT_I2S, i2s_irq_isr, IRQF_DISABLED, "Ralink_I2S", NULL);
1586 +#else
1587 + Ret = request_irq(SURFBOARDINT_I2S, i2s_irq_isr, SA_INTERRUPT, "Ralink_I2S", NULL);
1588 +#endif
1589 +
1590 + if(Ret){
1591 + MSG("IRQ %d is not free.\n", SURFBOARDINT_I2S);
1592 + i2s_release(inode, filp);
1593 + return -1;
1594 + }
1595 +#endif
1596 +
1597 + init_waitqueue_head(&(pi2s_config->i2s_tx_qh));
1598 + init_waitqueue_head(&(pi2s_config->i2s_rx_qh));
1599 + spin_lock_init(&pi2s_config->lock);
1600 +
1601 + return 0;
1602 +}
1603 +
1604 +
1605 +static int i2s_release(struct inode *inode, struct file *filp)
1606 +{
1607 + i2s_config_type* ptri2s_config;
1608 +
1609 + /* decrement usage count */
1610 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
1611 + MOD_DEC_USE_COUNT;
1612 +#else
1613 + module_put(THIS_MODULE);
1614 +#endif
1615 +
1616 +#if defined(I2S_HW_INTERRUPT_EN)&&(I2S_SW_IRQ_EN)
1617 + free_irq(SURFBOARDINT_I2S, NULL);
1618 +#endif
1619 +
1620 + ptri2s_config = filp->private_data;
1621 + if(ptri2s_config==NULL)
1622 + goto EXIT;
1623 +#ifdef CONFIG_I2S_MMAP
1624 + i2s_mem_unmap(ptri2s_config);
1625 +#else
1626 + i2s_txbuf_free(ptri2s_config);
1627 + i2s_rxbuf_free(ptri2s_config);
1628 +#endif
1629 + /* free buffer */
1630 + i2s_txPagebuf_free(ptri2s_config);
1631 + i2s_rxPagebuf_free(ptri2s_config);
1632 +EXIT:
1633 + MSG("i2s_release succeeds\n");
1634 + return 0;
1635 +}
1636 +
1637 +int i2s_mmap_alloc(unsigned long size)
1638 +{
1639 + int i;
1640 + u32 page_size;
1641 + int first_index;
1642 +
1643 + page_size = I2S_PAGE_SIZE;
1644 +
1645 + if ((pi2s_config->mmap_index == 0) || (pi2s_config->mmap_index == MAX_I2S_PAGE))
1646 + {
1647 + MSG("mmap_index=%d\n", pi2s_config->mmap_index);
1648 +
1649 + first_index = pi2s_config->mmap_index;
1650 + pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index] = kmalloc(size, GFP_DMA);
1651 + i2s_mmap_addr[pi2s_config->mmap_index] = (dma_addr_t)dma_map_single(NULL, pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index], size, DMA_BIDIRECTIONAL);
1652 +
1653 + if( pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index] == NULL )
1654 + {
1655 + MSG("i2s_mmap failed\n");
1656 + return -1;
1657 + }
1658 + }
1659 + else
1660 + {
1661 + _printk("illegal index:%d\n", pi2s_config->mmap_index);
1662 + return -1;
1663 + }
1664 +
1665 + _printk("MMAP[%d]=0x%08X, i2s_mmap_addr[%d]=0x%08x\n",
1666 + pi2s_config->mmap_index, (u32)pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index],
1667 + pi2s_config->mmap_index, i2s_mmap_addr[pi2s_config->mmap_index]);
1668 +
1669 + memset(pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index], 0, size);
1670 + pi2s_config->mmap_index++;
1671 +
1672 + for (i=1; i<MAX_I2S_PAGE; i++)
1673 + {
1674 + i2s_mmap_addr[pi2s_config->mmap_index] = i2s_mmap_addr[first_index] + i*page_size;
1675 + pi2s_config->pMMAPBufPtr[pi2s_config->mmap_index] = pi2s_config->pMMAPBufPtr[first_index] + i*page_size;
1676 +
1677 + _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]);
1678 +
1679 + /* Notice: The last mmap_index's value should be MAX_I2S_PAGE or MAX_I2S_PAGE*2 */
1680 + pi2s_config->mmap_index++;
1681 + }
1682 +
1683 + return 0;
1684 +}
1685 +
1686 +int i2s_mmap_remap(struct vm_area_struct *vma, unsigned long size)
1687 +{
1688 + int nRet;
1689 +
1690 + if((pi2s_config->pMMAPBufPtr[0]!=NULL) && (pi2s_config->mmap_index == MAX_I2S_PAGE))
1691 + {
1692 + MSG("i2s_mmap_remap:0\n");
1693 + nRet = remap_pfn_range(vma, vma->vm_start, virt_to_phys((void *)pi2s_config->pMMAPBufPtr[0]) >> PAGE_SHIFT, size, vma->vm_page_prot);
1694 +
1695 + if( nRet != 0 )
1696 + {
1697 + _printk("i2s_mmap->remap_pfn_range failed\n");
1698 + return -EIO;
1699 + }
1700 + }
1701 +
1702 + if((pi2s_config->pMMAPBufPtr[MAX_I2S_PAGE]!=NULL) && (pi2s_config->mmap_index == MAX_I2S_PAGE*2))
1703 + {
1704 + MSG("i2s_mmap_remap:%d\n", MAX_I2S_PAGE);
1705 +
1706 + 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);
1707 +
1708 + if( nRet != 0 )
1709 + {
1710 + _printk("i2s_mmap->remap_pfn_range failed\n");
1711 + return -EIO;
1712 + }
1713 + }
1714 +
1715 + return 0;
1716 +}
1717 +
1718 +static int i2s_mmap(struct file *filp, struct vm_area_struct *vma)
1719 +{
1720 + unsigned long size = vma->vm_end-vma->vm_start;
1721 + _printk("page_size=%d, ksize=%lu\n", I2S_PAGE_SIZE, size);
1722 +
1723 + if((pi2s_config->pMMAPBufPtr[0]==NULL)&&(pi2s_config->mmap_index!=0))
1724 + pi2s_config->mmap_index = 0;
1725 +
1726 + _printk("%s: vm_start=%08X,vm_end=%08X\n", __func__, (u32)vma->vm_start, (u32)vma->vm_end);
1727 +
1728 + /* Do memory allocate and dma sync */
1729 + i2s_mmap_alloc(size);
1730 +
1731 + i2s_mmap_remap(vma, size);
1732 +
1733 +
1734 + return 0;
1735 +}
1736 +
1737 +int i2s_mem_unmap(i2s_config_type* ptri2s_config)
1738 +{
1739 + u32 page_size;
1740 +
1741 + page_size = I2S_PAGE_SIZE;
1742 +
1743 + if(ptri2s_config->pMMAPBufPtr[0])
1744 + {
1745 + _printk("ummap MMAP[0]=0x%08X\n", (u32)ptri2s_config->pMMAPBufPtr[0]);
1746 + dma_unmap_single(NULL, i2s_mmap_addr[0], MAX_I2S_PAGE*page_size, DMA_BIDIRECTIONAL);
1747 + kfree(ptri2s_config->pMMAPBufPtr[0]);
1748 + }
1749 +
1750 + if(ptri2s_config->pMMAPBufPtr[MAX_I2S_PAGE])
1751 + {
1752 + _printk("ummap MMAP[%d]=0x%08X\n", MAX_I2S_PAGE, (u32)ptri2s_config->pMMAPBufPtr[MAX_I2S_PAGE]);
1753 + dma_unmap_single(NULL, i2s_mmap_addr[MAX_I2S_PAGE], MAX_I2S_PAGE*page_size, DMA_BIDIRECTIONAL);
1754 + kfree(ptri2s_config->pMMAPBufPtr[MAX_I2S_PAGE]);
1755 + }
1756 +
1757 + ptri2s_config->mmap_index = 0;
1758 +
1759 + return 0;
1760 +}
1761 +
1762 +int i2s_param_init(i2s_config_type* ptri2s_config)
1763 +{
1764 + ptri2s_config->dmach = GDMA_I2S_TX0;
1765 + ptri2s_config->tx_ff_thres = CONFIG_I2S_TFF_THRES;
1766 + ptri2s_config->tx_ch_swap = CONFIG_I2S_CH_SWAP;
1767 + ptri2s_config->rx_ff_thres = CONFIG_I2S_TFF_THRES;
1768 + ptri2s_config->rx_ch_swap = CONFIG_I2S_CH_SWAP;
1769 + ptri2s_config->slave_en = CONFIG_I2S_SLAVE_EN;
1770 + ptri2s_config->codec_pll_en = CONFIG_I2S_CODEC_PLL_EN;
1771 +
1772 + ptri2s_config->bRxDMAEnable = 0;
1773 + ptri2s_config->bTxDMAEnable = 0;
1774 + //ptri2s_config->bALSAEnable = 0;
1775 + ptri2s_config->srate = 44100;
1776 + ptri2s_config->txvol = 0;
1777 + ptri2s_config->rxvol = 0;
1778 + ptri2s_config->lbk = 0;
1779 + ptri2s_config->extlbk = 0;
1780 + ptri2s_config->txrx_coexist = 0;
1781 + ptri2s_config->wordlen_24b = 0;
1782 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
1783 + ptri2s_config->sys_endian = 0;
1784 + ptri2s_config->fmt = 0;
1785 +#endif
1786 + ptri2s_config->micboost = 0;
1787 + ptri2s_config->micin = 0;
1788 +
1789 + return 0;
1790 +}
1791 +
1792 +int i2s_txbuf_alloc(i2s_config_type* ptri2s_config)
1793 +{
1794 + int i;
1795 +
1796 + for( i = 0 ; i < MAX_I2S_PAGE ; i ++ )
1797 + {
1798 +#if defined(CONFIG_I2S_MMAP)
1799 + ptri2s_config->pMMAPTxBufPtr[i] = ptri2s_config->pMMAPBufPtr[i];
1800 +#else
1801 + if(ptri2s_config->pMMAPTxBufPtr[i]==NULL)
1802 + ptri2s_config->pMMAPTxBufPtr[i] = kmalloc(I2S_PAGE_SIZE, GFP_KERNEL);
1803 +#endif
1804 + memset(ptri2s_config->pMMAPTxBufPtr[i], 0, I2S_PAGE_SIZE);
1805 + }
1806 +
1807 + return 0;
1808 +}
1809 +
1810 +int i2s_rxbuf_alloc(i2s_config_type* ptri2s_config)
1811 +{
1812 + int i;
1813 +
1814 + for( i = 0 ; i < MAX_I2S_PAGE ; i ++ )
1815 + {
1816 +#if defined(CONFIG_I2S_MMAP)
1817 + ptri2s_config->pMMAPRxBufPtr[i] = ptri2s_config->pMMAPBufPtr[i+(ptri2s_config->mmap_index-MAX_I2S_PAGE)];
1818 +#else
1819 + if(ptri2s_config->pMMAPRxBufPtr[i]==NULL)
1820 + ptri2s_config->pMMAPRxBufPtr[i] = kmalloc(I2S_PAGE_SIZE, GFP_KERNEL);
1821 +#endif
1822 + memset(ptri2s_config->pMMAPRxBufPtr[i], 0, I2S_PAGE_SIZE);
1823 + }
1824 +
1825 + return 0;
1826 +}
1827 +
1828 +int i2s_txPagebuf_alloc(i2s_config_type* ptri2s_config)
1829 +{
1830 +#if defined(ARM_ARCH)
1831 + ptri2s_config->pPage0TxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE , &i2s_txdma_addr0);
1832 + ptri2s_config->pPage1TxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE , &i2s_txdma_addr1);
1833 + if(ptri2s_config->pPage0TxBuf8ptr==NULL)
1834 + {
1835 + MSG("Allocate Tx Page0 Buffer Failed\n");
1836 + return -1;
1837 + }
1838 + if(ptri2s_config->pPage1TxBuf8ptr==NULL)
1839 + {
1840 + MSG("Allocate Tx Page1 Buffer Failed\n");
1841 + return -1;
1842 + }
1843 +#else
1844 + ptri2s_config->pPage0TxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE*2 , &i2s_txdma_addr);
1845 + if(ptri2s_config->pPage0TxBuf8ptr==NULL)
1846 + {
1847 + MSG("Allocate Tx Page Buffer Failed\n");
1848 + return -1;
1849 + }
1850 + ptri2s_config->pPage1TxBuf8ptr = ptri2s_config->pPage0TxBuf8ptr + I2S_PAGE_SIZE;
1851 +#endif
1852 + return 0;
1853 +}
1854 +
1855 +int i2s_rxPagebuf_alloc(i2s_config_type* ptri2s_config)
1856 +{
1857 +#if defined(ARM_ARCH)
1858 + ptri2s_config->pPage0RxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE, &i2s_rxdma_addr0);
1859 + ptri2s_config->pPage1RxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE, &i2s_rxdma_addr1);
1860 + if(ptri2s_config->pPage0RxBuf8ptr==NULL)
1861 + {
1862 + MSG("Allocate Rx Page Buffer Failed\n");
1863 + return -1;
1864 + }
1865 + if(ptri2s_config->pPage1RxBuf8ptr==NULL)
1866 + {
1867 + MSG("Allocate Rx Page Buffer Failed\n");
1868 + return -1;
1869 + }
1870 +#else
1871 + ptri2s_config->pPage0RxBuf8ptr = (u8*)pci_alloc_consistent(NULL, I2S_PAGE_SIZE*2 , &i2s_rxdma_addr);
1872 + if(ptri2s_config->pPage0RxBuf8ptr==NULL)
1873 + {
1874 + MSG("Allocate Rx Page Buffer Failed\n");
1875 + return -1;
1876 + }
1877 + ptri2s_config->pPage1RxBuf8ptr = ptri2s_config->pPage0RxBuf8ptr + I2S_PAGE_SIZE;
1878 +#endif
1879 + return 0;
1880 +}
1881 +
1882 +int i2s_txbuf_free(i2s_config_type* ptri2s_config)
1883 +{
1884 + int i;
1885 +
1886 + for(i = 0 ; i < MAX_I2S_PAGE ; i ++)
1887 + {
1888 + if(ptri2s_config->pMMAPTxBufPtr[i] != NULL)
1889 + {
1890 +#if defined(CONFIG_I2S_MMAP)
1891 + ptri2s_config->pMMAPTxBufPtr[i] = NULL;
1892 +#else
1893 + kfree(ptri2s_config->pMMAPTxBufPtr[i]);
1894 + ptri2s_config->pMMAPTxBufPtr[i] = NULL;
1895 +#endif
1896 + }
1897 + }
1898 + return 0;
1899 +}
1900 +
1901 +int i2s_rxbuf_free(i2s_config_type* ptri2s_config)
1902 +{
1903 + int i;
1904 +
1905 + for(i = 0 ; i < MAX_I2S_PAGE ; i ++)
1906 + {
1907 + if(ptri2s_config->pMMAPRxBufPtr[i] != NULL)
1908 + {
1909 +#if defined(CONFIG_I2S_MMAP)
1910 + ptri2s_config->pMMAPRxBufPtr[i] = NULL;
1911 +#else
1912 + kfree(ptri2s_config->pMMAPRxBufPtr[i]);
1913 + ptri2s_config->pMMAPRxBufPtr[i] = NULL;
1914 +#endif
1915 + }
1916 + }
1917 +
1918 + return 0;
1919 +}
1920 +
1921 +int i2s_txPagebuf_free(i2s_config_type* ptri2s_config)
1922 +{
1923 +#if defined(ARM_ARCH)
1924 + if (ptri2s_config->pPage0TxBuf8ptr)
1925 + {
1926 + pci_free_consistent(NULL, I2S_PAGE_SIZE, ptri2s_config->pPage0TxBuf8ptr, i2s_txdma_addr0);
1927 + ptri2s_config->pPage0TxBuf8ptr = NULL;
1928 + }
1929 +
1930 + if (ptri2s_config->pPage1TxBuf8ptr)
1931 + {
1932 + pci_free_consistent(NULL, I2S_PAGE_SIZE, ptri2s_config->pPage1TxBuf8ptr, i2s_txdma_addr1);
1933 + ptri2s_config->pPage1TxBuf8ptr = NULL;
1934 + }
1935 + _printk("Free tx page buffer\n");
1936 +#else
1937 + if (ptri2s_config->pPage0TxBuf8ptr)
1938 + {
1939 + pci_free_consistent(NULL, I2S_PAGE_SIZE*2, ptri2s_config->pPage0TxBuf8ptr, i2s_txdma_addr);
1940 + ptri2s_config->pPage0TxBuf8ptr = NULL;
1941 + }
1942 +#endif
1943 + return 0;
1944 +
1945 +}
1946 +
1947 +int i2s_rxPagebuf_free(i2s_config_type* ptri2s_config)
1948 +{
1949 +#if defined(ARM_ARCH)
1950 + if (ptri2s_config->pPage0RxBuf8ptr)
1951 + {
1952 + pci_free_consistent(NULL, I2S_PAGE_SIZE, ptri2s_config->pPage0RxBuf8ptr, i2s_rxdma_addr0);
1953 + ptri2s_config->pPage0RxBuf8ptr = NULL;
1954 + }
1955 + if (ptri2s_config->pPage1RxBuf8ptr)
1956 + {
1957 + pci_free_consistent(NULL, I2S_PAGE_SIZE, ptri2s_config->pPage1RxBuf8ptr, i2s_rxdma_addr1);
1958 + ptri2s_config->pPage1RxBuf8ptr = NULL;
1959 + }
1960 + _printk("Free rx page buffer\n");
1961 +#else
1962 + if (ptri2s_config->pPage0RxBuf8ptr)
1963 + {
1964 + pci_free_consistent(NULL, I2S_PAGE_SIZE*2, ptri2s_config->pPage0RxBuf8ptr, i2s_rxdma_addr);
1965 + ptri2s_config->pPage0RxBuf8ptr = NULL;
1966 + }
1967 +#endif
1968 + return 0;
1969 +}
1970 +
1971 +int i2s_reset_tx_param(i2s_config_type* ptri2s_config)
1972 +{
1973 + ptri2s_config->tx_isr_cnt = 0;
1974 + ptri2s_config->tx_w_idx = 0;
1975 + ptri2s_config->tx_r_idx = 0;
1976 + ptri2s_config->enLable = 0;
1977 + ptri2s_config->tx_pause_en = 0;
1978 + ptri2s_config->end_cnt = 0;
1979 + ptri2s_config->tx_stop_cnt = 0;
1980 +
1981 +#ifdef I2S_STATISTIC
1982 + pi2s_status->txbuffer_unrun = 0;
1983 + pi2s_status->txbuffer_ovrun = 0;
1984 + pi2s_status->txdmafault = 0;
1985 + pi2s_status->txovrun = 0;
1986 + pi2s_status->txunrun = 0;
1987 + pi2s_status->txthres = 0;
1988 + pi2s_status->txbuffer_len = 0;
1989 +#endif
1990 +
1991 + return 0;
1992 +}
1993 +
1994 +int i2s_reset_rx_param(i2s_config_type* ptri2s_config)
1995 +{
1996 + ptri2s_config->rx_isr_cnt = 0;
1997 + ptri2s_config->rx_w_idx = 0;
1998 + ptri2s_config->rx_r_idx = 0;
1999 + ptri2s_config->enLable = 0;
2000 + ptri2s_config->rx_pause_en = 0;
2001 + ptri2s_config->rx_stop_cnt = 0;
2002 +
2003 +#ifdef I2S_STATISTIC
2004 + pi2s_status->rxbuffer_unrun = 0;
2005 + pi2s_status->rxbuffer_ovrun = 0;
2006 + pi2s_status->rxdmafault = 0;
2007 + pi2s_status->rxovrun = 0;
2008 + pi2s_status->rxunrun = 0;
2009 + pi2s_status->rxthres = 0;
2010 + pi2s_status->rxbuffer_len = 0;
2011 +#endif
2012 +
2013 + return 0;
2014 +}
2015 +#ifdef MT7621_ASIC_BOARD
2016 +int i2s_pll_config_mt7621(unsigned long index)
2017 +{
2018 + unsigned long data;
2019 + unsigned long regValue;
2020 + bool xtal_20M_en = 0;
2021 +// bool xtal_25M_en = 0;
2022 + bool xtal_40M_en = 0;
2023 +
2024 + regValue = i2s_inw(RALINK_SYSCTL_BASE + 0x10);
2025 + regValue = (regValue >> 6) & 0x7;
2026 + if (regValue < 3)
2027 + {
2028 + xtal_20M_en = 1;
2029 + MSG("Xtal is 20MHz. \n");
2030 + }
2031 + else if (regValue < 6)
2032 + {
2033 + xtal_40M_en = 1;
2034 + MSG("Xtal is 40M.\n");
2035 + }
2036 + else
2037 + {
2038 + //xtal_25M_en = 1;
2039 + MSG("Xtal is 25M.\n");
2040 + }
2041 +
2042 +#if defined (CONFIG_I2S_MCLK_12P288MHZ)
2043 + _printk("MT7621 provide 12.288M/11.298MHz REFCLK\n");
2044 + /* Firstly, reset all required register to default value */
2045 + i2s_outw(RALINK_ANA_CTRL_BASE, 0x00008000);
2046 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, 0x01001d61);//0x01401d61);
2047 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, 0x38233d0e);
2048 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, 0x80100004);//0x80120004);
2049 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x1c7dbf48);
2050 +
2051 + /* toggle RG_XPTL_CHG */
2052 + i2s_outw(RALINK_ANA_CTRL_BASE, 0x00008800);
2053 + i2s_outw(RALINK_ANA_CTRL_BASE, 0x00008c00);
2054 +
2055 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
2056 + data &= ~(0x0000ffc0);
2057 + if ((xtal_40M_en) || (xtal_20M_en))
2058 + {
2059 + data |= REGBIT(0x1d, 8); /* for 40M or 20M */
2060 + }
2061 + else
2062 + {
2063 + data |= REGBIT(0x17, 8); /* for 25M */
2064 + }
2065 +
2066 + if (xtal_40M_en)
2067 + {
2068 + data |= REGBIT(0x1, 6); /* for 40M */
2069 + }
2070 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
2071 +
2072 +
2073 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0018);
2074 + data &= ~(0xf0773f00);
2075 + data |= REGBIT(0x3, 28);
2076 + data |= REGBIT(0x2, 20);
2077 + if ((xtal_40M_en) || (xtal_20M_en))
2078 + {
2079 + data |= REGBIT(0x3, 16); /* for 40M or 20M */
2080 + }
2081 + else
2082 + {
2083 + data |= REGBIT(0x2, 16); /* for 25M */
2084 + }
2085 + data |= REGBIT(0x3, 12);
2086 + if ((xtal_40M_en) || (xtal_20M_en))
2087 + {
2088 + data |= REGBIT(0xd, 8); /* for 40M or 20M */
2089 + }
2090 + else
2091 + {
2092 + data |= REGBIT(0x7, 8); /* for 25M */
2093 + }
2094 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, data);
2095 +
2096 + if((index==1)|(index==4)|(index==7)|(index==9))// 270 MHz for 22.05K, 44.1K, 88.2K, 176.4K
2097 + {
2098 + if ((xtal_40M_en) || (xtal_20M_en))
2099 + {
2100 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x1a18548a); /* for 40M or 20M */
2101 + }
2102 + else
2103 + {
2104 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x14ad106e); /* for 25M */
2105 + }
2106 + }
2107 + else if ((index==0)|(index==3)|(index==5)|(index==6)|(index==8)|(index==10))// 294 MHZ for 24K, 48K, 96K, 192K
2108 + {
2109 + if ((xtal_40M_en) || (xtal_20M_en))
2110 + {
2111 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x1c7dbf48); /* for 40M or 20M */
2112 + }
2113 + else
2114 + {
2115 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0020, 0x1697cc39); /* for 25M */
2116 + }
2117 + }
2118 + else if (index==2)
2119 + {
2120 + _printk("Not support 12KHz sampling rate!\n");
2121 + return -1;
2122 + }
2123 + else
2124 + {
2125 + _printk("Wrong sampling rate!\n");
2126 + return -1;
2127 + }
2128 +
2129 + //*Common setting - Set PLLGP_CTRL_4 *//
2130 + /* 1. Bit 31 */
2131 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2132 + data &= ~(REGBIT(0x1, 31));
2133 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2134 + ndelay(10);
2135 +
2136 + /* 2. Bit 0 */
2137 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2138 + data |= REGBIT(0x1, 0);
2139 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2140 + udelay(200);
2141 +
2142 + /* 3. Bit 3 */
2143 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2144 + data |= REGBIT(0x1, 3);
2145 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2146 + udelay(1);
2147 +
2148 + /* 4. Bit 8 */
2149 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2150 + data |= REGBIT(0x1, 8);
2151 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2152 + ndelay(40);
2153 +
2154 + /* 5. Bit 6 */
2155 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2156 + data |= REGBIT(0x1, 6);
2157 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2158 + ndelay(40);
2159 +
2160 + /* 6. Bit 5 & Bit 7*/
2161 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2162 + data |= REGBIT(0x1, 5);
2163 + data |= REGBIT(0x1, 7);
2164 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2165 + udelay(1);
2166 +
2167 + /* 7. Bit 17 */
2168 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2169 + data |= REGBIT(0x1, 17);
2170 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2171 +
2172 +#elif defined(CONFIG_I2S_MCLK_12MHZ)
2173 + _printk("MT7621 provide 12MHz REFCLK\n");
2174 + /* Firstly, reset all required register to default value */
2175 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, 0x01401d61);//0x01401d61);
2176 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, 0x80120004);//0x80100004);
2177 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, 0x38233d0e);
2178 +
2179 + if (xtal_40M_en)
2180 + {
2181 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2182 + data &= ~REGBIT(0x1, 17);
2183 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2184 +
2185 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
2186 + data &= ~REGBIT(0x3, 4);
2187 + data |= REGBIT(0x1, 4);
2188 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
2189 +
2190 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2191 + data &= ~REGBIT(0x1, 31);
2192 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2193 + }
2194 + else if (xtal_20M_en)
2195 + {
2196 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2197 + data &= ~REGBIT(0x1, 17);
2198 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2199 +
2200 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
2201 + data &= ~REGBIT(0x3, 6);
2202 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
2203 +
2204 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
2205 + data &= ~REGBIT(0x3, 4);
2206 + data |= REGBIT(0x1, 4);
2207 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
2208 +
2209 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2210 + data &= ~REGBIT(0x1, 31);
2211 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2212 + }
2213 + else
2214 + {
2215 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2216 + data &= ~REGBIT(0x1, 17);
2217 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2218 +
2219 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
2220 + data &= ~REGBIT(0x7f, 8);
2221 + data |= REGBIT(0x17, 8);
2222 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
2223 +
2224 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
2225 + data &= ~REGBIT(0x3, 6);
2226 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
2227 +
2228 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0018);
2229 + data &= ~REGBIT(0x7, 16);
2230 + data |= REGBIT(0x2, 16);
2231 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, data);
2232 +
2233 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0018);
2234 + data &= ~REGBIT(0xf, 8);
2235 + data |= REGBIT(0x7, 8);
2236 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0018, data);
2237 +
2238 +
2239 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x0014);
2240 + data &= ~REGBIT(0x3, 4);
2241 + data |= REGBIT(0x1, 4);
2242 + i2s_outw(RALINK_ANA_CTRL_BASE+0x0014, data);
2243 +
2244 + data = i2s_inw(RALINK_ANA_CTRL_BASE+0x001c);
2245 + data &= ~REGBIT(0x1, 31);
2246 + i2s_outw(RALINK_ANA_CTRL_BASE+0x001c, data);
2247 +
2248 + }
2249 +#endif
2250 + return 0;
2251 +}
2252 +#if defined(CONFIG_I2S_IN_MCLK)
2253 +int i2s_pll_refclk_set(void)
2254 +{
2255 + unsigned long data;
2256 +
2257 + /* Set APLL register for REFCLK */
2258 + data = i2s_inw(RALINK_SYSCTL_BASE+0x90);
2259 + data &= ~(0x0000f000);
2260 + data |= REGBIT(0x1, 12);
2261 + i2s_outw(RALINK_SYSCTL_BASE+0x0090, data);
2262 +
2263 + data = i2s_inw(RALINK_SYSCTL_BASE+0x0090);
2264 + data &= ~(0x00000300);
2265 + i2s_outw(RALINK_SYSCTL_BASE+0x0090, data);
2266 + MSG("Set 0x90 register\n");
2267 +
2268 + return 0;
2269 +}
2270 +#endif
2271 +#endif
2272 +
2273 +#ifdef MT7623_ASIC_BOARD
2274 +int i2s_pll_config_mt7623(unsigned long index)
2275 +{
2276 + unsigned long data;
2277 +
2278 + /* xPLL PWR ON */
2279 + data = i2s_inw(AUD2PLL_PWR_CON0);
2280 + data |= 0x1;
2281 + i2s_outw(AUD2PLL_PWR_CON0, data);
2282 + udelay(5);
2283 +
2284 + /* xPLL ISO Disable */
2285 + data = i2s_inw(AUD2PLL_PWR_CON0);
2286 + data &= ~(0x2);
2287 + i2s_outw(AUD2PLL_PWR_CON0, data);
2288 +
2289 + /* xPLL Frequency Set */
2290 + data = i2s_inw(AUD2PLL_CON0);
2291 + data |= 0x1;
2292 + i2s_outw(AUD2PLL_CON0, data);
2293 +
2294 + /* AUD1PLL Frequency Set(change from 98.304MHz to 294.912MHz) */
2295 + i2s_outw(AUD1PLL_CON0, 0x121);
2296 + i2s_outw(AUD1PLL_CON1, 0xad5efee6);
2297 + udelay(40);
2298 +
2299 + /* Audio clock setting */
2300 + if((index==1)|(index==4)|(index==7)|(index==9)|(index==11))// for 22.05K, 44.1K, 88.2K, 176.4K
2301 + {
2302 + _printk("\n*****%s:index=%d(270MHz)*****\n", __func__, (int)index);
2303 + data = i2s_inw(0xFB00002c);
2304 + //data &= ~REGBIT(0x8, 1);
2305 + data &= ~(0x80);
2306 + i2s_outw(0xFB00002C, data); /* AUD1PLL 270.9204MHz */
2307 + }
2308 + else if ((index==0)|(index==3)|(index==5)|(index==6)|(index==8)|(index==10)|(index==12)) //for 24K, 48K, 96K, 192K
2309 + {
2310 + _printk("\n*****%s:index=%d(294MHz)*****\n", __func__, (int)index);
2311 + data = i2s_inw(0xFB00002c);
2312 + //data |= REGBIT(0x8, 1);
2313 + data |= (0x80);
2314 + i2s_outw(0xFB00002c, data); /* AUD1PLL 294.912MHz */
2315 + }
2316 + else if (index==2)
2317 + {
2318 + _printk("Not support 12KHz sampling rate!\n");
2319 + return -1;
2320 + }
2321 + else
2322 + {
2323 + _printk("Wrong sampling rate!\n");
2324 + return -1;
2325 + }
2326 + return 0;
2327 +}
2328 +#endif
2329 +
2330 +#if defined(MT7628_ASIC_BOARD) || defined(CONFIG_ARCH_MT7623)
2331 +int i2s_driving_strength_adjust(void)
2332 +{
2333 +#if defined(MT7628_ASIC_BOARD)
2334 + unsigned long data;
2335 +
2336 + MSG("Adjust MT7628 current's driving strngth\n");
2337 + /* Adjust REFCLK0's driving strength of current which can avoid
2338 + * the glitch of REFCKL0
2339 + * E4 = 0xb0001354[5]; E8 = 0xb0001364[5]
2340 + * (E4,E8)=(0,0)-> 4 mA;
2341 + * =(1,0)-> 8 mA;
2342 + * =(0,1)-> 12 mA;
2343 + * =(1,1)-> 16 mA*/
2344 +
2345 + /* Set to 12mA */
2346 + data = i2s_inw(0xb0001354);
2347 + data &= ~(0x1<<5);
2348 + i2s_outw(0xb0001354, data);
2349 +
2350 + data = i2s_inw(0xb0001364);
2351 + data |= (0x1<<5);
2352 + i2s_outw(0xb0001364, data);
2353 +#endif
2354 +#if defined(CONFIG_ARCH_MT7623)
2355 + MSG("Adjust MT7623 current's driving strngth\n");
2356 +
2357 + i2s_outw(0xF0005F80, 0x7777);
2358 +#endif
2359 +
2360 + return 0;
2361 +}
2362 +#endif
2363 +
2364 +#if defined(CONFIG_I2S_IN_MCLK)
2365 +#if defined(CONFIG_I2S_MCLK_12MHZ)
2366 +int i2s_refclk_12m_enable(void)
2367 +{
2368 + unsigned long data;
2369 +
2370 + MSG("Enable SoC MCLK 12Mhz\n");
2371 +
2372 +#if defined(CONFIG_RALINK_RT6855A)
2373 + data = i2s_inw(RALINK_SYSCTL_BASE+0x860);
2374 + data |= (0x1<<17);
2375 + data &= ~(0x7<<18);
2376 + data |= (0x1<<18);
2377 + i2s_outw(RALINK_SYSCTL_BASE+0x860, data);
2378 +#elif defined(CONFIG_RALINK_RT3350)
2379 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2380 + data |= (0x1<<8);
2381 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2382 +#elif defined(CONFIG_RALINK_RT3883)
2383 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2384 + data &= ~(0x03<<13);
2385 + data |= (0x1<<13);
2386 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2387 +#elif defined(CONFIG_RALINK_RT3352)||defined(CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855)
2388 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2389 + data &= ~(0x0F<<8);
2390 + data |= (0x3<<8);
2391 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2392 +#elif defined(CONFIG_RALINK_MT7620)
2393 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2394 + data &= ~(0x07<<9);
2395 + data |= (1<<9);
2396 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2397 +#elif defined(CONFIG_RALINK_MT7621)
2398 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2399 + data &= ~(0x1f<<18);
2400 + data |= REGBIT(0x19, 18);
2401 + data &= ~(0x1f<<12);
2402 + data |= REGBIT(0x1, 12);
2403 + data &= ~(0x7<<9);
2404 + data |= REGBIT(0x5, 9);
2405 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2406 +#elif defined(CONFIG_RALINK_MT7628)
2407 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2408 + MSG("turn on REFCLK output for MCLK1\n");
2409 + data &= ~(0x7<<9);
2410 + data |= (0x1<<9); /* output for MCLK */
2411 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2412 +#else
2413 + #error "This SoC does not provide 12MHz clock to audio codec\n");
2414 +#endif
2415 + i2s_refclk_gpio_out_config();
2416 +
2417 + return 0;
2418 +}
2419 +#endif
2420 +
2421 +#if defined(CONFIG_I2S_MCLK_12P288MHZ)
2422 +int i2s_refclk_12p288m_enable(void)
2423 +{
2424 + unsigned long data;
2425 + MSG("Enable SoC MCLK 12.288Mhz\n");
2426 +
2427 +#if defined(CONFIG_RALINK_RT3352)||defined(CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855)
2428 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2429 + data &= ~(0x01F<<18);
2430 + data |= 31<<18;
2431 + data &= ~(0x01F<<12);
2432 + data |= 1<<12;
2433 + data |= (0xF<<8);
2434 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2435 +#elif defined(CONFIG_RALINK_MT7621)
2436 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2437 + data &= ~(0x1f<<18);
2438 + data |= REGBIT(0xc, 18);
2439 + data &= ~(0x1f<<12);
2440 + data |= REGBIT(0x1, 12);
2441 + data &= ~(0x7<<9);
2442 + data |= REGBIT(0x5, 9);
2443 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2444 + _printk("MT7621 provide REFCLK 12.288MHz/11.289MHz\n");
2445 +#elif defined(CONFIG_ARCH_MT7623)
2446 + /* MT7623 does not need to set divider for REFCLK */
2447 + /* GPIO126 - I2S0_MCLK */
2448 + data = i2s_inw(0xF00058F0);
2449 + data &= ~(0x7<<3);
2450 + data |= (0x6<<3);
2451 + i2s_outw(0xF00058F0, data);
2452 + /* GPIO_DIR8: OUT */
2453 + data = i2s_inw(0xF0005070);
2454 + data |= (0x1<<14);
2455 + i2s_outw(0xF0005070, data);
2456 +#else
2457 + #error "This SoC does not provide 12.288Mhz clock to audio codec\n");
2458 +#endif
2459 +
2460 + return 0;
2461 +}
2462 +#endif
2463 +
2464 +#if defined(CONFIG_I2S_MCLK_18P432MHZ)
2465 +int i2s_refclk_18p432m_enable(unsigned long index)
2466 +{
2467 + unsigned long data;
2468 + MSG("Enable SoC MCLK 18.432MHz/16.934MHz");
2469 +
2470 + if((index==1)|(index==4)|(index==7)|(index==9))// 16.934MHz for 22.05K, 44.1K, 88.2K, 176.4K
2471 + {
2472 + data = i2s_inw(ETHDMASYS_SYSCTL_BASE+0x2c);
2473 + data &= ~(0x1<<7);
2474 + i2s_outw(ETHDMASYS_SYSCTL_BASE+0x2c, data);
2475 + }
2476 + else if((index==0)|(index==3)|(index==5)|(index==6)|(index==8)|(index==10))// 18.432MHZ for 24K, 48K, 96K, 192K
2477 + {
2478 + data = i2s_inw(ETHDMASYS_SYSCTL_BASE+0x2c);
2479 + data |= (0x1<<7);
2480 + i2s_outw(ETHDMASYS_SYSCTL_BASE+0x2c, data);
2481 + }
2482 +
2483 + data = i2s_inw(ETHDMASYS_SYSCTL_BASE+0x30);
2484 + data |= (0x1<<17);
2485 + i2s_outw(ETHDMASYS_SYSCTL_BASE+0x30, data);
2486 +
2487 + return 0;
2488 +}
2489 +#endif
2490 +#endif
2491 +
2492 +int i2s_refclk_disable(void)
2493 +{
2494 + unsigned long data;
2495 +
2496 +#if defined(CONFIG_RALINK_RT6855A)
2497 + data = i2s_inw(RALINK_SYSCTL_BASE+0x860);
2498 + data &= ~(1<<17);
2499 + i2s_outw(RALINK_SYSCTL_BASE+0x860, data);
2500 +#elif defined(CONFIG_RALINK_RT3350)
2501 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2502 + data &= ~(0x1<<8);
2503 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2504 +#elif defined(CONFIG_RALINK_RT3883)
2505 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2506 + data &= ~(0x0F<<13);
2507 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2508 +#elif defined(CONFIG_RALINK_RT3352)||defined(CONFIG_RALINK_RT5350)||defined (CONFIG_RALINK_RT6855)
2509 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2510 + data &= ~(0x0F<<8);
2511 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2512 +#elif defined (CONFIG_RALINK_MT7620)||defined (CONFIG_RALINK_MT7621)||defined (CONFIG_RALINK_MT7628)
2513 + _printk("turn off REFCLK output from internal CLK\n");
2514 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
2515 + data &= ~(0x07<<9);
2516 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
2517 +#elif defined (CONFIG_ARCH_MT7623) /*FIXME:2*/
2518 +#ifdef MT7623_ASIC_BOARD
2519 + _printk("turn off REFCLK output from internal CLK\n");
2520 + /* GPIO126 - I2S0_MCLK */
2521 + data = i2s_inw(0xF00058F0);
2522 + data &= ~(0x7<<3);
2523 + //data |= (0x2<<3);
2524 + i2s_outw(0xF00058F0, data);
2525 + /* GPIO126 => GPIO_DIR8: IN */
2526 + data = i2s_inw(0xF0005070);
2527 + data &= ~(0x1<<14);
2528 + i2s_outw(0xF0005070, data);
2529 +#else
2530 + _printk("turn off REFCLK output from internal CLK\n");
2531 + data = i2s_inw(ETHDMASYS_SYSCTL_BASE+0x30);
2532 + data &= ~(0x1<<17);
2533 + i2s_outw(ETHDMASYS_SYSCTL_BASE+0x30, data);
2534 +#endif
2535 +#endif
2536 + return 0;
2537 +}
2538 +
2539 +int i2s_refclk_gpio_out_config(void)
2540 +{
2541 +#ifndef CONFIG_ARCH_MT7623
2542 + unsigned long data; /* FIXME */
2543 +#endif
2544 +
2545 + /* Set REFCLK GPIO pin as REFCLK mode*/
2546 +#if defined(CONFIG_RALINK_MT7620)
2547 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2548 + data &= ~(0x03<<21); /* WDT */
2549 + data |= (1<<21);
2550 + //data &= ~(0x03<<16); /* PERST */
2551 + //data |= (1<<16);
2552 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2553 +#endif
2554 +#if defined(CONFIG_RALINK_MT7621)
2555 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2556 + //data &= ~(0x3<<10); /* PERST */
2557 + //data |= (0x2<<10);
2558 + data &= ~(0x3<<8); /* WDT */
2559 + data |= (0x2<<8);
2560 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2561 + MSG("Set 0x60 register\n");
2562 +#endif
2563 +#if defined(CONFIG_RALINK_MT7628)
2564 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2565 + data &= ~(0x1<<18);
2566 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2567 +#endif
2568 +
2569 + return 0;
2570 +}
2571 +
2572 +int i2s_refclk_gpio_in_config(void)
2573 +{
2574 +#ifndef CONFIG_ARCH_MT7623
2575 + unsigned long data; /* FIXME */
2576 +#endif
2577 +
2578 +#if defined (CONFIG_RALINK_MT7620)
2579 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2580 + data &= ~(0x03<<21); /* WDT */
2581 + data |= (1<<21);
2582 + //data &= ~(0x03<<16); /* PERST */
2583 + //data |= (1<<16);
2584 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2585 +
2586 + data = i2s_inw(RALINK_PIO_BASE);
2587 + data &= ~(0x1<<17); /* GPIO share ping 17 for WDT */
2588 + i2s_outw(RALINK_PIO_BASE, data);
2589 +
2590 + //data = i2s_inw(RALINK_PIO_BASE+0x04);
2591 + //data &= ~(0x1<<4); /* GPIO share ping 36 for PERST */
2592 + //i2s_outw(RALINK_PIO_BASE+0x04, data);
2593 +#endif
2594 +#if defined (CONFIG_RALINK_MT7621)
2595 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2596 + //data &= ~(0x3<<10); /* PERST */
2597 + //data |= (0x1<<10);
2598 + data &= ~(0x3<<8); /* WDT */
2599 + data |= (0x1<<8);
2600 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2601 +
2602 + data = i2s_inw(RALINK_PIO_BASE);
2603 + //data &= ~(0x1<<19); /* GPIO share ping 19 for RERST */
2604 + data &= ~(0x1<<18); /* GPIO share ping 18 for WDT */
2605 + i2s_outw(RALINK_PIO_BASE, data);
2606 +#endif
2607 +#if defined (CONFIG_RALINK_MT7628)
2608 + /* To use external OSC, set REFCLK_GPIO ping as GPIO mode and set it as input direction */
2609 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2610 + data |= (0x1<<18);
2611 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2612 +
2613 + data = i2s_inw(RALINK_PIO_BASE+0x04);
2614 + data &= ~(0x1<<5); /* GPIO share ping 37*/
2615 + i2s_outw(RALINK_PIO_BASE+0x04, data);
2616 +#endif
2617 +
2618 + return 0;
2619 +}
2620 +
2621 +int i2s_slave_clock_gpio_in_mt7623(void)
2622 +{
2623 + unsigned long data;
2624 +
2625 + /* GPIO74(I2S0_BCLK)=>GPIO_DIR5: IN */
2626 + data = i2s_inw(0xF0005040);
2627 + data &= ~(0x1<<10);
2628 + i2s_outw(0xF0005040, data);
2629 +
2630 + /* GPIO73(I2S0_LRCK)=>GPIO_DIR5: IN */
2631 + data = i2s_inw(0xF0005040);
2632 + data &= ~(0x1<<9);
2633 + i2s_outw(0xF0005040, data);
2634 +
2635 + _printk("i2s_slave_clock_gpio_in_mt7623\n");
2636 +
2637 + return 0;
2638 +}
2639 +
2640 +int i2s_master_clock_gpio_out_mt7623(void)
2641 +{
2642 + unsigned long data;
2643 +
2644 + /* GPIO74(I2S0_BCLK)=>GPIO_DIR5: OUT */
2645 + data = i2s_inw(0xF0005040);
2646 + data |= (0x1<<10);
2647 + i2s_outw(0xF0005040, data);
2648 +
2649 + /* GPIO73(I2S0_LRCK)=>GPIO_DIR5: OUT */
2650 + data = i2s_inw(0xF0005040);
2651 + data |= (0x1<<9);
2652 + i2s_outw(0xF0005040, data);
2653 +
2654 + _printk("i2s_master_clock_gpio_out_mt7623\n");
2655 +
2656 + return 0;
2657 +}
2658 +
2659 +int i2s_share_pin_mt7623(i2s_config_type* ptri2s_config)
2660 +{
2661 + unsigned long data;
2662 +
2663 + _printk("\nConfig MT7623 I2S pinmux\n");
2664 + /* GPIO74 - I2S0_BCLK */
2665 + data = i2s_inw(0xF0005840);
2666 + data &= ~(0x7<<12);
2667 + data |= (0x6<<12);
2668 + i2s_outw(0xF0005840, data);
2669 +
2670 + /* GPIO73 - I2S0_LRCK */
2671 + data = i2s_inw(0xF0005840);
2672 + data &= ~(0x7<<9);
2673 + data |= (0x6<<9);
2674 + i2s_outw(0xF0005840, data);
2675 +
2676 + if(ptri2s_config->slave_en==0)
2677 + i2s_master_clock_gpio_out_mt7623();
2678 + else
2679 + i2s_slave_clock_gpio_in_mt7623();
2680 +
2681 + /* GPIO49 - I2S0_DATA */
2682 + data = i2s_inw(0xF00057F0);
2683 + data &= ~(0x7<<12);
2684 + data |= (0x6<<12);
2685 + i2s_outw(0xF00057F0, data);
2686 + /* GPIO_DIR4: OUT */
2687 + data = i2s_inw(0xF0005030);
2688 + data |= (0x1<<1);
2689 + i2s_outw(0xF0005030, data);
2690 +
2691 + /* GPIO72 - I2S0_DATA_IN */
2692 + data = i2s_inw(0xF0005840);
2693 + data &= ~(0x7<<6);
2694 + data |= (0x6<<6);
2695 + i2s_outw(0xF0005840, data);
2696 + /* GPIO_DIR5: IN */
2697 + data = i2s_inw(0xF0005040);
2698 + data &= ~(0x1<<8);
2699 + i2s_outw(0xF0005040, data);
2700 +
2701 + return 0;
2702 +}
2703 +
2704 +int i2s_share_pin_config(i2s_config_type* ptri2s_config)
2705 +{
2706 +#ifndef CONFIG_ARCH_MT7623
2707 + unsigned long data; /*FIXME*/
2708 +#endif
2709 +
2710 + /* set share pins to i2s/gpio mode and i2c mode */
2711 +#if defined(CONFIG_RALINK_RT6855A)
2712 + data = i2s_inw(RALINK_SYSCTL_BASE+0x860);
2713 + data |= 0x00008080;
2714 + i2s_outw(RALINK_SYSCTL_BASE+0x860, data);
2715 +#elif defined(CONFIG_RALINK_MT7621)
2716 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2717 + data &= 0xFFFFFFE3;
2718 + data |= 0x00000010;
2719 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2720 +#elif defined(CONFIG_RALINK_MT7628)
2721 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2722 + data &= ~(0x3<<6); /* I2S_MODE */
2723 + data &= ~(0x3<<20); /* I2C_MODE */
2724 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2725 +#elif defined(CONFIG_ARCH_MT7623)
2726 + i2s_share_pin_mt7623(ptri2s_config);
2727 +#else
2728 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
2729 + data &= 0xFFFFFFE2;
2730 + data |= 0x00000018;
2731 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
2732 +#endif
2733 + return 0;
2734 +}
2735 +
2736 +int i2s_ws_config(i2s_config_type* ptri2s_config, unsigned long index)
2737 +{
2738 + unsigned long data;
2739 + unsigned long* pTable;
2740 +
2741 +#if defined(CONFIG_I2S_IN_CLK)
2742 + /* REFCLK is 15.625Mhz or 40Mhz(fractional division) */
2743 +#if defined(CONFIG_I2S_FRAC_DIV)
2744 + MSG("Internal REFCLK with fractional division\n");
2745 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
2746 + if (ptri2s_config->wordlen_24b == 1)
2747 + {
2748 + MSG("24 bit int table\n");
2749 + pTable = i2s_inclk_int_24bit;
2750 + }
2751 + else
2752 + {
2753 + MSG("16 bit int table\n");
2754 + pTable = i2s_inclk_int_16bit;
2755 + }
2756 +#else
2757 + pTable = i2s_inclk_int;
2758 +#endif /* CONFIG_RALINK_MT7628 */
2759 +
2760 + data = (unsigned long)(pTable[index]);
2761 + i2s_outw(I2S_DIVINT_CFG, data);
2762 +
2763 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
2764 + if (ptri2s_config->wordlen_24b == 1)
2765 + {
2766 + MSG("24 bit comp table\n");
2767 + pTable = i2s_inclk_comp_24bit;
2768 + }
2769 + else
2770 + {
2771 + MSG("16 bit comp table\n");
2772 + pTable = i2s_inclk_comp_16bit;
2773 + }
2774 +#else
2775 + pTable = i2s_inclk_comp;
2776 +#endif /* CONFIG_RALINK_MT7628 */
2777 +
2778 + data = (unsigned long)(pTable[index]);
2779 + data |= REGBIT(1, I2S_CLKDIV_EN);
2780 + i2s_outw(I2S_DIVCOMP_CFG, data);
2781 +#else
2782 + MSG("Internal REFCLK 15.625Mhz \n");
2783 + pTable = i2s_inclk_15p625Mhz;
2784 + data = i2s_inw(RALINK_SYSCTL_BASE+0x30);
2785 + data &= 0xFFFF00FF;
2786 + data |= (unsigned long)(pTable[index]);
2787 + data |= 0x00008000;
2788 + i2s_outw(RALINK_SYSCTL_BASE+0x30, data);
2789 +#endif /* CONFIG_I2S_FRAC_DIV */
2790 +#else
2791 +#if defined(CONFIG_I2S_MCLK_12MHZ)
2792 + /* REFCLK = MCLK = 12Mhz */
2793 + MSG("External REFCLK 12Mhz \n");
2794 + pTable = i2s_exclk_12Mhz;
2795 + data = i2s_inw(RALINK_SYSCTL_BASE+0x30);
2796 + data &= 0xFFFF00FF;
2797 + data |= (unsigned long)(pTable[index]);
2798 + data |= 0x0000C000;
2799 + i2s_outw(RALINK_SYSCTL_BASE+0x30, data);
2800 +#else
2801 + /* REFCLK = MCLK = 12.288Mhz */
2802 + pTable = i2s_exclk_12p288Mhz;
2803 + MSG("External REFCLK 12.288Mhz \n");
2804 + data = i2s_inw(RALINK_SYSCTL_BASE+0x30);
2805 + data &= 0xFFFF00FF;
2806 + data |= (unsigned long)(pTable[index]);
2807 + data |= 0x0000C000;
2808 + i2s_outw(RALINK_SYSCTL_BASE+0x30, data);
2809 +#endif /* CONFIG_I2S_MCLK_12MHZ */
2810 +#endif /* Not CONFIG_I2S_IN_CLK */
2811 +
2812 +#if defined(CONFIG_I2S_WS_EDGE)
2813 + data = i2s_inw(I2S_I2SCFG);
2814 + data |= REGBIT(0x1, I2S_WS_INV);
2815 + i2s_outw(I2S_I2SCFG, data);
2816 +#endif
2817 +
2818 + return 0;
2819 +}
2820 +
2821 +int i2s_mode_config(u32 slave_en)
2822 +{
2823 + unsigned long data;
2824 +
2825 + if(slave_en==0)
2826 + {
2827 + /* Master mode*/
2828 + _printk("This SoC is in Master mode\n");
2829 +#if defined(CONFIG_RALINK_RT3052)
2830 + data = i2s_inw(I2S_I2SCFG);
2831 + data &= ~REGBIT(0x1, I2S_SLAVE_EN);
2832 + data &= ~REGBIT(0x1, I2S_CLK_OUT_DIS);
2833 + i2s_outw(I2S_I2SCFG, data);
2834 +#elif defined(CONFIG_RALINK_RT3883)||defined(CONFIG_RALINK_RT3352)||\
2835 + defined(CONFIG_RALINK_RT5350)||defined(CONFIG_RALINK_RT6855)||\
2836 + defined(CONFIG_RALINK_MT7620)||defined(CONFIG_RALINK_RT6855A)||\
2837 + defined(CONFIG_RALINK_MT7621)||defined(CONFIG_RALINK_MT7628)||\
2838 + defined(CONFIG_ARCH_MT7623)
2839 + data = i2s_inw(I2S_I2SCFG);
2840 + data &= ~REGBIT(0x1, I2S_SLAVE_MODE);
2841 + i2s_outw(I2S_I2SCFG, data);
2842 +#else
2843 + #error "a strange clock mode"
2844 +#endif
2845 + }
2846 + else
2847 + {
2848 + /* Slave mode */
2849 + _printk("This SoC is in Slave mode\n");
2850 +#if defined(CONFIG_RALINK_RT3052)
2851 + data = i2s_inw(I2S_I2SCFG);
2852 + data |= REGBIT(0x1, I2S_SLAVE_EN);
2853 + data |= REGBIT(0x1, I2S_CLK_OUT_DIS);
2854 + i2s_outw(I2S_I2SCFG, data);
2855 +#elif defined(CONFIG_RALINK_RT3883)||defined(CONFIG_RALINK_RT3352)||\
2856 + defined(CONFIG_RALINK_RT5350)||defined(CONFIG_RALINK_RT6855)||\
2857 + defined(CONFIG_RALINK_MT7620)||defined(CONFIG_RALINK_RT6855A)||\
2858 + defined(CONFIG_RALINK_MT7621)||defined(CONFIG_RALINK_MT7628)||\
2859 + defined(CONFIG_ARCH_MT7623)
2860 + data = i2s_inw(I2S_I2SCFG);
2861 + data |= REGBIT(0x1, I2S_SLAVE_MODE);
2862 + i2s_outw(I2S_I2SCFG, data);
2863 +#else
2864 + #error "a strange clock mode "
2865 +#endif
2866 + }
2867 +
2868 + return 0;
2869 +}
2870 +
2871 +int i2s_codec_frequency_config(i2s_config_type* ptri2s_config, unsigned long index)
2872 +{
2873 +#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
2874 + unsigned long data;
2875 + unsigned long* pTable;
2876 +#endif
2877 +
2878 +#if defined(CONFIG_I2S_MCLK_12MHZ)
2879 +#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
2880 + pTable = i2s_codec_12Mhz;
2881 + data = pTable[index];
2882 +#endif
2883 +#if defined(CONFIG_I2S_WM8960)
2884 + audiohw_set_frequency(data, ptri2s_config->codec_pll_en);
2885 +#elif defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
2886 + audiohw_set_frequency(data|0x01);
2887 +#endif
2888 +#else
2889 +#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
2890 +#if defined(MT7623_FPGA_BOARD) && defined(CONFIG_I2S_WM8750)
2891 + pTable = i2s_codec_18p432Mhz;
2892 +#else
2893 + pTable = i2s_codec_12p288Mhz;
2894 +#endif
2895 + data = pTable[index];
2896 +#endif
2897 +#if defined(CONFIG_I2S_WM8960)
2898 + audiohw_set_frequency(data, ptri2s_config->codec_pll_en);
2899 +#elif defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
2900 + audiohw_set_frequency(data);
2901 +#endif
2902 +#endif
2903 + return 0;
2904 +}
2905 +
2906 +/*
2907 + * Ralink Audio System Clock Enable
2908 + *
2909 + * I2S_WS : signal direction opposite to/same as I2S_CLK
2910 + *
2911 + * I2S_CLK : Integer division or fractional division
2912 + * REFCLK from Internal or External (external REFCLK not support for fractional division)
2913 + * Suppose external REFCLK always be the same as external MCLK
2914 + *
2915 + * MCLK : External OSC or internal generation
2916 + *
2917 + */
2918 +int i2s_clock_enable(i2s_config_type* ptri2s_config)
2919 +{
2920 + unsigned long index;
2921 + /* audio sampling rate decision */
2922 + switch(ptri2s_config->srate)
2923 + {
2924 + case 8000:
2925 + index = 0;
2926 + break;
2927 + case 11025:
2928 + index = 1;
2929 + break;
2930 + case 12000:
2931 + index = 2;
2932 + break;
2933 + case 16000:
2934 + index = 3;
2935 + break;
2936 + case 22050:
2937 + index = 4;
2938 + break;
2939 + case 24000:
2940 + index = 5;
2941 + break;
2942 + case 32000:
2943 + index = 6;
2944 + break;
2945 + case 44100:
2946 + index = 7;
2947 + break;
2948 + case 48000:
2949 + index = 8;
2950 + break;
2951 + case 88200:
2952 + index = 9;
2953 + break;
2954 + case 96000:
2955 + index = 10;
2956 + break;
2957 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
2958 + case 176000:
2959 + index = 11;
2960 + break;
2961 + case 192000:
2962 + index = 12;
2963 + break;
2964 +#endif
2965 + default:
2966 + index = 7;
2967 + }
2968 +#ifdef MT7621_ASIC_BOARD
2969 + /* Set pll config */
2970 + i2s_pll_config_mt7621(index);
2971 +#endif
2972 +#ifdef MT7623_ASIC_BOARD
2973 + /* Set pll config */
2974 + i2s_pll_config_mt7623(index);
2975 +#endif
2976 +
2977 + /* enable internal MCLK */
2978 +#if defined(CONFIG_I2S_IN_MCLK)
2979 +#if defined(CONFIG_RALINK_MT7621)
2980 + i2s_pll_refclk_set();
2981 +#endif
2982 +#if defined(CONFIG_I2S_MCLK_12MHZ)
2983 +#if defined(MT7628_ASIC_BOARD) || defined(CONFIG_ARCH_MT7623)
2984 + i2s_driving_strength_adjust();
2985 +#endif
2986 + i2s_refclk_12m_enable();
2987 +#endif /* MCLK_12MHZ */
2988 +#if defined(CONFIG_I2S_MCLK_12P288MHZ)
2989 + i2s_refclk_12p288m_enable();
2990 +#endif /* MCLK_12P288MHZ */
2991 +#if defined(CONFIG_I2S_MCLK_18P432MHZ)
2992 + i2s_refclk_18p432m_enable(index);
2993 +#endif
2994 + i2s_refclk_gpio_out_config();
2995 +
2996 +#else
2997 + MSG("Disable SoC MCLK, use external OSC\n");
2998 + i2s_refclk_disable();
2999 + i2s_refclk_gpio_in_config();
3000 +#endif /* CONFIG_I2S_IN_MCLK */
3001 +
3002 + i2s_share_pin_config(ptri2s_config);
3003 +
3004 + if(ptri2s_config->slave_en==0)
3005 + {
3006 + /* Setup I2S_WS and I2S_CLK */
3007 + i2s_ws_config(ptri2s_config, index);
3008 + }
3009 +
3010 + i2s_mode_config(ptri2s_config->slave_en);
3011 +
3012 + if(!ptri2s_config->bALSAEnable)
3013 + {
3014 +#if defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)|| defined(CONFIG_I2S_WM8960)
3015 + i2s_codec_enable(ptri2s_config);
3016 +#endif
3017 + i2s_codec_frequency_config(ptri2s_config,index);
3018 + }
3019 +
3020 + return 0;
3021 +}
3022 +
3023 +int i2s_clock_disable(i2s_config_type* ptri2s_config)
3024 +{
3025 + if(!ptri2s_config->bALSAEnable)
3026 + {
3027 +#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
3028 + i2s_codec_disable(ptri2s_config);
3029 +#endif
3030 + }
3031 +
3032 + /* disable internal MCLK */
3033 +#if defined(CONFIG_I2S_IN_MCLK)
3034 + i2s_refclk_disable();
3035 + i2s_refclk_gpio_in_config();
3036 +#endif
3037 + return 0;
3038 +}
3039 +
3040 +
3041 +int i2s_codec_enable(i2s_config_type* ptri2s_config)
3042 +{
3043 +
3044 + int AIn = 0, AOut = 0;
3045 +#if 1
3046 +#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
3047 + /* Codec initialization */
3048 + audiohw_preinit();
3049 +#endif
3050 +#endif
3051 +
3052 +#if defined(CONFIG_I2S_WM8960)
3053 + if(ptri2s_config->codec_pll_en)
3054 + {
3055 + MSG("Codec PLL EN = %d\n", pi2s_config->codec_pll_en);
3056 + audiohw_set_apll(ptri2s_config->srate);
3057 + }
3058 +#endif
3059 +
3060 +#if defined(CONFIG_I2S_TXRX)
3061 + if((ptri2s_config->bTxDMAEnable) || (ptri2s_config->txrx_coexist))
3062 + AOut = 1;
3063 + if((ptri2s_config->bRxDMAEnable) || (ptri2s_config->txrx_coexist))
3064 + AIn = 1;
3065 +#if defined(CONFIG_I2S_WM8960)
3066 + audiohw_postinit(!(ptri2s_config->slave_en), AIn, AOut, ptri2s_config->codec_pll_en, ptri2s_config->wordlen_24b);
3067 + audiohw_micboost(ptri2s_config->micboost);
3068 + audiohw_micin(ptri2s_config->micin);
3069 +#elif defined(CONFIG_I2S_WM8750)
3070 + audiohw_postinit(!(ptri2s_config->slave_en), AIn, AOut, ptri2s_config->wordlen_24b);
3071 +#endif
3072 + MSG("AOut=%d, AIn=%d\n", AOut, AIn);
3073 +#else
3074 +#if defined(CONFIG_I2S_WM8750)
3075 + audiohw_postinit(!(ptri2s_config->slave_en), 0, 1);
3076 +#elif defined(CONFIG_I2S_WM8960)
3077 + audiohw_postinit(!(ptri2s_config->slave_en), 1, 1, ptri2s_config->codec_pll_en);
3078 +#elif defined(CONFIG_I2S_WM8751)
3079 + if(ptri2s_config->slave_en==0)
3080 + audiohw_postinit(1,1);
3081 + else
3082 + audiohw_postinit(0,1);
3083 +#endif
3084 +#endif
3085 + return 0;
3086 +}
3087 +
3088 +int i2s_codec_disable(i2s_config_type* ptri2s_config)
3089 +{
3090 +#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
3091 + audiohw_close();
3092 +#endif
3093 + return 0;
3094 +}
3095 +
3096 +int i2s_reset_config(i2s_config_type* ptri2s_config)
3097 +{
3098 + unsigned long data;
3099 +
3100 + /* RESET bit: write 1 clear */
3101 +#if defined(CONFIG_RALINK_RT6855A)
3102 + data = i2s_inw(RALINK_SYSCTL_BASE+0x834);
3103 + data |= (1<<17);
3104 + i2s_outw(RALINK_SYSCTL_BASE+0x834, data);
3105 +
3106 + data = i2s_inw(RALINK_SYSCTL_BASE+0x834);
3107 + data &= ~(1<<17);
3108 + i2s_outw(RALINK_SYSCTL_BASE+0x834, data);
3109 +#elif defined(CONFIG_ARCH_MT7623)
3110 + data = i2s_inw(0xFB000000+0x34);
3111 + data |= (1<<17);
3112 + i2s_outw(0xFB000000+0x34, data);
3113 +
3114 + data = i2s_inw(0xFB000000+0x34);
3115 + data &= ~(1<<17);
3116 + i2s_outw(0xFB000000+0x34, data);
3117 +#else
3118 + data = i2s_inw(RALINK_SYSCTL_BASE+0x34);
3119 + data |= (1<<17);
3120 + i2s_outw(RALINK_SYSCTL_BASE+0x34, data);
3121 +
3122 + data = i2s_inw(RALINK_SYSCTL_BASE+0x34);
3123 + data &= ~(1<<17);
3124 + i2s_outw(RALINK_SYSCTL_BASE+0x34, data);
3125 +
3126 +#if 0 /* Reset GDMA */
3127 + data = i2s_inw(RALINK_SYSCTL_BASE+0x34);
3128 + data |= (1<<14);
3129 + i2s_outw(RALINK_SYSCTL_BASE+0x34, data);
3130 +
3131 + data = i2s_inw(RALINK_SYSCTL_BASE+0x34);
3132 + data &= ~(1<<14);
3133 + i2s_outw(RALINK_SYSCTL_BASE+0x34, data);
3134 +#endif
3135 +#endif
3136 + _printk("I2S reset complete!!\n");
3137 + return 0;
3138 +}
3139 +
3140 +int i2s_tx_config(i2s_config_type* ptri2s_config)
3141 +{
3142 + unsigned long data;
3143 + /* set I2S_I2SCFG */
3144 + data = i2s_inw(I2S_I2SCFG);
3145 + data &= 0xFFFFFF81;
3146 + data |= REGBIT(ptri2s_config->tx_ff_thres, I2S_TX_FF_THRES);
3147 + data |= REGBIT(ptri2s_config->tx_ch_swap, I2S_TX_CH_SWAP);
3148 +#if defined(CONFIG_RALINK_RT6855A)
3149 + data |= REGBIT(1, I2S_BYTE_SWAP);
3150 +#endif
3151 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
3152 + MSG("TX:wordLen=%d, sysEndian=%d\n", ptri2s_config->wordlen_24b, ptri2s_config->sys_endian);
3153 + data |= REGBIT(ptri2s_config->wordlen_24b, I2S_DATA_24BIT);
3154 + data |= REGBIT(ptri2s_config->sys_endian, I2S_SYS_ENDIAN);
3155 + data |= REGBIT(ptri2s_config->little_edn, I2S_LITTLE_ENDIAN);
3156 +#endif
3157 + data &= ~REGBIT(1, I2S_TX_CH0_OFF);
3158 + data &= ~REGBIT(1, I2S_TX_CH1_OFF);
3159 + i2s_outw(I2S_I2SCFG, data);
3160 +
3161 + /* set I2S_I2SCFG1 */
3162 + MSG("internal loopback: %d\n", ptri2s_config->lbk);
3163 + data = i2s_inw(I2S_I2SCFG1);
3164 + data |= REGBIT(ptri2s_config->lbk, I2S_LBK_EN);
3165 + data |= REGBIT(ptri2s_config->extlbk, I2S_EXT_LBK_EN);
3166 + data &= 0xFFFFFFFC;
3167 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
3168 + data |= REGBIT(ptri2s_config->fmt, I2S_DATA_FMT);
3169 +#endif
3170 + i2s_outw(I2S_I2SCFG1, data);
3171 +
3172 + return 0;
3173 +}
3174 +
3175 +int i2s_rx_config(i2s_config_type* ptri2s_config)
3176 +{
3177 + unsigned long data;
3178 + /* set I2S_I2SCFG */
3179 + data = i2s_inw(I2S_I2SCFG);
3180 + data &= 0xFFFF81FF;
3181 + data |= REGBIT(ptri2s_config->rx_ff_thres, I2S_RX_FF_THRES);
3182 + data |= REGBIT(ptri2s_config->rx_ch_swap, I2S_RX_CH_SWAP);
3183 + data &= ~REGBIT(1, I2S_RX_CH0_OFF);
3184 + data &= ~REGBIT(1, I2S_RX_CH1_OFF);
3185 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
3186 + MSG("RX:wordLen=%d, sysEndian=%d\n", ptri2s_config->wordlen_24b, ptri2s_config->sys_endian);
3187 + data |= REGBIT(ptri2s_config->wordlen_24b, I2S_DATA_24BIT);
3188 + data |= REGBIT(ptri2s_config->sys_endian, I2S_SYS_ENDIAN);
3189 + data |= REGBIT(ptri2s_config->little_edn, I2S_LITTLE_ENDIAN);
3190 +#endif
3191 + i2s_outw(I2S_I2SCFG, data);
3192 +
3193 + /* set I2S_I2SCFG1 */
3194 + data = i2s_inw(I2S_I2SCFG1);
3195 + data |= REGBIT(ptri2s_config->lbk, I2S_LBK_EN);
3196 + data |= REGBIT(ptri2s_config->extlbk, I2S_EXT_LBK_EN);
3197 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
3198 + data &= 0xFFFFFFFC;
3199 + data |= REGBIT(ptri2s_config->fmt, I2S_DATA_FMT);
3200 +#endif
3201 + i2s_outw(I2S_I2SCFG1, data);
3202 +
3203 + return 0;
3204 +}
3205 +
3206 +/* Turn On Tx DMA and INT */
3207 +int i2s_tx_enable(i2s_config_type* ptri2s_config)
3208 +{
3209 + unsigned long data;
3210 +
3211 +#if defined(I2S_HW_INTERRUPT_EN)
3212 + data = i2s_inw(I2S_INT_EN);
3213 + data |= REGBIT(0x1, I2S_TX_INT3_EN); /* FIFO DMA fault */
3214 + data |= REGBIT(0x1, I2S_TX_INT2_EN); /* FIFO overrun */
3215 + data |= REGBIT(0x1, I2S_TX_INT1_EN); /* FIFO underrun */
3216 + data |= REGBIT(0x1, I2S_TX_INT0_EN); /* FIFO below threshold */
3217 + i2s_outw(I2S_INT_EN, data);
3218 +#endif
3219 +
3220 + data = i2s_inw(I2S_I2SCFG);
3221 +#if defined(CONFIG_I2S_TXRX)
3222 + data |= REGBIT(0x1, I2S_TX_EN);
3223 +#endif
3224 + data |= REGBIT(0x1, I2S_DMA_EN);
3225 + i2s_outw(I2S_I2SCFG, data);
3226 +
3227 + data = i2s_inw(I2S_I2SCFG);
3228 + data |= REGBIT(0x1, I2S_EN);
3229 + i2s_outw(I2S_I2SCFG, data);
3230 +
3231 + MSG("i2s_tx_enable done\n");
3232 + return I2S_OK;
3233 +}
3234 +
3235 +/* Turn On Rx DMA and INT */
3236 +int i2s_rx_enable(i2s_config_type* ptri2s_config)
3237 +{
3238 + unsigned long data;
3239 +
3240 +#if defined(I2S_HW_INTERRUPT_EN)
3241 + data = i2s_inw(I2S_INT_EN);
3242 + data |= REGBIT(0x1, I2S_RX_INT3_EN); /* FIFO DMA fault */
3243 + data |= REGBIT(0x1, I2S_RX_INT2_EN); /* FIFO overrun */
3244 + data |= REGBIT(0x1, I2S_RX_INT1_EN); /* FIFO underrun */
3245 + data |= REGBIT(0x1, I2S_RX_INT0_EN); /* FIFO below threshold */
3246 + i2s_outw(I2S_INT_EN, data);
3247 +#endif
3248 +
3249 + data = i2s_inw(I2S_I2SCFG);
3250 +#if defined(CONFIG_I2S_TXRX)
3251 + data |= REGBIT(0x1, I2S_RX_EN);
3252 +#endif
3253 + data |= REGBIT(0x1, I2S_DMA_EN);
3254 + i2s_outw(I2S_I2SCFG, data);
3255 +
3256 + data = i2s_inw(I2S_I2SCFG);
3257 + data |= REGBIT(0x1, I2S_EN);
3258 + i2s_outw(I2S_I2SCFG, data);
3259 +
3260 + MSG("i2s_rx_enable done\n");
3261 + return I2S_OK;
3262 +}
3263 +/* Turn Off Tx DMA and INT */
3264 +int i2s_tx_disable(i2s_config_type* ptri2s_config)
3265 +{
3266 + unsigned long data;
3267 +
3268 +#if defined(I2S_HW_INTERRUPT_EN)
3269 + data = i2s_inw(I2S_INT_EN);
3270 + data &= ~REGBIT(0x1, I2S_TX_INT3_EN);
3271 + data &= ~REGBIT(0x1, I2S_TX_INT2_EN);
3272 + data &= ~REGBIT(0x1, I2S_TX_INT1_EN);
3273 + data &= ~REGBIT(0x1, I2S_TX_INT0_EN);
3274 + i2s_outw(I2S_INT_EN, data);
3275 +#endif
3276 +
3277 + data = i2s_inw(I2S_I2SCFG);
3278 +#if defined(CONFIG_I2S_TXRX)
3279 + data &= ~REGBIT(0x1, I2S_TX_EN);
3280 +#endif
3281 + if(ptri2s_config->bRxDMAEnable==0)
3282 + {
3283 + ptri2s_config->bTxDMAEnable = 0;
3284 + data &= ~REGBIT(0x1, I2S_DMA_EN);
3285 + data &= ~REGBIT(0x1, I2S_EN);
3286 + }
3287 + i2s_outw(I2S_I2SCFG, data);
3288 + return I2S_OK;
3289 +}
3290 +/* Turn Off Rx DMA and INT */
3291 +int i2s_rx_disable(i2s_config_type* ptri2s_config)
3292 +{
3293 + unsigned long data;
3294 +
3295 +#if defined(I2S_HW_INTERRUPT_EN)
3296 + data = i2s_inw(I2S_INT_EN);
3297 + data &= ~REGBIT(0x1, I2S_RX_INT3_EN);
3298 + data &= ~REGBIT(0x1, I2S_RX_INT2_EN);
3299 + data &= ~REGBIT(0x1, I2S_RX_INT1_EN);
3300 + data &= ~REGBIT(0x1, I2S_RX_INT0_EN);
3301 + i2s_outw(I2S_INT_EN, data);
3302 +#endif
3303 +
3304 + data = i2s_inw(I2S_I2SCFG);
3305 +#if defined(CONFIG_I2S_TXRX)
3306 + data &= ~REGBIT(0x1, I2S_RX_EN);
3307 +#endif
3308 + if(ptri2s_config->bTxDMAEnable==0)
3309 + {
3310 + ptri2s_config->bRxDMAEnable = 0;
3311 + data &= ~REGBIT(0x1, I2S_DMA_EN);
3312 + data &= ~REGBIT(0x1, I2S_EN);
3313 + }
3314 + i2s_outw(I2S_I2SCFG, data);
3315 + return I2S_OK;
3316 +}
3317 +
3318 +int i2s_dma_tx_transf_data(i2s_config_type* ptri2s_config, u32 dma_ch)
3319 +{
3320 + int tx_r_idx;
3321 +
3322 + if ((pi2s_config->bALSAEnable==1) && (pi2s_config->bALSAMMAPEnable==1))
3323 + tx_r_idx = (pi2s_config->tx_r_idx + ALSA_MMAP_IDX_SHIFT)%MAX_I2S_PAGE;
3324 + else
3325 + tx_r_idx = pi2s_config->tx_r_idx;
3326 +
3327 + if(dma_ch==GDMA_I2S_TX0)
3328 + {
3329 +#if defined(CONFIG_I2S_MMAP)
3330 + dma_sync_single_for_device(NULL, i2s_mmap_addr[tx_r_idx], I2S_PAGE_SIZE, DMA_TO_DEVICE);
3331 +#if defined(ARM_ARCH)
3332 + 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);
3333 +#else
3334 + 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);
3335 +#endif
3336 +#else
3337 + memcpy(pi2s_config->pPage0TxBuf8ptr, pi2s_config->pMMAPTxBufPtr[tx_r_idx], I2S_PAGE_SIZE);
3338 +#if defined(ARM_ARCH)
3339 + GdmaI2sTx(i2s_txdma_addr0, I2S_TX_FIFO_WREG_PHY, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3340 +#else
3341 + GdmaI2sTx((u32)(pi2s_config->pPage0TxBuf8ptr), I2S_TX_FIFO_WREG, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3342 +#endif
3343 +#endif
3344 + pi2s_config->dmach = GDMA_I2S_TX0;
3345 + pi2s_config->tx_r_idx = (pi2s_config->tx_r_idx+1)%MAX_I2S_PAGE;
3346 + }
3347 + else
3348 + {
3349 +#if defined(CONFIG_I2S_MMAP)
3350 + dma_sync_single_for_device(NULL, i2s_mmap_addr[tx_r_idx], I2S_PAGE_SIZE, DMA_TO_DEVICE);
3351 +#if defined(ARM_ARCH)
3352 + 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);
3353 +#else
3354 + 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);
3355 +#endif
3356 +#else
3357 + memcpy(pi2s_config->pPage1TxBuf8ptr, pi2s_config->pMMAPTxBufPtr[tx_r_idx], I2S_PAGE_SIZE);
3358 +#if defined(ARM_ARCH)
3359 + GdmaI2sTx(i2s_txdma_addr1, I2S_TX_FIFO_WREG_PHY, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3360 +#else
3361 + GdmaI2sTx((u32)(pi2s_config->pPage1TxBuf8ptr), I2S_TX_FIFO_WREG, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3362 +#endif
3363 +#endif
3364 + pi2s_config->dmach = GDMA_I2S_TX1;
3365 + pi2s_config->tx_r_idx = (pi2s_config->tx_r_idx+1)%MAX_I2S_PAGE;
3366 + }
3367 +#if defined(CONFIG_I2S_WITH_AEC)
3368 + if(aecFuncP->AECFeEnq){
3369 + aecFuncP->AECFeEnq(0,pi2s_config->pMMAPTxBufPtr[pi2s_config->tx_r_idx],I2S_PAGE_SIZE);
3370 + }
3371 +#endif
3372 + return 0;
3373 +}
3374 +
3375 +int i2s_dma_tx_transf_zero(i2s_config_type* ptri2s_config, u32 dma_ch)
3376 +{
3377 + if(dma_ch==GDMA_I2S_TX0)
3378 + {
3379 + memset(pi2s_config->pPage0TxBuf8ptr, 0, I2S_PAGE_SIZE);
3380 +#if defined(ARM_ARCH)
3381 + GdmaI2sTx(i2s_txdma_addr0, I2S_TX_FIFO_WREG_PHY, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3382 +#else
3383 + GdmaI2sTx((u32)pi2s_config->pPage0TxBuf8ptr, I2S_TX_FIFO_WREG, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3384 +#endif
3385 + }
3386 + else
3387 + {
3388 + memset(pi2s_config->pPage1TxBuf8ptr, 0, I2S_PAGE_SIZE);
3389 +#if defined(ARM_ARCH)
3390 + GdmaI2sTx(i2s_txdma_addr1, I2S_TX_FIFO_WREG_PHY, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3391 +#else
3392 + GdmaI2sTx((u32)pi2s_config->pPage1TxBuf8ptr, I2S_TX_FIFO_WREG, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3393 +#endif
3394 + }
3395 + return 0;
3396 +}
3397 +
3398 +int i2s_dma_rx_transf_data(i2s_config_type* ptri2s_config, u32 dma_ch)
3399 +{
3400 + int rx_w_idx;
3401 +
3402 + pi2s_config->rx_w_idx = (pi2s_config->rx_w_idx+1)%MAX_I2S_PAGE;
3403 +
3404 + if ((pi2s_config->bALSAEnable==1) && (pi2s_config->bALSAMMAPEnable==1))
3405 + rx_w_idx = (pi2s_config->rx_w_idx+ALSA_MMAP_IDX_SHIFT)%MAX_I2S_PAGE;
3406 + else
3407 + rx_w_idx = (pi2s_config->rx_w_idx)%MAX_I2S_PAGE;
3408 +
3409 + if(dma_ch==GDMA_I2S_RX0)
3410 + {
3411 +
3412 +#ifdef CONFIG_I2S_MMAP
3413 + 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);
3414 +#if defined(ARM_ARCH)
3415 + 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);
3416 +#else
3417 + 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);
3418 +#endif
3419 +#else
3420 + memcpy(pi2s_config->pMMAPRxBufPtr[rx_w_idx], pi2s_config->pPage0RxBuf8ptr, I2S_PAGE_SIZE);
3421 +#if defined(ARM_ARCH)
3422 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr0, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3423 +#else
3424 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)(pi2s_config->pPage0RxBuf8ptr), 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3425 +#endif
3426 +#endif
3427 + pi2s_config->dmach = GDMA_I2S_RX0;
3428 + }
3429 + else
3430 + {
3431 +
3432 +#ifdef CONFIG_I2S_MMAP
3433 + 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);
3434 +#if defined(ARM_ARCH)
3435 + 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);
3436 +#else
3437 + 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);
3438 +#endif
3439 +#else
3440 + memcpy(pi2s_config->pMMAPRxBufPtr[rx_w_idx], pi2s_config->pPage1RxBuf8ptr, I2S_PAGE_SIZE);
3441 +#if defined(ARM_ARCH)
3442 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr1, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3443 +#else
3444 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)(pi2s_config->pPage1RxBuf8ptr), 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3445 +#endif
3446 +#endif
3447 + pi2s_config->dmach = GDMA_I2S_RX1;
3448 +
3449 + }
3450 +#if defined(CONFIG_I2S_WITH_AEC)
3451 + if(aecFuncP->AECNeEnq){
3452 + aecFuncP->AECNeEnq(0,pi2s_config->pMMAPRxBufPtr[rx_w_idx],I2S_PAGE_SIZE);
3453 + }
3454 +#endif
3455 + return 0;
3456 +}
3457 +
3458 +int i2s_dma_rx_transf_zero(i2s_config_type* ptri2s_config, u32 dma_ch)
3459 +{
3460 + if(dma_ch==GDMA_I2S_RX0)
3461 + {
3462 + memset(pi2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE);
3463 +#if defined(ARM_ARCH)
3464 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr0, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3465 +#else
3466 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)pi2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3467 +#endif
3468 + }
3469 + else
3470 + {
3471 + memset(pi2s_config->pPage1RxBuf8ptr, 0, I2S_PAGE_SIZE);
3472 +#if defined(ARM_ARCH)
3473 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr1, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3474 +#else
3475 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)pi2s_config->pPage1RxBuf8ptr, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3476 +#endif
3477 + }
3478 + return 0;
3479 +}
3480 +
3481 +void i2s_dma_tx_handler(u32 dma_ch)
3482 +{
3483 + pi2s_config->enLable = 1; /* TX:enLabel=1; RX:enLabel=2 */
3484 +
3485 + if(pi2s_config->bTxDMAEnable==0)
3486 + {
3487 + if(pi2s_config->end_cnt != 0)
3488 + {
3489 + i2s_dma_tx_transf_data(pi2s_config, dma_ch);
3490 + pi2s_config->end_cnt --;
3491 + MSG("end_cnt = %d, r_idx = %d\n", pi2s_config->end_cnt, pi2s_config->tx_r_idx);
3492 + }
3493 + else
3494 + {
3495 + pi2s_config->tx_stop_cnt++;
3496 + i2s_dma_tx_soft_stop(pi2s_config, dma_ch);
3497 + MSG("tx_stop=%d, ch=%d\n", pi2s_config->tx_stop_cnt, dma_ch);
3498 + if (pi2s_config->tx_stop_cnt == 3)
3499 + {
3500 + wake_up_interruptible(&(pi2s_config->i2s_tx_qh));
3501 + _printk("T:wake up!!\n");
3502 + }
3503 + }
3504 + return;
3505 + }
3506 +
3507 + pi2s_config->tx_isr_cnt++;
3508 +
3509 +#ifdef I2S_STATISTIC
3510 + i2s_int_status(dma_ch);
3511 +#endif
3512 + /* FIXME */
3513 + if(pi2s_config->bALSAEnable)
3514 + {
3515 + if(pi2s_config->dmaStat[STREAM_PLAYBACK])
3516 + {
3517 + if(!pi2s_config->bTrigger[STREAM_PLAYBACK]){
3518 + //_printk("trigger stop: rIdx:%d widx:%d\n", pi2s_config->tx_r_idx,pi2s_config->tx_w_idx);
3519 + i2s_dma_tx_transf_zero(pi2s_config, dma_ch);
3520 + if(pi2s_config->bPreTrigger[STREAM_PLAYBACK]){
3521 + /* mtk04880 commented:
3522 + * for corner case, there are cases which ALSA Trigger stop before disabling DMA.
3523 + * For which case, it needs to keep call snd_pcm_elapased to keep ALSA hw ptr updating.
3524 + * It is so called post stop handlment.
3525 + */
3526 + //_printk("post-stop\n");
3527 + goto EXIT;
3528 + }
3529 + else{
3530 + //_printk("pre-stop\n");
3531 + wake_up_interruptible(&(pi2s_config->i2s_tx_qh));
3532 + return;
3533 + }
3534 + }
3535 + else{
3536 + if(!pi2s_config->bPreTrigger[STREAM_PLAYBACK])
3537 + pi2s_config->bPreTrigger[STREAM_PLAYBACK] = 1;
3538 +
3539 + }
3540 + }
3541 + }
3542 + else
3543 + {
3544 + if(pi2s_config->tx_r_idx==pi2s_config->tx_w_idx)
3545 + {
3546 + /* Buffer Empty */
3547 + 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);
3548 +#ifdef I2S_STATISTIC
3549 + pi2s_status->txbuffer_unrun++;
3550 +#endif
3551 + i2s_dma_tx_transf_zero(pi2s_config, dma_ch);
3552 + goto EXIT;
3553 + }
3554 + }
3555 +
3556 + if(pi2s_config->pMMAPTxBufPtr[pi2s_config->tx_r_idx]==NULL)
3557 + {
3558 + MSG("mmap buf NULL [%d]\n",pi2s_config->tx_r_idx);
3559 + i2s_dma_tx_transf_zero(pi2s_config, dma_ch);
3560 +
3561 + goto EXIT;
3562 + }
3563 +
3564 + if(pi2s_config->tx_pause_en == 1)
3565 + {
3566 + /* Enable PAUSE */
3567 + MSG("TX pause now\n");
3568 + i2s_dma_tx_transf_zero(pi2s_config, dma_ch);
3569 +
3570 + goto EXIT;
3571 + }
3572 +
3573 +#ifdef I2S_STATISTIC
3574 + pi2s_status->txbuffer_len--;
3575 +#endif
3576 + i2s_dma_tx_transf_data(pi2s_config, dma_ch);
3577 +
3578 +EXIT:
3579 +#if defined(CONFIG_SND_MT76XX_SOC)
3580 + if(pi2s_config->bALSAEnable == 1){
3581 + if(pi2s_config->pss[STREAM_PLAYBACK])
3582 + snd_pcm_period_elapsed(pi2s_config->pss[STREAM_PLAYBACK]);
3583 + }
3584 +#endif
3585 + wake_up_interruptible(&(pi2s_config->i2s_tx_qh));
3586 + return;
3587 +}
3588 +
3589 +void i2s_dma_rx_handler(u32 dma_ch)
3590 +{
3591 + pi2s_config->enLable = 2; /* TX:enLabel=1; RX:enLabel=2 */
3592 +#if defined(CONFIG_I2S_TXRX)
3593 + if(pi2s_config->rx_isr_cnt==0)
3594 + {
3595 + pi2s_config->next_p0_idx = 0;
3596 + pi2s_config->next_p1_idx = 1;
3597 + }
3598 + pi2s_config->rx_isr_cnt++;
3599 +
3600 +#ifdef I2S_STATISTIC
3601 + i2s_int_status(dma_ch);
3602 +#endif
3603 +
3604 + if (pi2s_config->bRxDMAEnable==0)
3605 + {
3606 + pi2s_config->rx_stop_cnt++;
3607 + i2s_dma_rx_soft_stop(pi2s_config, dma_ch);
3608 + MSG("rx_stop=%d\n", pi2s_config->rx_stop_cnt);
3609 +
3610 + if(pi2s_config->rx_stop_cnt == 2)
3611 + {
3612 + wake_up_interruptible(&(pi2s_config->i2s_rx_qh));
3613 + _printk("R:wake up!!\n");
3614 + }
3615 + return;
3616 + }
3617 +
3618 + if(pi2s_config->bALSAEnable)
3619 + {
3620 + if(pi2s_config->dmaStat[STREAM_CAPTURE]){
3621 + if(!pi2s_config->bTrigger[STREAM_CAPTURE]){
3622 + MSG("trigger stop: rIdx:%d widx:%d\n", pi2s_config->rx_r_idx,pi2s_config->rx_w_idx);
3623 + i2s_dma_rx_transf_zero(pi2s_config, dma_ch);
3624 + wake_up_interruptible(&(pi2s_config->i2s_rx_qh));
3625 + return;
3626 + }
3627 + }
3628 + }
3629 + else
3630 + {
3631 + if(((pi2s_config->rx_w_idx+1)%MAX_I2S_PAGE)==pi2s_config->rx_r_idx){
3632 + /* Buffer Full */
3633 + 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);
3634 +#ifdef I2S_STATISTIC
3635 + pi2s_status->rxbuffer_unrun++;
3636 +#endif
3637 + i2s_dma_rx_transf_zero(pi2s_config, dma_ch);
3638 + goto EXIT;
3639 + }
3640 + }
3641 +
3642 + if(pi2s_config->rx_pause_en == 1)
3643 + {
3644 + /* Enable PAUSE */
3645 + i2s_dma_rx_transf_zero(pi2s_config, dma_ch);
3646 +
3647 + goto EXIT;
3648 + }
3649 +
3650 +#ifdef I2S_STATISTIC
3651 + pi2s_status->rxbuffer_len++;
3652 +#endif
3653 + i2s_dma_rx_transf_data(pi2s_config, dma_ch);
3654 +
3655 +EXIT:
3656 +#if defined(CONFIG_SND_MT76XX_SOC)
3657 + if(pi2s_config->bALSAEnable == 1){
3658 + if(pi2s_config->pss[STREAM_CAPTURE])
3659 + snd_pcm_period_elapsed(pi2s_config->pss[STREAM_CAPTURE]);
3660 + }
3661 +#endif
3662 + wake_up_interruptible(&(pi2s_config->i2s_rx_qh));
3663 +#endif
3664 + return;
3665 +}
3666 +
3667 +#ifdef I2S_STATISTIC
3668 +void i2s_int_status(u32 dma_ch)
3669 +{
3670 + u32 i2s_status;
3671 +
3672 + if((pi2s_config->tx_isr_cnt>0)||(pi2s_config->rx_isr_cnt>0))
3673 + {
3674 + i2s_status = i2s_inw(I2S_INT_STATUS);
3675 +
3676 + if(i2s_status&REGBIT(1, I2S_TX_DMA_FAULT))
3677 + {
3678 + pi2s_status->txdmafault++;
3679 + }
3680 + if(i2s_status&REGBIT(1, I2S_TX_OVRUN))
3681 + {
3682 + pi2s_status->txovrun++;
3683 + }
3684 + if(i2s_status&REGBIT(1, I2S_TX_UNRUN))
3685 + {
3686 + pi2s_status->txunrun++;
3687 + }
3688 + if(i2s_status&REGBIT(1, I2S_TX_THRES))
3689 + {
3690 + pi2s_status->txthres++;
3691 + }
3692 + if(i2s_status&REGBIT(1, I2S_RX_DMA_FAULT))
3693 + {
3694 + pi2s_status->rxdmafault++;
3695 + }
3696 + if(i2s_status&REGBIT(1, I2S_RX_OVRUN))
3697 + {
3698 + pi2s_status->rxovrun++;
3699 + }
3700 + if(i2s_status&REGBIT(1, I2S_RX_UNRUN))
3701 + {
3702 + pi2s_status->rxunrun++;
3703 + }
3704 + if(i2s_status&REGBIT(1, I2S_RX_THRES))
3705 + {
3706 + pi2s_status->rxthres++;
3707 + }
3708 + }
3709 +#if 0
3710 + if(pi2s_config->enLable == 1)
3711 + {
3712 + if((pi2s_config->tx_isr_cnt>0) && (pi2s_config->tx_isr_cnt%40==0))
3713 + {
3714 + MSG("tisr i=%u,ch=%u,o=%u,u=%d,s=%X [r=%d,w=%d]\n",\
3715 + pi2s_config->tx_isr_cnt,dma_ch,pi2s_status->txovrun,pi2s_status->txunrun,\
3716 + i2s_inw(I2S_INT_STATUS),pi2s_config->tx_r_idx,pi2s_config->tx_w_idx);
3717 + }
3718 + }
3719 +
3720 + if(pi2s_config->enLable == 2)
3721 + {
3722 + if((pi2s_config->rx_isr_cnt>0) && (pi2s_config->rx_isr_cnt%40==0))
3723 + {
3724 + MSG("risr i=%u,ch=%u,o=%u,u=%d,s=%X [r=%d,w=%d]\n",\
3725 + pi2s_config->rx_isr_cnt,dma_ch,pi2s_status->rxovrun,pi2s_status->rxunrun,\
3726 + i2s_inw(I2S_INT_STATUS),pi2s_config->rx_r_idx,pi2s_config->rx_w_idx);
3727 + }
3728 + }
3729 +#endif
3730 +
3731 + *(unsigned long*)(I2S_INT_STATUS) = 0xFFFFFFFF;
3732 +}
3733 +#endif
3734 +
3735 +#if defined(I2S_HW_INTERRUPT_EN)&&(I2S_SW_IRQ_EN)
3736 +irqreturn_t i2s_irq_isr(int irq, void *irqaction)
3737 +{
3738 + u32 i2s_status;
3739 +
3740 + //MSG("i2s_irq_isr [0x%08X]\n",i2s_inw(I2S_INT_STATUS));
3741 + if((pi2s_config->tx_isr_cnt>0)||(pi2s_config->rx_isr_cnt>0))
3742 + {
3743 + i2s_status = i2s_inw(I2S_INT_STATUS);
3744 + MSG("i2s_irq_isr [0x%08X]\n",i2s_status);
3745 + }
3746 + else
3747 + return IRQ_HANDLED;
3748 +
3749 + if(i2s_status&REGBIT(1, I2S_TX_DMA_FAULT))
3750 + {
3751 +#ifdef I2S_STATISTIC
3752 + pi2s_status->txdmafault++;
3753 +#endif
3754 + }
3755 + if(i2s_status&REGBIT(1, I2S_TX_OVRUN))
3756 + {
3757 +#ifdef I2S_STATISTIC
3758 + pi2s_status->txovrun++;
3759 +#endif
3760 + }
3761 + if(i2s_status&REGBIT(1, I2S_TX_UNRUN))
3762 + {
3763 +#ifdef I2S_STATISTIC
3764 + pi2s_status->txunrun++;
3765 +#endif
3766 + }
3767 + if(i2s_status&REGBIT(1, I2S_TX_THRES))
3768 + {
3769 +#ifdef I2S_STATISTIC
3770 + pi2s_status->txthres++;
3771 +#endif
3772 + }
3773 + if(i2s_status&REGBIT(1, I2S_RX_DMA_FAULT))
3774 + {
3775 +#ifdef I2S_STATISTIC
3776 + pi2s_status->rxdmafault++;
3777 +#endif
3778 + }
3779 + if(i2s_status&REGBIT(1, I2S_RX_OVRUN))
3780 + {
3781 +#ifdef I2S_STATISTIC
3782 + pi2s_status->rxovrun++;
3783 +#endif
3784 + }
3785 + if(i2s_status&REGBIT(1, I2S_RX_UNRUN))
3786 + {
3787 +#ifdef I2S_STATISTIC
3788 + pi2s_status->rxunrun++;
3789 +#endif
3790 + }
3791 + if(i2s_status&REGBIT(1, I2S_RX_THRES))
3792 + {
3793 +#ifdef I2S_STATISTIC
3794 + pi2s_status->rxthres++;
3795 +#endif
3796 + }
3797 + i2s_outw(I2S_INT_STATUS, 0xFFFFFFFF);
3798 + return IRQ_HANDLED;
3799 +}
3800 +#endif
3801 +
3802 +void i2s_tx_task(unsigned long pData)
3803 +{
3804 + unsigned long flags;
3805 + spin_lock_irqsave(&pi2s_config->lock, flags);
3806 + //if (pi2s_config->bTxDMAEnable!=0)
3807 + {
3808 + if (pi2s_config->tx_unmask_ch!=0)
3809 + {
3810 + u32 dmach = pi2s_config->tx_unmask_ch;
3811 + u32 ch;
3812 + for (ch = 0; ch < 16; ch++)
3813 + {
3814 + if (dmach& (1<<ch))
3815 + {
3816 + MSG("do unmask ch%d tisr=%d in tx_isr\n",ch,pi2s_config->tx_isr_cnt);
3817 + GdmaUnMaskChannel(ch);
3818 + }
3819 + }
3820 + pi2s_config->tx_unmask_ch = 0;
3821 + }
3822 + }
3823 + spin_unlock_irqrestore(&pi2s_config->lock, flags);
3824 +}
3825 +
3826 +void i2s_rx_task(unsigned long pData)
3827 +{
3828 + unsigned long flags;
3829 + spin_lock_irqsave(&pi2s_config->lock, flags);
3830 + //if (pi2s_config->bRxDMAEnable!=0)
3831 + {
3832 + if (pi2s_config->rx_unmask_ch!=0)
3833 + {
3834 + u32 dmach = pi2s_config->rx_unmask_ch;
3835 + u32 ch;
3836 + for (ch = 0; ch < 16; ch++)
3837 + {
3838 + if (dmach& (1<<ch))
3839 + {
3840 + MSG("do unmask ch%d risr=%d in rx_isr\n",ch,pi2s_config->rx_isr_cnt);
3841 + GdmaUnMaskChannel(ch);
3842 + }
3843 + }
3844 + pi2s_config->rx_unmask_ch = 0;
3845 +
3846 + }
3847 + }
3848 + spin_unlock_irqrestore(&pi2s_config->lock, flags);
3849 +}
3850 +
3851 +
3852 +void i2s_dma_unmask_handler(u32 dma_ch)
3853 +{
3854 + MSG("i2s_dma_unmask_handler ch=%d\n",dma_ch);
3855 +
3856 + GdmaUnMaskChannel(dma_ch);
3857 +
3858 + return;
3859 +}
3860 +
3861 +void i2s_dma_tx_unmask_handler(u32 dma_ch)
3862 +{
3863 + MSG("i2s_dma_tx_unmask_handler ch=%d\n",dma_ch);
3864 + pi2s_config->tx_unmask_ch |= (1<<dma_ch);
3865 + tasklet_hi_schedule(&i2s_tx_tasklet);
3866 + return;
3867 +}
3868 +
3869 +void i2s_dma_rx_unmask_handler(u32 dma_ch)
3870 +{
3871 + MSG("i2s_dma_rx_unmask_handler ch=%d\n",dma_ch);
3872 + pi2s_config->rx_unmask_ch |= (1<<dma_ch);
3873 + tasklet_hi_schedule(&i2s_rx_tasklet);
3874 + return;
3875 +}
3876 +
3877 +void i2s_dma_mask_handler(u32 dma_ch)
3878 +{
3879 + MSG("i2s_dma_mask_handler ch=%d\n", dma_ch);
3880 + GdmaMaskChannel(dma_ch);
3881 + return;
3882 +}
3883 +
3884 +void i2s_dma_tx_init(i2s_config_type* ptri2s_config)
3885 +{
3886 + memset(pi2s_config->pPage0TxBuf8ptr, 0, I2S_PAGE_SIZE);
3887 + memset(pi2s_config->pPage1TxBuf8ptr, 0, I2S_PAGE_SIZE);
3888 +#if defined(ARM_ARCH)
3889 + GdmaI2sTx(i2s_txdma_addr0, I2S_TX_FIFO_WREG_PHY, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3890 + GdmaI2sTx(i2s_txdma_addr1, I2S_TX_FIFO_WREG_PHY, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3891 +#else
3892 + GdmaI2sTx((u32)ptri2s_config->pPage0TxBuf8ptr, I2S_FIFO_WREG, 0, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3893 + GdmaI2sTx((u32)ptri2s_config->pPage1TxBuf8ptr, I2S_FIFO_WREG, 1, I2S_PAGE_SIZE, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3894 +#endif
3895 +
3896 + return;
3897 +}
3898 +
3899 +void i2s_dma_rx_init(i2s_config_type* ptri2s_config)
3900 +{
3901 + memset(pi2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE);
3902 + memset(pi2s_config->pPage1RxBuf8ptr, 0, I2S_PAGE_SIZE);
3903 +
3904 +#if defined(ARM_ARCH)
3905 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr0, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3906 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr1, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3907 +#else
3908 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)ptri2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3909 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)ptri2s_config->pPage1RxBuf8ptr, 1, I2S_PAGE_SIZE, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3910 +#endif
3911 +
3912 + return;
3913 +}
3914 +
3915 +void i2s_dma_tx_end_handle(i2s_config_type* ptri2s_config)
3916 +{
3917 + if (ptri2s_config->tx_w_idx < ptri2s_config->tx_r_idx)
3918 + {
3919 + ptri2s_config->end_cnt = (ptri2s_config->tx_w_idx + MAX_I2S_PAGE)-ptri2s_config->tx_r_idx;
3920 + _printk("case1: w=%d, r=%d, end=%d\n", ptri2s_config->tx_w_idx, ptri2s_config->tx_r_idx, ptri2s_config->end_cnt);
3921 + }
3922 + else if (ptri2s_config->tx_w_idx > ptri2s_config->tx_r_idx)
3923 + {
3924 + ptri2s_config->end_cnt = ptri2s_config->tx_w_idx-ptri2s_config->tx_r_idx;
3925 + _printk("case2: w=%d, r=%d, end=%d\n", ptri2s_config->tx_w_idx, ptri2s_config->tx_r_idx, ptri2s_config->end_cnt);
3926 + }
3927 + else
3928 + {
3929 + _printk("case3: w=%d, r=%d, end=%d\n", ptri2s_config->tx_w_idx, ptri2s_config->tx_r_idx, ptri2s_config->end_cnt);
3930 +
3931 + }
3932 +
3933 + if (ptri2s_config->end_cnt > 0)
3934 + {
3935 + interruptible_sleep_on(&(ptri2s_config->i2s_tx_qh));
3936 + }
3937 +
3938 + return;
3939 +}
3940 +
3941 +void i2s_tx_end_sleep_on(i2s_config_type* ptri2s_config)
3942 +{
3943 + while(ptri2s_config->tx_stop_cnt<3)
3944 + interruptible_sleep_on(&(ptri2s_config->i2s_tx_qh));
3945 +
3946 + return;
3947 +}
3948 +
3949 +void i2s_rx_end_sleep_on(i2s_config_type* ptri2s_config)
3950 +{
3951 + while(ptri2s_config->rx_stop_cnt<2)
3952 + interruptible_sleep_on(&(ptri2s_config->i2s_rx_qh));
3953 + return;
3954 +}
3955 +
3956 +int i2s_dma_tx_soft_stop(i2s_config_type* ptri2s_config, u32 dma_ch)
3957 +{
3958 + if(dma_ch==GDMA_I2S_TX0)
3959 + {
3960 +#if defined(ARM_ARCH)
3961 + GdmaI2sTx(i2s_txdma_addr0, I2S_TX_FIFO_WREG_PHY, 0, 4, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3962 +#else
3963 + GdmaI2sTx((u32)pi2s_config->pPage0TxBuf8ptr, I2S_TX_FIFO_WREG, 0, 4, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3964 +#endif
3965 + }
3966 + else
3967 + {
3968 +#if defined(ARM_ARCH)
3969 + GdmaI2sTx(i2s_txdma_addr1, I2S_TX_FIFO_WREG_PHY, 1, 4, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3970 +#else
3971 + GdmaI2sTx((u32)pi2s_config->pPage1TxBuf8ptr, I2S_TX_FIFO_WREG, 1, 4, i2s_dma_tx_handler, i2s_dma_tx_unmask_handler);
3972 +#endif
3973 + }
3974 +
3975 + return 0;
3976 +}
3977 +
3978 +int i2s_dma_rx_soft_stop(i2s_config_type* ptri2s_config, u32 dma_ch)
3979 +{
3980 + if(dma_ch==GDMA_I2S_RX0)
3981 + {
3982 + memset(pi2s_config->pPage0RxBuf8ptr, 0, I2S_PAGE_SIZE);
3983 +#if defined(ARM_ARCH)
3984 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr0, 0, 4, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3985 +#else
3986 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)pi2s_config->pPage0RxBuf8ptr, 0, 4, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3987 +#endif
3988 + }
3989 + else
3990 + {
3991 + memset(pi2s_config->pPage1RxBuf8ptr, 0, I2S_PAGE_SIZE);
3992 +#if defined(ARM_ARCH)
3993 + GdmaI2sRx(I2S_RX_FIFO_RREG_PHY, i2s_rxdma_addr1, 1, 4, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3994 +#else
3995 + GdmaI2sRx(I2S_RX_FIFO_RREG, (u32)pi2s_config->pPage1RxBuf8ptr, 1, 4, i2s_dma_rx_handler, i2s_dma_rx_unmask_handler);
3996 +#endif
3997 + }
3998 +
3999 + return 0;
4000 +}
4001 +
4002 +void i2s_gen_test_pattern(void)
4003 +{
4004 + int i;
4005 + for (i=0; i<I2S_PAGE_SIZE; i++)
4006 + {
4007 + test_buf[i] = 0x5A;
4008 + test_buf_1[i] = 0x11;
4009 + test_buf_2[i] = 0x22;
4010 +
4011 + }
4012 +}
4013 +
4014 +int i2s_put_audio(i2s_config_type* ptri2s_config, unsigned long arg)
4015 +{
4016 + unsigned long flags;
4017 + int tx_w_idx;
4018 +
4019 + do{
4020 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4021 +
4022 + if(((ptri2s_config->tx_w_idx+4)%MAX_I2S_PAGE)!=ptri2s_config->tx_r_idx)
4023 + {
4024 + ptri2s_config->tx_w_idx = (ptri2s_config->tx_w_idx+1)%MAX_I2S_PAGE;
4025 + tx_w_idx = ptri2s_config->tx_w_idx;
4026 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4027 + //_printk("put TB[%d] for user write\n",ptri2s_config->tx_w_idx);
4028 +#if defined(CONFIG_I2S_MMAP)
4029 + put_user(tx_w_idx, (int*)arg);
4030 +#else
4031 + copy_from_user(ptri2s_config->pMMAPTxBufPtr[tx_w_idx], (char*)arg, I2S_PAGE_SIZE);
4032 +#endif
4033 + pi2s_status->txbuffer_len++;
4034 + //spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4035 + break;
4036 + }
4037 + else
4038 + {
4039 + /* Buffer Full */
4040 + //_printk("TBF tr=%d, tw=%d\n", ptri2s_config->tx_r_idx, ptri2s_config->tx_w_idx);
4041 + pi2s_status->txbuffer_ovrun++;
4042 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4043 + interruptible_sleep_on(&(ptri2s_config->i2s_tx_qh));
4044 + if (ptri2s_config->bTxDMAEnable==0 && ptri2s_config->end_cnt==0)
4045 + {
4046 + _printk("wake up for exit i2s driver\n");
4047 + put_user(-1, (int*)arg);
4048 + break;
4049 + }
4050 + }
4051 + }while(1);
4052 +
4053 + return 0;
4054 +}
4055 +
4056 +int i2s_get_audio(i2s_config_type* ptri2s_config, unsigned long arg)
4057 +{
4058 + unsigned long flags;
4059 + int rx_r_idx;
4060 +
4061 + do{
4062 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4063 + //_printk("GA rr=%d, rw=%d,i=%d\n", ptri2s_config->rx_r_idx, ptri2s_config->rx_w_idx,ptri2s_config->rx_isr_cnt);
4064 + if(((ptri2s_config->rx_r_idx+2)%MAX_I2S_PAGE)!=ptri2s_config->rx_w_idx)
4065 + {
4066 + rx_r_idx = ptri2s_config->rx_r_idx;
4067 + ptri2s_config->rx_r_idx = (ptri2s_config->rx_r_idx+1)%MAX_I2S_PAGE;
4068 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4069 +#if defined(CONFIG_I2S_MMAP)
4070 + put_user(rx_r_idx, (int*)arg);
4071 +#else
4072 + copy_to_user((char*)arg, ptri2s_config->pMMAPRxBufPtr[rx_r_idx], I2S_PAGE_SIZE);
4073 +#endif
4074 + //_printk("rx_r_idx=%d\n", ptri2s_config->rx_r_idx);
4075 + //ptri2s_config->rx_r_idx = (ptri2s_config->rx_r_idx+1)%MAX_I2S_PAGE;
4076 + pi2s_status->rxbuffer_len--;
4077 + //spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4078 + break;
4079 + }
4080 + else
4081 + {
4082 + /* Buffer Full */
4083 + //_printk("RBF rr=%d, rw=%d\n", ptri2s_config->rx_r_idx, ptri2s_config->rx_w_idx);
4084 + pi2s_status->rxbuffer_ovrun++;
4085 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4086 + interruptible_sleep_on(&(ptri2s_config->i2s_rx_qh));
4087 + }
4088 +#if defined(CONFIG_I2S_WITH_AEC)
4089 + if(aecFuncP->AECECDeq){
4090 + aecFuncP->AECECDeq(0,pi2s_config->pMMAPRxBufPtr[ptri2s_config->rx_r_idx],I2S_PAGE_SIZE);
4091 + }
4092 +#endif
4093 + }while(1);
4094 +
4095 + return 0;
4096 +}
4097 +
4098 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
4099 +long i2s_ioctl (struct file *filp, unsigned int cmd, unsigned long arg)
4100 +#else
4101 +int i2s_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
4102 +#endif
4103 +{
4104 + int i ;
4105 + i2s_config_type* ptri2s_config;
4106 + unsigned long flags;
4107 +
4108 + ptri2s_config = filp->private_data;
4109 + switch (cmd) {
4110 + case I2S_RESET:
4111 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4112 + i2s_reset_config(ptri2s_config);
4113 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4114 + break;
4115 + case I2S_SRATE:
4116 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4117 +#if defined(CONFIG_I2S_WM8960)
4118 + if((arg>MAX_SRATE_HZ)||(arg<MIN_SRATE_HZ))
4119 + {
4120 + MSG("Audio sampling rate %u should be %d ~ %d Hz. Set SRate to 48000Hz\n", (u32)arg, MIN_SRATE_HZ, MAX_SRATE_HZ);
4121 + ptri2s_config->srate = 48000;
4122 + spin_unlock(&ptri2s_config->lock);
4123 + break;
4124 + }
4125 +#elif defined(CONFIG_I2S_WM8750)
4126 + if((arg>MAX_SRATE_HZ)||(arg<MIN_SRATE_HZ))
4127 + {
4128 + MSG("Audio sampling rate %u should be %d ~ %d Hz. Set SRate to 96000Hz\n", (u32)arg, MIN_SRATE_HZ, MAX_SRATE_HZ);
4129 + ptri2s_config->srate = 96000;
4130 + spin_unlock(&ptri2s_config->lock);
4131 + break;
4132 + }
4133 +#endif
4134 + ptri2s_config->srate = arg;
4135 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4136 + MSG("set audio sampling rate to %d Hz\n", ptri2s_config->srate);
4137 + break;
4138 + case I2S_TX_VOL:
4139 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4140 +
4141 + if((int)arg > 127)
4142 + ptri2s_config->txvol = 127;
4143 + else if((int)arg < 48)
4144 + ptri2s_config->txvol = 48;
4145 + else
4146 + ptri2s_config->txvol = arg;
4147 +
4148 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4149 +
4150 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4151 +#if (defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751))
4152 + audiohw_set_master_vol(arg,arg);
4153 +#elif defined(CONFIG_I2S_WM8960)
4154 + audiohw_set_lineout_vol(1, ptri2s_config->txvol, ptri2s_config->txvol);
4155 +#endif
4156 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4157 + break;
4158 + case I2S_RX_VOL:
4159 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4160 +
4161 + if((int)arg > 63)
4162 + ptri2s_config->rxvol = 63;
4163 + else if((int)arg < 0)
4164 + ptri2s_config->rxvol = 0;
4165 + else
4166 + ptri2s_config->rxvol = arg;
4167 +
4168 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4169 + break;
4170 +#if defined (CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4171 + case I2S_WORD_LEN:
4172 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4173 + if((int)arg == 16)
4174 + {
4175 + ptri2s_config->wordlen_24b = 0;
4176 + MSG("Enable 16 bit word length.\n");
4177 + }
4178 + else if ((int)arg == 24)
4179 + {
4180 + ptri2s_config->wordlen_24b = 1;
4181 + MSG("Enable 24 bit word length.\n");
4182 + }
4183 + else
4184 + {
4185 + MSG("MT7628 only support 16bit/24bit word length.\n");
4186 + spin_unlock(&ptri2s_config->lock);
4187 + break;
4188 + }
4189 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4190 + break;
4191 + case I2S_ENDIAN_FMT:
4192 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4193 + if((int)arg == 1)
4194 + {
4195 + ptri2s_config->little_edn = 1;
4196 + MSG("Little endian format.\n");
4197 + }
4198 + else
4199 + {
4200 + ptri2s_config->little_edn = 0;
4201 + MSG("Big endian format.\n");
4202 + }
4203 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4204 + break;
4205 +#endif
4206 + case I2S_INTERNAL_LBK:
4207 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4208 + if((int)arg == 1)
4209 + {
4210 + ptri2s_config->lbk = 1;
4211 + MSG("Enable internal loopback.\n");
4212 + }
4213 + else
4214 + {
4215 + ptri2s_config->lbk = 0;
4216 + MSG("Disable internal loopback.\n");
4217 + }
4218 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4219 + break;
4220 + case I2S_EXTERNAL_LBK:
4221 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4222 + if((int)arg == 1)
4223 + {
4224 + ptri2s_config->extlbk = 1;
4225 + MSG("Enable external loopback.\n");
4226 + }
4227 + else
4228 + {
4229 + ptri2s_config->extlbk = 0;
4230 + MSG("Disable external loopback.\n");
4231 + }
4232 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4233 + break;
4234 + case I2S_TXRX_COEXIST:
4235 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4236 + if((int)arg == 1)
4237 + {
4238 + ptri2s_config->txrx_coexist = 1;
4239 + MSG("TX/RX coexist.\n");
4240 + }
4241 + else
4242 + {
4243 + ptri2s_config->txrx_coexist = 0;
4244 + MSG("TX/RX coexist.\n");
4245 + }
4246 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4247 + break;
4248 +
4249 + case I2S_TX_ENABLE:
4250 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4251 + MSG("I2S_TXENABLE\n");
4252 +
4253 + pi2s_config->tx_unmask_ch = 0;
4254 + tasklet_init(&i2s_tx_tasklet, i2s_tx_task, (u32)pi2s_config);
4255 +
4256 + pi2s_config->dis_match = 0;
4257 + pi2s_config->start_cnt = 0;
4258 + i2s_gen_test_pattern();
4259 +
4260 + /* allocate tx buffer */
4261 + i2s_txPagebuf_alloc(ptri2s_config);
4262 + i2s_txbuf_alloc(ptri2s_config);
4263 +
4264 + /* Init two dma channels */
4265 + i2s_dma_tx_init(ptri2s_config);
4266 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4267 +
4268 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4269 + /* Init & config all tx param */
4270 + i2s_reset_tx_param(ptri2s_config);
4271 + ptri2s_config->bTxDMAEnable = 1;
4272 + /* Clear all ALSA related config */
4273 + ptri2s_config->bALSAEnable = 0;
4274 + ptri2s_config->bALSAMMAPEnable = 0;
4275 +
4276 + i2s_tx_config(ptri2s_config);
4277 +
4278 + if(ptri2s_config->bRxDMAEnable==0)
4279 + i2s_clock_enable(ptri2s_config);
4280 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4281 +
4282 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4283 +#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
4284 + audiohw_set_lineout_vol(1, ptri2s_config->txvol, ptri2s_config->txvol);
4285 +#endif
4286 + GdmaUnMaskChannel(GDMA_I2S_TX0);
4287 +
4288 + i2s_tx_enable(ptri2s_config);
4289 +
4290 + /* Kick off dma channel */
4291 + //GdmaUnMaskChannel(GDMA_I2S_TX0);
4292 +
4293 + MSG("I2S_TXENABLE done\n");
4294 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4295 + break;
4296 + case I2S_TX_DISABLE:
4297 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4298 + MSG("I2S_TXDISABLE\n");
4299 +
4300 + //tasklet_kill(&i2s_tx_tasklet);
4301 +
4302 + /* Handle tx end data */
4303 + ptri2s_config->bTxDMAEnable = 0;
4304 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4305 +
4306 + i2s_tx_end_sleep_on(ptri2s_config);
4307 +
4308 + tasklet_kill(&i2s_tx_tasklet);
4309 +
4310 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4311 + i2s_reset_tx_param(ptri2s_config);
4312 + i2s_tx_disable(ptri2s_config);
4313 + if((ptri2s_config->bRxDMAEnable==0)&&(ptri2s_config->bTxDMAEnable==0))
4314 + i2s_clock_disable(ptri2s_config);
4315 +
4316 + i2s_txbuf_free(ptri2s_config);
4317 + if(ptri2s_config->mmap_index <= MAX_I2S_PAGE)
4318 + ptri2s_config->mmap_index = 0;
4319 +
4320 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4321 + break;
4322 + case I2S_RX_ENABLE:
4323 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4324 + MSG("I2S_RXENABLE\n");
4325 + pi2s_config->rx_unmask_ch = 0;
4326 + tasklet_init(&i2s_rx_tasklet, i2s_rx_task, (u32)pi2s_config);
4327 +
4328 + /* allocate rx buffer */
4329 + i2s_rxPagebuf_alloc(ptri2s_config);
4330 + i2s_rxbuf_alloc(ptri2s_config);
4331 +
4332 + /* Init two dma channels */
4333 + i2s_dma_rx_init(ptri2s_config);
4334 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4335 +
4336 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4337 + /* Init & config all rx param */
4338 + i2s_reset_rx_param(ptri2s_config);
4339 + ptri2s_config->bRxDMAEnable = 1;
4340 + ptri2s_config->bALSAEnable = 0;
4341 + ptri2s_config->bALSAMMAPEnable = 0;
4342 +
4343 + i2s_rx_config(ptri2s_config);
4344 +
4345 + if(ptri2s_config->bTxDMAEnable==0)
4346 + i2s_clock_enable(ptri2s_config);
4347 +
4348 +#if defined(CONFIG_I2S_TXRX)
4349 +#if defined(CONFIG_I2S_WM8960)||defined(CONFIG_I2S_WM8750)||defined(CONFIG_I2S_WM8751)
4350 + audiohw_set_linein_vol(ptri2s_config->rxvol, ptri2s_config->rxvol);
4351 +#endif
4352 +#endif
4353 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4354 +
4355 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4356 + /* Kick off dma channel */
4357 + GdmaUnMaskChannel(GDMA_I2S_RX0);
4358 +
4359 + i2s_rx_enable(ptri2s_config);
4360 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4361 + break;
4362 + case I2S_RX_DISABLE:
4363 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4364 + MSG("I2S_RXDISABLE\n");
4365 + //tasklet_kill(&i2s_rx_tasklet);
4366 +
4367 + ptri2s_config->bRxDMAEnable = 0;
4368 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4369 +
4370 + i2s_rx_end_sleep_on(ptri2s_config);
4371 + tasklet_kill(&i2s_rx_tasklet);
4372 +
4373 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4374 + i2s_reset_rx_param(ptri2s_config);
4375 + i2s_rx_disable(ptri2s_config);
4376 + if((ptri2s_config->bRxDMAEnable==0)&&(ptri2s_config->bTxDMAEnable==0))
4377 + i2s_clock_disable(ptri2s_config);
4378 +
4379 + i2s_rxbuf_free(ptri2s_config);
4380 + if(ptri2s_config->mmap_index <= MAX_I2S_PAGE)
4381 + ptri2s_config->mmap_index = 0;
4382 + //i2s_rxPagebuf_free(ptri2s_config);
4383 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4384 + break;
4385 + case I2S_PUT_AUDIO:
4386 + i2s_put_audio(ptri2s_config, arg);
4387 + break;
4388 + case I2S_GET_AUDIO:
4389 + i2s_get_audio(ptri2s_config, arg);
4390 + break;
4391 + case I2S_TX_STOP:
4392 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4393 + MSG("TxGDMA STOP\n");
4394 + ptri2s_config->bTxDMAEnable = 0;
4395 + ptri2s_config->end_cnt = 0;
4396 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4397 +
4398 + while(ptri2s_config->tx_stop_cnt<3)
4399 + interruptible_sleep_on(&(ptri2s_config->i2s_tx_qh));
4400 +
4401 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4402 + i2s_reset_tx_param(ptri2s_config);
4403 + i2s_tx_disable(ptri2s_config);
4404 + if((ptri2s_config->bRxDMAEnable==0)&&(ptri2s_config->bTxDMAEnable==0))
4405 + i2s_clock_disable(ptri2s_config);
4406 +
4407 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4408 +
4409 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4410 + i2s_txbuf_free(ptri2s_config);
4411 + if(ptri2s_config->mmap_index <= MAX_I2S_PAGE)
4412 + ptri2s_config->mmap_index = 0;
4413 + //i2s_txPagebuf_free(ptri2s_config);
4414 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4415 + break;
4416 + case I2S_TX_PAUSE:
4417 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4418 + ptri2s_config->tx_pause_en = 1;
4419 + MSG("* tx_pause_en = 1 *\n");
4420 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4421 + break;
4422 + case I2S_TX_RESUME:
4423 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4424 + ptri2s_config->tx_pause_en = 0;
4425 + MSG("# tx_pause_en = 0 #\n");
4426 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4427 + break;
4428 + case I2S_RX_STOP:
4429 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4430 + MSG("I2S_RX_STOP\n");
4431 + ptri2s_config->bRxDMAEnable = 0;
4432 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4433 +
4434 + while(ptri2s_config->rx_stop_cnt<2)
4435 + interruptible_sleep_on(&(ptri2s_config->i2s_rx_qh));
4436 +
4437 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4438 + i2s_reset_rx_param(ptri2s_config);
4439 + i2s_rx_disable(ptri2s_config);
4440 + if((ptri2s_config->bRxDMAEnable==0)&&(ptri2s_config->bTxDMAEnable==0))
4441 + i2s_clock_disable(ptri2s_config);
4442 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4443 +
4444 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4445 + i2s_rxbuf_free(ptri2s_config);
4446 + if(ptri2s_config->mmap_index <= MAX_I2S_PAGE)
4447 + ptri2s_config->mmap_index = 0;
4448 + //i2s_rxPagebuf_free(ptri2s_config);
4449 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4450 + break;
4451 + case I2S_RX_PAUSE:
4452 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4453 + ptri2s_config->rx_pause_en = 1;
4454 + MSG("* rx_pause_en = 1 *\n");
4455 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4456 + break;
4457 + case I2S_RX_RESUME:
4458 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4459 + ptri2s_config->rx_pause_en = 0;
4460 + MSG("# rx_pause_en = 0 #\n");
4461 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4462 + break;
4463 + case I2S_CODEC_MIC_BOOST:
4464 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4465 + if((int)arg > 3)
4466 + ptri2s_config->micboost = 3;
4467 + else if((int)arg < 0)
4468 + ptri2s_config->micboost = 0;
4469 + else
4470 + ptri2s_config->micboost = arg;
4471 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4472 + break;
4473 + case I2S_CODEC_MIC_IN:
4474 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4475 + if((int)arg == 1)
4476 + ptri2s_config->micin = 1;
4477 + else
4478 + ptri2s_config->micin = 0;
4479 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4480 + break;
4481 + case I2S_CLOCK_ENABLE:
4482 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4483 + i2s_clock_disable(ptri2s_config);
4484 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4485 + ptri2s_config->wordlen_24b = 1;
4486 +#endif
4487 + i2s_tx_config(ptri2s_config);
4488 + i2s_clock_enable(ptri2s_config);
4489 + i2s_tx_enable(ptri2s_config);
4490 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4491 + break;
4492 + case I2S_DEBUG_CODEC:
4493 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4494 + for (i=0; i<10; i++)
4495 + {
4496 + _printk("### i=%d ###\n", i);
4497 + i2s_clock_enable(ptri2s_config);
4498 + i2s_clock_disable(ptri2s_config);
4499 + }
4500 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4501 + break;
4502 +#if defined(CONFIG_I2S_MS_CTRL)
4503 + case I2S_MS_MODE_CTRL:
4504 + spin_lock_irqsave(&ptri2s_config->lock, flags);
4505 + if((int)arg == 1)
4506 + {
4507 + ptri2s_config->slave_en = 1;
4508 + _printk("I2S in slave mode.\n");
4509 + }
4510 + else
4511 + {
4512 + ptri2s_config->slave_en = 0;
4513 + _printk("I2S in master mode.\n");
4514 + }
4515 + spin_unlock_irqrestore(&ptri2s_config->lock, flags);
4516 + break;
4517 +#endif
4518 + case I2S_DEBUG_CLKGEN:
4519 + case I2S_DEBUG_INLBK:
4520 + case I2S_DEBUG_EXLBK:
4521 + case I2S_DEBUG_CODECBYPASS:
4522 + case I2S_DEBUG_FMT:
4523 +#if defined(CONFIG_I2S_WM8960)
4524 + case I2S_DEBUG_CODEC_EXLBK:
4525 +#endif
4526 + case I2S_DEBUG_RESET:
4527 + i2s_debug_cmd(cmd, arg);
4528 + break;
4529 + default :
4530 + MSG("i2s_ioctl: command format error\n");
4531 + }
4532 +
4533 + return 0;
4534 +}
4535 +
4536 +/************************
4537 + * API for ALSA *
4538 + * *
4539 + ************************/
4540 +char* i2s_memPool_Alloc(i2s_config_type* ptri2s_config,int dir)
4541 +{
4542 + //_printk("%s\n",__func__);
4543 + if(!ptri2s_config)
4544 + return NULL;
4545 + if(dir == STREAM_PLAYBACK){
4546 +#if defined(CONFIG_I2S_MMAP)
4547 + i2s_mmap_alloc(I2S_TOTAL_PAGE_SIZE);
4548 +#endif
4549 + i2s_txbuf_alloc(ptri2s_config);
4550 + return ptri2s_config->pMMAPTxBufPtr[0];
4551 + }else{
4552 +#if defined(CONFIG_I2S_MMAP)
4553 + i2s_mmap_alloc(I2S_TOTAL_PAGE_SIZE);
4554 +#endif
4555 + i2s_rxbuf_alloc(ptri2s_config);
4556 + return ptri2s_config->pMMAPRxBufPtr[0];
4557 + }
4558 + return NULL;
4559 +}
4560 +
4561 +void i2s_memPool_free(i2s_config_type* ptri2s_config,int dir)
4562 +{
4563 + if(!ptri2s_config)
4564 + return;
4565 + if(dir == STREAM_PLAYBACK){
4566 +#if defined(CONFIG_I2S_MMAP)
4567 + i2s_mem_unmap(ptri2s_config);
4568 +#endif
4569 + i2s_txbuf_free(ptri2s_config);
4570 + }else{
4571 +#if defined(CONFIG_I2S_MMAP)
4572 + i2s_mem_unmap(ptri2s_config);
4573 +#endif
4574 + i2s_rxbuf_free(ptri2s_config);
4575 + }
4576 +
4577 + return;
4578 +}
4579 +
4580 +int i2s_page_prepare(i2s_config_type* ptri2s_config,int dir)
4581 +{
4582 + if(dir == STREAM_PLAYBACK){
4583 + /* allocate tx buffer */
4584 + i2s_txPagebuf_alloc(ptri2s_config);
4585 + i2s_dma_tx_init(ptri2s_config);
4586 + }else{
4587 + /* allocate rx buffer */
4588 + i2s_rxPagebuf_alloc(ptri2s_config);
4589 + i2s_dma_rx_init(ptri2s_config);
4590 + }
4591 + return 0;
4592 +}
4593 +
4594 +int i2s_page_release(i2s_config_type* ptri2s_config,int dir)
4595 +{
4596 + if(!ptri2s_config)
4597 + return (-1);
4598 + if(dir == STREAM_PLAYBACK)
4599 + i2s_txPagebuf_free(ptri2s_config);
4600 + else
4601 + i2s_rxPagebuf_free(ptri2s_config);
4602 +
4603 + return 0;
4604 +}
4605 +
4606 +int i2s_startup(void)
4607 +{
4608 + memset(pi2s_config, 0, sizeof(i2s_config_type));
4609 +
4610 +#ifdef I2S_STATISTIC
4611 + memset(pi2s_status, 0, sizeof(i2s_status_type));
4612 +#endif
4613 +
4614 + i2s_param_init(pi2s_config);
4615 + pi2s_config->bALSAEnable = 1;
4616 +#if defined(CONFIG_I2S_MMAP)
4617 + pi2s_config->bALSAMMAPEnable = 1;
4618 +#endif
4619 +
4620 +#if defined (CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4621 + pi2s_config->little_edn = 1;
4622 +#endif
4623 +
4624 + init_waitqueue_head(&(pi2s_config->i2s_tx_qh));
4625 + init_waitqueue_head(&(pi2s_config->i2s_rx_qh));
4626 + spin_lock_init(&pi2s_config->lock);
4627 +
4628 + return 0;
4629 +}
4630 +
4631 +int gdma_En_Switch(i2s_config_type* ptri2s_config,int dir,int enabled){
4632 + if(!ptri2s_config)
4633 + return (-1);
4634 + if(dir == STREAM_PLAYBACK){
4635 + ptri2s_config->bTxDMAEnable = enabled;
4636 + //MSG("%s:%d\n",__func__,ptri2s_config->bTxDMAEnable);
4637 + }else{
4638 + ptri2s_config->bRxDMAEnable = enabled;
4639 + }
4640 + return 0;
4641 +}
4642 +
4643 +int i2s_audio_exchange(i2s_config_type* ptri2s_config,int dir,unsigned long arg)
4644 +{
4645 + //MSG("I2S_PUT_AUDIO\n");
4646 + if(!ptri2s_config)
4647 + return (-1);
4648 + if(dir == STREAM_PLAYBACK){
4649 + i2s_put_audio(ptri2s_config, arg);
4650 + }else{
4651 + i2s_get_audio(ptri2s_config, arg);
4652 + }
4653 + return 0;
4654 +}
4655 +
4656 +void gdma_mask_handler(u32 dma_ch)
4657 +{
4658 + i2s_dma_mask_handler(dma_ch);
4659 + return;
4660 +}
4661 +
4662 +void gdma_unmask_handler(u32 dma_ch)
4663 +{
4664 + i2s_dma_unmask_handler(dma_ch);
4665 + return;
4666 +}
4667 +
4668 +u32 i2s_mmap_phys_addr(i2s_config_type* ptri2s_config)
4669 +{
4670 + if((ptri2s_config->pMMAPBufPtr[0]!=NULL) && (ptri2s_config->mmap_index == MAX_I2S_PAGE))
4671 + return (dma_addr_t)i2s_mmap_addr[0];
4672 + else if((ptri2s_config->pMMAPBufPtr[MAX_I2S_PAGE]!=NULL) && (ptri2s_config->mmap_index == MAX_I2S_PAGE*2))
4673 + return (dma_addr_t)i2s_mmap_addr[MAX_I2S_PAGE];
4674 + else
4675 + return -1;
4676 +}
4677 +
4678 +EXPORT_SYMBOL(i2s_startup);
4679 +EXPORT_SYMBOL(i2s_mem_unmap);
4680 +EXPORT_SYMBOL(i2s_mmap_alloc);
4681 +EXPORT_SYMBOL(i2s_mmap_remap);
4682 +EXPORT_SYMBOL(i2s_param_init);
4683 +EXPORT_SYMBOL(i2s_txbuf_alloc);
4684 +EXPORT_SYMBOL(i2s_rxbuf_alloc);
4685 +EXPORT_SYMBOL(i2s_txPagebuf_alloc);
4686 +EXPORT_SYMBOL(i2s_rxPagebuf_alloc);
4687 +EXPORT_SYMBOL(i2s_txbuf_free);
4688 +EXPORT_SYMBOL(i2s_rxbuf_free);
4689 +EXPORT_SYMBOL(i2s_txPagebuf_free);
4690 +EXPORT_SYMBOL(i2s_rxPagebuf_free);
4691 +EXPORT_SYMBOL(i2s_rx_disable);
4692 +EXPORT_SYMBOL(i2s_tx_disable);
4693 +EXPORT_SYMBOL(i2s_rx_enable);
4694 +EXPORT_SYMBOL(i2s_tx_enable);
4695 +EXPORT_SYMBOL(i2s_rx_config);
4696 +EXPORT_SYMBOL(i2s_tx_config);
4697 +EXPORT_SYMBOL(i2s_reset_config);
4698 +EXPORT_SYMBOL(i2s_clock_disable);
4699 +EXPORT_SYMBOL(i2s_clock_enable);
4700 +EXPORT_SYMBOL(i2s_reset_rx_param);
4701 +EXPORT_SYMBOL(i2s_reset_tx_param);
4702 +EXPORT_SYMBOL(i2s_dma_rx_handler);
4703 +EXPORT_SYMBOL(i2s_dma_tx_handler);
4704 +EXPORT_SYMBOL(i2s_dma_unmask_handler);
4705 +EXPORT_SYMBOL(i2s_dma_tx_unmask_handler);
4706 +EXPORT_SYMBOL(i2s_dma_rx_unmask_handler);
4707 +EXPORT_SYMBOL(i2s_dma_mask_handler);
4708 +EXPORT_SYMBOL(i2s_dma_tx_init);
4709 +EXPORT_SYMBOL(i2s_dma_rx_init);
4710 +EXPORT_SYMBOL(i2s_tx_end_sleep_on);
4711 +EXPORT_SYMBOL(i2s_rx_end_sleep_on);
4712 +EXPORT_SYMBOL(i2s_mmap_phys_addr);
4713 +EXPORT_SYMBOL(i2s_open);
4714 +EXPORT_SYMBOL(pi2s_config);
4715 +#if defined(CONFIG_I2S_IN_MCLK)
4716 +#if defined(CONFIG_I2S_MCLK_12MHZ)
4717 +EXPORT_SYMBOL(i2s_refclk_12m_enable);
4718 +#endif
4719 +#if defined(CONFIG_I2S_MCLK_12P288MHZ)
4720 +EXPORT_SYMBOL(i2s_refclk_12p288m_enable);
4721 +#endif
4722 +#endif
4723 +#if defined(MT7628_ASIC_BOARD) || defined(CONFIG_ARCH_MT7623)
4724 +EXPORT_SYMBOL(i2s_driving_strength_adjust);
4725 +#endif
4726 +EXPORT_SYMBOL(i2s_refclk_disable);
4727 +EXPORT_SYMBOL(i2s_refclk_gpio_out_config);
4728 +EXPORT_SYMBOL(i2s_refclk_gpio_in_config);
4729 +EXPORT_SYMBOL(i2s_share_pin_config);
4730 +EXPORT_SYMBOL(i2s_share_pin_mt7623);
4731 +EXPORT_SYMBOL(i2s_ws_config);
4732 +EXPORT_SYMBOL(i2s_mode_config);
4733 +EXPORT_SYMBOL(i2s_codec_frequency_config);
4734 +EXPORT_SYMBOL(i2s_dma_tx_transf_data);
4735 +EXPORT_SYMBOL(i2s_dma_tx_transf_zero);
4736 +EXPORT_SYMBOL(i2s_dma_rx_transf_data);
4737 +EXPORT_SYMBOL(i2s_dma_rx_transf_zero);
4738 +EXPORT_SYMBOL(i2s_dma_tx_end_handle);
4739 +EXPORT_SYMBOL(i2s_dma_tx_soft_stop);
4740 +EXPORT_SYMBOL(i2s_dma_rx_soft_stop);
4741 +EXPORT_SYMBOL(i2s_tx_task);
4742 +EXPORT_SYMBOL(i2s_rx_task);
4743 +
4744 +EXPORT_SYMBOL(i2s_memPool_Alloc);
4745 +EXPORT_SYMBOL(i2s_memPool_free);
4746 +EXPORT_SYMBOL(i2s_page_prepare);
4747 +EXPORT_SYMBOL(i2s_page_release);
4748 +EXPORT_SYMBOL(gdma_En_Switch);
4749 +EXPORT_SYMBOL(i2s_audio_exchange);
4750 +EXPORT_SYMBOL(gdma_mask_handler);
4751 +EXPORT_SYMBOL(gdma_unmask_handler);
4752 +#if defined(CONFIG_I2S_WITH_AEC)
4753 +EXPORT_SYMBOL(aecFuncP);
4754 +#endif
4755 +module_init(i2s_mod_init);
4756 +module_exit(i2s_mod_exit);
4757 +
4758 +MODULE_DESCRIPTION("Ralink SoC I2S Controller Module");
4759 +MODULE_AUTHOR("Qwert Chin <qwert.chin@ralinktech.com.tw>");
4760 +MODULE_SUPPORTED_DEVICE("I2S");
4761 +MODULE_VERSION(I2S_MOD_VERSION);
4762 +MODULE_LICENSE("GPL");
4763 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
4764 +MODULE_PARM (i2sdrv_major, "i");
4765 +#else
4766 +module_param (i2sdrv_major, int, 0);
4767 +#endif
4768 --- /dev/null
4769 +++ b/sound/soc/mtk/i2s_ctrl.h
4770 @@ -0,0 +1,523 @@
4771 +#ifndef __RALINK_I2S_H_
4772 +#define __RALINK_I2S_H_
4773 +
4774 +#ifdef __KERNEL__
4775 +//#include <asm/rt2880/rt_mmap.h>
4776 +#endif
4777 +
4778 +#if defined(CONFIG_I2S_WITH_AEC)
4779 +#include "aec/aec_api.h"
4780 +#endif
4781 +
4782 +#define I2S_MAX_DEV 1
4783 +#define I2S_MOD_VERSION "0.1"
4784 +#define phys_to_bus(a) (a & 0x1FFFFFFF)
4785 +
4786 +#ifndef u32
4787 +#define u32 unsigned int
4788 +#endif
4789 +
4790 +#ifndef u16
4791 +#define u16 unsigned short
4792 +#endif
4793 +
4794 +#ifndef u8
4795 +#define u8 unsigned char
4796 +#endif
4797 +
4798 +#ifndef REGBIT
4799 +#define REGBIT(x, n) (x << n)
4800 +#endif
4801 +
4802 +#define Virtual2Physical(x) (((int)x) & 0x1fffffff)
4803 +#define Physical2Virtual(x) (((int)x) | 0x80000000)
4804 +#define Virtual2NonCache(x) (((int)x) | 0x20000000)
4805 +#define Physical2NonCache(x) (((int)x) | 0xa0000000)
4806 +#define NonCache2Virtual(x) (((int)x) & 0xDFFFFFFF)
4807 +
4808 +#if defined(CONFIG_I2S_MCLK_12MHZ)
4809 +#define CONFIG_I2S_CODEC_PLL_EN 1
4810 +#else
4811 +#define CONFIG_I2S_CODEC_PLL_EN 0
4812 +#endif
4813 +
4814 +//#define CONFIG_I2S_MS_CTRL
4815 +//#define CONFIG_I2S_MS_MODE
4816 +//#define memory_test
4817 +
4818 +#if defined (CONFIG_ARCH_MT7623)
4819 +#define MT7623_ASIC_BOARD
4820 +#define ARM_ARCH
4821 +#endif
4822 +
4823 +#if defined (CONFIG_RALINK_MT7621)
4824 +#define MT7621_ASIC_BOARD
4825 +#endif
4826 +
4827 +#if defined (CONFIG_RALINK_MT7628)
4828 +#define MT7628_ASIC_BOARD
4829 +#endif
4830 +
4831 +//#define I2S_DEBUG_PRN
4832 +#ifdef I2S_DEBUG_PRN
4833 +#define MSG(fmt, args...) printk("I2S: " fmt, ## args)
4834 +#else
4835 +#define MSG(fmt, args...) { }
4836 +#endif
4837 +
4838 +#ifdef I2S_DEBUG_PRN
4839 +#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)
4840 +#else
4841 +#define i2s_outw(address, value) *((volatile uint32_t *)(address)) = cpu_to_le32(value)
4842 +#endif
4843 +#define i2s_inw(address) le32_to_cpu(*(volatile u32 *)(address))
4844 +
4845 +/* HW feature definiations */
4846 +#if defined(CONFIG_RALINK_RT3883)
4847 +#define CONFIG_I2S_TXRX 1
4848 +#define CONFIG_I2S_IN_MCLK 1
4849 +//#define CONFIG_I2S_WS_EDGE 1
4850 +#define CONFIG_I2S_FRAC_DIV 1
4851 +#define CONFIG_I2S_IN_CLK 1
4852 +#define CONFIG_I2S_MS_MODE 1
4853 +#endif
4854 +
4855 +#if defined(CONFIG_RALINK_RT3352)||defined(CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) \
4856 + || defined(CONFIG_RALINK_RT6855A) || defined(CONFIG_RALINK_MT7620) || defined(CONFIG_RALINK_MT7621) \
4857 + || defined (CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4858 +#define CONFIG_I2S_TXRX 1
4859 +//#define CONFIG_I2S_WS_EDGE 1
4860 +#define CONFIG_I2S_FRAC_DIV 1
4861 +#define CONFIG_I2S_IN_CLK 1
4862 +#endif
4863 +
4864 +#if defined(CONFIG_RALINK_RT3350)
4865 +#define CONFIG_I2S_IN_MCLK 1
4866 +#endif
4867 +
4868 +#if defined(CONFIG_RALINK_RT3052)
4869 +#define CONFIG_I2S_MS_MODE 1
4870 +#endif
4871 +
4872 +/* This is decided in menuconfig */
4873 +#define CONFIG_I2S_MMAP 1
4874 +
4875 +/* For MT7623 ASIC PLL Setting */
4876 +#if defined(CONFIG_ARCH_MT7623)
4877 +#define AUD1PLL_CON0 (0xF0209270)
4878 +#define AUD1PLL_CON1 (0xF0209274)
4879 +#define AUD1PLL_CON2 (0xF0209278)
4880 +#define AUD1PLL_PWR_CON0 (0xF020927C)
4881 +#define AUD2PLL_CON0 (0xF02092C0)
4882 +#define AUD2PLL_CON1 (0xF02092C4)
4883 +#define AUD2PLL_CON2 (0xF02092C8)
4884 +#define AUD2PLL_PWR_CON0 (0xF02092CC)
4885 +#endif
4886 +
4887 +/* Register Map, Ref to RT3052 Data Sheet */
4888 +
4889 +/* Register Map Detail */
4890 +#if defined(CONFIG_ARCH_MT7623)
4891 +#define I2S_I2SCFG (ETHDMASYS_I2S_BASE+0x0000)
4892 +#define I2S_INT_STATUS (ETHDMASYS_I2S_BASE+0x0004)
4893 +#define I2S_INT_EN (ETHDMASYS_I2S_BASE+0x0008)
4894 +#define I2S_FF_STATUS (ETHDMASYS_I2S_BASE+0x000c)
4895 +#define I2S_FIFO_WREG (ETHDMASYS_I2S_BASE+0x0010)
4896 +#define I2S_TX_FIFO_WREG I2S_FIFO_WREG
4897 +#define I2S_RX_FIFO_RREG (ETHDMASYS_I2S_BASE+0x0014)
4898 +#define I2S_I2SCFG1 (ETHDMASYS_I2S_BASE+0x0018)
4899 +#define I2S_DIVINT_CFG (ETHDMASYS_I2S_BASE+0x0024)
4900 +#define I2S_DIVCOMP_CFG (ETHDMASYS_I2S_BASE+0x0020)
4901 +#else
4902 +#define I2S_I2SCFG (RALINK_I2S_BASE+0x0000)
4903 +#define I2S_INT_STATUS (RALINK_I2S_BASE+0x0004)
4904 +#define I2S_INT_EN (RALINK_I2S_BASE+0x0008)
4905 +#define I2S_FF_STATUS (RALINK_I2S_BASE+0x000c)
4906 +#define I2S_FIFO_WREG (RALINK_I2S_BASE+0x0010)
4907 +#define I2S_TX_FIFO_WREG I2S_FIFO_WREG
4908 +#define I2S_RX_FIFO_RREG (RALINK_I2S_BASE+0x0014)
4909 +#define I2S_I2SCFG1 (RALINK_I2S_BASE+0x0018)
4910 +#define I2S_DIVINT_CFG (RALINK_I2S_BASE+0x0024)
4911 +#define I2S_DIVCOMP_CFG (RALINK_I2S_BASE+0x0020)
4912 +#endif
4913 +
4914 +
4915 +/* I2SCFG bit field */
4916 +#define I2S_EN 31
4917 +#define I2S_DMA_EN 30
4918 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4919 +#define I2S_LITTLE_ENDIAN 29
4920 +#define I2S_SYS_ENDIAN 28
4921 +#elif defined(CONFIG_RALINK_RT6855A)
4922 +#define I2S_BYTE_SWAP 28
4923 +#endif
4924 +#define I2S_TX_EN 24
4925 +#define I2S_RX_EN 20
4926 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4927 +#define I2S_NORM_24BIT 18
4928 +#define I2S_DATA_24BIT 17
4929 +#endif
4930 +#define I2S_SLAVE_MODE 16
4931 +#define I2S_RX_FF_THRES 12
4932 +#define I2S_RX_CH_SWAP 11
4933 +#define I2S_RX_CH1_OFF 10
4934 +#define I2S_RX_CH0_OFF 9
4935 +#if defined(CONFIG_RALINK_RT3052)
4936 +#define I2S_CLK_OUT_DIS 8
4937 +#endif
4938 +#define I2S_TX_FF_THRES 4
4939 +#define I2S_TX_CH_SWAP 3
4940 +#define I2S_TX_CH1_OFF 2
4941 +#define I2S_TX_CH0_OFF 1
4942 +#if defined(CONFIG_RALINK_RT3052)
4943 +#define I2S_SLAVE_EN 0
4944 +#else
4945 +#define I2S_WS_INV 0
4946 +#endif
4947 +/* INT_EN bit field */
4948 +#define I2S_RX_INT3_EN 7
4949 +#define I2S_RX_INT2_EN 6
4950 +#define I2S_RX_INT1_EN 5
4951 +#define I2S_RX_INT0_EN 4
4952 +#define I2S_TX_INT3_EN 3
4953 +#define I2S_TX_INT2_EN 2
4954 +#define I2S_TX_INT1_EN 1
4955 +#define I2S_TX_INT0_EN 0
4956 +
4957 +/* INT_STATUS bit field */
4958 +#define I2S_RX_DMA_FAULT 7
4959 +#define I2S_RX_OVRUN 6
4960 +#define I2S_RX_UNRUN 5
4961 +#define I2S_RX_THRES 4
4962 +#define I2S_TX_DMA_FAULT 3
4963 +#define I2S_TX_OVRUN 2
4964 +#define I2S_TX_UNRUN 1
4965 +#define I2S_TX_THRES 0
4966 +
4967 +/* FF_STATUS bit field */
4968 +#define I2S_RX_EPCNT 4
4969 +#define I2S_TX_EPCNT 0
4970 +/* I2S_DIVCOMP_CFG bit field */
4971 +#define I2S_CLKDIV_EN 31
4972 +
4973 +/* I2S_CFG1 bit field */
4974 +#define I2S_LBK_EN 31
4975 +#define I2S_EXT_LBK_EN 30
4976 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
4977 +#define I2S_DATA_FMT 0
4978 +#endif
4979 +
4980 +/* FIFO_WREG bit field */
4981 +#define I2S_FIFO_WDATA 0
4982 +
4983 +/* Constant definition */
4984 +#define NFF_THRES 4
4985 +#define I2S_PAGE_SIZE 3072//(3*4096)//(1152*2*2*2)
4986 +#define I2S_MIN_PAGE_SIZE 4096
4987 +#define MAX_I2S_PAGE 8
4988 +#define I2S_TOTAL_PAGE_SIZE (I2S_PAGE_SIZE*MAX_I2S_PAGE)
4989 +
4990 +#if defined(CONFIG_I2S_WM8960)
4991 +#define MAX_SRATE_HZ 48000
4992 +#define MIN_SRATE_HZ 8000
4993 +#elif defined(CONFIG_I2S_WM8750)
4994 +#define MAX_SRATE_HZ 96000
4995 +#define MIN_SRATE_HZ 8000
4996 +#endif
4997 +
4998 +#define MAX_VOL_DB +0
4999 +#define MIN_VOL_DB -127
5000 +
5001 +#define ALSA_MMAP_IDX_SHIFT 2
5002 +#if defined(CONFIG_SND_MT76XX_SOC)
5003 +#define STREAM_PLAYBACK SNDRV_PCM_STREAM_PLAYBACK
5004 +#define STREAM_CAPTURE SNDRV_PCM_STREAM_CAPTURE
5005 +#else
5006 +#define STREAM_PLAYBACK 0
5007 +#define STREAM_CAPTURE 1
5008 +#endif
5009 +
5010 +/* I2S I/O command */
5011 +#define I2S_SRATE 0
5012 +#define I2S_VOL 1
5013 +#define I2S_ENABLE 2
5014 +#define I2S_DISABLE 3
5015 +#define I2S_TX_ENABLE 27
5016 +#define I2S_TX_DISABLE 3
5017 +#define I2S_GET_WBUF 4
5018 +#define I2S_PUT_WBUF 5
5019 +#define I2S_RX_ENABLE 6
5020 +#define I2S_RX_DISABLE 7
5021 +#define I2S_PUT_AUDIO 4
5022 +#define I2S_GET_AUDIO 5
5023 +#define I2S_TX_VOL 1
5024 +#define I2S_RX_VOL 8
5025 +#define I2S_WORD_LEN 9
5026 +#define I2S_ENDIAN_FMT 10
5027 +#define I2S_INTERNAL_LBK 11
5028 +#define I2S_TX_STOP 12
5029 +#define I2S_DEBUG_CODEC 13
5030 +#define I2S_MS_MODE_CTRL 14
5031 +#define I2S_TX_PAUSE 15
5032 +#define I2S_TX_RESUME 16
5033 +#define I2S_RESET 17
5034 +#define I2S_RX_STOP 18
5035 +#define I2S_EXTERNAL_LBK 19
5036 +#define I2S_TXRX_COEXIST 20
5037 +#define I2S_RX_PAUSE 21
5038 +#define I2S_RX_RESUME 22
5039 +#define I2S_CODEC_MIC_BOOST 23
5040 +#define I2S_CODEC_MIC_IN 24
5041 +#define I2S_CLOCK_ENABLE 25
5042 +#define I2S_TEST_TEST 26
5043 +
5044 +#define I2S_DEBUG 30
5045 +#define I2S_DEBUG_CLKGEN 30
5046 +#define I2S_DEBUG_INLBK 31
5047 +#define I2S_DEBUG_EXLBK 32
5048 +#define I2S_DEBUG_FMT 33
5049 +#define I2S_DEBUG_RESET 34
5050 +#define I2S_DEBUG_CODECBYPASS 35
5051 +#if defined(CONFIG_I2S_WM8960)
5052 +#define I2S_DEBUG_CODEC_EXLBK 36
5053 +#endif
5054 +
5055 +/* configuration */
5056 +#define CONFIG_I2S_TFF_THRES NFF_THRES
5057 +#define CONFIG_I2S_CH_SWAP 0
5058 +#if defined(CONFIG_I2S_MS_MODE)
5059 +#define CONFIG_I2S_SLAVE_EN 0
5060 +#else
5061 +#define CONFIG_I2S_SLAVE_EN 1
5062 +#endif
5063 +
5064 +/* driver status definition */
5065 +#define I2S_OK 0
5066 +#define I2S_OUTOFMEM 0x01
5067 +#define I2S_GDMAFAILED 0x02
5068 +#define I2S_REQUEST_IRQ_FAILED 0x04
5069 +#define I2S_REG_SETUP_FAILED 0x08
5070 +
5071 +#define I2S_STATISTIC
5072 +//#define I2S_HW_INTERRUPT_EN
5073 +//#define I2S_SW_IRQ_EN
5074 +#define I2S_MAJOR 234
5075 +
5076 +/* parameter for ALSA */
5077 +/*GDMA for I2S Status*/
5078 +#define GDMA_I2S_DIS (0)
5079 +#define GDMA_I2S_EN (1)
5080 +
5081 +
5082 +typedef struct i2s_status_t
5083 +{
5084 + u32 txdmafault;
5085 + u32 txovrun;
5086 + u32 txunrun;
5087 + u32 txthres;
5088 + int txbuffer_unrun;
5089 + int txbuffer_ovrun;
5090 + int txbuffer_len;
5091 +
5092 + u32 rxdmafault;
5093 + u32 rxovrun;
5094 + u32 rxunrun;
5095 + u32 rxthres;
5096 + int rxbuffer_unrun;
5097 + int rxbuffer_ovrun;
5098 + int rxbuffer_len;
5099 +}i2s_status_type;
5100 +
5101 +
5102 +typedef struct i2s_config_t
5103 +{
5104 +
5105 + int srate;
5106 + int txvol;
5107 + int rxvol;
5108 + u32 pos;
5109 + u32 tx_isr_cnt;
5110 + u32 rx_isr_cnt;
5111 + int bSleep;
5112 + int bTxDMAEnable;
5113 + int bRxDMAEnable;
5114 + int enLable;
5115 + int micboost;
5116 + int micin;
5117 +
5118 + /* parameters fo ALSA */
5119 + int bALSAEnable;
5120 + int bALSAMMAPEnable;
5121 + unsigned char bTrigger[2];
5122 + unsigned char bPreTrigger[2];
5123 + unsigned char dmaStat[2];
5124 + unsigned char i2sStat[2];
5125 + unsigned int hw_base_frame[2];
5126 + struct snd_pcm_substream *pss[2];
5127 +
5128 +#ifdef __KERNEL__
5129 + spinlock_t lock;
5130 + wait_queue_head_t i2s_tx_qh, i2s_rx_qh;
5131 +#endif
5132 + u32 dmach;
5133 + u32 tx_unmask_ch;
5134 + u32 rx_unmask_ch;
5135 + u32 dma_unmask_status;
5136 + u32 dma_done_status;
5137 + u32 tx_ff_thres;
5138 + u32 tx_ch_swap;
5139 + u32 rx_ff_thres;
5140 + u32 rx_ch_swap;
5141 + u32 slave_en;
5142 +
5143 + u32 dis_match;
5144 + int start_cnt;
5145 +#if defined (CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
5146 + int little_edn; /* test file's fmt: little endian->1; big endian->0 */
5147 + int sys_endian; /* kernal' system fmt: little endian->0; big endian->1 */
5148 +#endif
5149 + int wordlen_24b;
5150 + int codec_pll_en;
5151 + int codec_num;
5152 + int tx_pause_en;
5153 + int rx_pause_en;
5154 + int end_cnt;
5155 + int txrx_coexist;
5156 + int tx_stop_cnt;
5157 + int rx_stop_cnt;
5158 + /* for I2S_CFG1 */
5159 + u32 lbk;
5160 + u32 extlbk;
5161 + u32 fmt;
5162 +
5163 + int w_idx;
5164 + int r_idx;
5165 +
5166 + int tx_w_idx;
5167 + int tx_r_idx;
5168 + int rx_w_idx;
5169 + int rx_r_idx;
5170 + int mmap_index;
5171 + int next_p0_idx;
5172 + int next_p1_idx;
5173 +
5174 + u8* buf8ptr;
5175 + char* pMMAPBufPtr[MAX_I2S_PAGE*2];
5176 + char* pMMAPTxBufPtr[MAX_I2S_PAGE];
5177 + char* pMMAPRxBufPtr[MAX_I2S_PAGE];
5178 +
5179 + union {
5180 + u16* pPage0TxBuf16Ptr;
5181 + u8* pPage0TxBuf8ptr;
5182 + };
5183 + union {
5184 + u16* pPage1TxBuf16Ptr;
5185 + u8* pPage1TxBuf8ptr;
5186 + };
5187 +
5188 + union {
5189 + u16* pPage0RxBuf16Ptr;
5190 + u8* pPage0RxBuf8ptr;
5191 + };
5192 + union {
5193 + u16* pPage1RxBuf16Ptr;
5194 + u8* pPage1RxBuf8ptr;
5195 + };
5196 +
5197 +}i2s_config_type;
5198 +
5199 +
5200 +void i2s_gen_test_pattern(void);
5201 +int i2s_mem_unmap(i2s_config_type* ptri2s_config);
5202 +int i2s_param_init(i2s_config_type* ptri2s_config);
5203 +int i2s_txbuf_alloc(i2s_config_type* ptri2s_config);
5204 +int i2s_rxbuf_alloc(i2s_config_type* ptri2s_config);
5205 +int i2s_txPagebuf_alloc(i2s_config_type* ptri2s_config);
5206 +int i2s_rxPagebuf_alloc(i2s_config_type* ptri2s_config);
5207 +int i2s_txbuf_free(i2s_config_type* ptri2s_config);
5208 +int i2s_rxbuf_free(i2s_config_type* ptri2s_config);
5209 +int i2s_txPagebuf_free(i2s_config_type* ptri2s_config);
5210 +int i2s_rxPagebuf_free(i2s_config_type* ptri2s_config);
5211 +int i2s_reset_tx_param(i2s_config_type* ptri2s_config);
5212 +int i2s_reset_rx_param(i2s_config_type* ptri2s_config);
5213 +int i2s_tx_config(i2s_config_type* ptri2s_config);
5214 +int i2s_rx_config(i2s_config_type* ptri2s_config);
5215 +int i2s_tx_enable(i2s_config_type* ptri2s_config);
5216 +int i2s_tx_disable(i2s_config_type* ptri2s_config);
5217 +int i2s_rx_enable(i2s_config_type* ptri2s_config);
5218 +int i2s_rx_disable(i2s_config_type* ptri2s_config);
5219 +int i2s_codec_enable(i2s_config_type* ptri2s_config);
5220 +int i2s_codec_disable(i2s_config_type* ptri2s_config);
5221 +int i2s_clock_enable(i2s_config_type* ptri2s_config);
5222 +int i2s_clock_disable(i2s_config_type* ptri2s_config);
5223 +int i2s_reset_config(i2s_config_type* ptri2s_config);
5224 +int i2s_refclk_disable(void);
5225 +int i2s_refclk_gpio_out_config(void);
5226 +int i2s_refclk_gpio_in_config(void);
5227 +int i2s_share_pin_config(i2s_config_type* ptri2s_config);
5228 +int i2s_share_pin_mt7623(i2s_config_type* ptri2s_config);
5229 +int i2s_master_clock_gpio_out_mt7623(void);
5230 +int i2s_slave_clock_gpio_in_mt7623(void);
5231 +int i2s_ws_config(i2s_config_type* ptri2s_config, unsigned long index);
5232 +int i2s_mode_config(u32 slave_en);
5233 +int i2s_codec_frequency_config(i2s_config_type* ptri2s_config, unsigned long index);
5234 +void i2s_tx_end_sleep_on(i2s_config_type* ptri2s_config);
5235 +void i2s_rx_end_sleep_on(i2s_config_type* ptri2s_config);
5236 +
5237 +#if defined(CONFIG_I2S_MCLK_12MHZ)
5238 +int i2s_refclk_12m_enable(void);
5239 +#endif
5240 +#if defined(CONFIG_I2S_MCLK_12P288MHZ)
5241 +int i2s_refclk_12p288m_enable(void);
5242 +#endif
5243 +
5244 +#if defined(MT7621_ASIC_BOARD)
5245 +int i2s_pll_config_mt7621(unsigned long index);
5246 +int i2s_pll_refclk_set(void);
5247 +#endif
5248 +#if defined(MT7623_ASIC_BOARD)
5249 +int i2s_pll_config_mt7623(unsigned long index);
5250 +#endif
5251 +#if defined(MT7628_ASIC_BOARD) || defined(CONFIG_ARCH_MT7623)
5252 +int i2s_driving_strength_adjust(void);
5253 +#endif
5254 +#if defined(I2S_STATISTIC)
5255 +void i2s_int_status(u32 dma_ch);
5256 +#endif
5257 +void i2s_dma_tx_handler(u32 dma_ch);
5258 +void i2s_dma_rx_handler(u32 dma_ch);
5259 +void i2s_dma_unmask_handler(u32 dma_ch);
5260 +void i2s_dma_mask_handler(u32 dma_ch);
5261 +void i2s_dma_tx_init(i2s_config_type* ptri2s_config);
5262 +void i2s_dma_rx_init(i2s_config_type* ptri2s_config);
5263 +void i2s_tx_task(unsigned long pData);
5264 +void i2s_rx_task(unsigned long pData);
5265 +void i2s_dma_tx_unmask_handler(u32 dma_ch);
5266 +void i2s_dma_rx_unmask_handler(u32 dma_ch);
5267 +int i2s_dma_tx_transf_data(i2s_config_type* ptri2s_config, u32 dma_ch);
5268 +int i2s_dma_tx_transf_zero(i2s_config_type* ptri2s_config, u32 dma_ch);
5269 +int i2s_dma_rx_transf_data(i2s_config_type* ptri2s_config, u32 dma_ch);
5270 +int i2s_dma_rx_transf_zero(i2s_config_type* ptri2s_config, u32 dma_ch);
5271 +void i2s_dma_tx_end_handle(i2s_config_type* ptri2s_config);
5272 +int i2s_dma_tx_soft_stop(i2s_config_type* ptri2s_config, u32 dma_ch);
5273 +int i2s_dma_rx_soft_stop(i2s_config_type* ptri2s_config, u32 dma_ch);
5274 +
5275 +int i2s_page_prepare(i2s_config_type* ptri2s_config,int dir);
5276 +int i2s_page_release(i2s_config_type* ptri2s_config,int dir);
5277 +int gdma_En_Switch(i2s_config_type* ptri2s_config,int dir,int enabled);
5278 +int i2s_startup(void);
5279 +int i2s_audio_exchange(i2s_config_type* ptri2s_config,int dir,unsigned long arg);
5280 +void gdma_unmask_handler(u32 dma_ch);
5281 +char* i2s_memPool_Alloc(i2s_config_type* ptri2s_config,int dir);
5282 +void i2s_memPool_free(i2s_config_type* ptri2s_config,int dir);
5283 +u32 i2s_mmap_phys_addr(i2s_config_type* ptri2s_config);
5284 +
5285 +#if !defined(CONFIG_I2S_TXRX)
5286 +#define GdmaI2sRx //GdmaI2sRx
5287 +#endif
5288 +
5289 +#define RALINK_I2S_VERSION "1.0"
5290 +#define I2SDRV_DEVNAME "i2s0"
5291 +
5292 +#endif /* __RALINK_I2S_H_ */
5293 +
5294 --- /dev/null
5295 +++ b/sound/soc/mtk/i2s_debug.c
5296 @@ -0,0 +1,698 @@
5297 +#include <linux/init.h>
5298 +#include <linux/version.h>
5299 +#include <linux/module.h>
5300 +#include <linux/kernel.h> /* printk() */
5301 +#include "i2s_ctrl.h"
5302 +#include <linux/delay.h>
5303 +#include <linux/jiffies.h>
5304 +#include <linux/random.h>
5305 +#include <linux/slab.h>
5306 +#include <asm/uaccess.h> /* copy_from/to_user */
5307 +
5308 +#if defined(CONFIG_SND_RALINK_SOC)
5309 +#include <sound/soc/mtk/mtk_audio_device.h>
5310 +#endif
5311 +
5312 +#if defined(CONFIG_I2S_WM8750)
5313 +#include "../codec/i2c_wm8750.h"
5314 +#endif
5315 +#if defined(CONFIG_I2S_WM8751)
5316 +#include "../codec/i2c_wm8751.h"
5317 +#endif
5318 +#if defined(CONFIG_I2S_WM8960)
5319 +#include "i2c_wm8960.h"
5320 +#endif
5321 +
5322 +
5323 +//#define INTERNAL_LOOPBACK_DEBUG
5324 +
5325 +extern unsigned long i2s_codec_12p288Mhz[11];
5326 +extern unsigned long i2s_codec_12Mhz[11];
5327 +#if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
5328 +extern unsigned long i2s_inclk_int_16bit[13];
5329 +extern unsigned long i2s_inclk_comp_16bit[13];
5330 +extern unsigned long i2s_inclk_int_24bit[13];
5331 +extern unsigned long i2s_inclk_comp_24bit[13];
5332 +#else
5333 +extern unsigned long i2s_inclk_int[11];
5334 +extern unsigned long i2s_inclk_comp[11];
5335 +#endif
5336 +extern int i2s_pll_config_mt7621(unsigned long index);
5337 +extern int i2s_pll_config_mt7623(unsigned long index);
5338 +
5339 +#if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
5340 +extern void audiohw_loopback(int fsel);
5341 +extern void audiohw_bypass(void);
5342 +extern int audiohw_set_lineout_vol(int Aout, int vol_l, int vol_r);
5343 +extern int audiohw_set_linein_vol(int vol_l, int vol_r);
5344 +#endif
5345 +
5346 +#if defined(CONFIG_I2S_WM8960)
5347 +extern void audiohw_codec_exlbk(void);
5348 +#endif
5349 +
5350 +unsigned long txbuffer[512] = {
5351 + 0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
5352 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
5353 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
5354 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
5355 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
5356 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
5357 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
5358 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 1
5359 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
5360 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
5361 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
5362 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
5363 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
5364 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
5365 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
5366 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 2
5367 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
5368 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
5369 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
5370 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
5371 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
5372 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
5373 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
5374 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 3
5375 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
5376 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
5377 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
5378 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
5379 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
5380 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
5381 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
5382 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 4
5383 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
5384 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
5385 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
5386 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
5387 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
5388 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
5389 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
5390 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 5
5391 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
5392 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
5393 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
5394 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
5395 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
5396 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
5397 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
5398 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 6
5399 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
5400 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
5401 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
5402 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
5403 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
5404 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
5405 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
5406 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00, //round 7
5407 +0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20,
5408 + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40,
5409 + 0x41424344, 0x45464748, 0x494a4b4c, 0x4d4e4f50, 0x51525354, 0x55565758, 0x595a5b5c, 0x5d5e5f60,
5410 + 0x61626364, 0x65666768, 0x696a6b6c, 0x6d6e6f70, 0x71727374, 0x75767778, 0x797a7b7c, 0x7d7e7f80,
5411 + 0x81828384, 0x85868788, 0x898a8b8c, 0x8d8e8f90, 0x91929394, 0x95969798, 0x999a9b9c, 0x9d9e9fa0,
5412 + 0xa1a2a3a4, 0xa5a6a7a8, 0xa9aaabac, 0xadaeafb0, 0xb1b2b3b4, 0xb5b6b7b8, 0xb9babbbc, 0xbdbebfc0,
5413 + 0xc1c2c3c4, 0xc5c6c7c8, 0xc9cacbcc, 0xcdcecfd0, 0xd1d2d3d4, 0xd5d6d7d8, 0xd9dadbdc, 0xdddedfe0,
5414 + 0xe1e2e3e4, 0xe5e6e7e8, 0xe9eaebec, 0xedeeeff0, 0xf1f2f3f4, 0xf5f6f7f8, 0xf9fafbfc, 0xfdfeff00 //round 8
5415 + };
5416 +
5417 +int i2s_debug_cmd(unsigned int cmd, unsigned long arg)
5418 +{
5419 + unsigned long data, index;
5420 + unsigned long *pTable;
5421 + int i;
5422 +
5423 + switch(cmd)
5424 + {
5425 + case I2S_DEBUG_CLKGEN:
5426 + MSG("I2S_DEBUG_CLKGEN\n");
5427 +#if defined(CONFIG_RALINK_RT3052)
5428 + *(volatile unsigned long*)(0xB0000060) = 0x00000016;
5429 + *(volatile unsigned long*)(0xB0000030) = 0x00009E00;
5430 + *(volatile unsigned long*)(0xB0000A00) = 0xC0000040;
5431 +#elif defined(CONFIG_RALINK_RT3350)
5432 + *(volatile unsigned long*)(0xB0000060) = 0x00000018;
5433 + *(volatile unsigned long*)(0xB000002C) = 0x00000100;
5434 + *(volatile unsigned long*)(0xB0000030) = 0x00009E00;
5435 + *(volatile unsigned long*)(0xB0000A00) = 0xC0000040;
5436 +#elif defined(CONFIG_RALINK_RT3883)
5437 + *(volatile unsigned long*)(0xB0000060) = 0x00000018;
5438 + *(volatile unsigned long*)(0xB000002C) = 0x00003000;
5439 + *(volatile unsigned long*)(0xB0000A00) = 0xC1104040;
5440 + *(volatile unsigned long*)(0xB0000A24) = 0x00000027;
5441 + *(volatile unsigned long*)(0xB0000A20) = 0x80000020;
5442 +#elif (defined(CONFIG_RALINK_RT3352)||defined(CONFIG_RALINK_RT5350)) || defined (CONFIG_RALINK_RT6855)
5443 + *(volatile unsigned long*)(0xB0000060) = 0x00000018;
5444 + *(volatile unsigned long*)(0xB000002C) = 0x00000300;
5445 + *(volatile unsigned long*)(0xB0000A00) = 0xC1104040;
5446 + *(volatile unsigned long*)(0xB0000A24) = 0x00000027;
5447 + *(volatile unsigned long*)(0xB0000A20) = 0x80000020;
5448 +#elif defined(CONFIG_RALINK_RT6855A)
5449 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x860) = 0x00008080;
5450 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x82C) = 0x00000300;
5451 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0xC1104040;
5452 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x24) = 0x00000027;
5453 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x20) = 0x80000020;
5454 +#else
5455 +//#error "I2S debug mode not support this Chip"
5456 +#endif
5457 + break;
5458 + case I2S_DEBUG_INLBK:
5459 + MSG("I2S_DEBUG_INLBK\n");
5460 +#if defined(CONFIG_RALINK_MT7621)
5461 + switch(96000)
5462 + {
5463 + case 8000:
5464 + index = 0;
5465 + break;
5466 + case 11025:
5467 + index = 1;
5468 + break;
5469 + case 12000:
5470 + index = 2;
5471 + break;
5472 + case 16000:
5473 + index = 3;
5474 + break;
5475 + case 22050:
5476 + index = 4;
5477 + break;
5478 + case 24000:
5479 + index = 5;
5480 + break;
5481 + case 32000:
5482 + index = 6;
5483 + break;
5484 + case 44100:
5485 + index = 7;
5486 + break;
5487 + case 48000:
5488 + index = 8;
5489 + break;
5490 + case 88200:
5491 + index = 9;
5492 + break;
5493 + case 96000:
5494 + index = 10;
5495 + break;
5496 + case 192000:
5497 + index = 11;
5498 + break;
5499 + default:
5500 + index = 7;
5501 + }
5502 + i2s_pll_config_mt7621(index);
5503 +#elif defined(CONFIG_ARCH_MT7623)
5504 + i2s_pll_config_mt7623(11);
5505 +#endif
5506 +
5507 +
5508 +#if defined(CONFIG_RALINK_RT3052)
5509 + break;
5510 +#endif
5511 +#if defined(CONFIG_RALINK_RT6855A)
5512 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x834) |= 0x00020000;
5513 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x834) &= 0xFFFDFFFF;
5514 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x0) &= 0x7FFFFFFF; //Rest I2S to default vaule
5515 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x860) |= 0x00008080;
5516 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x82C) = 0x00000300;
5517 +#elif defined(CONFIG_RALINK_MT7621)
5518 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x34) |= 0x00020000;
5519 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x34) &= 0xFFFDFFFF;
5520 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x0) &= 0x7FFFFFFF; //Rest I2S to default vaule
5521 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x60) = 0x00000010; //GPIO purpose selection
5522 +#elif defined(CONFIG_RALINK_MT7628)
5523 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x34) |= 0x00020000;
5524 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x34) &= 0xFFFDFFFF;
5525 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x0) &= 0x7FFFFFFF; //Rest I2S to default vaule
5526 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x60) &= ~((0x3)<<6); //GPIO purpose selection /*FIXME*/
5527 +#elif defined(CONFIG_ARCH_MT7623)
5528 + *(volatile unsigned long*)(0xFB000034) |= 0x00020000;
5529 + *(volatile unsigned long*)(0xFB000034) &= 0xFFFDFFFF;
5530 + *(volatile unsigned long*)(ETHDMASYS_I2S_BASE+0x0) &= 0x7FFFFFFF; //Rest I2S to default vaule
5531 +
5532 + *(volatile unsigned long*)(0xF0005840) &= ~((0x7)<<12);
5533 + *(volatile unsigned long*)(0xF0005840) |= ((0x6)<<12);
5534 + *(volatile unsigned long*)(0xF0005840) &= ~((0x7)<<9);
5535 + *(volatile unsigned long*)(0xF0005840) |= ((0x6)<<9);
5536 + *(volatile unsigned long*)(0xF0005040) |= ((0x1)<<10);
5537 + *(volatile unsigned long*)(0xF0005040) |= ((0x1)<<9);
5538 +
5539 + *(volatile unsigned long*)(0xF00057F0) &= ~((0x7)<<12);
5540 + *(volatile unsigned long*)(0xF00057F0) |= ((0x6)<<12);
5541 + *(volatile unsigned long*)(0xF0005030) |= ((0x1)<<1);
5542 +
5543 + *(volatile unsigned long*)(0xF0005840) &= ~((0x7)<<6);
5544 + *(volatile unsigned long*)(0xF0005840) |= ((0x6)<<6);
5545 + *(volatile unsigned long*)(0xF0005040) &= ~((0x1)<<8);
5546 +
5547 + *(volatile unsigned long*)(0xF00058F0) &= ~((0x7)<<3);
5548 + *(volatile unsigned long*)(0xF00058F0) |= ((0x6)<<3);
5549 + *(volatile unsigned long*)(0xF0005070) |= ((0x1)<<14);
5550 +
5551 +
5552 +#else
5553 + *(volatile unsigned long*)(0xB0000034) |= 0x00020000;
5554 + *(volatile unsigned long*)(0xB0000034) &= 0xFFFDFFFF;
5555 + *(volatile unsigned long*)(0xB0000A00) &= 0x7FFFFFFF; //Rest I2S to default vaule
5556 + *(volatile unsigned long*)(0xB0000060) = 0x00000018;
5557 +
5558 +#if defined(CONFIG_RALINK_RT3883)
5559 + *(volatile unsigned long*)(0xB000002C) = 0x00003000;
5560 +#elif defined(CONFIG_ARCH_MT7623)
5561 +
5562 +#else
5563 + *(volatile unsigned long*)(0xB000002C) = 0x00000300;
5564 +#endif
5565 +#endif
5566 +#if defined(CONFIG_RALINK_MT7621)
5567 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x18) = 0x80000000;
5568 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0xc1104040;
5569 +
5570 + pTable = i2s_inclk_int;
5571 + data = pTable[index];
5572 + //*(volatile unsigned long*)(RALINK_I2S_BASE+0x24) = data;
5573 + i2s_outw(RALINK_I2S_BASE+0x24, data);
5574 +
5575 + pTable = i2s_inclk_comp;
5576 + data = pTable[index];
5577 + //*(volatile unsigned long*)(RALINK_I2S_BASE+0x20) = data;
5578 + i2s_outw(RALINK_I2S_BASE+0x20, (data|0x80000000));
5579 +#elif defined(CONFIG_RALINK_MT7628)
5580 + index =11; /* SR: 192k */
5581 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x18) = 0x80000000;
5582 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0xc1104040;
5583 +
5584 + pTable = i2s_inclk_int_16bit;
5585 + //pTable = i2s_inclk_int_24bit;
5586 + data = pTable[index];
5587 + //*(volatile unsigned long*)(RALINK_I2S_BASE+0x24) = data;
5588 + i2s_outw(RALINK_I2S_BASE+0x24, data);
5589 +
5590 + pTable = i2s_inclk_comp_16bit;
5591 + //pTable = i2s_inclk_comp_24bit;
5592 + data = pTable[index];
5593 + //*(volatile unsigned long*)(RALINK_I2S_BASE+0x20) = data;
5594 + i2s_outw(RALINK_I2S_BASE+0x20, (data|0x80000000));
5595 + mdelay(5);
5596 +#elif defined(CONFIG_ARCH_MT7623)
5597 + index = 11;
5598 + *(volatile unsigned long*)(I2S_I2SCFG1) = 0x80000000;
5599 + *(volatile unsigned long*)(I2S_I2SCFG) = 0xE1104040;
5600 + *(volatile unsigned long*)(ETHDMASYS_SYSCTL_BASE+0x30) |= 0x00020000;
5601 + *(volatile unsigned long*)(ETHDMASYS_SYSCTL_BASE+0x2c) |= 0x00000080;
5602 +
5603 + pTable = i2s_inclk_int_16bit;
5604 + //pTable = i2s_inclk_int_24bit;
5605 + data = pTable[index];
5606 + i2s_outw(I2S_DIVINT_CFG, data);
5607 +
5608 + pTable = i2s_inclk_comp_16bit;
5609 + //pTable = i2s_inclk_comp_24bit;
5610 + data = pTable[index];
5611 + i2s_outw(I2S_DIVCOMP_CFG, (data|0x80000000));
5612 + mdelay(5);
5613 +#else
5614 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x18) = 0x80000000;
5615 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0xC1104040;
5616 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x24) = 0x00000006;
5617 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x20) = 0x80000105;
5618 +#endif
5619 + {
5620 + int count = 0;
5621 + int k=0;
5622 + int enable_cnt=0;
5623 + unsigned long param[4];
5624 + unsigned long data;
5625 + //unsigned long data_tmp;
5626 + unsigned long ff_status;
5627 + //unsigned long* txbuffer;
5628 +#if 0
5629 + int j=0;
5630 + int temp = 0;
5631 +#endif
5632 +#if defined (INTERNAL_LOOPBACK_DEBUG)
5633 + int count2 = 0;
5634 +#endif
5635 + memset(param, 0, 4*sizeof(unsigned long) );
5636 + copy_from_user(param, (unsigned long*)arg, sizeof(long)*2);
5637 +#if 0
5638 + txbuffer = (unsigned long*)kcalloc(param[0], sizeof(unsigned long), GFP_KERNEL);
5639 + if(txbuffer == NULL)
5640 + return -1;
5641 +#endif
5642 +
5643 + //ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C);
5644 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
5645 + printk("ff status=[0x%08X]\n",(u32)ff_status);
5646 +
5647 +#if 0
5648 + for(i = 0; i < param[0]; i++)
5649 + {
5650 + if (i==0)
5651 + {
5652 + txbuffer[i] = 0x555A555A;
5653 + printk("%d: 0x%8lx\n", i, txbuffer[i]);
5654 + }
5655 + else
5656 + {
5657 + #if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,14)
5658 + srandom32(jiffies);
5659 + txbuffer[i] = random32()%(0x555A555A)+1;
5660 + //printk("%d: 0x%8x\n", i, txbuffer[i]);
5661 + #else
5662 + //TODO:do we need to implement random32()
5663 + txbuffer[i] = 0x01010101;
5664 + #endif
5665 + }
5666 + }
5667 +#endif
5668 +
5669 + for( i = 0 ; i < param[0] ; i ++ )
5670 + {
5671 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
5672 + #if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
5673 + if((ff_status&0xFF) > 0)
5674 + #else
5675 + if((ff_status&0x0F) > 0)
5676 + #endif
5677 + {
5678 + *(volatile unsigned long*)(I2S_TX_FIFO_WREG) = txbuffer[i];
5679 + mdelay(1);
5680 + }
5681 + else
5682 + {
5683 + mdelay(1);
5684 + printk("[%d]NO TX FREE FIFO ST=[0x%08X]\n", i, (u32)ff_status);
5685 + continue;
5686 + }
5687 +
5688 + //if(i >= 16)
5689 + {
5690 +
5691 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
5692 + #if defined(CONFIG_RALINK_MT7628)
5693 + if(((ff_status>>8)&0xFF) > 0)
5694 + #else
5695 + if(((ff_status>>4)&0x0F) > 0)
5696 + #endif
5697 + {
5698 + data = *(volatile unsigned long*)(I2S_RX_FIFO_RREG);
5699 + //data_tmp = *(volatile unsigned long*)(I2S_RX_FIFO_RREG);
5700 + //MSG("[0x%08X] vs [0x%08X]\n", (u32)data, (u32)data_tmp);
5701 + }
5702 + else
5703 + {
5704 + printk("*[%d]NO RX FREE FIFO ST=[0x%08X]\n", i, (u32)ff_status);
5705 + continue;
5706 + }
5707 +
5708 + if (data == txbuffer[0])
5709 + {
5710 + k = i;
5711 + enable_cnt = 1;
5712 + }
5713 + if (enable_cnt==1)
5714 + {
5715 + if(data!= txbuffer[i-k])
5716 + {
5717 + MSG("[%d][0x%08X] vs [0x%08X]\n", (i-k), (u32)data, (u32)txbuffer[i-k]);
5718 + }
5719 + else
5720 + {
5721 + //MSG("**[%d][0x%08X] vs [0x%08X]\n" ,(i-k), (u32)data , (u32)txbuffer[i-k]);
5722 + count++;
5723 + data=0;
5724 + }
5725 + }
5726 +
5727 + }
5728 + }
5729 +#if 0
5730 + temp = i-k;
5731 + for (j=0; j<k; j++)
5732 + {
5733 +
5734 + //ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C);
5735 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
5736 + #if defined(CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623)
5737 + if(((ff_status>>8)&0xFF) > 0)
5738 + #else
5739 + if(((ff_status>>4)&0x0F) > 0)
5740 + #endif
5741 + {
5742 + //data = *(volatile unsigned long*)(RALINK_I2S_BASE+0x14);
5743 + data = *(volatile unsigned long*)(I2S_RX_FIFO_RREG);
5744 + }
5745 + else
5746 + {
5747 + printk("*NO RX FREE FIFO ST=[0x%08X]\n", (u32)ff_status);
5748 + continue;
5749 + }
5750 +
5751 + if(data!= txbuffer[temp+j])
5752 + {
5753 + MSG("[%d][0x%08X] vs [0x%08X]\n", (temp+j), (u32)data, (u32)txbuffer[temp+j]);
5754 + }
5755 + else
5756 + {
5757 + //MSG("&&[%d][0x%08X] vs [0x%08X]\n" ,(temp+j), (u32)data , (u32)txbuffer[temp+j]);
5758 + count++;
5759 + data=0;
5760 + }
5761 + if ((temp+j)==128)
5762 + {
5763 + //ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C);
5764 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
5765 + //printk("[%d]FIFO ST=[0x%08X]\n", (temp+j), (u32)ff_status);
5766 + }
5767 + }
5768 +#endif
5769 +
5770 +#if defined (INTERNAL_LOOPBACK_DEBUG)
5771 + for( i = 0 ; i < param[0] ; i ++ )
5772 + {
5773 + //ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C);
5774 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
5775 + #if defined(CONFIG_RALINK_MT7628)|| defined(CONFIG_ARCH_MT7623)
5776 + if((ff_status&0xFF) > 0)
5777 + #else
5778 + if((ff_status&0x0F) > 0)
5779 + #endif
5780 + {
5781 + //*(volatile unsigned long*)(RALINK_I2S_BASE+0x10) = txbuffer[i];
5782 + *(volatile unsigned long*)(I2S_TX_FIFO_WREG) = txbuffer[i];
5783 + mdelay(1);
5784 + }
5785 + else
5786 + {
5787 + mdelay(1);
5788 + printk("[%d]NO TX FREE FIFO ST=[0x%08X]\n", i, (u32)ff_status);
5789 + continue;
5790 + }
5791 +
5792 + //if(i >= 16)
5793 + {
5794 +
5795 + //ff_status = *(volatile unsigned long*)(RALINK_I2S_BASE+0x0C);
5796 + ff_status = *(volatile unsigned long*)(I2S_FF_STATUS);
5797 + #if defined(CONFIG_RALINK_MT7628)|| defined(CONFIG_ARCH_MT7623)
5798 + if(((ff_status>>8)&0xFF) > 0)
5799 + #else
5800 + if(((ff_status>>4)&0x0F) > 0)
5801 + #endif
5802 + {
5803 + //data = *(volatile unsigned long*)(RALINK_I2S_BASE+0x14);
5804 + data = *(volatile unsigned long*)(I2S_RX_FIFO_RREG);
5805 + }
5806 + else
5807 + {
5808 + printk("*[%d]NO RX FREE FIFO ST=[0x%08X]\n", i, (u32)ff_status);
5809 + continue;
5810 + }
5811 +
5812 + {
5813 + if(data!= txbuffer[i])
5814 + {
5815 + MSG("[%d][0x%08X] vs [0x%08X]\n", (i), (u32)data, (u32)txbuffer[i]);
5816 + }
5817 + else
5818 + {
5819 + MSG("**[%d][0x%08X] vs [0x%08X]\n" ,(i), (u32)data , (u32)txbuffer[i]);
5820 + count2++;
5821 + data=0;
5822 + }
5823 + }
5824 +
5825 + }
5826 + }
5827 + printk("Pattern match done count2=%d.\n", count2);
5828 +#endif
5829 + printk("Pattern match done count=%d.\n", count);
5830 +
5831 + }
5832 +#if defined(CONFIG_ARCH_MT7623)
5833 + *(volatile unsigned long*)(0xFB000034) |= 0x00020000;
5834 + *(volatile unsigned long*)(0xFB000034) &= 0xFFFDFFFF;
5835 + *(volatile unsigned long*)(ETHDMASYS_I2S_BASE+0x0) &= 0x7FFFFFFF; //Rest I2S to default vaule
5836 +#endif
5837 +
5838 +#if !defined(CONFIG_RALINK_RT3052)
5839 + break;
5840 +#endif
5841 + case I2S_DEBUG_EXLBK:
5842 + MSG("I2S_DEBUG_EXLBK\n");
5843 +#if !defined(CONFIG_ARCH_MT7623)
5844 + switch(arg)
5845 + {
5846 + case 8000:
5847 + index = 0;
5848 + break;
5849 + case 11025:
5850 + index = 1;
5851 + break;
5852 + case 12000:
5853 + index = 2;
5854 + break;
5855 + case 16000:
5856 + index = 3;
5857 + break;
5858 + case 22050:
5859 + index = 4;
5860 + break;
5861 + case 24000:
5862 + index = 5;
5863 + break;
5864 + case 32000:
5865 + index = 6;
5866 + break;
5867 + case 44100:
5868 + index = 7;
5869 + break;
5870 + case 48000:
5871 + index = 8;
5872 + break;
5873 + case 88200:
5874 + index = 9;
5875 + break;
5876 + case 96000:
5877 + index = 10;
5878 + break;
5879 + default:
5880 + index = 7;
5881 + }
5882 +#if defined(CONFIG_RALINK_RT3052)
5883 + break;
5884 +#endif
5885 +#if defined(CONFIG_RALINK_RT6855A)
5886 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x860) = 0x00008080;
5887 + //*(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x82C) = 0x00000300;
5888 +#else
5889 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x60) = 0x00000018;
5890 +#if defined(CONFIG_RALINK_RT3883)
5891 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x2C) = 0x00003000;
5892 +#else
5893 + *(volatile unsigned long*)(RALINK_SYSCTL_BASE+0x2C) = 0x00000300;
5894 +#endif
5895 +#endif
5896 +
5897 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x18) = 0x40000000;
5898 + *(volatile unsigned long*)(RALINK_I2S_BASE+0x00) = 0x81104040;
5899 +#if defined(CONFIG_RALINK_MT7628)
5900 + pTable = i2s_inclk_int_16bit;
5901 +#else
5902 + pTable = i2s_inclk_int;
5903 +#endif
5904 + data = (volatile unsigned long)(pTable[index]);
5905 + i2s_outw(I2S_DIVINT_CFG, data);
5906 +#if defined(CONFIG_RALINK_MT7628)
5907 + pTable = i2s_inclk_comp_16bit;
5908 +#else
5909 + pTable = i2s_inclk_comp;
5910 +#endif
5911 + data = (volatile unsigned long)(pTable[index]);
5912 + data |= REGBIT(1, I2S_CLKDIV_EN);
5913 + i2s_outw(I2S_DIVCOMP_CFG, data);
5914 +
5915 + #if defined(CONFIG_I2S_MCLK_12MHZ)
5916 + pTable = i2s_codec_12Mhz;
5917 + #if defined(CONFIG_I2S_WM8960)
5918 + data = pTable[index];
5919 + #else
5920 + data = pTable[index]|0x01;
5921 + #endif
5922 + #else
5923 + pTable = i2s_codec_12p288Mhz;
5924 + data = pTable[index];
5925 + #endif
5926 +
5927 + #if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
5928 + audiohw_preinit();
5929 + #endif
5930 +
5931 +
5932 + #if defined (CONFIG_I2S_WM8960)
5933 + audiohw_postinit(1, 1, 1, 1, 0); // for codec apll enable, 16 bit word length
5934 + #elif defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
5935 + audiohw_postinit(1, 1, 1, 0); // for 16 bit word length
5936 + #endif
5937 +
5938 +
5939 + #if defined (CONFIG_I2S_WM8960)
5940 + audiohw_set_frequency(data, 1); // for codec apll enable
5941 + #elif defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
5942 + audiohw_set_frequency(data|0x1);
5943 + #endif
5944 +
5945 +
5946 + #if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
5947 + audiohw_set_lineout_vol(1, 100, 100);
5948 + audiohw_set_linein_vol(100, 100);
5949 + #endif
5950 +
5951 +
5952 + #if defined(CONFIG_I2S_TXRX)
5953 + //audiohw_loopback(data);
5954 + #endif
5955 + #if !defined(CONFIG_RALINK_RT3052)
5956 + break;
5957 + #endif
5958 +#endif
5959 + case I2S_DEBUG_CODECBYPASS:
5960 + #if defined(CONFIG_I2S_TXRX)
5961 + #if defined(CONFIG_RALINK_MT7628)
5962 + data = i2s_inw(RALINK_SYSCTL_BASE+0x60);
5963 + //data &= ~(0x3<<4);
5964 + data &= ~(0x3<<6);
5965 + data &= ~(0x3<<16);
5966 + data &= ~(0x1<<14);
5967 + i2s_outw(RALINK_SYSCTL_BASE+0x60, data);
5968 +
5969 + data = i2s_inw(RALINK_SYSCTL_BASE+0x2c);
5970 + data &= ~(0x07<<9);
5971 + i2s_outw(RALINK_SYSCTL_BASE+0x2c, data);
5972 + #endif
5973 +
5974 + #if defined(CONFIG_I2S_WM8960) || defined(CONFIG_I2S_WM8750) || defined(CONFIG_I2S_WM8751)
5975 + audiohw_bypass(); /* did not work */
5976 + #endif
5977 + #endif
5978 + break;
5979 + case I2S_DEBUG_FMT:
5980 + break;
5981 + case I2S_DEBUG_RESET:
5982 + break;
5983 +#if defined(CONFIG_I2S_WM8960)
5984 + case I2S_DEBUG_CODEC_EXLBK:
5985 + audiohw_codec_exlbk();
5986 + break;
5987 +#endif
5988 + default:
5989 + MSG("Not support this debug cmd [%d]\n", cmd);
5990 + break;
5991 + }
5992 +
5993 + return 0;
5994 +}
5995 --- /dev/null
5996 +++ b/sound/soc/mtk/mt76xx_i2s.c
5997 @@ -0,0 +1,304 @@
5998 +/*
5999 + * mtk_audio_drv.c
6000 + *
6001 + * Created on: 2013/8/20
6002 + * Author: MTK04880
6003 + */
6004 +#include <linux/init.h>
6005 +#include <linux/version.h>
6006 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
6007 +#include <linux/sched.h>
6008 +#endif
6009 +#include <linux/module.h>
6010 +#include <linux/kernel.h> /* printk() */
6011 +#include <linux/slab.h> /* kmalloc() */
6012 +#include <linux/fs.h> /* everything... */
6013 +#include <linux/errno.h> /* error codes */
6014 +#include <linux/types.h> /* size_t */
6015 +#include <linux/proc_fs.h>
6016 +#include <linux/fcntl.h> /* O_ACCMODE */
6017 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36)
6018 +#include <asm/system.h> /* cli(), *_flags */
6019 +#endif
6020 +#include <asm/uaccess.h> /* copy_from/to_user */
6021 +#include <linux/interrupt.h>
6022 +#include <linux/mm.h>
6023 +#include <linux/dma-mapping.h>
6024 +#include <sound/core.h>
6025 +#include <linux/pci.h>
6026 +#include <sound/pcm.h>
6027 +#include <sound/pcm_params.h>
6028 +#include <sound/soc.h>
6029 +#include <sound/soc-dapm.h>
6030 +#include <sound/initval.h>
6031 +#include "ralink_gdma.h"
6032 +#include "mt76xx_i2s.h"
6033 +
6034 +/****************************/
6035 +/*GLOBAL VARIABLE DEFINITION*/
6036 +/****************************/
6037 +extern i2s_config_type* pi2s_config;
6038 +
6039 +/****************************/
6040 +/*FUNCTION DECLRATION */
6041 +/****************************/
6042 +static int mt76xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai,\
6043 + unsigned int fmt);
6044 +
6045 +//static int mt76xx_i2s_shutdown(struct snd_pcm_substream *substream,
6046 +// struct snd_soc_dai *dai);
6047 +static int mt76xx_i2s_startup(struct snd_pcm_substream *substream,
6048 + struct snd_soc_dai *dai);
6049 +static int mt76xx_i2s_hw_params(struct snd_pcm_substream *substream,\
6050 + struct snd_pcm_hw_params *params,\
6051 + struct snd_soc_dai *dai);
6052 +static int mt76xx_i2s_play_prepare(struct snd_pcm_substream *substream,struct snd_soc_dai *dai);
6053 +static int mt76xx_i2s_rec_prepare(struct snd_pcm_substream *substream,struct snd_soc_dai *dai);
6054 +static int mt76xx_i2s_hw_free(struct snd_pcm_substream *substream,struct snd_soc_dai *dai);
6055 +static int mt76xx_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai);
6056 +
6057 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,20)
6058 +static int mt76xx_i2s_drv_probe(struct platform_device *pdev);
6059 +static int mt76xx_i2s_drv_remove(struct platform_device *pdev);
6060 +#endif
6061 +/****************************/
6062 +/*STRUCTURE DEFINITION */
6063 +/****************************/
6064 +
6065 +
6066 +static struct snd_soc_dai_ops mt76xx_i2s_dai_ops = {
6067 + .startup = mt76xx_i2s_startup,
6068 + .hw_params = mt76xx_i2s_hw_params,
6069 + .hw_free = mt76xx_i2s_hw_free,
6070 + //.shutdown = mt76xx_i2s_shutdown,
6071 + .prepare = mt76xx_i2s_prepare,
6072 + .set_fmt = mt76xx_i2s_set_fmt,
6073 + //.set_sysclk = mt76xx_i2s_set_sysclk,
6074 +};
6075 +
6076 +const struct snd_soc_component_driver mt76xx_i2s_component = {
6077 + .name = "mt76xx-i2s",
6078 +};
6079 +
6080 +struct snd_soc_dai_driver mt76xx_i2s_dai = {
6081 + .playback = {
6082 + .channels_min = 1,
6083 + .channels_max = 2,
6084 + .rates = (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_11025|\
6085 + SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_22050|SNDRV_PCM_RATE_32000|\
6086 + SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000),
6087 +
6088 + .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
6089 + SNDRV_PCM_FMTBIT_S24_LE),
6090 + },
6091 + .capture = {
6092 + .channels_min = 1,
6093 + .channels_max = 2,
6094 + .rates = (SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_11025|\
6095 + SNDRV_PCM_RATE_16000|SNDRV_PCM_RATE_22050|SNDRV_PCM_RATE_32000|\
6096 + SNDRV_PCM_RATE_44100|SNDRV_PCM_RATE_48000),
6097 + .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
6098 + SNDRV_PCM_FMTBIT_S24_LE),
6099 + },
6100 + .ops = &mt76xx_i2s_dai_ops,
6101 + .symmetric_rates = 1,
6102 +};
6103 +
6104 +/****************************/
6105 +/*FUNCTION BODY */
6106 +/****************************/
6107 +
6108 +static int mt76xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
6109 + unsigned int fmt)
6110 +{//TODO
6111 +
6112 + //printk("******* %s *******\n", __func__);
6113 + return 0;
6114 +}
6115 +
6116 +static int mt76xx_i2s_play_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
6117 +{
6118 + //printk("******* %s *******\n", __func__);
6119 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
6120 + rtd->pss[SNDRV_PCM_STREAM_PLAYBACK] = substream;
6121 + if(! rtd->i2sStat[SNDRV_PCM_STREAM_PLAYBACK]){
6122 + i2s_reset_tx_param( rtd);
6123 + i2s_tx_config( rtd);
6124 + gdma_En_Switch(rtd, STREAM_PLAYBACK, GDMA_I2S_EN);
6125 +
6126 + if( rtd->bRxDMAEnable==0)
6127 + i2s_clock_enable( rtd);
6128 +
6129 + i2s_tx_enable( rtd);
6130 + rtd->i2sStat[SNDRV_PCM_STREAM_PLAYBACK] = 1;
6131 + MSG("I2S_TXENABLE done\n");
6132 + }
6133 +
6134 + return 0;
6135 +}
6136 +
6137 +static int mt76xx_i2s_rec_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
6138 +{
6139 +
6140 + //printk("******* %s *******\n", __func__);
6141 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
6142 + rtd->pss[SNDRV_PCM_STREAM_CAPTURE] = substream;
6143 + if(! rtd->i2sStat[SNDRV_PCM_STREAM_CAPTURE]) {
6144 + i2s_reset_rx_param(rtd);
6145 + i2s_rx_config(rtd);
6146 + gdma_En_Switch(rtd, STREAM_CAPTURE, GDMA_I2S_EN);
6147 +
6148 + if(rtd->bTxDMAEnable==0)
6149 + i2s_clock_enable(rtd);
6150 +
6151 + i2s_rx_enable(rtd);
6152 + rtd->i2sStat[SNDRV_PCM_STREAM_CAPTURE] = 1;
6153 + }
6154 + return 0;
6155 +}
6156 +
6157 +/*static int mt76xx_i2s_shutdown(struct snd_pcm_substream *substream,
6158 + struct snd_soc_dai *dai)
6159 +{
6160 + //i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
6161 + //printk("******* %s *******\n", __func__);
6162 + return 0;
6163 +}
6164 +*/
6165 +static int mt76xx_i2s_startup(struct snd_pcm_substream *substream,
6166 + struct snd_soc_dai *dai)
6167 +{
6168 +
6169 + //printk("******* %s *******\n", __func__);
6170 + if((!pi2s_config->i2sStat[SNDRV_PCM_STREAM_PLAYBACK]) && (!pi2s_config->i2sStat[SNDRV_PCM_STREAM_CAPTURE])){
6171 + i2s_startup();
6172 + if(!pi2s_config)
6173 + return -1;
6174 + i2s_reset_config(pi2s_config);
6175 + }
6176 + substream->runtime->private_data = pi2s_config;
6177 + return 0;
6178 +}
6179 +
6180 +static int mt76xx_i2s_hw_params(struct snd_pcm_substream *substream,\
6181 + struct snd_pcm_hw_params *params,\
6182 + struct snd_soc_dai *dai){
6183 + unsigned int srate = 0;
6184 + //unsigned long data;
6185 + struct snd_pcm_runtime *runtime = substream->runtime;
6186 + i2s_config_type* rtd = runtime->private_data;
6187 +
6188 + //printk("******* %s *******\n", __func__);
6189 + switch(params_rate(params)){
6190 + case 8000:
6191 + srate = 8000;
6192 + break;
6193 + case 16000:
6194 + srate = 16000;
6195 + break;
6196 + case 32000:
6197 + srate = 32000;
6198 + break;
6199 + case 44100:
6200 + srate = 44100;
6201 + break;
6202 + case 48000:
6203 + srate = 48000;
6204 + break;
6205 + default:
6206 + srate = 44100;
6207 + //MSG("audio sampling rate %u should be %d ~ %d Hz\n", (u32)params_rate(params), MIN_SRATE_HZ, MAX_SRATE_HZ);
6208 + break;
6209 + }
6210 + if(srate){
6211 + if((rtd->bRxDMAEnable != GDMA_I2S_EN) && (rtd->bTxDMAEnable != GDMA_I2S_EN)){
6212 + rtd->srate = srate;
6213 + MSG("set audio sampling rate to %d Hz\n", rtd->srate);
6214 + }
6215 + }
6216 +
6217 + return 0;
6218 +}
6219 +static int mt76xx_i2s_hw_free(struct snd_pcm_substream *substream,struct snd_soc_dai *dai){
6220 +
6221 + //printk("******* %s *******\n", __func__);
6222 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
6223 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
6224 + if(rtd->i2sStat[SNDRV_PCM_STREAM_PLAYBACK]){
6225 + MSG("I2S_TXDISABLE\n");
6226 + i2s_reset_tx_param(rtd);
6227 +
6228 + if((rtd->bRxDMAEnable==0)&&(rtd->bTxDMAEnable==0)){
6229 + i2s_clock_disable(rtd);
6230 + }
6231 + rtd->i2sStat[SNDRV_PCM_STREAM_PLAYBACK] = 0;
6232 + }
6233 + }
6234 + else{
6235 + if(rtd->i2sStat[SNDRV_PCM_STREAM_CAPTURE]){
6236 + MSG("I2S_RXDISABLE\n");
6237 + i2s_reset_rx_param(rtd);
6238 +
6239 + if((rtd->bRxDMAEnable==0)&&(rtd->bTxDMAEnable==0)){
6240 + i2s_clock_disable(rtd);
6241 + }
6242 + rtd->i2sStat[SNDRV_PCM_STREAM_CAPTURE] = 0;
6243 + }
6244 + }
6245 + return 0;
6246 +}
6247 +static int mt76xx_i2s_prepare(struct snd_pcm_substream *substream,struct snd_soc_dai *dai)
6248 +{
6249 +
6250 + //printk("******* %s *******\n", __func__);
6251 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
6252 + return mt76xx_i2s_play_prepare(substream, dai);
6253 + else
6254 + return mt76xx_i2s_rec_prepare(substream, dai);
6255 +
6256 + return 0;
6257 +}
6258 +
6259 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,20)
6260 +static int mt76xx_i2s_drv_probe(struct platform_device *pdev)
6261 +{
6262 + //printk("****** %s ******\n", __func__);
6263 + return snd_soc_register_component(&pdev->dev, &mt76xx_i2s_component,
6264 + &mt76xx_i2s_dai, 1);
6265 +}
6266 +
6267 +static int mt76xx_i2s_drv_remove(struct platform_device *pdev)
6268 +{
6269 + snd_soc_unregister_component(&pdev->dev);
6270 + return 0;
6271 +}
6272 +
6273 +static struct platform_driver mt76xx_i2s_driver = {
6274 + .probe = mt76xx_i2s_drv_probe,
6275 + .remove = mt76xx_i2s_drv_remove,
6276 + .driver = {
6277 + .name = "mt76xx-i2s",
6278 + .owner = THIS_MODULE,
6279 + },
6280 +};
6281 +
6282 +static int __init mt76xx_i2s_init(void)
6283 +{
6284 +
6285 + //printk("****** %s ******\n", __func__);
6286 + return platform_driver_register(&mt76xx_i2s_driver);
6287 +}
6288 +
6289 +static void __exit mt76xx_i2s_exit(void)
6290 +{
6291 + //printk("****** %s ******\n", __func__);
6292 + platform_driver_unregister(&mt76xx_i2s_driver);
6293 +}
6294 +
6295 +module_init(mt76xx_i2s_init);
6296 +module_exit(mt76xx_i2s_exit);
6297 +
6298 +MODULE_AUTHOR("Dora Chen");
6299 +MODULE_DESCRIPTION("Stretch MT76xx I2S Interface");
6300 +MODULE_LICENSE("GPL");
6301 +#endif
6302 --- /dev/null
6303 +++ b/sound/soc/mtk/mt76xx_i2s.h
6304 @@ -0,0 +1,18 @@
6305 +/*
6306 + * mtk_i2s.h
6307 + *
6308 + * Created on: 2013/8/20
6309 + * Author: MTK04880
6310 + */
6311 +
6312 +#ifndef MTK_I2S_H_
6313 +#define MTK_I2S_H_
6314 +
6315 +
6316 +#ifdef __KERNEL__
6317 +//#include <asm/rt2880/rt_mmap.h>
6318 +#include <linux/fs.h>
6319 +#endif
6320 +
6321 +#include "i2s_ctrl.h"
6322 +#endif /* MTK_I2S_H_ */
6323 --- /dev/null
6324 +++ b/sound/soc/mtk/mt76xx_machine.c
6325 @@ -0,0 +1,317 @@
6326 +/*
6327 + * mt76xx_machine.c
6328 + *
6329 + */
6330 +#include <linux/init.h>
6331 +#include <linux/version.h>
6332 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
6333 +#include <linux/sched.h>
6334 +#endif
6335 +#include <linux/module.h>
6336 +#include <linux/kernel.h> /* printk() */
6337 +#include <linux/slab.h> /* kmalloc() */
6338 +#include <linux/fs.h> /* everything... */
6339 +#include <linux/errno.h> /* error codes */
6340 +#include <linux/types.h> /* size_t */
6341 +#include <linux/proc_fs.h>
6342 +#include <linux/fcntl.h> /* O_ACCMODE */
6343 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36)
6344 +#include <asm/system.h> /* cli(), *_flags */
6345 +#endif
6346 +#include <asm/uaccess.h> /* copy_from/to_user */
6347 +#include <linux/interrupt.h>
6348 +#include <linux/mm.h>
6349 +#include <linux/dma-mapping.h>
6350 +#include <sound/core.h>
6351 +#include <linux/pci.h>
6352 +#include <sound/pcm.h>
6353 +#include <sound/pcm_params.h>
6354 +#include <sound/soc.h>
6355 +#include <sound/soc-dapm.h>
6356 +#include <sound/initval.h>
6357 +#include <linux/i2c.h>
6358 +#include <linux/ioport.h>
6359 +#include <linux/delay.h>
6360 +#include "ralink_gdma.h"
6361 +#include "mt76xx_i2s.h"
6362 +#include "mt76xx_machine.h"
6363 +#if defined(CONFIG_SND_SOC_WM8960)
6364 +#include "../codecs/wm8960.h"
6365 +#endif
6366 +
6367 +#define I2C_AUDIO_DEV_ID (0)
6368 +/****************************/
6369 +/*FUNCTION DECLRATION */
6370 +/****************************/
6371 +extern unsigned long i2s_codec_12p288Mhz[11];
6372 +extern unsigned long i2s_codec_12Mhz[11];
6373 +
6374 +
6375 +static int mt76xx_codec_clock_hwparams(struct snd_pcm_substream *substream,\
6376 + struct snd_pcm_hw_params *params);
6377 +static int mt76xx_codec_startup(struct snd_pcm_substream *substream);
6378 +static int mt76xx_codec_init(struct snd_soc_pcm_runtime *rtd);
6379 +extern struct snd_soc_dai_driver mt76xx_i2s_dai;
6380 +extern struct snd_soc_platform_driver mt76xx_soc_platform;
6381 +struct platform_device *mt76xx_audio_device;
6382 +
6383 +#if defined(CONFIG_SND_SOC_WM8960)
6384 +extern struct snd_soc_dai wm8960_dai;
6385 +extern struct snd_soc_codec_device soc_codec_dev_wm8960;
6386 +#endif
6387 +
6388 +static struct snd_soc_ops mtk_audio_ops = {
6389 + .hw_params = mt76xx_codec_clock_hwparams,
6390 + .startup = mt76xx_codec_startup,
6391 +};
6392 +
6393 +static struct snd_soc_dai_link mtk_audio_dai = {
6394 + .name = "mtk_dai",
6395 + .stream_name = "WMserious PCM",
6396 + .cpu_dai_name = "mt76xx-i2s",
6397 + .codec_dai_name = "wm8960-hifi",
6398 + .codec_name = "wm8960.0-001a",
6399 + .platform_name = "mt76xx-pcm",
6400 + .ignore_pmdown_time = true,
6401 + .init = mt76xx_codec_init,
6402 + .ops = &mtk_audio_ops,
6403 +};
6404 +
6405 +static struct snd_soc_card mtk_audio_card = {
6406 + .name = "MTK APSoC I2S",
6407 + .owner = THIS_MODULE,
6408 + .dai_link = &mtk_audio_dai,//I2S/Codec
6409 + .num_links = 1,
6410 +};
6411 +
6412 +static int mt76xx_codec_clock_hwparams(struct snd_pcm_substream *substream,
6413 + struct snd_pcm_hw_params *params)
6414 +{
6415 + struct snd_soc_pcm_runtime *p = substream->private_data;
6416 + struct snd_soc_dai *codec_dai = p->codec_dai;
6417 + struct snd_pcm_runtime *runtime = substream->runtime;
6418 + i2s_config_type* rtd = runtime->private_data;
6419 + unsigned long data,index = 0;
6420 + unsigned long* pTable;
6421 + int mclk,ret,targetClk = 0;
6422 +
6423 + /*For duplex mode, avoid setting twice.*/
6424 + if((rtd->bRxDMAEnable == GDMA_I2S_EN) || (rtd->bTxDMAEnable == GDMA_I2S_EN))
6425 + return 0;
6426 +#if defined(CONFIG_I2S_MCLK_12MHZ)
6427 + mclk = 12000000;
6428 +#elif defined(CONFIG_I2S_MCLK_12P288MHZ)
6429 + mclk = 12288000;
6430 +#else
6431 + mclk = 12000000;
6432 +#endif
6433 + //snd_soc_dai_set_sysclk(codec_dai,0,mclk, SND_SOC_CLOCK_IN);
6434 +
6435 + switch(params_rate(params)){
6436 + case 8000:
6437 + index = 0;
6438 + targetClk = 12288000;
6439 + break;
6440 + case 12000:
6441 + index = 2;
6442 + targetClk = 12288000;
6443 + break;
6444 + case 16000:
6445 + index = 3;
6446 + targetClk = 12288000;
6447 + break;
6448 + case 24000:
6449 + index = 5;
6450 + targetClk = 12288000;
6451 + break;
6452 + case 32000:
6453 + index = 6;
6454 + targetClk = 12288000;
6455 + break;
6456 + case 48000:
6457 + index = 8;
6458 + targetClk = 12288000;
6459 + break;
6460 + case 11025:
6461 + index = 1;
6462 + targetClk = 11289600;
6463 + break;
6464 + case 22050:
6465 + index = 4;
6466 + targetClk = 11289600;
6467 + break;
6468 + case 44100:
6469 + index = 7;
6470 + targetClk = 11289600;
6471 + break;
6472 + case 88200:
6473 + index = 9;
6474 + targetClk = 11289600;
6475 + break;
6476 + case 96000:
6477 + index = 10;
6478 + targetClk = 11289600;
6479 + break;
6480 + default:
6481 + index = 7;
6482 + targetClk = 12288000;
6483 + //MSG("audio sampling rate %u should be %d ~ %d Hz\n", (u32)params_rate(params), MIN_SRATE_HZ, MAX_SRATE_HZ);
6484 + break;
6485 + }
6486 +#if defined(CONFIG_SND_SOC_WM8960)
6487 + /*
6488 + * There is a fixed divide by 4 in the PLL and a selectable
6489 + * divide by N after the PLL which should be set to divide by 2 to meet this requirement.
6490 + * */
6491 + ret = snd_soc_dai_set_pll(codec_dai, 0, 0,mclk, targetClk*2);
6492 + /* From app notes: allow Vref to stabilize to reduce clicks */
6493 + if(rtd->slave_en){
6494 + //printk("WM8960 is in master mode\n");
6495 + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_DCLKDIV, 0x1c4);
6496 + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_SYSCLKDIV, 0x5);
6497 + }
6498 +
6499 +#endif
6500 + if(!rtd->slave_en)
6501 + snd_soc_dai_set_fmt(codec_dai,SND_SOC_DAIFMT_CBS_CFS|SND_SOC_DAIFMT_I2S|SND_SOC_DAIFMT_NB_NF);
6502 + else{
6503 + snd_soc_dai_set_fmt(codec_dai,SND_SOC_DAIFMT_CBM_CFM|SND_SOC_DAIFMT_I2S|SND_SOC_DAIFMT_NB_NF);
6504 + }
6505 + mdelay(5);
6506 +
6507 +#if defined(CONFIG_SND_SOC_WM8960)
6508 +#if defined(CONFIG_I2S_MCLK_12MHZ)
6509 + pTable = i2s_codec_12Mhz;
6510 + data = pTable[index];
6511 +#else
6512 + pTable = i2s_codec_12p288Mhz;
6513 + data = pTable[index];
6514 +#endif
6515 + if(rtd->codec_pll_en)
6516 + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_DACDIV, (data<<3)|0x5);
6517 + else
6518 + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8960_DACDIV, (data<<3|0x4));
6519 +#endif
6520 +
6521 + return 0;
6522 +}
6523 +
6524 +static int mt76xx_codec_startup(struct snd_pcm_substream *substream)
6525 +{
6526 + //printk("******* %s *******\n", __func__);
6527 + return 0;
6528 +}
6529 +static int mt76xx_codec_init(struct snd_soc_pcm_runtime *rtd)
6530 +{
6531 +
6532 + //printk("******* %s *******\n", __func__);
6533 + return 0;
6534 +}
6535 +
6536 +static struct i2c_board_info i2c_board_info[] = {
6537 + {
6538 +#if defined(CONFIG_SND_SOC_WM8750)
6539 + I2C_BOARD_INFO("wm8750", (0x36 >> 1)),
6540 +#elif defined(CONFIG_SND_SOC_WM8960)
6541 + I2C_BOARD_INFO("codec_wm8960", (0x34)),
6542 + }, {
6543 + I2C_BOARD_INFO("wm8960", (0x34 >> 1)),
6544 +#endif
6545 + }
6546 +};
6547 +
6548 +static struct platform_device *soc_mtk_i2s_dev;
6549 +static struct platform_device *soc_mtk_pcm_dev;
6550 +
6551 +static int __init mt76xx_machine_init(void)
6552 +{
6553 + //struct snd_soc_device *socdev = &mtk_audio_devdata;
6554 + //struct i2c_adapter *adapter = NULL;
6555 + //struct i2c_client *client = NULL;
6556 + int ret = 0;
6557 + struct i2c_adapter *adapter = NULL;
6558 + struct i2c_client *client = NULL;
6559 +
6560 + adapter = i2c_get_adapter(I2C_AUDIO_DEV_ID);
6561 + if (!adapter)
6562 + return -ENODEV;
6563 + client = i2c_new_device(adapter, &i2c_board_info[0]);
6564 + if (!client)
6565 + return -ENODEV;
6566 + i2c_get_clientdata(client);
6567 +
6568 + client = i2c_new_device(adapter, &i2c_board_info[1]);
6569 + if (!client)
6570 + return -ENODEV;
6571 + i2c_get_clientdata(client);
6572 +
6573 + i2c_put_adapter(adapter);
6574 +
6575 + soc_mtk_i2s_dev =
6576 + platform_device_register_simple("mt76xx-i2s", -1, NULL, 0);
6577 + if (IS_ERR(soc_mtk_i2s_dev))
6578 + return PTR_ERR(soc_mtk_i2s_dev);
6579 +
6580 + soc_mtk_pcm_dev =
6581 + platform_device_register_simple("mt76xx-pcm", -1, NULL, 0);
6582 + if (IS_ERR(soc_mtk_pcm_dev))
6583 + return PTR_ERR(soc_mtk_pcm_dev);
6584 +
6585 + mt76xx_audio_device = platform_device_alloc("soc-audio",-1);
6586 + if (mt76xx_audio_device == NULL) {
6587 + ret = -ENOMEM;
6588 + goto err_device_alloc;
6589 + }
6590 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
6591 + platform_set_drvdata(mt76xx_audio_device, &mtk_audio_card);
6592 +#else
6593 + platform_set_drvdata(mt76xx_audio_device, &mtk_audio_devdata);
6594 + mtk_audio_devdata.dev = &mt76xx_audio_device->dev;
6595 +#endif
6596 +
6597 + /*Ralink I2S register process end*/
6598 + ret = platform_device_add(mt76xx_audio_device);
6599 + if (ret) {
6600 + printk("mtk audio device : platform_device_add failed (%d)\n",ret);
6601 + goto err_device_add;
6602 + }
6603 +
6604 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
6605 +#else
6606 + snd_soc_register_dai(&mt76xx_i2s_dai);
6607 +#endif
6608 +
6609 + return 0;
6610 +
6611 +err_device_add:
6612 + if (mt76xx_audio_device!= NULL) {
6613 + platform_device_put(mt76xx_audio_device);
6614 + mt76xx_audio_device = NULL;
6615 + }
6616 +err_device_alloc:
6617 + return ret;
6618 +}
6619 +
6620 +
6621 +static void __exit mt76xx_machine_exit(void)
6622 +{
6623 +
6624 + platform_device_unregister(mt76xx_audio_device);
6625 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,20)
6626 + /* Do nothing */
6627 +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
6628 + snd_soc_unregister_platform(&mt76xx_audio_device->dev);
6629 +#else
6630 + snd_soc_unregister_platform(&mt76xx_soc_platform);
6631 +#endif
6632 + platform_device_unregister(soc_mtk_i2s_dev);
6633 + platform_device_unregister(soc_mtk_pcm_dev);
6634 +
6635 + mt76xx_audio_device = NULL;
6636 +}
6637 +
6638 +//module_init(mt76xx_machine_init);
6639 +late_initcall(mt76xx_machine_init);
6640 +module_exit(mt76xx_machine_exit);
6641 +//EXPORT_SYMBOL_GPL(mt76xx_soc_platform);
6642 +MODULE_LICENSE("GPL");
6643 --- /dev/null
6644 +++ b/sound/soc/mtk/mt76xx_machine.h
6645 @@ -0,0 +1,21 @@
6646 +/*
6647 + * mtk_audio_device.h
6648 + *
6649 + * Created on: 2013/10/23
6650 + * Author: MTK04880
6651 + */
6652 +
6653 +#ifndef MT76XX_MACHINE_H_
6654 +#define MT76XX_MACHINE_H_
6655 +#include <sound/pcm.h>
6656 +#include <sound/pcm_params.h>
6657 +#include <sound/soc.h>
6658 +#include <sound/soc-dapm.h>
6659 +
6660 +#if 0
6661 +#ifdef CONFIG_I2S_MMAP
6662 +#undef CONFIG_I2S_MMAP
6663 +#endif
6664 +#endif
6665 +
6666 +#endif /* MT76XX_MACHINE_H_ */
6667 --- /dev/null
6668 +++ b/sound/soc/mtk/mt76xx_pcm.c
6669 @@ -0,0 +1,499 @@
6670 +/*
6671 + * mt76xx_pcm.c
6672 + *
6673 + * Created on: 2013/9/6
6674 + * Author: MTK04880
6675 + */
6676 +
6677 +#include <linux/init.h>
6678 +#include <linux/version.h>
6679 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
6680 +#include <linux/sched.h>
6681 +#endif
6682 +#include <linux/module.h>
6683 +#include <linux/kernel.h> /* printk() */
6684 +#include <linux/slab.h> /* kmalloc() */
6685 +#include <linux/fs.h> /* everything... */
6686 +#include <linux/errno.h> /* error codes */
6687 +#include <linux/types.h> /* size_t */
6688 +#include <linux/proc_fs.h>
6689 +#include <linux/fcntl.h> /* O_ACCMODE */
6690 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36)
6691 +#include <asm/system.h> /* cli(), *_flags */
6692 +#endif
6693 +#include <asm/uaccess.h> /* copy_from/to_user */
6694 +#include <linux/interrupt.h>
6695 +#include <linux/mm.h>
6696 +#include <linux/dma-mapping.h>
6697 +#include <sound/core.h>
6698 +#include <linux/pci.h>
6699 +#include <sound/pcm.h>
6700 +#include <sound/pcm_params.h>
6701 +#include <sound/soc.h>
6702 +#include <sound/soc-dapm.h>
6703 +#include <sound/initval.h>
6704 +#include "ralink_gdma.h"
6705 +#include "mt76xx_i2s.h"
6706 +
6707 +#define GDMA_PAGE_SIZE I2S_PAGE_SIZE
6708 +#define GDMA_PAGE_NUM MAX_I2S_PAGE
6709 +#define GDMA_TOTAL_PAGE_SIZE I2S_TOTAL_PAGE_SIZE
6710 +
6711 +dma_addr_t i2s_txdma_addr, i2s_rxdma_addr;
6712 +dma_addr_t i2s_mmap_addr[GDMA_PAGE_NUM*2];
6713 +
6714 +extern struct tasklet_struct i2s_tx_tasklet;
6715 +extern struct tasklet_struct i2s_rx_tasklet;
6716 +extern int i2s_mmap_remap(struct vm_area_struct *vma, unsigned long size);
6717 +extern void i2s_tx_end_sleep_on(i2s_config_type* ptri2s_config);
6718 +extern void i2s_rx_end_sleep_on(i2s_config_type* ptri2s_config);
6719 +
6720 +static int mt76xx_pcm_open(struct snd_pcm_substream *substream);
6721 +static int mt76xx_pcm_new(struct snd_soc_pcm_runtime *rtd);
6722 +static void mt76xx_pcm_free(struct snd_pcm *pcm);
6723 +static int mt76xx_pcm_close(struct snd_pcm_substream *substream);
6724 +static snd_pcm_uframes_t mt76xx_pcm_pointer(struct snd_pcm_substream *substream);
6725 +static int mt76xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd);
6726 +static int mt76xx_pcm_prepare(struct snd_pcm_substream *substream);
6727 +static int mt76xx_pcm_hw_params(struct snd_pcm_substream *substream,\
6728 + struct snd_pcm_hw_params *hw_params);
6729 +static int mt76xx_pcm_copy(struct snd_pcm_substream *substream, int channel,\
6730 + snd_pcm_uframes_t pos,void __user *buf, snd_pcm_uframes_t count);
6731 +static int mt76xx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma);
6732 +static int mt76xx_pcm_hw_free(struct snd_pcm_substream *substream);
6733 +
6734 +static int mt76xx_pcm_free_dma_buffer(struct snd_pcm_substream *substream,int stream);
6735 +static int mt76xx_pcm_allocate_dma_buffer(struct snd_pcm_substream *substream,int stream);
6736 +
6737 +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,10,20)
6738 +static int mt76xx_platform_drv_probe(struct platform_device *pdev);
6739 +static int mt76xx_platform_drv_remove(struct platform_device *pdev);
6740 +#endif
6741 +
6742 +static const struct snd_pcm_hardware mt76xx_pcm_hwparam = {
6743 +#if defined(CONFIG_I2S_MMAP)
6744 + .info = (SNDRV_PCM_INFO_INTERLEAVED |
6745 + SNDRV_PCM_INFO_PAUSE |
6746 + SNDRV_PCM_INFO_RESUME |
6747 + SNDRV_PCM_INFO_MMAP |
6748 + SNDRV_PCM_INFO_MMAP_VALID),
6749 +#else
6750 + .info = (SNDRV_PCM_INFO_INTERLEAVED |
6751 + SNDRV_PCM_INFO_PAUSE |
6752 + SNDRV_PCM_INFO_RESUME),
6753 +#endif
6754 + .formats = SNDRV_PCM_FMTBIT_S16_LE,
6755 + .period_bytes_min = GDMA_PAGE_SIZE,
6756 + .period_bytes_max = GDMA_PAGE_SIZE,
6757 + .periods_min = 1,
6758 + .periods_max = GDMA_PAGE_NUM,
6759 + .buffer_bytes_max = GDMA_TOTAL_PAGE_SIZE,
6760 +};
6761 +
6762 +static struct snd_pcm_ops mt76xx_pcm_ops = {
6763 +
6764 + .open = mt76xx_pcm_open,
6765 + .ioctl = snd_pcm_lib_ioctl,
6766 + .hw_params = mt76xx_pcm_hw_params,
6767 + .hw_free = mt76xx_pcm_hw_free,
6768 + .trigger = mt76xx_pcm_trigger,
6769 + .prepare = mt76xx_pcm_prepare,
6770 + .pointer = mt76xx_pcm_pointer,
6771 + .close = mt76xx_pcm_close,
6772 +#if defined(CONFIG_I2S_MMAP)
6773 + .mmap = mt76xx_pcm_mmap,
6774 +#endif
6775 + .copy = mt76xx_pcm_copy,
6776 +};
6777 +#if LINUX_VERSION_CODE > KERNEL_VERSION(3,10,0)
6778 +struct snd_soc_platform_driver mt76xx_soc_platform = {
6779 + .ops = &mt76xx_pcm_ops,
6780 + .pcm_new = mt76xx_pcm_new,
6781 + .pcm_free = mt76xx_pcm_free,
6782 +};
6783 +#else
6784 +struct snd_soc_platform mt76xx_soc_platform = {
6785 + .name = "mtk-dma",
6786 + .pcm_ops = &mt76xx_pcm_ops,
6787 + .pcm_new = mt76xx_pcm_new,
6788 + .pcm_free = mt76xx_pcm_free,
6789 +};
6790 +#endif
6791 +
6792 +static int mt76xx_pcm_close(struct snd_pcm_substream *substream){
6793 +
6794 + //printk("******* %s *********\n", __func__);
6795 + return 0;
6796 +}
6797 +
6798 +static snd_pcm_uframes_t mt76xx_pcm_pointer(struct snd_pcm_substream *substream)
6799 +{
6800 + struct snd_pcm_runtime *runtime = substream->runtime;
6801 + i2s_config_type* rtd = runtime->private_data;
6802 + unsigned int offset = 0;
6803 + //int buff_frame_bond = bytes_to_frames(runtime, GDMA_PAGE_SIZE);
6804 + //printk("\n******* %s *********\n", __func__);
6805 +
6806 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
6807 + offset = bytes_to_frames(runtime, GDMA_PAGE_SIZE*rtd->tx_r_idx);
6808 + //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);
6809 + }
6810 + else{
6811 + offset = bytes_to_frames(runtime, GDMA_PAGE_SIZE*rtd->rx_w_idx);
6812 + //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);
6813 + }
6814 + return offset;
6815 +}
6816 +
6817 +
6818 +static int mt76xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
6819 +{
6820 + int ret = 0;
6821 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
6822 + //struct snd_pcm_runtime *runtime= substream->runtime;
6823 +
6824 + //printk("******* %s *********\n", __func__);
6825 +/* printk("trigger cmd:%s\n",(cmd==SNDRV_PCM_TRIGGER_START)?"START":\
6826 + (cmd==SNDRV_PCM_TRIGGER_RESUME)?"RESUME":\
6827 + (cmd==SNDRV_PCM_TRIGGER_PAUSE_RELEASE)?"PAUSE_RELEASE":\
6828 + (cmd==SNDRV_PCM_TRIGGER_STOP)?"STOP":\
6829 + (cmd==SNDRV_PCM_TRIGGER_SUSPEND)?"SUSPEND":\
6830 + (cmd==SNDRV_PCM_TRIGGER_PAUSE_PUSH)?"PAUSE_PUSH":"default");
6831 +*/
6832 + switch (cmd) {
6833 + case SNDRV_PCM_TRIGGER_START:
6834 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
6835 + rtd->bTrigger[SNDRV_PCM_STREAM_PLAYBACK] = 1;
6836 + } else {
6837 + rtd->bTrigger[SNDRV_PCM_STREAM_CAPTURE] = 1;
6838 + }
6839 + break;
6840 + case SNDRV_PCM_TRIGGER_STOP:
6841 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
6842 + rtd->bTrigger[SNDRV_PCM_STREAM_PLAYBACK] = 0;
6843 + } else {
6844 + rtd->bTrigger[SNDRV_PCM_STREAM_CAPTURE] = 0;
6845 + }
6846 + break;
6847 + case SNDRV_PCM_TRIGGER_RESUME:
6848 + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
6849 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
6850 + rtd->tx_pause_en = 0;
6851 + } else {
6852 + rtd->rx_pause_en = 0;
6853 + }
6854 + break;
6855 +
6856 + case SNDRV_PCM_TRIGGER_SUSPEND:
6857 + case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
6858 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
6859 + rtd->tx_pause_en = 1;
6860 + } else {
6861 + rtd->rx_pause_en = 1;
6862 + }
6863 + break;
6864 + default:
6865 + ret = -EINVAL;
6866 + break;
6867 + }
6868 + return ret;
6869 +}
6870 +
6871 +static int mt76xx_pcm_copy(struct snd_pcm_substream *substream, int channel,\
6872 + snd_pcm_uframes_t pos,void __user *buf, snd_pcm_uframes_t count)
6873 +{
6874 + struct snd_pcm_runtime *runtime= substream->runtime;
6875 + i2s_config_type* rtd = runtime->private_data;
6876 + int tx_w_idx = 0;
6877 + int rx_r_idx = 0;
6878 + char *hwbuf = NULL;
6879 +
6880 + //printk("******* %s *********\n", __func__);
6881 + hwbuf = runtime->dma_area + frames_to_bytes(runtime, pos);
6882 + //MSG("%s bur:%x\n",__func__,hwbuf);
6883 + //printk("hw_ptr:%d, buffer_size:%d, appl_prt:%d, boundary:%d\n",
6884 + // runtime->status->hw_ptr, runtime->buffer_size, runtime->control->appl_ptr, runtime->boundary);
6885 +
6886 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
6887 + rtd->tx_w_idx = (rtd->tx_w_idx+1)%MAX_I2S_PAGE;
6888 + tx_w_idx = rtd->tx_w_idx;
6889 + //printk("put TB[%d - %x] for user write\n",rtd->tx_w_idx,pos);
6890 + copy_from_user(rtd->pMMAPTxBufPtr[tx_w_idx], (char*)buf, I2S_PAGE_SIZE);
6891 + }
6892 + else{
6893 + rx_r_idx = rtd->rx_r_idx;
6894 + rtd->rx_r_idx = (rtd->rx_r_idx+1)%MAX_I2S_PAGE;
6895 + copy_to_user((char*)buf, rtd->pMMAPRxBufPtr[rx_r_idx], I2S_PAGE_SIZE);
6896 + }
6897 + return 0;
6898 +}
6899 +
6900 +static int mt76xx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma)
6901 +{
6902 + int ret;
6903 + unsigned long size;
6904 +
6905 + size = vma->vm_end-vma->vm_start;
6906 + printk("******* %s: size :%lx end:%lx start:%lx *******\n", __func__,size,vma->vm_end,vma->vm_start);
6907 + ret = i2s_mmap_remap(vma, size);
6908 +
6909 + return ret;
6910 +}
6911 +
6912 +
6913 +static int mt76xx_pcm_prepare(struct snd_pcm_substream *substream)
6914 +{
6915 + struct snd_pcm_runtime *runtime= substream->runtime;
6916 + i2s_config_type *rtd = (i2s_config_type*)runtime->private_data;
6917 + //runtime->buffer_size = GDMA_PAGE_NUM*GDMA_PAGE_SIZE;
6918 + //runtime->boundary = (GDMA_PAGE_NUM*GDMA_PAGE_SIZE)/4;
6919 +
6920 + //printk("******* %s *******\n", __func__);
6921 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
6922 + //printk("===== %s:%s:%d =====\n", __FILE__, __func__, __LINE__);
6923 + mt76xx_pcm_allocate_dma_buffer(substream,SNDRV_PCM_STREAM_PLAYBACK);
6924 +
6925 + if(! rtd->dmaStat[SNDRV_PCM_STREAM_PLAYBACK]){
6926 + i2s_page_prepare(rtd,STREAM_PLAYBACK);
6927 + tasklet_init(&i2s_tx_tasklet, i2s_tx_task, (u32)rtd);
6928 + rtd->dmaStat[SNDRV_PCM_STREAM_PLAYBACK] = 1;
6929 + gdma_unmask_handler(GDMA_I2S_TX0);
6930 + }
6931 + } else {
6932 + mt76xx_pcm_allocate_dma_buffer(substream,SNDRV_PCM_STREAM_CAPTURE);
6933 +
6934 + if(! rtd->dmaStat[SNDRV_PCM_STREAM_CAPTURE]){
6935 + i2s_page_prepare(rtd,STREAM_CAPTURE); /* TX:enLabel=1; RX:enLabel=2 */
6936 + tasklet_init(&i2s_rx_tasklet, i2s_rx_task, (u32)rtd);
6937 + rtd->dmaStat[SNDRV_PCM_STREAM_CAPTURE] = 1;
6938 + gdma_unmask_handler(GDMA_I2S_RX0);
6939 + }
6940 + }
6941 +
6942 + return 0;
6943 +}
6944 +
6945 +
6946 +static int mt76xx_pcm_hw_params(struct snd_pcm_substream *substream,
6947 + struct snd_pcm_hw_params *hw_params)
6948 +{
6949 + /*struct snd_pcm_runtime *runtime = substream->runtime;
6950 + i2s_config_type *rtd = (i2s_config_type*)runtime->private_data;
6951 + */
6952 + int ret,i;
6953 + ret = i = 0;
6954 +
6955 + //printk("******* %s *******\n", __func__);
6956 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
6957 + //i2s_page_prepare(rtd,STREAM_PLAYBACK);
6958 + } else {
6959 + //i2s_page_prepare(rtd,STREAM_CAPTURE);
6960 + }
6961 +
6962 + return ret;
6963 +}
6964 +
6965 +static int mt76xx_pcm_hw_free(struct snd_pcm_substream *substream)
6966 +{
6967 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
6968 + //struct snd_dma_buffer *buf = &substream->dma_buffer;
6969 +
6970 + //printk("******* %s *******\n", __func__);
6971 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK){
6972 + if(rtd->dmaStat[SNDRV_PCM_STREAM_PLAYBACK]){
6973 +
6974 + gdma_En_Switch(rtd,STREAM_PLAYBACK,GDMA_I2S_DIS);
6975 + i2s_tx_end_sleep_on(rtd);
6976 + tasklet_kill(&i2s_tx_tasklet);
6977 + i2s_tx_disable(rtd);
6978 + //mt76xx_pcm_free_dma_buffer(substream,substream->stream);
6979 + i2s_page_release(rtd,STREAM_PLAYBACK);
6980 + rtd->dmaStat[SNDRV_PCM_STREAM_PLAYBACK] = 0;
6981 + }
6982 + mt76xx_pcm_free_dma_buffer(substream,substream->stream);
6983 + }
6984 + else{
6985 + if(rtd->dmaStat[SNDRV_PCM_STREAM_CAPTURE]){
6986 +
6987 + gdma_En_Switch(rtd,STREAM_CAPTURE,GDMA_I2S_DIS);
6988 + i2s_tx_end_sleep_on(rtd);
6989 + tasklet_kill(&i2s_rx_tasklet);
6990 + i2s_rx_disable(rtd);
6991 + //mt76xx_pcm_free_dma_buffer(substream,substream->stream);
6992 + i2s_page_release(rtd,STREAM_CAPTURE);
6993 + rtd->dmaStat[SNDRV_PCM_STREAM_CAPTURE] = 0;
6994 + }
6995 + mt76xx_pcm_free_dma_buffer(substream,substream->stream);
6996 + }
6997 + return 0;
6998 +}
6999 +
7000 +static int mt76xx_pcm_free_dma_buffer(struct snd_pcm_substream *substream,
7001 + int stream)
7002 +{
7003 +
7004 + //struct snd_pcm_substream *substream = pcm->streams[stream].substream;
7005 + struct snd_dma_buffer *buf = &substream->dma_buffer;
7006 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
7007 +
7008 + //printk("******* %s *******\n", __func__);
7009 + if (!buf->area)
7010 + return 0;
7011 + if(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
7012 + i2s_memPool_free(rtd,STREAM_PLAYBACK);
7013 + else
7014 + i2s_memPool_free(rtd,STREAM_CAPTURE);
7015 + buf->area = NULL;
7016 + snd_pcm_set_runtime_buffer(substream, NULL);
7017 + return 0;
7018 +}
7019 +
7020 +static int mt76xx_pcm_allocate_dma_buffer(struct snd_pcm_substream *substream,
7021 + int stream)
7022 +{
7023 + //struct snd_pcm_substream *substream = pcm->streams[stream].substream;
7024 + struct snd_dma_buffer *buf = &substream->dma_buffer;
7025 + i2s_config_type* rtd = (i2s_config_type*)substream->runtime->private_data;
7026 +
7027 + //printk("******* %s *******\n", __func__);
7028 + if(!buf->area){
7029 +#if defined(CONFIG_I2S_MMAP)
7030 + printk("\n############## MMAP ##############\n");
7031 + buf->dev.type = SNDRV_DMA_TYPE_DEV;
7032 +#else
7033 + buf->dev.type = SNDRV_DMA_TYPE_UNKNOWN;
7034 +#endif
7035 + buf->dev.dev = NULL;
7036 + buf->private_data = NULL;
7037 + if(stream == SNDRV_PCM_STREAM_PLAYBACK)
7038 + buf->area = i2s_memPool_Alloc(rtd,STREAM_PLAYBACK);
7039 + else
7040 + buf->area = i2s_memPool_Alloc(rtd,STREAM_CAPTURE);
7041 +
7042 + if (!buf->area)
7043 + return -ENOMEM;
7044 + buf->bytes = GDMA_TOTAL_PAGE_SIZE;
7045 +#if defined(CONFIG_I2S_MMAP)
7046 + buf->addr = i2s_mmap_phys_addr(rtd);
7047 +#endif
7048 + snd_pcm_set_runtime_buffer(substream, buf);
7049 + } else{
7050 + //printk("Buffer have been allocated!\n");
7051 + }
7052 +
7053 + return 0;
7054 +}
7055 +
7056 +static int mt76xx_pcm_open(struct snd_pcm_substream *substream)
7057 +{
7058 + struct snd_pcm_runtime *runtime= substream->runtime;
7059 + struct snd_dma_buffer *buf = &substream->dma_buffer;
7060 + int stream = substream->stream;
7061 + int ret = 0;
7062 +
7063 + //printk("******* %s *******\n", __func__);
7064 + snd_soc_set_runtime_hwparams(substream, &mt76xx_pcm_hwparam);
7065 + /* ensure that buffer size is a multiple of period size */
7066 + ret = snd_pcm_hw_constraint_integer(runtime,
7067 + SNDRV_PCM_HW_PARAM_PERIODS);
7068 + if (ret < 0)
7069 + goto out;
7070 +
7071 +#if 1
7072 + if(stream == SNDRV_PCM_STREAM_PLAYBACK){
7073 + ret = mt76xx_pcm_allocate_dma_buffer(substream,
7074 + SNDRV_PCM_STREAM_PLAYBACK);
7075 + }
7076 + else{
7077 + ret = mt76xx_pcm_allocate_dma_buffer(substream,
7078 + SNDRV_PCM_STREAM_CAPTURE);
7079 + }
7080 +#endif
7081 +
7082 + if (ret)
7083 + goto out;
7084 +
7085 + if(buf)
7086 + memset(buf->area,0,sizeof(I2S_PAGE_SIZE*MAX_I2S_PAGE));
7087 +
7088 + out:
7089 + return ret;
7090 +}
7091 +
7092 +
7093 +
7094 +static int mt76xx_pcm_new(struct snd_soc_pcm_runtime *rtd)
7095 +{
7096 +// int ret = 0;
7097 +
7098 + //printk("******* %s *******\n", __func__);
7099 + return 0;
7100 +}
7101 +
7102 +static void mt76xx_pcm_free(struct snd_pcm *pcm)
7103 +{
7104 + /*struct snd_pcm_substream *substream;
7105 + struct snd_dma_buffer *buf;
7106 + i2s_config_type* rtd;
7107 + int stream;
7108 +*/
7109 + //printk("******* %s *******\n", __func__);
7110 + //return 0;
7111 +}
7112 +
7113 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,20)
7114 +static int mt76xx_platform_drv_probe(struct platform_device *pdev)
7115 +{
7116 + //printk("******* %s *******\n", __func__);
7117 + return snd_soc_register_platform(&pdev->dev, &mt76xx_soc_platform);
7118 +}
7119 +
7120 +static int mt76xx_platform_drv_remove(struct platform_device *pdev)
7121 +{
7122 + //printk("******* %s *******\n", __func__);
7123 + snd_soc_unregister_platform(&pdev->dev);
7124 + return 0;
7125 +}
7126 +
7127 +static struct platform_driver mt76xx_pcm_driver = {
7128 + .driver = {
7129 + .name = "mt76xx-pcm",
7130 + .owner = THIS_MODULE,
7131 + },
7132 +
7133 + .probe = mt76xx_platform_drv_probe,
7134 + .remove = mt76xx_platform_drv_remove,
7135 +};
7136 +
7137 +static int __init mt76xx_pcm_init(void)
7138 +{
7139 +
7140 + printk("******* %s *******\n", __func__);
7141 + return platform_driver_register(&mt76xx_pcm_driver);
7142 +}
7143 +
7144 +static void __exit mt76xx_pcm_exit(void)
7145 +{
7146 + platform_driver_unregister(&mt76xx_pcm_driver);
7147 +}
7148 +#else
7149 +static int __init mt76xx_pcm_init(void)
7150 +{
7151 +
7152 + printk("******* %s *******\n", __func__);
7153 + return snd_soc_register_platform(&mt76xx_soc_platform);
7154 +}
7155 +
7156 +static void __exit mt76xx_pcm_exit(void)
7157 +{
7158 + printk("******* %s *******\n", __func__);
7159 + snd_soc_unregister_platform(&mt76xx_soc_platform);
7160 +}
7161 +#endif
7162 +module_init(mt76xx_pcm_init);
7163 +module_exit(mt76xx_pcm_exit);
7164 +
7165 +MODULE_AUTHOR("Dora Chen");
7166 +MODULE_DESCRIPTION("MTK APSoC I2S DMA driver");
7167 +MODULE_LICENSE("GPL");
7168 +
7169 --- /dev/null
7170 +++ b/sound/soc/mtk/ralink_gdma.c
7171 @@ -0,0 +1,918 @@
7172 +/*
7173 + ***************************************************************************
7174 + * Ralink Tech Inc.
7175 + * 5F., No.36, Taiyuan St., Jhubei City,
7176 + * Hsinchu County 302,
7177 + * Taiwan, R.O.C.
7178 + *
7179 + * (c) Copyright, Ralink Technology, Inc.
7180 + *
7181 + * This program is free software; you can redistribute it and/or modify it
7182 + * under the terms of the GNU General Public License as published by the
7183 + * Free Software Foundation; either version 2 of the License, or (at your
7184 + * option) any later version.
7185 + *
7186 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
7187 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
7188 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
7189 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
7190 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
7191 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
7192 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
7193 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
7194 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
7195 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7196 + *
7197 + * You should have received a copy of the GNU General Public License along
7198 + * with this program; if not, write to the Free Software Foundation, Inc.,
7199 + * 675 Mass Ave, Cambridge, MA 02139, USA.
7200 + *
7201 + *
7202 + ***************************************************************************
7203 + *
7204 + Module Name:
7205 + ralink_gdma.c
7206 +
7207 + Abstract:
7208 +
7209 + Revision History:
7210 + Who When What
7211 + -------- ---------- ----------------------------------------------
7212 + Name Date Modification logs
7213 + Steven Liu 2009-03-24 Support RT3883
7214 + *
7215 + */
7216 +#include <linux/init.h>
7217 +#include <linux/version.h>
7218 +#include <linux/module.h>
7219 +#include <linux/kernel.h>
7220 +#include <linux/interrupt.h>
7221 +#include <linux/fs.h>
7222 +#if defined (CONFIG_MIPS)
7223 + #include <asm/uaccess.h>
7224 + #include <asm/addrspace.h>
7225 +#endif
7226 +
7227 +#include "ralink_gdma.h"
7228 +
7229 +/*
7230 + * RT305x:
7231 + * Ch0 : Pcm0_Rx0 | Pcm0_Rx0 | ALL
7232 + * Ch1 : Pcm0_Rx1 | Pcm0_Rx1 | ALL
7233 + * Ch2 : Pcm0_Tx0 | Pcm0_Tx0 | ALL
7234 + * Ch3 : Pcm0_Tx1 | Pcm0_Tx1 | ALL
7235 + * Ch4 : Pcm1_Rx0 | I2S_Tx0 | ALL
7236 + * Ch5 : Pcm1_Rx1 | I2S_Tx1 | ALL
7237 + * Ch6 : Pcm1_Tx0 | ALL | ALL
7238 + * Ch7 : Pcm1_Tx1 | ALL | ALL
7239 + *
7240 + * RT3883:
7241 + * Ch0 : Pcm0_Rx0 | Pcm0_Rx0 | ALL
7242 + * Ch1 : Pcm0_Rx1 | Pcm0_Rx1 | ALL
7243 + * Ch2 : Pcm0_Tx0 | Pcm0_Tx0 | ALL
7244 + * Ch3 : Pcm0_Tx1 | Pcm0_Tx1 | ALL
7245 + * Ch4 : Pcm1_Rx0 | I2S_Tx0 | ALL
7246 + * Ch5 : Pcm1_Rx1 | I2S_Tx1 | ALL
7247 + * Ch6 : Pcm1_Tx0 | I2S_Rx0 | ALL
7248 + * Ch7 : Pcm1_Tx1 | I2S_Rx1 | ALL
7249 + * Ch8 : ALL | ALL | ALL
7250 + * Ch9 : ALL | ALL | ALL
7251 + * Ch10 : ALL | ALL | ALL
7252 + * Ch11 : ALL | ALL | ALL
7253 + * Ch12 : ALL | ALL | ALL PCI TX
7254 + * Ch13 : ALL | ALL | ALL PCI RX
7255 + * Ch14 : ALL | ALL | ALL
7256 + * Ch15 : ALL | ALL | ALL
7257 + *
7258 + */
7259 +
7260 +spinlock_t gdma_lock;
7261 +spinlock_t gdma_lock_mem;
7262 +spinlock_t gdma_int_lock;
7263 +void (*GdmaDoneIntCallback[MAX_GDMA_CHANNEL])(uint32_t);
7264 +void (*GdmaUnMaskIntCallback[MAX_GDMA_CHANNEL])(uint32_t);
7265 +
7266 +
7267 +/**
7268 + * @brief Get free GDMA channel
7269 + *
7270 + * @param ChNum GDMA channel number
7271 + * @retval 1 channel is available
7272 + * @retval 0 channels are all busy
7273 + */
7274 +int _GdmaGetFreeCh(uint32_t *ChNum)
7275 +{
7276 + unsigned long flags;
7277 + uint32_t Data=0;
7278 + uint32_t Ch=0;
7279 +#if defined (CONFIG_GDMA_DEBUG)
7280 + static uint32_t Ch_RR=0;
7281 +#endif
7282 +
7283 + spin_lock_irqsave(&gdma_lock, flags);
7284 +
7285 +#if defined (CONFIG_GDMA_PCM_ONLY)
7286 +#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)
7287 + for(Ch=14; Ch<MAX_GDMA_CHANNEL;Ch++) //channel 14~max_channe, channel 0~13 be usedl
7288 +#else
7289 + for(Ch=MAX_GDMA_CHANNEL; Ch<MAX_GDMA_CHANNEL;Ch++) //no free channel
7290 +#endif
7291 +#elif defined (CONFIG_GDMA_PCM_I2S_OTHERS)
7292 +#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)
7293 + for(Ch=14; Ch<MAX_GDMA_CHANNEL;Ch++) //channel 14~max_channe, channel 0~13 be usedl
7294 +#else
7295 + for(Ch=6; Ch<MAX_GDMA_CHANNEL;Ch++) //channel 6~max_channel
7296 +#endif
7297 +#elif defined (CONFIG_GDMA_EVERYBODY)
7298 + for(Ch=0; Ch<MAX_GDMA_CHANNEL;Ch++) //all channel
7299 +#elif defined (CONFIG_GDMA_DEBUG)
7300 + for(Ch=(Ch_RR++)%MAX_GDMA_CHANNEL; Ch<MAX_GDMA_CHANNEL;Ch++) //round robin
7301 +#endif
7302 + {
7303 + Data=GDMA_READ_REG(GDMA_CTRL_REG(Ch));
7304 +
7305 + /* hardware will reset this bit if transaction is done.
7306 + * It means channel is free */
7307 + if((Data & (0x01<<CH_EBL_OFFSET))==0) {
7308 + *ChNum = Ch;
7309 + spin_unlock_irqrestore(&gdma_lock, flags);
7310 + return 1; //Channel is free
7311 + }
7312 + }
7313 +
7314 + spin_unlock_irqrestore(&gdma_lock, flags);
7315 + return 0; // Channels are all busy
7316 +
7317 +}
7318 +
7319 +/**
7320 + * @brief Set channel is masked
7321 + *
7322 + * When channel is masked, the GDMA transaction will stop.
7323 + * When GDMA controller comes back from another channel (chain feature)
7324 + *
7325 + * >> Channel Mask=0: It's strange, and turns on related bit in GDMA interrupt
7326 + * status register (16:23 Unmasked)
7327 + *
7328 + * >> Channel Mask=1: It'll start GDMA transation, and clear this bit.
7329 + *
7330 + * @param ChNum GDMA channel number
7331 + * @retval 1 success
7332 + * @retval 0 fail
7333 + */
7334 +int GdmaMaskChannel(uint32_t ChNum)
7335 +{
7336 + uint32_t Data=0;
7337 +
7338 + Data=GDMA_READ_REG(GDMA_CTRL_REG1(ChNum));
7339 + Data |= ( 0x01 << CH_MASK_OFFSET);
7340 + GDMA_WRITE_REG(GDMA_CTRL_REG1(ChNum), Data);
7341 + GDMA_PRINT("%s: Write %0X to %X\n", __FUNCTION__, Data, GDMA_CTRL_REG1(ChNum));
7342 +
7343 + return 1;
7344 +}
7345 +
7346 +/**
7347 + * @brief Set channel is unmasked
7348 + *
7349 + * You can unmask the channel to start GDMA transaction.
7350 + *
7351 + * When GDMA controller comes back from another channel (chain feature)
7352 + *
7353 + * >> Channel Mask=0: It's strange, and turns on related bit in GDMA interrupt
7354 + * status register (16:23 Unmasked)
7355 + *
7356 + * >> Channel Mask=1: It'll start GDMA transation, and clear this bit.
7357 + *
7358 + * @param ChNum GDMA channel number
7359 + * @retval 1 success
7360 + * @retval 0 fail
7361 + */
7362 +int GdmaUnMaskChannel(uint32_t ChNum)
7363 +{
7364 + uint32_t Data=0;
7365 +
7366 + Data=GDMA_READ_REG(GDMA_CTRL_REG1(ChNum));
7367 + Data &= ~( 0x01 << CH_MASK_OFFSET);
7368 + GDMA_WRITE_REG(GDMA_CTRL_REG1(ChNum), Data);
7369 + GDMA_PRINT("%s: Write %0X to %X\n", __FUNCTION__, Data, GDMA_CTRL_REG1(ChNum));
7370 +
7371 + return 1;
7372 +}
7373 +
7374 +/**
7375 + * @brief Insert new GDMA entry to start GDMA transaction
7376 + *
7377 + * @param ChNum GDMA channel number
7378 + * @retval 1 success
7379 + * @retval 0 fail
7380 + */
7381 +int GdmaReqQuickIns(uint32_t ChNum)
7382 +{
7383 + uint32_t Data=0;
7384 +
7385 + //Mask Channel
7386 + Data = GDMA_READ_REG(GDMA_CTRL_REG1(ChNum));
7387 + Data |= ( 0x1 << CH_MASK_OFFSET);
7388 + GDMA_WRITE_REG(GDMA_CTRL_REG1(ChNum), Data);
7389 +
7390 + //Channel Enable
7391 + Data = GDMA_READ_REG(GDMA_CTRL_REG(ChNum));
7392 + Data |= (0x01<<CH_EBL_OFFSET);
7393 + GDMA_WRITE_REG(GDMA_CTRL_REG(ChNum), Data);
7394 +
7395 + return 1;
7396 +
7397 +}
7398 +
7399 +int _GdmaReqEntryIns(GdmaReqEntry *NewEntry)
7400 +{
7401 + uint32_t Data=0;
7402 +
7403 + GDMA_PRINT("== << GDMA Control Reg (Channel=%d) >> ===\n", NewEntry->ChNum);
7404 + GDMA_PRINT(" Channel Source Addr = %x \n", NewEntry->Src);
7405 + GDMA_PRINT(" Channel Dest Addr = %x \n", NewEntry->Dst);
7406 + GDMA_PRINT(" Transfer Count=%d\n", NewEntry->TransCount);
7407 + GDMA_PRINT(" Source DMA Req= DMA_REQ%d\n", NewEntry->SrcReqNum);
7408 + GDMA_PRINT(" Dest DMA Req= DMA_REQ%d\n", NewEntry->DstReqNum);
7409 + GDMA_PRINT(" Source Burst Mode=%s\n", NewEntry->SrcBurstMode ? "Fix" : "Inc");
7410 + GDMA_PRINT(" Dest Burst Mode=%s\n", NewEntry->DstBurstMode ? "Fix" : "Inc");
7411 + GDMA_PRINT(" Burst Size=%s\n", NewEntry->BurstSize ==0 ? "1 transfer" : \
7412 + NewEntry->BurstSize ==1 ? "2 transfer" :\
7413 + NewEntry->BurstSize ==2 ? "4 transfer" :\
7414 + NewEntry->BurstSize ==3 ? "8 transfer" :\
7415 + NewEntry->BurstSize ==4 ? "16 transfer" :\
7416 + "Error");
7417 + GDMA_PRINT(" Hardware/Software Mode = %s\n", NewEntry->SoftMode ?
7418 + "Soft" : "Hw");
7419 + GDMA_PRINT("== << GDMA Control Reg1 (Channel=%d) >> =\n", NewEntry->ChNum);
7420 + GDMA_PRINT("Channel Done Interrput=%s\n", (NewEntry->DoneIntCallback!=NULL) ?
7421 + "Enable" : "Disable");
7422 + GDMA_PRINT("Channel Unmasked Int=%s\n", (NewEntry->UnMaskIntCallback!=NULL) ?
7423 + "Enable" : "Disable");
7424 +#if !defined (CONFIG_RALINK_RT3052) && !defined (CONFIG_RALINK_RT3883)
7425 + GDMA_PRINT("Coherent Interrupt =%s\n", (NewEntry->CoherentIntEbl==1)?
7426 + "Enable" : "Disable");
7427 +#endif
7428 + GDMA_PRINT("Next Unmasked Channel=%d\n", NewEntry->NextUnMaskCh);
7429 + GDMA_PRINT("Channel Mask=%d\n", NewEntry->ChMask);
7430 + GDMA_PRINT("========================================\n");
7431 +
7432 + GDMA_WRITE_REG(GDMA_SRC_REG(NewEntry->ChNum), NewEntry->Src);
7433 + GDMA_PRINT("SrcAddr: Write %0X to %X\n", \
7434 + NewEntry->Src, GDMA_SRC_REG(NewEntry->ChNum));
7435 +
7436 + GDMA_WRITE_REG(GDMA_DST_REG(NewEntry->ChNum), NewEntry->Dst);
7437 + GDMA_PRINT("DstAddr: Write %0X to %X\n", \
7438 + NewEntry->Dst, GDMA_DST_REG(NewEntry->ChNum));
7439 +
7440 + Data |= ( (NewEntry->NextUnMaskCh) << NEXT_UNMASK_CH_OFFSET);
7441 + Data |= ( NewEntry->ChMask << CH_MASK_OFFSET);
7442 +#if !defined (CONFIG_RALINK_RT3052) && !defined (CONFIG_RALINK_RT3883)
7443 + Data |= ( NewEntry->CoherentIntEbl << COHERENT_INT_EBL_OFFSET);
7444 +#endif
7445 +
7446 + if(NewEntry->UnMaskIntCallback!=NULL) {
7447 + Data |= (0x01<<CH_UNMASKINT_EBL_OFFSET);
7448 + GdmaUnMaskIntCallback[NewEntry->ChNum] = NewEntry->UnMaskIntCallback;
7449 + }
7450 +
7451 +#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)
7452 + Data |= (NewEntry->SrcReqNum << SRC_DMA_REQ_OFFSET);
7453 + Data |= (NewEntry->DstReqNum << DST_DMA_REQ_OFFSET);
7454 +#endif
7455 +
7456 + GDMA_WRITE_REG(GDMA_CTRL_REG1(NewEntry->ChNum), Data);
7457 + GDMA_PRINT("CTRL1: Write %08X to %8X\n", Data, GDMA_CTRL_REG1(NewEntry->ChNum));
7458 +
7459 + Data = ((NewEntry->TransCount) << TRANS_CNT_OFFSET);
7460 +#if defined (CONFIG_RALINK_RT3052)
7461 + Data |= (NewEntry->SrcReqNum << SRC_DMA_REQ_OFFSET);
7462 + Data |= (NewEntry->DstReqNum << DST_DMA_REQ_OFFSET);
7463 +#endif
7464 + Data |= (NewEntry->SrcBurstMode << SRC_BRST_MODE_OFFSET);
7465 + Data |= (NewEntry->DstBurstMode << DST_BRST_MODE_OFFSET);
7466 + Data |= (NewEntry->BurstSize << BRST_SIZE_OFFSET);
7467 +
7468 + if(NewEntry->DoneIntCallback!=NULL) {
7469 + Data |= (0x01<<CH_DONEINT_EBL_OFFSET);
7470 + GdmaDoneIntCallback[NewEntry->ChNum] = NewEntry->DoneIntCallback;
7471 + }
7472 +
7473 + if(NewEntry->SoftMode) {
7474 + Data |= (0x01<<MODE_SEL_OFFSET);
7475 + }
7476 +
7477 + Data |= (0x01<<CH_EBL_OFFSET);
7478 + GDMA_WRITE_REG(GDMA_CTRL_REG(NewEntry->ChNum), Data);
7479 + //GDMA_READ_REG(GDMA_CTRL_REG(NewEntry->ChNum));
7480 + GDMA_PRINT("CTRL: Write %08X to %8X\n", Data, GDMA_CTRL_REG(NewEntry->ChNum));
7481 + //if there is no interrupt handler, this function will
7482 + //return 1 until GDMA done.
7483 + if(NewEntry->DoneIntCallback==NULL) {
7484 + //wait for GDMA processing done
7485 +#if defined (CONFIG_RALINK_RT3052)
7486 + while((GDMA_READ_REG(RALINK_GDMAISTS) &
7487 + (0x1<<NewEntry->ChNum))==0);
7488 + //write 1 clear
7489 + GDMA_WRITE_REG(RALINK_GDMAISTS, 1<< NewEntry->ChNum);
7490 +#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)
7491 + while((GDMA_READ_REG(RALINK_GDMA_DONEINT) &
7492 + (0x1<<NewEntry->ChNum))==0);
7493 + //write 1 clear
7494 + GDMA_WRITE_REG(RALINK_GDMA_DONEINT, 1<< NewEntry->ChNum);
7495 +#endif
7496 + }
7497 +
7498 + return 1;
7499 +
7500 +}
7501 +
7502 +#if defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
7503 +/**
7504 + * @brief Start GDMA transaction for sending data to SPI
7505 + *
7506 + * @param *Src source address
7507 + * @param *Dst destination address
7508 +
7509 + * @param TransCount data length
7510 + * @param *DoneIntCallback callback function when transcation is done
7511 + * @param *UnMaskIntCallback callback func when ch mask field is incorrect
7512 + * @retval 1 success
7513 + * @retval 0 fail
7514 + */
7515 +int GdmaSpiTx(
7516 + uint32_t Src,
7517 + uint32_t Dst,
7518 + uint16_t TransCount,
7519 + void (*DoneIntCallback)(uint32_t data),
7520 + void (*UnMaskIntCallback)(uint32_t data)
7521 + )
7522 +{
7523 + GdmaReqEntry Entry;
7524 +
7525 + #if defined (CONFIG_MIPS)
7526 + Entry.Src= (Src & 0x1FFFFFFF);
7527 + Entry.Dst= (Dst & 0x1FFFFFFF);
7528 + #else
7529 + Entry.Src= Src;
7530 + Entry.Dst= Dst;
7531 + #endif
7532 + Entry.TransCount = TransCount;
7533 + Entry.SrcBurstMode=INC_MODE;
7534 + Entry.DstBurstMode=FIX_MODE;
7535 + Entry.BurstSize=BUSTER_SIZE_4B;
7536 + Entry.SrcReqNum=DMA_MEM_REQ;
7537 + Entry.DstReqNum=DMA_SPI_TX_REQ;
7538 + Entry.DoneIntCallback=DoneIntCallback;
7539 + Entry.UnMaskIntCallback=UnMaskIntCallback;
7540 + Entry.SoftMode=0;
7541 + Entry.ChMask=0;
7542 + Entry.CoherentIntEbl=0;
7543 +
7544 + //enable chain feature
7545 + Entry.ChNum = GDMA_SPI_TX;
7546 + Entry.NextUnMaskCh = GDMA_SPI_TX;
7547 +
7548 + return _GdmaReqEntryIns(&Entry);
7549 +}
7550 +
7551 +int GdmaSpiRx(
7552 + uint32_t Src,
7553 + uint32_t Dst,
7554 + uint16_t TransCount,
7555 + void (*DoneIntCallback)(uint32_t data),
7556 + void (*UnMaskIntCallback)(uint32_t data)
7557 + )
7558 +{
7559 + GdmaReqEntry Entry;
7560 +
7561 + #if defined (CONFIG_MIPS)
7562 + Entry.Src= (Src & 0x1FFFFFFF);
7563 + Entry.Dst= (Dst & 0x1FFFFFFF);
7564 + #else
7565 + Entry.Src= Src;
7566 + Entry.Dst= Dst;
7567 + #endif
7568 + Entry.TransCount = TransCount;
7569 + Entry.SrcBurstMode=FIX_MODE;
7570 + Entry.DstBurstMode=INC_MODE;
7571 + Entry.BurstSize=BUSTER_SIZE_4B;
7572 + Entry.SrcReqNum=DMA_SPI_RX_REQ;
7573 + Entry.DstReqNum=DMA_MEM_REQ;
7574 + Entry.DoneIntCallback=DoneIntCallback;
7575 + Entry.UnMaskIntCallback=UnMaskIntCallback;
7576 + Entry.SoftMode=0;
7577 + Entry.ChMask=0;
7578 + Entry.CoherentIntEbl=1;
7579 +
7580 +
7581 + //enable chain feature
7582 + Entry.ChNum=GDMA_SPI_RX;
7583 + Entry.NextUnMaskCh=GDMA_SPI_RX;
7584 +
7585 +
7586 + return _GdmaReqEntryIns(&Entry);
7587 +
7588 +}
7589 +#endif
7590 +
7591 +
7592 +/**
7593 + * @brief Start GDMA transaction for sending data to I2S
7594 + *
7595 + * @param *Src source address
7596 + * @param *Dst destination address
7597 + * @param TxNo I2S Tx number
7598 + * @param TransCount data length
7599 + * @param *DoneIntCallback callback function when transcation is done
7600 + * @param *UnMaskIntCallback callback func when ch mask field is incorrect
7601 + * @retval 1 success
7602 + * @retval 0 fail
7603 + */
7604 +int GdmaI2sTx(
7605 + uint32_t Src,
7606 + uint32_t Dst,
7607 + uint8_t TxNo,
7608 + uint16_t TransCount,
7609 + void (*DoneIntCallback)(uint32_t data),
7610 + void (*UnMaskIntCallback)(uint32_t data)
7611 + )
7612 +{
7613 + GdmaReqEntry Entry;
7614 +
7615 + #if defined (CONFIG_MIPS)
7616 + Entry.Src= (Src & 0x1FFFFFFF);
7617 + Entry.Dst= (Dst & 0x1FFFFFFF);
7618 + #else
7619 + Entry.Src= Src;
7620 + Entry.Dst= Dst;
7621 + #endif
7622 + Entry.TransCount = TransCount;
7623 + Entry.SrcBurstMode=INC_MODE;
7624 + Entry.DstBurstMode=FIX_MODE;
7625 + Entry.BurstSize=BUSTER_SIZE_4B;
7626 + Entry.SrcReqNum=DMA_MEM_REQ;
7627 + Entry.DstReqNum=DMA_I2S_TX_REQ;
7628 + Entry.DoneIntCallback=DoneIntCallback;
7629 + Entry.UnMaskIntCallback=UnMaskIntCallback;
7630 + Entry.SoftMode=0;
7631 + Entry.ChMask=1;
7632 + Entry.CoherentIntEbl=0;
7633 +
7634 + if(TxNo==0) { //TX0
7635 + //enable chain feature
7636 + Entry.ChNum=GDMA_I2S_TX0;
7637 + Entry.NextUnMaskCh= (TransCount==4) ? GDMA_I2S_TX0 : GDMA_I2S_TX1;
7638 + }else if(TxNo==1) { //TX1
7639 + //enable chain feature
7640 + Entry.ChNum=GDMA_I2S_TX1;
7641 + Entry.NextUnMaskCh= (TransCount==4) ? GDMA_I2S_TX1 : GDMA_I2S_TX0;
7642 + }else {
7643 + GDMA_PRINT("I2S Tx Number %x is invalid\n", TxNo);
7644 + return 0;
7645 + }
7646 +
7647 + return _GdmaReqEntryIns(&Entry);
7648 +
7649 +}
7650 +
7651 +
7652 +#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)
7653 +/**
7654 + * @brief Start GDMA transaction for receiving data to I2S
7655 + *
7656 + * @param *Src source address
7657 + * @param *Dst destination address
7658 + * @param TxNo I2S Tx number
7659 + * @param TransCount data length
7660 + * @param *DoneIntCallback callback function when transcation is done
7661 + * @param *UnMaskIntCallback callback func when ch mask field is incorrect
7662 + * @retval 1 success
7663 + * @retval 0 fail
7664 + */
7665 +int GdmaI2sRx(
7666 + uint32_t Src,
7667 + uint32_t Dst,
7668 + uint8_t RxNo,
7669 + uint16_t TransCount,
7670 + void (*DoneIntCallback)(uint32_t data),
7671 + void (*UnMaskIntCallback)(uint32_t data)
7672 + )
7673 +{
7674 + GdmaReqEntry Entry;
7675 + #if defined (CONFIG_MIPS)
7676 + Entry.Src= (Src & 0x1FFFFFFF);
7677 + Entry.Dst= (Dst & 0x1FFFFFFF);
7678 + #else
7679 + Entry.Src= Src;
7680 + Entry.Dst= Dst;
7681 + #endif
7682 + Entry.TransCount = TransCount;
7683 + Entry.SrcBurstMode=FIX_MODE;
7684 + Entry.DstBurstMode=INC_MODE;
7685 + Entry.BurstSize=BUSTER_SIZE_4B;
7686 + Entry.SrcReqNum=DMA_I2S_RX_REQ;
7687 + Entry.DstReqNum=DMA_MEM_REQ;
7688 + Entry.DoneIntCallback=DoneIntCallback;
7689 + Entry.UnMaskIntCallback=UnMaskIntCallback;
7690 + Entry.SoftMode=0;
7691 + Entry.ChMask=1;
7692 + Entry.CoherentIntEbl=1;
7693 +
7694 + if(RxNo==0) { //RX0
7695 + //enable chain feature
7696 + Entry.ChNum=GDMA_I2S_RX0;
7697 + Entry.NextUnMaskCh=(TransCount==4) ? GDMA_I2S_RX0 : GDMA_I2S_RX1;
7698 + }else if(RxNo==1) { //RX1
7699 + //enable chain feature
7700 + Entry.ChNum=GDMA_I2S_RX1;
7701 + Entry.NextUnMaskCh=(TransCount==4) ? GDMA_I2S_RX1 : GDMA_I2S_RX0;
7702 + }else {
7703 + GDMA_PRINT("I2S Rx Number %x is invalid\n", RxNo);
7704 + return 0;
7705 + }
7706 +
7707 + return _GdmaReqEntryIns(&Entry);
7708 +
7709 +}
7710 +
7711 +#endif
7712 +
7713 +/**
7714 + * @brief Start GDMA transaction for receiving data from PCM
7715 + *
7716 + * @param *Src source address
7717 + * @param *Dst destination address
7718 + * @param TransCount data length
7719 + * @param PcmNo PCM channel
7720 + * @param RxNo PCM Rx number
7721 + * @param *DoneIntCallback callback function when transcation is done
7722 + * @param *UnMaskIntCallback callback func when ch mask field is incorrect
7723 + * @retval 1 success
7724 + * @retval 0 fail
7725 + */
7726 +int GdmaPcmRx(
7727 + uint32_t Src,
7728 + uint32_t Dst,
7729 + uint8_t PcmNo,
7730 + uint8_t RxNo,
7731 + uint16_t TransCount,
7732 + void (*DoneIntCallback)(uint32_t data),
7733 + void (*UnMaskIntCallback)(uint32_t data)
7734 + )
7735 +{
7736 + GdmaReqEntry Entry;
7737 +
7738 + #if defined (CONFIG_MIPS)
7739 + Entry.Src= (Src & 0x1FFFFFFF);
7740 + Entry.Dst= (Dst & 0x1FFFFFFF);
7741 + #else
7742 + Entry.Src= Src;
7743 + Entry.Dst= Dst;
7744 + #endif
7745 + Entry.TransCount = TransCount;
7746 + Entry.SrcBurstMode=FIX_MODE;
7747 + Entry.DstBurstMode=INC_MODE;
7748 + Entry.BurstSize=BUSTER_SIZE_4B;
7749 + Entry.DstReqNum=DMA_MEM_REQ;
7750 + Entry.DoneIntCallback=DoneIntCallback;
7751 + Entry.UnMaskIntCallback=UnMaskIntCallback;
7752 + Entry.SoftMode=0;
7753 + Entry.ChMask=1;
7754 + Entry.CoherentIntEbl=1;
7755 +
7756 + if(RxNo > 2) {
7757 + GDMA_PRINT("PCM Rx Number %x is invalid\n", RxNo);
7758 + return 0;
7759 + }
7760 +
7761 + switch(PcmNo)
7762 + {
7763 + case 0:
7764 + Entry.SrcReqNum=DMA_PCM_RX0_REQ;
7765 + break;
7766 + case 1:
7767 + Entry.SrcReqNum=DMA_PCM_RX1_REQ;
7768 + break;
7769 +#if defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
7770 + case 2:
7771 + Entry.SrcReqNum=DMA_PCM_RX2_REQ;
7772 + break;
7773 + case 3:
7774 + Entry.SrcReqNum=DMA_PCM_RX3_REQ;
7775 + break;
7776 +#endif
7777 + default:
7778 + GDMA_PRINT("PCM Channel %x is invalid\n", PcmNo);
7779 + return 0;
7780 + }
7781 + Entry.ChNum=GDMA_PCM_RX(PcmNo,RxNo);
7782 + Entry.NextUnMaskCh=GDMA_PCM_RX(PcmNo,1-RxNo);
7783 +
7784 + return _GdmaReqEntryIns(&Entry);
7785 +
7786 +}
7787 +
7788 +/**
7789 + * @brief Start GDMA transaction for sending data to PCM
7790 + *
7791 + * @param *Src source address
7792 + * @param *Dst destination address
7793 + * @param TransCount data length
7794 + * @param PcmNo PCM channel
7795 + * @param TxNo PCM Tx number
7796 + * @param *DoneIntCallback callback func when transcation is done
7797 + * @param *UnMaskIntCallback callback func when ch mask field is incorrect
7798 + * @retval 1 success
7799 + * @retval 0 fail
7800 + */
7801 +int GdmaPcmTx(
7802 + uint32_t Src,
7803 + uint32_t Dst,
7804 + uint8_t PcmNo,
7805 + uint8_t TxNo,
7806 + uint16_t TransCount,
7807 + void (*DoneIntCallback)(uint32_t data),
7808 + void (*UnMaskIntCallback)(uint32_t data)
7809 + )
7810 +{
7811 + GdmaReqEntry Entry;
7812 +
7813 + #if defined (CONFIG_MIPS)
7814 + Entry.Src= (Src & 0x1FFFFFFF);
7815 + Entry.Dst= (Dst & 0x1FFFFFFF);
7816 + #else
7817 + Entry.Src= Src;
7818 + Entry.Dst= Dst;
7819 + #endif
7820 + Entry.TransCount = TransCount;
7821 + Entry.SrcBurstMode=INC_MODE;
7822 + Entry.DstBurstMode=FIX_MODE;
7823 + Entry.BurstSize=BUSTER_SIZE_4B;
7824 + Entry.SrcReqNum=DMA_MEM_REQ;
7825 + Entry.DoneIntCallback=DoneIntCallback;
7826 + Entry.UnMaskIntCallback=UnMaskIntCallback;
7827 + Entry.SoftMode=0; //Hardware Mode
7828 + Entry.ChMask=1;
7829 + Entry.CoherentIntEbl=0;
7830 +
7831 + if(TxNo > 2) {
7832 + GDMA_PRINT("PCM Tx Number %x is invalid\n", TxNo);
7833 + return 0;
7834 + }
7835 + switch(PcmNo)
7836 + {
7837 + case 0:
7838 + Entry.DstReqNum=DMA_PCM_TX0_REQ;
7839 + break;
7840 + case 1:
7841 + Entry.DstReqNum=DMA_PCM_TX1_REQ;
7842 + break;
7843 +#if defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
7844 + case 2:
7845 + Entry.DstReqNum=DMA_PCM_TX2_REQ;
7846 + break;
7847 + case 3:
7848 + Entry.DstReqNum=DMA_PCM_TX3_REQ;
7849 + break;
7850 +#endif
7851 + default:
7852 + GDMA_PRINT("PCM Channel %x is invalid\n", PcmNo);
7853 + return 0;
7854 + }
7855 + Entry.ChNum=GDMA_PCM_TX(PcmNo,TxNo);
7856 + Entry.NextUnMaskCh=GDMA_PCM_TX(PcmNo,1-TxNo);
7857 +
7858 + return _GdmaReqEntryIns(&Entry);
7859 +
7860 +}
7861 +
7862 +
7863 +/**
7864 + * @brief Start GDMA transaction for memory to memory copy
7865 + *
7866 + * @param *Src source address
7867 + * @param *Dst destination address
7868 + * @param TransCount data length
7869 + * @param *DoneIntCallback callback function when transcation is done
7870 + * @retval 1 success
7871 + * @retval 0 fail
7872 + */
7873 +int GdmaMem2Mem(
7874 + uint32_t Src,
7875 + uint32_t Dst,
7876 + uint16_t TransCount,
7877 + void (*DoneIntCallback)(uint32_t data)
7878 + )
7879 +
7880 +{
7881 +
7882 + GdmaReqEntry Entry;
7883 + #if defined (CONFIG_MIPS)
7884 + Entry.Src= (Src & 0x1FFFFFFF);
7885 + Entry.Dst= (Dst & 0x1FFFFFFF);
7886 + #else
7887 + Entry.Src= Src;
7888 + Entry.Dst= Dst;
7889 + #endif
7890 +
7891 + //Entry.Src= virt_to_phys(Src);
7892 + //Entry.Dst= virt_to_phys(Dst);
7893 +
7894 +
7895 +
7896 + Entry.TransCount = TransCount;
7897 + Entry.SrcBurstMode=INC_MODE;
7898 + Entry.DstBurstMode=INC_MODE;
7899 + Entry.BurstSize=BUSTER_SIZE_64B;
7900 + Entry.SrcReqNum=DMA_MEM_REQ;
7901 + Entry.DstReqNum=DMA_MEM_REQ;
7902 + Entry.DoneIntCallback=DoneIntCallback;
7903 + Entry.UnMaskIntCallback=NULL;
7904 + Entry.SoftMode=1;
7905 + Entry.ChMask=0;
7906 +
7907 + Entry.CoherentIntEbl=1;
7908 +
7909 + //No reserved channel for Memory to Memory GDMA,
7910 + //get free channel on demand
7911 + if(!_GdmaGetFreeCh(&Entry.ChNum)) {
7912 + GDMA_PRINT("GDMA Channels are all busy\n");
7913 + return 0;
7914 + }
7915 +
7916 +
7917 + //set next channel to their own channel
7918 + //to disable chain feature
7919 + Entry.NextUnMaskCh= Entry.ChNum;
7920 + //printk ("ChNum = %d\n", Entry.ChNum);
7921 + //set next channel to another channel
7922 + //to enable chain feature
7923 + //Entry.NextUnMaskCh= (Entry.ChNum+1) % MAX_GDMA_CHANNEL;
7924 +
7925 + return _GdmaReqEntryIns(&Entry);
7926 +
7927 +
7928 +}
7929 +
7930 +/**
7931 + * @brief GDMA interrupt handler
7932 + *
7933 + * When GDMA transcation is done, call related handler
7934 + * to do the remain job.
7935 + *
7936 + */
7937 +irqreturn_t GdmaIrqHandler(
7938 + int irq,
7939 + void *irqaction
7940 + )
7941 +{
7942 +
7943 + u32 Ch=0;
7944 + unsigned long flags;
7945 +#if defined (CONFIG_RALINK_RT3052)
7946 + u32 GdmaUnMaskStatus=GDMA_READ_REG(RALINK_GDMAISTS) & 0xFF0000;
7947 + u32 GdmaDoneStatus=GDMA_READ_REG(RALINK_GDMAISTS) & 0xFF;
7948 +#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)
7949 + u32 GdmaUnMaskStatus=GDMA_READ_REG(RALINK_GDMA_UNMASKINT);
7950 + u32 GdmaDoneStatus=GDMA_READ_REG(RALINK_GDMA_DONEINT);
7951 +#endif
7952 + //printk("********GDMA Interrupt*******************\n");
7953 +
7954 + //GDMA_PRINT("========================================\n");
7955 + //GDMA_PRINT("GdmaUnMask Interrupt=%x\n",GdmaUnMaskStatus);
7956 + //GDMA_PRINT("GdmaDone Interrupt=%x\n",GdmaDoneStatus);
7957 + //GDMA_PRINT("========================================\n");
7958 +
7959 + spin_lock_irqsave(&gdma_int_lock, flags);
7960 +
7961 + //write 1 clear
7962 +#if defined (CONFIG_RALINK_RT3052)
7963 + GDMA_WRITE_REG(RALINK_GDMAISTS, GdmaUnMaskStatus);
7964 +#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)
7965 + GDMA_WRITE_REG(RALINK_GDMA_UNMASKINT, GdmaUnMaskStatus);
7966 +#endif
7967 +
7968 + //UnMask error
7969 + for(Ch=0;Ch<MAX_GDMA_CHANNEL;Ch++) {
7970 +
7971 + if(GdmaUnMaskStatus & (0x1 << (UNMASK_INT_STATUS(Ch))) ) {
7972 + if(GdmaUnMaskIntCallback[Ch] != NULL) {
7973 + GdmaUnMaskIntCallback[Ch](Ch);
7974 + // printk("GdmaUnMaskIntCallback \n");
7975 + }
7976 + }
7977 + }
7978 +
7979 + //write 1 clear
7980 +#if defined (CONFIG_RALINK_RT3052)
7981 + GDMA_WRITE_REG(RALINK_GDMAISTS, GdmaDoneStatus);
7982 +#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)
7983 + GDMA_WRITE_REG(RALINK_GDMA_DONEINT, GdmaDoneStatus);
7984 +#endif
7985 +
7986 + //printk("interrupt status = %x \n", GdmaDoneStatus);
7987 + //processing done
7988 + for(Ch=0;Ch<MAX_GDMA_CHANNEL;Ch++) {
7989 + if(GdmaDoneStatus & (0x1<<Ch)) {
7990 + if(GdmaDoneIntCallback[Ch] != NULL) {
7991 + //printk("*************Interrupt Ch=%d***********\n", Ch);
7992 + GdmaDoneIntCallback[Ch](Ch);
7993 + }
7994 + }
7995 + }
7996 +
7997 +//printk("interrupt status clear = %x \n", GDMA_READ_REG(RALINK_GDMA_DONEINT));
7998 + spin_unlock_irqrestore(&gdma_int_lock, flags);
7999 +
8000 + return IRQ_HANDLED;
8001 +
8002 +}
8003 +
8004 +static int RalinkGdmaInit(void)
8005 +{
8006 +
8007 + uint32_t Ret=0;
8008 + uint32_t val = 0;
8009 + printk("Enable Ralink GDMA Controller Module \n");
8010 +#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)
8011 + printk("GDMA IP Version=%d\n", GET_GDMA_IP_VER);
8012 +#endif
8013 +spin_lock_init(&gdma_int_lock);
8014 +spin_lock_init(&gdma_lock);
8015 +//spin_lock_init(&gdma_lock_mem);
8016 +
8017 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
8018 + #if defined (CONFIG_MIPS)
8019 + Ret = request_irq(SURFBOARDINT_DMA, GdmaIrqHandler, \
8020 + IRQF_DISABLED, "Ralink_DMA", NULL);
8021 + #else
8022 + Ret = request_irq(SURFBOARDINT_DMA, GdmaIrqHandler, \
8023 + IRQF_TRIGGER_LOW, "Ralink_DMA", NULL);
8024 + #endif
8025 +#else
8026 + Ret = request_irq(SURFBOARDINT_DMA, GdmaIrqHandler, \
8027 + SA_INTERRUPT, "Ralink_DMA", NULL);
8028 +#endif
8029 +
8030 +/*
8031 + Ret = request_irq(131, GdmaIrqHandler, \
8032 + IRQF_TRIGGER_LOW, "Ralink_DMA", NULL);
8033 + */
8034 + if(Ret){
8035 + GDMA_PRINT("IRQ %d is not free.\n", SURFBOARDINT_DMA);
8036 + return 1;
8037 + }
8038 +
8039 +#if defined (CONFIG_MIPS)
8040 + //Enable GDMA interrupt
8041 + val = le32_to_cpu(*(volatile u32 *)(RALINK_REG_INTENA));
8042 + val |= RALINK_INTCTL_DMA;
8043 + GDMA_WRITE_REG(RALINK_REG_INTENA, val);
8044 +#endif
8045 +
8046 + //Channel0~Channel7 are round-robin
8047 +#if defined (CONFIG_RALINK_RT3052)
8048 + GDMA_WRITE_REG(RALINK_GDMAGCT, 0x01);
8049 +#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)
8050 + GDMA_WRITE_REG(RALINK_GDMA_GCT, 0x01);
8051 +#else
8052 +#error Please Choose System Type
8053 +#endif
8054 +
8055 + return 0;
8056 +}
8057 +
8058 +static void __exit RalinkGdmaExit(void)
8059 +{
8060 +
8061 + printk("Disable Ralink GDMA Controller Module\n");
8062 +#if defined (CONFIG_MIPS)
8063 + //Disable GDMA interrupt
8064 + GDMA_WRITE_REG(RALINK_REG_INTDIS, RALINK_INTCTL_DMA);
8065 +#endif
8066 + free_irq(SURFBOARDINT_DMA, NULL);
8067 +}
8068 +
8069 +module_init(RalinkGdmaInit);
8070 +module_exit(RalinkGdmaExit);
8071 +
8072 +EXPORT_SYMBOL(GdmaI2sRx);
8073 +EXPORT_SYMBOL(GdmaI2sTx);
8074 +EXPORT_SYMBOL(GdmaPcmRx);
8075 +EXPORT_SYMBOL(GdmaPcmTx);
8076 +#if defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
8077 +EXPORT_SYMBOL(GdmaSpiRx);
8078 +EXPORT_SYMBOL(GdmaSpiTx);
8079 +#endif
8080 +EXPORT_SYMBOL(GdmaMem2Mem);
8081 +EXPORT_SYMBOL(GdmaReqQuickIns);
8082 +EXPORT_SYMBOL(GdmaMaskChannel);
8083 +EXPORT_SYMBOL(GdmaUnMaskChannel);
8084 +
8085 +
8086 +MODULE_DESCRIPTION("Ralink SoC GDMA Controller API Module");
8087 +MODULE_AUTHOR("Steven Liu <steven_liu@ralinktech.com.tw>");
8088 +MODULE_LICENSE("GPL");
8089 +MODULE_VERSION(MOD_VERSION);
8090 --- /dev/null
8091 +++ b/sound/soc/mtk/ralink_gdma.h
8092 @@ -0,0 +1,326 @@
8093 +/*
8094 + ***************************************************************************
8095 + * Ralink Tech Inc.
8096 + * 5F., No.36, Taiyuan St., Jhubei City,
8097 + * Hsinchu County 302,
8098 + * Taiwan, R.O.C.
8099 + *
8100 + * (c) Copyright, Ralink Technology, Inc.
8101 + *
8102 + * This program is free software; you can redistribute it and/or modify it
8103 + * under the terms of the GNU General Public License as published by the
8104 + * Free Software Foundation; either version 2 of the License, or (at your
8105 + * option) any later version.
8106 + *
8107 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
8108 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
8109 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
8110 + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
8111 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
8112 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
8113 + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
8114 + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
8115 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
8116 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
8117 + *
8118 + * You should have received a copy of the GNU General Public License along
8119 + * with this program; if not, write to the Free Software Foundation, Inc.,
8120 + * 675 Mass Ave, Cambridge, MA 02139, USA.
8121 + *
8122 + *
8123 + ***************************************************************************
8124 + */
8125 +
8126 +#ifndef __RALINK_DMA_CTRL_H__
8127 +#define __RALINK_DMA_CTRL_H__
8128 +
8129 +//#include <asm/rt2880/rt_mmap.h>
8130 +
8131 +/*
8132 + * DEFINITIONS AND MACROS
8133 + */
8134 +#define MOD_VERSION "0.4"
8135 +
8136 +#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623)
8137 +#define MAX_GDMA_CHANNEL 16
8138 +#elif defined (CONFIG_RALINK_RT3052)
8139 +#define MAX_GDMA_CHANNEL 8
8140 +#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)
8141 +#define MAX_GDMA_CHANNEL 16
8142 +#else
8143 +#error Please Choose System Type
8144 +#endif
8145 +
8146 +
8147 +#define RALINK_GDMA_CTRL_BASE (RALINK_GDMA_BASE)
8148 +#if defined (CONFIG_RALINK_RT3052)
8149 +#define RALINK_GDMAISTS (RALINK_GDMA_BASE + 0x80)
8150 +#define RALINK_GDMAGCT (RALINK_GDMA_BASE + 0x88)
8151 +#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)
8152 +#define RALINK_GDMA_UNMASKINT (RALINK_GDMA_BASE + 0x200)
8153 +#define RALINK_GDMA_DONEINT (RALINK_GDMA_BASE + 0x204)
8154 +#define RALINK_GDMA_GCT (RALINK_GDMA_BASE + 0x220)
8155 +#endif
8156 +
8157 +#define KSEG1 0xa0000000
8158 +#define PHYS_TO_VIRT(x) ((void *)((x) | KSEG1))
8159 +#define VIRT_TO_PHYS(x) ((unsigned long)(x) & ~KSEG1)
8160 +
8161 +
8162 +
8163 +
8164 +#if defined (CONFIG_ARCH_MT7623)
8165 +#include <mach/sync_write.h>
8166 +#define GDMA_READ_REG(phys) (*(volatile unsigned int *)((phys)))
8167 +#define GDMA_WRITE_REG(phys, val) mt65xx_reg_sync_writel((val), (phys))
8168 +
8169 +#else
8170 +#define GDMA_READ_REG(addr) (le32_to_cpu(*(volatile u32 *)(addr)))
8171 +#define GDMA_WRITE_REG(addr, val) *((volatile uint32_t *)(addr)) = cpu_to_le32(val)
8172 +
8173 +
8174 +
8175 +#endif
8176 +
8177 +
8178 +#define GET_GDMA_IP_VER (GDMA_READ_REG(RALINK_GDMA_GCT) & 0x6) >> 1 //GDMA_GCT[2:1]
8179 +
8180 +#define RALINK_IRQ_ADDR RALINK_INTCL_BASE
8181 +#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7628)
8182 +#define RALINK_REG_INTENA (RALINK_IRQ_ADDR + 0x80)
8183 +#define RALINK_REG_INTDIS (RALINK_IRQ_ADDR + 0x78)
8184 +#else
8185 +#define RALINK_REG_INTENA (RALINK_IRQ_ADDR + 0x34)
8186 +#define RALINK_REG_INTDIS (RALINK_IRQ_ADDR + 0x38)
8187 +#endif
8188 +
8189 +/*
8190 + * 12bytes=GDMA Channel n Source Address(4) +
8191 + * GDMA Channel n Destination Address(4) +
8192 + * GDMA Channel n Control Register(4)
8193 + *
8194 + */
8195 +#define GDMA_SRC_REG(ch) (RALINK_GDMA_BASE + ch*16)
8196 +#define GDMA_DST_REG(ch) (GDMA_SRC_REG(ch) + 4)
8197 +#define GDMA_CTRL_REG(ch) (GDMA_DST_REG(ch) + 4)
8198 +#define GDMA_CTRL_REG1(ch) (GDMA_CTRL_REG(ch) + 4)
8199 +
8200 +//GDMA Interrupt Status Register
8201 +#if defined (CONFIG_RALINK_RT3052)
8202 +#define UNMASK_INT_STATUS(ch) (ch+16)
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 UNMASK_INT_STATUS(ch) (ch)
8205 +#endif
8206 +#define TXDONE_INT_STATUS(ch) (ch)
8207 +
8208 +//Control Reg0
8209 +#define MODE_SEL_OFFSET 0
8210 +#define CH_EBL_OFFSET 1
8211 +#define CH_DONEINT_EBL_OFFSET 2
8212 +#define BRST_SIZE_OFFSET 3
8213 +#define DST_BRST_MODE_OFFSET 6
8214 +#define SRC_BRST_MODE_OFFSET 7
8215 +#define TRANS_CNT_OFFSET 16
8216 +
8217 +//Control Reg1
8218 +#if defined (CONFIG_RALINK_RT3052)
8219 +#define CH_UNMASKINT_EBL_OFFSET 4
8220 +#define NEXT_UNMASK_CH_OFFSET 1
8221 +#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)
8222 +#define CH_UNMASKINT_EBL_OFFSET 1
8223 +#define NEXT_UNMASK_CH_OFFSET 3
8224 +#endif
8225 +#define COHERENT_INT_EBL_OFFSET 2
8226 +#define CH_MASK_OFFSET 0
8227 +
8228 +
8229 +#if defined (CONFIG_RALINK_RT3052)
8230 +//Control Reg0
8231 +#define DST_DMA_REQ_OFFSET 8
8232 +#define SRC_DMA_REQ_OFFSET 12
8233 +#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)
8234 +//Control Reg1
8235 +#define DST_DMA_REQ_OFFSET 8
8236 +#define SRC_DMA_REQ_OFFSET 16
8237 +#endif
8238 +
8239 +#define GDMA_PCM0_RX0 0
8240 +#define GDMA_PCM0_RX1 1
8241 +#define GDMA_PCM0_TX0 2
8242 +#define GDMA_PCM0_TX1 3
8243 +
8244 +#define GDMA_PCM1_RX0 4
8245 +#define GDMA_PCM1_RX1 5
8246 +#define GDMA_PCM1_TX0 6
8247 +#define GDMA_PCM1_TX1 7
8248 +
8249 +#define GDMA_PCM_RX(i,j) (0+((i)<<2)+j)
8250 +#define GDMA_PCM_TX(i,j) (2+((i)<<2)+j)
8251 +
8252 +#define GDMA_I2S_TX0 4
8253 +#define GDMA_I2S_TX1 5
8254 +#define GDMA_I2S_RX0 6
8255 +#define GDMA_I2S_RX1 7
8256 +
8257 +#define GDMA_SPI_TX 13
8258 +#define GDMA_SPI_RX 12
8259 +
8260 +
8261 +//#define GDMA_DEBUG
8262 +#ifdef GDMA_DEBUG
8263 +#define GDMA_PRINT(fmt, args...) printk(KERN_INFO "GDMA: " fmt, ## args)
8264 +#else
8265 +#define GDMA_PRINT(fmt, args...) { }
8266 +#endif
8267 +
8268 +/*
8269 + * TYPEDEFS AND STRUCTURES
8270 + */
8271 +
8272 +enum GdmaBusterMode {
8273 + INC_MODE=0,
8274 + FIX_MODE=1
8275 +};
8276 +
8277 +enum GdmaBusterSize {
8278 + BUSTER_SIZE_4B=0, /* 1 transfer */
8279 + BUSTER_SIZE_8B=1, /* 2 transfer */
8280 + BUSTER_SIZE_16B=2, /* 4 transfer */
8281 + BUSTER_SIZE_32B=3, /* 8 transfer */
8282 + BUSTER_SIZE_64B=4 /* 16 transfer */
8283 +};
8284 +
8285 +enum GdmaDmaReqNum {
8286 +#if defined (CONFIG_RALINK_RT3052)
8287 + DMA_REQ0=0,
8288 + DMA_NAND_REQ=1,
8289 + DMA_I2S_TX_REQ=2,
8290 + DMA_PCM_RX0_REQ=3,
8291 + DMA_PCM_RX1_REQ=4,
8292 + DMA_PCM_TX0_REQ=5,
8293 + DMA_PCM_TX1_REQ=6,
8294 + DMA_REG7=7,
8295 + DMA_MEM_REQ=8
8296 +#elif defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855)
8297 + DMA_REQ0=0,
8298 + DMA_NAND_REQ=1,
8299 + DMA_I2S_TX_REQ=2,
8300 + DMA_I2S_RX_REQ=3,
8301 + DMA_PCM_RX0_REQ=4,
8302 + DMA_PCM_RX1_REQ=5,
8303 + DMA_PCM_TX0_REQ=6,
8304 + DMA_PCM_TX1_REQ=7,
8305 + DMA_CODEC0_REQ8=8,
8306 + DMA_CODEC1_REQ9=9,
8307 + DMA_REQ10=10,
8308 + DMA_REQ11=11,
8309 + DMA_REQ12=12,
8310 + DMA_REQ13=13,
8311 + DMA_REQ14=14,
8312 + DMA_REQ15=15,
8313 +
8314 + #if defined (CONFIG_RALINK_RT3883)
8315 + DMA_MEM_REQ=16
8316 + #elif defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855)
8317 + DMA_MEM_REQ=32
8318 + #endif
8319 +
8320 +#elif defined(CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623)
8321 + DMA_REQ0=0,
8322 + DMA_NAND_REQ=1,
8323 + DMA_I2S_TX_REQ=2,
8324 + DMA_I2S_RX_REQ=3,
8325 + DMA_PCM_RX0_REQ=4,
8326 + DMA_PCM_RX1_REQ=5,
8327 + DMA_PCM_TX0_REQ=6,
8328 + DMA_PCM_TX1_REQ=7,
8329 + DMA_PCM_RX2_REQ=8,
8330 + DMA_PCM_RX3_REQ=9,
8331 + DMA_PCM_TX2_REQ=10,
8332 + DMA_PCM_TX3_REQ=11,
8333 + DMA_SPI_RX_REQ=12,
8334 + DMA_SPI_TX_REQ=13,
8335 + DMA_MEM_REQ=32
8336 +
8337 +#elif defined (CONFIG_RALINK_RT6855A)
8338 + DMA_NAND_REQ=0,
8339 + DMA_I2S_TX_REQ=1,
8340 + DMA_I2S_RX_REQ=2,
8341 + DMA_REQ0=3,
8342 + DMA_PCM_RX0_REQ=4,
8343 + DMA_PCM_RX1_REQ=5,
8344 + DMA_PCM_TX0_REQ=6,
8345 + DMA_PCM_TX1_REQ=7,
8346 + DMA_CODEC0_REQ8=8,
8347 + DMA_CODEC1_REQ9=9,
8348 + DMA_REQ10=10,
8349 + DMA_REQ11=11,
8350 + DMA_REQ12=12,
8351 + DMA_REQ13=13,
8352 + DMA_REQ14=14,
8353 + DMA_REQ15=15,
8354 + DMA_MEM_REQ=32
8355 +#else
8356 +#error Please Choose System Type
8357 +#endif
8358 +};
8359 +
8360 +
8361 +
8362 +typedef struct {
8363 + uint32_t Src;
8364 + uint32_t Dst;
8365 + uint16_t TransCount;
8366 + uint8_t SoftMode;
8367 + uint8_t NextUnMaskCh;
8368 + uint8_t ChMask;
8369 + uint8_t CoherentIntEbl;
8370 + uint32_t ChNum;
8371 + enum GdmaDmaReqNum SrcReqNum;
8372 + enum GdmaDmaReqNum DstReqNum;
8373 + enum GdmaBusterMode SrcBurstMode;
8374 + enum GdmaBusterMode DstBurstMode;
8375 + enum GdmaBusterSize BurstSize;
8376 + void (*DoneIntCallback)(uint32_t);
8377 + void (*UnMaskIntCallback)(uint32_t);
8378 +} GdmaReqEntry;
8379 +
8380 +/*
8381 + * EXPORT FUNCTION
8382 + */
8383 +int GdmaI2sTx(uint32_t Src, uint32_t Dst, uint8_t TxNo, uint16_t TransCount,
8384 + void (*DoneIntCallback)(uint32_t data),
8385 + void (*UnMaskIntCallback)(uint32_t data));
8386 +
8387 +int GdmaI2sRx(uint32_t Src, uint32_t Dst, uint8_t RxNo, uint16_t TransCount,
8388 + void (*DoneIntCallback)(uint32_t data),
8389 + void (*UnMaskIntCallback)(uint32_t data));
8390 +
8391 +int GdmaPcmRx(uint32_t Src, uint32_t Dst, uint8_t PcmNo, uint8_t RxNo, uint16_t TransCount,
8392 + void (*DoneIntCallback)(uint32_t data),
8393 + void (*UnMaskIntCallback)(uint32_t data));
8394 +
8395 +int GdmaPcmTx(uint32_t Src, uint32_t Dst, uint8_t PcmNo, uint8_t TxNo, uint16_t TransCount,
8396 + void (*DoneIntCallback)(uint32_t data),
8397 + void (*UnMaskIntCallback)(uint32_t data));
8398 +
8399 +int GdmaSpiTx(uint32_t Src, uint32_t Dst, uint16_t TransCount,
8400 + void (*DoneIntCallback)(uint32_t data),
8401 + void (*UnMaskIntCallback)(uint32_t data));
8402 +
8403 +int GdmaSpiRx(uint32_t Src, uint32_t Dst, uint16_t TransCount,
8404 + void (*DoneIntCallback)(uint32_t data),
8405 + void (*UnMaskIntCallback)(uint32_t data));
8406 +
8407 +
8408 +int GdmaMem2Mem(uint32_t Src, uint32_t Dst, uint16_t TransCount,
8409 + void (*DoneIntCallback)(uint32_t data));
8410 +
8411 +int GdmaMaskChannel(uint32_t ChNum);
8412 +
8413 +int GdmaUnMaskChannel(uint32_t ChNum);
8414 +
8415 +int GdmaReqQuickIns(uint32_t ChNum);
8416 +
8417 +
8418 +#endif
8419 --- a/sound/soc/soc-core.c
8420 +++ b/sound/soc/soc-core.c
8421 @@ -1758,7 +1758,8 @@ static int soc_probe(struct platform_dev
8422 /* Bodge while we unpick instantiation */
8423 card->dev = &pdev->dev;
8424
8425 - return snd_soc_register_card(card);
8426 + snd_soc_register_card(card);
8427 + return 0;
8428 }
8429
8430 static int soc_cleanup_card_resources(struct snd_soc_card *card)