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

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