[ALSA] Reduce interrupt latency in sound/pci/via82xx.c
Modules: VIA82xx driver The change only affects the via823x kind of chips. Here the via8233_pcm_pointer_hw() function (named snd_via8233_pcm_pointer() before) needed to loop until a non zero position is red from the chip. Measurements have shown that more than 200 loops are typically needed on an Athlon64. As io-reads cost many cycles, those loops sum up huge. via8233_pcm_pointer_hw() runs either in interrupt or with interrupts disabled. So it introduces significant interrupt latency. The patch introduces a calculated position value hwptr_done, that is updated by the interrupt routine when a period is completed. It is only used, if the 823x chip returns a zero position, which can't be interpreted reliably. Further optimisation is applied on the 8233 chip's interrupt routine: Only the SGD_SHADOW is read, as it contains all infos needed. We ommit ~5 more register reads that way. Signed-off-by: Karsten Wiese <annabellesgarden@yahoo.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
f0597a416d
commit
4f550df58f
1 changed files with 133 additions and 41 deletions
|
@ -41,6 +41,9 @@
|
||||||
* device for applications.
|
* device for applications.
|
||||||
* - clean up the code, separate low-level initialization
|
* - clean up the code, separate low-level initialization
|
||||||
* routines for each chipset.
|
* routines for each chipset.
|
||||||
|
*
|
||||||
|
* Sep. 26, 2005 Karsten Wiese <annabellesgarden@yahoo.de>
|
||||||
|
* - Optimize position calculation for the 823x chips.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sound/driver.h>
|
#include <sound/driver.h>
|
||||||
|
@ -131,6 +134,7 @@ module_param(enable, int, 0444);
|
||||||
/* common offsets */
|
/* common offsets */
|
||||||
#define VIA_REG_OFFSET_STATUS 0x00 /* byte - channel status */
|
#define VIA_REG_OFFSET_STATUS 0x00 /* byte - channel status */
|
||||||
#define VIA_REG_STAT_ACTIVE 0x80 /* RO */
|
#define VIA_REG_STAT_ACTIVE 0x80 /* RO */
|
||||||
|
#define VIA8233_SHADOW_STAT_ACTIVE 0x08 /* RO */
|
||||||
#define VIA_REG_STAT_PAUSED 0x40 /* RO */
|
#define VIA_REG_STAT_PAUSED 0x40 /* RO */
|
||||||
#define VIA_REG_STAT_TRIGGER_QUEUED 0x08 /* RO */
|
#define VIA_REG_STAT_TRIGGER_QUEUED 0x08 /* RO */
|
||||||
#define VIA_REG_STAT_STOPPED 0x04 /* RWC */
|
#define VIA_REG_STAT_STOPPED 0x04 /* RWC */
|
||||||
|
@ -329,6 +333,9 @@ struct via_dev {
|
||||||
unsigned int fragsize;
|
unsigned int fragsize;
|
||||||
unsigned int bufsize;
|
unsigned int bufsize;
|
||||||
unsigned int bufsize2;
|
unsigned int bufsize2;
|
||||||
|
int hwptr_done; /* processed frame position in the buffer */
|
||||||
|
int in_interrupt;
|
||||||
|
int shadow_shift;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -395,8 +402,10 @@ struct _snd_via82xx {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct pci_device_id snd_via82xx_ids[] = {
|
static struct pci_device_id snd_via82xx_ids[] = {
|
||||||
{ 0x1106, 0x3058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA686, }, /* 686A */
|
/* 0x1106, 0x3058 */
|
||||||
{ 0x1106, 0x3059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA8233, }, /* VT8233 */
|
{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA686, }, /* 686A */
|
||||||
|
/* 0x1106, 0x3059 */
|
||||||
|
{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA8233, }, /* VT8233 */
|
||||||
{ 0, }
|
{ 0, }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -550,7 +559,7 @@ static void snd_via82xx_codec_write(ac97_t *ac97,
|
||||||
{
|
{
|
||||||
via82xx_t *chip = ac97->private_data;
|
via82xx_t *chip = ac97->private_data;
|
||||||
unsigned int xval;
|
unsigned int xval;
|
||||||
|
|
||||||
xval = !ac97->num ? VIA_REG_AC97_CODEC_ID_PRIMARY : VIA_REG_AC97_CODEC_ID_SECONDARY;
|
xval = !ac97->num ? VIA_REG_AC97_CODEC_ID_PRIMARY : VIA_REG_AC97_CODEC_ID_SECONDARY;
|
||||||
xval <<= VIA_REG_AC97_CODEC_ID_SHIFT;
|
xval <<= VIA_REG_AC97_CODEC_ID_SHIFT;
|
||||||
xval |= reg << VIA_REG_AC97_CMD_SHIFT;
|
xval |= reg << VIA_REG_AC97_CMD_SHIFT;
|
||||||
|
@ -598,14 +607,15 @@ static void snd_via82xx_channel_reset(via82xx_t *chip, viadev_t *viadev)
|
||||||
outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */
|
outb(0x00, VIADEV_REG(viadev, OFFSET_TYPE)); /* for via686 */
|
||||||
// outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR));
|
// outl(0, VIADEV_REG(viadev, OFFSET_CURR_PTR));
|
||||||
viadev->lastpos = 0;
|
viadev->lastpos = 0;
|
||||||
|
viadev->hwptr_done = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Interrupt handler
|
* Interrupt handler
|
||||||
|
* Used for 686 and 8233A
|
||||||
*/
|
*/
|
||||||
|
static irqreturn_t snd_via686_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||||
static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
|
||||||
{
|
{
|
||||||
via82xx_t *chip = dev_id;
|
via82xx_t *chip = dev_id;
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
|
@ -624,13 +634,23 @@ static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *
|
||||||
for (i = 0; i < chip->num_devs; i++) {
|
for (i = 0; i < chip->num_devs; i++) {
|
||||||
viadev_t *viadev = &chip->devs[i];
|
viadev_t *viadev = &chip->devs[i];
|
||||||
unsigned char c_status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
|
unsigned char c_status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
|
||||||
c_status &= (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG|VIA_REG_STAT_STOPPED);
|
if (! (c_status & (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG|VIA_REG_STAT_STOPPED)))
|
||||||
if (! c_status)
|
|
||||||
continue;
|
continue;
|
||||||
if (viadev->substream && viadev->running) {
|
if (viadev->substream && viadev->running) {
|
||||||
|
/*
|
||||||
|
* Update hwptr_done based on 'period elapsed'
|
||||||
|
* interrupts. We'll use it, when the chip returns 0
|
||||||
|
* for OFFSET_CURR_COUNT.
|
||||||
|
*/
|
||||||
|
if (c_status & VIA_REG_STAT_EOL)
|
||||||
|
viadev->hwptr_done = 0;
|
||||||
|
else
|
||||||
|
viadev->hwptr_done += viadev->fragsize;
|
||||||
|
viadev->in_interrupt = c_status;
|
||||||
spin_unlock(&chip->reg_lock);
|
spin_unlock(&chip->reg_lock);
|
||||||
snd_pcm_period_elapsed(viadev->substream);
|
snd_pcm_period_elapsed(viadev->substream);
|
||||||
spin_lock(&chip->reg_lock);
|
spin_lock(&chip->reg_lock);
|
||||||
|
viadev->in_interrupt = 0;
|
||||||
}
|
}
|
||||||
outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
|
outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
|
||||||
}
|
}
|
||||||
|
@ -638,6 +658,60 @@ static irqreturn_t snd_via82xx_interrupt(int irq, void *dev_id, struct pt_regs *
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interrupt handler
|
||||||
|
*/
|
||||||
|
static irqreturn_t snd_via8233_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
||||||
|
{
|
||||||
|
via82xx_t *chip = dev_id;
|
||||||
|
unsigned int status;
|
||||||
|
unsigned int i;
|
||||||
|
int irqreturn = 0;
|
||||||
|
|
||||||
|
/* check status for each stream */
|
||||||
|
spin_lock(&chip->reg_lock);
|
||||||
|
status = inl(VIAREG(chip, SGD_SHADOW));
|
||||||
|
|
||||||
|
for (i = 0; i < chip->num_devs; i++) {
|
||||||
|
viadev_t *viadev = &chip->devs[i];
|
||||||
|
snd_pcm_substream_t *substream;
|
||||||
|
unsigned char c_status, shadow_status;
|
||||||
|
|
||||||
|
shadow_status = (status >> viadev->shadow_shift) &
|
||||||
|
(VIA8233_SHADOW_STAT_ACTIVE|VIA_REG_STAT_EOL|
|
||||||
|
VIA_REG_STAT_FLAG);
|
||||||
|
c_status = shadow_status & (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG);
|
||||||
|
if (!c_status)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
substream = viadev->substream;
|
||||||
|
if (substream && viadev->running) {
|
||||||
|
/*
|
||||||
|
* Update hwptr_done based on 'period elapsed'
|
||||||
|
* interrupts. We'll use it, when the chip returns 0
|
||||||
|
* for OFFSET_CURR_COUNT.
|
||||||
|
*/
|
||||||
|
if (c_status & VIA_REG_STAT_EOL)
|
||||||
|
viadev->hwptr_done = 0;
|
||||||
|
else
|
||||||
|
viadev->hwptr_done += viadev->fragsize;
|
||||||
|
viadev->in_interrupt = c_status;
|
||||||
|
if (shadow_status & VIA8233_SHADOW_STAT_ACTIVE)
|
||||||
|
viadev->in_interrupt |= VIA_REG_STAT_ACTIVE;
|
||||||
|
spin_unlock(&chip->reg_lock);
|
||||||
|
|
||||||
|
snd_pcm_period_elapsed(substream);
|
||||||
|
|
||||||
|
spin_lock(&chip->reg_lock);
|
||||||
|
viadev->in_interrupt = 0;
|
||||||
|
}
|
||||||
|
outb(c_status, VIADEV_REG(viadev, OFFSET_STATUS)); /* ack */
|
||||||
|
irqreturn = 1;
|
||||||
|
}
|
||||||
|
spin_unlock(&chip->reg_lock);
|
||||||
|
return IRQ_RETVAL(irqreturn);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* PCM callbacks
|
* PCM callbacks
|
||||||
*/
|
*/
|
||||||
|
@ -701,6 +775,8 @@ static inline unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, u
|
||||||
size = viadev->idx_table[idx].size;
|
size = viadev->idx_table[idx].size;
|
||||||
base = viadev->idx_table[idx].offset;
|
base = viadev->idx_table[idx].offset;
|
||||||
res = base + size - count;
|
res = base + size - count;
|
||||||
|
if (res >= viadev->bufsize)
|
||||||
|
res -= viadev->bufsize;
|
||||||
|
|
||||||
/* check the validity of the calculated position */
|
/* check the validity of the calculated position */
|
||||||
if (size < count) {
|
if (size < count) {
|
||||||
|
@ -730,9 +806,6 @@ static inline unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
viadev->lastpos = res; /* remember the last position */
|
|
||||||
if (res >= viadev->bufsize)
|
|
||||||
res -= viadev->bufsize;
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -760,6 +833,7 @@ static snd_pcm_uframes_t snd_via686_pcm_pointer(snd_pcm_substream_t *substream)
|
||||||
else /* CURR_PTR holds the address + 8 */
|
else /* CURR_PTR holds the address + 8 */
|
||||||
idx = ((ptr - (unsigned int)viadev->table.addr) / 8 - 1) % viadev->tbl_entries;
|
idx = ((ptr - (unsigned int)viadev->table.addr) / 8 - 1) % viadev->tbl_entries;
|
||||||
res = calc_linear_pos(viadev, idx, count);
|
res = calc_linear_pos(viadev, idx, count);
|
||||||
|
viadev->lastpos = res; /* remember the last position */
|
||||||
spin_unlock(&chip->reg_lock);
|
spin_unlock(&chip->reg_lock);
|
||||||
|
|
||||||
return bytes_to_frames(substream->runtime, res);
|
return bytes_to_frames(substream->runtime, res);
|
||||||
|
@ -773,30 +847,44 @@ static snd_pcm_uframes_t snd_via8233_pcm_pointer(snd_pcm_substream_t *substream)
|
||||||
via82xx_t *chip = snd_pcm_substream_chip(substream);
|
via82xx_t *chip = snd_pcm_substream_chip(substream);
|
||||||
viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
|
viadev_t *viadev = (viadev_t *)substream->runtime->private_data;
|
||||||
unsigned int idx, count, res;
|
unsigned int idx, count, res;
|
||||||
int timeout = 5000;
|
int status;
|
||||||
|
|
||||||
snd_assert(viadev->tbl_entries, return 0);
|
snd_assert(viadev->tbl_entries, return 0);
|
||||||
if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE))
|
|
||||||
return 0;
|
|
||||||
spin_lock(&chip->reg_lock);
|
spin_lock(&chip->reg_lock);
|
||||||
do {
|
count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT));
|
||||||
count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT));
|
status = viadev->in_interrupt;
|
||||||
/* some mobos read 0 count */
|
if (!status)
|
||||||
if ((count & 0xffffff) || ! viadev->running)
|
status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
|
||||||
break;
|
|
||||||
} while (--timeout);
|
if (!(status & VIA_REG_STAT_ACTIVE)) {
|
||||||
if (! timeout)
|
res = 0;
|
||||||
snd_printd(KERN_ERR "zero position is read\n");
|
goto unlock;
|
||||||
idx = count >> 24;
|
|
||||||
if (idx >= viadev->tbl_entries) {
|
|
||||||
#ifdef POINTER_DEBUG
|
|
||||||
printk("fail: invalid idx = %i/%i\n", idx, viadev->tbl_entries);
|
|
||||||
#endif
|
|
||||||
res = viadev->lastpos;
|
|
||||||
} else {
|
|
||||||
count &= 0xffffff;
|
|
||||||
res = calc_linear_pos(viadev, idx, count);
|
|
||||||
}
|
}
|
||||||
|
if (count & 0xffffff) {
|
||||||
|
idx = count >> 24;
|
||||||
|
if (idx >= viadev->tbl_entries) {
|
||||||
|
#ifdef POINTER_DEBUG
|
||||||
|
printk("fail: invalid idx = %i/%i\n", idx, viadev->tbl_entries);
|
||||||
|
#endif
|
||||||
|
res = viadev->lastpos;
|
||||||
|
} else {
|
||||||
|
count &= 0xffffff;
|
||||||
|
res = calc_linear_pos(viadev, idx, count);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res = viadev->hwptr_done;
|
||||||
|
if (!viadev->in_interrupt) {
|
||||||
|
if (status & VIA_REG_STAT_EOL) {
|
||||||
|
res = 0;
|
||||||
|
} else
|
||||||
|
if (status & VIA_REG_STAT_FLAG) {
|
||||||
|
res += viadev->fragsize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unlock:
|
||||||
|
viadev->lastpos = res;
|
||||||
spin_unlock(&chip->reg_lock);
|
spin_unlock(&chip->reg_lock);
|
||||||
|
|
||||||
return bytes_to_frames(substream->runtime, res);
|
return bytes_to_frames(substream->runtime, res);
|
||||||
|
@ -1241,9 +1329,10 @@ static snd_pcm_ops_t snd_via8233_capture_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static void init_viadev(via82xx_t *chip, int idx, unsigned int reg_offset, int direction)
|
static void init_viadev(via82xx_t *chip, int idx, unsigned int reg_offset, int shadow_pos, int direction)
|
||||||
{
|
{
|
||||||
chip->devs[idx].reg_offset = reg_offset;
|
chip->devs[idx].reg_offset = reg_offset;
|
||||||
|
chip->devs[idx].shadow_shift = shadow_pos * 4;
|
||||||
chip->devs[idx].direction = direction;
|
chip->devs[idx].direction = direction;
|
||||||
chip->devs[idx].port = chip->port + reg_offset;
|
chip->devs[idx].port = chip->port + reg_offset;
|
||||||
}
|
}
|
||||||
|
@ -1273,9 +1362,9 @@ static int __devinit snd_via8233_pcm_new(via82xx_t *chip)
|
||||||
chip->pcms[0] = pcm;
|
chip->pcms[0] = pcm;
|
||||||
/* set up playbacks */
|
/* set up playbacks */
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++)
|
||||||
init_viadev(chip, i, 0x10 * i, 0);
|
init_viadev(chip, i, 0x10 * i, i, 0);
|
||||||
/* capture */
|
/* capture */
|
||||||
init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 1);
|
init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1);
|
||||||
|
|
||||||
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
|
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
|
||||||
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
|
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
|
||||||
|
@ -1291,9 +1380,9 @@ static int __devinit snd_via8233_pcm_new(via82xx_t *chip)
|
||||||
strcpy(pcm->name, chip->card->shortname);
|
strcpy(pcm->name, chip->card->shortname);
|
||||||
chip->pcms[1] = pcm;
|
chip->pcms[1] = pcm;
|
||||||
/* set up playback */
|
/* set up playback */
|
||||||
init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 0);
|
init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 4, 0);
|
||||||
/* set up capture */
|
/* set up capture */
|
||||||
init_viadev(chip, chip->capture_devno + 1, VIA_REG_CAPTURE_8233_STATUS + 0x10, 1);
|
init_viadev(chip, chip->capture_devno + 1, VIA_REG_CAPTURE_8233_STATUS + 0x10, 7, 1);
|
||||||
|
|
||||||
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
|
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
|
||||||
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
|
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
|
||||||
|
@ -1326,9 +1415,9 @@ static int __devinit snd_via8233a_pcm_new(via82xx_t *chip)
|
||||||
strcpy(pcm->name, chip->card->shortname);
|
strcpy(pcm->name, chip->card->shortname);
|
||||||
chip->pcms[0] = pcm;
|
chip->pcms[0] = pcm;
|
||||||
/* set up playback */
|
/* set up playback */
|
||||||
init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 0);
|
init_viadev(chip, chip->multi_devno, VIA_REG_MULTPLAY_STATUS, 4, 0);
|
||||||
/* capture */
|
/* capture */
|
||||||
init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 1);
|
init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1);
|
||||||
|
|
||||||
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
|
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
|
||||||
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
|
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
|
||||||
|
@ -1347,7 +1436,7 @@ static int __devinit snd_via8233a_pcm_new(via82xx_t *chip)
|
||||||
strcpy(pcm->name, chip->card->shortname);
|
strcpy(pcm->name, chip->card->shortname);
|
||||||
chip->pcms[1] = pcm;
|
chip->pcms[1] = pcm;
|
||||||
/* set up playback */
|
/* set up playback */
|
||||||
init_viadev(chip, chip->playback_devno, 0x30, 0);
|
init_viadev(chip, chip->playback_devno, 0x30, 3, 0);
|
||||||
|
|
||||||
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
|
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
|
||||||
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
|
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
|
||||||
|
@ -1377,8 +1466,8 @@ static int __devinit snd_via686_pcm_new(via82xx_t *chip)
|
||||||
pcm->private_data = chip;
|
pcm->private_data = chip;
|
||||||
strcpy(pcm->name, chip->card->shortname);
|
strcpy(pcm->name, chip->card->shortname);
|
||||||
chip->pcms[0] = pcm;
|
chip->pcms[0] = pcm;
|
||||||
init_viadev(chip, 0, VIA_REG_PLAYBACK_STATUS, 0);
|
init_viadev(chip, 0, VIA_REG_PLAYBACK_STATUS, 0, 0);
|
||||||
init_viadev(chip, 1, VIA_REG_CAPTURE_STATUS, 1);
|
init_viadev(chip, 1, VIA_REG_CAPTURE_STATUS, 0, 1);
|
||||||
|
|
||||||
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
|
if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
|
||||||
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
|
snd_dma_pci_data(chip->pci), 64*1024, 128*1024)) < 0)
|
||||||
|
@ -2134,7 +2223,10 @@ static int __devinit snd_via82xx_create(snd_card_t * card,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
chip->port = pci_resource_start(pci, 0);
|
chip->port = pci_resource_start(pci, 0);
|
||||||
if (request_irq(pci->irq, snd_via82xx_interrupt, SA_INTERRUPT|SA_SHIRQ,
|
if (request_irq(pci->irq,
|
||||||
|
chip_type == TYPE_VIA8233 ?
|
||||||
|
snd_via8233_interrupt : snd_via686_interrupt,
|
||||||
|
SA_INTERRUPT|SA_SHIRQ,
|
||||||
card->driver, (void *)chip)) {
|
card->driver, (void *)chip)) {
|
||||||
snd_printk("unable to grab IRQ %d\n", pci->irq);
|
snd_printk("unable to grab IRQ %d\n", pci->irq);
|
||||||
snd_via82xx_free(chip);
|
snd_via82xx_free(chip);
|
||||||
|
|
Loading…
Add table
Reference in a new issue