sound/soc/fsl/fsl_asrc_m2m.c
Source file repositories/reference/linux-study-clean/sound/soc/fsl/fsl_asrc_m2m.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/fsl/fsl_asrc_m2m.c- Extension
.c- Size
- 19125 bytes
- Lines
- 736
- Domain
- Driver Families
- Bucket
- sound/soc
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/dma/imx-dma.hlinux/dma-buf.hlinux/dma-mapping.hlinux/pm_runtime.hsound/asound.hsound/dmaengine_pcm.hsound/initval.hfsl_asrc_common.h
Detected Declarations
function asrc_input_dma_callbackfunction asrc_output_dma_callbackfunction asrc_read_last_fifofunction asrc_dmaconfigfunction asrc_m2m_device_runfunction fsl_asrc_m2m_comp_openfunction fsl_asrc_m2m_comp_releasefunction fsl_asrc_m2m_comp_set_paramsfunction fsl_asrc_m2m_mmapfunction fsl_asrc_m2m_unmap_dma_buffunction fsl_asrc_m2m_releasefunction fsl_asrc_m2m_comp_task_createfunction fsl_asrc_m2m_comp_task_startfunction fsl_asrc_m2m_comp_task_stopfunction fsl_asrc_m2m_comp_task_freefunction fsl_asrc_m2m_get_capsfunction fsl_asrc_m2m_fill_codec_capsfunction pcm_for_each_formatfunction fsl_asrc_m2m_get_codec_capsfunction fsl_asrc_m2m_suspendfunction fsl_asrc_m2m_resumefunction fsl_asrc_m2m_initfunction fsl_asrc_m2m_exitexport fsl_asrc_m2m_suspendexport fsl_asrc_m2m_resumeexport fsl_asrc_m2m_initexport fsl_asrc_m2m_exit
Annotated Snippet
if (reg32) {
*reg32++ = reg;
} else if (reg16) {
*reg16++ = (u16)reg;
} else {
*reg24++ = (u8)reg;
*reg24++ = (u8)(reg >> 8);
*reg24++ = (u8)(reg >> 16);
}
}
t_size += size;
/* In case there is data left in FIFO */
if (size)
goto retry;
end:
/* Update payload length */
if (reg32)
*length += t_size * pair->channels * 4;
else if (reg16)
*length += t_size * pair->channels * 2;
else
*length += t_size * pair->channels * 3;
}
/* config dma channel */
static int asrc_dmaconfig(struct fsl_asrc_pair *pair,
struct dma_chan *chan,
u32 dma_addr, dma_addr_t buf_addr, u32 buf_len,
int dir, int width)
{
struct fsl_asrc *asrc = pair->asrc;
struct device *dev = &asrc->pdev->dev;
struct dma_slave_config slave_config;
enum dma_slave_buswidth buswidth;
unsigned int sg_len, max_period_size;
struct scatterlist *sg;
int ret, i;
switch (width) {
case 8:
buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
break;
case 16:
buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
break;
case 24:
buswidth = DMA_SLAVE_BUSWIDTH_3_BYTES;
break;
case 32:
buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
break;
default:
dev_err(dev, "invalid word width\n");
return -EINVAL;
}
memset(&slave_config, 0, sizeof(slave_config));
if (dir == IN) {
slave_config.direction = DMA_MEM_TO_DEV;
slave_config.dst_addr = dma_addr;
slave_config.dst_addr_width = buswidth;
slave_config.dst_maxburst = asrc->m2m_get_maxburst(IN, pair);
} else {
slave_config.direction = DMA_DEV_TO_MEM;
slave_config.src_addr = dma_addr;
slave_config.src_addr_width = buswidth;
slave_config.src_maxburst = asrc->m2m_get_maxburst(OUT, pair);
}
ret = dmaengine_slave_config(chan, &slave_config);
if (ret) {
dev_err(dev, "failed to config dmaengine for %s task: %d\n",
DIR_STR(dir), ret);
return -EINVAL;
}
max_period_size = rounddown(ASRC_M2M_PERIOD_SIZE, width * pair->channels / 8);
/* scatter gather mode */
sg_len = buf_len / max_period_size;
if (buf_len % max_period_size)
sg_len += 1;
sg = kmalloc_objs(*sg, sg_len);
if (!sg)
return -ENOMEM;
sg_init_table(sg, sg_len);
for (i = 0; i < (sg_len - 1); i++) {
sg_dma_address(&sg[i]) = buf_addr + i * max_period_size;
Annotation
- Immediate include surface: `linux/dma/imx-dma.h`, `linux/dma-buf.h`, `linux/dma-mapping.h`, `linux/pm_runtime.h`, `sound/asound.h`, `sound/dmaengine_pcm.h`, `sound/initval.h`, `fsl_asrc_common.h`.
- Detected declarations: `function asrc_input_dma_callback`, `function asrc_output_dma_callback`, `function asrc_read_last_fifo`, `function asrc_dmaconfig`, `function asrc_m2m_device_run`, `function fsl_asrc_m2m_comp_open`, `function fsl_asrc_m2m_comp_release`, `function fsl_asrc_m2m_comp_set_params`, `function fsl_asrc_m2m_mmap`, `function fsl_asrc_m2m_unmap_dma_buf`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: integration implementation candidate.
- 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.