summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2009-09-29 09:36:38 +0000
committermav <mav@FreeBSD.org>2009-09-29 09:36:38 +0000
commitc71d3f7c6ea3aec3504aa96c9b97b9510904f4f2 (patch)
tree300b4b3cb8940de3ed378099cea24a0af3eabb16 /sys/dev
parent063c1246e28834af41ec1d0f0a7ece79baee4809 (diff)
downloadFreeBSD-src-c71d3f7c6ea3aec3504aa96c9b97b9510904f4f2.zip
FreeBSD-src-c71d3f7c6ea3aec3504aa96c9b97b9510904f4f2.tar.gz
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.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/sound/pci/hda/hda_reg.h67
-rw-r--r--sys/dev/sound/pci/hda/hdac.c46
2 files changed, 100 insertions, 13 deletions
diff --git a/sys/dev/sound/pci/hda/hda_reg.h b/sys/dev/sound/pci/hda/hda_reg.h
index 3c5757a..0eeea64 100644
--- a/sys/dev/sound/pci/hda/hda_reg.h
+++ b/sys/dev/sound/pci/hda/hda_reg.h
@@ -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)
diff --git a/sys/dev/sound/pci/hda/hdac.c b/sys/dev/sound/pci/hda/hdac.c
index 31988a9..6b95f98 100644
--- a/sys/dev/sound/pci/hda/hdac.c
+++ b/sys/dev/sound/pci/hda/hdac.c
@@ -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 *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 *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 *devinfo)
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, struct hdac_widget *w)
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, struct hdac_widget *w)
}
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 *devinfo)
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);
}
OpenPOWER on IntegriCloud