[alsa-devel] Backported sbxfi driver (UNTESTED!)

Takashi Iwai tiwai at suse.de
Sat Oct 11 18:01:53 CEST 2008


At Fri, 10 Oct 2008 13:17:32 -0500,
William Pitcock wrote:
> 
> With this patch, the driver does output audio, but the DAC dies and we
> only get noise. Going to try to whack at this with a larger hammer, it's
> a fairly obvious bug, it just needs some debugging. The noise sounds
> like the write pointer is off-by-one; it sort of resembles the source
> audio.

OK, good to hear that it's not always locking up.

> Some patches for mixer stuff are coming soon (next few hours
> probably)... as well as chip revision detection and some other
> niceities.

Great.  I'm looking forward to your patches.

Meanwhile, the patch below might improve something.
Basically test sets the DMA mask, and use the continuous pages instead of
SG buffers (in case it's the error cause).
Give it a try.  (And I'll update the git tree, too).

Also, try different XXX_* flags in sbxfi.c.  The default setting isn't
completely identical with OSS v4 driver.


thanks,

Takashi

diff --git a/sound/pci/sbxfi/sbxfi.c b/sound/pci/sbxfi/sbxfi.c
index 8a0eea0..86dd025 100644
--- a/sound/pci/sbxfi/sbxfi.c
+++ b/sound/pci/sbxfi/sbxfi.c
@@ -66,6 +66,9 @@ enum {
 #define SBXFI_MAX_BUFFER	(SBXFI_TLB_PAGES * SBXFI_PAGE_SIZE)
 #define SBXFI_MAX_SRCS		128	/* 256 / 2 */
 #define SBXFI_TIMER_FREQ	96000
+/* FIXME: which mask? */
+/* #define SBXFI_DMA_MASK		DMA_32BIT_MASK */
+#define SBXFI_DMA_MASK		DMA_28BIT_MASK
 
 #define MAX_CHANNELS		2
 
@@ -154,6 +157,9 @@ struct sbxfi {
 /* constant ticks */
 /* #define XXX_CONST_TICKS		(96000 * 5 / 1000) */
 
+/* SG or continuous buffer */
+#undef XXX_USE_SG
+
 #ifdef XXX_48K_ONLY
 #define BASE_RATE	48000
 #else
@@ -796,8 +802,13 @@ static int sbxfi_setup_tlb(struct sbxfi *chip, struct sbxfi_port *port,
 
 	pgtbl = (u32*)chip->tlb.area;
 	pgtbl += port->tlb_index;
+#ifdef XXX_USE_SG
 	for (p = 0; p < pages; p++, pgtbl++)
 		*pgtbl = snd_pcm_sgbuf_get_addr(substream, p * SBXFI_PAGE_SIZE);
+#else
+	for (p = 0; p < pages; p++, pgtbl++)
+		*pgtbl = substream->runtime->dma_addr + p * SBXFI_PAGE_SIZE;
+#endif
 
 	return 0;
 }
@@ -1319,7 +1330,9 @@ static struct snd_pcm_ops sbxfi_playback_ops = {
 	.prepare = sbxfi_playback_prepare,
 	.trigger = sbxfi_playback_trigger,
 	.pointer = sbxfi_pcm_pointer,
+#ifdef XXX_USE_SG
 	.page = snd_pcm_sgbuf_ops_page,
+#endif
 };
 
 static struct snd_pcm_ops sbxfi_capture_ops = {
@@ -1331,7 +1344,9 @@ static struct snd_pcm_ops sbxfi_capture_ops = {
 	.prepare = sbxfi_capture_prepare,
 	.trigger = sbxfi_capture_trigger,
 	.pointer = sbxfi_pcm_pointer,
+#ifdef XXX_USE_SG
 	.page = snd_pcm_sgbuf_ops_page,
+#endif
 };
 
 static int __devinit sbxfi_create_pcm(struct sbxfi *chip)
@@ -1351,9 +1366,15 @@ static int __devinit sbxfi_create_pcm(struct sbxfi *chip)
 	pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
 #endif
 	strcpy(pcm->name, "SB-XFi");
+#ifdef XXX_USE_SG
 	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
 					      snd_dma_pci_data(chip->pci),
 					      1024 * 64, 32 * 1024 * 1024);
+#else
+	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+					      snd_dma_pci_data(chip->pci),
+					      1024 * 64, 32 * 1024 * 1024);
+#endif
 	chip->pcm = pcm;
 	return 0;
 }
@@ -1781,6 +1802,13 @@ static int __devinit sbxfi_create(struct snd_card *card, struct pci_dev *pci,
 	if (err < 0)
 		goto error;
 
+	if (pci_set_dma_mask(pci, SBXFI_DMA_MASK) < 0 ||
+	    pci_set_consistent_dma_mask(pci, SBXFI_DMA_MASK) < 0) {
+		printk(KERN_ERR PFX "Unable to set DMA mask\n");
+		err = -EINVAL;
+		goto error;
+	}
+
 	err = sbxfi_alloc_buffer(chip);
 	if (err < 0)
 		goto error;


More information about the Alsa-devel mailing list