⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gus_irq.c

📁 linux-2.6.15.6
💻 C
字号:
/* *  Routine for IRQ handling from GF1/InterWave chip *  Copyright (c) by Jaroslav Kysela <perex@suse.cz> * * *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 2 of the License, or *   (at your option) any later version. * *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program; if not, write to the Free Software *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA * */#include <sound/driver.h>#include <sound/core.h>#include <sound/info.h>#include <sound/gus.h>#ifdef CONFIG_SND_DEBUG#define STAT_ADD(x)	((x)++)#else#define STAT_ADD(x)	while (0) { ; }#endifirqreturn_t snd_gus_interrupt(int irq, void *dev_id, struct pt_regs *regs){	snd_gus_card_t * 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);		gus->gf1.interrupt_handler_midi_in(gus);	}	if (status & 0x01) {		STAT_ADD(gus->gf1.interrupt_stat_midi_out);		gus->gf1.interrupt_handler_midi_out(gus);	}	if (status & (0x20 | 0x40)) {		unsigned int already, _current_;		unsigned char voice_status, voice;		snd_gus_voice_t *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);		gus->gf1.interrupt_handler_timer1(gus);	}	if (status & 0x08) {		STAT_ADD(gus->gf1.interrupt_stat_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);			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);			gus->gf1.interrupt_handler_dma_read(gus);		}	}	if (--loop > 0)		goto __again;	return IRQ_NONE;}#ifdef CONFIG_SND_DEBUGstatic void snd_gus_irq_info_read(snd_info_entry_t *entry, 				  snd_info_buffer_t * buffer){	snd_gus_card_t *gus;	snd_gus_voice_t *pvoice;	int idx;	gus = entry->private_data;	snd_iprintf(buffer, "midi out = %u\n", gus->gf1.interrupt_stat_midi_out);	snd_iprintf(buffer, "midi in = %u\n", gus->gf1.interrupt_stat_midi_in);	snd_iprintf(buffer, "timer1 = %u\n", gus->gf1.interrupt_stat_timer1);	snd_iprintf(buffer, "timer2 = %u\n", gus->gf1.interrupt_stat_timer2);	snd_iprintf(buffer, "dma write = %u\n", gus->gf1.interrupt_stat_dma_write);	snd_iprintf(buffer, "dma read = %u\n", gus->gf1.interrupt_stat_dma_read);	snd_iprintf(buffer, "voice lost = %u\n", gus->gf1.interrupt_stat_voice_lost);	for (idx = 0; idx < 32; idx++) {		pvoice = &gus->gf1.voices[idx];		snd_iprintf(buffer, "voice %i: wave = %u, volume = %u\n",					idx,					pvoice->interrupt_stat_wave,					pvoice->interrupt_stat_volume);	}}void snd_gus_irq_profile_init(snd_gus_card_t *gus){	snd_info_entry_t *entry;	if (! snd_card_proc_new(gus->card, "gusirq", &entry))		snd_info_set_text_ops(entry, gus, 1024, snd_gus_irq_info_read);}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -