sound/soc/codecs/wm_hubs.c
Source file repositories/reference/linux-study-clean/sound/soc/codecs/wm_hubs.c
File Facts
- System
- Linux kernel
- Corpus path
sound/soc/codecs/wm_hubs.c- Extension
.c- Size
- 43186 bytes
- Lines
- 1311
- 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/delay.hlinux/pm.hlinux/i2c.hlinux/mfd/wm8994/registers.hlinux/string_choices.hsound/core.hsound/pcm.hsound/pcm_params.hsound/soc.hsound/initval.hsound/tlv.hwm8993.hwm_hubs.h
Detected Declarations
struct wm_hubs_dcs_cachefunction wait_for_dc_servofunction wm_hubs_dcs_donefunction wm_hubs_dac_hp_directfunction wm_hubs_dcs_cache_getfunction list_for_each_entryfunction wm_hubs_dcs_cache_setfunction wm_hubs_read_dc_servofunction enable_dc_servofunction wm_hubs_dcs_cache_getfunction wm8993_put_dc_servofunction hp_supply_eventfunction hp_eventfunction earpiece_eventfunction lineout_eventfunction micbias_eventfunction wm_hubs_update_class_wfunction class_w_put_volswfunction class_w_put_doublefunction wm_hubs_add_analogue_controlsfunction wm_hubs_add_analogue_routesfunction wm_hubs_handle_analogue_pdatafunction wm_hubs_vmid_enafunction wm_hubs_set_bias_levelexport wm_hubs_spkmix_tlvexport wm_hubs_dcs_doneexport wm_hubs_update_class_wexport wm_hubs_hpl_muxexport wm_hubs_hpr_muxexport wm_hubs_add_analogue_controlsexport wm_hubs_add_analogue_routesexport wm_hubs_handle_analogue_pdataexport wm_hubs_vmid_enaexport wm_hubs_set_bias_level
Annotated Snippet
struct wm_hubs_dcs_cache {
struct list_head list;
unsigned int left;
unsigned int right;
u16 dcs_cfg;
};
static bool wm_hubs_dcs_cache_get(struct snd_soc_component *component,
struct wm_hubs_dcs_cache **entry)
{
struct wm_hubs_data *hubs = snd_soc_component_get_drvdata(component);
struct wm_hubs_dcs_cache *cache;
unsigned int left, right;
left = snd_soc_component_read(component, WM8993_LEFT_OUTPUT_VOLUME);
left &= WM8993_HPOUT1L_VOL_MASK;
right = snd_soc_component_read(component, WM8993_RIGHT_OUTPUT_VOLUME);
right &= WM8993_HPOUT1R_VOL_MASK;
list_for_each_entry(cache, &hubs->dcs_cache, list) {
if (cache->left != left || cache->right != right)
continue;
*entry = cache;
return true;
}
return false;
}
static void wm_hubs_dcs_cache_set(struct snd_soc_component *component, u16 dcs_cfg)
{
struct wm_hubs_data *hubs = snd_soc_component_get_drvdata(component);
struct wm_hubs_dcs_cache *cache;
if (hubs->no_cache_dac_hp_direct)
return;
cache = devm_kzalloc(component->dev, sizeof(*cache), GFP_KERNEL);
if (!cache)
return;
cache->left = snd_soc_component_read(component, WM8993_LEFT_OUTPUT_VOLUME);
cache->left &= WM8993_HPOUT1L_VOL_MASK;
cache->right = snd_soc_component_read(component, WM8993_RIGHT_OUTPUT_VOLUME);
cache->right &= WM8993_HPOUT1R_VOL_MASK;
cache->dcs_cfg = dcs_cfg;
list_add_tail(&cache->list, &hubs->dcs_cache);
}
static int wm_hubs_read_dc_servo(struct snd_soc_component *component,
u16 *reg_l, u16 *reg_r)
{
struct wm_hubs_data *hubs = snd_soc_component_get_drvdata(component);
u16 dcs_reg, reg;
int ret = 0;
switch (hubs->dcs_readback_mode) {
case 2:
dcs_reg = WM8994_DC_SERVO_4E;
break;
case 1:
dcs_reg = WM8994_DC_SERVO_READBACK;
break;
default:
dcs_reg = WM8993_DC_SERVO_3;
break;
}
/* Different chips in the family support different readback
* methods.
*/
switch (hubs->dcs_readback_mode) {
case 0:
*reg_l = snd_soc_component_read(component, WM8993_DC_SERVO_READBACK_1)
& WM8993_DCS_INTEG_CHAN_0_MASK;
*reg_r = snd_soc_component_read(component, WM8993_DC_SERVO_READBACK_2)
& WM8993_DCS_INTEG_CHAN_1_MASK;
break;
case 2:
case 1:
reg = snd_soc_component_read(component, dcs_reg);
*reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
>> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
*reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
break;
Annotation
- Immediate include surface: `linux/module.h`, `linux/moduleparam.h`, `linux/init.h`, `linux/delay.h`, `linux/pm.h`, `linux/i2c.h`, `linux/mfd/wm8994/registers.h`, `linux/string_choices.h`.
- Detected declarations: `struct wm_hubs_dcs_cache`, `function wait_for_dc_servo`, `function wm_hubs_dcs_done`, `function wm_hubs_dac_hp_direct`, `function wm_hubs_dcs_cache_get`, `function list_for_each_entry`, `function wm_hubs_dcs_cache_set`, `function wm_hubs_read_dc_servo`, `function enable_dc_servo`, `function wm_hubs_dcs_cache_get`.
- 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.