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