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 *) kmalloc (sizeof (copr_buffer), GFP_KERNEL);
 697         if (buf == NULL)
 698           return -ENOSPC;
 699         memcpy_fromfs ((char *) buf, &(((char *) arg)[0]), sizeof (*buf));
 700         err = download_boot_block (dev_info, buf);
 701         kfree (buf);
 702         return err;
 703       }
 704       break;
 705 
 706     default:
 707       return -EINVAL;
 708     }
 709 
 710 }
 711 
 712 static coproc_operations sscape_coproc_operations =
 713 {
 714   "SoundScape M68K",
 715   sscape_coproc_open,
 716   sscape_coproc_close,
 717   sscape_coproc_ioctl,
 718   sscape_coproc_reset,
 719   &dev_info
 720 };
 721 
 722 static int
 723 sscape_audio_open (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 724 {
 725   unsigned long   flags;
 726   sscape_info    *devc = (sscape_info *) audio_devs[dev]->devc;
 727 
 728   save_flags (flags);
 729   cli ();
 730   if (devc->opened)
 731     {
 732       restore_flags (flags);
 733       return -EBUSY;
 734     }
 735   devc->opened = 1;
 736   restore_flags (flags);
 737 #ifdef SSCAPE_DEBUG4
 738   /*
 739      * Temporary debugging aid. Print contents of the registers
 740      * when the device is opened.
 741    */
 742   {
 743     int             i;
 744 
 745     for (i = 0; i < 13; i++)
 746       printk ("I%d = %02x\n", i, sscape_read (devc, i));
 747   }
 748 #endif
 749 
 750   return 0;
 751 }
 752 
 753 static void
 754 sscape_audio_close (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 755 {
 756   unsigned long   flags;
 757   sscape_info    *devc = (sscape_info *) audio_devs[dev]->devc;
 758 
 759   DEB (printk ("sscape_audio_close(void)\n"));
 760 
 761   save_flags (flags);
 762   cli ();
 763 
 764   devc->opened = 0;
 765 
 766   restore_flags (flags);
 767 }
 768 
 769 static int
 770 set_speed (sscape_info * devc, int arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 771 {
 772   return 8000;
 773 }
 774 
 775 static int
 776 set_channels (sscape_info * devc, int arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 777 {
 778   return 1;
 779 }
 780 
 781 static int
 782 set_format (sscape_info * devc, int arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 783 {
 784   return AFMT_U8;
 785 }
 786 
 787 static int
 788 sscape_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg, int local)
     /* [previous][next][first][last][top][bottom][index][help] */
 789 {
 790   sscape_info    *devc = (sscape_info *) audio_devs[dev]->devc;
 791 
 792   switch (cmd)
 793     {
 794     case SOUND_PCM_WRITE_RATE:
 795       if (local)
 796         return set_speed (devc, (int) arg);
 797       return snd_ioctl_return ((int *) arg, set_speed (devc, get_fs_long ((long *) arg)));
 798 
 799     case SOUND_PCM_READ_RATE:
 800       if (local)
 801         return 8000;
 802       return snd_ioctl_return ((int *) arg, 8000);
 803 
 804     case SNDCTL_DSP_STEREO:
 805       if (local)
 806         return set_channels (devc, (int) arg + 1) - 1;
 807       return snd_ioctl_return ((int *) arg, set_channels (devc, get_fs_long ((long *) arg) + 1) - 1);
 808 
 809     case SOUND_PCM_WRITE_CHANNELS:
 810       if (local)
 811         return set_channels (devc, (int) arg);
 812       return snd_ioctl_return ((int *) arg, set_channels (devc, get_fs_long ((long *) arg)));
 813 
 814     case SOUND_PCM_READ_CHANNELS:
 815       if (local)
 816         return 1;
 817       return snd_ioctl_return ((int *) arg, 1);
 818 
 819     case SNDCTL_DSP_SAMPLESIZE:
 820       if (local)
 821         return set_format (devc, (int) arg);
 822       return snd_ioctl_return ((int *) arg, set_format (devc, get_fs_long ((long *) arg)));
 823 
 824     case SOUND_PCM_READ_BITS:
 825       if (local)
 826         return 8;
 827       return snd_ioctl_return ((int *) arg, 8);
 828 
 829     default:;
 830     }
 831   return -EINVAL;
 832 }
 833 
 834 static void
 835 sscape_audio_output_block (int dev, unsigned long buf, int count, int intrflag, int dma_restart)
     /* [previous][next][first][last][top][bottom][index][help] */
 836 {
 837 }
 838 
 839 static void
 840 sscape_audio_start_input (int dev, unsigned long buf, int count, int intrflag, int dma_restart)
     /* [previous][next][first][last][top][bottom][index][help] */
 841 {
 842 }
 843 
 844 static int
 845 sscape_audio_prepare_for_input (int dev, int bsize, int bcount)
     /* [previous][next][first][last][top][bottom][index][help] */
 846 {
 847   return 0;
 848 }
 849 
 850 static int
 851 sscape_audio_prepare_for_output (int dev, int bsize, int bcount)
     /* [previous][next][first][last][top][bottom][index][help] */
 852 {
 853   return 0;
 854 }
 855 
 856 static void
 857 sscape_audio_halt (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 858 {
 859 }
 860 
 861 static void
 862 sscape_audio_reset (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 863 {
 864   sscape_audio_halt (dev);
 865 }
 866 
 867 static struct audio_operations sscape_audio_operations =
 868 {
 869   "Not functional",
 870   0,
 871   AFMT_U8 | AFMT_S16_LE,
 872   NULL,
 873   sscape_audio_open,
 874   sscape_audio_close,
 875   sscape_audio_output_block,
 876   sscape_audio_start_input,
 877   sscape_audio_ioctl,
 878   sscape_audio_prepare_for_input,
 879   sscape_audio_prepare_for_output,
 880   sscape_audio_reset,
 881   sscape_audio_halt,
 882   NULL,
 883   NULL
 884 };
 885 
 886 static int      sscape_detected = 0;
 887 
 888 long
 889 attach_sscape (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 890 {
 891   int             my_dev;
 892 
 893 #ifndef SSCAPE_REGS
 894   /*
 895      * Config register values for Spea/V7 Media FX and Ensoniq S-2000.
 896      * These values are card
 897      * dependent. If you have another SoundScape based card, you have to
 898      * find the correct values. Do the following:
 899      *  - Compile this driver with SSCAPE_DEBUG1 defined.
 900      *  - Shut down and power off your machine.
 901      *  - Boot with DOS so that the SSINIT.EXE program is run.
 902      *  - Warm boot to {Linux|SYSV|BSD} and write down the lines displayed
 903      *    when detecting the SoundScape.
 904      *  - Modify the following list to use the values printed during boot.
 905      *    Undefine the SSCAPE_DEBUG1
 906    */
 907 #define SSCAPE_REGS { \
 908 /* I0 */        0x00, \
 909                 0xf0, /* Note! Ignored. Set always to 0xf0 */ \
 910                 0x20, /* Note! Ignored. Set always to 0x20 */ \
 911                 0x20, /* Note! Ignored. Set always to 0x20 */ \
 912                 0xf5, /* Ignored */ \
 913                 0x10, \
 914                 0x00, \
 915                 0x2e, /* I7 MEM config A. Likely to vary between models */ \
 916                 0x00, /* I8 MEM config B. Likely to vary between models */ \
 917 /* I9 */        0x40 /* Ignored */ \
 918         }
 919 #endif
 920 
 921   unsigned long   flags;
 922   static unsigned char regs[10] = SSCAPE_REGS;
 923 
 924   int             i, irq_bits = 0xff;
 925 
 926   if (sscape_detected != hw_config->io_base)
 927     return mem_start;
 928 
 929   if (old_hardware)
 930     {
 931       valid_interrupts = valid_interrupts_old;
 932       printk (" <Ensoniq Soundscape (old)>");
 933     }
 934   else
 935     printk (" <Ensoniq Soundscape>");
 936 
 937   for (i = 0; i < sizeof (valid_interrupts); i++)
 938     if (hw_config->irq == valid_interrupts[i])
 939       {
 940         irq_bits = i;
 941         break;
 942       }
 943 
 944   if (hw_config->irq > 15 || (regs[4] = irq_bits == 0xff))
 945     {
 946       printk ("Invalid IRQ%d\n", hw_config->irq);
 947       return mem_start;
 948     }
 949 
 950   save_flags (flags);
 951   cli ();
 952 
 953   for (i = 1; i < 10; i++)
 954     switch (i)
 955       {
 956       case 1:                   /* Host interrupt enable */
 957         sscape_write (devc, i, 0xf0);   /* All interrupts enabled */
 958         break;
 959 
 960       case 2:                   /* DMA A status/trigger register */
 961       case 3:                   /* DMA B status/trigger register */
 962         sscape_write (devc, i, 0x20);   /* DMA channel disabled */
 963         break;
 964 
 965       case 4:                   /* Host interrupt config reg */
 966         sscape_write (devc, i, 0xf0 | (irq_bits << 2) | irq_bits);
 967         break;
 968 
 969       case 5:                   /* Don't destroy CD-ROM DMA config bits (0xc0) */
 970         sscape_write (devc, i, (regs[i] & 0x3f) |
 971                       (sscape_read (devc, i) & 0xc0));
 972         break;
 973 
 974       case 6:                   /* CD-ROM config. Don't touch. */
 975         break;
 976 
 977       case 9:                   /* Master control reg. Don't modify CR-ROM bits. Disable SB emul */
 978         sscape_write (devc, i,
 979                       (sscape_read (devc, i) & 0xf0) | 0x00);
 980         break;
 981 
 982       default:
 983         sscape_write (devc, i, regs[i]);
 984       }
 985 
 986   restore_flags (flags);
 987 
 988 #ifdef SSCAPE_DEBUG2
 989   /*
 990      * Temporary debugging aid. Print contents of the registers after
 991      * changing them.
 992    */
 993   {
 994     int             i;
 995 
 996     for (i = 0; i < 13; i++)
 997       printk ("I%d = %02x (new value)\n", i, sscape_read (devc, i));
 998   }
 999 #endif
1000 
1001 #if !defined(EXCLUDE_MIDI) && !defined(EXCLUDE_MPU_EMU)
1002   if (probe_mpu401 (hw_config))
1003     hw_config->always_detect = 1;
1004   {
1005     int             prev_devs;
1006 
1007     prev_devs = num_midis;
1008     mem_start = attach_mpu401 (mem_start, hw_config);
1009 
1010     if (num_midis == (prev_devs + 1))   /* The MPU driver installed itself */
1011       midi_devs[prev_devs]->coproc = &sscape_coproc_operations;
1012   }
1013 #endif
1014 
1015 #ifndef EXCLUDE_NATIVE_PCM
1016   /* Not supported yet */
1017 
1018 #ifndef EXCLUDE_AUDIO
1019   if (num_audiodevs < MAX_AUDIO_DEV)
1020     {
1021       audio_devs[my_dev = num_audiodevs++] = &sscape_audio_operations;
1022       audio_devs[my_dev]->dmachan1 = hw_config->dma;
1023       audio_devs[my_dev]->buffsize = DSP_BUFFSIZE;
1024       audio_devs[my_dev]->devc = devc;
1025       devc->my_audiodev = my_dev;
1026       devc->opened = 0;
1027       audio_devs[my_dev]->coproc = &sscape_coproc_operations;
1028       if (snd_set_irq_handler (hw_config->irq, sscapeintr, "SoundScape", devc->osp) < 0)
1029         printk ("Error: Can't allocate IRQ for SoundScape\n");
1030 
1031       sscape_write (devc, GA_INTENA_REG, 0x80);         /* Master IRQ enable */
1032     }
1033   else
1034     printk ("SoundScape: More than enough audio devices detected\n");
1035 #endif
1036 #endif
1037   devc->ok = 1;
1038   devc->failed = 0;
1039   return mem_start;
1040 }
1041 
1042 int
1043 probe_sscape (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
1044 {
1045   unsigned char   save;
1046 
1047   devc->failed = 1;
1048   devc->base = hw_config->io_base;
1049   devc->irq = hw_config->irq;
1050   devc->dma = hw_config->dma;
1051   devc->osp = hw_config->osp;
1052 
1053   if (sscape_detected != 0 && sscape_detected != hw_config->io_base)
1054     return 0;
1055 
1056   /*
1057      * First check that the address register of "ODIE" is
1058      * there and that it has exactly 4 writeable bits.
1059      * First 4 bits
1060    */
1061   if ((save = inb (PORT (ODIE_ADDR))) & 0xf0)
1062     return 0;
1063 
1064   outb (0x00, PORT (ODIE_ADDR));
1065   if (inb (PORT (ODIE_ADDR)) != 0x00)
1066     return 0;
1067 
1068   outb (0xff, PORT (ODIE_ADDR));
1069   if (inb (PORT (ODIE_ADDR)) != 0x0f)
1070     return 0;
1071 
1072   outb (save, PORT (ODIE_ADDR));
1073 
1074   /*
1075      * Now verify that some indirect registers return zero on some bits.
1076      * This may break the driver with some future revisions of "ODIE" but...
1077    */
1078 
1079   if (sscape_read (devc, 0) & 0x0c)
1080     return 0;
1081 
1082   if (sscape_read (devc, 1) & 0x0f)
1083     return 0;
1084 
1085   if (sscape_read (devc, 5) & 0x0f)
1086     return 0;
1087 
1088 #ifdef SSCAPE_DEBUG1
1089   /*
1090      * Temporary debugging aid. Print contents of the registers before
1091      * changing them.
1092    */
1093   {
1094     int             i;
1095 
1096     for (i = 0; i < 13; i++)
1097       printk ("I%d = %02x (old value)\n", i, sscape_read (devc, i));
1098   }
1099 #endif
1100 
1101   if (old_hardware)             /* Check that it's really an old Spea/Reveal card. */
1102     {
1103       int             status = 0;
1104       unsigned char   tmp;
1105       int             cc;
1106 
1107       if (!((tmp = sscape_read (devc, GA_HMCTL_REG)) & 0xc0))
1108         {
1109           sscape_write (devc, GA_HMCTL_REG, tmp | 0x80);
1110           for (cc = 0; cc < 200000; ++cc)
1111             inb (devc->base + ODIE_ADDR);
1112         }
1113       else
1114         old_hardware = 0;
1115     }
1116 
1117   if (sound_alloc_dma (hw_config->dma, "soundscape"))
1118     {
1119       printk ("sscape.c: Can't allocate DMA channel\n");
1120       return 0;
1121     }
1122 
1123   sscape_detected = hw_config->io_base;
1124 
1125   return 1;
1126 }
1127 
1128 int
1129 probe_ss_ms_sound (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
1130 {
1131   int             i, irq_bits = 0xff;
1132 
1133   if (devc->failed)
1134     return 0;
1135 
1136   if (devc->ok == 0)
1137     {
1138       printk ("SoundScape: Invalid initialization order.\n");
1139       return 0;
1140     }
1141 
1142   for (i = 0; i < sizeof (valid_interrupts); i++)
1143     if (hw_config->irq == valid_interrupts[i])
1144       {
1145         irq_bits = i;
1146         break;
1147       }
1148   if (hw_config->irq > 15 || irq_bits == 0xff)
1149     {
1150       printk ("SoundScape: Invalid MSS IRQ%d\n", hw_config->irq);
1151       return 0;
1152     }
1153 
1154   return ad1848_detect (hw_config->io_base, NULL, hw_config->osp);
1155 }
1156 
1157 long
1158 attach_ss_ms_sound (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
1159 {
1160   /*
1161      * This routine configures the SoundScape card for use with the
1162      * Win Sound System driver. The AD1848 codec interface uses the CD-ROM
1163      * config registers of the "ODIE".
1164    */
1165 
1166   int             i, irq_bits = 0xff;
1167 
1168 #ifdef EXCLUDE_NATIVE_PCM
1169   int             prev_devs = num_audiodevs;
1170 
1171 #endif
1172 
1173   /*
1174      * Setup the DMA polarity.
1175    */
1176   sscape_write (devc, GA_DMACFG_REG, 0x50);
1177 
1178   /*
1179      * Take the gate-arry off of the DMA channel.
1180    */
1181   sscape_write (devc, GA_DMAB_REG, 0x20);
1182 
1183   /*
1184      * Init the AD1848 (CD-ROM) config reg.
1185    */
1186 
1187   for (i = 0; i < sizeof (valid_interrupts); i++)
1188     if (hw_config->irq == valid_interrupts[i])
1189       {
1190         irq_bits = i;
1191         break;
1192       }
1193 
1194   sscape_write (devc, GA_CDCFG_REG, 0x89 | (hw_config->dma << 4) |
1195                 (irq_bits << 1));
1196 
1197   if (hw_config->irq == devc->irq)
1198     printk ("SoundScape: Warning! The WSS mode can't share IRQ with MIDI\n");
1199 
1200   ad1848_init ("SoundScape", hw_config->io_base,
1201                hw_config->irq,
1202                hw_config->dma,
1203                hw_config->dma,
1204                0,
1205                devc->osp);
1206 
1207 #ifdef EXCLUDE_NATIVE_PCM
1208   if (num_audiodevs == (prev_devs + 1))         /* The AD1848 driver installed itself */
1209     audio_devs[prev_devs]->coproc = &sscape_coproc_operations;
1210 #endif
1211 #ifdef SSCAPE_DEBUG5
1212   /*
1213      * Temporary debugging aid. Print contents of the registers
1214      * after the AD1848 device has been initialized.
1215    */
1216   {
1217     int             i;
1218 
1219     for (i = 0; i < 13; i++)
1220       printk ("I%d = %02x\n", i, sscape_read (devc, i));
1221   }
1222 #endif
1223 
1224   return mem_start;
1225 }
1226 
1227 void
1228 unload_sscape (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
1229 {
1230   unload_mpu401 (hw_config);
1231   snd_release_irq (hw_config->irq);
1232   sound_free_dma (hw_config->dma);
1233 }
1234 
1235 void
1236 unload_ss_ms_sound (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
1237 {
1238   ad1848_unload (hw_config->io_base,
1239                  hw_config->irq,
1240                  hw_config->dma,
1241                  hw_config->dma,
1242                  0);
1243 }
1244 
1245 #endif

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