diff options
Diffstat (limited to 'sound/pci/ali5451/ali5451.c')
| -rw-r--r-- | sound/pci/ali5451/ali5451.c | 311 |
1 files changed, 90 insertions, 221 deletions
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index 9f569379b77e..571d89a6a8da 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Matt Wu <Matt_Wu@acersoftech.com.cn> * Apr 26, 2001 @@ -8,21 +9,6 @@ * * TODO: * -- - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public Lcodecnse as published by - * the Free Software Foundation; either version 2 of the Lcodecnse, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public Lcodecnse for more details. - * - * You should have received a copy of the GNU General Public Lcodecnse - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * */ #include <linux/io.h> @@ -43,7 +29,6 @@ MODULE_AUTHOR("Matt Wu <Matt_Wu@acersoftech.com.cn>"); MODULE_DESCRIPTION("ALI M5451"); MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{ALI,M5451,pci},{ALI,M5451}}"); static int index = SNDRV_DEFAULT_IDX1; /* Index */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ @@ -258,9 +243,7 @@ struct snd_ali { spinlock_t reg_lock; spinlock_t voice_alloc; -#ifdef CONFIG_PM_SLEEP - struct snd_ali_image *image; -#endif + struct snd_ali_image image; }; static const struct pci_device_id snd_ali_ids[] = { @@ -309,7 +292,7 @@ static int snd_ali_codec_ready(struct snd_ali *codec, } snd_ali_5451_poke(codec, port, res & ~0x8000); - dev_dbg(codec->card->dev, "ali_codec_ready: codec is not ready.\n "); + dev_dbg(codec->card->dev, "ali_codec_ready: codec is not ready.\n"); return -EIO; } @@ -928,13 +911,12 @@ static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, dev_dbg(codec->card->dev, "alloc_voice: type=%d rec=%d\n", type, rec); - spin_lock_irq(&codec->voice_alloc); + guard(spinlock_irq)(&codec->voice_alloc); if (type == SNDRV_ALI_VOICE_TYPE_PCM) { idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) : snd_ali_find_free_channel(codec,rec); if (idx < 0) { dev_err(codec->card->dev, "ali_alloc_voice: err.\n"); - spin_unlock_irq(&codec->voice_alloc); return NULL; } pvoice = &(codec->synth.voices[idx]); @@ -942,10 +924,8 @@ static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, pvoice->use = 1; pvoice->pcm = 1; pvoice->mode = rec; - spin_unlock_irq(&codec->voice_alloc); return pvoice; } - spin_unlock_irq(&codec->voice_alloc); return NULL; } @@ -960,16 +940,16 @@ static void snd_ali_free_voice(struct snd_ali * codec, if (!pvoice->use) return; snd_ali_clear_voices(codec, pvoice->number, pvoice->number); - spin_lock_irq(&codec->voice_alloc); - private_free = pvoice->private_free; - private_data = pvoice->private_data; - pvoice->private_free = NULL; - pvoice->private_data = NULL; - if (pvoice->pcm) - snd_ali_free_channel_pcm(codec, pvoice->number); - pvoice->use = pvoice->pcm = pvoice->synth = 0; - pvoice->substream = NULL; - spin_unlock_irq(&codec->voice_alloc); + scoped_guard(spinlock_irq, &codec->voice_alloc) { + private_free = pvoice->private_free; + private_data = pvoice->private_data; + pvoice->private_free = NULL; + pvoice->private_data = NULL; + if (pvoice->pcm) + snd_ali_free_channel_pcm(codec, pvoice->number); + pvoice->use = pvoice->pcm = pvoice->synth = 0; + pvoice->substream = NULL; + } if (private_free) private_free(private_data); } @@ -1084,7 +1064,7 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream, { struct snd_ali *codec = snd_pcm_substream_chip(substream); struct snd_pcm_substream *s; - unsigned int what, whati, capture_flag; + unsigned int what, whati; struct snd_ali_voice *pvoice, *evoice; unsigned int val; int do_start; @@ -1102,7 +1082,7 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream, return -EINVAL; } - what = whati = capture_flag = 0; + what = whati = 0; snd_pcm_group_for_each_entry(s, substream) { if ((struct snd_ali *) snd_pcm_substream_chip(s) == codec) { pvoice = s->runtime->private_data; @@ -1124,11 +1104,9 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream, evoice->running = 0; } snd_pcm_trigger_done(s, substream); - if (pvoice->mode) - capture_flag = 1; } } - spin_lock(&codec->reg_lock); + guard(spinlock)(&codec->reg_lock); if (!do_start) outl(what, ALI_REG(codec, ALI_STOP)); val = inl(ALI_REG(codec, ALI_AINTEN)); @@ -1140,7 +1118,6 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream, if (do_start) outl(what, ALI_REG(codec, ALI_START)); dev_dbg(codec->card->dev, "trigger: what=%xh whati=%xh\n", what, whati); - spin_unlock(&codec->reg_lock); return 0; } @@ -1152,13 +1129,7 @@ static int snd_ali_playback_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime = substream->runtime; struct snd_ali_voice *pvoice = runtime->private_data; struct snd_ali_voice *evoice = pvoice->extra; - int err; - err = snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); - if (err < 0) - return err; - /* voice management */ if (params_buffer_size(hw_params) / 2 != @@ -1189,7 +1160,6 @@ static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream) struct snd_ali_voice *pvoice = runtime->private_data; struct snd_ali_voice *evoice = pvoice ? pvoice->extra : NULL; - snd_pcm_lib_free_pages(substream); if (evoice) { snd_ali_free_voice(codec, evoice); pvoice->extra = NULL; @@ -1197,18 +1167,6 @@ static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream) return 0; } -static int snd_ali_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - return snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); -} - -static int snd_ali_hw_free(struct snd_pcm_substream *substream) -{ - return snd_pcm_lib_free_pages(substream); -} - static int snd_ali_playback_prepare(struct snd_pcm_substream *substream) { struct snd_ali *codec = snd_pcm_substream_chip(substream); @@ -1227,8 +1185,8 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream) dev_dbg(codec->card->dev, "playback_prepare ...\n"); - spin_lock_irq(&codec->reg_lock); - + guard(spinlock_irq)(&codec->reg_lock); + /* set Delta (rate) value */ Delta = snd_ali_convert_rate(runtime->rate, 0); @@ -1297,7 +1255,6 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream) CTRL, EC); } - spin_unlock_irq(&codec->reg_lock); return 0; } @@ -1398,14 +1355,11 @@ snd_ali_playback_pointer(struct snd_pcm_substream *substream) struct snd_ali_voice *pvoice = runtime->private_data; unsigned int cso; - spin_lock(&codec->reg_lock); - if (!pvoice->running) { - spin_unlock(&codec->reg_lock); + guard(spinlock)(&codec->reg_lock); + if (!pvoice->running) return 0; - } outb(pvoice->number, ALI_REG(codec, ALI_GC_CIR)); cso = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2)); - spin_unlock(&codec->reg_lock); dev_dbg(codec->card->dev, "playback pointer returned cso=%xh.\n", cso); cso %= runtime->buffer_size; @@ -1420,20 +1374,17 @@ static snd_pcm_uframes_t snd_ali_pointer(struct snd_pcm_substream *substream) struct snd_ali_voice *pvoice = runtime->private_data; unsigned int cso; - spin_lock(&codec->reg_lock); - if (!pvoice->running) { - spin_unlock(&codec->reg_lock); + guard(spinlock)(&codec->reg_lock); + if (!pvoice->running) return 0; - } outb(pvoice->number, ALI_REG(codec, ALI_GC_CIR)); cso = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2)); - spin_unlock(&codec->reg_lock); cso %= runtime->buffer_size; return cso; } -static struct snd_pcm_hardware snd_ali_playback = +static const struct snd_pcm_hardware snd_ali_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1459,7 +1410,7 @@ static struct snd_pcm_hardware snd_ali_playback = * Capture support device description */ -static struct snd_pcm_hardware snd_ali_capture = +static const struct snd_pcm_hardware snd_ali_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1490,7 +1441,7 @@ static void snd_ali_pcm_free_substream(struct snd_pcm_runtime *runtime) } static int snd_ali_open(struct snd_pcm_substream *substream, int rec, - int channel, struct snd_pcm_hardware *phw) + int channel, const struct snd_pcm_hardware *phw) { struct snd_ali *codec = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; @@ -1540,7 +1491,6 @@ static int snd_ali_close(struct snd_pcm_substream *substream) static const struct snd_pcm_ops snd_ali_playback_ops = { .open = snd_ali_playback_open, .close = snd_ali_playback_close, - .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_ali_playback_hw_params, .hw_free = snd_ali_playback_hw_free, .prepare = snd_ali_playback_prepare, @@ -1551,9 +1501,6 @@ static const struct snd_pcm_ops snd_ali_playback_ops = { static const struct snd_pcm_ops snd_ali_capture_ops = { .open = snd_ali_capture_open, .close = snd_ali_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_ali_hw_params, - .hw_free = snd_ali_hw_free, .prepare = snd_ali_prepare, .trigger = snd_ali_trigger, .pointer = snd_ali_pointer, @@ -1571,10 +1518,10 @@ static int snd_ali_modem_hw_params(struct snd_pcm_substream *substream, snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE, params_rate(hw_params)); snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_LEVEL, 0); - return snd_ali_hw_params(substream, hw_params); + return 0; } -static struct snd_pcm_hardware snd_ali_modem = +static const struct snd_pcm_hardware snd_ali_modem = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1626,9 +1573,7 @@ static int snd_ali_modem_capture_open(struct snd_pcm_substream *substream) static const struct snd_pcm_ops snd_ali_modem_playback_ops = { .open = snd_ali_modem_playback_open, .close = snd_ali_close, - .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_ali_modem_hw_params, - .hw_free = snd_ali_hw_free, .prepare = snd_ali_prepare, .trigger = snd_ali_trigger, .pointer = snd_ali_pointer, @@ -1637,9 +1582,7 @@ static const struct snd_pcm_ops snd_ali_modem_playback_ops = { static const struct snd_pcm_ops snd_ali_modem_capture_ops = { .open = snd_ali_modem_capture_open, .close = snd_ali_close, - .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_ali_modem_hw_params, - .hw_free = snd_ali_hw_free, .prepare = snd_ali_prepare, .trigger = snd_ali_trigger, .pointer = snd_ali_pointer, @@ -1685,14 +1628,13 @@ static int snd_ali_pcm(struct snd_ali *codec, int device, snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, desc->capture_ops); - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(codec->pci), - 64*1024, 128*1024); + snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, + &codec->pci->dev, 64*1024, 128*1024); pcm->info_flags = 0; pcm->dev_class = desc->class; pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; - strcpy(pcm->name, desc->name); + strscpy(pcm->name, desc->name); codec->pcm[0] = pcm; return 0; } @@ -1735,12 +1677,12 @@ static int snd_ali_build_pcms(struct snd_ali *codec) static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_ali *codec = kcontrol->private_data; + struct snd_ali *codec = snd_kcontrol_chip(kcontrol); unsigned int spdif_enable; spdif_enable = ucontrol->value.integer.value[0] ? 1 : 0; - spin_lock_irq(&codec->reg_lock); + guard(spinlock_irq)(&codec->reg_lock); switch (kcontrol->private_value) { case 0: spdif_enable = (codec->spdif_mask & 0x02) ? 1 : 0; @@ -1756,19 +1698,18 @@ static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, break; } ucontrol->value.integer.value[0] = spdif_enable; - spin_unlock_irq(&codec->reg_lock); return 0; } static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - struct snd_ali *codec = kcontrol->private_data; + struct snd_ali *codec = snd_kcontrol_chip(kcontrol); unsigned int change = 0, spdif_enable = 0; spdif_enable = ucontrol->value.integer.value[0] ? 1 : 0; - spin_lock_irq(&codec->reg_lock); + guard(spinlock_irq)(&codec->reg_lock); switch (kcontrol->private_value) { case 0: change = (codec->spdif_mask & 0x02) ? 1 : 0; @@ -1813,12 +1754,11 @@ static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol, default: break; } - spin_unlock_irq(&codec->reg_lock); return change; } -static struct snd_kcontrol_new snd_ali5451_mixer_spdif[] = { +static const struct snd_kcontrol_new snd_ali5451_mixer_spdif[] = { /* spdif aplayback switch */ /* FIXME: "IEC958 Playback Switch" may conflict with one on ac97_codec */ ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), 0, 0), @@ -1833,7 +1773,7 @@ static int snd_ali_mixer(struct snd_ali *codec) struct snd_ac97_template ac97; unsigned int idx; int i, err; - static struct snd_ac97_bus_ops ops = { + static const struct snd_ac97_bus_ops ops = { .write = snd_ali_codec_write, .read = snd_ali_codec_read, }; @@ -1869,25 +1809,18 @@ static int snd_ali_mixer(struct snd_ali *codec) return 0; } -#ifdef CONFIG_PM_SLEEP static int ali_suspend(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); struct snd_ali *chip = card->private_data; - struct snd_ali_image *im; + struct snd_ali_image *im = &chip->image; int i, j; - im = chip->image; - if (!im) - return 0; - snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - for (i = 0; i < chip->num_of_codecs; i++) { - snd_pcm_suspend_all(chip->pcm[i]); + for (i = 0; i < chip->num_of_codecs; i++) snd_ac97_suspend(chip->ac97[i]); - } - spin_lock_irq(&chip->reg_lock); + guard(spinlock_irq)(&chip->reg_lock); im->regs[ALI_MISCINT >> 2] = inl(ALI_REG(chip, ALI_MISCINT)); /* im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START)); */ @@ -1911,7 +1844,6 @@ static int ali_suspend(struct device *dev) /* stop all HW channel */ outl(0xffffffff, ALI_REG(chip, ALI_STOP)); - spin_unlock_irq(&chip->reg_lock); return 0; } @@ -1919,34 +1851,28 @@ static int ali_resume(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); struct snd_ali *chip = card->private_data; - struct snd_ali_image *im; + struct snd_ali_image *im = &chip->image; int i, j; - im = chip->image; - if (!im) - return 0; - - spin_lock_irq(&chip->reg_lock); - - for (i = 0; i < ALI_CHANNELS; i++) { - outb(i, ALI_REG(chip, ALI_GC_CIR)); - for (j = 0; j < ALI_CHANNEL_REGS; j++) - outl(im->channel_regs[i][j], ALI_REG(chip, j*4 + 0xe0)); - } + scoped_guard(spinlock_irq, &chip->reg_lock) { + for (i = 0; i < ALI_CHANNELS; i++) { + outb(i, ALI_REG(chip, ALI_GC_CIR)); + for (j = 0; j < ALI_CHANNEL_REGS; j++) + outl(im->channel_regs[i][j], ALI_REG(chip, j*4 + 0xe0)); + } - for (i = 0; i < ALI_GLOBAL_REGS; i++) { - if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) || - (i*4 == ALI_START)) - continue; - outl(im->regs[i], ALI_REG(chip, i*4)); + for (i = 0; i < ALI_GLOBAL_REGS; i++) { + if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) || + (i*4 == ALI_START)) + continue; + outl(im->regs[i], ALI_REG(chip, i*4)); + } + + /* start HW channel */ + outl(im->regs[ALI_START >> 2], ALI_REG(chip, ALI_START)); + /* restore IRQ enable bits */ + outl(im->regs[ALI_MISCINT >> 2], ALI_REG(chip, ALI_MISCINT)); } - - /* start HW channel */ - outl(im->regs[ALI_START >> 2], ALI_REG(chip, ALI_START)); - /* restore IRQ enable bits */ - outl(im->regs[ALI_MISCINT >> 2], ALI_REG(chip, ALI_MISCINT)); - - spin_unlock_irq(&chip->reg_lock); for (i = 0 ; i < chip->num_of_codecs; i++) snd_ac97_resume(chip->ac97[i]); @@ -1955,28 +1881,16 @@ static int ali_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(ali_pm, ali_suspend, ali_resume); -#define ALI_PM_OPS &ali_pm -#else -#define ALI_PM_OPS NULL -#endif /* CONFIG_PM_SLEEP */ +static DEFINE_SIMPLE_DEV_PM_OPS(ali_pm, ali_suspend, ali_resume); -static int snd_ali_free(struct snd_ali * codec) +static void snd_ali_free(struct snd_card *card) { + struct snd_ali *codec = card->private_data; + if (codec->hw_initialized) snd_ali_disable_address_interrupt(codec); - if (codec->irq >= 0) - free_irq(codec->irq, codec); - if (codec->port) - pci_release_regions(codec->pci); - pci_disable_device(codec->pci); -#ifdef CONFIG_PM_SLEEP - kfree(codec->image); -#endif pci_dev_put(codec->pci_m1533); pci_dev_put(codec->pci_m7101); - kfree(codec); - return 0; } static int snd_ali_chip_init(struct snd_ali *codec) @@ -2051,9 +1965,7 @@ static void snd_ali_proc_read(struct snd_info_entry *entry, static void snd_ali_proc_init(struct snd_ali *codec) { - struct snd_info_entry *entry; - if (!snd_card_proc_new(codec->card, "ali5451", &entry)) - snd_info_set_text_ops(entry, codec, snd_ali_proc_read); + snd_card_ro_proc_new(codec->card, "ali5451", codec, snd_ali_proc_read); } static int snd_ali_resources(struct snd_ali *codec) @@ -2061,63 +1973,45 @@ static int snd_ali_resources(struct snd_ali *codec) int err; dev_dbg(codec->card->dev, "resources allocation ...\n"); - err = pci_request_regions(codec->pci, "ALI 5451"); + err = pcim_request_all_regions(codec->pci, "ALI 5451"); if (err < 0) return err; codec->port = pci_resource_start(codec->pci, 0); - if (request_irq(codec->pci->irq, snd_ali_card_interrupt, - IRQF_SHARED, KBUILD_MODNAME, codec)) { + if (devm_request_irq(&codec->pci->dev, codec->pci->irq, + snd_ali_card_interrupt, + IRQF_SHARED, KBUILD_MODNAME, codec)) { dev_err(codec->card->dev, "Unable to request irq.\n"); return -EBUSY; } codec->irq = codec->pci->irq; + codec->card->sync_irq = codec->irq; dev_dbg(codec->card->dev, "resources allocated.\n"); return 0; } -static int snd_ali_dev_free(struct snd_device *device) -{ - struct snd_ali *codec = device->device_data; - snd_ali_free(codec); - return 0; -} static int snd_ali_create(struct snd_card *card, struct pci_dev *pci, int pcm_streams, - int spdif_support, - struct snd_ali **r_ali) + int spdif_support) { - struct snd_ali *codec; + struct snd_ali *codec = card->private_data; int i, err; unsigned short cmdw; - static struct snd_device_ops ops = { - .dev_free = snd_ali_dev_free, - }; - - *r_ali = NULL; dev_dbg(card->dev, "creating ...\n"); /* enable PCI device */ - err = pci_enable_device(pci); + err = pcim_enable_device(pci); if (err < 0) return err; /* check, if we can restrict PCI DMA transfers to 31 bits */ - if (dma_set_mask(&pci->dev, DMA_BIT_MASK(31)) < 0 || - dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(31)) < 0) { + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(31))) { dev_err(card->dev, "architecture does not support 31bit PCI busmaster DMA\n"); - pci_disable_device(pci); return -ENXIO; } - codec = kzalloc(sizeof(*codec), GFP_KERNEL); - if (!codec) { - pci_disable_device(pci); - return -ENOMEM; - } - spin_lock_init(&codec->reg_lock); spin_lock_init(&codec->voice_alloc); @@ -2138,14 +2032,10 @@ static int snd_ali_create(struct snd_card *card, cmdw |= PCI_COMMAND_IO; pci_write_config_word(pci, PCI_COMMAND, cmdw); } - pci_set_master(pci); - if (snd_ali_resources(codec)) { - snd_ali_free(codec); + if (snd_ali_resources(codec)) return -EBUSY; - } - - synchronize_irq(pci->irq); + card->private_free = snd_ali_free; codec->synth.chmap = 0; codec->synth.chcnt = 0; @@ -2172,24 +2062,15 @@ static int snd_ali_create(struct snd_card *card, codec->pci_m1533 = pci_get_device(0x10b9, 0x1533, NULL); if (!codec->pci_m1533) { dev_err(card->dev, "cannot find ALi 1533 chip.\n"); - snd_ali_free(codec); return -ENODEV; } /* M7101: power management */ codec->pci_m7101 = pci_get_device(0x10b9, 0x7101, NULL); if (!codec->pci_m7101 && codec->revision == ALI_5451_V02) { dev_err(card->dev, "cannot find ALi 7101 chip.\n"); - snd_ali_free(codec); return -ENODEV; } - dev_dbg(card->dev, "snd_device_new is called.\n"); - err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops); - if (err < 0) { - snd_ali_free(codec); - return err; - } - /* initialise synth voices*/ for (i = 0; i < ALI_CHANNELS; i++) codec->synth.voices[i].number = i; @@ -2200,22 +2081,13 @@ static int snd_ali_create(struct snd_card *card, return err; } -#ifdef CONFIG_PM_SLEEP - codec->image = kmalloc(sizeof(*codec->image), GFP_KERNEL); - if (!codec->image) - dev_warn(card->dev, "can't allocate apm buffer\n"); -#endif - snd_ali_enable_address_interrupt(codec); codec->hw_initialized = 1; - - *r_ali = codec; - dev_dbg(card->dev, "created.\n"); return 0; } -static int snd_ali_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) +static int __snd_ali_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) { struct snd_card *card; struct snd_ali *codec; @@ -2223,29 +2095,30 @@ static int snd_ali_probe(struct pci_dev *pci, dev_dbg(&pci->dev, "probe ...\n"); - err = snd_card_new(&pci->dev, index, id, THIS_MODULE, 0, &card); + err = snd_devm_card_new(&pci->dev, index, id, THIS_MODULE, + sizeof(*codec), &card); if (err < 0) return err; + codec = card->private_data; - err = snd_ali_create(card, pci, pcm_channels, spdif, &codec); + err = snd_ali_create(card, pci, pcm_channels, spdif); if (err < 0) - goto error; - card->private_data = codec; + return err; dev_dbg(&pci->dev, "mixer building ...\n"); err = snd_ali_mixer(codec); if (err < 0) - goto error; + return err; dev_dbg(&pci->dev, "pcm building ...\n"); err = snd_ali_build_pcms(codec); if (err < 0) - goto error; + return err; snd_ali_proc_init(codec); - strcpy(card->driver, "ALI5451"); - strcpy(card->shortname, "ALI 5451"); + strscpy(card->driver, "ALI5451"); + strscpy(card->shortname, "ALI 5451"); sprintf(card->longname, "%s at 0x%lx, irq %i", card->shortname, codec->port, codec->irq); @@ -2253,28 +2126,24 @@ static int snd_ali_probe(struct pci_dev *pci, dev_dbg(&pci->dev, "register card.\n"); err = snd_card_register(card); if (err < 0) - goto error; + return err; pci_set_drvdata(pci, card); return 0; - - error: - snd_card_free(card); - return err; } -static void snd_ali_remove(struct pci_dev *pci) +static int snd_ali_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_ali_probe(pci, pci_id)); } static struct pci_driver ali5451_driver = { .name = KBUILD_MODNAME, .id_table = snd_ali_ids, .probe = snd_ali_probe, - .remove = snd_ali_remove, .driver = { - .pm = ALI_PM_OPS, + .pm = &ali_pm, }, }; |
