Update of /cvsroot/alsa/alsa-kernel/pci/trident
In directory sc8-pr-cvs1:/tmp/cvs-serv5849/pci/trident

Modified Files:
        trident_main.c trident_memory.c 
Log Message:
Fixed trident NX memory allocation for capture.
Improved capture workaround (IRQ ack).


Index: trident_main.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/trident/trident_main.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- trident_main.c      7 Mar 2003 15:12:38 -0000       1.34
+++ trident_main.c      9 Mar 2003 23:16:11 -0000       1.35
@@ -489,6 +489,7 @@
 #endif
 }
 
+#if 0
 /*---------------------------------------------------------------------------
    snd_trident_write_cso_reg
   
@@ -511,6 +512,30 @@
                outl((voice->Delta << 24) | (voice->CSO & 0x00ffffff), 
TRID_REG(trident, CH_NX_DELTA_CSO));
        }
 }
+#endif
+
+/*---------------------------------------------------------------------------
+   snd_trident_write_eso_reg
+  
+   Description: This routine will write the new ESO offset
+                register to hardware.
+  
+   Paramters:   trident - pointer to target device class for 4DWave.
+                voice - synthesizer voice structure
+                ESO - new ESO value
+  
+  ---------------------------------------------------------------------------*/
+
+static void snd_trident_write_eso_reg(trident_t * trident, snd_trident_voice_t * 
voice, unsigned int ESO)
+{
+       voice->ESO = ESO;
+       outb(voice->number, TRID_REG(trident, T4D_LFO_GC_CIR));
+       if (trident->device != TRIDENT_DEVICE_ID_NX) {
+               outw(voice->ESO, TRID_REG(trident, CH_DX_ESO_DELTA) + 2);
+       } else {
+               outl(((voice->Delta << 16) & 0xff000000) | (voice->ESO & 0x00ffffff), 
TRID_REG(trident, CH_NX_DELTA_ESO));
+       }
+}
 
 /*---------------------------------------------------------------------------
    snd_trident_write_vol_reg
@@ -983,6 +1008,8 @@
        snd_trident_voice_t *voice = (snd_trident_voice_t *) runtime->private_data;
        unsigned int val, ESO_bytes;
 
+       snd_assert(substream->dma_device.type == SNDRV_DMA_TYPE_PCI, return -EIO);
+
        spin_lock(&trident->reg_lock);
 
        // Initilize the channel and set channel Mode
@@ -991,13 +1018,11 @@
        // Set DMA channel operation mode register
        outb(0x54, TRID_REG(trident, LEGACY_DMAR11));
 
-       // Set channel buffer Address
-       /* FIXME: LEGACY_DMAR0 correctly set? */
+       // Set channel buffer Address, DMAR0 expects contiguous PCI memory area 
+       voice->LBA = runtime->dma_addr;
+       outl(voice->LBA, TRID_REG(trident, LEGACY_DMAR0));
        if (voice->memblk)
                voice->LBA = voice->memblk->offset;
-       else
-               voice->LBA = runtime->dma_addr;
-       outl(voice->LBA, TRID_REG(trident, LEGACY_DMAR0));
 
        // set ESO
        ESO_bytes = snd_pcm_lib_buffer_bytes(substream) - 1;
@@ -1006,7 +1031,7 @@
        ESO_bytes++;
 
        // Set channel sample rate, 4.12 format
-       val = ((unsigned int) 48000L << 12) / runtime->rate;
+       val = (((unsigned int) 48000L << 12) + (runtime->rate/2)) / runtime->rate;
        outw(val, TRID_REG(trident, T4D_SBDELTA_DELTA_R));
 
        // Set channel interrupt blk length
@@ -1033,15 +1058,13 @@
 
        voice->Delta = snd_trident_convert_rate(runtime->rate);
        voice->spurious_threshold = snd_trident_spurious_threshold(runtime->rate, 
runtime->period_size);
+       voice->isync = 1;
+       voice->isync_mark = runtime->period_size;
+       voice->isync_max = runtime->buffer_size;
 
        // Set voice parameters
        voice->CSO = 0;
-       /* the +2 is a correction for a h/w problem. if not
-          used, the ESO interrupt is received before the capture pointer
-          has actually reached the ESO point. this causes errors in
-          the mid-level code.
-       */
-       voice->ESO = (runtime->period_size * 2) + 2 - 1;
+       voice->ESO = voice->isync_ESO = (runtime->period_size * 2) + 8 - 1;
        voice->CTRL = snd_trident_control_mode(substream);
        voice->FMC = 3;
        voice->RVol = 0x7f;
@@ -1498,6 +1521,8 @@
                        } else {
                                what |= 1 << (evoice->number & 0x1f);
                                whati |= 1 << (evoice->number & 0x1f);
+                               if (go)
+                                       evoice->stimer = val;
                        }
                        if (go) {
                                voice->running = 1;
@@ -1611,8 +1636,6 @@
        if (result > 0)
                result = runtime->buffer_size - result;
 
-       // printk("capture result = 0x%x, cso = 0x%x\n", result, cso);
-
        return result;
 }
 
@@ -2173,10 +2196,14 @@
        strcpy(pcm->name, "Trident 4DWave");
        trident->pcm = pcm;
 
-       if (trident->tlb.entries)
-               snd_pcm_lib_preallocate_sg_pages_for_all(trident->pci, pcm, 64*1024, 
128*1024);
-       else
+       if (trident->tlb.entries) {
+               snd_pcm_substream_t *substream;
+               for (substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 
substream; substream = substream->next)
+                       snd_pcm_lib_preallocate_sg_pages(trident->pci, substream, 
64*1024, 128*1024);
+               snd_pcm_lib_preallocate_pci_pages(trident->pci, 
pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream, 64*1024, 128*1024);
+       } else {
                snd_pcm_lib_preallocate_pci_pages_for_all(trident->pci, pcm, 64*1024, 
128*1024);
+       }
 
        if (rpcm)
                *rpcm = pcm;
@@ -3676,7 +3703,7 @@
 static void snd_trident_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
        trident_t *trident = snd_magic_cast(trident_t, dev_id, return);
-       unsigned int audio_int, chn_int, stimer, channel, mask;
+       unsigned int audio_int, chn_int, stimer, channel, mask, tmp;
        int delta;
        snd_trident_voice_t *voice;
 
@@ -3715,16 +3742,31 @@
                                continue;
                        }
                        voice->stimer = stimer;
+                       if (voice->isync) {
+                               tmp = inw(TRID_REG(trident, T4D_SBBL_SBCL));
+                               if (trident->bDMAStart & 0x40)
+                                       tmp >>= 1;
+                               if (tmp > 0)
+                                       tmp = voice->isync_max - tmp;
+                               if (tmp < voice->isync_mark) {
+                                       if (tmp > 0x20)
+                                               tmp = voice->isync_ESO - 9;
+                                       else
+                                               tmp = voice->isync_ESO + 2;
+                                       /* update ESO for IRQ voice to preserve sync */
+                                       snd_trident_stop_voice(trident, voice->number);
+                                       snd_trident_write_eso_reg(trident, voice, tmp);
+                                       snd_trident_start_voice(trident, 
voice->number);
+                               }
+                       }
+#if 0
                        if (voice->extra) {
                                /* update CSO for extra voice to preserve sync */
                                snd_trident_stop_voice(trident, voice->extra->number);
                                snd_trident_write_cso_reg(trident, voice->extra, 0);
                                snd_trident_start_voice(trident, voice->extra->number);
-                       } else if (voice->spdif) {
-                               snd_trident_stop_voice(trident, voice->number);
-                               snd_trident_write_cso_reg(trident, voice, 0);
-                               snd_trident_start_voice(trident, voice->number);
                        }
+#endif
                        spin_unlock(&trident->reg_lock);
                        snd_pcm_period_elapsed(voice->substream);
                        spin_lock(&trident->reg_lock);

Index: trident_memory.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/trident/trident_memory.c,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- trident_memory.c    28 Feb 2003 14:29:27 -0000      1.10
+++ trident_memory.c    9 Mar 2003 23:16:12 -0000       1.11
@@ -180,23 +180,26 @@
 }
 
 /*
- * page allocation for DMA
+ * page allocation for DMA (Scatter-Gather version)
  */
-snd_util_memblk_t *
-snd_trident_alloc_pages(trident_t *trident, snd_pcm_substream_t *substream)
+static snd_util_memblk_t *
+snd_trident_alloc_sg_pages(trident_t *trident, snd_pcm_substream_t *substream)
 {
        snd_util_memhdr_t *hdr;
        snd_util_memblk_t *blk;
+       snd_pcm_runtime_t *runtime = substream->runtime;
        int idx, page;
-       struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream);
+       struct snd_sg_buf *sgbuf = runtime->dma_private;
 
-       snd_assert(trident != NULL, return NULL);
-       snd_assert(sgbuf->size > 0 && sgbuf->size < SNDRV_TRIDENT_MAX_PAGES * 
SNDRV_TRIDENT_PAGE_SIZE, return NULL);
+       snd_assert(substream->dma_device.type == SNDRV_DMA_TYPE_PCI_SG, return NULL);
+       snd_assert(runtime->dma_bytes > 0 && runtime->dma_bytes <= 
SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL);
        hdr = trident->tlb.memhdr;
        snd_assert(hdr != NULL, return NULL);
 
+       
+
        down(&hdr->block_mutex);
-       blk = search_empty(hdr, sgbuf->size);
+       blk = search_empty(hdr, runtime->dma_bytes);
        if (blk == NULL) {
                up(&hdr->block_mutex);
                return NULL;
@@ -222,6 +225,61 @@
        }
        up(&hdr->block_mutex);
        return blk;
+}
+
+/*
+ * page allocation for DMA (contiguous version)
+ */
+static snd_util_memblk_t *
+snd_trident_alloc_cont_pages(trident_t *trident, snd_pcm_substream_t *substream)
+{
+       snd_util_memhdr_t *hdr;
+       snd_util_memblk_t *blk;
+       int page;
+       snd_pcm_runtime_t *runtime = substream->runtime;
+       dma_addr_t addr;
+       unsigned long ptr;
+
+       snd_assert(substream->dma_device.type == SNDRV_DMA_TYPE_PCI, return NULL);
+       snd_assert(runtime->dma_bytes> 0 && runtime->dma_bytes <= 
SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL);
+       hdr = trident->tlb.memhdr;
+       snd_assert(hdr != NULL, return NULL);
+
+       down(&hdr->block_mutex);
+       blk = search_empty(hdr, runtime->dma_bytes);
+       if (blk == NULL) {
+               up(&hdr->block_mutex);
+               return NULL;
+       }
+                          
+       /* set TLB entries */
+       addr = runtime->dma_addr;
+       ptr = (unsigned long)runtime->dma_area;
+       for (page = firstpg(blk); page <= lastpg(blk); page++,
+            ptr += SNDRV_TRIDENT_PAGE_SIZE, addr += SNDRV_TRIDENT_PAGE_SIZE) {
+               if (! is_valid_page(addr)) {
+                       __snd_util_mem_free(hdr, blk);
+                       up(&hdr->block_mutex);
+                       return NULL;
+               }
+               set_tlb_bus(trident, page, ptr, addr);
+       }
+       up(&hdr->block_mutex);
+       return blk;
+}
+
+/*
+ * page allocation for DMA
+ */
+snd_util_memblk_t *
+snd_trident_alloc_pages(trident_t *trident, snd_pcm_substream_t *substream)
+{
+       snd_assert(trident != NULL, return NULL);
+       snd_assert(substream != NULL, return NULL);
+       if (substream->dma_device.type == SNDRV_DMA_TYPE_PCI_SG)
+               return snd_trident_alloc_sg_pages(trident, substream);
+       else
+               return snd_trident_alloc_cont_pages(trident, substream);
 }
 
 



-------------------------------------------------------
This SF.net email is sponsored by: Etnus, makers of TotalView, The debugger 
for complex code. Debugging C/C++ programs can leave you feeling lost and 
disoriented. TotalView can help you find your way. Available on major UNIX 
and Linux platforms. Try it free. www.etnus.com
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog

Reply via email to