Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 218028
b: refs/heads/master
c: ff482d8
h: refs/heads/master
v: v3
  • Loading branch information
Chris Wilson committed Sep 15, 2010
1 parent 63da91e commit aa03d35
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 29 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3f08e4ef807c3103ceebf7993c7463c7a90646f3
refs/heads/master: ff482d8317736908e1f803ef94ee5c736a3b8a3a
69 changes: 41 additions & 28 deletions trunk/drivers/gpu/drm/i915/intel_sdvo.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,6 @@ struct intel_sdvo {
/* DDC bus used by this SDVO encoder */
uint8_t ddc_bus;

/* Mac mini hack -- use the same DDC as the analog connector */
struct i2c_adapter *analog_ddc_bus;

/* Input timings for adjusted_mode */
struct intel_sdvo_dtd input_dtd;
};
Expand Down Expand Up @@ -1417,6 +1414,34 @@ intel_analog_is_connected(struct drm_device *dev)
return true;
}

/* Mac mini hack -- use the same DDC as the analog connector */
static struct edid *
intel_sdvo_get_analog_edid(struct drm_connector *connector)
{
struct intel_encoder *encoder = intel_attached_encoder(connector);
struct drm_device *dev = connector->dev;
struct i2c_adapter *ddc;
struct edid *edid;
u32 ddc_reg;

if (!intel_analog_is_connected(dev))
return NULL;

if (HAS_PCH_SPLIT(dev))
ddc_reg = PCH_GPIOA;
else
ddc_reg = GPIOA;

ddc = intel_i2c_create(encoder, ddc_reg, "SDVO/VGA DDC BUS");
if (ddc == NULL)
return NULL;

edid = drm_get_edid(connector, ddc);
intel_i2c_destroy(ddc);

return edid;
}

enum drm_connector_status
intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
{
Expand Down Expand Up @@ -1452,10 +1477,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
* When there is no edid and no monitor is connected with VGA
* port, try to use the CRT ddc to read the EDID for DVI-connector.
*/
if (edid == NULL &&
intel_sdvo->analog_ddc_bus &&
!intel_analog_is_connected(connector->dev))
edid = drm_get_edid(connector, intel_sdvo->analog_ddc_bus);
if (edid == NULL)
edid = intel_sdvo_get_analog_edid(connector);

status = connector_status_disconnected;
if (edid != NULL) {
Expand Down Expand Up @@ -1522,23 +1545,26 @@ 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_sdvo *intel_sdvo = intel_attached_sdvo(connector);
struct edid *edid;
int num_modes;

/* set the bus switch and get the modes */
num_modes = intel_ddc_get_modes(connector, intel_sdvo->base.ddc_bus);
if (num_modes)
return;

/*
* Mac mini hack. On this device, the DVI-I connector shares one DDC
* link between analog and digital outputs. So, if the regular SDVO
* DDC fails, check to see if the analog output is disconnected, in
* which case we'll look there for the digital DDC data.
*/
if (num_modes == 0 &&
intel_sdvo->analog_ddc_bus &&
!intel_analog_is_connected(connector->dev)) {
/* Switch to the analog ddc bus and try that
*/
(void) intel_ddc_get_modes(connector, intel_sdvo->analog_ddc_bus);
edid = intel_sdvo_get_analog_edid(connector);
if (edid != NULL) {
drm_mode_connector_update_edid_property(connector, edid);
drm_add_edid_modes(connector, edid);
connector->display_info.raw_edid = NULL;
kfree(edid);
}
}

Expand Down Expand Up @@ -1898,9 +1924,6 @@ static void intel_sdvo_enc_destroy(struct drm_encoder *encoder)
{
struct intel_sdvo *intel_sdvo = to_intel_sdvo(encoder);

if (intel_sdvo->analog_ddc_bus)
intel_i2c_destroy(intel_sdvo->analog_ddc_bus);

if (intel_sdvo->sdvo_lvds_fixed_mode != NULL)
drm_mode_destroy(encoder->dev,
intel_sdvo->sdvo_lvds_fixed_mode);
Expand Down Expand Up @@ -2519,7 +2542,7 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
struct intel_sdvo *intel_sdvo;
u8 ch[0x40];
int i;
u32 i2c_reg, ddc_reg, analog_ddc_reg;
u32 i2c_reg, ddc_reg;

intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL);
if (!intel_sdvo)
Expand All @@ -2533,11 +2556,9 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
if (HAS_PCH_SPLIT(dev)) {
i2c_reg = PCH_GPIOE;
ddc_reg = PCH_GPIOE;
analog_ddc_reg = PCH_GPIOA;
} else {
i2c_reg = GPIOE;
ddc_reg = GPIOE;
analog_ddc_reg = GPIOA;
}

/* setup the DDC bus. */
Expand Down Expand Up @@ -2572,20 +2593,14 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
intel_encoder->ddc_bus =
intel_i2c_create(intel_encoder,
ddc_reg, "SDVOB DDC BUS");
intel_sdvo->analog_ddc_bus =
intel_i2c_create(intel_encoder,
analog_ddc_reg, "SDVOB/VGA DDC BUS");
dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS;
} else {
intel_encoder->ddc_bus =
intel_i2c_create(intel_encoder,
ddc_reg, "SDVOC DDC BUS");
intel_sdvo->analog_ddc_bus =
intel_i2c_create(intel_encoder,
analog_ddc_reg, "SDVOC/VGA DDC BUS");
dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS;
}
if (intel_encoder->ddc_bus == NULL || intel_sdvo->analog_ddc_bus == NULL)
if (intel_encoder->ddc_bus == NULL)
goto err_i2c;

/* Wrap with our custom algo which switches to DDC mode */
Expand Down Expand Up @@ -2638,8 +2653,6 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg)
err_enc:
drm_encoder_cleanup(&intel_encoder->base);
err_i2c:
if (intel_sdvo->analog_ddc_bus != NULL)
intel_i2c_destroy(intel_sdvo->analog_ddc_bus);
if (intel_encoder->ddc_bus != NULL)
intel_i2c_destroy(intel_encoder->ddc_bus);
if (intel_encoder->i2c_bus != NULL)
Expand Down

0 comments on commit aa03d35

Please sign in to comment.