diff options
| -rw-r--r-- | sound/drivers/aloop.c | 51 |
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 | ||
| 309 | static 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 | |||
| 322 | static void params_change(struct snd_pcm_substream *substream) | 309 | static 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 | ||
| 339 | static int loopback_prepare(struct snd_pcm_substream *substream) | 322 | static int loopback_prepare(struct snd_pcm_substream *substream) |
| @@ -621,24 +604,29 @@ static unsigned int get_cable_index(struct snd_pcm_substream *substream) | |||
| 621 | static int rule_format(struct snd_pcm_hw_params *params, | 604 | static 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 | ||
| 634 | static int rule_rate(struct snd_pcm_hw_params *params, | 619 | static 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, | |||
| 647 | static int rule_channels(struct snd_pcm_hw_params *params, | 635 | static 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; |
