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

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