sound/soc/amd/ps/ps-pdm-dma.c
Source file repositories/reference/linux-study-clean/sound/soc/amd/ps/ps-pdm-dma.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/amd/ps/ps-pdm-dma.c- Extension
.c- Size
- 12864 bytes
- Lines
- 465
- Domain
- Driver Families
- Bucket
- sound/soc
- 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/platform_device.hlinux/module.hlinux/bitfield.hlinux/err.hlinux/io.hsound/pcm_params.hsound/soc.hsound/soc-dai.hlinux/pm_runtime.hacp63.h
Detected Declarations
function acp63_init_pdm_ring_bufferfunction acp63_enable_pdm_clockfunction acp63_enable_pdm_interruptsfunction acp63_disable_pdm_interruptsfunction acp63_check_pdm_dma_statusfunction acp63_start_pdm_dmafunction acp63_stop_pdm_dmafunction acp63_config_dmafunction acp63_pdm_dma_openfunction acp63_pdm_dma_hw_paramsfunction acp63_pdm_get_byte_countfunction acp63_pdm_dma_pointerfunction acp63_pdm_dma_newfunction acp63_pdm_dma_closefunction acp63_pdm_dai_triggerfunction acp63_pdm_audio_probefunction acp63_pdm_audio_removefunction acp63_pdm_resumefunction acp63_pdm_suspendfunction acp63_pdm_runtime_resume
Annotated Snippet
while (++timeout < ACP_COUNTER) {
pdm_dma_enable = readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
if ((pdm_dma_enable & 0x02) == 0x00)
break;
udelay(DELAY_US);
}
if (timeout == ACP_COUNTER)
return -ETIMEDOUT;
}
if (pdm_enable == ACP_PDM_ENABLE) {
pdm_enable = ACP_PDM_DISABLE;
writel(pdm_enable, acp_base + ACP_WOV_PDM_ENABLE);
}
writel(0x01, acp_base + ACP_WOV_PDM_FIFO_FLUSH);
return 0;
}
static void acp63_config_dma(struct pdm_stream_instance *rtd, int direction)
{
u16 page_idx;
u32 low, high, val;
dma_addr_t addr;
addr = rtd->dma_addr;
val = PDM_PTE_OFFSET;
/* Group Enable */
writel(ACP_SRAM_PTE_OFFSET | BIT(31), rtd->acp63_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_1);
writel(PAGE_SIZE_4K_ENABLE, rtd->acp63_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1);
for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) {
/* Load the low address of page int ACP SRAM through SRBM */
low = lower_32_bits(addr);
high = upper_32_bits(addr);
writel(low, rtd->acp63_base + ACP_SCRATCH_REG_0 + val);
high |= BIT(31);
writel(high, rtd->acp63_base + ACP_SCRATCH_REG_0 + val + 4);
val += 8;
addr += PAGE_SIZE;
}
}
static int acp63_pdm_dma_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime;
struct pdm_dev_data *adata;
struct pdm_stream_instance *pdm_data;
int ret;
runtime = substream->runtime;
adata = dev_get_drvdata(component->dev);
pdm_data = kzalloc_obj(*pdm_data);
if (!pdm_data)
return -EINVAL;
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
runtime->hw = acp63_pdm_hardware_capture;
ret = snd_pcm_hw_constraint_integer(runtime,
SNDRV_PCM_HW_PARAM_PERIODS);
if (ret < 0) {
dev_err(component->dev, "set integer constraint failed\n");
kfree(pdm_data);
return ret;
}
acp63_enable_pdm_interrupts(adata);
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
adata->capture_stream = substream;
pdm_data->acp63_base = adata->acp63_base;
runtime->private_data = pdm_data;
return ret;
}
static int acp63_pdm_dma_hw_params(struct snd_soc_component *component,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct pdm_stream_instance *rtd;
size_t size, period_bytes;
rtd = substream->runtime->private_data;
if (!rtd)
return -EINVAL;
size = params_buffer_bytes(params);
period_bytes = params_period_bytes(params);
rtd->dma_addr = substream->runtime->dma_addr;
Annotation
- Immediate include surface: `linux/platform_device.h`, `linux/module.h`, `linux/bitfield.h`, `linux/err.h`, `linux/io.h`, `sound/pcm_params.h`, `sound/soc.h`, `sound/soc-dai.h`.
- Detected declarations: `function acp63_init_pdm_ring_buffer`, `function acp63_enable_pdm_clock`, `function acp63_enable_pdm_interrupts`, `function acp63_disable_pdm_interrupts`, `function acp63_check_pdm_dma_status`, `function acp63_start_pdm_dma`, `function acp63_stop_pdm_dma`, `function acp63_config_dma`, `function acp63_pdm_dma_open`, `function acp63_pdm_dma_hw_params`.
- Atlas domain: Driver Families / sound/soc.
- 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.