1
linux/sound/pci/emu10k1/emu10k1_synth.c
Oswald Buddenhagen 67192cc0f0 ALSA: emu10k1: remove superfluous IRQ enable state saving
The mixer, PCM prepare, MIDI, synth driver, and procfs callbacks are all
always invoked with IRQs enabled, so there is no point in saving the
state.

snd_emu1010_load_firmware_entry() is called from emu1010_firmware_work()
and snd_emu10k1_emu1010_init(); the latter from snd_emu10k1_create() and
snd_emu10k1_resume(), all of which have IRQs enabled.

The voice and memory functions are called from mixed contexts, so they
keep the state saving.

The low-level functions all keep the state saving, because it's not
feasible to keep track of what is called where.

Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Link: https://lore.kernel.org/r/20230712145750.125086-2-oswald.buddenhagen@gmx.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
2023-07-13 10:30:06 +02:00

104 lines
2.3 KiB
C

// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2000 Takashi Iwai <tiwai@suse.de>
*
* Routines for control of EMU10K1 WaveTable synth
*/
#include "emu10k1_synth_local.h"
#include <linux/init.h>
#include <linux/module.h>
MODULE_AUTHOR("Takashi Iwai");
MODULE_DESCRIPTION("Routines for control of EMU10K1 WaveTable synth");
MODULE_LICENSE("GPL");
/*
* create a new hardware dependent device for Emu10k1
*/
static int snd_emu10k1_synth_probe(struct device *_dev)
{
struct snd_seq_device *dev = to_seq_dev(_dev);
struct snd_emux *emux;
struct snd_emu10k1 *hw;
struct snd_emu10k1_synth_arg *arg;
arg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
if (arg == NULL)
return -EINVAL;
if (arg->seq_ports <= 0)
return 0; /* nothing */
if (arg->max_voices < 1)
arg->max_voices = 1;
else if (arg->max_voices > 64)
arg->max_voices = 64;
if (snd_emux_new(&emux) < 0)
return -ENOMEM;
snd_emu10k1_ops_setup(emux);
hw = arg->hwptr;
emux->hw = hw;
emux->max_voices = arg->max_voices;
emux->num_ports = arg->seq_ports;
emux->memhdr = hw->memhdr;
/* maximum two ports */
emux->midi_ports = arg->seq_ports < 2 ? arg->seq_ports : 2;
/* audigy has two external midis */
emux->midi_devidx = hw->audigy ? 2 : 1;
emux->linear_panning = 0;
emux->hwdep_idx = 2; /* FIXED */
if (snd_emux_register(emux, dev->card, arg->index, "Emu10k1") < 0) {
snd_emux_free(emux);
return -ENOMEM;
}
spin_lock_irq(&hw->voice_lock);
hw->synth = emux;
hw->get_synth_voice = snd_emu10k1_synth_get_voice;
spin_unlock_irq(&hw->voice_lock);
dev->driver_data = emux;
return 0;
}
static int snd_emu10k1_synth_remove(struct device *_dev)
{
struct snd_seq_device *dev = to_seq_dev(_dev);
struct snd_emux *emux;
struct snd_emu10k1 *hw;
if (dev->driver_data == NULL)
return 0; /* not registered actually */
emux = dev->driver_data;
hw = emux->hw;
spin_lock_irq(&hw->voice_lock);
hw->synth = NULL;
hw->get_synth_voice = NULL;
spin_unlock_irq(&hw->voice_lock);
snd_emux_free(emux);
return 0;
}
/*
* INIT part
*/
static struct snd_seq_driver emu10k1_synth_driver = {
.driver = {
.name = KBUILD_MODNAME,
.probe = snd_emu10k1_synth_probe,
.remove = snd_emu10k1_synth_remove,
},
.id = SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH,
.argsize = sizeof(struct snd_emu10k1_synth_arg),
};
module_snd_seq_driver(emu10k1_synth_driver);