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