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 <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
  34MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Hannu Savolainen 1993-1996, Rob Hooft");
  35MODULE_DESCRIPTION("Routines for control of AdLib FM cards (OPL2/OPL3/OPL4 chips)");
  36MODULE_LICENSE("GPL");
  37
  38extern char snd_opl3_regmap[MAX_OPL2_VOICES][4];
  39
  40static 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
  63static 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
  88static 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
 157static 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
 175static 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
 194static 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
 212static 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
 231static 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
 240static 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
 249static 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
 269static 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
 293void 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
 320EXPORT_SYMBOL(snd_opl3_interrupt);
 321
 322/*
 323
 324 */
 325
 326static 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
 339static 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
 345int 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
 376EXPORT_SYMBOL(snd_opl3_new);
 377
 378int 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
 402EXPORT_SYMBOL(snd_opl3_init);
 403
 404int 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
 462EXPORT_SYMBOL(snd_opl3_create);
 463
 464int 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
 481EXPORT_SYMBOL(snd_opl3_timer_new);
 482
 483int 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
 544EXPORT_SYMBOL(snd_opl3_hwdep_new);
 545
 546/*
 547 *  INIT part
 548 */
 549
 550static int __init alsa_opl3_init(void)
 551{
 552        return 0;
 553}
 554
 555static void __exit alsa_opl3_exit(void)
 556{
 557}
 558
 559module_init(alsa_opl3_init)
 560module_exit(alsa_opl3_exit)
 561