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;
}
Example #2
0
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;
}