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