diff options
author | Olof Johansson <olof@lixom.net> | 2019-12-05 13:16:58 -0800 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2019-12-05 13:18:54 -0800 |
commit | 942e6f8a8314e5550e254519dfba4ccd5170421d (patch) | |
tree | 75ec655b440fbc1c454247af38b5596dd8c78de9 /sound/firewire/fireworks | |
parent | 336bab731be76a90291697e51d2aed0ad67d7cb5 (diff) | |
parent | b08baef02b26cf7c2123e4a24a2fa1fb7a593ffb (diff) |
Merge mainline/master into arm/fixes
This brings in the mainline tree right after armsoc contents was merged
this release cycle, so that we can re-run savedefconfig, etc.
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'sound/firewire/fireworks')
-rw-r--r-- | sound/firewire/fireworks/fireworks.h | 4 | ||||
-rw-r--r-- | sound/firewire/fireworks/fireworks_midi.c | 2 | ||||
-rw-r--r-- | sound/firewire/fireworks/fireworks_pcm.c | 72 | ||||
-rw-r--r-- | sound/firewire/fireworks/fireworks_stream.c | 14 |
4 files changed, 67 insertions, 25 deletions
diff --git a/sound/firewire/fireworks/fireworks.h b/sound/firewire/fireworks/fireworks.h index 4cda297f8438..dda797209a27 100644 --- a/sound/firewire/fireworks/fireworks.h +++ b/sound/firewire/fireworks/fireworks.h @@ -207,7 +207,9 @@ int snd_efw_command_get_sampling_rate(struct snd_efw *efw, unsigned int *rate); int snd_efw_command_set_sampling_rate(struct snd_efw *efw, unsigned int rate); int snd_efw_stream_init_duplex(struct snd_efw *efw); -int snd_efw_stream_reserve_duplex(struct snd_efw *efw, unsigned int rate); +int snd_efw_stream_reserve_duplex(struct snd_efw *efw, unsigned int rate, + unsigned int frames_per_period, + unsigned int frames_per_buffer); int snd_efw_stream_start_duplex(struct snd_efw *efw); void snd_efw_stream_stop_duplex(struct snd_efw *efw); void snd_efw_stream_update_duplex(struct snd_efw *efw); diff --git a/sound/firewire/fireworks/fireworks_midi.c b/sound/firewire/fireworks/fireworks_midi.c index a9f4a9630d15..84621e356848 100644 --- a/sound/firewire/fireworks/fireworks_midi.c +++ b/sound/firewire/fireworks/fireworks_midi.c @@ -17,7 +17,7 @@ static int midi_open(struct snd_rawmidi_substream *substream) goto end; mutex_lock(&efw->mutex); - err = snd_efw_stream_reserve_duplex(efw, 0); + err = snd_efw_stream_reserve_duplex(efw, 0, 0, 0); if (err >= 0) { ++efw->substreams_counter; err = snd_efw_stream_start_duplex(efw); diff --git a/sound/firewire/fireworks/fireworks_pcm.c b/sound/firewire/fireworks/fireworks_pcm.c index a7025dccc754..e69896d748df 100644 --- a/sound/firewire/fireworks/fireworks_pcm.c +++ b/sound/firewire/fireworks/fireworks_pcm.c @@ -173,13 +173,13 @@ end: 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,49 @@ 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 frames_per_buffer = d->events_per_buffer; + 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; + } + + err = snd_pcm_hw_constraint_minmax(substream->runtime, + SNDRV_PCM_HW_PARAM_BUFFER_SIZE, + frames_per_buffer, frames_per_buffer); + 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; @@ -224,16 +250,18 @@ static int pcm_hw_params(struct snd_pcm_substream *substream, struct snd_efw *efw = substream->private_data; int err; - err = snd_pcm_lib_alloc_vmalloc_buffer(substream, - params_buffer_bytes(hw_params)); + err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); if (err < 0) return err; if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) { unsigned int rate = params_rate(hw_params); + unsigned int frames_per_period = params_period_size(hw_params); + unsigned int frames_per_buffer = params_buffer_size(hw_params); mutex_lock(&efw->mutex); - err = snd_efw_stream_reserve_duplex(efw, rate); + err = snd_efw_stream_reserve_duplex(efw, rate, + frames_per_period, frames_per_buffer); if (err >= 0) ++efw->substreams_counter; mutex_unlock(&efw->mutex); @@ -255,7 +283,7 @@ static int pcm_hw_free(struct snd_pcm_substream *substream) mutex_unlock(&efw->mutex); - return snd_pcm_lib_free_vmalloc_buffer(substream); + return snd_pcm_lib_free_pages(substream); } static int pcm_capture_prepare(struct snd_pcm_substream *substream) @@ -319,26 +347,28 @@ static int pcm_playback_trigger(struct snd_pcm_substream *substream, int cmd) static snd_pcm_uframes_t pcm_capture_pointer(struct snd_pcm_substream *sbstrm) { struct snd_efw *efw = sbstrm->private_data; - return amdtp_stream_pcm_pointer(&efw->tx_stream); + + return amdtp_domain_stream_pcm_pointer(&efw->domain, &efw->tx_stream); } static snd_pcm_uframes_t pcm_playback_pointer(struct snd_pcm_substream *sbstrm) { struct snd_efw *efw = sbstrm->private_data; - return amdtp_stream_pcm_pointer(&efw->rx_stream); + + return amdtp_domain_stream_pcm_pointer(&efw->domain, &efw->rx_stream); } static int pcm_capture_ack(struct snd_pcm_substream *substream) { struct snd_efw *efw = substream->private_data; - return amdtp_stream_pcm_ack(&efw->tx_stream); + return amdtp_domain_stream_pcm_ack(&efw->domain, &efw->tx_stream); } static int pcm_playback_ack(struct snd_pcm_substream *substream) { struct snd_efw *efw = substream->private_data; - return amdtp_stream_pcm_ack(&efw->rx_stream); + return amdtp_domain_stream_pcm_ack(&efw->domain, &efw->rx_stream); } int snd_efw_create_pcm_devices(struct snd_efw *efw) @@ -353,7 +383,6 @@ int snd_efw_create_pcm_devices(struct snd_efw *efw) .trigger = pcm_capture_trigger, .pointer = pcm_capture_pointer, .ack = pcm_capture_ack, - .page = snd_pcm_lib_get_vmalloc_page, }; static const struct snd_pcm_ops playback_ops = { .open = pcm_open, @@ -365,7 +394,6 @@ int snd_efw_create_pcm_devices(struct snd_efw *efw) .trigger = pcm_playback_trigger, .pointer = pcm_playback_pointer, .ack = pcm_playback_ack, - .page = snd_pcm_lib_get_vmalloc_page, }; struct snd_pcm *pcm; int err; @@ -378,6 +406,8 @@ int snd_efw_create_pcm_devices(struct snd_efw *efw) snprintf(pcm->name, sizeof(pcm->name), "%s PCM", efw->card->shortname); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &capture_ops); + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_VMALLOC, + NULL, 0, 0); end: return err; } diff --git a/sound/firewire/fireworks/fireworks_stream.c b/sound/firewire/fireworks/fireworks_stream.c index f2de304d2f26..2206af0fef42 100644 --- a/sound/firewire/fireworks/fireworks_stream.c +++ b/sound/firewire/fireworks/fireworks_stream.c @@ -181,7 +181,9 @@ static int keep_resources(struct snd_efw *efw, struct amdtp_stream *stream, return cmp_connection_reserve(conn, amdtp_stream_get_max_payload(stream)); } -int snd_efw_stream_reserve_duplex(struct snd_efw *efw, unsigned int rate) +int snd_efw_stream_reserve_duplex(struct snd_efw *efw, unsigned int rate, + unsigned int frames_per_period, + unsigned int frames_per_buffer) { unsigned int curr_rate; int err; @@ -228,6 +230,14 @@ int snd_efw_stream_reserve_duplex(struct snd_efw *efw, unsigned int rate) cmp_connection_release(&efw->in_conn); return err; } + + err = amdtp_domain_set_events_per_period(&efw->domain, + frames_per_period, frames_per_buffer); + if (err < 0) { + cmp_connection_release(&efw->in_conn); + cmp_connection_release(&efw->out_conn); + return err; + } } return 0; @@ -262,7 +272,7 @@ int snd_efw_stream_start_duplex(struct snd_efw *efw) if (err < 0) goto error; - err = amdtp_domain_start(&efw->domain); + err = amdtp_domain_start(&efw->domain, 0); if (err < 0) goto error; |