// SPDX-License-Identifier: GPL-2.0-only /* * digi00x-stream.c - a part of driver for Digidesign Digi 002/003 family * * Copyright (c) 2014-2015 Takashi Sakamoto
*/
for (i = 0; i < ARRAY_SIZE(snd_dg00x_stream_rates); i++) { if (rate == snd_dg00x_stream_rates[i]) break;
} if (i == ARRAY_SIZE(snd_dg00x_stream_rates)) return -EINVAL;
curr--; while (curr > 0) {
data = cpu_to_be32(curr);
err = snd_fw_transaction(dg00x->unit,
TCODE_WRITE_QUADLET_REQUEST,
DG00X_ADDR_BASE +
DG00X_OFFSET_STREAMING_SET,
&data, sizeof(data), 0); if (err < 0) break;
msleep(20);
curr--;
}
return err;
}
staticint keep_resources(struct snd_dg00x *dg00x, struct amdtp_stream *stream, unsignedint rate)
{ struct fw_iso_resources *resources; int i; int err;
// Check sampling rate. for (i = 0; i < SND_DG00X_RATE_COUNT; i++) { if (snd_dg00x_stream_rates[i] == rate) break;
} if (i == SND_DG00X_RATE_COUNT) return -EINVAL;
/* * This function should be called before starting streams or after stopping * streams.
*/ void snd_dg00x_stream_destroy_duplex(struct snd_dg00x *dg00x)
{
amdtp_domain_destroy(&dg00x->domain);
int snd_dg00x_stream_start_duplex(struct snd_dg00x *dg00x)
{ unsignedint generation = dg00x->rx_resources.generation; int err = 0;
if (dg00x->substreams_counter == 0) return 0;
if (amdtp_streaming_error(&dg00x->tx_stream) ||
amdtp_streaming_error(&dg00x->rx_stream)) {
amdtp_domain_stop(&dg00x->domain);
finish_session(dg00x);
}
if (generation != fw_parent_device(dg00x->unit)->card->generation) {
err = fw_iso_resources_update(&dg00x->tx_resources); if (err < 0) goto error;
err = fw_iso_resources_update(&dg00x->rx_resources); if (err < 0) goto error;
}
/* * No packets are transmitted without receiving packets, reagardless of * which source of clock is used.
*/ if (!amdtp_stream_running(&dg00x->rx_stream)) { int spd = fw_parent_device(dg00x->unit)->max_speed;
err = begin_session(dg00x); if (err < 0) goto error;
// NOTE: The device doesn't start packet transmission till receiving any packet. // It ignores presentation time expressed by the value of syt field of CIP header // in received packets. The sequence of the number of data blocks per packet is // important for media clock recovery.
err = amdtp_domain_start(&dg00x->domain, 0, true, true); if (err < 0) goto error;
int snd_dg00x_stream_lock_try(struct snd_dg00x *dg00x)
{ int err;
spin_lock_irq(&dg00x->lock);
/* user land lock this */ if (dg00x->dev_lock_count < 0) {
err = -EBUSY; goto end;
}
/* this is the first time */ if (dg00x->dev_lock_count++ == 0)
snd_dg00x_stream_lock_changed(dg00x);
err = 0;
end:
spin_unlock_irq(&dg00x->lock); return err;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.