sound/pci/echoaudio/midi.c
Source file repositories/reference/linux-study-clean/sound/pci/echoaudio/midi.c
File Facts
- System
- Linux kernel
- Corpus path
sound/pci/echoaudio/midi.c- Extension
.c- Size
- 8537 bytes
- Lines
- 312
- Domain
- Driver Families
- Bucket
- sound/pci
- 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.
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
- No C-style include directives detected by the generator.
Detected Declarations
function Corporationfunction write_midifunction mtc_process_datafunction midi_service_irqfunction snd_echo_midi_input_openfunction snd_echo_midi_input_triggerfunction snd_echo_midi_input_closefunction snd_echo_midi_output_openfunction snd_echo_midi_output_writefunction snd_echo_midi_output_triggerfunction snd_echo_midi_output_closefunction snd_echo_midi_create
Annotated Snippet
if (sent < 0) {
dev_err(chip->card->dev,
"write_midi() error %d\n", sent);
/* retry later */
sent = 9000;
chip->midi_full = 1;
} else if (sent > 0) {
dev_dbg(chip->card->dev, "%d bytes sent\n", sent);
snd_rawmidi_transmit_ack(chip->midi_out, sent);
} else {
/* Buffer is full. DSP's internal buffer is 64 (128 ?)
bytes long. Let's wait until half of them are sent */
dev_dbg(chip->card->dev, "Full\n");
sent = 32;
chip->midi_full = 1;
}
}
/* We restart the timer only if there is some data left to send */
if (!snd_rawmidi_transmit_empty(chip->midi_out) && chip->tinuse) {
/* The timer will expire slightly after the data has been
sent */
time = (sent << 3) / 25 + 1; /* 8/25=0.32ms to send a byte */
mod_timer(&chip->timer, jiffies + (time * HZ + 999) / 1000);
dev_dbg(chip->card->dev,
"Timer armed(%d)\n", ((time * HZ + 999) / 1000));
}
}
static void snd_echo_midi_output_trigger(struct snd_rawmidi_substream *substream,
int up)
{
struct echoaudio *chip = substream->rmidi->private_data;
bool remove_timer = false;
dev_dbg(chip->card->dev, "snd_echo_midi_output_trigger(%d)\n", up);
scoped_guard(spinlock_irq, &chip->lock) {
if (up) {
if (!chip->tinuse) {
timer_setup(&chip->timer, snd_echo_midi_output_write,
0);
chip->tinuse = 1;
}
} else {
if (chip->tinuse) {
chip->tinuse = 0;
remove_timer = true;
}
}
}
if (remove_timer) {
timer_delete_sync(&chip->timer);
dev_dbg(chip->card->dev, "Timer removed\n");
return;
}
if (up && !chip->midi_full)
snd_echo_midi_output_write(&chip->timer);
}
static int snd_echo_midi_output_close(struct snd_rawmidi_substream *substream)
{
struct echoaudio *chip = substream->rmidi->private_data;
chip->midi_out = NULL;
return 0;
}
static const struct snd_rawmidi_ops snd_echo_midi_input = {
.open = snd_echo_midi_input_open,
.close = snd_echo_midi_input_close,
.trigger = snd_echo_midi_input_trigger,
};
static const struct snd_rawmidi_ops snd_echo_midi_output = {
.open = snd_echo_midi_output_open,
.close = snd_echo_midi_output_close,
.trigger = snd_echo_midi_output_trigger,
};
/* <--snd_echo_probe() */
Annotation
- Detected declarations: `function Corporation`, `function write_midi`, `function mtc_process_data`, `function midi_service_irq`, `function snd_echo_midi_input_open`, `function snd_echo_midi_input_trigger`, `function snd_echo_midi_input_close`, `function snd_echo_midi_output_open`, `function snd_echo_midi_output_write`, `function snd_echo_midi_output_trigger`.
- Atlas domain: Driver Families / sound/pci.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.