// SPDX-License-Identifier: GPL-2.0-only
/*
 *  Driver for SiS7019 Audio Accelerator
 *
 *  Copyright (C) 2004-2007, David Dillow
 *  Written by David Dillow <dave@thedillows.org>
 *  Inspired by the Trident 4D-WaveDX/NX driver.
 *
 *  All rights reserved.
 */

#include <linux/init.h>
#include <linux/pci.h>
#include <linux/time.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <sound/core.h>
#include <sound/ac97_codec.h>
#include <sound/initval.h>
#include "sis7019.h"

MODULE_AUTHOR("David Dillow <dave@thedillows.org>");
MODULE_DESCRIPTION("SiS7019");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{SiS,SiS7019 Audio Accelerator}}");

static int index = SNDRV_DEFAULT_IDX1;	/* Index 0-MAX */
static char *id = SNDRV_DEFAULT_STR1;	/* ID for this card */
static bool enable = 1;
static int codecs = 1;

module_param(index, int, 0444);
MODULE_PARM_DESC(index, "Index value for SiS7019 Audio Accelerator.");
module_param(id, charp, 0444);
MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator.");
module_param(enable, bool, 0444);
MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator.");
module_param(codecs, int, 0444);
MODULE_PARM_DESC(codecs, "Set bit to indicate that codec number is expected to be present (default 1)");

static const struct pci_device_id snd_sis7019_ids[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) },
	{ 0, }
};

MODULE_DEVICE_TABLE(pci, snd_sis7019_ids);

/* There are three timing modes for the voices.
 *
 * For both playback and capture, when the buffer is one or two periods long,
 * we use the hardware's built-in Mid-Loop Interrupt and End-Loop Interrupt
 * to let us know when the periods have ended.
 *
 * When performing playback with more than two periods per buffer, we set
 * the "Stop Sample Offset" and tell the hardware to interrupt us when we
 * reach it. We then update the offset and continue on until we are
 * interrupted for the next period.
 *
 * Capture channels do not have a SSO, so we allocate a playback channel to
 * use as a timer for the capture periods. We use the SSO on the playback
 * channel to clock out virtual periods, and adjust the virtual period length
 * to maintain synchronization. This algorithm came from the Trident driver.
 *
 * FIXME: It'd be nice to make use of some of the synth features in the
 * hardware, but a woeful lack of documentation is a significant roadblock.
 */
struct voice {
	u16 flags;
#define 	VOICE_IN_USE		1
#define 	VOICE_CAPTURE		2
#define 	VOICE_SSO_TIMING	4
#define 	VOICE_SYNC_TIMING	8
	u16 sync_cso;
	u16 period_size;
	u16 buffer_size;
	u16 sync_period_size;
	u16 sync_buffer_size;
	u32 sso;
	u32 vperiod;
	struct snd_pcm_substream *substream;
	struct voice *timing;
	void __iomem *ctrl_base;
	void __iomem *wave_base;
	void __iomem *sync_base;
	int num;
};

/* We need four pages to store our wave parameters during a suspend. If
 * we're not doing power management, we still need to allocate a page
 * for the silence buffer.
 */
#ifdef CONFIG_PM_SLEEP
#define SIS_SUSPEND_PAGES	4
#else
#define SIS_SUSPEND_PAGES	1
#endif

struct sis7019 {
	unsigned long ioport;
	void __iomem *ioaddr;
	int irq;
	int codecs_present;

	struct pci_dev *pci;
	struct snd_pcm *pcm;
	struct snd_card *card;
	struct snd_ac97 *ac97[3];

	/* Protect against more than one thread hitting the AC97
	 * registers (in a more polite manner than pounding the hardware
	 * semaphore)
	 */
	struct mutex ac97_mutex;

	/* voice_lock protects allocation/freeing of the voice descriptions
	 */
	spinlock_t voice_lock;

	struct voice voices[64];
	struct voice capture_voice;

	/* Allocate pages to store the internal wave state during
	 * suspends. When we're operating, this can be used as a silence
	 * buffer for a timing channel.
	 */
	void *suspend_state[SIS_SUSPEND_PAGES];

	int silence_users;
	dma_addr_t silence_dma_addr;
};

/* These values are also used by the module param 'codecs' to indicate
 * which codecs should be present.
 */
#define SIS_PRIMARY_CODEC_PRESENT	0x0001
#define SIS_SECONDARY_CODEC_PRESENT	0x0002
#define SIS_TERTIARY_CODEC_PRESENT	0x0004

/* The HW offset parameters (Loop End, Stop Sample, End Sample) have a
 * documented range of 8-0xfff8 samples. Given that they are 0-based,
 * that places our period/buffer range at 9-0xfff9 samples. That makes the
 * max buffer size 0xfff9 samples * 2 channels * 2 bytes per sample, and
 * max samples / min samples gives us the max periods in a buffer.
 *
 * We'll add a constraint upon open that limits the period and buffer sample
 * size to values that are legal for the hardware.
 */
static const struct snd_pcm_hardware sis_playback_hw_info = {
	.info = (SNDRV_PCM_INFO_MMAP |
		 SNDRV_PCM_INFO_MMAP_VALID |
		 SNDRV_PCM_INFO_INTERLEAVED |
		 SNDRV_PCM_INFO_BLOCK_TRANSFER |
		 SNDRV_PCM_INFO_SYNC_START |
		 SNDRV_PCM_INFO_RESUME),
	.formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
		    SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE),
	.rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS,
	.rate_min = 4000,
	.rate_max = 48000,
	.channels_min = 1,
	.channels_max = 2,
	.buffer_bytes_max = (0xfff9 * 4),
	.period_bytes_min = 9,
	.period_bytes_max = (0xfff9 * 4),
	.periods_min = 1,
	.periods_max = (0xfff9 / 9),
};

static const struct snd_pcm_hardware sis_capture_hw_info = {
	.info = (SNDRV_PCM_INFO_MMAP |
		 SNDRV_PCM_INFO_MMAP_VALID |
		 SNDRV_PCM_INFO_INTERLEAVED |
		 SNDRV_PCM_INFO_BLOCK_TRANSFER |
		 SNDRV_PCM_INFO_SYNC_START |
		 SNDRV_PCM_INFO_RESUME),
	.formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
		    SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE),
	.rates = SNDRV_PCM_RATE_48000,
	.rate_min = 4000,
	.rate_max = 48000,
	.channels_min = 1,
	.channels_max = 2,
	.buffer_bytes_max = (0xfff9 * 4),
	.period_bytes_min = 9,
	.period_bytes_max = (0xfff9 * 4),
	.periods_min = 1,
	.periods_max = (0xfff9 / 9),
};

static void sis_update_sso(struct voice *voice, u16 period)
{
	void __iomem *base = voice->ctrl_base;

	voice->sso += period;
	if (voice->sso >= voice->buffer_size)
		voice->sso -= voice->buffer_size;

	/* Enforce the documented hardware minimum offset */
	if (voice->sso < 8)
		voice->sso = 8;

	/* The SSO is in the upper 16 bits of the register. */
	writew(voice->sso & 0xffff, base + SIS_PLAY_DMA_SSO_ESO + 2);
}

static void sis_update_voice(struct voice *voice)
{
	if (voice->flags & VOICE_SSO_TIMING) {
		sis_update_sso(voice, voice->period_size);
	} else if (voice->flags & VOICE_SYNC_TIMING) {
		int sync;

		/* If we've not hit the end of the virtual period, update
		 * our records and keep going.
		 */
		if (voice->vperiod > voice->period_size) {
			voice->vperiod -= voice->period_size;
			if (voice->vperiod < voice->period_size)
				sis_update_sso(voice, voice->vperiod);
			else
				sis_update_sso(voice, voice->period_size);
			return;
		}

		/* Calculate our relative offset between the target and
		 * the actual CSO value. Since we're operating in a loop,
		 * if the value is more than half way around, we can
		 * consider ourselves wrapped.
		 */
		sync = voice->sync_cso;
		sync -= readw(voice->sync_base + SIS_CAPTURE_DMA_FORMAT_CSO);
		if (sync > (voice->sync_buffer_size / 2))
			sync -= voice->sync_buffer_size;

		/* If sync is positive, then we interrupted too early, and
		 * we'll need to come back in a few samples and try again.
		 * There's a minimum wait, as it takes some time for the DMA
		 * engine to startup, etc...
		 */
		if (sync > 0) {
			if (sync < 16)
				sync = 16;
			sis_update_sso(voice, sync);
			return;
		}

		/* Ok, we interrupted right on time, or (hopefully) just
		 * a bit late. We'll adjst our next waiting period based
		 * on how close we got.
		 *
		 * We need to stay just behind the actual channel to ensure
		 * it really is past a period when we get our interrupt --
		 * otherwise we'll fall into the early code above and have
		 * a minimum wait time, which makes us quite late here,
		 * eating into the user's time to refresh the buffer, esp.
		 * if using small periods.
		 *
		 * If we're less than 9 samples behind, we're on target.
		 * Otherwise, shorten the next vperiod by the amount we've
		 * been delayed.
		 */
		if (sync > -9)
			voice->vperiod = voice->sync_period_size + 1;
		else
			voice->vperiod = voice->sync_period_size + sync + 10;

		if (voice->vperiod < voice->buffer_size) {
			sis_update_sso(voice, voice->vperiod);
			voice->vperiod = 0;
		} else
			sis_update_sso(voice, voice->period_size);

		sync = voice->sync_cso + voice->sync_period_size;
		if (sync >= voice->sync_buffer_size)
			sync -= voice->sync_buffer_size;
		voice->sync_cso = sync;
	}

	snd_pcm_period_elapsed(voice->substream);
}

static void sis_voice_irq(u32 status, struct voice *voice)
{
	int bit;

	while (status) {
		bit = __ffs(status);
		status >>= bit + 1;
		voice += bit;
		sis_update_voice(voice);
		voice++;
	}
}

static irqreturn_t sis_interrupt(int irq, void *dev)
{
	struct sis7019 *sis = dev;
	unsigned long io = sis->ioport;
	struct voice *voice;
	u32 intr, status;

	/* We only use the DMA interrupts, and we don't enable any other
	 * source of interrupts. But, it is possible to see an interrupt
	 * status that didn't actually interrupt us, so eliminate anything
	 * we're not expecting to avoid falsely claiming an IRQ, and an
	 * ensuing endless loop.
	 */
	intr = inl(io + SIS_GISR);
	intr &= SIS_GISR_AUDIO_PLAY_DMA_IRQ_STATUS |
		SIS_GISR_AUDIO_RECORD_DMA_IRQ_STATUS;
	if (!intr)
		return IRQ_NONE;

	do {
		status = inl(io + SIS_PISR_A);
		if (status) {
			sis_voice_irq(status, sis->voices);
			outl(status, io + SIS_PISR_A);
		}

		status = inl(io + SIS_PISR_B);
		if (status) {
			sis_voice_irq(status, &sis->voices[32]);
			outl(status, io + SIS_PISR_B);
		}

		status = inl(io + SIS_RISR);
		if (status) {
			voice = &sis->capture_voice;
			if (!voice->timing)
				snd_pcm_period_elapsed(voice->substream);

			outl(status, io + SIS_RISR);
		}

		outl(intr, io + SIS_GISR);
		intr = inl(io + SIS_GISR);
		intr &= SIS_GISR_AUDIO_PLAY_DMA_IRQ_STATUS |
			SIS_GISR_AUDIO_RECORD_DMA_IRQ_STATUS;
	} while (intr);

	return IRQ_HANDLED;
}

static u32 sis_rate_to_delta(unsigned int rate)
{
	u32 delta;

	/* This was copied from the trident driver, but it seems its gotten
	 * around a bit... nevertheless, it works well.
	 *
	 * We special case 44100 and 8000 since rounding with the equation
	 * does not give us an accurate enough value. For 11025 and 22050
	 * the equation gives us the best answer. All other frequencies will
	 * also use the equation. JDW
	 */
	if (rate == 44100)
		delta = 0xeb3;
	else if (rate == 8000)
		delta = 0x2ab;
	else if (rate == 48000)
		delta = 0x1000;
	else
		delta = (((rate << 12) + 24000) / 48000) & 0x0000ffff;
	return delta;
}

static void __sis_map_silence(struct sis7019 *sis)
{
	/* Helper function: must hold sis->voice_lock on entry */
	if (!sis->silence_users)
		sis->silence_dma_addr = dma_map_single(&sis->pci->dev,
						sis->suspend_state[0],
						4096, DMA_TO_DEVICE);
	sis->silence_users++;
}

static void __sis_unmap_silence(struct sis7019 *sis)
{
	/* Helper function: must hold sis->voice_lock on entry */
	sis->silence_users--;
	if (!sis->silence_users)
		dma_unmap_single(&sis->pci->dev, sis->silence_dma_addr, 4096,
					DMA_TO_DEVICE);
}

static void sis_free_voice(struct sis7019 *sis, struct voice *voice)
{
	unsigned long flags;

	spin_lock_irqsave(&sis->voice_lock, flags);
	if (voice->timing) {
		__sis_unmap_silence(sis);
		voice->timing->flags &= ~(VOICE_IN_USE | VOICE_SSO_TIMING |
						VOICE_SYNC_TIMING);
		voice->timing = NULL;
	}
	voice->flags &= ~(VOICE_IN_USE | VOICE_SSO_TIMING | VOICE_SYNC_TIMING);
	spin_unlock_irqrestore(&sis->voice_lock, flags);
}

static struct voice *__sis_alloc_playback_voice(struct sis7019 *sis)
{
	/* Must hold the voice_lock on entry */
	struct voice *voice;
	int i;

	for (i = 0; i < 64; i++) {
		voice = &sis->voices[i];
		if (voice->flags & VOICE_IN_USE)
			continue;
		voice->flags |= VOICE_IN_USE;
		goto found_one;
	}
	voice = NULL;

found_one:
	return voice;
}

static struct voice *sis_alloc_playback_voice(struct sis7019 *sis)
{
	struct voice *voice;
	unsigned long flags;

	spin_lock_irqsave(&sis->voice_lock, flags);
	voice = __sis_alloc_playback_voice(sis);
	spin_unlock_irqrestore(&sis->voice_lock, flags);

	return voice;
}

static int sis_alloc_timing_voice(struct snd_pcm_substream *substream,
					struct snd_pcm_hw_params *hw_params)
{
	struct sis7019 *sis = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct voice *voice = runtime->private_data;
	unsigned int period_size, buffer_size;
	unsigned long flags;
	int needed;

	/* If there are one or two periods per buffer, we don't need a
	 * timing voice, as we can use the capture channel's interrupts
	 * to clock out the periods.
	 */
	period_size = params_period_size(hw_params);
	buffer_size = params_buffer_size(hw_params);
	needed = (period_size != buffer_size &&
			period_size != (buffer_size / 2));

	if (needed && !voice->timing) {
		spin_lock_irqsave(&sis->voice_lock, flags);
		voice->timing = __sis_alloc_playback_voice(sis);
		if (voice->timing)
			__sis_map_silence(sis);
		spin_unlock_irqrestore(&sis->voice_lock, flags);
		if (!voice->timing)
			return -ENOMEM;
		voice->timing->substream = substream;
	} else if (!needed && voice->timing) {
		sis_free_voice(sis, voice);
		voice->timing = NULL;
	}

	return 0;
}

static int sis_playback_open(struct snd_pcm_substream *substream)
{
	struct sis7019 *sis = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct voice *voice;

	voice = sis_alloc_playback_voice(sis);
	if (!voice)
		return -EAGAIN;

	voice->substream = substream;
	runtime->private_data = voice;
	runtime->hw = sis_playback_hw_info;
	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
						9, 0xfff9);
	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
						9, 0xfff9);
	snd_pcm_set_sync(substream);
	return 0;
}

static int sis_substream_close(struct snd_pcm_substream *substream)
{
	struct sis7019 *sis = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct voice *voice = runtime->private_data;

	sis_free_voice(sis, voice);
	return 0;
}

static int sis_pcm_playback_prepare(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct voice *voice = runtime->private_data;
	void __iomem *ctrl_base = voice->ctrl_base;
	void __iomem *wave_base = voice->wave_base;
	u32 format, dma_addr, control, sso_eso, delta, reg;
	u16 leo;

	/* We rely on the PCM core to ensure that the parameters for this
	 * substream do not change on us while we're programming the HW.
	 */
	format = 0;
	if (snd_pcm_format_width(runtime->format) == 8)
		format |= SIS_PLAY_DMA_FORMAT_8BIT;
	if (!snd_pcm_format_signed(runtime->format))
		format |= SIS_PLAY_DMA_FORMAT_UNSIGNED;
	if (runtime->channels == 1)
		format |= SIS_PLAY_DMA_FORMAT_MONO;

	/* The baseline setup is for a single period per buffer, and
	 * we add bells and whistles as needed from there.
	 */
	dma_addr = runtime->dma_addr;
	leo = runtime->buffer_size - 1;
	control = leo | SIS_PLAY_DMA_LOOP | SIS_PLAY_DMA_INTR_AT_LEO;
	sso_eso = leo;

	if (runtime->period_size == (runtime->buffer_size / 2)) {
		control |= SIS_PLAY_DMA_INTR_AT_MLP;
	} else if (runtime->period_size != runtime->buffer_size) {
		voice->flags |= VOICE_SSO_TIMING;
		voice->sso = runtime->period_size - 1;
		voice->period_size = runtime->period_size;
		voice->buffer_size = runtime->buffer_size;

		control &= ~SIS_PLAY_DMA_INTR_AT_LEO;
		control |= SIS_PLAY_DMA_INTR_AT_SSO;
		sso_eso |= (runtime->period_size - 1) << 16;
	}

	delta = sis_rate_to_delta(runtime->rate);

	/* Ok, we're ready to go, set up the channel.
	 */
	writel(format, ctrl_base + SIS_PLAY_DMA_FORMAT_CSO);
	writel(dma_addr, ctrl_base + SIS_PLAY_DMA_BASE);
	writel(control, ctrl_base + SIS_PLAY_DMA_CONTROL);
	writel(sso_eso, ctrl_base + SIS_PLAY_DMA_SSO_ESO);

	for (reg = 0; reg < SIS_WAVE_SIZE; reg += 4)
		writel(0, wave_base + reg);

	writel(SIS_WAVE_GENERAL_WAVE_VOLUME, wave_base + SIS_WAVE_GENERAL);
	writel(delta << 16, wave_base + SIS_WAVE_GENERAL_ARTICULATION);
	writel(SIS_WAVE_CHANNEL_CONTROL_FIRST_SAMPLE |
			SIS_WAVE_CHANNEL_CONTROL_AMP_ENABLE |
			SIS_WAVE_CHANNEL_CONTROL_INTERPOLATE_ENABLE,
			wave_base + SIS_WAVE_CHANNEL_CONTROL);

	/* Force PCI writes to post. */
	readl(ctrl_base);

	return 0;
}

static int sis_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct sis7019 *sis = snd_pcm_substream_chip(substream);
	unsigned long io = sis->ioport;
	struct snd_pcm_substream *s;
	struct voice *voice;
	void *chip;
	int starting;
	u32 record = 0;
	u32 play[2] = { 0, 0 };

	/* No locks needed, as the PCM core will hold the locks on the
	 * substreams, and the HW will only start/stop the indicated voices
	 * without changing the state of the others.
	 */
	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
	case SNDRV_PCM_TRIGGER_RESUME:
		starting = 1;
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
	case SNDRV_PCM_TRIGGER_SUSPEND:
		starting = 0;
		break;
	default:
		return -EINVAL;
	}

	snd_pcm_group_for_each_entry(s, substream) {
		/* Make sure it is for us... */
		chip = snd_pcm_substream_chip(s);
		if (chip != sis)
			continue;

		voice = s->runtime->private_data;
		if (voice->flags & VOICE_CAPTURE) {
			record |= 1 << voice->num;
			voice = voice->timing;
		}

		/* voice could be NULL if this a recording stream, and it
		 * doesn't have an external timing channel.
		 */
		if (voice)
			play[voice->num / 32] |= 1 << (voice->num & 0x1f);

		snd_pcm_trigger_done(s, substream);
	}

	if (starting) {
		if (record)
			outl(record, io + SIS_RECORD_START_REG);
		if (play[0])
			outl(play[0], io + SIS_PLAY_START_A_REG);
		if (play[1])
			outl(play[1], io + SIS_PLAY_START_B_REG);
	} else {
		if (record)
			outl(record, io + SIS_RECORD_STOP_REG);
		if (play[0])
			outl(play[0], io + SIS_PLAY_STOP_A_REG);
		if (play[1])
			outl(play[1], io + SIS_PLAY_STOP_B_REG);
	}
	return 0;
}

static snd_pcm_uframes_t sis_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct voice *voice = runtime->private_data;
	u32 cso;

	cso = readl(voice->ctrl_base + SIS_PLAY_DMA_FORMAT_CSO);
	cso &= 0xffff;
	return cso;
}

static int sis_capture_open(struct snd_pcm_substream *substream)
{
	struct sis7019 *sis = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct voice *voice = &sis->capture_voice;
	unsigned long flags;

	/* FIXME: The driver only supports recording from one channel
	 * at the moment, but it could support more.
	 */
	spin_lock_irqsave(&sis->voice_lock, flags);
	if (voice->flags & VOICE_IN_USE)
		voice = NULL;
	else
		voice->flags |= VOICE_IN_USE;
	spin_unlock_irqrestore(&sis->voice_lock, flags);

	if (!voice)
		return -EAGAIN;

	voice->substream = substream;
	runtime->private_data = voice;
	runtime->hw = sis_capture_hw_info;
	runtime->hw.rates = sis->ac97[0]->rates[AC97_RATES_ADC];
	snd_pcm_limit_hw_rates(runtime);
	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
						9, 0xfff9);
	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
						9, 0xfff9);
	snd_pcm_set_sync(substream);
	return 0;
}

static int sis_capture_hw_params(struct snd_pcm_substream *substream,
					struct snd_pcm_hw_params *hw_params)
{
	struct sis7019 *sis = snd_pcm_substream_chip(substream);
	int rc;

	rc = snd_ac97_set_rate(sis->ac97[0], AC97_PCM_LR_ADC_RATE,
						params_rate(hw_params));
	if (rc)
		goto out;

	rc = sis_alloc_timing_voice(substream, hw_params);

out:
	return rc;
}

static void sis_prepare_timing_voice(struct voice *voice,
					struct snd_pcm_substream *substream)
{
	struct sis7019 *sis = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct voice *timing = voice->timing;
	void __iomem *play_base = timing->ctrl_base;
	void __iomem *wave_base = timing->wave_base;
	u16 buffer_size, period_size;
	u32 format, control, sso_eso, delta;
	u32 vperiod, sso, reg;

	/* Set our initial buffer and period as large as we can given a
	 * single page of silence.
	 */
	buffer_size = 4096 / runtime->channels;
	buffer_size /= snd_pcm_format_size(runtime->format, 1);
	period_size = buffer_size;

	/* Initially, we want to interrupt just a bit behind the end of
	 * the period we're clocking out. 12 samples seems to give a good
	 * delay.
	 *
	 * We want to spread our interrupts throughout the virtual period,
	 * so that we don't end up with two interrupts back to back at the
	 * end -- this helps minimize the effects of any jitter. Adjust our
	 * clocking period size so that the last period is at least a fourth
	 * of a full period.
	 *
	 * This is all moot if we don't need to use virtual periods.
	 */
	vperiod = runtime->period_size + 12;
	if (vperiod > period_size) {
		u16 tail = vperiod % period_size;
		u16 quarter_period = period_size / 4;

		if (tail && tail < quarter_period) {
			u16 loops = vperiod / period_size;

			tail = quarter_period - tail;
			tail += loops - 1;
			tail /= loops;
			period_size -= tail;
		}

		sso = period_size - 1;
	} else {
		/* The initial period will fit inside the buffer, so we
		 * don't need to use virtual periods -- disable them.
		 */
		period_size = runtime->period_size;
		sso = vperiod - 1;
		vperiod = 0;
	}

	/* The interrupt handler implements the timing synchronization, so
	 * setup its state.
	 */
	timing->flags |= VOICE_SYNC_TIMING;
	timing->sync_base = voice->ctrl_base;
	timing->sync_cso = runtime->period_size;
	timing->sync_period_size = runtime->period_size;
	timing->sync_buffer_size = runtime->buffer_size;
	timing->period_size = period_size;
	timing->buffer_size = buffer_size;
	timing->sso = sso;
	timing->vperiod = vperiod;

	/* Using unsigned samples with the all-zero silence buffer
	 * forces the output to the lower rail, killing playback.
	 * So ignore unsigned vs signed -- it doesn't change the timing.
	 */
	format = 0;
	if (snd_pcm_format_width(runtime->format) == 8)
		format = SIS_CAPTURE_DMA_FORMAT_8BIT;
	if (runtime->channels == 1)
		format |= SIS_CAPTURE_DMA_FORMAT_MONO;

	control = timing->buffer_size - 1;
	control |= SIS_PLAY_DMA_LOOP | SIS_PLAY_DMA_INTR_AT_SSO;
	sso_eso = timing->buffer_size - 1;
	sso_eso |= timing->sso << 16;

	delta = sis_rate_to_delta(runtime->rate);

	/* We've done the math, now configure the channel.
	 */
	writel(format, play_base + SIS_PLAY_DMA_FORMAT_CSO);
	writel(sis->silence_dma_addr, play_base + SIS_PLAY_DMA_BASE);
	writel(control, play_base + SIS_PLAY_DMA_CONTROL);
	writel(sso_eso, play_base + SIS_PLAY_DMA_SSO_ESO);

	for (reg = 0; reg < SIS_WAVE_SIZE; reg += 4)
		writel(0, wave_base + reg);

	writel(SIS_WAVE_GENERAL_WAVE_VOLUME, wave_base + SIS_WAVE_GENERAL);
	writel(delta << 16, wave_base + SIS_WAVE_GENERAL_ARTICULATION);
	writel(SIS_WAVE_CHANNEL_CONTROL_FIRST_SAMPLE |
			SIS_WAVE_CHANNEL_CONTROL_AMP_ENABLE |
			SIS_WAVE_CHANNEL_CONTROL_INTERPOLATE_ENABLE,
			wave_base + SIS_WAVE_CHANNEL_CONTROL);
}

static int sis_pcm_capture_prepare(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct voice *voice = runtime->private_data;
	void __iomem *rec_base = voice->ctrl_base;
	u32 format, dma_addr, control;
	u16 leo;

	/* We rely on the PCM core to ensure that the parameters for this
	 * substream do not change on us while we're programming the HW.
	 */
	format = 0;
	if (snd_pcm_format_width(runtime->format) == 8)
		format = SIS_CAPTURE_DMA_FORMAT_8BIT;
	if (!snd_pcm_format_signed(runtime->format))
		format |= SIS_CAPTURE_DMA_FORMAT_UNSIGNED;
	if (runtime->channels == 1)
		format |= SIS_CAPTURE_DMA_FORMAT_MONO;

	dma_addr = runtime->dma_addr;
	leo = runtime->buffer_size - 1;
	control = leo | SIS_CAPTURE_DMA_LOOP;

	/* If we've got more than two periods per buffer, then we have
	 * use a timing voice to clock out the periods. Otherwise, we can
	 * use the capture channel's interrupts.
	 */
	if (voice->timing) {
		sis_prepare_timing_voice(voice, substream);
	} else {
		control |= SIS_CAPTURE_DMA_INTR_AT_LEO;
		if (runtime->period_size != runtime->buffer_size)
			control |= SIS_CAPTURE_DMA_INTR_AT_MLP;
	}

	writel(format, rec_base + SIS_CAPTURE_DMA_FORMAT_CSO);
	writel(dma_addr, rec_base + SIS_CAPTURE_DMA_BASE);
	writel(control, rec_base + SIS_CAPTURE_DMA_CONTROL);

	/* Force the writes to post. */
	readl(rec_base);

	return 0;
}

static const struct snd_pcm_ops sis_playback_ops = {
	.open = sis_playback_open,
	.close = sis_substream_close,
	.prepare = sis_pcm_playback_prepare,
	.trigger = sis_pcm_trigger,
	.pointer = sis_pcm_pointer,
};

static const struct snd_pcm_ops sis_capture_ops = {
	.open = sis_capture_open,
	.close = sis_substream_close,
	.hw_params = sis_capture_hw_params,
	.prepare = sis_pcm_capture_prepare,
	.trigger = sis_pcm_trigger,
	.pointer = sis_pcm_pointer,
};

static int sis_pcm_create(struct sis7019 *sis)
{
	struct snd_pcm *pcm;
	int rc;

	/* We have 64 voices, and the driver currently records from
	 * only one channel, though that could change in the future.
	 */
	rc = snd_pcm_new(sis->card, "SiS7019", 0, 64, 1, &pcm);
	if (rc)
		return rc;

	pcm->private_data = sis;
	strcpy(pcm->name, "SiS7019");
	sis->pcm = pcm;

	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &sis_playback_ops);
	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &sis_capture_ops);

	/* Try to preallocate some memory, but it's not the end of the
	 * world if this fails.
	 */
	snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
				       &sis->pci->dev, 64*1024, 128*1024);

	return 0;
}

static unsigned short sis_ac97_rw(struct sis7019 *sis, int codec, u32 cmd)
{
	unsigned long io = sis->ioport;
	unsigned short val = 0xffff;
	u16 status;
	u16 rdy;
	int count;
	static const u16 codec_ready[3] = {
		SIS_AC97_STATUS_CODEC_READY,
		SIS_AC97_STATUS_CODEC2_READY,
		SIS_AC97_STATUS_CODEC3_READY,
	};

	rdy = codec_ready[codec];


	/* Get the AC97 semaphore -- software first, so we don't spin
	 * pounding out IO reads on the hardware semaphore...
	 */
	mutex_lock(&sis->ac97_mutex);

	count = 0xffff;
	while ((inw(io + SIS_AC97_SEMA) & SIS_AC97_SEMA_BUSY) && --count)
		udelay(1);

	if (!count)
		goto timeout;

	/* ... and wait for any outstanding commands to complete ...
	 */
	count = 0xffff;
	do {
		status = inw(io + SIS_AC97_STATUS);
		if ((status & rdy) && !(status & SIS_AC97_STATUS_BUSY))
			break;

		udelay(1);
	} while (--count);

	if (!count)
		goto timeout_sema;

	/* ... before sending our command and waiting for it to finish ...
	 */
	outl(cmd, io + SIS_AC97_CMD);
	udelay(10);

	count = 0xffff;
	while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count)
		udelay(1);

	/* ... and reading the results (if any).
	 */
	val = inl(io + SIS_AC97_CMD) >> 16;

timeout_sema:
	outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA);
timeout:
	mutex_unlock(&sis->ac97_mutex);

	if (!count) {
		dev_err(&sis->pci->dev, "ac97 codec %d timeout cmd 0x%08x\n",
					codec, cmd);
	}

	return val;
}

static void sis_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
				unsigned short val)
{
	static const u32 cmd[3] = {
		SIS_AC97_CMD_CODEC_WRITE,
		SIS_AC97_CMD_CODEC2_WRITE,
		SIS_AC97_CMD_CODEC3_WRITE,
	};
	sis_ac97_rw(ac97->private_data, ac97->num,
			(val << 16) | (reg << 8) | cmd[ac97->num]);
}

static unsigned short sis_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
{
	static const u32 cmd[3] = {
		SIS_AC97_CMD_CODEC_READ,
		SIS_AC97_CMD_CODEC2_READ,
		SIS_AC97_CMD_CODEC3_READ,
	};
	return sis_ac97_rw(ac97->private_data, ac97->num,
					(reg << 8) | cmd[ac97->num]);
}

static int sis_mixer_create(struct sis7019 *sis)
{
	struct snd_ac97_bus *bus;
	struct snd_ac97_template ac97;
	static const struct snd_ac97_bus_ops ops = {
		.write = sis_ac97_write,
		.read = sis_ac97_read,
	};
	int rc;

	memset(&ac97, 0, sizeof(ac97));
	ac97.private_data = sis;

	rc = snd_ac97_bus(sis->card, 0, &ops, NULL, &bus);
	if (!rc && sis->codecs_present & SIS_PRIMARY_CODEC_PRESENT)
		rc = snd_ac97_mixer(bus, &ac97, &sis->ac97[0]);
	ac97.num = 1;
	if (!rc && (sis->codecs_present & SIS_SECONDARY_CODEC_PRESENT))
		rc = snd_ac97_mixer(bus, &ac97, &sis->ac97[1]);
	ac97.num = 2;
	if (!rc && (sis->codecs_present & SIS_TERTIARY_CODEC_PRESENT))
		rc = snd_ac97_mixer(bus, &ac97, &sis->ac97[2]);

	/* If we return an error here, then snd_card_free() should
	 * free up any ac97 codecs that got created, as well as the bus.
	 */
	return rc;
}

static void sis_free_suspend(struct sis7019 *sis)
{
	int i;

	for (i = 0; i < SIS_SUSPEND_PAGES; i++)
		kfree(sis->suspend_state[i]);
}

static int sis_chip_free(struct sis7019 *sis)
{
	/* Reset the chip, and disable all interrputs.
	 */
	outl(SIS_GCR_SOFTWARE_RESET, sis->ioport + SIS_GCR);
	udelay(25);
	outl(0, sis->ioport + SIS_GCR);
	outl(0, sis->ioport + SIS_GIER);

	/* Now, free everything we allocated.
	 */
	if (sis->irq >= 0)
		free_irq(sis->irq, sis);

	iounmap(sis->ioaddr);
	pci_release_regions(sis->pci);
	pci_disable_device(sis->pci);
	sis_free_suspend(sis);
	return 0;
}

static int sis_dev_free(struct snd_device *dev)
{
	struct sis7019 *sis = dev->device_data;
	return sis_chip_free(sis);
}

static int sis_chip_init(struct sis7019 *sis)
{
	unsigned long io = sis->ioport;
	void __iomem *ioaddr = sis->ioaddr;
	unsigned long timeout;
	u16 status;
	int count;
	int i;

	/* Reset the audio controller
	 */
	outl(SIS_GCR_SOFTWARE_RESET, io + SIS_GCR);
	udelay(25);
	outl(0, io + SIS_GCR);

	/* Get the AC-link semaphore, and reset the codecs
	 */
	count = 0xffff;
	while ((inw(io + SIS_AC97_SEMA) & SIS_AC97_SEMA_BUSY) && --count)
		udelay(1);

	if (!count)
		return -EIO;

	outl(SIS_AC97_CMD_CODEC_COLD_RESET, io + SIS_AC97_CMD);
	udelay(250);

	count = 0xffff;
	while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count)
		udelay(1);

	/* Command complete, we can let go of the semaphore now.
	 */
	outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA);
	if (!count)
		return -EIO;

	/* Now that we've finished the reset, find out what's attached.
	 * There are some codec/board combinations that take an extremely
	 * long time to come up. 350+ ms has been observed in the field,
	 * so we'll give them up to 500ms.
	 */
	sis->codecs_present = 0;
	timeout = msecs_to_jiffies(500) + jiffies;
	while (time_before_eq(jiffies, timeout)) {
		status = inl(io + SIS_AC97_STATUS);
		if (status & SIS_AC97_STATUS_CODEC_READY)
			sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT;
		if (status & SIS_AC97_STATUS_CODEC2_READY)
			sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT;
		if (status & SIS_AC97_STATUS_CODEC3_READY)
			sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT;

		if (sis->codecs_present == codecs)
			break;

		msleep(1);
	}

	/* All done, check for errors.
	 */
	if (!sis->codecs_present) {
		dev_err(&sis->pci->dev, "could not find any codecs\n");
		return -EIO;
	}

	if (sis->codecs_present != codecs) {
		dev_warn(&sis->pci->dev, "missing codecs, found %0x, expected %0x\n",
					 sis->codecs_present, codecs);
	}

	/* Let the hardware know that the audio driver is alive,
	 * and enable PCM slots on the AC-link for L/R playback (3 & 4) and
	 * record channels. We're going to want to use Variable Rate Audio
	 * for recording, to avoid needlessly resampling from 48kHZ.
	 */
	outl(SIS_AC97_CONF_AUDIO_ALIVE, io + SIS_AC97_CONF);
	outl(SIS_AC97_CONF_AUDIO_ALIVE | SIS_AC97_CONF_PCM_LR_ENABLE |
		SIS_AC97_CONF_PCM_CAP_MIC_ENABLE |
		SIS_AC97_CONF_PCM_CAP_LR_ENABLE |
		SIS_AC97_CONF_CODEC_VRA_ENABLE, io + SIS_AC97_CONF);

	/* All AC97 PCM slots should be sourced from sub-mixer 0.
	 */
	outl(0, io + SIS_AC97_PSR);

	/* There is only one valid DMA setup for a PCI environment.
	 */
	outl(SIS_DMA_CSR_PCI_SETTINGS, io + SIS_DMA_CSR);

	/* Reset the synchronization groups for all of the channels
	 * to be asynchronous. If we start doing SPDIF or 5.1 sound, etc.
	 * we'll need to change how we handle these. Until then, we just
	 * assign sub-mixer 0 to all playback channels, and avoid any
	 * attenuation on the audio.
	 */
	outl(0, io + SIS_PLAY_SYNC_GROUP_A);
	outl(0, io + SIS_PLAY_SYNC_GROUP_B);
	outl(0, io + SIS_PLAY_SYNC_GROUP_C);
	outl(0, io + SIS_PLAY_SYNC_GROUP_D);
	outl(0, io + SIS_MIXER_SYNC_GROUP);

	for (i = 0; i < 64; i++) {
		writel(i, SIS_MIXER_START_ADDR(ioaddr, i));
		writel(SIS_MIXER_RIGHT_NO_ATTEN | SIS_MIXER_LEFT_NO_ATTEN |
				SIS_MIXER_DEST_0, SIS_MIXER_ADDR(ioaddr, i));
	}

	/* Don't attenuate any audio set for the wave amplifier.
	 *
	 * FIXME: Maximum attenuation is set for the music amp, which will
	 * need to change if we start using the synth engine.
	 */
	outl(0xffff0000, io + SIS_WEVCR);

	/* Ensure that the wave engine is in normal operating mode.
	 */
	outl(0, io + SIS_WECCR);

	/* Go ahead and enable the DMA interrupts. They won't go live
	 * until we start a channel.
	 */
	outl(SIS_GIER_AUDIO_PLAY_DMA_IRQ_ENABLE |
		SIS_GIER_AUDIO_RECORD_DMA_IRQ_ENABLE, io + SIS_GIER);

	return 0;
}

#ifdef CONFIG_PM_SLEEP
static int sis_suspend(struct device *dev)
{
	struct snd_card *card = dev_get_drvdata(dev);
	struct sis7019 *sis = card->private_data;
	void __iomem *ioaddr = sis->ioaddr;
	int i;

	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
	if (sis->codecs_present & SIS_PRIMARY_CODEC_PRESENT)
		snd_ac97_suspend(sis->ac97[0]);
	if (sis->codecs_present & SIS_SECONDARY_CODEC_PRESENT)
		snd_ac97_suspend(sis->ac97[1]);
	if (sis->codecs_present & SIS_TERTIARY_CODEC_PRESENT)
		snd_ac97_suspend(sis->ac97[2]);

	/* snd_pcm_suspend_all() stopped all channels, so we're quiescent.
	 */
	if (sis->irq >= 0) {
		free_irq(sis->irq, sis);
		sis->irq = -1;
	}

	/* Save the internal state away
	 */
	for (i = 0; i < 4; i++) {
		memcpy_fromio(sis->suspend_state[i], ioaddr, 4096);
		ioaddr += 4096;
	}

	return 0;
}

static int sis_resume(struct device *dev)
{
	struct pci_dev *pci = to_pci_dev(dev);
	struct snd_card *card = dev_get_drvdata(dev);
	struct sis7019 *sis = card->private_data;
	void __iomem *ioaddr = sis->ioaddr;
	int i;

	if (sis_chip_init(sis)) {
		dev_err(&pci->dev, "unable to re-init controller\n");
		goto error;
	}

	if (request_irq(pci->irq, sis_interrupt, IRQF_SHARED,
			KBUILD_MODNAME, sis)) {
		dev_err(&pci->dev, "unable to regain IRQ %d\n", pci->irq);
		goto error;
	}

	/* Restore saved state, then clear out the page we use for the
	 * silence buffer.
	 */
	for (i = 0; i < 4; i++) {
		memcpy_toio(ioaddr, sis->suspend_state[i], 4096);
		ioaddr += 4096;
	}

	memset(sis->suspend_state[0], 0, 4096);

	sis->irq = pci->irq;

	if (sis->codecs_present & SIS_PRIMARY_CODEC_PRESENT)
		snd_ac97_resume(sis->ac97[0]);
	if (sis->codecs_present & SIS_SECONDARY_CODEC_PRESENT)
		snd_ac97_resume(sis->ac97[1]);
	if (sis->codecs_present & SIS_TERTIARY_CODEC_PRESENT)
		snd_ac97_resume(sis->ac97[2]);

	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
	return 0;

error:
	snd_card_disconnect(card);
	return -EIO;
}

static SIMPLE_DEV_PM_OPS(sis_pm, sis_suspend, sis_resume);
#define SIS_PM_OPS	&sis_pm
#else
#define SIS_PM_OPS	NULL
#endif /* CONFIG_PM_SLEEP */

static int sis_alloc_suspend(struct sis7019 *sis)
{
	int i;

	/* We need 16K to store the internal wave engine state during a
	 * suspend, but we don't need it to be contiguous, so play nice
	 * with the memory system. We'll also use this area for a silence
	 * buffer.
	 */
	for (i = 0; i < SIS_SUSPEND_PAGES; i++) {
		sis->suspend_state[i] = kmalloc(4096, GFP_KERNEL);
		if (!sis->suspend_state[i])
			return -ENOMEM;
	}
	memset(sis->suspend_state[0], 0, 4096);

	return 0;
}

static int sis_chip_create(struct snd_card *card,
			   struct pci_dev *pci)
{
	struct sis7019 *sis = card->private_data;
	struct voice *voice;
	static const struct snd_device_ops ops = {
		.dev_free = sis_dev_free,
	};
	int rc;
	int i;

	rc = pci_enable_device(pci);
	if (rc)
		goto error_out;

	rc = dma_set_mask(&pci->dev, DMA_BIT_MASK(30));
	if (rc < 0) {
		dev_err(&pci->dev, "architecture does not support 30-bit PCI busmaster DMA");
		goto error_out_enabled;
	}

	memset(sis, 0, sizeof(*sis));
	mutex_init(&sis->ac97_mutex);
	spin_lock_init(&sis->voice_lock);
	sis->card = card;
	sis->pci = pci;
	sis->irq = -1;
	sis->ioport = pci_resource_start(pci, 0);

	rc = pci_request_regions(pci, "SiS7019");
	if (rc) {
		dev_err(&pci->dev, "unable request regions\n");
		goto error_out_enabled;
	}

	rc = -EIO;
	sis->ioaddr = ioremap(pci_resource_start(pci, 1), 0x4000);
	if (!sis->ioaddr) {
		dev_err(&pci->dev, "unable to remap MMIO, aborting\n");
		goto error_out_cleanup;
	}

	rc = sis_alloc_suspend(sis);
	if (rc < 0) {
		dev_err(&pci->dev, "unable to allocate state storage\n");
		goto error_out_cleanup;
	}

	rc = sis_chip_init(sis);
	if (rc)
		goto error_out_cleanup;

	rc = request_irq(pci->irq, sis_interrupt, IRQF_SHARED, KBUILD_MODNAME,
			 sis);
	if (rc) {
		dev_err(&pci->dev, "unable to allocate irq %d\n", sis->irq);
		goto error_out_cleanup;
	}

	sis->irq = pci->irq;
	card->sync_irq = sis->irq;
	pci_set_master(pci);

	for (i = 0; i < 64; i++) {
		voice = &sis->voices[i];
		voice->num = i;
		voice->ctrl_base = SIS_PLAY_DMA_ADDR(sis->ioaddr, i);
		voice->wave_base = SIS_WAVE_ADDR(sis->ioaddr, i);
	}

	voice = &sis->capture_voice;
	voice->flags = VOICE_CAPTURE;
	voice->num = SIS_CAPTURE_CHAN_AC97_PCM_IN;
	voice->ctrl_base = SIS_CAPTURE_DMA_ADDR(sis->ioaddr, voice->num);

	rc = snd_device_new(card, SNDRV_DEV_LOWLEVEL, sis, &ops);
	if (rc)
		goto error_out_cleanup;

	return 0;

error_out_cleanup:
	sis_chip_free(sis);

error_out_enabled:
	pci_disable_device(pci);

error_out:
	return rc;
}

static int snd_sis7019_probe(struct pci_dev *pci,
			     const struct pci_device_id *pci_id)
{
	struct snd_card *card;
	struct sis7019 *sis;
	int rc;

	rc = -ENOENT;
	if (!enable)
		goto error_out;

	/* The user can specify which codecs should be present so that we
	 * can wait for them to show up if they are slow to recover from
	 * the AC97 cold reset. We default to a single codec, the primary.
	 *
	 * We assume that SIS_PRIMARY_*_PRESENT matches bits 0-2.
	 */
	codecs &= SIS_PRIMARY_CODEC_PRESENT | SIS_SECONDARY_CODEC_PRESENT |
		  SIS_TERTIARY_CODEC_PRESENT;
	if (!codecs)
		codecs = SIS_PRIMARY_CODEC_PRESENT;

	rc = snd_card_new(&pci->dev, index, id, THIS_MODULE,
			  sizeof(*sis), &card);
	if (rc < 0)
		goto error_out;

	strcpy(card->driver, "SiS7019");
	strcpy(card->shortname, "SiS7019");
	rc = sis_chip_create(card, pci);
	if (rc)
		goto card_error_out;

	sis = card->private_data;

	rc = sis_mixer_create(sis);
	if (rc)
		goto card_error_out;

	rc = sis_pcm_create(sis);
	if (rc)
		goto card_error_out;

	snprintf(card->longname, sizeof(card->longname),
			"%s Audio Accelerator with %s at 0x%lx, irq %d",
			card->shortname, snd_ac97_get_short_name(sis->ac97[0]),
			sis->ioport, sis->irq);

	rc = snd_card_register(card);
	if (rc)
		goto card_error_out;

	pci_set_drvdata(pci, card);
	return 0;

card_error_out:
	snd_card_free(card);

error_out:
	return rc;
}

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

static struct pci_driver sis7019_driver = {
	.name = KBUILD_MODNAME,
	.id_table = snd_sis7019_ids,
	.probe = snd_sis7019_probe,
	.remove = snd_sis7019_remove,
	.driver = {
		.pm = SIS_PM_OPS,
	},
};

module_pci_driver(sis7019_driver);
