Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/drivers/opl3/opl3_lib.c
10817 views
1
/*
2
* Copyright (c) by Jaroslav Kysela <[email protected]>,
3
* Hannu Savolainen 1993-1996,
4
* Rob Hooft
5
*
6
* Routines for control of AdLib FM cards (OPL2/OPL3/OPL4 chips)
7
*
8
* Most if code is ported from OSS/Lite.
9
*
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
14
*
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
19
*
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
*
24
*/
25
26
#include <sound/opl3.h>
27
#include <asm/io.h>
28
#include <linux/delay.h>
29
#include <linux/init.h>
30
#include <linux/slab.h>
31
#include <linux/ioport.h>
32
#include <sound/minors.h>
33
34
MODULE_AUTHOR("Jaroslav Kysela <[email protected]>, Hannu Savolainen 1993-1996, Rob Hooft");
35
MODULE_DESCRIPTION("Routines for control of AdLib FM cards (OPL2/OPL3/OPL4 chips)");
36
MODULE_LICENSE("GPL");
37
38
extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
39
40
static void snd_opl2_command(struct snd_opl3 * opl3, unsigned short cmd, unsigned char val)
41
{
42
unsigned long flags;
43
unsigned long port;
44
45
/*
46
* The original 2-OP synth requires a quite long delay
47
* after writing to a register.
48
*/
49
50
port = (cmd & OPL3_RIGHT) ? opl3->r_port : opl3->l_port;
51
52
spin_lock_irqsave(&opl3->reg_lock, flags);
53
54
outb((unsigned char) cmd, port);
55
udelay(10);
56
57
outb((unsigned char) val, port + 1);
58
udelay(30);
59
60
spin_unlock_irqrestore(&opl3->reg_lock, flags);
61
}
62
63
static void snd_opl3_command(struct snd_opl3 * opl3, unsigned short cmd, unsigned char val)
64
{
65
unsigned long flags;
66
unsigned long port;
67
68
/*
69
* The OPL-3 survives with just two INBs
70
* after writing to a register.
71
*/
72
73
port = (cmd & OPL3_RIGHT) ? opl3->r_port : opl3->l_port;
74
75
spin_lock_irqsave(&opl3->reg_lock, flags);
76
77
outb((unsigned char) cmd, port);
78
inb(opl3->l_port);
79
inb(opl3->l_port);
80
81
outb((unsigned char) val, port + 1);
82
inb(opl3->l_port);
83
inb(opl3->l_port);
84
85
spin_unlock_irqrestore(&opl3->reg_lock, flags);
86
}
87
88
static int snd_opl3_detect(struct snd_opl3 * opl3)
89
{
90
/*
91
* This function returns 1 if the FM chip is present at the given I/O port
92
* The detection algorithm plays with the timer built in the FM chip and
93
* looks for a change in the status register.
94
*
95
* Note! The timers of the FM chip are not connected to AdLib (and compatible)
96
* boards.
97
*
98
* Note2! The chip is initialized if detected.
99
*/
100
101
unsigned char stat1, stat2, signature;
102
103
/* Reset timers 1 and 2 */
104
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER1_MASK | OPL3_TIMER2_MASK);
105
/* Reset the IRQ of the FM chip */
106
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_IRQ_RESET);
107
signature = stat1 = inb(opl3->l_port); /* Status register */
108
if ((stat1 & 0xe0) != 0x00) { /* Should be 0x00 */
109
snd_printd("OPL3: stat1 = 0x%x\n", stat1);
110
return -ENODEV;
111
}
112
/* Set timer1 to 0xff */
113
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER1, 0xff);
114
/* Unmask and start timer 1 */
115
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER2_MASK | OPL3_TIMER1_START);
116
/* Now we have to delay at least 80us */
117
udelay(200);
118
/* Read status after timers have expired */
119
stat2 = inb(opl3->l_port);
120
/* Stop the timers */
121
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER1_MASK | OPL3_TIMER2_MASK);
122
/* Reset the IRQ of the FM chip */
123
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_IRQ_RESET);
124
if ((stat2 & 0xe0) != 0xc0) { /* There is no YM3812 */
125
snd_printd("OPL3: stat2 = 0x%x\n", stat2);
126
return -ENODEV;
127
}
128
129
/* If the toplevel code knows exactly the type of chip, don't try
130
to detect it. */
131
if (opl3->hardware != OPL3_HW_AUTO)
132
return 0;
133
134
/* There is a FM chip on this address. Detect the type (OPL2 to OPL4) */
135
if (signature == 0x06) { /* OPL2 */
136
opl3->hardware = OPL3_HW_OPL2;
137
} else {
138
/*
139
* If we had an OPL4 chip, opl3->hardware would have been set
140
* by the OPL4 driver; so we can assume OPL3 here.
141
*/
142
if (snd_BUG_ON(!opl3->r_port))
143
return -ENODEV;
144
opl3->hardware = OPL3_HW_OPL3;
145
}
146
return 0;
147
}
148
149
/*
150
* AdLib timers
151
*/
152
153
/*
154
* Timer 1 - 80us
155
*/
156
157
static int snd_opl3_timer1_start(struct snd_timer * timer)
158
{
159
unsigned long flags;
160
unsigned char tmp;
161
unsigned int ticks;
162
struct snd_opl3 *opl3;
163
164
opl3 = snd_timer_chip(timer);
165
spin_lock_irqsave(&opl3->timer_lock, flags);
166
ticks = timer->sticks;
167
tmp = (opl3->timer_enable | OPL3_TIMER1_START) & ~OPL3_TIMER1_MASK;
168
opl3->timer_enable = tmp;
169
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER1, 256 - ticks); /* timer 1 count */
170
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp); /* enable timer 1 IRQ */
171
spin_unlock_irqrestore(&opl3->timer_lock, flags);
172
return 0;
173
}
174
175
static int snd_opl3_timer1_stop(struct snd_timer * timer)
176
{
177
unsigned long flags;
178
unsigned char tmp;
179
struct snd_opl3 *opl3;
180
181
opl3 = snd_timer_chip(timer);
182
spin_lock_irqsave(&opl3->timer_lock, flags);
183
tmp = (opl3->timer_enable | OPL3_TIMER1_MASK) & ~OPL3_TIMER1_START;
184
opl3->timer_enable = tmp;
185
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp); /* disable timer #1 */
186
spin_unlock_irqrestore(&opl3->timer_lock, flags);
187
return 0;
188
}
189
190
/*
191
* Timer 2 - 320us
192
*/
193
194
static int snd_opl3_timer2_start(struct snd_timer * timer)
195
{
196
unsigned long flags;
197
unsigned char tmp;
198
unsigned int ticks;
199
struct snd_opl3 *opl3;
200
201
opl3 = snd_timer_chip(timer);
202
spin_lock_irqsave(&opl3->timer_lock, flags);
203
ticks = timer->sticks;
204
tmp = (opl3->timer_enable | OPL3_TIMER2_START) & ~OPL3_TIMER2_MASK;
205
opl3->timer_enable = tmp;
206
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER2, 256 - ticks); /* timer 1 count */
207
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp); /* enable timer 1 IRQ */
208
spin_unlock_irqrestore(&opl3->timer_lock, flags);
209
return 0;
210
}
211
212
static int snd_opl3_timer2_stop(struct snd_timer * timer)
213
{
214
unsigned long flags;
215
unsigned char tmp;
216
struct snd_opl3 *opl3;
217
218
opl3 = snd_timer_chip(timer);
219
spin_lock_irqsave(&opl3->timer_lock, flags);
220
tmp = (opl3->timer_enable | OPL3_TIMER2_MASK) & ~OPL3_TIMER2_START;
221
opl3->timer_enable = tmp;
222
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp); /* disable timer #1 */
223
spin_unlock_irqrestore(&opl3->timer_lock, flags);
224
return 0;
225
}
226
227
/*
228
229
*/
230
231
static struct snd_timer_hardware snd_opl3_timer1 =
232
{
233
.flags = SNDRV_TIMER_HW_STOP,
234
.resolution = 80000,
235
.ticks = 256,
236
.start = snd_opl3_timer1_start,
237
.stop = snd_opl3_timer1_stop,
238
};
239
240
static struct snd_timer_hardware snd_opl3_timer2 =
241
{
242
.flags = SNDRV_TIMER_HW_STOP,
243
.resolution = 320000,
244
.ticks = 256,
245
.start = snd_opl3_timer2_start,
246
.stop = snd_opl3_timer2_stop,
247
};
248
249
static int snd_opl3_timer1_init(struct snd_opl3 * opl3, int timer_no)
250
{
251
struct snd_timer *timer = NULL;
252
struct snd_timer_id tid;
253
int err;
254
255
tid.dev_class = SNDRV_TIMER_CLASS_CARD;
256
tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
257
tid.card = opl3->card->number;
258
tid.device = timer_no;
259
tid.subdevice = 0;
260
if ((err = snd_timer_new(opl3->card, "AdLib timer #1", &tid, &timer)) >= 0) {
261
strcpy(timer->name, "AdLib timer #1");
262
timer->private_data = opl3;
263
timer->hw = snd_opl3_timer1;
264
}
265
opl3->timer1 = timer;
266
return err;
267
}
268
269
static int snd_opl3_timer2_init(struct snd_opl3 * opl3, int timer_no)
270
{
271
struct snd_timer *timer = NULL;
272
struct snd_timer_id tid;
273
int err;
274
275
tid.dev_class = SNDRV_TIMER_CLASS_CARD;
276
tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
277
tid.card = opl3->card->number;
278
tid.device = timer_no;
279
tid.subdevice = 0;
280
if ((err = snd_timer_new(opl3->card, "AdLib timer #2", &tid, &timer)) >= 0) {
281
strcpy(timer->name, "AdLib timer #2");
282
timer->private_data = opl3;
283
timer->hw = snd_opl3_timer2;
284
}
285
opl3->timer2 = timer;
286
return err;
287
}
288
289
/*
290
291
*/
292
293
void snd_opl3_interrupt(struct snd_hwdep * hw)
294
{
295
unsigned char status;
296
struct snd_opl3 *opl3;
297
struct snd_timer *timer;
298
299
if (hw == NULL)
300
return;
301
302
opl3 = hw->private_data;
303
status = inb(opl3->l_port);
304
#if 0
305
snd_printk(KERN_DEBUG "AdLib IRQ status = 0x%x\n", status);
306
#endif
307
if (!(status & 0x80))
308
return;
309
310
if (status & 0x40) {
311
timer = opl3->timer1;
312
snd_timer_interrupt(timer, timer->sticks);
313
}
314
if (status & 0x20) {
315
timer = opl3->timer2;
316
snd_timer_interrupt(timer, timer->sticks);
317
}
318
}
319
320
EXPORT_SYMBOL(snd_opl3_interrupt);
321
322
/*
323
324
*/
325
326
static int snd_opl3_free(struct snd_opl3 *opl3)
327
{
328
if (snd_BUG_ON(!opl3))
329
return -ENXIO;
330
if (opl3->private_free)
331
opl3->private_free(opl3);
332
snd_opl3_clear_patches(opl3);
333
release_and_free_resource(opl3->res_l_port);
334
release_and_free_resource(opl3->res_r_port);
335
kfree(opl3);
336
return 0;
337
}
338
339
static int snd_opl3_dev_free(struct snd_device *device)
340
{
341
struct snd_opl3 *opl3 = device->device_data;
342
return snd_opl3_free(opl3);
343
}
344
345
int snd_opl3_new(struct snd_card *card,
346
unsigned short hardware,
347
struct snd_opl3 **ropl3)
348
{
349
static struct snd_device_ops ops = {
350
.dev_free = snd_opl3_dev_free,
351
};
352
struct snd_opl3 *opl3;
353
int err;
354
355
*ropl3 = NULL;
356
opl3 = kzalloc(sizeof(*opl3), GFP_KERNEL);
357
if (opl3 == NULL) {
358
snd_printk(KERN_ERR "opl3: cannot allocate\n");
359
return -ENOMEM;
360
}
361
362
opl3->card = card;
363
opl3->hardware = hardware;
364
spin_lock_init(&opl3->reg_lock);
365
spin_lock_init(&opl3->timer_lock);
366
367
if ((err = snd_device_new(card, SNDRV_DEV_CODEC, opl3, &ops)) < 0) {
368
snd_opl3_free(opl3);
369
return err;
370
}
371
372
*ropl3 = opl3;
373
return 0;
374
}
375
376
EXPORT_SYMBOL(snd_opl3_new);
377
378
int snd_opl3_init(struct snd_opl3 *opl3)
379
{
380
if (! opl3->command) {
381
printk(KERN_ERR "snd_opl3_init: command not defined!\n");
382
return -EINVAL;
383
}
384
385
opl3->command(opl3, OPL3_LEFT | OPL3_REG_TEST, OPL3_ENABLE_WAVE_SELECT);
386
/* Melodic mode */
387
opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 0x00);
388
389
switch (opl3->hardware & OPL3_HW_MASK) {
390
case OPL3_HW_OPL2:
391
opl3->max_voices = MAX_OPL2_VOICES;
392
break;
393
case OPL3_HW_OPL3:
394
case OPL3_HW_OPL4:
395
opl3->max_voices = MAX_OPL3_VOICES;
396
/* Enter OPL3 mode */
397
opl3->command(opl3, OPL3_RIGHT | OPL3_REG_MODE, OPL3_OPL3_ENABLE);
398
}
399
return 0;
400
}
401
402
EXPORT_SYMBOL(snd_opl3_init);
403
404
int snd_opl3_create(struct snd_card *card,
405
unsigned long l_port,
406
unsigned long r_port,
407
unsigned short hardware,
408
int integrated,
409
struct snd_opl3 ** ropl3)
410
{
411
struct snd_opl3 *opl3;
412
int err;
413
414
*ropl3 = NULL;
415
if ((err = snd_opl3_new(card, hardware, &opl3)) < 0)
416
return err;
417
if (! integrated) {
418
if ((opl3->res_l_port = request_region(l_port, 2, "OPL2/3 (left)")) == NULL) {
419
snd_printk(KERN_ERR "opl3: can't grab left port 0x%lx\n", l_port);
420
snd_device_free(card, opl3);
421
return -EBUSY;
422
}
423
if (r_port != 0 &&
424
(opl3->res_r_port = request_region(r_port, 2, "OPL2/3 (right)")) == NULL) {
425
snd_printk(KERN_ERR "opl3: can't grab right port 0x%lx\n", r_port);
426
snd_device_free(card, opl3);
427
return -EBUSY;
428
}
429
}
430
opl3->l_port = l_port;
431
opl3->r_port = r_port;
432
433
switch (opl3->hardware) {
434
/* some hardware doesn't support timers */
435
case OPL3_HW_OPL3_SV:
436
case OPL3_HW_OPL3_CS:
437
case OPL3_HW_OPL3_FM801:
438
opl3->command = &snd_opl3_command;
439
break;
440
default:
441
opl3->command = &snd_opl2_command;
442
if ((err = snd_opl3_detect(opl3)) < 0) {
443
snd_printd("OPL2/3 chip not detected at 0x%lx/0x%lx\n",
444
opl3->l_port, opl3->r_port);
445
snd_device_free(card, opl3);
446
return err;
447
}
448
/* detect routine returns correct hardware type */
449
switch (opl3->hardware & OPL3_HW_MASK) {
450
case OPL3_HW_OPL3:
451
case OPL3_HW_OPL4:
452
opl3->command = &snd_opl3_command;
453
}
454
}
455
456
snd_opl3_init(opl3);
457
458
*ropl3 = opl3;
459
return 0;
460
}
461
462
EXPORT_SYMBOL(snd_opl3_create);
463
464
int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev)
465
{
466
int err;
467
468
if (timer1_dev >= 0)
469
if ((err = snd_opl3_timer1_init(opl3, timer1_dev)) < 0)
470
return err;
471
if (timer2_dev >= 0) {
472
if ((err = snd_opl3_timer2_init(opl3, timer2_dev)) < 0) {
473
snd_device_free(opl3->card, opl3->timer1);
474
opl3->timer1 = NULL;
475
return err;
476
}
477
}
478
return 0;
479
}
480
481
EXPORT_SYMBOL(snd_opl3_timer_new);
482
483
int snd_opl3_hwdep_new(struct snd_opl3 * opl3,
484
int device, int seq_device,
485
struct snd_hwdep ** rhwdep)
486
{
487
struct snd_hwdep *hw;
488
struct snd_card *card = opl3->card;
489
int err;
490
491
if (rhwdep)
492
*rhwdep = NULL;
493
494
/* create hardware dependent device (direct FM) */
495
496
if ((err = snd_hwdep_new(card, "OPL2/OPL3", device, &hw)) < 0) {
497
snd_device_free(card, opl3);
498
return err;
499
}
500
hw->private_data = opl3;
501
hw->exclusive = 1;
502
#ifdef CONFIG_SND_OSSEMUL
503
if (device == 0) {
504
hw->oss_type = SNDRV_OSS_DEVICE_TYPE_DMFM;
505
sprintf(hw->oss_dev, "dmfm%i", card->number);
506
}
507
#endif
508
strcpy(hw->name, hw->id);
509
switch (opl3->hardware & OPL3_HW_MASK) {
510
case OPL3_HW_OPL2:
511
strcpy(hw->name, "OPL2 FM");
512
hw->iface = SNDRV_HWDEP_IFACE_OPL2;
513
break;
514
case OPL3_HW_OPL3:
515
strcpy(hw->name, "OPL3 FM");
516
hw->iface = SNDRV_HWDEP_IFACE_OPL3;
517
break;
518
case OPL3_HW_OPL4:
519
strcpy(hw->name, "OPL4 FM");
520
hw->iface = SNDRV_HWDEP_IFACE_OPL4;
521
break;
522
}
523
524
/* operators - only ioctl */
525
hw->ops.open = snd_opl3_open;
526
hw->ops.ioctl = snd_opl3_ioctl;
527
hw->ops.write = snd_opl3_write;
528
hw->ops.release = snd_opl3_release;
529
530
opl3->hwdep = hw;
531
opl3->seq_dev_num = seq_device;
532
#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
533
if (snd_seq_device_new(card, seq_device, SNDRV_SEQ_DEV_ID_OPL3,
534
sizeof(struct snd_opl3 *), &opl3->seq_dev) >= 0) {
535
strcpy(opl3->seq_dev->name, hw->name);
536
*(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(opl3->seq_dev) = opl3;
537
}
538
#endif
539
if (rhwdep)
540
*rhwdep = hw;
541
return 0;
542
}
543
544
EXPORT_SYMBOL(snd_opl3_hwdep_new);
545
546
/*
547
* INIT part
548
*/
549
550
static int __init alsa_opl3_init(void)
551
{
552
return 0;
553
}
554
555
static void __exit alsa_opl3_exit(void)
556
{
557
}
558
559
module_init(alsa_opl3_init)
560
module_exit(alsa_opl3_exit)
561
562