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

📄 mad16.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	for (i = 0; i < 5; i++)	{		if (i > 3)	/* Not a valid port */		{			printk(KERN_ERR "MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base);			return 0;		}		if (valid_ports[i] == hw_config->io_base)		{			tmp |= i << 4;	/* WSS port select bits */			break;		}	}	/*	 * Set optional CD-ROM and joystick settings.	 */	tmp &= ~0x0f;	mad_write(MC1_PORT, tmp);	tmp = mad_read(MC2_PORT);	mad_write(MC2_PORT, tmp);	mad_write(MC3_PORT, 0xf0);	/* Disable SB */	if (board_type == C924)	/* Specific C924 init values */	{		mad_write(MC4_PORT, 0xA0);		mad_write(MC5_PORT, 0x05);		mad_write(MC6_PORT, 0x03);	}	if (!ad1848_detect(hw_config->io_base + 4, &ad_flags, mad16_osp))		return 0;	if (ad_flags & (AD_F_CS4231 | AD_F_CS4248))		cs4231_mode = 0x02;	/* CS4248/CS4231 sync delay switch */	if (board_type == C929)	{		mad_write(MC4_PORT, 0xa2);		mad_write(MC5_PORT, 0xA5 | cs4231_mode);		mad_write(MC6_PORT, 0x03);	/* Disable MPU401 */	}	else	{		mad_write(MC4_PORT, 0x02);		mad_write(MC5_PORT, 0x30 | cs4231_mode);	}	for (i = 0xf8d; i <= 0xf93; i++) if (!c924pnp)		DDB(printk("port %03x after init = %02x\n", i, mad_read(i))) else		DDB(printk("port %03x after init = %02x\n", i-0x80, mad_read(i)));	wss_init(hw_config);	return 1;}static void __init attach_mad16(struct address_info *hw_config){	static signed char     interrupt_bits[12] = {		-1, -1, -1, -1, -1, -1, -1, 0x08, -1, 0x10, 0x18, 0x20	};	signed char bits;	static char     dma_bits[4] = {		1, 2, 0, 3	};	int config_port = hw_config->io_base + 0, version_port = hw_config->io_base + 3;	int ad_flags = 0, dma = hw_config->dma, dma2 = hw_config->dma2;	unsigned char dma2_bit = 0;	already_initialized = 1;	if (!ad1848_detect(hw_config->io_base + 4, &ad_flags, mad16_osp))		return;	/*	 * Set the IRQ and DMA addresses.	 */		if (board_type == C930 || c924pnp)		interrupt_bits[5] = 0x28;	/* Also IRQ5 is possible on C930 */	bits = interrupt_bits[hw_config->irq];	if (bits == -1)		return;	outb((bits | 0x40), config_port);	if ((inb(version_port) & 0x40) == 0)		printk(KERN_ERR "[IRQ Conflict?]\n");	/*	 * Handle the capture DMA channel	 */	if (ad_flags & AD_F_CS4231 && dma2 != -1 && dma2 != dma)	{		if (!((dma == 0 && dma2 == 1) ||			(dma == 1 && dma2 == 0) ||			(dma == 3 && dma2 == 0)))		{		/* Unsupported combination. Try to swap channels */			int tmp = dma;			dma = dma2;			dma2 = tmp;		}		if ((dma == 0 && dma2 == 1) || (dma == 1 && dma2 == 0) ||			(dma == 3 && dma2 == 0))		{			dma2_bit = 0x04;	/* Enable capture DMA */		}		else		{			printk("MAD16: Invalid capture DMA\n");			dma2 = dma;		}	}	else dma2 = dma;	outb((bits | dma_bits[dma] | dma2_bit), config_port);	/* Write IRQ+DMA setup */	hw_config->slots[0] = ad1848_init("MAD16 WSS", hw_config->io_base + 4,					  hw_config->irq,					  dma,					  dma2, 0,					  hw_config->osp,					  THIS_MODULE);	request_region(hw_config->io_base, 4, "MAD16 WSS config");}static int __init probe_mad16_mpu(struct address_info *hw_config){	static int mpu_attached = 0;	unsigned char tmp;	if (!already_initialized)	/* The MSS port must be initialized first */		return 0;	if (mpu_attached)		/* Don't let them call this twice */		return 0;	mpu_attached = 1;	if (board_type < C929)	/* Early chip. No MPU support. Just SB MIDI */	{#ifdef CONFIG_MAD16_OLDCARD		tmp = mad_read(MC3_PORT);		/* 		 * MAD16 SB base is defined by the WSS base. It cannot be changed 		 * alone.		 * Ignore configured I/O base. Use the active setting. 		 */		if (mad_read(MC1_PORT) & 0x20)			hw_config->io_base = 0x240;		else			hw_config->io_base = 0x220;		switch (hw_config->irq)		{			case 5:				tmp = (tmp & 0x3f) | 0x80;				break;			case 7:				tmp = (tmp & 0x3f);				break;			case 11:				tmp = (tmp & 0x3f) | 0x40;				break;			default:				printk(KERN_ERR "mad16/Mozart: Invalid MIDI IRQ\n");				return 0;		}		mad_write(MC3_PORT, tmp | 0x04);		hw_config->driver_use_1 = SB_MIDI_ONLY;		if (!sb_dsp_detect(hw_config, 0, 0, NULL))			return 0;		if (mad_read(MC1_PORT) & 0x20)			hw_config->io_base = 0x240;		else			hw_config->io_base = 0x220;		hw_config->name = "Mad16/Mozart";		sb_dsp_init(hw_config, THIS_MODULE);		return 1;#else		/* assuming all later Mozart cards are identified as		 * either 82C928 or Mozart. If so, following code attempts		 * to set MPU register. TODO - add probing		 */		tmp = mad_read(MC8_PORT);		switch (hw_config->irq)		{			case 5:				tmp |= 0x08;				break;			case 7:				tmp |= 0x10;				break;			case 9:				tmp |= 0x18;				break;			case 10:				tmp |= 0x20;				break;			case 11:				tmp |= 0x28;				break;			default:				printk(KERN_ERR "mad16/MOZART: invalid mpu_irq\n");				return 0;		}		switch (hw_config->io_base)		{			case 0x300:				tmp |= 0x01;				break;			case 0x310:				tmp |= 0x03;				break;			case 0x320:				tmp |= 0x05;				break;			case 0x330:				tmp |= 0x07;				break;			default:				printk(KERN_ERR "mad16/MOZART: invalid mpu_io\n");				return 0;		}		mad_write(MC8_PORT, tmp);	/* write MPU port parameters */		goto probe_401;#endif	}	tmp = mad_read(MC6_PORT) & 0x83;	tmp |= 0x80;		/* MPU-401 enable */	/* Set the MPU base bits */	switch (hw_config->io_base)	{		case 0x300:			tmp |= 0x60;			break;		case 0x310:			tmp |= 0x40;			break;		case 0x320:			tmp |= 0x20;			break;		case 0x330:			tmp |= 0x00;			break;		default:			printk(KERN_ERR "MAD16: Invalid MIDI port 0x%x\n", hw_config->io_base);			return 0;	}	/* Set the MPU IRQ bits */	switch (hw_config->irq)	{		case 5:			tmp |= 0x10;			break;		case 7:			tmp |= 0x18;			break;		case 9:			tmp |= 0x00;			break;		case 10:			tmp |= 0x08;			break;		default:			printk(KERN_ERR "MAD16: Invalid MIDI IRQ %d\n", hw_config->irq);			break;	}				mad_write(MC6_PORT, tmp);	/* Write MPU401 config */#ifndef CONFIG_MAD16_OLDCARDprobe_401:#endif	hw_config->driver_use_1 = SB_MIDI_ONLY;	hw_config->name = "Mad16/Mozart";	return probe_uart401(hw_config, THIS_MODULE);}static void __exit unload_mad16(struct address_info *hw_config){	ad1848_unload(hw_config->io_base + 4,			hw_config->irq,			hw_config->dma,			hw_config->dma2, 0);	release_region(hw_config->io_base, 4);	sound_unload_audiodev(hw_config->slots[0]);}static void __exit unload_mad16_mpu(struct address_info *hw_config){#ifdef CONFIG_MAD16_OLDCARD	if (board_type < C929)	/* Early chip. No MPU support. Just SB MIDI */	{		sb_dsp_unload(hw_config, 0);		return;	}#endif	unload_uart401(hw_config);}static struct address_info cfg;static struct address_info cfg_mpu;static int found_mpu;static int __initdata mpu_io = 0;static int __initdata mpu_irq = 0;static int __initdata io = -1;static int __initdata dma = -1;static int __initdata dma16 = -1; /* Set this for modules that need it */static int __initdata irq = -1;static int __initdata cdtype = 0;static int __initdata cdirq = 0;static int __initdata cdport = 0x340;static int __initdata cddma = -1;static int __initdata opl4 = 0;static int __initdata joystick = 0;MODULE_PARM(mpu_io, "i");MODULE_PARM(mpu_irq, "i");MODULE_PARM(io,"i");MODULE_PARM(dma,"i");MODULE_PARM(dma16,"i");MODULE_PARM(irq,"i");MODULE_PARM(cdtype,"i");MODULE_PARM(cdirq,"i");MODULE_PARM(cdport,"i");MODULE_PARM(cddma,"i");MODULE_PARM(opl4,"i");MODULE_PARM(joystick,"i");MODULE_PARM(debug,"i");static int __initdata dma_map[2][8] ={	{0x03, -1, -1, -1, -1, 0x00, 0x01, 0x02},	{0x03, -1, 0x01, 0x00, -1, -1, -1, -1}};static int __initdata irq_map[16] ={	0x00, -1, -1, 0x0A,	-1, 0x04, -1, 0x08,	-1, 0x10, 0x14, 0x18,	-1, -1, -1, -1};static int __init init_mad16(void){	int dmatype = 0;	printk(KERN_INFO "MAD16 audio driver Copyright (C) by Hannu Savolainen 1993-1996\n");	printk(KERN_INFO "CDROM ");	switch (cdtype)	{		case 0x00:			printk("Disabled");			cdirq = 0;			break;		case 0x02:			printk("Sony CDU31A");			dmatype = 1;			if(cddma == -1) cddma = 3;			break;		case 0x04:			printk("Mitsumi");			dmatype = 0;			if(cddma == -1) cddma = 5;			break;		case 0x06:			printk("Panasonic Lasermate");			dmatype = 1;			if(cddma == -1) cddma = 3;			break;		case 0x08:			printk("Secondary IDE");			dmatype = 0;			if(cddma == -1) cddma = 5;			break;		case 0x0A:			printk("Primary IDE");			dmatype = 0;			if(cddma == -1) cddma = 5;			break;		default:			printk("\n");			printk(KERN_ERR "Invalid CDROM type\n");			return -EINVAL;	} 	/*         *    Build the config words         */        mad16_conf = (joystick ^ 1) | cdtype;	mad16_cdsel = 0;        if (opl4)                mad16_cdsel |= 0x20;	if(cdtype){		if (cddma > 7 || cddma < 0 || dma_map[dmatype][cddma] == -1)		{			printk("\n");			printk(KERN_ERR "Invalid CDROM DMA\n");			return -EINVAL;		}		if (cddma)			printk(", DMA %d", cddma);		else			printk(", no DMA");		if (!cdirq)			printk(", no IRQ");		else if (cdirq < 0 || cdirq > 15 || irq_map[cdirq] == -1)		{		  	printk(", invalid IRQ (disabling)");		  	cdirq = 0;		}		else printk(", IRQ %d", cdirq);		mad16_cdsel |= dma_map[dmatype][cddma];		if (cdtype < 0x08)		{			switch (cdport)			{				case 0x340:					mad16_cdsel |= 0x00;					break;				case 0x330:					mad16_cdsel |= 0x40;					break;				case 0x360:					mad16_cdsel |= 0x80;					break;				case 0x320:					mad16_cdsel |= 0xC0;					break;				default:					printk(KERN_ERR "Unknown CDROM I/O base %d\n", cdport);					return -EINVAL;			}		}		mad16_cdsel |= irq_map[cdirq];	}	printk(".\n");        printk(KERN_INFO "Joystick port ");        if (joystick == 1)                printk("enabled.\n");        else        {                joystick = 0;                printk("disabled.\n");        }	cfg.io_base = io;	cfg.irq = irq;	cfg.dma = dma;	cfg.dma2 = dma16;	if (cfg.io_base == -1 || cfg.dma == -1 || cfg.irq == -1) {		printk(KERN_ERR "I/O, DMA and irq are mandatory\n");		return -EINVAL;	}		if (!probe_mad16(&cfg))		return -ENODEV;	cfg_mpu.io_base = mpu_io;	cfg_mpu.irq = mpu_irq;	attach_mad16(&cfg);	found_mpu = probe_mad16_mpu(&cfg_mpu);	return 0;}static void __exit cleanup_mad16(void){	if (found_mpu)		unload_mad16_mpu(&cfg_mpu);	unload_mad16(&cfg);}module_init(init_mad16);module_exit(cleanup_mad16);#ifndef MODULEstatic int __init setup_mad16(char *str){        /* io, irq */	int ints[7];		str = get_options(str, ARRAY_SIZE(ints), ints);	io	= ints[1];	irq	= ints[2];	dma	= ints[3];	dma16	= ints[4];	mpu_io	= ints[5];	mpu_irq = ints[6];	return 1;}__setup("mad16=", setup_mad16);#endif

⌨️ 快捷键说明

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