sound/hda/core/ext/controller.c
Source file repositories/reference/linux-study-clean/sound/hda/core/ext/controller.c
File Facts
- System
- Linux kernel
- Corpus path
sound/hda/core/ext/controller.c- Extension
.c- Size
- 10380 bytes
- Lines
- 411
- Domain
- Driver Families
- Bucket
- sound/hda
- 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.
- 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/bitfield.hlinux/delay.hlinux/slab.hsound/hda_register.hsound/hdaudio_ext.h
Detected Declarations
function Copyrightfunction snd_hdac_ext_bus_ppcap_int_enablefunction snd_hdac_ext_bus_get_ml_capabilitiesfunction snd_hdac_ext_link_free_allfunction check_hdac_link_power_activefunction snd_hdac_ext_bus_link_power_upfunction snd_hdac_ext_bus_link_power_downfunction snd_hdac_ext_bus_link_power_up_allfunction list_for_each_entryfunction snd_hdac_ext_bus_link_power_down_allfunction list_for_each_entryfunction snd_hdac_ext_bus_link_set_stream_idfunction snd_hdac_ext_bus_link_clear_stream_idfunction snd_hdac_ext_bus_link_getfunction snd_hdac_ext_bus_link_putfunction list_for_each_entryfunction hdac_ext_codec_link_upfunction hdac_ext_codec_link_downfunction snd_hdac_ext_bus_link_powerexport snd_hdac_ext_bus_ppcap_enableexport snd_hdac_ext_bus_ppcap_int_enableexport snd_hdac_ext_bus_get_ml_capabilitiesexport snd_hdac_ext_link_free_allexport snd_hdac_ext_bus_get_hlink_by_idexport snd_hdac_ext_bus_get_hlink_by_addrexport snd_hdac_ext_bus_get_hlink_by_nameexport snd_hdac_ext_bus_link_power_upexport snd_hdac_ext_bus_link_power_downexport snd_hdac_ext_bus_link_power_up_allexport snd_hdac_ext_bus_link_power_down_allexport snd_hdac_ext_bus_link_set_stream_idexport snd_hdac_ext_bus_link_clear_stream_idexport snd_hdac_ext_bus_link_getexport snd_hdac_ext_bus_link_putexport snd_hdac_ext_bus_link_power
Annotated Snippet
if (hdac_ext_link_alt(hlink)) {
leptr = readl(hlink->ml_addr + AZX_REG_ML_LEPTR);
hlink->id = FIELD_GET(AZX_REG_ML_LEPTR_ID, leptr);
}
/* since link in On, update the ref */
hlink->ref_count = 1;
list_add_tail(&hlink->list, &bus->hlink_list);
}
return 0;
}
EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_get_ml_capabilities);
/**
* snd_hdac_ext_link_free_all- free hdac extended link objects
*
* @bus: the pointer to HDAC bus object
*/
void snd_hdac_ext_link_free_all(struct hdac_bus *bus)
{
struct hdac_ext_link *hlink;
while (!list_empty(&bus->hlink_list)) {
hlink = list_first_entry(&bus->hlink_list, struct hdac_ext_link, list);
list_del(&hlink->list);
kfree(hlink);
}
}
EXPORT_SYMBOL_GPL(snd_hdac_ext_link_free_all);
struct hdac_ext_link *snd_hdac_ext_bus_get_hlink_by_id(struct hdac_bus *bus, u32 id)
{
struct hdac_ext_link *hlink;
list_for_each_entry(hlink, &bus->hlink_list, list)
if (hdac_ext_link_alt(hlink) && hlink->id == id)
return hlink;
return NULL;
}
EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_get_hlink_by_id);
/**
* snd_hdac_ext_bus_get_hlink_by_addr - get hlink at specified address
* @bus: hlink's parent bus device
* @addr: codec device address
*
* Returns hlink object or NULL if matching hlink is not found.
*/
struct hdac_ext_link *snd_hdac_ext_bus_get_hlink_by_addr(struct hdac_bus *bus, int addr)
{
struct hdac_ext_link *hlink;
list_for_each_entry(hlink, &bus->hlink_list, list)
if (hlink->lsdiid & (0x1 << addr))
return hlink;
return NULL;
}
EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_get_hlink_by_addr);
/**
* snd_hdac_ext_bus_get_hlink_by_name - get hlink based on codec name
* @bus: the pointer to HDAC bus object
* @codec_name: codec name
*/
struct hdac_ext_link *snd_hdac_ext_bus_get_hlink_by_name(struct hdac_bus *bus,
const char *codec_name)
{
int bus_idx, addr;
if (sscanf(codec_name, "ehdaudio%dD%d", &bus_idx, &addr) != 2)
return NULL;
if (bus->idx != bus_idx)
return NULL;
if (addr < 0 || addr > 31)
return NULL;
return snd_hdac_ext_bus_get_hlink_by_addr(bus, addr);
}
EXPORT_SYMBOL_GPL(snd_hdac_ext_bus_get_hlink_by_name);
static int check_hdac_link_power_active(struct hdac_ext_link *hlink, bool enable)
{
int timeout;
u32 val;
int mask = (1 << AZX_ML_LCTL_CPA_SHIFT);
udelay(3);
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/delay.h`, `linux/slab.h`, `sound/hda_register.h`, `sound/hdaudio_ext.h`.
- Detected declarations: `function Copyright`, `function snd_hdac_ext_bus_ppcap_int_enable`, `function snd_hdac_ext_bus_get_ml_capabilities`, `function snd_hdac_ext_link_free_all`, `function check_hdac_link_power_active`, `function snd_hdac_ext_bus_link_power_up`, `function snd_hdac_ext_bus_link_power_down`, `function snd_hdac_ext_bus_link_power_up_all`, `function list_for_each_entry`, `function snd_hdac_ext_bus_link_power_down_all`.
- Atlas domain: Driver Families / sound/hda.
- 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.