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