drivers/media/pci/tw686x/tw686x-audio.c
Source file repositories/reference/linux-study-clean/drivers/media/pci/tw686x/tw686x-audio.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/pci/tw686x/tw686x-audio.c- Extension
.c- Size
- 10842 bytes
- Lines
- 414
- Domain
- Driver Families
- Bucket
- drivers/media
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/types.hlinux/kernel.hlinux/module.hlinux/init.hlinux/kmod.hlinux/mutex.hlinux/pci.hlinux/delay.hsound/core.hsound/initval.hsound/pcm.hsound/control.htw686x.htw686x-regs.h
Detected Declarations
function Copyrightfunction for_each_set_bitfunction tw686x_pcm_openfunction tw686x_pcm_closefunction tw686x_pcm_preparefunction tw686x_pcm_triggerfunction tw686x_pcm_pointerfunction tw686x_snd_pcm_initfunction tw686x_audio_dma_freefunction tw686x_audio_dma_allocfunction tw686x_audio_freefunction tw686x_audio_init
Annotated Snippet
if (!ac->ss || !ac->curr_bufs[0] || !ac->curr_bufs[1]) {
spin_unlock_irqrestore(&ac->lock, flags);
continue;
}
if (!list_empty(&ac->buf_list)) {
next = list_first_entry(&ac->buf_list,
struct tw686x_audio_buf, list);
list_move_tail(&next->list, &ac->buf_list);
done = ac->curr_bufs[!pb];
ac->curr_bufs[pb] = next;
}
spin_unlock_irqrestore(&ac->lock, flags);
if (!done)
continue;
/*
* Checking for a non-nil dma_desc[pb]->virt buffer is
* the same as checking for memcpy DMA mode.
*/
desc = &ac->dma_descs[pb];
if (desc->virt) {
memcpy(done->virt, desc->virt,
dev->period_size);
} else {
u32 reg = pb ? ADMA_B_ADDR[ch] : ADMA_P_ADDR[ch];
reg_write(dev, reg, next->dma);
}
ac->ptr = done->dma - ac->buf[0].dma;
snd_pcm_period_elapsed(ac->ss);
}
}
/*
* Audio parameters are global and shared among all
* capture channels. The driver prevents changes to
* the parameters if any audio channel is capturing.
*/
static const struct snd_pcm_hardware tw686x_capture_hw = {
.info = (SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP_VALID),
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.rates = SNDRV_PCM_RATE_8000_48000,
.rate_min = 8000,
.rate_max = 48000,
.channels_min = 1,
.channels_max = 1,
.buffer_bytes_max = TW686X_AUDIO_PAGE_MAX * AUDIO_DMA_SIZE_MAX,
.period_bytes_min = AUDIO_DMA_SIZE_MIN,
.period_bytes_max = AUDIO_DMA_SIZE_MAX,
.periods_min = TW686X_AUDIO_PERIODS_MIN,
.periods_max = TW686X_AUDIO_PERIODS_MAX,
};
static int tw686x_pcm_open(struct snd_pcm_substream *ss)
{
struct tw686x_dev *dev = snd_pcm_substream_chip(ss);
struct tw686x_audio_channel *ac = &dev->audio_channels[ss->number];
struct snd_pcm_runtime *rt = ss->runtime;
int err;
ac->ss = ss;
rt->hw = tw686x_capture_hw;
err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
if (err < 0)
return err;
return 0;
}
static int tw686x_pcm_close(struct snd_pcm_substream *ss)
{
struct tw686x_dev *dev = snd_pcm_substream_chip(ss);
struct tw686x_audio_channel *ac = &dev->audio_channels[ss->number];
ac->ss = NULL;
return 0;
}
static int tw686x_pcm_prepare(struct snd_pcm_substream *ss)
{
struct tw686x_dev *dev = snd_pcm_substream_chip(ss);
struct tw686x_audio_channel *ac = &dev->audio_channels[ss->number];
struct snd_pcm_runtime *rt = ss->runtime;
unsigned int period_size = snd_pcm_lib_period_bytes(ss);
struct tw686x_audio_buf *p_buf, *b_buf;
unsigned long flags;
Annotation
- Immediate include surface: `linux/types.h`, `linux/kernel.h`, `linux/module.h`, `linux/init.h`, `linux/kmod.h`, `linux/mutex.h`, `linux/pci.h`, `linux/delay.h`.
- Detected declarations: `function Copyright`, `function for_each_set_bit`, `function tw686x_pcm_open`, `function tw686x_pcm_close`, `function tw686x_pcm_prepare`, `function tw686x_pcm_trigger`, `function tw686x_pcm_pointer`, `function tw686x_snd_pcm_init`, `function tw686x_audio_dma_free`, `function tw686x_audio_dma_alloc`.
- Atlas domain: Driver Families / drivers/media.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.