]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - sound/isa/sb/emu8000.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
[linux-2.6-omap-h63xx.git] / sound / isa / sb / emu8000.c
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                 size += 512 * 1024;  /* increment 512kbytes */
397
398                 /* Write a unique data on the test address.
399                  * if the address is out of range, the data is written on
400                  * 0x200000(=EMU8000_DRAM_OFFSET).  Then the id word is
401                  * changed by this data.
402                  */
403                 /*snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_WRITE);*/
404                 EMU8000_SMALW_WRITE(emu, EMU8000_DRAM_OFFSET + (size>>1));
405                 EMU8000_SMLD_WRITE(emu, UNIQUE_ID2);
406                 snd_emu8000_write_wait(emu);
407
408                 /*
409                  * read the data on the just written DRAM address
410                  * if not the same then we have reached the end of ram.
411                  */
412                 /*snd_emu8000_dma_chan(emu, 0, EMU8000_RAM_READ);*/
413                 EMU8000_SMALR_WRITE(emu, EMU8000_DRAM_OFFSET + (size>>1));
414                 /*snd_emu8000_read_wait(emu);*/
415                 EMU8000_SMLD_READ(emu); /* discard stale data  */
416                 if (EMU8000_SMLD_READ(emu) != UNIQUE_ID2)
417                         break; /* we must have wrapped around */
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);