Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-tc
[sfrench/cifs-2.6.git] / sound / isa / sb / emu8000.c
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 __devinit
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 __devinit
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 __devinit
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 __devinit
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 __devinit
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 __devinit
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 __devinit
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 __devinit
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 __devinit
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 __devinit
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 __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);