1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Common functionality for the alsa driver code base for HD Audio.
4*4882a593Smuzhiyun */
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun #ifndef __SOUND_HDA_CONTROLLER_H
7*4882a593Smuzhiyun #define __SOUND_HDA_CONTROLLER_H
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #include <linux/timecounter.h>
10*4882a593Smuzhiyun #include <linux/interrupt.h>
11*4882a593Smuzhiyun #include <sound/core.h>
12*4882a593Smuzhiyun #include <sound/pcm.h>
13*4882a593Smuzhiyun #include <sound/initval.h>
14*4882a593Smuzhiyun #include <sound/hda_codec.h>
15*4882a593Smuzhiyun #include <sound/hda_register.h>
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #define AZX_MAX_CODECS HDA_MAX_CODECS
18*4882a593Smuzhiyun #define AZX_DEFAULT_CODECS 4
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun /* driver quirks (capabilities) */
21*4882a593Smuzhiyun /* bits 0-7 are used for indicating driver type */
22*4882a593Smuzhiyun #define AZX_DCAPS_NO_TCSEL (1 << 8) /* No Intel TCSEL bit */
23*4882a593Smuzhiyun #define AZX_DCAPS_NO_MSI (1 << 9) /* No MSI support */
24*4882a593Smuzhiyun #define AZX_DCAPS_SNOOP_MASK (3 << 10) /* snoop type mask */
25*4882a593Smuzhiyun #define AZX_DCAPS_SNOOP_OFF (1 << 12) /* snoop default off */
26*4882a593Smuzhiyun #ifdef CONFIG_SND_HDA_I915
27*4882a593Smuzhiyun #define AZX_DCAPS_I915_COMPONENT (1 << 13) /* bind with i915 gfx */
28*4882a593Smuzhiyun #else
29*4882a593Smuzhiyun #define AZX_DCAPS_I915_COMPONENT 0 /* NOP */
30*4882a593Smuzhiyun #endif
31*4882a593Smuzhiyun /* 14 unused */
32*4882a593Smuzhiyun #define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */
33*4882a593Smuzhiyun #define AZX_DCAPS_POSFIX_LPIB (1 << 16) /* Use LPIB as default */
34*4882a593Smuzhiyun #define AZX_DCAPS_AMD_WORKAROUND (1 << 17) /* AMD-specific workaround */
35*4882a593Smuzhiyun #define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */
36*4882a593Smuzhiyun /* 19 unused */
37*4882a593Smuzhiyun #define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */
38*4882a593Smuzhiyun #define AZX_DCAPS_NO_ALIGN_BUFSIZE (1 << 21) /* no buffer size alignment */
39*4882a593Smuzhiyun /* 22 unused */
40*4882a593Smuzhiyun #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */
41*4882a593Smuzhiyun /* 24 unused */
42*4882a593Smuzhiyun #define AZX_DCAPS_COUNT_LPIB_DELAY (1 << 25) /* Take LPIB as delay */
43*4882a593Smuzhiyun #define AZX_DCAPS_PM_RUNTIME (1 << 26) /* runtime PM support */
44*4882a593Smuzhiyun #define AZX_DCAPS_RETRY_PROBE (1 << 27) /* retry probe if no codec is configured */
45*4882a593Smuzhiyun #define AZX_DCAPS_CORBRP_SELF_CLEAR (1 << 28) /* CORBRP clears itself after reset */
46*4882a593Smuzhiyun #define AZX_DCAPS_NO_MSI64 (1 << 29) /* Stick to 32-bit MSIs */
47*4882a593Smuzhiyun #define AZX_DCAPS_SEPARATE_STREAM_TAG (1 << 30) /* capture and playback use separate stream tag */
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun enum {
50*4882a593Smuzhiyun AZX_SNOOP_TYPE_NONE,
51*4882a593Smuzhiyun AZX_SNOOP_TYPE_SCH,
52*4882a593Smuzhiyun AZX_SNOOP_TYPE_ATI,
53*4882a593Smuzhiyun AZX_SNOOP_TYPE_NVIDIA,
54*4882a593Smuzhiyun };
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun struct azx_dev {
57*4882a593Smuzhiyun struct hdac_stream core;
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun unsigned int irq_pending:1;
60*4882a593Smuzhiyun /*
61*4882a593Smuzhiyun * For VIA:
62*4882a593Smuzhiyun * A flag to ensure DMA position is 0
63*4882a593Smuzhiyun * when link position is not greater than FIFO size
64*4882a593Smuzhiyun */
65*4882a593Smuzhiyun unsigned int insufficient:1;
66*4882a593Smuzhiyun };
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun #define azx_stream(dev) (&(dev)->core)
69*4882a593Smuzhiyun #define stream_to_azx_dev(s) container_of(s, struct azx_dev, core)
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun struct azx;
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun /* Functions to read/write to hda registers. */
74*4882a593Smuzhiyun struct hda_controller_ops {
75*4882a593Smuzhiyun /* Disable msi if supported, PCI only */
76*4882a593Smuzhiyun int (*disable_msi_reset_irq)(struct azx *);
77*4882a593Smuzhiyun void (*pcm_mmap_prepare)(struct snd_pcm_substream *substream,
78*4882a593Smuzhiyun struct vm_area_struct *area);
79*4882a593Smuzhiyun /* Check if current position is acceptable */
80*4882a593Smuzhiyun int (*position_check)(struct azx *chip, struct azx_dev *azx_dev);
81*4882a593Smuzhiyun /* enable/disable the link power */
82*4882a593Smuzhiyun int (*link_power)(struct azx *chip, bool enable);
83*4882a593Smuzhiyun };
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun struct azx_pcm {
86*4882a593Smuzhiyun struct azx *chip;
87*4882a593Smuzhiyun struct snd_pcm *pcm;
88*4882a593Smuzhiyun struct hda_codec *codec;
89*4882a593Smuzhiyun struct hda_pcm *info;
90*4882a593Smuzhiyun struct list_head list;
91*4882a593Smuzhiyun };
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun typedef unsigned int (*azx_get_pos_callback_t)(struct azx *, struct azx_dev *);
94*4882a593Smuzhiyun typedef int (*azx_get_delay_callback_t)(struct azx *, struct azx_dev *, unsigned int pos);
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun struct azx {
97*4882a593Smuzhiyun struct hda_bus bus;
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun struct snd_card *card;
100*4882a593Smuzhiyun struct pci_dev *pci;
101*4882a593Smuzhiyun int dev_index;
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun /* chip type specific */
104*4882a593Smuzhiyun int driver_type;
105*4882a593Smuzhiyun unsigned int driver_caps;
106*4882a593Smuzhiyun int playback_streams;
107*4882a593Smuzhiyun int playback_index_offset;
108*4882a593Smuzhiyun int capture_streams;
109*4882a593Smuzhiyun int capture_index_offset;
110*4882a593Smuzhiyun int num_streams;
111*4882a593Smuzhiyun int jackpoll_interval; /* jack poll interval in jiffies */
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun /* Register interaction. */
114*4882a593Smuzhiyun const struct hda_controller_ops *ops;
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun /* position adjustment callbacks */
117*4882a593Smuzhiyun azx_get_pos_callback_t get_position[2];
118*4882a593Smuzhiyun azx_get_delay_callback_t get_delay[2];
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun /* locks */
121*4882a593Smuzhiyun struct mutex open_mutex; /* Prevents concurrent open/close operations */
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun /* PCM */
124*4882a593Smuzhiyun struct list_head pcm_list; /* azx_pcm list */
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun /* HD codec */
127*4882a593Smuzhiyun int codec_probe_mask; /* copied from probe_mask option */
128*4882a593Smuzhiyun unsigned int beep_mode;
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun #ifdef CONFIG_SND_HDA_PATCH_LOADER
131*4882a593Smuzhiyun const struct firmware *fw;
132*4882a593Smuzhiyun #endif
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun /* flags */
135*4882a593Smuzhiyun int bdl_pos_adj;
136*4882a593Smuzhiyun unsigned int running:1;
137*4882a593Smuzhiyun unsigned int fallback_to_single_cmd:1;
138*4882a593Smuzhiyun unsigned int single_cmd:1;
139*4882a593Smuzhiyun unsigned int msi:1;
140*4882a593Smuzhiyun unsigned int probing:1; /* codec probing phase */
141*4882a593Smuzhiyun unsigned int snoop:1;
142*4882a593Smuzhiyun unsigned int uc_buffer:1; /* non-cached pages for stream buffers */
143*4882a593Smuzhiyun unsigned int align_buffer_size:1;
144*4882a593Smuzhiyun unsigned int region_requested:1;
145*4882a593Smuzhiyun unsigned int disabled:1; /* disabled by vga_switcheroo */
146*4882a593Smuzhiyun unsigned int pm_prepared:1;
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun /* GTS present */
149*4882a593Smuzhiyun unsigned int gts_present:1;
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun #ifdef CONFIG_SND_HDA_DSP_LOADER
152*4882a593Smuzhiyun struct azx_dev saved_azx_dev;
153*4882a593Smuzhiyun #endif
154*4882a593Smuzhiyun };
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun #define azx_bus(chip) (&(chip)->bus.core)
157*4882a593Smuzhiyun #define bus_to_azx(_bus) container_of(_bus, struct azx, bus.core)
158*4882a593Smuzhiyun
azx_snoop(struct azx * chip)159*4882a593Smuzhiyun static inline bool azx_snoop(struct azx *chip)
160*4882a593Smuzhiyun {
161*4882a593Smuzhiyun return !IS_ENABLED(CONFIG_X86) || chip->snoop;
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun /*
165*4882a593Smuzhiyun * macros for easy use
166*4882a593Smuzhiyun */
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun #define azx_writel(chip, reg, value) \
169*4882a593Smuzhiyun snd_hdac_chip_writel(azx_bus(chip), reg, value)
170*4882a593Smuzhiyun #define azx_readl(chip, reg) \
171*4882a593Smuzhiyun snd_hdac_chip_readl(azx_bus(chip), reg)
172*4882a593Smuzhiyun #define azx_writew(chip, reg, value) \
173*4882a593Smuzhiyun snd_hdac_chip_writew(azx_bus(chip), reg, value)
174*4882a593Smuzhiyun #define azx_readw(chip, reg) \
175*4882a593Smuzhiyun snd_hdac_chip_readw(azx_bus(chip), reg)
176*4882a593Smuzhiyun #define azx_writeb(chip, reg, value) \
177*4882a593Smuzhiyun snd_hdac_chip_writeb(azx_bus(chip), reg, value)
178*4882a593Smuzhiyun #define azx_readb(chip, reg) \
179*4882a593Smuzhiyun snd_hdac_chip_readb(azx_bus(chip), reg)
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun #define azx_has_pm_runtime(chip) \
182*4882a593Smuzhiyun ((chip)->driver_caps & AZX_DCAPS_PM_RUNTIME)
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun /* PCM setup */
get_azx_dev(struct snd_pcm_substream * substream)185*4882a593Smuzhiyun static inline struct azx_dev *get_azx_dev(struct snd_pcm_substream *substream)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun return substream->runtime->private_data;
188*4882a593Smuzhiyun }
189*4882a593Smuzhiyun unsigned int azx_get_position(struct azx *chip, struct azx_dev *azx_dev);
190*4882a593Smuzhiyun unsigned int azx_get_pos_lpib(struct azx *chip, struct azx_dev *azx_dev);
191*4882a593Smuzhiyun unsigned int azx_get_pos_posbuf(struct azx *chip, struct azx_dev *azx_dev);
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun /* Stream control. */
194*4882a593Smuzhiyun void azx_stop_all_streams(struct azx *chip);
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun /* Allocation functions. */
197*4882a593Smuzhiyun #define azx_alloc_stream_pages(chip) \
198*4882a593Smuzhiyun snd_hdac_bus_alloc_stream_pages(azx_bus(chip))
199*4882a593Smuzhiyun #define azx_free_stream_pages(chip) \
200*4882a593Smuzhiyun snd_hdac_bus_free_stream_pages(azx_bus(chip))
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun /* Low level azx interface */
203*4882a593Smuzhiyun void azx_init_chip(struct azx *chip, bool full_reset);
204*4882a593Smuzhiyun void azx_stop_chip(struct azx *chip);
205*4882a593Smuzhiyun #define azx_enter_link_reset(chip) \
206*4882a593Smuzhiyun snd_hdac_bus_enter_link_reset(azx_bus(chip))
207*4882a593Smuzhiyun irqreturn_t azx_interrupt(int irq, void *dev_id);
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun /* Codec interface */
210*4882a593Smuzhiyun int azx_bus_init(struct azx *chip, const char *model);
211*4882a593Smuzhiyun int azx_probe_codecs(struct azx *chip, unsigned int max_slots);
212*4882a593Smuzhiyun int azx_codec_configure(struct azx *chip);
213*4882a593Smuzhiyun int azx_init_streams(struct azx *chip);
214*4882a593Smuzhiyun void azx_free_streams(struct azx *chip);
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun #endif /* __SOUND_HDA_CONTROLLER_H */
217