diff options
Diffstat (limited to '')
-rw-r--r-- | sound/pci/emu10k1/emu10k1x.c | 196 |
1 files changed, 78 insertions, 118 deletions
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index ddb7c2ce3f7c..89043392f3ec 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c @@ -31,7 +31,6 @@ MODULE_AUTHOR("Francisco Moraes <fmoraes@nc.rr.com>"); MODULE_DESCRIPTION("EMU10K1X"); MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{Dell Creative Labs,SB Live!}"); // module parameters (see "Module Parameters") static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; @@ -217,7 +216,6 @@ struct emu10k1x { struct pci_dev *pci; unsigned long port; - struct resource *res_port; int irq; unsigned char revision; /* chip revision */ @@ -234,7 +232,7 @@ struct emu10k1x { struct emu10k1x_voice capture_voice; u32 spdif_bits[3]; // SPDIF out setup - struct snd_dma_buffer dma_buffer; + struct snd_dma_buffer *dma_buffer; struct emu10k1x_midi midi; }; @@ -350,7 +348,8 @@ static void snd_emu10k1x_pcm_interrupt(struct emu10k1x *emu, struct emu10k1x_voi { struct emu10k1x_pcm *epcm; - if ((epcm = voice->epcm) == NULL) + epcm = voice->epcm; + if (!epcm) return; if (epcm->substream == NULL) return; @@ -372,10 +371,11 @@ static int snd_emu10k1x_playback_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; int err; - if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) { + err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); + if (err < 0) return err; - } - if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0) + err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64); + if (err < 0) return err; epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); @@ -441,7 +441,7 @@ static int snd_emu10k1x_pcm_prepare(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct emu10k1x_pcm *epcm = runtime->private_data; int voice = epcm->voice->number; - u32 *table_base = (u32 *)(emu->dma_buffer.area+1024*voice); + u32 *table_base = (u32 *)(emu->dma_buffer->area+1024*voice); u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size); int i; @@ -450,7 +450,7 @@ static int snd_emu10k1x_pcm_prepare(struct snd_pcm_substream *substream) *table_base++=period_size_bytes<<16; } - snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_ADDR, voice, emu->dma_buffer.addr+1024*voice); + snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_ADDR, voice, emu->dma_buffer->addr+1024*voice); snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_SIZE, voice, (runtime->periods - 1) << 19); snd_emu10k1x_ptr_write(emu, PLAYBACK_LIST_PTR, voice, 0); snd_emu10k1x_ptr_write(emu, PLAYBACK_POINTER, voice, 0); @@ -551,10 +551,12 @@ static int snd_emu10k1x_pcm_open_capture(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; int err; - if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) - return err; - if ((err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64)) < 0) - return err; + err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); + if (err < 0) + return err; + err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64); + if (err < 0) + return err; epcm = kzalloc(sizeof(*epcm), GFP_KERNEL); if (epcm == NULL) @@ -723,7 +725,8 @@ static int snd_emu10k1x_ac97(struct emu10k1x *chip) .read = snd_emu10k1x_ac97_read, }; - if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0) + err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus); + if (err < 0) return err; pbus->no_vra = 1; /* we don't need VRA */ @@ -733,37 +736,15 @@ static int snd_emu10k1x_ac97(struct emu10k1x *chip) return snd_ac97_mixer(pbus, &ac97, &chip->ac97); } -static int snd_emu10k1x_free(struct emu10k1x *chip) +static void snd_emu10k1x_free(struct snd_card *card) { + struct emu10k1x *chip = card->private_data; + snd_emu10k1x_ptr_write(chip, TRIGGER_CHANNEL, 0, 0); // disable interrupts outl(0, chip->port + INTE); // disable audio outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG); - - /* release the irq */ - if (chip->irq >= 0) - free_irq(chip->irq, chip); - - // release the i/o port - release_and_free_resource(chip->res_port); - - // release the DMA - if (chip->dma_buffer.area) { - snd_dma_free_pages(&chip->dma_buffer); - } - - pci_disable_device(chip->pci); - - // release the data - kfree(chip); - return 0; -} - -static int snd_emu10k1x_dev_free(struct snd_device *device) -{ - struct emu10k1x *chip = device->device_data; - return snd_emu10k1x_free(chip); } static irqreturn_t snd_emu10k1x_interrupt(int irq, void *dev_id) @@ -839,7 +820,8 @@ static int snd_emu10k1x_pcm(struct emu10k1x *emu, int device) if (device == 0) capture = 1; - if ((err = snd_pcm_new(emu->card, "emu10k1x", device, 1, capture, &pcm)) < 0) + err = snd_pcm_new(emu->card, "emu10k1x", device, 1, capture, &pcm); + if (err < 0) return err; pcm->private_data = emu; @@ -880,33 +862,21 @@ static int snd_emu10k1x_pcm(struct emu10k1x *emu, int device) } static int snd_emu10k1x_create(struct snd_card *card, - struct pci_dev *pci, - struct emu10k1x **rchip) + struct pci_dev *pci) { - struct emu10k1x *chip; + struct emu10k1x *chip = card->private_data; int err; int ch; - static const struct snd_device_ops ops = { - .dev_free = snd_emu10k1x_dev_free, - }; - - *rchip = NULL; - if ((err = pci_enable_device(pci)) < 0) + err = pcim_enable_device(pci); + if (err < 0) return err; - if (pci_set_dma_mask(pci, DMA_BIT_MASK(28)) < 0 || - pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(28)) < 0) { + + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(28)) < 0) { dev_err(card->dev, "error to set 28bit mask DMA\n"); - pci_disable_device(pci); return -ENXIO; } - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (chip == NULL) { - pci_disable_device(pci); - return -ENOMEM; - } - chip->card = card; chip->pci = pci; chip->irq = -1; @@ -914,29 +884,24 @@ static int snd_emu10k1x_create(struct snd_card *card, spin_lock_init(&chip->emu_lock); spin_lock_init(&chip->voice_lock); + err = pci_request_regions(pci, "EMU10K1X"); + if (err < 0) + return err; chip->port = pci_resource_start(pci, 0); - if ((chip->res_port = request_region(chip->port, 8, - "EMU10K1X")) == NULL) { - dev_err(card->dev, "cannot allocate the port 0x%lx\n", - chip->port); - snd_emu10k1x_free(chip); - return -EBUSY; - } - if (request_irq(pci->irq, snd_emu10k1x_interrupt, - IRQF_SHARED, KBUILD_MODNAME, chip)) { + if (devm_request_irq(&pci->dev, pci->irq, snd_emu10k1x_interrupt, + IRQF_SHARED, KBUILD_MODNAME, chip)) { dev_err(card->dev, "cannot grab irq %d\n", pci->irq); - snd_emu10k1x_free(chip); return -EBUSY; } chip->irq = pci->irq; card->sync_irq = chip->irq; + card->private_free = snd_emu10k1x_free; - if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev, - 4 * 1024, &chip->dma_buffer) < 0) { - snd_emu10k1x_free(chip); + chip->dma_buffer = snd_devm_alloc_pages(&pci->dev, SNDRV_DMA_TYPE_DEV, + 4 * 1024); + if (!chip->dma_buffer) return -ENOMEM; - } pci_set_master(pci); /* read revision & serial */ @@ -992,12 +957,6 @@ static int snd_emu10k1x_create(struct snd_card *card, outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG); - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, - chip, &ops)) < 0) { - snd_emu10k1x_free(chip); - return err; - } - *rchip = chip; return 0; } @@ -1040,7 +999,7 @@ static void snd_emu10k1x_proc_reg_write(struct snd_info_entry *entry, if (sscanf(line, "%x %x %x", ®, &channel_id, &val) != 3) continue; - if (reg < 0x49 && val <= 0xffffffff && channel_id <= 2) + if (reg < 0x49 && channel_id <= 2) snd_emu10k1x_ptr_write(emu, reg, channel_id, val); } } @@ -1172,17 +1131,23 @@ static int snd_emu10k1x_mixer(struct emu10k1x *emu) struct snd_kcontrol *kctl; struct snd_card *card = emu->card; - if ((kctl = snd_ctl_new1(&snd_emu10k1x_spdif_mask_control, emu)) == NULL) + kctl = snd_ctl_new1(&snd_emu10k1x_spdif_mask_control, emu); + if (!kctl) return -ENOMEM; - if ((err = snd_ctl_add(card, kctl))) + err = snd_ctl_add(card, kctl); + if (err) return err; - if ((kctl = snd_ctl_new1(&snd_emu10k1x_shared_spdif, emu)) == NULL) + kctl = snd_ctl_new1(&snd_emu10k1x_shared_spdif, emu); + if (!kctl) return -ENOMEM; - if ((err = snd_ctl_add(card, kctl))) + err = snd_ctl_add(card, kctl); + if (err) return err; - if ((kctl = snd_ctl_new1(&snd_emu10k1x_spdif_control, emu)) == NULL) + kctl = snd_ctl_new1(&snd_emu10k1x_spdif_control, emu); + if (!kctl) return -ENOMEM; - if ((err = snd_ctl_add(card, kctl))) + err = snd_ctl_add(card, kctl); + if (err) return err; return 0; @@ -1489,7 +1454,8 @@ static int emu10k1x_midi_init(struct emu10k1x *emu, struct snd_rawmidi *rmidi; int err; - if ((err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi)) < 0) + err = snd_rawmidi_new(emu->card, name, device, 1, 1, &rmidi); + if (err < 0) return err; midi->emu = emu; spin_lock_init(&midi->open_lock); @@ -1512,7 +1478,8 @@ static int snd_emu10k1x_midi(struct emu10k1x *emu) struct emu10k1x_midi *midi = &emu->midi; int err; - if ((err = emu10k1x_midi_init(emu, midi, 0, "EMU10K1X MPU-401 (UART)")) < 0) + err = emu10k1x_midi_init(emu, midi, 0, "EMU10K1X MPU-401 (UART)"); + if (err < 0) return err; midi->tx_enable = INTE_MIDITXENABLE; @@ -1524,8 +1491,8 @@ static int snd_emu10k1x_midi(struct emu10k1x *emu) return 0; } -static int snd_emu10k1x_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) +static int __snd_emu10k1x_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) { static int dev; struct snd_card *card; @@ -1539,43 +1506,37 @@ static int snd_emu10k1x_probe(struct pci_dev *pci, return -ENOENT; } - err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, - 0, &card); + err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, + sizeof(*chip), &card); if (err < 0) return err; + chip = card->private_data; - if ((err = snd_emu10k1x_create(card, pci, &chip)) < 0) { - snd_card_free(card); + err = snd_emu10k1x_create(card, pci); + if (err < 0) return err; - } - if ((err = snd_emu10k1x_pcm(chip, 0)) < 0) { - snd_card_free(card); + err = snd_emu10k1x_pcm(chip, 0); + if (err < 0) return err; - } - if ((err = snd_emu10k1x_pcm(chip, 1)) < 0) { - snd_card_free(card); + err = snd_emu10k1x_pcm(chip, 1); + if (err < 0) return err; - } - if ((err = snd_emu10k1x_pcm(chip, 2)) < 0) { - snd_card_free(card); + err = snd_emu10k1x_pcm(chip, 2); + if (err < 0) return err; - } - if ((err = snd_emu10k1x_ac97(chip)) < 0) { - snd_card_free(card); + err = snd_emu10k1x_ac97(chip); + if (err < 0) return err; - } - if ((err = snd_emu10k1x_mixer(chip)) < 0) { - snd_card_free(card); + err = snd_emu10k1x_mixer(chip); + if (err < 0) return err; - } - if ((err = snd_emu10k1x_midi(chip)) < 0) { - snd_card_free(card); + err = snd_emu10k1x_midi(chip); + if (err < 0) return err; - } snd_emu10k1x_proc_init(chip); @@ -1584,19 +1545,19 @@ static int snd_emu10k1x_probe(struct pci_dev *pci, sprintf(card->longname, "%s at 0x%lx irq %i", card->shortname, chip->port, chip->irq); - if ((err = snd_card_register(card)) < 0) { - snd_card_free(card); + err = snd_card_register(card); + if (err < 0) return err; - } pci_set_drvdata(pci, card); dev++; return 0; } -static void snd_emu10k1x_remove(struct pci_dev *pci) +static int snd_emu10k1x_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) { - snd_card_free(pci_get_drvdata(pci)); + return snd_card_free_on_error(&pci->dev, __snd_emu10k1x_probe(pci, pci_id)); } // PCI IDs @@ -1611,7 +1572,6 @@ static struct pci_driver emu10k1x_driver = { .name = KBUILD_MODNAME, .id_table = snd_emu10k1x_ids, .probe = snd_emu10k1x_probe, - .remove = snd_emu10k1x_remove, }; module_pci_driver(emu10k1x_driver); |