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