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  * all but ioport.h :)
  35  */
  36 #include <linux/ioport.h>
  37 
  38 #if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_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 INB and OUTB #defined in os.h instead of inb and outb.
 213    - Corrected the code for GetCardName (DSP Copyright) 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    - Rearrangemens 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 offest 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 alredy 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 availabe, 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 alredy 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 alredy 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   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   if (InitAEDSP16 (INIT_MSS))
 766     return -1;
 767 
 768 #if !defined(MODULE)
 769   /*
 770      * If we are compiling sound.o (MODULAR version) we can not
 771      * request any region because there is not a uninit routine that
 772      * can allow me to release the requested region. So when unloading
 773      * and then reloading it, we are going to have some nice Oops!
 774    */
 775   request_region (hw_config->io_base, 0x08, "aedsp16 (mss)");
 776 #endif
 777 
 778   if (!(ae_init & INIT_MPU401))
 779     request_region (AEDSP16_BASE, 0x0f, "aedsp16 (sbpro)");
 780 
 781   ae_init |= INIT_MSS;
 782   return 0;
 783 }
 784 
 785 #endif /* AEDSP16_MSS */
 786 
 787 #if defined(AEDSP16_MPU401)
 788 
 789 int
 790 InitAEDSP16_MPU401 (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 791 {
 792   if (ae_init & INIT_MPU401)
 793     return 0;
 794 
 795   /*
 796      * For now we will leave this
 797      * code included only when INCLUDE_AEDSP16 is configured in, but it should
 798      * be better include it every time.
 799    */
 800   if (check_region (hw_config->io_base, 0x02))
 801     {
 802       printk ("SB I/O port region is alredy in use.\n");
 803       return -1;
 804     }
 805 
 806   /*
 807      * We must allocate the AEDSP16 region too because these are the I/O ports
 808      * to access card's control registers.
 809    */
 810   if (!(ae_init & (INIT_MSS | INIT_SBPRO)))
 811     {
 812       if (check_region (AEDSP16_BASE, 0x0f))
 813         {
 814           printk ("AEDSP16 I/O port region is alredy in use.\n");
 815           return -1;
 816         }
 817     }
 818 
 819   /*
 820      * If mpu401, the irq and dma are not important, do not touch it
 821      * because we may use the default if sbpro is not yet configured,
 822      * we may use the sbpro ones if configured, and nothing wrong
 823      * should happen.
 824      *
 825      * The mirq default is 0, but once set it to non-0 value, we should
 826      * not touch it anymore (unless I write an ioctl to do it, of course).
 827    */
 828   mirq = hw_config->irq;
 829   if (InitAEDSP16 (INIT_MPU401))
 830     return -1;
 831 
 832 #if !defined(MODULE)
 833   /*
 834      * If we are compiling sound.o (MODULAR version) we can not
 835      * request any region because there is not a uninit routine that
 836      * can allow me to release the requested region.
 837    */
 838   request_region (hw_config->io_base, 0x02, "aedsp16 (mpu401)");
 839 #endif
 840 
 841   if (!(ae_init & (INIT_MSS | INIT_SBPRO)))
 842     request_region (AEDSP16_BASE, 0x0f, "aedsp16 (sbpro)");
 843 
 844   ae_init |= INIT_MPU401;
 845   return 0;
 846 }
 847 
 848 #endif /* AEDSP16_MPU401 */
 849 
 850 #if 0                           /* Leave it out for now. We are not using this portion of code. */
 851 
 852 /*
 853  * Entry point for a reset function.
 854  * May be I will write the infamous ioctl :)
 855  */
 856 int
 857 ResetAEDSP16 (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 858 {
 859 #if defined(AEDSP16_DEBUG)
 860   printk ("[aedsp16] ResetAEDSP16 called.\n");
 861 #endif
 862   return InitAEDSP16 (RESET_DSP16);
 863 }
 864 
 865 #endif /* 0 */
 866 
 867 #endif /* !EXCLUDE_AEDSP16 */

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