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

ALSA: dice: share PCM buffer size for both direction

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

authored by

Takashi Sakamoto and committed by
Takashi Iwai
ecb40fd2 3299d2a0

+23 -7
+1 -1
sound/firewire/dice/dice-midi.c
··· 17 17 18 18 mutex_lock(&dice->mutex); 19 19 20 - err = snd_dice_stream_reserve_duplex(dice, 0, 0); 20 + err = snd_dice_stream_reserve_duplex(dice, 0, 0, 0); 21 21 if (err >= 0) { 22 22 ++dice->substreams_counter; 23 23 err = snd_dice_stream_start_duplex(dice);
+17 -3
sound/firewire/dice/dice-pcm.c
··· 204 204 if (!internal || 205 205 (dice->substreams_counter > 0 && d->events_per_period > 0)) { 206 206 unsigned int frames_per_period = d->events_per_period; 207 + unsigned int frames_per_buffer = d->events_per_buffer; 207 208 unsigned int rate; 208 209 209 210 err = snd_dice_transaction_get_rate(dice, &rate); ··· 218 217 219 218 if (frames_per_period > 0) { 220 219 // For double_pcm_frame quirk. 221 - if (rate > 96000) 220 + if (rate > 96000) { 222 221 frames_per_period *= 2; 222 + frames_per_buffer *= 2; 223 + } 223 224 224 225 err = snd_pcm_hw_constraint_minmax(substream->runtime, 225 226 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 226 227 frames_per_period, frames_per_period); 228 + if (err < 0) { 229 + mutex_unlock(&dice->mutex); 230 + goto err_locked; 231 + } 232 + 233 + err = snd_pcm_hw_constraint_minmax(substream->runtime, 234 + SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 235 + frames_per_buffer, frames_per_buffer); 227 236 if (err < 0) { 228 237 mutex_unlock(&dice->mutex); 229 238 goto err_locked; ··· 274 263 if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) { 275 264 unsigned int rate = params_rate(hw_params); 276 265 unsigned int events_per_period = params_period_size(hw_params); 266 + unsigned int events_per_buffer = params_buffer_size(hw_params); 277 267 278 268 mutex_lock(&dice->mutex); 279 269 // For double_pcm_frame quirk. 280 - if (rate > 96000) 270 + if (rate > 96000) { 281 271 events_per_period /= 2; 272 + events_per_buffer /= 2; 273 + } 282 274 err = snd_dice_stream_reserve_duplex(dice, rate, 283 - events_per_period); 275 + events_per_period, events_per_buffer); 284 276 if (err >= 0) 285 277 ++dice->substreams_counter; 286 278 mutex_unlock(&dice->mutex);
+3 -2
sound/firewire/dice/dice-stream.c
··· 279 279 } 280 280 281 281 int snd_dice_stream_reserve_duplex(struct snd_dice *dice, unsigned int rate, 282 - unsigned int events_per_period) 282 + unsigned int events_per_period, 283 + unsigned int events_per_buffer) 283 284 { 284 285 unsigned int curr_rate; 285 286 int err; ··· 328 327 goto error; 329 328 330 329 err = amdtp_domain_set_events_per_period(&dice->domain, 331 - events_per_period, 0); 330 + events_per_period, events_per_buffer); 332 331 if (err < 0) 333 332 goto error; 334 333 }
+2 -1
sound/firewire/dice/dice.h
··· 211 211 int snd_dice_stream_init_duplex(struct snd_dice *dice); 212 212 void snd_dice_stream_destroy_duplex(struct snd_dice *dice); 213 213 int snd_dice_stream_reserve_duplex(struct snd_dice *dice, unsigned int rate, 214 - unsigned int events_per_period); 214 + unsigned int events_per_period, 215 + unsigned int events_per_buffer); 215 216 void snd_dice_stream_update_duplex(struct snd_dice *dice); 216 217 int snd_dice_stream_detect_current_formats(struct snd_dice *dice); 217 218