root/drivers/sound/sscape.c

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

DEFINITIONS

This source file includes following definitions.
  1. sscape_read
  2. sscape_write
  3. host_open
  4. host_close
  5. host_write
  6. host_read
  7. host_command1
  8. host_command2
  9. host_command3
  10. set_mt32
  11. set_control
  12. get_board_type
  13. sscapeintr
  14. sscape_enable_intr
  15. sscape_disable_intr
  16. do_dma
  17. verify_mpu
  18. sscape_coproc_open
  19. sscape_coproc_close
  20. sscape_coproc_reset
  21. sscape_download_boot
  22. download_boot_block
  23. sscape_coproc_ioctl
  24. sscape_audio_open
  25. sscape_audio_close
  26. set_speed
  27. set_channels
  28. set_format
  29. sscape_audio_ioctl
  30. sscape_audio_output_block
  31. sscape_audio_start_input
  32. sscape_audio_prepare_for_input
  33. sscape_audio_prepare_for_output
  34. sscape_audio_halt
  35. sscape_audio_reset
  36. attach_sscape
  37. probe_sscape
  38. probe_ss_ms_sound
  39. attach_ss_ms_sound
  40. unload_sscape
  41. unload_ss_ms_sound

   1 /*
   2  * sound/sscape.c
   3  *
   4  * Low level driver for Ensoniq Soundscape
   5  *
   6  * Copyright by Hannu Savolainen 1994
   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_SSCAPE)
  33 
  34 #include "coproc.h"
  35 
  36 /*
  37  *    I/O ports
  38  */
  39 #define MIDI_DATA        0
  40 #define MIDI_CTRL        1
  41 #define HOST_CTRL        2
  42 #define TX_READY                0x02
  43 #define RX_READY                0x01
  44 #define HOST_DATA        3
  45 #define ODIE_ADDR        4
  46 #define ODIE_DATA        5
  47 
  48 /*
  49  *    Indirect registers
  50  */
  51 #define GA_INTSTAT_REG   0
  52 #define GA_INTENA_REG    1
  53 #define GA_DMAA_REG      2
  54 #define GA_DMAB_REG      3
  55 #define GA_INTCFG_REG    4
  56 #define GA_DMACFG_REG    5
  57 #define GA_CDCFG_REG     6
  58 #define GA_SMCFGA_REG    7
  59 #define GA_SMCFGB_REG    8
  60 #define GA_HMCTL_REG     9
  61 
  62 /*
  63  * DMA channel identifiers (A and B)
  64  */
  65 #define SSCAPE_DMA_A            0
  66 #define SSCAPE_DMA_B            1
  67 
  68 #define PORT(name)      (devc->base+name)
  69 
  70 /*
  71  * Host commands recognized by the OBP microcode
  72  */
  73 #define CMD_GEN_HOST_ACK        0x80
  74 #define CMD_GEN_MPU_ACK         0x81
  75 #define CMD_GET_BOARD_TYPE      0x82
  76 #define CMD_SET_CONTROL         0x88
  77 #define CMD_GET_CONTROL         0x89
  78 #define         CTL_MASTER_VOL          0
  79 #define         CTL_MIC_MODE            2
  80 #define         CTL_SYNTH_VOL           4
  81 #define         CTL_WAVE_VOL            7
  82 #define CMD_SET_MT32            0x96
  83 #define CMD_GET_MT32            0x97
  84 #define CMD_SET_EXTMIDI         0x9b
  85 #define CMD_GET_EXTMIDI         0x9c
  86 
  87 #define CMD_ACK                 0x80
  88 
  89 typedef struct sscape_info
  90   {
  91     int             base, irq, dma;
  92     int             ok;         /* Properly detected */
  93     int             failed;
  94     int             dma_allocated;
  95     int             my_audiodev;
  96     int             opened;
  97     sound_os_info  *osp;
  98   }
  99 
 100 sscape_info;
 101 static struct sscape_info dev_info =
 102 {0};
 103 static struct sscape_info *devc = &dev_info;
 104 
 105 static struct wait_queue *sscape_sleeper = NULL;
 106 static volatile struct snd_wait sscape_sleep_flag =
 107 {0};
 108 
 109 /* Some older cards have assigned interrupt bits differently than new ones */
 110 static char     valid_interrupts_old[] =
 111 {9, 7, 5, 15};
 112 
 113 static char     valid_interrupts_new[] =
 114 {9, 5, 7, 10};
 115 
 116 static char    *valid_interrupts = valid_interrupts_new;
 117 
 118 #ifdef REVEAL_SPEA
 119 static char     old_hardware = 1;
 120 
 121 #else
 122 static char     old_hardware = 0;
 123 
 124 #endif
 125 
 126 static unsigned char
 127 sscape_read (struct sscape_info *devc, int reg)
     /* [previous][next][first][last][top][bottom][index][help] */
 128 {
 129   unsigned long   flags;
 130   unsigned char   val;
 131 
 132   save_flags (flags);
 133   cli ();
 134   outb (reg, PORT (ODIE_ADDR));
 135   val = inb (PORT (ODIE_DATA));
 136   restore_flags (flags);
 137   return val;
 138 }
 139 
 140 static void
 141 sscape_write (struct sscape_info *devc, int reg, int data)
     /* [previous][next][first][last][top][bottom][index][help] */
 142 {
 143   unsigned long   flags;
 144 
 145   save_flags (flags);
 146   cli ();
 147   outb (reg, PORT (ODIE_ADDR));
 148   outb (data, PORT (ODIE_DATA));
 149   restore_flags (flags);
 150 }
 151 
 152 static void
 153 host_open (struct sscape_info *devc)
     /* [previous][next][first][last][top][bottom][index][help] */
 154 {
 155   outb (0x00, PORT (HOST_CTRL));        /* Put the board to the host mode */
 156 }
 157 
 158 static void
 159 host_close (struct sscape_info *devc)
     /* [previous][next][first][last][top][bottom][index][help] */
 160 {
 161   outb (0x03, PORT (HOST_CTRL));        /* Put the board to the MIDI mode */
 162 }
 163 
 164 static int
 165 host_write (struct sscape_info *devc, unsigned char *data, int count)
     /* [previous][next][first][last][top][bottom][index][help] */
 166 {
 167   unsigned long   flags;
 168   int             i, timeout_val;
 169 
 170   save_flags (flags);
 171   cli ();
 172 
 173   /*
 174      * Send the command and data bytes
 175    */
 176 
 177   for (i = 0; i < count; i++)
 178     {
 179       for (timeout_val = 10000; timeout_val > 0; timeout_val--)
 180         if (inb (PORT (HOST_CTRL)) & TX_READY)
 181           break;
 182 
 183       if (timeout_val <= 0)
 184         {
 185           restore_flags (flags);
 186           return 0;
 187         }
 188 
 189       outb (data[i], PORT (HOST_DATA));
 190     }
 191 
 192 
 193   restore_flags (flags);
 194 
 195   return 1;
 196 }
 197 
 198 static int
 199 host_read (struct sscape_info *devc)
     /* [previous][next][first][last][top][bottom][index][help] */
 200 {
 201   unsigned long   flags;
 202   int             timeout_val;
 203   unsigned char   data;
 204 
 205   save_flags (flags);
 206   cli ();
 207 
 208   /*
 209      * Read a byte
 210    */
 211 
 212   for (timeout_val = 10000; timeout_val > 0; timeout_val--)
 213     if (inb (PORT (HOST_CTRL)) & RX_READY)
 214       break;
 215 
 216   if (timeout_val <= 0)
 217     {
 218       restore_flags (flags);
 219       return -1;
 220     }
 221 
 222   data = inb (PORT (HOST_DATA));
 223 
 224   restore_flags (flags);
 225 
 226   return data;
 227 }
 228 
 229 static int
 230 host_command1 (struct sscape_info *devc, int cmd)
     /* [previous][next][first][last][top][bottom][index][help] */
 231 {
 232   unsigned char   buf[10];
 233 
 234   buf[0] = (unsigned char) (cmd & 0xff);
 235 
 236   return host_write (devc, buf, 1);
 237 }
 238 
 239 static int
 240 host_command2 (struct sscape_info *devc, int cmd, int parm1)
     /* [previous][next][first][last][top][bottom][index][help] */
 241 {
 242   unsigned char   buf[10];
 243 
 244   buf[0] = (unsigned char) (cmd & 0xff);
 245   buf[1] = (unsigned char) (parm1 & 0xff);
 246 
 247   return host_write (devc, buf, 2);
 248 }
 249 
 250 static int
 251 host_command3 (struct sscape_info *devc, int cmd, int parm1, int parm2)
     /* [previous][next][first][last][top][bottom][index][help] */
 252 {
 253   unsigned char   buf[10];
 254 
 255   buf[0] = (unsigned char) (cmd & 0xff);
 256   buf[1] = (unsigned char) (parm1 & 0xff);
 257   buf[2] = (unsigned char) (parm2 & 0xff);
 258 
 259   return host_write (devc, buf, 3);
 260 }
 261 
 262 static void
 263 set_mt32 (struct sscape_info *devc, int value)
     /* [previous][next][first][last][top][bottom][index][help] */
 264 {
 265   host_open (devc);
 266   host_command2 (devc, CMD_SET_MT32,
 267                  value ? 1 : 0);
 268   if (host_read (devc) != CMD_ACK)
 269     {
 270       printk ("SNDSCAPE: Setting MT32 mode failed\n");
 271     }
 272   host_close (devc);
 273 }
 274 
 275 static void
 276 set_control (struct sscape_info *devc, int ctrl, int value)
     /* [previous][next][first][last][top][bottom][index][help] */
 277 {
 278   host_open (devc);
 279   host_command3 (devc, CMD_SET_CONTROL, ctrl, value);
 280   if (host_read (devc) != CMD_ACK)
 281     {
 282       printk ("SNDSCAPE: Setting control (%d) failed\n", ctrl);
 283     }
 284   host_close (devc);
 285 }
 286 
 287 static int
 288 get_board_type (struct sscape_info *devc)
     /* [previous][next][first][last][top][bottom][index][help] */
 289 {
 290   int             tmp;
 291 
 292   host_open (devc);
 293   if (!host_command1 (devc, CMD_GET_BOARD_TYPE))
 294     tmp = -1;
 295   else
 296     tmp = host_read (devc);
 297   host_close (devc);
 298   return tmp;
 299 }
 300 
 301 void
 302 sscapeintr (int irq, struct pt_regs *dummy)
     /* [previous][next][first][last][top][bottom][index][help] */
 303 {
 304   unsigned char   bits, tmp;
 305   static int      debug = 0;
 306 
 307   printk ("sscapeintr(0x%02x)\n", (bits = sscape_read (devc, GA_INTSTAT_REG)));
 308   if ((sscape_sleep_flag.mode & WK_SLEEP))
 309     {
 310       {
 311         sscape_sleep_flag.mode = WK_WAKEUP;
 312         wake_up (&sscape_sleeper);
 313       };
 314     }
 315 
 316   if (bits & 0x02)              /* Host interface interrupt */
 317     {
 318       printk ("SSCAPE: Host interrupt, data=%02x\n", host_read (devc));
 319     }
 320 
 321 #if (!defined(EXCLUDE_MPU401) || !defined(EXCLUDE_MPU_EMU)) && !defined(EXCLUDE_MIDI)
 322   if (bits & 0x01)
 323     {
 324       mpuintr (irq, NULL);
 325       if (debug++ > 10)         /* Temporary debugging hack */
 326         {
 327           sscape_write (devc, GA_INTENA_REG, 0x00);     /* Disable all interrupts */
 328         }
 329     }
 330 #endif
 331 
 332   /*
 333      * Acknowledge interrupts (toggle the interrupt bits)
 334    */
 335 
 336   tmp = sscape_read (devc, GA_INTENA_REG);
 337   sscape_write (devc, GA_INTENA_REG, (~bits & 0x0e) | (tmp & 0xf1));
 338 
 339 }
 340 
 341 static void
 342 sscape_enable_intr (struct sscape_info *devc, unsigned intr_bits)
     /* [previous][next][first][last][top][bottom][index][help] */
 343 {
 344   unsigned char   temp, orig;
 345 
 346   temp = orig = sscape_read (devc, GA_INTENA_REG);
 347   temp |= intr_bits;
 348   temp |= 0x80;                 /* Master IRQ enable */
 349 
 350   if (temp == orig)
 351     return;                     /* No change */
 352 
 353   sscape_write (devc, GA_INTENA_REG, temp);
 354 }
 355 
 356 static void
 357 sscape_disable_intr (struct sscape_info *devc, unsigned intr_bits)
     /* [previous][next][first][last][top][bottom][index][help] */
 358 {
 359   unsigned char   temp, orig;
 360 
 361   temp = orig = sscape_read (devc, GA_INTENA_REG);
 362   temp &= ~intr_bits;
 363   if ((temp & ~0x80) == 0x00)
 364     temp = 0x00;                /* Master IRQ disable */
 365   if (temp == orig)
 366     return;                     /* No change */
 367 
 368   sscape_write (devc, GA_INTENA_REG, temp);
 369 }
 370 
 371 static void
 372 do_dma (struct sscape_info *devc, int dma_chan, unsigned long buf, int blk_size, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 373 {
 374   unsigned char   temp;
 375 
 376   if (dma_chan != SSCAPE_DMA_A)
 377     {
 378       printk ("SSCAPE: Tried to use DMA channel  != A. Why?\n");
 379       return;
 380     }
 381 
 382   DMAbuf_start_dma (devc->my_audiodev,
 383                     buf,
 384                     blk_size, mode);
 385 
 386   temp = devc->dma << 4;        /* Setup DMA channel select bits */
 387   if (devc->dma <= 3)
 388     temp |= 0x80;               /* 8 bit DMA channel */
 389 
 390   temp |= 1;                    /* Trigger DMA */
 391   sscape_write (devc, GA_DMAA_REG, temp);
 392   temp &= 0xfe;                 /* Clear DMA trigger */
 393   sscape_write (devc, GA_DMAA_REG, temp);
 394 }
 395 
 396 static int
 397 verify_mpu (struct sscape_info *devc)
     /* [previous][next][first][last][top][bottom][index][help] */
 398 {
 399   /*
 400      * The SoundScape board could be in three modes (MPU, 8250 and host).
 401      * If the card is not in the MPU mode, enabling the MPU driver will
 402      * cause infinite loop (the driver believes that there is always some
 403      * received data in the buffer.
 404      *
 405      * Detect this by looking if there are more than 10 received MIDI bytes
 406      * (0x00) in the buffer.
 407    */
 408 
 409   int             i;
 410 
 411   for (i = 0; i < 10; i++)
 412     {
 413       if (inb (devc->base + HOST_CTRL) & 0x80)
 414         return 1;
 415 
 416       if (inb (devc->base) != 0x00)
 417         return 1;
 418     }
 419 
 420   printk ("SoundScape: The device is not in the MPU-401 mode\n");
 421   return 0;
 422 }
 423 
 424 static int
 425 sscape_coproc_open (void *dev_info, int sub_device)
     /* [previous][next][first][last][top][bottom][index][help] */
 426 {
 427   if (sub_device == COPR_MIDI)
 428     {
 429       set_mt32 (devc, 0);
 430       if (!verify_mpu (devc))
 431         return -EIO;
 432     }
 433 
 434   return 0;
 435 }
 436 
 437 static void
 438 sscape_coproc_close (void *dev_info, int sub_device)
     /* [previous][next][first][last][top][bottom][index][help] */
 439 {
 440   struct sscape_info *devc = dev_info;
 441   unsigned long   flags;
 442 
 443   save_flags (flags);
 444   cli ();
 445   if (devc->dma_allocated)
 446     {
 447       sscape_write (devc, GA_DMAA_REG, 0x20);   /* DMA channel disabled */
 448 #ifndef EXCLUDE_NATIVE_PCM
 449 #endif
 450       devc->dma_allocated = 0;
 451     }
 452   {
 453     sscape_sleep_flag.aborting = 0;
 454     sscape_sleep_flag.mode = WK_NONE;
 455   };
 456   restore_flags (flags);
 457 
 458   return;
 459 }
 460 
 461 static void
 462 sscape_coproc_reset (void *dev_info)
     /* [previous][next][first][last][top][bottom][index][help] */
 463 {
 464 }
 465 
 466 static int
 467 sscape_download_boot (struct sscape_info *devc, unsigned char *block, int size, int flag)
     /* [previous][next][first][last][top][bottom][index][help] */
 468 {
 469   unsigned long   flags;
 470   unsigned char   temp;
 471   int             done, timeout_val;
 472 
 473   if (flag & CPF_FIRST)
 474     {
 475       /*
 476          * First block. Have to allocate DMA and to reset the board
 477          * before continuing.
 478        */
 479 
 480       save_flags (flags);
 481       cli ();
 482       if (devc->dma_allocated == 0)
 483         {
 484 #ifndef EXCLUDE_NATIVE_PCM
 485 #endif
 486 
 487           devc->dma_allocated = 1;
 488         }
 489       restore_flags (flags);
 490 
 491       sscape_write (devc, GA_HMCTL_REG,
 492                     (temp = sscape_read (devc, GA_HMCTL_REG)) & 0x3f);  /*Reset */
 493 
 494       for (timeout_val = 10000; timeout_val > 0; timeout_val--)
 495         sscape_read (devc, GA_HMCTL_REG);       /* Delay */
 496 
 497       /* Take board out of reset */
 498       sscape_write (devc, GA_HMCTL_REG,
 499                     (temp = sscape_read (devc, GA_HMCTL_REG)) | 0x80);
 500     }
 501 
 502   /*
 503      * Transfer one code block using DMA
 504    */
 505   memcpy (audio_devs[devc->my_audiodev]->dmap_out->raw_buf, block, size);
 506 
 507   save_flags (flags);
 508   cli ();
 509 /******** INTERRUPTS DISABLED NOW ********/
 510   do_dma (devc, SSCAPE_DMA_A,
 511           audio_devs[devc->my_audiodev]->dmap_out->raw_buf_phys,
 512           size, DMA_MODE_WRITE);
 513 
 514   /*
 515    * Wait until transfer completes.
 516    */
 517   {
 518     sscape_sleep_flag.aborting = 0;
 519     sscape_sleep_flag.mode = WK_NONE;
 520   };
 521   done = 0;
 522   timeout_val = 100;
 523   while (!done && timeout_val-- > 0)
 524     {
 525       int             resid;
 526 
 527 
 528       {
 529         unsigned long   tl;
 530 
 531         if (1)
 532           tl = current->timeout = jiffies + (1);
 533         else
 534           tl = 0xffffffff;
 535         sscape_sleep_flag.mode = WK_SLEEP;
 536         interruptible_sleep_on (&sscape_sleeper);
 537         if (!(sscape_sleep_flag.mode & WK_WAKEUP))
 538           {
 539             if (current->signal & ~current->blocked)
 540               sscape_sleep_flag.aborting = 1;
 541             else if (jiffies >= tl)
 542               sscape_sleep_flag.mode |= WK_TIMEOUT;
 543           }
 544         sscape_sleep_flag.mode &= ~WK_SLEEP;
 545       };
 546       clear_dma_ff (devc->dma);
 547       if ((resid = get_dma_residue (devc->dma)) == 0)
 548         done = 1;
 549     }
 550 
 551   restore_flags (flags);
 552   if (!done)
 553     return 0;
 554 
 555   if (flag & CPF_LAST)
 556     {
 557       /*
 558          * Take the board out of reset
 559        */
 560       outb (0x00, PORT (HOST_CTRL));
 561       outb (0x00, PORT (MIDI_CTRL));
 562 
 563       temp = sscape_read (devc, GA_HMCTL_REG);
 564       temp |= 0x40;
 565       sscape_write (devc, GA_HMCTL_REG, temp);  /* Kickstart the board */
 566 
 567       /*
 568          * Wait until the ODB wakes up
 569        */
 570 
 571       save_flags (flags);
 572       cli ();
 573       done = 0;
 574       timeout_val = 5 * HZ;
 575       while (!done && timeout_val-- > 0)
 576         {
 577 
 578           {
 579             unsigned long   tl;
 580 
 581             if (1)
 582               tl = current->timeout = jiffies + (1);
 583             else
 584               tl = 0xffffffff;
 585             sscape_sleep_flag.mode = WK_SLEEP;
 586             interruptible_sleep_on (&sscape_sleeper);
 587             if (!(sscape_sleep_flag.mode & WK_WAKEUP))
 588               {
 589                 if (current->signal & ~current->blocked)
 590                   sscape_sleep_flag.aborting = 1;
 591                 else if (jiffies >= tl)
 592                   sscape_sleep_flag.mode |= WK_TIMEOUT;
 593               }
 594             sscape_sleep_flag.mode &= ~WK_SLEEP;
 595           };
 596           if (inb (PORT (HOST_DATA)) == 0xff)   /* OBP startup acknowledge */
 597             done = 1;
 598         }
 599       restore_flags (flags);
 600       if (!done)
 601         {
 602           printk ("SoundScape: The OBP didn't respond after code download\n");
 603           return 0;
 604         }
 605 
 606       save_flags (flags);
 607       cli ();
 608       done = 0;
 609       timeout_val = 5 * HZ;
 610       while (!done && timeout_val-- > 0)
 611         {
 612 
 613           {
 614             unsigned long   tl;
 615 
 616             if (1)
 617               tl = current->timeout = jiffies + (1);
 618             else
 619               tl = 0xffffffff;
 620             sscape_sleep_flag.mode = WK_SLEEP;
 621             interruptible_sleep_on (&sscape_sleeper);
 622             if (!(sscape_sleep_flag.mode & WK_WAKEUP))
 623               {
 624                 if (current->signal & ~current->blocked)
 625                   sscape_sleep_flag.aborting = 1;
 626                 else if (jiffies >= tl)
 627                   sscape_sleep_flag.mode |= WK_TIMEOUT;
 628               }
 629             sscape_sleep_flag.mode &= ~WK_SLEEP;
 630           };
 631           if (inb (PORT (HOST_DATA)) == 0xfe)   /* Host startup acknowledge */
 632             done = 1;
 633         }
 634       restore_flags (flags);
 635       if (!done)
 636         {
 637           printk ("SoundScape: OBP Initialization failed.\n");
 638           return 0;
 639         }
 640 
 641       printk ("SoundScape board of type %d initialized OK\n",
 642               get_board_type (devc));
 643 
 644       set_control (devc, CTL_MASTER_VOL, 100);
 645       set_control (devc, CTL_SYNTH_VOL, 100);
 646 
 647 #ifdef SSCAPE_DEBUG3
 648       /*
 649          * Temporary debugging aid. Print contents of the registers after
 650          * downloading the code.
 651        */
 652       {
 653         int             i;
 654 
 655         for (i = 0; i < 13; i++)
 656           printk ("I%d = %02x (new value)\n", i, sscape_read (devc, i));
 657       }
 658 #endif
 659 
 660     }
 661 
 662   return 1;
 663 }
 664 
 665 static int
 666 download_boot_block (void *dev_info, copr_buffer * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 667 {
 668   if (buf->len <= 0 || buf->len > sizeof (buf->data))
 669     return -EINVAL;
 670 
 671   if (!sscape_download_boot (devc, buf->data, buf->len, buf->flags))
 672     {
 673       printk ("SSCAPE: Unable to load microcode block to the OBP.\n");
 674       return -EIO;
 675     }
 676 
 677   return 0;
 678 }
 679 
 680 static int
 681 sscape_coproc_ioctl (void *dev_info, unsigned int cmd, ioctl_arg arg, int local)
     /* [previous][next][first][last][top][bottom][index][help] */
 682 {
 683 
 684   switch (cmd)
 685     {
 686     case SNDCTL_COPR_RESET:
 687       sscape_coproc_reset (dev_info);
 688       return 0;
 689       break;
 690 
 691     case SNDCTL_COPR_LOAD:
 692       {
 693         copr_buffer    *buf;
 694         int             err;
 695 
 696         buf = (copr_buffer *) (
 697                                 {
 698                                 caddr_t x;
 699                              x = kmalloc (sizeof (copr_buffer), GFP_KERNEL);
 700                                 x;
 701                                 }
 702         );
 703         if (buf == NULL)
 704           return -ENOSPC;
 705         memcpy_fromfs (((char *) buf), &(((char *) arg)[0]), (sizeof (*buf)));
 706         err = download_boot_block (dev_info, buf);
 707         kfree (buf);
 708         return err;
 709       }
 710       break;
 711 
 712     default:
 713       return -EINVAL;
 714     }
 715 
 716 }
 717 
 718 static coproc_operations sscape_coproc_operations =
 719 {
 720   "SoundScape M68K",
 721   sscape_coproc_open,
 722   sscape_coproc_close,
 723   sscape_coproc_ioctl,
 724   sscape_coproc_reset,
 725   &dev_info
 726 };
 727 
 728 static int
 729 sscape_audio_open (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 730 {
 731   unsigned long   flags;
 732   sscape_info    *devc = (sscape_info *) audio_devs[dev]->devc;
 733 
 734   save_flags (flags);
 735   cli ();
 736   if (devc->opened)
 737     {
 738       restore_flags (flags);
 739       return -EBUSY;
 740     }
 741   devc->opened = 1;
 742   restore_flags (flags);
 743 #ifdef SSCAPE_DEBUG4
 744   /*
 745      * Temporary debugging aid. Print contents of the registers
 746      * when the device is opened.
 747    */
 748   {
 749     int             i;
 750 
 751     for (i = 0; i < 13; i++)
 752       printk ("I%d = %02x\n", i, sscape_read (devc, i));
 753   }
 754 #endif
 755 
 756   return 0;
 757 }
 758 
 759 static void
 760 sscape_audio_close (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 761 {
 762   unsigned long   flags;
 763   sscape_info    *devc = (sscape_info *) audio_devs[dev]->devc;
 764 
 765   DEB (printk ("sscape_audio_close(void)\n"));
 766 
 767   save_flags (flags);
 768   cli ();
 769 
 770   devc->opened = 0;
 771 
 772   restore_flags (flags);
 773 }
 774 
 775 static int
 776 set_speed (sscape_info * devc, int arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 777 {
 778   return 8000;
 779 }
 780 
 781 static int
 782 set_channels (sscape_info * devc, int arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 783 {
 784   return 1;
 785 }
 786 
 787 static int
 788 set_format (sscape_info * devc, int arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 789 {
 790   return AFMT_U8;
 791 }
 792 
 793 static int
 794 sscape_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg, int local)
     /* [previous][next][first][last][top][bottom][index][help] */
 795 {
 796   sscape_info    *devc = (sscape_info *) audio_devs[dev]->devc;
 797 
 798   switch (cmd)
 799     {
 800     case SOUND_PCM_WRITE_RATE:
 801       if (local)
 802         return set_speed (devc, (int) arg);
 803       return snd_ioctl_return ((int *) arg, set_speed (devc, get_fs_long ((long *) arg)));
 804 
 805     case SOUND_PCM_READ_RATE:
 806       if (local)
 807         return 8000;
 808       return snd_ioctl_return ((int *) arg, 8000);
 809 
 810     case SNDCTL_DSP_STEREO:
 811       if (local)
 812         return set_channels (devc, (int) arg + 1) - 1;
 813       return snd_ioctl_return ((int *) arg, set_channels (devc, get_fs_long ((long *) arg) + 1) - 1);
 814 
 815     case SOUND_PCM_WRITE_CHANNELS:
 816       if (local)
 817         return set_channels (devc, (int) arg);
 818       return snd_ioctl_return ((int *) arg, set_channels (devc, get_fs_long ((long *) arg)));
 819 
 820     case SOUND_PCM_READ_CHANNELS:
 821       if (local)
 822         return 1;
 823       return snd_ioctl_return ((int *) arg, 1);
 824 
 825     case SNDCTL_DSP_SAMPLESIZE:
 826       if (local)
 827         return set_format (devc, (int) arg);
 828       return snd_ioctl_return ((int *) arg, set_format (devc, get_fs_long ((long *) arg)));
 829 
 830     case SOUND_PCM_READ_BITS:
 831       if (local)
 832         return 8;
 833       return snd_ioctl_return ((int *) arg, 8);
 834 
 835     default:;
 836     }
 837   return -EINVAL;
 838 }
 839 
 840 static void
 841 sscape_audio_output_block (int dev, unsigned long buf, int count, int intrflag, int dma_restart)
     /* [previous][next][first][last][top][bottom][index][help] */
 842 {
 843 }
 844 
 845 static void
 846 sscape_audio_start_input (int dev, unsigned long buf, int count, int intrflag, int dma_restart)
     /* [previous][next][first][last][top][bottom][index][help] */
 847 {
 848 }
 849 
 850 static int
 851 sscape_audio_prepare_for_input (int dev, int bsize, int bcount)
     /* [previous][next][first][last][top][bottom][index][help] */
 852 {
 853   return 0;
 854 }
 855 
 856 static int
 857 sscape_audio_prepare_for_output (int dev, int bsize, int bcount)
     /* [previous][next][first][last][top][bottom][index][help] */
 858 {
 859   return 0;
 860 }
 861 
 862 static void
 863 sscape_audio_halt (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 864 {
 865 }
 866 
 867 static void
 868 sscape_audio_reset (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 869 {
 870   sscape_audio_halt (dev);
 871 }
 872 
 873 static struct audio_operations sscape_audio_operations =
 874 {
 875   "Not functional",
 876   0,
 877   AFMT_U8 | AFMT_S16_LE,
 878   NULL,
 879   sscape_audio_open,
 880   sscape_audio_close,
 881   sscape_audio_output_block,
 882   sscape_audio_start_input,
 883   sscape_audio_ioctl,
 884   sscape_audio_prepare_for_input,
 885   sscape_audio_prepare_for_output,
 886   sscape_audio_reset,
 887   sscape_audio_halt,
 888   NULL,
 889   NULL
 890 };
 891 
 892 static int      sscape_detected = 0;
 893 
 894 long
 895 attach_sscape (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 896 {
 897   int             my_dev;
 898 
 899 #ifndef SSCAPE_REGS
 900   /*
 901      * Config register values for Spea/V7 Media FX and Ensoniq S-2000.
 902      * These values are card
 903      * dependent. If you have another SoundScape based card, you have to
 904      * find the correct values. Do the following:
 905      *  - Compile this driver with SSCAPE_DEBUG1 defined.
 906      *  - Shut down and power off your machine.
 907      *  - Boot with DOS so that the SSINIT.EXE program is run.
 908      *  - Warm boot to {Linux|SYSV|BSD} and write down the lines displayed
 909      *    when detecting the SoundScape.
 910      *  - Modify the following list to use the values printed during boot.
 911      *    Undefine the SSCAPE_DEBUG1
 912    */
 913 #define SSCAPE_REGS { \
 914 /* I0 */        0x00, \
 915                 0xf0, /* Note! Ignored. Set always to 0xf0 */ \
 916                 0x20, /* Note! Ignored. Set always to 0x20 */ \
 917                 0x20, /* Note! Ignored. Set always to 0x20 */ \
 918                 0xf5, /* Ignored */ \
 919                 0x10, \
 920                 0x00, \
 921                 0x2e, /* I7 MEM config A. Likely to vary between models */ \
 922                 0x00, /* I8 MEM config B. Likely to vary between models */ \
 923 /* I9 */        0x40 /* Ignored */ \
 924         }
 925 #endif
 926 
 927   unsigned long   flags;
 928   static unsigned char regs[10] = SSCAPE_REGS;
 929 
 930   int             i, irq_bits = 0xff;
 931 
 932   if (sscape_detected != hw_config->io_base)
 933     return mem_start;
 934 
 935   if (old_hardware)
 936     {
 937       valid_interrupts = valid_interrupts_old;
 938       printk (" <Ensoniq Soundscape (old)>");
 939     }
 940   else
 941     printk (" <Ensoniq Soundscape>");
 942 
 943   for (i = 0; i < sizeof (valid_interrupts); i++)
 944     if (hw_config->irq == valid_interrupts[i])
 945       {
 946         irq_bits = i;
 947         break;
 948       }
 949 
 950   if (hw_config->irq > 15 || (regs[4] = irq_bits == 0xff))
 951     {
 952       printk ("Invalid IRQ%d\n", hw_config->irq);
 953       return mem_start;
 954     }
 955 
 956   save_flags (flags);
 957   cli ();
 958 
 959   for (i = 1; i < 10; i++)
 960     switch (i)
 961       {
 962       case 1:                   /* Host interrupt enable */
 963         sscape_write (devc, i, 0xf0);   /* All interrupts enabled */
 964         break;
 965 
 966       case 2:                   /* DMA A status/trigger register */
 967       case 3:                   /* DMA B status/trigger register */
 968         sscape_write (devc, i, 0x20);   /* DMA channel disabled */
 969         break;
 970 
 971       case 4:                   /* Host interrupt config reg */
 972         sscape_write (devc, i, 0xf0 | (irq_bits << 2) | irq_bits);
 973         break;
 974 
 975       case 5:                   /* Don't destroy CD-ROM DMA config bits (0xc0) */
 976         sscape_write (devc, i, (regs[i] & 0x3f) |
 977                       (sscape_read (devc, i) & 0xc0));
 978         break;
 979 
 980       case 6:                   /* CD-ROM config. Don't touch. */
 981         break;
 982 
 983       case 9:                   /* Master control reg. Don't modify CR-ROM bits. Disable SB emul */
 984         sscape_write (devc, i,
 985                       (sscape_read (devc, i) & 0xf0) | 0x00);
 986         break;
 987 
 988       default:
 989         sscape_write (devc, i, regs[i]);
 990       }
 991 
 992   restore_flags (flags);
 993 
 994 #ifdef SSCAPE_DEBUG2
 995   /*
 996      * Temporary debugging aid. Print contents of the registers after
 997      * changing them.
 998    */
 999   {
1000     int             i;
1001 
1002     for (i = 0; i < 13; i++)
1003       printk ("I%d = %02x (new value)\n", i, sscape_read (devc, i));
1004   }
1005 #endif
1006 
1007 #if !defined(EXCLUDE_MIDI) && !defined(EXCLUDE_MPU_EMU)
1008   if (probe_mpu401 (hw_config))
1009     hw_config->always_detect = 1;
1010   {
1011     int             prev_devs;
1012 
1013     prev_devs = num_midis;
1014     mem_start = attach_mpu401 (mem_start, hw_config);
1015 
1016     if (num_midis == (prev_devs + 1))   /* The MPU driver installed itself */
1017       midi_devs[prev_devs]->coproc = &sscape_coproc_operations;
1018   }
1019 #endif
1020 
1021 #ifndef EXCLUDE_NATIVE_PCM
1022   /* Not supported yet */
1023 
1024 #ifndef EXCLUDE_AUDIO
1025   if (num_audiodevs < MAX_AUDIO_DEV)
1026     {
1027       audio_devs[my_dev = num_audiodevs++] = &sscape_audio_operations;
1028       audio_devs[my_dev]->dmachan1 = hw_config->dma;
1029       audio_devs[my_dev]->buffsize = DSP_BUFFSIZE;
1030       audio_devs[my_dev]->devc = devc;
1031       devc->my_audiodev = my_dev;
1032       devc->opened = 0;
1033       audio_devs[my_dev]->coproc = &sscape_coproc_operations;
1034       if (snd_set_irq_handler (hw_config->irq, sscapeintr, "SoundScape", devc->osp) < 0)
1035         printk ("Error: Can't allocate IRQ for SoundScape\n");
1036 
1037       sscape_write (devc, GA_INTENA_REG, 0x80);         /* Master IRQ enable */
1038     }
1039   else
1040     printk ("SoundScape: More than enough audio devices detected\n");
1041 #endif
1042 #endif
1043   devc->ok = 1;
1044   devc->failed = 0;
1045   return mem_start;
1046 }
1047 
1048 int
1049 probe_sscape (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
1050 {
1051   unsigned char   save;
1052 
1053   devc->failed = 1;
1054   devc->base = hw_config->io_base;
1055   devc->irq = hw_config->irq;
1056   devc->dma = hw_config->dma;
1057   devc->osp = hw_config->osp;
1058 
1059   if (sscape_detected != 0 && sscape_detected != hw_config->io_base)
1060     return 0;
1061 
1062   /*
1063      * First check that the address register of "ODIE" is
1064      * there and that it has exactly 4 writeable bits.
1065      * First 4 bits
1066    */
1067   if ((save = inb (PORT (ODIE_ADDR))) & 0xf0)
1068     return 0;
1069 
1070   outb (0x00, PORT (ODIE_ADDR));
1071   if (inb (PORT (ODIE_ADDR)) != 0x00)
1072     return 0;
1073 
1074   outb (0xff, PORT (ODIE_ADDR));
1075   if (inb (PORT (ODIE_ADDR)) != 0x0f)
1076     return 0;
1077 
1078   outb (save, PORT (ODIE_ADDR));
1079 
1080   /*
1081      * Now verify that some indirect registers return zero on some bits.
1082      * This may break the driver with some future revisions of "ODIE" but...
1083    */
1084 
1085   if (sscape_read (devc, 0) & 0x0c)
1086     return 0;
1087 
1088   if (sscape_read (devc, 1) & 0x0f)
1089     return 0;
1090 
1091   if (sscape_read (devc, 5) & 0x0f)
1092     return 0;
1093 
1094 #ifdef SSCAPE_DEBUG1
1095   /*
1096      * Temporary debugging aid. Print contents of the registers before
1097      * changing them.
1098    */
1099   {
1100     int             i;
1101 
1102     for (i = 0; i < 13; i++)
1103       printk ("I%d = %02x (old value)\n", i, sscape_read (devc, i));
1104   }
1105 #endif
1106 
1107   if (old_hardware)             /* Check that it's really an old Spea/Reveal card. */
1108     {
1109       int             status = 0;
1110       unsigned char   tmp;
1111       int             cc;
1112 
1113       if (!((tmp = sscape_read (devc, GA_HMCTL_REG)) & 0xc0))
1114         {
1115           sscape_write (devc, GA_HMCTL_REG, tmp | 0x80);
1116           for (cc = 0; cc < 200000; ++cc)
1117             inb (devc->base + ODIE_ADDR);
1118         }
1119       else
1120         old_hardware = 0;
1121     }
1122 
1123   if (sound_alloc_dma (hw_config->dma, "soundscape"))
1124     {
1125       printk ("sscape.c: Can't allocate DMA channel\n");
1126       return 0;
1127     }
1128 
1129   sscape_detected = hw_config->io_base;
1130 
1131   return 1;
1132 }
1133 
1134 int
1135 probe_ss_ms_sound (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
1136 {
1137   int             i, irq_bits = 0xff;
1138 
1139   if (devc->failed)
1140     return 0;
1141 
1142   if (devc->ok == 0)
1143     {
1144       printk ("SoundScape: Invalid initialization order.\n");
1145       return 0;
1146     }
1147 
1148   for (i = 0; i < sizeof (valid_interrupts); i++)
1149     if (hw_config->irq == valid_interrupts[i])
1150       {
1151         irq_bits = i;
1152         break;
1153       }
1154   if (hw_config->irq > 15 || irq_bits == 0xff)
1155     {
1156       printk ("SoundScape: Invalid MSS IRQ%d\n", hw_config->irq);
1157       return 0;
1158     }
1159 
1160   return ad1848_detect (hw_config->io_base, NULL, hw_config->osp);
1161 }
1162 
1163 long
1164 attach_ss_ms_sound (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
1165 {
1166   /*
1167      * This routine configures the SoundScape card for use with the
1168      * Win Sound System driver. The AD1848 codec interface uses the CD-ROM
1169      * config registers of the "ODIE".
1170    */
1171 
1172   int             i, irq_bits = 0xff;
1173 
1174 #ifdef EXCLUDE_NATIVE_PCM
1175   int             prev_devs = num_audiodevs;
1176 
1177 #endif
1178 
1179   /*
1180      * Setup the DMA polarity.
1181    */
1182   sscape_write (devc, GA_DMACFG_REG, 0x50);
1183 
1184   /*
1185      * Take the gate-arry off of the DMA channel.
1186    */
1187   sscape_write (devc, GA_DMAB_REG, 0x20);
1188 
1189   /*
1190      * Init the AD1848 (CD-ROM) config reg.
1191    */
1192 
1193   for (i = 0; i < sizeof (valid_interrupts); i++)
1194     if (hw_config->irq == valid_interrupts[i])
1195       {
1196         irq_bits = i;
1197         break;
1198       }
1199 
1200   sscape_write (devc, GA_CDCFG_REG, 0x89 | (hw_config->dma << 4) |
1201                 (irq_bits << 1));
1202 
1203   if (hw_config->irq == devc->irq)
1204     printk ("SoundScape: Warning! The WSS mode can't share IRQ with MIDI\n");
1205 
1206   ad1848_init ("SoundScape", hw_config->io_base,
1207                hw_config->irq,
1208                hw_config->dma,
1209                hw_config->dma,
1210                0,
1211                devc->osp);
1212 
1213 #ifdef EXCLUDE_NATIVE_PCM
1214   if (num_audiodevs == (prev_devs + 1))         /* The AD1848 driver installed itself */
1215     audio_devs[prev_devs]->coproc = &sscape_coproc_operations;
1216 #endif
1217 #ifdef SSCAPE_DEBUG5
1218   /*
1219      * Temporary debugging aid. Print contents of the registers
1220      * after the AD1848 device has been initialized.
1221    */
1222   {
1223     int             i;
1224 
1225     for (i = 0; i < 13; i++)
1226       printk ("I%d = %02x\n", i, sscape_read (devc, i));
1227   }
1228 #endif
1229 
1230   return mem_start;
1231 }
1232 
1233 void
1234 unload_sscape (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
1235 {
1236   unload_mpu401 (hw_config);
1237   snd_release_irq (hw_config->irq);
1238   sound_free_dma (hw_config->dma);
1239 }
1240 
1241 void
1242 unload_ss_ms_sound (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
1243 {
1244   ad1848_unload (hw_config->io_base,
1245                  hw_config->irq,
1246                  hw_config->dma,
1247                  hw_config->dma,
1248                  0);
1249 }
1250 
1251 #endif

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