linux/sound/isa/sb/emu8000_synth.c
<<
>>
Prefs
   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
  28MODULE_AUTHOR("Takashi Iwai, Steve Ratcliffe");
  29MODULE_DESCRIPTION("Emu8000 synth plug-in routine");
  30MODULE_LICENSE("GPL");
  31
  32/*----------------------------------------------------------------*/
  33
  34/*
  35 * create a new hardware dependent device for Emu8000
  36 */
  37static 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 */
  96static 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
 119static 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
 130static void __exit alsa_emu8000_exit(void)
 131{
 132        snd_seq_device_unregister_driver(SNDRV_SEQ_DEV_ID_EMU8000);
 133}
 134
 135module_init(alsa_emu8000_init)
 136module_exit(alsa_emu8000_exit)
 137