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

📄 ad1848.c

📁 iis s3c2410-uda1341语音系统的 开发
💻 C
📖 第 1 页 / 共 5 页
字号:
void ad1848_unload(int io_base, int irq, int dma_playback, int dma_capture, int share_dma){	int i, mixer, dev = 0;	ad1848_info *devc = NULL;	for (i = 0; devc == NULL && i < nr_ad1848_devs; i++)	{		if (adev_info[i].base == io_base)		{			devc = &adev_info[i];			dev = devc->dev_no;		}	}			if (devc != NULL)	{		if(audio_devs[dev]->portc!=NULL)			kfree(audio_devs[dev]->portc);		release_region(devc->base, 4);		if (!share_dma)		{			if (devc->irq > 0) /* There is no point in freeing irq, if it wasn't allocated */				free_irq(devc->irq, (void *)devc->dev_no);			sound_free_dma(dma_playback);			if (dma_playback != dma_capture)				sound_free_dma(dma_capture);		}		mixer = audio_devs[devc->dev_no]->mixer_dev;		if(mixer>=0)			sound_unload_mixerdev(mixer);		if (devc->pmdev)			pm_unregister(devc->pmdev);		nr_ad1848_devs--;		for ( ; i < nr_ad1848_devs ; i++)			adev_info[i] = adev_info[i+1];	}	else		printk(KERN_ERR "ad1848: Can't find device to be unloaded. Base=%x\n", io_base);}void adintr(int irq, void *dev_id, struct pt_regs *dummy){	unsigned char status;	ad1848_info *devc;	int dev;	int alt_stat = 0xff;	unsigned char c930_stat = 0;	int cnt = 0;	dev = (int)dev_id;	devc = (ad1848_info *) audio_devs[dev]->devc;interrupt_again:		/* Jump back here if int status doesn't reset */	status = inb(io_Status(devc));	if (status == 0x80)		printk(KERN_DEBUG "adintr: Why?\n");	if (devc->model == MD_1848)		outb((0), io_Status(devc));	/* Clear interrupt status */	if (status & 0x01)	{		if (devc->model == MD_C930)		{		/* 82C930 has interrupt status register in MAD16 register MC11 */			unsigned long   flags;			save_flags(flags);			cli();			/* 0xe0e is C930 address port			 * 0xe0f is C930 data port			 */			outb(11, 0xe0e);			c930_stat = inb(0xe0f);			outb((~c930_stat), 0xe0f);			restore_flags(flags);			alt_stat = (c930_stat << 2) & 0x30;		}		else if (devc->model != MD_1848)		{			alt_stat = ad_read(devc, 24);			ad_write(devc, 24, ad_read(devc, 24) & ~alt_stat);	/* Selective ack */		}		if ((devc->open_mode & OPEN_READ) && (devc->audio_mode & PCM_ENABLE_INPUT) && (alt_stat & 0x20))		{			DMAbuf_inputintr(devc->record_dev);		}		if ((devc->open_mode & OPEN_WRITE) && (devc->audio_mode & PCM_ENABLE_OUTPUT) &&		      (alt_stat & 0x10))		{			DMAbuf_outputintr(devc->playback_dev, 1);		}		if (devc->model != MD_1848 && (alt_stat & 0x40))	/* Timer interrupt */		{			devc->timer_ticks++;#ifndef EXCLUDE_TIMERS			if (timer_installed == dev && devc->timer_running)				sound_timer_interrupt();#endif		}	}/* * Sometimes playback or capture interrupts occur while a timer interrupt * is being handled. The interrupt will not be retriggered if we don't * handle it now. Check if an interrupt is still pending and restart * the handler in this case. */	if (inb(io_Status(devc)) & 0x01 && cnt++ < 4)	{		  goto interrupt_again;	}}/* *	Experimental initialization sequence for the integrated sound system *	of the Compaq Deskpro M. */static int init_deskpro_m(struct address_info *hw_config){	unsigned char   tmp;	if ((tmp = inb(0xc44)) == 0xff)	{		DDB(printk("init_deskpro_m: Dead port 0xc44\n"));		return 0;	}	outb(0x10, 0xc44);	outb(0x40, 0xc45);	outb(0x00, 0xc46);	outb(0xe8, 0xc47);	outb(0x14, 0xc44);	outb(0x40, 0xc45);	outb(0x00, 0xc46);	outb(0xe8, 0xc47);	outb(0x10, 0xc44);	return 1;}/* *	Experimental initialization sequence for the integrated sound system *	of Compaq Deskpro XL. */static int init_deskpro(struct address_info *hw_config){	unsigned char   tmp;	if ((tmp = inb(0xc44)) == 0xff)	{		DDB(printk("init_deskpro: Dead port 0xc44\n"));		return 0;	}	outb((tmp | 0x04), 0xc44);	/* Select bank 1 */	if (inb(0xc44) != 0x04)	{		DDB(printk("init_deskpro: Invalid bank1 signature in port 0xc44\n"));		return 0;	}	/*	 * OK. It looks like a Deskpro so let's proceed.	 */	/*	 * I/O port 0xc44 Audio configuration register.	 *	 * bits 0xc0:   Audio revision bits	 *              0x00 = Compaq Business Audio	 *              0x40 = MS Sound System Compatible (reset default)	 *              0x80 = Reserved	 *              0xc0 = Reserved	 * bit 0x20:    No Wait State Enable	 *              0x00 = Disabled (reset default, DMA mode)	 *              0x20 = Enabled (programmed I/O mode)	 * bit 0x10:    MS Sound System Decode Enable	 *              0x00 = Decoding disabled (reset default)	 *              0x10 = Decoding enabled	 * bit 0x08:    FM Synthesis Decode Enable	 *              0x00 = Decoding Disabled (reset default)	 *              0x08 = Decoding enabled	 * bit 0x04     Bank select	 *              0x00 = Bank 0	 *              0x04 = Bank 1	 * bits 0x03    MSS Base address	 *              0x00 = 0x530 (reset default)	 *              0x01 = 0x604	 *              0x02 = 0xf40	 *              0x03 = 0xe80	 */#ifdef DEBUGXL	/* Debug printing */	printk("Port 0xc44 (before): ");	outb((tmp & ~0x04), 0xc44);	printk("%02x ", inb(0xc44));	outb((tmp | 0x04), 0xc44);	printk("%02x\n", inb(0xc44));#endif	/* Set bank 1 of the register */	tmp = 0x58;		/* MSS Mode, MSS&FM decode enabled */	switch (hw_config->io_base)	{		case 0x530:			tmp |= 0x00;			break;		case 0x604:			tmp |= 0x01;			break;		case 0xf40:			tmp |= 0x02;			break;		case 0xe80:			tmp |= 0x03;			break;		default:			DDB(printk("init_deskpro: Invalid MSS port %x\n", hw_config->io_base));			return 0;	}	outb((tmp & ~0x04), 0xc44);	/* Write to bank=0 */#ifdef DEBUGXL	/* Debug printing */	printk("Port 0xc44 (after): ");	outb((tmp & ~0x04), 0xc44);	/* Select bank=0 */	printk("%02x ", inb(0xc44));	outb((tmp | 0x04), 0xc44);	/* Select bank=1 */	printk("%02x\n", inb(0xc44));#endif	/*	 * I/O port 0xc45 FM Address Decode/MSS ID Register.	 *	 * bank=0, bits 0xfe:   FM synthesis Decode Compare bits 7:1 (default=0x88)	 * bank=0, bit 0x01:    SBIC Power Control Bit	 *                      0x00 = Powered up	 *                      0x01 = Powered down	 * bank=1, bits 0xfc:   MSS ID (default=0x40)	 */#ifdef DEBUGXL	/* Debug printing */	printk("Port 0xc45 (before): ");	outb((tmp & ~0x04), 0xc44);	/* Select bank=0 */	printk("%02x ", inb(0xc45));	outb((tmp | 0x04), 0xc44);	/* Select bank=1 */	printk("%02x\n", inb(0xc45));#endif	outb((tmp & ~0x04), 0xc44);	/* Select bank=0 */	outb((0x88), 0xc45);	/* FM base 7:0 = 0x88 */	outb((tmp | 0x04), 0xc44);	/* Select bank=1 */	outb((0x10), 0xc45);	/* MSS ID = 0x10 (MSS port returns 0x04) */#ifdef DEBUGXL	/* Debug printing */	printk("Port 0xc45 (after): ");	outb((tmp & ~0x04), 0xc44);	/* Select bank=0 */	printk("%02x ", inb(0xc45));	outb((tmp | 0x04), 0xc44);	/* Select bank=1 */	printk("%02x\n", inb(0xc45));#endif	/*	 * I/O port 0xc46 FM Address Decode/Address ASIC Revision Register.	 *	 * bank=0, bits 0xff:   FM synthesis Decode Compare bits 15:8 (default=0x03)	 * bank=1, bits 0xff:   Audio addressing ASIC id	 */#ifdef DEBUGXL	/* Debug printing */	printk("Port 0xc46 (before): ");	outb((tmp & ~0x04), 0xc44);	/* Select bank=0 */	printk("%02x ", inb(0xc46));	outb((tmp | 0x04), 0xc44);	/* Select bank=1 */	printk("%02x\n", inb(0xc46));#endif	outb((tmp & ~0x04), 0xc44);	/* Select bank=0 */	outb((0x03), 0xc46);	/* FM base 15:8 = 0x03 */	outb((tmp | 0x04), 0xc44);	/* Select bank=1 */	outb((0x11), 0xc46);	/* ASIC ID = 0x11 */#ifdef DEBUGXL	/* Debug printing */	printk("Port 0xc46 (after): ");	outb((tmp & ~0x04), 0xc44);	/* Select bank=0 */	printk("%02x ", inb(0xc46));	outb((tmp | 0x04), 0xc44);	/* Select bank=1 */	printk("%02x\n", inb(0xc46));#endif	/*	 * I/O port 0xc47 FM Address Decode Register.	 *	 * bank=0, bits 0xff:   Decode enable selection for various FM address bits	 * bank=1, bits 0xff:   Reserved	 */#ifdef DEBUGXL	/* Debug printing */	printk("Port 0xc47 (before): ");	outb((tmp & ~0x04), 0xc44);	/* Select bank=0 */	printk("%02x ", inb(0xc47));	outb((tmp | 0x04), 0xc44);	/* Select bank=1 */	printk("%02x\n", inb(0xc47));#endif	outb((tmp & ~0x04), 0xc44);	/* Select bank=0 */	outb((0x7c), 0xc47);	/* FM decode enable bits = 0x7c */	outb((tmp | 0x04), 0xc44);	/* Select bank=1 */	outb((0x00), 0xc47);	/* Reserved bank1 = 0x00 */#ifdef DEBUGXL	/* Debug printing */	printk("Port 0xc47 (after): ");	outb((tmp & ~0x04), 0xc44);	/* Select bank=0 */	printk("%02x ", inb(0xc47));	outb((tmp | 0x04), 0xc44);	/* Select bank=1 */	printk("%02x\n", inb(0xc47));#endif	/*	 * I/O port 0xc6f = Audio Disable Function Register	 */#ifdef DEBUGXL	printk("Port 0xc6f (before) = %02x\n", inb(0xc6f));#endif	outb((0x80), 0xc6f);#ifdef DEBUGXL	printk("Port 0xc6f (after) = %02x\n", inb(0xc6f));#endif	return 1;}int probe_ms_sound(struct address_info *hw_config){	unsigned char   tmp;	DDB(printk("Entered probe_ms_sound(%x, %d)\n", hw_config->io_base, hw_config->card_subtype));	if (check_region(hw_config->io_base, 8))	{		printk(KERN_ERR "MSS: I/O port conflict\n");		return 0;	}	if (hw_config->card_subtype == 1)	/* Has no IRQ/DMA registers */	{		/* check_opl3(0x388, hw_config); */		return ad1848_detect(hw_config->io_base + 4, NULL, hw_config->osp);	}	if (deskpro_xl && hw_config->card_subtype == 2)	/* Compaq Deskpro XL */	{		if (!init_deskpro(hw_config))			return 0;	}	if (deskpro_m)	/* Compaq Deskpro M */	{		if (!init_deskpro_m(hw_config))			return 0;	}	/*	   * Check if the IO port returns valid signature. The original MS Sound	   * system returns 0x04 while some cards (AudioTrix Pro for example)	   * return 0x00 or 0x0f.	 */	if ((tmp = inb(hw_config->io_base + 3)) == 0xff)	/* Bus float */	{		  int             ret;		  DDB(printk("I/O address is inactive (%x)\n", tmp));		  if (!(ret = ad1848_detect(hw_config->io_base + 4, NULL, hw_config->osp)))			  return 0;		  return 1;	}	DDB(printk("MSS signature = %x\n", tmp & 0x3f));	if ((tmp & 0x3f) != 0x04 &&	    (tmp & 0x3f) != 0x0f &&	    (tmp & 0x3f) != 0x00)	{		int ret;		MDB(printk(KERN_ERR "No MSS signature detected on port 0x%x (0x%x)\n", hw_config->io_base, (int) inb(hw_config->io_base + 3)));		DDB(printk("Trying to detect codec anyway but IRQ/DMA may not work\n"));		if (!(ret = ad1848_detect(hw_config->io_base + 4, NULL, hw_config->osp)))			return 0;		hw_config->card_subtype = 1;		return 1;	}	if ((hw_config->irq != 5)  &&	    (hw_config->irq != 7)  &&	    (hw_config->irq != 9)  &&	    (hw_config->irq != 10) &&	    (hw_config->irq != 11) &&	    (hw_config->irq != 12))	{		printk(KERN_ERR "MSS: Bad IRQ %d\n", hw_config->irq);		return 0;	}	if (hw_config->dma != 0 && hw_config->dma != 1 && hw_config->dma != 3)	{		  printk(KERN_ERR "MSS: Bad DMA %d\n", hw_config->dma);		  return 0;	}	/*	 * Check that DMA0 is not in use with a 8 bit board.	 */	if (hw_config->dma == 0 && inb(hw_config->io_base + 3) & 0x80)	{		printk(KERN_ERR "MSS: Can't use DMA0 with a 8 bit card/slot\n");		return 0;	}	if (hw_config->irq > 7 && hw_config->irq != 9 && inb(hw_config->io_base + 3) & 0x80)	{		printk(KERN_ERR "MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);		return 0;	}	return ad1848_detect(hw_config->io_base + 4, NULL, hw_config->osp);}void attach_ms_sound(struct address_info *hw_config, struct module *owner){	static signed char interrupt_bits[12] =	{		-1, -1, -1, -1, -1, 0x00, -1, 0x08, -1, 0x10, 0x18, 0x20	};	signed char     bits;	char            dma2_bit = 0;	static char     dma_bits[4] =	{		1, 2, 0, 3	};	int config_port = hw_config->io_base + 0;	int version_port = hw_config->io_base + 3;	int dma = hw_config->dma;	int dma2 = hw_config->dma2;	if (hw_config->card_subtype == 1)	/* Has no IRQ/DMA registers */	{		hw_config->slots[0] = ad1848_init("MS Sound System", hw_config->io_base + 4,						    hw_config->irq,						    hw_config->dma,						    hw_config->dma2, 0, 						    hw_config->osp,						    owner);		request_region(hw_config->io_base, 4, "WSS config");		return;	}	/*	 * Set the IRQ and DMA addresses.	 */	bits = interrupt_bits[hw_config->irq];	if (bits == -1)	{		printk(KERN_ERR "MSS: Bad IRQ %d\n", hw_config->irq);		return;	}	outb((bits | 0x40), config_port);	if ((inb(version_port) & 0x40) == 0)		printk(KERN_ERR "[MSS: IRQ Conflict?]\n");/* * Handle the capture DMA channel */	if (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(KERN_WARNING "MSS: Invalid capture DMA\n");			dma2 = dma;		}	}	else	{		dma2 = dma;	}	hw_config->dma = dma;	hw_config->dma2 = dma2;	outb((bits | dma_bits[dma] | dma2_bit), config_port);	/* Write IRQ+DMA setup */	hw_config->slots[0] = ad1848_init("MS Sound System", hw_config->io_base + 4,					  hw_config->irq,					  dma, dma2, 0,					  hw_config->osp,					  THIS_MODULE);	request_region(hw_config->io_base, 4, "WSS config");}void unload_ms_sound(struct address_info *hw_config){	ad1848_unload(hw_config->io_base + 4,		      

⌨️ 快捷键说明

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