diff options
Diffstat (limited to 'sound/pci/aw2/aw2-alsa.c')
| -rw-r--r-- | sound/pci/aw2/aw2-alsa.c | 227 |
1 files changed, 53 insertions, 174 deletions
diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c index 9a49e4243a9c..e2c501f4394c 100644 --- a/sound/pci/aw2/aw2-alsa.c +++ b/sound/pci/aw2/aw2-alsa.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only /***************************************************************************** * * Copyright (C) 2008 Cedric Bregardis <cedric.bregardis@free.fr> and @@ -5,20 +6,6 @@ * * This file is part of the Audiowerk2 ALSA driver * - * The Audiowerk2 ALSA driver 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; version 2. - * - * The Audiowerk2 ALSA driver 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 the Audiowerk2 ALSA driver; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - * USA. - * *****************************************************************************/ #include <linux/init.h> #include <linux/pci.h> @@ -112,19 +99,13 @@ struct aw2 { /********************************* * FUNCTION DECLARATIONS ********************************/ -static int snd_aw2_dev_free(struct snd_device *device); -static int snd_aw2_create(struct snd_card *card, - struct pci_dev *pci, struct aw2 **rchip); +static int snd_aw2_create(struct snd_card *card, struct pci_dev *pci); static int snd_aw2_probe(struct pci_dev *pci, const struct pci_device_id *pci_id); -static void snd_aw2_remove(struct pci_dev *pci); static int snd_aw2_pcm_playback_open(struct snd_pcm_substream *substream); static int snd_aw2_pcm_playback_close(struct snd_pcm_substream *substream); static int snd_aw2_pcm_capture_open(struct snd_pcm_substream *substream); static int snd_aw2_pcm_capture_close(struct snd_pcm_substream *substream); -static int snd_aw2_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params); -static int snd_aw2_pcm_hw_free(struct snd_pcm_substream *substream); static int snd_aw2_pcm_prepare_playback(struct snd_pcm_substream *substream); static int snd_aw2_pcm_prepare_capture(struct snd_pcm_substream *substream); static int snd_aw2_pcm_trigger_playback(struct snd_pcm_substream *substream, @@ -173,7 +154,6 @@ static struct pci_driver aw2_driver = { .name = KBUILD_MODNAME, .id_table = snd_aw2_ids, .probe = snd_aw2_probe, - .remove = snd_aw2_remove, }; module_pci_driver(aw2_driver); @@ -182,9 +162,6 @@ module_pci_driver(aw2_driver); static const struct snd_pcm_ops snd_aw2_playback_ops = { .open = snd_aw2_pcm_playback_open, .close = snd_aw2_pcm_playback_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_aw2_pcm_hw_params, - .hw_free = snd_aw2_pcm_hw_free, .prepare = snd_aw2_pcm_prepare_playback, .trigger = snd_aw2_pcm_trigger_playback, .pointer = snd_aw2_pcm_pointer_playback, @@ -194,9 +171,6 @@ static const struct snd_pcm_ops snd_aw2_playback_ops = { static const struct snd_pcm_ops snd_aw2_capture_ops = { .open = snd_aw2_pcm_capture_open, .close = snd_aw2_pcm_capture_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_aw2_pcm_hw_params, - .hw_free = snd_aw2_pcm_hw_free, .prepare = snd_aw2_pcm_prepare_capture, .trigger = snd_aw2_pcm_trigger_capture, .pointer = snd_aw2_pcm_pointer_capture, @@ -218,57 +192,32 @@ static const struct snd_kcontrol_new aw2_control = { ********************************/ /* component-destructor */ -static int snd_aw2_dev_free(struct snd_device *device) +static void snd_aw2_free(struct snd_card *card) { - struct aw2 *chip = device->device_data; + struct aw2 *chip = card->private_data; /* Free hardware */ snd_aw2_saa7146_free(&chip->saa7146); - - /* release the irq */ - if (chip->irq >= 0) - free_irq(chip->irq, (void *)chip); - /* release the i/o ports & memory */ - iounmap(chip->iobase_virt); - pci_release_regions(chip->pci); - /* disable the PCI entry */ - pci_disable_device(chip->pci); - /* release the data */ - kfree(chip); - - return 0; } /* chip-specific constructor */ static int snd_aw2_create(struct snd_card *card, - struct pci_dev *pci, struct aw2 **rchip) + struct pci_dev *pci) { - struct aw2 *chip; + struct aw2 *chip = card->private_data; int err; - static struct snd_device_ops ops = { - .dev_free = snd_aw2_dev_free, - }; - - *rchip = NULL; /* initialize the PCI entry */ - err = pci_enable_device(pci); + err = pcim_enable_device(pci); if (err < 0) return err; pci_set_master(pci); /* check PCI availability (32bit DMA) */ - if ((dma_set_mask(&pci->dev, DMA_BIT_MASK(32)) < 0) || - (dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)) < 0)) { + if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) { dev_err(card->dev, "Impossible to set 32bit mask DMA\n"); - pci_disable_device(pci); return -ENXIO; } - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (chip == NULL) { - pci_disable_device(pci); - return -ENOMEM; - } /* initialize the stuff */ chip->card = card; @@ -276,51 +225,22 @@ static int snd_aw2_create(struct snd_card *card, chip->irq = -1; /* (1) PCI resource allocation */ - err = pci_request_regions(pci, "Audiowerk2"); - if (err < 0) { - pci_disable_device(pci); - kfree(chip); - return err; - } + chip->iobase_virt = pcim_iomap_region(pci, 0, "Audiowerk2"); + if (IS_ERR(chip->iobase_virt)) + return PTR_ERR(chip->iobase_virt); chip->iobase_phys = pci_resource_start(pci, 0); - chip->iobase_virt = - ioremap_nocache(chip->iobase_phys, - pci_resource_len(pci, 0)); - - if (chip->iobase_virt == NULL) { - dev_err(card->dev, "unable to remap memory region"); - pci_release_regions(pci); - pci_disable_device(pci); - kfree(chip); - return -ENOMEM; - } /* (2) initialization of the chip hardware */ snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt); - if (request_irq(pci->irq, snd_aw2_saa7146_interrupt, - IRQF_SHARED, KBUILD_MODNAME, chip)) { + if (devm_request_irq(&pci->dev, pci->irq, snd_aw2_saa7146_interrupt, + IRQF_SHARED, KBUILD_MODNAME, chip)) { dev_err(card->dev, "Cannot grab irq %d\n", pci->irq); - - iounmap(chip->iobase_virt); - pci_release_regions(chip->pci); - pci_disable_device(chip->pci); - kfree(chip); return -EBUSY; } chip->irq = pci->irq; - - err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); - if (err < 0) { - free_irq(chip->irq, (void *)chip); - iounmap(chip->iobase_virt); - pci_release_regions(chip->pci); - pci_disable_device(chip->pci); - kfree(chip); - return err; - } - - *rchip = chip; + card->sync_irq = chip->irq; + card->private_free = snd_aw2_free; dev_info(card->dev, "Audiowerk 2 sound card (saa7146 chipset) detected and managed\n"); @@ -345,25 +265,24 @@ static int snd_aw2_probe(struct pci_dev *pci, } /* (2) Create card instance */ - 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; /* (3) Create main component */ - err = snd_aw2_create(card, pci, &chip); - if (err < 0) { - snd_card_free(card); - return err; - } + err = snd_aw2_create(card, pci); + if (err < 0) + goto error; /* initialize mutex */ mutex_init(&chip->mtx); /* init spinlock */ spin_lock_init(&chip->reg_lock); /* (4) Define driver ID and name string */ - strcpy(card->driver, "aw2"); - strcpy(card->shortname, "Audiowerk2"); + strscpy(card->driver, "aw2"); + strscpy(card->shortname, "Audiowerk2"); sprintf(card->longname, "%s with SAA7146 irq %i", card->shortname, chip->irq); @@ -373,22 +292,18 @@ static int snd_aw2_probe(struct pci_dev *pci, /* (6) Register card instance */ err = snd_card_register(card); - if (err < 0) { - snd_card_free(card); - return err; - } + if (err < 0) + goto error; /* (7) Set PCI driver data */ pci_set_drvdata(pci, card); dev++; return 0; -} -/* destructor */ -static void snd_aw2_remove(struct pci_dev *pci) -{ - snd_card_free(pci_get_drvdata(pci)); + error: + snd_card_free(card); + return err; } /* open callback */ @@ -424,20 +339,6 @@ static int snd_aw2_pcm_capture_close(struct snd_pcm_substream *substream) return 0; } - /* hw_params callback */ -static int snd_aw2_pcm_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)); -} - -/* hw_free callback */ -static int snd_aw2_pcm_hw_free(struct snd_pcm_substream *substream) -{ - return snd_pcm_lib_free_pages(substream); -} - /* prepare callback for playback */ static int snd_aw2_pcm_prepare_playback(struct snd_pcm_substream *substream) { @@ -446,7 +347,7 @@ static int snd_aw2_pcm_prepare_playback(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; unsigned long period_size, buffer_size; - mutex_lock(&chip->mtx); + guard(mutex)(&chip->mtx); period_size = snd_pcm_lib_period_bytes(substream); buffer_size = snd_pcm_lib_buffer_bytes(substream); @@ -462,8 +363,6 @@ static int snd_aw2_pcm_prepare_playback(struct snd_pcm_substream *substream) snd_pcm_period_elapsed, (void *)substream); - mutex_unlock(&chip->mtx); - return 0; } @@ -475,7 +374,7 @@ static int snd_aw2_pcm_prepare_capture(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; unsigned long period_size, buffer_size; - mutex_lock(&chip->mtx); + guard(mutex)(&chip->mtx); period_size = snd_pcm_lib_period_bytes(substream); buffer_size = snd_pcm_lib_buffer_bytes(substream); @@ -491,8 +390,6 @@ static int snd_aw2_pcm_prepare_capture(struct snd_pcm_substream *substream) snd_pcm_period_elapsed, (void *)substream); - mutex_unlock(&chip->mtx); - return 0; } @@ -500,10 +397,10 @@ static int snd_aw2_pcm_prepare_capture(struct snd_pcm_substream *substream) static int snd_aw2_pcm_trigger_playback(struct snd_pcm_substream *substream, int cmd) { - int status = 0; struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream); struct aw2 *chip = pcm_device->chip; - spin_lock(&chip->reg_lock); + + guard(spinlock)(&chip->reg_lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: snd_aw2_saa7146_pcm_trigger_start_playback(&chip->saa7146, @@ -516,20 +413,19 @@ static int snd_aw2_pcm_trigger_playback(struct snd_pcm_substream *substream, stream_number); break; default: - status = -EINVAL; + return -EINVAL; } - spin_unlock(&chip->reg_lock); - return status; + return 0; } /* capture trigger callback */ static int snd_aw2_pcm_trigger_capture(struct snd_pcm_substream *substream, int cmd) { - int status = 0; struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream); struct aw2 *chip = pcm_device->chip; - spin_lock(&chip->reg_lock); + + guard(spinlock)(&chip->reg_lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: snd_aw2_saa7146_pcm_trigger_start_capture(&chip->saa7146, @@ -542,10 +438,9 @@ static int snd_aw2_pcm_trigger_capture(struct snd_pcm_substream *substream, stream_number); break; default: - status = -EINVAL; + return -EINVAL; } - spin_unlock(&chip->reg_lock); - return status; + return 0; } /* playback pointer callback */ @@ -608,7 +503,7 @@ static int snd_aw2_new_pcm(struct aw2 *chip) pcm_device = &chip->device_playback[NUM_STREAM_PLAYBACK_ANA]; /* Set PCM device name */ - strcpy(pcm_playback_ana->name, "Analog playback"); + strscpy(pcm_playback_ana->name, "Analog playback"); /* Associate private data to PCM device */ pcm_playback_ana->private_data = pcm_device; /* set operators of PCM device */ @@ -624,15 +519,10 @@ static int snd_aw2_new_pcm(struct aw2 *chip) /* pre-allocation of buffers */ /* Preallocate continuous pages. */ - err = snd_pcm_lib_preallocate_pages_for_all(pcm_playback_ana, - SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data - (chip->pci), - 64 * 1024, 64 * 1024); - if (err) - dev_err(chip->card->dev, - "snd_pcm_lib_preallocate_pages_for_all error (0x%X)\n", - err); + snd_pcm_set_managed_buffer_all(pcm_playback_ana, + SNDRV_DMA_TYPE_DEV, + &chip->pci->dev, + 64 * 1024, 64 * 1024); err = snd_pcm_new(chip->card, "Audiowerk2 digital playback", 1, 1, 0, &pcm_playback_num); @@ -645,7 +535,7 @@ static int snd_aw2_new_pcm(struct aw2 *chip) pcm_device = &chip->device_playback[NUM_STREAM_PLAYBACK_DIG]; /* Set PCM device name */ - strcpy(pcm_playback_num->name, "Digital playback"); + strscpy(pcm_playback_num->name, "Digital playback"); /* Associate private data to PCM device */ pcm_playback_num->private_data = pcm_device; /* set operators of PCM device */ @@ -661,15 +551,10 @@ static int snd_aw2_new_pcm(struct aw2 *chip) /* pre-allocation of buffers */ /* Preallocate continuous pages. */ - err = snd_pcm_lib_preallocate_pages_for_all(pcm_playback_num, - SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data - (chip->pci), - 64 * 1024, 64 * 1024); - if (err) - dev_err(chip->card->dev, - "snd_pcm_lib_preallocate_pages_for_all error (0x%X)\n", - err); + snd_pcm_set_managed_buffer_all(pcm_playback_num, + SNDRV_DMA_TYPE_DEV, + &chip->pci->dev, + 64 * 1024, 64 * 1024); err = snd_pcm_new(chip->card, "Audiowerk2 capture", 2, 0, 1, &pcm_capture); @@ -683,7 +568,7 @@ static int snd_aw2_new_pcm(struct aw2 *chip) pcm_device = &chip->device_capture[NUM_STREAM_CAPTURE_ANA]; /* Set PCM device name */ - strcpy(pcm_capture->name, "Capture"); + strscpy(pcm_capture->name, "Capture"); /* Associate private data to PCM device */ pcm_capture->private_data = pcm_device; /* set operators of PCM device */ @@ -699,16 +584,10 @@ static int snd_aw2_new_pcm(struct aw2 *chip) /* pre-allocation of buffers */ /* Preallocate continuous pages. */ - err = snd_pcm_lib_preallocate_pages_for_all(pcm_capture, - SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data - (chip->pci), - 64 * 1024, 64 * 1024); - if (err) - dev_err(chip->card->dev, - "snd_pcm_lib_preallocate_pages_for_all error (0x%X)\n", - err); - + snd_pcm_set_managed_buffer_all(pcm_capture, + SNDRV_DMA_TYPE_DEV, + &chip->pci->dev, + 64 * 1024, 64 * 1024); /* Create control */ err = snd_ctl_add(chip->card, snd_ctl_new1(&aw2_control, chip)); |
