sound/soc/codecs/wm8350.c
Source file repositories/reference/linux-study-clean/sound/soc/codecs/wm8350.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/codecs/wm8350.c- Extension
.c- Size
- 49199 bytes
- Lines
- 1639
- 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/module.hlinux/moduleparam.hlinux/init.hlinux/slab.hlinux/delay.hlinux/pm.hlinux/platform_device.hlinux/mfd/wm8350/audio.hlinux/mfd/wm8350/core.hlinux/regulator/consumer.hsound/core.hsound/pcm.hsound/pcm_params.hsound/soc.hsound/initval.hsound/tlv.htrace/events/asoc.hwm8350.h
Detected Declarations
struct wm8350_outputstruct wm8350_jack_datastruct wm8350_datastruct _fll_divfunction wm8350_out1_ramp_stepfunction wm8350_out2_ramp_stepfunction wm8350_pga_workfunction pga_eventfunction wm8350_put_volsw_2r_vufunction wm8350_get_volsw_2rfunction wm8350_set_dai_sysclkfunction wm8350_set_clkdivfunction wm8350_set_dai_fmtfunction wm8350_pcm_hw_paramsfunction wm8350_mutefunction fll_factorsfunction wm8350_set_fllfunction wm8350_set_bias_levelfunction wm8350_hp_workfunction wm8350_hpl_workfunction wm8350_hpr_workfunction wm8350_hpl_jack_handlerfunction wm8350_hpr_jack_handlerfunction wm8350_hp_jack_detectfunction wm8350_mic_handlerfunction wm8350_mic_jack_detectfunction wm8350_component_probefunction wm8350_component_removefunction wm8350_probeexport wm8350_hp_jack_detectexport wm8350_mic_jack_detect
Annotated Snippet
struct wm8350_output {
u16 active;
u16 left_vol;
u16 right_vol;
u16 ramp;
u16 mute;
};
struct wm8350_jack_data {
struct snd_soc_jack *jack;
struct delayed_work work;
int report;
int short_report;
};
struct wm8350_data {
struct wm8350 *wm8350;
struct wm8350_output out1;
struct wm8350_output out2;
struct wm8350_jack_data hpl;
struct wm8350_jack_data hpr;
struct wm8350_jack_data mic;
struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
int fll_freq_out;
int fll_freq_in;
struct delayed_work pga_work;
};
/*
* Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown.
*/
static inline int wm8350_out1_ramp_step(struct wm8350_data *wm8350_data)
{
struct wm8350_output *out1 = &wm8350_data->out1;
struct wm8350 *wm8350 = wm8350_data->wm8350;
int left_complete = 0, right_complete = 0;
u16 reg, val;
/* left channel */
reg = wm8350_reg_read(wm8350, WM8350_LOUT1_VOLUME);
val = (reg & WM8350_OUT1L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
if (out1->ramp == WM8350_RAMP_UP) {
/* ramp step up */
if (val < out1->left_vol) {
val++;
reg &= ~WM8350_OUT1L_VOL_MASK;
wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME,
reg | (val << WM8350_OUT1L_VOL_SHIFT));
} else
left_complete = 1;
} else if (out1->ramp == WM8350_RAMP_DOWN) {
/* ramp step down */
if (val > 0) {
val--;
reg &= ~WM8350_OUT1L_VOL_MASK;
wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME,
reg | (val << WM8350_OUT1L_VOL_SHIFT));
} else
left_complete = 1;
} else
return 1;
/* right channel */
reg = wm8350_reg_read(wm8350, WM8350_ROUT1_VOLUME);
val = (reg & WM8350_OUT1R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
if (out1->ramp == WM8350_RAMP_UP) {
/* ramp step up */
if (val < out1->right_vol) {
val++;
reg &= ~WM8350_OUT1R_VOL_MASK;
wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME,
reg | (val << WM8350_OUT1R_VOL_SHIFT));
} else
right_complete = 1;
} else if (out1->ramp == WM8350_RAMP_DOWN) {
/* ramp step down */
if (val > 0) {
val--;
reg &= ~WM8350_OUT1R_VOL_MASK;
wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME,
reg | (val << WM8350_OUT1R_VOL_SHIFT));
} else
right_complete = 1;
}
/* only hit the update bit if either volume has changed this step */
if (!left_complete || !right_complete)
wm8350_set_bits(wm8350, WM8350_LOUT1_VOLUME, WM8350_OUT1_VU);
Annotation
- Immediate include surface: `linux/module.h`, `linux/moduleparam.h`, `linux/init.h`, `linux/slab.h`, `linux/delay.h`, `linux/pm.h`, `linux/platform_device.h`, `linux/mfd/wm8350/audio.h`.
- Detected declarations: `struct wm8350_output`, `struct wm8350_jack_data`, `struct wm8350_data`, `struct _fll_div`, `function wm8350_out1_ramp_step`, `function wm8350_out2_ramp_step`, `function wm8350_pga_work`, `function pga_event`, `function wm8350_put_volsw_2r_vu`, `function wm8350_get_volsw_2r`.
- 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.