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

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