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

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