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