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

📄 interwave.c

📁 是关于linux2.5.1的完全源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		if (inb(iwcard->gus_status_reg)) {			snd_gus_interrupt(irq, iwcard->gus, regs);			loop++;		}		if (inb(iwcard->pcm_status_reg) & 0x01) {	/* IRQ bit is set? */			snd_cs4231_interrupt(irq, iwcard->cs4231, regs);			loop++;		}	} while (loop && --max > 0);}static void __init snd_interwave_reset(snd_gus_card_t * gus){	snd_gf1_write8(gus, SNDRV_GF1_GB_RESET, 0x00);	udelay(160);	snd_gf1_write8(gus, SNDRV_GF1_GB_RESET, 0x01);	udelay(160);}static void __init snd_interwave_bank_sizes(snd_gus_card_t * gus, int *sizes){	unsigned int idx;	unsigned int local;	unsigned char d;	for (idx = 0; idx < 4; idx++) {		sizes[idx] = 0;		d = 0x55;		for (local = idx << 22;		     local < (idx << 22) + 0x400000;		     local += 0x40000, d++) {			snd_gf1_poke(gus, local, d);			snd_gf1_poke(gus, local + 1, d + 1);#if 0			printk("d = 0x%x, local = 0x%x, local + 1 = 0x%x, idx << 22 = 0x%x\n",			       d,			       snd_gf1_peek(gus, local),			       snd_gf1_peek(gus, local + 1),			       snd_gf1_peek(gus, idx << 22));#endif			if (snd_gf1_peek(gus, local) != d ||			    snd_gf1_peek(gus, local + 1) != d + 1 ||			    snd_gf1_peek(gus, idx << 22) != 0x55)				break;			sizes[idx]++;		}	}#if 0	printk("sizes: %i %i %i %i\n", sizes[0], sizes[1], sizes[2], sizes[3]);#endif}struct rom_hdr {	/* 000 */ unsigned char iwave[8];	/* 008 */ unsigned char rom_hdr_revision;	/* 009 */ unsigned char series_number;	/* 010 */ unsigned char series_name[16];	/* 026 */ unsigned char date[10];	/* 036 */ unsigned short vendor_revision_major;	/* 038 */ unsigned short vendor_revision_minor;	/* 040 */ unsigned int rom_size;	/* 044 */ unsigned char copyright[128];	/* 172 */ unsigned char vendor_name[64];	/* 236 */ unsigned char rom_description[128];	/* 364 */ unsigned char pad[147];	/* 511 */ unsigned char csum;};static void __init snd_interwave_detect_memory(snd_gus_card_t * gus){	static unsigned int lmc[13] =	{		0x00000001, 0x00000101, 0x01010101, 0x00000401,		0x04040401, 0x00040101, 0x04040101, 0x00000004,		0x00000404, 0x04040404, 0x00000010, 0x00001010,		0x10101010	};	int bank_pos, pages;	unsigned int i, lmct;	int psizes[4];	unsigned char csum;	struct rom_hdr romh;	snd_interwave_reset(gus);	snd_gf1_write8(gus, SNDRV_GF1_GB_GLOBAL_MODE, snd_gf1_read8(gus, SNDRV_GF1_GB_GLOBAL_MODE) | 0x01);		/* enhanced mode */	snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x01);	/* DRAM I/O cycles selected */	snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xff10) | 0x004c);	/* ok.. simple test of memory size */	pages = 0;	snd_gf1_poke(gus, 0, 0x55);	snd_gf1_poke(gus, 1, 0xaa);#if 1	if (snd_gf1_peek(gus, 0) == 0x55 && snd_gf1_peek(gus, 1) == 0xaa)#else	if (0)			/* ok.. for testing of 0k RAM */#endif	{		snd_interwave_bank_sizes(gus, psizes);		lmct = (psizes[3] << 24) | (psizes[2] << 16) |		    (psizes[1] << 8) | psizes[0];#if 0		printk("lmct = 0x%08x\n", lmct);#endif		for (i = 0; i < sizeof(lmc) / sizeof(unsigned int); i++)			if (lmct == lmc[i]) {#if 0				printk("found !!! %i\n", i);#endif				snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xfff0) | i);				snd_interwave_bank_sizes(gus, psizes);				break;			}		if (i >= sizeof(lmc) / sizeof(unsigned int) && !gus->gf1.enh_mode)			 snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xfff0) | 2);		for (i = 0; i < 4; i++) {			gus->gf1.mem_alloc.banks_8[i].address =			    gus->gf1.mem_alloc.banks_16[i].address = i << 22;			gus->gf1.mem_alloc.banks_8[i].size =			    gus->gf1.mem_alloc.banks_16[i].size = psizes[i] << 18;			pages += psizes[i];		}	}	pages <<= 18;	gus->gf1.memory = pages;	snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x03);	/* select ROM */	snd_gf1_write16(gus, SNDRV_GF1_GW_MEMORY_CONFIG, (snd_gf1_look16(gus, SNDRV_GF1_GW_MEMORY_CONFIG) & 0xff1f) | (4 << 5));	gus->gf1.rom_banks = 0;	gus->gf1.rom_memory = 0;	for (bank_pos = 0; bank_pos < 16L * 1024L * 1024L; bank_pos += 4L * 1024L * 1024L) {		for (i = 0; i < sizeof(struct rom_hdr); i++)			*(((unsigned char *) &romh) + i) = snd_gf1_peek(gus, i + bank_pos);#ifdef CONFIG_SND_DEBUG_ROM		printk("ROM at 0x%06x = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", bank_pos,		       romh.iwave[0], romh.iwave[1], romh.iwave[2], romh.iwave[3],		       romh.iwave[4], romh.iwave[5], romh.iwave[6], romh.iwave[7]);#endif		if (strncmp(romh.iwave, "INTRWAVE", 8))			continue;	/* first check */		csum = 0;		for (i = 0; i < sizeof(struct rom_hdr) - 1; i++)			csum += *(((unsigned char *) &romh) + i);#ifdef CONFIG_SND_DEBUG_ROM		printk("ROM checksum = 0x%x == 0x%x (computed)\n", romh.csum, (unsigned char) (256 - csum));#endif		if (256 - csum != romh.csum)			continue;	/* not valid rom */		gus->gf1.rom_banks++;		gus->gf1.rom_present |= 1 << (bank_pos >> 22);#ifdef SNDRV_LITTLE_ENDIAN		gus->gf1.rom_memory = romh.rom_size;#else		gus->gf1.rom_memory = ((romh.rom_size >> 24) & 0x000000ff) |				      ((romh.rom_size >>  8) & 0x0000ff00) |				      ((romh.rom_size <<  8) & 0x00ff0000) |				      ((romh.rom_size << 24) & 0xff000000);#endif	}#if 0	if (gus->gf1.rom_memory > 0) {		if (gus->gf1.rom_banks == 1 && gus->gf1.rom_present == 8)			gus->card->type = SNDRV_CARD_TYPE_IW_DYNASONIC;	}#endif	snd_gf1_write8(gus, SNDRV_GF1_GB_MEMORY_CONTROL, 0x00);	/* select RAM */	if (!gus->gf1.enh_mode)		snd_interwave_reset(gus);}static void __init snd_interwave_init(int dev, snd_gus_card_t * gus){	unsigned long flags;	/* ok.. some InterWave specific initialization */	spin_lock_irqsave(&gus->reg_lock, flags);	snd_gf1_write8(gus, SNDRV_GF1_GB_SOUND_BLASTER_CONTROL, 0x00);	snd_gf1_write8(gus, SNDRV_GF1_GB_COMPATIBILITY, 0x1f);	snd_gf1_write8(gus, SNDRV_GF1_GB_DECODE_CONTROL, 0x49);	snd_gf1_write8(gus, SNDRV_GF1_GB_VERSION_NUMBER, 0x11);	snd_gf1_write8(gus, SNDRV_GF1_GB_MPU401_CONTROL_A, 0x00);	snd_gf1_write8(gus, SNDRV_GF1_GB_MPU401_CONTROL_B, 0x30);	snd_gf1_write8(gus, SNDRV_GF1_GB_EMULATION_IRQ, 0x00);	spin_unlock_irqrestore(&gus->reg_lock, flags);	gus->equal_irq = 1;	gus->codec_flag = 1;	gus->interwave = 1;	gus->max_flag = 1;	gus->joystick_dac = snd_joystick_dac[dev];}#define INTERWAVE_CONTROLS (sizeof(snd_interwave_controls)/sizeof(snd_kcontrol_new_t))static snd_kcontrol_new_t snd_interwave_controls[] = {CS4231_DOUBLE("Master Playback Switch", 0, CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 7, 7, 1, 1),CS4231_DOUBLE("Master Playback Volume", 0, CS4231_LINE_LEFT_OUTPUT, CS4231_LINE_RIGHT_OUTPUT, 0, 0, 31, 1),CS4231_DOUBLE("Mic Playback Switch", 0, CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 7, 7, 1, 1),CS4231_DOUBLE("Mic Playback Volume", 0, CS4231_LEFT_MIC_INPUT, CS4231_RIGHT_MIC_INPUT, 0, 0, 31, 1)};static int __init snd_interwave_mixer(cs4231_t *chip){	snd_card_t *card = chip->card;	snd_ctl_elem_id_t id1, id2;	int idx, err;	memset(&id1, 0, sizeof(id1));	memset(&id2, 0, sizeof(id2));	id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;#if 0	/* remove mono microphone controls */	strcpy(id1.name, "Mic Playback Switch");	if ((err = snd_ctl_remove_id(card, &id1)) < 0)		return err;	strcpy(id1.name, "Mic Playback Volume");	if ((err = snd_ctl_remove_id(card, &id1)) < 0)		return err;#endif	/* add new master and mic controls */	for (idx = 0; idx < INTERWAVE_CONTROLS; idx++)		if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_interwave_controls[idx], chip))) < 0)			return err;	snd_cs4231_out(chip, CS4231_LINE_LEFT_OUTPUT, 0x9f);	snd_cs4231_out(chip, CS4231_LINE_RIGHT_OUTPUT, 0x9f);	snd_cs4231_out(chip, CS4231_LEFT_MIC_INPUT, 0x9f);	snd_cs4231_out(chip, CS4231_RIGHT_MIC_INPUT, 0x9f);	/* reassign AUXA to SYNTHESIZER */	strcpy(id1.name, "Aux Playback Switch");	strcpy(id2.name, "Synth Playback Switch");	if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)		return err;	strcpy(id1.name, "Aux Playback Volume");	strcpy(id2.name, "Synth Playback Volume");	if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)		return err;	/* reassign AUXB to CD */	strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;	strcpy(id2.name, "CD Playback Switch");	if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)		return err;	strcpy(id1.name, "Aux Playback Volume");	strcpy(id2.name, "CD Playback Volume");	if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)		return err;	return 0;}#ifdef __ISAPNP__static int __init snd_interwave_isapnp(int dev, struct snd_interwave *iwcard){	const struct isapnp_card_id *id = snd_interwave_isapnp_id[dev];	struct isapnp_card *card = snd_interwave_isapnp_cards[dev];	struct isapnp_dev *pdev;	iwcard->dev = isapnp_find_dev(card, id->devs[0].vendor, id->devs[0].function, NULL);	if (iwcard->dev->active) {		iwcard->dev = NULL;		return -EBUSY;	}#ifdef SNDRV_STB	iwcard->devtc = isapnp_find_dev(card, id->devs[1].vendor, id->devs[1].function, NULL);	if (iwcard->devtc->active) {		iwcard->dev = iwcard->devtc = NULL;		return -EBUSY;	}#endif	/* Synth & Codec initialization */	pdev = iwcard->dev;	if (pdev->prepare(pdev)<0)		return -EAGAIN;	if (snd_port[dev] != SNDRV_AUTO_PORT) {		isapnp_resource_change(&pdev->resource[0], snd_port[dev], 16);		isapnp_resource_change(&pdev->resource[1], snd_port[dev] + 0x100, 12);		isapnp_resource_change(&pdev->resource[2], snd_port[dev] + 0x10c, 4);	}	if (snd_dma1[dev] != SNDRV_AUTO_DMA)		isapnp_resource_change(&pdev->dma_resource[0], snd_dma1[dev], 1);	if (snd_dma2[dev] != SNDRV_AUTO_DMA)		isapnp_resource_change(&pdev->dma_resource[1], snd_dma2[dev], 1);	if (snd_dma2[dev] < 0)		isapnp_resource_change(&pdev->dma_resource[1], 4, 1);	if (snd_irq[dev] != SNDRV_AUTO_IRQ)		isapnp_resource_change(&pdev->irq_resource[0], snd_irq[dev], 1);	if (pdev->activate(pdev)<0) {		snd_printk("isapnp configure failure (out of resources?)\n");		return -EBUSY;	}	if (pdev->resource[0].start + 0x100 != pdev->resource[1].start ||	    pdev->resource[0].start + 0x10c != pdev->resource[2].start) {		snd_printk("isapnp configure failure (wrong ports)\n");		pdev->deactivate(pdev);		return -ENOENT;	}	snd_port[dev] = pdev->resource[0].start;	snd_dma1[dev] = pdev->dma_resource[0].start;	if (snd_dma2[dev] >= 0)		snd_dma2[dev] = pdev->dma_resource[1].start;	snd_irq[dev] = pdev->irq_resource[0].start;	snd_printdd("isapnp IW: sb port=0x%lx, gf1 port=0x%lx, codec port=0x%lx\n",				pdev->resource[0].start,				pdev->resource[1].start,				pdev->resource[2].start);	snd_printdd("isapnp IW: dma1=%i, dma2=%i, irq=%i\n", snd_dma1[dev], snd_dma2[dev], snd_irq[dev]);#ifdef SNDRV_STB	/* Tone Control initialization */	pdev = iwcard->devtc;	if (pdev->prepare(pdev)<0) {		iwcard->dev->deactivate(iwcard->dev);		return -EAGAIN;	}	if (snd_port_tc[dev] != SNDRV_AUTO_PORT)		isapnp_resource_change(&pdev->resource[0], snd_port_tc[dev], 1);	if (pdev->activate(pdev)<0) {		snd_printk("Tone Control isapnp configure failure (out of resources?)\n");		iwcard->dev->deactivate(iwcard->dev);		return -EBUSY;	}	snd_port_tc[dev] = pdev->resource[0].start;	snd_printdd("isapnp IW: tone control port=0x%lx\n", snd_port_tc[dev]);#endif	return 0;}static void snd_interwave_deactivate(struct snd_interwave *iwcard){	if (iwcard->dev) {		iwcard->dev->deactivate(iwcard->dev);		iwcard->dev = NULL;	}#ifdef SNDRV_STB	if (iwcard->devtc) {		iwcard->devtc->deactivate(iwcard->devtc);		iwcard->devtc = NULL;	}#endif}#endif /* __ISAPNP__ */

⌨️ 快捷键说明

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