// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Support for Digigram Lola PCI-e boards
 *
 *  Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/pcm.h>
#include <sound/initval.h>
#include "lola.h"

/* Standard options */
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;

module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Digigram Lola driver.");
module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for Digigram Lola driver.");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable Digigram Lola driver.");

/* Lola-specific options */

/* for instance use always max granularity which is compatible
 * with all sample rates
 */
static int granularity[SNDRV_CARDS] = {
	[0 ... (SNDRV_CARDS - 1)] = LOLA_GRANULARITY_MAX
};

/* below a sample_rate of 16kHz the analogue audio quality is NOT excellent */
static int sample_rate_min[SNDRV_CARDS] = {
	[0 ... (SNDRV_CARDS - 1) ] = 16000
};

module_param_array(granularity, int, NULL, 0444);
MODULE_PARM_DESC(granularity, "Granularity value");
module_param_array(sample_rate_min, int, NULL, 0444);
MODULE_PARM_DESC(sample_rate_min, "Minimal sample rate");

/*
 */

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Digigram Lola driver");
MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");

#ifdef CONFIG_SND_DEBUG_VERBOSE
static int debug;
module_param(debug, int, 0644);
#define verbose_debug(fmt, args...)			\
	do { if (debug > 1) pr_debug(SFX fmt, ##args); } while (0)
#else
#define verbose_debug(fmt, args...)
#endif

/*
 * pseudo-codec read/write via CORB/RIRB
 */

static int corb_send_verb(struct lola *chip, unsigned int nid,
			  unsigned int verb, unsigned int data,
			  unsigned int extdata)
{
	unsigned long flags;
	int ret = -EIO;

	chip->last_cmd_nid = nid;
	chip->last_verb = verb;
	chip->last_data = data;
	chip->last_extdata = extdata;
	data |= (nid << 20) | (verb << 8);

	spin_lock_irqsave(&chip->reg_lock, flags);
	if (chip->rirb.cmds < LOLA_CORB_ENTRIES - 1) {
		unsigned int wp = chip->corb.wp + 1;
		wp %= LOLA_CORB_ENTRIES;
		chip->corb.wp = wp;
		chip->corb.buf[wp * 2] = cpu_to_le32(data);
		chip->corb.buf[wp * 2 + 1] = cpu_to_le32(extdata);
		lola_writew(chip, BAR0, CORBWP, wp);
		chip->rirb.cmds++;
		smp_wmb();
		ret = 0;
	}
	spin_unlock_irqrestore(&chip->reg_lock, flags);
	return ret;
}

static void lola_queue_unsol_event(struct lola *chip, unsigned int res,
				   unsigned int res_ex)
{
	lola_update_ext_clock_freq(chip, res);
}

/* retrieve RIRB entry - called from interrupt handler */
static void lola_update_rirb(struct lola *chip)
{
	unsigned int rp, wp;
	u32 res, res_ex;

	wp = lola_readw(chip, BAR0, RIRBWP);
	if (wp == chip->rirb.wp)
		return;
	chip->rirb.wp = wp;

	while (chip->rirb.rp != wp) {
		chip->rirb.rp++;
		chip->rirb.rp %= LOLA_CORB_ENTRIES;

		rp = chip->rirb.rp << 1; /* an RIRB entry is 8-bytes */
		res_ex = le32_to_cpu(chip->rirb.buf[rp + 1]);
		res = le32_to_cpu(chip->rirb.buf[rp]);
		if (res_ex & LOLA_RIRB_EX_UNSOL_EV)
			lola_queue_unsol_event(chip, res, res_ex);
		else if (chip->rirb.cmds) {
			chip->res = res;
			chip->res_ex = res_ex;
			smp_wmb();
			chip->rirb.cmds--;
		}
	}
}

static int rirb_get_response(struct lola *chip, unsigned int *val,
			     unsigned int *extval)
{
	unsigned long timeout;

 again:
	timeout = jiffies + msecs_to_jiffies(1000);
	for (;;) {
		if (chip->polling_mode) {
			spin_lock_irq(&chip->reg_lock);
			lola_update_rirb(chip);
			spin_unlock_irq(&chip->reg_lock);
		}
		if (!chip->rirb.cmds) {
			*val = chip->res;
			if (extval)
				*extval = chip->res_ex;
			verbose_debug("get_response: %x, %x\n",
				      chip->res, chip->res_ex);
			if (chip->res_ex & LOLA_RIRB_EX_ERROR) {
				dev_warn(chip->card->dev, "RIRB ERROR: "
				       "NID=%x, verb=%x, data=%x, ext=%x\n",
				       chip->last_cmd_nid,
				       chip->last_verb, chip->last_data,
				       chip->last_extdata);
				return -EIO;
			}
			return 0;
		}
		if (time_after(jiffies, timeout))
			break;
		udelay(20);
		cond_resched();
	}
	dev_warn(chip->card->dev, "RIRB response error\n");
	if (!chip->polling_mode) {
		dev_warn(chip->card->dev, "switching to polling mode\n");
		chip->polling_mode = 1;
		goto again;
	}
	return -EIO;
}

/* aynchronous write of a codec verb with data */
int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb,
		     unsigned int data, unsigned int extdata)
{
	verbose_debug("codec_write NID=%x, verb=%x, data=%x, ext=%x\n",
		      nid, verb, data, extdata);
	return corb_send_verb(chip, nid, verb, data, extdata);
}

/* write a codec verb with data and read the returned status */
int lola_codec_read(struct lola *chip, unsigned int nid, unsigned int verb,
		    unsigned int data, unsigned int extdata,
		    unsigned int *val, unsigned int *extval)
{
	int err;

	verbose_debug("codec_read NID=%x, verb=%x, data=%x, ext=%x\n",
		      nid, verb, data, extdata);
	err = corb_send_verb(chip, nid, verb, data, extdata);
	if (err < 0)
		return err;
	err = rirb_get_response(chip, val, extval);
	return err;
}

/* flush all pending codec writes */
int lola_codec_flush(struct lola *chip)
{
	unsigned int tmp;
	return rirb_get_response(chip, &tmp, NULL);
}

/*
 * interrupt handler
 */
static irqreturn_t lola_interrupt(int irq, void *dev_id)
{
	struct lola *chip = dev_id;
	unsigned int notify_ins, notify_outs, error_ins, error_outs;
	int handled = 0;
	int i;

	notify_ins = notify_outs = error_ins = error_outs = 0;
	spin_lock(&chip->reg_lock);
	for (;;) {
		unsigned int status, in_sts, out_sts;
		unsigned int reg;

		status = lola_readl(chip, BAR1, DINTSTS);
		if (!status || status == -1)
			break;

		in_sts = lola_readl(chip, BAR1, DIINTSTS);
		out_sts = lola_readl(chip, BAR1, DOINTSTS);

		/* clear Input Interrupts */
		for (i = 0; in_sts && i < chip->pcm[CAPT].num_streams; i++) {
			if (!(in_sts & (1 << i)))
				continue;
			in_sts &= ~(1 << i);
			reg = lola_dsd_read(chip, i, STS);
			if (reg & LOLA_DSD_STS_DESE) /* error */
				error_ins |= (1 << i);
			if (reg & LOLA_DSD_STS_BCIS) /* notify */
				notify_ins |= (1 << i);
			/* clear */
			lola_dsd_write(chip, i, STS, reg);
		}

		/* clear Output Interrupts */
		for (i = 0; out_sts && i < chip->pcm[PLAY].num_streams; i++) {
			if (!(out_sts & (1 << i)))
				continue;
			out_sts &= ~(1 << i);
			reg = lola_dsd_read(chip, i + MAX_STREAM_IN_COUNT, STS);
			if (reg & LOLA_DSD_STS_DESE) /* error */
				error_outs |= (1 << i);
			if (reg & LOLA_DSD_STS_BCIS) /* notify */
				notify_outs |= (1 << i);
			lola_dsd_write(chip, i + MAX_STREAM_IN_COUNT, STS, reg);
		}

		if (status & LOLA_DINT_CTRL) {
			unsigned char rbsts; /* ring status is byte access */
			rbsts = lola_readb(chip, BAR0, RIRBSTS);
			rbsts &= LOLA_RIRB_INT_MASK;
			if (rbsts)
				lola_writeb(chip, BAR0, RIRBSTS, rbsts);
			rbsts = lola_readb(chip, BAR0, CORBSTS);
			rbsts &= LOLA_CORB_INT_MASK;
			if (rbsts)
				lola_writeb(chip, BAR0, CORBSTS, rbsts);

			lola_update_rirb(chip);
		}

		if (status & (LOLA_DINT_FIFOERR | LOLA_DINT_MUERR)) {
			/* clear global fifo error interrupt */
			lola_writel(chip, BAR1, DINTSTS,
				    (status & (LOLA_DINT_FIFOERR | LOLA_DINT_MUERR)));
		}
		handled = 1;
	}
	spin_unlock(&chip->reg_lock);

	lola_pcm_update(chip, &chip->pcm[CAPT], notify_ins);
	lola_pcm_update(chip, &chip->pcm[PLAY], notify_outs);

	return IRQ_RETVAL(handled);
}


/*
 * controller
 */
static int reset_controller(struct lola *chip)
{
	unsigned int gctl = lola_readl(chip, BAR0, GCTL);
	unsigned long end_time;

	if (gctl) {
		/* to be sure */
		lola_writel(chip, BAR1, BOARD_MODE, 0);
		return 0;
	}

	chip->cold_reset = 1;
	lola_writel(chip, BAR0, GCTL, LOLA_GCTL_RESET);
	end_time = jiffies + msecs_to_jiffies(200);
	do {
		msleep(1);
		gctl = lola_readl(chip, BAR0, GCTL);
		if (gctl)
			break;
	} while (time_before(jiffies, end_time));
	if (!gctl) {
		dev_err(chip->card->dev, "cannot reset controller\n");
		return -EIO;
	}
	return 0;
}

static void lola_irq_enable(struct lola *chip)
{
	unsigned int val;

	/* enalbe all I/O streams */
	val = (1 << chip->pcm[PLAY].num_streams) - 1;
	lola_writel(chip, BAR1, DOINTCTL, val);
	val = (1 << chip->pcm[CAPT].num_streams) - 1;
	lola_writel(chip, BAR1, DIINTCTL, val);

	/* enable global irqs */
	val = LOLA_DINT_GLOBAL | LOLA_DINT_CTRL | LOLA_DINT_FIFOERR |
		LOLA_DINT_MUERR;
	lola_writel(chip, BAR1, DINTCTL, val);
}

static void lola_irq_disable(struct lola *chip)
{
	lola_writel(chip, BAR1, DINTCTL, 0);
	lola_writel(chip, BAR1, DIINTCTL, 0);
	lola_writel(chip, BAR1, DOINTCTL, 0);
}

static int setup_corb_rirb(struct lola *chip)
{
	int err;
	unsigned char tmp;
	unsigned long end_time;

	err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV,
				  &chip->pci->dev,
				  PAGE_SIZE, &chip->rb);
	if (err < 0)
		return err;

	chip->corb.addr = chip->rb.addr;
	chip->corb.buf = (__le32 *)chip->rb.area;
	chip->rirb.addr = chip->rb.addr + 2048;
	chip->rirb.buf = (__le32 *)(chip->rb.area + 2048);

	/* disable ringbuffer DMAs */
	lola_writeb(chip, BAR0, RIRBCTL, 0);
	lola_writeb(chip, BAR0, CORBCTL, 0);

	end_time = jiffies + msecs_to_jiffies(200);
	do {
		if (!lola_readb(chip, BAR0, RIRBCTL) &&
		    !lola_readb(chip, BAR0, CORBCTL))
			break;
		msleep(1);
	} while (time_before(jiffies, end_time));

	/* CORB set up */
	lola_writel(chip, BAR0, CORBLBASE, (u32)chip->corb.addr);
	lola_writel(chip, BAR0, CORBUBASE, upper_32_bits(chip->corb.addr));
	/* set the corb size to 256 entries */
	lola_writeb(chip, BAR0, CORBSIZE, 0x02);
	/* set the corb write pointer to 0 */
	lola_writew(chip, BAR0, CORBWP, 0);
	/* reset the corb hw read pointer */
	lola_writew(chip, BAR0, CORBRP, LOLA_RBRWP_CLR);
	/* enable corb dma */
	lola_writeb(chip, BAR0, CORBCTL, LOLA_RBCTL_DMA_EN);
	/* clear flags if set */
	tmp = lola_readb(chip, BAR0, CORBSTS) & LOLA_CORB_INT_MASK;
	if (tmp)
		lola_writeb(chip, BAR0, CORBSTS, tmp);
	chip->corb.wp = 0;

	/* RIRB set up */
	lola_writel(chip, BAR0, RIRBLBASE, (u32)chip->rirb.addr);
	lola_writel(chip, BAR0, RIRBUBASE, upper_32_bits(chip->rirb.addr));
	/* set the rirb size to 256 entries */
	lola_writeb(chip, BAR0, RIRBSIZE, 0x02);
	/* reset the rirb hw write pointer */
	lola_writew(chip, BAR0, RIRBWP, LOLA_RBRWP_CLR);
	/* set N=1, get RIRB response interrupt for new entry */
	lola_writew(chip, BAR0, RINTCNT, 1);
	/* enable rirb dma and response irq */
	lola_writeb(chip, BAR0, RIRBCTL, LOLA_RBCTL_DMA_EN | LOLA_RBCTL_IRQ_EN);
	/* clear flags if set */
	tmp =  lola_readb(chip, BAR0, RIRBSTS) & LOLA_RIRB_INT_MASK;
	if (tmp)
		lola_writeb(chip, BAR0, RIRBSTS, tmp);
	chip->rirb.rp = chip->rirb.cmds = 0;

	return 0;
}

static void stop_corb_rirb(struct lola *chip)
{
	/* disable ringbuffer DMAs */
	lola_writeb(chip, BAR0, RIRBCTL, 0);
	lola_writeb(chip, BAR0, CORBCTL, 0);
}

static void lola_reset_setups(struct lola *chip)
{
	/* update the granularity */
	lola_set_granularity(chip, chip->granularity, true);
	/* update the sample clock */
	lola_set_clock_index(chip, chip->clock.cur_index);
	/* enable unsolicited events of the clock widget */
	lola_enable_clock_events(chip);
	/* update the analog gains */
	lola_setup_all_analog_gains(chip, CAPT, false); /* input, update */
	/* update SRC configuration if applicable */
	lola_set_src_config(chip, chip->input_src_mask, false);
	/* update the analog outputs */
	lola_setup_all_analog_gains(chip, PLAY, false); /* output, update */
}

static int lola_parse_tree(struct lola *chip)
{
	unsigned int val;
	int nid, err;

	err = lola_read_param(chip, 0, LOLA_PAR_VENDOR_ID, &val);
	if (err < 0) {
		dev_err(chip->card->dev, "Can't read VENDOR_ID\n");
		return err;
	}
	val >>= 16;
	if (val != 0x1369) {
		dev_err(chip->card->dev, "Unknown codec vendor 0x%x\n", val);
		return -EINVAL;
	}

	err = lola_read_param(chip, 1, LOLA_PAR_FUNCTION_TYPE, &val);
	if (err < 0) {
		dev_err(chip->card->dev, "Can't read FUNCTION_TYPE\n");
		return err;
	}
	if (val != 1) {
		dev_err(chip->card->dev, "Unknown function type %d\n", val);
		return -EINVAL;
	}

	err = lola_read_param(chip, 1, LOLA_PAR_SPECIFIC_CAPS, &val);
	if (err < 0) {
		dev_err(chip->card->dev, "Can't read SPECCAPS\n");
		return err;
	}
	chip->lola_caps = val;
	chip->pin[CAPT].num_pins = LOLA_AFG_INPUT_PIN_COUNT(chip->lola_caps);
	chip->pin[PLAY].num_pins = LOLA_AFG_OUTPUT_PIN_COUNT(chip->lola_caps);
	dev_dbg(chip->card->dev, "speccaps=0x%x, pins in=%d, out=%d\n",
		    chip->lola_caps,
		    chip->pin[CAPT].num_pins, chip->pin[PLAY].num_pins);

	if (chip->pin[CAPT].num_pins > MAX_AUDIO_INOUT_COUNT ||
	    chip->pin[PLAY].num_pins > MAX_AUDIO_INOUT_COUNT) {
		dev_err(chip->card->dev, "Invalid Lola-spec caps 0x%x\n", val);
		return -EINVAL;
	}

	nid = 0x02;
	err = lola_init_pcm(chip, CAPT, &nid);
	if (err < 0)
		return err;
	err = lola_init_pcm(chip, PLAY, &nid);
	if (err < 0)
		return err;

	err = lola_init_pins(chip, CAPT, &nid);
	if (err < 0)
		return err;
	err = lola_init_pins(chip, PLAY, &nid);
	if (err < 0)
		return err;

	if (LOLA_AFG_CLOCK_WIDGET_PRESENT(chip->lola_caps)) {
		err = lola_init_clock_widget(chip, nid);
		if (err < 0)
			return err;
		nid++;
	}
	if (LOLA_AFG_MIXER_WIDGET_PRESENT(chip->lola_caps)) {
		err = lola_init_mixer_widget(chip, nid);
		if (err < 0)
			return err;
		nid++;
	}

	/* enable unsolicited events of the clock widget */
	err = lola_enable_clock_events(chip);
	if (err < 0)
		return err;

	/* if last ResetController was not a ColdReset, we don't know
	 * the state of the card; initialize here again
	 */
	if (!chip->cold_reset) {
		lola_reset_setups(chip);
		chip->cold_reset = 1;
	} else {
		/* set the granularity if it is not the default */
		if (chip->granularity != LOLA_GRANULARITY_MIN)
			lola_set_granularity(chip, chip->granularity, true);
	}

	return 0;
}

static void lola_stop_hw(struct lola *chip)
{
	stop_corb_rirb(chip);
	lola_irq_disable(chip);
}

static void lola_free(struct lola *chip)
{
	if (chip->initialized)
		lola_stop_hw(chip);
	lola_free_pcm(chip);
	lola_free_mixer(chip);
	if (chip->irq >= 0)
		free_irq(chip->irq, (void *)chip);
	iounmap(chip->bar[0].remap_addr);
	iounmap(chip->bar[1].remap_addr);
	if (chip->rb.area)
		snd_dma_free_pages(&chip->rb);
	pci_release_regions(chip->pci);
	pci_disable_device(chip->pci);
	kfree(chip);
}

static int lola_dev_free(struct snd_device *device)
{
	lola_free(device->device_data);
	return 0;
}

static int lola_create(struct snd_card *card, struct pci_dev *pci,
		       int dev, struct lola **rchip)
{
	struct lola *chip;
	int err;
	unsigned int dever;
	static const struct snd_device_ops ops = {
		.dev_free = lola_dev_free,
	};

	*rchip = NULL;

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

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

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

	chip->granularity = granularity[dev];
	switch (chip->granularity) {
	case 8:
		chip->sample_rate_max = 48000;
		break;
	case 16:
		chip->sample_rate_max = 96000;
		break;
	case 32:
		chip->sample_rate_max = 192000;
		break;
	default:
		dev_warn(chip->card->dev,
			   "Invalid granularity %d, reset to %d\n",
			   chip->granularity, LOLA_GRANULARITY_MAX);
		chip->granularity = LOLA_GRANULARITY_MAX;
		chip->sample_rate_max = 192000;
		break;
	}
	chip->sample_rate_min = sample_rate_min[dev];
	if (chip->sample_rate_min > chip->sample_rate_max) {
		dev_warn(chip->card->dev,
			   "Invalid sample_rate_min %d, reset to 16000\n",
			   chip->sample_rate_min);
		chip->sample_rate_min = 16000;
	}

	err = pci_request_regions(pci, DRVNAME);
	if (err < 0) {
		kfree(chip);
		pci_disable_device(pci);
		return err;
	}

	chip->bar[0].addr = pci_resource_start(pci, 0);
	chip->bar[0].remap_addr = pci_ioremap_bar(pci, 0);
	chip->bar[1].addr = pci_resource_start(pci, 2);
	chip->bar[1].remap_addr = pci_ioremap_bar(pci, 2);
	if (!chip->bar[0].remap_addr || !chip->bar[1].remap_addr) {
		dev_err(chip->card->dev, "ioremap error\n");
		err = -ENXIO;
		goto errout;
	}

	pci_set_master(pci);

	err = reset_controller(chip);
	if (err < 0)
		goto errout;

	if (request_irq(pci->irq, lola_interrupt, IRQF_SHARED,
			KBUILD_MODNAME, chip)) {
		dev_err(chip->card->dev, "unable to grab IRQ %d\n", pci->irq);
		err = -EBUSY;
		goto errout;
	}
	chip->irq = pci->irq;
	card->sync_irq = chip->irq;

	dever = lola_readl(chip, BAR1, DEVER);
	chip->pcm[CAPT].num_streams = (dever >> 0) & 0x3ff;
	chip->pcm[PLAY].num_streams = (dever >> 10) & 0x3ff;
	chip->version = (dever >> 24) & 0xff;
	dev_dbg(chip->card->dev, "streams in=%d, out=%d, version=0x%x\n",
		    chip->pcm[CAPT].num_streams, chip->pcm[PLAY].num_streams,
		    chip->version);

	/* Test LOLA_BAR1_DEVER */
	if (chip->pcm[CAPT].num_streams > MAX_STREAM_IN_COUNT ||
	    chip->pcm[PLAY].num_streams > MAX_STREAM_OUT_COUNT ||
	    (!chip->pcm[CAPT].num_streams &&
	     !chip->pcm[PLAY].num_streams)) {
		dev_err(chip->card->dev, "invalid DEVER = %x\n", dever);
		err = -EINVAL;
		goto errout;
	}

	err = setup_corb_rirb(chip);
	if (err < 0)
		goto errout;

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

	strcpy(card->driver, "Lola");
	strscpy(card->shortname, "Digigram Lola", sizeof(card->shortname));
	snprintf(card->longname, sizeof(card->longname),
		 "%s at 0x%lx irq %i",
		 card->shortname, chip->bar[0].addr, chip->irq);
	strcpy(card->mixername, card->shortname);

	lola_irq_enable(chip);

	chip->initialized = 1;
	*rchip = chip;
	return 0;

 errout:
	lola_free(chip);
	return err;
}

static int lola_probe(struct pci_dev *pci,
		      const struct pci_device_id *pci_id)
{
	static int dev;
	struct snd_card *card;
	struct lola *chip;
	int err;

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

	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
			   0, &card);
	if (err < 0) {
		dev_err(&pci->dev, "Error creating card!\n");
		return err;
	}

	err = lola_create(card, pci, dev, &chip);
	if (err < 0)
		goto out_free;
	card->private_data = chip;

	err = lola_parse_tree(chip);
	if (err < 0)
		goto out_free;

	err = lola_create_pcm(chip);
	if (err < 0)
		goto out_free;

	err = lola_create_mixer(chip);
	if (err < 0)
		goto out_free;

	lola_proc_debug_new(chip);

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

	pci_set_drvdata(pci, card);
	dev++;
	return err;
out_free:
	snd_card_free(card);
	return err;
}

static void lola_remove(struct pci_dev *pci)
{
	snd_card_free(pci_get_drvdata(pci));
}

/* PCI IDs */
static const struct pci_device_id lola_ids[] = {
	{ PCI_VDEVICE(DIGIGRAM, 0x0001) },
	{ 0, }
};
MODULE_DEVICE_TABLE(pci, lola_ids);

/* pci_driver definition */
static struct pci_driver lola_driver = {
	.name = KBUILD_MODNAME,
	.id_table = lola_ids,
	.probe = lola_probe,
	.remove = lola_remove,
};

module_pci_driver(lola_driver);
