diff options
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 36 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_hdmi.c | 39 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 34 |
3 files changed, 91 insertions, 18 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1f4242b682c..51cb4e36997 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
| @@ -1639,6 +1639,24 @@ static int intel_dp_get_modes(struct drm_connector *connector) | |||
| 1639 | return 0; | 1639 | return 0; |
| 1640 | } | 1640 | } |
| 1641 | 1641 | ||
| 1642 | static bool | ||
| 1643 | intel_dp_detect_audio(struct drm_connector *connector) | ||
| 1644 | { | ||
| 1645 | struct intel_dp *intel_dp = intel_attached_dp(connector); | ||
| 1646 | struct edid *edid; | ||
| 1647 | bool has_audio = false; | ||
| 1648 | |||
| 1649 | edid = drm_get_edid(connector, &intel_dp->adapter); | ||
| 1650 | if (edid) { | ||
| 1651 | has_audio = drm_detect_monitor_audio(edid); | ||
| 1652 | |||
| 1653 | connector->display_info.raw_edid = NULL; | ||
| 1654 | kfree(edid); | ||
| 1655 | } | ||
| 1656 | |||
| 1657 | return has_audio; | ||
| 1658 | } | ||
| 1659 | |||
| 1642 | static int | 1660 | static int |
| 1643 | intel_dp_set_property(struct drm_connector *connector, | 1661 | intel_dp_set_property(struct drm_connector *connector, |
| 1644 | struct drm_property *property, | 1662 | struct drm_property *property, |
| @@ -1652,17 +1670,23 @@ intel_dp_set_property(struct drm_connector *connector, | |||
| 1652 | return ret; | 1670 | return ret; |
| 1653 | 1671 | ||
| 1654 | if (property == intel_dp->force_audio_property) { | 1672 | if (property == intel_dp->force_audio_property) { |
| 1655 | if (val == intel_dp->force_audio) | 1673 | int i = val; |
| 1674 | bool has_audio; | ||
| 1675 | |||
| 1676 | if (i == intel_dp->force_audio) | ||
| 1656 | return 0; | 1677 | return 0; |
| 1657 | 1678 | ||
| 1658 | intel_dp->force_audio = val; | 1679 | intel_dp->force_audio = i; |
| 1659 | 1680 | ||
| 1660 | if (val > 0 && intel_dp->has_audio) | 1681 | if (i == 0) |
| 1661 | return 0; | 1682 | has_audio = intel_dp_detect_audio(connector); |
| 1662 | if (val < 0 && !intel_dp->has_audio) | 1683 | else |
| 1684 | has_audio = i > 0; | ||
| 1685 | |||
| 1686 | if (has_audio == intel_dp->has_audio) | ||
| 1663 | return 0; | 1687 | return 0; |
| 1664 | 1688 | ||
| 1665 | intel_dp->has_audio = val > 0; | 1689 | intel_dp->has_audio = has_audio; |
| 1666 | goto done; | 1690 | goto done; |
| 1667 | } | 1691 | } |
| 1668 | 1692 | ||
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 0d0273e7b02..c635c9e357b 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
| @@ -251,6 +251,27 @@ static int intel_hdmi_get_modes(struct drm_connector *connector) | |||
| 251 | &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter); | 251 | &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter); |
| 252 | } | 252 | } |
| 253 | 253 | ||
| 254 | static bool | ||
| 255 | intel_hdmi_detect_audio(struct drm_connector *connector) | ||
| 256 | { | ||
| 257 | struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector); | ||
| 258 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | ||
| 259 | struct edid *edid; | ||
| 260 | bool has_audio = false; | ||
| 261 | |||
| 262 | edid = drm_get_edid(connector, | ||
| 263 | &dev_priv->gmbus[intel_hdmi->ddc_bus].adapter); | ||
| 264 | if (edid) { | ||
| 265 | if (edid->input & DRM_EDID_INPUT_DIGITAL) | ||
| 266 | has_audio = drm_detect_monitor_audio(edid); | ||
| 267 | |||
| 268 | connector->display_info.raw_edid = NULL; | ||
| 269 | kfree(edid); | ||
| 270 | } | ||
| 271 | |||
| 272 | return has_audio; | ||
| 273 | } | ||
| 274 | |||
| 254 | static int | 275 | static int |
| 255 | intel_hdmi_set_property(struct drm_connector *connector, | 276 | intel_hdmi_set_property(struct drm_connector *connector, |
| 256 | struct drm_property *property, | 277 | struct drm_property *property, |
| @@ -264,17 +285,23 @@ intel_hdmi_set_property(struct drm_connector *connector, | |||
| 264 | return ret; | 285 | return ret; |
| 265 | 286 | ||
| 266 | if (property == intel_hdmi->force_audio_property) { | 287 | if (property == intel_hdmi->force_audio_property) { |
| 267 | if (val == intel_hdmi->force_audio) | 288 | int i = val; |
| 289 | bool has_audio; | ||
| 290 | |||
| 291 | if (i == intel_hdmi->force_audio) | ||
| 268 | return 0; | 292 | return 0; |
| 269 | 293 | ||
| 270 | intel_hdmi->force_audio = val; | 294 | intel_hdmi->force_audio = i; |
| 271 | 295 | ||
| 272 | if (val > 0 && intel_hdmi->has_audio) | 296 | if (i == 0) |
| 273 | return 0; | 297 | has_audio = intel_hdmi_detect_audio(connector); |
| 274 | if (val < 0 && !intel_hdmi->has_audio) | 298 | else |
| 299 | has_audio = i > 0; | ||
| 300 | |||
| 301 | if (has_audio == intel_hdmi->has_audio) | ||
| 275 | return 0; | 302 | return 0; |
| 276 | 303 | ||
| 277 | intel_hdmi->has_audio = val > 0; | 304 | intel_hdmi->has_audio = has_audio; |
| 278 | goto done; | 305 | goto done; |
| 279 | } | 306 | } |
| 280 | 307 | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d2dd90a9a10..7c50cdce84f 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
| @@ -1690,6 +1690,22 @@ static void intel_sdvo_destroy(struct drm_connector *connector) | |||
| 1690 | kfree(connector); | 1690 | kfree(connector); |
| 1691 | } | 1691 | } |
| 1692 | 1692 | ||
| 1693 | static bool intel_sdvo_detect_hdmi_audio(struct drm_connector *connector) | ||
| 1694 | { | ||
| 1695 | struct intel_sdvo *intel_sdvo = intel_attached_sdvo(connector); | ||
| 1696 | struct edid *edid; | ||
| 1697 | bool has_audio = false; | ||
| 1698 | |||
| 1699 | if (!intel_sdvo->is_hdmi) | ||
| 1700 | return false; | ||
| 1701 | |||
| 1702 | edid = intel_sdvo_get_edid(connector); | ||
| 1703 | if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL) | ||
| 1704 | has_audio = drm_detect_monitor_audio(edid); | ||
| 1705 | |||
| 1706 | return has_audio; | ||
| 1707 | } | ||
| 1708 | |||
| 1693 | static int | 1709 | static int |
| 1694 | intel_sdvo_set_property(struct drm_connector *connector, | 1710 | intel_sdvo_set_property(struct drm_connector *connector, |
| 1695 | struct drm_property *property, | 1711 | struct drm_property *property, |
| @@ -1706,17 +1722,23 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
| 1706 | return ret; | 1722 | return ret; |
| 1707 | 1723 | ||
| 1708 | if (property == intel_sdvo_connector->force_audio_property) { | 1724 | if (property == intel_sdvo_connector->force_audio_property) { |
| 1709 | if (val == intel_sdvo_connector->force_audio) | 1725 | int i = val; |
| 1726 | bool has_audio; | ||
| 1727 | |||
| 1728 | if (i == intel_sdvo_connector->force_audio) | ||
| 1710 | return 0; | 1729 | return 0; |
| 1711 | 1730 | ||
| 1712 | intel_sdvo_connector->force_audio = val; | 1731 | intel_sdvo_connector->force_audio = i; |
| 1713 | 1732 | ||
| 1714 | if (val > 0 && intel_sdvo->has_hdmi_audio) | 1733 | if (i == 0) |
| 1715 | return 0; | 1734 | has_audio = intel_sdvo_detect_hdmi_audio(connector); |
| 1716 | if (val < 0 && !intel_sdvo->has_hdmi_audio) | 1735 | else |
| 1736 | has_audio = i > 0; | ||
| 1737 | |||
| 1738 | if (has_audio == intel_sdvo->has_hdmi_audio) | ||
| 1717 | return 0; | 1739 | return 0; |
| 1718 | 1740 | ||
| 1719 | intel_sdvo->has_hdmi_audio = val > 0; | 1741 | intel_sdvo->has_hdmi_audio = has_audio; |
| 1720 | goto done; | 1742 | goto done; |
| 1721 | } | 1743 | } |
| 1722 | 1744 | ||
