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

📄 ymf_sb.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 2 页
字号:
#endif	dma = sb_data[cards].dma;#ifdef YMF_DEBUG	printk(PFX "set DMA address at 0x%x\n",sb_data[cards].dma);#endif	v = 0x0000 | ((dma & 0x03) << 6) | 0x003f;	pci_write_config_word(pcidev, YMFSB_PCIR_LEGCTRL, v);#ifdef YMF_DEBUG	printk(PFX "LEGCTRL: 0x%x\n",v);#endif	switch( pcidev->device ) {	case PCI_DEVICE_ID_YMF724:	case PCI_DEVICE_ID_YMF740:	case PCI_DEVICE_ID_YMF724F:	case PCI_DEVICE_ID_YMF740C:		v = 0x8800 | ((mpuio & 0x03) << 4)			   | ((sbio & 0x03) << 2)			   | (oplio & 0x03);		pci_write_config_word(pcidev, YMFSB_PCIR_ELEGCTRL, v);#ifdef YMF_DEBUG		printk(PFX "ELEGCTRL: 0x%x\n",v);#endif		break;	case PCI_DEVICE_ID_YMF744:	case PCI_DEVICE_ID_YMF754:		v = 0x8800;		pci_write_config_word(pcidev, YMFSB_PCIR_ELEGCTRL, v);#ifdef YMF_DEBUG		printk(PFX "ELEGCTRL: 0x%x\n",v);#endif		pci_write_config_word(pcidev, YMFSB_PCIR_OPLADR, opl3_data[cards].io_base);		pci_write_config_word(pcidev, YMFSB_PCIR_SBADR,  sb_data[cards].io_base);#ifdef SUPPORT_UART401_MIDI		pci_write_config_word(pcidev, YMFSB_PCIR_MPUADR, mpu_data[cards].io_base);#endif		break;	default:		printk(KERN_ERR PFX "Invalid device ID: %d\n",pcidev->device);		return -1;		break;	}	return 0;}/* ---------------------------------------------------------------------- */static void enableDSP( void ){	writeRegDWord( YMFSB_CONFIG, 0x00000001 );	return;}static void disableDSP( void ){	int val;	int i;	val = readRegDWord( YMFSB_CONFIG );	if ( val ) {		writeRegDWord( YMFSB_CONFIG, 0 );	}	i=0;	while( ++i < YMFSB_WORKBITTIMEOUT ) {		val = readRegDWord(YMFSB_STATUS);		if ( (val & 0x00000002) == 0x00000000 ) break;	}	return;}static int __init setupInstruction( struct pci_dev *pcidev ){	int i;	int val;	writeRegDWord( YMFSB_NATIVEDACOUTVOL, 0 ); /* mute dac */	disableDSP();	writeRegDWord( YMFSB_MODE, 0x00010000 );	/* DS-XG Software Reset */	writeRegDWord( YMFSB_MODE,         0x00000000 );	writeRegDWord( YMFSB_MAPOFREC,     0x00000000 );	writeRegDWord( YMFSB_MAPOFEFFECT,  0x00000000 );	writeRegDWord( YMFSB_PLAYCTRLBASE, 0x00000000 );	writeRegDWord( YMFSB_RECCTRLBASE,  0x00000000 );	writeRegDWord( YMFSB_EFFCTRLBASE,  0x00000000 );	val = readRegWord( YMFSB_GLOBALCTRL );	writeRegWord( YMFSB_GLOBALCTRL, (val&~0x0007) );	/* setup DSP instruction code */	for ( i=0 ; i<YMFSB_DSPLENGTH ; i+=4 ) {	  writeRegDWord( YMFSB_DSPINSTRAM+i, DspInst[i>>2] );	}	switch( pcidev->device ) {	case PCI_DEVICE_ID_YMF724:	case PCI_DEVICE_ID_YMF740:		/* setup Control instruction code */		for ( i=0 ; i<YMFSB_CTRLLENGTH ; i+=4 ) {			writeRegDWord( YMFSB_CTRLINSTRAM+i, CntrlInst[i>>2] );		}		break;	case PCI_DEVICE_ID_YMF724F:	case PCI_DEVICE_ID_YMF740C:	case PCI_DEVICE_ID_YMF744:	case PCI_DEVICE_ID_YMF754:		/* setup Control instruction code */		for ( i=0 ; i<YMFSB_CTRLLENGTH ; i+=4 ) {			writeRegDWord( YMFSB_CTRLINSTRAM+i, CntrlInst1E[i>>2] );		}		break;	default:		return -1;	}	enableDSP();	return 0;}/* ---------------------------------------------------------------------- */static int __init ymf7xx_init(struct pci_dev *pcidev){	unsigned short v;	/* Read hardware information */#ifdef YMF_DEBUG	unsigned int   dv;	pci_read_config_word(pcidev, YMFSB_PCIR_VENDORID, &v);	printk(KERN_INFO PFX "Vendor ID = 0x%x\n",v);	pci_read_config_word(pcidev, YMFSB_PCIR_DEVICEID, &v);	printk(KERN_INFO PFX "Device ID = 0x%x\n",v);	pci_read_config_word(pcidev, YMFSB_PCIR_REVISIONID, &v);	printk(KERN_INFO PFX "Revision ID = 0x%x\n",v&0xff);	pci_read_config_dword(pcidev, YMFSB_PCIR_BASEADDR, &dv);	printk(KERN_INFO PFX "Base address = 0x%x\n",dv);	pci_read_config_word(pcidev, YMFSB_PCIR_IRQ, &v);	printk(KERN_INFO PFX "IRQ line = 0x%x\n",v&0xff);#endif	/* enables memory space access / bus mastering */	pci_read_config_word(pcidev, YMFSB_PCIR_CMD, &v);	pci_write_config_word(pcidev, YMFSB_PCIR_CMD, v|0x06);	/* check codec */#ifdef YMF_DEBUG	printk(KERN_INFO PFX "check codec...\n");#endif	if (checkCodec(pcidev)) return -1;	/* setup legacy I/O */#ifdef YMF_DEBUG	printk(KERN_INFO PFX "setup legacy I/O...\n");#endif	if (setupLegacyIO(pcidev)) return -1;		/* setup instruction code */	#ifdef YMF_DEBUG	printk(KERN_INFO PFX "setup instructions...\n");#endif	if (setupInstruction(pcidev)) return -1;	/* AC'97 setup */	#ifdef YMF_DEBUG	printk(KERN_INFO PFX "setup AC'97...\n");#endif	if ( writeAc97(AC97_RESET            ,0x0000) )  /* Reset */		return -1;	if ( writeAc97(AC97_MASTER_VOL_STEREO,0x0000) )  /* Master Volume */		return -1;	v = 31*(100-master_vol)/100;	v = (v<<8 | v)&0x7fff;	if ( writeAc97(AC97_PCMOUT_VOL       ,v     ) )  /* PCM out Volume */		return -1;#ifdef YMF_DEBUG	printk(KERN_INFO PFX "setup Legacy Volume...\n");#endif	/* Legacy Audio Output Volume L & R ch */	writeRegDWord( YMFSB_LEGACYOUTVOL, 0x3fff3fff );#ifdef YMF_DEBUG	printk(KERN_INFO PFX "setup SPDIF output control...\n");#endif	/* SPDIF Output control */	v = spdif_out != 0 ? 0x0001 : 0x0000;	writeRegWord( YMFSB_SPDIFOUTCTRL, v );	/* no copyright protection, 	   sample-rate converted,	   re-recorded software comercially available (the 1st generation),	   original */	writeRegWord( YMFSB_SPDIFOUTSTATUS, 0x9a04 );	return 0;}/* ---------------------------------------------------------------------- */static void __init ymf7xxsb_attach_sb(struct address_info *hw_config){	if(!sb_dsp_init(hw_config, THIS_MODULE))		hw_config->slots[0] = -1;}static int __init ymf7xxsb_probe_sb(struct address_info *hw_config){	if (check_region(hw_config->io_base, 16))	{		printk(KERN_DEBUG PFX "SBPro port 0x%x is already in use\n",		       hw_config->io_base);		return 0;	}	return sb_dsp_detect(hw_config, SB_PCI_YAMAHA, 0, NULL);}static void ymf7xxsb_unload_sb(struct address_info *hw_config, int unload_mpu){	if(hw_config->slots[0]!=-1)		sb_dsp_unload(hw_config, unload_mpu);}/* ---------------------------------------------------------------------- */enum chip_types {	CH_YMF724 = 0,	CH_YMF724F,	CH_YMF740,	CH_YMF740C,	CH_YMF744,	CH_YMF754,};/* directly indexed by chip_types enum above *//* note we keep this a struct to ease adding * other per-board or per-chip info here */struct {	const char           *devicename;} devicetable[] __initdata = {	{ "YMF724A-E" },	{ "YMF724F" },	{ "YMF740A-B" },	{ "YMF740C" },	{ "YMF744" },	{ "YMF754" },};static struct pci_device_id ymf7xxsb_pci_tbl[] __initdata = {	{ PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF724,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF724 },	{ PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF724F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF724F },	{ PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF740,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF740 },	{ PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF740C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF740C },	{ PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF744,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF744 },	{ PCI_VENDOR_ID_YAMAHA, PCI_DEVICE_ID_YMF754,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_YMF754 },	{ 0, }};MODULE_DEVICE_TABLE(pci, ymf7xxsb_pci_tbl);static int __init ymf7xxsb_init_one (struct pci_dev *pcidev, const struct pci_device_id *ent){	const char	*devicename;	unsigned long   iobase;	if (cards == MAX_CARDS) {	  	printk (KERN_DEBUG PFX "maximum number of cards reached\n");		return -ENODEV;	}	if ( pcidev->irq == 0 ) return -ENODEV;	iobase = pci_resource_start (pcidev, 0);	if ( iobase == 0x00000000 ) return -ENODEV;	devicename = devicetable[ent->driver_data].devicename;	/* remap memory mapped I/O onto kernel virtual memory */	if ( (ymfbase[cards] = ioremap_nocache(iobase, YMFSB_REGSIZE)) == 0 )	{		printk(KERN_ERR PFX "ioremap (0x%lx) returns zero\n", iobase);		return -ENODEV;	}	printk(KERN_INFO PFX "found %s at 0x%lx\n", devicename, iobase);#ifdef YMF_DEBUG	printk(KERN_INFO PFX "remappling to 0x%p\n", ymfbase[cards]);#endif	memset (&sb_data[cards], 0, sizeof (struct address_info));	memset (&opl3_data[cards], 0, sizeof (struct address_info));#ifdef SUPPORT_UART401_MIDI	memset (&mpu_data[cards], 0, sizeof (struct address_info));#endif	sb_data[cards].name   = YMFSB_CARD_NAME;	opl3_data[cards].name = YMFSB_CARD_NAME;#ifdef SUPPORT_UART401_MIDI	mpu_data[cards].name  = YMFSB_CARD_NAME;#endif	sb_data[cards].card_subtype = MDL_YMPCI;	if ( io == 0 ) io      = 0x220;	sb_data[cards].io_base = io;	sb_data[cards].irq     = pcidev->irq;	sb_data[cards].dma     = dma;	if ( synth_io == 0 ) synth_io = 0x388;	opl3_data[cards].io_base = synth_io;	opl3_data[cards].irq     = -1;#ifdef SUPPORT_UART401_MIDI	if ( mpu_io == 0 ) mpu_io = 0x330;	mpu_data[cards].io_base = mpu_io;	mpu_data[cards].irq     = -1;#endif	if ( ymf7xx_init(pcidev) ) {		printk (KERN_ERR PFX			"Cannot initialize %s, aborting\n",			devicename);		return -ENODEV;	}	/* register legacy SoundBlaster Pro */	if (!ymf7xxsb_probe_sb(&sb_data[cards])) {		printk (KERN_ERR PFX			"SB probe at 0x%X failed, aborting\n",			io);		return -ENODEV;	}	ymf7xxsb_attach_sb (&sb_data[cards]);#ifdef SUPPORT_UART401_MIDI	/* register legacy MIDI */	if ( mpu_io > 0 && 0)	{		if (!ymf7xxsb_probe_midi (&mpu_data[cards], THIS_MODULE)) {			printk (KERN_ERR PFX				"MIDI probe @ 0x%X failed, aborting\n",				mpu_io);			ymf7xxsb_unload_sb (&sb_data[cards], 0);			return -ENODEV;		}	}#endif	/* register legacy OPL3 */	cards++;		return 0;}static struct pci_driver ymf7xxsb_driver = {	name:		"ymf7xxsb",	id_table:	ymf7xxsb_pci_tbl,	probe:		ymf7xxsb_init_one,};static int __init init_ymf7xxsb_module(void){	int i;	if ( master_vol < 0 ) master_vol  = 50;	if ( master_vol > 100 ) master_vol = 100;	for (i=0 ; i<MAX_CARDS ; i++ )		ymfbase[i] = NULL;	i = pci_module_init (&ymf7xxsb_driver);	if (i < 0)		return i;	printk (KERN_INFO PFX YMFSB_CARD_NAME " loaded\n");		return 0;}static void __exit free_iomaps( void ){	int i;	for ( i=0 ; i<MAX_CARDS ; i++ ) {		if ( ymfbase[i]!=NULL )			iounmap(ymfbase[i]);	}	return;}static void __exit cleanup_ymf7xxsb_module(void){	int i;		for (i = 0; i < cards; i++) {#ifdef SUPPORT_UART401_MIDI		ymf7xxsb_unload_sb (&sb_data[i], 0);		ymf7xxsb_unload_midi (&mpu_data[i]);#else		ymf7xxsb_unload_sb (&sb_data[i], 1);#endif	}	free_iomaps();	pci_unregister_driver(&ymf7xxsb_driver);}MODULE_AUTHOR("Daisuke Nagano, breeze.nagano@nifty.ne.jp");MODULE_DESCRIPTION("YMF7xx Legacy Audio Driver");module_init(init_ymf7xxsb_module);module_exit(cleanup_ymf7xxsb_module);

⌨️ 快捷键说明

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