xref: /openbmc/linux/sound/pci/hda/hda_intel.c (revision 8ebc80a25f9d9bf7a8e368b266d5b740c485c362)
11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  *
4d01ce99fSTakashi Iwai  *  hda_intel.c - Implementation of primary alsa driver code base
5d01ce99fSTakashi Iwai  *                for Intel HD Audio.
61da177e4SLinus Torvalds  *
71da177e4SLinus Torvalds  *  Copyright(c) 2004 Intel Corporation. All rights reserved.
81da177e4SLinus Torvalds  *
91da177e4SLinus Torvalds  *  Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
101da177e4SLinus Torvalds  *                     PeiSen Hou <pshou@realtek.com.tw>
111da177e4SLinus Torvalds  *
121da177e4SLinus Torvalds  *  CONTACTS:
131da177e4SLinus Torvalds  *
141da177e4SLinus Torvalds  *  Matt Jared		matt.jared@intel.com
151da177e4SLinus Torvalds  *  Andy Kopp		andy.kopp@intel.com
161da177e4SLinus Torvalds  *  Dan Kogan		dan.d.kogan@intel.com
171da177e4SLinus Torvalds  *
181da177e4SLinus Torvalds  *  CHANGES:
191da177e4SLinus Torvalds  *
201da177e4SLinus Torvalds  *  2004.12.01	Major rewrite by tiwai, merged the work of pshou
211da177e4SLinus Torvalds  */
221da177e4SLinus Torvalds 
231da177e4SLinus Torvalds #include <linux/delay.h>
241da177e4SLinus Torvalds #include <linux/interrupt.h>
25362775e2SRandy Dunlap #include <linux/kernel.h>
261da177e4SLinus Torvalds #include <linux/module.h>
2724982c5fSAndrew Morton #include <linux/dma-mapping.h>
281da177e4SLinus Torvalds #include <linux/moduleparam.h>
291da177e4SLinus Torvalds #include <linux/init.h>
301da177e4SLinus Torvalds #include <linux/slab.h>
311da177e4SLinus Torvalds #include <linux/pci.h>
3262932df8SIngo Molnar #include <linux/mutex.h>
3327fe48d9STakashi Iwai #include <linux/io.h>
34b8dfc462SMengdong Lin #include <linux/pm_runtime.h>
355d890f59SPierre-Louis Bossart #include <linux/clocksource.h>
365d890f59SPierre-Louis Bossart #include <linux/time.h>
37f4c482a4STakashi Iwai #include <linux/completion.h>
38586bc4aaSAlex Deucher #include <linux/acpi.h>
3965fddcfcSMike Rapoport #include <linux/pgtable.h>
405d890f59SPierre-Louis Bossart 
4127fe48d9STakashi Iwai #ifdef CONFIG_X86
4227fe48d9STakashi Iwai /* for snoop control */
437f80f513SLaura Abbott #include <asm/set_memory.h>
4450279d9bSGuneshwor Singh #include <asm/cpufeature.h>
4527fe48d9STakashi Iwai #endif
461da177e4SLinus Torvalds #include <sound/core.h>
471da177e4SLinus Torvalds #include <sound/initval.h>
4898d8fc6cSMengdong Lin #include <sound/hdaudio.h>
4998d8fc6cSMengdong Lin #include <sound/hda_i915.h>
5082d9d54aSJaroslav Kysela #include <sound/intel-dsp-config.h>
519121947dSTakashi Iwai #include <linux/vgaarb.h>
52a82d51edSTakashi Iwai #include <linux/vga_switcheroo.h>
535beb5627SOrlando Chamberlain #include <linux/apple-gmux.h>
544918cdabSTakashi Iwai #include <linux/firmware.h>
55be57bfffSPierre-Louis Bossart #include <sound/hda_codec.h>
5605e84878SDylan Reid #include "hda_controller.h"
57347de1f8SImre Deak #include "hda_intel.h"
581da177e4SLinus Torvalds 
59785d8c4bSLibin Yang #define CREATE_TRACE_POINTS
60785d8c4bSLibin Yang #include "hda_intel_trace.h"
61785d8c4bSLibin Yang 
62b6050ef6STakashi Iwai /* position fix mode */
63b6050ef6STakashi Iwai enum {
64b6050ef6STakashi Iwai 	POS_FIX_AUTO,
65b6050ef6STakashi Iwai 	POS_FIX_LPIB,
66b6050ef6STakashi Iwai 	POS_FIX_POSBUF,
67b6050ef6STakashi Iwai 	POS_FIX_VIACOMBO,
68b6050ef6STakashi Iwai 	POS_FIX_COMBO,
69f87e7f25STakashi Iwai 	POS_FIX_SKL,
70c02f77d3STakashi Iwai 	POS_FIX_FIFO,
71b6050ef6STakashi Iwai };
72b6050ef6STakashi Iwai 
739a34af4aSTakashi Iwai /* Defines for ATI HD Audio support in SB450 south bridge */
749a34af4aSTakashi Iwai #define ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR   0x42
759a34af4aSTakashi Iwai #define ATI_SB450_HDAUDIO_ENABLE_SNOOP      0x02
769a34af4aSTakashi Iwai 
779a34af4aSTakashi Iwai /* Defines for Nvidia HDA support */
789a34af4aSTakashi Iwai #define NVIDIA_HDA_TRANSREG_ADDR      0x4e
799a34af4aSTakashi Iwai #define NVIDIA_HDA_ENABLE_COHBITS     0x0f
809a34af4aSTakashi Iwai #define NVIDIA_HDA_ISTRM_COH          0x4d
819a34af4aSTakashi Iwai #define NVIDIA_HDA_OSTRM_COH          0x4c
829a34af4aSTakashi Iwai #define NVIDIA_HDA_ENABLE_COHBIT      0x01
839a34af4aSTakashi Iwai 
849a34af4aSTakashi Iwai /* Defines for Intel SCH HDA snoop control */
856639484dSLibin Yang #define INTEL_HDA_CGCTL	 0x48
866639484dSLibin Yang #define INTEL_HDA_CGCTL_MISCBDCGE        (0x1 << 6)
879a34af4aSTakashi Iwai #define INTEL_SCH_HDA_DEVC      0x78
889a34af4aSTakashi Iwai #define INTEL_SCH_HDA_DEVC_NOSNOOP       (0x1<<11)
899a34af4aSTakashi Iwai 
9033124929STakashi Iwai /* max number of SDs */
9133124929STakashi Iwai /* ICH, ATI and VIA have 4 playback and 4 capture */
9233124929STakashi Iwai #define ICH6_NUM_CAPTURE	4
9333124929STakashi Iwai #define ICH6_NUM_PLAYBACK	4
9433124929STakashi Iwai 
9533124929STakashi Iwai /* ULI has 6 playback and 5 capture */
9633124929STakashi Iwai #define ULI_NUM_CAPTURE		5
9733124929STakashi Iwai #define ULI_NUM_PLAYBACK	6
9833124929STakashi Iwai 
9933124929STakashi Iwai /* ATI HDMI may have up to 8 playbacks and 0 capture */
10033124929STakashi Iwai #define ATIHDMI_NUM_CAPTURE	0
10133124929STakashi Iwai #define ATIHDMI_NUM_PLAYBACK	8
10233124929STakashi Iwai 
1031da177e4SLinus Torvalds 
1045aba4f8eSTakashi Iwai static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
1055aba4f8eSTakashi Iwai static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
106a67ff6a5SRusty Russell static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
1075aba4f8eSTakashi Iwai static char *model[SNDRV_CARDS];
1081dac6695STakashi Iwai static int position_fix[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
1095c0d7bc1STakashi Iwai static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
1105aba4f8eSTakashi Iwai static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
111d4d9cd03STakashi Iwai static int probe_only[SNDRV_CARDS];
11226a6cb6cSDavid Henningsson static int jackpoll_ms[SNDRV_CARDS];
11341438f13STakashi Iwai static int single_cmd = -1;
11471623855STakashi Iwai static int enable_msi = -1;
1154ea6fbc8STakashi Iwai #ifdef CONFIG_SND_HDA_PATCH_LOADER
1164ea6fbc8STakashi Iwai static char *patch[SNDRV_CARDS];
1174ea6fbc8STakashi Iwai #endif
1182dca0bbaSJaroslav Kysela #ifdef CONFIG_SND_HDA_INPUT_BEEP
1190920c9b4STakashi Iwai static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] =
1202dca0bbaSJaroslav Kysela 					CONFIG_SND_HDA_INPUT_BEEP_MODE};
1212dca0bbaSJaroslav Kysela #endif
1227fba6aeaSTakashi Iwai static bool dmic_detect = 1;
123d045bcefSJaroslav Kysela static bool ctl_dev_id = IS_ENABLED(CONFIG_SND_HDA_CTL_DEV_ID) ? 1 : 0;
1241da177e4SLinus Torvalds 
1255aba4f8eSTakashi Iwai module_param_array(index, int, NULL, 0444);
1261da177e4SLinus Torvalds MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
1275aba4f8eSTakashi Iwai module_param_array(id, charp, NULL, 0444);
1281da177e4SLinus Torvalds MODULE_PARM_DESC(id, "ID string for Intel HD audio interface.");
1295aba4f8eSTakashi Iwai module_param_array(enable, bool, NULL, 0444);
1305aba4f8eSTakashi Iwai MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");
1315aba4f8eSTakashi Iwai module_param_array(model, charp, NULL, 0444);
1321da177e4SLinus Torvalds MODULE_PARM_DESC(model, "Use the given board model.");
1335aba4f8eSTakashi Iwai module_param_array(position_fix, int, NULL, 0444);
1344cb36310SDavid Henningsson MODULE_PARM_DESC(position_fix, "DMA pointer read method."
135c02f77d3STakashi Iwai 		 "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO, 5 = SKL+, 6 = FIFO).");
136555e219fSTakashi Iwai module_param_array(bdl_pos_adj, int, NULL, 0644);
137555e219fSTakashi Iwai MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
1385aba4f8eSTakashi Iwai module_param_array(probe_mask, int, NULL, 0444);
139606ad75fSTakashi Iwai MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
140079e683eSJaroslav Kysela module_param_array(probe_only, int, NULL, 0444);
141d4d9cd03STakashi Iwai MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");
14226a6cb6cSDavid Henningsson module_param_array(jackpoll_ms, int, NULL, 0444);
14326a6cb6cSDavid Henningsson MODULE_PARM_DESC(jackpoll_ms, "Ms between polling for jack events (default = 0, using unsol events only)");
14441438f13STakashi Iwai module_param(single_cmd, bint, 0444);
145d01ce99fSTakashi Iwai MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
146d01ce99fSTakashi Iwai 		 "(for debugging only).");
147ac9ef6cfSTakashi Iwai module_param(enable_msi, bint, 0444);
148134a11f0STakashi Iwai MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
1494ea6fbc8STakashi Iwai #ifdef CONFIG_SND_HDA_PATCH_LOADER
1504ea6fbc8STakashi Iwai module_param_array(patch, charp, NULL, 0444);
1514ea6fbc8STakashi Iwai MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface.");
1524ea6fbc8STakashi Iwai #endif
1532dca0bbaSJaroslav Kysela #ifdef CONFIG_SND_HDA_INPUT_BEEP
1540920c9b4STakashi Iwai module_param_array(beep_mode, bool, NULL, 0444);
1552dca0bbaSJaroslav Kysela MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode "
1560920c9b4STakashi Iwai 			    "(0=off, 1=on) (default=1).");
1572dca0bbaSJaroslav Kysela #endif
1587fba6aeaSTakashi Iwai module_param(dmic_detect, bool, 0444);
1597fba6aeaSTakashi Iwai MODULE_PARM_DESC(dmic_detect, "Allow DSP driver selection (bypass this driver) "
1607fba6aeaSTakashi Iwai 			     "(0=off, 1=on) (default=1); "
1617fba6aeaSTakashi Iwai 		 "deprecated, use snd-intel-dspcfg.dsp_driver option instead");
162d045bcefSJaroslav Kysela module_param(ctl_dev_id, bool, 0444);
163d045bcefSJaroslav Kysela MODULE_PARM_DESC(ctl_dev_id, "Use control device identifier (based on codec address).");
164606ad75fSTakashi Iwai 
16583012a7cSTakashi Iwai #ifdef CONFIG_PM
16665fcd41dSTakashi Iwai static int param_set_xint(const char *val, const struct kernel_param *kp);
1679c27847dSLuis R. Rodriguez static const struct kernel_param_ops param_ops_xint = {
16865fcd41dSTakashi Iwai 	.set = param_set_xint,
16965fcd41dSTakashi Iwai 	.get = param_get_int,
17065fcd41dSTakashi Iwai };
17165fcd41dSTakashi Iwai #define param_check_xint param_check_int
17265fcd41dSTakashi Iwai 
173fee2fba3STakashi Iwai static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
17465fcd41dSTakashi Iwai module_param(power_save, xint, 0644);
175fee2fba3STakashi Iwai MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
176fee2fba3STakashi Iwai 		 "(in second, 0 = disable).");
1771da177e4SLinus Torvalds 
17840088dc4STakashi Iwai static bool pm_blacklist = true;
17940088dc4STakashi Iwai module_param(pm_blacklist, bool, 0644);
1806317e5ebSTakashi Iwai MODULE_PARM_DESC(pm_blacklist, "Enable power-management denylist");
18140088dc4STakashi Iwai 
182dee1b66cSTakashi Iwai /* reset the HD-audio controller in power save mode.
183dee1b66cSTakashi Iwai  * this may give more power-saving, but will take longer time to
184dee1b66cSTakashi Iwai  * wake up.
185dee1b66cSTakashi Iwai  */
1868fc24426STakashi Iwai static bool power_save_controller = 1;
1878fc24426STakashi Iwai module_param(power_save_controller, bool, 0644);
188dee1b66cSTakashi Iwai MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
189e62a42aeSDylan Reid #else
190bb573928STakashi Iwai #define power_save	0
19183012a7cSTakashi Iwai #endif /* CONFIG_PM */
192dee1b66cSTakashi Iwai 
1937bfe059eSTakashi Iwai static int align_buffer_size = -1;
1947bfe059eSTakashi Iwai module_param(align_buffer_size, bint, 0644);
1952ae66c26SPierre-Louis Bossart MODULE_PARM_DESC(align_buffer_size,
1962ae66c26SPierre-Louis Bossart 		"Force buffer and period sizes to be multiple of 128 bytes.");
1972ae66c26SPierre-Louis Bossart 
19827fe48d9STakashi Iwai #ifdef CONFIG_X86
1997c732015STakashi Iwai static int hda_snoop = -1;
2007c732015STakashi Iwai module_param_named(snoop, hda_snoop, bint, 0444);
20127fe48d9STakashi Iwai MODULE_PARM_DESC(snoop, "Enable/disable snooping");
20227fe48d9STakashi Iwai #else
20327fe48d9STakashi Iwai #define hda_snoop		true
20427fe48d9STakashi Iwai #endif
20527fe48d9STakashi Iwai 
20627fe48d9STakashi Iwai 
2071da177e4SLinus Torvalds MODULE_LICENSE("GPL");
2081da177e4SLinus Torvalds MODULE_DESCRIPTION("Intel HDA driver");
2091da177e4SLinus Torvalds 
210a82d51edSTakashi Iwai #if defined(CONFIG_PM) && defined(CONFIG_VGA_SWITCHEROO)
211f8f1becfSTakashi Iwai #if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI)
212a82d51edSTakashi Iwai #define SUPPORT_VGA_SWITCHEROO
213a82d51edSTakashi Iwai #endif
214a82d51edSTakashi Iwai #endif
215a82d51edSTakashi Iwai 
216a82d51edSTakashi Iwai 
217cb53c626STakashi Iwai /*
2181da177e4SLinus Torvalds  */
2191da177e4SLinus Torvalds 
22007e4ca50STakashi Iwai /* driver types */
22107e4ca50STakashi Iwai enum {
22207e4ca50STakashi Iwai 	AZX_DRIVER_ICH,
22332679f95SSeth Heasley 	AZX_DRIVER_PCH,
2244979bca9STobin Davis 	AZX_DRIVER_SCH,
225a4b4793fSTakashi Iwai 	AZX_DRIVER_SKL,
226fab1285aSTakashi Iwai 	AZX_DRIVER_HDMI,
22707e4ca50STakashi Iwai 	AZX_DRIVER_ATI,
228778b6e1bSFelix Kuehling 	AZX_DRIVER_ATIHDMI,
2291815b34aSAndiry Xu 	AZX_DRIVER_ATIHDMI_NS,
230c51e4310Sjasontao 	AZX_DRIVER_GFHDMI,
23107e4ca50STakashi Iwai 	AZX_DRIVER_VIA,
23207e4ca50STakashi Iwai 	AZX_DRIVER_SIS,
23307e4ca50STakashi Iwai 	AZX_DRIVER_ULI,
234da3fca21SVinod G 	AZX_DRIVER_NVIDIA,
235f269002eSKailang Yang 	AZX_DRIVER_TERA,
23614d34f16STakashi Iwai 	AZX_DRIVER_CTX,
2375ae763b1STakashi Iwai 	AZX_DRIVER_CTHDA,
238c563f473STakashi Iwai 	AZX_DRIVER_CMEDIA,
239b6fcab14STony W Wang-oc 	AZX_DRIVER_ZHAOXIN,
24028bd137aSYanteng Si 	AZX_DRIVER_LOONGSON,
241c4da29caSYang, Libin 	AZX_DRIVER_GENERIC,
2422f5983f2STakashi Iwai 	AZX_NUM_DRIVERS, /* keep this as last entry */
24307e4ca50STakashi Iwai };
24407e4ca50STakashi Iwai 
24537e661eeSTakashi Iwai #define azx_get_snoop_type(chip) \
24637e661eeSTakashi Iwai 	(((chip)->driver_caps & AZX_DCAPS_SNOOP_MASK) >> 10)
24737e661eeSTakashi Iwai #define AZX_DCAPS_SNOOP_TYPE(type) ((AZX_SNOOP_TYPE_ ## type) << 10)
24837e661eeSTakashi Iwai 
249b42b4afbSTakashi Iwai /* quirks for old Intel chipsets */
250b42b4afbSTakashi Iwai #define AZX_DCAPS_INTEL_ICH \
251f34a4c9dSTakashi Iwai 	(AZX_DCAPS_OLD_SSYNC | AZX_DCAPS_NO_ALIGN_BUFSIZE)
252b42b4afbSTakashi Iwai 
2532ea3c6a2STakashi Iwai /* quirks for Intel PCH */
2546603249dSTakashi Iwai #define AZX_DCAPS_INTEL_PCH_BASE \
255103884a3STakashi Iwai 	(AZX_DCAPS_NO_ALIGN_BUFSIZE | AZX_DCAPS_COUNT_LPIB_DELAY |\
256f34a4c9dSTakashi Iwai 	 AZX_DCAPS_SNOOP_TYPE(SCH))
257d7dab4dbSTakashi Iwai 
258dba9b7b6STakashi Iwai /* PCH up to IVB; no runtime PM; bind with i915 gfx */
2596603249dSTakashi Iwai #define AZX_DCAPS_INTEL_PCH_NOPM \
260dba9b7b6STakashi Iwai 	(AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_I915_COMPONENT)
2619477c58eSTakashi Iwai 
26255913110STakashi Iwai /* PCH for HSW/BDW; with runtime PM */
263dba9b7b6STakashi Iwai /* no i915 binding for this as HSW/BDW has another controller for HDMI */
2646603249dSTakashi Iwai #define AZX_DCAPS_INTEL_PCH \
265f5dac54dSKai-Heng Feng 	(AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME)
2666603249dSTakashi Iwai 
2676603249dSTakashi Iwai /* HSW HDMI */
26833499a15STakashi Iwai #define AZX_DCAPS_INTEL_HASWELL \
269103884a3STakashi Iwai 	(/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_COUNT_LPIB_DELAY |\
270dba9b7b6STakashi Iwai 	 AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_COMPONENT |\
271f34a4c9dSTakashi Iwai 	 AZX_DCAPS_SNOOP_TYPE(SCH))
27233499a15STakashi Iwai 
27354a0405dSLibin Yang /* Broadwell HDMI can't use position buffer reliably, force to use LPIB */
27454a0405dSLibin Yang #define AZX_DCAPS_INTEL_BROADWELL \
275103884a3STakashi Iwai 	(/*AZX_DCAPS_ALIGN_BUFSIZE |*/ AZX_DCAPS_POSFIX_LPIB |\
276dba9b7b6STakashi Iwai 	 AZX_DCAPS_PM_RUNTIME | AZX_DCAPS_I915_COMPONENT |\
277f34a4c9dSTakashi Iwai 	 AZX_DCAPS_SNOOP_TYPE(SCH))
27854a0405dSLibin Yang 
27940cc2392SMengdong Lin #define AZX_DCAPS_INTEL_BAYTRAIL \
280e454ff8eSTakashi Iwai 	(AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_I915_COMPONENT)
28140cc2392SMengdong Lin 
2822d846c74SLibin Yang #define AZX_DCAPS_INTEL_BRASWELL \
283dba9b7b6STakashi Iwai 	(AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME |\
284e454ff8eSTakashi Iwai 	 AZX_DCAPS_I915_COMPONENT)
2852d846c74SLibin Yang 
286d6795827SLibin Yang #define AZX_DCAPS_INTEL_SKYLAKE \
287dba9b7b6STakashi Iwai 	(AZX_DCAPS_INTEL_PCH_BASE | AZX_DCAPS_PM_RUNTIME |\
288e454ff8eSTakashi Iwai 	 AZX_DCAPS_SEPARATE_STREAM_TAG | AZX_DCAPS_I915_COMPONENT)
289d6795827SLibin Yang 
2902756d914STakashi Iwai #define AZX_DCAPS_INTEL_BROXTON		AZX_DCAPS_INTEL_SKYLAKE
291c87693daSLu, Han 
2929477c58eSTakashi Iwai /* quirks for ATI SB / AMD Hudson */
2939477c58eSTakashi Iwai #define AZX_DCAPS_PRESET_ATI_SB \
294f34a4c9dSTakashi Iwai 	(AZX_DCAPS_NO_TCSEL | AZX_DCAPS_POSFIX_LPIB |\
29537e661eeSTakashi Iwai 	 AZX_DCAPS_SNOOP_TYPE(ATI))
2969477c58eSTakashi Iwai 
2979477c58eSTakashi Iwai /* quirks for ATI/AMD HDMI */
2989477c58eSTakashi Iwai #define AZX_DCAPS_PRESET_ATI_HDMI \
299f34a4c9dSTakashi Iwai 	(AZX_DCAPS_NO_TCSEL | AZX_DCAPS_POSFIX_LPIB|\
300db79afa1SBenjamin Herrenschmidt 	 AZX_DCAPS_NO_MSI64)
3019477c58eSTakashi Iwai 
30237e661eeSTakashi Iwai /* quirks for ATI HDMI with snoop off */
30337e661eeSTakashi Iwai #define AZX_DCAPS_PRESET_ATI_HDMI_NS \
304b8c0aee7STakashi Iwai 	(AZX_DCAPS_PRESET_ATI_HDMI | AZX_DCAPS_SNOOP_OFF)
30537e661eeSTakashi Iwai 
306c02f77d3STakashi Iwai /* quirks for AMD SB */
307c02f77d3STakashi Iwai #define AZX_DCAPS_PRESET_AMD_SB \
308f34a4c9dSTakashi Iwai 	(AZX_DCAPS_NO_TCSEL | AZX_DCAPS_AMD_WORKAROUND |\
309c0f1886dSTakashi Iwai 	 AZX_DCAPS_SNOOP_TYPE(ATI) | AZX_DCAPS_PM_RUNTIME |\
310c0f1886dSTakashi Iwai 	 AZX_DCAPS_RETRY_PROBE)
311c02f77d3STakashi Iwai 
3129477c58eSTakashi Iwai /* quirks for Nvidia */
3139477c58eSTakashi Iwai #define AZX_DCAPS_PRESET_NVIDIA \
3143ab7511eSArd Biesheuvel 	(AZX_DCAPS_NO_MSI | AZX_DCAPS_CORBRP_SELF_CLEAR |\
31537e661eeSTakashi Iwai 	 AZX_DCAPS_SNOOP_TYPE(NVIDIA))
3169477c58eSTakashi Iwai 
3175ae763b1STakashi Iwai #define AZX_DCAPS_PRESET_CTHDA \
31837e661eeSTakashi Iwai 	(AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB |\
319cadd16eaSTakashi Iwai 	 AZX_DCAPS_NO_64BIT |\
32037e661eeSTakashi Iwai 	 AZX_DCAPS_4K_BDLE_BOUNDARY | AZX_DCAPS_SNOOP_OFF)
3215ae763b1STakashi Iwai 
322a82d51edSTakashi Iwai /*
3232b760d88SLukas Wunner  * vga_switcheroo support
324a82d51edSTakashi Iwai  */
325a82d51edSTakashi Iwai #ifdef SUPPORT_VGA_SWITCHEROO
3265cb543dbSTakashi Iwai #define use_vga_switcheroo(chip)	((chip)->use_vga_switcheroo)
327dd23e1d5STakashi Iwai #define needs_eld_notify_link(chip)	((chip)->bus.keep_power)
3285cb543dbSTakashi Iwai #else
3295cb543dbSTakashi Iwai #define use_vga_switcheroo(chip)	0
33037a3a98eSTakashi Iwai #define needs_eld_notify_link(chip)	false
3315cb543dbSTakashi Iwai #endif
3325cb543dbSTakashi Iwai 
333bf82326fSTakashi Iwai static const char * const driver_short_names[] = {
33407e4ca50STakashi Iwai 	[AZX_DRIVER_ICH] = "HDA Intel",
33532679f95SSeth Heasley 	[AZX_DRIVER_PCH] = "HDA Intel PCH",
3364979bca9STobin Davis 	[AZX_DRIVER_SCH] = "HDA Intel MID",
337a4b4793fSTakashi Iwai 	[AZX_DRIVER_SKL] = "HDA Intel PCH", /* kept old name for compatibility */
338fab1285aSTakashi Iwai 	[AZX_DRIVER_HDMI] = "HDA Intel HDMI",
33907e4ca50STakashi Iwai 	[AZX_DRIVER_ATI] = "HDA ATI SB",
340778b6e1bSFelix Kuehling 	[AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI",
3411815b34aSAndiry Xu 	[AZX_DRIVER_ATIHDMI_NS] = "HDA ATI HDMI",
342c51e4310Sjasontao 	[AZX_DRIVER_GFHDMI] = "HDA GF HDMI",
34307e4ca50STakashi Iwai 	[AZX_DRIVER_VIA] = "HDA VIA VT82xx",
34407e4ca50STakashi Iwai 	[AZX_DRIVER_SIS] = "HDA SIS966",
345da3fca21SVinod G 	[AZX_DRIVER_ULI] = "HDA ULI M5461",
346da3fca21SVinod G 	[AZX_DRIVER_NVIDIA] = "HDA NVidia",
347f269002eSKailang Yang 	[AZX_DRIVER_TERA] = "HDA Teradici",
34814d34f16STakashi Iwai 	[AZX_DRIVER_CTX] = "HDA Creative",
3495ae763b1STakashi Iwai 	[AZX_DRIVER_CTHDA] = "HDA Creative",
350c563f473STakashi Iwai 	[AZX_DRIVER_CMEDIA] = "HDA C-Media",
351b6fcab14STony W Wang-oc 	[AZX_DRIVER_ZHAOXIN] = "HDA Zhaoxin",
35228bd137aSYanteng Si 	[AZX_DRIVER_LOONGSON] = "HDA Loongson",
353c4da29caSYang, Libin 	[AZX_DRIVER_GENERIC] = "HD-Audio Generic",
35407e4ca50STakashi Iwai };
35507e4ca50STakashi Iwai 
35668e7fffcSTakashi Iwai static int azx_acquire_irq(struct azx *chip, int do_disconnect);
35737a3a98eSTakashi Iwai static void set_default_power_save(struct azx *chip);
358111d3af5STakashi Iwai 
359cb53c626STakashi Iwai /*
360cb53c626STakashi Iwai  * initialize the PCI registers
361cb53c626STakashi Iwai  */
362cb53c626STakashi Iwai /* update bits in a PCI register byte */
update_pci_byte(struct pci_dev * pci,unsigned int reg,unsigned char mask,unsigned char val)363cb53c626STakashi Iwai static void update_pci_byte(struct pci_dev *pci, unsigned int reg,
364cb53c626STakashi Iwai 			    unsigned char mask, unsigned char val)
365cb53c626STakashi Iwai {
366cb53c626STakashi Iwai 	unsigned char data;
367cb53c626STakashi Iwai 
368cb53c626STakashi Iwai 	pci_read_config_byte(pci, reg, &data);
369cb53c626STakashi Iwai 	data &= ~mask;
370cb53c626STakashi Iwai 	data |= (val & mask);
371cb53c626STakashi Iwai 	pci_write_config_byte(pci, reg, data);
372cb53c626STakashi Iwai }
373cb53c626STakashi Iwai 
azx_init_pci(struct azx * chip)374cb53c626STakashi Iwai static void azx_init_pci(struct azx *chip)
375cb53c626STakashi Iwai {
37637e661eeSTakashi Iwai 	int snoop_type = azx_get_snoop_type(chip);
37737e661eeSTakashi Iwai 
378cb53c626STakashi Iwai 	/* Clear bits 0-2 of PCI register TCSEL (at offset 0x44)
379cb53c626STakashi Iwai 	 * TCSEL == Traffic Class Select Register, which sets PCI express QOS
380cb53c626STakashi Iwai 	 * Ensuring these bits are 0 clears playback static on some HD Audio
381a09e89f6SAdam Lackorzynski 	 * codecs.
382a09e89f6SAdam Lackorzynski 	 * The PCI register TCSEL is defined in the Intel manuals.
383cb53c626STakashi Iwai 	 */
38446f2cc80SLinus Torvalds 	if (!(chip->driver_caps & AZX_DCAPS_NO_TCSEL)) {
3854e76a883STakashi Iwai 		dev_dbg(chip->card->dev, "Clearing TCSEL\n");
386fb1d8ac2STakashi Iwai 		update_pci_byte(chip->pci, AZX_PCIREG_TCSEL, 0x07, 0);
3879477c58eSTakashi Iwai 	}
388cb53c626STakashi Iwai 
3899477c58eSTakashi Iwai 	/* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio,
3909477c58eSTakashi Iwai 	 * we need to enable snoop.
3919477c58eSTakashi Iwai 	 */
39237e661eeSTakashi Iwai 	if (snoop_type == AZX_SNOOP_TYPE_ATI) {
3934e76a883STakashi Iwai 		dev_dbg(chip->card->dev, "Setting ATI snoop: %d\n",
3944e76a883STakashi Iwai 			azx_snoop(chip));
395cb53c626STakashi Iwai 		update_pci_byte(chip->pci,
39627fe48d9STakashi Iwai 				ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 0x07,
39727fe48d9STakashi Iwai 				azx_snoop(chip) ? ATI_SB450_HDAUDIO_ENABLE_SNOOP : 0);
3989477c58eSTakashi Iwai 	}
3999477c58eSTakashi Iwai 
400da3fca21SVinod G 	/* For NVIDIA HDA, enable snoop */
40137e661eeSTakashi Iwai 	if (snoop_type == AZX_SNOOP_TYPE_NVIDIA) {
4024e76a883STakashi Iwai 		dev_dbg(chip->card->dev, "Setting Nvidia snoop: %d\n",
4034e76a883STakashi Iwai 			azx_snoop(chip));
404cb53c626STakashi Iwai 		update_pci_byte(chip->pci,
405cb53c626STakashi Iwai 				NVIDIA_HDA_TRANSREG_ADDR,
406cb53c626STakashi Iwai 				0x0f, NVIDIA_HDA_ENABLE_COHBITS);
407320dcc30SPeer Chen 		update_pci_byte(chip->pci,
408320dcc30SPeer Chen 				NVIDIA_HDA_ISTRM_COH,
409320dcc30SPeer Chen 				0x01, NVIDIA_HDA_ENABLE_COHBIT);
410320dcc30SPeer Chen 		update_pci_byte(chip->pci,
411320dcc30SPeer Chen 				NVIDIA_HDA_OSTRM_COH,
412320dcc30SPeer Chen 				0x01, NVIDIA_HDA_ENABLE_COHBIT);
4139477c58eSTakashi Iwai 	}
4149477c58eSTakashi Iwai 
4159477c58eSTakashi Iwai 	/* Enable SCH/PCH snoop if needed */
41637e661eeSTakashi Iwai 	if (snoop_type == AZX_SNOOP_TYPE_SCH) {
41727fe48d9STakashi Iwai 		unsigned short snoop;
41890a5ad52STakashi Iwai 		pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
41927fe48d9STakashi Iwai 		if ((!azx_snoop(chip) && !(snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)) ||
42027fe48d9STakashi Iwai 		    (azx_snoop(chip) && (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP))) {
42127fe48d9STakashi Iwai 			snoop &= ~INTEL_SCH_HDA_DEVC_NOSNOOP;
42227fe48d9STakashi Iwai 			if (!azx_snoop(chip))
42327fe48d9STakashi Iwai 				snoop |= INTEL_SCH_HDA_DEVC_NOSNOOP;
42427fe48d9STakashi Iwai 			pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, snoop);
42590a5ad52STakashi Iwai 			pci_read_config_word(chip->pci,
42690a5ad52STakashi Iwai 				INTEL_SCH_HDA_DEVC, &snoop);
42790a5ad52STakashi Iwai 		}
4284e76a883STakashi Iwai 		dev_dbg(chip->card->dev, "SCH snoop: %s\n",
4294e76a883STakashi Iwai 			(snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) ?
4304e76a883STakashi Iwai 			"Disabled" : "Enabled");
431f5d40b30SFrederick Li         }
4321da177e4SLinus Torvalds }
4331da177e4SLinus Torvalds 
4347c23b7c1SLu, Han /*
4357c23b7c1SLu, Han  * In BXT-P A0, HD-Audio DMA requests is later than expected,
4367c23b7c1SLu, Han  * and makes an audio stream sensitive to system latencies when
4377c23b7c1SLu, Han  * 24/32 bits are playing.
4387c23b7c1SLu, Han  * Adjusting threshold of DMA fifo to force the DMA request
4397c23b7c1SLu, Han  * sooner to improve latency tolerance at the expense of power.
4407c23b7c1SLu, Han  */
bxt_reduce_dma_latency(struct azx * chip)4417c23b7c1SLu, Han static void bxt_reduce_dma_latency(struct azx *chip)
4427c23b7c1SLu, Han {
4437c23b7c1SLu, Han 	u32 val;
4447c23b7c1SLu, Han 
44570eafad8STakashi Iwai 	val = azx_readl(chip, VS_EM4L);
4467c23b7c1SLu, Han 	val &= (0x3 << 20);
44770eafad8STakashi Iwai 	azx_writel(chip, VS_EM4L, val);
4487c23b7c1SLu, Han }
4497c23b7c1SLu, Han 
4501f9d3d98SLibin Yang /*
4511f9d3d98SLibin Yang  * ML_LCAP bits:
4521f9d3d98SLibin Yang  *  bit 0: 6 MHz Supported
4531f9d3d98SLibin Yang  *  bit 1: 12 MHz Supported
4541f9d3d98SLibin Yang  *  bit 2: 24 MHz Supported
4551f9d3d98SLibin Yang  *  bit 3: 48 MHz Supported
4561f9d3d98SLibin Yang  *  bit 4: 96 MHz Supported
4571f9d3d98SLibin Yang  *  bit 5: 192 MHz Supported
4581f9d3d98SLibin Yang  */
intel_get_lctl_scf(struct azx * chip)4591f9d3d98SLibin Yang static int intel_get_lctl_scf(struct azx *chip)
4601f9d3d98SLibin Yang {
4611f9d3d98SLibin Yang 	struct hdac_bus *bus = azx_bus(chip);
462bf82326fSTakashi Iwai 	static const int preferred_bits[] = { 2, 3, 1, 4, 5 };
4631f9d3d98SLibin Yang 	u32 val, t;
4641f9d3d98SLibin Yang 	int i;
4651f9d3d98SLibin Yang 
4661f9d3d98SLibin Yang 	val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCAP);
4671f9d3d98SLibin Yang 
4681f9d3d98SLibin Yang 	for (i = 0; i < ARRAY_SIZE(preferred_bits); i++) {
4691f9d3d98SLibin Yang 		t = preferred_bits[i];
4701f9d3d98SLibin Yang 		if (val & (1 << t))
4711f9d3d98SLibin Yang 			return t;
4721f9d3d98SLibin Yang 	}
4731f9d3d98SLibin Yang 
4741f9d3d98SLibin Yang 	dev_warn(chip->card->dev, "set audio clock frequency to 6MHz");
4751f9d3d98SLibin Yang 	return 0;
4761f9d3d98SLibin Yang }
4771f9d3d98SLibin Yang 
intel_ml_lctl_set_power(struct azx * chip,int state)4781f9d3d98SLibin Yang static int intel_ml_lctl_set_power(struct azx *chip, int state)
4791f9d3d98SLibin Yang {
4801f9d3d98SLibin Yang 	struct hdac_bus *bus = azx_bus(chip);
4811f9d3d98SLibin Yang 	u32 val;
4821f9d3d98SLibin Yang 	int timeout;
4831f9d3d98SLibin Yang 
4841f9d3d98SLibin Yang 	/*
48510e794bdSPierre-Louis Bossart 	 * Changes to LCTL.SCF are only needed for the first multi-link dealing
48610e794bdSPierre-Louis Bossart 	 * with external codecs
4871f9d3d98SLibin Yang 	 */
4881f9d3d98SLibin Yang 	val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
48918afcf90SPierre-Louis Bossart 	val &= ~AZX_ML_LCTL_SPA;
49018afcf90SPierre-Louis Bossart 	val |= state << AZX_ML_LCTL_SPA_SHIFT;
4911f9d3d98SLibin Yang 	writel(val, bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
4921f9d3d98SLibin Yang 	/* wait for CPA */
4931f9d3d98SLibin Yang 	timeout = 50;
4941f9d3d98SLibin Yang 	while (timeout) {
4951f9d3d98SLibin Yang 		if (((readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL)) &
49618afcf90SPierre-Louis Bossart 		    AZX_ML_LCTL_CPA) == (state << AZX_ML_LCTL_CPA_SHIFT))
4971f9d3d98SLibin Yang 			return 0;
4981f9d3d98SLibin Yang 		timeout--;
4991f9d3d98SLibin Yang 		udelay(10);
5001f9d3d98SLibin Yang 	}
5011f9d3d98SLibin Yang 
5021f9d3d98SLibin Yang 	return -1;
5031f9d3d98SLibin Yang }
5041f9d3d98SLibin Yang 
intel_init_lctl(struct azx * chip)5051f9d3d98SLibin Yang static void intel_init_lctl(struct azx *chip)
5061f9d3d98SLibin Yang {
5071f9d3d98SLibin Yang 	struct hdac_bus *bus = azx_bus(chip);
5081f9d3d98SLibin Yang 	u32 val;
5091f9d3d98SLibin Yang 	int ret;
5101f9d3d98SLibin Yang 
5111f9d3d98SLibin Yang 	/* 0. check lctl register value is correct or not */
5121f9d3d98SLibin Yang 	val = readl(bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
51310e794bdSPierre-Louis Bossart 	/* only perform additional configurations if the SCF is initially based on 6MHz */
51418afcf90SPierre-Louis Bossart 	if ((val & AZX_ML_LCTL_SCF) != 0)
5151f9d3d98SLibin Yang 		return;
5161f9d3d98SLibin Yang 
5171f9d3d98SLibin Yang 	/*
5181f9d3d98SLibin Yang 	 * Before operating on SPA, CPA must match SPA.
5191f9d3d98SLibin Yang 	 * Any deviation may result in undefined behavior.
5201f9d3d98SLibin Yang 	 */
52118afcf90SPierre-Louis Bossart 	if (((val & AZX_ML_LCTL_SPA) >> AZX_ML_LCTL_SPA_SHIFT) !=
52218afcf90SPierre-Louis Bossart 		((val & AZX_ML_LCTL_CPA) >> AZX_ML_LCTL_CPA_SHIFT))
5231f9d3d98SLibin Yang 		return;
5241f9d3d98SLibin Yang 
5251f9d3d98SLibin Yang 	/* 1. turn link down: set SPA to 0 and wait CPA to 0 */
5261f9d3d98SLibin Yang 	ret = intel_ml_lctl_set_power(chip, 0);
5271f9d3d98SLibin Yang 	udelay(100);
5281f9d3d98SLibin Yang 	if (ret)
5291f9d3d98SLibin Yang 		goto set_spa;
5301f9d3d98SLibin Yang 
53110e794bdSPierre-Louis Bossart 	/* 2. update SCF to select an audio clock different from 6MHz */
53218afcf90SPierre-Louis Bossart 	val &= ~AZX_ML_LCTL_SCF;
5331f9d3d98SLibin Yang 	val |= intel_get_lctl_scf(chip);
5341f9d3d98SLibin Yang 	writel(val, bus->mlcap + AZX_ML_BASE + AZX_REG_ML_LCTL);
5351f9d3d98SLibin Yang 
5361f9d3d98SLibin Yang set_spa:
5371f9d3d98SLibin Yang 	/* 4. turn link up: set SPA to 1 and wait CPA to 1 */
5381f9d3d98SLibin Yang 	intel_ml_lctl_set_power(chip, 1);
5391f9d3d98SLibin Yang 	udelay(100);
5401f9d3d98SLibin Yang }
5411f9d3d98SLibin Yang 
hda_intel_init_chip(struct azx * chip,bool full_reset)5420a673521SLu, Han static void hda_intel_init_chip(struct azx *chip, bool full_reset)
5430a673521SLu, Han {
54498d8fc6cSMengdong Lin 	struct hdac_bus *bus = azx_bus(chip);
5457c23b7c1SLu, Han 	struct pci_dev *pci = chip->pci;
5466639484dSLibin Yang 	u32 val;
5470a673521SLu, Han 
54898d8fc6cSMengdong Lin 	snd_hdac_set_codec_wakeup(bus, true);
549a4b4793fSTakashi Iwai 	if (chip->driver_type == AZX_DRIVER_SKL) {
5506639484dSLibin Yang 		pci_read_config_dword(pci, INTEL_HDA_CGCTL, &val);
5516639484dSLibin Yang 		val = val & ~INTEL_HDA_CGCTL_MISCBDCGE;
5526639484dSLibin Yang 		pci_write_config_dword(pci, INTEL_HDA_CGCTL, val);
5536639484dSLibin Yang 	}
5540a673521SLu, Han 	azx_init_chip(chip, full_reset);
555a4b4793fSTakashi Iwai 	if (chip->driver_type == AZX_DRIVER_SKL) {
5566639484dSLibin Yang 		pci_read_config_dword(pci, INTEL_HDA_CGCTL, &val);
5576639484dSLibin Yang 		val = val | INTEL_HDA_CGCTL_MISCBDCGE;
5586639484dSLibin Yang 		pci_write_config_dword(pci, INTEL_HDA_CGCTL, val);
5596639484dSLibin Yang 	}
560e454ff8eSTakashi Iwai 
56198d8fc6cSMengdong Lin 	snd_hdac_set_codec_wakeup(bus, false);
5627c23b7c1SLu, Han 
5637c23b7c1SLu, Han 	/* reduce dma latency to avoid noise */
5641b21bd7aSAmadeusz Sławiński 	if (HDA_CONTROLLER_IS_APL(pci))
5657c23b7c1SLu, Han 		bxt_reduce_dma_latency(chip);
5661f9d3d98SLibin Yang 
5671f9d3d98SLibin Yang 	if (bus->mlcap != NULL)
5681f9d3d98SLibin Yang 		intel_init_lctl(chip);
5690a673521SLu, Han }
5700a673521SLu, Han 
571b6050ef6STakashi Iwai /* calculate runtime delay from LPIB */
azx_get_delay_from_lpib(struct azx * chip,struct azx_dev * azx_dev,unsigned int pos)572b6050ef6STakashi Iwai static int azx_get_delay_from_lpib(struct azx *chip, struct azx_dev *azx_dev,
573b6050ef6STakashi Iwai 				   unsigned int pos)
574b6050ef6STakashi Iwai {
5757833c3f8STakashi Iwai 	struct snd_pcm_substream *substream = azx_dev->core.substream;
576b6050ef6STakashi Iwai 	int stream = substream->stream;
577b6050ef6STakashi Iwai 	unsigned int lpib_pos = azx_get_pos_lpib(chip, azx_dev);
578b6050ef6STakashi Iwai 	int delay;
579b6050ef6STakashi Iwai 
580b6050ef6STakashi Iwai 	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
581b6050ef6STakashi Iwai 		delay = pos - lpib_pos;
582b6050ef6STakashi Iwai 	else
583b6050ef6STakashi Iwai 		delay = lpib_pos - pos;
584b6050ef6STakashi Iwai 	if (delay < 0) {
5857833c3f8STakashi Iwai 		if (delay >= azx_dev->core.delay_negative_threshold)
586b6050ef6STakashi Iwai 			delay = 0;
587b6050ef6STakashi Iwai 		else
5887833c3f8STakashi Iwai 			delay += azx_dev->core.bufsize;
589b6050ef6STakashi Iwai 	}
590b6050ef6STakashi Iwai 
5917833c3f8STakashi Iwai 	if (delay >= azx_dev->core.period_bytes) {
592b6050ef6STakashi Iwai 		dev_info(chip->card->dev,
593b6050ef6STakashi Iwai 			 "Unstable LPIB (%d >= %d); disabling LPIB delay counting\n",
5947833c3f8STakashi Iwai 			 delay, azx_dev->core.period_bytes);
595b6050ef6STakashi Iwai 		delay = 0;
596b6050ef6STakashi Iwai 		chip->driver_caps &= ~AZX_DCAPS_COUNT_LPIB_DELAY;
597b6050ef6STakashi Iwai 		chip->get_delay[stream] = NULL;
598b6050ef6STakashi Iwai 	}
599b6050ef6STakashi Iwai 
600b6050ef6STakashi Iwai 	return bytes_to_frames(substream->runtime, delay);
601b6050ef6STakashi Iwai }
602b6050ef6STakashi Iwai 
6039ad593f6STakashi Iwai static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev);
6049ad593f6STakashi Iwai 
6057ca954a8SDylan Reid /* called from IRQ */
azx_position_check(struct azx * chip,struct azx_dev * azx_dev)6067ca954a8SDylan Reid static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
6077ca954a8SDylan Reid {
6089a34af4aSTakashi Iwai 	struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
6097ca954a8SDylan Reid 	int ok;
6107ca954a8SDylan Reid 
6117ca954a8SDylan Reid 	ok = azx_position_ok(chip, azx_dev);
6127ca954a8SDylan Reid 	if (ok == 1) {
6137ca954a8SDylan Reid 		azx_dev->irq_pending = 0;
6147ca954a8SDylan Reid 		return ok;
6152f35c630STakashi Iwai 	} else if (ok == 0) {
6167ca954a8SDylan Reid 		/* bogus IRQ, process it later */
6177ca954a8SDylan Reid 		azx_dev->irq_pending = 1;
6182f35c630STakashi Iwai 		schedule_work(&hda->irq_pending_work);
6197ca954a8SDylan Reid 	}
6207ca954a8SDylan Reid 	return 0;
6217ca954a8SDylan Reid }
6227ca954a8SDylan Reid 
623029d92c2STakashi Iwai #define display_power(chip, enable) \
624029d92c2STakashi Iwai 	snd_hdac_display_power(azx_bus(chip), HDA_CODEC_IDX_CONTROLLER, enable)
62517eccb27SMengdong Lin 
6261da177e4SLinus Torvalds /*
6279ad593f6STakashi Iwai  * Check whether the current DMA position is acceptable for updating
6289ad593f6STakashi Iwai  * periods.  Returns non-zero if it's OK.
6299ad593f6STakashi Iwai  *
6309ad593f6STakashi Iwai  * Many HD-audio controllers appear pretty inaccurate about
6319ad593f6STakashi Iwai  * the update-IRQ timing.  The IRQ is issued before actually the
6329ad593f6STakashi Iwai  * data is processed.  So, we need to process it afterwords in a
6339ad593f6STakashi Iwai  * workqueue.
63446243b85STakashi Iwai  *
63546243b85STakashi Iwai  * Returns 1 if OK to proceed, 0 for delay handling, -1 for skipping update
6369ad593f6STakashi Iwai  */
azx_position_ok(struct azx * chip,struct azx_dev * azx_dev)6379ad593f6STakashi Iwai static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev)
6389ad593f6STakashi Iwai {
6397833c3f8STakashi Iwai 	struct snd_pcm_substream *substream = azx_dev->core.substream;
64046243b85STakashi Iwai 	struct snd_pcm_runtime *runtime = substream->runtime;
641b6050ef6STakashi Iwai 	int stream = substream->stream;
642e5463720SJaroslav Kysela 	u32 wallclk;
6439ad593f6STakashi Iwai 	unsigned int pos;
64446243b85STakashi Iwai 	snd_pcm_uframes_t hwptr, target;
6459ad593f6STakashi Iwai 
646a4d2b853SYanteng Si 	/*
647a4d2b853SYanteng Si 	 * The value of the WALLCLK register is always 0
648a4d2b853SYanteng Si 	 * on the Loongson controller, so we return directly.
649a4d2b853SYanteng Si 	 */
650a4d2b853SYanteng Si 	if (chip->driver_type == AZX_DRIVER_LOONGSON)
651a4d2b853SYanteng Si 		return 1;
652a4d2b853SYanteng Si 
6537833c3f8STakashi Iwai 	wallclk = azx_readl(chip, WALLCLK) - azx_dev->core.start_wallclk;
6547833c3f8STakashi Iwai 	if (wallclk < (azx_dev->core.period_wallclk * 2) / 3)
655fa00e046SJaroslav Kysela 		return -1;	/* bogus (too early) interrupt */
656fa00e046SJaroslav Kysela 
657b6050ef6STakashi Iwai 	if (chip->get_position[stream])
658b6050ef6STakashi Iwai 		pos = chip->get_position[stream](chip, azx_dev);
659b6050ef6STakashi Iwai 	else { /* use the position buffer as default */
660b6050ef6STakashi Iwai 		pos = azx_get_pos_posbuf(chip, azx_dev);
661b6050ef6STakashi Iwai 		if (!pos || pos == (u32)-1) {
662b6050ef6STakashi Iwai 			dev_info(chip->card->dev,
663b6050ef6STakashi Iwai 				 "Invalid position buffer, using LPIB read method instead.\n");
664b6050ef6STakashi Iwai 			chip->get_position[stream] = azx_get_pos_lpib;
665ccc98865STakashi Iwai 			if (chip->get_position[0] == azx_get_pos_lpib &&
666ccc98865STakashi Iwai 			    chip->get_position[1] == azx_get_pos_lpib)
667ccc98865STakashi Iwai 				azx_bus(chip)->use_posbuf = false;
668b6050ef6STakashi Iwai 			pos = azx_get_pos_lpib(chip, azx_dev);
669b6050ef6STakashi Iwai 			chip->get_delay[stream] = NULL;
670b6050ef6STakashi Iwai 		} else {
671b6050ef6STakashi Iwai 			chip->get_position[stream] = azx_get_pos_posbuf;
672b6050ef6STakashi Iwai 			if (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)
673b6050ef6STakashi Iwai 				chip->get_delay[stream] = azx_get_delay_from_lpib;
674b6050ef6STakashi Iwai 		}
675b6050ef6STakashi Iwai 	}
676b6050ef6STakashi Iwai 
6777833c3f8STakashi Iwai 	if (pos >= azx_dev->core.bufsize)
678b6050ef6STakashi Iwai 		pos = 0;
6799ad593f6STakashi Iwai 
6807833c3f8STakashi Iwai 	if (WARN_ONCE(!azx_dev->core.period_bytes,
681d6d8bf54STakashi Iwai 		      "hda-intel: zero azx_dev->period_bytes"))
682f48f606dSJaroslav Kysela 		return -1; /* this shouldn't happen! */
6837833c3f8STakashi Iwai 	if (wallclk < (azx_dev->core.period_wallclk * 5) / 4 &&
6847833c3f8STakashi Iwai 	    pos % azx_dev->core.period_bytes > azx_dev->core.period_bytes / 2)
685f48f606dSJaroslav Kysela 		/* NG - it's below the first next period boundary */
6864f0189beSTakashi Iwai 		return chip->bdl_pos_adj ? 0 : -1;
6877833c3f8STakashi Iwai 	azx_dev->core.start_wallclk += wallclk;
68846243b85STakashi Iwai 
68946243b85STakashi Iwai 	if (azx_dev->core.no_period_wakeup)
69046243b85STakashi Iwai 		return 1; /* OK, no need to check period boundary */
69146243b85STakashi Iwai 
69246243b85STakashi Iwai 	if (runtime->hw_ptr_base != runtime->hw_ptr_interrupt)
69346243b85STakashi Iwai 		return 1; /* OK, already in hwptr updating process */
69446243b85STakashi Iwai 
69546243b85STakashi Iwai 	/* check whether the period gets really elapsed */
69646243b85STakashi Iwai 	pos = bytes_to_frames(runtime, pos);
69746243b85STakashi Iwai 	hwptr = runtime->hw_ptr_base + pos;
69846243b85STakashi Iwai 	if (hwptr < runtime->status->hw_ptr)
69946243b85STakashi Iwai 		hwptr += runtime->buffer_size;
70046243b85STakashi Iwai 	target = runtime->hw_ptr_interrupt + runtime->period_size;
70146243b85STakashi Iwai 	if (hwptr < target) {
70246243b85STakashi Iwai 		/* too early wakeup, process it later */
70346243b85STakashi Iwai 		return chip->bdl_pos_adj ? 0 : -1;
70446243b85STakashi Iwai 	}
70546243b85STakashi Iwai 
7069ad593f6STakashi Iwai 	return 1; /* OK, it's fine */
7079ad593f6STakashi Iwai }
7089ad593f6STakashi Iwai 
7099ad593f6STakashi Iwai /*
7109ad593f6STakashi Iwai  * The work for pending PCM period updates.
7119ad593f6STakashi Iwai  */
azx_irq_pending_work(struct work_struct * work)7129ad593f6STakashi Iwai static void azx_irq_pending_work(struct work_struct *work)
7139ad593f6STakashi Iwai {
7149a34af4aSTakashi Iwai 	struct hda_intel *hda = container_of(work, struct hda_intel, irq_pending_work);
7159a34af4aSTakashi Iwai 	struct azx *chip = &hda->chip;
7167833c3f8STakashi Iwai 	struct hdac_bus *bus = azx_bus(chip);
7177833c3f8STakashi Iwai 	struct hdac_stream *s;
7187833c3f8STakashi Iwai 	int pending, ok;
7199ad593f6STakashi Iwai 
7209a34af4aSTakashi Iwai 	if (!hda->irq_pending_warned) {
7214e76a883STakashi Iwai 		dev_info(chip->card->dev,
7224e76a883STakashi Iwai 			 "IRQ timing workaround is activated for card #%d. Suggest a bigger bdl_pos_adj.\n",
723a6a950a8STakashi Iwai 			 chip->card->number);
7249a34af4aSTakashi Iwai 		hda->irq_pending_warned = 1;
725a6a950a8STakashi Iwai 	}
726a6a950a8STakashi Iwai 
7279ad593f6STakashi Iwai 	for (;;) {
7289ad593f6STakashi Iwai 		pending = 0;
729a41d1224STakashi Iwai 		spin_lock_irq(&bus->reg_lock);
7307833c3f8STakashi Iwai 		list_for_each_entry(s, &bus->stream_list, list) {
7317833c3f8STakashi Iwai 			struct azx_dev *azx_dev = stream_to_azx_dev(s);
7329ad593f6STakashi Iwai 			if (!azx_dev->irq_pending ||
7337833c3f8STakashi Iwai 			    !s->substream ||
7347833c3f8STakashi Iwai 			    !s->running)
7359ad593f6STakashi Iwai 				continue;
736e5463720SJaroslav Kysela 			ok = azx_position_ok(chip, azx_dev);
737e5463720SJaroslav Kysela 			if (ok > 0) {
7389ad593f6STakashi Iwai 				azx_dev->irq_pending = 0;
739a41d1224STakashi Iwai 				spin_unlock(&bus->reg_lock);
7407833c3f8STakashi Iwai 				snd_pcm_period_elapsed(s->substream);
741a41d1224STakashi Iwai 				spin_lock(&bus->reg_lock);
742e5463720SJaroslav Kysela 			} else if (ok < 0) {
743e5463720SJaroslav Kysela 				pending = 0;	/* too early */
7449ad593f6STakashi Iwai 			} else
7459ad593f6STakashi Iwai 				pending++;
7469ad593f6STakashi Iwai 		}
747a41d1224STakashi Iwai 		spin_unlock_irq(&bus->reg_lock);
7489ad593f6STakashi Iwai 		if (!pending)
7499ad593f6STakashi Iwai 			return;
75008af495fSTakashi Iwai 		msleep(1);
7519ad593f6STakashi Iwai 	}
7529ad593f6STakashi Iwai }
7539ad593f6STakashi Iwai 
7549ad593f6STakashi Iwai /* clear irq_pending flags and assure no on-going workq */
azx_clear_irq_pending(struct azx * chip)7559ad593f6STakashi Iwai static void azx_clear_irq_pending(struct azx *chip)
7569ad593f6STakashi Iwai {
7577833c3f8STakashi Iwai 	struct hdac_bus *bus = azx_bus(chip);
7587833c3f8STakashi Iwai 	struct hdac_stream *s;
7599ad593f6STakashi Iwai 
760a41d1224STakashi Iwai 	spin_lock_irq(&bus->reg_lock);
7617833c3f8STakashi Iwai 	list_for_each_entry(s, &bus->stream_list, list) {
7627833c3f8STakashi Iwai 		struct azx_dev *azx_dev = stream_to_azx_dev(s);
7637833c3f8STakashi Iwai 		azx_dev->irq_pending = 0;
7647833c3f8STakashi Iwai 	}
765a41d1224STakashi Iwai 	spin_unlock_irq(&bus->reg_lock);
7661da177e4SLinus Torvalds }
7671da177e4SLinus Torvalds 
azx_acquire_irq(struct azx * chip,int do_disconnect)76868e7fffcSTakashi Iwai static int azx_acquire_irq(struct azx *chip, int do_disconnect)
76968e7fffcSTakashi Iwai {
770a41d1224STakashi Iwai 	struct hdac_bus *bus = azx_bus(chip);
771a41d1224STakashi Iwai 
772437a5a46STakashi Iwai 	if (request_irq(chip->pci->irq, azx_interrupt,
773437a5a46STakashi Iwai 			chip->msi ? 0 : IRQF_SHARED,
774de65360bSHeiner Kallweit 			chip->card->irq_descr, chip)) {
7754e76a883STakashi Iwai 		dev_err(chip->card->dev,
7764e76a883STakashi Iwai 			"unable to grab IRQ %d, disabling device\n",
7774e76a883STakashi Iwai 			chip->pci->irq);
77868e7fffcSTakashi Iwai 		if (do_disconnect)
77968e7fffcSTakashi Iwai 			snd_card_disconnect(chip->card);
78068e7fffcSTakashi Iwai 		return -1;
78168e7fffcSTakashi Iwai 	}
782a41d1224STakashi Iwai 	bus->irq = chip->pci->irq;
783f36da940STakashi Iwai 	chip->card->sync_irq = bus->irq;
78469e13418STakashi Iwai 	pci_intx(chip->pci, !chip->msi);
78568e7fffcSTakashi Iwai 	return 0;
78668e7fffcSTakashi Iwai }
78768e7fffcSTakashi Iwai 
788b6050ef6STakashi Iwai /* get the current DMA position with correction on VIA chips */
azx_via_get_position(struct azx * chip,struct azx_dev * azx_dev)789b6050ef6STakashi Iwai static unsigned int azx_via_get_position(struct azx *chip,
790b6050ef6STakashi Iwai 					 struct azx_dev *azx_dev)
791b6050ef6STakashi Iwai {
792b6050ef6STakashi Iwai 	unsigned int link_pos, mini_pos, bound_pos;
793b6050ef6STakashi Iwai 	unsigned int mod_link_pos, mod_dma_pos, mod_mini_pos;
794b6050ef6STakashi Iwai 	unsigned int fifo_size;
795b6050ef6STakashi Iwai 
7961604eeeeSTakashi Iwai 	link_pos = snd_hdac_stream_get_pos_lpib(azx_stream(azx_dev));
7977833c3f8STakashi Iwai 	if (azx_dev->core.substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
798b6050ef6STakashi Iwai 		/* Playback, no problem using link position */
799b6050ef6STakashi Iwai 		return link_pos;
800b6050ef6STakashi Iwai 	}
801b6050ef6STakashi Iwai 
802b6050ef6STakashi Iwai 	/* Capture */
803b6050ef6STakashi Iwai 	/* For new chipset,
804b6050ef6STakashi Iwai 	 * use mod to get the DMA position just like old chipset
805b6050ef6STakashi Iwai 	 */
8067833c3f8STakashi Iwai 	mod_dma_pos = le32_to_cpu(*azx_dev->core.posbuf);
8077833c3f8STakashi Iwai 	mod_dma_pos %= azx_dev->core.period_bytes;
808b6050ef6STakashi Iwai 
8097da20788STakashi Iwai 	fifo_size = azx_stream(azx_dev)->fifo_size - 1;
810b6050ef6STakashi Iwai 
811b6050ef6STakashi Iwai 	if (azx_dev->insufficient) {
812b6050ef6STakashi Iwai 		/* Link position never gather than FIFO size */
813b6050ef6STakashi Iwai 		if (link_pos <= fifo_size)
814b6050ef6STakashi Iwai 			return 0;
815b6050ef6STakashi Iwai 
816b6050ef6STakashi Iwai 		azx_dev->insufficient = 0;
817b6050ef6STakashi Iwai 	}
818b6050ef6STakashi Iwai 
819b6050ef6STakashi Iwai 	if (link_pos <= fifo_size)
8207833c3f8STakashi Iwai 		mini_pos = azx_dev->core.bufsize + link_pos - fifo_size;
821b6050ef6STakashi Iwai 	else
822b6050ef6STakashi Iwai 		mini_pos = link_pos - fifo_size;
823b6050ef6STakashi Iwai 
824b6050ef6STakashi Iwai 	/* Find nearest previous boudary */
8257833c3f8STakashi Iwai 	mod_mini_pos = mini_pos % azx_dev->core.period_bytes;
8267833c3f8STakashi Iwai 	mod_link_pos = link_pos % azx_dev->core.period_bytes;
827b6050ef6STakashi Iwai 	if (mod_link_pos >= fifo_size)
828b6050ef6STakashi Iwai 		bound_pos = link_pos - mod_link_pos;
829b6050ef6STakashi Iwai 	else if (mod_dma_pos >= mod_mini_pos)
830b6050ef6STakashi Iwai 		bound_pos = mini_pos - mod_mini_pos;
831b6050ef6STakashi Iwai 	else {
8327833c3f8STakashi Iwai 		bound_pos = mini_pos - mod_mini_pos + azx_dev->core.period_bytes;
8337833c3f8STakashi Iwai 		if (bound_pos >= azx_dev->core.bufsize)
834b6050ef6STakashi Iwai 			bound_pos = 0;
835b6050ef6STakashi Iwai 	}
836b6050ef6STakashi Iwai 
837b6050ef6STakashi Iwai 	/* Calculate real DMA position we want */
838b6050ef6STakashi Iwai 	return bound_pos + mod_dma_pos;
839b6050ef6STakashi Iwai }
840b6050ef6STakashi Iwai 
841c02f77d3STakashi Iwai #define AMD_FIFO_SIZE	32
842c02f77d3STakashi Iwai 
843c02f77d3STakashi Iwai /* get the current DMA position with FIFO size correction */
azx_get_pos_fifo(struct azx * chip,struct azx_dev * azx_dev)844c02f77d3STakashi Iwai static unsigned int azx_get_pos_fifo(struct azx *chip, struct azx_dev *azx_dev)
845c02f77d3STakashi Iwai {
846c02f77d3STakashi Iwai 	struct snd_pcm_substream *substream = azx_dev->core.substream;
847c02f77d3STakashi Iwai 	struct snd_pcm_runtime *runtime = substream->runtime;
848c02f77d3STakashi Iwai 	unsigned int pos, delay;
849c02f77d3STakashi Iwai 
850c02f77d3STakashi Iwai 	pos = snd_hdac_stream_get_pos_lpib(azx_stream(azx_dev));
851c02f77d3STakashi Iwai 	if (!runtime)
852c02f77d3STakashi Iwai 		return pos;
853c02f77d3STakashi Iwai 
854c02f77d3STakashi Iwai 	runtime->delay = AMD_FIFO_SIZE;
855c02f77d3STakashi Iwai 	delay = frames_to_bytes(runtime, AMD_FIFO_SIZE);
856c02f77d3STakashi Iwai 	if (azx_dev->insufficient) {
857c02f77d3STakashi Iwai 		if (pos < delay) {
858c02f77d3STakashi Iwai 			delay = pos;
859c02f77d3STakashi Iwai 			runtime->delay = bytes_to_frames(runtime, pos);
860c02f77d3STakashi Iwai 		} else {
861c02f77d3STakashi Iwai 			azx_dev->insufficient = 0;
862c02f77d3STakashi Iwai 		}
863c02f77d3STakashi Iwai 	}
864c02f77d3STakashi Iwai 
865c02f77d3STakashi Iwai 	/* correct the DMA position for capture stream */
866c02f77d3STakashi Iwai 	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
867c02f77d3STakashi Iwai 		if (pos < delay)
868c02f77d3STakashi Iwai 			pos += azx_dev->core.bufsize;
869c02f77d3STakashi Iwai 		pos -= delay;
870c02f77d3STakashi Iwai 	}
871c02f77d3STakashi Iwai 
872c02f77d3STakashi Iwai 	return pos;
873c02f77d3STakashi Iwai }
874c02f77d3STakashi Iwai 
azx_get_delay_from_fifo(struct azx * chip,struct azx_dev * azx_dev,unsigned int pos)875c02f77d3STakashi Iwai static int azx_get_delay_from_fifo(struct azx *chip, struct azx_dev *azx_dev,
876c02f77d3STakashi Iwai 				   unsigned int pos)
877c02f77d3STakashi Iwai {
878c02f77d3STakashi Iwai 	struct snd_pcm_substream *substream = azx_dev->core.substream;
879c02f77d3STakashi Iwai 
880c02f77d3STakashi Iwai 	/* just read back the calculated value in the above */
881c02f77d3STakashi Iwai 	return substream->runtime->delay;
882c02f77d3STakashi Iwai }
883c02f77d3STakashi Iwai 
__azx_shutdown_chip(struct azx * chip,bool skip_link_reset)8846f445784STakashi Iwai static void __azx_shutdown_chip(struct azx *chip, bool skip_link_reset)
885472e18f6SImre Deak {
886472e18f6SImre Deak 	azx_stop_chip(chip);
8876f445784STakashi Iwai 	if (!skip_link_reset)
888472e18f6SImre Deak 		azx_enter_link_reset(chip);
889472e18f6SImre Deak 	azx_clear_irq_pending(chip);
890472e18f6SImre Deak 	display_power(chip, false);
891472e18f6SImre Deak }
892472e18f6SImre Deak 
89383012a7cSTakashi Iwai #ifdef CONFIG_PM
89465fcd41dSTakashi Iwai static DEFINE_MUTEX(card_list_lock);
89565fcd41dSTakashi Iwai static LIST_HEAD(card_list);
89665fcd41dSTakashi Iwai 
azx_shutdown_chip(struct azx * chip)8976f445784STakashi Iwai static void azx_shutdown_chip(struct azx *chip)
8986f445784STakashi Iwai {
8996f445784STakashi Iwai 	__azx_shutdown_chip(chip, false);
9006f445784STakashi Iwai }
9016f445784STakashi Iwai 
azx_add_card_list(struct azx * chip)90265fcd41dSTakashi Iwai static void azx_add_card_list(struct azx *chip)
90365fcd41dSTakashi Iwai {
9049a34af4aSTakashi Iwai 	struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
90565fcd41dSTakashi Iwai 	mutex_lock(&card_list_lock);
9069a34af4aSTakashi Iwai 	list_add(&hda->list, &card_list);
90765fcd41dSTakashi Iwai 	mutex_unlock(&card_list_lock);
90865fcd41dSTakashi Iwai }
90965fcd41dSTakashi Iwai 
azx_del_card_list(struct azx * chip)91065fcd41dSTakashi Iwai static void azx_del_card_list(struct azx *chip)
91165fcd41dSTakashi Iwai {
9129a34af4aSTakashi Iwai 	struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
91365fcd41dSTakashi Iwai 	mutex_lock(&card_list_lock);
9149a34af4aSTakashi Iwai 	list_del_init(&hda->list);
91565fcd41dSTakashi Iwai 	mutex_unlock(&card_list_lock);
91665fcd41dSTakashi Iwai }
91765fcd41dSTakashi Iwai 
91865fcd41dSTakashi Iwai /* trigger power-save check at writing parameter */
param_set_xint(const char * val,const struct kernel_param * kp)91965fcd41dSTakashi Iwai static int param_set_xint(const char *val, const struct kernel_param *kp)
92065fcd41dSTakashi Iwai {
9219a34af4aSTakashi Iwai 	struct hda_intel *hda;
92265fcd41dSTakashi Iwai 	struct azx *chip;
92365fcd41dSTakashi Iwai 	int prev = power_save;
92465fcd41dSTakashi Iwai 	int ret = param_set_int(val, kp);
92565fcd41dSTakashi Iwai 
92665fcd41dSTakashi Iwai 	if (ret || prev == power_save)
92765fcd41dSTakashi Iwai 		return ret;
92865fcd41dSTakashi Iwai 
92965fcd41dSTakashi Iwai 	mutex_lock(&card_list_lock);
9309a34af4aSTakashi Iwai 	list_for_each_entry(hda, &card_list, list) {
9319a34af4aSTakashi Iwai 		chip = &hda->chip;
932a41d1224STakashi Iwai 		if (!hda->probe_continued || chip->disabled)
93365fcd41dSTakashi Iwai 			continue;
934a41d1224STakashi Iwai 		snd_hda_set_power_save(&chip->bus, power_save * 1000);
93565fcd41dSTakashi Iwai 	}
93665fcd41dSTakashi Iwai 	mutex_unlock(&card_list_lock);
93765fcd41dSTakashi Iwai 	return 0;
93865fcd41dSTakashi Iwai }
9395c0b9becSTakashi Iwai 
9405c0b9becSTakashi Iwai /*
9415c0b9becSTakashi Iwai  * power management
9425c0b9becSTakashi Iwai  */
azx_is_pm_ready(struct snd_card * card)9433baffc4aSTakashi Iwai static bool azx_is_pm_ready(struct snd_card *card)
9441da177e4SLinus Torvalds {
9452d9772efSTakashi Iwai 	struct azx *chip;
9462d9772efSTakashi Iwai 	struct hda_intel *hda;
9471da177e4SLinus Torvalds 
9482d9772efSTakashi Iwai 	if (!card)
9493baffc4aSTakashi Iwai 		return false;
9502d9772efSTakashi Iwai 	chip = card->private_data;
9512d9772efSTakashi Iwai 	hda = container_of(chip, struct hda_intel, chip);
952342e8449SU. Artie Eoff 	if (chip->disabled || hda->init_failed || !chip->running)
9533baffc4aSTakashi Iwai 		return false;
9543baffc4aSTakashi Iwai 	return true;
9553baffc4aSTakashi Iwai }
956c5c21523STakashi Iwai 
__azx_runtime_resume(struct azx * chip)957f5dac54dSKai-Heng Feng static void __azx_runtime_resume(struct azx *chip)
9581da177e4SLinus Torvalds {
9593baffc4aSTakashi Iwai 	struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
9603baffc4aSTakashi Iwai 	struct hdac_bus *bus = azx_bus(chip);
9613baffc4aSTakashi Iwai 	struct hda_codec *codec;
9623baffc4aSTakashi Iwai 	int status;
963c5c21523STakashi Iwai 
964029d92c2STakashi Iwai 	display_power(chip, true);
965a52ff34eSTakashi Iwai 	if (hda->need_i915_power)
966a52ff34eSTakashi Iwai 		snd_hdac_i915_set_bclk(bus);
967a52ff34eSTakashi Iwai 
9683baffc4aSTakashi Iwai 	/* Read STATESTS before controller reset */
9693baffc4aSTakashi Iwai 	status = azx_readw(chip, STATESTS);
970d804ad92SMaxim Levitsky 
9713baffc4aSTakashi Iwai 	azx_init_pci(chip);
9720a673521SLu, Han 	hda_intel_init_chip(chip, true);
973d804ad92SMaxim Levitsky 
974f5dac54dSKai-Heng Feng 	/* Avoid codec resume if runtime resume is for system suspend */
975f5dac54dSKai-Heng Feng 	if (!chip->pm_prepared) {
976a6e7d0a4SKai Vehmanen 		list_for_each_codec(codec, &chip->bus) {
977a6e7d0a4SKai Vehmanen 			if (codec->relaxed_resume)
978a6e7d0a4SKai Vehmanen 				continue;
979a6e7d0a4SKai Vehmanen 
980a6e7d0a4SKai Vehmanen 			if (codec->forced_resume || (status & (1 << codec->addr)))
981a6e7d0a4SKai Vehmanen 				pm_request_resume(hda_codec_dev(codec));
982a6e7d0a4SKai Vehmanen 		}
9833baffc4aSTakashi Iwai 	}
9843baffc4aSTakashi Iwai 
985a52ff34eSTakashi Iwai 	/* power down again for link-controlled chips */
986e454ff8eSTakashi Iwai 	if (!hda->need_i915_power)
987029d92c2STakashi Iwai 		display_power(chip, false);
9883baffc4aSTakashi Iwai }
989a52ff34eSTakashi Iwai 
9903baffc4aSTakashi Iwai #ifdef CONFIG_PM_SLEEP
azx_prepare(struct device * dev)991f5dac54dSKai-Heng Feng static int azx_prepare(struct device *dev)
992f5dac54dSKai-Heng Feng {
993f5dac54dSKai-Heng Feng 	struct snd_card *card = dev_get_drvdata(dev);
994f5dac54dSKai-Heng Feng 	struct azx *chip;
995f5dac54dSKai-Heng Feng 
99666affb7bSTakashi Iwai 	if (!azx_is_pm_ready(card))
99766affb7bSTakashi Iwai 		return 0;
99866affb7bSTakashi Iwai 
999f5dac54dSKai-Heng Feng 	chip = card->private_data;
1000f5dac54dSKai-Heng Feng 	chip->pm_prepared = 1;
1001c8f79808STakashi Iwai 	snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1002f5dac54dSKai-Heng Feng 
100313661fc4STakashi Iwai 	flush_work(&azx_bus(chip)->unsol_work);
100413661fc4STakashi Iwai 
1005f5dac54dSKai-Heng Feng 	/* HDA controller always requires different WAKEEN for runtime suspend
1006f5dac54dSKai-Heng Feng 	 * and system suspend, so don't use direct-complete here.
1007f5dac54dSKai-Heng Feng 	 */
1008f5dac54dSKai-Heng Feng 	return 0;
1009f5dac54dSKai-Heng Feng }
1010f5dac54dSKai-Heng Feng 
azx_complete(struct device * dev)1011f5dac54dSKai-Heng Feng static void azx_complete(struct device *dev)
1012f5dac54dSKai-Heng Feng {
1013f5dac54dSKai-Heng Feng 	struct snd_card *card = dev_get_drvdata(dev);
1014f5dac54dSKai-Heng Feng 	struct azx *chip;
1015f5dac54dSKai-Heng Feng 
101666affb7bSTakashi Iwai 	if (!azx_is_pm_ready(card))
101766affb7bSTakashi Iwai 		return;
101866affb7bSTakashi Iwai 
1019f5dac54dSKai-Heng Feng 	chip = card->private_data;
1020c8f79808STakashi Iwai 	snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1021f5dac54dSKai-Heng Feng 	chip->pm_prepared = 0;
1022f5dac54dSKai-Heng Feng }
1023f5dac54dSKai-Heng Feng 
azx_suspend(struct device * dev)10243baffc4aSTakashi Iwai static int azx_suspend(struct device *dev)
10253baffc4aSTakashi Iwai {
10263baffc4aSTakashi Iwai 	struct snd_card *card = dev_get_drvdata(dev);
10273baffc4aSTakashi Iwai 	struct azx *chip;
10283baffc4aSTakashi Iwai 	struct hdac_bus *bus;
10293baffc4aSTakashi Iwai 
10303baffc4aSTakashi Iwai 	if (!azx_is_pm_ready(card))
10313baffc4aSTakashi Iwai 		return 0;
10323baffc4aSTakashi Iwai 
10333baffc4aSTakashi Iwai 	chip = card->private_data;
10343baffc4aSTakashi Iwai 	bus = azx_bus(chip);
1035472e18f6SImre Deak 	azx_shutdown_chip(chip);
10363baffc4aSTakashi Iwai 	if (bus->irq >= 0) {
10373baffc4aSTakashi Iwai 		free_irq(bus->irq, chip);
10383baffc4aSTakashi Iwai 		bus->irq = -1;
1039f36da940STakashi Iwai 		chip->card->sync_irq = -1;
10403baffc4aSTakashi Iwai 	}
10413baffc4aSTakashi Iwai 
10423baffc4aSTakashi Iwai 	if (chip->msi)
10433baffc4aSTakashi Iwai 		pci_disable_msi(chip->pci);
10443baffc4aSTakashi Iwai 
10453baffc4aSTakashi Iwai 	trace_azx_suspend(chip);
10463baffc4aSTakashi Iwai 	return 0;
10473baffc4aSTakashi Iwai }
10483baffc4aSTakashi Iwai 
azx_resume(struct device * dev)10493baffc4aSTakashi Iwai static int azx_resume(struct device *dev)
10503baffc4aSTakashi Iwai {
10513baffc4aSTakashi Iwai 	struct snd_card *card = dev_get_drvdata(dev);
10523baffc4aSTakashi Iwai 	struct azx *chip;
10533baffc4aSTakashi Iwai 
10543baffc4aSTakashi Iwai 	if (!azx_is_pm_ready(card))
10553baffc4aSTakashi Iwai 		return 0;
10563baffc4aSTakashi Iwai 
10573baffc4aSTakashi Iwai 	chip = card->private_data;
10583baffc4aSTakashi Iwai 	if (chip->msi)
10593baffc4aSTakashi Iwai 		if (pci_enable_msi(chip->pci) < 0)
10603baffc4aSTakashi Iwai 			chip->msi = 0;
10613baffc4aSTakashi Iwai 	if (azx_acquire_irq(chip, 1) < 0)
10623baffc4aSTakashi Iwai 		return -EIO;
1063c4c8dd6eSTakashi Iwai 
1064f5dac54dSKai-Heng Feng 	__azx_runtime_resume(chip);
1065785d8c4bSLibin Yang 
1066785d8c4bSLibin Yang 	trace_azx_resume(chip);
10671da177e4SLinus Torvalds 	return 0;
10681da177e4SLinus Torvalds }
1069b8dfc462SMengdong Lin 
10703e6db33aSXiong Zhang /* put codec down to D3 at hibernation for Intel SKL+;
10713e6db33aSXiong Zhang  * otherwise BIOS may still access the codec and screw up the driver
10723e6db33aSXiong Zhang  */
azx_freeze_noirq(struct device * dev)10733e6db33aSXiong Zhang static int azx_freeze_noirq(struct device *dev)
10743e6db33aSXiong Zhang {
1075a4b4793fSTakashi Iwai 	struct snd_card *card = dev_get_drvdata(dev);
1076a4b4793fSTakashi Iwai 	struct azx *chip = card->private_data;
10773e6db33aSXiong Zhang 	struct pci_dev *pci = to_pci_dev(dev);
10783e6db33aSXiong Zhang 
107910db5bccSTakashi Iwai 	if (!azx_is_pm_ready(card))
108010db5bccSTakashi Iwai 		return 0;
1081a4b4793fSTakashi Iwai 	if (chip->driver_type == AZX_DRIVER_SKL)
10823e6db33aSXiong Zhang 		pci_set_power_state(pci, PCI_D3hot);
10833e6db33aSXiong Zhang 
10843e6db33aSXiong Zhang 	return 0;
10853e6db33aSXiong Zhang }
10863e6db33aSXiong Zhang 
azx_thaw_noirq(struct device * dev)10873e6db33aSXiong Zhang static int azx_thaw_noirq(struct device *dev)
10883e6db33aSXiong Zhang {
1089a4b4793fSTakashi Iwai 	struct snd_card *card = dev_get_drvdata(dev);
1090a4b4793fSTakashi Iwai 	struct azx *chip = card->private_data;
10913e6db33aSXiong Zhang 	struct pci_dev *pci = to_pci_dev(dev);
10923e6db33aSXiong Zhang 
109310db5bccSTakashi Iwai 	if (!azx_is_pm_ready(card))
109410db5bccSTakashi Iwai 		return 0;
1095a4b4793fSTakashi Iwai 	if (chip->driver_type == AZX_DRIVER_SKL)
10963e6db33aSXiong Zhang 		pci_set_power_state(pci, PCI_D0);
10973e6db33aSXiong Zhang 
10983e6db33aSXiong Zhang 	return 0;
10993e6db33aSXiong Zhang }
11003e6db33aSXiong Zhang #endif /* CONFIG_PM_SLEEP */
11013e6db33aSXiong Zhang 
azx_runtime_suspend(struct device * dev)1102b8dfc462SMengdong Lin static int azx_runtime_suspend(struct device *dev)
1103b8dfc462SMengdong Lin {
1104b8dfc462SMengdong Lin 	struct snd_card *card = dev_get_drvdata(dev);
11052d9772efSTakashi Iwai 	struct azx *chip;
1106b8dfc462SMengdong Lin 
11073baffc4aSTakashi Iwai 	if (!azx_is_pm_ready(card))
11082d9772efSTakashi Iwai 		return 0;
11092d9772efSTakashi Iwai 	chip = card->private_data;
1110246efa4aSDave Airlie 
11117d4f606cSWang Xingchao 	/* enable controller wake up event */
1112f5dac54dSKai-Heng Feng 	azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) | STATESTS_INT_MASK);
11137d4f606cSWang Xingchao 
1114472e18f6SImre Deak 	azx_shutdown_chip(chip);
1115785d8c4bSLibin Yang 	trace_azx_runtime_suspend(chip);
1116b8dfc462SMengdong Lin 	return 0;
1117b8dfc462SMengdong Lin }
1118b8dfc462SMengdong Lin 
azx_runtime_resume(struct device * dev)1119b8dfc462SMengdong Lin static int azx_runtime_resume(struct device *dev)
1120b8dfc462SMengdong Lin {
1121b8dfc462SMengdong Lin 	struct snd_card *card = dev_get_drvdata(dev);
11222d9772efSTakashi Iwai 	struct azx *chip;
1123b8dfc462SMengdong Lin 
11243baffc4aSTakashi Iwai 	if (!azx_is_pm_ready(card))
11252d9772efSTakashi Iwai 		return 0;
11262d9772efSTakashi Iwai 	chip = card->private_data;
1127f5dac54dSKai-Heng Feng 	__azx_runtime_resume(chip);
11287d4f606cSWang Xingchao 
11297d4f606cSWang Xingchao 	/* disable controller Wake Up event*/
1130f5dac54dSKai-Heng Feng 	azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) & ~STATESTS_INT_MASK);
11317d4f606cSWang Xingchao 
1132785d8c4bSLibin Yang 	trace_azx_runtime_resume(chip);
1133b8dfc462SMengdong Lin 	return 0;
1134b8dfc462SMengdong Lin }
11356eb827d2STakashi Iwai 
azx_runtime_idle(struct device * dev)11366eb827d2STakashi Iwai static int azx_runtime_idle(struct device *dev)
11376eb827d2STakashi Iwai {
11386eb827d2STakashi Iwai 	struct snd_card *card = dev_get_drvdata(dev);
11392d9772efSTakashi Iwai 	struct azx *chip;
11402d9772efSTakashi Iwai 	struct hda_intel *hda;
11416eb827d2STakashi Iwai 
11422d9772efSTakashi Iwai 	if (!card)
11432d9772efSTakashi Iwai 		return 0;
11442d9772efSTakashi Iwai 
11452d9772efSTakashi Iwai 	chip = card->private_data;
11462d9772efSTakashi Iwai 	hda = container_of(chip, struct hda_intel, chip);
11471618e84aSTakashi Iwai 	if (chip->disabled || hda->init_failed)
1148246efa4aSDave Airlie 		return 0;
1149246efa4aSDave Airlie 
115055ed9cd1STakashi Iwai 	if (!power_save_controller || !azx_has_pm_runtime(chip) ||
1151342e8449SU. Artie Eoff 	    azx_bus(chip)->codec_powered || !chip->running)
11526eb827d2STakashi Iwai 		return -EBUSY;
11536eb827d2STakashi Iwai 
115437a3a98eSTakashi Iwai 	/* ELD notification gets broken when HD-audio bus is off */
1155dd23e1d5STakashi Iwai 	if (needs_eld_notify_link(chip))
115637a3a98eSTakashi Iwai 		return -EBUSY;
115737a3a98eSTakashi Iwai 
11586eb827d2STakashi Iwai 	return 0;
11596eb827d2STakashi Iwai }
11606eb827d2STakashi Iwai 
1161b8dfc462SMengdong Lin static const struct dev_pm_ops azx_pm = {
1162b8dfc462SMengdong Lin 	SET_SYSTEM_SLEEP_PM_OPS(azx_suspend, azx_resume)
11633e6db33aSXiong Zhang #ifdef CONFIG_PM_SLEEP
1164f5dac54dSKai-Heng Feng 	.prepare = azx_prepare,
1165f5dac54dSKai-Heng Feng 	.complete = azx_complete,
11663e6db33aSXiong Zhang 	.freeze_noirq = azx_freeze_noirq,
11673e6db33aSXiong Zhang 	.thaw_noirq = azx_thaw_noirq,
11683e6db33aSXiong Zhang #endif
11696eb827d2STakashi Iwai 	SET_RUNTIME_PM_OPS(azx_runtime_suspend, azx_runtime_resume, azx_runtime_idle)
1170b8dfc462SMengdong Lin };
1171b8dfc462SMengdong Lin 
117268cb2b55STakashi Iwai #define AZX_PM_OPS	&azx_pm
117368cb2b55STakashi Iwai #else
11743baffc4aSTakashi Iwai #define azx_add_card_list(chip) /* NOP */
11753baffc4aSTakashi Iwai #define azx_del_card_list(chip) /* NOP */
117668cb2b55STakashi Iwai #define AZX_PM_OPS	NULL
1177b8dfc462SMengdong Lin #endif /* CONFIG_PM */
11781da177e4SLinus Torvalds 
11791da177e4SLinus Torvalds 
118048c8b0ebSTakashi Iwai static int azx_probe_continue(struct azx *chip);
1181a82d51edSTakashi Iwai 
11828393ec4aSSteven Newbury #ifdef SUPPORT_VGA_SWITCHEROO
1183e23e7a14SBill Pemberton static struct pci_dev *get_bound_vga(struct pci_dev *pci);
1184a82d51edSTakashi Iwai 
azx_vs_set_state(struct pci_dev * pci,enum vga_switcheroo_state state)1185a82d51edSTakashi Iwai static void azx_vs_set_state(struct pci_dev *pci,
1186a82d51edSTakashi Iwai 			     enum vga_switcheroo_state state)
1187a82d51edSTakashi Iwai {
1188a82d51edSTakashi Iwai 	struct snd_card *card = pci_get_drvdata(pci);
1189a82d51edSTakashi Iwai 	struct azx *chip = card->private_data;
11909a34af4aSTakashi Iwai 	struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
119107f4f97dSLukas Wunner 	struct hda_codec *codec;
1192a82d51edSTakashi Iwai 	bool disabled;
1193a82d51edSTakashi Iwai 
11949a34af4aSTakashi Iwai 	wait_for_completion(&hda->probe_wait);
11959a34af4aSTakashi Iwai 	if (hda->init_failed)
1196a82d51edSTakashi Iwai 		return;
1197a82d51edSTakashi Iwai 
1198a82d51edSTakashi Iwai 	disabled = (state == VGA_SWITCHEROO_OFF);
1199a82d51edSTakashi Iwai 	if (chip->disabled == disabled)
1200a82d51edSTakashi Iwai 		return;
1201a82d51edSTakashi Iwai 
1202a41d1224STakashi Iwai 	if (!hda->probe_continued) {
1203a82d51edSTakashi Iwai 		chip->disabled = disabled;
1204a82d51edSTakashi Iwai 		if (!disabled) {
12054e76a883STakashi Iwai 			dev_info(chip->card->dev,
12064e76a883STakashi Iwai 				 "Start delayed initialization\n");
12072393e755STakashi Iwai 			if (azx_probe_continue(chip) < 0)
12084e76a883STakashi Iwai 				dev_err(chip->card->dev, "initialization error\n");
1209a82d51edSTakashi Iwai 		}
1210a82d51edSTakashi Iwai 	} else {
12112b760d88SLukas Wunner 		dev_info(chip->card->dev, "%s via vga_switcheroo\n",
1212445a51b3SDaniel J Blueman 			 disabled ? "Disabling" : "Enabling");
1213a82d51edSTakashi Iwai 		if (disabled) {
121407f4f97dSLukas Wunner 			list_for_each_codec(codec, &chip->bus) {
121507f4f97dSLukas Wunner 				pm_runtime_suspend(hda_codec_dev(codec));
121607f4f97dSLukas Wunner 				pm_runtime_disable(hda_codec_dev(codec));
121707f4f97dSLukas Wunner 			}
121807f4f97dSLukas Wunner 			pm_runtime_suspend(card->dev);
121907f4f97dSLukas Wunner 			pm_runtime_disable(card->dev);
12202b760d88SLukas Wunner 			/* when we get suspended by vga_switcheroo we end up in D3cold,
1221246efa4aSDave Airlie 			 * however we have no ACPI handle, so pci/acpi can't put us there,
1222246efa4aSDave Airlie 			 * put ourselves there */
1223246efa4aSDave Airlie 			pci->current_state = PCI_D3cold;
1224a82d51edSTakashi Iwai 			chip->disabled = true;
1225a41d1224STakashi Iwai 			if (snd_hda_lock_devices(&chip->bus))
12264e76a883STakashi Iwai 				dev_warn(chip->card->dev,
12274e76a883STakashi Iwai 					 "Cannot lock devices!\n");
1228a82d51edSTakashi Iwai 		} else {
1229a41d1224STakashi Iwai 			snd_hda_unlock_devices(&chip->bus);
1230a82d51edSTakashi Iwai 			chip->disabled = false;
123107f4f97dSLukas Wunner 			pm_runtime_enable(card->dev);
123207f4f97dSLukas Wunner 			list_for_each_codec(codec, &chip->bus) {
123307f4f97dSLukas Wunner 				pm_runtime_enable(hda_codec_dev(codec));
123407f4f97dSLukas Wunner 				pm_runtime_resume(hda_codec_dev(codec));
123507f4f97dSLukas Wunner 			}
1236a82d51edSTakashi Iwai 		}
1237a82d51edSTakashi Iwai 	}
1238a82d51edSTakashi Iwai }
1239a82d51edSTakashi Iwai 
azx_vs_can_switch(struct pci_dev * pci)1240a82d51edSTakashi Iwai static bool azx_vs_can_switch(struct pci_dev *pci)
1241a82d51edSTakashi Iwai {
1242a82d51edSTakashi Iwai 	struct snd_card *card = pci_get_drvdata(pci);
1243a82d51edSTakashi Iwai 	struct azx *chip = card->private_data;
12449a34af4aSTakashi Iwai 	struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
1245a82d51edSTakashi Iwai 
12469a34af4aSTakashi Iwai 	wait_for_completion(&hda->probe_wait);
12479a34af4aSTakashi Iwai 	if (hda->init_failed)
1248a82d51edSTakashi Iwai 		return false;
1249a41d1224STakashi Iwai 	if (chip->disabled || !hda->probe_continued)
1250a82d51edSTakashi Iwai 		return true;
1251a41d1224STakashi Iwai 	if (snd_hda_lock_devices(&chip->bus))
1252a82d51edSTakashi Iwai 		return false;
1253a41d1224STakashi Iwai 	snd_hda_unlock_devices(&chip->bus);
1254a82d51edSTakashi Iwai 	return true;
1255a82d51edSTakashi Iwai }
1256a82d51edSTakashi Iwai 
125737a3a98eSTakashi Iwai /*
125837a3a98eSTakashi Iwai  * The discrete GPU cannot power down unless the HDA controller runtime
125937a3a98eSTakashi Iwai  * suspends, so activate runtime PM on codecs even if power_save == 0.
126037a3a98eSTakashi Iwai  */
setup_vga_switcheroo_runtime_pm(struct azx * chip)126137a3a98eSTakashi Iwai static void setup_vga_switcheroo_runtime_pm(struct azx *chip)
126237a3a98eSTakashi Iwai {
126337a3a98eSTakashi Iwai 	struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
126437a3a98eSTakashi Iwai 	struct hda_codec *codec;
126537a3a98eSTakashi Iwai 
1266dd23e1d5STakashi Iwai 	if (hda->use_vga_switcheroo && !needs_eld_notify_link(chip)) {
126737a3a98eSTakashi Iwai 		list_for_each_codec(codec, &chip->bus)
126837a3a98eSTakashi Iwai 			codec->auto_runtime_pm = 1;
126937a3a98eSTakashi Iwai 		/* reset the power save setup */
127037a3a98eSTakashi Iwai 		if (chip->running)
127137a3a98eSTakashi Iwai 			set_default_power_save(chip);
127237a3a98eSTakashi Iwai 	}
127337a3a98eSTakashi Iwai }
127437a3a98eSTakashi Iwai 
azx_vs_gpu_bound(struct pci_dev * pci,enum vga_switcheroo_client_id client_id)127537a3a98eSTakashi Iwai static void azx_vs_gpu_bound(struct pci_dev *pci,
127637a3a98eSTakashi Iwai 			     enum vga_switcheroo_client_id client_id)
127737a3a98eSTakashi Iwai {
127837a3a98eSTakashi Iwai 	struct snd_card *card = pci_get_drvdata(pci);
127937a3a98eSTakashi Iwai 	struct azx *chip = card->private_data;
128037a3a98eSTakashi Iwai 
128137a3a98eSTakashi Iwai 	if (client_id == VGA_SWITCHEROO_DIS)
1282dd23e1d5STakashi Iwai 		chip->bus.keep_power = 0;
128337a3a98eSTakashi Iwai 	setup_vga_switcheroo_runtime_pm(chip);
128437a3a98eSTakashi Iwai }
128537a3a98eSTakashi Iwai 
init_vga_switcheroo(struct azx * chip)1286e23e7a14SBill Pemberton static void init_vga_switcheroo(struct azx *chip)
1287a82d51edSTakashi Iwai {
12889a34af4aSTakashi Iwai 	struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
1289a82d51edSTakashi Iwai 	struct pci_dev *p = get_bound_vga(chip->pci);
1290bacd8614SKai-Heng Feng 	struct pci_dev *parent;
1291a82d51edSTakashi Iwai 	if (p) {
12924e76a883STakashi Iwai 		dev_info(chip->card->dev,
12932b760d88SLukas Wunner 			 "Handle vga_switcheroo audio client\n");
12949a34af4aSTakashi Iwai 		hda->use_vga_switcheroo = 1;
1295bacd8614SKai-Heng Feng 
1296bacd8614SKai-Heng Feng 		/* cleared in either gpu_bound op or codec probe, or when its
1297bacd8614SKai-Heng Feng 		 * upstream port has _PR3 (i.e. dGPU).
1298bacd8614SKai-Heng Feng 		 */
1299bacd8614SKai-Heng Feng 		parent = pci_upstream_bridge(p);
1300bacd8614SKai-Heng Feng 		chip->bus.keep_power = parent ? !pci_pr3_present(parent) : 1;
130107f4f97dSLukas Wunner 		chip->driver_caps |= AZX_DCAPS_PM_RUNTIME;
1302a82d51edSTakashi Iwai 		pci_dev_put(p);
1303a82d51edSTakashi Iwai 	}
1304a82d51edSTakashi Iwai }
1305a82d51edSTakashi Iwai 
1306a82d51edSTakashi Iwai static const struct vga_switcheroo_client_ops azx_vs_ops = {
1307a82d51edSTakashi Iwai 	.set_gpu_state = azx_vs_set_state,
1308a82d51edSTakashi Iwai 	.can_switch = azx_vs_can_switch,
130937a3a98eSTakashi Iwai 	.gpu_bound = azx_vs_gpu_bound,
1310a82d51edSTakashi Iwai };
1311a82d51edSTakashi Iwai 
register_vga_switcheroo(struct azx * chip)1312e23e7a14SBill Pemberton static int register_vga_switcheroo(struct azx *chip)
1313a82d51edSTakashi Iwai {
13149a34af4aSTakashi Iwai 	struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
13154aaf448fSJim Qu 	struct pci_dev *p;
1316128960a9STakashi Iwai 	int err;
1317128960a9STakashi Iwai 
13189a34af4aSTakashi Iwai 	if (!hda->use_vga_switcheroo)
1319a82d51edSTakashi Iwai 		return 0;
13204aaf448fSJim Qu 
13214aaf448fSJim Qu 	p = get_bound_vga(chip->pci);
13224aaf448fSJim Qu 	err = vga_switcheroo_register_audio_client(chip->pci, &azx_vs_ops, p);
13234aaf448fSJim Qu 	pci_dev_put(p);
13244aaf448fSJim Qu 
1325128960a9STakashi Iwai 	if (err < 0)
1326128960a9STakashi Iwai 		return err;
13279a34af4aSTakashi Iwai 	hda->vga_switcheroo_registered = 1;
1328246efa4aSDave Airlie 
1329128960a9STakashi Iwai 	return 0;
1330a82d51edSTakashi Iwai }
1331a82d51edSTakashi Iwai #else
1332a82d51edSTakashi Iwai #define init_vga_switcheroo(chip)		/* NOP */
1333a82d51edSTakashi Iwai #define register_vga_switcheroo(chip)		0
13348393ec4aSSteven Newbury #define check_hdmi_disabled(pci)	false
133537a3a98eSTakashi Iwai #define setup_vga_switcheroo_runtime_pm(chip)	/* NOP */
1336a82d51edSTakashi Iwai #endif /* SUPPORT_VGA_SWITCHER */
1337a82d51edSTakashi Iwai 
13380cbf0098STakashi Iwai /*
13391da177e4SLinus Torvalds  * destructor
13401da177e4SLinus Torvalds  */
azx_free(struct azx * chip)13412393e755STakashi Iwai static void azx_free(struct azx *chip)
13421da177e4SLinus Torvalds {
1343c67e2228SWang Xingchao 	struct pci_dev *pci = chip->pci;
1344a07187c9SMengdong Lin 	struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
1345a41d1224STakashi Iwai 	struct hdac_bus *bus = azx_bus(chip);
13464ce107b9STakashi Iwai 
13472393e755STakashi Iwai 	if (hda->freed)
13482393e755STakashi Iwai 		return;
13492393e755STakashi Iwai 
13504f66a9efSTakashi Iwai 	if (azx_has_pm_runtime(chip) && chip->running) {
1351c67e2228SWang Xingchao 		pm_runtime_get_noresume(&pci->dev);
13524f66a9efSTakashi Iwai 		pm_runtime_forbid(&pci->dev);
13534f66a9efSTakashi Iwai 		pm_runtime_dont_use_autosuspend(&pci->dev);
13544f66a9efSTakashi Iwai 	}
13554f66a9efSTakashi Iwai 
135637a3a98eSTakashi Iwai 	chip->running = 0;
1357c67e2228SWang Xingchao 
135865fcd41dSTakashi Iwai 	azx_del_card_list(chip);
135965fcd41dSTakashi Iwai 
13609a34af4aSTakashi Iwai 	hda->init_failed = 1; /* to be sure */
13619a34af4aSTakashi Iwai 	complete_all(&hda->probe_wait);
1362f4c482a4STakashi Iwai 
13639a34af4aSTakashi Iwai 	if (use_vga_switcheroo(hda)) {
1364a41d1224STakashi Iwai 		if (chip->disabled && hda->probe_continued)
1365a41d1224STakashi Iwai 			snd_hda_unlock_devices(&chip->bus);
136607f4f97dSLukas Wunner 		if (hda->vga_switcheroo_registered)
1367a82d51edSTakashi Iwai 			vga_switcheroo_unregister_client(chip->pci);
1368a82d51edSTakashi Iwai 	}
1369a82d51edSTakashi Iwai 
1370a41d1224STakashi Iwai 	if (bus->chip_init) {
13719ad593f6STakashi Iwai 		azx_clear_irq_pending(chip);
13727833c3f8STakashi Iwai 		azx_stop_all_streams(chip);
13731a7f60b9STakashi Iwai 		azx_stop_chip(chip);
13741da177e4SLinus Torvalds 	}
13751da177e4SLinus Torvalds 
1376a41d1224STakashi Iwai 	if (bus->irq >= 0)
1377a41d1224STakashi Iwai 		free_irq(bus->irq, (void*)chip);
13781da177e4SLinus Torvalds 
137967908994SDylan Reid 	azx_free_stream_pages(chip);
1380a41d1224STakashi Iwai 	azx_free_streams(chip);
1381a41d1224STakashi Iwai 	snd_hdac_bus_exit(bus);
1382a41d1224STakashi Iwai 
13834918cdabSTakashi Iwai #ifdef CONFIG_SND_HDA_PATCH_LOADER
13844918cdabSTakashi Iwai 	release_firmware(chip->fw);
13854918cdabSTakashi Iwai #endif
1386029d92c2STakashi Iwai 	display_power(chip, false);
1387e454ff8eSTakashi Iwai 
1388fc18282cSTakashi Iwai 	if (chip->driver_caps & AZX_DCAPS_I915_COMPONENT)
1389fcc88d91STakashi Iwai 		snd_hdac_i915_exit(bus);
13901da177e4SLinus Torvalds 
13912393e755STakashi Iwai 	hda->freed = 1;
13921da177e4SLinus Torvalds }
13931da177e4SLinus Torvalds 
azx_dev_disconnect(struct snd_device * device)1394a41d1224STakashi Iwai static int azx_dev_disconnect(struct snd_device *device)
1395a41d1224STakashi Iwai {
1396a41d1224STakashi Iwai 	struct azx *chip = device->device_data;
1397ca58f551STakashi Iwai 	struct hdac_bus *bus = azx_bus(chip);
1398a41d1224STakashi Iwai 
1399a41d1224STakashi Iwai 	chip->bus.shutdown = 1;
1400ca58f551STakashi Iwai 	cancel_work_sync(&bus->unsol_work);
1401ca58f551STakashi Iwai 
1402a41d1224STakashi Iwai 	return 0;
1403a41d1224STakashi Iwai }
1404a41d1224STakashi Iwai 
azx_dev_free(struct snd_device * device)1405a98f90fdSTakashi Iwai static int azx_dev_free(struct snd_device *device)
14061da177e4SLinus Torvalds {
14072393e755STakashi Iwai 	azx_free(device->device_data);
14082393e755STakashi Iwai 	return 0;
14091da177e4SLinus Torvalds }
14101da177e4SLinus Torvalds 
14118393ec4aSSteven Newbury #ifdef SUPPORT_VGA_SWITCHEROO
1412586bc4aaSAlex Deucher #ifdef CONFIG_ACPI
1413586bc4aaSAlex Deucher /* ATPX is in the integrated GPU's namespace */
atpx_present(void)1414586bc4aaSAlex Deucher static bool atpx_present(void)
1415586bc4aaSAlex Deucher {
1416586bc4aaSAlex Deucher 	struct pci_dev *pdev = NULL;
1417586bc4aaSAlex Deucher 	acpi_handle dhandle, atpx_handle;
1418586bc4aaSAlex Deucher 	acpi_status status;
1419586bc4aaSAlex Deucher 
14208cc0991cSAlex Deucher 	while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
14218cc0991cSAlex Deucher 		dhandle = ACPI_HANDLE(&pdev->dev);
14228cc0991cSAlex Deucher 		if (dhandle) {
14238cc0991cSAlex Deucher 			status = acpi_get_handle(dhandle, "ATPX", &atpx_handle);
142410e92724SBjorn Helgaas 			if (ACPI_SUCCESS(status)) {
14258cc0991cSAlex Deucher 				pci_dev_put(pdev);
14268cc0991cSAlex Deucher 				return true;
14278cc0991cSAlex Deucher 			}
14288cc0991cSAlex Deucher 		}
14298cc0991cSAlex Deucher 	}
14308cc0991cSAlex Deucher 	while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
1431586bc4aaSAlex Deucher 		dhandle = ACPI_HANDLE(&pdev->dev);
1432586bc4aaSAlex Deucher 		if (dhandle) {
1433586bc4aaSAlex Deucher 			status = acpi_get_handle(dhandle, "ATPX", &atpx_handle);
143410e92724SBjorn Helgaas 			if (ACPI_SUCCESS(status)) {
1435586bc4aaSAlex Deucher 				pci_dev_put(pdev);
1436586bc4aaSAlex Deucher 				return true;
1437586bc4aaSAlex Deucher 			}
1438586bc4aaSAlex Deucher 		}
1439586bc4aaSAlex Deucher 	}
1440586bc4aaSAlex Deucher 	return false;
1441586bc4aaSAlex Deucher }
1442586bc4aaSAlex Deucher #else
atpx_present(void)1443586bc4aaSAlex Deucher static bool atpx_present(void)
1444586bc4aaSAlex Deucher {
1445586bc4aaSAlex Deucher 	return false;
1446586bc4aaSAlex Deucher }
1447586bc4aaSAlex Deucher #endif
1448586bc4aaSAlex Deucher 
14491da177e4SLinus Torvalds /*
14502b760d88SLukas Wunner  * Check of disabled HDMI controller by vga_switcheroo
14519121947dSTakashi Iwai  */
get_bound_vga(struct pci_dev * pci)1452e23e7a14SBill Pemberton static struct pci_dev *get_bound_vga(struct pci_dev *pci)
14539121947dSTakashi Iwai {
14549121947dSTakashi Iwai 	struct pci_dev *p;
14559121947dSTakashi Iwai 
14569121947dSTakashi Iwai 	/* check only discrete GPU */
14579121947dSTakashi Iwai 	switch (pci->vendor) {
14589121947dSTakashi Iwai 	case PCI_VENDOR_ID_ATI:
14599121947dSTakashi Iwai 	case PCI_VENDOR_ID_AMD:
1460586bc4aaSAlex Deucher 		if (pci->devfn == 1) {
1461586bc4aaSAlex Deucher 			p = pci_get_domain_bus_and_slot(pci_domain_nr(pci->bus),
1462586bc4aaSAlex Deucher 							pci->bus->number, 0);
1463586bc4aaSAlex Deucher 			if (p) {
1464586bc4aaSAlex Deucher 				/* ATPX is in the integrated GPU's ACPI namespace
1465586bc4aaSAlex Deucher 				 * rather than the dGPU's namespace. However,
1466586bc4aaSAlex Deucher 				 * the dGPU is the one who is involved in
1467586bc4aaSAlex Deucher 				 * vgaswitcheroo.
1468586bc4aaSAlex Deucher 				 */
1469586bc4aaSAlex Deucher 				if (((p->class >> 16) == PCI_BASE_CLASS_DISPLAY) &&
14705beb5627SOrlando Chamberlain 				    (atpx_present() || apple_gmux_detect(NULL, NULL)))
1471586bc4aaSAlex Deucher 					return p;
1472586bc4aaSAlex Deucher 				pci_dev_put(p);
1473586bc4aaSAlex Deucher 			}
1474586bc4aaSAlex Deucher 		}
1475586bc4aaSAlex Deucher 		break;
14769121947dSTakashi Iwai 	case PCI_VENDOR_ID_NVIDIA:
14779121947dSTakashi Iwai 		if (pci->devfn == 1) {
14789121947dSTakashi Iwai 			p = pci_get_domain_bus_and_slot(pci_domain_nr(pci->bus),
14799121947dSTakashi Iwai 							pci->bus->number, 0);
14809121947dSTakashi Iwai 			if (p) {
1481b6d7b362SJim Qu 				if ((p->class >> 16) == PCI_BASE_CLASS_DISPLAY)
14829121947dSTakashi Iwai 					return p;
14839121947dSTakashi Iwai 				pci_dev_put(p);
14849121947dSTakashi Iwai 			}
14859121947dSTakashi Iwai 		}
14869121947dSTakashi Iwai 		break;
14879121947dSTakashi Iwai 	}
14889121947dSTakashi Iwai 	return NULL;
14899121947dSTakashi Iwai }
14909121947dSTakashi Iwai 
check_hdmi_disabled(struct pci_dev * pci)1491e23e7a14SBill Pemberton static bool check_hdmi_disabled(struct pci_dev *pci)
14929121947dSTakashi Iwai {
14939121947dSTakashi Iwai 	bool vga_inactive = false;
14949121947dSTakashi Iwai 	struct pci_dev *p = get_bound_vga(pci);
14959121947dSTakashi Iwai 
14969121947dSTakashi Iwai 	if (p) {
149712b78a7fSTakashi Iwai 		if (vga_switcheroo_get_client_state(p) == VGA_SWITCHEROO_OFF)
14989121947dSTakashi Iwai 			vga_inactive = true;
14999121947dSTakashi Iwai 		pci_dev_put(p);
15009121947dSTakashi Iwai 	}
15019121947dSTakashi Iwai 	return vga_inactive;
15029121947dSTakashi Iwai }
15038393ec4aSSteven Newbury #endif /* SUPPORT_VGA_SWITCHEROO */
15049121947dSTakashi Iwai 
15059121947dSTakashi Iwai /*
15066317e5ebSTakashi Iwai  * allow/deny-listing for position_fix
15073372a153STakashi Iwai  */
1508a5dc05e4STakashi Iwai static const struct snd_pci_quirk position_fix_list[] = {
1509d2e1c973STakashi Iwai 	SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
1510d2e1c973STakashi Iwai 	SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
15112f703e7aSTakashi Iwai 	SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
1512d2e1c973STakashi Iwai 	SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
1513dd37f8e8SDaniel T Chen 	SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
15149f75c1b1SDaniel T Chen 	SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB),
1515e96d3127SDaniel T Chen 	SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB),
1516b01de4fbSDavid Henningsson 	SND_PCI_QUIRK(0x10de, 0xcb89, "Macbook Pro 7,1", POS_FIX_LPIB),
151761bb42c3SDaniel T Chen 	SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB),
15189ec8ddadSDaniel T Chen 	SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB),
151945d4ebf1STakashi Iwai 	SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
15208815cd03STakashi Iwai 	SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB),
1521b90c0764SDaniel T Chen 	SND_PCI_QUIRK(0x1849, 0x0888, "775Dual-VSTA", POS_FIX_LPIB),
15220e0280dcSDaniel T Chen 	SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB),
15233372a153STakashi Iwai 	{}
15243372a153STakashi Iwai };
15253372a153STakashi Iwai 
check_position_fix(struct azx * chip,int fix)1526e23e7a14SBill Pemberton static int check_position_fix(struct azx *chip, int fix)
15273372a153STakashi Iwai {
15283372a153STakashi Iwai 	const struct snd_pci_quirk *q;
15293372a153STakashi Iwai 
1530c673ba1cSTakashi Iwai 	switch (fix) {
15311dac6695STakashi Iwai 	case POS_FIX_AUTO:
1532c673ba1cSTakashi Iwai 	case POS_FIX_LPIB:
1533c673ba1cSTakashi Iwai 	case POS_FIX_POSBUF:
15344cb36310SDavid Henningsson 	case POS_FIX_VIACOMBO:
1535a6f2fd55STakashi Iwai 	case POS_FIX_COMBO:
1536f87e7f25STakashi Iwai 	case POS_FIX_SKL:
1537c02f77d3STakashi Iwai 	case POS_FIX_FIFO:
1538c673ba1cSTakashi Iwai 		return fix;
1539c673ba1cSTakashi Iwai 	}
1540c673ba1cSTakashi Iwai 
15413372a153STakashi Iwai 	q = snd_pci_quirk_lookup(chip->pci, position_fix_list);
15423372a153STakashi Iwai 	if (q) {
15434e76a883STakashi Iwai 		dev_info(chip->card->dev,
15444e76a883STakashi Iwai 			 "position_fix set to %d for device %04x:%04x\n",
15453372a153STakashi Iwai 			 q->value, q->subvendor, q->subdevice);
15463372a153STakashi Iwai 		return q->value;
15473372a153STakashi Iwai 	}
1548bdd9ef24SDavid Henningsson 
1549bdd9ef24SDavid Henningsson 	/* Check VIA/ATI HD Audio Controller exist */
155026f05717STakashi Iwai 	if (chip->driver_type == AZX_DRIVER_VIA) {
15514e76a883STakashi Iwai 		dev_dbg(chip->card->dev, "Using VIACOMBO position fix\n");
1552bdd9ef24SDavid Henningsson 		return POS_FIX_VIACOMBO;
1553bdd9ef24SDavid Henningsson 	}
1554c02f77d3STakashi Iwai 	if (chip->driver_caps & AZX_DCAPS_AMD_WORKAROUND) {
1555c02f77d3STakashi Iwai 		dev_dbg(chip->card->dev, "Using FIFO position fix\n");
1556c02f77d3STakashi Iwai 		return POS_FIX_FIFO;
1557c02f77d3STakashi Iwai 	}
15589477c58eSTakashi Iwai 	if (chip->driver_caps & AZX_DCAPS_POSFIX_LPIB) {
15594e76a883STakashi Iwai 		dev_dbg(chip->card->dev, "Using LPIB position fix\n");
15609477c58eSTakashi Iwai 		return POS_FIX_LPIB;
15619477c58eSTakashi Iwai 	}
1562a4b4793fSTakashi Iwai 	if (chip->driver_type == AZX_DRIVER_SKL) {
1563f87e7f25STakashi Iwai 		dev_dbg(chip->card->dev, "Using SKL position fix\n");
1564f87e7f25STakashi Iwai 		return POS_FIX_SKL;
1565f87e7f25STakashi Iwai 	}
1566c673ba1cSTakashi Iwai 	return POS_FIX_AUTO;
15673372a153STakashi Iwai }
15683372a153STakashi Iwai 
assign_position_fix(struct azx * chip,int fix)1569b6050ef6STakashi Iwai static void assign_position_fix(struct azx *chip, int fix)
1570b6050ef6STakashi Iwai {
1571bf82326fSTakashi Iwai 	static const azx_get_pos_callback_t callbacks[] = {
1572b6050ef6STakashi Iwai 		[POS_FIX_AUTO] = NULL,
1573b6050ef6STakashi Iwai 		[POS_FIX_LPIB] = azx_get_pos_lpib,
1574b6050ef6STakashi Iwai 		[POS_FIX_POSBUF] = azx_get_pos_posbuf,
1575b6050ef6STakashi Iwai 		[POS_FIX_VIACOMBO] = azx_via_get_position,
1576b6050ef6STakashi Iwai 		[POS_FIX_COMBO] = azx_get_pos_lpib,
1577c4ca3871STakashi Iwai 		[POS_FIX_SKL] = azx_get_pos_posbuf,
1578c02f77d3STakashi Iwai 		[POS_FIX_FIFO] = azx_get_pos_fifo,
1579b6050ef6STakashi Iwai 	};
1580b6050ef6STakashi Iwai 
1581b6050ef6STakashi Iwai 	chip->get_position[0] = chip->get_position[1] = callbacks[fix];
1582b6050ef6STakashi Iwai 
1583b6050ef6STakashi Iwai 	/* combo mode uses LPIB only for playback */
1584b6050ef6STakashi Iwai 	if (fix == POS_FIX_COMBO)
1585b6050ef6STakashi Iwai 		chip->get_position[1] = NULL;
1586b6050ef6STakashi Iwai 
1587f87e7f25STakashi Iwai 	if ((fix == POS_FIX_POSBUF || fix == POS_FIX_SKL) &&
1588b6050ef6STakashi Iwai 	    (chip->driver_caps & AZX_DCAPS_COUNT_LPIB_DELAY)) {
1589b6050ef6STakashi Iwai 		chip->get_delay[0] = chip->get_delay[1] =
1590b6050ef6STakashi Iwai 			azx_get_delay_from_lpib;
1591b6050ef6STakashi Iwai 	}
1592b6050ef6STakashi Iwai 
1593c02f77d3STakashi Iwai 	if (fix == POS_FIX_FIFO)
1594c02f77d3STakashi Iwai 		chip->get_delay[0] = chip->get_delay[1] =
1595c02f77d3STakashi Iwai 			azx_get_delay_from_fifo;
1596b6050ef6STakashi Iwai }
1597b6050ef6STakashi Iwai 
15983372a153STakashi Iwai /*
15996317e5ebSTakashi Iwai  * deny-lists for probe_mask
1600669ba27aSTakashi Iwai  */
1601a5dc05e4STakashi Iwai static const struct snd_pci_quirk probe_mask_list[] = {
1602669ba27aSTakashi Iwai 	/* Thinkpad often breaks the controller communication when accessing
1603669ba27aSTakashi Iwai 	 * to the non-working (or non-existing) modem codec slot.
1604669ba27aSTakashi Iwai 	 */
1605669ba27aSTakashi Iwai 	SND_PCI_QUIRK(0x1014, 0x05b7, "Thinkpad Z60", 0x01),
1606669ba27aSTakashi Iwai 	SND_PCI_QUIRK(0x17aa, 0x2010, "Thinkpad X/T/R60", 0x01),
1607669ba27aSTakashi Iwai 	SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X/T/R61", 0x01),
16080edb9454STakashi Iwai 	/* broken BIOS */
16090edb9454STakashi Iwai 	SND_PCI_QUIRK(0x1028, 0x20ac, "Dell Studio Desktop", 0x01),
1610ef1681d8STakashi Iwai 	/* including bogus ALC268 in slot#2 that conflicts with ALC888 */
1611ef1681d8STakashi Iwai 	SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01),
161220db7cb0STakashi Iwai 	/* forced codec slots */
161393574844SOzan Çağlayan 	SND_PCI_QUIRK(0x1043, 0x1262, "ASUS W5Fm", 0x103),
161420db7cb0STakashi Iwai 	SND_PCI_QUIRK(0x1046, 0x1262, "ASUS W5F", 0x103),
1615dd8e5b16STakashi Iwai 	SND_PCI_QUIRK(0x1558, 0x0351, "Schenker Dock 15", 0x105),
1616f3af9051SJaroslav Kysela 	/* WinFast VP200 H (Teradici) user reported broken communication */
1617f3af9051SJaroslav Kysela 	SND_PCI_QUIRK(0x3a21, 0x040d, "WinFast VP200 H", 0x101),
1618669ba27aSTakashi Iwai 	{}
1619669ba27aSTakashi Iwai };
1620669ba27aSTakashi Iwai 
1621f1eaaeecSTakashi Iwai #define AZX_FORCE_CODEC_MASK	0x100
1622f1eaaeecSTakashi Iwai 
check_probe_mask(struct azx * chip,int dev)1623e23e7a14SBill Pemberton static void check_probe_mask(struct azx *chip, int dev)
1624669ba27aSTakashi Iwai {
1625669ba27aSTakashi Iwai 	const struct snd_pci_quirk *q;
1626669ba27aSTakashi Iwai 
1627f1eaaeecSTakashi Iwai 	chip->codec_probe_mask = probe_mask[dev];
1628f1eaaeecSTakashi Iwai 	if (chip->codec_probe_mask == -1) {
1629669ba27aSTakashi Iwai 		q = snd_pci_quirk_lookup(chip->pci, probe_mask_list);
1630669ba27aSTakashi Iwai 		if (q) {
16314e76a883STakashi Iwai 			dev_info(chip->card->dev,
16324e76a883STakashi Iwai 				 "probe_mask set to 0x%x for device %04x:%04x\n",
1633669ba27aSTakashi Iwai 				 q->value, q->subvendor, q->subdevice);
1634f1eaaeecSTakashi Iwai 			chip->codec_probe_mask = q->value;
1635669ba27aSTakashi Iwai 		}
1636669ba27aSTakashi Iwai 	}
1637f1eaaeecSTakashi Iwai 
1638f1eaaeecSTakashi Iwai 	/* check forced option */
1639f1eaaeecSTakashi Iwai 	if (chip->codec_probe_mask != -1 &&
1640f1eaaeecSTakashi Iwai 	    (chip->codec_probe_mask & AZX_FORCE_CODEC_MASK)) {
1641a41d1224STakashi Iwai 		azx_bus(chip)->codec_mask = chip->codec_probe_mask & 0xff;
16424e76a883STakashi Iwai 		dev_info(chip->card->dev, "codec_mask forced to 0x%x\n",
1643a41d1224STakashi Iwai 			 (int)azx_bus(chip)->codec_mask);
1644f1eaaeecSTakashi Iwai 	}
1645669ba27aSTakashi Iwai }
1646669ba27aSTakashi Iwai 
16474d8e22e0STakashi Iwai /*
16486317e5ebSTakashi Iwai  * allow/deny-list for enable_msi
16494d8e22e0STakashi Iwai  */
16506317e5ebSTakashi Iwai static const struct snd_pci_quirk msi_deny_list[] = {
1651693e0cb0SDavid Henningsson 	SND_PCI_QUIRK(0x103c, 0x2191, "HP", 0), /* AMD Hudson */
1652693e0cb0SDavid Henningsson 	SND_PCI_QUIRK(0x103c, 0x2192, "HP", 0), /* AMD Hudson */
1653693e0cb0SDavid Henningsson 	SND_PCI_QUIRK(0x103c, 0x21f7, "HP", 0), /* AMD Hudson */
1654693e0cb0SDavid Henningsson 	SND_PCI_QUIRK(0x103c, 0x21fa, "HP", 0), /* AMD Hudson */
16559dc8398bSTakashi Iwai 	SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */
16560a27fcfaSTakashi Iwai 	SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
1657ecd21626SRalf Gerbig 	SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */
165883f72151STakashi Iwai 	SND_PCI_QUIRK(0x1179, 0xfb44, "Toshiba Satellite C870", 0), /* AMD Hudson */
16594193d13bSMichele Ballabio 	SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */
16603815595eSTakashi Iwai 	SND_PCI_QUIRK(0xa0a0, 0x0575, "Aopen MZ915-M", 0), /* ICH6 */
16614d8e22e0STakashi Iwai 	{}
16624d8e22e0STakashi Iwai };
16634d8e22e0STakashi Iwai 
check_msi(struct azx * chip)1664e23e7a14SBill Pemberton static void check_msi(struct azx *chip)
16654d8e22e0STakashi Iwai {
16664d8e22e0STakashi Iwai 	const struct snd_pci_quirk *q;
16674d8e22e0STakashi Iwai 
166871623855STakashi Iwai 	if (enable_msi >= 0) {
166971623855STakashi Iwai 		chip->msi = !!enable_msi;
16704d8e22e0STakashi Iwai 		return;
167171623855STakashi Iwai 	}
167271623855STakashi Iwai 	chip->msi = 1;	/* enable MSI as default */
16736317e5ebSTakashi Iwai 	q = snd_pci_quirk_lookup(chip->pci, msi_deny_list);
16744d8e22e0STakashi Iwai 	if (q) {
16754e76a883STakashi Iwai 		dev_info(chip->card->dev,
16764e76a883STakashi Iwai 			 "msi for device %04x:%04x set to %d\n",
16774d8e22e0STakashi Iwai 			 q->subvendor, q->subdevice, q->value);
16784d8e22e0STakashi Iwai 		chip->msi = q->value;
167980c43ed7STakashi Iwai 		return;
168080c43ed7STakashi Iwai 	}
168180c43ed7STakashi Iwai 
168280c43ed7STakashi Iwai 	/* NVidia chipsets seem to cause troubles with MSI */
16839477c58eSTakashi Iwai 	if (chip->driver_caps & AZX_DCAPS_NO_MSI) {
16844e76a883STakashi Iwai 		dev_info(chip->card->dev, "Disabling MSI\n");
168580c43ed7STakashi Iwai 		chip->msi = 0;
16864d8e22e0STakashi Iwai 	}
16874d8e22e0STakashi Iwai }
16884d8e22e0STakashi Iwai 
1689a1585d76STakashi Iwai /* check the snoop mode availability */
azx_check_snoop_available(struct azx * chip)1690e23e7a14SBill Pemberton static void azx_check_snoop_available(struct azx *chip)
1691a1585d76STakashi Iwai {
16927c732015STakashi Iwai 	int snoop = hda_snoop;
1693a1585d76STakashi Iwai 
16947c732015STakashi Iwai 	if (snoop >= 0) {
16957c732015STakashi Iwai 		dev_info(chip->card->dev, "Force to %s mode by module option\n",
16967c732015STakashi Iwai 			 snoop ? "snoop" : "non-snoop");
16977c732015STakashi Iwai 		chip->snoop = snoop;
169878c9be61STakashi Iwai 		chip->uc_buffer = !snoop;
16997c732015STakashi Iwai 		return;
17007c732015STakashi Iwai 	}
17017c732015STakashi Iwai 
17027c732015STakashi Iwai 	snoop = true;
170337e661eeSTakashi Iwai 	if (azx_get_snoop_type(chip) == AZX_SNOOP_TYPE_NONE &&
170437e661eeSTakashi Iwai 	    chip->driver_type == AZX_DRIVER_VIA) {
1705a1585d76STakashi Iwai 		/* force to non-snoop mode for a new VIA controller
1706a1585d76STakashi Iwai 		 * when BIOS is set
1707a1585d76STakashi Iwai 		 */
1708a1585d76STakashi Iwai 		u8 val;
1709a1585d76STakashi Iwai 		pci_read_config_byte(chip->pci, 0x42, &val);
1710af52f998SDavid Wang 		if (!(val & 0x80) && (chip->pci->revision == 0x30 ||
1711af52f998SDavid Wang 				      chip->pci->revision == 0x20))
1712a1585d76STakashi Iwai 			snoop = false;
1713a1585d76STakashi Iwai 	}
1714a1585d76STakashi Iwai 
171537e661eeSTakashi Iwai 	if (chip->driver_caps & AZX_DCAPS_SNOOP_OFF)
171637e661eeSTakashi Iwai 		snoop = false;
171737e661eeSTakashi Iwai 
1718a1585d76STakashi Iwai 	chip->snoop = snoop;
171978c9be61STakashi Iwai 	if (!snoop) {
17207c732015STakashi Iwai 		dev_info(chip->card->dev, "Force to non-snoop mode\n");
172178c9be61STakashi Iwai 		/* C-Media requires non-cached pages only for CORB/RIRB */
172278c9be61STakashi Iwai 		if (chip->driver_type != AZX_DRIVER_CMEDIA)
172378c9be61STakashi Iwai 			chip->uc_buffer = true;
172478c9be61STakashi Iwai 	}
1725a1585d76STakashi Iwai }
1726669ba27aSTakashi Iwai 
azx_probe_work(struct work_struct * work)172799a2008dSWang Xingchao static void azx_probe_work(struct work_struct *work)
172899a2008dSWang Xingchao {
1729c0f1886dSTakashi Iwai 	struct hda_intel *hda = container_of(work, struct hda_intel, probe_work.work);
17309a34af4aSTakashi Iwai 	azx_probe_continue(&hda->chip);
173199a2008dSWang Xingchao }
173299a2008dSWang Xingchao 
default_bdl_pos_adj(struct azx * chip)17334f0189beSTakashi Iwai static int default_bdl_pos_adj(struct azx *chip)
17344f0189beSTakashi Iwai {
17352cf721dbSTakashi Iwai 	/* some exceptions: Atoms seem problematic with value 1 */
17362cf721dbSTakashi Iwai 	if (chip->pci->vendor == PCI_VENDOR_ID_INTEL) {
17372cf721dbSTakashi Iwai 		switch (chip->pci->device) {
1738580118d5SRui Salvaterra 		case PCI_DEVICE_ID_INTEL_HDA_BYT:
1739580118d5SRui Salvaterra 		case PCI_DEVICE_ID_INTEL_HDA_BSW:
17402cf721dbSTakashi Iwai 			return 32;
1741034a0061SRui Salvaterra 		case PCI_DEVICE_ID_INTEL_HDA_APL:
1742034a0061SRui Salvaterra 			return 64;
17432cf721dbSTakashi Iwai 		}
17442cf721dbSTakashi Iwai 	}
17452cf721dbSTakashi Iwai 
17464f0189beSTakashi Iwai 	switch (chip->driver_type) {
1747c51e4310Sjasontao 	/*
1748c51e4310Sjasontao 	 * increase the bdl size for Glenfly Gpus for hardware
1749c51e4310Sjasontao 	 * limitation on hdac interrupt interval
1750c51e4310Sjasontao 	 */
1751c51e4310Sjasontao 	case AZX_DRIVER_GFHDMI:
1752c51e4310Sjasontao 		return 128;
17534f0189beSTakashi Iwai 	case AZX_DRIVER_ICH:
17544f0189beSTakashi Iwai 	case AZX_DRIVER_PCH:
17554f0189beSTakashi Iwai 		return 1;
17564f0189beSTakashi Iwai 	default:
17574f0189beSTakashi Iwai 		return 32;
17584f0189beSTakashi Iwai 	}
17594f0189beSTakashi Iwai }
17604f0189beSTakashi Iwai 
1761669ba27aSTakashi Iwai /*
17621da177e4SLinus Torvalds  * constructor
17631da177e4SLinus Torvalds  */
1764a43ff5baSTakashi Iwai static const struct hda_controller_ops pci_hda_ops;
1765a43ff5baSTakashi Iwai 
azx_create(struct snd_card * card,struct pci_dev * pci,int dev,unsigned int driver_caps,struct azx ** rchip)1766e23e7a14SBill Pemberton static int azx_create(struct snd_card *card, struct pci_dev *pci,
17679477c58eSTakashi Iwai 		      int dev, unsigned int driver_caps,
1768a98f90fdSTakashi Iwai 		      struct azx **rchip)
17691da177e4SLinus Torvalds {
177041f394a8STakashi Iwai 	static const struct snd_device_ops ops = {
1771a41d1224STakashi Iwai 		.dev_disconnect = azx_dev_disconnect,
17721da177e4SLinus Torvalds 		.dev_free = azx_dev_free,
17731da177e4SLinus Torvalds 	};
1774a07187c9SMengdong Lin 	struct hda_intel *hda;
1775a82d51edSTakashi Iwai 	struct azx *chip;
1776a82d51edSTakashi Iwai 	int err;
17771da177e4SLinus Torvalds 
17781da177e4SLinus Torvalds 	*rchip = NULL;
17791da177e4SLinus Torvalds 
17803fcaf24eSTakashi Iwai 	err = pcim_enable_device(pci);
1781927fc866SPavel Machek 	if (err < 0)
17821da177e4SLinus Torvalds 		return err;
17831da177e4SLinus Torvalds 
17842393e755STakashi Iwai 	hda = devm_kzalloc(&pci->dev, sizeof(*hda), GFP_KERNEL);
17853fcaf24eSTakashi Iwai 	if (!hda)
17861da177e4SLinus Torvalds 		return -ENOMEM;
17871da177e4SLinus Torvalds 
1788a07187c9SMengdong Lin 	chip = &hda->chip;
178962932df8SIngo Molnar 	mutex_init(&chip->open_mutex);
17901da177e4SLinus Torvalds 	chip->card = card;
17911da177e4SLinus Torvalds 	chip->pci = pci;
1792a43ff5baSTakashi Iwai 	chip->ops = &pci_hda_ops;
17939477c58eSTakashi Iwai 	chip->driver_caps = driver_caps;
17949477c58eSTakashi Iwai 	chip->driver_type = driver_caps & 0xff;
17954d8e22e0STakashi Iwai 	check_msi(chip);
1796555e219fSTakashi Iwai 	chip->dev_index = dev;
17973a182c84STakashi Iwai 	if (jackpoll_ms[dev] >= 50 && jackpoll_ms[dev] <= 60000)
17983a182c84STakashi Iwai 		chip->jackpoll_interval = msecs_to_jiffies(jackpoll_ms[dev]);
179901b65bfbSTakashi Iwai 	INIT_LIST_HEAD(&chip->pcm_list);
18009a34af4aSTakashi Iwai 	INIT_WORK(&hda->irq_pending_work, azx_irq_pending_work);
18019a34af4aSTakashi Iwai 	INIT_LIST_HEAD(&hda->list);
1802a82d51edSTakashi Iwai 	init_vga_switcheroo(chip);
18039a34af4aSTakashi Iwai 	init_completion(&hda->probe_wait);
18041da177e4SLinus Torvalds 
1805b6050ef6STakashi Iwai 	assign_position_fix(chip, check_position_fix(chip, position_fix[dev]));
1806a6f2fd55STakashi Iwai 
180741438f13STakashi Iwai 	if (single_cmd < 0) /* allow fallback to single_cmd at errors */
180841438f13STakashi Iwai 		chip->fallback_to_single_cmd = 1;
180941438f13STakashi Iwai 	else /* explicitly set to single_cmd or not */
181027346166STakashi Iwai 		chip->single_cmd = single_cmd;
181141438f13STakashi Iwai 
1812a1585d76STakashi Iwai 	azx_check_snoop_available(chip);
1813c74db86bSTakashi Iwai 
18144f0189beSTakashi Iwai 	if (bdl_pos_adj[dev] < 0)
18154f0189beSTakashi Iwai 		chip->bdl_pos_adj = default_bdl_pos_adj(chip);
18164f0189beSTakashi Iwai 	else
18174f0189beSTakashi Iwai 		chip->bdl_pos_adj = bdl_pos_adj[dev];
18185c0d7bc1STakashi Iwai 
181919abfefdSTakashi Iwai 	err = azx_bus_init(chip, model[dev]);
18203fcaf24eSTakashi Iwai 	if (err < 0)
1821a41d1224STakashi Iwai 		return err;
1822a41d1224STakashi Iwai 
1823619a1f19STakashi Iwai 	/* use the non-cached pages in non-snoop mode */
1824619a1f19STakashi Iwai 	if (!azx_snoop(chip))
182537137ec2STakashi Iwai 		azx_bus(chip)->dma_type = SNDRV_DMA_TYPE_DEV_WC_SG;
1826619a1f19STakashi Iwai 
18277d9a1808STakashi Iwai 	if (chip->driver_type == AZX_DRIVER_NVIDIA) {
18287d9a1808STakashi Iwai 		dev_dbg(chip->card->dev, "Enable delay in RIRB handling\n");
18295f2cb361STakashi Iwai 		chip->bus.core.needs_damn_long_delay = 1;
18307d9a1808STakashi Iwai 	}
18317d9a1808STakashi Iwai 
18326317f744STakashi Iwai 	check_probe_mask(chip, dev);
18336317f744STakashi Iwai 
1834a82d51edSTakashi Iwai 	err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
1835a82d51edSTakashi Iwai 	if (err < 0) {
18364e76a883STakashi Iwai 		dev_err(card->dev, "Error creating device [card]!\n");
1837a82d51edSTakashi Iwai 		azx_free(chip);
1838a82d51edSTakashi Iwai 		return err;
1839a82d51edSTakashi Iwai 	}
1840a82d51edSTakashi Iwai 
184199a2008dSWang Xingchao 	/* continue probing in work context as may trigger request module */
1842c0f1886dSTakashi Iwai 	INIT_DELAYED_WORK(&hda->probe_work, azx_probe_work);
184399a2008dSWang Xingchao 
1844a82d51edSTakashi Iwai 	*rchip = chip;
184599a2008dSWang Xingchao 
1846a82d51edSTakashi Iwai 	return 0;
1847a82d51edSTakashi Iwai }
1848a82d51edSTakashi Iwai 
azx_first_init(struct azx * chip)184948c8b0ebSTakashi Iwai static int azx_first_init(struct azx *chip)
1850a82d51edSTakashi Iwai {
1851a82d51edSTakashi Iwai 	int dev = chip->dev_index;
1852a82d51edSTakashi Iwai 	struct pci_dev *pci = chip->pci;
1853a82d51edSTakashi Iwai 	struct snd_card *card = chip->card;
1854a41d1224STakashi Iwai 	struct hdac_bus *bus = azx_bus(chip);
185567908994SDylan Reid 	int err;
1856a82d51edSTakashi Iwai 	unsigned short gcap;
1857413cbf46STakashi Iwai 	unsigned int dma_bits = 64;
1858a82d51edSTakashi Iwai 
185907e4ca50STakashi Iwai #if BITS_PER_LONG != 64
186007e4ca50STakashi Iwai 	/* Fix up base address on ULI M5461 */
186107e4ca50STakashi Iwai 	if (chip->driver_type == AZX_DRIVER_ULI) {
186207e4ca50STakashi Iwai 		u16 tmp3;
186307e4ca50STakashi Iwai 		pci_read_config_word(pci, 0x40, &tmp3);
186407e4ca50STakashi Iwai 		pci_write_config_word(pci, 0x40, tmp3 | 0x10);
186507e4ca50STakashi Iwai 		pci_write_config_dword(pci, PCI_BASE_ADDRESS_1, 0);
186607e4ca50STakashi Iwai 	}
186707e4ca50STakashi Iwai #endif
1868c51e4310Sjasontao 	/*
1869c51e4310Sjasontao 	 * Fix response write request not synced to memory when handle
1870c51e4310Sjasontao 	 * hdac interrupt on Glenfly Gpus
1871c51e4310Sjasontao 	 */
1872c51e4310Sjasontao 	if (chip->driver_type == AZX_DRIVER_GFHDMI)
1873c51e4310Sjasontao 		bus->polling_mode = 1;
187407e4ca50STakashi Iwai 
1875cbc3e98aSYanteng Si 	if (chip->driver_type == AZX_DRIVER_LOONGSON) {
1876cbc3e98aSYanteng Si 		bus->polling_mode = 1;
1877cbc3e98aSYanteng Si 		bus->not_use_interrupts = 1;
1878942ccdd8SYanteng Si 		bus->access_sdnctl_in_dword = 1;
1879cbc3e98aSYanteng Si 	}
1880cbc3e98aSYanteng Si 
18813fcaf24eSTakashi Iwai 	err = pcim_iomap_regions(pci, 1 << 0, "ICH HD audio");
1882a82d51edSTakashi Iwai 	if (err < 0)
18831da177e4SLinus Torvalds 		return err;
18841da177e4SLinus Torvalds 
1885a41d1224STakashi Iwai 	bus->addr = pci_resource_start(pci, 0);
18863fcaf24eSTakashi Iwai 	bus->remap_addr = pcim_iomap_table(pci)[0];
18871da177e4SLinus Torvalds 
1888a4b4793fSTakashi Iwai 	if (chip->driver_type == AZX_DRIVER_SKL)
188950279d9bSGuneshwor Singh 		snd_hdac_bus_parse_capabilities(bus);
189050279d9bSGuneshwor Singh 
189150279d9bSGuneshwor Singh 	/*
189250279d9bSGuneshwor Singh 	 * Some Intel CPUs has always running timer (ART) feature and
189350279d9bSGuneshwor Singh 	 * controller may have Global time sync reporting capability, so
189450279d9bSGuneshwor Singh 	 * check both of these before declaring synchronized time reporting
189550279d9bSGuneshwor Singh 	 * capability SNDRV_PCM_INFO_HAS_LINK_SYNCHRONIZED_ATIME
189650279d9bSGuneshwor Singh 	 */
189750279d9bSGuneshwor Singh 	chip->gts_present = false;
189850279d9bSGuneshwor Singh 
189950279d9bSGuneshwor Singh #ifdef CONFIG_X86
190050279d9bSGuneshwor Singh 	if (bus->ppcap && boot_cpu_has(X86_FEATURE_ART))
190150279d9bSGuneshwor Singh 		chip->gts_present = true;
190250279d9bSGuneshwor Singh #endif
190350279d9bSGuneshwor Singh 
1904db79afa1SBenjamin Herrenschmidt 	if (chip->msi) {
1905db79afa1SBenjamin Herrenschmidt 		if (chip->driver_caps & AZX_DCAPS_NO_MSI64) {
1906db79afa1SBenjamin Herrenschmidt 			dev_dbg(card->dev, "Disabling 64bit MSI\n");
1907db79afa1SBenjamin Herrenschmidt 			pci->no_64bit_msi = true;
1908db79afa1SBenjamin Herrenschmidt 		}
190968e7fffcSTakashi Iwai 		if (pci_enable_msi(pci) < 0)
191068e7fffcSTakashi Iwai 			chip->msi = 0;
1911db79afa1SBenjamin Herrenschmidt 	}
19127376d013SStephen Hemminger 
19131da177e4SLinus Torvalds 	pci_set_master(pci);
19141da177e4SLinus Torvalds 
1915bcd72003STobin Davis 	gcap = azx_readw(chip, GCAP);
19164e76a883STakashi Iwai 	dev_dbg(card->dev, "chipset global capabilities = 0x%x\n", gcap);
1917bcd72003STobin Davis 
1918413cbf46STakashi Iwai 	/* AMD devices support 40 or 48bit DMA, take the safe one */
1919413cbf46STakashi Iwai 	if (chip->pci->vendor == PCI_VENDOR_ID_AMD)
1920413cbf46STakashi Iwai 		dma_bits = 40;
1921413cbf46STakashi Iwai 
1922dc4c2e6bSAndiry Brienza 	/* disable SB600 64bit support for safety */
19239477c58eSTakashi Iwai 	if (chip->pci->vendor == PCI_VENDOR_ID_ATI) {
1924dc4c2e6bSAndiry Brienza 		struct pci_dev *p_smbus;
1925413cbf46STakashi Iwai 		dma_bits = 40;
1926dc4c2e6bSAndiry Brienza 		p_smbus = pci_get_device(PCI_VENDOR_ID_ATI,
1927dc4c2e6bSAndiry Brienza 					 PCI_DEVICE_ID_ATI_SBX00_SMBUS,
1928dc4c2e6bSAndiry Brienza 					 NULL);
1929dc4c2e6bSAndiry Brienza 		if (p_smbus) {
1930dc4c2e6bSAndiry Brienza 			if (p_smbus->revision < 0x30)
1931fb1d8ac2STakashi Iwai 				gcap &= ~AZX_GCAP_64OK;
1932dc4c2e6bSAndiry Brienza 			pci_dev_put(p_smbus);
1933dc4c2e6bSAndiry Brienza 		}
1934dc4c2e6bSAndiry Brienza 	}
193509240cf4STakashi Iwai 
19363ab7511eSArd Biesheuvel 	/* NVidia hardware normally only supports up to 40 bits of DMA */
19373ab7511eSArd Biesheuvel 	if (chip->pci->vendor == PCI_VENDOR_ID_NVIDIA)
19383ab7511eSArd Biesheuvel 		dma_bits = 40;
19393ab7511eSArd Biesheuvel 
19409477c58eSTakashi Iwai 	/* disable 64bit DMA address on some devices */
19419477c58eSTakashi Iwai 	if (chip->driver_caps & AZX_DCAPS_NO_64BIT) {
19424e76a883STakashi Iwai 		dev_dbg(card->dev, "Disabling 64bit DMA\n");
1943fb1d8ac2STakashi Iwai 		gcap &= ~AZX_GCAP_64OK;
19449477c58eSTakashi Iwai 	}
1945396087eaSJaroslav Kysela 
19462ae66c26SPierre-Louis Bossart 	/* disable buffer size rounding to 128-byte multiples if supported */
19477bfe059eSTakashi Iwai 	if (align_buffer_size >= 0)
19487bfe059eSTakashi Iwai 		chip->align_buffer_size = !!align_buffer_size;
19497bfe059eSTakashi Iwai 	else {
1950103884a3STakashi Iwai 		if (chip->driver_caps & AZX_DCAPS_NO_ALIGN_BUFSIZE)
195152409aa6STakashi Iwai 			chip->align_buffer_size = 0;
19527bfe059eSTakashi Iwai 		else
19537bfe059eSTakashi Iwai 			chip->align_buffer_size = 1;
19547bfe059eSTakashi Iwai 	}
19552ae66c26SPierre-Louis Bossart 
1956cf7aaca8STakashi Iwai 	/* allow 64bit DMA address if supported by H/W */
1957413cbf46STakashi Iwai 	if (!(gcap & AZX_GCAP_64OK))
1958413cbf46STakashi Iwai 		dma_bits = 32;
1959669f65eaSTakashi Iwai 	if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(dma_bits)))
1960669f65eaSTakashi Iwai 		dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32));
1961acd289e0STakashi Iwai 	dma_set_max_seg_size(&pci->dev, UINT_MAX);
1962cf7aaca8STakashi Iwai 
1963bcd72003STobin Davis 	/* read number of streams from GCAP register instead of using
1964bcd72003STobin Davis 	 * hardcoded value
1965bcd72003STobin Davis 	 */
19668b6ed8e7STakashi Iwai 	chip->capture_streams = (gcap >> 8) & 0x0f;
19678b6ed8e7STakashi Iwai 	chip->playback_streams = (gcap >> 12) & 0x0f;
19688b6ed8e7STakashi Iwai 	if (!chip->playback_streams && !chip->capture_streams) {
1969bcd72003STobin Davis 		/* gcap didn't give any info, switching to old method */
1970bcd72003STobin Davis 
197107e4ca50STakashi Iwai 		switch (chip->driver_type) {
197207e4ca50STakashi Iwai 		case AZX_DRIVER_ULI:
197307e4ca50STakashi Iwai 			chip->playback_streams = ULI_NUM_PLAYBACK;
197407e4ca50STakashi Iwai 			chip->capture_streams = ULI_NUM_CAPTURE;
197507e4ca50STakashi Iwai 			break;
1976778b6e1bSFelix Kuehling 		case AZX_DRIVER_ATIHDMI:
19771815b34aSAndiry Xu 		case AZX_DRIVER_ATIHDMI_NS:
1978778b6e1bSFelix Kuehling 			chip->playback_streams = ATIHDMI_NUM_PLAYBACK;
1979778b6e1bSFelix Kuehling 			chip->capture_streams = ATIHDMI_NUM_CAPTURE;
1980778b6e1bSFelix Kuehling 			break;
1981c51e4310Sjasontao 		case AZX_DRIVER_GFHDMI:
1982c4da29caSYang, Libin 		case AZX_DRIVER_GENERIC:
198307e4ca50STakashi Iwai 		default:
198407e4ca50STakashi Iwai 			chip->playback_streams = ICH6_NUM_PLAYBACK;
198507e4ca50STakashi Iwai 			chip->capture_streams = ICH6_NUM_CAPTURE;
198607e4ca50STakashi Iwai 			break;
198707e4ca50STakashi Iwai 		}
1988bcd72003STobin Davis 	}
19898b6ed8e7STakashi Iwai 	chip->capture_index_offset = 0;
19908b6ed8e7STakashi Iwai 	chip->playback_index_offset = chip->capture_streams;
199107e4ca50STakashi Iwai 	chip->num_streams = chip->playback_streams + chip->capture_streams;
199207e4ca50STakashi Iwai 
1993df56c3dbSJaroslav Kysela 	/* sanity check for the SDxCTL.STRM field overflow */
1994df56c3dbSJaroslav Kysela 	if (chip->num_streams > 15 &&
1995df56c3dbSJaroslav Kysela 	    (chip->driver_caps & AZX_DCAPS_SEPARATE_STREAM_TAG) == 0) {
1996df56c3dbSJaroslav Kysela 		dev_warn(chip->card->dev, "number of I/O streams is %d, "
1997df56c3dbSJaroslav Kysela 			 "forcing separate stream tags", chip->num_streams);
1998df56c3dbSJaroslav Kysela 		chip->driver_caps |= AZX_DCAPS_SEPARATE_STREAM_TAG;
1999df56c3dbSJaroslav Kysela 	}
2000df56c3dbSJaroslav Kysela 
2001a41d1224STakashi Iwai 	/* initialize streams */
2002a41d1224STakashi Iwai 	err = azx_init_streams(chip);
200367908994SDylan Reid 	if (err < 0)
200467908994SDylan Reid 		return err;
20051da177e4SLinus Torvalds 
20061da177e4SLinus Torvalds 	err = azx_alloc_stream_pages(chip);
20071da177e4SLinus Torvalds 	if (err < 0)
20081da177e4SLinus Torvalds 		return err;
20091da177e4SLinus Torvalds 
20101da177e4SLinus Torvalds 	/* initialize chip */
2011cb53c626STakashi Iwai 	azx_init_pci(chip);
2012e4d9e513SMengdong Lin 
2013bb03ed21STakashi Iwai 	snd_hdac_i915_set_bclk(bus);
2014e4d9e513SMengdong Lin 
20150a673521SLu, Han 	hda_intel_init_chip(chip, (probe_only[dev] & 2) == 0);
20161da177e4SLinus Torvalds 
20171da177e4SLinus Torvalds 	/* codec detection */
2018a41d1224STakashi Iwai 	if (!azx_bus(chip)->codec_mask) {
20194e76a883STakashi Iwai 		dev_err(card->dev, "no codecs found!\n");
20209479e75fSTakashi Iwai 		/* keep running the rest for the runtime PM */
20211da177e4SLinus Torvalds 	}
20221da177e4SLinus Torvalds 
2023f495222eSTakashi Iwai 	if (azx_acquire_irq(chip, 0) < 0)
2024f495222eSTakashi Iwai 		return -EBUSY;
2025f495222eSTakashi Iwai 
202607e4ca50STakashi Iwai 	strcpy(card->driver, "HDA-Intel");
202775b1a8f9SJoe Perches 	strscpy(card->shortname, driver_short_names[chip->driver_type],
202818cb7109STakashi Iwai 		sizeof(card->shortname));
202918cb7109STakashi Iwai 	snprintf(card->longname, sizeof(card->longname),
203018cb7109STakashi Iwai 		 "%s at 0x%lx irq %i",
2031a41d1224STakashi Iwai 		 card->shortname, bus->addr, bus->irq);
203207e4ca50STakashi Iwai 
20331da177e4SLinus Torvalds 	return 0;
20341da177e4SLinus Torvalds }
20351da177e4SLinus Torvalds 
203697c6a3d1STakashi Iwai #ifdef CONFIG_SND_HDA_PATCH_LOADER
20375cb543dbSTakashi Iwai /* callback from request_firmware_nowait() */
azx_firmware_cb(const struct firmware * fw,void * context)20385cb543dbSTakashi Iwai static void azx_firmware_cb(const struct firmware *fw, void *context)
20395cb543dbSTakashi Iwai {
20405cb543dbSTakashi Iwai 	struct snd_card *card = context;
20415cb543dbSTakashi Iwai 	struct azx *chip = card->private_data;
20425cb543dbSTakashi Iwai 
204325faa4bdSTakashi Iwai 	if (fw)
20445cb543dbSTakashi Iwai 		chip->fw = fw;
204525faa4bdSTakashi Iwai 	else
204625faa4bdSTakashi Iwai 		dev_err(card->dev, "Cannot load firmware, continue without patching\n");
20475cb543dbSTakashi Iwai 	if (!chip->disabled) {
20485cb543dbSTakashi Iwai 		/* continue probing */
204925faa4bdSTakashi Iwai 		azx_probe_continue(chip);
20505cb543dbSTakashi Iwai 	}
20515cb543dbSTakashi Iwai }
205297c6a3d1STakashi Iwai #endif
20535cb543dbSTakashi Iwai 
disable_msi_reset_irq(struct azx * chip)2054f46ea609SDylan Reid static int disable_msi_reset_irq(struct azx *chip)
2055f46ea609SDylan Reid {
2056a41d1224STakashi Iwai 	struct hdac_bus *bus = azx_bus(chip);
2057f46ea609SDylan Reid 	int err;
2058f46ea609SDylan Reid 
2059a41d1224STakashi Iwai 	free_irq(bus->irq, chip);
2060a41d1224STakashi Iwai 	bus->irq = -1;
2061f36da940STakashi Iwai 	chip->card->sync_irq = -1;
2062f46ea609SDylan Reid 	pci_disable_msi(chip->pci);
2063f46ea609SDylan Reid 	chip->msi = 0;
2064f46ea609SDylan Reid 	err = azx_acquire_irq(chip, 1);
2065f46ea609SDylan Reid 	if (err < 0)
2066f46ea609SDylan Reid 		return err;
2067f46ea609SDylan Reid 
2068f46ea609SDylan Reid 	return 0;
2069f46ea609SDylan Reid }
2070f46ea609SDylan Reid 
20716317e5ebSTakashi Iwai /* Denylist for skipping the whole probe:
20723c6fd1f0STakashi Iwai  * some HD-audio PCI entries are exposed without any codecs, and such devices
20733c6fd1f0STakashi Iwai  * should be ignored from the beginning.
20743c6fd1f0STakashi Iwai  */
20756317e5ebSTakashi Iwai static const struct pci_device_id driver_denylist[] = {
2076977dfef4STakashi Iwai 	{ PCI_DEVICE_SUB(0x1022, 0x1487, 0x1043, 0x874f) }, /* ASUS ROG Zenith II / Strix */
2077977dfef4STakashi Iwai 	{ PCI_DEVICE_SUB(0x1022, 0x1487, 0x1462, 0xcb59) }, /* MSI TRX40 Creator */
2078977dfef4STakashi Iwai 	{ PCI_DEVICE_SUB(0x1022, 0x1487, 0x1462, 0xcb60) }, /* MSI TRX40 */
20793c6fd1f0STakashi Iwai 	{}
20803c6fd1f0STakashi Iwai };
20813c6fd1f0STakashi Iwai 
2082a43ff5baSTakashi Iwai static const struct hda_controller_ops pci_hda_ops = {
2083a43ff5baSTakashi Iwai 	.disable_msi_reset_irq = disable_msi_reset_irq,
20847ca954a8SDylan Reid 	.position_check = azx_position_check,
208540830813SDylan Reid };
208640830813SDylan Reid 
208769458e2cSTakashi Iwai static DECLARE_BITMAP(probed_devs, SNDRV_CARDS);
208869458e2cSTakashi Iwai 
azx_probe(struct pci_dev * pci,const struct pci_device_id * pci_id)2089e23e7a14SBill Pemberton static int azx_probe(struct pci_dev *pci,
2090d01ce99fSTakashi Iwai 		     const struct pci_device_id *pci_id)
20911da177e4SLinus Torvalds {
2092a98f90fdSTakashi Iwai 	struct snd_card *card;
20939a34af4aSTakashi Iwai 	struct hda_intel *hda;
2094a98f90fdSTakashi Iwai 	struct azx *chip;
2095aad730d0STakashi Iwai 	bool schedule_probe;
209669458e2cSTakashi Iwai 	int dev;
2097927fc866SPavel Machek 	int err;
20981da177e4SLinus Torvalds 
20996317e5ebSTakashi Iwai 	if (pci_match_id(driver_denylist, pci)) {
21006317e5ebSTakashi Iwai 		dev_info(&pci->dev, "Skipping the device on the denylist\n");
21013c6fd1f0STakashi Iwai 		return -ENODEV;
21023c6fd1f0STakashi Iwai 	}
21033c6fd1f0STakashi Iwai 
210469458e2cSTakashi Iwai 	dev = find_first_zero_bit(probed_devs, SNDRV_CARDS);
21055aba4f8eSTakashi Iwai 	if (dev >= SNDRV_CARDS)
21065aba4f8eSTakashi Iwai 		return -ENODEV;
21075aba4f8eSTakashi Iwai 	if (!enable[dev]) {
210869458e2cSTakashi Iwai 		set_bit(dev, probed_devs);
21095aba4f8eSTakashi Iwai 		return -ENOENT;
21105aba4f8eSTakashi Iwai 	}
21115aba4f8eSTakashi Iwai 
211282d9d54aSJaroslav Kysela 	/*
211382d9d54aSJaroslav Kysela 	 * stop probe if another Intel's DSP driver should be activated
211482d9d54aSJaroslav Kysela 	 */
21157fba6aeaSTakashi Iwai 	if (dmic_detect) {
211682d9d54aSJaroslav Kysela 		err = snd_intel_dsp_driver_probe(pci);
2117ae035947SPierre-Louis Bossart 		if (err != SND_INTEL_DSP_DRIVER_ANY && err != SND_INTEL_DSP_DRIVER_LEGACY) {
2118ae035947SPierre-Louis Bossart 			dev_dbg(&pci->dev, "HDAudio driver not selected, aborting probe\n");
211982d9d54aSJaroslav Kysela 			return -ENODEV;
2120ae035947SPierre-Louis Bossart 		}
21217fba6aeaSTakashi Iwai 	} else {
21227fba6aeaSTakashi Iwai 		dev_warn(&pci->dev, "dmic_detect option is deprecated, pass snd-intel-dspcfg.dsp_driver=1 option instead\n");
212382d9d54aSJaroslav Kysela 	}
212482d9d54aSJaroslav Kysela 
212560c5772bSTakashi Iwai 	err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
212660c5772bSTakashi Iwai 			   0, &card);
2127e58de7baSTakashi Iwai 	if (err < 0) {
21284e76a883STakashi Iwai 		dev_err(&pci->dev, "Error creating card!\n");
2129e58de7baSTakashi Iwai 		return err;
21301da177e4SLinus Torvalds 	}
21311da177e4SLinus Torvalds 
2132a43ff5baSTakashi Iwai 	err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
213341dda0fdSWu Fengguang 	if (err < 0)
213441dda0fdSWu Fengguang 		goto out_free;
2135421a1252STakashi Iwai 	card->private_data = chip;
21369a34af4aSTakashi Iwai 	hda = container_of(chip, struct hda_intel, chip);
2137f4c482a4STakashi Iwai 
2138f4c482a4STakashi Iwai 	pci_set_drvdata(pci, card);
2139f4c482a4STakashi Iwai 
2140f4c482a4STakashi Iwai 	err = register_vga_switcheroo(chip);
2141f4c482a4STakashi Iwai 	if (err < 0) {
21422b760d88SLukas Wunner 		dev_err(card->dev, "Error registering vga_switcheroo client\n");
2143f4c482a4STakashi Iwai 		goto out_free;
2144f4c482a4STakashi Iwai 	}
2145f4c482a4STakashi Iwai 
2146f4c482a4STakashi Iwai 	if (check_hdmi_disabled(pci)) {
21474e76a883STakashi Iwai 		dev_info(card->dev, "VGA controller is disabled\n");
21484e76a883STakashi Iwai 		dev_info(card->dev, "Delaying initialization\n");
2149f4c482a4STakashi Iwai 		chip->disabled = true;
2150f4c482a4STakashi Iwai 	}
2151f4c482a4STakashi Iwai 
2152aad730d0STakashi Iwai 	schedule_probe = !chip->disabled;
21531da177e4SLinus Torvalds 
21544918cdabSTakashi Iwai #ifdef CONFIG_SND_HDA_PATCH_LOADER
21554918cdabSTakashi Iwai 	if (patch[dev] && *patch[dev]) {
21564e76a883STakashi Iwai 		dev_info(card->dev, "Applying patch firmware '%s'\n",
21574e76a883STakashi Iwai 			 patch[dev]);
21585cb543dbSTakashi Iwai 		err = request_firmware_nowait(THIS_MODULE, true, patch[dev],
21595cb543dbSTakashi Iwai 					      &pci->dev, GFP_KERNEL, card,
21605cb543dbSTakashi Iwai 					      azx_firmware_cb);
21614918cdabSTakashi Iwai 		if (err < 0)
21624918cdabSTakashi Iwai 			goto out_free;
2163aad730d0STakashi Iwai 		schedule_probe = false; /* continued in azx_firmware_cb() */
21644918cdabSTakashi Iwai 	}
21654918cdabSTakashi Iwai #endif /* CONFIG_SND_HDA_PATCH_LOADER */
21664918cdabSTakashi Iwai 
2167aad730d0STakashi Iwai #ifndef CONFIG_SND_HDA_I915
21681b21bd7aSAmadeusz Sławiński 	if (HDA_CONTROLLER_IN_GPU(pci))
21696ee8eeb4STakashi Iwai 		dev_err(card->dev, "Haswell/Broadwell HDMI/DP must build in CONFIG_SND_HDA_I915\n");
217099a2008dSWang Xingchao #endif
217199a2008dSWang Xingchao 
2172aad730d0STakashi Iwai 	if (schedule_probe)
2173c0f1886dSTakashi Iwai 		schedule_delayed_work(&hda->probe_work, 0);
2174a82d51edSTakashi Iwai 
217569458e2cSTakashi Iwai 	set_bit(dev, probed_devs);
217688d071fcSTakashi Iwai 	if (chip->disabled)
21779a34af4aSTakashi Iwai 		complete_all(&hda->probe_wait);
2178a82d51edSTakashi Iwai 	return 0;
2179a82d51edSTakashi Iwai 
2180a82d51edSTakashi Iwai out_free:
2181a82d51edSTakashi Iwai 	snd_card_free(card);
2182a82d51edSTakashi Iwai 	return err;
2183a82d51edSTakashi Iwai }
2184a82d51edSTakashi Iwai 
21851ba8f9d3SHans de Goede #ifdef CONFIG_PM
21861ba8f9d3SHans de Goede /* On some boards setting power_save to a non 0 value leads to clicking /
21871ba8f9d3SHans de Goede  * popping sounds when ever we enter/leave powersaving mode. Ideally we would
21881ba8f9d3SHans de Goede  * figure out how to avoid these sounds, but that is not always feasible.
21891ba8f9d3SHans de Goede  * So we keep a list of devices where we disable powersaving as its known
21901ba8f9d3SHans de Goede  * to causes problems on these devices.
21911ba8f9d3SHans de Goede  */
21926317e5ebSTakashi Iwai static const struct snd_pci_quirk power_save_denylist[] = {
21931ba8f9d3SHans de Goede 	/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
21948e82a728SHans de Goede 	SND_PCI_QUIRK(0x1849, 0xc892, "Asrock B85M-ITX", 0),
21951ba8f9d3SHans de Goede 	/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
219639070a98SHans de Goede 	SND_PCI_QUIRK(0x1849, 0x0397, "Asrock N68C-S UCC", 0),
219739070a98SHans de Goede 	/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
219845e5fbc2SHans de Goede 	SND_PCI_QUIRK(0x1849, 0x7662, "Asrock H81M-HDS", 0),
219945e5fbc2SHans de Goede 	/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
22001ba8f9d3SHans de Goede 	SND_PCI_QUIRK(0x1043, 0x8733, "Asus Prime X370-Pro", 0),
220138d9c12cSHans de Goede 	/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
22025cb6b5fcSHans de Goede 	SND_PCI_QUIRK(0x1028, 0x0497, "Dell Precision T3600", 0),
22035cb6b5fcSHans de Goede 	/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
220438d9c12cSHans de Goede 	/* Note the P55A-UD3 and Z87-D3HP share the subsys id for the HDA dev */
220538d9c12cSHans de Goede 	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P55A-UD3 / Z87-D3HP", 0),
22065cb6b5fcSHans de Goede 	/* https://bugzilla.redhat.com/show_bug.cgi?id=1525104 */
22075cb6b5fcSHans de Goede 	SND_PCI_QUIRK(0x8086, 0x2040, "Intel DZ77BH-55K", 0),
2208f91f1806SHans de Goede 	/* https://bugzilla.kernel.org/show_bug.cgi?id=199607 */
2209f91f1806SHans de Goede 	SND_PCI_QUIRK(0x8086, 0x2057, "Intel NUC5i7RYB", 0),
2210cae30527SHui Wang 	/* https://bugs.launchpad.net/bugs/1821663 */
2211cae30527SHui Wang 	SND_PCI_QUIRK(0x8086, 0x2064, "Intel SDP 8086:2064", 0),
2212dd6dd536SHans de Goede 	/* https://bugzilla.redhat.com/show_bug.cgi?id=1520902 */
2213dd6dd536SHans de Goede 	SND_PCI_QUIRK(0x8086, 0x2068, "Intel NUC7i3BNB", 0),
22141ba8f9d3SHans de Goede 	/* https://bugzilla.kernel.org/show_bug.cgi?id=198611 */
22151ba8f9d3SHans de Goede 	SND_PCI_QUIRK(0x17aa, 0x2227, "Lenovo X1 Carbon 3rd Gen", 0),
2216057a28efSKailang Yang 	SND_PCI_QUIRK(0x17aa, 0x316e, "Lenovo ThinkCentre M70q", 0),
2217721f1e6cSJaroslav Kysela 	/* https://bugzilla.redhat.com/show_bug.cgi?id=1689623 */
2218721f1e6cSJaroslav Kysela 	SND_PCI_QUIRK(0x17aa, 0x367b, "Lenovo IdeaCentre B550", 0),
2219721f1e6cSJaroslav Kysela 	/* https://bugzilla.redhat.com/show_bug.cgi?id=1572975 */
2220721f1e6cSJaroslav Kysela 	SND_PCI_QUIRK(0x17aa, 0x36a7, "Lenovo C50 All in one", 0),
2221cae30527SHui Wang 	/* https://bugs.launchpad.net/bugs/1821663 */
2222cae30527SHui Wang 	SND_PCI_QUIRK(0x1631, 0xe017, "Packard Bell NEC IMEDIA 5204", 0),
222395c06d0dSTakashi Iwai 	/* KONTRON SinglePC may cause a stall at runtime resume */
222495c06d0dSTakashi Iwai 	SND_PCI_QUIRK(0x1734, 0x1232, "KONTRON SinglePC", 0),
2225*3f63e8feSHoku Ishibe 	/* Dell ALC3271 */
2226*3f63e8feSHoku Ishibe 	SND_PCI_QUIRK(0x1028, 0x0962, "Dell ALC3271", 0),
22271ba8f9d3SHans de Goede 	{}
22281ba8f9d3SHans de Goede };
22291ba8f9d3SHans de Goede #endif /* CONFIG_PM */
22301ba8f9d3SHans de Goede 
set_default_power_save(struct azx * chip)223137a3a98eSTakashi Iwai static void set_default_power_save(struct azx *chip)
223237a3a98eSTakashi Iwai {
223337a3a98eSTakashi Iwai 	int val = power_save;
223437a3a98eSTakashi Iwai 
223537a3a98eSTakashi Iwai #ifdef CONFIG_PM
223637a3a98eSTakashi Iwai 	if (pm_blacklist) {
223737a3a98eSTakashi Iwai 		const struct snd_pci_quirk *q;
223837a3a98eSTakashi Iwai 
22396317e5ebSTakashi Iwai 		q = snd_pci_quirk_lookup(chip->pci, power_save_denylist);
224037a3a98eSTakashi Iwai 		if (q && val) {
22416317e5ebSTakashi Iwai 			dev_info(chip->card->dev, "device %04x:%04x is on the power_save denylist, forcing power_save to 0\n",
224237a3a98eSTakashi Iwai 				 q->subvendor, q->subdevice);
224337a3a98eSTakashi Iwai 			val = 0;
224437a3a98eSTakashi Iwai 		}
224537a3a98eSTakashi Iwai 	}
224637a3a98eSTakashi Iwai #endif /* CONFIG_PM */
224737a3a98eSTakashi Iwai 	snd_hda_set_power_save(&chip->bus, val * 1000);
224837a3a98eSTakashi Iwai }
224937a3a98eSTakashi Iwai 
2250e62a42aeSDylan Reid /* number of codec slots for each chipset: 0 = default slots (i.e. 4) */
2251bf82326fSTakashi Iwai static const unsigned int azx_max_codecs[AZX_NUM_DRIVERS] = {
2252e62a42aeSDylan Reid 	[AZX_DRIVER_NVIDIA] = 8,
2253e62a42aeSDylan Reid 	[AZX_DRIVER_TERA] = 1,
2254e62a42aeSDylan Reid };
2255e62a42aeSDylan Reid 
azx_probe_continue(struct azx * chip)225648c8b0ebSTakashi Iwai static int azx_probe_continue(struct azx *chip)
2257a82d51edSTakashi Iwai {
22589a34af4aSTakashi Iwai 	struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
225998d8fc6cSMengdong Lin 	struct hdac_bus *bus = azx_bus(chip);
2260c67e2228SWang Xingchao 	struct pci_dev *pci = chip->pci;
2261a82d51edSTakashi Iwai 	int dev = chip->dev_index;
2262a82d51edSTakashi Iwai 	int err;
2263a82d51edSTakashi Iwai 
2264c0f1886dSTakashi Iwai 	if (chip->disabled || hda->init_failed)
2265c0f1886dSTakashi Iwai 		return -EIO;
2266c0f1886dSTakashi Iwai 	if (hda->probe_retry)
2267c0f1886dSTakashi Iwai 		goto probe_retry;
2268c0f1886dSTakashi Iwai 
2269305a0adeSTakashi Iwai 	to_hda_bus(bus)->bus_probing = 1;
2270a41d1224STakashi Iwai 	hda->probe_continued = 1;
2271795614ddSMengdong Lin 
2272fcc88d91STakashi Iwai 	/* bind with i915 if needed */
2273dba9b7b6STakashi Iwai 	if (chip->driver_caps & AZX_DCAPS_I915_COMPONENT) {
227498d8fc6cSMengdong Lin 		err = snd_hdac_i915_init(bus);
2275535115b5STakashi Iwai 		if (err < 0) {
2276535115b5STakashi Iwai 			/* if the controller is bound only with HDMI/DP
2277535115b5STakashi Iwai 			 * (for HSW and BDW), we need to abort the probe;
2278535115b5STakashi Iwai 			 * for other chips, still continue probing as other
2279535115b5STakashi Iwai 			 * codecs can be on the same link.
2280535115b5STakashi Iwai 			 */
22811b21bd7aSAmadeusz Sławiński 			if (HDA_CONTROLLER_IN_GPU(pci)) {
2282bed2e98eSTakashi Iwai 				dev_err(chip->card->dev,
2283bed2e98eSTakashi Iwai 					"HSW/BDW HD-audio HDMI/DP requires binding with gfx driver\n");
2284535115b5STakashi Iwai 				goto out_free;
2285fcc88d91STakashi Iwai 			} else {
2286fcc88d91STakashi Iwai 				/* don't bother any longer */
2287e454ff8eSTakashi Iwai 				chip->driver_caps &= ~AZX_DCAPS_I915_COMPONENT;
2288535115b5STakashi Iwai 			}
2289fcc88d91STakashi Iwai 		}
2290e454ff8eSTakashi Iwai 
2291e454ff8eSTakashi Iwai 		/* HSW/BDW controllers need this power */
22921b21bd7aSAmadeusz Sławiński 		if (HDA_CONTROLLER_IN_GPU(pci))
229362c2b4beSJiapeng Zhong 			hda->need_i915_power = true;
2294fcc88d91STakashi Iwai 	}
2295fcc88d91STakashi Iwai 
2296fcc88d91STakashi Iwai 	/* Request display power well for the HDA controller or codec. For
2297fcc88d91STakashi Iwai 	 * Haswell/Broadwell, both the display HDA controller and codec need
2298fcc88d91STakashi Iwai 	 * this power. For other platforms, like Baytrail/Braswell, only the
2299fcc88d91STakashi Iwai 	 * display codec needs the power and it can be released after probe.
2300fcc88d91STakashi Iwai 	 */
23014f799e73STakashi Iwai 	display_power(chip, true);
230299a2008dSWang Xingchao 
23035c90680eSTakashi Iwai 	err = azx_first_init(chip);
23045c90680eSTakashi Iwai 	if (err < 0)
23055c90680eSTakashi Iwai 		goto out_free;
23065c90680eSTakashi Iwai 
23072dca0bbaSJaroslav Kysela #ifdef CONFIG_SND_HDA_INPUT_BEEP
23082dca0bbaSJaroslav Kysela 	chip->beep_mode = beep_mode[dev];
23092dca0bbaSJaroslav Kysela #endif
23102dca0bbaSJaroslav Kysela 
2311d045bcefSJaroslav Kysela 	chip->ctl_dev_id = ctl_dev_id;
2312d045bcefSJaroslav Kysela 
23131da177e4SLinus Torvalds 	/* create codec instances */
23149479e75fSTakashi Iwai 	if (bus->codec_mask) {
231596d2bd6eSTakashi Iwai 		err = azx_probe_codecs(chip, azx_max_codecs[chip->driver_type]);
231696d2bd6eSTakashi Iwai 		if (err < 0)
231796d2bd6eSTakashi Iwai 			goto out_free;
23189479e75fSTakashi Iwai 	}
231996d2bd6eSTakashi Iwai 
23204ea6fbc8STakashi Iwai #ifdef CONFIG_SND_HDA_PATCH_LOADER
23214918cdabSTakashi Iwai 	if (chip->fw) {
2322a41d1224STakashi Iwai 		err = snd_hda_load_patch(&chip->bus, chip->fw->size,
23234918cdabSTakashi Iwai 					 chip->fw->data);
23244ea6fbc8STakashi Iwai 		if (err < 0)
23254ea6fbc8STakashi Iwai 			goto out_free;
2326e39ae856STakashi Iwai #ifndef CONFIG_PM
23274918cdabSTakashi Iwai 		release_firmware(chip->fw); /* no longer needed */
23284918cdabSTakashi Iwai 		chip->fw = NULL;
2329e39ae856STakashi Iwai #endif
23304ea6fbc8STakashi Iwai 	}
23314ea6fbc8STakashi Iwai #endif
2332c0f1886dSTakashi Iwai 
2333c0f1886dSTakashi Iwai  probe_retry:
23349479e75fSTakashi Iwai 	if (bus->codec_mask && !(probe_only[dev] & 1)) {
2335a1e21c90STakashi Iwai 		err = azx_codec_configure(chip);
2336c0f1886dSTakashi Iwai 		if (err) {
2337c0f1886dSTakashi Iwai 			if ((chip->driver_caps & AZX_DCAPS_RETRY_PROBE) &&
2338c0f1886dSTakashi Iwai 			    ++hda->probe_retry < 60) {
2339c0f1886dSTakashi Iwai 				schedule_delayed_work(&hda->probe_work,
2340c0f1886dSTakashi Iwai 						      msecs_to_jiffies(1000));
2341c0f1886dSTakashi Iwai 				return 0; /* keep things up */
2342c0f1886dSTakashi Iwai 			}
2343c0f1886dSTakashi Iwai 			dev_err(chip->card->dev, "Cannot probe codecs, giving up\n");
2344a1e21c90STakashi Iwai 			goto out_free;
2345a1e21c90STakashi Iwai 		}
2346c0f1886dSTakashi Iwai 	}
23471da177e4SLinus Torvalds 
2348a82d51edSTakashi Iwai 	err = snd_card_register(chip->card);
234941dda0fdSWu Fengguang 	if (err < 0)
235041dda0fdSWu Fengguang 		goto out_free;
23511da177e4SLinus Torvalds 
235237a3a98eSTakashi Iwai 	setup_vga_switcheroo_runtime_pm(chip);
235337a3a98eSTakashi Iwai 
2354cb53c626STakashi Iwai 	chip->running = 1;
235565fcd41dSTakashi Iwai 	azx_add_card_list(chip);
235607f4f97dSLukas Wunner 
235737a3a98eSTakashi Iwai 	set_default_power_save(chip);
23581ba8f9d3SHans de Goede 
23593ba21113SRoy Spliet 	if (azx_has_pm_runtime(chip)) {
23603ba21113SRoy Spliet 		pm_runtime_use_autosuspend(&pci->dev);
23619fc149c3SKai-Heng Feng 		pm_runtime_allow(&pci->dev);
236230ff5957SVille Syrjälä 		pm_runtime_put_autosuspend(&pci->dev);
23633ba21113SRoy Spliet 	}
23641da177e4SLinus Torvalds 
236541dda0fdSWu Fengguang out_free:
23662393e755STakashi Iwai 	if (err < 0) {
236739173303STakashi Iwai 		pci_set_drvdata(pci, NULL);
236839173303STakashi Iwai 		snd_card_free(chip->card);
23692393e755STakashi Iwai 		return err;
23702393e755STakashi Iwai 	}
23712393e755STakashi Iwai 
23722393e755STakashi Iwai 	if (!hda->need_i915_power)
2373029d92c2STakashi Iwai 		display_power(chip, false);
23749a34af4aSTakashi Iwai 	complete_all(&hda->probe_wait);
2375305a0adeSTakashi Iwai 	to_hda_bus(bus)->bus_probing = 0;
2376c0f1886dSTakashi Iwai 	hda->probe_retry = 0;
23772393e755STakashi Iwai 	return 0;
23781da177e4SLinus Torvalds }
23791da177e4SLinus Torvalds 
azx_remove(struct pci_dev * pci)2380e23e7a14SBill Pemberton static void azx_remove(struct pci_dev *pci)
23811da177e4SLinus Torvalds {
23829121947dSTakashi Iwai 	struct snd_card *card = pci_get_drvdata(pci);
2383991f86d7STakashi Iwai 	struct azx *chip;
2384991f86d7STakashi Iwai 	struct hda_intel *hda;
2385b8dfc462SMengdong Lin 
2386991f86d7STakashi Iwai 	if (card) {
23870b8c8219STakashi Iwai 		/* cancel the pending probing work */
2388991f86d7STakashi Iwai 		chip = card->private_data;
2389991f86d7STakashi Iwai 		hda = container_of(chip, struct hda_intel, chip);
2390ab949d51STakashi Iwai 		/* FIXME: below is an ugly workaround.
2391ab949d51STakashi Iwai 		 * Both device_release_driver() and driver_probe_device()
2392ab949d51STakashi Iwai 		 * take *both* the device's and its parent's lock before
2393ab949d51STakashi Iwai 		 * calling the remove() and probe() callbacks.  The codec
2394ab949d51STakashi Iwai 		 * probe takes the locks of both the codec itself and its
2395ab949d51STakashi Iwai 		 * parent, i.e. the PCI controller dev.  Meanwhile, when
2396ab949d51STakashi Iwai 		 * the PCI controller is unbound, it takes its lock, too
2397ab949d51STakashi Iwai 		 * ==> ouch, a deadlock!
2398ab949d51STakashi Iwai 		 * As a workaround, we unlock temporarily here the controller
2399ab949d51STakashi Iwai 		 * device during cancel_work_sync() call.
2400ab949d51STakashi Iwai 		 */
2401ab949d51STakashi Iwai 		device_unlock(&pci->dev);
2402c0f1886dSTakashi Iwai 		cancel_delayed_work_sync(&hda->probe_work);
2403ab949d51STakashi Iwai 		device_lock(&pci->dev);
2404991f86d7STakashi Iwai 
240569458e2cSTakashi Iwai 		clear_bit(chip->dev_index, probed_devs);
2406e81478bbSKai Vehmanen 		pci_set_drvdata(pci, NULL);
24079121947dSTakashi Iwai 		snd_card_free(card);
24081da177e4SLinus Torvalds 	}
2409991f86d7STakashi Iwai }
24101da177e4SLinus Torvalds 
azx_shutdown(struct pci_dev * pci)2411b2a0bafaSTakashi Iwai static void azx_shutdown(struct pci_dev *pci)
2412b2a0bafaSTakashi Iwai {
2413b2a0bafaSTakashi Iwai 	struct snd_card *card = pci_get_drvdata(pci);
2414b2a0bafaSTakashi Iwai 	struct azx *chip;
2415b2a0bafaSTakashi Iwai 
2416b2a0bafaSTakashi Iwai 	if (!card)
2417b2a0bafaSTakashi Iwai 		return;
2418b2a0bafaSTakashi Iwai 	chip = card->private_data;
2419b2a0bafaSTakashi Iwai 	if (chip && chip->running)
24206f445784STakashi Iwai 		__azx_shutdown_chip(chip, true);
2421b2a0bafaSTakashi Iwai }
2422b2a0bafaSTakashi Iwai 
24231da177e4SLinus Torvalds /* PCI IDs */
24246f51f6cfSBenoit Taine static const struct pci_device_id azx_ids[] = {
2425d2f2fcd2SSeth Heasley 	/* CPT */
2426e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_CPT, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM) },
2427cea310e8SSeth Heasley 	/* PBG */
2428e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_PBG, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM) },
2429d2edeb7cSSeth Heasley 	/* Panther Point */
2430e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_PPT, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM) },
24318bc039a1SSeth Heasley 	/* Lynx Point */
2432e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_LPT, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH) },
243377f07800STakashi Iwai 	/* 9 Series */
2434e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_9_SERIES, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH) },
2435884b088fSJames Ralston 	/* Wellsburg */
2436e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_WBG_0, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH) },
2437e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_WBG_1, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH) },
24385cf92c8bSAlexandra Yates 	/* Lewisburg */
2439e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_LBG_0, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE) },
2440e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_LBG_1, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE) },
2441144dad99SJames Ralston 	/* Lynx Point-LP */
2442e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_LPT_LP_0, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH) },
2443144dad99SJames Ralston 	/* Lynx Point-LP */
2444e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_LPT_LP_1, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH) },
24454eeca499SJames Ralston 	/* Wildcat Point-LP */
2446e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_WPT_LP, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH) },
2447e6232c80SAmadeusz Sławiński 	/* Skylake (Sunrise Point) */
2448e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_SKL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2449e6232c80SAmadeusz Sławiński 	/* Skylake-LP (Sunrise Point-LP) */
2450e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_SKL_LP, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
245135639a0eSVinod Koul 	/* Kabylake */
2452e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_KBL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
245335639a0eSVinod Koul 	/* Kabylake-LP */
2454e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_KBL_LP, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
24556858107eSVinod Koul 	/* Kabylake-H */
2456e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_KBL_H, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2457e79b0006SMegha Dey 	/* Coffelake */
2458e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_CNL_H, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
24592357f6f0SGuneshwor Singh 	/* Cannonlake */
2460e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_CNL_LP, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2461d4c2ccdbSPierre-Louis Bossart 	/* CometLake-LP */
2462e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_CML_LP, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2463d4c2ccdbSPierre-Louis Bossart 	/* CometLake-H */
2464e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_CML_H, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2465e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_RKL_S, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2466b73a5854SChiou, Cooper 	/* CometLake-S */
2467e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_CML_S, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2468f84d3a1eSKai-Chuan Hsieh 	/* CometLake-R */
2469e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_CML_R, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2470491f8331SGuneshwor Singh 	/* Icelake */
2471e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_ICL_LP, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2472d50313a5SPierre-Louis Bossart 	/* Icelake-H */
2473e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_ICL_H, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
24744750c212SPan Xiuli 	/* Jasperlake */
2475e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_ICL_N, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2476e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_JSL_N, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
24774750c212SPan Xiuli 	/* Tigerlake */
2478e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_TGL_LP, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2479d50313a5SPierre-Louis Bossart 	/* Tigerlake-H */
2480e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_TGL_H, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
248169b08bdfSKai Vehmanen 	/* DG1 */
2482e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_DG1, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2483d85ffff5SKai Vehmanen 	/* DG2 */
2484e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_DG2_0, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2485e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_DG2_1, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2486e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_DG2_2, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2487d78359b2SKai Vehmanen 	/* Alderlake-S */
2488e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_ADL_S, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
24895e941fc0SKai Vehmanen 	/* Alderlake-P */
2490e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_ADL_P, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2491e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_ADL_PS, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2492e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_ADL_PX, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
24934ad7935dSKai Vehmanen 	/* Alderlake-M */
2494e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_ADL_M, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
24954d5a628dSKai Vehmanen 	/* Alderlake-N */
2496e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_ADL_N, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2497f94287b6SLai, Poey Seng 	/* Elkhart Lake */
2498e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_EHL_0, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2499e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_EHL_3, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2500a531caa5SKai Vehmanen 	/* Raptor Lake */
2501e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_RPL_S, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2502e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_RPL_P_0, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2503e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_RPL_P_1, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2504e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_RPL_M, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2505e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_RPL_PX, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2506e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_MTL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2507714b2f02SFred Oh 	/* Lunarlake-P */
2508e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_LNL_P, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
25093bef0681SKai Vehmanen 	/* Arrow Lake-S */
25103bef0681SKai Vehmanen 	{ PCI_DEVICE_DATA(INTEL, HDA_ARL_S, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
25110f04f8d6SPierre-Louis Bossart 	/* Arrow Lake */
25120f04f8d6SPierre-Louis Bossart 	{ PCI_DEVICE_DATA(INTEL, HDA_ARL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE) },
2513e6232c80SAmadeusz Sławiński 	/* Apollolake (Broxton-P) */
2514e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_APL, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON) },
251544b46d73SVinod Koul 	/* Gemini-Lake */
2516e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_GML, AZX_DRIVER_SKL | AZX_DCAPS_INTEL_BROXTON) },
2517e926f2c8SWang Xingchao 	/* Haswell */
2518e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_HSW_0, AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL) },
2519e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_HSW_2, AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL) },
2520e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_HSW_3, AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_HASWELL) },
2521862d7618SMengdong Lin 	/* Broadwell */
2522e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_BDW, AZX_DRIVER_HDMI | AZX_DCAPS_INTEL_BROADWELL) },
252399df18b3SPierre-Louis Bossart 	/* 5 Series/3400 */
2524e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_5_3400_SERIES_0, AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM) },
2525e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_5_3400_SERIES_1, AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_NOPM) },
2526f748abccSTakashi Iwai 	/* Poulsbo */
2527e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_POULSBO, AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE |
2528e6232c80SAmadeusz Sławiński 	  AZX_DCAPS_POSFIX_LPIB) },
2529f748abccSTakashi Iwai 	/* Oaktrail */
2530e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_OAKTRAIL, AZX_DRIVER_SCH | AZX_DCAPS_INTEL_PCH_BASE) },
2531e44007e0SChew, Chiau Ee 	/* BayTrail */
2532e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_BYT, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BAYTRAIL) },
2533f31b2ffcSLibin Yang 	/* Braswell */
2534e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_BSW, AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BRASWELL) },
2535b42b4afbSTakashi Iwai 	/* ICH6 */
2536e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_ICH6, AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH) },
2537b42b4afbSTakashi Iwai 	/* ICH7 */
2538e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_ICH7, AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH) },
2539b42b4afbSTakashi Iwai 	/* ESB2 */
2540e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_ESB2, AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH) },
2541b42b4afbSTakashi Iwai 	/* ICH8 */
2542e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_ICH8, AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH) },
2543b42b4afbSTakashi Iwai 	/* ICH9 */
2544e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_ICH9_0, AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH) },
2545b42b4afbSTakashi Iwai 	/* ICH9 */
2546e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_ICH9_1, AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH) },
2547b42b4afbSTakashi Iwai 	/* ICH10 */
2548e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_ICH10_0, AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH) },
2549b42b4afbSTakashi Iwai 	/* ICH10 */
2550e6232c80SAmadeusz Sławiński 	{ PCI_DEVICE_DATA(INTEL, HDA_ICH10_1, AZX_DRIVER_ICH | AZX_DCAPS_INTEL_ICH) },
2551b6864535STakashi Iwai 	/* Generic Intel */
2552b6864535STakashi Iwai 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID),
2553b6864535STakashi Iwai 	  .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2554b6864535STakashi Iwai 	  .class_mask = 0xffffff,
2555103884a3STakashi Iwai 	  .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_NO_ALIGN_BUFSIZE },
25569477c58eSTakashi Iwai 	/* ATI SB 450/600/700/800/900 */
2557e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0x437b),
25589477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },
2559e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0x4383),
25609477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB },
25619477c58eSTakashi Iwai 	/* AMD Hudson */
2562e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(AMD, 0x780d),
25639477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB },
2564c02f77d3STakashi Iwai 	/* AMD, X370 & co */
2565e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(AMD, 0x1457),
2566c02f77d3STakashi Iwai 	  .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_AMD_SB },
2567de768ce4STakashi Iwai 	/* AMD, X570 & co */
2568e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(AMD, 0x1487),
2569de768ce4STakashi Iwai 	  .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_AMD_SB },
25703deef52cSKai-Heng Feng 	/* AMD Stoney */
2571e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(AMD, 0x157a),
25723deef52cSKai-Heng Feng 	  .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB |
25733deef52cSKai-Heng Feng 			 AZX_DCAPS_PM_RUNTIME },
25749ceace3cSVijendar Mukunda 	/* AMD Raven */
2575e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(AMD, 0x15e3),
2576d2c63b7dSTakashi Iwai 	  .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_AMD_SB },
257787218e9cSTakashi Iwai 	/* ATI HDMI */
2578e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0x0002),
257920c7842eSAlex Deucher 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
258020c7842eSAlex Deucher 	  AZX_DCAPS_PM_RUNTIME },
2581e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0x1308),
2582650474fbSAlex Deucher 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
2583e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0x157a),
25845022813dSMaruthi Srinivas Bayyavarapu 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
2585e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0x15b3),
2586d716fb03SAwais Belal 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
2587e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0x793b),
25889477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2589e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0x7919),
25909477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2591e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0x960f),
25929477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2593e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0x970f),
25949477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2595e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0x9840),
2596650474fbSAlex Deucher 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
2597e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaa00),
25989477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2599e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaa08),
26009477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2601e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaa10),
26029477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2603e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaa18),
26049477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2605e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaa20),
26069477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2607e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaa28),
26089477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2609e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaa30),
26109477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2611e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaa38),
26129477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2613e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaa40),
26149477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2615e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaa48),
26169477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2617e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaa50),
2618bbaa0d66SClemens Ladisch 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2619e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaa58),
2620bbaa0d66SClemens Ladisch 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2621e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaa60),
2622bbaa0d66SClemens Ladisch 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2623e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaa68),
2624bbaa0d66SClemens Ladisch 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2625e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaa80),
2626bbaa0d66SClemens Ladisch 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2627e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaa88),
2628bbaa0d66SClemens Ladisch 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2629e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaa90),
2630bbaa0d66SClemens Ladisch 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2631e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaa98),
2632bbaa0d66SClemens Ladisch 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
2633e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0x9902),
263437e661eeSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
2635e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaaa0),
263637e661eeSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
2637e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaaa8),
263837e661eeSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
2639e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaab0),
264037e661eeSTakashi Iwai 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
2641e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaac0),
264220c7842eSAlex Deucher 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
264320c7842eSAlex Deucher 	  AZX_DCAPS_PM_RUNTIME },
2644e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaac8),
264520c7842eSAlex Deucher 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
264620c7842eSAlex Deucher 	  AZX_DCAPS_PM_RUNTIME },
2647e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaad8),
264873b1422bSAlex Deucher 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
264973b1422bSAlex Deucher 	  AZX_DCAPS_PM_RUNTIME },
2650e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaae0),
265173b1422bSAlex Deucher 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
265273b1422bSAlex Deucher 	  AZX_DCAPS_PM_RUNTIME },
2653e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaae8),
265473b1422bSAlex Deucher 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
265573b1422bSAlex Deucher 	  AZX_DCAPS_PM_RUNTIME },
2656e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaaf0),
265773b1422bSAlex Deucher 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
265873b1422bSAlex Deucher 	  AZX_DCAPS_PM_RUNTIME },
2659e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xaaf8),
266073b1422bSAlex Deucher 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
266173b1422bSAlex Deucher 	  AZX_DCAPS_PM_RUNTIME },
2662e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xab00),
266373b1422bSAlex Deucher 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
266473b1422bSAlex Deucher 	  AZX_DCAPS_PM_RUNTIME },
2665e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xab08),
266673b1422bSAlex Deucher 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
266773b1422bSAlex Deucher 	  AZX_DCAPS_PM_RUNTIME },
2668e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xab10),
266973b1422bSAlex Deucher 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
267073b1422bSAlex Deucher 	  AZX_DCAPS_PM_RUNTIME },
2671e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xab18),
267273b1422bSAlex Deucher 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
267373b1422bSAlex Deucher 	  AZX_DCAPS_PM_RUNTIME },
2674e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xab20),
267573b1422bSAlex Deucher 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
267673b1422bSAlex Deucher 	  AZX_DCAPS_PM_RUNTIME },
2677e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xab28),
267827a7c670SHersen Wu 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
267927a7c670SHersen Wu 	  AZX_DCAPS_PM_RUNTIME },
2680e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xab30),
2681fdcc4c22SEvan Quan 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
2682fdcc4c22SEvan Quan 	  AZX_DCAPS_PM_RUNTIME },
2683e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ATI, 0xab38),
268473b1422bSAlex Deucher 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS |
268573b1422bSAlex Deucher 	  AZX_DCAPS_PM_RUNTIME },
2686c51e4310Sjasontao 	/* GLENFLY */
2687bd9a77a9SWangYuli 	{ PCI_DEVICE(PCI_VENDOR_ID_GLENFLY, PCI_ANY_ID),
2688c51e4310Sjasontao 	  .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2689c51e4310Sjasontao 	  .class_mask = 0xffffff,
2690c51e4310Sjasontao 	  .driver_data = AZX_DRIVER_GFHDMI | AZX_DCAPS_POSFIX_LPIB |
2691c51e4310Sjasontao 	  AZX_DCAPS_NO_MSI | AZX_DCAPS_NO_64BIT },
269287218e9cSTakashi Iwai 	/* VIA VT8251/VT8237A */
2693e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(VIA, 0x3288), .driver_data = AZX_DRIVER_VIA },
2694754fdff8SAnnie Liu 	/* VIA GFX VT7122/VX900 */
2695e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(VIA, 0x9170), .driver_data = AZX_DRIVER_GENERIC },
2696754fdff8SAnnie Liu 	/* VIA GFX VT6122/VX11 */
2697e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(VIA, 0x9140), .driver_data = AZX_DRIVER_GENERIC },
269887218e9cSTakashi Iwai 	/* SIS966 */
2699e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(SI, 0x7502), .driver_data = AZX_DRIVER_SIS },
270087218e9cSTakashi Iwai 	/* ULI M5461 */
2701e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(AL, 0x5461), .driver_data = AZX_DRIVER_ULI },
270287218e9cSTakashi Iwai 	/* NVIDIA MCP */
27030c2fd1bfSTakashi Iwai 	{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID),
27040c2fd1bfSTakashi Iwai 	  .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
27050c2fd1bfSTakashi Iwai 	  .class_mask = 0xffffff,
27069477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_NVIDIA | AZX_DCAPS_PRESET_NVIDIA },
2707f269002eSKailang Yang 	/* Teradici */
27089477c58eSTakashi Iwai 	{ PCI_DEVICE(0x6549, 0x1200),
27099477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT },
2710f0b3da98SLars R. Damerow 	{ PCI_DEVICE(0x6549, 0x2200),
2711f0b3da98SLars R. Damerow 	  .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT },
27124e01f54bSTakashi Iwai 	/* Creative X-Fi (CA0110-IBG) */
2713f2a8ecafSTakashi Iwai 	/* CTHDA chips */
2714e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(CREATIVE, 0x0010),
2715f2a8ecafSTakashi Iwai 	  .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },
2716e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(CREATIVE, 0x0012),
2717f2a8ecafSTakashi Iwai 	  .driver_data = AZX_DRIVER_CTHDA | AZX_DCAPS_PRESET_CTHDA },
27188eeaa2f9STakashi Iwai #if !IS_ENABLED(CONFIG_SND_CTXFI)
2719313f6e2dSTakashi Iwai 	/* the following entry conflicts with snd-ctxfi driver,
2720313f6e2dSTakashi Iwai 	 * as ctxfi driver mutates from HD-audio to native mode with
2721313f6e2dSTakashi Iwai 	 * a special command sequence.
2722313f6e2dSTakashi Iwai 	 */
27234e01f54bSTakashi Iwai 	{ PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID),
27244e01f54bSTakashi Iwai 	  .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
27254e01f54bSTakashi Iwai 	  .class_mask = 0xffffff,
27269477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
2727ef85f299STakashi Iwai 	  AZX_DCAPS_NO_64BIT | AZX_DCAPS_POSFIX_LPIB },
2728313f6e2dSTakashi Iwai #else
2729313f6e2dSTakashi Iwai 	/* this entry seems still valid -- i.e. without emu20kx chip */
2730e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(CREATIVE, 0x0009),
27319477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND |
2732ef85f299STakashi Iwai 	  AZX_DCAPS_NO_64BIT | AZX_DCAPS_POSFIX_LPIB },
2733313f6e2dSTakashi Iwai #endif
2734c563f473STakashi Iwai 	/* CM8888 */
2735e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(CMEDIA, 0x5011),
2736c563f473STakashi Iwai 	  .driver_data = AZX_DRIVER_CMEDIA |
273737e661eeSTakashi Iwai 	  AZX_DCAPS_NO_MSI | AZX_DCAPS_POSFIX_LPIB | AZX_DCAPS_SNOOP_OFF },
2738e35d4b11SOtavio Salvador 	/* Vortex86MX */
2739e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(RDC, 0x3010), .driver_data = AZX_DRIVER_GENERIC },
27400f0714c5SBankim Bhavsar 	/* VMware HDAudio */
2741e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(VMWARE, 0x1977), .driver_data = AZX_DRIVER_GENERIC },
27429176b672SAndiry Brienza 	/* AMD/ATI Generic, PCI class code and Vendor ID for HD Audio */
2743c4da29caSYang, Libin 	{ PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),
2744c4da29caSYang, Libin 	  .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2745c4da29caSYang, Libin 	  .class_mask = 0xffffff,
27469477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI },
27479176b672SAndiry Brienza 	{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_ANY_ID),
27489176b672SAndiry Brienza 	  .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
27499176b672SAndiry Brienza 	  .class_mask = 0xffffff,
27509477c58eSTakashi Iwai 	  .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI },
2751b6fcab14STony W Wang-oc 	/* Zhaoxin */
2752e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(ZHAOXIN, 0x3288), .driver_data = AZX_DRIVER_ZHAOXIN },
275328bd137aSYanteng Si 	/* Loongson HDAudio*/
2754e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(LOONGSON, PCI_DEVICE_ID_LOONGSON_HDA),
275528bd137aSYanteng Si 	  .driver_data = AZX_DRIVER_LOONGSON },
2756e6232c80SAmadeusz Sławiński 	{ PCI_VDEVICE(LOONGSON, PCI_DEVICE_ID_LOONGSON_HDMI),
275728bd137aSYanteng Si 	  .driver_data = AZX_DRIVER_LOONGSON },
27581da177e4SLinus Torvalds 	{ 0, }
27591da177e4SLinus Torvalds };
27601da177e4SLinus Torvalds MODULE_DEVICE_TABLE(pci, azx_ids);
27611da177e4SLinus Torvalds 
27621da177e4SLinus Torvalds /* pci_driver definition */
2763e9f66d9bSTakashi Iwai static struct pci_driver azx_driver = {
27643733e424STakashi Iwai 	.name = KBUILD_MODNAME,
27651da177e4SLinus Torvalds 	.id_table = azx_ids,
27661da177e4SLinus Torvalds 	.probe = azx_probe,
2767e23e7a14SBill Pemberton 	.remove = azx_remove,
2768b2a0bafaSTakashi Iwai 	.shutdown = azx_shutdown,
276968cb2b55STakashi Iwai 	.driver = {
277068cb2b55STakashi Iwai 		.pm = AZX_PM_OPS,
277168cb2b55STakashi Iwai 	},
27721da177e4SLinus Torvalds };
27731da177e4SLinus Torvalds 
2774e9f66d9bSTakashi Iwai module_pci_driver(azx_driver);
2775