home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / drivers / sound / sb_midi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-02  |  4.8 KB  |  198 lines

  1. /*
  2.  * sound/sb_dsp.c
  3.  * 
  4.  * The low level driver for the SoundBlaster DS chips.
  5.  * 
  6.  * Copyright by Hannu Savolainen 1993
  7.  * 
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions are
  10.  * met: 1. Redistributions of source code must retain the above copyright
  11.  * notice, this list of conditions and the following disclaimer. 2.
  12.  * Redistributions in binary form must reproduce the above copyright notice,
  13.  * this list of conditions and the following disclaimer in the documentation
  14.  * and/or other materials provided with the distribution.
  15.  * 
  16.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
  17.  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19.  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  20.  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  22.  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23.  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26.  * SUCH DAMAGE.
  27.  * 
  28.  */
  29.  
  30. #include "sound_config.h"
  31.  
  32. #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SB) && !defined(EXCLUDE_MIDI)
  33.  
  34. #include "sb.h"
  35. #undef SB_TEST_IRQ
  36.  
  37. /*
  38.  * The DSP channel can be used either for input or output. Variable
  39.  * 'sb_irq_mode' will be set when the program calls read or write first time
  40.  * after open. Current version doesn't support mode changes without closing
  41.  * and reopening the device. Support for this feature may be implemented in a
  42.  * future version of this driver.
  43.  */
  44.  
  45. extern int      sb_dsp_ok;    /* Set to 1 after successful initialization */
  46.  
  47. extern int      sb_midi_mode;
  48. extern int      sb_midi_busy;    /* 1 if the process has output to MIDI */
  49. extern int      sb_dsp_busy;
  50. extern int      sb_dsp_highspeed;
  51.  
  52. extern volatile int sb_irq_mode;    /* IMODE_INPUT, IMODE_OUTPUT
  53.                      * or IMODE_NONE */
  54. extern int      sb_dsp_model;    /* 1=SB, 2=SB Pro */
  55. extern int      sb_duplex_midi;
  56. extern int      sb_intr_active;
  57.  
  58. static int
  59. sb_midi_open (int dev, int mode,
  60.           void            (*input) (int dev, unsigned char data),
  61.           void            (*output) (int dev)
  62. )
  63. {
  64.   int             ret;
  65.  
  66.   if (!sb_dsp_ok)
  67.     {
  68.       printk ("SB Error: MIDI hardware not installed\n");
  69.       return RET_ERROR (ENXIO);
  70.     }
  71.  
  72.   if (mode != OPEN_WRITE && !sb_duplex_midi)
  73.     {
  74.       if (num_midis == 1)
  75.     printk ("SoundBlaster: Midi input not currently supported\n");
  76.       return RET_ERROR (EPERM);
  77.     }
  78.  
  79.   sb_midi_mode = NORMAL_MIDI;
  80.   if (mode != OPEN_WRITE)
  81.     {
  82.       if (sb_dsp_busy || sb_intr_active)
  83.     return RET_ERROR (EBUSY);
  84.       sb_midi_mode = UART_MIDI;
  85.     }
  86.  
  87.   if (sb_dsp_highspeed)
  88.     {
  89.       printk ("SB Error: Midi output not possible during stereo or high speed audio\n");
  90.       return RET_ERROR (EBUSY);
  91.     }
  92.  
  93.   if (sb_midi_mode == UART_MIDI)
  94.     {
  95.       sb_irq_mode = IMODE_MIDI;
  96.  
  97.       sb_reset_dsp ();
  98.  
  99.       if (!sb_dsp_command (0x35))
  100.     return RET_ERROR (EIO);    /* Enter the UART mode */
  101.       sb_intr_active = 1;
  102.  
  103.       if ((ret = sb_get_irq ()) < 0)
  104.     {
  105.       sb_reset_dsp ();
  106.       return 0;        /* IRQ not free */
  107.     }
  108.     }
  109.  
  110.   sb_midi_busy = 1;
  111.  
  112.   return 0;
  113. }
  114.  
  115. static void
  116. sb_midi_close (int dev)
  117. {
  118.   if (sb_midi_mode == UART_MIDI)
  119.     {
  120.       sb_reset_dsp ();        /* The only way to kill the UART mode */
  121.       sb_free_irq ();
  122.     }
  123.   sb_intr_active = 0;
  124.   sb_midi_busy = 0;
  125. }
  126.  
  127. static int
  128. sb_midi_out (int dev, unsigned char midi_byte)
  129. {
  130.   unsigned long   flags;
  131.  
  132.   sb_midi_busy = 1;        /* Kill all notes after close */
  133.  
  134.   if (sb_midi_mode == NORMAL_MIDI)
  135.     {
  136.       DISABLE_INTR (flags);
  137.       if (sb_dsp_command (0x38))
  138.     sb_dsp_command (midi_byte);
  139.       else
  140.     printk ("SB Error: Unable to send a MIDI byte\n");
  141.       RESTORE_INTR (flags);
  142.     }
  143.   else
  144.     sb_dsp_command (midi_byte);    /* UART write */
  145.  
  146.   return 1;
  147. }
  148.  
  149. static int
  150. sb_midi_start_read (int dev)
  151. {
  152.   if (sb_midi_mode != UART_MIDI)
  153.     {
  154.       printk ("SoundBlaster: MIDI input not implemented.\n");
  155.       return RET_ERROR (EPERM);
  156.     }
  157.   return 0;
  158. }
  159.  
  160. static int
  161. sb_midi_end_read (int dev)
  162. {
  163.   if (sb_midi_mode == UART_MIDI)
  164.     {
  165.       sb_reset_dsp ();
  166.       sb_intr_active = 0;
  167.     }
  168.   return 0;
  169. }
  170.  
  171. static int
  172. sb_midi_ioctl (int dev, unsigned cmd, unsigned arg)
  173. {
  174.   return RET_ERROR (EPERM);
  175. }
  176.  
  177. static struct midi_operations sb_midi_operations =
  178. {
  179.   {"SoundBlaster", 0, 0, SNDCARD_SB},
  180.   sb_midi_open,
  181.   sb_midi_close,
  182.   sb_midi_ioctl,
  183.   sb_midi_out,
  184.   sb_midi_start_read,
  185.   sb_midi_end_read,
  186.   NULL,                /* Kick */
  187.   NULL,                /* command */
  188.   NULL                /* buffer_status */
  189. };
  190.  
  191. void
  192. sb_midi_init(int model)
  193. {
  194.   midi_devs[num_midis++] = &sb_midi_operations;
  195. }
  196.  
  197. #endif
  198.