xref: /linux/sound/pci/hda/hda_generic.h (revision e6b85f3c9d5ea3807dee651c28d5b0d5982ae2fa)
1352f7f91STakashi Iwai /*
2352f7f91STakashi Iwai  * Generic BIOS auto-parser helper functions for HD-audio
3352f7f91STakashi Iwai  *
4352f7f91STakashi Iwai  * Copyright (c) 2012 Takashi Iwai <tiwai@suse.de>
5352f7f91STakashi Iwai  *
6352f7f91STakashi Iwai  * This driver is free software; you can redistribute it and/or modify
7352f7f91STakashi Iwai  * it under the terms of the GNU General Public License as published by
8352f7f91STakashi Iwai  * the Free Software Foundation; either version 2 of the License, or
9352f7f91STakashi Iwai  * (at your option) any later version.
10352f7f91STakashi Iwai  */
11352f7f91STakashi Iwai 
12352f7f91STakashi Iwai #ifndef __SOUND_HDA_GENERIC_H
13352f7f91STakashi Iwai #define __SOUND_HDA_GENERIC_H
14352f7f91STakashi Iwai 
15352f7f91STakashi Iwai /* unsol event tags */
16352f7f91STakashi Iwai enum {
17406b285dSTakashi Iwai 	HDA_GEN_HP_EVENT = 1, HDA_GEN_FRONT_EVENT, HDA_GEN_MIC_EVENT,
18352f7f91STakashi Iwai 	HDA_GEN_LAST_EVENT = HDA_GEN_MIC_EVENT
19352f7f91STakashi Iwai };
20352f7f91STakashi Iwai 
21352f7f91STakashi Iwai /* table entry for multi-io paths */
22352f7f91STakashi Iwai struct hda_multi_io {
23352f7f91STakashi Iwai 	hda_nid_t pin;		/* multi-io widget pin NID */
24352f7f91STakashi Iwai 	hda_nid_t dac;		/* DAC to be connected */
25352f7f91STakashi Iwai 	unsigned int ctl_in;	/* cached input-pin control value */
26352f7f91STakashi Iwai };
27352f7f91STakashi Iwai 
28352f7f91STakashi Iwai /* Widget connection path
29352f7f91STakashi Iwai  *
30352f7f91STakashi Iwai  * For output, stored in the order of DAC -> ... -> pin,
31352f7f91STakashi Iwai  * for input, pin -> ... -> ADC.
32352f7f91STakashi Iwai  *
33352f7f91STakashi Iwai  * idx[i] contains the source index number to select on of the widget path[i];
34352f7f91STakashi Iwai  * e.g. idx[1] is the index of the DAC (path[0]) selected by path[1] widget
35352f7f91STakashi Iwai  * multi[] indicates whether it's a selector widget with multi-connectors
36352f7f91STakashi Iwai  * (i.e. the connection selection is mandatory)
37352f7f91STakashi Iwai  * vol_ctl and mute_ctl contains the NIDs for the assigned mixers
38352f7f91STakashi Iwai  */
39352f7f91STakashi Iwai 
40d94ddd85STakashi Iwai #define MAX_NID_PATH_DEPTH	10
41352f7f91STakashi Iwai 
42352f7f91STakashi Iwai enum {
43352f7f91STakashi Iwai 	NID_PATH_VOL_CTL,
44352f7f91STakashi Iwai 	NID_PATH_MUTE_CTL,
45352f7f91STakashi Iwai 	NID_PATH_BOOST_CTL,
46352f7f91STakashi Iwai 	NID_PATH_NUM_CTLS
47352f7f91STakashi Iwai };
48352f7f91STakashi Iwai 
49352f7f91STakashi Iwai struct nid_path {
50352f7f91STakashi Iwai 	int depth;
51352f7f91STakashi Iwai 	hda_nid_t path[MAX_NID_PATH_DEPTH];
52352f7f91STakashi Iwai 	unsigned char idx[MAX_NID_PATH_DEPTH];
53352f7f91STakashi Iwai 	unsigned char multi[MAX_NID_PATH_DEPTH];
54352f7f91STakashi Iwai 	unsigned int ctls[NID_PATH_NUM_CTLS]; /* NID_PATH_XXX_CTL */
55352f7f91STakashi Iwai 	bool active;
56f5172a7eSTakashi Iwai 	bool with_aa_mix;
57352f7f91STakashi Iwai };
58352f7f91STakashi Iwai 
59352f7f91STakashi Iwai /* mic/line-in auto switching entry */
60352f7f91STakashi Iwai 
61352f7f91STakashi Iwai #define MAX_AUTO_MIC_PINS	3
62352f7f91STakashi Iwai 
63352f7f91STakashi Iwai struct automic_entry {
64352f7f91STakashi Iwai 	hda_nid_t pin;		/* pin */
65352f7f91STakashi Iwai 	int idx;		/* imux index, -1 = invalid */
66352f7f91STakashi Iwai 	unsigned int attr;	/* pin attribute (INPUT_PIN_ATTR_*) */
67352f7f91STakashi Iwai };
68352f7f91STakashi Iwai 
6938cf6f1aSTakashi Iwai /* active stream id */
7038cf6f1aSTakashi Iwai enum { STREAM_MULTI_OUT, STREAM_INDEP_HP };
7138cf6f1aSTakashi Iwai 
72*e6b85f3cSTakashi Iwai /* PCM hook action */
73*e6b85f3cSTakashi Iwai enum {
74*e6b85f3cSTakashi Iwai 	HDA_GEN_PCM_ACT_OPEN,
75*e6b85f3cSTakashi Iwai 	HDA_GEN_PCM_ACT_PREPARE,
76*e6b85f3cSTakashi Iwai 	HDA_GEN_PCM_ACT_CLEANUP,
77*e6b85f3cSTakashi Iwai 	HDA_GEN_PCM_ACT_CLOSE,
78*e6b85f3cSTakashi Iwai };
79*e6b85f3cSTakashi Iwai 
80352f7f91STakashi Iwai struct hda_gen_spec {
81352f7f91STakashi Iwai 	char stream_name_analog[32];	/* analog PCM stream */
82352f7f91STakashi Iwai 	const struct hda_pcm_stream *stream_analog_playback;
83352f7f91STakashi Iwai 	const struct hda_pcm_stream *stream_analog_capture;
84352f7f91STakashi Iwai 	const struct hda_pcm_stream *stream_analog_alt_playback;
85352f7f91STakashi Iwai 	const struct hda_pcm_stream *stream_analog_alt_capture;
86352f7f91STakashi Iwai 
87352f7f91STakashi Iwai 	char stream_name_digital[32];	/* digital PCM stream */
88352f7f91STakashi Iwai 	const struct hda_pcm_stream *stream_digital_playback;
89352f7f91STakashi Iwai 	const struct hda_pcm_stream *stream_digital_capture;
90352f7f91STakashi Iwai 
9138cf6f1aSTakashi Iwai 	/* PCM */
9238cf6f1aSTakashi Iwai 	unsigned int active_streams;
9338cf6f1aSTakashi Iwai 	struct mutex pcm_mutex;
9438cf6f1aSTakashi Iwai 
95352f7f91STakashi Iwai 	/* playback */
96352f7f91STakashi Iwai 	struct hda_multi_out multiout;	/* playback set-up
97352f7f91STakashi Iwai 					 * max_channels, dacs must be set
98352f7f91STakashi Iwai 					 * dig_out_nid and hp_nid are optional
99352f7f91STakashi Iwai 					 */
100352f7f91STakashi Iwai 	hda_nid_t alt_dac_nid;
101352f7f91STakashi Iwai 	hda_nid_t slave_dig_outs[3];	/* optional - for auto-parsing */
102352f7f91STakashi Iwai 	int dig_out_type;
103352f7f91STakashi Iwai 
104352f7f91STakashi Iwai 	/* capture */
105352f7f91STakashi Iwai 	unsigned int num_adc_nids;
106352f7f91STakashi Iwai 	hda_nid_t adc_nids[AUTO_CFG_MAX_OUTS];
107352f7f91STakashi Iwai 	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
108352f7f91STakashi Iwai 	hda_nid_t mixer_nid;		/* analog-mixer NID */
109352f7f91STakashi Iwai 
110352f7f91STakashi Iwai 	/* capture setup for dynamic dual-adc switch */
111352f7f91STakashi Iwai 	hda_nid_t cur_adc;
112352f7f91STakashi Iwai 	unsigned int cur_adc_stream_tag;
113352f7f91STakashi Iwai 	unsigned int cur_adc_format;
114352f7f91STakashi Iwai 
115352f7f91STakashi Iwai 	/* capture source */
116352f7f91STakashi Iwai 	struct hda_input_mux input_mux;
117352f7f91STakashi Iwai 	unsigned int cur_mux[3];
118352f7f91STakashi Iwai 
119352f7f91STakashi Iwai 	/* channel model */
120352f7f91STakashi Iwai 	int const_channel_count;	/* min. channel count (for speakers) */
121352f7f91STakashi Iwai 	int ext_channel_count;		/* current channel count for multi-io */
122352f7f91STakashi Iwai 
123352f7f91STakashi Iwai 	/* PCM information */
124352f7f91STakashi Iwai 	struct hda_pcm pcm_rec[3];	/* used in build_pcms() */
125352f7f91STakashi Iwai 
126352f7f91STakashi Iwai 	/* dynamic controls, init_verbs and input_mux */
127352f7f91STakashi Iwai 	struct auto_pin_cfg autocfg;
128352f7f91STakashi Iwai 	struct snd_array kctls;
129352f7f91STakashi Iwai 	hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
130352f7f91STakashi Iwai 	hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS];
131352f7f91STakashi Iwai 	unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS];
132352f7f91STakashi Iwai 	hda_nid_t shared_mic_vref_pin;
133352f7f91STakashi Iwai 
134352f7f91STakashi Iwai 	/* DAC list */
135352f7f91STakashi Iwai 	int num_all_dacs;
136352f7f91STakashi Iwai 	hda_nid_t all_dacs[16];
137352f7f91STakashi Iwai 
138352f7f91STakashi Iwai 	/* path list */
139352f7f91STakashi Iwai 	struct snd_array paths;
140352f7f91STakashi Iwai 
141196c1766STakashi Iwai 	/* path indices */
142196c1766STakashi Iwai 	int out_paths[AUTO_CFG_MAX_OUTS];
143196c1766STakashi Iwai 	int hp_paths[AUTO_CFG_MAX_OUTS];
144196c1766STakashi Iwai 	int speaker_paths[AUTO_CFG_MAX_OUTS];
145c30aa7b2STakashi Iwai 	int aamix_out_paths[3];
146196c1766STakashi Iwai 	int digout_paths[AUTO_CFG_MAX_OUTS];
147196c1766STakashi Iwai 	int loopback_paths[HDA_MAX_NUM_INPUTS];
1482430d7b7STakashi Iwai 	int digin_path;
149196c1766STakashi Iwai 
150352f7f91STakashi Iwai 	/* auto-mic stuff */
151352f7f91STakashi Iwai 	int am_num_entries;
152352f7f91STakashi Iwai 	struct automic_entry am_entry[MAX_AUTO_MIC_PINS];
153352f7f91STakashi Iwai 
154352f7f91STakashi Iwai 	/* for pin sensing */
155352f7f91STakashi Iwai 	unsigned int hp_jack_present:1;
156352f7f91STakashi Iwai 	unsigned int line_jack_present:1;
157352f7f91STakashi Iwai 	unsigned int master_mute:1;
158352f7f91STakashi Iwai 	unsigned int auto_mic:1;
159352f7f91STakashi Iwai 	unsigned int automute_speaker:1; /* automute speaker outputs */
160352f7f91STakashi Iwai 	unsigned int automute_lo:1; /* automute LO outputs */
161352f7f91STakashi Iwai 	unsigned int detect_hp:1;	/* Headphone detection enabled */
162352f7f91STakashi Iwai 	unsigned int detect_lo:1;	/* Line-out detection enabled */
163352f7f91STakashi Iwai 	unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */
164352f7f91STakashi Iwai 	unsigned int automute_lo_possible:1;	  /* there are line outs and HP */
165352f7f91STakashi Iwai 	unsigned int keep_vref_in_automute:1; /* Don't clear VREF in automute */
166352f7f91STakashi Iwai 	unsigned int line_in_auto_switch:1; /* allow line-in auto switch */
167352f7f91STakashi Iwai 
168352f7f91STakashi Iwai 	/* other flags */
169352f7f91STakashi Iwai 	unsigned int need_dac_fix:1; /* need to limit DACs for multi channels */
170352f7f91STakashi Iwai 	unsigned int no_analog:1; /* digital I/O only */
171352f7f91STakashi Iwai 	unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */
172352f7f91STakashi Iwai 	unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */
173352f7f91STakashi Iwai 	unsigned int no_primary_hp:1; /* Don't prefer HP pins to speaker pins */
174352f7f91STakashi Iwai 	unsigned int multi_cap_vol:1; /* allow multiple capture xxx volumes */
175352f7f91STakashi Iwai 	unsigned int inv_dmic_split:1; /* inverted dmic w/a for conexant */
176731dc301STakashi Iwai 	unsigned int own_eapd_ctl:1; /* set EAPD by own function */
177fd25a97aSTakashi Iwai 	unsigned int vmaster_mute_enum:1; /* add vmaster mute mode enum */
17838cf6f1aSTakashi Iwai 	unsigned int indep_hp:1; /* independent HP supported */
17938cf6f1aSTakashi Iwai 	unsigned int indep_hp_enabled:1; /* independent HP enabled */
180352f7f91STakashi Iwai 
181c30aa7b2STakashi Iwai 	/* loopback mixing mode */
182c30aa7b2STakashi Iwai 	bool aamix_mode;
183c30aa7b2STakashi Iwai 
184352f7f91STakashi Iwai 	/* for virtual master */
185352f7f91STakashi Iwai 	hda_nid_t vmaster_nid;
186352f7f91STakashi Iwai 	struct hda_vmaster_mute_hook vmaster_mute;
187352f7f91STakashi Iwai #ifdef CONFIG_PM
188352f7f91STakashi Iwai 	struct hda_loopback_check loopback;
189352f7f91STakashi Iwai 	int num_loopbacks;
190352f7f91STakashi Iwai 	struct hda_amp_list loopback_list[8];
191352f7f91STakashi Iwai #endif
192352f7f91STakashi Iwai 
193352f7f91STakashi Iwai 	/* multi-io */
194352f7f91STakashi Iwai 	int multi_ios;
195352f7f91STakashi Iwai 	struct hda_multi_io multi_io[4];
196352f7f91STakashi Iwai 
197352f7f91STakashi Iwai 	/* hooks */
198352f7f91STakashi Iwai 	void (*init_hook)(struct hda_codec *codec);
199352f7f91STakashi Iwai 	void (*automute_hook)(struct hda_codec *codec);
200352f7f91STakashi Iwai 	void (*cap_sync_hook)(struct hda_codec *codec);
2012e03e952STakashi Iwai 
202*e6b85f3cSTakashi Iwai 	/* PCM playback hook */
203*e6b85f3cSTakashi Iwai 	void (*pcm_playback_hook)(struct hda_pcm_stream *hinfo,
204*e6b85f3cSTakashi Iwai 				  struct hda_codec *codec,
205*e6b85f3cSTakashi Iwai 				  struct snd_pcm_substream *substream,
206*e6b85f3cSTakashi Iwai 				  int action);
207*e6b85f3cSTakashi Iwai 
2082e03e952STakashi Iwai 	/* automute / autoswitch hooks */
2092e03e952STakashi Iwai 	void (*hp_automute_hook)(struct hda_codec *codec,
2102e03e952STakashi Iwai 				 struct hda_jack_tbl *tbl);
2112e03e952STakashi Iwai 	void (*line_automute_hook)(struct hda_codec *codec,
2122e03e952STakashi Iwai 				   struct hda_jack_tbl *tbl);
2132e03e952STakashi Iwai 	void (*mic_autoswitch_hook)(struct hda_codec *codec,
2142e03e952STakashi Iwai 				    struct hda_jack_tbl *tbl);
215352f7f91STakashi Iwai };
216352f7f91STakashi Iwai 
217352f7f91STakashi Iwai int snd_hda_gen_spec_init(struct hda_gen_spec *spec);
218352f7f91STakashi Iwai void snd_hda_gen_spec_free(struct hda_gen_spec *spec);
219352f7f91STakashi Iwai 
220352f7f91STakashi Iwai int snd_hda_gen_init(struct hda_codec *codec);
221352f7f91STakashi Iwai 
222352f7f91STakashi Iwai struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec,
223352f7f91STakashi Iwai 				      hda_nid_t from_nid, hda_nid_t to_nid);
224196c1766STakashi Iwai int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path);
225196c1766STakashi Iwai struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx);
2264ac0eefaSTakashi Iwai 
2274ac0eefaSTakashi Iwai enum {
2284ac0eefaSTakashi Iwai 	HDA_PARSE_NO_AAMIX,
2294ac0eefaSTakashi Iwai 	HDA_PARSE_ONLY_AAMIX,
2304ac0eefaSTakashi Iwai 	HDA_PARSE_ALL,
2314ac0eefaSTakashi Iwai };
2324ac0eefaSTakashi Iwai 
233352f7f91STakashi Iwai bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid,
234352f7f91STakashi Iwai 			    hda_nid_t to_nid, int with_aa_mix,
235352f7f91STakashi Iwai 			    struct nid_path *path);
236352f7f91STakashi Iwai struct nid_path *
237352f7f91STakashi Iwai snd_hda_add_new_path(struct hda_codec *codec, hda_nid_t from_nid,
238352f7f91STakashi Iwai 		     hda_nid_t to_nid, int with_aa_mix);
239352f7f91STakashi Iwai void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path,
240352f7f91STakashi Iwai 			   bool enable, bool add_aamix);
241352f7f91STakashi Iwai 
24212c93df6STakashi Iwai struct snd_kcontrol_new *
24312c93df6STakashi Iwai snd_hda_gen_add_kctl(struct hda_gen_spec *spec, const char *name,
24412c93df6STakashi Iwai 		     const struct snd_kcontrol_new *temp);
24512c93df6STakashi Iwai 
246352f7f91STakashi Iwai int snd_hda_gen_parse_auto_config(struct hda_codec *codec,
2479eb413e5STakashi Iwai 				  struct auto_pin_cfg *cfg);
248352f7f91STakashi Iwai int snd_hda_gen_build_controls(struct hda_codec *codec);
249352f7f91STakashi Iwai int snd_hda_gen_build_pcms(struct hda_codec *codec);
250352f7f91STakashi Iwai 
2515d550e15STakashi Iwai /* standard jack event callbacks */
2525d550e15STakashi Iwai void snd_hda_gen_hp_automute(struct hda_codec *codec,
2535d550e15STakashi Iwai 			     struct hda_jack_tbl *jack);
2545d550e15STakashi Iwai void snd_hda_gen_line_automute(struct hda_codec *codec,
2555d550e15STakashi Iwai 			       struct hda_jack_tbl *jack);
2565d550e15STakashi Iwai void snd_hda_gen_mic_autoswitch(struct hda_codec *codec,
2575d550e15STakashi Iwai 				struct hda_jack_tbl *jack);
2585d550e15STakashi Iwai void snd_hda_gen_update_outputs(struct hda_codec *codec);
2595d550e15STakashi Iwai 
260352f7f91STakashi Iwai #endif /* __SOUND_HDA_GENERIC_H */
261