sound/soc/codecs/hda.c
Source file repositories/reference/linux-study-clean/sound/soc/codecs/hda.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/codecs/hda.c- Extension
.c- Size
- 11048 bytes
- Lines
- 397
- 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.
- 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/module.hlinux/pm_runtime.hsound/soc.hsound/hdaudio_ext.hsound/hda_i915.hsound/hda_codec.hhda.h
Detected Declarations
function hda_codec_create_daisfunction hda_codec_register_daisfunction list_for_each_entryfunction hda_codec_unregister_daisfunction for_each_component_dais_safefunction list_for_each_entryfunction hda_codec_probe_completefunction hda_codec_probefunction hda_codec_removefunction hda_hdev_attachfunction hda_hdev_detachexport hda_codec_probe_completeexport soc_hda_ext_bus_ops
Annotated Snippet
if (!pcm->stream[dir].substreams) {
dev_info(dev, "skipping playback dai for %s\n", pcm->name);
goto capture_dais;
}
stream->stream_name =
devm_kasprintf(dev, GFP_KERNEL, "%s %s", pcm->name,
snd_pcm_direction_name(dir));
if (!stream->stream_name)
return -ENOMEM;
stream->channels_min = pcm->stream[dir].channels_min;
stream->channels_max = pcm->stream[dir].channels_max;
stream->rates = pcm->stream[dir].rates;
stream->formats = pcm->stream[dir].formats;
stream->subformats = pcm->stream[dir].subformats;
stream->sig_bits = pcm->stream[dir].maxbps;
capture_dais:
dir = SNDRV_PCM_STREAM_CAPTURE;
stream = &drvs[i].capture;
if (!pcm->stream[dir].substreams) {
dev_info(dev, "skipping capture dai for %s\n", pcm->name);
continue;
}
stream->stream_name =
devm_kasprintf(dev, GFP_KERNEL, "%s %s", pcm->name,
snd_pcm_direction_name(dir));
if (!stream->stream_name)
return -ENOMEM;
stream->channels_min = pcm->stream[dir].channels_min;
stream->channels_max = pcm->stream[dir].channels_max;
stream->rates = pcm->stream[dir].rates;
stream->formats = pcm->stream[dir].formats;
stream->subformats = pcm->stream[dir].subformats;
stream->sig_bits = pcm->stream[dir].maxbps;
}
*drivers = drvs;
return 0;
}
static int hda_codec_register_dais(struct hda_codec *codec, struct snd_soc_component *component)
{
struct snd_soc_dai_driver *drvs = NULL;
struct snd_soc_dapm_context *dapm;
struct hda_pcm *pcm;
int ret, pcm_count = 0;
if (list_empty(&codec->pcm_list_head))
return -EINVAL;
list_for_each_entry(pcm, &codec->pcm_list_head, list)
pcm_count++;
ret = hda_codec_create_dais(codec, pcm_count, &drvs);
if (ret < 0)
return ret;
dapm = snd_soc_component_to_dapm(component);
list_for_each_entry(pcm, &codec->pcm_list_head, list) {
struct snd_soc_dai *dai;
dai = snd_soc_register_dai(component, drvs, false);
if (!dai) {
dev_err(component->dev, "register dai for %s failed\n", pcm->name);
return -EINVAL;
}
ret = snd_soc_dapm_new_dai_widgets(dapm, dai);
if (ret < 0) {
dev_err(component->dev, "create widgets failed: %d\n", ret);
snd_soc_unregister_dai(dai);
return ret;
}
snd_soc_dai_init_dma_data(dai, &pcm->stream[0], &pcm->stream[1]);
drvs++;
}
return 0;
}
static void hda_codec_unregister_dais(struct hda_codec *codec,
struct snd_soc_component *component)
{
struct snd_soc_dai *dai, *save;
struct hda_pcm *pcm;
for_each_component_dais_safe(component, dai, save) {
Annotation
- Immediate include surface: `linux/module.h`, `linux/pm_runtime.h`, `sound/soc.h`, `sound/hdaudio_ext.h`, `sound/hda_i915.h`, `sound/hda_codec.h`, `hda.h`.
- Detected declarations: `function hda_codec_create_dais`, `function hda_codec_register_dais`, `function list_for_each_entry`, `function hda_codec_unregister_dais`, `function for_each_component_dais_safe`, `function list_for_each_entry`, `function hda_codec_probe_complete`, `function hda_codec_probe`, `function hda_codec_remove`, `function hda_hdev_attach`.
- Atlas domain: Driver Families / sound/soc.
- Implementation status: integration 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.