1/* 2 * Copyright (C) 2000 Takashi Iwai <tiwai@suse.de> 3 * 4 * Routines for control of EMU10K1 WaveTable synth 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 21#include "emu10k1_synth_local.h" 22#include <linux/init.h> 23#include <linux/module.h> 24 25MODULE_AUTHOR("Takashi Iwai"); 26MODULE_DESCRIPTION("Routines for control of EMU10K1 WaveTable synth"); 27MODULE_LICENSE("GPL"); 28 29/* 30 * create a new hardware dependent device for Emu10k1 31 */ 32static int snd_emu10k1_synth_probe(struct device *_dev) 33{ 34 struct snd_seq_device *dev = to_seq_dev(_dev); 35 struct snd_emux *emux; 36 struct snd_emu10k1 *hw; 37 struct snd_emu10k1_synth_arg *arg; 38 unsigned long flags; 39 40 arg = SNDRV_SEQ_DEVICE_ARGPTR(dev); 41 if (arg == NULL) 42 return -EINVAL; 43 44 if (arg->seq_ports <= 0) 45 return 0; /* nothing */ 46 if (arg->max_voices < 1) 47 arg->max_voices = 1; 48 else if (arg->max_voices > 64) 49 arg->max_voices = 64; 50 51 if (snd_emux_new(&emux) < 0) 52 return -ENOMEM; 53 54 snd_emu10k1_ops_setup(emux); 55 hw = arg->hwptr; 56 emux->hw = hw; 57 emux->max_voices = arg->max_voices; 58 emux->num_ports = arg->seq_ports; 59 emux->pitch_shift = -501; 60 emux->memhdr = hw->memhdr; 61 /* maximum two ports */ 62 emux->midi_ports = arg->seq_ports < 2 ? arg->seq_ports : 2; 63 /* audigy has two external midis */ 64 emux->midi_devidx = hw->audigy ? 2 : 1; 65 emux->linear_panning = 0; 66 emux->hwdep_idx = 2; /* FIXED */ 67 68 if (snd_emux_register(emux, dev->card, arg->index, "Emu10k1") < 0) { 69 snd_emux_free(emux); 70 return -ENOMEM; 71 } 72 73 spin_lock_irqsave(&hw->voice_lock, flags); 74 hw->synth = emux; 75 hw->get_synth_voice = snd_emu10k1_synth_get_voice; 76 spin_unlock_irqrestore(&hw->voice_lock, flags); 77 78 dev->driver_data = emux; 79 80 return 0; 81} 82 83static int snd_emu10k1_synth_remove(struct device *_dev) 84{ 85 struct snd_seq_device *dev = to_seq_dev(_dev); 86 struct snd_emux *emux; 87 struct snd_emu10k1 *hw; 88 unsigned long flags; 89 90 if (dev->driver_data == NULL) 91 return 0; /* not registered actually */ 92 93 emux = dev->driver_data; 94 95 hw = emux->hw; 96 spin_lock_irqsave(&hw->voice_lock, flags); 97 hw->synth = NULL; 98 hw->get_synth_voice = NULL; 99 spin_unlock_irqrestore(&hw->voice_lock, flags); 100 101 snd_emux_free(emux); 102 return 0; 103} 104 105/* 106 * INIT part 107 */ 108 109static struct snd_seq_driver emu10k1_synth_driver = { 110 .driver = { 111 .name = KBUILD_MODNAME, 112 .probe = snd_emu10k1_synth_probe, 113 .remove = snd_emu10k1_synth_remove, 114 }, 115 .id = SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH, 116 .argsize = sizeof(struct snd_emu10k1_synth_arg), 117}; 118 119module_snd_seq_driver(emu10k1_synth_driver); 120