Loading sound/isa/Kconfig +4 −2 Original line number Diff line number Diff line Loading @@ -377,10 +377,12 @@ config SND_SSCAPE select SND_WSS_LIB help Say Y here to include support for Ensoniq SoundScape soundcards. and Ensoniq OEM soundcards. The PCM audio is supported on SoundScape Classic, Elite, PnP and VIVO cards. The MIDI support is very experimental. and VIVO cards. The supported OEM cards are SPEA Media FX and Reveal SC-600. The MIDI support is very experimental. To compile this driver as a module, choose M here: the module will be called snd-sscape. Loading sound/isa/sscape.c +82 −34 Original line number Diff line number Diff line Loading @@ -127,7 +127,8 @@ enum GA_REG { enum card_type { SSCAPE, MEDIA_FX, /* Sequoia S-1000 */ SSCAPE, /* Sequoia S-2000 */ SSCAPE_PNP, SSCAPE_VIVO, }; Loading Loading @@ -784,20 +785,25 @@ static struct snd_kcontrol_new midi_mixer_ctl = { * These IRQs are encoded as bit patterns so that they can be * written to the control registers. */ static unsigned __devinit get_irq_config(int irq) static unsigned __devinit get_irq_config(int sscape_type, int irq) { static const int valid_irq[] = { 9, 5, 7, 10 }; static const int old_irq[] = { 9, 7, 5, 15 }; unsigned cfg; for (cfg = 0; cfg < ARRAY_SIZE(valid_irq); ++cfg) { if (sscape_type == MEDIA_FX) { for (cfg = 0; cfg < ARRAY_SIZE(old_irq); ++cfg) if (irq == old_irq[cfg]) return cfg; } else { for (cfg = 0; cfg < ARRAY_SIZE(valid_irq); ++cfg) if (irq == valid_irq[cfg]) return cfg; } /* for */ } return INVALID_IRQ; } /* * Perform certain arcane port-checks to see whether there * is a SoundScape board lurking behind the given ports. Loading Loading @@ -842,11 +848,39 @@ static int __devinit detect_sscape(struct soundscape *s, long wss_io) if (s->type != SSCAPE_VIVO && (d & 0x9f) != 0x0e) goto _done; d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f; sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0); if (s->ic_type == IC_OPUS) activate_ad1845_unsafe(s->io_base); if (s->type == SSCAPE_VIVO) wss_io += 4; d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f; sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0); /* wait for WSS codec */ for (d = 0; d < 500; d++) { if ((inb(wss_io) & 0x80) == 0) break; spin_unlock_irqrestore(&s->lock, flags); msleep(1); spin_lock_irqsave(&s->lock, flags); } snd_printd(KERN_INFO "init delay = %d ms\n", d); if ((inb(wss_io) & 0x80) != 0) goto _done; if (inb(wss_io + 2) == 0xff) goto _done; d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f; sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d); if ((inb(wss_io) & 0x80) != 0) s->type = MEDIA_FX; d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f; sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0); /* wait for WSS codec */ for (d = 0; d < 500; d++) { if ((inb(wss_io) & 0x80) == 0) Loading Loading @@ -954,9 +988,6 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port, if (sscape->type == SSCAPE_VIVO) port += 4; if (dma1 == dma2) dma2 = -1; err = snd_wss_create(card, port, -1, irq, dma1, dma2, WSS_HW_DETECT, WSS_HWSHARE_DMA1, &chip); if (!err) { Loading Loading @@ -1051,21 +1082,7 @@ static int __devinit create_sscape(int dev, struct snd_card *card) struct resource *wss_res; unsigned long flags; int err; /* * Check that the user didn't pass us garbage data ... */ irq_cfg = get_irq_config(irq[dev]); if (irq_cfg == INVALID_IRQ) { snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", irq[dev]); return -ENXIO; } mpu_irq_cfg = get_irq_config(mpu_irq[dev]); if (mpu_irq_cfg == INVALID_IRQ) { printk(KERN_ERR "sscape: Invalid IRQ %d\n", mpu_irq[dev]); return -ENXIO; } const char *name; /* * Grab IO ports that we will need to probe so that we Loading Loading @@ -1109,8 +1126,41 @@ static int __devinit create_sscape(int dev, struct snd_card *card) goto _release_dma; } printk(KERN_INFO "sscape: hardware detected at 0x%x, using IRQ %d, DMA %d\n", sscape->io_base, irq[dev], dma[dev]); switch (sscape->type) { case MEDIA_FX: name = "MediaFX/SoundFX"; break; case SSCAPE: name = "Soundscape"; break; case SSCAPE_PNP: name = "Soundscape PnP"; break; case SSCAPE_VIVO: name = "Soundscape VIVO"; break; default: name = "unknown Soundscape"; break; } printk(KERN_INFO "sscape: %s card detected at 0x%x, using IRQ %d, DMA %d\n", name, sscape->io_base, irq[dev], dma[dev]); /* * Check that the user didn't pass us garbage data ... */ irq_cfg = get_irq_config(sscape->type, irq[dev]); if (irq_cfg == INVALID_IRQ) { snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", irq[dev]); return -ENXIO; } mpu_irq_cfg = get_irq_config(sscape->type, mpu_irq[dev]); if (mpu_irq_cfg == INVALID_IRQ) { printk(KERN_ERR "sscape: Invalid IRQ %d\n", mpu_irq[dev]); return -ENXIO; } if (sscape->type != SSCAPE_VIVO) { /* Loading Loading @@ -1141,8 +1191,6 @@ static int __devinit create_sscape(int dev, struct snd_card *card) */ spin_lock_irqsave(&sscape->lock, flags); activate_ad1845_unsafe(sscape->io_base); sscape_write_unsafe(sscape->io_base, GA_INTENA_REG, 0x00); /* disable */ sscape_write_unsafe(sscape->io_base, GA_SMCFGA_REG, 0x2e); sscape_write_unsafe(sscape->io_base, GA_SMCFGB_REG, 0x00); Loading @@ -1151,12 +1199,12 @@ static int __devinit create_sscape(int dev, struct snd_card *card) * Enable and configure the DMA channels ... */ sscape_write_unsafe(sscape->io_base, GA_DMACFG_REG, 0x50); dma_cfg = (sscape->ic_type == IC_ODIE ? 0x70 : 0x40); dma_cfg = (sscape->ic_type == IC_OPUS ? 0x40 : 0x70); sscape_write_unsafe(sscape->io_base, GA_DMAA_REG, dma_cfg); sscape_write_unsafe(sscape->io_base, GA_DMAB_REG, 0x20); sscape_write_unsafe(sscape->io_base, GA_INTCFG_REG, 0xf0 | (mpu_irq_cfg << 2) | mpu_irq_cfg); mpu_irq_cfg |= mpu_irq_cfg << 2; sscape_write_unsafe(sscape->io_base, GA_INTCFG_REG, 0xf0 | mpu_irq_cfg); sscape_write_unsafe(sscape->io_base, GA_CDCFG_REG, 0x09 | DMA_8BIT | (dma[dev] << 4) | (irq_cfg << 1)); Loading Loading
sound/isa/Kconfig +4 −2 Original line number Diff line number Diff line Loading @@ -377,10 +377,12 @@ config SND_SSCAPE select SND_WSS_LIB help Say Y here to include support for Ensoniq SoundScape soundcards. and Ensoniq OEM soundcards. The PCM audio is supported on SoundScape Classic, Elite, PnP and VIVO cards. The MIDI support is very experimental. and VIVO cards. The supported OEM cards are SPEA Media FX and Reveal SC-600. The MIDI support is very experimental. To compile this driver as a module, choose M here: the module will be called snd-sscape. Loading
sound/isa/sscape.c +82 −34 Original line number Diff line number Diff line Loading @@ -127,7 +127,8 @@ enum GA_REG { enum card_type { SSCAPE, MEDIA_FX, /* Sequoia S-1000 */ SSCAPE, /* Sequoia S-2000 */ SSCAPE_PNP, SSCAPE_VIVO, }; Loading Loading @@ -784,20 +785,25 @@ static struct snd_kcontrol_new midi_mixer_ctl = { * These IRQs are encoded as bit patterns so that they can be * written to the control registers. */ static unsigned __devinit get_irq_config(int irq) static unsigned __devinit get_irq_config(int sscape_type, int irq) { static const int valid_irq[] = { 9, 5, 7, 10 }; static const int old_irq[] = { 9, 7, 5, 15 }; unsigned cfg; for (cfg = 0; cfg < ARRAY_SIZE(valid_irq); ++cfg) { if (sscape_type == MEDIA_FX) { for (cfg = 0; cfg < ARRAY_SIZE(old_irq); ++cfg) if (irq == old_irq[cfg]) return cfg; } else { for (cfg = 0; cfg < ARRAY_SIZE(valid_irq); ++cfg) if (irq == valid_irq[cfg]) return cfg; } /* for */ } return INVALID_IRQ; } /* * Perform certain arcane port-checks to see whether there * is a SoundScape board lurking behind the given ports. Loading Loading @@ -842,11 +848,39 @@ static int __devinit detect_sscape(struct soundscape *s, long wss_io) if (s->type != SSCAPE_VIVO && (d & 0x9f) != 0x0e) goto _done; d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f; sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0); if (s->ic_type == IC_OPUS) activate_ad1845_unsafe(s->io_base); if (s->type == SSCAPE_VIVO) wss_io += 4; d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f; sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0); /* wait for WSS codec */ for (d = 0; d < 500; d++) { if ((inb(wss_io) & 0x80) == 0) break; spin_unlock_irqrestore(&s->lock, flags); msleep(1); spin_lock_irqsave(&s->lock, flags); } snd_printd(KERN_INFO "init delay = %d ms\n", d); if ((inb(wss_io) & 0x80) != 0) goto _done; if (inb(wss_io + 2) == 0xff) goto _done; d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f; sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d); if ((inb(wss_io) & 0x80) != 0) s->type = MEDIA_FX; d = sscape_read_unsafe(s->io_base, GA_HMCTL_REG) & 0x3f; sscape_write_unsafe(s->io_base, GA_HMCTL_REG, d | 0xc0); /* wait for WSS codec */ for (d = 0; d < 500; d++) { if ((inb(wss_io) & 0x80) == 0) Loading Loading @@ -954,9 +988,6 @@ static int __devinit create_ad1845(struct snd_card *card, unsigned port, if (sscape->type == SSCAPE_VIVO) port += 4; if (dma1 == dma2) dma2 = -1; err = snd_wss_create(card, port, -1, irq, dma1, dma2, WSS_HW_DETECT, WSS_HWSHARE_DMA1, &chip); if (!err) { Loading Loading @@ -1051,21 +1082,7 @@ static int __devinit create_sscape(int dev, struct snd_card *card) struct resource *wss_res; unsigned long flags; int err; /* * Check that the user didn't pass us garbage data ... */ irq_cfg = get_irq_config(irq[dev]); if (irq_cfg == INVALID_IRQ) { snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", irq[dev]); return -ENXIO; } mpu_irq_cfg = get_irq_config(mpu_irq[dev]); if (mpu_irq_cfg == INVALID_IRQ) { printk(KERN_ERR "sscape: Invalid IRQ %d\n", mpu_irq[dev]); return -ENXIO; } const char *name; /* * Grab IO ports that we will need to probe so that we Loading Loading @@ -1109,8 +1126,41 @@ static int __devinit create_sscape(int dev, struct snd_card *card) goto _release_dma; } printk(KERN_INFO "sscape: hardware detected at 0x%x, using IRQ %d, DMA %d\n", sscape->io_base, irq[dev], dma[dev]); switch (sscape->type) { case MEDIA_FX: name = "MediaFX/SoundFX"; break; case SSCAPE: name = "Soundscape"; break; case SSCAPE_PNP: name = "Soundscape PnP"; break; case SSCAPE_VIVO: name = "Soundscape VIVO"; break; default: name = "unknown Soundscape"; break; } printk(KERN_INFO "sscape: %s card detected at 0x%x, using IRQ %d, DMA %d\n", name, sscape->io_base, irq[dev], dma[dev]); /* * Check that the user didn't pass us garbage data ... */ irq_cfg = get_irq_config(sscape->type, irq[dev]); if (irq_cfg == INVALID_IRQ) { snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", irq[dev]); return -ENXIO; } mpu_irq_cfg = get_irq_config(sscape->type, mpu_irq[dev]); if (mpu_irq_cfg == INVALID_IRQ) { printk(KERN_ERR "sscape: Invalid IRQ %d\n", mpu_irq[dev]); return -ENXIO; } if (sscape->type != SSCAPE_VIVO) { /* Loading Loading @@ -1141,8 +1191,6 @@ static int __devinit create_sscape(int dev, struct snd_card *card) */ spin_lock_irqsave(&sscape->lock, flags); activate_ad1845_unsafe(sscape->io_base); sscape_write_unsafe(sscape->io_base, GA_INTENA_REG, 0x00); /* disable */ sscape_write_unsafe(sscape->io_base, GA_SMCFGA_REG, 0x2e); sscape_write_unsafe(sscape->io_base, GA_SMCFGB_REG, 0x00); Loading @@ -1151,12 +1199,12 @@ static int __devinit create_sscape(int dev, struct snd_card *card) * Enable and configure the DMA channels ... */ sscape_write_unsafe(sscape->io_base, GA_DMACFG_REG, 0x50); dma_cfg = (sscape->ic_type == IC_ODIE ? 0x70 : 0x40); dma_cfg = (sscape->ic_type == IC_OPUS ? 0x40 : 0x70); sscape_write_unsafe(sscape->io_base, GA_DMAA_REG, dma_cfg); sscape_write_unsafe(sscape->io_base, GA_DMAB_REG, 0x20); sscape_write_unsafe(sscape->io_base, GA_INTCFG_REG, 0xf0 | (mpu_irq_cfg << 2) | mpu_irq_cfg); mpu_irq_cfg |= mpu_irq_cfg << 2; sscape_write_unsafe(sscape->io_base, GA_INTCFG_REG, 0xf0 | mpu_irq_cfg); sscape_write_unsafe(sscape->io_base, GA_CDCFG_REG, 0x09 | DMA_8BIT | (dma[dev] << 4) | (irq_cfg << 1)); Loading