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: 82C929 detected???\n");
 236     }
 237   else
 238     {
 239       unsigned char model;
 240 
 241       if (((model=mad_read (MC3_PORT)) & 0x03) == 0x03)
 242         {
 243           printk ("mad16.c: Mozart detected???\n");
 244           board_type = MOZART;
 245         }
 246       else
 247         {
 248           printk ("mad16.c: 82C928 detected???\n");
 249           board_type = C928;
 250         }
 251     }
 252 
 253   for (i = 0xf8d; i <= 0xf93; i++)
 254     DDB (printk ("port %03x = %03x\n", i, mad_read (i)));
 255 
 256 /*
 257  * Set the WSS address
 258  */
 259 
 260   tmp = 0x80;                   /* Enable WSS, Disable SB */
 261 
 262   for (i = 0; i < 5; i++)
 263     {
 264       if (i > 3)                /* Not a valid port */
 265         {
 266           printk ("MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base);
 267           return 0;
 268         }
 269 
 270       if (valid_ports[i] == hw_config->io_base)
 271         {
 272           tmp |= i << 4;        /* WSS port select bits */
 273           break;
 274         }
 275     }
 276 
 277 /*
 278  * Set optional CD-ROM and joystick settings.
 279  */
 280 
 281 #ifdef MAD16_CONF
 282   tmp |= ((MAD16_CONF) & 0x0f); /* CD-ROM and joystick bits */
 283 #endif
 284   mad_write (MC1_PORT, tmp);
 285 
 286 #if defined(MAD16_CONF) && defined(MAD16_CDSEL)
 287   tmp = MAD16_CDSEL;
 288 #else
 289   tmp = 0x03;
 290 #endif
 291 
 292 #ifdef MAD16_OPL4
 293   tmp |= 0x20;                  /* Enable OPL4 access */
 294 #endif
 295 
 296   mad_write (MC2_PORT, tmp);
 297   mad_write (MC3_PORT, 0xf0);   /* Disable SB */
 298 
 299   if (board_type == C929)
 300     {
 301       mad_write (MC4_PORT, 0xa2);
 302       mad_write (MC5_PORT, 0x95);       /* AD184x mode (0x9f for CS42xx) */
 303       mad_write (MC6_PORT, 0x03);       /* Disable MPU401 */
 304     }
 305   else
 306     {
 307       mad_write (MC4_PORT, 0x02);
 308       mad_write (MC5_PORT, 0x10);       /* AD184x mode (0x12 for CS42xx) */
 309     }
 310 
 311   for (i = 0xf8d; i <= 0xf93; i++)
 312     DDB (printk ("port %03x after init = %03x\n", i, mad_read (i)));
 313 
 314   return probe_ms_sound (hw_config);
 315 }
 316 
 317 long
 318 attach_mad16 (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 319 {
 320 
 321   already_initialized = 1;
 322 
 323   return attach_ms_sound (mem_start, hw_config);
 324 }
 325 
 326 long
 327 attach_mad16_mpu (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 328 {
 329 
 330 #ifdef EXCLUDE_MIDI
 331   return mem_start;
 332 #else
 333   if (!already_initialized)
 334     return mem_start;
 335 
 336   return attach_mpu401 (mem_start, hw_config);
 337 #endif
 338 }
 339 
 340 int
 341 probe_mad16_mpu (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 342 {
 343 #ifdef EXCLUDE_MIDI
 344   return 0;
 345 #else
 346   static int      mpu_attached = 0;
 347   static int      valid_ports[] =
 348   {0x330, 0x320, 0x310, 0x300};
 349   static short    valid_irqs[] =
 350   {9, 10, 5, 7};
 351   unsigned char   tmp;
 352 
 353   int             i;            /* A variable with secret power */
 354 
 355   if (!already_initialized)     /* The MSS port must be initialized first */
 356     return 0;
 357 
 358   if (mpu_attached)             /* Don't let them call this twice */
 359     return 0;
 360   mpu_attached = 1;
 361 
 362   if (board_type < C929)        /* Early chip. No MPU support */
 363     {
 364       printk ("Mozart and OPTi 82C928 based cards don't support MPU401. Sorry\n");
 365       return 0;
 366     }
 367 
 368   tmp = 0x80;                   /* MPU-401 enable */
 369 
 370 /*
 371  * Set the MPU base bits
 372  */
 373 
 374   for (i = 0; i < 5; i++)
 375     {
 376       if (i > 3)                /* Out of array bounds */
 377         {
 378           printk ("MAD16 / Mozart: Invalid MIDI port 0x%x\n", hw_config->io_base);
 379           return 0;
 380         }
 381 
 382       if (valid_ports[i] == hw_config->io_base)
 383         {
 384           tmp |= i << 5;
 385           break;
 386         }
 387     }
 388 
 389 /*
 390  * Set the MPU IRQ bits
 391  */
 392 
 393   for (i = 0; i < 5; i++)
 394     {
 395       if (i > 3)                /* Out of array bounds */
 396         {
 397           printk ("MAD16 / Mozart: Invalid MIDI IRQ %d\n", hw_config->irq);
 398           return 0;
 399         }
 400 
 401       if (valid_irqs[i] == hw_config->irq)
 402         {
 403           tmp |= i << 3;
 404           break;
 405         }
 406 
 407       tmp |= 0x03;              /* ???????? */
 408       mad_write (MC6_PORT, tmp);        /* Write MPU401 config */
 409     }
 410 
 411   return probe_mpu401 (hw_config);
 412 #endif
 413 }
 414 
 415 /* That's all folks */
 416 #endif

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