static int __init snd_gusclassic_detect(snd_gus_card_t * gus) { snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */ #ifdef CONFIG_SND_DEBUG_DETECT { unsigned char d; if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) { snd_printk("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d); return -ENODEV; } } #else if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 0) return -ENODEV; #endif udelay(160); snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* release reset */ udelay(160); #ifdef CONFIG_SND_DEBUG_DETECT { unsigned char d; if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) { snd_printk("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d); return -ENODEV; } } #else if ((snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET) & 0x07) != 1) return -ENODEV; #endif return 0; }
static int __init snd_gusextreme_detect(int dev, struct snd_card *card, struct snd_gus_card * gus, struct snd_es1688 *es1688) { unsigned long flags; unsigned char d; /* * This is main stuff - enable access to GF1 chip... * I'm not sure, if this will work for card which have * ES1688 chip in another place than 0x220. * * I used reverse-engineering in DOSEMU. [--jk] * * ULTRINIT.EXE: * 0x230 = 0,2,3 * 0x240 = 2,0,1 * 0x250 = 2,0,3 * 0x260 = 2,2,1 */ spin_lock_irqsave(&es1688->mixer_lock, flags); snd_es1688_mixer_write(es1688, 0x40, 0x0b); /* don't change!!! */ spin_unlock_irqrestore(&es1688->mixer_lock, flags); spin_lock_irqsave(&es1688->reg_lock, flags); outb(gf1_port[dev] & 0x040 ? 2 : 0, ES1688P(es1688, INIT1)); outb(0, 0x201); outb(gf1_port[dev] & 0x020 ? 2 : 0, ES1688P(es1688, INIT1)); outb(0, 0x201); outb(gf1_port[dev] & 0x010 ? 3 : 1, ES1688P(es1688, INIT1)); spin_unlock_irqrestore(&es1688->reg_lock, flags); udelay(100); snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */ if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) { snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d); return -EIO; } udelay(160); snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* release reset */ udelay(160); if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) { snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d); return -EIO; } return 0; }
static int __devinit snd_gusclassic_detect(struct snd_gus_card *gus) { unsigned char d; snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 0); /* reset GF1 */ if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 0) { snd_printdd("[0x%lx] check 1 failed - 0x%x\n", gus->gf1.port, d); return -ENODEV; } udelay(160); snd_gf1_i_write8(gus, SNDRV_GF1_GB_RESET, 1); /* release reset */ udelay(160); if (((d = snd_gf1_i_look8(gus, SNDRV_GF1_GB_RESET)) & 0x07) != 1) { snd_printdd("[0x%lx] check 2 failed - 0x%x\n", gus->gf1.port, d); return -ENODEV; } return 0; }
irqreturn_t snd_gus_interrupt(int irq, void *dev_id) { struct snd_gus_card * gus = dev_id; unsigned char status; int loop = 100; int handled = 0; __again: status = inb(gus->gf1.reg_irqstat); if (status == 0) return IRQ_RETVAL(handled); handled = 1; // snd_printk("IRQ: status = 0x%x\n", status); if (status & 0x02) { STAT_ADD(gus->gf1.interrupt_stat_midi_in); if (gus->gf1.interrupt_handler_midi_in) gus->gf1.interrupt_handler_midi_in(gus); } if (status & 0x01) { STAT_ADD(gus->gf1.interrupt_stat_midi_out); if (gus->gf1.interrupt_handler_midi_out) gus->gf1.interrupt_handler_midi_out(gus); } if (status & (0x20 | 0x40)) { unsigned int already, _current_; unsigned char voice_status, voice; struct snd_gus_voice *pvoice; already = 0; while (((voice_status = snd_gf1_i_read8(gus, SNDRV_GF1_GB_VOICES_IRQ)) & 0xc0) != 0xc0) { voice = voice_status & 0x1f; _current_ = 1 << voice; if (already & _current_) continue; /* multi request */ already |= _current_; /* mark request */ #if 0 printk("voice = %i, voice_status = 0x%x, voice_verify = %i\n", voice, voice_status, inb(GUSP(gus, GF1PAGE))); #endif pvoice = &gus->gf1.voices[voice]; if (pvoice->use) { if (!(voice_status & 0x80)) { /* voice position IRQ */ STAT_ADD(pvoice->interrupt_stat_wave); pvoice->handler_wave(gus, pvoice); } if (!(voice_status & 0x40)) { /* volume ramp IRQ */ STAT_ADD(pvoice->interrupt_stat_volume); pvoice->handler_volume(gus, pvoice); } } else { STAT_ADD(gus->gf1.interrupt_stat_voice_lost); snd_gf1_i_ctrl_stop(gus, SNDRV_GF1_VB_ADDRESS_CONTROL); snd_gf1_i_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL); } } } if (status & 0x04) { STAT_ADD(gus->gf1.interrupt_stat_timer1); if (gus->gf1.interrupt_handler_timer1) gus->gf1.interrupt_handler_timer1(gus); } if (status & 0x08) { STAT_ADD(gus->gf1.interrupt_stat_timer2); if (gus->gf1.interrupt_handler_timer2) gus->gf1.interrupt_handler_timer2(gus); } if (status & 0x80) { if (snd_gf1_i_look8(gus, SNDRV_GF1_GB_DRAM_DMA_CONTROL) & 0x40) { STAT_ADD(gus->gf1.interrupt_stat_dma_write); if (gus->gf1.interrupt_handler_dma_write) gus->gf1.interrupt_handler_dma_write(gus); } if (snd_gf1_i_look8(gus, SNDRV_GF1_GB_REC_DMA_CONTROL) & 0x40) { STAT_ADD(gus->gf1.interrupt_stat_dma_read); if (gus->gf1.interrupt_handler_dma_read) gus->gf1.interrupt_handler_dma_read(gus); } } if (--loop > 0) goto __again; return IRQ_NONE; }