All of lore.kernel.org
 help / color / mirror / Atom feed
* Testers needed: memio-mmap patch (rme32,rme96,nm256)
@ 2004-06-18 14:51 Takashi Iwai
  2004-06-20 10:11 ` Martin Langer
  0 siblings, 1 reply; 7+ messages in thread
From: Takashi Iwai @ 2004-06-18 14:51 UTC (permalink / raw)
  To: alsa-devel

[-- Attachment #1: Type: text/plain, Size: 323 bytes --]

Hi,

the attached patch will fix/simplify the mmap of the devices with the
mmio buffers, such as rme32, rme96 and nm256.
If you have one of such devices, please test and report whether it
works with mmap mode (e.g. aplay -M option).

The patch is to CVS version, but likely can be applied to 1.0.5, too.


thanks,

Takashi

[-- Attachment #2: mmap-iomem.dif --]
[-- Type: application/octet-stream, Size: 28212 bytes --]

Index: alsa-kernel/core/pcm_native.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/core/pcm_native.c,v
retrieving revision 1.92
diff -u -r1.92 pcm_native.c
--- alsa-kernel/core/pcm_native.c	1 Jun 2004 07:57:54 -0000	1.92
+++ alsa-kernel/core/pcm_native.c	18 Jun 2004 14:00:19 -0000
@@ -3001,6 +3001,12 @@
 	.nopage =	snd_pcm_mmap_data_nopage,
 };
 
+static struct vm_operations_struct snd_pcm_vm_ops_data_mmio =
+{
+	.open =		snd_pcm_mmap_data_open,
+	.close =	snd_pcm_mmap_data_close,
+};
+
 int snd_pcm_mmap_data(snd_pcm_substream_t *substream, struct file *file,
 		      struct vm_area_struct *area)
 {
@@ -3036,6 +3042,14 @@
 	area->vm_ops = &snd_pcm_vm_ops_data;
 	area->vm_private_data = substream;
 	area->vm_flags |= VM_RESERVED;
+	if (runtime->hw.info & SNDRV_PCM_INFO_MMAP_IOMEM) {
+		area->vm_ops = &snd_pcm_vm_ops_data_mmio;
+		area->vm_flags |= VM_IO;
+		if (io_remap_page_range(area, area->vm_start,
+					runtime->dma_addr + offset,
+					size, area->vm_page_prot))
+			return -EAGAIN;
+	}
 	atomic_inc(&runtime->mmap_count);
 	return 0;
 }
Index: alsa-kernel/include/asound.h
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/include/asound.h,v
retrieving revision 1.40
diff -u -r1.40 asound.h
--- alsa-kernel/include/asound.h	22 May 2004 10:12:58 -0000	1.40
+++ alsa-kernel/include/asound.h	18 Jun 2004 14:00:19 -0000
@@ -274,6 +274,7 @@
 #define SNDRV_PCM_INFO_JOINT_DUPLEX	0x00200000	/* playback and capture stream are somewhat correlated */
 #define SNDRV_PCM_INFO_SYNC_START	0x00400000	/* pcm support some kind of sync go */
 #define SNDRV_PCM_INFO_NONATOMIC_OPS	0x00800000	/* non-atomic prepare callback */
+#define SNDRV_PCM_INFO_MMAP_IOMEM	0x01000000	/* mmap on IO memory */
 
 enum sndrv_pcm_state {
 	SNDRV_PCM_STATE_OPEN = 0,	/* stream is open */
Index: alsa-kernel/pci/rme32.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/rme32.c,v
retrieving revision 1.33
diff -u -r1.33 rme32.c
--- alsa-kernel/pci/rme32.c	13 Apr 2004 14:59:00 -0000	1.33
+++ alsa-kernel/pci/rme32.c	18 Jun 2004 14:00:20 -0000
@@ -213,10 +213,6 @@
 	size_t playback_periodsize;	/* in bytes, zero if not used */
 	size_t capture_periodsize;	/* in bytes, zero if not used */
 
-	snd_pcm_uframes_t playback_last_appl_ptr;
-	size_t playback_ptr;
-	size_t capture_ptr;
-
 	snd_card_t *card;
 	snd_pcm_t *spdif_pcm;
 	snd_pcm_t *adat_pcm;
@@ -329,6 +325,7 @@
 static snd_pcm_hardware_t snd_rme32_playback_spdif_info = {
 	.info =		(SNDRV_PCM_INFO_MMAP |
 			 SNDRV_PCM_INFO_MMAP_VALID |
+			 SNDRV_PCM_INFO_MMAP_IOMEM |
 			 SNDRV_PCM_INFO_INTERLEAVED | 
 			 SNDRV_PCM_INFO_PAUSE),
 	.formats =	(SNDRV_PCM_FMTBIT_S16_LE | 
@@ -354,6 +351,7 @@
 static snd_pcm_hardware_t snd_rme32_capture_spdif_info = {
 	.info =		(SNDRV_PCM_INFO_MMAP |
 			 SNDRV_PCM_INFO_MMAP_VALID |
+			 SNDRV_PCM_INFO_MMAP_IOMEM |
 			 SNDRV_PCM_INFO_INTERLEAVED | 
 			 SNDRV_PCM_INFO_PAUSE),
 	.formats =	(SNDRV_PCM_FMTBIT_S16_LE | 
@@ -380,6 +378,7 @@
 {
 	.info =		     (SNDRV_PCM_INFO_MMAP |
 			      SNDRV_PCM_INFO_MMAP_VALID |
+			      SNDRV_PCM_INFO_MMAP_IOMEM |
 			      SNDRV_PCM_INFO_INTERLEAVED |
 			      SNDRV_PCM_INFO_PAUSE),
 	.formats=            SNDRV_PCM_FMTBIT_S16_LE,
@@ -404,6 +403,7 @@
 {
 	.info =		     (SNDRV_PCM_INFO_MMAP |
 			      SNDRV_PCM_INFO_MMAP_VALID |
+			      SNDRV_PCM_INFO_MMAP_IOMEM |
 			      SNDRV_PCM_INFO_INTERLEAVED |
 			      SNDRV_PCM_INFO_PAUSE),
 	.formats =           SNDRV_PCM_FMTBIT_S16_LE,
@@ -678,10 +678,12 @@
 {
 	int err, rate, dummy;
 	rme32_t *rme32 = _snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
+
+	runtime->dma_area = (void *)(rme32->iobase + RME32_IO_DATA_BUFFER);
+	runtime->dma_addr = rme32->port + RME32_IO_DATA_BUFFER;
+	runtime->dma_bytes = RME32_BUFFER_SIZE;
 
-	if ((err = snd_pcm_lib_malloc_pages(substream,
-				      params_buffer_bytes(params))) < 0)
-		return err;
 	spin_lock_irq(&rme32->lock);
 	if ((rme32->rcreg & RME32_RCR_KMODE) &&
 	    (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
@@ -719,12 +721,6 @@
 	return 0;
 }
 
-static int snd_rme32_playback_hw_free(snd_pcm_substream_t * substream)
-{
-	snd_pcm_lib_free_pages(substream);
-	return 0;
-}
-
 static int
 snd_rme32_capture_hw_params(snd_pcm_substream_t * substream,
 			    snd_pcm_hw_params_t * params)
@@ -734,9 +730,10 @@
 	rme32_t *rme32 = _snd_pcm_substream_chip(substream);
 	snd_pcm_runtime_t *runtime = substream->runtime;
 
-	if ((err = snd_pcm_lib_malloc_pages(substream,
-				      params_buffer_bytes(params))) < 0)
-		return err;
+	runtime->dma_area = (void *)(rme32->iobase + RME32_IO_DATA_BUFFER);
+	runtime->dma_addr = rme32->port + RME32_IO_DATA_BUFFER;
+	runtime->dma_bytes = RME32_BUFFER_SIZE;
+
 	spin_lock_irqsave(&rme32->lock, flags);
 	/* enable AutoSync for record-preparing */
 	rme32->wcreg |= RME32_WCR_AUTOSYNC;
@@ -780,18 +777,10 @@
 	return 0;
 }
 
-static int snd_rme32_capture_hw_free(snd_pcm_substream_t * substream)
-{
-	snd_pcm_lib_free_pages(substream);
-	return 0;
-}
-
 static void snd_rme32_playback_start(rme32_t * rme32, int from_pause)
 {
 	if (!from_pause) {
 		writel(0, rme32->iobase + RME32_IO_RESET_POS);
-		rme32->playback_last_appl_ptr = 0;
-		rme32->playback_ptr = 0;
 	}
 
 	rme32->wcreg |= RME32_WCR_START;
@@ -882,8 +871,6 @@
 	rme32->wcreg &= ~RME32_WCR_ADAT;
 	writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
 	rme32->playback_substream = substream;
-	rme32->playback_last_appl_ptr = 0;
-	rme32->playback_ptr = 0;
 	spin_unlock_irqrestore(&rme32->lock, flags);
 
 	runtime->hw = snd_rme32_playback_spdif_info;
@@ -927,7 +914,6 @@
                 return -EBUSY;
         }
 	rme32->capture_substream = substream;
-	rme32->capture_ptr = 0;
 	spin_unlock_irqrestore(&rme32->lock, flags);
 
 	runtime->hw = snd_rme32_capture_spdif_info;
@@ -972,8 +958,6 @@
 	rme32->wcreg |= RME32_WCR_ADAT;
 	writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
 	rme32->playback_substream = substream;
-	rme32->playback_last_appl_ptr = 0;
-	rme32->playback_ptr = 0;
 	spin_unlock_irqrestore(&rme32->lock, flags);
 	
 	runtime->hw = snd_rme32_playback_adat_info;
@@ -1017,7 +1001,6 @@
 		return -EBUSY;
         }
 	rme32->capture_substream = substream;
-	rme32->capture_ptr = 0;
 	spin_unlock_irqrestore(&rme32->lock, flags);
 
 	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
@@ -1178,36 +1161,6 @@
 snd_rme32_playback_pointer(snd_pcm_substream_t * substream)
 {
 	rme32_t *rme32 = _snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_pcm_sframes_t diff;
-	size_t bytes;
-
-
-	if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
-		diff = runtime->control->appl_ptr -
-		       rme32->playback_last_appl_ptr;
-		rme32->playback_last_appl_ptr = runtime->control->appl_ptr;
-		if (diff != 0 && diff < -(snd_pcm_sframes_t) (runtime->boundary >> 1)) {
-			diff += runtime->boundary;
-		}
-		bytes = diff << rme32->playback_frlog;
-		if (bytes > RME32_BUFFER_SIZE - rme32->playback_ptr) {
-			memcpy_toio((void *)(rme32->iobase + RME32_IO_DATA_BUFFER + rme32->playback_ptr),
-				    runtime->dma_area + rme32->playback_ptr,
-				    RME32_BUFFER_SIZE - rme32->playback_ptr);
-			bytes -= RME32_BUFFER_SIZE - rme32->playback_ptr;
-			if (bytes > RME32_BUFFER_SIZE) {
-				bytes = RME32_BUFFER_SIZE;
-			}
-			memcpy_toio((void *)(rme32->iobase + RME32_IO_DATA_BUFFER),
-				    runtime->dma_area, bytes);
-			rme32->playback_ptr = bytes;
-		} else if (bytes != 0) {
-			memcpy_toio((void *)(rme32->iobase + RME32_IO_DATA_BUFFER + rme32->playback_ptr),
-				    runtime->dma_area + rme32->playback_ptr, bytes);
-			rme32->playback_ptr += bytes;
-		}
-	}
 	return snd_rme32_playback_ptr(rme32);
 }
 
@@ -1215,31 +1168,7 @@
 snd_rme32_capture_pointer(snd_pcm_substream_t * substream)
 {
 	rme32_t *rme32 = _snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_pcm_uframes_t frameptr;
-	size_t ptr;
-
-	frameptr = snd_rme32_capture_ptr(rme32);
-	if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
-		ptr = frameptr << rme32->capture_frlog;
-		if (ptr > rme32->capture_ptr) {
-			memcpy_fromio(runtime->dma_area + rme32->capture_ptr,
-				      (void *)(rme32->iobase + RME32_IO_DATA_BUFFER +
-					       rme32->capture_ptr),
-				      ptr - rme32->capture_ptr);
-			rme32->capture_ptr += ptr - rme32->capture_ptr;
-		} else if (ptr < rme32->capture_ptr) {
-			memcpy_fromio(runtime->dma_area + rme32->capture_ptr,
-				      (void *)(rme32->iobase + RME32_IO_DATA_BUFFER +
-					       rme32->capture_ptr),
-				      RME32_BUFFER_SIZE - rme32->capture_ptr);
-			memcpy_fromio(runtime->dma_area,
-				      (void *)(rme32->iobase + RME32_IO_DATA_BUFFER),
-				      ptr);
-			rme32->capture_ptr = ptr;
-		}
-	}
-	return frameptr;
+	return snd_rme32_capture_ptr(rme32);
 }
 
 static snd_pcm_ops_t snd_rme32_playback_spdif_ops = {
@@ -1247,7 +1176,6 @@
 	.close =	snd_rme32_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
 	.hw_params =	snd_rme32_playback_hw_params,
-	.hw_free =	snd_rme32_playback_hw_free,
 	.prepare =	snd_rme32_playback_prepare,
 	.trigger =	snd_rme32_playback_trigger,
 	.pointer =	snd_rme32_playback_pointer,
@@ -1260,7 +1188,6 @@
 	.close =	snd_rme32_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
 	.hw_params =	snd_rme32_capture_hw_params,
-	.hw_free =	snd_rme32_capture_hw_free,
 	.prepare =	snd_rme32_capture_prepare,
 	.trigger =	snd_rme32_capture_trigger,
 	.pointer =	snd_rme32_capture_pointer,
@@ -1272,7 +1199,6 @@
 	.close =	snd_rme32_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
 	.hw_params =	snd_rme32_playback_hw_params,
-	.hw_free =	snd_rme32_playback_hw_free,
 	.prepare =	snd_rme32_playback_prepare,
 	.trigger =	snd_rme32_playback_trigger,
 	.pointer =	snd_rme32_playback_pointer,
@@ -1285,7 +1211,6 @@
 	.close =	snd_rme32_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
 	.hw_params =	snd_rme32_capture_hw_params,
-	.hw_free =	snd_rme32_capture_hw_free,
 	.prepare =	snd_rme32_capture_prepare,
 	.trigger =	snd_rme32_capture_trigger,
 	.pointer =	snd_rme32_capture_pointer,
@@ -1319,7 +1244,6 @@
 {
 	rme32_t *rme32 = (rme32_t *) pcm->private_data;
 	rme32->spdif_pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
 }
 
 static void
@@ -1327,7 +1251,6 @@
 {
 	rme32_t *rme32 = (rme32_t *) pcm->private_data;
 	rme32->adat_pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
 }
 
 static int __devinit snd_rme32_create(rme32_t * rme32)
@@ -1376,13 +1299,7 @@
 	snd_pcm_set_ops(rme32->spdif_pcm, SNDRV_PCM_STREAM_CAPTURE,
 			&snd_rme32_capture_spdif_ops);
 
-	rme32->spdif_pcm->info_flags = 0;
-
-	snd_pcm_lib_preallocate_pages_for_all(rme32->spdif_pcm,
-					      SNDRV_DMA_TYPE_CONTINUOUS,
-					      snd_dma_continuous_data(GFP_KERNEL),
-					      RME32_BUFFER_SIZE,
-					      RME32_BUFFER_SIZE);
+	rme32->spdif_pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
 
 	/* set up ALSA pcm device for ADAT */
 	if ((pci->device == PCI_DEVICE_ID_DIGI32) ||
@@ -1404,13 +1321,7 @@
 		snd_pcm_set_ops(rme32->adat_pcm, SNDRV_PCM_STREAM_CAPTURE, 
 				&snd_rme32_capture_adat_ops);
 		
-		rme32->adat_pcm->info_flags = 0;
-
-		snd_pcm_lib_preallocate_pages_for_all(rme32->adat_pcm, 
-						      SNDRV_DMA_TYPE_CONTINUOUS,
-						      snd_dma_continuous_data(GFP_KERNEL),
-						      RME32_BUFFER_SIZE, 
-						      RME32_BUFFER_SIZE);
+		rme32->adat_pcm->info_flags = SNDRV_PCM_INFO_HALF_DUPLEX;
 	}
 
 
Index: alsa-kernel/pci/rme96.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/rme96.c,v
retrieving revision 1.35
diff -u -r1.35 rme96.c
--- alsa-kernel/pci/rme96.c	13 Apr 2004 14:59:00 -0000	1.35
+++ alsa-kernel/pci/rme96.c	18 Jun 2004 14:00:20 -0000
@@ -250,10 +250,6 @@
         size_t playback_periodsize; /* in bytes, zero if not used */
 	size_t capture_periodsize; /* in bytes, zero if not used */
 
-        snd_pcm_uframes_t playback_last_appl_ptr;
-	size_t playback_ptr;
-	size_t capture_ptr;
-
 	snd_card_t         *card;
 	snd_pcm_t          *spdif_pcm;
 	snd_pcm_t          *adat_pcm; 
@@ -394,6 +390,7 @@
 {
 	.info =		     (SNDRV_PCM_INFO_MMAP |
 			      SNDRV_PCM_INFO_MMAP_VALID |
+			      SNDRV_PCM_INFO_MMAP_IOMEM |
 			      SNDRV_PCM_INFO_INTERLEAVED |
 			      SNDRV_PCM_INFO_PAUSE),
 	.formats =	     (SNDRV_PCM_FMTBIT_S16_LE |
@@ -423,6 +420,7 @@
 {
 	.info =		     (SNDRV_PCM_INFO_MMAP |
 			      SNDRV_PCM_INFO_MMAP_VALID |
+			      SNDRV_PCM_INFO_MMAP_IOMEM |
 			      SNDRV_PCM_INFO_INTERLEAVED |
 			      SNDRV_PCM_INFO_PAUSE),
 	.formats =	     (SNDRV_PCM_FMTBIT_S16_LE |
@@ -452,6 +450,7 @@
 {
 	.info =		     (SNDRV_PCM_INFO_MMAP |
 			      SNDRV_PCM_INFO_MMAP_VALID |
+			      SNDRV_PCM_INFO_MMAP_IOMEM |
 			      SNDRV_PCM_INFO_INTERLEAVED |
 			      SNDRV_PCM_INFO_PAUSE),
 	.formats =	     (SNDRV_PCM_FMTBIT_S16_LE |
@@ -477,6 +476,7 @@
 {
 	.info =		     (SNDRV_PCM_INFO_MMAP |
 			      SNDRV_PCM_INFO_MMAP_VALID |
+			      SNDRV_PCM_INFO_MMAP_IOMEM |
 			      SNDRV_PCM_INFO_INTERLEAVED |
 			      SNDRV_PCM_INFO_PAUSE),
 	.formats =	     (SNDRV_PCM_FMTBIT_S16_LE |
@@ -993,10 +993,13 @@
 {
 	unsigned long flags;        
 	rme96_t *rme96 = _snd_pcm_substream_chip(substream);
+	snd_pcm_runtime_t *runtime = substream->runtime;
 	int err, rate, dummy;
 
-	if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params))) < 0)
-		return err;
+	runtime->dma_area = (void *)(rme96->iobase + RME96_IO_PLAY_BUFFER);
+	runtime->dma_addr = rme96->port + RME96_IO_PLAY_BUFFER;
+	runtime->dma_bytes = RME96_BUFFER_SIZE;
+
 	spin_lock_irqsave(&rme96->lock, flags);
 	if (!(rme96->wcreg & RME96_WCR_MASTER) &&
             snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
@@ -1038,13 +1041,6 @@
 }
 
 static int
-snd_rme96_playback_hw_free(snd_pcm_substream_t *substream)
-{
-	snd_pcm_lib_free_pages(substream);
-	return 0;
-}
-
-static int
 snd_rme96_capture_hw_params(snd_pcm_substream_t *substream,
 			    snd_pcm_hw_params_t *params)
 {
@@ -1053,8 +1049,10 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	int err, isadat, rate;
 	
-	if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params))) < 0)
-		return err;
+	runtime->dma_area = (void *)(rme96->iobase + RME96_IO_REC_BUFFER);
+	runtime->dma_addr = rme96->port + RME96_IO_REC_BUFFER;
+	runtime->dma_bytes = RME96_BUFFER_SIZE;
+
 	spin_lock_irqsave(&rme96->lock, flags);
 	if ((err = snd_rme96_capture_setformat(rme96, params_format(params))) < 0) {
 		spin_unlock_irqrestore(&rme96->lock, flags);
@@ -1096,21 +1094,12 @@
 	return 0;
 }
 
-static int
-snd_rme96_capture_hw_free(snd_pcm_substream_t *substream)
-{
-	snd_pcm_lib_free_pages(substream);
-	return 0;
-}
-
 static void
 snd_rme96_playback_start(rme96_t *rme96,
 			 int from_pause)
 {
 	if (!from_pause) {
 		writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS);
-		rme96->playback_last_appl_ptr = 0;
-		rme96->playback_ptr = 0;
 	}
 
 	rme96->wcreg |= RME96_WCR_START;
@@ -1123,7 +1112,6 @@
 {
 	if (!from_pause) {
 		writel(0, rme96->iobase + RME96_IO_RESET_REC_POS);
-		rme96->capture_ptr = 0;
 	}
 
 	rme96->wcreg |= RME96_WCR_START_2;
@@ -1212,8 +1200,6 @@
 	rme96->wcreg &= ~RME96_WCR_ADAT;
 	writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
 	rme96->playback_substream = substream;
-	rme96->playback_last_appl_ptr = 0;
-	rme96->playback_ptr = 0;
 	spin_unlock_irqrestore(&rme96->lock, flags);
 
 	runtime->hw = snd_rme96_playback_spdif_info;
@@ -1264,7 +1250,6 @@
                 return -EBUSY;
         }
 	rme96->capture_substream = substream;
-	rme96->capture_ptr = 0;
 	spin_unlock_irqrestore(&rme96->lock, flags);
 	
 	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE);
@@ -1291,8 +1276,6 @@
 	rme96->wcreg |= RME96_WCR_ADAT;
 	writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
 	rme96->playback_substream = substream;
-	rme96->playback_last_appl_ptr = 0;
-	rme96->playback_ptr = 0;
 	spin_unlock_irqrestore(&rme96->lock, flags);
 	
 	runtime->hw = snd_rme96_playback_adat_info;
@@ -1341,7 +1324,6 @@
                 return -EBUSY;
         }
 	rme96->capture_substream = substream;
-	rme96->capture_ptr = 0;
 	spin_unlock_irqrestore(&rme96->lock, flags);
 
 	snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, RME96_BUFFER_SIZE, RME96_BUFFER_SIZE);
@@ -1509,42 +1491,6 @@
 snd_rme96_playback_pointer(snd_pcm_substream_t *substream)
 {
 	rme96_t *rme96 = _snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_pcm_sframes_t diff;
-	size_t bytes;
-	
-	if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
-		diff = runtime->control->appl_ptr -
-		    rme96->playback_last_appl_ptr;
- 	        rme96->playback_last_appl_ptr = runtime->control->appl_ptr;
-	        if (diff != 0 &&
-		    diff < -(snd_pcm_sframes_t)(runtime->boundary >> 1))
-		{
-		        diff += runtime->boundary;
-		}
-		bytes = diff << rme96->playback_frlog;
-		
-		if (bytes > RME96_BUFFER_SIZE - rme96->playback_ptr) {
-			memcpy_toio((void *)(rme96->iobase + RME96_IO_PLAY_BUFFER +
-					     rme96->playback_ptr),
-				    runtime->dma_area + rme96->playback_ptr,
-				    RME96_BUFFER_SIZE - rme96->playback_ptr);
-		        bytes -= RME96_BUFFER_SIZE - rme96->playback_ptr;
-			if (bytes > RME96_BUFFER_SIZE) {
-			        bytes = RME96_BUFFER_SIZE;
-			}
-			memcpy_toio((void *)(rme96->iobase + RME96_IO_PLAY_BUFFER),
-				    runtime->dma_area,
-				    bytes);
-			rme96->playback_ptr = bytes;
-		} else if (bytes != 0) {
-			memcpy_toio((void *)(rme96->iobase + RME96_IO_PLAY_BUFFER +
-					     rme96->playback_ptr),
-				    runtime->dma_area + rme96->playback_ptr,
-				    bytes);
-			rme96->playback_ptr += bytes;
-		}
-	}
 	return snd_rme96_playback_ptr(rme96);
 }
 
@@ -1552,31 +1498,7 @@
 snd_rme96_capture_pointer(snd_pcm_substream_t *substream)
 {
 	rme96_t *rme96 = _snd_pcm_substream_chip(substream);
-	snd_pcm_runtime_t *runtime = substream->runtime;
-	snd_pcm_uframes_t frameptr;
-	size_t ptr;
-
-	frameptr = snd_rme96_capture_ptr(rme96);
-	if (runtime->access == SNDRV_PCM_ACCESS_MMAP_INTERLEAVED) {
-		ptr = frameptr << rme96->capture_frlog;
-		if (ptr > rme96->capture_ptr) {
-			memcpy_fromio(runtime->dma_area + rme96->capture_ptr,
-				      (void *)(rme96->iobase + RME96_IO_REC_BUFFER +
-					       rme96->capture_ptr),
-				      ptr - rme96->capture_ptr);
-			rme96->capture_ptr += ptr - rme96->capture_ptr;
-		} else if (ptr < rme96->capture_ptr) {
-			memcpy_fromio(runtime->dma_area + rme96->capture_ptr,
-				      (void *)(rme96->iobase + RME96_IO_REC_BUFFER +
-					       rme96->capture_ptr),
-				      RME96_BUFFER_SIZE - rme96->capture_ptr);
-			memcpy_fromio(runtime->dma_area,
-				      (void *)(rme96->iobase + RME96_IO_REC_BUFFER),
-				      ptr);
-			rme96->capture_ptr = ptr;
-		}
-	}
-	return frameptr;
+	return snd_rme96_capture_ptr(rme96);
 }
 
 static snd_pcm_ops_t snd_rme96_playback_spdif_ops = {
@@ -1584,7 +1506,6 @@
 	.close =	snd_rme96_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
 	.hw_params =	snd_rme96_playback_hw_params,
-	.hw_free =	snd_rme96_playback_hw_free,
 	.prepare =	snd_rme96_playback_prepare,
 	.trigger =	snd_rme96_playback_trigger,
 	.pointer =	snd_rme96_playback_pointer,
@@ -1597,7 +1518,6 @@
 	.close =	snd_rme96_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
 	.hw_params =	snd_rme96_capture_hw_params,
-	.hw_free =	snd_rme96_capture_hw_free,
 	.prepare =	snd_rme96_capture_prepare,
 	.trigger =	snd_rme96_capture_trigger,
 	.pointer =	snd_rme96_capture_pointer,
@@ -1609,7 +1529,6 @@
 	.close =	snd_rme96_playback_close,
 	.ioctl =	snd_pcm_lib_ioctl,
 	.hw_params =	snd_rme96_playback_hw_params,
-	.hw_free =	snd_rme96_playback_hw_free,
 	.prepare =	snd_rme96_playback_prepare,
 	.trigger =	snd_rme96_playback_trigger,
 	.pointer =	snd_rme96_playback_pointer,
@@ -1622,7 +1541,6 @@
 	.close =	snd_rme96_capture_close,
 	.ioctl =	snd_pcm_lib_ioctl,
 	.hw_params =	snd_rme96_capture_hw_params,
-	.hw_free =	snd_rme96_capture_hw_free,
 	.prepare =	snd_rme96_capture_prepare,
 	.trigger =	snd_rme96_capture_trigger,
 	.pointer =	snd_rme96_capture_pointer,
@@ -1661,7 +1579,6 @@
 {
 	rme96_t *rme96 = (rme96_t *) pcm->private_data;
 	rme96->spdif_pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
 }
 
 static void
@@ -1669,7 +1586,6 @@
 {
 	rme96_t *rme96 = (rme96_t *) pcm->private_data;
 	rme96->adat_pcm = NULL;
-	snd_pcm_lib_preallocate_free_for_all(pcm);
 }
 
 static int __devinit
@@ -1719,12 +1635,6 @@
 
 	rme96->spdif_pcm->info_flags = 0;
 
-	snd_pcm_lib_preallocate_pages_for_all(rme96->spdif_pcm,
-					      SNDRV_DMA_TYPE_CONTINUOUS,
-					      snd_dma_continuous_data(GFP_KERNEL),
-					      RME96_BUFFER_SIZE,
-					      RME96_BUFFER_SIZE);
-
 	/* set up ALSA pcm device for ADAT */
 	if (pci->device == PCI_DEVICE_ID_DIGI96) {
 		/* ADAT is not available on the base model */
@@ -1742,12 +1652,6 @@
 		snd_pcm_set_ops(rme96->adat_pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_rme96_capture_adat_ops);
 		
 		rme96->adat_pcm->info_flags = 0;
-
-		snd_pcm_lib_preallocate_pages_for_all(rme96->adat_pcm,
-						      SNDRV_DMA_TYPE_CONTINUOUS,
-						      snd_dma_continuous_data(GFP_KERNEL),
-						      RME96_BUFFER_SIZE,
-						      RME96_BUFFER_SIZE);
 	}
 
 	rme96->playback_periodsize = 0;
Index: alsa-kernel/pci/nm256/nm256.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/nm256/nm256.c,v
retrieving revision 1.38
diff -u -r1.38 nm256.c
--- alsa-kernel/pci/nm256/nm256.c	4 May 2004 15:19:25 -0000	1.38
+++ alsa-kernel/pci/nm256/nm256.c	18 Jun 2004 14:00:20 -0000
@@ -656,9 +656,9 @@
 	return bytes_to_frames(substream->runtime, curp);
 }
 
+/* Remapped I/O space can be accessible as pointer on i386 */
+/* This might be changed in the future */
 #ifndef __i386__
-/* FIXME: I/O space is not accessible via pointers on all architectures */
-
 /*
  * silence / copy for playback
  */
@@ -753,10 +753,8 @@
  */
 static snd_pcm_hardware_t snd_nm256_playback =
 {
-	.info =
-#ifdef __i386__
-				SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID|
-#endif
+	.info =			SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID|
+				SNDRV_PCM_INFO_MMAP_IOMEM|
 				SNDRV_PCM_INFO_INTERLEAVED |
 				/*SNDRV_PCM_INFO_PAUSE |*/
 				SNDRV_PCM_INFO_RESUME,
@@ -775,10 +773,8 @@
 
 static snd_pcm_hardware_t snd_nm256_capture =
 {
-	.info =
-#ifdef __i386__
-				SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID|
-#endif
+	.info =			SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID|
+				SNDRV_PCM_INFO_MMAP_IOMEM|
 				SNDRV_PCM_INFO_INTERLEAVED |
 				/*SNDRV_PCM_INFO_PAUSE |*/
 				SNDRV_PCM_INFO_RESUME,
Index: alsa-driver/acore/pcm_native.patch
===================================================================
RCS file: /cvsroot/alsa/alsa-driver/acore/pcm_native.patch,v
retrieving revision 1.4
diff -u -r1.4 pcm_native.patch
--- alsa-driver/acore/pcm_native.patch	8 Jan 2004 11:01:20 -0000	1.4
+++ alsa-driver/acore/pcm_native.patch	18 Jun 2004 14:00:20 -0000
@@ -1,11 +1,11 @@
---- ../alsa-kernel/core/pcm_native.c	2004-01-05 12:34:33.000000000 +0100
-+++ pcm_native.c	2004-01-08 11:54:28.000000000 +0100
+--- ../alsa-kernel/core/pcm_native.c	2004-06-18 15:45:30.889084942 +0200
++++ pcm_native.c	2004-06-18 15:46:30.484608248 +0200
 @@ -1,3 +1,4 @@
 +#define __NO_VERSION__
  /*
   *  Digital Audio (PCM) abstract layer
   *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
-@@ -2655,6 +2656,9 @@
+@@ -2696,6 +2697,9 @@
  	snd_pcm_runtime_t *runtime;
  	snd_pcm_sframes_t result;
  
@@ -15,7 +15,7 @@
  	pcm_file = snd_magic_cast(snd_pcm_file_t, file->private_data, result = -ENXIO; goto end);
  	substream = pcm_file->substream;
  	snd_assert(substream != NULL, result = -ENXIO; goto end);
-@@ -2672,9 +2676,13 @@
+@@ -2713,9 +2717,13 @@
  	if (result > 0)
  		result = frames_to_bytes(runtime, result);
   end:
@@ -29,7 +29,7 @@
  static ssize_t snd_pcm_readv(struct file *file, const struct iovec *_vector,
  			     unsigned long count, loff_t * offset)
  
-@@ -2721,6 +2729,9 @@
+@@ -2762,6 +2770,9 @@
  	void **bufs;
  	snd_pcm_uframes_t frames;
  
@@ -39,7 +39,7 @@
  	pcm_file = snd_magic_cast(snd_pcm_file_t, file->private_data, result = -ENXIO; goto end);
  	substream = pcm_file->substream;
  	snd_assert(substream != NULL, result = -ENXIO; goto end);
-@@ -2745,8 +2756,12 @@
+@@ -2786,8 +2797,12 @@
  		result = frames_to_bytes(runtime, result);
  	kfree(bufs);
   end:
@@ -52,7 +52,7 @@
  
  unsigned int snd_pcm_playback_poll(struct file *file, poll_table * wait)
  {
-@@ -2828,7 +2843,24 @@
+@@ -2869,7 +2884,24 @@
  	return mask;
  }
  
@@ -77,7 +77,7 @@
  {
  	snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
  	snd_pcm_runtime_t *runtime;
-@@ -2840,9 +2872,15 @@
+@@ -2881,9 +2913,15 @@
  	page = virt_to_page(runtime->status);
  	if (!PageReserved(page))
  		get_page(page);
@@ -93,7 +93,7 @@
  }
  
  static struct vm_operations_struct snd_pcm_vm_ops_status =
-@@ -2863,12 +2901,24 @@
+@@ -2904,12 +2942,24 @@
  	if (size != PAGE_ALIGN(sizeof(snd_pcm_mmap_status_t)))
  		return -EINVAL;
  	area->vm_ops = &snd_pcm_vm_ops_status;
@@ -118,7 +118,7 @@
  {
  	snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
  	snd_pcm_runtime_t *runtime;
-@@ -2880,9 +2930,15 @@
+@@ -2921,9 +2971,15 @@
  	page = virt_to_page(runtime->control);
  	if (!PageReserved(page))
  		get_page(page);
@@ -134,7 +134,7 @@
  }
  
  static struct vm_operations_struct snd_pcm_vm_ops_control =
-@@ -2903,8 +2959,14 @@
+@@ -2944,8 +3000,14 @@
  	if (size != PAGE_ALIGN(sizeof(snd_pcm_mmap_control_t)))
  		return -EINVAL;
  	area->vm_ops = &snd_pcm_vm_ops_control;
@@ -149,7 +149,7 @@
  	return 0;
  }
  
-@@ -2920,7 +2982,13 @@
+@@ -2961,7 +3023,13 @@
  	atomic_dec(&substream->runtime->mmap_count);
  }
  
@@ -163,7 +163,7 @@
  {
  	snd_pcm_substream_t *substream = (snd_pcm_substream_t *)area->vm_private_data;
  	snd_pcm_runtime_t *runtime;
-@@ -2932,7 +3000,11 @@
+@@ -2973,7 +3041,11 @@
  	if (substream == NULL)
  		return NOPAGE_OOM;
  	runtime = substream->runtime;
@@ -175,7 +175,7 @@
  	offset += address - area->vm_start;
  	snd_assert((offset % PAGE_SIZE) == 0, return NOPAGE_OOM);
  	dma_bytes = PAGE_ALIGN(runtime->dma_bytes);
-@@ -2948,9 +3020,15 @@
+@@ -2989,9 +3061,15 @@
  	}
  	if (!PageReserved(page))
  		get_page(page);
@@ -191,7 +191,7 @@
  }
  
  static struct vm_operations_struct snd_pcm_vm_ops_data =
-@@ -2958,6 +3036,9 @@
+@@ -2999,6 +3077,9 @@
  	.open =		snd_pcm_mmap_data_open,
  	.close =	snd_pcm_mmap_data_close,
  	.nopage =	snd_pcm_mmap_data_nopage,
@@ -200,8 +200,8 @@
 +#endif
  };
  
- int snd_pcm_mmap_data(snd_pcm_substream_t *substream, struct file *file,
-@@ -2985,7 +3066,11 @@
+ static struct vm_operations_struct snd_pcm_vm_ops_data_mmio =
+@@ -3032,7 +3113,11 @@
  	    runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
  		return -EINVAL;
  	size = area->vm_end - area->vm_start;
@@ -213,7 +213,7 @@
  	dma_bytes = PAGE_ALIGN(runtime->dma_bytes);
  	if ((size_t)size > dma_bytes)
  		return -EINVAL;
-@@ -2993,8 +3078,14 @@
+@@ -3040,8 +3125,14 @@
  		return -EINVAL;
  
  	area->vm_ops = &snd_pcm_vm_ops_data;
@@ -225,10 +225,10 @@
 +#ifdef VM_RESERVED
  	area->vm_flags |= VM_RESERVED;
 +#endif
- 	atomic_inc(&runtime->mmap_count);
- 	return 0;
- }
-@@ -3009,7 +3100,11 @@
+ 	if (runtime->hw.info & SNDRV_PCM_INFO_MMAP_IOMEM) {
+ 		area->vm_ops = &snd_pcm_vm_ops_data_mmio;
+ 		area->vm_flags |= VM_IO;
+@@ -3064,7 +3155,11 @@
  	substream = pcm_file->substream;
  	snd_assert(substream != NULL, return -ENXIO);
  
@@ -240,7 +240,7 @@
  	switch (offset) {
  	case SNDRV_PCM_MMAP_OFFSET_STATUS:
  		return snd_pcm_mmap_status(substream, file, area);
-@@ -3117,9 +3212,13 @@
+@@ -3209,9 +3304,13 @@
   */
  
  static struct file_operations snd_pcm_f_ops_playback = {
@@ -254,7 +254,7 @@
  	.open =		snd_pcm_open,
  	.release =	snd_pcm_release,
  	.poll =		snd_pcm_playback_poll,
-@@ -3129,9 +3228,13 @@
+@@ -3221,9 +3320,13 @@
  };
  
  static struct file_operations snd_pcm_f_ops_capture = {

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Testers needed: memio-mmap patch (rme32,rme96,nm256)
  2004-06-18 14:51 Testers needed: memio-mmap patch (rme32,rme96,nm256) Takashi Iwai
@ 2004-06-20 10:11 ` Martin Langer
  2004-07-01 13:44   ` Takashi Iwai
  0 siblings, 1 reply; 7+ messages in thread
From: Martin Langer @ 2004-06-20 10:11 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, pilo.c

On Fri, Jun 18, 2004 at 04:51:33PM +0200, Takashi Iwai wrote:
> Hi,
> 
> the attached patch will fix/simplify the mmap of the devices with the
> mmio buffers, such as rme32, rme96 and nm256.
> If you have one of such devices, please test and report whether it
> works with mmap mode (e.g. aplay -M option).

aplay -M and arecord -M is running fine on rme32 :)

> The patch is to CVS version, but likely can be applied to 1.0.5, too.

And if you are using kernel 2.4.x, you have to tune io_remap_page_range()
in the pcm_native.c patch:

    io_remap_page_range(area->vm_start, runtime->dma_addr + offset,
    			size, area->vm_page_prot)

Ok, let's try fullduplex now...

bye,
martin

-- 
                                     Living on earth may be expensive,
                   but it includes an annual free trip around the sun. 


-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Testers needed: memio-mmap patch (rme32,rme96,nm256)
  2004-06-20 10:11 ` Martin Langer
@ 2004-07-01 13:44   ` Takashi Iwai
  2004-07-01 20:13     ` Martin Langer
  0 siblings, 1 reply; 7+ messages in thread
From: Takashi Iwai @ 2004-07-01 13:44 UTC (permalink / raw)
  To: Martin Langer; +Cc: alsa-devel, pilo.c

At Sun, 20 Jun 2004 12:11:35 +0200,
Martin Langer wrote:
> 
> Ok, let's try fullduplex now...

JFYI: it's now on CVS tree.
fullduplex module option is disabled as default, though.


Takashi


-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 - 
digital self defense, top technical experts, no vendor pitches, 
unmatched networking opportunities. Visit www.blackhat.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Testers needed: memio-mmap patch (rme32,rme96,nm256)
  2004-07-01 13:44   ` Takashi Iwai
@ 2004-07-01 20:13     ` Martin Langer
  2004-07-02 12:50       ` Takashi Iwai
  0 siblings, 1 reply; 7+ messages in thread
From: Martin Langer @ 2004-07-01 20:13 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, pilo.c

On Thu, Jul 01, 2004 at 03:44:11PM +0200, Takashi Iwai wrote:
> At Sun, 20 Jun 2004 12:11:35 +0200,
> Martin Langer wrote:
> > 
> > Ok, let's try fullduplex now...
> 
> JFYI: it's now on CVS tree.
> fullduplex module option is disabled as default, though.

For enabling fullduplex you will need the following patch, too.

FYI: The situation is that I get only silence in fullduplex_mode after a
short time. But nevertheless in the beginning it is correct.


martin


--- alsa-kernel/pci/rme32.c	Thu Jul  1 19:52:09 2004
+++ ../alsa-rme32b/alsa-kernel/pci/rme32.c	Sun Jun 27 21:55:37 2004
@@ -1990,6 +2002,11 @@
 	rme32->card = card;
 	rme32->pci = pci;
 	snd_card_set_dev(card, &pci->dev);
+
+        if (fullduplex[dev]) {
+                rme32->fullduplex_mode = 1;
+        }
+
 	if ((err = snd_rme32_create(rme32)) < 0) {
 		snd_card_free(card);
 		return err;


-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 - 
digital self defense, top technical experts, no vendor pitches, 
unmatched networking opportunities. Visit www.blackhat.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Testers needed: memio-mmap patch (rme32,rme96,nm256)
  2004-07-01 20:13     ` Martin Langer
@ 2004-07-02 12:50       ` Takashi Iwai
  2004-07-05 18:47         ` Martin Langer
  0 siblings, 1 reply; 7+ messages in thread
From: Takashi Iwai @ 2004-07-02 12:50 UTC (permalink / raw)
  To: Martin Langer; +Cc: alsa-devel, pilo.c

[-- Attachment #1: Type: text/plain, Size: 601 bytes --]

At Thu, 1 Jul 2004 22:13:26 +0200,
Martin Langer wrote:
> 
> On Thu, Jul 01, 2004 at 03:44:11PM +0200, Takashi Iwai wrote:
> > At Sun, 20 Jun 2004 12:11:35 +0200,
> > Martin Langer wrote:
> > > 
> > > Ok, let's try fullduplex now...
> > 
> > JFYI: it's now on CVS tree.
> > fullduplex module option is disabled as default, though.
> 
> For enabling fullduplex you will need the following patch, too.

Oh yes, thanks ;)

 
> FYI: The situation is that I get only silence in fullduplex_mode after a
> short time. But nevertheless in the beginning it is correct.

How about the attached patch?


Takashi

[-- Attachment #2: Type: text/plain, Size: 4289 bytes --]

Index: alsa-kernel/include/pcm-indirect.h
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/include/pcm-indirect.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- alsa-kernel/include/pcm-indirect.h	1 Jul 2004 09:17:40 -0000	1.1
+++ alsa-kernel/include/pcm-indirect.h	2 Jul 2004 12:48:27 -0000	1.2
@@ -34,7 +34,7 @@
 	unsigned int sw_data;	/* Offset to next dst (or src) in sw ring buffer */
 	unsigned int sw_io;	/* Current software pointer in bytes */
 	int sw_ready;		/* Bytes ready to be transferred to/from hw */
-	size_t appl_ptr;	/* Last seen appl_ptr */
+	snd_pcm_uframes_t appl_ptr;	/* Last seen appl_ptr */
 } snd_pcm_indirect_t;
 
 typedef void (*snd_pcm_indirect_copy_t)(snd_pcm_substream_t *substream,
@@ -51,19 +51,19 @@
 	snd_pcm_runtime_t *runtime = substream->runtime;
 	snd_pcm_uframes_t appl_ptr = runtime->control->appl_ptr;
 	snd_pcm_sframes_t diff = appl_ptr - rec->appl_ptr;
-	snd_pcm_uframes_t qsize;
+	int qsize;
 
 	if (diff) {
 		if (diff < -(snd_pcm_sframes_t) (runtime->boundary / 2))
 			diff += runtime->boundary;
-		rec->sw_ready += frames_to_bytes(runtime, diff);
+		rec->sw_ready += (int)frames_to_bytes(runtime, diff);
 		rec->appl_ptr = appl_ptr;
 	}
 	qsize = rec->hw_queue_size ? rec->hw_queue_size : rec->hw_buffer_size;
 	while (rec->hw_ready < qsize && rec->sw_ready > 0) {
-		size_t hw_to_end = rec->hw_buffer_size - rec->hw_data;
-		size_t sw_to_end = rec->sw_buffer_size - rec->sw_data;
-		size_t bytes = rec->hw_buffer_size - rec->hw_ready;
+		unsigned int hw_to_end = rec->hw_buffer_size - rec->hw_data;
+		unsigned int sw_to_end = rec->sw_buffer_size - rec->sw_data;
+		unsigned int bytes = qsize - rec->hw_ready;
 		if (rec->sw_ready < (int)bytes)
 			bytes = rec->sw_ready;
 		if (hw_to_end < bytes)
@@ -74,7 +74,7 @@
 			break;
 		copy(substream, rec, bytes);
 		rec->hw_data += bytes;
-		if ((int)rec->hw_data == rec->hw_buffer_size)
+		if (rec->hw_data == rec->hw_buffer_size)
 			rec->hw_data = 0;
 		rec->sw_data += bytes;
 		if (rec->sw_data == rec->sw_buffer_size)
@@ -90,9 +90,9 @@
  */
 static inline snd_pcm_uframes_t
 snd_pcm_indirect_playback_pointer(snd_pcm_substream_t *substream,
-				  snd_pcm_indirect_t *rec, size_t ptr)
+				  snd_pcm_indirect_t *rec, unsigned int ptr)
 {
-	ssize_t bytes = ptr - rec->hw_io;
+	int bytes = ptr - rec->hw_io;
 	if (bytes < 0)
 		bytes += rec->hw_buffer_size;
 	rec->hw_io = ptr;
@@ -155,9 +155,9 @@
  */
 static inline snd_pcm_uframes_t
 snd_pcm_indirect_capture_pointer(snd_pcm_substream_t *substream,
-				 snd_pcm_indirect_t *rec, size_t ptr)
+				 snd_pcm_indirect_t *rec, unsigned int ptr)
 {
-	ssize_t bytes = ptr - rec->hw_io;
+	int bytes = ptr - rec->hw_io;
 	if (bytes < 0)
 		bytes += rec->hw_buffer_size;
 	rec->hw_io = ptr;
Index: alsa-kernel/pci/rme32.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/pci/rme32.c,v
retrieving revision 1.40
diff -u -r1.40 rme32.c
--- alsa-kernel/pci/rme32.c	1 Jul 2004 09:17:52 -0000	1.40
+++ alsa-kernel/pci/rme32.c	2 Jul 2004 11:14:58 -0000
@@ -1210,20 +1210,16 @@
 snd_rme32_playback_fd_pointer(snd_pcm_substream_t * substream)
 {
 	rme32_t *rme32 = snd_pcm_substream_chip(substream);
-	size_t ptr;
-
-	ptr = readl(rme32->iobase + RME32_IO_GET_POS) & RME32_RCR_AUDIO_ADDR_MASK;
-	return snd_pcm_indirect_playback_pointer(substream, &rme32->playback_pcm, ptr);
+	return snd_pcm_indirect_playback_pointer(substream, &rme32->playback_pcm,
+						 snd_rme32_pcm_byteptr(rme32));
 }
 
 static snd_pcm_uframes_t
 snd_rme32_capture_fd_pointer(snd_pcm_substream_t * substream)
 {
 	rme32_t *rme32 = snd_pcm_substream_chip(substream);
-	size_t ptr;
-
-	ptr = readl(rme32->iobase + RME32_IO_GET_POS) & RME32_RCR_AUDIO_ADDR_MASK;
-	return snd_pcm_indirect_capture_pointer(substream, &rme32->capture_pcm, ptr);
+	return snd_pcm_indirect_capture_pointer(substream, &rme32->capture_pcm,
+						snd_rme32_pcm_byteptr(rme32));
 }
 
 /* for halfduplex mode */
@@ -1990,6 +1986,8 @@
 	rme32->card = card;
 	rme32->pci = pci;
 	snd_card_set_dev(card, &pci->dev);
+        if (fullduplex[dev])
+		rme32->fullduplex_mode = 1;
 	if ((err = snd_rme32_create(rme32)) < 0) {
 		snd_card_free(card);
 		return err;


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Testers needed: memio-mmap patch (rme32,rme96,nm256)
  2004-07-02 12:50       ` Takashi Iwai
@ 2004-07-05 18:47         ` Martin Langer
  2004-07-13 19:54           ` Martin Langer
  0 siblings, 1 reply; 7+ messages in thread
From: Martin Langer @ 2004-07-05 18:47 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, pilo.c

On Fri, Jul 02, 2004 at 02:50:22PM +0200, Takashi Iwai wrote:
> At Thu, 1 Jul 2004 22:13:26 +0200,
> Martin Langer wrote:
>  
> > FYI: The situation is that I get only silence in fullduplex_mode after a
> > short time. But nevertheless in the beginning it is correct.
> 
> How about the attached patch?

Fine, there's no longer silence via the indirect way. But I'm still unhappy
because the resulting data fragments on playback and capturing aren't clean.
I mean there are often capturing fragments in the playback data; and OTOH 
you can get playback fragments during capturing. And the length of this
fragments and the winning data type (playback or capture) seems to be chaotic
for my ears.

Nevertheless thanks for the patch.

martin

-- 
                                     Living on earth may be expensive,
                   but it includes an annual free trip around the sun. 


-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 - 
digital self defense, top technical experts, no vendor pitches, 
unmatched networking opportunities. Visit www.blackhat.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Testers needed: memio-mmap patch (rme32,rme96,nm256)
  2004-07-05 18:47         ` Martin Langer
@ 2004-07-13 19:54           ` Martin Langer
  0 siblings, 0 replies; 7+ messages in thread
From: Martin Langer @ 2004-07-13 19:54 UTC (permalink / raw)
  To: alsa-devel; +Cc: Takashi Iwai, pilo.c

On Mon, Jul 05, 2004 at 08:47:31PM +0200, Martin Langer wrote:
> On Fri, Jul 02, 2004 at 02:50:22PM +0200, Takashi Iwai wrote:
> > At Thu, 1 Jul 2004 22:13:26 +0200,
> > Martin Langer wrote:
> >  
> > > FYI: The situation is that I get only silence in fullduplex_mode after a
> > > short time. But nevertheless in the beginning it is correct.
> > 
> > How about the attached patch?
> 
> Fine, there's no longer silence via the indirect way. But I'm still unhappy
> because the resulting data fragments on playback and capturing aren't clean.
> I mean there are often capturing fragments in the playback data; and OTOH 
> you can get playback fragments during capturing. And the length of this
> fragments and the winning data type (playback or capture) seems to be chaotic
> for my ears.

If I understand the fullduplex mode correct: then playback is sometimes the
winning process and another time it is capturing. I guess the code works
fine if playback wins the race. But if capturing is the winner, the playback
buffer isn't prefilled and the capture data will also be used in playback.

I don't see a rule that says: prefill the playback buffer before you run
capturing. But perhaps I'm totally blind at the moment.


martin



-- 
                                     Living on earth may be expensive,
                   but it includes an annual free trip around the sun. 


-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 - 
digital self defense, top technical experts, no vendor pitches, 
unmatched networking opportunities. Visit www.blackhat.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2004-07-13 19:54 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-06-18 14:51 Testers needed: memio-mmap patch (rme32,rme96,nm256) Takashi Iwai
2004-06-20 10:11 ` Martin Langer
2004-07-01 13:44   ` Takashi Iwai
2004-07-01 20:13     ` Martin Langer
2004-07-02 12:50       ` Takashi Iwai
2004-07-05 18:47         ` Martin Langer
2004-07-13 19:54           ` Martin Langer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.