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