root/drivers/sound/uart6850.c

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

DEFINITIONS

This source file includes following definitions.
  1. uart6850_status
  2. uart6850_cmd
  3. uart6850_read
  4. uart6850_write
  5. uart6850_input_loop
  6. m6850intr
  7. poll_uart6850
  8. uart6850_open
  9. uart6850_close
  10. uart6850_out
  11. uart6850_command
  12. uart6850_start_read
  13. uart6850_end_read
  14. uart6850_ioctl
  15. uart6850_kick
  16. uart6850_buffer_status
  17. attach_uart6850
  18. reset_uart6850
  19. probe_uart6850
  20. unload_uart6850

   1 /*
   2  * sound/uart6850.c
   3  */
   4 /*
   5  * Copyright by Hannu Savolainen 1993-1996
   6  *
   7  * Redistribution and use in source and binary forms, with or without
   8  * modification, are permitted provided that the following conditions are
   9  * met: 1. Redistributions of source code must retain the above copyright
  10  * notice, this list of conditions and the following disclaimer. 2.
  11  * Redistributions in binary form must reproduce the above copyright notice,
  12  * this list of conditions and the following disclaimer in the documentation
  13  * and/or other materials provided with the distribution.
  14  *
  15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
  16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  19  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  21  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  22  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  25  * SUCH DAMAGE.
  26  */
  27 #include <linux/config.h>
  28 
  29 /* Mon Nov 22 22:38:35 MET 1993 marco@driq.home.usn.nl:
  30  *      added 6850 support, used with COVOX SoundMaster II and custom cards.
  31  */
  32 
  33 #include "sound_config.h"
  34 
  35 #if defined(CONFIG_UART6850) && defined(CONFIG_MIDI)
  36 
  37 static int      uart6850_base = 0x330;
  38 
  39 static int     *uart6850_osp;
  40 
  41 #define DATAPORT   (uart6850_base)
  42 #define COMDPORT   (uart6850_base+1)
  43 #define STATPORT   (uart6850_base+1)
  44 
  45 static int 
  46 uart6850_status (void)
     /* [previous][next][first][last][top][bottom][index][help] */
  47 {
  48   return inb (STATPORT);
  49 }
  50 #define input_avail()           (uart6850_status()&INPUT_AVAIL)
  51 #define output_ready()          (uart6850_status()&OUTPUT_READY)
  52 static void 
  53 uart6850_cmd (unsigned char cmd)
     /* [previous][next][first][last][top][bottom][index][help] */
  54 {
  55   outb (cmd, COMDPORT);
  56 }
  57 static int 
  58 uart6850_read (void)
     /* [previous][next][first][last][top][bottom][index][help] */
  59 {
  60   return inb (DATAPORT);
  61 }
  62 static void 
  63 uart6850_write (unsigned char byte)
     /* [previous][next][first][last][top][bottom][index][help] */
  64 {
  65   outb (byte, DATAPORT);
  66 }
  67 
  68 #define OUTPUT_READY    0x02    /* Mask for data ready Bit */
  69 #define INPUT_AVAIL     0x01    /* Mask for Data Send Ready Bit */
  70 
  71 #define UART_RESET      0x95
  72 #define UART_MODE_ON    0x03
  73 
  74 static int      uart6850_opened = 0;
  75 static int      uart6850_irq;
  76 static int      uart6850_detected = 0;
  77 static int      my_dev;
  78 
  79 static int      reset_uart6850 (void);
  80 static void     (*midi_input_intr) (int dev, unsigned char data);
  81 static void     poll_uart6850 (unsigned long dummy);
  82 
  83 
  84 static struct timer_list uart6850_timer =
  85 {NULL, NULL, 0, 0, poll_uart6850};
  86 
  87 static void
  88 uart6850_input_loop (void)
     /* [previous][next][first][last][top][bottom][index][help] */
  89 {
  90   int             count;
  91 
  92   count = 10;
  93 
  94   while (count)                 /*
  95                                  * Not timed out
  96                                  */
  97     if (input_avail ())
  98       {
  99         unsigned char   c = uart6850_read ();
 100 
 101         count = 100;
 102 
 103         if (uart6850_opened & OPEN_READ)
 104           midi_input_intr (my_dev, c);
 105       }
 106     else
 107       while (!input_avail () && count)
 108         count--;
 109 }
 110 
 111 void
 112 m6850intr (int irq, void *dev_id, struct pt_regs *dummy)
     /* [previous][next][first][last][top][bottom][index][help] */
 113 {
 114   if (input_avail ())
 115     uart6850_input_loop ();
 116 }
 117 
 118 /*
 119  * It looks like there is no input interrupts in the UART mode. Let's try
 120  * polling.
 121  */
 122 
 123 static void
 124 poll_uart6850 (unsigned long dummy)
     /* [previous][next][first][last][top][bottom][index][help] */
 125 {
 126   unsigned long   flags;
 127 
 128   if (!(uart6850_opened & OPEN_READ))
 129     return;                     /* Device has been closed */
 130 
 131   save_flags (flags);
 132   cli ();
 133 
 134   if (input_avail ())
 135     uart6850_input_loop ();
 136 
 137 
 138   {
 139     uart6850_timer.expires = (1) + jiffies;
 140     add_timer (&uart6850_timer);
 141   };                            /*
 142                                    * Come back later
 143                                  */
 144 
 145   restore_flags (flags);
 146 }
 147 
 148 static int
 149 uart6850_open (int dev, int mode,
     /* [previous][next][first][last][top][bottom][index][help] */
 150                void            (*input) (int dev, unsigned char data),
 151                void            (*output) (int dev)
 152 )
 153 {
 154   if (uart6850_opened)
 155     {
 156       printk ("Midi6850: Midi busy\n");
 157       return -EBUSY;
 158     }
 159 
 160   ;
 161   uart6850_cmd (UART_RESET);
 162 
 163   uart6850_input_loop ();
 164 
 165   midi_input_intr = input;
 166   uart6850_opened = mode;
 167   poll_uart6850 (0);            /*
 168                                  * Enable input polling
 169                                  */
 170 
 171   return 0;
 172 }
 173 
 174 static void
 175 uart6850_close (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 176 {
 177   uart6850_cmd (UART_MODE_ON);
 178 
 179   del_timer (&uart6850_timer);;
 180   uart6850_opened = 0;
 181 }
 182 
 183 static int
 184 uart6850_out (int dev, unsigned char midi_byte)
     /* [previous][next][first][last][top][bottom][index][help] */
 185 {
 186   int             timeout;
 187   unsigned long   flags;
 188 
 189   /*
 190    * Test for input since pending input seems to block the output.
 191    */
 192 
 193   save_flags (flags);
 194   cli ();
 195 
 196   if (input_avail ())
 197     uart6850_input_loop ();
 198 
 199   restore_flags (flags);
 200 
 201   /*
 202    * Sometimes it takes about 13000 loops before the output becomes ready
 203    * (After reset). Normally it takes just about 10 loops.
 204    */
 205 
 206   for (timeout = 30000; timeout > 0 && !output_ready (); timeout--);    /*
 207                                                                          * Wait
 208                                                                          */
 209 
 210   if (!output_ready ())
 211     {
 212       printk ("Midi6850: Timeout\n");
 213       return 0;
 214     }
 215 
 216   uart6850_write (midi_byte);
 217   return 1;
 218 }
 219 
 220 static int
 221 uart6850_command (int dev, unsigned char *midi_byte)
     /* [previous][next][first][last][top][bottom][index][help] */
 222 {
 223   return 1;
 224 }
 225 
 226 static int
 227 uart6850_start_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 228 {
 229   return 0;
 230 }
 231 
 232 static int
 233 uart6850_end_read (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 234 {
 235   return 0;
 236 }
 237 
 238 static int
 239 uart6850_ioctl (int dev, unsigned cmd, caddr_t arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 240 {
 241   return -EINVAL;
 242 }
 243 
 244 static void
 245 uart6850_kick (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 246 {
 247 }
 248 
 249 static int
 250 uart6850_buffer_status (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 251 {
 252   return 0;                     /*
 253                                  * No data in buffers
 254                                  */
 255 }
 256 
 257 #define MIDI_SYNTH_NAME "6850 UART Midi"
 258 #define MIDI_SYNTH_CAPS SYNTH_CAP_INPUT
 259 #include "midi_synth.h"
 260 
 261 static struct midi_operations uart6850_operations =
 262 {
 263   {"6850 UART", 0, 0, SNDCARD_UART6850},
 264   &std_midi_synth,
 265   {0},
 266   uart6850_open,
 267   uart6850_close,
 268   uart6850_ioctl,
 269   uart6850_out,
 270   uart6850_start_read,
 271   uart6850_end_read,
 272   uart6850_kick,
 273   uart6850_command,
 274   uart6850_buffer_status
 275 };
 276 
 277 
 278 long
 279 attach_uart6850 (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 280 {
 281   int             ok, timeout;
 282   unsigned long   flags;
 283 
 284   if (num_midis >= MAX_MIDI_DEV)
 285     {
 286       printk ("Sound: Too many midi devices detected\n");
 287       return mem_start;
 288     }
 289 
 290   uart6850_base = hw_config->io_base;
 291   uart6850_osp = hw_config->osp;
 292   uart6850_irq = hw_config->irq;
 293 
 294   if (!uart6850_detected)
 295     return -EIO;
 296 
 297   save_flags (flags);
 298   cli ();
 299 
 300   for (timeout = 30000; timeout < 0 && !output_ready (); timeout--);    /*
 301                                                                          * Wait
 302                                                                          */
 303   uart6850_cmd (UART_MODE_ON);
 304 
 305   ok = 1;
 306 
 307   restore_flags (flags);
 308 
 309   conf_printf ("6850 Midi Interface", hw_config);
 310 
 311   std_midi_synth.midi_dev = my_dev = num_midis;
 312   midi_devs[num_midis++] = &uart6850_operations;
 313   return mem_start;
 314 }
 315 
 316 static int
 317 reset_uart6850 (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 318 {
 319   uart6850_read ();
 320   return 1;                     /*
 321                                  * OK
 322                                  */
 323 }
 324 
 325 
 326 int
 327 probe_uart6850 (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 328 {
 329   int             ok = 0;
 330 
 331   uart6850_osp = hw_config->osp;
 332   uart6850_base = hw_config->io_base;
 333   uart6850_irq = hw_config->irq;
 334 
 335   if (snd_set_irq_handler (uart6850_irq, m6850intr, "MIDI6850", uart6850_osp) < 0)
 336     return 0;
 337 
 338   ok = reset_uart6850 ();
 339 
 340   uart6850_detected = ok;
 341   return ok;
 342 }
 343 
 344 void
 345 unload_uart6850 (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 346 {
 347   snd_release_irq (hw_config->irq);
 348 }
 349 
 350 #endif

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