summaryrefslogtreecommitdiff
path: root/sound/firewire
diff options
context:
space:
mode:
Diffstat (limited to 'sound/firewire')
-rw-r--r--sound/firewire/digi00x/digi00x-pcm.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/sound/firewire/digi00x/digi00x-pcm.c b/sound/firewire/digi00x/digi00x-pcm.c
index 9ced309d61fa..8dbfb3ff17f6 100644
--- a/sound/firewire/digi00x/digi00x-pcm.c
+++ b/sound/firewire/digi00x/digi00x-pcm.c
@@ -100,14 +100,14 @@ static int pcm_init_hw_params(struct snd_dg00x *dg00x,
static int pcm_open(struct snd_pcm_substream *substream)
{
struct snd_dg00x *dg00x = substream->private_data;
+ struct amdtp_domain *d = &dg00x->domain;
enum snd_dg00x_clock clock;
bool detect;
- unsigned int rate;
int err;
err = snd_dg00x_stream_lock_try(dg00x);
if (err < 0)
- goto end;
+ return err;
err = pcm_init_hw_params(dg00x, substream);
if (err < 0)
@@ -127,19 +127,40 @@ static int pcm_open(struct snd_pcm_substream *substream)
}
}
+ mutex_lock(&dg00x->mutex);
+
+ // When source of clock is not internal or any stream is reserved for
+ // transmission of PCM frames, the available sampling rate is limited
+ // at current one.
if ((clock != SND_DG00X_CLOCK_INTERNAL) ||
- amdtp_stream_pcm_running(&dg00x->rx_stream) ||
- amdtp_stream_pcm_running(&dg00x->tx_stream)) {
+ (dg00x->substreams_counter > 0 && d->events_per_period > 0)) {
+ unsigned int frames_per_period = d->events_per_period;
+ unsigned int rate;
+
err = snd_dg00x_stream_get_external_rate(dg00x, &rate);
- if (err < 0)
+ if (err < 0) {
+ mutex_unlock(&dg00x->mutex);
goto err_locked;
+ }
substream->runtime->hw.rate_min = rate;
substream->runtime->hw.rate_max = rate;
+
+ if (frames_per_period > 0) {
+ err = snd_pcm_hw_constraint_minmax(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ frames_per_period, frames_per_period);
+ if (err < 0) {
+ mutex_unlock(&dg00x->mutex);
+ goto err_locked;
+ }
+ }
}
+ mutex_unlock(&dg00x->mutex);
+
snd_pcm_set_sync(substream);
-end:
- return err;
+
+ return 0;
err_locked:
snd_dg00x_stream_lock_release(dg00x);
return err;