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 atfer successful initialization */
  46 extern int      sbc_base;
  47 
  48 extern int      sb_midi_mode;
  49 extern int      sb_midi_busy;   /*
  50 
  51 
  52                                  * *  * * 1 if the process has output to MIDI
  53                                  *
  54                                  */
  55 extern int      sb_dsp_busy;
  56 extern int      sb_dsp_highspeed;
  57 
  58 extern volatile int sb_irq_mode;
  59 extern int      sb_duplex_midi;
  60 extern int      sb_intr_active;
  61 int             input_opened = 0;
  62 static int      my_dev;
  63 
  64 extern sound_os_info *sb_osp;
  65 
  66 void            (*midi_input_intr) (int dev, unsigned char data);
  67 
  68 static int
  69 sb_midi_open (int dev, int mode,
     /* [previous][next][first][last][top][bottom][index][help] */
  70               void            (*input) (int dev, unsigned char data),
  71               void            (*output) (int dev)
  72 )
  73 {
  74   int             ret;
  75 
  76   if (!sb_dsp_ok)
  77     {
  78       printk ("SB Error: MIDI hardware not installed\n");
  79       return -ENXIO;
  80     }
  81 
  82   if (sb_midi_busy)
  83     return -EBUSY;
  84 
  85   if (mode != OPEN_WRITE && !sb_duplex_midi)
  86     {
  87       if (num_midis == 1)
  88         printk ("SoundBlaster: Midi input not currently supported\n");
  89       return -EPERM;
  90     }
  91 
  92   sb_midi_mode = NORMAL_MIDI;
  93   if (mode != OPEN_WRITE)
  94     {
  95       if (sb_dsp_busy || sb_intr_active)
  96         return -EBUSY;
  97       sb_midi_mode = UART_MIDI;
  98     }
  99 
 100   if (sb_dsp_highspeed)
 101     {
 102       printk ("SB Error: Midi output not possible during stereo or high speed audio\n");
 103       return -EBUSY;
 104     }
 105 
 106   if (sb_midi_mode == UART_MIDI)
 107     {
 108       sb_irq_mode = IMODE_MIDI;
 109 
 110       sb_reset_dsp ();
 111 
 112       if (!sb_dsp_command (0x35))
 113         return -EIO;            /*
 114                                    * Enter the UART mode
 115                                  */
 116       sb_intr_active = 1;
 117 
 118       if ((ret = sb_get_irq ()) < 0)
 119         {
 120           sb_reset_dsp ();
 121           return 0;             /*
 122                                  * IRQ not free
 123                                  */
 124         }
 125       input_opened = 1;
 126       midi_input_intr = input;
 127     }
 128 
 129   sb_midi_busy = 1;
 130 
 131   return 0;
 132 }
 133 
 134 static void
 135 sb_midi_close (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 136 {
 137   if (sb_midi_mode == UART_MIDI)
 138     {
 139       sb_reset_dsp ();          /*
 140                                  * The only way to kill the UART mode
 141                                  */
 142       sb_free_irq ();
 143     }
 144   sb_intr_active = 0;
 145   sb_midi_busy = 0;
 146   input_opened = 0;
 147 }
 148 
 149 static int
 150 sb_midi_out (int dev, unsigned char midi_byte)
     /* [previous][next][first][last][top][bottom][index][help] */
 151 {
 152   unsigned long   flags;
 153 
 154   if (sb_midi_mode == NORMAL_MIDI)
 155     {
 156       save_flags (flags);
 157       cli ();
 158       if (sb_dsp_command (0x38))
 159         sb_dsp_command (midi_byte);
 160       else
 161         printk ("SB Error: Unable to send a MIDI byte\n");
 162       restore_flags (flags);
 163     }
 164   else
 165     sb_dsp_command (midi_byte); /*
 166                                  * UART write
 167                                  */
 168 
 169   return 1;
 170 }
 171 
 172 static int
 173 sb_midi_start_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 174 {
 175   if (sb_midi_mode != UART_MIDI)
 176     {
 177       printk ("SoundBlaster: MIDI input not implemented.\n");
 178       return -EPERM;
 179     }
 180   return 0;
 181 }
 182 
 183 static int
 184 sb_midi_end_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 185 {
 186   if (sb_midi_mode == UART_MIDI)
 187     {
 188       sb_reset_dsp ();
 189       sb_intr_active = 0;
 190     }
 191   return 0;
 192 }
 193 
 194 static int
 195 sb_midi_ioctl (int dev, unsigned cmd, ioctl_arg arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 196 {
 197   return -EPERM;
 198 }
 199 
 200 void
 201 sb_midi_interrupt (int dummy)
     /* [previous][next][first][last][top][bottom][index][help] */
 202 {
 203   unsigned long   flags;
 204   unsigned char   data;
 205 
 206   save_flags (flags);
 207   cli ();
 208 
 209   data = inb (DSP_READ);
 210   if (input_opened)
 211     midi_input_intr (my_dev, data);
 212 
 213   restore_flags (flags);
 214 }
 215 
 216 #define MIDI_SYNTH_NAME "SoundBlaster Midi"
 217 #define MIDI_SYNTH_CAPS 0
 218 #include "midi_synth.h"
 219 
 220 static struct midi_operations sb_midi_operations =
 221 {
 222   {"SoundBlaster", 0, 0, SNDCARD_SB},
 223   &std_midi_synth,
 224   {0},
 225   sb_midi_open,
 226   sb_midi_close,
 227   sb_midi_ioctl,
 228   sb_midi_out,
 229   sb_midi_start_read,
 230   sb_midi_end_read,
 231   NULL,                         /*
 232                                  * Kick
 233                                  */
 234   NULL,                         /*
 235                                  * command
 236                                  */
 237   NULL,                         /*
 238                                  * buffer_status
 239                                  */
 240   NULL
 241 };
 242 
 243 void
 244 sb_midi_init (int model)
     /* [previous][next][first][last][top][bottom][index][help] */
 245 {
 246   if (num_midis >= MAX_MIDI_DEV)
 247     {
 248       printk ("Sound: Too many midi devices detected\n");
 249       return;
 250     }
 251 
 252   std_midi_synth.midi_dev = num_midis;
 253   my_dev = num_midis;
 254   midi_devs[num_midis++] = &sb_midi_operations;
 255 }
 256 
 257 #endif

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