summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEric Anholt <anholt@FreeBSD.org>2006-06-20 14:32:40 -0700
committerEric Anholt <anholt@FreeBSD.org>2006-06-20 14:32:40 -0700
commitb454c9601f005c69c11556a558150403378d34d9 (patch)
treea3f6d04d1af48f44b2a43290687a70713b6a38ae /src
parent0b76646666e9d330e77c6f81af8b91e34623be92 (diff)
Add support for CRT detection using DDC.
This method is slower (~5ms), but works on older chipsets. Also, load-based detection is disabled, as it can be fooled by other outputs on the pipe being active, such as LVDS.
Diffstat (limited to 'src')
-rw-r--r--src/i830_display.c46
-rw-r--r--src/i830_display.h2
2 files changed, 45 insertions, 3 deletions
diff --git a/src/i830_display.c b/src/i830_display.c
index 6146933d..3a4833e2 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -737,15 +737,57 @@ i830LoadDetectCRT(ScrnInfoPtr pScrn)
return FALSE;
}
+/**
+ * Detects CRT presence by probing for a response on the DDC address.
+ *
+ * This takes approximately 5ms in testing on an i915GM, with CRT connected or
+ * not.
+ */
Bool
-i830DetectCRT(ScrnInfoPtr pScrn)
+i830DDCDetectCRT(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
+ struct _I830OutputRec *output;
+
+ output = &pI830->output[0];
+ /* CRT should always be at 0, but check anyway */
+ if (output->type != I830_OUTPUT_ANALOG)
+ return FALSE;
+
+ return xf86I2CProbeAddress(output->pDDCBus, 0x00A0);
+}
+
+/**
+ * Attempts to detect CRT presence through any method available.
+ *
+ * @param allow_disturb enables detection methods that may cause flickering
+ * on active displays.
+ */
+Bool
+i830DetectCRT(ScrnInfoPtr pScrn, Bool allow_disturb)
+{
+ I830Ptr pI830 = I830PTR(pScrn);
+ Bool found_ddc;
if (IS_I945G(pI830) || IS_I945GM(pI830))
return i830HotplugDetectCRT(pScrn);
- return i830LoadDetectCRT(pScrn);
+ found_ddc = i830DDCDetectCRT(pScrn);
+ if (found_ddc)
+ return TRUE;
+
+ /* Use the load-detect method if we're not currently outputting to the CRT,
+ * or we don't care.
+ *
+ * Actually, the method is unreliable currently. We need to not share a
+ * pipe, as it seems having other outputs on that pipe will result in a
+ * false positive.
+ */
+ if (0 && (allow_disturb || !(INREG(ADPA) & !ADPA_DAC_ENABLE))) {
+ return i830LoadDetectCRT(pScrn);
+ }
+
+ return FALSE;
}
/**
diff --git a/src/i830_display.h b/src/i830_display.h
index aecf8dcd..2e61afce 100644
--- a/src/i830_display.h
+++ b/src/i830_display.h
@@ -27,7 +27,7 @@
/* i830_display.c */
Bool i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode);
-Bool i830DetectCRT(ScrnInfoPtr pScrn);
+Bool i830DetectCRT(ScrnInfoPtr pScrn, Bool allow_disturb);
void i830SetLVDSPanelPower(ScrnInfoPtr pScrn, Bool on);
void i830PipeSetBase(ScrnInfoPtr pScrn, int pipe, int x, int y);