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                snd_assert(opl3->r_port != 0, return -ENODEV);
 143                opl3->hardware = OPL3_HW_OPL3;
 144        }
 145        return 0;
 146}
 147
 148/*
 149 *  AdLib timers
 150 */
 151
 152/*
 153 *  Timer 1 - 80us
 154 */
 155
 156static int snd_opl3_timer1_start(struct snd_timer * timer)
 157{
 158        unsigned long flags;
 159        unsigned char tmp;
 160        unsigned int ticks;
 161        struct snd_opl3 *opl3;
 162
 163        opl3 = snd_timer_chip(timer);
 164        spin_lock_irqsave(&opl3->timer_lock, flags);
 165        ticks = timer->sticks;
 166        tmp = (opl3->timer_enable | OPL3_TIMER1_START) & ~OPL3_TIMER1_MASK;
 167        opl3->timer_enable = tmp;
 168        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER1, 256 - ticks);  /* timer 1 count */
 169        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);   /* enable timer 1 IRQ */
 170        spin_unlock_irqrestore(&opl3->timer_lock, flags);
 171        return 0;
 172}
 173
 174static int snd_opl3_timer1_stop(struct snd_timer * timer)
 175{
 176        unsigned long flags;
 177        unsigned char tmp;
 178        struct snd_opl3 *opl3;
 179
 180        opl3 = snd_timer_chip(timer);
 181        spin_lock_irqsave(&opl3->timer_lock, flags);
 182        tmp = (opl3->timer_enable | OPL3_TIMER1_MASK) & ~OPL3_TIMER1_START;
 183        opl3->timer_enable = tmp;
 184        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);   /* disable timer #1 */
 185        spin_unlock_irqrestore(&opl3->timer_lock, flags);
 186        return 0;
 187}
 188
 189/*
 190 *  Timer 2 - 320us
 191 */
 192
 193static int snd_opl3_timer2_start(struct snd_timer * timer)
 194{
 195        unsigned long flags;
 196        unsigned char tmp;
 197        unsigned int ticks;
 198        struct snd_opl3 *opl3;
 199
 200        opl3 = snd_timer_chip(timer);
 201        spin_lock_irqsave(&opl3->timer_lock, flags);
 202        ticks = timer->sticks;
 203        tmp = (opl3->timer_enable | OPL3_TIMER2_START) & ~OPL3_TIMER2_MASK;
 204        opl3->timer_enable = tmp;
 205        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER2, 256 - ticks);  /* timer 1 count */
 206        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);   /* enable timer 1 IRQ */
 207        spin_unlock_irqrestore(&opl3->timer_lock, flags);
 208        return 0;
 209}
 210
 211static int snd_opl3_timer2_stop(struct snd_timer * timer)
 212{
 213        unsigned long flags;
 214        unsigned char tmp;
 215        struct snd_opl3 *opl3;
 216
 217        opl3 = snd_timer_chip(timer);
 218        spin_lock_irqsave(&opl3->timer_lock, flags);
 219        tmp = (opl3->timer_enable | OPL3_TIMER2_MASK) & ~OPL3_TIMER2_START;
 220        opl3->timer_enable = tmp;
 221        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TIMER_CONTROL, tmp);   /* disable timer #1 */
 222        spin_unlock_irqrestore(&opl3->timer_lock, flags);
 223        return 0;
 224}
 225
 226/*
 227
 228 */
 229
 230static struct snd_timer_hardware snd_opl3_timer1 =
 231{
 232        .flags =        SNDRV_TIMER_HW_STOP,
 233        .resolution =   80000,
 234        .ticks =        256,
 235        .start =        snd_opl3_timer1_start,
 236        .stop =         snd_opl3_timer1_stop,
 237};
 238
 239static struct snd_timer_hardware snd_opl3_timer2 =
 240{
 241        .flags =        SNDRV_TIMER_HW_STOP,
 242        .resolution =   320000,
 243        .ticks =        256,
 244        .start =        snd_opl3_timer2_start,
 245        .stop =         snd_opl3_timer2_stop,
 246};
 247
 248static int snd_opl3_timer1_init(struct snd_opl3 * opl3, int timer_no)
 249{
 250        struct snd_timer *timer = NULL;
 251        struct snd_timer_id tid;
 252        int err;
 253
 254        tid.dev_class = SNDRV_TIMER_CLASS_CARD;
 255        tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
 256        tid.card = opl3->card->number;
 257        tid.device = timer_no;
 258        tid.subdevice = 0;
 259        if ((err = snd_timer_new(opl3->card, "AdLib timer #1", &tid, &timer)) >= 0) {
 260                strcpy(timer->name, "AdLib timer #1");
 261                timer->private_data = opl3;
 262                timer->hw = snd_opl3_timer1;
 263        }
 264        opl3->timer1 = timer;
 265        return err;
 266}
 267
 268static int snd_opl3_timer2_init(struct snd_opl3 * opl3, int timer_no)
 269{
 270        struct snd_timer *timer = NULL;
 271        struct snd_timer_id tid;
 272        int err;
 273
 274        tid.dev_class = SNDRV_TIMER_CLASS_CARD;
 275        tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
 276        tid.card = opl3->card->number;
 277        tid.device = timer_no;
 278        tid.subdevice = 0;
 279        if ((err = snd_timer_new(opl3->card, "AdLib timer #2", &tid, &timer)) >= 0) {
 280                strcpy(timer->name, "AdLib timer #2");
 281                timer->private_data = opl3;
 282                timer->hw = snd_opl3_timer2;
 283        }
 284        opl3->timer2 = timer;
 285        return err;
 286}
 287
 288/*
 289
 290 */
 291
 292void snd_opl3_interrupt(struct snd_hwdep * hw)
 293{
 294        unsigned char status;
 295        struct snd_opl3 *opl3;
 296        struct snd_timer *timer;
 297
 298        if (hw == NULL)
 299                return;
 300
 301        opl3 = hw->private_data;
 302        status = inb(opl3->l_port);
 303#if 0
 304        snd_printk("AdLib IRQ status = 0x%x\n", status);
 305#endif
 306        if (!(status & 0x80))
 307                return;
 308
 309        if (status & 0x40) {
 310                timer = opl3->timer1;
 311                snd_timer_interrupt(timer, timer->sticks);
 312        }
 313        if (status & 0x20) {
 314                timer = opl3->timer2;
 315                snd_timer_interrupt(timer, timer->sticks);
 316        }
 317}
 318
 319EXPORT_SYMBOL(snd_opl3_interrupt);
 320
 321/*
 322
 323 */
 324
 325static int snd_opl3_free(struct snd_opl3 *opl3)
 326{
 327        snd_assert(opl3 != NULL, return -ENXIO);
 328        if (opl3->private_free)
 329                opl3->private_free(opl3);
 330        release_and_free_resource(opl3->res_l_port);
 331        release_and_free_resource(opl3->res_r_port);
 332        kfree(opl3);
 333        return 0;
 334}
 335
 336static int snd_opl3_dev_free(struct snd_device *device)
 337{
 338        struct snd_opl3 *opl3 = device->device_data;
 339        return snd_opl3_free(opl3);
 340}
 341
 342int snd_opl3_new(struct snd_card *card,
 343                 unsigned short hardware,
 344                 struct snd_opl3 **ropl3)
 345{
 346        static struct snd_device_ops ops = {
 347                .dev_free = snd_opl3_dev_free,
 348        };
 349        struct snd_opl3 *opl3;
 350        int err;
 351
 352        *ropl3 = NULL;
 353        opl3 = kzalloc(sizeof(*opl3), GFP_KERNEL);
 354        if (opl3 == NULL) {
 355                snd_printk(KERN_ERR "opl3: cannot allocate\n");
 356                return -ENOMEM;
 357        }
 358
 359        opl3->card = card;
 360        opl3->hardware = hardware;
 361        spin_lock_init(&opl3->reg_lock);
 362        spin_lock_init(&opl3->timer_lock);
 363        mutex_init(&opl3->access_mutex);
 364
 365        if ((err = snd_device_new(card, SNDRV_DEV_CODEC, opl3, &ops)) < 0) {
 366                snd_opl3_free(opl3);
 367                return err;
 368        }
 369
 370        *ropl3 = opl3;
 371        return 0;
 372}
 373
 374EXPORT_SYMBOL(snd_opl3_new);
 375
 376int snd_opl3_init(struct snd_opl3 *opl3)
 377{
 378        if (! opl3->command) {
 379                printk(KERN_ERR "snd_opl3_init: command not defined!\n");
 380                return -EINVAL;
 381        }
 382
 383        opl3->command(opl3, OPL3_LEFT | OPL3_REG_TEST, OPL3_ENABLE_WAVE_SELECT);
 384        /* Melodic mode */
 385        opl3->command(opl3, OPL3_LEFT | OPL3_REG_PERCUSSION, 0x00);
 386
 387        switch (opl3->hardware & OPL3_HW_MASK) {
 388        case OPL3_HW_OPL2:
 389                opl3->max_voices = MAX_OPL2_VOICES;
 390                break;
 391        case OPL3_HW_OPL3:
 392        case OPL3_HW_OPL4:
 393                opl3->max_voices = MAX_OPL3_VOICES;
 394                /* Enter OPL3 mode */
 395                opl3->command(opl3, OPL3_RIGHT | OPL3_REG_MODE, OPL3_OPL3_ENABLE);
 396        }
 397        return 0;
 398}
 399
 400EXPORT_SYMBOL(snd_opl3_init);
 401
 402int snd_opl3_create(struct snd_card *card,
 403                    unsigned long l_port,
 404                    unsigned long r_port,
 405                    unsigned short hardware,
 406                    int integrated,
 407                    struct snd_opl3 ** ropl3)
 408{
 409        struct snd_opl3 *opl3;
 410        int err;
 411
 412        *ropl3 = NULL;
 413        if ((err = snd_opl3_new(card, hardware, &opl3)) < 0)
 414                return err;
 415        if (! integrated) {
 416                if ((opl3->res_l_port = request_region(l_port, 2, "OPL2/3 (left)")) == NULL) {
 417                        snd_printk(KERN_ERR "opl3: can't grab left port 0x%lx\n", l_port);
 418                        snd_device_free(card, opl3);
 419                        return -EBUSY;
 420                }
 421                if (r_port != 0 &&
 422                    (opl3->res_r_port = request_region(r_port, 2, "OPL2/3 (right)")) == NULL) {
 423                        snd_printk(KERN_ERR "opl3: can't grab right port 0x%lx\n", r_port);
 424                        snd_device_free(card, opl3);
 425                        return -EBUSY;
 426                }
 427        }
 428        opl3->l_port = l_port;
 429        opl3->r_port = r_port;
 430
 431        switch (opl3->hardware) {
 432        /* some hardware doesn't support timers */
 433        case OPL3_HW_OPL3_SV:
 434        case OPL3_HW_OPL3_CS:
 435        case OPL3_HW_OPL3_FM801:
 436                opl3->command = &snd_opl3_command;
 437                break;
 438        default:
 439                opl3->command = &snd_opl2_command;
 440                if ((err = snd_opl3_detect(opl3)) < 0) {
 441                        snd_printd("OPL2/3 chip not detected at 0x%lx/0x%lx\n",
 442                                   opl3->l_port, opl3->r_port);
 443                        snd_device_free(card, opl3);
 444                        return err;
 445                }
 446                /* detect routine returns correct hardware type */
 447                switch (opl3->hardware & OPL3_HW_MASK) {
 448                case OPL3_HW_OPL3:
 449                case OPL3_HW_OPL4:
 450                        opl3->command = &snd_opl3_command;
 451                }
 452        }
 453
 454        snd_opl3_init(opl3);
 455
 456        *ropl3 = opl3;
 457        return 0;
 458}
 459
 460EXPORT_SYMBOL(snd_opl3_create);
 461
 462int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev)
 463{
 464        int err;
 465
 466        if (timer1_dev >= 0)
 467                if ((err = snd_opl3_timer1_init(opl3, timer1_dev)) < 0)
 468                        return err;
 469        if (timer2_dev >= 0) {
 470                if ((err = snd_opl3_timer2_init(opl3, timer2_dev)) < 0) {
 471                        snd_device_free(opl3->card, opl3->timer1);
 472                        opl3->timer1 = NULL;
 473                        return err;
 474                }
 475        }
 476        return 0;
 477}
 478
 479EXPORT_SYMBOL(snd_opl3_timer_new);
 480
 481int snd_opl3_hwdep_new(struct snd_opl3 * opl3,
 482                       int device, int seq_device,
 483                       struct snd_hwdep ** rhwdep)
 484{
 485        struct snd_hwdep *hw;
 486        struct snd_card *card = opl3->card;
 487        int err;
 488
 489        if (rhwdep)
 490                *rhwdep = NULL;
 491
 492        /* create hardware dependent device (direct FM) */
 493
 494        if ((err = snd_hwdep_new(card, "OPL2/OPL3", device, &hw)) < 0) {
 495                snd_device_free(card, opl3);
 496                return err;
 497        }
 498        hw->private_data = opl3;
 499#ifdef CONFIG_SND_OSSEMUL
 500        if (device == 0) {
 501                hw->oss_type = SNDRV_OSS_DEVICE_TYPE_DMFM;
 502                sprintf(hw->oss_dev, "dmfm%i", card->number);
 503        }
 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.release = snd_opl3_release;
 525
 526        opl3->seq_dev_num = seq_device;
 527#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
 528        if (snd_seq_device_new(card, seq_device, SNDRV_SEQ_DEV_ID_OPL3,
 529                               sizeof(struct snd_opl3 *), &opl3->seq_dev) >= 0) {
 530                strcpy(opl3->seq_dev->name, hw->name);
 531                *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(opl3->seq_dev) = opl3;
 532        }
 533#endif
 534        if (rhwdep)
 535                *rhwdep = hw;
 536        return 0;
 537}
 538
 539EXPORT_SYMBOL(snd_opl3_hwdep_new);
 540
 541/*
 542 *  INIT part
 543 */
 544
 545static int __init alsa_opl3_init(void)
 546{
 547        return 0;
 548}
 549
 550static void __exit alsa_opl3_exit(void)
 551{
 552}
 553
 554module_init(alsa_opl3_init)
 555module_exit(alsa_opl3_exit)
 556