diff options
-rw-r--r-- | sound/pci/hda/Kconfig | 10 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 34 |
2 files changed, 44 insertions, 0 deletions
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index 35d934309cb2..b5966014b5f7 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig | |||
@@ -12,6 +12,7 @@ config SND_HDA_INTEL | |||
12 | tristate "HD Audio PCI" | 12 | tristate "HD Audio PCI" |
13 | depends on SND_PCI | 13 | depends on SND_PCI |
14 | select SND_HDA | 14 | select SND_HDA |
15 | select SND_INTEL_NHLT if ACPI | ||
15 | help | 16 | help |
16 | Say Y here to include support for Intel "High Definition | 17 | Say Y here to include support for Intel "High Definition |
17 | Audio" (Azalia) and its compatible devices. | 18 | Audio" (Azalia) and its compatible devices. |
@@ -22,6 +23,15 @@ config SND_HDA_INTEL | |||
22 | To compile this driver as a module, choose M here: the module | 23 | To compile this driver as a module, choose M here: the module |
23 | will be called snd-hda-intel. | 24 | will be called snd-hda-intel. |
24 | 25 | ||
26 | config SND_HDA_INTEL_DETECT_DMIC | ||
27 | bool "DMIC detection and probe abort" | ||
28 | depends on SND_HDA_INTEL | ||
29 | help | ||
30 | Say Y to detect digital microphones on SKL+ devices. DMICs | ||
31 | cannot be handled by the HDaudio legacy driver and are | ||
32 | currently only supported by the SOF driver. | ||
33 | If unsure say N. | ||
34 | |||
25 | config SND_HDA_TEGRA | 35 | config SND_HDA_TEGRA |
26 | tristate "NVIDIA Tegra HD Audio" | 36 | tristate "NVIDIA Tegra HD Audio" |
27 | depends on ARCH_TEGRA | 37 | depends on ARCH_TEGRA |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index cb8b0945547c..ae9c13248a1d 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <sound/initval.h> | 46 | #include <sound/initval.h> |
47 | #include <sound/hdaudio.h> | 47 | #include <sound/hdaudio.h> |
48 | #include <sound/hda_i915.h> | 48 | #include <sound/hda_i915.h> |
49 | #include <sound/intel-nhlt.h> | ||
49 | #include <linux/vgaarb.h> | 50 | #include <linux/vgaarb.h> |
50 | #include <linux/vga_switcheroo.h> | 51 | #include <linux/vga_switcheroo.h> |
51 | #include <linux/firmware.h> | 52 | #include <linux/firmware.h> |
@@ -124,6 +125,7 @@ static char *patch[SNDRV_CARDS]; | |||
124 | static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = | 125 | static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = |
125 | CONFIG_SND_HDA_INPUT_BEEP_MODE}; | 126 | CONFIG_SND_HDA_INPUT_BEEP_MODE}; |
126 | #endif | 127 | #endif |
128 | static bool dmic_detect = IS_ENABLED(CONFIG_SND_HDA_INTEL_DETECT_DMIC); | ||
127 | 129 | ||
128 | module_param_array(index, int, NULL, 0444); | 130 | module_param_array(index, int, NULL, 0444); |
129 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); | 131 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); |
@@ -158,6 +160,8 @@ module_param_array(beep_mode, bool, NULL, 0444); | |||
158 | MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " | 160 | MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " |
159 | "(0=off, 1=on) (default=1)."); | 161 | "(0=off, 1=on) (default=1)."); |
160 | #endif | 162 | #endif |
163 | module_param(dmic_detect, bool, 0444); | ||
164 | MODULE_PARM_DESC(dmic_detect, "DMIC detect on SKL+ platforms"); | ||
161 | 165 | ||
162 | #ifdef CONFIG_PM | 166 | #ifdef CONFIG_PM |
163 | static int param_set_xint(const char *val, const struct kernel_param *kp); | 167 | static int param_set_xint(const char *val, const struct kernel_param *kp); |
@@ -2025,6 +2029,25 @@ static const struct hda_controller_ops pci_hda_ops = { | |||
2025 | .position_check = azx_position_check, | 2029 | .position_check = azx_position_check, |
2026 | }; | 2030 | }; |
2027 | 2031 | ||
2032 | static int azx_check_dmic(struct pci_dev *pci, struct azx *chip) | ||
2033 | { | ||
2034 | struct nhlt_acpi_table *nhlt; | ||
2035 | int ret = 0; | ||
2036 | |||
2037 | if (chip->driver_type == AZX_DRIVER_SKL && | ||
2038 | pci->class != 0x040300) { | ||
2039 | nhlt = intel_nhlt_init(&pci->dev); | ||
2040 | if (nhlt) { | ||
2041 | if (intel_nhlt_get_dmic_geo(&pci->dev, nhlt)) { | ||
2042 | ret = -ENODEV; | ||
2043 | dev_info(&pci->dev, "Digital mics found on Skylake+ platform, aborting probe\n"); | ||
2044 | } | ||
2045 | intel_nhlt_free(nhlt); | ||
2046 | } | ||
2047 | } | ||
2048 | return ret; | ||
2049 | } | ||
2050 | |||
2028 | static int azx_probe(struct pci_dev *pci, | 2051 | static int azx_probe(struct pci_dev *pci, |
2029 | const struct pci_device_id *pci_id) | 2052 | const struct pci_device_id *pci_id) |
2030 | { | 2053 | { |
@@ -2055,6 +2078,17 @@ static int azx_probe(struct pci_dev *pci, | |||
2055 | card->private_data = chip; | 2078 | card->private_data = chip; |
2056 | hda = container_of(chip, struct hda_intel, chip); | 2079 | hda = container_of(chip, struct hda_intel, chip); |
2057 | 2080 | ||
2081 | /* | ||
2082 | * stop probe if digital microphones detected on Skylake+ platform | ||
2083 | * with the DSP enabled. This is an opt-in behavior defined at build | ||
2084 | * time or at run-time with a module parameter | ||
2085 | */ | ||
2086 | if (dmic_detect) { | ||
2087 | err = azx_check_dmic(pci, chip); | ||
2088 | if (err < 0) | ||
2089 | goto out_free; | ||
2090 | } | ||
2091 | |||
2058 | pci_set_drvdata(pci, card); | 2092 | pci_set_drvdata(pci, card); |
2059 | 2093 | ||
2060 | err = register_vga_switcheroo(chip); | 2094 | err = register_vga_switcheroo(chip); |