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 /*
   7  * Copyright by Hannu Savolainen 1993-1996
   8  *
   9  * Redistribution and use in source and binary forms, with or without
  10  * modification, are permitted provided that the following conditions are
  11  * met: 1. Redistributions of source code must retain the above copyright
  12  * notice, this list of conditions and the following disclaimer. 2.
  13  * Redistributions in binary form must reproduce the above copyright notice,
  14  * this list of conditions and the following disclaimer in the documentation
  15  * and/or other materials provided with the distribution.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
  18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  23  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  24  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27  * SUCH DAMAGE.
  28  */
  29 #include <linux/config.h>
  30 
  31 
  32 #include "sound_config.h"
  33 
  34 #if defined(CONFIG_SB) && defined(CONFIG_MIDI)
  35 
  36 #include "sb.h"
  37 #undef SB_TEST_IRQ
  38 
  39 /*
  40  * The DSP channel can be used either for input or output. Variable
  41  * 'sb_irq_mode' will be set when the program calls read or write first time
  42  * after open. Current version doesn't support mode changes without closing
  43  * and reopening the device. Support for this feature may be implemented in a
  44  * future version of this driver.
  45  */
  46 
  47 extern int      sb_dsp_ok;      /* Set to 1 after successful initialization */
  48 extern int      sbc_base;
  49 
  50 extern int      sb_midi_mode;
  51 extern int      sb_midi_busy;   /*
  52 
  53 
  54                                  * *  * * 1 if the process has output to MIDI
  55                                  *
  56                                  */
  57 extern int      sb_dsp_busy;
  58 extern int      sb_dsp_highspeed;
  59 
  60 extern volatile int sb_irq_mode;
  61 extern int      sb_duplex_midi;
  62 extern int      sb_intr_active;
  63 int             input_opened = 0;
  64 static int      my_dev;
  65 
  66 extern int     *sb_osp;
  67 
  68 void            (*midi_input_intr) (int dev, unsigned char data);
  69 
  70 static int
  71 sb_midi_open (int dev, int mode,
     /* [previous][next][first][last][top][bottom][index][help] */
  72               void            (*input) (int dev, unsigned char data),
  73               void            (*output) (int dev)
  74 )
  75 {
  76   int             ret;
  77 
  78   if (!sb_dsp_ok)
  79     {
  80       printk ("SB Error: MIDI hardware not installed\n");
  81       return -ENXIO;
  82     }
  83 
  84   if (sb_midi_busy)
  85     return -EBUSY;
  86 
  87   if (mode != OPEN_WRITE && !sb_duplex_midi)
  88     {
  89       if (num_midis == 1)
  90         printk ("SoundBlaster: Midi input not currently supported\n");
  91       return -EPERM;
  92     }
  93 
  94   sb_midi_mode = NORMAL_MIDI;
  95   if (mode != OPEN_WRITE)
  96     {
  97       if (sb_dsp_busy || sb_intr_active)
  98         return -EBUSY;
  99       sb_midi_mode = UART_MIDI;
 100     }
 101 
 102   if (sb_dsp_highspeed)
 103     {
 104       printk ("SB Error: Midi output not possible during stereo or high speed audio\n");
 105       return -EBUSY;
 106     }
 107 
 108   if (sb_midi_mode == UART_MIDI)
 109     {
 110       sb_irq_mode = IMODE_MIDI;
 111 
 112       sb_reset_dsp ();
 113 
 114       if (!sb_dsp_command (0x35))
 115         return -EIO;            /*
 116                                    * Enter the UART mode
 117                                  */
 118       sb_intr_active = 1;
 119 
 120       if ((ret = sb_get_irq ()) < 0)
 121         {
 122           sb_reset_dsp ();
 123           return 0;             /*
 124                                  * IRQ not free
 125                                  */
 126         }
 127       input_opened = 1;
 128       midi_input_intr = input;
 129     }
 130 
 131   sb_midi_busy = 1;
 132 
 133   return 0;
 134 }
 135 
 136 static void
 137 sb_midi_close (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 138 {
 139   if (sb_midi_mode == UART_MIDI)
 140     {
 141       sb_reset_dsp ();          /*
 142                                  * The only way to kill the UART mode
 143                                  */
 144       sb_free_irq ();
 145     }
 146   sb_intr_active = 0;
 147   sb_midi_busy = 0;
 148   input_opened = 0;
 149 }
 150 
 151 static int
 152 sb_midi_out (int dev, unsigned char midi_byte)
     /* [previous][next][first][last][top][bottom][index][help] */
 153 {
 154   unsigned long   flags;
 155 
 156   if (sb_midi_mode == NORMAL_MIDI)
 157     {
 158       save_flags (flags);
 159       cli ();
 160       if (sb_dsp_command (0x38))
 161         sb_dsp_command (midi_byte);
 162       else
 163         printk ("SB Error: Unable to send a MIDI byte\n");
 164       restore_flags (flags);
 165     }
 166   else
 167     sb_dsp_command (midi_byte); /*
 168                                  * UART write
 169                                  */
 170 
 171   return 1;
 172 }
 173 
 174 static int
 175 sb_midi_start_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 176 {
 177   if (sb_midi_mode != UART_MIDI)
 178     {
 179       printk ("SoundBlaster: MIDI input not implemented.\n");
 180       return -EPERM;
 181     }
 182   return 0;
 183 }
 184 
 185 static int
 186 sb_midi_end_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 187 {
 188   if (sb_midi_mode == UART_MIDI)
 189     {
 190       sb_reset_dsp ();
 191       sb_intr_active = 0;
 192     }
 193   return 0;
 194 }
 195 
 196 static int
 197 sb_midi_ioctl (int dev, unsigned cmd, caddr_t arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 198 {
 199   return -EPERM;
 200 }
 201 
 202 void
 203 sb_midi_interrupt (int dummy)
     /* [previous][next][first][last][top][bottom][index][help] */
 204 {
 205   unsigned long   flags;
 206   unsigned char   data;
 207 
 208   save_flags (flags);
 209   cli ();
 210 
 211   data = inb (DSP_READ);
 212   if (input_opened)
 213     midi_input_intr (my_dev, data);
 214 
 215   restore_flags (flags);
 216 }
 217 
 218 #define MIDI_SYNTH_NAME "SoundBlaster Midi"
 219 #define MIDI_SYNTH_CAPS 0
 220 #include "midi_synth.h"
 221 
 222 static struct midi_operations sb_midi_operations =
 223 {
 224   {"SoundBlaster", 0, 0, SNDCARD_SB},
 225   &std_midi_synth,
 226   {0},
 227   sb_midi_open,
 228   sb_midi_close,
 229   sb_midi_ioctl,
 230   sb_midi_out,
 231   sb_midi_start_read,
 232   sb_midi_end_read,
 233   NULL,                         /*
 234                                  * Kick
 235                                  */
 236   NULL,                         /*
 237                                  * command
 238                                  */
 239   NULL,                         /*
 240                                  * buffer_status
 241                                  */
 242   NULL
 243 };
 244 
 245 void
 246 sb_midi_init (int model)
     /* [previous][next][first][last][top][bottom][index][help] */
 247 {
 248   if (num_midis >= MAX_MIDI_DEV)
 249     {
 250       printk ("Sound: Too many midi devices detected\n");
 251       return;
 252     }
 253 
 254   std_midi_synth.midi_dev = num_midis;
 255   my_dev = num_midis;
 256   midi_devs[num_midis++] = &sb_midi_operations;
 257 }
 258 
 259 #endif

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