Update of /cvsroot/alsa/alsa-kernel/pci
In directory sc8-pr-cvs1:/tmp/cvs-serv19620
Modified Files:
rme96.c
Log Message:
Anders Torger <[EMAIL PROTECTED]>
Now properly considers slave/master and input signal format in open and
hwparams; fixed parallel ADAT/SPDIF open bug
Index: rme96.c
===================================================================
RCS file: /cvsroot/alsa/alsa-kernel/pci/rme96.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- rme96.c 2 Dec 2002 16:58:04 -0000 1.19
+++ rme96.c 5 Jan 2003 16:52:34 -0000 1.20
@@ -330,6 +330,20 @@
}
static int
+snd_rme96_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_rme96_playback_silence(snd_pcm_substream_t *substream,
int channel, /* not used (interleaved data) */
snd_pcm_uframes_t pos,
@@ -671,8 +685,8 @@
if (!(rme96->wcreg & RME96_WCR_MASTER) &&
(rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
{
- /* slave clock */
- return rate;
+ /* slave clock */
+ return rate;
}
rate = ((rme96->wcreg >> RME96_WCR_BITPOS_FREQ_0) & 1) +
(((rme96->wcreg >> RME96_WCR_BITPOS_FREQ_1) & 1) << 1);
@@ -974,14 +988,22 @@
snd_rme96_playback_hw_params(snd_pcm_substream_t *substream,
snd_pcm_hw_params_t *params)
{
- unsigned long flags;
+ unsigned long flags;
rme96_t *rme96 = _snd_pcm_substream_chip(substream);
- int err;
+ int err, rate, dummy;
if ((err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params))) <
0)
return err;
spin_lock_irqsave(&rme96->lock, flags);
- if ((err = snd_rme96_playback_setrate(rme96, params_rate(params))) < 0) {
+ if (!(rme96->wcreg & RME96_WCR_MASTER) &&
+ (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
+ {
+ /* slave clock */
+ if (params_rate(params) != rate) {
+ spin_unlock_irqrestore(&rme96->lock, flags);
+ return -EIO;
+ }
+ } else if ((err = snd_rme96_playback_setrate(rme96, params_rate(params))) < 0)
+{
spin_unlock_irqrestore(&rme96->lock, flags);
return err;
}
@@ -1024,7 +1046,8 @@
{
unsigned long flags;
rme96_t *rme96 = _snd_pcm_substream_chip(substream);
- int err, isadat;
+ 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;
@@ -1040,9 +1063,6 @@
spin_unlock_irqrestore(&rme96->lock, flags);
return err;
}
- } else if (params_rate(params) != snd_rme96_capture_getrate(rme96, &isadat)) {
- spin_unlock_irqrestore(&rme96->lock, flags);
- return -EBUSY;
}
snd_rme96_setframelog(rme96, params_channels(params), 0);
if (rme96->playback_periodsize != 0) {
@@ -1052,7 +1072,18 @@
spin_unlock_irqrestore(&rme96->lock, flags);
return -EBUSY;
}
- }
+ } else if ((rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) {
+ if (params_rate(params) != rate) {
+ spin_unlock_irqrestore(&rme96->lock, flags);
+ return -EIO;
+ }
+ if ((isadat && runtime->hw.channels_min == 2) ||
+ (!isadat && runtime->hw.channels_min == 8))
+ {
+ spin_unlock_irqrestore(&rme96->lock, flags);
+ return -EIO;
+ }
+ }
rme96->capture_periodsize =
params_period_size(params) << rme96->capture_frlog;
snd_rme96_set_period_properties(rme96, rme96->capture_periodsize);
@@ -1138,7 +1169,7 @@
if (rme96->rcreg & RME96_RCR_IRQ) {
/* playback */
- snd_pcm_period_elapsed(rme96->playback_substream);
+ snd_pcm_period_elapsed(rme96->playback_substream);
writel(0, rme96->iobase + RME96_IO_CONFIRM_PLAY_IRQ);
}
if (rme96->rcreg & RME96_RCR_IRQ_2) {
@@ -1162,12 +1193,17 @@
snd_rme96_playback_spdif_open(snd_pcm_substream_t *substream)
{
unsigned long flags;
+ int rate, dummy;
rme96_t *rme96 = _snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
snd_pcm_set_sync(substream);
spin_lock_irqsave(&rme96->lock, flags);
+ if (rme96->playback_substream != NULL) {
+ spin_unlock_irqrestore(&rme96->lock, flags);
+ return -EBUSY;
+ }
rme96->wcreg &= ~RME96_WCR_ADAT;
writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
rme96->playback_substream = substream;
@@ -1175,7 +1211,15 @@
rme96->playback_ptr = 0;
spin_unlock_irqrestore(&rme96->lock, flags);
- runtime->hw = snd_rme96_playback_spdif_info;
+ runtime->hw = snd_rme96_playback_spdif_info;
+ if (!(rme96->wcreg & RME96_WCR_MASTER) &&
+ (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
+ {
+ /* slave clock */
+ runtime->hw.rates = snd_rme96_ratecode(rate);
+ runtime->hw.rate_min = rate;
+ runtime->hw.rate_max = rate;
+ }
snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
RME96_BUFFER_SIZE, RME96_BUFFER_SIZE);
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
&hw_constraints_period_bytes);
@@ -1190,28 +1234,31 @@
snd_rme96_capture_spdif_open(snd_pcm_substream_t *substream)
{
unsigned long flags;
- int isadat;
+ int isadat, rate;
rme96_t *rme96 = _snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
- rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
- if (snd_rme96_capture_getrate(rme96, &isadat) < 0) {
- /* no input */
- return -EIO;
- }
- if (isadat) {
- /* ADAT input */
- return -EBUSY;
- }
snd_pcm_set_sync(substream);
- spin_lock_irqsave(&rme96->lock, flags);
+ runtime->hw = snd_rme96_capture_spdif_info;
+ if ((rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) {
+ if (isadat) {
+ return -EIO;
+ }
+ runtime->hw.rates = snd_rme96_ratecode(rate);
+ runtime->hw.rate_min = rate;
+ runtime->hw.rate_max = rate;
+ }
+
+ spin_lock_irqsave(&rme96->lock, flags);
+ if (rme96->capture_substream != NULL) {
+ spin_unlock_irqrestore(&rme96->lock, flags);
+ return -EBUSY;
+ }
rme96->capture_substream = substream;
rme96->capture_ptr = 0;
spin_unlock_irqrestore(&rme96->lock, flags);
- runtime->hw = snd_rme96_capture_spdif_info;
-
snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
RME96_BUFFER_SIZE, RME96_BUFFER_SIZE);
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
&hw_constraints_period_bytes);
@@ -1222,12 +1269,17 @@
snd_rme96_playback_adat_open(snd_pcm_substream_t *substream)
{
unsigned long flags;
+ int rate, dummy;
rme96_t *rme96 = _snd_pcm_substream_chip(substream);
- snd_pcm_runtime_t *runtime = substream->runtime;
+ snd_pcm_runtime_t *runtime = substream->runtime;
snd_pcm_set_sync(substream);
spin_lock_irqsave(&rme96->lock, flags);
+ if (rme96->playback_substream != NULL) {
+ spin_unlock_irqrestore(&rme96->lock, flags);
+ return -EBUSY;
+ }
rme96->wcreg |= RME96_WCR_ADAT;
writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
rme96->playback_substream = substream;
@@ -1236,6 +1288,14 @@
spin_unlock_irqrestore(&rme96->lock, flags);
runtime->hw = snd_rme96_playback_adat_info;
+ if (!(rme96->wcreg & RME96_WCR_MASTER) &&
+ (rate = snd_rme96_capture_getrate(rme96, &dummy)) > 0)
+ {
+ /* slave clock */
+ runtime->hw.rates = snd_rme96_ratecode(rate);
+ runtime->hw.rate_min = rate;
+ runtime->hw.rate_max = rate;
+ }
snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
RME96_BUFFER_SIZE, RME96_BUFFER_SIZE);
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
&hw_constraints_period_bytes);
return 0;
@@ -1245,27 +1305,31 @@
snd_rme96_capture_adat_open(snd_pcm_substream_t *substream)
{
unsigned long flags;
- int isadat;
+ int isadat, rate;
rme96_t *rme96 = _snd_pcm_substream_chip(substream);
snd_pcm_runtime_t *runtime = substream->runtime;
- rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
- if (snd_rme96_capture_getrate(rme96, &isadat) < 0) {
- /* no input */
- return -EIO;
- }
- if (!isadat) {
- /* S/PDIF input */
- return -EBUSY;
- }
snd_pcm_set_sync(substream);
+ runtime->hw = snd_rme96_capture_adat_info;
+ if ((rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) {
+ if (!isadat) {
+ return -EIO;
+ }
+ runtime->hw.rates = snd_rme96_ratecode(rate);
+ runtime->hw.rate_min = rate;
+ runtime->hw.rate_max = rate;
+ }
+
spin_lock_irqsave(&rme96->lock, flags);
+ if (rme96->capture_substream != NULL) {
+ spin_unlock_irqrestore(&rme96->lock, flags);
+ return -EBUSY;
+ }
rme96->capture_substream = substream;
rme96->capture_ptr = 0;
spin_unlock_irqrestore(&rme96->lock, flags);
- runtime->hw = snd_rme96_capture_adat_info;
snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
RME96_BUFFER_SIZE, RME96_BUFFER_SIZE);
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
&hw_constraints_period_bytes);
return 0;
@@ -1279,6 +1343,9 @@
int spdif = 0;
spin_lock_irqsave(&rme96->lock, flags);
+ if (RME96_ISPLAYING(rme96)) {
+ snd_rme96_playback_stop(rme96);
+ }
rme96->playback_substream = NULL;
rme96->playback_periodsize = 0;
spdif = (rme96->wcreg & RME96_WCR_ADAT) == 0;
@@ -1298,6 +1365,9 @@
rme96_t *rme96 = _snd_pcm_substream_chip(substream);
spin_lock_irqsave(&rme96->lock, flags);
+ if (RME96_ISRECORDING(rme96)) {
+ snd_rme96_capture_stop(rme96);
+ }
rme96->capture_substream = NULL;
rme96->capture_periodsize = 0;
spin_unlock_irqrestore(&rme96->lock, flags);
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Alsa-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-cvslog