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