Lines Matching +full:clock +full:- +full:error +full:- +full:detect

1 // SPDX-License-Identifier: GPL-2.0-only
3 * digi00x-stream.c - a part of driver for Digidesign Digi 002/003 family
5 * Copyright (c) 2014-2015 Takashi Sakamoto
36 err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST, in snd_dg00x_stream_get_local_rate()
46 err = -EIO; in snd_dg00x_stream_get_local_rate()
61 return -EINVAL; in snd_dg00x_stream_set_local_rate()
64 return snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST, in snd_dg00x_stream_set_local_rate()
70 enum snd_dg00x_clock *clock) in snd_dg00x_stream_get_clock() argument
75 err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST, in snd_dg00x_stream_get_clock()
81 *clock = be32_to_cpu(reg) & 0x0f; in snd_dg00x_stream_get_clock()
82 if (*clock >= SND_DG00X_CLOCK_COUNT) in snd_dg00x_stream_get_clock()
83 err = -EIO; in snd_dg00x_stream_get_clock()
88 int snd_dg00x_stream_check_external_clock(struct snd_dg00x *dg00x, bool *detect) in snd_dg00x_stream_check_external_clock() argument
93 err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST, in snd_dg00x_stream_check_external_clock()
97 *detect = be32_to_cpu(reg) > 0; in snd_dg00x_stream_check_external_clock()
109 err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST, in snd_dg00x_stream_get_external_rate()
120 err = -EBUSY; in snd_dg00x_stream_get_external_rate()
130 snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST, in finish_session()
136 snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST, in finish_session()
152 data = cpu_to_be32((dg00x->tx_resources.channel << 16) | in begin_session()
153 dg00x->rx_resources.channel); in begin_session()
154 err = snd_fw_transaction(dg00x->unit, TCODE_WRITE_QUADLET_REQUEST, in begin_session()
160 err = snd_fw_transaction(dg00x->unit, TCODE_READ_QUADLET_REQUEST, in begin_session()
170 curr--; in begin_session()
173 err = snd_fw_transaction(dg00x->unit, in begin_session()
182 curr--; in begin_session()
201 return -EINVAL; in keep_resources()
203 if (stream == &dg00x->tx_stream) in keep_resources()
204 resources = &dg00x->tx_resources; in keep_resources()
206 resources = &dg00x->rx_resources; in keep_resources()
215 fw_parent_device(dg00x->unit)->max_speed); in keep_resources()
224 if (s == &dg00x->tx_stream) { in init_stream()
225 resources = &dg00x->tx_resources; in init_stream()
228 resources = &dg00x->rx_resources; in init_stream()
232 err = fw_iso_resources_init(resources, dg00x->unit); in init_stream()
236 err = amdtp_dot_init(s, dg00x->unit, dir); in init_stream()
247 if (s == &dg00x->tx_stream) in destroy_stream()
248 fw_iso_resources_destroy(&dg00x->tx_resources); in destroy_stream()
250 fw_iso_resources_destroy(&dg00x->rx_resources); in destroy_stream()
257 err = init_stream(dg00x, &dg00x->rx_stream); in snd_dg00x_stream_init_duplex()
261 err = init_stream(dg00x, &dg00x->tx_stream); in snd_dg00x_stream_init_duplex()
263 destroy_stream(dg00x, &dg00x->rx_stream); in snd_dg00x_stream_init_duplex()
267 err = amdtp_domain_init(&dg00x->domain); in snd_dg00x_stream_init_duplex()
269 destroy_stream(dg00x, &dg00x->rx_stream); in snd_dg00x_stream_init_duplex()
270 destroy_stream(dg00x, &dg00x->tx_stream); in snd_dg00x_stream_init_duplex()
282 amdtp_domain_destroy(&dg00x->domain); in snd_dg00x_stream_destroy_duplex()
284 destroy_stream(dg00x, &dg00x->rx_stream); in snd_dg00x_stream_destroy_duplex()
285 destroy_stream(dg00x, &dg00x->tx_stream); in snd_dg00x_stream_destroy_duplex()
301 if (dg00x->substreams_counter == 0 || curr_rate != rate) { in snd_dg00x_stream_reserve_duplex()
302 amdtp_domain_stop(&dg00x->domain); in snd_dg00x_stream_reserve_duplex()
306 fw_iso_resources_free(&dg00x->tx_resources); in snd_dg00x_stream_reserve_duplex()
307 fw_iso_resources_free(&dg00x->rx_resources); in snd_dg00x_stream_reserve_duplex()
313 err = keep_resources(dg00x, &dg00x->rx_stream, rate); in snd_dg00x_stream_reserve_duplex()
317 err = keep_resources(dg00x, &dg00x->tx_stream, rate); in snd_dg00x_stream_reserve_duplex()
319 fw_iso_resources_free(&dg00x->rx_resources); in snd_dg00x_stream_reserve_duplex()
323 err = amdtp_domain_set_events_per_period(&dg00x->domain, in snd_dg00x_stream_reserve_duplex()
326 fw_iso_resources_free(&dg00x->rx_resources); in snd_dg00x_stream_reserve_duplex()
327 fw_iso_resources_free(&dg00x->tx_resources); in snd_dg00x_stream_reserve_duplex()
337 unsigned int generation = dg00x->rx_resources.generation; in snd_dg00x_stream_start_duplex()
340 if (dg00x->substreams_counter == 0) in snd_dg00x_stream_start_duplex()
343 if (amdtp_streaming_error(&dg00x->tx_stream) || in snd_dg00x_stream_start_duplex()
344 amdtp_streaming_error(&dg00x->rx_stream)) { in snd_dg00x_stream_start_duplex()
345 amdtp_domain_stop(&dg00x->domain); in snd_dg00x_stream_start_duplex()
349 if (generation != fw_parent_device(dg00x->unit)->card->generation) { in snd_dg00x_stream_start_duplex()
350 err = fw_iso_resources_update(&dg00x->tx_resources); in snd_dg00x_stream_start_duplex()
352 goto error; in snd_dg00x_stream_start_duplex()
354 err = fw_iso_resources_update(&dg00x->rx_resources); in snd_dg00x_stream_start_duplex()
356 goto error; in snd_dg00x_stream_start_duplex()
361 * which source of clock is used. in snd_dg00x_stream_start_duplex()
363 if (!amdtp_stream_running(&dg00x->rx_stream)) { in snd_dg00x_stream_start_duplex()
364 int spd = fw_parent_device(dg00x->unit)->max_speed; in snd_dg00x_stream_start_duplex()
368 goto error; in snd_dg00x_stream_start_duplex()
370 err = amdtp_domain_add_stream(&dg00x->domain, &dg00x->rx_stream, in snd_dg00x_stream_start_duplex()
371 dg00x->rx_resources.channel, spd); in snd_dg00x_stream_start_duplex()
373 goto error; in snd_dg00x_stream_start_duplex()
375 err = amdtp_domain_add_stream(&dg00x->domain, &dg00x->tx_stream, in snd_dg00x_stream_start_duplex()
376 dg00x->tx_resources.channel, spd); in snd_dg00x_stream_start_duplex()
378 goto error; in snd_dg00x_stream_start_duplex()
383 // important for media clock recovery. in snd_dg00x_stream_start_duplex()
384 err = amdtp_domain_start(&dg00x->domain, 0, true, true); in snd_dg00x_stream_start_duplex()
386 goto error; in snd_dg00x_stream_start_duplex()
388 if (!amdtp_domain_wait_ready(&dg00x->domain, READY_TIMEOUT_MS)) { in snd_dg00x_stream_start_duplex()
389 err = -ETIMEDOUT; in snd_dg00x_stream_start_duplex()
390 goto error; in snd_dg00x_stream_start_duplex()
395 error: in snd_dg00x_stream_start_duplex()
396 amdtp_domain_stop(&dg00x->domain); in snd_dg00x_stream_start_duplex()
404 if (dg00x->substreams_counter == 0) { in snd_dg00x_stream_stop_duplex()
405 amdtp_domain_stop(&dg00x->domain); in snd_dg00x_stream_stop_duplex()
408 fw_iso_resources_free(&dg00x->tx_resources); in snd_dg00x_stream_stop_duplex()
409 fw_iso_resources_free(&dg00x->rx_resources); in snd_dg00x_stream_stop_duplex()
415 fw_iso_resources_update(&dg00x->tx_resources); in snd_dg00x_stream_update_duplex()
416 fw_iso_resources_update(&dg00x->rx_resources); in snd_dg00x_stream_update_duplex()
418 amdtp_stream_update(&dg00x->tx_stream); in snd_dg00x_stream_update_duplex()
419 amdtp_stream_update(&dg00x->rx_stream); in snd_dg00x_stream_update_duplex()
424 dg00x->dev_lock_changed = true; in snd_dg00x_stream_lock_changed()
425 wake_up(&dg00x->hwdep_wait); in snd_dg00x_stream_lock_changed()
432 spin_lock_irq(&dg00x->lock); in snd_dg00x_stream_lock_try()
435 if (dg00x->dev_lock_count < 0) { in snd_dg00x_stream_lock_try()
436 err = -EBUSY; in snd_dg00x_stream_lock_try()
441 if (dg00x->dev_lock_count++ == 0) in snd_dg00x_stream_lock_try()
445 spin_unlock_irq(&dg00x->lock); in snd_dg00x_stream_lock_try()
451 spin_lock_irq(&dg00x->lock); in snd_dg00x_stream_lock_release()
453 if (WARN_ON(dg00x->dev_lock_count <= 0)) in snd_dg00x_stream_lock_release()
455 if (--dg00x->dev_lock_count == 0) in snd_dg00x_stream_lock_release()
458 spin_unlock_irq(&dg00x->lock); in snd_dg00x_stream_lock_release()