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 24 #include <linux/init.h> 25 #include <sound/core.h> 26 #include "hda_codec.h" 27 #include "hda_local.h" 28 29 static const char *get_wid_type_name(unsigned int wid_value) 30 { 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", 41 }; 42 wid_value &= 0xf; 43 if (names[wid_value]) 44 return names[wid_value]; 45 else 46 return "UNKNOWN Widget"; 47 } 48 49 static void print_amp_caps(struct snd_info_buffer *buffer, 50 struct hda_codec *codec, hda_nid_t nid, int dir) 51 { 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; 59 } 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); 66 } 67 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) 71 { 72 unsigned int val; 73 int i; 74 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); 83 } 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); 88 } 89 snd_iprintf(buffer, "\n"); 90 } 91 92 static void print_pcm_rates(struct snd_info_buffer *buffer, unsigned int pcm) 93 { 94 static unsigned int rates[] = { 95 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200, 96 96000, 176400, 192000, 384000 97 }; 98 int i; 99 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"); 106 } 107 108 static void print_pcm_bits(struct snd_info_buffer *buffer, unsigned int pcm) 109 { 110 static unsigned int bits[] = { 8, 16, 20, 24, 32 }; 111 int i; 112 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"); 119 } 120 121 static void print_pcm_formats(struct snd_info_buffer *buffer, 122 unsigned int streams) 123 { 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"); 132 } 133 134 static void print_pcm_caps(struct snd_info_buffer *buffer, 135 struct hda_codec *codec, hda_nid_t nid) 136 { 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; 142 } 143 print_pcm_rates(buffer, pcm); 144 print_pcm_bits(buffer, pcm); 145 print_pcm_formats(buffer, stream); 146 } 147 148 static const char *get_jack_location(u32 cfg) 149 { 150 static char *bases[7] = { 151 "N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom", 152 }; 153 static unsigned char specials_idx[] = { 154 0x07, 0x08, 155 0x17, 0x18, 0x19, 156 0x37, 0x38 157 }; 158 static char *specials[] = { 159 "Rear Panel", "Drive Bar", 160 "Riser", "HDMI", "ATAPI", 161 "Mobile-In", "Mobile-Out" 162 }; 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]; 170 } 171 return "UNKNOWN"; 172 } 173 174 static const char *get_jack_connection(u32 cfg) 175 { 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" 181 }; 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"; 187 } 188 189 static const char *get_jack_color(u32 cfg) 190 { 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", 196 }; 197 cfg = (cfg & AC_DEFCFG_COLOR) >> AC_DEFCFG_COLOR_SHIFT; 198 if (names[cfg]) 199 return names[cfg]; 200 else 201 return "UNKNOWN"; 202 } 203 204 static void print_pin_caps(struct snd_info_buffer *buffer, 205 struct hda_codec *codec, hda_nid_t nid, 206 int *supports_vref) 207 { 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" 214 }; 215 static char *jack_locations[4] = { "Ext", "Int", "Sep", "Oth" }; 216 unsigned int caps, val; 217 218 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); 219 snd_iprintf(buffer, " Pincap 0x08%x:", 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"); 268 } 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. 281 */ 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. 290 */ 291 snd_iprintf(buffer, " Misc = NO_PRESENCE\n"); 292 } 293 } 294 295 static void print_pin_ctls(struct snd_info_buffer *buffer, 296 struct hda_codec *codec, hda_nid_t nid, 297 int supports_vref) 298 { 299 unsigned int pinctls; 300 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; 328 } 329 } 330 snd_iprintf(buffer, "\n"); 331 } 332 333 static void print_vol_knob(struct snd_info_buffer *buffer, 334 struct hda_codec *codec, hda_nid_t nid) 335 { 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); 344 } 345 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) 349 { 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); 355 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); 361 } 362 } 363 364 static void print_digital_conv(struct snd_info_buffer *buffer, 365 struct hda_codec *codec, hda_nid_t nid) 366 { 367 unsigned int digi1 = snd_hda_codec_read(codec, nid, 0, 368 AC_VERB_GET_DIGI_CONVERT_1, 0); 369 unsigned int digi2 = snd_hda_codec_read(codec, nid, 0, 370 AC_VERB_GET_DIGI_CONVERT_2, 0); 371 snd_iprintf(buffer, " Digital:"); 372 if (digi1 & AC_DIG1_ENABLE) 373 snd_iprintf(buffer, " Enabled"); 374 if (digi1 & AC_DIG1_V) 375 snd_iprintf(buffer, " Validity"); 376 if (digi1 & AC_DIG1_VCFG) 377 snd_iprintf(buffer, " ValidityCfg"); 378 if (digi1 & AC_DIG1_EMPHASIS) 379 snd_iprintf(buffer, " Preemphasis"); 380 if (digi1 & AC_DIG1_COPYRIGHT) 381 snd_iprintf(buffer, " Copyright"); 382 if (digi1 & AC_DIG1_NONAUDIO) 383 snd_iprintf(buffer, " Non-Audio"); 384 if (digi1 & AC_DIG1_PROFESSIONAL) 385 snd_iprintf(buffer, " Pro"); 386 if (digi1 & AC_DIG1_LEVEL) 387 snd_iprintf(buffer, " GenLevel"); 388 snd_iprintf(buffer, "\n"); 389 snd_iprintf(buffer, " Digital category: 0x%x\n", digi2 & AC_DIG2_CC); 390 } 391 392 static const char *get_pwr_state(u32 state) 393 { 394 static const char *buf[4] = { 395 "D0", "D1", "D2", "D3" 396 }; 397 if (state < 4) 398 return buf[state]; 399 return "UNKNOWN"; 400 } 401 402 static void print_power_state(struct snd_info_buffer *buffer, 403 struct hda_codec *codec, hda_nid_t nid) 404 { 405 int pwr = snd_hda_codec_read(codec, nid, 0, 406 AC_VERB_GET_POWER_STATE, 0); 407 snd_iprintf(buffer, " Power: setting=%s, actual=%s\n", 408 get_pwr_state(pwr & AC_PWRST_SETTING), 409 get_pwr_state((pwr & AC_PWRST_ACTUAL) >> 410 AC_PWRST_ACTUAL_SHIFT)); 411 } 412 413 static void print_unsol_cap(struct snd_info_buffer *buffer, 414 struct hda_codec *codec, hda_nid_t nid) 415 { 416 int unsol = snd_hda_codec_read(codec, nid, 0, 417 AC_VERB_GET_UNSOLICITED_RESPONSE, 0); 418 snd_iprintf(buffer, 419 " Unsolicited: tag=%02x, enabled=%d\n", 420 unsol & AC_UNSOL_TAG, 421 (unsol & AC_UNSOL_ENABLED) ? 1 : 0); 422 } 423 424 static void print_proc_caps(struct snd_info_buffer *buffer, 425 struct hda_codec *codec, hda_nid_t nid) 426 { 427 unsigned int proc_caps = snd_hda_param_read(codec, nid, 428 AC_PAR_PROC_CAP); 429 snd_iprintf(buffer, " Processing caps: benign=%d, ncoeff=%d\n", 430 proc_caps & AC_PCAP_BENIGN, 431 (proc_caps & AC_PCAP_NUM_COEF) >> AC_PCAP_NUM_COEF_SHIFT); 432 } 433 434 static void print_conn_list(struct snd_info_buffer *buffer, 435 struct hda_codec *codec, hda_nid_t nid, 436 unsigned int wid_type, hda_nid_t *conn, 437 int conn_len) 438 { 439 int c, curr = -1; 440 441 if (conn_len > 1 && wid_type != AC_WID_AUD_MIX) 442 curr = snd_hda_codec_read(codec, nid, 0, 443 AC_VERB_GET_CONNECT_SEL, 0); 444 snd_iprintf(buffer, " Connection: %d\n", conn_len); 445 if (conn_len > 0) { 446 snd_iprintf(buffer, " "); 447 for (c = 0; c < conn_len; c++) { 448 snd_iprintf(buffer, " 0x%02x", conn[c]); 449 if (c == curr) 450 snd_iprintf(buffer, "*"); 451 } 452 snd_iprintf(buffer, "\n"); 453 } 454 } 455 456 static void print_realtek_coef(struct snd_info_buffer *buffer, 457 struct hda_codec *codec, hda_nid_t nid) 458 { 459 int coeff = snd_hda_codec_read(codec, nid, 0, 460 AC_VERB_GET_PROC_COEF, 0); 461 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff); 462 coeff = snd_hda_codec_read(codec, nid, 0, 463 AC_VERB_GET_COEF_INDEX, 0); 464 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff); 465 } 466 467 static void print_gpio(struct snd_info_buffer *buffer, 468 struct hda_codec *codec, hda_nid_t nid) 469 { 470 unsigned int gpio = 471 snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP); 472 unsigned int enable, direction, wake, unsol, sticky, data; 473 int i, max; 474 snd_iprintf(buffer, "GPIO: io=%d, o=%d, i=%d, " 475 "unsolicited=%d, wake=%d\n", 476 gpio & AC_GPIO_IO_COUNT, 477 (gpio & AC_GPIO_O_COUNT) >> AC_GPIO_O_COUNT_SHIFT, 478 (gpio & AC_GPIO_I_COUNT) >> AC_GPIO_I_COUNT_SHIFT, 479 (gpio & AC_GPIO_UNSOLICITED) ? 1 : 0, 480 (gpio & AC_GPIO_WAKE) ? 1 : 0); 481 max = gpio & AC_GPIO_IO_COUNT; 482 enable = snd_hda_codec_read(codec, nid, 0, 483 AC_VERB_GET_GPIO_MASK, 0); 484 direction = snd_hda_codec_read(codec, nid, 0, 485 AC_VERB_GET_GPIO_DIRECTION, 0); 486 wake = snd_hda_codec_read(codec, nid, 0, 487 AC_VERB_GET_GPIO_WAKE_MASK, 0); 488 unsol = snd_hda_codec_read(codec, nid, 0, 489 AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK, 0); 490 sticky = snd_hda_codec_read(codec, nid, 0, 491 AC_VERB_GET_GPIO_STICKY_MASK, 0); 492 data = snd_hda_codec_read(codec, nid, 0, 493 AC_VERB_GET_GPIO_DATA, 0); 494 for (i = 0; i < max; ++i) 495 snd_iprintf(buffer, 496 " IO[%d]: enable=%d, dir=%d, wake=%d, " 497 "sticky=%d, data=%d\n", i, 498 (enable & (1<<i)) ? 1 : 0, 499 (direction & (1<<i)) ? 1 : 0, 500 (wake & (1<<i)) ? 1 : 0, 501 (sticky & (1<<i)) ? 1 : 0, 502 (data & (1<<i)) ? 1 : 0); 503 /* FIXME: add GPO and GPI pin information */ 504 } 505 506 static void print_codec_info(struct snd_info_entry *entry, 507 struct snd_info_buffer *buffer) 508 { 509 struct hda_codec *codec = entry->private_data; 510 char buf[32]; 511 hda_nid_t nid; 512 int i, nodes; 513 514 snd_hda_get_codec_name(codec, buf, sizeof(buf)); 515 snd_iprintf(buffer, "Codec: %s\n", buf); 516 snd_iprintf(buffer, "Address: %d\n", codec->addr); 517 snd_iprintf(buffer, "Vendor Id: 0x%x\n", codec->vendor_id); 518 snd_iprintf(buffer, "Subsystem Id: 0x%x\n", codec->subsystem_id); 519 snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id); 520 521 if (codec->mfg) 522 snd_iprintf(buffer, "Modem Function Group: 0x%x\n", codec->mfg); 523 else 524 snd_iprintf(buffer, "No Modem Function Group found\n"); 525 526 if (! codec->afg) 527 return; 528 snd_hda_power_up(codec); 529 snd_iprintf(buffer, "Default PCM:\n"); 530 print_pcm_caps(buffer, codec, codec->afg); 531 snd_iprintf(buffer, "Default Amp-In caps: "); 532 print_amp_caps(buffer, codec, codec->afg, HDA_INPUT); 533 snd_iprintf(buffer, "Default Amp-Out caps: "); 534 print_amp_caps(buffer, codec, codec->afg, HDA_OUTPUT); 535 536 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid); 537 if (! nid || nodes < 0) { 538 snd_iprintf(buffer, "Invalid AFG subtree\n"); 539 snd_hda_power_down(codec); 540 return; 541 } 542 543 print_gpio(buffer, codec, codec->afg); 544 545 for (i = 0; i < nodes; i++, nid++) { 546 unsigned int wid_caps = 547 snd_hda_param_read(codec, nid, 548 AC_PAR_AUDIO_WIDGET_CAP); 549 unsigned int wid_type = 550 (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 551 hda_nid_t conn[HDA_MAX_CONNECTIONS]; 552 int conn_len = 0; 553 554 snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid, 555 get_wid_type_name(wid_type), wid_caps); 556 if (wid_caps & AC_WCAP_STEREO) 557 snd_iprintf(buffer, " Stereo"); 558 else 559 snd_iprintf(buffer, " Mono"); 560 if (wid_caps & AC_WCAP_DIGITAL) 561 snd_iprintf(buffer, " Digital"); 562 if (wid_caps & AC_WCAP_IN_AMP) 563 snd_iprintf(buffer, " Amp-In"); 564 if (wid_caps & AC_WCAP_OUT_AMP) 565 snd_iprintf(buffer, " Amp-Out"); 566 if (wid_caps & AC_WCAP_STRIPE) 567 snd_iprintf(buffer, " Stripe"); 568 if (wid_caps & AC_WCAP_LR_SWAP) 569 snd_iprintf(buffer, " R/L"); 570 snd_iprintf(buffer, "\n"); 571 572 /* volume knob is a special widget that always have connection 573 * list 574 */ 575 if (wid_type == AC_WID_VOL_KNB) 576 wid_caps |= AC_WCAP_CONN_LIST; 577 578 if (wid_caps & AC_WCAP_CONN_LIST) 579 conn_len = snd_hda_get_connections(codec, nid, conn, 580 HDA_MAX_CONNECTIONS); 581 582 if (wid_caps & AC_WCAP_IN_AMP) { 583 snd_iprintf(buffer, " Amp-In caps: "); 584 print_amp_caps(buffer, codec, nid, HDA_INPUT); 585 snd_iprintf(buffer, " Amp-In vals: "); 586 print_amp_vals(buffer, codec, nid, HDA_INPUT, 587 wid_caps & AC_WCAP_STEREO, 588 wid_type == AC_WID_PIN ? 1 : conn_len); 589 } 590 if (wid_caps & AC_WCAP_OUT_AMP) { 591 snd_iprintf(buffer, " Amp-Out caps: "); 592 print_amp_caps(buffer, codec, nid, HDA_OUTPUT); 593 snd_iprintf(buffer, " Amp-Out vals: "); 594 print_amp_vals(buffer, codec, nid, HDA_OUTPUT, 595 wid_caps & AC_WCAP_STEREO, 1); 596 } 597 598 switch (wid_type) { 599 case AC_WID_PIN: { 600 int supports_vref; 601 print_pin_caps(buffer, codec, nid, &supports_vref); 602 print_pin_ctls(buffer, codec, nid, supports_vref); 603 break; 604 } 605 case AC_WID_VOL_KNB: 606 print_vol_knob(buffer, codec, nid); 607 break; 608 case AC_WID_AUD_OUT: 609 case AC_WID_AUD_IN: 610 print_audio_io(buffer, codec, nid, wid_type); 611 if (wid_caps & AC_WCAP_DIGITAL) 612 print_digital_conv(buffer, codec, nid); 613 if (wid_caps & AC_WCAP_FORMAT_OVRD) { 614 snd_iprintf(buffer, " PCM:\n"); 615 print_pcm_caps(buffer, codec, nid); 616 } 617 break; 618 } 619 620 if (wid_caps & AC_WCAP_UNSOL_CAP) 621 print_unsol_cap(buffer, codec, nid); 622 623 if (wid_caps & AC_WCAP_POWER) 624 print_power_state(buffer, codec, nid); 625 626 if (wid_caps & AC_WCAP_DELAY) 627 snd_iprintf(buffer, " Delay: %d samples\n", 628 (wid_caps & AC_WCAP_DELAY) >> 629 AC_WCAP_DELAY_SHIFT); 630 631 if (wid_caps & AC_WCAP_CONN_LIST) 632 print_conn_list(buffer, codec, nid, wid_type, 633 conn, conn_len); 634 635 if (wid_caps & AC_WCAP_PROC_WID) 636 print_proc_caps(buffer, codec, nid); 637 638 /* NID 0x20 == Realtek Define Registers */ 639 if (codec->vendor_id == 0x10ec && nid == 0x20) 640 print_realtek_coef(buffer, codec, nid); 641 } 642 snd_hda_power_down(codec); 643 } 644 645 /* 646 * create a proc read 647 */ 648 int snd_hda_codec_proc_new(struct hda_codec *codec) 649 { 650 char name[32]; 651 struct snd_info_entry *entry; 652 int err; 653 654 snprintf(name, sizeof(name), "codec#%d", codec->addr); 655 err = snd_card_proc_new(codec->bus->card, name, &entry); 656 if (err < 0) 657 return err; 658 659 snd_info_set_text_ops(entry, codec, print_codec_info); 660 return 0; 661 } 662 663