root/drivers/sound/gus_midi.c

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

DEFINITIONS

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

   1 /*
   2  * sound/gus2_midi.c
   3  *
   4  * The low level driver for the GUS Midi Interface.
   5  */
   6 /*
   7  * Copyright by Hannu Savolainen 1993-1996
   8  *
   9  * Redistribution and use in source and binary forms, with or without
  10  * modification, are permitted provided that the following conditions are
  11  * met: 1. Redistributions of source code must retain the above copyright
  12  * notice, this list of conditions and the following disclaimer. 2.
  13  * Redistributions in binary form must reproduce the above copyright notice,
  14  * this list of conditions and the following disclaimer in the documentation
  15  * and/or other materials provided with the distribution.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
  18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  23  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  24  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27  * SUCH DAMAGE.
  28  */
  29 #include <linux/config.h>
  30 
  31 
  32 #include "sound_config.h"
  33 
  34 #include "gus_hw.h"
  35 
  36 #if defined(CONFIG_GUS) && defined(CONFIG_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 int     *gus_osp;
  50 
  51 static int 
  52 GUS_MIDI_STATUS (void)
     /* [previous][next][first][last][top][bottom][index][help] */
  53 {
  54   return inb (u_MidiStatus);
  55 }
  56 
  57 static int
  58 gus_midi_open (int dev, int mode,
     /* [previous][next][first][last][top][bottom][index][help] */
  59                void            (*input) (int dev, unsigned char data),
  60                void            (*output) (int dev)
  61 )
  62 {
  63 
  64   if (midi_busy)
  65     {
  66       printk ("GUS: Midi busy\n");
  67       return -EBUSY;
  68     }
  69 
  70   outb (MIDI_RESET, u_MidiControl);
  71   gus_delay ();
  72 
  73   gus_midi_control = 0;
  74   input_opened = 0;
  75 
  76   if (mode == OPEN_READ || mode == OPEN_READWRITE)
  77     {
  78       gus_midi_control |= MIDI_ENABLE_RCV;
  79       input_opened = 1;
  80     }
  81 
  82 
  83   outb (gus_midi_control, u_MidiControl);       /* Enable */
  84 
  85   midi_busy = 1;
  86   qlen = qhead = qtail = output_used = 0;
  87   midi_input_intr = input;
  88 
  89   return 0;
  90 }
  91 
  92 static int
  93 dump_to_midi (unsigned char midi_byte)
     /* [previous][next][first][last][top][bottom][index][help] */
  94 {
  95   unsigned long   flags;
  96   int             ok = 0;
  97 
  98   output_used = 1;
  99 
 100   save_flags (flags);
 101   cli ();
 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_flags (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   save_flags (flags);
 143   cli ();
 144 
 145   while (qlen && dump_to_midi (tmp_queue[qhead]))
 146     {
 147       qlen--;
 148       qhead++;
 149     }
 150 
 151   restore_flags (flags);
 152 
 153   /*
 154    * Output the byte if the local queue is empty.
 155    */
 156 
 157   if (!qlen)
 158     if (dump_to_midi (midi_byte))
 159       return 1;                 /*
 160                                  * OK
 161                                  */
 162 
 163   /*
 164    * Put to the local queue
 165    */
 166 
 167   if (qlen >= 256)
 168     return 0;                   /*
 169                                  * Local queue full
 170                                  */
 171 
 172   save_flags (flags);
 173   cli ();
 174 
 175   tmp_queue[qtail] = midi_byte;
 176   qlen++;
 177   qtail++;
 178 
 179   restore_flags (flags);
 180 
 181   return 1;
 182 }
 183 
 184 static int
 185 gus_midi_start_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 186 {
 187   return 0;
 188 }
 189 
 190 static int
 191 gus_midi_end_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 192 {
 193   return 0;
 194 }
 195 
 196 static int
 197 gus_midi_ioctl (int dev, unsigned cmd, caddr_t arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 198 {
 199   return -EINVAL;
 200 }
 201 
 202 static void
 203 gus_midi_kick (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 204 {
 205 }
 206 
 207 static int
 208 gus_midi_buffer_status (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 209 {
 210   unsigned long   flags;
 211 
 212   if (!output_used)
 213     return 0;
 214 
 215   save_flags (flags);
 216   cli ();
 217 
 218   if (qlen && dump_to_midi (tmp_queue[qhead]))
 219     {
 220       qlen--;
 221       qhead++;
 222     }
 223 
 224   restore_flags (flags);
 225 
 226   return (qlen > 0) | !(GUS_MIDI_STATUS () & MIDI_XMIT_EMPTY);
 227 }
 228 
 229 #define MIDI_SYNTH_NAME "Gravis Ultrasound Midi"
 230 #define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
 231 #include "midi_synth.h"
 232 
 233 static struct midi_operations gus_midi_operations =
 234 {
 235   {"Gravis UltraSound Midi", 0, 0, SNDCARD_GUS},
 236   &std_midi_synth,
 237   {0},
 238   gus_midi_open,
 239   gus_midi_close,
 240   gus_midi_ioctl,
 241   gus_midi_out,
 242   gus_midi_start_read,
 243   gus_midi_end_read,
 244   gus_midi_kick,
 245   NULL,                         /*
 246                                  * command
 247                                  */
 248   gus_midi_buffer_status,
 249   NULL
 250 };
 251 
 252 long
 253 gus_midi_init (long mem_start)
     /* [previous][next][first][last][top][bottom][index][help] */
 254 {
 255   if (num_midis >= MAX_MIDI_DEV)
 256     {
 257       printk ("Sound: Too many midi devices detected\n");
 258       return mem_start;
 259     }
 260 
 261   outb (MIDI_RESET, u_MidiControl);
 262 
 263   std_midi_synth.midi_dev = my_dev = num_midis;
 264   midi_devs[num_midis++] = &gus_midi_operations;
 265   return mem_start;
 266 }
 267 
 268 void
 269 gus_midi_interrupt (int dummy)
     /* [previous][next][first][last][top][bottom][index][help] */
 270 {
 271   volatile unsigned char stat, data;
 272   unsigned long   flags;
 273   int             timeout = 10;
 274 
 275   save_flags (flags);
 276   cli ();
 277 
 278   while (timeout-- > 0 && (stat = GUS_MIDI_STATUS ()) & (MIDI_RCV_FULL | MIDI_XMIT_EMPTY))
 279     {
 280       if (stat & MIDI_RCV_FULL)
 281         {
 282           data = inb (u_MidiData);
 283           if (input_opened)
 284             midi_input_intr (my_dev, data);
 285         }
 286 
 287       if (stat & MIDI_XMIT_EMPTY)
 288         {
 289           while (qlen && dump_to_midi (tmp_queue[qhead]))
 290             {
 291               qlen--;
 292               qhead++;
 293             }
 294 
 295           if (!qlen)
 296             {
 297               /*
 298                * Disable Midi output interrupts, since no data in the buffer
 299                */
 300               gus_midi_control &= ~MIDI_ENABLE_XMIT;
 301               outb (gus_midi_control, u_MidiControl);
 302               outb (gus_midi_control, u_MidiControl);
 303             }
 304         }
 305 
 306     }
 307 
 308   restore_flags (flags);
 309 }
 310 
 311 #endif

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