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)
 359                return -ENOMEM;
 360
 361        opl3->card = card;
 362        opl3->hardware = hardware;
 363        spin_lock_init(&opl3->reg_lock);
 364        spin_lock_init(&opl3->timer_lock);
 365
 366        if ((err = snd_device_new(card, SNDRV_DEV_CODEC, opl3, &ops)) < 0) {
 367                snd_opl3_free(opl3);
 368                return err;
 369        }
 370
 371        *ropl3 = opl3;
 372        return 0;
 373}
 374
 375EXPORT_SYMBOL(snd_opl3_new);
 376
 377int snd_opl3_init(struct snd_opl3 *opl3)
 378{
 379        if (! opl3->command) {
 380                printk(KERN_ERR "snd_opl3_init: command not defined!\n");
 381                return -EINVAL;
 382        }
 383
 384        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TEST, OPL3_ENABLE_WAVE_SELECT);
 385        /* Melodic mode */
 386        opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 0x00);
 387
 388        switch (opl3->hardware & OPL3_HW_MASK) {
 389        case OPL3_HW_OPL2:
 390                opl3->max_voices = MAX_OPL2_VOICES;
 391                break;
 392        case OPL3_HW_OPL3:
 393        case OPL3_HW_OPL4:
 394                opl3->max_voices = MAX_OPL3_VOICES;
 395                /* Enter OPL3 mode */
 396                opl3->command(opl3, OPL3_RIGHT | OPL3_REG_MODE, OPL3_OPL3_ENABLE);
 397        }
 398        return 0;
 399}
 400
 401EXPORT_SYMBOL(snd_opl3_init);
 402
 403int snd_opl3_create(struct snd_card *card,
 404                    unsigned long l_port,
 405                    unsigned long r_port,
 406                    unsigned short hardware,
 407                    int integrated,
 408                    struct snd_opl3 ** ropl3)
 409{
 410        struct snd_opl3 *opl3;
 411        int err;
 412
 413        *ropl3 = NULL;
 414        if ((err = snd_opl3_new(card, hardware, &opl3)) < 0)
 415                return err;
 416        if (! integrated) {
 417                if ((opl3->res_l_port = request_region(l_port, 2, "OPL2/3 (left)")) == NULL) {
 418                        snd_printk(KERN_ERR "opl3: can't grab left port 0x%lx\n", l_port);
 419                        snd_device_free(card, opl3);
 420                        return -EBUSY;
 421                }
 422                if (r_port != 0 &&
 423                    (opl3->res_r_port = request_region(r_port, 2, "OPL2/3 (right)")) == NULL) {
 424                        snd_printk(KERN_ERR "opl3: can't grab right port 0x%lx\n", r_port);
 425                        snd_device_free(card, opl3);
 426                        return -EBUSY;
 427                }
 428        }
 429        opl3->l_port = l_port;
 430        opl3->r_port = r_port;
 431
 432        switch (opl3->hardware) {
 433        /* some hardware doesn't support timers */
 434        case OPL3_HW_OPL3_SV:
 435        case OPL3_HW_OPL3_CS:
 436        case OPL3_HW_OPL3_FM801:
 437                opl3->command = &snd_opl3_command;
 438                break;
 439        default:
 440                opl3->command = &snd_opl2_command;
 441                if ((err = snd_opl3_detect(opl3)) < 0) {
 442                        snd_printd("OPL2/3 chip not detected at 0x%lx/0x%lx\n",
 443                                   opl3->l_port, opl3->r_port);
 444                        snd_device_free(card, opl3);
 445                        return err;
 446                }
 447                /* detect routine returns correct hardware type */
 448                switch (opl3->hardware & OPL3_HW_MASK) {
 449                case OPL3_HW_OPL3:
 450                case OPL3_HW_OPL4:
 451                        opl3->command = &snd_opl3_command;
 452                }
 453        }
 454
 455        snd_opl3_init(opl3);
 456
 457        *ropl3 = opl3;
 458        return 0;
 459}
 460
 461EXPORT_SYMBOL(snd_opl3_create);
 462
 463int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev)
 464{
 465        int err;
 466
 467        if (timer1_dev >= 0)
 468                if ((err = snd_opl3_timer1_init(opl3, timer1_dev)) < 0)
 469                        return err;
 470        if (timer2_dev >= 0) {
 471                if ((err = snd_opl3_timer2_init(opl3, timer2_dev)) < 0) {
 472                        snd_device_free(opl3->card, opl3->timer1);
 473                        opl3->timer1 = NULL;
 474                        return err;
 475                }
 476        }
 477        return 0;
 478}
 479
 480EXPORT_SYMBOL(snd_opl3_timer_new);
 481
 482int snd_opl3_hwdep_new(struct snd_opl3 * opl3,
 483                       int device, int seq_device,
 484                       struct snd_hwdep ** rhwdep)
 485{
 486        struct snd_hwdep *hw;
 487        struct snd_card *card = opl3->card;
 488        int err;
 489
 490        if (rhwdep)
 491                *rhwdep = NULL;
 492
 493        /* create hardware dependent device (direct FM) */
 494
 495        if ((err = snd_hwdep_new(card, "OPL2/OPL3", device, &hw)) < 0) {
 496                snd_device_free(card, opl3);
 497                return err;
 498        }
 499        hw->private_data = opl3;
 500        hw->exclusive = 1;
 501#ifdef CONFIG_SND_OSSEMUL
 502        if (device == 0)
 503                hw->oss_type = SNDRV_OSS_DEVICE_TYPE_DMFM;
 504#endif
 505        strcpy(hw->name, hw->id);
 506        switch (opl3->hardware & OPL3_HW_MASK) {
 507        case OPL3_HW_OPL2:
 508                strcpy(hw->name, "OPL2 FM");
 509                hw->iface = SNDRV_HWDEP_IFACE_OPL2;
 510                break;
 511        case OPL3_HW_OPL3:
 512                strcpy(hw->name, "OPL3 FM");
 513                hw->iface = SNDRV_HWDEP_IFACE_OPL3;
 514                break;
 515        case OPL3_HW_OPL4:
 516                strcpy(hw->name, "OPL4 FM");
 517                hw->iface = SNDRV_HWDEP_IFACE_OPL4;
 518                break;
 519        }
 520
 521        /* operators - only ioctl */
 522        hw->ops.open = snd_opl3_open;
 523        hw->ops.ioctl = snd_opl3_ioctl;
 524        hw->ops.write = snd_opl3_write;
 525        hw->ops.release = snd_opl3_release;
 526
 527        opl3->hwdep = hw;
 528        opl3->seq_dev_num = seq_device;
 529#if IS_ENABLED(CONFIG_SND_SEQUENCER)
 530        if (snd_seq_device_new(card, seq_device, SNDRV_SEQ_DEV_ID_OPL3,
 531                               sizeof(struct snd_opl3 *), &opl3->seq_dev) >= 0) {
 532                strcpy(opl3->seq_dev->name, hw->name);
 533                *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(opl3->seq_dev) = opl3;
 534        }
 535#endif
 536        if (rhwdep)
 537                *rhwdep = hw;
 538        return 0;
 539}
 540
 541EXPORT_SYMBOL(snd_opl3_hwdep_new);
 542
 543/*
 544 *  INIT part
 545 */
 546
 547static int __init alsa_opl3_init(void)
 548{
 549        return 0;
 550}
 551
 552static void __exit alsa_opl3_exit(void)
 553{
 554}
 555
 556module_init(alsa_opl3_init)
 557module_exit(alsa_opl3_exit)
 558