]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - sound/pci/hda/hda_proc.c
Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[mirror_ubuntu-jammy-kernel.git] / sound / pci / hda / hda_proc.c
CommitLineData
d0fa1179 1// SPDX-License-Identifier: GPL-2.0-or-later
1da177e4
LT
2/*
3 * Universal Interface for Intel High Definition Audio Codec
4 *
5 * Generic proc interface
6 *
7 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
1da177e4
LT
8 */
9
1da177e4 10#include <linux/init.h>
4eea3091 11#include <linux/slab.h>
1da177e4 12#include <sound/core.h>
cd262518 13#include <linux/module.h>
be57bfff 14#include <sound/hda_codec.h>
18612048 15#include "hda_local.h"
1da177e4 16
cd262518
DH
17static int dump_coef = -1;
18module_param(dump_coef, int, 0644);
19MODULE_PARM_DESC(dump_coef, "Dump processing coefficients in codec proc file (-1=auto, 0=disable, 1=enable)");
20
9ba17b4d
TI
21/* always use noncached version */
22#define param_read(codec, nid, parm) \
23 snd_hdac_read_parm_uncached(&(codec)->core, nid, parm)
24
1da177e4
LT
25static const char *get_wid_type_name(unsigned int wid_value)
26{
cc75cdfe 27 static const char * const names[16] = {
1da177e4
LT
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",
37 };
3a90274d
TI
38 if (wid_value == -1)
39 return "UNKNOWN Widget";
1da177e4
LT
40 wid_value &= 0xf;
41 if (names[wid_value])
42 return names[wid_value];
43 else
3bc89529 44 return "UNKNOWN Widget";
1da177e4
LT
45}
46
5b0cb1d8
JK
47static void print_nid_array(struct snd_info_buffer *buffer,
48 struct hda_codec *codec, hda_nid_t nid,
49 struct snd_array *array)
3911a4c1
JK
50{
51 int i;
5b0cb1d8 52 struct hda_nid_item *items = array->list, *item;
3911a4c1 53 struct snd_kcontrol *kctl;
5b0cb1d8
JK
54 for (i = 0; i < array->used; i++) {
55 item = &items[i];
56 if (item->nid == nid) {
57 kctl = item->kctl;
3911a4c1
JK
58 snd_iprintf(buffer,
59 " Control: name=\"%s\", index=%i, device=%i\n",
5b0cb1d8
JK
60 kctl->id.name, kctl->id.index + item->index,
61 kctl->id.device);
9e3fd871
JK
62 if (item->flags & HDA_NID_ITEM_AMP)
63 snd_iprintf(buffer,
64 " ControlAmp: chs=%lu, dir=%s, "
65 "idx=%lu, ofs=%lu\n",
66 get_amp_channels(kctl),
67 get_amp_direction(kctl) ? "Out" : "In",
68 get_amp_index(kctl),
69 get_amp_offset(kctl));
3911a4c1
JK
70 }
71 }
72}
73
74static void print_nid_pcms(struct snd_info_buffer *buffer,
75 struct hda_codec *codec, hda_nid_t nid)
76{
bbbc7e85 77 int type;
3911a4c1 78 struct hda_pcm *cpcm;
bbbc7e85
TI
79
80 list_for_each_entry(cpcm, &codec->pcm_list_head, list) {
3911a4c1
JK
81 for (type = 0; type < 2; type++) {
82 if (cpcm->stream[type].nid != nid || cpcm->pcm == NULL)
83 continue;
84 snd_iprintf(buffer, " Device: name=\"%s\", "
85 "type=\"%s\", device=%i\n",
86 cpcm->name,
87 snd_hda_pcm_type_name[cpcm->pcm_type],
88 cpcm->pcm->device);
89 }
90 }
91}
92
c8b6bf9b 93static void print_amp_caps(struct snd_info_buffer *buffer,
1da177e4
LT
94 struct hda_codec *codec, hda_nid_t nid, int dir)
95{
96 unsigned int caps;
9ba17b4d
TI
97 caps = param_read(codec, nid, dir == HDA_OUTPUT ?
98 AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP);
1da177e4
LT
99 if (caps == -1 || caps == 0) {
100 snd_iprintf(buffer, "N/A\n");
101 return;
102 }
d01ce99f
TI
103 snd_iprintf(buffer, "ofs=0x%02x, nsteps=0x%02x, stepsize=0x%02x, "
104 "mute=%x\n",
1da177e4
LT
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);
109}
110
cc261738
TI
111/* is this a stereo widget or a stereo-to-mono mix? */
112static bool is_stereo_amps(struct hda_codec *codec, hda_nid_t nid,
113 int dir, unsigned int wcaps, int indices)
114{
115 hda_nid_t conn;
116
117 if (wcaps & AC_WCAP_STEREO)
118 return true;
119 /* check for a stereo-to-mono mix; it must be:
120 * only a single connection, only for input, and only a mixer widget
121 */
122 if (indices != 1 || dir != HDA_INPUT ||
123 get_wcaps_type(wcaps) != AC_WID_AUD_MIX)
124 return false;
125
126 if (snd_hda_get_raw_connections(codec, nid, &conn, 1) < 0)
127 return false;
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);
131}
132
c8b6bf9b 133static void print_amp_vals(struct snd_info_buffer *buffer,
1da177e4 134 struct hda_codec *codec, hda_nid_t nid,
cc261738 135 int dir, unsigned int wcaps, int indices)
1da177e4
LT
136{
137 unsigned int val;
cc261738 138 bool stereo;
3e289f16
TI
139 int i;
140
cc261738
TI
141 stereo = is_stereo_amps(codec, nid, dir, wcaps, indices);
142
7f0e2f8b 143 dir = dir == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT;
3e289f16
TI
144 for (i = 0; i < indices; i++) {
145 snd_iprintf(buffer, " [");
2f179721
TI
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);
3e289f16 150 if (stereo) {
d01ce99f
TI
151 val = snd_hda_codec_read(codec, nid, 0,
152 AC_VERB_GET_AMP_GAIN_MUTE,
2f179721
TI
153 AC_AMP_GET_RIGHT | dir | i);
154 snd_iprintf(buffer, " 0x%02x", val);
3e289f16 155 }
2f179721 156 snd_iprintf(buffer, "]");
1da177e4 157 }
3e289f16 158 snd_iprintf(buffer, "\n");
1da177e4
LT
159}
160
33deeca3
WF
161static void print_pcm_rates(struct snd_info_buffer *buffer, unsigned int pcm)
162{
f71ff0d7
TI
163 static unsigned int rates[] = {
164 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
165 96000, 176400, 192000, 384000
166 };
167 int i;
d39b4352 168
b90d7760
TI
169 pcm &= AC_SUPPCM_RATES;
170 snd_iprintf(buffer, " rates [0x%x]:", pcm);
f71ff0d7
TI
171 for (i = 0; i < ARRAY_SIZE(rates); i++)
172 if (pcm & (1 << i))
173 snd_iprintf(buffer, " %d", rates[i]);
174 snd_iprintf(buffer, "\n");
b90d7760
TI
175}
176
d39b4352
WF
177static void print_pcm_bits(struct snd_info_buffer *buffer, unsigned int pcm)
178{
179 char buf[SND_PRINT_BITS_ADVISED_BUFSIZE];
b90d7760 180
b0e6481a 181 snd_iprintf(buffer, " bits [0x%x]:", (pcm >> 16) & 0xff);
d39b4352
WF
182 snd_print_pcm_bits(pcm, buf, sizeof(buf));
183 snd_iprintf(buffer, "%s\n", buf);
b90d7760
TI
184}
185
186static void print_pcm_formats(struct snd_info_buffer *buffer,
187 unsigned int streams)
188{
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");
197}
198
c8b6bf9b 199static void print_pcm_caps(struct snd_info_buffer *buffer,
1da177e4
LT
200 struct hda_codec *codec, hda_nid_t nid)
201{
9ba17b4d
TI
202 unsigned int pcm = param_read(codec, nid, AC_PAR_PCM);
203 unsigned int stream = param_read(codec, nid, AC_PAR_STREAM);
1da177e4
LT
204 if (pcm == -1 || stream == -1) {
205 snd_iprintf(buffer, "N/A\n");
206 return;
207 }
b90d7760
TI
208 print_pcm_rates(buffer, pcm);
209 print_pcm_bits(buffer, pcm);
210 print_pcm_formats(buffer, stream);
1da177e4
LT
211}
212
1da177e4
LT
213static const char *get_jack_connection(u32 cfg)
214{
cc75cdfe 215 static const char * const names[16] = {
1da177e4
LT
216 "Unknown", "1/8", "1/4", "ATAPI",
217 "RCA", "Optical","Digital", "Analog",
218 "DIN", "XLR", "RJ11", "Comb",
219 NULL, NULL, NULL, "Other"
220 };
221 cfg = (cfg & AC_DEFCFG_CONN_TYPE) >> AC_DEFCFG_CONN_TYPE_SHIFT;
222 if (names[cfg])
223 return names[cfg];
224 else
225 return "UNKNOWN";
226}
227
228static const char *get_jack_color(u32 cfg)
229{
cc75cdfe 230 static const char * const names[16] = {
1da177e4
LT
231 "Unknown", "Black", "Grey", "Blue",
232 "Green", "Red", "Orange", "Yellow",
233 "Purple", "Pink", NULL, NULL,
234 NULL, NULL, "White", "Other",
235 };
236 cfg = (cfg & AC_DEFCFG_COLOR) >> AC_DEFCFG_COLOR_SHIFT;
237 if (names[cfg])
238 return names[cfg];
239 else
240 return "UNKNOWN";
241}
242
d2c6b63d
TI
243/*
244 * Parse the pin default config value and returns the string of the
245 * jack location, e.g. "Rear", "Front", etc.
246 */
247static const char *get_jack_location(u32 cfg)
248{
cc75cdfe 249 static const char * const bases[7] = {
d2c6b63d
TI
250 "N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom",
251 };
cc75cdfe 252 static const unsigned char specials_idx[] = {
d2c6b63d
TI
253 0x07, 0x08,
254 0x17, 0x18, 0x19,
255 0x37, 0x38
256 };
cc75cdfe 257 static const char * const specials[] = {
d2c6b63d
TI
258 "Rear Panel", "Drive Bar",
259 "Riser", "HDMI", "ATAPI",
260 "Mobile-In", "Mobile-Out"
261 };
262 int i;
263
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])
269 return specials[i];
270 }
271 return "UNKNOWN";
272}
273
274/*
275 * Parse the pin default config value and returns the string of the
276 * jack connectivity, i.e. external or internal connection.
277 */
278static const char *get_jack_connectivity(u32 cfg)
279{
cc75cdfe
TI
280 static const char * const jack_locations[4] = {
281 "Ext", "Int", "Sep", "Oth"
282 };
d2c6b63d
TI
283
284 return jack_locations[(cfg >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3];
285}
286
287/*
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.
290 */
291static const char *get_jack_type(u32 cfg)
292{
cc75cdfe 293 static const char * const jack_types[16] = {
d2c6b63d
TI
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"
298 };
299
300 return jack_types[(cfg & AC_DEFCFG_DEVICE)
301 >> AC_DEFCFG_DEVICE_SHIFT];
302}
303
c8b6bf9b 304static void print_pin_caps(struct snd_info_buffer *buffer,
797760ab
AP
305 struct hda_codec *codec, hda_nid_t nid,
306 int *supports_vref)
1da177e4 307{
cc75cdfe
TI
308 static const char * const jack_conns[4] = {
309 "Jack", "N/A", "Fixed", "Both"
310 };
e97a5167 311 unsigned int caps, val;
1da177e4 312
9ba17b4d 313 caps = param_read(codec, nid, AC_PAR_PIN_CAP);
0481f453 314 snd_iprintf(buffer, " Pincap 0x%08x:", caps);
1da177e4
LT
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");
5885492a
TI
321 if (caps & AC_PINCAP_EAPD)
322 snd_iprintf(buffer, " EAPD");
323 if (caps & AC_PINCAP_PRES_DETECT)
324 snd_iprintf(buffer, " Detect");
797760ab
AP
325 if (caps & AC_PINCAP_BALANCE)
326 snd_iprintf(buffer, " Balanced");
c4920606
TI
327 if (caps & AC_PINCAP_HDMI) {
328 /* Realtek uses this bit as a different meaning */
7639a06c 329 if ((codec->core.vendor_id >> 16) == 0x10ec)
c4920606 330 snd_iprintf(buffer, " R/L");
b923528e
WF
331 else {
332 if (caps & AC_PINCAP_HBR)
333 snd_iprintf(buffer, " HBR");
c4920606 334 snd_iprintf(buffer, " HDMI");
b923528e 335 }
c4920606 336 }
728765b3
WF
337 if (caps & AC_PINCAP_DP)
338 snd_iprintf(buffer, " DP");
797760ab
AP
339 if (caps & AC_PINCAP_TRIG_REQ)
340 snd_iprintf(buffer, " Trigger");
341 if (caps & AC_PINCAP_IMP_SENSE)
342 snd_iprintf(buffer, " ImpSense");
1da177e4 343 snd_iprintf(buffer, "\n");
797760ab
AP
344 if (caps & AC_PINCAP_VREF) {
345 unsigned int 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");
359 *supports_vref = 1;
360 } else
361 *supports_vref = 0;
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");
373 }
1da177e4 374 caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
b0c95f51
TI
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],
d2c6b63d
TI
377 get_jack_type(caps),
378 get_jack_connectivity(caps),
379 get_jack_location(caps));
1da177e4
LT
380 snd_iprintf(buffer, " Conn = %s, Color = %s\n",
381 get_jack_connection(caps),
382 get_jack_color(caps));
797760ab
AP
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.
386 */
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.
395 */
396 snd_iprintf(buffer, " Misc = NO_PRESENCE\n");
e97a5167 397 }
1da177e4
LT
398}
399
797760ab
AP
400static void print_pin_ctls(struct snd_info_buffer *buffer,
401 struct hda_codec *codec, hda_nid_t nid,
402 int supports_vref)
403{
404 unsigned int pinctls;
405
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");
415 if (supports_vref) {
416 int vref = pinctls & AC_PINCTL_VREFEN;
417 switch (vref) {
418 case AC_PINCTL_VREF_HIZ:
419 snd_iprintf(buffer, " VREF_HIZ");
420 break;
421 case AC_PINCTL_VREF_50:
422 snd_iprintf(buffer, " VREF_50");
423 break;
424 case AC_PINCTL_VREF_GRD:
425 snd_iprintf(buffer, " VREF_GRD");
426 break;
427 case AC_PINCTL_VREF_80:
428 snd_iprintf(buffer, " VREF_80");
429 break;
430 case AC_PINCTL_VREF_100:
431 snd_iprintf(buffer, " VREF_100");
432 break;
433 }
434 }
435 snd_iprintf(buffer, "\n");
436}
437
438static void print_vol_knob(struct snd_info_buffer *buffer,
439 struct hda_codec *codec, hda_nid_t nid)
440{
9ba17b4d 441 unsigned int cap = param_read(codec, nid, AC_PAR_VOL_KNB_CAP);
797760ab
AP
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);
448}
449
450static void print_audio_io(struct snd_info_buffer *buffer,
451 struct hda_codec *codec, hda_nid_t nid,
452 unsigned int wid_type)
453{
3911a4c1 454 int conv = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
797760ab
AP
455 snd_iprintf(buffer,
456 " Converter: stream=%d, channel=%d\n",
457 (conv & AC_CONV_STREAM) >> AC_CONV_STREAM_SHIFT,
458 conv & AC_CONV_CHANNEL);
459
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);
465 }
466}
467
468static void print_digital_conv(struct snd_info_buffer *buffer,
469 struct hda_codec *codec, hda_nid_t nid)
470{
471 unsigned int digi1 = snd_hda_codec_read(codec, nid, 0,
472 AC_VERB_GET_DIGI_CONVERT_1, 0);
61525979
WX
473 unsigned char digi2 = digi1 >> 8;
474 unsigned char digi3 = digi1 >> 16;
475
797760ab
AP
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)
088c820b 486 snd_iprintf(buffer, " Non-Copyright");
797760ab
AP
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");
61525979
WX
493 if (digi3 & AC_DIG3_KAE)
494 snd_iprintf(buffer, " KAE");
797760ab 495 snd_iprintf(buffer, "\n");
a1855d80 496 snd_iprintf(buffer, " Digital category: 0x%x\n",
61525979
WX
497 digi2 & AC_DIG2_CC);
498 snd_iprintf(buffer, " IEC Coding Type: 0x%x\n",
499 digi3 & AC_DIG3_ICT);
797760ab
AP
500}
501
502static const char *get_pwr_state(u32 state)
503{
167d2d55
TI
504 static const char * const buf[] = {
505 "D0", "D1", "D2", "D3", "D3cold"
797760ab 506 };
167d2d55 507 if (state < ARRAY_SIZE(buf))
797760ab
AP
508 return buf[state];
509 return "UNKNOWN";
510}
511
512static void print_power_state(struct snd_info_buffer *buffer,
513 struct hda_codec *codec, hda_nid_t nid)
514{
cc75cdfe 515 static const char * const names[] = {
83d605fd
WF
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",
524 };
525
9ba17b4d 526 int sup = param_read(codec, nid, AC_PAR_POWER_STATE);
797760ab
AP
527 int pwr = snd_hda_codec_read(codec, nid, 0,
528 AC_VERB_GET_POWER_STATE, 0);
1d260d7b
TI
529 if (sup != -1) {
530 int i;
531
532 snd_iprintf(buffer, " Power states: ");
533 for (i = 0; i < ARRAY_SIZE(names); i++) {
534 if (sup & (1U << i))
535 snd_iprintf(buffer, " %s", names[i]);
536 }
537 snd_iprintf(buffer, "\n");
538 }
83d605fd 539
ce63f3ba 540 snd_iprintf(buffer, " Power: setting=%s, actual=%s",
797760ab
AP
541 get_pwr_state(pwr & AC_PWRST_SETTING),
542 get_pwr_state((pwr & AC_PWRST_ACTUAL) >>
543 AC_PWRST_ACTUAL_SHIFT));
ce63f3ba
WX
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");
797760ab
AP
551}
552
553static void print_unsol_cap(struct snd_info_buffer *buffer,
554 struct hda_codec *codec, hda_nid_t nid)
555{
556 int unsol = snd_hda_codec_read(codec, nid, 0,
557 AC_VERB_GET_UNSOLICITED_RESPONSE, 0);
558 snd_iprintf(buffer,
559 " Unsolicited: tag=%02x, enabled=%d\n",
560 unsol & AC_UNSOL_TAG,
561 (unsol & AC_UNSOL_ENABLED) ? 1 : 0);
562}
563
cd262518
DH
564static inline bool can_dump_coef(struct hda_codec *codec)
565{
566 switch (dump_coef) {
567 case 0: return false;
568 case 1: return true;
569 default: return codec->dump_coef;
570 }
571}
572
797760ab
AP
573static void print_proc_caps(struct snd_info_buffer *buffer,
574 struct hda_codec *codec, hda_nid_t nid)
575{
cd262518 576 unsigned int i, ncoeff, oldindex;
9ba17b4d 577 unsigned int proc_caps = param_read(codec, nid, AC_PAR_PROC_CAP);
cd262518 578 ncoeff = (proc_caps & AC_PCAP_NUM_COEF) >> AC_PCAP_NUM_COEF_SHIFT;
797760ab 579 snd_iprintf(buffer, " Processing caps: benign=%d, ncoeff=%d\n",
cd262518
DH
580 proc_caps & AC_PCAP_BENIGN, ncoeff);
581
582 if (!can_dump_coef(codec))
583 return;
584
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++) {
589 unsigned int val;
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,
592 0);
593 snd_iprintf(buffer, " Coeff 0x%02x: 0x%04x\n", i, val);
594 }
595 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, oldindex);
797760ab
AP
596}
597
598static 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,
601 int conn_len)
602{
603 int c, curr = -1;
8b2c7a5c
WX
604 const hda_nid_t *list;
605 int cache_len;
797760ab 606
07a1e813
TI
607 if (conn_len > 1 &&
608 wid_type != AC_WID_AUD_MIX &&
609 wid_type != AC_WID_VOL_KNB &&
610 wid_type != AC_WID_POWER)
797760ab
AP
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);
614 if (conn_len > 0) {
615 snd_iprintf(buffer, " ");
616 for (c = 0; c < conn_len; c++) {
617 snd_iprintf(buffer, " 0x%02x", conn[c]);
618 if (c == curr)
619 snd_iprintf(buffer, "*");
620 }
621 snd_iprintf(buffer, "\n");
622 }
8b2c7a5c
WX
623
624 /* Get Cache connections info */
625 cache_len = snd_hda_get_conn_list(codec, nid, &list);
f4d77031
DC
626 if (cache_len >= 0 && (cache_len != conn_len ||
627 memcmp(list, conn, conn_len) != 0)) {
8b2c7a5c
WX
628 snd_iprintf(buffer, " In-driver Connection: %d\n", cache_len);
629 if (cache_len > 0) {
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");
634 }
635 }
797760ab
AP
636}
637
797760ab
AP
638static void print_gpio(struct snd_info_buffer *buffer,
639 struct hda_codec *codec, hda_nid_t nid)
640{
641 unsigned int gpio =
9ba17b4d 642 param_read(codec, codec->core.afg, AC_PAR_GPIO_CAP);
797760ab
AP
643 unsigned int enable, direction, wake, unsol, sticky, data;
644 int i, max;
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;
c4dc5071
TI
653 if (!max || max > 8)
654 return;
797760ab
AP
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)
668 snd_iprintf(buffer,
669 " IO[%d]: enable=%d, dir=%d, wake=%d, "
85639646 670 "sticky=%d, data=%d, unsol=%d\n", i,
797760ab
AP
671 (enable & (1<<i)) ? 1 : 0,
672 (direction & (1<<i)) ? 1 : 0,
673 (wake & (1<<i)) ? 1 : 0,
674 (sticky & (1<<i)) ? 1 : 0,
85639646
TI
675 (data & (1<<i)) ? 1 : 0,
676 (unsol & (1<<i)) ? 1 : 0);
797760ab 677 /* FIXME: add GPO and GPI pin information */
5b0cb1d8
JK
678 print_nid_array(buffer, codec, nid, &codec->mixers);
679 print_nid_array(buffer, codec, nid, &codec->nids);
797760ab 680}
1da177e4 681
7a624ea5
ML
682static void print_device_list(struct snd_info_buffer *buffer,
683 struct hda_codec *codec, hda_nid_t nid)
684{
685 int i, curr = -1;
686 u8 dev_list[AC_MAX_DEV_LIST_LEN];
687 int devlist_len;
688
689 devlist_len = snd_hda_get_devices(codec, nid, dev_list,
690 AC_MAX_DEV_LIST_LEN);
691 snd_iprintf(buffer, " Devices: %d\n", devlist_len);
692 if (devlist_len <= 0)
693 return;
694
695 curr = snd_hda_codec_read(codec, nid, 0,
696 AC_VERB_GET_DEVICE_SEL, 0);
697
698 for (i = 0; i < devlist_len; i++) {
699 if (i == curr)
700 snd_iprintf(buffer, " *");
701 else
702 snd_iprintf(buffer, " ");
703
704 snd_iprintf(buffer,
705 "Dev %02d: PD = %d, ELDV = %d, IA = %d\n", i,
706 !!(dev_list[i] & AC_DE_PD),
707 !!(dev_list[i] & AC_DE_ELDV),
708 !!(dev_list[i] & AC_DE_IA));
709 }
710}
711
7639a06c
TI
712static void print_codec_core_info(struct hdac_device *codec,
713 struct snd_info_buffer *buffer)
1da177e4 714{
812a2cca
TI
715 snd_iprintf(buffer, "Codec: ");
716 if (codec->vendor_name && codec->chip_name)
717 snd_iprintf(buffer, "%s %s\n",
718 codec->vendor_name, codec->chip_name);
719 else
720 snd_iprintf(buffer, "Not Set\n");
1da177e4 721 snd_iprintf(buffer, "Address: %d\n", codec->addr);
79c944ad
JK
722 if (codec->afg)
723 snd_iprintf(buffer, "AFG Function Id: 0x%x (unsol %u)\n",
724 codec->afg_function_id, codec->afg_unsol);
725 if (codec->mfg)
726 snd_iprintf(buffer, "MFG Function Id: 0x%x (unsol %u)\n",
727 codec->mfg_function_id, codec->mfg_unsol);
234b4346
PB
728 snd_iprintf(buffer, "Vendor Id: 0x%08x\n", codec->vendor_id);
729 snd_iprintf(buffer, "Subsystem Id: 0x%08x\n", codec->subsystem_id);
1da177e4 730 snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id);
e25c05f1
JP
731
732 if (codec->mfg)
733 snd_iprintf(buffer, "Modem Function Group: 0x%x\n", codec->mfg);
734 else
735 snd_iprintf(buffer, "No Modem Function Group found\n");
7639a06c
TI
736}
737
738static void print_codec_info(struct snd_info_entry *entry,
739 struct snd_info_buffer *buffer)
740{
741 struct hda_codec *codec = entry->private_data;
742 hda_nid_t nid, fg;
743 int i, nodes;
e25c05f1 744
7639a06c
TI
745 print_codec_core_info(&codec->core, buffer);
746 fg = codec->core.afg;
747 if (!fg)
ec9e1c5c 748 return;
cb53c626 749 snd_hda_power_up(codec);
b90d7760 750 snd_iprintf(buffer, "Default PCM:\n");
7639a06c 751 print_pcm_caps(buffer, codec, fg);
1da177e4 752 snd_iprintf(buffer, "Default Amp-In caps: ");
7639a06c 753 print_amp_caps(buffer, codec, fg, HDA_INPUT);
1da177e4 754 snd_iprintf(buffer, "Default Amp-Out caps: ");
7639a06c
TI
755 print_amp_caps(buffer, codec, fg, HDA_OUTPUT);
756 snd_iprintf(buffer, "State of AFG node 0x%02x:\n", fg);
757 print_power_state(buffer, codec, fg);
1da177e4 758
7639a06c 759 nodes = snd_hda_get_sub_nodes(codec, fg, &nid);
1da177e4
LT
760 if (! nid || nodes < 0) {
761 snd_iprintf(buffer, "Invalid AFG subtree\n");
cb53c626 762 snd_hda_power_down(codec);
1da177e4
LT
763 return;
764 }
797760ab 765
7639a06c 766 print_gpio(buffer, codec, fg);
2d34e1b3 767 if (codec->proc_widget_hook)
7639a06c 768 codec->proc_widget_hook(buffer, codec, fg);
797760ab 769
1da177e4 770 for (i = 0; i < nodes; i++, nid++) {
d01ce99f 771 unsigned int wid_caps =
9ba17b4d 772 param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
a22d543a 773 unsigned int wid_type = get_wcaps_type(wid_caps);
4eea3091 774 hda_nid_t *conn = NULL;
797760ab 775 int conn_len = 0;
3e289f16 776
1da177e4
LT
777 snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid,
778 get_wid_type_name(wid_type), wid_caps);
c4920606 779 if (wid_caps & AC_WCAP_STEREO) {
fd72d008 780 unsigned int chans = get_wcaps_channels(wid_caps);
c4920606
TI
781 if (chans == 2)
782 snd_iprintf(buffer, " Stereo");
783 else
784 snd_iprintf(buffer, " %d-Channels", chans);
785 } else
1da177e4
LT
786 snd_iprintf(buffer, " Mono");
787 if (wid_caps & AC_WCAP_DIGITAL)
788 snd_iprintf(buffer, " Digital");
789 if (wid_caps & AC_WCAP_IN_AMP)
790 snd_iprintf(buffer, " Amp-In");
791 if (wid_caps & AC_WCAP_OUT_AMP)
792 snd_iprintf(buffer, " Amp-Out");
797760ab
AP
793 if (wid_caps & AC_WCAP_STRIPE)
794 snd_iprintf(buffer, " Stripe");
795 if (wid_caps & AC_WCAP_LR_SWAP)
796 snd_iprintf(buffer, " R/L");
c4920606
TI
797 if (wid_caps & AC_WCAP_CP_CAPS)
798 snd_iprintf(buffer, " CP");
1da177e4
LT
799 snd_iprintf(buffer, "\n");
800
5b0cb1d8
JK
801 print_nid_array(buffer, codec, nid, &codec->mixers);
802 print_nid_array(buffer, codec, nid, &codec->nids);
3911a4c1
JK
803 print_nid_pcms(buffer, codec, nid);
804
e1716139
TI
805 /* volume knob is a special widget that always have connection
806 * list
807 */
808 if (wid_type == AC_WID_VOL_KNB)
809 wid_caps |= AC_WCAP_CONN_LIST;
810
4eea3091
TI
811 if (wid_caps & AC_WCAP_CONN_LIST) {
812 conn_len = snd_hda_get_num_raw_conns(codec, nid);
813 if (conn_len > 0) {
6da2ec56
KC
814 conn = kmalloc_array(conn_len,
815 sizeof(hda_nid_t),
816 GFP_KERNEL);
4eea3091
TI
817 if (!conn)
818 return;
819 if (snd_hda_get_raw_connections(codec, nid, conn,
820 conn_len) < 0)
821 conn_len = 0;
822 }
823 }
3e289f16 824
1da177e4
LT
825 if (wid_caps & AC_WCAP_IN_AMP) {
826 snd_iprintf(buffer, " Amp-In caps: ");
827 print_amp_caps(buffer, codec, nid, HDA_INPUT);
828 snd_iprintf(buffer, " Amp-In vals: ");
4f32456e
MK
829 if (wid_type == AC_WID_PIN ||
830 (codec->single_adc_amp &&
831 wid_type == AC_WID_AUD_IN))
832 print_amp_vals(buffer, codec, nid, HDA_INPUT,
cc261738 833 wid_caps, 1);
4f32456e
MK
834 else
835 print_amp_vals(buffer, codec, nid, HDA_INPUT,
cc261738 836 wid_caps, conn_len);
1da177e4
LT
837 }
838 if (wid_caps & AC_WCAP_OUT_AMP) {
839 snd_iprintf(buffer, " Amp-Out caps: ");
840 print_amp_caps(buffer, codec, nid, HDA_OUTPUT);
841 snd_iprintf(buffer, " Amp-Out vals: ");
9421f954
TI
842 if (wid_type == AC_WID_PIN &&
843 codec->pin_amp_workaround)
844 print_amp_vals(buffer, codec, nid, HDA_OUTPUT,
cc261738 845 wid_caps, conn_len);
9421f954
TI
846 else
847 print_amp_vals(buffer, codec, nid, HDA_OUTPUT,
cc261738 848 wid_caps, 1);
1da177e4
LT
849 }
850
e97a5167 851 switch (wid_type) {
797760ab
AP
852 case AC_WID_PIN: {
853 int supports_vref;
854 print_pin_caps(buffer, codec, nid, &supports_vref);
855 print_pin_ctls(buffer, codec, nid, supports_vref);
e97a5167 856 break;
797760ab 857 }
e97a5167 858 case AC_WID_VOL_KNB:
797760ab 859 print_vol_knob(buffer, codec, nid);
e97a5167
TI
860 break;
861 case AC_WID_AUD_OUT:
862 case AC_WID_AUD_IN:
797760ab
AP
863 print_audio_io(buffer, codec, nid, wid_type);
864 if (wid_caps & AC_WCAP_DIGITAL)
865 print_digital_conv(buffer, codec, nid);
e97a5167
TI
866 if (wid_caps & AC_WCAP_FORMAT_OVRD) {
867 snd_iprintf(buffer, " PCM:\n");
868 print_pcm_caps(buffer, codec, nid);
869 }
870 break;
1da177e4
LT
871 }
872
797760ab
AP
873 if (wid_caps & AC_WCAP_UNSOL_CAP)
874 print_unsol_cap(buffer, codec, nid);
875
b7027cc2 876 if (wid_caps & AC_WCAP_POWER)
797760ab
AP
877 print_power_state(buffer, codec, nid);
878
879 if (wid_caps & AC_WCAP_DELAY)
880 snd_iprintf(buffer, " Delay: %d samples\n",
881 (wid_caps & AC_WCAP_DELAY) >>
882 AC_WCAP_DELAY_SHIFT);
883
7a624ea5
ML
884 if (wid_type == AC_WID_PIN && codec->dp_mst)
885 print_device_list(buffer, codec, nid);
886
797760ab
AP
887 if (wid_caps & AC_WCAP_CONN_LIST)
888 print_conn_list(buffer, codec, nid, wid_type,
889 conn, conn_len);
890
891 if (wid_caps & AC_WCAP_PROC_WID)
892 print_proc_caps(buffer, codec, nid);
893
daead538
TI
894 if (codec->proc_widget_hook)
895 codec->proc_widget_hook(buffer, codec, nid);
4eea3091
TI
896
897 kfree(conn);
1da177e4 898 }
cb53c626 899 snd_hda_power_down(codec);
1da177e4
LT
900}
901
902/*
903 * create a proc read
904 */
905int snd_hda_codec_proc_new(struct hda_codec *codec)
906{
907 char name[32];
1da177e4 908
7639a06c 909 snprintf(name, sizeof(name), "codec#%d", codec->core.addr);
47f2769b 910 return snd_card_ro_proc_new(codec->card, name, codec, print_codec_info);
1da177e4
LT
911}
912