root/drivers/sound/mad16.c

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

DEFINITIONS

This source file includes following definitions.
  1. mad_read
  2. mad_write
  3. detect_mad16
  4. probe_mad16
  5. attach_mad16
  6. attach_mad16_mpu
  7. probe_mad16_mpu

   1 #define MAD16_OPL4              /* Disable this if you have problems with OPL3 */
   2 /*
   3  * sound/mad16.c
   4  *
   5  * Initialization code for OPTi MAD16 compatible audio chips. Including
   6  *
   7  *      OPTi 82C928     MAD16           (replaced by C929)
   8  *      OAK OTI-601D    Mozart
   9  *      OPTi 82C929     MAD16 Pro
  10  *
  11  * These audio interface chips don't prduce sound themselves. They just
  12  * connect some other components (OPL-[234] and a WSS compatible codec)
  13  * to the PC bus and perform I/O, DMA and IRQ address decoding. There is
  14  * also a UART for the MPU-401 mode (not 82C928/Mozart).
  15  * The Mozart chip appears to be compatible with the 82C928 (can anybody
  16  * confirm this?).
  17  *
  18  * NOTE! If you want to set CD-ROM address and/or joystick enable, define
  19  *       MAD16_CONF in local.h as combination of the following bits:
  20  *
  21  *      0x01    - joystick disabled
  22  *
  23  *      CD-ROM type selection (select just one):
  24  *      0x00    - none
  25  *      0x02    - Sony 31A
  26  *      0x04    - Mitsumi
  27  *      0x06    - Panasonic (type "LaserMate", not "SoundBlaster")
  28  *      0x08    - Secondary IDE (address 0x170)
  29  *      0x0a    - Primary IDE (address 0x1F0)
  30  *      
  31  *      For example Mitsumi with joystick disabled = 0x04|0x01 = 0x05
  32  *      For example LaserMate (for use with sbpcd) plus joystick = 0x06
  33  *      
  34  *    MAD16_CDSEL:
  35  *      This defaults to CD I/O 0x340, no IRQ and DMA3 
  36  *      (DMA5 with Mitsumi or IDE). If you like to change these, define
  37  *      MAD16_CDSEL with the following bits:
  38  *
  39  *      CD-ROM port: 0x00=340, 0x40=330, 0x80=360 or 0xc0=320
  40  *      OPL4 select: 0x20=OPL4, 0x00=OPL3
  41  *      CD-ROM irq: 0x00=disabled, 0x04=IRQ5, 0x08=IRQ7, 0x0a=IRQ3, 0x10=IRQ9,
  42  *                  0x14=IRQ10 and 0x18=IRQ11.
  43  *
  44  *      CD-ROM DMA (Sony or Panasonic): 0x00=DMA3, 0x01=DMA2, 0x02=DMA1 or 0x03=disabled
  45  *   or
  46  *      CD-ROM DMA (Mitsumi or IDE):    0x00=DMA5, 0x01=DMA6, 0x02=DMA7 or 0x03=disabled
  47  *
  48  *      For use with sbpcd, address 0x340, set MAD16_CDSEL to 0x03 or 0x23.
  49  *
  50  * Copyright by Hannu Savolainen 1995
  51  *
  52  * Redistribution and use in source and binary forms, with or without
  53  * modification, are permitted provided that the following conditions are
  54  * met: 1. Redistributions of source code must retain the above copyright
  55  * notice, this list of conditions and the following disclaimer. 2.
  56  * Redistributions in binary form must reproduce the above copyright notice,
  57  * this list of conditions and the following disclaimer in the documentation
  58  * and/or other materials provided with the distribution.
  59  *
  60  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
  61  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  62  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  63  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  64  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  65  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  66  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  67  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  68  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  69  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  70  * SUCH DAMAGE.
  71  *
  72  */
  73 
  74 #include "sound_config.h"
  75 
  76 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_MAD16)
  77 
  78 static int      already_initialized = 0;
  79 
  80 #define C928    1
  81 #define MOZART  2
  82 #define C929    3
  83 
  84 /*
  85  *    Registers
  86  *
  87  *      The MAD16 occupies I/O ports 0xf8d to 0xf93 (fixed locations).
  88  *      All ports are inactive by default. They can be activated by
  89  *      writing 0xE2 or 0xE3 to the password register. The password is valid
  90  *      only until the next I/O read or write.
  91  */
  92 
  93 #define MC1_PORT        0xf8d   /* SB address, CDROM interface type, joystick */
  94 #define MC2_PORT        0xf8e   /* CDROM address, IRQ, DMA, plus OPL4 bit */
  95 #define MC3_PORT        0xf8f
  96 #define PASSWD_REG      0xf8f
  97 #define MC4_PORT        0xf90
  98 #define MC5_PORT        0xf91
  99 #define MC6_PORT        0xf92
 100 #define MC7_PORT        0xf93
 101 
 102 static int      board_type = C928;
 103 
 104 #ifndef DDB
 105 #define DDB(x)
 106 #endif
 107 
 108 static unsigned char
 109 mad_read (int port)
     /* [previous][next][first][last][top][bottom][index][help] */
 110 {
 111   unsigned long   flags;
 112   unsigned char   tmp;
 113 
 114   DISABLE_INTR (flags);
 115 
 116   switch (board_type)           /* Output password */
 117     {
 118     case C928:
 119     case MOZART:
 120       OUTB (0xE2, PASSWD_REG);
 121       break;
 122 
 123     case C929:
 124       OUTB (0xE3, PASSWD_REG);
 125       break;
 126     }
 127 
 128   tmp = INB (port);
 129   RESTORE_INTR (flags);
 130 
 131   return tmp;
 132 }
 133 
 134 static void
 135 mad_write (int port, int value)
     /* [previous][next][first][last][top][bottom][index][help] */
 136 {
 137   unsigned long   flags;
 138 
 139   DISABLE_INTR (flags);
 140 
 141   switch (board_type)           /* Output password */
 142     {
 143     case C928:
 144     case MOZART:
 145       OUTB (0xE2, PASSWD_REG);
 146       break;
 147 
 148     case C929:
 149       OUTB (0xE3, PASSWD_REG);
 150       break;
 151     }
 152 
 153   OUTB ((unsigned char) (value & 0xff), port);
 154   RESTORE_INTR (flags);
 155 }
 156 
 157 static int
 158 detect_mad16 (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 159 {
 160   unsigned char   tmp, tmp2;
 161 
 162 /*
 163  * Check that reading a register doesn't return bus float (0xff)
 164  * when the card is accessed using password. This may fail in case
 165  * the card is in low power mode. Normally at least the power saving mode
 166  * bit should be 0.
 167  */
 168   if ((tmp = mad_read (MC1_PORT)) == 0xff)
 169     {
 170       DDB (printk ("MC1_PORT returned 0xff\n"));
 171       return 0;
 172     }
 173 /*
 174  * Now check that the gate is closed on first I/O after writing
 175  * the password. (This is how a MAD16 compatible card works).
 176  */
 177 
 178   if ((tmp2 = INB (MC1_PORT)) == tmp)   /* It didn't close */
 179     {
 180       DDB (printk ("MC1_PORT didn't close after read (0x%02x)\n", tmp2));
 181       return 0;
 182     }
 183 
 184   mad_write (MC1_PORT, tmp ^ 0x80);     /* Togge a bit */
 185 
 186   if ((tmp2 = mad_read (MC1_PORT)) != (tmp ^ 0x80))     /* Compare the bit */
 187     {
 188       mad_write (MC1_PORT, tmp);        /* Restore */
 189       DDB (printk ("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2));
 190       return 0;
 191     }
 192 
 193   mad_write (MC1_PORT, tmp);    /* Restore */
 194   return 1;                     /* Bingo */
 195 
 196 }
 197 
 198 int
 199 probe_mad16 (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 200 {
 201   int             i;
 202   static int      valid_ports[] =
 203   {0x530, 0xe80, 0xf40, 0x604};
 204   unsigned char   tmp;
 205 
 206   if (already_initialized)
 207     return 0;
 208 
 209 /*
 210  *    Check that all ports return 0xff (bus float) when no password
 211  *      is written to the password register.
 212  */
 213 
 214   DDB (printk ("--- Detecting MAD16 / Mozart ---\n"));
 215 
 216 #if 0
 217   for (i = 0xf8d; i <= 0xf93; i++)
 218     if (INB (i) != 0xff)
 219       {
 220         DDB (printk ("port 0x%03x != 0xff (0x%02x)\n", i, INB (i)));
 221         return 0;
 222       }
 223 #endif
 224 
 225 /*
 226  *    Then try to detect with the old password
 227  */
 228   board_type = C928;
 229 
 230   DDB (printk ("Detect using password = 0xE2\n"));
 231 
 232   if (!detect_mad16 ())         /* No luck. Try different model */
 233     {
 234       board_type = C929;
 235 
 236       DDB (printk ("Detect using password = 0xE3\n"));
 237 
 238       if (!detect_mad16 ())
 239         return 0;
 240 
 241       printk ("mad16.c: 82C929 detected???\n");
 242     }
 243   else
 244     {
 245       unsigned char   model;
 246 
 247       if (((model = mad_read (MC3_PORT)) & 0x03) == 0x03)
 248         {
 249           printk ("mad16.c: Mozart detected???\n");
 250           board_type = MOZART;
 251         }
 252       else
 253         {
 254           printk ("mad16.c: 82C928 detected???\n");
 255           board_type = C928;
 256         }
 257     }
 258 
 259   for (i = 0xf8d; i <= 0xf93; i++)
 260     DDB (printk ("port %03x = %03x\n", i, mad_read (i)));
 261 
 262 /*
 263  * Set the WSS address
 264  */
 265 
 266   tmp = 0x80;                   /* Enable WSS, Disable SB */
 267 
 268   for (i = 0; i < 5; i++)
 269     {
 270       if (i > 3)                /* Not a valid port */
 271         {
 272           printk ("MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base);
 273           return 0;
 274         }
 275 
 276       if (valid_ports[i] == hw_config->io_base)
 277         {
 278           tmp |= i << 4;        /* WSS port select bits */
 279           break;
 280         }
 281     }
 282 
 283 /*
 284  * Set optional CD-ROM and joystick settings.
 285  */
 286 #define MAD16_CONF 0x06
 287 #define MAD16_CDSEL 0x03
 288 
 289 #ifdef MAD16_CONF
 290   tmp |= ((MAD16_CONF) & 0x0f); /* CD-ROM and joystick bits */
 291 #endif
 292   mad_write (MC1_PORT, tmp);
 293 
 294 #if defined(MAD16_CONF) && defined(MAD16_CDSEL)
 295   tmp = MAD16_CDSEL;
 296 #else
 297   tmp = 0x03;
 298 #endif
 299 
 300 #ifdef MAD16_OPL4
 301   tmp |= 0x20;                  /* Enable OPL4 access */
 302 #endif
 303 
 304   mad_write (MC2_PORT, tmp);
 305   mad_write (MC3_PORT, 0xf0);   /* Disable SB */
 306 
 307   if (board_type == C929)
 308     {
 309       mad_write (MC4_PORT, 0xa2);
 310       mad_write (MC5_PORT, 0x95);       /* AD184x mode (0x9f for CS42xx) */
 311       mad_write (MC6_PORT, 0x03);       /* Disable MPU401 */
 312     }
 313   else
 314     {
 315       mad_write (MC4_PORT, 0x02);
 316       mad_write (MC5_PORT, 0x10);       /* AD184x mode (0x12 for CS42xx) */
 317     }
 318 
 319   for (i = 0xf8d; i <= 0xf93; i++)
 320     DDB (printk ("port %03x after init = %03x\n", i, mad_read (i)));
 321 
 322   return probe_ms_sound (hw_config);
 323 }
 324 
 325 long
 326 attach_mad16 (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 327 {
 328 
 329   already_initialized = 1;
 330 
 331   return attach_ms_sound (mem_start, hw_config);
 332 }
 333 
 334 long
 335 attach_mad16_mpu (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 336 {
 337 
 338 #if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI)
 339   if (!already_initialized)
 340     return mem_start;
 341 
 342   return attach_mpu401 (mem_start, hw_config);
 343 #else
 344   return mem_start;
 345 #endif
 346 }
 347 
 348 int
 349 probe_mad16_mpu (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 350 {
 351 #if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI)
 352   static int      mpu_attached = 0;
 353   static int      valid_ports[] =
 354   {0x330, 0x320, 0x310, 0x300};
 355   static short    valid_irqs[] =
 356   {9, 10, 5, 7};
 357   unsigned char   tmp;
 358 
 359   int             i;            /* A variable with secret power */
 360 
 361   if (!already_initialized)     /* The MSS port must be initialized first */
 362     return 0;
 363 
 364   if (mpu_attached)             /* Don't let them call this twice */
 365     return 0;
 366   mpu_attached = 1;
 367 
 368   if (board_type < C929)        /* Early chip. No MPU support */
 369     {
 370       printk ("Mozart and OPTi 82C928 based cards don't support MPU401. Sorry\n");
 371       return 0;
 372     }
 373 
 374   tmp = 0x83;                   /* MPU-401 enable */
 375 
 376 /*
 377  * Set the MPU base bits
 378  */
 379 
 380   for (i = 0; i < 5; i++)
 381     {
 382       if (i > 3)                /* Out of array bounds */
 383         {
 384           printk ("MAD16 / Mozart: Invalid MIDI port 0x%x\n", hw_config->io_base);
 385           return 0;
 386         }
 387 
 388       if (valid_ports[i] == hw_config->io_base)
 389         {
 390           tmp |= i << 5;
 391           break;
 392         }
 393     }
 394 
 395 /*
 396  * Set the MPU IRQ bits
 397  */
 398 
 399   for (i = 0; i < 5; i++)
 400     {
 401       if (i > 3)                /* Out of array bounds */
 402         {
 403           printk ("MAD16 / Mozart: Invalid MIDI IRQ %d\n", hw_config->irq);
 404           return 0;
 405         }
 406 
 407       if (valid_irqs[i] == hw_config->irq)
 408         {
 409           tmp |= i << 3;
 410           break;
 411         }
 412     }
 413   mad_write (MC6_PORT, tmp);    /* Write MPU401 config */
 414 
 415   return probe_mpu401 (hw_config);
 416 #else
 417   return 0;
 418 #endif
 419 }
 420 
 421 /* That's all folks */
 422 #endif

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