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