diff options
Diffstat (limited to 'sound/pci/atiixp.c')
| -rw-r--r-- | sound/pci/atiixp.c | 358 |
1 files changed, 124 insertions, 234 deletions
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index fe4c61bdb8ba..2a0c59d5afa5 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c @@ -1,25 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * ALSA driver for ATI IXP 150/200/250/300 AC97 controllers * * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, 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 License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * */ -#include <asm/io.h> +#include <linux/io.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/init.h> @@ -37,7 +23,6 @@ MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); MODULE_DESCRIPTION("ATI IXP AC97 controller"); MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250/300/400/600}}"); static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ @@ -207,10 +192,10 @@ struct atiixp; */ struct atiixp_dma_desc { - u32 addr; /* DMA buffer address */ + __le32 addr; /* DMA buffer address */ u16 status; /* status bits */ u16 size; /* size of the packet in dwords */ - u32 next; /* address of the next packet descriptor */ + __le32 next; /* address of the next packet descriptor */ }; /* @@ -286,7 +271,7 @@ struct atiixp { /* */ -static DEFINE_PCI_DEVICE_TABLE(snd_atiixp_ids) = { +static const struct pci_device_id snd_atiixp_ids[] = { { PCI_VDEVICE(ATI, 0x4341), 0 }, /* SB200 */ { PCI_VDEVICE(ATI, 0x4361), 0 }, /* SB300 */ { PCI_VDEVICE(ATI, 0x4370), 0 }, /* SB400 */ @@ -296,7 +281,7 @@ static DEFINE_PCI_DEVICE_TABLE(snd_atiixp_ids) = { MODULE_DEVICE_TABLE(pci, snd_atiixp_ids); -static struct snd_pci_quirk atiixp_quirks[] = { +static const struct snd_pci_quirk atiixp_quirks[] = { SND_PCI_QUIRK(0x105b, 0x0c81, "Foxconn RC4107MA-RS2", 0), SND_PCI_QUIRK(0x15bd, 0x3100, "DFI RS482", 0), { } /* terminator */ @@ -360,14 +345,13 @@ static int atiixp_build_dma_packets(struct atiixp *chip, struct atiixp_dma *dma, { unsigned int i; u32 addr, desc_addr; - unsigned long flags; if (periods > ATI_MAX_DESCRIPTORS) return -ENOMEM; if (dma->desc_buf.area == NULL) { if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(chip->pci), + &chip->pci->dev, ATI_DESC_LIST_SIZE, &dma->desc_buf) < 0) return -ENOMEM; @@ -378,11 +362,11 @@ static int atiixp_build_dma_packets(struct atiixp *chip, struct atiixp_dma *dma, return 0; /* reset DMA before changing the descriptor table */ - spin_lock_irqsave(&chip->reg_lock, flags); - writel(0, chip->remap_addr + dma->ops->llp_offset); - dma->ops->enable_dma(chip, 0); - dma->ops->enable_dma(chip, 1); - spin_unlock_irqrestore(&chip->reg_lock, flags); + scoped_guard(spinlock_irqsave, &chip->reg_lock) { + writel(0, chip->remap_addr + dma->ops->llp_offset); + dma->ops->enable_dma(chip, 0); + dma->ops->enable_dma(chip, 1); + } /* fill the entries */ addr = (u32)substream->runtime->dma_addr; @@ -432,7 +416,7 @@ static int snd_atiixp_acquire_codec(struct atiixp *chip) while (atiixp_read(chip, PHYS_OUT_ADDR) & ATI_REG_PHYS_OUT_ADDR_EN) { if (! timeout--) { - snd_printk(KERN_WARNING "atiixp: codec acquire timeout\n"); + dev_warn(chip->card->dev, "codec acquire timeout\n"); return -EBUSY; } udelay(1); @@ -463,7 +447,7 @@ static unsigned short snd_atiixp_codec_read(struct atiixp *chip, unsigned short } while (--timeout); /* time out may happen during reset */ if (reg < 0x7c) - snd_printk(KERN_WARNING "atiixp: codec read timeout (reg %x)\n", reg); + dev_warn(chip->card->dev, "codec read timeout (reg %x)\n", reg); return 0xffff; } @@ -523,7 +507,7 @@ static int snd_atiixp_aclink_reset(struct atiixp *chip) mdelay(1); atiixp_update(chip, CMD, ATI_REG_CMD_AC_RESET, ATI_REG_CMD_AC_RESET); if (!--timeout) { - snd_printk(KERN_ERR "atiixp: codec reset timeout\n"); + dev_err(chip->card->dev, "codec reset timeout\n"); break; } } @@ -535,7 +519,6 @@ static int snd_atiixp_aclink_reset(struct atiixp *chip) return 0; } -#ifdef CONFIG_PM_SLEEP static int snd_atiixp_aclink_down(struct atiixp *chip) { // if (atiixp_read(chip, MODEM_MIRROR) & 0x1) /* modem running, too? */ @@ -545,7 +528,6 @@ static int snd_atiixp_aclink_down(struct atiixp *chip) ATI_REG_CMD_POWERDOWN); return 0; } -#endif /* * auto-detection of codecs @@ -567,9 +549,8 @@ static int ac97_probing_bugs(struct pci_dev *pci) q = snd_pci_quirk_lookup(pci, atiixp_quirks); if (q) { - snd_printdd(KERN_INFO - "Atiixp quirk for %s. Forcing codec %d\n", - snd_pci_quirk_name(q), q->value); + dev_dbg(&pci->dev, "atiixp quirk for %s. Forcing codec %d\n", + snd_pci_quirk_name(q), q->value); return q->value; } /* this hardware doesn't need workarounds. Probe for codec */ @@ -600,7 +581,7 @@ static int snd_atiixp_codec_detect(struct atiixp *chip) atiixp_write(chip, IER, 0); /* disable irqs */ if ((chip->codec_not_ready_bits & ALL_CODEC_NOT_READY) == ALL_CODEC_NOT_READY) { - snd_printk(KERN_ERR "atiixp: no codec detected!\n"); + dev_err(chip->card->dev, "no codec detected!\n"); return -ENXIO; } return 0; @@ -676,7 +657,7 @@ static snd_pcm_uframes_t snd_atiixp_pcm_pointer(struct snd_pcm_substream *substr continue; return bytes_to_frames(runtime, curptr); } - snd_printd("atiixp: invalid DMA pointer read 0x%x (buf=%x)\n", + dev_dbg(chip->card->dev, "invalid DMA pointer read 0x%x (buf=%x)\n", readl(chip->remap_addr + dma->ops->dt_cur), dma->buf_addr); return 0; } @@ -688,8 +669,8 @@ static void snd_atiixp_xrun_dma(struct atiixp *chip, struct atiixp_dma *dma) { if (! dma->substream || ! dma->running) return; - snd_printdd("atiixp: XRUN detected (DMA %d)\n", dma->ops->type); - snd_pcm_stop(dma->substream, SNDRV_PCM_STATE_XRUN); + dev_dbg(chip->card->dev, "XRUN detected (DMA %d)\n", dma->ops->type); + snd_pcm_stop_xrun(dma->substream); } /* @@ -729,11 +710,15 @@ static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd) !dma->ops->flush_dma)) return -EINVAL; - spin_lock(&chip->reg_lock); + guard(spinlock)(&chip->reg_lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_RESUME: + if (dma->running && dma->suspended && + cmd == SNDRV_PCM_TRIGGER_RESUME) + writel(dma->saved_curptr, chip->remap_addr + + dma->ops->dt_cur); dma->ops->enable_transfer(chip, 1); dma->running = 1; dma->suspended = 0; @@ -741,9 +726,12 @@ static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_SUSPEND: + dma->suspended = cmd == SNDRV_PCM_TRIGGER_SUSPEND; + if (dma->running && dma->suspended) + dma->saved_curptr = readl(chip->remap_addr + + dma->ops->dt_cur); dma->ops->enable_transfer(chip, 0); dma->running = 0; - dma->suspended = cmd == SNDRV_PCM_TRIGGER_SUSPEND; break; default: err = -EINVAL; @@ -756,7 +744,6 @@ static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd) snd_atiixp_check_bus_busy(chip); } } - spin_unlock(&chip->reg_lock); return err; } @@ -870,7 +857,7 @@ static int snd_atiixp_spdif_prepare(struct snd_pcm_substream *substream) { struct atiixp *chip = snd_pcm_substream_chip(substream); - spin_lock_irq(&chip->reg_lock); + guard(spinlock_irq)(&chip->reg_lock); if (chip->spdif_over_aclink) { unsigned int data; /* enable slots 10/11 */ @@ -888,7 +875,6 @@ static int snd_atiixp_spdif_prepare(struct snd_pcm_substream *substream) atiixp_update(chip, CMD, ATI_REG_CMD_SPDF_CONFIG_MASK, 0); atiixp_update(chip, CMD, ATI_REG_CMD_INTERLEAVE_SPDF, 0); } - spin_unlock_irq(&chip->reg_lock); return 0; } @@ -898,21 +884,21 @@ static int snd_atiixp_playback_prepare(struct snd_pcm_substream *substream) struct atiixp *chip = snd_pcm_substream_chip(substream); unsigned int data; - spin_lock_irq(&chip->reg_lock); + guard(spinlock_irq)(&chip->reg_lock); data = atiixp_read(chip, OUT_DMA_SLOT) & ~ATI_REG_OUT_DMA_SLOT_MASK; switch (substream->runtime->channels) { case 8: data |= ATI_REG_OUT_DMA_SLOT_BIT(10) | ATI_REG_OUT_DMA_SLOT_BIT(11); - /* fallthru */ + fallthrough; case 6: data |= ATI_REG_OUT_DMA_SLOT_BIT(7) | ATI_REG_OUT_DMA_SLOT_BIT(8); - /* fallthru */ + fallthrough; case 4: data |= ATI_REG_OUT_DMA_SLOT_BIT(6) | ATI_REG_OUT_DMA_SLOT_BIT(9); - /* fallthru */ + fallthrough; default: data |= ATI_REG_OUT_DMA_SLOT_BIT(3) | ATI_REG_OUT_DMA_SLOT_BIT(4); @@ -933,7 +919,6 @@ static int snd_atiixp_playback_prepare(struct snd_pcm_substream *substream) atiixp_update(chip, 6CH_REORDER, ATI_REG_6CH_REORDER_EN, substream->runtime->channels >= 6 ? ATI_REG_6CH_REORDER_EN: 0); - spin_unlock_irq(&chip->reg_lock); return 0; } @@ -942,11 +927,10 @@ static int snd_atiixp_capture_prepare(struct snd_pcm_substream *substream) { struct atiixp *chip = snd_pcm_substream_chip(substream); - spin_lock_irq(&chip->reg_lock); + guard(spinlock_irq)(&chip->reg_lock); atiixp_update(chip, CMD, ATI_REG_CMD_INTERLEAVE_IN, substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE ? ATI_REG_CMD_INTERLEAVE_IN : 0); - spin_unlock_irq(&chip->reg_lock); return 0; } @@ -960,9 +944,6 @@ static int snd_atiixp_pcm_hw_params(struct snd_pcm_substream *substream, struct atiixp_dma *dma = substream->runtime->private_data; int err; - err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); - if (err < 0) - return err; dma->buf_addr = substream->runtime->dma_addr; dma->buf_bytes = params_buffer_bytes(hw_params); @@ -1002,7 +983,6 @@ static int snd_atiixp_pcm_hw_free(struct snd_pcm_substream *substream) dma->pcm_open_flag = 0; } atiixp_clear_dma_packets(chip, dma, substream); - snd_pcm_lib_free_pages(substream); return 0; } @@ -1010,7 +990,7 @@ static int snd_atiixp_pcm_hw_free(struct snd_pcm_substream *substream) /* * pcm hardware definition, identical for all DMA types */ -static struct snd_pcm_hardware snd_atiixp_pcm_hw = +static const struct snd_pcm_hardware snd_atiixp_pcm_hw = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | @@ -1052,14 +1032,15 @@ static int snd_atiixp_pcm_open(struct snd_pcm_substream *substream, /* direct SPDIF */ runtime->hw.formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE; } - 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; runtime->private_data = dma; /* enable DMA bits */ - spin_lock_irq(&chip->reg_lock); - dma->ops->enable_dma(chip, 1); - spin_unlock_irq(&chip->reg_lock); + scoped_guard(spinlock_irq, &chip->reg_lock) { + dma->ops->enable_dma(chip, 1); + } dma->opened = 1; return 0; @@ -1072,9 +1053,9 @@ static int snd_atiixp_pcm_close(struct snd_pcm_substream *substream, /* disable DMA bits */ if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma)) return -EINVAL; - spin_lock_irq(&chip->reg_lock); - dma->ops->enable_dma(chip, 0); - spin_unlock_irq(&chip->reg_lock); + scoped_guard(spinlock_irq, &chip->reg_lock) { + dma->ops->enable_dma(chip, 0); + } dma->substream = NULL; dma->opened = 0; return 0; @@ -1087,9 +1068,8 @@ static int snd_atiixp_playback_open(struct snd_pcm_substream *substream) struct atiixp *chip = snd_pcm_substream_chip(substream); int err; - mutex_lock(&chip->open_mutex); + guard(mutex)(&chip->open_mutex); err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 0); - mutex_unlock(&chip->open_mutex); if (err < 0) return err; substream->runtime->hw.channels_max = chip->max_channels; @@ -1103,11 +1083,9 @@ static int snd_atiixp_playback_open(struct snd_pcm_substream *substream) static int snd_atiixp_playback_close(struct snd_pcm_substream *substream) { struct atiixp *chip = snd_pcm_substream_chip(substream); - int err; - mutex_lock(&chip->open_mutex); - err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]); - mutex_unlock(&chip->open_mutex); - return err; + + guard(mutex)(&chip->open_mutex); + return snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]); } static int snd_atiixp_capture_open(struct snd_pcm_substream *substream) @@ -1125,34 +1103,29 @@ static int snd_atiixp_capture_close(struct snd_pcm_substream *substream) static int snd_atiixp_spdif_open(struct snd_pcm_substream *substream) { struct atiixp *chip = snd_pcm_substream_chip(substream); - int err; - mutex_lock(&chip->open_mutex); + + guard(mutex)(&chip->open_mutex); if (chip->spdif_over_aclink) /* share DMA_PLAYBACK */ - err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 2); + return snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_PLAYBACK], 2); else - err = snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_SPDIF], -1); - mutex_unlock(&chip->open_mutex); - return err; + return snd_atiixp_pcm_open(substream, &chip->dmas[ATI_DMA_SPDIF], -1); } static int snd_atiixp_spdif_close(struct snd_pcm_substream *substream) { struct atiixp *chip = snd_pcm_substream_chip(substream); - int err; - mutex_lock(&chip->open_mutex); + + guard(mutex)(&chip->open_mutex); if (chip->spdif_over_aclink) - err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]); + return snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_PLAYBACK]); else - err = snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_SPDIF]); - mutex_unlock(&chip->open_mutex); - return err; + return snd_atiixp_pcm_close(substream, &chip->dmas[ATI_DMA_SPDIF]); } /* AC97 playback */ -static struct snd_pcm_ops snd_atiixp_playback_ops = { +static const struct snd_pcm_ops snd_atiixp_playback_ops = { .open = snd_atiixp_playback_open, .close = snd_atiixp_playback_close, - .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_atiixp_pcm_hw_params, .hw_free = snd_atiixp_pcm_hw_free, .prepare = snd_atiixp_playback_prepare, @@ -1161,10 +1134,9 @@ static struct snd_pcm_ops snd_atiixp_playback_ops = { }; /* AC97 capture */ -static struct snd_pcm_ops snd_atiixp_capture_ops = { +static const struct snd_pcm_ops snd_atiixp_capture_ops = { .open = snd_atiixp_capture_open, .close = snd_atiixp_capture_close, - .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_atiixp_pcm_hw_params, .hw_free = snd_atiixp_pcm_hw_free, .prepare = snd_atiixp_capture_prepare, @@ -1173,10 +1145,9 @@ static struct snd_pcm_ops snd_atiixp_capture_ops = { }; /* SPDIF playback */ -static struct snd_pcm_ops snd_atiixp_spdif_ops = { +static const struct snd_pcm_ops snd_atiixp_spdif_ops = { .open = snd_atiixp_spdif_open, .close = snd_atiixp_spdif_close, - .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_atiixp_pcm_hw_params, .hw_free = snd_atiixp_pcm_hw_free, .prepare = snd_atiixp_spdif_prepare, @@ -1184,7 +1155,7 @@ static struct snd_pcm_ops snd_atiixp_spdif_ops = { .pointer = snd_atiixp_pcm_pointer, }; -static struct ac97_pcm atiixp_pcm_defs[] = { +static const struct ac97_pcm atiixp_pcm_defs[] = { /* front PCM */ { .exclusive = 1, @@ -1220,7 +1191,7 @@ static struct ac97_pcm atiixp_pcm_defs[] = { }, }; -static struct atiixp_dma_ops snd_atiixp_playback_dma_ops = { +static const struct atiixp_dma_ops snd_atiixp_playback_dma_ops = { .type = ATI_DMA_PLAYBACK, .llp_offset = ATI_REG_OUT_DMA_LINKPTR, .dt_cur = ATI_REG_OUT_DMA_DT_CUR, @@ -1229,7 +1200,7 @@ static struct atiixp_dma_ops snd_atiixp_playback_dma_ops = { .flush_dma = atiixp_out_flush_dma, }; -static struct atiixp_dma_ops snd_atiixp_capture_dma_ops = { +static const struct atiixp_dma_ops snd_atiixp_capture_dma_ops = { .type = ATI_DMA_CAPTURE, .llp_offset = ATI_REG_IN_DMA_LINKPTR, .dt_cur = ATI_REG_IN_DMA_DT_CUR, @@ -1238,7 +1209,7 @@ static struct atiixp_dma_ops snd_atiixp_capture_dma_ops = { .flush_dma = atiixp_in_flush_dma, }; -static struct atiixp_dma_ops snd_atiixp_spdif_dma_ops = { +static const struct atiixp_dma_ops snd_atiixp_spdif_dma_ops = { .type = ATI_DMA_SPDIF, .llp_offset = ATI_REG_SPDF_DMA_LINKPTR, .dt_cur = ATI_REG_SPDF_DMA_DT_CUR, @@ -1288,12 +1259,11 @@ static int snd_atiixp_pcm_new(struct atiixp *chip) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_atiixp_capture_ops); pcm->private_data = chip; - strcpy(pcm->name, "ATI IXP AC97"); + strscpy(pcm->name, "ATI IXP AC97"); chip->pcmdevs[ATI_PCMDEV_ANALOG] = pcm; - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(chip->pci), - 64*1024, 128*1024); + snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, + &chip->pci->dev, 64*1024, 128*1024); err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, snd_pcm_alt_chmaps, chip->max_channels, 0, @@ -1319,14 +1289,13 @@ static int snd_atiixp_pcm_new(struct atiixp *chip) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_atiixp_spdif_ops); pcm->private_data = chip; if (chip->spdif_over_aclink) - strcpy(pcm->name, "ATI IXP IEC958 (AC97)"); + strscpy(pcm->name, "ATI IXP IEC958 (AC97)"); else - strcpy(pcm->name, "ATI IXP IEC958 (Direct)"); + strscpy(pcm->name, "ATI IXP IEC958 (Direct)"); chip->pcmdevs[ATI_PCMDEV_DIGITAL] = pcm; - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(chip->pci), - 64*1024, 128*1024); + snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, + &chip->pci->dev, 64*1024, 128*1024); /* pre-select AC97 SPDIF slots 10/11 */ for (i = 0; i < NUM_ATI_CODECS; i++) { @@ -1374,10 +1343,9 @@ static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id) if (status & CODEC_CHECK_BITS) { unsigned int detected; detected = status & CODEC_CHECK_BITS; - spin_lock(&chip->reg_lock); + guard(spinlock)(&chip->reg_lock); chip->codec_not_ready_bits |= detected; atiixp_update(chip, IER, detected, 0); /* disable the detected irqs */ - spin_unlock(&chip->reg_lock); } /* ack */ @@ -1391,7 +1359,7 @@ static irqreturn_t snd_atiixp_interrupt(int irq, void *dev_id) * ac97 mixer section */ -static struct ac97_quirk ac97_quirks[] = { +static const struct ac97_quirk ac97_quirks[] = { { .subvendor = 0x103c, .subdevice = 0x006b, @@ -1420,11 +1388,11 @@ static int snd_atiixp_mixer_new(struct atiixp *chip, int clock, struct snd_ac97_template ac97; int i, err; int codec_count; - static struct snd_ac97_bus_ops ops = { + static const struct snd_ac97_bus_ops ops = { .write = snd_atiixp_ac97_write, .read = snd_atiixp_ac97_read, }; - static unsigned int codec_skip[NUM_ATI_CODECS] = { + static const unsigned int codec_skip[NUM_ATI_CODECS] = { ATI_REG_ISR_CODEC0_NOT_READY, ATI_REG_ISR_CODEC1_NOT_READY, ATI_REG_ISR_CODEC2_NOT_READY, @@ -1433,7 +1401,8 @@ static int snd_atiixp_mixer_new(struct atiixp *chip, int clock, if (snd_atiixp_codec_detect(chip) < 0) return -ENXIO; - if ((err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus)) < 0) + err = snd_ac97_bus(chip->card, 0, &ops, chip, &pbus); + if (err < 0) return err; pbus->clock = clock; chip->ac97_bus = pbus; @@ -1449,16 +1418,18 @@ static int snd_atiixp_mixer_new(struct atiixp *chip, int clock, ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE; if (! chip->spdif_over_aclink) ac97.scaps |= AC97_SCAP_NO_SPDIF; - if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) { + err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i]); + if (err < 0) { chip->ac97[i] = NULL; /* to be sure */ - snd_printdd("atiixp: codec %d not available for audio\n", i); + dev_dbg(chip->card->dev, + "codec %d not available for audio\n", i); continue; } codec_count++; } if (! codec_count) { - snd_printk(KERN_ERR "atiixp: no codec available\n"); + dev_err(chip->card->dev, "no codec available\n"); return -ENODEV; } @@ -1468,54 +1439,29 @@ static int snd_atiixp_mixer_new(struct atiixp *chip, int clock, } -#ifdef CONFIG_PM_SLEEP /* * power management */ static int snd_atiixp_suspend(struct device *dev) { - struct pci_dev *pci = to_pci_dev(dev); struct snd_card *card = dev_get_drvdata(dev); struct atiixp *chip = card->private_data; int i; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - for (i = 0; i < NUM_ATI_PCMDEVS; i++) - if (chip->pcmdevs[i]) { - struct atiixp_dma *dma = &chip->dmas[i]; - if (dma->substream && dma->running) - dma->saved_curptr = readl(chip->remap_addr + - dma->ops->dt_cur); - snd_pcm_suspend_all(chip->pcmdevs[i]); - } for (i = 0; i < NUM_ATI_CODECS; i++) snd_ac97_suspend(chip->ac97[i]); snd_atiixp_aclink_down(chip); snd_atiixp_chip_stop(chip); - - pci_disable_device(pci); - pci_save_state(pci); - pci_set_power_state(pci, PCI_D3hot); return 0; } static int snd_atiixp_resume(struct device *dev) { - struct pci_dev *pci = to_pci_dev(dev); struct snd_card *card = dev_get_drvdata(dev); struct atiixp *chip = card->private_data; int i; - pci_set_power_state(pci, PCI_D0); - pci_restore_state(pci); - if (pci_enable_device(pci) < 0) { - printk(KERN_ERR "atiixp: pci_enable_device failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } - pci_set_master(pci); - snd_atiixp_aclink_reset(chip); snd_atiixp_chip_start(chip); @@ -1530,8 +1476,6 @@ static int snd_atiixp_resume(struct device *dev) dma->substream->ops->prepare(dma->substream); writel((u32)dma->desc_buf.addr | ATI_REG_LINKPTR_EN, chip->remap_addr + dma->ops->llp_offset); - writel(dma->saved_curptr, chip->remap_addr + - dma->ops->dt_cur); } } @@ -1539,14 +1483,8 @@ static int snd_atiixp_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(snd_atiixp_pm, snd_atiixp_suspend, snd_atiixp_resume); -#define SND_ATIIXP_PM_OPS &snd_atiixp_pm -#else -#define SND_ATIIXP_PM_OPS NULL -#endif /* CONFIG_PM_SLEEP */ +static DEFINE_SIMPLE_DEV_PM_OPS(snd_atiixp_pm, snd_atiixp_suspend, snd_atiixp_resume); - -#ifdef CONFIG_PROC_FS /* * proc interface for register dump */ @@ -1563,132 +1501,87 @@ static void snd_atiixp_proc_read(struct snd_info_entry *entry, static void snd_atiixp_proc_init(struct atiixp *chip) { - struct snd_info_entry *entry; - - if (! snd_card_proc_new(chip->card, "atiixp", &entry)) - snd_info_set_text_ops(entry, chip, snd_atiixp_proc_read); + snd_card_ro_proc_new(chip->card, "atiixp", chip, snd_atiixp_proc_read); } -#else /* !CONFIG_PROC_FS */ -#define snd_atiixp_proc_init(chip) -#endif /* * destructor */ -static int snd_atiixp_free(struct atiixp *chip) +static void snd_atiixp_free(struct snd_card *card) { - if (chip->irq < 0) - goto __hw_end; - snd_atiixp_chip_stop(chip); - - __hw_end: - if (chip->irq >= 0) - free_irq(chip->irq, chip); - if (chip->remap_addr) - iounmap(chip->remap_addr); - pci_release_regions(chip->pci); - pci_disable_device(chip->pci); - kfree(chip); - return 0; -} - -static int snd_atiixp_dev_free(struct snd_device *device) -{ - struct atiixp *chip = device->device_data; - return snd_atiixp_free(chip); + snd_atiixp_chip_stop(card->private_data); } /* * constructor for chip instance */ -static int snd_atiixp_create(struct snd_card *card, - struct pci_dev *pci, - struct atiixp **r_chip) +static int snd_atiixp_init(struct snd_card *card, struct pci_dev *pci) { - static struct snd_device_ops ops = { - .dev_free = snd_atiixp_dev_free, - }; - struct atiixp *chip; + struct atiixp *chip = card->private_data; int err; - if ((err = pci_enable_device(pci)) < 0) + err = pcim_enable_device(pci); + if (err < 0) return err; - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (chip == NULL) { - pci_disable_device(pci); - return -ENOMEM; - } - spin_lock_init(&chip->reg_lock); mutex_init(&chip->open_mutex); chip->card = card; chip->pci = pci; chip->irq = -1; - if ((err = pci_request_regions(pci, "ATI IXP AC97")) < 0) { - pci_disable_device(pci); - kfree(chip); - return err; - } + chip->remap_addr = pcim_iomap_region(pci, 0, "ATI IXP AC97"); + if (IS_ERR(chip->remap_addr)) + return PTR_ERR(chip->remap_addr); chip->addr = pci_resource_start(pci, 0); - chip->remap_addr = pci_ioremap_bar(pci, 0); - if (chip->remap_addr == NULL) { - snd_printk(KERN_ERR "AC'97 space ioremap problem\n"); - snd_atiixp_free(chip); - return -EIO; - } - if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED, - KBUILD_MODNAME, chip)) { - snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); - snd_atiixp_free(chip); + if (devm_request_irq(&pci->dev, pci->irq, snd_atiixp_interrupt, + IRQF_SHARED, KBUILD_MODNAME, chip)) { + dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq); return -EBUSY; } chip->irq = pci->irq; + card->sync_irq = chip->irq; + card->private_free = snd_atiixp_free; pci_set_master(pci); - synchronize_irq(chip->irq); - - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { - snd_atiixp_free(chip); - return err; - } - snd_card_set_dev(card, &pci->dev); - - *r_chip = chip; return 0; } -static int snd_atiixp_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) +static int __snd_atiixp_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) { struct snd_card *card; struct atiixp *chip; int err; - err = snd_card_create(index, id, THIS_MODULE, 0, &card); + err = snd_devm_card_new(&pci->dev, index, id, THIS_MODULE, + sizeof(*chip), &card); if (err < 0) return err; + chip = card->private_data; - strcpy(card->driver, spdif_aclink ? "ATIIXP" : "ATIIXP-SPDMA"); - strcpy(card->shortname, "ATI IXP"); - if ((err = snd_atiixp_create(card, pci, &chip)) < 0) - goto __error; - card->private_data = chip; + strscpy(card->driver, spdif_aclink ? "ATIIXP" : "ATIIXP-SPDMA"); + strscpy(card->shortname, "ATI IXP"); + err = snd_atiixp_init(card, pci); + if (err < 0) + return err; - if ((err = snd_atiixp_aclink_reset(chip)) < 0) - goto __error; + err = snd_atiixp_aclink_reset(chip); + if (err < 0) + return err; chip->spdif_over_aclink = spdif_aclink; - if ((err = snd_atiixp_mixer_new(chip, ac97_clock, ac97_quirk)) < 0) - goto __error; + err = snd_atiixp_mixer_new(chip, ac97_clock, ac97_quirk); + if (err < 0) + return err; - if ((err = snd_atiixp_pcm_new(chip)) < 0) - goto __error; + err = snd_atiixp_pcm_new(chip); + if (err < 0) + return err; snd_atiixp_proc_init(chip); @@ -1700,29 +1593,26 @@ static int snd_atiixp_probe(struct pci_dev *pci, chip->ac97[0] ? snd_ac97_get_short_name(chip->ac97[0]) : "?", chip->addr, chip->irq); - if ((err = snd_card_register(card)) < 0) - goto __error; + err = snd_card_register(card); + if (err < 0) + return err; pci_set_drvdata(pci, card); return 0; - - __error: - snd_card_free(card); - return err; } -static void snd_atiixp_remove(struct pci_dev *pci) +static int snd_atiixp_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_atiixp_probe(pci, pci_id)); } static struct pci_driver atiixp_driver = { .name = KBUILD_MODNAME, .id_table = snd_atiixp_ids, .probe = snd_atiixp_probe, - .remove = snd_atiixp_remove, .driver = { - .pm = SND_ATIIXP_PM_OPS, + .pm = &snd_atiixp_pm, }, }; |
