sound/firewire/tascam/tascam-stream.c

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

File Facts

System
Linux kernel
Corpus path
sound/firewire/tascam/tascam-stream.c
Extension
.c
Size
13166 bytes
Lines
552
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 ((rate % 44100) == 0) {
			data |= 0x00000100;
			/* Multiplier. */
			if (rate / 44100 == 2)
				data |= 0x00008000;
		} else if ((rate % 48000) == 0) {
			data |= 0x00000200;
			/* Multiplier. */
			if (rate / 48000 == 2)
				data |= 0x00008000;
		} else {
			return -EAGAIN;
		}
	}

	if (clock != INT_MAX) {
		data &= 0x0000ff00;
		data |= clock + 1;
	}

	reg = cpu_to_be32(data);

	err = snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
				 TSCM_ADDR_BASE + TSCM_OFFSET_CLOCK_STATUS,
				 &reg, sizeof(reg), 0);
	if (err < 0)
		return err;

	if (data & 0x00008000)
		reg = cpu_to_be32(0x0000001a);
	else
		reg = cpu_to_be32(0x0000000d);

	return snd_fw_transaction(tscm->unit, TCODE_WRITE_QUADLET_REQUEST,
				  TSCM_ADDR_BASE + TSCM_OFFSET_MULTIPLEX_MODE,
				  &reg, sizeof(reg), 0);
}

int snd_tscm_stream_get_rate(struct snd_tscm *tscm, unsigned int *rate)
{
	u32 data;
	int err;

	err = get_clock(tscm, &data);
	if (err < 0)
		return err;

	data = (data & 0xff000000) >> 24;

	/* Check base rate. */
	if ((data & 0x0f) == 0x01)
		*rate = 44100;
	else if ((data & 0x0f) == 0x02)
		*rate = 48000;
	else
		return -EAGAIN;

	/* Check multiplier. */
	if ((data & 0xf0) == 0x80)
		*rate *= 2;
	else if ((data & 0xf0) != 0x00)
		return -EAGAIN;

	return err;
}

int snd_tscm_stream_get_clock(struct snd_tscm *tscm, enum snd_tscm_clock *clock)
{
	u32 data;
	int err;

	err = get_clock(tscm, &data);
	if (err < 0)
		return err;

	*clock = ((data & 0x00ff0000) >> 16) - 1;
	if (*clock < 0 || *clock > SND_TSCM_CLOCK_ADAT)
		return -EIO;

	return 0;
}

static int enable_data_channels(struct snd_tscm *tscm)
{
	__be32 reg;
	u32 data;
	unsigned int i;
	int err;

	data = 0;

Annotation

Implementation Notes