sound/soc/fsl/fsl_asrc_dma.c
Source file repositories/reference/linux-study-clean/sound/soc/fsl/fsl_asrc_dma.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/fsl/fsl_asrc_dma.c- Extension
.c- Size
- 14844 bytes
- Lines
- 515
- 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.
- 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-mapping.hlinux/module.hlinux/dma/imx-dma.hsound/dmaengine_pcm.hsound/pcm_params.hfsl_asrc_common.h
Detected Declarations
function filterfunction fsl_asrc_dma_completefunction fsl_asrc_dma_prepare_and_submitfunction fsl_asrc_dma_triggerfunction fsl_asrc_dma_hw_paramsfunction fsl_asrc_dma_hw_freefunction fsl_asrc_dma_startupfunction fsl_asrc_dma_shutdownfunction fsl_asrc_dma_pcm_pointerfunction fsl_asrc_dma_pcm_newexport fsl_asrc_component
Annotated Snippet
if (IS_ERR(tmp_chan)) {
dev_err(dev, "failed to request DMA channel for Back-End\n");
return -EINVAL;
}
}
/*
* An EDMA DEV_TO_DEV channel is fixed and bound with DMA event of each
* peripheral, unlike SDMA channel that is allocated dynamically. So no
* need to configure dma_request and dma_request2, but get dma_chan of
* Back-End device directly via dma_request_chan.
*/
if (!asrc->use_edma) {
/* Get DMA request of Back-End */
tmp_data = tmp_chan->private;
pair->dma_data.dma_request = tmp_data->dma_request;
be_peripheral_type = tmp_data->peripheral_type;
if (!be_chan)
dma_release_channel(tmp_chan);
/* Get DMA request of Front-End */
tmp_chan = asrc->get_dma_channel(pair, dir);
tmp_data = tmp_chan->private;
pair->dma_data.dma_request2 = tmp_data->dma_request;
pair->dma_data.peripheral_type = tmp_data->peripheral_type;
pair->dma_data.priority = tmp_data->priority;
dma_release_channel(tmp_chan);
of_dma_node = pair->dma_chan[!dir]->device->dev->of_node;
pair->dma_chan[dir] =
__dma_request_channel(&mask, filter, &pair->dma_data,
of_dma_node);
pair->req_dma_chan = true;
} else {
pair->dma_chan[dir] = tmp_chan;
/* Do not flag to release if we are reusing the Back-End one */
pair->req_dma_chan = !be_chan;
}
if (!pair->dma_chan[dir]) {
dev_err(dev, "failed to request DMA channel for Back-End\n");
return -EINVAL;
}
width = snd_pcm_format_physical_width(asrc->asrc_format);
if (width < 8 || width > 64)
return -EINVAL;
else if (width == 8)
buswidth = DMA_SLAVE_BUSWIDTH_1_BYTE;
else if (width == 16)
buswidth = DMA_SLAVE_BUSWIDTH_2_BYTES;
else if (width == 24)
buswidth = DMA_SLAVE_BUSWIDTH_3_BYTES;
else if (width <= 32)
buswidth = DMA_SLAVE_BUSWIDTH_4_BYTES;
else
buswidth = DMA_SLAVE_BUSWIDTH_8_BYTES;
config_be.direction = DMA_DEV_TO_DEV;
config_be.src_addr_width = buswidth;
config_be.src_maxburst = dma_params_be->maxburst;
config_be.dst_addr_width = buswidth;
config_be.dst_maxburst = dma_params_be->maxburst;
memset(&audio_config, 0, sizeof(audio_config));
config_be.peripheral_config = &audio_config;
config_be.peripheral_size = sizeof(audio_config);
if (tx && (be_peripheral_type == IMX_DMATYPE_SSI_DUAL ||
be_peripheral_type == IMX_DMATYPE_SPDIF))
audio_config.n_fifos_dst = 2;
if (!tx && (be_peripheral_type == IMX_DMATYPE_SSI_DUAL ||
be_peripheral_type == IMX_DMATYPE_SPDIF))
audio_config.n_fifos_src = 2;
if (tx) {
config_be.src_addr = asrc->paddr + asrc->get_fifo_addr(OUT, index);
config_be.dst_addr = dma_params_be->addr;
} else {
config_be.dst_addr = asrc->paddr + asrc->get_fifo_addr(IN, index);
config_be.src_addr = dma_params_be->addr;
}
ret = dmaengine_slave_config(pair->dma_chan[dir], &config_be);
if (ret) {
dev_err(dev, "failed to config DMA channel for Back-End\n");
if (pair->req_dma_chan)
dma_release_channel(pair->dma_chan[dir]);
return ret;
}
Annotation
- Immediate include surface: `linux/dma-mapping.h`, `linux/module.h`, `linux/dma/imx-dma.h`, `sound/dmaengine_pcm.h`, `sound/pcm_params.h`, `fsl_asrc_common.h`.
- Detected declarations: `function filter`, `function fsl_asrc_dma_complete`, `function fsl_asrc_dma_prepare_and_submit`, `function fsl_asrc_dma_trigger`, `function fsl_asrc_dma_hw_params`, `function fsl_asrc_dma_hw_free`, `function fsl_asrc_dma_startup`, `function fsl_asrc_dma_shutdown`, `function fsl_asrc_dma_pcm_pointer`, `function fsl_asrc_dma_pcm_new`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: integration 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.