Ejemplo n.º 1
0
/*
 * registration of the synth device
 */
int
snd_seq_oss_synth_register(struct snd_seq_device *dev)
{
	int i;
	struct seq_oss_synth *rec;
	struct snd_seq_oss_reg *reg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
	unsigned long flags;

	if ((rec = kzalloc(sizeof(*rec), GFP_KERNEL)) == NULL) {
		snd_printk(KERN_ERR "can't malloc synth info\n");
		return -ENOMEM;
	}
	rec->seq_device = -1;
	rec->synth_type = reg->type;
	rec->synth_subtype = reg->subtype;
	rec->nr_voices = reg->nvoices;
	rec->oper = reg->oper;
	rec->private_data = reg->private_data;
	rec->opened = 0;
	snd_use_lock_init(&rec->use_lock);

	/* copy and truncate the name of synth device */
	strlcpy(rec->name, dev->name, sizeof(rec->name));

	/* registration */
	spin_lock_irqsave(&register_lock, flags);
	for (i = 0; i < max_synth_devs; i++) {
		if (synth_devs[i] == NULL)
			break;
	}
	if (i >= max_synth_devs) {
		if (max_synth_devs >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS) {
			spin_unlock_irqrestore(&register_lock, flags);
			snd_printk(KERN_ERR "no more synth slot\n");
			kfree(rec);
			return -ENOMEM;
		}
		max_synth_devs++;
	}
	rec->seq_device = i;
	synth_devs[i] = rec;
#ifdef CONFIG_DEBUG_PRINTK
	debug_printk(("synth %s registered %d\n", rec->name, i));
#else
	debug_;
#endif
	spin_unlock_irqrestore(&register_lock, flags);
	dev->driver_data = rec;
#ifdef SNDRV_OSS_INFO_DEV_SYNTH
	if (i < SNDRV_CARDS)
		snd_oss_info_register(SNDRV_OSS_INFO_DEV_SYNTH, i, rec->name);
#endif
	return 0;
}
Ejemplo n.º 2
0
/*
 * create a new hardware dependent device for Emu8000
 */
static int snd_emu8000_new_device(struct snd_seq_device *dev)
{
	struct snd_emu8000 *hw;
	struct snd_emux *emu;

	hw = *(struct snd_emu8000**)SNDRV_SEQ_DEVICE_ARGPTR(dev);
	if (hw == NULL)
		return -EINVAL;

	if (hw->emu)
		return -EBUSY; /* already exists..? */

	if (snd_emux_new(&emu) < 0)
		return -ENOMEM;

	hw->emu = emu;
	snd_emu8000_ops_setup(hw);

	emu->hw = hw;
	emu->max_voices = EMU8000_DRAM_VOICES;
	emu->num_ports = hw->seq_ports;

	if (hw->memhdr) {
;
		snd_util_memhdr_free(hw->memhdr);
	}
	hw->memhdr = snd_util_memhdr_new(hw->mem_size);
	if (hw->memhdr == NULL) {
		snd_emux_free(emu);
		hw->emu = NULL;
		return -ENOMEM;
	}

	emu->memhdr = hw->memhdr;
	emu->midi_ports = hw->seq_ports < 2 ? hw->seq_ports : 2; /* number of virmidi ports */
	emu->midi_devidx = 1;
	emu->linear_panning = 1;
	emu->hwdep_idx = 2; /* FIXED */

	if (snd_emux_register(emu, dev->card, hw->index, "Emu8000") < 0) {
		snd_emux_free(emu);
		snd_util_memhdr_free(hw->memhdr);
		hw->emu = NULL;
		hw->memhdr = NULL;
		return -ENOMEM;
	}

	if (hw->mem_size > 0)
		snd_emu8000_pcm_new(dev->card, hw, 1);

	dev->driver_data = hw;

	return 0;
}
Ejemplo n.º 3
0
static int snd_opl4_create_seq_dev(struct snd_opl4 *opl4, int seq_device)
{
	opl4->seq_dev_num = seq_device;
	if (snd_seq_device_new(opl4->card, seq_device, SNDRV_SEQ_DEV_ID_OPL4,
			       sizeof(struct snd_opl4 *), &opl4->seq_dev) >= 0) {
		strcpy(opl4->seq_dev->name, "OPL4 Wavetable");
		*(struct snd_opl4 **)SNDRV_SEQ_DEVICE_ARGPTR(opl4->seq_dev) = opl4;
		opl4->seq_dev->private_data = opl4;
		opl4->seq_dev->private_free = snd_opl4_seq_dev_free;
	}
	return 0;
}
Ejemplo n.º 4
0
static int snd_opl3_seq_new_device(struct snd_seq_device *dev)
{
	struct snd_opl3 *opl3;
	int client, err;
	char name[32];
	int opl_ver;

	opl3 = *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
	if (opl3 == NULL)
		return -EINVAL;

	spin_lock_init(&opl3->voice_lock);

	opl3->seq_client = -1;

	/* allocate new client */
	opl_ver = (opl3->hardware & OPL3_HW_MASK) >> 8;
	sprintf(name, "OPL%i FM synth", opl_ver);
	client = opl3->seq_client =
		snd_seq_create_kernel_client(opl3->card, opl3->seq_dev_num,
					     name);
	if (client < 0)
		return client;

	if ((err = snd_opl3_synth_create_port(opl3)) < 0) {
		snd_seq_delete_kernel_client(client);
		opl3->seq_client = -1;
		return err;
	}

	/* initialize instrument list */
	opl3->ilist = snd_seq_instr_list_new();
	if (opl3->ilist == NULL) {
		snd_seq_delete_kernel_client(client);
		opl3->seq_client = -1;
		return -ENOMEM;
	}
	opl3->ilist->flags = SNDRV_SEQ_INSTR_FLG_DIRECT;
	snd_seq_fm_init(&opl3->fm_ops, NULL);

	/* setup system timer */
	init_timer(&opl3->tlist);
	opl3->tlist.function = snd_opl3_timer_func;
	opl3->tlist.data = (unsigned long) opl3;
	spin_lock_init(&opl3->sys_timer_lock);
	opl3->sys_timer_status = 0;

#ifdef CONFIG_SND_SEQUENCER_OSS
	snd_opl3_init_seq_oss(opl3, name);
#endif
	return 0;
}
Ejemplo n.º 5
0
static int snd_opl4_seq_delete_device(struct snd_seq_device *dev)
{
    struct snd_opl4 *opl4;

    opl4 = *(struct snd_opl4 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
    if (!opl4)
        return -EINVAL;

    if (opl4->seq_client >= 0) {
        snd_seq_delete_kernel_client(opl4->seq_client);
        opl4->seq_client = -1;
    }
    return 0;
}
Ejemplo n.º 6
0
/*
 * create a new hardware dependent device for Emu10k1
 */
static int snd_emu10k1_synth_new_device(struct snd_seq_device *dev)
{
	struct snd_emux *emux;
	struct snd_emu10k1 *hw;
	struct snd_emu10k1_synth_arg *arg;
	unsigned long flags;

	arg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
	if (arg == NULL)
		return -EINVAL;

	if (arg->seq_ports <= 0)
		return 0; /* nothing */
	if (arg->max_voices < 1)
		arg->max_voices = 1;
	else if (arg->max_voices > 64)
		arg->max_voices = 64;

	if (snd_emux_new(&emux) < 0)
		return -ENOMEM;

	snd_emu10k1_ops_setup(emux);
	hw = arg->hwptr;
	emux->hw = hw;
	emux->max_voices = arg->max_voices;
	emux->num_ports = arg->seq_ports;
	emux->pitch_shift = -501;
	emux->memhdr = hw->memhdr;
	/* maximum two ports */
	emux->midi_ports = arg->seq_ports < 2 ? arg->seq_ports : 2;
	/* audigy has two external midis */
	emux->midi_devidx = hw->audigy ? 2 : 1;
	emux->linear_panning = 0;
	emux->hwdep_idx = 2; /* FIXED */

	if (snd_emux_register(emux, dev->card, arg->index, "Emu10k1") < 0) {
		snd_emux_free(emux);
		return -ENOMEM;
	}

	spin_lock_irqsave(&hw->voice_lock, flags);
	hw->synth = emux;
	hw->get_synth_voice = snd_emu10k1_synth_get_voice;
	spin_unlock_irqrestore(&hw->voice_lock, flags);

	dev->driver_data = emux;

	return 0;
}
Ejemplo n.º 7
0
/*
 * registration of the synth device
 */
int
snd_seq_oss_synth_probe(struct device *_dev)
{
    struct snd_seq_device *dev = to_seq_dev(_dev);
    int i;
    struct seq_oss_synth *rec;
    struct snd_seq_oss_reg *reg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
    unsigned long flags;

    rec = kzalloc(sizeof(*rec), GFP_KERNEL);
    if (!rec)
        return -ENOMEM;
    rec->seq_device = -1;
    rec->synth_type = reg->type;
    rec->synth_subtype = reg->subtype;
    rec->nr_voices = reg->nvoices;
    rec->oper = reg->oper;
    rec->private_data = reg->private_data;
    rec->opened = 0;
    snd_use_lock_init(&rec->use_lock);

    /* copy and truncate the name of synth device */
    strlcpy(rec->name, dev->name, sizeof(rec->name));

    /* registration */
    spin_lock_irqsave(&register_lock, flags);
    for (i = 0; i < max_synth_devs; i++) {
        if (synth_devs[i] == NULL)
            break;
    }
    if (i >= max_synth_devs) {
        if (max_synth_devs >= SNDRV_SEQ_OSS_MAX_SYNTH_DEVS) {
            spin_unlock_irqrestore(&register_lock, flags);
            pr_err("ALSA: seq_oss: no more synth slot\n");
            kfree(rec);
            return -ENOMEM;
        }
        max_synth_devs++;
    }
    rec->seq_device = i;
    synth_devs[i] = rec;
    spin_unlock_irqrestore(&register_lock, flags);
    dev->driver_data = rec;
#ifdef SNDRV_OSS_INFO_DEV_SYNTH
    if (i < SNDRV_CARDS)
        snd_oss_info_register(SNDRV_OSS_INFO_DEV_SYNTH, i, rec->name);
#endif
    return 0;
}
Ejemplo n.º 8
0
static int snd_gus_synth_delete_device(snd_seq_device_t *dev)
{
    snd_gus_card_t *gus;

    gus = *(snd_gus_card_t**)SNDRV_SEQ_DEVICE_ARGPTR(dev);
    if (gus == NULL)
        return -EINVAL;

    if (gus->gf1.seq_client >= 0) {
        snd_seq_delete_kernel_client(gus->gf1.seq_client);
        gus->gf1.seq_client = -1;
    }
    if (gus->gf1.ilist)
        snd_seq_instr_list_free(&gus->gf1.ilist);
    return 0;
}
Ejemplo n.º 9
0
static int snd_opl3_seq_delete_device(struct snd_seq_device *dev)
{
    struct snd_opl3 *opl3;

    opl3 = *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
    if (opl3 == NULL)
        return -EINVAL;

#ifdef CONFIG_SND_SEQUENCER_OSS
    snd_opl3_free_seq_oss(opl3);
#endif
    if (opl3->seq_client >= 0) {
        snd_seq_delete_kernel_client(opl3->seq_client);
        opl3->seq_client = -1;
    }
    return 0;
}
Ejemplo n.º 10
0
static int snd_opl3_seq_probe(struct device *_dev)
{
	struct snd_seq_device *dev = to_seq_dev(_dev);
	struct snd_opl3 *opl3;
	int client, err;
	char name[32];
	int opl_ver;

	opl3 = *(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(dev);
	if (opl3 == NULL)
		return -EINVAL;

	spin_lock_init(&opl3->voice_lock);

	opl3->seq_client = -1;

	/* allocate new client */
	opl_ver = (opl3->hardware & OPL3_HW_MASK) >> 8;
	sprintf(name, "OPL%i FM synth", opl_ver);
	client = opl3->seq_client =
		snd_seq_create_kernel_client(opl3->card, opl3->seq_dev_num,
					     name);
	if (client < 0)
		return client;

	if ((err = snd_opl3_synth_create_port(opl3)) < 0) {
		snd_seq_delete_kernel_client(client);
		opl3->seq_client = -1;
		return err;
	}

	/* setup system timer */
	setup_timer(&opl3->tlist, snd_opl3_timer_func, (unsigned long) opl3);
	spin_lock_init(&opl3->sys_timer_lock);
	opl3->sys_timer_status = 0;

#if IS_ENABLED(CONFIG_SND_SEQUENCER_OSS)
	snd_opl3_init_seq_oss(opl3, name);
#endif
	return 0;
}
Ejemplo n.º 11
0
void
snd_emux_init_seq_oss(struct snd_emux *emu)
{
	struct snd_seq_oss_reg *arg;
	struct snd_seq_device *dev;

	if (snd_seq_device_new(emu->card, 0, SNDRV_SEQ_DEV_ID_OSS,
			       sizeof(struct snd_seq_oss_reg), &dev) < 0)
		return;

	emu->oss_synth = dev;
	strcpy(dev->name, emu->name);
	arg = SNDRV_SEQ_DEVICE_ARGPTR(dev);
	arg->type = SYNTH_TYPE_SAMPLE;
	arg->subtype = SAMPLE_TYPE_AWE32;
	arg->nvoices = emu->max_voices;
	arg->oper = oss_callback;
	arg->private_data = emu;

	/* register to OSS synth table */
	snd_device_register(emu->card, dev);
}
Ejemplo n.º 12
0
static int snd_card_emu10k1_probe(struct pci_dev *pci,
				  const struct pci_device_id *pci_id)
{
	static int dev;
	struct snd_card *card;
	struct snd_emu10k1 *emu;
#ifdef ENABLE_SYNTH
	struct snd_seq_device *wave = NULL;
#endif
	int err;

	if (dev >= SNDRV_CARDS)
        	return -ENODEV;
	if (!enable[dev]) {
		dev++;
		return -ENOENT;
	}

	err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card);
	if (err < 0)
		return err;
	if (max_buffer_size[dev] < 32)
		max_buffer_size[dev] = 32;
	else if (max_buffer_size[dev] > 1024)
		max_buffer_size[dev] = 1024;
	if ((err = snd_emu10k1_create(card, pci, extin[dev], extout[dev],
				      (long)max_buffer_size[dev] * 1024 * 1024,
				      enable_ir[dev], subsystem[dev],
				      &emu)) < 0)
		goto error;
	card->private_data = emu;
	emu->delay_pcm_irq = delay_pcm_irq[dev] & 0x1f;
	if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0)
		goto error;
	if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0)
		goto error;
	if ((err = snd_emu10k1_pcm_efx(emu, 2, NULL)) < 0)
		goto error;
	/* This stores the periods table. */
	if (emu->card_capabilities->ca0151_chip) { /* P16V */	
		if ((err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
					       1024, &emu->p16v_buffer)) < 0)
			goto error;
	}

	if ((err = snd_emu10k1_mixer(emu, 0, 3)) < 0)
		goto error;
	
	if ((err = snd_emu10k1_timer(emu, 0)) < 0)
		goto error;

	if ((err = snd_emu10k1_pcm_multi(emu, 3, NULL)) < 0)
		goto error;
	if (emu->card_capabilities->ca0151_chip) { /* P16V */
		if ((err = snd_p16v_pcm(emu, 4, NULL)) < 0)
			goto error;
	}
	if (emu->audigy) {
		if ((err = snd_emu10k1_audigy_midi(emu)) < 0)
			goto error;
	} else {
		if ((err = snd_emu10k1_midi(emu)) < 0)
			goto error;
	}
	if ((err = snd_emu10k1_fx8010_new(emu, 0, NULL)) < 0)
		goto error;
#ifdef ENABLE_SYNTH
	if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH,
			       sizeof(struct snd_emu10k1_synth_arg), &wave) < 0 ||
	    wave == NULL) {
		snd_printk(KERN_WARNING "can't initialize Emu10k1 wavetable synth\n");
	} else {
		struct snd_emu10k1_synth_arg *arg;
		arg = SNDRV_SEQ_DEVICE_ARGPTR(wave);
		strcpy(wave->name, "Emu-10k1 Synth");
		arg->hwptr = emu;
		arg->index = 1;
		arg->seq_ports = seq_ports[dev];
		arg->max_voices = max_synth_voices[dev];
	}
#endif
 
	strlcpy(card->driver, emu->card_capabilities->driver,
		sizeof(card->driver));
	strlcpy(card->shortname, emu->card_capabilities->name,
		sizeof(card->shortname));
	snprintf(card->longname, sizeof(card->longname),
		 "%s (rev.%d, serial:0x%x) at 0x%lx, irq %i",
		 card->shortname, emu->revision, emu->serial, emu->port, emu->irq);

	if ((err = snd_card_register(card)) < 0)
		goto error;

	pci_set_drvdata(pci, card);
	dev++;
	return 0;

 error:
	snd_card_free(card);
	return err;
}
Ejemplo n.º 13
0
// constructor -- see "Constructor" sub-section
static int __devinit
snd_vortex_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
{
	static int dev;
	snd_card_t *card;
	vortex_t *chip;
	int err;

	// (1)
	if (dev >= SNDRV_CARDS)
		return -ENODEV;
	if (!enable[dev]) {
		dev++;
		return -ENOENT;
	}
	// (2)
	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
	if (card == NULL)
		return -ENOMEM;

	// (3)
	if ((err = snd_vortex_create(card, pci, &chip)) < 0) {
		snd_card_free(card);
		return err;
	}
	snd_vortex_workaround(pci, pcifix[dev]);
	// (4) Alloc components.
	// ADB pcm.
	if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_ADB, NR_ADB)) < 0) {
		snd_card_free(card);
		return err;
	}
#ifndef CHIP_AU8820
	// ADB SPDIF
	if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_SPDIF, 1)) < 0) {
		snd_card_free(card);
		return err;
	}
	// A3D
	if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_A3D, NR_A3D)) < 0) {
		snd_card_free(card);
		return err;
	}
#endif
	/*
	   // ADB I2S
	   if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_I2S, 1)) < 0) {
	   snd_card_free(card);
	   return err;
	   }
	 */
#ifndef CHIP_AU8810
	// WT pcm.
	if ((err = snd_vortex_new_pcm(chip, VORTEX_PCM_WT, NR_WT)) < 0) {
		snd_card_free(card);
		return err;
	}
#endif
	// snd_ac97_mixer and Vortex mixer.
	if ((err = snd_vortex_mixer(chip)) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = snd_vortex_midi(chip)) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = vortex_gameport_register(chip)) < 0) {
		snd_card_free(card);
		return err;
	}
#if 0
	if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_VORTEX_SYNTH,
			       sizeof(snd_vortex_synth_arg_t), &wave) < 0
	    || wave == NULL) {
		snd_printk("Can't initialize Aureal wavetable synth\n");
	} else {
		snd_vortex_synth_arg_t *arg;

		arg = SNDRV_SEQ_DEVICE_ARGPTR(wave);
		strcpy(wave->name, "Aureal Synth");
		arg->hwptr = vortex;
		arg->index = 1;
		arg->seq_ports = seq_ports[dev];
		arg->max_voices = max_synth_voices[dev];
	}
#endif

	// (5)
	strcpy(card->driver, CARD_NAME_SHORT);
	strcpy(card->shortname, CARD_NAME_SHORT);
	sprintf(card->longname, "%s at 0x%lx irq %i",
		card->shortname, chip->io, chip->irq);

	if ((err = pci_read_config_word(pci, PCI_DEVICE_ID,
				  &(chip->device))) < 0) {
		snd_card_free(card);
		return err;
	}	
	if ((err = pci_read_config_word(pci, PCI_VENDOR_ID,
				  &(chip->vendor))) < 0) {
		snd_card_free(card);
		return err;
	}
	if ((err = pci_read_config_byte(pci, PCI_REVISION_ID,
				  &(chip->rev))) < 0) {
		snd_card_free(card);
		return err;
	}
#ifdef CHIP_AU8830
	if ((chip->rev) != 0xfe && (chip->rev) != 0xfa) {
		printk(KERN_ALERT
		       "vortex: The revision (%x) of your card has not been seen before.\n",
		       chip->rev);
		printk(KERN_ALERT
		       "vortex: Please email the results of 'lspci -vv' to [email protected].\n");
		snd_card_free(card);
		err = -ENODEV;
		return err;
	}
#endif

	// (6)
	if ((err = snd_card_register(card)) < 0) {
		snd_card_free(card);
		return err;
	}
	// (7)
	pci_set_drvdata(pci, card);
	dev++;
	vortex_connect_default(chip, 1);
	vortex_enable_int(chip);
	return 0;
}
Ejemplo n.º 14
0
static int __devinit snd_card_emu10k1_probe(struct pci_dev *pci,
					    const struct pci_device_id *pci_id)
{
	static int dev;
	snd_card_t *card;
	emu10k1_t *emu;
#ifdef ENABLE_SYNTH
	snd_seq_device_t *wave = NULL;
#endif
	int err;

	if (dev >= SNDRV_CARDS)
        	return -ENODEV;
	if (!enable[dev]) {
		dev++;
		return -ENOENT;
	}

	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
	if (card == NULL)
		return -ENOMEM;
	if (max_buffer_size[dev] < 32)
		max_buffer_size[dev] = 32;
	else if (max_buffer_size[dev] > 1024)
		max_buffer_size[dev] = 1024;
	if ((err = snd_emu10k1_create(card, pci, extin[dev], extout[dev],
				      (long)max_buffer_size[dev] * 1024 * 1024,
				      enable_ir[dev],
				      &emu)) < 0) {
		snd_card_free(card);
		return err;
	}		
	if ((err = snd_emu10k1_pcm(emu, 0, NULL)) < 0) {
		snd_card_free(card);
		return err;
	}		
	if ((err = snd_emu10k1_pcm_mic(emu, 1, NULL)) < 0) {
		snd_card_free(card);
		return err;
	}		
	if ((err = snd_emu10k1_pcm_efx(emu, 2, NULL)) < 0) {
		snd_card_free(card);
		return err;
	}		
	if ((err = snd_emu10k1_mixer(emu)) < 0) {
		snd_card_free(card);
		return err;
	}
	
	if ((err = snd_emu10k1_timer(emu, 0)) < 0) {
		snd_card_free(card);
		return err;
	}

	if (emu->audigy) {
		if ((err = snd_emu10k1_audigy_midi(emu)) < 0) {
			snd_card_free(card);
			return err;
		}
	} else {
		if ((err = snd_emu10k1_midi(emu)) < 0) {
			snd_card_free(card);
			return err;
		}
	}
	if ((err = snd_emu10k1_fx8010_new(emu, 0, NULL)) < 0) {
		snd_card_free(card);
		return err;
	}
#ifdef ENABLE_SYNTH
	if (snd_seq_device_new(card, 1, SNDRV_SEQ_DEV_ID_EMU10K1_SYNTH,
			       sizeof(snd_emu10k1_synth_arg_t), &wave) < 0 ||
	    wave == NULL) {
		snd_printk("can't initialize Emu10k1 wavetable synth\n");
	} else {
		snd_emu10k1_synth_arg_t *arg;
		arg = SNDRV_SEQ_DEVICE_ARGPTR(wave);
		strcpy(wave->name, "Emu-10k1 Synth");
		arg->hwptr = emu;
		arg->index = 1;
		arg->seq_ports = seq_ports[dev];
		arg->max_voices = max_synth_voices[dev];
	}
#endif
 
	if (emu->audigy && (emu->serial == 0x10011102) ) {
		strcpy(card->driver, "Audigy2");
		strcpy(card->shortname, "Sound Blaster Audigy2_Value");
	} else if (emu->audigy && (emu->revision == 4) ) {
		strcpy(card->driver, "Audigy2");
		strcpy(card->shortname, "Sound Blaster Audigy2");
	} else if (emu->audigy) {
		strcpy(card->driver, "Audigy");
		strcpy(card->shortname, "Sound Blaster Audigy");
	} else if (emu->APS) {
		strcpy(card->driver, "E-mu APS");
		strcpy(card->shortname, "E-mu APS");
	} else {
		strcpy(card->driver, "EMU10K1");
		strcpy(card->shortname, "Sound Blaster Live!");
	}
	sprintf(card->longname, "%s (rev.%d, serial:0x%x) at 0x%lx, irq %i", card->shortname, emu->revision, emu->serial, emu->port, emu->irq);

	if ((err = snd_card_register(card)) < 0) {
		snd_card_free(card);
		return err;
	}
	pci_set_drvdata(pci, card);
	dev++;
	return 0;
}
Ejemplo n.º 15
0
static int snd_gus_synth_new_device(snd_seq_device_t *dev)
{
    snd_gus_card_t *gus;
    int client, i;
    snd_seq_client_callback_t callbacks;
    snd_seq_client_info_t *cinfo;
    snd_seq_port_subscribe_t sub;
    snd_iwffff_ops_t *iwops;
    snd_gf1_ops_t *gf1ops;
    snd_simple_ops_t *simpleops;

    gus = *(snd_gus_card_t**)SNDRV_SEQ_DEVICE_ARGPTR(dev);
    if (gus == NULL)
        return -EINVAL;

    init_MUTEX(&gus->register_mutex);
    gus->gf1.seq_client = -1;

    cinfo = kmalloc(sizeof(*cinfo), GFP_KERNEL);
    if (! cinfo)
        return -ENOMEM;

    /* allocate new client */
    memset(&callbacks, 0, sizeof(callbacks));
    callbacks.private_data = gus;
    callbacks.allow_output = callbacks.allow_input = 1;
    client = gus->gf1.seq_client =
                 snd_seq_create_kernel_client(gus->card, 1, &callbacks);
    if (client < 0) {
        kfree(cinfo);
        return client;
    }

    /* change name of client */
    memset(cinfo, 0, sizeof(*cinfo));
    cinfo->client = client;
    cinfo->type = KERNEL_CLIENT;
    sprintf(cinfo->name, gus->interwave ? "AMD InterWave" : "GF1");
    snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SET_CLIENT_INFO, cinfo);
    kfree(cinfo);

    for (i = 0; i < 4; i++)
        snd_gus_synth_create_port(gus, i);

    gus->gf1.ilist = snd_seq_instr_list_new();
    if (gus->gf1.ilist == NULL) {
        snd_seq_delete_kernel_client(client);
        gus->gf1.seq_client = -1;
        return -ENOMEM;
    }
    gus->gf1.ilist->flags = SNDRV_SEQ_INSTR_FLG_DIRECT;

    simpleops = &gus->gf1.simple_ops;
    snd_seq_simple_init(simpleops, gus, NULL);
    simpleops->put_sample = snd_gus_simple_put_sample;
    simpleops->get_sample = snd_gus_simple_get_sample;
    simpleops->remove_sample = snd_gus_simple_remove_sample;
    simpleops->notify = snd_gus_synth_instr_notify;

    gf1ops = &gus->gf1.gf1_ops;
    snd_seq_gf1_init(gf1ops, gus, &simpleops->kops);
    gf1ops->put_sample = snd_gus_gf1_put_sample;
    gf1ops->get_sample = snd_gus_gf1_get_sample;
    gf1ops->remove_sample = snd_gus_gf1_remove_sample;
    gf1ops->notify = snd_gus_synth_instr_notify;

    iwops = &gus->gf1.iwffff_ops;
    snd_seq_iwffff_init(iwops, gus, &gf1ops->kops);
    iwops->put_sample = snd_gus_iwffff_put_sample;
    iwops->get_sample = snd_gus_iwffff_get_sample;
    iwops->remove_sample = snd_gus_iwffff_remove_sample;
    iwops->notify = snd_gus_synth_instr_notify;

    memset(&sub, 0, sizeof(sub));
    sub.sender.client = SNDRV_SEQ_CLIENT_SYSTEM;
    sub.sender.port = SNDRV_SEQ_PORT_SYSTEM_ANNOUNCE;
    sub.dest.client = client;
    sub.dest.port = 0;
    snd_seq_kernel_client_ctl(client, SNDRV_SEQ_IOCTL_SUBSCRIBE_PORT, &sub);

    return 0;
}