1 /* 2 * Copyright (c) by Jaroslav Kysela <perex@perex.cz> 3 * and (c) 1999 Steve Ratcliffe <steve@parabola.demon.co.uk> 4 * Copyright (C) 1999-2000 Takashi Iwai <tiwai@suse.de> 5 * 6 * Emu8000 synth plug-in routine 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 */ 22 23 #include "emu8000_local.h" 24 #include <linux/init.h> 25 #include <linux/module.h> 26 #include <sound/initval.h> 27 28 MODULE_AUTHOR("Takashi Iwai, Steve Ratcliffe"); 29 MODULE_DESCRIPTION("Emu8000 synth plug-in routine"); 30 MODULE_LICENSE("GPL"); 31 32 /*----------------------------------------------------------------*/ 33 34 /* 35 * create a new hardware dependent device for Emu8000 36 */ 37 static int snd_emu8000_new_device(struct snd_seq_device *dev) 38 { 39 struct snd_emu8000 *hw; 40 struct snd_emux *emu; 41 42 hw = *(struct snd_emu8000**)SNDRV_SEQ_DEVICE_ARGPTR(dev); 43 if (hw == NULL) 44 return -EINVAL; 45 46 if (hw->emu) 47 return -EBUSY; /* already exists..? */ 48 49 if (snd_emux_new(&emu) < 0) 50 return -ENOMEM; 51 52 hw->emu = emu; 53 snd_emu8000_ops_setup(hw); 54 55 emu->hw = hw; 56 emu->max_voices = EMU8000_DRAM_VOICES; 57 emu->num_ports = hw->seq_ports; 58 59 if (hw->memhdr) { 60 snd_printk(KERN_ERR "memhdr is already initialized!?\n"); 61 snd_util_memhdr_free(hw->memhdr); 62 } 63 hw->memhdr = snd_util_memhdr_new(hw->mem_size); 64 if (hw->memhdr == NULL) { 65 snd_emux_free(emu); 66 hw->emu = NULL; 67 return -ENOMEM; 68 } 69 70 emu->memhdr = hw->memhdr; 71 emu->midi_ports = hw->seq_ports < 2 ? hw->seq_ports : 2; /* number of virmidi ports */ 72 emu->midi_devidx = 1; 73 emu->linear_panning = 1; 74 emu->hwdep_idx = 2; /* FIXED */ 75 76 if (snd_emux_register(emu, dev->card, hw->index, "Emu8000") < 0) { 77 snd_emux_free(emu); 78 snd_util_memhdr_free(hw->memhdr); 79 hw->emu = NULL; 80 hw->memhdr = NULL; 81 return -ENOMEM; 82 } 83 84 if (hw->mem_size > 0) 85 snd_emu8000_pcm_new(dev->card, hw, 1); 86 87 dev->driver_data = hw; 88 89 return 0; 90 } 91 92 93 /* 94 * free all resources 95 */ 96 static int snd_emu8000_delete_device(struct snd_seq_device *dev) 97 { 98 struct snd_emu8000 *hw; 99 100 if (dev->driver_data == NULL) 101 return 0; /* no synth was allocated actually */ 102 103 hw = dev->driver_data; 104 if (hw->pcm) 105 snd_device_free(dev->card, hw->pcm); 106 if (hw->emu) 107 snd_emux_free(hw->emu); 108 if (hw->memhdr) 109 snd_util_memhdr_free(hw->memhdr); 110 hw->emu = NULL; 111 hw->memhdr = NULL; 112 return 0; 113 } 114 115 /* 116 * INIT part 117 */ 118 119 static int __init alsa_emu8000_init(void) 120 { 121 122 static struct snd_seq_dev_ops ops = { 123 snd_emu8000_new_device, 124 snd_emu8000_delete_device, 125 }; 126 return snd_seq_device_register_driver(SNDRV_SEQ_DEV_ID_EMU8000, &ops, 127 sizeof(struct snd_emu8000*)); 128 } 129 130 static void __exit alsa_emu8000_exit(void) 131 { 132 snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_EMU8000); 133 } 134 135 module_init(alsa_emu8000_init) 136 module_exit(alsa_emu8000_exit) 137