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
  8. unload_mad16
  9. unload_mad16_mpu

   1 /*
   2  * Copyright by Hannu Savolainen 1993-1996
   3  *
   4  * Redistribution and use in source and binary forms, with or without
   5  * modification, are permitted provided that the following conditions are
   6  * met: 1. Redistributions of source code must retain the above copyright
   7  * notice, this list of conditions and the following disclaimer. 2.
   8  * Redistributions in binary form must reproduce the above copyright notice,
   9  * this list of conditions and the following disclaimer in the documentation
  10  * and/or other materials provided with the distribution.
  11  *
  12  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
  13  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  14  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  15  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  16  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  17  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  18  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  19  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  20  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  21  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  22  * SUCH DAMAGE.
  23  */
  24 #include <linux/config.h>
  25 
  26 
  27 /*
  28  * sound/mad16.c
  29  *
  30  * Initialization code for OPTi MAD16 compatible audio chips. Including
  31  *
  32  *      OPTi 82C928     MAD16           (replaced by C929)
  33  *      OAK OTI-601D    Mozart
  34  *      OPTi 82C929     MAD16 Pro
  35  *
  36  * These audio interface chips don't prduce sound themselves. They just
  37  * connect some other components (OPL-[234] and a WSS compatible codec)
  38  * to the PC bus and perform I/O, DMA and IRQ address decoding. There is
  39  * also a UART for the MPU-401 mode (not 82C928/Mozart).
  40  * The Mozart chip appears to be compatible with the 82C928 (can anybody
  41  * confirm this?).
  42  *
  43  * NOTE! If you want to set CD-ROM address and/or joystick enable, define
  44  *       MAD16_CONF in local.h as combination of the following bits:
  45  *
  46  *      0x01    - joystick disabled
  47  *
  48  *      CD-ROM type selection (select just one):
  49  *      0x00    - none
  50  *      0x02    - Sony 31A
  51  *      0x04    - Mitsumi
  52  *      0x06    - Panasonic (type "LaserMate", not "SoundBlaster")
  53  *      0x08    - Secondary IDE (address 0x170)
  54  *      0x0a    - Primary IDE (address 0x1F0)
  55  *      
  56  *      For example Mitsumi with joystick disabled = 0x04|0x01 = 0x05
  57  *      For example LaserMate (for use with sbpcd) plus joystick = 0x06
  58  *      
  59  *    MAD16_CDSEL:
  60  *      This defaults to CD I/O 0x340, no IRQ and DMA3 
  61  *      (DMA5 with Mitsumi or IDE). If you like to change these, define
  62  *      MAD16_CDSEL with the following bits:
  63  *
  64  *      CD-ROM port: 0x00=340, 0x40=330, 0x80=360 or 0xc0=320
  65  *      OPL4 select: 0x20=OPL4, 0x00=OPL3
  66  *      CD-ROM irq: 0x00=disabled, 0x04=IRQ5, 0x08=IRQ7, 0x0a=IRQ3, 0x10=IRQ9,
  67  *                  0x14=IRQ10 and 0x18=IRQ11.
  68  *
  69  *      CD-ROM DMA (Sony or Panasonic): 0x00=DMA3, 0x01=DMA2, 0x02=DMA1 or 0x03=disabled
  70  *   or
  71  *      CD-ROM DMA (Mitsumi or IDE):    0x00=DMA5, 0x01=DMA6, 0x02=DMA7 or 0x03=disabled
  72  *
  73  *      For use with sbpcd, address 0x340, set MAD16_CDSEL to 0x03 or 0x23.
  74  */
  75 
  76 #include "sound_config.h"
  77 
  78 #if defined(CONFIG_MAD16)
  79 
  80 static int      already_initialized = 0;
  81 
  82 #define C928    1
  83 #define MOZART  2
  84 #define C929    3
  85 
  86 /*
  87  *    Registers
  88  *
  89  *      The MAD16 occupies I/O ports 0xf8d to 0xf93 (fixed locations).
  90  *      All ports are inactive by default. They can be activated by
  91  *      writing 0xE2 or 0xE3 to the password register. The password is valid
  92  *      only until the next I/O read or write.
  93  */
  94 
  95 #define MC1_PORT        0xf8d   /* SB address, CDROM interface type, joystick */
  96 #define MC2_PORT        0xf8e   /* CDROM address, IRQ, DMA, plus OPL4 bit */
  97 #define MC3_PORT        0xf8f
  98 #define PASSWD_REG      0xf8f
  99 #define MC4_PORT        0xf90
 100 #define MC5_PORT        0xf91
 101 #define MC6_PORT        0xf92
 102 #define MC7_PORT        0xf93
 103 
 104 static int      board_type = C928;
 105 
 106 static int     *mad16_osp;
 107 
 108 #ifndef DDB
 109 #define DDB(x)
 110 #endif
 111 
 112 static unsigned char
 113 mad_read (int port)
     /* [previous][next][first][last][top][bottom][index][help] */
 114 {
 115   unsigned long   flags;
 116   unsigned char   tmp;
 117 
 118   save_flags (flags);
 119   cli ();
 120 
 121   switch (board_type)           /* Output password */
 122     {
 123     case C928:
 124     case MOZART:
 125       outb (0xE2, PASSWD_REG);
 126       break;
 127 
 128     case C929:
 129       outb (0xE3, PASSWD_REG);
 130       break;
 131     }
 132 
 133   tmp = inb (port);
 134   restore_flags (flags);
 135 
 136   return tmp;
 137 }
 138 
 139 static void
 140 mad_write (int port, int value)
     /* [previous][next][first][last][top][bottom][index][help] */
 141 {
 142   unsigned long   flags;
 143 
 144   save_flags (flags);
 145   cli ();
 146 
 147   switch (board_type)           /* Output password */
 148     {
 149     case C928:
 150     case MOZART:
 151       outb (0xE2, PASSWD_REG);
 152       break;
 153 
 154     case C929:
 155       outb (0xE3, PASSWD_REG);
 156       break;
 157     }
 158 
 159   outb ((unsigned char) (value & 0xff), port);
 160   restore_flags (flags);
 161 }
 162 
 163 static int
 164 detect_mad16 (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 165 {
 166   unsigned char   tmp, tmp2;
 167 
 168 /*
 169  * Check that reading a register doesn't return bus float (0xff)
 170  * when the card is accessed using password. This may fail in case
 171  * the card is in low power mode. Normally at least the power saving mode
 172  * bit should be 0.
 173  */
 174   if ((tmp = mad_read (MC1_PORT)) == 0xff)
 175     {
 176       DDB (printk ("MC1_PORT returned 0xff\n"));
 177       return 0;
 178     }
 179 /*
 180  * Now check that the gate is closed on first I/O after writing
 181  * the password. (This is how a MAD16 compatible card works).
 182  */
 183 
 184   if ((tmp2 = inb (MC1_PORT)) == tmp)   /* It didn't close */
 185     {
 186       DDB (printk ("MC1_PORT didn't close after read (0x%02x)\n", tmp2));
 187       return 0;
 188     }
 189 
 190   mad_write (MC1_PORT, tmp ^ 0x80);     /* Togge a bit */
 191 
 192   if ((tmp2 = mad_read (MC1_PORT)) != (tmp ^ 0x80))     /* Compare the bit */
 193     {
 194       mad_write (MC1_PORT, tmp);        /* Restore */
 195       DDB (printk ("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2));
 196       return 0;
 197     }
 198 
 199   mad_write (MC1_PORT, tmp);    /* Restore */
 200   return 1;                     /* Bingo */
 201 
 202 }
 203 
 204 int
 205 probe_mad16 (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 206 {
 207   int             i;
 208   static int      valid_ports[] =
 209   {0x530, 0xe80, 0xf40, 0x604};
 210   unsigned char   tmp;
 211   unsigned char   cs4231_mode = 0;
 212 
 213   int             ad_flags = 0;
 214 
 215   if (already_initialized)
 216     return 0;
 217 
 218   mad16_osp = hw_config->osp;
 219 /*
 220  *    Check that all ports return 0xff (bus float) when no password
 221  *      is written to the password register.
 222  */
 223 
 224   DDB (printk ("--- Detecting MAD16 / Mozart ---\n"));
 225 
 226 
 227 /*
 228  *    Then try to detect with the old password
 229  */
 230   board_type = C928;
 231 
 232   DDB (printk ("Detect using password = 0xE2\n"));
 233 
 234   if (!detect_mad16 ())         /* No luck. Try different model */
 235     {
 236       board_type = C929;
 237 
 238       DDB (printk ("Detect using password = 0xE3\n"));
 239 
 240       if (!detect_mad16 ())
 241         return 0;
 242 
 243       DDB (printk ("mad16.c: 82C929 detected\n"));
 244     }
 245   else
 246     {
 247       unsigned char   model;
 248 
 249       if (((model = mad_read (MC3_PORT)) & 0x03) == 0x03)
 250         {
 251           DDB (printk ("mad16.c: Mozart detected\n"));
 252           board_type = MOZART;
 253         }
 254       else
 255         {
 256           DDB (printk ("mad16.c: 82C928 detected???\n"));
 257           board_type = C928;
 258         }
 259     }
 260 
 261   for (i = 0xf8d; i <= 0xf93; i++)
 262     DDB (printk ("port %03x = %03x\n", i, mad_read (i)));
 263 
 264 /*
 265  * Set the WSS address
 266  */
 267 
 268   tmp = 0x80;                   /* Enable WSS, Disable SB */
 269 
 270   for (i = 0; i < 5; i++)
 271     {
 272       if (i > 3)                /* Not a valid port */
 273         {
 274           printk ("MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base);
 275           return 0;
 276         }
 277 
 278       if (valid_ports[i] == hw_config->io_base)
 279         {
 280           tmp |= i << 4;        /* WSS port select bits */
 281           break;
 282         }
 283     }
 284 
 285 /*
 286  * Set optional CD-ROM and joystick settings.
 287  */
 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 (!ad1848_detect (hw_config->io_base + 4, &ad_flags, mad16_osp))
 308     return 0;
 309 
 310   if (ad_flags & (AD_F_CS4231 | AD_F_CS4248))
 311     cs4231_mode = 0x02;         /* CS4248/CS4231 sync delay switch */
 312 
 313   if (board_type == C929)
 314     {
 315       mad_write (MC4_PORT, 0xa2);
 316       mad_write (MC5_PORT, 0xA5 | cs4231_mode);
 317       mad_write (MC6_PORT, 0x03);       /* Disable MPU401 */
 318     }
 319   else
 320     {
 321       mad_write (MC4_PORT, 0x02);
 322       mad_write (MC5_PORT, 0x30 | cs4231_mode);
 323     }
 324 
 325   for (i = 0xf8d; i <= 0xf93; i++)
 326     DDB (printk ("port %03x after init = %03x\n", i, mad_read (i)));
 327 
 328 /*
 329  *    Verify the WSS parameters
 330  */
 331 
 332   if (check_region (hw_config->io_base, 8))
 333     {
 334       printk ("MSS: I/O port conflict\n");
 335       return 0;
 336     }
 337 
 338   /*
 339      * Check if the IO port returns valid signature. The original MS Sound
 340      * system returns 0x04 while some cards (AudioTriX Pro for example)
 341      * return 0x00.
 342    */
 343 
 344   if ((inb (hw_config->io_base + 3) & 0x3f) != 0x04 &&
 345       (inb (hw_config->io_base + 3) & 0x3f) != 0x00)
 346     {
 347       DDB (printk ("No MSS signature detected on port 0x%x (0x%x)\n",
 348                    hw_config->io_base, inb (hw_config->io_base + 3)));
 349       return 0;
 350     }
 351 
 352   if (hw_config->irq > 11)
 353     {
 354       printk ("MSS: Bad IRQ %d\n", hw_config->irq);
 355       return 0;
 356     }
 357 
 358   if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
 359     {
 360       printk ("MSS: Bad DMA %d\n", hw_config->dma);
 361       return 0;
 362     }
 363 
 364   /*
 365      * Check that DMA0 is not in use with a 8 bit board.
 366    */
 367 
 368   if (hw_config->dma == 0 && inb (hw_config->io_base + 3) & 0x80)
 369     {
 370       printk ("MSS: Can't use DMA0 with a 8 bit card/slot\n");
 371       return 0;
 372     }
 373 
 374   if (hw_config->irq > 7 && hw_config->irq != 9 && inb (hw_config->io_base + 3) & 0x80)
 375     {
 376       printk ("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
 377       return 0;
 378     }
 379 
 380   return 1;
 381 }
 382 
 383 long
 384 attach_mad16 (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 385 {
 386 
 387   static char     interrupt_bits[12] =
 388   {
 389     -1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20
 390   };
 391   char            bits;
 392 
 393   static char     dma_bits[4] =
 394   {
 395     1, 2, 0, 3
 396   };
 397 
 398   int             config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3;
 399   int             ad_flags = 0, dma = hw_config->dma, dma2 = hw_config->dma2;
 400   unsigned char   dma2_bit = 0;
 401 
 402   already_initialized = 1;
 403 
 404   if (!ad1848_detect (hw_config->io_base + 4, &ad_flags, mad16_osp))
 405     return mem_start;
 406 
 407   /*
 408      * Set the IRQ and DMA addresses.
 409    */
 410 
 411   bits = interrupt_bits[hw_config->irq];
 412   if (bits == -1)
 413     return mem_start;
 414 
 415   outb (bits | 0x40, config_port);
 416   if ((inb (version_port) & 0x40) == 0)
 417     printk ("[IRQ Conflict?]");
 418 
 419 /*
 420  * Handle the capture DMA channel
 421  */
 422 
 423   if (ad_flags & AD_F_CS4231 && dma2 != -1 && dma2 != dma)
 424     {
 425       if ((dma == 0 && dma2 == 1) ||
 426           (dma == 1 && dma2 == 0) ||
 427           (dma == 3 && dma2 == 0))
 428         {
 429           dma2_bit = 0x04;      /* Enable capture DMA */
 430 
 431           /* Change SB DMA so that it doesn't conflict with codec's DMAs */
 432 
 433           if (dma == 3)
 434             mad_write (MC3_PORT, (mad_read (MC3_PORT) & ~0x30) | 0x00);         /*DMA1 */
 435           else
 436             mad_write (MC3_PORT, (mad_read (MC3_PORT) & ~0x30) | 0x20);         /*DMA3 */
 437         }
 438       else
 439         {
 440           printk ("MAD16: Invalid capture DMA\n");
 441           dma2 = dma;
 442         }
 443     }
 444   else
 445     dma2 = dma;
 446 
 447   outb (bits | dma_bits[dma] | dma2_bit, config_port);  /* Write IRQ+DMA setup */
 448 
 449   ad1848_init ("MAD16 WSS", hw_config->io_base + 4,
 450                hw_config->irq,
 451                dma,
 452                dma2, 0,
 453                hw_config->osp);
 454   request_region (hw_config->io_base, 4, "MAD16 WSS config");
 455 
 456   return mem_start;
 457 }
 458 
 459 long
 460 attach_mad16_mpu (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 461 {
 462   if (board_type < C929)        /* Early chip. No MPU support. Just SB MIDI */
 463     {
 464 #ifdef CONFIG_MIDI
 465 
 466       if (mad_read (MC1_PORT) & 0x20)
 467         hw_config->io_base = 0x240;
 468       else
 469         hw_config->io_base = 0x220;
 470 
 471       return mad16_sb_dsp_init (mem_start, hw_config);
 472 #else
 473       return 0;
 474 #endif
 475     }
 476 
 477 #if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
 478   if (!already_initialized)
 479     return mem_start;
 480 
 481   return attach_mpu401 (mem_start, hw_config);
 482 #else
 483   return mem_start;
 484 #endif
 485 }
 486 
 487 int
 488 probe_mad16_mpu (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 489 {
 490 #if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
 491   static int      mpu_attached = 0;
 492   static int      valid_ports[] =
 493   {0x330, 0x320, 0x310, 0x300};
 494   static short    valid_irqs[] =
 495   {9, 10, 5, 7};
 496   unsigned char   tmp;
 497 
 498   int             i;            /* A variable with secret power */
 499 
 500   if (!already_initialized)     /* The MSS port must be initialized first */
 501     return 0;
 502 
 503   if (mpu_attached)             /* Don't let them call this twice */
 504     return 0;
 505   mpu_attached = 1;
 506 
 507   if (board_type < C929)        /* Early chip. No MPU support. Just SB MIDI */
 508     {
 509 
 510 #ifdef CONFIG_MIDI
 511       unsigned char   tmp;
 512 
 513       tmp = mad_read (MC3_PORT);
 514 
 515       /* 
 516        * MAD16 SB base is defined by the WSS base. It cannot be changed 
 517        * alone.
 518        * Ignore configured I/O base. Use the active setting. 
 519        */
 520 
 521       if (mad_read (MC1_PORT) & 0x20)
 522         hw_config->io_base = 0x240;
 523       else
 524         hw_config->io_base = 0x220;
 525 
 526       switch (hw_config->irq)
 527         {
 528         case 5:
 529           tmp = (tmp & 0x3f) | 0x80;
 530           break;
 531         case 7:
 532           tmp = (tmp & 0x3f);
 533           break;
 534         case 11:
 535           tmp = (tmp & 0x3f) | 0x40;
 536           break;
 537         default:
 538           printk ("mad16/Mozart: Invalid MIDI IRQ\n");
 539           return 0;
 540         }
 541 
 542       mad_write (MC3_PORT, tmp | 0x04);
 543       return mad16_sb_dsp_detect (hw_config);
 544 #else
 545       return 0;
 546 #endif
 547     }
 548 
 549   tmp = 0x83;                   /* MPU-401 enable */
 550 
 551 /*
 552  * Set the MPU base bits
 553  */
 554 
 555   for (i = 0; i < 5; i++)
 556     {
 557       if (i > 3)                /* Out of array bounds */
 558         {
 559           printk ("MAD16 / Mozart: Invalid MIDI port 0x%x\n", hw_config->io_base);
 560           return 0;
 561         }
 562 
 563       if (valid_ports[i] == hw_config->io_base)
 564         {
 565           tmp |= i << 5;
 566           break;
 567         }
 568     }
 569 
 570 /*
 571  * Set the MPU IRQ bits
 572  */
 573 
 574   for (i = 0; i < 5; i++)
 575     {
 576       if (i > 3)                /* Out of array bounds */
 577         {
 578           printk ("MAD16 / Mozart: Invalid MIDI IRQ %d\n", hw_config->irq);
 579           return 0;
 580         }
 581 
 582       if (valid_irqs[i] == hw_config->irq)
 583         {
 584           tmp |= i << 3;
 585           break;
 586         }
 587     }
 588   mad_write (MC6_PORT, tmp);    /* Write MPU401 config */
 589 
 590   return probe_mpu401 (hw_config);
 591 #else
 592   return 0;
 593 #endif
 594 }
 595 
 596 void
 597 unload_mad16 (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 598 {
 599   ad1848_unload (hw_config->io_base + 4,
 600                  hw_config->irq,
 601                  hw_config->dma,
 602                  hw_config->dma2, 0);
 603   release_region (hw_config->io_base, 4);
 604 
 605 }
 606 
 607 void
 608 unload_mad16_mpu (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 609 {
 610 #ifdef CONFIG_MIDI
 611   if (board_type < C929)        /* Early chip. No MPU support. Just SB MIDI */
 612     {
 613       mad16_sb_dsp_unload (hw_config);
 614       return;
 615     }
 616 #endif
 617 
 618 #if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
 619   unload_mpu401 (hw_config);
 620 #endif
 621 }
 622 
 623 /* That's all folks */
 624 #endif

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