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