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