sound/soc/codecs/wm8804.c
Source file repositories/reference/linux-study-clean/sound/soc/codecs/wm8804.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/codecs/wm8804.c- Extension
.c- Size
- 18328 bytes
- Lines
- 723
- 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/moduleparam.hlinux/init.hlinux/gpio/consumer.hlinux/delay.hlinux/pm.hlinux/pm_runtime.hlinux/regulator/consumer.hlinux/slab.hsound/core.hsound/pcm.hsound/pcm_params.hsound/soc.hsound/initval.hsound/tlv.hsound/soc-dapm.hwm8804.h
Detected Declarations
struct wm8804_privstruct pll_divfunction wm8804_aif_eventfunction txsrc_putfunction wm8804_volatilefunction wm8804_soft_resetfunction wm8804_set_fmtfunction wm8804_hw_paramsfunction pll_factorsfunction wm8804_set_pllfunction wm8804_set_sysclkfunction wm8804_set_clkdivfunction wm8804_probefunction wm8804_removefunction wm8804_runtime_resumefunction wm8804_runtime_suspendexport wm8804_regmap_configexport wm8804_probeexport wm8804_remove
Annotated Snippet
struct wm8804_priv {
struct device *dev;
struct regmap *regmap;
struct regulator_bulk_data supplies[WM8804_NUM_SUPPLIES];
struct notifier_block disable_nb[WM8804_NUM_SUPPLIES];
int mclk_div;
struct gpio_desc *reset;
int aif_pwr;
};
static int txsrc_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
static int wm8804_aif_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
/*
* We can't use the same notifier block for more than one supply and
* there's no way I can see to get from a callback to the caller
* except container_of().
*/
#define WM8804_REGULATOR_EVENT(n) \
static int wm8804_regulator_event_##n(struct notifier_block *nb, \
unsigned long event, void *data) \
{ \
struct wm8804_priv *wm8804 = container_of(nb, struct wm8804_priv, \
disable_nb[n]); \
if (event & REGULATOR_EVENT_DISABLE) { \
regcache_mark_dirty(wm8804->regmap); \
} \
return 0; \
}
WM8804_REGULATOR_EVENT(0)
WM8804_REGULATOR_EVENT(1)
static const char *txsrc_text[] = { "S/PDIF RX", "AIF" };
static SOC_ENUM_SINGLE_DECL(txsrc, WM8804_SPDTX4, 6, txsrc_text);
static const struct snd_kcontrol_new wm8804_tx_source_mux[] = {
SOC_DAPM_ENUM_EXT("Input Source", txsrc,
snd_soc_dapm_get_enum_double, txsrc_put),
};
static const struct snd_soc_dapm_widget wm8804_dapm_widgets[] = {
SND_SOC_DAPM_OUTPUT("SPDIF Out"),
SND_SOC_DAPM_INPUT("SPDIF In"),
SND_SOC_DAPM_PGA("SPDIFTX", WM8804_PWRDN, 2, 1, NULL, 0),
SND_SOC_DAPM_PGA("SPDIFRX", WM8804_PWRDN, 1, 1, NULL, 0),
SND_SOC_DAPM_MUX("Tx Source", SND_SOC_NOPM, 6, 0, wm8804_tx_source_mux),
SND_SOC_DAPM_AIF_OUT_E("AIFTX", NULL, 0, SND_SOC_NOPM, 0, 0, wm8804_aif_event,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_AIF_IN_E("AIFRX", NULL, 0, SND_SOC_NOPM, 0, 0, wm8804_aif_event,
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
};
static const struct snd_soc_dapm_route wm8804_dapm_routes[] = {
{ "AIFRX", NULL, "Playback" },
{ "Tx Source", "AIF", "AIFRX" },
{ "SPDIFRX", NULL, "SPDIF In" },
{ "Tx Source", "S/PDIF RX", "SPDIFRX" },
{ "SPDIFTX", NULL, "Tx Source" },
{ "SPDIF Out", NULL, "SPDIFTX" },
{ "AIFTX", NULL, "SPDIFRX" },
{ "Capture", NULL, "AIFTX" },
};
static int wm8804_aif_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct wm8804_priv *wm8804 = snd_soc_component_get_drvdata(component);
switch (event) {
case SND_SOC_DAPM_POST_PMU:
/* power up the aif */
if (!wm8804->aif_pwr)
snd_soc_component_update_bits(component, WM8804_PWRDN, 0x10, 0x0);
wm8804->aif_pwr++;
break;
case SND_SOC_DAPM_POST_PMD:
/* power down only both paths are disabled */
Annotation
- Immediate include surface: `linux/module.h`, `linux/moduleparam.h`, `linux/init.h`, `linux/gpio/consumer.h`, `linux/delay.h`, `linux/pm.h`, `linux/pm_runtime.h`, `linux/regulator/consumer.h`.
- Detected declarations: `struct wm8804_priv`, `struct pll_div`, `function wm8804_aif_event`, `function txsrc_put`, `function wm8804_volatile`, `function wm8804_soft_reset`, `function wm8804_set_fmt`, `function wm8804_hw_params`, `function pll_factors`, `function wm8804_set_pll`.
- 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.