diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 186 |
1 files changed, 132 insertions, 54 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 9a00adb3a50..4f0c30948bc 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -38,8 +38,7 @@ | |||
38 | #undef SDVO_DEBUG | 38 | #undef SDVO_DEBUG |
39 | #define I915_SDVO "i915_sdvo" | 39 | #define I915_SDVO "i915_sdvo" |
40 | struct intel_sdvo_priv { | 40 | struct intel_sdvo_priv { |
41 | struct intel_i2c_chan *i2c_bus; | 41 | u8 slave_addr; |
42 | int slaveaddr; | ||
43 | 42 | ||
44 | /* Register for the SDVO device: SDVOB or SDVOC */ | 43 | /* Register for the SDVO device: SDVOB or SDVOC */ |
45 | int output_device; | 44 | int output_device; |
@@ -69,12 +68,23 @@ struct intel_sdvo_priv { | |||
69 | * This is set if we treat the device as HDMI, instead of DVI. | 68 | * This is set if we treat the device as HDMI, instead of DVI. |
70 | */ | 69 | */ |
71 | bool is_hdmi; | 70 | bool is_hdmi; |
71 | |||
72 | /** | 72 | /** |
73 | * This is set if we detect output of sdvo device as LVDS. | 73 | * This is set if we detect output of sdvo device as LVDS. |
74 | */ | 74 | */ |
75 | bool is_lvds; | 75 | bool is_lvds; |
76 | 76 | ||
77 | /** | 77 | /** |
78 | * This is sdvo flags for input timing. | ||
79 | */ | ||
80 | uint8_t sdvo_flags; | ||
81 | |||
82 | /** | ||
83 | * This is sdvo fixed pannel mode pointer | ||
84 | */ | ||
85 | struct drm_display_mode *sdvo_lvds_fixed_mode; | ||
86 | |||
87 | /** | ||
78 | * Returned SDTV resolutions allowed for the current format, if the | 88 | * Returned SDTV resolutions allowed for the current format, if the |
79 | * device reported it. | 89 | * device reported it. |
80 | */ | 90 | */ |
@@ -146,13 +156,13 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, | |||
146 | 156 | ||
147 | struct i2c_msg msgs[] = { | 157 | struct i2c_msg msgs[] = { |
148 | { | 158 | { |
149 | .addr = sdvo_priv->i2c_bus->slave_addr, | 159 | .addr = sdvo_priv->slave_addr >> 1, |
150 | .flags = 0, | 160 | .flags = 0, |
151 | .len = 1, | 161 | .len = 1, |
152 | .buf = out_buf, | 162 | .buf = out_buf, |
153 | }, | 163 | }, |
154 | { | 164 | { |
155 | .addr = sdvo_priv->i2c_bus->slave_addr, | 165 | .addr = sdvo_priv->slave_addr >> 1, |
156 | .flags = I2C_M_RD, | 166 | .flags = I2C_M_RD, |
157 | .len = 1, | 167 | .len = 1, |
158 | .buf = buf, | 168 | .buf = buf, |
@@ -162,7 +172,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, | |||
162 | out_buf[0] = addr; | 172 | out_buf[0] = addr; |
163 | out_buf[1] = 0; | 173 | out_buf[1] = 0; |
164 | 174 | ||
165 | if ((ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2)) == 2) | 175 | if ((ret = i2c_transfer(intel_output->i2c_bus, msgs, 2)) == 2) |
166 | { | 176 | { |
167 | *ch = buf[0]; | 177 | *ch = buf[0]; |
168 | return true; | 178 | return true; |
@@ -175,10 +185,11 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, | |||
175 | static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, | 185 | static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, |
176 | u8 ch) | 186 | u8 ch) |
177 | { | 187 | { |
188 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
178 | u8 out_buf[2]; | 189 | u8 out_buf[2]; |
179 | struct i2c_msg msgs[] = { | 190 | struct i2c_msg msgs[] = { |
180 | { | 191 | { |
181 | .addr = intel_output->i2c_bus->slave_addr, | 192 | .addr = sdvo_priv->slave_addr >> 1, |
182 | .flags = 0, | 193 | .flags = 0, |
183 | .len = 2, | 194 | .len = 2, |
184 | .buf = out_buf, | 195 | .buf = out_buf, |
@@ -188,7 +199,7 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, | |||
188 | out_buf[0] = addr; | 199 | out_buf[0] = addr; |
189 | out_buf[1] = ch; | 200 | out_buf[1] = ch; |
190 | 201 | ||
191 | if (i2c_transfer(&intel_output->i2c_bus->adapter, msgs, 1) == 1) | 202 | if (i2c_transfer(intel_output->i2c_bus, msgs, 1) == 1) |
192 | { | 203 | { |
193 | return true; | 204 | return true; |
194 | } | 205 | } |
@@ -592,6 +603,7 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output, | |||
592 | uint16_t height) | 603 | uint16_t height) |
593 | { | 604 | { |
594 | struct intel_sdvo_preferred_input_timing_args args; | 605 | struct intel_sdvo_preferred_input_timing_args args; |
606 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | ||
595 | uint8_t status; | 607 | uint8_t status; |
596 | 608 | ||
597 | memset(&args, 0, sizeof(args)); | 609 | memset(&args, 0, sizeof(args)); |
@@ -599,7 +611,12 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output, | |||
599 | args.width = width; | 611 | args.width = width; |
600 | args.height = height; | 612 | args.height = height; |
601 | args.interlace = 0; | 613 | args.interlace = 0; |
602 | args.scaled = 0; | 614 | |
615 | if (sdvo_priv->is_lvds && | ||
616 | (sdvo_priv->sdvo_lvds_fixed_mode->hdisplay != width || | ||
617 | sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height)) | ||
618 | args.scaled = 1; | ||
619 | |||
603 | intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, | 620 | intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, |
604 | &args, sizeof(args)); | 621 | &args, sizeof(args)); |
605 | status = intel_sdvo_read_response(output, NULL, 0); | 622 | status = intel_sdvo_read_response(output, NULL, 0); |
@@ -944,12 +961,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
944 | struct intel_output *output = enc_to_intel_output(encoder); | 961 | struct intel_output *output = enc_to_intel_output(encoder); |
945 | struct intel_sdvo_priv *dev_priv = output->dev_priv; | 962 | struct intel_sdvo_priv *dev_priv = output->dev_priv; |
946 | 963 | ||
947 | if (!dev_priv->is_tv) { | 964 | if (dev_priv->is_tv) { |
948 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | ||
949 | * SDVO device will be told of the multiplier during mode_set. | ||
950 | */ | ||
951 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
952 | } else { | ||
953 | struct intel_sdvo_dtd output_dtd; | 965 | struct intel_sdvo_dtd output_dtd; |
954 | bool success; | 966 | bool success; |
955 | 967 | ||
@@ -980,6 +992,7 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
980 | intel_sdvo_get_preferred_input_timing(output, | 992 | intel_sdvo_get_preferred_input_timing(output, |
981 | &input_dtd); | 993 | &input_dtd); |
982 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | 994 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); |
995 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
983 | 996 | ||
984 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 997 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
985 | 998 | ||
@@ -990,6 +1003,52 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | |||
990 | } else { | 1003 | } else { |
991 | return false; | 1004 | return false; |
992 | } | 1005 | } |
1006 | } else if (dev_priv->is_lvds) { | ||
1007 | struct intel_sdvo_dtd output_dtd; | ||
1008 | bool success; | ||
1009 | |||
1010 | drm_mode_set_crtcinfo(dev_priv->sdvo_lvds_fixed_mode, 0); | ||
1011 | /* Set output timings */ | ||
1012 | intel_sdvo_get_dtd_from_mode(&output_dtd, | ||
1013 | dev_priv->sdvo_lvds_fixed_mode); | ||
1014 | |||
1015 | intel_sdvo_set_target_output(output, | ||
1016 | dev_priv->controlled_output); | ||
1017 | intel_sdvo_set_output_timing(output, &output_dtd); | ||
1018 | |||
1019 | /* Set the input timing to the screen. Assume always input 0. */ | ||
1020 | intel_sdvo_set_target_input(output, true, false); | ||
1021 | |||
1022 | |||
1023 | success = intel_sdvo_create_preferred_input_timing( | ||
1024 | output, | ||
1025 | mode->clock / 10, | ||
1026 | mode->hdisplay, | ||
1027 | mode->vdisplay); | ||
1028 | |||
1029 | if (success) { | ||
1030 | struct intel_sdvo_dtd input_dtd; | ||
1031 | |||
1032 | intel_sdvo_get_preferred_input_timing(output, | ||
1033 | &input_dtd); | ||
1034 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | ||
1035 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
1036 | |||
1037 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
1038 | |||
1039 | mode->clock = adjusted_mode->clock; | ||
1040 | |||
1041 | adjusted_mode->clock *= | ||
1042 | intel_sdvo_get_pixel_multiplier(mode); | ||
1043 | } else { | ||
1044 | return false; | ||
1045 | } | ||
1046 | |||
1047 | } else { | ||
1048 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | ||
1049 | * SDVO device will be told of the multiplier during mode_set. | ||
1050 | */ | ||
1051 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
993 | } | 1052 | } |
994 | return true; | 1053 | return true; |
995 | } | 1054 | } |
@@ -1033,15 +1092,16 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1033 | 1092 | ||
1034 | /* We have tried to get input timing in mode_fixup, and filled into | 1093 | /* We have tried to get input timing in mode_fixup, and filled into |
1035 | adjusted_mode */ | 1094 | adjusted_mode */ |
1036 | if (sdvo_priv->is_tv) | 1095 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { |
1037 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | 1096 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
1038 | else | 1097 | input_dtd.part2.sdvo_flags = sdvo_priv->sdvo_flags; |
1098 | } else | ||
1039 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); | 1099 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); |
1040 | 1100 | ||
1041 | /* If it's a TV, we already set the output timing in mode_fixup. | 1101 | /* If it's a TV, we already set the output timing in mode_fixup. |
1042 | * Otherwise, the output timing is equal to the input timing. | 1102 | * Otherwise, the output timing is equal to the input timing. |
1043 | */ | 1103 | */ |
1044 | if (!sdvo_priv->is_tv) { | 1104 | if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) { |
1045 | /* Set the output timing to the screen */ | 1105 | /* Set the output timing to the screen */ |
1046 | intel_sdvo_set_target_output(output, | 1106 | intel_sdvo_set_target_output(output, |
1047 | sdvo_priv->controlled_output); | 1107 | sdvo_priv->controlled_output); |
@@ -1116,6 +1176,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1116 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; | 1176 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; |
1117 | } | 1177 | } |
1118 | 1178 | ||
1179 | if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL) | ||
1180 | sdvox |= SDVO_STALL_SELECT; | ||
1119 | intel_sdvo_write_sdvox(output, sdvox); | 1181 | intel_sdvo_write_sdvox(output, sdvox); |
1120 | } | 1182 | } |
1121 | 1183 | ||
@@ -1276,6 +1338,17 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector, | |||
1276 | if (sdvo_priv->pixel_clock_max < mode->clock) | 1338 | if (sdvo_priv->pixel_clock_max < mode->clock) |
1277 | return MODE_CLOCK_HIGH; | 1339 | return MODE_CLOCK_HIGH; |
1278 | 1340 | ||
1341 | if (sdvo_priv->is_lvds == true) { | ||
1342 | if (sdvo_priv->sdvo_lvds_fixed_mode == NULL) | ||
1343 | return MODE_PANEL; | ||
1344 | |||
1345 | if (mode->hdisplay > sdvo_priv->sdvo_lvds_fixed_mode->hdisplay) | ||
1346 | return MODE_PANEL; | ||
1347 | |||
1348 | if (mode->vdisplay > sdvo_priv->sdvo_lvds_fixed_mode->vdisplay) | ||
1349 | return MODE_PANEL; | ||
1350 | } | ||
1351 | |||
1279 | return MODE_OK; | 1352 | return MODE_OK; |
1280 | } | 1353 | } |
1281 | 1354 | ||
@@ -1369,9 +1442,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | |||
1369 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1442 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; |
1370 | struct edid *edid = NULL; | 1443 | struct edid *edid = NULL; |
1371 | 1444 | ||
1372 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | ||
1373 | edid = drm_get_edid(&intel_output->base, | 1445 | edid = drm_get_edid(&intel_output->base, |
1374 | &intel_output->ddc_bus->adapter); | 1446 | intel_output->ddc_bus); |
1375 | if (edid != NULL) { | 1447 | if (edid != NULL) { |
1376 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); | 1448 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); |
1377 | kfree(edid); | 1449 | kfree(edid); |
@@ -1549,23 +1621,21 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | |||
1549 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | 1621 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) |
1550 | { | 1622 | { |
1551 | struct intel_output *intel_output = to_intel_output(connector); | 1623 | struct intel_output *intel_output = to_intel_output(connector); |
1552 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1553 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 1624 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
1625 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1626 | struct drm_display_mode *newmode; | ||
1554 | 1627 | ||
1555 | /* | 1628 | /* |
1556 | * Attempt to get the mode list from DDC. | 1629 | * Attempt to get the mode list from DDC. |
1557 | * Assume that the preferred modes are | 1630 | * Assume that the preferred modes are |
1558 | * arranged in priority order. | 1631 | * arranged in priority order. |
1559 | */ | 1632 | */ |
1560 | /* set the bus switch and get the modes */ | ||
1561 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | ||
1562 | intel_ddc_get_modes(intel_output); | 1633 | intel_ddc_get_modes(intel_output); |
1563 | if (list_empty(&connector->probed_modes) == false) | 1634 | if (list_empty(&connector->probed_modes) == false) |
1564 | return; | 1635 | goto end; |
1565 | 1636 | ||
1566 | /* Fetch modes from VBT */ | 1637 | /* Fetch modes from VBT */ |
1567 | if (dev_priv->sdvo_lvds_vbt_mode != NULL) { | 1638 | if (dev_priv->sdvo_lvds_vbt_mode != NULL) { |
1568 | struct drm_display_mode *newmode; | ||
1569 | newmode = drm_mode_duplicate(connector->dev, | 1639 | newmode = drm_mode_duplicate(connector->dev, |
1570 | dev_priv->sdvo_lvds_vbt_mode); | 1640 | dev_priv->sdvo_lvds_vbt_mode); |
1571 | if (newmode != NULL) { | 1641 | if (newmode != NULL) { |
@@ -1575,6 +1645,16 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1575 | drm_mode_probed_add(connector, newmode); | 1645 | drm_mode_probed_add(connector, newmode); |
1576 | } | 1646 | } |
1577 | } | 1647 | } |
1648 | |||
1649 | end: | ||
1650 | list_for_each_entry(newmode, &connector->probed_modes, head) { | ||
1651 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { | ||
1652 | sdvo_priv->sdvo_lvds_fixed_mode = | ||
1653 | drm_mode_duplicate(connector->dev, newmode); | ||
1654 | break; | ||
1655 | } | ||
1656 | } | ||
1657 | |||
1578 | } | 1658 | } |
1579 | 1659 | ||
1580 | static int intel_sdvo_get_modes(struct drm_connector *connector) | 1660 | static int intel_sdvo_get_modes(struct drm_connector *connector) |
@@ -1597,14 +1677,20 @@ static int intel_sdvo_get_modes(struct drm_connector *connector) | |||
1597 | static void intel_sdvo_destroy(struct drm_connector *connector) | 1677 | static void intel_sdvo_destroy(struct drm_connector *connector) |
1598 | { | 1678 | { |
1599 | struct intel_output *intel_output = to_intel_output(connector); | 1679 | struct intel_output *intel_output = to_intel_output(connector); |
1680 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1600 | 1681 | ||
1601 | if (intel_output->i2c_bus) | 1682 | if (intel_output->i2c_bus) |
1602 | intel_i2c_destroy(intel_output->i2c_bus); | 1683 | intel_i2c_destroy(intel_output->i2c_bus); |
1603 | if (intel_output->ddc_bus) | 1684 | if (intel_output->ddc_bus) |
1604 | intel_i2c_destroy(intel_output->ddc_bus); | 1685 | intel_i2c_destroy(intel_output->ddc_bus); |
1605 | 1686 | ||
1687 | if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) | ||
1688 | drm_mode_destroy(connector->dev, | ||
1689 | sdvo_priv->sdvo_lvds_fixed_mode); | ||
1690 | |||
1606 | drm_sysfs_connector_remove(connector); | 1691 | drm_sysfs_connector_remove(connector); |
1607 | drm_connector_cleanup(connector); | 1692 | drm_connector_cleanup(connector); |
1693 | |||
1608 | kfree(intel_output); | 1694 | kfree(intel_output); |
1609 | } | 1695 | } |
1610 | 1696 | ||
@@ -1709,7 +1795,7 @@ intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan) | |||
1709 | 1795 | ||
1710 | list_for_each_entry(connector, | 1796 | list_for_each_entry(connector, |
1711 | &dev->mode_config.connector_list, head) { | 1797 | &dev->mode_config.connector_list, head) { |
1712 | if (to_intel_output(connector)->ddc_bus == chan) { | 1798 | if (to_intel_output(connector)->ddc_bus == &chan->adapter) { |
1713 | intel_output = to_intel_output(connector); | 1799 | intel_output = to_intel_output(connector); |
1714 | break; | 1800 | break; |
1715 | } | 1801 | } |
@@ -1723,7 +1809,7 @@ static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, | |||
1723 | struct intel_output *intel_output; | 1809 | struct intel_output *intel_output; |
1724 | struct intel_sdvo_priv *sdvo_priv; | 1810 | struct intel_sdvo_priv *sdvo_priv; |
1725 | struct i2c_algo_bit_data *algo_data; | 1811 | struct i2c_algo_bit_data *algo_data; |
1726 | struct i2c_algorithm *algo; | 1812 | const struct i2c_algorithm *algo; |
1727 | 1813 | ||
1728 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; | 1814 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; |
1729 | intel_output = | 1815 | intel_output = |
@@ -1733,7 +1819,7 @@ static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, | |||
1733 | return -EINVAL; | 1819 | return -EINVAL; |
1734 | 1820 | ||
1735 | sdvo_priv = intel_output->dev_priv; | 1821 | sdvo_priv = intel_output->dev_priv; |
1736 | algo = (struct i2c_algorithm *)intel_output->i2c_bus->adapter.algo; | 1822 | algo = intel_output->i2c_bus->algo; |
1737 | 1823 | ||
1738 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | 1824 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); |
1739 | return algo->master_xfer(i2c_adap, msgs, num); | 1825 | return algo->master_xfer(i2c_adap, msgs, num); |
@@ -1785,13 +1871,11 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1785 | struct drm_connector *connector; | 1871 | struct drm_connector *connector; |
1786 | struct intel_output *intel_output; | 1872 | struct intel_output *intel_output; |
1787 | struct intel_sdvo_priv *sdvo_priv; | 1873 | struct intel_sdvo_priv *sdvo_priv; |
1788 | struct intel_i2c_chan *i2cbus = NULL; | 1874 | |
1789 | struct intel_i2c_chan *ddcbus = NULL; | ||
1790 | int connector_type; | 1875 | int connector_type; |
1791 | u8 ch[0x40]; | 1876 | u8 ch[0x40]; |
1792 | int i; | 1877 | int i; |
1793 | int encoder_type, output_id; | 1878 | int encoder_type; |
1794 | u8 slave_addr; | ||
1795 | 1879 | ||
1796 | intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); | 1880 | intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); |
1797 | if (!intel_output) { | 1881 | if (!intel_output) { |
@@ -1799,29 +1883,24 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1799 | } | 1883 | } |
1800 | 1884 | ||
1801 | sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1); | 1885 | sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1); |
1886 | sdvo_priv->output_device = output_device; | ||
1887 | |||
1888 | intel_output->dev_priv = sdvo_priv; | ||
1802 | intel_output->type = INTEL_OUTPUT_SDVO; | 1889 | intel_output->type = INTEL_OUTPUT_SDVO; |
1803 | 1890 | ||
1804 | /* setup the DDC bus. */ | 1891 | /* setup the DDC bus. */ |
1805 | if (output_device == SDVOB) | 1892 | if (output_device == SDVOB) |
1806 | i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); | 1893 | intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); |
1807 | else | 1894 | else |
1808 | i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); | 1895 | intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); |
1809 | 1896 | ||
1810 | if (!i2cbus) | 1897 | if (!intel_output->i2c_bus) |
1811 | goto err_inteloutput; | 1898 | goto err_inteloutput; |
1812 | 1899 | ||
1813 | slave_addr = intel_sdvo_get_slave_addr(dev, output_device); | 1900 | sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, output_device); |
1814 | sdvo_priv->i2c_bus = i2cbus; | ||
1815 | 1901 | ||
1816 | if (output_device == SDVOB) { | 1902 | /* Save the bit-banging i2c functionality for use by the DDC wrapper */ |
1817 | output_id = 1; | 1903 | intel_sdvo_i2c_bit_algo.functionality = intel_output->i2c_bus->algo->functionality; |
1818 | } else { | ||
1819 | output_id = 2; | ||
1820 | } | ||
1821 | sdvo_priv->i2c_bus->slave_addr = slave_addr >> 1; | ||
1822 | sdvo_priv->output_device = output_device; | ||
1823 | intel_output->i2c_bus = i2cbus; | ||
1824 | intel_output->dev_priv = sdvo_priv; | ||
1825 | 1904 | ||
1826 | /* Read the regs to test if we can talk to the device */ | 1905 | /* Read the regs to test if we can talk to the device */ |
1827 | for (i = 0; i < 0x40; i++) { | 1906 | for (i = 0; i < 0x40; i++) { |
@@ -1835,17 +1914,15 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1835 | 1914 | ||
1836 | /* setup the DDC bus. */ | 1915 | /* setup the DDC bus. */ |
1837 | if (output_device == SDVOB) | 1916 | if (output_device == SDVOB) |
1838 | ddcbus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); | 1917 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); |
1839 | else | 1918 | else |
1840 | ddcbus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); | 1919 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); |
1841 | 1920 | ||
1842 | if (ddcbus == NULL) | 1921 | if (intel_output->ddc_bus == NULL) |
1843 | goto err_i2c; | 1922 | goto err_i2c; |
1844 | 1923 | ||
1845 | intel_sdvo_i2c_bit_algo.functionality = | 1924 | /* Wrap with our custom algo which switches to DDC mode */ |
1846 | intel_output->i2c_bus->adapter.algo->functionality; | 1925 | intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; |
1847 | ddcbus->adapter.algo = &intel_sdvo_i2c_bit_algo; | ||
1848 | intel_output->ddc_bus = ddcbus; | ||
1849 | 1926 | ||
1850 | /* In defaut case sdvo lvds is false */ | 1927 | /* In defaut case sdvo lvds is false */ |
1851 | sdvo_priv->is_lvds = false; | 1928 | sdvo_priv->is_lvds = false; |
@@ -1965,9 +2042,10 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1965 | return true; | 2042 | return true; |
1966 | 2043 | ||
1967 | err_i2c: | 2044 | err_i2c: |
1968 | if (ddcbus != NULL) | 2045 | if (intel_output->ddc_bus != NULL) |
1969 | intel_i2c_destroy(intel_output->ddc_bus); | 2046 | intel_i2c_destroy(intel_output->ddc_bus); |
1970 | intel_i2c_destroy(intel_output->i2c_bus); | 2047 | if (intel_output->i2c_bus != NULL) |
2048 | intel_i2c_destroy(intel_output->i2c_bus); | ||
1971 | err_inteloutput: | 2049 | err_inteloutput: |
1972 | kfree(intel_output); | 2050 | kfree(intel_output); |
1973 | 2051 | ||