예제 #1
0
파일: trix.c 프로젝트: 274914765/C
static void download_boot(int base)
{
    int i = 0, n = trix_boot_len;

    if (trix_boot_len == 0)
        return;

    trix_write(0xf8, 0x00);    /* ??????? */
    outb((0x01), base + 6);    /* Clear the internal data pointer */
    outb((0x00), base + 6);    /* Restart */

    /*
       *  Write the boot code to the RAM upload/download register.
       *  Each write increments the internal data pointer.
     */
    outb((0x01), base + 6);    /* Clear the internal data pointer */
    outb((0x1A), 0x390);    /* Select RAM download/upload port */

    for (i = 0; i < n; i++)
        outb((trix_boot[i]), 0x391);
    for (i = n; i < 10016; i++)    /* Clear up to first 16 bytes of data RAM */
        outb((0x00), 0x391);
    outb((0x00), base + 6);    /* Reset */
    outb((0x50), 0x390);    /* ?????? */

}
예제 #2
0
static int
trix_set_wss_port (struct address_info *hw_config)
{
  unsigned char   addr_bits;

  if (kilroy_was_here)		/* Already initialized */
    return 0;

  kilroy_was_here = 1;

  if (trix_read (0x15) != 0x71)	/* No asic signature */
    return 0;

  /*
     * Disable separate wave playback and recording DMA channels since
     * the driver doesn't support duplex mode yet.
   */

  trix_write (0x13, trix_read (0x13) & ~0x80);
  trix_write (0x14, trix_read (0x14) & ~0x80);

  /*
     * Configure the ASIC to place the codec to the proper I/O location
   */

  switch (hw_config->io_base)
    {
    case 0x530:
      addr_bits = 0;
      break;
    case 0x604:
      addr_bits = 1;
      break;
    case 0xE80:
      addr_bits = 2;
      break;
    case 0xF40:
      addr_bits = 3;
      break;
    default:
      return 0;
    }

  trix_write (0x19, (trix_read (0x19) & 0x03) | addr_bits);
  return 1;
}
예제 #3
0
파일: trix.c 프로젝트: 274914765/C
static int __init probe_trix_sb(struct address_info *hw_config)
{

    int tmp;
    unsigned char conf;
    extern int sb_be_quiet;
    int old_quiet;
    static signed char irq_translate[] = {
        -1, -1, -1, 0, 1, 2, -1, 3
    };

    if (trix_boot_len == 0)
        return 0;    /* No boot code -> no fun */

    if ((hw_config->io_base & 0xffffff8f) != 0x200)
        return 0;

    tmp = hw_config->irq;
    if (tmp > 7)
        return 0;
    if (irq_translate[tmp] == -1)
        return 0;

    tmp = hw_config->dma;
    if (tmp != 1 && tmp != 3)
        return 0;

    if (!request_region(hw_config->io_base, 16, "soundblaster")) {
        printk(KERN_ERR "AudioTrix: SB I/O port conflict (%x)\n", hw_config->io_base);
        return 0;
    }

    conf = 0x84;        /* DMA and IRQ enable */
    conf |= hw_config->io_base & 0x70;    /* I/O address bits */
    conf |= irq_translate[hw_config->irq];
    if (hw_config->dma == 3)
        conf |= 0x08;
    trix_write(0x1b, conf);

    download_boot(hw_config->io_base);

    hw_config->name = "AudioTrix SB";
    if (!sb_dsp_detect(hw_config, 0, 0, NULL)) {
        release_region(hw_config->io_base, 16);
        return 0;
    }

    hw_config->driver_use_1 = SB_NO_MIDI | SB_NO_MIXER | SB_NO_RECORDING;

    /* Prevent false alarms */
    old_quiet = sb_be_quiet;
    sb_be_quiet = 1;

    sb_dsp_init(hw_config, THIS_MODULE);

    sb_be_quiet = old_quiet;
    return 1;
}
예제 #4
0
파일: trix.c 프로젝트: 274914765/C
static int trix_set_wss_port(struct address_info *hw_config)
{
    unsigned char   addr_bits;

    if (trix_read(0x15) != 0x71)    /* No ASIC signature */
    {
        MDB(printk(KERN_ERR "No AudioTrix ASIC signature found\n"));
        return 0;
    }

    /*
     * Reset some registers.
     */

    trix_write(0x13, 0);
    trix_write(0x14, 0);

    /*
     * Configure the ASIC to place the codec to the proper I/O location
     */

    switch (hw_config->io_base)
    {
        case 0x530:
            addr_bits = 0;
            break;
        case 0x604:
            addr_bits = 1;
            break;
        case 0xE80:
            addr_bits = 2;
            break;
        case 0xF40:
            addr_bits = 3;
            break;
        default:
            return 0;
    }

    trix_write(0x19, (trix_read(0x19) & 0x03) | addr_bits);
    return 1;
}
예제 #5
0
int
probe_trix_mpu (struct address_info *hw_config)
{
  unsigned char   conf;
  static char     irq_bits[] =
  {-1, -1, -1, 1, 2, 3, -1, 4, -1, 5};

  if (!kilroy_was_here)
    return 0;			/* AudioTriX Pro has not been detected earlier */

  if (!sb_initialized)
    return 0;

  if (mpu_initialized)
    return 0;

  if (hw_config->irq > 9)
    return 0;

  if (irq_bits[hw_config->irq] == -1)
    return 0;

  switch (hw_config->io_base)
    {
    case 0x330:
      conf = 0x00;
      break;
    case 0x370:
      conf = 0x04;
      break;
    case 0x3b0:
      conf = 0x08;
      break;
    case 0x3f0:
      conf = 0x0c;
      break;
    default:
      return 0;			/* Invalid port */
    }

  conf |= irq_bits[hw_config->irq] << 4;

  trix_write (0x19, (trix_read (0x19) & 0x83) | conf);

  mpu_initialized = 1;

  return probe_mpu401 (hw_config);
}
예제 #6
0
int
probe_trix_sb (struct address_info *hw_config)
{

  int             tmp;
  unsigned char   conf;
  static char     irq_translate[] =
  {-1, -1, -1, 0, 1, 2, -1, 3};

#ifndef INCLUDE_TRIX_BOOT
  return 0;			/* No boot code -> no fun */
#endif
  if (!kilroy_was_here)
    return 0;			/* AudioTriX Pro has not been detected earlier */

  if (sb_initialized)
    return 0;

  if (hw_config->io_base & 0xffffff8f != 0x200)
    return 0;

  tmp = hw_config->irq;
  if (tmp > 7)
    return 0;
  if (irq_translate[tmp] == -1)
    return 0;

  tmp = hw_config->dma;
  if (tmp != 1 && tmp != 3)
    return 0;

  conf = 0x84;			/* DMA and IRQ enable */
  conf |= hw_config->io_base & 0x70;	/* I/O address bits */
  conf |= irq_translate[hw_config->irq];
  if (hw_config->dma == 3)
    conf |= 0x08;
  trix_write (0x1b, conf);

  download_boot (hw_config->io_base);
  sb_initialized = 1;

  return 1;
}
예제 #7
0
파일: trix.c 프로젝트: 274914765/C
static int __init probe_trix_mpu(struct address_info *hw_config)
{
    unsigned char conf;
    static int irq_bits[] = {
        -1, -1, -1, 1, 2, 3, -1, 4, -1, 5
    };

    if (hw_config->irq > 9)
    {
        printk(KERN_ERR "AudioTrix: Bad MPU IRQ %d\n", hw_config->irq);
        return 0;
    }
    if (irq_bits[hw_config->irq] == -1)
    {
        printk(KERN_ERR "AudioTrix: Bad MPU IRQ %d\n", hw_config->irq);
        return 0;
    }
    switch (hw_config->io_base)
    {
        case 0x330:
            conf = 0x00;
            break;
        case 0x370:
            conf = 0x04;
            break;
        case 0x3b0:
            conf = 0x08;
            break;
        case 0x3f0:
            conf = 0x0c;
            break;
        default:
            return 0;    /* Invalid port */
    }

    conf |= irq_bits[hw_config->irq] << 4;
    trix_write(0x19, (trix_read(0x19) & 0x83) | conf);
    hw_config->name = "AudioTrix Pro";
    return probe_uart401(hw_config, THIS_MODULE);
}
예제 #8
0
static void
download_boot (int base)
{
  int             i = 0, n = sizeof (trix_boot);

  trix_write (0xf8, 0x00);	/* ??????? */
  OUTB (0x01, base + 6);	/* Clear the internal data pointer */
  OUTB (0x00, base + 6);	/* Restart */

  /*
     *  Write the boot code to the RAM upload/download register.
     *  Each write increments the internal data pointer.
   */
  OUTB (0x01, base + 6);	/* Clear the internal data pointer */
  OUTB (0x1A, 0x390);		/* Select RAM download/upload port */

  for (i = 0; i < n; i++)
    OUTB (trix_boot[i], 0x391);
  for (i = n; i < 10016; i++)	/* Clear up to first 16 bytes of data RAM */
    OUTB (0x00, 0x391);
  OUTB (0x00, base + 6);	/* Reset */
  OUTB (0x50, 0x390);		/* ?????? */
}
예제 #9
0
파일: trix.c 프로젝트: 274914765/C
static int __init init_trix_wss(struct address_info *hw_config)
{
    static unsigned char dma_bits[4] = {
        1, 2, 0, 3
    };
    struct resource *ports;
    int config_port = hw_config->io_base + 0;
    int dma1 = hw_config->dma, dma2 = hw_config->dma2;
    int old_num_mixers = num_mixers;
    u8 config, bits;
    int ret;
 
    switch(hw_config->irq) {
    case 7:
        bits = 8;
        break;
    case 9:
        bits = 0x10;
        break;
    case 10:
        bits = 0x18;
        break;
    case 11:
        bits = 0x20;
        break;
    default:
        printk(KERN_ERR "AudioTrix: Bad WSS IRQ %d\n", hw_config->irq);
        return 0;
    }

    switch (dma1) {
    case 0:
    case 1:
    case 3:
        break;
    default:
        printk(KERN_ERR "AudioTrix: Bad WSS DMA %d\n", dma1);
        return 0;
    }

    switch (dma2) {
    case -1:
    case 0:
    case 1:
    case 3:
        break;
    default:
        printk(KERN_ERR "AudioTrix: Bad capture DMA %d\n", dma2);
        return 0;
    }

    /*
     * Check if the IO port returns valid signature. The original MS Sound
     * system returns 0x04 while some cards (AudioTrix Pro for example)
     * return 0x00.
     */
    ports = request_region(hw_config->io_base + 4, 4, "ad1848");
    if (!ports) {
        printk(KERN_ERR "AudioTrix: MSS I/O port conflict (%x)\n", hw_config->io_base);
        return 0;
    }

    if (!request_region(hw_config->io_base, 4, "MSS config")) {
        printk(KERN_ERR "AudioTrix: MSS I/O port conflict (%x)\n", hw_config->io_base);
        release_region(hw_config->io_base + 4, 4);
        return 0;
    }

    if (!trix_set_wss_port(hw_config))
        goto fail;

    config = inb(hw_config->io_base + 3);

    if ((config & 0x3f) != 0x00)
    {
        MDB(printk(KERN_ERR "No MSS signature detected on port 0x%x\n", hw_config->io_base));
        goto fail;
    }

    /*
     * Check that DMA0 is not in use with a 8 bit board.
     */

    if (dma1 == 0 && config & 0x80)
    {
        printk(KERN_ERR "AudioTrix: Can't use DMA0 with a 8 bit card slot\n");
        goto fail;
    }
    if (hw_config->irq > 9 && config & 0x80)
    {
        printk(KERN_ERR "AudioTrix: Can't use IRQ%d with a 8 bit card slot\n", hw_config->irq);
        goto fail;
    }

    ret = ad1848_detect(ports, NULL, hw_config->osp);
    if (!ret)
        goto fail;

    if (joystick==1)
        trix_write(0x15, 0x80);

    /*
     * Set the IRQ and DMA addresses.
     */

    outb((bits | 0x40), config_port);

    if (dma2 == -1 || dma2 == dma1)
    {
          bits |= dma_bits[dma1];
          dma2 = dma1;
    }
    else
    {
        unsigned char tmp;

        tmp = trix_read(0x13) & ~30;
        trix_write(0x13, tmp | 0x80 | (dma1 << 4));

        tmp = trix_read(0x14) & ~30;
        trix_write(0x14, tmp | 0x80 | (dma2 << 4));
    }

    outb((bits), config_port);    /* Write IRQ+DMA setup */

    hw_config->slots[0] = ad1848_init("AudioTrix Pro", ports,
                      hw_config->irq,
                      dma1,
                      dma2,
                      0,
                      hw_config->osp,
                      THIS_MODULE);

    if (num_mixers > old_num_mixers)    /* Mixer got installed */
    {
        AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE);    /* Line in */
        AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_CD);
        AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_SYNTH);        /* OPL4 */
        AD1848_REROUTE(SOUND_MIXER_SPEAKER, SOUND_MIXER_ALTPCM);    /* SB */
    }
    return 1;

fail:
    release_region(hw_config->io_base, 4);
    release_region(hw_config->io_base + 4, 4);
    return 0;
}