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

📄 opl3sa2.c

📁 iis s3c2410-uda1341语音系统的 开发
💻 C
📖 第 1 页 / 共 3 页
字号:
		unsigned char sys_ctrl;		opl3sa2_read(hw_config->io_base, OPL3SA2_SYS_CTRL, &sys_ctrl);		sys_ctrl = (sys_ctrl & 0xcf) | ((ymode & 3) << 4);		opl3sa2_write(hw_config->io_base, OPL3SA2_SYS_CTRL, sys_ctrl);	}	else {		printk(KERN_ERR "opl3sa2: not setting ymode, it must be one of 0,1,2,3\n");	}}static void __init opl3sa2_set_loopback(struct address_info* hw_config, int loopback){	if(loopback >= 0 && loopback <= 1) {		unsigned char misc;		opl3sa2_read(hw_config->io_base, OPL3SA2_MISC, &misc);		misc = (misc & 0xef) | ((loopback & 1) << 4);		opl3sa2_write(hw_config->io_base, OPL3SA2_MISC, misc);	}	else {		printk(KERN_ERR "opl3sa2: not setting loopback, it must be either 0 or 1\n");	}}static void __exit unload_opl3sa2(struct address_info* hw_config, int card){        /* Release control ports */	release_region(hw_config->io_base, 2);	/* Unload mixer */	if(opl3sa2_mixer[card] >= 0)		sound_unload_mixerdev(opl3sa2_mixer[card]);}#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULEstruct isapnp_device_id isapnp_opl3sa2_list[] __initdata = {	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,		ISAPNP_VENDOR('Y','M','H'), ISAPNP_FUNCTION(0x0021),		0 },	{0}};MODULE_DEVICE_TABLE(isapnp, isapnp_opl3sa2_list);static int __init opl3sa2_isapnp_probe(struct address_info* hw_cfg,				       struct address_info* mss_cfg,				       struct address_info* mpu_cfg,				       int card){	static struct pci_dev* dev;	int ret;	/* Find and configure device */	dev = isapnp_find_dev(NULL,			      ISAPNP_VENDOR('Y','M','H'),			      ISAPNP_FUNCTION(0x0021),			      dev);	if(dev == NULL) {		return -ENODEV;	}	/*	 * If device is active, assume configured with /proc/isapnp	 * and use anyway. Any other way to check this?	 */	ret = dev->prepare(dev);	if(ret && ret != -EBUSY) {		printk(KERN_ERR "opl3sa2: ISA PnP found device that could not be autoconfigured.\n");		return -ENODEV;	}	if(ret == -EBUSY) {		opl3sa2_activated[card] = 1;	}	else {		if(dev->activate(dev) < 0) {			printk(KERN_WARNING "opl3sa2: ISA PnP activate failed\n");			opl3sa2_activated[card] = 0;			return -ENODEV;		}		printk(KERN_DEBUG		       "opl3sa2: Activated ISA PnP card %d (active=%d)\n",		       card, dev->active);	}	/* Our own config: */	hw_cfg->io_base = dev->resource[4].start;	hw_cfg->irq     = dev->irq_resource[0].start;	hw_cfg->dma     = dev->dma_resource[0].start;	hw_cfg->dma2    = dev->dma_resource[1].start;		/* The MSS config: */	mss_cfg->io_base      = dev->resource[1].start;	mss_cfg->irq          = dev->irq_resource[0].start;	mss_cfg->dma          = dev->dma_resource[0].start;	mss_cfg->dma2         = dev->dma_resource[1].start;	mss_cfg->card_subtype = 1; /* No IRQ or DMA setup */	mpu_cfg->io_base       = dev->resource[3].start;	mpu_cfg->irq           = dev->irq_resource[0].start;	mpu_cfg->dma           = -1;	mpu_cfg->dma2          = -1;	mpu_cfg->always_detect = 1; /* It's there, so use shared IRQs */	/* Call me paranoid: */	opl3sa2_clear_slots(hw_cfg);	opl3sa2_clear_slots(mss_cfg);	opl3sa2_clear_slots(mpu_cfg);	opl3sa2_dev[card] = dev;	return 0;}#endif /* CONFIG_ISAPNP || CONFIG_ISAPNP_MODULE *//* End of component functions *//* Power Management support functions */static int opl3sa2_suspend(struct pm_dev *pdev, unsigned char pm_mode){	unsigned long flags;	opl3sa2_mixerdata *p;	if (!pdev)		return -EINVAL;	save_flags(flags);	cli();	p = (opl3sa2_mixerdata *) pdev->data;	switch (pm_mode) {	case 1:		pm_mode = OPL3SA2_PM_MODE1;		break;	case 2:		pm_mode = OPL3SA2_PM_MODE2;		break;	case 3:		pm_mode = OPL3SA2_PM_MODE3;		break;	default:		/* we don't know howto handle this... */		restore_flags(flags);		return -EBUSY;	}	p->in_suspend = 1;	/* its supposed to automute before suspending, so we wont bother */	opl3sa2_read(p->cfg_port, OPL3SA2_PM, &p->pm_reg);	opl3sa2_write(p->cfg_port, OPL3SA2_PM, p->pm_reg | pm_mode);	/* wait a while for the clock oscillator to stabilise */	mdelay(10);	restore_flags(flags);	return 0;}static int opl3sa2_resume(struct pm_dev *pdev){	unsigned long flags;	opl3sa2_mixerdata *p;	if (!pdev)		return -EINVAL;	p = (opl3sa2_mixerdata *) pdev->data;	save_flags(flags);	cli();	/* I don't think this is necessary */	opl3sa2_write(p->cfg_port, OPL3SA2_PM, p->pm_reg);	opl3sa2_mixer_restore(p, p->card);	p->in_suspend = 0;	restore_flags(flags);	return 0;}static int opl3sa2_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data){	unsigned char mode = (unsigned  char)data;	switch (rqst) {		case PM_SUSPEND:			return opl3sa2_suspend(pdev, mode);		case PM_RESUME:			return opl3sa2_resume(pdev);	}	return 0;}/* * Install OPL3-SA2 based card(s). * * Need to have ad1848 and mpu401 loaded ready. */static int __init init_opl3sa2(void){        int card;	int max;	/* Sanitize isapnp and multiple settings */	isapnp = isapnp != 0 ? 1 : 0;	multiple = multiple != 0 ? 1 : 0;		max = (multiple && isapnp) ? OPL3SA2_CARDS_MAX : 1;	for(card = 0; card < max; card++, opl3sa2_cards_num++) {#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE		/*		 * Please remember that even with CONFIG_ISAPNP defined one		 * should still be able to disable PNP support for this 		 * single driver!		 */		if(isapnp && opl3sa2_isapnp_probe(&cfg[card],						  &cfg_mss[card],						  &cfg_mpu[card],						  card) < 0) {			if(!opl3sa2_cards_num)				printk(KERN_INFO "opl3sa2: No PnP cards found\n");			if(io == -1)				break;			isapnp=0;			printk(KERN_INFO "opl3sa2: Search for a card at 0x%d.\n", io);			/* Fall through */		}#endif		/* If a user wants an I/O then assume they meant it */				if(!isapnp) {			if(io == -1 || irq == -1 || dma == -1 ||			   dma2 == -1 || mss_io == -1) {				printk(KERN_ERR				       "opl3sa2: io, mss_io, irq, dma, and dma2 must be set\n");				return -EINVAL;			}			/*			 * Our own config:			 * (NOTE: IRQ and DMA aren't used, so they're set to			 *  give pretty output from conf_printf. :)			 */			cfg[card].io_base = io;			cfg[card].irq     = irq;			cfg[card].dma     = dma;			cfg[card].dma2    = dma2;				/* The MSS config: */			cfg_mss[card].io_base      = mss_io;			cfg_mss[card].irq          = irq;			cfg_mss[card].dma          = dma;			cfg_mss[card].dma2         = dma2;			cfg_mss[card].card_subtype = 1; /* No IRQ or DMA setup */			cfg_mpu[card].io_base       = mpu_io;			cfg_mpu[card].irq           = irq;			cfg_mpu[card].dma           = -1;			cfg_mpu[card].always_detect = 1; /* Use shared IRQs */			/* Call me paranoid: */			opl3sa2_clear_slots(&cfg[card]);			opl3sa2_clear_slots(&cfg_mss[card]);			opl3sa2_clear_slots(&cfg_mpu[card]);		}		if(!probe_opl3sa2(&cfg[card], card) ||		   !probe_opl3sa2_mss(&cfg_mss[card])) {			/*			 * If one or more cards are already registered, don't			 * return an error but print a warning.  Note, this			 * should never really happen unless the hardware or			 * ISA PnP screwed up.			 */			if(opl3sa2_cards_num) {				printk(KERN_WARNING				       "opl3sa2: There was a problem probing one "				       " of the ISA PNP cards, continuing\n");				opl3sa2_cards_num--;				continue;			} else				return -ENODEV;		}		attach_opl3sa2(&cfg[card], card);		conf_printf(chipset_name[card], &cfg[card]);		attach_opl3sa2_mss(&cfg_mss[card]);		attach_opl3sa2_mixer(&cfg[card], card);		opl3sa2_data[card].card = card;		/* register our power management capabilities */		opl3sa2_data[card].pmdev = pm_register(PM_ISA_DEV, card, opl3sa2_pm_callback);		if (opl3sa2_data[card].pmdev)			opl3sa2_data[card].pmdev->data = &opl3sa2_data[card];		/*		 * Set the Yamaha 3D enhancement mode (aka Ymersion) if asked to and		 * it's supported.		 */		if(ymode != -1) {			if(chipset[card] == CHIPSET_OPL3SA2) {				printk(KERN_ERR				       "opl3sa2: ymode not supported on OPL3-SA2\n");			}			else {				opl3sa2_set_ymode(&cfg[card], ymode);			}		}		/* Set A/D input to Mono loopback if asked to. */		if(loopback != -1) {			opl3sa2_set_loopback(&cfg[card], loopback);		}				/* Attach MPU if we've been asked to do so */		if(cfg_mpu[card].io_base != -1) {			if(probe_opl3sa2_mpu(&cfg_mpu[card])) {				attach_opl3sa2_mpu(&cfg_mpu[card]);			}		}	}	if(isapnp) {		printk(KERN_NOTICE "opl3sa2: %d PnP card(s) found.\n", opl3sa2_cards_num);	}	return 0;}/* * Uninstall OPL3-SA2 based card(s). */static void __exit cleanup_opl3sa2(void){	int card;	for(card = 0; card < opl3sa2_cards_num; card++) {		if (opl3sa2_data[card].pmdev)			pm_unregister(opl3sa2_data[card].pmdev);	        if(cfg_mpu[card].slots[1] != -1) {			unload_opl3sa2_mpu(&cfg_mpu[card]);		}		unload_opl3sa2_mss(&cfg_mss[card]);		unload_opl3sa2(&cfg[card], card);#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE		if(opl3sa2_activated[card] && opl3sa2_dev[card]) {			opl3sa2_dev[card]->deactivate(opl3sa2_dev[card]);			printk(KERN_DEBUG			       "opl3sa2: Deactivated ISA PnP card %d (active=%d)\n",			       card, opl3sa2_dev[card]->active);		}#endif	}}module_init(init_opl3sa2);module_exit(cleanup_opl3sa2);#ifndef MODULEstatic int __init setup_opl3sa2(char *str){	/* io, irq, dma, dma2,... */#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE	int ints[11];#else	int ints[9];#endif	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];	ymode    = ints[7];	loopback = ints[8];#if defined CONFIG_ISAPNP || defined CONFIG_ISAPNP_MODULE	isapnp   = ints[9];	multiple = ints[10];#endif	return 1;}__setup("opl3sa2=", setup_opl3sa2);#endif

⌨️ 快捷键说明

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