diff options
Diffstat (limited to 'sound/pci/rme96.c')
| -rw-r--r-- | sound/pci/rme96.c | 510 |
1 files changed, 201 insertions, 309 deletions
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index dcfa4d7a73e2..58b8ebf1a24e 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * ALSA driver for RME Digi96, Digi96/8 and Digi96/8 PRO/PAD/PST audio * interfaces @@ -6,21 +7,6 @@ * * Thanks to Henk Hesselink <henk@anda.nl> for the analog volume control * code. - * - * 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 <linux/delay.h> @@ -45,11 +31,6 @@ MODULE_AUTHOR("Anders Torger <torger@ludd.luth.se>"); MODULE_DESCRIPTION("RME Digi96, Digi96/8, Digi96/8 PRO, Digi96/8 PST, " "Digi96/8 PAD"); MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{RME,Digi96}," - "{RME,Digi96/8}," - "{RME,Digi96/8 PRO}," - "{RME,Digi96/8 PST}," - "{RME,Digi96/8 PAD}}"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ @@ -239,12 +220,10 @@ struct rme96 { u8 rev; /* card revision number */ -#ifdef CONFIG_PM_SLEEP u32 playback_pointer; u32 capture_pointer; void *playback_suspend_buffer; void *capture_suspend_buffer; -#endif struct snd_pcm_substream *playback_substream; struct snd_pcm_substream *capture_substream; @@ -339,45 +318,26 @@ snd_rme96_playback_silence(struct snd_pcm_substream *substream, static int snd_rme96_playback_copy(struct snd_pcm_substream *substream, int channel, unsigned long pos, - void __user *src, unsigned long count) -{ - struct rme96 *rme96 = snd_pcm_substream_chip(substream); - - return copy_from_user_toio(rme96->iobase + RME96_IO_PLAY_BUFFER + pos, - src, count); -} - -static int -snd_rme96_playback_copy_kernel(struct snd_pcm_substream *substream, - int channel, unsigned long pos, - void *src, unsigned long count) + struct iov_iter *src, unsigned long count) { struct rme96 *rme96 = snd_pcm_substream_chip(substream); - memcpy_toio(rme96->iobase + RME96_IO_PLAY_BUFFER + pos, src, count); + if (copy_from_iter_toio(rme96->iobase + RME96_IO_PLAY_BUFFER + pos, + count, src) != count) + return -EFAULT; return 0; } static int snd_rme96_capture_copy(struct snd_pcm_substream *substream, int channel, unsigned long pos, - void __user *dst, unsigned long count) -{ - struct rme96 *rme96 = snd_pcm_substream_chip(substream); - - return copy_to_user_fromio(dst, - rme96->iobase + RME96_IO_REC_BUFFER + pos, - count); -} - -static int -snd_rme96_capture_copy_kernel(struct snd_pcm_substream *substream, - int channel, unsigned long pos, - void *dst, unsigned long count) + struct iov_iter *dst, unsigned long count) { struct rme96 *rme96 = snd_pcm_substream_chip(substream); - memcpy_fromio(dst, rme96->iobase + RME96_IO_REC_BUFFER + pos, count); + if (copy_to_iter_fromio(rme96->iobase + RME96_IO_REC_BUFFER + pos, + count, dst) != count) + return -EFAULT; return 0; } @@ -685,12 +645,14 @@ snd_rme96_playback_getrate(struct rme96 *rme96) int rate, dummy; if (!(rme96->wcreg & RME96_WCR_MASTER) && - snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG && - (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0) - { - /* slave clock */ - return rate; + snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG) { + rate = snd_rme96_capture_getrate(rme96, &dummy); + if (rate > 0) { + /* slave clock */ + return rate; + } } + rate = ((rme96->wcreg >> RME96_WCR_BITPOS_FREQ_0) & 1) + (((rme96->wcreg >> RME96_WCR_BITPOS_FREQ_1) & 1) << 1); switch (rate) { @@ -1002,47 +964,45 @@ snd_rme96_playback_hw_params(struct snd_pcm_substream *substream, runtime->dma_addr = rme96->port + RME96_IO_PLAY_BUFFER; runtime->dma_bytes = RME96_BUFFER_SIZE; - spin_lock_irq(&rme96->lock); - if (!(rme96->wcreg & RME96_WCR_MASTER) && - snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG && - (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0) - { - /* slave clock */ - if ((int)params_rate(params) != rate) { - err = -EIO; - goto error; + scoped_guard(spinlock_irq, &rme96->lock) { + rate = 0; + if (!(rme96->wcreg & RME96_WCR_MASTER) && + snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG) + rate = snd_rme96_capture_getrate(rme96, &dummy); + if (rate > 0) { + /* slave clock */ + if ((int)params_rate(params) != rate) + return -EIO; + } else { + err = snd_rme96_playback_setrate(rme96, params_rate(params)); + if (err < 0) + return err; + apply_dac_volume = err > 0; /* need to restore volume later? */ } - } else { - err = snd_rme96_playback_setrate(rme96, params_rate(params)); - if (err < 0) - goto error; - apply_dac_volume = err > 0; /* need to restore volume later? */ - } - err = snd_rme96_playback_setformat(rme96, params_format(params)); - if (err < 0) - goto error; - snd_rme96_setframelog(rme96, params_channels(params), 1); - if (rme96->capture_periodsize != 0) { - if (params_period_size(params) << rme96->playback_frlog != - rme96->capture_periodsize) - { - err = -EBUSY; + err = snd_rme96_playback_setformat(rme96, params_format(params)); + if (err < 0) goto error; + snd_rme96_setframelog(rme96, params_channels(params), 1); + if (rme96->capture_periodsize != 0) { + if (params_period_size(params) << rme96->playback_frlog != + rme96->capture_periodsize) { + err = -EBUSY; + goto error; + } + } + rme96->playback_periodsize = + params_period_size(params) << rme96->playback_frlog; + snd_rme96_set_period_properties(rme96, rme96->playback_periodsize); + /* S/PDIF setup */ + if ((rme96->wcreg & RME96_WCR_ADAT) == 0) { + rme96->wcreg &= ~(RME96_WCR_PRO | RME96_WCR_DOLBY | RME96_WCR_EMP); + writel(rme96->wcreg |= rme96->wcreg_spdif_stream, rme96->iobase + RME96_IO_CONTROL_REGISTER); } - } - rme96->playback_periodsize = - params_period_size(params) << rme96->playback_frlog; - snd_rme96_set_period_properties(rme96, rme96->playback_periodsize); - /* S/PDIF setup */ - if ((rme96->wcreg & RME96_WCR_ADAT) == 0) { - rme96->wcreg &= ~(RME96_WCR_PRO | RME96_WCR_DOLBY | RME96_WCR_EMP); - writel(rme96->wcreg |= rme96->wcreg_spdif_stream, rme96->iobase + RME96_IO_CONTROL_REGISTER); - } - err = 0; + err = 0; + } error: - spin_unlock_irq(&rme96->lock); if (apply_dac_volume) { usleep_range(3000, 10000); snd_rme96_apply_dac_volume(rme96); @@ -1064,43 +1024,33 @@ snd_rme96_capture_hw_params(struct snd_pcm_substream *substream, runtime->dma_addr = rme96->port + RME96_IO_REC_BUFFER; runtime->dma_bytes = RME96_BUFFER_SIZE; - spin_lock_irq(&rme96->lock); - if ((err = snd_rme96_capture_setformat(rme96, params_format(params))) < 0) { - spin_unlock_irq(&rme96->lock); + guard(spinlock_irq)(&rme96->lock); + err = snd_rme96_capture_setformat(rme96, params_format(params)); + if (err < 0) return err; - } if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) { - if ((err = snd_rme96_capture_analog_setrate(rme96, - params_rate(params))) < 0) - { - spin_unlock_irq(&rme96->lock); + err = snd_rme96_capture_analog_setrate(rme96, params_rate(params)); + if (err < 0) return err; + } else { + rate = snd_rme96_capture_getrate(rme96, &isadat); + if (rate > 0) { + if ((int)params_rate(params) != rate) + return -EIO; + if ((isadat && runtime->hw.channels_min == 2) || + (!isadat && runtime->hw.channels_min == 8)) + return -EIO; } - } else if ((rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) { - if ((int)params_rate(params) != rate) { - spin_unlock_irq(&rme96->lock); - return -EIO; - } - if ((isadat && runtime->hw.channels_min == 2) || - (!isadat && runtime->hw.channels_min == 8)) - { - spin_unlock_irq(&rme96->lock); - return -EIO; - } } snd_rme96_setframelog(rme96, params_channels(params), 0); if (rme96->playback_periodsize != 0) { if (params_period_size(params) << rme96->capture_frlog != rme96->playback_periodsize) - { - spin_unlock_irq(&rme96->lock); return -EBUSY; - } } rme96->capture_periodsize = params_period_size(params) << rme96->capture_frlog; snd_rme96_set_period_properties(rme96, rme96->capture_periodsize); - spin_unlock_irq(&rme96->lock); return 0; } @@ -1179,8 +1129,10 @@ rme96_set_buffer_size_constraint(struct rme96 *rme96, snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE); - if ((size = rme96->playback_periodsize) != 0 || - (size = rme96->capture_periodsize) != 0) + size = rme96->playback_periodsize; + if (!size) + size = rme96->capture_periodsize; + if (size) snd_pcm_hw_constraint_single(runtime, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, size); @@ -1198,25 +1150,24 @@ snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_set_sync(substream); - spin_lock_irq(&rme96->lock); - if (rme96->playback_substream) { - spin_unlock_irq(&rme96->lock); - return -EBUSY; - } - rme96->wcreg &= ~RME96_WCR_ADAT; - writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); - rme96->playback_substream = substream; - spin_unlock_irq(&rme96->lock); + scoped_guard(spinlock_irq, &rme96->lock) { + if (rme96->playback_substream) + return -EBUSY; + rme96->wcreg &= ~RME96_WCR_ADAT; + writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); + rme96->playback_substream = substream; + } runtime->hw = snd_rme96_playback_spdif_info; if (!(rme96->wcreg & RME96_WCR_MASTER) && - snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG && - (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0) - { - /* slave clock */ - runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate); - runtime->hw.rate_min = rate; - runtime->hw.rate_max = rate; + snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG) { + rate = snd_rme96_capture_getrate(rme96, &dummy); + if (rate > 0) { + /* slave clock */ + runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate); + runtime->hw.rate_min = rate; + runtime->hw.rate_max = rate; + } } rme96_set_buffer_size_constraint(rme96, runtime); @@ -1236,24 +1187,22 @@ snd_rme96_capture_spdif_open(struct snd_pcm_substream *substream) snd_pcm_set_sync(substream); runtime->hw = snd_rme96_capture_spdif_info; - if (snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG && - (rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) - { - if (isadat) { - return -EIO; - } - runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate); - runtime->hw.rate_min = rate; - runtime->hw.rate_max = rate; - } + if (snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG) { + rate = snd_rme96_capture_getrate(rme96, &isadat); + if (rate > 0) { + if (isadat) + return -EIO; + runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate); + runtime->hw.rate_min = rate; + runtime->hw.rate_max = rate; + } + } - spin_lock_irq(&rme96->lock); - if (rme96->capture_substream) { - spin_unlock_irq(&rme96->lock); - return -EBUSY; - } - rme96->capture_substream = substream; - spin_unlock_irq(&rme96->lock); + scoped_guard(spinlock_irq, &rme96->lock) { + if (rme96->capture_substream) + return -EBUSY; + rme96->capture_substream = substream; + } rme96_set_buffer_size_constraint(rme96, runtime); return 0; @@ -1267,26 +1216,26 @@ snd_rme96_playback_adat_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_set_sync(substream); - spin_lock_irq(&rme96->lock); - if (rme96->playback_substream) { - spin_unlock_irq(&rme96->lock); - return -EBUSY; - } - rme96->wcreg |= RME96_WCR_ADAT; - writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); - rme96->playback_substream = substream; - spin_unlock_irq(&rme96->lock); + scoped_guard(spinlock_irq, &rme96->lock) { + if (rme96->playback_substream) + return -EBUSY; + rme96->wcreg |= RME96_WCR_ADAT; + writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); + rme96->playback_substream = substream; + } runtime->hw = snd_rme96_playback_adat_info; if (!(rme96->wcreg & RME96_WCR_MASTER) && - snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG && - (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0) - { - /* slave clock */ - runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate); - runtime->hw.rate_min = rate; - runtime->hw.rate_max = rate; - } + snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG) { + rate = snd_rme96_capture_getrate(rme96, &dummy); + if (rate > 0) { + /* slave clock */ + runtime->hw.rates = snd_pcm_rate_to_rate_bit(rate); + runtime->hw.rate_min = rate; + runtime->hw.rate_max = rate; + } + } + rme96_set_buffer_size_constraint(rme96, runtime); return 0; } @@ -1305,7 +1254,8 @@ snd_rme96_capture_adat_open(struct snd_pcm_substream *substream) expension cards AEB4/8-I are RME96_INPUT_INTERNAL */ return -EIO; } - if ((rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) { + rate = snd_rme96_capture_getrate(rme96, &isadat); + if (rate > 0) { if (!isadat) { return -EIO; } @@ -1314,13 +1264,11 @@ snd_rme96_capture_adat_open(struct snd_pcm_substream *substream) runtime->hw.rate_max = rate; } - spin_lock_irq(&rme96->lock); - if (rme96->capture_substream) { - spin_unlock_irq(&rme96->lock); - return -EBUSY; - } - rme96->capture_substream = substream; - spin_unlock_irq(&rme96->lock); + scoped_guard(spinlock_irq, &rme96->lock) { + if (rme96->capture_substream) + return -EBUSY; + rme96->capture_substream = substream; + } rme96_set_buffer_size_constraint(rme96, runtime); return 0; @@ -1332,14 +1280,13 @@ snd_rme96_playback_close(struct snd_pcm_substream *substream) struct rme96 *rme96 = snd_pcm_substream_chip(substream); int spdif = 0; - spin_lock_irq(&rme96->lock); - if (RME96_ISPLAYING(rme96)) { - snd_rme96_trigger(rme96, RME96_STOP_PLAYBACK); + scoped_guard(spinlock_irq, &rme96->lock) { + if (RME96_ISPLAYING(rme96)) + snd_rme96_trigger(rme96, RME96_STOP_PLAYBACK); + rme96->playback_substream = NULL; + rme96->playback_periodsize = 0; + spdif = (rme96->wcreg & RME96_WCR_ADAT) == 0; } - rme96->playback_substream = NULL; - rme96->playback_periodsize = 0; - spdif = (rme96->wcreg & RME96_WCR_ADAT) == 0; - spin_unlock_irq(&rme96->lock); if (spdif) { rme96->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; snd_ctl_notify(rme96->card, SNDRV_CTL_EVENT_MASK_VALUE | @@ -1353,13 +1300,12 @@ snd_rme96_capture_close(struct snd_pcm_substream *substream) { struct rme96 *rme96 = snd_pcm_substream_chip(substream); - spin_lock_irq(&rme96->lock); + guard(spinlock_irq)(&rme96->lock); if (RME96_ISRECORDING(rme96)) { snd_rme96_trigger(rme96, RME96_STOP_CAPTURE); } rme96->capture_substream = NULL; rme96->capture_periodsize = 0; - spin_unlock_irq(&rme96->lock); return 0; } @@ -1368,12 +1314,11 @@ snd_rme96_playback_prepare(struct snd_pcm_substream *substream) { struct rme96 *rme96 = snd_pcm_substream_chip(substream); - spin_lock_irq(&rme96->lock); + guard(spinlock_irq)(&rme96->lock); if (RME96_ISPLAYING(rme96)) { snd_rme96_trigger(rme96, RME96_STOP_PLAYBACK); } writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS); - spin_unlock_irq(&rme96->lock); return 0; } @@ -1382,12 +1327,11 @@ snd_rme96_capture_prepare(struct snd_pcm_substream *substream) { struct rme96 *rme96 = snd_pcm_substream_chip(substream); - spin_lock_irq(&rme96->lock); + guard(spinlock_irq)(&rme96->lock); if (RME96_ISRECORDING(rme96)) { snd_rme96_trigger(rme96, RME96_STOP_CAPTURE); } writel(0, rme96->iobase + RME96_IO_RESET_REC_POS); - spin_unlock_irq(&rme96->lock); return 0; } @@ -1522,13 +1466,11 @@ snd_rme96_capture_pointer(struct snd_pcm_substream *substream) static const struct snd_pcm_ops snd_rme96_playback_spdif_ops = { .open = snd_rme96_playback_spdif_open, .close = snd_rme96_playback_close, - .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_rme96_playback_hw_params, .prepare = snd_rme96_playback_prepare, .trigger = snd_rme96_playback_trigger, .pointer = snd_rme96_playback_pointer, - .copy_user = snd_rme96_playback_copy, - .copy_kernel = snd_rme96_playback_copy_kernel, + .copy = snd_rme96_playback_copy, .fill_silence = snd_rme96_playback_silence, .mmap = snd_pcm_lib_mmap_iomem, }; @@ -1536,26 +1478,22 @@ static const struct snd_pcm_ops snd_rme96_playback_spdif_ops = { static const struct snd_pcm_ops snd_rme96_capture_spdif_ops = { .open = snd_rme96_capture_spdif_open, .close = snd_rme96_capture_close, - .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_rme96_capture_hw_params, .prepare = snd_rme96_capture_prepare, .trigger = snd_rme96_capture_trigger, .pointer = snd_rme96_capture_pointer, - .copy_user = snd_rme96_capture_copy, - .copy_kernel = snd_rme96_capture_copy_kernel, + .copy = snd_rme96_capture_copy, .mmap = snd_pcm_lib_mmap_iomem, }; static const struct snd_pcm_ops snd_rme96_playback_adat_ops = { .open = snd_rme96_playback_adat_open, .close = snd_rme96_playback_close, - .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_rme96_playback_hw_params, .prepare = snd_rme96_playback_prepare, .trigger = snd_rme96_playback_trigger, .pointer = snd_rme96_playback_pointer, - .copy_user = snd_rme96_playback_copy, - .copy_kernel = snd_rme96_playback_copy_kernel, + .copy = snd_rme96_playback_copy, .fill_silence = snd_rme96_playback_silence, .mmap = snd_pcm_lib_mmap_iomem, }; @@ -1563,44 +1501,24 @@ static const struct snd_pcm_ops snd_rme96_playback_adat_ops = { static const struct snd_pcm_ops snd_rme96_capture_adat_ops = { .open = snd_rme96_capture_adat_open, .close = snd_rme96_capture_close, - .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_rme96_capture_hw_params, .prepare = snd_rme96_capture_prepare, .trigger = snd_rme96_capture_trigger, .pointer = snd_rme96_capture_pointer, - .copy_user = snd_rme96_capture_copy, - .copy_kernel = snd_rme96_capture_copy_kernel, + .copy = snd_rme96_capture_copy, .mmap = snd_pcm_lib_mmap_iomem, }; static void -snd_rme96_free(void *private_data) +snd_rme96_free(struct rme96 *rme96) { - struct rme96 *rme96 = (struct rme96 *)private_data; - - if (!rme96) - return; - if (rme96->irq >= 0) { snd_rme96_trigger(rme96, RME96_STOP_BOTH); rme96->areg &= ~RME96_AR_DAC_EN; writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG); - free_irq(rme96->irq, (void *)rme96); - rme96->irq = -1; - } - if (rme96->iobase) { - iounmap(rme96->iobase); - rme96->iobase = NULL; } - if (rme96->port) { - pci_release_regions(rme96->pci); - rme96->port = 0; - } -#ifdef CONFIG_PM_SLEEP vfree(rme96->playback_suspend_buffer); vfree(rme96->capture_suspend_buffer); -#endif - pci_disable_device(rme96->pci); } static void @@ -1626,40 +1544,43 @@ snd_rme96_create(struct rme96 *rme96) rme96->irq = -1; spin_lock_init(&rme96->lock); - if ((err = pci_enable_device(pci)) < 0) + err = pcim_enable_device(pci); + if (err < 0) return err; - if ((err = pci_request_regions(pci, "RME96")) < 0) + err = pcim_request_all_regions(pci, "RME96"); + if (err < 0) return err; rme96->port = pci_resource_start(rme96->pci, 0); - rme96->iobase = ioremap_nocache(rme96->port, RME96_IO_SIZE); + rme96->iobase = devm_ioremap(&pci->dev, rme96->port, RME96_IO_SIZE); if (!rme96->iobase) { dev_err(rme96->card->dev, "unable to remap memory region 0x%lx-0x%lx\n", rme96->port, rme96->port + RME96_IO_SIZE - 1); - return -ENOMEM; + return -EBUSY; } - if (request_irq(pci->irq, snd_rme96_interrupt, IRQF_SHARED, - KBUILD_MODNAME, rme96)) { + if (devm_request_irq(&pci->dev, pci->irq, snd_rme96_interrupt, + IRQF_SHARED, KBUILD_MODNAME, rme96)) { dev_err(rme96->card->dev, "unable to grab IRQ %d\n", pci->irq); return -EBUSY; } rme96->irq = pci->irq; + rme96->card->sync_irq = rme96->irq; /* read the card's revision number */ pci_read_config_byte(pci, 8, &rme96->rev); /* set up ALSA pcm device for S/PDIF */ - if ((err = snd_pcm_new(rme96->card, "Digi96 IEC958", 0, - 1, 1, &rme96->spdif_pcm)) < 0) - { + err = snd_pcm_new(rme96->card, "Digi96 IEC958", 0, + 1, 1, &rme96->spdif_pcm); + if (err < 0) return err; - } + rme96->spdif_pcm->private_data = rme96; rme96->spdif_pcm->private_free = snd_rme96_free_spdif_pcm; - strcpy(rme96->spdif_pcm->name, "Digi96 IEC958"); + strscpy(rme96->spdif_pcm->name, "Digi96 IEC958"); snd_pcm_set_ops(rme96->spdif_pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_rme96_playback_spdif_ops); snd_pcm_set_ops(rme96->spdif_pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_rme96_capture_spdif_ops); @@ -1670,14 +1591,13 @@ snd_rme96_create(struct rme96 *rme96) /* ADAT is not available on the base model */ rme96->adat_pcm = NULL; } else { - if ((err = snd_pcm_new(rme96->card, "Digi96 ADAT", 1, - 1, 1, &rme96->adat_pcm)) < 0) - { + err = snd_pcm_new(rme96->card, "Digi96 ADAT", 1, + 1, 1, &rme96->adat_pcm); + if (err < 0) return err; - } rme96->adat_pcm->private_data = rme96; rme96->adat_pcm->private_free = snd_rme96_free_adat_pcm; - strcpy(rme96->adat_pcm->name, "Digi96 ADAT"); + strscpy(rme96->adat_pcm->name, "Digi96 ADAT"); snd_pcm_set_ops(rme96->adat_pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_rme96_playback_adat_ops); snd_pcm_set_ops(rme96->adat_pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_rme96_capture_adat_ops); @@ -1723,9 +1643,9 @@ snd_rme96_create(struct rme96 *rme96) } /* init switch interface */ - if ((err = snd_rme96_create_switches(rme96->card, rme96)) < 0) { + err = snd_rme96_create_switches(rme96->card, rme96); + if (err < 0) return err; - } /* init proc interface */ snd_rme96_proc_init(rme96); @@ -1868,10 +1788,7 @@ snd_rme96_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer static void snd_rme96_proc_init(struct rme96 *rme96) { - struct snd_info_entry *entry; - - if (! snd_card_proc_new(rme96->card, "rme96", &entry)) - snd_info_set_text_ops(entry, rme96, snd_rme96_proc_read); + snd_card_ro_proc_new(rme96->card, "rme96", rme96, snd_rme96_proc_read); } /* @@ -1885,9 +1802,8 @@ snd_rme96_get_loopback_control(struct snd_kcontrol *kcontrol, struct snd_ctl_ele { struct rme96 *rme96 = snd_kcontrol_chip(kcontrol); - spin_lock_irq(&rme96->lock); + guard(spinlock_irq)(&rme96->lock); ucontrol->value.integer.value[0] = rme96->wcreg & RME96_WCR_SEL ? 0 : 1; - spin_unlock_irq(&rme96->lock); return 0; } static int @@ -1898,12 +1814,11 @@ snd_rme96_put_loopback_control(struct snd_kcontrol *kcontrol, struct snd_ctl_ele int change; val = ucontrol->value.integer.value[0] ? 0 : RME96_WCR_SEL; - spin_lock_irq(&rme96->lock); + guard(spinlock_irq)(&rme96->lock); val = (rme96->wcreg & ~RME96_WCR_SEL) | val; change = val != rme96->wcreg; rme96->wcreg = val; writel(val, rme96->iobase + RME96_IO_CONTROL_REGISTER); - spin_unlock_irq(&rme96->lock); return change; } @@ -1949,7 +1864,7 @@ snd_rme96_get_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_el struct rme96 *rme96 = snd_kcontrol_chip(kcontrol); unsigned int items = 3; - spin_lock_irq(&rme96->lock); + guard(spinlock_irq)(&rme96->lock); ucontrol->value.enumerated.item[0] = snd_rme96_getinputtype(rme96); switch (rme96->pci->device) { @@ -1979,7 +1894,6 @@ snd_rme96_get_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_el ucontrol->value.enumerated.item[0] = items - 1; } - spin_unlock_irq(&rme96->lock); return 0; } static int @@ -2017,10 +1931,9 @@ snd_rme96_put_inputtype_control(struct snd_kcontrol *kcontrol, struct snd_ctl_el } } - spin_lock_irq(&rme96->lock); + guard(spinlock_irq)(&rme96->lock); change = (int)val != snd_rme96_getinputtype(rme96); snd_rme96_setinputtype(rme96, val); - spin_unlock_irq(&rme96->lock); return change; } @@ -2036,9 +1949,8 @@ snd_rme96_get_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_el { struct rme96 *rme96 = snd_kcontrol_chip(kcontrol); - spin_lock_irq(&rme96->lock); + guard(spinlock_irq)(&rme96->lock); ucontrol->value.enumerated.item[0] = snd_rme96_getclockmode(rme96); - spin_unlock_irq(&rme96->lock); return 0; } static int @@ -2049,10 +1961,9 @@ snd_rme96_put_clockmode_control(struct snd_kcontrol *kcontrol, struct snd_ctl_el int change; val = ucontrol->value.enumerated.item[0] % 3; - spin_lock_irq(&rme96->lock); + guard(spinlock_irq)(&rme96->lock); change = (int)val != snd_rme96_getclockmode(rme96); snd_rme96_setclockmode(rme96, val); - spin_unlock_irq(&rme96->lock); return change; } @@ -2070,9 +1981,8 @@ snd_rme96_get_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_ { struct rme96 *rme96 = snd_kcontrol_chip(kcontrol); - spin_lock_irq(&rme96->lock); + guard(spinlock_irq)(&rme96->lock); ucontrol->value.enumerated.item[0] = snd_rme96_getattenuation(rme96); - spin_unlock_irq(&rme96->lock); return 0; } static int @@ -2083,11 +1993,10 @@ snd_rme96_put_attenuation_control(struct snd_kcontrol *kcontrol, struct snd_ctl_ int change; val = ucontrol->value.enumerated.item[0] % 4; - spin_lock_irq(&rme96->lock); + guard(spinlock_irq)(&rme96->lock); change = (int)val != snd_rme96_getattenuation(rme96); snd_rme96_setattenuation(rme96, val); - spin_unlock_irq(&rme96->lock); return change; } @@ -2103,9 +2012,8 @@ snd_rme96_get_montracks_control(struct snd_kcontrol *kcontrol, struct snd_ctl_el { struct rme96 *rme96 = snd_kcontrol_chip(kcontrol); - spin_lock_irq(&rme96->lock); + guard(spinlock_irq)(&rme96->lock); ucontrol->value.enumerated.item[0] = snd_rme96_getmontracks(rme96); - spin_unlock_irq(&rme96->lock); return 0; } static int @@ -2116,10 +2024,9 @@ snd_rme96_put_montracks_control(struct snd_kcontrol *kcontrol, struct snd_ctl_el int change; val = ucontrol->value.enumerated.item[0] % 4; - spin_lock_irq(&rme96->lock); + guard(spinlock_irq)(&rme96->lock); change = (int)val != snd_rme96_getmontracks(rme96); snd_rme96_setmontracks(rme96, val); - spin_unlock_irq(&rme96->lock); return change; } @@ -2167,10 +2074,9 @@ static int snd_rme96_control_spdif_put(struct snd_kcontrol *kcontrol, struct snd u32 val; val = snd_rme96_convert_from_aes(&ucontrol->value.iec958); - spin_lock_irq(&rme96->lock); + guard(spinlock_irq)(&rme96->lock); change = val != rme96->wcreg_spdif; rme96->wcreg_spdif = val; - spin_unlock_irq(&rme96->lock); return change; } @@ -2196,13 +2102,12 @@ static int snd_rme96_control_spdif_stream_put(struct snd_kcontrol *kcontrol, str u32 val; val = snd_rme96_convert_from_aes(&ucontrol->value.iec958); - spin_lock_irq(&rme96->lock); + guard(spinlock_irq)(&rme96->lock); change = val != rme96->wcreg_spdif_stream; rme96->wcreg_spdif_stream = val; rme96->wcreg &= ~(RME96_WCR_PRO | RME96_WCR_DOLBY | RME96_WCR_EMP); rme96->wcreg |= val; writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); - spin_unlock_irq(&rme96->lock); return change; } @@ -2236,10 +2141,9 @@ snd_rme96_dac_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu { struct rme96 *rme96 = snd_kcontrol_chip(kcontrol); - spin_lock_irq(&rme96->lock); + guard(spinlock_irq)(&rme96->lock); u->value.integer.value[0] = rme96->vol[0]; u->value.integer.value[1] = rme96->vol[1]; - spin_unlock_irq(&rme96->lock); return 0; } @@ -2255,7 +2159,7 @@ snd_rme96_dac_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu if (!RME96_HAS_ANALOG_OUT(rme96)) return -EINVAL; maxvol = RME96_185X_MAX_OUT(rme96); - spin_lock_irq(&rme96->lock); + guard(spinlock_irq)(&rme96->lock); vol = u->value.integer.value[0]; if (vol != rme96->vol[0] && vol <= maxvol) { rme96->vol[0] = vol; @@ -2268,12 +2172,11 @@ snd_rme96_dac_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_valu } if (change) snd_rme96_apply_dac_volume(rme96); - spin_unlock_irq(&rme96->lock); return change; } -static struct snd_kcontrol_new snd_rme96_controls[] = { +static const struct snd_kcontrol_new snd_rme96_controls[] = { { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), @@ -2361,16 +2264,20 @@ snd_rme96_create_switches(struct snd_card *card, struct snd_kcontrol *kctl; for (idx = 0; idx < 7; idx++) { - if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_rme96_controls[idx], rme96))) < 0) + kctl = snd_ctl_new1(&snd_rme96_controls[idx], rme96); + err = snd_ctl_add(card, kctl); + if (err < 0) return err; if (idx == 1) /* IEC958 (S/PDIF) Stream */ rme96->spdif_ctl = kctl; } if (RME96_HAS_ANALOG_OUT(rme96)) { - for (idx = 7; idx < 10; idx++) - if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_rme96_controls[idx], rme96))) < 0) + for (idx = 7; idx < 10; idx++) { + err = snd_ctl_add(card, snd_ctl_new1(&snd_rme96_controls[idx], rme96)); + if (err < 0) return err; + } } return 0; @@ -2380,16 +2287,12 @@ snd_rme96_create_switches(struct snd_card *card, * Card initialisation */ -#ifdef CONFIG_PM_SLEEP - static int rme96_suspend(struct device *dev) { struct snd_card *card = dev_get_drvdata(dev); struct rme96 *rme96 = card->private_data; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - snd_pcm_suspend(rme96->playback_substream); - snd_pcm_suspend(rme96->capture_substream); /* save capture & playback pointers */ rme96->playback_pointer = readl(rme96->iobase + RME96_IO_GET_PLAY_POS) @@ -2445,11 +2348,7 @@ static int rme96_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(rme96_pm, rme96_suspend, rme96_resume); -#define RME96_PM_OPS &rme96_pm -#else -#define RME96_PM_OPS NULL -#endif /* CONFIG_PM_SLEEP */ +static DEFINE_SIMPLE_DEV_PM_OPS(rme96_pm, rme96_suspend, rme96_resume); static void snd_rme96_card_free(struct snd_card *card) { @@ -2457,8 +2356,8 @@ static void snd_rme96_card_free(struct snd_card *card) } static int -snd_rme96_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) +__snd_rme96_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) { static int dev; struct rme96 *rme96; @@ -2473,8 +2372,8 @@ snd_rme96_probe(struct pci_dev *pci, dev++; return -ENOENT; } - err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, - sizeof(struct rme96), &card); + err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, + sizeof(*rme96), &card); if (err < 0) return err; card->private_free = snd_rme96_card_free; @@ -2483,38 +2382,34 @@ snd_rme96_probe(struct pci_dev *pci, rme96->pci = pci; err = snd_rme96_create(rme96); if (err) - goto free_card; + return err; -#ifdef CONFIG_PM_SLEEP - rme96->playback_suspend_buffer = vmalloc(RME96_BUFFER_SIZE); - if (!rme96->playback_suspend_buffer) { - err = -ENOMEM; - goto free_card; + if (IS_ENABLED(CONFIG_PM_SLEEP)) { + rme96->playback_suspend_buffer = vmalloc(RME96_BUFFER_SIZE); + if (!rme96->playback_suspend_buffer) + return -ENOMEM; + rme96->capture_suspend_buffer = vmalloc(RME96_BUFFER_SIZE); + if (!rme96->capture_suspend_buffer) + return -ENOMEM; } - rme96->capture_suspend_buffer = vmalloc(RME96_BUFFER_SIZE); - if (!rme96->capture_suspend_buffer) { - err = -ENOMEM; - goto free_card; - } -#endif - strcpy(card->driver, "Digi96"); + strscpy(card->driver, "Digi96"); switch (rme96->pci->device) { case PCI_DEVICE_ID_RME_DIGI96: - strcpy(card->shortname, "RME Digi96"); + strscpy(card->shortname, "RME Digi96"); break; case PCI_DEVICE_ID_RME_DIGI96_8: - strcpy(card->shortname, "RME Digi96/8"); + strscpy(card->shortname, "RME Digi96/8"); break; case PCI_DEVICE_ID_RME_DIGI96_8_PRO: - strcpy(card->shortname, "RME Digi96/8 PRO"); + strscpy(card->shortname, "RME Digi96/8 PRO"); break; case PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST: pci_read_config_byte(rme96->pci, 8, &val); if (val < 5) { - strcpy(card->shortname, "RME Digi96/8 PAD"); + strscpy(card->shortname, "RME Digi96/8 PAD"); } else { - strcpy(card->shortname, "RME Digi96/8 PST"); + strscpy(card->shortname, "RME Digi96/8 PST"); } break; } @@ -2522,28 +2417,25 @@ snd_rme96_probe(struct pci_dev *pci, rme96->port, rme96->irq); err = snd_card_register(card); if (err) - goto free_card; + return err; pci_set_drvdata(pci, card); dev++; return 0; -free_card: - snd_card_free(card); - return err; } -static void snd_rme96_remove(struct pci_dev *pci) +static int snd_rme96_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_rme96_probe(pci, pci_id)); } static struct pci_driver rme96_driver = { .name = KBUILD_MODNAME, .id_table = snd_rme96_ids, .probe = snd_rme96_probe, - .remove = snd_rme96_remove, .driver = { - .pm = RME96_PM_OPS, + .pm = &rme96_pm, }, }; |
