1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz> 4 * and (c) 1999 Steve Ratcliffe <steve@parabola.demon.co.uk> 5 * Copyright (C) 1999-2000 Takashi Iwai <tiwai@suse.de> 6 * 7 * Emu8000 synth plug-in routine 8 */ 9 10 #include "emu8000_local.h" 11 #include <linux/init.h> 12 #include <linux/module.h> 13 #include <sound/initval.h> 14 15 MODULE_AUTHOR("Takashi Iwai, Steve Ratcliffe"); 16 MODULE_DESCRIPTION("Emu8000 synth plug-in routine"); 17 MODULE_LICENSE("GPL"); 18 19 /*----------------------------------------------------------------*/ 20 21 /* 22 * create a new hardware dependent device for Emu8000 23 */ 24 static int snd_emu8000_probe(struct device *_dev) 25 { 26 struct snd_seq_device *dev = to_seq_dev(_dev); 27 struct snd_emu8000 *hw; 28 struct snd_emux *emu; 29 30 hw = *(struct snd_emu8000**)SNDRV_SEQ_DEVICE_ARGPTR(dev); 31 if (hw == NULL) 32 return -EINVAL; 33 34 if (hw->emu) 35 return -EBUSY; /* already exists..? */ 36 37 if (snd_emux_new(&emu) < 0) 38 return -ENOMEM; 39 40 hw->emu = emu; 41 snd_emu8000_ops_setup(hw); 42 43 emu->hw = hw; 44 emu->max_voices = EMU8000_DRAM_VOICES; 45 emu->num_ports = hw->seq_ports; 46 47 if (hw->memhdr) { 48 snd_printk(KERN_ERR "memhdr is already initialized!?\n"); 49 snd_util_memhdr_free(hw->memhdr); 50 } 51 hw->memhdr = snd_util_memhdr_new(hw->mem_size); 52 if (hw->memhdr == NULL) { 53 snd_emux_free(emu); 54 hw->emu = NULL; 55 return -ENOMEM; 56 } 57 58 emu->memhdr = hw->memhdr; 59 emu->midi_ports = hw->seq_ports < 2 ? hw->seq_ports : 2; /* number of virmidi ports */ 60 emu->midi_devidx = 1; 61 emu->linear_panning = 1; 62 emu->hwdep_idx = 2; /* FIXED */ 63 64 if (snd_emux_register(emu, dev->card, hw->index, "Emu8000") < 0) { 65 snd_emux_free(emu); 66 snd_util_memhdr_free(hw->memhdr); 67 hw->emu = NULL; 68 hw->memhdr = NULL; 69 return -ENOMEM; 70 } 71 72 if (hw->mem_size > 0) 73 snd_emu8000_pcm_new(dev->card, hw, 1); 74 75 dev->driver_data = hw; 76 77 return 0; 78 } 79 80 81 /* 82 * free all resources 83 */ 84 static int snd_emu8000_remove(struct device *_dev) 85 { 86 struct snd_seq_device *dev = to_seq_dev(_dev); 87 struct snd_emu8000 *hw; 88 89 if (dev->driver_data == NULL) 90 return 0; /* no synth was allocated actually */ 91 92 hw = dev->driver_data; 93 if (hw->pcm) 94 snd_device_free(dev->card, hw->pcm); 95 snd_emux_free(hw->emu); 96 snd_util_memhdr_free(hw->memhdr); 97 hw->emu = NULL; 98 hw->memhdr = NULL; 99 return 0; 100 } 101 102 /* 103 * INIT part 104 */ 105 106 static struct snd_seq_driver emu8000_driver = { 107 .driver = { 108 .name = KBUILD_MODNAME, 109 .probe = snd_emu8000_probe, 110 .remove = snd_emu8000_remove, 111 }, 112 .id = SNDRV_SEQ_DEV_ID_EMU8000, 113 .argsize = sizeof(struct snd_emu8000 *), 114 }; 115 116 module_snd_seq_driver(emu8000_driver); 117