root/drivers/sound/gus_midi.c

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

DEFINITIONS

This source file includes following definitions.
  1. gus_midi_open
  2. dump_to_midi
  3. gus_midi_close
  4. gus_midi_out
  5. gus_midi_start_read
  6. gus_midi_end_read
  7. gus_midi_ioctl
  8. gus_midi_kick
  9. gus_midi_buffer_status
  10. gus_midi_init
  11. gus_midi_interrupt

   1 /*
   2  * sound/gus2_midi.c
   3  *
   4  * The low level driver for the GUS Midi Interface.
   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 #ifdef CONFIGURE_SOUNDCARD
  33 
  34 #include "gus_hw.h"
  35 
  36 #if !defined(EXCLUDE_GUS) && !defined(EXCLUDE_MIDI)
  37 
  38 static int      midi_busy = 0, input_opened = 0;
  39 static int      my_dev;
  40 static int      output_used = 0;
  41 static volatile unsigned char gus_midi_control;
  42 
  43 static void     (*midi_input_intr) (int dev, unsigned char data);
  44 
  45 static unsigned char tmp_queue[256];
  46 static volatile int qlen;
  47 static volatile unsigned char qhead, qtail;
  48 extern int      gus_base, gus_irq, gus_dma;
  49 extern sound_os_info *gus_osp;
  50 
  51 #define GUS_MIDI_STATUS()       inb( u_MidiStatus)
  52 
  53 static int
  54 gus_midi_open (int dev, int mode,
     /* [previous][next][first][last][top][bottom][index][help] */
  55                void            (*input) (int dev, unsigned char data),
  56                void            (*output) (int dev)
  57 )
  58 {
  59 
  60   if (midi_busy)
  61     {
  62       printk ("GUS: Midi busy\n");
  63       return -EBUSY;
  64     }
  65 
  66   outb (MIDI_RESET, u_MidiControl);
  67   gus_delay ();
  68 
  69   gus_midi_control = 0;
  70   input_opened = 0;
  71 
  72   if (mode == OPEN_READ || mode == OPEN_READWRITE)
  73     {
  74       gus_midi_control |= MIDI_ENABLE_RCV;
  75       input_opened = 1;
  76     }
  77 
  78   if (mode == OPEN_WRITE || mode == OPEN_READWRITE)
  79     {
  80       gus_midi_control |= MIDI_ENABLE_XMIT;
  81     }
  82 
  83   outb (gus_midi_control, u_MidiControl);       /*
  84                                                    * Enable
  85                                                  */
  86 
  87   midi_busy = 1;
  88   qlen = qhead = qtail = output_used = 0;
  89   midi_input_intr = input;
  90 
  91   return 0;
  92 }
  93 
  94 static int
  95 dump_to_midi (unsigned char midi_byte)
     /* [previous][next][first][last][top][bottom][index][help] */
  96 {
  97   unsigned long   flags;
  98   int             ok = 0;
  99 
 100   output_used = 1;
 101 
 102   save_flags (flags);
 103   cli ();
 104 
 105   if (GUS_MIDI_STATUS () & MIDI_XMIT_EMPTY)
 106     {
 107       ok = 1;
 108       outb (midi_byte, u_MidiData);
 109     }
 110   else
 111     {
 112       /*
 113        * Enable Midi xmit interrupts (again)
 114        */
 115       gus_midi_control |= MIDI_ENABLE_XMIT;
 116       outb (gus_midi_control, u_MidiControl);
 117     }
 118 
 119   restore_flags (flags);
 120   return ok;
 121 }
 122 
 123 static void
 124 gus_midi_close (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 125 {
 126   /*
 127    * Reset FIFO pointers, disable intrs
 128    */
 129 
 130   outb (MIDI_RESET, u_MidiControl);
 131   midi_busy = 0;
 132 }
 133 
 134 static int
 135 gus_midi_out (int dev, unsigned char midi_byte)
     /* [previous][next][first][last][top][bottom][index][help] */
 136 {
 137 
 138   unsigned long   flags;
 139 
 140   /*
 141    * Drain the local queue first
 142    */
 143 
 144   save_flags (flags);
 145   cli ();
 146 
 147   while (qlen && dump_to_midi (tmp_queue[qhead]))
 148     {
 149       qlen--;
 150       qhead++;
 151     }
 152 
 153   restore_flags (flags);
 154 
 155   /*
 156    * Output the byte if the local queue is empty.
 157    */
 158 
 159   if (!qlen)
 160     if (dump_to_midi (midi_byte))
 161       return 1;                 /*
 162                                  * OK
 163                                  */
 164 
 165   /*
 166    * Put to the local queue
 167    */
 168 
 169   if (qlen >= 256)
 170     return 0;                   /*
 171                                  * Local queue full
 172                                  */
 173 
 174   save_flags (flags);
 175   cli ();
 176 
 177   tmp_queue[qtail] = midi_byte;
 178   qlen++;
 179   qtail++;
 180 
 181   restore_flags (flags);
 182 
 183   return 1;
 184 }
 185 
 186 static int
 187 gus_midi_start_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 188 {
 189   return 0;
 190 }
 191 
 192 static int
 193 gus_midi_end_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 194 {
 195   return 0;
 196 }
 197 
 198 static int
 199 gus_midi_ioctl (int dev, unsigned cmd, ioctl_arg arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 200 {
 201   return -EINVAL;
 202 }
 203 
 204 static void
 205 gus_midi_kick (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 206 {
 207 }
 208 
 209 static int
 210 gus_midi_buffer_status (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 211 {
 212   unsigned long   flags;
 213 
 214   if (!output_used)
 215     return 0;
 216 
 217   save_flags (flags);
 218   cli ();
 219 
 220   if (qlen && dump_to_midi (tmp_queue[qhead]))
 221     {
 222       qlen--;
 223       qhead++;
 224     }
 225 
 226   restore_flags (flags);
 227 
 228   return (qlen > 0) | !(GUS_MIDI_STATUS () & MIDI_XMIT_EMPTY);
 229 }
 230 
 231 #define MIDI_SYNTH_NAME "Gravis Ultrasound Midi"
 232 #define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
 233 #include "midi_synth.h"
 234 
 235 static struct midi_operations gus_midi_operations =
 236 {
 237   {"Gravis UltraSound Midi", 0, 0, SNDCARD_GUS},
 238   &std_midi_synth,
 239   {0},
 240   gus_midi_open,
 241   gus_midi_close,
 242   gus_midi_ioctl,
 243   gus_midi_out,
 244   gus_midi_start_read,
 245   gus_midi_end_read,
 246   gus_midi_kick,
 247   NULL,                         /*
 248                                  * command
 249                                  */
 250   gus_midi_buffer_status,
 251   NULL
 252 };
 253 
 254 long
 255 gus_midi_init (long mem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
 256 {
 257   if (num_midis >= MAX_MIDI_DEV)
 258     {
 259       printk ("Sound: Too many midi devices detected\n");
 260       return mem_start;
 261     }
 262 
 263   outb (MIDI_RESET, u_MidiControl);
 264 
 265   std_midi_synth.midi_dev = my_dev = num_midis;
 266   midi_devs[num_midis++] = &gus_midi_operations;
 267   return mem_start;
 268 }
 269 
 270 void
 271 gus_midi_interrupt (int dummy)
     /* [previous][next][first][last][top][bottom][index][help] */
 272 {
 273   unsigned char   stat, data;
 274   unsigned long   flags;
 275 
 276   save_flags (flags);
 277   cli ();
 278 
 279   stat = GUS_MIDI_STATUS ();
 280 
 281   if (stat & MIDI_RCV_FULL)
 282     {
 283       data = inb (u_MidiData);
 284       if (input_opened)
 285         midi_input_intr (my_dev, data);
 286     }
 287 
 288   if (stat & MIDI_XMIT_EMPTY)
 289     {
 290       while (qlen && dump_to_midi (tmp_queue[qhead]))
 291         {
 292           qlen--;
 293           qhead++;
 294         }
 295 
 296       if (!qlen)
 297         {
 298           /*
 299            * Disable Midi output interrupts, since no data in the buffer
 300            */
 301           gus_midi_control &= ~MIDI_ENABLE_XMIT;
 302           outb (gus_midi_control, u_MidiControl);
 303         }
 304     }
 305 
 306 
 307   restore_flags (flags);
 308 }
 309 
 310 #endif
 311 
 312 #endif

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