aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/drivers/aloop.c51
1 files changed, 21 insertions, 30 deletions
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
index 006521db487d..0333143a1fa7 100644
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -306,19 +306,6 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd)
306 return 0; 306 return 0;
307} 307}
308 308
309static void params_change_substream(struct loopback_pcm *dpcm,
310 struct snd_pcm_runtime *runtime)
311{
312 struct snd_pcm_runtime *dst_runtime;
313
314 if (dpcm == NULL || dpcm->substream == NULL)
315 return;
316 dst_runtime = dpcm->substream->runtime;
317 if (dst_runtime == NULL)
318 return;
319 dst_runtime->hw = dpcm->cable->hw;
320}
321
322static void params_change(struct snd_pcm_substream *substream) 309static void params_change(struct snd_pcm_substream *substream)
323{ 310{
324 struct snd_pcm_runtime *runtime = substream->runtime; 311 struct snd_pcm_runtime *runtime = substream->runtime;
@@ -330,10 +317,6 @@ static void params_change(struct snd_pcm_substream *substream)
330 cable->hw.rate_max = runtime->rate; 317 cable->hw.rate_max = runtime->rate;
331 cable->hw.channels_min = runtime->channels; 318 cable->hw.channels_min = runtime->channels;
332 cable->hw.channels_max = runtime->channels; 319 cable->hw.channels_max = runtime->channels;
333 params_change_substream(cable->streams[SNDRV_PCM_STREAM_PLAYBACK],
334 runtime);
335 params_change_substream(cable->streams[SNDRV_PCM_STREAM_CAPTURE],
336 runtime);
337} 320}
338 321
339static int loopback_prepare(struct snd_pcm_substream *substream) 322static int loopback_prepare(struct snd_pcm_substream *substream)
@@ -621,24 +604,29 @@ static unsigned int get_cable_index(struct snd_pcm_substream *substream)
621static int rule_format(struct snd_pcm_hw_params *params, 604static int rule_format(struct snd_pcm_hw_params *params,
622 struct snd_pcm_hw_rule *rule) 605 struct snd_pcm_hw_rule *rule)
623{ 606{
624 607 struct loopback_pcm *dpcm = rule->private;
625 struct snd_pcm_hardware *hw = rule->private; 608 struct loopback_cable *cable = dpcm->cable;
626 struct snd_mask m; 609 struct snd_mask m;
627 610
628 snd_mask_none(&m); 611 snd_mask_none(&m);
629 m.bits[0] = (u_int32_t)hw->formats; 612 mutex_lock(&dpcm->loopback->cable_lock);
630 m.bits[1] = (u_int32_t)(hw->formats >> 32); 613 m.bits[0] = (u_int32_t)cable->hw.formats;
614 m.bits[1] = (u_int32_t)(cable->hw.formats >> 32);
615 mutex_unlock(&dpcm->loopback->cable_lock);
631 return snd_mask_refine(hw_param_mask(params, rule->var), &m); 616 return snd_mask_refine(hw_param_mask(params, rule->var), &m);
632} 617}
633 618
634static int rule_rate(struct snd_pcm_hw_params *params, 619static int rule_rate(struct snd_pcm_hw_params *params,
635 struct snd_pcm_hw_rule *rule) 620 struct snd_pcm_hw_rule *rule)
636{ 621{
637 struct snd_pcm_hardware *hw = rule->private; 622 struct loopback_pcm *dpcm = rule->private;
623 struct loopback_cable *cable = dpcm->cable;
638 struct snd_interval t; 624 struct snd_interval t;
639 625
640 t.min = hw->rate_min; 626 mutex_lock(&dpcm->loopback->cable_lock);
641 t.max = hw->rate_max; 627 t.min = cable->hw.rate_min;
628 t.max = cable->hw.rate_max;
629 mutex_unlock(&dpcm->loopback->cable_lock);
642 t.openmin = t.openmax = 0; 630 t.openmin = t.openmax = 0;
643 t.integer = 0; 631 t.integer = 0;
644 return snd_interval_refine(hw_param_interval(params, rule->var), &t); 632 return snd_interval_refine(hw_param_interval(params, rule->var), &t);
@@ -647,11 +635,14 @@ static int rule_rate(struct snd_pcm_hw_params *params,
647static int rule_channels(struct snd_pcm_hw_params *params, 635static int rule_channels(struct snd_pcm_hw_params *params,
648 struct snd_pcm_hw_rule *rule) 636 struct snd_pcm_hw_rule *rule)
649{ 637{
650 struct snd_pcm_hardware *hw = rule->private; 638 struct loopback_pcm *dpcm = rule->private;
639 struct loopback_cable *cable = dpcm->cable;
651 struct snd_interval t; 640 struct snd_interval t;
652 641
653 t.min = hw->channels_min; 642 mutex_lock(&dpcm->loopback->cable_lock);
654 t.max = hw->channels_max; 643 t.min = cable->hw.channels_min;
644 t.max = cable->hw.channels_max;
645 mutex_unlock(&dpcm->loopback->cable_lock);
655 t.openmin = t.openmax = 0; 646 t.openmin = t.openmax = 0;
656 t.integer = 0; 647 t.integer = 0;
657 return snd_interval_refine(hw_param_interval(params, rule->var), &t); 648 return snd_interval_refine(hw_param_interval(params, rule->var), &t);
@@ -716,19 +707,19 @@ static int loopback_open(struct snd_pcm_substream *substream)
716 /* are cached -> they do not reflect the actual state */ 707 /* are cached -> they do not reflect the actual state */
717 err = snd_pcm_hw_rule_add(runtime, 0, 708 err = snd_pcm_hw_rule_add(runtime, 0,
718 SNDRV_PCM_HW_PARAM_FORMAT, 709 SNDRV_PCM_HW_PARAM_FORMAT,
719 rule_format, &runtime->hw, 710 rule_format, dpcm,
720 SNDRV_PCM_HW_PARAM_FORMAT, -1); 711 SNDRV_PCM_HW_PARAM_FORMAT, -1);
721 if (err < 0) 712 if (err < 0)
722 goto unlock; 713 goto unlock;
723 err = snd_pcm_hw_rule_add(runtime, 0, 714 err = snd_pcm_hw_rule_add(runtime, 0,
724 SNDRV_PCM_HW_PARAM_RATE, 715 SNDRV_PCM_HW_PARAM_RATE,
725 rule_rate, &runtime->hw, 716 rule_rate, dpcm,
726 SNDRV_PCM_HW_PARAM_RATE, -1); 717 SNDRV_PCM_HW_PARAM_RATE, -1);
727 if (err < 0) 718 if (err < 0)
728 goto unlock; 719 goto unlock;
729 err = snd_pcm_hw_rule_add(runtime, 0, 720 err = snd_pcm_hw_rule_add(runtime, 0,
730 SNDRV_PCM_HW_PARAM_CHANNELS, 721 SNDRV_PCM_HW_PARAM_CHANNELS,
731 rule_channels, &runtime->hw, 722 rule_channels, dpcm,
732 SNDRV_PCM_HW_PARAM_CHANNELS, -1); 723 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
733 if (err < 0) 724 if (err < 0)
734 goto unlock; 725 goto unlock;