sound/hda/core/intel-nhlt.c

Source file repositories/reference/linux-study-clean/sound/hda/core/intel-nhlt.c

File Facts

System
Linux kernel
Corpus path
sound/hda/core/intel-nhlt.c
Extension
.c
Size
10929 bytes
Lines
389
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 (fmt_configs->fmt_count) {
			struct nhlt_fmt_cfg *fmt_cfg = fmt_configs->fmt_config;

			dev_dbg(dev, "found %d format definitions\n",
				fmt_configs->fmt_count);

			for (i = 0; i < fmt_configs->fmt_count; i++) {
				struct wav_fmt_ext *fmt_ext;

				fmt_ext = &fmt_cfg->fmt_ext;

				if (fmt_ext->fmt.channels > max_ch)
					max_ch = fmt_ext->fmt.channels;

				/* Move to the next nhlt_fmt_cfg */
				fmt_cfg = (struct nhlt_fmt_cfg *)(fmt_cfg->config.caps +
								  fmt_cfg->config.size);
			}
			dev_dbg(dev, "max channels found %d\n", max_ch);
		} else {
			dev_dbg(dev, "No format information found\n");
		}

		if (cfg->device_config.config_type != NHLT_CONFIG_TYPE_MIC_ARRAY) {
			dmic_geo = max_ch;
		} else {
			switch (cfg->array_type) {
			case NHLT_MIC_ARRAY_2CH_SMALL:
			case NHLT_MIC_ARRAY_2CH_BIG:
				dmic_geo = MIC_ARRAY_2CH;
				break;

			case NHLT_MIC_ARRAY_4CH_1ST_GEOM:
			case NHLT_MIC_ARRAY_4CH_L_SHAPED:
			case NHLT_MIC_ARRAY_4CH_2ND_GEOM:
				dmic_geo = MIC_ARRAY_4CH;
				break;
			case NHLT_MIC_ARRAY_VENDOR_DEFINED:
				cfg_vendor = (struct nhlt_vendor_dmic_array_config *)cfg;
				dmic_geo = cfg_vendor->nb_mics;
				break;
			default:
				dev_warn(dev, "%s: undefined DMIC array_type 0x%0x\n",
					 __func__, cfg->array_type);
			}

			if (dmic_geo > 0) {
				dev_dbg(dev, "Array with %d dmics\n", dmic_geo);
			}
			if (max_ch > dmic_geo) {
				dev_dbg(dev, "max channels %d exceed dmic number %d\n",
					max_ch, dmic_geo);
			}
		}
	}

	dev_dbg(dev, "dmic number %d max_ch %d\n", dmic_geo, max_ch);

	return dmic_geo;
}
EXPORT_SYMBOL_GPL(intel_nhlt_get_dmic_geo);

bool intel_nhlt_has_endpoint_type(struct nhlt_acpi_table *nhlt, u8 link_type)
{
	struct nhlt_endpoint *epnt;
	int i;

	if (!nhlt)
		return false;

	epnt = (struct nhlt_endpoint *)nhlt->desc;
	for (i = 0; i < nhlt->endpoint_count; i++) {
		if (epnt->linktype == link_type)
			return true;

		epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length);
	}
	return false;
}
EXPORT_SYMBOL(intel_nhlt_has_endpoint_type);

int intel_nhlt_ssp_endpoint_mask(struct nhlt_acpi_table *nhlt, u8 device_type)
{
	struct nhlt_endpoint *epnt;
	int ssp_mask = 0;
	int i;

	if (!nhlt || (device_type != NHLT_DEVICE_BT && device_type != NHLT_DEVICE_I2S))
		return 0;

Annotation

Implementation Notes