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

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