2 * Universal Interface for Intel High Definition Audio Codec
4 * Generic proc interface
6 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This driver is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include <linux/init.h>
25 #include <sound/core.h>
26 #include "hda_codec.h"
27 #include "hda_local.h"
29 static const char *get_wid_type_name(unsigned int wid_value
)
31 static char *names
[16] = {
32 [AC_WID_AUD_OUT
] = "Audio Output",
33 [AC_WID_AUD_IN
] = "Audio Input",
34 [AC_WID_AUD_MIX
] = "Audio Mixer",
35 [AC_WID_AUD_SEL
] = "Audio Selector",
36 [AC_WID_PIN
] = "Pin Complex",
37 [AC_WID_POWER
] = "Power Widget",
38 [AC_WID_VOL_KNB
] = "Volume Knob Widget",
39 [AC_WID_BEEP
] = "Beep Generator Widget",
40 [AC_WID_VENDOR
] = "Vendor Defined Widget",
44 return names
[wid_value
];
46 return "UNKNOWN Widget";
49 static void print_amp_caps(struct snd_info_buffer
*buffer
,
50 struct hda_codec
*codec
, hda_nid_t nid
, int dir
)
53 caps
= snd_hda_param_read(codec
, nid
,
55 AC_PAR_AMP_OUT_CAP
: AC_PAR_AMP_IN_CAP
);
56 if (caps
== -1 || caps
== 0) {
57 snd_iprintf(buffer
, "N/A\n");
60 snd_iprintf(buffer
, "ofs=0x%02x, nsteps=0x%02x, stepsize=0x%02x, "
62 caps
& AC_AMPCAP_OFFSET
,
63 (caps
& AC_AMPCAP_NUM_STEPS
) >> AC_AMPCAP_NUM_STEPS_SHIFT
,
64 (caps
& AC_AMPCAP_STEP_SIZE
) >> AC_AMPCAP_STEP_SIZE_SHIFT
,
65 (caps
& AC_AMPCAP_MUTE
) >> AC_AMPCAP_MUTE_SHIFT
);
68 static void print_amp_vals(struct snd_info_buffer
*buffer
,
69 struct hda_codec
*codec
, hda_nid_t nid
,
70 int dir
, int stereo
, int indices
)
75 dir
= dir
== HDA_OUTPUT
? AC_AMP_GET_OUTPUT
: AC_AMP_GET_INPUT
;
76 for (i
= 0; i
< indices
; i
++) {
77 snd_iprintf(buffer
, " [");
79 val
= snd_hda_codec_read(codec
, nid
, 0,
80 AC_VERB_GET_AMP_GAIN_MUTE
,
81 AC_AMP_GET_LEFT
| dir
| i
);
82 snd_iprintf(buffer
, "0x%02x ", val
);
84 val
= snd_hda_codec_read(codec
, nid
, 0,
85 AC_VERB_GET_AMP_GAIN_MUTE
,
86 AC_AMP_GET_RIGHT
| dir
| i
);
87 snd_iprintf(buffer
, "0x%02x]", val
);
89 snd_iprintf(buffer
, "\n");
92 static void print_pcm_rates(struct snd_info_buffer
*buffer
, unsigned int pcm
)
94 static unsigned int rates
[] = {
95 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
96 96000, 176400, 192000, 384000
100 pcm
&= AC_SUPPCM_RATES
;
101 snd_iprintf(buffer
, " rates [0x%x]:", pcm
);
102 for (i
= 0; i
< ARRAY_SIZE(rates
); i
++)
104 snd_iprintf(buffer
, " %d", rates
[i
]);
105 snd_iprintf(buffer
, "\n");
108 static void print_pcm_bits(struct snd_info_buffer
*buffer
, unsigned int pcm
)
110 static unsigned int bits
[] = { 8, 16, 20, 24, 32 };
113 pcm
= (pcm
>> 16) & 0xff;
114 snd_iprintf(buffer
, " bits [0x%x]:", pcm
);
115 for (i
= 0; i
< ARRAY_SIZE(bits
); i
++)
117 snd_iprintf(buffer
, " %d", bits
[i
]);
118 snd_iprintf(buffer
, "\n");
121 static void print_pcm_formats(struct snd_info_buffer
*buffer
,
122 unsigned int streams
)
124 snd_iprintf(buffer
, " formats [0x%x]:", streams
& 0xf);
125 if (streams
& AC_SUPFMT_PCM
)
126 snd_iprintf(buffer
, " PCM");
127 if (streams
& AC_SUPFMT_FLOAT32
)
128 snd_iprintf(buffer
, " FLOAT");
129 if (streams
& AC_SUPFMT_AC3
)
130 snd_iprintf(buffer
, " AC3");
131 snd_iprintf(buffer
, "\n");
134 static void print_pcm_caps(struct snd_info_buffer
*buffer
,
135 struct hda_codec
*codec
, hda_nid_t nid
)
137 unsigned int pcm
= snd_hda_param_read(codec
, nid
, AC_PAR_PCM
);
138 unsigned int stream
= snd_hda_param_read(codec
, nid
, AC_PAR_STREAM
);
139 if (pcm
== -1 || stream
== -1) {
140 snd_iprintf(buffer
, "N/A\n");
143 print_pcm_rates(buffer
, pcm
);
144 print_pcm_bits(buffer
, pcm
);
145 print_pcm_formats(buffer
, stream
);
148 static const char *get_jack_location(u32 cfg
)
150 static char *bases
[7] = {
151 "N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom",
153 static unsigned char specials_idx
[] = {
158 static char *specials
[] = {
159 "Rear Panel", "Drive Bar",
160 "Riser", "HDMI", "ATAPI",
161 "Mobile-In", "Mobile-Out"
164 cfg
= (cfg
& AC_DEFCFG_LOCATION
) >> AC_DEFCFG_LOCATION_SHIFT
;
165 if ((cfg
& 0x0f) < 7)
166 return bases
[cfg
& 0x0f];
167 for (i
= 0; i
< ARRAY_SIZE(specials_idx
); i
++) {
168 if (cfg
== specials_idx
[i
])
174 static const char *get_jack_connection(u32 cfg
)
176 static char *names
[16] = {
177 "Unknown", "1/8", "1/4", "ATAPI",
178 "RCA", "Optical","Digital", "Analog",
179 "DIN", "XLR", "RJ11", "Comb",
180 NULL
, NULL
, NULL
, "Other"
182 cfg
= (cfg
& AC_DEFCFG_CONN_TYPE
) >> AC_DEFCFG_CONN_TYPE_SHIFT
;
189 static const char *get_jack_color(u32 cfg
)
191 static char *names
[16] = {
192 "Unknown", "Black", "Grey", "Blue",
193 "Green", "Red", "Orange", "Yellow",
194 "Purple", "Pink", NULL
, NULL
,
195 NULL
, NULL
, "White", "Other",
197 cfg
= (cfg
& AC_DEFCFG_COLOR
) >> AC_DEFCFG_COLOR_SHIFT
;
204 static void print_pin_caps(struct snd_info_buffer
*buffer
,
205 struct hda_codec
*codec
, hda_nid_t nid
,
208 static char *jack_conns
[4] = { "Jack", "N/A", "Fixed", "Both" };
209 static char *jack_types
[16] = {
210 "Line Out", "Speaker", "HP Out", "CD",
211 "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
212 "Line In", "Aux", "Mic", "Telephony",
213 "SPDIF In", "Digitial In", "Reserved", "Other"
215 static char *jack_locations
[4] = { "Ext", "Int", "Sep", "Oth" };
216 unsigned int caps
, val
;
218 caps
= snd_hda_param_read(codec
, nid
, AC_PAR_PIN_CAP
);
219 snd_iprintf(buffer
, " Pincap 0x08%x:", caps
);
220 if (caps
& AC_PINCAP_IN
)
221 snd_iprintf(buffer
, " IN");
222 if (caps
& AC_PINCAP_OUT
)
223 snd_iprintf(buffer
, " OUT");
224 if (caps
& AC_PINCAP_HP_DRV
)
225 snd_iprintf(buffer
, " HP");
226 if (caps
& AC_PINCAP_EAPD
)
227 snd_iprintf(buffer
, " EAPD");
228 if (caps
& AC_PINCAP_PRES_DETECT
)
229 snd_iprintf(buffer
, " Detect");
230 if (caps
& AC_PINCAP_BALANCE
)
231 snd_iprintf(buffer
, " Balanced");
232 if (caps
& AC_PINCAP_LR_SWAP
)
233 snd_iprintf(buffer
, " R/L");
234 if (caps
& AC_PINCAP_TRIG_REQ
)
235 snd_iprintf(buffer
, " Trigger");
236 if (caps
& AC_PINCAP_IMP_SENSE
)
237 snd_iprintf(buffer
, " ImpSense");
238 snd_iprintf(buffer
, "\n");
239 if (caps
& AC_PINCAP_VREF
) {
241 (caps
& AC_PINCAP_VREF
) >> AC_PINCAP_VREF_SHIFT
;
242 snd_iprintf(buffer
, " Vref caps:");
243 if (vref
& AC_PINCAP_VREF_HIZ
)
244 snd_iprintf(buffer
, " HIZ");
245 if (vref
& AC_PINCAP_VREF_50
)
246 snd_iprintf(buffer
, " 50");
247 if (vref
& AC_PINCAP_VREF_GRD
)
248 snd_iprintf(buffer
, " GRD");
249 if (vref
& AC_PINCAP_VREF_80
)
250 snd_iprintf(buffer
, " 80");
251 if (vref
& AC_PINCAP_VREF_100
)
252 snd_iprintf(buffer
, " 100");
253 snd_iprintf(buffer
, "\n");
257 if (caps
& AC_PINCAP_EAPD
) {
258 val
= snd_hda_codec_read(codec
, nid
, 0,
259 AC_VERB_GET_EAPD_BTLENABLE
, 0);
260 snd_iprintf(buffer
, " EAPD 0x%x:", val
);
261 if (val
& AC_EAPDBTL_BALANCED
)
262 snd_iprintf(buffer
, " BALANCED");
263 if (val
& AC_EAPDBTL_EAPD
)
264 snd_iprintf(buffer
, " EAPD");
265 if (val
& AC_EAPDBTL_LR_SWAP
)
266 snd_iprintf(buffer
, " R/L");
267 snd_iprintf(buffer
, "\n");
269 caps
= snd_hda_codec_read(codec
, nid
, 0, AC_VERB_GET_CONFIG_DEFAULT
, 0);
270 snd_iprintf(buffer
, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps
,
271 jack_conns
[(caps
& AC_DEFCFG_PORT_CONN
) >> AC_DEFCFG_PORT_CONN_SHIFT
],
272 jack_types
[(caps
& AC_DEFCFG_DEVICE
) >> AC_DEFCFG_DEVICE_SHIFT
],
273 jack_locations
[(caps
>> (AC_DEFCFG_LOCATION_SHIFT
+ 4)) & 3],
274 get_jack_location(caps
));
275 snd_iprintf(buffer
, " Conn = %s, Color = %s\n",
276 get_jack_connection(caps
),
277 get_jack_color(caps
));
278 /* Default association and sequence values refer to default grouping
279 * of pin complexes and their sequence within the group. This is used
280 * for priority and resource allocation.
282 snd_iprintf(buffer
, " DefAssociation = 0x%x, Sequence = 0x%x\n",
283 (caps
& AC_DEFCFG_DEF_ASSOC
) >> AC_DEFCFG_ASSOC_SHIFT
,
284 caps
& AC_DEFCFG_SEQUENCE
);
285 if (((caps
& AC_DEFCFG_MISC
) >> AC_DEFCFG_MISC_SHIFT
) &
286 AC_DEFCFG_MISC_NO_PRESENCE
) {
287 /* Miscellaneous bit indicates external hardware does not
288 * support presence detection even if the pin complex
289 * indicates it is supported.
291 snd_iprintf(buffer
, " Misc = NO_PRESENCE\n");
295 static void print_pin_ctls(struct snd_info_buffer
*buffer
,
296 struct hda_codec
*codec
, hda_nid_t nid
,
299 unsigned int pinctls
;
301 pinctls
= snd_hda_codec_read(codec
, nid
, 0,
302 AC_VERB_GET_PIN_WIDGET_CONTROL
, 0);
303 snd_iprintf(buffer
, " Pin-ctls: 0x%02x:", pinctls
);
304 if (pinctls
& AC_PINCTL_IN_EN
)
305 snd_iprintf(buffer
, " IN");
306 if (pinctls
& AC_PINCTL_OUT_EN
)
307 snd_iprintf(buffer
, " OUT");
308 if (pinctls
& AC_PINCTL_HP_EN
)
309 snd_iprintf(buffer
, " HP");
311 int vref
= pinctls
& AC_PINCTL_VREFEN
;
313 case AC_PINCTL_VREF_HIZ
:
314 snd_iprintf(buffer
, " VREF_HIZ");
316 case AC_PINCTL_VREF_50
:
317 snd_iprintf(buffer
, " VREF_50");
319 case AC_PINCTL_VREF_GRD
:
320 snd_iprintf(buffer
, " VREF_GRD");
322 case AC_PINCTL_VREF_80
:
323 snd_iprintf(buffer
, " VREF_80");
325 case AC_PINCTL_VREF_100
:
326 snd_iprintf(buffer
, " VREF_100");
330 snd_iprintf(buffer
, "\n");
333 static void print_vol_knob(struct snd_info_buffer
*buffer
,
334 struct hda_codec
*codec
, hda_nid_t nid
)
336 unsigned int cap
= snd_hda_param_read(codec
, nid
,
338 snd_iprintf(buffer
, " Volume-Knob: delta=%d, steps=%d, ",
339 (cap
>> 7) & 1, cap
& 0x7f);
340 cap
= snd_hda_codec_read(codec
, nid
, 0,
341 AC_VERB_GET_VOLUME_KNOB_CONTROL
, 0);
342 snd_iprintf(buffer
, "direct=%d, val=%d\n",
343 (cap
>> 7) & 1, cap
& 0x7f);
346 static void print_audio_io(struct snd_info_buffer
*buffer
,
347 struct hda_codec
*codec
, hda_nid_t nid
,
348 unsigned int wid_type
)
350 int conv
= snd_hda_codec_read(codec
, nid
, 0, AC_VERB_GET_CONV
, 0);
352 " Converter: stream=%d, channel=%d\n",
353 (conv
& AC_CONV_STREAM
) >> AC_CONV_STREAM_SHIFT
,
354 conv
& AC_CONV_CHANNEL
);
356 if (wid_type
== AC_WID_AUD_IN
&& (conv
& AC_CONV_CHANNEL
) == 0) {
357 int sdi
= snd_hda_codec_read(codec
, nid
, 0,
358 AC_VERB_GET_SDI_SELECT
, 0);
359 snd_iprintf(buffer
, " SDI-Select: %d\n",
360 sdi
& AC_SDI_SELECT
);
364 static void print_digital_conv(struct snd_info_buffer
*buffer
,
365 struct hda_codec
*codec
, hda_nid_t nid
)
367 unsigned int digi1
= snd_hda_codec_read(codec
, nid
, 0,
368 AC_VERB_GET_DIGI_CONVERT_1
, 0);
369 unsigned int digi2
= snd_hda_codec_read(codec
, nid
, 0,
370 AC_VERB_GET_DIGI_CONVERT_2
, 0);
371 snd_iprintf(buffer
, " Digital:");
372 if (digi1
& AC_DIG1_ENABLE
)
373 snd_iprintf(buffer
, " Enabled");
374 if (digi1
& AC_DIG1_V
)
375 snd_iprintf(buffer
, " Validity");
376 if (digi1
& AC_DIG1_VCFG
)
377 snd_iprintf(buffer
, " ValidityCfg");
378 if (digi1
& AC_DIG1_EMPHASIS
)
379 snd_iprintf(buffer
, " Preemphasis");
380 if (digi1
& AC_DIG1_COPYRIGHT
)
381 snd_iprintf(buffer
, " Copyright");
382 if (digi1
& AC_DIG1_NONAUDIO
)
383 snd_iprintf(buffer
, " Non-Audio");
384 if (digi1
& AC_DIG1_PROFESSIONAL
)
385 snd_iprintf(buffer
, " Pro");
386 if (digi1
& AC_DIG1_LEVEL
)
387 snd_iprintf(buffer
, " GenLevel");
388 snd_iprintf(buffer
, "\n");
389 snd_iprintf(buffer
, " Digital category: 0x%x\n", digi2
& AC_DIG2_CC
);
392 static const char *get_pwr_state(u32 state
)
394 static const char *buf
[4] = {
395 "D0", "D1", "D2", "D3"
402 static void print_power_state(struct snd_info_buffer
*buffer
,
403 struct hda_codec
*codec
, hda_nid_t nid
)
405 int pwr
= snd_hda_codec_read(codec
, nid
, 0,
406 AC_VERB_GET_POWER_STATE
, 0);
407 snd_iprintf(buffer
, " Power: setting=%s, actual=%s\n",
408 get_pwr_state(pwr
& AC_PWRST_SETTING
),
409 get_pwr_state((pwr
& AC_PWRST_ACTUAL
) >>
410 AC_PWRST_ACTUAL_SHIFT
));
413 static void print_unsol_cap(struct snd_info_buffer
*buffer
,
414 struct hda_codec
*codec
, hda_nid_t nid
)
416 int unsol
= snd_hda_codec_read(codec
, nid
, 0,
417 AC_VERB_GET_UNSOLICITED_RESPONSE
, 0);
419 " Unsolicited: tag=%02x, enabled=%d\n",
420 unsol
& AC_UNSOL_TAG
,
421 (unsol
& AC_UNSOL_ENABLED
) ? 1 : 0);
424 static void print_proc_caps(struct snd_info_buffer
*buffer
,
425 struct hda_codec
*codec
, hda_nid_t nid
)
427 unsigned int proc_caps
= snd_hda_param_read(codec
, nid
,
429 snd_iprintf(buffer
, " Processing caps: benign=%d, ncoeff=%d\n",
430 proc_caps
& AC_PCAP_BENIGN
,
431 (proc_caps
& AC_PCAP_NUM_COEF
) >> AC_PCAP_NUM_COEF_SHIFT
);
434 static void print_conn_list(struct snd_info_buffer
*buffer
,
435 struct hda_codec
*codec
, hda_nid_t nid
,
436 unsigned int wid_type
, hda_nid_t
*conn
,
441 if (conn_len
> 1 && wid_type
!= AC_WID_AUD_MIX
)
442 curr
= snd_hda_codec_read(codec
, nid
, 0,
443 AC_VERB_GET_CONNECT_SEL
, 0);
444 snd_iprintf(buffer
, " Connection: %d\n", conn_len
);
446 snd_iprintf(buffer
, " ");
447 for (c
= 0; c
< conn_len
; c
++) {
448 snd_iprintf(buffer
, " 0x%02x", conn
[c
]);
450 snd_iprintf(buffer
, "*");
452 snd_iprintf(buffer
, "\n");
456 static void print_realtek_coef(struct snd_info_buffer
*buffer
,
457 struct hda_codec
*codec
, hda_nid_t nid
)
459 int coeff
= snd_hda_codec_read(codec
, nid
, 0,
460 AC_VERB_GET_PROC_COEF
, 0);
461 snd_iprintf(buffer
, " Processing Coefficient: 0x%02x\n", coeff
);
462 coeff
= snd_hda_codec_read(codec
, nid
, 0,
463 AC_VERB_GET_COEF_INDEX
, 0);
464 snd_iprintf(buffer
, " Coefficient Index: 0x%02x\n", coeff
);
467 static void print_gpio(struct snd_info_buffer
*buffer
,
468 struct hda_codec
*codec
, hda_nid_t nid
)
471 snd_hda_param_read(codec
, codec
->afg
, AC_PAR_GPIO_CAP
);
472 unsigned int enable
, direction
, wake
, unsol
, sticky
, data
;
474 snd_iprintf(buffer
, "GPIO: io=%d, o=%d, i=%d, "
475 "unsolicited=%d, wake=%d\n",
476 gpio
& AC_GPIO_IO_COUNT
,
477 (gpio
& AC_GPIO_O_COUNT
) >> AC_GPIO_O_COUNT_SHIFT
,
478 (gpio
& AC_GPIO_I_COUNT
) >> AC_GPIO_I_COUNT_SHIFT
,
479 (gpio
& AC_GPIO_UNSOLICITED
) ? 1 : 0,
480 (gpio
& AC_GPIO_WAKE
) ? 1 : 0);
481 max
= gpio
& AC_GPIO_IO_COUNT
;
482 enable
= snd_hda_codec_read(codec
, nid
, 0,
483 AC_VERB_GET_GPIO_MASK
, 0);
484 direction
= snd_hda_codec_read(codec
, nid
, 0,
485 AC_VERB_GET_GPIO_DIRECTION
, 0);
486 wake
= snd_hda_codec_read(codec
, nid
, 0,
487 AC_VERB_GET_GPIO_WAKE_MASK
, 0);
488 unsol
= snd_hda_codec_read(codec
, nid
, 0,
489 AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK
, 0);
490 sticky
= snd_hda_codec_read(codec
, nid
, 0,
491 AC_VERB_GET_GPIO_STICKY_MASK
, 0);
492 data
= snd_hda_codec_read(codec
, nid
, 0,
493 AC_VERB_GET_GPIO_DATA
, 0);
494 for (i
= 0; i
< max
; ++i
)
496 " IO[%d]: enable=%d, dir=%d, wake=%d, "
497 "sticky=%d, data=%d\n", i
,
498 (enable
& (1<<i
)) ? 1 : 0,
499 (direction
& (1<<i
)) ? 1 : 0,
500 (wake
& (1<<i
)) ? 1 : 0,
501 (sticky
& (1<<i
)) ? 1 : 0,
502 (data
& (1<<i
)) ? 1 : 0);
503 /* FIXME: add GPO and GPI pin information */
506 static void print_codec_info(struct snd_info_entry
*entry
,
507 struct snd_info_buffer
*buffer
)
509 struct hda_codec
*codec
= entry
->private_data
;
514 snd_hda_get_codec_name(codec
, buf
, sizeof(buf
));
515 snd_iprintf(buffer
, "Codec: %s\n", buf
);
516 snd_iprintf(buffer
, "Address: %d\n", codec
->addr
);
517 snd_iprintf(buffer
, "Vendor Id: 0x%x\n", codec
->vendor_id
);
518 snd_iprintf(buffer
, "Subsystem Id: 0x%x\n", codec
->subsystem_id
);
519 snd_iprintf(buffer
, "Revision Id: 0x%x\n", codec
->revision_id
);
522 snd_iprintf(buffer
, "Modem Function Group: 0x%x\n", codec
->mfg
);
524 snd_iprintf(buffer
, "No Modem Function Group found\n");
528 snd_hda_power_up(codec
);
529 snd_iprintf(buffer
, "Default PCM:\n");
530 print_pcm_caps(buffer
, codec
, codec
->afg
);
531 snd_iprintf(buffer
, "Default Amp-In caps: ");
532 print_amp_caps(buffer
, codec
, codec
->afg
, HDA_INPUT
);
533 snd_iprintf(buffer
, "Default Amp-Out caps: ");
534 print_amp_caps(buffer
, codec
, codec
->afg
, HDA_OUTPUT
);
536 nodes
= snd_hda_get_sub_nodes(codec
, codec
->afg
, &nid
);
537 if (! nid
|| nodes
< 0) {
538 snd_iprintf(buffer
, "Invalid AFG subtree\n");
539 snd_hda_power_down(codec
);
543 print_gpio(buffer
, codec
, codec
->afg
);
545 for (i
= 0; i
< nodes
; i
++, nid
++) {
546 unsigned int wid_caps
=
547 snd_hda_param_read(codec
, nid
,
548 AC_PAR_AUDIO_WIDGET_CAP
);
549 unsigned int wid_type
=
550 (wid_caps
& AC_WCAP_TYPE
) >> AC_WCAP_TYPE_SHIFT
;
551 hda_nid_t conn
[HDA_MAX_CONNECTIONS
];
554 snd_iprintf(buffer
, "Node 0x%02x [%s] wcaps 0x%x:", nid
,
555 get_wid_type_name(wid_type
), wid_caps
);
556 if (wid_caps
& AC_WCAP_STEREO
)
557 snd_iprintf(buffer
, " Stereo");
559 snd_iprintf(buffer
, " Mono");
560 if (wid_caps
& AC_WCAP_DIGITAL
)
561 snd_iprintf(buffer
, " Digital");
562 if (wid_caps
& AC_WCAP_IN_AMP
)
563 snd_iprintf(buffer
, " Amp-In");
564 if (wid_caps
& AC_WCAP_OUT_AMP
)
565 snd_iprintf(buffer
, " Amp-Out");
566 if (wid_caps
& AC_WCAP_STRIPE
)
567 snd_iprintf(buffer
, " Stripe");
568 if (wid_caps
& AC_WCAP_LR_SWAP
)
569 snd_iprintf(buffer
, " R/L");
570 snd_iprintf(buffer
, "\n");
572 /* volume knob is a special widget that always have connection
575 if (wid_type
== AC_WID_VOL_KNB
)
576 wid_caps
|= AC_WCAP_CONN_LIST
;
578 if (wid_caps
& AC_WCAP_CONN_LIST
)
579 conn_len
= snd_hda_get_connections(codec
, nid
, conn
,
580 HDA_MAX_CONNECTIONS
);
582 if (wid_caps
& AC_WCAP_IN_AMP
) {
583 snd_iprintf(buffer
, " Amp-In caps: ");
584 print_amp_caps(buffer
, codec
, nid
, HDA_INPUT
);
585 snd_iprintf(buffer
, " Amp-In vals: ");
586 print_amp_vals(buffer
, codec
, nid
, HDA_INPUT
,
587 wid_caps
& AC_WCAP_STEREO
, conn_len
);
589 if (wid_caps
& AC_WCAP_OUT_AMP
) {
590 snd_iprintf(buffer
, " Amp-Out caps: ");
591 print_amp_caps(buffer
, codec
, nid
, HDA_OUTPUT
);
592 snd_iprintf(buffer
, " Amp-Out vals: ");
593 print_amp_vals(buffer
, codec
, nid
, HDA_OUTPUT
,
594 wid_caps
& AC_WCAP_STEREO
, 1);
600 print_pin_caps(buffer
, codec
, nid
, &supports_vref
);
601 print_pin_ctls(buffer
, codec
, nid
, supports_vref
);
605 print_vol_knob(buffer
, codec
, nid
);
609 print_audio_io(buffer
, codec
, nid
, wid_type
);
610 if (wid_caps
& AC_WCAP_DIGITAL
)
611 print_digital_conv(buffer
, codec
, nid
);
612 if (wid_caps
& AC_WCAP_FORMAT_OVRD
) {
613 snd_iprintf(buffer
, " PCM:\n");
614 print_pcm_caps(buffer
, codec
, nid
);
619 if (wid_caps
& AC_WCAP_UNSOL_CAP
)
620 print_unsol_cap(buffer
, codec
, nid
);
622 if (wid_caps
& AC_WCAP_POWER
)
623 print_power_state(buffer
, codec
, nid
);
625 if (wid_caps
& AC_WCAP_DELAY
)
626 snd_iprintf(buffer
, " Delay: %d samples\n",
627 (wid_caps
& AC_WCAP_DELAY
) >>
628 AC_WCAP_DELAY_SHIFT
);
630 if (wid_caps
& AC_WCAP_CONN_LIST
)
631 print_conn_list(buffer
, codec
, nid
, wid_type
,
634 if (wid_caps
& AC_WCAP_PROC_WID
)
635 print_proc_caps(buffer
, codec
, nid
);
637 /* NID 0x20 == Realtek Define Registers */
638 if (codec
->vendor_id
== 0x10ec && nid
== 0x20)
639 print_realtek_coef(buffer
, codec
, nid
);
641 snd_hda_power_down(codec
);
647 int snd_hda_codec_proc_new(struct hda_codec
*codec
)
650 struct snd_info_entry
*entry
;
653 snprintf(name
, sizeof(name
), "codec#%d", codec
->addr
);
654 err
= snd_card_proc_new(codec
->bus
->card
, name
, &entry
);
658 snd_info_set_text_ops(entry
, codec
, print_codec_info
);