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);       /* Enable */
  83 
  84   midi_busy = 1;
  85   qlen = qhead = qtail = output_used = 0;
  86   midi_input_intr = input;
  87 
  88   return 0;
  89 }
  90 
  91 static int
  92 dump_to_midi (unsigned char midi_byte)
     /* [previous][next][first][last][top][bottom][index][help] */
  93 {
  94   unsigned long   flags;
  95   int             ok = 0;
  96 
  97   output_used = 1;
  98 
  99   DISABLE_INTR (flags);
 100 
 101   if (GUS_MIDI_STATUS () & MIDI_XMIT_EMPTY)
 102     {
 103       ok = 1;
 104       OUTB (midi_byte, u_MidiData);
 105     }
 106   else
 107     {
 108       /* Enable Midi xmit interrupts (again) */
 109       gus_midi_control |= MIDI_ENABLE_XMIT;
 110       OUTB (gus_midi_control, u_MidiControl);
 111     }
 112 
 113   RESTORE_INTR (flags);
 114   return ok;
 115 }
 116 
 117 static void
 118 gus_midi_close (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 119 {
 120   /* Reset FIFO pointers, disable intrs */
 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   DISABLE_INTR (flags);
 137 
 138   while (qlen && dump_to_midi (tmp_queue[qhead]))
 139     {
 140       qlen--;
 141       qhead++;
 142     }
 143 
 144   RESTORE_INTR (flags);
 145 
 146   /*
 147    * Output the byte if the local queue is empty.
 148    */
 149 
 150   if (!qlen)
 151     if (dump_to_midi (midi_byte))
 152       return 1;                 /* OK */
 153 
 154   /*
 155    * Put to the local queue
 156    */
 157 
 158   if (qlen >= 256)
 159     return 0;                   /* Local queue full */
 160 
 161   DISABLE_INTR (flags);
 162 
 163   tmp_queue[qtail] = midi_byte;
 164   qlen++;
 165   qtail++;
 166 
 167   RESTORE_INTR (flags);
 168 
 169   return 1;
 170 }
 171 
 172 static int
 173 gus_midi_start_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 174 {
 175   return 0;
 176 }
 177 
 178 static int
 179 gus_midi_end_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 180 {
 181   return 0;
 182 }
 183 
 184 static int
 185 gus_midi_ioctl (int dev, unsigned cmd, unsigned arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 186 {
 187   return RET_ERROR (EINVAL);
 188 }
 189 
 190 static void
 191 gus_midi_kick (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 192 {
 193 }
 194 
 195 static int
 196 gus_midi_buffer_status (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 197 {
 198   unsigned long   flags;
 199 
 200   if (!output_used)
 201     return 0;
 202 
 203   DISABLE_INTR (flags);
 204 
 205   if (qlen && dump_to_midi (tmp_queue[qhead]))
 206     {
 207       qlen--;
 208       qhead++;
 209     }
 210 
 211   RESTORE_INTR (flags);
 212 
 213   return (qlen > 0) | !(GUS_MIDI_STATUS () & MIDI_XMIT_EMPTY);
 214 }
 215 
 216 static struct midi_operations gus_midi_operations =
 217 {
 218   {"Gravis UltraSound", 0, 0, SNDCARD_GUS},
 219   gus_midi_open,
 220   gus_midi_close,
 221   gus_midi_ioctl,
 222   gus_midi_out,
 223   gus_midi_start_read,
 224   gus_midi_end_read,
 225   gus_midi_kick,
 226   NULL,                         /* command */
 227   gus_midi_buffer_status
 228 };
 229 
 230 long
 231 gus_midi_init (long mem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
 232 {
 233   OUTB (MIDI_RESET, u_MidiControl);
 234 
 235   my_dev = num_midis;
 236   midi_devs[num_midis++] = &gus_midi_operations;
 237   return mem_start;
 238 }
 239 
 240 void
 241 gus_midi_interrupt (int dummy)
     /* [previous][next][first][last][top][bottom][index][help] */
 242 {
 243   unsigned char   stat, data;
 244   unsigned long   flags;
 245 
 246   DISABLE_INTR (flags);
 247 
 248   stat = GUS_MIDI_STATUS ();
 249 
 250   if (stat & MIDI_RCV_FULL)
 251     {
 252       data = INB (u_MidiData);
 253       if (input_opened)
 254         midi_input_intr (my_dev, data);
 255     }
 256 
 257   if (stat & MIDI_XMIT_EMPTY)
 258     {
 259       while (qlen && dump_to_midi (tmp_queue[qhead]))
 260         {
 261           qlen--;
 262           qhead++;
 263         }
 264 
 265       if (!qlen)
 266         {
 267           /* Disable Midi output interrupts, since no data in the buffer */
 268           gus_midi_control &= ~MIDI_ENABLE_XMIT;
 269           OUTB (gus_midi_control, u_MidiControl);
 270         }
 271     }
 272 
 273   if (stat & MIDI_FRAME_ERR)
 274     printk ("Midi framing error\n");
 275   if (stat & MIDI_OVERRUN && input_opened)
 276     printk ("GUS: Midi input overrun\n");
 277 
 278   RESTORE_INTR (flags);
 279 }
 280 
 281 #endif
 282 
 283 #endif

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