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

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