root/drivers/sound/aedsp16.c

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

DEFINITIONS

This source file includes following definitions.
  1. tenmillisec
  2. WaitForDataAvail
  3. ReadData
  4. CheckDSPOkay
  5. ResetBoard
  6. WriteDSPCommand
  7. InitMSS
  8. SetUpBoard
  9. GetCardVersion
  10. GetCardName
  11. InitializeHardParams
  12. InitAEDSP16
  13. InitAEDSP16_SBPRO
  14. InitAEDSP16_MSS
  15. InitAEDSP16_MPU401
  16. ResetAEDSP16

   1 /*
   2    sound/aedsp16.c
   3 
   4    Audio Excel DSP 16 software configuration routines
   5 
   6    Copyright (C) 1995  Riccardo Facchetti (riccardo@cdc8g5.cdc.polimi.it)
   7 
   8    Redistribution and use in source and binary forms, with or without
   9    modification, are permitted provided that the following conditions are
  10    met: 1. Redistributions of source code must retain the above copyright
  11    notice, this list of conditions and the following disclaimer. 2.
  12    Redistributions in binary form must reproduce the above copyright notice,
  13    this list of conditions and the following disclaimer in the documentation
  14    and/or other materials provided with the distribution.
  15 
  16    THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
  17    EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19    DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  20    ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  22    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  23    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25    OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26    SUCH DAMAGE.
  27  */
  28 /*
  29  * Include the main voxware header file. It include all the os/voxware/etc
  30  * headers needed by this source.
  31  */
  32 #include <linux/config.h>
  33 #include "sound_config.h"
  34 
  35 #ifndef AEDSP16_BASE
  36 #undef CONFIG_AEDSP16
  37 #endif
  38 
  39 #if defined(CONFIG_AEDSP16)
  40 /*
  41 
  42    READ THIS
  43 
  44    This module is intended for Audio Excel DSP 16 Sound Card.
  45 
  46    Audio Excel DSP 16 is an SB pro II, Microsoft Sound System
  47    and MPU-401 compatible card.
  48    It is software-only configurable (no jumpers to hard-set irq/dma/mpu-irq),
  49    so before this module, the only way to configure the DSP under linux was
  50    boot the MS-BAU loading the sound.sys device driver (this driver soft-
  51    configure the sound board hardware by massaging someone of its registers),
  52    and then ctrl-alt-del to boot linux with the DSP configured by the DOG
  53    driver.
  54 
  55    This module works configuring your Audio Excel DSP 16's
  56    irq, dma and mpu-401-irq. The voxware probe routines rely on the
  57    fact that if the hardware is there, they can detect it. The problem
  58    with AEDSP16 is that no hardware can be found by the probe routines
  59    if the sound card is not well configured. Sometimes the kernel probe
  60    routines can find an SBPRO even when the card is not configured (this
  61    is the standard setup of the card), but the SBPRO emulation don't work
  62    well if the card is not properly initialized. For this reason
  63 
  64    InitAEDSP16_...()
  65 
  66    routines are called before the voxware probe routines try to detect the
  67    hardware.
  68 
  69    NOTE (READ THE NOTE TOO, IT CONTAIN USEFUL INFORMATIONS)
  70 
  71    The Audio Excel DSP 16 Sound Card emulates both SBPRO and MSS;
  72    the voxware sound driver can be configured for SBPRO and MSS cards
  73    at the same time, but the aedsp16 can't be two cards!!
  74    When we configure it, we have to choose the SBPRO or the MSS emulation
  75    for AEDSP16. We also can install a *REAL* card of the other type
  76    (see [1], not tested but I can't see any reason for it to fail).
  77 
  78    NOTE: If someone can test the combination AEDSP16+MSS or AEDSP16+SBPRO
  79    please let me know if it works.
  80 
  81    The MPU-401 support can be compiled in together with one of the other
  82    two operating modes.
  83 
  84    The board configuration calls, are in the probe_...() routines because
  85    we have to configure the board before probing it for a particular
  86    hardware. After card configuration, we can probe the hardware.
  87 
  88    NOTE: This is something like plug-and-play: we have only to plug
  89    the AEDSP16 board in the socket, and then configure and compile
  90    a kernel that uses the AEDSP16 software configuration capability.
  91    No jumper setting is needed!
  92 
  93    For example, if you want AEDSP16 to be an SBPro, on irq 10, dma 3
  94    you have just to make config the voxware package, configuring
  95    the SBPro sound card with that parameters, then when configure
  96    asks if you have an AEDSP16, answer yes. That's it.
  97    Compile the kernel and run it.
  98 
  99    NOTE: This means that you can choose irq and dma, but not the
 100    I/O addresses. To change I/O addresses you have to set them
 101    with jumpers.
 102 
 103    NOTE: InitAEDSP16_...() routines get as parameter the hw_config,
 104    the hardware configuration of the - to be configured - board.
 105    The InitAEDSP16() routine, configure the board following our
 106    wishes, that are in the hw_config structure.
 107 
 108    You can change the irq/dma/mirq settings WITHOUT THE NEED to open
 109    your computer and massage the jumpers (there are no irq/dma/mirq
 110    jumpers to be configured anyway, only I/O port ones have to be
 111    configured with jumpers)
 112 
 113    For some ununderstandable reason, the card default of irq 7, dma 1,
 114    don't work for me. Seems to be an IRQ or DMA conflict. Under heavy
 115    HDD work, the kernel start to erupt out a lot of messages like:
 116 
 117    'Sound: DMA timed out - IRQ/DRQ config error?'
 118 
 119    For what I can say, I have NOT any conflict at irq 7 (under linux I'm
 120    using the lp polling driver), and dma line 1 is unused as stated by
 121    /proc/dma. I can suppose this is a bug of AEDSP16. I know my hardware so
 122    I'm pretty sure I have not any conflict, but may be I'm wrong. Who knows!
 123    Anyway a setting of irq 10, dma 3 works really fine.
 124 
 125    NOTE: if someone can use AEDSP16 with irq 7, dma 1, please let me know
 126    the emulation mode, all the installed hardware and the hardware
 127    configuration (irq and dma settings of all the hardware).
 128 
 129    This init module should work with SBPRO+MSS, when one of the two is
 130    the AEDSP16 emulation and the other the real card. (see [1])
 131    For example:
 132 
 133    AEDSP16 (0x220) in SBPRO emu (0x220) + real MSS + other
 134    AEDSP16 (0x220) in MSS emu + real SBPRO (0x240) + other
 135 
 136    MPU401 should work. (see [1])
 137 
 138    [1] Not tested by me for lack of hardware.
 139 
 140    TODO, WISHES AND TECH
 141 
 142    May be there's lot of redundant delays, but for now I want to leave it
 143    this way.
 144 
 145    Should be interesting eventually write down a new ioctl for the
 146    aedsp16, to let the suser() change the irq/dma/mirq on the fly.
 147    The thing is not trivial.
 148    In the real world, there's no need to have such an ioctl because
 149    when we configure the kernel for compile, we can choose the config
 150    parameters. If we change our mind, we can easily re-config the kernel
 151    and re-compile.
 152    Why let the suser() change the config parameters on the fly ?
 153    If anyone have a reasonable answer to this question, I will write down
 154    the code to do it.
 155 
 156    More integration with voxware, using voxware low level routines to
 157    read-write dsp is not possible because you may want to have MSS
 158    support and in that case we can not rely on the functions included
 159    in sb_dsp.c to control 0x2yy I/O ports. I will continue to use my
 160    own I/O functions.
 161 
 162    - About I/O ports allocation -
 163 
 164    The request_region should be done at device probe in every sound card
 165    module. This module is not the best site for requesting regions.
 166    When the request_region code will be added to the main modules such as
 167    sb, adlib, gus, ad1848, etc, the requesting code in this module should
 168    go away.
 169 
 170    I think the request regions should be done this way:
 171 
 172    if (check_region(...))
 173    return ERR; // I/O region already reserved
 174    device_probe(...);
 175    device_attach(...);
 176    request_region(...); // reserve only when we are sure all is okay
 177 
 178    Request the 2x0h region in any case if we are using this card.
 179 
 180    NOTE: the "(sbpro)" string with which we are requesting the aedsp16 region
 181    (see code) does not mean necessarily that we are emulating sbpro.
 182    It mean that the region is the sbpro I/O ports region. We use this
 183    region to access the control registers of the card, and if emulating
 184    sbpro, I/O sbpro registers too. If we are emulating MSS, the sbpro
 185    registers are not used, in no way, to emulate an sbpro: they are
 186    used only for configuration purposes.
 187 
 188    Someone pointed out that should be possible use both the SBPRO and MSS
 189    modes because the sound card have all the two chipsets, supposing that
 190    the card is really two cards. I have tried something to have the two
 191    modes work together, but, for some reason unknown to me, without success.
 192 
 193    I think all the soft-config only cards have an init sequence similar to
 194    this. If you have a card that is not an aedsp16, you can try to start
 195    with this module changing it (mainly in the CMD? I think) to fit your
 196    needs.
 197 
 198    Started Fri Mar 17 16:13:18 MET 1995
 199 
 200    v0.1 (ALPHA, was an user-level program called AudioExcelDSP16.c)
 201    - Initial code.
 202    v0.2 (ALPHA)
 203    - Cleanups.
 204    - Integrated with Linux voxware v 2.90-2 kernel sound driver.
 205    - SoundBlaster Pro mode configuration.
 206    - Microsoft Sound System mode configuration.
 207    - MPU-401 mode configuration.
 208    v0.3 (ALPHA)
 209    - Cleanups.
 210    - Rearranged the code to let InitAEDSP16 be more general.
 211    - Erased the REALLY_SLOW_IO. We don't need it. Erased the linux/io.h
 212    inclusion too. We rely on os.h
 213    - Used the  to get a variable
 214    len string (we are not sure about the len of Copyright string).
 215    This works with any SB and compatible.
 216    - Added the code to request_region at device init (should go in
 217    the main body of voxware).
 218    v0.4 (BETA)
 219    - Better configure.c patch for aedsp16 configuration (better
 220    logic of inclusion of AEDSP16 support)
 221    - Modified the conditional compilation to better support more than
 222    one sound card of the emulated type (read the NOTES above)
 223    - Moved the sb init routine from the attach to the very first
 224    probe in sb_card.c
 225    - Rearrangements and cleanups
 226    - Wiped out some unnecessary code and variables: this is kernel
 227    code so it is better save some TEXT and DATA
 228    - Fixed the request_region code. We must allocate the aedsp16 (sbpro)
 229    I/O ports in any case because they are used to access the DSP
 230    configuration registers and we can not allow anyone to get them.
 231    v0.5
 232    - cleanups on comments
 233    - prep for diffs against v3.0-proto-950402
 234    v0.6
 235    - removed the request_region()s when compiling the MODULE sound.o
 236    because we are not allowed (by the actual voxware structure) to
 237    release_region()
 238 
 239  */
 240 
 241 
 242 #define VERSION "0.6"           /* Version of Audio Excel DSP 16 driver */
 243 
 244 #undef AEDSP16_DEBUG            /* Define this to enable debug code     */
 245 /* Actually no debug code is activated  */
 246 
 247 /*
 248  * Hardware related defaults
 249  */
 250 #define IRQ  7                  /* 5 7(default) 9 10 11                 */
 251 #define MIRQ 0                  /* 5 7 9 10 0(default), 0 means disable */
 252 #define DMA  1                  /* 0 1(default) 3                       */
 253 
 254 /*
 255  * Commands of AEDSP16's DSP (SBPRO+special).
 256  * For now they are CMDn, in the future they may change.
 257  */
 258 #define CMD1 0xe3               /* Get DSP Copyright                    */
 259 #define CMD2 0xe1               /* Get DSP Version                      */
 260 #define CMD3 0x88               /*                                      */
 261 #define CMD4 0x5c               /*                                      */
 262 #define CMD5 0x50               /* Set M&I&DRQ mask (the real config)   */
 263 #define CMD6 0x8c               /* Enable Microsoft Sound System mode   */
 264 
 265 /*
 266  * Offsets of AEDSP16 DSP I/O ports. The offset is added to portbase
 267  * to have the actual I/O port.
 268  * Register permissions are:
 269  * (wo) == Write Only
 270  * (ro) == Read  Only
 271  * (w-) == Write
 272  * (r-) == Read
 273  */
 274 #define DSP_RESET    0x06       /* offset of DSP RESET             (wo) */
 275 #define DSP_READ     0x0a       /* offset of DSP READ              (ro) */
 276 #define DSP_WRITE    0x0c       /* offset of DSP WRITE             (w-) */
 277 #define DSP_COMMAND  0x0c       /* offset of DSP COMMAND           (w-) */
 278 #define DSP_STATUS   0x0c       /* offset of DSP STATUS            (r-) */
 279 #define DSP_DATAVAIL 0x0e       /* offset of DSP DATA AVAILABLE    (ro) */
 280 
 281 
 282 #define RETRY           10      /* Various retry values on I/O opera-   */
 283 #define STATUSRETRY   1000      /* tions. Sometimes we have to          */
 284 #define HARDRETRY   500000      /* wait for previous cmd to complete    */
 285 
 286 /*
 287  * Size of character arrays that store name and version of sound card
 288  */
 289 #define CARDNAMELEN 15          /* Size of the card's name in chars     */
 290 #define CARDVERLEN  2           /* Size of the card's version in chars  */
 291 
 292 /*
 293  * Bit mapped flags for calling InitAEDSP16(), and saving the current
 294  * emulation mode.
 295  */
 296 #define INIT_NONE   (0   )
 297 #define INIT_SBPRO  (1<<0)
 298 #define INIT_MSS    (1<<1)
 299 #define INIT_MPU401 (1<<2)
 300 #define RESET_DSP16 (1<<3)
 301 
 302 /* Base HW Port for Audio Card          */
 303 static int      portbase = AEDSP16_BASE;
 304 static int      irq = IRQ;      /* irq for DSP I/O                      */
 305 static int      mirq = MIRQ;    /* irq for MPU-401 I/O                  */
 306 static int      dma = DMA;      /* dma for DSP I/O                      */
 307 
 308 /* Init status of the card              */
 309 static int      ae_init = INIT_NONE;    /* (bitmapped variable)                 */
 310 static int      oredparams = 0; /* Will contain or'ed values of params  */
 311 static int      gc = 0;         /* generic counter (utility counter)    */
 312 struct orVals
 313   {                             /* Contain the values to be or'ed       */
 314     int             val;        /* irq|mirq|dma                         */
 315     int             or;         /* oredparams |= TheStruct.or           */
 316   };
 317 
 318 /*
 319  * Magic values that the DSP will eat when configuring irq/mirq/dma
 320  */
 321 /* DSP IRQ conversion array             */
 322 static struct orVals orIRQ[] =
 323 {
 324   {0x05, 0x28},
 325   {0x07, 0x08},
 326   {0x09, 0x10},
 327   {0x0a, 0x18},
 328   {0x0b, 0x20},
 329   {0x00, 0x00}
 330 };
 331 
 332 /* MPU-401 IRQ conversion array         */
 333 static struct orVals orMIRQ[] =
 334 {
 335   {0x05, 0x04},
 336   {0x07, 0x44},
 337   {0x09, 0x84},
 338   {0x0a, 0xc4},
 339   {0x00, 0x00}
 340 };
 341 
 342 /* DMA Channels conversion array        */
 343 static struct orVals orDMA[] =
 344 {
 345   {0x00, 0x01},
 346   {0x01, 0x02},
 347   {0x03, 0x03},
 348   {0x00, 0x00}
 349 };
 350 
 351 /*
 352  * Buffers to store audio card informations
 353  */
 354 static char     AudioExcelName[CARDNAMELEN + 1];
 355 static char     AudioExcelVersion[CARDVERLEN + 1];
 356 
 357 static void
 358 tenmillisec (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 359 {
 360 
 361   for (gc = 0; gc < 1000; gc++)
 362     tenmicrosec ();
 363 }
 364 
 365 static int
 366 WaitForDataAvail (int port)
     /* [previous][next][first][last][top][bottom][index][help] */
 367 {
 368   int             loop = STATUSRETRY;
 369   unsigned char   ret = 0;
 370 
 371   do
 372     {
 373       ret = inb (port + DSP_DATAVAIL);
 374       /*
 375          * Wait for data available (bit 7 of ret == 1)
 376        */
 377     }
 378   while (!(ret & 0x80) && loop--);
 379 
 380   if (ret & 0x80)
 381     return 0;
 382 
 383   return -1;
 384 }
 385 
 386 static int
 387 ReadData (int port)
     /* [previous][next][first][last][top][bottom][index][help] */
 388 {
 389   if (WaitForDataAvail (port))
 390     return -1;
 391   return inb (port + DSP_READ);
 392 }
 393 
 394 static int
 395 CheckDSPOkay (int port)
     /* [previous][next][first][last][top][bottom][index][help] */
 396 {
 397   return ((ReadData (port) == 0xaa) ? 0 : -1);
 398 }
 399 
 400 static int
 401 ResetBoard (int port)
     /* [previous][next][first][last][top][bottom][index][help] */
 402 {
 403   /*
 404      * Reset DSP
 405    */
 406   outb (1, (port + DSP_RESET));
 407   tenmicrosec ();
 408   outb (0, (port + DSP_RESET));
 409   tenmicrosec ();
 410   tenmicrosec ();
 411   return CheckDSPOkay (port);
 412 }
 413 
 414 static int
 415 WriteDSPCommand (int port, int cmd)
     /* [previous][next][first][last][top][bottom][index][help] */
 416 {
 417   unsigned char   ret;
 418   int             loop = HARDRETRY;
 419 
 420   do
 421     {
 422       ret = inb (port + DSP_STATUS);
 423       /*
 424          * DSP ready to receive data if bit 7 of ret == 0
 425        */
 426       if (!(ret & 0x80))
 427         {
 428           outb (cmd, port + DSP_COMMAND);
 429           return 0;
 430         }
 431     }
 432   while (loop--);
 433 
 434   printk ("[aedsp16] DSP Command (0x%x) timeout.\n", cmd);
 435   return -1;
 436 }
 437 
 438 int
 439 InitMSS (int port)
     /* [previous][next][first][last][top][bottom][index][help] */
 440 {
 441 
 442   tenmillisec ();
 443 
 444   if (WriteDSPCommand (port, CMD6))
 445     {
 446       printk ("[aedsp16] CMD 0x%x: failed!\n", CMD6);
 447       return -1;
 448     }
 449 
 450   tenmillisec ();
 451 
 452   return 0;
 453 }
 454 
 455 static int
 456 SetUpBoard (int port)
     /* [previous][next][first][last][top][bottom][index][help] */
 457 {
 458   int             loop = RETRY;
 459 
 460   do
 461     {
 462       if (WriteDSPCommand (portbase, CMD3))
 463         {
 464           printk ("[aedsp16] CMD 0x%x: failed!\n", CMD3);
 465           return -1;
 466         }
 467 
 468       tenmillisec ();
 469 
 470     }
 471   while (WaitForDataAvail (port) && loop--);
 472 
 473 #if defined(THIS_SHOULD_GO_AWAY)
 474   if (CheckDSPOkay (port))
 475     {
 476       printk ("[aedsp16]     CheckDSPOkay: failed\n");
 477       return -1;
 478     }
 479 #else
 480   if (ReadData (port) == -1)
 481     {
 482       printk ("[aedsp16] ReadData after CMD 0x%x: failed\n", CMD3);
 483       return -1;
 484     }
 485 #endif
 486 
 487   if (WriteDSPCommand (portbase, CMD4))
 488     {
 489       printk ("[aedsp16] CMD 0x%x: failed!\n", CMD4);
 490       return -1;
 491     }
 492 
 493   if (WriteDSPCommand (portbase, CMD5))
 494     {
 495       printk ("[aedsp16] CMD 0x%x: failed!\n", CMD5);
 496       return -1;
 497     }
 498 
 499   if (WriteDSPCommand (portbase, oredparams))
 500     {
 501       printk ("[aedsp16] Initialization of (M)IRQ and DMA: failed!\n");
 502       return -1;
 503     }
 504   return 0;
 505 }
 506 
 507 static int
 508 GetCardVersion (int port)
     /* [previous][next][first][last][top][bottom][index][help] */
 509 {
 510   int             len = 0;
 511   int             ret;
 512   int             ver[3];
 513 
 514   do
 515     {
 516       if ((ret = ReadData (port)) == -1)
 517         return -1;
 518       /*
 519          * We already know how many int are stored (2), so we know when the
 520          * string is finished.
 521        */
 522       ver[len++] = ret;
 523     }
 524   while (len < CARDVERLEN);
 525   sprintf (AudioExcelVersion, "%d.%d", ver[0], ver[1]);
 526   return 0;
 527 }
 528 
 529 static int
 530 GetCardName (int port)
     /* [previous][next][first][last][top][bottom][index][help] */
 531 {
 532   int             len = 0;
 533   int             ret;
 534 
 535   do
 536     {
 537       if ((ret = ReadData (port)) == -1)
 538         /*
 539            * If no more data available, return to the caller, no error if len>0.
 540            * We have no other way to know when the string is finished.
 541          */
 542         return (len ? 0 : -1);
 543 
 544       AudioExcelName[len++] = ret;
 545 
 546     }
 547   while (len < CARDNAMELEN);
 548   return 0;
 549 }
 550 
 551 static void
 552 InitializeHardParams (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 553 {
 554 
 555   memset (AudioExcelName, 0, CARDNAMELEN + 1);
 556   memset (AudioExcelVersion, 0, CARDVERLEN + 1);
 557 
 558   for (gc = 0; orIRQ[gc].or; gc++)
 559     if (orIRQ[gc].val == irq)
 560       oredparams |= orIRQ[gc].or;
 561 
 562   for (gc = 0; orMIRQ[gc].or; gc++)
 563     if (orMIRQ[gc].or == mirq)
 564       oredparams |= orMIRQ[gc].or;
 565 
 566   for (gc = 0; orDMA[gc].or; gc++)
 567     if (orDMA[gc].val == dma)
 568       oredparams |= orDMA[gc].or;
 569 }
 570 
 571 static int
 572 InitAEDSP16 (int which)
     /* [previous][next][first][last][top][bottom][index][help] */
 573 {
 574   static char    *InitName = NULL;
 575 
 576   InitializeHardParams ();
 577 
 578   if (ResetBoard (portbase))
 579     {
 580       printk ("[aedsp16] ResetBoard: failed!\n");
 581       return -1;
 582     }
 583 
 584 #if defined(THIS_SHOULD_GO_AWAY)
 585   if (CheckDSPOkay (portbase))
 586     {
 587       printk ("[aedsp16] CheckDSPOkay: failed!\n");
 588       return -1;
 589     }
 590 #endif
 591 
 592   if (WriteDSPCommand (portbase, CMD1))
 593     {
 594       printk ("[aedsp16] CMD 0x%x: failed!\n", CMD1);
 595       return -1;
 596     }
 597 
 598   if (GetCardName (portbase))
 599     {
 600       printk ("[aedsp16] GetCardName: failed!\n");
 601       return -1;
 602     }
 603 
 604   /*
 605      * My AEDSP16 card return SC-6000 in AudioExcelName, so
 606      * if we have something different, we have to be warned.
 607    */
 608   if (strcmp ("SC-6000", AudioExcelName))
 609     printk ("[aedsp16] Warning: non SC-6000 audio card!\n");
 610 
 611   if (WriteDSPCommand (portbase, CMD2))
 612     {
 613       printk ("[aedsp16] CMD 0x%x: failed!\n", CMD2);
 614       return -1;
 615     }
 616 
 617   if (GetCardVersion (portbase))
 618     {
 619       printk ("[aedsp16] GetCardVersion: failed!\n");
 620       return -1;
 621     }
 622 
 623   if (SetUpBoard (portbase))
 624     {
 625       printk ("[aedsp16] SetUpBoard: failed!\n");
 626       return -1;
 627     }
 628 
 629   if (which == INIT_MSS)
 630     {
 631       if (InitMSS (portbase))
 632         {
 633           printk ("[aedsp16] Can't initialize Microsoft Sound System mode.\n");
 634           return -1;
 635         }
 636     }
 637 
 638   /*
 639      * If we are resetting, do not print any message because we may be
 640      * in playing and we do not want lost too much time.
 641    */
 642   if (!(which & RESET_DSP16))
 643     {
 644       if (which & INIT_MPU401)
 645         InitName = "MPU401";
 646       else if (which & INIT_SBPRO)
 647         InitName = "SBPro";
 648       else if (which & INIT_MSS)
 649         InitName = "MSS";
 650       else
 651         InitName = "None";
 652 
 653       printk ("Audio Excel DSP 16 init v%s (%s %s) [%s]\n",
 654               VERSION, AudioExcelName,
 655               AudioExcelVersion, InitName);
 656     }
 657 
 658   tenmillisec ();
 659 
 660   return 0;
 661 }
 662 
 663 #if defined(AEDSP16_SBPRO)
 664 
 665 int
 666 InitAEDSP16_SBPRO (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 667 {
 668   /*
 669      * If the card is already init'ed MSS, we can not init it to SBPRO too
 670      * because the board can not emulate simultaneously MSS and SBPRO.
 671    */
 672   if (ae_init & INIT_MSS)
 673     return -1;
 674   if (ae_init & INIT_SBPRO)
 675     return 0;
 676 
 677   /*
 678      * For now we will leave this
 679      * code included only when INCLUDE_AEDSP16 is configured in, but it should
 680      * be better include it every time.
 681    */
 682   if (!(ae_init & INIT_MPU401))
 683     {
 684       if (check_region (hw_config->io_base, 0x0f))
 685         {
 686           printk ("AEDSP16/SBPRO I/O port region is already in use.\n");
 687           return -1;
 688         }
 689     }
 690 
 691   /*
 692      * Set up the internal hardware parameters, to let the driver reach
 693      * the Sound Card.
 694    */
 695   portbase = hw_config->io_base;
 696   irq = hw_config->irq;
 697   dma = hw_config->dma;
 698 
 699   if (InitAEDSP16 (INIT_SBPRO))
 700     return -1;
 701 
 702 #if !defined(MODULE)
 703   /*
 704      * If we are compiling sound.o (MODULAR version) we can not
 705      * request any region because there is not a uninit routine that
 706      * can allow me to release the requested region.
 707    */
 708   if (!(ae_init & INIT_MPU401))
 709     request_region (hw_config->io_base, 0x0f, "aedsp16 (sbpro)");
 710 #endif
 711 
 712   ae_init |= INIT_SBPRO;
 713   return 0;
 714 }
 715 
 716 #endif /* AEDSP16_SBPRO */
 717 
 718 #if defined(AEDSP16_MSS)
 719 
 720 int
 721 InitAEDSP16_MSS (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 722 {
 723   /*
 724      * If the card is already init'ed SBPRO, we can not init it to MSS too
 725      * because the board can not emulate simultaneously MSS and SBPRO.
 726    */
 727   if (ae_init & INIT_SBPRO)
 728     return -1;
 729   if (ae_init & INIT_MSS)
 730     return 0;
 731 
 732   /*
 733      * For now we will leave this
 734      * code included only when INCLUDE_AEDSP16 is configured in, but it should
 735      * be better include it every time.
 736    */
 737   if (check_region (hw_config->io_base, 0x08))
 738     {
 739       printk ("MSS I/O port region is already in use.\n");
 740       return -1;
 741     }
 742 
 743   /*
 744      * We must allocate the AEDSP16 region too because these are the I/O ports
 745      * to access card's control registers.
 746    */
 747   if (!(ae_init & INIT_MPU401))
 748     {
 749       if (check_region (AEDSP16_BASE, 0x0f))
 750         {
 751           printk ("AEDSP16 I/O port region is already in use.\n");
 752           return -1;
 753         }
 754     }
 755 
 756 
 757   /*
 758      * If we are configuring the card for MSS, the portbase for card
 759      * configuration is the default one (0x220 unless you have changed the
 760      * factory default with board switches), so no need to modify the
 761      * portbase variable.
 762      * The default is AEDSP16_BASE, that is the right value.
 763    */
 764   irq = hw_config->irq;
 765   dma = hw_config->dma;
 766 
 767   if (InitAEDSP16 (INIT_MSS))
 768     return -1;
 769 
 770 #if !defined(MODULE)
 771   /*
 772      * If we are compiling sound.o (MODULAR version) we can not
 773      * request any region because there is not a uninit routine that
 774      * can allow me to release the requested region. So when unloading
 775      * and then reloading it, we are going to have some nice Oops!
 776    */
 777   request_region (hw_config->io_base, 0x08, "aedsp16 (mss)");
 778 #endif
 779 
 780   if (!(ae_init & INIT_MPU401))
 781     request_region (AEDSP16_BASE, 0x0f, "aedsp16 (sbpro)");
 782 
 783   ae_init |= INIT_MSS;
 784   return 0;
 785 }
 786 
 787 #endif /* AEDSP16_MSS */
 788 
 789 #if defined(AEDSP16_MPU401)
 790 
 791 int
 792 InitAEDSP16_MPU401 (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 793 {
 794   if (ae_init & INIT_MPU401)
 795     return 0;
 796 
 797   /*
 798      * For now we will leave this
 799      * code included only when INCLUDE_AEDSP16 is configured in, but it should
 800      * be better include it every time.
 801    */
 802   if (check_region (hw_config->io_base, 0x02))
 803     {
 804       printk ("SB I/O port region is already in use.\n");
 805       return -1;
 806     }
 807 
 808   /*
 809      * We must allocate the AEDSP16 region too because these are the I/O ports
 810      * to access card's control registers.
 811    */
 812   if (!(ae_init & (INIT_MSS | INIT_SBPRO)))
 813     {
 814       if (check_region (AEDSP16_BASE, 0x0f))
 815         {
 816           printk ("AEDSP16 I/O port region is already in use.\n");
 817           return -1;
 818         }
 819     }
 820 
 821   /*
 822      * If mpu401, the irq and dma are not important, do not touch it
 823      * because we may use the default if sbpro is not yet configured,
 824      * we may use the sbpro ones if configured, and nothing wrong
 825      * should happen.
 826      *
 827      * The mirq default is 0, but once set it to non-0 value, we should
 828      * not touch it anymore (unless I write an ioctl to do it, of course).
 829    */
 830   mirq = hw_config->irq;
 831   if (InitAEDSP16 (INIT_MPU401))
 832     return -1;
 833 
 834 #if !defined(MODULE)
 835   /*
 836      * If we are compiling sound.o (MODULAR version) we can not
 837      * request any region because there is not a uninit routine that
 838      * can allow me to release the requested region.
 839    */
 840   request_region (hw_config->io_base, 0x02, "aedsp16 (mpu401)");
 841 #endif
 842 
 843   if (!(ae_init & (INIT_MSS | INIT_SBPRO)))
 844     request_region (AEDSP16_BASE, 0x0f, "aedsp16 (sbpro)");
 845 
 846   ae_init |= INIT_MPU401;
 847   return 0;
 848 }
 849 
 850 #endif /* AEDSP16_MPU401 */
 851 
 852 #if 0                           /* Leave it out for now. We are not using this portion of code. */
 853 
 854 /*
 855  * Entry point for a reset function.
 856  * May be I will write the infamous ioctl :)
 857  */
 858 int
 859 ResetAEDSP16 (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 860 {
 861 #if defined(AEDSP16_DEBUG)
 862   printk ("[aedsp16] ResetAEDSP16 called.\n");
 863 #endif
 864   return InitAEDSP16 (RESET_DSP16);
 865 }
 866 
 867 #endif /* 0 */
 868 
 869 #endif /* CONFIG_AEDSP16 */

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