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

📄 gus_card.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
字号:
/* * sound/gus_card.c * * Detection routine for the Gravis Ultrasound. * * Copyright (C) by Hannu Savolainen 1993-1997 * * * Frank van de Pol : Fixed GUS MAX interrupt handling, enabled simultanious *                    usage of CS4231A codec, GUS wave and MIDI for GUS MAX. * Christoph Hellwig: Adapted to module_init/module_exit, simple cleanups. * * Status: *              Tested...  */       #include <linux/config.h>#include <linux/init.h>#include <linux/module.h>#include "sound_config.h"#include "gus.h"#include "gus_hw.h"void            gusintr(int irq, void *dev_id, struct pt_regs *dummy);int             gus_base = 0, gus_irq = 0, gus_dma = 0;int             gus_no_wave_dma = 0; extern int      gus_wave_volume;extern int      gus_pcm_volume;extern int      have_gus_max;int             gus_pnp_flag = 0;#ifdef CONFIG_SOUND_GUS16static int      db16 = 0;	/* Has a Gus16 AD1848 on it */#endifstatic void __init attach_gus(struct address_info *hw_config){	gus_wave_init(hw_config);	request_region(hw_config->io_base, 16, "GUS");	request_region(hw_config->io_base + 0x100, 12, "GUS");	/* 0x10c-> is MAX */	if (sound_alloc_dma(hw_config->dma, "GUS"))		printk(KERN_ERR "gus_card.c: Can't allocate DMA channel %d\n", hw_config->dma);	if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)		if (sound_alloc_dma(hw_config->dma2, "GUS(2)"))			printk(KERN_ERR "gus_card.c: Can't allocate DMA channel %d\n", hw_config->dma2);	gus_midi_init(hw_config);	if(request_irq(hw_config->irq, gusintr, 0,  "Gravis Ultrasound", hw_config)<0)		printk(KERN_ERR "gus_card.c: Unable to allocate IRQ %d\n", hw_config->irq);	return;}static int __init probe_gus(struct address_info *hw_config){	int             irq;	int             io_addr;	if (hw_config->card_subtype == 1)		gus_pnp_flag = 1;	irq = hw_config->irq;	if (hw_config->card_subtype == 0)	/* GUS/MAX/ACE */		if (irq != 3 && irq != 5 && irq != 7 && irq != 9 &&		    irq != 11 && irq != 12 && irq != 15)		  {			  printk(KERN_ERR "GUS: Unsupported IRQ %d\n", irq);			  return 0;		  }	if (check_region(hw_config->io_base, 16))		printk(KERN_ERR "GUS: I/O range conflict (1)\n");	else if (check_region(hw_config->io_base + 0x100, 16))		printk(KERN_ERR "GUS: I/O range conflict (2)\n");	else if (gus_wave_detect(hw_config->io_base))		return 1;#ifndef EXCLUDE_GUS_IODETECT	/*	 * Look at the possible base addresses (0x2X0, X=1, 2, 3, 4, 5, 6)	 */	for (io_addr = 0x210; io_addr <= 0x260; io_addr += 0x10)		if (io_addr != hw_config->io_base)	/*							 * Already tested							 */			if (!check_region(io_addr, 16))				if (!check_region(io_addr + 0x100, 16))					if (gus_wave_detect(io_addr))					  {						  hw_config->io_base = io_addr;						  return 1;					  }#endif	printk("NO GUS card found !\n");	return 0;}static void __exit unload_gus(struct address_info *hw_config){	DDB(printk("unload_gus(%x)\n", hw_config->io_base));	gus_wave_unload(hw_config);	release_region(hw_config->io_base, 16);	release_region(hw_config->io_base + 0x100, 12);		/* 0x10c-> is MAX */	free_irq(hw_config->irq, hw_config);	sound_free_dma(hw_config->dma);	if (hw_config->dma2 != -1 && hw_config->dma2 != hw_config->dma)		sound_free_dma(hw_config->dma2);}void gusintr(int irq, void *dev_id, struct pt_regs *dummy){	unsigned char src;	extern int gus_timer_enabled;	sti();#ifdef CONFIG_SOUND_GUSMAX	if (have_gus_max) {		struct address_info *hw_config = dev_id;		adintr(irq, (void *)hw_config->slots[1], NULL);	}#endif#ifdef CONFIG_SOUND_GUS16	if (db16) {		struct address_info *hw_config = dev_id;		adintr(irq, (void *)hw_config->slots[3], NULL);	}#endif	while (1)	{		if (!(src = inb(u_IrqStatus)))			return;		if (src & DMA_TC_IRQ)		{			guswave_dma_irq();		}		if (src & (MIDI_TX_IRQ | MIDI_RX_IRQ))		{			gus_midi_interrupt(0);		}		if (src & (GF1_TIMER1_IRQ | GF1_TIMER2_IRQ))		{			if (gus_timer_enabled)				sound_timer_interrupt();			gus_write8(0x45, 0);	/* Ack IRQ */			gus_timer_command(4, 0x80);		/* Reset IRQ flags */		}		if (src & (WAVETABLE_IRQ | ENVELOPE_IRQ))			gus_voice_irq();	}}/* *	Some extra code for the 16 bit sampling option */#ifdef CONFIG_SOUND_GUS16static int __init probe_gus_db16(struct address_info *hw_config){	return ad1848_detect(hw_config->io_base, NULL, hw_config->osp);}static void __init attach_gus_db16(struct address_info *hw_config){	gus_pcm_volume = 100;	gus_wave_volume = 90;	hw_config->slots[3] = ad1848_init("GUS 16 bit sampling", hw_config->io_base,					  hw_config->irq,					  hw_config->dma,					  hw_config->dma, 0,					  hw_config->osp,					  THIS_MODULE);}static void __exit unload_gus_db16(struct address_info *hw_config){	ad1848_unload(hw_config->io_base,		      hw_config->irq,		      hw_config->dma,		      hw_config->dma, 0);	sound_unload_audiodev(hw_config->slots[3]);}#endif#ifdef CONFIG_SOUND_GUS16static int gus16 = 0;#endif#ifdef CONFIG_SOUND_GUSMAXstatic int no_wave_dma = 0;/* Set if no dma is to be used for the                                   wave table (GF1 chip) */#endif/* *    Note DMA2 of -1 has the right meaning in the GUS driver as well *      as here.  */static struct address_info cfg;static int __initdata io = -1;static int __initdata irq = -1;static int __initdata dma = -1;static int __initdata dma16 = -1;	/* Set this for modules that need it */static int __initdata type = 0;		/* 1 for PnP */MODULE_PARM(io, "i");MODULE_PARM(irq, "i");MODULE_PARM(dma, "i");MODULE_PARM(dma16, "i");MODULE_PARM(type, "i");#ifdef CONFIG_SOUND_GUSMAXMODULE_PARM(no_wave_dma, "i");#endif#ifdef CONFIG_SOUND_GUS16MODULE_PARM(db16, "i");MODULE_PARM(gus16, "i");#endifstatic int __init init_gus(void){	printk(KERN_INFO "Gravis Ultrasound audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");	cfg.io_base = io;	cfg.irq = irq;	cfg.dma = dma;	cfg.dma2 = dma16;	cfg.card_subtype = type;#ifdef CONFIG_SOUND_GUSMAX	gus_no_wave_dma = no_wave_dma;#endif	if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {		printk(KERN_ERR "I/O, IRQ, and DMA are mandatory\n");		return -EINVAL;	}#ifdef CONFIG_SOUND_GUS16	if (probe_gus_db16(&cfg) && gus16) {		/* FIXME: This can't work, can it ? -- Christoph */		attach_gus_db16(&cfg);		db16 = 1;	}	#endif	if (!probe_gus(&cfg))		return -ENODEV;	attach_gus(&cfg);	return 0;}static void __exit cleanup_gus(void){#ifdef CONFIG_SOUND_GUS16	if (db16)		unload_gus_db16(&cfg);#endif	unload_gus(&cfg);}module_init(init_gus);module_exit(cleanup_gus);#ifndef MODULEstatic int __init setup_gus(char *str){	/* io, irq, dma, dma2 */	int ints[5];		str = get_options(str, ARRAY_SIZE(ints), ints);		io	= ints[1];	irq	= ints[2];	dma	= ints[3];	dma16	= ints[4];	return 1;}__setup("gus=", setup_gus);#endif

⌨️ 快捷键说明

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