sound/firewire/digi00x/digi00x-midi.c

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

File Facts

System
Linux kernel
Corpus path
sound/firewire/digi00x/digi00x-midi.c
Extension
.c
Size
3875 bytes
Lines
168
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) {
			++dg00x->substreams_counter;
			err = snd_dg00x_stream_start_duplex(dg00x);
			if (err < 0)
				--dg00x->substreams_counter;
		}
	}
	if (err < 0)
		snd_dg00x_stream_lock_release(dg00x);

	return err;
}

static int midi_close(struct snd_rawmidi_substream *substream)
{
	struct snd_dg00x *dg00x = substream->rmidi->private_data;

	scoped_guard(mutex, &dg00x->mutex) {
		--dg00x->substreams_counter;
		snd_dg00x_stream_stop_duplex(dg00x);
	}

	snd_dg00x_stream_lock_release(dg00x);
	return 0;
}

static void midi_capture_trigger(struct snd_rawmidi_substream *substream,
				 int up)
{
	struct snd_dg00x *dg00x = substream->rmidi->private_data;
	unsigned int port;

	if (substream->rmidi->device == 0)
		port = substream->number;
	else
		port = 2;

	guard(spinlock_irqsave)(&dg00x->lock);

	if (up)
		amdtp_dot_midi_trigger(&dg00x->tx_stream, port, substream);
	else
		amdtp_dot_midi_trigger(&dg00x->tx_stream, port, NULL);
}

static void midi_playback_trigger(struct snd_rawmidi_substream *substream,
				  int up)
{
	struct snd_dg00x *dg00x = substream->rmidi->private_data;
	unsigned int port;

	if (substream->rmidi->device == 0)
		port = substream->number;
	else
		port = 2;

	guard(spinlock_irqsave)(&dg00x->lock);

	if (up)
		amdtp_dot_midi_trigger(&dg00x->rx_stream, port, substream);
	else
		amdtp_dot_midi_trigger(&dg00x->rx_stream, port, NULL);
}

static void set_substream_names(struct snd_dg00x *dg00x,
				struct snd_rawmidi *rmidi, bool is_console)
{
	struct snd_rawmidi_substream *subs;
	struct snd_rawmidi_str *str;
	int i;

	for (i = 0; i < 2; ++i) {
		str = &rmidi->streams[i];

		list_for_each_entry(subs, &str->substreams, list) {
			if (!is_console) {
				scnprintf(subs->name, sizeof(subs->name),
					  "%s MIDI %d",
					  dg00x->card->shortname,
					  subs->number + 1);
			} else {
				scnprintf(subs->name, sizeof(subs->name),
					  "%s control",
					  dg00x->card->shortname);
			}
		}
	}
}

static int add_substream_pair(struct snd_dg00x *dg00x, unsigned int out_ports,

Annotation

Implementation Notes