sound/drivers/serial-generic.c
Source file repositories/reference/linux-study-clean/sound/drivers/serial-generic.c
File Facts
- System
- Linux kernel
- Corpus path
sound/drivers/serial-generic.c- Extension
.c- Size
- 10243 bytes
- Lines
- 377
- Domain
- Driver Families
- Bucket
- sound/drivers
- 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
linux/err.hlinux/init.hlinux/interrupt.hlinux/io.hlinux/ioport.hlinux/module.hlinux/of.hlinux/serdev.hlinux/serial_reg.hlinux/slab.hlinux/dev_printk.hsound/core.hsound/rawmidi.hsound/initval.h
Detected Declarations
struct snd_serial_genericfunction snd_serial_generic_tx_wakeupfunction snd_serial_generic_tx_workfunction snd_serial_generic_write_wakeupfunction snd_serial_generic_receive_buffunction snd_serial_generic_ensure_serdev_openfunction snd_serial_generic_input_openfunction snd_serial_generic_input_closefunction snd_serial_generic_input_triggerfunction snd_serial_generic_output_openfunction snd_serial_generic_output_closefunction snd_serial_generic_output_triggerfunction snd_serial_generic_output_drainfunction snd_serial_generic_parse_dtfunction snd_serial_generic_substreamsfunction list_for_each_entryfunction snd_serial_generic_rmidifunction snd_serial_generic_probe
Annotated Snippet
struct snd_serial_generic {
struct serdev_device *serdev;
struct snd_card *card;
struct snd_rawmidi *rmidi;
struct snd_rawmidi_substream *midi_output;
struct snd_rawmidi_substream *midi_input;
unsigned int baudrate;
unsigned long filemode; /* open status of file */
struct work_struct tx_work;
unsigned long tx_state;
char tx_buf[INTERNAL_BUF_SIZE];
};
static void snd_serial_generic_tx_wakeup(struct snd_serial_generic *drvdata)
{
if (test_and_set_bit(SERIAL_TX_STATE_ACTIVE, &drvdata->tx_state))
set_bit(SERIAL_TX_STATE_WAKEUP, &drvdata->tx_state);
schedule_work(&drvdata->tx_work);
}
static void snd_serial_generic_tx_work(struct work_struct *work)
{
int num_bytes;
struct snd_serial_generic *drvdata = container_of(work, struct snd_serial_generic,
tx_work);
struct snd_rawmidi_substream *substream = drvdata->midi_output;
clear_bit(SERIAL_TX_STATE_WAKEUP, &drvdata->tx_state);
while (!snd_rawmidi_transmit_empty(substream)) {
if (!test_bit(SERIAL_MODE_OUTPUT_OPEN, &drvdata->filemode))
break;
num_bytes = snd_rawmidi_transmit_peek(substream, drvdata->tx_buf,
INTERNAL_BUF_SIZE);
num_bytes = serdev_device_write_buf(drvdata->serdev, drvdata->tx_buf,
num_bytes);
if (!num_bytes)
break;
snd_rawmidi_transmit_ack(substream, num_bytes);
if (!test_bit(SERIAL_TX_STATE_WAKEUP, &drvdata->tx_state))
break;
}
clear_bit(SERIAL_TX_STATE_ACTIVE, &drvdata->tx_state);
}
static void snd_serial_generic_write_wakeup(struct serdev_device *serdev)
{
struct snd_serial_generic *drvdata = serdev_device_get_drvdata(serdev);
snd_serial_generic_tx_wakeup(drvdata);
}
static size_t snd_serial_generic_receive_buf(struct serdev_device *serdev,
const u8 *buf, size_t count)
{
int ret;
struct snd_serial_generic *drvdata = serdev_device_get_drvdata(serdev);
if (!test_bit(SERIAL_MODE_INPUT_OPEN, &drvdata->filemode))
return 0;
ret = snd_rawmidi_receive(drvdata->midi_input, buf, count);
return ret < 0 ? 0 : ret;
}
static const struct serdev_device_ops snd_serial_generic_serdev_device_ops = {
.receive_buf = snd_serial_generic_receive_buf,
.write_wakeup = snd_serial_generic_write_wakeup
};
static int snd_serial_generic_ensure_serdev_open(struct snd_serial_generic *drvdata)
{
int err;
unsigned int actual_baud;
if (drvdata->filemode)
return 0;
dev_dbg(drvdata->card->dev, "Opening serial port for card %s\n",
Annotation
- Immediate include surface: `linux/err.h`, `linux/init.h`, `linux/interrupt.h`, `linux/io.h`, `linux/ioport.h`, `linux/module.h`, `linux/of.h`, `linux/serdev.h`.
- Detected declarations: `struct snd_serial_generic`, `function snd_serial_generic_tx_wakeup`, `function snd_serial_generic_tx_work`, `function snd_serial_generic_write_wakeup`, `function snd_serial_generic_receive_buf`, `function snd_serial_generic_ensure_serdev_open`, `function snd_serial_generic_input_open`, `function snd_serial_generic_input_close`, `function snd_serial_generic_input_trigger`, `function snd_serial_generic_output_open`.
- Atlas domain: Driver Families / sound/drivers.
- 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.