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

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