Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0-or-later */
2 : : /*
3 : : * Universal Interface for Intel High Definition Audio Codec
4 : : *
5 : : * Local helper functions
6 : : *
7 : : * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
8 : : */
9 : :
10 : : #ifndef __SOUND_HDA_LOCAL_H
11 : : #define __SOUND_HDA_LOCAL_H
12 : :
13 : : /* We abuse kcontrol_new.subdev field to pass the NID corresponding to
14 : : * the given new control. If id.subdev has a bit flag HDA_SUBDEV_NID_FLAG,
15 : : * snd_hda_ctl_add() takes the lower-bit subdev value as a valid NID.
16 : : *
17 : : * Note that the subdevice field is cleared again before the real registration
18 : : * in snd_hda_ctl_add(), so that this value won't appear in the outside.
19 : : */
20 : : #define HDA_SUBDEV_NID_FLAG (1U << 31)
21 : : #define HDA_SUBDEV_AMP_FLAG (1U << 30)
22 : :
23 : : /*
24 : : * for mixer controls
25 : : */
26 : : #define HDA_COMPOSE_AMP_VAL_OFS(nid,chs,idx,dir,ofs) \
27 : : ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19) | ((ofs)<<23))
28 : : #define HDA_AMP_VAL_MIN_MUTE (1<<29)
29 : : #define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) \
30 : : HDA_COMPOSE_AMP_VAL_OFS(nid, chs, idx, dir, 0)
31 : : /* mono volume with index (index=0,1,...) (channel=1,2) */
32 : : #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, dir, flags) \
33 : : { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
34 : : .subdevice = HDA_SUBDEV_AMP_FLAG, \
35 : : .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
36 : : SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
37 : : SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
38 : : .info = snd_hda_mixer_amp_volume_info, \
39 : : .get = snd_hda_mixer_amp_volume_get, \
40 : : .put = snd_hda_mixer_amp_volume_put, \
41 : : .tlv = { .c = snd_hda_mixer_amp_tlv }, \
42 : : .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, dir) | flags }
43 : : /* stereo volume with index */
44 : : #define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \
45 : : HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction, 0)
46 : : /* mono volume */
47 : : #define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \
48 : : HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction, 0)
49 : : /* stereo volume */
50 : : #define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \
51 : : HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction)
52 : : /* stereo volume with min=mute */
53 : : #define HDA_CODEC_VOLUME_MIN_MUTE(xname, nid, xindex, direction) \
54 : : HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, 3, xindex, direction, \
55 : : HDA_AMP_VAL_MIN_MUTE)
56 : : /* mono mute switch with index (index=0,1,...) (channel=1,2) */
57 : : #define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
58 : : { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
59 : : .subdevice = HDA_SUBDEV_AMP_FLAG, \
60 : : .info = snd_hda_mixer_amp_switch_info, \
61 : : .get = snd_hda_mixer_amp_switch_get, \
62 : : .put = snd_hda_mixer_amp_switch_put, \
63 : : .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
64 : : /* stereo mute switch with index */
65 : : #define HDA_CODEC_MUTE_IDX(xname, xcidx, nid, xindex, direction) \
66 : : HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
67 : : /* mono mute switch */
68 : : #define HDA_CODEC_MUTE_MONO(xname, nid, channel, xindex, direction) \
69 : : HDA_CODEC_MUTE_MONO_IDX(xname, 0, nid, channel, xindex, direction)
70 : : /* stereo mute switch */
71 : : #define HDA_CODEC_MUTE(xname, nid, xindex, direction) \
72 : : HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction)
73 : : #ifdef CONFIG_SND_HDA_INPUT_BEEP
74 : : /* special beep mono mute switch with index (index=0,1,...) (channel=1,2) */
75 : : #define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
76 : : { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
77 : : .subdevice = HDA_SUBDEV_AMP_FLAG, \
78 : : .info = snd_hda_mixer_amp_switch_info, \
79 : : .get = snd_hda_mixer_amp_switch_get_beep, \
80 : : .put = snd_hda_mixer_amp_switch_put_beep, \
81 : : .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
82 : : #else
83 : : /* no digital beep - just the standard one */
84 : : #define HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, xcidx, nid, ch, xidx, dir) \
85 : : HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, ch, xidx, dir)
86 : : #endif /* CONFIG_SND_HDA_INPUT_BEEP */
87 : : /* special beep mono mute switch */
88 : : #define HDA_CODEC_MUTE_BEEP_MONO(xname, nid, channel, xindex, direction) \
89 : : HDA_CODEC_MUTE_BEEP_MONO_IDX(xname, 0, nid, channel, xindex, direction)
90 : : /* special beep stereo mute switch */
91 : : #define HDA_CODEC_MUTE_BEEP(xname, nid, xindex, direction) \
92 : : HDA_CODEC_MUTE_BEEP_MONO(xname, nid, 3, xindex, direction)
93 : :
94 : : extern const char *snd_hda_pcm_type_name[];
95 : :
96 : : int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
97 : : struct snd_ctl_elem_info *uinfo);
98 : : int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
99 : : struct snd_ctl_elem_value *ucontrol);
100 : : int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
101 : : struct snd_ctl_elem_value *ucontrol);
102 : : int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
103 : : unsigned int size, unsigned int __user *tlv);
104 : : int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
105 : : struct snd_ctl_elem_info *uinfo);
106 : : int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
107 : : struct snd_ctl_elem_value *ucontrol);
108 : : int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
109 : : struct snd_ctl_elem_value *ucontrol);
110 : : #ifdef CONFIG_SND_HDA_INPUT_BEEP
111 : : int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol,
112 : : struct snd_ctl_elem_value *ucontrol);
113 : : int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
114 : : struct snd_ctl_elem_value *ucontrol);
115 : : #endif
116 : : /* lowlevel accessor with caching; use carefully */
117 : : #define snd_hda_codec_amp_read(codec, nid, ch, dir, idx) \
118 : : snd_hdac_regmap_get_amp(&(codec)->core, nid, ch, dir, idx)
119 : : int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid,
120 : : int ch, int dir, int idx, int mask, int val);
121 : : int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
122 : : int dir, int idx, int mask, int val);
123 : : int snd_hda_codec_amp_init(struct hda_codec *codec, hda_nid_t nid, int ch,
124 : : int direction, int idx, int mask, int val);
125 : : int snd_hda_codec_amp_init_stereo(struct hda_codec *codec, hda_nid_t nid,
126 : : int dir, int idx, int mask, int val);
127 : : void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
128 : : unsigned int *tlv);
129 : : struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
130 : : const char *name);
131 : : int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
132 : : unsigned int *tlv, const char * const *slaves,
133 : : const char *suffix, bool init_slave_vol,
134 : : struct snd_kcontrol **ctl_ret);
135 : : #define snd_hda_add_vmaster(codec, name, tlv, slaves, suffix) \
136 : : __snd_hda_add_vmaster(codec, name, tlv, slaves, suffix, true, NULL)
137 : : int snd_hda_codec_reset(struct hda_codec *codec);
138 : : void snd_hda_codec_register(struct hda_codec *codec);
139 : : void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec);
140 : :
141 : : #define snd_hda_regmap_sync(codec) snd_hdac_regmap_sync(&(codec)->core)
142 : :
143 : : enum {
144 : : HDA_VMUTE_OFF,
145 : : HDA_VMUTE_ON,
146 : : HDA_VMUTE_FOLLOW_MASTER,
147 : : };
148 : :
149 : : struct hda_vmaster_mute_hook {
150 : : /* below two fields must be filled by the caller of
151 : : * snd_hda_add_vmaster_hook() beforehand
152 : : */
153 : : struct snd_kcontrol *sw_kctl;
154 : : void (*hook)(void *, int);
155 : : /* below are initialized automatically */
156 : : unsigned int mute_mode; /* HDA_VMUTE_XXX */
157 : : struct hda_codec *codec;
158 : : };
159 : :
160 : : int snd_hda_add_vmaster_hook(struct hda_codec *codec,
161 : : struct hda_vmaster_mute_hook *hook,
162 : : bool expose_enum_ctl);
163 : : void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook);
164 : :
165 : : /* amp value bits */
166 : : #define HDA_AMP_MUTE 0x80
167 : : #define HDA_AMP_UNMUTE 0x00
168 : : #define HDA_AMP_VOLMASK 0x7f
169 : :
170 : : /*
171 : : * SPDIF I/O
172 : : */
173 : : int snd_hda_create_dig_out_ctls(struct hda_codec *codec,
174 : : hda_nid_t associated_nid,
175 : : hda_nid_t cvt_nid, int type);
176 : : #define snd_hda_create_spdif_out_ctls(codec, anid, cnid) \
177 : : snd_hda_create_dig_out_ctls(codec, anid, cnid, HDA_PCM_TYPE_SPDIF)
178 : : int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
179 : :
180 : : /*
181 : : * input MUX helper
182 : : */
183 : : #define HDA_MAX_NUM_INPUTS 16
184 : : struct hda_input_mux_item {
185 : : char label[32];
186 : : unsigned int index;
187 : : };
188 : : struct hda_input_mux {
189 : : unsigned int num_items;
190 : : struct hda_input_mux_item items[HDA_MAX_NUM_INPUTS];
191 : : };
192 : :
193 : : int snd_hda_input_mux_info(const struct hda_input_mux *imux,
194 : : struct snd_ctl_elem_info *uinfo);
195 : : int snd_hda_input_mux_put(struct hda_codec *codec,
196 : : const struct hda_input_mux *imux,
197 : : struct snd_ctl_elem_value *ucontrol, hda_nid_t nid,
198 : : unsigned int *cur_val);
199 : : int snd_hda_add_imux_item(struct hda_codec *codec,
200 : : struct hda_input_mux *imux, const char *label,
201 : : int index, int *type_index_ret);
202 : :
203 : : /*
204 : : * Multi-channel / digital-out PCM helper
205 : : */
206 : :
207 : : enum { HDA_FRONT, HDA_REAR, HDA_CLFE, HDA_SIDE }; /* index for dac_nidx */
208 : : enum { HDA_DIG_NONE, HDA_DIG_EXCLUSIVE, HDA_DIG_ANALOG_DUP }; /* dig_out_used */
209 : :
210 : : #define HDA_MAX_OUTS 5
211 : :
212 : : struct hda_multi_out {
213 : : int num_dacs; /* # of DACs, must be more than 1 */
214 : : const hda_nid_t *dac_nids; /* DAC list */
215 : : hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */
216 : : hda_nid_t hp_out_nid[HDA_MAX_OUTS]; /* DACs for multiple HPs */
217 : : hda_nid_t extra_out_nid[HDA_MAX_OUTS]; /* other (e.g. speaker) DACs */
218 : : hda_nid_t dig_out_nid; /* digital out audio widget */
219 : : const hda_nid_t *slave_dig_outs;
220 : : int max_channels; /* currently supported analog channels */
221 : : int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */
222 : : int no_share_stream; /* don't share a stream with multiple pins */
223 : : int share_spdif; /* share SPDIF pin */
224 : : /* PCM information for both analog and SPDIF DACs */
225 : : unsigned int analog_rates;
226 : : unsigned int analog_maxbps;
227 : : u64 analog_formats;
228 : : unsigned int spdif_rates;
229 : : unsigned int spdif_maxbps;
230 : : u64 spdif_formats;
231 : : };
232 : :
233 : : int snd_hda_create_spdif_share_sw(struct hda_codec *codec,
234 : : struct hda_multi_out *mout);
235 : : int snd_hda_multi_out_dig_open(struct hda_codec *codec,
236 : : struct hda_multi_out *mout);
237 : : int snd_hda_multi_out_dig_close(struct hda_codec *codec,
238 : : struct hda_multi_out *mout);
239 : : int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
240 : : struct hda_multi_out *mout,
241 : : unsigned int stream_tag,
242 : : unsigned int format,
243 : : struct snd_pcm_substream *substream);
244 : : int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec,
245 : : struct hda_multi_out *mout);
246 : : int snd_hda_multi_out_analog_open(struct hda_codec *codec,
247 : : struct hda_multi_out *mout,
248 : : struct snd_pcm_substream *substream,
249 : : struct hda_pcm_stream *hinfo);
250 : : int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
251 : : struct hda_multi_out *mout,
252 : : unsigned int stream_tag,
253 : : unsigned int format,
254 : : struct snd_pcm_substream *substream);
255 : : int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
256 : : struct hda_multi_out *mout);
257 : :
258 : : /*
259 : : * generic proc interface
260 : : */
261 : : #ifdef CONFIG_SND_PROC_FS
262 : : int snd_hda_codec_proc_new(struct hda_codec *codec);
263 : : #else
264 : : static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; }
265 : : #endif
266 : :
267 : : #define SND_PRINT_BITS_ADVISED_BUFSIZE 16
268 : : void snd_print_pcm_bits(int pcm, char *buf, int buflen);
269 : :
270 : : /*
271 : : * Misc
272 : : */
273 : : int snd_hda_add_new_ctls(struct hda_codec *codec,
274 : : const struct snd_kcontrol_new *knew);
275 : :
276 : : /*
277 : : * Fix-up pin default configurations and add default verbs
278 : : */
279 : :
280 : : struct hda_pintbl {
281 : : hda_nid_t nid;
282 : : u32 val;
283 : : };
284 : :
285 : : struct hda_model_fixup {
286 : : const int id;
287 : : const char *name;
288 : : };
289 : :
290 : : struct hda_fixup {
291 : : int type;
292 : : bool chained:1; /* call the chained fixup(s) after this */
293 : : bool chained_before:1; /* call the chained fixup(s) before this */
294 : : int chain_id;
295 : : union {
296 : : const struct hda_pintbl *pins;
297 : : const struct hda_verb *verbs;
298 : : void (*func)(struct hda_codec *codec,
299 : : const struct hda_fixup *fix,
300 : : int action);
301 : : } v;
302 : : };
303 : :
304 : : struct snd_hda_pin_quirk {
305 : : unsigned int codec; /* Codec vendor/device ID */
306 : : unsigned short subvendor; /* PCI subvendor ID */
307 : : const struct hda_pintbl *pins; /* list of matching pins */
308 : : #ifdef CONFIG_SND_DEBUG_VERBOSE
309 : : const char *name;
310 : : #endif
311 : : int value; /* quirk value */
312 : : };
313 : :
314 : : #ifdef CONFIG_SND_DEBUG_VERBOSE
315 : :
316 : : #define SND_HDA_PIN_QUIRK(_codec, _subvendor, _name, _value, _pins...) \
317 : : { .codec = _codec,\
318 : : .subvendor = _subvendor,\
319 : : .name = _name,\
320 : : .value = _value,\
321 : : .pins = (const struct hda_pintbl[]) { _pins, {0, 0}} \
322 : : }
323 : : #else
324 : :
325 : : #define SND_HDA_PIN_QUIRK(_codec, _subvendor, _name, _value, _pins...) \
326 : : { .codec = _codec,\
327 : : .subvendor = _subvendor,\
328 : : .value = _value,\
329 : : .pins = (const struct hda_pintbl[]) { _pins, {0, 0}} \
330 : : }
331 : :
332 : : #endif
333 : :
334 : : #define HDA_FIXUP_ID_NOT_SET -1
335 : : #define HDA_FIXUP_ID_NO_FIXUP -2
336 : :
337 : : /* fixup types */
338 : : enum {
339 : : HDA_FIXUP_INVALID,
340 : : HDA_FIXUP_PINS,
341 : : HDA_FIXUP_VERBS,
342 : : HDA_FIXUP_FUNC,
343 : : HDA_FIXUP_PINCTLS,
344 : : };
345 : :
346 : : /* fixup action definitions */
347 : : enum {
348 : : HDA_FIXUP_ACT_PRE_PROBE,
349 : : HDA_FIXUP_ACT_PROBE,
350 : : HDA_FIXUP_ACT_INIT,
351 : : HDA_FIXUP_ACT_BUILD,
352 : : HDA_FIXUP_ACT_FREE,
353 : : };
354 : :
355 : : int snd_hda_add_verbs(struct hda_codec *codec, const struct hda_verb *list);
356 : : void snd_hda_apply_verbs(struct hda_codec *codec);
357 : : void snd_hda_apply_pincfgs(struct hda_codec *codec,
358 : : const struct hda_pintbl *cfg);
359 : : void snd_hda_apply_fixup(struct hda_codec *codec, int action);
360 : : void snd_hda_pick_fixup(struct hda_codec *codec,
361 : : const struct hda_model_fixup *models,
362 : : const struct snd_pci_quirk *quirk,
363 : : const struct hda_fixup *fixlist);
364 : : void snd_hda_pick_pin_fixup(struct hda_codec *codec,
365 : : const struct snd_hda_pin_quirk *pin_quirk,
366 : : const struct hda_fixup *fixlist,
367 : : bool match_all_pins);
368 : :
369 : : /* helper macros to retrieve pin default-config values */
370 : : #define get_defcfg_connect(cfg) \
371 : : ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT)
372 : : #define get_defcfg_association(cfg) \
373 : : ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT)
374 : : #define get_defcfg_location(cfg) \
375 : : ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT)
376 : : #define get_defcfg_sequence(cfg) \
377 : : (cfg & AC_DEFCFG_SEQUENCE)
378 : : #define get_defcfg_device(cfg) \
379 : : ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT)
380 : : #define get_defcfg_misc(cfg) \
381 : : ((cfg & AC_DEFCFG_MISC) >> AC_DEFCFG_MISC_SHIFT)
382 : :
383 : : /* amp values */
384 : : #define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8))
385 : : #define AMP_IN_UNMUTE(idx) (0x7000 | ((idx)<<8))
386 : : #define AMP_OUT_MUTE 0xb080
387 : : #define AMP_OUT_UNMUTE 0xb000
388 : : #define AMP_OUT_ZERO 0xb000
389 : : /* pinctl values */
390 : : #define PIN_IN (AC_PINCTL_IN_EN)
391 : : #define PIN_VREFHIZ (AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ)
392 : : #define PIN_VREF50 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_50)
393 : : #define PIN_VREFGRD (AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD)
394 : : #define PIN_VREF80 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_80)
395 : : #define PIN_VREF100 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_100)
396 : : #define PIN_OUT (AC_PINCTL_OUT_EN)
397 : : #define PIN_HP (AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN)
398 : : #define PIN_HP_AMP (AC_PINCTL_HP_EN)
399 : :
400 : : unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin);
401 : : unsigned int snd_hda_correct_pin_ctl(struct hda_codec *codec,
402 : : hda_nid_t pin, unsigned int val);
403 : : int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin,
404 : : unsigned int val, bool cached);
405 : :
406 : : /**
407 : : * _snd_hda_set_pin_ctl - Set a pin-control value safely
408 : : * @codec: the codec instance
409 : : * @pin: the pin NID to set the control
410 : : * @val: the pin-control value (AC_PINCTL_* bits)
411 : : *
412 : : * This function sets the pin-control value to the given pin, but
413 : : * filters out the invalid pin-control bits when the pin has no such
414 : : * capabilities. For example, when PIN_HP is passed but the pin has no
415 : : * HP-drive capability, the HP bit is omitted.
416 : : *
417 : : * The function doesn't check the input VREF capability bits, though.
418 : : * Use snd_hda_get_default_vref() to guess the right value.
419 : : * Also, this function is only for analog pins, not for HDMI pins.
420 : : */
421 : : static inline int
422 : : snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin, unsigned int val)
423 : : {
424 : : return _snd_hda_set_pin_ctl(codec, pin, val, false);
425 : : }
426 : :
427 : : /**
428 : : * snd_hda_set_pin_ctl_cache - Set a pin-control value safely
429 : : * @codec: the codec instance
430 : : * @pin: the pin NID to set the control
431 : : * @val: the pin-control value (AC_PINCTL_* bits)
432 : : *
433 : : * Just like snd_hda_set_pin_ctl() but write to cache as well.
434 : : */
435 : : static inline int
436 : 0 : snd_hda_set_pin_ctl_cache(struct hda_codec *codec, hda_nid_t pin,
437 : : unsigned int val)
438 : : {
439 : 0 : return _snd_hda_set_pin_ctl(codec, pin, val, true);
440 : : }
441 : :
442 : : int snd_hda_codec_get_pin_target(struct hda_codec *codec, hda_nid_t nid);
443 : : int snd_hda_codec_set_pin_target(struct hda_codec *codec, hda_nid_t nid,
444 : : unsigned int val);
445 : :
446 : : #define for_each_hda_codec_node(nid, codec) \
447 : : for ((nid) = (codec)->core.start_nid; (nid) < (codec)->core.end_nid; (nid)++)
448 : :
449 : : /*
450 : : * get widget capabilities
451 : : */
452 : 0 : static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid)
453 : : {
454 [ # # # # : 0 : if (nid < codec->core.start_nid ||
# # # # #
# # # # #
# # # # #
# # # #
# ]
455 [ # # # # : 0 : nid >= codec->core.start_nid + codec->core.num_nodes)
# # # # #
# # # # #
# # # # #
# # # #
# ]
456 : : return 0;
457 [ # # ]: 0 : return codec->wcaps[nid - codec->core.start_nid];
458 : : }
459 : :
460 : : /* get the widget type from widget capability bits */
461 : 0 : static inline int get_wcaps_type(unsigned int wcaps)
462 : : {
463 [ # # # # : 0 : if (!wcaps)
# # # # #
# ]
464 : : return -1; /* invalid type */
465 [ # # ]: 0 : return (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
466 : : }
467 : :
468 : 0 : static inline unsigned int get_wcaps_channels(u32 wcaps)
469 : : {
470 : 0 : unsigned int chans;
471 : :
472 : 0 : chans = (wcaps & AC_WCAP_CHAN_CNT_EXT) >> 13;
473 : 0 : chans = ((chans << 1) | 1) + 1;
474 : :
475 [ # # ]: 0 : return chans;
476 : : }
477 : :
478 : 0 : static inline void snd_hda_override_wcaps(struct hda_codec *codec,
479 : : hda_nid_t nid, u32 val)
480 : : {
481 [ # # ]: 0 : if (nid >= codec->core.start_nid &&
482 [ # # ]: 0 : nid < codec->core.start_nid + codec->core.num_nodes)
483 : 0 : codec->wcaps[nid - codec->core.start_nid] = val;
484 : : }
485 : :
486 : : u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction);
487 : : int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
488 : : unsigned int caps);
489 : : /**
490 : : * snd_hda_query_pin_caps - Query PIN capabilities
491 : : * @codec: the HD-auio codec
492 : : * @nid: the NID to query
493 : : *
494 : : * Query PIN capabilities for the given widget.
495 : : * Returns the obtained capability bits.
496 : : *
497 : : * When cap bits have been already read, this doesn't read again but
498 : : * returns the cached value.
499 : : */
500 : : static inline u32
501 : 0 : snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid)
502 : : {
503 [ # # # # : 0 : return snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
# # ]
504 : :
505 : : }
506 : :
507 : : /**
508 : : * snd_hda_override_pin_caps - Override the pin capabilities
509 : : * @codec: the CODEC
510 : : * @nid: the NID to override
511 : : * @caps: the capability bits to set
512 : : *
513 : : * Override the cached PIN capabilitiy bits value by the given one.
514 : : *
515 : : * Returns zero if successful or a negative error code.
516 : : */
517 : : static inline int
518 : : snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid,
519 : : unsigned int caps)
520 : : {
521 : : return snd_hdac_override_parm(&codec->core, nid, AC_PAR_PIN_CAP, caps);
522 : : }
523 : :
524 : : bool snd_hda_check_amp_caps(struct hda_codec *codec, hda_nid_t nid,
525 : : int dir, unsigned int bits);
526 : :
527 : : #define nid_has_mute(codec, nid, dir) \
528 : : snd_hda_check_amp_caps(codec, nid, dir, (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE))
529 : : #define nid_has_volume(codec, nid, dir) \
530 : : snd_hda_check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS)
531 : :
532 : :
533 : : /* flags for hda_nid_item */
534 : : #define HDA_NID_ITEM_AMP (1<<0)
535 : :
536 : : struct hda_nid_item {
537 : : struct snd_kcontrol *kctl;
538 : : unsigned int index;
539 : : hda_nid_t nid;
540 : : unsigned short flags;
541 : : };
542 : :
543 : : int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
544 : : struct snd_kcontrol *kctl);
545 : : int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
546 : : unsigned int index, hda_nid_t nid);
547 : : void snd_hda_ctls_clear(struct hda_codec *codec);
548 : :
549 : : /*
550 : : * hwdep interface
551 : : */
552 : : #ifdef CONFIG_SND_HDA_HWDEP
553 : : int snd_hda_create_hwdep(struct hda_codec *codec);
554 : : #else
555 : : static inline int snd_hda_create_hwdep(struct hda_codec *codec) { return 0; }
556 : : #endif
557 : :
558 : : void snd_hda_sysfs_init(struct hda_codec *codec);
559 : : void snd_hda_sysfs_clear(struct hda_codec *codec);
560 : :
561 : : extern const struct attribute_group *snd_hda_dev_attr_groups[];
562 : :
563 : : #ifdef CONFIG_SND_HDA_RECONFIG
564 : : const char *snd_hda_get_hint(struct hda_codec *codec, const char *key);
565 : : int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key);
566 : : int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp);
567 : : #else
568 : : static inline
569 : : const char *snd_hda_get_hint(struct hda_codec *codec, const char *key)
570 : : {
571 : : return NULL;
572 : : }
573 : :
574 : : static inline
575 : : int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key)
576 : : {
577 : : return -ENOENT;
578 : : }
579 : :
580 : : static inline
581 : 0 : int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp)
582 : : {
583 : 0 : return -ENOENT;
584 : : }
585 : : #endif
586 : :
587 : : /*
588 : : * power-management
589 : : */
590 : :
591 : : void snd_hda_schedule_power_save(struct hda_codec *codec);
592 : :
593 : : struct hda_amp_list {
594 : : hda_nid_t nid;
595 : : unsigned char dir;
596 : : unsigned char idx;
597 : : };
598 : :
599 : : struct hda_loopback_check {
600 : : const struct hda_amp_list *amplist;
601 : : int power_on;
602 : : };
603 : :
604 : : int snd_hda_check_amp_list_power(struct hda_codec *codec,
605 : : struct hda_loopback_check *check,
606 : : hda_nid_t nid);
607 : :
608 : : /* check whether the actual power state matches with the target state */
609 : : static inline bool
610 : 0 : snd_hda_check_power_state(struct hda_codec *codec, hda_nid_t nid,
611 : : unsigned int target_state)
612 : : {
613 : 0 : return snd_hdac_check_power_state(&codec->core, nid, target_state);
614 : : }
615 : :
616 : 0 : static inline unsigned int snd_hda_sync_power_state(struct hda_codec *codec,
617 : : hda_nid_t nid,
618 : : unsigned int target_state)
619 : : {
620 : 0 : return snd_hdac_sync_power_state(&codec->core, nid, target_state);
621 : : }
622 : : unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec,
623 : : hda_nid_t nid,
624 : : unsigned int power_state);
625 : :
626 : : /*
627 : : * AMP control callbacks
628 : : */
629 : : /* retrieve parameters from private_value */
630 : : #define get_amp_nid_(pv) ((pv) & 0xffff)
631 : : #define get_amp_nid(kc) get_amp_nid_((kc)->private_value)
632 : : #define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3)
633 : : #define get_amp_direction_(pv) (((pv) >> 18) & 0x1)
634 : : #define get_amp_direction(kc) get_amp_direction_((kc)->private_value)
635 : : #define get_amp_index_(pv) (((pv) >> 19) & 0xf)
636 : : #define get_amp_index(kc) get_amp_index_((kc)->private_value)
637 : : #define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f)
638 : : #define get_amp_min_mute(kc) (((kc)->private_value >> 29) & 0x1)
639 : :
640 : : /*
641 : : * enum control helper
642 : : */
643 : : int snd_hda_enum_helper_info(struct snd_kcontrol *kcontrol,
644 : : struct snd_ctl_elem_info *uinfo,
645 : : int num_entries, const char * const *texts);
646 : : #define snd_hda_enum_bool_helper_info(kcontrol, uinfo) \
647 : : snd_hda_enum_helper_info(kcontrol, uinfo, 0, NULL)
648 : :
649 : : /*
650 : : * CEA Short Audio Descriptor data
651 : : */
652 : : struct cea_sad {
653 : : int channels;
654 : : int format; /* (format == 0) indicates invalid SAD */
655 : : int rates;
656 : : int sample_bits; /* for LPCM */
657 : : int max_bitrate; /* for AC3...ATRAC */
658 : : int profile; /* for WMAPRO */
659 : : };
660 : :
661 : : #define ELD_FIXED_BYTES 20
662 : : #define ELD_MAX_SIZE 256
663 : : #define ELD_MAX_MNL 16
664 : : #define ELD_MAX_SAD 16
665 : :
666 : : /*
667 : : * ELD: EDID Like Data
668 : : */
669 : : struct parsed_hdmi_eld {
670 : : /*
671 : : * all fields will be cleared before updating ELD
672 : : */
673 : : int baseline_len;
674 : : int eld_ver;
675 : : int cea_edid_ver;
676 : : char monitor_name[ELD_MAX_MNL + 1];
677 : : int manufacture_id;
678 : : int product_id;
679 : : u64 port_id;
680 : : int support_hdcp;
681 : : int support_ai;
682 : : int conn_type;
683 : : int aud_synch_delay;
684 : : int spk_alloc;
685 : : int sad_count;
686 : : struct cea_sad sad[ELD_MAX_SAD];
687 : : };
688 : :
689 : : struct hdmi_eld {
690 : : bool monitor_present;
691 : : bool eld_valid;
692 : : int eld_size;
693 : : char eld_buffer[ELD_MAX_SIZE];
694 : : struct parsed_hdmi_eld info;
695 : : };
696 : :
697 : : int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid);
698 : : int snd_hdmi_get_eld(struct hda_codec *codec, hda_nid_t nid,
699 : : unsigned char *buf, int *eld_size);
700 : : int snd_hdmi_parse_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e,
701 : : const unsigned char *buf, int size);
702 : : void snd_hdmi_show_eld(struct hda_codec *codec, struct parsed_hdmi_eld *e);
703 : : void snd_hdmi_eld_update_pcm_info(struct parsed_hdmi_eld *e,
704 : : struct hda_pcm_stream *hinfo);
705 : :
706 : : int snd_hdmi_get_eld_ati(struct hda_codec *codec, hda_nid_t nid,
707 : : unsigned char *buf, int *eld_size,
708 : : bool rev3_or_later);
709 : :
710 : : #ifdef CONFIG_SND_PROC_FS
711 : : void snd_hdmi_print_eld_info(struct hdmi_eld *eld,
712 : : struct snd_info_buffer *buffer);
713 : : void snd_hdmi_write_eld_info(struct hdmi_eld *eld,
714 : : struct snd_info_buffer *buffer);
715 : : #endif
716 : :
717 : : #define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80
718 : : void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen);
719 : :
720 : : /*
721 : : */
722 : : #define codec_err(codec, fmt, args...) \
723 : : dev_err(hda_codec_dev(codec), fmt, ##args)
724 : : #define codec_warn(codec, fmt, args...) \
725 : : dev_warn(hda_codec_dev(codec), fmt, ##args)
726 : : #define codec_info(codec, fmt, args...) \
727 : : dev_info(hda_codec_dev(codec), fmt, ##args)
728 : : #define codec_dbg(codec, fmt, args...) \
729 : : dev_dbg(hda_codec_dev(codec), fmt, ##args)
730 : :
731 : : #endif /* __SOUND_HDA_LOCAL_H */
|