• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/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 * Someday its supposed to make use of the WT DMA engine
19 * for a Wavetable synthesizer.
20 */
21
22#include "au88x0.h"
23#include "au88x0_wt.h"
24
25static void vortex_fifo_setwtvalid(vortex_t * vortex, int fifo, int en);
26static void vortex_connection_adb_mixin(vortex_t * vortex, int en,
27					unsigned char channel,
28					unsigned char source,
29					unsigned char mixin);
30static void vortex_connection_mixin_mix(vortex_t * vortex, int en,
31					unsigned char mixin,
32					unsigned char mix, int a);
33static void vortex_fifo_wtinitialize(vortex_t * vortex, int fifo, int j);
34static int vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt,
35			    u32 val);
36
37/* WT */
38
39/* Put 2 WT channels together for one stereo interlaced channel. */
40static void vortex_wt_setstereo(vortex_t * vortex, u32 wt, u32 stereo)
41{
42	int temp;
43
44	//temp = hwread(vortex->mmio, 0x80 + ((wt >> 0x5)<< 0xf) + (((wt & 0x1f) >> 1) << 2));
45	temp = hwread(vortex->mmio, WT_STEREO(wt));
46	temp = (temp & 0xfe) | (stereo & 1);
47	//hwwrite(vortex->mmio, 0x80 + ((wt >> 0x5)<< 0xf) + (((wt & 0x1f) >> 1) << 2), temp);
48	hwwrite(vortex->mmio, WT_STEREO(wt), temp);
49}
50
51/* Join to mixdown route. */
52static void vortex_wt_setdsout(vortex_t * vortex, u32 wt, int en)
53{
54	int temp;
55
56	/* There is one DSREG register for each bank (32 voices each). */
57	temp = hwread(vortex->mmio, WT_DSREG((wt >= 0x20) ? 1 : 0));
58	if (en)
59		temp |= (1 << (wt & 0x1f));
60	else
61		temp &= (1 << ~(wt & 0x1f));
62	hwwrite(vortex->mmio, WT_DSREG((wt >= 0x20) ? 1 : 0), temp);
63}
64
65/* Setup WT route. */
66static int vortex_wt_allocroute(vortex_t * vortex, int wt, int nr_ch)
67{
68	wt_voice_t *voice = &(vortex->wt_voice[wt]);
69	int temp;
70
71	if (nr_ch) {
72		vortex_fifo_wtinitialize(vortex, wt, 1);
73		vortex_fifo_setwtvalid(vortex, wt, 1);
74		vortex_wt_setstereo(vortex, wt, nr_ch - 1);
75	} else
76		vortex_fifo_setwtvalid(vortex, wt, 0);
77
78	/* Set mixdown mode. */
79	vortex_wt_setdsout(vortex, wt, 1);
80	/* Set other parameter registers. */
81	hwwrite(vortex->mmio, WT_SRAMP(0), 0x880000);
82	//hwwrite(vortex->mmio, WT_GMODE(0), 0xffffffff);
83#ifdef CHIP_AU8830
84	hwwrite(vortex->mmio, WT_SRAMP(1), 0x880000);
85	//hwwrite(vortex->mmio, WT_GMODE(1), 0xffffffff);
86#endif
87	hwwrite(vortex->mmio, WT_PARM(wt, 0), 0);
88	hwwrite(vortex->mmio, WT_PARM(wt, 1), 0);
89	hwwrite(vortex->mmio, WT_PARM(wt, 2), 0);
90
91	temp = hwread(vortex->mmio, WT_PARM(wt, 3));
92	printk(KERN_DEBUG "vortex: WT PARM3: %x\n", temp);
93	//hwwrite(vortex->mmio, WT_PARM(wt, 3), temp);
94
95	hwwrite(vortex->mmio, WT_DELAY(wt, 0), 0);
96	hwwrite(vortex->mmio, WT_DELAY(wt, 1), 0);
97	hwwrite(vortex->mmio, WT_DELAY(wt, 2), 0);
98	hwwrite(vortex->mmio, WT_DELAY(wt, 3), 0);
99
100	printk(KERN_DEBUG "vortex: WT GMODE: %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
101
102	hwwrite(vortex->mmio, WT_PARM(wt, 2), 0xffffffff);
103	hwwrite(vortex->mmio, WT_PARM(wt, 3), 0xcff1c810);
104
105	voice->parm0 = voice->parm1 = 0xcfb23e2f;
106	hwwrite(vortex->mmio, WT_PARM(wt, 0), voice->parm0);
107	hwwrite(vortex->mmio, WT_PARM(wt, 1), voice->parm1);
108	printk(KERN_DEBUG "vortex: WT GMODE 2 : %x\n", hwread(vortex->mmio, WT_GMODE(wt)));
109	return 0;
110}
111
112
113static void vortex_wt_connect(vortex_t * vortex, int en)
114{
115	int i, ii, mix;
116
117#define NR_WTROUTES 6
118#ifdef CHIP_AU8830
119#define NR_WTBLOCKS 2
120#else
121#define NR_WTBLOCKS 1
122#endif
123
124	for (i = 0; i < NR_WTBLOCKS; i++) {
125		for (ii = 0; ii < NR_WTROUTES; ii++) {
126			mix =
127			    vortex_adb_checkinout(vortex,
128						  vortex->fixed_res, en,
129						  VORTEX_RESOURCE_MIXIN);
130			vortex->mixwt[(i * NR_WTROUTES) + ii] = mix;
131
132			vortex_route(vortex, en, 0x11,
133				     ADB_WTOUT(i, ii + 0x20), ADB_MIXIN(mix));
134
135			vortex_connection_mixin_mix(vortex, en, mix,
136						    vortex->mixplayb[ii % 2], 0);
137			if (VORTEX_IS_QUAD(vortex))
138				vortex_connection_mixin_mix(vortex, en,
139							    mix,
140							    vortex->mixplayb[2 +
141								     (ii % 2)], 0);
142		}
143	}
144	for (i = 0; i < NR_WT; i++) {
145		hwwrite(vortex->mmio, WT_RUN(i), 1);
146	}
147}
148
149/* Read WT Register */
150static int
151vortex_wt_SetReg(vortex_t * vortex, unsigned char reg, int wt,
152		 u32 val)
153{
154	int ecx;
155
156	if ((reg == 5) || ((reg >= 7) && (reg <= 10)) || (reg == 0xc)) {
157		if (wt >= (NR_WT / NR_WT_PB)) {
158			printk
159			    ("vortex: WT SetReg: bank out of range. reg=0x%x, wt=%d\n",
160			     reg, wt);
161			return 0;
162		}
163	} else {
164		if (wt >= NR_WT) {
165			printk(KERN_ERR "vortex: WT SetReg: voice out of range\n");
166			return 0;
167		}
168	}
169	if (reg > 0xc)
170		return 0;
171
172	switch (reg) {
173		/* Voice specific parameters */
174	case 0:		/* running */
175		/*
176		printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n",
177		       WT_RUN(wt), (int)val);
178		*/
179		hwwrite(vortex->mmio, WT_RUN(wt), val);
180		return 0xc;
181		break;
182	case 1:		/* param 0 */
183		/*
184		printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n",
185		       WT_PARM(wt,0), (int)val);
186		*/
187		hwwrite(vortex->mmio, WT_PARM(wt, 0), val);
188		return 0xc;
189		break;
190	case 2:		/* param 1 */
191		/*
192		printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n",
193		       WT_PARM(wt,1), (int)val);
194		*/
195		hwwrite(vortex->mmio, WT_PARM(wt, 1), val);
196		return 0xc;
197		break;
198	case 3:		/* param 2 */
199		/*
200		printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n",
201		       WT_PARM(wt,2), (int)val);
202		*/
203		hwwrite(vortex->mmio, WT_PARM(wt, 2), val);
204		return 0xc;
205		break;
206	case 4:		/* param 3 */
207		/*
208		printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n",
209		       WT_PARM(wt,3), (int)val);
210		*/
211		hwwrite(vortex->mmio, WT_PARM(wt, 3), val);
212		return 0xc;
213		break;
214	case 6:		/* mute */
215		/*
216		printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n",
217		       WT_MUTE(wt), (int)val);
218		*/
219		hwwrite(vortex->mmio, WT_MUTE(wt), val);
220		return 0xc;
221		break;
222	case 0xb:
223		{		/* delay */
224			/*
225			printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n",
226			       WT_DELAY(wt,0), (int)val);
227			*/
228			hwwrite(vortex->mmio, WT_DELAY(wt, 3), val);
229			hwwrite(vortex->mmio, WT_DELAY(wt, 2), val);
230			hwwrite(vortex->mmio, WT_DELAY(wt, 1), val);
231			hwwrite(vortex->mmio, WT_DELAY(wt, 0), val);
232			return 0xc;
233		}
234		break;
235		/* Global WT block parameters */
236	case 5:		/* sramp */
237		ecx = WT_SRAMP(wt);
238		break;
239	case 8:		/* aramp */
240		ecx = WT_ARAMP(wt);
241		break;
242	case 9:		/* mramp */
243		ecx = WT_MRAMP(wt);
244		break;
245	case 0xa:		/* ctrl */
246		ecx = WT_CTRL(wt);
247		break;
248	case 0xc:		/* ds_reg */
249		ecx = WT_DSREG(wt);
250		break;
251	default:
252		return 0;
253		break;
254	}
255	/*
256	printk(KERN_DEBUG "vortex: WT SetReg(0x%x) = 0x%08x\n", ecx, (int)val);
257	*/
258	hwwrite(vortex->mmio, ecx, val);
259	return 1;
260}
261
262static void vortex_wt_init(vortex_t * vortex)
263{
264	u32 var4, var8, varc, var10 = 0, edi;
265
266	var10 &= 0xFFFFFFE3;
267	var10 |= 0x22;
268	var10 &= 0xFFFFFEBF;
269	var10 |= 0x80;
270	var10 |= 0x200;
271	var10 &= 0xfffffffe;
272	var10 &= 0xfffffbff;
273	var10 |= 0x1800;
274	// var10 = 0x1AA2
275	var4 = 0x10000000;
276	varc = 0x00830000;
277	var8 = 0x00830000;
278
279	/* Init Bank registers. */
280	for (edi = 0; edi < (NR_WT / NR_WT_PB); edi++) {
281		vortex_wt_SetReg(vortex, 0xc, edi, 0);	/* ds_reg */
282		vortex_wt_SetReg(vortex, 0xa, edi, var10);	/* ctrl  */
283		vortex_wt_SetReg(vortex, 0x9, edi, var4);	/* mramp */
284		vortex_wt_SetReg(vortex, 0x8, edi, varc);	/* aramp */
285		vortex_wt_SetReg(vortex, 0x5, edi, var8);	/* sramp */
286	}
287	/* Init Voice registers. */
288	for (edi = 0; edi < NR_WT; edi++) {
289		vortex_wt_SetReg(vortex, 0x4, edi, 0);	/* param 3 0x20c */
290		vortex_wt_SetReg(vortex, 0x3, edi, 0);	/* param 2 0x208 */
291		vortex_wt_SetReg(vortex, 0x2, edi, 0);	/* param 1 0x204 */
292		vortex_wt_SetReg(vortex, 0x1, edi, 0);	/* param 0 0x200 */
293		vortex_wt_SetReg(vortex, 0xb, edi, 0);	/* delay 0x400 - 0x40c */
294	}
295	var10 |= 1;
296	for (edi = 0; edi < (NR_WT / NR_WT_PB); edi++)
297		vortex_wt_SetReg(vortex, 0xa, edi, var10);	/* ctrl */
298}
299
300/* Extract of CAdbTopology::SetVolume(struct _ASPVOLUME *) */
301
302/* End of File */
303