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
  16. unload_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 static void     poll_uart6850 (unsigned long dummy);
  71 
  72 static sound_os_info *uart6850_osp;
  73 
  74 
  75 static struct timer_list uart6850_timer =
  76 {NULL, NULL, 0, 0, poll_uart6850};
  77 
  78 static void
  79 uart6850_input_loop (void)
     /* [previous][next][first][last][top][bottom][index][help] */
  80 {
  81   int             count;
  82 
  83   count = 10;
  84 
  85   while (count)                 /*
  86                                  * Not timed out
  87                                  */
  88     if (input_avail ())
  89       {
  90         unsigned char   c = uart6850_read ();
  91 
  92         count = 100;
  93 
  94         if (uart6850_opened & OPEN_READ)
  95           midi_input_intr (my_dev, c);
  96       }
  97     else
  98       while (!input_avail () && count)
  99         count--;
 100 }
 101 
 102 void
 103 m6850intr (int irq, struct pt_regs *dummy)
     /* [previous][next][first][last][top][bottom][index][help] */
 104 {
 105   if (input_avail ())
 106     uart6850_input_loop ();
 107 }
 108 
 109 /*
 110  * It looks like there is no input interrupts in the UART mode. Let's try
 111  * polling.
 112  */
 113 
 114 static void
 115 poll_uart6850 (unsigned long dummy)
     /* [previous][next][first][last][top][bottom][index][help] */
 116 {
 117   unsigned long   flags;
 118 
 119   if (!(uart6850_opened & OPEN_READ))
 120     return;                     /*
 121                                  * No longer required
 122                                  */
 123 
 124   save_flags (flags);
 125   cli ();
 126 
 127   if (input_avail ())
 128     uart6850_input_loop ();
 129 
 130 
 131   {
 132     uart6850_timer.expires = (1) + jiffies;
 133     add_timer (&uart6850_timer);
 134   };                            /*
 135                                    * Come back later
 136                                  */
 137 
 138   restore_flags (flags);
 139 }
 140 
 141 static int
 142 uart6850_open (int dev, int mode,
     /* [previous][next][first][last][top][bottom][index][help] */
 143                void            (*input) (int dev, unsigned char data),
 144                void            (*output) (int dev)
 145 )
 146 {
 147   if (uart6850_opened)
 148     {
 149       printk ("Midi6850: Midi busy\n");
 150       return -EBUSY;
 151     }
 152 
 153   uart6850_cmd (UART_RESET);
 154 
 155   uart6850_input_loop ();
 156 
 157   midi_input_intr = input;
 158   uart6850_opened = mode;
 159   poll_uart6850 (0);            /*
 160                                  * Enable input polling
 161                                  */
 162 
 163   return 0;
 164 }
 165 
 166 static void
 167 uart6850_close (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 168 {
 169   uart6850_cmd (UART_MODE_ON);
 170 
 171   del_timer (&uart6850_timer);;
 172   uart6850_opened = 0;
 173 }
 174 
 175 static int
 176 uart6850_out (int dev, unsigned char midi_byte)
     /* [previous][next][first][last][top][bottom][index][help] */
 177 {
 178   int             timeout;
 179   unsigned long   flags;
 180 
 181   /*
 182    * Test for input since pending input seems to block the output.
 183    */
 184 
 185   save_flags (flags);
 186   cli ();
 187 
 188   if (input_avail ())
 189     uart6850_input_loop ();
 190 
 191   restore_flags (flags);
 192 
 193   /*
 194    * Sometimes it takes about 13000 loops before the output becomes ready
 195    * (After reset). Normally it takes just about 10 loops.
 196    */
 197 
 198   for (timeout = 30000; timeout > 0 && !output_ready (); timeout--);    /*
 199                                                                          * Wait
 200                                                                          */
 201 
 202   if (!output_ready ())
 203     {
 204       printk ("Midi6850: Timeout\n");
 205       return 0;
 206     }
 207 
 208   uart6850_write (midi_byte);
 209   return 1;
 210 }
 211 
 212 static int
 213 uart6850_command (int dev, unsigned char *midi_byte)
     /* [previous][next][first][last][top][bottom][index][help] */
 214 {
 215   return 1;
 216 }
 217 
 218 static int
 219 uart6850_start_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 220 {
 221   return 0;
 222 }
 223 
 224 static int
 225 uart6850_end_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 226 {
 227   return 0;
 228 }
 229 
 230 static int
 231 uart6850_ioctl (int dev, unsigned cmd, ioctl_arg arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 232 {
 233   return -EINVAL;
 234 }
 235 
 236 static void
 237 uart6850_kick (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 238 {
 239 }
 240 
 241 static int
 242 uart6850_buffer_status (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 243 {
 244   return 0;                     /*
 245                                  * No data in buffers
 246                                  */
 247 }
 248 
 249 #define MIDI_SYNTH_NAME "6850 UART Midi"
 250 #define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
 251 #include "midi_synth.h"
 252 
 253 static struct midi_operations uart6850_operations =
 254 {
 255   {"6850 UART", 0, 0, SNDCARD_UART6850},
 256   &std_midi_synth,
 257   {0},
 258   uart6850_open,
 259   uart6850_close,
 260   uart6850_ioctl,
 261   uart6850_out,
 262   uart6850_start_read,
 263   uart6850_end_read,
 264   uart6850_kick,
 265   uart6850_command,
 266   uart6850_buffer_status
 267 };
 268 
 269 
 270 long
 271 attach_uart6850 (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 272 {
 273   int             ok, timeout;
 274   unsigned long   flags;
 275 
 276   if (num_midis >= MAX_MIDI_DEV)
 277     {
 278       printk ("Sound: Too many midi devices detected\n");
 279       return mem_start;
 280     }
 281 
 282   uart6850_base = hw_config->io_base;
 283   uart6850_osp = hw_config->osp;
 284   uart6850_irq = hw_config->irq;
 285 
 286   if (!uart6850_detected)
 287     return -EIO;
 288 
 289   save_flags (flags);
 290   cli ();
 291 
 292   for (timeout = 30000; timeout < 0 && !output_ready (); timeout--);    /*
 293                                                                          * Wait
 294                                                                          */
 295   uart6850_cmd (UART_MODE_ON);
 296 
 297   ok = 1;
 298 
 299   restore_flags (flags);
 300 
 301   printk (" <6850 Midi Interface>");
 302 
 303   std_midi_synth.midi_dev = my_dev = num_midis;
 304   midi_devs[num_midis++] = &uart6850_operations;
 305   return mem_start;
 306 }
 307 
 308 static int
 309 reset_uart6850 (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 310 {
 311   uart6850_read ();
 312   return 1;                     /*
 313                                  * OK
 314                                  */
 315 }
 316 
 317 
 318 int
 319 probe_uart6850 (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 320 {
 321   int             ok = 0;
 322 
 323   uart6850_osp = hw_config->osp;
 324   uart6850_base = hw_config->io_base;
 325   uart6850_irq = hw_config->irq;
 326 
 327   if (snd_set_irq_handler (uart6850_irq, m6850intr, "MIDI6850", uart6850_osp) < 0)
 328     return 0;
 329 
 330   ok = reset_uart6850 ();
 331 
 332   uart6850_detected = ok;
 333   return ok;
 334 }
 335 
 336 void
 337 unload_uart6850 (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 338 {
 339   snd_release_irq (hw_config->irq);
 340 }
 341 
 342 #endif
 343 
 344 #endif

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