root/drivers/sound/sb_midi.c

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

DEFINITIONS

This source file includes following definitions.
  1. sb_midi_open
  2. sb_midi_close
  3. sb_midi_out
  4. sb_midi_start_read
  5. sb_midi_end_read
  6. sb_midi_ioctl
  7. sb_midi_interrupt
  8. sb_midi_init

   1 /*
   2  * 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  */
  29 
  30 #include "sound_config.h"
  31 
  32 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB) && !defined(EXCLUDE_MIDI)
  33 
  34 #include "sb.h"
  35 #undef SB_TEST_IRQ
  36 
  37 /*
  38  * The DSP channel can be used either for input or output. Variable
  39  * 'sb_irq_mode' will be set when the program calls read or write first time
  40  * after open. Current version doesn't support mode changes without closing
  41  * and reopening the device. Support for this feature may be implemented in a
  42  * future version of this driver.
  43  */
  44 
  45 extern int      sb_dsp_ok;      /* Set to 1 after successful initialization */
  46 
  47 extern int      sb_midi_mode;
  48 extern int      sb_midi_busy;   /* 1 if the process has output to MIDI */
  49 extern int      sb_dsp_busy;
  50 extern int      sb_dsp_highspeed;
  51 
  52 extern volatile int sb_irq_mode;/* IMODE_INPUT, IMODE_OUTPUT
  53 
  54                                          * or IMODE_NONE */
  55 extern int      sb_duplex_midi;
  56 extern int      sb_intr_active;
  57 extern int      sbc_base;
  58 
  59 static int      input_opened = 0;
  60 static void     (*midi_input_intr) (int dev, unsigned char data);
  61 static int      my_dev = 0;
  62 
  63 static int
  64 sb_midi_open (int dev, int mode,
     /* [previous][next][first][last][top][bottom][index][help] */
  65               void            (*input) (int dev, unsigned char data),
  66               void            (*output) (int dev)
  67 )
  68 {
  69   int             ret;
  70 
  71   if (!sb_dsp_ok)
  72     {
  73       printk ("SB Error: MIDI hardware not installed\n");
  74       return RET_ERROR (ENXIO);
  75     }
  76 
  77   if (mode != OPEN_WRITE && !sb_duplex_midi)
  78     {
  79       if (num_midis == 1)
  80         printk ("SoundBlaster: MIDI input not supported with plain SB\n");
  81       return RET_ERROR (EPERM);
  82     }
  83 
  84   sb_midi_mode = NORMAL_MIDI;
  85   if (mode != OPEN_WRITE)
  86     {
  87       if (sb_dsp_busy || sb_intr_active)
  88         return RET_ERROR (EBUSY);
  89       sb_midi_mode = UART_MIDI;
  90     }
  91 
  92   if (sb_dsp_highspeed)
  93     {
  94       printk ("SB Error: Midi output not possible during stereo or high speed audio\n");
  95       return RET_ERROR (EBUSY);
  96     }
  97 
  98   if (sb_midi_mode == UART_MIDI)
  99     {
 100       sb_irq_mode = IMODE_MIDI;
 101 
 102       sb_reset_dsp ();
 103 
 104       if (!sb_dsp_command (0xf2))       /* This is undodumented, isn't it */
 105         return RET_ERROR (EIO); /* be nice to DSP */
 106 
 107       if (!sb_dsp_command (0x35))
 108         return RET_ERROR (EIO); /* Enter the UART mode */
 109       sb_intr_active = 1;
 110 
 111       if ((ret = sb_get_irq ()) < 0)
 112         {
 113           sb_reset_dsp ();
 114           return 0;             /* IRQ not free */
 115         }
 116       input_opened = 1;
 117       my_dev = dev;
 118       midi_input_intr = input;
 119     }
 120 
 121   sb_midi_busy = 1;
 122 
 123   return 0;
 124 }
 125 
 126 static void
 127 sb_midi_close (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 128 {
 129   if (sb_midi_mode == UART_MIDI)
 130     {
 131       sb_reset_dsp ();          /* The only way to kill the UART mode */
 132       sb_free_irq ();
 133     }
 134   sb_intr_active = 0;
 135   sb_midi_busy = 0;
 136   input_opened = 0;
 137 }
 138 
 139 static int
 140 sb_midi_out (int dev, unsigned char midi_byte)
     /* [previous][next][first][last][top][bottom][index][help] */
 141 {
 142   unsigned long   flags;
 143 
 144   sb_midi_busy = 1;             /* Kill all notes after close */
 145 
 146   if (sb_midi_mode == NORMAL_MIDI)
 147     {
 148       DISABLE_INTR (flags);
 149       if (sb_dsp_command (0x38))
 150         sb_dsp_command (midi_byte);
 151       else
 152         printk ("SB Error: Unable to send a MIDI byte\n");
 153       RESTORE_INTR (flags);
 154     }
 155   else
 156     sb_dsp_command (midi_byte); /* UART write */
 157 
 158   return 1;
 159 }
 160 
 161 static int
 162 sb_midi_start_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 163 {
 164   if (sb_midi_mode != UART_MIDI)
 165     {
 166       printk ("SoundBlaster: MIDI input not implemented.\n");
 167       return RET_ERROR (EPERM);
 168     }
 169   return 0;
 170 }
 171 
 172 static int
 173 sb_midi_end_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 174 {
 175   if (sb_midi_mode == UART_MIDI)
 176     {
 177       sb_reset_dsp ();
 178       sb_intr_active = 0;
 179     }
 180   return 0;
 181 }
 182 
 183 static int
 184 sb_midi_ioctl (int dev, unsigned cmd, unsigned arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 185 {
 186   return RET_ERROR (EPERM);
 187 }
 188 
 189 void
 190 sb_midi_interrupt (int dummy)
     /* [previous][next][first][last][top][bottom][index][help] */
 191 {
 192   unsigned long   flags;
 193   unsigned char   data;
 194 
 195   DISABLE_INTR (flags);
 196 
 197   data = INB (DSP_READ);
 198   if (input_opened)
 199     midi_input_intr (my_dev, data);
 200 
 201   RESTORE_INTR (flags);
 202 }
 203 
 204 static struct midi_operations sb_midi_operations =
 205 {
 206   {"SoundBlaster", 0, 0, SNDCARD_SB},
 207   sb_midi_open,
 208   sb_midi_close,
 209   sb_midi_ioctl,
 210   sb_midi_out,
 211   sb_midi_start_read,
 212   sb_midi_end_read,
 213   NULL,                         /* Kick */
 214   NULL,                         /* command */
 215   NULL                          /* buffer_status */
 216 };
 217 
 218 void
 219 sb_midi_init (int model)
     /* [previous][next][first][last][top][bottom][index][help] */
 220 {
 221   midi_devs[num_midis++] = &sb_midi_operations;
 222 }
 223 
 224 #endif

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