diff options
author | Zhenyu Wang <zhenyu.z.wang@intel.com> | 2008-09-19 15:20:55 +0800 |
---|---|---|
committer | Zhenyu Wang <zhenyu.z.wang@intel.com> | 2008-09-19 15:20:55 +0800 |
commit | 2f93cfbc7e96acc32efb5e1ca49b817a81cba6e3 (patch) | |
tree | 92183ce31054f54578156b939c8332acf126dbf9 | |
parent | 1fbe4d602816c9dfc5fba917b9fdc257d8d025b0 (diff) |
Fix output detection for DVI-I
For CRT this trys to probe all possible port for EDID and
detects got confirmed by EDID's d/a type bit.
For HDMI/DVI, also using EDID d/a type bit to ensure it should
handle the connect or not.
-rw-r--r-- | src/i830_crt.c | 45 | ||||
-rw-r--r-- | src/i830_hdmi.c | 10 |
2 files changed, 53 insertions, 2 deletions
diff --git a/src/i830_crt.c b/src/i830_crt.c index 8274c0cc..5812e2b7 100644 --- a/src/i830_crt.c +++ b/src/i830_crt.c @@ -410,6 +410,49 @@ i830_crt_get_crtc(xf86OutputPtr output) } #endif +static xf86MonPtr +i830_get_edid(xf86OutputPtr output, int gpio_reg, char *gpio_str) +{ + I830OutputPrivatePtr intel_output = output->driver_private; + xf86MonPtr edid_mon = NULL; + + /* Set up the DDC bus. */ + if (gpio_reg != GPIOA) + I830I2CInit(output->scrn, &intel_output->pDDCBus, gpio_reg, gpio_str); + + edid_mon = xf86OutputGetEDID (output, intel_output->pDDCBus); + + if (!edid_mon || DIGITAL(edid_mon->features.input_type)) { + xf86DestroyI2CBusRec(intel_output->pDDCBus, TRUE, TRUE); + if (edid_mon) { + xfree(edid_mon); + edid_mon = NULL; + } + } + return edid_mon; +} + +static DisplayModePtr +i830_crt_get_modes (xf86OutputPtr output) +{ + DisplayModePtr modes; + xf86MonPtr edid_mon = NULL; + + /* Try to probe normal CRT port, and also digital port for output + in DVI-I mode. */ + if ((edid_mon = i830_get_edid(output, GPIOA, "CRTDDC_A"))) + goto found; + if ((edid_mon = i830_get_edid(output, GPIOD, "CRTDDC_D"))) + goto found; + if ((edid_mon = i830_get_edid(output, GPIOE, "CRTDDC_E"))) + goto found; +found: + xf86OutputSetEDID (output, edid_mon); + + modes = xf86OutputGetEDIDModes (output); + return modes; +} + static const xf86OutputFuncsRec i830_crt_output_funcs = { .dpms = i830_crt_dpms, .save = i830_crt_save, @@ -420,7 +463,7 @@ static const xf86OutputFuncsRec i830_crt_output_funcs = { .mode_set = i830_crt_mode_set, .commit = i830_output_commit, .detect = i830_crt_detect, - .get_modes = i830_ddc_get_modes, + .get_modes = i830_crt_get_modes, .destroy = i830_crt_destroy, #ifdef RANDR_GET_CRTC_INTERFACE .get_crtc = i830_crt_get_crtc, diff --git a/src/i830_hdmi.c b/src/i830_hdmi.c index d56eec90..44e5c056 100644 --- a/src/i830_hdmi.c +++ b/src/i830_hdmi.c @@ -139,6 +139,8 @@ i830_hdmi_detect(xf86OutputPtr output) struct i830_hdmi_priv *dev_priv = intel_output->dev_priv; I830Ptr pI830 = I830PTR(pScrn); uint32_t temp, bit; + xf86OutputStatus status; + xf86MonPtr edid_mon; /* For G4X, PEG_BAND_GAP_DATA 3:0 must first be written 0xd. * Failure to do so will result in spurious interrupts being @@ -171,9 +173,15 @@ i830_hdmi_detect(xf86OutputPtr output) } if ((INREG(PORT_HOTPLUG_STAT) & bit) != 0) - return XF86OutputStatusConnected; + status = XF86OutputStatusConnected; else return XF86OutputStatusDisconnected; + + edid_mon = xf86OutputGetEDID (output, intel_output->pDDCBus); + if (!edid_mon || !DIGITAL(edid_mon->features.input_type)) + status = XF86OutputStatusDisconnected; + xfree(edid_mon); + return status; } static void |