root/drivers/sound/trix.c

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

DEFINITIONS

This source file includes following definitions.
  1. trix_read
  2. trix_write
  3. download_boot
  4. trix_set_wss_port
  5. probe_trix_wss
  6. attach_trix_wss
  7. probe_trix_sb
  8. attach_trix_sb
  9. attach_trix_mpu
  10. probe_trix_mpu

   1 /*
   2  * sound/trix.c
   3  *
   4  * Low level driver for the MediaTriX AudioTriX Pro
   5  * (MT-0002-PC Control Chip)
   6  *
   7  * Copyright by Hannu Savolainen 1995
   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(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_TRIX)
  34 
  35 #ifdef INCLUDE_TRIX_BOOT
  36 #include "trix_boot.h"
  37 #endif
  38 
  39 static int      kilroy_was_here = 0;    /* Don't detect twice */
  40 static int      sb_initialized = 0;
  41 static int      mpu_initialized = 0;
  42 
  43 static unsigned char
  44 trix_read (int addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  45 {
  46   OUTB ((unsigned char) addr, 0x390);   /* MT-0002-PC ASIC address */
  47   return INB (0x391);           /* MT-0002-PC ASIC data */
  48 }
  49 
  50 static void
  51 trix_write (int addr, int data)
     /* [previous][next][first][last][top][bottom][index][help] */
  52 {
  53   OUTB ((unsigned char) addr, 0x390);   /* MT-0002-PC ASIC address */
  54   OUTB ((unsigned char) data, 0x391);   /* MT-0002-PC ASIC data */
  55 }
  56 
  57 static void
  58 download_boot (int base)
     /* [previous][next][first][last][top][bottom][index][help] */
  59 {
  60 #ifdef INCLUDE_TRIX_BOOT
  61   int             i = 0, n = sizeof (trix_boot);
  62 
  63   trix_write (0xf8, 0x00);      /* ??????? */
  64   OUTB (0x01, base + 6);        /* Clear the internal data pointer */
  65   OUTB (0x00, base + 6);        /* Restart */
  66 
  67   /*
  68      *  Write the boot code to the RAM upload/download register.
  69      *  Each write increments the internal data pointer.
  70    */
  71   OUTB (0x01, base + 6);        /* Clear the internal data pointer */
  72   OUTB (0x1A, 0x390);           /* Select RAM download/upload port */
  73 
  74   for (i = 0; i < n; i++)
  75     OUTB (trix_boot[i], 0x391);
  76   for (i = n; i < 10016; i++)   /* Clear up to first 16 bytes of data RAM */
  77     OUTB (0x00, 0x391);
  78   OUTB (0x00, base + 6);        /* Reset */
  79   OUTB (0x50, 0x390);           /* ?????? */
  80 #endif
  81 }
  82 
  83 static int
  84 trix_set_wss_port (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
  85 {
  86   unsigned char   addr_bits;
  87 
  88   if (kilroy_was_here)          /* Already initialized */
  89     return 0;
  90 
  91   kilroy_was_here = 1;
  92 
  93   if (trix_read (0x15) != 0x71) /* No asic signature */
  94     return 0;
  95 
  96   /*
  97      * Disable separate wave playback and recording DMA channels since
  98      * the driver doesn't support duplex mode yet.
  99    */
 100 
 101   trix_write (0x13, trix_read (0x13) & ~0x80);
 102   trix_write (0x14, trix_read (0x14) & ~0x80);
 103 
 104   /*
 105      * Configure the ASIC to place the codec to the proper I/O location
 106    */
 107 
 108   switch (hw_config->io_base)
 109     {
 110     case 0x530:
 111       addr_bits = 0;
 112       break;
 113     case 0x604:
 114       addr_bits = 1;
 115       break;
 116     case 0xE80:
 117       addr_bits = 2;
 118       break;
 119     case 0xF40:
 120       addr_bits = 3;
 121       break;
 122     default:
 123       return 0;
 124     }
 125 
 126   trix_write (0x19, (trix_read (0x19) & 0x03) | addr_bits);
 127   return 1;
 128 }
 129 
 130 /*
 131  *    Probe and attach routines for the Windows Sound System mode of
 132  *      AudioTriX Pro
 133  */
 134 
 135 int
 136 probe_trix_wss (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 137 {
 138   /*
 139      * Check if the IO port returns valid signature. The original MS Sound
 140      * system returns 0x04 while some cards (AudioTriX Pro for example)
 141      * return 0x00.
 142    */
 143   if (!trix_set_wss_port (hw_config))
 144     return 0;
 145 
 146   if ((INB (hw_config->io_base + 3) & 0x3f) != 0x00)
 147     {
 148       DDB (printk ("No MSS signature detected on port 0x%x\n", hw_config->io_base));
 149       return 0;
 150     }
 151 
 152   if (hw_config->irq > 11)
 153     {
 154       printk ("AudioTriX: Bad WSS IRQ %d\n", hw_config->irq);
 155       return 0;
 156     }
 157 
 158   if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
 159     {
 160       printk ("AudioTriX: Bad WSS DMA %d\n", hw_config->dma);
 161       return 0;
 162     }
 163 
 164   /*
 165      * Check that DMA0 is not in use with a 8 bit board.
 166    */
 167 
 168   if (hw_config->dma == 0 && INB (hw_config->io_base + 3) & 0x80)
 169     {
 170       printk ("AudioTriX: Can't use DMA0 with a 8 bit card\n");
 171       return 0;
 172     }
 173 
 174   if (hw_config->irq > 7 && hw_config->irq != 9 && INB (hw_config->io_base + 3) & 0x80)
 175     {
 176       printk ("AudioTriX: Can't use IRQ%d with a 8 bit card\n", hw_config->irq);
 177       return 0;
 178     }
 179 
 180   return ad1848_detect (hw_config->io_base + 4);
 181 }
 182 
 183 long
 184 attach_trix_wss (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 185 {
 186   static unsigned char interrupt_bits[12] =
 187   {-1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20};
 188   char            bits;
 189 
 190   static unsigned char dma_bits[4] =
 191   {1, 2, 0, 3};
 192 
 193   int             config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3;
 194 
 195   if (!kilroy_was_here)
 196     return mem_start;
 197 
 198   /*
 199      * Set the IRQ and DMA addresses.
 200    */
 201 
 202   bits = interrupt_bits[hw_config->irq];
 203   if (bits == -1)
 204     return mem_start;
 205 
 206   OUTB (bits | 0x40, config_port);
 207   if ((INB (version_port) & 0x40) == 0)
 208     printk ("[IRQ Conflict?]");
 209 
 210   OUTB (bits | dma_bits[hw_config->dma], config_port);  /* Write IRQ+DMA setup */
 211 
 212   ad1848_init ("AudioTriX Pro", hw_config->io_base + 4,
 213                hw_config->irq,
 214                hw_config->dma,
 215                hw_config->dma);
 216   return mem_start;
 217 }
 218 
 219 int
 220 probe_trix_sb (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 221 {
 222 
 223   int             tmp;
 224   unsigned char   conf;
 225   static char     irq_translate[] =
 226   {-1, -1, -1, 0, 1, 2, -1, 3};
 227 
 228 #ifndef INCLUDE_TRIX_BOOT
 229   return 0;                     /* No boot code -> no fun */
 230 #endif
 231   if (!kilroy_was_here)
 232     return 0;                   /* AudioTriX Pro has not been detected earlier */
 233 
 234   if (sb_initialized)
 235     return 0;
 236 
 237   if (hw_config->io_base & 0xffffff8f != 0x200)
 238     return 0;
 239 
 240   tmp = hw_config->irq;
 241   if (tmp > 7)
 242     return 0;
 243   if (irq_translate[tmp] == -1)
 244     return 0;
 245 
 246   tmp = hw_config->dma;
 247   if (tmp != 1 && tmp != 3)
 248     return 0;
 249 
 250   conf = 0x84;                  /* DMA and IRQ enable */
 251   conf |= hw_config->io_base & 0x70;    /* I/O address bits */
 252   conf |= irq_translate[hw_config->irq];
 253   if (hw_config->dma == 3)
 254     conf |= 0x08;
 255   trix_write (0x1b, conf);
 256 
 257   download_boot (hw_config->io_base);
 258   sb_initialized = 1;
 259 
 260   return 1;
 261 }
 262 
 263 long
 264 attach_trix_sb (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 265 {
 266 #ifndef EXCLUDE_SB
 267   extern int      sb_no_recording;
 268 
 269   sb_dsp_disable_midi ();
 270   sb_no_recording = 1;
 271 #endif
 272   printk (" <AudioTriX (SB)>");
 273   return mem_start;
 274 }
 275 
 276 long
 277 attach_trix_mpu (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 278 {
 279   return attach_mpu401 (mem_start, hw_config);
 280 }
 281 
 282 int
 283 probe_trix_mpu (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 284 {
 285   unsigned char   conf;
 286   static char     irq_bits[] =
 287   {-1, -1, -1, 1, 2, 3, -1, 4, -1, 5};
 288 
 289   if (!kilroy_was_here)
 290     return 0;                   /* AudioTriX Pro has not been detected earlier */
 291 
 292   if (!sb_initialized)
 293     return 0;
 294 
 295   if (mpu_initialized)
 296     return 0;
 297 
 298   if (hw_config->irq > 9)
 299     return 0;
 300 
 301   if (irq_bits[hw_config->irq] == -1)
 302     return 0;
 303 
 304   switch (hw_config->io_base)
 305     {
 306     case 0x330:
 307       conf = 0x00;
 308       break;
 309     case 0x370:
 310       conf = 0x04;
 311       break;
 312     case 0x3b0:
 313       conf = 0x08;
 314       break;
 315     case 0x3f0:
 316       conf = 0x0c;
 317       break;
 318     default:
 319       return 0;                 /* Invalid port */
 320     }
 321 
 322   conf |= irq_bits[hw_config->irq] << 4;
 323 
 324   trix_write (0x19, (trix_read (0x19) & 0x83) | conf);
 325 
 326   mpu_initialized = 1;
 327 
 328   return probe_mpu401 (hw_config);
 329 }
 330 
 331 #endif

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