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 char *bits_names(unsigned int bits
, char *names
[], int size
)
34 for (i
= 0, n
= 0; i
< size
; i
++) {
35 if (bits
& (1U<<i
) && names
[i
])
36 n
+= snprintf(buf
+ n
, sizeof(buf
) - n
, " %s",
44 static const char *get_wid_type_name(unsigned int wid_value
)
46 static char *names
[16] = {
47 [AC_WID_AUD_OUT
] = "Audio Output",
48 [AC_WID_AUD_IN
] = "Audio Input",
49 [AC_WID_AUD_MIX
] = "Audio Mixer",
50 [AC_WID_AUD_SEL
] = "Audio Selector",
51 [AC_WID_PIN
] = "Pin Complex",
52 [AC_WID_POWER
] = "Power Widget",
53 [AC_WID_VOL_KNB
] = "Volume Knob Widget",
54 [AC_WID_BEEP
] = "Beep Generator Widget",
55 [AC_WID_VENDOR
] = "Vendor Defined Widget",
59 return names
[wid_value
];
61 return "UNKNOWN Widget";
64 static void print_nid_array(struct snd_info_buffer
*buffer
,
65 struct hda_codec
*codec
, hda_nid_t nid
,
66 struct snd_array
*array
)
69 struct hda_nid_item
*items
= array
->list
, *item
;
70 struct snd_kcontrol
*kctl
;
71 for (i
= 0; i
< array
->used
; i
++) {
73 if (item
->nid
== nid
) {
76 " Control: name=\"%s\", index=%i, device=%i\n",
77 kctl
->id
.name
, kctl
->id
.index
+ item
->index
,
83 static void print_nid_pcms(struct snd_info_buffer
*buffer
,
84 struct hda_codec
*codec
, hda_nid_t nid
)
88 for (pcm
= 0; pcm
< codec
->num_pcms
; pcm
++) {
89 cpcm
= &codec
->pcm_info
[pcm
];
90 for (type
= 0; type
< 2; type
++) {
91 if (cpcm
->stream
[type
].nid
!= nid
|| cpcm
->pcm
== NULL
)
93 snd_iprintf(buffer
, " Device: name=\"%s\", "
94 "type=\"%s\", device=%i\n",
96 snd_hda_pcm_type_name
[cpcm
->pcm_type
],
102 static void print_amp_caps(struct snd_info_buffer
*buffer
,
103 struct hda_codec
*codec
, hda_nid_t nid
, int dir
)
106 caps
= snd_hda_param_read(codec
, nid
,
108 AC_PAR_AMP_OUT_CAP
: AC_PAR_AMP_IN_CAP
);
109 if (caps
== -1 || caps
== 0) {
110 snd_iprintf(buffer
, "N/A\n");
113 snd_iprintf(buffer
, "ofs=0x%02x, nsteps=0x%02x, stepsize=0x%02x, "
115 caps
& AC_AMPCAP_OFFSET
,
116 (caps
& AC_AMPCAP_NUM_STEPS
) >> AC_AMPCAP_NUM_STEPS_SHIFT
,
117 (caps
& AC_AMPCAP_STEP_SIZE
) >> AC_AMPCAP_STEP_SIZE_SHIFT
,
118 (caps
& AC_AMPCAP_MUTE
) >> AC_AMPCAP_MUTE_SHIFT
);
121 static void print_amp_vals(struct snd_info_buffer
*buffer
,
122 struct hda_codec
*codec
, hda_nid_t nid
,
123 int dir
, int stereo
, int indices
)
128 dir
= dir
== HDA_OUTPUT
? AC_AMP_GET_OUTPUT
: AC_AMP_GET_INPUT
;
129 for (i
= 0; i
< indices
; i
++) {
130 snd_iprintf(buffer
, " [");
132 val
= snd_hda_codec_read(codec
, nid
, 0,
133 AC_VERB_GET_AMP_GAIN_MUTE
,
134 AC_AMP_GET_LEFT
| dir
| i
);
135 snd_iprintf(buffer
, "0x%02x ", val
);
137 val
= snd_hda_codec_read(codec
, nid
, 0,
138 AC_VERB_GET_AMP_GAIN_MUTE
,
139 AC_AMP_GET_RIGHT
| dir
| i
);
140 snd_iprintf(buffer
, "0x%02x]", val
);
142 snd_iprintf(buffer
, "\n");
145 static void print_pcm_rates(struct snd_info_buffer
*buffer
, unsigned int pcm
)
147 char buf
[SND_PRINT_RATES_ADVISED_BUFSIZE
];
149 pcm
&= AC_SUPPCM_RATES
;
150 snd_iprintf(buffer
, " rates [0x%x]:", pcm
);
151 snd_print_pcm_rates(pcm
, buf
, sizeof(buf
));
152 snd_iprintf(buffer
, "%s\n", buf
);
155 static void print_pcm_bits(struct snd_info_buffer
*buffer
, unsigned int pcm
)
157 char buf
[SND_PRINT_BITS_ADVISED_BUFSIZE
];
159 snd_iprintf(buffer
, " bits [0x%x]:", (pcm
>> 16) & 0xff);
160 snd_print_pcm_bits(pcm
, buf
, sizeof(buf
));
161 snd_iprintf(buffer
, "%s\n", buf
);
164 static void print_pcm_formats(struct snd_info_buffer
*buffer
,
165 unsigned int streams
)
167 snd_iprintf(buffer
, " formats [0x%x]:", streams
& 0xf);
168 if (streams
& AC_SUPFMT_PCM
)
169 snd_iprintf(buffer
, " PCM");
170 if (streams
& AC_SUPFMT_FLOAT32
)
171 snd_iprintf(buffer
, " FLOAT");
172 if (streams
& AC_SUPFMT_AC3
)
173 snd_iprintf(buffer
, " AC3");
174 snd_iprintf(buffer
, "\n");
177 static void print_pcm_caps(struct snd_info_buffer
*buffer
,
178 struct hda_codec
*codec
, hda_nid_t nid
)
180 unsigned int pcm
= snd_hda_param_read(codec
, nid
, AC_PAR_PCM
);
181 unsigned int stream
= snd_hda_param_read(codec
, nid
, AC_PAR_STREAM
);
182 if (pcm
== -1 || stream
== -1) {
183 snd_iprintf(buffer
, "N/A\n");
186 print_pcm_rates(buffer
, pcm
);
187 print_pcm_bits(buffer
, pcm
);
188 print_pcm_formats(buffer
, stream
);
191 static const char *get_jack_connection(u32 cfg
)
193 static char *names
[16] = {
194 "Unknown", "1/8", "1/4", "ATAPI",
195 "RCA", "Optical","Digital", "Analog",
196 "DIN", "XLR", "RJ11", "Comb",
197 NULL
, NULL
, NULL
, "Other"
199 cfg
= (cfg
& AC_DEFCFG_CONN_TYPE
) >> AC_DEFCFG_CONN_TYPE_SHIFT
;
206 static const char *get_jack_color(u32 cfg
)
208 static char *names
[16] = {
209 "Unknown", "Black", "Grey", "Blue",
210 "Green", "Red", "Orange", "Yellow",
211 "Purple", "Pink", NULL
, NULL
,
212 NULL
, NULL
, "White", "Other",
214 cfg
= (cfg
& AC_DEFCFG_COLOR
) >> AC_DEFCFG_COLOR_SHIFT
;
221 static void print_pin_caps(struct snd_info_buffer
*buffer
,
222 struct hda_codec
*codec
, hda_nid_t nid
,
225 static char *jack_conns
[4] = { "Jack", "N/A", "Fixed", "Both" };
226 unsigned int caps
, val
;
228 caps
= snd_hda_param_read(codec
, nid
, AC_PAR_PIN_CAP
);
229 snd_iprintf(buffer
, " Pincap 0x%08x:", caps
);
230 if (caps
& AC_PINCAP_IN
)
231 snd_iprintf(buffer
, " IN");
232 if (caps
& AC_PINCAP_OUT
)
233 snd_iprintf(buffer
, " OUT");
234 if (caps
& AC_PINCAP_HP_DRV
)
235 snd_iprintf(buffer
, " HP");
236 if (caps
& AC_PINCAP_EAPD
)
237 snd_iprintf(buffer
, " EAPD");
238 if (caps
& AC_PINCAP_PRES_DETECT
)
239 snd_iprintf(buffer
, " Detect");
240 if (caps
& AC_PINCAP_BALANCE
)
241 snd_iprintf(buffer
, " Balanced");
242 if (caps
& AC_PINCAP_HDMI
) {
243 /* Realtek uses this bit as a different meaning */
244 if ((codec
->vendor_id
>> 16) == 0x10ec)
245 snd_iprintf(buffer
, " R/L");
247 if (caps
& AC_PINCAP_HBR
)
248 snd_iprintf(buffer
, " HBR");
249 snd_iprintf(buffer
, " HDMI");
252 if (caps
& AC_PINCAP_DP
)
253 snd_iprintf(buffer
, " DP");
254 if (caps
& AC_PINCAP_TRIG_REQ
)
255 snd_iprintf(buffer
, " Trigger");
256 if (caps
& AC_PINCAP_IMP_SENSE
)
257 snd_iprintf(buffer
, " ImpSense");
258 snd_iprintf(buffer
, "\n");
259 if (caps
& AC_PINCAP_VREF
) {
261 (caps
& AC_PINCAP_VREF
) >> AC_PINCAP_VREF_SHIFT
;
262 snd_iprintf(buffer
, " Vref caps:");
263 if (vref
& AC_PINCAP_VREF_HIZ
)
264 snd_iprintf(buffer
, " HIZ");
265 if (vref
& AC_PINCAP_VREF_50
)
266 snd_iprintf(buffer
, " 50");
267 if (vref
& AC_PINCAP_VREF_GRD
)
268 snd_iprintf(buffer
, " GRD");
269 if (vref
& AC_PINCAP_VREF_80
)
270 snd_iprintf(buffer
, " 80");
271 if (vref
& AC_PINCAP_VREF_100
)
272 snd_iprintf(buffer
, " 100");
273 snd_iprintf(buffer
, "\n");
277 if (caps
& AC_PINCAP_EAPD
) {
278 val
= snd_hda_codec_read(codec
, nid
, 0,
279 AC_VERB_GET_EAPD_BTLENABLE
, 0);
280 snd_iprintf(buffer
, " EAPD 0x%x:", val
);
281 if (val
& AC_EAPDBTL_BALANCED
)
282 snd_iprintf(buffer
, " BALANCED");
283 if (val
& AC_EAPDBTL_EAPD
)
284 snd_iprintf(buffer
, " EAPD");
285 if (val
& AC_EAPDBTL_LR_SWAP
)
286 snd_iprintf(buffer
, " R/L");
287 snd_iprintf(buffer
, "\n");
289 caps
= snd_hda_codec_read(codec
, nid
, 0, AC_VERB_GET_CONFIG_DEFAULT
, 0);
290 snd_iprintf(buffer
, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps
,
291 jack_conns
[(caps
& AC_DEFCFG_PORT_CONN
) >> AC_DEFCFG_PORT_CONN_SHIFT
],
292 snd_hda_get_jack_type(caps
),
293 snd_hda_get_jack_connectivity(caps
),
294 snd_hda_get_jack_location(caps
));
295 snd_iprintf(buffer
, " Conn = %s, Color = %s\n",
296 get_jack_connection(caps
),
297 get_jack_color(caps
));
298 /* Default association and sequence values refer to default grouping
299 * of pin complexes and their sequence within the group. This is used
300 * for priority and resource allocation.
302 snd_iprintf(buffer
, " DefAssociation = 0x%x, Sequence = 0x%x\n",
303 (caps
& AC_DEFCFG_DEF_ASSOC
) >> AC_DEFCFG_ASSOC_SHIFT
,
304 caps
& AC_DEFCFG_SEQUENCE
);
305 if (((caps
& AC_DEFCFG_MISC
) >> AC_DEFCFG_MISC_SHIFT
) &
306 AC_DEFCFG_MISC_NO_PRESENCE
) {
307 /* Miscellaneous bit indicates external hardware does not
308 * support presence detection even if the pin complex
309 * indicates it is supported.
311 snd_iprintf(buffer
, " Misc = NO_PRESENCE\n");
315 static void print_pin_ctls(struct snd_info_buffer
*buffer
,
316 struct hda_codec
*codec
, hda_nid_t nid
,
319 unsigned int pinctls
;
321 pinctls
= snd_hda_codec_read(codec
, nid
, 0,
322 AC_VERB_GET_PIN_WIDGET_CONTROL
, 0);
323 snd_iprintf(buffer
, " Pin-ctls: 0x%02x:", pinctls
);
324 if (pinctls
& AC_PINCTL_IN_EN
)
325 snd_iprintf(buffer
, " IN");
326 if (pinctls
& AC_PINCTL_OUT_EN
)
327 snd_iprintf(buffer
, " OUT");
328 if (pinctls
& AC_PINCTL_HP_EN
)
329 snd_iprintf(buffer
, " HP");
331 int vref
= pinctls
& AC_PINCTL_VREFEN
;
333 case AC_PINCTL_VREF_HIZ
:
334 snd_iprintf(buffer
, " VREF_HIZ");
336 case AC_PINCTL_VREF_50
:
337 snd_iprintf(buffer
, " VREF_50");
339 case AC_PINCTL_VREF_GRD
:
340 snd_iprintf(buffer
, " VREF_GRD");
342 case AC_PINCTL_VREF_80
:
343 snd_iprintf(buffer
, " VREF_80");
345 case AC_PINCTL_VREF_100
:
346 snd_iprintf(buffer
, " VREF_100");
350 snd_iprintf(buffer
, "\n");
353 static void print_vol_knob(struct snd_info_buffer
*buffer
,
354 struct hda_codec
*codec
, hda_nid_t nid
)
356 unsigned int cap
= snd_hda_param_read(codec
, nid
,
358 snd_iprintf(buffer
, " Volume-Knob: delta=%d, steps=%d, ",
359 (cap
>> 7) & 1, cap
& 0x7f);
360 cap
= snd_hda_codec_read(codec
, nid
, 0,
361 AC_VERB_GET_VOLUME_KNOB_CONTROL
, 0);
362 snd_iprintf(buffer
, "direct=%d, val=%d\n",
363 (cap
>> 7) & 1, cap
& 0x7f);
366 static void print_audio_io(struct snd_info_buffer
*buffer
,
367 struct hda_codec
*codec
, hda_nid_t nid
,
368 unsigned int wid_type
)
370 int conv
= snd_hda_codec_read(codec
, nid
, 0, AC_VERB_GET_CONV
, 0);
372 " Converter: stream=%d, channel=%d\n",
373 (conv
& AC_CONV_STREAM
) >> AC_CONV_STREAM_SHIFT
,
374 conv
& AC_CONV_CHANNEL
);
376 if (wid_type
== AC_WID_AUD_IN
&& (conv
& AC_CONV_CHANNEL
) == 0) {
377 int sdi
= snd_hda_codec_read(codec
, nid
, 0,
378 AC_VERB_GET_SDI_SELECT
, 0);
379 snd_iprintf(buffer
, " SDI-Select: %d\n",
380 sdi
& AC_SDI_SELECT
);
384 static void print_digital_conv(struct snd_info_buffer
*buffer
,
385 struct hda_codec
*codec
, hda_nid_t nid
)
387 unsigned int digi1
= snd_hda_codec_read(codec
, nid
, 0,
388 AC_VERB_GET_DIGI_CONVERT_1
, 0);
389 snd_iprintf(buffer
, " Digital:");
390 if (digi1
& AC_DIG1_ENABLE
)
391 snd_iprintf(buffer
, " Enabled");
392 if (digi1
& AC_DIG1_V
)
393 snd_iprintf(buffer
, " Validity");
394 if (digi1
& AC_DIG1_VCFG
)
395 snd_iprintf(buffer
, " ValidityCfg");
396 if (digi1
& AC_DIG1_EMPHASIS
)
397 snd_iprintf(buffer
, " Preemphasis");
398 if (digi1
& AC_DIG1_COPYRIGHT
)
399 snd_iprintf(buffer
, " Copyright");
400 if (digi1
& AC_DIG1_NONAUDIO
)
401 snd_iprintf(buffer
, " Non-Audio");
402 if (digi1
& AC_DIG1_PROFESSIONAL
)
403 snd_iprintf(buffer
, " Pro");
404 if (digi1
& AC_DIG1_LEVEL
)
405 snd_iprintf(buffer
, " GenLevel");
406 snd_iprintf(buffer
, "\n");
407 snd_iprintf(buffer
, " Digital category: 0x%x\n",
408 (digi1
>> 8) & AC_DIG2_CC
);
411 static const char *get_pwr_state(u32 state
)
413 static const char *buf
[4] = {
414 "D0", "D1", "D2", "D3"
421 static void print_power_state(struct snd_info_buffer
*buffer
,
422 struct hda_codec
*codec
, hda_nid_t nid
)
424 static char *names
[] = {
425 [ilog2(AC_PWRST_D0SUP
)] = "D0",
426 [ilog2(AC_PWRST_D1SUP
)] = "D1",
427 [ilog2(AC_PWRST_D2SUP
)] = "D2",
428 [ilog2(AC_PWRST_D3SUP
)] = "D3",
429 [ilog2(AC_PWRST_D3COLDSUP
)] = "D3cold",
430 [ilog2(AC_PWRST_S3D3COLDSUP
)] = "S3D3cold",
431 [ilog2(AC_PWRST_CLKSTOP
)] = "CLKSTOP",
432 [ilog2(AC_PWRST_EPSS
)] = "EPSS",
435 int sup
= snd_hda_param_read(codec
, nid
, AC_PAR_POWER_STATE
);
436 int pwr
= snd_hda_codec_read(codec
, nid
, 0,
437 AC_VERB_GET_POWER_STATE
, 0);
439 snd_iprintf(buffer
, " Power states: %s\n",
440 bits_names(sup
, names
, ARRAY_SIZE(names
)));
442 snd_iprintf(buffer
, " Power: setting=%s, actual=%s\n",
443 get_pwr_state(pwr
& AC_PWRST_SETTING
),
444 get_pwr_state((pwr
& AC_PWRST_ACTUAL
) >>
445 AC_PWRST_ACTUAL_SHIFT
));
448 static void print_unsol_cap(struct snd_info_buffer
*buffer
,
449 struct hda_codec
*codec
, hda_nid_t nid
)
451 int unsol
= snd_hda_codec_read(codec
, nid
, 0,
452 AC_VERB_GET_UNSOLICITED_RESPONSE
, 0);
454 " Unsolicited: tag=%02x, enabled=%d\n",
455 unsol
& AC_UNSOL_TAG
,
456 (unsol
& AC_UNSOL_ENABLED
) ? 1 : 0);
459 static void print_proc_caps(struct snd_info_buffer
*buffer
,
460 struct hda_codec
*codec
, hda_nid_t nid
)
462 unsigned int proc_caps
= snd_hda_param_read(codec
, nid
,
464 snd_iprintf(buffer
, " Processing caps: benign=%d, ncoeff=%d\n",
465 proc_caps
& AC_PCAP_BENIGN
,
466 (proc_caps
& AC_PCAP_NUM_COEF
) >> AC_PCAP_NUM_COEF_SHIFT
);
469 static void print_conn_list(struct snd_info_buffer
*buffer
,
470 struct hda_codec
*codec
, hda_nid_t nid
,
471 unsigned int wid_type
, hda_nid_t
*conn
,
477 wid_type
!= AC_WID_AUD_MIX
&&
478 wid_type
!= AC_WID_VOL_KNB
&&
479 wid_type
!= AC_WID_POWER
)
480 curr
= snd_hda_codec_read(codec
, nid
, 0,
481 AC_VERB_GET_CONNECT_SEL
, 0);
482 snd_iprintf(buffer
, " Connection: %d\n", conn_len
);
484 snd_iprintf(buffer
, " ");
485 for (c
= 0; c
< conn_len
; c
++) {
486 snd_iprintf(buffer
, " 0x%02x", conn
[c
]);
488 snd_iprintf(buffer
, "*");
490 snd_iprintf(buffer
, "\n");
494 static void print_gpio(struct snd_info_buffer
*buffer
,
495 struct hda_codec
*codec
, hda_nid_t nid
)
498 snd_hda_param_read(codec
, codec
->afg
, AC_PAR_GPIO_CAP
);
499 unsigned int enable
, direction
, wake
, unsol
, sticky
, data
;
501 snd_iprintf(buffer
, "GPIO: io=%d, o=%d, i=%d, "
502 "unsolicited=%d, wake=%d\n",
503 gpio
& AC_GPIO_IO_COUNT
,
504 (gpio
& AC_GPIO_O_COUNT
) >> AC_GPIO_O_COUNT_SHIFT
,
505 (gpio
& AC_GPIO_I_COUNT
) >> AC_GPIO_I_COUNT_SHIFT
,
506 (gpio
& AC_GPIO_UNSOLICITED
) ? 1 : 0,
507 (gpio
& AC_GPIO_WAKE
) ? 1 : 0);
508 max
= gpio
& AC_GPIO_IO_COUNT
;
511 enable
= snd_hda_codec_read(codec
, nid
, 0,
512 AC_VERB_GET_GPIO_MASK
, 0);
513 direction
= snd_hda_codec_read(codec
, nid
, 0,
514 AC_VERB_GET_GPIO_DIRECTION
, 0);
515 wake
= snd_hda_codec_read(codec
, nid
, 0,
516 AC_VERB_GET_GPIO_WAKE_MASK
, 0);
517 unsol
= snd_hda_codec_read(codec
, nid
, 0,
518 AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK
, 0);
519 sticky
= snd_hda_codec_read(codec
, nid
, 0,
520 AC_VERB_GET_GPIO_STICKY_MASK
, 0);
521 data
= snd_hda_codec_read(codec
, nid
, 0,
522 AC_VERB_GET_GPIO_DATA
, 0);
523 for (i
= 0; i
< max
; ++i
)
525 " IO[%d]: enable=%d, dir=%d, wake=%d, "
526 "sticky=%d, data=%d, unsol=%d\n", i
,
527 (enable
& (1<<i
)) ? 1 : 0,
528 (direction
& (1<<i
)) ? 1 : 0,
529 (wake
& (1<<i
)) ? 1 : 0,
530 (sticky
& (1<<i
)) ? 1 : 0,
531 (data
& (1<<i
)) ? 1 : 0,
532 (unsol
& (1<<i
)) ? 1 : 0);
533 /* FIXME: add GPO and GPI pin information */
534 print_nid_array(buffer
, codec
, nid
, &codec
->mixers
);
535 print_nid_array(buffer
, codec
, nid
, &codec
->nids
);
538 static void print_codec_info(struct snd_info_entry
*entry
,
539 struct snd_info_buffer
*buffer
)
541 struct hda_codec
*codec
= entry
->private_data
;
545 snd_iprintf(buffer
, "Codec: ");
546 if (codec
->vendor_name
&& codec
->chip_name
)
547 snd_iprintf(buffer
, "%s %s\n",
548 codec
->vendor_name
, codec
->chip_name
);
550 snd_iprintf(buffer
, "Not Set\n");
551 snd_iprintf(buffer
, "Address: %d\n", codec
->addr
);
552 snd_iprintf(buffer
, "Function Id: 0x%x\n", codec
->function_id
);
553 snd_iprintf(buffer
, "Vendor Id: 0x%08x\n", codec
->vendor_id
);
554 snd_iprintf(buffer
, "Subsystem Id: 0x%08x\n", codec
->subsystem_id
);
555 snd_iprintf(buffer
, "Revision Id: 0x%x\n", codec
->revision_id
);
558 snd_iprintf(buffer
, "Modem Function Group: 0x%x\n", codec
->mfg
);
560 snd_iprintf(buffer
, "No Modem Function Group found\n");
564 snd_hda_power_up(codec
);
565 snd_iprintf(buffer
, "Default PCM:\n");
566 print_pcm_caps(buffer
, codec
, codec
->afg
);
567 snd_iprintf(buffer
, "Default Amp-In caps: ");
568 print_amp_caps(buffer
, codec
, codec
->afg
, HDA_INPUT
);
569 snd_iprintf(buffer
, "Default Amp-Out caps: ");
570 print_amp_caps(buffer
, codec
, codec
->afg
, HDA_OUTPUT
);
572 nodes
= snd_hda_get_sub_nodes(codec
, codec
->afg
, &nid
);
573 if (! nid
|| nodes
< 0) {
574 snd_iprintf(buffer
, "Invalid AFG subtree\n");
575 snd_hda_power_down(codec
);
579 print_gpio(buffer
, codec
, codec
->afg
);
580 if (codec
->proc_widget_hook
)
581 codec
->proc_widget_hook(buffer
, codec
, codec
->afg
);
583 for (i
= 0; i
< nodes
; i
++, nid
++) {
584 unsigned int wid_caps
=
585 snd_hda_param_read(codec
, nid
,
586 AC_PAR_AUDIO_WIDGET_CAP
);
587 unsigned int wid_type
= get_wcaps_type(wid_caps
);
588 hda_nid_t conn
[HDA_MAX_CONNECTIONS
];
591 snd_iprintf(buffer
, "Node 0x%02x [%s] wcaps 0x%x:", nid
,
592 get_wid_type_name(wid_type
), wid_caps
);
593 if (wid_caps
& AC_WCAP_STEREO
) {
594 unsigned int chans
= get_wcaps_channels(wid_caps
);
596 snd_iprintf(buffer
, " Stereo");
598 snd_iprintf(buffer
, " %d-Channels", chans
);
600 snd_iprintf(buffer
, " Mono");
601 if (wid_caps
& AC_WCAP_DIGITAL
)
602 snd_iprintf(buffer
, " Digital");
603 if (wid_caps
& AC_WCAP_IN_AMP
)
604 snd_iprintf(buffer
, " Amp-In");
605 if (wid_caps
& AC_WCAP_OUT_AMP
)
606 snd_iprintf(buffer
, " Amp-Out");
607 if (wid_caps
& AC_WCAP_STRIPE
)
608 snd_iprintf(buffer
, " Stripe");
609 if (wid_caps
& AC_WCAP_LR_SWAP
)
610 snd_iprintf(buffer
, " R/L");
611 if (wid_caps
& AC_WCAP_CP_CAPS
)
612 snd_iprintf(buffer
, " CP");
613 snd_iprintf(buffer
, "\n");
615 print_nid_array(buffer
, codec
, nid
, &codec
->mixers
);
616 print_nid_array(buffer
, codec
, nid
, &codec
->nids
);
617 print_nid_pcms(buffer
, codec
, nid
);
619 /* volume knob is a special widget that always have connection
622 if (wid_type
== AC_WID_VOL_KNB
)
623 wid_caps
|= AC_WCAP_CONN_LIST
;
625 if (wid_caps
& AC_WCAP_CONN_LIST
)
626 conn_len
= snd_hda_get_connections(codec
, nid
, conn
,
627 HDA_MAX_CONNECTIONS
);
629 if (wid_caps
& AC_WCAP_IN_AMP
) {
630 snd_iprintf(buffer
, " Amp-In caps: ");
631 print_amp_caps(buffer
, codec
, nid
, HDA_INPUT
);
632 snd_iprintf(buffer
, " Amp-In vals: ");
633 print_amp_vals(buffer
, codec
, nid
, HDA_INPUT
,
634 wid_caps
& AC_WCAP_STEREO
,
635 wid_type
== AC_WID_PIN
? 1 : conn_len
);
637 if (wid_caps
& AC_WCAP_OUT_AMP
) {
638 snd_iprintf(buffer
, " Amp-Out caps: ");
639 print_amp_caps(buffer
, codec
, nid
, HDA_OUTPUT
);
640 snd_iprintf(buffer
, " Amp-Out vals: ");
641 if (wid_type
== AC_WID_PIN
&&
642 codec
->pin_amp_workaround
)
643 print_amp_vals(buffer
, codec
, nid
, HDA_OUTPUT
,
644 wid_caps
& AC_WCAP_STEREO
,
647 print_amp_vals(buffer
, codec
, nid
, HDA_OUTPUT
,
648 wid_caps
& AC_WCAP_STEREO
, 1);
654 print_pin_caps(buffer
, codec
, nid
, &supports_vref
);
655 print_pin_ctls(buffer
, codec
, nid
, supports_vref
);
659 print_vol_knob(buffer
, codec
, nid
);
663 print_audio_io(buffer
, codec
, nid
, wid_type
);
664 if (wid_caps
& AC_WCAP_DIGITAL
)
665 print_digital_conv(buffer
, codec
, nid
);
666 if (wid_caps
& AC_WCAP_FORMAT_OVRD
) {
667 snd_iprintf(buffer
, " PCM:\n");
668 print_pcm_caps(buffer
, codec
, nid
);
673 if (wid_caps
& AC_WCAP_UNSOL_CAP
)
674 print_unsol_cap(buffer
, codec
, nid
);
676 if (wid_caps
& AC_WCAP_POWER
)
677 print_power_state(buffer
, codec
, nid
);
679 if (wid_caps
& AC_WCAP_DELAY
)
680 snd_iprintf(buffer
, " Delay: %d samples\n",
681 (wid_caps
& AC_WCAP_DELAY
) >>
682 AC_WCAP_DELAY_SHIFT
);
684 if (wid_caps
& AC_WCAP_CONN_LIST
)
685 print_conn_list(buffer
, codec
, nid
, wid_type
,
688 if (wid_caps
& AC_WCAP_PROC_WID
)
689 print_proc_caps(buffer
, codec
, nid
);
691 if (codec
->proc_widget_hook
)
692 codec
->proc_widget_hook(buffer
, codec
, nid
);
694 snd_hda_power_down(codec
);
700 int snd_hda_codec_proc_new(struct hda_codec
*codec
)
703 struct snd_info_entry
*entry
;
706 snprintf(name
, sizeof(name
), "codec#%d", codec
->addr
);
707 err
= snd_card_proc_new(codec
->bus
->card
, name
, &entry
);
711 snd_info_set_text_ops(entry
, codec
, print_codec_info
);