sound/soc/intel/avs/pcm.c

Source file repositories/reference/linux-study-clean/sound/soc/intel/avs/pcm.c

File Facts

System
Linux kernel
Corpus path
sound/soc/intel/avs/pcm.c
Extension
.c
Size
49436 bytes
Lines
1774
Domain
Driver Families
Bucket
sound/soc
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern 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

static const struct file_operations topology_name_fops = {
	.open = simple_open,
	.read = topology_name_read,
	.llseek = default_llseek,
};

static int avs_component_load_libraries(struct avs_soc_component *acomp)
{
	struct avs_tplg *tplg = acomp->tplg;
	struct avs_dev *adev = to_avs_dev(acomp->base.dev);
	int ret;

	if (!tplg->num_libs)
		return 0;

	/* Parent device may be asleep and library loading involves IPCs. */
	ret = pm_runtime_resume_and_get(adev->dev);
	if (ret < 0)
		return ret;

	avs_hda_power_gating_enable(adev, false);
	avs_hda_clock_gating_enable(adev, false);
	avs_hda_l1sen_enable(adev, false);

	ret = avs_dsp_load_libraries(adev, tplg->libs, tplg->num_libs);

	avs_hda_l1sen_enable(adev, true);
	avs_hda_clock_gating_enable(adev, true);
	avs_hda_power_gating_enable(adev, true);

	if (!ret)
		ret = avs_module_info_init(adev, false);

	pm_runtime_put_autosuspend(adev->dev);

	return ret;
}

static int avs_component_probe(struct snd_soc_component *component)
{
	struct snd_soc_card *card = component->card;
	struct snd_soc_acpi_mach *mach;
	struct avs_soc_component *acomp;
	struct avs_dev *adev;
	char *filename;
	int ret;

	dev_dbg(card->dev, "probing %s card %s\n", component->name, card->name);
	mach = dev_get_platdata(card->dev);
	acomp = to_avs_soc_component(component);
	adev = to_avs_dev(component->dev);

	acomp->tplg = avs_tplg_new(component);
	if (!acomp->tplg)
		return -ENOMEM;

	if (!mach->tplg_filename)
		goto finalize;

	/* Load specified topology and create debugfs for it. */
	filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
			     mach->tplg_filename);
	if (!filename)
		return -ENOMEM;

	ret = avs_load_topology(component, filename);
	kfree(filename);
	if (ret == -ENOENT && !strncmp(mach->tplg_filename, "hda-", 4)) {
		unsigned int vendor_id;

		if (sscanf(mach->tplg_filename, "hda-%08x-tplg.bin", &vendor_id) != 1)
			return ret;

		if (((vendor_id >> 16) & 0xFFFF) == 0x8086)
			mach->tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL,
							     "hda-8086-generic-tplg.bin");
		else
			mach->tplg_filename = devm_kasprintf(adev->dev, GFP_KERNEL,
							     "hda-generic-tplg.bin");
		if (!mach->tplg_filename)
			return -ENOMEM;
		filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
				     mach->tplg_filename);
		if (!filename)
			return -ENOMEM;

		dev_info(card->dev, "trying to load fallback topology %s\n", mach->tplg_filename);
		ret = avs_load_topology(component, filename);
		kfree(filename);
	}

Annotation

Implementation Notes