Lines Matching +full:min +full:- +full:sample +full:- +full:rate +full:- +full:hz

1 // SPDX-License-Identifier: GPL-2.0-or-later
8 * More accurate positioning and full-duplex support:
9 * Copyright (c) Ahmet İnan <ainan at mathematik.uni-freiburg.de>
39 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
41 static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
42 static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
53 MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-8) for loopback driver.");
55 MODULE_PARM_DESC(pcm_notify, "Break capture when PCM format/rate/channels changes.");
70 * call in loopback->cable_lock
74 * call in cable->lock
78 * call in cable->lock
86 * call in loopback->cable_lock
90 * call in cable->lock
121 unsigned int rate; member
150 unsigned int pcm_salign; /* bytes per sample * channels */
151 unsigned int pcm_rate_shift; /* rate shift value */
164 /* size of per channel buffer in case of non-interleaved access */
172 if (dpcm->pcm_rate_shift == NO_PITCH) { in byte_pos()
173 x /= HZ; in byte_pos()
176 HZ * (unsigned long long)dpcm->pcm_rate_shift); in byte_pos()
178 return x - (x % dpcm->pcm_salign); in byte_pos()
183 if (dpcm->pcm_rate_shift == NO_PITCH) { /* no pitch */ in frac_pos()
184 return x * HZ; in frac_pos()
186 x = div_u64(dpcm->pcm_rate_shift * (unsigned long long)x * HZ, in frac_pos()
194 int device = dpcm->substream->pstr->pcm->device; in get_setup()
196 if (dpcm->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in get_setup()
198 return &dpcm->loopback->setup[dpcm->substream->number][device]; in get_setup()
203 return get_setup(dpcm)->notify; in get_notify()
208 return get_setup(dpcm)->rate_shift; in get_rate_shift()
211 /* call in cable->lock */
217 if (rate_shift != dpcm->pcm_rate_shift) { in loopback_jiffies_timer_start()
218 dpcm->pcm_rate_shift = rate_shift; in loopback_jiffies_timer_start()
219 dpcm->period_size_frac = frac_pos(dpcm, dpcm->pcm_period_size); in loopback_jiffies_timer_start()
221 if (dpcm->period_size_frac <= dpcm->irq_pos) { in loopback_jiffies_timer_start()
222 dpcm->irq_pos %= dpcm->period_size_frac; in loopback_jiffies_timer_start()
223 dpcm->period_update_pending = 1; in loopback_jiffies_timer_start()
225 tick = dpcm->period_size_frac - dpcm->irq_pos; in loopback_jiffies_timer_start()
226 tick = DIV_ROUND_UP(tick, dpcm->pcm_bps); in loopback_jiffies_timer_start()
227 mod_timer(&dpcm->timer, jiffies + tick); in loopback_jiffies_timer_start()
232 /* call in cable->lock */
235 struct loopback_cable *cable = dpcm->cable; in loopback_snd_timer_start()
241 err = snd_timer_start(cable->snd_timer.instance, 1); in loopback_snd_timer_start()
247 if (err == -EBUSY) in loopback_snd_timer_start()
250 pcm_err(dpcm->substream->pcm, in loopback_snd_timer_start()
252 cable->snd_timer.id.card, in loopback_snd_timer_start()
253 cable->snd_timer.id.device, in loopback_snd_timer_start()
254 cable->snd_timer.id.subdevice, in loopback_snd_timer_start()
261 /* call in cable->lock */
264 del_timer(&dpcm->timer); in loopback_jiffies_timer_stop()
265 dpcm->timer.expires = 0; in loopback_jiffies_timer_stop()
270 /* call in cable->lock */
273 struct loopback_cable *cable = dpcm->cable; in loopback_snd_timer_stop()
277 if (cable->running ^ cable->pause) in loopback_snd_timer_stop()
280 err = snd_timer_stop(cable->snd_timer.instance); in loopback_snd_timer_stop()
282 pcm_err(dpcm->substream->pcm, in loopback_snd_timer_stop()
284 cable->snd_timer.id.card, in loopback_snd_timer_stop()
285 cable->snd_timer.id.device, in loopback_snd_timer_stop()
286 cable->snd_timer.id.subdevice, in loopback_snd_timer_stop()
295 del_timer_sync(&dpcm->timer); in loopback_jiffies_timer_stop_sync()
300 /* call in loopback->cable_lock */
303 struct loopback_cable *cable = dpcm->cable; in loopback_snd_timer_close_cable()
306 if (!cable->snd_timer.instance) in loopback_snd_timer_close_cable()
311 * loopback->cable_lock is locked. Therefore no need to lock in loopback_snd_timer_close_cable()
312 * cable->lock; in loopback_snd_timer_close_cable()
314 snd_timer_close(cable->snd_timer.instance); in loopback_snd_timer_close_cable()
317 cancel_work_sync(&cable->snd_timer.event_work); in loopback_snd_timer_close_cable()
319 snd_timer_instance_free(cable->snd_timer.instance); in loopback_snd_timer_close_cable()
320 memset(&cable->snd_timer, 0, sizeof(cable->snd_timer)); in loopback_snd_timer_close_cable()
343 if (cable->valid != CABLE_VALID_BOTH) { in loopback_check_format()
348 runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]-> in loopback_check_format()
349 substream->runtime; in loopback_check_format()
350 cruntime = cable->streams[SNDRV_PCM_STREAM_CAPTURE]-> in loopback_check_format()
351 substream->runtime; in loopback_check_format()
352 check = runtime->format != cruntime->format || in loopback_check_format()
353 runtime->rate != cruntime->rate || in loopback_check_format()
354 runtime->channels != cruntime->channels || in loopback_check_format()
355 is_access_interleaved(runtime->access) != in loopback_check_format()
356 is_access_interleaved(cruntime->access); in loopback_check_format()
360 return -EIO; in loopback_check_format()
362 snd_pcm_stop(cable->streams[SNDRV_PCM_STREAM_CAPTURE]-> in loopback_check_format()
365 runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]-> in loopback_check_format()
366 substream->runtime; in loopback_check_format()
367 setup = get_setup(cable->streams[SNDRV_PCM_STREAM_PLAYBACK]); in loopback_check_format()
368 card = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->loopback->card; in loopback_check_format()
369 if (setup->format != runtime->format) { in loopback_check_format()
371 &setup->format_id); in loopback_check_format()
372 setup->format = runtime->format; in loopback_check_format()
374 if (setup->rate != runtime->rate) { in loopback_check_format()
376 &setup->rate_id); in loopback_check_format()
377 setup->rate = runtime->rate; in loopback_check_format()
379 if (setup->channels != runtime->channels) { in loopback_check_format()
381 &setup->channels_id); in loopback_check_format()
382 setup->channels = runtime->channels; in loopback_check_format()
384 if (is_access_interleaved(setup->access) != in loopback_check_format()
385 is_access_interleaved(runtime->access)) { in loopback_check_format()
387 &setup->access_id); in loopback_check_format()
388 setup->access = runtime->access; in loopback_check_format()
396 snd_ctl_notify(dpcm->loopback->card, in loopback_active_notify()
398 &get_setup(dpcm)->active_id); in loopback_active_notify()
403 struct snd_pcm_runtime *runtime = substream->runtime; in loopback_trigger()
404 struct loopback_pcm *dpcm = runtime->private_data; in loopback_trigger()
405 struct loopback_cable *cable = dpcm->cable; in loopback_trigger()
406 int err = 0, stream = 1 << substream->stream; in loopback_trigger()
410 err = loopback_check_format(cable, substream->stream); in loopback_trigger()
413 dpcm->last_jiffies = jiffies; in loopback_trigger()
414 dpcm->pcm_rate_shift = 0; in loopback_trigger()
415 dpcm->last_drift = 0; in loopback_trigger()
416 spin_lock(&cable->lock); in loopback_trigger()
417 cable->running |= stream; in loopback_trigger()
418 cable->pause &= ~stream; in loopback_trigger()
419 err = cable->ops->start(dpcm); in loopback_trigger()
420 spin_unlock(&cable->lock); in loopback_trigger()
421 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in loopback_trigger()
425 spin_lock(&cable->lock); in loopback_trigger()
426 cable->running &= ~stream; in loopback_trigger()
427 cable->pause &= ~stream; in loopback_trigger()
428 err = cable->ops->stop(dpcm); in loopback_trigger()
429 spin_unlock(&cable->lock); in loopback_trigger()
430 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in loopback_trigger()
435 spin_lock(&cable->lock); in loopback_trigger()
436 cable->pause |= stream; in loopback_trigger()
437 err = cable->ops->stop(dpcm); in loopback_trigger()
438 spin_unlock(&cable->lock); in loopback_trigger()
439 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in loopback_trigger()
444 spin_lock(&cable->lock); in loopback_trigger()
445 dpcm->last_jiffies = jiffies; in loopback_trigger()
446 cable->pause &= ~stream; in loopback_trigger()
447 err = cable->ops->start(dpcm); in loopback_trigger()
448 spin_unlock(&cable->lock); in loopback_trigger()
449 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in loopback_trigger()
453 return -EINVAL; in loopback_trigger()
460 struct snd_pcm_runtime *runtime = substream->runtime; in params_change()
461 struct loopback_pcm *dpcm = runtime->private_data; in params_change()
462 struct loopback_cable *cable = dpcm->cable; in params_change()
464 cable->hw.formats = pcm_format_to_bits(runtime->format); in params_change()
465 cable->hw.rate_min = runtime->rate; in params_change()
466 cable->hw.rate_max = runtime->rate; in params_change()
467 cable->hw.channels_min = runtime->channels; in params_change()
468 cable->hw.channels_max = runtime->channels; in params_change()
470 if (cable->snd_timer.instance) { in params_change()
471 cable->hw.period_bytes_min = in params_change()
472 frames_to_bytes(runtime, runtime->period_size); in params_change()
473 cable->hw.period_bytes_max = cable->hw.period_bytes_min; in params_change()
480 struct snd_pcm_runtime *runtime = substream->runtime; in loopback_prepare()
481 struct loopback_pcm *dpcm = runtime->private_data; in loopback_prepare()
482 struct loopback_cable *cable = dpcm->cable; in loopback_prepare()
485 if (cable->ops->stop_sync) { in loopback_prepare()
486 err = cable->ops->stop_sync(dpcm); in loopback_prepare()
491 salign = (snd_pcm_format_physical_width(runtime->format) * in loopback_prepare()
492 runtime->channels) / 8; in loopback_prepare()
493 bps = salign * runtime->rate; in loopback_prepare()
495 return -EINVAL; in loopback_prepare()
497 dpcm->buf_pos = 0; in loopback_prepare()
498 dpcm->pcm_buffer_size = frames_to_bytes(runtime, runtime->buffer_size); in loopback_prepare()
499 dpcm->channel_buf_n = dpcm->pcm_buffer_size / runtime->channels; in loopback_prepare()
500 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { in loopback_prepare()
502 dpcm->silent_size = dpcm->pcm_buffer_size; in loopback_prepare()
503 snd_pcm_format_set_silence(runtime->format, runtime->dma_area, in loopback_prepare()
504 runtime->buffer_size * runtime->channels); in loopback_prepare()
507 dpcm->irq_pos = 0; in loopback_prepare()
508 dpcm->period_update_pending = 0; in loopback_prepare()
509 dpcm->pcm_bps = bps; in loopback_prepare()
510 dpcm->pcm_salign = salign; in loopback_prepare()
511 dpcm->pcm_period_size = frames_to_bytes(runtime, runtime->period_size); in loopback_prepare()
513 mutex_lock(&dpcm->loopback->cable_lock); in loopback_prepare()
514 if (!(cable->valid & ~(1 << substream->stream)) || in loopback_prepare()
515 (get_setup(dpcm)->notify && in loopback_prepare()
516 substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) in loopback_prepare()
518 cable->valid |= 1 << substream->stream; in loopback_prepare()
519 mutex_unlock(&dpcm->loopback->cable_lock); in loopback_prepare()
526 struct snd_pcm_runtime *runtime = dpcm->substream->runtime; in clear_capture_buf()
527 char *dst = runtime->dma_area; in clear_capture_buf()
528 unsigned int dst_off = dpcm->buf_pos; in clear_capture_buf()
530 if (dpcm->silent_size >= dpcm->pcm_buffer_size) in clear_capture_buf()
532 if (dpcm->silent_size + bytes > dpcm->pcm_buffer_size) in clear_capture_buf()
533 bytes = dpcm->pcm_buffer_size - dpcm->silent_size; in clear_capture_buf()
537 if (dst_off + size > dpcm->pcm_buffer_size) in clear_capture_buf()
538 size = dpcm->pcm_buffer_size - dst_off; in clear_capture_buf()
539 snd_pcm_format_set_silence(runtime->format, dst + dst_off, in clear_capture_buf()
541 runtime->channels); in clear_capture_buf()
542 dpcm->silent_size += size; in clear_capture_buf()
543 bytes -= size; in clear_capture_buf()
553 unsigned int channels = capt->substream->runtime->channels; in copy_play_buf_part_n()
560 memcpy(capt->substream->runtime->dma_area + capt->channel_buf_n * i + dst_off_ch, in copy_play_buf_part_n()
561 play->substream->runtime->dma_area + play->channel_buf_n * i + src_off_ch, in copy_play_buf_part_n()
570 struct snd_pcm_runtime *runtime = play->substream->runtime; in copy_play_buf()
571 char *src = runtime->dma_area; in copy_play_buf()
572 char *dst = capt->substream->runtime->dma_area; in copy_play_buf()
573 unsigned int src_off = play->buf_pos; in copy_play_buf()
574 unsigned int dst_off = capt->buf_pos; in copy_play_buf()
579 if (runtime->state == SNDRV_PCM_STATE_DRAINING && in copy_play_buf()
580 snd_pcm_playback_hw_avail(runtime) < runtime->buffer_size) { in copy_play_buf()
582 appl_ptr = appl_ptr1 = runtime->control->appl_ptr; in copy_play_buf()
583 appl_ptr1 -= appl_ptr1 % runtime->buffer_size; in copy_play_buf()
584 appl_ptr1 += play->buf_pos / play->pcm_salign; in copy_play_buf()
586 appl_ptr1 -= runtime->buffer_size; in copy_play_buf()
587 diff = (appl_ptr - appl_ptr1) * play->pcm_salign; in copy_play_buf()
589 clear_bytes = bytes - diff; in copy_play_buf()
596 if (src_off + size > play->pcm_buffer_size) in copy_play_buf()
597 size = play->pcm_buffer_size - src_off; in copy_play_buf()
598 if (dst_off + size > capt->pcm_buffer_size) in copy_play_buf()
599 size = capt->pcm_buffer_size - dst_off; in copy_play_buf()
600 if (!is_access_interleaved(runtime->access)) in copy_play_buf()
604 capt->silent_size = 0; in copy_play_buf()
605 bytes -= size; in copy_play_buf()
608 src_off = (src_off + size) % play->pcm_buffer_size; in copy_play_buf()
609 dst_off = (dst_off + size) % capt->pcm_buffer_size; in copy_play_buf()
614 capt->silent_size = 0; in copy_play_buf()
624 last_pos = byte_pos(dpcm, dpcm->irq_pos); in bytepos_delta()
625 dpcm->irq_pos += jiffies_delta * dpcm->pcm_bps; in bytepos_delta()
626 delta = byte_pos(dpcm, dpcm->irq_pos) - last_pos; in bytepos_delta()
627 if (delta >= dpcm->last_drift) in bytepos_delta()
628 delta -= dpcm->last_drift; in bytepos_delta()
629 dpcm->last_drift = 0; in bytepos_delta()
630 if (dpcm->irq_pos >= dpcm->period_size_frac) { in bytepos_delta()
631 dpcm->irq_pos %= dpcm->period_size_frac; in bytepos_delta()
632 dpcm->period_update_pending = 1; in bytepos_delta()
640 dpcm->buf_pos += delta; in bytepos_finish()
641 dpcm->buf_pos %= dpcm->pcm_buffer_size; in bytepos_finish()
644 /* call in cable->lock */
649 cable->streams[SNDRV_PCM_STREAM_PLAYBACK]; in loopback_jiffies_timer_pos_update()
651 cable->streams[SNDRV_PCM_STREAM_CAPTURE]; in loopback_jiffies_timer_pos_update()
656 running = cable->running ^ cable->pause; in loopback_jiffies_timer_pos_update()
658 delta_play = cur_jiffies - dpcm_play->last_jiffies; in loopback_jiffies_timer_pos_update()
659 dpcm_play->last_jiffies += delta_play; in loopback_jiffies_timer_pos_update()
663 delta_capt = cur_jiffies - dpcm_capt->last_jiffies; in loopback_jiffies_timer_pos_update()
664 dpcm_capt->last_jiffies += delta_capt; in loopback_jiffies_timer_pos_update()
671 count1 = bytepos_delta(dpcm_play, delta_play - delta_capt); in loopback_jiffies_timer_pos_update()
675 count1 = bytepos_delta(dpcm_capt, delta_capt - delta_play); in loopback_jiffies_timer_pos_update()
688 dpcm_capt->last_drift = count2 - count1; in loopback_jiffies_timer_pos_update()
691 dpcm_play->last_drift = count1 - count2; in loopback_jiffies_timer_pos_update()
705 spin_lock_irqsave(&dpcm->cable->lock, flags); in loopback_jiffies_timer_function()
706 if (loopback_jiffies_timer_pos_update(dpcm->cable) & in loopback_jiffies_timer_function()
707 (1 << dpcm->substream->stream)) { in loopback_jiffies_timer_function()
709 if (dpcm->period_update_pending) { in loopback_jiffies_timer_function()
710 dpcm->period_update_pending = 0; in loopback_jiffies_timer_function()
711 spin_unlock_irqrestore(&dpcm->cable->lock, flags); in loopback_jiffies_timer_function()
713 snd_pcm_period_elapsed(dpcm->substream); in loopback_jiffies_timer_function()
717 spin_unlock_irqrestore(&dpcm->cable->lock, flags); in loopback_jiffies_timer_function()
720 /* call in cable->lock */
724 if (resolution != runtime->timer_resolution) { in loopback_snd_timer_check_resolution()
725 struct loopback_pcm *dpcm = runtime->private_data; in loopback_snd_timer_check_resolution()
726 struct loopback_cable *cable = dpcm->cable; in loopback_snd_timer_check_resolution()
737 resolution / 1000 * runtime->rate; in loopback_snd_timer_check_resolution()
738 /* round to nearest sample rate */ in loopback_snd_timer_check_resolution()
742 pcm_err(dpcm->substream->pcm, in loopback_snd_timer_check_resolution()
744 runtime->period_size, resolution, period_size, in loopback_snd_timer_check_resolution()
745 cable->snd_timer.id.card, in loopback_snd_timer_check_resolution()
746 cable->snd_timer.id.device, in loopback_snd_timer_check_resolution()
747 cable->snd_timer.id.subdevice, in loopback_snd_timer_check_resolution()
749 return -EINVAL; in loopback_snd_timer_check_resolution()
764 spin_lock_irqsave(&cable->lock, flags); in loopback_snd_timer_period_elapsed()
765 running = cable->running ^ cable->pause; in loopback_snd_timer_period_elapsed()
768 spin_unlock_irqrestore(&cable->lock, flags); in loopback_snd_timer_period_elapsed()
772 dpcm_play = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]; in loopback_snd_timer_period_elapsed()
773 dpcm_capt = cable->streams[SNDRV_PCM_STREAM_CAPTURE]; in loopback_snd_timer_period_elapsed()
777 dpcm_play->substream->runtime->state != in loopback_snd_timer_period_elapsed()
779 spin_unlock_irqrestore(&cable->lock, flags); in loopback_snd_timer_period_elapsed()
785 dpcm_play->substream : NULL; in loopback_snd_timer_period_elapsed()
787 dpcm_capt->substream : NULL; in loopback_snd_timer_period_elapsed()
789 dpcm_play->substream->runtime : in loopback_snd_timer_period_elapsed()
790 dpcm_capt->substream->runtime; in loopback_snd_timer_period_elapsed()
800 spin_unlock_irqrestore(&cable->lock, flags); in loopback_snd_timer_period_elapsed()
810 valid_runtime->period_size); in loopback_snd_timer_period_elapsed()
823 spin_unlock_irqrestore(&cable->lock, flags); in loopback_snd_timer_period_elapsed()
835 struct loopback_cable *cable = timeri->callback_data; in loopback_snd_timer_function()
854 /* Do not lock cable->lock here because timer->lock is already hold. in loopback_snd_timer_event()
855 * There are other functions which first lock cable->lock and than in loopback_snd_timer_event()
856 * timer->lock e.g. in loopback_snd_timer_event()
858 * spin_lock(&cable->lock) in loopback_snd_timer_event()
861 * spin_lock(&timer->lock) in loopback_snd_timer_event()
867 struct loopback_cable *cable = timeri->callback_data; in loopback_snd_timer_event()
877 schedule_work(&cable->snd_timer.event_work); in loopback_snd_timer_event()
885 dpcm->period_update_pending); in loopback_jiffies_timer_dpcm_info()
886 snd_iprintf(buffer, " irq_pos:\t\t%u\n", dpcm->irq_pos); in loopback_jiffies_timer_dpcm_info()
887 snd_iprintf(buffer, " period_frac:\t%u\n", dpcm->period_size_frac); in loopback_jiffies_timer_dpcm_info()
889 dpcm->last_jiffies, jiffies); in loopback_jiffies_timer_dpcm_info()
890 snd_iprintf(buffer, " timer_expires:\t%lu\n", dpcm->timer.expires); in loopback_jiffies_timer_dpcm_info()
896 struct loopback_cable *cable = dpcm->cable; in loopback_snd_timer_dpcm_info()
899 cable->snd_timer.id.card, in loopback_snd_timer_dpcm_info()
900 cable->snd_timer.id.device, in loopback_snd_timer_dpcm_info()
901 cable->snd_timer.id.subdevice); in loopback_snd_timer_dpcm_info()
903 snd_pcm_direction_name(cable->snd_timer.stream)); in loopback_snd_timer_dpcm_info()
908 struct snd_pcm_runtime *runtime = substream->runtime; in loopback_pointer()
909 struct loopback_pcm *dpcm = runtime->private_data; in loopback_pointer()
912 spin_lock(&dpcm->cable->lock); in loopback_pointer()
913 if (dpcm->cable->ops->pos_update) in loopback_pointer()
914 dpcm->cable->ops->pos_update(dpcm->cable); in loopback_pointer()
915 pos = dpcm->buf_pos; in loopback_pointer()
916 spin_unlock(&dpcm->cable->lock); in loopback_pointer()
950 struct loopback_pcm *dpcm = runtime->private_data; in loopback_runtime_free()
956 struct snd_pcm_runtime *runtime = substream->runtime; in loopback_hw_free()
957 struct loopback_pcm *dpcm = runtime->private_data; in loopback_hw_free()
958 struct loopback_cable *cable = dpcm->cable; in loopback_hw_free()
960 mutex_lock(&dpcm->loopback->cable_lock); in loopback_hw_free()
961 cable->valid &= ~(1 << substream->stream); in loopback_hw_free()
962 mutex_unlock(&dpcm->loopback->cable_lock); in loopback_hw_free()
968 if (!substream->pcm->device) in get_cable_index()
969 return substream->stream; in get_cable_index()
971 return !substream->stream; in get_cable_index()
977 struct loopback_pcm *dpcm = rule->private; in rule_format()
978 struct loopback_cable *cable = dpcm->cable; in rule_format()
982 mutex_lock(&dpcm->loopback->cable_lock); in rule_format()
983 m.bits[0] = (u_int32_t)cable->hw.formats; in rule_format()
984 m.bits[1] = (u_int32_t)(cable->hw.formats >> 32); in rule_format()
985 mutex_unlock(&dpcm->loopback->cable_lock); in rule_format()
986 return snd_mask_refine(hw_param_mask(params, rule->var), &m); in rule_format()
992 struct loopback_pcm *dpcm = rule->private; in rule_rate()
993 struct loopback_cable *cable = dpcm->cable; in rule_rate()
996 mutex_lock(&dpcm->loopback->cable_lock); in rule_rate()
997 t.min = cable->hw.rate_min; in rule_rate()
998 t.max = cable->hw.rate_max; in rule_rate()
999 mutex_unlock(&dpcm->loopback->cable_lock); in rule_rate()
1002 return snd_interval_refine(hw_param_interval(params, rule->var), &t); in rule_rate()
1008 struct loopback_pcm *dpcm = rule->private; in rule_channels()
1009 struct loopback_cable *cable = dpcm->cable; in rule_channels()
1012 mutex_lock(&dpcm->loopback->cable_lock); in rule_channels()
1013 t.min = cable->hw.channels_min; in rule_channels()
1014 t.max = cable->hw.channels_max; in rule_channels()
1015 mutex_unlock(&dpcm->loopback->cable_lock); in rule_channels()
1018 return snd_interval_refine(hw_param_interval(params, rule->var), &t); in rule_channels()
1024 struct loopback_pcm *dpcm = rule->private; in rule_period_bytes()
1025 struct loopback_cable *cable = dpcm->cable; in rule_period_bytes()
1028 mutex_lock(&dpcm->loopback->cable_lock); in rule_period_bytes()
1029 t.min = cable->hw.period_bytes_min; in rule_period_bytes()
1030 t.max = cable->hw.period_bytes_max; in rule_period_bytes()
1031 mutex_unlock(&dpcm->loopback->cable_lock); in rule_period_bytes()
1035 return snd_interval_refine(hw_param_interval(params, rule->var), &t); in rule_period_bytes()
1040 struct loopback *loopback = substream->private_data; in free_cable()
1044 cable = loopback->cables[substream->number][dev]; in free_cable()
1047 if (cable->streams[!substream->stream]) { in free_cable()
1049 spin_lock_irq(&cable->lock); in free_cable()
1050 cable->streams[substream->stream] = NULL; in free_cable()
1051 spin_unlock_irq(&cable->lock); in free_cable()
1053 struct loopback_pcm *dpcm = substream->runtime->private_data; in free_cable()
1055 if (cable->ops && cable->ops->close_cable && dpcm) in free_cable()
1056 cable->ops->close_cable(dpcm); in free_cable()
1058 loopback->cables[substream->number][dev] = NULL; in free_cable()
1065 timer_setup(&dpcm->timer, loopback_jiffies_timer_function, 0); in loopback_jiffies_timer_open()
1100 if (err == -EINVAL) { in loopback_parse_timer_id()
1106 if (!strcmp(card->id, name)) in loopback_parse_timer_id()
1132 if (card_idx == -1) in loopback_parse_timer_id()
1133 tid->dev_class = SNDRV_TIMER_CLASS_GLOBAL; in loopback_parse_timer_id()
1135 tid->card = card_idx; in loopback_parse_timer_id()
1136 tid->device = dev; in loopback_parse_timer_id()
1137 tid->subdevice = subdev; in loopback_parse_timer_id()
1142 /* call in loopback->cable_lock */
1151 struct loopback_cable *cable = dpcm->cable; in loopback_snd_timer_open()
1156 if (cable->snd_timer.instance) in loopback_snd_timer_open()
1159 err = loopback_parse_timer_id(dpcm->loopback->timer_source, &tid); in loopback_snd_timer_open()
1161 pcm_err(dpcm->substream->pcm, in loopback_snd_timer_open()
1163 dpcm->loopback->timer_source, err); in loopback_snd_timer_open()
1167 cable->snd_timer.stream = dpcm->substream->stream; in loopback_snd_timer_open()
1168 cable->snd_timer.id = tid; in loopback_snd_timer_open()
1170 timeri = snd_timer_instance_new(dpcm->loopback->card->id); in loopback_snd_timer_open()
1172 err = -ENOMEM; in loopback_snd_timer_open()
1183 timeri->flags |= SNDRV_TIMER_IFLG_AUTO; in loopback_snd_timer_open()
1184 timeri->callback = loopback_snd_timer_function; in loopback_snd_timer_open()
1185 timeri->callback_data = (void *)cable; in loopback_snd_timer_open()
1186 timeri->ccallback = loopback_snd_timer_event; in loopback_snd_timer_open()
1189 INIT_WORK(&cable->snd_timer.event_work, loopback_snd_timer_work); in loopback_snd_timer_open()
1191 /* The mutex loopback->cable_lock is kept locked. in loopback_snd_timer_open()
1195 * [proc1] Call loopback_timer_open() -> in loopback_snd_timer_open()
1196 * Unlock cable->lock for snd_timer_close/open() call in loopback_snd_timer_open()
1197 * [proc2] Call loopback_timer_open() -> snd_timer_open(), in loopback_snd_timer_open()
1202 err = snd_timer_open(timeri, &cable->snd_timer.id, current->pid); in loopback_snd_timer_open()
1204 pcm_err(dpcm->substream->pcm, in loopback_snd_timer_open()
1206 cable->snd_timer.id.card, in loopback_snd_timer_open()
1207 cable->snd_timer.id.device, in loopback_snd_timer_open()
1208 cable->snd_timer.id.subdevice, in loopback_snd_timer_open()
1214 cable->snd_timer.instance = timeri; in loopback_snd_timer_open()
1233 struct snd_pcm_runtime *runtime = substream->runtime; in loopback_open()
1234 struct loopback *loopback = substream->private_data; in loopback_open()
1240 mutex_lock(&loopback->cable_lock); in loopback_open()
1243 err = -ENOMEM; in loopback_open()
1246 dpcm->loopback = loopback; in loopback_open()
1247 dpcm->substream = substream; in loopback_open()
1249 cable = loopback->cables[substream->number][dev]; in loopback_open()
1253 err = -ENOMEM; in loopback_open()
1256 spin_lock_init(&cable->lock); in loopback_open()
1257 cable->hw = loopback_pcm_hardware; in loopback_open()
1258 if (loopback->timer_source) in loopback_open()
1259 cable->ops = &loopback_snd_timer_ops; in loopback_open()
1261 cable->ops = &loopback_jiffies_timer_ops; in loopback_open()
1262 loopback->cables[substream->number][dev] = cable; in loopback_open()
1264 dpcm->cable = cable; in loopback_open()
1265 runtime->private_data = dpcm; in loopback_open()
1267 if (cable->ops->open) { in loopback_open()
1268 err = cable->ops->open(dpcm); in loopback_open()
1275 /* use dynamic rules based on actual runtime->hw values */ in loopback_open()
1277 /* are cached -> they do not reflect the actual state */ in loopback_open()
1281 SNDRV_PCM_HW_PARAM_FORMAT, -1); in loopback_open()
1287 SNDRV_PCM_HW_PARAM_RATE, -1); in loopback_open()
1293 SNDRV_PCM_HW_PARAM_CHANNELS, -1); in loopback_open()
1301 if (cable->snd_timer.instance) { in loopback_open()
1305 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, -1); in loopback_open()
1313 runtime->private_free = loopback_runtime_free; in loopback_open()
1315 runtime->hw = loopback_pcm_hardware; in loopback_open()
1317 runtime->hw = cable->hw; in loopback_open()
1319 spin_lock_irq(&cable->lock); in loopback_open()
1320 cable->streams[substream->stream] = dpcm; in loopback_open()
1321 spin_unlock_irq(&cable->lock); in loopback_open()
1328 mutex_unlock(&loopback->cable_lock); in loopback_open()
1334 struct loopback *loopback = substream->private_data; in loopback_close()
1335 struct loopback_pcm *dpcm = substream->runtime->private_data; in loopback_close()
1338 if (dpcm->cable->ops->close_substream) in loopback_close()
1339 err = dpcm->cable->ops->close_substream(dpcm); in loopback_close()
1340 mutex_lock(&loopback->cable_lock); in loopback_close()
1342 mutex_unlock(&loopback->cable_lock); in loopback_close()
1361 err = snd_pcm_new(loopback->card, "Loopback PCM", device, in loopback_pcm_new()
1369 pcm->private_data = loopback; in loopback_pcm_new()
1370 pcm->info_flags = 0; in loopback_pcm_new()
1371 strcpy(pcm->name, "Loopback PCM"); in loopback_pcm_new()
1373 loopback->pcm[device] = pcm; in loopback_pcm_new()
1380 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in loopback_rate_shift_info()
1381 uinfo->count = 1; in loopback_rate_shift_info()
1382 uinfo->value.integer.min = 80000; in loopback_rate_shift_info()
1383 uinfo->value.integer.max = 120000; in loopback_rate_shift_info()
1384 uinfo->value.integer.step = 1; in loopback_rate_shift_info()
1393 mutex_lock(&loopback->cable_lock); in loopback_rate_shift_get()
1394 ucontrol->value.integer.value[0] = in loopback_rate_shift_get()
1395 loopback->setup[kcontrol->id.subdevice] in loopback_rate_shift_get()
1396 [kcontrol->id.device].rate_shift; in loopback_rate_shift_get()
1397 mutex_unlock(&loopback->cable_lock); in loopback_rate_shift_get()
1408 val = ucontrol->value.integer.value[0]; in loopback_rate_shift_put()
1413 mutex_lock(&loopback->cable_lock); in loopback_rate_shift_put()
1414 if (val != loopback->setup[kcontrol->id.subdevice] in loopback_rate_shift_put()
1415 [kcontrol->id.device].rate_shift) { in loopback_rate_shift_put()
1416 loopback->setup[kcontrol->id.subdevice] in loopback_rate_shift_put()
1417 [kcontrol->id.device].rate_shift = val; in loopback_rate_shift_put()
1420 mutex_unlock(&loopback->cable_lock); in loopback_rate_shift_put()
1429 mutex_lock(&loopback->cable_lock); in loopback_notify_get()
1430 ucontrol->value.integer.value[0] = in loopback_notify_get()
1431 loopback->setup[kcontrol->id.subdevice] in loopback_notify_get()
1432 [kcontrol->id.device].notify; in loopback_notify_get()
1433 mutex_unlock(&loopback->cable_lock); in loopback_notify_get()
1444 val = ucontrol->value.integer.value[0] ? 1 : 0; in loopback_notify_put()
1445 mutex_lock(&loopback->cable_lock); in loopback_notify_put()
1446 if (val != loopback->setup[kcontrol->id.subdevice] in loopback_notify_put()
1447 [kcontrol->id.device].notify) { in loopback_notify_put()
1448 loopback->setup[kcontrol->id.subdevice] in loopback_notify_put()
1449 [kcontrol->id.device].notify = val; in loopback_notify_put()
1452 mutex_unlock(&loopback->cable_lock); in loopback_notify_put()
1464 mutex_lock(&loopback->cable_lock); in loopback_active_get()
1465 cable = loopback->cables[kcontrol->id.subdevice][kcontrol->id.device ^ 1]; in loopback_active_get()
1467 unsigned int running = cable->running ^ cable->pause; in loopback_active_get()
1471 mutex_unlock(&loopback->cable_lock); in loopback_active_get()
1472 ucontrol->value.integer.value[0] = val; in loopback_active_get()
1479 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in loopback_format_info()
1480 uinfo->count = 1; in loopback_format_info()
1481 uinfo->value.integer.min = 0; in loopback_format_info()
1482 uinfo->value.integer.max = (__force int)SNDRV_PCM_FORMAT_LAST; in loopback_format_info()
1483 uinfo->value.integer.step = 1; in loopback_format_info()
1492 ucontrol->value.integer.value[0] = in loopback_format_get()
1493 (__force int)loopback->setup[kcontrol->id.subdevice] in loopback_format_get()
1494 [kcontrol->id.device].format; in loopback_format_get()
1501 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in loopback_rate_info()
1502 uinfo->count = 1; in loopback_rate_info()
1503 uinfo->value.integer.min = 0; in loopback_rate_info()
1504 uinfo->value.integer.max = 192000; in loopback_rate_info()
1505 uinfo->value.integer.step = 1; in loopback_rate_info()
1514 mutex_lock(&loopback->cable_lock); in loopback_rate_get()
1515 ucontrol->value.integer.value[0] = in loopback_rate_get()
1516 loopback->setup[kcontrol->id.subdevice] in loopback_rate_get()
1517 [kcontrol->id.device].rate; in loopback_rate_get()
1518 mutex_unlock(&loopback->cable_lock); in loopback_rate_get()
1525 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in loopback_channels_info()
1526 uinfo->count = 1; in loopback_channels_info()
1527 uinfo->value.integer.min = 1; in loopback_channels_info()
1528 uinfo->value.integer.max = 1024; in loopback_channels_info()
1529 uinfo->value.integer.step = 1; in loopback_channels_info()
1538 mutex_lock(&loopback->cable_lock); in loopback_channels_get()
1539 ucontrol->value.integer.value[0] = in loopback_channels_get()
1540 loopback->setup[kcontrol->id.subdevice] in loopback_channels_get()
1541 [kcontrol->id.device].channels; in loopback_channels_get()
1542 mutex_unlock(&loopback->cable_lock); in loopback_channels_get()
1549 const char * const texts[] = {"Interleaved", "Non-interleaved"}; in loopback_access_info()
1560 mutex_lock(&loopback->cable_lock); in loopback_access_get()
1561 access = loopback->setup[kcontrol->id.subdevice][kcontrol->id.device].access; in loopback_access_get()
1563 ucontrol->value.enumerated.item[0] = !is_access_interleaved(access); in loopback_access_get()
1565 mutex_unlock(&loopback->cable_lock); in loopback_access_get()
1572 .name = "PCM Rate Shift 100000",
1604 .name = "PCM Slave Rate",
1628 struct snd_card *card = loopback->card; in loopback_mixer_new()
1634 strcpy(card->mixername, "Loopback Mixer"); in loopback_mixer_new()
1636 pcm = loopback->pcm[dev]; in loopback_mixer_new()
1638 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count; in loopback_mixer_new()
1640 setup = &loopback->setup[substr][dev]; in loopback_mixer_new()
1641 setup->notify = notify; in loopback_mixer_new()
1642 setup->rate_shift = NO_PITCH; in loopback_mixer_new()
1643 setup->format = SNDRV_PCM_FORMAT_S16_LE; in loopback_mixer_new()
1644 setup->access = SNDRV_PCM_ACCESS_RW_INTERLEAVED; in loopback_mixer_new()
1645 setup->rate = 48000; in loopback_mixer_new()
1646 setup->channels = 2; in loopback_mixer_new()
1652 return -ENOMEM; in loopback_mixer_new()
1653 kctl->id.device = dev; in loopback_mixer_new()
1654 kctl->id.subdevice = substr; in loopback_mixer_new()
1665 setup->active_id = kctl->id; in loopback_mixer_new()
1668 setup->format_id = kctl->id; in loopback_mixer_new()
1671 setup->rate_id = kctl->id; in loopback_mixer_new()
1674 setup->channels_id = kctl->id; in loopback_mixer_new()
1677 setup->access_id = kctl->id; in loopback_mixer_new()
1697 snd_iprintf(buffer, " buffer_size:\t%u\n", dpcm->pcm_buffer_size); in print_dpcm_info()
1698 snd_iprintf(buffer, " buffer_pos:\t\t%u\n", dpcm->buf_pos); in print_dpcm_info()
1699 snd_iprintf(buffer, " silent_size:\t%u\n", dpcm->silent_size); in print_dpcm_info()
1700 snd_iprintf(buffer, " period_size:\t%u\n", dpcm->pcm_period_size); in print_dpcm_info()
1701 snd_iprintf(buffer, " bytes_per_sec:\t%u\n", dpcm->pcm_bps); in print_dpcm_info()
1702 snd_iprintf(buffer, " sample_align:\t%u\n", dpcm->pcm_salign); in print_dpcm_info()
1703 snd_iprintf(buffer, " rate_shift:\t\t%u\n", dpcm->pcm_rate_shift); in print_dpcm_info()
1704 if (dpcm->cable->ops->dpcm_info) in print_dpcm_info()
1705 dpcm->cable->ops->dpcm_info(dpcm, buffer); in print_dpcm_info()
1713 struct loopback_cable *cable = loopback->cables[sub][num]; in print_substream_info()
1720 snd_iprintf(buffer, " valid: %u\n", cable->valid); in print_substream_info()
1721 snd_iprintf(buffer, " running: %u\n", cable->running); in print_substream_info()
1722 snd_iprintf(buffer, " pause: %u\n", cable->pause); in print_substream_info()
1723 print_dpcm_info(buffer, cable->streams[0], "Playback"); in print_substream_info()
1724 print_dpcm_info(buffer, cable->streams[1], "Capture"); in print_substream_info()
1730 struct loopback *loopback = entry->private_data; in print_cable_info()
1733 mutex_lock(&loopback->cable_lock); in print_cable_info()
1734 num = entry->name[strlen(entry->name)-1]; in print_cable_info()
1738 mutex_unlock(&loopback->cable_lock); in print_cable_info()
1746 return snd_card_ro_proc_new(loopback->card, name, loopback, in loopback_cable_proc_new()
1753 if (loopback->timer_source) { in loopback_set_timer_source()
1754 devm_kfree(loopback->card->dev, loopback->timer_source); in loopback_set_timer_source()
1755 loopback->timer_source = NULL; in loopback_set_timer_source()
1758 loopback->timer_source = devm_kstrdup(loopback->card->dev, in loopback_set_timer_source()
1765 struct loopback *loopback = entry->private_data; in print_timer_source_info()
1767 mutex_lock(&loopback->cable_lock); in print_timer_source_info()
1769 loopback->timer_source ? loopback->timer_source : ""); in print_timer_source_info()
1770 mutex_unlock(&loopback->cable_lock); in print_timer_source_info()
1776 struct loopback *loopback = entry->private_data; in change_timer_source_info()
1779 mutex_lock(&loopback->cable_lock); in change_timer_source_info()
1782 mutex_unlock(&loopback->cable_lock); in change_timer_source_info()
1787 return snd_card_rw_proc_new(loopback->card, "timer_source", loopback, in loopback_timer_source_proc_new()
1796 int dev = devptr->id; in loopback_probe()
1799 err = snd_devm_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE, in loopback_probe()
1803 loopback = card->private_data; in loopback_probe()
1810 loopback->card = card; in loopback_probe()
1813 mutex_init(&loopback->cable_lock); in loopback_probe()
1827 strcpy(card->driver, "Loopback"); in loopback_probe()
1828 strcpy(card->shortname, "Loopback"); in loopback_probe()
1829 sprintf(card->longname, "Loopback %i", dev + 1); in loopback_probe()
1904 return -ENODEV; in alsa_card_loopback_init()