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