/* 
 * Audio driver for the NeoMagic 256AV and 256ZX chipsets in native
 * mode, with AC97 mixer support.
 *
 * Overall design and parts of this code stolen from vidc_*.c and
 * skeleton.c.
 *
 * Yeah, there are a lot of magic constants in here.  You tell ME what
 * they are.  I just get this stuff psychically, remember? 
 *
 * This driver was written by someone who wishes to remain anonymous. 
 * It is in the public domain, so share and enjoy.  Try to make a profit
 * off of it; go on, I dare you.  
 *
 * Changes:
 * 11-10-2000	Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
 *		Added some __init
 * 19-04-2001	Marcus Meissner <mm@caldera.de>
 *		Ported to 2.4 PCI API.
 */

#include <linux/pci.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include "sound_config.h"

static int nm256_debug;
static int force_load;

#include "nm256.h"
#include "nm256_coeff.h"

/* 
 * The size of the playback reserve.  When the playback buffer has less
 * than NM256_PLAY_WMARK_SIZE bytes to output, we request a new
 * buffer.
 */
#define NM256_PLAY_WMARK_SIZE 512

static struct audio_driver nm256_audio_driver;

static int nm256_grabInterrupt (struct nm256_info *card);
static int nm256_releaseInterrupt (struct nm256_info *card);
static irqreturn_t nm256_interrupt (int irq, void *dev_id);
static irqreturn_t nm256_interrupt_zx (int irq, void *dev_id);

/* These belong in linux/pci.h. */
#define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005
#define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006
#define PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO 0x8016

/* List of cards.  */
static struct nm256_info *nmcard_list;

/* Release the mapped-in memory for CARD.  */
static void
nm256_release_ports (struct nm256_info *card)
{
    int x;

    for (x = 0; x < 2; x++) {
	if (card->port[x].ptr != NULL) {
	    iounmap (card->port[x].ptr);
	    card->port[x].ptr = NULL;
	}
    }
}

/* 
 * Map in the memory ports for CARD, if they aren't already mapped in
 * and have been configured.  If successful, a zero value is returned;
 * otherwise any previously mapped-in areas are released and a non-zero
 * value is returned.
 *
 * This is invoked twice, once for each port.  Ideally it would only be
 * called once, but we now need to map in the second port in order to
 * check how much memory the card has on the 256ZX.
 */
static int
nm256_remap_ports (struct nm256_info *card)
{
    int x;

    for (x = 0; x < 2; x++) {
	if (card->port[x].ptr == NULL && card->port[x].end_offset > 0) {
	    u32 physaddr 
		= card->port[x].physaddr + card->port[x].start_offset;
	    u32 size 
		= card->port[x].end_offset - card->port[x].start_offset;

	    card->port[x].ptr = ioremap_nocache (physaddr, size);
						  
	    if (card->port[x].ptr == NULL) {
		printk (KERN_ERR "NM256: Unable to remap port %d\n", x + 1);
		nm256_release_ports (card);
		return -1;
	    }
	}
    }
    return 0;
}

/* Locate the card in our list. */
static struct nm256_info *
nm256_find_card (int dev)
{
    struct nm256_info *card;

    for (card = nmcard_list; card != NULL; card = card->next_card)
	if (card->dev[0] == dev || card->dev[1] == dev)
	    return card;

    return NULL;
}

/*
 * Ditto, but find the card struct corresponding to the mixer device DEV 
 * instead. 
 */
static struct nm256_info *
nm256_find_card_for_mixer (int dev)
{
    struct nm256_info *card;

    for (card = nmcard_list; card != NULL; card = card->next_card)
	if (card->mixer_oss_dev == dev)
	    return card;

    return NULL;
}

static int usecache;
static int buffertop;

/* Check to see if we're using the bank of cached coefficients. */
static int
nm256_cachedCoefficients (struct nm256_info *card)
{
    return usecache;
}

/* The actual rates supported by the card. */
static int samplerates[9] = {
    8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000, 99999999
};

/*
 * Set the card samplerate, word size and stereo mode to correspond to
 * the settings in the CARD struct for the specified device in DEV.
 * We keep two separate sets of information, one for each device; the
 * hardware is not actually configured until a read or write is
 * attempted.
 */

static int
nm256_setInfo (int dev, struct nm256_info *card)
{
    int x;
    int w;
    int targetrate;

    if (card->dev[0] == dev)
	w = 0;
    else if (card->dev[1] == dev)
	w = 1;
    else
	return -ENODEV;

    targetrate = card->sinfo[w].samplerate;

    if ((card->sinfo[w].bits != 8 && card->sinfo[w].bits != 16)
	|| targetrate < samplerates[0]
	|| targetrate > samplerates[7])
	return -EINVAL;

    for (x = 0; x < 8; x++)
	if (targetrate < ((samplerates[x] + samplerates[x + 1]) / 2))
	    break;

    if (x < 8) {
	u8 ratebits = ((x << 4) & NM_RATE_MASK);
	if (card->sinfo[w].bits == 16)
	    ratebits |= NM_RATE_BITS_16;
	if (card->sinfo[w].stereo)
	    ratebits |= NM_RATE_STEREO;

	card->sinfo[w].samplerate = samplerates[x];


	if (card->dev_for_play == dev && card->playing) {
	    if (nm256_debug)
		printk (KERN_DEBUG "Setting play ratebits to 0x%x\n",
			ratebits);
	    nm256_loadCoefficient (card, 0, x);
	    nm256_writePort8 (card, 2,
			      NM_PLAYBACK_REG_OFFSET + NM_RATE_REG_OFFSET,
			      ratebits);
	}

	if (card->dev_for_record == dev && card->recording) {
	    if (nm256_debug)
		printk (KERN_DEBUG "Setting record ratebits to 0x%x\n",
			ratebits);
	    nm256_loadCoefficient (card, 1, x);
	    nm256_writePort8 (card, 2,
			      NM_RECORD_REG_OFFSET + NM_RATE_REG_OFFSET,
			      ratebits);
	}
	return 0;
    }
    else
	return -EINVAL;
}

/* Start the play process going. */
static void
startPlay (struct nm256_info *card)
{
    if (! card->playing) {
	card->playing = 1;
	if (nm256_grabInterrupt (card) == 0) {
	    nm256_setInfo (card->dev_for_play, card);

	    /* Enable playback engine and interrupts. */
	    nm256_writePort8 (card, 2, NM_PLAYBACK_ENABLE_REG,
			      NM_PLAYBACK_ENABLE_FLAG | NM_PLAYBACK_FREERUN);

	    /* Enable both channels. */
	    nm256_writePort16 (card, 2, NM_AUDIO_MUTE_REG, 0x0);
	}
    }
}

/* 
 * Request one chunk of AMT bytes from the recording device.  When the
 * operation is complete, the data will be copied into BUFFER and the
 * function DMAbuf_inputintr will be invoked.
 */

static void
nm256_startRecording (struct nm256_info *card, char *buffer, u32 amt)
{
    u32 endpos;
    int enableEngine = 0;
    u32 ringsize = card->recordBufferSize;
    unsigned long flags;

    if (amt > (ringsize / 2)) {
	/*
	 * Of course this won't actually work right, because the
	 * caller is going to assume we will give what we got asked
	 * for.
	 */
	printk (KERN_ERR "NM256: Read request too large: %d\n", amt);
	amt = ringsize / 2;
    }

    if (amt < 8) {
	printk (KERN_ERR "NM256: Read request too small; %d\n", amt);
	return;
    }

    spin_lock_irqsave(&card->lock,flags);
    /*
     * If we're not currently recording, set up the start and end registers
     * for the recording engine.
     */
    if (! card->recording) {
	card->recording = 1;
	if (nm256_grabInterrupt (card) == 0) {
	    card->curRecPos = 0;
	    nm256_setInfo (card->dev_for_record, card);
	    nm256_writePort32 (card, 2, NM_RBUFFER_START, card->abuf2);
	    nm256_writePort32 (card, 2, NM_RBUFFER_END,
				 card->abuf2 + ringsize);

	    nm256_writePort32 (card, 2, NM_RBUFFER_CURRP,
				 card->abuf2 + card->curRecPos);
	    enableEngine = 1;
	}
	else {
	    /* Not sure what else to do here.  */
	    spin_unlock_irqrestore(&card->lock,flags);
	    return;
	}
    }

    /* 
     * If we happen to go past the end of the buffer a bit (due to a
     * delayed interrupt) it's OK.  So might as well set the watermark
     * right at the end of the data we want.
     */
    endpos = card->abuf2 + ((card->curRecPos + amt) % ringsize);

    card->recBuf = buffer;
    card->requestedRecAmt = amt;
    nm256_writePort32 (card, 2, NM_RBUFFER_WMARK, endpos);
    /* Enable recording engine and interrupts. */
    if (enableEngine)
	nm256_writePort8 (card, 2, NM_RECORD_ENABLE_REG,
			    NM_RECORD_ENABLE_FLAG | NM_RECORD_FREERUN);

    spin_unlock_irqrestore(&card->lock,flags);
}

/* Stop the play engine. */
static void
stopPlay (struct nm256_info *card)
{
    /* Shut off sound from both channels. */
    nm256_writePort16 (card, 2, NM_AUDIO_MUTE_REG,
		       NM_AUDIO_MUTE_LEFT | NM_AUDIO_MUTE_RIGHT);
    /* Disable play engine. */
    nm256_writePort8 (card, 2, NM_PLAYBACK_ENABLE_REG, 0);
    if (card->playing) {
	nm256_releaseInterrupt (card);

	/* Reset the relevant state bits. */
	card->playing = 0;
	card->curPlayPos = 0;
    }
}

/* Stop recording. */
static void
stopRecord (struct nm256_info *card)
{
    /* Disable recording engine. */
    nm256_writePort8 (card, 2, NM_RECORD_ENABLE_REG, 0);

    if (card->recording) {
	nm256_releaseInterrupt (card);

	card->recording = 0;
	card->curRecPos = 0;
    }
}

/*
 * Ring buffers, man.  That's where the hip-hop, wild-n-wooly action's at.
 * 1972?  (Well, I suppose it was cheep-n-easy to implement.)
 *
 * Write AMT bytes of BUFFER to the playback ring buffer, and start the
 * playback engine running.  It will only accept up to 1/2 of the total
 * size of the ring buffer.  No check is made that we're about to overwrite
 * the currently-playing sample.
 */

static void
nm256_write_block (struct nm256_info *card, char *buffer, u32 amt)
{
    u32 ringsize = card->playbackBufferSize;
    u32 endstop;
    unsigned long flags;

    if (amt > (ringsize / 2)) {
	printk (KERN_ERR "NM256: Write request too large: %d\n", amt);
	amt = (ringsize / 2);
    }

    if (amt < NM256_PLAY_WMARK_SIZE) {
	printk (KERN_ERR "NM256: Write request too small: %d\n", amt);
	return;
    }

    card->curPlayPos %= ringsize;

    card->requested_amt = amt;

    spin_lock_irqsave(&card->lock,flags);

    if ((card->curPlayPos + amt) >= ringsize) {
	u32 rem = ringsize - card->curPlayPos;

	nm256_writeBuffer8 (card, buffer, 1,
			      card->abuf1 + card->curPlayPos,
			      rem);
	if (amt > rem)
	    nm256_writeBuffer8 (card, buffer + rem, 1, card->abuf1,
				  amt - rem);
    } 
    else
	nm256_writeBuffer8 (card, buffer, 1,
			      card->abuf1 + card->curPlayPos,
			      amt);

    /*
     * Setup the start-n-stop-n-limit registers, and start that engine
     * goin'. 
     *
     * Normally we just let it wrap around to avoid the click-click
     * action scene.
     */
    if (! card->playing) {
	/* The PBUFFER_END register in this case points to one sample
	   before the end of the buffer. */
	int w = (card->dev_for_play == card->dev[0] ? 0 : 1);
	int sampsize = (card->sinfo[w].bits == 16 ? 2 : 1);

	if (card->sinfo[w].stereo)
	    sampsize *= 2;

	/* Need to set the not-normally-changing-registers up. */
	nm256_writePort32 (card, 2, NM_PBUFFER_START,
			     card->abuf1 + card->curPlayPos);
	nm256_writePort32 (card, 2, NM_PBUFFER_END,
			     card->abuf1 + ringsize - sampsize);
	nm256_writePort32 (card, 2, NM_PBUFFER_CURRP,
			     card->abuf1 + card->curPlayPos);
    }
    endstop = (card->curPlayPos + amt - NM256_PLAY_WMARK_SIZE) % ringsize;
    nm256_writePort32 (card, 2, NM_PBUFFER_WMARK, card->abuf1 + endstop);

    if (! card->playing)
	startPlay (card);

    spin_unlock_irqrestore(&card->lock,flags);
}

/*  We just got a card playback interrupt; process it.  */
static void
nm256_get_new_block (struct nm256_info *card)
{
    /* Check to see how much got played so far. */
    u32 amt = nm256_readPort32 (card, 2, NM_PBUFFER_CURRP) - card->abuf1;

    if (amt >= card->playbackBufferSize) {
	printk (KERN_ERR "NM256: Sound playback pointer invalid!\n");
	amt = 0;
    }

    if (amt < card->curPlayPos)
	amt = (card->playbackBufferSize - card->curPlayPos) + amt;
    else
	amt -= card->curPlayPos;

    if (card->requested_amt > (amt + NM256_PLAY_WMARK_SIZE)) {
	u32 endstop =
	    card->curPlayPos + card->requested_amt - NM256_PLAY_WMARK_SIZE;
	nm256_writePort32 (card, 2, NM_PBUFFER_WMARK, card->abuf1 + endstop);
    } 
    else {
	card->curPlayPos += card->requested_amt;
	/* Get a new block to write.  This will eventually invoke
	   nm256_write_block () or stopPlay ().  */
	DMAbuf_outputintr (card->dev_for_play, 1);
    }
}

/* 
 * Read the last-recorded block from the ring buffer, copy it into the
 * saved buffer pointer, and invoke DMAuf_inputintr() with the recording
 * device. 
 */

static void
nm256_read_block (struct nm256_info *card)
{
    /* Grab the current position of the recording pointer. */
    u32 currptr = nm256_readPort32 (card, 2, NM_RBUFFER_CURRP) - card->abuf2;
    u32 amtToRead = card->requestedRecAmt;
    u32 ringsize = card->recordBufferSize;

    if (currptr >= card->recordBufferSize) {
	printk (KERN_ERR "NM256: Sound buffer record pointer invalid!\n");
        currptr = 0;
    }

    /*
     * This test is probably redundant; we shouldn't be here unless
     * it's true.
     */
    if (card->recording) {
	/* If we wrapped around, copy everything from the start of our
	   recording buffer to the end of the buffer. */
	if (currptr < card->curRecPos) {
	    u32 amt = min (ringsize - card->curRecPos, amtToRead);

	    nm256_readBuffer8 (card, card->recBuf, 1,
				 card->abuf2 + card->curRecPos,
				 amt);
	    amtToRead -= amt;
	    card->curRecPos += amt;
	    card->recBuf += amt;
	    if (card->curRecPos == ringsize)
		card->curRecPos = 0;
	}

	if ((card->curRecPos < currptr) && (amtToRead > 0)) {
	    u32 amt = min (currptr - card->curRecPos, amtToRead);
	    nm256_readBuffer8 (card, card->recBuf, 1,
				 card->abuf2 + card->curRecPos, amt);
	    card->curRecPos = ((card->curRecPos + amt) % ringsize);
	}
	card->recBuf = NULL;
	card->requestedRecAmt = 0;
	DMAbuf_inputintr (card->dev_for_record);
    }
}

/*
 * Initialize the hardware. 
 */
static void
nm256_initHw (struct nm256_info *card)
{
    /* Reset everything. */
    nm256_writePort8 (card, 2, 0x0, 0x11);
    nm256_writePort16 (card, 2, 0x214, 0);

    stopRecord (card);
    stopPlay (card);
}

/* 
 * Handle a potential interrupt for the device referred to by DEV_ID. 
 *
 * I don't like the cut-n-paste job here either between the two routines,
 * but there are sufficient differences between the two interrupt handlers
 * that parameterizing it isn't all that great either.  (Could use a macro,
 * I suppose...yucky bleah.)
 */

static irqreturn_t
nm256_interrupt (int irq, void *dev_id)
{
    struct nm256_info *card = (struct nm256_info *)dev_id;
    u16 status;
    static int badintrcount;
    int handled = 0;

    if ((card == NULL) || (card->magsig != NM_MAGIC_SIG)) {
	printk (KERN_ERR "NM256: Bad card pointer\n");
	return IRQ_NONE;
    }

    status = nm256_readPort16 (card, 2, NM_INT_REG);

    /* Not ours. */
    if (status == 0) {
	if (badintrcount++ > 1000) {
	    /*
	     * I'm not sure if the best thing is to stop the card from
	     * playing or just release the interrupt (after all, we're in
	     * a bad situation, so doing fancy stuff may not be such a good
	     * idea).
	     *
	     * I worry about the card engine continuing to play noise
	     * over and over, however--that could become a very
	     * obnoxious problem.  And we know that when this usually
	     * happens things are fairly safe, it just means the user's
	     * inserted a PCMCIA card and someone's spamming us with IRQ 9s.
	     */

	    handled = 1;
	    if (card->playing)
		stopPlay (card);
	    if (card->recording)
		stopRecord (card);
	    badintrcount = 0;
	}
	return IRQ_RETVAL(handled);
    }

    badintrcount = 0;

    /* Rather boring; check for individual interrupts and process them. */

    if (status & NM_PLAYBACK_INT) {
	handled = 1;
	status &= ~NM_PLAYBACK_INT;
	NM_ACK_INT (card, NM_PLAYBACK_INT);

	if (card->playing)
	    nm256_get_new_block (card);
    }

    if (status & NM_RECORD_INT) {
	handled = 1;
	status &= ~NM_RECORD_INT;
	NM_ACK_INT (card, NM_RECORD_INT);

	if (card->recording)
	    nm256_read_block (card);
    }

    if (status & NM_MISC_INT_1) {
	u8 cbyte;

	handled = 1;
	status &= ~NM_MISC_INT_1;
	printk (KERN_ERR "NM256: Got misc interrupt #1\n");
	NM_ACK_INT (card, NM_MISC_INT_1);
	nm256_writePort16 (card, 2, NM_INT_REG, 0x8000);
	cbyte = nm256_readPort8 (card, 2, 0x400);
	nm256_writePort8 (card, 2, 0x400, cbyte | 2);
    }

    if (status & NM_MISC_INT_2) {
	u8 cbyte;

	handled = 1;
	status &= ~NM_MISC_INT_2;
	printk (KERN_ERR "NM256: Got misc interrupt #2\n");
	NM_ACK_INT (card, NM_MISC_INT_2);
	cbyte = nm256_readPort8 (card, 2, 0x400);
	nm256_writePort8 (card, 2, 0x400, cbyte & ~2);
    }

    /* Unknown interrupt. */
    if (status) {
	handled = 1;
	printk (KERN_ERR "NM256: Fire in the hole! Unknown status 0x%x\n",
		status);
	/* Pray. */
	NM_ACK_INT (card, status);
    }
    return IRQ_RETVAL(handled);
}

/*
 * Handle a potential interrupt for the device referred to by DEV_ID.
 * This handler is for the 256ZX, and is very similar to the non-ZX
 * routine.
 */

static irqreturn_t
nm256_interrupt_zx (int irq, void *dev_id)
{
    struct nm256_info *card = (struct nm256_info *)dev_id;
    u32 status;
    static int badintrcount;
    int handled = 0;

    if ((card == NULL) || (card->magsig != NM_MAGIC_SIG)) {
	printk (KERN_ERR "NM256: Bad card pointer\n");
	return IRQ_NONE;
    }

    status = nm256_readPort32 (card, 2, NM_INT_REG);

    /* Not ours. */
    if (status == 0) {
	if (badintrcount++ > 1000) {
	    printk (KERN_ERR "NM256: Releasing interrupt, over 1000 invalid interrupts\n");
	    /*
	     * I'm not sure if the best thing is to stop the card from
	     * playing or just release the interrupt (after all, we're in
	     * a bad situation, so doing fancy stuff may not be such a good
	     * idea).
	     *
	     * I worry about the card engine continuing to play noise
	     * over and over, however--that could become a very
	     * obnoxious problem.  And we know that when this usually
	     * happens things are fairly safe, it just means the user's
	     * inserted a PCMCIA card and someone's spamming us with 
	     * IRQ 9s.
	     */

	    handled = 1;
	    if (card->playing)
		stopPlay (card);
	    if (card->recording)
		stopRecord (card);
	    badintrcount = 0;
	}
	return IRQ_RETVAL(handled);
    }

    badintrcount = 0;

    /* Rather boring; check for individual interrupts and process them. */

    if (status & NM2_PLAYBACK_INT) {
	handled = 1;
	status &= ~NM2_PLAYBACK_INT;
	NM2_ACK_INT (card, NM2_PLAYBACK_INT);

	if (card->playing)
	    nm256_get_new_block (card);
    }

    if (status & NM2_RECORD_INT) {
	handled = 1;
	status &= ~NM2_RECORD_INT;
	NM2_ACK_INT (card, NM2_RECORD_INT);

	if (card->recording)
	    nm256_read_block (card);
    }

    if (status & NM2_MISC_INT_1) {
	u8 cbyte;

	handled = 1;
	status &= ~NM2_MISC_INT_1;
	printk (KERN_ERR "NM256: Got misc interrupt #1\n");
	NM2_ACK_INT (card, NM2_MISC_INT_1);
	cbyte = nm256_readPort8 (card, 2, 0x400);
	nm256_writePort8 (card, 2, 0x400, cbyte | 2);
    }

    if (status & NM2_MISC_INT_2) {
	u8 cbyte;

	handled = 1;
	status &= ~NM2_MISC_INT_2;
	printk (KERN_ERR "NM256: Got misc interrupt #2\n");
	NM2_ACK_INT (card, NM2_MISC_INT_2);
	cbyte = nm256_readPort8 (card, 2, 0x400);
	nm256_writePort8 (card, 2, 0x400, cbyte & ~2);
    }

    /* Unknown interrupt. */
    if (status) {
	handled = 1;
	printk (KERN_ERR "NM256: Fire in the hole! Unknown status 0x%x\n",
		status);
	/* Pray. */
	NM2_ACK_INT (card, status);
    }
    return IRQ_RETVAL(handled);
}

/* 
 * Request our interrupt.
 */
static int
nm256_grabInterrupt (struct nm256_info *card)
{
    if (card->has_irq++ == 0) {
	if (request_irq (card->irq, card->introutine, IRQF_SHARED,
			 "NM256_audio", card) < 0) {
	    printk (KERN_ERR "NM256: can't obtain IRQ %d\n", card->irq);
	    return -1;
	}
    }
    return 0;
}

/* 
 * Release our interrupt. 
 */
static int
nm256_releaseInterrupt (struct nm256_info *card)
{
    if (card->has_irq <= 0) {
	printk (KERN_ERR "nm256: too many calls to releaseInterrupt\n");
	return -1;
    }
    card->has_irq--;
    if (card->has_irq == 0) {
	free_irq (card->irq, card);
    }
    return 0;
}

/*
 * Waits for the mixer to become ready to be written; returns a zero value
 * if it timed out.
 */

static int
nm256_isReady (struct ac97_hwint *dev)
{
    struct nm256_info *card = (struct nm256_info *)dev->driver_private;
    int t2 = 10;
    u32 testaddr;
    u16 testb;
    int done = 0;

    if (card->magsig != NM_MAGIC_SIG) {
	printk (KERN_ERR "NM256: Bad magic signature in isReady!\n");
	return 0;
    }

    testaddr = card->mixer_status_offset;
    testb = card->mixer_status_mask;

    /* 
     * Loop around waiting for the mixer to become ready. 
     */
    while (! done && t2-- > 0) {
	if ((nm256_readPort16 (card, 2, testaddr) & testb) == 0)
	    done = 1;
	else
	    udelay (100);
    }
    return done;
}

/*
 * Return the contents of the AC97 mixer register REG.  Returns a positive
 * value if successful, or a negative error code.
 */
static int
nm256_readAC97Reg (struct ac97_hwint *dev, u8 reg)
{
    struct nm256_info *card = (struct nm256_info *)dev->driver_private;

    if (card->magsig != NM_MAGIC_SIG) {
	printk (KERN_ERR "NM256: Bad magic signature in readAC97Reg!\n");
	return -EINVAL;
    }

    if (reg < 128) {
	int res;

	nm256_isReady (dev);
	res = nm256_readPort16 (card, 2, card->mixer + reg);
	/* Magic delay.  Bleah yucky.  */
        udelay (1000);
	return res;
    }
    else
	return -EINVAL;
}

/* 
 * Writes VALUE to AC97 mixer register REG.  Returns 0 if successful, or
 * a negative error code. 
 */
static int
nm256_writeAC97Reg (struct ac97_hwint *dev, u8 reg, u16 value)
{
    unsigned long flags;
    int tries = 2;
    int done = 0;
    u32 base;

    struct nm256_info *card = (struct nm256_info *)dev->driver_private;

    if (card->magsig != NM_MAGIC_SIG) {
	printk (KERN_ERR "NM256: Bad magic signature in writeAC97Reg!\n");
	return -EINVAL;
    }

    base = card->mixer;

    spin_lock_irqsave(&card->lock,flags);

    nm256_isReady (dev);

    /* Wait for the write to take, too. */
    while ((tries-- > 0) && !done) {
	nm256_writePort16 (card, 2, base + reg, value);
	if (nm256_isReady (dev)) {
	    done = 1;
	    break;
	}

    }

    spin_unlock_irqrestore(&card->lock,flags);
    udelay (1000);

    return ! done;
}

/* 
 * Initial register values to be written to the AC97 mixer.
 * While most of these are identical to the reset values, we do this
 * so that we have most of the register contents cached--this avoids
 * reading from the mixer directly (which seems to be problematic,
 * probably due to ignorance).
 */
struct initialValues 
{
    unsigned short port;
    unsigned short value;
};

static struct initialValues nm256_ac97_initial_values[] = 
{
    { AC97_MASTER_VOL_STEREO, 0x8000 },
    { AC97_HEADPHONE_VOL,     0x8000 },
    { AC97_MASTER_VOL_MONO,   0x0000 },
    { AC97_PCBEEP_VOL,        0x0000 },
    { AC97_PHONE_VOL,         0x0008 },
    { AC97_MIC_VOL,           0x8000 },
    { AC97_LINEIN_VOL,        0x8808 },
    { AC97_CD_VOL,            0x8808 },
    { AC97_VIDEO_VOL,         0x8808 },
    { AC97_AUX_VOL,           0x8808 },
    { AC97_PCMOUT_VOL,        0x0808 },
    { AC97_RECORD_SELECT,     0x0000 },
    { AC97_RECORD_GAIN,       0x0B0B },
    { AC97_GENERAL_PURPOSE,   0x0000 },
    { 0xffff, 0xffff }
};

/* Initialize the AC97 into a known state.  */
static int
nm256_resetAC97 (struct ac97_hwint *dev)
{
    struct nm256_info *card = (struct nm256_info *)dev->driver_private;
    int x;

    if (card->magsig != NM_MAGIC_SIG) {
	printk (KERN_ERR "NM256: Bad magic signature in resetAC97!\n");
	return -EINVAL;
    }

    /* Reset the mixer.  'Tis magic!  */
    nm256_writePort8 (card, 2, 0x6c0, 1);
//  nm256_writePort8 (card, 2, 0x6cc, 0x87);	/* This crashes Dell latitudes */
    nm256_writePort8 (card, 2, 0x6cc, 0x80);
    nm256_writePort8 (card, 2, 0x6cc, 0x0);

    if (! card->mixer_values_init) {
	for (x = 0; nm256_ac97_initial_values[x].port != 0xffff; x++) {
	    ac97_put_register (dev,
			       nm256_ac97_initial_values[x].port,
			       nm256_ac97_initial_values[x].value);
	    card->mixer_values_init = 1;
	}
    }

    return 0;
}

/*
 * We don't do anything particularly special here; it just passes the
 * mixer ioctl to the AC97 driver.
 */
static int
nm256_default_mixer_ioctl (int dev, unsigned int cmd, void __user *arg)
{
    struct nm256_info *card = nm256_find_card_for_mixer (dev);
    if (card != NULL)
	return ac97_mixer_ioctl (&(card->mdev), cmd, arg);
    else
	return -ENODEV;
}

static struct mixer_operations nm256_mixer_operations = {
	.owner	= THIS_MODULE,
	.id	= "NeoMagic",
	.name	= "NM256AC97Mixer",
	.ioctl	= nm256_default_mixer_ioctl
};

/*
 * Default settings for the OSS mixer.  These are set last, after the
 * mixer is initialized.
 *
 * I "love" C sometimes.  Got braces?
 */
static struct ac97_mixer_value_list mixer_defaults[] = {
    { SOUND_MIXER_VOLUME,  { { 85, 85 } } },
    { SOUND_MIXER_SPEAKER, { { 100 } } },
    { SOUND_MIXER_PCM,     { { 65, 65 } } },
    { SOUND_MIXER_CD,      { { 65, 65 } } },
    { -1,                  {  { 0,  0 } } }
};


/* Installs the AC97 mixer into CARD.  */
static int __devinit
nm256_install_mixer (struct nm256_info *card)
{
    int mixer;

    card->mdev.reset_device = nm256_resetAC97;
    card->mdev.read_reg = nm256_readAC97Reg;
    card->mdev.write_reg = nm256_writeAC97Reg;
    card->mdev.driver_private = (void *)card;

    if (ac97_init (&(card->mdev)))
	return -1;

    mixer = sound_alloc_mixerdev();
    if (num_mixers >= MAX_MIXER_DEV) {
	printk ("NM256 mixer: Unable to alloc mixerdev\n");
	return -1;
    }

    mixer_devs[mixer] = &nm256_mixer_operations;
    card->mixer_oss_dev = mixer;

    /* Some reasonable default values.  */
    ac97_set_values (&(card->mdev), mixer_defaults);

    printk(KERN_INFO "Initialized AC97 mixer\n");
    return 0;
}

/* 
 * See if the signature left by the NM256 BIOS is intact; if so, we use
 * the associated address as the end of our audio buffer in the video
 * RAM.
 */

static void __devinit
nm256_peek_for_sig (struct nm256_info *card)
{
    u32 port1offset 
	= card->port[0].physaddr + card->port[0].end_offset - 0x0400;
    /* The signature is located 1K below the end of video RAM.  */
    char __iomem *temp = ioremap_nocache (port1offset, 16);
    /* Default buffer end is 5120 bytes below the top of RAM.  */
    u32 default_value = card->port[0].end_offset - 0x1400;
    u32 sig;

    /* Install the default value first, so we don't have to repeatedly
       do it if there is a problem.  */
    card->port[0].end_offset = default_value;

    if (temp == NULL) {
	printk (KERN_ERR "NM256: Unable to scan for card signature in video RAM\n");
	return;
    }
    sig = readl (temp);
    if ((sig & NM_SIG_MASK) == NM_SIGNATURE) {
	u32 pointer = readl (temp + 4);

	/*
	 * If it's obviously invalid, don't use it (the port already has a
	 * suitable default value set).
	 */
	if (pointer != 0xffffffff)
	    card->port[0].end_offset = pointer;

	printk (KERN_INFO "NM256: Found card signature in video RAM: 0x%x\n",
		pointer);
    }

    iounmap (temp);
}

/* 
 * Install a driver for the PCI device referenced by PCIDEV.
 * VERSTR is a human-readable version string.
 */

static int __devinit
nm256_install(struct pci_dev *pcidev, enum nm256rev rev, char *verstr)
{
    struct nm256_info *card;
    int x;

    if (pci_enable_device(pcidev))
	    return 0;

    card = kmalloc (sizeof (struct nm256_info), GFP_KERNEL);
    if (card == NULL) {
	printk (KERN_ERR "NM256: out of memory!\n");
	return 0;
    }

    card->magsig = NM_MAGIC_SIG;
    card->playing  = 0;
    card->recording = 0;
    card->rev = rev;
    spin_lock_init(&card->lock);

    /* Init the memory port info.  */
    for (x = 0; x < 2; x++) {
	card->port[x].physaddr = pci_resource_start (pcidev, x);
	card->port[x].ptr = NULL;
	card->port[x].start_offset = 0;
	card->port[x].end_offset = 0;
    }

    /* Port 2 is easy.  */
    card->port[1].start_offset = 0;
    card->port[1].end_offset = NM_PORT2_SIZE;

    /* Yuck.  But we have to map in port 2 so we can check how much RAM the
       card has.  */
    if (nm256_remap_ports (card)) {
	kfree (card);
	return 0;
    }

    /* 
     * The NM256 has two memory ports.  The first port is nothing
     * more than a chunk of video RAM, which is used as the I/O ring
     * buffer.  The second port has the actual juicy stuff (like the
     * mixer and the playback engine control registers).
     */

    if (card->rev == REV_NM256AV) {
	/* Ok, try to see if this is a non-AC97 version of the hardware. */
	int pval = nm256_readPort16 (card, 2, NM_MIXER_PRESENCE);
	if ((pval & NM_PRESENCE_MASK) != NM_PRESENCE_VALUE) {
	    if (! force_load) {
		printk (KERN_ERR "NM256: This doesn't look to me like the AC97-compatible version.\n");
		printk (KERN_ERR "       You can force the driver to load by passing in the module\n");
		printk (KERN_ERR "       parameter:\n");
		printk (KERN_ERR "              force_load = 1\n");
		printk (KERN_ERR "\n");
		printk (KERN_ERR "       More likely, you should be using the appropriate SB-16 or\n");
		printk (KERN_ERR "       CS4232 driver instead.  (If your BIOS has settings for\n");
		printk (KERN_ERR "       IRQ and/or DMA for the sound card, this is *not* the correct\n");
		printk (KERN_ERR "       driver to use.)\n");
		nm256_release_ports (card);
		kfree (card);
		return 0;
	    }
	    else {
		printk (KERN_INFO "NM256: Forcing driver load as per user request.\n");
	    }
	}
	else {
	 /*   printk (KERN_INFO "NM256: Congratulations. You're not running Eunice.\n")*/;
	}
	card->port[0].end_offset = 2560 * 1024;
	card->introutine = nm256_interrupt;
	card->mixer_status_offset = NM_MIXER_STATUS_OFFSET;
	card->mixer_status_mask = NM_MIXER_READY_MASK;
    } 
    else {
	/* Not sure if there is any relevant detect for the ZX or not.  */
	if (nm256_readPort8 (card, 2, 0xa0b) != 0)
	    card->port[0].end_offset = 6144 * 1024;
	else
	    card->port[0].end_offset = 4096 * 1024;

	card->introutine = nm256_interrupt_zx;
	card->mixer_status_offset = NM2_MIXER_STATUS_OFFSET;
	card->mixer_status_mask = NM2_MIXER_READY_MASK;
    }

    if (buffertop >= 98304 && buffertop < card->port[0].end_offset)
	card->port[0].end_offset = buffertop;
    else
	nm256_peek_for_sig (card);

    card->port[0].start_offset = card->port[0].end_offset - 98304;

    printk (KERN_INFO "NM256: Mapping port 1 from 0x%x - 0x%x\n",
	    card->port[0].start_offset, card->port[0].end_offset);

    if (nm256_remap_ports (card)) {
	kfree (card);
	return 0;
    }

    /* See if we can get the interrupt. */

    card->irq = pcidev->irq;
    card->has_irq = 0;

    if (nm256_grabInterrupt (card) != 0) {
	nm256_release_ports (card);
	kfree (card);
	return 0;
    }

    nm256_releaseInterrupt (card);

    /*
     *	Init the board.
     */

    card->playbackBufferSize = 16384;
    card->recordBufferSize = 16384;

    card->coeffBuf = card->port[0].end_offset - NM_MAX_COEFFICIENT;
    card->abuf2 = card->coeffBuf - card->recordBufferSize;
    card->abuf1 = card->abuf2 - card->playbackBufferSize;
    card->allCoeffBuf = card->abuf2 - (NM_TOTAL_COEFF_COUNT * 4);

    /* Fixed setting. */
    card->mixer = NM_MIXER_OFFSET;
    card->mixer_values_init = 0;

    card->is_open_play = 0;
    card->is_open_record = 0;

    card->coeffsCurrent = 0;

    card->opencnt[0] = 0; card->opencnt[1] = 0;

    /* Reasonable default settings, but largely unnecessary. */
    for (x = 0; x < 2; x++) {
	card->sinfo[x].bits = 8;
	card->sinfo[x].stereo = 0;
	card->sinfo[x].samplerate = 8000;
    }

    nm256_initHw (card);

    for (x = 0; x < 2; x++) {
	if ((card->dev[x] =
	     sound_install_audiodrv(AUDIO_DRIVER_VERSION,
				    "NM256", &nm256_audio_driver,
				    sizeof(struct audio_driver),
				    DMA_NODMA, AFMT_U8 | AFMT_S16_LE,
				    NULL, -1, -1)) >= 0) {
	    /* 1K minimum buffer size. */
	    audio_devs[card->dev[x]]->min_fragment = 10;
	    /* Maximum of 8K buffer size. */
	    audio_devs[card->dev[x]]->max_fragment = 13;
	}
	else {
	    printk(KERN_ERR "NM256: Too many PCM devices available\n");
	    nm256_release_ports (card);
	    kfree (card);
	    return 0;
	}
    }

    pci_set_drvdata(pcidev,card);

    /* Insert the card in the list.  */
    card->next_card = nmcard_list;
    nmcard_list = card;

    printk(KERN_INFO "Initialized NeoMagic %s audio in PCI native mode\n",
	   verstr);

    /* 
     * And our mixer.  (We should allow support for other mixers, maybe.)
     */

    nm256_install_mixer (card);

    return 1;
}


static int __devinit
nm256_probe(struct pci_dev *pcidev,const struct pci_device_id *pciid)
{
    if (pcidev->device == PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO)
	return nm256_install(pcidev, REV_NM256AV, "256AV");
    if (pcidev->device == PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO)
	return nm256_install(pcidev, REV_NM256ZX, "256ZX");
    if (pcidev->device == PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO)
	return nm256_install(pcidev, REV_NM256ZX, "256XL+");
    return -1; /* should not come here ... */
}

static void __devinit
nm256_remove(struct pci_dev *pcidev) {
    struct nm256_info *xcard = pci_get_drvdata(pcidev);
    struct nm256_info *card,*next_card = NULL;

    for (card = nmcard_list; card != NULL; card = next_card) {
	next_card = card->next_card;
	if (card == xcard) {
	    stopPlay (card);
	    stopRecord (card);
	    if (card->has_irq)
		free_irq (card->irq, card);
	    nm256_release_ports (card);
	    sound_unload_mixerdev (card->mixer_oss_dev);
	    sound_unload_audiodev (card->dev[0]);
	    sound_unload_audiodev (card->dev[1]);
	    kfree (card);
	    break;
	}
    }
    if (nmcard_list == card)
    	nmcard_list = next_card;
}

/*
 * Open the device
 *
 * DEV  - device
 * MODE - mode to open device (logical OR of OPEN_READ and OPEN_WRITE)
 *
 * Called when opening the DMAbuf               (dmabuf.c:259)
 */
static int
nm256_audio_open(int dev, int mode)
{
    struct nm256_info *card = nm256_find_card (dev);
    int w;
	
    if (card == NULL)
	return -ENODEV;

    if (card->dev[0] == dev)
	w = 0;
    else if (card->dev[1] == dev)
	w = 1;
    else
	return -ENODEV;

    if (card->opencnt[w] > 0)
	return -EBUSY;

    /* No bits set? Huh? */
    if (! ((mode & OPEN_READ) || (mode & OPEN_WRITE)))
	return -EIO;

    /*
     * If it's open for both read and write, and the card's currently
     * being read or written to, then do the opposite of what has
     * already been done.  Otherwise, don't specify any mode until the
     * user actually tries to do I/O.  (Some programs open the device
     * for both read and write, but only actually do reading or writing.)
     */

    if ((mode & OPEN_WRITE) && (mode & OPEN_READ)) {
	if (card->is_open_play)
	    mode = OPEN_WRITE;
	else if (card->is_open_record)
	    mode = OPEN_READ;
	else mode = 0;
    }
	
    if (mode & OPEN_WRITE) {
	if (card->is_open_play == 0) {
	    card->dev_for_play = dev;
	    card->is_open_play = 1;
	}
	else
	    return -EBUSY;
    }

    if (mode & OPEN_READ) {
	if (card->is_open_record == 0) {
	    card->dev_for_record = dev;
	    card->is_open_record = 1;
	}
	else
	    return -EBUSY;
    }

    card->opencnt[w]++;
    return 0;
}

/*
 * Close the device
 *
 * DEV  - device
 *
 * Called when closing the DMAbuf               (dmabuf.c:477)
 *      after halt_xfer
 */
static void
nm256_audio_close(int dev)
{
    struct nm256_info *card = nm256_find_card (dev);
	
    if (card != NULL) {
	int w;

	if (card->dev[0] == dev)
	    w = 0;
	else if (card->dev[1] == dev)
	    w = 1;
	else
	    return;

	card->opencnt[w]--;
	if (card->opencnt[w] <= 0) {
	    card->opencnt[w] = 0;

	    if (card->dev_for_play == dev) {
		stopPlay (card);
		card->is_open_play = 0;
		card->dev_for_play = -1;
	    }

	    if (card->dev_for_record == dev) {
		stopRecord (card);
		card->is_open_record = 0;
		card->dev_for_record = -1;
	    }
	}
    }
}

/* Standard ioctl handler. */
static int
nm256_audio_ioctl(int dev, unsigned int cmd, void __user *arg)
{
    int ret;
    u32 oldinfo;
    int w;

    struct nm256_info *card = nm256_find_card (dev);

    if (card == NULL)
	return -ENODEV;

    if (dev == card->dev[0])
	w = 0;
    else
	w = 1;

    /* 
     * The code here is messy.  There are probably better ways to do
     * it.  (It should be possible to handle it the same way the AC97 mixer 
     * is done.)
     */
    switch (cmd)
	{
	case SOUND_PCM_WRITE_RATE:
	    if (get_user(ret, (int __user *) arg))
		return -EFAULT;

	    if (ret != 0) {
		oldinfo = card->sinfo[w].samplerate;
		card->sinfo[w].samplerate = ret;
		ret = nm256_setInfo(dev, card);
		if (ret != 0)
		    card->sinfo[w].samplerate = oldinfo;
	    }
	    if (ret == 0)
		ret = card->sinfo[w].samplerate;
	    break;

	case SOUND_PCM_READ_RATE:
	    ret = card->sinfo[w].samplerate;
	    break;

	case SNDCTL_DSP_STEREO:
	    if (get_user(ret, (int __user *) arg))
		return -EFAULT;

	    card->sinfo[w].stereo = ret ? 1 : 0;
	    ret = nm256_setInfo (dev, card);
	    if (ret == 0)
		ret = card->sinfo[w].stereo;

	    break;

	case SOUND_PCM_WRITE_CHANNELS:
	    if (get_user(ret, (int __user *) arg))
		return -EFAULT;

	    if (ret < 1 || ret > 3)
		ret = card->sinfo[w].stereo + 1;
	    else {
		card->sinfo[w].stereo = ret - 1;
		ret = nm256_setInfo (dev, card);
		if (ret == 0)
		    ret = card->sinfo[w].stereo + 1;
	    }
	    break;

	case SOUND_PCM_READ_CHANNELS:
	    ret = card->sinfo[w].stereo + 1;
	    break;

	case SNDCTL_DSP_SETFMT:
	    if (get_user(ret, (int __user *) arg))
		return -EFAULT;

	    if (ret != 0) {
		oldinfo = card->sinfo[w].bits;
		card->sinfo[w].bits = ret;
		ret = nm256_setInfo (dev, card);
		if (ret != 0)
		    card->sinfo[w].bits = oldinfo;
	    }
	    if (ret == 0)
		ret = card->sinfo[w].bits;
	    break;

	case SOUND_PCM_READ_BITS:
	    ret = card->sinfo[w].bits;
	    break;

	default:
	    return -EINVAL;
	}
    return put_user(ret, (int __user *) arg);
}

/*
 * Given the sound device DEV and an associated physical buffer PHYSBUF, 
 * return a pointer to the actual buffer in kernel space. 
 *
 * This routine should exist as part of the soundcore routines.
 */

static char *
nm256_getDMAbuffer (int dev, unsigned long physbuf)
{
    struct audio_operations *adev = audio_devs[dev];
    struct dma_buffparms *dmap = adev->dmap_out;
    char *dma_start =
	(char *)(physbuf - (unsigned long)dmap->raw_buf_phys 
		 + (unsigned long)dmap->raw_buf);

    return dma_start;
}


/*
 * Output a block to sound device
 *
 * dev          - device number
 * buf          - physical address of buffer
 * total_count  - total byte count in buffer
 * intrflag     - set if this has been called from an interrupt 
 *				  (via DMAbuf_outputintr)
 * restart_dma  - set if engine needs to be re-initialised
 *
 * Called when:
 *  1. Starting output                                  (dmabuf.c:1327)
 *  2.                                                  (dmabuf.c:1504)
 *  3. A new buffer needs to be sent to the device      (dmabuf.c:1579)
 */
static void
nm256_audio_output_block(int dev, unsigned long physbuf,
				       int total_count, int intrflag)
{
    struct nm256_info *card = nm256_find_card (dev);

    if (card != NULL) {
	char *dma_buf = nm256_getDMAbuffer (dev, physbuf);
	card->is_open_play = 1;
	card->dev_for_play = dev;
	nm256_write_block (card, dma_buf, total_count);
    }
}

/* Ditto, but do recording instead.  */
static void
nm256_audio_start_input(int dev, unsigned long physbuf, int count,
			int intrflag)
{
    struct nm256_info *card = nm256_find_card (dev);

    if (card != NULL) {
	char *dma_buf = nm256_getDMAbuffer (dev, physbuf);
	card->is_open_record = 1;
	card->dev_for_record = dev;
	nm256_startRecording (card, dma_buf, count);
    }
}

/* 
 * Prepare for inputting samples to DEV. 
 * Each requested buffer will be BSIZE byes long, with a total of
 * BCOUNT buffers. 
 */

static int
nm256_audio_prepare_for_input(int dev, int bsize, int bcount)
{
    struct nm256_info *card = nm256_find_card (dev);

    if (card == NULL) 
	return -ENODEV;

    if (card->is_open_record && card->dev_for_record != dev)
	return -EBUSY;

    audio_devs[dev]->dmap_in->flags |= DMA_NODMA;
    return 0;
}

/*
 * Prepare for outputting samples to `dev'
 *
 * Each buffer that will be passed will be `bsize' bytes long,
 * with a total of `bcount' buffers.
 *
 * Called when:
 *  1. A trigger enables audio output                   (dmabuf.c:978)
 *  2. We get a write buffer without dma_mode setup     (dmabuf.c:1152)
 *  3. We restart a transfer                            (dmabuf.c:1324)
 */

static int
nm256_audio_prepare_for_output(int dev, int bsize, int bcount)
{
    struct nm256_info *card = nm256_find_card (dev);

    if (card == NULL)
	return -ENODEV;

    if (card->is_open_play && card->dev_for_play != dev)
	return -EBUSY;

    audio_devs[dev]->dmap_out->flags |= DMA_NODMA;
    return 0;
}

/* Stop the current operations associated with DEV.  */
static void
nm256_audio_reset(int dev)
{
    struct nm256_info *card = nm256_find_card (dev);

    if (card != NULL) {
	if (card->dev_for_play == dev)
	    stopPlay (card);
	if (card->dev_for_record == dev)
	    stopRecord (card);
    }
}

static int
nm256_audio_local_qlen(int dev)
{
    return 0;
}

static struct audio_driver nm256_audio_driver =
{
	.owner			= THIS_MODULE,
	.open			= nm256_audio_open,
	.close			= nm256_audio_close,
	.output_block		= nm256_audio_output_block,
	.start_input		= nm256_audio_start_input,
	.ioctl			= nm256_audio_ioctl,
	.prepare_for_input	= nm256_audio_prepare_for_input,
	.prepare_for_output	= nm256_audio_prepare_for_output,
	.halt_io		= nm256_audio_reset,
	.local_qlen		= nm256_audio_local_qlen,
};

static struct pci_device_id nm256_pci_tbl[] = {
	{PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO,
	PCI_ANY_ID, PCI_ANY_ID, 0, 0},
	{PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO,
	PCI_ANY_ID, PCI_ANY_ID, 0, 0},
	{PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO,
	PCI_ANY_ID, PCI_ANY_ID, 0, 0},
	{0,}
};
MODULE_DEVICE_TABLE(pci, nm256_pci_tbl);
MODULE_LICENSE("GPL");


static struct pci_driver nm256_pci_driver = {
	.name		= "nm256_audio",
	.id_table	= nm256_pci_tbl,
	.probe		= nm256_probe,
	.remove		= nm256_remove,
};

module_param(usecache, bool, 0);
module_param(buffertop, int, 0);
module_param(nm256_debug, bool, 0644);
module_param(force_load, bool, 0);

static int __init do_init_nm256(void)
{
    printk (KERN_INFO "NeoMagic 256AV/256ZX audio driver, version 1.1p\n");
    return pci_register_driver(&nm256_pci_driver);
}

static void __exit cleanup_nm256 (void)
{
    pci_unregister_driver(&nm256_pci_driver);
}

module_init(do_init_nm256);
module_exit(cleanup_nm256);

/*
 * Local variables:
 *  c-basic-offset: 4
 * End:
 */
