Esempio n. 1
0
int snd_opl3_create(struct snd_card *card,
		    unsigned long l_port,
		    unsigned long r_port,
		    unsigned short hardware,
		    int integrated,
		    struct snd_opl3 ** ropl3)
{
	struct snd_opl3 *opl3;
	int err;

	*ropl3 = NULL;
	if ((err = snd_opl3_new(card, hardware, &opl3)) < 0)
		return err;
	if (! integrated) {
		if ((opl3->res_l_port = request_region(l_port, 2, "OPL2/3 (left)")) == NULL) {
			snd_mprintk(KERN_ERR "opl3: can't grab left port 0x%lx\n", l_port); // MJR
			snd_device_free(card, opl3);
			return -EBUSY;
		}
		if (r_port != 0 &&
		    (opl3->res_r_port = request_region(r_port, 2, "OPL2/3 (right)")) == NULL) {
			snd_mprintk(KERN_ERR "opl3: can't grab right port 0x%lx\n", r_port); // MJR
			snd_device_free(card, opl3);
			return -EBUSY;
		}
	}
	opl3->l_port = l_port;
	opl3->r_port = r_port;

	switch (opl3->hardware) {
	/* some hardware doesn't support timers */
	case OPL3_HW_OPL3_SV:
	case OPL3_HW_OPL3_CS:
	case OPL3_HW_OPL3_FM801:
		opl3->command = &snd_opl3_command;
		break;
	default:
		opl3->command = &snd_opl2_command;
		if ((err = snd_opl3_detect(opl3)) < 0) {
			snd_printd("OPL2/3 chip not detected at 0x%lx/0x%lx\n",
				   opl3->l_port, opl3->r_port);
			snd_device_free(card, opl3);
			return err;
		}
		/* detect routine returns correct hardware type */
		switch (opl3->hardware & OPL3_HW_MASK) {
		case OPL3_HW_OPL3:
		case OPL3_HW_OPL4:
			opl3->command = &snd_opl3_command;
		}
	}

	snd_opl3_init(opl3);

	*ropl3 = opl3;
	return 0;
}
Esempio n. 2
0
void snd_gf1_timers_done(snd_gus_card_t * gus)
{
	snd_gf1_set_default_handlers(gus, SNDRV_GF1_HANDLER_TIMER1 | SNDRV_GF1_HANDLER_TIMER2);
	if (gus->gf1.timer1) {
		snd_device_free(gus->card, gus->gf1.timer1);
		gus->gf1.timer1 = NULL;
	}
	if (gus->gf1.timer2) {
		snd_device_free(gus->card, gus->gf1.timer2);
		gus->gf1.timer2 = NULL;
	}
}
Esempio n. 3
0
static int snd_gus_free(struct snd_gus_card *gus)
{
	if (gus->gf1.res_port2 == NULL)
		goto __hw_end;
#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
	if (gus->seq_dev) {
		snd_device_free(gus->card, gus->seq_dev);
		gus->seq_dev = NULL;
	}
#endif
	snd_gf1_stop(gus);
	snd_gus_init_dma_irq(gus, 0);
      __hw_end:
	release_and_free_resource(gus->gf1.res_port1);
	release_and_free_resource(gus->gf1.res_port2);
	if (gus->gf1.irq >= 0)
		free_irq(gus->gf1.irq, (void *) gus);
	if (gus->gf1.dma1 >= 0) {
		disable_dma(gus->gf1.dma1);
		free_dma(gus->gf1.dma1);
	}
	if (!gus->equal_dma && gus->gf1.dma2 >= 0) {
		disable_dma(gus->gf1.dma2);
		free_dma(gus->gf1.dma2);
	}
	kfree(gus);
	return 0;
}
Esempio n. 4
0
void snd_pcm_timer_init(struct snd_pcm_substream *substream)
{
    struct snd_timer_id tid;
    struct snd_timer *timer;
    
    tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE;
    tid.dev_class = SNDRV_TIMER_CLASS_PCM;
    tid.card = substream->pcm->card->number;
    tid.device = substream->pcm->device;
    tid.subdevice = (substream->number << 1) | (substream->stream & 1);
    if (snd_timer_new(substream->pcm->card, "PCM", &tid, &timer) < 0)
        return;
    sprintf(timer->name, "PCM %s %i-%i-%i",
            substream->stream == SNDRV_PCM_STREAM_CAPTURE ?
                "capture" : "playback",
            tid.card, tid.device, tid.subdevice);
    timer->hw = snd_pcm_timer;
    if (snd_device_register(timer->card, timer) < 0) {
        snd_device_free(timer->card, timer);
        return;
    }
    timer->private_data = substream;
    timer->private_free = snd_pcm_timer_free;
    substream->timer = timer;
}
Esempio n. 5
0
int snd_msndmidi_new(struct snd_card *card, int device)
{
	struct snd_msnd *chip = card->private_data;
	struct snd_msndmidi *mpu;
	struct snd_rawmidi *rmidi;
	int err;

	err = snd_rawmidi_new(card, "MSND-MIDI", device, 1, 1, &rmidi);
	if (err < 0)
		return err;
	mpu = kzalloc(sizeof(*mpu), GFP_KERNEL);
	if (mpu == NULL) {
		snd_device_free(card, rmidi);
		return -ENOMEM;
	}
	mpu->dev = chip;
	chip->msndmidi_mpu = mpu;
	rmidi->private_data = mpu;
	rmidi->private_free = snd_msndmidi_free;
	spin_lock_init(&mpu->input_lock);
	strcpy(rmidi->name, "MSND MIDI");
	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
			    &snd_msndmidi_input);
	rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
	return 0;
}
Esempio n. 6
0
void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
{
	if (!codec->bus->shutdown && eld->proc_entry) {
		snd_device_free(codec->bus->card, eld->proc_entry);
		eld->proc_entry = NULL;
	}
}
Esempio n. 7
0
int snd_opl3_hwdep_new(struct snd_opl3 * opl3,
		       int device, int seq_device,
		       struct snd_hwdep ** rhwdep)
{
	struct snd_hwdep *hw;
	struct snd_card *card = opl3->card;
	int err;

	if (rhwdep)
		*rhwdep = NULL;

	/* create hardware dependent device (direct FM) */

	if ((err = snd_hwdep_new(card, "OPL2/OPL3", device, &hw)) < 0) {
		snd_device_free(card, opl3);
		return err;
	}
	hw->private_data = opl3;
	hw->exclusive = 1;
#ifdef CONFIG_SND_OSSEMUL
	if (device == 0) {
		hw->oss_type = SNDRV_OSS_DEVICE_TYPE_DMFM;
		sprintf(hw->oss_dev, "dmfm%i", card->number);
	}
#endif
	strcpy(hw->name, hw->id);
	switch (opl3->hardware & OPL3_HW_MASK) {
	case OPL3_HW_OPL2:
		strcpy(hw->name, "OPL2 FM");
		hw->iface = SNDRV_HWDEP_IFACE_OPL2;
		break;
	case OPL3_HW_OPL3:
		strcpy(hw->name, "OPL3 FM");
		hw->iface = SNDRV_HWDEP_IFACE_OPL3;
		break;
	case OPL3_HW_OPL4:
		strcpy(hw->name, "OPL4 FM");
		hw->iface = SNDRV_HWDEP_IFACE_OPL4;
		break;
	}

	/* operators - only ioctl */
	hw->ops.open = snd_opl3_open;
	hw->ops.ioctl = snd_opl3_ioctl;
	hw->ops.write = snd_opl3_write;
	hw->ops.release = snd_opl3_release;

	opl3->hwdep = hw;
	opl3->seq_dev_num = seq_device;
#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
	if (snd_seq_device_new(card, seq_device, SNDRV_SEQ_DEV_ID_OPL3,
			       sizeof(struct snd_opl3 *), &opl3->seq_dev) >= 0) {
		strcpy(opl3->seq_dev->name, hw->name);
		*(struct snd_opl3 **)SNDRV_SEQ_DEVICE_ARGPTR(opl3->seq_dev) = opl3;
	}
#endif
	if (rhwdep)
		*rhwdep = hw;
	return 0;
}
Esempio n. 8
0
void snd_pcm_timer_done(struct snd_pcm_substream *substream)
{
    if (substream->timer) {
        snd_device_free(substream->pcm->card, substream->timer);
        substream->timer = NULL;
    }
}
/*
 * unregister
 */
void
snd_emux_detach_seq_oss(struct snd_emux *emu)
{
	if (emu->oss_synth) {
		snd_device_free(emu->card, emu->oss_synth);
		emu->oss_synth = NULL;
	}
}
Esempio n. 10
0
/*
 * unregister
 */
void
snd_emux_delete_hwdep(struct snd_emux *emu)
{
	if (emu->hwdep) {
		snd_device_free(emu->card, emu->hwdep);
		emu->hwdep = NULL;
	}
}
Esempio n. 11
0
/* component-destructor
 * (see "Management of Cards and Components")
 */
static int snd_bcm2835_dev_free(struct snd_device *device)
{
	struct bcm2835_chip *chip = device->device_data;
	struct snd_card *card = chip->card;

	/* TODO: free pcm, ctl */

	snd_device_free(card, chip);

	return 0;
}
Esempio n. 12
0
int snd_emux_delete_virmidi(snd_emux_t *emu)
{
	int i;

	if (emu->vmidi == NULL)
		return 0;

	for (i = 0; i < emu->midi_ports; i++) {
		if (emu->vmidi[i])
			snd_device_free(emu->card, emu->vmidi[i]);
	}
	kfree(emu->vmidi);
	emu->vmidi = NULL;
	return 0;
}
Esempio n. 13
0
void snd_hda_jack_tbl_clear(struct hda_codec *codec)
{
#ifdef CONFIG_SND_HDA_INPUT_JACK
	/* free jack instances manually when clearing/reconfiguring */
	if (!codec->bus->shutdown && codec->jacktbl.list) {
		struct hda_jack_tbl *jack = codec->jacktbl.list;
		int i;
		for (i = 0; i < codec->jacktbl.used; i++, jack++) {
			if (jack->jack)
				snd_device_free(codec->bus->card, jack->jack);
		}
	}
#endif
	snd_array_free(&codec->jacktbl);
}
Esempio n. 14
0
int snd_opl3_timer_new(struct snd_opl3 * opl3, int timer1_dev, int timer2_dev)
{
	int err;

	if (timer1_dev >= 0)
		if ((err = snd_opl3_timer1_init(opl3, timer1_dev)) < 0)
			return err;
	if (timer2_dev >= 0) {
		if ((err = snd_opl3_timer2_init(opl3, timer2_dev)) < 0) {
			snd_device_free(opl3->card, opl3->timer1);
			opl3->timer1 = NULL;
			return err;
		}
	}
	return 0;
}
Esempio n. 15
0
/*
 * free all resources
 */
static int snd_emu8000_delete_device(struct snd_seq_device *dev)
{
	struct snd_emu8000 *hw;

	if (dev->driver_data == NULL)
		return 0; /* no synth was allocated actually */

	hw = dev->driver_data;
	if (hw->pcm)
		snd_device_free(dev->card, hw->pcm);
	if (hw->emu)
		snd_emux_free(hw->emu);
	if (hw->memhdr)
		snd_util_memhdr_free(hw->memhdr);
	hw->emu = NULL;
	hw->memhdr = NULL;
	return 0;
}
Esempio n. 16
0
void snd_hda_jack_tbl_clear(struct hda_codec *codec)
{
	struct hda_jack_tbl *jack = codec->jacktbl.list;
	int i;

	for (i = 0; i < codec->jacktbl.used; i++, jack++) {
		struct hda_jack_callback *cb, *next;
#ifdef CONFIG_SND_HDA_INPUT_JACK
		/* free jack instances manually when clearing/reconfiguring */
		if (!codec->bus->shutdown && jack->jack)
			snd_device_free(codec->bus->card, jack->jack);
#endif
		for (cb = jack->callback; cb; cb = next) {
			next = cb->next;
			kfree(cb);
		}
	}
	snd_array_free(&codec->jacktbl);
}
Esempio n. 17
0
int aoa_snd_device_new(snd_device_type_t type,
		       void * device_data, struct snd_device_ops * ops)
{
	struct snd_card *card = aoa_get_card();
	int err;

	if (!card) return -ENOMEM;

	err = snd_device_new(card, type, device_data, ops);
	if (err) {
		printk(KERN_ERR "snd-aoa: failed to create snd device (%d)\n", err);
		return err;
	}
	err = snd_device_register(card, device_data);
	if (err) {
		printk(KERN_ERR "snd-aoa: failed to register "
				"snd device (%d)\n", err);
		printk(KERN_ERR "snd-aoa: have you forgotten the "
				"dev_register callback?\n");
		snd_device_free(card, device_data);
	}
	return err;
}
Esempio n. 18
0
int aoa_snd_device_new(snd_device_type_t type,
		       void * device_data, struct snd_device_ops * ops)
{
	struct snd_card *card = aoa_get_card();
	int err;

	if (!card) return -ENOMEM;

	err = snd_device_new(card, type, device_data, ops);
	if (err) {
;
		return err;
	}
	err = snd_device_register(card, device_data);
	if (err) {
//		printk(KERN_ERR "snd-aoa: failed to register "
;
//		printk(KERN_ERR "snd-aoa: have you forgotten the "
;
		snd_device_free(card, device_data);
	}
	return err;
}
Esempio n. 19
0
/*
 * attach virtual rawmidi devices
 */
int snd_emux_init_virmidi(snd_emux_t *emu, snd_card_t *card)
{
	int i;

	emu->vmidi = NULL;
	if (emu->midi_ports <= 0)
		return 0;

	emu->vmidi = kcalloc(emu->midi_ports, sizeof(snd_rawmidi_t*), GFP_KERNEL);
	if (emu->vmidi == NULL)
		return -ENOMEM;

	for (i = 0; i < emu->midi_ports; i++) {
		snd_rawmidi_t *rmidi;
		snd_virmidi_dev_t *rdev;
		if (snd_virmidi_new(card, emu->midi_devidx + i, &rmidi) < 0)
			goto __error;
		rdev = rmidi->private_data;
		sprintf(rmidi->name, "%s Synth MIDI", emu->name);
		rdev->seq_mode = SNDRV_VIRMIDI_SEQ_ATTACH;
		rdev->client = emu->client;
		rdev->port = emu->ports[i];
		if (snd_device_register(card, rmidi) < 0) {
			snd_device_free(card, rmidi);
			goto __error;
		}
		emu->vmidi[i] = rmidi;
		//snd_printk("virmidi %d ok\n", i);
	}
	return 0;

__error:
	//snd_printk("error init..\n");
	snd_emux_delete_virmidi(emu);
	return -ENOMEM;
}
Esempio n. 20
0
static int snd_i2c_bus_free(struct snd_i2c_bus *bus)
{
	struct snd_i2c_bus *slave;
	struct snd_i2c_device *device;

	if (snd_BUG_ON(!bus))
		return -EINVAL;
	while (!list_empty(&bus->devices)) {
		device = snd_i2c_device(bus->devices.next);
		snd_i2c_device_free(device);
	}
	if (bus->master)
		list_del(&bus->buses);
	else {
		while (!list_empty(&bus->buses)) {
			slave = snd_i2c_slave_bus(bus->buses.next);
			snd_device_free(bus->card, slave);
		}
	}
	if (bus->private_free)
		bus->private_free(bus);
	kfree(bus);
	return 0;
}
/*
 * snd_compress_free: free compress device
 * @card: sound card pointer
 * @compr: compress device pointer
 */
void snd_compress_free(struct snd_card *card, struct snd_compr *compr)
{
	snd_device_free(card, compr);
}
Esempio n. 22
0
static int snd_stm_pcm_player_probe(struct platform_device *pdev)
{
	int result = 0;
	struct snd_stm_pcm_player *pcm_player;
	struct snd_card *card = snd_stm_card_get();
	int i;

	snd_stm_printd(0, "%s('%s')\n", __func__, dev_name(&pdev->dev));

	BUG_ON(!card);

	pcm_player = kzalloc(sizeof(*pcm_player), GFP_KERNEL);
	if (!pcm_player) {
		snd_stm_printe("Can't allocate memory "
				"for a device description!\n");
		result = -ENOMEM;
		goto error_alloc;
	}
	snd_stm_magic_set(pcm_player);
	pcm_player->info = pdev->dev.platform_data;
	BUG_ON(!pcm_player->info);
	pcm_player->ver = pcm_player->info->ver;
	BUG_ON(pcm_player->ver <= 0);
	pcm_player->device = &pdev->dev;

	/* Get resources */

	result = snd_stm_memory_request(pdev, &pcm_player->mem_region,
			&pcm_player->base);
	if (result < 0) {
		snd_stm_printe("Memory region request failed!\n");
		goto error_memory_request;
	}
	pcm_player->fifo_phys_address = pcm_player->mem_region->start +
		offset__AUD_PCMOUT_DATA(pcm_player);
	snd_stm_printd(0, "FIFO physical address: 0x%lx.\n",
			pcm_player->fifo_phys_address);

	result = snd_stm_irq_request(pdev, &pcm_player->irq,
			snd_stm_pcm_player_irq_handler, pcm_player);
	if (result < 0) {
		snd_stm_printe("IRQ request failed!\n");
		goto error_irq_request;
	}

	result = snd_stm_fdma_request(pdev, &pcm_player->fdma_channel);
	if (result < 0) {
		snd_stm_printe("FDMA request failed!\n");
		goto error_fdma_request;
	}

	/* FDMA transfer size depends (among others ;-) on FIFO length,
	 * which is:
	 * - 30 cells (120 bytes) in STx7100/9 and STx7200 cut 1.0
	 * - 70 cells (280 bytes) in STx7111 and STx7200 cut 2.0. */

	if (pcm_player->ver < 5)
		pcm_player->fdma_max_transfer_size = 2;
	else if (pcm_player->ver == 5)
		pcm_player->fdma_max_transfer_size = 20;
	else
		pcm_player->fdma_max_transfer_size = 30;

	/* Get player capabilities */

	snd_stm_printd(0, "Player's name is '%s'\n", pcm_player->info->name);

	BUG_ON(pcm_player->info->channels <= 0);
	BUG_ON(pcm_player->info->channels > 10);
	BUG_ON(pcm_player->info->channels % 2 != 0);
	if (pcm_player->ver > 1) {
		static unsigned int channels_2_10[] = { 2, 4, 6, 8, 10 };

		pcm_player->channels_constraint.list = channels_2_10;
		pcm_player->channels_constraint.count =
			pcm_player->info->channels / 2;
	} else {
		/* In STx7100 cut < 3.0 PCM player ignored NUM_CH setting in
		 * AUD_PCMOUT_FMT register (and it was always in 10 channels
		 * mode...) */
		static unsigned int channels_10[] = { 10 };

		pcm_player->channels_constraint.list = channels_10;
		pcm_player->channels_constraint.count = 1;
	}
	pcm_player->channels_constraint.mask = 0;
	for (i = 0; i < pcm_player->channels_constraint.count; i++)
		snd_stm_printd(0, "Player capable of playing %u-channels PCM."
				"\n", pcm_player->channels_constraint.list[i]);

	/* STx7100 has a problem with 16/16 bits FIFO organization,
	 * so we disable the 16 bits samples capability... */
	if (pcm_player->ver <= 2)
		snd_stm_pcm_player_hw.formats &= ~SNDRV_PCM_FMTBIT_S16_LE;

	/* Create ALSA lowlevel device */

	result = snd_device_new(card, SNDRV_DEV_LOWLEVEL, pcm_player,
			&snd_stm_pcm_player_snd_device_ops);
	if (result < 0) {
		snd_stm_printe("ALSA low level device creation failed!\n");
		goto error_device;
	}

	/* Create ALSA PCM device */

	result = snd_pcm_new(card, NULL, pcm_player->info->card_device, 1, 0,
			&pcm_player->pcm);
	if (result < 0) {
		snd_stm_printe("ALSA PCM instance creation failed!\n");
		goto error_pcm;
	}
	pcm_player->pcm->private_data = pcm_player;
	strcpy(pcm_player->pcm->name, pcm_player->info->name);

	snd_pcm_set_ops(pcm_player->pcm, SNDRV_PCM_STREAM_PLAYBACK,
			&snd_stm_pcm_player_pcm_ops);

	/* Initialize buffer */

	pcm_player->buffer = snd_stm_buffer_create(pcm_player->pcm,
			pcm_player->device,
			snd_stm_pcm_player_hw.buffer_bytes_max);
	if (!pcm_player->buffer) {
		snd_stm_printe("Cannot initialize buffer!\n");
		result = -ENOMEM;
		goto error_buffer_init;
	}

	/* Register in converters router */

	pcm_player->conv_source = snd_stm_conv_register_source(
		&platform_bus_type, dev_name(&pdev->dev),
			pcm_player->info->channels,
			card, pcm_player->info->card_device);
	if (!pcm_player->conv_source) {
		snd_stm_printe("Cannot register in converters router!\n");
		result = -ENOMEM;
		goto error_conv_register_source;
	}

	/* Claim the pads */

	if (pcm_player->info->pad_config) {
		pcm_player->pads = stm_pad_claim(pcm_player->info->pad_config,
				dev_name(&pdev->dev));
		if (!pcm_player->pads) {
			snd_stm_printe("Failed to claimed pads for '%s'!\n",
					dev_name(&pdev->dev));
			result = -EBUSY;
			goto error_pad_claim;
		}
	}

	/* Done now */

	platform_set_drvdata(pdev, pcm_player);

	return 0;

error_pad_claim:
	snd_stm_conv_unregister_source(pcm_player->conv_source);
error_conv_register_source:
	snd_stm_buffer_dispose(pcm_player->buffer);
error_buffer_init:
	/* snd_pcm_free() is not available - PCM device will be released
	 * during card release */
error_pcm:
	snd_device_free(card, pcm_player);
error_device:
	snd_stm_fdma_release(pcm_player->fdma_channel);
error_fdma_request:
	snd_stm_irq_release(pcm_player->irq, pcm_player);
error_irq_request:
	snd_stm_memory_release(pcm_player->mem_region, pcm_player->base);
error_memory_request:
	snd_stm_magic_clear(pcm_player);
	kfree(pcm_player);
error_alloc:
	return result;
}
Esempio n. 23
0
int snd_opl4_create(struct snd_card *card,
		    unsigned long fm_port, unsigned long pcm_port,
		    int seq_device,
		    struct snd_opl3 **ropl3, struct snd_opl4 **ropl4)
{
	struct snd_opl4 *opl4;
	struct snd_opl3 *opl3;
	int err;
	static struct snd_device_ops ops = {
		.dev_free = snd_opl4_dev_free
	};

	if (ropl3)
		*ropl3 = NULL;
	if (ropl4)
		*ropl4 = NULL;

	opl4 = kzalloc(sizeof(*opl4), GFP_KERNEL);
	if (!opl4)
		return -ENOMEM;

	opl4->res_fm_port = request_region(fm_port, 8, "OPL4 FM");
	opl4->res_pcm_port = request_region(pcm_port, 8, "OPL4 PCM/MIX");
	if (!opl4->res_fm_port || !opl4->res_pcm_port) {
		snd_printk(KERN_ERR "opl4: can't grab ports 0x%lx, 0x%lx\n", fm_port, pcm_port);
		snd_opl4_free(opl4);
		return -EBUSY;
	}

	opl4->card = card;
	opl4->fm_port = fm_port;
	opl4->pcm_port = pcm_port;
	spin_lock_init(&opl4->reg_lock);
	mutex_init(&opl4->access_mutex);

	err = snd_opl4_detect(opl4);
	if (err < 0) {
		snd_opl4_free(opl4);
		snd_printd("OPL4 chip not detected at %#lx/%#lx\n", fm_port, pcm_port);
		return err;
	}

	err = snd_device_new(card, SNDRV_DEV_CODEC, opl4, &ops);
	if (err < 0) {
		snd_opl4_free(opl4);
		return err;
	}

	err = snd_opl3_create(card, fm_port, fm_port + 2, opl4->hardware, 1, &opl3);
	if (err < 0) {
		snd_device_free(card, opl4);
		return err;
	}

	/* opl3 initialization disabled opl4, so reenable */
	snd_opl4_enable_opl4(opl4);

	snd_opl4_create_mixer(opl4);
	snd_opl4_create_proc(opl4);

#if defined(CONFIG_SND_SEQUENCER) || (defined(MODULE) && defined(CONFIG_SND_SEQUENCER_MODULE))
	opl4->seq_client = -1;
	if (opl4->hardware < OPL3_HW_OPL4_ML)
		snd_opl4_create_seq_dev(opl4, seq_device);
#endif

	if (ropl3)
		*ropl3 = opl3;
	if (ropl4)
		*ropl4 = opl4;
	return 0;
}
int snd_cs4236_create(struct snd_card *card,
		      unsigned long port,
		      unsigned long cport,
		      int irq, int dma1, int dma2,
		      unsigned short hardware,
		      unsigned short hwshare,
		      struct snd_wss **rchip)
{
	struct snd_wss *chip;
	unsigned char ver1, ver2;
	unsigned int reg;
	int err;

	*rchip = NULL;
	if (hardware == WSS_HW_DETECT)
		hardware = WSS_HW_DETECT3;

	err = snd_wss_create(card, port, cport,
			     irq, dma1, dma2, hardware, hwshare, &chip);
	if (err < 0)
		return err;

	if ((chip->hardware & WSS_HW_CS4236B_MASK) == 0) {
		snd_printd("chip is not CS4236+, hardware=0x%x\n",
			   chip->hardware);
		*rchip = chip;
		return 0;
	}
#if 0
	{
		int idx;
		for (idx = 0; idx < 8; idx++)
			snd_printk(KERN_DEBUG "CD%i = 0x%x\n",
				   idx, inb(chip->cport + idx));
		for (idx = 0; idx < 9; idx++)
			snd_printk(KERN_DEBUG "C%i = 0x%x\n",
				   idx, snd_cs4236_ctrl_in(chip, idx));
	}
#endif
	if (cport < 0x100 || cport == SNDRV_AUTO_PORT) {
		snd_printk(KERN_ERR "please, specify control port "
			   "for CS4236+ chips\n");
		snd_device_free(card, chip);
		return -ENODEV;
	}
	ver1 = snd_cs4236_ctrl_in(chip, 1);
	ver2 = snd_cs4236_ext_in(chip, CS4236_VERSION);
	snd_printdd("CS4236: [0x%lx] C1 (version) = 0x%x, ext = 0x%x\n",
			cport, ver1, ver2);
	if (ver1 != ver2) {
		snd_printk(KERN_ERR "CS4236+ chip detected, but "
			   "control port 0x%lx is not valid\n", cport);
		snd_device_free(card, chip);
		return -ENODEV;
	}
	snd_cs4236_ctrl_out(chip, 0, 0x00);
	snd_cs4236_ctrl_out(chip, 2, 0xff);
	snd_cs4236_ctrl_out(chip, 3, 0x00);
	snd_cs4236_ctrl_out(chip, 4, 0x80);
	reg = ((IEC958_AES1_CON_PCM_CODER & 3) << 6) |
	      IEC958_AES0_CON_EMPHASIS_NONE;
	snd_cs4236_ctrl_out(chip, 5, reg);
	snd_cs4236_ctrl_out(chip, 6, IEC958_AES1_CON_PCM_CODER >> 2);
	snd_cs4236_ctrl_out(chip, 7, 0x00);
	snd_cs4236_ctrl_out(chip, 8, 0x8c);
	chip->rate_constraint = snd_cs4236_xrate;
	chip->set_playback_format = snd_cs4236_playback_format;
	chip->set_capture_format = snd_cs4236_capture_format;
#ifdef CONFIG_PM
	chip->suspend = snd_cs4236_suspend;
	chip->resume = snd_cs4236_resume;
#endif

	
	for (reg = 0; reg < sizeof(snd_cs4236_ext_map); reg++)
		snd_cs4236_ext_out(chip, CS4236_I23VAL(reg),
				   snd_cs4236_ext_map[reg]);

	
	snd_wss_out(chip, CS4231_LEFT_INPUT, 0x40);
	snd_wss_out(chip, CS4231_RIGHT_INPUT, 0x40);
	snd_wss_out(chip, CS4231_AUX1_LEFT_INPUT, 0xff);
	snd_wss_out(chip, CS4231_AUX1_RIGHT_INPUT, 0xff);
	snd_wss_out(chip, CS4231_AUX2_LEFT_INPUT, 0xdf);
	snd_wss_out(chip, CS4231_AUX2_RIGHT_INPUT, 0xdf);
	snd_wss_out(chip, CS4231_RIGHT_LINE_IN, 0xff);
	snd_wss_out(chip, CS4231_LEFT_LINE_IN, 0xff);
	snd_wss_out(chip, CS4231_RIGHT_LINE_IN, 0xff);
	switch (chip->hardware) {
	case WSS_HW_CS4235:
	case WSS_HW_CS4239:
		snd_wss_out(chip, CS4235_LEFT_MASTER, 0xff);
		snd_wss_out(chip, CS4235_RIGHT_MASTER, 0xff);
		break;
	}

	*rchip = chip;
	return 0;
}
Esempio n. 25
0
int snd_mpu401_uart_new(struct snd_card *card, int device,
			unsigned short hardware,
			unsigned long port,
			unsigned int info_flags,
			int irq,
			struct snd_rawmidi ** rrawmidi)
{
	struct snd_mpu401 *mpu;
	struct snd_rawmidi *rmidi;
	int in_enable, out_enable;
	int err;

	if (rrawmidi)
		*rrawmidi = NULL;
	if (! (info_flags & (MPU401_INFO_INPUT | MPU401_INFO_OUTPUT)))
		info_flags |= MPU401_INFO_INPUT | MPU401_INFO_OUTPUT;
	in_enable = (info_flags & MPU401_INFO_INPUT) ? 1 : 0;
	out_enable = (info_flags & MPU401_INFO_OUTPUT) ? 1 : 0;
	if ((err = snd_rawmidi_new(card, "MPU-401U", device,
				   out_enable, in_enable, &rmidi)) < 0)
		return err;
	mpu = kzalloc(sizeof(*mpu), GFP_KERNEL);
	if (mpu == NULL) {
		snd_printk(KERN_ERR "mpu401_uart: cannot allocate\n");
		snd_device_free(card, rmidi);
		return -ENOMEM;
	}
	rmidi->private_data = mpu;
	rmidi->private_free = snd_mpu401_uart_free;
	spin_lock_init(&mpu->input_lock);
	spin_lock_init(&mpu->output_lock);
	spin_lock_init(&mpu->timer_lock);
	mpu->hardware = hardware;
	mpu->irq = -1;
	if (! (info_flags & MPU401_INFO_INTEGRATED)) {
		int res_size = hardware == MPU401_HW_PC98II ? 4 : 2;
		mpu->res = request_region(port, res_size, "MPU401 UART");
		if (mpu->res == NULL) {
			snd_printk(KERN_ERR "mpu401_uart: "
				   "unable to grab port 0x%lx size %d\n",
				   port, res_size);
			snd_device_free(card, rmidi);
			return -EBUSY;
		}
	}
	if (info_flags & MPU401_INFO_MMIO) {
		mpu->write = mpu401_write_mmio;
		mpu->read = mpu401_read_mmio;
	} else {
		mpu->write = mpu401_write_port;
		mpu->read = mpu401_read_port;
	}
	mpu->port = port;
	if (hardware == MPU401_HW_PC98II)
		mpu->cport = port + 2;
	else
		mpu->cport = port + 1;
	if (irq >= 0) {
		if (request_irq(irq, snd_mpu401_uart_interrupt, 0,
				"MPU401 UART", (void *) mpu)) {
			snd_printk(KERN_ERR "mpu401_uart: "
				   "unable to grab IRQ %d\n", irq);
			snd_device_free(card, rmidi);
			return -EBUSY;
		}
	}
	if (irq < 0 && !(info_flags & MPU401_INFO_IRQ_HOOK))
		info_flags |= MPU401_INFO_USE_TIMER;
	mpu->info_flags = info_flags;
	mpu->irq = irq;
	if (card->shortname[0])
		snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI",
			 card->shortname);
	else
		sprintf(rmidi->name, "MPU-401 MIDI %d-%d",card->number, device);
	if (out_enable) {
		snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
				    &snd_mpu401_uart_output);
		rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT;
	}
	if (in_enable) {
		snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
				    &snd_mpu401_uart_input);
		rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT;
		if (out_enable)
			rmidi->info_flags |= SNDRV_RAWMIDI_INFO_DUPLEX;
	}
	mpu->rmidi = rmidi;
	if (rrawmidi)
		*rrawmidi = rmidi;
	return 0;
}
Esempio n. 26
0
int snd_cs4236_create(struct snd_card *card,
              unsigned long port,
              unsigned long cport,
              int irq, int dma1, int dma2,
              unsigned short hardware,
              unsigned short hwshare,
              struct snd_cs4231 ** rchip)
{
    struct snd_cs4231 *chip;
    unsigned char ver1, ver2;
    unsigned int reg;
    int err;

    *rchip = NULL;
    if (hardware == CS4231_HW_DETECT)
        hardware = CS4231_HW_DETECT3;
    if (cport < 0x100) {
        snd_printk("please, specify control port for CS4236+ chips\n");
        return -ENODEV;
    }
    if ((err = snd_cs4231_create(card, port, cport, irq, dma1, dma2, hardware, hwshare, &chip)) < 0)
        return err;

    if (!(chip->hardware & CS4231_HW_CS4236B_MASK)) {
            snd_printk("CS4236+: MODE3 and extended registers not available, hardware=0x%x\n",chip->hardware);
        snd_device_free(card, chip);
        return -ENODEV;
    }
#if 0
    {
        int idx;
        for (idx = 0; idx < 8; idx++)
            snd_printk("CD%i = 0x%x\n", idx, inb(chip->cport + idx));
        for (idx = 0; idx < 9; idx++)
            snd_printk("C%i = 0x%x\n", idx, snd_cs4236_ctrl_in(chip, idx));
    }
#endif
    ver1 = snd_cs4236_ctrl_in(chip, 1);
    ver2 = snd_cs4236_ext_in(chip, CS4236_VERSION);
    snd_printdd("CS4236: [0x%lx] C1 (version) = 0x%x, ext = 0x%x\n", cport, ver1, ver2);
    if (ver1 != ver2) {
        snd_printk("CS4236+ chip detected, but control port 0x%lx is not valid\n", cport);
        snd_device_free(card, chip);
        return -ENODEV;
    }
    snd_cs4236_ctrl_out(chip, 0, 0x00);
    snd_cs4236_ctrl_out(chip, 2, 0xff);
    snd_cs4236_ctrl_out(chip, 3, 0x00);
    snd_cs4236_ctrl_out(chip, 4, 0x80);
    snd_cs4236_ctrl_out(chip, 5, ((IEC958_AES1_CON_PCM_CODER & 3) << 6) | IEC958_AES0_CON_EMPHASIS_NONE);
    snd_cs4236_ctrl_out(chip, 6, IEC958_AES1_CON_PCM_CODER >> 2);
    snd_cs4236_ctrl_out(chip, 7, 0x00);
    /* 0x8c for C8 is valid for Turtle Beach Malibu - the IEC-958 output */
    /* is working with this setup, other hardware should have */
    /* different signal paths and this value should be selectable */
    /* in the future */
    snd_cs4236_ctrl_out(chip, 8, 0x8c);
    chip->rate_constraint = snd_cs4236_xrate;
    chip->set_playback_format = snd_cs4236_playback_format;
    chip->set_capture_format = snd_cs4236_capture_format;
#ifdef CONFIG_PM
    chip->suspend = snd_cs4236_suspend;
    chip->resume = snd_cs4236_resume;
#endif

    /* initialize extended registers */
    for (reg = 0; reg < sizeof(snd_cs4236_ext_map); reg++)
        snd_cs4236_ext_out(chip, CS4236_I23VAL(reg), snd_cs4236_ext_map[reg]);

        /* initialize compatible but more featured registers */
    snd_cs4231_out(chip, CS4231_LEFT_INPUT, 0x40);
    snd_cs4231_out(chip, CS4231_RIGHT_INPUT, 0x40);
    snd_cs4231_out(chip, CS4231_AUX1_LEFT_INPUT, 0xff);
    snd_cs4231_out(chip, CS4231_AUX1_RIGHT_INPUT, 0xff);
    snd_cs4231_out(chip, CS4231_AUX2_LEFT_INPUT, 0xdf);
    snd_cs4231_out(chip, CS4231_AUX2_RIGHT_INPUT, 0xdf);
    snd_cs4231_out(chip, CS4231_RIGHT_LINE_IN, 0xff);
    snd_cs4231_out(chip, CS4231_LEFT_LINE_IN, 0xff);
    snd_cs4231_out(chip, CS4231_RIGHT_LINE_IN, 0xff);
    switch (chip->hardware) {
    case CS4231_HW_CS4235:
    case CS4231_HW_CS4239:
        snd_cs4231_out(chip, CS4235_LEFT_MASTER, 0xff);
        snd_cs4231_out(chip, CS4235_RIGHT_MASTER, 0xff);
        break;
    }

    *rchip = chip;
    return 0;
}
Esempio n. 27
0
/**
 * snd_hda_detach_beep_device - Detach the beep device
 * @codec: the HDA codec
 */
void snd_hda_detach_beep_device(struct hda_codec *codec)
{
	if (!codec->bus->shutdown && codec->beep)
		snd_device_free(codec->card, codec->beep);
}
Esempio n. 28
0
/**
 * snd_mpu401_uart_new - create an MPU401-UART instance
 * @card: the card instance
 * @device: the device index, zero-based
 * @hardware: the hardware type, MPU401_HW_XXXX
 * @port: the base address of MPU401 port
 * @integrated: non-zero if the port was already reserved by the chip
 * @irq: the irq number, -1 if no interrupt for mpu
 * @irq_flags: the irq request flags (SA_XXX), 0 if irq was already reserved.
 * @rrawmidi: the pointer to store the new rawmidi instance
 *
 * Creates a new MPU-401 instance.
 *
 * Note that the rawmidi instance is returned on the rrawmidi argument,
 * not the mpu401 instance itself.  To access to the mpu401 instance,
 * cast from rawmidi->private_data (with mpu401_t magic-cast).
 *
 * Returns zero if successful, or a negative error code.
 */
int snd_mpu401_uart_new(snd_card_t * card, int device,
			unsigned short hardware,
			unsigned long port, int integrated,
			int irq, int irq_flags,
			snd_rawmidi_t ** rrawmidi)
{
	mpu401_t *mpu;
	snd_rawmidi_t *rmidi;
	int err;

	if (rrawmidi)
		*rrawmidi = NULL;
	if ((err = snd_rawmidi_new(card, "MPU-401U", device, 1, 1, &rmidi)) < 0)
		return err;
	mpu = kcalloc(1, sizeof(*mpu), GFP_KERNEL);
	if (mpu == NULL) {
		snd_device_free(card, rmidi);
		return -ENOMEM;
	}
	rmidi->private_data = mpu;
	rmidi->private_free = snd_mpu401_uart_free;
	spin_lock_init(&mpu->input_lock);
	spin_lock_init(&mpu->output_lock);
	spin_lock_init(&mpu->timer_lock);
	mpu->hardware = hardware;
	if (!integrated) {
		int res_size = hardware == MPU401_HW_PC98II ? 4 : 2;
		if ((mpu->res = request_region(port, res_size, "MPU401 UART")) == NULL) {
			snd_printk(KERN_ERR "mpu401_uart: unable to grab port 0x%lx size %d\n", port, res_size);
			snd_device_free(card, rmidi);
			return -EBUSY;
		}
	}
	switch (hardware) {
	case MPU401_HW_AUREAL:
		mpu->write = mpu401_write_mmio;
		mpu->read = mpu401_read_mmio;
		break;
	default:
		mpu->write = mpu401_write_port;
		mpu->read = mpu401_read_port;
		break;
	}
	mpu->port = port;
	if (hardware == MPU401_HW_PC98II)
		mpu->cport = port + 2;
	else
		mpu->cport = port + 1;
	if (irq >= 0 && irq_flags) {
		if (request_irq(irq, snd_mpu401_uart_interrupt, irq_flags, "MPU401 UART", (void *) mpu)) {
			snd_printk(KERN_ERR "mpu401_uart: unable to grab IRQ %d\n", irq);
			snd_device_free(card, rmidi);
			return -EBUSY;
		}
	}
	mpu->irq = irq;
	mpu->irq_flags = irq_flags;
	if (card->shortname[0])
		snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI", card->shortname);
	else
		sprintf(rmidi->name, "MPU-401 MIDI %d-%d", card->number, device);
	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_mpu401_uart_output);
	snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, &snd_mpu401_uart_input);
	rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT |
	                     SNDRV_RAWMIDI_INFO_INPUT |
	                     SNDRV_RAWMIDI_INFO_DUPLEX;
	mpu->rmidi = rmidi;
	if (rrawmidi)
		*rrawmidi = rmidi;
	return 0;
}
Esempio n. 29
0
int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
				int pcm_device, int multi_device)
{
	int err, pcm;
	struct snd_kcontrol *kctl;
	struct snd_card *card = emu->card;
	char **c;
	static char *emu10k1_remove_ctls[] = {
		/* no AC97 mono, surround, center/lfe */
		"Master Mono Playback Switch",
		"Master Mono Playback Volume",
		"PCM Out Path & Mute",
		"Mono Output Select",
		"Front Playback Switch",
		"Front Playback Volume",
		"Surround Playback Switch",
		"Surround Playback Volume",
		"Center Playback Switch",
		"Center Playback Volume",
		"LFE Playback Switch",
		"LFE Playback Volume",
		NULL
	};
	static char *emu10k1_rename_ctls[] = {
		"Surround Digital Playback Volume", "Surround Playback Volume",
		"Center Digital Playback Volume", "Center Playback Volume",
		"LFE Digital Playback Volume", "LFE Playback Volume",
		NULL
	};
	static char *audigy_remove_ctls[] = {
		/* Master/PCM controls on ac97 of Audigy has no effect */
		/* On the Audigy2 the AC97 playback is piped into
		 * the Philips ADC for 24bit capture */
		"PCM Playback Switch",
		"PCM Playback Volume",
		"Master Mono Playback Switch",
		"Master Mono Playback Volume",
		"Master Playback Switch",
		"Master Playback Volume",
		"PCM Out Path & Mute",
		"Mono Output Select",
		/* remove unused AC97 capture controls */
		"Capture Source",
		"Capture Switch",
		"Capture Volume",
		"Mic Select",
		"Video Playback Switch",
		"Video Playback Volume",
		"Mic Playback Switch",
		"Mic Playback Volume",
		NULL
	};
	static char *audigy_rename_ctls[] = {
		/* use conventional names */
		"Wave Playback Volume", "PCM Playback Volume",
		/* "Wave Capture Volume", "PCM Capture Volume", */
		"Wave Master Playback Volume", "Master Playback Volume",
		"AMic Playback Volume", "Mic Playback Volume",
		NULL
	};
	static char *audigy_remove_ctls_1361t_adc[] = {
		/* On the Audigy2 the AC97 playback is piped into
		 * the Philips ADC for 24bit capture */
		"PCM Playback Switch",
		"PCM Playback Volume",
		"Master Mono Playback Switch",
		"Master Mono Playback Volume",
		"Capture Source",
		"Capture Switch",
		"Capture Volume",
		"Mic Capture Volume",
		"Headphone Playback Switch",
		"Headphone Playback Volume",
		"3D Control - Center",
		"3D Control - Depth",
		"3D Control - Switch",
		"Line2 Playback Volume",
		"Line2 Capture Volume",
		NULL
	};
	static char *audigy_rename_ctls_1361t_adc[] = {
		"Master Playback Switch", "Master Capture Switch",
		"Master Playback Volume", "Master Capture Volume",
		"Wave Master Playback Volume", "Master Playback Volume",
		"PC Speaker Playback Switch", "PC Speaker Capture Switch",
		"PC Speaker Playback Volume", "PC Speaker Capture Volume",
		"Phone Playback Switch", "Phone Capture Switch",
		"Phone Playback Volume", "Phone Capture Volume",
		"Mic Playback Switch", "Mic Capture Switch",
		"Mic Playback Volume", "Mic Capture Volume",
		"Line Playback Switch", "Line Capture Switch",
		"Line Playback Volume", "Line Capture Volume",
		"CD Playback Switch", "CD Capture Switch",
		"CD Playback Volume", "CD Capture Volume",
		"Aux Playback Switch", "Aux Capture Switch",
		"Aux Playback Volume", "Aux Capture Volume",
		"Video Playback Switch", "Video Capture Switch",
		"Video Playback Volume", "Video Capture Volume",

		NULL
	};

	if (emu->card_capabilities->ac97_chip) {
		struct snd_ac97_bus *pbus;
		struct snd_ac97_template ac97;
		static struct snd_ac97_bus_ops ops = {
			.write = snd_emu10k1_ac97_write,
			.read = snd_emu10k1_ac97_read,
		};

		if ((err = snd_ac97_bus(emu->card, 0, &ops, NULL, &pbus)) < 0)
			return err;
		pbus->no_vra = 1; /* we don't need VRA */
		
		memset(&ac97, 0, sizeof(ac97));
		ac97.private_data = emu;
		ac97.private_free = snd_emu10k1_mixer_free_ac97;
		ac97.scaps = AC97_SCAP_NO_SPDIF;
		if ((err = snd_ac97_mixer(pbus, &ac97, &emu->ac97)) < 0) {
			if (emu->card_capabilities->ac97_chip == 1)
				return err;
			snd_printd(KERN_INFO "emu10k1: AC97 is optional on this board\n");
			snd_printd(KERN_INFO"          Proceeding without ac97 mixers...\n");
			snd_device_free(emu->card, pbus);
			goto no_ac97; /* FIXME: get rid of ugly gotos.. */
		}
		if (emu->audigy) {
			/* set master volume to 0 dB */
			snd_ac97_write_cache(emu->ac97, AC97_MASTER, 0x0000);
			/* set capture source to mic */
			snd_ac97_write_cache(emu->ac97, AC97_REC_SEL, 0x0000);
			if (emu->card_capabilities->adc_1361t)
				c = audigy_remove_ctls_1361t_adc;
			else 
				c = audigy_remove_ctls;
		} else {
			/*
			 * Credits for cards based on STAC9758:
			 *   James Courtier-Dutton <*****@*****.**>
			 *   Voluspa <*****@*****.**>
			 */
			if (emu->ac97->id == AC97_ID_STAC9758) {
				emu->rear_ac97 = 1;
				snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT);
			}
			/* remove unused AC97 controls */
			snd_ac97_write_cache(emu->ac97, AC97_SURROUND_MASTER, 0x0202);
			snd_ac97_write_cache(emu->ac97, AC97_CENTER_LFE_MASTER, 0x0202);
			c = emu10k1_remove_ctls;
		}
		for (; *c; c++)
			remove_ctl(card, *c);
	} else {