xref: /openbmc/linux/include/sound/hda_codec.h (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
11a59d1b8SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
2be57bfffSPierre-Louis Bossart /*
3be57bfffSPierre-Louis Bossart  * Universal Interface for Intel High Definition Audio Codec
4be57bfffSPierre-Louis Bossart  *
5be57bfffSPierre-Louis Bossart  * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
6be57bfffSPierre-Louis Bossart  */
7be57bfffSPierre-Louis Bossart 
8be57bfffSPierre-Louis Bossart #ifndef __SOUND_HDA_CODEC_H
9be57bfffSPierre-Louis Bossart #define __SOUND_HDA_CODEC_H
10be57bfffSPierre-Louis Bossart 
117206998fSTakashi Iwai #include <linux/refcount.h>
12be57bfffSPierre-Louis Bossart #include <linux/mod_devicetable.h>
13be57bfffSPierre-Louis Bossart #include <sound/info.h>
14be57bfffSPierre-Louis Bossart #include <sound/control.h>
15be57bfffSPierre-Louis Bossart #include <sound/pcm.h>
16be57bfffSPierre-Louis Bossart #include <sound/hwdep.h>
17be57bfffSPierre-Louis Bossart #include <sound/hdaudio.h>
18be57bfffSPierre-Louis Bossart #include <sound/hda_verbs.h>
19be57bfffSPierre-Louis Bossart #include <sound/hda_regmap.h>
20be57bfffSPierre-Louis Bossart 
21be57bfffSPierre-Louis Bossart /*
22be57bfffSPierre-Louis Bossart  * Structures
23be57bfffSPierre-Louis Bossart  */
24be57bfffSPierre-Louis Bossart 
25be57bfffSPierre-Louis Bossart struct hda_bus;
26be57bfffSPierre-Louis Bossart struct hda_beep;
27be57bfffSPierre-Louis Bossart struct hda_codec;
28be57bfffSPierre-Louis Bossart struct hda_pcm;
29be57bfffSPierre-Louis Bossart struct hda_pcm_stream;
30be57bfffSPierre-Louis Bossart 
31be57bfffSPierre-Louis Bossart /*
32be57bfffSPierre-Louis Bossart  * codec bus
33be57bfffSPierre-Louis Bossart  *
34be57bfffSPierre-Louis Bossart  * each controller needs to creata a hda_bus to assign the accessor.
35be57bfffSPierre-Louis Bossart  * A hda_bus contains several codecs in the list codec_list.
36be57bfffSPierre-Louis Bossart  */
37be57bfffSPierre-Louis Bossart struct hda_bus {
38be57bfffSPierre-Louis Bossart 	struct hdac_bus core;
39be57bfffSPierre-Louis Bossart 
40be57bfffSPierre-Louis Bossart 	struct snd_card *card;
41be57bfffSPierre-Louis Bossart 
42be57bfffSPierre-Louis Bossart 	struct pci_dev *pci;
43be57bfffSPierre-Louis Bossart 	const char *modelname;
44be57bfffSPierre-Louis Bossart 
45be57bfffSPierre-Louis Bossart 	struct mutex prepare_mutex;
46be57bfffSPierre-Louis Bossart 
47be57bfffSPierre-Louis Bossart 	/* assigned PCMs */
48be57bfffSPierre-Louis Bossart 	DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES);
49be57bfffSPierre-Louis Bossart 
50be57bfffSPierre-Louis Bossart 	/* misc op flags */
51be57bfffSPierre-Louis Bossart 	unsigned int allow_bus_reset:1;	/* allow bus reset at fatal error */
52be57bfffSPierre-Louis Bossart 	/* status for codec/controller */
53be57bfffSPierre-Louis Bossart 	unsigned int shutdown :1;	/* being unloaded */
54be57bfffSPierre-Louis Bossart 	unsigned int response_reset:1;	/* controller was reset */
55be57bfffSPierre-Louis Bossart 	unsigned int in_reset:1;	/* during reset operation */
56be57bfffSPierre-Louis Bossart 	unsigned int no_response_fallback:1; /* don't fallback at RIRB error */
57305a0adeSTakashi Iwai 	unsigned int bus_probing :1;	/* during probing process */
58dd23e1d5STakashi Iwai 	unsigned int keep_power:1;	/* keep power up for notification */
59b33115bdSMohan Kumar 	unsigned int jackpoll_in_suspend:1; /* keep jack polling during
60b33115bdSMohan Kumar 					     * runtime suspend
61b33115bdSMohan Kumar 					     */
62be57bfffSPierre-Louis Bossart 
63be57bfffSPierre-Louis Bossart 	int primary_dig_out_type;	/* primary digital out PCM type */
64be57bfffSPierre-Louis Bossart 	unsigned int mixer_assigned;	/* codec addr for mixer name */
65be57bfffSPierre-Louis Bossart };
66be57bfffSPierre-Louis Bossart 
67be57bfffSPierre-Louis Bossart /* from hdac_bus to hda_bus */
68be57bfffSPierre-Louis Bossart #define to_hda_bus(bus)		container_of(bus, struct hda_bus, core)
69be57bfffSPierre-Louis Bossart 
70be57bfffSPierre-Louis Bossart /*
71be57bfffSPierre-Louis Bossart  * codec preset
72be57bfffSPierre-Louis Bossart  *
73be57bfffSPierre-Louis Bossart  * Known codecs have the patch to build and set up the controls/PCMs
74be57bfffSPierre-Louis Bossart  * better than the generic parser.
75be57bfffSPierre-Louis Bossart  */
76be57bfffSPierre-Louis Bossart typedef int (*hda_codec_patch_t)(struct hda_codec *);
77be57bfffSPierre-Louis Bossart 
78be57bfffSPierre-Louis Bossart #define HDA_CODEC_ID_SKIP_PROBE		0x00000001
79be57bfffSPierre-Louis Bossart #define HDA_CODEC_ID_GENERIC_HDMI	0x00000101
80be57bfffSPierre-Louis Bossart #define HDA_CODEC_ID_GENERIC		0x00000201
81be57bfffSPierre-Louis Bossart 
82be57bfffSPierre-Louis Bossart #define HDA_CODEC_REV_ENTRY(_vid, _rev, _name, _patch) \
83be57bfffSPierre-Louis Bossart 	{ .vendor_id = (_vid), .rev_id = (_rev), .name = (_name), \
84be57bfffSPierre-Louis Bossart 	  .api_version = HDA_DEV_LEGACY, \
85be57bfffSPierre-Louis Bossart 	  .driver_data = (unsigned long)(_patch) }
86be57bfffSPierre-Louis Bossart #define HDA_CODEC_ENTRY(_vid, _name, _patch) \
87be57bfffSPierre-Louis Bossart 	HDA_CODEC_REV_ENTRY(_vid, 0, _name, _patch)
88be57bfffSPierre-Louis Bossart 
89be57bfffSPierre-Louis Bossart struct hda_codec_driver {
90be57bfffSPierre-Louis Bossart 	struct hdac_driver core;
91be57bfffSPierre-Louis Bossart 	const struct hda_device_id *id;
92be57bfffSPierre-Louis Bossart };
93be57bfffSPierre-Louis Bossart 
94be57bfffSPierre-Louis Bossart int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name,
95be57bfffSPierre-Louis Bossart 			       struct module *owner);
96be57bfffSPierre-Louis Bossart #define hda_codec_driver_register(drv) \
97be57bfffSPierre-Louis Bossart 	__hda_codec_driver_register(drv, KBUILD_MODNAME, THIS_MODULE)
98be57bfffSPierre-Louis Bossart void hda_codec_driver_unregister(struct hda_codec_driver *drv);
99be57bfffSPierre-Louis Bossart #define module_hda_codec_driver(drv) \
100be57bfffSPierre-Louis Bossart 	module_driver(drv, hda_codec_driver_register, \
101be57bfffSPierre-Louis Bossart 		      hda_codec_driver_unregister)
102be57bfffSPierre-Louis Bossart 
103be57bfffSPierre-Louis Bossart /* ops set by the preset patch */
104be57bfffSPierre-Louis Bossart struct hda_codec_ops {
105be57bfffSPierre-Louis Bossart 	int (*build_controls)(struct hda_codec *codec);
106be57bfffSPierre-Louis Bossart 	int (*build_pcms)(struct hda_codec *codec);
107be57bfffSPierre-Louis Bossart 	int (*init)(struct hda_codec *codec);
108be57bfffSPierre-Louis Bossart 	void (*free)(struct hda_codec *codec);
109be57bfffSPierre-Louis Bossart 	void (*unsol_event)(struct hda_codec *codec, unsigned int res);
110be57bfffSPierre-Louis Bossart 	void (*set_power_state)(struct hda_codec *codec, hda_nid_t fg,
111be57bfffSPierre-Louis Bossart 				unsigned int power_state);
112be57bfffSPierre-Louis Bossart #ifdef CONFIG_PM
113be57bfffSPierre-Louis Bossart 	int (*suspend)(struct hda_codec *codec);
114be57bfffSPierre-Louis Bossart 	int (*resume)(struct hda_codec *codec);
115be57bfffSPierre-Louis Bossart 	int (*check_power_status)(struct hda_codec *codec, hda_nid_t nid);
116be57bfffSPierre-Louis Bossart #endif
117be57bfffSPierre-Louis Bossart 	void (*stream_pm)(struct hda_codec *codec, hda_nid_t nid, bool on);
118be57bfffSPierre-Louis Bossart };
119be57bfffSPierre-Louis Bossart 
120be57bfffSPierre-Louis Bossart /* PCM callbacks */
121be57bfffSPierre-Louis Bossart struct hda_pcm_ops {
122be57bfffSPierre-Louis Bossart 	int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec,
123be57bfffSPierre-Louis Bossart 		    struct snd_pcm_substream *substream);
124be57bfffSPierre-Louis Bossart 	int (*close)(struct hda_pcm_stream *info, struct hda_codec *codec,
125be57bfffSPierre-Louis Bossart 		     struct snd_pcm_substream *substream);
126be57bfffSPierre-Louis Bossart 	int (*prepare)(struct hda_pcm_stream *info, struct hda_codec *codec,
127be57bfffSPierre-Louis Bossart 		       unsigned int stream_tag, unsigned int format,
128be57bfffSPierre-Louis Bossart 		       struct snd_pcm_substream *substream);
129be57bfffSPierre-Louis Bossart 	int (*cleanup)(struct hda_pcm_stream *info, struct hda_codec *codec,
130be57bfffSPierre-Louis Bossart 		       struct snd_pcm_substream *substream);
131be57bfffSPierre-Louis Bossart 	unsigned int (*get_delay)(struct hda_pcm_stream *info,
132be57bfffSPierre-Louis Bossart 				  struct hda_codec *codec,
133be57bfffSPierre-Louis Bossart 				  struct snd_pcm_substream *substream);
134be57bfffSPierre-Louis Bossart };
135be57bfffSPierre-Louis Bossart 
136be57bfffSPierre-Louis Bossart /* PCM information for each substream */
137be57bfffSPierre-Louis Bossart struct hda_pcm_stream {
138be57bfffSPierre-Louis Bossart 	unsigned int substreams;	/* number of substreams, 0 = not exist*/
139be57bfffSPierre-Louis Bossart 	unsigned int channels_min;	/* min. number of channels */
140be57bfffSPierre-Louis Bossart 	unsigned int channels_max;	/* max. number of channels */
141be57bfffSPierre-Louis Bossart 	hda_nid_t nid;	/* default NID to query rates/formats/bps, or set up */
142be57bfffSPierre-Louis Bossart 	u32 rates;	/* supported rates */
143be57bfffSPierre-Louis Bossart 	u64 formats;	/* supported formats (SNDRV_PCM_FMTBIT_) */
144be57bfffSPierre-Louis Bossart 	unsigned int maxbps;	/* supported max. bit per sample */
145be57bfffSPierre-Louis Bossart 	const struct snd_pcm_chmap_elem *chmap; /* chmap to override */
146be57bfffSPierre-Louis Bossart 	struct hda_pcm_ops ops;
147be57bfffSPierre-Louis Bossart };
148be57bfffSPierre-Louis Bossart 
149be57bfffSPierre-Louis Bossart /* PCM types */
150be57bfffSPierre-Louis Bossart enum {
151be57bfffSPierre-Louis Bossart 	HDA_PCM_TYPE_AUDIO,
152be57bfffSPierre-Louis Bossart 	HDA_PCM_TYPE_SPDIF,
153be57bfffSPierre-Louis Bossart 	HDA_PCM_TYPE_HDMI,
154be57bfffSPierre-Louis Bossart 	HDA_PCM_TYPE_MODEM,
155be57bfffSPierre-Louis Bossart 	HDA_PCM_NTYPES
156be57bfffSPierre-Louis Bossart };
157be57bfffSPierre-Louis Bossart 
158be57bfffSPierre-Louis Bossart #define SNDRV_PCM_INVALID_DEVICE	(-1)
159be57bfffSPierre-Louis Bossart /* for PCM creation */
160be57bfffSPierre-Louis Bossart struct hda_pcm {
161be57bfffSPierre-Louis Bossart 	char *name;
162be57bfffSPierre-Louis Bossart 	struct hda_pcm_stream stream[2];
163be57bfffSPierre-Louis Bossart 	unsigned int pcm_type;	/* HDA_PCM_TYPE_XXX */
164be57bfffSPierre-Louis Bossart 	int device;		/* device number to assign */
165be57bfffSPierre-Louis Bossart 	struct snd_pcm *pcm;	/* assigned PCM instance */
166be57bfffSPierre-Louis Bossart 	bool own_chmap;		/* codec driver provides own channel maps */
167be57bfffSPierre-Louis Bossart 	/* private: */
168be57bfffSPierre-Louis Bossart 	struct hda_codec *codec;
169be57bfffSPierre-Louis Bossart 	struct list_head list;
1707206998fSTakashi Iwai 	unsigned int disconnected:1;
171be57bfffSPierre-Louis Bossart };
172be57bfffSPierre-Louis Bossart 
173be57bfffSPierre-Louis Bossart /* codec information */
174be57bfffSPierre-Louis Bossart struct hda_codec {
175be57bfffSPierre-Louis Bossart 	struct hdac_device core;
176be57bfffSPierre-Louis Bossart 	struct hda_bus *bus;
177be57bfffSPierre-Louis Bossart 	struct snd_card *card;
178be57bfffSPierre-Louis Bossart 	unsigned int addr;	/* codec addr*/
179be57bfffSPierre-Louis Bossart 	u32 probe_id; /* overridden id for probing */
180be57bfffSPierre-Louis Bossart 
181be57bfffSPierre-Louis Bossart 	/* detected preset */
182be57bfffSPierre-Louis Bossart 	const struct hda_device_id *preset;
183be57bfffSPierre-Louis Bossart 	const char *modelname;	/* model name for preset */
184be57bfffSPierre-Louis Bossart 
185be57bfffSPierre-Louis Bossart 	/* set by patch */
186be57bfffSPierre-Louis Bossart 	struct hda_codec_ops patch_ops;
187be57bfffSPierre-Louis Bossart 
188be57bfffSPierre-Louis Bossart 	/* PCM to create, set by patch_ops.build_pcms callback */
189be57bfffSPierre-Louis Bossart 	struct list_head pcm_list_head;
1907206998fSTakashi Iwai 	refcount_t pcm_ref;
1917206998fSTakashi Iwai 	wait_queue_head_t remove_sleep;
192be57bfffSPierre-Louis Bossart 
193be57bfffSPierre-Louis Bossart 	/* codec specific info */
194be57bfffSPierre-Louis Bossart 	void *spec;
195be57bfffSPierre-Louis Bossart 
196be57bfffSPierre-Louis Bossart 	/* beep device */
197be57bfffSPierre-Louis Bossart 	struct hda_beep *beep;
198be57bfffSPierre-Louis Bossart 	unsigned int beep_mode;
199be57bfffSPierre-Louis Bossart 
200be57bfffSPierre-Louis Bossart 	/* widget capabilities cache */
201be57bfffSPierre-Louis Bossart 	u32 *wcaps;
202be57bfffSPierre-Louis Bossart 
203be57bfffSPierre-Louis Bossart 	struct snd_array mixers;	/* list of assigned mixer elements */
204be57bfffSPierre-Louis Bossart 	struct snd_array nids;		/* list of mapped mixer elements */
205be57bfffSPierre-Louis Bossart 
206be57bfffSPierre-Louis Bossart 	struct list_head conn_list;	/* linked-list of connection-list */
207be57bfffSPierre-Louis Bossart 
208be57bfffSPierre-Louis Bossart 	struct mutex spdif_mutex;
209be57bfffSPierre-Louis Bossart 	struct mutex control_mutex;
210be57bfffSPierre-Louis Bossart 	struct snd_array spdif_out;
211be57bfffSPierre-Louis Bossart 	unsigned int spdif_in_enable;	/* SPDIF input enable? */
2129ab0cb30STakashi Iwai 	const hda_nid_t *follower_dig_outs; /* optional digital out follower widgets */
213be57bfffSPierre-Louis Bossart 	struct snd_array init_pins;	/* initial (BIOS) pin configurations */
214be57bfffSPierre-Louis Bossart 	struct snd_array driver_pins;	/* pin configs set by codec parser */
215be57bfffSPierre-Louis Bossart 	struct snd_array cvt_setups;	/* audio convert setups */
216be57bfffSPierre-Louis Bossart 
217be57bfffSPierre-Louis Bossart 	struct mutex user_mutex;
218be57bfffSPierre-Louis Bossart #ifdef CONFIG_SND_HDA_RECONFIG
219be57bfffSPierre-Louis Bossart 	struct snd_array init_verbs;	/* additional init verbs */
220be57bfffSPierre-Louis Bossart 	struct snd_array hints;		/* additional hints */
221be57bfffSPierre-Louis Bossart 	struct snd_array user_pins;	/* default pin configs to override */
222be57bfffSPierre-Louis Bossart #endif
223be57bfffSPierre-Louis Bossart 
224be57bfffSPierre-Louis Bossart #ifdef CONFIG_SND_HDA_HWDEP
225be57bfffSPierre-Louis Bossart 	struct snd_hwdep *hwdep;	/* assigned hwdep device */
226be57bfffSPierre-Louis Bossart #endif
227be57bfffSPierre-Louis Bossart 
228be57bfffSPierre-Louis Bossart 	/* misc flags */
229c0f1886dSTakashi Iwai 	unsigned int configured:1; /* codec was configured */
230be57bfffSPierre-Louis Bossart 	unsigned int in_freeing:1; /* being released */
231029d92c2STakashi Iwai 	unsigned int display_power_control:1; /* needs display power */
232be57bfffSPierre-Louis Bossart 	unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each
233be57bfffSPierre-Louis Bossart 					     * status change
234be57bfffSPierre-Louis Bossart 					     * (e.g. Realtek codecs)
235be57bfffSPierre-Louis Bossart 					     */
236be57bfffSPierre-Louis Bossart 	unsigned int pin_amp_workaround:1; /* pin out-amp takes index
237be57bfffSPierre-Louis Bossart 					    * (e.g. Conexant codecs)
238be57bfffSPierre-Louis Bossart 					    */
239be57bfffSPierre-Louis Bossart 	unsigned int single_adc_amp:1; /* adc in-amp takes no index
240be57bfffSPierre-Louis Bossart 					* (e.g. CX20549 codec)
241be57bfffSPierre-Louis Bossart 					*/
242be57bfffSPierre-Louis Bossart 	unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */
243be57bfffSPierre-Louis Bossart 	unsigned int pins_shutup:1;	/* pins are shut up */
244be57bfffSPierre-Louis Bossart 	unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */
245be57bfffSPierre-Louis Bossart 	unsigned int no_jack_detect:1;	/* Machine has no jack-detection */
246be57bfffSPierre-Louis Bossart 	unsigned int inv_eapd:1; /* broken h/w: inverted EAPD control */
247be57bfffSPierre-Louis Bossart 	unsigned int inv_jack_detect:1;	/* broken h/w: inverted detection bit */
248be57bfffSPierre-Louis Bossart 	unsigned int pcm_format_first:1; /* PCM format must be set first */
249be57bfffSPierre-Louis Bossart 	unsigned int cached_write:1;	/* write only to caches */
250be57bfffSPierre-Louis Bossart 	unsigned int dp_mst:1; /* support DP1.2 Multi-stream transport */
251be57bfffSPierre-Louis Bossart 	unsigned int dump_coef:1; /* dump processing coefs in codec proc file */
252be57bfffSPierre-Louis Bossart 	unsigned int power_save_node:1; /* advanced PM for each widget */
253be57bfffSPierre-Louis Bossart 	unsigned int auto_runtime_pm:1; /* enable automatic codec runtime pm */
254be57bfffSPierre-Louis Bossart 	unsigned int force_pin_prefix:1; /* Add location prefix */
255be57bfffSPierre-Louis Bossart 	unsigned int link_down_at_suspend:1; /* link down at runtime suspend */
2564914da2fSTakashi Iwai 	unsigned int relaxed_resume:1;	/* don't resume forcibly for jack */
257a6e7d0a4SKai Vehmanen 	unsigned int forced_resume:1; /* forced resume for jack */
258ee0b089dSKai Vehmanen 	unsigned int no_stream_clean_at_suspend:1; /* do not clean streams at suspend */
259*d045bcefSJaroslav Kysela 	unsigned int ctl_dev_id:1; /* old control element id build behaviour */
2604914da2fSTakashi Iwai 
261be57bfffSPierre-Louis Bossart #ifdef CONFIG_PM
262be57bfffSPierre-Louis Bossart 	unsigned long power_on_acct;
263be57bfffSPierre-Louis Bossart 	unsigned long power_off_acct;
264be57bfffSPierre-Louis Bossart 	unsigned long power_jiffies;
265be57bfffSPierre-Louis Bossart #endif
266be57bfffSPierre-Louis Bossart 
267be57bfffSPierre-Louis Bossart 	/* filter the requested power state per nid */
268be57bfffSPierre-Louis Bossart 	unsigned int (*power_filter)(struct hda_codec *codec, hda_nid_t nid,
269be57bfffSPierre-Louis Bossart 				     unsigned int power_state);
270be57bfffSPierre-Louis Bossart 
271be57bfffSPierre-Louis Bossart 	/* codec-specific additional proc output */
272be57bfffSPierre-Louis Bossart 	void (*proc_widget_hook)(struct snd_info_buffer *buffer,
273be57bfffSPierre-Louis Bossart 				 struct hda_codec *codec, hda_nid_t nid);
274be57bfffSPierre-Louis Bossart 
275be57bfffSPierre-Louis Bossart 	/* jack detection */
276be57bfffSPierre-Louis Bossart 	struct snd_array jacktbl;
277be57bfffSPierre-Louis Bossart 	unsigned long jackpoll_interval; /* In jiffies. Zero means no poll, rely on unsol events */
278be57bfffSPierre-Louis Bossart 	struct delayed_work jackpoll_work;
279be57bfffSPierre-Louis Bossart 
280be57bfffSPierre-Louis Bossart 	int depop_delay; /* depop delay in ms, -1 for default delay time */
281be57bfffSPierre-Louis Bossart 
282be57bfffSPierre-Louis Bossart 	/* fix-up list */
283be57bfffSPierre-Louis Bossart 	int fixup_id;
284be57bfffSPierre-Louis Bossart 	const struct hda_fixup *fixup_list;
285be57bfffSPierre-Louis Bossart 	const char *fixup_name;
286be57bfffSPierre-Louis Bossart 
287be57bfffSPierre-Louis Bossart 	/* additional init verbs */
288be57bfffSPierre-Louis Bossart 	struct snd_array verbs;
289be57bfffSPierre-Louis Bossart };
290be57bfffSPierre-Louis Bossart 
291be57bfffSPierre-Louis Bossart #define dev_to_hda_codec(_dev)	container_of(_dev, struct hda_codec, core.dev)
292be57bfffSPierre-Louis Bossart #define hda_codec_dev(_dev)	(&(_dev)->core.dev)
293be57bfffSPierre-Louis Bossart 
2948c11827bSKai-Heng Feng #define hdac_to_hda_codec(_hdac) container_of(_hdac, struct hda_codec, core)
2958c11827bSKai-Heng Feng 
296be57bfffSPierre-Louis Bossart #define list_for_each_codec(c, bus) \
297be57bfffSPierre-Louis Bossart 	list_for_each_entry(c, &(bus)->core.codec_list, core.list)
298be57bfffSPierre-Louis Bossart #define list_for_each_codec_safe(c, n, bus)				\
299be57bfffSPierre-Louis Bossart 	list_for_each_entry_safe(c, n, &(bus)->core.codec_list, core.list)
300be57bfffSPierre-Louis Bossart 
301be57bfffSPierre-Louis Bossart /* snd_hda_codec_read/write optional flags */
302be57bfffSPierre-Louis Bossart #define HDA_RW_NO_RESPONSE_FALLBACK	(1 << 0)
303be57bfffSPierre-Louis Bossart 
304be57bfffSPierre-Louis Bossart /*
305be57bfffSPierre-Louis Bossart  * constructors
306be57bfffSPierre-Louis Bossart  */
307595511a3SCezary Rojewski __printf(3, 4) struct hda_codec *
308595511a3SCezary Rojewski snd_hda_codec_device_init(struct hda_bus *bus, unsigned int codec_addr,
309595511a3SCezary Rojewski 			  const char *fmt, ...);
310be57bfffSPierre-Louis Bossart int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
311be57bfffSPierre-Louis Bossart 		      unsigned int codec_addr, struct hda_codec **codecp);
312be57bfffSPierre-Louis Bossart int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card,
31317e0c4cbSCezary Rojewski 		      unsigned int codec_addr, struct hda_codec *codec,
31417e0c4cbSCezary Rojewski 		      bool snddev_managed);
315be57bfffSPierre-Louis Bossart int snd_hda_codec_configure(struct hda_codec *codec);
316be57bfffSPierre-Louis Bossart int snd_hda_codec_update_widgets(struct hda_codec *codec);
31717e0c4cbSCezary Rojewski void snd_hda_codec_register(struct hda_codec *codec);
31817e0c4cbSCezary Rojewski void snd_hda_codec_unregister(struct hda_codec *codec);
319bb682f7aSCezary Rojewski void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec);
320be57bfffSPierre-Louis Bossart 
321be57bfffSPierre-Louis Bossart /*
322be57bfffSPierre-Louis Bossart  * low level functions
323be57bfffSPierre-Louis Bossart  */
324be57bfffSPierre-Louis Bossart static inline unsigned int
snd_hda_codec_read(struct hda_codec * codec,hda_nid_t nid,int flags,unsigned int verb,unsigned int parm)325be57bfffSPierre-Louis Bossart snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
326be57bfffSPierre-Louis Bossart 				int flags,
327be57bfffSPierre-Louis Bossart 				unsigned int verb, unsigned int parm)
328be57bfffSPierre-Louis Bossart {
329be57bfffSPierre-Louis Bossart 	return snd_hdac_codec_read(&codec->core, nid, flags, verb, parm);
330be57bfffSPierre-Louis Bossart }
331be57bfffSPierre-Louis Bossart 
332be57bfffSPierre-Louis Bossart static inline int
snd_hda_codec_write(struct hda_codec * codec,hda_nid_t nid,int flags,unsigned int verb,unsigned int parm)333be57bfffSPierre-Louis Bossart snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int flags,
334be57bfffSPierre-Louis Bossart 			unsigned int verb, unsigned int parm)
335be57bfffSPierre-Louis Bossart {
336be57bfffSPierre-Louis Bossart 	return snd_hdac_codec_write(&codec->core, nid, flags, verb, parm);
337be57bfffSPierre-Louis Bossart }
338be57bfffSPierre-Louis Bossart 
339be57bfffSPierre-Louis Bossart #define snd_hda_param_read(codec, nid, param) \
340be57bfffSPierre-Louis Bossart 	snd_hdac_read_parm(&(codec)->core, nid, param)
341be57bfffSPierre-Louis Bossart #define snd_hda_get_sub_nodes(codec, nid, start_nid) \
342be57bfffSPierre-Louis Bossart 	snd_hdac_get_sub_nodes(&(codec)->core, nid, start_nid)
343be57bfffSPierre-Louis Bossart int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
344be57bfffSPierre-Louis Bossart 			    hda_nid_t *conn_list, int max_conns);
345be57bfffSPierre-Louis Bossart static inline int
snd_hda_get_num_conns(struct hda_codec * codec,hda_nid_t nid)346be57bfffSPierre-Louis Bossart snd_hda_get_num_conns(struct hda_codec *codec, hda_nid_t nid)
347be57bfffSPierre-Louis Bossart {
348be57bfffSPierre-Louis Bossart 	return snd_hda_get_connections(codec, nid, NULL, 0);
349be57bfffSPierre-Louis Bossart }
350be57bfffSPierre-Louis Bossart 
351be57bfffSPierre-Louis Bossart #define snd_hda_get_raw_connections(codec, nid, list, max_conns) \
352be57bfffSPierre-Louis Bossart 	snd_hdac_get_connections(&(codec)->core, nid, list, max_conns)
353be57bfffSPierre-Louis Bossart #define snd_hda_get_num_raw_conns(codec, nid) \
3540183a855STom Rix 	snd_hdac_get_connections(&(codec)->core, nid, NULL, 0)
355be57bfffSPierre-Louis Bossart 
356be57bfffSPierre-Louis Bossart int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid,
357be57bfffSPierre-Louis Bossart 			  const hda_nid_t **listp);
358be57bfffSPierre-Louis Bossart int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int nums,
359be57bfffSPierre-Louis Bossart 			  const hda_nid_t *list);
360be57bfffSPierre-Louis Bossart int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
361be57bfffSPierre-Louis Bossart 			   hda_nid_t nid, int recursive);
362be57bfffSPierre-Louis Bossart unsigned int snd_hda_get_num_devices(struct hda_codec *codec, hda_nid_t nid);
363be57bfffSPierre-Louis Bossart int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
364be57bfffSPierre-Louis Bossart 			u8 *dev_list, int max_devices);
365be57bfffSPierre-Louis Bossart int snd_hda_get_dev_select(struct hda_codec *codec, hda_nid_t nid);
366be57bfffSPierre-Louis Bossart int snd_hda_set_dev_select(struct hda_codec *codec, hda_nid_t nid, int dev_id);
367be57bfffSPierre-Louis Bossart 
368be57bfffSPierre-Louis Bossart struct hda_verb {
369be57bfffSPierre-Louis Bossart 	hda_nid_t nid;
370be57bfffSPierre-Louis Bossart 	u32 verb;
371be57bfffSPierre-Louis Bossart 	u32 param;
372be57bfffSPierre-Louis Bossart };
373be57bfffSPierre-Louis Bossart 
374be57bfffSPierre-Louis Bossart void snd_hda_sequence_write(struct hda_codec *codec,
375be57bfffSPierre-Louis Bossart 			    const struct hda_verb *seq);
376be57bfffSPierre-Louis Bossart 
377be57bfffSPierre-Louis Bossart /* cached write */
378be57bfffSPierre-Louis Bossart static inline int
snd_hda_codec_write_cache(struct hda_codec * codec,hda_nid_t nid,int flags,unsigned int verb,unsigned int parm)379be57bfffSPierre-Louis Bossart snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
380be57bfffSPierre-Louis Bossart 			  int flags, unsigned int verb, unsigned int parm)
381be57bfffSPierre-Louis Bossart {
382be57bfffSPierre-Louis Bossart 	return snd_hdac_regmap_write(&codec->core, nid, verb, parm);
383be57bfffSPierre-Louis Bossart }
384be57bfffSPierre-Louis Bossart 
385be57bfffSPierre-Louis Bossart /* the struct for codec->pin_configs */
386be57bfffSPierre-Louis Bossart struct hda_pincfg {
387be57bfffSPierre-Louis Bossart 	hda_nid_t nid;
388be57bfffSPierre-Louis Bossart 	unsigned char ctrl;	/* original pin control value */
389be57bfffSPierre-Louis Bossart 	unsigned char target;	/* target pin control value */
390be57bfffSPierre-Louis Bossart 	unsigned int cfg;	/* default configuration */
391be57bfffSPierre-Louis Bossart };
392be57bfffSPierre-Louis Bossart 
393be57bfffSPierre-Louis Bossart unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid);
394be57bfffSPierre-Louis Bossart int snd_hda_codec_set_pincfg(struct hda_codec *codec, hda_nid_t nid,
395be57bfffSPierre-Louis Bossart 			     unsigned int cfg);
396be57bfffSPierre-Louis Bossart int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
397be57bfffSPierre-Louis Bossart 		       hda_nid_t nid, unsigned int cfg); /* for hwdep */
398be57bfffSPierre-Louis Bossart void snd_hda_shutup_pins(struct hda_codec *codec);
399be57bfffSPierre-Louis Bossart 
400be57bfffSPierre-Louis Bossart /* SPDIF controls */
401be57bfffSPierre-Louis Bossart struct hda_spdif_out {
402be57bfffSPierre-Louis Bossart 	hda_nid_t nid;		/* Converter nid values relate to */
403be57bfffSPierre-Louis Bossart 	unsigned int status;	/* IEC958 status bits */
404be57bfffSPierre-Louis Bossart 	unsigned short ctls;	/* SPDIF control bits */
405be57bfffSPierre-Louis Bossart };
406be57bfffSPierre-Louis Bossart struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec,
407be57bfffSPierre-Louis Bossart 					       hda_nid_t nid);
408be57bfffSPierre-Louis Bossart void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx);
409be57bfffSPierre-Louis Bossart void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid);
410be57bfffSPierre-Louis Bossart 
411be57bfffSPierre-Louis Bossart /*
412be57bfffSPierre-Louis Bossart  * Mixer
413be57bfffSPierre-Louis Bossart  */
414be57bfffSPierre-Louis Bossart int snd_hda_codec_build_controls(struct hda_codec *codec);
415be57bfffSPierre-Louis Bossart 
416be57bfffSPierre-Louis Bossart /*
417be57bfffSPierre-Louis Bossart  * PCM
418be57bfffSPierre-Louis Bossart  */
419be57bfffSPierre-Louis Bossart int snd_hda_codec_parse_pcms(struct hda_codec *codec);
420be57bfffSPierre-Louis Bossart int snd_hda_codec_build_pcms(struct hda_codec *codec);
421be57bfffSPierre-Louis Bossart 
422be57bfffSPierre-Louis Bossart __printf(2, 3)
423be57bfffSPierre-Louis Bossart struct hda_pcm *snd_hda_codec_pcm_new(struct hda_codec *codec,
424be57bfffSPierre-Louis Bossart 				      const char *fmt, ...);
425be57bfffSPierre-Louis Bossart 
426cc1d0cd8SKai Vehmanen void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec);
427cc1d0cd8SKai Vehmanen 
snd_hda_codec_pcm_get(struct hda_pcm * pcm)428be57bfffSPierre-Louis Bossart static inline void snd_hda_codec_pcm_get(struct hda_pcm *pcm)
429be57bfffSPierre-Louis Bossart {
4307206998fSTakashi Iwai 	refcount_inc(&pcm->codec->pcm_ref);
431be57bfffSPierre-Louis Bossart }
432be57bfffSPierre-Louis Bossart void snd_hda_codec_pcm_put(struct hda_pcm *pcm);
433be57bfffSPierre-Louis Bossart 
434be57bfffSPierre-Louis Bossart int snd_hda_codec_prepare(struct hda_codec *codec,
435be57bfffSPierre-Louis Bossart 			  struct hda_pcm_stream *hinfo,
436be57bfffSPierre-Louis Bossart 			  unsigned int stream,
437be57bfffSPierre-Louis Bossart 			  unsigned int format,
438be57bfffSPierre-Louis Bossart 			  struct snd_pcm_substream *substream);
439be57bfffSPierre-Louis Bossart void snd_hda_codec_cleanup(struct hda_codec *codec,
440be57bfffSPierre-Louis Bossart 			   struct hda_pcm_stream *hinfo,
441be57bfffSPierre-Louis Bossart 			   struct snd_pcm_substream *substream);
442be57bfffSPierre-Louis Bossart 
443be57bfffSPierre-Louis Bossart void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
444be57bfffSPierre-Louis Bossart 				u32 stream_tag,
445be57bfffSPierre-Louis Bossart 				int channel_id, int format);
446be57bfffSPierre-Louis Bossart void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid,
447be57bfffSPierre-Louis Bossart 				    int do_now);
448be57bfffSPierre-Louis Bossart #define snd_hda_codec_cleanup_stream(codec, nid) \
449be57bfffSPierre-Louis Bossart 	__snd_hda_codec_cleanup_stream(codec, nid, 0)
450be57bfffSPierre-Louis Bossart 
451be57bfffSPierre-Louis Bossart #define snd_hda_query_supported_pcm(codec, nid, ratesp, fmtsp, bpsp) \
452be57bfffSPierre-Louis Bossart 	snd_hdac_query_supported_pcm(&(codec)->core, nid, ratesp, fmtsp, bpsp)
453be57bfffSPierre-Louis Bossart #define snd_hda_is_supported_format(codec, nid, fmt) \
454be57bfffSPierre-Louis Bossart 	snd_hdac_is_supported_format(&(codec)->core, nid, fmt)
455be57bfffSPierre-Louis Bossart 
456be57bfffSPierre-Louis Bossart extern const struct snd_pcm_chmap_elem snd_pcm_2_1_chmaps[];
457be57bfffSPierre-Louis Bossart 
458be57bfffSPierre-Louis Bossart int snd_hda_attach_pcm_stream(struct hda_bus *_bus, struct hda_codec *codec,
459be57bfffSPierre-Louis Bossart 			      struct hda_pcm *cpcm);
460be57bfffSPierre-Louis Bossart 
461be57bfffSPierre-Louis Bossart /*
462be57bfffSPierre-Louis Bossart  * Misc
463be57bfffSPierre-Louis Bossart  */
464be57bfffSPierre-Louis Bossart void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen);
465be57bfffSPierre-Louis Bossart void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
466be57bfffSPierre-Louis Bossart 				    unsigned int power_state);
467be57bfffSPierre-Louis Bossart 
468be57bfffSPierre-Louis Bossart int snd_hda_lock_devices(struct hda_bus *bus);
469be57bfffSPierre-Louis Bossart void snd_hda_unlock_devices(struct hda_bus *bus);
470be57bfffSPierre-Louis Bossart void snd_hda_bus_reset(struct hda_bus *bus);
471be57bfffSPierre-Louis Bossart void snd_hda_bus_reset_codecs(struct hda_bus *bus);
472be57bfffSPierre-Louis Bossart 
473be57bfffSPierre-Louis Bossart int snd_hda_codec_set_name(struct hda_codec *codec, const char *name);
474be57bfffSPierre-Louis Bossart 
475be57bfffSPierre-Louis Bossart /*
476be57bfffSPierre-Louis Bossart  * power management
477be57bfffSPierre-Louis Bossart  */
478be57bfffSPierre-Louis Bossart extern const struct dev_pm_ops hda_codec_driver_pm;
479be57bfffSPierre-Louis Bossart 
480be57bfffSPierre-Louis Bossart static inline
hda_call_check_power_status(struct hda_codec * codec,hda_nid_t nid)481be57bfffSPierre-Louis Bossart int hda_call_check_power_status(struct hda_codec *codec, hda_nid_t nid)
482be57bfffSPierre-Louis Bossart {
483be57bfffSPierre-Louis Bossart #ifdef CONFIG_PM
484be57bfffSPierre-Louis Bossart 	if (codec->patch_ops.check_power_status)
485be57bfffSPierre-Louis Bossart 		return codec->patch_ops.check_power_status(codec, nid);
486be57bfffSPierre-Louis Bossart #endif
487be57bfffSPierre-Louis Bossart 	return 0;
488be57bfffSPierre-Louis Bossart }
489be57bfffSPierre-Louis Bossart 
490be57bfffSPierre-Louis Bossart /*
491be57bfffSPierre-Louis Bossart  * power saving
492be57bfffSPierre-Louis Bossart  */
493be57bfffSPierre-Louis Bossart #define snd_hda_power_up(codec)		snd_hdac_power_up(&(codec)->core)
494be57bfffSPierre-Louis Bossart #define snd_hda_power_up_pm(codec)	snd_hdac_power_up_pm(&(codec)->core)
495be57bfffSPierre-Louis Bossart #define snd_hda_power_down(codec)	snd_hdac_power_down(&(codec)->core)
496be57bfffSPierre-Louis Bossart #define snd_hda_power_down_pm(codec)	snd_hdac_power_down_pm(&(codec)->core)
497be57bfffSPierre-Louis Bossart #ifdef CONFIG_PM
498bb682f7aSCezary Rojewski void snd_hda_codec_set_power_save(struct hda_codec *codec, int delay);
499be57bfffSPierre-Louis Bossart void snd_hda_set_power_save(struct hda_bus *bus, int delay);
500be57bfffSPierre-Louis Bossart void snd_hda_update_power_acct(struct hda_codec *codec);
501be57bfffSPierre-Louis Bossart #else
snd_hda_codec_set_power_save(struct hda_codec * codec,int delay)502bb682f7aSCezary Rojewski static inline void snd_hda_codec_set_power_save(struct hda_codec *codec, int delay) {}
snd_hda_set_power_save(struct hda_bus * bus,int delay)503be57bfffSPierre-Louis Bossart static inline void snd_hda_set_power_save(struct hda_bus *bus, int delay) {}
504be57bfffSPierre-Louis Bossart #endif
505be57bfffSPierre-Louis Bossart 
hda_codec_need_resume(struct hda_codec * codec)506c4c8dd6eSTakashi Iwai static inline bool hda_codec_need_resume(struct hda_codec *codec)
507c4c8dd6eSTakashi Iwai {
508c4c8dd6eSTakashi Iwai 	return !codec->relaxed_resume && codec->jacktbl.used;
509c4c8dd6eSTakashi Iwai }
510c4c8dd6eSTakashi Iwai 
511be57bfffSPierre-Louis Bossart #ifdef CONFIG_SND_HDA_PATCH_LOADER
512be57bfffSPierre-Louis Bossart /*
513be57bfffSPierre-Louis Bossart  * patch firmware
514be57bfffSPierre-Louis Bossart  */
515be57bfffSPierre-Louis Bossart int snd_hda_load_patch(struct hda_bus *bus, size_t size, const void *buf);
516be57bfffSPierre-Louis Bossart #endif
517be57bfffSPierre-Louis Bossart 
518be57bfffSPierre-Louis Bossart #ifdef CONFIG_SND_HDA_DSP_LOADER
519be57bfffSPierre-Louis Bossart int snd_hda_codec_load_dsp_prepare(struct hda_codec *codec, unsigned int format,
520be57bfffSPierre-Louis Bossart 				   unsigned int size,
521be57bfffSPierre-Louis Bossart 				   struct snd_dma_buffer *bufp);
522be57bfffSPierre-Louis Bossart void snd_hda_codec_load_dsp_trigger(struct hda_codec *codec, bool start);
523be57bfffSPierre-Louis Bossart void snd_hda_codec_load_dsp_cleanup(struct hda_codec *codec,
524be57bfffSPierre-Louis Bossart 				    struct snd_dma_buffer *dmab);
525be57bfffSPierre-Louis Bossart #else
526be57bfffSPierre-Louis Bossart static inline int
snd_hda_codec_load_dsp_prepare(struct hda_codec * codec,unsigned int format,unsigned int size,struct snd_dma_buffer * bufp)527be57bfffSPierre-Louis Bossart snd_hda_codec_load_dsp_prepare(struct hda_codec *codec, unsigned int format,
528be57bfffSPierre-Louis Bossart 				unsigned int size,
529be57bfffSPierre-Louis Bossart 				struct snd_dma_buffer *bufp)
530be57bfffSPierre-Louis Bossart {
531be57bfffSPierre-Louis Bossart 	return -ENOSYS;
532be57bfffSPierre-Louis Bossart }
533be57bfffSPierre-Louis Bossart static inline void
snd_hda_codec_load_dsp_trigger(struct hda_codec * codec,bool start)534be57bfffSPierre-Louis Bossart snd_hda_codec_load_dsp_trigger(struct hda_codec *codec, bool start) {}
535be57bfffSPierre-Louis Bossart static inline void
snd_hda_codec_load_dsp_cleanup(struct hda_codec * codec,struct snd_dma_buffer * dmab)536be57bfffSPierre-Louis Bossart snd_hda_codec_load_dsp_cleanup(struct hda_codec *codec,
537be57bfffSPierre-Louis Bossart 				struct snd_dma_buffer *dmab) {}
538be57bfffSPierre-Louis Bossart #endif
539be57bfffSPierre-Louis Bossart 
540be57bfffSPierre-Louis Bossart #endif /* __SOUND_HDA_CODEC_H */
541