root/drivers/sound/uart6850.c

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

DEFINITIONS

This source file includes following definitions.
  1. uart6850_input_loop
  2. m6850intr
  3. poll_uart6850
  4. uart6850_open
  5. uart6850_close
  6. uart6850_out
  7. uart6850_command
  8. uart6850_start_read
  9. uart6850_end_read
  10. uart6850_ioctl
  11. uart6850_kick
  12. uart6850_buffer_status
  13. attach_uart6850
  14. reset_uart6850
  15. probe_uart6850

   1 /*
   2  * sound/uart6850.c
   3  *
   4  * Copyright by Hannu Savolainen 1993
   5  *
   6  * Mon Nov 22 22:38:35 MET 1993 marco@driq.home.usn.nl:
   7  *      added 6850 support, used with COVOX SoundMaster II and custom cards.
   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  */
  30 
  31 #include "sound_config.h"
  32 
  33 #ifdef CONFIGURE_SOUNDCARD
  34 
  35 #if !defined(EXCLUDE_UART6850) && !defined(EXCLUDE_MIDI)
  36 
  37 #define DATAPORT   (uart6850_base)      /*
  38                                            * * * Midi6850 Data I/O Port on IBM
  39                                            *  */
  40 #define COMDPORT   (uart6850_base+1)    /*
  41                                            * * * Midi6850 Command Port on IBM   */
  42 #define STATPORT   (uart6850_base+1)    /*
  43                                            * * * Midi6850 Status Port on IBM   */
  44 
  45 #define uart6850_status()               INB(STATPORT)
  46 #define input_avail()           ((uart6850_status()&INPUT_AVAIL))
  47 #define output_ready()          ((uart6850_status()&OUTPUT_READY))
  48 #define uart6850_cmd(cmd)       OUTB(cmd, COMDPORT)
  49 #define uart6850_read()         INB(DATAPORT)
  50 #define uart6850_write(byte)    OUTB(byte, DATAPORT)
  51 
  52 #define OUTPUT_READY    0x02    /*
  53                                    * * * Mask for Data Read Ready Bit   */
  54 #define INPUT_AVAIL     0x01    /*
  55                                    * * * Mask for Data Send Ready Bit   */
  56 
  57 #define UART_RESET      0x95    /*
  58                                    * * * 6850 Total Reset Command   */
  59 #define UART_MODE_ON    0x03    /*
  60                                    * * * 6850 Send/Receive UART Mode   */
  61 
  62 static int      uart6850_opened = 0;
  63 static int      uart6850_base = 0x330;
  64 static int      uart6850_irq;
  65 static int      uart6850_detected = 0;
  66 static int      my_dev;
  67 
  68 static int      reset_uart6850 (void);
  69 static void     (*midi_input_intr) (int dev, unsigned char data);
  70 
  71 static void
  72 uart6850_input_loop (void)
     /* [previous][next][first][last][top][bottom][index][help] */
  73 {
  74   int             count;
  75 
  76   count = 10;
  77 
  78   while (count)                 /*
  79                                  * Not timed out
  80                                  */
  81     if (input_avail ())
  82       {
  83         unsigned char   c = uart6850_read ();
  84 
  85         count = 100;
  86 
  87         if (uart6850_opened & OPEN_READ)
  88           midi_input_intr (my_dev, c);
  89       }
  90     else
  91       while (!input_avail () && count)
  92         count--;
  93 }
  94 
  95 void
  96 m6850intr (int unit, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
  97 {
  98   printk ("M");
  99   if (input_avail ())
 100     uart6850_input_loop ();
 101 }
 102 
 103 /*
 104  * It looks like there is no input interrupts in the UART mode. Let's try
 105  * polling.
 106  */
 107 
 108 static void
 109 poll_uart6850 (unsigned long dummy)
     /* [previous][next][first][last][top][bottom][index][help] */
 110 {
 111   unsigned long   flags;
 112 
 113   DEFINE_TIMER (uart6850_timer, poll_uart6850);
 114 
 115   if (!(uart6850_opened & OPEN_READ))
 116     return;                     /*
 117                                  * No longer required
 118                                  */
 119 
 120   DISABLE_INTR (flags);
 121 
 122   if (input_avail ())
 123     uart6850_input_loop ();
 124 
 125   ACTIVATE_TIMER (uart6850_timer, poll_uart6850, 1);    /*
 126                                                          * Come back later
 127                                                          */
 128 
 129   RESTORE_INTR (flags);
 130 }
 131 
 132 static int
 133 uart6850_open (int dev, int mode,
     /* [previous][next][first][last][top][bottom][index][help] */
 134                void            (*input) (int dev, unsigned char data),
 135                void            (*output) (int dev)
 136 )
 137 {
 138   if (uart6850_opened)
 139     {
 140       printk ("Midi6850: Midi busy\n");
 141       return RET_ERROR (EBUSY);
 142     }
 143 
 144   uart6850_cmd (UART_RESET);
 145 
 146   uart6850_input_loop ();
 147 
 148   midi_input_intr = input;
 149   uart6850_opened = mode;
 150   poll_uart6850 (0);            /*
 151                                  * Enable input polling
 152                                  */
 153 
 154   return 0;
 155 }
 156 
 157 static void
 158 uart6850_close (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 159 {
 160   uart6850_cmd (UART_MODE_ON);
 161 
 162   uart6850_opened = 0;
 163 }
 164 
 165 static int
 166 uart6850_out (int dev, unsigned char midi_byte)
     /* [previous][next][first][last][top][bottom][index][help] */
 167 {
 168   int             timeout;
 169   unsigned long   flags;
 170 
 171   /*
 172    * Test for input since pending input seems to block the output.
 173    */
 174 
 175   DISABLE_INTR (flags);
 176 
 177   if (input_avail ())
 178     uart6850_input_loop ();
 179 
 180   RESTORE_INTR (flags);
 181 
 182   /*
 183    * Sometimes it takes about 13000 loops before the output becomes ready
 184    * (After reset). Normally it takes just about 10 loops.
 185    */
 186 
 187   for (timeout = 30000; timeout > 0 && !output_ready (); timeout--);    /*
 188                                                                          * Wait
 189                                                                          */
 190 
 191   if (!output_ready ())
 192     {
 193       printk ("Midi6850: Timeout\n");
 194       return 0;
 195     }
 196 
 197   uart6850_write (midi_byte);
 198   return 1;
 199 }
 200 
 201 static int
 202 uart6850_command (int dev, unsigned char *midi_byte)
     /* [previous][next][first][last][top][bottom][index][help] */
 203 {
 204   return 1;
 205 }
 206 
 207 static int
 208 uart6850_start_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 209 {
 210   return 0;
 211 }
 212 
 213 static int
 214 uart6850_end_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 215 {
 216   return 0;
 217 }
 218 
 219 static int
 220 uart6850_ioctl (int dev, unsigned cmd, unsigned arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 221 {
 222   return RET_ERROR (EINVAL);
 223 }
 224 
 225 static void
 226 uart6850_kick (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 227 {
 228 }
 229 
 230 static int
 231 uart6850_buffer_status (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 232 {
 233   return 0;                     /*
 234                                  * No data in buffers
 235                                  */
 236 }
 237 
 238 #define MIDI_SYNTH_NAME "6850 UART Midi"
 239 #define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
 240 #include "midi_synth.h"
 241 
 242 static struct midi_operations uart6850_operations =
 243 {
 244   {"6850 UART", 0, 0, SNDCARD_UART6850},
 245   &std_midi_synth,
 246   uart6850_open,
 247   uart6850_close,
 248   uart6850_ioctl,
 249   uart6850_out,
 250   uart6850_start_read,
 251   uart6850_end_read,
 252   uart6850_kick,
 253   uart6850_command,
 254   uart6850_buffer_status
 255 };
 256 
 257 
 258 long
 259 attach_uart6850 (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 260 {
 261   int             ok, timeout;
 262   unsigned long   flags;
 263 
 264   if (num_midis >= MAX_MIDI_DEV)
 265     {
 266       printk ("Sound: Too many midi devices detected\n");
 267       return mem_start;
 268     }
 269 
 270   uart6850_base = hw_config->io_base;
 271   uart6850_irq = hw_config->irq;
 272 
 273   if (!uart6850_detected)
 274     return RET_ERROR (EIO);
 275 
 276   DISABLE_INTR (flags);
 277 
 278   for (timeout = 30000; timeout < 0 && !output_ready (); timeout--);    /*
 279                                                                          * Wait
 280                                                                          */
 281   uart6850_cmd (UART_MODE_ON);
 282 
 283   ok = 1;
 284 
 285   RESTORE_INTR (flags);
 286 
 287   printk (" <6850 Midi Interface>");
 288 
 289   std_midi_synth.midi_dev = my_dev = num_midis;
 290   midi_devs[num_midis++] = &uart6850_operations;
 291   return mem_start;
 292 }
 293 
 294 static int
 295 reset_uart6850 (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 296 {
 297   uart6850_read ();
 298   return 1;                     /*
 299                                  * OK
 300                                  */
 301 }
 302 
 303 
 304 int
 305 probe_uart6850 (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 306 {
 307   int             ok = 0;
 308 
 309   uart6850_base = hw_config->io_base;
 310   uart6850_irq = hw_config->irq;
 311 
 312   if (snd_set_irq_handler (uart6850_irq, m6850intr) < 0)
 313     return 0;
 314 
 315   ok = reset_uart6850 ();
 316 
 317   uart6850_detected = ok;
 318   return ok;
 319 }
 320 
 321 #endif
 322 
 323 #endif

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