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
391 err = snd_tscm_stream_get_rate(tscm, &curr_rate); in snd_tscm_stream_reserve_duplex()
395 if (tscm->substreams_counter == 0 || rate != curr_rate) { in snd_tscm_stream_reserve_duplex()
396 amdtp_domain_stop(&tscm->domain); in snd_tscm_stream_reserve_duplex()
398 finish_session(tscm); in snd_tscm_stream_reserve_duplex()
400 fw_iso_resources_free(&tscm->tx_resources); in snd_tscm_stream_reserve_duplex()
401 fw_iso_resources_free(&tscm->rx_resources); in snd_tscm_stream_reserve_duplex()
403 err = set_clock(tscm, rate, INT_MAX); in snd_tscm_stream_reserve_duplex()
407 err = keep_resources(tscm, rate, &tscm->tx_stream); in snd_tscm_stream_reserve_duplex()
411 err = keep_resources(tscm, rate, &tscm->rx_stream); in snd_tscm_stream_reserve_duplex()
413 fw_iso_resources_free(&tscm->tx_resources); in snd_tscm_stream_reserve_duplex()
421 int snd_tscm_stream_start_duplex(struct snd_tscm *tscm, unsigned int rate) in snd_tscm_stream_start_duplex() argument
423 unsigned int generation = tscm->rx_resources.generation; in snd_tscm_stream_start_duplex()
426 if (tscm->substreams_counter == 0) in snd_tscm_stream_start_duplex()
429 if (amdtp_streaming_error(&tscm->rx_stream) || in snd_tscm_stream_start_duplex()
430 amdtp_streaming_error(&tscm->tx_stream)) { in snd_tscm_stream_start_duplex()
431 amdtp_domain_stop(&tscm->domain); in snd_tscm_stream_start_duplex()
432 finish_session(tscm); in snd_tscm_stream_start_duplex()
435 if (generation != fw_parent_device(tscm->unit)->card->generation) { in snd_tscm_stream_start_duplex()
436 err = fw_iso_resources_update(&tscm->tx_resources); in snd_tscm_stream_start_duplex()
440 err = fw_iso_resources_update(&tscm->rx_resources); in snd_tscm_stream_start_duplex()
445 if (!amdtp_stream_running(&tscm->rx_stream)) { in snd_tscm_stream_start_duplex()
446 int spd = fw_parent_device(tscm->unit)->max_speed; in snd_tscm_stream_start_duplex()
448 err = set_stream_formats(tscm, rate); in snd_tscm_stream_start_duplex()
452 err = begin_session(tscm); in snd_tscm_stream_start_duplex()
456 err = amdtp_domain_add_stream(&tscm->domain, &tscm->rx_stream, in snd_tscm_stream_start_duplex()
457 tscm->rx_resources.channel, spd); in snd_tscm_stream_start_duplex()
461 err = amdtp_domain_add_stream(&tscm->domain, &tscm->tx_stream, in snd_tscm_stream_start_duplex()
462 tscm->tx_resources.channel, spd); in snd_tscm_stream_start_duplex()
466 err = amdtp_domain_start(&tscm->domain); in snd_tscm_stream_start_duplex()
470 if (!amdtp_stream_wait_callback(&tscm->rx_stream, in snd_tscm_stream_start_duplex()
472 !amdtp_stream_wait_callback(&tscm->tx_stream, in snd_tscm_stream_start_duplex()
481 amdtp_domain_stop(&tscm->domain); in snd_tscm_stream_start_duplex()
482 finish_session(tscm); in snd_tscm_stream_start_duplex()
487 void snd_tscm_stream_stop_duplex(struct snd_tscm *tscm) in snd_tscm_stream_stop_duplex() argument
489 if (tscm->substreams_counter == 0) { in snd_tscm_stream_stop_duplex()
490 amdtp_domain_stop(&tscm->domain); in snd_tscm_stream_stop_duplex()
491 finish_session(tscm); in snd_tscm_stream_stop_duplex()
493 fw_iso_resources_free(&tscm->tx_resources); in snd_tscm_stream_stop_duplex()
494 fw_iso_resources_free(&tscm->rx_resources); in snd_tscm_stream_stop_duplex()
498 void snd_tscm_stream_lock_changed(struct snd_tscm *tscm) in snd_tscm_stream_lock_changed() argument
500 tscm->dev_lock_changed = true; in snd_tscm_stream_lock_changed()
501 wake_up(&tscm->hwdep_wait); in snd_tscm_stream_lock_changed()
504 int snd_tscm_stream_lock_try(struct snd_tscm *tscm) in snd_tscm_stream_lock_try() argument
508 spin_lock_irq(&tscm->lock); in snd_tscm_stream_lock_try()
511 if (tscm->dev_lock_count < 0) { in snd_tscm_stream_lock_try()
517 if (tscm->dev_lock_count++ == 0) in snd_tscm_stream_lock_try()
518 snd_tscm_stream_lock_changed(tscm); in snd_tscm_stream_lock_try()
521 spin_unlock_irq(&tscm->lock); in snd_tscm_stream_lock_try()
525 void snd_tscm_stream_lock_release(struct snd_tscm *tscm) in snd_tscm_stream_lock_release() argument
527 spin_lock_irq(&tscm->lock); in snd_tscm_stream_lock_release()
529 if (WARN_ON(tscm->dev_lock_count <= 0)) in snd_tscm_stream_lock_release()
531 if (--tscm->dev_lock_count == 0) in snd_tscm_stream_lock_release()
532 snd_tscm_stream_lock_changed(tscm); in snd_tscm_stream_lock_release()
534 spin_unlock_irq(&tscm->lock); in snd_tscm_stream_lock_release()