root/drivers/sound/pss.c

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

DEFINITIONS

This source file includes following definitions.
  1. probe_pss
  2. set_irq
  3. set_io_base
  4. set_dma
  5. pss_reset_dsp
  6. pss_put_dspword
  7. pss_get_dspword
  8. pss_download_boot
  9. attach_pss
  10. probe_pss_mpu
  11. pss_coproc_open
  12. pss_coproc_close
  13. pss_coproc_reset
  14. download_boot_block
  15. pss_coproc_ioctl
  16. attach_pss_mpu
  17. probe_pss_mss
  18. attach_pss_mss
  19. unload_pss
  20. unload_pss_mpu
  21. unload_pss_mss

   1 /*
   2  * sound/pss.c
   3  *
   4  * The low level driver for the Personal Sound System (ECHO ESC614).
   5  *
   6  * Copyright by Hannu Savolainen 1993
   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 
  30 #include "sound_config.h"
  31 
  32 #if defined (CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_PSS) && !defined(EXCLUDE_AUDIO)
  33 
  34 /*
  35  * PSS registers.
  36  */
  37 #define REG(x)  (devc->base+x)
  38 #define PSS_DATA        0
  39 #define PSS_STATUS      2
  40 #define PSS_CONTROL     2
  41 #define PSS_ID          4
  42 #define PSS_IRQACK      4
  43 #define PSS_PIO         0x1a
  44 
  45 /*
  46  * Config registers
  47  */
  48 #define CONF_PSS        0x10
  49 #define CONF_WSS        0x12
  50 #define CONF_SB         0x13
  51 #define CONF_CDROM      0x16
  52 #define CONF_MIDI       0x18
  53 
  54 /*
  55  * Status bits.
  56  */
  57 #define PSS_FLAG3     0x0800
  58 #define PSS_FLAG2     0x0400
  59 #define PSS_FLAG1     0x1000
  60 #define PSS_FLAG0     0x0800
  61 #define PSS_WRITE_EMPTY  0x8000
  62 #define PSS_READ_FULL    0x4000
  63 
  64 #include "coproc.h"
  65 
  66 #ifdef PSS_HAVE_LD
  67 #include "synth-ld.h"
  68 #else
  69 static int      pss_synthLen = 0;
  70 static unsigned char pss_synth[1] =
  71 {0};
  72 
  73 #endif
  74 
  75 typedef struct pss_config
  76   {
  77     int             base;
  78     int             irq;
  79     int             dma;
  80     sound_os_info  *osp;
  81   }
  82 
  83 pss_config;
  84 
  85 static pss_config pss_data;
  86 static pss_config *devc = &pss_data;
  87 
  88 static int      pss_initialized = 0;
  89 static int      nonstandard_microcode = 0;
  90 
  91 int
  92 probe_pss (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
  93 {
  94   unsigned short  id;
  95   int             irq, dma;
  96 
  97   devc->base = hw_config->io_base;
  98   irq = devc->irq = hw_config->irq;
  99   dma = devc->dma = hw_config->dma;
 100   devc->osp = hw_config->osp;
 101 
 102   if (devc->base != 0x220 && devc->base != 0x240)
 103     if (devc->base != 0x230 && devc->base != 0x250)     /* Some cards use these */
 104       return 0;
 105 
 106   if (check_region (devc->base, 16))
 107     {
 108       printk ("PSS: I/O port conflict\n");
 109       return 0;
 110     }
 111 
 112   if (irq != 3 && irq != 5 && irq != 7 && irq != 9 &&
 113       irq != 10 && irq != 11 && irq != 12)
 114     return 0;
 115 
 116   if (dma != 5 && dma != 6 && dma != 7)
 117     return 0;
 118 
 119   id = inw (REG (PSS_ID));
 120   if ((id >> 8) != 'E')
 121     {
 122       /* printk ("No PSS signature detected at 0x%x (0x%x)\n", devc->base, id); */
 123       return 0;
 124     }
 125 
 126   return 1;
 127 }
 128 
 129 static int
 130 set_irq (pss_config * devc, int dev, int irq)
     /* [previous][next][first][last][top][bottom][index][help] */
 131 {
 132   static unsigned short irq_bits[16] =
 133   {
 134     0x0000, 0x0000, 0x0000, 0x0008,
 135     0x0000, 0x0010, 0x0000, 0x0018,
 136     0x0000, 0x0020, 0x0028, 0x0030,
 137     0x0038, 0x0000, 0x0000, 0x0000
 138   };
 139 
 140   unsigned short  tmp, bits;
 141 
 142   if (irq < 0 || irq > 15)
 143     return 0;
 144 
 145   tmp = inw (REG (dev)) & ~0x38;        /* Load confreg, mask IRQ bits out */
 146 
 147   if ((bits = irq_bits[irq]) == 0 && irq != 0)
 148     {
 149       printk ("PSS: Invalid IRQ %d\n", irq);
 150       return 0;
 151     }
 152 
 153   outw (tmp | bits, REG (dev));
 154   return 1;
 155 }
 156 
 157 static int
 158 set_io_base (pss_config * devc, int dev, int base)
     /* [previous][next][first][last][top][bottom][index][help] */
 159 {
 160   unsigned short  tmp = inw (REG (dev)) & 0x003f;
 161   unsigned short  bits = (base & 0x0ffc) << 4;
 162 
 163   outw (bits | tmp, REG (dev));
 164 
 165   return 1;
 166 }
 167 
 168 static int
 169 set_dma (pss_config * devc, int dev, int dma)
     /* [previous][next][first][last][top][bottom][index][help] */
 170 {
 171   static unsigned short dma_bits[8] =
 172   {
 173     0x0001, 0x0002, 0x0000, 0x0003,
 174     0x0000, 0x0005, 0x0006, 0x0007
 175   };
 176 
 177   unsigned short  tmp, bits;
 178 
 179   if (dma < 0 || dma > 7)
 180     return 0;
 181 
 182   tmp = inw (REG (dev)) & ~0x07;        /* Load confreg, mask DMA bits out */
 183 
 184   if ((bits = dma_bits[dma]) == 0 && dma != 4)
 185     {
 186       printk ("PSS: Invalid DMA %d\n", dma);
 187       return 0;
 188     }
 189 
 190   outw (tmp | bits, REG (dev));
 191   return 1;
 192 }
 193 
 194 static int
 195 pss_reset_dsp (pss_config * devc)
     /* [previous][next][first][last][top][bottom][index][help] */
 196 {
 197   unsigned long   i, limit = jiffies + 10;
 198 
 199   outw (0x2000, REG (PSS_CONTROL));
 200 
 201   for (i = 0; i < 32768 && jiffies < limit; i++)
 202     inw (REG (PSS_CONTROL));
 203 
 204   outw (0x0000, REG (PSS_CONTROL));
 205 
 206   return 1;
 207 }
 208 
 209 static int
 210 pss_put_dspword (pss_config * devc, unsigned short word)
     /* [previous][next][first][last][top][bottom][index][help] */
 211 {
 212   int             i, val;
 213 
 214   for (i = 0; i < 327680; i++)
 215     {
 216       val = inw (REG (PSS_STATUS));
 217       if (val & PSS_WRITE_EMPTY)
 218         {
 219           outw (word, REG (PSS_DATA));
 220           return 1;
 221         }
 222     }
 223   return 0;
 224 }
 225 
 226 static int
 227 pss_get_dspword (pss_config * devc, unsigned short *word)
     /* [previous][next][first][last][top][bottom][index][help] */
 228 {
 229   int             i, val;
 230 
 231   for (i = 0; i < 327680; i++)
 232     {
 233       val = inw (REG (PSS_STATUS));
 234       if (val & PSS_READ_FULL)
 235         {
 236           *word = inw (REG (PSS_DATA));
 237           return 1;
 238         }
 239     }
 240 
 241   return 0;
 242 }
 243 
 244 static int
 245 pss_download_boot (pss_config * devc, unsigned char *block, int size, int flags)
     /* [previous][next][first][last][top][bottom][index][help] */
 246 {
 247   int             i, limit, val, count;
 248 
 249   if (flags & CPF_FIRST)
 250     {
 251 /*_____ Warn DSP software that a boot is coming */
 252       outw (0x00fe, REG (PSS_DATA));
 253 
 254       limit = jiffies + 10;
 255 
 256       for (i = 0; i < 32768 && jiffies < limit; i++)
 257         if (inw (REG (PSS_DATA)) == 0x5500)
 258           break;
 259 
 260       outw (*block++, REG (PSS_DATA));
 261 
 262       pss_reset_dsp (devc);
 263     }
 264 
 265   count = 1;
 266   while (1)
 267     {
 268       int             j;
 269 
 270       for (j = 0; j < 327670; j++)
 271         {
 272 /*_____ Wait for BG to appear */
 273           if (inw (REG (PSS_STATUS)) & PSS_FLAG3)
 274             break;
 275         }
 276 
 277       if (j == 327670)
 278         {
 279           /* It's ok we timed out when the file was empty */
 280           if (count >= size && flags & CPF_LAST)
 281             break;
 282           else
 283             {
 284               printk ("\nPSS: DownLoad timeout problems, byte %d=%d\n",
 285                       count, size);
 286               return 0;
 287             }
 288         }
 289 /*_____ Send the next byte */
 290       outw (*block++, REG (PSS_DATA));
 291       count++;
 292     }
 293 
 294   if (flags & CPF_LAST)
 295     {
 296 /*_____ Why */
 297       outw (0, REG (PSS_DATA));
 298 
 299       limit = jiffies + 10;
 300       for (i = 0; i < 32768 && jiffies < limit; i++)
 301         val = inw (REG (PSS_STATUS));
 302 
 303       limit = jiffies + 10;
 304       for (i = 0; i < 32768 && jiffies < limit; i++)
 305         {
 306           val = inw (REG (PSS_STATUS));
 307           if (val & 0x4000)
 308             break;
 309         }
 310 
 311       /* now read the version */
 312       for (i = 0; i < 32000; i++)
 313         {
 314           val = inw (REG (PSS_STATUS));
 315           if (val & PSS_READ_FULL)
 316             break;
 317         }
 318       if (i == 32000)
 319         return 0;
 320 
 321       val = inw (REG (PSS_DATA));
 322       /* printk("<PSS: microcode version %d.%d loaded>", val/16, val % 16); */
 323     }
 324 
 325   return 1;
 326 }
 327 
 328 long
 329 attach_pss (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 330 {
 331   unsigned short  id;
 332 
 333   devc->base = hw_config->io_base;
 334   devc->irq = hw_config->irq;
 335   devc->dma = hw_config->dma;
 336   devc->osp = hw_config->osp;
 337 
 338   if (!probe_pss (hw_config))
 339     return mem_start;
 340 
 341   id = inw (REG (PSS_ID)) & 0x00ff;
 342 
 343   /*
 344      * Disable all emulations. Will be enabled later (if required).
 345    */
 346   outw (0x0000, REG (CONF_PSS));
 347   outw (0x0000, REG (CONF_WSS));
 348   outw (0x0000, REG (CONF_SB));
 349   outw (0x0000, REG (CONF_MIDI));
 350   outw (0x0000, REG (CONF_CDROM));
 351 
 352 #if YOU_REALLY_WANT_TO_ALLOCATE_THESE_RESOURCES
 353   if (sound_alloc_dma (hw_config->dma, "PSS"))
 354     {
 355       printk ("pss.c: Can't allocate DMA channel\n");
 356       return mem_start;
 357     }
 358 
 359   if (!set_irq (devc, CONF_PSS, devc->irq))
 360     {
 361       printk ("PSS: IRQ error\n");
 362       return mem_start;
 363     }
 364 
 365   if (!set_dma (devc, CONF_PSS, devc->dma))
 366     {
 367       printk ("PSS: DRQ error\n");
 368       return mem_start;
 369     }
 370 #endif
 371 
 372   pss_initialized = 1;
 373   printk (" <ECHO-PSS  Rev. %d>", id);
 374 
 375   return mem_start;
 376 }
 377 
 378 int
 379 probe_pss_mpu (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 380 {
 381   int             timeout;
 382 
 383   if (!pss_initialized)
 384     return 0;
 385 
 386   if (check_region (hw_config->io_base, 2))
 387     {
 388       printk ("PSS: MPU I/O port conflict\n");
 389       return 0;
 390     }
 391 
 392   if (!set_io_base (devc, CONF_MIDI, hw_config->io_base))
 393     {
 394       printk ("PSS: MIDI base error.\n");
 395       return 0;
 396     }
 397 
 398   if (!set_irq (devc, CONF_MIDI, hw_config->irq))
 399     {
 400       printk ("PSS: MIDI IRQ error.\n");
 401       return 0;
 402     }
 403 
 404   if (!pss_synthLen)
 405     {
 406       printk ("PSS: Can't enable MPU. MIDI synth microcode not available.\n");
 407       return 0;
 408     }
 409 
 410   if (!pss_download_boot (devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
 411     {
 412       printk ("PSS: Unable to load MIDI synth microcode to DSP.\n");
 413       return 0;
 414     }
 415 
 416 /*
 417  * Finally wait until the DSP algorithm has initialized itself and
 418  * deactivates receive interrupt.
 419  */
 420 
 421   for (timeout = 900000; timeout > 0; timeout--)
 422     {
 423       if ((inb (hw_config->io_base + 1) & 0x80) == 0)   /* Input data avail */
 424         inb (hw_config->io_base);       /* Discard it */
 425       else
 426         break;                  /* No more input */
 427     }
 428 
 429 #if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI)
 430   return probe_mpu401 (hw_config);
 431 #else
 432   return 0
 433 #endif
 434 }
 435 
 436 static int
 437 pss_coproc_open (void *dev_info, int sub_device)
     /* [previous][next][first][last][top][bottom][index][help] */
 438 {
 439   switch (sub_device)
 440     {
 441     case COPR_MIDI:
 442 
 443       if (pss_synthLen == 0)
 444         {
 445           printk ("PSS: MIDI synth microcode not available.\n");
 446           return -EIO;
 447         }
 448 
 449       if (nonstandard_microcode)
 450         if (!pss_download_boot (devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
 451           {
 452             printk ("PSS: Unable to load MIDI synth microcode to DSP.\n");
 453             return -EIO;
 454           }
 455       nonstandard_microcode = 0;
 456       break;
 457 
 458     default:;
 459     }
 460   return 0;
 461 }
 462 
 463 static void
 464 pss_coproc_close (void *dev_info, int sub_device)
     /* [previous][next][first][last][top][bottom][index][help] */
 465 {
 466   return;
 467 }
 468 
 469 static void
 470 pss_coproc_reset (void *dev_info)
     /* [previous][next][first][last][top][bottom][index][help] */
 471 {
 472   if (pss_synthLen)
 473     if (!pss_download_boot (devc, pss_synth, pss_synthLen, CPF_FIRST | CPF_LAST))
 474       {
 475         printk ("PSS: Unable to load MIDI synth microcode to DSP.\n");
 476       }
 477   nonstandard_microcode = 0;
 478 }
 479 
 480 static int
 481 download_boot_block (void *dev_info, copr_buffer * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 482 {
 483   if (buf->len <= 0 || buf->len > sizeof (buf->data))
 484     return -EINVAL;
 485 
 486   if (!pss_download_boot (devc, buf->data, buf->len, buf->flags))
 487     {
 488       printk ("PSS: Unable to load microcode block to DSP.\n");
 489       return -EIO;
 490     }
 491   nonstandard_microcode = 1;    /* The MIDI microcode has been overwritten */
 492 
 493   return 0;
 494 }
 495 
 496 static int
 497 pss_coproc_ioctl (void *dev_info, unsigned int cmd, ioctl_arg arg, int local)
     /* [previous][next][first][last][top][bottom][index][help] */
 498 {
 499   /* printk("PSS coproc ioctl %x %x %d\n", cmd, arg, local); */
 500 
 501   switch (cmd)
 502     {
 503     case SNDCTL_COPR_RESET:
 504       pss_coproc_reset (dev_info);
 505       return 0;
 506       break;
 507 
 508     case SNDCTL_COPR_LOAD:
 509       {
 510         copr_buffer    *buf;
 511         int             err;
 512 
 513         buf = (copr_buffer *) kmalloc (sizeof (copr_buffer), GFP_KERNEL);
 514         if (buf == NULL)
 515           return -ENOSPC;
 516 
 517         memcpy_fromfs ((char *) buf, &(((char *) arg)[0]), sizeof (*buf));
 518         err = download_boot_block (dev_info, buf);
 519         kfree (buf);
 520         return err;
 521       }
 522       break;
 523 
 524     case SNDCTL_COPR_RDATA:
 525       {
 526         copr_debug_buf  buf;
 527         unsigned long   flags;
 528         unsigned short  tmp;
 529 
 530         memcpy_fromfs ((char *) &buf, &(((char *) arg)[0]), sizeof (buf));
 531 
 532         save_flags (flags);
 533         cli ();
 534         if (!pss_put_dspword (devc, 0x00d0))
 535           {
 536             restore_flags (flags);
 537             return -EIO;
 538           }
 539 
 540         if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
 541           {
 542             restore_flags (flags);
 543             return -EIO;
 544           }
 545 
 546         if (!pss_get_dspword (devc, &tmp))
 547           {
 548             restore_flags (flags);
 549             return -EIO;
 550           }
 551 
 552         buf.parm1 = tmp;
 553         restore_flags (flags);
 554 
 555         memcpy_tofs ((&((char *) arg)[0]), &buf, sizeof (buf));
 556         return 0;
 557       }
 558       break;
 559 
 560     case SNDCTL_COPR_WDATA:
 561       {
 562         copr_debug_buf  buf;
 563         unsigned long   flags;
 564         unsigned short  tmp;
 565 
 566         memcpy_fromfs ((char *) &buf, &(((char *) arg)[0]), sizeof (buf));
 567 
 568         save_flags (flags);
 569         cli ();
 570         if (!pss_put_dspword (devc, 0x00d1))
 571           {
 572             restore_flags (flags);
 573             return -EIO;
 574           }
 575 
 576         if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
 577           {
 578             restore_flags (flags);
 579             return -EIO;
 580           }
 581 
 582         tmp = (unsigned int) buf.parm2 & 0xffff;
 583         if (!pss_put_dspword (devc, tmp))
 584           {
 585             restore_flags (flags);
 586             return -EIO;
 587           }
 588 
 589         restore_flags (flags);
 590         return 0;
 591       }
 592       break;
 593 
 594     case SNDCTL_COPR_WCODE:
 595       {
 596         copr_debug_buf  buf;
 597         unsigned long   flags;
 598         unsigned short  tmp;
 599 
 600         memcpy_fromfs ((char *) &buf, &(((char *) arg)[0]), sizeof (buf));
 601 
 602         save_flags (flags);
 603         cli ();
 604         if (!pss_put_dspword (devc, 0x00d3))
 605           {
 606             restore_flags (flags);
 607             return -EIO;
 608           }
 609 
 610         if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
 611           {
 612             restore_flags (flags);
 613             return -EIO;
 614           }
 615 
 616         tmp = ((unsigned int) buf.parm2 >> 8) & 0xffff;
 617         if (!pss_put_dspword (devc, tmp))
 618           {
 619             restore_flags (flags);
 620             return -EIO;
 621           }
 622 
 623         tmp = (unsigned int) buf.parm2 & 0x00ff;
 624         if (!pss_put_dspword (devc, tmp))
 625           {
 626             restore_flags (flags);
 627             return -EIO;
 628           }
 629 
 630         restore_flags (flags);
 631         return 0;
 632       }
 633       break;
 634 
 635     case SNDCTL_COPR_RCODE:
 636       {
 637         copr_debug_buf  buf;
 638         unsigned long   flags;
 639         unsigned short  tmp;
 640 
 641         memcpy_fromfs ((char *) &buf, &(((char *) arg)[0]), sizeof (buf));
 642 
 643         save_flags (flags);
 644         cli ();
 645         if (!pss_put_dspword (devc, 0x00d2))
 646           {
 647             restore_flags (flags);
 648             return -EIO;
 649           }
 650 
 651         if (!pss_put_dspword (devc, (unsigned short) (buf.parm1 & 0xffff)))
 652           {
 653             restore_flags (flags);
 654             return -EIO;
 655           }
 656 
 657         if (!pss_get_dspword (devc, &tmp))      /* Read msb */
 658           {
 659             restore_flags (flags);
 660             return -EIO;
 661           }
 662 
 663         buf.parm1 = tmp << 8;
 664 
 665         if (!pss_get_dspword (devc, &tmp))      /* Read lsb */
 666           {
 667             restore_flags (flags);
 668             return -EIO;
 669           }
 670 
 671         buf.parm1 |= tmp & 0x00ff;
 672 
 673         restore_flags (flags);
 674 
 675         memcpy_tofs ((&((char *) arg)[0]), &buf, sizeof (buf));
 676         return 0;
 677       }
 678       break;
 679 
 680     default:
 681       return -EINVAL;
 682     }
 683 
 684   return -EINVAL;
 685 }
 686 
 687 static coproc_operations pss_coproc_operations =
 688 {
 689   "ADSP-2115",
 690   pss_coproc_open,
 691   pss_coproc_close,
 692   pss_coproc_ioctl,
 693   pss_coproc_reset,
 694   &pss_data
 695 };
 696 
 697 long
 698 attach_pss_mpu (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 699 {
 700   int             prev_devs;
 701   long            ret;
 702 
 703 #if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI)
 704   prev_devs = num_midis;
 705   ret = attach_mpu401 (mem_start, hw_config);
 706 
 707   if (num_midis == (prev_devs + 1))     /* The MPU driver installed itself */
 708     midi_devs[prev_devs]->coproc = &pss_coproc_operations;
 709 #endif
 710   return ret;
 711 }
 712 
 713 int
 714 probe_pss_mss (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 715 {
 716   int             timeout;
 717 
 718   if (!pss_initialized)
 719     return 0;
 720 
 721   if (check_region (hw_config->io_base, 8))
 722     {
 723       printk ("PSS: WSS I/O port conflict\n");
 724       return 0;
 725     }
 726 
 727   if (!set_io_base (devc, CONF_WSS, hw_config->io_base))
 728     {
 729       printk ("PSS: WSS base error.\n");
 730       return 0;
 731     }
 732 
 733   if (!set_irq (devc, CONF_WSS, hw_config->irq))
 734     {
 735       printk ("PSS: WSS IRQ error.\n");
 736       return 0;
 737     }
 738 
 739   if (!set_dma (devc, CONF_WSS, hw_config->dma))
 740     {
 741       printk ("PSS: WSS DRQ error\n");
 742       return 0;
 743     }
 744 
 745   /*
 746      * For some reason the card returns 0xff in the WSS status register
 747      * immediately after boot. Propably MIDI+SB emulation algorithm
 748      * downloaded to the ADSP2115 spends some time initializing the card.
 749      * Let's try to wait until it finishes this task.
 750    */
 751   for (timeout = 0;
 752        timeout < 100000 && (inb (hw_config->io_base + 3) & 0x3f) != 0x04;
 753        timeout++);
 754 
 755   return probe_ms_sound (hw_config);
 756 }
 757 
 758 long
 759 attach_pss_mss (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 760 {
 761   int             prev_devs;
 762   long            ret;
 763 
 764   prev_devs = num_audiodevs;
 765   ret = attach_ms_sound (mem_start, hw_config);
 766 
 767   if (num_audiodevs == (prev_devs + 1))         /* The MSS driver installed itself */
 768     audio_devs[prev_devs]->coproc = &pss_coproc_operations;
 769 
 770   return ret;
 771 }
 772 
 773 void
 774 unload_pss (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 775 {
 776 }
 777 
 778 void
 779 unload_pss_mpu (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 780 {
 781   unload_mpu401 (hw_config);
 782 }
 783 
 784 void
 785 unload_pss_mss (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 786 {
 787   unload_ms_sound (hw_config);
 788 }
 789 
 790 #endif

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