/*
 *  Support for Digigram Lola PCI-e boards
 *
 *  Copyright (c) 2011 Takashi Iwai <tiwai@suse.de>
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under the terms of the GNU General Public License as published by the Free
 *  Software Foundation; either version 2 of the License, or (at your option)
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 *  more details.
 *
 *  You should have received a copy of the GNU General Public License along with
 *  this program; if not, write to the Free Software Foundation, Inc., 59
 *  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/moduleparam.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 int 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_SUPPORTED_DEVICE("{{Digigram, Lola}}");
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) printk(KERN_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) {
				printk(KERN_WARNING SFX "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();
	}
	printk(KERN_WARNING SFX "RIRB response error\n");
	if (!chip->polling_mode) {
		printk(KERN_WARNING SFX "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) {
		printk(KERN_ERR SFX "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,
				  snd_dma_pci_data(chip->pci),
				  PAGE_SIZE, &chip->rb);
	if (err < 0)
		return err;

	chip->corb.addr = chip->rb.addr;
	chip->corb.buf = (u32 *)chip->rb.area;
	chip->rirb.addr = chip->rb.addr + 2048;
	chip->rirb.buf = (u32 *)(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) {
		printk(KERN_ERR SFX "Can't read VENDOR_ID\n");
		return err;
	}
	val >>= 16;
	if (val != 0x1369) {
		printk(KERN_ERR SFX "Unknown codec vendor 0x%x\n", val);
		return -EINVAL;
	}

	err = lola_read_param(chip, 1, LOLA_PAR_FUNCTION_TYPE, &val);
	if (err < 0) {
		printk(KERN_ERR SFX "Can't read FUNCTION_TYPE for 0x%x\n", nid);
		return err;
	}
	if (val != 1) {
		printk(KERN_ERR SFX "Unknown function type %d\n", val);
		return -EINVAL;
	}

	err = lola_read_param(chip, 1, LOLA_PAR_SPECIFIC_CAPS, &val);
	if (err < 0) {
		printk(KERN_ERR SFX "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);
	snd_printdd(SFX "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) {
		printk(KERN_ERR SFX "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);
	if (chip->bar[0].remap_addr)
		iounmap(chip->bar[0].remap_addr);
	if (chip->bar[1].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 __devinit lola_create(struct snd_card *card, struct pci_dev *pci,
				 int dev, struct lola **rchip)
{
	struct lola *chip;
	int err;
	unsigned int dever;
	static 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) {
		snd_printk(KERN_ERR SFX "cannot allocate chip\n");
		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:
		snd_printk(KERN_WARNING SFX
			   "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) {
		snd_printk(KERN_WARNING SFX
			   "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) {
		snd_printk(KERN_ERR SFX "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,
			DRVNAME, chip)) {
		printk(KERN_ERR SFX "unable to grab IRQ %d\n", pci->irq);
		err = -EBUSY;
		goto errout;
	}
	chip->irq = pci->irq;
	synchronize_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;
	snd_printdd(SFX "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)) {
		printk(KERN_ERR SFX "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) {
		snd_printk(KERN_ERR SFX "Error creating device [card]!\n");
		goto errout;
	}

	strcpy(card->driver, "Lola");
	strlcpy(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 __devinit 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_create(index[dev], id[dev], THIS_MODULE, 0, &card);
	if (err < 0) {
		snd_printk(KERN_ERR SFX "Error creating card!\n");
		return err;
	}

	snd_card_set_dev(card, &pci->dev);

	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 __devexit lola_remove(struct pci_dev *pci)
{
	snd_card_free(pci_get_drvdata(pci));
	pci_set_drvdata(pci, NULL);
}

/* PCI IDs */
static DEFINE_PCI_DEVICE_TABLE(lola_ids) = {
	{ PCI_VDEVICE(DIGIGRAM, 0x0001) },
	{ 0, }
};
MODULE_DEVICE_TABLE(pci, lola_ids);

/* pci_driver definition */
static struct pci_driver driver = {
	.name = DRVNAME,
	.id_table = lola_ids,
	.probe = lola_probe,
	.remove = __devexit_p(lola_remove),
};

static int __init alsa_card_lola_init(void)
{
	return pci_register_driver(&driver);
}

static void __exit alsa_card_lola_exit(void)
{
	pci_unregister_driver(&driver);
}

module_init(alsa_card_lola_init)
module_exit(alsa_card_lola_exit)
