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 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_HDMI) { 233 /* Realtek uses this bit as a different meaning */ 234 if ((codec->vendor_id >> 16) == 0x10ec) 235 snd_iprintf(buffer, " R/L"); 236 else 237 snd_iprintf(buffer, " HDMI"); 238 } 239 if (caps & AC_PINCAP_TRIG_REQ) 240 snd_iprintf(buffer, " Trigger"); 241 if (caps & AC_PINCAP_IMP_SENSE) 242 snd_iprintf(buffer, " ImpSense"); 243 snd_iprintf(buffer, "\n"); 244 if (caps & AC_PINCAP_VREF) { 245 unsigned int vref = 246 (caps & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; 247 snd_iprintf(buffer, " Vref caps:"); 248 if (vref & AC_PINCAP_VREF_HIZ) 249 snd_iprintf(buffer, " HIZ"); 250 if (vref & AC_PINCAP_VREF_50) 251 snd_iprintf(buffer, " 50"); 252 if (vref & AC_PINCAP_VREF_GRD) 253 snd_iprintf(buffer, " GRD"); 254 if (vref & AC_PINCAP_VREF_80) 255 snd_iprintf(buffer, " 80"); 256 if (vref & AC_PINCAP_VREF_100) 257 snd_iprintf(buffer, " 100"); 258 snd_iprintf(buffer, "\n"); 259 *supports_vref = 1; 260 } else 261 *supports_vref = 0; 262 if (caps & AC_PINCAP_EAPD) { 263 val = snd_hda_codec_read(codec, nid, 0, 264 AC_VERB_GET_EAPD_BTLENABLE, 0); 265 snd_iprintf(buffer, " EAPD 0x%x:", val); 266 if (val & AC_EAPDBTL_BALANCED) 267 snd_iprintf(buffer, " BALANCED"); 268 if (val & AC_EAPDBTL_EAPD) 269 snd_iprintf(buffer, " EAPD"); 270 if (val & AC_EAPDBTL_LR_SWAP) 271 snd_iprintf(buffer, " R/L"); 272 snd_iprintf(buffer, "\n"); 273 } 274 caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); 275 snd_iprintf(buffer, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps, 276 jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT], 277 jack_types[(caps & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT], 278 jack_locations[(caps >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3], 279 get_jack_location(caps)); 280 snd_iprintf(buffer, " Conn = %s, Color = %s\n", 281 get_jack_connection(caps), 282 get_jack_color(caps)); 283 /* Default association and sequence values refer to default grouping 284 * of pin complexes and their sequence within the group. This is used 285 * for priority and resource allocation. 286 */ 287 snd_iprintf(buffer, " DefAssociation = 0x%x, Sequence = 0x%x\n", 288 (caps & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT, 289 caps & AC_DEFCFG_SEQUENCE); 290 if (((caps & AC_DEFCFG_MISC) >> AC_DEFCFG_MISC_SHIFT) & 291 AC_DEFCFG_MISC_NO_PRESENCE) { 292 /* Miscellaneous bit indicates external hardware does not 293 * support presence detection even if the pin complex 294 * indicates it is supported. 295 */ 296 snd_iprintf(buffer, " Misc = NO_PRESENCE\n"); 297 } 298 } 299 300 static void print_pin_ctls(struct snd_info_buffer *buffer, 301 struct hda_codec *codec, hda_nid_t nid, 302 int supports_vref) 303 { 304 unsigned int pinctls; 305 306 pinctls = snd_hda_codec_read(codec, nid, 0, 307 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 308 snd_iprintf(buffer, " Pin-ctls: 0x%02x:", pinctls); 309 if (pinctls & AC_PINCTL_IN_EN) 310 snd_iprintf(buffer, " IN"); 311 if (pinctls & AC_PINCTL_OUT_EN) 312 snd_iprintf(buffer, " OUT"); 313 if (pinctls & AC_PINCTL_HP_EN) 314 snd_iprintf(buffer, " HP"); 315 if (supports_vref) { 316 int vref = pinctls & AC_PINCTL_VREFEN; 317 switch (vref) { 318 case AC_PINCTL_VREF_HIZ: 319 snd_iprintf(buffer, " VREF_HIZ"); 320 break; 321 case AC_PINCTL_VREF_50: 322 snd_iprintf(buffer, " VREF_50"); 323 break; 324 case AC_PINCTL_VREF_GRD: 325 snd_iprintf(buffer, " VREF_GRD"); 326 break; 327 case AC_PINCTL_VREF_80: 328 snd_iprintf(buffer, " VREF_80"); 329 break; 330 case AC_PINCTL_VREF_100: 331 snd_iprintf(buffer, " VREF_100"); 332 break; 333 } 334 } 335 snd_iprintf(buffer, "\n"); 336 } 337 338 static void print_vol_knob(struct snd_info_buffer *buffer, 339 struct hda_codec *codec, hda_nid_t nid) 340 { 341 unsigned int cap = snd_hda_param_read(codec, nid, 342 AC_PAR_VOL_KNB_CAP); 343 snd_iprintf(buffer, " Volume-Knob: delta=%d, steps=%d, ", 344 (cap >> 7) & 1, cap & 0x7f); 345 cap = snd_hda_codec_read(codec, nid, 0, 346 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); 347 snd_iprintf(buffer, "direct=%d, val=%d\n", 348 (cap >> 7) & 1, cap & 0x7f); 349 } 350 351 static void print_audio_io(struct snd_info_buffer *buffer, 352 struct hda_codec *codec, hda_nid_t nid, 353 unsigned int wid_type) 354 { 355 int conv = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); 356 snd_iprintf(buffer, 357 " Converter: stream=%d, channel=%d\n", 358 (conv & AC_CONV_STREAM) >> AC_CONV_STREAM_SHIFT, 359 conv & AC_CONV_CHANNEL); 360 361 if (wid_type == AC_WID_AUD_IN && (conv & AC_CONV_CHANNEL) == 0) { 362 int sdi = snd_hda_codec_read(codec, nid, 0, 363 AC_VERB_GET_SDI_SELECT, 0); 364 snd_iprintf(buffer, " SDI-Select: %d\n", 365 sdi & AC_SDI_SELECT); 366 } 367 } 368 369 static void print_digital_conv(struct snd_info_buffer *buffer, 370 struct hda_codec *codec, hda_nid_t nid) 371 { 372 unsigned int digi1 = snd_hda_codec_read(codec, nid, 0, 373 AC_VERB_GET_DIGI_CONVERT_1, 0); 374 snd_iprintf(buffer, " Digital:"); 375 if (digi1 & AC_DIG1_ENABLE) 376 snd_iprintf(buffer, " Enabled"); 377 if (digi1 & AC_DIG1_V) 378 snd_iprintf(buffer, " Validity"); 379 if (digi1 & AC_DIG1_VCFG) 380 snd_iprintf(buffer, " ValidityCfg"); 381 if (digi1 & AC_DIG1_EMPHASIS) 382 snd_iprintf(buffer, " Preemphasis"); 383 if (digi1 & AC_DIG1_COPYRIGHT) 384 snd_iprintf(buffer, " Copyright"); 385 if (digi1 & AC_DIG1_NONAUDIO) 386 snd_iprintf(buffer, " Non-Audio"); 387 if (digi1 & AC_DIG1_PROFESSIONAL) 388 snd_iprintf(buffer, " Pro"); 389 if (digi1 & AC_DIG1_LEVEL) 390 snd_iprintf(buffer, " GenLevel"); 391 snd_iprintf(buffer, "\n"); 392 snd_iprintf(buffer, " Digital category: 0x%x\n", 393 (digi1 >> 8) & AC_DIG2_CC); 394 } 395 396 static const char *get_pwr_state(u32 state) 397 { 398 static const char *buf[4] = { 399 "D0", "D1", "D2", "D3" 400 }; 401 if (state < 4) 402 return buf[state]; 403 return "UNKNOWN"; 404 } 405 406 static void print_power_state(struct snd_info_buffer *buffer, 407 struct hda_codec *codec, hda_nid_t nid) 408 { 409 int pwr = snd_hda_codec_read(codec, nid, 0, 410 AC_VERB_GET_POWER_STATE, 0); 411 snd_iprintf(buffer, " Power: setting=%s, actual=%s\n", 412 get_pwr_state(pwr & AC_PWRST_SETTING), 413 get_pwr_state((pwr & AC_PWRST_ACTUAL) >> 414 AC_PWRST_ACTUAL_SHIFT)); 415 } 416 417 static void print_unsol_cap(struct snd_info_buffer *buffer, 418 struct hda_codec *codec, hda_nid_t nid) 419 { 420 int unsol = snd_hda_codec_read(codec, nid, 0, 421 AC_VERB_GET_UNSOLICITED_RESPONSE, 0); 422 snd_iprintf(buffer, 423 " Unsolicited: tag=%02x, enabled=%d\n", 424 unsol & AC_UNSOL_TAG, 425 (unsol & AC_UNSOL_ENABLED) ? 1 : 0); 426 } 427 428 static void print_proc_caps(struct snd_info_buffer *buffer, 429 struct hda_codec *codec, hda_nid_t nid) 430 { 431 unsigned int proc_caps = snd_hda_param_read(codec, nid, 432 AC_PAR_PROC_CAP); 433 snd_iprintf(buffer, " Processing caps: benign=%d, ncoeff=%d\n", 434 proc_caps & AC_PCAP_BENIGN, 435 (proc_caps & AC_PCAP_NUM_COEF) >> AC_PCAP_NUM_COEF_SHIFT); 436 } 437 438 static void print_conn_list(struct snd_info_buffer *buffer, 439 struct hda_codec *codec, hda_nid_t nid, 440 unsigned int wid_type, hda_nid_t *conn, 441 int conn_len) 442 { 443 int c, curr = -1; 444 445 if (conn_len > 1 && wid_type != AC_WID_AUD_MIX) 446 curr = snd_hda_codec_read(codec, nid, 0, 447 AC_VERB_GET_CONNECT_SEL, 0); 448 snd_iprintf(buffer, " Connection: %d\n", conn_len); 449 if (conn_len > 0) { 450 snd_iprintf(buffer, " "); 451 for (c = 0; c < conn_len; c++) { 452 snd_iprintf(buffer, " 0x%02x", conn[c]); 453 if (c == curr) 454 snd_iprintf(buffer, "*"); 455 } 456 snd_iprintf(buffer, "\n"); 457 } 458 } 459 460 static void print_realtek_coef(struct snd_info_buffer *buffer, 461 struct hda_codec *codec, hda_nid_t nid) 462 { 463 int coeff = snd_hda_codec_read(codec, nid, 0, 464 AC_VERB_GET_PROC_COEF, 0); 465 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff); 466 coeff = snd_hda_codec_read(codec, nid, 0, 467 AC_VERB_GET_COEF_INDEX, 0); 468 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff); 469 } 470 471 static void print_gpio(struct snd_info_buffer *buffer, 472 struct hda_codec *codec, hda_nid_t nid) 473 { 474 unsigned int gpio = 475 snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP); 476 unsigned int enable, direction, wake, unsol, sticky, data; 477 int i, max; 478 snd_iprintf(buffer, "GPIO: io=%d, o=%d, i=%d, " 479 "unsolicited=%d, wake=%d\n", 480 gpio & AC_GPIO_IO_COUNT, 481 (gpio & AC_GPIO_O_COUNT) >> AC_GPIO_O_COUNT_SHIFT, 482 (gpio & AC_GPIO_I_COUNT) >> AC_GPIO_I_COUNT_SHIFT, 483 (gpio & AC_GPIO_UNSOLICITED) ? 1 : 0, 484 (gpio & AC_GPIO_WAKE) ? 1 : 0); 485 max = gpio & AC_GPIO_IO_COUNT; 486 enable = snd_hda_codec_read(codec, nid, 0, 487 AC_VERB_GET_GPIO_MASK, 0); 488 direction = snd_hda_codec_read(codec, nid, 0, 489 AC_VERB_GET_GPIO_DIRECTION, 0); 490 wake = snd_hda_codec_read(codec, nid, 0, 491 AC_VERB_GET_GPIO_WAKE_MASK, 0); 492 unsol = snd_hda_codec_read(codec, nid, 0, 493 AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK, 0); 494 sticky = snd_hda_codec_read(codec, nid, 0, 495 AC_VERB_GET_GPIO_STICKY_MASK, 0); 496 data = snd_hda_codec_read(codec, nid, 0, 497 AC_VERB_GET_GPIO_DATA, 0); 498 for (i = 0; i < max; ++i) 499 snd_iprintf(buffer, 500 " IO[%d]: enable=%d, dir=%d, wake=%d, " 501 "sticky=%d, data=%d\n", i, 502 (enable & (1<<i)) ? 1 : 0, 503 (direction & (1<<i)) ? 1 : 0, 504 (wake & (1<<i)) ? 1 : 0, 505 (sticky & (1<<i)) ? 1 : 0, 506 (data & (1<<i)) ? 1 : 0); 507 /* FIXME: add GPO and GPI pin information */ 508 } 509 510 static void print_codec_info(struct snd_info_entry *entry, 511 struct snd_info_buffer *buffer) 512 { 513 struct hda_codec *codec = entry->private_data; 514 char buf[32]; 515 hda_nid_t nid; 516 int i, nodes; 517 518 snd_hda_get_codec_name(codec, buf, sizeof(buf)); 519 snd_iprintf(buffer, "Codec: %s\n", buf); 520 snd_iprintf(buffer, "Address: %d\n", codec->addr); 521 snd_iprintf(buffer, "Vendor Id: 0x%x\n", codec->vendor_id); 522 snd_iprintf(buffer, "Subsystem Id: 0x%x\n", codec->subsystem_id); 523 snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id); 524 525 if (codec->mfg) 526 snd_iprintf(buffer, "Modem Function Group: 0x%x\n", codec->mfg); 527 else 528 snd_iprintf(buffer, "No Modem Function Group found\n"); 529 530 if (! codec->afg) 531 return; 532 snd_hda_power_up(codec); 533 snd_iprintf(buffer, "Default PCM:\n"); 534 print_pcm_caps(buffer, codec, codec->afg); 535 snd_iprintf(buffer, "Default Amp-In caps: "); 536 print_amp_caps(buffer, codec, codec->afg, HDA_INPUT); 537 snd_iprintf(buffer, "Default Amp-Out caps: "); 538 print_amp_caps(buffer, codec, codec->afg, HDA_OUTPUT); 539 540 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid); 541 if (! nid || nodes < 0) { 542 snd_iprintf(buffer, "Invalid AFG subtree\n"); 543 snd_hda_power_down(codec); 544 return; 545 } 546 547 print_gpio(buffer, codec, codec->afg); 548 549 for (i = 0; i < nodes; i++, nid++) { 550 unsigned int wid_caps = 551 snd_hda_param_read(codec, nid, 552 AC_PAR_AUDIO_WIDGET_CAP); 553 unsigned int wid_type = 554 (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 555 hda_nid_t conn[HDA_MAX_CONNECTIONS]; 556 int conn_len = 0; 557 558 snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid, 559 get_wid_type_name(wid_type), wid_caps); 560 if (wid_caps & AC_WCAP_STEREO) { 561 unsigned int chans; 562 chans = (wid_caps & AC_WCAP_CHAN_CNT_EXT) >> 13; 563 chans = ((chans << 1) | 1) + 1; 564 if (chans == 2) 565 snd_iprintf(buffer, " Stereo"); 566 else 567 snd_iprintf(buffer, " %d-Channels", chans); 568 } else 569 snd_iprintf(buffer, " Mono"); 570 if (wid_caps & AC_WCAP_DIGITAL) 571 snd_iprintf(buffer, " Digital"); 572 if (wid_caps & AC_WCAP_IN_AMP) 573 snd_iprintf(buffer, " Amp-In"); 574 if (wid_caps & AC_WCAP_OUT_AMP) 575 snd_iprintf(buffer, " Amp-Out"); 576 if (wid_caps & AC_WCAP_STRIPE) 577 snd_iprintf(buffer, " Stripe"); 578 if (wid_caps & AC_WCAP_LR_SWAP) 579 snd_iprintf(buffer, " R/L"); 580 if (wid_caps & AC_WCAP_CP_CAPS) 581 snd_iprintf(buffer, " CP"); 582 snd_iprintf(buffer, "\n"); 583 584 /* volume knob is a special widget that always have connection 585 * list 586 */ 587 if (wid_type == AC_WID_VOL_KNB) 588 wid_caps |= AC_WCAP_CONN_LIST; 589 590 if (wid_caps & AC_WCAP_CONN_LIST) 591 conn_len = snd_hda_get_connections(codec, nid, conn, 592 HDA_MAX_CONNECTIONS); 593 594 if (wid_caps & AC_WCAP_IN_AMP) { 595 snd_iprintf(buffer, " Amp-In caps: "); 596 print_amp_caps(buffer, codec, nid, HDA_INPUT); 597 snd_iprintf(buffer, " Amp-In vals: "); 598 print_amp_vals(buffer, codec, nid, HDA_INPUT, 599 wid_caps & AC_WCAP_STEREO, 600 wid_type == AC_WID_PIN ? 1 : conn_len); 601 } 602 if (wid_caps & AC_WCAP_OUT_AMP) { 603 snd_iprintf(buffer, " Amp-Out caps: "); 604 print_amp_caps(buffer, codec, nid, HDA_OUTPUT); 605 snd_iprintf(buffer, " Amp-Out vals: "); 606 print_amp_vals(buffer, codec, nid, HDA_OUTPUT, 607 wid_caps & AC_WCAP_STEREO, 1); 608 } 609 610 switch (wid_type) { 611 case AC_WID_PIN: { 612 int supports_vref; 613 print_pin_caps(buffer, codec, nid, &supports_vref); 614 print_pin_ctls(buffer, codec, nid, supports_vref); 615 break; 616 } 617 case AC_WID_VOL_KNB: 618 print_vol_knob(buffer, codec, nid); 619 break; 620 case AC_WID_AUD_OUT: 621 case AC_WID_AUD_IN: 622 print_audio_io(buffer, codec, nid, wid_type); 623 if (wid_caps & AC_WCAP_DIGITAL) 624 print_digital_conv(buffer, codec, nid); 625 if (wid_caps & AC_WCAP_FORMAT_OVRD) { 626 snd_iprintf(buffer, " PCM:\n"); 627 print_pcm_caps(buffer, codec, nid); 628 } 629 break; 630 } 631 632 if (wid_caps & AC_WCAP_UNSOL_CAP) 633 print_unsol_cap(buffer, codec, nid); 634 635 if (wid_caps & AC_WCAP_POWER) 636 print_power_state(buffer, codec, nid); 637 638 if (wid_caps & AC_WCAP_DELAY) 639 snd_iprintf(buffer, " Delay: %d samples\n", 640 (wid_caps & AC_WCAP_DELAY) >> 641 AC_WCAP_DELAY_SHIFT); 642 643 if (wid_caps & AC_WCAP_CONN_LIST) 644 print_conn_list(buffer, codec, nid, wid_type, 645 conn, conn_len); 646 647 if (wid_caps & AC_WCAP_PROC_WID) 648 print_proc_caps(buffer, codec, nid); 649 650 /* NID 0x20 == Realtek Define Registers */ 651 if (codec->vendor_id == 0x10ec && nid == 0x20) 652 print_realtek_coef(buffer, codec, nid); 653 } 654 snd_hda_power_down(codec); 655 } 656 657 /* 658 * create a proc read 659 */ 660 int snd_hda_codec_proc_new(struct hda_codec *codec) 661 { 662 char name[32]; 663 struct snd_info_entry *entry; 664 int err; 665 666 snprintf(name, sizeof(name), "codec#%d", codec->addr); 667 err = snd_card_proc_new(codec->bus->card, name, &entry); 668 if (err < 0) 669 return err; 670 671 snd_info_set_text_ops(entry, codec, print_codec_info); 672 return 0; 673 } 674 675