root/drivers/sound/sb_dsp.c

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

DEFINITIONS

This source file includes following definitions.
  1. dsp_command
  2. sbintr
  3. set_dsp_irq
  4. reset_dsp
  5. dsp_speaker
  6. dsp_speed
  7. dsp_set_stereo
  8. sb_dsp_output_block
  9. sb_dsp_start_input
  10. dsp_cleanup
  11. sb_dsp_prepare_for_input
  12. sb_dsp_prepare_for_output
  13. sb_dsp_halt_xfer
  14. sb_dsp_open
  15. sb_dsp_close
  16. sb_dsp_ioctl
  17. sb_dsp_reset
  18. sb_dsp_detect
  19. setmixer
  20. getmixer
  21. detect_mixer
  22. init_mixer
  23. set_filter
  24. mixer_output
  25. sbp_mixer_set
  26. mixer_input
  27. sbp_mixer_get
  28. mixer_set_levels
  29. mixer_set_params
  30. mixer_get_levels
  31. mixer_get_params
  32. sb_mixer_ioctl
  33. sb_midi_open
  34. sb_midi_close
  35. sb_midi_out
  36. sb_midi_start_read
  37. sb_midi_end_read
  38. sb_midi_ioctl
  39. verify_irq
  40. sb_dsp_init
  41. sb_dsp_disable_midi

   1 /*
   2  * linux/kernel/chr_drv/sound/sb_dsp.c
   3  * 
   4  * The low level driver for the SoundBlaster DS chips.
   5  * 
   6  * Copyright by Hannu Savolainen 1993
   7  * 
   8  * Redistribution and use in source and binary forms, with or without
   9  * modification, are permitted provided that the following conditions are
  10  * met: 1. Redistributions of source code must retain the above copyright
  11  * notice, this list of conditions and the following disclaimer. 2.
  12  * Redistributions in binary form must reproduce the above copyright notice,
  13  * this list of conditions and the following disclaimer in the documentation
  14  * and/or other materials provided with the distribution.
  15  * 
  16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
  17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  22  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26  * SUCH DAMAGE.
  27  * 
  28  * The mixer support is based on the SB-BSD 1.5 driver by (C) Steve Haehnichen
  29  * <shaehnic@ucsd.edu>
  30  */
  31 
  32 #include "sound_config.h"
  33 
  34 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB)
  35 
  36 #undef SB_TEST_IRQ
  37 
  38 #define DSP_RESET       (sbc_base + 0x6)
  39 #define DSP_READ        (sbc_base + 0xA)
  40 #define DSP_WRITE       (sbc_base + 0xC)
  41 #define DSP_COMMAND     (sbc_base + 0xC)
  42 #define DSP_STATUS      (sbc_base + 0xC)
  43 #define DSP_DATA_AVAIL  (sbc_base + 0xE)
  44 #define MIXER_ADDR      (sbc_base + 0x4)
  45 #define MIXER_DATA      (sbc_base + 0x5)
  46 #define OPL3_LEFT       (sbc_base + 0x0)
  47 #define OPL3_RIGHT      (sbc_base + 0x2)
  48 #define OPL3_BOTH       (sbc_base + 0x8)
  49 
  50 static int      sbc_base = 0;
  51 static int      sbc_irq = 0;
  52 
  53 #define POSSIBLE_RECORDING_DEVICES      (SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD)
  54 
  55 #define SUPPORTED_MIXER_DEVICES         (SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_LINE | SOUND_MASK_MIC | \
  56                                          SOUND_MASK_CD | SOUND_MASK_VOLUME)
  57 
  58 /*
  59  * Mixer registers
  60  * 
  61  * NOTE!        RECORD_SRC == IN_FILTER
  62  */
  63 
  64 #define VOC_VOL         0x04
  65 #define MIC_VOL         0x0A
  66 #define MIC_MIX         0x0A
  67 #define RECORD_SRC      0x0C
  68 #define IN_FILTER       0x0C
  69 #define OUT_FILTER      0x0E
  70 #define MASTER_VOL      0x22
  71 #define FM_VOL          0x26
  72 #define CD_VOL          0x28
  73 #define LINE_VOL        0x2E
  74 
  75 #define FREQ_HI         (1 << 3)/* Use High-frequency ANFI filters */
  76 #define FREQ_LOW        0       /* Use Low-frequency ANFI filters */
  77 #define FILT_ON         0       /* Yes, 0 to turn it on, 1 for off */
  78 #define FILT_OFF        (1 << 5)
  79 
  80 /* Convenient byte masks */
  81 #define B1(x)   ((x) & 0x01)
  82 #define B2(x)   ((x) & 0x03)
  83 #define B3(x)   ((x) & 0x07)
  84 #define B4(x)   ((x) & 0x0f)
  85 #define B5(x)   ((x) & 0x1f)
  86 #define B6(x)   ((x) & 0x3f)
  87 #define B7(x)   ((x) & 0x7f)
  88 #define B8(x)   ((x) & 0xff)
  89 #define F(x)    (!!(x))         /* 0 or 1 only */
  90 
  91 #define MONO_DAC        0x00
  92 #define STEREO_DAC      0x02
  93 
  94 /* DSP Commands */
  95 
  96 #define DSP_CMD_SPKON           0xD1
  97 #define DSP_CMD_SPKOFF          0xD3
  98 
  99 /*
 100  * The DSP channel can be used either for input or output. Variable
 101  * 'irq_mode' will be set when the program calls read or write first time
 102  * after open. Current version doesn't support mode changes without closing
 103  * and reopening the device. Support for this feature may be implemented in a
 104  * future version of this driver.
 105  */
 106 
 107 #define IMODE_NONE              0
 108 #define IMODE_OUTPUT            1
 109 #define IMODE_INPUT             2
 110 #define IMODE_INIT              3
 111 #define IMODE_MIDI              4
 112 
 113 #define NORMAL_MIDI     0
 114 #define UART_MIDI       1
 115 
 116 static int      sb_dsp_ok = 0;  /* Set to 1 after successful initialization */
 117 static int      midi_disabled = 0;
 118 static int      dsp_highspeed = 0, dsp_stereo = 0;
 119 static int      dsp_current_speed = DSP_DEFAULT_SPEED;
 120 static int      sb16 = 0;
 121 
 122 #ifndef EXCLUDE_SBPRO
 123 static int      rec_devices = SOUND_MASK_MIC;
 124 static int      hi_filter = 0, filter_in = 0, filter_out = 0;
 125 
 126 #endif
 127 
 128 static int      midi_mode = NORMAL_MIDI;
 129 static int      midi_busy = 0;  /* 1 if the process has output to MIDI */
 130 static int      dsp_busy = 0;
 131 
 132 static volatile int irq_mode = IMODE_NONE;      /* IMODE_INPUT, IMODE_OUTPUT
 133                                                  * or IMODE_NONE */
 134 static volatile int irq_ok = 0;
 135 
 136 static int      dsp_model = 1;  /* 1=SB, 2=SB Pro */
 137 static int      duplex_midi = 0;
 138 static int      my_dev = 0;
 139 
 140 static volatile int intr_active = 0;
 141 
 142 static int      dsp_speed (int);
 143 static int      dsp_set_stereo (int mode);
 144 static int      dsp_command (unsigned char val);
 145 
 146 #ifndef EXCLUDE_SBPRO
 147 static void     setmixer (unsigned char port, unsigned char value);
 148 static int      getmixer (unsigned char port);
 149 static void     init_mixer (void);
 150 static int      detect_mixer (void);
 151 
 152 #endif
 153 
 154 #if !defined(EXCLUDE_MIDI) || !defined(EXCLUDE_AUDIO)
 155 
 156 /* Common code for the midi and pcm functions */
 157 
 158 static int
 159 dsp_command (unsigned char val)
     /* [previous][next][first][last][top][bottom][index][help] */
 160 {
 161   int             i, limit;
 162 
 163   limit = GET_TIME () + 10;     /* The timeout is 0.1 secods */
 164 
 165   /*
 166    * Note! the i<5000000 is an emergency exit. The dsp_command() is sometimes
 167    * called while interrupts are disabled. This means that the timer is
 168    * disabled also. However the timeout situation is a abnormal condition.
 169    * Normally the DSP should be ready to accept commands after just couple of
 170    * loops.
 171    */
 172 
 173   for (i = 0; i < 5000000 && GET_TIME () < limit; i++)
 174     {
 175       if ((INB (DSP_STATUS) & 0x80) == 0)
 176         {
 177           OUTB (val, DSP_COMMAND);
 178           return 1;
 179         }
 180     }
 181 
 182   printk ("SoundBlaster: DSP Command(%02x) Timeout.\n", val);
 183   printk ("IRQ conflict???\n");
 184   return 0;
 185 }
 186 
 187 void
 188 sbintr (int unused)
     /* [previous][next][first][last][top][bottom][index][help] */
 189 {
 190   int             status, data;
 191 
 192 #ifndef EXCLUDE_SBPRO
 193   if (sb16)
 194     {
 195       unsigned char   src = getmixer (0x82);    /* Interrupt status register */
 196 
 197       if (!(src & 1))
 198         return;                 /* Not a DSP interupt */
 199     }
 200 #endif
 201 
 202   status = INB (DSP_DATA_AVAIL);/* Clear interrupt */
 203 
 204   if (intr_active)
 205     switch (irq_mode)
 206       {
 207       case IMODE_OUTPUT:
 208         intr_active = 0;
 209         DMAbuf_outputintr (my_dev);
 210         break;
 211 
 212       case IMODE_INPUT:
 213         intr_active = 0;
 214         DMAbuf_inputintr (my_dev);
 215         /* A complete buffer has been input. Let's start new one */
 216         break;
 217 
 218       case IMODE_INIT:
 219         intr_active = 0;
 220         irq_ok = 1;
 221         break;
 222 
 223       case IMODE_MIDI:
 224         printk ("+");
 225         data = INB (DSP_READ);
 226         printk ("%02x", data);
 227 
 228         break;
 229 
 230       default:
 231         printk ("SoundBlaster: Unexpected interrupt\n");
 232       }
 233 }
 234 
 235 static int
 236 set_dsp_irq (int interrupt_level)
     /* [previous][next][first][last][top][bottom][index][help] */
 237 {
 238   int             retcode;
 239 
 240 #ifdef linux
 241   struct sigaction sa;
 242 
 243   sa.sa_handler = sbintr;
 244 
 245 #ifdef SND_SA_INTERRUPT
 246   sa.sa_flags = SA_INTERRUPT;
 247 #else
 248   sa.sa_flags = 0;
 249 #endif
 250 
 251   sa.sa_mask = 0;
 252   sa.sa_restorer = NULL;
 253 
 254   retcode = irqaction (interrupt_level, &sa);
 255 
 256   if (retcode < 0)
 257     {
 258       printk ("SoundBlaster: IRQ%d already in use\n", interrupt_level);
 259     }
 260 
 261 #else
 262   /* #  error Unimplemented for this OS  */
 263 #endif
 264   return retcode;
 265 }
 266 
 267 static int
 268 reset_dsp (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 269 {
 270   int             loopc;
 271 
 272   OUTB (1, DSP_RESET);
 273   tenmicrosec ();
 274   OUTB (0, DSP_RESET);
 275   tenmicrosec ();
 276   tenmicrosec ();
 277   tenmicrosec ();
 278 
 279   for (loopc = 0; loopc < 1000 && !(INB (DSP_DATA_AVAIL) & 0x80); loopc++);     /* Wait for data
 280                                                                                  * available status */
 281 
 282   if (INB (DSP_READ) != 0xAA)
 283     return 0;                   /* Sorry */
 284 
 285   return 1;
 286 }
 287 
 288 #endif
 289 
 290 #ifndef EXCLUDE_AUDIO
 291 
 292 static void
 293 dsp_speaker (char state)
     /* [previous][next][first][last][top][bottom][index][help] */
 294 {
 295   if (state)
 296     dsp_command (DSP_CMD_SPKON);
 297   else
 298     dsp_command (DSP_CMD_SPKOFF);
 299 }
 300 
 301 static int
 302 dsp_speed (int speed)
     /* [previous][next][first][last][top][bottom][index][help] */
 303 {
 304   unsigned char   tconst;
 305   unsigned long   flags;
 306 
 307 
 308   if (speed < 4000)
 309     speed = 4000;
 310 
 311   if (speed > 44100)
 312     speed = 44100;              /* Invalid speed */
 313 
 314   if (dsp_model == 1 && speed > 22050)
 315     speed = 22050;
 316   /* SB Classic doesn't support higher speed */
 317 
 318 
 319   if (dsp_stereo && speed > 22050)
 320     speed = 22050;
 321   /* Max. stereo speed is 22050 */
 322 
 323   if ((speed > 22050) && midi_busy)
 324     {
 325       printk ("SB Warning: High speed DSP not possible simultaneously with MIDI output\n");
 326       speed = 22050;
 327     }
 328 
 329   if (dsp_stereo)
 330     speed <<= 1;
 331 
 332   /* Now the speed should be valid */
 333 
 334   if (speed > 22050)
 335     {                           /* High speed mode */
 336       tconst = (unsigned char) ((65536 - (256000000 / speed)) >> 8);
 337       dsp_highspeed = 1;
 338 
 339       DISABLE_INTR (flags);
 340       if (dsp_command (0x40))
 341         dsp_command (tconst);
 342       RESTORE_INTR (flags);
 343 
 344       speed = (256000000 / (65536 - (tconst << 8)));
 345     }
 346   else
 347     {
 348       dsp_highspeed = 0;
 349       tconst = (256 - (1000000 / speed)) & 0xff;
 350 
 351       DISABLE_INTR (flags);
 352       if (dsp_command (0x40))   /* Set time constant */
 353         dsp_command (tconst);
 354       RESTORE_INTR (flags);
 355 
 356       speed = 1000000 / (256 - tconst);
 357     }
 358 
 359   if (dsp_stereo)
 360     speed >>= 1;
 361 
 362   dsp_current_speed = speed;
 363   return speed;
 364 }
 365 
 366 static int
 367 dsp_set_stereo (int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 368 {
 369   dsp_stereo = 0;
 370 
 371   if (dsp_model == 1 || sb16)
 372     return 0;                   /* Sorry no stereo */
 373 
 374   if (mode && midi_busy)
 375     {
 376       printk ("SB Warning: Stereo DSP not possible simultaneously with MIDI output\n");
 377       return 0;
 378     }
 379 
 380   dsp_stereo = !!mode;
 381 
 382 #ifndef EXCLUDE_SBPRO
 383   setmixer (OUT_FILTER, ((getmixer (OUT_FILTER) & ~STEREO_DAC)
 384                          | (mode ? STEREO_DAC : MONO_DAC)));
 385 #endif
 386   dsp_speed (dsp_current_speed);/* Speed must be recalculated if #channels
 387                                  * changes */
 388   return mode;
 389 }
 390 
 391 static void
 392 sb_dsp_output_block (int dev, unsigned long buf, int count, int intrflag)
     /* [previous][next][first][last][top][bottom][index][help] */
 393 {
 394   unsigned long   flags;
 395 
 396   if (!irq_mode)
 397     dsp_speaker (ON);
 398 
 399   irq_mode = IMODE_OUTPUT;
 400   DMAbuf_start_dma (dev, buf, count, DMA_MODE_WRITE);
 401 
 402   if (sound_dsp_dmachan[dev] > 3)
 403     count >>= 1;
 404   count--;
 405 
 406   if (dsp_highspeed)
 407     {
 408       DISABLE_INTR (flags);
 409       if (dsp_command (0x48))   /* High speed size */
 410         {
 411           dsp_command (count & 0xff);
 412           dsp_command ((count >> 8) & 0xff);
 413           dsp_command (0x91);   /* High speed 8 bit DAC */
 414         }
 415       else
 416         printk ("SB Error: Unable to start (high speed) DAC\n");
 417       RESTORE_INTR (flags);
 418     }
 419   else
 420     {
 421       DISABLE_INTR (flags);
 422       if (dsp_command (0x14))   /* 8-bit DAC (DMA) */
 423         {
 424           dsp_command (count & 0xff);
 425           dsp_command ((count >> 8) & 0xff);
 426         }
 427       else
 428         printk ("SB Error: Unable to start DAC\n");
 429       RESTORE_INTR (flags);
 430     }
 431   intr_active = 1;
 432 }
 433 
 434 static void
 435 sb_dsp_start_input (int dev, unsigned long buf, int count, int intrflag)
     /* [previous][next][first][last][top][bottom][index][help] */
 436 {
 437   /* Start a DMA input to the buffer pointed by dmaqtail */
 438 
 439   unsigned long   flags;
 440 
 441   if (!irq_mode)
 442     dsp_speaker (OFF);
 443 
 444   irq_mode = IMODE_INPUT;
 445   DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ);
 446 
 447   if (sound_dsp_dmachan[dev] > 3)
 448     count >>= 1;
 449   count--;
 450 
 451   if (dsp_highspeed)
 452     {
 453       DISABLE_INTR (flags);
 454       if (dsp_command (0x48))   /* High speed size */
 455         {
 456           dsp_command (count & 0xff);
 457           dsp_command ((count >> 8) & 0xff);
 458           dsp_command (0x99);   /* High speed 8 bit ADC */
 459         }
 460       else
 461         printk ("SB Error: Unable to start (high speed) ADC\n");
 462       RESTORE_INTR (flags);
 463     }
 464   else
 465     {
 466       DISABLE_INTR (flags);
 467       if (dsp_command (0x24))   /* 8-bit ADC (DMA) */
 468         {
 469           dsp_command (count & 0xff);
 470           dsp_command ((count >> 8) & 0xff);
 471         }
 472       else
 473         printk ("SB Error: Unable to start ADC\n");
 474       RESTORE_INTR (flags);
 475     }
 476 
 477   intr_active = 1;
 478 }
 479 
 480 static void
 481 dsp_cleanup (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 482 {
 483   intr_active = 0;
 484 }
 485 
 486 static int
 487 sb_dsp_prepare_for_input (int dev, int bsize, int bcount)
     /* [previous][next][first][last][top][bottom][index][help] */
 488 {
 489   dsp_cleanup ();
 490   dsp_speaker (OFF);
 491   return 0;
 492 }
 493 
 494 static int
 495 sb_dsp_prepare_for_output (int dev, int bsize, int bcount)
     /* [previous][next][first][last][top][bottom][index][help] */
 496 {
 497   dsp_cleanup ();
 498   dsp_speaker (ON);
 499   return 0;
 500 }
 501 
 502 static void
 503 sb_dsp_halt_xfer (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 504 {
 505 }
 506 
 507 static int
 508 sb_dsp_open (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 509 {
 510   int             retval;
 511 
 512   if (!sb_dsp_ok)
 513     {
 514       printk ("SB Error: SoundBlaster board not installed\n");
 515       return RET_ERROR (ENXIO);
 516     }
 517 
 518   if (!irq_ok)
 519     {
 520       printk ("SB Error: Incorrect IRQ setting (%d)\n", sbc_irq);
 521       return RET_ERROR (ENXIO);
 522     }
 523 
 524   if (intr_active || (midi_busy && midi_mode == UART_MIDI))
 525     {
 526       printk ("SB: PCM not possible during MIDI input\n");
 527       return RET_ERROR (EBUSY);
 528     }
 529 
 530   if (mode != OPEN_READ && mode != OPEN_WRITE)
 531     {
 532       printk ("SoundBlaster error: DAC and ACD not possible simultaneously\n");
 533       return RET_ERROR (EINVAL);
 534     }
 535 
 536   retval = set_dsp_irq (sbc_irq);
 537   if (retval)
 538     return retval;
 539 
 540   if (!DMAbuf_open_dma (dev))
 541     {
 542       RELEASE_IRQ (sbc_irq);
 543       printk ("SB: DMA Busy\n");
 544       return RET_ERROR (EBUSY);
 545     }
 546 
 547   dsp_set_stereo (OFF);
 548   dsp_speed (DSP_DEFAULT_SPEED);
 549   irq_mode = IMODE_NONE;
 550 
 551   dsp_busy = 1;
 552 
 553   return 0;
 554 }
 555 
 556 static void
 557 sb_dsp_close (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 558 {
 559   DMAbuf_close_dma (dev);
 560   RELEASE_IRQ (sbc_irq);
 561   dsp_cleanup ();
 562   dsp_speed (DSP_DEFAULT_SPEED);
 563   dsp_set_stereo (OFF);
 564   dsp_speaker (OFF);
 565   dsp_busy = 0;
 566 }
 567 
 568 static int
 569 sb_dsp_ioctl (int dev, unsigned int cmd, unsigned int arg, int local)
     /* [previous][next][first][last][top][bottom][index][help] */
 570 {
 571   switch (cmd)
 572     {
 573     case SOUND_PCM_WRITE_RATE:
 574       if (local)
 575         return dsp_speed (arg);
 576       return IOCTL_OUT (arg, dsp_speed (IOCTL_IN (arg)));
 577       break;
 578 
 579     case SOUND_PCM_READ_RATE:
 580       if (local)
 581         return dsp_current_speed;
 582       return IOCTL_OUT (arg, dsp_current_speed);
 583       break;
 584 
 585     case SOUND_PCM_WRITE_CHANNELS:
 586       return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg) - 1) + 1);
 587       break;
 588 
 589     case SOUND_PCM_READ_CHANNELS:
 590       if (local)
 591         return dsp_stereo + 1;
 592       return IOCTL_OUT (arg, dsp_stereo + 1);
 593       break;
 594 
 595     case SNDCTL_DSP_STEREO:
 596       if (local)
 597         return dsp_set_stereo (arg);
 598       return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg)));
 599       break;
 600 
 601     case SOUND_PCM_WRITE_BITS:
 602     case SOUND_PCM_READ_BITS:
 603       if (local)
 604         return 8;
 605       return IOCTL_OUT (arg, 8);/* Only 8 bits/sample supported */
 606       break;
 607 
 608     case SOUND_PCM_WRITE_FILTER:
 609     case SOUND_PCM_READ_FILTER:
 610       return RET_ERROR (EINVAL);
 611       break;
 612 
 613     default:
 614       return RET_ERROR (EINVAL);
 615     }
 616 
 617   return RET_ERROR (EINVAL);
 618 }
 619 
 620 static void
 621 sb_dsp_reset (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 622 {
 623   unsigned long   flags;
 624 
 625   DISABLE_INTR (flags);
 626 
 627   reset_dsp ();
 628   dsp_cleanup ();
 629 
 630   RESTORE_INTR (flags);
 631 }
 632 
 633 #endif
 634 
 635 int
 636 sb_dsp_detect (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 637 {
 638   sbc_base = hw_config->io_base;
 639   sbc_irq = hw_config->irq;
 640 
 641   if (sb_dsp_ok)
 642     return 0;                   /* Already initialized */
 643 
 644   if (!reset_dsp ())
 645     return 0;
 646 
 647   return 1;                     /* Detected */
 648 }
 649 
 650 #ifndef EXCLUDE_SBPRO
 651 
 652 static void
 653 setmixer (unsigned char port, unsigned char value)
     /* [previous][next][first][last][top][bottom][index][help] */
 654 {
 655   OUTB (port, MIXER_ADDR);      /* Select register */
 656   tenmicrosec ();
 657   OUTB (value, MIXER_DATA);
 658   tenmicrosec ();
 659 }
 660 
 661 static int
 662 getmixer (unsigned char port)
     /* [previous][next][first][last][top][bottom][index][help] */
 663 {
 664   int             val;
 665 
 666   OUTB (port, MIXER_ADDR);      /* Select register */
 667   tenmicrosec ();
 668   val = INB (MIXER_DATA);
 669   tenmicrosec ();
 670 
 671   return val;
 672 }
 673 
 674 static int
 675 detect_mixer (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 676 {
 677   /*
 678    * Detect the mixer by changing parameters of two volume channels. If the
 679    * values read back match with the values written, the mixer is there (is
 680    * it?)
 681    */
 682   setmixer (FM_VOL, 0xff);
 683   setmixer (VOC_VOL, 0x33);
 684 
 685   if (getmixer (FM_VOL) != 0xff)
 686     return 0;                   /* No match */
 687   if (getmixer (VOC_VOL) != 0x33)
 688     return 0;
 689 
 690   return 1;
 691 }
 692 
 693 static void
 694 init_mixer (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 695 {
 696   setmixer (MASTER_VOL, 0xbb);
 697   setmixer (VOC_VOL, 0x99);
 698   setmixer (LINE_VOL, 0xbb);
 699   setmixer (FM_VOL, 0x99);
 700   setmixer (CD_VOL, 0x11);
 701   setmixer (MIC_MIX, 0x11);
 702   setmixer (RECORD_SRC, 0x31);
 703   setmixer (OUT_FILTER, 0x31);
 704 }
 705 
 706 static void
 707 set_filter (int record_source, int hifreq_filter, int filter_input, int filter_output)
     /* [previous][next][first][last][top][bottom][index][help] */
 708 {
 709   setmixer (RECORD_SRC, (record_source
 710                          | (hifreq_filter ? FREQ_HI : FREQ_LOW)
 711                          | (filter_input ? FILT_ON : FILT_OFF)));
 712 
 713   setmixer (OUT_FILTER, ((dsp_stereo ? STEREO_DAC : MONO_DAC)
 714                          | (filter_output ? FILT_ON : FILT_OFF)));
 715 
 716   hi_filter = hifreq_filter;
 717   filter_in = filter_input;
 718   filter_out = filter_output;
 719 }
 720 
 721 static int
 722 mixer_output (int right_vol, int left_vol, int div, int device)
     /* [previous][next][first][last][top][bottom][index][help] */
 723 {
 724   int             left = ((left_vol * div) + 50) / 100;
 725   int             right = ((right_vol * div) + 50) / 100;
 726 
 727   setmixer (device, ((left & 0xf) << 4) | (right & 0xf));
 728 
 729   return (left_vol | (right_vol << 8));
 730 }
 731 
 732 static int
 733 sbp_mixer_set (int whichDev, unsigned int level)
     /* [previous][next][first][last][top][bottom][index][help] */
 734 {
 735   int             left, right, devmask;
 736 
 737   left = level & 0x7f;
 738   right = (level & 0x7f00) >> 8;
 739 
 740   switch (whichDev)
 741     {
 742     case SOUND_MIXER_VOLUME:    /* Master volume (0-15) */
 743       return mixer_output (right, left, 15, MASTER_VOL);
 744       break;
 745     case SOUND_MIXER_SYNTH:     /* Internal synthesizer (0-15) */
 746       return mixer_output (right, left, 15, FM_VOL);
 747       break;
 748     case SOUND_MIXER_PCM:       /* PAS PCM (0-15) */
 749       return mixer_output (right, left, 15, VOC_VOL);
 750       break;
 751     case SOUND_MIXER_LINE:      /* External line (0-15) */
 752       return mixer_output (right, left, 15, LINE_VOL);
 753       break;
 754     case SOUND_MIXER_CD:        /* CD (0-15) */
 755       return mixer_output (right, left, 15, CD_VOL);
 756       break;
 757     case SOUND_MIXER_MIC:       /* External microphone (0-7) */
 758       return mixer_output (right, left, 7, MIC_VOL);
 759       break;
 760 
 761     case SOUND_MIXER_RECSRC:
 762       devmask = level & POSSIBLE_RECORDING_DEVICES;
 763 
 764       if (devmask != SOUND_MASK_MIC &&
 765           devmask != SOUND_MASK_LINE &&
 766           devmask != SOUND_MASK_CD)
 767         {                       /* More than one devices selected. Drop the
 768                                  * previous selection */
 769           devmask &= ~rec_devices;
 770         }
 771 
 772       if (devmask != SOUND_MASK_MIC &&
 773           devmask != SOUND_MASK_LINE &&
 774           devmask != SOUND_MASK_CD)
 775         {                       /* More than one devices selected. Default to
 776                                  * mic */
 777           devmask = SOUND_MASK_MIC;
 778         }
 779 
 780       if (devmask ^ rec_devices)/* Input source changed */
 781         {
 782           switch (devmask)
 783             {
 784 
 785             case SOUND_MASK_MIC:
 786               set_filter (SRC_MIC, hi_filter, filter_in, filter_out);
 787               break;
 788 
 789             case SOUND_MASK_LINE:
 790               set_filter (SRC_LINE, hi_filter, filter_in, filter_out);
 791               break;
 792 
 793             case SOUND_MASK_CD:
 794               set_filter (SRC_CD, hi_filter, filter_in, filter_out);
 795               break;
 796 
 797             default:
 798               set_filter (SRC_MIC, hi_filter, filter_in, filter_out);
 799             }
 800         }
 801 
 802       rec_devices = devmask;
 803 
 804       return rec_devices;
 805       break;
 806 
 807     default:
 808       return RET_ERROR (EINVAL);
 809     }
 810 
 811 }
 812 
 813 static int
 814 mixer_input (int div, int device)
     /* [previous][next][first][last][top][bottom][index][help] */
 815 {
 816   int             level, left, right, half;
 817 
 818   level = getmixer (device);
 819   half = div / 2;
 820 
 821   left = ((((level & 0xf0) >> 4) * 100) + half) / div;
 822   right = (((level & 0x0f) * 100) + half) / div;
 823 
 824   return (right << 8) | left;
 825 }
 826 
 827 static int
 828 sbp_mixer_get (int whichDev)
     /* [previous][next][first][last][top][bottom][index][help] */
 829 {
 830 
 831   switch (whichDev)
 832     {
 833     case SOUND_MIXER_VOLUME:    /* Master volume (0-15) */
 834       return mixer_input (15, MASTER_VOL);
 835       break;
 836     case SOUND_MIXER_SYNTH:     /* Internal synthesizer (0-15) */
 837       return mixer_input (15, FM_VOL);
 838       break;
 839     case SOUND_MIXER_PCM:       /* PAS PCM (0-15) */
 840       return mixer_input (15, VOC_VOL);
 841       break;
 842     case SOUND_MIXER_LINE:      /* External line (0-15) */
 843       return mixer_input (15, LINE_VOL);
 844       break;
 845     case SOUND_MIXER_CD:        /* CD (0-15) */
 846       return mixer_input (15, CD_VOL);
 847       break;
 848     case SOUND_MIXER_MIC:       /* External microphone (0-7) */
 849       return mixer_input (7, MIC_VOL);
 850       break;
 851 
 852     default:
 853       return RET_ERROR (EINVAL);
 854     }
 855 
 856 }
 857 
 858 /*
 859  * Sets mixer volume levels. All levels except mic are 0 to 15, mic is 7. See
 860  * sbinfo.doc for details on granularity and such. Basically, the mixer
 861  * forces the lowest bit high, effectively reducing the possible settings by
 862  * one half.  Yes, that's right, volume levels have 8 settings, and
 863  * microphone has four.  Sucks.
 864  */
 865 static int
 866 mixer_set_levels (struct sb_mixer_levels *user_l)
     /* [previous][next][first][last][top][bottom][index][help] */
 867 {
 868   struct sb_mixer_levels l;
 869 
 870   IOCTL_FROM_USER ((char *) &l, ((char *) user_l), 0, sizeof (l));
 871 
 872   if (l.master.l & ~0xF || l.master.r & ~0xF
 873       || l.line.l & ~0xF || l.line.r & ~0xF
 874       || l.voc.l & ~0xF || l.voc.r & ~0xF
 875       || l.fm.l & ~0xF || l.fm.r & ~0xF
 876       || l.cd.l & ~0xF || l.cd.r & ~0xF
 877       || l.mic & ~0x7)
 878     return (RET_ERROR (EINVAL));
 879 
 880   setmixer (MASTER_VOL, (l.master.l << 4) | l.master.r);
 881   setmixer (LINE_VOL, (l.line.l << 4) | l.line.r);
 882   setmixer (VOC_VOL, (l.voc.l << 4) | l.voc.r);
 883   setmixer (FM_VOL, (l.fm.l << 4) | l.fm.r);
 884   setmixer (CD_VOL, (l.cd.l << 4) | l.cd.r);
 885   setmixer (MIC_VOL, l.mic);
 886   return (0);
 887 }
 888 
 889 /*
 890  * This sets aspects of the Mixer that are not volume levels. (Recording
 891  * source, filter level, I/O filtering, and stereo.)
 892  */
 893 
 894 static int
 895 mixer_set_params (struct sb_mixer_params *user_p)
     /* [previous][next][first][last][top][bottom][index][help] */
 896 {
 897   struct sb_mixer_params p;
 898 
 899   IOCTL_FROM_USER ((char *) &p, (char *) user_p, 0, sizeof (p));
 900 
 901   if (p.record_source != SRC_MIC
 902       && p.record_source != SRC_CD
 903       && p.record_source != SRC_LINE)
 904     return (EINVAL);
 905 
 906   /*
 907    * I'm not sure if this is The Right Thing.  Should stereo be entirely
 908    * under control of DSP?  I like being able to toggle it while a sound is
 909    * playing, so I do this... because I can.
 910    */
 911 
 912   dsp_stereo = !!p.dsp_stereo;
 913 
 914   set_filter (p.record_source, p.hifreq_filter, p.filter_input, p.filter_output);
 915 
 916   switch (p.record_source)
 917     {
 918 
 919     case SRC_MIC:
 920       rec_devices = SOUND_MASK_MIC;
 921       break;
 922 
 923     case SRC_LINE:
 924       rec_devices = SOUND_MASK_LINE;
 925       break;
 926 
 927     case SRC_CD:
 928       rec_devices = SOUND_MASK_CD;
 929     }
 930 
 931   return (0);
 932 }
 933 
 934 /* Read the current mixer level settings into the user's struct. */
 935 static int
 936 mixer_get_levels (struct sb_mixer_levels *user_l)
     /* [previous][next][first][last][top][bottom][index][help] */
 937 {
 938   S_BYTE          val;
 939   struct sb_mixer_levels l;
 940 
 941   val = getmixer (MASTER_VOL);  /* Master */
 942   l.master.l = B4 (val >> 4);
 943   l.master.r = B4 (val);
 944 
 945   val = getmixer (LINE_VOL);    /* FM */
 946   l.line.l = B4 (val >> 4);
 947   l.line.r = B4 (val);
 948 
 949   val = getmixer (VOC_VOL);     /* DAC */
 950   l.voc.l = B4 (val >> 4);
 951   l.voc.r = B4 (val);
 952 
 953   val = getmixer (FM_VOL);      /* FM */
 954   l.fm.l = B4 (val >> 4);
 955   l.fm.r = B4 (val);
 956 
 957   val = getmixer (CD_VOL);      /* CD */
 958   l.cd.l = B4 (val >> 4);
 959   l.cd.r = B4 (val);
 960 
 961   val = getmixer (MIC_VOL);     /* Microphone */
 962   l.mic = B3 (val);
 963 
 964   IOCTL_TO_USER ((char *) user_l, 0, (char *) &l, sizeof (l));
 965 
 966   return (0);
 967 }
 968 
 969 /* Read the current mixer parameters into the user's struct. */
 970 static int
 971 mixer_get_params (struct sb_mixer_params *user_params)
     /* [previous][next][first][last][top][bottom][index][help] */
 972 {
 973   S_BYTE          val;
 974   struct sb_mixer_params params;
 975 
 976   val = getmixer (RECORD_SRC);
 977   params.record_source = val & 0x07;
 978   params.hifreq_filter = !!(val & FREQ_HI);
 979   params.filter_input = (val & FILT_OFF) ? OFF : ON;
 980   params.filter_output = (getmixer (OUT_FILTER) & FILT_OFF) ? OFF : ON;
 981   params.dsp_stereo = dsp_stereo;
 982 
 983   IOCTL_TO_USER ((char *) user_params, 0, (char *) &params, sizeof (params));
 984   return (0);
 985 }
 986 
 987 static int
 988 sb_mixer_ioctl (int dev, unsigned int cmd, unsigned int arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 989 {
 990   if (((cmd >> 8) & 0xff) == 'M')
 991     {
 992       if (cmd & IOC_IN)
 993         return IOCTL_OUT (arg, sbp_mixer_set (cmd & 0xff, IOCTL_IN (arg)));
 994       else
 995         {                       /* Read parameters */
 996 
 997           switch (cmd & 0xff)
 998             {
 999 
1000             case SOUND_MIXER_RECSRC:
1001               return IOCTL_OUT (arg, rec_devices);
1002               break;
1003 
1004             case SOUND_MIXER_DEVMASK:
1005               return IOCTL_OUT (arg, SUPPORTED_MIXER_DEVICES);
1006               break;
1007 
1008             case SOUND_MIXER_STEREODEVS:
1009               return IOCTL_OUT (arg, SUPPORTED_MIXER_DEVICES & ~SOUND_MASK_MIC);
1010               break;
1011 
1012             case SOUND_MIXER_RECMASK:
1013               return IOCTL_OUT (arg, POSSIBLE_RECORDING_DEVICES);
1014               break;
1015 
1016             case SOUND_MIXER_CAPS:
1017               return IOCTL_OUT (arg, SOUND_CAP_EXCL_INPUT);
1018               break;
1019 
1020             default:
1021               return IOCTL_OUT (arg, sbp_mixer_get (cmd & 0xff));
1022             }
1023         }
1024     }
1025   else
1026     {
1027       switch (cmd)
1028         {
1029         case MIXER_IOCTL_SET_LEVELS:
1030           return (mixer_set_levels ((struct sb_mixer_levels *) arg));
1031         case MIXER_IOCTL_SET_PARAMS:
1032           return (mixer_set_params ((struct sb_mixer_params *) arg));
1033         case MIXER_IOCTL_READ_LEVELS:
1034           return (mixer_get_levels ((struct sb_mixer_levels *) arg));
1035         case MIXER_IOCTL_READ_PARAMS:
1036           return (mixer_get_params ((struct sb_mixer_params *) arg));
1037         case MIXER_IOCTL_RESET:
1038           init_mixer ();
1039           return (0);
1040         default:
1041           return RET_ERROR (EINVAL);
1042         }
1043     }
1044 }
1045 
1046 /* End of mixer code */
1047 #endif
1048 
1049 #ifndef EXCLUDE_MIDI
1050 
1051 /* Midi code */
1052 
1053 static int
1054 sb_midi_open (int dev, int mode,
     /* [previous][next][first][last][top][bottom][index][help] */
1055               void            (*input) (int dev, unsigned char data),
1056               void            (*output) (int dev)
1057 )
1058 {
1059   int             ret;
1060 
1061   if (!sb_dsp_ok)
1062     {
1063       printk ("SB Error: MIDI hardware not installed\n");
1064       return RET_ERROR (ENXIO);
1065     }
1066 
1067   if (mode != OPEN_WRITE && !duplex_midi)
1068     {
1069       if (num_midis == 1)
1070         printk ("SoundBlaster: Midi input not currently supported\n");
1071       return RET_ERROR (EPERM);
1072     }
1073 
1074   midi_mode = NORMAL_MIDI;
1075   if (mode != OPEN_WRITE)
1076     {
1077       if (dsp_busy || intr_active)
1078         return RET_ERROR (EBUSY);
1079       midi_mode = UART_MIDI;
1080     }
1081 
1082   if (dsp_highspeed || dsp_stereo)
1083     {
1084       printk ("SB Error: Midi output not possible during stereo or high speed audio\n");
1085       return RET_ERROR (EBUSY);
1086     }
1087 
1088   if (midi_mode == UART_MIDI)
1089     {
1090       irq_mode = IMODE_MIDI;
1091 
1092       reset_dsp ();
1093       dsp_speaker (OFF);
1094 
1095       if (!dsp_command (0x35))
1096         return RET_ERROR (EIO); /* Enter the UART mode */
1097       intr_active = 1;
1098 
1099       if ((ret = set_dsp_irq (sbc_irq)) < 0)
1100         {
1101           reset_dsp ();
1102           return 0;             /* IRQ not free */
1103         }
1104     }
1105 
1106   midi_busy = 1;
1107 
1108   return 0;
1109 }
1110 
1111 static void
1112 sb_midi_close (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1113 {
1114   if (midi_mode == UART_MIDI)
1115     {
1116       reset_dsp ();             /* The only way to kill the UART mode */
1117       RELEASE_IRQ (sbc_irq);
1118     }
1119   intr_active = 0;
1120   midi_busy = 0;
1121 }
1122 
1123 static int
1124 sb_midi_out (int dev, unsigned char midi_byte)
     /* [previous][next][first][last][top][bottom][index][help] */
1125 {
1126   unsigned long   flags;
1127 
1128   midi_busy = 1;                /* Kill all notes after close */
1129 
1130   if (midi_mode == NORMAL_MIDI)
1131     {
1132       DISABLE_INTR (flags);
1133       if (dsp_command (0x38))
1134         dsp_command (midi_byte);
1135       else
1136         printk ("SB Error: Unable to send a MIDI byte\n");
1137       RESTORE_INTR (flags);
1138     }
1139   else
1140     dsp_command (midi_byte);    /* UART write */
1141 
1142   return 1;
1143 }
1144 
1145 static int
1146 sb_midi_start_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1147 {
1148   if (midi_mode != UART_MIDI)
1149     {
1150       printk ("SoundBlaster: MIDI input not implemented.\n");
1151       return RET_ERROR (EPERM);
1152     }
1153   return 0;
1154 }
1155 
1156 static int
1157 sb_midi_end_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1158 {
1159   if (midi_mode == UART_MIDI)
1160     {
1161       reset_dsp ();
1162       intr_active = 0;
1163     }
1164   return 0;
1165 }
1166 
1167 static int
1168 sb_midi_ioctl (int dev, unsigned cmd, unsigned arg)
     /* [previous][next][first][last][top][bottom][index][help] */
1169 {
1170   return RET_ERROR (EPERM);
1171 }
1172 
1173 /* End of midi code */
1174 #endif
1175 
1176 #ifndef EXCLUDE_AUDIO
1177 static struct audio_operations sb_dsp_operations =
1178 {
1179   "SoundBlaster",
1180   sb_dsp_open,
1181   sb_dsp_close,
1182   sb_dsp_output_block,
1183   sb_dsp_start_input,
1184   sb_dsp_ioctl,
1185   sb_dsp_prepare_for_input,
1186   sb_dsp_prepare_for_output,
1187   sb_dsp_reset,
1188   sb_dsp_halt_xfer,
1189   NULL,                         /* has_output_drained */
1190   NULL                          /* copy_from_user */
1191 };
1192 
1193 #endif
1194 
1195 #ifndef EXCLUDE_SBPRO
1196 static struct mixer_operations sb_mixer_operations =
1197 {
1198   sb_mixer_ioctl
1199 };
1200 
1201 #endif
1202 
1203 #ifndef EXCLUDE_MIDI
1204 static struct midi_operations sb_midi_operations =
1205 {
1206   {"SoundBlaster", 0},
1207   sb_midi_open,
1208   sb_midi_close,
1209   sb_midi_ioctl,
1210   sb_midi_out,
1211   sb_midi_start_read,
1212   sb_midi_end_read,
1213   NULL,                         /* Kick */
1214   NULL,                         /* command */
1215   NULL                          /* buffer_status */
1216 };
1217 
1218 #endif
1219 
1220 static int
1221 verify_irq (void)
     /* [previous][next][first][last][top][bottom][index][help] */
1222 {
1223 #if 0
1224   unsigned long   loop;
1225 
1226   irq_ok = 0;
1227 
1228   if (set_dsp_irq (sbc_irq) == -1)
1229     {
1230       printk ("*** SB Error: Irq %d already in use\n", sbc_irq);
1231       return 0;
1232     }
1233 
1234 
1235   irq_mode = IMODE_INIT;
1236 
1237   dsp_command (0xf2);           /* This should cause immediate interrupt */
1238 
1239   for (loop = 100000; loop > 0 && !irq_ok; loop--);
1240 
1241   RELEASE_IRQ (sbc_irq);
1242 
1243   if (!irq_ok)
1244     {
1245       printk ("SB Warning: IRQ test not passed!");
1246       irq_ok = 1;
1247     }
1248 #else
1249   irq_ok = 1;
1250 #endif
1251   return irq_ok;
1252 }
1253 
1254 long
1255 sb_dsp_init (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
1256 {
1257   int             i, major, minor;
1258 
1259   major = minor = 0;
1260   dsp_command (0xe1);           /* Get version */
1261 
1262   for (i = 1000; i; i--)
1263     {
1264       if (inb (DSP_DATA_AVAIL) & 0x80)
1265         {                       /* wait for Data Ready */
1266           if (major == 0)
1267             major = inb (DSP_READ);
1268           else
1269             {
1270               minor = inb (DSP_READ);
1271               break;
1272             }
1273         }
1274     }
1275 
1276 #ifndef EXCLUDE_SBPRO
1277   if (detect_mixer ())
1278     {
1279 #ifndef SCO
1280       sprintf (sb_dsp_operations.name, "SoundBlaster Pro %d.%d", major, minor);
1281 #endif
1282       init_mixer ();
1283       mixer_devs[num_mixers++] = &sb_mixer_operations;
1284 
1285       if (major == 2 || major == 3)
1286         duplex_midi = 1;
1287 
1288       if (major == 4)
1289         sb16 = 1;
1290 
1291       if (major >= 3)
1292         dsp_model = 2;
1293 
1294 #ifndef EXCLUDE_YM8312
1295       if (major > 3 || (major == 3 && minor > 0))       /* SB Pro2 or later */
1296         {
1297           enable_opl3_mode (OPL3_LEFT, OPL3_RIGHT, OPL3_BOTH);
1298         }
1299 #endif
1300     }
1301   else
1302 #endif
1303 
1304 #ifndef SCO
1305     sprintf (sb_dsp_operations.name, "SoundBlaster %d.%d", major, minor);
1306 #endif
1307 
1308   printk (" <%s>", sb_dsp_operations.name);
1309 
1310   if (!verify_irq ())
1311     return mem_start;
1312 
1313 #ifndef EXCLUDE_AUDIO
1314   if (num_dspdevs < MAX_DSP_DEV)
1315     {
1316       dsp_devs[my_dev = num_dspdevs++] = &sb_dsp_operations;
1317       sound_buffcounts[my_dev] = DSP_BUFFCOUNT;
1318       sound_buffsizes[my_dev] = DSP_BUFFSIZE;
1319       sound_dsp_dmachan[my_dev] = hw_config->dma;
1320       sound_dma_automode[my_dev] = 0;
1321     }
1322   else
1323     printk ("SB: Too many DSP devices available\n");
1324 #endif
1325 
1326 #ifndef EXCLUDE_MIDI
1327   if (!midi_disabled)           /* Midi don't work in the SB emulation mode
1328                                  * of PAS */
1329     midi_devs[num_midis++] = &sb_midi_operations;
1330 #endif
1331 
1332   sb_dsp_ok = 1;
1333   return mem_start;
1334 }
1335 
1336 void
1337 sb_dsp_disable_midi (void)
     /* [previous][next][first][last][top][bottom][index][help] */
1338 {
1339   midi_disabled = 1;
1340 }
1341 
1342 #endif

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