summaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/Kconfig11
-rw-r--r--sound/pci/hda/hda_bind.c4
-rw-r--r--sound/pci/hda/hda_controller.c1
-rw-r--r--sound/pci/hda/hda_intel.c60
-rw-r--r--sound/pci/hda/patch_hdmi.c19
5 files changed, 44 insertions, 51 deletions
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index dae47a45b2b8..bd48335d09d7 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -12,7 +12,7 @@ config SND_HDA_INTEL
tristate "HD Audio PCI"
depends on SND_PCI
select SND_HDA
- select SND_INTEL_NHLT if ACPI
+ select SND_INTEL_DSP_CONFIG
help
Say Y here to include support for Intel "High Definition
Audio" (Azalia) and its compatible devices.
@@ -23,15 +23,6 @@ config SND_HDA_INTEL
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
diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c
index 8272b50b8349..6a8564566375 100644
--- a/sound/pci/hda/hda_bind.c
+++ b/sound/pci/hda/hda_bind.c
@@ -43,6 +43,10 @@ static void hda_codec_unsol_event(struct hdac_device *dev, unsigned int ev)
{
struct hda_codec *codec = container_of(dev, struct hda_codec, core);
+ /* ignore unsol events during shutdown */
+ if (codec->bus->shutdown)
+ return;
+
if (codec->patch_ops.unsol_event)
codec->patch_ops.unsol_event(codec, ev);
}
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c
index 6387c7e90918..2f3b7a35f2d9 100644
--- a/sound/pci/hda/hda_controller.c
+++ b/sound/pci/hda/hda_controller.c
@@ -701,7 +701,6 @@ static const struct snd_pcm_ops azx_pcm_ops = {
.pointer = azx_pcm_pointer,
.get_time_info = azx_get_time_info,
.mmap = azx_pcm_mmap,
- .page = snd_pcm_sgbuf_ops_page,
};
static void azx_pcm_free(struct snd_pcm *pcm)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index c52419376c74..8981109e3565 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -46,7 +46,7 @@
#include <sound/initval.h>
#include <sound/hdaudio.h>
#include <sound/hda_i915.h>
-#include <sound/intel-nhlt.h>
+#include <sound/intel-dsp-config.h>
#include <linux/vgaarb.h>
#include <linux/vga_switcheroo.h>
#include <linux/firmware.h>
@@ -124,7 +124,7 @@ static char *patch[SNDRV_CARDS];
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);
+static bool dsp_driver = 1;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
@@ -159,8 +159,9 @@ module_param_array(beep_mode, bool, NULL, 0444);
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");
+module_param(dsp_driver, bool, 0444);
+MODULE_PARM_DESC(dsp_driver, "Allow DSP driver selection (bypass this driver) "
+ "(0=off, 1=on) (default=1)");
#ifdef CONFIG_PM
static int param_set_xint(const char *val, const struct kernel_param *kp);
@@ -1280,11 +1281,17 @@ static void init_vga_switcheroo(struct azx *chip)
{
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
struct pci_dev *p = get_bound_vga(chip->pci);
+ struct pci_dev *parent;
if (p) {
dev_info(chip->card->dev,
"Handle vga_switcheroo audio client\n");
hda->use_vga_switcheroo = 1;
- chip->bus.keep_power = 1; /* cleared in either gpu_bound op or codec probe */
+
+ /* cleared in either gpu_bound op or codec probe, or when its
+ * upstream port has _PR3 (i.e. dGPU).
+ */
+ parent = pci_upstream_bridge(p);
+ chip->bus.keep_power = parent ? !pci_pr3_present(parent) : 1;
chip->driver_caps |= AZX_DCAPS_PM_RUNTIME;
pci_dev_put(p);
}
@@ -1382,8 +1389,11 @@ static int azx_free(struct azx *chip)
static int azx_dev_disconnect(struct snd_device *device)
{
struct azx *chip = device->device_data;
+ struct hdac_bus *bus = azx_bus(chip);
chip->bus.shutdown = 1;
+ cancel_work_sync(&bus->unsol_work);
+
return 0;
}
@@ -2020,25 +2030,6 @@ static const struct hda_controller_ops pci_hda_ops = {
.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)
{
@@ -2056,6 +2047,16 @@ static int azx_probe(struct pci_dev *pci,
return -ENOENT;
}
+ /*
+ * stop probe if another Intel's DSP driver should be activated
+ */
+ if (dsp_driver) {
+ err = snd_intel_dsp_driver_probe(pci);
+ if (err != SND_INTEL_DSP_DRIVER_ANY &&
+ err != SND_INTEL_DSP_DRIVER_LEGACY)
+ return -ENODEV;
+ }
+
err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
0, &card);
if (err < 0) {
@@ -2069,17 +2070,6 @@ static int azx_probe(struct pci_dev *pci,
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);
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 78bd2e3722c7..d24bd95c6e95 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -2075,15 +2075,24 @@ static bool is_hdmi_pcm_attached(struct hdac_device *hdac, int pcm_idx)
static int generic_hdmi_build_pcms(struct hda_codec *codec)
{
struct hdmi_spec *spec = codec->spec;
- int idx;
+ int idx, pcm_num;
/*
* for non-mst mode, pcm number is the same as before
- * for DP MST mode, pcm number is (nid number + dev_num - 1)
- * dev_num is the device entry number in a pin
- *
+ * for DP MST mode without extra PCM, pcm number is same
+ * for DP MST mode with extra PCMs, pcm number is
+ * (nid number + dev_num - 1)
+ * dev_num is the device entry number in a pin
*/
- for (idx = 0; idx < spec->num_nids + spec->dev_num - 1; idx++) {
+
+ if (codec->mst_no_extra_pcms)
+ pcm_num = spec->num_nids;
+ else
+ pcm_num = spec->num_nids + spec->dev_num - 1;
+
+ codec_dbg(codec, "hdmi: pcm_num set to %d\n", pcm_num);
+
+ for (idx = 0; idx < pcm_num; idx++) {
struct hda_pcm *info;
struct hda_pcm_stream *pstr;