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

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