• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/sound/pci/au88x0/
1/*
2 *  This program is free software; you can redistribute it and/or modify
3 *  it under the terms of the GNU General Public License as published by
4 *  the Free Software Foundation; either version 2 of the License, or
5 *  (at your option) any later version.
6 *
7 *  This program is distributed in the hope that it will be useful,
8 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *  GNU Library General Public License for more details.
11 *
12 *  You should have received a copy of the GNU General Public License
13 *  along with this program; if not, write to the Free Software
14 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 */
16
17/*
18    Vortex core low level functions.
19
20 Author: Manuel Jander (mjander@users.sourceforge.cl)
21 These functions are mainly the result of translations made
22 from the original disassembly of the au88x0 binary drivers,
23 written by Aureal before they went down.
24 Many thanks to the Jeff Muizelaar, Kester Maddock, and whoever
25 contributed to the OpenVortex project.
26 The author of this file, put the few available pieces together
27 and translated the rest of the riddle (Mix, Src and connection stuff).
28 Some things are still to be discovered, and their meanings are unclear.
29
30 Some of these functions aren't intended to be really used, rather
31 to help to understand how does the AU88X0 chips work. Keep them in, because
32 they could be used somewhere in the future.
33
34 This code hasn't been tested or proof read thoroughly. If you wanna help,
35 take a look at the AU88X0 assembly and check if this matches.
36 Functions tested ok so far are (they show the desired effect
37 at least):
38   vortex_routes(); (1 bug fixed).
39   vortex_adb_addroute();
40   vortex_adb_addroutes();
41   vortex_connect_codecplay();
42   vortex_src_flushbuffers();
43   vortex_adbdma_setmode();  note: still some unknown arguments!
44   vortex_adbdma_startfifo();
45   vortex_adbdma_stopfifo();
46   vortex_fifo_setadbctrl(); note: still some unknown arguments!
47   vortex_mix_setinputvolumebyte();
48   vortex_mix_enableinput();
49   vortex_mixer_addWTD(); (fixed)
50   vortex_connection_adbdma_src_src();
51   vortex_connection_adbdma_src();
52   vortex_src_change_convratio();
53   vortex_src_addWTD(); (fixed)
54
55 History:
56
57 01-03-2003 First revision.
58 01-21-2003 Some bug fixes.
59 17-02-2003 many bugfixes after a big versioning mess.
60 18-02-2003 JAAAAAHHHUUUUUU!!!! The mixer works !! I'm just so happy !
61			 (2 hours later...) I cant believe it! Im really lucky today.
62			 Now the SRC is working too! Yeah! XMMS works !
63 20-02-2003 First steps into the ALSA world.
64 28-02-2003 As my birthday present, i discovered how the DMA buffer pages really
65            work :-). It was all wrong.
66 12-03-2003 ALSA driver starts working (2 channels).
67 16-03-2003 More srcblock_setupchannel discoveries.
68 12-04-2003 AU8830 playback support. Recording in the works.
69 17-04-2003 vortex_route() and vortex_routes() bug fixes. AU8830 recording
70 			works now, but chipn' dale effect is still there.
71 16-05-2003 SrcSetupChannel cleanup. Moved the Src setup stuff entirely
72            into au88x0_pcm.c .
73 06-06-2003 Buffer shifter bugfix. Mixer volume fix.
74 07-12-2003 A3D routing finally fixed. Believed to be OK.
75 25-03-2004 Many thanks to Claudia, for such valuable bug reports.
76
77*/
78
79#include "au88x0.h"
80#include "au88x0_a3d.h"
81#include <linux/delay.h>
82
83/*  MIXER (CAsp4Mix.s and CAsp4Mixer.s) */
84
85static int mchannels[NR_MIXIN];
86static int rampchs[NR_MIXIN];
87
88static void vortex_mixer_en_sr(vortex_t * vortex, int channel)
89{
90	hwwrite(vortex->mmio, VORTEX_MIXER_SR,
91		hwread(vortex->mmio, VORTEX_MIXER_SR) | (0x1 << channel));
92}
93static void vortex_mixer_dis_sr(vortex_t * vortex, int channel)
94{
95	hwwrite(vortex->mmio, VORTEX_MIXER_SR,
96		hwread(vortex->mmio, VORTEX_MIXER_SR) & ~(0x1 << channel));
97}
98
99static void
100vortex_mix_setvolumebyte(vortex_t * vortex, unsigned char mix,
101			 unsigned char vol)
102{
103	int temp;
104	hwwrite(vortex->mmio, VORTEX_MIX_VOL_A + (mix << 2), vol);
105	if (1) {		/*if (this_10) */
106		temp = hwread(vortex->mmio, VORTEX_MIX_VOL_B + (mix << 2));
107		if ((temp != 0x80) || (vol == 0x80))
108			return;
109	}
110	hwwrite(vortex->mmio, VORTEX_MIX_VOL_B + (mix << 2), vol);
111}
112
113static void
114vortex_mix_setinputvolumebyte(vortex_t * vortex, unsigned char mix,
115			      int mixin, unsigned char vol)
116{
117	int temp;
118
119	hwwrite(vortex->mmio,
120		VORTEX_MIX_INVOL_A + (((mix << 5) + mixin) << 2), vol);
121	if (1) {		/* this_10, initialized to 1. */
122		temp =
123		    hwread(vortex->mmio,
124			   VORTEX_MIX_INVOL_B + (((mix << 5) + mixin) << 2));
125		if ((temp != 0x80) || (vol == 0x80))
126			return;
127	}
128	hwwrite(vortex->mmio,
129		VORTEX_MIX_INVOL_B + (((mix << 5) + mixin) << 2), vol);
130}
131
132static void
133vortex_mix_setenablebit(vortex_t * vortex, unsigned char mix, int mixin, int en)
134{
135	int temp, addr;
136
137	if (mixin < 0)
138		addr = (mixin + 3);
139	else
140		addr = mixin;
141	addr = ((mix << 3) + (addr >> 2)) << 2;
142	temp = hwread(vortex->mmio, VORTEX_MIX_ENIN + addr);
143	if (en)
144		temp |= (1 << (mixin & 3));
145	else
146		temp &= ~(1 << (mixin & 3));
147	/* Mute input. Astatic void crackling? */
148	hwwrite(vortex->mmio,
149		VORTEX_MIX_INVOL_B + (((mix << 5) + mixin) << 2), 0x80);
150	/* Looks like clear buffer. */
151	hwwrite(vortex->mmio, VORTEX_MIX_SMP + (mixin << 2), 0x0);
152	hwwrite(vortex->mmio, VORTEX_MIX_SMP + 4 + (mixin << 2), 0x0);
153	/* Write enable bit. */
154	hwwrite(vortex->mmio, VORTEX_MIX_ENIN + addr, temp);
155}
156
157static void
158vortex_mix_killinput(vortex_t * vortex, unsigned char mix, int mixin)
159{
160	rampchs[mix] &= ~(1 << mixin);
161	vortex_mix_setinputvolumebyte(vortex, mix, mixin, 0x80);
162	mchannels[mix] &= ~(1 << mixin);
163	vortex_mix_setenablebit(vortex, mix, mixin, 0);
164}
165
166static void
167vortex_mix_enableinput(vortex_t * vortex, unsigned char mix, int mixin)
168{
169	vortex_mix_killinput(vortex, mix, mixin);
170	if ((mchannels[mix] & (1 << mixin)) == 0) {
171		vortex_mix_setinputvolumebyte(vortex, mix, mixin, 0x80);	/*0x80 : mute */
172		mchannels[mix] |= (1 << mixin);
173	}
174	vortex_mix_setenablebit(vortex, mix, mixin, 1);
175}
176
177static void
178vortex_mix_disableinput(vortex_t * vortex, unsigned char mix, int channel,
179			int ramp)
180{
181	if (ramp) {
182		rampchs[mix] |= (1 << channel);
183		// Register callback.
184		//vortex_mix_startrampvolume(vortex);
185		vortex_mix_killinput(vortex, mix, channel);
186	} else
187		vortex_mix_killinput(vortex, mix, channel);
188}
189
190static int
191vortex_mixer_addWTD(vortex_t * vortex, unsigned char mix, unsigned char ch)
192{
193	int temp, lifeboat = 0, prev;
194
195	temp = hwread(vortex->mmio, VORTEX_MIXER_SR);
196	if ((temp & (1 << ch)) == 0) {
197		hwwrite(vortex->mmio, VORTEX_MIXER_CHNBASE + (ch << 2), mix);
198		vortex_mixer_en_sr(vortex, ch);
199		return 1;
200	}
201	prev = VORTEX_MIXER_CHNBASE + (ch << 2);
202	temp = hwread(vortex->mmio, prev);
203	while (temp & 0x10) {
204		prev = VORTEX_MIXER_RTBASE + ((temp & 0xf) << 2);
205		temp = hwread(vortex->mmio, prev);
206		//printk(KERN_INFO "vortex: mixAddWTD: while addr=%x, val=%x\n", prev, temp);
207		if ((++lifeboat) > 0xf) {
208			printk(KERN_ERR
209			       "vortex_mixer_addWTD: lifeboat overflow\n");
210			return 0;
211		}
212	}
213	hwwrite(vortex->mmio, VORTEX_MIXER_RTBASE + ((temp & 0xf) << 2), mix);
214	hwwrite(vortex->mmio, prev, (temp & 0xf) | 0x10);
215	return 1;
216}
217
218static int
219vortex_mixer_delWTD(vortex_t * vortex, unsigned char mix, unsigned char ch)
220{
221	int esp14 = -1, esp18, eax, ebx, edx, ebp, esi = 0;
222	//int esp1f=edi(while)=src, esp10=ch;
223
224	eax = hwread(vortex->mmio, VORTEX_MIXER_SR);
225	if (((1 << ch) & eax) == 0) {
226		printk(KERN_ERR "mix ALARM %x\n", eax);
227		return 0;
228	}
229	ebp = VORTEX_MIXER_CHNBASE + (ch << 2);
230	esp18 = hwread(vortex->mmio, ebp);
231	if (esp18 & 0x10) {
232		ebx = (esp18 & 0xf);
233		if (mix == ebx) {
234			ebx = VORTEX_MIXER_RTBASE + (mix << 2);
235			edx = hwread(vortex->mmio, ebx);
236			//7b60
237			hwwrite(vortex->mmio, ebp, edx);
238			hwwrite(vortex->mmio, ebx, 0);
239		} else {
240			//7ad3
241			edx =
242			    hwread(vortex->mmio,
243				   VORTEX_MIXER_RTBASE + (ebx << 2));
244			//printk(KERN_INFO "vortex: mixdelWTD: 1 addr=%x, val=%x, src=%x\n", ebx, edx, src);
245			while ((edx & 0xf) != mix) {
246				if ((esi) > 0xf) {
247					printk(KERN_ERR
248					       "vortex: mixdelWTD: error lifeboat overflow\n");
249					return 0;
250				}
251				esp14 = ebx;
252				ebx = edx & 0xf;
253				ebp = ebx << 2;
254				edx =
255				    hwread(vortex->mmio,
256					   VORTEX_MIXER_RTBASE + ebp);
257				//printk(KERN_INFO "vortex: mixdelWTD: while addr=%x, val=%x\n", ebp, edx);
258				esi++;
259			}
260			//7b30
261			ebp = ebx << 2;
262			if (edx & 0x10) {	/* Delete entry in between others */
263				ebx = VORTEX_MIXER_RTBASE + ((edx & 0xf) << 2);
264				edx = hwread(vortex->mmio, ebx);
265				//7b60
266				hwwrite(vortex->mmio,
267					VORTEX_MIXER_RTBASE + ebp, edx);
268				hwwrite(vortex->mmio, ebx, 0);
269				//printk(KERN_INFO "vortex mixdelWTD between addr= 0x%x, val= 0x%x\n", ebp, edx);
270			} else {	/* Delete last entry */
271				//7b83
272				if (esp14 == -1)
273					hwwrite(vortex->mmio,
274						VORTEX_MIXER_CHNBASE +
275						(ch << 2), esp18 & 0xef);
276				else {
277					ebx = (0xffffffe0 & edx) | (0xf & ebx);
278					hwwrite(vortex->mmio,
279						VORTEX_MIXER_RTBASE +
280						(esp14 << 2), ebx);
281					//printk(KERN_INFO "vortex mixdelWTD last addr= 0x%x, val= 0x%x\n", esp14, ebx);
282				}
283				hwwrite(vortex->mmio,
284					VORTEX_MIXER_RTBASE + ebp, 0);
285				return 1;
286			}
287		}
288	} else {
289		//printk(KERN_INFO "removed last mix\n");
290		//7be0
291		vortex_mixer_dis_sr(vortex, ch);
292		hwwrite(vortex->mmio, ebp, 0);
293	}
294	return 1;
295}
296
297static void vortex_mixer_init(vortex_t * vortex)
298{
299	u32 addr;
300	int x;
301
302	memset(mchannels, 0, NR_MIXOUT * sizeof(int));
303	memset(rampchs, 0, NR_MIXOUT * sizeof(int));
304
305	addr = VORTEX_MIX_SMP + 0x17c;
306	for (x = 0x5f; x >= 0; x--) {
307		hwwrite(vortex->mmio, addr, 0);
308		addr -= 4;
309	}
310	addr = VORTEX_MIX_ENIN + 0x1fc;
311	for (x = 0x7f; x >= 0; x--) {
312		hwwrite(vortex->mmio, addr, 0);
313		addr -= 4;
314	}
315	addr = VORTEX_MIX_SMP + 0x17c;
316	for (x = 0x5f; x >= 0; x--) {
317		hwwrite(vortex->mmio, addr, 0);
318		addr -= 4;
319	}
320	addr = VORTEX_MIX_INVOL_A + 0x7fc;
321	for (x = 0x1ff; x >= 0; x--) {
322		hwwrite(vortex->mmio, addr, 0x80);
323		addr -= 4;
324	}
325	addr = VORTEX_MIX_VOL_A + 0x3c;
326	for (x = 0xf; x >= 0; x--) {
327		hwwrite(vortex->mmio, addr, 0x80);
328		addr -= 4;
329	}
330	addr = VORTEX_MIX_INVOL_B + 0x7fc;
331	for (x = 0x1ff; x >= 0; x--) {
332		hwwrite(vortex->mmio, addr, 0x80);
333		addr -= 4;
334	}
335	addr = VORTEX_MIX_VOL_B + 0x3c;
336	for (x = 0xf; x >= 0; x--) {
337		hwwrite(vortex->mmio, addr, 0x80);
338		addr -= 4;
339	}
340	addr = VORTEX_MIXER_RTBASE + (MIXER_RTBASE_SIZE - 1) * 4;
341	for (x = (MIXER_RTBASE_SIZE - 1); x >= 0; x--) {
342		hwwrite(vortex->mmio, addr, 0x0);
343		addr -= 4;
344	}
345	hwwrite(vortex->mmio, VORTEX_MIXER_SR, 0);
346
347	/* Set clipping ceiling (this may be all wrong). */
348	/*
349	for (x = 0; x < 0x80; x++) {
350		hwwrite(vortex->mmio, VORTEX_MIXER_CLIP + (x << 2), 0x3ffff);
351	}
352	*/
353	/*
354	   call CAsp4Mix__Initialize_CAsp4HwIO____CAsp4Mixer____
355	   Register ISR callback for volume smooth fade out.
356	   Maybe this avoids clicks when press "stop" ?
357	 */
358}
359
360/*  SRC (CAsp4Src.s and CAsp4SrcBlock) */
361
362static void vortex_src_en_sr(vortex_t * vortex, int channel)
363{
364	hwwrite(vortex->mmio, VORTEX_SRCBLOCK_SR,
365		hwread(vortex->mmio, VORTEX_SRCBLOCK_SR) | (0x1 << channel));
366}
367
368static void vortex_src_dis_sr(vortex_t * vortex, int channel)
369{
370	hwwrite(vortex->mmio, VORTEX_SRCBLOCK_SR,
371		hwread(vortex->mmio, VORTEX_SRCBLOCK_SR) & ~(0x1 << channel));
372}
373
374static void vortex_src_flushbuffers(vortex_t * vortex, unsigned char src)
375{
376	int i;
377
378	for (i = 0x1f; i >= 0; i--)
379		hwwrite(vortex->mmio,
380			VORTEX_SRC_DATA0 + (src << 7) + (i << 2), 0);
381	hwwrite(vortex->mmio, VORTEX_SRC_DATA + (src << 3), 0);
382	hwwrite(vortex->mmio, VORTEX_SRC_DATA + (src << 3) + 4, 0);
383}
384
385static void vortex_src_cleardrift(vortex_t * vortex, unsigned char src)
386{
387	hwwrite(vortex->mmio, VORTEX_SRC_DRIFT0 + (src << 2), 0);
388	hwwrite(vortex->mmio, VORTEX_SRC_DRIFT1 + (src << 2), 0);
389	hwwrite(vortex->mmio, VORTEX_SRC_DRIFT2 + (src << 2), 1);
390}
391
392static void
393vortex_src_set_throttlesource(vortex_t * vortex, unsigned char src, int en)
394{
395	int temp;
396
397	temp = hwread(vortex->mmio, VORTEX_SRC_SOURCE);
398	if (en)
399		temp |= 1 << src;
400	else
401		temp &= ~(1 << src);
402	hwwrite(vortex->mmio, VORTEX_SRC_SOURCE, temp);
403}
404
405static int
406vortex_src_persist_convratio(vortex_t * vortex, unsigned char src, int ratio)
407{
408	int temp, lifeboat = 0;
409
410	do {
411		hwwrite(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2), ratio);
412		temp = hwread(vortex->mmio, VORTEX_SRC_CONVRATIO + (src << 2));
413		if ((++lifeboat) > 0x9) {
414			printk(KERN_ERR "Vortex: Src cvr fail\n");
415			break;
416		}
417	}
418	while (temp != ratio);
419	return temp;
420}
421
422/*
423 Objective: Set samplerate for given SRC module.
424 Arguments:
425	card:	pointer to vortex_t strcut.
426	src:	Integer index of the SRC module.
427	cr:		Current sample rate conversion factor.
428	b:		unknown 16 bit value.
429	sweep:	Enable Samplerate fade from cr toward tr flag.
430	dirplay: 1: playback, 0: recording.
431	sl:		Slow Lock flag.
432	tr:		Target samplerate conversion.
433	thsource: Throttle source flag (no idea what that means).
434*/
435static void vortex_src_setupchannel(vortex_t * card, unsigned char src,
436			unsigned int cr, unsigned int b, int sweep, int d,
437			int dirplay, int sl, unsigned int tr, int thsource)
438{
439	// noplayback: d=2,4,7,0xa,0xb when using first 2 src's.
440	// c: enables pitch sweep.
441	// looks like g is c related. Maybe g is a sweep parameter ?
442	// g = cvr
443	// dirplay: 0 = recording, 1 = playback
444	// d = src hw index.
445
446	int esi, ebp = 0, esp10;
447
448	vortex_src_flushbuffers(card, src);
449
450	if (sweep) {
451		if ((tr & 0x10000) && (tr != 0x10000)) {
452			tr = 0;
453			esi = 0x7;
454		} else {
455			if ((((short)tr) < 0) && (tr != 0x8000)) {
456				tr = 0;
457				esi = 0x8;
458			} else {
459				tr = 1;
460				esi = 0xc;
461			}
462		}
463	} else {
464		if ((cr & 0x10000) && (cr != 0x10000)) {
465			tr = 0;	/*ebx = 0 */
466			esi = 0x11 - ((cr >> 0xe) & 7);
467			if (cr & 0x3fff)
468				esi -= 1;
469			else
470				esi -= 2;
471		} else {
472			tr = 1;
473			esi = 0xc;
474		}
475	}
476	vortex_src_cleardrift(card, src);
477	vortex_src_set_throttlesource(card, src, thsource);
478
479	if ((dirplay == 0) && (sweep == 0)) {
480		if (tr)
481			esp10 = 0xf;
482		else
483			esp10 = 0xc;
484		ebp = 0;
485	} else {
486		if (tr)
487			ebp = 0xf;
488		else
489			ebp = 0xc;
490		esp10 = 0;
491	}
492	hwwrite(card->mmio, VORTEX_SRC_U0 + (src << 2),
493		(sl << 0x9) | (sweep << 0x8) | ((esi & 0xf) << 4) | d);
494	/* 0xc0   esi=0xc c=f=0 d=0 */
495	vortex_src_persist_convratio(card, src, cr);
496	hwwrite(card->mmio, VORTEX_SRC_U1 + (src << 2), b & 0xffff);
497	/* 0   b=0 */
498	hwwrite(card->mmio, VORTEX_SRC_U2 + (src << 2),
499		(tr << 0x11) | (dirplay << 0x10) | (ebp << 0x8) | esp10);
500	/* 0x30f00 e=g=1 esp10=0 ebp=f */
501	//printk(KERN_INFO "vortex: SRC %d, d=0x%x, esi=0x%x, esp10=0x%x, ebp=0x%x\n", src, d, esi, esp10, ebp);
502}
503
504static void vortex_srcblock_init(vortex_t * vortex)
505{
506	u32 addr;
507	int x;
508	hwwrite(vortex->mmio, VORTEX_SRC_SOURCESIZE, 0x1ff);
509	/*
510	   for (x=0; x<0x10; x++) {
511	   vortex_src_init(&vortex_src[x], x);
512	   }
513	 */
514	//addr = 0xcc3c;
515	//addr = 0x26c3c;
516	addr = VORTEX_SRC_RTBASE + 0x3c;
517	for (x = 0xf; x >= 0; x--) {
518		hwwrite(vortex->mmio, addr, 0);
519		addr -= 4;
520	}
521	//addr = 0xcc94;
522	//addr = 0x26c94;
523	addr = VORTEX_SRC_CHNBASE + 0x54;
524	for (x = 0x15; x >= 0; x--) {
525		hwwrite(vortex->mmio, addr, 0);
526		addr -= 4;
527	}
528}
529
530static int
531vortex_src_addWTD(vortex_t * vortex, unsigned char src, unsigned char ch)
532{
533	int temp, lifeboat = 0, prev;
534	// esp13 = src
535
536	temp = hwread(vortex->mmio, VORTEX_SRCBLOCK_SR);
537	if ((temp & (1 << ch)) == 0) {
538		hwwrite(vortex->mmio, VORTEX_SRC_CHNBASE + (ch << 2), src);
539		vortex_src_en_sr(vortex, ch);
540		return 1;
541	}
542	prev = VORTEX_SRC_CHNBASE + (ch << 2);	/*ebp */
543	temp = hwread(vortex->mmio, prev);
544	//while (temp & NR_SRC) {
545	while (temp & 0x10) {
546		prev = VORTEX_SRC_RTBASE + ((temp & 0xf) << 2);	/*esp12 */
547		//prev = VORTEX_SRC_RTBASE + ((temp & (NR_SRC-1)) << 2); /*esp12*/
548		temp = hwread(vortex->mmio, prev);
549		//printk(KERN_INFO "vortex: srcAddWTD: while addr=%x, val=%x\n", prev, temp);
550		if ((++lifeboat) > 0xf) {
551			printk(KERN_ERR
552			       "vortex_src_addWTD: lifeboat overflow\n");
553			return 0;
554		}
555	}
556	hwwrite(vortex->mmio, VORTEX_SRC_RTBASE + ((temp & 0xf) << 2), src);
557	//hwwrite(vortex->mmio, prev, (temp & (NR_SRC-1)) | NR_SRC);
558	hwwrite(vortex->mmio, prev, (temp & 0xf) | 0x10);
559	return 1;
560}
561
562static int
563vortex_src_delWTD(vortex_t * vortex, unsigned char src, unsigned char ch)
564{
565	int esp14 = -1, esp18, eax, ebx, edx, ebp, esi = 0;
566	//int esp1f=edi(while)=src, esp10=ch;
567
568	eax = hwread(vortex->mmio, VORTEX_SRCBLOCK_SR);
569	if (((1 << ch) & eax) == 0) {
570		printk(KERN_ERR "src alarm\n");
571		return 0;
572	}
573	ebp = VORTEX_SRC_CHNBASE + (ch << 2);
574	esp18 = hwread(vortex->mmio, ebp);
575	if (esp18 & 0x10) {
576		ebx = (esp18 & 0xf);
577		if (src == ebx) {
578			ebx = VORTEX_SRC_RTBASE + (src << 2);
579			edx = hwread(vortex->mmio, ebx);
580			//7b60
581			hwwrite(vortex->mmio, ebp, edx);
582			hwwrite(vortex->mmio, ebx, 0);
583		} else {
584			//7ad3
585			edx =
586			    hwread(vortex->mmio,
587				   VORTEX_SRC_RTBASE + (ebx << 2));
588			//printk(KERN_INFO "vortex: srcdelWTD: 1 addr=%x, val=%x, src=%x\n", ebx, edx, src);
589			while ((edx & 0xf) != src) {
590				if ((esi) > 0xf) {
591					printk
592					    ("vortex: srcdelWTD: error, lifeboat overflow\n");
593					return 0;
594				}
595				esp14 = ebx;
596				ebx = edx & 0xf;
597				ebp = ebx << 2;
598				edx =
599				    hwread(vortex->mmio,
600					   VORTEX_SRC_RTBASE + ebp);
601				//printk(KERN_INFO "vortex: srcdelWTD: while addr=%x, val=%x\n", ebp, edx);
602				esi++;
603			}
604			//7b30
605			ebp = ebx << 2;
606			if (edx & 0x10) {	/* Delete entry in between others */
607				ebx = VORTEX_SRC_RTBASE + ((edx & 0xf) << 2);
608				edx = hwread(vortex->mmio, ebx);
609				//7b60
610				hwwrite(vortex->mmio,
611					VORTEX_SRC_RTBASE + ebp, edx);
612				hwwrite(vortex->mmio, ebx, 0);
613				//printk(KERN_INFO "vortex srcdelWTD between addr= 0x%x, val= 0x%x\n", ebp, edx);
614			} else {	/* Delete last entry */
615				//7b83
616				if (esp14 == -1)
617					hwwrite(vortex->mmio,
618						VORTEX_SRC_CHNBASE +
619						(ch << 2), esp18 & 0xef);
620				else {
621					ebx = (0xffffffe0 & edx) | (0xf & ebx);
622					hwwrite(vortex->mmio,
623						VORTEX_SRC_RTBASE +
624						(esp14 << 2), ebx);
625					//printk(KERN_INFO"vortex srcdelWTD last addr= 0x%x, val= 0x%x\n", esp14, ebx);
626				}
627				hwwrite(vortex->mmio,
628					VORTEX_SRC_RTBASE + ebp, 0);
629				return 1;
630			}
631		}
632	} else {
633		//7be0
634		vortex_src_dis_sr(vortex, ch);
635		hwwrite(vortex->mmio, ebp, 0);
636	}
637	return 1;
638}
639
640 /*FIFO*/
641
642static void
643vortex_fifo_clearadbdata(vortex_t * vortex, int fifo, int x)
644{
645	for (x--; x >= 0; x--)
646		hwwrite(vortex->mmio,
647			VORTEX_FIFO_ADBDATA +
648			(((fifo << FIFO_SIZE_BITS) + x) << 2), 0);
649}
650
651static void vortex_fifo_setadbvalid(vortex_t * vortex, int fifo, int en)
652{
653	hwwrite(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2),
654		(hwread(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2)) &
655		 0xffffffef) | ((1 & en) << 4) | FIFO_U1);
656}
657
658static void
659vortex_fifo_setadbctrl(vortex_t * vortex, int fifo, int b, int priority,
660		       int empty, int valid, int f)
661{
662	int temp, lifeboat = 0;
663	//int this_8[NR_ADB] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* position */
664	int this_4 = 0x2;
665	/* f seems priority related.
666	 * CAsp4AdbDma::SetPriority is the only place that calls SetAdbCtrl with f set to 1
667	 * every where else it is set to 0. It seems, however, that CAsp4AdbDma::SetPriority
668	 * is never called, thus the f related bits remain a mystery for now.
669	 */
670	do {
671		temp = hwread(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2));
672		if (lifeboat++ > 0xbb8) {
673			printk(KERN_ERR
674			       "Vortex: vortex_fifo_setadbctrl fail\n");
675			break;
676		}
677	}
678	while (temp & FIFO_RDONLY);
679
680	// AU8830 semes to take some special care about fifo content (data).
681	// But i'm just to lazy to translate that :)
682	if (valid) {
683		if ((temp & FIFO_VALID) == 0) {
684			//this_8[fifo] = 0;
685			vortex_fifo_clearadbdata(vortex, fifo, FIFO_SIZE);	// this_4
686#ifdef CHIP_AU8820
687			temp = (this_4 & 0x1f) << 0xb;
688#else
689			temp = (this_4 & 0x3f) << 0xc;
690#endif
691			temp = (temp & 0xfffffffd) | ((b & 1) << 1);
692			temp = (temp & 0xfffffff3) | ((priority & 3) << 2);
693			temp = (temp & 0xffffffef) | ((valid & 1) << 4);
694			temp |= FIFO_U1;
695			temp = (temp & 0xffffffdf) | ((empty & 1) << 5);
696#ifdef CHIP_AU8820
697			temp = (temp & 0xfffbffff) | ((f & 1) << 0x12);
698#endif
699#ifdef CHIP_AU8830
700			temp = (temp & 0xf7ffffff) | ((f & 1) << 0x1b);
701			temp = (temp & 0xefffffff) | ((f & 1) << 0x1c);
702#endif
703#ifdef CHIP_AU8810
704			temp = (temp & 0xfeffffff) | ((f & 1) << 0x18);
705			temp = (temp & 0xfdffffff) | ((f & 1) << 0x19);
706#endif
707		}
708	} else {
709		if (temp & FIFO_VALID) {
710#ifdef CHIP_AU8820
711			temp = ((f & 1) << 0x12) | (temp & 0xfffbffef);
712#endif
713#ifdef CHIP_AU8830
714			temp =
715			    ((f & 1) << 0x1b) | (temp & 0xe7ffffef) | FIFO_BITS;
716#endif
717#ifdef CHIP_AU8810
718			temp =
719			    ((f & 1) << 0x18) | (temp & 0xfcffffef) | FIFO_BITS;
720#endif
721		} else
722			/*if (this_8[fifo]) */
723			vortex_fifo_clearadbdata(vortex, fifo, FIFO_SIZE);
724	}
725	hwwrite(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2), temp);
726	hwread(vortex->mmio, VORTEX_FIFO_ADBCTRL + (fifo << 2));
727}
728
729#ifndef CHIP_AU8810
730static void vortex_fifo_clearwtdata(vortex_t * vortex, int fifo, int x)
731{
732	if (x < 1)
733		return;
734	for (x--; x >= 0; x--)
735		hwwrite(vortex->mmio,
736			VORTEX_FIFO_WTDATA +
737			(((fifo << FIFO_SIZE_BITS) + x) << 2), 0);
738}
739
740static void vortex_fifo_wtinitialize(vortex_t * vortex, int fifo, int j)
741{
742	vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);
743#ifdef CHIP_AU8820
744	hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2),
745		(FIFO_U1 | ((j & FIFO_MASK) << 0xb)));
746#else
747	hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2),
748		(FIFO_U1 | ((j & FIFO_MASK) << 0xc)));
749#endif
750}
751
752static void vortex_fifo_setwtvalid(vortex_t * vortex, int fifo, int en)
753{
754	hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2),
755		(hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2)) &
756		 0xffffffef) | ((en & 1) << 4) | FIFO_U1);
757}
758
759static void
760vortex_fifo_setwtctrl(vortex_t * vortex, int fifo, int ctrl, int priority,
761		      int empty, int valid, int f)
762{
763	int temp = 0, lifeboat = 0;
764	int this_4 = 2;
765
766	do {
767		temp = hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2));
768		if (lifeboat++ > 0xbb8) {
769			printk(KERN_ERR "Vortex: vortex_fifo_setwtctrl fail\n");
770			break;
771		}
772	}
773	while (temp & FIFO_RDONLY);
774
775	if (valid) {
776		if ((temp & FIFO_VALID) == 0) {
777			vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);	// this_4
778#ifdef CHIP_AU8820
779			temp = (this_4 & 0x1f) << 0xb;
780#else
781			temp = (this_4 & 0x3f) << 0xc;
782#endif
783			temp = (temp & 0xfffffffd) | ((ctrl & 1) << 1);
784			temp = (temp & 0xfffffff3) | ((priority & 3) << 2);
785			temp = (temp & 0xffffffef) | ((valid & 1) << 4);
786			temp |= FIFO_U1;
787			temp = (temp & 0xffffffdf) | ((empty & 1) << 5);
788#ifdef CHIP_AU8820
789			temp = (temp & 0xfffbffff) | ((f & 1) << 0x12);
790#endif
791#ifdef CHIP_AU8830
792			temp = (temp & 0xf7ffffff) | ((f & 1) << 0x1b);
793			temp = (temp & 0xefffffff) | ((f & 1) << 0x1c);
794#endif
795#ifdef CHIP_AU8810
796			temp = (temp & 0xfeffffff) | ((f & 1) << 0x18);
797			temp = (temp & 0xfdffffff) | ((f & 1) << 0x19);
798#endif
799		}
800	} else {
801		if (temp & FIFO_VALID) {
802#ifdef CHIP_AU8820
803			temp = ((f & 1) << 0x12) | (temp & 0xfffbffef);
804#endif
805#ifdef CHIP_AU8830
806			temp =
807			    ((f & 1) << 0x1b) | (temp & 0xe7ffffef) | FIFO_BITS;
808#endif
809#ifdef CHIP_AU8810
810			temp =
811			    ((f & 1) << 0x18) | (temp & 0xfcffffef) | FIFO_BITS;
812#endif
813		} else
814			/*if (this_8[fifo]) */
815			vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);
816	}
817	hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
818	hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2));
819
820/*
821    do {
822		temp = hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2));
823		if (lifeboat++ > 0xbb8) {
824			printk(KERN_ERR "Vortex: vortex_fifo_setwtctrl fail (hanging)\n");
825			break;
826		}
827    } while ((temp & FIFO_RDONLY)&&(temp & FIFO_VALID)&&(temp != 0xFFFFFFFF));
828
829
830	if (valid) {
831		if (temp & FIFO_VALID) {
832			temp = 0x40000;
833			//temp |= 0x08000000;
834			//temp |= 0x10000000;
835			//temp |= 0x04000000;
836			//temp |= 0x00400000;
837			temp |= 0x1c400000;
838			temp &= 0xFFFFFFF3;
839			temp &= 0xFFFFFFEF;
840			temp |= (valid & 1) << 4;
841			hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
842			return;
843		} else {
844			vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);
845			return;
846		}
847	} else {
848		temp &= 0xffffffef;
849		temp |= 0x08000000;
850		temp |= 0x10000000;
851		temp |= 0x04000000;
852		temp |= 0x00400000;
853		hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
854		temp = hwread(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2));
855		//((temp >> 6) & 0x3f)
856
857		priority = 0;
858		if (((temp & 0x0fc0) ^ ((temp >> 6) & 0x0fc0)) & 0FFFFFFC0)
859			vortex_fifo_clearwtdata(vortex, fifo, FIFO_SIZE);
860		valid = 0xfb;
861		temp = (temp & 0xfffffffd) | ((ctrl & 1) << 1);
862		temp = (temp & 0xfffdffff) | ((f & 1) << 0x11);
863		temp = (temp & 0xfffffff3) | ((priority & 3) << 2);
864		temp = (temp & 0xffffffef) | ((valid & 1) << 4);
865		temp = (temp & 0xffffffdf) | ((empty & 1) << 5);
866		hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
867	}
868
869	*/
870
871	/*
872	   temp = (temp & 0xfffffffd) | ((ctrl & 1) << 1);
873	   temp = (temp & 0xfffdffff) | ((f & 1) << 0x11);
874	   temp = (temp & 0xfffffff3) | ((priority & 3) << 2);
875	   temp = (temp & 0xffffffef) | ((valid & 1) << 4);
876	   temp = (temp & 0xffffffdf) | ((empty & 1) << 5);
877	   #ifdef FIFO_BITS
878	   temp = temp | FIFO_BITS | 40000;
879	   #endif
880	   // 0x1c440010, 0x1c400000
881	   hwwrite(vortex->mmio, VORTEX_FIFO_WTCTRL + (fifo << 2), temp);
882	 */
883}
884
885#endif
886static void vortex_fifo_init(vortex_t * vortex)
887{
888	int x;
889	u32 addr;
890
891	/* ADB DMA channels fifos. */
892	addr = VORTEX_FIFO_ADBCTRL + ((NR_ADB - 1) * 4);
893	for (x = NR_ADB - 1; x >= 0; x--) {
894		hwwrite(vortex->mmio, addr, (FIFO_U0 | FIFO_U1));
895		if (hwread(vortex->mmio, addr) != (FIFO_U0 | FIFO_U1))
896			printk(KERN_ERR "bad adb fifo reset!");
897		vortex_fifo_clearadbdata(vortex, x, FIFO_SIZE);
898		addr -= 4;
899	}
900
901#ifndef CHIP_AU8810
902	/* WT DMA channels fifos. */
903	addr = VORTEX_FIFO_WTCTRL + ((NR_WT - 1) * 4);
904	for (x = NR_WT - 1; x >= 0; x--) {
905		hwwrite(vortex->mmio, addr, FIFO_U0);
906		if (hwread(vortex->mmio, addr) != FIFO_U0)
907			printk(KERN_ERR
908			       "bad wt fifo reset (0x%08x, 0x%08x)!\n",
909			       addr, hwread(vortex->mmio, addr));
910		vortex_fifo_clearwtdata(vortex, x, FIFO_SIZE);
911		addr -= 4;
912	}
913#endif
914	/* trigger... */
915#ifdef CHIP_AU8820
916	hwwrite(vortex->mmio, 0xf8c0, 0xd03);	//0x0843 0xd6b
917#else
918#ifdef CHIP_AU8830
919	hwwrite(vortex->mmio, 0x17000, 0x61);	/* wt a */
920	hwwrite(vortex->mmio, 0x17004, 0x61);	/* wt b */
921#endif
922	hwwrite(vortex->mmio, 0x17008, 0x61);	/* adb */
923#endif
924}
925
926/* ADBDMA */
927
928static void vortex_adbdma_init(vortex_t * vortex)
929{
930}
931
932static void vortex_adbdma_setfirstbuffer(vortex_t * vortex, int adbdma)
933{
934	stream_t *dma = &vortex->dma_adb[adbdma];
935
936	hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
937		dma->dma_ctrl);
938}
939
940static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb)
941{
942	stream_t *dma = &vortex->dma_adb[adbdma];
943	//hwwrite(vortex->mmio, VORTEX_ADBDMA_START + (adbdma << 2), sb << (((NR_ADB-1)-((adbdma&0xf)*2))));
944	hwwrite(vortex->mmio, VORTEX_ADBDMA_START + (adbdma << 2),
945		sb << ((0xf - (adbdma & 0xf)) * 2));
946	dma->period_real = dma->period_virt = sb;
947}
948
949static void
950vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma,
951			 int psize, int count)
952{
953	stream_t *dma = &vortex->dma_adb[adbdma];
954
955	dma->period_bytes = psize;
956	dma->nr_periods = count;
957
958	dma->cfg0 = 0;
959	dma->cfg1 = 0;
960	switch (count) {
961		/* Four or more pages */
962	default:
963	case 4:
964		dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize - 1);
965		hwwrite(vortex->mmio,
966			VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0xc,
967			snd_pcm_sgbuf_get_addr(dma->substream, psize * 3));
968		/* 3 pages */
969	case 3:
970		dma->cfg0 |= 0x12000000;
971		dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc);
972		hwwrite(vortex->mmio,
973			VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x8,
974			snd_pcm_sgbuf_get_addr(dma->substream, psize * 2));
975		/* 2 pages */
976	case 2:
977		dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize - 1);
978		hwwrite(vortex->mmio,
979			VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x4,
980			snd_pcm_sgbuf_get_addr(dma->substream, psize));
981		/* 1 page */
982	case 1:
983		dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc);
984		hwwrite(vortex->mmio,
985			VORTEX_ADBDMA_BUFBASE + (adbdma << 4),
986			snd_pcm_sgbuf_get_addr(dma->substream, 0));
987		break;
988	}
989	/*
990	printk(KERN_DEBUG "vortex: cfg0 = 0x%x\nvortex: cfg1=0x%x\n",
991	       dma->cfg0, dma->cfg1);
992	*/
993	hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFCFG0 + (adbdma << 3), dma->cfg0);
994	hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFCFG1 + (adbdma << 3), dma->cfg1);
995
996	vortex_adbdma_setfirstbuffer(vortex, adbdma);
997	vortex_adbdma_setstartbuffer(vortex, adbdma, 0);
998}
999
1000static void
1001vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie, int dir,
1002		      int fmt, int d, u32 offset)
1003{
1004	stream_t *dma = &vortex->dma_adb[adbdma];
1005
1006	dma->dma_unknown = d;
1007	dma->dma_ctrl =
1008	    ((offset & OFFSET_MASK) | (dma->dma_ctrl & ~OFFSET_MASK));
1009	/* Enable PCMOUT interrupts. */
1010	dma->dma_ctrl =
1011	    (dma->dma_ctrl & ~IE_MASK) | ((ie << IE_SHIFT) & IE_MASK);
1012
1013	dma->dma_ctrl =
1014	    (dma->dma_ctrl & ~DIR_MASK) | ((dir << DIR_SHIFT) & DIR_MASK);
1015	dma->dma_ctrl =
1016	    (dma->dma_ctrl & ~FMT_MASK) | ((fmt << FMT_SHIFT) & FMT_MASK);
1017
1018	hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
1019		dma->dma_ctrl);
1020	hwread(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2));
1021}
1022
1023static int vortex_adbdma_bufshift(vortex_t * vortex, int adbdma)
1024{
1025	stream_t *dma = &vortex->dma_adb[adbdma];
1026	int page, p, pp, delta, i;
1027
1028	page =
1029	    (hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2)) &
1030	     ADB_SUBBUF_MASK) >> ADB_SUBBUF_SHIFT;
1031	if (dma->nr_periods >= 4)
1032		delta = (page - dma->period_real) & 3;
1033	else {
1034		delta = (page - dma->period_real);
1035		if (delta < 0)
1036			delta += dma->nr_periods;
1037	}
1038	if (delta == 0)
1039		return 0;
1040
1041	/* refresh hw page table */
1042	if (dma->nr_periods > 4) {
1043		for (i = 0; i < delta; i++) {
1044			/* p: audio buffer page index */
1045			p = dma->period_virt + i + 4;
1046			if (p >= dma->nr_periods)
1047				p -= dma->nr_periods;
1048			/* pp: hardware DMA page index. */
1049			pp = dma->period_real + i;
1050			if (pp >= 4)
1051				pp -= 4;
1052			//hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), dma->table[p].addr);
1053			hwwrite(vortex->mmio,
1054				VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),
1055				snd_pcm_sgbuf_get_addr(dma->substream,
1056				dma->period_bytes * p));
1057			/* Force write thru cache. */
1058			hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE +
1059			       (((adbdma << 2) + pp) << 2));
1060		}
1061	}
1062	dma->period_virt += delta;
1063	dma->period_real = page;
1064	if (dma->period_virt >= dma->nr_periods)
1065		dma->period_virt -= dma->nr_periods;
1066	if (delta != 1)
1067		printk(KERN_INFO "vortex: %d virt=%d, real=%d, delta=%d\n",
1068		       adbdma, dma->period_virt, dma->period_real, delta);
1069
1070	return delta;
1071}
1072
1073
1074static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) {
1075	stream_t *dma = &vortex->dma_adb[adbdma];
1076	int p, pp, i;
1077
1078	/* refresh hw page table */
1079	for (i=0 ; i < 4 && i < dma->nr_periods; i++) {
1080		/* p: audio buffer page index */
1081		p = dma->period_virt + i;
1082		if (p >= dma->nr_periods)
1083			p -= dma->nr_periods;
1084		/* pp: hardware DMA page index. */
1085		pp = dma->period_real + i;
1086		if (dma->nr_periods < 4) {
1087			if (pp >= dma->nr_periods)
1088				pp -= dma->nr_periods;
1089		}
1090		else {
1091			if (pp >= 4)
1092				pp -= 4;
1093		}
1094		hwwrite(vortex->mmio,
1095			VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2),
1096			snd_pcm_sgbuf_get_addr(dma->substream,
1097					       dma->period_bytes * p));
1098		/* Force write thru cache. */
1099		hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (((adbdma << 2)+pp) << 2));
1100	}
1101}
1102
1103static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma)
1104{
1105	stream_t *dma = &vortex->dma_adb[adbdma];
1106	int temp;
1107
1108	temp = hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2));
1109	temp = (dma->period_virt * dma->period_bytes) + (temp & (dma->period_bytes - 1));
1110	return temp;
1111}
1112
1113static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma)
1114{
1115	int this_8 = 0 /*empty */ , this_4 = 0 /*priority */ ;
1116	stream_t *dma = &vortex->dma_adb[adbdma];
1117
1118	switch (dma->fifo_status) {
1119	case FIFO_START:
1120		vortex_fifo_setadbvalid(vortex, adbdma,
1121					dma->fifo_enabled ? 1 : 0);
1122		break;
1123	case FIFO_STOP:
1124		this_8 = 1;
1125		hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
1126			dma->dma_ctrl);
1127		vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1128				       this_4, this_8,
1129				       dma->fifo_enabled ? 1 : 0, 0);
1130		break;
1131	case FIFO_PAUSE:
1132		vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1133				       this_4, this_8,
1134				       dma->fifo_enabled ? 1 : 0, 0);
1135		break;
1136	}
1137	dma->fifo_status = FIFO_START;
1138}
1139
1140static void vortex_adbdma_resumefifo(vortex_t * vortex, int adbdma)
1141{
1142	stream_t *dma = &vortex->dma_adb[adbdma];
1143
1144	int this_8 = 1, this_4 = 0;
1145	switch (dma->fifo_status) {
1146	case FIFO_STOP:
1147		hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
1148			dma->dma_ctrl);
1149		vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1150				       this_4, this_8,
1151				       dma->fifo_enabled ? 1 : 0, 0);
1152		break;
1153	case FIFO_PAUSE:
1154		vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1155				       this_4, this_8,
1156				       dma->fifo_enabled ? 1 : 0, 0);
1157		break;
1158	}
1159	dma->fifo_status = FIFO_START;
1160}
1161
1162static void vortex_adbdma_pausefifo(vortex_t * vortex, int adbdma)
1163{
1164	stream_t *dma = &vortex->dma_adb[adbdma];
1165
1166	int this_8 = 0, this_4 = 0;
1167	switch (dma->fifo_status) {
1168	case FIFO_START:
1169		vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1170				       this_4, this_8, 0, 0);
1171		break;
1172	case FIFO_STOP:
1173		hwwrite(vortex->mmio, VORTEX_ADBDMA_CTRL + (adbdma << 2),
1174			dma->dma_ctrl);
1175		vortex_fifo_setadbctrl(vortex, adbdma, dma->dma_unknown,
1176				       this_4, this_8, 0, 0);
1177		break;
1178	}
1179	dma->fifo_status = FIFO_PAUSE;
1180}
1181
1182/* WTDMA */
1183
1184#ifndef CHIP_AU8810
1185static void vortex_wtdma_setfirstbuffer(vortex_t * vortex, int wtdma)
1186{
1187	//int this_7c=dma_ctrl;
1188	stream_t *dma = &vortex->dma_wt[wtdma];
1189
1190	hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2), dma->dma_ctrl);
1191}
1192
1193static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb)
1194{
1195	stream_t *dma = &vortex->dma_wt[wtdma];
1196	//hwwrite(vortex->mmio, VORTEX_WTDMA_START + (wtdma << 2), sb << ((0x1f-(wtdma&0xf)*2)));
1197	hwwrite(vortex->mmio, VORTEX_WTDMA_START + (wtdma << 2),
1198		sb << ((0xf - (wtdma & 0xf)) * 2));
1199	dma->period_real = dma->period_virt = sb;
1200}
1201
1202static void
1203vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma,
1204			int psize, int count)
1205{
1206	stream_t *dma = &vortex->dma_wt[wtdma];
1207
1208	dma->period_bytes = psize;
1209	dma->nr_periods = count;
1210
1211	dma->cfg0 = 0;
1212	dma->cfg1 = 0;
1213	switch (count) {
1214		/* Four or more pages */
1215	default:
1216	case 4:
1217		dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize-1);
1218		hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0xc,
1219			snd_pcm_sgbuf_get_addr(dma->substream, psize * 3));
1220		/* 3 pages */
1221	case 3:
1222		dma->cfg0 |= 0x12000000;
1223		dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);
1224		hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4)  + 0x8,
1225			snd_pcm_sgbuf_get_addr(dma->substream, psize * 2));
1226		/* 2 pages */
1227	case 2:
1228		dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize-1);
1229		hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x4,
1230			snd_pcm_sgbuf_get_addr(dma->substream, psize));
1231		/* 1 page */
1232	case 1:
1233		dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc);
1234		hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4),
1235			snd_pcm_sgbuf_get_addr(dma->substream, 0));
1236		break;
1237	}
1238	hwwrite(vortex->mmio, VORTEX_WTDMA_BUFCFG0 + (wtdma << 3), dma->cfg0);
1239	hwwrite(vortex->mmio, VORTEX_WTDMA_BUFCFG1 + (wtdma << 3), dma->cfg1);
1240
1241	vortex_wtdma_setfirstbuffer(vortex, wtdma);
1242	vortex_wtdma_setstartbuffer(vortex, wtdma, 0);
1243}
1244
1245static void
1246vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d,
1247		     /*int e, */ u32 offset)
1248{
1249	stream_t *dma = &vortex->dma_wt[wtdma];
1250
1251	//dma->this_08 = e;
1252	dma->dma_unknown = d;
1253	dma->dma_ctrl = 0;
1254	dma->dma_ctrl =
1255	    ((offset & OFFSET_MASK) | (dma->dma_ctrl & ~OFFSET_MASK));
1256	/* PCMOUT interrupt */
1257	dma->dma_ctrl =
1258	    (dma->dma_ctrl & ~IE_MASK) | ((ie << IE_SHIFT) & IE_MASK);
1259	/* Always playback. */
1260	dma->dma_ctrl |= (1 << DIR_SHIFT);
1261	/* Audio Format */
1262	dma->dma_ctrl =
1263	    (dma->dma_ctrl & FMT_MASK) | ((fmt << FMT_SHIFT) & FMT_MASK);
1264	/* Write into hardware */
1265	hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2), dma->dma_ctrl);
1266}
1267
1268static int vortex_wtdma_bufshift(vortex_t * vortex, int wtdma)
1269{
1270	stream_t *dma = &vortex->dma_wt[wtdma];
1271	int page, p, pp, delta, i;
1272
1273	page =
1274	    (hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2)) &
1275	     WT_SUBBUF_MASK)
1276	    >> WT_SUBBUF_SHIFT;
1277	if (dma->nr_periods >= 4)
1278		delta = (page - dma->period_real) & 3;
1279	else {
1280		delta = (page - dma->period_real);
1281		if (delta < 0)
1282			delta += dma->nr_periods;
1283	}
1284	if (delta == 0)
1285		return 0;
1286
1287	/* refresh hw page table */
1288	if (dma->nr_periods > 4) {
1289		for (i = 0; i < delta; i++) {
1290			/* p: audio buffer page index */
1291			p = dma->period_virt + i + 4;
1292			if (p >= dma->nr_periods)
1293				p -= dma->nr_periods;
1294			/* pp: hardware DMA page index. */
1295			pp = dma->period_real + i;
1296			if (pp >= 4)
1297				pp -= 4;
1298			hwwrite(vortex->mmio,
1299				VORTEX_WTDMA_BUFBASE +
1300				(((wtdma << 2) + pp) << 2),
1301				snd_pcm_sgbuf_get_addr(dma->substream,
1302						       dma->period_bytes * p));
1303			/* Force write thru cache. */
1304			hwread(vortex->mmio, VORTEX_WTDMA_BUFBASE +
1305			       (((wtdma << 2) + pp) << 2));
1306		}
1307	}
1308	dma->period_virt += delta;
1309	if (dma->period_virt >= dma->nr_periods)
1310		dma->period_virt -= dma->nr_periods;
1311	dma->period_real = page;
1312
1313	if (delta != 1)
1314		printk(KERN_WARNING "vortex: wt virt = %d, delta = %d\n",
1315		       dma->period_virt, delta);
1316
1317	return delta;
1318}
1319
1320static int inline vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma)
1321{
1322	stream_t *dma = &vortex->dma_wt[wtdma];
1323	int temp;
1324
1325	temp = hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2));
1326	temp = (dma->period_virt * dma->period_bytes) + (temp & (dma->period_bytes - 1));
1327	return temp;
1328}
1329
1330static void vortex_wtdma_startfifo(vortex_t * vortex, int wtdma)
1331{
1332	stream_t *dma = &vortex->dma_wt[wtdma];
1333	int this_8 = 0, this_4 = 0;
1334
1335	switch (dma->fifo_status) {
1336	case FIFO_START:
1337		vortex_fifo_setwtvalid(vortex, wtdma,
1338				       dma->fifo_enabled ? 1 : 0);
1339		break;
1340	case FIFO_STOP:
1341		this_8 = 1;
1342		hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2),
1343			dma->dma_ctrl);
1344		vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1345				      this_4, this_8,
1346				      dma->fifo_enabled ? 1 : 0, 0);
1347		break;
1348	case FIFO_PAUSE:
1349		vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1350				      this_4, this_8,
1351				      dma->fifo_enabled ? 1 : 0, 0);
1352		break;
1353	}
1354	dma->fifo_status = FIFO_START;
1355}
1356
1357static void vortex_wtdma_resumefifo(vortex_t * vortex, int wtdma)
1358{
1359	stream_t *dma = &vortex->dma_wt[wtdma];
1360
1361	int this_8 = 0, this_4 = 0;
1362	switch (dma->fifo_status) {
1363	case FIFO_STOP:
1364		hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2),
1365			dma->dma_ctrl);
1366		vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1367				      this_4, this_8,
1368				      dma->fifo_enabled ? 1 : 0, 0);
1369		break;
1370	case FIFO_PAUSE:
1371		vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1372				      this_4, this_8,
1373				      dma->fifo_enabled ? 1 : 0, 0);
1374		break;
1375	}
1376	dma->fifo_status = FIFO_START;
1377}
1378
1379static void vortex_wtdma_pausefifo(vortex_t * vortex, int wtdma)
1380{
1381	stream_t *dma = &vortex->dma_wt[wtdma];
1382
1383	int this_8 = 0, this_4 = 0;
1384	switch (dma->fifo_status) {
1385	case FIFO_START:
1386		vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1387				      this_4, this_8, 0, 0);
1388		break;
1389	case FIFO_STOP:
1390		hwwrite(vortex->mmio, VORTEX_WTDMA_CTRL + (wtdma << 2),
1391			dma->dma_ctrl);
1392		vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1393				      this_4, this_8, 0, 0);
1394		break;
1395	}
1396	dma->fifo_status = FIFO_PAUSE;
1397}
1398
1399static void vortex_wtdma_stopfifo(vortex_t * vortex, int wtdma)
1400{
1401	stream_t *dma = &vortex->dma_wt[wtdma];
1402
1403	int this_4 = 0, this_8 = 0;
1404	if (dma->fifo_status == FIFO_START)
1405		vortex_fifo_setwtctrl(vortex, wtdma, dma->dma_unknown,
1406				      this_4, this_8, 0, 0);
1407	else if (dma->fifo_status == FIFO_STOP)
1408		return;
1409	dma->fifo_status = FIFO_STOP;
1410	dma->fifo_enabled = 0;
1411}
1412
1413#endif
1414/* ADB Routes */
1415
1416typedef int ADBRamLink;
1417static void vortex_adb_init(vortex_t * vortex)
1418{
1419	int i;
1420	/* it looks like we are writing more than we need to...
1421	 * if we write what we are supposed to it breaks things... */
1422	hwwrite(vortex->mmio, VORTEX_ADB_SR, 0);
1423	for (i = 0; i < VORTEX_ADB_RTBASE_COUNT; i++)
1424		hwwrite(vortex->mmio, VORTEX_ADB_RTBASE + (i << 2),
1425			hwread(vortex->mmio,
1426			       VORTEX_ADB_RTBASE + (i << 2)) | ROUTE_MASK);
1427	for (i = 0; i < VORTEX_ADB_CHNBASE_COUNT; i++) {
1428		hwwrite(vortex->mmio, VORTEX_ADB_CHNBASE + (i << 2),
1429			hwread(vortex->mmio,
1430			       VORTEX_ADB_CHNBASE + (i << 2)) | ROUTE_MASK);
1431	}
1432}
1433
1434static void vortex_adb_en_sr(vortex_t * vortex, int channel)
1435{
1436	hwwrite(vortex->mmio, VORTEX_ADB_SR,
1437		hwread(vortex->mmio, VORTEX_ADB_SR) | (0x1 << channel));
1438}
1439
1440static void vortex_adb_dis_sr(vortex_t * vortex, int channel)
1441{
1442	hwwrite(vortex->mmio, VORTEX_ADB_SR,
1443		hwread(vortex->mmio, VORTEX_ADB_SR) & ~(0x1 << channel));
1444}
1445
1446static void
1447vortex_adb_addroutes(vortex_t * vortex, unsigned char channel,
1448		     ADBRamLink * route, int rnum)
1449{
1450	int temp, prev, lifeboat = 0;
1451
1452	if ((rnum <= 0) || (route == NULL))
1453		return;
1454	/* Write last routes. */
1455	rnum--;
1456	hwwrite(vortex->mmio,
1457		VORTEX_ADB_RTBASE + ((route[rnum] & ADB_MASK) << 2),
1458		ROUTE_MASK);
1459	while (rnum > 0) {
1460		hwwrite(vortex->mmio,
1461			VORTEX_ADB_RTBASE +
1462			((route[rnum - 1] & ADB_MASK) << 2), route[rnum]);
1463		rnum--;
1464	}
1465	/* Write first route. */
1466	temp =
1467	    hwread(vortex->mmio,
1468		   VORTEX_ADB_CHNBASE + (channel << 2)) & ADB_MASK;
1469	if (temp == ADB_MASK) {
1470		/* First entry on this channel. */
1471		hwwrite(vortex->mmio, VORTEX_ADB_CHNBASE + (channel << 2),
1472			route[0]);
1473		vortex_adb_en_sr(vortex, channel);
1474		return;
1475	}
1476	/* Not first entry on this channel. Need to link. */
1477	do {
1478		prev = temp;
1479		temp =
1480		    hwread(vortex->mmio,
1481			   VORTEX_ADB_RTBASE + (temp << 2)) & ADB_MASK;
1482		if ((lifeboat++) > ADB_MASK) {
1483			printk(KERN_ERR
1484			       "vortex_adb_addroutes: unending route! 0x%x\n",
1485			       *route);
1486			return;
1487		}
1488	}
1489	while (temp != ADB_MASK);
1490	hwwrite(vortex->mmio, VORTEX_ADB_RTBASE + (prev << 2), route[0]);
1491}
1492
1493static void
1494vortex_adb_delroutes(vortex_t * vortex, unsigned char channel,
1495		     ADBRamLink route0, ADBRamLink route1)
1496{
1497	int temp, lifeboat = 0, prev;
1498
1499	/* Find route. */
1500	temp =
1501	    hwread(vortex->mmio,
1502		   VORTEX_ADB_CHNBASE + (channel << 2)) & ADB_MASK;
1503	if (temp == (route0 & ADB_MASK)) {
1504		temp =
1505		    hwread(vortex->mmio,
1506			   VORTEX_ADB_RTBASE + ((route1 & ADB_MASK) << 2));
1507		if ((temp & ADB_MASK) == ADB_MASK)
1508			vortex_adb_dis_sr(vortex, channel);
1509		hwwrite(vortex->mmio, VORTEX_ADB_CHNBASE + (channel << 2),
1510			temp);
1511		return;
1512	}
1513	do {
1514		prev = temp;
1515		temp =
1516		    hwread(vortex->mmio,
1517			   VORTEX_ADB_RTBASE + (prev << 2)) & ADB_MASK;
1518		if (((lifeboat++) > ADB_MASK) || (temp == ADB_MASK)) {
1519			printk(KERN_ERR
1520			       "vortex_adb_delroutes: route not found! 0x%x\n",
1521			       route0);
1522			return;
1523		}
1524	}
1525	while (temp != (route0 & ADB_MASK));
1526	temp = hwread(vortex->mmio, VORTEX_ADB_RTBASE + (temp << 2));
1527	if ((temp & ADB_MASK) == route1)
1528		temp = hwread(vortex->mmio, VORTEX_ADB_RTBASE + (temp << 2));
1529	/* Make bridge over deleted route. */
1530	hwwrite(vortex->mmio, VORTEX_ADB_RTBASE + (prev << 2), temp);
1531}
1532
1533static void
1534vortex_route(vortex_t * vortex, int en, unsigned char channel,
1535	     unsigned char source, unsigned char dest)
1536{
1537	ADBRamLink route;
1538
1539	route = ((source & ADB_MASK) << ADB_SHIFT) | (dest & ADB_MASK);
1540	if (en) {
1541		vortex_adb_addroutes(vortex, channel, &route, 1);
1542		if ((source < (OFFSET_SRCOUT + NR_SRC))
1543		    && (source >= OFFSET_SRCOUT))
1544			vortex_src_addWTD(vortex, (source - OFFSET_SRCOUT),
1545					  channel);
1546		else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))
1547			 && (source >= OFFSET_MIXOUT))
1548			vortex_mixer_addWTD(vortex,
1549					    (source - OFFSET_MIXOUT), channel);
1550	} else {
1551		vortex_adb_delroutes(vortex, channel, route, route);
1552		if ((source < (OFFSET_SRCOUT + NR_SRC))
1553		    && (source >= OFFSET_SRCOUT))
1554			vortex_src_delWTD(vortex, (source - OFFSET_SRCOUT),
1555					  channel);
1556		else if ((source < (OFFSET_MIXOUT + NR_MIXOUT))
1557			 && (source >= OFFSET_MIXOUT))
1558			vortex_mixer_delWTD(vortex,
1559					    (source - OFFSET_MIXOUT), channel);
1560	}
1561}
1562
1563/* Route two sources to same target. Sources must be of same class !!! */
1564static void
1565vortex_routeLRT(vortex_t * vortex, int en, unsigned char ch,
1566		unsigned char source0, unsigned char source1,
1567		unsigned char dest)
1568{
1569	ADBRamLink route[2];
1570
1571	route[0] = ((source0 & ADB_MASK) << ADB_SHIFT) | (dest & ADB_MASK);
1572	route[1] = ((source1 & ADB_MASK) << ADB_SHIFT) | (dest & ADB_MASK);
1573
1574	if (dest < 0x10)
1575		route[1] = (route[1] & ~ADB_MASK) | (dest + 0x20);	/* fifo A */
1576
1577	if (en) {
1578		vortex_adb_addroutes(vortex, ch, route, 2);
1579		if ((source0 < (OFFSET_SRCOUT + NR_SRC))
1580		    && (source0 >= OFFSET_SRCOUT)) {
1581			vortex_src_addWTD(vortex,
1582					  (source0 - OFFSET_SRCOUT), ch);
1583			vortex_src_addWTD(vortex,
1584					  (source1 - OFFSET_SRCOUT), ch);
1585		} else if ((source0 < (OFFSET_MIXOUT + NR_MIXOUT))
1586			   && (source0 >= OFFSET_MIXOUT)) {
1587			vortex_mixer_addWTD(vortex,
1588					    (source0 - OFFSET_MIXOUT), ch);
1589			vortex_mixer_addWTD(vortex,
1590					    (source1 - OFFSET_MIXOUT), ch);
1591		}
1592	} else {
1593		vortex_adb_delroutes(vortex, ch, route[0], route[1]);
1594		if ((source0 < (OFFSET_SRCOUT + NR_SRC))
1595		    && (source0 >= OFFSET_SRCOUT)) {
1596			vortex_src_delWTD(vortex,
1597					  (source0 - OFFSET_SRCOUT), ch);
1598			vortex_src_delWTD(vortex,
1599					  (source1 - OFFSET_SRCOUT), ch);
1600		} else if ((source0 < (OFFSET_MIXOUT + NR_MIXOUT))
1601			   && (source0 >= OFFSET_MIXOUT)) {
1602			vortex_mixer_delWTD(vortex,
1603					    (source0 - OFFSET_MIXOUT), ch);
1604			vortex_mixer_delWTD(vortex,
1605					    (source1 - OFFSET_MIXOUT), ch);
1606		}
1607	}
1608}
1609
1610/* Connection stuff */
1611
1612// Connect adbdma to src('s).
1613static void
1614vortex_connection_adbdma_src(vortex_t * vortex, int en, unsigned char ch,
1615			     unsigned char adbdma, unsigned char src)
1616{
1617	vortex_route(vortex, en, ch, ADB_DMA(adbdma), ADB_SRCIN(src));
1618}
1619
1620// Connect SRC to mixin.
1621static void
1622vortex_connection_src_mixin(vortex_t * vortex, int en,
1623			    unsigned char channel, unsigned char src,
1624			    unsigned char mixin)
1625{
1626	vortex_route(vortex, en, channel, ADB_SRCOUT(src), ADB_MIXIN(mixin));
1627}
1628
1629// Connect mixin with mix output.
1630static void
1631vortex_connection_mixin_mix(vortex_t * vortex, int en, unsigned char mixin,
1632			    unsigned char mix, int a)
1633{
1634	if (en) {
1635		vortex_mix_enableinput(vortex, mix, mixin);
1636		vortex_mix_setinputvolumebyte(vortex, mix, mixin, MIX_DEFIGAIN);	// added to original code.
1637	} else
1638		vortex_mix_disableinput(vortex, mix, mixin, a);
1639}
1640
1641// Connect absolut address to mixin.
1642static void
1643vortex_connection_adb_mixin(vortex_t * vortex, int en,
1644			    unsigned char channel, unsigned char source,
1645			    unsigned char mixin)
1646{
1647	vortex_route(vortex, en, channel, source, ADB_MIXIN(mixin));
1648}
1649
1650static void
1651vortex_connection_src_adbdma(vortex_t * vortex, int en, unsigned char ch,
1652			     unsigned char src, unsigned char adbdma)
1653{
1654	vortex_route(vortex, en, ch, ADB_SRCOUT(src), ADB_DMA(adbdma));
1655}
1656
1657static void
1658vortex_connection_src_src_adbdma(vortex_t * vortex, int en,
1659				 unsigned char ch, unsigned char src0,
1660				 unsigned char src1, unsigned char adbdma)
1661{
1662
1663	vortex_routeLRT(vortex, en, ch, ADB_SRCOUT(src0), ADB_SRCOUT(src1),
1664			ADB_DMA(adbdma));
1665}
1666
1667// mix to absolut address.
1668static void
1669vortex_connection_mix_adb(vortex_t * vortex, int en, unsigned char ch,
1670			  unsigned char mix, unsigned char dest)
1671{
1672	vortex_route(vortex, en, ch, ADB_MIXOUT(mix), dest);
1673	vortex_mix_setvolumebyte(vortex, mix, MIX_DEFOGAIN);	// added to original code.
1674}
1675
1676// mixer to src.
1677static void
1678vortex_connection_mix_src(vortex_t * vortex, int en, unsigned char ch,
1679			  unsigned char mix, unsigned char src)
1680{
1681	vortex_route(vortex, en, ch, ADB_MIXOUT(mix), ADB_SRCIN(src));
1682	vortex_mix_setvolumebyte(vortex, mix, MIX_DEFOGAIN);	// added to original code.
1683}
1684
1685
1686/* CODEC connect. */
1687
1688static void
1689vortex_connect_codecplay(vortex_t * vortex, int en, unsigned char mixers[])
1690{
1691#ifdef CHIP_AU8820
1692	vortex_connection_mix_adb(vortex, en, 0x11, mixers[0], ADB_CODECOUT(0));
1693	vortex_connection_mix_adb(vortex, en, 0x11, mixers[1], ADB_CODECOUT(1));
1694#else
1695	// Connect front channels through EQ.
1696	vortex_connection_mix_adb(vortex, en, 0x11, mixers[0], ADB_EQIN(0));
1697	vortex_connection_mix_adb(vortex, en, 0x11, mixers[1], ADB_EQIN(1));
1698	/* Lower volume, since EQ has some gain. */
1699	vortex_mix_setvolumebyte(vortex, mixers[0], 0);
1700	vortex_mix_setvolumebyte(vortex, mixers[1], 0);
1701	vortex_route(vortex, en, 0x11, ADB_EQOUT(0), ADB_CODECOUT(0));
1702	vortex_route(vortex, en, 0x11, ADB_EQOUT(1), ADB_CODECOUT(1));
1703
1704	/* Check if reg 0x28 has SDAC bit set. */
1705	if (VORTEX_IS_QUAD(vortex)) {
1706		/* Rear channel. Note: ADB_CODECOUT(0+2) and (1+2) is for AC97 modem */
1707		vortex_connection_mix_adb(vortex, en, 0x11, mixers[2],
1708					  ADB_CODECOUT(0 + 4));
1709		vortex_connection_mix_adb(vortex, en, 0x11, mixers[3],
1710					  ADB_CODECOUT(1 + 4));
1711		/* printk(KERN_DEBUG "SDAC detected "); */
1712	}
1713#endif
1714}
1715
1716static void
1717vortex_connect_codecrec(vortex_t * vortex, int en, unsigned char mixin0,
1718			unsigned char mixin1)
1719{
1720	/*
1721	   Enable: 0x1, 0x1
1722	   Channel: 0x11, 0x11
1723	   ADB Source address: 0x48, 0x49
1724	   Destination Asp4Topology_0x9c,0x98
1725	 */
1726	vortex_connection_adb_mixin(vortex, en, 0x11, ADB_CODECIN(0), mixin0);
1727	vortex_connection_adb_mixin(vortex, en, 0x11, ADB_CODECIN(1), mixin1);
1728}
1729
1730// Higher level ADB audio path (de)allocator.
1731
1732/* Resource manager */
1733static int resnum[VORTEX_RESOURCE_LAST] =
1734    { NR_ADB, NR_SRC, NR_MIXIN, NR_MIXOUT, NR_A3D };
1735/*
1736 Checkout/Checkin resource of given type.
1737 resmap: resource map to be used. If NULL means that we want to allocate
1738 a DMA resource (root of all other resources of a dma channel).
1739 out: Mean checkout if != 0. Else mean Checkin resource.
1740 restype: Indicates type of resource to be checked in or out.
1741*/
1742static char
1743vortex_adb_checkinout(vortex_t * vortex, int resmap[], int out, int restype)
1744{
1745	int i, qty = resnum[restype], resinuse = 0;
1746
1747	if (out) {
1748		/* Gather used resources by all streams. */
1749		for (i = 0; i < NR_ADB; i++) {
1750			resinuse |= vortex->dma_adb[i].resources[restype];
1751		}
1752		resinuse |= vortex->fixed_res[restype];
1753		/* Find and take free resource. */
1754		for (i = 0; i < qty; i++) {
1755			if ((resinuse & (1 << i)) == 0) {
1756				if (resmap != NULL)
1757					resmap[restype] |= (1 << i);
1758				else
1759					vortex->dma_adb[i].resources[restype] |= (1 << i);
1760				/*
1761				printk(KERN_DEBUG
1762				       "vortex: ResManager: type %d out %d\n",
1763				       restype, i);
1764				*/
1765				return i;
1766			}
1767		}
1768	} else {
1769		if (resmap == NULL)
1770			return -EINVAL;
1771		/* Checkin first resource of type restype. */
1772		for (i = 0; i < qty; i++) {
1773			if (resmap[restype] & (1 << i)) {
1774				resmap[restype] &= ~(1 << i);
1775				/*
1776				printk(KERN_DEBUG
1777				       "vortex: ResManager: type %d in %d\n",
1778				       restype, i);
1779				*/
1780				return i;
1781			}
1782		}
1783	}
1784	printk(KERN_ERR "vortex: FATAL: ResManager: resource type %d exhausted.\n", restype);
1785	return -ENOMEM;
1786}
1787
1788/* Default Connections  */
1789static int
1790vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type);
1791
1792static void vortex_connect_default(vortex_t * vortex, int en)
1793{
1794	// Connect AC97 codec.
1795	vortex->mixplayb[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
1796				  VORTEX_RESOURCE_MIXOUT);
1797	vortex->mixplayb[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
1798				  VORTEX_RESOURCE_MIXOUT);
1799	if (VORTEX_IS_QUAD(vortex)) {
1800		vortex->mixplayb[2] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
1801					  VORTEX_RESOURCE_MIXOUT);
1802		vortex->mixplayb[3] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
1803					  VORTEX_RESOURCE_MIXOUT);
1804	}
1805	vortex_connect_codecplay(vortex, en, vortex->mixplayb);
1806
1807	vortex->mixcapt[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
1808				  VORTEX_RESOURCE_MIXIN);
1809	vortex->mixcapt[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
1810				  VORTEX_RESOURCE_MIXIN);
1811	vortex_connect_codecrec(vortex, en, MIX_CAPT(0), MIX_CAPT(1));
1812
1813	// Connect SPDIF
1814#ifndef CHIP_AU8820
1815	vortex->mixspdif[0] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
1816				  VORTEX_RESOURCE_MIXOUT);
1817	vortex->mixspdif[1] = vortex_adb_checkinout(vortex, vortex->fixed_res, en,
1818				  VORTEX_RESOURCE_MIXOUT);
1819	vortex_connection_mix_adb(vortex, en, 0x14, vortex->mixspdif[0],
1820				  ADB_SPDIFOUT(0));
1821	vortex_connection_mix_adb(vortex, en, 0x14, vortex->mixspdif[1],
1822				  ADB_SPDIFOUT(1));
1823#endif
1824	// Connect WT
1825#ifndef CHIP_AU8810
1826	vortex_wt_connect(vortex, en);
1827#endif
1828	// A3D (crosstalk canceler and A3D slices). AU8810 disabled for now.
1829#ifndef CHIP_AU8820
1830	vortex_Vort3D_connect(vortex, en);
1831#endif
1832	// Connect I2S
1833
1834	// Connect DSP interface for SQ3500 turbo (not here i think...)
1835
1836	// Connect AC98 modem codec
1837
1838}
1839
1840/*
1841  Allocate nr_ch pcm audio routes if dma < 0. If dma >= 0, existing routes
1842  are deallocated.
1843  dma: DMA engine routes to be deallocated when dma >= 0.
1844  nr_ch: Number of channels to be de/allocated.
1845  dir: direction of stream. Uses same values as substream->stream.
1846  type: Type of audio output/source (codec, spdif, i2s, dsp, etc)
1847  Return: Return allocated DMA or same DMA passed as "dma" when dma >= 0.
1848*/
1849static int
1850vortex_adb_allocroute(vortex_t * vortex, int dma, int nr_ch, int dir, int type)
1851{
1852	stream_t *stream;
1853	int i, en;
1854
1855	if ((nr_ch == 3)
1856	    || ((dir == SNDRV_PCM_STREAM_CAPTURE) && (nr_ch > 2)))
1857		return -EBUSY;
1858
1859	if (dma >= 0) {
1860		en = 0;
1861		vortex_adb_checkinout(vortex,
1862				      vortex->dma_adb[dma].resources, en,
1863				      VORTEX_RESOURCE_DMA);
1864	} else {
1865		en = 1;
1866		if ((dma =
1867		     vortex_adb_checkinout(vortex, NULL, en,
1868					   VORTEX_RESOURCE_DMA)) < 0)
1869			return -EBUSY;
1870	}
1871
1872	stream = &vortex->dma_adb[dma];
1873	stream->dma = dma;
1874	stream->dir = dir;
1875	stream->type = type;
1876
1877	/* PLAYBACK ROUTES. */
1878	if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
1879		int src[4], mix[4], ch_top;
1880#ifndef CHIP_AU8820
1881		int a3d = 0;
1882#endif
1883		/* Get SRC and MIXER hardware resources. */
1884		if (stream->type != VORTEX_PCM_SPDIF) {
1885			for (i = 0; i < nr_ch; i++) {
1886				if ((src[i] = vortex_adb_checkinout(vortex,
1887							   stream->resources, en,
1888							   VORTEX_RESOURCE_SRC)) < 0) {
1889					memset(stream->resources, 0,
1890					       sizeof(unsigned char) *
1891					       VORTEX_RESOURCE_LAST);
1892					return -EBUSY;
1893				}
1894				if (stream->type != VORTEX_PCM_A3D) {
1895					if ((mix[i] = vortex_adb_checkinout(vortex,
1896								   stream->resources,
1897								   en,
1898								   VORTEX_RESOURCE_MIXIN)) < 0) {
1899						memset(stream->resources,
1900						       0,
1901						       sizeof(unsigned char) * VORTEX_RESOURCE_LAST);
1902						return -EBUSY;
1903					}
1904				}
1905			}
1906		}
1907#ifndef CHIP_AU8820
1908		if (stream->type == VORTEX_PCM_A3D) {
1909			if ((a3d =
1910			     vortex_adb_checkinout(vortex,
1911						   stream->resources, en,
1912						   VORTEX_RESOURCE_A3D)) < 0) {
1913				memset(stream->resources, 0,
1914				       sizeof(unsigned char) *
1915				       VORTEX_RESOURCE_LAST);
1916				printk(KERN_ERR "vortex: out of A3D sources. Sorry\n");
1917				return -EBUSY;
1918			}
1919			/* (De)Initialize A3D hardware source. */
1920			vortex_Vort3D_InitializeSource(&(vortex->a3d[a3d]), en);
1921		}
1922		/* Make SPDIF out exclusive to "spdif" device when in use. */
1923		if ((stream->type == VORTEX_PCM_SPDIF) && (en)) {
1924			vortex_route(vortex, 0, 0x14,
1925				     ADB_MIXOUT(vortex->mixspdif[0]),
1926				     ADB_SPDIFOUT(0));
1927			vortex_route(vortex, 0, 0x14,
1928				     ADB_MIXOUT(vortex->mixspdif[1]),
1929				     ADB_SPDIFOUT(1));
1930		}
1931#endif
1932		/* Make playback routes. */
1933		for (i = 0; i < nr_ch; i++) {
1934			if (stream->type == VORTEX_PCM_ADB) {
1935				vortex_connection_adbdma_src(vortex, en,
1936							     src[nr_ch - 1],
1937							     dma,
1938							     src[i]);
1939				vortex_connection_src_mixin(vortex, en,
1940							    0x11, src[i],
1941							    mix[i]);
1942				vortex_connection_mixin_mix(vortex, en,
1943							    mix[i],
1944							    MIX_PLAYB(i), 0);
1945#ifndef CHIP_AU8820
1946				vortex_connection_mixin_mix(vortex, en,
1947							    mix[i],
1948							    MIX_SPDIF(i % 2), 0);
1949				vortex_mix_setinputvolumebyte(vortex,
1950							      MIX_SPDIF(i % 2),
1951							      mix[i],
1952							      MIX_DEFIGAIN);
1953#endif
1954			}
1955#ifndef CHIP_AU8820
1956			if (stream->type == VORTEX_PCM_A3D) {
1957				vortex_connection_adbdma_src(vortex, en,
1958							     src[nr_ch - 1],
1959								 dma,
1960							     src[i]);
1961				vortex_route(vortex, en, 0x11, ADB_SRCOUT(src[i]), ADB_A3DIN(a3d));
1962				/* XTalk test. */
1963				//vortex_route(vortex, en, 0x11, dma, ADB_XTALKIN(i?9:4));
1964				//vortex_route(vortex, en, 0x11, ADB_SRCOUT(src[i]), ADB_XTALKIN(i?4:9));
1965			}
1966			if (stream->type == VORTEX_PCM_SPDIF)
1967				vortex_route(vortex, en, 0x14,
1968					     ADB_DMA(stream->dma),
1969					     ADB_SPDIFOUT(i));
1970#endif
1971		}
1972		if (stream->type != VORTEX_PCM_SPDIF && stream->type != VORTEX_PCM_A3D) {
1973			ch_top = (VORTEX_IS_QUAD(vortex) ? 4 : 2);
1974			for (i = nr_ch; i < ch_top; i++) {
1975				vortex_connection_mixin_mix(vortex, en,
1976							    mix[i % nr_ch],
1977							    MIX_PLAYB(i), 0);
1978#ifndef CHIP_AU8820
1979				vortex_connection_mixin_mix(vortex, en,
1980							    mix[i % nr_ch],
1981							    MIX_SPDIF(i % 2),
1982								0);
1983				vortex_mix_setinputvolumebyte(vortex,
1984							      MIX_SPDIF(i % 2),
1985							      mix[i % nr_ch],
1986							      MIX_DEFIGAIN);
1987#endif
1988			}
1989		}
1990#ifndef CHIP_AU8820
1991		else {
1992			if (nr_ch == 1 && stream->type == VORTEX_PCM_SPDIF)
1993				vortex_route(vortex, en, 0x14,
1994					     ADB_DMA(stream->dma),
1995					     ADB_SPDIFOUT(1));
1996		}
1997		/* Reconnect SPDIF out when "spdif" device is down. */
1998		if ((stream->type == VORTEX_PCM_SPDIF) && (!en)) {
1999			vortex_route(vortex, 1, 0x14,
2000				     ADB_MIXOUT(vortex->mixspdif[0]),
2001				     ADB_SPDIFOUT(0));
2002			vortex_route(vortex, 1, 0x14,
2003				     ADB_MIXOUT(vortex->mixspdif[1]),
2004				     ADB_SPDIFOUT(1));
2005		}
2006#endif
2007	/* CAPTURE ROUTES. */
2008	} else {
2009		int src[2], mix[2];
2010
2011		/* Get SRC and MIXER hardware resources. */
2012		for (i = 0; i < nr_ch; i++) {
2013			if ((mix[i] =
2014			     vortex_adb_checkinout(vortex,
2015						   stream->resources, en,
2016						   VORTEX_RESOURCE_MIXOUT))
2017			    < 0) {
2018				memset(stream->resources, 0,
2019				       sizeof(unsigned char) *
2020				       VORTEX_RESOURCE_LAST);
2021				return -EBUSY;
2022			}
2023			if ((src[i] =
2024			     vortex_adb_checkinout(vortex,
2025						   stream->resources, en,
2026						   VORTEX_RESOURCE_SRC)) < 0) {
2027				memset(stream->resources, 0,
2028				       sizeof(unsigned char) *
2029				       VORTEX_RESOURCE_LAST);
2030				return -EBUSY;
2031			}
2032		}
2033
2034		/* Make capture routes. */
2035		vortex_connection_mixin_mix(vortex, en, MIX_CAPT(0), mix[0], 0);
2036		vortex_connection_mix_src(vortex, en, 0x11, mix[0], src[0]);
2037		if (nr_ch == 1) {
2038			vortex_connection_mixin_mix(vortex, en,
2039						    MIX_CAPT(1), mix[0], 0);
2040			vortex_connection_src_adbdma(vortex, en,
2041						     src[0],
2042						     src[0], dma);
2043		} else {
2044			vortex_connection_mixin_mix(vortex, en,
2045						    MIX_CAPT(1), mix[1], 0);
2046			vortex_connection_mix_src(vortex, en, 0x11, mix[1],
2047						  src[1]);
2048			vortex_connection_src_src_adbdma(vortex, en,
2049							 src[1], src[0],
2050							 src[1], dma);
2051		}
2052	}
2053	vortex->dma_adb[dma].nr_ch = nr_ch;
2054
2055	return dma;
2056}
2057
2058/*
2059 Set the SampleRate of the SRC's attached to the given DMA engine.
2060 */
2061static void
2062vortex_adb_setsrc(vortex_t * vortex, int adbdma, unsigned int rate, int dir)
2063{
2064	stream_t *stream = &(vortex->dma_adb[adbdma]);
2065	int i, cvrt;
2066
2067	/* dir=1:play ; dir=0:rec */
2068	if (dir)
2069		cvrt = SRC_RATIO(rate, 48000);
2070	else
2071		cvrt = SRC_RATIO(48000, rate);
2072
2073	/* Setup SRC's */
2074	for (i = 0; i < NR_SRC; i++) {
2075		if (stream->resources[VORTEX_RESOURCE_SRC] & (1 << i))
2076			vortex_src_setupchannel(vortex, i, cvrt, 0, 0, i, dir, 1, cvrt, dir);
2077	}
2078}
2079
2080// Timer and ISR functions.
2081
2082static void vortex_settimer(vortex_t * vortex, int period)
2083{
2084	//set the timer period to <period> 48000ths of a second.
2085	hwwrite(vortex->mmio, VORTEX_IRQ_STAT, period);
2086}
2087
2088static void vortex_enable_int(vortex_t * card)
2089{
2090	// CAsp4ISR__EnableVortexInt_void_
2091	hwwrite(card->mmio, VORTEX_CTRL,
2092		hwread(card->mmio, VORTEX_CTRL) | CTRL_IRQ_ENABLE);
2093	hwwrite(card->mmio, VORTEX_IRQ_CTRL,
2094		(hwread(card->mmio, VORTEX_IRQ_CTRL) & 0xffffefc0) | 0x24);
2095}
2096
2097static void vortex_disable_int(vortex_t * card)
2098{
2099	hwwrite(card->mmio, VORTEX_CTRL,
2100		hwread(card->mmio, VORTEX_CTRL) & ~CTRL_IRQ_ENABLE);
2101}
2102
2103static irqreturn_t vortex_interrupt(int irq, void *dev_id)
2104{
2105	vortex_t *vortex = dev_id;
2106	int i, handled;
2107	u32 source;
2108
2109	//check if the interrupt is ours.
2110	if (!(hwread(vortex->mmio, VORTEX_STAT) & 0x1))
2111		return IRQ_NONE;
2112
2113	// This is the Interrupt Enable flag we set before (consistency check).
2114	if (!(hwread(vortex->mmio, VORTEX_CTRL) & CTRL_IRQ_ENABLE))
2115		return IRQ_NONE;
2116
2117	source = hwread(vortex->mmio, VORTEX_IRQ_SOURCE);
2118	// Reset IRQ flags.
2119	hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, source);
2120	hwread(vortex->mmio, VORTEX_IRQ_SOURCE);
2121	// Is at least one IRQ flag set?
2122	if (source == 0) {
2123		printk(KERN_ERR "vortex: missing irq source\n");
2124		return IRQ_NONE;
2125	}
2126
2127	handled = 0;
2128	// Attend every interrupt source.
2129	if (unlikely(source & IRQ_ERR_MASK)) {
2130		if (source & IRQ_FATAL) {
2131			printk(KERN_ERR "vortex: IRQ fatal error\n");
2132		}
2133		if (source & IRQ_PARITY) {
2134			printk(KERN_ERR "vortex: IRQ parity error\n");
2135		}
2136		if (source & IRQ_REG) {
2137			printk(KERN_ERR "vortex: IRQ reg error\n");
2138		}
2139		if (source & IRQ_FIFO) {
2140			printk(KERN_ERR "vortex: IRQ fifo error\n");
2141		}
2142		if (source & IRQ_DMA) {
2143			printk(KERN_ERR "vortex: IRQ dma error\n");
2144		}
2145		handled = 1;
2146	}
2147	if (source & IRQ_PCMOUT) {
2148		/* ALSA period acknowledge. */
2149		spin_lock(&vortex->lock);
2150		for (i = 0; i < NR_ADB; i++) {
2151			if (vortex->dma_adb[i].fifo_status == FIFO_START) {
2152				if (!vortex_adbdma_bufshift(vortex, i))
2153					continue;
2154				spin_unlock(&vortex->lock);
2155				snd_pcm_period_elapsed(vortex->dma_adb[i].
2156						       substream);
2157				spin_lock(&vortex->lock);
2158			}
2159		}
2160#ifndef CHIP_AU8810
2161		for (i = 0; i < NR_WT; i++) {
2162			if (vortex->dma_wt[i].fifo_status == FIFO_START) {
2163				if (vortex_wtdma_bufshift(vortex, i)) ;
2164				spin_unlock(&vortex->lock);
2165				snd_pcm_period_elapsed(vortex->dma_wt[i].
2166						       substream);
2167				spin_lock(&vortex->lock);
2168			}
2169		}
2170#endif
2171		spin_unlock(&vortex->lock);
2172		handled = 1;
2173	}
2174	//Acknowledge the Timer interrupt
2175	if (source & IRQ_TIMER) {
2176		hwread(vortex->mmio, VORTEX_IRQ_STAT);
2177		handled = 1;
2178	}
2179	if (source & IRQ_MIDI) {
2180		snd_mpu401_uart_interrupt(vortex->irq,
2181					  vortex->rmidi->private_data);
2182		handled = 1;
2183	}
2184
2185	if (!handled) {
2186		printk(KERN_ERR "vortex: unknown irq source %x\n", source);
2187	}
2188	return IRQ_RETVAL(handled);
2189}
2190
2191/* Codec */
2192
2193#define POLL_COUNT 1000
2194static void vortex_codec_init(vortex_t * vortex)
2195{
2196	int i;
2197
2198	for (i = 0; i < 32; i++) {
2199		/* the windows driver writes -i, so we write -i */
2200		hwwrite(vortex->mmio, (VORTEX_CODEC_CHN + (i << 2)), -i);
2201		msleep(2);
2202	}
2203	if (0) {
2204		hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x8068);
2205		msleep(1);
2206		hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00e8);
2207		msleep(1);
2208	} else {
2209		hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00a8);
2210		msleep(2);
2211		hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80a8);
2212		msleep(2);
2213		hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80e8);
2214		msleep(2);
2215		hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x80a8);
2216		msleep(2);
2217		hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00a8);
2218		msleep(2);
2219		hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0x00e8);
2220	}
2221	for (i = 0; i < 32; i++) {
2222		hwwrite(vortex->mmio, (VORTEX_CODEC_CHN + (i << 2)), -i);
2223		msleep(5);
2224	}
2225	hwwrite(vortex->mmio, VORTEX_CODEC_CTRL, 0xe8);
2226	msleep(1);
2227	/* Enable codec channels 0 and 1. */
2228	hwwrite(vortex->mmio, VORTEX_CODEC_EN,
2229		hwread(vortex->mmio, VORTEX_CODEC_EN) | EN_CODEC);
2230}
2231
2232static void
2233vortex_codec_write(struct snd_ac97 * codec, unsigned short addr, unsigned short data)
2234{
2235
2236	vortex_t *card = (vortex_t *) codec->private_data;
2237	unsigned int lifeboat = 0;
2238
2239	/* wait for transactions to clear */
2240	while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) {
2241		udelay(100);
2242		if (lifeboat++ > POLL_COUNT) {
2243			printk(KERN_ERR "vortex: ac97 codec stuck busy\n");
2244			return;
2245		}
2246	}
2247	/* write register */
2248	hwwrite(card->mmio, VORTEX_CODEC_IO,
2249		((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
2250		((data << VORTEX_CODEC_DATSHIFT) & VORTEX_CODEC_DATMASK) |
2251		VORTEX_CODEC_WRITE |
2252		(codec->num << VORTEX_CODEC_ID_SHIFT) );
2253
2254	/* Flush Caches. */
2255	hwread(card->mmio, VORTEX_CODEC_IO);
2256}
2257
2258static unsigned short vortex_codec_read(struct snd_ac97 * codec, unsigned short addr)
2259{
2260
2261	vortex_t *card = (vortex_t *) codec->private_data;
2262	u32 read_addr, data;
2263	unsigned lifeboat = 0;
2264
2265	/* wait for transactions to clear */
2266	while (!(hwread(card->mmio, VORTEX_CODEC_CTRL) & 0x100)) {
2267		udelay(100);
2268		if (lifeboat++ > POLL_COUNT) {
2269			printk(KERN_ERR "vortex: ac97 codec stuck busy\n");
2270			return 0xffff;
2271		}
2272	}
2273	/* set up read address */
2274	read_addr = ((addr << VORTEX_CODEC_ADDSHIFT) & VORTEX_CODEC_ADDMASK) |
2275		(codec->num << VORTEX_CODEC_ID_SHIFT) ;
2276	hwwrite(card->mmio, VORTEX_CODEC_IO, read_addr);
2277
2278	/* wait for address */
2279	do {
2280		udelay(100);
2281		data = hwread(card->mmio, VORTEX_CODEC_IO);
2282		if (lifeboat++ > POLL_COUNT) {
2283			printk(KERN_ERR "vortex: ac97 address never arrived\n");
2284			return 0xffff;
2285		}
2286	} while ((data & VORTEX_CODEC_ADDMASK) !=
2287		 (addr << VORTEX_CODEC_ADDSHIFT));
2288
2289	/* return data. */
2290	return (u16) (data & VORTEX_CODEC_DATMASK);
2291}
2292
2293/* SPDIF support  */
2294
2295static void vortex_spdif_init(vortex_t * vortex, int spdif_sr, int spdif_mode)
2296{
2297	int i, this_38 = 0, this_04 = 0, this_08 = 0, this_0c = 0;
2298
2299	/* CAsp4Spdif::InitializeSpdifHardware(void) */
2300	hwwrite(vortex->mmio, VORTEX_SPDIF_FLAGS,
2301		hwread(vortex->mmio, VORTEX_SPDIF_FLAGS) & 0xfff3fffd);
2302	//for (i=0x291D4; i<0x29200; i+=4)
2303	for (i = 0; i < 11; i++)
2304		hwwrite(vortex->mmio, VORTEX_SPDIF_CFG1 + (i << 2), 0);
2305	//hwwrite(vortex->mmio, 0x29190, hwread(vortex->mmio, 0x29190) | 0xc0000);
2306	hwwrite(vortex->mmio, VORTEX_CODEC_EN,
2307		hwread(vortex->mmio, VORTEX_CODEC_EN) | EN_SPDIF);
2308
2309	/* CAsp4Spdif::ProgramSRCInHardware(enum  SPDIF_SR,enum  SPDIFMODE) */
2310	if (this_04 && this_08) {
2311		int edi;
2312
2313		i = (((0x5DC00000 / spdif_sr) + 1) >> 1);
2314		if (i > 0x800) {
2315			if (i < 0x1ffff)
2316				edi = (i >> 1);
2317			else
2318				edi = 0x1ffff;
2319		} else {
2320			i = edi = 0x800;
2321		}
2322		/* this_04 and this_08 are the CASp4Src's (samplerate converters) */
2323		vortex_src_setupchannel(vortex, this_04, edi, 0, 1,
2324					this_0c, 1, 0, edi, 1);
2325		vortex_src_setupchannel(vortex, this_08, edi, 0, 1,
2326					this_0c, 1, 0, edi, 1);
2327	}
2328
2329	i = spdif_sr;
2330	spdif_sr |= 0x8c;
2331	switch (i) {
2332	case 32000:
2333		this_38 &= 0xFFFFFFFE;
2334		this_38 &= 0xFFFFFFFD;
2335		this_38 &= 0xF3FFFFFF;
2336		this_38 |= 0x03000000;	/* set 32khz samplerate */
2337		this_38 &= 0xFFFFFF3F;
2338		spdif_sr &= 0xFFFFFFFD;
2339		spdif_sr |= 1;
2340		break;
2341	case 44100:
2342		this_38 &= 0xFFFFFFFE;
2343		this_38 &= 0xFFFFFFFD;
2344		this_38 &= 0xF0FFFFFF;
2345		this_38 |= 0x03000000;
2346		this_38 &= 0xFFFFFF3F;
2347		spdif_sr &= 0xFFFFFFFC;
2348		break;
2349	case 48000:
2350		if (spdif_mode == 1) {
2351			this_38 &= 0xFFFFFFFE;
2352			this_38 &= 0xFFFFFFFD;
2353			this_38 &= 0xF2FFFFFF;
2354			this_38 |= 0x02000000;	/* set 48khz samplerate */
2355			this_38 &= 0xFFFFFF3F;
2356		} else {
2357			/* J. Gordon Wolfe: I think this stuff is for AC3 */
2358			this_38 |= 0x00000003;
2359			this_38 &= 0xFFFFFFBF;
2360			this_38 |= 0x80;
2361		}
2362		spdif_sr |= 2;
2363		spdif_sr &= 0xFFFFFFFE;
2364		break;
2365
2366	}
2367	/* looks like the next 2 lines transfer a 16-bit value into 2 8-bit
2368	   registers. seems to be for the standard IEC/SPDIF initialization
2369	   stuff */
2370	hwwrite(vortex->mmio, VORTEX_SPDIF_CFG0, this_38 & 0xffff);
2371	hwwrite(vortex->mmio, VORTEX_SPDIF_CFG1, this_38 >> 0x10);
2372	hwwrite(vortex->mmio, VORTEX_SPDIF_SMPRATE, spdif_sr);
2373}
2374
2375/* Initialization */
2376
2377static int __devinit vortex_core_init(vortex_t * vortex)
2378{
2379
2380	printk(KERN_INFO "Vortex: init.... ");
2381	/* Hardware Init. */
2382	hwwrite(vortex->mmio, VORTEX_CTRL, 0xffffffff);
2383	msleep(5);
2384	hwwrite(vortex->mmio, VORTEX_CTRL,
2385		hwread(vortex->mmio, VORTEX_CTRL) & 0xffdfffff);
2386	msleep(5);
2387	/* Reset IRQ flags */
2388	hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, 0xffffffff);
2389	hwread(vortex->mmio, VORTEX_IRQ_STAT);
2390
2391	vortex_codec_init(vortex);
2392
2393#ifdef CHIP_AU8830
2394	hwwrite(vortex->mmio, VORTEX_CTRL,
2395		hwread(vortex->mmio, VORTEX_CTRL) | 0x1000000);
2396#endif
2397
2398	/* Init audio engine. */
2399	vortex_adbdma_init(vortex);
2400	hwwrite(vortex->mmio, VORTEX_ENGINE_CTRL, 0x0);	//, 0xc83c7e58, 0xc5f93e58
2401	vortex_adb_init(vortex);
2402	/* Init processing blocks. */
2403	vortex_fifo_init(vortex);
2404	vortex_mixer_init(vortex);
2405	vortex_srcblock_init(vortex);
2406#ifndef CHIP_AU8820
2407	vortex_eq_init(vortex);
2408	vortex_spdif_init(vortex, 48000, 1);
2409	vortex_Vort3D_enable(vortex);
2410#endif
2411#ifndef CHIP_AU8810
2412	vortex_wt_init(vortex);
2413#endif
2414	// Moved to au88x0.c
2415	//vortex_connect_default(vortex, 1);
2416
2417	vortex_settimer(vortex, 0x90);
2418	// Enable Interrupts.
2419	// vortex_enable_int() must be first !!
2420	//  hwwrite(vortex->mmio, VORTEX_IRQ_CTRL, 0);
2421	// vortex_enable_int(vortex);
2422	//vortex_enable_timer_int(vortex);
2423	//vortex_disable_timer_int(vortex);
2424
2425	printk(KERN_INFO "done.\n");
2426	spin_lock_init(&vortex->lock);
2427
2428	return 0;
2429}
2430
2431static int vortex_core_shutdown(vortex_t * vortex)
2432{
2433
2434	printk(KERN_INFO "Vortex: shutdown...");
2435#ifndef CHIP_AU8820
2436	vortex_eq_free(vortex);
2437	vortex_Vort3D_disable(vortex);
2438#endif
2439	//vortex_disable_timer_int(vortex);
2440	vortex_disable_int(vortex);
2441	vortex_connect_default(vortex, 0);
2442	/* Reset all DMA fifos. */
2443	vortex_fifo_init(vortex);
2444	/* Erase all audio routes. */
2445	vortex_adb_init(vortex);
2446
2447	/* Disable MPU401 */
2448	//hwwrite(vortex->mmio, VORTEX_IRQ_CTRL, hwread(vortex->mmio, VORTEX_IRQ_CTRL) & ~IRQ_MIDI);
2449	//hwwrite(vortex->mmio, VORTEX_CTRL, hwread(vortex->mmio, VORTEX_CTRL) & ~CTRL_MIDI_EN);
2450
2451	hwwrite(vortex->mmio, VORTEX_IRQ_CTRL, 0);
2452	hwwrite(vortex->mmio, VORTEX_CTRL, 0);
2453	msleep(5);
2454	hwwrite(vortex->mmio, VORTEX_IRQ_SOURCE, 0xffff);
2455
2456	printk(KERN_INFO "done.\n");
2457	return 0;
2458}
2459
2460/* Alsa support. */
2461
2462static int vortex_alsafmt_aspfmt(int alsafmt)
2463{
2464	int fmt;
2465
2466	switch (alsafmt) {
2467	case SNDRV_PCM_FORMAT_U8:
2468		fmt = 0x1;
2469		break;
2470	case SNDRV_PCM_FORMAT_MU_LAW:
2471		fmt = 0x2;
2472		break;
2473	case SNDRV_PCM_FORMAT_A_LAW:
2474		fmt = 0x3;
2475		break;
2476	case SNDRV_PCM_FORMAT_SPECIAL:
2477		fmt = 0x4;	/* guess. */
2478		break;
2479	case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
2480		fmt = 0x5;	/* guess. */
2481		break;
2482	case SNDRV_PCM_FORMAT_S16_LE:
2483		fmt = 0x8;
2484		break;
2485	case SNDRV_PCM_FORMAT_S16_BE:
2486		fmt = 0x9;	/* check this... */
2487		break;
2488	default:
2489		fmt = 0x8;
2490		printk(KERN_ERR "vortex: format unsupported %d\n", alsafmt);
2491		break;
2492	}
2493	return fmt;
2494}
2495
2496/* Some not yet useful translations. */
2497