svn commit: r197611 - head/sys/dev/sound/pci/hda

Alexander Motin mav at FreeBSD.org
Tue Sep 29 09:36:39 UTC 2009


Author: mav
Date: Tue Sep 29 09:36:38 2009
New Revision: 197611
URL: http://svn.freebsd.org/changeset/base/197611

Log:
  Add some bits of HDMI/DisplayPort support from later specification updates.
  It may be not enough to make them work, but at least should give some
  information about these beasts.

Modified:
  head/sys/dev/sound/pci/hda/hda_reg.h
  head/sys/dev/sound/pci/hda/hdac.c

Modified: head/sys/dev/sound/pci/hda/hda_reg.h
==============================================================================
--- head/sys/dev/sound/pci/hda/hda_reg.h	Tue Sep 29 08:00:45 2009	(r197610)
+++ head/sys/dev/sound/pci/hda/hda_reg.h	Tue Sep 29 09:36:38 2009	(r197611)
@@ -660,13 +660,49 @@
 #define HDA_CMD_VERB_GET_STRIPE_CONTROL			0xf24
 #define HDA_CMD_VERB_SET_STRIPE_CONTROL			0x724
 
-#define HDA_CMD_SET_STRIPE_CONTROL(cad, nid)				\
+#define HDA_CMD_GET_STRIPE_CONTROL(cad, nid)				\
     (HDA_CMD_12BIT((cad), (nid),					\
     HDA_CMD_VERB_GET_STRIPE_CONTROL, 0x0))
-#define HDA_CMD_GET_STRIPE_CONTROL(cad, nid, payload)			\
+#define HDA_CMD_SET_STRIPE_CONTROL(cad, nid, payload)			\
     (HDA_CMD_12BIT((cad), (nid),					\
     HDA_CMD_VERB_SET_STRIPE_CONTROL, (payload)))
 
+/* Channel Count Control */
+#define HDA_CMD_VERB_GET_CONV_CHAN_COUNT			0xf2d
+#define HDA_CMD_VERB_SET_CONV_CHAN_COUNT			0x72d 
+
+#define HDA_CMD_GET_CONV_CHAN_COUNT(cad, nid)				\
+    (HDA_CMD_12BIT((cad), (nid),					\
+    HDA_CMD_VERB_GET_CONV_CHAN_COUNT, 0x0))
+#define HDA_CMD_SET_CONV_CHAN_COUNT(cad, nid, payload)			\
+    (HDA_CMD_12BIT((cad), (nid),					\
+    HDA_CMD_VERB_SET_CONV_CHAN_COUNT, (payload)))
+
+#define HDA_CMD_VERB_GET_HDMI_DIP_SIZE			0xf2e 
+#define HDA_CMD_VERB_GET_HDMI_ELDD			0xf2f 
+
+#define HDA_CMD_VERB_GET_HDMI_DIP_INDEX			0xf30 
+#define HDA_CMD_VERB_SET_HDMI_DIP_INDEX			0x730 
+
+#define HDA_CMD_VERB_GET_HDMI_DIP_DATA			0xf31 
+#define HDA_CMD_VERB_SET_HDMI_DIP_DATA			0x731 
+
+#define HDA_CMD_VERB_GET_HDMI_DIP_XMIT			0xf32 
+#define HDA_CMD_VERB_SET_HDMI_DIP_XMIT			0x732 
+
+#define HDA_CMD_VERB_GET_HDMI_CP_CTRL			0xf33 
+#define HDA_CMD_VERB_SET_HDMI_CP_CTRL			0x733 
+
+#define HDA_CMD_VERB_GET_HDMI_CHAN_SLOT			0xf34 
+#define HDA_CMD_VERB_SET_HDMI_CHAN_SLOT			0x734 
+
+#define HDA_CMD_GET_HDMI_CHAN_SLOT(cad, nid)				\
+    (HDA_CMD_12BIT((cad), (nid),					\
+    HDA_CMD_VERB_GET_HDMI_CHAN_SLOT, 0x0))
+#define HDA_CMD_SET_HDMI_CHAN_SLOT(cad, nid, payload)			\
+    (HDA_CMD_12BIT((cad), (nid),					\
+    HDA_CMD_VERB_SET_HDMI_CHAN_SLOT, (payload)))
+
 /* Function Reset */
 #define HDA_CMD_VERB_FUNCTION_RESET			0x7ff
 
@@ -779,6 +815,10 @@
 #define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT		20
 #define HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_MASK		0x000f0000
 #define HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_SHIFT		16
+#define HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_MASK		0x0000e000
+#define HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_SHIFT		13
+#define HDA_PARAM_AUDIO_WIDGET_CAP_CP_MASK		0x00001000
+#define HDA_PARAM_AUDIO_WIDGET_CAP_CP_SHIFT		12
 #define HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_MASK		0x00000800
 #define HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_SHIFT	11
 #define HDA_PARAM_AUDIO_WIDGET_CAP_POWER_CTRL_MASK	0x00000400
@@ -810,6 +850,14 @@
 #define HDA_PARAM_AUDIO_WIDGET_CAP_DELAY(param)				\
     (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_MASK) >>		\
     HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_SHIFT)
+#define HDA_PARAM_AUDIO_WIDGET_CAP_CC(param)				\
+    ((((param) & HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_MASK) >>		\
+    (HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_SHIFT - 1)) |			\
+    (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_MASK) >>		\
+    HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_SHIFT))
+#define HDA_PARAM_AUDIO_WIDGET_CAP_CP(param)				\
+    (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_CP_MASK) >>			\
+    HDA_PARAM_AUDIO_WIDGET_CAP_CP_SHIFT)
 #define HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP(param)			\
     (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_MASK) >>		\
     HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_SHIFT)
@@ -971,6 +1019,10 @@
 /* Pin Capabilities */
 #define HDA_PARAM_PIN_CAP				0x0c
 
+#define HDA_PARAM_PIN_CAP_HBR_MASK			0x08000000
+#define HDA_PARAM_PIN_CAP_HBR_SHIFT			27
+#define HDA_PARAM_PIN_CAP_DP_MASK			0x01000000
+#define HDA_PARAM_PIN_CAP_DP_SHIFT			24
 #define HDA_PARAM_PIN_CAP_EAPD_CAP_MASK			0x00010000
 #define HDA_PARAM_PIN_CAP_EAPD_CAP_SHIFT		16
 #define HDA_PARAM_PIN_CAP_VREF_CTRL_MASK		0x0000ff00
@@ -985,6 +1037,8 @@
 #define HDA_PARAM_PIN_CAP_VREF_CTRL_50_SHIFT		9
 #define HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_MASK		0x00000100
 #define HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_SHIFT		8
+#define HDA_PARAM_PIN_CAP_HDMI_MASK			0x00000080
+#define HDA_PARAM_PIN_CAP_HDMI_SHIFT			7
 #define HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_MASK		0x00000040
 #define HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_SHIFT	6
 #define HDA_PARAM_PIN_CAP_INPUT_CAP_MASK		0x00000020
@@ -1000,6 +1054,12 @@
 #define HDA_PARAM_PIN_CAP_IMP_SENSE_CAP_MASK		0x00000001
 #define HDA_PARAM_PIN_CAP_IMP_SENSE_CAP_SHIFT		0
 
+#define HDA_PARAM_PIN_CAP_HBR(param)					\
+    (((param) & HDA_PARAM_PIN_CAP_HBR_MASK) >>				\
+    HDA_PARAM_PIN_CAP_HBR_SHIFT)
+#define HDA_PARAM_PIN_CAP_DP(param)					\
+    (((param) & HDA_PARAM_PIN_CAP_DP_MASK) >>				\
+    HDA_PARAM_PIN_CAP_DP_SHIFT)
 #define HDA_PARAM_PIN_CAP_EAPD_CAP(param)				\
     (((param) & HDA_PARAM_PIN_CAP_EAPD_CAP_MASK) >>			\
     HDA_PARAM_PIN_CAP_EAPD_CAP_SHIFT)
@@ -1021,6 +1081,9 @@
 #define HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ(param)				\
     (((param) & HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_MASK) >>		\
     HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_SHIFT)
+#define HDA_PARAM_PIN_CAP_HDMI(param)					\
+    (((param) & HDA_PARAM_PIN_CAP_HDMI_MASK) >>				\
+    HDA_PARAM_PIN_CAP_HDMI_SHIFT)
 #define HDA_PARAM_PIN_CAP_BALANCED_IO_PINS(param)			\
     (((param) & HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_MASK) >>		\
     HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_SHIFT)

Modified: head/sys/dev/sound/pci/hda/hdac.c
==============================================================================
--- head/sys/dev/sound/pci/hda/hdac.c	Tue Sep 29 08:00:45 2009	(r197610)
+++ head/sys/dev/sound/pci/hda/hdac.c	Tue Sep 29 09:36:38 2009	(r197611)
@@ -38,7 +38,6 @@
  *     2) HDA Codecs support, which may include
  *        - HDA
  *        - Modem
- *        - HDMI
  *     3) Widget parser - the real magic of why this driver works on so
  *        many hardwares with minimal vendor specific quirk. The original
  *        parser was written using Ruby and can be found at
@@ -87,7 +86,7 @@
 
 #include "mixer_if.h"
 
-#define HDA_DRV_TEST_REV	"20090624_0136"
+#define HDA_DRV_TEST_REV	"20090929_0137"
 
 SND_DECLARE_FILE("$FreeBSD$");
 
@@ -3485,6 +3484,14 @@ hdac_stream_setup(struct hdac_chan *ch)
 		}
 		hdac_command(sc,
 		    HDA_CMD_SET_CONV_STREAM_CHAN(cad, ch->io[i], c), cad);
+#if 0
+		hdac_command(sc,
+		    HDA_CMD_SET_CONV_CHAN_COUNT(cad, ch->io[i], 1), cad);
+		hdac_command(sc,
+		    HDA_CMD_SET_HDMI_CHAN_SLOT(cad, ch->io[i], 0x00), cad);
+		hdac_command(sc,
+		    HDA_CMD_SET_HDMI_CHAN_SLOT(cad, ch->io[i], 0x11), cad);
+#endif
 		chn +=
 		    HDA_PARAM_AUDIO_WIDGET_CAP_STEREO(w->param.widget_cap) ?
 		    2 : 1;
@@ -4492,7 +4499,7 @@ hdac_audio_as_parse(struct hdac_devinfo 
 	for (i = 0; i < max; i++) {
 		as[i].hpredir = -1;
 		as[i].chan = -1;
-		as[i].digital = 1;
+		as[i].digital = 0;
 	}
 
 	/* Scan associations skipping as=0. */
@@ -4547,8 +4554,14 @@ hdac_audio_as_parse(struct hdac_devinfo 
 				    __func__, w->nid, j);
 				as[cnt].enable = 0;
 			}
-			if (!HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap))
-				as[cnt].digital = 0;
+			if (HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(w->param.widget_cap)) {
+				if (HDA_PARAM_PIN_CAP_DP(w->wclass.pin.cap))
+					as[cnt].digital = 3;
+				else if (HDA_PARAM_PIN_CAP_HDMI(w->wclass.pin.cap))
+					as[cnt].digital = 2;
+				else
+					as[cnt].digital = 1;
+			}
 			/* Headphones with seq=15 may mean redirection. */
 			if (type == HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT &&
 			    seq == 15)
@@ -6548,15 +6561,15 @@ hdac_create_pcms(struct hdac_devinfo *de
 		devinfo->function.audio.devs[i].devinfo = devinfo;
 		devinfo->function.audio.devs[i].play = -1;
 		devinfo->function.audio.devs[i].rec = -1;
-		devinfo->function.audio.devs[i].digital = 2;
+		devinfo->function.audio.devs[i].digital = 255;
 	}
 	for (i = 0; i < devinfo->function.audio.ascnt; i++) {
 		if (as[i].enable == 0)
 			continue;
 		for (j = 0; j < devinfo->function.audio.num_devs; j++) {
-			if (devinfo->function.audio.devs[j].digital != 2 &&
-			    devinfo->function.audio.devs[j].digital !=
-			    as[i].digital)
+			if (devinfo->function.audio.devs[j].digital != 255 &&
+			    (!devinfo->function.audio.devs[j].digital) ==
+			    (!as[i].digital))
 				continue;
 			if (as[i].dir == HDA_CTL_IN) {
 				if (devinfo->function.audio.devs[j].rec >= 0)
@@ -6732,6 +6745,8 @@ hdac_dump_pin(struct hdac_softc *sc, str
 		printf(" IN");
 	if (HDA_PARAM_PIN_CAP_BALANCED_IO_PINS(pincap))
 		printf(" BAL");
+	if (HDA_PARAM_PIN_CAP_HDMI(pincap))
+		printf(" HDMI");
 	if (HDA_PARAM_PIN_CAP_VREF_CTRL(pincap)) {
 		printf(" VREF[");
 		if (HDA_PARAM_PIN_CAP_VREF_CTRL_50(pincap))
@@ -6748,6 +6763,10 @@ hdac_dump_pin(struct hdac_softc *sc, str
 	}
 	if (HDA_PARAM_PIN_CAP_EAPD_CAP(pincap))
 		printf(" EAPD");
+	if (HDA_PARAM_PIN_CAP_DP(pincap))
+		printf(" DP");
+	if (HDA_PARAM_PIN_CAP_HBR(pincap))
+		printf(" HBR");
 	printf("\n");
 	device_printf(sc->dev, "     Pin config: 0x%08x\n",
 	    w->wclass.pin.config);
@@ -6855,8 +6874,11 @@ hdac_dump_nodes(struct hdac_devinfo *dev
 			    printf(" PROC");
 			if (HDA_PARAM_AUDIO_WIDGET_CAP_STRIPE(w->param.widget_cap))
 			    printf(" STRIPE");
-			if (HDA_PARAM_AUDIO_WIDGET_CAP_STEREO(w->param.widget_cap))
+			j = HDA_PARAM_AUDIO_WIDGET_CAP_CC(w->param.widget_cap);
+			if (j == 1)
 			    printf(" STEREO");
+			else if (j > 1)
+			    printf(" %dCH", j + 1);
 			printf("\n");
 		}
 		if (w->bindas != -1) {
@@ -7957,7 +7979,9 @@ hdac_pcm_probe(device_t dev)
 	snprintf(buf, sizeof(buf), "HDA %s PCM #%d %s",
 	    hdac_codec_name(pdevinfo->devinfo->codec),
 	    pdevinfo->index,
-	    pdevinfo->digital?"Digital":"Analog");
+	    (pdevinfo->digital == 3)?"DisplayPort":
+	    ((pdevinfo->digital == 2)?"HDMI":
+	    ((pdevinfo->digital)?"Digital":"Analog")));
 	device_set_desc_copy(dev, buf);
 	return (0);
 }


More information about the svn-src-all mailing list