sound/soc/sof/pcm.c
Source file repositories/reference/linux-study-clean/sound/soc/sof/pcm.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/sof/pcm.c- Extension
.c- Size
- 24957 bytes
- Lines
- 871
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/pm_runtime.hsound/pcm_params.hsound/sof.htrace/events/sof.hsof-of-dev.hsof-priv.hsof-audio.hsof-utils.hops.h
Detected Declarations
function snd_sof_pcm_period_elapsed_workfunction snd_sof_pcm_init_elapsed_workfunction snd_sof_pcm_period_elapsedfunction sof_pcm_setup_connected_widgetsfunction list_for_each_entryfunction sof_pcm_hw_paramsfunction hw_paramsfunction sof_pcm_stream_freefunction sof_pcm_free_all_streamsfunction list_for_each_entryfunction sof_pcm_hw_freefunction sof_pcm_preparefunction sof_pcm_triggerfunction sof_pcm_pointerfunction sof_pcm_openfunction sof_pcm_closefunction snd_pcm_lib_preallocate_free_for_allfunction sof_pcm_dai_link_fixupfunction sof_pcm_probefunction sof_pcm_removefunction sof_pcm_ackfunction sof_pcm_delayfunction snd_sof_new_platform_drvexport snd_sof_pcm_period_elapsedexport sof_pcm_dai_link_fixup
Annotated Snippet
if (ret < 0) {
spcm_err(spcm, dir, "dai %s has no valid %s path\n",
dai->name, snd_pcm_direction_name(dir));
return ret;
}
spcm->stream[dir].list = list;
ret = sof_widget_list_prepare(sdev, spcm, params, platform_params, dir);
if (ret < 0) {
spcm_err(spcm, dir, "widget list prepare failed\n");
spcm->stream[dir].list = NULL;
snd_soc_dapm_dai_free_widgets(&list);
return ret;
}
}
return 0;
}
static struct snd_sof_widget *snd_sof_find_swidget_by_comp_id(struct snd_sof_dev *sdev,
int comp_id)
{
struct snd_sof_widget *swidget;
list_for_each_entry(swidget, &sdev->widget_list, list) {
if (comp_id == swidget->comp_id)
return swidget;
}
return NULL;
}
static int sof_pcm_hw_params(struct snd_soc_component *component,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
const struct sof_ipc_tplg_ops *tplg_ops = sof_ipc_get_ops(sdev, tplg);
const struct sof_ipc_pcm_ops *pcm_ops = sof_ipc_get_ops(sdev, pcm);
struct snd_sof_platform_stream_params *platform_params;
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_sof_widget *host_widget;
struct snd_sof_pcm *spcm;
int ret;
/* nothing to do for BE */
if (rtd->dai_link->no_pcm)
return 0;
spcm = snd_sof_find_spcm_dai(component, rtd);
if (!spcm)
return -EINVAL;
spcm_dbg(spcm, substream->stream, "Entry: hw_params\n");
if (!sdev->dspless_mode_selected) {
/*
* Make sure that the DSP is booted up, which might not be the
* case if the on-demand DSP boot is used
*/
ret = snd_sof_boot_dsp_firmware(sdev);
if (ret)
return ret;
}
/*
* Handle repeated calls to hw_params() without free_pcm() in
* between. At least ALSA OSS emulation depends on this.
*/
if (spcm->prepared[substream->stream] && pcm_ops && pcm_ops->hw_free) {
ret = pcm_ops->hw_free(component, substream);
if (ret < 0)
return ret;
spcm->prepared[substream->stream] = false;
}
platform_params = &spcm->platform_params[substream->stream];
ret = snd_sof_pcm_platform_hw_params(sdev, substream, params, platform_params);
if (ret < 0) {
spcm_err(spcm, substream->stream, "platform hw params failed\n");
return ret;
}
/* if this is a repeated hw_params without hw_free, skip setting up widgets */
if (!spcm->stream[substream->stream].list) {
ret = sof_pcm_setup_connected_widgets(sdev, rtd, spcm, params, platform_params,
substream->stream);
Annotation
- Immediate include surface: `linux/pm_runtime.h`, `sound/pcm_params.h`, `sound/sof.h`, `trace/events/sof.h`, `sof-of-dev.h`, `sof-priv.h`, `sof-audio.h`, `sof-utils.h`.
- Detected declarations: `function snd_sof_pcm_period_elapsed_work`, `function snd_sof_pcm_init_elapsed_work`, `function snd_sof_pcm_period_elapsed`, `function sof_pcm_setup_connected_widgets`, `function list_for_each_entry`, `function sof_pcm_hw_params`, `function hw_params`, `function sof_pcm_stream_free`, `function sof_pcm_free_all_streams`, `function list_for_each_entry`.
- 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.