aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorAndrew Paprocki <andrew@ishiboo.com>2008-01-18 06:51:11 -0500
committerJaroslav Kysela <perex@perex.cz>2008-01-31 11:30:04 -0500
commit797760ab14db4e82a50c06a9916dd5c6147b415b (patch)
treec60c279c9dbbe81d399a0d6a7648cfacb2bef60d /sound
parente0059549345903195d6eb796c22048204c40a785 (diff)
[ALSA] hda_proc - Add a number of new settings to proc codec output
This patch adds additional output to the /proc codec#X info. The following pieces of information are added to the output: - Balanced, L/R swap, trigger, impedance sense pin capabilities - Vref pin capabilities - Current Vref pin widget control setting - Default configuration association, sequence, and misc bit test - EAPD/BTL bits conveying balanced mode, EAPD, and L/R swap - Power state modified to show state name as well as setting vs actual value - GPIO parameter output on Audio Function Group, including enumeration of IO pins which are indicated present (Any I and O pins are not output at this time) - Stripe and L/R swap widget capabilities - All digital converter bits: enable, validity, validity config, preemphasis, copyright, non-audio, professional, generation level, and content category - Converter stream and channel values for in/out widgets - SDI select value for in widgets - Unsolicited response widget capability tag and enabled bit - Delay widget capability value - Processing widget capability benign bit and number of coefficients - Realtek Define Registers: processing coefficient, coefficient index [Also, fixed space/tab issues and make codes a bit more readable -- Takashi] Signed-off-by: Andrew Paprocki <andrew@ishiboo.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_codec.h42
-rw-r--r--sound/pci/hda/hda_proc.c351
2 files changed, 343 insertions, 50 deletions
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 719e46f6fb36..eb4a2ae792e9 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -84,7 +84,9 @@ enum {
84#define AC_VERB_GET_GPIO_DATA 0x0f15 84#define AC_VERB_GET_GPIO_DATA 0x0f15
85#define AC_VERB_GET_GPIO_MASK 0x0f16 85#define AC_VERB_GET_GPIO_MASK 0x0f16
86#define AC_VERB_GET_GPIO_DIRECTION 0x0f17 86#define AC_VERB_GET_GPIO_DIRECTION 0x0f17
87#define AC_VERB_GET_GPIO_WAKE_MASK 0x0f18
87#define AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK 0x0f19 88#define AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK 0x0f19
89#define AC_VERB_GET_GPIO_STICKY_MASK 0x0f1a
88#define AC_VERB_GET_CONFIG_DEFAULT 0x0f1c 90#define AC_VERB_GET_CONFIG_DEFAULT 0x0f1c
89/* f20: AFG/MFG */ 91/* f20: AFG/MFG */
90#define AC_VERB_GET_SUBSYSTEM_ID 0x0f20 92#define AC_VERB_GET_SUBSYSTEM_ID 0x0f20
@@ -112,7 +114,9 @@ enum {
112#define AC_VERB_SET_GPIO_DATA 0x715 114#define AC_VERB_SET_GPIO_DATA 0x715
113#define AC_VERB_SET_GPIO_MASK 0x716 115#define AC_VERB_SET_GPIO_MASK 0x716
114#define AC_VERB_SET_GPIO_DIRECTION 0x717 116#define AC_VERB_SET_GPIO_DIRECTION 0x717
117#define AC_VERB_SET_GPIO_WAKE_MASK 0x718
115#define AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK 0x719 118#define AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK 0x719
119#define AC_VERB_SET_GPIO_STICKY_MASK 0x71a
116#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 0x71c 120#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 0x71c
117#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_1 0x71d 121#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_1 0x71d
118#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_2 0x71e 122#define AC_VERB_SET_CONFIG_DEFAULT_BYTES_2 0x71e
@@ -185,6 +189,27 @@ enum {
185#define AC_SUPFMT_FLOAT32 (1<<1) 189#define AC_SUPFMT_FLOAT32 (1<<1)
186#define AC_SUPFMT_AC3 (1<<2) 190#define AC_SUPFMT_AC3 (1<<2)
187 191
192/* GP I/O count */
193#define AC_GPIO_IO_COUNT (0xff<<0)
194#define AC_GPIO_O_COUNT (0xff<<8)
195#define AC_GPIO_O_COUNT_SHIFT 8
196#define AC_GPIO_I_COUNT (0xff<<16)
197#define AC_GPIO_I_COUNT_SHIFT 16
198#define AC_GPIO_UNSOLICITED (1<<30)
199#define AC_GPIO_WAKE (1<<31)
200
201/* Converter stream, channel */
202#define AC_CONV_CHANNEL (0xf<<0)
203#define AC_CONV_STREAM (0xf<<4)
204#define AC_CONV_STREAM_SHIFT 4
205
206/* Input converter SDI select */
207#define AC_SDI_SELECT (0xf<<0)
208
209/* Unsolicited response */
210#define AC_UNSOL_TAG (0x3f<<0)
211#define AC_UNSOL_ENABLED (1<<7)
212
188/* Pin widget capabilies */ 213/* Pin widget capabilies */
189#define AC_PINCAP_IMP_SENSE (1<<0) /* impedance sense capable */ 214#define AC_PINCAP_IMP_SENSE (1<<0) /* impedance sense capable */
190#define AC_PINCAP_TRIG_REQ (1<<1) /* trigger required */ 215#define AC_PINCAP_TRIG_REQ (1<<1) /* trigger required */
@@ -230,6 +255,9 @@ enum {
230#define AC_PWRST_D3SUP (1<<3) 255#define AC_PWRST_D3SUP (1<<3)
231 256
232/* Power state values */ 257/* Power state values */
258#define AC_PWRST_SETTING (0xf<<0)
259#define AC_PWRST_ACTUAL (0xf<<4)
260#define AC_PWRST_ACTUAL_SHIFT 4
233#define AC_PWRST_D0 0x00 261#define AC_PWRST_D0 0x00
234#define AC_PWRST_D1 0x01 262#define AC_PWRST_D1 0x01
235#define AC_PWRST_D2 0x02 263#define AC_PWRST_D2 0x02
@@ -238,6 +266,7 @@ enum {
238/* Processing capabilies */ 266/* Processing capabilies */
239#define AC_PCAP_BENIGN (1<<0) 267#define AC_PCAP_BENIGN (1<<0)
240#define AC_PCAP_NUM_COEF (0xff<<8) 268#define AC_PCAP_NUM_COEF (0xff<<8)
269#define AC_PCAP_NUM_COEF_SHIFT 8
241 270
242/* Volume knobs capabilities */ 271/* Volume knobs capabilities */
243#define AC_KNBCAP_NUM_STEPS (0x7f<<0) 272#define AC_KNBCAP_NUM_STEPS (0x7f<<0)
@@ -274,6 +303,9 @@ enum {
274#define AC_DIG1_PROFESSIONAL (1<<6) 303#define AC_DIG1_PROFESSIONAL (1<<6)
275#define AC_DIG1_LEVEL (1<<7) 304#define AC_DIG1_LEVEL (1<<7)
276 305
306/* DIGITAL2 bits */
307#define AC_DIG2_CC (0x7f<<0)
308
277/* Pin widget control - 8bit */ 309/* Pin widget control - 8bit */
278#define AC_PINCTL_VREFEN (0x7<<0) 310#define AC_PINCTL_VREFEN (0x7<<0)
279#define AC_PINCTL_VREF_HIZ 0 /* Hi-Z */ 311#define AC_PINCTL_VREF_HIZ 0 /* Hi-Z */
@@ -288,12 +320,22 @@ enum {
288/* Unsolicited response - 8bit */ 320/* Unsolicited response - 8bit */
289#define AC_USRSP_EN (1<<7) 321#define AC_USRSP_EN (1<<7)
290 322
323/* Pin sense - 32bit */
324#define AC_PINSENSE_IMPEDANCE_MASK (0x7fffffff)
325#define AC_PINSENSE_PRESENCE (1<<31)
326
327/* EAPD/BTL enable - 32bit */
328#define AC_EAPDBTL_BALANCED (1<<0)
329#define AC_EAPDBTL_EAPD (1<<1)
330#define AC_EAPDBTL_LR_SWAP (1<<2)
331
291/* configuration default - 32bit */ 332/* configuration default - 32bit */
292#define AC_DEFCFG_SEQUENCE (0xf<<0) 333#define AC_DEFCFG_SEQUENCE (0xf<<0)
293#define AC_DEFCFG_DEF_ASSOC (0xf<<4) 334#define AC_DEFCFG_DEF_ASSOC (0xf<<4)
294#define AC_DEFCFG_ASSOC_SHIFT 4 335#define AC_DEFCFG_ASSOC_SHIFT 4
295#define AC_DEFCFG_MISC (0xf<<8) 336#define AC_DEFCFG_MISC (0xf<<8)
296#define AC_DEFCFG_MISC_SHIFT 8 337#define AC_DEFCFG_MISC_SHIFT 8
338#define AC_DEFCFG_MISC_NO_PRESENCE (1<<0)
297#define AC_DEFCFG_COLOR (0xf<<12) 339#define AC_DEFCFG_COLOR (0xf<<12)
298#define AC_DEFCFG_COLOR_SHIFT 12 340#define AC_DEFCFG_COLOR_SHIFT 12
299#define AC_DEFCFG_CONN_TYPE (0xf<<16) 341#define AC_DEFCFG_CONN_TYPE (0xf<<16)
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 4b8d64498fb1..35a630d1770f 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -202,7 +202,8 @@ static const char *get_jack_color(u32 cfg)
202} 202}
203 203
204static void print_pin_caps(struct snd_info_buffer *buffer, 204static void print_pin_caps(struct snd_info_buffer *buffer,
205 struct hda_codec *codec, hda_nid_t nid) 205 struct hda_codec *codec, hda_nid_t nid,
206 int *supports_vref)
206{ 207{
207 static char *jack_conns[4] = { "Jack", "N/A", "Fixed", "Both" }; 208 static char *jack_conns[4] = { "Jack", "N/A", "Fixed", "Both" };
208 static char *jack_types[16] = { 209 static char *jack_types[16] = {
@@ -226,7 +227,45 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
226 snd_iprintf(buffer, " EAPD"); 227 snd_iprintf(buffer, " EAPD");
227 if (caps & AC_PINCAP_PRES_DETECT) 228 if (caps & AC_PINCAP_PRES_DETECT)
228 snd_iprintf(buffer, " Detect"); 229 snd_iprintf(buffer, " Detect");
230 if (caps & AC_PINCAP_BALANCE)
231 snd_iprintf(buffer, " Balanced");
232 if (caps & AC_PINCAP_LR_SWAP)
233 snd_iprintf(buffer, " R/L");
234 if (caps & AC_PINCAP_TRIG_REQ)
235 snd_iprintf(buffer, " Trigger");
236 if (caps & AC_PINCAP_IMP_SENSE)
237 snd_iprintf(buffer, " ImpSense");
229 snd_iprintf(buffer, "\n"); 238 snd_iprintf(buffer, "\n");
239 if (caps & AC_PINCAP_VREF) {
240 unsigned int vref =
241 (caps & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
242 snd_iprintf(buffer, " Vref caps:");
243 if (vref & AC_PINCAP_VREF_HIZ)
244 snd_iprintf(buffer, " HIZ");
245 if (vref & AC_PINCAP_VREF_50)
246 snd_iprintf(buffer, " 50");
247 if (vref & AC_PINCAP_VREF_GRD)
248 snd_iprintf(buffer, " GRD");
249 if (vref & AC_PINCAP_VREF_80)
250 snd_iprintf(buffer, " 80");
251 if (vref & AC_PINCAP_VREF_100)
252 snd_iprintf(buffer, " 100");
253 snd_iprintf(buffer, "\n");
254 *supports_vref = 1;
255 } else
256 *supports_vref = 0;
257 if (caps & AC_PINCAP_EAPD) {
258 val = snd_hda_codec_read(codec, nid, 0,
259 AC_VERB_GET_EAPD_BTLENABLE, 0);
260 snd_iprintf(buffer, " EAPD 0x%x:", val);
261 if (val & AC_EAPDBTL_BALANCED)
262 snd_iprintf(buffer, " BALANCED");
263 if (val & AC_EAPDBTL_EAPD)
264 snd_iprintf(buffer, " EAPD");
265 if (val & AC_EAPDBTL_LR_SWAP)
266 snd_iprintf(buffer, " R/L");
267 snd_iprintf(buffer, "\n");
268 }
230 caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); 269 caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
231 snd_iprintf(buffer, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps, 270 snd_iprintf(buffer, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps,
232 jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT], 271 jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT],
@@ -236,13 +275,233 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
236 snd_iprintf(buffer, " Conn = %s, Color = %s\n", 275 snd_iprintf(buffer, " Conn = %s, Color = %s\n",
237 get_jack_connection(caps), 276 get_jack_connection(caps),
238 get_jack_color(caps)); 277 get_jack_color(caps));
239 if (caps & AC_PINCAP_EAPD) { 278 /* Default association and sequence values refer to default grouping
240 val = snd_hda_codec_read(codec, nid, 0, 279 * of pin complexes and their sequence within the group. This is used
241 AC_VERB_GET_EAPD_BTLENABLE, 0); 280 * for priority and resource allocation.
242 snd_iprintf(buffer, " EAPD: 0x%x\n", val); 281 */
282 snd_iprintf(buffer, " DefAssociation = 0x%x, Sequence = 0x%x\n",
283 (caps & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT,
284 caps & AC_DEFCFG_SEQUENCE);
285 if (((caps & AC_DEFCFG_MISC) >> AC_DEFCFG_MISC_SHIFT) &
286 AC_DEFCFG_MISC_NO_PRESENCE) {
287 /* Miscellaneous bit indicates external hardware does not
288 * support presence detection even if the pin complex
289 * indicates it is supported.
290 */
291 snd_iprintf(buffer, " Misc = NO_PRESENCE\n");
243 } 292 }
244} 293}
245 294
295static void print_pin_ctls(struct snd_info_buffer *buffer,
296 struct hda_codec *codec, hda_nid_t nid,
297 int supports_vref)
298{
299 unsigned int pinctls;
300
301 pinctls = snd_hda_codec_read(codec, nid, 0,
302 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
303 snd_iprintf(buffer, " Pin-ctls: 0x%02x:", pinctls);
304 if (pinctls & AC_PINCTL_IN_EN)
305 snd_iprintf(buffer, " IN");
306 if (pinctls & AC_PINCTL_OUT_EN)
307 snd_iprintf(buffer, " OUT");
308 if (pinctls & AC_PINCTL_HP_EN)
309 snd_iprintf(buffer, " HP");
310 if (supports_vref) {
311 int vref = pinctls & AC_PINCTL_VREFEN;
312 switch (vref) {
313 case AC_PINCTL_VREF_HIZ:
314 snd_iprintf(buffer, " VREF_HIZ");
315 break;
316 case AC_PINCTL_VREF_50:
317 snd_iprintf(buffer, " VREF_50");
318 break;
319 case AC_PINCTL_VREF_GRD:
320 snd_iprintf(buffer, " VREF_GRD");
321 break;
322 case AC_PINCTL_VREF_80:
323 snd_iprintf(buffer, " VREF_80");
324 break;
325 case AC_PINCTL_VREF_100:
326 snd_iprintf(buffer, " VREF_100");
327 break;
328 }
329 }
330 snd_iprintf(buffer, "\n");
331}
332
333static void print_vol_knob(struct snd_info_buffer *buffer,
334 struct hda_codec *codec, hda_nid_t nid)
335{
336 unsigned int cap = snd_hda_param_read(codec, nid,
337 AC_PAR_VOL_KNB_CAP);
338 snd_iprintf(buffer, " Volume-Knob: delta=%d, steps=%d, ",
339 (cap >> 7) & 1, cap & 0x7f);
340 cap = snd_hda_codec_read(codec, nid, 0,
341 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
342 snd_iprintf(buffer, "direct=%d, val=%d\n",
343 (cap >> 7) & 1, cap & 0x7f);
344}
345
346static void print_audio_io(struct snd_info_buffer *buffer,
347 struct hda_codec *codec, hda_nid_t nid,
348 unsigned int wid_type)
349{
350 int conv = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
351 snd_iprintf(buffer,
352 " Converter: stream=%d, channel=%d\n",
353 (conv & AC_CONV_STREAM) >> AC_CONV_STREAM_SHIFT,
354 conv & AC_CONV_CHANNEL);
355
356 if (wid_type == AC_WID_AUD_IN && (conv & AC_CONV_CHANNEL) == 0) {
357 int sdi = snd_hda_codec_read(codec, nid, 0,
358 AC_VERB_GET_SDI_SELECT, 0);
359 snd_iprintf(buffer, " SDI-Select: %d\n",
360 sdi & AC_SDI_SELECT);
361 }
362}
363
364static void print_digital_conv(struct snd_info_buffer *buffer,
365 struct hda_codec *codec, hda_nid_t nid)
366{
367 unsigned int digi1 = snd_hda_codec_read(codec, nid, 0,
368 AC_VERB_GET_DIGI_CONVERT_1, 0);
369 unsigned int digi2 = snd_hda_codec_read(codec, nid, 0,
370 AC_VERB_GET_DIGI_CONVERT_2, 0);
371 snd_iprintf(buffer, " Digital:");
372 if (digi1 & AC_DIG1_ENABLE)
373 snd_iprintf(buffer, " Enabled");
374 if (digi1 & AC_DIG1_V)
375 snd_iprintf(buffer, " Validity");
376 if (digi1 & AC_DIG1_VCFG)
377 snd_iprintf(buffer, " ValidityCfg");
378 if (digi1 & AC_DIG1_EMPHASIS)
379 snd_iprintf(buffer, " Preemphasis");
380 if (digi1 & AC_DIG1_COPYRIGHT)
381 snd_iprintf(buffer, " Copyright");
382 if (digi1 & AC_DIG1_NONAUDIO)
383 snd_iprintf(buffer, " Non-Audio");
384 if (digi1 & AC_DIG1_PROFESSIONAL)
385 snd_iprintf(buffer, " Pro");
386 if (digi1 & AC_DIG1_LEVEL)
387 snd_iprintf(buffer, " GenLevel");
388 snd_iprintf(buffer, "\n");
389 snd_iprintf(buffer, " Digital category: 0x%x\n", digi2 & AC_DIG2_CC);
390}
391
392static const char *get_pwr_state(u32 state)
393{
394 static const char *buf[4] = {
395 "D0", "D1", "D2", "D3"
396 };
397 if (state < 4)
398 return buf[state];
399 return "UNKNOWN";
400}
401
402static void print_power_state(struct snd_info_buffer *buffer,
403 struct hda_codec *codec, hda_nid_t nid)
404{
405 int pwr = snd_hda_codec_read(codec, nid, 0,
406 AC_VERB_GET_POWER_STATE, 0);
407 snd_iprintf(buffer, " Power: setting=%s, actual=%s\n",
408 get_pwr_state(pwr & AC_PWRST_SETTING),
409 get_pwr_state((pwr & AC_PWRST_ACTUAL) >>
410 AC_PWRST_ACTUAL_SHIFT));
411}
412
413static void print_unsol_cap(struct snd_info_buffer *buffer,
414 struct hda_codec *codec, hda_nid_t nid)
415{
416 int unsol = snd_hda_codec_read(codec, nid, 0,
417 AC_VERB_GET_UNSOLICITED_RESPONSE, 0);
418 snd_iprintf(buffer,
419 " Unsolicited: tag=%02x, enabled=%d\n",
420 unsol & AC_UNSOL_TAG,
421 (unsol & AC_UNSOL_ENABLED) ? 1 : 0);
422}
423
424static void print_proc_caps(struct snd_info_buffer *buffer,
425 struct hda_codec *codec, hda_nid_t nid)
426{
427 unsigned int proc_caps = snd_hda_param_read(codec, nid,
428 AC_PAR_PROC_CAP);
429 snd_iprintf(buffer, " Processing caps: benign=%d, ncoeff=%d\n",
430 proc_caps & AC_PCAP_BENIGN,
431 (proc_caps & AC_PCAP_NUM_COEF) >> AC_PCAP_NUM_COEF_SHIFT);
432}
433
434static void print_conn_list(struct snd_info_buffer *buffer,
435 struct hda_codec *codec, hda_nid_t nid,
436 unsigned int wid_type, hda_nid_t *conn,
437 int conn_len)
438{
439 int c, curr = -1;
440
441 if (conn_len > 1 && wid_type != AC_WID_AUD_MIX)
442 curr = snd_hda_codec_read(codec, nid, 0,
443 AC_VERB_GET_CONNECT_SEL, 0);
444 snd_iprintf(buffer, " Connection: %d\n", conn_len);
445 if (conn_len > 0) {
446 snd_iprintf(buffer, " ");
447 for (c = 0; c < conn_len; c++) {
448 snd_iprintf(buffer, " 0x%02x", conn[c]);
449 if (c == curr)
450 snd_iprintf(buffer, "*");
451 }
452 snd_iprintf(buffer, "\n");
453 }
454}
455
456static void print_realtek_coef(struct snd_info_buffer *buffer,
457 struct hda_codec *codec, hda_nid_t nid)
458{
459 int coeff = snd_hda_codec_read(codec, nid, 0,
460 AC_VERB_GET_PROC_COEF, 0);
461 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
462 coeff = snd_hda_codec_read(codec, nid, 0,
463 AC_VERB_GET_COEF_INDEX, 0);
464 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
465}
466
467static void print_gpio(struct snd_info_buffer *buffer,
468 struct hda_codec *codec, hda_nid_t nid)
469{
470 unsigned int gpio =
471 snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP);
472 unsigned int enable, direction, wake, unsol, sticky, data;
473 int i, max;
474 snd_iprintf(buffer, "GPIO: io=%d, o=%d, i=%d, "
475 "unsolicited=%d, wake=%d\n",
476 gpio & AC_GPIO_IO_COUNT,
477 (gpio & AC_GPIO_O_COUNT) >> AC_GPIO_O_COUNT_SHIFT,
478 (gpio & AC_GPIO_I_COUNT) >> AC_GPIO_I_COUNT_SHIFT,
479 (gpio & AC_GPIO_UNSOLICITED) ? 1 : 0,
480 (gpio & AC_GPIO_WAKE) ? 1 : 0);
481 max = gpio & AC_GPIO_IO_COUNT;
482 enable = snd_hda_codec_read(codec, nid, 0,
483 AC_VERB_GET_GPIO_MASK, 0);
484 direction = snd_hda_codec_read(codec, nid, 0,
485 AC_VERB_GET_GPIO_DIRECTION, 0);
486 wake = snd_hda_codec_read(codec, nid, 0,
487 AC_VERB_GET_GPIO_WAKE_MASK, 0);
488 unsol = snd_hda_codec_read(codec, nid, 0,
489 AC_VERB_GET_GPIO_UNSOLICITED_RSP_MASK, 0);
490 sticky = snd_hda_codec_read(codec, nid, 0,
491 AC_VERB_GET_GPIO_STICKY_MASK, 0);
492 data = snd_hda_codec_read(codec, nid, 0,
493 AC_VERB_GET_GPIO_DATA, 0);
494 for (i = 0; i < max; ++i)
495 snd_iprintf(buffer,
496 " IO[%d]: enable=%d, dir=%d, wake=%d, "
497 "sticky=%d, data=%d\n", i,
498 (enable & (1<<i)) ? 1 : 0,
499 (direction & (1<<i)) ? 1 : 0,
500 (wake & (1<<i)) ? 1 : 0,
501 (sticky & (1<<i)) ? 1 : 0,
502 (data & (1<<i)) ? 1 : 0);
503 /* FIXME: add GPO and GPI pin information */
504}
246 505
247static void print_codec_info(struct snd_info_entry *entry, 506static void print_codec_info(struct snd_info_entry *entry,
248 struct snd_info_buffer *buffer) 507 struct snd_info_buffer *buffer)
@@ -280,15 +539,17 @@ static void print_codec_info(struct snd_info_entry *entry,
280 snd_hda_power_down(codec); 539 snd_hda_power_down(codec);
281 return; 540 return;
282 } 541 }
542
543 print_gpio(buffer, codec, codec->afg);
544
283 for (i = 0; i < nodes; i++, nid++) { 545 for (i = 0; i < nodes; i++, nid++) {
284 unsigned int wid_caps = 546 unsigned int wid_caps =
285 snd_hda_param_read(codec, nid, 547 snd_hda_param_read(codec, nid,
286 AC_PAR_AUDIO_WIDGET_CAP); 548 AC_PAR_AUDIO_WIDGET_CAP);
287 unsigned int wid_type = 549 unsigned int wid_type =
288 (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 550 (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
289 int conn_len = 0;
290 hda_nid_t conn[HDA_MAX_CONNECTIONS]; 551 hda_nid_t conn[HDA_MAX_CONNECTIONS];
291 unsigned int pinctls; 552 int conn_len = 0;
292 553
293 snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid, 554 snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid,
294 get_wid_type_name(wid_type), wid_caps); 555 get_wid_type_name(wid_type), wid_caps);
@@ -302,6 +563,10 @@ static void print_codec_info(struct snd_info_entry *entry,
302 snd_iprintf(buffer, " Amp-In"); 563 snd_iprintf(buffer, " Amp-In");
303 if (wid_caps & AC_WCAP_OUT_AMP) 564 if (wid_caps & AC_WCAP_OUT_AMP)
304 snd_iprintf(buffer, " Amp-Out"); 565 snd_iprintf(buffer, " Amp-Out");
566 if (wid_caps & AC_WCAP_STRIPE)
567 snd_iprintf(buffer, " Stripe");
568 if (wid_caps & AC_WCAP_LR_SWAP)
569 snd_iprintf(buffer, " R/L");
305 snd_iprintf(buffer, "\n"); 570 snd_iprintf(buffer, "\n");
306 571
307 /* volume knob is a special widget that always have connection 572 /* volume knob is a special widget that always have connection
@@ -330,33 +595,20 @@ static void print_codec_info(struct snd_info_entry *entry,
330 } 595 }
331 596
332 switch (wid_type) { 597 switch (wid_type) {
333 case AC_WID_PIN: 598 case AC_WID_PIN: {
334 print_pin_caps(buffer, codec, nid); 599 int supports_vref;
335 pinctls = snd_hda_codec_read(codec, nid, 0, 600 print_pin_caps(buffer, codec, nid, &supports_vref);
336 AC_VERB_GET_PIN_WIDGET_CONTROL, 601 print_pin_ctls(buffer, codec, nid, supports_vref);
337 0);
338 snd_iprintf(buffer, " Pin-ctls: 0x%02x:", pinctls);
339 if (pinctls & AC_PINCTL_IN_EN)
340 snd_iprintf(buffer, " IN");
341 if (pinctls & AC_PINCTL_OUT_EN)
342 snd_iprintf(buffer, " OUT");
343 if (pinctls & AC_PINCTL_HP_EN)
344 snd_iprintf(buffer, " HP");
345 snd_iprintf(buffer, "\n");
346 break; 602 break;
603 }
347 case AC_WID_VOL_KNB: 604 case AC_WID_VOL_KNB:
348 pinctls = snd_hda_param_read(codec, nid, 605 print_vol_knob(buffer, codec, nid);
349 AC_PAR_VOL_KNB_CAP);
350 snd_iprintf(buffer, " Volume-Knob: delta=%d, "
351 "steps=%d, ",
352 (pinctls >> 7) & 1, pinctls & 0x7f);
353 pinctls = snd_hda_codec_read(codec, nid, 0,
354 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
355 snd_iprintf(buffer, "direct=%d, val=%d\n",
356 (pinctls >> 7) & 1, pinctls & 0x7f);
357 break; 606 break;
358 case AC_WID_AUD_OUT: 607 case AC_WID_AUD_OUT:
359 case AC_WID_AUD_IN: 608 case AC_WID_AUD_IN:
609 print_audio_io(buffer, codec, nid, wid_type);
610 if (wid_caps & AC_WCAP_DIGITAL)
611 print_digital_conv(buffer, codec, nid);
360 if (wid_caps & AC_WCAP_FORMAT_OVRD) { 612 if (wid_caps & AC_WCAP_FORMAT_OVRD) {
361 snd_iprintf(buffer, " PCM:\n"); 613 snd_iprintf(buffer, " PCM:\n");
362 print_pcm_caps(buffer, codec, nid); 614 print_pcm_caps(buffer, codec, nid);
@@ -364,28 +616,27 @@ static void print_codec_info(struct snd_info_entry *entry,
364 break; 616 break;
365 } 617 }
366 618
619 if (wid_caps & AC_WCAP_UNSOL_CAP)
620 print_unsol_cap(buffer, codec, nid);
621
367 if (wid_caps & AC_WCAP_POWER) 622 if (wid_caps & AC_WCAP_POWER)
368 snd_iprintf(buffer, " Power: 0x%x\n", 623 print_power_state(buffer, codec, nid);
369 snd_hda_codec_read(codec, nid, 0, 624
370 AC_VERB_GET_POWER_STATE, 625 if (wid_caps & AC_WCAP_DELAY)
371 0)); 626 snd_iprintf(buffer, " Delay: %d samples\n",
372 627 (wid_caps & AC_WCAP_DELAY) >>
373 if (wid_caps & AC_WCAP_CONN_LIST) { 628 AC_WCAP_DELAY_SHIFT);
374 int c, curr = -1; 629
375 if (conn_len > 1 && wid_type != AC_WID_AUD_MIX) 630 if (wid_caps & AC_WCAP_CONN_LIST)
376 curr = snd_hda_codec_read(codec, nid, 0, 631 print_conn_list(buffer, codec, nid, wid_type,
377 AC_VERB_GET_CONNECT_SEL, 0); 632 conn, conn_len);
378 snd_iprintf(buffer, " Connection: %d\n", conn_len); 633
379 if (conn_len > 0) { 634 if (wid_caps & AC_WCAP_PROC_WID)
380 snd_iprintf(buffer, " "); 635 print_proc_caps(buffer, codec, nid);
381 for (c = 0; c < conn_len; c++) { 636
382 snd_iprintf(buffer, " 0x%02x", conn[c]); 637 /* NID 0x20 == Realtek Define Registers */
383 if (c == curr) 638 if (codec->vendor_id == 0x10ec && nid == 0x20)
384 snd_iprintf(buffer, "*"); 639 print_realtek_coef(buffer, codec, nid);
385 }
386 snd_iprintf(buffer, "\n");
387 }
388 }
389 } 640 }
390 snd_hda_power_down(codec); 641 snd_hda_power_down(codec);
391} 642}