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

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

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