Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
emu8000.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) by Jaroslav Kysela <[email protected]>
3  * and (c) 1999 Steve Ratcliffe <[email protected]>
4  * Copyright (C) 1999-2000 Takashi Iwai <[email protected]>
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
111 {
112  unsigned right_bit = (mode & EMU8000_RAM_RIGHT) ? 0x01000000 : 0;
113  mode &= EMU8000_RAM_MODE_MASK;
114  if (mode == EMU8000_RAM_CLOSE) {
115  EMU8000_CCCA_WRITE(emu, ch, 0);
116  EMU8000_DCYSUSV_WRITE(emu, ch, 0x807F);
117  return;
118  }
119  EMU8000_DCYSUSV_WRITE(emu, ch, 0x80);
120  EMU8000_VTFT_WRITE(emu, ch, 0);
121  EMU8000_CVCF_WRITE(emu, ch, 0);
122  EMU8000_PTRX_WRITE(emu, ch, 0x40000000);
123  EMU8000_CPF_WRITE(emu, ch, 0x40000000);
124  EMU8000_PSST_WRITE(emu, ch, 0);
125  EMU8000_CSL_WRITE(emu, ch, 0);
126  if (mode == EMU8000_RAM_WRITE) /* DMA write */
127  EMU8000_CCCA_WRITE(emu, ch, 0x06000000 | right_bit);
128  else /* DMA read */
129  EMU8000_CCCA_WRITE(emu, ch, 0x04000000 | right_bit);
130 }
131 
132 /*
133  */
134 static void __devinit
135 snd_emu8000_read_wait(struct snd_emu8000 *emu)
136 {
137  while ((EMU8000_SMALR_READ(emu) & 0x80000000) != 0) {
139  if (signal_pending(current))
140  break;
141  }
142 }
143 
144 /*
145  */
146 static void __devinit
147 snd_emu8000_write_wait(struct snd_emu8000 *emu)
148 {
149  while ((EMU8000_SMALW_READ(emu) & 0x80000000) != 0) {
151  if (signal_pending(current))
152  break;
153  }
154 }
155 
156 /*
157  * detect a card at the given port
158  */
159 static int __devinit
160 snd_emu8000_detect(struct snd_emu8000 *emu)
161 {
162  /* Initialise */
163  EMU8000_HWCF1_WRITE(emu, 0x0059);
164  EMU8000_HWCF2_WRITE(emu, 0x0020);
165  EMU8000_HWCF3_WRITE(emu, 0x0000);
166  /* Check for a recognisable emu8000 */
167  /*
168  if ((EMU8000_U1_READ(emu) & 0x000f) != 0x000c)
169  return -ENODEV;
170  */
171  if ((EMU8000_HWCF1_READ(emu) & 0x007e) != 0x0058)
172  return -ENODEV;
173  if ((EMU8000_HWCF2_READ(emu) & 0x0003) != 0x0003)
174  return -ENODEV;
175 
176  snd_printdd("EMU8000 [0x%lx]: Synth chip found\n",
177  emu->port1);
178  return 0;
179 }
180 
181 
182 /*
183  * intiailize audio channels
184  */
185 static void __devinit
186 init_audio(struct snd_emu8000 *emu)
187 {
188  int ch;
189 
190  /* turn off envelope engines */
191  for (ch = 0; ch < EMU8000_CHANNELS; ch++)
192  EMU8000_DCYSUSV_WRITE(emu, ch, 0x80);
193 
194  /* reset all other parameters to zero */
195  for (ch = 0; ch < EMU8000_CHANNELS; ch++) {
196  EMU8000_ENVVOL_WRITE(emu, ch, 0);
197  EMU8000_ENVVAL_WRITE(emu, ch, 0);
198  EMU8000_DCYSUS_WRITE(emu, ch, 0);
199  EMU8000_ATKHLDV_WRITE(emu, ch, 0);
200  EMU8000_LFO1VAL_WRITE(emu, ch, 0);
201  EMU8000_ATKHLD_WRITE(emu, ch, 0);
202  EMU8000_LFO2VAL_WRITE(emu, ch, 0);
203  EMU8000_IP_WRITE(emu, ch, 0);
204  EMU8000_IFATN_WRITE(emu, ch, 0);
205  EMU8000_PEFE_WRITE(emu, ch, 0);
206  EMU8000_FMMOD_WRITE(emu, ch, 0);
207  EMU8000_TREMFRQ_WRITE(emu, ch, 0);
208  EMU8000_FM2FRQ2_WRITE(emu, ch, 0);
209  EMU8000_PTRX_WRITE(emu, ch, 0);
210  EMU8000_VTFT_WRITE(emu, ch, 0);
211  EMU8000_PSST_WRITE(emu, ch, 0);
212  EMU8000_CSL_WRITE(emu, ch, 0);
213  EMU8000_CCCA_WRITE(emu, ch, 0);
214  }
215 
216  for (ch = 0; ch < EMU8000_CHANNELS; ch++) {
217  EMU8000_CPF_WRITE(emu, ch, 0);
218  EMU8000_CVCF_WRITE(emu, ch, 0);
219  }
220 }
221 
222 
223 /*
224  * initialize DMA address
225  */
226 static void __devinit
227 init_dma(struct snd_emu8000 *emu)
228 {
229  EMU8000_SMALR_WRITE(emu, 0);
230  EMU8000_SMARR_WRITE(emu, 0);
231  EMU8000_SMALW_WRITE(emu, 0);
232  EMU8000_SMARW_WRITE(emu, 0);
233 }
234 
235 /*
236  * initialization arrays; from ADIP
237  */
238 static unsigned short init1[128] /*__devinitdata*/ = {
239  0x03ff, 0x0030, 0x07ff, 0x0130, 0x0bff, 0x0230, 0x0fff, 0x0330,
240  0x13ff, 0x0430, 0x17ff, 0x0530, 0x1bff, 0x0630, 0x1fff, 0x0730,
241  0x23ff, 0x0830, 0x27ff, 0x0930, 0x2bff, 0x0a30, 0x2fff, 0x0b30,
242  0x33ff, 0x0c30, 0x37ff, 0x0d30, 0x3bff, 0x0e30, 0x3fff, 0x0f30,
243 
244  0x43ff, 0x0030, 0x47ff, 0x0130, 0x4bff, 0x0230, 0x4fff, 0x0330,
245  0x53ff, 0x0430, 0x57ff, 0x0530, 0x5bff, 0x0630, 0x5fff, 0x0730,
246  0x63ff, 0x0830, 0x67ff, 0x0930, 0x6bff, 0x0a30, 0x6fff, 0x0b30,
247  0x73ff, 0x0c30, 0x77ff, 0x0d30, 0x7bff, 0x0e30, 0x7fff, 0x0f30,
248 
249  0x83ff, 0x0030, 0x87ff, 0x0130, 0x8bff, 0x0230, 0x8fff, 0x0330,
250  0x93ff, 0x0430, 0x97ff, 0x0530, 0x9bff, 0x0630, 0x9fff, 0x0730,
251  0xa3ff, 0x0830, 0xa7ff, 0x0930, 0xabff, 0x0a30, 0xafff, 0x0b30,
252  0xb3ff, 0x0c30, 0xb7ff, 0x0d30, 0xbbff, 0x0e30, 0xbfff, 0x0f30,
253 
254  0xc3ff, 0x0030, 0xc7ff, 0x0130, 0xcbff, 0x0230, 0xcfff, 0x0330,
255  0xd3ff, 0x0430, 0xd7ff, 0x0530, 0xdbff, 0x0630, 0xdfff, 0x0730,
256  0xe3ff, 0x0830, 0xe7ff, 0x0930, 0xebff, 0x0a30, 0xefff, 0x0b30,
257  0xf3ff, 0x0c30, 0xf7ff, 0x0d30, 0xfbff, 0x0e30, 0xffff, 0x0f30,
258 };
259 
260 static unsigned short init2[128] /*__devinitdata*/ = {
261  0x03ff, 0x8030, 0x07ff, 0x8130, 0x0bff, 0x8230, 0x0fff, 0x8330,
262  0x13ff, 0x8430, 0x17ff, 0x8530, 0x1bff, 0x8630, 0x1fff, 0x8730,
263  0x23ff, 0x8830, 0x27ff, 0x8930, 0x2bff, 0x8a30, 0x2fff, 0x8b30,
264  0x33ff, 0x8c30, 0x37ff, 0x8d30, 0x3bff, 0x8e30, 0x3fff, 0x8f30,
265 
266  0x43ff, 0x8030, 0x47ff, 0x8130, 0x4bff, 0x8230, 0x4fff, 0x8330,
267  0x53ff, 0x8430, 0x57ff, 0x8530, 0x5bff, 0x8630, 0x5fff, 0x8730,
268  0x63ff, 0x8830, 0x67ff, 0x8930, 0x6bff, 0x8a30, 0x6fff, 0x8b30,
269  0x73ff, 0x8c30, 0x77ff, 0x8d30, 0x7bff, 0x8e30, 0x7fff, 0x8f30,
270 
271  0x83ff, 0x8030, 0x87ff, 0x8130, 0x8bff, 0x8230, 0x8fff, 0x8330,
272  0x93ff, 0x8430, 0x97ff, 0x8530, 0x9bff, 0x8630, 0x9fff, 0x8730,
273  0xa3ff, 0x8830, 0xa7ff, 0x8930, 0xabff, 0x8a30, 0xafff, 0x8b30,
274  0xb3ff, 0x8c30, 0xb7ff, 0x8d30, 0xbbff, 0x8e30, 0xbfff, 0x8f30,
275 
276  0xc3ff, 0x8030, 0xc7ff, 0x8130, 0xcbff, 0x8230, 0xcfff, 0x8330,
277  0xd3ff, 0x8430, 0xd7ff, 0x8530, 0xdbff, 0x8630, 0xdfff, 0x8730,
278  0xe3ff, 0x8830, 0xe7ff, 0x8930, 0xebff, 0x8a30, 0xefff, 0x8b30,
279  0xf3ff, 0x8c30, 0xf7ff, 0x8d30, 0xfbff, 0x8e30, 0xffff, 0x8f30,
280 };
281 
282 static unsigned short init3[128] /*__devinitdata*/ = {
283  0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
284  0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x8F7C, 0x167E, 0xF254,
285  0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x8BAA, 0x1B6D, 0xF234,
286  0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x86E7, 0x229E, 0xF224,
287 
288  0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x87F6, 0x2C28, 0xF254,
289  0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x8F02, 0x1341, 0xF264,
290  0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x8FA9, 0x3EB5, 0xF294,
291  0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0xC4C3, 0x3EBB, 0xC5C3,
292 
293  0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x8671, 0x14FD, 0x8287,
294  0x3EBC, 0xE610, 0x3EC8, 0x8C7B, 0x031A, 0x87E6, 0x3EC8, 0x86F7,
295  0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x821F, 0x3ECA, 0x8386,
296  0x3EC1, 0x8C03, 0x3EC9, 0x831E, 0x3ECA, 0x8C4C, 0x3EBF, 0x8C55,
297 
298  0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x8EAD, 0x3EC8, 0xD308,
299  0x3EC2, 0x8F7E, 0x3ECB, 0x8219, 0x3ECB, 0xD26E, 0x3EC5, 0x831F,
300  0x3EC6, 0xC308, 0x3EC3, 0xB2FF, 0x3EC9, 0x8265, 0x3EC9, 0x8319,
301  0x1342, 0xD36E, 0x3EC7, 0xB3FF, 0x0000, 0x8365, 0x1420, 0x9570,
302 };
303 
304 static unsigned short init4[128] /*__devinitdata*/ = {
305  0x0C10, 0x8470, 0x14FE, 0xB488, 0x167F, 0xA470, 0x18E7, 0x84B5,
306  0x1B6E, 0x842A, 0x1F1D, 0x852A, 0x0DA3, 0x0F7C, 0x167E, 0x7254,
307  0x0000, 0x842A, 0x0001, 0x852A, 0x18E6, 0x0BAA, 0x1B6D, 0x7234,
308  0x229F, 0x8429, 0x2746, 0x8529, 0x1F1C, 0x06E7, 0x229E, 0x7224,
309 
310  0x0DA4, 0x8429, 0x2C29, 0x8529, 0x2745, 0x07F6, 0x2C28, 0x7254,
311  0x383B, 0x8428, 0x320F, 0x8528, 0x320E, 0x0F02, 0x1341, 0x7264,
312  0x3EB6, 0x8428, 0x3EB9, 0x8528, 0x383A, 0x0FA9, 0x3EB5, 0x7294,
313  0x3EB7, 0x8474, 0x3EBA, 0x8575, 0x3EB8, 0x44C3, 0x3EBB, 0x45C3,
314 
315  0x0000, 0xA404, 0x0001, 0xA504, 0x141F, 0x0671, 0x14FD, 0x0287,
316  0x3EBC, 0xE610, 0x3EC8, 0x0C7B, 0x031A, 0x07E6, 0x3EC8, 0x86F7,
317  0x3EC0, 0x821E, 0x3EBE, 0xD208, 0x3EBD, 0x021F, 0x3ECA, 0x0386,
318  0x3EC1, 0x0C03, 0x3EC9, 0x031E, 0x3ECA, 0x8C4C, 0x3EBF, 0x0C55,
319 
320  0x3EC9, 0xC208, 0x3EC4, 0xBC84, 0x3EC8, 0x0EAD, 0x3EC8, 0xD308,
321  0x3EC2, 0x8F7E, 0x3ECB, 0x0219, 0x3ECB, 0xD26E, 0x3EC5, 0x031F,
322  0x3EC6, 0xC308, 0x3EC3, 0x32FF, 0x3EC9, 0x0265, 0x3EC9, 0x8319,
323  0x1342, 0xD36E, 0x3EC7, 0x33FF, 0x0000, 0x8365, 0x1420, 0x9570,
324 };
325 
326 /* send an initialization array
327  * Taken from the oss driver, not obvious from the doc how this
328  * is meant to work
329  */
330 static void __devinit
331 send_array(struct snd_emu8000 *emu, unsigned short *data, int size)
332 {
333  int i;
334  unsigned short *p;
335 
336  p = data;
337  for (i = 0; i < size; i++, p++)
338  EMU8000_INIT1_WRITE(emu, i, *p);
339  for (i = 0; i < size; i++, p++)
340  EMU8000_INIT2_WRITE(emu, i, *p);
341  for (i = 0; i < size; i++, p++)
342  EMU8000_INIT3_WRITE(emu, i, *p);
343  for (i = 0; i < size; i++, p++)
344  EMU8000_INIT4_WRITE(emu, i, *p);
345 }
346 
347 
348 /*
349  * Send initialization arrays to start up, this just follows the
350  * initialisation sequence in the adip.
351  */
352 static void __devinit
353 init_arrays(struct snd_emu8000 *emu)
354 {
355  send_array(emu, init1, ARRAY_SIZE(init1)/4);
356 
357  msleep((1024 * 1000) / 44100); /* wait for 1024 clocks */
358  send_array(emu, init2, ARRAY_SIZE(init2)/4);
359  send_array(emu, init3, ARRAY_SIZE(init3)/4);
360 
361  EMU8000_HWCF4_WRITE(emu, 0);
362  EMU8000_HWCF5_WRITE(emu, 0x83);
363  EMU8000_HWCF6_WRITE(emu, 0x8000);
364 
365  send_array(emu, init4, ARRAY_SIZE(init4)/4);
366 }
367 
368 
369 #define UNIQUE_ID1 0xa5b9
370 #define UNIQUE_ID2 0x9d53
371 
372 /*
373  * Size the onboard memory.
374  * This is written so as not to need 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 __devinit
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 */
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));
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  */
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);
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;
451  if (signal_pending(current))
452  break;
453  }
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
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 __devinit
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 */
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
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 
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
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 
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
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 {
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);
869  return change;
870 }
871 
872 static struct snd_kcontrol_new mixer_bass_control =
873 {
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 {
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 {
898  uinfo->count = 1;
899  uinfo->value.integer.min = 0;
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)
933  else
935  }
936  return change;
937 }
938 
939 static struct snd_kcontrol_new mixer_chorus_mode_control =
940 {
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 {
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 {
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 __devinit
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 
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 {
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 __devinit
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))
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