ALSA: hda - Add new GPU codec ID 0x10de0083 to snd-hda
[linux-2.6-block.git] / sound / pci / hda / hda_proc.c
CommitLineData
1da177e4
LT
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * Generic proc interface
5 *
6 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
7 *
8 *
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.
13 *
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.
18 *
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
22 */
23
1da177e4 24#include <linux/init.h>
4eea3091 25#include <linux/slab.h>
1da177e4 26#include <sound/core.h>
cd262518 27#include <linux/module.h>
1da177e4 28#include "hda_codec.h"
18612048 29#include "hda_local.h"
1da177e4 30
cd262518
DH
31static int dump_coef = -1;
32module_param(dump_coef, int, 0644);
33MODULE_PARM_DESC(dump_coef, "Dump processing coefficients in codec proc file (-1=auto, 0=disable, 1=enable)");
34
9ba17b4d
TI
35/* always use noncached version */
36#define param_read(codec, nid, parm) \
37 snd_hdac_read_parm_uncached(&(codec)->core, nid, parm)
38
1da177e4
LT
39static const char *get_wid_type_name(unsigned int wid_value)
40{
cc75cdfe 41 static const char * const names[16] = {
1da177e4
LT
42 [AC_WID_AUD_OUT] = "Audio Output",
43 [AC_WID_AUD_IN] = "Audio Input",
44 [AC_WID_AUD_MIX] = "Audio Mixer",
45 [AC_WID_AUD_SEL] = "Audio Selector",
46 [AC_WID_PIN] = "Pin Complex",
47 [AC_WID_POWER] = "Power Widget",
48 [AC_WID_VOL_KNB] = "Volume Knob Widget",
49 [AC_WID_BEEP] = "Beep Generator Widget",
50 [AC_WID_VENDOR] = "Vendor Defined Widget",
51 };
3a90274d
TI
52 if (wid_value == -1)
53 return "UNKNOWN Widget";
1da177e4
LT
54 wid_value &= 0xf;
55 if (names[wid_value])
56 return names[wid_value];
57 else
3bc89529 58 return "UNKNOWN Widget";
1da177e4
LT
59}
60
5b0cb1d8
JK
61static void print_nid_array(struct snd_info_buffer *buffer,
62 struct hda_codec *codec, hda_nid_t nid,
63 struct snd_array *array)
3911a4c1
JK
64{
65 int i;
5b0cb1d8 66 struct hda_nid_item *items = array->list, *item;
3911a4c1 67 struct snd_kcontrol *kctl;
5b0cb1d8
JK
68 for (i = 0; i < array->used; i++) {
69 item = &items[i];
70 if (item->nid == nid) {
71 kctl = item->kctl;
3911a4c1
JK
72 snd_iprintf(buffer,
73 " Control: name=\"%s\", index=%i, device=%i\n",
5b0cb1d8
JK
74 kctl->id.name, kctl->id.index + item->index,
75 kctl->id.device);
9e3fd871
JK
76 if (item->flags & HDA_NID_ITEM_AMP)
77 snd_iprintf(buffer,
78 " ControlAmp: chs=%lu, dir=%s, "
79 "idx=%lu, ofs=%lu\n",
80 get_amp_channels(kctl),
81 get_amp_direction(kctl) ? "Out" : "In",
82 get_amp_index(kctl),
83 get_amp_offset(kctl));
3911a4c1
JK
84 }
85 }
86}
87
88static void print_nid_pcms(struct snd_info_buffer *buffer,
89 struct hda_codec *codec, hda_nid_t nid)
90{
bbbc7e85 91 int type;
3911a4c1 92 struct hda_pcm *cpcm;
bbbc7e85
TI
93
94 list_for_each_entry(cpcm, &codec->pcm_list_head, list) {
3911a4c1
JK
95 for (type = 0; type < 2; type++) {
96 if (cpcm->stream[type].nid != nid || cpcm->pcm == NULL)
97 continue;
98 snd_iprintf(buffer, " Device: name=\"%s\", "
99 "type=\"%s\", device=%i\n",
100 cpcm->name,
101 snd_hda_pcm_type_name[cpcm->pcm_type],
102 cpcm->pcm->device);
103 }
104 }
105}
106
c8b6bf9b 107static void print_amp_caps(struct snd_info_buffer *buffer,
1da177e4
LT
108 struct hda_codec *codec, hda_nid_t nid, int dir)
109{
110 unsigned int caps;
9ba17b4d
TI
111 caps = param_read(codec, nid, dir == HDA_OUTPUT ?
112 AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP);
1da177e4
LT
113 if (caps == -1 || caps == 0) {
114 snd_iprintf(buffer, "N/A\n");
115 return;
116 }
d01ce99f
TI
117 snd_iprintf(buffer, "ofs=0x%02x, nsteps=0x%02x, stepsize=0x%02x, "
118 "mute=%x\n",
1da177e4
LT
119 caps & AC_AMPCAP_OFFSET,
120 (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT,
121 (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT,
122 (caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT);
123}
124
cc261738
TI
125/* is this a stereo widget or a stereo-to-mono mix? */
126static bool is_stereo_amps(struct hda_codec *codec, hda_nid_t nid,
127 int dir, unsigned int wcaps, int indices)
128{
129 hda_nid_t conn;
130
131 if (wcaps & AC_WCAP_STEREO)
132 return true;
133 /* check for a stereo-to-mono mix; it must be:
134 * only a single connection, only for input, and only a mixer widget
135 */
136 if (indices != 1 || dir != HDA_INPUT ||
137 get_wcaps_type(wcaps) != AC_WID_AUD_MIX)
138 return false;
139
140 if (snd_hda_get_raw_connections(codec, nid, &conn, 1) < 0)
141 return false;
142 /* the connection source is a stereo? */
143 wcaps = snd_hda_param_read(codec, conn, AC_PAR_AUDIO_WIDGET_CAP);
144 return !!(wcaps & AC_WCAP_STEREO);
145}
146
c8b6bf9b 147static void print_amp_vals(struct snd_info_buffer *buffer,
1da177e4 148 struct hda_codec *codec, hda_nid_t nid,
cc261738 149 int dir, unsigned int wcaps, int indices)
1da177e4
LT
150{
151 unsigned int val;
cc261738 152 bool stereo;
3e289f16
TI
153 int i;
154
cc261738
TI
155 stereo = is_stereo_amps(codec, nid, dir, wcaps, indices);
156
7f0e2f8b 157 dir = dir == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT;
3e289f16
TI
158 for (i = 0; i < indices; i++) {
159 snd_iprintf(buffer, " [");
2f179721
TI
160 val = snd_hda_codec_read(codec, nid, 0,
161 AC_VERB_GET_AMP_GAIN_MUTE,
162 AC_AMP_GET_LEFT | dir | i);
163 snd_iprintf(buffer, "0x%02x", val);
3e289f16 164 if (stereo) {
d01ce99f
TI
165 val = snd_hda_codec_read(codec, nid, 0,
166 AC_VERB_GET_AMP_GAIN_MUTE,
2f179721
TI
167 AC_AMP_GET_RIGHT | dir | i);
168 snd_iprintf(buffer, " 0x%02x", val);
3e289f16 169 }
2f179721 170 snd_iprintf(buffer, "]");
1da177e4 171 }
3e289f16 172 snd_iprintf(buffer, "\n");
1da177e4
LT
173}
174
33deeca3
WF
175static void print_pcm_rates(struct snd_info_buffer *buffer, unsigned int pcm)
176{
f71ff0d7
TI
177 static unsigned int rates[] = {
178 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
179 96000, 176400, 192000, 384000
180 };
181 int i;
d39b4352 182
b90d7760
TI
183 pcm &= AC_SUPPCM_RATES;
184 snd_iprintf(buffer, " rates [0x%x]:", pcm);
f71ff0d7
TI
185 for (i = 0; i < ARRAY_SIZE(rates); i++)
186 if (pcm & (1 << i))
187 snd_iprintf(buffer, " %d", rates[i]);
188 snd_iprintf(buffer, "\n");
b90d7760
TI
189}
190
d39b4352
WF
191static void print_pcm_bits(struct snd_info_buffer *buffer, unsigned int pcm)
192{
193 char buf[SND_PRINT_BITS_ADVISED_BUFSIZE];
b90d7760 194
b0e6481a 195 snd_iprintf(buffer, " bits [0x%x]:", (pcm >> 16) & 0xff);
d39b4352
WF
196 snd_print_pcm_bits(pcm, buf, sizeof(buf));
197 snd_iprintf(buffer, "%s\n", buf);
b90d7760
TI
198}
199
200static void print_pcm_formats(struct snd_info_buffer *buffer,
201 unsigned int streams)
202{
203 snd_iprintf(buffer, " formats [0x%x]:", streams & 0xf);
204 if (streams & AC_SUPFMT_PCM)
205 snd_iprintf(buffer, " PCM");
206 if (streams & AC_SUPFMT_FLOAT32)
207 snd_iprintf(buffer, " FLOAT");
208 if (streams & AC_SUPFMT_AC3)
209 snd_iprintf(buffer, " AC3");
210 snd_iprintf(buffer, "\n");
211}
212
c8b6bf9b 213static void print_pcm_caps(struct snd_info_buffer *buffer,
1da177e4
LT
214 struct hda_codec *codec, hda_nid_t nid)
215{
9ba17b4d
TI
216 unsigned int pcm = param_read(codec, nid, AC_PAR_PCM);
217 unsigned int stream = param_read(codec, nid, AC_PAR_STREAM);
1da177e4
LT
218 if (pcm == -1 || stream == -1) {
219 snd_iprintf(buffer, "N/A\n");
220 return;
221 }
b90d7760
TI
222 print_pcm_rates(buffer, pcm);
223 print_pcm_bits(buffer, pcm);
224 print_pcm_formats(buffer, stream);
1da177e4
LT
225}
226
1da177e4
LT
227static const char *get_jack_connection(u32 cfg)
228{
cc75cdfe 229 static const char * const names[16] = {
1da177e4
LT
230 "Unknown", "1/8", "1/4", "ATAPI",
231 "RCA", "Optical","Digital", "Analog",
232 "DIN", "XLR", "RJ11", "Comb",
233 NULL, NULL, NULL, "Other"
234 };
235 cfg = (cfg & AC_DEFCFG_CONN_TYPE) >> AC_DEFCFG_CONN_TYPE_SHIFT;
236 if (names[cfg])
237 return names[cfg];
238 else
239 return "UNKNOWN";
240}
241
242static const char *get_jack_color(u32 cfg)
243{
cc75cdfe 244 static const char * const names[16] = {
1da177e4
LT
245 "Unknown", "Black", "Grey", "Blue",
246 "Green", "Red", "Orange", "Yellow",
247 "Purple", "Pink", NULL, NULL,
248 NULL, NULL, "White", "Other",
249 };
250 cfg = (cfg & AC_DEFCFG_COLOR) >> AC_DEFCFG_COLOR_SHIFT;
251 if (names[cfg])
252 return names[cfg];
253 else
254 return "UNKNOWN";
255}
256
d2c6b63d
TI
257/*
258 * Parse the pin default config value and returns the string of the
259 * jack location, e.g. "Rear", "Front", etc.
260 */
261static const char *get_jack_location(u32 cfg)
262{
cc75cdfe 263 static const char * const bases[7] = {
d2c6b63d
TI
264 "N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom",
265 };
cc75cdfe 266 static const unsigned char specials_idx[] = {
d2c6b63d
TI
267 0x07, 0x08,
268 0x17, 0x18, 0x19,
269 0x37, 0x38
270 };
cc75cdfe 271 static const char * const specials[] = {
d2c6b63d
TI
272 "Rear Panel", "Drive Bar",
273 "Riser", "HDMI", "ATAPI",
274 "Mobile-In", "Mobile-Out"
275 };
276 int i;
277
278 cfg = (cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT;
279 if ((cfg & 0x0f) < 7)
280 return bases[cfg & 0x0f];
281 for (i = 0; i < ARRAY_SIZE(specials_idx); i++) {
282 if (cfg == specials_idx[i])
283 return specials[i];
284 }
285 return "UNKNOWN";
286}
287
288/*
289 * Parse the pin default config value and returns the string of the
290 * jack connectivity, i.e. external or internal connection.
291 */
292static const char *get_jack_connectivity(u32 cfg)
293{
cc75cdfe
TI
294 static const char * const jack_locations[4] = {
295 "Ext", "Int", "Sep", "Oth"
296 };
d2c6b63d
TI
297
298 return jack_locations[(cfg >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3];
299}
300
301/*
302 * Parse the pin default config value and returns the string of the
303 * jack type, i.e. the purpose of the jack, such as Line-Out or CD.
304 */
305static const char *get_jack_type(u32 cfg)
306{
cc75cdfe 307 static const char * const jack_types[16] = {
d2c6b63d
TI
308 "Line Out", "Speaker", "HP Out", "CD",
309 "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
310 "Line In", "Aux", "Mic", "Telephony",
311 "SPDIF In", "Digital In", "Reserved", "Other"
312 };
313
314 return jack_types[(cfg & AC_DEFCFG_DEVICE)
315 >> AC_DEFCFG_DEVICE_SHIFT];
316}
317
c8b6bf9b 318static void print_pin_caps(struct snd_info_buffer *buffer,
797760ab
AP
319 struct hda_codec *codec, hda_nid_t nid,
320 int *supports_vref)
1da177e4 321{
cc75cdfe
TI
322 static const char * const jack_conns[4] = {
323 "Jack", "N/A", "Fixed", "Both"
324 };
e97a5167 325 unsigned int caps, val;
1da177e4 326
9ba17b4d 327 caps = param_read(codec, nid, AC_PAR_PIN_CAP);
0481f453 328 snd_iprintf(buffer, " Pincap 0x%08x:", caps);
1da177e4
LT
329 if (caps & AC_PINCAP_IN)
330 snd_iprintf(buffer, " IN");
331 if (caps & AC_PINCAP_OUT)
332 snd_iprintf(buffer, " OUT");
333 if (caps & AC_PINCAP_HP_DRV)
334 snd_iprintf(buffer, " HP");
5885492a
TI
335 if (caps & AC_PINCAP_EAPD)
336 snd_iprintf(buffer, " EAPD");
337 if (caps & AC_PINCAP_PRES_DETECT)
338 snd_iprintf(buffer, " Detect");
797760ab
AP
339 if (caps & AC_PINCAP_BALANCE)
340 snd_iprintf(buffer, " Balanced");
c4920606
TI
341 if (caps & AC_PINCAP_HDMI) {
342 /* Realtek uses this bit as a different meaning */
7639a06c 343 if ((codec->core.vendor_id >> 16) == 0x10ec)
c4920606 344 snd_iprintf(buffer, " R/L");
b923528e
WF
345 else {
346 if (caps & AC_PINCAP_HBR)
347 snd_iprintf(buffer, " HBR");
c4920606 348 snd_iprintf(buffer, " HDMI");
b923528e 349 }
c4920606 350 }
728765b3
WF
351 if (caps & AC_PINCAP_DP)
352 snd_iprintf(buffer, " DP");
797760ab
AP
353 if (caps & AC_PINCAP_TRIG_REQ)
354 snd_iprintf(buffer, " Trigger");
355 if (caps & AC_PINCAP_IMP_SENSE)
356 snd_iprintf(buffer, " ImpSense");
1da177e4 357 snd_iprintf(buffer, "\n");
797760ab
AP
358 if (caps & AC_PINCAP_VREF) {
359 unsigned int vref =
360 (caps & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
361 snd_iprintf(buffer, " Vref caps:");
362 if (vref & AC_PINCAP_VREF_HIZ)
363 snd_iprintf(buffer, " HIZ");
364 if (vref & AC_PINCAP_VREF_50)
365 snd_iprintf(buffer, " 50");
366 if (vref & AC_PINCAP_VREF_GRD)
367 snd_iprintf(buffer, " GRD");
368 if (vref & AC_PINCAP_VREF_80)
369 snd_iprintf(buffer, " 80");
370 if (vref & AC_PINCAP_VREF_100)
371 snd_iprintf(buffer, " 100");
372 snd_iprintf(buffer, "\n");
373 *supports_vref = 1;
374 } else
375 *supports_vref = 0;
376 if (caps & AC_PINCAP_EAPD) {
377 val = snd_hda_codec_read(codec, nid, 0,
378 AC_VERB_GET_EAPD_BTLENABLE, 0);
379 snd_iprintf(buffer, " EAPD 0x%x:", val);
380 if (val & AC_EAPDBTL_BALANCED)
381 snd_iprintf(buffer, " BALANCED");
382 if (val & AC_EAPDBTL_EAPD)
383 snd_iprintf(buffer, " EAPD");
384 if (val & AC_EAPDBTL_LR_SWAP)
385 snd_iprintf(buffer, " R/L");
386 snd_iprintf(buffer, "\n");
387 }
1da177e4 388 caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
b0c95f51
TI
389 snd_iprintf(buffer, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps,
390 jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT],
d2c6b63d
TI
391 get_jack_type(caps),
392 get_jack_connectivity(caps),
393 get_jack_location(caps));
1da177e4
LT
394 snd_iprintf(buffer, " Conn = %s, Color = %s\n",
395 get_jack_connection(caps),
396 get_jack_color(caps));
797760ab
AP
397 /* Default association and sequence values refer to default grouping
398 * of pin complexes and their sequence within the group. This is used
399 * for priority and resource allocation.
400 */
401 snd_iprintf(buffer, " DefAssociation = 0x%x, Sequence = 0x%x\n",
402 (caps & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT,
403 caps & AC_DEFCFG_SEQUENCE);
404 if (((caps & AC_DEFCFG_MISC) >> AC_DEFCFG_MISC_SHIFT) &
405 AC_DEFCFG_MISC_NO_PRESENCE) {
406 /* Miscellaneous bit indicates external hardware does not
407 * support presence detection even if the pin complex
408 * indicates it is supported.
409 */
410 snd_iprintf(buffer, " Misc = NO_PRESENCE\n");
e97a5167 411 }
1da177e4
LT
412}
413
797760ab
AP
414static void print_pin_ctls(struct snd_info_buffer *buffer,
415 struct hda_codec *codec, hda_nid_t nid,
416 int supports_vref)
417{
418 unsigned int pinctls;
419
420 pinctls = snd_hda_codec_read(codec, nid, 0,
421 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
422 snd_iprintf(buffer, " Pin-ctls: 0x%02x:", pinctls);
423 if (pinctls & AC_PINCTL_IN_EN)
424 snd_iprintf(buffer, " IN");
425 if (pinctls & AC_PINCTL_OUT_EN)
426 snd_iprintf(buffer, " OUT");
427 if (pinctls & AC_PINCTL_HP_EN)
428 snd_iprintf(buffer, " HP");
429 if (supports_vref) {
430 int vref = pinctls & AC_PINCTL_VREFEN;
431 switch (vref) {
432 case AC_PINCTL_VREF_HIZ:
433 snd_iprintf(buffer, " VREF_HIZ");
434 break;
435 case AC_PINCTL_VREF_50:
436 snd_iprintf(buffer, " VREF_50");
437 break;
438 case AC_PINCTL_VREF_GRD:
439 snd_iprintf(buffer, " VREF_GRD");
440 break;
441 case AC_PINCTL_VREF_80:
442 snd_iprintf(buffer, " VREF_80");
443 break;
444 case AC_PINCTL_VREF_100:
445 snd_iprintf(buffer, " VREF_100");
446 break;
447 }
448 }
449 snd_iprintf(buffer, "\n");
450}
451
452static void print_vol_knob(struct snd_info_buffer *buffer,
453 struct hda_codec *codec, hda_nid_t nid)
454{
9ba17b4d 455 unsigned int cap = param_read(codec, nid, AC_PAR_VOL_KNB_CAP);
797760ab
AP
456 snd_iprintf(buffer, " Volume-Knob: delta=%d, steps=%d, ",
457 (cap >> 7) & 1, cap & 0x7f);
458 cap = snd_hda_codec_read(codec, nid, 0,
459 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
460 snd_iprintf(buffer, "direct=%d, val=%d\n",
461 (cap >> 7) & 1, cap & 0x7f);
462}
463
464static void print_audio_io(struct snd_info_buffer *buffer,
465 struct hda_codec *codec, hda_nid_t nid,
466 unsigned int wid_type)
467{
3911a4c1 468 int conv = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
797760ab
AP
469 snd_iprintf(buffer,
470 " Converter: stream=%d, channel=%d\n",
471 (conv & AC_CONV_STREAM) >> AC_CONV_STREAM_SHIFT,
472 conv & AC_CONV_CHANNEL);
473
474 if (wid_type == AC_WID_AUD_IN && (conv & AC_CONV_CHANNEL) == 0) {
475 int sdi = snd_hda_codec_read(codec, nid, 0,
476 AC_VERB_GET_SDI_SELECT, 0);
477 snd_iprintf(buffer, " SDI-Select: %d\n",
478 sdi & AC_SDI_SELECT);
479 }
480}
481
482static void print_digital_conv(struct snd_info_buffer *buffer,
483 struct hda_codec *codec, hda_nid_t nid)
484{
485 unsigned int digi1 = snd_hda_codec_read(codec, nid, 0,
486 AC_VERB_GET_DIGI_CONVERT_1, 0);
61525979
WX
487 unsigned char digi2 = digi1 >> 8;
488 unsigned char digi3 = digi1 >> 16;
489
797760ab
AP
490 snd_iprintf(buffer, " Digital:");
491 if (digi1 & AC_DIG1_ENABLE)
492 snd_iprintf(buffer, " Enabled");
493 if (digi1 & AC_DIG1_V)
494 snd_iprintf(buffer, " Validity");
495 if (digi1 & AC_DIG1_VCFG)
496 snd_iprintf(buffer, " ValidityCfg");
497 if (digi1 & AC_DIG1_EMPHASIS)
498 snd_iprintf(buffer, " Preemphasis");
499 if (digi1 & AC_DIG1_COPYRIGHT)
088c820b 500 snd_iprintf(buffer, " Non-Copyright");
797760ab
AP
501 if (digi1 & AC_DIG1_NONAUDIO)
502 snd_iprintf(buffer, " Non-Audio");
503 if (digi1 & AC_DIG1_PROFESSIONAL)
504 snd_iprintf(buffer, " Pro");
505 if (digi1 & AC_DIG1_LEVEL)
506 snd_iprintf(buffer, " GenLevel");
61525979
WX
507 if (digi3 & AC_DIG3_KAE)
508 snd_iprintf(buffer, " KAE");
797760ab 509 snd_iprintf(buffer, "\n");
a1855d80 510 snd_iprintf(buffer, " Digital category: 0x%x\n",
61525979
WX
511 digi2 & AC_DIG2_CC);
512 snd_iprintf(buffer, " IEC Coding Type: 0x%x\n",
513 digi3 & AC_DIG3_ICT);
797760ab
AP
514}
515
516static const char *get_pwr_state(u32 state)
517{
167d2d55
TI
518 static const char * const buf[] = {
519 "D0", "D1", "D2", "D3", "D3cold"
797760ab 520 };
167d2d55 521 if (state < ARRAY_SIZE(buf))
797760ab
AP
522 return buf[state];
523 return "UNKNOWN";
524}
525
526static void print_power_state(struct snd_info_buffer *buffer,
527 struct hda_codec *codec, hda_nid_t nid)
528{
cc75cdfe 529 static const char * const names[] = {
83d605fd
WF
530 [ilog2(AC_PWRST_D0SUP)] = "D0",
531 [ilog2(AC_PWRST_D1SUP)] = "D1",
532 [ilog2(AC_PWRST_D2SUP)] = "D2",
533 [ilog2(AC_PWRST_D3SUP)] = "D3",
534 [ilog2(AC_PWRST_D3COLDSUP)] = "D3cold",
535 [ilog2(AC_PWRST_S3D3COLDSUP)] = "S3D3cold",
536 [ilog2(AC_PWRST_CLKSTOP)] = "CLKSTOP",
537 [ilog2(AC_PWRST_EPSS)] = "EPSS",
538 };
539
9ba17b4d 540 int sup = param_read(codec, nid, AC_PAR_POWER_STATE);
797760ab
AP
541 int pwr = snd_hda_codec_read(codec, nid, 0,
542 AC_VERB_GET_POWER_STATE, 0);
1d260d7b
TI
543 if (sup != -1) {
544 int i;
545
546 snd_iprintf(buffer, " Power states: ");
547 for (i = 0; i < ARRAY_SIZE(names); i++) {
548 if (sup & (1U << i))
549 snd_iprintf(buffer, " %s", names[i]);
550 }
551 snd_iprintf(buffer, "\n");
552 }
83d605fd 553
ce63f3ba 554 snd_iprintf(buffer, " Power: setting=%s, actual=%s",
797760ab
AP
555 get_pwr_state(pwr & AC_PWRST_SETTING),
556 get_pwr_state((pwr & AC_PWRST_ACTUAL) >>
557 AC_PWRST_ACTUAL_SHIFT));
ce63f3ba
WX
558 if (pwr & AC_PWRST_ERROR)
559 snd_iprintf(buffer, ", Error");
560 if (pwr & AC_PWRST_CLK_STOP_OK)
561 snd_iprintf(buffer, ", Clock-stop-OK");
562 if (pwr & AC_PWRST_SETTING_RESET)
563 snd_iprintf(buffer, ", Setting-reset");
564 snd_iprintf(buffer, "\n");
797760ab
AP
565}
566
567static void print_unsol_cap(struct snd_info_buffer *buffer,
568 struct hda_codec *codec, hda_nid_t nid)
569{
570 int unsol = snd_hda_codec_read(codec, nid, 0,
571 AC_VERB_GET_UNSOLICITED_RESPONSE, 0);
572 snd_iprintf(buffer,
573 " Unsolicited: tag=%02x, enabled=%d\n",
574 unsol & AC_UNSOL_TAG,
575 (unsol & AC_UNSOL_ENABLED) ? 1 : 0);
576}
577
cd262518
DH
578static inline bool can_dump_coef(struct hda_codec *codec)
579{
580 switch (dump_coef) {
581 case 0: return false;
582 case 1: return true;
583 default: return codec->dump_coef;
584 }
585}
586
797760ab
AP
587static void print_proc_caps(struct snd_info_buffer *buffer,
588 struct hda_codec *codec, hda_nid_t nid)
589{
cd262518 590 unsigned int i, ncoeff, oldindex;
9ba17b4d 591 unsigned int proc_caps = param_read(codec, nid, AC_PAR_PROC_CAP);
cd262518 592 ncoeff = (proc_caps & AC_PCAP_NUM_COEF) >> AC_PCAP_NUM_COEF_SHIFT;
797760ab 593 snd_iprintf(buffer, " Processing caps: benign=%d, ncoeff=%d\n",
cd262518
DH
594 proc_caps & AC_PCAP_BENIGN, ncoeff);
595
596 if (!can_dump_coef(codec))
597 return;
598
599 /* Note: This is racy - another process could run in parallel and change
600 the coef index too. */
601 oldindex = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_COEF_INDEX, 0);
602 for (i = 0; i < ncoeff; i++) {
603 unsigned int val;
604 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, i);
605 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF,
606 0);
607 snd_iprintf(buffer, " Coeff 0x%02x: 0x%04x\n", i, val);
608 }
609 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, oldindex);
797760ab
AP
610}
611
612static void print_conn_list(struct snd_info_buffer *buffer,
613 struct hda_codec *codec, hda_nid_t nid,
614 unsigned int wid_type, hda_nid_t *conn,
615 int conn_len)
616{
617 int c, curr = -1;
8b2c7a5c
WX
618 const hda_nid_t *list;
619 int cache_len;
797760ab 620
07a1e813
TI
621 if (conn_len > 1 &&
622 wid_type != AC_WID_AUD_MIX &&
623 wid_type != AC_WID_VOL_KNB &&
624 wid_type != AC_WID_POWER)
797760ab
AP
625 curr = snd_hda_codec_read(codec, nid, 0,
626 AC_VERB_GET_CONNECT_SEL, 0);
627 snd_iprintf(buffer, " Connection: %d\n", conn_len);
628 if (conn_len > 0) {
629 snd_iprintf(buffer, " ");
630 for (c = 0; c < conn_len; c++) {
631 snd_iprintf(buffer, " 0x%02x", conn[c]);
632 if (c == curr)
633 snd_iprintf(buffer, "*");
634 }
635 snd_iprintf(buffer, "\n");
636 }
8b2c7a5c
WX
637
638 /* Get Cache connections info */
639 cache_len = snd_hda_get_conn_list(codec, nid, &list);
f4d77031
DC
640 if (cache_len >= 0 && (cache_len != conn_len ||
641 memcmp(list, conn, conn_len) != 0)) {
8b2c7a5c
WX
642 snd_iprintf(buffer, " In-driver Connection: %d\n", cache_len);
643 if (cache_len > 0) {
644 snd_iprintf(buffer, " ");
645 for (c = 0; c < cache_len; c++)
646 snd_iprintf(buffer, " 0x%02x", list[c]);
647 snd_iprintf(buffer, "\n");
648 }
649 }
797760ab
AP
650}
651
797760ab
AP
652static void print_gpio(struct snd_info_buffer *buffer,
653 struct hda_codec *codec, hda_nid_t nid)
654{
655 unsigned int gpio =
9ba17b4d 656 param_read(codec, codec->core.afg, AC_PAR_GPIO_CAP);
797760ab
AP
657 unsigned int enable, direction, wake, unsol, sticky, data;
658 int i, max;
659 snd_iprintf(buffer, "GPIO: io=%d, o=%d, i=%d, "
660 "unsolicited=%d, wake=%d\n",
661 gpio & AC_GPIO_IO_COUNT,
662 (gpio & AC_GPIO_O_COUNT) >> AC_GPIO_O_COUNT_SHIFT,
663 (gpio & AC_GPIO_I_COUNT) >> AC_GPIO_I_COUNT_SHIFT,
664 (gpio & AC_GPIO_UNSOLICITED) ? 1 : 0,
665 (gpio & AC_GPIO_WAKE) ? 1 : 0);
666 max = gpio & AC_GPIO_IO_COUNT;
c4dc5071
TI
667 if (!max || max > 8)
668 return;
797760ab
AP
669 enable = snd_hda_codec_read(codec, nid, 0,
670 AC_VERB_GET_GPIO_MASK, 0);
671 direction = snd_hda_codec_read(codec, nid, 0,
672 AC_VERB_GET_GPIO_DIRECTION, 0);
673 wake = snd_hda_codec_read(codec, nid, 0,
674 AC_VERB_GET_GPIO_WAKE_MASK, 0);
675 unsol = snd_hda_codec_read(codec, nid, 0,
676 AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK, 0);
677 sticky = snd_hda_codec_read(codec, nid, 0,
678 AC_VERB_GET_GPIO_STICKY_MASK, 0);
679 data = snd_hda_codec_read(codec, nid, 0,
680 AC_VERB_GET_GPIO_DATA, 0);
681 for (i = 0; i < max; ++i)
682 snd_iprintf(buffer,
683 " IO[%d]: enable=%d, dir=%d, wake=%d, "
85639646 684 "sticky=%d, data=%d, unsol=%d\n", i,
797760ab
AP
685 (enable & (1<<i)) ? 1 : 0,
686 (direction & (1<<i)) ? 1 : 0,
687 (wake & (1<<i)) ? 1 : 0,
688 (sticky & (1<<i)) ? 1 : 0,
85639646
TI
689 (data & (1<<i)) ? 1 : 0,
690 (unsol & (1<<i)) ? 1 : 0);
797760ab 691 /* FIXME: add GPO and GPI pin information */
5b0cb1d8
JK
692 print_nid_array(buffer, codec, nid, &codec->mixers);
693 print_nid_array(buffer, codec, nid, &codec->nids);
797760ab 694}
1da177e4 695
7a624ea5
ML
696static void print_device_list(struct snd_info_buffer *buffer,
697 struct hda_codec *codec, hda_nid_t nid)
698{
699 int i, curr = -1;
700 u8 dev_list[AC_MAX_DEV_LIST_LEN];
701 int devlist_len;
702
703 devlist_len = snd_hda_get_devices(codec, nid, dev_list,
704 AC_MAX_DEV_LIST_LEN);
705 snd_iprintf(buffer, " Devices: %d\n", devlist_len);
706 if (devlist_len <= 0)
707 return;
708
709 curr = snd_hda_codec_read(codec, nid, 0,
710 AC_VERB_GET_DEVICE_SEL, 0);
711
712 for (i = 0; i < devlist_len; i++) {
713 if (i == curr)
714 snd_iprintf(buffer, " *");
715 else
716 snd_iprintf(buffer, " ");
717
718 snd_iprintf(buffer,
719 "Dev %02d: PD = %d, ELDV = %d, IA = %d\n", i,
720 !!(dev_list[i] & AC_DE_PD),
721 !!(dev_list[i] & AC_DE_ELDV),
722 !!(dev_list[i] & AC_DE_IA));
723 }
724}
725
7639a06c
TI
726static void print_codec_core_info(struct hdac_device *codec,
727 struct snd_info_buffer *buffer)
1da177e4 728{
812a2cca
TI
729 snd_iprintf(buffer, "Codec: ");
730 if (codec->vendor_name && codec->chip_name)
731 snd_iprintf(buffer, "%s %s\n",
732 codec->vendor_name, codec->chip_name);
733 else
734 snd_iprintf(buffer, "Not Set\n");
1da177e4 735 snd_iprintf(buffer, "Address: %d\n", codec->addr);
79c944ad
JK
736 if (codec->afg)
737 snd_iprintf(buffer, "AFG Function Id: 0x%x (unsol %u)\n",
738 codec->afg_function_id, codec->afg_unsol);
739 if (codec->mfg)
740 snd_iprintf(buffer, "MFG Function Id: 0x%x (unsol %u)\n",
741 codec->mfg_function_id, codec->mfg_unsol);
234b4346
PB
742 snd_iprintf(buffer, "Vendor Id: 0x%08x\n", codec->vendor_id);
743 snd_iprintf(buffer, "Subsystem Id: 0x%08x\n", codec->subsystem_id);
1da177e4 744 snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id);
e25c05f1
JP
745
746 if (codec->mfg)
747 snd_iprintf(buffer, "Modem Function Group: 0x%x\n", codec->mfg);
748 else
749 snd_iprintf(buffer, "No Modem Function Group found\n");
7639a06c
TI
750}
751
752static void print_codec_info(struct snd_info_entry *entry,
753 struct snd_info_buffer *buffer)
754{
755 struct hda_codec *codec = entry->private_data;
756 hda_nid_t nid, fg;
757 int i, nodes;
e25c05f1 758
7639a06c
TI
759 print_codec_core_info(&codec->core, buffer);
760 fg = codec->core.afg;
761 if (!fg)
ec9e1c5c 762 return;
cb53c626 763 snd_hda_power_up(codec);
b90d7760 764 snd_iprintf(buffer, "Default PCM:\n");
7639a06c 765 print_pcm_caps(buffer, codec, fg);
1da177e4 766 snd_iprintf(buffer, "Default Amp-In caps: ");
7639a06c 767 print_amp_caps(buffer, codec, fg, HDA_INPUT);
1da177e4 768 snd_iprintf(buffer, "Default Amp-Out caps: ");
7639a06c
TI
769 print_amp_caps(buffer, codec, fg, HDA_OUTPUT);
770 snd_iprintf(buffer, "State of AFG node 0x%02x:\n", fg);
771 print_power_state(buffer, codec, fg);
1da177e4 772
7639a06c 773 nodes = snd_hda_get_sub_nodes(codec, fg, &nid);
1da177e4
LT
774 if (! nid || nodes < 0) {
775 snd_iprintf(buffer, "Invalid AFG subtree\n");
cb53c626 776 snd_hda_power_down(codec);
1da177e4
LT
777 return;
778 }
797760ab 779
7639a06c 780 print_gpio(buffer, codec, fg);
2d34e1b3 781 if (codec->proc_widget_hook)
7639a06c 782 codec->proc_widget_hook(buffer, codec, fg);
797760ab 783
1da177e4 784 for (i = 0; i < nodes; i++, nid++) {
d01ce99f 785 unsigned int wid_caps =
9ba17b4d 786 param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
a22d543a 787 unsigned int wid_type = get_wcaps_type(wid_caps);
4eea3091 788 hda_nid_t *conn = NULL;
797760ab 789 int conn_len = 0;
3e289f16 790
1da177e4
LT
791 snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid,
792 get_wid_type_name(wid_type), wid_caps);
c4920606 793 if (wid_caps & AC_WCAP_STEREO) {
fd72d008 794 unsigned int chans = get_wcaps_channels(wid_caps);
c4920606
TI
795 if (chans == 2)
796 snd_iprintf(buffer, " Stereo");
797 else
798 snd_iprintf(buffer, " %d-Channels", chans);
799 } else
1da177e4
LT
800 snd_iprintf(buffer, " Mono");
801 if (wid_caps & AC_WCAP_DIGITAL)
802 snd_iprintf(buffer, " Digital");
803 if (wid_caps & AC_WCAP_IN_AMP)
804 snd_iprintf(buffer, " Amp-In");
805 if (wid_caps & AC_WCAP_OUT_AMP)
806 snd_iprintf(buffer, " Amp-Out");
797760ab
AP
807 if (wid_caps & AC_WCAP_STRIPE)
808 snd_iprintf(buffer, " Stripe");
809 if (wid_caps & AC_WCAP_LR_SWAP)
810 snd_iprintf(buffer, " R/L");
c4920606
TI
811 if (wid_caps & AC_WCAP_CP_CAPS)
812 snd_iprintf(buffer, " CP");
1da177e4
LT
813 snd_iprintf(buffer, "\n");
814
5b0cb1d8
JK
815 print_nid_array(buffer, codec, nid, &codec->mixers);
816 print_nid_array(buffer, codec, nid, &codec->nids);
3911a4c1
JK
817 print_nid_pcms(buffer, codec, nid);
818
e1716139
TI
819 /* volume knob is a special widget that always have connection
820 * list
821 */
822 if (wid_type == AC_WID_VOL_KNB)
823 wid_caps |= AC_WCAP_CONN_LIST;
824
4eea3091
TI
825 if (wid_caps & AC_WCAP_CONN_LIST) {
826 conn_len = snd_hda_get_num_raw_conns(codec, nid);
827 if (conn_len > 0) {
828 conn = kmalloc(sizeof(hda_nid_t) * conn_len,
829 GFP_KERNEL);
830 if (!conn)
831 return;
832 if (snd_hda_get_raw_connections(codec, nid, conn,
833 conn_len) < 0)
834 conn_len = 0;
835 }
836 }
3e289f16 837
1da177e4
LT
838 if (wid_caps & AC_WCAP_IN_AMP) {
839 snd_iprintf(buffer, " Amp-In caps: ");
840 print_amp_caps(buffer, codec, nid, HDA_INPUT);
841 snd_iprintf(buffer, " Amp-In vals: ");
4f32456e
MK
842 if (wid_type == AC_WID_PIN ||
843 (codec->single_adc_amp &&
844 wid_type == AC_WID_AUD_IN))
845 print_amp_vals(buffer, codec, nid, HDA_INPUT,
cc261738 846 wid_caps, 1);
4f32456e
MK
847 else
848 print_amp_vals(buffer, codec, nid, HDA_INPUT,
cc261738 849 wid_caps, conn_len);
1da177e4
LT
850 }
851 if (wid_caps & AC_WCAP_OUT_AMP) {
852 snd_iprintf(buffer, " Amp-Out caps: ");
853 print_amp_caps(buffer, codec, nid, HDA_OUTPUT);
854 snd_iprintf(buffer, " Amp-Out vals: ");
9421f954
TI
855 if (wid_type == AC_WID_PIN &&
856 codec->pin_amp_workaround)
857 print_amp_vals(buffer, codec, nid, HDA_OUTPUT,
cc261738 858 wid_caps, conn_len);
9421f954
TI
859 else
860 print_amp_vals(buffer, codec, nid, HDA_OUTPUT,
cc261738 861 wid_caps, 1);
1da177e4
LT
862 }
863
e97a5167 864 switch (wid_type) {
797760ab
AP
865 case AC_WID_PIN: {
866 int supports_vref;
867 print_pin_caps(buffer, codec, nid, &supports_vref);
868 print_pin_ctls(buffer, codec, nid, supports_vref);
e97a5167 869 break;
797760ab 870 }
e97a5167 871 case AC_WID_VOL_KNB:
797760ab 872 print_vol_knob(buffer, codec, nid);
e97a5167
TI
873 break;
874 case AC_WID_AUD_OUT:
875 case AC_WID_AUD_IN:
797760ab
AP
876 print_audio_io(buffer, codec, nid, wid_type);
877 if (wid_caps & AC_WCAP_DIGITAL)
878 print_digital_conv(buffer, codec, nid);
e97a5167
TI
879 if (wid_caps & AC_WCAP_FORMAT_OVRD) {
880 snd_iprintf(buffer, " PCM:\n");
881 print_pcm_caps(buffer, codec, nid);
882 }
883 break;
1da177e4
LT
884 }
885
797760ab
AP
886 if (wid_caps & AC_WCAP_UNSOL_CAP)
887 print_unsol_cap(buffer, codec, nid);
888
b7027cc2 889 if (wid_caps & AC_WCAP_POWER)
797760ab
AP
890 print_power_state(buffer, codec, nid);
891
892 if (wid_caps & AC_WCAP_DELAY)
893 snd_iprintf(buffer, " Delay: %d samples\n",
894 (wid_caps & AC_WCAP_DELAY) >>
895 AC_WCAP_DELAY_SHIFT);
896
7a624ea5
ML
897 if (wid_type == AC_WID_PIN && codec->dp_mst)
898 print_device_list(buffer, codec, nid);
899
797760ab
AP
900 if (wid_caps & AC_WCAP_CONN_LIST)
901 print_conn_list(buffer, codec, nid, wid_type,
902 conn, conn_len);
903
904 if (wid_caps & AC_WCAP_PROC_WID)
905 print_proc_caps(buffer, codec, nid);
906
daead538
TI
907 if (codec->proc_widget_hook)
908 codec->proc_widget_hook(buffer, codec, nid);
4eea3091
TI
909
910 kfree(conn);
1da177e4 911 }
cb53c626 912 snd_hda_power_down(codec);
1da177e4
LT
913}
914
915/*
916 * create a proc read
917 */
918int snd_hda_codec_proc_new(struct hda_codec *codec)
919{
920 char name[32];
c8b6bf9b 921 struct snd_info_entry *entry;
1da177e4
LT
922 int err;
923
7639a06c 924 snprintf(name, sizeof(name), "codec#%d", codec->core.addr);
6efdd851 925 err = snd_card_proc_new(codec->card, name, &entry);
1da177e4
LT
926 if (err < 0)
927 return err;
928
bf850204 929 snd_info_set_text_ops(entry, codec, print_codec_info);
1da177e4
LT
930 return 0;
931}
932