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

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