aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_sdvo.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-02-16 04:36:05 -0500
committerChris Wilson <chris@chris-wilson.co.uk>2011-02-16 04:44:30 -0500
commit9035a97a32836d0e456ddafaaf249a844e6e4b5e (patch)
tree41ec3db083bdb46cd831f0d39db1fe294ae7d55f /drivers/gpu/drm/i915/intel_sdvo.c
parentfe16d949b45036d9f80e20e07bde1ddacc930b10 (diff)
parent452858338aec31c1f4414bf07f31663690479869 (diff)
Merge branch 'drm-intel-fixes' into drm-intel-next
Grab the latest stabilisation bits from -fixes and some suspend and resume fixes from linus. Conflicts: drivers/gpu/drm/i915/i915_drv.h drivers/gpu/drm/i915/i915_irq.c
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c66
1 files changed, 55 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 740c9dded0a0..19c817a2df0c 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -46,6 +46,7 @@
46 SDVO_TV_MASK) 46 SDVO_TV_MASK)
47 47
48#define IS_TV(c) (c->output_flag & SDVO_TV_MASK) 48#define IS_TV(c) (c->output_flag & SDVO_TV_MASK)
49#define IS_TMDS(c) (c->output_flag & SDVO_TMDS_MASK)
49#define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) 50#define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK)
50#define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK)) 51#define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK))
51 52
@@ -1341,7 +1342,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
1341 intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid); 1342 intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid);
1342 intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid); 1343 intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid);
1343 } 1344 }
1344 } 1345 } else
1346 status = connector_status_disconnected;
1345 connector->display_info.raw_edid = NULL; 1347 connector->display_info.raw_edid = NULL;
1346 kfree(edid); 1348 kfree(edid);
1347 } 1349 }
@@ -1389,10 +1391,25 @@ intel_sdvo_detect(struct drm_connector *connector, bool force)
1389 1391
1390 if ((intel_sdvo_connector->output_flag & response) == 0) 1392 if ((intel_sdvo_connector->output_flag & response) == 0)
1391 ret = connector_status_disconnected; 1393 ret = connector_status_disconnected;
1392 else if (response & SDVO_TMDS_MASK) 1394 else if (IS_TMDS(intel_sdvo_connector))
1393 ret = intel_sdvo_hdmi_sink_detect(connector); 1395 ret = intel_sdvo_hdmi_sink_detect(connector);
1394 else 1396 else {
1395 ret = connector_status_connected; 1397 struct edid *edid;
1398
1399 /* if we have an edid check it matches the connection */
1400 edid = intel_sdvo_get_edid(connector);
1401 if (edid == NULL)
1402 edid = intel_sdvo_get_analog_edid(connector);
1403 if (edid != NULL) {
1404 if (edid->input & DRM_EDID_INPUT_DIGITAL)
1405 ret = connector_status_disconnected;
1406 else
1407 ret = connector_status_connected;
1408 connector->display_info.raw_edid = NULL;
1409 kfree(edid);
1410 } else
1411 ret = connector_status_connected;
1412 }
1396 1413
1397 /* May update encoder flag for like clock for SDVO TV, etc.*/ 1414 /* May update encoder flag for like clock for SDVO TV, etc.*/
1398 if (ret == connector_status_connected) { 1415 if (ret == connector_status_connected) {
@@ -1428,10 +1445,15 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector)
1428 edid = intel_sdvo_get_analog_edid(connector); 1445 edid = intel_sdvo_get_analog_edid(connector);
1429 1446
1430 if (edid != NULL) { 1447 if (edid != NULL) {
1431 if (edid->input & DRM_EDID_INPUT_DIGITAL) { 1448 struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector);
1449 bool monitor_is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL);
1450 bool connector_is_digital = !!IS_TMDS(intel_sdvo_connector);
1451
1452 if (connector_is_digital == monitor_is_digital) {
1432 drm_mode_connector_update_edid_property(connector, edid); 1453 drm_mode_connector_update_edid_property(connector, edid);
1433 drm_add_edid_modes(connector, edid); 1454 drm_add_edid_modes(connector, edid);
1434 } 1455 }
1456
1435 connector->display_info.raw_edid = NULL; 1457 connector->display_info.raw_edid = NULL;
1436 kfree(edid); 1458 kfree(edid);
1437 } 1459 }
@@ -1650,6 +1672,22 @@ static void intel_sdvo_destroy(struct drm_connector *connector)
1650 kfree(connector); 1672 kfree(connector);
1651} 1673}
1652 1674
1675static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector)
1676{
1677 struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector);
1678 struct edid *edid;
1679 bool has_audio = false;
1680
1681 if (!intel_sdvo->is_hdmi)
1682 return false;
1683
1684 edid = intel_sdvo_get_edid(connector);
1685 if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL)
1686 has_audio = drm_detect_monitor_audio(edid);
1687
1688 return has_audio;
1689}
1690
1653static int 1691static int
1654intel_sdvo_set_property(struct drm_connector *connector, 1692intel_sdvo_set_property(struct drm_connector *connector,
1655 struct drm_property *property, 1693 struct drm_property *property,
@@ -1666,17 +1704,23 @@ intel_sdvo_set_property(struct drm_connector *connector,
1666 return ret; 1704 return ret;
1667 1705
1668 if (property == intel_sdvo_connector->force_audio_property) { 1706 if (property == intel_sdvo_connector->force_audio_property) {
1669 if (val == intel_sdvo_connector->force_audio) 1707 int i = val;
1708 bool has_audio;
1709
1710 if (i == intel_sdvo_connector->force_audio)
1670 return 0; 1711 return 0;
1671 1712
1672 intel_sdvo_connector->force_audio = val; 1713 intel_sdvo_connector->force_audio = i;
1673 1714
1674 if (val > 0 && intel_sdvo->has_hdmi_audio) 1715 if (i == 0)
1675 return 0; 1716 has_audio = intel_sdvo_detect_hdmi_audio(connector);
1676 if (val < 0 && !intel_sdvo->has_hdmi_audio) 1717 else
1718 has_audio = i > 0;
1719
1720 if (has_audio == intel_sdvo->has_hdmi_audio)
1677 return 0; 1721 return 0;
1678 1722
1679 intel_sdvo->has_hdmi_audio = val > 0; 1723 intel_sdvo->has_hdmi_audio = has_audio;
1680 goto done; 1724 goto done;
1681 } 1725 }
1682 1726