static int __devinit snd_vx222_create(struct snd_card *card, struct pci_dev *pci,
				      struct snd_vx_hardware *hw,
				      struct snd_vx222 **rchip)
{
	struct vx_core *chip;
	struct snd_vx222 *vx;
	int i, err;
	static struct snd_device_ops ops = {
		.dev_free =	snd_vx222_dev_free,
	};
	struct snd_vx_ops *vx_ops;

	
	if ((err = pci_enable_device(pci)) < 0)
		return err;
	pci_set_master(pci);

	vx_ops = hw->type == VX_TYPE_BOARD ? &vx222_old_ops : &vx222_ops;
	chip = snd_vx_create(card, hw, vx_ops,
			     sizeof(struct snd_vx222) - sizeof(struct vx_core));
	if (! chip) {
		pci_disable_device(pci);
		return -ENOMEM;
	}
	vx = (struct snd_vx222 *)chip;
	vx->pci = pci;

	if ((err = pci_request_regions(pci, CARD_NAME)) < 0) {
		snd_vx222_free(chip);
		return err;
	}
	for (i = 0; i < 2; i++)
		vx->port[i] = pci_resource_start(pci, i + 1);

	if (request_irq(pci->irq, snd_vx_irq_handler, IRQF_SHARED,
			KBUILD_MODNAME, chip)) {
		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
		snd_vx222_free(chip);
		return -EBUSY;
	}
	chip->irq = pci->irq;

	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
		snd_vx222_free(chip);
		return err;
	}

	snd_card_set_dev(card, &pci->dev);

	*rchip = vx;
	return 0;
}
Example #2
0
/**
 * snd_intelhad_create - to crete alsa card instance
 *
 * @intelhaddata: pointer to internal context
 * @card: pointer to card
 *
 * This function is called when the hdmi cable is plugged in
 */
static int __devinit snd_intelhad_create(
		struct snd_intelhad *intelhaddata,
		struct snd_card *card)
{
	int retval;
	static struct snd_device_ops ops = {
	};

	BUG_ON(!intelhaddata);
	/* ALSA api to register the device */
	retval = snd_device_new(card, SNDRV_DEV_LOWLEVEL, intelhaddata, &ops);
	return retval;
}
Example #3
0
/*
 * Use __devinit to place it in the same section as rtx_ac97_probe() (see
 * below).
 */
static int __devinit	rtx_ac97_create(struct snd_card *card,
					struct pci_dev *pdev)
{
	static struct snd_device_ops	ops = {
		.dev_free = rtx_ac97_dev_free
	};
	struct rtx_ac97			*chip;
	int				err;

	err = pci_enable_device(pdev);
	if (err < 0)
		return (err);

	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
	if (!chip) {
		err = -ENOMEM;
		goto fail;
	}
	chip->pdev = pdev;
	chip->card = card;

	/* Allocate PCI stuff here */

	/*
	 * create a "fake" lowlevel (custom) device to have a dtor for our chip
	 * structure:
	 */
	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
	if (err < 0)
		goto fail;

	/*
	 * registration of device structure this seems needed for alsa/linux
	 * internal stuff:
	 */
	snd_card_set_dev(card, &pdev->dev);

	printk(KERN_INFO "rtx_ac97: chip=0x%p created.\n", chip);

	/* attach ourselves to the card instance: */
	card->private_data = chip;

	return (0);

fail:
	if (chip)
		rtx_ac97_free(chip);
	else
		pci_disable_device(pdev);
	return (err);
}
Example #4
0
/*
	Initialize the Line6 MIDI subsystem.
*/
int line6_init_midi(struct usb_line6 *line6)
{
	static struct snd_device_ops midi_ops = {
		.dev_free = snd_line6_midi_free,
	};

	int err;
	struct snd_line6_midi *line6midi;

	if (!(line6->properties->capabilities & LINE6_BIT_CONTROL)) {
		/* skip MIDI initialization and report success */
		return 0;
	}

	line6midi = kzalloc(sizeof(struct snd_line6_midi), GFP_KERNEL);

	if (line6midi == NULL)
		return -ENOMEM;

	err = line6_midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0);
	if (err < 0) {
		kfree(line6midi);
		return err;
	}

	err = line6_midibuf_init(&line6midi->midibuf_out, MIDI_BUFFER_SIZE, 1);
	if (err < 0) {
		kfree(line6midi->midibuf_in.buf);
		kfree(line6midi);
		return err;
	}

	line6midi->line6 = line6;
	line6->line6midi = line6midi;

	err = snd_device_new(line6->card, SNDRV_DEV_RAWMIDI, line6midi,
			     &midi_ops);
	if (err < 0)
		return err;

	snd_card_set_dev(line6->card, line6->ifcdev);

	err = snd_line6_new_midi(line6midi);
	if (err < 0)
		return err;

	init_waitqueue_head(&line6midi->send_wait);
	spin_lock_init(&line6midi->send_urb_lock);
	spin_lock_init(&line6midi->midi_transmit_lock);
	return 0;
}
Example #5
0
static int snd_pcsp_create(struct snd_card *card)
{
	static struct snd_device_ops ops = { };
	unsigned int resolution = hrtimer_resolution;
	int err, div, min_div, order;

	if (!nopcm) {
		if (resolution > PCSP_MAX_PERIOD_NS) {
			printk(KERN_ERR "PCSP: Timer resolution is not sufficient "
				"(%unS)\n", resolution);
			printk(KERN_ERR "PCSP: Make sure you have HPET and ACPI "
				"enabled.\n");
			printk(KERN_ERR "PCSP: Turned into nopcm mode.\n");
			nopcm = 1;
		}
	}

	if (loops_per_jiffy >= PCSP_MIN_LPJ && resolution <= PCSP_MIN_PERIOD_NS)
		min_div = MIN_DIV;
	else
		min_div = MAX_DIV;
#if PCSP_DEBUG
	printk(KERN_DEBUG "PCSP: lpj=%li, min_div=%i, res=%u\n",
	       loops_per_jiffy, min_div, resolution);
#endif

	div = MAX_DIV / min_div;
	order = fls(div) - 1;

	pcsp_chip.max_treble = min(order, PCSP_MAX_TREBLE);
	pcsp_chip.treble = min(pcsp_chip.max_treble, PCSP_DEFAULT_TREBLE);
	pcsp_chip.playback_ptr = 0;
	pcsp_chip.period_ptr = 0;
	atomic_set(&pcsp_chip.timer_active, 0);
	pcsp_chip.enable = 1;
	pcsp_chip.pcspkr = 1;

	spin_lock_init(&pcsp_chip.substream_lock);

	pcsp_chip.card = card;
	pcsp_chip.port = 0x61;
	pcsp_chip.irq = -1;
	pcsp_chip.dma = -1;

	/* Register device */
	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, &pcsp_chip, &ops);
	if (err < 0)
		return err;

	return 0;
}
Example #6
0
static int __devinit snd_pcsp_create(struct snd_card *card)
{
	static struct snd_device_ops ops = { };
	struct timespec tp;
	int err;
	int div, min_div, order;

	hrtimer_get_res(CLOCK_MONOTONIC, &tp);
	if (tp.tv_sec || tp.tv_nsec > PCSP_MAX_PERIOD_NS) {
		printk(KERN_ERR "PCSP: Timer resolution is not sufficient "
		       "(%linS)\n", tp.tv_nsec);
		printk(KERN_ERR "PCSP: Make sure you have HPET and ACPI "
		       "enabled.\n");
		return -EIO;
	}

	if (loops_per_jiffy >= PCSP_MIN_LPJ && tp.tv_nsec <= PCSP_MIN_PERIOD_NS)
		min_div = MIN_DIV;
	else
		min_div = MAX_DIV;
#if PCSP_DEBUG
	printk("PCSP: lpj=%li, min_div=%i, res=%li\n",
	       loops_per_jiffy, min_div, tp.tv_nsec);
#endif

	div = MAX_DIV / min_div;
	order = fls(div) - 1;

	pcsp_chip.max_treble = min(order, PCSP_MAX_TREBLE);
	pcsp_chip.treble = min(pcsp_chip.max_treble, PCSP_DEFAULT_TREBLE);
	pcsp_chip.playback_ptr = 0;
	pcsp_chip.period_ptr = 0;
	atomic_set(&pcsp_chip.timer_active, 0);
	pcsp_chip.enable = 1;
	pcsp_chip.pcspkr = 1;

	spin_lock_init(&pcsp_chip.substream_lock);

	pcsp_chip.card = card;
	pcsp_chip.port = 0x61;
	pcsp_chip.irq = -1;
	pcsp_chip.dma = -1;

	/* Register device */
	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, &pcsp_chip, &ops);
	if (err < 0)
		return err;

	return 0;
}
/*
 * snd_compress_new: create new compress device
 * @card: sound card pointer
 * @device: device number
 * @dirn: device direction, should be of type enum snd_compr_direction
 * @compr: compress device pointer
 */
int snd_compress_new(struct snd_card *card, int device,
			int dirn, struct snd_compr *compr)
{
	static struct snd_device_ops ops = {
		.dev_free = NULL,
		.dev_register = snd_compress_dev_register,
		.dev_disconnect = snd_compress_dev_disconnect,
	};

	compr->card = card;
	compr->device = device;
	compr->direction = dirn;
	return snd_device_new(card, SNDRV_DEV_COMPRESS, compr, &ops);
}
Example #8
0
static int __devinit snd_intelmad_create(
		struct snd_intelmad *intelmaddata,
		struct snd_card *card)
{
	int ret_val;
	static struct snd_device_ops ops = {
		.dev_free =	snd_intelmad_dev_free,
	};

	WARN_ON(!intelmaddata);
	WARN_ON(!card);
	/* ALSA api to register for the device */
	ret_val = snd_device_new(card, SNDRV_DEV_LOWLEVEL, intelmaddata, &ops);
	return ret_val;
}
Example #9
0
int snd_ak4114_create(snd_card_t *card,
		      ak4114_read_t *read, ak4114_write_t *write,
		      unsigned char pgm[7], unsigned char txcsb[5],
		      void *private_data, ak4114_t **r_ak4114)
{
	ak4114_t *chip;
	int err = 0;
	unsigned char reg;
	static snd_device_ops_t ops = {
		.dev_free =     snd_ak4114_dev_free,
	};

	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
	if (chip == NULL)
		return -ENOMEM;
	spin_lock_init(&chip->lock);
	chip->card = card;
	chip->read = read;
	chip->write = write;
	chip->private_data = private_data;

	for (reg = 0; reg < 7; reg++)
		chip->regmap[reg] = pgm[reg];
	for (reg = 0; reg < 5; reg++)
		chip->txcsb[reg] = txcsb[reg];

	chip->workqueue = create_workqueue("snd-ak4114");
	if (chip->workqueue == NULL) {
		kfree(chip);
		return -ENOMEM;
	}

	snd_ak4114_reinit(chip);

	chip->rcs0 = reg_read(chip, AK4114_REG_RCS0) & ~(AK4114_QINT | AK4114_CINT);
	chip->rcs1 = reg_read(chip, AK4114_REG_RCS1);

	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
		goto __fail;

	if (r_ak4114)
		*r_ak4114 = chip;
	return 0;

      __fail:
	snd_ak4114_free(chip);
	return err < 0 ? err : -EIO;
}
Example #10
0
/**
 * snd_jack_new - Create a new jack
 * @card:  the card instance
 * @id:    an identifying string for this jack
 * @type:  a bitmask of enum snd_jack_type values that can be detected by
 *         this jack
 * @jjack: Used to provide the allocated jack object to the caller.
 *
 * Creates a new jack object.
 *
 * Returns zero if successful, or a negative error code on failure.
 * On success jjack will be initialised.
 */
int snd_jack_new(struct snd_card *card, const char *id, int type,
		 struct snd_jack **jjack)
{
	struct snd_jack *jack;
	int err;
	int i;
	static struct snd_device_ops ops = {
		.dev_free = snd_jack_dev_free,
		.dev_register = snd_jack_dev_register,
		.dev_disconnect = snd_jack_dev_disconnect,
	};

	jack = kzalloc(sizeof(struct snd_jack), GFP_KERNEL);
	if (jack == NULL)
		return -ENOMEM;

	jack->id = kstrdup(id, GFP_KERNEL);

	jack->input_dev = input_allocate_device();
	if (jack->input_dev == NULL) {
		err = -ENOMEM;
		goto fail_input;
	}

	jack->input_dev->phys = "ALSA";

	jack->type = type;

	for (i = 0; i < ARRAY_SIZE(jack_types); i++)
		if (type & (1 << i))
			input_set_capability(jack->input_dev, EV_SW,
					     jack_types[i]);

	err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops);
	if (err < 0)
		goto fail_input;

	*jjack = jack;

	return 0;

fail_input:
	input_free_device(jack->input_dev);
	kfree(jack->id);
	kfree(jack);
	return err;
}
Example #11
0
File: hwdep.c Project: Abioy/kasan
/**
 * snd_hwdep_new - create a new hwdep instance
 * @card: the card instance
 * @id: the id string
 * @device: the device index (zero-based)
 * @rhwdep: the pointer to store the new hwdep instance
 *
 * Creates a new hwdep instance with the given index on the card.
 * The callbacks (hwdep->ops) must be set on the returned instance
 * after this call manually by the caller.
 *
 * Return: Zero if successful, or a negative error code on failure.
 */
int snd_hwdep_new(struct snd_card *card, char *id, int device,
		  struct snd_hwdep **rhwdep)
{
	struct snd_hwdep *hwdep;
	int err;
	static struct snd_device_ops ops = {
		.dev_free = snd_hwdep_dev_free,
		.dev_register = snd_hwdep_dev_register,
		.dev_disconnect = snd_hwdep_dev_disconnect,
	};

	if (snd_BUG_ON(!card))
		return -ENXIO;
	if (rhwdep)
		*rhwdep = NULL;
	hwdep = kzalloc(sizeof(*hwdep), GFP_KERNEL);
	if (hwdep == NULL) {
		dev_err(card->dev, "hwdep: cannot allocate\n");
		return -ENOMEM;
	}

	init_waitqueue_head(&hwdep->open_wait);
	mutex_init(&hwdep->open_mutex);
	hwdep->card = card;
	hwdep->device = device;
	if (id)
		strlcpy(hwdep->id, id, sizeof(hwdep->id));

	snd_device_initialize(&hwdep->dev, card);
	hwdep->dev.release = release_hwdep_device;
	dev_set_name(&hwdep->dev, "hwC%iD%i", card->number, device);
#ifdef CONFIG_SND_OSSEMUL
	hwdep->oss_type = -1;
#endif

	err = snd_device_new(card, SNDRV_DEV_HWDEP, hwdep, &ops);
	if (err < 0) {
		put_device(&hwdep->dev);
		return err;
	}

	if (rhwdep)
		*rhwdep = hwdep;
	return 0;
}
Example #12
0
/*
 * snd_compress_new: create new compress device
 * @card: sound card pointer
 * @device: device number
 * @dirn: device direction, should be of type enum snd_compr_direction
 * @compr: compress device pointer
 */
int snd_compress_new(struct snd_card *card, int device,
			int dirn, struct snd_compr *compr)
{
	static struct snd_device_ops ops = {
		.dev_free = snd_compress_dev_free,
		.dev_register = snd_compress_dev_register,
		.dev_disconnect = snd_compress_dev_disconnect,
	};

	compr->card = card;
	compr->device = device;
	compr->direction = dirn;

	snd_device_initialize(&compr->dev, card);
	dev_set_name(&compr->dev, "comprC%iD%i", card->number, device);

	return snd_device_new(card, SNDRV_DEV_COMPRESS, compr, &ops);
}
static int __devinit snd_sh_dac_create(struct snd_card *card,
				       struct platform_device *devptr,
				       struct snd_sh_dac **rchip)
{
	struct snd_sh_dac *chip;
	int err;

	static struct snd_device_ops ops = {
		   .dev_free = snd_sh_dac_dev_free,
	};

	*rchip = NULL;

	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
	if (chip == NULL)
		return -ENOMEM;

	chip->card = card;

	hrtimer_init(&chip->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	chip->hrtimer.function = sh_dac_audio_timer;

	dac_audio_reset(chip);
	chip->rate = 8000;
	dac_audio_set_rate(chip);

	chip->pdata = devptr->dev.platform_data;

	chip->data_buffer = kmalloc(chip->pdata->buffer_size, GFP_KERNEL);
	if (chip->data_buffer == NULL) {
		kfree(chip);
		return -ENOMEM;
	}

	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
	if (err < 0) {
		snd_sh_dac_free(chip);
		return err;
	}

	*rchip = chip;

	return 0;
}
Example #14
0
int snd_ak4114_create(struct snd_card *card,
		      ak4114_read_t *read, ak4114_write_t *write,
		      const unsigned char pgm[7], const unsigned char txcsb[5],
		      void *private_data, struct ak4114 **r_ak4114)
{
	struct ak4114 *chip;
	int err = 0;
	unsigned char reg;
	static struct snd_device_ops ops = {
		.dev_free =     snd_ak4114_dev_free,
	};

	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
	if (chip == NULL)
		return -ENOMEM;
	spin_lock_init(&chip->lock);
	chip->card = card;
	chip->read = read;
	chip->write = write;
	chip->private_data = private_data;
	INIT_DELAYED_WORK(&chip->work, ak4114_stats);

	for (reg = 0; reg < 7; reg++)
		chip->regmap[reg] = pgm[reg];
	for (reg = 0; reg < 5; reg++)
		chip->txcsb[reg] = txcsb[reg];

	ak4114_init_regs(chip);

	chip->rcs0 = reg_read(chip, AK4114_REG_RCS0) & ~(AK4114_QINT | AK4114_CINT);
	chip->rcs1 = reg_read(chip, AK4114_REG_RCS1);

	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0)
		goto __fail;

	if (r_ak4114)
		*r_ak4114 = chip;
	return 0;

      __fail:
	snd_ak4114_free(chip);
	return err < 0 ? err : -EIO;
}
Example #15
0
int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
		ak4113_write_t *write, const unsigned char *pgm,
		void *private_data, struct ak4113 **r_ak4113)
{
	struct ak4113 *chip;
	int err = 0;
	unsigned char reg;
	static struct snd_device_ops ops = {
		.dev_free =     snd_ak4113_dev_free,
	};

	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
	if (chip == NULL)
		return -ENOMEM;
	spin_lock_init(&chip->lock);
	chip->card = card;
	chip->read = read;
	chip->write = write;
	chip->private_data = private_data;
	INIT_DELAYED_WORK(&chip->work, ak4113_stats);
	atomic_set(&chip->wq_processing, 0);

	for (reg = 0; reg < AK4113_WRITABLE_REGS ; reg++)
		chip->regmap[reg] = pgm[reg];
	ak4113_init_regs(chip);

	chip->rcs0 = reg_read(chip, AK4113_REG_RCS0) & ~(AK4113_QINT |
			AK4113_CINT | AK4113_STC);
	chip->rcs1 = reg_read(chip, AK4113_REG_RCS1);
	chip->rcs2 = reg_read(chip, AK4113_REG_RCS2);
	err = snd_device_new(card, SNDRV_DEV_CODEC, chip, &ops);
	if (err < 0)
		goto __fail;

	if (r_ak4113)
		*r_ak4113 = chip;
	return 0;

__fail:
	snd_ak4113_free(chip);
	return err < 0 ? err : -EIO;
}
Example #16
0
static int hda_tegra_create(struct snd_card *card,
			    unsigned int driver_caps,
			    struct hda_tegra *hda)
{
	static struct snd_device_ops ops = {
		.dev_disconnect = hda_tegra_dev_disconnect,
		.dev_free = hda_tegra_dev_free,
	};
	struct azx *chip;
	int err;

	chip = &hda->chip;

	mutex_init(&chip->open_mutex);
	chip->card = card;
	chip->ops = &hda_tegra_ops;
	chip->driver_caps = driver_caps;
	chip->driver_type = driver_caps & 0xff;
	chip->dev_index = 0;
	INIT_LIST_HEAD(&chip->pcm_list);

	chip->codec_probe_mask = -1;

	chip->single_cmd = false;
	chip->snoop = true;

	INIT_WORK(&hda->probe_work, hda_tegra_probe_work);

	err = azx_bus_init(chip, NULL, &hda_tegra_io_ops);
	if (err < 0)
		return err;

	chip->bus.needs_damn_long_delay = 1;

	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
	if (err < 0) {
		dev_err(card->dev, "Error creating device\n");
		return err;
	}

	return 0;
}
/*
 * create vxpocket instance
 */
static struct snd_vxpocket *snd_vxpocket_new(struct snd_card *card, int ibl)
{
	dev_link_t *link;		/* Info for cardmgr */
	struct vx_core *chip;
	struct snd_vxpocket *vxp;
	static struct snd_device_ops ops = {
		.dev_free =	snd_vxpocket_dev_free,
	};

	chip = snd_vx_create(card, &vxpocket_hw, &snd_vxpocket_ops,
			     sizeof(struct snd_vxpocket) - sizeof(struct vx_core));
	if (! chip)
		return NULL;

	if (snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops) < 0) {
		kfree(chip);
		return NULL;
	}
	chip->ibl.size = ibl;

	vxp = (struct snd_vxpocket *)chip;

	link = &vxp->link;
	link->priv = chip;

	link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
	link->io.NumPorts1 = 16;

	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;

	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
	link->irq.Handler = &snd_vx_irq_handler;
	link->irq.Instance = chip;

	link->conf.Attributes = CONF_ENABLE_IRQ;
	link->conf.Vcc = 50;
	link->conf.IntType = INT_MEMORY_AND_IO;
	link->conf.ConfigIndex = 1;
	link->conf.Present = PRESENT_OPTION;

	return vxp;
}
Example #18
0
int snd_ak4117_create(struct snd_card *card, ak4117_read_t *read, ak4117_write_t *write,
		      const unsigned char pgm[5], void *private_data, struct ak4117 **r_ak4117)
{
	struct ak4117 *chip;
	int err = 0;
	unsigned char reg;
	static struct snd_device_ops ops = {
		.dev_free =     snd_ak4117_dev_free,
	};

	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
	if (chip == NULL)
		return -ENOMEM;
	spin_lock_init(&chip->lock);
	chip->card = card;
	chip->read = read;
	chip->write = write;
	chip->private_data = private_data;
	init_timer(&chip->timer);
	chip->timer.data = (unsigned long)chip;
	chip->timer.function = snd_ak4117_timer;

	for (reg = 0; reg < 5; reg++)
		chip->regmap[reg] = pgm[reg];
	snd_ak4117_reinit(chip);

	chip->rcs0 = reg_read(chip, AK4117_REG_RCS0) & ~(AK4117_QINT | AK4117_CINT | AK4117_STC);
	chip->rcs1 = reg_read(chip, AK4117_REG_RCS1);
	chip->rcs2 = reg_read(chip, AK4117_REG_RCS2);

	if ((err = snd_device_new(card, SNDRV_DEV_CODEC, chip, &ops)) < 0)
		goto __fail;

	if (r_ak4117)
		*r_ak4117 = chip;
	return 0;

      __fail:
	snd_ak4117_free(chip);
	return err < 0 ? err : -EIO;
}
Example #19
0
static int __devinit snd_vx222_create(struct snd_card *card, struct pci_dev *pci,
				      struct snd_vx_hardware *hw,
				      struct snd_vx222 **rchip)
{
	struct vx_core *chip;
	struct snd_vx222 *vx;
	static struct snd_device_ops ops = {
		.dev_free =	snd_vx222_dev_free,
	};
	chip = snd_vx_create(card, hw, vx_ops,
			     sizeof(struct snd_vx222) - sizeof(struct vx_core));
	if (! chip) {
		pci_disable_device(pci);
		return -ENOMEM;
	}
	vx = (struct snd_vx222 *)chip;
	vx->pci = pci;

	if ((err = pci_request_regions(pci, CARD_NAME)) < 0) {
		snd_vx222_free(chip);
		return 0;
	}
	for (i = 0; i < 2; i++)
		vx->port[i] = pci_resource_start(pci, i + 1);

	if (request_irq(pci->irq, snd_vx_irq_handler, IRQF_SHARED,
			CARD_NAME, chip)) {
		snd_vx222_free(chip);
		return -EBUSY;
	}
	chip->irq = pci->irq;

	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
		snd_vx222_free(chip);
		return 0;
	}


	return 0;
}
Example #20
0
/*
 * constructor
 */
static int hda_tegra_create(struct snd_card *card,
			    unsigned int driver_caps,
			    const struct hda_controller_ops *hda_ops,
			    struct hda_tegra *hda)
{
	static struct snd_device_ops ops = {
		.dev_free = hda_tegra_dev_free,
	};
	struct azx *chip;
	int err;

	chip = &hda->chip;

	spin_lock_init(&chip->reg_lock);
	mutex_init(&chip->open_mutex);
	chip->card = card;
	chip->ops = hda_ops;
	chip->irq = -1;
	chip->driver_caps = driver_caps;
	chip->driver_type = driver_caps & 0xff;
	chip->dev_index = 0;
	INIT_LIST_HEAD(&chip->pcm_list);
	INIT_LIST_HEAD(&chip->list);

	chip->position_fix[0] = POS_FIX_AUTO;
	chip->position_fix[1] = POS_FIX_AUTO;
	chip->codec_probe_mask = -1;

	chip->single_cmd = false;
	chip->snoop = true;

	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
	if (err < 0) {
		dev_err(card->dev, "Error creating device\n");
		return err;
	}

	return 0;
}
Example #21
0
/*
 * create vxpocket instance
 */
static int snd_vxpocket_new(struct snd_card *card, int ibl,
			    struct pcmcia_device *link,
			    struct snd_vxpocket **chip_ret)
{
	struct vx_core *chip;
	struct snd_vxpocket *vxp;
	static struct snd_device_ops ops = {
		.dev_free =	snd_vxpocket_dev_free,
	};
	int err;

	chip = snd_vx_create(card, &vxpocket_hw, &snd_vxpocket_ops,
			     sizeof(struct snd_vxpocket) - sizeof(struct vx_core));
	if (!chip)
		return -ENOMEM;

	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
	if (err < 0) {
		kfree(chip);
		return err;
	}
	chip->ibl.size = ibl;

	vxp = (struct snd_vxpocket *)chip;

	vxp->p_dev = link;
	link->priv = chip;

	link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
	link->resource[0]->end = 16;

	link->config_flags |= CONF_ENABLE_IRQ;
	link->config_index = 1;
	link->config_regs = PRESENT_OPTION;

	*chip_ret = vxp;
	return 0;
}
Example #22
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;
}
Example #23
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;
}
/**
 * snd_hwdep_new - create a new hwdep instance
 * @card: the card instance
 * @id: the id string
 * @device: the device index (zero-based)
 * @rhwdep: the pointer to store the new hwdep instance
 *
 * Creates a new hwdep instance with the given index on the card.
 * The callbacks (hwdep->ops) must be set on the returned instance
 * after this call manually by the caller.
 *
 * Returns zero if successful, or a negative error code on failure.
 */
int snd_hwdep_new(struct snd_card *card, char *id, int device,
		  struct snd_hwdep **rhwdep)
{
	struct snd_hwdep *hwdep;
	int err;
	static struct snd_device_ops ops = {
		.dev_free = snd_hwdep_dev_free,
		.dev_register = snd_hwdep_dev_register,
		.dev_disconnect = snd_hwdep_dev_disconnect,
	};

	if (snd_BUG_ON(!card))
		return -ENXIO;
	if (rhwdep)
		*rhwdep = NULL;
	hwdep = kzalloc(sizeof(*hwdep), GFP_KERNEL);
	if (hwdep == NULL) {
		snd_printk(KERN_ERR "hwdep: cannot allocate\n");
		return -ENOMEM;
	}
	hwdep->card = card;
	hwdep->device = device;
	if (id)
		strlcpy(hwdep->id, id, sizeof(hwdep->id));
#ifdef CONFIG_SND_OSSEMUL
	hwdep->oss_type = -1;
#endif
	if ((err = snd_device_new(card, SNDRV_DEV_HWDEP, hwdep, &ops)) < 0) {
		snd_hwdep_free(hwdep);
		return err;
	}
	init_waitqueue_head(&hwdep->open_wait);
	mutex_init(&hwdep->open_mutex);
	if (rhwdep)
		*rhwdep = hwdep;
	return 0;
}
int snd_sbdsp_create(struct snd_card *card,
		     unsigned long port,
		     int irq,
		     irqreturn_t (*irq_handler)(int, void *, struct pt_regs *),
		     int dma8,
		     int dma16,
		     unsigned short hardware,
		     struct snd_sb **r_chip)
{
	struct snd_sb *chip;
	int err;
	static struct snd_device_ops ops = {
		.dev_free =	snd_sbdsp_dev_free,
	};

	snd_assert(r_chip != NULL, return -EINVAL);
	*r_chip = NULL;
	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
	if (chip == NULL)
		return -ENOMEM;
	spin_lock_init(&chip->reg_lock);
	spin_lock_init(&chip->open_lock);
	spin_lock_init(&chip->midi_input_lock);
	spin_lock_init(&chip->mixer_lock);
	chip->irq = -1;
	chip->dma8 = -1;
	chip->dma16 = -1;
	chip->port = port;
	
	if (request_irq(irq, irq_handler, hardware == SB_HW_ALS4000 ?
			SA_INTERRUPT | SA_SHIRQ : SA_INTERRUPT,
			"SoundBlaster", (void *) chip)) {
		snd_printk(KERN_ERR "sb: can't grab irq %d\n", irq);
		snd_sbdsp_free(chip);
		return -EBUSY;
	}
	chip->irq = irq;

	if (hardware == SB_HW_ALS4000)
		goto __skip_allocation;
	
	if ((chip->res_port = request_region(port, 16, "SoundBlaster")) == NULL) {
		snd_printk(KERN_ERR "sb: can't grab port 0x%lx\n", port);
		snd_sbdsp_free(chip);
		return -EBUSY;
	}

#ifdef CONFIG_ISA
	if (dma8 >= 0 && request_dma(dma8, "SoundBlaster - 8bit")) {
		snd_printk(KERN_ERR "sb: can't grab DMA8 %d\n", dma8);
		snd_sbdsp_free(chip);
		return -EBUSY;
	}
	chip->dma8 = dma8;
	if (dma16 >= 0) {
		if (hardware != SB_HW_ALS100 && (dma16 < 5 || dma16 > 7)) {
			/* no duplex */
			dma16 = -1;
		} else if (request_dma(dma16, "SoundBlaster - 16bit")) {
			snd_printk(KERN_ERR "sb: can't grab DMA16 %d\n", dma16);
			snd_sbdsp_free(chip);
			return -EBUSY;
		}
	}
	chip->dma16 = dma16;
#endif

      __skip_allocation:
	chip->card = card;
	chip->hardware = hardware;
	if ((err = snd_sbdsp_probe(chip)) < 0) {
		snd_sbdsp_free(chip);
		return err;
	}
	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
		snd_sbdsp_free(chip);
		return err;
	}
	*r_chip = chip;
	return 0;
}
Example #26
0
static int snd_als300_create(struct snd_card *card,
			     struct pci_dev *pci, int chip_type,
			     struct snd_als300 **rchip)
{
	struct snd_als300 *chip;
	void *irq_handler;
	int err;

	static struct snd_device_ops ops = {
		.dev_free = snd_als300_dev_free,
	};
	*rchip = NULL;

	if ((err = pci_enable_device(pci)) < 0)
		return err;

	if (dma_set_mask(&pci->dev, DMA_BIT_MASK(28)) < 0 ||
		dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(28)) < 0) {
		dev_err(card->dev, "error setting 28bit DMA mask\n");
		pci_disable_device(pci);
		return -ENXIO;
	}
	pci_set_master(pci);

	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
	if (chip == NULL) {
		pci_disable_device(pci);
		return -ENOMEM;
	}

	chip->card = card;
	chip->pci = pci;
	chip->irq = -1;
	chip->chip_type = chip_type;
	spin_lock_init(&chip->reg_lock);

	if ((err = pci_request_regions(pci, "ALS300")) < 0) {
		kfree(chip);
		pci_disable_device(pci);
		return err;
	}
	chip->port = pci_resource_start(pci, 0);

	if (chip->chip_type == DEVICE_ALS300_PLUS)
		irq_handler = snd_als300plus_interrupt;
	else
		irq_handler = snd_als300_interrupt;

	if (request_irq(pci->irq, irq_handler, IRQF_SHARED,
			KBUILD_MODNAME, chip)) {
		dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
		snd_als300_free(chip);
		return -EBUSY;
	}
	chip->irq = pci->irq;


	snd_als300_init(chip);

	err = snd_als300_ac97(chip);
	if (err < 0) {
		dev_err(card->dev, "Could not create ac97\n");
		snd_als300_free(chip);
		return err;
	}

	if ((err = snd_als300_new_pcm(chip)) < 0) {
		dev_err(card->dev, "Could not create PCM\n");
		snd_als300_free(chip);
		return err;
	}

	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL,
						chip, &ops)) < 0) {
		snd_als300_free(chip);
		return err;
	}

	*rchip = chip;
	return 0;
}
Example #27
0
/*
	Create and register the PCM device and mixer entries.
	Create URBs for playback and capture.
*/
int line6_init_pcm(struct usb_line6 *line6,
		   struct line6_pcm_properties *properties)
{
	static struct snd_device_ops pcm_ops = {
		.dev_free = snd_line6_pcm_free,
	};

	int err;
	int ep_read = 0, ep_write = 0;
	struct snd_line6_pcm *line6pcm;

	if (!(line6->properties->capabilities & LINE6_BIT_PCM))
		return 0;	/* skip PCM initialization and report success */

	/* initialize PCM subsystem based on product id: */
	switch (line6->product) {
	case LINE6_DEVID_BASSPODXT:
	case LINE6_DEVID_BASSPODXTLIVE:
	case LINE6_DEVID_BASSPODXTPRO:
	case LINE6_DEVID_PODXT:
	case LINE6_DEVID_PODXTLIVE:
	case LINE6_DEVID_PODXTPRO:
	case LINE6_DEVID_PODHD300:
		ep_read = 0x82;
		ep_write = 0x01;
		break;

	case LINE6_DEVID_PODHD500:
	case LINE6_DEVID_PODX3:
	case LINE6_DEVID_PODX3LIVE:
		ep_read = 0x86;
		ep_write = 0x02;
		break;

	case LINE6_DEVID_POCKETPOD:
		ep_read = 0x82;
		ep_write = 0x02;
		break;

	case LINE6_DEVID_GUITARPORT:
	case LINE6_DEVID_PODSTUDIO_GX:
	case LINE6_DEVID_PODSTUDIO_UX1:
	case LINE6_DEVID_PODSTUDIO_UX2:
	case LINE6_DEVID_TONEPORT_GX:
	case LINE6_DEVID_TONEPORT_UX1:
	case LINE6_DEVID_TONEPORT_UX2:
		ep_read = 0x82;
		ep_write = 0x01;
		break;

		/* this is for interface_number == 1:
		   case LINE6_DEVID_TONEPORT_UX2:
		   case LINE6_DEVID_PODSTUDIO_UX2:
		   ep_read  = 0x87;
		   ep_write = 0x00;
		   break;
		 */

	default:
		MISSING_CASE;
	}

	line6pcm = kzalloc(sizeof(struct snd_line6_pcm), GFP_KERNEL);

	if (line6pcm == NULL)
		return -ENOMEM;

	line6pcm->volume_playback[0] = line6pcm->volume_playback[1] = 255;
	line6pcm->volume_monitor = 255;
	line6pcm->line6 = line6;
	line6pcm->ep_audio_read = ep_read;
	line6pcm->ep_audio_write = ep_write;

	/* Read and write buffers are sized identically, so choose minimum */
	line6pcm->max_packet_size = min(
			usb_maxpacket(line6->usbdev,
				usb_rcvisocpipe(line6->usbdev, ep_read), 0),
			usb_maxpacket(line6->usbdev,
				usb_sndisocpipe(line6->usbdev, ep_write), 1));

	line6pcm->properties = properties;
	line6->line6pcm = line6pcm;

	/* PCM device: */
	err = snd_device_new(line6->card, SNDRV_DEV_PCM, line6, &pcm_ops);
	if (err < 0)
		return err;

	snd_card_set_dev(line6->card, line6->ifcdev);

	err = snd_line6_new_pcm(line6pcm);
	if (err < 0)
		return err;

	spin_lock_init(&line6pcm->lock_audio_out);
	spin_lock_init(&line6pcm->lock_audio_in);
	spin_lock_init(&line6pcm->lock_trigger);

	err = line6_create_audio_out_urbs(line6pcm);
	if (err < 0)
		return err;

	err = line6_create_audio_in_urbs(line6pcm);
	if (err < 0)
		return err;

	/* mixer: */
	err =
	    snd_ctl_add(line6->card,
			snd_ctl_new1(&line6_control_playback, line6pcm));
	if (err < 0)
		return err;

#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE
	/* impulse response test: */
	err = device_create_file(line6->ifcdev, &dev_attr_impulse_volume);
	if (err < 0)
		return err;

	err = device_create_file(line6->ifcdev, &dev_attr_impulse_period);
	if (err < 0)
		return err;

	line6pcm->impulse_period = LINE6_IMPULSE_DEFAULT_PERIOD;
#endif

	return 0;
}
static int snd_cs5530_create(struct snd_card *card,
			     struct pci_dev *pci,
			     struct snd_cs5530 **rchip)
{
	struct snd_cs5530 *chip;
	unsigned long sb_base;
	u8 irq, dma8, dma16 = 0;
	u16 map;
	void __iomem *mem;
	int err;

	static struct snd_device_ops ops = {
		.dev_free = snd_cs5530_dev_free,
	};
	*rchip = NULL;

	err = pci_enable_device(pci);
 	if (err < 0)
		return err;

	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
	if (chip == NULL) {
		pci_disable_device(pci);
		return -ENOMEM;
	}

	chip->card = card;
	chip->pci = pci;

	err = pci_request_regions(pci, "CS5530");
	if (err < 0) {
		kfree(chip); 
		pci_disable_device(pci);
		return err;
	}
	chip->pci_base = pci_resource_start(pci, 0);

	mem = pci_ioremap_bar(pci, 0);
	if (mem == NULL) {
		snd_cs5530_free(chip);
		return -EBUSY;
	}

	map = readw(mem + 0x18);
	iounmap(mem);

	/* Map bits
		0:1	* 0x20 + 0x200 = sb base
		2	sb enable
		3	adlib enable
		5	MPU enable 0x330
		6	MPU enable 0x300

	   The other bits may be used internally so must be masked */

	sb_base = 0x220 + 0x20 * (map & 3);

	if (map & (1<<2))
		printk(KERN_INFO "CS5530: XpressAudio at 0x%lx\n", sb_base);
	else {
		printk(KERN_ERR "Could not find XpressAudio!\n");
		snd_cs5530_free(chip);
		return -ENODEV;
	}

	if (map & (1<<5))
		printk(KERN_INFO "CS5530: MPU at 0x300\n");
	else if (map & (1<<6))
		printk(KERN_INFO "CS5530: MPU at 0x330\n");

	irq = snd_cs5530_mixer_read(sb_base, 0x80) & 0x0F;
	dma8 = snd_cs5530_mixer_read(sb_base, 0x81);

	if (dma8 & 0x20)
		dma16 = 5;
	else if (dma8 & 0x40)
		dma16 = 6;
	else if (dma8 & 0x80)
		dma16 = 7;
	else {
		printk(KERN_ERR "CS5530: No 16bit DMA enabled\n");
		snd_cs5530_free(chip);
		return -ENODEV;
	}

	if (dma8 & 0x01)
		dma8 = 0;
	else if (dma8 & 02)
		dma8 = 1;
	else if (dma8 & 0x08)
		dma8 = 3;
	else {
		printk(KERN_ERR "CS5530: No 8bit DMA enabled\n");
		snd_cs5530_free(chip);
		return -ENODEV;
	}

	if (irq & 1)
		irq = 9;
	else if (irq & 2)
		irq = 5;
	else if (irq & 4)
		irq = 7;
	else if (irq & 8)
		irq = 10;
	else {
		printk(KERN_ERR "CS5530: SoundBlaster IRQ not set\n");
		snd_cs5530_free(chip);
		return -ENODEV;
	}

	printk(KERN_INFO "CS5530: IRQ: %d DMA8: %d DMA16: %d\n", irq, dma8, 
									dma16);

	err = snd_sbdsp_create(card, sb_base, irq, snd_sb16dsp_interrupt, dma8,
						dma16, SB_HW_CS5530, &chip->sb);
	if (err < 0) {
		printk(KERN_ERR "CS5530: Could not create SoundBlaster\n");
		snd_cs5530_free(chip);
		return err;
	}

	err = snd_sb16dsp_pcm(chip->sb, 0, &chip->sb->pcm);
	if (err < 0) {
		printk(KERN_ERR "CS5530: Could not create PCM\n");
		snd_cs5530_free(chip);
		return err;
	}

	err = snd_sbmixer_new(chip->sb);
	if (err < 0) {
		printk(KERN_ERR "CS5530: Could not create Mixer\n");
		snd_cs5530_free(chip);
		return err;
	}

	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
	if (err < 0) {
		snd_cs5530_free(chip);
		return err;
	}

	snd_card_set_dev(card, &pci->dev);
	*rchip = chip;
	return 0;
}
Example #29
0
// chip-specific constructor
// (see "Management of Cards and Components")
static int __devinit
snd_vortex_create(snd_card_t * card, struct pci_dev *pci, vortex_t ** rchip)
{
	vortex_t *chip;
	int err;
	static snd_device_ops_t ops = {
		.dev_free = snd_vortex_dev_free,
	};

	*rchip = NULL;

	// check PCI availability (DMA).
	if ((err = pci_enable_device(pci)) < 0)
		return err;
	if (!pci_dma_supported(pci, VORTEX_DMA_MASK)) {
		printk(KERN_ERR "error to set DMA mask\n");
		return -ENXIO;
	}
	pci_set_dma_mask(pci, VORTEX_DMA_MASK);

	chip = kcalloc(1, sizeof(*chip), GFP_KERNEL);
	if (chip == NULL)
		return -ENOMEM;

	chip->card = card;

	// initialize the stuff
	chip->pci_dev = pci;
	chip->io = pci_resource_start(pci, 0);
	chip->vendor = pci->vendor;
	chip->device = pci->device;
	chip->card = card;
	chip->irq = -1;

	// (1) PCI resource allocation
	// Get MMIO area
	//
	if ((err = pci_request_regions(pci, CARD_NAME_SHORT)) != 0)
		goto regions_out;

	chip->mmio = ioremap_nocache(pci_resource_start(pci, 0),
	                             pci_resource_len(pci, 0));
	if (!chip->mmio) {
		printk(KERN_ERR "MMIO area remap failed.\n");
		err = -ENOMEM;
		goto ioremap_out;
	}

	/* Init audio core.
	 * This must be done before we do request_irq otherwise we can get spurious
	 * interupts that we do not handle properly and make a mess of things */
	if ((err = vortex_core_init(chip)) != 0) {
		printk(KERN_ERR "hw core init failed\n");
		goto core_out;
	}

	if ((err = request_irq(pci->irq, vortex_interrupt,
	                       SA_INTERRUPT | SA_SHIRQ, CARD_NAME_SHORT,
	                       chip)) != 0) {
		printk(KERN_ERR "cannot grab irq\n");
		goto irq_out;
	}
	chip->irq = pci->irq;

	pci_set_master(pci);
	// End of PCI setup.

	// Register alsa root device.
	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
		goto alloc_out;
	}

	*rchip = chip;

	return 0;

      alloc_out:
	synchronize_irq(chip->irq);
	free_irq(chip->irq, chip);
      irq_out:
	vortex_core_shutdown(chip);
      core_out:
	iounmap(chip->mmio);
      ioremap_out:
	pci_release_regions(chip->pci_dev);
      regions_out:
	pci_disable_device(chip->pci_dev);
	//FIXME: this not the right place to unregister the gameport
	vortex_gameport_unregister(chip);
	return err;
}
Example #30
0
static int __devinit snd_via82xx_create(struct snd_card *card,
					struct pci_dev *pci,
					int chip_type,
					int revision,
					unsigned int ac97_clock,
					struct via82xx_modem ** r_via)
{
	struct via82xx_modem *chip;
	int err;
        static struct snd_device_ops ops = {
		.dev_free =	snd_via82xx_dev_free,
        };

	if ((err = pci_enable_device(pci)) < 0)
		return err;

	if ((chip = kzalloc(sizeof(*chip), GFP_KERNEL)) == NULL) {
		pci_disable_device(pci);
		return -ENOMEM;
	}

	spin_lock_init(&chip->reg_lock);
	chip->card = card;
	chip->pci = pci;
	chip->irq = -1;

	if ((err = pci_request_regions(pci, card->driver)) < 0) {
		kfree(chip);
		pci_disable_device(pci);
		return err;
	}
	chip->port = pci_resource_start(pci, 0);
	if (request_irq(pci->irq, snd_via82xx_interrupt, IRQF_SHARED,
			card->driver, chip)) {
		snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
		snd_via82xx_free(chip);
		return -EBUSY;
	}
	chip->irq = pci->irq;
	if (ac97_clock >= 8000 && ac97_clock <= 48000)
		chip->ac97_clock = ac97_clock;
	synchronize_irq(chip->irq);

	if ((err = snd_via82xx_chip_init(chip)) < 0) {
		snd_via82xx_free(chip);
		return err;
	}

	if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
		snd_via82xx_free(chip);
		return err;
	}

	/* The 8233 ac97 controller does not implement the master bit
	 * in the pci command register. IMHO this is a violation of the PCI spec.
	 * We call pci_set_master here because it does not hurt. */
	pci_set_master(pci);

	snd_card_set_dev(card, &pci->dev);

	*r_via = chip;
	return 0;
}