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