md/raid: only permit hot-add of compatible integrity profiles
[linux/fpc-iii.git] / sound / pci / hda / hda_proc.c
blob033aa84365b9b26de27dbb2918498c1d114b892b
1 /*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * Generic proc interface
6 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This driver is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include <linux/init.h>
25 #include <linux/slab.h>
26 #include <sound/core.h>
27 #include <linux/module.h>
28 #include "hda_codec.h"
29 #include "hda_local.h"
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)");
35 /* always use noncached version */
36 #define param_read(codec, nid, parm) \
37 snd_hdac_read_parm_uncached(&(codec)->core, nid, parm)
39 static const char *get_wid_type_name(unsigned int wid_value)
41 static const char * const names[16] = {
42 [AC_WID_AUD_OUT] = "Audio Output",
43 [AC_WID_AUD_IN] = "Audio Input",
44 [AC_WID_AUD_MIX] = "Audio Mixer",
45 [AC_WID_AUD_SEL] = "Audio Selector",
46 [AC_WID_PIN] = "Pin Complex",
47 [AC_WID_POWER] = "Power Widget",
48 [AC_WID_VOL_KNB] = "Volume Knob Widget",
49 [AC_WID_BEEP] = "Beep Generator Widget",
50 [AC_WID_VENDOR] = "Vendor Defined Widget",
52 if (wid_value == -1)
53 return "UNKNOWN Widget";
54 wid_value &= 0xf;
55 if (names[wid_value])
56 return names[wid_value];
57 else
58 return "UNKNOWN Widget";
61 static void print_nid_array(struct snd_info_buffer *buffer,
62 struct hda_codec *codec, hda_nid_t nid,
63 struct snd_array *array)
65 int i;
66 struct hda_nid_item *items = array->list, *item;
67 struct snd_kcontrol *kctl;
68 for (i = 0; i < array->used; i++) {
69 item = &items[i];
70 if (item->nid == nid) {
71 kctl = item->kctl;
72 snd_iprintf(buffer,
73 " Control: name=\"%s\", index=%i, device=%i\n",
74 kctl->id.name, kctl->id.index + item->index,
75 kctl->id.device);
76 if (item->flags & HDA_NID_ITEM_AMP)
77 snd_iprintf(buffer,
78 " ControlAmp: chs=%lu, dir=%s, "
79 "idx=%lu, ofs=%lu\n",
80 get_amp_channels(kctl),
81 get_amp_direction(kctl) ? "Out" : "In",
82 get_amp_index(kctl),
83 get_amp_offset(kctl));
88 static void print_nid_pcms(struct snd_info_buffer *buffer,
89 struct hda_codec *codec, hda_nid_t nid)
91 int type;
92 struct hda_pcm *cpcm;
94 list_for_each_entry(cpcm, &codec->pcm_list_head, list) {
95 for (type = 0; type < 2; type++) {
96 if (cpcm->stream[type].nid != nid || cpcm->pcm == NULL)
97 continue;
98 snd_iprintf(buffer, " Device: name=\"%s\", "
99 "type=\"%s\", device=%i\n",
100 cpcm->name,
101 snd_hda_pcm_type_name[cpcm->pcm_type],
102 cpcm->pcm->device);
107 static void print_amp_caps(struct snd_info_buffer *buffer,
108 struct hda_codec *codec, hda_nid_t nid, int dir)
110 unsigned int caps;
111 caps = param_read(codec, nid, dir == HDA_OUTPUT ?
112 AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP);
113 if (caps == -1 || caps == 0) {
114 snd_iprintf(buffer, "N/A\n");
115 return;
117 snd_iprintf(buffer, "ofs=0x%02x, nsteps=0x%02x, stepsize=0x%02x, "
118 "mute=%x\n",
119 caps & AC_AMPCAP_OFFSET,
120 (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT,
121 (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT,
122 (caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT);
125 /* is this a stereo widget or a stereo-to-mono mix? */
126 static bool is_stereo_amps(struct hda_codec *codec, hda_nid_t nid,
127 int dir, unsigned int wcaps, int indices)
129 hda_nid_t conn;
131 if (wcaps & AC_WCAP_STEREO)
132 return true;
133 /* check for a stereo-to-mono mix; it must be:
134 * only a single connection, only for input, and only a mixer widget
136 if (indices != 1 || dir != HDA_INPUT ||
137 get_wcaps_type(wcaps) != AC_WID_AUD_MIX)
138 return false;
140 if (snd_hda_get_raw_connections(codec, nid, &conn, 1) < 0)
141 return false;
142 /* the connection source is a stereo? */
143 wcaps = snd_hda_param_read(codec, conn, AC_PAR_AUDIO_WIDGET_CAP);
144 return !!(wcaps & AC_WCAP_STEREO);
147 static void print_amp_vals(struct snd_info_buffer *buffer,
148 struct hda_codec *codec, hda_nid_t nid,
149 int dir, unsigned int wcaps, int indices)
151 unsigned int val;
152 bool stereo;
153 int i;
155 stereo = is_stereo_amps(codec, nid, dir, wcaps, indices);
157 dir = dir == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT;
158 for (i = 0; i < indices; i++) {
159 snd_iprintf(buffer, " [");
160 val = snd_hda_codec_read(codec, nid, 0,
161 AC_VERB_GET_AMP_GAIN_MUTE,
162 AC_AMP_GET_LEFT | dir | i);
163 snd_iprintf(buffer, "0x%02x", val);
164 if (stereo) {
165 val = snd_hda_codec_read(codec, nid, 0,
166 AC_VERB_GET_AMP_GAIN_MUTE,
167 AC_AMP_GET_RIGHT | dir | i);
168 snd_iprintf(buffer, " 0x%02x", val);
170 snd_iprintf(buffer, "]");
172 snd_iprintf(buffer, "\n");
175 static void print_pcm_rates(struct snd_info_buffer *buffer, unsigned int pcm)
177 static unsigned int rates[] = {
178 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
179 96000, 176400, 192000, 384000
181 int i;
183 pcm &= AC_SUPPCM_RATES;
184 snd_iprintf(buffer, " rates [0x%x]:", pcm);
185 for (i = 0; i < ARRAY_SIZE(rates); i++)
186 if (pcm & (1 << i))
187 snd_iprintf(buffer, " %d", rates[i]);
188 snd_iprintf(buffer, "\n");
191 static void print_pcm_bits(struct snd_info_buffer *buffer, unsigned int pcm)
193 char buf[SND_PRINT_BITS_ADVISED_BUFSIZE];
195 snd_iprintf(buffer, " bits [0x%x]:", (pcm >> 16) & 0xff);
196 snd_print_pcm_bits(pcm, buf, sizeof(buf));
197 snd_iprintf(buffer, "%s\n", buf);
200 static void print_pcm_formats(struct snd_info_buffer *buffer,
201 unsigned int streams)
203 snd_iprintf(buffer, " formats [0x%x]:", streams & 0xf);
204 if (streams & AC_SUPFMT_PCM)
205 snd_iprintf(buffer, " PCM");
206 if (streams & AC_SUPFMT_FLOAT32)
207 snd_iprintf(buffer, " FLOAT");
208 if (streams & AC_SUPFMT_AC3)
209 snd_iprintf(buffer, " AC3");
210 snd_iprintf(buffer, "\n");
213 static void print_pcm_caps(struct snd_info_buffer *buffer,
214 struct hda_codec *codec, hda_nid_t nid)
216 unsigned int pcm = param_read(codec, nid, AC_PAR_PCM);
217 unsigned int stream = param_read(codec, nid, AC_PAR_STREAM);
218 if (pcm == -1 || stream == -1) {
219 snd_iprintf(buffer, "N/A\n");
220 return;
222 print_pcm_rates(buffer, pcm);
223 print_pcm_bits(buffer, pcm);
224 print_pcm_formats(buffer, stream);
227 static const char *get_jack_connection(u32 cfg)
229 static const char * const names[16] = {
230 "Unknown", "1/8", "1/4", "ATAPI",
231 "RCA", "Optical","Digital", "Analog",
232 "DIN", "XLR", "RJ11", "Comb",
233 NULL, NULL, NULL, "Other"
235 cfg = (cfg & AC_DEFCFG_CONN_TYPE) >> AC_DEFCFG_CONN_TYPE_SHIFT;
236 if (names[cfg])
237 return names[cfg];
238 else
239 return "UNKNOWN";
242 static const char *get_jack_color(u32 cfg)
244 static const char * const names[16] = {
245 "Unknown", "Black", "Grey", "Blue",
246 "Green", "Red", "Orange", "Yellow",
247 "Purple", "Pink", NULL, NULL,
248 NULL, NULL, "White", "Other",
250 cfg = (cfg & AC_DEFCFG_COLOR) >> AC_DEFCFG_COLOR_SHIFT;
251 if (names[cfg])
252 return names[cfg];
253 else
254 return "UNKNOWN";
258 * Parse the pin default config value and returns the string of the
259 * jack location, e.g. "Rear", "Front", etc.
261 static const char *get_jack_location(u32 cfg)
263 static const char * const bases[7] = {
264 "N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom",
266 static const unsigned char specials_idx[] = {
267 0x07, 0x08,
268 0x17, 0x18, 0x19,
269 0x37, 0x38
271 static const char * const specials[] = {
272 "Rear Panel", "Drive Bar",
273 "Riser", "HDMI", "ATAPI",
274 "Mobile-In", "Mobile-Out"
276 int i;
278 cfg = (cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT;
279 if ((cfg & 0x0f) < 7)
280 return bases[cfg & 0x0f];
281 for (i = 0; i < ARRAY_SIZE(specials_idx); i++) {
282 if (cfg == specials_idx[i])
283 return specials[i];
285 return "UNKNOWN";
289 * Parse the pin default config value and returns the string of the
290 * jack connectivity, i.e. external or internal connection.
292 static const char *get_jack_connectivity(u32 cfg)
294 static const char * const jack_locations[4] = {
295 "Ext", "Int", "Sep", "Oth"
298 return jack_locations[(cfg >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3];
302 * Parse the pin default config value and returns the string of the
303 * jack type, i.e. the purpose of the jack, such as Line-Out or CD.
305 static const char *get_jack_type(u32 cfg)
307 static const char * const jack_types[16] = {
308 "Line Out", "Speaker", "HP Out", "CD",
309 "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
310 "Line In", "Aux", "Mic", "Telephony",
311 "SPDIF In", "Digital In", "Reserved", "Other"
314 return jack_types[(cfg & AC_DEFCFG_DEVICE)
315 >> AC_DEFCFG_DEVICE_SHIFT];
318 static void print_pin_caps(struct snd_info_buffer *buffer,
319 struct hda_codec *codec, hda_nid_t nid,
320 int *supports_vref)
322 static const char * const jack_conns[4] = {
323 "Jack", "N/A", "Fixed", "Both"
325 unsigned int caps, val;
327 caps = param_read(codec, nid, AC_PAR_PIN_CAP);
328 snd_iprintf(buffer, " Pincap 0x%08x:", caps);
329 if (caps & AC_PINCAP_IN)
330 snd_iprintf(buffer, " IN");
331 if (caps & AC_PINCAP_OUT)
332 snd_iprintf(buffer, " OUT");
333 if (caps & AC_PINCAP_HP_DRV)
334 snd_iprintf(buffer, " HP");
335 if (caps & AC_PINCAP_EAPD)
336 snd_iprintf(buffer, " EAPD");
337 if (caps & AC_PINCAP_PRES_DETECT)
338 snd_iprintf(buffer, " Detect");
339 if (caps & AC_PINCAP_BALANCE)
340 snd_iprintf(buffer, " Balanced");
341 if (caps & AC_PINCAP_HDMI) {
342 /* Realtek uses this bit as a different meaning */
343 if ((codec->core.vendor_id >> 16) == 0x10ec)
344 snd_iprintf(buffer, " R/L");
345 else {
346 if (caps & AC_PINCAP_HBR)
347 snd_iprintf(buffer, " HBR");
348 snd_iprintf(buffer, " HDMI");
351 if (caps & AC_PINCAP_DP)
352 snd_iprintf(buffer, " DP");
353 if (caps & AC_PINCAP_TRIG_REQ)
354 snd_iprintf(buffer, " Trigger");
355 if (caps & AC_PINCAP_IMP_SENSE)
356 snd_iprintf(buffer, " ImpSense");
357 snd_iprintf(buffer, "\n");
358 if (caps & AC_PINCAP_VREF) {
359 unsigned int vref =
360 (caps & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
361 snd_iprintf(buffer, " Vref caps:");
362 if (vref & AC_PINCAP_VREF_HIZ)
363 snd_iprintf(buffer, " HIZ");
364 if (vref & AC_PINCAP_VREF_50)
365 snd_iprintf(buffer, " 50");
366 if (vref & AC_PINCAP_VREF_GRD)
367 snd_iprintf(buffer, " GRD");
368 if (vref & AC_PINCAP_VREF_80)
369 snd_iprintf(buffer, " 80");
370 if (vref & AC_PINCAP_VREF_100)
371 snd_iprintf(buffer, " 100");
372 snd_iprintf(buffer, "\n");
373 *supports_vref = 1;
374 } else
375 *supports_vref = 0;
376 if (caps & AC_PINCAP_EAPD) {
377 val = snd_hda_codec_read(codec, nid, 0,
378 AC_VERB_GET_EAPD_BTLENABLE, 0);
379 snd_iprintf(buffer, " EAPD 0x%x:", val);
380 if (val & AC_EAPDBTL_BALANCED)
381 snd_iprintf(buffer, " BALANCED");
382 if (val & AC_EAPDBTL_EAPD)
383 snd_iprintf(buffer, " EAPD");
384 if (val & AC_EAPDBTL_LR_SWAP)
385 snd_iprintf(buffer, " R/L");
386 snd_iprintf(buffer, "\n");
388 caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
389 snd_iprintf(buffer, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps,
390 jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT],
391 get_jack_type(caps),
392 get_jack_connectivity(caps),
393 get_jack_location(caps));
394 snd_iprintf(buffer, " Conn = %s, Color = %s\n",
395 get_jack_connection(caps),
396 get_jack_color(caps));
397 /* Default association and sequence values refer to default grouping
398 * of pin complexes and their sequence within the group. This is used
399 * for priority and resource allocation.
401 snd_iprintf(buffer, " DefAssociation = 0x%x, Sequence = 0x%x\n",
402 (caps & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT,
403 caps & AC_DEFCFG_SEQUENCE);
404 if (((caps & AC_DEFCFG_MISC) >> AC_DEFCFG_MISC_SHIFT) &
405 AC_DEFCFG_MISC_NO_PRESENCE) {
406 /* Miscellaneous bit indicates external hardware does not
407 * support presence detection even if the pin complex
408 * indicates it is supported.
410 snd_iprintf(buffer, " Misc = NO_PRESENCE\n");
414 static void print_pin_ctls(struct snd_info_buffer *buffer,
415 struct hda_codec *codec, hda_nid_t nid,
416 int supports_vref)
418 unsigned int pinctls;
420 pinctls = snd_hda_codec_read(codec, nid, 0,
421 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
422 snd_iprintf(buffer, " Pin-ctls: 0x%02x:", pinctls);
423 if (pinctls & AC_PINCTL_IN_EN)
424 snd_iprintf(buffer, " IN");
425 if (pinctls & AC_PINCTL_OUT_EN)
426 snd_iprintf(buffer, " OUT");
427 if (pinctls & AC_PINCTL_HP_EN)
428 snd_iprintf(buffer, " HP");
429 if (supports_vref) {
430 int vref = pinctls & AC_PINCTL_VREFEN;
431 switch (vref) {
432 case AC_PINCTL_VREF_HIZ:
433 snd_iprintf(buffer, " VREF_HIZ");
434 break;
435 case AC_PINCTL_VREF_50:
436 snd_iprintf(buffer, " VREF_50");
437 break;
438 case AC_PINCTL_VREF_GRD:
439 snd_iprintf(buffer, " VREF_GRD");
440 break;
441 case AC_PINCTL_VREF_80:
442 snd_iprintf(buffer, " VREF_80");
443 break;
444 case AC_PINCTL_VREF_100:
445 snd_iprintf(buffer, " VREF_100");
446 break;
449 snd_iprintf(buffer, "\n");
452 static void print_vol_knob(struct snd_info_buffer *buffer,
453 struct hda_codec *codec, hda_nid_t nid)
455 unsigned int cap = param_read(codec, nid, AC_PAR_VOL_KNB_CAP);
456 snd_iprintf(buffer, " Volume-Knob: delta=%d, steps=%d, ",
457 (cap >> 7) & 1, cap & 0x7f);
458 cap = snd_hda_codec_read(codec, nid, 0,
459 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
460 snd_iprintf(buffer, "direct=%d, val=%d\n",
461 (cap >> 7) & 1, cap & 0x7f);
464 static void print_audio_io(struct snd_info_buffer *buffer,
465 struct hda_codec *codec, hda_nid_t nid,
466 unsigned int wid_type)
468 int conv = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
469 snd_iprintf(buffer,
470 " Converter: stream=%d, channel=%d\n",
471 (conv & AC_CONV_STREAM) >> AC_CONV_STREAM_SHIFT,
472 conv & AC_CONV_CHANNEL);
474 if (wid_type == AC_WID_AUD_IN && (conv & AC_CONV_CHANNEL) == 0) {
475 int sdi = snd_hda_codec_read(codec, nid, 0,
476 AC_VERB_GET_SDI_SELECT, 0);
477 snd_iprintf(buffer, " SDI-Select: %d\n",
478 sdi & AC_SDI_SELECT);
482 static void print_digital_conv(struct snd_info_buffer *buffer,
483 struct hda_codec *codec, hda_nid_t nid)
485 unsigned int digi1 = snd_hda_codec_read(codec, nid, 0,
486 AC_VERB_GET_DIGI_CONVERT_1, 0);
487 unsigned char digi2 = digi1 >> 8;
488 unsigned char digi3 = digi1 >> 16;
490 snd_iprintf(buffer, " Digital:");
491 if (digi1 & AC_DIG1_ENABLE)
492 snd_iprintf(buffer, " Enabled");
493 if (digi1 & AC_DIG1_V)
494 snd_iprintf(buffer, " Validity");
495 if (digi1 & AC_DIG1_VCFG)
496 snd_iprintf(buffer, " ValidityCfg");
497 if (digi1 & AC_DIG1_EMPHASIS)
498 snd_iprintf(buffer, " Preemphasis");
499 if (digi1 & AC_DIG1_COPYRIGHT)
500 snd_iprintf(buffer, " Non-Copyright");
501 if (digi1 & AC_DIG1_NONAUDIO)
502 snd_iprintf(buffer, " Non-Audio");
503 if (digi1 & AC_DIG1_PROFESSIONAL)
504 snd_iprintf(buffer, " Pro");
505 if (digi1 & AC_DIG1_LEVEL)
506 snd_iprintf(buffer, " GenLevel");
507 if (digi3 & AC_DIG3_KAE)
508 snd_iprintf(buffer, " KAE");
509 snd_iprintf(buffer, "\n");
510 snd_iprintf(buffer, " Digital category: 0x%x\n",
511 digi2 & AC_DIG2_CC);
512 snd_iprintf(buffer, " IEC Coding Type: 0x%x\n",
513 digi3 & AC_DIG3_ICT);
516 static const char *get_pwr_state(u32 state)
518 static const char * const buf[] = {
519 "D0", "D1", "D2", "D3", "D3cold"
521 if (state < ARRAY_SIZE(buf))
522 return buf[state];
523 return "UNKNOWN";
526 static void print_power_state(struct snd_info_buffer *buffer,
527 struct hda_codec *codec, hda_nid_t nid)
529 static const char * const names[] = {
530 [ilog2(AC_PWRST_D0SUP)] = "D0",
531 [ilog2(AC_PWRST_D1SUP)] = "D1",
532 [ilog2(AC_PWRST_D2SUP)] = "D2",
533 [ilog2(AC_PWRST_D3SUP)] = "D3",
534 [ilog2(AC_PWRST_D3COLDSUP)] = "D3cold",
535 [ilog2(AC_PWRST_S3D3COLDSUP)] = "S3D3cold",
536 [ilog2(AC_PWRST_CLKSTOP)] = "CLKSTOP",
537 [ilog2(AC_PWRST_EPSS)] = "EPSS",
540 int sup = param_read(codec, nid, AC_PAR_POWER_STATE);
541 int pwr = snd_hda_codec_read(codec, nid, 0,
542 AC_VERB_GET_POWER_STATE, 0);
543 if (sup != -1) {
544 int i;
546 snd_iprintf(buffer, " Power states: ");
547 for (i = 0; i < ARRAY_SIZE(names); i++) {
548 if (sup & (1U << i))
549 snd_iprintf(buffer, " %s", names[i]);
551 snd_iprintf(buffer, "\n");
554 snd_iprintf(buffer, " Power: setting=%s, actual=%s",
555 get_pwr_state(pwr & AC_PWRST_SETTING),
556 get_pwr_state((pwr & AC_PWRST_ACTUAL) >>
557 AC_PWRST_ACTUAL_SHIFT));
558 if (pwr & AC_PWRST_ERROR)
559 snd_iprintf(buffer, ", Error");
560 if (pwr & AC_PWRST_CLK_STOP_OK)
561 snd_iprintf(buffer, ", Clock-stop-OK");
562 if (pwr & AC_PWRST_SETTING_RESET)
563 snd_iprintf(buffer, ", Setting-reset");
564 snd_iprintf(buffer, "\n");
567 static void print_unsol_cap(struct snd_info_buffer *buffer,
568 struct hda_codec *codec, hda_nid_t nid)
570 int unsol = snd_hda_codec_read(codec, nid, 0,
571 AC_VERB_GET_UNSOLICITED_RESPONSE, 0);
572 snd_iprintf(buffer,
573 " Unsolicited: tag=%02x, enabled=%d\n",
574 unsol & AC_UNSOL_TAG,
575 (unsol & AC_UNSOL_ENABLED) ? 1 : 0);
578 static inline bool can_dump_coef(struct hda_codec *codec)
580 switch (dump_coef) {
581 case 0: return false;
582 case 1: return true;
583 default: return codec->dump_coef;
587 static void print_proc_caps(struct snd_info_buffer *buffer,
588 struct hda_codec *codec, hda_nid_t nid)
590 unsigned int i, ncoeff, oldindex;
591 unsigned int proc_caps = param_read(codec, nid, AC_PAR_PROC_CAP);
592 ncoeff = (proc_caps & AC_PCAP_NUM_COEF) >> AC_PCAP_NUM_COEF_SHIFT;
593 snd_iprintf(buffer, " Processing caps: benign=%d, ncoeff=%d\n",
594 proc_caps & AC_PCAP_BENIGN, ncoeff);
596 if (!can_dump_coef(codec))
597 return;
599 /* Note: This is racy - another process could run in parallel and change
600 the coef index too. */
601 oldindex = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_COEF_INDEX, 0);
602 for (i = 0; i < ncoeff; i++) {
603 unsigned int val;
604 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, i);
605 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF,
607 snd_iprintf(buffer, " Coeff 0x%02x: 0x%04x\n", i, val);
609 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, oldindex);
612 static void print_conn_list(struct snd_info_buffer *buffer,
613 struct hda_codec *codec, hda_nid_t nid,
614 unsigned int wid_type, hda_nid_t *conn,
615 int conn_len)
617 int c, curr = -1;
618 const hda_nid_t *list;
619 int cache_len;
621 if (conn_len > 1 &&
622 wid_type != AC_WID_AUD_MIX &&
623 wid_type != AC_WID_VOL_KNB &&
624 wid_type != AC_WID_POWER)
625 curr = snd_hda_codec_read(codec, nid, 0,
626 AC_VERB_GET_CONNECT_SEL, 0);
627 snd_iprintf(buffer, " Connection: %d\n", conn_len);
628 if (conn_len > 0) {
629 snd_iprintf(buffer, " ");
630 for (c = 0; c < conn_len; c++) {
631 snd_iprintf(buffer, " 0x%02x", conn[c]);
632 if (c == curr)
633 snd_iprintf(buffer, "*");
635 snd_iprintf(buffer, "\n");
638 /* Get Cache connections info */
639 cache_len = snd_hda_get_conn_list(codec, nid, &list);
640 if (cache_len >= 0 && (cache_len != conn_len ||
641 memcmp(list, conn, conn_len) != 0)) {
642 snd_iprintf(buffer, " In-driver Connection: %d\n", cache_len);
643 if (cache_len > 0) {
644 snd_iprintf(buffer, " ");
645 for (c = 0; c < cache_len; c++)
646 snd_iprintf(buffer, " 0x%02x", list[c]);
647 snd_iprintf(buffer, "\n");
652 static void print_gpio(struct snd_info_buffer *buffer,
653 struct hda_codec *codec, hda_nid_t nid)
655 unsigned int gpio =
656 param_read(codec, codec->core.afg, AC_PAR_GPIO_CAP);
657 unsigned int enable, direction, wake, unsol, sticky, data;
658 int i, max;
659 snd_iprintf(buffer, "GPIO: io=%d, o=%d, i=%d, "
660 "unsolicited=%d, wake=%d\n",
661 gpio & AC_GPIO_IO_COUNT,
662 (gpio & AC_GPIO_O_COUNT) >> AC_GPIO_O_COUNT_SHIFT,
663 (gpio & AC_GPIO_I_COUNT) >> AC_GPIO_I_COUNT_SHIFT,
664 (gpio & AC_GPIO_UNSOLICITED) ? 1 : 0,
665 (gpio & AC_GPIO_WAKE) ? 1 : 0);
666 max = gpio & AC_GPIO_IO_COUNT;
667 if (!max || max > 8)
668 return;
669 enable = snd_hda_codec_read(codec, nid, 0,
670 AC_VERB_GET_GPIO_MASK, 0);
671 direction = snd_hda_codec_read(codec, nid, 0,
672 AC_VERB_GET_GPIO_DIRECTION, 0);
673 wake = snd_hda_codec_read(codec, nid, 0,
674 AC_VERB_GET_GPIO_WAKE_MASK, 0);
675 unsol = snd_hda_codec_read(codec, nid, 0,
676 AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK, 0);
677 sticky = snd_hda_codec_read(codec, nid, 0,
678 AC_VERB_GET_GPIO_STICKY_MASK, 0);
679 data = snd_hda_codec_read(codec, nid, 0,
680 AC_VERB_GET_GPIO_DATA, 0);
681 for (i = 0; i < max; ++i)
682 snd_iprintf(buffer,
683 " IO[%d]: enable=%d, dir=%d, wake=%d, "
684 "sticky=%d, data=%d, unsol=%d\n", i,
685 (enable & (1<<i)) ? 1 : 0,
686 (direction & (1<<i)) ? 1 : 0,
687 (wake & (1<<i)) ? 1 : 0,
688 (sticky & (1<<i)) ? 1 : 0,
689 (data & (1<<i)) ? 1 : 0,
690 (unsol & (1<<i)) ? 1 : 0);
691 /* FIXME: add GPO and GPI pin information */
692 print_nid_array(buffer, codec, nid, &codec->mixers);
693 print_nid_array(buffer, codec, nid, &codec->nids);
696 static void print_device_list(struct snd_info_buffer *buffer,
697 struct hda_codec *codec, hda_nid_t nid)
699 int i, curr = -1;
700 u8 dev_list[AC_MAX_DEV_LIST_LEN];
701 int devlist_len;
703 devlist_len = snd_hda_get_devices(codec, nid, dev_list,
704 AC_MAX_DEV_LIST_LEN);
705 snd_iprintf(buffer, " Devices: %d\n", devlist_len);
706 if (devlist_len <= 0)
707 return;
709 curr = snd_hda_codec_read(codec, nid, 0,
710 AC_VERB_GET_DEVICE_SEL, 0);
712 for (i = 0; i < devlist_len; i++) {
713 if (i == curr)
714 snd_iprintf(buffer, " *");
715 else
716 snd_iprintf(buffer, " ");
718 snd_iprintf(buffer,
719 "Dev %02d: PD = %d, ELDV = %d, IA = %d\n", i,
720 !!(dev_list[i] & AC_DE_PD),
721 !!(dev_list[i] & AC_DE_ELDV),
722 !!(dev_list[i] & AC_DE_IA));
726 static void print_codec_core_info(struct hdac_device *codec,
727 struct snd_info_buffer *buffer)
729 snd_iprintf(buffer, "Codec: ");
730 if (codec->vendor_name && codec->chip_name)
731 snd_iprintf(buffer, "%s %s\n",
732 codec->vendor_name, codec->chip_name);
733 else
734 snd_iprintf(buffer, "Not Set\n");
735 snd_iprintf(buffer, "Address: %d\n", codec->addr);
736 if (codec->afg)
737 snd_iprintf(buffer, "AFG Function Id: 0x%x (unsol %u)\n",
738 codec->afg_function_id, codec->afg_unsol);
739 if (codec->mfg)
740 snd_iprintf(buffer, "MFG Function Id: 0x%x (unsol %u)\n",
741 codec->mfg_function_id, codec->mfg_unsol);
742 snd_iprintf(buffer, "Vendor Id: 0x%08x\n", codec->vendor_id);
743 snd_iprintf(buffer, "Subsystem Id: 0x%08x\n", codec->subsystem_id);
744 snd_iprintf(buffer, "Revision Id: 0x%x\n", codec->revision_id);
746 if (codec->mfg)
747 snd_iprintf(buffer, "Modem Function Group: 0x%x\n", codec->mfg);
748 else
749 snd_iprintf(buffer, "No Modem Function Group found\n");
752 static void print_codec_info(struct snd_info_entry *entry,
753 struct snd_info_buffer *buffer)
755 struct hda_codec *codec = entry->private_data;
756 hda_nid_t nid, fg;
757 int i, nodes;
759 print_codec_core_info(&codec->core, buffer);
760 fg = codec->core.afg;
761 if (!fg)
762 return;
763 snd_hda_power_up(codec);
764 snd_iprintf(buffer, "Default PCM:\n");
765 print_pcm_caps(buffer, codec, fg);
766 snd_iprintf(buffer, "Default Amp-In caps: ");
767 print_amp_caps(buffer, codec, fg, HDA_INPUT);
768 snd_iprintf(buffer, "Default Amp-Out caps: ");
769 print_amp_caps(buffer, codec, fg, HDA_OUTPUT);
770 snd_iprintf(buffer, "State of AFG node 0x%02x:\n", fg);
771 print_power_state(buffer, codec, fg);
773 nodes = snd_hda_get_sub_nodes(codec, fg, &nid);
774 if (! nid || nodes < 0) {
775 snd_iprintf(buffer, "Invalid AFG subtree\n");
776 snd_hda_power_down(codec);
777 return;
780 print_gpio(buffer, codec, fg);
781 if (codec->proc_widget_hook)
782 codec->proc_widget_hook(buffer, codec, fg);
784 for (i = 0; i < nodes; i++, nid++) {
785 unsigned int wid_caps =
786 param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
787 unsigned int wid_type = get_wcaps_type(wid_caps);
788 hda_nid_t *conn = NULL;
789 int conn_len = 0;
791 snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid,
792 get_wid_type_name(wid_type), wid_caps);
793 if (wid_caps & AC_WCAP_STEREO) {
794 unsigned int chans = get_wcaps_channels(wid_caps);
795 if (chans == 2)
796 snd_iprintf(buffer, " Stereo");
797 else
798 snd_iprintf(buffer, " %d-Channels", chans);
799 } else
800 snd_iprintf(buffer, " Mono");
801 if (wid_caps & AC_WCAP_DIGITAL)
802 snd_iprintf(buffer, " Digital");
803 if (wid_caps & AC_WCAP_IN_AMP)
804 snd_iprintf(buffer, " Amp-In");
805 if (wid_caps & AC_WCAP_OUT_AMP)
806 snd_iprintf(buffer, " Amp-Out");
807 if (wid_caps & AC_WCAP_STRIPE)
808 snd_iprintf(buffer, " Stripe");
809 if (wid_caps & AC_WCAP_LR_SWAP)
810 snd_iprintf(buffer, " R/L");
811 if (wid_caps & AC_WCAP_CP_CAPS)
812 snd_iprintf(buffer, " CP");
813 snd_iprintf(buffer, "\n");
815 print_nid_array(buffer, codec, nid, &codec->mixers);
816 print_nid_array(buffer, codec, nid, &codec->nids);
817 print_nid_pcms(buffer, codec, nid);
819 /* volume knob is a special widget that always have connection
820 * list
822 if (wid_type == AC_WID_VOL_KNB)
823 wid_caps |= AC_WCAP_CONN_LIST;
825 if (wid_caps & AC_WCAP_CONN_LIST) {
826 conn_len = snd_hda_get_num_raw_conns(codec, nid);
827 if (conn_len > 0) {
828 conn = kmalloc(sizeof(hda_nid_t) * conn_len,
829 GFP_KERNEL);
830 if (!conn)
831 return;
832 if (snd_hda_get_raw_connections(codec, nid, conn,
833 conn_len) < 0)
834 conn_len = 0;
838 if (wid_caps & AC_WCAP_IN_AMP) {
839 snd_iprintf(buffer, " Amp-In caps: ");
840 print_amp_caps(buffer, codec, nid, HDA_INPUT);
841 snd_iprintf(buffer, " Amp-In vals: ");
842 if (wid_type == AC_WID_PIN ||
843 (codec->single_adc_amp &&
844 wid_type == AC_WID_AUD_IN))
845 print_amp_vals(buffer, codec, nid, HDA_INPUT,
846 wid_caps, 1);
847 else
848 print_amp_vals(buffer, codec, nid, HDA_INPUT,
849 wid_caps, conn_len);
851 if (wid_caps & AC_WCAP_OUT_AMP) {
852 snd_iprintf(buffer, " Amp-Out caps: ");
853 print_amp_caps(buffer, codec, nid, HDA_OUTPUT);
854 snd_iprintf(buffer, " Amp-Out vals: ");
855 if (wid_type == AC_WID_PIN &&
856 codec->pin_amp_workaround)
857 print_amp_vals(buffer, codec, nid, HDA_OUTPUT,
858 wid_caps, conn_len);
859 else
860 print_amp_vals(buffer, codec, nid, HDA_OUTPUT,
861 wid_caps, 1);
864 switch (wid_type) {
865 case AC_WID_PIN: {
866 int supports_vref;
867 print_pin_caps(buffer, codec, nid, &supports_vref);
868 print_pin_ctls(buffer, codec, nid, supports_vref);
869 break;
871 case AC_WID_VOL_KNB:
872 print_vol_knob(buffer, codec, nid);
873 break;
874 case AC_WID_AUD_OUT:
875 case AC_WID_AUD_IN:
876 print_audio_io(buffer, codec, nid, wid_type);
877 if (wid_caps & AC_WCAP_DIGITAL)
878 print_digital_conv(buffer, codec, nid);
879 if (wid_caps & AC_WCAP_FORMAT_OVRD) {
880 snd_iprintf(buffer, " PCM:\n");
881 print_pcm_caps(buffer, codec, nid);
883 break;
886 if (wid_caps & AC_WCAP_UNSOL_CAP)
887 print_unsol_cap(buffer, codec, nid);
889 if (wid_caps & AC_WCAP_POWER)
890 print_power_state(buffer, codec, nid);
892 if (wid_caps & AC_WCAP_DELAY)
893 snd_iprintf(buffer, " Delay: %d samples\n",
894 (wid_caps & AC_WCAP_DELAY) >>
895 AC_WCAP_DELAY_SHIFT);
897 if (wid_type == AC_WID_PIN && codec->dp_mst)
898 print_device_list(buffer, codec, nid);
900 if (wid_caps & AC_WCAP_CONN_LIST)
901 print_conn_list(buffer, codec, nid, wid_type,
902 conn, conn_len);
904 if (wid_caps & AC_WCAP_PROC_WID)
905 print_proc_caps(buffer, codec, nid);
907 if (codec->proc_widget_hook)
908 codec->proc_widget_hook(buffer, codec, nid);
910 kfree(conn);
912 snd_hda_power_down(codec);
916 * create a proc read
918 int snd_hda_codec_proc_new(struct hda_codec *codec)
920 char name[32];
921 struct snd_info_entry *entry;
922 int err;
924 snprintf(name, sizeof(name), "codec#%d", codec->core.addr);
925 err = snd_card_proc_new(codec->card, name, &entry);
926 if (err < 0)
927 return err;
929 snd_info_set_text_ops(entry, codec, print_codec_info);
930 return 0;