Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: fireworks: share PCM buffer size for both direction

This commit allows ALSA fireworks driver to share PCM buffer size for
both capture and playback PCM substream. When AMDTP domain starts for
one of the PCM substream, buffer size of the PCM substream is stores
to AMDTP domain structure. Some AMDTP streams have already run with the
buffer size when another PCM substream starts, therefore the PCM
substream has a constraint to its buffer size.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Link: https://lore.kernel.org/r/20191017155424.885-4-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Takashi Sakamoto and committed by
Takashi Iwai
659c6af5 1fde7a44

+17 -5
+2 -1
sound/firewire/fireworks/fireworks.h
··· 208 208 209 209 int snd_efw_stream_init_duplex(struct snd_efw *efw); 210 210 int snd_efw_stream_reserve_duplex(struct snd_efw *efw, unsigned int rate, 211 - unsigned int frames_per_period); 211 + unsigned int frames_per_period, 212 + unsigned int frames_per_buffer); 212 213 int snd_efw_stream_start_duplex(struct snd_efw *efw); 213 214 void snd_efw_stream_stop_duplex(struct snd_efw *efw); 214 215 void snd_efw_stream_update_duplex(struct snd_efw *efw);
+1 -1
sound/firewire/fireworks/fireworks_midi.c
··· 17 17 goto end; 18 18 19 19 mutex_lock(&efw->mutex); 20 - err = snd_efw_stream_reserve_duplex(efw, 0, 0); 20 + err = snd_efw_stream_reserve_duplex(efw, 0, 0, 0); 21 21 if (err >= 0) { 22 22 ++efw->substreams_counter; 23 23 err = snd_efw_stream_start_duplex(efw);
+11 -1
sound/firewire/fireworks/fireworks_pcm.c
··· 197 197 if ((clock_source != SND_EFW_CLOCK_SOURCE_INTERNAL) || 198 198 (efw->substreams_counter > 0 && d->events_per_period > 0)) { 199 199 unsigned int frames_per_period = d->events_per_period; 200 + unsigned int frames_per_buffer = d->events_per_buffer; 200 201 unsigned int sampling_rate; 201 202 202 203 err = snd_efw_command_get_sampling_rate(efw, &sampling_rate); ··· 212 211 err = snd_pcm_hw_constraint_minmax(substream->runtime, 213 212 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 214 213 frames_per_period, frames_per_period); 214 + if (err < 0) { 215 + mutex_unlock(&efw->mutex); 216 + goto err_locked; 217 + } 218 + 219 + err = snd_pcm_hw_constraint_minmax(substream->runtime, 220 + SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 221 + frames_per_buffer, frames_per_buffer); 215 222 if (err < 0) { 216 223 mutex_unlock(&efw->mutex); 217 224 goto err_locked; ··· 258 249 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) { 259 250 unsigned int rate = params_rate(hw_params); 260 251 unsigned int frames_per_period = params_period_size(hw_params); 252 + unsigned int frames_per_buffer = params_buffer_size(hw_params); 261 253 262 254 mutex_lock(&efw->mutex); 263 255 err = snd_efw_stream_reserve_duplex(efw, rate, 264 - frames_per_period); 256 + frames_per_period, frames_per_buffer); 265 257 if (err >= 0) 266 258 ++efw->substreams_counter; 267 259 mutex_unlock(&efw->mutex);
+3 -2
sound/firewire/fireworks/fireworks_stream.c
··· 182 182 } 183 183 184 184 int snd_efw_stream_reserve_duplex(struct snd_efw *efw, unsigned int rate, 185 - unsigned int frames_per_period) 185 + unsigned int frames_per_period, 186 + unsigned int frames_per_buffer) 186 187 { 187 188 unsigned int curr_rate; 188 189 int err; ··· 232 231 } 233 232 234 233 err = amdtp_domain_set_events_per_period(&efw->domain, 235 - frames_per_period, 0); 234 + frames_per_period, frames_per_buffer); 236 235 if (err < 0) { 237 236 cmp_connection_release(&efw->in_conn); 238 237 cmp_connection_release(&efw->out_conn);