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.

Dependency Surface

Detected Declarations

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

Implementation Notes