sound/firewire/digi00x/digi00x-stream.c

Source file repositories/reference/linux-study-clean/sound/firewire/digi00x/digi00x-stream.c

File Facts

System
Linux kernel
Corpus path
sound/firewire/digi00x/digi00x-stream.c
Extension
.c
Size
10638 bytes
Lines
451
Domain
Driver Families
Bucket
sound/firewire
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (err < 0) {
			fw_iso_resources_free(&dg00x->rx_resources);
			return err;
		}

		err = amdtp_domain_set_events_per_period(&dg00x->domain,
					frames_per_period, frames_per_buffer);
		if (err < 0) {
			fw_iso_resources_free(&dg00x->rx_resources);
			fw_iso_resources_free(&dg00x->tx_resources);
			return err;
		}
	}

	return 0;
}

int snd_dg00x_stream_start_duplex(struct snd_dg00x *dg00x)
{
	unsigned int 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;

		err = amdtp_domain_add_stream(&dg00x->domain, &dg00x->rx_stream,
					      dg00x->rx_resources.channel, spd);
		if (err < 0)
			goto error;

		err = amdtp_domain_add_stream(&dg00x->domain, &dg00x->tx_stream,
					      dg00x->tx_resources.channel, spd);
		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;

		if (!amdtp_domain_wait_ready(&dg00x->domain, READY_TIMEOUT_MS)) {
			err = -ETIMEDOUT;
			goto error;
		}
	}

	return 0;
error:
	amdtp_domain_stop(&dg00x->domain);
	finish_session(dg00x);

	return err;
}

void snd_dg00x_stream_stop_duplex(struct snd_dg00x *dg00x)
{
	if (dg00x->substreams_counter == 0) {
		amdtp_domain_stop(&dg00x->domain);
		finish_session(dg00x);

Annotation

Implementation Notes