コード例 #1
0
static int __devinit snd_es1688_probe(struct device *dev, unsigned int n)
{
	struct snd_card *card;
	struct snd_es1688 *chip;
	struct snd_opl3 *opl3;
	struct snd_pcm *pcm;
	int error;

	card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
	if (!card)
		return -EINVAL;

	error = snd_es1688_legacy_create(card, dev, n, &chip);
	if (error < 0)
		goto out;

	error = snd_es1688_pcm(chip, 0, &pcm);
	if (error < 0)
		goto out;

	error = snd_es1688_mixer(chip);
	if (error < 0)
		goto out;

	strcpy(card->driver, "ES1688");
	strcpy(card->shortname, pcm->name);
	sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name,
		chip->port, chip->irq, chip->dma8);

	if (snd_opl3_create(card, chip->port, chip->port + 2,
			OPL3_HW_OPL3, 0, &opl3) < 0)
		printk(KERN_WARNING "%s: opl3 not detected at 0x%lx\n",
			dev->bus_id, chip->port);
	else {
		error =	snd_opl3_hwdep_new(opl3, 0, 1, NULL);
		if (error < 0)
			goto out;
	}

	if (mpu_irq[n] >= 0 && mpu_irq[n] != SNDRV_AUTO_IRQ &&
			chip->mpu_port > 0) {
		error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
				chip->mpu_port, 0,
				mpu_irq[n], IRQF_DISABLED, NULL);
		if (error < 0)
			goto out;
	}

	snd_card_set_dev(card, dev);

	error = snd_card_register(card);
	if (error < 0)
		goto out;

	dev_set_drvdata(dev, card);
	return 0;

out:	snd_card_free(card);
	return error;
}
コード例 #2
0
static int __devinit snd_adlib_probe(struct device *dev, unsigned int n)
{
	struct snd_card *card;
	struct snd_opl3 *opl3;
	int error;

	error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card);
	if (error < 0) {
		dev_err(dev, "could not create card\n");
		return error;
	}

	card->private_data = request_region(port[n], 4, CRD_NAME);
	if (!card->private_data) {
		dev_err(dev, "could not grab ports\n");
		error = -EBUSY;
		goto out;
	}
	card->private_free = snd_adlib_free;

	strcpy(card->driver, DEV_NAME);
	strcpy(card->shortname, CRD_NAME);
	sprintf(card->longname, CRD_NAME " at %#lx", port[n]);

	error = snd_opl3_create(card, port[n], port[n] + 2, OPL3_HW_AUTO, 1, &opl3);
	if (error < 0) {
		dev_err(dev, "could not create OPL\n");
		goto out;
	}

	error = snd_opl3_hwdep_new(opl3, 0, 0, NULL);
	if (error < 0) {
		dev_err(dev, "could not create FM\n");
		goto out;
	}

	snd_card_set_dev(card, dev);

	error = snd_card_register(card);
	if (error < 0) {
		dev_err(dev, "could not register card\n");
		goto out;
	}

	dev_set_drvdata(dev, card);
	return 0;

out:	snd_card_free(card);
	return error;
}
コード例 #3
0
ファイル: es1688.c プロジェクト: 33d/linux-2.6.21-hh20
static int __devinit snd_es1688_probe(struct snd_card *card, unsigned int n)
{
	struct snd_es1688 *chip = card->private_data;
	struct snd_opl3 *opl3;
	struct snd_pcm *pcm;
	int error;

	error = snd_es1688_pcm(card, chip, 0, &pcm);
	if (error < 0)
		return error;

	error = snd_es1688_mixer(card, chip);
	if (error < 0)
		return error;

	strlcpy(card->driver, "ES1688", sizeof(card->driver));
	strlcpy(card->shortname, pcm->name, sizeof(card->shortname));
	snprintf(card->longname, sizeof(card->longname),
		"%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port,
		 chip->irq, chip->dma8);

	if (fm_port[n] == SNDRV_AUTO_PORT)
		fm_port[n] = port[n];	/* share the same port */

	if (fm_port[n] > 0) {
		if (snd_opl3_create(card, fm_port[n], fm_port[n] + 2,
				OPL3_HW_OPL3, 0, &opl3) < 0)
			dev_warn(card->dev,
				 "opl3 not detected at 0x%lx\n", fm_port[n]);
		else {
			error =	snd_opl3_hwdep_new(opl3, 0, 1, NULL);
			if (error < 0)
				return error;
		}
	}

	if (mpu_irq[n] >= 0 && mpu_irq[n] != SNDRV_AUTO_IRQ &&
			chip->mpu_port > 0) {
		error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
				chip->mpu_port, 0,
				mpu_irq[n], NULL);
		if (error < 0)
			return error;
	}

	return snd_card_register(card);
}
コード例 #4
0
static int snd_cmi8328_probe(struct device *pdev, unsigned int ndev)
{
	struct snd_card *card;
	struct snd_opl3 *opl3;
	struct snd_cmi8328 *cmi;
#ifdef SUPPORT_JOYSTICK
	struct resource *res;
#endif
	int err, pos;
	static long mpu_ports[] = { 0x330, 0x300, 0x310, 0x320, 0x332, 0x334,
				   0x336, -1 };
	static u8 mpu_port_bits[] = { 3, 0, 1, 2, 4, 5, 6 };
	static int mpu_irqs[] = { 9, 7, 5, 3, -1 };
	static u8 mpu_irq_bits[] = { 3, 2, 1, 0 };
	static int irqs[] = { 9, 10, 11, 7, -1 };
	static u8 irq_bits[] = { 2, 3, 4, 1 };
	static int dma1s[] = { 3, 1, 0, -1 };
	static u8 dma_bits[] = { 3, 2, 1 };
	static int dma2s[][2] = { {1, -1}, {0, -1}, {-1, -1}, {0, -1} };
	u16 port = cmi8328_ports[ndev];
	u8 val;

	/* 0xff is invalid configuration (but settable - hope it isn't set) */
	if (snd_cmi8328_cfg_read(port, CFG1) == 0xff)
		return -ENODEV;
	/* the SB disable bit must NEVER EVER be cleared or the WSS dies */
	snd_cmi8328_cfg_write(port, CFG1, CFG1_SB_DISABLE);
	if (snd_cmi8328_cfg_read(port, CFG1) != CFG1_SB_DISABLE)
		return -ENODEV;
	/* disable everything first */
	snd_cmi8328_cfg_write(port, CFG2, 0);	/* disable CDROM and MPU401 */
	snd_cmi8328_cfg_write(port, CFG3, 0);	/* disable CDROM IRQ and DMA */

	if (irq[ndev] == SNDRV_AUTO_IRQ) {
		irq[ndev] = snd_legacy_find_free_irq(irqs);
		if (irq[ndev] < 0) {
			snd_printk(KERN_ERR "unable to find a free IRQ\n");
			return -EBUSY;
		}
	}
	if (dma1[ndev] == SNDRV_AUTO_DMA) {
		dma1[ndev] = snd_legacy_find_free_dma(dma1s);
		if (dma1[ndev] < 0) {
			snd_printk(KERN_ERR "unable to find a free DMA1\n");
			return -EBUSY;
		}
	}
	if (dma2[ndev] == SNDRV_AUTO_DMA) {
		dma2[ndev] = snd_legacy_find_free_dma(dma2s[dma1[ndev] % 4]);
		if (dma2[ndev] < 0) {
			snd_printk(KERN_WARNING "unable to find a free DMA2, full-duplex will not work\n");
			dma2[ndev] = -1;
		}
	}
	/* configure WSS IRQ... */
	pos = array_find(irqs, irq[ndev]);
	if (pos < 0) {
		snd_printk(KERN_ERR "invalid IRQ %d\n", irq[ndev]);
		return -EINVAL;
	}
	val = irq_bits[pos] << 3;
	/* ...and DMA... */
	pos = array_find(dma1s, dma1[ndev]);
	if (pos < 0) {
		snd_printk(KERN_ERR "invalid DMA1 %d\n", dma1[ndev]);
		return -EINVAL;
	}
	val |= dma_bits[pos];
	/* ...and DMA2 */
	if (dma2[ndev] >= 0 && dma1[ndev] != dma2[ndev]) {
		pos = array_find(dma2s[dma1[ndev]], dma2[ndev]);
		if (pos < 0) {
			snd_printk(KERN_ERR "invalid DMA2 %d\n", dma2[ndev]);
			return -EINVAL;
		}
		val |= 0x04; /* enable separate capture DMA */
	}
	outb(val, port);

	err = snd_card_create(index[ndev], id[ndev], THIS_MODULE,
				sizeof(struct snd_cmi8328), &card);
	if (err < 0)
		return err;
	cmi = card->private_data;
	cmi->card = card;
	cmi->port = port;
	cmi->wss_cfg = val;
	snd_card_set_dev(card, pdev);

	err = snd_wss_create(card, port + 4, -1, irq[ndev], dma1[ndev],
			dma2[ndev], WSS_HW_DETECT, 0, &cmi->wss);
	if (err < 0)
		goto error;

	err = snd_wss_pcm(cmi->wss, 0, NULL);
	if (err < 0)
		goto error;

	err = snd_wss_mixer(cmi->wss);
	if (err < 0)
		goto error;
	err = snd_cmi8328_mixer(cmi->wss);
	if (err < 0)
		goto error;

	if (snd_wss_timer(cmi->wss, 0, NULL) < 0)
		snd_printk(KERN_WARNING "error initializing WSS timer\n");

	if (mpuport[ndev] == SNDRV_AUTO_PORT) {
		mpuport[ndev] = snd_legacy_find_free_ioport(mpu_ports, 2);
		if (mpuport[ndev] < 0)
			snd_printk(KERN_ERR "unable to find a free MPU401 port\n");
	}
	if (mpuirq[ndev] == SNDRV_AUTO_IRQ) {
		mpuirq[ndev] = snd_legacy_find_free_irq(mpu_irqs);
		if (mpuirq[ndev] < 0)
			snd_printk(KERN_ERR "unable to find a free MPU401 IRQ\n");
	}
	/* enable and configure MPU401 */
	if (mpuport[ndev] > 0 && mpuirq[ndev] > 0) {
		val = CFG2_MPU_ENABLE;
		pos = array_find_l(mpu_ports, mpuport[ndev]);
		if (pos < 0)
			snd_printk(KERN_WARNING "invalid MPU401 port 0x%lx\n",
								mpuport[ndev]);
		else {
			val |= mpu_port_bits[pos] << 5;
			pos = array_find(mpu_irqs, mpuirq[ndev]);
			if (pos < 0)
				snd_printk(KERN_WARNING "invalid MPU401 IRQ %d\n",
								mpuirq[ndev]);
			else {
				val |= mpu_irq_bits[pos] << 3;
				snd_cmi8328_cfg_write(port, CFG2, val);
				if (snd_mpu401_uart_new(card, 0,
						MPU401_HW_MPU401, mpuport[ndev],
						0, mpuirq[ndev], NULL) < 0)
					snd_printk(KERN_ERR "error initializing MPU401\n");
			}
		}
	}
	/* OPL3 is hardwired to 0x388 and cannot be disabled */
	if (snd_opl3_create(card, 0x388, 0x38a, OPL3_HW_AUTO, 0, &opl3) < 0)
		snd_printk(KERN_ERR "error initializing OPL3\n");
	else
		if (snd_opl3_hwdep_new(opl3, 0, 1, NULL) < 0)
			snd_printk(KERN_WARNING "error initializing OPL3 hwdep\n");

	strcpy(card->driver, "CMI8328");
	strcpy(card->shortname, "C-Media CMI8328");
	sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d,%d",
		card->shortname, cmi->wss->port, irq[ndev], dma1[ndev],
		(dma2[ndev] >= 0) ? dma2[ndev] : dma1[ndev]);

	dev_set_drvdata(pdev, card);
	err = snd_card_register(card);
	if (err < 0)
		goto error;
#ifdef SUPPORT_JOYSTICK
	if (!gameport[ndev])
		return 0;
	/* gameport is hardwired to 0x200 */
	res = request_region(0x200, 8, "CMI8328 gameport");
	if (!res)
		snd_printk(KERN_WARNING "unable to allocate gameport I/O port\n");
	else {
		struct gameport *gp = cmi->gameport = gameport_allocate_port();
		if (!cmi->gameport)
			release_and_free_resource(res);
		else {
			gameport_set_name(gp, "CMI8328 Gameport");
			gameport_set_phys(gp, "%s/gameport0", dev_name(pdev));
			gameport_set_dev_parent(gp, pdev);
			gp->io = 0x200;
			gameport_set_port_data(gp, res);
			/* Enable gameport */
			snd_cmi8328_cfg_write(port, CFG1,
					CFG1_SB_DISABLE | CFG1_GAMEPORT);
			gameport_register_port(gp);
		}
	}
#endif
	return 0;
error:
	snd_card_free(card);

	return err;
}
コード例 #5
0
ファイル: sb8.c プロジェクト: CSCLOG/beaglebone
static int __devinit snd_sb8_probe(struct device *pdev, unsigned int dev)
{
	struct snd_sb *chip;
	struct snd_card *card;
	struct snd_sb8 *acard;
	struct snd_opl3 *opl3;
	int err;

	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
			      sizeof(struct snd_sb8), &card);
	if (err < 0)
		return err;
	acard = card->private_data;
	card->private_free = snd_sb8_free;

	/* block the 0x388 port to avoid PnP conflicts */
	acard->fm_res = request_region(0x388, 4, "SoundBlaster FM");

	if (port[dev] != SNDRV_AUTO_PORT) {
		if ((err = snd_sbdsp_create(card, port[dev], irq[dev],
					    snd_sb8_interrupt,
					    dma8[dev],
					    -1,
					    SB_HW_AUTO,
					    &chip)) < 0)
			goto _err;
	} else {
		/* auto-probe legacy ports */
		static unsigned long possible_ports[] = {
			0x220, 0x240, 0x260,
		};
		int i;
		for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
			err = snd_sbdsp_create(card, possible_ports[i],
					       irq[dev],
					       snd_sb8_interrupt,
					       dma8[dev],
					       -1,
					       SB_HW_AUTO,
					       &chip);
			if (err >= 0) {
				port[dev] = possible_ports[i];
				break;
			}
		}
		if (i >= ARRAY_SIZE(possible_ports)) {
			err = -EINVAL;
			goto _err;
		}
	}
	acard->chip = chip;
			
	if (chip->hardware >= SB_HW_16) {
		if (chip->hardware == SB_HW_ALS100)
			snd_printk(KERN_WARNING "ALS100 chip detected at 0x%lx, try snd-als100 module\n",
				    port[dev]);
		else
			snd_printk(KERN_WARNING "SB 16 chip detected at 0x%lx, try snd-sb16 module\n",
				   port[dev]);
		err = -ENODEV;
		goto _err;
	}

	if ((err = snd_sb8dsp_pcm(chip, 0, NULL)) < 0)
		goto _err;

	if ((err = snd_sbmixer_new(chip)) < 0)
		goto _err;

	if (chip->hardware == SB_HW_10 || chip->hardware == SB_HW_20) {
		if ((err = snd_opl3_create(card, chip->port + 8, 0,
					   OPL3_HW_AUTO, 1,
					   &opl3)) < 0) {
			snd_printk(KERN_WARNING "sb8: no OPL device at 0x%lx\n", chip->port + 8);
		}
	} else {
		if ((err = snd_opl3_create(card, chip->port, chip->port + 2,
					   OPL3_HW_AUTO, 1,
					   &opl3)) < 0) {
			snd_printk(KERN_WARNING "sb8: no OPL device at 0x%lx-0x%lx\n",
				   chip->port, chip->port + 2);
		}
	}
	if (err >= 0) {
		if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
			goto _err;
	}

	if ((err = snd_sb8dsp_midi(chip, 0, NULL)) < 0)
		goto _err;

	strcpy(card->driver, chip->hardware == SB_HW_PRO ? "SB Pro" : "SB8");
	strcpy(card->shortname, chip->name);
	sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
		chip->name,
		chip->port,
		irq[dev], dma8[dev]);

	snd_card_set_dev(card, pdev);

	if ((err = snd_card_register(card)) < 0)
		goto _err;

	dev_set_drvdata(pdev, card);
	return 0;

 _err:
	snd_card_free(card);
	return err;
}
コード例 #6
0
static int __init snd_gusextreme_probe(int dev)
{
	static int possible_ess_irqs[] = {5, 9, 10, 7, -1};
	static int possible_ess_dmas[] = {1, 3, 0, -1};
	static int possible_gf1_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
	static int possible_gf1_dmas[] = {5, 6, 7, 1, 3, -1};
	int xgf1_irq, xgf1_dma, xess_irq, xmpu_irq, xess_dma;
	snd_card_t *card;
	struct snd_gusextreme *acard;
	snd_gus_card_t *gus;
	es1688_t *es1688;
	opl3_t *opl3;
	int err;

	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
	if (card == NULL)
		return -ENOMEM;
	acard = (struct snd_gusextreme *)card->private_data;

	xgf1_irq = gf1_irq[dev];
	if (xgf1_irq == SNDRV_AUTO_IRQ) {
		if ((xgf1_irq = snd_legacy_find_free_irq(possible_gf1_irqs)) < 0) {
			snd_printk("unable to find a free IRQ for GF1\n");
			err = -EBUSY;
			goto out;
		}
	}
	xess_irq = irq[dev];
	if (xess_irq == SNDRV_AUTO_IRQ) {
		if ((xess_irq = snd_legacy_find_free_irq(possible_ess_irqs)) < 0) {
			snd_printk("unable to find a free IRQ for ES1688\n");
			err = -EBUSY;
			goto out;
		}
	}
	if (mpu_port[dev] == SNDRV_AUTO_PORT)
		mpu_port[dev] = 0;
	xmpu_irq = mpu_irq[dev];
	if (xmpu_irq > 15)
		xmpu_irq = -1;
	xgf1_dma = dma1[dev];
	if (xgf1_dma == SNDRV_AUTO_DMA) {
		if ((xgf1_dma = snd_legacy_find_free_dma(possible_gf1_dmas)) < 0) {
			snd_printk("unable to find a free DMA for GF1\n");
			err = -EBUSY;
			goto out;
		}
	}
	xess_dma = dma8[dev];
	if (xess_dma == SNDRV_AUTO_DMA) {
		if ((xess_dma = snd_legacy_find_free_dma(possible_ess_dmas)) < 0) {
			snd_printk("unable to find a free DMA for ES1688\n");
			err = -EBUSY;
			goto out;
		}
	}

	if ((err = snd_es1688_create(card, port[dev], mpu_port[dev],
				     xess_irq, xmpu_irq, xess_dma,
				     ES1688_HW_1688, &es1688)) < 0)
		goto out;
	if (gf1_port[dev] < 0)
		gf1_port[dev] = port[dev] + 0x20;
	if ((err = snd_gus_create(card,
				  gf1_port[dev],
				  xgf1_irq,
				  xgf1_dma,
				  -1,
				  0, channels[dev],
				  pcm_channels[dev], 0,
				  &gus)) < 0)
		goto out;

	if ((err = snd_gusextreme_detect(dev, card, gus, es1688)) < 0)
		goto out;

	snd_gusextreme_init(dev, gus);
	if ((err = snd_gus_initialize(gus)) < 0)
		goto out;

	if (!gus->ess_flag) {
		snd_printdd("GUS Extreme soundcard was not detected at 0x%lx\n", gus->gf1.port);
		err = -ENODEV;
		goto out;
	}
	if ((err = snd_es1688_pcm(es1688, 0, NULL)) < 0)
		goto out;

	if ((err = snd_es1688_mixer(es1688)) < 0)
		goto out;

	snd_component_add(card, "ES1688");
	if (pcm_channels[dev] > 0) {
		if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0)
			goto out;
	}
	if ((err = snd_gf1_new_mixer(gus)) < 0)
		goto out;

	if ((err = snd_gusextreme_mixer(es1688)) < 0)
		goto out;

	if (snd_opl3_create(card, es1688->port, es1688->port + 2,
			    OPL3_HW_OPL3, 0, &opl3) < 0) {
		printk(KERN_ERR "gusextreme: opl3 not detected at 0x%lx\n", es1688->port);
	} else {
		if ((err = snd_opl3_hwdep_new(opl3, 0, 2, NULL)) < 0)
			goto out;
	}

	if (es1688->mpu_port >= 0x300 &&
	    (err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
					       es1688->mpu_port, 0,
					       xmpu_irq,
					       SA_INTERRUPT,
					       NULL)) < 0)
		goto out;

	sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, irq %i&%i, dma %i&%i",
		es1688->port, xgf1_irq, xess_irq, xgf1_dma, xess_dma);
	if ((err = snd_card_register(card)) < 0)
		goto out;

	snd_gusextreme_cards[dev] = card;
	return 0;

      out:
	snd_card_free(card);
	return err;
}
コード例 #7
0
ファイル: gusextreme.c プロジェクト: FatSunHYS/OSCourseDesign
static int __init snd_gusextreme_probe(struct platform_device *pdev)
{
	int dev = pdev->id;
	static int possible_ess_irqs[] = {5, 9, 10, 7, -1};
	static int possible_ess_dmas[] = {1, 3, 0, -1};
	static int possible_gf1_irqs[] = {5, 11, 12, 9, 7, 15, 3, -1};
	static int possible_gf1_dmas[] = {5, 6, 7, 1, 3, -1};
	int xgf1_irq, xgf1_dma, xess_irq, xmpu_irq, xess_dma;
	struct snd_card *card;
	struct snd_gus_card *gus;
	struct snd_es1688 *es1688;
	struct snd_opl3 *opl3;
	int err;

	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
	if (card == NULL)
		return -ENOMEM;

	xgf1_irq = gf1_irq[dev];
	if (xgf1_irq == SNDRV_AUTO_IRQ) {
		if ((xgf1_irq = snd_legacy_find_free_irq(possible_gf1_irqs)) < 0) {
			snd_printk(KERN_ERR PFX "unable to find a free IRQ for GF1\n");
			err = -EBUSY;
			goto out;
		}
	}
	xess_irq = irq[dev];
	if (xess_irq == SNDRV_AUTO_IRQ) {
		if ((xess_irq = snd_legacy_find_free_irq(possible_ess_irqs)) < 0) {
			snd_printk(KERN_ERR PFX "unable to find a free IRQ for ES1688\n");
			err = -EBUSY;
			goto out;
		}
	}
	if (mpu_port[dev] == SNDRV_AUTO_PORT)
		mpu_port[dev] = 0;
	xmpu_irq = mpu_irq[dev];
	if (xmpu_irq > 15)
		xmpu_irq = -1;
	xgf1_dma = dma1[dev];
	if (xgf1_dma == SNDRV_AUTO_DMA) {
		if ((xgf1_dma = snd_legacy_find_free_dma(possible_gf1_dmas)) < 0) {
			snd_printk(KERN_ERR PFX "unable to find a free DMA for GF1\n");
			err = -EBUSY;
			goto out;
		}
	}
	xess_dma = dma8[dev];
	if (xess_dma == SNDRV_AUTO_DMA) {
		if ((xess_dma = snd_legacy_find_free_dma(possible_ess_dmas)) < 0) {
			snd_printk(KERN_ERR PFX "unable to find a free DMA for ES1688\n");
			err = -EBUSY;
			goto out;
		}
	}

	if (port[dev] != SNDRV_AUTO_PORT) {
		err = snd_es1688_create(card, port[dev], mpu_port[dev],
					xess_irq, xmpu_irq, xess_dma,
					ES1688_HW_1688, &es1688);
	} else {
		/* auto-probe legacy ports */
		static unsigned long possible_ports[] = {0x220, 0x240, 0x260};
		int i;
		for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
			err = snd_es1688_create(card,
						possible_ports[i],
						mpu_port[dev],
						xess_irq, xmpu_irq, xess_dma,
						ES1688_HW_1688, &es1688);
			if (err >= 0) {
				port[dev] = possible_ports[i];
				break;
			}
		}
	}
	if (err < 0)
		goto out;

	if (gf1_port[dev] < 0)
		gf1_port[dev] = port[dev] + 0x20;
	if ((err = snd_gus_create(card,
				  gf1_port[dev],
				  xgf1_irq,
				  xgf1_dma,
				  -1,
				  0, channels[dev],
				  pcm_channels[dev], 0,
				  &gus)) < 0)
		goto out;

	if ((err = snd_gusextreme_detect(dev, card, gus, es1688)) < 0)
		goto out;

	snd_gusextreme_init(dev, gus);
	if ((err = snd_gus_initialize(gus)) < 0)
		goto out;

	if (!gus->ess_flag) {
		snd_printk(KERN_ERR PFX "GUS Extreme soundcard was not detected at 0x%lx\n", gus->gf1.port);
		err = -ENODEV;
		goto out;
	}
	if ((err = snd_es1688_pcm(es1688, 0, NULL)) < 0)
		goto out;

	if ((err = snd_es1688_mixer(es1688)) < 0)
		goto out;

	snd_component_add(card, "ES1688");
	if (pcm_channels[dev] > 0) {
		if ((err = snd_gf1_pcm_new(gus, 1, 1, NULL)) < 0)
			goto out;
	}
	if ((err = snd_gf1_new_mixer(gus)) < 0)
		goto out;

	if ((err = snd_gusextreme_mixer(es1688)) < 0)
		goto out;

	if (snd_opl3_create(card, es1688->port, es1688->port + 2,
			    OPL3_HW_OPL3, 0, &opl3) < 0) {
		printk(KERN_ERR PFX "gusextreme: opl3 not detected at 0x%lx\n", es1688->port);
	} else {
		if ((err = snd_opl3_hwdep_new(opl3, 0, 2, NULL)) < 0)
			goto out;
	}

	if (es1688->mpu_port >= 0x300 &&
	    (err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
					       es1688->mpu_port, 0,
					       xmpu_irq,
					       IRQF_DISABLED,
					       NULL)) < 0)
		goto out;

	sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, irq %i&%i, dma %i&%i",
		es1688->port, xgf1_irq, xess_irq, xgf1_dma, xess_dma);

	snd_card_set_dev(card, &pdev->dev);

	if ((err = snd_card_register(card)) < 0)
		goto out;

	platform_set_drvdata(pdev, card);
	return 0;

      out:
	snd_card_free(card);
	return err;
}
コード例 #8
0
ファイル: es1688.c プロジェクト: BackupTheBerlios/tuxap
static int __init snd_audiodrive_probe(int dev)
{
	static int possible_irqs[] = {5, 9, 10, 7, -1};
	static int possible_dmas[] = {1, 3, 0, -1};
	int xirq, xdma, xmpu_irq;
	snd_card_t *card;
	es1688_t *chip;
	opl3_t *opl3;
	snd_pcm_t *pcm;
	int err;

	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
	if (card == NULL)
		return -ENOMEM;

	xirq = irq[dev];
	if (xirq == SNDRV_AUTO_IRQ) {
		if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
			snd_card_free(card);
			snd_printk("unable to find a free IRQ\n");
			return -EBUSY;
		}
	}
	xmpu_irq = mpu_irq[dev];
	xdma = dma8[dev];
	if (xdma == SNDRV_AUTO_DMA) {
		if ((xdma = snd_legacy_find_free_dma(possible_dmas)) < 0) {
			snd_card_free(card);
			snd_printk("unable to find a free DMA\n");
			return -EBUSY;
		}
	}

	if ((err = snd_es1688_create(card, port[dev], mpu_port[dev],
				     xirq, xmpu_irq, xdma,
				     ES1688_HW_AUTO, &chip)) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_es1688_pcm(chip, 0, &pcm)) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_es1688_mixer(chip)) < 0) {
		snd_card_free(card);
		return err;
	}

	strcpy(card->driver, "ES1688");
	strcpy(card->shortname, pcm->name);
	sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port, xirq, xdma);

	if ((snd_opl3_create(card, chip->port, chip->port + 2, OPL3_HW_OPL3, 0, &opl3)) < 0) {
		printk(KERN_ERR "es1688: opl3 not detected at 0x%lx\n", chip->port);
	} else {
		if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
			snd_card_free(card);
			return err;
		}
	}

	if (xmpu_irq >= 0 && xmpu_irq != SNDRV_AUTO_IRQ && chip->mpu_port > 0) {
		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
					       chip->mpu_port, 0,
					       xmpu_irq,
					       SA_INTERRUPT,
					       NULL)) < 0) {
			snd_card_free(card);
			return err;
		}
	}
	if ((err = snd_card_register(card)) < 0) {
		snd_card_free(card);
		return err;
	}
	snd_audiodrive_cards[dev] = card;
	return 0;

}
コード例 #9
0
ファイル: jazz16.c プロジェクト: 33d/linux-2.6.21-hh20
static int __devinit snd_jazz16_probe(struct device *devptr, unsigned int dev)
{
	struct snd_card *card;
	struct snd_card_jazz16 *jazz16;
	struct snd_sb *chip;
	struct snd_opl3 *opl3;
	static int possible_irqs[] = {2, 3, 5, 7, 9, 10, 15, -1};
	static int possible_dmas8[] = {1, 3, -1};
	static int possible_dmas16[] = {5, 7, -1};
	int err, xirq, xdma8, xdma16, xmpu_port, xmpu_irq;

	err = snd_card_create(index[dev], id[dev], THIS_MODULE,
			      sizeof(struct snd_card_jazz16), &card);
	if (err < 0)
		return err;

	jazz16 = card->private_data;

	xirq = irq[dev];
	if (xirq == SNDRV_AUTO_IRQ) {
		xirq = snd_legacy_find_free_irq(possible_irqs);
		if (xirq < 0) {
			snd_printk(KERN_ERR "unable to find a free IRQ\n");
			err = -EBUSY;
			goto err_free;
		}
	}
	xdma8 = dma8[dev];
	if (xdma8 == SNDRV_AUTO_DMA) {
		xdma8 = snd_legacy_find_free_dma(possible_dmas8);
		if (xdma8 < 0) {
			snd_printk(KERN_ERR "unable to find a free DMA8\n");
			err = -EBUSY;
			goto err_free;
		}
	}
	xdma16 = dma16[dev];
	if (xdma16 == SNDRV_AUTO_DMA) {
		xdma16 = snd_legacy_find_free_dma(possible_dmas16);
		if (xdma16 < 0) {
			snd_printk(KERN_ERR "unable to find a free DMA16\n");
			err = -EBUSY;
			goto err_free;
		}
	}

	xmpu_port = mpu_port[dev];
	if (xmpu_port == SNDRV_AUTO_PORT)
		xmpu_port = 0;
	err = jazz16_detect_board(port[dev], xmpu_port);
	if (err < 0) {
		printk(KERN_ERR "Media Vision Jazz16 board not detected\n");
		goto err_free;
	}
	err = snd_sbdsp_create(card, port[dev], irq[dev],
			       jazz16_interrupt,
			       dma8[dev], dma16[dev],
			       SB_HW_JAZZ16,
			       &chip);
	if (err < 0)
		goto err_free;

	xmpu_irq = mpu_irq[dev];
	if (xmpu_irq == SNDRV_AUTO_IRQ || mpu_port[dev] == SNDRV_AUTO_PORT)
		xmpu_irq = 0;
	err = jazz16_configure_board(chip, xmpu_irq);
	if (err < 0) {
		printk(KERN_ERR "Media Vision Jazz16 configuration failed\n");
		goto err_free;
	}

	jazz16->chip = chip;

	strcpy(card->driver, "jazz16");
	strcpy(card->shortname, "Media Vision Jazz16");
	sprintf(card->longname,
		"Media Vision Jazz16 at 0x%lx, irq %d, dma8 %d, dma16 %d",
		port[dev], xirq, xdma8, xdma16);

	err = snd_sb8dsp_pcm(chip, 0, NULL);
	if (err < 0)
		goto err_free;
	err = snd_sbmixer_new(chip);
	if (err < 0)
		goto err_free;

	err = snd_opl3_create(card, chip->port, chip->port + 2,
			      OPL3_HW_AUTO, 1, &opl3);
	if (err < 0)
		snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n",
			   chip->port, chip->port + 2);
	else {
		err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
		if (err < 0)
			goto err_free;
	}
	if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
		if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
			mpu_irq[dev] = -1;

		if (snd_mpu401_uart_new(card, 0,
					MPU401_HW_MPU401,
					mpu_port[dev], 0,
					mpu_irq[dev],
					NULL) < 0)
			snd_printk(KERN_ERR "no MPU-401 device at 0x%lx\n",
					mpu_port[dev]);
	}

	snd_card_set_dev(card, devptr);

	err = snd_card_register(card);
	if (err < 0)
		goto err_free;

	dev_set_drvdata(devptr, card);
	return 0;

err_free:
	snd_card_free(card);
	return err;
}
コード例 #10
0
ファイル: sc6000.c プロジェクト: acassis/emlinux-ssd1935
static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev)
{
	static int possible_irqs[] = { 5, 7, 9, 10, 11, -1 };
	static int possible_dmas[] = { 1, 3, 0, -1 };
	int err;
	int xirq = irq[dev];
	int xdma = dma[dev];
	struct snd_card *card;
	struct snd_ad1848 *chip;
	struct snd_opl3 *opl3;
	char __iomem *vport;
	char __iomem *vmss_port;


	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
	if (!card)
		return -ENOMEM;

	if (xirq == SNDRV_AUTO_IRQ) {
		xirq = snd_legacy_find_free_irq(possible_irqs);
		if (xirq < 0) {
			snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
			err = -EBUSY;
			goto err_exit;
		}
	}

	if (xdma == SNDRV_AUTO_DMA) {
		xdma = snd_legacy_find_free_dma(possible_dmas);
		if (xdma < 0) {
			snd_printk(KERN_ERR PFX "unable to find a free DMA\n");
			err = -EBUSY;
			goto err_exit;
		}
	}

	if (!request_region(port[dev], 0x10, DRV_NAME)) {
		snd_printk(KERN_ERR PFX
			   "I/O port region is already in use.\n");
		err = -EBUSY;
		goto err_exit;
	}
	vport = devm_ioport_map(devptr, port[dev], 0x10);
	if (!vport) {
		snd_printk(KERN_ERR PFX
			   "I/O port cannot be iomaped.\n");
		err = -EBUSY;
		goto err_unmap1;
	}

	/* to make it marked as used */
	if (!request_region(mss_port[dev], 4, DRV_NAME)) {
		snd_printk(KERN_ERR PFX
			   "SC-6000 port I/O port region is already in use.\n");
		err = -EBUSY;
		goto err_unmap1;
	}
	vmss_port = devm_ioport_map(devptr, mss_port[dev], 4);
	if (!vport) {
		snd_printk(KERN_ERR PFX
			   "MSS port I/O cannot be iomaped.\n");
		err = -EBUSY;
		goto err_unmap2;
	}

	snd_printd("Initializing BASE[0x%lx] IRQ[%d] DMA[%d] MIRQ[%d]\n",
		   port[dev], xirq, xdma,
		   mpu_irq[dev] == SNDRV_AUTO_IRQ ? 0 : mpu_irq[dev]);

	err = sc6000_init_board(vport, xirq, xdma, vmss_port, mpu_irq[dev]);
	if (err < 0)
		goto err_unmap2;

	err = snd_ad1848_create(card, mss_port[dev] + 4, xirq, xdma,
				AD1848_HW_DETECT, &chip);
	if (err < 0)
		goto err_unmap2;
	card->private_data = chip;

	err = snd_ad1848_pcm(chip, 0, NULL);
	if (err < 0) {
		snd_printk(KERN_ERR PFX
			   "error creating new ad1848 PCM device\n");
		goto err_unmap2;
	}
	err = snd_ad1848_mixer(chip);
	if (err < 0) {
		snd_printk(KERN_ERR PFX "error creating new ad1848 mixer\n");
		goto err_unmap2;
	}
	err = snd_sc6000_mixer(chip);
	if (err < 0) {
		snd_printk(KERN_ERR PFX "the mixer rewrite failed\n");
		goto err_unmap2;
	}
	if (snd_opl3_create(card,
			    0x388, 0x388 + 2,
			    OPL3_HW_AUTO, 0, &opl3) < 0) {
		snd_printk(KERN_ERR PFX "no OPL device at 0x%x-0x%x ?\n",
			   0x388, 0x388 + 2);
	} else {
		err = snd_opl3_timer_new(opl3, 0, 1);
		if (err < 0)
			goto err_unmap2;

		err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
		if (err < 0)
			goto err_unmap2;
	}

	if (mpu_port[dev] != SNDRV_AUTO_PORT) {
		if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
			mpu_irq[dev] = -1;
		if (snd_mpu401_uart_new(card, 0,
					MPU401_HW_MPU401,
					mpu_port[dev], 0,
					mpu_irq[dev], IRQF_DISABLED,
					NULL) < 0)
			snd_printk(KERN_ERR "no MPU-401 device at 0x%lx ?\n",
					mpu_port[dev]);
	}

	strcpy(card->driver, DRV_NAME);
	strcpy(card->shortname, "SC-6000");
	sprintf(card->longname, "Gallant SC-6000 at 0x%lx, irq %d, dma %d",
		mss_port[dev], xirq, xdma);

	snd_card_set_dev(card, devptr);

	err = snd_card_register(card);
	if (err < 0)
		goto err_unmap2;

	dev_set_drvdata(devptr, card);
	return 0;

err_unmap2:
	release_region(mss_port[dev], 4);
err_unmap1:
	release_region(port[dev], 0x10);
err_exit:
	snd_card_free(card);
	return err;
}
コード例 #11
0
ファイル: opl4_lib.c プロジェクト: 020gzh/linux
int snd_opl4_create(struct snd_card *card,
		    unsigned long fm_port, unsigned long pcm_port,
		    int seq_device,
		    struct snd_opl3 **ropl3, struct snd_opl4 **ropl4)
{
	struct snd_opl4 *opl4;
	struct snd_opl3 *opl3;
	int err;
	static struct snd_device_ops ops = {
		.dev_free = snd_opl4_dev_free
	};

	if (ropl3)
		*ropl3 = NULL;
	if (ropl4)
		*ropl4 = NULL;

	opl4 = kzalloc(sizeof(*opl4), GFP_KERNEL);
	if (!opl4)
		return -ENOMEM;

	opl4->res_fm_port = request_region(fm_port, 8, "OPL4 FM");
	opl4->res_pcm_port = request_region(pcm_port, 8, "OPL4 PCM/MIX");
	if (!opl4->res_fm_port || !opl4->res_pcm_port) {
		snd_printk(KERN_ERR "opl4: can't grab ports 0x%lx, 0x%lx\n", fm_port, pcm_port);
		snd_opl4_free(opl4);
		return -EBUSY;
	}

	opl4->card = card;
	opl4->fm_port = fm_port;
	opl4->pcm_port = pcm_port;
	spin_lock_init(&opl4->reg_lock);
	mutex_init(&opl4->access_mutex);

	err = snd_opl4_detect(opl4);
	if (err < 0) {
		snd_opl4_free(opl4);
		snd_printd("OPL4 chip not detected at %#lx/%#lx\n", fm_port, pcm_port);
		return err;
	}

	err = snd_device_new(card, SNDRV_DEV_CODEC, opl4, &ops);
	if (err < 0) {
		snd_opl4_free(opl4);
		return err;
	}

	err = snd_opl3_create(card, fm_port, fm_port + 2, opl4->hardware, 1, &opl3);
	if (err < 0) {
		snd_device_free(card, opl4);
		return err;
	}

	/* opl3 initialization disabled opl4, so reenable */
	snd_opl4_enable_opl4(opl4);

	snd_opl4_create_mixer(opl4);
	snd_opl4_create_proc(opl4);

#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
	opl4->seq_client = -1;
	if (opl4->hardware < OPL3_HW_OPL4_ML)
		snd_opl4_create_seq_dev(opl4, seq_device);
#endif

	if (ropl3)
		*ropl3 = opl3;
	if (ropl4)
		*ropl4 = opl4;
	return 0;
}
コード例 #12
0
ファイル: pc98.c プロジェクト: plbossart/alsa-driver-build
static int __init snd_card_pc98_probe(int dev)
{
	struct snd_card *card;
	struct snd_pcm *pcm = NULL;
	cs4231_t *chip;
	struct snd_opl3 *opl3;
	int err;

	if (port[dev] == SNDRV_AUTO_PORT) {
		snd_printk(KERN_ERR IDENT ": specify port\n");
		return -EINVAL;
	}
	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
	if (err < 0)
		return err;

	if ((err = pc98_cs4231_chip_init(dev)) < 0) {
		snd_card_free(card);
		return err;
	}

	if ((err = snd_cs4231_create(card,
				     port[dev],
				     -1,
				     irq[dev],
				     dma1[dev],
				     dma2[dev],
				     CS4231_HW_DETECT,
				     0,
				     &chip)) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_cs4231_pcm(chip, 0, &pcm)) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_cs4231_mixer(chip)) < 0) {
		snd_card_free(card);
		return err;
	}

	if ((err = snd_cs4231_timer(chip, 0, NULL)) < 0) {
		snd_card_free(card);
		return err;
	}

	if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
		/* ??? */
		outb(0x00, fm_port[dev] + 6);
		inb(fm_port[dev] + 7);
		/* Enable OPL-3 Function */
		outb(inb(PC9800_SOUND_IO_ID) | 0x03, PC9800_SOUND_IO_ID);
		if (snd_opl3_create(card,
				    fm_port[dev], fm_port[dev] + 2,
				    OPL3_HW_OPL3_PC98, 0, &opl3) < 0) {
			printk(KERN_ERR IDENT ": OPL3 not detected\n");
		} else {
			if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
				snd_card_free(card);
				return err;
			}
		}
	}

	if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
		err = pc98_mpu401_init(mpu_irq[dev]);
		if (! err) {
			err = snd_mpu401_uart_new(card, 0,
						  pc98ii[dev] ? MPU401_HW_PC98II : MPU401_HW_MPU401,
						  mpu_port[dev], 0,
						  mpu_irq[dev], SA_INTERRUPT, NULL);
			if (err < 0)
				snd_printk(KERN_INFO IDENT ": MPU401 not detected\n");
		}
	}

	strcpy(card->driver, pcm->name);
	strcpy(card->shortname, pcm->name);
	sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i",
		pcm->name,
		chip->port,
		irq[dev],
		dma1[dev]);
	if (dma2[dev] >= 0)
		sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]);
	if ((err = snd_card_register(card)) < 0) {
		snd_card_free(card);
		return err;
	}
	snd_pc98_cards[dev] = card;
	return 0;
}
コード例 #13
0
ファイル: gusextreme.c プロジェクト: antonywcl/AR-5315u_PLD
static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
{
	struct snd_card *card;
	struct snd_gus_card *gus;
	struct snd_es1688 *es1688;
	struct snd_opl3 *opl3;
	int error;

	error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card);
	if (error < 0)
		return error;

	if (mpu_port[n] == SNDRV_AUTO_PORT)
		mpu_port[n] = 0;

	if (mpu_irq[n] > 15)
		mpu_irq[n] = -1;

	error = snd_gusextreme_es1688_create(card, dev, n, &es1688);
	if (error < 0)
		goto out;

	if (gf1_port[n] < 0)
		gf1_port[n] = es1688->port + 0x20;

	error = snd_gusextreme_gus_card_create(card, dev, n, &gus);
	if (error < 0)
		goto out;

	error = snd_gusextreme_detect(gus, es1688);
	if (error < 0)
		goto out;

	gus->joystick_dac = joystick_dac[n];

	error = snd_gus_initialize(gus);
	if (error < 0)
		goto out;

	error = -ENODEV;
	if (!gus->ess_flag) {
		dev_err(dev, "GUS Extreme soundcard was not "
			"detected at 0x%lx\n", gus->gf1.port);
		goto out;
	}
	gus->codec_flag = 1;

	error = snd_es1688_pcm(es1688, 0, NULL);
	if (error < 0)
		goto out;

	error = snd_es1688_mixer(es1688);
	if (error < 0)
		goto out;

	snd_component_add(card, "ES1688");

	if (pcm_channels[n] > 0) {
		error = snd_gf1_pcm_new(gus, 1, 1, NULL);
		if (error < 0)
			goto out;
	}

	error = snd_gf1_new_mixer(gus);
	if (error < 0)
		goto out;

	error = snd_gusextreme_mixer(es1688);
	if (error < 0)
		goto out;

	if (snd_opl3_create(card, es1688->port, es1688->port + 2,
			OPL3_HW_OPL3, 0, &opl3) < 0)
		dev_warn(dev, "opl3 not detected at 0x%lx\n", es1688->port);
	else {
		error = snd_opl3_hwdep_new(opl3, 0, 2, NULL);
		if (error < 0)
			goto out;
	}

	if (es1688->mpu_port >= 0x300) {
		error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
				es1688->mpu_port, 0,
				mpu_irq[n], IRQF_DISABLED, NULL);
		if (error < 0)
			goto out;
	}

	sprintf(card->longname, "Gravis UltraSound Extreme at 0x%lx, "
		"irq %i&%i, dma %i&%i", es1688->port,
		gus->gf1.irq, es1688->irq, gus->gf1.dma1, es1688->dma8);

	snd_card_set_dev(card, dev);

	error = snd_card_register(card);
	if (error < 0)
		goto out;

	dev_set_drvdata(dev, card);
	return 0;

out:	snd_card_free(card);
	return error;
}
static int __init snd_es1688_probe(struct platform_device *pdev)
{
	int dev = pdev->id;
	static int possible_irqs[] = {5, 9, 10, 7, -1};
	static int possible_dmas[] = {1, 3, 0, -1};
	int xirq, xdma, xmpu_irq;
	struct snd_card *card;
	struct snd_es1688 *chip;
	struct snd_opl3 *opl3;
	struct snd_pcm *pcm;
	int err;

	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
	if (card == NULL)
		return -ENOMEM;

	xirq = irq[dev];
	if (xirq == SNDRV_AUTO_IRQ) {
		if ((xirq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
			snd_printk(KERN_ERR PFX "unable to find a free IRQ\n");
			err = -EBUSY;
			goto _err;
		}
	}
	xmpu_irq = mpu_irq[dev];
	xdma = dma8[dev];
	if (xdma == SNDRV_AUTO_DMA) {
		if ((xdma = snd_legacy_find_free_dma(possible_dmas)) < 0) {
			snd_printk(KERN_ERR PFX "unable to find a free DMA\n");
			err = -EBUSY;
			goto _err;
		}
	}

	if (port[dev] != SNDRV_AUTO_PORT) {
		if ((err = snd_es1688_create(card, port[dev], mpu_port[dev],
					     xirq, xmpu_irq, xdma,
					     ES1688_HW_AUTO, &chip)) < 0)
			goto _err;
	} else {
		/* auto-probe legacy ports */
		static unsigned long possible_ports[] = {
			0x220, 0x240, 0x260,
		};
		int i;
		for (i = 0; i < ARRAY_SIZE(possible_ports); i++) {
			err = snd_es1688_create(card, possible_ports[i],
						mpu_port[dev],
						xirq, xmpu_irq, xdma,
						ES1688_HW_AUTO, &chip);
			if (err >= 0) {
				port[dev] = possible_ports[i];
				break;
			}
		}
		if (i >= ARRAY_SIZE(possible_ports))
			goto _err;
	}

	if ((err = snd_es1688_pcm(chip, 0, &pcm)) < 0)
		goto _err;

	if ((err = snd_es1688_mixer(chip)) < 0)
		goto _err;

	strcpy(card->driver, "ES1688");
	strcpy(card->shortname, pcm->name);
	sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port, xirq, xdma);

	if ((snd_opl3_create(card, chip->port, chip->port + 2, OPL3_HW_OPL3, 0, &opl3)) < 0) {
		printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->port);
	} else {
		if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
			goto _err;
	}

	if (xmpu_irq >= 0 && xmpu_irq != SNDRV_AUTO_IRQ && chip->mpu_port > 0) {
		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688,
					       chip->mpu_port, 0,
					       xmpu_irq,
					       SA_INTERRUPT,
					       NULL)) < 0)
			goto _err;
	}

	snd_card_set_dev(card, &pdev->dev);

	if ((err = snd_card_register(card)) < 0)
		goto _err;

	platform_set_drvdata(pdev, card);
	return 0;

 _err:
	snd_card_free(card);
	return err;
}
コード例 #15
0
static int snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard,
				  const struct pnp_card_device_id *pid)
{
	int error;
	struct snd_card *card;
	struct snd_ad1816a *chip;
	struct snd_opl3 *opl3;
	struct snd_timer *timer;

	error = snd_card_create(index[dev], id[dev], THIS_MODULE,
				sizeof(struct snd_ad1816a), &card);
	if (error < 0)
		return error;
	chip = card->private_data;

	if ((error = snd_card_ad1816a_pnp(dev, pcard, pid))) {
		snd_card_free(card);
		return error;
	}
	snd_card_set_dev(card, &pcard->card->dev);

	if ((error = snd_ad1816a_create(card, port[dev],
					irq[dev],
					dma1[dev],
					dma2[dev],
					chip)) < 0) {
		snd_card_free(card);
		return error;
	}
	if (clockfreq[dev] >= 5000 && clockfreq[dev] <= 100000)
		chip->clock_freq = clockfreq[dev];

	strcpy(card->driver, "AD1816A");
	strcpy(card->shortname, "ADI SoundPort AD1816A");
	sprintf(card->longname, "%s, SS at 0x%lx, irq %d, dma %d&%d",
		card->shortname, chip->port, irq[dev], dma1[dev], dma2[dev]);

	if ((error = snd_ad1816a_pcm(chip, 0, NULL)) < 0) {
		snd_card_free(card);
		return error;
	}

	if ((error = snd_ad1816a_mixer(chip)) < 0) {
		snd_card_free(card);
		return error;
	}

	error = snd_ad1816a_timer(chip, 0, &timer);
	if (error < 0) {
		snd_card_free(card);
		return error;
	}

	if (mpu_port[dev] > 0) {
		if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
					mpu_port[dev], 0, mpu_irq[dev],
					NULL) < 0)
			printk(KERN_ERR PFX "no MPU-401 device at 0x%lx.\n", mpu_port[dev]);
	}

	if (fm_port[dev] > 0) {
		if (snd_opl3_create(card,
				    fm_port[dev], fm_port[dev] + 2,
				    OPL3_HW_AUTO, 0, &opl3) < 0) {
			printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx.\n", fm_port[dev], fm_port[dev] + 2);
		} else {
			error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
			if (error < 0) {
				snd_card_free(card);
				return error;
			}
		}
	}

	if ((error = snd_card_register(card)) < 0) {
		snd_card_free(card);
		return error;
	}
	pnp_set_card_drvdata(pcard, card);
	return 0;
}
コード例 #16
0
static int
snd_wavefront_probe (struct snd_card *card, int dev)
{
	snd_wavefront_card_t *acard = card->private_data;
	struct snd_wss *chip;
	struct snd_hwdep *wavefront_synth;
	struct snd_rawmidi *ics2115_internal_rmidi = NULL;
	struct snd_rawmidi *ics2115_external_rmidi = NULL;
	struct snd_hwdep *fx_processor;
	int hw_dev = 0, midi_dev = 0, err;

	/* --------- PCM --------------- */

	err = snd_wss_create(card, cs4232_pcm_port[dev], -1,
			     cs4232_pcm_irq[dev], dma1[dev], dma2[dev],
			     WSS_HW_DETECT, 0, &chip);
	if (err < 0) {
		snd_printk(KERN_ERR "can't allocate WSS device\n");
		return err;
	}

	err = snd_wss_pcm(chip, 0, NULL);
	if (err < 0)
		return err;

	err = snd_wss_timer(chip, 0, NULL);
	if (err < 0)
		return err;

	/* ---------- OPL3 synth --------- */

	if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
		struct snd_opl3 *opl3;

		err = snd_opl3_create(card, fm_port[dev], fm_port[dev] + 2,
				      OPL3_HW_OPL3_CS, 0, &opl3);
		if (err < 0) {
			snd_printk (KERN_ERR "can't allocate or detect OPL3 synth\n");
			return err;
		}

		err = snd_opl3_hwdep_new(opl3, hw_dev, 1, NULL);
		if (err < 0)
			return err;
		hw_dev++;
	}

	/* ------- ICS2115 Wavetable synth ------- */

	acard->wavefront.res_base = request_region(ics2115_port[dev], 16,
						   "ICS2115");
	if (acard->wavefront.res_base == NULL) {
		snd_printk(KERN_ERR "unable to grab ICS2115 i/o region 0x%lx-0x%lx\n",
			   ics2115_port[dev], ics2115_port[dev] + 16 - 1);
		return -EBUSY;
	}
	if (request_irq(ics2115_irq[dev], snd_wavefront_ics2115_interrupt,
			0, "ICS2115", acard)) {
		snd_printk(KERN_ERR "unable to use ICS2115 IRQ %d\n", ics2115_irq[dev]);
		return -EBUSY;
	}
	
	acard->wavefront.irq = ics2115_irq[dev];
	acard->wavefront.base = ics2115_port[dev];

	wavefront_synth = snd_wavefront_new_synth(card, hw_dev, acard);
	if (wavefront_synth == NULL) {
		snd_printk (KERN_ERR "can't create WaveFront synth device\n");
		return -ENOMEM;
	}

	strcpy (wavefront_synth->name, "ICS2115 Wavetable MIDI Synthesizer");
	wavefront_synth->iface = SNDRV_HWDEP_IFACE_ICS2115;
	hw_dev++;

	/* --------- Mixer ------------ */

	err = snd_wss_mixer(chip);
	if (err < 0) {
		snd_printk (KERN_ERR "can't allocate mixer device\n");
		return err;
	}

	/* -------- CS4232 MPU-401 interface -------- */

	if (cs4232_mpu_port[dev] > 0 && cs4232_mpu_port[dev] != SNDRV_AUTO_PORT) {
		err = snd_mpu401_uart_new(card, midi_dev, MPU401_HW_CS4232,
					  cs4232_mpu_port[dev], 0,
					  cs4232_mpu_irq[dev], NULL);
		if (err < 0) {
			snd_printk (KERN_ERR "can't allocate CS4232 MPU-401 device\n");
			return err;
		}
		midi_dev++;
	}

	/* ------ ICS2115 internal MIDI ------------ */

	if (ics2115_port[dev] > 0 && ics2115_port[dev] != SNDRV_AUTO_PORT) {
		ics2115_internal_rmidi = 
			snd_wavefront_new_midi (card, 
						midi_dev,
						acard,
						ics2115_port[dev],
						internal_mpu);
		if (ics2115_internal_rmidi == NULL) {
			snd_printk (KERN_ERR "can't setup ICS2115 internal MIDI device\n");
			return -ENOMEM;
		}
		midi_dev++;
	}

	/* ------ ICS2115 external MIDI ------------ */

	if (ics2115_port[dev] > 0 && ics2115_port[dev] != SNDRV_AUTO_PORT) {
		ics2115_external_rmidi = 
			snd_wavefront_new_midi (card, 
						midi_dev,
						acard,
						ics2115_port[dev],
						external_mpu);
		if (ics2115_external_rmidi == NULL) {
			snd_printk (KERN_ERR "can't setup ICS2115 external MIDI device\n");
			return -ENOMEM;
		}
		midi_dev++;
	}

	/* FX processor for Tropez+ */

	if (acard->wavefront.has_fx) {
		fx_processor = snd_wavefront_new_fx (card,
						     hw_dev,
						     acard,
						     ics2115_port[dev]);
		if (fx_processor == NULL) {
			snd_printk (KERN_ERR "can't setup FX device\n");
			return -ENOMEM;
		}

		hw_dev++;

		strcpy(card->driver, "Tropez+");
		strcpy(card->shortname, "Turtle Beach Tropez+");
	} else {
		/* Need a way to distinguish between Maui and Tropez */
		strcpy(card->driver, "WaveFront");
		strcpy(card->shortname, "Turtle Beach WaveFront");
	}

	/* ----- Register the card --------- */

	/* Not safe to include "Turtle Beach" in longname, due to 
	   length restrictions
	*/

	sprintf(card->longname, "%s PCM 0x%lx irq %d dma %d",
		card->driver,
		chip->port,
		cs4232_pcm_irq[dev],
		dma1[dev]);

	if (dma2[dev] >= 0 && dma2[dev] < 8)
		sprintf(card->longname + strlen(card->longname), "&%d", dma2[dev]);

	if (cs4232_mpu_port[dev] > 0 && cs4232_mpu_port[dev] != SNDRV_AUTO_PORT) {
		sprintf (card->longname + strlen (card->longname), 
			 " MPU-401 0x%lx irq %d",
			 cs4232_mpu_port[dev],
			 cs4232_mpu_irq[dev]);
	}

	sprintf (card->longname + strlen (card->longname), 
		 " SYNTH 0x%lx irq %d",
		 ics2115_port[dev],
		 ics2115_irq[dev]);

	return snd_card_register(card);
}	
コード例 #17
0
static int __devinit snd_galaxy_probe(struct device *dev, unsigned int n)
{
    struct snd_galaxy *galaxy;
    struct snd_wss *chip;
    struct snd_card *card;
    u8 type;
    int err;

    err = snd_card_create(index[n], id[n], THIS_MODULE, sizeof *galaxy,
                          &card);
    if (err < 0)
        return err;

    snd_card_set_dev(card, dev);

    card->private_free = snd_galaxy_free;
    galaxy = card->private_data;

    galaxy->res_port = request_region(port[n], 16, DRV_NAME);
    if (!galaxy->res_port) {
        dev_err(dev, "could not grab ports %#lx-%#lx\n", port[n],
                port[n] + 15);
        err = -EBUSY;
        goto error;
    }
    galaxy->port = ioport_map(port[n], 16);

    err = galaxy_init(galaxy, &type);
    if (err < 0) {
        dev_err(dev, "did not find a Sound Galaxy at %#lx\n", port[n]);
        goto error;
    }
    dev_info(dev, "Sound Galaxy (type %d) found at %#lx\n", type, port[n]);

    galaxy->res_config_port = request_region(port[n] + GALAXY_PORT_CONFIG,
                              16, DRV_NAME);
    if (!galaxy->res_config_port) {
        dev_err(dev, "could not grab ports %#lx-%#lx\n",
                port[n] + GALAXY_PORT_CONFIG,
                port[n] + GALAXY_PORT_CONFIG + 15);
        err = -EBUSY;
        goto error;
    }
    galaxy->config_port = ioport_map(port[n] + GALAXY_PORT_CONFIG, 16);

    galaxy_config(galaxy, config[n]);

    galaxy->res_wss_port = request_region(wss_port[n], 4, DRV_NAME);
    if (!galaxy->res_wss_port)  {
        dev_err(dev, "could not grab ports %#lx-%#lx\n", wss_port[n],
                wss_port[n] + 3);
        err = -EBUSY;
        goto error;
    }
    galaxy->wss_port = ioport_map(wss_port[n], 4);

    err = galaxy_wss_config(galaxy, wss_config[n]);
    if (err < 0) {
        dev_err(dev, "could not configure WSS\n");
        goto error;
    }

    strcpy(card->driver, DRV_NAME);
    strcpy(card->shortname, DRV_NAME);
    sprintf(card->longname, "%s at %#lx/%#lx, irq %d, dma %d/%d",
            card->shortname, port[n], wss_port[n], irq[n], dma1[n],
            dma2[n]);

    err = snd_wss_create(card, wss_port[n] + 4, -1, irq[n], dma1[n],
                         dma2[n], WSS_HW_DETECT, 0, &chip);
    if (err < 0)
        goto error;

    err = snd_wss_pcm(chip, 0, NULL);
    if (err < 0)
        goto error;

    err = snd_wss_mixer(chip);
    if (err < 0)
        goto error;

    err = snd_wss_timer(chip, 0, NULL);
    if (err < 0)
        goto error;

    if (mpu_port[n] >= 0) {
        err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
                                  mpu_port[n], 0, mpu_irq[n], NULL);
        if (err < 0)
            goto error;
    }

    if (fm_port[n] >= 0) {
        struct snd_opl3 *opl3;

        err = snd_opl3_create(card, fm_port[n], fm_port[n] + 2,
                              OPL3_HW_AUTO, 0, &opl3);
        if (err < 0) {
            dev_err(dev, "no OPL device at %#lx\n", fm_port[n]);
            goto error;
        }
        err = snd_opl3_timer_new(opl3, 1, 2);
        if (err < 0)
            goto error;

        err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
        if (err < 0)
            goto error;
    }

    err = snd_card_register(card);
    if (err < 0)
        goto error;

    dev_set_drvdata(dev, card);
    return 0;

error:
    snd_card_free(card);
    return err;
}
コード例 #18
0
ファイル: ymfpci.c プロジェクト: johnny/CobraDroidBeta
static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
					   const struct pci_device_id *pci_id)
{
	static int dev;
	struct snd_card *card;
	struct resource *fm_res = NULL;
	struct resource *mpu_res = NULL;
	struct snd_ymfpci *chip;
	struct snd_opl3 *opl3;
	const char *str, *model;
	int err;
	u16 legacy_ctrl, legacy_ctrl2, old_legacy_ctrl;

	if (dev >= SNDRV_CARDS)
		return -ENODEV;
	if (!enable[dev]) {
		dev++;
		return -ENOENT;
	}

	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
	if (card == NULL)
		return -ENOMEM;

	switch (pci_id->device) {
	case 0x0004: str = "YMF724";  model = "DS-1"; break;
	case 0x000d: str = "YMF724F"; model = "DS-1"; break;
	case 0x000a: str = "YMF740";  model = "DS-1L"; break;
	case 0x000c: str = "YMF740C"; model = "DS-1L"; break;
	case 0x0010: str = "YMF744";  model = "DS-1S"; break;
	case 0x0012: str = "YMF754";  model = "DS-1E"; break;
	default: model = str = "???"; break;
	}

	legacy_ctrl = 0;
	legacy_ctrl2 = 0x0800;	/* SBEN = 0, SMOD = 01, LAD = 0 */

	if (pci_id->device >= 0x0010) { /* YMF 744/754 */
		if (fm_port[dev] == 1) {
			/* auto-detect */
			fm_port[dev] = pci_resource_start(pci, 1);
		}
		if (fm_port[dev] > 0 &&
		    (fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3")) != NULL) {
			legacy_ctrl |= YMFPCI_LEGACY_FMEN;
			pci_write_config_word(pci, PCIR_DSXG_FMBASE, fm_port[dev]);
		}
		if (mpu_port[dev] == 1) {
			/* auto-detect */
			mpu_port[dev] = pci_resource_start(pci, 1) + 0x20;
		}
		if (mpu_port[dev] > 0 &&
		    (mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401")) != NULL) {
			legacy_ctrl |= YMFPCI_LEGACY_MEN;
			pci_write_config_word(pci, PCIR_DSXG_MPU401BASE, mpu_port[dev]);
		}
	} else {
		switch (fm_port[dev]) {
		case 0x388: legacy_ctrl2 |= 0; break;
		case 0x398: legacy_ctrl2 |= 1; break;
		case 0x3a0: legacy_ctrl2 |= 2; break;
		case 0x3a8: legacy_ctrl2 |= 3; break;
		default: fm_port[dev] = 0; break;
		}
		if (fm_port[dev] > 0 &&
		    (fm_res = request_region(fm_port[dev], 4, "YMFPCI OPL3")) != NULL) {
			legacy_ctrl |= YMFPCI_LEGACY_FMEN;
		} else {
			legacy_ctrl2 &= ~YMFPCI_LEGACY2_FMIO;
			fm_port[dev] = 0;
		}
		switch (mpu_port[dev]) {
		case 0x330: legacy_ctrl2 |= 0 << 4; break;
		case 0x300: legacy_ctrl2 |= 1 << 4; break;
		case 0x332: legacy_ctrl2 |= 2 << 4; break;
		case 0x334: legacy_ctrl2 |= 3 << 4; break;
		default: mpu_port[dev] = 0; break;
		}
		if (mpu_port[dev] > 0 &&
		    (mpu_res = request_region(mpu_port[dev], 2, "YMFPCI MPU401")) != NULL) {
			legacy_ctrl |= YMFPCI_LEGACY_MEN;
		} else {
			legacy_ctrl2 &= ~YMFPCI_LEGACY2_MPUIO;
			mpu_port[dev] = 0;
		}
	}
	if (mpu_res) {
		legacy_ctrl |= YMFPCI_LEGACY_MIEN;
		legacy_ctrl2 |= YMFPCI_LEGACY2_IMOD;
	}
	pci_read_config_word(pci, PCIR_DSXG_LEGACY, &old_legacy_ctrl);
	pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
	pci_write_config_word(pci, PCIR_DSXG_ELEGACY, legacy_ctrl2);
	if ((err = snd_ymfpci_create(card, pci,
				     old_legacy_ctrl,
			 	     &chip)) < 0) {
		snd_card_free(card);
		release_and_free_resource(mpu_res);
		release_and_free_resource(fm_res);
		return err;
	}
	chip->fm_res = fm_res;
	chip->mpu_res = mpu_res;
	card->private_data = chip;

	strcpy(card->driver, str);
	sprintf(card->shortname, "Yamaha %s (%s)", model, str);
	sprintf(card->longname, "%s at 0x%lx, irq %i",
		card->shortname,
		chip->reg_area_phys,
		chip->irq);
	if ((err = snd_ymfpci_pcm(chip, 0, NULL)) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_ymfpci_pcm_spdif(chip, 1, NULL)) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_ymfpci_pcm_4ch(chip, 2, NULL)) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_ymfpci_pcm2(chip, 3, NULL)) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_ymfpci_mixer(chip, rear_switch[dev])) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_ymfpci_timer(chip, 0)) < 0) {
		snd_card_free(card);
		return err;
	}
	if (chip->mpu_res) {
		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI,
					       mpu_port[dev],
					       MPU401_INFO_INTEGRATED,
					       pci->irq, 0, &chip->rawmidi)) < 0) {
			printk(KERN_WARNING "ymfpci: cannot initialize MPU401 at 0x%lx, skipping...\n", mpu_port[dev]);
			legacy_ctrl &= ~YMFPCI_LEGACY_MIEN; /* disable MPU401 irq */
			pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
		}
	}
	if (chip->fm_res) {
		if ((err = snd_opl3_create(card,
					   fm_port[dev],
					   fm_port[dev] + 2,
					   OPL3_HW_OPL3, 1, &opl3)) < 0) {
			printk(KERN_WARNING "ymfpci: cannot initialize FM OPL3 at 0x%lx, skipping...\n", fm_port[dev]);
			legacy_ctrl &= ~YMFPCI_LEGACY_FMEN;
			pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl);
		} else if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
			snd_card_free(card);
			snd_printk(KERN_ERR "cannot create opl3 hwdep\n");
			return err;
		}
	}

	snd_ymfpci_create_gameport(chip, dev, legacy_ctrl, legacy_ctrl2);

	if ((err = snd_card_register(card)) < 0) {
		snd_card_free(card);
		return err;
	}
	pci_set_drvdata(pci, card);
	dev++;
	return 0;
}
コード例 #19
0
ファイル: ymfpci.c プロジェクト: OS2World/DRV-UNIAUD
static int __init snd_card_ymfpci_probe(struct pci_dev *pci,
					const struct pci_device_id *id)
{
	static int dev = 0;
	snd_card_t *card;
	ymfpci_t *chip;
	opl3_t *opl3;
	char *str;
	int err;
	u16 legacy_ctrl, legacy_ctrl2, old_legacy_ctrl;

	for ( ; dev < SNDRV_CARDS; dev++) {
		if (!snd_enable[dev]) {
			dev++;
			return -ENOENT;
		}
		break;
	}
	if (dev >= SNDRV_CARDS)
		return -ENODEV;

	card = snd_card_new(snd_index[dev], snd_id[dev], THIS_MODULE, 0);
	if (card == NULL)
		return -ENOMEM;

	switch (id->device) {
	case 0x0004: str = "YMF724"; break;
	case 0x000d: str = "YMF724F"; break;
	case 0x000a: str = "YMF740"; break;
	case 0x000c: str = "YMF740C"; break;
	case 0x0010: str = "YMF744"; break;
	case 0x0012: str = "YMF754"; break;
	default: str = "???"; break;
	}

	legacy_ctrl = 0;
	legacy_ctrl2 = 0;

	if (id->device >= 0x0010) { /* YMF 744/754 */
		if (snd_fm_port[dev] < 0)
			snd_fm_port[dev] = pci_resource_start(pci, 1);
		else if (check_region(snd_fm_port[dev], 4))
			snd_fm_port[dev] = -1;
		if (snd_fm_port[dev] >= 0) {
			legacy_ctrl |= 2;
			pci_write_config_word(pci, 0x60, snd_fm_port[dev]);
		}
		if (snd_mpu_port[dev] < 0)
			snd_mpu_port[dev] = pci_resource_start(pci, 1) + 0x20;
		else if (check_region(snd_mpu_port[dev], 2))
			snd_mpu_port[dev] = -1;
		if (snd_mpu_port[dev] >= 0) {
			legacy_ctrl |= 8;
			pci_write_config_word(pci, 0x62, snd_fm_port[dev]);
		}
#if 0
		sprintf(str1, "%s joystick", str);
		if (snd_joystick_port[dev] < 0)
			snd_joystick_port[dev] = pci_resource_start(pci, 2);
		else if (check_region(snd_joystick_port[dev], 4))
			snd_joystick_port[dev] = -1;
		if (snd_joystick_port[dev] >= 0) {
			legacy_ctrl |= 4;
			pci_write_config_word(pci, 0x66, snd_joystick_port[dev]);
		}
#endif
	} else {
		switch (snd_fm_port[dev]) {
		case 0x388: legacy_ctrl2 |= 0; break;
		case 0x398: legacy_ctrl2 |= 1; break;
		case 0x3a0: legacy_ctrl2 |= 2; break;
		case 0x3a8: legacy_ctrl2 |= 3; break;
		default: snd_fm_port[dev] = -1; break;
		}
		if (snd_fm_port[dev] > 0 && check_region(snd_fm_port[dev], 4) == 0)
			legacy_ctrl |= 2;
		else {
			legacy_ctrl2 &= ~3;
			snd_fm_port[dev] = -1;
		}
		switch (snd_mpu_port[dev]) {
		case 0x330: legacy_ctrl2 |= 0 << 4; break;
		case 0x300: legacy_ctrl2 |= 1 << 4; break;
		case 0x332: legacy_ctrl2 |= 2 << 4; break;
		case 0x334: legacy_ctrl2 |= 3 << 4; break;
		default: snd_mpu_port[dev] = -1; break;
		}
		if (snd_mpu_port[dev] > 0 && check_region(snd_mpu_port[dev], 2) == 0)
			legacy_ctrl |= 8;
		else {
			legacy_ctrl2 &= ~(3 << 4);
			snd_mpu_port[dev] = -1;
		}
#if 0
		switch (snd_joystick_port[dev]) {
		case 0x201: legacy_ctrl2 |= 0 << 6; break;
		case 0x202: legacy_ctrl2 |= 1 << 6; break;
		case 0x204: legacy_ctrl2 |= 2 << 6; break;
		case 0x205: legacy_ctrl2 |= 3 << 6; break;
		default: snd_joystick_port[dev] = -1; break;
		}
		if (snd_joystick_port[dev] > 0 && check_region(snd_joystick_port[dev], 2) == 0)
			legacy_ctrl |= 4;
		else {
			legacy_ctrl2 &= ~(3 << 6);
			snd_joystick_port[dev] = -1;
		}
#endif
	}
	pci_read_config_word(pci, 0x40, &old_legacy_ctrl);
	switch (snd_mpu_irq[dev]) {
	case 5:	break;
	case 7:	legacy_ctrl |= 1 << 11; break;
	case 9: legacy_ctrl |= 2 << 11; break;
	case 10: legacy_ctrl |= 3 << 11; break;
	case 11: legacy_ctrl |= 4 << 11; break;
	default: snd_mpu_irq[dev] = -1; break;
	}
	legacy_ctrl |= (snd_mpu_irq[dev] > 0 ? 0x10 : 0);	/* MPU401 IRQ enable */
	snd_printdd("legacy_ctrl = 0x%x\n", legacy_ctrl);
	pci_write_config_word(pci, 0x40, legacy_ctrl);
	snd_printdd("legacy_ctrl2 = 0x%x\n", legacy_ctrl2);
	pci_write_config_word(pci, 0x42, legacy_ctrl2);
	if ((err = snd_ymfpci_create(card, pci,
				     old_legacy_ctrl,
			 	     &chip)) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_ymfpci_pcm(chip, 0, NULL)) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_ymfpci_pcm_spdif(chip, 1, NULL)) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_ymfpci_pcm_4ch(chip, 2, NULL)) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_ymfpci_pcm2(chip, 3, NULL)) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_ymfpci_mixer(chip)) < 0) {
		snd_card_free(card);
		return err;
	}
	if (snd_mpu_port[dev] > 0) {
		if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI,
					       snd_mpu_port[dev], 0,
					       snd_mpu_irq[dev] > 0 ? snd_mpu_irq[dev] : -1, SA_INTERRUPT, NULL)) < 0) {
			snd_card_free(card);
			return err;
		}
	}
	if (snd_fm_port[dev] > 0) {
		if ((err = snd_opl3_create(card,
					   snd_fm_port[dev],
					   snd_fm_port[dev] + 2,
					   OPL3_HW_OPL3, 0, &opl3)) < 0) {
			snd_card_free(card);
			return err;
		}
		if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
			snd_card_free(card);
			return err;
		}
	}
	strcpy(card->driver, str);
	sprintf(card->shortname, "Yamaha DS-XG PCI (%s)", str);
	sprintf(card->longname, "%s at 0x%lx, irq %i",
		card->shortname,
		chip->reg_area_virt,
		chip->irq);

	if ((err = snd_card_register(card)) < 0) {
		snd_card_free(card);
		return err;
	}
	PCI_SET_DRIVER_DATA(pci, chip);
	dev++;
	return 0;
}