• Home
  • Raw
  • Download

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>
40 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
42 static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
43 static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
54 MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-8) for loopback driver.");
56 MODULE_PARM_DESC(pcm_notify, "Break capture when PCM format/rate/channels changes.");
71 * call in loopback->cable_lock
75 * call in cable->lock
79 * call in cable->lock
87 * call in loopback->cable_lock
91 * call in cable->lock
123 unsigned int channels; member
149 unsigned int pcm_salign; /* bytes per sample * channels */
168 if (dpcm->pcm_rate_shift == NO_PITCH) { in byte_pos()
172 HZ * (unsigned long long)dpcm->pcm_rate_shift); in byte_pos()
174 return x - (x % dpcm->pcm_salign); in byte_pos()
179 if (dpcm->pcm_rate_shift == NO_PITCH) { /* no pitch */ in frac_pos()
182 x = div_u64(dpcm->pcm_rate_shift * (unsigned long long)x * HZ, in frac_pos()
190 int device = dpcm->substream->pstr->pcm->device; in get_setup()
192 if (dpcm->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in get_setup()
194 return &dpcm->loopback->setup[dpcm->substream->number][device]; in get_setup()
199 return get_setup(dpcm)->notify; in get_notify()
204 return get_setup(dpcm)->rate_shift; in get_rate_shift()
207 /* call in cable->lock */
213 if (rate_shift != dpcm->pcm_rate_shift) { in loopback_jiffies_timer_start()
214 dpcm->pcm_rate_shift = rate_shift; in loopback_jiffies_timer_start()
215 dpcm->period_size_frac = frac_pos(dpcm, dpcm->pcm_period_size); in loopback_jiffies_timer_start()
217 if (dpcm->period_size_frac <= dpcm->irq_pos) { in loopback_jiffies_timer_start()
218 dpcm->irq_pos %= dpcm->period_size_frac; in loopback_jiffies_timer_start()
219 dpcm->period_update_pending = 1; in loopback_jiffies_timer_start()
221 tick = dpcm->period_size_frac - dpcm->irq_pos; in loopback_jiffies_timer_start()
222 tick = (tick + dpcm->pcm_bps - 1) / dpcm->pcm_bps; in loopback_jiffies_timer_start()
223 mod_timer(&dpcm->timer, jiffies + tick); in loopback_jiffies_timer_start()
228 /* call in cable->lock */
231 struct loopback_cable *cable = dpcm->cable; in loopback_snd_timer_start()
237 err = snd_timer_start(cable->snd_timer.instance, 1); in loopback_snd_timer_start()
243 if (err == -EBUSY) in loopback_snd_timer_start()
246 pcm_err(dpcm->substream->pcm, in loopback_snd_timer_start()
248 cable->snd_timer.id.card, in loopback_snd_timer_start()
249 cable->snd_timer.id.device, in loopback_snd_timer_start()
250 cable->snd_timer.id.subdevice, in loopback_snd_timer_start()
257 /* call in cable->lock */
260 del_timer(&dpcm->timer); in loopback_jiffies_timer_stop()
261 dpcm->timer.expires = 0; in loopback_jiffies_timer_stop()
266 /* call in cable->lock */
269 struct loopback_cable *cable = dpcm->cable; in loopback_snd_timer_stop()
273 if (cable->running ^ cable->pause) in loopback_snd_timer_stop()
276 err = snd_timer_stop(cable->snd_timer.instance); in loopback_snd_timer_stop()
278 pcm_err(dpcm->substream->pcm, in loopback_snd_timer_stop()
280 cable->snd_timer.id.card, in loopback_snd_timer_stop()
281 cable->snd_timer.id.device, in loopback_snd_timer_stop()
282 cable->snd_timer.id.subdevice, in loopback_snd_timer_stop()
291 del_timer_sync(&dpcm->timer); in loopback_jiffies_timer_stop_sync()
296 /* call in loopback->cable_lock */
299 struct loopback_cable *cable = dpcm->cable; in loopback_snd_timer_close_cable()
302 if (!cable->snd_timer.instance) in loopback_snd_timer_close_cable()
307 * loopback->cable_lock is locked. Therefore no need to lock in loopback_snd_timer_close_cable()
308 * cable->lock; in loopback_snd_timer_close_cable()
310 snd_timer_close(cable->snd_timer.instance); in loopback_snd_timer_close_cable()
313 cancel_work_sync(&cable->snd_timer.event_work); in loopback_snd_timer_close_cable()
315 snd_timer_instance_free(cable->snd_timer.instance); in loopback_snd_timer_close_cable()
316 memset(&cable->snd_timer, 0, sizeof(cable->snd_timer)); in loopback_snd_timer_close_cable()
328 if (cable->valid != CABLE_VALID_BOTH) { in loopback_check_format()
333 runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]-> in loopback_check_format()
334 substream->runtime; in loopback_check_format()
335 cruntime = cable->streams[SNDRV_PCM_STREAM_CAPTURE]-> in loopback_check_format()
336 substream->runtime; in loopback_check_format()
337 check = runtime->format != cruntime->format || in loopback_check_format()
338 runtime->rate != cruntime->rate || in loopback_check_format()
339 runtime->channels != cruntime->channels; in loopback_check_format()
343 return -EIO; in loopback_check_format()
345 snd_pcm_stop(cable->streams[SNDRV_PCM_STREAM_CAPTURE]-> in loopback_check_format()
348 runtime = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]-> in loopback_check_format()
349 substream->runtime; in loopback_check_format()
350 setup = get_setup(cable->streams[SNDRV_PCM_STREAM_PLAYBACK]); in loopback_check_format()
351 card = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]->loopback->card; in loopback_check_format()
352 if (setup->format != runtime->format) { in loopback_check_format()
354 &setup->format_id); in loopback_check_format()
355 setup->format = runtime->format; in loopback_check_format()
357 if (setup->rate != runtime->rate) { in loopback_check_format()
359 &setup->rate_id); in loopback_check_format()
360 setup->rate = runtime->rate; in loopback_check_format()
362 if (setup->channels != runtime->channels) { in loopback_check_format()
364 &setup->channels_id); in loopback_check_format()
365 setup->channels = runtime->channels; in loopback_check_format()
373 snd_ctl_notify(dpcm->loopback->card, in loopback_active_notify()
375 &get_setup(dpcm)->active_id); in loopback_active_notify()
380 struct snd_pcm_runtime *runtime = substream->runtime; in loopback_trigger()
381 struct loopback_pcm *dpcm = runtime->private_data; in loopback_trigger()
382 struct loopback_cable *cable = dpcm->cable; in loopback_trigger()
383 int err = 0, stream = 1 << substream->stream; in loopback_trigger()
387 err = loopback_check_format(cable, substream->stream); in loopback_trigger()
390 dpcm->last_jiffies = jiffies; in loopback_trigger()
391 dpcm->pcm_rate_shift = 0; in loopback_trigger()
392 dpcm->last_drift = 0; in loopback_trigger()
393 spin_lock(&cable->lock); in loopback_trigger()
394 cable->running |= stream; in loopback_trigger()
395 cable->pause &= ~stream; in loopback_trigger()
396 err = cable->ops->start(dpcm); in loopback_trigger()
397 spin_unlock(&cable->lock); in loopback_trigger()
398 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in loopback_trigger()
402 spin_lock(&cable->lock); in loopback_trigger()
403 cable->running &= ~stream; in loopback_trigger()
404 cable->pause &= ~stream; in loopback_trigger()
405 err = cable->ops->stop(dpcm); in loopback_trigger()
406 spin_unlock(&cable->lock); in loopback_trigger()
407 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in loopback_trigger()
412 spin_lock(&cable->lock); in loopback_trigger()
413 cable->pause |= stream; in loopback_trigger()
414 err = cable->ops->stop(dpcm); in loopback_trigger()
415 spin_unlock(&cable->lock); in loopback_trigger()
416 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in loopback_trigger()
421 spin_lock(&cable->lock); in loopback_trigger()
422 dpcm->last_jiffies = jiffies; in loopback_trigger()
423 cable->pause &= ~stream; in loopback_trigger()
424 err = cable->ops->start(dpcm); in loopback_trigger()
425 spin_unlock(&cable->lock); in loopback_trigger()
426 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in loopback_trigger()
430 return -EINVAL; in loopback_trigger()
437 struct snd_pcm_runtime *runtime = substream->runtime; in params_change()
438 struct loopback_pcm *dpcm = runtime->private_data; in params_change()
439 struct loopback_cable *cable = dpcm->cable; in params_change()
441 cable->hw.formats = pcm_format_to_bits(runtime->format); in params_change()
442 cable->hw.rate_min = runtime->rate; in params_change()
443 cable->hw.rate_max = runtime->rate; in params_change()
444 cable->hw.channels_min = runtime->channels; in params_change()
445 cable->hw.channels_max = runtime->channels; in params_change()
447 if (cable->snd_timer.instance) { in params_change()
448 cable->hw.period_bytes_min = in params_change()
449 frames_to_bytes(runtime, runtime->period_size); in params_change()
450 cable->hw.period_bytes_max = cable->hw.period_bytes_min; in params_change()
457 struct snd_pcm_runtime *runtime = substream->runtime; in loopback_prepare()
458 struct loopback_pcm *dpcm = runtime->private_data; in loopback_prepare()
459 struct loopback_cable *cable = dpcm->cable; in loopback_prepare()
462 if (cable->ops->stop_sync) { in loopback_prepare()
463 err = cable->ops->stop_sync(dpcm); in loopback_prepare()
468 salign = (snd_pcm_format_physical_width(runtime->format) * in loopback_prepare()
469 runtime->channels) / 8; in loopback_prepare()
470 bps = salign * runtime->rate; in loopback_prepare()
472 return -EINVAL; in loopback_prepare()
474 dpcm->buf_pos = 0; in loopback_prepare()
475 dpcm->pcm_buffer_size = frames_to_bytes(runtime, runtime->buffer_size); in loopback_prepare()
476 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { in loopback_prepare()
478 dpcm->silent_size = dpcm->pcm_buffer_size; in loopback_prepare()
479 snd_pcm_format_set_silence(runtime->format, runtime->dma_area, in loopback_prepare()
480 runtime->buffer_size * runtime->channels); in loopback_prepare()
483 dpcm->irq_pos = 0; in loopback_prepare()
484 dpcm->period_update_pending = 0; in loopback_prepare()
485 dpcm->pcm_bps = bps; in loopback_prepare()
486 dpcm->pcm_salign = salign; in loopback_prepare()
487 dpcm->pcm_period_size = frames_to_bytes(runtime, runtime->period_size); in loopback_prepare()
489 mutex_lock(&dpcm->loopback->cable_lock); in loopback_prepare()
490 if (!(cable->valid & ~(1 << substream->stream)) || in loopback_prepare()
491 (get_setup(dpcm)->notify && in loopback_prepare()
492 substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) in loopback_prepare()
494 cable->valid |= 1 << substream->stream; in loopback_prepare()
495 mutex_unlock(&dpcm->loopback->cable_lock); in loopback_prepare()
502 struct snd_pcm_runtime *runtime = dpcm->substream->runtime; in clear_capture_buf()
503 char *dst = runtime->dma_area; in clear_capture_buf()
504 unsigned int dst_off = dpcm->buf_pos; in clear_capture_buf()
506 if (dpcm->silent_size >= dpcm->pcm_buffer_size) in clear_capture_buf()
508 if (dpcm->silent_size + bytes > dpcm->pcm_buffer_size) in clear_capture_buf()
509 bytes = dpcm->pcm_buffer_size - dpcm->silent_size; in clear_capture_buf()
513 if (dst_off + size > dpcm->pcm_buffer_size) in clear_capture_buf()
514 size = dpcm->pcm_buffer_size - dst_off; in clear_capture_buf()
515 snd_pcm_format_set_silence(runtime->format, dst + dst_off, in clear_capture_buf()
517 runtime->channels); in clear_capture_buf()
518 dpcm->silent_size += size; in clear_capture_buf()
519 bytes -= size; in clear_capture_buf()
530 struct snd_pcm_runtime *runtime = play->substream->runtime; in copy_play_buf()
531 char *src = runtime->dma_area; in copy_play_buf()
532 char *dst = capt->substream->runtime->dma_area; in copy_play_buf()
533 unsigned int src_off = play->buf_pos; in copy_play_buf()
534 unsigned int dst_off = capt->buf_pos; in copy_play_buf()
539 if (runtime->status->state == SNDRV_PCM_STATE_DRAINING && in copy_play_buf()
540 snd_pcm_playback_hw_avail(runtime) < runtime->buffer_size) { in copy_play_buf()
541 snd_pcm_uframes_t appl_ptr, appl_ptr1, diff; in copy_play_buf() local
542 appl_ptr = appl_ptr1 = runtime->control->appl_ptr; in copy_play_buf()
543 appl_ptr1 -= appl_ptr1 % runtime->buffer_size; in copy_play_buf()
544 appl_ptr1 += play->buf_pos / play->pcm_salign; in copy_play_buf()
546 appl_ptr1 -= runtime->buffer_size; in copy_play_buf()
547 diff = (appl_ptr - appl_ptr1) * play->pcm_salign; in copy_play_buf()
548 if (diff < bytes) { in copy_play_buf()
549 clear_bytes = bytes - diff; in copy_play_buf()
550 bytes = diff; in copy_play_buf()
556 if (src_off + size > play->pcm_buffer_size) in copy_play_buf()
557 size = play->pcm_buffer_size - src_off; in copy_play_buf()
558 if (dst_off + size > capt->pcm_buffer_size) in copy_play_buf()
559 size = capt->pcm_buffer_size - dst_off; in copy_play_buf()
561 capt->silent_size = 0; in copy_play_buf()
562 bytes -= size; in copy_play_buf()
565 src_off = (src_off + size) % play->pcm_buffer_size; in copy_play_buf()
566 dst_off = (dst_off + size) % capt->pcm_buffer_size; in copy_play_buf()
571 capt->silent_size = 0; in copy_play_buf()
581 last_pos = byte_pos(dpcm, dpcm->irq_pos); in bytepos_delta()
582 dpcm->irq_pos += jiffies_delta * dpcm->pcm_bps; in bytepos_delta()
583 delta = byte_pos(dpcm, dpcm->irq_pos) - last_pos; in bytepos_delta()
584 if (delta >= dpcm->last_drift) in bytepos_delta()
585 delta -= dpcm->last_drift; in bytepos_delta()
586 dpcm->last_drift = 0; in bytepos_delta()
587 if (dpcm->irq_pos >= dpcm->period_size_frac) { in bytepos_delta()
588 dpcm->irq_pos %= dpcm->period_size_frac; in bytepos_delta()
589 dpcm->period_update_pending = 1; in bytepos_delta()
597 dpcm->buf_pos += delta; in bytepos_finish()
598 dpcm->buf_pos %= dpcm->pcm_buffer_size; in bytepos_finish()
601 /* call in cable->lock */
606 cable->streams[SNDRV_PCM_STREAM_PLAYBACK]; in loopback_jiffies_timer_pos_update()
608 cable->streams[SNDRV_PCM_STREAM_CAPTURE]; in loopback_jiffies_timer_pos_update()
612 running = cable->running ^ cable->pause; in loopback_jiffies_timer_pos_update()
614 delta_play = jiffies - dpcm_play->last_jiffies; in loopback_jiffies_timer_pos_update()
615 dpcm_play->last_jiffies += delta_play; in loopback_jiffies_timer_pos_update()
619 delta_capt = jiffies - dpcm_capt->last_jiffies; in loopback_jiffies_timer_pos_update()
620 dpcm_capt->last_jiffies += delta_capt; in loopback_jiffies_timer_pos_update()
627 count1 = bytepos_delta(dpcm_play, delta_play - delta_capt); in loopback_jiffies_timer_pos_update()
631 count1 = bytepos_delta(dpcm_capt, delta_capt - delta_play); in loopback_jiffies_timer_pos_update()
644 dpcm_capt->last_drift = count2 - count1; in loopback_jiffies_timer_pos_update()
647 dpcm_play->last_drift = count1 - count2; in loopback_jiffies_timer_pos_update()
661 spin_lock_irqsave(&dpcm->cable->lock, flags); in loopback_jiffies_timer_function()
662 if (loopback_jiffies_timer_pos_update(dpcm->cable) & in loopback_jiffies_timer_function()
663 (1 << dpcm->substream->stream)) { in loopback_jiffies_timer_function()
665 if (dpcm->period_update_pending) { in loopback_jiffies_timer_function()
666 dpcm->period_update_pending = 0; in loopback_jiffies_timer_function()
667 spin_unlock_irqrestore(&dpcm->cable->lock, flags); in loopback_jiffies_timer_function()
669 snd_pcm_period_elapsed(dpcm->substream); in loopback_jiffies_timer_function()
673 spin_unlock_irqrestore(&dpcm->cable->lock, flags); in loopback_jiffies_timer_function()
676 /* call in cable->lock */
680 if (resolution != runtime->timer_resolution) { in loopback_snd_timer_check_resolution()
681 struct loopback_pcm *dpcm = runtime->private_data; in loopback_snd_timer_check_resolution()
682 struct loopback_cable *cable = dpcm->cable; in loopback_snd_timer_check_resolution()
693 resolution / 1000 * runtime->rate; in loopback_snd_timer_check_resolution()
698 pcm_err(dpcm->substream->pcm, in loopback_snd_timer_check_resolution()
700 runtime->period_size, resolution, period_size, in loopback_snd_timer_check_resolution()
701 cable->snd_timer.id.card, in loopback_snd_timer_check_resolution()
702 cable->snd_timer.id.device, in loopback_snd_timer_check_resolution()
703 cable->snd_timer.id.subdevice, in loopback_snd_timer_check_resolution()
705 return -EINVAL; in loopback_snd_timer_check_resolution()
720 spin_lock_irqsave(&cable->lock, flags); in loopback_snd_timer_period_elapsed()
721 running = cable->running ^ cable->pause; in loopback_snd_timer_period_elapsed()
724 spin_unlock_irqrestore(&cable->lock, flags); in loopback_snd_timer_period_elapsed()
728 dpcm_play = cable->streams[SNDRV_PCM_STREAM_PLAYBACK]; in loopback_snd_timer_period_elapsed()
729 dpcm_capt = cable->streams[SNDRV_PCM_STREAM_CAPTURE]; in loopback_snd_timer_period_elapsed()
733 dpcm_play->substream->runtime->status->state != in loopback_snd_timer_period_elapsed()
735 spin_unlock_irqrestore(&cable->lock, flags); in loopback_snd_timer_period_elapsed()
741 dpcm_play->substream : NULL; in loopback_snd_timer_period_elapsed()
743 dpcm_capt->substream : NULL; in loopback_snd_timer_period_elapsed()
745 dpcm_play->substream->runtime : in loopback_snd_timer_period_elapsed()
746 dpcm_capt->substream->runtime; in loopback_snd_timer_period_elapsed()
756 spin_unlock_irqrestore(&cable->lock, flags); in loopback_snd_timer_period_elapsed()
766 valid_runtime->period_size); in loopback_snd_timer_period_elapsed()
779 spin_unlock_irqrestore(&cable->lock, flags); in loopback_snd_timer_period_elapsed()
791 struct loopback_cable *cable = timeri->callback_data; in loopback_snd_timer_function()
810 /* Do not lock cable->lock here because timer->lock is already hold. in loopback_snd_timer_event()
811 * There are other functions which first lock cable->lock and than in loopback_snd_timer_event()
812 * timer->lock e.g. in loopback_snd_timer_event()
814 * spin_lock(&cable->lock) in loopback_snd_timer_event()
817 * spin_lock(&timer->lock) in loopback_snd_timer_event()
823 struct loopback_cable *cable = timeri->callback_data; in loopback_snd_timer_event()
833 schedule_work(&cable->snd_timer.event_work); in loopback_snd_timer_event()
841 dpcm->period_update_pending); in loopback_jiffies_timer_dpcm_info()
842 snd_iprintf(buffer, " irq_pos:\t\t%u\n", dpcm->irq_pos); in loopback_jiffies_timer_dpcm_info()
843 snd_iprintf(buffer, " period_frac:\t%u\n", dpcm->period_size_frac); in loopback_jiffies_timer_dpcm_info()
845 dpcm->last_jiffies, jiffies); in loopback_jiffies_timer_dpcm_info()
846 snd_iprintf(buffer, " timer_expires:\t%lu\n", dpcm->timer.expires); in loopback_jiffies_timer_dpcm_info()
852 struct loopback_cable *cable = dpcm->cable; in loopback_snd_timer_dpcm_info()
855 cable->snd_timer.id.card, in loopback_snd_timer_dpcm_info()
856 cable->snd_timer.id.device, in loopback_snd_timer_dpcm_info()
857 cable->snd_timer.id.subdevice); in loopback_snd_timer_dpcm_info()
859 (cable->snd_timer.stream == SNDRV_PCM_STREAM_CAPTURE) ? in loopback_snd_timer_dpcm_info()
865 struct snd_pcm_runtime *runtime = substream->runtime; in loopback_pointer()
866 struct loopback_pcm *dpcm = runtime->private_data; in loopback_pointer()
869 spin_lock(&dpcm->cable->lock); in loopback_pointer()
870 if (dpcm->cable->ops->pos_update) in loopback_pointer()
871 dpcm->cable->ops->pos_update(dpcm->cable); in loopback_pointer()
872 pos = dpcm->buf_pos; in loopback_pointer()
873 spin_unlock(&dpcm->cable->lock); in loopback_pointer()
904 struct loopback_pcm *dpcm = runtime->private_data; in loopback_runtime_free()
910 struct snd_pcm_runtime *runtime = substream->runtime; in loopback_hw_free()
911 struct loopback_pcm *dpcm = runtime->private_data; in loopback_hw_free()
912 struct loopback_cable *cable = dpcm->cable; in loopback_hw_free()
914 mutex_lock(&dpcm->loopback->cable_lock); in loopback_hw_free()
915 cable->valid &= ~(1 << substream->stream); in loopback_hw_free()
916 mutex_unlock(&dpcm->loopback->cable_lock); in loopback_hw_free()
922 if (!substream->pcm->device) in get_cable_index()
923 return substream->stream; in get_cable_index()
925 return !substream->stream; in get_cable_index()
931 struct loopback_pcm *dpcm = rule->private; in rule_format()
932 struct loopback_cable *cable = dpcm->cable; in rule_format()
936 mutex_lock(&dpcm->loopback->cable_lock); in rule_format()
937 m.bits[0] = (u_int32_t)cable->hw.formats; in rule_format()
938 m.bits[1] = (u_int32_t)(cable->hw.formats >> 32); in rule_format()
939 mutex_unlock(&dpcm->loopback->cable_lock); in rule_format()
940 return snd_mask_refine(hw_param_mask(params, rule->var), &m); in rule_format()
946 struct loopback_pcm *dpcm = rule->private; in rule_rate()
947 struct loopback_cable *cable = dpcm->cable; in rule_rate()
950 mutex_lock(&dpcm->loopback->cable_lock); in rule_rate()
951 t.min = cable->hw.rate_min; in rule_rate()
952 t.max = cable->hw.rate_max; in rule_rate()
953 mutex_unlock(&dpcm->loopback->cable_lock); in rule_rate()
956 return snd_interval_refine(hw_param_interval(params, rule->var), &t); in rule_rate()
962 struct loopback_pcm *dpcm = rule->private; in rule_channels()
963 struct loopback_cable *cable = dpcm->cable; in rule_channels()
966 mutex_lock(&dpcm->loopback->cable_lock); in rule_channels()
967 t.min = cable->hw.channels_min; in rule_channels()
968 t.max = cable->hw.channels_max; in rule_channels()
969 mutex_unlock(&dpcm->loopback->cable_lock); in rule_channels()
972 return snd_interval_refine(hw_param_interval(params, rule->var), &t); in rule_channels()
978 struct loopback_pcm *dpcm = rule->private; in rule_period_bytes()
979 struct loopback_cable *cable = dpcm->cable; in rule_period_bytes()
982 mutex_lock(&dpcm->loopback->cable_lock); in rule_period_bytes()
983 t.min = cable->hw.period_bytes_min; in rule_period_bytes()
984 t.max = cable->hw.period_bytes_max; in rule_period_bytes()
985 mutex_unlock(&dpcm->loopback->cable_lock); in rule_period_bytes()
989 return snd_interval_refine(hw_param_interval(params, rule->var), &t); in rule_period_bytes()
994 struct loopback *loopback = substream->private_data; in free_cable()
998 cable = loopback->cables[substream->number][dev]; in free_cable()
1001 if (cable->streams[!substream->stream]) { in free_cable()
1003 spin_lock_irq(&cable->lock); in free_cable()
1004 cable->streams[substream->stream] = NULL; in free_cable()
1005 spin_unlock_irq(&cable->lock); in free_cable()
1007 struct loopback_pcm *dpcm = substream->runtime->private_data; in free_cable()
1009 if (cable->ops && cable->ops->close_cable && dpcm) in free_cable()
1010 cable->ops->close_cable(dpcm); in free_cable()
1012 loopback->cables[substream->number][dev] = NULL; in free_cable()
1019 timer_setup(&dpcm->timer, loopback_jiffies_timer_function, 0); in loopback_jiffies_timer_open()
1054 if (err == -EINVAL) { in loopback_parse_timer_id()
1060 if (!strcmp(card->id, name)) in loopback_parse_timer_id()
1087 tid->card = card_idx; in loopback_parse_timer_id()
1088 tid->device = dev; in loopback_parse_timer_id()
1089 tid->subdevice = subdev; in loopback_parse_timer_id()
1094 /* call in loopback->cable_lock */
1103 struct loopback_cable *cable = dpcm->cable; in loopback_snd_timer_open()
1108 if (cable->snd_timer.instance) in loopback_snd_timer_open()
1111 err = loopback_parse_timer_id(dpcm->loopback->timer_source, &tid); in loopback_snd_timer_open()
1113 pcm_err(dpcm->substream->pcm, in loopback_snd_timer_open()
1115 dpcm->loopback->timer_source, err); in loopback_snd_timer_open()
1119 cable->snd_timer.stream = dpcm->substream->stream; in loopback_snd_timer_open()
1120 cable->snd_timer.id = tid; in loopback_snd_timer_open()
1122 timeri = snd_timer_instance_new(dpcm->loopback->card->id); in loopback_snd_timer_open()
1124 err = -ENOMEM; in loopback_snd_timer_open()
1135 timeri->flags |= SNDRV_TIMER_IFLG_AUTO; in loopback_snd_timer_open()
1136 timeri->callback = loopback_snd_timer_function; in loopback_snd_timer_open()
1137 timeri->callback_data = (void *)cable; in loopback_snd_timer_open()
1138 timeri->ccallback = loopback_snd_timer_event; in loopback_snd_timer_open()
1141 INIT_WORK(&cable->snd_timer.event_work, loopback_snd_timer_work); in loopback_snd_timer_open()
1143 /* The mutex loopback->cable_lock is kept locked. in loopback_snd_timer_open()
1147 * [proc1] Call loopback_timer_open() -> in loopback_snd_timer_open()
1148 * Unlock cable->lock for snd_timer_close/open() call in loopback_snd_timer_open()
1149 * [proc2] Call loopback_timer_open() -> snd_timer_open(), in loopback_snd_timer_open()
1154 err = snd_timer_open(timeri, &cable->snd_timer.id, current->pid); in loopback_snd_timer_open()
1156 pcm_err(dpcm->substream->pcm, in loopback_snd_timer_open()
1158 cable->snd_timer.id.card, in loopback_snd_timer_open()
1159 cable->snd_timer.id.device, in loopback_snd_timer_open()
1160 cable->snd_timer.id.subdevice, in loopback_snd_timer_open()
1166 cable->snd_timer.instance = timeri; in loopback_snd_timer_open()
1185 struct snd_pcm_runtime *runtime = substream->runtime; in loopback_open()
1186 struct loopback *loopback = substream->private_data; in loopback_open()
1192 mutex_lock(&loopback->cable_lock); in loopback_open()
1195 err = -ENOMEM; in loopback_open()
1198 dpcm->loopback = loopback; in loopback_open()
1199 dpcm->substream = substream; in loopback_open()
1201 cable = loopback->cables[substream->number][dev]; in loopback_open()
1205 err = -ENOMEM; in loopback_open()
1208 spin_lock_init(&cable->lock); in loopback_open()
1209 cable->hw = loopback_pcm_hardware; in loopback_open()
1210 if (loopback->timer_source) in loopback_open()
1211 cable->ops = &loopback_snd_timer_ops; in loopback_open()
1213 cable->ops = &loopback_jiffies_timer_ops; in loopback_open()
1214 loopback->cables[substream->number][dev] = cable; in loopback_open()
1216 dpcm->cable = cable; in loopback_open()
1217 runtime->private_data = dpcm; in loopback_open()
1219 if (cable->ops->open) { in loopback_open()
1220 err = cable->ops->open(dpcm); in loopback_open()
1227 /* use dynamic rules based on actual runtime->hw values */ in loopback_open()
1229 /* are cached -> they do not reflect the actual state */ in loopback_open()
1233 SNDRV_PCM_HW_PARAM_FORMAT, -1); in loopback_open()
1239 SNDRV_PCM_HW_PARAM_RATE, -1); in loopback_open()
1245 SNDRV_PCM_HW_PARAM_CHANNELS, -1); in loopback_open()
1253 if (cable->snd_timer.instance) { in loopback_open()
1257 SNDRV_PCM_HW_PARAM_PERIOD_BYTES, -1); in loopback_open()
1265 runtime->private_free = loopback_runtime_free; in loopback_open()
1267 runtime->hw = loopback_pcm_hardware; in loopback_open()
1269 runtime->hw = cable->hw; in loopback_open()
1271 spin_lock_irq(&cable->lock); in loopback_open()
1272 cable->streams[substream->stream] = dpcm; in loopback_open()
1273 spin_unlock_irq(&cable->lock); in loopback_open()
1280 mutex_unlock(&loopback->cable_lock); in loopback_open()
1286 struct loopback *loopback = substream->private_data; in loopback_close()
1287 struct loopback_pcm *dpcm = substream->runtime->private_data; in loopback_close()
1290 if (dpcm->cable->ops->close_substream) in loopback_close()
1291 err = dpcm->cable->ops->close_substream(dpcm); in loopback_close()
1292 mutex_lock(&loopback->cable_lock); in loopback_close()
1294 mutex_unlock(&loopback->cable_lock); in loopback_close()
1313 err = snd_pcm_new(loopback->card, "Loopback PCM", device, in loopback_pcm_new()
1321 pcm->private_data = loopback; in loopback_pcm_new()
1322 pcm->info_flags = 0; in loopback_pcm_new()
1323 strcpy(pcm->name, "Loopback PCM"); in loopback_pcm_new()
1325 loopback->pcm[device] = pcm; in loopback_pcm_new()
1332 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in loopback_rate_shift_info()
1333 uinfo->count = 1; in loopback_rate_shift_info()
1334 uinfo->value.integer.min = 80000; in loopback_rate_shift_info()
1335 uinfo->value.integer.max = 120000; in loopback_rate_shift_info()
1336 uinfo->value.integer.step = 1; in loopback_rate_shift_info()
1345 mutex_lock(&loopback->cable_lock); in loopback_rate_shift_get()
1346 ucontrol->value.integer.value[0] = in loopback_rate_shift_get()
1347 loopback->setup[kcontrol->id.subdevice] in loopback_rate_shift_get()
1348 [kcontrol->id.device].rate_shift; in loopback_rate_shift_get()
1349 mutex_unlock(&loopback->cable_lock); in loopback_rate_shift_get()
1360 val = ucontrol->value.integer.value[0]; in loopback_rate_shift_put()
1365 mutex_lock(&loopback->cable_lock); in loopback_rate_shift_put()
1366 if (val != loopback->setup[kcontrol->id.subdevice] in loopback_rate_shift_put()
1367 [kcontrol->id.device].rate_shift) { in loopback_rate_shift_put()
1368 loopback->setup[kcontrol->id.subdevice] in loopback_rate_shift_put()
1369 [kcontrol->id.device].rate_shift = val; in loopback_rate_shift_put()
1372 mutex_unlock(&loopback->cable_lock); in loopback_rate_shift_put()
1381 mutex_lock(&loopback->cable_lock); in loopback_notify_get()
1382 ucontrol->value.integer.value[0] = in loopback_notify_get()
1383 loopback->setup[kcontrol->id.subdevice] in loopback_notify_get()
1384 [kcontrol->id.device].notify; in loopback_notify_get()
1385 mutex_unlock(&loopback->cable_lock); in loopback_notify_get()
1396 val = ucontrol->value.integer.value[0] ? 1 : 0; in loopback_notify_put()
1397 mutex_lock(&loopback->cable_lock); in loopback_notify_put()
1398 if (val != loopback->setup[kcontrol->id.subdevice] in loopback_notify_put()
1399 [kcontrol->id.device].notify) { in loopback_notify_put()
1400 loopback->setup[kcontrol->id.subdevice] in loopback_notify_put()
1401 [kcontrol->id.device].notify = val; in loopback_notify_put()
1404 mutex_unlock(&loopback->cable_lock); in loopback_notify_put()
1416 mutex_lock(&loopback->cable_lock); in loopback_active_get()
1417 cable = loopback->cables[kcontrol->id.subdevice][kcontrol->id.device ^ 1]; in loopback_active_get()
1419 unsigned int running = cable->running ^ cable->pause; in loopback_active_get()
1423 mutex_unlock(&loopback->cable_lock); in loopback_active_get()
1424 ucontrol->value.integer.value[0] = val; in loopback_active_get()
1431 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in loopback_format_info()
1432 uinfo->count = 1; in loopback_format_info()
1433 uinfo->value.integer.min = 0; in loopback_format_info()
1434 uinfo->value.integer.max = (__force int)SNDRV_PCM_FORMAT_LAST; in loopback_format_info()
1435 uinfo->value.integer.step = 1; in loopback_format_info()
1444 ucontrol->value.integer.value[0] = in loopback_format_get()
1445 (__force int)loopback->setup[kcontrol->id.subdevice] in loopback_format_get()
1446 [kcontrol->id.device].format; in loopback_format_get()
1453 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in loopback_rate_info()
1454 uinfo->count = 1; in loopback_rate_info()
1455 uinfo->value.integer.min = 0; in loopback_rate_info()
1456 uinfo->value.integer.max = 192000; in loopback_rate_info()
1457 uinfo->value.integer.step = 1; in loopback_rate_info()
1466 mutex_lock(&loopback->cable_lock); in loopback_rate_get()
1467 ucontrol->value.integer.value[0] = in loopback_rate_get()
1468 loopback->setup[kcontrol->id.subdevice] in loopback_rate_get()
1469 [kcontrol->id.device].rate; in loopback_rate_get()
1470 mutex_unlock(&loopback->cable_lock); in loopback_rate_get()
1477 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in loopback_channels_info()
1478 uinfo->count = 1; in loopback_channels_info()
1479 uinfo->value.integer.min = 1; in loopback_channels_info()
1480 uinfo->value.integer.max = 1024; in loopback_channels_info()
1481 uinfo->value.integer.step = 1; in loopback_channels_info()
1490 mutex_lock(&loopback->cable_lock); in loopback_channels_get()
1491 ucontrol->value.integer.value[0] = in loopback_channels_get()
1492 loopback->setup[kcontrol->id.subdevice] in loopback_channels_get()
1493 [kcontrol->id.device].channels; in loopback_channels_get()
1494 mutex_unlock(&loopback->cable_lock); in loopback_channels_get()
1541 .name = "PCM Slave Channels",
1549 struct snd_card *card = loopback->card; in loopback_mixer_new()
1555 strcpy(card->mixername, "Loopback Mixer"); in loopback_mixer_new()
1557 pcm = loopback->pcm[dev]; in loopback_mixer_new()
1559 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count; in loopback_mixer_new()
1561 setup = &loopback->setup[substr][dev]; in loopback_mixer_new()
1562 setup->notify = notify; in loopback_mixer_new()
1563 setup->rate_shift = NO_PITCH; in loopback_mixer_new()
1564 setup->format = SNDRV_PCM_FORMAT_S16_LE; in loopback_mixer_new()
1565 setup->rate = 48000; in loopback_mixer_new()
1566 setup->channels = 2; in loopback_mixer_new()
1572 return -ENOMEM; in loopback_mixer_new()
1573 kctl->id.device = dev; in loopback_mixer_new()
1574 kctl->id.subdevice = substr; in loopback_mixer_new()
1585 setup->active_id = kctl->id; in loopback_mixer_new()
1588 setup->format_id = kctl->id; in loopback_mixer_new()
1591 setup->rate_id = kctl->id; in loopback_mixer_new()
1594 setup->channels_id = kctl->id; in loopback_mixer_new()
1614 snd_iprintf(buffer, " buffer_size:\t%u\n", dpcm->pcm_buffer_size); in print_dpcm_info()
1615 snd_iprintf(buffer, " buffer_pos:\t\t%u\n", dpcm->buf_pos); in print_dpcm_info()
1616 snd_iprintf(buffer, " silent_size:\t%u\n", dpcm->silent_size); in print_dpcm_info()
1617 snd_iprintf(buffer, " period_size:\t%u\n", dpcm->pcm_period_size); in print_dpcm_info()
1618 snd_iprintf(buffer, " bytes_per_sec:\t%u\n", dpcm->pcm_bps); in print_dpcm_info()
1619 snd_iprintf(buffer, " sample_align:\t%u\n", dpcm->pcm_salign); in print_dpcm_info()
1620 snd_iprintf(buffer, " rate_shift:\t\t%u\n", dpcm->pcm_rate_shift); in print_dpcm_info()
1621 if (dpcm->cable->ops->dpcm_info) in print_dpcm_info()
1622 dpcm->cable->ops->dpcm_info(dpcm, buffer); in print_dpcm_info()
1630 struct loopback_cable *cable = loopback->cables[sub][num]; in print_substream_info()
1637 snd_iprintf(buffer, " valid: %u\n", cable->valid); in print_substream_info()
1638 snd_iprintf(buffer, " running: %u\n", cable->running); in print_substream_info()
1639 snd_iprintf(buffer, " pause: %u\n", cable->pause); in print_substream_info()
1640 print_dpcm_info(buffer, cable->streams[0], "Playback"); in print_substream_info()
1641 print_dpcm_info(buffer, cable->streams[1], "Capture"); in print_substream_info()
1647 struct loopback *loopback = entry->private_data; in print_cable_info()
1650 mutex_lock(&loopback->cable_lock); in print_cable_info()
1651 num = entry->name[strlen(entry->name)-1]; in print_cable_info()
1655 mutex_unlock(&loopback->cable_lock); in print_cable_info()
1663 return snd_card_ro_proc_new(loopback->card, name, loopback, in loopback_cable_proc_new()
1670 if (loopback->timer_source) { in loopback_set_timer_source()
1671 devm_kfree(loopback->card->dev, loopback->timer_source); in loopback_set_timer_source()
1672 loopback->timer_source = NULL; in loopback_set_timer_source()
1675 loopback->timer_source = devm_kstrdup(loopback->card->dev, in loopback_set_timer_source()
1682 struct loopback *loopback = entry->private_data; in print_timer_source_info()
1684 mutex_lock(&loopback->cable_lock); in print_timer_source_info()
1686 loopback->timer_source ? loopback->timer_source : ""); in print_timer_source_info()
1687 mutex_unlock(&loopback->cable_lock); in print_timer_source_info()
1693 struct loopback *loopback = entry->private_data; in change_timer_source_info()
1696 mutex_lock(&loopback->cable_lock); in change_timer_source_info()
1699 mutex_unlock(&loopback->cable_lock); in change_timer_source_info()
1704 return snd_card_rw_proc_new(loopback->card, "timer_source", loopback, in loopback_timer_source_proc_new()
1713 int dev = devptr->id; in loopback_probe()
1716 err = snd_card_new(&devptr->dev, index[dev], id[dev], THIS_MODULE, in loopback_probe()
1720 loopback = card->private_data; in loopback_probe()
1727 loopback->card = card; in loopback_probe()
1730 mutex_init(&loopback->cable_lock); in loopback_probe()
1744 strcpy(card->driver, "Loopback"); in loopback_probe()
1745 strcpy(card->shortname, "Loopback"); in loopback_probe()
1746 sprintf(card->longname, "Loopback %i", dev + 1); in loopback_probe()
1836 return -ENODEV; in alsa_card_loopback_init()