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

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