diff options
-rw-r--r-- | include/sound/hdaudio.h | 6 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 26 | ||||
-rw-r--r-- | sound/soc/intel/skylake/skl.c | 48 |
3 files changed, 62 insertions, 18 deletions
diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index f9b2b6330d27..b4fa1c775251 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h | |||
@@ -98,6 +98,12 @@ enum { | |||
98 | HDA_DEV_ASOC, | 98 | HDA_DEV_ASOC, |
99 | }; | 99 | }; |
100 | 100 | ||
101 | enum { | ||
102 | SND_SKL_PCI_BIND_AUTO, /* automatic selection based on pci class */ | ||
103 | SND_SKL_PCI_BIND_LEGACY,/* bind only with legacy driver */ | ||
104 | SND_SKL_PCI_BIND_ASOC /* bind only with ASoC driver */ | ||
105 | }; | ||
106 | |||
101 | /* direction */ | 107 | /* direction */ |
102 | enum { | 108 | enum { |
103 | HDA_INPUT, HDA_OUTPUT | 109 | HDA_INPUT, HDA_OUTPUT |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 2ec9c896ebc0..e42cc2230977 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -172,6 +172,9 @@ module_param_array(beep_mode, bool, NULL, 0444); | |||
172 | MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " | 172 | MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " |
173 | "(0=off, 1=on) (default=1)."); | 173 | "(0=off, 1=on) (default=1)."); |
174 | #endif | 174 | #endif |
175 | static int skl_pci_binding; | ||
176 | module_param_named(pci_binding, skl_pci_binding, int, 0444); | ||
177 | MODULE_PARM_DESC(pci_binding, "PCI binding (0=auto, 1=only legacy, 2=only asoc"); | ||
175 | 178 | ||
176 | #ifdef CONFIG_PM | 179 | #ifdef CONFIG_PM |
177 | static int param_set_xint(const char *val, const struct kernel_param *kp); | 180 | static int param_set_xint(const char *val, const struct kernel_param *kp); |
@@ -2050,9 +2053,26 @@ static int azx_probe(struct pci_dev *pci, | |||
2050 | int err; | 2053 | int err; |
2051 | 2054 | ||
2052 | /* check if this driver can be used on SKL+ Intel platforms */ | 2055 | /* check if this driver can be used on SKL+ Intel platforms */ |
2053 | if ((pci_id->driver_data & AZX_DCAPS_INTEL_SHARED) && | 2056 | if (pci_id->driver_data & AZX_DCAPS_INTEL_SHARED) { |
2054 | pci->class != 0x040300) | 2057 | switch (skl_pci_binding) { |
2055 | return -ENODEV; | 2058 | case SND_SKL_PCI_BIND_AUTO: |
2059 | if (pci->class != 0x040300) { | ||
2060 | dev_info(&pci->dev, "The DSP is enabled on this platform, aborting probe\n"); | ||
2061 | return -ENODEV; | ||
2062 | } | ||
2063 | dev_info(&pci->dev, "No DSP detected, continuing HDaudio legacy probe\n"); | ||
2064 | break; | ||
2065 | case SND_SKL_PCI_BIND_LEGACY: | ||
2066 | dev_info(&pci->dev, "Module parameter forced binding with HDaudio legacy, bypassed detection logic\n"); | ||
2067 | break; | ||
2068 | case SND_SKL_PCI_BIND_ASOC: | ||
2069 | dev_info(&pci->dev, "Module parameter forced binding with SKL+ ASoC driver, aborting probe\n"); | ||
2070 | return -ENODEV; | ||
2071 | default: | ||
2072 | dev_err(&pci->dev, "invalid value for skl_pci_binding module parameter, ignored\n"); | ||
2073 | break; | ||
2074 | } | ||
2075 | } | ||
2056 | 2076 | ||
2057 | if (dev >= SNDRV_CARDS) | 2077 | if (dev >= SNDRV_CARDS) |
2058 | return -ENODEV; | 2078 | return -ENODEV; |
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 29d9b0eb83ea..60c94836bf5b 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c | |||
@@ -40,6 +40,9 @@ | |||
40 | #if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) | 40 | #if IS_ENABLED(CONFIG_SND_SOC_INTEL_SKYLAKE_HDAUDIO_CODEC) |
41 | #include "../../../soc/codecs/hdac_hda.h" | 41 | #include "../../../soc/codecs/hdac_hda.h" |
42 | #endif | 42 | #endif |
43 | static int skl_pci_binding; | ||
44 | module_param_named(pci_binding, skl_pci_binding, int, 0444); | ||
45 | MODULE_PARM_DESC(pci_binding, "PCI binding (0=auto, 1=only legacy, 2=only asoc"); | ||
43 | 46 | ||
44 | /* | 47 | /* |
45 | * initialize the PCI registers | 48 | * initialize the PCI registers |
@@ -896,21 +899,6 @@ static int skl_first_init(struct hdac_bus *bus) | |||
896 | unsigned short gcap; | 899 | unsigned short gcap; |
897 | int cp_streams, pb_streams, start_idx; | 900 | int cp_streams, pb_streams, start_idx; |
898 | 901 | ||
899 | /* | ||
900 | * detect DSP by checking class/subclass/prog-id information | ||
901 | * class=04 subclass 03 prog-if 00: no DSP, legacy driver needs to be used | ||
902 | * class=04 subclass 01 prog-if 00: DSP is present (and may be required e.g. for DMIC or SSP support) | ||
903 | * class=04 subclass 03 prog-if 80: either of DSP or legacy mode can be used | ||
904 | */ | ||
905 | if (pci->class == 0x040300) { | ||
906 | dev_err(bus->dev, "The DSP is not enabled on this platform, aborting probe\n"); | ||
907 | return -ENODEV; | ||
908 | } else if (pci->class != 0x040100 && pci->class != 0x040380) { | ||
909 | dev_err(bus->dev, "Unknown PCI class/subclass/prog-if information (0x%06x) found, aborting probe\n", pci->class); | ||
910 | return -ENODEV; | ||
911 | } | ||
912 | dev_info(bus->dev, "DSP detected with PCI class/subclass/prog-if info 0x%06x\n", pci->class); | ||
913 | |||
914 | err = pci_request_regions(pci, "Skylake HD audio"); | 902 | err = pci_request_regions(pci, "Skylake HD audio"); |
915 | if (err < 0) | 903 | if (err < 0) |
916 | return err; | 904 | return err; |
@@ -984,6 +972,36 @@ static int skl_probe(struct pci_dev *pci, | |||
984 | struct hdac_bus *bus = NULL; | 972 | struct hdac_bus *bus = NULL; |
985 | int err; | 973 | int err; |
986 | 974 | ||
975 | switch (skl_pci_binding) { | ||
976 | case SND_SKL_PCI_BIND_AUTO: | ||
977 | /* | ||
978 | * detect DSP by checking class/subclass/prog-id information | ||
979 | * class=04 subclass 03 prog-if 00: no DSP, use legacy driver | ||
980 | * class=04 subclass 01 prog-if 00: DSP is present | ||
981 | * (and may be required e.g. for DMIC or SSP support) | ||
982 | * class=04 subclass 03 prog-if 80: use DSP or legacy mode | ||
983 | */ | ||
984 | if (pci->class == 0x040300) { | ||
985 | dev_info(&pci->dev, "The DSP is not enabled on this platform, aborting probe\n"); | ||
986 | return -ENODEV; | ||
987 | } | ||
988 | if (pci->class != 0x040100 && pci->class != 0x040380) { | ||
989 | dev_err(&pci->dev, "Unknown PCI class/subclass/prog-if information (0x%06x) found, aborting probe\n", pci->class); | ||
990 | return -ENODEV; | ||
991 | } | ||
992 | dev_info(&pci->dev, "DSP detected with PCI class/subclass/prog-if info 0x%06x\n", pci->class); | ||
993 | break; | ||
994 | case SND_SKL_PCI_BIND_LEGACY: | ||
995 | dev_info(&pci->dev, "Module parameter forced binding with HDaudio legacy, aborting probe\n"); | ||
996 | return -ENODEV; | ||
997 | case SND_SKL_PCI_BIND_ASOC: | ||
998 | dev_info(&pci->dev, "Module parameter forced binding with SKL driver, bypassed detection logic\n"); | ||
999 | break; | ||
1000 | default: | ||
1001 | dev_err(&pci->dev, "invalid value for skl_pci_binding module parameter, ignored\n"); | ||
1002 | break; | ||
1003 | } | ||
1004 | |||
987 | /* we use ext core ops, so provide NULL for ops here */ | 1005 | /* we use ext core ops, so provide NULL for ops here */ |
988 | err = skl_create(pci, NULL, &skl); | 1006 | err = skl_create(pci, NULL, &skl); |
989 | if (err < 0) | 1007 | if (err < 0) |