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; }
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; }