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. wss_init
  5. probe_mad16
  6. attach_mad16
  7. attach_mad16_mpu
  8. probe_mad16_mpu
  9. unload_mad16
  10. 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  * sound/mad16.c
  28  *
  29  * Initialization code for OPTi MAD16 compatible audio chips. Including
  30  *
  31  *      OPTi 82C928     MAD16           (replaced by C929)
  32  *      OAK OTI-601D    Mozart
  33  *      OPTi 82C929     MAD16 Pro
  34  *      OPTi 82C930     (Not supported yet)
  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 #define C930    4
  86 
  87 /*
  88  *    Registers
  89  *
  90  *      The MAD16 occupies I/O ports 0xf8d to 0xf93 (fixed locations).
  91  *      All ports are inactive by default. They can be activated by
  92  *      writing 0xE2 or 0xE3 to the password register. The password is valid
  93  *      only until the next I/O read or write.
  94  */
  95 
  96 #define MC0_PORT        0xf8c   /* Dummy port */
  97 #define MC1_PORT        0xf8d   /* SB address, CDROM interface type, joystick */
  98 #define MC2_PORT        0xf8e   /* CDROM address, IRQ, DMA, plus OPL4 bit */
  99 #define MC3_PORT        0xf8f
 100 #define PASSWD_REG      0xf8f
 101 #define MC4_PORT        0xf90
 102 #define MC5_PORT        0xf91
 103 #define MC6_PORT        0xf92
 104 #define MC7_PORT        0xf93
 105 #define MC8_PORT        0xf94
 106 #define MC9_PORT        0xf95
 107 #define MC10_PORT       0xf96
 108 #define MC11_PORT       0xf97
 109 #define MC12_PORT       0xf98
 110 
 111 static int      board_type = C928;
 112 
 113 static int     *mad16_osp;
 114 
 115 #ifndef DDB
 116 #define DDB(x)
 117 #endif
 118 
 119 static unsigned char
 120 mad_read (int port)
     /* [previous][next][first][last][top][bottom][index][help] */
 121 {
 122   unsigned long   flags;
 123   unsigned char   tmp;
 124 
 125   save_flags (flags);
 126   cli ();
 127 
 128   switch (board_type)           /* Output password */
 129     {
 130     case C928:
 131     case MOZART:
 132       outb (0xE2, PASSWD_REG);
 133       break;
 134 
 135     case C929:
 136       outb (0xE3, PASSWD_REG);
 137       break;
 138 
 139     }
 140 
 141   tmp = inb (port);
 142   restore_flags (flags);
 143 
 144   return tmp;
 145 }
 146 
 147 static void
 148 mad_write (int port, int value)
     /* [previous][next][first][last][top][bottom][index][help] */
 149 {
 150   unsigned long   flags;
 151 
 152   save_flags (flags);
 153   cli ();
 154 
 155   switch (board_type)           /* Output password */
 156     {
 157     case C928:
 158     case MOZART:
 159       outb (0xE2, PASSWD_REG);
 160       break;
 161 
 162     case C929:
 163       outb (0xE3, PASSWD_REG);
 164       break;
 165 
 166     }
 167 
 168   outb ((unsigned char) (value & 0xff), port);
 169   restore_flags (flags);
 170 }
 171 
 172 static int
 173 detect_mad16 (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 174 {
 175   unsigned char   tmp, tmp2;
 176   int             i;
 177 
 178 /*
 179  * Check that reading a register doesn't return bus float (0xff)
 180  * when the card is accessed using password. This may fail in case
 181  * the card is in low power mode. Normally at least the power saving mode
 182  * bit should be 0.
 183  */
 184   if ((tmp = mad_read (MC1_PORT)) == 0xff)
 185     {
 186       DDB (printk ("MC1_PORT returned 0xff\n"));
 187       return 0;
 188     }
 189 
 190   for (i = 0xf8d; i <= 0xf98; i++)
 191     DDB (printk ("Port %0x (init value) = %0x\n", i, mad_read (i)));
 192 
 193 /*
 194  * Now check that the gate is closed on first I/O after writing
 195  * the password. (This is how a MAD16 compatible card works).
 196  */
 197 
 198   if ((tmp2 = inb (MC1_PORT)) == tmp)   /* It didn't close */
 199     {
 200       DDB (printk ("MC1_PORT didn't close after read (0x%02x)\n", tmp2));
 201       return 0;
 202     }
 203 
 204   mad_write (MC1_PORT, tmp ^ 0x80);     /* Togge a bit */
 205   if ((tmp2 = mad_read (MC1_PORT)) != (tmp ^ 0x80))     /* Compare the bit */
 206     {
 207       mad_write (MC1_PORT, tmp);        /* Restore */
 208       DDB (printk ("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2));
 209       return 0;
 210     }
 211 
 212   mad_write (MC1_PORT, tmp);    /* Restore */
 213   return 1;                     /* Bingo */
 214 
 215 }
 216 
 217 static int
 218 wss_init (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 219 {
 220   int             ad_flags = 0;
 221 
 222 /*
 223  *    Verify the WSS parameters
 224  */
 225 
 226   if (check_region (hw_config->io_base, 8))
 227     {
 228       printk ("MSS: I/O port conflict\n");
 229       return 0;
 230     }
 231 
 232   if (!ad1848_detect (hw_config->io_base + 4, &ad_flags, mad16_osp))
 233     return 0;
 234   /*
 235      * Check if the IO port returns valid signature. The original MS Sound
 236      * system returns 0x04 while some cards (AudioTriX Pro for example)
 237      * return 0x00.
 238    */
 239 
 240   if ((inb (hw_config->io_base + 3) & 0x3f) != 0x04 &&
 241       (inb (hw_config->io_base + 3) & 0x3f) != 0x00)
 242     {
 243       DDB (printk ("No MSS signature detected on port 0x%x (0x%x)\n",
 244                    hw_config->io_base, inb (hw_config->io_base + 3)));
 245       return 0;
 246     }
 247 
 248   if (hw_config->irq > 11)
 249     {
 250       printk ("MSS: Bad IRQ %d\n", hw_config->irq);
 251       return 0;
 252     }
 253 
 254   if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)
 255     {
 256       printk ("MSS: Bad DMA %d\n", hw_config->dma);
 257       return 0;
 258     }
 259 
 260   /*
 261      * Check that DMA0 is not in use with a 8 bit board.
 262    */
 263 
 264   if (hw_config->dma == 0 && inb (hw_config->io_base + 3) & 0x80)
 265     {
 266       printk ("MSS: Can't use DMA0 with a 8 bit card/slot\n");
 267       return 0;
 268     }
 269 
 270   if (hw_config->irq > 7 && hw_config->irq != 9 && inb (hw_config->io_base + 3) & 0x80)
 271     {
 272       printk ("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
 273     }
 274 
 275   return 1;
 276 }
 277 
 278 int
 279 probe_mad16 (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 280 {
 281   int             i;
 282   static int      valid_ports[] =
 283   {0x530, 0xe80, 0xf40, 0x604};
 284   unsigned char   tmp;
 285   unsigned char   cs4231_mode = 0;
 286 
 287   int             ad_flags = 0;
 288 
 289   if (already_initialized)
 290     return 0;
 291 
 292   mad16_osp = hw_config->osp;
 293 /*
 294  *    Check that all ports return 0xff (bus float) when no password
 295  *      is written to the password register.
 296  */
 297 
 298   DDB (printk ("--- Detecting MAD16 / Mozart ---\n"));
 299 
 300 
 301 /*
 302  *    Then try to detect with the old password
 303  */
 304   board_type = C928;
 305 
 306   DDB (printk ("Detect using password = 0xE2\n"));
 307 
 308   if (!detect_mad16 ())         /* No luck. Try different model */
 309     {
 310       board_type = C929;
 311 
 312       DDB (printk ("Detect using password = 0xE3\n"));
 313 
 314       if (!detect_mad16 ())
 315         {
 316           return 0;
 317         }
 318       else
 319         {
 320           DDB (printk ("mad16.c: 82C929 detected\n"));
 321         }
 322     }
 323   else
 324     {
 325       unsigned char   model;
 326 
 327       if (((model = mad_read (MC3_PORT)) & 0x03) == 0x03)
 328         {
 329           DDB (printk ("mad16.c: Mozart detected\n"));
 330           board_type = MOZART;
 331         }
 332       else
 333         {
 334           DDB (printk ("mad16.c: 82C928 detected???\n"));
 335           board_type = C928;
 336         }
 337     }
 338 
 339   for (i = 0xf8d; i <= 0xf93; i++)
 340     DDB (printk ("port %03x = %02x\n", i, mad_read (i)));
 341 
 342 /*
 343  * Set the WSS address
 344  */
 345 
 346   tmp = 0x80;                   /* Enable WSS, Disable SB */
 347 
 348   for (i = 0; i < 5; i++)
 349     {
 350       if (i > 3)                /* Not a valid port */
 351         {
 352           printk ("MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base);
 353           return 0;
 354         }
 355 
 356       if (valid_ports[i] == hw_config->io_base)
 357         {
 358           tmp |= i << 4;        /* WSS port select bits */
 359           break;
 360         }
 361     }
 362 
 363 /*
 364  * Set optional CD-ROM and joystick settings.
 365  */
 366 
 367 #ifdef MAD16_CONF
 368   tmp |= ((MAD16_CONF) & 0x0f); /* CD-ROM and joystick bits */
 369 #endif
 370   mad_write (MC1_PORT, tmp);
 371 
 372 #if defined(MAD16_CONF) && defined(MAD16_CDSEL)
 373   tmp = MAD16_CDSEL;
 374 #else
 375   tmp = 0x03;
 376 #endif
 377 
 378 #ifdef MAD16_OPL4
 379   tmp |= 0x20;                  /* Enable OPL4 access */
 380 #endif
 381 
 382   mad_write (MC2_PORT, tmp);
 383   mad_write (MC3_PORT, 0xf0);   /* Disable SB */
 384 
 385   if (!ad1848_detect (hw_config->io_base + 4, &ad_flags, mad16_osp))
 386     return 0;
 387 
 388   if (ad_flags & (AD_F_CS4231 | AD_F_CS4248))
 389     cs4231_mode = 0x02;         /* CS4248/CS4231 sync delay switch */
 390 
 391   if (board_type == C929)
 392     {
 393       mad_write (MC4_PORT, 0xa2);
 394       mad_write (MC5_PORT, 0xA5 | cs4231_mode);
 395       mad_write (MC6_PORT, 0x03);       /* Disable MPU401 */
 396     }
 397   else
 398     {
 399       mad_write (MC4_PORT, 0x02);
 400       mad_write (MC5_PORT, 0x30 | cs4231_mode);
 401     }
 402 
 403   for (i = 0xf8d; i <= 0xf93; i++)
 404     DDB (printk ("port %03x after init = %02x\n", i, mad_read (i)));
 405 
 406   wss_init (hw_config);
 407 
 408   return 1;
 409 }
 410 
 411 long
 412 attach_mad16 (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 413 {
 414 
 415   static char     interrupt_bits[12] =
 416   {
 417     -1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20
 418   };
 419   char            bits;
 420 
 421   static char     dma_bits[4] =
 422   {
 423     1, 2, 0, 3
 424   };
 425 
 426   int             config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3;
 427   int             ad_flags = 0, dma = hw_config->dma, dma2 = hw_config->dma2;
 428   unsigned char   dma2_bit = 0;
 429 
 430   already_initialized = 1;
 431 
 432   if (!ad1848_detect (hw_config->io_base + 4, &ad_flags, mad16_osp))
 433     return mem_start;
 434 
 435   /*
 436      * Set the IRQ and DMA addresses.
 437    */
 438 
 439   bits = interrupt_bits[hw_config->irq];
 440   if (bits == -1)
 441     return mem_start;
 442 
 443   outb (bits | 0x40, config_port);
 444   if ((inb (version_port) & 0x40) == 0)
 445     printk ("[IRQ Conflict?]");
 446 
 447 /*
 448  * Handle the capture DMA channel
 449  */
 450 
 451   if (ad_flags & AD_F_CS4231 && dma2 != -1 && dma2 != dma)
 452     {
 453       if ((dma == 0 && dma2 == 1) ||
 454           (dma == 1 && dma2 == 0) ||
 455           (dma == 3 && dma2 == 0))
 456         {
 457           dma2_bit = 0x04;      /* Enable capture DMA */
 458 
 459         }
 460       else
 461         {
 462           printk ("MAD16: Invalid capture DMA\n");
 463           dma2 = dma;
 464         }
 465     }
 466   else
 467     dma2 = dma;
 468 
 469   outb (bits | dma_bits[dma] | dma2_bit, config_port);  /* Write IRQ+DMA setup */
 470 
 471   ad1848_init ("MAD16 WSS", hw_config->io_base + 4,
 472                hw_config->irq,
 473                dma,
 474                dma2, 0,
 475                hw_config->osp);
 476   request_region (hw_config->io_base, 4, "MAD16 WSS config");
 477 
 478   return mem_start;
 479 }
 480 
 481 long
 482 attach_mad16_mpu (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 483 {
 484   if (board_type < C929)        /* Early chip. No MPU support. Just SB MIDI */
 485     {
 486 #ifdef CONFIG_MIDI
 487 
 488       if (mad_read (MC1_PORT) & 0x20)
 489         hw_config->io_base = 0x240;
 490       else
 491         hw_config->io_base = 0x220;
 492 
 493       return mad16_sb_dsp_init (mem_start, hw_config);
 494 #else
 495       return 0;
 496 #endif
 497     }
 498 
 499 #if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
 500   if (!already_initialized)
 501     return mem_start;
 502 
 503   return attach_mpu401 (mem_start, hw_config);
 504 #else
 505   return mem_start;
 506 #endif
 507 }
 508 
 509 int
 510 probe_mad16_mpu (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 511 {
 512 #if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
 513   static int      mpu_attached = 0;
 514   static int      valid_ports[] =
 515   {0x330, 0x320, 0x310, 0x300};
 516   static short    valid_irqs[] =
 517   {9, 10, 5, 7};
 518   unsigned char   tmp;
 519 
 520   int             i;            /* A variable with secret power */
 521 
 522   if (!already_initialized)     /* The MSS port must be initialized first */
 523     return 0;
 524 
 525   if (mpu_attached)             /* Don't let them call this twice */
 526     return 0;
 527   mpu_attached = 1;
 528 
 529   if (board_type < C929)        /* Early chip. No MPU support. Just SB MIDI */
 530     {
 531 
 532 #ifdef CONFIG_MIDI
 533       unsigned char   tmp;
 534 
 535       tmp = mad_read (MC3_PORT);
 536 
 537       /* 
 538        * MAD16 SB base is defined by the WSS base. It cannot be changed 
 539        * alone.
 540        * Ignore configured I/O base. Use the active setting. 
 541        */
 542 
 543       if (mad_read (MC1_PORT) & 0x20)
 544         hw_config->io_base = 0x240;
 545       else
 546         hw_config->io_base = 0x220;
 547 
 548       switch (hw_config->irq)
 549         {
 550         case 5:
 551           tmp = (tmp & 0x3f) | 0x80;
 552           break;
 553         case 7:
 554           tmp = (tmp & 0x3f);
 555           break;
 556         case 11:
 557           tmp = (tmp & 0x3f) | 0x40;
 558           break;
 559         default:
 560           printk ("mad16/Mozart: Invalid MIDI IRQ\n");
 561           return 0;
 562         }
 563 
 564       mad_write (MC3_PORT, tmp | 0x04);
 565       return mad16_sb_dsp_detect (hw_config);
 566 #else
 567       return 0;
 568 #endif
 569     }
 570 
 571   tmp = 0x83;                   /* MPU-401 enable */
 572 
 573 /*
 574  * Set the MPU base bits
 575  */
 576 
 577   for (i = 0; i < 5; i++)
 578     {
 579       if (i > 3)                /* Out of array bounds */
 580         {
 581           printk ("MAD16 / Mozart: Invalid MIDI port 0x%x\n", hw_config->io_base);
 582           return 0;
 583         }
 584 
 585       if (valid_ports[i] == hw_config->io_base)
 586         {
 587           tmp |= i << 5;
 588           break;
 589         }
 590     }
 591 
 592 /*
 593  * Set the MPU IRQ bits
 594  */
 595 
 596   for (i = 0; i < 5; i++)
 597     {
 598       if (i > 3)                /* Out of array bounds */
 599         {
 600           printk ("MAD16 / Mozart: Invalid MIDI IRQ %d\n", hw_config->irq);
 601           return 0;
 602         }
 603 
 604       if (valid_irqs[i] == hw_config->irq)
 605         {
 606           tmp |= i << 3;
 607           break;
 608         }
 609     }
 610   mad_write (MC6_PORT, tmp);    /* Write MPU401 config */
 611 
 612   return probe_mpu401 (hw_config);
 613 #else
 614   return 0;
 615 #endif
 616 }
 617 
 618 void
 619 unload_mad16 (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 620 {
 621   ad1848_unload (hw_config->io_base + 4,
 622                  hw_config->irq,
 623                  hw_config->dma,
 624                  hw_config->dma2, 0);
 625   release_region (hw_config->io_base, 4);
 626 
 627 }
 628 
 629 void
 630 unload_mad16_mpu (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 631 {
 632 #ifdef CONFIG_MIDI
 633   if (board_type < C929)        /* Early chip. No MPU support. Just SB MIDI */
 634     {
 635       mad16_sb_dsp_unload (hw_config);
 636       return;
 637     }
 638 #endif
 639 
 640 #if (defined(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_MIDI)
 641   unload_mpu401 (hw_config);
 642 #endif
 643 }
 644 
 645 /* That's all folks */
 646 #endif

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