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

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