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()
101 static int get_register_params(struct snd_dice *dice, in get_register_params() argument
108 err = snd_dice_transaction_read_tx(dice, TX_NUMBER, reg, sizeof(reg)); in get_register_params()
115 err = snd_dice_transaction_read_rx(dice, RX_NUMBER, reg, sizeof(reg)); in get_register_params()
125 static void release_resources(struct snd_dice *dice) in release_resources() argument
130 fw_iso_resources_free(&dice->tx_resources[i]); in release_resources()
131 fw_iso_resources_free(&dice->rx_resources[i]); in release_resources()
135 static void stop_streams(struct snd_dice *dice, enum amdtp_stream_direction dir, in stop_streams() argument
144 snd_dice_transaction_write_tx(dice, in stop_streams()
148 snd_dice_transaction_write_rx(dice, in stop_streams()
155 static int keep_resources(struct snd_dice *dice, struct amdtp_stream *stream, in keep_resources() argument
171 double_pcm_frames = (rate > 96000 && !dice->disable_double_pcm_frames); in keep_resources()
194 fw_parent_device(dice->unit)->max_speed); in keep_resources()
197 static int keep_dual_resources(struct snd_dice *dice, unsigned int rate, in keep_dual_resources() argument
205 err = snd_dice_stream_get_rate_mode(dice, rate, &mode); in keep_dual_resources()
218 stream = &dice->tx_stream[i]; in keep_dual_resources()
219 resources = &dice->tx_resources[i]; in keep_dual_resources()
221 pcm_cache = dice->tx_pcm_chs[i][mode]; in keep_dual_resources()
222 err = snd_dice_transaction_read_tx(dice, in keep_dual_resources()
226 stream = &dice->rx_stream[i]; in keep_dual_resources()
227 resources = &dice->rx_resources[i]; in keep_dual_resources()
229 pcm_cache = dice->rx_pcm_chs[i][mode]; in keep_dual_resources()
230 err = snd_dice_transaction_read_rx(dice, in keep_dual_resources()
241 dev_info(&dice->unit->device, in keep_dual_resources()
247 err = keep_resources(dice, stream, resources, rate, pcm_chs, in keep_dual_resources()
256 static void finish_session(struct snd_dice *dice, struct reg_params *tx_params, in finish_session() argument
259 stop_streams(dice, AMDTP_IN_STREAM, tx_params); in finish_session()
260 stop_streams(dice, AMDTP_OUT_STREAM, rx_params); in finish_session()
262 snd_dice_transaction_clear_enable(dice); in finish_session()
265 int snd_dice_stream_reserve_duplex(struct snd_dice *dice, unsigned int rate, in snd_dice_stream_reserve_duplex() argument
273 err = snd_dice_transaction_get_rate(dice, &curr_rate); in snd_dice_stream_reserve_duplex()
279 if (dice->substreams_counter == 0 || curr_rate != rate) { in snd_dice_stream_reserve_duplex()
282 amdtp_domain_stop(&dice->domain); in snd_dice_stream_reserve_duplex()
284 err = get_register_params(dice, &tx_params, &rx_params); in snd_dice_stream_reserve_duplex()
287 finish_session(dice, &tx_params, &rx_params); in snd_dice_stream_reserve_duplex()
289 release_resources(dice); in snd_dice_stream_reserve_duplex()
294 err = select_clock(dice, rate); in snd_dice_stream_reserve_duplex()
300 err = get_register_params(dice, &tx_params, &rx_params); in snd_dice_stream_reserve_duplex()
304 err = keep_dual_resources(dice, rate, AMDTP_IN_STREAM, in snd_dice_stream_reserve_duplex()
309 err = keep_dual_resources(dice, rate, AMDTP_OUT_STREAM, in snd_dice_stream_reserve_duplex()
314 err = amdtp_domain_set_events_per_period(&dice->domain, in snd_dice_stream_reserve_duplex()
322 release_resources(dice); in snd_dice_stream_reserve_duplex()
326 static int start_streams(struct snd_dice *dice, enum amdtp_stream_direction dir, in start_streams() argument
329 unsigned int max_speed = fw_parent_device(dice->unit)->max_speed; in start_streams()
339 stream = dice->tx_stream + i; in start_streams()
340 resources = dice->tx_resources + i; in start_streams()
342 stream = dice->rx_stream + i; in start_streams()
343 resources = dice->rx_resources + i; in start_streams()
348 err = snd_dice_transaction_write_tx(dice, in start_streams()
352 err = snd_dice_transaction_write_rx(dice, in start_streams()
361 err = snd_dice_transaction_write_tx(dice, in start_streams()
368 err = amdtp_domain_add_stream(&dice->domain, stream, in start_streams()
382 int snd_dice_stream_start_duplex(struct snd_dice *dice) in snd_dice_stream_start_duplex() argument
384 unsigned int generation = dice->rx_resources[0].generation; in snd_dice_stream_start_duplex()
391 if (dice->substreams_counter == 0) in snd_dice_stream_start_duplex()
394 err = get_register_params(dice, &tx_params, &rx_params); in snd_dice_stream_start_duplex()
400 if (amdtp_streaming_error(&dice->tx_stream[i]) || in snd_dice_stream_start_duplex()
401 amdtp_streaming_error(&dice->rx_stream[i])) { in snd_dice_stream_start_duplex()
402 amdtp_domain_stop(&dice->domain); in snd_dice_stream_start_duplex()
403 finish_session(dice, &tx_params, &rx_params); in snd_dice_stream_start_duplex()
408 if (generation != fw_parent_device(dice->unit)->card->generation) { in snd_dice_stream_start_duplex()
411 fw_iso_resources_update(dice->tx_resources + i); in snd_dice_stream_start_duplex()
413 fw_iso_resources_update(dice->rx_resources + i); in snd_dice_stream_start_duplex()
418 err = snd_dice_transaction_get_rate(dice, &rate); in snd_dice_stream_start_duplex()
421 err = snd_dice_stream_get_rate_mode(dice, rate, &mode); in snd_dice_stream_start_duplex()
425 if (dice->tx_pcm_chs[i][mode] > 0 && in snd_dice_stream_start_duplex()
426 !amdtp_stream_running(&dice->tx_stream[i])) in snd_dice_stream_start_duplex()
428 if (dice->rx_pcm_chs[i][mode] > 0 && in snd_dice_stream_start_duplex()
429 !amdtp_stream_running(&dice->rx_stream[i])) in snd_dice_stream_start_duplex()
434 err = start_streams(dice, AMDTP_IN_STREAM, rate, &tx_params); in snd_dice_stream_start_duplex()
438 err = start_streams(dice, AMDTP_OUT_STREAM, rate, &rx_params); in snd_dice_stream_start_duplex()
442 err = snd_dice_transaction_set_enable(dice); in snd_dice_stream_start_duplex()
444 dev_err(&dice->unit->device, in snd_dice_stream_start_duplex()
453 err = amdtp_domain_start(&dice->domain, 0, true, false); in snd_dice_stream_start_duplex()
457 if (!amdtp_domain_wait_ready(&dice->domain, READY_TIMEOUT_MS)) { in snd_dice_stream_start_duplex()
465 amdtp_domain_stop(&dice->domain); in snd_dice_stream_start_duplex()
466 finish_session(dice, &tx_params, &rx_params); in snd_dice_stream_start_duplex()
475 void snd_dice_stream_stop_duplex(struct snd_dice *dice) in snd_dice_stream_stop_duplex() argument
479 if (dice->substreams_counter == 0) { in snd_dice_stream_stop_duplex()
480 if (get_register_params(dice, &tx_params, &rx_params) >= 0) in snd_dice_stream_stop_duplex()
481 finish_session(dice, &tx_params, &rx_params); in snd_dice_stream_stop_duplex()
483 amdtp_domain_stop(&dice->domain); in snd_dice_stream_stop_duplex()
484 release_resources(dice); in snd_dice_stream_stop_duplex()
488 static int init_stream(struct snd_dice *dice, enum amdtp_stream_direction dir, in init_stream() argument
496 stream = &dice->tx_stream[index]; in init_stream()
497 resources = &dice->tx_resources[index]; in init_stream()
499 stream = &dice->rx_stream[index]; in init_stream()
500 resources = &dice->rx_resources[index]; in init_stream()
503 err = fw_iso_resources_init(resources, dice->unit); in init_stream()
508 err = amdtp_am824_init(stream, dice->unit, dir, CIP_BLOCKING); in init_stream()
521 static void destroy_stream(struct snd_dice *dice, in destroy_stream() argument
529 stream = &dice->tx_stream[index]; in destroy_stream()
530 resources = &dice->tx_resources[index]; in destroy_stream()
532 stream = &dice->rx_stream[index]; in destroy_stream()
533 resources = &dice->rx_resources[index]; in destroy_stream()
540 int snd_dice_stream_init_duplex(struct snd_dice *dice) in snd_dice_stream_init_duplex() argument
545 err = init_stream(dice, AMDTP_IN_STREAM, i); in snd_dice_stream_init_duplex()
548 destroy_stream(dice, AMDTP_IN_STREAM, i); in snd_dice_stream_init_duplex()
554 err = init_stream(dice, AMDTP_OUT_STREAM, i); in snd_dice_stream_init_duplex()
557 destroy_stream(dice, AMDTP_OUT_STREAM, i); in snd_dice_stream_init_duplex()
559 destroy_stream(dice, AMDTP_IN_STREAM, i); in snd_dice_stream_init_duplex()
564 err = amdtp_domain_init(&dice->domain); in snd_dice_stream_init_duplex()
567 destroy_stream(dice, AMDTP_OUT_STREAM, i); in snd_dice_stream_init_duplex()
568 destroy_stream(dice, AMDTP_IN_STREAM, i); in snd_dice_stream_init_duplex()
575 void snd_dice_stream_destroy_duplex(struct snd_dice *dice) in snd_dice_stream_destroy_duplex() argument
580 destroy_stream(dice, AMDTP_IN_STREAM, i); in snd_dice_stream_destroy_duplex()
581 destroy_stream(dice, AMDTP_OUT_STREAM, i); in snd_dice_stream_destroy_duplex()
584 amdtp_domain_destroy(&dice->domain); in snd_dice_stream_destroy_duplex()
587 void snd_dice_stream_update_duplex(struct snd_dice *dice) in snd_dice_stream_update_duplex() argument
599 dice->global_enabled = false; in snd_dice_stream_update_duplex()
601 if (get_register_params(dice, &tx_params, &rx_params) == 0) { in snd_dice_stream_update_duplex()
602 amdtp_domain_stop(&dice->domain); in snd_dice_stream_update_duplex()
604 stop_streams(dice, AMDTP_IN_STREAM, &tx_params); in snd_dice_stream_update_duplex()
605 stop_streams(dice, AMDTP_OUT_STREAM, &rx_params); in snd_dice_stream_update_duplex()
609 int snd_dice_stream_detect_current_formats(struct snd_dice *dice) in snd_dice_stream_detect_current_formats() argument
619 err = snd_dice_detect_extension_formats(dice); in snd_dice_stream_detect_current_formats()
627 err = snd_dice_transaction_get_rate(dice, &rate); in snd_dice_stream_detect_current_formats()
631 err = snd_dice_stream_get_rate_mode(dice, rate, &mode); in snd_dice_stream_detect_current_formats()
640 err = select_clock(dice, rate); in snd_dice_stream_detect_current_formats()
644 err = get_register_params(dice, &tx_params, &rx_params); in snd_dice_stream_detect_current_formats()
649 err = snd_dice_transaction_read_tx(dice, in snd_dice_stream_detect_current_formats()
654 dice->tx_pcm_chs[i][mode] = be32_to_cpu(reg[0]); in snd_dice_stream_detect_current_formats()
655 dice->tx_midi_ports[i] = max_t(unsigned int, in snd_dice_stream_detect_current_formats()
656 be32_to_cpu(reg[1]), dice->tx_midi_ports[i]); in snd_dice_stream_detect_current_formats()
659 err = snd_dice_transaction_read_rx(dice, in snd_dice_stream_detect_current_formats()
664 dice->rx_pcm_chs[i][mode] = be32_to_cpu(reg[0]); in snd_dice_stream_detect_current_formats()
665 dice->rx_midi_ports[i] = max_t(unsigned int, in snd_dice_stream_detect_current_formats()
666 be32_to_cpu(reg[1]), dice->rx_midi_ports[i]); in snd_dice_stream_detect_current_formats()
672 static void dice_lock_changed(struct snd_dice *dice) in dice_lock_changed() argument
674 dice->dev_lock_changed = true; in dice_lock_changed()
675 wake_up(&dice->hwdep_wait); in dice_lock_changed()
678 int snd_dice_stream_lock_try(struct snd_dice *dice) in snd_dice_stream_lock_try() argument
682 spin_lock_irq(&dice->lock); in snd_dice_stream_lock_try()
684 if (dice->dev_lock_count < 0) { in snd_dice_stream_lock_try()
689 if (dice->dev_lock_count++ == 0) in snd_dice_stream_lock_try()
690 dice_lock_changed(dice); in snd_dice_stream_lock_try()
693 spin_unlock_irq(&dice->lock); in snd_dice_stream_lock_try()
697 void snd_dice_stream_lock_release(struct snd_dice *dice) in snd_dice_stream_lock_release() argument
699 spin_lock_irq(&dice->lock); in snd_dice_stream_lock_release()
701 if (WARN_ON(dice->dev_lock_count <= 0)) in snd_dice_stream_lock_release()
704 if (--dice->dev_lock_count == 0) in snd_dice_stream_lock_release()
705 dice_lock_changed(dice); in snd_dice_stream_lock_release()
707 spin_unlock_irq(&dice->lock); in snd_dice_stream_lock_release()