mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 02:19:51 +00:00
ALSA: fireworks: use the same size of period for PCM substream in AMDTP streams
In current implementation, when opening a PCM substream, it's needed to check whether the opposite PCM substream runs. This is to assign effectual constraints (e.g. sampling rate) to opened PCM substream. The number of PCM substreams and MIDI substreams on AMDTP streams in domain is recorded in own structure. Usage of this count is an alternative of the above check. This is better because the count is incremented in pcm.hw_params earlier than pcm.trigger. This idea has one issue because it's incremented for MIDI substreams as well. In current implementation, for a case that any MIDI substream run and a PCM substream is going to start, PCM application to start the PCM substream can decide hardware parameters by restart packet streaming. Just checking the substream count can brings regression. Now AMDTP domain structure has a member for the size of PCM period in PCM substream which starts AMDTP streams in domain. When the value has zero and the substream count is greater than 1, it means that any MIDI substream starts AMDTP streams in domain. Usage of the value can resolve the above issue. This commit replaces the check with the substream count and the value for the size of PCM period. Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Link: https://lore.kernel.org/r/20191007110532.30270-12-o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
a80b29a41d
commit
56faf928db
1 changed files with 28 additions and 11 deletions
|
@ -173,13 +173,13 @@ pcm_init_hw_params(struct snd_efw *efw,
|
|||
static int pcm_open(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_efw *efw = substream->private_data;
|
||||
unsigned int sampling_rate;
|
||||
struct amdtp_domain *d = &efw->domain;
|
||||
enum snd_efw_clock_source clock_source;
|
||||
int err;
|
||||
|
||||
err = snd_efw_stream_lock_try(efw);
|
||||
if (err < 0)
|
||||
goto end;
|
||||
return err;
|
||||
|
||||
err = pcm_init_hw_params(efw, substream);
|
||||
if (err < 0)
|
||||
|
@ -189,23 +189,40 @@ static int pcm_open(struct snd_pcm_substream *substream)
|
|||
if (err < 0)
|
||||
goto err_locked;
|
||||
|
||||
/*
|
||||
* When source of clock is not internal or any PCM streams are running,
|
||||
* available sampling rate is limited at current sampling rate.
|
||||
*/
|
||||
mutex_lock(&efw->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_source != SND_EFW_CLOCK_SOURCE_INTERNAL) ||
|
||||
amdtp_stream_pcm_running(&efw->tx_stream) ||
|
||||
amdtp_stream_pcm_running(&efw->rx_stream)) {
|
||||
(efw->substreams_counter > 0 && d->events_per_period > 0)) {
|
||||
unsigned int frames_per_period = d->events_per_period;
|
||||
unsigned int sampling_rate;
|
||||
|
||||
err = snd_efw_command_get_sampling_rate(efw, &sampling_rate);
|
||||
if (err < 0)
|
||||
if (err < 0) {
|
||||
mutex_unlock(&efw->mutex);
|
||||
goto err_locked;
|
||||
}
|
||||
substream->runtime->hw.rate_min = sampling_rate;
|
||||
substream->runtime->hw.rate_max = sampling_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(&efw->mutex);
|
||||
goto err_locked;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&efw->mutex);
|
||||
|
||||
snd_pcm_set_sync(substream);
|
||||
end:
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
err_locked:
|
||||
snd_efw_stream_lock_release(efw);
|
||||
return err;
|
||||
|
|
Loading…
Reference in a new issue