static int snd_nm256_free(nm256_t *chip) { if (chip->streams[SNDRV_PCM_STREAM_PLAYBACK].running) snd_nm256_playback_stop(chip); if (chip->streams[SNDRV_PCM_STREAM_CAPTURE].running) snd_nm256_capture_stop(chip); if (chip->irq >= 0) synchronize_irq(chip->irq); if (chip->cport) iounmap(chip->cport); if (chip->buffer) iounmap(chip->buffer); if (chip->res_cport) { release_resource(chip->res_cport); kfree_nocheck(chip->res_cport); } if (chip->res_buffer) { release_resource(chip->res_buffer); kfree_nocheck(chip->res_buffer); } if (chip->irq >= 0) free_irq(chip->irq, (void*)chip); pci_disable_device(chip->pci); kfree(chip); return 0; }
static int snd_gus_free(snd_gus_card_t *gus) { if (gus->gf1.res_port2 == NULL) goto __hw_end; #if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE)) if (gus->seq_dev) { snd_device_free(gus->card, gus->seq_dev); gus->seq_dev = NULL; } #endif snd_gf1_stop(gus); snd_gus_init_dma_irq(gus, 0); __hw_end: if (gus->gf1.res_port1) { release_resource(gus->gf1.res_port1); kfree_nocheck(gus->gf1.res_port1); } if (gus->gf1.res_port2) { release_resource(gus->gf1.res_port2); kfree_nocheck(gus->gf1.res_port2); } if (gus->gf1.irq >= 0) free_irq(gus->gf1.irq, (void *) gus); if (gus->gf1.dma1 >= 0) { disable_dma(gus->gf1.dma1); free_dma(gus->gf1.dma1); } if (!gus->equal_dma && gus->gf1.dma2 >= 0) { disable_dma(gus->gf1.dma2); free_dma(gus->gf1.dma2); } kfree(gus); return 0; }
static int snd_opl3_free(opl3_t *opl3) { if (opl3->res_l_port) { release_resource(opl3->res_l_port); kfree_nocheck(opl3->res_l_port); } if (opl3->res_r_port) { release_resource(opl3->res_r_port); kfree_nocheck(opl3->res_r_port); } snd_magic_kfree(opl3); return 0; }
/* * Do the necessary ALSA-level cleanup to deallocate our driver ... */ static void soundscape_free(snd_card_t * c) { register struct soundscape *sscape = get_card_soundscape(c); release_resource(sscape->io_res); kfree_nocheck(sscape->io_res); free_dma(sscape->chip->dma1); }
static void snd_mpu401_uart_free(snd_rawmidi_t *rmidi) { mpu401_t *mpu = rmidi->private_data; if (mpu->irq_flags && mpu->irq >= 0) free_irq(mpu->irq, (void *) mpu); if (mpu->res) { release_resource(mpu->res); kfree_nocheck(mpu->res); } kfree(mpu); }
static int snd_uart16550_free(snd_uart16550_t *uart) { if (uart->irq >= 0) free_irq(uart->irq, (void *)uart); if (uart->res_base) { release_resource(uart->res_base); kfree_nocheck(uart->res_base); } snd_magic_kfree(uart); return 0; };
void snd_ymfpci_free_gameport(ymfpci_t *chip) { if (chip->gameport) { struct resource *r = gameport_get_port_data(chip->gameport); gameport_unregister_port(chip->gameport); chip->gameport = NULL; release_resource(r); kfree_nocheck(r); } }
static int snd_vx222_free(vx_core_t *chip) { int i; struct snd_vx222 *vx = (struct snd_vx222 *)chip; if (chip->irq >= 0) free_irq(chip->irq, (void*)chip); for (i = 0; i < 2; i++) { if (vx->port_res[i]) { release_resource(vx->port_res[i]); kfree_nocheck(vx->port_res[i]); } } snd_magic_kfree(chip); return 0; }
static int __devinit snd_ymfpci_create_gameport(ymfpci_t *chip, int dev, int legacy_ctrl, int legacy_ctrl2) { struct gameport *gp; struct resource *r = NULL; int io_port = joystick_port[dev]; if (!io_port) return -ENODEV; if (chip->pci->device >= 0x0010) { /* YMF 744/754 */ if (io_port == 1) { /* auto-detect */ if (!(io_port = pci_resource_start(chip->pci, 2))) return -ENODEV; } } else { if (io_port == 1) { /* auto-detect */ for (io_port = 0x201; io_port <= 0x205; io_port++) { if (io_port == 0x203) continue; if ((r = request_region(io_port, 1, "YMFPCI gameport")) != NULL) break; } if (!r) { printk(KERN_ERR "ymfpci: no gameport ports available\n"); return -EBUSY; } } switch (io_port) { 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: printk(KERN_ERR "ymfpci: invalid joystick port %#x", io_port); return -EINVAL; } } if (!r && !(r = request_region(io_port, 1, "YMFPCI gameport"))) { printk(KERN_ERR "ymfpci: joystick port %#x is in use.\n", io_port); return -EBUSY; } chip->gameport = gp = gameport_allocate_port(); if (!gp) { printk(KERN_ERR "ymfpci: cannot allocate memory for gameport\n"); release_resource(r); kfree_nocheck(r); return -ENOMEM; } gameport_set_name(gp, "Yamaha YMF Gameport"); gameport_set_phys(gp, "pci%s/gameport0", pci_name(chip->pci)); gameport_set_dev_parent(gp, &chip->pci->dev); gp->io = io_port; gameport_set_port_data(gp, r); if (chip->pci->device >= 0x0010) /* YMF 744/754 */ pci_write_config_word(chip->pci, PCIR_DSXG_JOYBASE, io_port); pci_write_config_word(chip->pci, PCIR_DSXG_LEGACY, legacy_ctrl | YMFPCI_LEGACY_JPEN); pci_write_config_word(chip->pci, PCIR_DSXG_ELEGACY, legacy_ctrl2); gameport_register_port(chip->gameport); return 0; }
static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { static int dev; snd_card_t *card; struct resource *fm_res = NULL; struct resource *mpu_res = NULL; ymfpci_t *chip; opl3_t *opl3; char *str; 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"; 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 = 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); if (mpu_res) { release_resource(mpu_res); kfree_nocheck(mpu_res); } if (fm_res) { release_resource(fm_res); kfree_nocheck(fm_res); } return err; } chip->fm_res = fm_res; chip->mpu_res = mpu_res; strcpy(card->driver, str); sprintf(card->shortname, "Yamaha DS-XG (%s)", 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], 1, 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("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; }
/* * Create an ALSA soundcard entry for the SoundScape, using * the given list of port, IRQ and DMA resources. */ static int __devinit create_sscape(const struct params *params, snd_card_t **rcardp) { snd_card_t *card; register struct soundscape *sscape; register unsigned dma_cfg; unsigned irq_cfg; unsigned mpu_irq_cfg; struct resource *io_res; unsigned long flags; int err; /* * Check that the user didn't pass us garbage data ... */ irq_cfg = get_irq_config(params->irq); if (irq_cfg == INVALID_IRQ) { snd_printk(KERN_ERR "sscape: Invalid IRQ %d\n", params->irq); return -ENXIO; } mpu_irq_cfg = get_irq_config(params->mpu_irq); if (mpu_irq_cfg == INVALID_IRQ) { printk(KERN_ERR "sscape: Invalid IRQ %d\n", params->mpu_irq); return -ENXIO; } /* * Grab IO ports that we will need to probe so that we * can detect and control this hardware ... */ if ((io_res = request_region(params->port, 8, "SoundScape")) == NULL) { snd_printk(KERN_ERR "sscape: can't grab port 0x%x\n", params->port); return -EBUSY; } /* * Grab both DMA channels (OK, only one for now) ... */ if ((err = request_dma(params->dma1, "SoundScape")) < 0) { snd_printk(KERN_ERR "sscape: can't grab DMA %d\n", params->dma1); goto _release_region; } /* * Create a new ALSA sound card entry, in anticipation * of detecting our hardware ... */ if ((card = snd_card_new(params->index, params->id, THIS_MODULE, sizeof(struct soundscape))) == NULL) { err = -ENOMEM; goto _release_dma; } sscape = get_card_soundscape(card); spin_lock_init(&sscape->lock); spin_lock_init(&sscape->fwlock); sscape->io_res = io_res; sscape->io_base = params->port; if (!detect_sscape(sscape)) { printk(KERN_ERR "sscape: hardware not detected at 0x%x\n", sscape->io_base); err = -ENODEV; goto _release_card; } printk(KERN_INFO "sscape: hardware detected at 0x%x, using IRQ %d, DMA %d\n", sscape->io_base, params->irq, params->dma1); /* * Now create the hardware-specific device so that we can * load the microcode into the on-board processor. * We cannot use the MPU-401 MIDI system until this firmware * has been loaded into the card. */ if ((err = snd_hwdep_new(card, "MC68EC000", 0, &(sscape->hw))) < 0) { printk(KERN_ERR "sscape: Failed to create firmware device\n"); goto _release_card; } strlcpy(sscape->hw->name, "SoundScape M68K", sizeof(sscape->hw->name)); sscape->hw->name[sizeof(sscape->hw->name) - 1] = '\0'; sscape->hw->iface = SNDRV_HWDEP_IFACE_SSCAPE; sscape->hw->ops.open = sscape_hw_open; sscape->hw->ops.release = sscape_hw_release; sscape->hw->ops.ioctl = sscape_hw_ioctl; sscape->hw->private_data = sscape; /* * Tell the on-board devices where their resources are (I think - * I can't be sure without a datasheet ... So many magic values!) */ spin_lock_irqsave(&sscape->lock, flags); activate_ad1845_unsafe(sscape->io_base); sscape_write_unsafe(sscape->io_base, GA_INTENA_REG, 0x00); /* disable */ sscape_write_unsafe(sscape->io_base, GA_SMCFGA_REG, 0x2e); sscape_write_unsafe(sscape->io_base, GA_SMCFGB_REG, 0x00); /* * Enable and configure the DMA channels ... */ sscape_write_unsafe(sscape->io_base, GA_DMACFG_REG, 0x50); dma_cfg = (sscape->ic_type == IC_ODIE ? 0x70 : 0x40); sscape_write_unsafe(sscape->io_base, GA_DMAA_REG, dma_cfg); sscape_write_unsafe(sscape->io_base, GA_DMAB_REG, 0x20); sscape_write_unsafe(sscape->io_base, GA_INTCFG_REG, 0xf0 | (mpu_irq_cfg << 2) | mpu_irq_cfg); sscape_write_unsafe(sscape->io_base, GA_CDCFG_REG, 0x09 | DMA_8BIT | (params->dma1 << 4) | (irq_cfg << 1)); spin_unlock_irqrestore(&sscape->lock, flags); /* * We have now enabled the codec chip, and so we should * detect the AD1845 device ... */ if ((err = create_ad1845(card, CODEC_IO(params->port), params->irq, params->dma1)) < 0) { printk(KERN_ERR "sscape: No AD1845 device at 0x%x, IRQ %d\n", CODEC_IO(params->port), params->irq); goto _release_card; } #define MIDI_DEVNUM 0 if ((err = create_mpu401(card, MIDI_DEVNUM, MPU401_IO(params->port), params->mpu_irq)) < 0) { printk(KERN_ERR "sscape: Failed to create MPU-401 device at 0x%x\n", MPU401_IO(params->port)); goto _release_card; } /* * Enable the master IRQ ... */ sscape_write(sscape, GA_INTENA_REG, 0x80); if ((err = snd_card_register(card)) < 0) { printk(KERN_ERR "sscape: Failed to register sound card\n"); goto _release_card; } /* * Initialize mixer */ sscape->midi_vol = 0; host_write_ctrl_unsafe(sscape->io_base, CMD_SET_MIDI_VOL, 100); host_write_ctrl_unsafe(sscape->io_base, 0, 100); host_write_ctrl_unsafe(sscape->io_base, CMD_XXX_MIDI_VOL, 100); /* * Now that we have successfully created this sound card, * it is safe to store the pointer. * NOTE: we only register the sound card's "destructor" * function now that our "constructor" has completed. */ card->private_free = soundscape_free; *rcardp = card; return 0; _release_card: snd_card_free(card); _release_dma: free_dma(params->dma1); _release_region: release_resource(io_res); kfree_nocheck(io_res); return err; }