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

📄 interwave.c

📁 linux2.6.16版本
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 = joystick_dac[dev];}static struct snd_kcontrol_new 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 __devinit snd_interwave_mixer(struct snd_cs4231 *chip){	struct snd_card *card = chip->card;	struct snd_ctl_elem_id id1, id2;	unsigned int idx;	int 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 < ARRAY_SIZE(snd_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 CONFIG_PNPstatic int __devinit snd_interwave_pnp(int dev, struct snd_interwave *iwcard,				       struct pnp_card_link *card,				       const struct pnp_card_device_id *id){	struct pnp_dev *pdev;	struct pnp_resource_table * cfg = kmalloc(sizeof(struct pnp_resource_table), GFP_KERNEL);	int err;	iwcard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);	if (iwcard->dev == NULL) {		kfree(cfg);		return -EBUSY;	}#ifdef SNDRV_STB	iwcard->devtc = pnp_request_card_device(card, id->devs[1].id, NULL);	if (iwcard->devtc == NULL) {		kfree(cfg);		return -EBUSY;	}#endif	/* Synth & Codec initialization */	pdev = iwcard->dev;	pnp_init_resource_table(cfg);	if (port[dev] != SNDRV_AUTO_PORT) {		pnp_resource_change(&cfg->port_resource[0], port[dev], 16);		pnp_resource_change(&cfg->port_resource[1], port[dev] + 0x100, 12);		pnp_resource_change(&cfg->port_resource[2], port[dev] + 0x10c, 4);	}	if (dma1[dev] != SNDRV_AUTO_DMA)		pnp_resource_change(&cfg->dma_resource[0], dma1[dev], 1);	if (dma2[dev] != SNDRV_AUTO_DMA)		pnp_resource_change(&cfg->dma_resource[1], dma2[dev], 1);	if (dma2[dev] < 0)		pnp_resource_change(&cfg->dma_resource[1], 4, 1);	if (irq[dev] != SNDRV_AUTO_IRQ)		pnp_resource_change(&cfg->irq_resource[0], irq[dev], 1);        if (pnp_manual_config_dev(pdev, cfg, 0) < 0)		snd_printk(KERN_ERR "InterWave - Synth - the requested resources are invalid, using auto config\n");	err = pnp_activate_dev(pdev);	if (err < 0) {		kfree(cfg);		snd_printk(KERN_ERR "InterWave PnP configure failure (out of resources?)\n");		return err;	}	if (pnp_port_start(pdev, 0) + 0x100 != pnp_port_start(pdev, 1) ||	    pnp_port_start(pdev, 0) + 0x10c != pnp_port_start(pdev, 2)) {		kfree(cfg);		snd_printk(KERN_ERR "PnP configure failure (wrong ports)\n");		return -ENOENT;	}	port[dev] = pnp_port_start(pdev, 0);	dma1[dev] = pnp_dma(pdev, 0);	if (dma2[dev] >= 0)		dma2[dev] = pnp_dma(pdev, 1);	irq[dev] = pnp_irq(pdev, 0);	snd_printdd("isapnp IW: sb port=0x%lx, gf1 port=0x%lx, codec port=0x%lx\n",				pnp_port_start(pdev, 0),				pnp_port_start(pdev, 1),				pnp_port_start(pdev, 2));	snd_printdd("isapnp IW: dma1=%i, dma2=%i, irq=%i\n", dma1[dev], dma2[dev], irq[dev]);#ifdef SNDRV_STB	/* Tone Control initialization */	pdev = iwcard->devtc;	pnp_init_resource_table(cfg);	if (port_tc[dev] != SNDRV_AUTO_PORT)		pnp_resource_change(&cfg->port_resource[0], port_tc[dev], 1);        if (pnp_manual_config_dev(pdev, cfg, 0) < 0)		snd_printk(KERN_ERR "InterWave - ToneControl - the requested resources are invalid, using auto config\n");	err = pnp_activate_dev(pdev);	if (err < 0) {		kfree(cfg);		snd_printk(KERN_ERR "InterWave ToneControl PnP configure failure (out of resources?)\n");		return err;	}	port_tc[dev] = pnp_port_start(pdev, 0);	snd_printdd("isapnp IW: tone control port=0x%lx\n", port_tc[dev]);#endif	kfree(cfg);	return 0;}#endif /* CONFIG_PNP */static void snd_interwave_free(struct snd_card *card){	struct snd_interwave *iwcard = card->private_data;	if (iwcard == NULL)		return;#ifdef SNDRV_STB	release_and_free_resource(iwcard->i2c_res);#endif	if (iwcard->irq >= 0)		free_irq(iwcard->irq, (void *)iwcard);}static struct snd_card *snd_interwave_card_new(int dev){	struct snd_card *card;	struct snd_interwave *iwcard;	card = snd_card_new(index[dev], id[dev], THIS_MODULE,			    sizeof(struct snd_interwave));	if (card == NULL)		return NULL;	iwcard = card->private_data;	iwcard->card = card;	iwcard->irq = -1;	card->private_free = snd_interwave_free;	return card;}static int __devinit snd_interwave_probe(struct snd_card *card, int dev){	int xirq, xdma1, xdma2;	struct snd_interwave *iwcard = card->private_data;	struct snd_cs4231 *cs4231;	struct snd_gus_card *gus;#ifdef SNDRV_STB	struct snd_i2c_bus *i2c_bus;#endif	struct snd_pcm *pcm;	char *str;	int err;	xirq = irq[dev];	xdma1 = dma1[dev];	xdma2 = dma2[dev];	if ((err = snd_gus_create(card,				  port[dev],				  -xirq, xdma1, xdma2,				  0, 32,				  pcm_channels[dev], effect[dev], &gus)) < 0)		return err;	if ((err = snd_interwave_detect(iwcard, gus, dev#ifdef SNDRV_STB            , &i2c_bus#endif	    )) < 0)		return err;	iwcard->gus_status_reg = gus->gf1.reg_irqstat;	iwcard->pcm_status_reg = gus->gf1.port + 0x10c + 2;	snd_interwave_init(dev, gus);	snd_interwave_detect_memory(gus);	if ((err = snd_gus_initialize(gus)) < 0)		return err;	if (request_irq(xirq, snd_interwave_interrupt, SA_INTERRUPT,			"InterWave", iwcard)) {		snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq);		return -EBUSY;	}	iwcard->irq = xirq;	if ((err = snd_cs4231_create(card,				     gus->gf1.port + 0x10c, -1, xirq,				     xdma2 < 0 ? xdma1 : xdma2, xdma1,				     CS4231_HW_INTERWAVE,				     CS4231_HWSHARE_IRQ |				     CS4231_HWSHARE_DMA1 |				     CS4231_HWSHARE_DMA2,				     &cs4231)) < 0)		return err;	if ((err = snd_cs4231_pcm(cs4231, 0, &pcm)) < 0)		return err;	sprintf(pcm->name + strlen(pcm->name), " rev %c", gus->revision + 'A');	strcat(pcm->name, " (codec)");	if ((err = snd_cs4231_timer(cs4231, 2, NULL)) < 0)		return err;	if ((err = snd_cs4231_mixer(cs4231)) < 0)		return err;	if (pcm_channels[dev] > 0) {		if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0)			return err;	}	if ((err = snd_interwave_mixer(cs4231)) < 0)		return err;#ifdef SNDRV_STB	{		struct snd_ctl_elem_id id1, id2;		memset(&id1, 0, sizeof(id1));		memset(&id2, 0, sizeof(id2));		id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;		strcpy(id1.name, "Master Playback Switch");		strcpy(id2.name, id1.name);		id2.index = 1;		if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)			return err;		strcpy(id1.name, "Master Playback Volume");		strcpy(id2.name, id1.name);		if ((err = snd_ctl_rename_id(card, &id1, &id2)) < 0)			return err;		if ((err = snd_tea6330t_update_mixer(card, i2c_bus, 0, 1)) < 0)			return err;	}#endif	gus->uart_enable = midi[dev];	if ((err = snd_gf1_rawmidi_new(gus, 0, NULL)) < 0)		return err;#ifndef SNDRV_STB	str = "AMD InterWave";	if (gus->gf1.rom_banks == 1 && gus->gf1.rom_present == 8)		str = "Dynasonic 3-D";#else	str = "InterWave STB";#endif	strcpy(card->driver, str);	strcpy(card->shortname, str);	sprintf(card->longname, "%s at 0x%lx, irq %i, dma %d",		str,		gus->gf1.port,		xirq,		xdma1);	if (xdma2 >= 0)		sprintf(card->longname + strlen(card->longname), "&%d", xdma2);	if ((err = snd_card_register(card)) < 0)		return err;		iwcard->cs4231 = cs4231;	iwcard->gus = gus;	return 0;}static int __init snd_interwave_nonpnp_probe1(int dev, struct platform_device *devptr){	struct snd_card *card;	int err;	card = snd_interwave_card_new(dev);	if (! card)		return -ENOMEM;	snd_card_set_dev(card, &devptr->dev);	if ((err = snd_interwave_probe(card, dev)) < 0) {		snd_card_free(card);		return err;	}	platform_set_drvdata(devptr, card);	return 0;}static int __init snd_interwave_nonpnp_probe(struct platform_device *pdev){	int dev = pdev->id;	int err;	static int possible_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};	static int possible_dmas[] = {0, 1, 3, 5, 6, 7, -1};	if (irq[dev] == SNDRV_AUTO_IRQ) {		if ((irq[dev] = snd_legacy_find_free_irq(possible_irqs)) < 0) {			snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");			return -EBUSY;		}	}	if (dma1[dev] == SNDRV_AUTO_DMA) {		if ((dma1[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) {			snd_printk(KERN_ERR PFX "unable to find a free DMA1\n");			return -EBUSY;		}	}	if (dma2[dev] == SNDRV_AUTO_DMA) {		if ((dma2[dev] = snd_legacy_find_free_dma(possible_dmas)) < 0) {			snd_printk(KERN_ERR PFX "unable to find a free DMA2\n");			return -EBUSY;		}	}	if (port[dev] != SNDRV_AUTO_PORT)		return snd_interwave_nonpnp_probe1(dev, pdev);	else {		static long possible_ports[] = {0x210, 0x220, 0x230, 0x240, 0x250, 0x260};		int i;		for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {			port[dev] = possible_ports[i];			err = snd_interwave_nonpnp_probe1(dev, pdev);			if (! err)				return 0;		}		return err;	}}static int __devexit snd_interwave_nonpnp_remove(struct platform_device *devptr){	snd_card_free(platform_get_drvdata(devptr));	platform_set_drvdata(devptr, NULL);	return 0;}static struct platform_driver snd_interwave_driver = {	.probe		= snd_interwave_nonpnp_probe,	.remove		= __devexit_p(snd_interwave_nonpnp_remove),	/* FIXME: suspend,resume */	.driver		= {		.name	= INTERWAVE_DRIVER	},};#ifdef CONFIG_PNPstatic int __devinit snd_interwave_pnp_detect(struct pnp_card_link *pcard,					      const struct pnp_card_device_id *pid){	static int dev;	struct snd_card *card;	int res;	for ( ; dev < SNDRV_CARDS; dev++) {		if (enable[dev] && isapnp[dev])			break;	}	if (dev >= SNDRV_CARDS)		return -ENODEV;					card = snd_interwave_card_new(dev);	if (! card)		return -ENOMEM;	if ((res = snd_interwave_pnp(dev, card->private_data, pcard, pid)) < 0) {		snd_card_free(card);		return res;	}	snd_card_set_dev(card, &pcard->card->dev);	if ((res = snd_interwave_probe(card, dev)) < 0) {		snd_card_free(card);		return res;	}	pnp_set_card_drvdata(pcard, card);	dev++;	return 0;}static void __devexit snd_interwave_pnp_remove(struct pnp_card_link * pcard){	snd_card_free(pnp_get_card_drvdata(pcard));	pnp_set_card_drvdata(pcard, NULL);}static struct pnp_card_driver interwave_pnpc_driver = {	.flags = PNP_DRIVER_RES_DISABLE,	.name = INTERWAVE_PNP_DRIVER,	.id_table = snd_interwave_pnpids,	.probe = snd_interwave_pnp_detect,	.remove = __devexit_p(snd_interwave_pnp_remove),	/* FIXME: suspend,resume */};#endif /* CONFIG_PNP */static void __init_or_module snd_interwave_unregister_all(void){	int i;	if (pnp_registered)		pnp_unregister_card_driver(&interwave_pnpc_driver);	for (i = 0; i < ARRAY_SIZE(platform_devices); ++i)		platform_device_unregister(platform_devices[i]);	platform_driver_unregister(&snd_interwave_driver);}static int __init alsa_card_interwave_init(void){	int i, err, cards = 0;	if ((err = platform_driver_register(&snd_interwave_driver)) < 0)		return err;	for (i = 0; i < SNDRV_CARDS && enable[i]; i++) {		struct platform_device *device;#ifdef CONFIG_PNP		if (isapnp[i])			continue;#endif		device = platform_device_register_simple(INTERWAVE_DRIVER,							 i, NULL, 0);		if (IS_ERR(device)) {			err = PTR_ERR(device);			goto errout;		}		platform_devices[i] = device;		cards++;	}	/* ISA PnP cards */	i = pnp_register_card_driver(&interwave_pnpc_driver);	if (i >= 0) {		pnp_registered = 1;		cards += i;	}	if (!cards) {#ifdef MODULE		printk(KERN_ERR "InterWave soundcard not found or device busy\n");#endif		err = -ENODEV;		goto errout;	}	return 0; errout:	snd_interwave_unregister_all();	return err;}static void __exit alsa_card_interwave_exit(void){	snd_interwave_unregister_all();}module_init(alsa_card_interwave_init)module_exit(alsa_card_interwave_exit)

⌨️ 快捷键说明

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