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 DS chips.
   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(%02x) 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 status register */
 118 
 119 
 120 #ifndef EXCLUDE_SB16
 121       if (src & 2) sb16_dsp_interrupt(unit);
 122 #endif
 123 
 124       if (!(src & 1))
 125         return;                 /* Not a DSP interupt */
 126     }
 127 #endif
 128 
 129   status = INB (DSP_DATA_AVAIL);/* Clear interrupt */
 130 
 131   if (sb_intr_active)
 132     switch (sb_irq_mode)
 133       {
 134       case IMODE_OUTPUT:
 135         sb_intr_active = 0;
 136         DMAbuf_outputintr (my_dev, 1);
 137         break;
 138 
 139       case IMODE_INPUT:
 140         sb_intr_active = 0;
 141         DMAbuf_inputintr (my_dev);
 142         /* A complete buffer has been input. Let's start new one */
 143         break;
 144 
 145       case IMODE_INIT:
 146         sb_intr_active = 0;
 147         irq_ok = 1;
 148         break;
 149 
 150       case IMODE_MIDI:
 151         printk ("+");
 152         data = INB (DSP_READ);
 153         printk ("%02x", data);
 154 
 155         break;
 156 
 157       default:
 158         printk ("SoundBlaster: Unexpected interrupt\n");
 159       }
 160 }
 161 
 162 static int sb_irq_usecount = 0;
 163 
 164 int
 165 sb_get_irq(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 166 {
 167         int ok;
 168 
 169         if (!sb_irq_usecount)
 170           if ((ok=snd_set_irq_handler(sbc_irq, sbintr))<0) return ok;
 171 
 172         sb_irq_usecount++;
 173 
 174         return 0; 
 175 }
 176 
 177 void 
 178 sb_free_irq(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 179 {
 180         if (!sb_irq_usecount) return;
 181 
 182         sb_irq_usecount--;
 183 
 184         if (!sb_irq_usecount) snd_release_irq(sbc_irq);
 185 }
 186 
 187 int
 188 sb_reset_dsp (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 189 {
 190   int             loopc;
 191 
 192   OUTB (1, DSP_RESET);
 193   tenmicrosec ();
 194   OUTB (0, DSP_RESET);
 195   tenmicrosec ();
 196   tenmicrosec ();
 197   tenmicrosec ();
 198 
 199   for (loopc = 0; loopc < 1000 && !(INB (DSP_DATA_AVAIL) & 0x80); loopc++);     /* Wait for data
 200                                                                                  * available status */
 201 
 202   if (INB (DSP_READ) != 0xAA)
 203     return 0;                   /* Sorry */
 204 
 205   return 1;
 206 }
 207 
 208 #endif
 209 
 210 #ifndef EXCLUDE_AUDIO
 211 
 212 static void
 213 dsp_speaker (char state)
     /* [previous][next][first][last][top][bottom][index][help] */
 214 {
 215   if (state)
 216     sb_dsp_command (DSP_CMD_SPKON);
 217   else
 218     sb_dsp_command (DSP_CMD_SPKOFF);
 219 }
 220 
 221 static int
 222 dsp_speed (int speed)
     /* [previous][next][first][last][top][bottom][index][help] */
 223 {
 224   unsigned char   tconst;
 225   unsigned long   flags;
 226 
 227   if (speed < 4000)
 228     speed = 4000;
 229 
 230   if (speed > 44100)
 231     speed = 44100;              /* Invalid speed */
 232 
 233   if (sb_dsp_model == 1 && speed > 22050)
 234     speed = 22050;
 235   /* SB Classic doesn't support higher speed */
 236 
 237 
 238   if (dsp_stereo && speed > 22050)
 239     speed = 22050;
 240   /* Max. stereo speed is 22050 */
 241 
 242   if ((speed > 22050) && sb_midi_busy)
 243     {
 244       printk ("SB Warning: High speed DSP not possible simultaneously with MIDI output\n");
 245       speed = 22050;
 246     }
 247 
 248   if (dsp_stereo)
 249     speed *= 2;
 250 
 251   /* Now the speed should be valid */
 252 
 253   if (speed > 22050)
 254     {                           /* High speed mode */
 255       int tmp;
 256 
 257       tconst = (unsigned char) ((65536 - 
 258                                 ((256000000+speed/2) / speed)) >> 8);
 259       sb_dsp_highspeed = 1;
 260 
 261       DISABLE_INTR (flags);
 262       if (sb_dsp_command (0x40))
 263         sb_dsp_command (tconst);
 264       RESTORE_INTR (flags);
 265 
 266       tmp = 65536 - (tconst << 8);
 267       speed = (256000000+tmp/2) / tmp;
 268     }
 269   else
 270     {
 271       int tmp;
 272 
 273       sb_dsp_highspeed = 0;
 274       tconst = (256 - ((1000000+speed/2) / speed)) & 0xff;
 275 
 276       DISABLE_INTR (flags);
 277       if (sb_dsp_command (0x40))        /* Set time constant */
 278         sb_dsp_command (tconst);
 279       RESTORE_INTR (flags);
 280 
 281       tmp = 256 - tconst;
 282       speed = (1000000+tmp/2) / tmp;
 283     }
 284 
 285   if (dsp_stereo)
 286     speed /= 2;
 287 
 288   dsp_current_speed = speed;
 289   return speed;
 290 }
 291 
 292 static int
 293 dsp_set_stereo (int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 294 {
 295   dsp_stereo = 0;
 296 
 297 #ifdef EXCLUDE_SBPRO
 298   return 0;
 299 #else
 300   if (sb_dsp_model == 1 || sb16)
 301     return 0;                   /* Sorry no stereo */
 302 
 303   if (mode && sb_midi_busy)
 304     {
 305       printk ("SB Warning: Stereo DSP not possible simultaneously with MIDI output\n");
 306       return 0;
 307     }
 308 
 309   dsp_stereo = !!mode;
 310   return dsp_stereo;
 311 #endif
 312 }
 313 
 314 static void
 315 sb_dsp_output_block (int dev, unsigned long buf, int count, 
     /* [previous][next][first][last][top][bottom][index][help] */
 316                      int intrflag, int restart_dma)
 317 {
 318   unsigned long   flags;
 319 
 320   if (!sb_irq_mode)
 321     dsp_speaker (ON);
 322 
 323   sb_irq_mode = IMODE_OUTPUT;
 324   DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE);
 325 
 326   if (sound_dsp_dmachan[dev] > 3)
 327     count >>= 1;
 328   count--;
 329 
 330   if (sb_dsp_highspeed)
 331     {
 332       DISABLE_INTR (flags);
 333       if (sb_dsp_command (0x48))        /* High speed size */
 334         {
 335           sb_dsp_command (count & 0xff);
 336           sb_dsp_command ((count >> 8) & 0xff);
 337           sb_dsp_command (0x91);        /* High speed 8 bit DAC */
 338         }
 339       else
 340         printk ("SB Error: Unable to start (high speed) DAC\n");
 341       RESTORE_INTR (flags);
 342     }
 343   else
 344     {
 345       DISABLE_INTR (flags);
 346       if (sb_dsp_command (0x14))        /* 8-bit DAC (DMA) */
 347         {
 348           sb_dsp_command (count & 0xff);
 349           sb_dsp_command ((count >> 8) & 0xff);
 350         }
 351       else
 352         printk ("SB Error: Unable to start DAC\n");
 353       RESTORE_INTR (flags);
 354     }
 355   sb_intr_active = 1;
 356 }
 357 
 358 static void
 359 sb_dsp_start_input (int dev, unsigned long buf, int count, int intrflag,
     /* [previous][next][first][last][top][bottom][index][help] */
 360                     int restart_dma)
 361 {
 362   /* Start a DMA input to the buffer pointed by dmaqtail */
 363 
 364   unsigned long   flags;
 365 
 366   if (!sb_irq_mode)
 367     dsp_speaker (OFF);
 368 
 369   sb_irq_mode = IMODE_INPUT;
 370   DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ);
 371 
 372   if (sound_dsp_dmachan[dev] > 3)
 373     count >>= 1;
 374   count--;
 375 
 376   if (sb_dsp_highspeed)
 377     {
 378       DISABLE_INTR (flags);
 379       if (sb_dsp_command (0x48))        /* High speed size */
 380         {
 381           sb_dsp_command (count & 0xff);
 382           sb_dsp_command ((count >> 8) & 0xff);
 383           sb_dsp_command (0x99);        /* High speed 8 bit ADC */
 384         }
 385       else
 386         printk ("SB Error: Unable to start (high speed) ADC\n");
 387       RESTORE_INTR (flags);
 388     }
 389   else
 390     {
 391       DISABLE_INTR (flags);
 392       if (sb_dsp_command (0x24))        /* 8-bit ADC (DMA) */
 393         {
 394           sb_dsp_command (count & 0xff);
 395           sb_dsp_command ((count >> 8) & 0xff);
 396         }
 397       else
 398         printk ("SB Error: Unable to start ADC\n");
 399       RESTORE_INTR (flags);
 400     }
 401 
 402   sb_intr_active = 1;
 403 }
 404 
 405 static void
 406 dsp_cleanup (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 407 {
 408   sb_intr_active = 0;
 409 }
 410 
 411 static int
 412 sb_dsp_prepare_for_input (int dev, int bsize, int bcount)
     /* [previous][next][first][last][top][bottom][index][help] */
 413 {
 414   dsp_cleanup ();
 415   dsp_speaker (OFF);
 416 
 417   if (major == 3)       /* SB Pro */
 418   {
 419     if (dsp_stereo)
 420        sb_dsp_command(0xa8);
 421     else
 422        sb_dsp_command(0xa0);
 423 
 424     dsp_speed (dsp_current_speed);/* Speed must be recalculated if #channels
 425                                    * changes */
 426   }
 427   return 0;
 428 }
 429 
 430 static int
 431 sb_dsp_prepare_for_output (int dev, int bsize, int bcount)
     /* [previous][next][first][last][top][bottom][index][help] */
 432 {
 433   dsp_cleanup ();
 434   dsp_speaker (ON);
 435 
 436 #ifndef EXCLUDE_SBPRO
 437   if (major == 3)       /* SB Pro */
 438   {
 439     sb_mixer_set_stereo(dsp_stereo);
 440     dsp_speed (dsp_current_speed);/* Speed must be recalculated if #channels
 441                                    * changes */
 442   }
 443 #endif
 444   return 0;
 445 }
 446 
 447 static void
 448 sb_dsp_halt_xfer (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 449 {
 450 }
 451 
 452 static int
 453 verify_irq (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 454 {
 455 #if 0
 456   DEFINE_WAIT_QUEUE(testq, testf);
 457 
 458   irq_ok = 0;
 459 
 460   if (sb_get_irq () == -1)
 461     {
 462       printk ("*** SB Error: Irq %d already in use\n", sbc_irq);
 463       return 0;
 464     }
 465 
 466 
 467   sb_irq_mode = IMODE_INIT;
 468 
 469   sb_dsp_command (0xf2);                /* This should cause immediate interrupt */
 470 
 471   DO_SLEEP(testq, testf, HZ / 5);
 472 
 473   sb_free_irq();
 474 
 475   if (!irq_ok)
 476     {
 477       printk ("SB Warning: IRQ%d test not passed!", sbc_irq);
 478       irq_ok = 1;
 479     }
 480 #else
 481   irq_ok = 1;
 482 #endif
 483   return irq_ok;
 484 }
 485 
 486 static int
 487 sb_dsp_open (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 488 {
 489   int             retval;
 490 
 491   if (!sb_dsp_ok)
 492     {
 493       printk ("SB Error: SoundBlaster board not installed\n");
 494       return RET_ERROR (ENXIO);
 495     }
 496 
 497   if (sb_intr_active || (sb_midi_busy && sb_midi_mode == UART_MIDI))
 498     {
 499       printk ("SB: PCM not possible during MIDI input\n");
 500       return RET_ERROR (EBUSY);
 501     }
 502 
 503   if (!irq_verified)
 504     {
 505         verify_irq();
 506         irq_verified = 1;
 507     }
 508   else
 509     if (!irq_ok)
 510        printk("SB Warning: Incorrect IRQ setting %d\n",
 511               sbc_irq);
 512 
 513   retval = sb_get_irq ();
 514   if (retval)
 515     return retval;
 516 
 517   if (!DMAbuf_open_dma (dev))
 518     {
 519       sb_free_irq ();
 520       printk ("SB: DMA Busy\n");
 521       return RET_ERROR (EBUSY);
 522     }
 523 
 524   sb_irq_mode = IMODE_NONE;
 525 
 526   sb_dsp_busy = 1;
 527 
 528   return 0;
 529 }
 530 
 531 static void
 532 sb_dsp_close (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 533 {
 534   DMAbuf_close_dma (dev);
 535   sb_free_irq ();
 536   dsp_cleanup ();
 537   dsp_speaker (OFF);
 538   sb_dsp_busy = 0;
 539   sb_dsp_highspeed = 0;
 540 }
 541 
 542 static int
 543 sb_dsp_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
     /* [previous][next][first][last][top][bottom][index][help] */
 544 {
 545   switch (cmd)
 546     {
 547     case SOUND_PCM_WRITE_RATE:
 548       if (local)
 549         return dsp_speed (arg);
 550       return IOCTL_OUT (arg, dsp_speed (IOCTL_IN (arg)));
 551       break;
 552 
 553     case SOUND_PCM_READ_RATE:
 554       if (local)
 555         return dsp_current_speed;
 556       return IOCTL_OUT (arg, dsp_current_speed);
 557       break;
 558 
 559     case SOUND_PCM_WRITE_CHANNELS:
 560       return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg) - 1) + 1);
 561       break;
 562 
 563     case SOUND_PCM_READ_CHANNELS:
 564       if (local)
 565         return dsp_stereo + 1;
 566       return IOCTL_OUT (arg, dsp_stereo + 1);
 567       break;
 568 
 569     case SNDCTL_DSP_STEREO:
 570       if (local)
 571         return dsp_set_stereo (arg);
 572       return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg)));
 573       break;
 574 
 575     case SOUND_PCM_WRITE_BITS:
 576     case SOUND_PCM_READ_BITS:
 577       if (local)
 578         return 8;
 579       return IOCTL_OUT (arg, 8);/* Only 8 bits/sample supported */
 580       break;
 581 
 582     case SOUND_PCM_WRITE_FILTER:
 583     case SOUND_PCM_READ_FILTER:
 584       return RET_ERROR (EINVAL);
 585       break;
 586 
 587     default:
 588       return RET_ERROR (EINVAL);
 589     }
 590 
 591   return RET_ERROR (EINVAL);
 592 }
 593 
 594 static void
 595 sb_dsp_reset (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 596 {
 597   unsigned long   flags;
 598 
 599   DISABLE_INTR (flags);
 600 
 601   sb_reset_dsp ();
 602   dsp_cleanup ();
 603 
 604   RESTORE_INTR (flags);
 605 }
 606 
 607 #endif
 608 
 609 int
 610 sb_dsp_detect (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 611 {
 612   sbc_base = hw_config->io_base;
 613   sbc_irq = hw_config->irq;
 614 
 615   if (sb_dsp_ok)
 616     return 0;                   /* Already initialized */
 617 
 618   if (!sb_reset_dsp ())
 619     return 0;
 620 
 621   return 1;                     /* Detected */
 622 }
 623 
 624 #ifndef EXCLUDE_AUDIO
 625 static struct audio_operations sb_dsp_operations =
 626 {
 627   "SoundBlaster",
 628   sb_dsp_open,
 629   sb_dsp_close,
 630   sb_dsp_output_block,
 631   sb_dsp_start_input,
 632   sb_dsp_ioctl,
 633   sb_dsp_prepare_for_input,
 634   sb_dsp_prepare_for_output,
 635   sb_dsp_reset,
 636   sb_dsp_halt_xfer,
 637   NULL,                         /* has_output_drained */
 638   NULL                          /* copy_from_user */
 639 };
 640 
 641 #endif
 642 
 643 long
 644 sb_dsp_init (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 645 {
 646   int             i;
 647 
 648   major = minor = 0;
 649   sb_dsp_command (0xe1);                /* Get version */
 650 
 651   for (i = 1000; i; i--)
 652     {
 653       if (INB (DSP_DATA_AVAIL) & 0x80)
 654         {                       /* wait for Data Ready */
 655           if (major == 0)
 656             major = INB (DSP_READ);
 657           else
 658             {
 659               minor = INB (DSP_READ);
 660               break;
 661             }
 662         }
 663     }
 664 
 665       if (major == 2 || major == 3)
 666         sb_duplex_midi = 1;
 667 
 668       if (major == 4)
 669         sb16 = 1;
 670 
 671       if (major >= 3)
 672         sb_dsp_model = 2;
 673 
 674 #ifndef EXCLUDE_SBPRO
 675       if (major >= 3)
 676          sb_mixer_init(major);
 677 #endif
 678 
 679 #ifndef EXCLUDE_YM8312
 680       if (major > 3 || (major == 3 && minor > 0))       /* SB Pro2 or later */
 681         {
 682           enable_opl3_mode (OPL3_LEFT, OPL3_RIGHT, OPL3_BOTH);
 683         }
 684 #endif
 685 
 686     if (major >= 3)
 687       {
 688 #ifndef SCO
 689         sprintf (sb_dsp_operations.name, "SoundBlaster Pro %d.%d", major, minor);
 690 #endif
 691       }
 692     else
 693       {
 694 #ifndef SCO
 695         sprintf (sb_dsp_operations.name, "SoundBlaster %d.%d", major, minor);
 696 #endif
 697       }
 698 
 699   printk (" <%s>", sb_dsp_operations.name);
 700 
 701 #ifndef EXCLUDE_AUDIO
 702   if (num_dspdevs < MAX_DSP_DEV)
 703     {
 704       dsp_devs[my_dev = num_dspdevs++] = &sb_dsp_operations;
 705       sound_buffcounts[my_dev] = DSP_BUFFCOUNT;
 706       sound_buffsizes[my_dev] = DSP_BUFFSIZE;
 707       sound_dsp_dmachan[my_dev] = hw_config->dma;
 708       sound_dma_automode[my_dev] = 0;
 709     }
 710   else
 711     printk ("SB: Too many DSP devices available\n");
 712 #endif
 713 
 714 #ifndef EXCLUDE_MIDI
 715   if (!midi_disabled)           /* Midi don't work in the SB emulation mode
 716                                  * of PAS */
 717         sb_midi_init(major);
 718 #endif
 719 
 720   sb_dsp_ok = 1;
 721   return mem_start;
 722 }
 723 
 724 void
 725 sb_dsp_disable_midi (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 726 {
 727   midi_disabled = 1;
 728 }
 729 
 730 #endif

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