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

Modified Files:
        rme32.c 
Log Message:
Martin Langer <[EMAIL PROTECTED]>
- AutoSync/Internal Clock changes. Adapted from the latest rme96 patch by
  Anders. This also solves another problem: Capturing from Digital Input
  must be reduced to one rate, else "rate conversion" of arecord can fail.
- remove one of two lines with #include <sound/info.h>
- fix: RME32_RCR_KMODE belongs to Read Control Register, not Write CR
- muting of output disabled, if card is in "digital forward" mode


Index: rme32.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/rme32.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- rme32.c     9 Jan 2003 10:48:19 -0000       1.19
+++ rme32.c     12 Jan 2003 09:48:19 -0000      1.20
@@ -70,7 +70,6 @@
 #include <sound/asoundef.h>
 #define SNDRV_GET_ID
 #include <sound/initval.h>
-#include <sound/info.h>
 
 #include <asm/io.h>
 
@@ -272,6 +271,19 @@
                & RME32_RCR_AUDIO_ADDR_MASK) >> rme32->capture_frlog;
 }
 
+static int snd_rme32_ratecode(int rate)
+{
+       switch (rate) {
+       case 32000: return SNDRV_PCM_RATE_32000;
+       case 44100: return SNDRV_PCM_RATE_44100;
+       case 48000: return SNDRV_PCM_RATE_48000;
+       case 64000: return SNDRV_PCM_RATE_64000;
+       case 88200: return SNDRV_PCM_RATE_88200;
+       case 96000: return SNDRV_PCM_RATE_96000;
+       }
+       return 0;
+}
+
 static int snd_rme32_playback_silence(snd_pcm_substream_t * substream, int channel,   
 /* not used (interleaved data) */
                                      snd_pcm_uframes_t pos,
                                      snd_pcm_uframes_t count)
@@ -663,14 +675,21 @@
 snd_rme32_playback_hw_params(snd_pcm_substream_t * substream,
                             snd_pcm_hw_params_t * params)
 {
+       int err, rate, dummy;
        rme32_t *rme32 = _snd_pcm_substream_chip(substream);
-       int err;
 
        if ((err = snd_pcm_lib_malloc_pages(substream,
                                      params_buffer_bytes(params))) < 0)
                return err;
        spin_lock_irq(&rme32->lock);
-       if ((err = snd_rme32_playback_setrate(rme32, params_rate(params))) < 0) {
+       if ((rme32->rcreg & RME32_RCR_KMODE) &&
+           (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
+               /* AutoSync */
+               if (params_rate(params) != rate) {
+                       spin_unlock_irq(&rme32->lock);
+                       return -EIO;
+               }
+       } else if ((err = snd_rme32_playback_setrate(rme32, params_rate(params))) < 0) 
+{
                spin_unlock_irq(&rme32->lock);
                return err;
        }
@@ -710,8 +729,9 @@
                            snd_pcm_hw_params_t * params)
 {
        unsigned long flags;
+       int err, isadat, rate;
        rme32_t *rme32 = _snd_pcm_substream_chip(substream);
-       int err, isadat;
+       snd_pcm_runtime_t *runtime = substream->runtime;
 
        if ((err = snd_pcm_lib_malloc_pages(substream,
                                      params_buffer_bytes(params))) < 0)
@@ -729,9 +749,16 @@
                spin_unlock_irqrestore(&rme32->lock, flags);
                return err;
        }
-       if (params_rate(params) != snd_rme32_capture_getrate(rme32, &isadat)) {
-               spin_unlock_irqrestore(&rme32->lock, flags);
-               return -EBUSY;
+       if ((rate = snd_rme32_capture_getrate(rme32, &isadat)) > 0) {
+                if (params_rate(params) != rate) {
+                        spin_unlock_irqrestore(&rme32->lock, flags);
+                        return -EIO;                    
+                }
+                if ((isadat && runtime->hw.channels_min == 2) ||
+                    (!isadat && runtime->hw.channels_min == 8)) {
+                        spin_unlock_irqrestore(&rme32->lock, flags);
+                        return -EIO;
+                }
        }
        /* AutoSync off for recording */
        rme32->wcreg &= ~RME32_WCR_AUTOSYNC;
@@ -791,7 +818,8 @@
                writel(0, rme32->iobase + RME32_IO_CONFIRM_ACTION_IRQ);
        }
        rme32->wcreg &= ~RME32_WCR_START;
-       rme32->wcreg |= RME32_WCR_MUTE;
+       if (rme32->wcreg & RME32_WCR_SEL)
+               rme32->wcreg |= RME32_WCR_MUTE;
        writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
 }
 
@@ -838,12 +866,17 @@
 static int snd_rme32_playback_spdif_open(snd_pcm_substream_t * substream)
 {
        unsigned long flags;
+       int rate, dummy;
        rme32_t *rme32 = _snd_pcm_substream_chip(substream);
        snd_pcm_runtime_t *runtime = substream->runtime;
 
        snd_pcm_set_sync(substream);
 
        spin_lock_irqsave(&rme32->lock, flags);
+       if (rme32->playback_substream != NULL) {
+               spin_unlock_irqrestore(&rme32->lock, flags);
+               return -EBUSY;
+       }
        rme32->wcreg &= ~RME32_WCR_ADAT;
        writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
        rme32->playback_substream = substream;
@@ -856,7 +889,13 @@
                runtime->hw.rates |= SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 | 
SNDRV_PCM_RATE_96000;
                runtime->hw.rate_max = 96000;
        }
-
+       if ((rme32->rcreg & RME32_RCR_KMODE) &&
+           (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
+               /* AutoSync */
+               runtime->hw.rates = snd_rme32_ratecode(rate);
+               runtime->hw.rate_min = rate;
+               runtime->hw.rate_max = rate;
+       }       
        snd_pcm_hw_constraint_minmax(runtime,
                                     SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
                                     RME32_BUFFER_SIZE, RME32_BUFFER_SIZE);
@@ -874,28 +913,31 @@
 static int snd_rme32_capture_spdif_open(snd_pcm_substream_t * substream)
 {
        unsigned long flags;
-       int isadat;
+       int isadat, rate;
        rme32_t *rme32 = _snd_pcm_substream_chip(substream);
        snd_pcm_runtime_t *runtime = substream->runtime;
 
-       rme32->rcreg = readl(rme32->iobase + RME32_IO_CONTROL_REGISTER);
-       if (snd_rme32_capture_getrate(rme32, &isadat) < 0) {
-               /* no input */
-               return -EIO;
-       }
-       if (isadat) {
-               /* ADAT input */
-               return -EBUSY;
-       }
        snd_pcm_set_sync(substream);
 
-       spin_lock_irqsave(&rme32->lock, flags);
+       runtime->hw = snd_rme32_capture_spdif_info;
+        if ((rate = snd_rme32_capture_getrate(rme32, &isadat)) > 0) {
+                if (isadat) {
+                        return -EIO;
+                }
+                runtime->hw.rates = snd_rme32_ratecode(rate);
+                runtime->hw.rate_min = rate;
+                runtime->hw.rate_max = rate;
+        }
 
+       spin_lock_irqsave(&rme32->lock, flags);
+        if (rme32->capture_substream != NULL) {
+               spin_unlock_irqrestore(&rme32->lock, flags);
+                return -EBUSY;
+        }
        rme32->capture_substream = substream;
        rme32->capture_ptr = 0;
        spin_unlock_irqrestore(&rme32->lock, flags);
 
-       runtime->hw = snd_rme32_capture_spdif_info;
        if (RME32_PRO_WITH_8414(rme32)) {
                runtime->hw.rates |= SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000;
                runtime->hw.rate_max = 96000;
@@ -915,12 +957,17 @@
 snd_rme32_playback_adat_open(snd_pcm_substream_t *substream)
 {
        unsigned long flags;
+       int rate, dummy;
        rme32_t *rme32 = _snd_pcm_substream_chip(substream);
        snd_pcm_runtime_t *runtime = substream->runtime;
        
        snd_pcm_set_sync(substream);
 
        spin_lock_irqsave(&rme32->lock, flags); 
+        if (rme32->playback_substream != NULL) {
+               spin_unlock_irqrestore(&rme32->lock, flags);
+                return -EBUSY;
+        }
        rme32->wcreg |= RME32_WCR_ADAT;
        writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
        rme32->playback_substream = substream;
@@ -929,6 +976,13 @@
        spin_unlock_irqrestore(&rme32->lock, flags);
        
        runtime->hw = snd_rme32_playback_adat_info;
+       if ((rme32->rcreg & RME32_RCR_KMODE) &&
+           (rate = snd_rme32_capture_getrate(rme32, &dummy)) > 0) {
+                /* AutoSync */
+                runtime->hw.rates = snd_rme32_ratecode(rate);
+                runtime->hw.rate_min = rate;
+                runtime->hw.rate_max = rate;
+       }        
        snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
                                     RME32_BUFFER_SIZE, RME32_BUFFER_SIZE);
        snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
@@ -940,27 +994,31 @@
 snd_rme32_capture_adat_open(snd_pcm_substream_t *substream)
 {
        unsigned long flags;
-       int isadat;
+       int isadat, rate;
        rme32_t *rme32 = _snd_pcm_substream_chip(substream);
        snd_pcm_runtime_t *runtime = substream->runtime;
 
-       rme32->rcreg = readl(rme32->iobase + RME32_IO_CONTROL_REGISTER);
-       if (snd_rme32_capture_getrate(rme32, &isadat) < 0) {
-               /* no input */
-               return -EIO;
-       }
-       if (!isadat) {
-               /* S/PDIF input */
-               return -EBUSY;
-       }
-       snd_pcm_set_sync(substream);
+       runtime->hw = snd_rme32_capture_adat_info;
+       if ((rate = snd_rme32_capture_getrate(rme32, &isadat)) > 0) {
+               if (!isadat) {
+                       return -EIO;
+               }
+                runtime->hw.rates = snd_rme32_ratecode(rate);
+                runtime->hw.rate_min = rate;
+                runtime->hw.rate_max = rate;
+        }
 
+       snd_pcm_set_sync(substream);
+        
        spin_lock_irqsave(&rme32->lock, flags); 
+       if (rme32->capture_substream != NULL) {
+               spin_unlock_irqrestore(&rme32->lock, flags);
+               return -EBUSY;
+        }
        rme32->capture_substream = substream;
        rme32->capture_ptr = 0;
        spin_unlock_irqrestore(&rme32->lock, flags);
 
-       runtime->hw = snd_rme32_capture_adat_info;
        snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
                                     RME32_BUFFER_SIZE, RME32_BUFFER_SIZE);
        snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
@@ -1010,7 +1068,8 @@
                snd_rme32_playback_stop(rme32);
        }
        writel(0, rme32->iobase + RME32_IO_RESET_POS);
-       rme32->wcreg &= ~RME32_WCR_MUTE;
+       if (rme32->wcreg & RME32_WCR_SEL)
+               rme32->wcreg &= ~RME32_WCR_MUTE;
        writel(rme32->wcreg, rme32->iobase + RME32_IO_CONTROL_REGISTER);
        spin_unlock_irqrestore(&rme32->lock, flags);
        return 0;
@@ -1464,7 +1523,7 @@
                snd_iprintf(buffer, "  sample rate: %d Hz\n",
                            snd_rme32_playback_getrate(rme32));
        }
-       if (rme32->wcreg & RME32_RCR_KMODE) {
+       if (rme32->rcreg & RME32_RCR_KMODE) {
                snd_iprintf(buffer, "  sample clock source: AutoSync\n");
        } else {
                snd_iprintf(buffer, "  sample clock source: Internal\n");
@@ -1529,6 +1588,10 @@
        spin_lock_irqsave(&rme32->lock, flags);
        val = (rme32->wcreg & ~RME32_WCR_SEL) | val;
        change = val != rme32->wcreg;
+       if (ucontrol->value.integer.value[0])
+               val &= ~RME32_WCR_MUTE;
+       else
+               val |= RME32_WCR_MUTE;
        writel(rme32->wcreg =
               val, rme32->iobase + RME32_IO_CONTROL_REGISTER);
        spin_unlock_irqrestore(&rme32->lock, flags);



-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog

Reply via email to