Skip to contentSkip to conversation

hda_proc - Add output of Vref, additional pcaps, and proccaps to proc output

PATCH In review Andrew Paprocki 3 participants 6 messages Jan 17, 2008 – Jan 18, 2008

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 hda_proc - Add output of Vref, additional pcaps, and proccaps to proc output

This adds additional pincaps which were not previously output. Also, Vref capabilities are output per-pin along with the current Vref pinctl setting if the NID supports Vref. Also added: processing widgets and proccaps, as well as processing coefficient and coefficient index from the Realtek Define Registers per the ALC883 datasheet.

pci/hda/hda_proc.c +80 -4
diff -r 1e5c4ccf093c -r 8a9218bae32f pci/hda/hda_proc.c
@@ -202,7 +202,8 @@ static const char *get_jack_color(u32 cf
 }
 
 static void print_pin_caps(struct snd_info_buffer *buffer,
-			   struct hda_codec *codec, hda_nid_t nid)
+                           struct hda_codec *codec, hda_nid_t nid,
+                           int *supports_vref)
 {
 	static char *jack_conns[4] = { "Jack", "N/A", "Fixed", "Both" };
 	static char *jack_types[16] = {
@@ -226,7 +227,35 @@ static void print_pin_caps(struct snd_in
 		snd_iprintf(buffer, " EAPD");
 	if (caps & AC_PINCAP_PRES_DETECT)
 		snd_iprintf(buffer, " Detect");
-	snd_iprintf(buffer, "\n");
+        if (caps & AC_PINCAP_BALANCE)
+                snd_iprintf(buffer, " Balanced");
+        if (caps & AC_PINCAP_LR_SWAP)
+                snd_iprintf(buffer, " R/L");
+        if (caps & AC_PINCAP_TRIG_REQ)
+                snd_iprintf(buffer, " Trigger");
+        if (caps & AC_PINCAP_IMP_SENSE)
+                snd_iprintf(buffer, " ImpSense");
+	snd_iprintf(buffer, "\n");
+        if (caps & AC_PINCAP_VREF) {
+                unsigned int vref =
+                        (caps & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
+                snd_iprintf(buffer, "    Vref:");
+                if (vref & AC_PINCAP_VREF_HIZ)
+                        snd_iprintf(buffer, " HIZ");
+                if (vref & AC_PINCAP_VREF_50)
+                        snd_iprintf(buffer, " 50");
+                if (vref & AC_PINCAP_VREF_GRD)
+                        snd_iprintf(buffer, " GRD");
+                if (vref & AC_PINCAP_VREF_80)
+                        snd_iprintf(buffer, " 80");
+                if (vref & AC_PINCAP_VREF_100)
+                        snd_iprintf(buffer, " 100");
+                snd_iprintf(buffer, "\n");
+                *supports_vref = 1;
+        }
+        else {
+                *supports_vref = 0;
+        }
 	caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
 	snd_iprintf(buffer, "  Pin Default 0x%08x: [%s] %s at %s %s\n", caps,
 		    jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT],
@@ -330,8 +359,9 @@ static void print_codec_info(struct snd_
 		}
 
 		switch (wid_type) {
-		case AC_WID_PIN:
-			print_pin_caps(buffer, codec, nid);
+		case AC_WID_PIN: {
+                        int supports_vref;
+			print_pin_caps(buffer, codec, nid, &supports_vref);
 			pinctls = snd_hda_codec_read(codec, nid, 0,
 					     AC_VERB_GET_PIN_WIDGET_CONTROL,
 						     0);
@@ -342,8 +372,29 @@ static void print_codec_info(struct snd_
 				snd_iprintf(buffer, " OUT");
 			if (pinctls & AC_PINCTL_HP_EN)
 				snd_iprintf(buffer, " HP");
+                        if (supports_vref) {
+                                int vref = pinctls & AC_PINCTL_VREFEN;
+                                switch (vref) {
+                                case AC_PINCTL_VREF_HIZ:
+                                        snd_iprintf(buffer, " VREF_HIZ");
+                                        break;
+                                case AC_PINCTL_VREF_50:
+                                        snd_iprintf(buffer, " VREF_50");
+                                        break;
+                                case AC_PINCTL_VREF_GRD:
+                                        snd_iprintf(buffer, " VREF_GRD");
+                                        break;
+                                case AC_PINCTL_VREF_80:
+                                        snd_iprintf(buffer, " VREF_80");
+                                        break;
+                                case AC_PINCTL_VREF_100:
+                                        snd_iprintf(buffer, " VREF_100");
+                                        break;
+                                }
+                        }
 			snd_iprintf(buffer, "\n");
 			break;
+                }
 		case AC_WID_VOL_KNB:
 			pinctls = snd_hda_param_read(codec, nid,
 						     AC_PAR_VOL_KNB_CAP);
@@ -386,6 +437,31 @@ static void print_codec_info(struct snd_
 				snd_iprintf(buffer, "\n");
 			}
 		}
+
+                if (wid_caps & AC_WCAP_PROC_WID) {
+                        unsigned int proc_caps =
+                                snd_hda_param_read(codec, nid,
+                                                   AC_PAR_PROC_CAP);
+                        snd_iprintf(buffer,
+                                    "  Processing Caps: benign=%d ncoeff=%d\n",
+                                    proc_caps & AC_PCAP_BENIGN,
+                                    (proc_caps & AC_PCAP_NUM_COEF) >>
+                                    AC_PCAP_NUM_COEF_SHIFT);
+                }
+
+                /* NID 0x20 == Realtek Define Registers */
+                if (codec->vendor_id == 0x10ec && nid == 0x20) {
+                        int coeff =
+                                snd_hda_codec_read(codec, nid, 0,
+                                                   AC_VERB_GET_PROC_COEF, 0);
+                        snd_iprintf(buffer,
+                                    "  Processing Coefficient: 0x%02x\n",
+                                    coeff);
+                        coeff = snd_hda_codec_read(codec, nid, 0,
+                                                   AC_VERB_GET_COEF_INDEX, 0);
+                        snd_iprintf(buffer,
+                                    "  Coefficient Index: 0x%02x\n", coeff);
+                }
 	}
 	snd_hda_power_down(codec);
 }
#1 lore raw

At Thu, 17 Jan 2008 09:46:06 -0400,

Quoted 8 lines · Andrew Paprocki

This adds additional pincaps which were not previously output. Also, Vref capabilities are output per-pin along with the current Vref pinctl setting if the NID supports Vref. Also added: processing widgets and proccaps, as well as processing coefficient and coefficient index from the Realtek Define Registers per the ALC883 datasheet.

Did you check whether this doesn't break Claudio's codecgraph parser? If it's OK, I'd like to apply it, of course...

Takashi

Quoted 125 lines

diff -r 1e5c4ccf093c -r 8a9218bae32f pci/hda/hda_proc.c

pci/hda/hda_proc.c +80 -4
@@ -202,7 +202,8 @@ static const char *get_jack_color(u32 cf
 }
 
 static void print_pin_caps(struct snd_info_buffer *buffer,
-			   struct hda_codec *codec, hda_nid_t nid)
+                           struct hda_codec *codec, hda_nid_t nid,
+                           int *supports_vref)
 {
 	static char *jack_conns[4] = { "Jack", "N/A", "Fixed", "Both" };
 	static char *jack_types[16] = {
@@ -226,7 +227,35 @@ static void print_pin_caps(struct snd_in
 		snd_iprintf(buffer, " EAPD");
 	if (caps & AC_PINCAP_PRES_DETECT)
 		snd_iprintf(buffer, " Detect");
-	snd_iprintf(buffer, "\n");
+        if (caps & AC_PINCAP_BALANCE)
+                snd_iprintf(buffer, " Balanced");
+        if (caps & AC_PINCAP_LR_SWAP)
+                snd_iprintf(buffer, " R/L");
+        if (caps & AC_PINCAP_TRIG_REQ)
+                snd_iprintf(buffer, " Trigger");
+        if (caps & AC_PINCAP_IMP_SENSE)
+                snd_iprintf(buffer, " ImpSense");
+	snd_iprintf(buffer, "\n");
+        if (caps & AC_PINCAP_VREF) {
+                unsigned int vref =
+                        (caps & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
+                snd_iprintf(buffer, "    Vref:");
+                if (vref & AC_PINCAP_VREF_HIZ)
+                        snd_iprintf(buffer, " HIZ");
+                if (vref & AC_PINCAP_VREF_50)
+                        snd_iprintf(buffer, " 50");
+                if (vref & AC_PINCAP_VREF_GRD)
+                        snd_iprintf(buffer, " GRD");
+                if (vref & AC_PINCAP_VREF_80)
+                        snd_iprintf(buffer, " 80");
+                if (vref & AC_PINCAP_VREF_100)
+                        snd_iprintf(buffer, " 100");
+                snd_iprintf(buffer, "\n");
+                *supports_vref = 1;
+        }
+        else {
+                *supports_vref = 0;
+        }
 	caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
 	snd_iprintf(buffer, "  Pin Default 0x%08x: [%s] %s at %s %s\n", caps,
 		    jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT],
@@ -330,8 +359,9 @@ static void print_codec_info(struct snd_
 		}
 
 		switch (wid_type) {
-		case AC_WID_PIN:
-			print_pin_caps(buffer, codec, nid);
+		case AC_WID_PIN: {
+                        int supports_vref;
+			print_pin_caps(buffer, codec, nid, &supports_vref);
 			pinctls = snd_hda_codec_read(codec, nid, 0,
 					     AC_VERB_GET_PIN_WIDGET_CONTROL,
 						     0);
@@ -342,8 +372,29 @@ static void print_codec_info(struct snd_
 				snd_iprintf(buffer, " OUT");
 			if (pinctls & AC_PINCTL_HP_EN)
 				snd_iprintf(buffer, " HP");
+                        if (supports_vref) {
+                                int vref = pinctls & AC_PINCTL_VREFEN;
+                                switch (vref) {
+                                case AC_PINCTL_VREF_HIZ:
+                                        snd_iprintf(buffer, " VREF_HIZ");
+                                        break;
+                                case AC_PINCTL_VREF_50:
+                                        snd_iprintf(buffer, " VREF_50");
+                                        break;
+                                case AC_PINCTL_VREF_GRD:
+                                        snd_iprintf(buffer, " VREF_GRD");
+                                        break;
+                                case AC_PINCTL_VREF_80:
+                                        snd_iprintf(buffer, " VREF_80");
+                                        break;
+                                case AC_PINCTL_VREF_100:
+                                        snd_iprintf(buffer, " VREF_100");
+                                        break;
+                                }
+                        }
 			snd_iprintf(buffer, "\n");
 			break;
+                }
 		case AC_WID_VOL_KNB:
 			pinctls = snd_hda_param_read(codec, nid,
 						     AC_PAR_VOL_KNB_CAP);
@@ -386,6 +437,31 @@ static void print_codec_info(struct snd_
 				snd_iprintf(buffer, "\n");
 			}
 		}
+
+                if (wid_caps & AC_WCAP_PROC_WID) {
+                        unsigned int proc_caps =
+                                snd_hda_param_read(codec, nid,
+                                                   AC_PAR_PROC_CAP);
+                        snd_iprintf(buffer,
+                                    "  Processing Caps: benign=%d ncoeff=%d\n",
+                                    proc_caps & AC_PCAP_BENIGN,
+                                    (proc_caps & AC_PCAP_NUM_COEF) >>
+                                    AC_PCAP_NUM_COEF_SHIFT);
+                }
+
+                /* NID 0x20 == Realtek Define Registers */
+                if (codec->vendor_id == 0x10ec && nid == 0x20) {
+                        int coeff =
+                                snd_hda_codec_read(codec, nid, 0,
+                                                   AC_VERB_GET_PROC_COEF, 0);
+                        snd_iprintf(buffer,
+                                    "  Processing Coefficient: 0x%02x\n",
+                                    coeff);
+                        coeff = snd_hda_codec_read(codec, nid, 0,
+                                                   AC_VERB_GET_COEF_INDEX, 0);
+                        snd_iprintf(buffer,
+                                    "  Coefficient Index: 0x%02x\n", coeff);
+                }
 	}
 	snd_hda_power_down(codec);
 }
#2 lore raw
Quoted 9 lines · Takashi Iwai

At Thu, 17 Jan 2008 09:46:06 -0400,

Quoted 7 lines · Andrew Paprocki

This adds additional pincaps which were not previously output. Also, Vref capabilities are output per-pin along with the current Vref pinctl setting if the NID supports Vref. Also added: processing widgets and proccaps, as well as processing coefficient and coefficient index from the Realtek Define Registers per the ALC883 datasheet.

Quoted 7 lines
Quoted 1 line

Did you check whether this doesn't break Claudio's codecgraph parser? If it's OK, I'd like to apply it, of course...

Takashi

You're kidding, right? Adding more details about a codec is more useful at this point than making sure a non-essential script (that can be easily modified) isn't broken.

What I want to know is if we can add even more to /proc, like EAPD status (not just capabilities), jack sense, etc. These are useful bits of information, not only for driver development, but also could be useful for userspace tools that can monitor these. Imagine having your system auto adjust from 5.1 surround settings to optimal headphone settings (not just automute) when you plug in your headphones.

Tobin

Quoted 130 lines
Quoted 116 lines

diff -r 1e5c4ccf093c -r 8a9218bae32f pci/hda/hda_proc.c

pci/hda/hda_proc.c +73 -4
@@ -202,7 +202,8 @@ static const char *get_jack_color(u32 cf
 }
 
 static void print_pin_caps(struct snd_info_buffer *buffer,
-			   struct hda_codec *codec, hda_nid_t nid)
+                           struct hda_codec *codec, hda_nid_t nid,
+                           int *supports_vref)
 {
 	static char *jack_conns[4] = { "Jack", "N/A", "Fixed", "Both" };
 	static char *jack_types[16] = {
@@ -226,7 +227,35 @@ static void print_pin_caps(struct snd_in
 		snd_iprintf(buffer, " EAPD");
 	if (caps & AC_PINCAP_PRES_DETECT)
 		snd_iprintf(buffer, " Detect");
-	snd_iprintf(buffer, "\n");
+        if (caps & AC_PINCAP_BALANCE)
+                snd_iprintf(buffer, " Balanced");
+        if (caps & AC_PINCAP_LR_SWAP)
+                snd_iprintf(buffer, " R/L");
+        if (caps & AC_PINCAP_TRIG_REQ)
+                snd_iprintf(buffer, " Trigger");
+        if (caps & AC_PINCAP_IMP_SENSE)
+                snd_iprintf(buffer, " ImpSense");
+	snd_iprintf(buffer, "\n");
+        if (caps & AC_PINCAP_VREF) {
+                unsigned int vref =
+                        (caps & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
+                snd_iprintf(buffer, "    Vref:");
+                if (vref & AC_PINCAP_VREF_HIZ)
+                        snd_iprintf(buffer, " HIZ");
+                if (vref & AC_PINCAP_VREF_50)
+                        snd_iprintf(buffer, " 50");
+                if (vref & AC_PINCAP_VREF_GRD)
+                        snd_iprintf(buffer, " GRD");
+                if (vref & AC_PINCAP_VREF_80)
+                        snd_iprintf(buffer, " 80");
+                if (vref & AC_PINCAP_VREF_100)
+                        snd_iprintf(buffer, " 100");
+                snd_iprintf(buffer, "\n");
+                *supports_vref = 1;
+        }
+        else {
+                *supports_vref = 0;
+        }
 	caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
 	snd_iprintf(buffer, "  Pin Default 0x%08x: [%s] %s at %s %s\n", caps,
 		    jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT],
@@ -330,8 +359,9 @@ static void print_codec_info(struct snd_
 		}
 
 		switch (wid_type) {
-		case AC_WID_PIN:
-			print_pin_caps(buffer, codec, nid);
+		case AC_WID_PIN: {
+                        int supports_vref;
+			print_pin_caps(buffer, codec, nid, &supports_vref);
 			pinctls = snd_hda_codec_read(codec, nid, 0,
 					     AC_VERB_GET_PIN_WIDGET_CONTROL,
 						     0);
@@ -342,8 +372,29 @@ static void print_codec_info(struct snd_
 				snd_iprintf(buffer, " OUT");
 			if (pinctls & AC_PINCTL_HP_EN)
 				snd_iprintf(buffer, " HP");
+                        if (supports_vref) {
+                                int vref = pinctls & AC_PINCTL_VREFEN;
+                                switch (vref) {
+                                case AC_PINCTL_VREF_HIZ:
+                                        snd_iprintf(buffer, " VREF_HIZ");
+                                        break;
+                                case AC_PINCTL_VREF_50:
+                                        snd_iprintf(buffer, " VREF_50");
+                                        break;
+                                case AC_PINCTL_VREF_GRD:
+                                        snd_iprintf(buffer, " VREF_GRD");
+                                        break;
+                                case AC_PINCTL_VREF_80:
+                                        snd_iprintf(buffer, " VREF_80");
+                                        break;
+                                case AC_PINCTL_VREF_100:
+                                        snd_iprintf(buffer, " VREF_100");
+                                        break;
+                                }
+                        }
 			snd_iprintf(buffer, "\n");
 			break;
+                }
 		case AC_WID_VOL_KNB:
 			pinctls = snd_hda_param_read(codec, nid,
 						     AC_PAR_VOL_KNB_CAP);
@@ -386,6 +437,31 @@ static void print_codec_info(struct snd_
 				snd_iprintf(buffer, "\n");
 			}
 		}
+
+                if (wid_caps & AC_WCAP_PROC_WID) {
+                        unsigned int proc_caps =
+                                snd_hda_param_read(codec, nid,
+                                                   AC_PAR_PROC_CAP);
+                        snd_iprintf(buffer,
+                                    "  Processing Caps: benign=%d ncoeff=%d\n",
+                                    proc_caps & AC_PCAP_BENIGN,
+                                    (proc_caps & AC_PCAP_NUM_COEF) >>
+                                    AC_PCAP_NUM_COEF_SHIFT);
+                }
+
+                /* NID 0x20 == Realtek Define Registers */
+                if (codec->vendor_id == 0x10ec && nid == 0x20) {
+                        int coeff =
+                                snd_hda_codec_read(codec, nid, 0,
+                                                   AC_VERB_GET_PROC_COEF, 0);
+                        snd_iprintf(buffer,

pci/hda/hda_proc.c static void print_codec_info(struct snd_ · line 467

Quoted 10 lines
pci/hda/hda_proc.c +7 -0
+                                    "  Processing Coefficient: 0x%02x\n",
+                                    coeff);
+                        coeff = snd_hda_codec_read(codec, nid, 0,
+                                                   AC_VERB_GET_COEF_INDEX, 0);
+                        snd_iprintf(buffer,
+                                    "  Coefficient Index: 0x%02x\n", coeff);
+                }
 	}
 	snd_hda_power_down(codec);
 }

_______________________________________________
Alsa-devel mailing list
[email protected]
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

Signature · 5 lines
Tobin Davis  


If they're just accessories, how come we want them so badly? 
	-- Murphy's Law of Accessories
#3 lore raw

At Thu, 17 Jan 2008 09:11:00 -0800,

Quoted 14 lines · Tobin Davis

On Thu, 2008-01-17 at 17:58 +0100, Takashi Iwai wrote:

At Thu, 17 Jan 2008 09:46:06 -0400,
Andrew Paprocki wrote:
>
> This adds additional pincaps which were not previously output. Also, Vref > capabilities are output per-pin along with the current Vref pinctl setting > if the NID supports Vref. Also added: processing widgets and proccaps, as > well as processing coefficient and coefficient index from the Realtek Define > Registers per the ALC883 datasheet.
>
> Signed-off-by: Andrew Paprocki <[email protected]>

Quoted 8 lines

Did you check whether this doesn't break Claudio's codecgraph parser? If it's OK, I'd like to apply it, of course...

Takashi

You're kidding, right? Adding more details about a codec is more useful at this point than making sure a non-essential script (that can be easily modified) isn't broken.

Well, now we have some parser program, then it's the high time to think about the proc output consistent in a certain level. So far, it's just written to be readable for human being. But, now we'd need to make it also easily readable by dumb programs, too.

Quoted 6 lines

What I want to know is if we can add even more to /proc, like EAPD status (not just capabilities), jack sense, etc. These are useful bits of information, not only for driver development, but also could be useful for userspace tools that can monitor these. Imagine having your system auto adjust from 5.1 surround settings to optimal headphone settings (not just automute) when you plug in your headphones.

The jack-sense is a bit problem. I once had a laptop that causes codec errors when issuing a jack-sense command without unsolicited events. So, I'd say, let's be as conservative as possible for the proc.

Moreover, we can read any commands via hwdep ioctl easily now...

Takashi

#4 lore raw

I should have known this would happen since the graph tool was just announced! :) I would gladly help keep the tool up to date, but I think Claudio is fine with handling it right now:

Quoted 2 lines

Change the format as needed, as long as it is unambiguous and contains all the necessary information we'll keep the tool up to date.

If/when the tool is merged into the alsa tree, it would make more sense for anyone submitting a patch to /proc output to verify and patch the tool if needed.

If anything needs modification for easier parsing by the tool, it is very easy to do and I'm willing to help. I would apply this (and any future /proc enhancements) and if Claudio's tool can be made simpler by changing the output format, it should be requested and anyone can help make the patch.

Thanks,
-Andrew

Quoted 29 lines · Takashi Iwai

At Thu, 17 Jan 2008 09:11:00 -0800,

Quoted 14 lines · Tobin Davis

On Thu, 2008-01-17 at 17:58 +0100, Takashi Iwai wrote:

At Thu, 17 Jan 2008 09:46:06 -0400,
Andrew Paprocki wrote:
>
> This adds additional pincaps which were not previously output. Also, Vref > capabilities are output per-pin along with the current Vref pinctl setting > if the NID supports Vref. Also added: processing widgets and proccaps, as > well as processing coefficient and coefficient index from the Realtek Define > Registers per the ALC883 datasheet.
>
> Signed-off-by: Andrew Paprocki <[email protected]>

Quoted 8 lines

Did you check whether this doesn't break Claudio's codecgraph parser? If it's OK, I'd like to apply it, of course...

Takashi

You're kidding, right? Adding more details about a codec is more useful at this point than making sure a non-essential script (that can be easily modified) isn't broken.

Well, now we have some parser program, then it's the high time to think about the proc output consistent in a certain level. So far, it's just written to be readable for human being. But, now we'd need to make it also easily readable by dumb programs, too.

#5 lore raw
In reply to Takashi Iwai

Takashi,

I just realized I did something silly and didn't send you all the changes in this patch. I'm adding some more useful stuff to the proc output and I'll send another patch shortly which contains all the changes. This one can be disregarded for now.

Thanks,
-Andrew

Quoted 146 lines · Takashi Iwai

At Thu, 17 Jan 2008 09:46:06 -0400,

Quoted 8 lines · Andrew Paprocki

This adds additional pincaps which were not previously output. Also, Vref capabilities are output per-pin along with the current Vref pinctl setting if the NID supports Vref. Also added: processing widgets and proccaps, as well as processing coefficient and coefficient index from the Realtek Define Registers per the ALC883 datasheet.

Did you check whether this doesn't break Claudio's codecgraph parser? If it's OK, I'd like to apply it, of course...

Takashi

Quoted 125 lines

diff -r 1e5c4ccf093c -r 8a9218bae32f pci/hda/hda_proc.c

pci/hda/hda_proc.c Thu Jan 17 09:44:07 2008 -0500 renamed from pci/hda/hda_proc.c Sun Jan 13 12:03:53 2008 +0100 +80 -4
@@ -202,7 +202,8 @@ static const char *get_jack_color(u32 cf
 }
 
 static void print_pin_caps(struct snd_info_buffer *buffer,
-                        struct hda_codec *codec, hda_nid_t nid)
+                           struct hda_codec *codec, hda_nid_t nid,
+                           int *supports_vref)
 {
      static char *jack_conns[4] = { "Jack", "N/A", "Fixed", "Both" };
      static char *jack_types[16] = {
@@ -226,7 +227,35 @@ static void print_pin_caps(struct snd_in
              snd_iprintf(buffer, " EAPD");
      if (caps & AC_PINCAP_PRES_DETECT)
              snd_iprintf(buffer, " Detect");
-     snd_iprintf(buffer, "\n");
+        if (caps & AC_PINCAP_BALANCE)
+                snd_iprintf(buffer, " Balanced");
+        if (caps & AC_PINCAP_LR_SWAP)
+                snd_iprintf(buffer, " R/L");
+        if (caps & AC_PINCAP_TRIG_REQ)
+                snd_iprintf(buffer, " Trigger");
+        if (caps & AC_PINCAP_IMP_SENSE)
+                snd_iprintf(buffer, " ImpSense");
+     snd_iprintf(buffer, "\n");
+        if (caps & AC_PINCAP_VREF) {
+                unsigned int vref =
+                        (caps & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
+                snd_iprintf(buffer, "    Vref:");
+                if (vref & AC_PINCAP_VREF_HIZ)
+                        snd_iprintf(buffer, " HIZ");
+                if (vref & AC_PINCAP_VREF_50)
+                        snd_iprintf(buffer, " 50");
+                if (vref & AC_PINCAP_VREF_GRD)
+                        snd_iprintf(buffer, " GRD");
+                if (vref & AC_PINCAP_VREF_80)
+                        snd_iprintf(buffer, " 80");
+                if (vref & AC_PINCAP_VREF_100)
+                        snd_iprintf(buffer, " 100");
+                snd_iprintf(buffer, "\n");
+                *supports_vref = 1;
+        }
+        else {
+                *supports_vref = 0;
+        }
      caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
      snd_iprintf(buffer, "  Pin Default 0x%08x: [%s] %s at %s %s\n", caps,
                  jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT],
@@ -330,8 +359,9 @@ static void print_codec_info(struct snd_
              }
 
              switch (wid_type) {
-             case AC_WID_PIN:
-                     print_pin_caps(buffer, codec, nid);
+             case AC_WID_PIN: {
+                        int supports_vref;
+                     print_pin_caps(buffer, codec, nid, &supports_vref);
                      pinctls = snd_hda_codec_read(codec, nid, 0,
                                           AC_VERB_GET_PIN_WIDGET_CONTROL,
                                                   0);
@@ -342,8 +372,29 @@ static void print_codec_info(struct snd_
                              snd_iprintf(buffer, " OUT");
                      if (pinctls & AC_PINCTL_HP_EN)
                              snd_iprintf(buffer, " HP");
+                        if (supports_vref) {
+                                int vref = pinctls & AC_PINCTL_VREFEN;
+                                switch (vref) {
+                                case AC_PINCTL_VREF_HIZ:
+                                        snd_iprintf(buffer, " VREF_HIZ");
+                                        break;
+                                case AC_PINCTL_VREF_50:
+                                        snd_iprintf(buffer, " VREF_50");
+                                        break;
+                                case AC_PINCTL_VREF_GRD:
+                                        snd_iprintf(buffer, " VREF_GRD");
+                                        break;
+                                case AC_PINCTL_VREF_80:
+                                        snd_iprintf(buffer, " VREF_80");
+                                        break;
+                                case AC_PINCTL_VREF_100:
+                                        snd_iprintf(buffer, " VREF_100");
+                                        break;
+                                }
+                        }
                      snd_iprintf(buffer, "\n");
                      break;
+                }
              case AC_WID_VOL_KNB:
                      pinctls = snd_hda_param_read(codec, nid,
                                                   AC_PAR_VOL_KNB_CAP);
@@ -386,6 +437,31 @@ static void print_codec_info(struct snd_
                              snd_iprintf(buffer, "\n");
                      }
              }
+
+                if (wid_caps & AC_WCAP_PROC_WID) {
+                        unsigned int proc_caps =
+                                snd_hda_param_read(codec, nid,
+                                                   AC_PAR_PROC_CAP);
+                        snd_iprintf(buffer,
+                                    "  Processing Caps: benign=%d ncoeff=%d\n",
+                                    proc_caps & AC_PCAP_BENIGN,
+                                    (proc_caps & AC_PCAP_NUM_COEF) >>
+                                    AC_PCAP_NUM_COEF_SHIFT);
+                }
+
+                /* NID 0x20 == Realtek Define Registers */
+                if (codec->vendor_id == 0x10ec && nid == 0x20) {
+                        int coeff =
+                                snd_hda_codec_read(codec, nid, 0,
+                                                   AC_VERB_GET_PROC_COEF, 0);
+                        snd_iprintf(buffer,
+                                    "  Processing Coefficient: 0x%02x\n",
+                                    coeff);
+                        coeff = snd_hda_codec_read(codec, nid, 0,
+                                                   AC_VERB_GET_COEF_INDEX, 0);
+                        snd_iprintf(buffer,
+                                    "  Coefficient Index: 0x%02x\n", coeff);
+                }
      }
      snd_hda_power_down(codec);
 }