1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Universal Interface for Intel High Definition Audio Codec
5 * Generic proc interface
7 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
10 #include <linux/init.h>
11 #include <linux/slab.h>
12 #include <sound/core.h>
13 #include <linux/module.h>
14 #include <sound/hda_codec.h>
15 #include "hda_local.h"
17 static int dump_coef
= -1;
18 module_param(dump_coef
, int, 0644);
19 MODULE_PARM_DESC(dump_coef
, "Dump processing coefficients in codec proc file (-1=auto, 0=disable, 1=enable)");
21 /* always use noncached version */
22 #define param_read(codec, nid, parm) \
23 snd_hdac_read_parm_uncached(&(codec)->core, nid, parm)
25 static const char *get_wid_type_name(unsigned int wid_value
)
27 static const char * const names
[16] = {
28 [AC_WID_AUD_OUT
] = "Audio Output",
29 [AC_WID_AUD_IN
] = "Audio Input",
30 [AC_WID_AUD_MIX
] = "Audio Mixer",
31 [AC_WID_AUD_SEL
] = "Audio Selector",
32 [AC_WID_PIN
] = "Pin Complex",
33 [AC_WID_POWER
] = "Power Widget",
34 [AC_WID_VOL_KNB
] = "Volume Knob Widget",
35 [AC_WID_BEEP
] = "Beep Generator Widget",
36 [AC_WID_VENDOR
] = "Vendor Defined Widget",
39 return "UNKNOWN Widget";
42 return names
[wid_value
];
44 return "UNKNOWN Widget";
47 static void print_nid_array(struct snd_info_buffer
*buffer
,
48 struct hda_codec
*codec
, hda_nid_t nid
,
49 struct snd_array
*array
)
52 struct hda_nid_item
*items
= array
->list
, *item
;
53 struct snd_kcontrol
*kctl
;
54 for (i
= 0; i
< array
->used
; i
++) {
56 if (item
->nid
== nid
) {
59 " Control: name=\"%s\", index=%i, device=%i\n",
60 kctl
->id
.name
, kctl
->id
.index
+ item
->index
,
62 if (item
->flags
& HDA_NID_ITEM_AMP
)
64 " ControlAmp: chs=%lu, dir=%s, "
66 get_amp_channels(kctl
),
67 get_amp_direction(kctl
) ? "Out" : "In",
69 get_amp_offset(kctl
));
74 static void print_nid_pcms(struct snd_info_buffer
*buffer
,
75 struct hda_codec
*codec
, hda_nid_t nid
)
80 list_for_each_entry(cpcm
, &codec
->pcm_list_head
, list
) {
81 for (type
= 0; type
< 2; type
++) {
82 if (cpcm
->stream
[type
].nid
!= nid
|| cpcm
->pcm
== NULL
)
84 snd_iprintf(buffer
, " Device: name=\"%s\", "
85 "type=\"%s\", device=%i\n",
87 snd_hda_pcm_type_name
[cpcm
->pcm_type
],
93 static void print_amp_caps(struct snd_info_buffer
*buffer
,
94 struct hda_codec
*codec
, hda_nid_t nid
, int dir
)
97 caps
= param_read(codec
, nid
, dir
== HDA_OUTPUT
?
98 AC_PAR_AMP_OUT_CAP
: AC_PAR_AMP_IN_CAP
);
99 if (caps
== -1 || caps
== 0) {
100 snd_iprintf(buffer
, "N/A\n");
103 snd_iprintf(buffer
, "ofs=0x%02x, nsteps=0x%02x, stepsize=0x%02x, "
105 caps
& AC_AMPCAP_OFFSET
,
106 (caps
& AC_AMPCAP_NUM_STEPS
) >> AC_AMPCAP_NUM_STEPS_SHIFT
,
107 (caps
& AC_AMPCAP_STEP_SIZE
) >> AC_AMPCAP_STEP_SIZE_SHIFT
,
108 (caps
& AC_AMPCAP_MUTE
) >> AC_AMPCAP_MUTE_SHIFT
);
111 /* is this a stereo widget or a stereo-to-mono mix? */
112 static bool is_stereo_amps(struct hda_codec
*codec
, hda_nid_t nid
,
113 int dir
, unsigned int wcaps
, int indices
)
117 if (wcaps
& AC_WCAP_STEREO
)
119 /* check for a stereo-to-mono mix; it must be:
120 * only a single connection, only for input, and only a mixer widget
122 if (indices
!= 1 || dir
!= HDA_INPUT
||
123 get_wcaps_type(wcaps
) != AC_WID_AUD_MIX
)
126 if (snd_hda_get_raw_connections(codec
, nid
, &conn
, 1) < 0)
128 /* the connection source is a stereo? */
129 wcaps
= snd_hda_param_read(codec
, conn
, AC_PAR_AUDIO_WIDGET_CAP
);
130 return !!(wcaps
& AC_WCAP_STEREO
);
133 static void print_amp_vals(struct snd_info_buffer
*buffer
,
134 struct hda_codec
*codec
, hda_nid_t nid
,
135 int dir
, unsigned int wcaps
, int indices
)
141 stereo
= is_stereo_amps(codec
, nid
, dir
, wcaps
, indices
);
143 dir
= dir
== HDA_OUTPUT
? AC_AMP_GET_OUTPUT
: AC_AMP_GET_INPUT
;
144 for (i
= 0; i
< indices
; i
++) {
145 snd_iprintf(buffer
, " [");
146 val
= snd_hda_codec_read(codec
, nid
, 0,
147 AC_VERB_GET_AMP_GAIN_MUTE
,
148 AC_AMP_GET_LEFT
| dir
| i
);
149 snd_iprintf(buffer
, "0x%02x", val
);
151 val
= snd_hda_codec_read(codec
, nid
, 0,
152 AC_VERB_GET_AMP_GAIN_MUTE
,
153 AC_AMP_GET_RIGHT
| dir
| i
);
154 snd_iprintf(buffer
, " 0x%02x", val
);
156 snd_iprintf(buffer
, "]");
158 snd_iprintf(buffer
, "\n");
161 static void print_pcm_rates(struct snd_info_buffer
*buffer
, unsigned int pcm
)
163 static const unsigned int rates
[] = {
164 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
165 96000, 176400, 192000, 384000
169 pcm
&= AC_SUPPCM_RATES
;
170 snd_iprintf(buffer
, " rates [0x%x]:", pcm
);
171 for (i
= 0; i
< ARRAY_SIZE(rates
); i
++)
173 snd_iprintf(buffer
, " %d", rates
[i
]);
174 snd_iprintf(buffer
, "\n");
177 static void print_pcm_bits(struct snd_info_buffer
*buffer
, unsigned int pcm
)
179 char buf
[SND_PRINT_BITS_ADVISED_BUFSIZE
];
181 snd_iprintf(buffer
, " bits [0x%x]:", (pcm
>> 16) & 0xff);
182 snd_print_pcm_bits(pcm
, buf
, sizeof(buf
));
183 snd_iprintf(buffer
, "%s\n", buf
);
186 static void print_pcm_formats(struct snd_info_buffer
*buffer
,
187 unsigned int streams
)
189 snd_iprintf(buffer
, " formats [0x%x]:", streams
& 0xf);
190 if (streams
& AC_SUPFMT_PCM
)
191 snd_iprintf(buffer
, " PCM");
192 if (streams
& AC_SUPFMT_FLOAT32
)
193 snd_iprintf(buffer
, " FLOAT");
194 if (streams
& AC_SUPFMT_AC3
)
195 snd_iprintf(buffer
, " AC3");
196 snd_iprintf(buffer
, "\n");
199 static void print_pcm_caps(struct snd_info_buffer
*buffer
,
200 struct hda_codec
*codec
, hda_nid_t nid
)
202 unsigned int pcm
= param_read(codec
, nid
, AC_PAR_PCM
);
203 unsigned int stream
= param_read(codec
, nid
, AC_PAR_STREAM
);
204 if (pcm
== -1 || stream
== -1) {
205 snd_iprintf(buffer
, "N/A\n");
208 print_pcm_rates(buffer
, pcm
);
209 print_pcm_bits(buffer
, pcm
);
210 print_pcm_formats(buffer
, stream
);
213 static const char *get_jack_connection(u32 cfg
)
215 static const char * const names
[16] = {
216 "Unknown", "1/8", "1/4", "ATAPI",
217 "RCA", "Optical","Digital", "Analog",
218 "DIN", "XLR", "RJ11", "Comb",
219 NULL
, NULL
, NULL
, "Other"
221 cfg
= (cfg
& AC_DEFCFG_CONN_TYPE
) >> AC_DEFCFG_CONN_TYPE_SHIFT
;
228 static const char *get_jack_color(u32 cfg
)
230 static const char * const names
[16] = {
231 "Unknown", "Black", "Grey", "Blue",
232 "Green", "Red", "Orange", "Yellow",
233 "Purple", "Pink", NULL
, NULL
,
234 NULL
, NULL
, "White", "Other",
236 cfg
= (cfg
& AC_DEFCFG_COLOR
) >> AC_DEFCFG_COLOR_SHIFT
;
244 * Parse the pin default config value and returns the string of the
245 * jack location, e.g. "Rear", "Front", etc.
247 static const char *get_jack_location(u32 cfg
)
249 static const char * const bases
[7] = {
250 "N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom",
252 static const unsigned char specials_idx
[] = {
257 static const char * const specials
[] = {
258 "Rear Panel", "Drive Bar",
259 "Riser", "HDMI", "ATAPI",
260 "Mobile-In", "Mobile-Out"
264 cfg
= (cfg
& AC_DEFCFG_LOCATION
) >> AC_DEFCFG_LOCATION_SHIFT
;
265 if ((cfg
& 0x0f) < 7)
266 return bases
[cfg
& 0x0f];
267 for (i
= 0; i
< ARRAY_SIZE(specials_idx
); i
++) {
268 if (cfg
== specials_idx
[i
])
275 * Parse the pin default config value and returns the string of the
276 * jack connectivity, i.e. external or internal connection.
278 static const char *get_jack_connectivity(u32 cfg
)
280 static const char * const jack_locations
[4] = {
281 "Ext", "Int", "Sep", "Oth"
284 return jack_locations
[(cfg
>> (AC_DEFCFG_LOCATION_SHIFT
+ 4)) & 3];
288 * Parse the pin default config value and returns the string of the
289 * jack type, i.e. the purpose of the jack, such as Line-Out or CD.
291 static const char *get_jack_type(u32 cfg
)
293 static const char * const jack_types
[16] = {
294 "Line Out", "Speaker", "HP Out", "CD",
295 "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
296 "Line In", "Aux", "Mic", "Telephony",
297 "SPDIF In", "Digital In", "Reserved", "Other"
300 return jack_types
[(cfg
& AC_DEFCFG_DEVICE
)
301 >> AC_DEFCFG_DEVICE_SHIFT
];
304 static void print_pin_caps(struct snd_info_buffer
*buffer
,
305 struct hda_codec
*codec
, hda_nid_t nid
,
308 static const char * const jack_conns
[4] = {
309 "Jack", "N/A", "Fixed", "Both"
311 unsigned int caps
, val
;
313 caps
= param_read(codec
, nid
, AC_PAR_PIN_CAP
);
314 snd_iprintf(buffer
, " Pincap 0x%08x:", caps
);
315 if (caps
& AC_PINCAP_IN
)
316 snd_iprintf(buffer
, " IN");
317 if (caps
& AC_PINCAP_OUT
)
318 snd_iprintf(buffer
, " OUT");
319 if (caps
& AC_PINCAP_HP_DRV
)
320 snd_iprintf(buffer
, " HP");
321 if (caps
& AC_PINCAP_EAPD
)
322 snd_iprintf(buffer
, " EAPD");
323 if (caps
& AC_PINCAP_PRES_DETECT
)
324 snd_iprintf(buffer
, " Detect");
325 if (caps
& AC_PINCAP_BALANCE
)
326 snd_iprintf(buffer
, " Balanced");
327 if (caps
& AC_PINCAP_HDMI
) {
328 /* Realtek uses this bit as a different meaning */
329 if ((codec
->core
.vendor_id
>> 16) == 0x10ec)
330 snd_iprintf(buffer
, " R/L");
332 if (caps
& AC_PINCAP_HBR
)
333 snd_iprintf(buffer
, " HBR");
334 snd_iprintf(buffer
, " HDMI");
337 if (caps
& AC_PINCAP_DP
)
338 snd_iprintf(buffer
, " DP");
339 if (caps
& AC_PINCAP_TRIG_REQ
)
340 snd_iprintf(buffer
, " Trigger");
341 if (caps
& AC_PINCAP_IMP_SENSE
)
342 snd_iprintf(buffer
, " ImpSense");
343 snd_iprintf(buffer
, "\n");
344 if (caps
& AC_PINCAP_VREF
) {
346 (caps
& AC_PINCAP_VREF
) >> AC_PINCAP_VREF_SHIFT
;
347 snd_iprintf(buffer
, " Vref caps:");
348 if (vref
& AC_PINCAP_VREF_HIZ
)
349 snd_iprintf(buffer
, " HIZ");
350 if (vref
& AC_PINCAP_VREF_50
)
351 snd_iprintf(buffer
, " 50");
352 if (vref
& AC_PINCAP_VREF_GRD
)
353 snd_iprintf(buffer
, " GRD");
354 if (vref
& AC_PINCAP_VREF_80
)
355 snd_iprintf(buffer
, " 80");
356 if (vref
& AC_PINCAP_VREF_100
)
357 snd_iprintf(buffer
, " 100");
358 snd_iprintf(buffer
, "\n");
362 if (caps
& AC_PINCAP_EAPD
) {
363 val
= snd_hda_codec_read(codec
, nid
, 0,
364 AC_VERB_GET_EAPD_BTLENABLE
, 0);
365 snd_iprintf(buffer
, " EAPD 0x%x:", val
);
366 if (val
& AC_EAPDBTL_BALANCED
)
367 snd_iprintf(buffer
, " BALANCED");
368 if (val
& AC_EAPDBTL_EAPD
)
369 snd_iprintf(buffer
, " EAPD");
370 if (val
& AC_EAPDBTL_LR_SWAP
)
371 snd_iprintf(buffer
, " R/L");
372 snd_iprintf(buffer
, "\n");
374 caps
= snd_hda_codec_read(codec
, nid
, 0, AC_VERB_GET_CONFIG_DEFAULT
, 0);
375 snd_iprintf(buffer
, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps
,
376 jack_conns
[(caps
& AC_DEFCFG_PORT_CONN
) >> AC_DEFCFG_PORT_CONN_SHIFT
],
378 get_jack_connectivity(caps
),
379 get_jack_location(caps
));
380 snd_iprintf(buffer
, " Conn = %s, Color = %s\n",
381 get_jack_connection(caps
),
382 get_jack_color(caps
));
383 /* Default association and sequence values refer to default grouping
384 * of pin complexes and their sequence within the group. This is used
385 * for priority and resource allocation.
387 snd_iprintf(buffer
, " DefAssociation = 0x%x, Sequence = 0x%x\n",
388 (caps
& AC_DEFCFG_DEF_ASSOC
) >> AC_DEFCFG_ASSOC_SHIFT
,
389 caps
& AC_DEFCFG_SEQUENCE
);
390 if (((caps
& AC_DEFCFG_MISC
) >> AC_DEFCFG_MISC_SHIFT
) &
391 AC_DEFCFG_MISC_NO_PRESENCE
) {
392 /* Miscellaneous bit indicates external hardware does not
393 * support presence detection even if the pin complex
394 * indicates it is supported.
396 snd_iprintf(buffer
, " Misc = NO_PRESENCE\n");
400 static void print_pin_ctls(struct snd_info_buffer
*buffer
,
401 struct hda_codec
*codec
, hda_nid_t nid
,
404 unsigned int pinctls
;
406 pinctls
= snd_hda_codec_read(codec
, nid
, 0,
407 AC_VERB_GET_PIN_WIDGET_CONTROL
, 0);
408 snd_iprintf(buffer
, " Pin-ctls: 0x%02x:", pinctls
);
409 if (pinctls
& AC_PINCTL_IN_EN
)
410 snd_iprintf(buffer
, " IN");
411 if (pinctls
& AC_PINCTL_OUT_EN
)
412 snd_iprintf(buffer
, " OUT");
413 if (pinctls
& AC_PINCTL_HP_EN
)
414 snd_iprintf(buffer
, " HP");
416 int vref
= pinctls
& AC_PINCTL_VREFEN
;
418 case AC_PINCTL_VREF_HIZ
:
419 snd_iprintf(buffer
, " VREF_HIZ");
421 case AC_PINCTL_VREF_50
:
422 snd_iprintf(buffer
, " VREF_50");
424 case AC_PINCTL_VREF_GRD
:
425 snd_iprintf(buffer
, " VREF_GRD");
427 case AC_PINCTL_VREF_80
:
428 snd_iprintf(buffer
, " VREF_80");
430 case AC_PINCTL_VREF_100
:
431 snd_iprintf(buffer
, " VREF_100");
435 snd_iprintf(buffer
, "\n");
438 static void print_vol_knob(struct snd_info_buffer
*buffer
,
439 struct hda_codec
*codec
, hda_nid_t nid
)
441 unsigned int cap
= param_read(codec
, nid
, AC_PAR_VOL_KNB_CAP
);
442 snd_iprintf(buffer
, " Volume-Knob: delta=%d, steps=%d, ",
443 (cap
>> 7) & 1, cap
& 0x7f);
444 cap
= snd_hda_codec_read(codec
, nid
, 0,
445 AC_VERB_GET_VOLUME_KNOB_CONTROL
, 0);
446 snd_iprintf(buffer
, "direct=%d, val=%d\n",
447 (cap
>> 7) & 1, cap
& 0x7f);
450 static void print_audio_io(struct snd_info_buffer
*buffer
,
451 struct hda_codec
*codec
, hda_nid_t nid
,
452 unsigned int wid_type
)
454 int conv
= snd_hda_codec_read(codec
, nid
, 0, AC_VERB_GET_CONV
, 0);
456 " Converter: stream=%d, channel=%d\n",
457 (conv
& AC_CONV_STREAM
) >> AC_CONV_STREAM_SHIFT
,
458 conv
& AC_CONV_CHANNEL
);
460 if (wid_type
== AC_WID_AUD_IN
&& (conv
& AC_CONV_CHANNEL
) == 0) {
461 int sdi
= snd_hda_codec_read(codec
, nid
, 0,
462 AC_VERB_GET_SDI_SELECT
, 0);
463 snd_iprintf(buffer
, " SDI-Select: %d\n",
464 sdi
& AC_SDI_SELECT
);
468 static void print_digital_conv(struct snd_info_buffer
*buffer
,
469 struct hda_codec
*codec
, hda_nid_t nid
)
471 unsigned int digi1
= snd_hda_codec_read(codec
, nid
, 0,
472 AC_VERB_GET_DIGI_CONVERT_1
, 0);
473 unsigned char digi2
= digi1
>> 8;
474 unsigned char digi3
= digi1
>> 16;
476 snd_iprintf(buffer
, " Digital:");
477 if (digi1
& AC_DIG1_ENABLE
)
478 snd_iprintf(buffer
, " Enabled");
479 if (digi1
& AC_DIG1_V
)
480 snd_iprintf(buffer
, " Validity");
481 if (digi1
& AC_DIG1_VCFG
)
482 snd_iprintf(buffer
, " ValidityCfg");
483 if (digi1
& AC_DIG1_EMPHASIS
)
484 snd_iprintf(buffer
, " Preemphasis");
485 if (digi1
& AC_DIG1_COPYRIGHT
)
486 snd_iprintf(buffer
, " Non-Copyright");
487 if (digi1
& AC_DIG1_NONAUDIO
)
488 snd_iprintf(buffer
, " Non-Audio");
489 if (digi1
& AC_DIG1_PROFESSIONAL
)
490 snd_iprintf(buffer
, " Pro");
491 if (digi1
& AC_DIG1_LEVEL
)
492 snd_iprintf(buffer
, " GenLevel");
493 if (digi3
& AC_DIG3_KAE
)
494 snd_iprintf(buffer
, " KAE");
495 snd_iprintf(buffer
, "\n");
496 snd_iprintf(buffer
, " Digital category: 0x%x\n",
498 snd_iprintf(buffer
, " IEC Coding Type: 0x%x\n",
499 digi3
& AC_DIG3_ICT
);
502 static const char *get_pwr_state(u32 state
)
504 static const char * const buf
[] = {
505 "D0", "D1", "D2", "D3", "D3cold"
507 if (state
< ARRAY_SIZE(buf
))
512 static void print_power_state(struct snd_info_buffer
*buffer
,
513 struct hda_codec
*codec
, hda_nid_t nid
)
515 static const char * const names
[] = {
516 [ilog2(AC_PWRST_D0SUP
)] = "D0",
517 [ilog2(AC_PWRST_D1SUP
)] = "D1",
518 [ilog2(AC_PWRST_D2SUP
)] = "D2",
519 [ilog2(AC_PWRST_D3SUP
)] = "D3",
520 [ilog2(AC_PWRST_D3COLDSUP
)] = "D3cold",
521 [ilog2(AC_PWRST_S3D3COLDSUP
)] = "S3D3cold",
522 [ilog2(AC_PWRST_CLKSTOP
)] = "CLKSTOP",
523 [ilog2(AC_PWRST_EPSS
)] = "EPSS",
526 int sup
= param_read(codec
, nid
, AC_PAR_POWER_STATE
);
527 int pwr
= snd_hda_codec_read(codec
, nid
, 0,
528 AC_VERB_GET_POWER_STATE
, 0);
532 snd_iprintf(buffer
, " Power states: ");
533 for (i
= 0; i
< ARRAY_SIZE(names
); i
++) {
535 snd_iprintf(buffer
, " %s", names
[i
]);
537 snd_iprintf(buffer
, "\n");
540 snd_iprintf(buffer
, " Power: setting=%s, actual=%s",
541 get_pwr_state(pwr
& AC_PWRST_SETTING
),
542 get_pwr_state((pwr
& AC_PWRST_ACTUAL
) >>
543 AC_PWRST_ACTUAL_SHIFT
));
544 if (pwr
& AC_PWRST_ERROR
)
545 snd_iprintf(buffer
, ", Error");
546 if (pwr
& AC_PWRST_CLK_STOP_OK
)
547 snd_iprintf(buffer
, ", Clock-stop-OK");
548 if (pwr
& AC_PWRST_SETTING_RESET
)
549 snd_iprintf(buffer
, ", Setting-reset");
550 snd_iprintf(buffer
, "\n");
553 static void print_unsol_cap(struct snd_info_buffer
*buffer
,
554 struct hda_codec
*codec
, hda_nid_t nid
)
556 int unsol
= snd_hda_codec_read(codec
, nid
, 0,
557 AC_VERB_GET_UNSOLICITED_RESPONSE
, 0);
559 " Unsolicited: tag=%02x, enabled=%d\n",
560 unsol
& AC_UNSOL_TAG
,
561 (unsol
& AC_UNSOL_ENABLED
) ? 1 : 0);
564 static inline bool can_dump_coef(struct hda_codec
*codec
)
567 case 0: return false;
569 default: return codec
->dump_coef
;
573 static void print_proc_caps(struct snd_info_buffer
*buffer
,
574 struct hda_codec
*codec
, hda_nid_t nid
)
576 unsigned int i
, ncoeff
, oldindex
;
577 unsigned int proc_caps
= param_read(codec
, nid
, AC_PAR_PROC_CAP
);
578 ncoeff
= (proc_caps
& AC_PCAP_NUM_COEF
) >> AC_PCAP_NUM_COEF_SHIFT
;
579 snd_iprintf(buffer
, " Processing caps: benign=%d, ncoeff=%d\n",
580 proc_caps
& AC_PCAP_BENIGN
, ncoeff
);
582 if (!can_dump_coef(codec
))
585 /* Note: This is racy - another process could run in parallel and change
586 the coef index too. */
587 oldindex
= snd_hda_codec_read(codec
, nid
, 0, AC_VERB_GET_COEF_INDEX
, 0);
588 for (i
= 0; i
< ncoeff
; i
++) {
590 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_COEF_INDEX
, i
);
591 val
= snd_hda_codec_read(codec
, nid
, 0, AC_VERB_GET_PROC_COEF
,
593 snd_iprintf(buffer
, " Coeff 0x%02x: 0x%04x\n", i
, val
);
595 snd_hda_codec_write(codec
, nid
, 0, AC_VERB_SET_COEF_INDEX
, oldindex
);
598 static void print_conn_list(struct snd_info_buffer
*buffer
,
599 struct hda_codec
*codec
, hda_nid_t nid
,
600 unsigned int wid_type
, hda_nid_t
*conn
,
604 const hda_nid_t
*list
;
608 wid_type
!= AC_WID_AUD_MIX
&&
609 wid_type
!= AC_WID_VOL_KNB
&&
610 wid_type
!= AC_WID_POWER
)
611 curr
= snd_hda_codec_read(codec
, nid
, 0,
612 AC_VERB_GET_CONNECT_SEL
, 0);
613 snd_iprintf(buffer
, " Connection: %d\n", conn_len
);
615 snd_iprintf(buffer
, " ");
616 for (c
= 0; c
< conn_len
; c
++) {
617 snd_iprintf(buffer
, " 0x%02x", conn
[c
]);
619 snd_iprintf(buffer
, "*");
621 snd_iprintf(buffer
, "\n");
624 /* Get Cache connections info */
625 cache_len
= snd_hda_get_conn_list(codec
, nid
, &list
);
626 if (cache_len
>= 0 && (cache_len
!= conn_len
||
627 memcmp(list
, conn
, conn_len
) != 0)) {
628 snd_iprintf(buffer
, " In-driver Connection: %d\n", cache_len
);
630 snd_iprintf(buffer
, " ");
631 for (c
= 0; c
< cache_len
; c
++)
632 snd_iprintf(buffer
, " 0x%02x", list
[c
]);
633 snd_iprintf(buffer
, "\n");
638 static void print_gpio(struct snd_info_buffer
*buffer
,
639 struct hda_codec
*codec
, hda_nid_t nid
)
642 param_read(codec
, codec
->core
.afg
, AC_PAR_GPIO_CAP
);
643 unsigned int enable
, direction
, wake
, unsol
, sticky
, data
;
645 snd_iprintf(buffer
, "GPIO: io=%d, o=%d, i=%d, "
646 "unsolicited=%d, wake=%d\n",
647 gpio
& AC_GPIO_IO_COUNT
,
648 (gpio
& AC_GPIO_O_COUNT
) >> AC_GPIO_O_COUNT_SHIFT
,
649 (gpio
& AC_GPIO_I_COUNT
) >> AC_GPIO_I_COUNT_SHIFT
,
650 (gpio
& AC_GPIO_UNSOLICITED
) ? 1 : 0,
651 (gpio
& AC_GPIO_WAKE
) ? 1 : 0);
652 max
= gpio
& AC_GPIO_IO_COUNT
;
655 enable
= snd_hda_codec_read(codec
, nid
, 0,
656 AC_VERB_GET_GPIO_MASK
, 0);
657 direction
= snd_hda_codec_read(codec
, nid
, 0,
658 AC_VERB_GET_GPIO_DIRECTION
, 0);
659 wake
= snd_hda_codec_read(codec
, nid
, 0,
660 AC_VERB_GET_GPIO_WAKE_MASK
, 0);
661 unsol
= snd_hda_codec_read(codec
, nid
, 0,
662 AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK
, 0);
663 sticky
= snd_hda_codec_read(codec
, nid
, 0,
664 AC_VERB_GET_GPIO_STICKY_MASK
, 0);
665 data
= snd_hda_codec_read(codec
, nid
, 0,
666 AC_VERB_GET_GPIO_DATA
, 0);
667 for (i
= 0; i
< max
; ++i
)
669 " IO[%d]: enable=%d, dir=%d, wake=%d, "
670 "sticky=%d, data=%d, unsol=%d\n", i
,
671 (enable
& (1<<i
)) ? 1 : 0,
672 (direction
& (1<<i
)) ? 1 : 0,
673 (wake
& (1<<i
)) ? 1 : 0,
674 (sticky
& (1<<i
)) ? 1 : 0,
675 (data
& (1<<i
)) ? 1 : 0,
676 (unsol
& (1<<i
)) ? 1 : 0);
677 /* FIXME: add GPO and GPI pin information */
678 print_nid_array(buffer
, codec
, nid
, &codec
->mixers
);
679 print_nid_array(buffer
, codec
, nid
, &codec
->nids
);
682 static void print_dpmst_connections(struct snd_info_buffer
*buffer
, struct hda_codec
*codec
,
683 hda_nid_t nid
, int dev_num
)
685 int c
, conn_len
, curr
, dev_id_saved
;
688 conn_len
= snd_hda_get_num_raw_conns(codec
, nid
);
692 conn
= kmalloc_array(conn_len
, sizeof(hda_nid_t
), GFP_KERNEL
);
696 dev_id_saved
= snd_hda_get_dev_select(codec
, nid
);
698 snd_hda_set_dev_select(codec
, nid
, dev_num
);
699 curr
= snd_hda_codec_read(codec
, nid
, 0, AC_VERB_GET_CONNECT_SEL
, 0);
700 if (snd_hda_get_raw_connections(codec
, nid
, conn
, conn_len
) < 0)
703 for (c
= 0; c
< conn_len
; c
++) {
704 snd_iprintf(buffer
, " 0x%02x", conn
[c
]);
706 snd_iprintf(buffer
, "*");
711 snd_hda_set_dev_select(codec
, nid
, dev_id_saved
);
714 static void print_device_list(struct snd_info_buffer
*buffer
,
715 struct hda_codec
*codec
, hda_nid_t nid
)
718 u8 dev_list
[AC_MAX_DEV_LIST_LEN
];
721 devlist_len
= snd_hda_get_devices(codec
, nid
, dev_list
,
722 AC_MAX_DEV_LIST_LEN
);
723 snd_iprintf(buffer
, " Devices: %d\n", devlist_len
);
724 if (devlist_len
<= 0)
727 curr
= snd_hda_codec_read(codec
, nid
, 0,
728 AC_VERB_GET_DEVICE_SEL
, 0);
730 for (i
= 0; i
< devlist_len
; i
++) {
732 snd_iprintf(buffer
, " *");
734 snd_iprintf(buffer
, " ");
737 "Dev %02d: PD = %d, ELDV = %d, IA = %d, Connections [", i
,
738 !!(dev_list
[i
] & AC_DE_PD
),
739 !!(dev_list
[i
] & AC_DE_ELDV
),
740 !!(dev_list
[i
] & AC_DE_IA
));
742 print_dpmst_connections(buffer
, codec
, nid
, i
);
744 snd_iprintf(buffer
, " ]\n");
748 static void print_codec_core_info(struct hdac_device
*codec
,
749 struct snd_info_buffer
*buffer
)
751 snd_iprintf(buffer
, "Codec: ");
752 if (codec
->vendor_name
&& codec
->chip_name
)
753 snd_iprintf(buffer
, "%s %s\n",
754 codec
->vendor_name
, codec
->chip_name
);
756 snd_iprintf(buffer
, "Not Set\n");
757 snd_iprintf(buffer
, "Address: %d\n", codec
->addr
);
759 snd_iprintf(buffer
, "AFG Function Id: 0x%x (unsol %u)\n",
760 codec
->afg_function_id
, codec
->afg_unsol
);
762 snd_iprintf(buffer
, "MFG Function Id: 0x%x (unsol %u)\n",
763 codec
->mfg_function_id
, codec
->mfg_unsol
);
764 snd_iprintf(buffer
, "Vendor Id: 0x%08x\n", codec
->vendor_id
);
765 snd_iprintf(buffer
, "Subsystem Id: 0x%08x\n", codec
->subsystem_id
);
766 snd_iprintf(buffer
, "Revision Id: 0x%x\n", codec
->revision_id
);
769 snd_iprintf(buffer
, "Modem Function Group: 0x%x\n", codec
->mfg
);
771 snd_iprintf(buffer
, "No Modem Function Group found\n");
774 static void print_codec_info(struct snd_info_entry
*entry
,
775 struct snd_info_buffer
*buffer
)
777 struct hda_codec
*codec
= entry
->private_data
;
781 print_codec_core_info(&codec
->core
, buffer
);
782 fg
= codec
->core
.afg
;
785 snd_hda_power_up(codec
);
786 snd_iprintf(buffer
, "Default PCM:\n");
787 print_pcm_caps(buffer
, codec
, fg
);
788 snd_iprintf(buffer
, "Default Amp-In caps: ");
789 print_amp_caps(buffer
, codec
, fg
, HDA_INPUT
);
790 snd_iprintf(buffer
, "Default Amp-Out caps: ");
791 print_amp_caps(buffer
, codec
, fg
, HDA_OUTPUT
);
792 snd_iprintf(buffer
, "State of AFG node 0x%02x:\n", fg
);
793 print_power_state(buffer
, codec
, fg
);
795 nodes
= snd_hda_get_sub_nodes(codec
, fg
, &nid
);
796 if (! nid
|| nodes
< 0) {
797 snd_iprintf(buffer
, "Invalid AFG subtree\n");
798 snd_hda_power_down(codec
);
802 print_gpio(buffer
, codec
, fg
);
803 if (codec
->proc_widget_hook
)
804 codec
->proc_widget_hook(buffer
, codec
, fg
);
806 for (i
= 0; i
< nodes
; i
++, nid
++) {
807 unsigned int wid_caps
=
808 param_read(codec
, nid
, AC_PAR_AUDIO_WIDGET_CAP
);
809 unsigned int wid_type
= get_wcaps_type(wid_caps
);
810 hda_nid_t
*conn
= NULL
;
813 snd_iprintf(buffer
, "Node 0x%02x [%s] wcaps 0x%x:", nid
,
814 get_wid_type_name(wid_type
), wid_caps
);
815 if (wid_caps
& AC_WCAP_STEREO
) {
816 unsigned int chans
= get_wcaps_channels(wid_caps
);
818 snd_iprintf(buffer
, " Stereo");
820 snd_iprintf(buffer
, " %d-Channels", chans
);
822 snd_iprintf(buffer
, " Mono");
823 if (wid_caps
& AC_WCAP_DIGITAL
)
824 snd_iprintf(buffer
, " Digital");
825 if (wid_caps
& AC_WCAP_IN_AMP
)
826 snd_iprintf(buffer
, " Amp-In");
827 if (wid_caps
& AC_WCAP_OUT_AMP
)
828 snd_iprintf(buffer
, " Amp-Out");
829 if (wid_caps
& AC_WCAP_STRIPE
)
830 snd_iprintf(buffer
, " Stripe");
831 if (wid_caps
& AC_WCAP_LR_SWAP
)
832 snd_iprintf(buffer
, " R/L");
833 if (wid_caps
& AC_WCAP_CP_CAPS
)
834 snd_iprintf(buffer
, " CP");
835 snd_iprintf(buffer
, "\n");
837 print_nid_array(buffer
, codec
, nid
, &codec
->mixers
);
838 print_nid_array(buffer
, codec
, nid
, &codec
->nids
);
839 print_nid_pcms(buffer
, codec
, nid
);
841 /* volume knob is a special widget that always have connection
844 if (wid_type
== AC_WID_VOL_KNB
)
845 wid_caps
|= AC_WCAP_CONN_LIST
;
847 if (wid_caps
& AC_WCAP_CONN_LIST
) {
848 conn_len
= snd_hda_get_num_raw_conns(codec
, nid
);
850 conn
= kmalloc_array(conn_len
,
855 if (snd_hda_get_raw_connections(codec
, nid
, conn
,
861 if (wid_caps
& AC_WCAP_IN_AMP
) {
862 snd_iprintf(buffer
, " Amp-In caps: ");
863 print_amp_caps(buffer
, codec
, nid
, HDA_INPUT
);
864 snd_iprintf(buffer
, " Amp-In vals: ");
865 if (wid_type
== AC_WID_PIN
||
866 (codec
->single_adc_amp
&&
867 wid_type
== AC_WID_AUD_IN
))
868 print_amp_vals(buffer
, codec
, nid
, HDA_INPUT
,
871 print_amp_vals(buffer
, codec
, nid
, HDA_INPUT
,
874 if (wid_caps
& AC_WCAP_OUT_AMP
) {
875 snd_iprintf(buffer
, " Amp-Out caps: ");
876 print_amp_caps(buffer
, codec
, nid
, HDA_OUTPUT
);
877 snd_iprintf(buffer
, " Amp-Out vals: ");
878 if (wid_type
== AC_WID_PIN
&&
879 codec
->pin_amp_workaround
)
880 print_amp_vals(buffer
, codec
, nid
, HDA_OUTPUT
,
883 print_amp_vals(buffer
, codec
, nid
, HDA_OUTPUT
,
890 print_pin_caps(buffer
, codec
, nid
, &supports_vref
);
891 print_pin_ctls(buffer
, codec
, nid
, supports_vref
);
895 print_vol_knob(buffer
, codec
, nid
);
899 print_audio_io(buffer
, codec
, nid
, wid_type
);
900 if (wid_caps
& AC_WCAP_DIGITAL
)
901 print_digital_conv(buffer
, codec
, nid
);
902 if (wid_caps
& AC_WCAP_FORMAT_OVRD
) {
903 snd_iprintf(buffer
, " PCM:\n");
904 print_pcm_caps(buffer
, codec
, nid
);
909 if (wid_caps
& AC_WCAP_UNSOL_CAP
)
910 print_unsol_cap(buffer
, codec
, nid
);
912 if (wid_caps
& AC_WCAP_POWER
)
913 print_power_state(buffer
, codec
, nid
);
915 if (wid_caps
& AC_WCAP_DELAY
)
916 snd_iprintf(buffer
, " Delay: %d samples\n",
917 (wid_caps
& AC_WCAP_DELAY
) >>
918 AC_WCAP_DELAY_SHIFT
);
920 if (wid_type
== AC_WID_PIN
&& codec
->dp_mst
)
921 print_device_list(buffer
, codec
, nid
);
923 if (wid_caps
& AC_WCAP_CONN_LIST
)
924 print_conn_list(buffer
, codec
, nid
, wid_type
,
927 if (wid_caps
& AC_WCAP_PROC_WID
)
928 print_proc_caps(buffer
, codec
, nid
);
930 if (codec
->proc_widget_hook
)
931 codec
->proc_widget_hook(buffer
, codec
, nid
);
935 snd_hda_power_down(codec
);
941 int snd_hda_codec_proc_new(struct hda_codec
*codec
)
945 snprintf(name
, sizeof(name
), "codec#%d", codec
->core
.addr
);
946 return snd_card_ro_proc_new(codec
->card
, name
, codec
, print_codec_info
);