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

ALSA: oxfw: share PCM buffer size for both direction

This commit allows ALSA oxfw 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-5-o-takashi@sakamocchi.jp
Signed-off-by: Takashi Iwai <tiwai@suse.de>

authored by

Takashi Sakamoto and committed by
Takashi Iwai
3299d2a0 659c6af5

+22 -7
+2 -2
sound/firewire/oxfw/oxfw-midi.c
··· 18 18 19 19 mutex_lock(&oxfw->mutex); 20 20 21 - err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->tx_stream, 0, 0, 0); 21 + err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->tx_stream, 0, 0, 0, 0); 22 22 if (err >= 0) { 23 23 ++oxfw->substreams_count; 24 24 err = snd_oxfw_stream_start_duplex(oxfw); ··· 45 45 46 46 mutex_lock(&oxfw->mutex); 47 47 48 - err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->rx_stream, 0, 0, 0); 48 + err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->rx_stream, 0, 0, 0, 0); 49 49 if (err >= 0) { 50 50 ++oxfw->substreams_count; 51 51 err = snd_oxfw_stream_start_duplex(oxfw);
+15 -2
sound/firewire/oxfw/oxfw-pcm.c
··· 188 188 // at current one. 189 189 if (oxfw->substreams_count > 0 && d->events_per_period > 0) { 190 190 unsigned int frames_per_period = d->events_per_period; 191 + unsigned int frames_per_buffer = d->events_per_buffer; 191 192 192 193 err = limit_to_current_params(substream); 193 194 if (err < 0) { ··· 200 199 err = snd_pcm_hw_constraint_minmax(substream->runtime, 201 200 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 202 201 frames_per_period, frames_per_period); 202 + if (err < 0) { 203 + mutex_unlock(&oxfw->mutex); 204 + goto err_locked; 205 + } 206 + 207 + err = snd_pcm_hw_constraint_minmax(substream->runtime, 208 + SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 209 + frames_per_buffer, frames_per_buffer); 203 210 if (err < 0) { 204 211 mutex_unlock(&oxfw->mutex); 205 212 goto err_locked; ··· 248 239 unsigned int rate = params_rate(hw_params); 249 240 unsigned int channels = params_channels(hw_params); 250 241 unsigned int frames_per_period = params_period_size(hw_params); 242 + unsigned int frames_per_buffer = params_buffer_size(hw_params); 251 243 252 244 mutex_lock(&oxfw->mutex); 253 245 err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->tx_stream, 254 - rate, channels, frames_per_period); 246 + rate, channels, frames_per_period, 247 + frames_per_buffer); 255 248 if (err >= 0) 256 249 ++oxfw->substreams_count; 257 250 mutex_unlock(&oxfw->mutex); ··· 276 265 unsigned int rate = params_rate(hw_params); 277 266 unsigned int channels = params_channels(hw_params); 278 267 unsigned int frames_per_period = params_period_size(hw_params); 268 + unsigned int frames_per_buffer = params_buffer_size(hw_params); 279 269 280 270 mutex_lock(&oxfw->mutex); 281 271 err = snd_oxfw_stream_reserve_duplex(oxfw, &oxfw->rx_stream, 282 - rate, channels, frames_per_period); 272 + rate, channels, frames_per_period, 273 + frames_per_buffer); 283 274 if (err >= 0) 284 275 ++oxfw->substreams_count; 285 276 mutex_unlock(&oxfw->mutex);
+3 -2
sound/firewire/oxfw/oxfw-stream.c
··· 245 245 int snd_oxfw_stream_reserve_duplex(struct snd_oxfw *oxfw, 246 246 struct amdtp_stream *stream, 247 247 unsigned int rate, unsigned int pcm_channels, 248 - unsigned int frames_per_period) 248 + unsigned int frames_per_period, 249 + unsigned int frames_per_buffer) 249 250 { 250 251 struct snd_oxfw_stream_formation formation; 251 252 enum avc_general_plug_dir dir; ··· 309 308 } 310 309 311 310 err = amdtp_domain_set_events_per_period(&oxfw->domain, 312 - frames_per_period, 0); 311 + frames_per_period, frames_per_buffer); 313 312 if (err < 0) { 314 313 cmp_connection_release(&oxfw->in_conn); 315 314 if (oxfw->has_output)
+2 -1
sound/firewire/oxfw/oxfw.h
··· 104 104 int snd_oxfw_stream_reserve_duplex(struct snd_oxfw *oxfw, 105 105 struct amdtp_stream *stream, 106 106 unsigned int rate, unsigned int pcm_channels, 107 - unsigned int frames_per_period); 107 + unsigned int frames_per_period, 108 + unsigned int frames_per_buffer); 108 109 int snd_oxfw_stream_start_duplex(struct snd_oxfw *oxfw); 109 110 void snd_oxfw_stream_stop_duplex(struct snd_oxfw *oxfw); 110 111 void snd_oxfw_stream_destroy_duplex(struct snd_oxfw *oxfw);