/* * CoffeeLake, CannonLake, CometLake, IceLake, TigerLake, AlderLake, * RaptorLake, MeteorLake use legacy HDAudio driver except for Google * Chromebooks and when DMICs are present. Two cases are required since * Coreboot does not expose NHLT tables. * * When the Chromebook quirk is not present, it's based on information * that no such device exists. When the quirk is present, it could be * either based on product information or a placeholder.
*/
device = pci->device; for (; len > 0; len--, table++) { if (table->device != device) continue; if (table->dmi_table && !dmi_check_system(table->dmi_table)) continue; if (table->codec_hid) { int i;
for (i = 0; i < table->codec_hid->num_codecs; i++) { struct nhlt_acpi_table *nhlt; bool ssp_found = false;
if (!acpi_dev_present(table->codec_hid->codecs[i], NULL, -1)) continue;
nhlt = intel_nhlt_init(&pci->dev); if (!nhlt) {
dev_warn(&pci->dev, "%s: NHLT table not found, skipped HID %s\n",
__func__, table->codec_hid->codecs[i]); continue;
}
if (intel_nhlt_has_endpoint_type(nhlt, NHLT_LINK_SSP) &&
intel_nhlt_ssp_endpoint_mask(nhlt, NHLT_DEVICE_I2S))
ssp_found = true;
intel_nhlt_free(nhlt);
if (ssp_found) break;
dev_warn(&pci->dev, "%s: no valid SSP found for HID %s, skipped\n",
__func__, table->codec_hid->codecs[i]);
} if (i == table->codec_hid->num_codecs) continue;
} return table;
} return NULL;
}
staticint snd_intel_dsp_check_dmic(struct pci_dev *pci)
{ int ret = 0;
acpi_nhlt_get_gbl_table();
if (acpi_nhlt_find_endpoint(ACPI_NHLT_LINKTYPE_PDM, -1, -1, -1))
ret = 1;
int snd_intel_dsp_driver_probe(struct pci_dev *pci)
{ conststruct config_entry *cfg;
/* Intel vendor only */ if (pci->vendor != PCI_VENDOR_ID_INTEL) return SND_INTEL_DSP_DRIVER_ANY;
/* * Legacy devices don't have a PCI-based DSP and use HDaudio * for HDMI/DP support, ignore kernel parameter
*/ switch (pci->device) { case PCI_DEVICE_ID_INTEL_HDA_BDW: case PCI_DEVICE_ID_INTEL_HDA_HSW_0: case PCI_DEVICE_ID_INTEL_HDA_HSW_2: case PCI_DEVICE_ID_INTEL_HDA_HSW_3: case PCI_DEVICE_ID_INTEL_HDA_BYT: case PCI_DEVICE_ID_INTEL_HDA_BSW: return SND_INTEL_DSP_DRIVER_ANY;
}
if (dsp_driver > 0 && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST) return dsp_driver;
/* * detect DSP by checking class/subclass/prog-id information * class=04 subclass 03 prog-if 00: no DSP, use legacy driver * class=04 subclass 01 prog-if 00: DSP is present * (and may be required e.g. for DMIC or SSP support) * class=04 subclass 03 prog-if 80: use DSP or legacy mode
*/ if (pci->class == 0x040300) return SND_INTEL_DSP_DRIVER_LEGACY; if (pci->class != 0x040100 && pci->class != 0x040380) {
dev_err(&pci->dev, "Unknown PCI class/subclass/prog-if information (0x%06x) found, selecting HDAudio legacy driver\n", pci->class); return SND_INTEL_DSP_DRIVER_LEGACY;
}
dev_dbg(&pci->dev, "DSP detected with PCI class/subclass/prog-if info 0x%06x\n", pci->class);
/* find the configuration for the specific device */
cfg = snd_intel_dsp_find_config(pci, config_table, ARRAY_SIZE(config_table)); if (!cfg) return SND_INTEL_DSP_DRIVER_ANY;
if (cfg->flags & FLAG_SOF) { if (cfg->flags & FLAG_SOF_ONLY_IF_SOUNDWIRE &&
snd_intel_dsp_check_soundwire(pci) > 0) {
dev_info_once(&pci->dev, "SoundWire enabled on CannonLake+ platform, using SOF driver\n"); return SND_INTEL_DSP_DRIVER_SOF;
} if (cfg->flags & FLAG_SOF_ONLY_IF_DMIC &&
snd_intel_dsp_check_dmic(pci)) {
dev_info_once(&pci->dev, "Digital mics found on Skylake+ platform, using SOF driver\n"); return SND_INTEL_DSP_DRIVER_SOF;
} if (!(cfg->flags & FLAG_SOF_ONLY_IF_DMIC_OR_SOUNDWIRE)) return SND_INTEL_DSP_DRIVER_SOF;
}
if (cfg->flags & FLAG_SST) { if (cfg->flags & FLAG_SST_ONLY_IF_DMIC) { if (snd_intel_dsp_check_dmic(pci)) {
dev_info_once(&pci->dev, "Digital mics found on Skylake+ platform, using SST driver\n"); return SND_INTEL_DSP_DRIVER_SST;
}
} else { return SND_INTEL_DSP_DRIVER_SST;
}
}
/* Should we default to SOF or SST for BYT/CHT ? */ #if IS_ENABLED(CONFIG_SND_INTEL_BYT_PREFER_SOF) || \
!IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) #define FLAG_SST_OR_SOF_BYT FLAG_SOF #else #define FLAG_SST_OR_SOF_BYT FLAG_SST #endif
/* * configuration table * - the order of similar ACPI ID entries is important! * - the first successful match will win
*/ staticconststruct config_entry acpi_config_table[] = { #if IS_ENABLED(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM_ACPI) || \
IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL) /* BayTrail */
{
.flags = FLAG_SST_OR_SOF_BYT,
.acpi_hid = "LPE0F28",
},
{
.flags = FLAG_SST_OR_SOF_BYT,
.acpi_hid = "80860F28",
}, /* CherryTrail */
{
.flags = FLAG_SST_OR_SOF_BYT,
.acpi_hid = "808622A8",
}, #endif /* Broadwell */ #if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT)
{
.flags = FLAG_SST,
.acpi_hid = "INT3438"
}, #endif #if IS_ENABLED(CONFIG_SND_SOC_SOF_BROADWELL)
{
.flags = FLAG_SOF,
.acpi_hid = "INT3438"
}, #endif /* Haswell - not supported by SOF but added for consistency */ #if IS_ENABLED(CONFIG_SND_SOC_INTEL_CATPT)
{
.flags = FLAG_SST,
.acpi_hid = "INT33C8"
}, #endif
};
staticconststruct config_entry *snd_intel_acpi_dsp_find_config(const u8 acpi_hid[ACPI_ID_LEN], conststruct config_entry *table,
u32 len)
{ for (; len > 0; len--, table++) { if (memcmp(table->acpi_hid, acpi_hid, ACPI_ID_LEN)) continue; if (table->dmi_table && !dmi_check_system(table->dmi_table)) continue; return table;
} return NULL;
}
if (dsp_driver > SND_INTEL_DSP_DRIVER_LEGACY && dsp_driver <= SND_INTEL_DSP_DRIVER_LAST) return dsp_driver;
if (dsp_driver == SND_INTEL_DSP_DRIVER_LEGACY) {
dev_warn(dev, "dsp_driver parameter %d not supported, using automatic detection\n",
SND_INTEL_DSP_DRIVER_LEGACY);
}
/* find the configuration for the specific device */
cfg = snd_intel_acpi_dsp_find_config(acpi_hid, acpi_config_table,
ARRAY_SIZE(acpi_config_table)); if (!cfg) return SND_INTEL_DSP_DRIVER_ANY;
if (cfg->flags & FLAG_SST) return SND_INTEL_DSP_DRIVER_SST;
if (cfg->flags & FLAG_SOF) return SND_INTEL_DSP_DRIVER_SOF;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.