tristate "HD Audio PCI"
        depends on SND_PCI
        select SND_HDA
+       select SND_INTEL_NHLT if ACPI
        help
          Say Y here to include support for Intel "High Definition
          Audio" (Azalia) and its compatible devices.
          To compile this driver as a module, choose M here: the module
          will be called snd-hda-intel.
 
+config SND_HDA_INTEL_DETECT_DMIC
+       bool "DMIC detection and probe abort"
+       depends on SND_HDA_INTEL
+       help
+         Say Y to detect digital microphones on SKL+ devices. DMICs
+         cannot be handled by the HDaudio legacy driver and are
+         currently only supported by the SOF driver.
+         If unsure say N.
+
 config SND_HDA_TEGRA
        tristate "NVIDIA Tegra HD Audio"
        depends on ARCH_TEGRA
 
 #include <sound/initval.h>
 #include <sound/hdaudio.h>
 #include <sound/hda_i915.h>
+#include <sound/intel-nhlt.h>
 #include <linux/vgaarb.h>
 #include <linux/vga_switcheroo.h>
 #include <linux/firmware.h>
 static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] =
                                        CONFIG_SND_HDA_INPUT_BEEP_MODE};
 #endif
+static bool dmic_detect = IS_ENABLED(CONFIG_SND_HDA_INTEL_DETECT_DMIC);
 
 module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
 MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode "
                            "(0=off, 1=on) (default=1).");
 #endif
+module_param(dmic_detect, bool, 0444);
+MODULE_PARM_DESC(dmic_detect, "DMIC detect on SKL+ platforms");
 
 #ifdef CONFIG_PM
 static int param_set_xint(const char *val, const struct kernel_param *kp);
        .position_check = azx_position_check,
 };
 
+static int azx_check_dmic(struct pci_dev *pci, struct azx *chip)
+{
+       struct nhlt_acpi_table *nhlt;
+       int ret = 0;
+
+       if (chip->driver_type == AZX_DRIVER_SKL &&
+           pci->class != 0x040300) {
+               nhlt = intel_nhlt_init(&pci->dev);
+               if (nhlt) {
+                       if (intel_nhlt_get_dmic_geo(&pci->dev, nhlt)) {
+                               ret = -ENODEV;
+                               dev_info(&pci->dev, "Digital mics found on Skylake+ platform, aborting probe\n");
+                       }
+                       intel_nhlt_free(nhlt);
+               }
+       }
+       return ret;
+}
+
 static int azx_probe(struct pci_dev *pci,
                     const struct pci_device_id *pci_id)
 {
        card->private_data = chip;
        hda = container_of(chip, struct hda_intel, chip);
 
+       /*
+        * stop probe if digital microphones detected on Skylake+ platform
+        * with the DSP enabled. This is an opt-in behavior defined at build
+        * time or at run-time with a module parameter
+        */
+       if (dmic_detect) {
+               err = azx_check_dmic(pci, chip);
+               if (err < 0)
+                       goto out_free;
+       }
+
        pci_set_drvdata(pci, card);
 
        err = register_vga_switcheroo(chip);