xref: /openbmc/linux/sound/isa/sb/emu8000.c (revision 87c2ce3b)
1 /*
2  *  Copyright (c) by Jaroslav Kysela <perex@suse.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 <sound/driver.h>
24 #include <linux/wait.h>
25 #include <linux/sched.h>
26 #include <linux/slab.h>
27 #include <linux/ioport.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 __init
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 __init
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 __init
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 __init
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 __init
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] /*__devinitdata*/ = {
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] /*__devinitdata*/ = {
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] /*__devinitdata*/ = {
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] /*__devinitdata*/ = {
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 __init
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 __init
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 arbitary 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 __init
379 size_dram(struct snd_emu8000 *emu)
380 {
381 	int i, size;
382 
383 	if (emu->dram_checked)
384 		return;
385 
386 	size = 0;
387 
388 	/* write out a magic number */
389 	snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE);
390 	snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_READ);
391 	EMU8000_SMALW_WRITE(emu, EMU8000_DRAM_OFFSET);
392 	EMU8000_SMLD_WRITE(emu, UNIQUE_ID1);
393 	snd_emu8000_init_fm(emu); /* This must really be here and not 2 lines back even */
394 
395 	while (size < EMU8000_MAX_DRAM) {
396 
397 		size += 512 * 1024;  /* increment 512kbytes */
398 
399 		/* Write a unique data on the test address.
400 		 * if the address is out of range, the data is written on
401 		 * 0x200000(=EMU8000_DRAM_OFFSET).  Then the id word is
402 		 * changed by this data.
403 		 */
404 		/*snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE);*/
405 		EMU8000_SMALW_WRITE(emu, EMU8000_DRAM_OFFSET + (size>>1));
406 		EMU8000_SMLD_WRITE(emu, UNIQUE_ID2);
407 		snd_emu8000_write_wait(emu);
408 
409 		/*
410 		 * read the data on the just written DRAM address
411 		 * if not the same then we have reached the end of ram.
412 		 */
413 		/*snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_READ);*/
414 		EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET + (size>>1));
415 		/*snd_emu8000_read_wait(emu);*/
416 		EMU8000_SMLD_READ(emu); /* discard stale data  */
417 		if (EMU8000_SMLD_READ(emu) != UNIQUE_ID2)
418 			break; /* we must have wrapped around */
419 
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 
434 	/* wait until FULL bit in SMAxW register is false */
435 	for (i = 0; i < 10000; i++) {
436 		if ((EMU8000_SMALW_READ(emu) & 0x80000000) == 0)
437 			break;
438 		schedule_timeout_interruptible(1);
439 		if (signal_pending(current))
440 			break;
441 	}
442 	snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_CLOSE);
443 	snd_emu8000_dma_chan(emu, 1, EMU8000_RAM_CLOSE);
444 
445 	snd_printdd("EMU8000 [0x%lx]: %d Kb on-board memory detected\n",
446 		    emu->port1, size/1024);
447 
448 	emu->mem_size = size;
449 	emu->dram_checked = 1;
450 }
451 
452 
453 /*
454  * Initiailise the FM section.  You have to do this to use sample RAM
455  * and therefore lose 2 voices.
456  */
457 /*exported*/ void
458 snd_emu8000_init_fm(struct snd_emu8000 *emu)
459 {
460 	unsigned long flags;
461 
462 	/* Initialize the last two channels for DRAM refresh and producing
463 	   the reverb and chorus effects for Yamaha OPL-3 synthesizer */
464 
465 	/* 31: FM left channel, 0xffffe0-0xffffe8 */
466 	EMU8000_DCYSUSV_WRITE(emu, 30, 0x80);
467 	EMU8000_PSST_WRITE(emu, 30, 0xFFFFFFE0); /* full left */
468 	EMU8000_CSL_WRITE(emu, 30, 0x00FFFFE8 | (emu->fm_chorus_depth << 24));
469 	EMU8000_PTRX_WRITE(emu, 30, (emu->fm_reverb_depth << 8));
470 	EMU8000_CPF_WRITE(emu, 30, 0);
471 	EMU8000_CCCA_WRITE(emu, 30, 0x00FFFFE3);
472 
473 	/* 32: FM right channel, 0xfffff0-0xfffff8 */
474 	EMU8000_DCYSUSV_WRITE(emu, 31, 0x80);
475 	EMU8000_PSST_WRITE(emu, 31, 0x00FFFFF0); /* full right */
476 	EMU8000_CSL_WRITE(emu, 31, 0x00FFFFF8 | (emu->fm_chorus_depth << 24));
477 	EMU8000_PTRX_WRITE(emu, 31, (emu->fm_reverb_depth << 8));
478 	EMU8000_CPF_WRITE(emu, 31, 0x8000);
479 	EMU8000_CCCA_WRITE(emu, 31, 0x00FFFFF3);
480 
481 	snd_emu8000_poke((emu), EMU8000_DATA0(emu), EMU8000_CMD(1, (30)), 0);
482 
483 	spin_lock_irqsave(&emu->reg_lock, flags);
484 	while (!(inw(EMU8000_PTR(emu)) & 0x1000))
485 		;
486 	while ((inw(EMU8000_PTR(emu)) & 0x1000))
487 		;
488 	spin_unlock_irqrestore(&emu->reg_lock, flags);
489 	snd_emu8000_poke((emu), EMU8000_DATA0(emu), EMU8000_CMD(1, (30)), 0x4828);
490 	/* this is really odd part.. */
491 	outb(0x3C, EMU8000_PTR(emu));
492 	outb(0, EMU8000_DATA1(emu));
493 
494 	/* skew volume & cutoff */
495 	EMU8000_VTFT_WRITE(emu, 30, 0x8000FFFF);
496 	EMU8000_VTFT_WRITE(emu, 31, 0x8000FFFF);
497 }
498 
499 
500 /*
501  * The main initialization routine.
502  */
503 static void __init
504 snd_emu8000_init_hw(struct snd_emu8000 *emu)
505 {
506 	int i;
507 
508 	emu->last_reg = 0xffff; /* reset the last register index */
509 
510 	/* initialize hardware configuration */
511 	EMU8000_HWCF1_WRITE(emu, 0x0059);
512 	EMU8000_HWCF2_WRITE(emu, 0x0020);
513 
514 	/* disable audio; this seems to reduce a clicking noise a bit.. */
515 	EMU8000_HWCF3_WRITE(emu, 0);
516 
517 	/* initialize audio channels */
518 	init_audio(emu);
519 
520 	/* initialize DMA */
521 	init_dma(emu);
522 
523 	/* initialize init arrays */
524 	init_arrays(emu);
525 
526 	/*
527 	 * Initialize the FM section of the AWE32, this is needed
528 	 * for DRAM refresh as well
529 	 */
530 	snd_emu8000_init_fm(emu);
531 
532 	/* terminate all voices */
533 	for (i = 0; i < EMU8000_DRAM_VOICES; i++)
534 		EMU8000_DCYSUSV_WRITE(emu, 0, 0x807F);
535 
536 	/* check DRAM memory size */
537 	size_dram(emu);
538 
539 	/* enable audio */
540 	EMU8000_HWCF3_WRITE(emu, 0x4);
541 
542 	/* set equzlier, chorus and reverb modes */
543 	snd_emu8000_update_equalizer(emu);
544 	snd_emu8000_update_chorus_mode(emu);
545 	snd_emu8000_update_reverb_mode(emu);
546 }
547 
548 
549 /*----------------------------------------------------------------
550  * Bass/Treble Equalizer
551  *----------------------------------------------------------------*/
552 
553 static unsigned short bass_parm[12][3] = {
554 	{0xD26A, 0xD36A, 0x0000}, /* -12 dB */
555 	{0xD25B, 0xD35B, 0x0000}, /*  -8 */
556 	{0xD24C, 0xD34C, 0x0000}, /*  -6 */
557 	{0xD23D, 0xD33D, 0x0000}, /*  -4 */
558 	{0xD21F, 0xD31F, 0x0000}, /*  -2 */
559 	{0xC208, 0xC308, 0x0001}, /*   0 (HW default) */
560 	{0xC219, 0xC319, 0x0001}, /*  +2 */
561 	{0xC22A, 0xC32A, 0x0001}, /*  +4 */
562 	{0xC24C, 0xC34C, 0x0001}, /*  +6 */
563 	{0xC26E, 0xC36E, 0x0001}, /*  +8 */
564 	{0xC248, 0xC384, 0x0002}, /* +10 */
565 	{0xC26A, 0xC36A, 0x0002}, /* +12 dB */
566 };
567 
568 static unsigned short treble_parm[12][9] = {
569 	{0x821E, 0xC26A, 0x031E, 0xC36A, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001}, /* -12 dB */
570 	{0x821E, 0xC25B, 0x031E, 0xC35B, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
571 	{0x821E, 0xC24C, 0x031E, 0xC34C, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
572 	{0x821E, 0xC23D, 0x031E, 0xC33D, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
573 	{0x821E, 0xC21F, 0x031E, 0xC31F, 0x021E, 0xD208, 0x831E, 0xD308, 0x0001},
574 	{0x821E, 0xD208, 0x031E, 0xD308, 0x021E, 0xD208, 0x831E, 0xD308, 0x0002},
575 	{0x821E, 0xD208, 0x031E, 0xD308, 0x021D, 0xD219, 0x831D, 0xD319, 0x0002},
576 	{0x821E, 0xD208, 0x031E, 0xD308, 0x021C, 0xD22A, 0x831C, 0xD32A, 0x0002},
577 	{0x821E, 0xD208, 0x031E, 0xD308, 0x021A, 0xD24C, 0x831A, 0xD34C, 0x0002},
578 	{0x821E, 0xD208, 0x031E, 0xD308, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}, /* +8 (HW default) */
579 	{0x821D, 0xD219, 0x031D, 0xD319, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002},
580 	{0x821C, 0xD22A, 0x031C, 0xD32A, 0x0219, 0xD26E, 0x8319, 0xD36E, 0x0002}  /* +12 dB */
581 };
582 
583 
584 /*
585  * set Emu8000 digital equalizer; from 0 to 11 [-12dB - 12dB]
586  */
587 /*exported*/ void
588 snd_emu8000_update_equalizer(struct snd_emu8000 *emu)
589 {
590 	unsigned short w;
591 	int bass = emu->bass_level;
592 	int treble = emu->treble_level;
593 
594 	if (bass < 0 || bass > 11 || treble < 0 || treble > 11)
595 		return;
596 	EMU8000_INIT4_WRITE(emu, 0x01, bass_parm[bass][0]);
597 	EMU8000_INIT4_WRITE(emu, 0x11, bass_parm[bass][1]);
598 	EMU8000_INIT3_WRITE(emu, 0x11, treble_parm[treble][0]);
599 	EMU8000_INIT3_WRITE(emu, 0x13, treble_parm[treble][1]);
600 	EMU8000_INIT3_WRITE(emu, 0x1b, treble_parm[treble][2]);
601 	EMU8000_INIT4_WRITE(emu, 0x07, treble_parm[treble][3]);
602 	EMU8000_INIT4_WRITE(emu, 0x0b, treble_parm[treble][4]);
603 	EMU8000_INIT4_WRITE(emu, 0x0d, treble_parm[treble][5]);
604 	EMU8000_INIT4_WRITE(emu, 0x17, treble_parm[treble][6]);
605 	EMU8000_INIT4_WRITE(emu, 0x19, treble_parm[treble][7]);
606 	w = bass_parm[bass][2] + treble_parm[treble][8];
607 	EMU8000_INIT4_WRITE(emu, 0x15, (unsigned short)(w + 0x0262));
608 	EMU8000_INIT4_WRITE(emu, 0x1d, (unsigned short)(w + 0x8362));
609 }
610 
611 
612 /*----------------------------------------------------------------
613  * Chorus mode control
614  *----------------------------------------------------------------*/
615 
616 /*
617  * chorus mode parameters
618  */
619 #define SNDRV_EMU8000_CHORUS_1		0
620 #define	SNDRV_EMU8000_CHORUS_2		1
621 #define	SNDRV_EMU8000_CHORUS_3		2
622 #define	SNDRV_EMU8000_CHORUS_4		3
623 #define	SNDRV_EMU8000_CHORUS_FEEDBACK	4
624 #define	SNDRV_EMU8000_CHORUS_FLANGER	5
625 #define	SNDRV_EMU8000_CHORUS_SHORTDELAY	6
626 #define	SNDRV_EMU8000_CHORUS_SHORTDELAY2	7
627 #define SNDRV_EMU8000_CHORUS_PREDEFINED	8
628 /* user can define chorus modes up to 32 */
629 #define SNDRV_EMU8000_CHORUS_NUMBERS	32
630 
631 struct soundfont_chorus_fx {
632 	unsigned short feedback;	/* feedback level (0xE600-0xE6FF) */
633 	unsigned short delay_offset;	/* delay (0-0x0DA3) [1/44100 sec] */
634 	unsigned short lfo_depth;	/* LFO depth (0xBC00-0xBCFF) */
635 	unsigned int delay;	/* right delay (0-0xFFFFFFFF) [1/256/44100 sec] */
636 	unsigned int lfo_freq;		/* LFO freq LFO freq (0-0xFFFFFFFF) */
637 };
638 
639 /* 5 parameters for each chorus mode; 3 x 16bit, 2 x 32bit */
640 static char chorus_defined[SNDRV_EMU8000_CHORUS_NUMBERS];
641 static struct soundfont_chorus_fx chorus_parm[SNDRV_EMU8000_CHORUS_NUMBERS] = {
642 	{0xE600, 0x03F6, 0xBC2C ,0x00000000, 0x0000006D}, /* chorus 1 */
643 	{0xE608, 0x031A, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 2 */
644 	{0xE610, 0x031A, 0xBC84, 0x00000000, 0x00000083}, /* chorus 3 */
645 	{0xE620, 0x0269, 0xBC6E, 0x00000000, 0x0000017C}, /* chorus 4 */
646 	{0xE680, 0x04D3, 0xBCA6, 0x00000000, 0x0000005B}, /* feedback */
647 	{0xE6E0, 0x044E, 0xBC37, 0x00000000, 0x00000026}, /* flanger */
648 	{0xE600, 0x0B06, 0xBC00, 0x0006E000, 0x00000083}, /* short delay */
649 	{0xE6C0, 0x0B06, 0xBC00, 0x0006E000, 0x00000083}, /* short delay + feedback */
650 };
651 
652 /*exported*/ int
653 snd_emu8000_load_chorus_fx(struct snd_emu8000 *emu, int mode, const void __user *buf, long len)
654 {
655 	struct soundfont_chorus_fx rec;
656 	if (mode < SNDRV_EMU8000_CHORUS_PREDEFINED || mode >= SNDRV_EMU8000_CHORUS_NUMBERS) {
657 		snd_printk(KERN_WARNING "invalid chorus mode %d for uploading\n", mode);
658 		return -EINVAL;
659 	}
660 	if (len < (long)sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec)))
661 		return -EFAULT;
662 	chorus_parm[mode] = rec;
663 	chorus_defined[mode] = 1;
664 	return 0;
665 }
666 
667 /*exported*/ void
668 snd_emu8000_update_chorus_mode(struct snd_emu8000 *emu)
669 {
670 	int effect = emu->chorus_mode;
671 	if (effect < 0 || effect >= SNDRV_EMU8000_CHORUS_NUMBERS ||
672 	    (effect >= SNDRV_EMU8000_CHORUS_PREDEFINED && !chorus_defined[effect]))
673 		return;
674 	EMU8000_INIT3_WRITE(emu, 0x09, chorus_parm[effect].feedback);
675 	EMU8000_INIT3_WRITE(emu, 0x0c, chorus_parm[effect].delay_offset);
676 	EMU8000_INIT4_WRITE(emu, 0x03, chorus_parm[effect].lfo_depth);
677 	EMU8000_HWCF4_WRITE(emu, chorus_parm[effect].delay);
678 	EMU8000_HWCF5_WRITE(emu, chorus_parm[effect].lfo_freq);
679 	EMU8000_HWCF6_WRITE(emu, 0x8000);
680 	EMU8000_HWCF7_WRITE(emu, 0x0000);
681 }
682 
683 /*----------------------------------------------------------------
684  * Reverb mode control
685  *----------------------------------------------------------------*/
686 
687 /*
688  * reverb mode parameters
689  */
690 #define	SNDRV_EMU8000_REVERB_ROOM1	0
691 #define SNDRV_EMU8000_REVERB_ROOM2	1
692 #define	SNDRV_EMU8000_REVERB_ROOM3	2
693 #define	SNDRV_EMU8000_REVERB_HALL1	3
694 #define	SNDRV_EMU8000_REVERB_HALL2	4
695 #define	SNDRV_EMU8000_REVERB_PLATE	5
696 #define	SNDRV_EMU8000_REVERB_DELAY	6
697 #define	SNDRV_EMU8000_REVERB_PANNINGDELAY 7
698 #define SNDRV_EMU8000_REVERB_PREDEFINED	8
699 /* user can define reverb modes up to 32 */
700 #define SNDRV_EMU8000_REVERB_NUMBERS	32
701 
702 struct soundfont_reverb_fx {
703 	unsigned short parms[28];
704 };
705 
706 /* reverb mode settings; write the following 28 data of 16 bit length
707  *   on the corresponding ports in the reverb_cmds array
708  */
709 static char reverb_defined[SNDRV_EMU8000_CHORUS_NUMBERS];
710 static struct soundfont_reverb_fx reverb_parm[SNDRV_EMU8000_REVERB_NUMBERS] = {
711 {{  /* room 1 */
712 	0xB488, 0xA450, 0x9550, 0x84B5, 0x383A, 0x3EB5, 0x72F4,
713 	0x72A4, 0x7254, 0x7204, 0x7204, 0x7204, 0x4416, 0x4516,
714 	0xA490, 0xA590, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
715 	0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
716 }},
717 {{  /* room 2 */
718 	0xB488, 0xA458, 0x9558, 0x84B5, 0x383A, 0x3EB5, 0x7284,
719 	0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
720 	0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
721 	0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
722 }},
723 {{  /* room 3 */
724 	0xB488, 0xA460, 0x9560, 0x84B5, 0x383A, 0x3EB5, 0x7284,
725 	0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4416, 0x4516,
726 	0xA490, 0xA590, 0x842C, 0x852C, 0x842C, 0x852C, 0x842B,
727 	0x852B, 0x842B, 0x852B, 0x842A, 0x852A, 0x842A, 0x852A,
728 }},
729 {{  /* hall 1 */
730 	0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7284,
731 	0x7254, 0x7224, 0x7224, 0x7254, 0x7284, 0x4448, 0x4548,
732 	0xA440, 0xA540, 0x842B, 0x852B, 0x842B, 0x852B, 0x842A,
733 	0x852A, 0x842A, 0x852A, 0x8429, 0x8529, 0x8429, 0x8529,
734 }},
735 {{  /* hall 2 */
736 	0xB488, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7254,
737 	0x7234, 0x7224, 0x7254, 0x7264, 0x7294, 0x44C3, 0x45C3,
738 	0xA404, 0xA504, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
739 	0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
740 }},
741 {{  /* plate */
742 	0xB4FF, 0xA470, 0x9570, 0x84B5, 0x383A, 0x3EB5, 0x7234,
743 	0x7234, 0x7234, 0x7234, 0x7234, 0x7234, 0x4448, 0x4548,
744 	0xA440, 0xA540, 0x842A, 0x852A, 0x842A, 0x852A, 0x8429,
745 	0x8529, 0x8429, 0x8529, 0x8428, 0x8528, 0x8428, 0x8528,
746 }},
747 {{  /* delay */
748 	0xB4FF, 0xA470, 0x9500, 0x84B5, 0x333A, 0x39B5, 0x7204,
749 	0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
750 	0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
751 	0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
752 }},
753 {{  /* panning delay */
754 	0xB4FF, 0xA490, 0x9590, 0x8474, 0x333A, 0x39B5, 0x7204,
755 	0x7204, 0x7204, 0x7204, 0x7204, 0x72F4, 0x4400, 0x4500,
756 	0xA4FF, 0xA5FF, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420,
757 	0x8520, 0x8420, 0x8520, 0x8420, 0x8520, 0x8420, 0x8520,
758 }},
759 };
760 
761 enum { DATA1, DATA2 };
762 #define AWE_INIT1(c)	EMU8000_CMD(2,c), DATA1
763 #define AWE_INIT2(c)	EMU8000_CMD(2,c), DATA2
764 #define AWE_INIT3(c)	EMU8000_CMD(3,c), DATA1
765 #define AWE_INIT4(c)	EMU8000_CMD(3,c), DATA2
766 
767 static struct reverb_cmd_pair {
768 	unsigned short cmd, port;
769 } reverb_cmds[28] = {
770   {AWE_INIT1(0x03)}, {AWE_INIT1(0x05)}, {AWE_INIT4(0x1F)}, {AWE_INIT1(0x07)},
771   {AWE_INIT2(0x14)}, {AWE_INIT2(0x16)}, {AWE_INIT1(0x0F)}, {AWE_INIT1(0x17)},
772   {AWE_INIT1(0x1F)}, {AWE_INIT2(0x07)}, {AWE_INIT2(0x0F)}, {AWE_INIT2(0x17)},
773   {AWE_INIT2(0x1D)}, {AWE_INIT2(0x1F)}, {AWE_INIT3(0x01)}, {AWE_INIT3(0x03)},
774   {AWE_INIT1(0x09)}, {AWE_INIT1(0x0B)}, {AWE_INIT1(0x11)}, {AWE_INIT1(0x13)},
775   {AWE_INIT1(0x19)}, {AWE_INIT1(0x1B)}, {AWE_INIT2(0x01)}, {AWE_INIT2(0x03)},
776   {AWE_INIT2(0x09)}, {AWE_INIT2(0x0B)}, {AWE_INIT2(0x11)}, {AWE_INIT2(0x13)},
777 };
778 
779 /*exported*/ int
780 snd_emu8000_load_reverb_fx(struct snd_emu8000 *emu, int mode, const void __user *buf, long len)
781 {
782 	struct soundfont_reverb_fx rec;
783 
784 	if (mode < SNDRV_EMU8000_REVERB_PREDEFINED || mode >= SNDRV_EMU8000_REVERB_NUMBERS) {
785 		snd_printk(KERN_WARNING "invalid reverb mode %d for uploading\n", mode);
786 		return -EINVAL;
787 	}
788 	if (len < (long)sizeof(rec) || copy_from_user(&rec, buf, sizeof(rec)))
789 		return -EFAULT;
790 	reverb_parm[mode] = rec;
791 	reverb_defined[mode] = 1;
792 	return 0;
793 }
794 
795 /*exported*/ void
796 snd_emu8000_update_reverb_mode(struct snd_emu8000 *emu)
797 {
798 	int effect = emu->reverb_mode;
799 	int i;
800 
801 	if (effect < 0 || effect >= SNDRV_EMU8000_REVERB_NUMBERS ||
802 	    (effect >= SNDRV_EMU8000_REVERB_PREDEFINED && !reverb_defined[effect]))
803 		return;
804 	for (i = 0; i < 28; i++) {
805 		int port;
806 		if (reverb_cmds[i].port == DATA1)
807 			port = EMU8000_DATA1(emu);
808 		else
809 			port = EMU8000_DATA2(emu);
810 		snd_emu8000_poke(emu, port, reverb_cmds[i].cmd, reverb_parm[effect].parms[i]);
811 	}
812 }
813 
814 
815 /*----------------------------------------------------------------
816  * mixer interface
817  *----------------------------------------------------------------*/
818 
819 /*
820  * bass/treble
821  */
822 static int mixer_bass_treble_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
823 {
824 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
825 	uinfo->count = 1;
826 	uinfo->value.integer.min = 0;
827 	uinfo->value.integer.max = 11;
828 	return 0;
829 }
830 
831 static int mixer_bass_treble_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
832 {
833 	struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
834 
835 	ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->treble_level : emu->bass_level;
836 	return 0;
837 }
838 
839 static int mixer_bass_treble_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
840 {
841 	struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
842 	unsigned long flags;
843 	int change;
844 	unsigned short val1;
845 
846 	val1 = ucontrol->value.integer.value[0] % 12;
847 	spin_lock_irqsave(&emu->control_lock, flags);
848 	if (kcontrol->private_value) {
849 		change = val1 != emu->treble_level;
850 		emu->treble_level = val1;
851 	} else {
852 		change = val1 != emu->bass_level;
853 		emu->bass_level = val1;
854 	}
855 	spin_unlock_irqrestore(&emu->control_lock, flags);
856 	snd_emu8000_update_equalizer(emu);
857 	return change;
858 }
859 
860 static struct snd_kcontrol_new mixer_bass_control =
861 {
862 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
863 	.name = "Synth Tone Control - Bass",
864 	.info = mixer_bass_treble_info,
865 	.get = mixer_bass_treble_get,
866 	.put = mixer_bass_treble_put,
867 	.private_value = 0,
868 };
869 
870 static struct snd_kcontrol_new mixer_treble_control =
871 {
872 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
873 	.name = "Synth Tone Control - Treble",
874 	.info = mixer_bass_treble_info,
875 	.get = mixer_bass_treble_get,
876 	.put = mixer_bass_treble_put,
877 	.private_value = 1,
878 };
879 
880 /*
881  * chorus/reverb mode
882  */
883 static int mixer_chorus_reverb_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
884 {
885 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
886 	uinfo->count = 1;
887 	uinfo->value.integer.min = 0;
888 	uinfo->value.integer.max = kcontrol->private_value ? (SNDRV_EMU8000_CHORUS_NUMBERS-1) : (SNDRV_EMU8000_REVERB_NUMBERS-1);
889 	return 0;
890 }
891 
892 static int mixer_chorus_reverb_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
893 {
894 	struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
895 
896 	ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->chorus_mode : emu->reverb_mode;
897 	return 0;
898 }
899 
900 static int mixer_chorus_reverb_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
901 {
902 	struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
903 	unsigned long flags;
904 	int change;
905 	unsigned short val1;
906 
907 	spin_lock_irqsave(&emu->control_lock, flags);
908 	if (kcontrol->private_value) {
909 		val1 = ucontrol->value.integer.value[0] % SNDRV_EMU8000_CHORUS_NUMBERS;
910 		change = val1 != emu->chorus_mode;
911 		emu->chorus_mode = val1;
912 	} else {
913 		val1 = ucontrol->value.integer.value[0] % SNDRV_EMU8000_REVERB_NUMBERS;
914 		change = val1 != emu->reverb_mode;
915 		emu->reverb_mode = val1;
916 	}
917 	spin_unlock_irqrestore(&emu->control_lock, flags);
918 	if (change) {
919 		if (kcontrol->private_value)
920 			snd_emu8000_update_chorus_mode(emu);
921 		else
922 			snd_emu8000_update_reverb_mode(emu);
923 	}
924 	return change;
925 }
926 
927 static struct snd_kcontrol_new mixer_chorus_mode_control =
928 {
929 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
930 	.name = "Chorus Mode",
931 	.info = mixer_chorus_reverb_info,
932 	.get = mixer_chorus_reverb_get,
933 	.put = mixer_chorus_reverb_put,
934 	.private_value = 1,
935 };
936 
937 static struct snd_kcontrol_new mixer_reverb_mode_control =
938 {
939 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
940 	.name = "Reverb Mode",
941 	.info = mixer_chorus_reverb_info,
942 	.get = mixer_chorus_reverb_get,
943 	.put = mixer_chorus_reverb_put,
944 	.private_value = 0,
945 };
946 
947 /*
948  * FM OPL3 chorus/reverb depth
949  */
950 static int mixer_fm_depth_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
951 {
952 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
953 	uinfo->count = 1;
954 	uinfo->value.integer.min = 0;
955 	uinfo->value.integer.max = 255;
956 	return 0;
957 }
958 
959 static int mixer_fm_depth_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
960 {
961 	struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
962 
963 	ucontrol->value.integer.value[0] = kcontrol->private_value ? emu->fm_chorus_depth : emu->fm_reverb_depth;
964 	return 0;
965 }
966 
967 static int mixer_fm_depth_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
968 {
969 	struct snd_emu8000 *emu = snd_kcontrol_chip(kcontrol);
970 	unsigned long flags;
971 	int change;
972 	unsigned short val1;
973 
974 	val1 = ucontrol->value.integer.value[0] % 256;
975 	spin_lock_irqsave(&emu->control_lock, flags);
976 	if (kcontrol->private_value) {
977 		change = val1 != emu->fm_chorus_depth;
978 		emu->fm_chorus_depth = val1;
979 	} else {
980 		change = val1 != emu->fm_reverb_depth;
981 		emu->fm_reverb_depth = val1;
982 	}
983 	spin_unlock_irqrestore(&emu->control_lock, flags);
984 	if (change)
985 		snd_emu8000_init_fm(emu);
986 	return change;
987 }
988 
989 static struct snd_kcontrol_new mixer_fm_chorus_depth_control =
990 {
991 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
992 	.name = "FM Chorus Depth",
993 	.info = mixer_fm_depth_info,
994 	.get = mixer_fm_depth_get,
995 	.put = mixer_fm_depth_put,
996 	.private_value = 1,
997 };
998 
999 static struct snd_kcontrol_new mixer_fm_reverb_depth_control =
1000 {
1001 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1002 	.name = "FM Reverb Depth",
1003 	.info = mixer_fm_depth_info,
1004 	.get = mixer_fm_depth_get,
1005 	.put = mixer_fm_depth_put,
1006 	.private_value = 0,
1007 };
1008 
1009 
1010 static struct snd_kcontrol_new *mixer_defs[EMU8000_NUM_CONTROLS] = {
1011 	&mixer_bass_control,
1012 	&mixer_treble_control,
1013 	&mixer_chorus_mode_control,
1014 	&mixer_reverb_mode_control,
1015 	&mixer_fm_chorus_depth_control,
1016 	&mixer_fm_reverb_depth_control,
1017 };
1018 
1019 /*
1020  * create and attach mixer elements for WaveTable treble/bass controls
1021  */
1022 static int __init
1023 snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu)
1024 {
1025 	int i, err = 0;
1026 
1027 	snd_assert(emu != NULL && card != NULL, return -EINVAL);
1028 
1029 	spin_lock_init(&emu->control_lock);
1030 
1031 	memset(emu->controls, 0, sizeof(emu->controls));
1032 	for (i = 0; i < EMU8000_NUM_CONTROLS; i++) {
1033 		if ((err = snd_ctl_add(card, emu->controls[i] = snd_ctl_new1(mixer_defs[i], emu))) < 0)
1034 			goto __error;
1035 	}
1036 	return 0;
1037 
1038 __error:
1039 	for (i = 0; i < EMU8000_NUM_CONTROLS; i++) {
1040 		down_write(&card->controls_rwsem);
1041 		if (emu->controls[i])
1042 			snd_ctl_remove(card, emu->controls[i]);
1043 		up_write(&card->controls_rwsem);
1044 	}
1045 	return err;
1046 }
1047 
1048 
1049 /*
1050  * free resources
1051  */
1052 static int snd_emu8000_free(struct snd_emu8000 *hw)
1053 {
1054 	release_and_free_resource(hw->res_port1);
1055 	release_and_free_resource(hw->res_port2);
1056 	release_and_free_resource(hw->res_port3);
1057 	kfree(hw);
1058 	return 0;
1059 }
1060 
1061 /*
1062  */
1063 static int snd_emu8000_dev_free(struct snd_device *device)
1064 {
1065 	struct snd_emu8000 *hw = device->device_data;
1066 	return snd_emu8000_free(hw);
1067 }
1068 
1069 /*
1070  * initialize and register emu8000 synth device.
1071  */
1072 int __init
1073 snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports,
1074 		struct snd_seq_device **awe_ret)
1075 {
1076 	struct snd_seq_device *awe;
1077 	struct snd_emu8000 *hw;
1078 	int err;
1079 	static struct snd_device_ops ops = {
1080 		.dev_free = snd_emu8000_dev_free,
1081 	};
1082 
1083 	if (awe_ret)
1084 		*awe_ret = NULL;
1085 
1086 	if (seq_ports <= 0)
1087 		return 0;
1088 
1089 	hw = kzalloc(sizeof(*hw), GFP_KERNEL);
1090 	if (hw == NULL)
1091 		return -ENOMEM;
1092 	spin_lock_init(&hw->reg_lock);
1093 	hw->index = index;
1094 	hw->port1 = port;
1095 	hw->port2 = port + 0x400;
1096 	hw->port3 = port + 0x800;
1097 	if (!(hw->res_port1 = request_region(hw->port1, 4, "Emu8000-1")) ||
1098 	    !(hw->res_port2 = request_region(hw->port2, 4, "Emu8000-2")) ||
1099 	    !(hw->res_port3 = request_region(hw->port3, 4, "Emu8000-3"))) {
1100 		snd_printk(KERN_ERR "sbawe: can't grab ports 0x%lx, 0x%lx, 0x%lx\n", hw->port1, hw->port2, hw->port3);
1101 		snd_emu8000_free(hw);
1102 		return -EBUSY;
1103 	}
1104 	hw->mem_size = 0;
1105 	hw->card = card;
1106 	hw->seq_ports = seq_ports;
1107 	hw->bass_level = 5;
1108 	hw->treble_level = 9;
1109 	hw->chorus_mode = 2;
1110 	hw->reverb_mode = 4;
1111 	hw->fm_chorus_depth = 0;
1112 	hw->fm_reverb_depth = 0;
1113 
1114 	if (snd_emu8000_detect(hw) < 0) {
1115 		snd_emu8000_free(hw);
1116 		return -ENODEV;
1117 	}
1118 
1119 	snd_emu8000_init_hw(hw);
1120 	if ((err = snd_emu8000_create_mixer(card, hw)) < 0) {
1121 		snd_emu8000_free(hw);
1122 		return err;
1123 	}
1124 
1125 	if ((err = snd_device_new(card, SNDRV_DEV_CODEC, hw, &ops)) < 0) {
1126 		snd_emu8000_free(hw);
1127 		return err;
1128 	}
1129 #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
1130 	if (snd_seq_device_new(card, index, SNDRV_SEQ_DEV_ID_EMU8000,
1131 			       sizeof(struct snd_emu8000*), &awe) >= 0) {
1132 		strcpy(awe->name, "EMU-8000");
1133 		*(struct snd_emu8000 **)SNDRV_SEQ_DEVICE_ARGPTR(awe) = hw;
1134 	}
1135 #else
1136 	awe = NULL;
1137 #endif
1138 	if (awe_ret)
1139 		*awe_ret = awe;
1140 
1141 	return 0;
1142 }
1143 
1144 
1145 /*
1146  * exported stuff
1147  */
1148 
1149 EXPORT_SYMBOL(snd_emu8000_poke);
1150 EXPORT_SYMBOL(snd_emu8000_peek);
1151 EXPORT_SYMBOL(snd_emu8000_poke_dw);
1152 EXPORT_SYMBOL(snd_emu8000_peek_dw);
1153 EXPORT_SYMBOL(snd_emu8000_dma_chan);
1154 EXPORT_SYMBOL(snd_emu8000_init_fm);
1155 EXPORT_SYMBOL(snd_emu8000_load_chorus_fx);
1156 EXPORT_SYMBOL(snd_emu8000_load_reverb_fx);
1157 EXPORT_SYMBOL(snd_emu8000_update_chorus_mode);
1158 EXPORT_SYMBOL(snd_emu8000_update_reverb_mode);
1159 EXPORT_SYMBOL(snd_emu8000_update_equalizer);
1160