xref: /linux/sound/isa/sb/emu8000.c (revision af1f459233d4edeef634f559539e7f4b64cb1d25)
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 */
35 void 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 */
48 unsigned 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 */
63 void 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 */
77 unsigned 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
97 snd_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  */
121 static void
122 snd_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  */
133 static void
134 snd_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  */
146 static int
147 snd_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  */
172 static void
173 init_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  */
213 static void
214 init_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  */
225 static const 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 
247 static const 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 
269 static const 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 
291 static const 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  */
317 static void
318 send_array(struct snd_emu8000 *emu, const unsigned short *data, int size)
319 {
320 	int i;
321 	const 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  */
339 static void
340 init_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  */
365 static void
366 size_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 
431 skip_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
456 snd_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  */
501 static void
502 snd_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 
551 static const 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 
566 static const 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
586 snd_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 
629 struct 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 */
638 static char chorus_defined[SNDRV_EMU8000_CHORUS_NUMBERS];
639 static 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
651 snd_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
666 snd_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 
700 struct 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  */
707 static char reverb_defined[SNDRV_EMU8000_CHORUS_NUMBERS];
708 static 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 
759 enum { 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 
765 static 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
778 snd_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
794 snd_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  */
820 static 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 
829 static 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 
837 static 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 
858 static const 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 
868 static const 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  */
881 static 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 
890 static 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 
898 static 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 
925 static const 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 
935 static const 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  */
948 static 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 
957 static 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 
965 static 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 
987 static const 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 
997 static const 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 
1008 static const 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  */
1020 static int
1021 snd_emu8000_create_mixer(struct snd_card *card, struct snd_emu8000 *emu)
1022 {
1023 	struct snd_kcontrol *kctl;
1024 	int i, err = 0;
1025 
1026 	if (snd_BUG_ON(!emu || !card))
1027 		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 		kctl = snd_ctl_new1(mixer_defs[i], emu);
1034 		err = snd_ctl_add(card, kctl);
1035 		if (err < 0)
1036 			goto __error;
1037 		emu->controls[i] = kctl;
1038 	}
1039 	return 0;
1040 
1041 __error:
1042 	for (i = 0; i < EMU8000_NUM_CONTROLS; i++) {
1043 		if (emu->controls[i])
1044 			snd_ctl_remove(card, emu->controls[i]);
1045 	}
1046 	return err;
1047 }
1048 
1049 /*
1050  * initialize and register emu8000 synth device.
1051  */
1052 int
1053 snd_emu8000_new(struct snd_card *card, int index, long port, int seq_ports,
1054 		struct snd_seq_device **awe_ret)
1055 {
1056 	struct snd_seq_device *awe;
1057 	struct snd_emu8000 *hw;
1058 	int err;
1059 
1060 	if (awe_ret)
1061 		*awe_ret = NULL;
1062 
1063 	if (seq_ports <= 0)
1064 		return 0;
1065 
1066 	hw = devm_kzalloc(card->dev, sizeof(*hw), GFP_KERNEL);
1067 	if (hw == NULL)
1068 		return -ENOMEM;
1069 	spin_lock_init(&hw->reg_lock);
1070 	hw->index = index;
1071 	hw->port1 = port;
1072 	hw->port2 = port + 0x400;
1073 	hw->port3 = port + 0x800;
1074 	if (!devm_request_region(card->dev, hw->port1, 4, "Emu8000-1") ||
1075 	    !devm_request_region(card->dev, hw->port2, 4, "Emu8000-2") ||
1076 	    !devm_request_region(card->dev, hw->port3, 4, "Emu8000-3")) {
1077 		snd_printk(KERN_ERR "sbawe: can't grab ports 0x%lx, 0x%lx, 0x%lx\n", hw->port1, hw->port2, hw->port3);
1078 		return -EBUSY;
1079 	}
1080 	hw->mem_size = 0;
1081 	hw->card = card;
1082 	hw->seq_ports = seq_ports;
1083 	hw->bass_level = 5;
1084 	hw->treble_level = 9;
1085 	hw->chorus_mode = 2;
1086 	hw->reverb_mode = 4;
1087 	hw->fm_chorus_depth = 0;
1088 	hw->fm_reverb_depth = 0;
1089 
1090 	if (snd_emu8000_detect(hw) < 0)
1091 		return -ENODEV;
1092 
1093 	snd_emu8000_init_hw(hw);
1094 	err = snd_emu8000_create_mixer(card, hw);
1095 	if (err < 0)
1096 		return err;
1097 #if IS_ENABLED(CONFIG_SND_SEQUENCER)
1098 	if (snd_seq_device_new(card, index, SNDRV_SEQ_DEV_ID_EMU8000,
1099 			       sizeof(struct snd_emu8000*), &awe) >= 0) {
1100 		strcpy(awe->name, "EMU-8000");
1101 		*(struct snd_emu8000 **)SNDRV_SEQ_DEVICE_ARGPTR(awe) = hw;
1102 	}
1103 #else
1104 	awe = NULL;
1105 #endif
1106 	if (awe_ret)
1107 		*awe_ret = awe;
1108 
1109 	return 0;
1110 }
1111 
1112 
1113 /*
1114  * exported stuff
1115  */
1116 
1117 EXPORT_SYMBOL(snd_emu8000_poke);
1118 EXPORT_SYMBOL(snd_emu8000_peek);
1119 EXPORT_SYMBOL(snd_emu8000_poke_dw);
1120 EXPORT_SYMBOL(snd_emu8000_peek_dw);
1121 EXPORT_SYMBOL(snd_emu8000_dma_chan);
1122 EXPORT_SYMBOL(snd_emu8000_init_fm);
1123 EXPORT_SYMBOL(snd_emu8000_load_chorus_fx);
1124 EXPORT_SYMBOL(snd_emu8000_load_reverb_fx);
1125 EXPORT_SYMBOL(snd_emu8000_update_chorus_mode);
1126 EXPORT_SYMBOL(snd_emu8000_update_reverb_mode);
1127 EXPORT_SYMBOL(snd_emu8000_update_equalizer);
1128