Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
0004  *                   Hannu Savolainen 1993-1996,
0005  *                   Rob Hooft
0006  *                   
0007  *  Routines for control of AdLib FM cards (OPL2/OPL3/OPL4 chips)
0008  *
0009  *  Most if code is ported from OSS/Lite.
0010  */
0011 
0012 #include <sound/opl3.h>
0013 #include <linux/io.h>
0014 #include <linux/delay.h>
0015 #include <linux/module.h>
0016 #include <linux/init.h>
0017 #include <linux/slab.h>
0018 #include <linux/ioport.h>
0019 #include <sound/minors.h>
0020 #include "opl3_voice.h"
0021 
0022 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Hannu Savolainen 1993-1996, Rob Hooft");
0023 MODULE_DESCRIPTION("Routines for control of AdLib FM cards (OPL2/OPL3/OPL4 chips)");
0024 MODULE_LICENSE("GPL");
0025 
0026 static void snd_opl2_command(struct snd_opl3 * opl3, unsigned short cmd, unsigned char val)
0027 {
0028     unsigned long flags;
0029     unsigned long port;
0030 
0031     /*
0032      * The original 2-OP synth requires a quite long delay
0033      * after writing to a register.
0034      */
0035 
0036     port = (cmd & OPL3_RIGHT) ? opl3->r_port : opl3->l_port;
0037 
0038     spin_lock_irqsave(&opl3->reg_lock, flags);
0039 
0040     outb((unsigned char) cmd, port);
0041     udelay(10);
0042 
0043     outb((unsigned char) val, port + 1);
0044     udelay(30);
0045 
0046     spin_unlock_irqrestore(&opl3->reg_lock, flags);
0047 }
0048 
0049 static void snd_opl3_command(struct snd_opl3 * opl3, unsigned short cmd, unsigned char val)
0050 {
0051     unsigned long flags;
0052     unsigned long port;
0053 
0054     /*
0055      * The OPL-3 survives with just two INBs
0056      * after writing to a register.
0057      */
0058 
0059     port = (cmd & OPL3_RIGHT) ? opl3->r_port : opl3->l_port;
0060 
0061     spin_lock_irqsave(&opl3->reg_lock, flags);
0062 
0063     outb((unsigned char) cmd, port);
0064     inb(opl3->l_port);
0065     inb(opl3->l_port);
0066 
0067     outb((unsigned char) val, port + 1);
0068     inb(opl3->l_port);
0069     inb(opl3->l_port);
0070 
0071     spin_unlock_irqrestore(&opl3->reg_lock, flags);
0072 }
0073 
0074 static int snd_opl3_detect(struct snd_opl3 * opl3)
0075 {
0076     /*
0077      * This function returns 1 if the FM chip is present at the given I/O port
0078      * The detection algorithm plays with the timer built in the FM chip and
0079      * looks for a change in the status register.
0080      *
0081      * Note! The timers of the FM chip are not connected to AdLib (and compatible)
0082      * boards.
0083      *
0084      * Note2! The chip is initialized if detected.
0085      */
0086 
0087     unsigned char stat1, stat2, signature;
0088 
0089     /* Reset timers 1 and 2 */
0090     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER1_MASK | OPL3_TIMER2_MASK);
0091     /* Reset the IRQ of the FM chip */
0092     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_IRQ_RESET);
0093     signature = stat1 = inb(opl3->l_port);  /* Status register */
0094     if ((stat1 & 0xe0) != 0x00) {   /* Should be 0x00 */
0095         snd_printd("OPL3: stat1 = 0x%x\n", stat1);
0096         return -ENODEV;
0097     }
0098     /* Set timer1 to 0xff */
0099     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER1, 0xff);
0100     /* Unmask and start timer 1 */
0101     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER2_MASK | OPL3_TIMER1_START);
0102     /* Now we have to delay at least 80us */
0103     udelay(200);
0104     /* Read status after timers have expired */
0105     stat2 = inb(opl3->l_port);
0106     /* Stop the timers */
0107     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_TIMER1_MASK | OPL3_TIMER2_MASK);
0108     /* Reset the IRQ of the FM chip */
0109     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, OPL3_IRQ_RESET);
0110     if ((stat2 & 0xe0) != 0xc0) {   /* There is no YM3812 */
0111         snd_printd("OPL3: stat2 = 0x%x\n", stat2);
0112         return -ENODEV;
0113     }
0114 
0115     /* If the toplevel code knows exactly the type of chip, don't try
0116        to detect it. */
0117     if (opl3->hardware != OPL3_HW_AUTO)
0118         return 0;
0119 
0120     /* There is a FM chip on this address. Detect the type (OPL2 to OPL4) */
0121     if (signature == 0x06) {    /* OPL2 */
0122         opl3->hardware = OPL3_HW_OPL2;
0123     } else {
0124         /*
0125          * If we had an OPL4 chip, opl3->hardware would have been set
0126          * by the OPL4 driver; so we can assume OPL3 here.
0127          */
0128         if (snd_BUG_ON(!opl3->r_port))
0129             return -ENODEV;
0130         opl3->hardware = OPL3_HW_OPL3;
0131     }
0132     return 0;
0133 }
0134 
0135 /*
0136  *  AdLib timers
0137  */
0138 
0139 /*
0140  *  Timer 1 - 80us
0141  */
0142 
0143 static int snd_opl3_timer1_start(struct snd_timer * timer)
0144 {
0145     unsigned long flags;
0146     unsigned char tmp;
0147     unsigned int ticks;
0148     struct snd_opl3 *opl3;
0149 
0150     opl3 = snd_timer_chip(timer);
0151     spin_lock_irqsave(&opl3->timer_lock, flags);
0152     ticks = timer->sticks;
0153     tmp = (opl3->timer_enable | OPL3_TIMER1_START) & ~OPL3_TIMER1_MASK;
0154     opl3->timer_enable = tmp;
0155     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER1, 256 - ticks);  /* timer 1 count */
0156     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);   /* enable timer 1 IRQ */
0157     spin_unlock_irqrestore(&opl3->timer_lock, flags);
0158     return 0;
0159 }
0160 
0161 static int snd_opl3_timer1_stop(struct snd_timer * timer)
0162 {
0163     unsigned long flags;
0164     unsigned char tmp;
0165     struct snd_opl3 *opl3;
0166 
0167     opl3 = snd_timer_chip(timer);
0168     spin_lock_irqsave(&opl3->timer_lock, flags);
0169     tmp = (opl3->timer_enable | OPL3_TIMER1_MASK) & ~OPL3_TIMER1_START;
0170     opl3->timer_enable = tmp;
0171     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);   /* disable timer #1 */
0172     spin_unlock_irqrestore(&opl3->timer_lock, flags);
0173     return 0;
0174 }
0175 
0176 /*
0177  *  Timer 2 - 320us
0178  */
0179 
0180 static int snd_opl3_timer2_start(struct snd_timer * timer)
0181 {
0182     unsigned long flags;
0183     unsigned char tmp;
0184     unsigned int ticks;
0185     struct snd_opl3 *opl3;
0186 
0187     opl3 = snd_timer_chip(timer);
0188     spin_lock_irqsave(&opl3->timer_lock, flags);
0189     ticks = timer->sticks;
0190     tmp = (opl3->timer_enable | OPL3_TIMER2_START) & ~OPL3_TIMER2_MASK;
0191     opl3->timer_enable = tmp;
0192     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER2, 256 - ticks);  /* timer 1 count */
0193     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);   /* enable timer 1 IRQ */
0194     spin_unlock_irqrestore(&opl3->timer_lock, flags);
0195     return 0;
0196 }
0197 
0198 static int snd_opl3_timer2_stop(struct snd_timer * timer)
0199 {
0200     unsigned long flags;
0201     unsigned char tmp;
0202     struct snd_opl3 *opl3;
0203 
0204     opl3 = snd_timer_chip(timer);
0205     spin_lock_irqsave(&opl3->timer_lock, flags);
0206     tmp = (opl3->timer_enable | OPL3_TIMER2_MASK) & ~OPL3_TIMER2_START;
0207     opl3->timer_enable = tmp;
0208     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);   /* disable timer #1 */
0209     spin_unlock_irqrestore(&opl3->timer_lock, flags);
0210     return 0;
0211 }
0212 
0213 /*
0214 
0215  */
0216 
0217 static const struct snd_timer_hardware snd_opl3_timer1 =
0218 {
0219     .flags =    SNDRV_TIMER_HW_STOP,
0220     .resolution =   80000,
0221     .ticks =    256,
0222     .start =    snd_opl3_timer1_start,
0223     .stop =     snd_opl3_timer1_stop,
0224 };
0225 
0226 static const struct snd_timer_hardware snd_opl3_timer2 =
0227 {
0228     .flags =    SNDRV_TIMER_HW_STOP,
0229     .resolution =   320000,
0230     .ticks =    256,
0231     .start =    snd_opl3_timer2_start,
0232     .stop =     snd_opl3_timer2_stop,
0233 };
0234 
0235 static int snd_opl3_timer1_init(struct snd_opl3 * opl3, int timer_no)
0236 {
0237     struct snd_timer *timer = NULL;
0238     struct snd_timer_id tid;
0239     int err;
0240 
0241     tid.dev_class = SNDRV_TIMER_CLASS_CARD;
0242     tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
0243     tid.card = opl3->card->number;
0244     tid.device = timer_no;
0245     tid.subdevice = 0;
0246     err = snd_timer_new(opl3->card, "AdLib timer #1", &tid, &timer);
0247     if (err >= 0) {
0248         strcpy(timer->name, "AdLib timer #1");
0249         timer->private_data = opl3;
0250         timer->hw = snd_opl3_timer1;
0251     }
0252     opl3->timer1 = timer;
0253     return err;
0254 }
0255 
0256 static int snd_opl3_timer2_init(struct snd_opl3 * opl3, int timer_no)
0257 {
0258     struct snd_timer *timer = NULL;
0259     struct snd_timer_id tid;
0260     int err;
0261 
0262     tid.dev_class = SNDRV_TIMER_CLASS_CARD;
0263     tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
0264     tid.card = opl3->card->number;
0265     tid.device = timer_no;
0266     tid.subdevice = 0;
0267     err = snd_timer_new(opl3->card, "AdLib timer #2", &tid, &timer);
0268     if (err >= 0) {
0269         strcpy(timer->name, "AdLib timer #2");
0270         timer->private_data = opl3;
0271         timer->hw = snd_opl3_timer2;
0272     }
0273     opl3->timer2 = timer;
0274     return err;
0275 }
0276 
0277 /*
0278 
0279  */
0280 
0281 void snd_opl3_interrupt(struct snd_hwdep * hw)
0282 {
0283     unsigned char status;
0284     struct snd_opl3 *opl3;
0285     struct snd_timer *timer;
0286 
0287     if (hw == NULL)
0288         return;
0289 
0290     opl3 = hw->private_data;
0291     status = inb(opl3->l_port);
0292 #if 0
0293     snd_printk(KERN_DEBUG "AdLib IRQ status = 0x%x\n", status);
0294 #endif
0295     if (!(status & 0x80))
0296         return;
0297 
0298     if (status & 0x40) {
0299         timer = opl3->timer1;
0300         snd_timer_interrupt(timer, timer->sticks);
0301     }
0302     if (status & 0x20) {
0303         timer = opl3->timer2;
0304         snd_timer_interrupt(timer, timer->sticks);
0305     }
0306 }
0307 
0308 EXPORT_SYMBOL(snd_opl3_interrupt);
0309 
0310 /*
0311 
0312  */
0313 
0314 static int snd_opl3_free(struct snd_opl3 *opl3)
0315 {
0316     if (snd_BUG_ON(!opl3))
0317         return -ENXIO;
0318     if (opl3->private_free)
0319         opl3->private_free(opl3);
0320     snd_opl3_clear_patches(opl3);
0321     release_and_free_resource(opl3->res_l_port);
0322     release_and_free_resource(opl3->res_r_port);
0323     kfree(opl3);
0324     return 0;
0325 }
0326 
0327 static int snd_opl3_dev_free(struct snd_device *device)
0328 {
0329     struct snd_opl3 *opl3 = device->device_data;
0330     return snd_opl3_free(opl3);
0331 }
0332 
0333 int snd_opl3_new(struct snd_card *card,
0334          unsigned short hardware,
0335          struct snd_opl3 **ropl3)
0336 {
0337     static const struct snd_device_ops ops = {
0338         .dev_free = snd_opl3_dev_free,
0339     };
0340     struct snd_opl3 *opl3;
0341     int err;
0342 
0343     *ropl3 = NULL;
0344     opl3 = kzalloc(sizeof(*opl3), GFP_KERNEL);
0345     if (!opl3)
0346         return -ENOMEM;
0347 
0348     opl3->card = card;
0349     opl3->hardware = hardware;
0350     spin_lock_init(&opl3->reg_lock);
0351     spin_lock_init(&opl3->timer_lock);
0352 
0353     err = snd_device_new(card, SNDRV_DEV_CODEC, opl3, &ops);
0354     if (err < 0) {
0355         snd_opl3_free(opl3);
0356         return err;
0357     }
0358 
0359     *ropl3 = opl3;
0360     return 0;
0361 }
0362 
0363 EXPORT_SYMBOL(snd_opl3_new);
0364 
0365 int snd_opl3_init(struct snd_opl3 *opl3)
0366 {
0367     if (! opl3->command) {
0368         printk(KERN_ERR "snd_opl3_init: command not defined!\n");
0369         return -EINVAL;
0370     }
0371 
0372     opl3->command(opl3, OPL3_LEFT | OPL3_REG_TEST, OPL3_ENABLE_WAVE_SELECT);
0373     /* Melodic mode */
0374     opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 0x00);
0375 
0376     switch (opl3->hardware & OPL3_HW_MASK) {
0377     case OPL3_HW_OPL2:
0378         opl3->max_voices = MAX_OPL2_VOICES;
0379         break;
0380     case OPL3_HW_OPL3:
0381     case OPL3_HW_OPL4:
0382         opl3->max_voices = MAX_OPL3_VOICES;
0383         /* Enter OPL3 mode */
0384         opl3->command(opl3, OPL3_RIGHT | OPL3_REG_MODE, OPL3_OPL3_ENABLE);
0385     }
0386     return 0;
0387 }
0388 
0389 EXPORT_SYMBOL(snd_opl3_init);
0390 
0391 int snd_opl3_create(struct snd_card *card,
0392             unsigned long l_port,
0393             unsigned long r_port,
0394             unsigned short hardware,
0395             int integrated,
0396             struct snd_opl3 ** ropl3)
0397 {
0398     struct snd_opl3 *opl3;
0399     int err;
0400 
0401     *ropl3 = NULL;
0402     err = snd_opl3_new(card, hardware, &opl3);
0403     if (err < 0)
0404         return err;
0405     if (! integrated) {
0406         opl3->res_l_port = request_region(l_port, 2, "OPL2/3 (left)");
0407         if (!opl3->res_l_port) {
0408             snd_printk(KERN_ERR "opl3: can't grab left port 0x%lx\n", l_port);
0409             snd_device_free(card, opl3);
0410             return -EBUSY;
0411         }
0412         if (r_port != 0) {
0413             opl3->res_r_port = request_region(r_port, 2, "OPL2/3 (right)");
0414             if (!opl3->res_r_port) {
0415                 snd_printk(KERN_ERR "opl3: can't grab right port 0x%lx\n", r_port);
0416                 snd_device_free(card, opl3);
0417                 return -EBUSY;
0418             }
0419         }
0420     }
0421     opl3->l_port = l_port;
0422     opl3->r_port = r_port;
0423 
0424     switch (opl3->hardware) {
0425     /* some hardware doesn't support timers */
0426     case OPL3_HW_OPL3_SV:
0427     case OPL3_HW_OPL3_CS:
0428     case OPL3_HW_OPL3_FM801:
0429         opl3->command = &snd_opl3_command;
0430         break;
0431     default:
0432         opl3->command = &snd_opl2_command;
0433         err = snd_opl3_detect(opl3);
0434         if (err < 0) {
0435             snd_printd("OPL2/3 chip not detected at 0x%lx/0x%lx\n",
0436                    opl3->l_port, opl3->r_port);
0437             snd_device_free(card, opl3);
0438             return err;
0439         }
0440         /* detect routine returns correct hardware type */
0441         switch (opl3->hardware & OPL3_HW_MASK) {
0442         case OPL3_HW_OPL3:
0443         case OPL3_HW_OPL4:
0444             opl3->command = &snd_opl3_command;
0445         }
0446     }
0447 
0448     snd_opl3_init(opl3);
0449 
0450     *ropl3 = opl3;
0451     return 0;
0452 }
0453 
0454 EXPORT_SYMBOL(snd_opl3_create);
0455 
0456 int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev)
0457 {
0458     int err;
0459 
0460     if (timer1_dev >= 0) {
0461         err = snd_opl3_timer1_init(opl3, timer1_dev);
0462         if (err < 0)
0463             return err;
0464     }
0465     if (timer2_dev >= 0) {
0466         err = snd_opl3_timer2_init(opl3, timer2_dev);
0467         if (err < 0) {
0468             snd_device_free(opl3->card, opl3->timer1);
0469             opl3->timer1 = NULL;
0470             return err;
0471         }
0472     }
0473     return 0;
0474 }
0475 
0476 EXPORT_SYMBOL(snd_opl3_timer_new);
0477 
0478 int snd_opl3_hwdep_new(struct snd_opl3 * opl3,
0479                int device, int seq_device,
0480                struct snd_hwdep ** rhwdep)
0481 {
0482     struct snd_hwdep *hw;
0483     struct snd_card *card = opl3->card;
0484     int err;
0485 
0486     if (rhwdep)
0487         *rhwdep = NULL;
0488 
0489     /* create hardware dependent device (direct FM) */
0490 
0491     err = snd_hwdep_new(card, "OPL2/OPL3", device, &hw);
0492     if (err < 0) {
0493         snd_device_free(card, opl3);
0494         return err;
0495     }
0496     hw->private_data = opl3;
0497     hw->exclusive = 1;
0498 #ifdef CONFIG_SND_OSSEMUL
0499     if (device == 0)
0500         hw->oss_type = SNDRV_OSS_DEVICE_TYPE_DMFM;
0501 #endif
0502     strcpy(hw->name, hw->id);
0503     switch (opl3->hardware & OPL3_HW_MASK) {
0504     case OPL3_HW_OPL2:
0505         strcpy(hw->name, "OPL2 FM");
0506         hw->iface = SNDRV_HWDEP_IFACE_OPL2;
0507         break;
0508     case OPL3_HW_OPL3:
0509         strcpy(hw->name, "OPL3 FM");
0510         hw->iface = SNDRV_HWDEP_IFACE_OPL3;
0511         break;
0512     case OPL3_HW_OPL4:
0513         strcpy(hw->name, "OPL4 FM");
0514         hw->iface = SNDRV_HWDEP_IFACE_OPL4;
0515         break;
0516     }
0517 
0518     /* operators - only ioctl */
0519     hw->ops.open = snd_opl3_open;
0520     hw->ops.ioctl = snd_opl3_ioctl;
0521     hw->ops.write = snd_opl3_write;
0522     hw->ops.release = snd_opl3_release;
0523 
0524     opl3->hwdep = hw;
0525     opl3->seq_dev_num = seq_device;
0526 #if IS_ENABLED(CONFIG_SND_SEQUENCER)
0527     if (snd_seq_device_new(card, seq_device, SNDRV_SEQ_DEV_ID_OPL3,
0528                    sizeof(struct snd_opl3 *), &opl3->seq_dev) >= 0) {
0529         strcpy(opl3->seq_dev->name, hw->name);
0530         *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(opl3->seq_dev) = opl3;
0531     }
0532 #endif
0533     if (rhwdep)
0534         *rhwdep = hw;
0535     return 0;
0536 }
0537 
0538 EXPORT_SYMBOL(snd_opl3_hwdep_new);