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()
64 static int ensure_phase_lock(struct snd_dice *dice, unsigned int rate) in ensure_phase_lock() argument
71 err = snd_dice_transaction_read_global(dice, GLOBAL_CLOCK_SELECT, in ensure_phase_lock()
87 if (completion_done(&dice->clock_accepted)) in ensure_phase_lock()
88 reinit_completion(&dice->clock_accepted); in ensure_phase_lock()
91 err = snd_dice_transaction_write_global(dice, GLOBAL_CLOCK_SELECT, in ensure_phase_lock()
96 if (wait_for_completion_timeout(&dice->clock_accepted, in ensure_phase_lock()
103 err = snd_dice_transaction_read_global(dice, GLOBAL_STATUS, in ensure_phase_lock()
114 static int get_register_params(struct snd_dice *dice, in get_register_params() argument
121 err = snd_dice_transaction_read_tx(dice, TX_NUMBER, reg, sizeof(reg)); in get_register_params()
128 err = snd_dice_transaction_read_rx(dice, RX_NUMBER, reg, sizeof(reg)); in get_register_params()
138 static void release_resources(struct snd_dice *dice) in release_resources() argument
143 fw_iso_resources_free(&dice->tx_resources[i]); in release_resources()
144 fw_iso_resources_free(&dice->rx_resources[i]); in release_resources()
148 static void stop_streams(struct snd_dice *dice, enum amdtp_stream_direction dir, in stop_streams() argument
157 snd_dice_transaction_write_tx(dice, in stop_streams()
161 snd_dice_transaction_write_rx(dice, in stop_streams()
168 static int keep_resources(struct snd_dice *dice, struct amdtp_stream *stream, in keep_resources() argument
207 fw_parent_device(dice->unit)->max_speed); in keep_resources()
210 static int keep_dual_resources(struct snd_dice *dice, unsigned int rate, in keep_dual_resources() argument
218 err = snd_dice_stream_get_rate_mode(dice, rate, &mode); in keep_dual_resources()
231 stream = &dice->tx_stream[i]; in keep_dual_resources()
232 resources = &dice->tx_resources[i]; in keep_dual_resources()
234 pcm_cache = dice->tx_pcm_chs[i][mode]; in keep_dual_resources()
235 err = snd_dice_transaction_read_tx(dice, in keep_dual_resources()
239 stream = &dice->rx_stream[i]; in keep_dual_resources()
240 resources = &dice->rx_resources[i]; in keep_dual_resources()
242 pcm_cache = dice->rx_pcm_chs[i][mode]; in keep_dual_resources()
243 err = snd_dice_transaction_read_rx(dice, in keep_dual_resources()
254 dev_info(&dice->unit->device, in keep_dual_resources()
260 err = keep_resources(dice, stream, resources, rate, pcm_chs, in keep_dual_resources()
269 static void finish_session(struct snd_dice *dice, struct reg_params *tx_params, in finish_session() argument
272 stop_streams(dice, AMDTP_IN_STREAM, tx_params); in finish_session()
273 stop_streams(dice, AMDTP_OUT_STREAM, rx_params); in finish_session()
275 snd_dice_transaction_clear_enable(dice); in finish_session()
278 int snd_dice_stream_reserve_duplex(struct snd_dice *dice, unsigned int rate, in snd_dice_stream_reserve_duplex() argument
286 err = snd_dice_transaction_get_rate(dice, &curr_rate); in snd_dice_stream_reserve_duplex()
292 if (dice->substreams_counter == 0 || curr_rate != rate) { in snd_dice_stream_reserve_duplex()
295 amdtp_domain_stop(&dice->domain); in snd_dice_stream_reserve_duplex()
297 err = get_register_params(dice, &tx_params, &rx_params); in snd_dice_stream_reserve_duplex()
300 finish_session(dice, &tx_params, &rx_params); in snd_dice_stream_reserve_duplex()
302 release_resources(dice); in snd_dice_stream_reserve_duplex()
307 err = ensure_phase_lock(dice, rate); in snd_dice_stream_reserve_duplex()
313 err = get_register_params(dice, &tx_params, &rx_params); in snd_dice_stream_reserve_duplex()
317 err = keep_dual_resources(dice, rate, AMDTP_IN_STREAM, in snd_dice_stream_reserve_duplex()
322 err = keep_dual_resources(dice, rate, AMDTP_OUT_STREAM, in snd_dice_stream_reserve_duplex()
327 err = amdtp_domain_set_events_per_period(&dice->domain, in snd_dice_stream_reserve_duplex()
335 release_resources(dice); in snd_dice_stream_reserve_duplex()
339 static int start_streams(struct snd_dice *dice, enum amdtp_stream_direction dir, in start_streams() argument
342 unsigned int max_speed = fw_parent_device(dice->unit)->max_speed; in start_streams()
352 stream = dice->tx_stream + i; in start_streams()
353 resources = dice->tx_resources + i; in start_streams()
355 stream = dice->rx_stream + i; in start_streams()
356 resources = dice->rx_resources + i; in start_streams()
361 err = snd_dice_transaction_write_tx(dice, in start_streams()
365 err = snd_dice_transaction_write_rx(dice, in start_streams()
374 err = snd_dice_transaction_write_tx(dice, in start_streams()
381 err = amdtp_domain_add_stream(&dice->domain, stream, in start_streams()
395 int snd_dice_stream_start_duplex(struct snd_dice *dice) in snd_dice_stream_start_duplex() argument
397 unsigned int generation = dice->rx_resources[0].generation; in snd_dice_stream_start_duplex()
404 if (dice->substreams_counter == 0) in snd_dice_stream_start_duplex()
407 err = get_register_params(dice, &tx_params, &rx_params); in snd_dice_stream_start_duplex()
413 if (amdtp_streaming_error(&dice->tx_stream[i]) || in snd_dice_stream_start_duplex()
414 amdtp_streaming_error(&dice->rx_stream[i])) { in snd_dice_stream_start_duplex()
415 amdtp_domain_stop(&dice->domain); in snd_dice_stream_start_duplex()
416 finish_session(dice, &tx_params, &rx_params); in snd_dice_stream_start_duplex()
421 if (generation != fw_parent_device(dice->unit)->card->generation) { in snd_dice_stream_start_duplex()
424 fw_iso_resources_update(dice->tx_resources + i); in snd_dice_stream_start_duplex()
426 fw_iso_resources_update(dice->rx_resources + i); in snd_dice_stream_start_duplex()
431 err = snd_dice_transaction_get_rate(dice, &rate); in snd_dice_stream_start_duplex()
434 err = snd_dice_stream_get_rate_mode(dice, rate, &mode); in snd_dice_stream_start_duplex()
438 if (dice->tx_pcm_chs[i][mode] > 0 && in snd_dice_stream_start_duplex()
439 !amdtp_stream_running(&dice->tx_stream[i])) in snd_dice_stream_start_duplex()
441 if (dice->rx_pcm_chs[i][mode] > 0 && in snd_dice_stream_start_duplex()
442 !amdtp_stream_running(&dice->rx_stream[i])) in snd_dice_stream_start_duplex()
447 err = start_streams(dice, AMDTP_IN_STREAM, rate, &tx_params); in snd_dice_stream_start_duplex()
451 err = start_streams(dice, AMDTP_OUT_STREAM, rate, &rx_params); in snd_dice_stream_start_duplex()
455 err = snd_dice_transaction_set_enable(dice); in snd_dice_stream_start_duplex()
457 dev_err(&dice->unit->device, in snd_dice_stream_start_duplex()
462 err = amdtp_domain_start(&dice->domain, 0); in snd_dice_stream_start_duplex()
468 !amdtp_stream_wait_callback(&dice->tx_stream[i], in snd_dice_stream_start_duplex()
471 !amdtp_stream_wait_callback(&dice->rx_stream[i], in snd_dice_stream_start_duplex()
481 amdtp_domain_stop(&dice->domain); in snd_dice_stream_start_duplex()
482 finish_session(dice, &tx_params, &rx_params); in snd_dice_stream_start_duplex()
491 void snd_dice_stream_stop_duplex(struct snd_dice *dice) in snd_dice_stream_stop_duplex() argument
495 if (dice->substreams_counter == 0) { in snd_dice_stream_stop_duplex()
496 if (get_register_params(dice, &tx_params, &rx_params) >= 0) in snd_dice_stream_stop_duplex()
497 finish_session(dice, &tx_params, &rx_params); in snd_dice_stream_stop_duplex()
499 amdtp_domain_stop(&dice->domain); in snd_dice_stream_stop_duplex()
500 release_resources(dice); in snd_dice_stream_stop_duplex()
504 static int init_stream(struct snd_dice *dice, enum amdtp_stream_direction dir, in init_stream() argument
512 stream = &dice->tx_stream[index]; in init_stream()
513 resources = &dice->tx_resources[index]; in init_stream()
515 stream = &dice->rx_stream[index]; in init_stream()
516 resources = &dice->rx_resources[index]; in init_stream()
519 err = fw_iso_resources_init(resources, dice->unit); in init_stream()
524 err = amdtp_am824_init(stream, dice->unit, dir, CIP_BLOCKING); in init_stream()
537 static void destroy_stream(struct snd_dice *dice, in destroy_stream() argument
545 stream = &dice->tx_stream[index]; in destroy_stream()
546 resources = &dice->tx_resources[index]; in destroy_stream()
548 stream = &dice->rx_stream[index]; in destroy_stream()
549 resources = &dice->rx_resources[index]; in destroy_stream()
556 int snd_dice_stream_init_duplex(struct snd_dice *dice) in snd_dice_stream_init_duplex() argument
561 err = init_stream(dice, AMDTP_IN_STREAM, i); in snd_dice_stream_init_duplex()
564 destroy_stream(dice, AMDTP_IN_STREAM, i); in snd_dice_stream_init_duplex()
570 err = init_stream(dice, AMDTP_OUT_STREAM, i); in snd_dice_stream_init_duplex()
573 destroy_stream(dice, AMDTP_OUT_STREAM, i); in snd_dice_stream_init_duplex()
575 destroy_stream(dice, AMDTP_IN_STREAM, i); in snd_dice_stream_init_duplex()
580 err = amdtp_domain_init(&dice->domain); in snd_dice_stream_init_duplex()
583 destroy_stream(dice, AMDTP_OUT_STREAM, i); in snd_dice_stream_init_duplex()
584 destroy_stream(dice, AMDTP_IN_STREAM, i); in snd_dice_stream_init_duplex()
591 void snd_dice_stream_destroy_duplex(struct snd_dice *dice) in snd_dice_stream_destroy_duplex() argument
596 destroy_stream(dice, AMDTP_IN_STREAM, i); in snd_dice_stream_destroy_duplex()
597 destroy_stream(dice, AMDTP_OUT_STREAM, i); in snd_dice_stream_destroy_duplex()
600 amdtp_domain_destroy(&dice->domain); in snd_dice_stream_destroy_duplex()
603 void snd_dice_stream_update_duplex(struct snd_dice *dice) in snd_dice_stream_update_duplex() argument
615 dice->global_enabled = false; in snd_dice_stream_update_duplex()
617 if (get_register_params(dice, &tx_params, &rx_params) == 0) { in snd_dice_stream_update_duplex()
618 amdtp_domain_stop(&dice->domain); in snd_dice_stream_update_duplex()
620 stop_streams(dice, AMDTP_IN_STREAM, &tx_params); in snd_dice_stream_update_duplex()
621 stop_streams(dice, AMDTP_OUT_STREAM, &rx_params); in snd_dice_stream_update_duplex()
625 int snd_dice_stream_detect_current_formats(struct snd_dice *dice) in snd_dice_stream_detect_current_formats() argument
635 err = snd_dice_detect_extension_formats(dice); in snd_dice_stream_detect_current_formats()
643 err = snd_dice_transaction_get_rate(dice, &rate); in snd_dice_stream_detect_current_formats()
647 err = snd_dice_stream_get_rate_mode(dice, rate, &mode); in snd_dice_stream_detect_current_formats()
656 err = ensure_phase_lock(dice, rate); in snd_dice_stream_detect_current_formats()
660 err = get_register_params(dice, &tx_params, &rx_params); in snd_dice_stream_detect_current_formats()
665 err = snd_dice_transaction_read_tx(dice, in snd_dice_stream_detect_current_formats()
670 dice->tx_pcm_chs[i][mode] = be32_to_cpu(reg[0]); in snd_dice_stream_detect_current_formats()
671 dice->tx_midi_ports[i] = max_t(unsigned int, in snd_dice_stream_detect_current_formats()
672 be32_to_cpu(reg[1]), dice->tx_midi_ports[i]); in snd_dice_stream_detect_current_formats()
675 err = snd_dice_transaction_read_rx(dice, in snd_dice_stream_detect_current_formats()
680 dice->rx_pcm_chs[i][mode] = be32_to_cpu(reg[0]); in snd_dice_stream_detect_current_formats()
681 dice->rx_midi_ports[i] = max_t(unsigned int, in snd_dice_stream_detect_current_formats()
682 be32_to_cpu(reg[1]), dice->rx_midi_ports[i]); in snd_dice_stream_detect_current_formats()
688 static void dice_lock_changed(struct snd_dice *dice) in dice_lock_changed() argument
690 dice->dev_lock_changed = true; in dice_lock_changed()
691 wake_up(&dice->hwdep_wait); in dice_lock_changed()
694 int snd_dice_stream_lock_try(struct snd_dice *dice) in snd_dice_stream_lock_try() argument
698 spin_lock_irq(&dice->lock); in snd_dice_stream_lock_try()
700 if (dice->dev_lock_count < 0) { in snd_dice_stream_lock_try()
705 if (dice->dev_lock_count++ == 0) in snd_dice_stream_lock_try()
706 dice_lock_changed(dice); in snd_dice_stream_lock_try()
709 spin_unlock_irq(&dice->lock); in snd_dice_stream_lock_try()
713 void snd_dice_stream_lock_release(struct snd_dice *dice) in snd_dice_stream_lock_release() argument
715 spin_lock_irq(&dice->lock); in snd_dice_stream_lock_release()
717 if (WARN_ON(dice->dev_lock_count <= 0)) in snd_dice_stream_lock_release()
720 if (--dice->dev_lock_count == 0) in snd_dice_stream_lock_release()
721 dice_lock_changed(dice); in snd_dice_stream_lock_release()
723 spin_unlock_irq(&dice->lock); in snd_dice_stream_lock_release()