sound/firewire/bebob/bebob_stream.c

Source file repositories/reference/linux-study-clean/sound/firewire/bebob/bebob_stream.c

File Facts

System
Linux kernel
Corpus path
sound/firewire/bebob/bebob_stream.c
Extension
.c
Size
24790 bytes
Lines
988
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 (snd_bebob_rate_table[i] == rate) {
			*index = i;
			return 0;
		}
	}
	return -EINVAL;
}

int
snd_bebob_stream_get_rate(struct snd_bebob *bebob, unsigned int *curr_rate)
{
	unsigned int tx_rate, rx_rate, trials;
	int err;

	trials = 0;
	do {
		err = avc_general_get_sig_fmt(bebob->unit, &tx_rate,
					      AVC_GENERAL_PLUG_DIR_OUT, 0);
	} while (err == -EAGAIN && ++trials < 3);
	if (err < 0)
		goto end;

	trials = 0;
	do {
		err = avc_general_get_sig_fmt(bebob->unit, &rx_rate,
					      AVC_GENERAL_PLUG_DIR_IN, 0);
	} while (err == -EAGAIN && ++trials < 3);
	if (err < 0)
		goto end;

	*curr_rate = rx_rate;
	if (rx_rate == tx_rate)
		goto end;

	/* synchronize receive stream rate to transmit stream rate */
	err = avc_general_set_sig_fmt(bebob->unit, rx_rate,
				      AVC_GENERAL_PLUG_DIR_IN, 0);
end:
	return err;
}

int
snd_bebob_stream_set_rate(struct snd_bebob *bebob, unsigned int rate)
{
	int err;

	err = avc_general_set_sig_fmt(bebob->unit, rate,
				      AVC_GENERAL_PLUG_DIR_OUT, 0);
	if (err < 0)
		goto end;

	err = avc_general_set_sig_fmt(bebob->unit, rate,
				      AVC_GENERAL_PLUG_DIR_IN, 0);
	if (err < 0)
		goto end;

	/*
	 * Some devices need a bit time for transition.
	 * 300msec is got by some experiments.
	 */
	msleep(300);
end:
	return err;
}

int snd_bebob_stream_get_clock_src(struct snd_bebob *bebob,
				   enum snd_bebob_clock_type *src)
{
	const struct snd_bebob_clock_spec *clk_spec = bebob->spec->clock;
	u8 addr[AVC_BRIDGECO_ADDR_BYTES], input[7];
	unsigned int id;
	enum avc_bridgeco_plug_type type;
	int err = 0;

	/* 1.The device has its own operation to switch source of clock */
	if (clk_spec) {
		err = clk_spec->get(bebob, &id);
		if (err < 0) {
			dev_err(&bebob->unit->device,
				"fail to get clock source: %d\n", err);
			goto end;
		}

		if (id >= clk_spec->num) {
			dev_err(&bebob->unit->device,
				"clock source %d out of range 0..%d\n",
				id, clk_spec->num - 1);
			err = -EIO;
			goto end;
		}

Annotation

Implementation Notes