sound/soc/intel/avs/board_selection.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/intel/avs/board_selection.c
Extension
.c
Size
15800 bytes
Lines
676
Domain
Driver Families
Bucket
sound/soc
Inferred role
Driver Families: implementation source
Status
source 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

struct avs_acpi_boards {
	int id;
	struct snd_soc_acpi_mach *machs;
};

#define AVS_MACH_ENTRY(_id, _mach) \
	{ .id = PCI_DEVICE_ID_INTEL_##_id, .machs = (_mach), }

/* supported I2S boards per platform */
static const struct avs_acpi_boards i2s_boards[] = {
	AVS_MACH_ENTRY(HDA_SKL_LP,	avs_skl_i2s_machines),
	AVS_MACH_ENTRY(HDA_KBL_LP,	avs_kbl_i2s_machines),
	AVS_MACH_ENTRY(HDA_APL,		avs_apl_i2s_machines),
	AVS_MACH_ENTRY(HDA_GLK,		avs_gml_i2s_machines),
	AVS_MACH_ENTRY(HDA_CNL_LP,	avs_cnl_i2s_machines),
	AVS_MACH_ENTRY(HDA_CNL_H,	avs_cnl_i2s_machines),
	AVS_MACH_ENTRY(HDA_CML_LP,	avs_cnl_i2s_machines),
	AVS_MACH_ENTRY(HDA_ICL_LP,	avs_icl_i2s_machines),
	AVS_MACH_ENTRY(HDA_TGL_LP,	avs_tgl_i2s_machines),
	AVS_MACH_ENTRY(HDA_EHL_0,	avs_tgl_i2s_machines),
	AVS_MACH_ENTRY(HDA_ADL_N,	avs_mbl_i2s_machines),
	AVS_MACH_ENTRY(HDA_ADL_P,	avs_tgl_i2s_machines),
	AVS_MACH_ENTRY(HDA_RPL_P_0,	avs_tgl_i2s_machines),
	AVS_MACH_ENTRY(HDA_RPL_M,	avs_mbl_i2s_machines),
	AVS_MACH_ENTRY(HDA_FCL,		avs_tgl_i2s_machines),
	{ },
};

static struct snd_soc_acpi_mach *avs_get_i2s_machines(struct avs_dev *adev)
{
	int id, i;

	id = adev->base.pci->device;
	for (i = 0; i < ARRAY_SIZE(i2s_boards); i++)
		if (i2s_boards[i].id == id)
			return i2s_boards[i].machs;
	return NULL;
}

/* Platform devices spawned by AVS driver are removed with this hook. */
static void avs_unregister_board(void *pdev)
{
	platform_device_unregister(pdev);
}

static struct platform_device *avs_register_board(struct avs_dev *adev, const char *name,
						  const void *data, size_t size)
{
	struct platform_device *pdev;
	int ret;

	pdev = platform_device_register_data(NULL, name, PLATFORM_DEVID_AUTO, data, size);
	if (IS_ERR(pdev))
		return pdev;

	ret = devm_add_action_or_reset(adev->dev, avs_unregister_board, pdev);
	if (ret)
		return ERR_PTR(ret);

	return pdev;
}

static struct platform_device *avs_register_board_pdata(struct avs_dev *adev, const char *name,
							struct snd_soc_acpi_mach *mach,
							struct hda_codec *codec,
							unsigned long *tdms, char *codec_name)
{
	struct avs_mach_pdata *pdata;

	pdata = devm_kzalloc(adev->dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
		return ERR_PTR(-ENOMEM);

	pdata->codec = codec;
	pdata->tdms = tdms;
	pdata->codec_name = codec_name;
	pdata->obsolete_card_names = obsolete_card_names;
	mach->pdata = pdata;

	return avs_register_board(adev, name, mach, sizeof(*mach));
}

static int __maybe_unused avs_register_probe_board(struct avs_dev *adev)
{
	struct platform_device *pdev;

	pdev = avs_register_board(adev, "avs_probe_mb", NULL, 0);
	if (IS_ERR(pdev))
		return PTR_ERR(pdev);

Annotation

Implementation Notes