xref: /linux/sound/isa/sb/emu8000.c (revision b889fcf63cb62e7fdb7816565e28f44dbe4a76a5)
1 /*
2  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
3  *     and (c) 1999 Steve Ratcliffe <steve@parabola.demon.co.uk>
4  *  Copyright (C) 1999-2000 Takashi Iwai <tiwai@suse.de>
5  *
6  *  Routines for control of EMU8000 chip
7  *
8  *   This program is free software; you can redistribute it and/or modify
9  *   it under the terms of the GNU General Public License as published by
10  *   the Free Software Foundation; either version 2 of the License, or
11  *   (at your option) any later version.
12  *
13  *   This program is distributed in the hope that it will be useful,
14  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *   GNU General Public License for more details.
17  *
18  *   You should have received a copy of the GNU General Public License
19  *   along with this program; if not, write to the Free Software
20  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  */
22 
23 #include <linux/wait.h>
24 #include <linux/sched.h>
25 #include <linux/slab.h>
26 #include <linux/ioport.h>
27 #include <linux/export.h>
28 #include <linux/delay.h>
29 #include <sound/core.h>
30 #include <sound/emu8000.h>
31 #include <sound/emu8000_reg.h>
32 #include <asm/io.h>
33 #include <asm/uaccess.h>
34 #include <linux/init.h>
35 #include <sound/control.h>
36 #include <sound/initval.h>
37 
38 /*
39  * emu8000 register controls
40  */
41 
42 /*
43  * The following routines read and write registers on the emu8000.  They
44  * should always be called via the EMU8000*READ/WRITE macros and never
45  * directly.  The macros handle the port number and command word.
46  */
47 /* Write a word */
48 void snd_emu8000_poke(struct snd_emu8000 *emu, unsigned int port, unsigned int reg, unsigned int val)
49 {
50 	unsigned long flags;
51 	spin_lock_irqsave(&emu->reg_lock, flags);
52 	if (reg != emu->last_reg) {
53 		outw((unsigned short)reg, EMU8000_PTR(emu)); /* Set register */
54 		emu->last_reg = reg;
55 	}
56 	outw((unsigned short)val, port); /* Send data */
57 	spin_unlock_irqrestore(&emu->reg_lock, flags);
58 }
59 
60 /* Read a word */
61 unsigned short snd_emu8000_peek(struct snd_emu8000 *emu, unsigned int port, unsigned int reg)
62 {
63 	unsigned short res;
64 	unsigned long flags;
65 	spin_lock_irqsave(&emu->reg_lock, flags);
66 	if (reg != emu->last_reg) {
67 		outw((unsigned short)reg, EMU8000_PTR(emu)); /* Set register */
68 		emu->last_reg = reg;
69 	}
70 	res = inw(port);	/* Read data */
71 	spin_unlock_irqrestore(&emu->reg_lock, flags);
72 	return res;
73 }
74 
75 /* Write a double word */
76 void snd_emu8000_poke_dw(struct snd_emu8000 *emu, unsigned int port, unsigned int reg, unsigned int val)
77 {
78 	unsigned long flags;
79 	spin_lock_irqsave(&emu->reg_lock, flags);
80 	if (reg != emu->last_reg) {
81 		outw((unsigned short)reg, EMU8000_PTR(emu)); /* Set register */
82 		emu->last_reg = reg;
83 	}
84 	outw((unsigned short)val, port); /* Send low word of data */
85 	outw((unsigned short)(val>>16), port+2); /* Send high word of data */
86 	spin_unlock_irqrestore(&emu->reg_lock, flags);
87 }
88 
89 /* Read a double word */
90 unsigned int snd_emu8000_peek_dw(struct snd_emu8000 *emu, unsigned int port, unsigned int reg)
91 {
92 	unsigned short low;
93 	unsigned int res;
94 	unsigned long flags;
95 	spin_lock_irqsave(&emu->reg_lock, flags);
96 	if (reg != emu->last_reg) {
97 		outw((unsigned short)reg, EMU8000_PTR(emu)); /* Set register */
98 		emu->last_reg = reg;
99 	}
100 	low = inw(port);	/* Read low word of data */
101 	res = low + (inw(port+2) << 16);
102 	spin_unlock_irqrestore(&emu->reg_lock, flags);
103 	return res;
104 }
105 
106 /*
107  * Set up / close a channel to be used for DMA.
108  */
109 /*exported*/ void
110 snd_emu8000_dma_chan(struct snd_emu8000 *emu, int ch, int mode)
111 {
112 	unsigned right_bit = (mode & EMU8000_RAM_RIGHT) ? 0x01000000 : 0;
113 	mode &= EMU8000_RAM_MODE_MASK;
114 	if (mode == EMU8000_RAM_CLOSE) {
115 		EMU8000_CCCA_WRITE(emu, ch, 0);
116 		EMU8000_DCYSUSV_WRITE(emu, ch, 0x807F);
117 		return;
118 	}
119 	EMU8000_DCYSUSV_WRITE(emu, ch, 0x80);
120 	EMU8000_VTFT_WRITE(emu, ch, 0);
121 	EMU8000_CVCF_WRITE(emu, ch, 0);
122 	EMU8000_PTRX_WRITE(emu, ch, 0x40000000);
123 	EMU8000_CPF_WRITE(emu, ch, 0x40000000);
124 	EMU8000_PSST_WRITE(emu, ch, 0);
125 	EMU8000_CSL_WRITE(emu, ch, 0);
126 	if (mode == EMU8000_RAM_WRITE) /* DMA write */
127 		EMU8000_CCCA_WRITE(emu, ch, 0x06000000 | right_bit);
128 	else	   /* DMA read */
129 		EMU8000_CCCA_WRITE(emu, ch, 0x04000000 | right_bit);
130 }
131 
132 /*
133  */
134 static void
135 snd_emu8000_read_wait(struct snd_emu8000 *emu)
136 {
137 	while ((EMU8000_SMALR_READ(emu) & 0x80000000) != 0) {
138 		schedule_timeout_interruptible(1);
139 		if (signal_pending(current))
140 			break;
141 	}
142 }
143 
144 /*
145  */
146 static void
147 snd_emu8000_write_wait(struct snd_emu8000 *emu)
148 {
149 	while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
150 		schedule_timeout_interruptible(1);
151 		if (signal_pending(current))
152 			break;
153 	}
154 }
155 
156 /*
157  * detect a card at the given port
158  */
159 static int
160 snd_emu8000_detect(struct snd_emu8000 *emu)
161 {
162 	/* Initialise */
163 	EMU8000_HWCF1_WRITE(emu, 0x0059);
164 	EMU8000_HWCF2_WRITE(emu, 0x0020);
165 	EMU8000_HWCF3_WRITE(emu, 0x0000);
166 	/* Check for a recognisable emu8000 */
167 	/*
168 	if ((EMU8000_U1_READ(emu) & 0x000f) != 0x000c)
169 		return -ENODEV;
170 		*/
171 	if ((EMU8000_HWCF1_READ(emu) & 0x007e) != 0x0058)
172 		return -ENODEV;
173 	if ((EMU8000_HWCF2_READ(emu) & 0x0003) != 0x0003)
174 		return -ENODEV;
175 
176 	snd_printdd("EMU8000 [0x%lx]: Synth chip found\n",
177                     emu->port1);
178 	return 0;
179 }
180 
181 
182 /*
183  * intiailize audio channels
184  */
185 static void
186 init_audio(struct snd_emu8000 *emu)
187 {
188 	int ch;
189 
190 	/* turn off envelope engines */
191 	for (ch = 0; ch < EMU8000_CHANNELS; ch++)
192 		EMU8000_DCYSUSV_WRITE(emu, ch, 0x80);
193 
194 	/* reset all other parameters to zero */
195 	for (ch = 0; ch < EMU8000_CHANNELS; ch++) {
196 		EMU8000_ENVVOL_WRITE(emu, ch, 0);
197 		EMU8000_ENVVAL_WRITE(emu, ch, 0);
198 		EMU8000_DCYSUS_WRITE(emu, ch, 0);
199 		EMU8000_ATKHLDV_WRITE(emu, ch, 0);
200 		EMU8000_LFO1VAL_WRITE(emu, ch, 0);
201 		EMU8000_ATKHLD_WRITE(emu, ch, 0);
202 		EMU8000_LFO2VAL_WRITE(emu, ch, 0);
203 		EMU8000_IP_WRITE(emu, ch, 0);
204 		EMU8000_IFATN_WRITE(emu, ch, 0);
205 		EMU8000_PEFE_WRITE(emu, ch, 0);
206 		EMU8000_FMMOD_WRITE(emu, ch, 0);
207 		EMU8000_TREMFRQ_WRITE(emu, ch, 0);
208 		EMU8000_FM2FRQ2_WRITE(emu, ch, 0);
209 		EMU8000_PTRX_WRITE(emu, ch, 0);
210 		EMU8000_VTFT_WRITE(emu, ch, 0);
211 		EMU8000_PSST_WRITE(emu, ch, 0);
212 		EMU8000_CSL_WRITE(emu, ch, 0);
213 		EMU8000_CCCA_WRITE(emu, ch, 0);
214 	}
215 
216 	for (ch = 0; ch < EMU8000_CHANNELS; ch++) {
217 		EMU8000_CPF_WRITE(emu, ch, 0);
218 		EMU8000_CVCF_WRITE(emu, ch, 0);
219 	}
220 }
221 
222 
223 /*
224  * initialize DMA address
225  */
226 static void
227 init_dma(struct snd_emu8000 *emu)
228 {
229 	EMU8000_SMALR_WRITE(emu, 0);
230 	EMU8000_SMARR_WRITE(emu, 0);
231 	EMU8000_SMALW_WRITE(emu, 0);
232 	EMU8000_SMARW_WRITE(emu, 0);
233 }
234 
235 /*
236  * initialization arrays; from ADIP
237  */
238 static unsigned short init1[128] = {
239 	0x03ff, 0x0030,  0x07ff, 0x0130, 0x0bff, 0x0230,  0x0fff, 0x0330,
240 	0x13ff, 0x0430,  0x17ff, 0x0530, 0x1bff, 0x0630,  0x1fff, 0x0730,
241 	0x23ff, 0x0830,  0x27ff, 0x0930, 0x2bff, 0x0a30,  0x2fff, 0x0b30,
242 	0x33ff, 0x0c30,  0x37ff, 0x0d30, 0x3bff, 0x0e30,  0x3fff, 0x0f30,
243 
244 	0x43ff, 0x0030,  0x47ff, 0x0130, 0x4bff, 0x0230,  0x4fff, 0x0330,
245 	0x53ff, 0x0430,  0x57ff, 0x0530, 0x5bff, 0x0630,  0x5fff, 0x0730,
246 	0x63ff, 0x0830,  0x67ff, 0x0930, 0x6bff, 0x0a30,  0x6fff, 0x0b30,
247 	0x73ff, 0x0c30,  0x77ff, 0x0d30, 0x7bff, 0x0e30,  0x7fff, 0x0f30,
248 
249 	0x83ff, 0x0030,  0x87ff, 0x0130, 0x8bff, 0x0230,  0x8fff, 0x0330,
250 	0x93ff, 0x0430,  0x97ff, 0x0530, 0x9bff, 0x0630,  0x9fff, 0x0730,
251 	0xa3ff, 0x0830,  0xa7ff, 0x0930, 0xabff, 0x0a30,  0xafff, 0x0b30,
252 	0xb3ff, 0x0c30,  0xb7ff, 0x0d30, 0xbbff, 0x0e30,  0xbfff, 0x0f30,
253 
254 	0xc3ff, 0x0030,  0xc7ff, 0x0130, 0xcbff, 0x0230,  0xcfff, 0x0330,
255 	0xd3ff, 0x0430,  0xd7ff, 0x0530, 0xdbff, 0x0630,  0xdfff, 0x0730,
256 	0xe3ff, 0x0830,  0xe7ff, 0x0930, 0xebff, 0x0a30,  0xefff, 0x0b30,
257 	0xf3ff, 0x0c30,  0xf7ff, 0x0d30, 0xfbff, 0x0e30,  0xffff, 0x0f30,
258 };
259 
260 static unsigned short init2[128] = {
261 	0x03ff, 0x8030, 0x07ff, 0x8130, 0x0bff, 0x8230, 0x0fff, 0x8330,
262 	0x13ff, 0x8430, 0x17ff, 0x8530, 0x1bff, 0x8630, 0x1fff, 0x8730,
263 	0x23ff, 0x8830, 0x27ff, 0x8930, 0x2bff, 0x8a30, 0x2fff, 0x8b30,
264 	0x33ff, 0x8c30, 0x37ff, 0x8d30, 0x3bff, 0x8e30, 0x3fff, 0x8f30,
265 
266 	0x43ff, 0x8030, 0x47ff, 0x8130, 0x4bff, 0x8230, 0x4fff, 0x8330,
267 	0x53ff, 0x8430, 0x57ff, 0x8530, 0x5bff, 0x8630, 0x5fff, 0x8730,
268 	0x63ff, 0x8830, 0x67ff, 0x8930, 0x6bff, 0x8a30, 0x6fff, 0x8b30,
269 	0x73ff, 0x8c30, 0x77ff, 0x8d30, 0x7bff, 0x8e30, 0x7fff, 0x8f30,
270 
271 	0x83ff, 0x8030, 0x87ff, 0x8130, 0x8bff, 0x8230, 0x8fff, 0x8330,
272 	0x93ff, 0x8430, 0x97ff, 0x8530, 0x9bff, 0x8630, 0x9fff, 0x8730,
273 	0xa3ff, 0x8830, 0xa7ff, 0x8930, 0xabff, 0x8a30, 0xafff, 0x8b30,
274 	0xb3ff, 0x8c30, 0xb7ff, 0x8d30, 0xbbff, 0x8e30, 0xbfff, 0x8f30,
275 
276 	0xc3ff, 0x8030, 0xc7ff, 0x8130, 0xcbff, 0x8230, 0xcfff, 0x8330,
277 	0xd3ff, 0x8430, 0xd7ff, 0x8530, 0xdbff, 0x8630, 0xdfff, 0x8730,
278 	0xe3ff, 0x8830, 0xe7ff, 0x8930, 0xebff, 0x8a30, 0xefff, 0x8b30,
279 	0xf3ff, 0x8c30, 0xf7ff, 0x8d30, 0xfbff, 0x8e30, 0xffff, 0x8f30,
280 };
281 
282 static unsigned short init3[128] = {
283 	0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
284 	0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x8F7C, 0x167E, 0xF254,
285 	0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x8BAA, 0x1B6D, 0xF234,
286 	0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x86E7, 0x229E, 0xF224,
287 
288 	0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x87F6, 0x2C28, 0xF254,
289 	0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x8F02, 0x1341, 0xF264,
290 	0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x8FA9, 0x3EB5, 0xF294,
291 	0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0xC4C3, 0x3EBB, 0xC5C3,
292 
293 	0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x8671, 0x14FD, 0x8287,
294 	0x3EBC, 0xE610, 0x3EC8, 0x8C7B, 0x031A, 0x87E6, 0x3EC8, 0x86F7,
295 	0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x821F, 0x3ECA, 0x8386,
296 	0x3EC1, 0x8C03, 0x3EC9, 0x831E, 0x3ECA, 0x8C4C, 0x3EBF, 0x8C55,
297 
298 	0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x8EAD, 0x3EC8, 0xD308,
299 	0x3EC2, 0x8F7E, 0x3ECB, 0x8219, 0x3ECB, 0xD26E, 0x3EC5, 0x831F,
300 	0x3EC6, 0xC308, 0x3EC3, 0xB2FF, 0x3EC9, 0x8265, 0x3EC9, 0x8319,
301 	0x1342, 0xD36E, 0x3EC7, 0xB3FF, 0x0000, 0x8365, 0x1420, 0x9570,
302 };
303 
304 static unsigned short init4[128] = {
305 	0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
306 	0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x0F7C, 0x167E, 0x7254,
307 	0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x0BAA, 0x1B6D, 0x7234,
308 	0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x06E7, 0x229E, 0x7224,
309 
310 	0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x07F6, 0x2C28, 0x7254,
311 	0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x0F02, 0x1341, 0x7264,
312 	0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x0FA9, 0x3EB5, 0x7294,
313 	0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0x44C3, 0x3EBB, 0x45C3,
314 
315 	0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x0671, 0x14FD, 0x0287,
316 	0x3EBC, 0xE610, 0x3EC8, 0x0C7B, 0x031A, 0x07E6, 0x3EC8, 0x86F7,
317 	0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x021F, 0x3ECA, 0x0386,
318 	0x3EC1, 0x0C03, 0x3EC9, 0x031E, 0x3ECA, 0x8C4C, 0x3EBF, 0x0C55,
319 
320 	0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x0EAD, 0x3EC8, 0xD308,
321 	0x3EC2, 0x8F7E, 0x3ECB, 0x0219, 0x3ECB, 0xD26E, 0x3EC5, 0x031F,
322 	0x3EC6, 0xC308, 0x3EC3, 0x32FF, 0x3EC9, 0x0265, 0x3EC9, 0x8319,
323 	0x1342, 0xD36E, 0x3EC7, 0x33FF, 0x0000, 0x8365, 0x1420, 0x9570,
324 };
325 
326 /* send an initialization array
327  * Taken from the oss driver, not obvious from the doc how this
328  * is meant to work
329  */
330 static void
331 send_array(struct snd_emu8000 *emu, unsigned short *data, int size)
332 {
333 	int i;
334 	unsigned short *p;
335 
336 	p = data;
337 	for (i = 0; i < size; i++, p++)
338 		EMU8000_INIT1_WRITE(emu, i, *p);
339 	for (i = 0; i < size; i++, p++)
340 		EMU8000_INIT2_WRITE(emu, i, *p);
341 	for (i = 0; i < size; i++, p++)
342 		EMU8000_INIT3_WRITE(emu, i, *p);
343 	for (i = 0; i < size; i++, p++)
344 		EMU8000_INIT4_WRITE(emu, i, *p);
345 }
346 
347 
348 /*
349  * Send initialization arrays to start up, this just follows the
350  * initialisation sequence in the adip.
351  */
352 static void
353 init_arrays(struct snd_emu8000 *emu)
354 {
355 	send_array(emu, init1, ARRAY_SIZE(init1)/4);
356 
357 	msleep((1024 * 1000) / 44100); /* wait for 1024 clocks */
358 	send_array(emu, init2, ARRAY_SIZE(init2)/4);
359 	send_array(emu, init3, ARRAY_SIZE(init3)/4);
360 
361 	EMU8000_HWCF4_WRITE(emu, 0);
362 	EMU8000_HWCF5_WRITE(emu, 0x83);
363 	EMU8000_HWCF6_WRITE(emu, 0x8000);
364 
365 	send_array(emu, init4, ARRAY_SIZE(init4)/4);
366 }
367 
368 
369 #define UNIQUE_ID1	0xa5b9
370 #define UNIQUE_ID2	0x9d53
371 
372 /*
373  * Size the onboard memory.
374  * This is written so as not to need arbitrary delays after the write. It
375  * seems that the only way to do this is to use the one channel and keep
376  * reallocating between read and write.
377  */
378 static void
379 size_dram(struct snd_emu8000 *emu)
380 {
381 	int i, size, detected_size;
382 
383 	if (emu->dram_checked)
384 		return;
385 
386 	size = 0;
387 	detected_size = 0;
388 
389 	/* write out a magic number */
390 	snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE);
391 	snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_READ);
392 	EMU8000_SMALW_WRITE(emu, EMU8000_DRAM_OFFSET);
393 	EMU8000_SMLD_WRITE(emu, UNIQUE_ID1);
394 	snd_emu8000_init_fm(emu); /* This must really be here and not 2 lines back even */
395 
396 	while (size < EMU8000_MAX_DRAM) {
397 
398 		size += 512 * 1024;  /* increment 512kbytes */
399 
400 		/* Write a unique data on the test address.
401 		 * if the address is out of range, the data is written on
402 		 * 0x200000(=EMU8000_DRAM_OFFSET).  Then the id word is
403 		 * changed by this data.
404 		 */
405 		/*snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE);*/
406 		EMU8000_SMALW_WRITE(emu, EMU8000_DRAM_OFFSET + (size>>1));
407 		EMU8000_SMLD_WRITE(emu, UNIQUE_ID2);
408 		snd_emu8000_write_wait(emu);
409 
410 		/*
411 		 * read the data on the just written DRAM address
412 		 * if not the same then we have reached the end of ram.
413 		 */
414 		/*snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_READ);*/
415 		EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET + (size>>1));
416 		/*snd_emu8000_read_wait(emu);*/
417 		EMU8000_SMLD_READ(emu); /* discard stale data  */
418 		if (EMU8000_SMLD_READ(emu) != UNIQUE_ID2)
419 			break; /* no memory at this address */
420 		snd_emu8000_read_wait(emu);
421 
422 		/*
423 		 * If it is the same it could be that the address just
424 		 * wraps back to the beginning; so check to see if the
425 		 * initial value has been overwritten.
426 		 */
427 		EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET);
428 		EMU8000_SMLD_READ(emu); /* discard stale data  */
429 		if (EMU8000_SMLD_READ(emu) != UNIQUE_ID1)
430 			break; /* we must have wrapped around */
431 		snd_emu8000_read_wait(emu);
432 
433 		/* Otherwise, it's valid memory. */
434 		detected_size = size + 512 * 1024;
435 	}
436 
437 	/* Distinguish 512 KiB from 0. */
438 	if (detected_size == 0) {
439 		snd_emu8000_read_wait(emu);
440 		EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET);
441 		EMU8000_SMLD_READ(emu); /* discard stale data  */
442 		if (EMU8000_SMLD_READ(emu) == UNIQUE_ID1)
443 			detected_size = 512 * 1024;
444 	}
445 
446 	/* wait until FULL bit in SMAxW register is false */
447 	for (i = 0; i < 10000; i++) {
448 		if ((EMU8000_SMALW_READ(emu) & 0x80000000) == 0)
449 			break;
450 		schedule_timeout_interruptible(1);
451 		if (signal_pending(current))
452 			break;
453 	}
454 	snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_CLOSE);
455 	snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_CLOSE);
456 
457 	snd_printdd("EMU8000 [0x%lx]: %d Kb on-board memory detected\n",
458 		    emu->port1, detected_size/1024);
459 
460 	emu->mem_size = detected_size;
461 	emu->dram_checked = 1;
462 }
463 
464 
465 /*
466  * Initiailise the FM section.  You have to do this to use sample RAM
467  * and therefore lose 2 voices.
468  */
469 /*exported*/ void
470 snd_emu8000_init_fm(struct snd_emu8000 *emu)
471 {
472 	unsigned long flags;
473 
474 	/* Initialize the last two channels for DRAM refresh and producing
475 	   the reverb and chorus effects for Yamaha OPL-3 synthesizer */
476 
477 	/* 31: FM left channel, 0xffffe0-0xffffe8 */
478 	EMU8000_DCYSUSV_WRITE(emu, 30, 0x80);
479 	EMU8000_PSST_WRITE(emu, 30, 0xFFFFFFE0); /* full left */
480 	EMU8000_CSL_WRITE(emu, 30, 0x00FFFFE8 | (emu->fm_chorus_depth << 24));
481 	EMU8000_PTRX_WRITE(emu, 30, (emu->fm_reverb_depth << 8));
482 	EMU8000_CPF_WRITE(emu, 30, 0);
483 	EMU8000_CCCA_WRITE(emu, 30, 0x00FFFFE3);
484 
485 	/* 32: FM right channel, 0xfffff0-0xfffff8 */
486 	EMU8000_DCYSUSV_WRITE(emu, 31, 0x80);
487 	EMU8000_PSST_WRITE(emu, 31, 0x00FFFFF0); /* full right */
488 	EMU8000_CSL_WRITE(emu, 31, 0x00FFFFF8 | (emu->fm_chorus_depth << 24));
489 	EMU8000_PTRX_WRITE(emu, 31, (emu->fm_reverb_depth << 8));
490 	EMU8000_CPF_WRITE(emu, 31, 0x8000);
491 	EMU8000_CCCA_WRITE(emu, 31, 0x00FFFFF3);
492 
493 	snd_emu8000_poke((emu), EMU8000_DATA0(emu), EMU8000_CMD(1, (30)), 0);
494 
495 	spin_lock_irqsave(&emu->reg_lock, flags);
496 	while (!(inw(EMU8000_PTR(emu)) & 0x1000))
497 		;
498 	while ((inw(EMU8000_PTR(emu)) & 0x1000))
499 		;
500 	spin_unlock_irqrestore(&emu->reg_lock, flags);
501 	snd_emu8000_poke((emu), EMU8000_DATA0(emu), EMU8000_CMD(1, (30)), 0x4828);
502 	/* this is really odd part.. */
503 	outb(0x3C, EMU8000_PTR(emu));
504 	outb(0, EMU8000_DATA1(emu));
505 
506 	/* skew volume & cutoff */
507 	EMU8000_VTFT_WRITE(emu, 30, 0x8000FFFF);
508 	EMU8000_VTFT_WRITE(emu, 31, 0x8000FFFF);
509 }
510 
511 
512 /*
513  * The main initialization routine.
514  */
515 static void
516 snd_emu8000_init_hw(struct snd_emu8000 *emu)
517 {
518 	int i;
519 
520 	emu->last_reg = 0xffff; /* reset the last register index */
521 
522 	/* initialize hardware configuration */
523 	EMU8000_HWCF1_WRITE(emu, 0x0059);
524 	EMU8000_HWCF2_WRITE(emu, 0x0020);
525 
526 	/* disable audio; this seems to reduce a clicking noise a bit.. */
527 	EMU8000_HWCF3_WRITE(emu, 0);
528 
529 	/* initialize audio channels */
530 	init_audio(emu);
531 
532 	/* initialize DMA */
533 	init_dma(emu);
534 
535 	/* initialize init arrays */
536 	init_arrays(emu);
537 
538 	/*
539 	 * Initialize the FM section of the AWE32, this is needed
540 	 * for DRAM refresh as well
541 	 */
542 	snd_emu8000_init_fm(emu);
543 
544 	/* terminate all voices */
545 	for (i = 0; i < EMU8000_DRAM_VOICES; i++)
546 		EMU8000_DCYSUSV_WRITE(emu, 0, 0x807F);
547 
548 	/* check DRAM memory size */
549 	size_dram(emu);
550 
551 	/* enable audio */
552 	EMU8000_HWCF3_WRITE(emu, 0x4);
553 
554 	/* set equzlier, chorus and reverb modes */
555 	snd_emu8000_update_equalizer(emu);
556 	snd_emu8000_update_chorus_mode(emu);
557 	snd_emu8000_update_reverb_mode(emu);
558 }
559 
560 
561 /*----------------------------------------------------------------
562  * Bass/Treble Equalizer
563  *----------------------------------------------------------------*/
564 
565 static unsigned short bass_parm[12][3] = {
566 	{0xD26A, 0xD36A, 0x0000}, /* -12 dB */
567 	{0xD25B, 0xD35B, 0x0000}, /*  -8 */
568 	{0xD24C, 0xD34C, 0x0000}, /*  -6 */
569 	{0xD23D, 0xD33D, 0x0000}, /*  -4 */
570 	{0xD21F, 0xD31F, 0x0000}, /*  -2 */
571 	{0xC208, 0xC308, 0x0001}, /*   0 (HW default) */
572 	{0xC219, 0xC319, 0x0001}, /*  +2 */
573 	{0xC22A, 0xC32A, 0x0001}, /*  +4 */
574 	{0xC24C, 0xC34C, 0x0001}, /*  +6 */
575 	{0xC26E, 0xC36E, 0x0001}, /*  +8 */
576 	{0xC248, 0xC384, 0x0002}, /* +10 */
577 	{0xC26A, 0xC36A, 0x0002}, /* +12 dB */
578 };
579 
580 static unsigned short treble_parm[12][9] = {
581 	{0x821E, 0xC26A, 0x031E, 0xC36A, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, /* -12 dB */
582 	{0x821E, 0xC25B, 0x031E, 0xC35B, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
583 	{0x821E, 0xC24C, 0x031E, 0xC34C, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
584 	{0x821E, 0xC23D, 0x031E, 0xC33D, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
585 	{0x821E, 0xC21F, 0x031E, 0xC31F, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
586 	{0x821E, 0xD208, 0x031E, 0xD308, 0x021E, 0xD208, 0x831E, 0xD308, 0x0002},
587 	{0x821E, 0xD208, 0x031E, 0xD308, 0x021D, 0xD219, 0x831D, 0xD319, 0x0002},
588 	{0x821E, 0xD208, 0x031E, 0xD308, 0x021C, 0xD22A, 0x831C, 0xD32A, 0x0002},
589 	{0x821E, 0xD208, 0x031E, 0xD308, 0x021A, 0xD24C, 0x831A, 0xD34C, 0x0002},
590 	{0x821E, 0xD208, 0x031E, 0xD308, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +8 (HW default) */
591 	{0x821D, 0xD219, 0x031D, 0xD319, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002},
592 	{0x821C, 0xD22A, 0x031C, 0xD32A, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}  /* +12 dB */
593 };
594 
595 
596 /*
597  * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB]
598  */
599 /*exported*/ void
600 snd_emu8000_update_equalizer(struct snd_emu8000 *emu)
601 {
602 	unsigned short w;
603 	int bass = emu->bass_level;
604 	int treble = emu->treble_level;
605 
606 	if (bass < 0 || bass > 11 || treble < 0 || treble > 11)
607 		return;
608 	EMU8000_INIT4_WRITE(emu, 0x01, bass_parm[bass][0]);
609 	EMU8000_INIT4_WRITE(emu, 0x11, bass_parm[bass][1]);
610 	EMU8000_INIT3_WRITE(emu, 0x11, treble_parm[treble][0]);
611 	EMU8000_INIT3_WRITE(emu, 0x13, treble_parm[treble][1]);
612 	EMU8000_INIT3_WRITE(emu, 0x1b, treble_parm[treble][2]);
613 	EMU8000_INIT4_WRITE(emu, 0x07, treble_parm[treble][3]);
614 	EMU8000_INIT4_WRITE(emu, 0x0b, treble_parm[treble][4]);
615 	EMU8000_INIT4_WRITE(emu, 0x0d, treble_parm[treble][5]);
616 	EMU8000_INIT4_WRITE(emu, 0x17, treble_parm[treble][6]);
617 	EMU8000_INIT4_WRITE(emu, 0x19, treble_parm[treble][7]);
618 	w = bass_parm[bass][2] + treble_parm[treble][8];
619 	EMU8000_INIT4_WRITE(emu, 0x15, (unsigned short)(w + 0x0262));
620 	EMU8000_INIT4_WRITE(emu, 0x1d, (unsigned short)(w + 0x8362));
621 }
622 
623 
624 /*----------------------------------------------------------------
625  * Chorus mode control
626  *----------------------------------------------------------------*/
627 
628 /*
629  * chorus mode parameters
630  */
631 #define SNDRV_EMU8000_CHORUS_1		0
632 #define	SNDRV_EMU8000_CHORUS_2		1
633 #define	SNDRV_EMU8000_CHORUS_3		2
634 #define	SNDRV_EMU8000_CHORUS_4		3
635 #define	SNDRV_EMU8000_CHORUS_FEEDBACK	4
636 #define	SNDRV_EMU8000_CHORUS_FLANGER	5
637 #define	SNDRV_EMU8000_CHORUS_SHORTDELAY	6
638 #define	SNDRV_EMU8000_CHORUS_SHORTDELAY2	7
639 #define SNDRV_EMU8000_CHORUS_PREDEFINED	8
640 /* user can define chorus modes up to 32 */
641 #define SNDRV_EMU8000_CHORUS_NUMBERS	32
642 
643 struct soundfont_chorus_fx {
644 	unsigned short feedback;	/* feedback level (0xE600-0xE6FF) */
645 	unsigned short delay_offset;	/* delay (0-0x0DA3) [1/44100 sec] */
646 	unsigned short lfo_depth;	/* LFO depth (0xBC00-0xBCFF) */
647 	unsigned int delay;	/* right delay (0-0xFFFFFFFF) [1/256/44100 sec] */
648 	unsigned int lfo_freq;		/* LFO freq LFO freq (0-0xFFFFFFFF) */
649 };
650 
651 /* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */
652 static char chorus_defined[SNDRV_EMU8000_CHORUS_NUMBERS];
653 static struct soundfont_chorus_fx chorus_parm[SNDRV_EMU8000_CHORUS_NUMBERS] = {
654 	{0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */
655 	{0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */
656 	{0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */
657 	{0xE620, 0x0269, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 4 */
658 	{0xE680, 0x04D3, 0xBCA6, 0x00000000, 0x0000005B}, /* feedback */
659 	{0xE6E0, 0x044E, 0xBC37, 0x00000000, 0x00000026}, /* flanger */
660 	{0xE600, 0x0B06, 0xBC00, 0x0006E000, 0x00000083}, /* short delay */
661 	{0xE6C0, 0x0B06, 0xBC00, 0x0006E000, 0x00000083}, /* short delay + feedback */
662 };
663 
664 /*exported*/ int
665 snd_emu8000_load_chorus_fx(struct snd_emu8000 *emu, int mode, const void __user *buf, long len)
666 {
667 	struct soundfont_chorus_fx rec;
668 	if (mode < SNDRV_EMU8000_CHORUS_PREDEFINED || mode >= SNDRV_EMU8000_CHORUS_NUMBERS) {
669 		snd_printk(KERN_WARNING "invalid chorus mode %d for uploading\n", mode);
670 		return -EINVAL;
671 	}
672 	if (len < (long)sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec)))
673 		return -EFAULT;
674 	chorus_parm[mode] = rec;
675 	chorus_defined[mode] = 1;
676 	return 0;
677 }
678 
679 /*exported*/ void
680 snd_emu8000_update_chorus_mode(struct snd_emu8000 *emu)
681 {
682 	int effect = emu->chorus_mode;
683 	if (effect < 0 || effect >= SNDRV_EMU8000_CHORUS_NUMBERS ||
684 	    (effect >= SNDRV_EMU8000_CHORUS_PREDEFINED && !chorus_defined[effect]))
685 		return;
686 	EMU8000_INIT3_WRITE(emu, 0x09, chorus_parm[effect].feedback);
687 	EMU8000_INIT3_WRITE(emu, 0x0c, chorus_parm[effect].delay_offset);
688 	EMU8000_INIT4_WRITE(emu, 0x03, chorus_parm[effect].lfo_depth);
689 	EMU8000_HWCF4_WRITE(emu, chorus_parm[effect].delay);
690 	EMU8000_HWCF5_WRITE(emu, chorus_parm[effect].lfo_freq);
691 	EMU8000_HWCF6_WRITE(emu, 0x8000);
692 	EMU8000_HWCF7_WRITE(emu, 0x0000);
693 }
694 
695 /*----------------------------------------------------------------
696  * Reverb mode control
697  *----------------------------------------------------------------*/
698 
699 /*
700  * reverb mode parameters
701  */
702 #define	SNDRV_EMU8000_REVERB_ROOM1	0
703 #define SNDRV_EMU8000_REVERB_ROOM2	1
704 #define	SNDRV_EMU8000_REVERB_ROOM3	2
705 #define	SNDRV_EMU8000_REVERB_HALL1	3
706 #define	SNDRV_EMU8000_REVERB_HALL2	4
707 #define	SNDRV_EMU8000_REVERB_PLATE	5
708 #define	SNDRV_EMU8000_REVERB_DELAY	6
709 #define	SNDRV_EMU8000_REVERB_PANNINGDELAY 7
710 #define SNDRV_EMU8000_REVERB_PREDEFINED	8
711 /* user can define reverb modes up to 32 */
712 #define SNDRV_EMU8000_REVERB_NUMBERS	32
713 
714 struct soundfont_reverb_fx {
715 	unsigned short parms[28];
716 };
717 
718 /* reverb mode settings; write the following 28 data of 16 bit length
719  *   on the corresponding ports in the reverb_cmds array
720  */
721 static char reverb_defined[SNDRV_EMU8000_CHORUS_NUMBERS];
722 static struct soundfont_reverb_fx reverb_parm[SNDRV_EMU8000_REVERB_NUMBERS] = {
723 {{  /* room 1 */
724 	0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4,
725 	0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516,
726 	0xA490, 0xA590, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
727 	0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
728 }},
729 {{  /* room 2 */
730 	0xB488, 0xA458, 0x9558, 0x84B5, 0x383A, 0x3EB5, 0x7284,
731 	0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
732 	0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
733 	0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
734 }},
735 {{  /* room 3 */
736 	0xB488, 0xA460, 0x9560, 0x84B5, 0x383A, 0x3EB5, 0x7284,
737 	0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4416, 0x4516,
738 	0xA490, 0xA590, 0x842C, 0x852C, 0x842C, 0x852C, 0x842B,
739 	0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A,
740 }},
741 {{  /* hall 1 */
742 	0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7284,
743 	0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
744 	0xA440, 0xA540, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A,
745 	0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529,
746 }},
747 {{  /* hall 2 */
748 	0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7254,
749 	0x7234, 0x7224, 0x7254, 0x7264, 0x7294, 0x44C3, 0x45C3,
750 	0xA404, 0xA504, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
751 	0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
752 }},
753 {{  /* plate */
754 	0xB4FF, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7234,
755 	0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x4448, 0x4548,
756 	0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
757 	0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
758 }},
759 {{  /* delay */
760 	0xB4FF, 0xA470, 0x9500, 0x84B5, 0x333A, 0x39B5, 0x7204,
761 	0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
762 	0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
763 	0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
764 }},
765 {{  /* panning delay */
766 	0xB4FF, 0xA490, 0x9590, 0x8474, 0x333A, 0x39B5, 0x7204,
767 	0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
768 	0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
769 	0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
770 }},
771 };
772 
773 enum { DATA1, DATA2 };
774 #define AWE_INIT1(c)	EMU8000_CMD(2,c), DATA1
775 #define AWE_INIT2(c)	EMU8000_CMD(2,c), DATA2
776 #define AWE_INIT3(c)	EMU8000_CMD(3,c), DATA1
777 #define AWE_INIT4(c)	EMU8000_CMD(3,c), DATA2
778 
779 static struct reverb_cmd_pair {
780 	unsigned short cmd, port;
781 } reverb_cmds[28] = {
782   {AWE_INIT1(0x03)}, {AWE_INIT1(0x05)}, {AWE_INIT4(0x1F)}, {AWE_INIT1(0x07)},
783   {AWE_INIT2(0x14)}, {AWE_INIT2(0x16)}, {AWE_INIT1(0x0F)}, {AWE_INIT1(0x17)},
784   {AWE_INIT1(0x1F)}, {AWE_INIT2(0x07)}, {AWE_INIT2(0x0F)}, {AWE_INIT2(0x17)},
785   {AWE_INIT2(0x1D)}, {AWE_INIT2(0x1F)}, {AWE_INIT3(0x01)}, {AWE_INIT3(0x03)},
786   {AWE_INIT1(0x09)}, {AWE_INIT1(0x0B)}, {AWE_INIT1(0x11)}, {AWE_INIT1(0x13)},
787   {AWE_INIT1(0x19)}, {AWE_INIT1(0x1B)}, {AWE_INIT2(0x01)}, {AWE_INIT2(0x03)},
788   {AWE_INIT2(0x09)}, {AWE_INIT2(0x0B)}, {AWE_INIT2(0x11)}, {AWE_INIT2(0x13)},
789 };
790 
791 /*exported*/ int
792 snd_emu8000_load_reverb_fx(struct snd_emu8000 *emu, int mode, const void __user *buf, long len)
793 {
794 	struct soundfont_reverb_fx rec;
795 
796 	if (mode < SNDRV_EMU8000_REVERB_PREDEFINED || mode >= SNDRV_EMU8000_REVERB_NUMBERS) {
797 		snd_printk(KERN_WARNING "invalid reverb mode %d for uploading\n", mode);
798 		return -EINVAL;
799 	}
800 	if (len < (long)sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec)))
801 		return -EFAULT;
802 	reverb_parm[mode] = rec;
803 	reverb_defined[mode] = 1;
804 	return 0;
805 }
806 
807 /*exported*/ void
808 snd_emu8000_update_reverb_mode(struct snd_emu8000 *emu)
809 {
810 	int effect = emu->reverb_mode;
811 	int i;
812 
813 	if (effect < 0 || effect >= SNDRV_EMU8000_REVERB_NUMBERS ||
814 	    (effect >= SNDRV_EMU8000_REVERB_PREDEFINED && !reverb_defined[effect]))
815 		return;
816 	for (i = 0; i < 28; i++) {
817 		int port;
818 		if (reverb_cmds[i].port == DATA1)
819 			port = EMU8000_DATA1(emu);
820 		else
821 			port = EMU8000_DATA2(emu);
822 		snd_emu8000_poke(emu, port, reverb_cmds[i].cmd, reverb_parm[effect].parms[i]);
823 	}
824 }
825 
826 
827 /*----------------------------------------------------------------
828  * mixer interface
829  *----------------------------------------------------------------*/
830 
831 /*
832  * bass/treble
833  */
834 static int mixer_bass_treble_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
835 {
836 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
837 	uinfo->count = 1;
838 	uinfo->value.integer.min = 0;
839 	uinfo->value.integer.max = 11;
840 	return 0;
841 }
842 
843 static int mixer_bass_treble_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
844 {
845 	struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
846 
847 	ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->treble_level : emu->bass_level;
848 	return 0;
849 }
850 
851 static int mixer_bass_treble_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
852 {
853 	struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
854 	unsigned long flags;
855 	int change;
856 	unsigned short val1;
857 
858 	val1 = ucontrol->value.integer.value[0] % 12;
859 	spin_lock_irqsave(&emu->control_lock, flags);
860 	if (kcontrol->private_value) {
861 		change = val1 != emu->treble_level;
862 		emu->treble_level = val1;
863 	} else {
864 		change = val1 != emu->bass_level;
865 		emu->bass_level = val1;
866 	}
867 	spin_unlock_irqrestore(&emu->control_lock, flags);
868 	snd_emu8000_update_equalizer(emu);
869 	return change;
870 }
871 
872 static struct snd_kcontrol_new mixer_bass_control =
873 {
874 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
875 	.name = "Synth Tone Control - Bass",
876 	.info = mixer_bass_treble_info,
877 	.get = mixer_bass_treble_get,
878 	.put = mixer_bass_treble_put,
879 	.private_value = 0,
880 };
881 
882 static struct snd_kcontrol_new mixer_treble_control =
883 {
884 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
885 	.name = "Synth Tone Control - Treble",
886 	.info = mixer_bass_treble_info,
887 	.get = mixer_bass_treble_get,
888 	.put = mixer_bass_treble_put,
889 	.private_value = 1,
890 };
891 
892 /*
893  * chorus/reverb mode
894  */
895 static int mixer_chorus_reverb_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
896 {
897 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
898 	uinfo->count = 1;
899 	uinfo->value.integer.min = 0;
900 	uinfo->value.integer.max = kcontrol->private_value ? (SNDRV_EMU8000_CHORUS_NUMBERS-1) : (SNDRV_EMU8000_REVERB_NUMBERS-1);
901 	return 0;
902 }
903 
904 static int mixer_chorus_reverb_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
905 {
906 	struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
907 
908 	ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->chorus_mode : emu->reverb_mode;
909 	return 0;
910 }
911 
912 static int mixer_chorus_reverb_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
913 {
914 	struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
915 	unsigned long flags;
916 	int change;
917 	unsigned short val1;
918 
919 	spin_lock_irqsave(&emu->control_lock, flags);
920 	if (kcontrol->private_value) {
921 		val1 = ucontrol->value.integer.value[0] % SNDRV_EMU8000_CHORUS_NUMBERS;
922 		change = val1 != emu->chorus_mode;
923 		emu->chorus_mode = val1;
924 	} else {
925 		val1 = ucontrol->value.integer.value[0] % SNDRV_EMU8000_REVERB_NUMBERS;
926 		change = val1 != emu->reverb_mode;
927 		emu->reverb_mode = val1;
928 	}
929 	spin_unlock_irqrestore(&emu->control_lock, flags);
930 	if (change) {
931 		if (kcontrol->private_value)
932 			snd_emu8000_update_chorus_mode(emu);
933 		else
934 			snd_emu8000_update_reverb_mode(emu);
935 	}
936 	return change;
937 }
938 
939 static struct snd_kcontrol_new mixer_chorus_mode_control =
940 {
941 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
942 	.name = "Chorus Mode",
943 	.info = mixer_chorus_reverb_info,
944 	.get = mixer_chorus_reverb_get,
945 	.put = mixer_chorus_reverb_put,
946 	.private_value = 1,
947 };
948 
949 static struct snd_kcontrol_new mixer_reverb_mode_control =
950 {
951 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
952 	.name = "Reverb Mode",
953 	.info = mixer_chorus_reverb_info,
954 	.get = mixer_chorus_reverb_get,
955 	.put = mixer_chorus_reverb_put,
956 	.private_value = 0,
957 };
958 
959 /*
960  * FM OPL3 chorus/reverb depth
961  */
962 static int mixer_fm_depth_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
963 {
964 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
965 	uinfo->count = 1;
966 	uinfo->value.integer.min = 0;
967 	uinfo->value.integer.max = 255;
968 	return 0;
969 }
970 
971 static int mixer_fm_depth_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
972 {
973 	struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
974 
975 	ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->fm_chorus_depth : emu->fm_reverb_depth;
976 	return 0;
977 }
978 
979 static int mixer_fm_depth_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
980 {
981 	struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
982 	unsigned long flags;
983 	int change;
984 	unsigned short val1;
985 
986 	val1 = ucontrol->value.integer.value[0] % 256;
987 	spin_lock_irqsave(&emu->control_lock, flags);
988 	if (kcontrol->private_value) {
989 		change = val1 != emu->fm_chorus_depth;
990 		emu->fm_chorus_depth = val1;
991 	} else {
992 		change = val1 != emu->fm_reverb_depth;
993 		emu->fm_reverb_depth = val1;
994 	}
995 	spin_unlock_irqrestore(&emu->control_lock, flags);
996 	if (change)
997 		snd_emu8000_init_fm(emu);
998 	return change;
999 }
1000 
1001 static struct snd_kcontrol_new mixer_fm_chorus_depth_control =
1002 {
1003 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1004 	.name = "FM Chorus Depth",
1005 	.info = mixer_fm_depth_info,
1006 	.get = mixer_fm_depth_get,
1007 	.put = mixer_fm_depth_put,
1008 	.private_value = 1,
1009 };
1010 
1011 static struct snd_kcontrol_new mixer_fm_reverb_depth_control =
1012 {
1013 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1014 	.name = "FM Reverb Depth",
1015 	.info = mixer_fm_depth_info,
1016 	.get = mixer_fm_depth_get,
1017 	.put = mixer_fm_depth_put,
1018 	.private_value = 0,
1019 };
1020 
1021 
1022 static struct snd_kcontrol_new *mixer_defs[EMU8000_NUM_CONTROLS] = {
1023 	&mixer_bass_control,
1024 	&mixer_treble_control,
1025 	&mixer_chorus_mode_control,
1026 	&mixer_reverb_mode_control,
1027 	&mixer_fm_chorus_depth_control,
1028 	&mixer_fm_reverb_depth_control,
1029 };
1030 
1031 /*
1032  * create and attach mixer elements for WaveTable treble/bass controls
1033  */
1034 static int
1035 snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu)
1036 {
1037 	int i, err = 0;
1038 
1039 	if (snd_BUG_ON(!emu || !card))
1040 		return -EINVAL;
1041 
1042 	spin_lock_init(&emu->control_lock);
1043 
1044 	memset(emu->controls, 0, sizeof(emu->controls));
1045 	for (i = 0; i < EMU8000_NUM_CONTROLS; i++) {
1046 		if ((err = snd_ctl_add(card, emu->controls[i] = snd_ctl_new1(mixer_defs[i], emu))) < 0)
1047 			goto __error;
1048 	}
1049 	return 0;
1050 
1051 __error:
1052 	for (i = 0; i < EMU8000_NUM_CONTROLS; i++) {
1053 		down_write(&card->controls_rwsem);
1054 		if (emu->controls[i])
1055 			snd_ctl_remove(card, emu->controls[i]);
1056 		up_write(&card->controls_rwsem);
1057 	}
1058 	return err;
1059 }
1060 
1061 
1062 /*
1063  * free resources
1064  */
1065 static int snd_emu8000_free(struct snd_emu8000 *hw)
1066 {
1067 	release_and_free_resource(hw->res_port1);
1068 	release_and_free_resource(hw->res_port2);
1069 	release_and_free_resource(hw->res_port3);
1070 	kfree(hw);
1071 	return 0;
1072 }
1073 
1074 /*
1075  */
1076 static int snd_emu8000_dev_free(struct snd_device *device)
1077 {
1078 	struct snd_emu8000 *hw = device->device_data;
1079 	return snd_emu8000_free(hw);
1080 }
1081 
1082 /*
1083  * initialize and register emu8000 synth device.
1084  */
1085 int
1086 snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports,
1087 		struct snd_seq_device **awe_ret)
1088 {
1089 	struct snd_seq_device *awe;
1090 	struct snd_emu8000 *hw;
1091 	int err;
1092 	static struct snd_device_ops ops = {
1093 		.dev_free = snd_emu8000_dev_free,
1094 	};
1095 
1096 	if (awe_ret)
1097 		*awe_ret = NULL;
1098 
1099 	if (seq_ports <= 0)
1100 		return 0;
1101 
1102 	hw = kzalloc(sizeof(*hw), GFP_KERNEL);
1103 	if (hw == NULL)
1104 		return -ENOMEM;
1105 	spin_lock_init(&hw->reg_lock);
1106 	hw->index = index;
1107 	hw->port1 = port;
1108 	hw->port2 = port + 0x400;
1109 	hw->port3 = port + 0x800;
1110 	if (!(hw->res_port1 = request_region(hw->port1, 4, "Emu8000-1")) ||
1111 	    !(hw->res_port2 = request_region(hw->port2, 4, "Emu8000-2")) ||
1112 	    !(hw->res_port3 = request_region(hw->port3, 4, "Emu8000-3"))) {
1113 		snd_printk(KERN_ERR "sbawe: can't grab ports 0x%lx, 0x%lx, 0x%lx\n", hw->port1, hw->port2, hw->port3);
1114 		snd_emu8000_free(hw);
1115 		return -EBUSY;
1116 	}
1117 	hw->mem_size = 0;
1118 	hw->card = card;
1119 	hw->seq_ports = seq_ports;
1120 	hw->bass_level = 5;
1121 	hw->treble_level = 9;
1122 	hw->chorus_mode = 2;
1123 	hw->reverb_mode = 4;
1124 	hw->fm_chorus_depth = 0;
1125 	hw->fm_reverb_depth = 0;
1126 
1127 	if (snd_emu8000_detect(hw) < 0) {
1128 		snd_emu8000_free(hw);
1129 		return -ENODEV;
1130 	}
1131 
1132 	snd_emu8000_init_hw(hw);
1133 	if ((err = snd_emu8000_create_mixer(card, hw)) < 0) {
1134 		snd_emu8000_free(hw);
1135 		return err;
1136 	}
1137 
1138 	if ((err = snd_device_new(card, SNDRV_DEV_CODEC, hw, &ops)) < 0) {
1139 		snd_emu8000_free(hw);
1140 		return err;
1141 	}
1142 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
1143 	if (snd_seq_device_new(card, index, SNDRV_SEQ_DEV_ID_EMU8000,
1144 			       sizeof(struct snd_emu8000*), &awe) >= 0) {
1145 		strcpy(awe->name, "EMU-8000");
1146 		*(struct snd_emu8000 **)SNDRV_SEQ_DEVICE_ARGPTR(awe) = hw;
1147 	}
1148 #else
1149 	awe = NULL;
1150 #endif
1151 	if (awe_ret)
1152 		*awe_ret = awe;
1153 
1154 	return 0;
1155 }
1156 
1157 
1158 /*
1159  * exported stuff
1160  */
1161 
1162 EXPORT_SYMBOL(snd_emu8000_poke);
1163 EXPORT_SYMBOL(snd_emu8000_peek);
1164 EXPORT_SYMBOL(snd_emu8000_poke_dw);
1165 EXPORT_SYMBOL(snd_emu8000_peek_dw);
1166 EXPORT_SYMBOL(snd_emu8000_dma_chan);
1167 EXPORT_SYMBOL(snd_emu8000_init_fm);
1168 EXPORT_SYMBOL(snd_emu8000_load_chorus_fx);
1169 EXPORT_SYMBOL(snd_emu8000_load_reverb_fx);
1170 EXPORT_SYMBOL(snd_emu8000_update_chorus_mode);
1171 EXPORT_SYMBOL(snd_emu8000_update_reverb_mode);
1172 EXPORT_SYMBOL(snd_emu8000_update_equalizer);
1173