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. dsp_set_bits
  19. sb_dsp_ioctl
  20. sb_dsp_reset
  21. get_sb_byte
  22. smw_putmem
  23. smw_getmem
  24. initialize_smw
  25. initialize_ProSonic16
  26. sb_dsp_detect
  27. sb_dsp_init
  28. 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  *      JRA Gibson      April 1995
  33  *      Code added for MV ProSonic/Jazz 16 in 16 bit mode
  34  */
  35 
  36 #include "sound_config.h"
  37 
  38 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB)
  39 
  40 #include "sb.h"
  41 #include "sb_mixer.h"
  42 #undef SB_TEST_IRQ
  43 
  44 int             sbc_base = 0;
  45 static int      sbc_irq = 0;
  46 static int      open_mode = 0;  /* Read, write or both */
  47 int             Jazz16_detected = 0;
  48 int             sb_no_recording = 0;
  49 
  50 /*
  51  * The DSP channel can be used either for input or output. Variable
  52  * 'sb_irq_mode' will be set when the program calls read or write first time
  53  * after open. Current version doesn't support mode changes without closing
  54  * and reopening the device. Support for this feature may be implemented in a
  55  * future version of this driver.
  56  */
  57 
  58 int             sb_dsp_ok = 0;  /*
  59 
  60 
  61                                  * *  * * Set to 1 after successful
  62                                  * initialization  *  */
  63 static int      midi_disabled = 0;
  64 int             sb_dsp_highspeed = 0;
  65 int             sbc_major = 1, sbc_minor = 0;   /*
  66 
  67 
  68                                                    * *  * * DSP version   */
  69 static int      dsp_stereo = 0;
  70 static int      dsp_current_speed = DSP_DEFAULT_SPEED;
  71 static int      sb16 = 0;
  72 static int      irq_verified = 0;
  73 
  74 int             sb_midi_mode = NORMAL_MIDI;
  75 int             sb_midi_busy = 0;       /*
  76 
  77 
  78                                          * *  * * 1 if the process has output
  79                                          * to *  * MIDI   */
  80 int             sb_dsp_busy = 0;
  81 
  82 volatile int    sb_irq_mode = IMODE_NONE;       /*
  83 
  84 
  85                                                  * *  * * IMODE_INPUT, *
  86                                                  * IMODE_OUTPUT * * or *
  87                                                  * IMODE_NONE   */
  88 static volatile int irq_ok = 0;
  89 
  90 #ifdef JAZZ16
  91 /* 16 bit support
  92  */
  93 
  94 static int      dsp_16bit = 0;
  95 static int      dma8 = 1;
  96 static int      dma16 = 5;
  97 
  98 static int      dsp_set_bits (int arg);
  99 static int      initialize_ProSonic16 (void);
 100 
 101 /* end of 16 bit support
 102  */
 103 #endif
 104 
 105 int             sb_duplex_midi = 0;
 106 static int      my_dev = 0;
 107 
 108 volatile int    sb_intr_active = 0;
 109 
 110 static int      dsp_speed (int);
 111 static int      dsp_set_stereo (int mode);
 112 int             sb_dsp_command (unsigned char val);
 113 
 114 #if !defined(EXCLUDE_MIDI) || !defined(EXCLUDE_AUDIO)
 115 
 116 /*
 117  * Common code for the midi and pcm functions
 118  */
 119 
 120 int
 121 sb_dsp_command (unsigned char val)
     /* [previous][next][first][last][top][bottom][index][help] */
 122 {
 123   int             i;
 124   unsigned long   limit;
 125 
 126   limit = GET_TIME () + HZ / 10;        /*
 127                                            * The timeout is 0.1 secods
 128                                          */
 129 
 130   /*
 131    * Note! the i<500000 is an emergency exit. The sb_dsp_command() is sometimes
 132    * called while interrupts are disabled. This means that the timer is
 133    * disabled also. However the timeout situation is a abnormal condition.
 134    * Normally the DSP should be ready to accept commands after just couple of
 135    * loops.
 136    */
 137 
 138   for (i = 0; i < 500000 && GET_TIME () < limit; i++)
 139     {
 140       if ((INB (DSP_STATUS) & 0x80) == 0)
 141         {
 142           OUTB (val, DSP_COMMAND);
 143           return 1;
 144         }
 145     }
 146 
 147   printk ("SoundBlaster: DSP Command(%x) Timeout.\n", val);
 148   printk ("IRQ conflict???\n");
 149   return 0;
 150 }
 151 
 152 void
 153 sbintr (INT_HANDLER_PARMS (irq, dummy))
     /* [previous][next][first][last][top][bottom][index][help] */
 154 {
 155   int             status;
 156 
 157 #ifndef EXCLUDE_SBPRO
 158   if (sb16)
 159     {
 160       unsigned char   src = sb_getmixer (IRQ_STAT);     /* Interrupt source register */
 161 
 162 #ifndef EXCLUDE_SB16
 163       if (src & 3)
 164         sb16_dsp_interrupt (irq);
 165 
 166 #ifndef EXCLUDE_MIDI
 167       if (src & 4)
 168         sb16midiintr (irq);     /*
 169                                  * SB MPU401 interrupt
 170                                  */
 171 #endif
 172 
 173 #endif
 174 
 175       if (!(src & 1))
 176         return;                 /*
 177                                  * Not a DSP interupt
 178                                  */
 179     }
 180 #endif
 181 
 182   status = INB (DSP_DATA_AVAIL);        /*
 183                                            * Clear interrupt
 184                                          */
 185 
 186   if (sb_intr_active)
 187     switch (sb_irq_mode)
 188       {
 189       case IMODE_OUTPUT:
 190         sb_intr_active = 0;
 191         DMAbuf_outputintr (my_dev, 1);
 192         break;
 193 
 194       case IMODE_INPUT:
 195         sb_intr_active = 0;
 196         DMAbuf_inputintr (my_dev);
 197         /*
 198          * A complete buffer has been input. Let's start new one
 199          */
 200         break;
 201 
 202       case IMODE_INIT:
 203         sb_intr_active = 0;
 204         irq_ok = 1;
 205         break;
 206 
 207       case IMODE_MIDI:
 208 #ifndef EXCLUDE_MIDI
 209         sb_midi_interrupt (irq);
 210 #endif
 211         break;
 212 
 213       default:
 214         printk ("SoundBlaster: Unexpected interrupt\n");
 215       }
 216 }
 217 
 218 static int      sb_irq_usecount = 0;
 219 
 220 int
 221 sb_get_irq (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 222 {
 223   int             ok;
 224 
 225   if (!sb_irq_usecount)
 226     if ((ok = snd_set_irq_handler (sbc_irq, sbintr, "SoundBlaster")) < 0)
 227       return ok;
 228 
 229   sb_irq_usecount++;
 230 
 231   return 0;
 232 }
 233 
 234 void
 235 sb_free_irq (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 236 {
 237   if (!sb_irq_usecount)
 238     return;
 239 
 240   sb_irq_usecount--;
 241 
 242   if (!sb_irq_usecount)
 243     snd_release_irq (sbc_irq);
 244 }
 245 
 246 int
 247 sb_reset_dsp (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 248 {
 249   int             loopc;
 250 
 251   OUTB (1, DSP_RESET);
 252   tenmicrosec ();
 253   OUTB (0, DSP_RESET);
 254   tenmicrosec ();
 255   tenmicrosec ();
 256   tenmicrosec ();
 257 
 258   for (loopc = 0; loopc < 1000 && !(INB (DSP_DATA_AVAIL) & 0x80); loopc++);     /*
 259                                                                                  * Wait
 260                                                                                  * for
 261                                                                                  * data
 262                                                                                  * *
 263                                                                                  * available
 264                                                                                  * status
 265                                                                                  */
 266 
 267   if (INB (DSP_READ) != 0xAA)
 268     return 0;                   /*
 269                                  * Sorry
 270                                  */
 271 
 272   return 1;
 273 }
 274 
 275 #endif
 276 
 277 #ifndef EXCLUDE_AUDIO
 278 
 279 static void
 280 dsp_speaker (char state)
     /* [previous][next][first][last][top][bottom][index][help] */
 281 {
 282   if (state)
 283     sb_dsp_command (DSP_CMD_SPKON);
 284   else
 285     sb_dsp_command (DSP_CMD_SPKOFF);
 286 }
 287 
 288 static int
 289 dsp_speed (int speed)
     /* [previous][next][first][last][top][bottom][index][help] */
 290 {
 291   unsigned char   tconst;
 292   unsigned long   flags;
 293   int             max_speed = 44100;
 294 
 295   if (speed < 4000)
 296     speed = 4000;
 297 
 298   /*
 299      * Older SB models don't support higher speeds than 22050.
 300    */
 301 
 302   if (sbc_major < 2 ||
 303       (sbc_major == 2 && sbc_minor == 0))
 304     max_speed = 22050;
 305 
 306   /*
 307      * SB models earlier than SB Pro have low limit for the input speed.
 308    */
 309   if (open_mode != OPEN_WRITE)  /* Recording is possible */
 310     if (sbc_major < 3)          /* Limited input speed with these cards */
 311       if (sbc_major == 2 && sbc_minor > 0)
 312         max_speed = 15000;
 313       else
 314         max_speed = 13000;
 315 
 316   if (speed > max_speed)
 317     speed = max_speed;          /*
 318                                  * Invalid speed
 319                                  */
 320 
 321   /* Logitech SoundMan Games and Jazz16 cards can support 44.1kHz stereo */
 322 #if !defined (SM_GAMES)
 323   /*
 324    * Max. stereo speed is 22050
 325    */
 326   if (dsp_stereo && speed > 22050 && Jazz16_detected == 0)
 327     speed = 22050;
 328 #endif
 329 
 330   if ((speed > 22050) && sb_midi_busy)
 331     {
 332       printk ("SB Warning: High speed DSP not possible simultaneously with MIDI output\n");
 333       speed = 22050;
 334     }
 335 
 336   if (dsp_stereo)
 337     speed *= 2;
 338 
 339   /*
 340    * Now the speed should be valid
 341    */
 342 
 343   if (speed > 22050)
 344     {                           /*
 345                                  * High speed mode
 346                                  */
 347       int             tmp;
 348 
 349       tconst = (unsigned char) ((65536 -
 350                                  ((256000000 + speed / 2) / speed)) >> 8);
 351       sb_dsp_highspeed = 1;
 352 
 353       DISABLE_INTR (flags);
 354       if (sb_dsp_command (0x40))
 355         sb_dsp_command (tconst);
 356       RESTORE_INTR (flags);
 357 
 358       tmp = 65536 - (tconst << 8);
 359       speed = (256000000 + tmp / 2) / tmp;
 360     }
 361   else
 362     {
 363       int             tmp;
 364 
 365       sb_dsp_highspeed = 0;
 366       tconst = (256 - ((1000000 + speed / 2) / speed)) & 0xff;
 367 
 368       DISABLE_INTR (flags);
 369       if (sb_dsp_command (0x40))        /*
 370                                          * Set time constant
 371                                          */
 372         sb_dsp_command (tconst);
 373       RESTORE_INTR (flags);
 374 
 375       tmp = 256 - tconst;
 376       speed = (1000000 + tmp / 2) / tmp;
 377     }
 378 
 379   if (dsp_stereo)
 380     speed /= 2;
 381 
 382   dsp_current_speed = speed;
 383   return speed;
 384 }
 385 
 386 static int
 387 dsp_set_stereo (int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 388 {
 389   dsp_stereo = 0;
 390 
 391 #ifdef EXCLUDE_SBPRO
 392   return 0;
 393 #else
 394   if (sbc_major < 3 || sb16)
 395     return 0;                   /*
 396                                  * Sorry no stereo
 397                                  */
 398 
 399   if (mode && sb_midi_busy)
 400     {
 401       printk ("SB Warning: Stereo DSP not possible simultaneously with MIDI output\n");
 402       return 0;
 403     }
 404 
 405   dsp_stereo = !!mode;
 406   return dsp_stereo;
 407 #endif
 408 }
 409 
 410 static void
 411 sb_dsp_output_block (int dev, unsigned long buf, int count,
     /* [previous][next][first][last][top][bottom][index][help] */
 412                      int intrflag, int restart_dma)
 413 {
 414   unsigned long   flags;
 415 
 416   if (!sb_irq_mode)
 417     dsp_speaker (ON);
 418 
 419   sb_irq_mode = IMODE_OUTPUT;
 420   DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE);
 421 
 422   if (audio_devs[dev]->dmachan > 3)
 423     count >>= 1;
 424   count--;
 425 
 426   if (sb_dsp_highspeed)
 427     {
 428       DISABLE_INTR (flags);
 429       if (sb_dsp_command (0x48))        /*
 430                                            * High speed size
 431                                          */
 432         {
 433           sb_dsp_command ((unsigned char) (count & 0xff));
 434           sb_dsp_command ((unsigned char) ((count >> 8) & 0xff));
 435           sb_dsp_command (0x91);        /*
 436                                            * High speed 8 bit DAC
 437                                          */
 438         }
 439       else
 440         printk ("SB Error: Unable to start (high speed) DAC\n");
 441       RESTORE_INTR (flags);
 442     }
 443   else
 444     {
 445       DISABLE_INTR (flags);
 446       if (sb_dsp_command (0x14))        /*
 447                                            * 8-bit DAC (DMA)
 448                                          */
 449         {
 450           sb_dsp_command ((unsigned char) (count & 0xff));
 451           sb_dsp_command ((unsigned char) ((count >> 8) & 0xff));
 452         }
 453       else
 454         printk ("SB Error: Unable to start DAC\n");
 455       RESTORE_INTR (flags);
 456     }
 457   sb_intr_active = 1;
 458 }
 459 
 460 static void
 461 sb_dsp_start_input (int dev, unsigned long buf, int count, int intrflag,
     /* [previous][next][first][last][top][bottom][index][help] */
 462                     int restart_dma)
 463 {
 464   /*
 465    * Start a DMA input to the buffer pointed by dmaqtail
 466    */
 467 
 468   unsigned long   flags;
 469 
 470   if (!sb_irq_mode)
 471     dsp_speaker (OFF);
 472 
 473   sb_irq_mode = IMODE_INPUT;
 474   DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ);
 475 
 476   if (audio_devs[dev]->dmachan > 3)
 477     count >>= 1;
 478   count--;
 479 
 480   if (sb_dsp_highspeed)
 481     {
 482       DISABLE_INTR (flags);
 483       if (sb_dsp_command (0x48))        /*
 484                                            * High speed size
 485                                          */
 486         {
 487           sb_dsp_command ((unsigned char) (count & 0xff));
 488           sb_dsp_command ((unsigned char) ((count >> 8) & 0xff));
 489           sb_dsp_command (0x99);        /*
 490                                            * High speed 8 bit ADC
 491                                          */
 492         }
 493       else
 494         printk ("SB Error: Unable to start (high speed) ADC\n");
 495       RESTORE_INTR (flags);
 496     }
 497   else
 498     {
 499       DISABLE_INTR (flags);
 500       if (sb_dsp_command (0x24))        /*
 501                                            * 8-bit ADC (DMA)
 502                                          */
 503         {
 504           sb_dsp_command ((unsigned char) (count & 0xff));
 505           sb_dsp_command ((unsigned char) ((count >> 8) & 0xff));
 506         }
 507       else
 508         printk ("SB Error: Unable to start ADC\n");
 509       RESTORE_INTR (flags);
 510     }
 511 
 512   sb_intr_active = 1;
 513 }
 514 
 515 static void
 516 dsp_cleanup (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 517 {
 518   sb_intr_active = 0;
 519 }
 520 
 521 static int
 522 sb_dsp_prepare_for_input (int dev, int bsize, int bcount)
     /* [previous][next][first][last][top][bottom][index][help] */
 523 {
 524   dsp_cleanup ();
 525   dsp_speaker (OFF);
 526 
 527   if (sbc_major == 3)           /*
 528                                  * SB Pro
 529                                  */
 530     {
 531 #ifdef JAZZ16
 532       /* Select correct dma channel
 533          * for 16/8 bit acccess
 534        */
 535       audio_devs[my_dev]->dmachan = dsp_16bit ? dma16 : dma8;
 536       if (dsp_stereo)
 537         sb_dsp_command (dsp_16bit ? 0xac : 0xa8);
 538       else
 539         sb_dsp_command (dsp_16bit ? 0xa4 : 0xa0);
 540 #else
 541       /* 8 bit only cards use this
 542        */
 543       if (dsp_stereo)
 544         sb_dsp_command (0xa8);
 545       else
 546         sb_dsp_command (0xa0);
 547 #endif
 548       dsp_speed (dsp_current_speed);    /*
 549                                          * Speed must be recalculated if
 550                                          * #channels * changes
 551                                          */
 552     }
 553   return 0;
 554 }
 555 
 556 static int
 557 sb_dsp_prepare_for_output (int dev, int bsize, int bcount)
     /* [previous][next][first][last][top][bottom][index][help] */
 558 {
 559   dsp_cleanup ();
 560   dsp_speaker (ON);
 561 
 562 #ifndef EXCLUDE_SBPRO
 563   if (sbc_major == 3)           /*
 564                                  * SB Pro
 565                                  */
 566     {
 567 #ifdef JAZZ16
 568       /* 16 bit specific instructions
 569        */
 570       audio_devs[my_dev]->dmachan = dsp_16bit ? dma16 : dma8;
 571       if (Jazz16_detected != 2) /* SM Wave */
 572         sb_mixer_set_stereo (dsp_stereo);
 573       if (dsp_stereo)
 574         sb_dsp_command (dsp_16bit ? 0xac : 0xa8);
 575       else
 576         sb_dsp_command (dsp_16bit ? 0xa4 : 0xa0);
 577 #else
 578       sb_mixer_set_stereo (dsp_stereo);
 579 #endif
 580       dsp_speed (dsp_current_speed);    /*
 581                                          * Speed must be recalculated if
 582                                          * #channels * changes
 583                                          */
 584     }
 585 #endif
 586   return 0;
 587 }
 588 
 589 static void
 590 sb_dsp_halt_xfer (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 591 {
 592 }
 593 
 594 static int
 595 verify_irq (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 596 {
 597 #if 0
 598   DEFINE_WAIT_QUEUE (testq, testf);
 599 
 600   irq_ok = 0;
 601 
 602   if (sb_get_irq () == -1)
 603     {
 604       printk ("*** SB Error: Irq %d already in use\n", sbc_irq);
 605       return 0;
 606     }
 607 
 608 
 609   sb_irq_mode = IMODE_INIT;
 610 
 611   sb_dsp_command (0xf2);        /*
 612                                  * This should cause immediate interrupt
 613                                  */
 614 
 615   DO_SLEEP (testq, testf, HZ / 5);
 616 
 617   sb_free_irq ();
 618 
 619   if (!irq_ok)
 620     {
 621       printk ("SB Warning: IRQ%d test not passed!", sbc_irq);
 622       irq_ok = 1;
 623     }
 624 #else
 625   irq_ok = 1;
 626 #endif
 627   return irq_ok;
 628 }
 629 
 630 static int
 631 sb_dsp_open (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 632 {
 633   int             retval;
 634 
 635   if (!sb_dsp_ok)
 636     {
 637       printk ("SB Error: SoundBlaster board not installed\n");
 638       return RET_ERROR (ENXIO);
 639     }
 640 
 641   if (sb_no_recording && mode & OPEN_READ)
 642     {
 643       printk ("SB Error: Recording not supported by this device\n");
 644       return RET_ERROR (ENOTTY);
 645     }
 646 
 647   if (sb_intr_active || (sb_midi_busy && sb_midi_mode == UART_MIDI))
 648     {
 649       printk ("SB: PCM not possible during MIDI input\n");
 650       return RET_ERROR (EBUSY);
 651     }
 652 
 653   if (!irq_verified)
 654     {
 655       verify_irq ();
 656       irq_verified = 1;
 657     }
 658   else if (!irq_ok)
 659     printk ("SB Warning: Incorrect IRQ setting %d\n",
 660             sbc_irq);
 661 
 662   retval = sb_get_irq ();
 663   if (retval)
 664     return retval;
 665 
 666   /* Allocate 8 bit dma
 667    */
 668 #ifdef JAZZ16
 669   audio_devs[my_dev]->dmachan = dma8;
 670 #endif
 671 
 672   if (DMAbuf_open_dma (dev) < 0)
 673     {
 674       sb_free_irq ();
 675       printk ("SB: DMA Busy\n");
 676       return RET_ERROR (EBUSY);
 677     }
 678 #ifdef JAZZ16
 679   /* Allocate 16 bit dma
 680    */
 681   if (Jazz16_detected != 0)
 682     if (dma16 != dma8)
 683       {
 684         if (ALLOC_DMA_CHN (dma16, "Jazz16 16 bit"))
 685           {
 686             sb_free_irq ();
 687             DMAbuf_close_dma (dev);
 688             return RET_ERROR (EBUSY);
 689           }
 690       }
 691 #endif
 692 
 693   sb_irq_mode = IMODE_NONE;
 694 
 695   sb_dsp_busy = 1;
 696   open_mode = mode;
 697 
 698   return 0;
 699 }
 700 
 701 static void
 702 sb_dsp_close (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 703 {
 704 #ifdef JAZZ16
 705   /* Release 16 bit dma channel
 706    */
 707   if (Jazz16_detected)
 708     {
 709       if (audio_devs[my_dev]->dmachan == dma8)
 710         RELEASE_DMA_CHN (dma16);
 711       else
 712         RELEASE_DMA_CHN (dma8);
 713 
 714     }
 715 #endif
 716 
 717   DMAbuf_close_dma (dev);
 718   sb_free_irq ();
 719   dsp_cleanup ();
 720   dsp_speaker (OFF);
 721   sb_dsp_busy = 0;
 722   sb_dsp_highspeed = 0;
 723   open_mode = 0;
 724 }
 725 
 726 #ifdef JAZZ16
 727 /* Function dsp_set_bits() only required for 16 bit cards
 728  */
 729 static int
 730 dsp_set_bits (int arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 731 {
 732   if (arg)
 733     if (Jazz16_detected == 0)
 734       dsp_16bit = 0;
 735     else
 736       switch (arg)
 737         {
 738         case 8:
 739           dsp_16bit = 0;
 740           break;
 741         case 16:
 742           dsp_16bit = 1;
 743           break;
 744         default:
 745           dsp_16bit = 0;
 746         }
 747   return dsp_16bit ? 16 : 8;
 748 }
 749 
 750 #endif /* ifdef JAZZ16 */
 751 
 752 static int
 753 sb_dsp_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
     /* [previous][next][first][last][top][bottom][index][help] */
 754 {
 755   switch (cmd)
 756     {
 757     case SOUND_PCM_WRITE_RATE:
 758       if (local)
 759         return dsp_speed (arg);
 760       return IOCTL_OUT (arg, dsp_speed (IOCTL_IN (arg)));
 761       break;
 762 
 763     case SOUND_PCM_READ_RATE:
 764       if (local)
 765         return dsp_current_speed;
 766       return IOCTL_OUT (arg, dsp_current_speed);
 767       break;
 768 
 769     case SOUND_PCM_WRITE_CHANNELS:
 770       if (local)
 771         return dsp_set_stereo (arg - 1) + 1;
 772       return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg) - 1) + 1);
 773       break;
 774 
 775     case SOUND_PCM_READ_CHANNELS:
 776       if (local)
 777         return dsp_stereo + 1;
 778       return IOCTL_OUT (arg, dsp_stereo + 1);
 779       break;
 780 
 781     case SNDCTL_DSP_STEREO:
 782       if (local)
 783         return dsp_set_stereo (arg);
 784       return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg)));
 785       break;
 786 
 787 #ifdef JAZZ16
 788       /* Word size specific cases here.
 789          * SNDCTL_DSP_SETFMT=SOUND_PCM_WRITE_BITS
 790        */
 791     case SNDCTL_DSP_SETFMT:
 792       if (local)
 793         return dsp_set_bits (arg);
 794       return IOCTL_OUT (arg, dsp_set_bits (IOCTL_IN (arg)));
 795       break;
 796 
 797     case SOUND_PCM_READ_BITS:
 798       if (local)
 799         return dsp_16bit ? 16 : 8;
 800       return IOCTL_OUT (arg, dsp_16bit ? 16 : 8);
 801       break;
 802 #else
 803     case SOUND_PCM_WRITE_BITS:
 804     case SOUND_PCM_READ_BITS:
 805       if (local)
 806         return 8;
 807       return IOCTL_OUT (arg, 8);        /*
 808                                            * Only 8 bits/sample supported
 809                                          */
 810       break;
 811 #endif /* ifdef JAZZ16  */
 812 
 813     case SOUND_PCM_WRITE_FILTER:
 814     case SOUND_PCM_READ_FILTER:
 815       return RET_ERROR (EINVAL);
 816       break;
 817 
 818     default:
 819       return RET_ERROR (EINVAL);
 820     }
 821 
 822   return RET_ERROR (EINVAL);
 823 }
 824 
 825 static void
 826 sb_dsp_reset (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 827 {
 828   unsigned long   flags;
 829 
 830   DISABLE_INTR (flags);
 831 
 832   sb_reset_dsp ();
 833   dsp_speed (dsp_current_speed);
 834   dsp_cleanup ();
 835 
 836   RESTORE_INTR (flags);
 837 }
 838 
 839 #endif
 840 
 841 
 842 #ifdef JAZZ16
 843 
 844 /*
 845  * Initialization of a Media Vision ProSonic 16 Soundcard.
 846  * The function initializes a ProSonic 16 like PROS.EXE does for DOS. It sets
 847  * the base address, the DMA-channels, interrupts and enables the joystickport.
 848  *
 849  * Also used by Jazz 16 (same card, different name)
 850  *
 851  * written 1994 by Rainer Vranken
 852  * E-Mail: rvranken@polaris.informatik.uni-essen.de
 853  */
 854 
 855 
 856 #ifndef MPU_BASE                /* take default values if not specified */
 857 #define MPU_BASE 0
 858 #endif
 859 #ifndef MPU_IRQ
 860 #define MPU_IRQ 0
 861 #endif
 862 
 863 unsigned int
 864 get_sb_byte (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 865 {
 866   int             i;
 867 
 868   for (i = 1000; i; i--)
 869     if (INB (DSP_DATA_AVAIL) & 0x80)
 870       {
 871         return INB (DSP_READ);
 872       }
 873 
 874   return 0xffff;
 875 }
 876 
 877 #ifdef SM_WAVE
 878 /*
 879  * Logitech Soundman Wave detection and initialization by Hannu Savolainen.
 880  *
 881  * There is a microcontroller (8031) in the SM Wave card for MIDI emulation.
 882  * it's located at address MPU_BASE+4.  MPU_BASE+7 is a SM Wave specific
 883  * control register for MC reset, SCSI, OPL4 and DSP (future expansion)
 884  * address decoding. Otherwise the SM Wave is just a ordinary MV Jazz16
 885  * based soundcard.
 886  */
 887 
 888 static void
 889 smw_putmem (int base, int addr, unsigned char val)
     /* [previous][next][first][last][top][bottom][index][help] */
 890 {
 891   unsigned long   flags;
 892 
 893   DISABLE_INTR (flags);
 894 
 895   OUTB (addr & 0xff, base + 1); /* Low address bits */
 896   OUTB (addr >> 8, base + 2);   /* High address bits */
 897   OUTB (val, base);             /* Data */
 898 
 899   RESTORE_INTR (flags);
 900 }
 901 
 902 static unsigned char
 903 smw_getmem (int base, int addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 904 {
 905   unsigned long   flags;
 906   unsigned char   val;
 907 
 908   DISABLE_INTR (flags);
 909 
 910   OUTB (addr & 0xff, base + 1); /* Low address bits */
 911   OUTB (addr >> 8, base + 2);   /* High address bits */
 912   val = INB (base);             /* Data */
 913 
 914   RESTORE_INTR (flags);
 915   return val;
 916 }
 917 
 918 static int
 919 initialize_smw (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 920 {
 921 #ifdef SMW_MIDI0001_INCLUDED
 922 #include "smw-midi0001.h"
 923 #else
 924   unsigned char   smw_ucode[1];
 925   int             smw_ucodeLen = 0;
 926 
 927 #endif
 928 
 929   int             mp_base = MPU_BASE + 4;       /* Microcontroller base */
 930   int             i;
 931   unsigned char   control;
 932 
 933   /*
 934      *  Reset the microcontroller so that the RAM can be accessed
 935    */
 936 
 937   control = INB (MPU_BASE + 7);
 938   OUTB (control | 3, MPU_BASE + 7);     /* Set last two bits to 1 (?) */
 939   OUTB ((control & 0xfe) | 2, MPU_BASE + 7);    /* xxxxxxx0 resets the mc */
 940 
 941   for (i = 0; i < 300; i++)     /* Wait at least 1ms */
 942     tenmicrosec ();
 943 
 944   OUTB (control & 0xfc, MPU_BASE + 7);  /* xxxxxx00 enables RAM */
 945 
 946   /*
 947      *  Detect microcontroller by probing the 8k RAM area
 948    */
 949   smw_putmem (mp_base, 0, 0x00);
 950   smw_putmem (mp_base, 1, 0xff);
 951   tenmicrosec ();
 952 
 953   if (smw_getmem (mp_base, 0) != 0x00 || smw_getmem (mp_base, 1) != 0xff)
 954     {
 955       printk ("\nSM Wave: No microcontroller RAM detected (%02x, %02x)\n",
 956               smw_getmem (mp_base, 0), smw_getmem (mp_base, 1));
 957       return 0;                 /* No RAM */
 958     }
 959 
 960   /*
 961      *  There is RAM so assume it's really a SM Wave
 962    */
 963 
 964 #ifdef SMW_MIDI0001_INCLUDED
 965   if (smw_ucodeLen != 8192)
 966     {
 967       printk ("\nSM Wave: Invalid microcode (MIDI0001.BIN) length\n");
 968       return 1;
 969     }
 970 #endif
 971 
 972   /*
 973      *  Download microcode
 974    */
 975 
 976   for (i = 0; i < 8192; i++)
 977     smw_putmem (mp_base, i, smw_ucode[i]);
 978 
 979   /*
 980      *  Verify microcode
 981    */
 982 
 983   for (i = 0; i < 8192; i++)
 984     if (smw_getmem (mp_base, i) != smw_ucode[i])
 985       {
 986         printk ("SM Wave: Microcode verification failed\n");
 987         return 0;
 988       }
 989 
 990   control = 0;
 991 #ifdef SMW_SCSI_IRQ
 992   /*
 993      * Set the SCSI interrupt (IRQ2/9, IRQ3 or IRQ10). The SCSI interrupt
 994      * is disabled by default.
 995      *
 996      * Btw the Zilog 5380 SCSI controller is located at MPU base + 0x10.
 997    */
 998   {
 999     static unsigned char scsi_irq_bits[] =
1000     {0, 0, 3, 1, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0};
1001 
1002     control |= scsi_irq_bits[SMW_SCSI_IRQ] << 6;
1003   }
1004 #endif
1005 
1006 #ifdef SMW_OPL4_ENABLE
1007   /*
1008      *  Make the OPL4 chip visible on the PC bus at 0x380.
1009      *
1010      *  There is no need to enable this feature since VoxWare
1011      *  doesn't support OPL4 yet. Also there is no RAM in SM Wave so
1012      *  enabling OPL4 is pretty useless.
1013    */
1014   control |= 0x10;              /* Uses IRQ12 if bit 0x20 == 0 */
1015   /* control |= 0x20;      Uncomment this if you want to use IRQ7 */
1016 #endif
1017 
1018   OUTB (control | 0x03, MPU_BASE + 7);  /* xxxxxx11 restarts */
1019   return 1;
1020 }
1021 
1022 #endif
1023 
1024 static int
1025 initialize_ProSonic16 (void)
     /* [previous][next][first][last][top][bottom][index][help] */
1026 {
1027   int             x;
1028   static unsigned char int_translat[16] =
1029   {0, 0, 2, 3, 0, 1, 0, 4, 0, 2, 5, 0, 0, 0, 0, 6}, dma_translat[8] =
1030   {0, 1, 0, 2, 0, 3, 0, 4};
1031 
1032   OUTB (0xAF, 0x201);           /* ProSonic/Jazz16 wakeup */
1033   for (x = 0; x < 1000; ++x)    /* wait 10 milliseconds */
1034     tenmicrosec ();
1035   OUTB (0x50, 0x201);
1036   OUTB ((sbc_base & 0x70) | ((MPU_BASE & 0x30) >> 4), 0x201);
1037 
1038   if (sb_reset_dsp ())
1039     {                           /* OK. We have at least a SB */
1040 
1041       /* Check the version number of ProSonic (I guess) */
1042 
1043       if (!sb_dsp_command (0xFA))
1044         return 1;
1045       if (get_sb_byte () != 0x12)
1046         return 1;
1047 
1048       if (sb_dsp_command (0xFB) &&      /* set DMA-channels and Interrupts */
1049           sb_dsp_command ((dma_translat[JAZZ_DMA16] << 4) | dma_translat[SBC_DMA]) &&
1050       sb_dsp_command ((int_translat[MPU_IRQ] << 4) | int_translat[sbc_irq]))
1051         {
1052           Jazz16_detected = 1;
1053 #ifdef SM_WAVE
1054           if (initialize_smw ())
1055             Jazz16_detected = 2;
1056 #endif
1057           sb_dsp_disable_midi ();
1058         }
1059 
1060       return 1;                 /* There was at least a SB */
1061     }
1062   return 0;                     /* No SB or ProSonic16 detected */
1063 }
1064 
1065 #endif /* ifdef JAZZ16  */
1066 
1067 int
1068 sb_dsp_detect (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
1069 {
1070   sbc_base = hw_config->io_base;
1071   sbc_irq = hw_config->irq;
1072 
1073   if (sb_dsp_ok)
1074     return 0;                   /*
1075                                  * Already initialized
1076                                  */
1077 #ifdef JAZZ16
1078   dma8 = hw_config->dma;
1079   dma16 = JAZZ_DMA16;
1080 
1081   if (!initialize_ProSonic16 ())
1082     return 0;
1083 #else
1084   if (!sb_reset_dsp ())
1085     return 0;
1086 #endif
1087 
1088   return 1;                     /*
1089                                  * Detected
1090                                  */
1091 }
1092 
1093 #ifndef EXCLUDE_AUDIO
1094 static struct audio_operations sb_dsp_operations =
1095 {
1096   "SoundBlaster",
1097   NOTHING_SPECIAL,
1098   AFMT_U8,                      /* Just 8 bits. Poor old SB */
1099   NULL,
1100   sb_dsp_open,
1101   sb_dsp_close,
1102   sb_dsp_output_block,
1103   sb_dsp_start_input,
1104   sb_dsp_ioctl,
1105   sb_dsp_prepare_for_input,
1106   sb_dsp_prepare_for_output,
1107   sb_dsp_reset,
1108   sb_dsp_halt_xfer,
1109   NULL,                         /* local_qlen */
1110   NULL                          /* copy_from_user */
1111 };
1112 
1113 #endif
1114 
1115 long
1116 sb_dsp_init (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
1117 {
1118   int             i;
1119   int             mixer_type = 0;
1120 
1121   sbc_major = sbc_minor = 0;
1122   sb_dsp_command (0xe1);        /*
1123                                  * Get version
1124                                  */
1125 
1126   for (i = 1000; i; i--)
1127     {
1128       if (INB (DSP_DATA_AVAIL) & 0x80)
1129         {                       /*
1130                                  * wait for Data Ready
1131                                  */
1132           if (sbc_major == 0)
1133             sbc_major = INB (DSP_READ);
1134           else
1135             {
1136               sbc_minor = INB (DSP_READ);
1137               break;
1138             }
1139         }
1140     }
1141 
1142   if (sbc_major == 0)
1143     {
1144       printk ("\n\nFailed to get SB version (%x) - possible I/O conflict\n\n",
1145               INB (DSP_DATA_AVAIL));
1146       sbc_major = 1;
1147     }
1148 
1149   if (sbc_major == 2 || sbc_major == 3)
1150     sb_duplex_midi = 1;
1151 
1152   if (sbc_major == 4)
1153     sb16 = 1;
1154 
1155 #ifndef EXCLUDE_SBPRO
1156   if (sbc_major >= 3)
1157     mixer_type = sb_mixer_init (sbc_major);
1158 #else
1159   if (sbc_major >= 3)
1160     printk ("\n\n\n\nNOTE! SB Pro support is required with your soundcard!\n\n\n");
1161 #endif
1162 
1163 #ifndef EXCLUDE_YM3812
1164 
1165   if (sbc_major > 3 ||
1166       (sbc_major == 3 && INB (0x388) == 0x00))  /* Should be 0x06 if not OPL-3 */
1167     enable_opl3_mode (OPL3_LEFT, OPL3_RIGHT, OPL3_BOTH);
1168 #endif
1169 
1170 #ifndef EXCLUDE_AUDIO
1171   if (sbc_major >= 3)
1172     {
1173       if (Jazz16_detected)
1174         {
1175           if (Jazz16_detected == 2)
1176             sprintf (sb_dsp_operations.name, "SoundMan Wave %d.%d", sbc_major, sbc_minor);
1177           else
1178             sprintf (sb_dsp_operations.name, "MV Jazz16 %d.%d", sbc_major, sbc_minor);
1179           sb_dsp_operations.format_mask |= AFMT_S16_LE;         /* Hurrah, 16 bits          */
1180         }
1181       else
1182 #ifdef __SGNXPRO__
1183       if (mixer_type == 2)
1184         {
1185           sprintf (sb_dsp_operations.name, "Sound Galaxy NX Pro %d.%d", sbc_major, sbc_minor);
1186         }
1187       else
1188 #endif
1189 
1190       if (sbc_major == 4)
1191         {
1192           sprintf (sb_dsp_operations.name, "SoundBlaster 16 %d.%d", sbc_major, sbc_minor);
1193         }
1194       else
1195         {
1196           sprintf (sb_dsp_operations.name, "SoundBlaster Pro %d.%d", sbc_major, sbc_minor);
1197         }
1198     }
1199   else
1200     {
1201       sprintf (sb_dsp_operations.name, "SoundBlaster %d.%d", sbc_major, sbc_minor);
1202     }
1203 
1204   printk (" <%s>", sb_dsp_operations.name);
1205 
1206 #if !defined(EXCLUDE_SB16) && !defined(EXCLUDE_SBPRO)
1207   if (!sb16)                    /*
1208                                  * There is a better driver for SB16
1209                                  */
1210 #endif
1211     if (num_audiodevs < MAX_AUDIO_DEV)
1212       {
1213         audio_devs[my_dev = num_audiodevs++] = &sb_dsp_operations;
1214         audio_devs[my_dev]->buffcount = DSP_BUFFCOUNT;
1215         audio_devs[my_dev]->buffsize = DSP_BUFFSIZE;
1216         audio_devs[my_dev]->dmachan = hw_config->dma;
1217       }
1218     else
1219       printk ("SB: Too many DSP devices available\n");
1220 #else
1221   printk (" <SoundBlaster (configured without audio support)>");
1222 #endif
1223 
1224 #ifndef EXCLUDE_MIDI
1225   if (!midi_disabled && !sb16)  /*
1226                                  * Midi don't work in the SB emulation mode *
1227                                  * of PAS, SB16 has better midi interface
1228                                  */
1229     sb_midi_init (sbc_major);
1230 #endif
1231 
1232   sb_dsp_ok = 1;
1233   return mem_start;
1234 }
1235 
1236 void
1237 sb_dsp_disable_midi (void)
     /* [previous][next][first][last][top][bottom][index][help] */
1238 {
1239   midi_disabled = 1;
1240 }
1241 
1242 #endif

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