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         }
 432       else
 433         {
 434           printk ("MAD16: Invalid capture DMA\n");
 435           dma2 = dma;
 436         }
 437     }
 438   else
 439     dma2 = dma;
 440 
 441   outb (bits | dma_bits[dma] | dma2_bit, config_port);  /* Write IRQ+DMA setup */
 442 
 443   ad1848_init ("MAD16 WSS", hw_config->io_base + 4,
 444                hw_config->irq,
 445                dma,
 446                dma2, 0,
 447                hw_config->osp);
 448   request_region (hw_config->io_base, 4, "MAD16 WSS config");
 449 
 450   return mem_start;
 451 }
 452 
 453 long
 454 attach_mad16_mpu (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 455 {
 456   if (board_type < C929)        /* Early chip. No MPU support. Just SB MIDI */
 457     {
 458 #ifdef CONFIG_MIDI
 459 
 460       if (mad_read (MC1_PORT) & 0x20)
 461         hw_config->io_base = 0x240;
 462       else
 463         hw_config->io_base = 0x220;
 464 
 465       return mad16_sb_dsp_init (mem_start, hw_config);
 466 #else
 467       return 0;
 468 #endif
 469     }
 470 
 471 #if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
 472   if (!already_initialized)
 473     return mem_start;
 474 
 475   return attach_mpu401 (mem_start, hw_config);
 476 #else
 477   return mem_start;
 478 #endif
 479 }
 480 
 481 int
 482 probe_mad16_mpu (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 483 {
 484 #if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
 485   static int      mpu_attached = 0;
 486   static int      valid_ports[] =
 487   {0x330, 0x320, 0x310, 0x300};
 488   static short    valid_irqs[] =
 489   {9, 10, 5, 7};
 490   unsigned char   tmp;
 491 
 492   int             i;            /* A variable with secret power */
 493 
 494   if (!already_initialized)     /* The MSS port must be initialized first */
 495     return 0;
 496 
 497   if (mpu_attached)             /* Don't let them call this twice */
 498     return 0;
 499   mpu_attached = 1;
 500 
 501   if (board_type < C929)        /* Early chip. No MPU support. Just SB MIDI */
 502     {
 503 
 504 #ifdef CONFIG_MIDI
 505       unsigned char   tmp;
 506 
 507       tmp = mad_read (MC3_PORT);
 508 
 509       /* 
 510        * MAD16 SB base is defined by the WSS base. It cannot be changed 
 511        * alone.
 512        * Ignore configured I/O base. Use the active setting. 
 513        */
 514 
 515       if (mad_read (MC1_PORT) & 0x20)
 516         hw_config->io_base = 0x240;
 517       else
 518         hw_config->io_base = 0x220;
 519 
 520       switch (hw_config->irq)
 521         {
 522         case 5:
 523           tmp = (tmp & 0x3f) | 0x80;
 524           break;
 525         case 7:
 526           tmp = (tmp & 0x3f);
 527           break;
 528         case 11:
 529           tmp = (tmp & 0x3f) | 0x40;
 530           break;
 531         default:
 532           printk ("mad16/Mozart: Invalid MIDI IRQ\n");
 533           return 0;
 534         }
 535 
 536       mad_write (MC3_PORT, tmp | 0x04);
 537       return mad16_sb_dsp_detect (hw_config);
 538 #else
 539       return 0;
 540 #endif
 541     }
 542 
 543   tmp = 0x83;                   /* MPU-401 enable */
 544 
 545 /*
 546  * Set the MPU base bits
 547  */
 548 
 549   for (i = 0; i < 5; i++)
 550     {
 551       if (i > 3)                /* Out of array bounds */
 552         {
 553           printk ("MAD16 / Mozart: Invalid MIDI port 0x%x\n", hw_config->io_base);
 554           return 0;
 555         }
 556 
 557       if (valid_ports[i] == hw_config->io_base)
 558         {
 559           tmp |= i << 5;
 560           break;
 561         }
 562     }
 563 
 564 /*
 565  * Set the MPU IRQ bits
 566  */
 567 
 568   for (i = 0; i < 5; i++)
 569     {
 570       if (i > 3)                /* Out of array bounds */
 571         {
 572           printk ("MAD16 / Mozart: Invalid MIDI IRQ %d\n", hw_config->irq);
 573           return 0;
 574         }
 575 
 576       if (valid_irqs[i] == hw_config->irq)
 577         {
 578           tmp |= i << 3;
 579           break;
 580         }
 581     }
 582   mad_write (MC6_PORT, tmp);    /* Write MPU401 config */
 583 
 584   return probe_mpu401 (hw_config);
 585 #else
 586   return 0;
 587 #endif
 588 }
 589 
 590 void
 591 unload_mad16 (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 592 {
 593   ad1848_unload (hw_config->io_base + 4,
 594                  hw_config->irq,
 595                  hw_config->dma,
 596                  hw_config->dma2, 0);
 597   release_region (hw_config->io_base, 4);
 598 
 599 }
 600 
 601 void
 602 unload_mad16_mpu (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 603 {
 604 #ifdef CONFIG_MIDI
 605   if (board_type < C929)        /* Early chip. No MPU support. Just SB MIDI */
 606     {
 607       mad16_sb_dsp_unload (hw_config);
 608       return;
 609     }
 610 #endif
 611 
 612 #if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
 613   unload_mpu401 (hw_config);
 614 #endif
 615 }
 616 
 617 /* That's all folks */
 618 #endif

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