Subject: [PATCH] drm/i915: Fetch EDID for SDVO output on Mac machine. Because Mac machine has only one port, which can connect VGA, DVI or TV by adapter, share ddc bus(GPIOA), in sdvo get modes function we need to check VGA, and steal the ddc bus, then return after operaton. This is actually a sync with UMS Signed-off-by: Ma Ling --- drivers/gpu/drm/i915/intel_sdvo.c | 53 ++++++++++++++++++++++++++---------- 1 files changed, 38 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 4f0c309..9da5a6b 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1475,31 +1475,54 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) { struct intel_output *intel_output = to_intel_output(connector); + struct drm_connector *vgaconn; + struct i2c_adapter *ddcbus; + int ret; /* set the bus switch and get the modes */ - intel_ddc_get_modes(intel_output); + ret = intel_ddc_get_modes(intel_output); + + if (ret) + return; -#if 0 - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; /* Mac mini hack. On this device, I get DDC through the analog, which * load-detects as disconnected. I fail to DDC through the SDVO DDC, * but it does load-detect as connected. So, just steal the DDC bits * from analog when we fail at finding it the right way. */ - crt = xf86_config->output[0]; - intel_output = crt->driver_private; - if (intel_output->type == I830_OUTPUT_ANALOG && - crt->funcs->detect(crt) == XF86OutputStatusDisconnected) { - I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOA, "CRTDDC_A"); - edid_mon = xf86OutputGetEDID(crt, intel_output->pDDCBus); - xf86DestroyI2CBusRec(intel_output->pDDCBus, true, true); + + list_for_each_entry(vgaconn, + &connector->dev->mode_config.connector_list, head) { + /* We check all connector to guarantee CRT is invalid, + * then steal CRT ddcbus. + */ + enum drm_connector_status status; + struct intel_output *intel_vga_output = + to_intel_output(vgaconn); + if (intel_vga_output->type == INTEL_OUTPUT_ANALOG) { + status = vgaconn->funcs->detect(connector); + if (status == connector_status_connected) + return; + break; + } } - if (edid_mon) { - xf86OutputSetEDID(output, edid_mon); - modes = xf86OutputGetEDIDModes(output); + /*Resever SDVO DDC bus */ + ddcbus = intel_output->ddc_bus; + intel_output->ddc_bus = intel_i2c_create(connector->dev, + GPIOA, "CRTDDC_A"); + if (!intel_output->ddc_bus) { + intel_output->ddc_bus = ddcbus; + return; } -#endif + + intel_ddc_get_modes(intel_output); + + /* + * Because user might connect CRT later, + * so we need to restore ddc bus. + */ + intel_i2c_destroy(intel_output->ddc_bus); + intel_output->ddc_bus = ddcbus; } /** -- 1.5.4.4