root/drivers/sound/maui.c

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

DEFINITIONS

This source file includes following definitions.
  1. maui_read
  2. maui_write
  3. mauiintr
  4. maui_load_patch
  5. probe_maui
  6. attach_maui
  7. unload_maui

   1 /*
   2  * sound/maui.c
   3  *
   4  * The low level driver for Turtle Beach Maui and Tropez.
   5  */
   6 /*
   7  * Copyright by Hannu Savolainen 1993-1996
   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 #include <linux/config.h>
  30 
  31 
  32 #define USE_SEQ_MACROS
  33 #define USE_SIMPLE_MACROS
  34 
  35 #include "sound_config.h"
  36 
  37 #if defined(CONFIG_MAUI)
  38 
  39 static int      maui_base = 0x330;
  40 
  41 static volatile int irq_ok = 0;
  42 static int     *maui_osp;
  43 
  44 #define HOST_DATA_PORT  (maui_base + 2)
  45 #define HOST_STAT_PORT  (maui_base + 3)
  46 #define HOST_CTRL_PORT  (maui_base + 3)
  47 
  48 #define STAT_TX_INTR    0x40
  49 #define STAT_TX_AVAIL   0x20
  50 #define STAT_TX_IENA    0x10
  51 #define STAT_RX_INTR    0x04
  52 #define STAT_RX_AVAIL   0x02
  53 #define STAT_RX_IENA    0x01
  54 
  55 static int      (*orig_load_patch) (int dev, int format, const char *addr,
  56                                  int offs, int count, int pmgr_flag) = NULL;
  57 
  58 static int
  59 maui_read (void)
     /* [previous][next][first][last][top][bottom][index][help] */
  60 {
  61   int             timeout;
  62 
  63   for (timeout = 0; timeout < 1000000; timeout++)
  64     {
  65       if (inb (HOST_STAT_PORT) & STAT_RX_AVAIL)
  66         {
  67           return inb (HOST_DATA_PORT);
  68         }
  69     }
  70 
  71   printk ("Maui: Receive timeout\n");
  72 
  73   return -1;
  74 }
  75 
  76 static int
  77 maui_write (unsigned char data)
     /* [previous][next][first][last][top][bottom][index][help] */
  78 {
  79   int             timeout;
  80 
  81   for (timeout = 0; timeout < 10000000; timeout++)
  82     {
  83       if (inb (HOST_STAT_PORT) & STAT_TX_AVAIL)
  84         {
  85           outb (data, HOST_DATA_PORT);
  86           return 1;
  87         }
  88     }
  89 
  90   printk ("Maui: Write timeout\n");
  91 
  92   return 0;
  93 }
  94 
  95 void
  96 mauiintr (int irq, struct pt_regs *dummy)
     /* [previous][next][first][last][top][bottom][index][help] */
  97 {
  98   irq_ok = 1;
  99 }
 100 
 101 
 102 int
 103 maui_load_patch (int dev, int format, const char *addr,
     /* [previous][next][first][last][top][bottom][index][help] */
 104                  int offs, int count, int pmgr_flag)
 105 {
 106 
 107   struct sysex_info header;
 108   unsigned long   left, src_offs;
 109   int             hdr_size = (unsigned long) &header.data[0] - (unsigned long) &header;
 110   int             i;
 111 
 112   if (format == SYSEX_PATCH)    /* Handled by midi_synth.c */
 113     return orig_load_patch (dev, format, addr, offs, count, pmgr_flag);
 114 
 115   if (format != MAUI_PATCH)
 116     {
 117       printk ("Maui: Unknown patch format\n");
 118     }
 119 
 120   if (count < hdr_size)
 121     {
 122       printk ("Maui error: Patch header too short\n");
 123       return -EINVAL;
 124     }
 125 
 126   count -= hdr_size;
 127 
 128   /*
 129    * Copy the header from user space but ignore the first bytes which have
 130    * been transferred already.
 131    */
 132 
 133   memcpy_fromfs (&((char *) &header)[offs], &((addr)[offs]), hdr_size - offs);
 134 
 135   if (count < header.len)
 136     {
 137       printk ("Maui warning: Host command record too short (%d<%d)\n",
 138               count, (int) header.len);
 139       header.len = count;
 140     }
 141 
 142   left = header.len;
 143   src_offs = 0;
 144 
 145   for (i = 0; i < left; i++)
 146     {
 147       unsigned char   data;
 148 
 149       data = get_fs_byte (&((addr)[hdr_size + i]));
 150       if (i == 0 && !(data & 0x80))
 151         return -EINVAL;
 152 
 153       if (maui_write (data) == -1)
 154         return -EIO;
 155     }
 156 
 157   if ((i = maui_read ()) != 0x80)
 158     {
 159       if (i != -1)
 160         printk ("Maui: Error status %02x\n", i);
 161 
 162       return -EIO;
 163     }
 164 
 165   return 0;
 166 }
 167 
 168 int
 169 probe_maui (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 170 {
 171   int             i;
 172   int             tmp1, tmp2;
 173 
 174   if (check_region (hw_config->io_base, 8))
 175     return 0;
 176 
 177   maui_base = hw_config->io_base;
 178   maui_osp = hw_config->osp;
 179 
 180   if (snd_set_irq_handler (hw_config->irq, mauiintr, "Maui", maui_osp) < 0)
 181     return 0;
 182 
 183 
 184   if (!maui_write (0xCF))       /* Report hardware version */
 185     {
 186       snd_release_irq (hw_config->irq);
 187       return 0;
 188     }
 189 
 190   if ((tmp1 = maui_read ()) == -1 || (tmp2 = maui_read ()) == -1)
 191     {
 192       snd_release_irq (hw_config->irq);
 193       return 0;
 194     }
 195 
 196   if (trace_init)
 197     printk ("WaveFront hardware version %d.%d\n", tmp1, tmp2);
 198 
 199   if (!maui_write (0x9F))       /* Report firmware version */
 200     return 0;
 201   if ((tmp1 = maui_read ()) == -1 || (tmp2 = maui_read ()) == -1)
 202     return 0;
 203 
 204   if (trace_init)
 205     printk ("WaveFront firmware version %d.%d\n", tmp1, tmp2);
 206 
 207   if (!maui_write (0x85))       /* Report free DRAM */
 208     return 0;
 209   tmp1 = 0;
 210   for (i = 0; i < 4; i++)
 211     {
 212       tmp1 |= maui_read () << (7 * i);
 213     }
 214   if (trace_init)
 215     printk ("Available DRAM %dk\n", tmp1 / 1024);
 216 
 217   request_region (hw_config->io_base + 2, 6, "Maui");
 218 
 219   for (i = 0; i < 1000; i++)
 220     if (probe_mpu401 (hw_config))
 221       break;
 222 
 223   return probe_mpu401 (hw_config);
 224 }
 225 
 226 long
 227 attach_maui (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 228 {
 229   int             this_dev = num_midis;
 230 
 231   conf_printf ("Maui", hw_config);
 232 
 233   hw_config->irq *= -1;
 234   mem_start = attach_mpu401 (mem_start, hw_config);
 235 
 236   if (num_midis > this_dev)     /* The MPU401 driver installed itself */
 237     {
 238       struct synth_operations *synth;
 239 
 240       /*
 241        * Intercept patch loading calls so that they canbe handled
 242        * by the Maui driver.
 243        */
 244 
 245       synth = midi_devs[this_dev]->converter;
 246 
 247       if (synth != NULL)
 248         {
 249           orig_load_patch = synth->load_patch;
 250           synth->load_patch = &maui_load_patch;
 251         }
 252       else
 253         printk ("Maui: Can't install patch loader\n");
 254     }
 255   return mem_start;
 256 }
 257 
 258 void
 259 unload_maui (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 260 {
 261   int             irq = hw_config->irq;
 262 
 263   release_region (hw_config->io_base + 2, 6);
 264 
 265   unload_mpu401 (hw_config);
 266 
 267   if (irq < 0)
 268     irq = -irq;
 269 
 270   if (irq > 0)
 271     snd_release_irq (irq);
 272 }
 273 
 274 
 275 #endif

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