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

📄 opl3sa2.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
				{					/* No recording devices */					return (*(int*)arg = 0);				}			case SOUND_MIXER_CAPS:				if(devc->ad_mixer_dev != -1)				{					return call_ad_mixer(devc, cmd, arg);				}				else				{					*(int*)arg = SOUND_CAP_EXCL_INPUT;					return 0;				}			case SOUND_MIXER_RECSRC:				if(devc->ad_mixer_dev != -1)				{					return call_ad_mixer(devc, cmd, arg);				}				else				{					/* No recording source */					return (*(int*)arg = 0);				}			case SOUND_MIXER_VOLUME:				*(int*)arg = ret_vol_stereo(devc->volume_l,							    devc->volume_r);				return 0;			  			case SOUND_MIXER_MIC:				*(int*)arg = ret_vol_mono(devc->mic);				return 0;			case SOUND_MIXER_BASS:				if(chipset != CHIPSET_OPL3SA2)				{					*(int*)arg = ret_vol_mono(devc->bass);					return 0;				}				else				{					return -EINVAL;				}			  			case SOUND_MIXER_TREBLE:				if(chipset != CHIPSET_OPL3SA2)				{					*(int*)arg = ret_vol_mono(devc->treble);					return 0;				}				else				{					return -EINVAL;				}			  			default:				return -EINVAL;		}	}}static struct mixer_operations opl3sa2_mixer_operations ={	owner:	THIS_MODULE,	id:	"Yamaha",	name:	"", /* hmm? */	ioctl:	opl3sa2_mixer_ioctl};/* End of mixer-related stuff */static inline int __init probe_opl3sa2_mpu(struct address_info *hw_config){	return probe_mpu401(hw_config);}static inline void __init attach_opl3sa2_mpu(struct address_info *hw_config){	attach_mpu401(hw_config, THIS_MODULE);}static inline void __exit unload_opl3sa2_mpu(struct address_info *hw_config){	unload_mpu401(hw_config);}static inline int __init probe_opl3sa2_mss(struct address_info *hw_config){	return probe_ms_sound(hw_config);}static void __init attach_opl3sa2_mss(struct address_info *hw_config){	char mixer_name[64];	/* Create pretty names for mixer stuff */	strncpy(mixer_name, chipset_name, 16);	strncat(mixer_name, " and AD1848 (through MSS)", 64);	strncpy(opl3sa2_mixer_operations.name, chipset_name, 16);	strncat(opl3sa2_mixer_operations.name, "-AD1848", 64);	/* Install master mixer */	devc->ad_mixer_dev = -1;	if((opl3sa2_mixer = sound_install_mixer(MIXER_DRIVER_VERSION,						mixer_name,						&opl3sa2_mixer_operations,						sizeof(struct mixer_operations),						devc)) < 0) 	{		printk(KERN_ERR "Could not install %s master mixer\n", chipset_name);		return;	}	opl3sa2_mixer_reset(devc);	attach_ms_sound(hw_config, THIS_MODULE);	/* Slot 0 */	if(hw_config->slots[0] != -1)	{		/* Did the MSS driver install? */		if(num_mixers == (opl3sa2_mixer + 2))		{			/* The MSS mixer is installed */			devc->ad_mixer_dev = audio_devs[hw_config->slots[0]]->mixer_dev;			/* Reroute mixers appropiately */			AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_CD);			AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_SYNTH);			AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_LINE);		}	}}static inline void __exit unload_opl3sa2_mss(struct address_info *hw_config){	unload_ms_sound(hw_config);}static int __init probe_opl3sa2(struct address_info *hw_config){	unsigned char version = 0;	char tag;	/*	 * Verify that the I/O port range is free.	 */	if(check_region(hw_config->io_base, 2))	{	    printk(KERN_ERR		   "%s: Control I/O port 0x%03x not free\n",		   __FILE__,		   hw_config->io_base);	    return 0;	}	/*	 * Determine chipset type (SA2, SA3, or SAx)	 */	/*	 * Look at chipset version in lower 3 bits of index 0x0A, miscellaneous	 */	opl3sa2_read(hw_config->io_base,		     OPL3SA2_MISC,		     (unsigned char*) &version);	version &= 0x07;	/* Match version number to appropiate chipset */	if(version & CHIPSET_OPL3SAX)	{		chipset = CHIPSET_OPL3SAX;		tag = 'x';		printk(KERN_INFO "Found OPL3-SAx (YMF719)\n");	}	else	{ 		if(version & CHIPSET_OPL3SA3)		{			chipset = CHIPSET_OPL3SA3;			tag = '3';			printk(KERN_INFO "Found OPL3-SA3 (YMF715)\n");		}		else		{			if(version & CHIPSET_OPL3SA2)			{				chipset = CHIPSET_OPL3SA2;				tag = '2';				printk(KERN_INFO "Found OPL3-SA2 (YMF711)\n");			}			else			{				chipset = CHIPSET_UNKNOWN;				tag = '?';				printk(KERN_ERR				       "Unknown Yamaha audio controller version\n");				printk(KERN_INFO				       "%s: chipset version = %x\n",				       __FILE__,				       version);			}		}	}	if(chipset != CHIPSET_UNKNOWN)	{		/* Generate a pretty name */		sprintf(chipset_name, "OPL3-SA%c", tag);		return 1;	}	return 0;}static void __init attach_opl3sa2(struct address_info *hw_config){   	request_region(hw_config->io_base, 2, chipset_name);	devc->cfg_port = hw_config->io_base;}static void __exit unload_opl3sa2(struct address_info *hw_config){        /* Release control ports */	release_region(hw_config->io_base, 2);	/* Unload mixer */	if(opl3sa2_mixer >= 0)		sound_unload_mixerdev(opl3sa2_mixer);}static struct address_info cfg;static struct address_info cfg2;static struct address_info cfg_mpu;static int __initdata io	= -1;static int __initdata mss_io	= -1;static int __initdata mpu_io	= -1;static int __initdata irq	= -1;static int __initdata dma	= -1;static int __initdata dma2	= -1;MODULE_PARM(io, "i");MODULE_PARM_DESC(io, "Set i/o base of OPL3-SA2 or SA3 card (usually 0x370)");MODULE_PARM(mss_io, "i");MODULE_PARM_DESC(mss_io, "Set MSS (audio) I/O base (0x530, 0xE80, or other. Address must end in 0 or 4 and must be from 0x530 to 0xF48)");MODULE_PARM(mpu_io, "i");MODULE_PARM_DESC(mpu_io, "Set MIDI I/O base (0x330 or other. Address must be on 4 location boundaries and must be from 0x300 to 0x334)");MODULE_PARM(irq, "i");MODULE_PARM_DESC(mss_irq, "Set MSS (audio) IRQ (5, 7, 9, 10, 11, 12)");MODULE_PARM(dma, "i");MODULE_PARM_DESC(dma, "Set MSS (audio) first DMA channel (0, 1, 3)");MODULE_PARM(dma2, "i");MODULE_PARM_DESC(dma2, "Set MSS (audio) second DMA channel (0, 1, 3)");MODULE_DESCRIPTION("Module for OPL3-SA2 and SA3 sound cards (uses AD1848 MSS driver).");MODULE_AUTHOR("Scott Murray <scottm@interlog.com>");/* * Install a OPL3SA2 based card. * * Need to have ad1848 and mpu401 loaded ready. */static int __init init_opl3sa2(void){        int i;        /* Our own config: */        cfg.io_base = io;	cfg.irq     = irq;	cfg.dma     = dma;	cfg.dma2    = dma2;	        /* The MSS config: */	cfg2.io_base      = mss_io;	cfg2.irq          = irq;	cfg2.dma          = dma;	cfg2.dma2         = dma2;	cfg2.card_subtype = 1;      /* No IRQ or DMA setup */	cfg_mpu.io_base       = mpu_io;	cfg_mpu.irq           = irq;	cfg_mpu.dma           = dma;	cfg_mpu.always_detect = 1;  /* It's there, so use shared IRQs */	if(cfg.io_base == -1 || cfg.irq == -1 || cfg.dma == -1 || cfg.dma2 == -1 || cfg2.io_base == -1) {		printk(KERN_ERR "opl3sa2: io, mss_io, irq, dma, and dma2 must be set.\n");		return -EINVAL;	}	/* Call me paranoid: */	for(i = 0; i < 6; i++)	{		cfg.slots[i] = cfg2.slots[i] = cfg_mpu.slots[i] = -1;	}	if(probe_opl3sa2(&cfg) == 0)	{		return -ENODEV;	}	if(probe_opl3sa2_mss(&cfg2) == 0)	{		return -ENODEV;	}	attach_opl3sa2(&cfg);	attach_opl3sa2_mss(&cfg2);	if(cfg_mpu.io_base != -1) {		if(probe_opl3sa2_mpu(&cfg_mpu)) {			attach_opl3sa2_mpu(&cfg_mpu);		}	}	return 0;}static void __exit cleanup_opl3sa2(void){        if(cfg_mpu.slots[1] != -1) {		unload_opl3sa2_mpu(&cfg_mpu);	}	unload_opl3sa2_mss(&cfg2);	unload_opl3sa2(&cfg);}module_init(init_opl3sa2);module_exit(cleanup_opl3sa2);#ifndef MODULEstatic int __init setup_opl3sa2(char *str){	/* io, irq, dma, dma2 */	int ints[7];		str = get_options(str, ARRAY_SIZE(ints), ints);		io	= ints[1];	irq	= ints[2];	dma	= ints[3];	dma2	= ints[4];	mss_io	= ints[5];	mpu_io	= ints[6];	return 1;}__setup("opl3sa2=", setup_opl3sa2);#endif

⌨️ 快捷键说明

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