Lines Matching refs:tscm

16 static int get_clock(struct snd_tscm *tscm, u32 *data)  in get_clock()  argument
23 err = snd_fw_transaction(tscm->unit, TCODE_READ_QUADLET_REQUEST, in get_clock()
44 static int set_clock(struct snd_tscm *tscm, unsigned int rate, in set_clock() argument
51 err = get_clock(tscm, &data); in set_clock()
81 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, in set_clock()
92 return snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, in set_clock()
97 int snd_tscm_stream_get_rate(struct snd_tscm *tscm, unsigned int *rate) in snd_tscm_stream_get_rate() argument
102 err = get_clock(tscm, &data); in snd_tscm_stream_get_rate()
125 int snd_tscm_stream_get_clock(struct snd_tscm *tscm, enum snd_tscm_clock *clock) in snd_tscm_stream_get_clock() argument
130 err = get_clock(tscm, &data); in snd_tscm_stream_get_clock()
141 static int enable_data_channels(struct snd_tscm *tscm) in enable_data_channels() argument
149 for (i = 0; i < tscm->spec->pcm_capture_analog_channels; ++i) in enable_data_channels()
151 if (tscm->spec->has_adat) in enable_data_channels()
153 if (tscm->spec->has_spdif) in enable_data_channels()
157 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, in enable_data_channels()
164 for (i = 0; i < tscm->spec->pcm_playback_analog_channels; ++i) in enable_data_channels()
166 if (tscm->spec->has_adat) in enable_data_channels()
168 if (tscm->spec->has_spdif) in enable_data_channels()
172 return snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, in enable_data_channels()
177 static int set_stream_formats(struct snd_tscm *tscm, unsigned int rate) in set_stream_formats() argument
184 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, in set_stream_formats()
190 return enable_data_channels(tscm); in set_stream_formats()
193 static void finish_session(struct snd_tscm *tscm) in finish_session() argument
198 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, in finish_session()
203 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, in finish_session()
209 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, in finish_session()
213 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, in finish_session()
217 snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, in finish_session()
222 static int begin_session(struct snd_tscm *tscm) in begin_session() argument
228 reg = cpu_to_be32(tscm->tx_resources.channel); in begin_session()
229 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, in begin_session()
237 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, in begin_session()
244 reg = cpu_to_be32(tscm->rx_resources.channel); in begin_session()
245 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, in begin_session()
252 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, in begin_session()
259 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, in begin_session()
267 err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST, in begin_session()
275 return snd_fw_transaction(tscm->unit, in begin_session()
281 static int keep_resources(struct snd_tscm *tscm, unsigned int rate, in keep_resources() argument
287 if (stream == &tscm->tx_stream) in keep_resources()
288 resources = &tscm->tx_resources; in keep_resources()
290 resources = &tscm->rx_resources; in keep_resources()
298 fw_parent_device(tscm->unit)->max_speed); in keep_resources()
301 static int init_stream(struct snd_tscm *tscm, struct amdtp_stream *s) in init_stream() argument
308 if (s == &tscm->tx_stream) { in init_stream()
309 resources = &tscm->tx_resources; in init_stream()
311 pcm_channels = tscm->spec->pcm_capture_analog_channels; in init_stream()
313 resources = &tscm->rx_resources; in init_stream()
315 pcm_channels = tscm->spec->pcm_playback_analog_channels; in init_stream()
318 if (tscm->spec->has_adat) in init_stream()
320 if (tscm->spec->has_spdif) in init_stream()
323 err = fw_iso_resources_init(resources, tscm->unit); in init_stream()
327 err = amdtp_tscm_init(s, tscm->unit, dir, pcm_channels); in init_stream()
334 static void destroy_stream(struct snd_tscm *tscm, struct amdtp_stream *s) in destroy_stream() argument
338 if (s == &tscm->tx_stream) in destroy_stream()
339 fw_iso_resources_destroy(&tscm->tx_resources); in destroy_stream()
341 fw_iso_resources_destroy(&tscm->rx_resources); in destroy_stream()
344 int snd_tscm_stream_init_duplex(struct snd_tscm *tscm) in snd_tscm_stream_init_duplex() argument
348 err = init_stream(tscm, &tscm->tx_stream); in snd_tscm_stream_init_duplex()
352 err = init_stream(tscm, &tscm->rx_stream); in snd_tscm_stream_init_duplex()
354 destroy_stream(tscm, &tscm->tx_stream); in snd_tscm_stream_init_duplex()
358 err = amdtp_domain_init(&tscm->domain); in snd_tscm_stream_init_duplex()
360 destroy_stream(tscm, &tscm->tx_stream); in snd_tscm_stream_init_duplex()
361 destroy_stream(tscm, &tscm->rx_stream); in snd_tscm_stream_init_duplex()
368 void snd_tscm_stream_update_duplex(struct snd_tscm *tscm) in snd_tscm_stream_update_duplex() argument
370 amdtp_domain_stop(&tscm->domain); in snd_tscm_stream_update_duplex()
372 amdtp_stream_pcm_abort(&tscm->tx_stream); in snd_tscm_stream_update_duplex()
373 amdtp_stream_pcm_abort(&tscm->rx_stream); in snd_tscm_stream_update_duplex()
378 void snd_tscm_stream_destroy_duplex(struct snd_tscm *tscm) in snd_tscm_stream_destroy_duplex() argument
380 amdtp_domain_destroy(&tscm->domain); in snd_tscm_stream_destroy_duplex()
382 destroy_stream(tscm, &tscm->rx_stream); in snd_tscm_stream_destroy_duplex()
383 destroy_stream(tscm, &tscm->tx_stream); in snd_tscm_stream_destroy_duplex()
386 int snd_tscm_stream_reserve_duplex(struct snd_tscm *tscm, unsigned int rate, in snd_tscm_stream_reserve_duplex() argument
393 err = snd_tscm_stream_get_rate(tscm, &curr_rate); in snd_tscm_stream_reserve_duplex()
397 if (tscm->substreams_counter == 0 || rate != curr_rate) { in snd_tscm_stream_reserve_duplex()
398 amdtp_domain_stop(&tscm->domain); in snd_tscm_stream_reserve_duplex()
400 finish_session(tscm); in snd_tscm_stream_reserve_duplex()
402 fw_iso_resources_free(&tscm->tx_resources); in snd_tscm_stream_reserve_duplex()
403 fw_iso_resources_free(&tscm->rx_resources); in snd_tscm_stream_reserve_duplex()
405 err = set_clock(tscm, rate, INT_MAX); in snd_tscm_stream_reserve_duplex()
409 err = keep_resources(tscm, rate, &tscm->tx_stream); in snd_tscm_stream_reserve_duplex()
413 err = keep_resources(tscm, rate, &tscm->rx_stream); in snd_tscm_stream_reserve_duplex()
415 fw_iso_resources_free(&tscm->tx_resources); in snd_tscm_stream_reserve_duplex()
419 err = amdtp_domain_set_events_per_period(&tscm->domain, in snd_tscm_stream_reserve_duplex()
422 fw_iso_resources_free(&tscm->tx_resources); in snd_tscm_stream_reserve_duplex()
423 fw_iso_resources_free(&tscm->rx_resources); in snd_tscm_stream_reserve_duplex()
427 tscm->need_long_tx_init_skip = (rate != curr_rate); in snd_tscm_stream_reserve_duplex()
433 int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate) in snd_tscm_stream_start_duplex() argument
435 unsigned int generation = tscm->rx_resources.generation; in snd_tscm_stream_start_duplex()
438 if (tscm->substreams_counter == 0) in snd_tscm_stream_start_duplex()
441 if (amdtp_streaming_error(&tscm->rx_stream) || in snd_tscm_stream_start_duplex()
442 amdtp_streaming_error(&tscm->tx_stream)) { in snd_tscm_stream_start_duplex()
443 amdtp_domain_stop(&tscm->domain); in snd_tscm_stream_start_duplex()
444 finish_session(tscm); in snd_tscm_stream_start_duplex()
447 if (generation != fw_parent_device(tscm->unit)->card->generation) { in snd_tscm_stream_start_duplex()
448 err = fw_iso_resources_update(&tscm->tx_resources); in snd_tscm_stream_start_duplex()
452 err = fw_iso_resources_update(&tscm->rx_resources); in snd_tscm_stream_start_duplex()
457 if (!amdtp_stream_running(&tscm->rx_stream)) { in snd_tscm_stream_start_duplex()
458 int spd = fw_parent_device(tscm->unit)->max_speed; in snd_tscm_stream_start_duplex()
461 err = set_stream_formats(tscm, rate); in snd_tscm_stream_start_duplex()
465 err = begin_session(tscm); in snd_tscm_stream_start_duplex()
469 err = amdtp_domain_add_stream(&tscm->domain, &tscm->rx_stream, in snd_tscm_stream_start_duplex()
470 tscm->rx_resources.channel, spd); in snd_tscm_stream_start_duplex()
474 err = amdtp_domain_add_stream(&tscm->domain, &tscm->tx_stream, in snd_tscm_stream_start_duplex()
475 tscm->tx_resources.channel, spd); in snd_tscm_stream_start_duplex()
479 if (tscm->need_long_tx_init_skip) in snd_tscm_stream_start_duplex()
491 err = amdtp_domain_start(&tscm->domain, tx_init_skip_cycles, true, true); in snd_tscm_stream_start_duplex()
495 if (!amdtp_domain_wait_ready(&tscm->domain, READY_TIMEOUT_MS)) { in snd_tscm_stream_start_duplex()
503 amdtp_domain_stop(&tscm->domain); in snd_tscm_stream_start_duplex()
504 finish_session(tscm); in snd_tscm_stream_start_duplex()
509 void snd_tscm_stream_stop_duplex(struct snd_tscm *tscm) in snd_tscm_stream_stop_duplex() argument
511 if (tscm->substreams_counter == 0) { in snd_tscm_stream_stop_duplex()
512 amdtp_domain_stop(&tscm->domain); in snd_tscm_stream_stop_duplex()
513 finish_session(tscm); in snd_tscm_stream_stop_duplex()
515 fw_iso_resources_free(&tscm->tx_resources); in snd_tscm_stream_stop_duplex()
516 fw_iso_resources_free(&tscm->rx_resources); in snd_tscm_stream_stop_duplex()
518 tscm->need_long_tx_init_skip = false; in snd_tscm_stream_stop_duplex()
522 void snd_tscm_stream_lock_changed(struct snd_tscm *tscm) in snd_tscm_stream_lock_changed() argument
524 tscm->dev_lock_changed = true; in snd_tscm_stream_lock_changed()
525 wake_up(&tscm->hwdep_wait); in snd_tscm_stream_lock_changed()
528 int snd_tscm_stream_lock_try(struct snd_tscm *tscm) in snd_tscm_stream_lock_try() argument
532 spin_lock_irq(&tscm->lock); in snd_tscm_stream_lock_try()
535 if (tscm->dev_lock_count < 0) { in snd_tscm_stream_lock_try()
541 if (tscm->dev_lock_count++ == 0) in snd_tscm_stream_lock_try()
542 snd_tscm_stream_lock_changed(tscm); in snd_tscm_stream_lock_try()
545 spin_unlock_irq(&tscm->lock); in snd_tscm_stream_lock_try()
549 void snd_tscm_stream_lock_release(struct snd_tscm *tscm) in snd_tscm_stream_lock_release() argument
551 spin_lock_irq(&tscm->lock); in snd_tscm_stream_lock_release()
553 if (WARN_ON(tscm->dev_lock_count <= 0)) in snd_tscm_stream_lock_release()
555 if (--tscm->dev_lock_count == 0) in snd_tscm_stream_lock_release()
556 snd_tscm_stream_lock_changed(tscm); in snd_tscm_stream_lock_release()
558 spin_unlock_irq(&tscm->lock); in snd_tscm_stream_lock_release()