root/drivers/sound/sb_dsp.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sb_dsp_command
  2. sbintr
  3. sb_get_irq
  4. sb_free_irq
  5. sb_reset_dsp
  6. dsp_speaker
  7. dsp_speed
  8. dsp_set_stereo
  9. sb_dsp_output_block
  10. sb_dsp_start_input
  11. dsp_cleanup
  12. sb_dsp_prepare_for_input
  13. sb_dsp_prepare_for_output
  14. sb_dsp_halt_xfer
  15. verify_irq
  16. sb_dsp_open
  17. sb_dsp_close
  18. sb_dsp_ioctl
  19. sb_dsp_reset
  20. sb_dsp_detect
  21. sb_dsp_init
  22. sb_dsp_disable_midi

   1 /*
   2  * sound/sb_dsp.c
   3  * 
   4  * The low level driver for the SoundBlaster DSP chip.
   5  * 
   6  * Copyright by Hannu Savolainen 1993
   7  * 
   8  * Redistribution and use in source and binary forms, with or without
   9  * modification, are permitted provided that the following conditions are
  10  * met: 1. Redistributions of source code must retain the above copyright
  11  * notice, this list of conditions and the following disclaimer. 2.
  12  * Redistributions in binary form must reproduce the above copyright notice,
  13  * this list of conditions and the following disclaimer in the documentation
  14  * and/or other materials provided with the distribution.
  15  * 
  16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
  17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26  * SUCH DAMAGE.
  27  * 
  28  */
  29 
  30 #include "sound_config.h"
  31 
  32 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB)
  33 
  34 #include "sb.h"
  35 #include "sb_mixer.h"
  36 #undef SB_TEST_IRQ
  37 
  38 int      sbc_base = 0;
  39 static int      sbc_irq = 0;
  40 
  41 /*
  42  * The DSP channel can be used either for input or output. Variable
  43  * 'sb_irq_mode' will be set when the program calls read or write first time
  44  * after open. Current version doesn't support mode changes without closing
  45  * and reopening the device. Support for this feature may be implemented in a
  46  * future version of this driver.
  47  */
  48 
  49 int      sb_dsp_ok = 0; /* Set to 1 after successful initialization */
  50 static int      midi_disabled = 0;
  51 int      sb_dsp_highspeed = 0;
  52 static int      major=1, minor=0;       /* DSP version */
  53 static int      dsp_stereo = 0;
  54 static int      dsp_current_speed = DSP_DEFAULT_SPEED;
  55 static int      sb16 = 0;
  56 static int      irq_verified = 0;
  57 
  58 int      sb_midi_mode = NORMAL_MIDI;
  59 int      sb_midi_busy = 0;      /* 1 if the process has output to MIDI */
  60 int      sb_dsp_busy = 0;
  61 
  62 volatile int sb_irq_mode = IMODE_NONE;  /* IMODE_INPUT, IMODE_OUTPUT
  63                                                  * or IMODE_NONE */
  64 static volatile int irq_ok = 0;
  65 
  66 int      sb_dsp_model = 1;      /* 1=SB, 2=SB Pro */
  67 int      sb_duplex_midi = 0;
  68 static int      my_dev = 0;
  69 
  70 volatile int sb_intr_active = 0;
  71 
  72 static int      dsp_speed (int);
  73 static int      dsp_set_stereo (int mode);
  74 int      sb_dsp_command (unsigned char val);
  75 
  76 #if !defined(EXCLUDE_MIDI) || !defined(EXCLUDE_AUDIO)
  77 
  78 /* Common code for the midi and pcm functions */
  79 
  80 int
  81 sb_dsp_command (unsigned char val)
     /* [previous][next][first][last][top][bottom][index][help] */
  82 {
  83   int             i, limit;
  84 
  85   limit = GET_TIME () + 10;     /* The timeout is 0.1 secods */
  86 
  87   /*
  88    * Note! the i<500000 is an emergency exit. The sb_dsp_command() is sometimes
  89    * called while interrupts are disabled. This means that the timer is
  90    * disabled also. However the timeout situation is a abnormal condition.
  91    * Normally the DSP should be ready to accept commands after just couple of
  92    * loops.
  93    */
  94 
  95   for (i = 0; i < 500000 && GET_TIME () < limit; i++)
  96     {
  97       if ((INB (DSP_STATUS) & 0x80) == 0)
  98         {
  99           OUTB (val, DSP_COMMAND);
 100           return 1;
 101         }
 102     }
 103 
 104   printk ("SoundBlaster: DSP Command(%x) Timeout.\n", val);
 105   printk ("IRQ conflict???\n");
 106   return 0;
 107 }
 108 
 109 void
 110 sbintr (int unit)
     /* [previous][next][first][last][top][bottom][index][help] */
 111 {
 112   int             status, data;
 113 
 114 #ifndef EXCLUDE_SBPRO
 115   if (sb16)
 116     {
 117       unsigned char   src = sb_getmixer (IRQ_STAT);     /* Interrupt source register */
 118 
 119 #ifndef EXCLUDE_SB16
 120       if (src & 3) sb16_dsp_interrupt(unit);
 121 
 122 #ifndef EXCLUDE_MIDI
 123       if (src & 4) sb16midiintr (unit);                 /* MPU401 interrupt */
 124 #endif
 125 
 126 #endif
 127 
 128       if (!(src & 1))
 129         return;                 /* Not a DSP interupt */
 130     }
 131 #endif
 132 
 133   status = INB (DSP_DATA_AVAIL);/* Clear interrupt */
 134 
 135   if (sb_intr_active)
 136     switch (sb_irq_mode)
 137       {
 138       case IMODE_OUTPUT:
 139         sb_intr_active = 0;
 140         DMAbuf_outputintr (my_dev, 1);
 141         break;
 142 
 143       case IMODE_INPUT:
 144         sb_intr_active = 0;
 145         DMAbuf_inputintr (my_dev);
 146         /* A complete buffer has been input. Let's start new one */
 147         break;
 148 
 149       case IMODE_INIT:
 150         sb_intr_active = 0;
 151         irq_ok = 1;
 152         break;
 153 
 154       case IMODE_MIDI:
 155         printk ("+");
 156         data = INB (DSP_READ);
 157         printk ("%x", data);
 158 
 159         break;
 160 
 161       default:
 162         printk ("SoundBlaster: Unexpected interrupt\n");
 163       }
 164 }
 165 
 166 static int sb_irq_usecount = 0;
 167 
 168 int
 169 sb_get_irq(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 170 {
 171         int ok;
 172 
 173         if (!sb_irq_usecount)
 174           if ((ok=snd_set_irq_handler(sbc_irq, sbintr))<0) return ok;
 175 
 176         sb_irq_usecount++;
 177 
 178         return 0; 
 179 }
 180 
 181 void 
 182 sb_free_irq(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 183 {
 184         if (!sb_irq_usecount) return;
 185 
 186         sb_irq_usecount--;
 187 
 188         if (!sb_irq_usecount) snd_release_irq(sbc_irq);
 189 }
 190 
 191 int
 192 sb_reset_dsp (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 193 {
 194   int             loopc;
 195 
 196   OUTB (1, DSP_RESET);
 197   tenmicrosec ();
 198   OUTB (0, DSP_RESET);
 199   tenmicrosec ();
 200   tenmicrosec ();
 201   tenmicrosec ();
 202 
 203   for (loopc = 0; loopc < 1000 && !(INB (DSP_DATA_AVAIL) & 0x80); loopc++);     /* Wait for data
 204                                                                                  * available status */
 205 
 206   if (INB (DSP_READ) != 0xAA)
 207     return 0;                   /* Sorry */
 208 
 209   return 1;
 210 }
 211 
 212 #endif
 213 
 214 #ifndef EXCLUDE_AUDIO
 215 
 216 static void
 217 dsp_speaker (char state)
     /* [previous][next][first][last][top][bottom][index][help] */
 218 {
 219   if (state)
 220     sb_dsp_command (DSP_CMD_SPKON);
 221   else
 222     sb_dsp_command (DSP_CMD_SPKOFF);
 223 }
 224 
 225 static int
 226 dsp_speed (int speed)
     /* [previous][next][first][last][top][bottom][index][help] */
 227 {
 228   unsigned char   tconst;
 229   unsigned long   flags;
 230 
 231   if (speed < 4000)
 232     speed = 4000;
 233 
 234   if (speed > 44100)
 235     speed = 44100;              /* Invalid speed */
 236 
 237   if (sb_dsp_model == 1 && speed > 22050)
 238     speed = 22050;
 239   /* SB Classic doesn't support higher speed */
 240 
 241 
 242   if (dsp_stereo && speed > 22050)
 243     speed = 22050;
 244   /* Max. stereo speed is 22050 */
 245 
 246   if ((speed > 22050) && sb_midi_busy)
 247     {
 248       printk ("SB Warning: High speed DSP not possible simultaneously with MIDI output\n");
 249       speed = 22050;
 250     }
 251 
 252   if (dsp_stereo)
 253     speed *= 2;
 254 
 255   /* Now the speed should be valid */
 256 
 257   if (speed > 22050)
 258     {                           /* High speed mode */
 259       int tmp;
 260 
 261       tconst = (unsigned char) ((65536 - 
 262                                 ((256000000+speed/2) / speed)) >> 8);
 263       sb_dsp_highspeed = 1;
 264 
 265       DISABLE_INTR (flags);
 266       if (sb_dsp_command (0x40))
 267         sb_dsp_command (tconst);
 268       RESTORE_INTR (flags);
 269 
 270       tmp = 65536 - (tconst << 8);
 271       speed = (256000000+tmp/2) / tmp;
 272     }
 273   else
 274     {
 275       int tmp;
 276 
 277       sb_dsp_highspeed = 0;
 278       tconst = (256 - ((1000000+speed/2) / speed)) & 0xff;
 279 
 280       DISABLE_INTR (flags);
 281       if (sb_dsp_command (0x40))        /* Set time constant */
 282         sb_dsp_command (tconst);
 283       RESTORE_INTR (flags);
 284 
 285       tmp = 256 - tconst;
 286       speed = (1000000+tmp/2) / tmp;
 287     }
 288 
 289   if (dsp_stereo)
 290     speed /= 2;
 291 
 292   dsp_current_speed = speed;
 293   return speed;
 294 }
 295 
 296 static int
 297 dsp_set_stereo (int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 298 {
 299   dsp_stereo = 0;
 300 
 301 #ifdef EXCLUDE_SBPRO
 302   return 0;
 303 #else
 304   if (sb_dsp_model == 1 || sb16)
 305     return 0;                   /* Sorry no stereo */
 306 
 307   if (mode && sb_midi_busy)
 308     {
 309       printk ("SB Warning: Stereo DSP not possible simultaneously with MIDI output\n");
 310       return 0;
 311     }
 312 
 313   dsp_stereo = !!mode;
 314   return dsp_stereo;
 315 #endif
 316 }
 317 
 318 static void
 319 sb_dsp_output_block (int dev, unsigned long buf, int count, 
     /* [previous][next][first][last][top][bottom][index][help] */
 320                      int intrflag, int restart_dma)
 321 {
 322   unsigned long   flags;
 323 
 324   if (!sb_irq_mode)
 325     dsp_speaker (ON);
 326 
 327   sb_irq_mode = IMODE_OUTPUT;
 328   DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE);
 329 
 330   if (sound_dsp_dmachan[dev] > 3)
 331     count >>= 1;
 332   count--;
 333 
 334   if (sb_dsp_highspeed)
 335     {
 336       DISABLE_INTR (flags);
 337       if (sb_dsp_command (0x48))        /* High speed size */
 338         {
 339           sb_dsp_command ((unsigned char)(count & 0xff));
 340           sb_dsp_command ((unsigned char)((count >> 8) & 0xff));
 341           sb_dsp_command (0x91);        /* High speed 8 bit DAC */
 342         }
 343       else
 344         printk ("SB Error: Unable to start (high speed) DAC\n");
 345       RESTORE_INTR (flags);
 346     }
 347   else
 348     {
 349       DISABLE_INTR (flags);
 350       if (sb_dsp_command (0x14))        /* 8-bit DAC (DMA) */
 351         {
 352           sb_dsp_command ((unsigned char)(count & 0xff));
 353           sb_dsp_command ((unsigned char)((count >> 8) & 0xff));
 354         }
 355       else
 356         printk ("SB Error: Unable to start DAC\n");
 357       RESTORE_INTR (flags);
 358     }
 359   sb_intr_active = 1;
 360 }
 361 
 362 static void
 363 sb_dsp_start_input (int dev, unsigned long buf, int count, int intrflag,
     /* [previous][next][first][last][top][bottom][index][help] */
 364                     int restart_dma)
 365 {
 366   /* Start a DMA input to the buffer pointed by dmaqtail */
 367 
 368   unsigned long   flags;
 369 
 370   if (!sb_irq_mode)
 371     dsp_speaker (OFF);
 372 
 373   sb_irq_mode = IMODE_INPUT;
 374   DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ);
 375 
 376   if (sound_dsp_dmachan[dev] > 3)
 377     count >>= 1;
 378   count--;
 379 
 380   if (sb_dsp_highspeed)
 381     {
 382       DISABLE_INTR (flags);
 383       if (sb_dsp_command (0x48))        /* High speed size */
 384         {
 385           sb_dsp_command ((unsigned char)(count & 0xff));
 386           sb_dsp_command ((unsigned char)((count >> 8) & 0xff));
 387           sb_dsp_command (0x99);        /* High speed 8 bit ADC */
 388         }
 389       else
 390         printk ("SB Error: Unable to start (high speed) ADC\n");
 391       RESTORE_INTR (flags);
 392     }
 393   else
 394     {
 395       DISABLE_INTR (flags);
 396       if (sb_dsp_command (0x24))        /* 8-bit ADC (DMA) */
 397         {
 398           sb_dsp_command ((unsigned char)(count & 0xff));
 399           sb_dsp_command ((unsigned char)((count >> 8) & 0xff));
 400         }
 401       else
 402         printk ("SB Error: Unable to start ADC\n");
 403       RESTORE_INTR (flags);
 404     }
 405 
 406   sb_intr_active = 1;
 407 }
 408 
 409 static void
 410 dsp_cleanup (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 411 {
 412   sb_intr_active = 0;
 413 }
 414 
 415 static int
 416 sb_dsp_prepare_for_input (int dev, int bsize, int bcount)
     /* [previous][next][first][last][top][bottom][index][help] */
 417 {
 418   dsp_cleanup ();
 419   dsp_speaker (OFF);
 420 
 421   if (major == 3)       /* SB Pro */
 422   {
 423     if (dsp_stereo)
 424        sb_dsp_command(0xa8);
 425     else
 426        sb_dsp_command(0xa0);
 427 
 428     dsp_speed (dsp_current_speed);/* Speed must be recalculated if #channels
 429                                    * changes */
 430   }
 431   return 0;
 432 }
 433 
 434 static int
 435 sb_dsp_prepare_for_output (int dev, int bsize, int bcount)
     /* [previous][next][first][last][top][bottom][index][help] */
 436 {
 437   dsp_cleanup ();
 438   dsp_speaker (ON);
 439 
 440 #ifndef EXCLUDE_SBPRO
 441   if (major == 3)       /* SB Pro */
 442   {
 443     sb_mixer_set_stereo(dsp_stereo);
 444     dsp_speed (dsp_current_speed);/* Speed must be recalculated if #channels
 445                                    * changes */
 446   }
 447 #endif
 448   return 0;
 449 }
 450 
 451 static void
 452 sb_dsp_halt_xfer (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 453 {
 454 }
 455 
 456 static int
 457 verify_irq (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 458 {
 459 #if 0
 460   DEFINE_WAIT_QUEUE(testq, testf);
 461 
 462   irq_ok = 0;
 463 
 464   if (sb_get_irq () == -1)
 465     {
 466       printk ("*** SB Error: Irq %d already in use\n", sbc_irq);
 467       return 0;
 468     }
 469 
 470 
 471   sb_irq_mode = IMODE_INIT;
 472 
 473   sb_dsp_command (0xf2);                /* This should cause immediate interrupt */
 474 
 475   DO_SLEEP(testq, testf, HZ / 5);
 476 
 477   sb_free_irq();
 478 
 479   if (!irq_ok)
 480     {
 481       printk ("SB Warning: IRQ%d test not passed!", sbc_irq);
 482       irq_ok = 1;
 483     }
 484 #else
 485   irq_ok = 1;
 486 #endif
 487   return irq_ok;
 488 }
 489 
 490 static int
 491 sb_dsp_open (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 492 {
 493   int             retval;
 494 
 495   if (!sb_dsp_ok)
 496     {
 497       printk ("SB Error: SoundBlaster board not installed\n");
 498       return RET_ERROR (ENXIO);
 499     }
 500 
 501   if (sb_intr_active || (sb_midi_busy && sb_midi_mode == UART_MIDI))
 502     {
 503       printk ("SB: PCM not possible during MIDI input\n");
 504       return RET_ERROR (EBUSY);
 505     }
 506 
 507   if (!irq_verified)
 508     {
 509         verify_irq();
 510         irq_verified = 1;
 511     }
 512   else
 513     if (!irq_ok)
 514        printk("SB Warning: Incorrect IRQ setting %d\n",
 515               sbc_irq);
 516 
 517   retval = sb_get_irq ();
 518   if (retval)
 519     return retval;
 520 
 521   if (!DMAbuf_open_dma (dev))
 522     {
 523       sb_free_irq ();
 524       printk ("SB: DMA Busy\n");
 525       return RET_ERROR (EBUSY);
 526     }
 527 
 528   sb_irq_mode = IMODE_NONE;
 529 
 530   sb_dsp_busy = 1;
 531 
 532   return 0;
 533 }
 534 
 535 static void
 536 sb_dsp_close (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 537 {
 538   DMAbuf_close_dma (dev);
 539   sb_free_irq ();
 540   dsp_cleanup ();
 541   dsp_speaker (OFF);
 542   sb_dsp_busy = 0;
 543   sb_dsp_highspeed = 0;
 544 }
 545 
 546 static int
 547 sb_dsp_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
     /* [previous][next][first][last][top][bottom][index][help] */
 548 {
 549   switch (cmd)
 550     {
 551     case SOUND_PCM_WRITE_RATE:
 552       if (local)
 553         return dsp_speed (arg);
 554       return IOCTL_OUT (arg, dsp_speed (IOCTL_IN (arg)));
 555       break;
 556 
 557     case SOUND_PCM_READ_RATE:
 558       if (local)
 559         return dsp_current_speed;
 560       return IOCTL_OUT (arg, dsp_current_speed);
 561       break;
 562 
 563     case SOUND_PCM_WRITE_CHANNELS:
 564       if (local)
 565          return dsp_set_stereo (arg - 1) + 1;
 566       return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg) - 1) + 1);
 567       break;
 568 
 569     case SOUND_PCM_READ_CHANNELS:
 570       if (local)
 571         return dsp_stereo + 1;
 572       return IOCTL_OUT (arg, dsp_stereo + 1);
 573       break;
 574 
 575     case SNDCTL_DSP_STEREO:
 576       if (local)
 577         return dsp_set_stereo (arg);
 578       return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg)));
 579       break;
 580 
 581     case SOUND_PCM_WRITE_BITS:
 582     case SOUND_PCM_READ_BITS:
 583       if (local)
 584         return 8;
 585       return IOCTL_OUT (arg, 8);/* Only 8 bits/sample supported */
 586       break;
 587 
 588     case SOUND_PCM_WRITE_FILTER:
 589     case SOUND_PCM_READ_FILTER:
 590       return RET_ERROR (EINVAL);
 591       break;
 592 
 593     default:
 594       return RET_ERROR (EINVAL);
 595     }
 596 
 597   return RET_ERROR (EINVAL);
 598 }
 599 
 600 static void
 601 sb_dsp_reset (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 602 {
 603   unsigned long   flags;
 604 
 605   DISABLE_INTR (flags);
 606 
 607   sb_reset_dsp ();
 608   dsp_cleanup ();
 609 
 610   RESTORE_INTR (flags);
 611 }
 612 
 613 #endif
 614 
 615 int
 616 sb_dsp_detect (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 617 {
 618   sbc_base = hw_config->io_base;
 619   sbc_irq = hw_config->irq;
 620 
 621   if (sb_dsp_ok)
 622     return 0;                   /* Already initialized */
 623 
 624   if (!sb_reset_dsp ())
 625     return 0;
 626 
 627   return 1;                     /* Detected */
 628 }
 629 
 630 #ifndef EXCLUDE_AUDIO
 631 static struct audio_operations sb_dsp_operations =
 632 {
 633   "SoundBlaster",
 634   sb_dsp_open,
 635   sb_dsp_close,
 636   sb_dsp_output_block,
 637   sb_dsp_start_input,
 638   sb_dsp_ioctl,
 639   sb_dsp_prepare_for_input,
 640   sb_dsp_prepare_for_output,
 641   sb_dsp_reset,
 642   sb_dsp_halt_xfer,
 643   NULL,                         /* has_output_drained */
 644   NULL                          /* copy_from_user */
 645 };
 646 
 647 #endif
 648 
 649 long
 650 sb_dsp_init (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 651 {
 652   int             i;
 653 
 654   major = minor = 0;
 655   sb_dsp_command (0xe1);                /* Get version */
 656 
 657   for (i = 1000; i; i--)
 658     {
 659       if (INB (DSP_DATA_AVAIL) & 0x80)
 660         {                       /* wait for Data Ready */
 661           if (major == 0)
 662             major = INB (DSP_READ);
 663           else
 664             {
 665               minor = INB (DSP_READ);
 666               break;
 667             }
 668         }
 669     }
 670 
 671       if (major == 2 || major == 3)
 672         sb_duplex_midi = 1;
 673 
 674       if (major == 4)
 675         sb16 = 1;
 676 
 677       if (major >= 3)
 678         sb_dsp_model = 2;
 679 
 680 #ifndef EXCLUDE_SBPRO
 681       if (major >= 3)
 682          sb_mixer_init(major);
 683 #endif
 684 
 685 #ifndef EXCLUDE_YM3812
 686       if (major > 3 || (major == 3 && minor > 0))       /* SB Pro2 or later */
 687         {
 688           enable_opl3_mode (OPL3_LEFT, OPL3_RIGHT, OPL3_BOTH);
 689         }
 690 #endif
 691 
 692     if (major >= 3)
 693       {
 694 #ifndef SCO
 695         sprintf (sb_dsp_operations.name, "SoundBlaster Pro %d.%d", major, minor);
 696 #endif
 697       }
 698     else
 699       {
 700 #ifndef SCO
 701         sprintf (sb_dsp_operations.name, "SoundBlaster %d.%d", major, minor);
 702 #endif
 703       }
 704 
 705   printk (" <%s>", sb_dsp_operations.name);
 706 
 707 #ifndef EXCLUDE_AUDIO
 708 #  if !defined(EXCLUDE_SB16) && !defined(EXCLUDE_SBPRO)
 709   if (!sb16)    /* There is a better driver for SB16    */
 710 #  endif
 711   if (num_dspdevs < MAX_DSP_DEV)
 712     {
 713       dsp_devs[my_dev = num_dspdevs++] = &sb_dsp_operations;
 714       sound_buffcounts[my_dev] = DSP_BUFFCOUNT;
 715       sound_buffsizes[my_dev] = DSP_BUFFSIZE;
 716       sound_dsp_dmachan[my_dev] = hw_config->dma;
 717       sound_dma_automode[my_dev] = 0;
 718     }
 719   else
 720     printk ("SB: Too many DSP devices available\n");
 721 #endif
 722 
 723 #ifndef EXCLUDE_MIDI
 724   if (!midi_disabled && !sb16)  /* Midi don't work in the SB emulation mode
 725                                  * of PAS, SB16 has better midi interface */
 726         sb_midi_init(major);
 727 #endif
 728 
 729   sb_dsp_ok = 1;
 730   return mem_start;
 731 }
 732 
 733 void
 734 sb_dsp_disable_midi (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 735 {
 736   midi_disabled = 1;
 737 }
 738 
 739 #endif

/* [previous][next][first][last][top][bottom][index][help] */