Lines Matching +full:diff +full:- +full:channels

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
122 unsigned int channels; member
148 unsigned int pcm_salign; /* bytes per sample * channels */
167 if (dpcm->pcm_rate_shift == NO_PITCH) { in byte_pos()
171 HZ * (unsigned long long)dpcm->pcm_rate_shift); in byte_pos()
173 return x - (x % dpcm->pcm_salign); in byte_pos()
178 if (dpcm->pcm_rate_shift == NO_PITCH) { /* no pitch */ in frac_pos()
181 x = div_u64(dpcm->pcm_rate_shift * (unsigned long long)x * HZ, in frac_pos()
189 int device = dpcm->substream->pstr->pcm->device; in get_setup()
191 if (dpcm->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in get_setup()
193 return &dpcm->loopback->setup[dpcm->substream->number][device]; in get_setup()
198 return get_setup(dpcm)->notify; in get_notify()
203 return get_setup(dpcm)->rate_shift; in get_rate_shift()
206 /* call in cable->lock */
212 if (rate_shift != dpcm->pcm_rate_shift) { in loopback_jiffies_timer_start()
213 dpcm->pcm_rate_shift = rate_shift; in loopback_jiffies_timer_start()
214 dpcm->period_size_frac = frac_pos(dpcm, dpcm->pcm_period_size); in loopback_jiffies_timer_start()
216 if (dpcm->period_size_frac <= dpcm->irq_pos) { in loopback_jiffies_timer_start()
217 dpcm->irq_pos %= dpcm->period_size_frac; in loopback_jiffies_timer_start()
218 dpcm->period_update_pending = 1; in loopback_jiffies_timer_start()
220 tick = dpcm->period_size_frac - dpcm->irq_pos; in loopback_jiffies_timer_start()
221 tick = DIV_ROUND_UP(tick, dpcm->pcm_bps); in loopback_jiffies_timer_start()
222 mod_timer(&dpcm->timer, jiffies + tick); in loopback_jiffies_timer_start()
227 /* call in cable->lock */
230 struct loopback_cable *cable = dpcm->cable; in loopback_snd_timer_start()
236 err = snd_timer_start(cable->snd_timer.instance, 1); in loopback_snd_timer_start()
242 if (err == -EBUSY) in loopback_snd_timer_start()
245 pcm_err(dpcm->substream->pcm, in loopback_snd_timer_start()
247 cable->snd_timer.id.card, in loopback_snd_timer_start()
248 cable->snd_timer.id.device, in loopback_snd_timer_start()
249 cable->snd_timer.id.subdevice, in loopback_snd_timer_start()
256 /* call in cable->lock */
259 del_timer(&dpcm->timer); in loopback_jiffies_timer_stop()
260 dpcm->timer.expires = 0; in loopback_jiffies_timer_stop()
265 /* call in cable->lock */
268 struct loopback_cable *cable = dpcm->cable; in loopback_snd_timer_stop()
272 if (cable->running ^ cable->pause) in loopback_snd_timer_stop()
275 err = snd_timer_stop(cable->snd_timer.instance); in loopback_snd_timer_stop()
277 pcm_err(dpcm->substream->pcm, in loopback_snd_timer_stop()
279 cable->snd_timer.id.card, in loopback_snd_timer_stop()
280 cable->snd_timer.id.device, in loopback_snd_timer_stop()
281 cable->snd_timer.id.subdevice, in loopback_snd_timer_stop()
290 del_timer_sync(&dpcm->timer); in loopback_jiffies_timer_stop_sync()
295 /* call in loopback->cable_lock */
298 struct loopback_cable *cable = dpcm->cable; in loopback_snd_timer_close_cable()
301 if (!cable->snd_timer.instance) in loopback_snd_timer_close_cable()
306 * loopback->cable_lock is locked. Therefore no need to lock in loopback_snd_timer_close_cable()
307 * cable->lock; in loopback_snd_timer_close_cable()
309 snd_timer_close(cable->snd_timer.instance); in loopback_snd_timer_close_cable()
312 cancel_work_sync(&cable->snd_timer.event_work); in loopback_snd_timer_close_cable()
314 snd_timer_instance_free(cable->snd_timer.instance); in loopback_snd_timer_close_cable()
315 memset(&cable->snd_timer, 0, sizeof(cable->snd_timer)); in loopback_snd_timer_close_cable()
327 if (cable->valid != CABLE_VALID_BOTH) { in loopback_check_format()
332 runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]-> in loopback_check_format()
333 substream->runtime; in loopback_check_format()
334 cruntime = cable->streams[SNDRV_PCM_STREAM_CAPTURE]-> in loopback_check_format()
335 substream->runtime; in loopback_check_format()
336 check = runtime->format != cruntime->format || in loopback_check_format()
337 runtime->rate != cruntime->rate || in loopback_check_format()
338 runtime->channels != cruntime->channels; in loopback_check_format()
342 return -EIO; in loopback_check_format()
344 snd_pcm_stop(cable->streams[SNDRV_PCM_STREAM_CAPTURE]-> in loopback_check_format()
347 runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]-> in loopback_check_format()
348 substream->runtime; in loopback_check_format()
349 setup = get_setup(cable->streams[SNDRV_PCM_STREAM_PLAYBACK]); in loopback_check_format()
350 card = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->loopback->card; in loopback_check_format()
351 if (setup->format != runtime->format) { in loopback_check_format()
353 &setup->format_id); in loopback_check_format()
354 setup->format = runtime->format; in loopback_check_format()
356 if (setup->rate != runtime->rate) { in loopback_check_format()
358 &setup->rate_id); in loopback_check_format()
359 setup->rate = runtime->rate; in loopback_check_format()
361 if (setup->channels != runtime->channels) { in loopback_check_format()
363 &setup->channels_id); in loopback_check_format()
364 setup->channels = runtime->channels; in loopback_check_format()
372 snd_ctl_notify(dpcm->loopback->card, in loopback_active_notify()
374 &get_setup(dpcm)->active_id); in loopback_active_notify()
379 struct snd_pcm_runtime *runtime = substream->runtime; in loopback_trigger()
380 struct loopback_pcm *dpcm = runtime->private_data; in loopback_trigger()
381 struct loopback_cable *cable = dpcm->cable; in loopback_trigger()
382 int err = 0, stream = 1 << substream->stream; in loopback_trigger()
386 err = loopback_check_format(cable, substream->stream); in loopback_trigger()
389 dpcm->last_jiffies = jiffies; in loopback_trigger()
390 dpcm->pcm_rate_shift = 0; in loopback_trigger()
391 dpcm->last_drift = 0; in loopback_trigger()
392 spin_lock(&cable->lock); in loopback_trigger()
393 cable->running |= stream; in loopback_trigger()
394 cable->pause &= ~stream; in loopback_trigger()
395 err = cable->ops->start(dpcm); in loopback_trigger()
396 spin_unlock(&cable->lock); in loopback_trigger()
397 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in loopback_trigger()
401 spin_lock(&cable->lock); in loopback_trigger()
402 cable->running &= ~stream; in loopback_trigger()
403 cable->pause &= ~stream; in loopback_trigger()
404 err = cable->ops->stop(dpcm); in loopback_trigger()
405 spin_unlock(&cable->lock); in loopback_trigger()
406 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in loopback_trigger()
411 spin_lock(&cable->lock); in loopback_trigger()
412 cable->pause |= stream; in loopback_trigger()
413 err = cable->ops->stop(dpcm); in loopback_trigger()
414 spin_unlock(&cable->lock); in loopback_trigger()
415 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in loopback_trigger()
420 spin_lock(&cable->lock); in loopback_trigger()
421 dpcm->last_jiffies = jiffies; in loopback_trigger()
422 cable->pause &= ~stream; in loopback_trigger()
423 err = cable->ops->start(dpcm); in loopback_trigger()
424 spin_unlock(&cable->lock); in loopback_trigger()
425 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in loopback_trigger()
429 return -EINVAL; in loopback_trigger()
436 struct snd_pcm_runtime *runtime = substream->runtime; in params_change()
437 struct loopback_pcm *dpcm = runtime->private_data; in params_change()
438 struct loopback_cable *cable = dpcm->cable; in params_change()
440 cable->hw.formats = pcm_format_to_bits(runtime->format); in params_change()
441 cable->hw.rate_min = runtime->rate; in params_change()
442 cable->hw.rate_max = runtime->rate; in params_change()
443 cable->hw.channels_min = runtime->channels; in params_change()
444 cable->hw.channels_max = runtime->channels; in params_change()
446 if (cable->snd_timer.instance) { in params_change()
447 cable->hw.period_bytes_min = in params_change()
448 frames_to_bytes(runtime, runtime->period_size); in params_change()
449 cable->hw.period_bytes_max = cable->hw.period_bytes_min; in params_change()
456 struct snd_pcm_runtime *runtime = substream->runtime; in loopback_prepare()
457 struct loopback_pcm *dpcm = runtime->private_data; in loopback_prepare()
458 struct loopback_cable *cable = dpcm->cable; in loopback_prepare()
461 if (cable->ops->stop_sync) { in loopback_prepare()
462 err = cable->ops->stop_sync(dpcm); in loopback_prepare()
467 salign = (snd_pcm_format_physical_width(runtime->format) * in loopback_prepare()
468 runtime->channels) / 8; in loopback_prepare()
469 bps = salign * runtime->rate; in loopback_prepare()
471 return -EINVAL; in loopback_prepare()
473 dpcm->buf_pos = 0; in loopback_prepare()
474 dpcm->pcm_buffer_size = frames_to_bytes(runtime, runtime->buffer_size); in loopback_prepare()
475 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { in loopback_prepare()
477 dpcm->silent_size = dpcm->pcm_buffer_size; in loopback_prepare()
478 snd_pcm_format_set_silence(runtime->format, runtime->dma_area, in loopback_prepare()
479 runtime->buffer_size * runtime->channels); in loopback_prepare()
482 dpcm->irq_pos = 0; in loopback_prepare()
483 dpcm->period_update_pending = 0; in loopback_prepare()
484 dpcm->pcm_bps = bps; in loopback_prepare()
485 dpcm->pcm_salign = salign; in loopback_prepare()
486 dpcm->pcm_period_size = frames_to_bytes(runtime, runtime->period_size); in loopback_prepare()
488 mutex_lock(&dpcm->loopback->cable_lock); in loopback_prepare()
489 if (!(cable->valid & ~(1 << substream->stream)) || in loopback_prepare()
490 (get_setup(dpcm)->notify && in loopback_prepare()
491 substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) in loopback_prepare()
493 cable->valid |= 1 << substream->stream; in loopback_prepare()
494 mutex_unlock(&dpcm->loopback->cable_lock); in loopback_prepare()
501 struct snd_pcm_runtime *runtime = dpcm->substream->runtime; in clear_capture_buf()
502 char *dst = runtime->dma_area; in clear_capture_buf()
503 unsigned int dst_off = dpcm->buf_pos; in clear_capture_buf()
505 if (dpcm->silent_size >= dpcm->pcm_buffer_size) in clear_capture_buf()
507 if (dpcm->silent_size + bytes > dpcm->pcm_buffer_size) in clear_capture_buf()
508 bytes = dpcm->pcm_buffer_size - dpcm->silent_size; in clear_capture_buf()
512 if (dst_off + size > dpcm->pcm_buffer_size) in clear_capture_buf()
513 size = dpcm->pcm_buffer_size - dst_off; in clear_capture_buf()
514 snd_pcm_format_set_silence(runtime->format, dst + dst_off, in clear_capture_buf()
516 runtime->channels); in clear_capture_buf()
517 dpcm->silent_size += size; in clear_capture_buf()
518 bytes -= size; in clear_capture_buf()
529 struct snd_pcm_runtime *runtime = play->substream->runtime; in copy_play_buf()
530 char *src = runtime->dma_area; in copy_play_buf()
531 char *dst = capt->substream->runtime->dma_area; in copy_play_buf()
532 unsigned int src_off = play->buf_pos; in copy_play_buf()
533 unsigned int dst_off = capt->buf_pos; in copy_play_buf()
538 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING && in copy_play_buf()
539 snd_pcm_playback_hw_avail(runtime) < runtime->buffer_size) { in copy_play_buf()
540 snd_pcm_uframes_t appl_ptr, appl_ptr1, diff; in copy_play_buf() local
541 appl_ptr = appl_ptr1 = runtime->control->appl_ptr; in copy_play_buf()
542 appl_ptr1 -= appl_ptr1 % runtime->buffer_size; in copy_play_buf()
543 appl_ptr1 += play->buf_pos / play->pcm_salign; in copy_play_buf()
545 appl_ptr1 -= runtime->buffer_size; in copy_play_buf()
546 diff = (appl_ptr - appl_ptr1) * play->pcm_salign; in copy_play_buf()
547 if (diff < bytes) { in copy_play_buf()
548 clear_bytes = bytes - diff; in copy_play_buf()
549 bytes = diff; in copy_play_buf()
555 if (src_off + size > play->pcm_buffer_size) in copy_play_buf()
556 size = play->pcm_buffer_size - src_off; in copy_play_buf()
557 if (dst_off + size > capt->pcm_buffer_size) in copy_play_buf()
558 size = capt->pcm_buffer_size - dst_off; in copy_play_buf()
560 capt->silent_size = 0; in copy_play_buf()
561 bytes -= size; in copy_play_buf()
564 src_off = (src_off + size) % play->pcm_buffer_size; in copy_play_buf()
565 dst_off = (dst_off + size) % capt->pcm_buffer_size; in copy_play_buf()
570 capt->silent_size = 0; in copy_play_buf()
580 last_pos = byte_pos(dpcm, dpcm->irq_pos); in bytepos_delta()
581 dpcm->irq_pos += jiffies_delta * dpcm->pcm_bps; in bytepos_delta()
582 delta = byte_pos(dpcm, dpcm->irq_pos) - last_pos; in bytepos_delta()
583 if (delta >= dpcm->last_drift) in bytepos_delta()
584 delta -= dpcm->last_drift; in bytepos_delta()
585 dpcm->last_drift = 0; in bytepos_delta()
586 if (dpcm->irq_pos >= dpcm->period_size_frac) { in bytepos_delta()
587 dpcm->irq_pos %= dpcm->period_size_frac; in bytepos_delta()
588 dpcm->period_update_pending = 1; in bytepos_delta()
596 dpcm->buf_pos += delta; in bytepos_finish()
597 dpcm->buf_pos %= dpcm->pcm_buffer_size; in bytepos_finish()
600 /* call in cable->lock */
605 cable->streams[SNDRV_PCM_STREAM_PLAYBACK]; in loopback_jiffies_timer_pos_update()
607 cable->streams[SNDRV_PCM_STREAM_CAPTURE]; in loopback_jiffies_timer_pos_update()
611 running = cable->running ^ cable->pause; in loopback_jiffies_timer_pos_update()
613 delta_play = jiffies - dpcm_play->last_jiffies; in loopback_jiffies_timer_pos_update()
614 dpcm_play->last_jiffies += delta_play; in loopback_jiffies_timer_pos_update()
618 delta_capt = jiffies - dpcm_capt->last_jiffies; in loopback_jiffies_timer_pos_update()
619 dpcm_capt->last_jiffies += delta_capt; in loopback_jiffies_timer_pos_update()
626 count1 = bytepos_delta(dpcm_play, delta_play - delta_capt); in loopback_jiffies_timer_pos_update()
630 count1 = bytepos_delta(dpcm_capt, delta_capt - delta_play); in loopback_jiffies_timer_pos_update()
643 dpcm_capt->last_drift = count2 - count1; in loopback_jiffies_timer_pos_update()
646 dpcm_play->last_drift = count1 - count2; in loopback_jiffies_timer_pos_update()
660 spin_lock_irqsave(&dpcm->cable->lock, flags); in loopback_jiffies_timer_function()
661 if (loopback_jiffies_timer_pos_update(dpcm->cable) & in loopback_jiffies_timer_function()
662 (1 << dpcm->substream->stream)) { in loopback_jiffies_timer_function()
664 if (dpcm->period_update_pending) { in loopback_jiffies_timer_function()
665 dpcm->period_update_pending = 0; in loopback_jiffies_timer_function()
666 spin_unlock_irqrestore(&dpcm->cable->lock, flags); in loopback_jiffies_timer_function()
668 snd_pcm_period_elapsed(dpcm->substream); in loopback_jiffies_timer_function()
672 spin_unlock_irqrestore(&dpcm->cable->lock, flags); in loopback_jiffies_timer_function()
675 /* call in cable->lock */
679 if (resolution != runtime->timer_resolution) { in loopback_snd_timer_check_resolution()
680 struct loopback_pcm *dpcm = runtime->private_data; in loopback_snd_timer_check_resolution()
681 struct loopback_cable *cable = dpcm->cable; in loopback_snd_timer_check_resolution()
692 resolution / 1000 * runtime->rate; in loopback_snd_timer_check_resolution()
697 pcm_err(dpcm->substream->pcm, in loopback_snd_timer_check_resolution()
699 runtime->period_size, resolution, period_size, in loopback_snd_timer_check_resolution()
700 cable->snd_timer.id.card, in loopback_snd_timer_check_resolution()
701 cable->snd_timer.id.device, in loopback_snd_timer_check_resolution()
702 cable->snd_timer.id.subdevice, in loopback_snd_timer_check_resolution()
704 return -EINVAL; in loopback_snd_timer_check_resolution()
719 spin_lock_irqsave(&cable->lock, flags); in loopback_snd_timer_period_elapsed()
720 running = cable->running ^ cable->pause; in loopback_snd_timer_period_elapsed()
723 spin_unlock_irqrestore(&cable->lock, flags); in loopback_snd_timer_period_elapsed()
727 dpcm_play = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]; in loopback_snd_timer_period_elapsed()
728 dpcm_capt = cable->streams[SNDRV_PCM_STREAM_CAPTURE]; in loopback_snd_timer_period_elapsed()
732 dpcm_play->substream->runtime->status->state != in loopback_snd_timer_period_elapsed()
734 spin_unlock_irqrestore(&cable->lock, flags); in loopback_snd_timer_period_elapsed()
740 dpcm_play->substream : NULL; in loopback_snd_timer_period_elapsed()
742 dpcm_capt->substream : NULL; in loopback_snd_timer_period_elapsed()
744 dpcm_play->substream->runtime : in loopback_snd_timer_period_elapsed()
745 dpcm_capt->substream->runtime; in loopback_snd_timer_period_elapsed()
755 spin_unlock_irqrestore(&cable->lock, flags); in loopback_snd_timer_period_elapsed()
765 valid_runtime->period_size); in loopback_snd_timer_period_elapsed()
778 spin_unlock_irqrestore(&cable->lock, flags); in loopback_snd_timer_period_elapsed()
790 struct loopback_cable *cable = timeri->callback_data; in loopback_snd_timer_function()
809 /* Do not lock cable->lock here because timer->lock is already hold. in loopback_snd_timer_event()
810 * There are other functions which first lock cable->lock and than in loopback_snd_timer_event()
811 * timer->lock e.g. in loopback_snd_timer_event()
813 * spin_lock(&cable->lock) in loopback_snd_timer_event()
816 * spin_lock(&timer->lock) in loopback_snd_timer_event()
822 struct loopback_cable *cable = timeri->callback_data; in loopback_snd_timer_event()
832 schedule_work(&cable->snd_timer.event_work); in loopback_snd_timer_event()
840 dpcm->period_update_pending); in loopback_jiffies_timer_dpcm_info()
841 snd_iprintf(buffer, " irq_pos:\t\t%u\n", dpcm->irq_pos); in loopback_jiffies_timer_dpcm_info()
842 snd_iprintf(buffer, " period_frac:\t%u\n", dpcm->period_size_frac); in loopback_jiffies_timer_dpcm_info()
844 dpcm->last_jiffies, jiffies); in loopback_jiffies_timer_dpcm_info()
845 snd_iprintf(buffer, " timer_expires:\t%lu\n", dpcm->timer.expires); in loopback_jiffies_timer_dpcm_info()
851 struct loopback_cable *cable = dpcm->cable; in loopback_snd_timer_dpcm_info()
854 cable->snd_timer.id.card, in loopback_snd_timer_dpcm_info()
855 cable->snd_timer.id.device, in loopback_snd_timer_dpcm_info()
856 cable->snd_timer.id.subdevice); in loopback_snd_timer_dpcm_info()
858 (cable->snd_timer.stream == SNDRV_PCM_STREAM_CAPTURE) ? in loopback_snd_timer_dpcm_info()
864 struct snd_pcm_runtime *runtime = substream->runtime; in loopback_pointer()
865 struct loopback_pcm *dpcm = runtime->private_data; in loopback_pointer()
868 spin_lock(&dpcm->cable->lock); in loopback_pointer()
869 if (dpcm->cable->ops->pos_update) in loopback_pointer()
870 dpcm->cable->ops->pos_update(dpcm->cable); in loopback_pointer()
871 pos = dpcm->buf_pos; in loopback_pointer()
872 spin_unlock(&dpcm->cable->lock); in loopback_pointer()
903 struct loopback_pcm *dpcm = runtime->private_data; in loopback_runtime_free()
909 struct snd_pcm_runtime *runtime = substream->runtime; in loopback_hw_free()
910 struct loopback_pcm *dpcm = runtime->private_data; in loopback_hw_free()
911 struct loopback_cable *cable = dpcm->cable; in loopback_hw_free()
913 mutex_lock(&dpcm->loopback->cable_lock); in loopback_hw_free()
914 cable->valid &= ~(1 << substream->stream); in loopback_hw_free()
915 mutex_unlock(&dpcm->loopback->cable_lock); in loopback_hw_free()
921 if (!substream->pcm->device) in get_cable_index()
922 return substream->stream; in get_cable_index()
924 return !substream->stream; in get_cable_index()
930 struct loopback_pcm *dpcm = rule->private; in rule_format()
931 struct loopback_cable *cable = dpcm->cable; in rule_format()
935 mutex_lock(&dpcm->loopback->cable_lock); in rule_format()
936 m.bits[0] = (u_int32_t)cable->hw.formats; in rule_format()
937 m.bits[1] = (u_int32_t)(cable->hw.formats >> 32); in rule_format()
938 mutex_unlock(&dpcm->loopback->cable_lock); in rule_format()
939 return snd_mask_refine(hw_param_mask(params, rule->var), &m); in rule_format()
945 struct loopback_pcm *dpcm = rule->private; in rule_rate()
946 struct loopback_cable *cable = dpcm->cable; in rule_rate()
949 mutex_lock(&dpcm->loopback->cable_lock); in rule_rate()
950 t.min = cable->hw.rate_min; in rule_rate()
951 t.max = cable->hw.rate_max; in rule_rate()
952 mutex_unlock(&dpcm->loopback->cable_lock); in rule_rate()
955 return snd_interval_refine(hw_param_interval(params, rule->var), &t); in rule_rate()
961 struct loopback_pcm *dpcm = rule->private; in rule_channels()
962 struct loopback_cable *cable = dpcm->cable; in rule_channels()
965 mutex_lock(&dpcm->loopback->cable_lock); in rule_channels()
966 t.min = cable->hw.channels_min; in rule_channels()
967 t.max = cable->hw.channels_max; in rule_channels()
968 mutex_unlock(&dpcm->loopback->cable_lock); in rule_channels()
971 return snd_interval_refine(hw_param_interval(params, rule->var), &t); in rule_channels()
977 struct loopback_pcm *dpcm = rule->private; in rule_period_bytes()
978 struct loopback_cable *cable = dpcm->cable; in rule_period_bytes()
981 mutex_lock(&dpcm->loopback->cable_lock); in rule_period_bytes()
982 t.min = cable->hw.period_bytes_min; in rule_period_bytes()
983 t.max = cable->hw.period_bytes_max; in rule_period_bytes()
984 mutex_unlock(&dpcm->loopback->cable_lock); in rule_period_bytes()
988 return snd_interval_refine(hw_param_interval(params, rule->var), &t); in rule_period_bytes()
993 struct loopback *loopback = substream->private_data; in free_cable()
997 cable = loopback->cables[substream->number][dev]; in free_cable()
1000 if (cable->streams[!substream->stream]) { in free_cable()
1002 spin_lock_irq(&cable->lock); in free_cable()
1003 cable->streams[substream->stream] = NULL; in free_cable()
1004 spin_unlock_irq(&cable->lock); in free_cable()
1006 struct loopback_pcm *dpcm = substream->runtime->private_data; in free_cable()
1008 if (cable->ops && cable->ops->close_cable && dpcm) in free_cable()
1009 cable->ops->close_cable(dpcm); in free_cable()
1011 loopback->cables[substream->number][dev] = NULL; in free_cable()
1018 timer_setup(&dpcm->timer, loopback_jiffies_timer_function, 0); in loopback_jiffies_timer_open()
1053 if (err == -EINVAL) { in loopback_parse_timer_id()
1059 if (!strcmp(card->id, name)) in loopback_parse_timer_id()
1086 tid->card = card_idx; in loopback_parse_timer_id()
1087 tid->device = dev; in loopback_parse_timer_id()
1088 tid->subdevice = subdev; in loopback_parse_timer_id()
1093 /* call in loopback->cable_lock */
1102 struct loopback_cable *cable = dpcm->cable; in loopback_snd_timer_open()
1107 if (cable->snd_timer.instance) in loopback_snd_timer_open()
1110 err = loopback_parse_timer_id(dpcm->loopback->timer_source, &tid); in loopback_snd_timer_open()
1112 pcm_err(dpcm->substream->pcm, in loopback_snd_timer_open()
1114 dpcm->loopback->timer_source, err); in loopback_snd_timer_open()
1118 cable->snd_timer.stream = dpcm->substream->stream; in loopback_snd_timer_open()
1119 cable->snd_timer.id = tid; in loopback_snd_timer_open()
1121 timeri = snd_timer_instance_new(dpcm->loopback->card->id); in loopback_snd_timer_open()
1123 err = -ENOMEM; in loopback_snd_timer_open()
1134 timeri->flags |= SNDRV_TIMER_IFLG_AUTO; in loopback_snd_timer_open()
1135 timeri->callback = loopback_snd_timer_function; in loopback_snd_timer_open()
1136 timeri->callback_data = (void *)cable; in loopback_snd_timer_open()
1137 timeri->ccallback = loopback_snd_timer_event; in loopback_snd_timer_open()
1140 INIT_WORK(&cable->snd_timer.event_work, loopback_snd_timer_work); in loopback_snd_timer_open()
1142 /* The mutex loopback->cable_lock is kept locked. in loopback_snd_timer_open()
1146 * [proc1] Call loopback_timer_open() -> in loopback_snd_timer_open()
1147 * Unlock cable->lock for snd_timer_close/open() call in loopback_snd_timer_open()
1148 * [proc2] Call loopback_timer_open() -> snd_timer_open(), in loopback_snd_timer_open()
1153 err = snd_timer_open(timeri, &cable->snd_timer.id, current->pid); in loopback_snd_timer_open()
1155 pcm_err(dpcm->substream->pcm, in loopback_snd_timer_open()
1157 cable->snd_timer.id.card, in loopback_snd_timer_open()
1158 cable->snd_timer.id.device, in loopback_snd_timer_open()
1159 cable->snd_timer.id.subdevice, in loopback_snd_timer_open()
1165 cable->snd_timer.instance = timeri; in loopback_snd_timer_open()
1184 struct snd_pcm_runtime *runtime = substream->runtime; in loopback_open()
1185 struct loopback *loopback = substream->private_data; in loopback_open()
1191 mutex_lock(&loopback->cable_lock); in loopback_open()
1194 err = -ENOMEM; in loopback_open()
1197 dpcm->loopback = loopback; in loopback_open()
1198 dpcm->substream = substream; in loopback_open()
1200 cable = loopback->cables[substream->number][dev]; in loopback_open()
1204 err = -ENOMEM; in loopback_open()
1207 spin_lock_init(&cable->lock); in loopback_open()
1208 cable->hw = loopback_pcm_hardware; in loopback_open()
1209 if (loopback->timer_source) in loopback_open()
1210 cable->ops = &loopback_snd_timer_ops; in loopback_open()
1212 cable->ops = &loopback_jiffies_timer_ops; in loopback_open()
1213 loopback->cables[substream->number][dev] = cable; in loopback_open()
1215 dpcm->cable = cable; in loopback_open()
1216 runtime->private_data = dpcm; in loopback_open()
1218 if (cable->ops->open) { in loopback_open()
1219 err = cable->ops->open(dpcm); in loopback_open()
1226 /* use dynamic rules based on actual runtime->hw values */ in loopback_open()
1228 /* are cached -> they do not reflect the actual state */ in loopback_open()
1232 SNDRV_PCM_HW_PARAM_FORMAT, -1); in loopback_open()
1238 SNDRV_PCM_HW_PARAM_RATE, -1); in loopback_open()
1244 SNDRV_PCM_HW_PARAM_CHANNELS, -1); in loopback_open()
1252 if (cable->snd_timer.instance) { in loopback_open()
1256 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, -1); in loopback_open()
1264 runtime->private_free = loopback_runtime_free; in loopback_open()
1266 runtime->hw = loopback_pcm_hardware; in loopback_open()
1268 runtime->hw = cable->hw; in loopback_open()
1270 spin_lock_irq(&cable->lock); in loopback_open()
1271 cable->streams[substream->stream] = dpcm; in loopback_open()
1272 spin_unlock_irq(&cable->lock); in loopback_open()
1279 mutex_unlock(&loopback->cable_lock); in loopback_open()
1285 struct loopback *loopback = substream->private_data; in loopback_close()
1286 struct loopback_pcm *dpcm = substream->runtime->private_data; in loopback_close()
1289 if (dpcm->cable->ops->close_substream) in loopback_close()
1290 err = dpcm->cable->ops->close_substream(dpcm); in loopback_close()
1291 mutex_lock(&loopback->cable_lock); in loopback_close()
1293 mutex_unlock(&loopback->cable_lock); in loopback_close()
1312 err = snd_pcm_new(loopback->card, "Loopback PCM", device, in loopback_pcm_new()
1320 pcm->private_data = loopback; in loopback_pcm_new()
1321 pcm->info_flags = 0; in loopback_pcm_new()
1322 strcpy(pcm->name, "Loopback PCM"); in loopback_pcm_new()
1324 loopback->pcm[device] = pcm; in loopback_pcm_new()
1331 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in loopback_rate_shift_info()
1332 uinfo->count = 1; in loopback_rate_shift_info()
1333 uinfo->value.integer.min = 80000; in loopback_rate_shift_info()
1334 uinfo->value.integer.max = 120000; in loopback_rate_shift_info()
1335 uinfo->value.integer.step = 1; in loopback_rate_shift_info()
1344 mutex_lock(&loopback->cable_lock); in loopback_rate_shift_get()
1345 ucontrol->value.integer.value[0] = in loopback_rate_shift_get()
1346 loopback->setup[kcontrol->id.subdevice] in loopback_rate_shift_get()
1347 [kcontrol->id.device].rate_shift; in loopback_rate_shift_get()
1348 mutex_unlock(&loopback->cable_lock); in loopback_rate_shift_get()
1359 val = ucontrol->value.integer.value[0]; in loopback_rate_shift_put()
1364 mutex_lock(&loopback->cable_lock); in loopback_rate_shift_put()
1365 if (val != loopback->setup[kcontrol->id.subdevice] in loopback_rate_shift_put()
1366 [kcontrol->id.device].rate_shift) { in loopback_rate_shift_put()
1367 loopback->setup[kcontrol->id.subdevice] in loopback_rate_shift_put()
1368 [kcontrol->id.device].rate_shift = val; in loopback_rate_shift_put()
1371 mutex_unlock(&loopback->cable_lock); in loopback_rate_shift_put()
1380 mutex_lock(&loopback->cable_lock); in loopback_notify_get()
1381 ucontrol->value.integer.value[0] = in loopback_notify_get()
1382 loopback->setup[kcontrol->id.subdevice] in loopback_notify_get()
1383 [kcontrol->id.device].notify; in loopback_notify_get()
1384 mutex_unlock(&loopback->cable_lock); in loopback_notify_get()
1395 val = ucontrol->value.integer.value[0] ? 1 : 0; in loopback_notify_put()
1396 mutex_lock(&loopback->cable_lock); in loopback_notify_put()
1397 if (val != loopback->setup[kcontrol->id.subdevice] in loopback_notify_put()
1398 [kcontrol->id.device].notify) { in loopback_notify_put()
1399 loopback->setup[kcontrol->id.subdevice] in loopback_notify_put()
1400 [kcontrol->id.device].notify = val; in loopback_notify_put()
1403 mutex_unlock(&loopback->cable_lock); in loopback_notify_put()
1415 mutex_lock(&loopback->cable_lock); in loopback_active_get()
1416 cable = loopback->cables[kcontrol->id.subdevice][kcontrol->id.device ^ 1]; in loopback_active_get()
1418 unsigned int running = cable->running ^ cable->pause; in loopback_active_get()
1422 mutex_unlock(&loopback->cable_lock); in loopback_active_get()
1423 ucontrol->value.integer.value[0] = val; in loopback_active_get()
1430 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in loopback_format_info()
1431 uinfo->count = 1; in loopback_format_info()
1432 uinfo->value.integer.min = 0; in loopback_format_info()
1433 uinfo->value.integer.max = (__force int)SNDRV_PCM_FORMAT_LAST; in loopback_format_info()
1434 uinfo->value.integer.step = 1; in loopback_format_info()
1443 ucontrol->value.integer.value[0] = in loopback_format_get()
1444 (__force int)loopback->setup[kcontrol->id.subdevice] in loopback_format_get()
1445 [kcontrol->id.device].format; in loopback_format_get()
1452 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in loopback_rate_info()
1453 uinfo->count = 1; in loopback_rate_info()
1454 uinfo->value.integer.min = 0; in loopback_rate_info()
1455 uinfo->value.integer.max = 192000; in loopback_rate_info()
1456 uinfo->value.integer.step = 1; in loopback_rate_info()
1465 mutex_lock(&loopback->cable_lock); in loopback_rate_get()
1466 ucontrol->value.integer.value[0] = in loopback_rate_get()
1467 loopback->setup[kcontrol->id.subdevice] in loopback_rate_get()
1468 [kcontrol->id.device].rate; in loopback_rate_get()
1469 mutex_unlock(&loopback->cable_lock); in loopback_rate_get()
1476 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in loopback_channels_info()
1477 uinfo->count = 1; in loopback_channels_info()
1478 uinfo->value.integer.min = 1; in loopback_channels_info()
1479 uinfo->value.integer.max = 1024; in loopback_channels_info()
1480 uinfo->value.integer.step = 1; in loopback_channels_info()
1489 mutex_lock(&loopback->cable_lock); in loopback_channels_get()
1490 ucontrol->value.integer.value[0] = in loopback_channels_get()
1491 loopback->setup[kcontrol->id.subdevice] in loopback_channels_get()
1492 [kcontrol->id.device].channels; in loopback_channels_get()
1493 mutex_unlock(&loopback->cable_lock); in loopback_channels_get()
1540 .name = "PCM Slave Channels",
1548 struct snd_card *card = loopback->card; in loopback_mixer_new()
1554 strcpy(card->mixername, "Loopback Mixer"); in loopback_mixer_new()
1556 pcm = loopback->pcm[dev]; in loopback_mixer_new()
1558 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count; in loopback_mixer_new()
1560 setup = &loopback->setup[substr][dev]; in loopback_mixer_new()
1561 setup->notify = notify; in loopback_mixer_new()
1562 setup->rate_shift = NO_PITCH; in loopback_mixer_new()
1563 setup->format = SNDRV_PCM_FORMAT_S16_LE; in loopback_mixer_new()
1564 setup->rate = 48000; in loopback_mixer_new()
1565 setup->channels = 2; in loopback_mixer_new()
1571 return -ENOMEM; in loopback_mixer_new()
1572 kctl->id.device = dev; in loopback_mixer_new()
1573 kctl->id.subdevice = substr; in loopback_mixer_new()
1584 setup->active_id = kctl->id; in loopback_mixer_new()
1587 setup->format_id = kctl->id; in loopback_mixer_new()
1590 setup->rate_id = kctl->id; in loopback_mixer_new()
1593 setup->channels_id = kctl->id; in loopback_mixer_new()
1613 snd_iprintf(buffer, " buffer_size:\t%u\n", dpcm->pcm_buffer_size); in print_dpcm_info()
1614 snd_iprintf(buffer, " buffer_pos:\t\t%u\n", dpcm->buf_pos); in print_dpcm_info()
1615 snd_iprintf(buffer, " silent_size:\t%u\n", dpcm->silent_size); in print_dpcm_info()
1616 snd_iprintf(buffer, " period_size:\t%u\n", dpcm->pcm_period_size); in print_dpcm_info()
1617 snd_iprintf(buffer, " bytes_per_sec:\t%u\n", dpcm->pcm_bps); in print_dpcm_info()
1618 snd_iprintf(buffer, " sample_align:\t%u\n", dpcm->pcm_salign); in print_dpcm_info()
1619 snd_iprintf(buffer, " rate_shift:\t\t%u\n", dpcm->pcm_rate_shift); in print_dpcm_info()
1620 if (dpcm->cable->ops->dpcm_info) in print_dpcm_info()
1621 dpcm->cable->ops->dpcm_info(dpcm, buffer); in print_dpcm_info()
1629 struct loopback_cable *cable = loopback->cables[sub][num]; in print_substream_info()
1636 snd_iprintf(buffer, " valid: %u\n", cable->valid); in print_substream_info()
1637 snd_iprintf(buffer, " running: %u\n", cable->running); in print_substream_info()
1638 snd_iprintf(buffer, " pause: %u\n", cable->pause); in print_substream_info()
1639 print_dpcm_info(buffer, cable->streams[0], "Playback"); in print_substream_info()
1640 print_dpcm_info(buffer, cable->streams[1], "Capture"); in print_substream_info()
1646 struct loopback *loopback = entry->private_data; in print_cable_info()
1649 mutex_lock(&loopback->cable_lock); in print_cable_info()
1650 num = entry->name[strlen(entry->name)-1]; in print_cable_info()
1654 mutex_unlock(&loopback->cable_lock); in print_cable_info()
1662 return snd_card_ro_proc_new(loopback->card, name, loopback, in loopback_cable_proc_new()
1669 if (loopback->timer_source) { in loopback_set_timer_source()
1670 devm_kfree(loopback->card->dev, loopback->timer_source); in loopback_set_timer_source()
1671 loopback->timer_source = NULL; in loopback_set_timer_source()
1674 loopback->timer_source = devm_kstrdup(loopback->card->dev, in loopback_set_timer_source()
1681 struct loopback *loopback = entry->private_data; in print_timer_source_info()
1683 mutex_lock(&loopback->cable_lock); in print_timer_source_info()
1685 loopback->timer_source ? loopback->timer_source : ""); in print_timer_source_info()
1686 mutex_unlock(&loopback->cable_lock); in print_timer_source_info()
1692 struct loopback *loopback = entry->private_data; in change_timer_source_info()
1695 mutex_lock(&loopback->cable_lock); in change_timer_source_info()
1698 mutex_unlock(&loopback->cable_lock); in change_timer_source_info()
1703 return snd_card_rw_proc_new(loopback->card, "timer_source", loopback, in loopback_timer_source_proc_new()
1712 int dev = devptr->id; in loopback_probe()
1715 err = snd_devm_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE, in loopback_probe()
1719 loopback = card->private_data; in loopback_probe()
1726 loopback->card = card; in loopback_probe()
1729 mutex_init(&loopback->cable_lock); in loopback_probe()
1743 strcpy(card->driver, "Loopback"); in loopback_probe()
1744 strcpy(card->shortname, "Loopback"); in loopback_probe()
1745 sprintf(card->longname, "Loopback %i", dev + 1); in loopback_probe()
1825 return -ENODEV; in alsa_card_loopback_init()