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

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