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. do_dma
  15. verify_mpu
  16. sscape_coproc_open
  17. sscape_coproc_close
  18. sscape_coproc_reset
  19. sscape_download_boot
  20. download_boot_block
  21. sscape_coproc_ioctl
  22. sscape_audio_open
  23. sscape_audio_close
  24. set_speed
  25. set_channels
  26. set_format
  27. sscape_audio_ioctl
  28. sscape_audio_output_block
  29. sscape_audio_start_input
  30. sscape_audio_prepare_for_input
  31. sscape_audio_prepare_for_output
  32. sscape_audio_halt
  33. sscape_audio_reset
  34. attach_sscape
  35. probe_sscape
  36. probe_ss_ms_sound
  37. attach_ss_ms_sound
  38. unload_sscape
  39. 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(CONFIG_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 wait_handle *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         module_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(CONFIG_MPU401) || defined(CONFIG_MPU_EMU)) && defined(CONFIG_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 
 342 static void
 343 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] */
 344 {
 345   unsigned char   temp;
 346 
 347   if (dma_chan != SSCAPE_DMA_A)
 348     {
 349       printk ("SSCAPE: Tried to use DMA channel  != A. Why?\n");
 350       return;
 351     }
 352 
 353   DMAbuf_start_dma (devc->my_audiodev,
 354                     buf,
 355                     blk_size, mode);
 356 
 357   temp = devc->dma << 4;        /* Setup DMA channel select bits */
 358   if (devc->dma <= 3)
 359     temp |= 0x80;               /* 8 bit DMA channel */
 360 
 361   temp |= 1;                    /* Trigger DMA */
 362   sscape_write (devc, GA_DMAA_REG, temp);
 363   temp &= 0xfe;                 /* Clear DMA trigger */
 364   sscape_write (devc, GA_DMAA_REG, temp);
 365 }
 366 
 367 static int
 368 verify_mpu (struct sscape_info *devc)
     /* [previous][next][first][last][top][bottom][index][help] */
 369 {
 370   /*
 371      * The SoundScape board could be in three modes (MPU, 8250 and host).
 372      * If the card is not in the MPU mode, enabling the MPU driver will
 373      * cause infinite loop (the driver believes that there is always some
 374      * received data in the buffer.
 375      *
 376      * Detect this by looking if there are more than 10 received MIDI bytes
 377      * (0x00) in the buffer.
 378    */
 379 
 380   int             i;
 381 
 382   for (i = 0; i < 10; i++)
 383     {
 384       if (inb (devc->base + HOST_CTRL) & 0x80)
 385         return 1;
 386 
 387       if (inb (devc->base) != 0x00)
 388         return 1;
 389     }
 390 
 391   printk ("SoundScape: The device is not in the MPU-401 mode\n");
 392   return 0;
 393 }
 394 
 395 static int
 396 sscape_coproc_open (void *dev_info, int sub_device)
     /* [previous][next][first][last][top][bottom][index][help] */
 397 {
 398   if (sub_device == COPR_MIDI)
 399     {
 400       set_mt32 (devc, 0);
 401       if (!verify_mpu (devc))
 402         return -EIO;
 403     }
 404 
 405   sscape_sleep_flag.mode = WK_NONE;
 406   return 0;
 407 }
 408 
 409 static void
 410 sscape_coproc_close (void *dev_info, int sub_device)
     /* [previous][next][first][last][top][bottom][index][help] */
 411 {
 412   struct sscape_info *devc = dev_info;
 413   unsigned long   flags;
 414 
 415   save_flags (flags);
 416   cli ();
 417   if (devc->dma_allocated)
 418     {
 419       sscape_write (devc, GA_DMAA_REG, 0x20);   /* DMA channel disabled */
 420 #ifdef CONFIG_NATIVE_PCM
 421 #endif
 422       devc->dma_allocated = 0;
 423     }
 424   sscape_sleep_flag.mode = WK_NONE;
 425   restore_flags (flags);
 426 
 427   return;
 428 }
 429 
 430 static void
 431 sscape_coproc_reset (void *dev_info)
     /* [previous][next][first][last][top][bottom][index][help] */
 432 {
 433 }
 434 
 435 static int
 436 sscape_download_boot (struct sscape_info *devc, unsigned char *block, int size, int flag)
     /* [previous][next][first][last][top][bottom][index][help] */
 437 {
 438   unsigned long   flags;
 439   unsigned char   temp;
 440   int             done, timeout_val;
 441 
 442   if (flag & CPF_FIRST)
 443     {
 444       /*
 445          * First block. Have to allocate DMA and to reset the board
 446          * before continuing.
 447        */
 448 
 449       save_flags (flags);
 450       cli ();
 451       if (devc->dma_allocated == 0)
 452         {
 453 #ifdef CONFIG_NATIVE_PCM
 454 #endif
 455 
 456           devc->dma_allocated = 1;
 457         }
 458       restore_flags (flags);
 459 
 460       sscape_write (devc, GA_HMCTL_REG,
 461                     (temp = sscape_read (devc, GA_HMCTL_REG)) & 0x3f);  /*Reset */
 462 
 463       for (timeout_val = 10000; timeout_val > 0; timeout_val--)
 464         sscape_read (devc, GA_HMCTL_REG);       /* Delay */
 465 
 466       /* Take board out of reset */
 467       sscape_write (devc, GA_HMCTL_REG,
 468                     (temp = sscape_read (devc, GA_HMCTL_REG)) | 0x80);
 469     }
 470 
 471   /*
 472      * Transfer one code block using DMA
 473    */
 474   memcpy (audio_devs[devc->my_audiodev]->dmap_out->raw_buf, block, size);
 475 
 476   save_flags (flags);
 477   cli ();
 478 /******** INTERRUPTS DISABLED NOW ********/
 479   do_dma (devc, SSCAPE_DMA_A,
 480           audio_devs[devc->my_audiodev]->dmap_out->raw_buf_phys,
 481           size, DMA_MODE_WRITE);
 482 
 483   /*
 484    * Wait until transfer completes.
 485    */
 486   sscape_sleep_flag.mode = WK_NONE;
 487   done = 0;
 488   timeout_val = 100;
 489   while (!done && timeout_val-- > 0)
 490     {
 491       int             resid;
 492 
 493 
 494       {
 495         unsigned long   tl;
 496 
 497         if (1)
 498           current_set_timeout (tl = jiffies + (1));
 499         else
 500           tl = 0xffffffff;
 501         sscape_sleep_flag.mode = WK_SLEEP;
 502         module_interruptible_sleep_on (&sscape_sleeper);
 503         if (!(sscape_sleep_flag.mode & WK_WAKEUP))
 504           {
 505             if (jiffies >= tl)
 506               sscape_sleep_flag.mode |= WK_TIMEOUT;
 507           }
 508         sscape_sleep_flag.mode &= ~WK_SLEEP;
 509       };
 510       clear_dma_ff (devc->dma);
 511       if ((resid = get_dma_residue (devc->dma)) == 0)
 512         done = 1;
 513     }
 514 
 515   restore_flags (flags);
 516   if (!done)
 517     return 0;
 518 
 519   if (flag & CPF_LAST)
 520     {
 521       /*
 522          * Take the board out of reset
 523        */
 524       outb (0x00, PORT (HOST_CTRL));
 525       outb (0x00, PORT (MIDI_CTRL));
 526 
 527       temp = sscape_read (devc, GA_HMCTL_REG);
 528       temp |= 0x40;
 529       sscape_write (devc, GA_HMCTL_REG, temp);  /* Kickstart the board */
 530 
 531       /*
 532          * Wait until the ODB wakes up
 533        */
 534 
 535       save_flags (flags);
 536       cli ();
 537       done = 0;
 538       timeout_val = 5 * HZ;
 539       while (!done && timeout_val-- > 0)
 540         {
 541 
 542           {
 543             unsigned long   tl;
 544 
 545             if (1)
 546               current_set_timeout (tl = jiffies + (1));
 547             else
 548               tl = 0xffffffff;
 549             sscape_sleep_flag.mode = WK_SLEEP;
 550             module_interruptible_sleep_on (&sscape_sleeper);
 551             if (!(sscape_sleep_flag.mode & WK_WAKEUP))
 552               {
 553                 if (jiffies >= tl)
 554                   sscape_sleep_flag.mode |= WK_TIMEOUT;
 555               }
 556             sscape_sleep_flag.mode &= ~WK_SLEEP;
 557           };
 558           if (inb (PORT (HOST_DATA)) == 0xff)   /* OBP startup acknowledge */
 559             done = 1;
 560         }
 561       restore_flags (flags);
 562       if (!done)
 563         {
 564           printk ("SoundScape: The OBP didn't respond after code download\n");
 565           return 0;
 566         }
 567 
 568       save_flags (flags);
 569       cli ();
 570       done = 0;
 571       timeout_val = 5 * HZ;
 572       while (!done && timeout_val-- > 0)
 573         {
 574 
 575           {
 576             unsigned long   tl;
 577 
 578             if (1)
 579               current_set_timeout (tl = jiffies + (1));
 580             else
 581               tl = 0xffffffff;
 582             sscape_sleep_flag.mode = WK_SLEEP;
 583             module_interruptible_sleep_on (&sscape_sleeper);
 584             if (!(sscape_sleep_flag.mode & WK_WAKEUP))
 585               {
 586                 if (jiffies >= tl)
 587                   sscape_sleep_flag.mode |= WK_TIMEOUT;
 588               }
 589             sscape_sleep_flag.mode &= ~WK_SLEEP;
 590           };
 591           if (inb (PORT (HOST_DATA)) == 0xfe)   /* Host startup acknowledge */
 592             done = 1;
 593         }
 594       restore_flags (flags);
 595       if (!done)
 596         {
 597           printk ("SoundScape: OBP Initialization failed.\n");
 598           return 0;
 599         }
 600 
 601       printk ("SoundScape board of type %d initialized OK\n",
 602               get_board_type (devc));
 603 
 604       set_control (devc, CTL_MASTER_VOL, 100);
 605       set_control (devc, CTL_SYNTH_VOL, 100);
 606 
 607 #ifdef SSCAPE_DEBUG3
 608       /*
 609          * Temporary debugging aid. Print contents of the registers after
 610          * downloading the code.
 611        */
 612       {
 613         int             i;
 614 
 615         for (i = 0; i < 13; i++)
 616           printk ("I%d = %02x (new value)\n", i, sscape_read (devc, i));
 617       }
 618 #endif
 619 
 620     }
 621 
 622   return 1;
 623 }
 624 
 625 static int
 626 download_boot_block (void *dev_info, copr_buffer * buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 627 {
 628   if (buf->len <= 0 || buf->len > sizeof (buf->data))
 629     return -EINVAL;
 630 
 631   if (!sscape_download_boot (devc, buf->data, buf->len, buf->flags))
 632     {
 633       printk ("SSCAPE: Unable to load microcode block to the OBP.\n");
 634       return -EIO;
 635     }
 636 
 637   return 0;
 638 }
 639 
 640 static int
 641 sscape_coproc_ioctl (void *dev_info, unsigned int cmd, ioctl_arg arg, int local)
     /* [previous][next][first][last][top][bottom][index][help] */
 642 {
 643 
 644   switch (cmd)
 645     {
 646     case SNDCTL_COPR_RESET:
 647       sscape_coproc_reset (dev_info);
 648       return 0;
 649       break;
 650 
 651     case SNDCTL_COPR_LOAD:
 652       {
 653         copr_buffer    *buf;
 654         int             err;
 655 
 656         buf = (copr_buffer *) kmalloc (sizeof (copr_buffer), GFP_KERNEL);
 657         if (buf == NULL)
 658           return -ENOSPC;
 659         memcpy_fromfs ((char *) buf, &(((char *) arg)[0]), sizeof (*buf));
 660         err = download_boot_block (dev_info, buf);
 661         kfree (buf);
 662         return err;
 663       }
 664       break;
 665 
 666     default:
 667       return -EINVAL;
 668     }
 669 
 670 }
 671 
 672 static coproc_operations sscape_coproc_operations =
 673 {
 674   "SoundScape M68K",
 675   sscape_coproc_open,
 676   sscape_coproc_close,
 677   sscape_coproc_ioctl,
 678   sscape_coproc_reset,
 679   &dev_info
 680 };
 681 
 682 static int
 683 sscape_audio_open (int dev, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 684 {
 685   unsigned long   flags;
 686   sscape_info    *devc = (sscape_info *) audio_devs[dev]->devc;
 687 
 688   save_flags (flags);
 689   cli ();
 690   if (devc->opened)
 691     {
 692       restore_flags (flags);
 693       return -EBUSY;
 694     }
 695   devc->opened = 1;
 696   restore_flags (flags);
 697 #ifdef SSCAPE_DEBUG4
 698   /*
 699      * Temporary debugging aid. Print contents of the registers
 700      * when the device is opened.
 701    */
 702   {
 703     int             i;
 704 
 705     for (i = 0; i < 13; i++)
 706       printk ("I%d = %02x\n", i, sscape_read (devc, i));
 707   }
 708 #endif
 709 
 710   return 0;
 711 }
 712 
 713 static void
 714 sscape_audio_close (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 715 {
 716   unsigned long   flags;
 717   sscape_info    *devc = (sscape_info *) audio_devs[dev]->devc;
 718 
 719   DEB (printk ("sscape_audio_close(void)\n"));
 720 
 721   save_flags (flags);
 722   cli ();
 723 
 724   devc->opened = 0;
 725 
 726   restore_flags (flags);
 727 }
 728 
 729 static int
 730 set_speed (sscape_info * devc, int arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 731 {
 732   return 8000;
 733 }
 734 
 735 static int
 736 set_channels (sscape_info * devc, int arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 737 {
 738   return 1;
 739 }
 740 
 741 static int
 742 set_format (sscape_info * devc, int arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 743 {
 744   return AFMT_U8;
 745 }
 746 
 747 static int
 748 sscape_audio_ioctl (int dev, unsigned int cmd, ioctl_arg arg, int local)
     /* [previous][next][first][last][top][bottom][index][help] */
 749 {
 750   sscape_info    *devc = (sscape_info *) audio_devs[dev]->devc;
 751 
 752   switch (cmd)
 753     {
 754     case SOUND_PCM_WRITE_RATE:
 755       if (local)
 756         return set_speed (devc, (int) arg);
 757       return snd_ioctl_return ((int *) arg, set_speed (devc, get_fs_long ((long *) arg)));
 758 
 759     case SOUND_PCM_READ_RATE:
 760       if (local)
 761         return 8000;
 762       return snd_ioctl_return ((int *) arg, 8000);
 763 
 764     case SNDCTL_DSP_STEREO:
 765       if (local)
 766         return set_channels (devc, (int) arg + 1) - 1;
 767       return snd_ioctl_return ((int *) arg, set_channels (devc, get_fs_long ((long *) arg) + 1) - 1);
 768 
 769     case SOUND_PCM_WRITE_CHANNELS:
 770       if (local)
 771         return set_channels (devc, (int) arg);
 772       return snd_ioctl_return ((int *) arg, set_channels (devc, get_fs_long ((long *) arg)));
 773 
 774     case SOUND_PCM_READ_CHANNELS:
 775       if (local)
 776         return 1;
 777       return snd_ioctl_return ((int *) arg, 1);
 778 
 779     case SNDCTL_DSP_SAMPLESIZE:
 780       if (local)
 781         return set_format (devc, (int) arg);
 782       return snd_ioctl_return ((int *) arg, set_format (devc, get_fs_long ((long *) arg)));
 783 
 784     case SOUND_PCM_READ_BITS:
 785       if (local)
 786         return 8;
 787       return snd_ioctl_return ((int *) arg, 8);
 788 
 789     default:;
 790     }
 791   return -EINVAL;
 792 }
 793 
 794 static void
 795 sscape_audio_output_block (int dev, unsigned long buf, int count, int intrflag, int dma_restart)
     /* [previous][next][first][last][top][bottom][index][help] */
 796 {
 797 }
 798 
 799 static void
 800 sscape_audio_start_input (int dev, unsigned long buf, int count, int intrflag, int dma_restart)
     /* [previous][next][first][last][top][bottom][index][help] */
 801 {
 802 }
 803 
 804 static int
 805 sscape_audio_prepare_for_input (int dev, int bsize, int bcount)
     /* [previous][next][first][last][top][bottom][index][help] */
 806 {
 807   return 0;
 808 }
 809 
 810 static int
 811 sscape_audio_prepare_for_output (int dev, int bsize, int bcount)
     /* [previous][next][first][last][top][bottom][index][help] */
 812 {
 813   return 0;
 814 }
 815 
 816 static void
 817 sscape_audio_halt (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 818 {
 819 }
 820 
 821 static void
 822 sscape_audio_reset (int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 823 {
 824   sscape_audio_halt (dev);
 825 }
 826 
 827 static struct audio_operations sscape_audio_operations =
 828 {
 829   "Not functional",
 830   0,
 831   AFMT_U8 | AFMT_S16_LE,
 832   NULL,
 833   sscape_audio_open,
 834   sscape_audio_close,
 835   sscape_audio_output_block,
 836   sscape_audio_start_input,
 837   sscape_audio_ioctl,
 838   sscape_audio_prepare_for_input,
 839   sscape_audio_prepare_for_output,
 840   sscape_audio_reset,
 841   sscape_audio_halt,
 842   NULL,
 843   NULL
 844 };
 845 
 846 static int      sscape_detected = 0;
 847 
 848 long
 849 attach_sscape (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
 850 {
 851   int             my_dev;
 852 
 853 #ifndef SSCAPE_REGS
 854   /*
 855      * Config register values for Spea/V7 Media FX and Ensoniq S-2000.
 856      * These values are card
 857      * dependent. If you have another SoundScape based card, you have to
 858      * find the correct values. Do the following:
 859      *  - Compile this driver with SSCAPE_DEBUG1 defined.
 860      *  - Shut down and power off your machine.
 861      *  - Boot with DOS so that the SSINIT.EXE program is run.
 862      *  - Warm boot to {Linux|SYSV|BSD} and write down the lines displayed
 863      *    when detecting the SoundScape.
 864      *  - Modify the following list to use the values printed during boot.
 865      *    Undefine the SSCAPE_DEBUG1
 866    */
 867 #define SSCAPE_REGS { \
 868 /* I0 */        0x00, \
 869                 0xf0, /* Note! Ignored. Set always to 0xf0 */ \
 870                 0x20, /* Note! Ignored. Set always to 0x20 */ \
 871                 0x20, /* Note! Ignored. Set always to 0x20 */ \
 872                 0xf5, /* Ignored */ \
 873                 0x10, \
 874                 0x00, \
 875                 0x2e, /* I7 MEM config A. Likely to vary between models */ \
 876                 0x00, /* I8 MEM config B. Likely to vary between models */ \
 877 /* I9 */        0x40 /* Ignored */ \
 878         }
 879 #endif
 880 
 881   unsigned long   flags;
 882   static unsigned char regs[10] = SSCAPE_REGS;
 883 
 884   int             i, irq_bits = 0xff;
 885 
 886   if (sscape_detected != hw_config->io_base)
 887     return mem_start;
 888 
 889   if (old_hardware)
 890     {
 891       valid_interrupts = valid_interrupts_old;
 892       conf_printf ("Ensoniq Soundscape (old)", hw_config);
 893     }
 894   else
 895     conf_printf ("Ensoniq Soundscape", hw_config);
 896 
 897   for (i = 0; i < sizeof (valid_interrupts); i++)
 898     if (hw_config->irq == valid_interrupts[i])
 899       {
 900         irq_bits = i;
 901         break;
 902       }
 903 
 904   if (hw_config->irq > 15 || (regs[4] = irq_bits == 0xff))
 905     {
 906       printk ("Invalid IRQ%d\n", hw_config->irq);
 907       return mem_start;
 908     }
 909 
 910   save_flags (flags);
 911   cli ();
 912 
 913   for (i = 1; i < 10; i++)
 914     switch (i)
 915       {
 916       case 1:                   /* Host interrupt enable */
 917         sscape_write (devc, i, 0xf0);   /* All interrupts enabled */
 918         break;
 919 
 920       case 2:                   /* DMA A status/trigger register */
 921       case 3:                   /* DMA B status/trigger register */
 922         sscape_write (devc, i, 0x20);   /* DMA channel disabled */
 923         break;
 924 
 925       case 4:                   /* Host interrupt config reg */
 926         sscape_write (devc, i, 0xf0 | (irq_bits << 2) | irq_bits);
 927         break;
 928 
 929       case 5:                   /* Don't destroy CD-ROM DMA config bits (0xc0) */
 930         sscape_write (devc, i, (regs[i] & 0x3f) |
 931                       (sscape_read (devc, i) & 0xc0));
 932         break;
 933 
 934       case 6:                   /* CD-ROM config. Don't touch. */
 935         break;
 936 
 937       case 9:                   /* Master control reg. Don't modify CR-ROM bits. Disable SB emul */
 938         sscape_write (devc, i,
 939                       (sscape_read (devc, i) & 0xf0) | 0x08);
 940         break;
 941 
 942       default:
 943         sscape_write (devc, i, regs[i]);
 944       }
 945 
 946   restore_flags (flags);
 947 
 948 #ifdef SSCAPE_DEBUG2
 949   /*
 950      * Temporary debugging aid. Print contents of the registers after
 951      * changing them.
 952    */
 953   {
 954     int             i;
 955 
 956     for (i = 0; i < 13; i++)
 957       printk ("I%d = %02x (new value)\n", i, sscape_read (devc, i));
 958   }
 959 #endif
 960 
 961 #if defined(CONFIG_MIDI) && defined(CONFIG_MPU_EMU)
 962   if (probe_mpu401 (hw_config))
 963     hw_config->always_detect = 1;
 964   {
 965     int             prev_devs;
 966 
 967     prev_devs = num_midis;
 968     mem_start = attach_mpu401 (mem_start, hw_config);
 969 
 970     if (num_midis == (prev_devs + 1))   /* The MPU driver installed itself */
 971       midi_devs[prev_devs]->coproc = &sscape_coproc_operations;
 972   }
 973 #endif
 974 
 975 #ifndef EXCLUDE_NATIVE_PCM
 976   /* Not supported yet */
 977 
 978 #ifdef CONFIG_AUDIO
 979   if (num_audiodevs < MAX_AUDIO_DEV)
 980     {
 981       audio_devs[my_dev = num_audiodevs++] = &sscape_audio_operations;
 982       audio_devs[my_dev]->dmachan1 = hw_config->dma;
 983       audio_devs[my_dev]->buffsize = DSP_BUFFSIZE;
 984       audio_devs[my_dev]->devc = devc;
 985       devc->my_audiodev = my_dev;
 986       devc->opened = 0;
 987       audio_devs[my_dev]->coproc = &sscape_coproc_operations;
 988       if (snd_set_irq_handler (hw_config->irq, sscapeintr, "SoundScape", devc->osp) < 0)
 989         printk ("Error: Can't allocate IRQ for SoundScape\n");
 990 
 991       sscape_write (devc, GA_INTENA_REG, 0x80);         /* Master IRQ enable */
 992     }
 993   else
 994     printk ("SoundScape: More than enough audio devices detected\n");
 995 #endif
 996 #endif
 997   devc->ok = 1;
 998   devc->failed = 0;
 999   return mem_start;
1000 }
1001 
1002 int
1003 probe_sscape (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
1004 {
1005   unsigned char   save;
1006 
1007   devc->failed = 1;
1008   devc->base = hw_config->io_base;
1009   devc->irq = hw_config->irq;
1010   devc->dma = hw_config->dma;
1011   devc->osp = hw_config->osp;
1012 
1013   if (sscape_detected != 0 && sscape_detected != hw_config->io_base)
1014     return 0;
1015 
1016   /*
1017      * First check that the address register of "ODIE" is
1018      * there and that it has exactly 4 writeable bits.
1019      * First 4 bits
1020    */
1021   if ((save = inb (PORT (ODIE_ADDR))) & 0xf0)
1022     return 0;
1023 
1024   outb (0x00, PORT (ODIE_ADDR));
1025   if (inb (PORT (ODIE_ADDR)) != 0x00)
1026     return 0;
1027 
1028   outb (0xff, PORT (ODIE_ADDR));
1029   if (inb (PORT (ODIE_ADDR)) != 0x0f)
1030     return 0;
1031 
1032   outb (save, PORT (ODIE_ADDR));
1033 
1034   /*
1035      * Now verify that some indirect registers return zero on some bits.
1036      * This may break the driver with some future revisions of "ODIE" but...
1037    */
1038 
1039   if (sscape_read (devc, 0) & 0x0c)
1040     return 0;
1041 
1042   if (sscape_read (devc, 1) & 0x0f)
1043     return 0;
1044 
1045   if (sscape_read (devc, 5) & 0x0f)
1046     return 0;
1047 
1048 #ifdef SSCAPE_DEBUG1
1049   /*
1050      * Temporary debugging aid. Print contents of the registers before
1051      * changing them.
1052    */
1053   {
1054     int             i;
1055 
1056     for (i = 0; i < 13; i++)
1057       printk ("I%d = %02x (old value)\n", i, sscape_read (devc, i));
1058   }
1059 #endif
1060 
1061   if (old_hardware)             /* Check that it's really an old Spea/Reveal card. */
1062     {
1063       unsigned char   tmp;
1064       int             cc;
1065 
1066       if (!((tmp = sscape_read (devc, GA_HMCTL_REG)) & 0xc0))
1067         {
1068           sscape_write (devc, GA_HMCTL_REG, tmp | 0x80);
1069           for (cc = 0; cc < 200000; ++cc)
1070             inb (devc->base + ODIE_ADDR);
1071         }
1072       else
1073         old_hardware = 0;
1074     }
1075 
1076   if (sound_alloc_dma (hw_config->dma, "soundscape"))
1077     {
1078       printk ("sscape.c: Can't allocate DMA channel\n");
1079       return 0;
1080     }
1081 
1082   sscape_detected = hw_config->io_base;
1083 
1084   return 1;
1085 }
1086 
1087 int
1088 probe_ss_ms_sound (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
1089 {
1090   int             i, irq_bits = 0xff;
1091 
1092   if (devc->failed)
1093     return 0;
1094 
1095   if (devc->ok == 0)
1096     {
1097       printk ("SoundScape: Invalid initialization order.\n");
1098       return 0;
1099     }
1100 
1101   for (i = 0; i < sizeof (valid_interrupts); i++)
1102     if (hw_config->irq == valid_interrupts[i])
1103       {
1104         irq_bits = i;
1105         break;
1106       }
1107   if (hw_config->irq > 15 || irq_bits == 0xff)
1108     {
1109       printk ("SoundScape: Invalid MSS IRQ%d\n", hw_config->irq);
1110       return 0;
1111     }
1112 
1113   return ad1848_detect (hw_config->io_base, NULL, hw_config->osp);
1114 }
1115 
1116 long
1117 attach_ss_ms_sound (long mem_start, struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
1118 {
1119   /*
1120      * This routine configures the SoundScape card for use with the
1121      * Win Sound System driver. The AD1848 codec interface uses the CD-ROM
1122      * config registers of the "ODIE".
1123    */
1124 
1125   int             i, irq_bits = 0xff;
1126 
1127 #ifndef CONFIG_NATIVE_PCM
1128   int             prev_devs = num_audiodevs;
1129 
1130 #endif
1131 
1132   /*
1133      * Setup the DMA polarity.
1134    */
1135   sscape_write (devc, GA_DMACFG_REG, 0x50);
1136 
1137   /*
1138      * Take the gate-arry off of the DMA channel.
1139    */
1140   sscape_write (devc, GA_DMAB_REG, 0x20);
1141 
1142   /*
1143      * Init the AD1848 (CD-ROM) config reg.
1144    */
1145 
1146   for (i = 0; i < sizeof (valid_interrupts); i++)
1147     if (hw_config->irq == valid_interrupts[i])
1148       {
1149         irq_bits = i;
1150         break;
1151       }
1152 
1153   sscape_write (devc, GA_CDCFG_REG, 0x89 | (hw_config->dma << 4) |
1154                 (irq_bits << 1));
1155 
1156   if (hw_config->irq == devc->irq)
1157     printk ("SoundScape: Warning! The WSS mode can't share IRQ with MIDI\n");
1158 
1159   ad1848_init ("SoundScape", hw_config->io_base,
1160                hw_config->irq,
1161                hw_config->dma,
1162                hw_config->dma,
1163                0,
1164                devc->osp);
1165 
1166 #ifndef CONFIG_NATIVE_PCM
1167   if (num_audiodevs == (prev_devs + 1))         /* The AD1848 driver installed itself */
1168     audio_devs[prev_devs]->coproc = &sscape_coproc_operations;
1169 #endif
1170 #ifdef SSCAPE_DEBUG5
1171   /*
1172      * Temporary debugging aid. Print contents of the registers
1173      * after the AD1848 device has been initialized.
1174    */
1175   {
1176     int             i;
1177 
1178     for (i = 0; i < 13; i++)
1179       printk ("I%d = %02x\n", i, sscape_read (devc, i));
1180   }
1181 #endif
1182 
1183   return mem_start;
1184 }
1185 
1186 void
1187 unload_sscape (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
1188 {
1189   unload_mpu401 (hw_config);
1190   snd_release_irq (hw_config->irq);
1191   sound_free_dma (hw_config->dma);
1192 }
1193 
1194 void
1195 unload_ss_ms_sound (struct address_info *hw_config)
     /* [previous][next][first][last][top][bottom][index][help] */
1196 {
1197   ad1848_unload (hw_config->io_base,
1198                  hw_config->irq,
1199                  hw_config->dma,
1200                  hw_config->dma,
1201                  0);
1202 }
1203 
1204 #endif

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