root/drivers/sound/mpu401.c

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

DEFINITIONS

This source file includes following definitions.
  1. mpuintr
  2. mpu401_open
  3. mpu401_close
  4. mpu401_out
  5. mpu401_command
  6. mpu401_start_read
  7. mpu401_end_read
  8. mpu401_ioctl
  9. mpu401_kick
  10. mpu401_buffer_status
  11. attach_mpu401
  12. reset_mpu401
  13. probe_mpu401

   1 /*
   2  * sound/mpu401.c
   3  *
   4  * The low level driver for Roland MPU-401 compatible Midi cards.
   5  *
   6  * This version supports just the DUMB UART mode.
   7  *
   8  * Copyright by Hannu Savolainen 1993
   9  *
  10  * Redistribution and use in source and binary forms, with or without
  11  * modification, are permitted provided that the following conditions are
  12  * met: 1. Redistributions of source code must retain the above copyright
  13  * notice, this list of conditions and the following disclaimer. 2.
  14  * Redistributions in binary form must reproduce the above copyright notice,
  15  * this list of conditions and the following disclaimer in the documentation
  16  * and/or other materials provided with the distribution.
  17  *
  18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
  19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  22  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  24  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  25  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28  * SUCH DAMAGE.
  29  *
  30  */
  31 
  32 #include "sound_config.h"
  33 
  34 #ifdef CONFIGURE_SOUNDCARD
  35 
  36 #if !defined(EXCLUDE_MPU401) && !defined(EXCLUDE_MIDI)
  37 
  38 #define DATAPORT   (mpu401_base)/* MPU-401 Data I/O Port on IBM */
  39 #define COMDPORT   (mpu401_base+1)      /* MPU-401 Command Port on IBM */
  40 #define STATPORT   (mpu401_base+1)      /* MPU-401 Status Port on IBM */
  41 
  42 #define mpu401_status()         INB(STATPORT)
  43 #define input_avail()           (!(mpu401_status()&INPUT_AVAIL))
  44 #define output_ready()          (!(mpu401_status()&OUTPUT_READY))
  45 #define mpu401_cmd(cmd)         OUTB(cmd, COMDPORT)
  46 #define mpu401_read()           INB(DATAPORT)
  47 #define mpu401_write(byte)      OUTB(byte, DATAPORT)
  48 
  49 #define OUTPUT_READY    0x40    /* Mask for Data Read Redy Bit */
  50 #define INPUT_AVAIL     0x80    /* Mask for Data Send Ready Bit */
  51 #define MPU_ACK         0xFE    /* MPU-401 Acknowledge Response */
  52 #define MPU_RESET       0xFF    /* MPU-401 Total Reset Command */
  53 #define UART_MODE_ON    0x3F    /* MPU-401 "Dumb UART Mode" */
  54 
  55 static int      mpu401_opened = 0;
  56 static int      mpu401_base = 0x330;
  57 static int      mpu401_irq;
  58 static int      mpu401_detected = 0;
  59 static int      my_dev;
  60 
  61 static int      reset_mpu401 (void);
  62 static void     (*midi_input_intr) (int dev, unsigned char data);
  63 
  64 void
  65 mpuintr (int unit)
     /* [previous][next][first][last][top][bottom][index][help] */
  66 {
  67   while (input_avail ())
  68     {
  69       unsigned char   c = mpu401_read ();
  70 
  71       if (mpu401_opened & OPEN_READ)
  72         midi_input_intr (my_dev, c);
  73     }
  74 }
  75 
  76 static int
  77 mpu401_open (int dev, int mode,
     /* [previous][next][first][last][top][bottom][index][help] */
  78              void            (*input) (int dev, unsigned char data),
  79              void            (*output) (int dev)
  80 )
  81 {
  82   if (mpu401_opened)
  83     {
  84       printk ("MPU-401: Midi busy\n");
  85       return RET_ERROR (EBUSY);
  86     }
  87 
  88   mpuintr (0);
  89 
  90   midi_input_intr = input;
  91   mpu401_opened = mode;
  92 
  93   return 0;
  94 }
  95 
  96 static void
  97 mpu401_close (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  98 {
  99   mpu401_opened = 0;
 100 }
 101 
 102 static int
 103 mpu401_out (int dev, unsigned char midi_byte)
     /* [previous][next][first][last][top][bottom][index][help] */
 104 {
 105   int             timeout;
 106   unsigned long   flags;
 107 
 108   /*
 109    * Test for input since pending input seems to block the output.
 110    */
 111 
 112   DISABLE_INTR (flags);
 113 
 114   if (input_avail ())
 115     mpuintr (0);
 116 
 117   RESTORE_INTR (flags);
 118 
 119   /*
 120    * Sometimes it takes about 13000 loops before the output becomes ready
 121    * (After reset). Normally it takes just about 10 loops.
 122    */
 123 
 124   for (timeout = 30000; timeout > 0 && !output_ready (); timeout--);    /* Wait */
 125 
 126   if (!output_ready ())
 127     {
 128       printk ("MPU-401: Timeout\n");
 129       return 0;
 130     }
 131 
 132   mpu401_write (midi_byte);
 133   return 1;
 134 }
 135 
 136 static int
 137 mpu401_command (int dev, unsigned char midi_byte)
     /* [previous][next][first][last][top][bottom][index][help] */
 138 {
 139   return 1;
 140 }
 141 
 142 static int
 143 mpu401_start_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 144 {
 145   return 0;
 146 }
 147 
 148 static int
 149 mpu401_end_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 150 {
 151   return 0;
 152 }
 153 
 154 static int
 155 mpu401_ioctl (int dev, unsigned cmd, unsigned arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 156 {
 157   return RET_ERROR (EINVAL);
 158 }
 159 
 160 static void
 161 mpu401_kick (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 162 {
 163 }
 164 
 165 static int
 166 mpu401_buffer_status (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 167 {
 168   return 0;                     /* No data in buffers */
 169 }
 170 
 171 static struct midi_operations mpu401_operations =
 172 {
 173   {"MPU-401", 0, 0, SNDCARD_MPU401},
 174   mpu401_open,
 175   mpu401_close,
 176   mpu401_ioctl,
 177   mpu401_out,
 178   mpu401_start_read,
 179   mpu401_end_read,
 180   mpu401_kick,
 181   mpu401_command,
 182   mpu401_buffer_status
 183 };
 184 
 185 
 186 long
 187 attach_mpu401 (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 188 {
 189   int             ok, timeout;
 190   unsigned long   flags;
 191 
 192   mpu401_base = hw_config->io_base;
 193   mpu401_irq = hw_config->irq;
 194 
 195   if (!mpu401_detected)
 196     return RET_ERROR (EIO);
 197 
 198   DISABLE_INTR (flags);
 199   for (timeout = 30000; timeout < 0 && !output_ready (); timeout--);    /* Wait */
 200   mpu401_cmd (UART_MODE_ON);
 201 
 202   ok = 0;
 203   for (timeout = 50000; timeout > 0 && !ok; timeout--)
 204     if (input_avail ())
 205       if (mpu401_read () == MPU_ACK)
 206         ok = 1;
 207 
 208   RESTORE_INTR (flags);
 209 
 210   printk (" <Roland MPU-401>");
 211 
 212   my_dev = num_midis;
 213   mpu401_dev = num_midis;
 214   midi_devs[num_midis++] = &mpu401_operations;
 215   return mem_start;
 216 }
 217 
 218 static int
 219 reset_mpu401 (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 220 {
 221   unsigned long   flags;
 222   int             ok, timeout, n;
 223 
 224   /*
 225    * Send the RESET command. Try again if no success at the first time.
 226    */
 227 
 228   ok = 0;
 229 
 230   DISABLE_INTR (flags);
 231 
 232   for (n = 0; n < 2 && !ok; n++)
 233     {
 234       for (timeout = 30000; timeout < 0 && !output_ready (); timeout--);        /* Wait */
 235       mpu401_cmd (MPU_RESET);   /* Send MPU-401 RESET Command */
 236 
 237       /*
 238        * Wait at least 25 msec. This method is not accurate so let's make the
 239        * loop bit longer. Cannot sleep since this is called during boot.
 240        */
 241 
 242       for (timeout = 50000; timeout > 0 && !ok; timeout--)
 243         if (input_avail ())
 244           if (mpu401_read () == MPU_ACK)
 245             ok = 1;
 246 
 247     }
 248 
 249   mpu401_opened = 0;
 250   if (ok)
 251     mpuintr (0);                /* Flush input before enabling interrupts */
 252 
 253   RESTORE_INTR (flags);
 254 
 255   return ok;
 256 }
 257 
 258 
 259 int
 260 probe_mpu401 (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 261 {
 262   int             ok = 0;
 263 
 264   mpu401_base = hw_config->io_base;
 265   mpu401_irq = hw_config->irq;
 266 
 267   if (snd_set_irq_handler (mpu401_irq, mpuintr) < 0)
 268     return 0;
 269 
 270   ok = reset_mpu401 ();
 271 
 272   mpu401_detected = ok;
 273   return ok;
 274 }
 275 
 276 #endif
 277 
 278 #endif

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