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

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