sound/hda/core/controller.c
Source file repositories/reference/linux-study-clean/sound/hda/core/controller.c
File Facts
- System
- Linux kernel
- Corpus path
sound/hda/core/controller.c- Extension
.c- Size
- 20173 bytes
- Lines
- 767
- 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.
- 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/kernel.hlinux/delay.hlinux/export.hsound/core.hsound/hdaudio.hsound/hda_register.hlocal.h
Detected Declarations
function azx_clear_corbrpfunction snd_hdac_bus_init_cmd_iofunction hdac_wait_for_cmd_dmasfunction snd_hdac_bus_stop_cmd_iofunction azx_command_addrfunction snd_hdac_bus_wait_for_pio_responsefunction snd_hdac_bus_send_cmd_piofunction snd_hdac_bus_get_response_piofunction snd_hdac_bus_send_cmd_corbfunction snd_hdac_bus_update_rirbfunction snd_hdac_bus_get_response_rirbfunction scoped_guardfunction snd_hdac_bus_send_cmdfunction snd_hdac_bus_get_responsefunction snd_hdac_bus_parse_capabilitiesfunction snd_hdac_bus_enter_link_resetfunction snd_hdac_bus_exit_link_resetfunction snd_hdac_bus_reset_linkfunction azx_int_enablefunction azx_int_disablefunction azx_int_clearfunction snd_hdac_bus_init_chipfunction snd_hdac_bus_stop_chipfunction snd_hdac_bus_handle_stream_irqfunction list_for_each_entryfunction snd_hdac_bus_alloc_stream_pagesfunction list_for_each_entryfunction snd_hdac_bus_free_stream_pagesfunction list_for_each_entryfunction snd_hdac_bus_link_powerexport snd_hdac_bus_init_cmd_ioexport snd_hdac_bus_stop_cmd_ioexport snd_hdac_bus_update_rirbexport snd_hdac_bus_send_cmdexport snd_hdac_bus_get_responseexport snd_hdac_bus_parse_capabilitiesexport snd_hdac_bus_enter_link_resetexport snd_hdac_bus_exit_link_resetexport snd_hdac_bus_reset_linkexport snd_hdac_bus_init_chipexport snd_hdac_bus_stop_chipexport snd_hdac_bus_handle_stream_irqexport snd_hdac_bus_alloc_stream_pagesexport snd_hdac_bus_free_stream_pagesexport snd_hdac_bus_link_power
Annotated Snippet
if (snd_hdac_chip_readw(bus, IRS) & AZX_IRS_VALID) {
/* reuse rirb.res as the response return value */
bus->rirb.res[addr] = snd_hdac_chip_readl(bus, IR);
return 0;
}
udelay(1);
}
dev_dbg_ratelimited(bus->dev, "get_response_pio timeout: IRS=%#x\n",
snd_hdac_chip_readw(bus, IRS));
bus->rirb.res[addr] = -1;
return -EIO;
}
/**
* snd_hdac_bus_send_cmd_pio - send a command verb via Immediate Command
* @bus: HD-audio core bus
* @val: encoded verb value to send
*
* Returns zero for success or a negative error code.
*/
static int snd_hdac_bus_send_cmd_pio(struct hdac_bus *bus, unsigned int val)
{
unsigned int addr = azx_command_addr(val);
int timeout = 50;
guard(spinlock_irq)(&bus->reg_lock);
while (timeout--) {
/* check ICB bit */
if (!((snd_hdac_chip_readw(bus, IRS) & AZX_IRS_BUSY))) {
/* Clear IRV bit */
snd_hdac_chip_updatew(bus, IRS, AZX_IRS_VALID, AZX_IRS_VALID);
snd_hdac_chip_writel(bus, IC, val);
/* Set ICB bit */
snd_hdac_chip_updatew(bus, IRS, AZX_IRS_BUSY, AZX_IRS_BUSY);
return snd_hdac_bus_wait_for_pio_response(bus, addr);
}
udelay(1);
}
dev_dbg_ratelimited(bus->dev, "send_cmd_pio timeout: IRS=%#x, val=%#x\n",
snd_hdac_chip_readw(bus, IRS), val);
return -EIO;
}
/**
* snd_hdac_bus_get_response_pio - receive a response via Immediate Response
* @bus: HD-audio core bus
* @addr: codec address
* @res: pointer to store the value, NULL when not needed
*
* Returns zero if a value is read, or a negative error code.
*/
static int snd_hdac_bus_get_response_pio(struct hdac_bus *bus,
unsigned int addr, unsigned int *res)
{
if (res)
*res = bus->rirb.res[addr];
return 0;
}
/**
* snd_hdac_bus_send_cmd_corb - send a command verb via CORB
* @bus: HD-audio core bus
* @val: encoded verb value to send
*
* Returns zero for success or a negative error code.
*/
static int snd_hdac_bus_send_cmd_corb(struct hdac_bus *bus, unsigned int val)
{
unsigned int addr = azx_command_addr(val);
unsigned int wp, rp;
guard(spinlock_irq)(&bus->reg_lock);
bus->last_cmd[azx_command_addr(val)] = val;
/* add command to corb */
wp = snd_hdac_chip_readw(bus, CORBWP);
if (wp == 0xffff) {
/* something wrong, controller likely turned to D3 */
return -EIO;
}
wp++;
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/delay.h`, `linux/export.h`, `sound/core.h`, `sound/hdaudio.h`, `sound/hda_register.h`, `local.h`.
- Detected declarations: `function azx_clear_corbrp`, `function snd_hdac_bus_init_cmd_io`, `function hdac_wait_for_cmd_dmas`, `function snd_hdac_bus_stop_cmd_io`, `function azx_command_addr`, `function snd_hdac_bus_wait_for_pio_response`, `function snd_hdac_bus_send_cmd_pio`, `function snd_hdac_bus_get_response_pio`, `function snd_hdac_bus_send_cmd_corb`, `function snd_hdac_bus_update_rirb`.
- Atlas domain: Driver Families / sound/hda.
- 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.