emu10k1_synth.c (2469B)
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de> 4 * 5 * Routines for control of EMU10K1 WaveTable synth 6 */ 7 8#include "emu10k1_synth_local.h" 9#include <linux/init.h> 10#include <linux/module.h> 11 12MODULE_AUTHOR("Takashi Iwai"); 13MODULE_DESCRIPTION("Routines for control of EMU10K1 WaveTable synth"); 14MODULE_LICENSE("GPL"); 15 16/* 17 * create a new hardware dependent device for Emu10k1 18 */ 19static int snd_emu10k1_synth_probe(struct device *_dev) 20{ 21 struct snd_seq_device *dev = to_seq_dev(_dev); 22 struct snd_emux *emux; 23 struct snd_emu10k1 *hw; 24 struct snd_emu10k1_synth_arg *arg; 25 unsigned long flags; 26 27 arg = SNDRV_SEQ_DEVICE_ARGPTR(dev); 28 if (arg == NULL) 29 return -EINVAL; 30 31 if (arg->seq_ports <= 0) 32 return 0; /* nothing */ 33 if (arg->max_voices < 1) 34 arg->max_voices = 1; 35 else if (arg->max_voices > 64) 36 arg->max_voices = 64; 37 38 if (snd_emux_new(&emux) < 0) 39 return -ENOMEM; 40 41 snd_emu10k1_ops_setup(emux); 42 hw = arg->hwptr; 43 emux->hw = hw; 44 emux->max_voices = arg->max_voices; 45 emux->num_ports = arg->seq_ports; 46 emux->pitch_shift = -501; 47 emux->memhdr = hw->memhdr; 48 /* maximum two ports */ 49 emux->midi_ports = arg->seq_ports < 2 ? arg->seq_ports : 2; 50 /* audigy has two external midis */ 51 emux->midi_devidx = hw->audigy ? 2 : 1; 52 emux->linear_panning = 0; 53 emux->hwdep_idx = 2; /* FIXED */ 54 55 if (snd_emux_register(emux, dev->card, arg->index, "Emu10k1") < 0) { 56 snd_emux_free(emux); 57 return -ENOMEM; 58 } 59 60 spin_lock_irqsave(&hw->voice_lock, flags); 61 hw->synth = emux; 62 hw->get_synth_voice = snd_emu10k1_synth_get_voice; 63 spin_unlock_irqrestore(&hw->voice_lock, flags); 64 65 dev->driver_data = emux; 66 67 return 0; 68} 69 70static int snd_emu10k1_synth_remove(struct device *_dev) 71{ 72 struct snd_seq_device *dev = to_seq_dev(_dev); 73 struct snd_emux *emux; 74 struct snd_emu10k1 *hw; 75 unsigned long flags; 76 77 if (dev->driver_data == NULL) 78 return 0; /* not registered actually */ 79 80 emux = dev->driver_data; 81 82 hw = emux->hw; 83 spin_lock_irqsave(&hw->voice_lock, flags); 84 hw->synth = NULL; 85 hw->get_synth_voice = NULL; 86 spin_unlock_irqrestore(&hw->voice_lock, flags); 87 88 snd_emux_free(emux); 89 return 0; 90} 91 92/* 93 * INIT part 94 */ 95 96static struct snd_seq_driver emu10k1_synth_driver = { 97 .driver = { 98 .name = KBUILD_MODNAME, 99 .probe = snd_emu10k1_synth_probe, 100 .remove = snd_emu10k1_synth_remove, 101 }, 102 .id = SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH, 103 .argsize = sizeof(struct snd_emu10k1_synth_arg), 104}; 105 106module_snd_seq_driver(emu10k1_synth_driver);