Lines Matching refs:dice

32 int snd_dice_stream_get_rate_mode(struct snd_dice *dice, unsigned int rate,  in snd_dice_stream_get_rate_mode()  argument
48 if (!(dice->clock_caps & BIT(i))) in snd_dice_stream_get_rate_mode()
60 static int select_clock(struct snd_dice *dice, unsigned int rate) in select_clock() argument
67 err = snd_dice_transaction_read_global(dice, GLOBAL_CLOCK_SELECT, in select_clock()
83 if (completion_done(&dice->clock_accepted)) in select_clock()
84 reinit_completion(&dice->clock_accepted); in select_clock()
87 err = snd_dice_transaction_write_global(dice, GLOBAL_CLOCK_SELECT, in select_clock()
92 if (wait_for_completion_timeout(&dice->clock_accepted, in select_clock()
99 static int get_register_params(struct snd_dice *dice, in get_register_params() argument
106 err = snd_dice_transaction_read_tx(dice, TX_NUMBER, reg, sizeof(reg)); in get_register_params()
113 err = snd_dice_transaction_read_rx(dice, RX_NUMBER, reg, sizeof(reg)); in get_register_params()
123 static void release_resources(struct snd_dice *dice) in release_resources() argument
128 fw_iso_resources_free(&dice->tx_resources[i]); in release_resources()
129 fw_iso_resources_free(&dice->rx_resources[i]); in release_resources()
133 static void stop_streams(struct snd_dice *dice, enum amdtp_stream_direction dir, in stop_streams() argument
142 snd_dice_transaction_write_tx(dice, in stop_streams()
146 snd_dice_transaction_write_rx(dice, in stop_streams()
153 static int keep_resources(struct snd_dice *dice, struct amdtp_stream *stream, in keep_resources() argument
169 double_pcm_frames = (rate > 96000 && !dice->disable_double_pcm_frames); in keep_resources()
192 fw_parent_device(dice->unit)->max_speed); in keep_resources()
195 static int keep_dual_resources(struct snd_dice *dice, unsigned int rate, in keep_dual_resources() argument
203 err = snd_dice_stream_get_rate_mode(dice, rate, &mode); in keep_dual_resources()
216 stream = &dice->tx_stream[i]; in keep_dual_resources()
217 resources = &dice->tx_resources[i]; in keep_dual_resources()
219 pcm_cache = dice->tx_pcm_chs[i][mode]; in keep_dual_resources()
220 err = snd_dice_transaction_read_tx(dice, in keep_dual_resources()
224 stream = &dice->rx_stream[i]; in keep_dual_resources()
225 resources = &dice->rx_resources[i]; in keep_dual_resources()
227 pcm_cache = dice->rx_pcm_chs[i][mode]; in keep_dual_resources()
228 err = snd_dice_transaction_read_rx(dice, in keep_dual_resources()
239 dev_info(&dice->unit->device, in keep_dual_resources()
245 err = keep_resources(dice, stream, resources, rate, pcm_chs, in keep_dual_resources()
254 static void finish_session(struct snd_dice *dice, struct reg_params *tx_params, in finish_session() argument
257 stop_streams(dice, AMDTP_IN_STREAM, tx_params); in finish_session()
258 stop_streams(dice, AMDTP_OUT_STREAM, rx_params); in finish_session()
260 snd_dice_transaction_clear_enable(dice); in finish_session()
263 int snd_dice_stream_reserve_duplex(struct snd_dice *dice, unsigned int rate, in snd_dice_stream_reserve_duplex() argument
271 err = snd_dice_transaction_get_rate(dice, &curr_rate); in snd_dice_stream_reserve_duplex()
277 if (dice->substreams_counter == 0 || curr_rate != rate) { in snd_dice_stream_reserve_duplex()
280 amdtp_domain_stop(&dice->domain); in snd_dice_stream_reserve_duplex()
282 err = get_register_params(dice, &tx_params, &rx_params); in snd_dice_stream_reserve_duplex()
285 finish_session(dice, &tx_params, &rx_params); in snd_dice_stream_reserve_duplex()
287 release_resources(dice); in snd_dice_stream_reserve_duplex()
292 err = select_clock(dice, rate); in snd_dice_stream_reserve_duplex()
298 err = get_register_params(dice, &tx_params, &rx_params); in snd_dice_stream_reserve_duplex()
302 err = keep_dual_resources(dice, rate, AMDTP_IN_STREAM, in snd_dice_stream_reserve_duplex()
307 err = keep_dual_resources(dice, rate, AMDTP_OUT_STREAM, in snd_dice_stream_reserve_duplex()
312 err = amdtp_domain_set_events_per_period(&dice->domain, in snd_dice_stream_reserve_duplex()
320 release_resources(dice); in snd_dice_stream_reserve_duplex()
324 static int start_streams(struct snd_dice *dice, enum amdtp_stream_direction dir, in start_streams() argument
327 unsigned int max_speed = fw_parent_device(dice->unit)->max_speed; in start_streams()
337 stream = dice->tx_stream + i; in start_streams()
338 resources = dice->tx_resources + i; in start_streams()
340 stream = dice->rx_stream + i; in start_streams()
341 resources = dice->rx_resources + i; in start_streams()
346 err = snd_dice_transaction_write_tx(dice, in start_streams()
350 err = snd_dice_transaction_write_rx(dice, in start_streams()
359 err = snd_dice_transaction_write_tx(dice, in start_streams()
366 err = amdtp_domain_add_stream(&dice->domain, stream, in start_streams()
380 int snd_dice_stream_start_duplex(struct snd_dice *dice) in snd_dice_stream_start_duplex() argument
382 unsigned int generation = dice->rx_resources[0].generation; in snd_dice_stream_start_duplex()
389 if (dice->substreams_counter == 0) in snd_dice_stream_start_duplex()
392 err = get_register_params(dice, &tx_params, &rx_params); in snd_dice_stream_start_duplex()
398 if (amdtp_streaming_error(&dice->tx_stream[i]) || in snd_dice_stream_start_duplex()
399 amdtp_streaming_error(&dice->rx_stream[i])) { in snd_dice_stream_start_duplex()
400 amdtp_domain_stop(&dice->domain); in snd_dice_stream_start_duplex()
401 finish_session(dice, &tx_params, &rx_params); in snd_dice_stream_start_duplex()
406 if (generation != fw_parent_device(dice->unit)->card->generation) { in snd_dice_stream_start_duplex()
409 fw_iso_resources_update(dice->tx_resources + i); in snd_dice_stream_start_duplex()
411 fw_iso_resources_update(dice->rx_resources + i); in snd_dice_stream_start_duplex()
416 err = snd_dice_transaction_get_rate(dice, &rate); in snd_dice_stream_start_duplex()
419 err = snd_dice_stream_get_rate_mode(dice, rate, &mode); in snd_dice_stream_start_duplex()
423 if (dice->tx_pcm_chs[i][mode] > 0 && in snd_dice_stream_start_duplex()
424 !amdtp_stream_running(&dice->tx_stream[i])) in snd_dice_stream_start_duplex()
426 if (dice->rx_pcm_chs[i][mode] > 0 && in snd_dice_stream_start_duplex()
427 !amdtp_stream_running(&dice->rx_stream[i])) in snd_dice_stream_start_duplex()
432 err = start_streams(dice, AMDTP_IN_STREAM, rate, &tx_params); in snd_dice_stream_start_duplex()
436 err = start_streams(dice, AMDTP_OUT_STREAM, rate, &rx_params); in snd_dice_stream_start_duplex()
440 err = snd_dice_transaction_set_enable(dice); in snd_dice_stream_start_duplex()
442 dev_err(&dice->unit->device, in snd_dice_stream_start_duplex()
451 err = amdtp_domain_start(&dice->domain, 0, true, false); in snd_dice_stream_start_duplex()
455 if (!amdtp_domain_wait_ready(&dice->domain, READY_TIMEOUT_MS)) { in snd_dice_stream_start_duplex()
463 amdtp_domain_stop(&dice->domain); in snd_dice_stream_start_duplex()
464 finish_session(dice, &tx_params, &rx_params); in snd_dice_stream_start_duplex()
473 void snd_dice_stream_stop_duplex(struct snd_dice *dice) in snd_dice_stream_stop_duplex() argument
477 if (dice->substreams_counter == 0) { in snd_dice_stream_stop_duplex()
478 if (get_register_params(dice, &tx_params, &rx_params) >= 0) in snd_dice_stream_stop_duplex()
479 finish_session(dice, &tx_params, &rx_params); in snd_dice_stream_stop_duplex()
481 amdtp_domain_stop(&dice->domain); in snd_dice_stream_stop_duplex()
482 release_resources(dice); in snd_dice_stream_stop_duplex()
486 static int init_stream(struct snd_dice *dice, enum amdtp_stream_direction dir, in init_stream() argument
494 stream = &dice->tx_stream[index]; in init_stream()
495 resources = &dice->tx_resources[index]; in init_stream()
497 stream = &dice->rx_stream[index]; in init_stream()
498 resources = &dice->rx_resources[index]; in init_stream()
501 err = fw_iso_resources_init(resources, dice->unit); in init_stream()
506 err = amdtp_am824_init(stream, dice->unit, dir, CIP_BLOCKING); in init_stream()
519 static void destroy_stream(struct snd_dice *dice, in destroy_stream() argument
527 stream = &dice->tx_stream[index]; in destroy_stream()
528 resources = &dice->tx_resources[index]; in destroy_stream()
530 stream = &dice->rx_stream[index]; in destroy_stream()
531 resources = &dice->rx_resources[index]; in destroy_stream()
538 int snd_dice_stream_init_duplex(struct snd_dice *dice) in snd_dice_stream_init_duplex() argument
543 err = init_stream(dice, AMDTP_IN_STREAM, i); in snd_dice_stream_init_duplex()
546 destroy_stream(dice, AMDTP_IN_STREAM, i); in snd_dice_stream_init_duplex()
552 err = init_stream(dice, AMDTP_OUT_STREAM, i); in snd_dice_stream_init_duplex()
555 destroy_stream(dice, AMDTP_OUT_STREAM, i); in snd_dice_stream_init_duplex()
557 destroy_stream(dice, AMDTP_IN_STREAM, i); in snd_dice_stream_init_duplex()
562 err = amdtp_domain_init(&dice->domain); in snd_dice_stream_init_duplex()
565 destroy_stream(dice, AMDTP_OUT_STREAM, i); in snd_dice_stream_init_duplex()
566 destroy_stream(dice, AMDTP_IN_STREAM, i); in snd_dice_stream_init_duplex()
573 void snd_dice_stream_destroy_duplex(struct snd_dice *dice) in snd_dice_stream_destroy_duplex() argument
578 destroy_stream(dice, AMDTP_IN_STREAM, i); in snd_dice_stream_destroy_duplex()
579 destroy_stream(dice, AMDTP_OUT_STREAM, i); in snd_dice_stream_destroy_duplex()
582 amdtp_domain_destroy(&dice->domain); in snd_dice_stream_destroy_duplex()
585 void snd_dice_stream_update_duplex(struct snd_dice *dice) in snd_dice_stream_update_duplex() argument
597 dice->global_enabled = false; in snd_dice_stream_update_duplex()
599 if (get_register_params(dice, &tx_params, &rx_params) == 0) { in snd_dice_stream_update_duplex()
600 amdtp_domain_stop(&dice->domain); in snd_dice_stream_update_duplex()
602 stop_streams(dice, AMDTP_IN_STREAM, &tx_params); in snd_dice_stream_update_duplex()
603 stop_streams(dice, AMDTP_OUT_STREAM, &rx_params); in snd_dice_stream_update_duplex()
607 int snd_dice_stream_detect_current_formats(struct snd_dice *dice) in snd_dice_stream_detect_current_formats() argument
617 err = snd_dice_detect_extension_formats(dice); in snd_dice_stream_detect_current_formats()
625 err = snd_dice_transaction_get_rate(dice, &rate); in snd_dice_stream_detect_current_formats()
629 err = snd_dice_stream_get_rate_mode(dice, rate, &mode); in snd_dice_stream_detect_current_formats()
638 err = select_clock(dice, rate); in snd_dice_stream_detect_current_formats()
642 err = get_register_params(dice, &tx_params, &rx_params); in snd_dice_stream_detect_current_formats()
647 err = snd_dice_transaction_read_tx(dice, in snd_dice_stream_detect_current_formats()
652 dice->tx_pcm_chs[i][mode] = be32_to_cpu(reg[0]); in snd_dice_stream_detect_current_formats()
653 dice->tx_midi_ports[i] = max_t(unsigned int, in snd_dice_stream_detect_current_formats()
654 be32_to_cpu(reg[1]), dice->tx_midi_ports[i]); in snd_dice_stream_detect_current_formats()
657 err = snd_dice_transaction_read_rx(dice, in snd_dice_stream_detect_current_formats()
662 dice->rx_pcm_chs[i][mode] = be32_to_cpu(reg[0]); in snd_dice_stream_detect_current_formats()
663 dice->rx_midi_ports[i] = max_t(unsigned int, in snd_dice_stream_detect_current_formats()
664 be32_to_cpu(reg[1]), dice->rx_midi_ports[i]); in snd_dice_stream_detect_current_formats()
670 static void dice_lock_changed(struct snd_dice *dice) in dice_lock_changed() argument
672 dice->dev_lock_changed = true; in dice_lock_changed()
673 wake_up(&dice->hwdep_wait); in dice_lock_changed()
676 int snd_dice_stream_lock_try(struct snd_dice *dice) in snd_dice_stream_lock_try() argument
680 spin_lock_irq(&dice->lock); in snd_dice_stream_lock_try()
682 if (dice->dev_lock_count < 0) { in snd_dice_stream_lock_try()
687 if (dice->dev_lock_count++ == 0) in snd_dice_stream_lock_try()
688 dice_lock_changed(dice); in snd_dice_stream_lock_try()
691 spin_unlock_irq(&dice->lock); in snd_dice_stream_lock_try()
695 void snd_dice_stream_lock_release(struct snd_dice *dice) in snd_dice_stream_lock_release() argument
697 spin_lock_irq(&dice->lock); in snd_dice_stream_lock_release()
699 if (WARN_ON(dice->dev_lock_count <= 0)) in snd_dice_stream_lock_release()
702 if (--dice->dev_lock_count == 0) in snd_dice_stream_lock_release()
703 dice_lock_changed(dice); in snd_dice_stream_lock_release()
705 spin_unlock_irq(&dice->lock); in snd_dice_stream_lock_release()