diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-11-23 17:37:01 -0500 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-11-23 18:04:55 -0500 |
commit | 0c1dab89ee0e483f382391d6aec77db4affb0931 (patch) | |
tree | acf3ed2bfebe699b61dd9540482e567ca8975bff | |
parent | bcf50e2775bbc3101932d8e4ab8c7902aa4163b4 (diff) |
drm/i915/sdvo: Always fallback to querying the shared DDC line
On a few devices, like the Mac Mini, the CRT DDC pins are shared between
the analog connector and the digital connector. In this scenario, rely
on the EDID to determine if a digital panel is connected to the digital
connector.
Reported-and-tested-by: Tino Keitel <tino.keitel@tikei.de>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 51 |
1 files changed, 6 insertions, 45 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 843182528b79..bf643100dec8 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1296,55 +1296,14 @@ intel_sdvo_get_edid(struct drm_connector *connector) | |||
1296 | return drm_get_edid(connector, &sdvo->ddc); | 1296 | return drm_get_edid(connector, &sdvo->ddc); |
1297 | } | 1297 | } |
1298 | 1298 | ||
1299 | static struct drm_connector * | ||
1300 | intel_find_analog_connector(struct drm_device *dev) | ||
1301 | { | ||
1302 | struct drm_connector *connector; | ||
1303 | struct intel_sdvo *encoder; | ||
1304 | |||
1305 | list_for_each_entry(encoder, | ||
1306 | &dev->mode_config.encoder_list, | ||
1307 | base.base.head) { | ||
1308 | if (encoder->base.type == INTEL_OUTPUT_ANALOG) { | ||
1309 | list_for_each_entry(connector, | ||
1310 | &dev->mode_config.connector_list, | ||
1311 | head) { | ||
1312 | if (&encoder->base == | ||
1313 | intel_attached_encoder(connector)) | ||
1314 | return connector; | ||
1315 | } | ||
1316 | } | ||
1317 | } | ||
1318 | |||
1319 | return NULL; | ||
1320 | } | ||
1321 | |||
1322 | static int | ||
1323 | intel_analog_is_connected(struct drm_device *dev) | ||
1324 | { | ||
1325 | struct drm_connector *analog_connector; | ||
1326 | |||
1327 | analog_connector = intel_find_analog_connector(dev); | ||
1328 | if (!analog_connector) | ||
1329 | return false; | ||
1330 | |||
1331 | if (analog_connector->funcs->detect(analog_connector, false) == | ||
1332 | connector_status_disconnected) | ||
1333 | return false; | ||
1334 | |||
1335 | return true; | ||
1336 | } | ||
1337 | |||
1338 | /* Mac mini hack -- use the same DDC as the analog connector */ | 1299 | /* Mac mini hack -- use the same DDC as the analog connector */ |
1339 | static struct edid * | 1300 | static struct edid * |
1340 | intel_sdvo_get_analog_edid(struct drm_connector *connector) | 1301 | intel_sdvo_get_analog_edid(struct drm_connector *connector) |
1341 | { | 1302 | { |
1342 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 1303 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
1343 | 1304 | ||
1344 | if (!intel_analog_is_connected(connector->dev)) | 1305 | return drm_get_edid(connector, |
1345 | return NULL; | 1306 | &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter); |
1346 | |||
1347 | return drm_get_edid(connector, &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter); | ||
1348 | } | 1307 | } |
1349 | 1308 | ||
1350 | enum drm_connector_status | 1309 | enum drm_connector_status |
@@ -1475,8 +1434,10 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | |||
1475 | edid = intel_sdvo_get_analog_edid(connector); | 1434 | edid = intel_sdvo_get_analog_edid(connector); |
1476 | 1435 | ||
1477 | if (edid != NULL) { | 1436 | if (edid != NULL) { |
1478 | drm_mode_connector_update_edid_property(connector, edid); | 1437 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { |
1479 | drm_add_edid_modes(connector, edid); | 1438 | drm_mode_connector_update_edid_property(connector, edid); |
1439 | drm_add_edid_modes(connector, edid); | ||
1440 | } | ||
1480 | connector->display_info.raw_edid = NULL; | 1441 | connector->display_info.raw_edid = NULL; |
1481 | kfree(edid); | 1442 | kfree(edid); |
1482 | } | 1443 | } |