drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c
Source file repositories/reference/linux-study-clean/drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/staging/vc04_services/bcm2835-audio/bcm2835-pcm.c- Extension
.c- Size
- 9898 bytes
- Lines
- 356
- Domain
- Driver Families
- Bucket
- drivers/staging
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/interrupt.hlinux/slab.hsound/asoundef.hbcm2835.h
Detected Declarations
function snd_bcm2835_playback_freefunction bcm2835_playback_fifofunction snd_bcm2835_playback_open_genericfunction snd_bcm2835_playback_openfunction snd_bcm2835_playback_spdif_openfunction snd_bcm2835_playback_closefunction snd_bcm2835_pcm_preparefunction snd_bcm2835_pcm_transferfunction snd_bcm2835_pcm_ackfunction snd_bcm2835_pcm_triggerfunction snd_bcm2835_pcm_pointerfunction snd_bcm2835_new_pcm
Annotated Snippet
// SPDX-License-Identifier: GPL-2.0
/* Copyright 2011 Broadcom Corporation. All rights reserved. */
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <sound/asoundef.h>
#include "bcm2835.h"
/* hardware definition */
static const struct snd_pcm_hardware snd_bcm2835_playback_hw = {
.info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_SYNC_APPLPTR | SNDRV_PCM_INFO_BATCH),
.formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
.rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_192000,
.rate_min = 8000,
.rate_max = 192000,
.channels_min = 1,
.channels_max = 8,
.buffer_bytes_max = 512 * 1024,
.period_bytes_min = 1 * 1024,
.period_bytes_max = 512 * 1024,
.periods_min = 1,
.periods_max = 128,
};
static const struct snd_pcm_hardware snd_bcm2835_playback_spdif_hw = {
.info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
SNDRV_PCM_INFO_SYNC_APPLPTR | SNDRV_PCM_INFO_BATCH),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000,
.rate_min = 44100,
.rate_max = 48000,
.channels_min = 2,
.channels_max = 2,
.buffer_bytes_max = 128 * 1024,
.period_bytes_min = 1 * 1024,
.period_bytes_max = 128 * 1024,
.periods_min = 1,
.periods_max = 128,
};
static void snd_bcm2835_playback_free(struct snd_pcm_runtime *runtime)
{
kfree(runtime->private_data);
}
void bcm2835_playback_fifo(struct bcm2835_alsa_stream *alsa_stream,
unsigned int bytes)
{
struct snd_pcm_substream *substream = alsa_stream->substream;
unsigned int pos;
if (!alsa_stream->period_size)
return;
if (bytes >= alsa_stream->buffer_size) {
snd_pcm_stream_lock(substream);
snd_pcm_stop(substream,
alsa_stream->draining ?
SNDRV_PCM_STATE_SETUP :
SNDRV_PCM_STATE_XRUN);
snd_pcm_stream_unlock(substream);
return;
}
pos = atomic_read(&alsa_stream->pos);
pos += bytes;
pos %= alsa_stream->buffer_size;
atomic_set(&alsa_stream->pos, pos);
alsa_stream->period_offset += bytes;
alsa_stream->interpolate_start = ktime_get();
if (alsa_stream->period_offset >= alsa_stream->period_size) {
alsa_stream->period_offset %= alsa_stream->period_size;
snd_pcm_period_elapsed(substream);
}
}
/* open callback */
static int snd_bcm2835_playback_open_generic(struct snd_pcm_substream *substream, int spdif)
{
struct bcm2835_chip *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
struct bcm2835_alsa_stream *alsa_stream;
int idx;
Annotation
- Immediate include surface: `linux/interrupt.h`, `linux/slab.h`, `sound/asoundef.h`, `bcm2835.h`.
- Detected declarations: `function snd_bcm2835_playback_free`, `function bcm2835_playback_fifo`, `function snd_bcm2835_playback_open_generic`, `function snd_bcm2835_playback_open`, `function snd_bcm2835_playback_spdif_open`, `function snd_bcm2835_playback_close`, `function snd_bcm2835_pcm_prepare`, `function snd_bcm2835_pcm_transfer`, `function snd_bcm2835_pcm_ack`, `function snd_bcm2835_pcm_trigger`.
- Atlas domain: Driver Families / drivers/staging.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
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.