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