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