aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/sound/pci/maestro3.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/maestro3.c')
-rw-r--r--sound/pci/maestro3.c181
1 files changed, 56 insertions, 125 deletions
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 40232a278b1a..f4d211970d7e 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -39,11 +39,6 @@
MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Takashi Iwai <tiwai@suse.de>");
MODULE_DESCRIPTION("ESS Maestro3 PCI");
MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{ESS,Maestro3 PCI},"
- "{ESS,ES1988},"
- "{ESS,Allegro PCI},"
- "{ESS,Allegro-1 PCI},"
- "{ESS,Canyon3D-2/LE PCI}}");
MODULE_FIRMWARE("ess/maestro3_assp_kernel.fw");
MODULE_FIRMWARE("ess/maestro3_assp_minisrc.fw");
@@ -774,9 +769,7 @@ struct snd_m3 {
unsigned int in_suspend;
-#ifdef CONFIG_PM_SLEEP
u16 *suspend_mem;
-#endif
const struct firmware *assp_kernel_image;
const struct firmware *assp_minisrc_image;
@@ -1245,7 +1238,7 @@ static void snd_m3_pcm_setup2(struct snd_m3 *chip, struct m3_dma *s,
snd_pcm_format_width(runtime->format) == 16 ? 0 : 1);
/* set up dac/adc rate */
- freq = ((runtime->rate << 15) + 24000 ) / 48000;
+ freq = DIV_ROUND_CLOSEST(runtime->rate << 15, 48000);
if (freq)
freq--;
@@ -1770,7 +1763,8 @@ snd_m3_playback_open(struct snd_pcm_substream *subs)
struct snd_pcm_runtime *runtime = subs->runtime;
int err;
- if ((err = snd_m3_substream_open(chip, subs)) < 0)
+ err = snd_m3_substream_open(chip, subs);
+ if (err < 0)
return err;
runtime->hw = snd_m3_playback;
@@ -1794,7 +1788,8 @@ snd_m3_capture_open(struct snd_pcm_substream *subs)
struct snd_pcm_runtime *runtime = subs->runtime;
int err;
- if ((err = snd_m3_substream_open(chip, subs)) < 0)
+ err = snd_m3_substream_open(chip, subs);
+ if (err < 0)
return err;
runtime->hw = snd_m3_capture;
@@ -2032,21 +2027,20 @@ static int snd_m3_mixer(struct snd_m3 *chip)
{
struct snd_ac97_bus *pbus;
struct snd_ac97_template ac97;
-#ifndef CONFIG_SND_MAESTRO3_INPUT
- struct snd_ctl_elem_id elem_id;
-#endif
int err;
static const struct snd_ac97_bus_ops ops = {
.write = snd_m3_ac97_write,
.read = snd_m3_ac97_read,
};
- if ((err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus)) < 0)
+ err = snd_ac97_bus(chip->card, 0, &ops, NULL, &pbus);
+ if (err < 0)
return err;
memset(&ac97, 0, sizeof(ac97));
ac97.private_data = chip;
- if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97)) < 0)
+ err = snd_ac97_mixer(pbus, &ac97, &chip->ac97);
+ if (err < 0)
return err;
/* seems ac97 PCM needs initialization.. hack hack.. */
@@ -2055,14 +2049,10 @@ static int snd_m3_mixer(struct snd_m3 *chip)
snd_ac97_write(chip->ac97, AC97_PCM, 0);
#ifndef CONFIG_SND_MAESTRO3_INPUT
- memset(&elem_id, 0, sizeof(elem_id));
- elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(elem_id.name, "Master Playback Switch");
- chip->master_switch = snd_ctl_find_id(chip->card, &elem_id);
- memset(&elem_id, 0, sizeof(elem_id));
- elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(elem_id.name, "Master Playback Volume");
- chip->master_volume = snd_ctl_find_id(chip->card, &elem_id);
+ chip->master_switch = snd_ctl_find_id_mixer(chip->card,
+ "Master Playback Switch");
+ chip->master_volume = snd_ctl_find_id_mixer(chip->card,
+ "Master Playback Volume");
#endif
return 0;
@@ -2340,16 +2330,13 @@ snd_m3_enable_ints(struct snd_m3 *chip)
/*
*/
-static int snd_m3_free(struct snd_m3 *chip)
+static void snd_m3_free(struct snd_card *card)
{
+ struct snd_m3 *chip = card->private_data;
struct m3_dma *s;
int i;
cancel_work_sync(&chip->hwvol_work);
-#ifdef CONFIG_SND_MAESTRO3_INPUT
- if (chip->input_dev)
- input_unregister_device(chip->input_dev);
-#endif
if (chip->substreams) {
spin_lock_irq(&chip->reg_lock);
@@ -2360,35 +2347,20 @@ static int snd_m3_free(struct snd_m3 *chip)
snd_m3_pcm_stop(chip, s, s->substream);
}
spin_unlock_irq(&chip->reg_lock);
- kfree(chip->substreams);
}
if (chip->iobase) {
outw(0, chip->iobase + HOST_INT_CTRL); /* disable ints */
}
-#ifdef CONFIG_PM_SLEEP
vfree(chip->suspend_mem);
-#endif
-
- if (chip->irq >= 0)
- free_irq(chip->irq, chip);
-
- if (chip->iobase)
- pci_release_regions(chip->pci);
-
release_firmware(chip->assp_kernel_image);
release_firmware(chip->assp_minisrc_image);
-
- pci_disable_device(chip->pci);
- kfree(chip);
- return 0;
}
/*
* APM support
*/
-#ifdef CONFIG_PM_SLEEP
static int m3_suspend(struct device *dev)
{
struct snd_card *card = dev_get_drvdata(dev);
@@ -2462,11 +2434,7 @@ static int m3_resume(struct device *dev)
return 0;
}
-static SIMPLE_DEV_PM_OPS(m3_pm, m3_suspend, m3_resume);
-#define M3_PM_OPS &m3_pm
-#else
-#define M3_PM_OPS NULL
-#endif /* CONFIG_PM_SLEEP */
+static DEFINE_SIMPLE_DEV_PM_OPS(m3_pm, m3_suspend, m3_resume);
#ifdef CONFIG_SND_MAESTRO3_INPUT
static int snd_m3_input_register(struct snd_m3 *chip)
@@ -2474,7 +2442,7 @@ static int snd_m3_input_register(struct snd_m3 *chip)
struct input_dev *input_dev;
int err;
- input_dev = input_allocate_device();
+ input_dev = devm_input_allocate_device(&chip->pci->dev);
if (!input_dev)
return -ENOMEM;
@@ -2494,10 +2462,8 @@ static int snd_m3_input_register(struct snd_m3 *chip)
__set_bit(KEY_VOLUMEUP, input_dev->keybit);
err = input_register_device(input_dev);
- if (err) {
- input_free_device(input_dev);
+ if (err)
return err;
- }
chip->input_dev = input_dev;
return 0;
@@ -2507,45 +2473,25 @@ static int snd_m3_input_register(struct snd_m3 *chip)
/*
*/
-static int snd_m3_dev_free(struct snd_device *device)
-{
- struct snd_m3 *chip = device->device_data;
- return snd_m3_free(chip);
-}
-
static int
snd_m3_create(struct snd_card *card, struct pci_dev *pci,
int enable_amp,
- int amp_gpio,
- struct snd_m3 **chip_ret)
+ int amp_gpio)
{
- struct snd_m3 *chip;
+ struct snd_m3 *chip = card->private_data;
int i, err;
const struct snd_pci_quirk *quirk;
- static const struct snd_device_ops ops = {
- .dev_free = snd_m3_dev_free,
- };
-
- *chip_ret = NULL;
- if (pci_enable_device(pci))
+ if (pcim_enable_device(pci))
return -EIO;
/* check, if we can restrict PCI DMA transfers to 28 bits */
- if (dma_set_mask(&pci->dev, DMA_BIT_MASK(28)) < 0 ||
- dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(28)) < 0) {
+ if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(28))) {
dev_err(card->dev,
"architecture does not support 28bit PCI busmaster DMA\n");
- pci_disable_device(pci);
return -ENXIO;
}
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
- if (chip == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
spin_lock_init(&chip->reg_lock);
switch (pci->device) {
@@ -2561,6 +2507,7 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
chip->pci = pci;
chip->irq = -1;
INIT_WORK(&chip->hwvol_work, snd_m3_update_hw_volume);
+ card->private_free = snd_m3_free;
chip->external_amp = enable_amp;
if (amp_gpio >= 0 && amp_gpio <= 0x0f)
@@ -2590,27 +2537,24 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
chip->is_omnibook = 1;
chip->num_substreams = NR_DSPS;
- chip->substreams = kcalloc(chip->num_substreams, sizeof(struct m3_dma),
- GFP_KERNEL);
- if (chip->substreams == NULL) {
- kfree(chip);
- pci_disable_device(pci);
+ chip->substreams = devm_kcalloc(&pci->dev, chip->num_substreams,
+ sizeof(struct m3_dma), GFP_KERNEL);
+ if (!chip->substreams)
return -ENOMEM;
- }
err = request_firmware(&chip->assp_kernel_image,
"ess/maestro3_assp_kernel.fw", &pci->dev);
if (err < 0)
- goto free_chip;
+ return err;
err = request_firmware(&chip->assp_minisrc_image,
"ess/maestro3_assp_minisrc.fw", &pci->dev);
if (err < 0)
- goto free_chip;
+ return err;
err = pci_request_regions(pci, card->driver);
if (err < 0)
- goto free_chip;
+ return err;
chip->iobase = pci_resource_start(pci, 0);
@@ -2626,38 +2570,36 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
snd_m3_hv_init(chip);
- if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED,
- KBUILD_MODNAME, chip)) {
+ if (devm_request_irq(&pci->dev, pci->irq, snd_m3_interrupt, IRQF_SHARED,
+ KBUILD_MODNAME, chip)) {
dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
- err = -ENOMEM;
- goto free_chip;
+ return -ENOMEM;
}
chip->irq = pci->irq;
card->sync_irq = chip->irq;
-#ifdef CONFIG_PM_SLEEP
- chip->suspend_mem =
- vmalloc(array_size(sizeof(u16),
- REV_B_CODE_MEMORY_LENGTH +
- REV_B_DATA_MEMORY_LENGTH));
- if (chip->suspend_mem == NULL)
- dev_warn(card->dev, "can't allocate apm buffer\n");
-#endif
+ if (IS_ENABLED(CONFIG_PM_SLEEP)) {
+ chip->suspend_mem =
+ vmalloc(array_size(sizeof(u16),
+ REV_B_CODE_MEMORY_LENGTH +
+ REV_B_DATA_MEMORY_LENGTH));
+ if (!chip->suspend_mem)
+ dev_warn(card->dev, "can't allocate apm buffer\n");
+ }
- err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
+ err = snd_m3_mixer(chip);
if (err < 0)
- goto free_chip;
-
- if ((err = snd_m3_mixer(chip)) < 0)
return err;
for (i = 0; i < chip->num_substreams; i++) {
struct m3_dma *s = &chip->substreams[i];
- if ((err = snd_m3_assp_client_init(chip, s, i)) < 0)
+ err = snd_m3_assp_client_init(chip, s, i);
+ if (err < 0)
return err;
}
- if ((err = snd_m3_pcm(chip, 0)) < 0)
+ err = snd_m3_pcm(chip, 0);
+ if (err < 0)
return err;
#ifdef CONFIG_SND_MAESTRO3_INPUT
@@ -2673,19 +2615,13 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
snd_m3_enable_ints(chip);
snd_m3_assp_continue(chip);
- *chip_ret = chip;
-
return 0;
-
-free_chip:
- snd_m3_free(chip);
- return err;
}
/*
*/
static int
-snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
+__snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
{
static int dev;
struct snd_card *card;
@@ -2703,10 +2639,11 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
return -ENOENT;
}
- err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
- 0, &card);
+ err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+ sizeof(*chip), &card);
if (err < 0)
return err;
+ chip = card->private_data;
switch (pci->device) {
case PCI_DEVICE_ID_ESS_ALLEGRO:
@@ -2722,11 +2659,9 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
break;
}
- err = snd_m3_create(card, pci, external_amp[dev], amp_gpio[dev], &chip);
+ err = snd_m3_create(card, pci, external_amp[dev], amp_gpio[dev]);
if (err < 0)
- goto free_card;
-
- card->private_data = chip;
+ return err;
sprintf(card->shortname, "ESS %s PCI", card->driver);
sprintf(card->longname, "%s at 0x%lx, irq %d",
@@ -2734,7 +2669,7 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
err = snd_card_register(card);
if (err < 0)
- goto free_card;
+ return err;
#if 0 /* TODO: not supported yet */
/* TODO enable MIDI IRQ and I/O */
@@ -2749,24 +2684,20 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
pci_set_drvdata(pci, card);
dev++;
return 0;
-
-free_card:
- snd_card_free(card);
- return err;
}
-static void snd_m3_remove(struct pci_dev *pci)
+static int
+snd_m3_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_m3_probe(pci, pci_id));
}
static struct pci_driver m3_driver = {
.name = KBUILD_MODNAME,
.id_table = snd_m3_ids,
.probe = snd_m3_probe,
- .remove = snd_m3_remove,
.driver = {
- .pm = M3_PM_OPS,
+ .pm = &m3_pm,
},
};