[Intel-gfx] [PATCH V3] drm/i915: Construct all possible sdvo outputs for one sdvo port

Ma Ling ling_ma at linux.intel.com
Mon Jun 8 13:28:49 CEST 2009


Some SDVO encoders will advertise multiple functions,
We will be aware of the real one until sdvo output detection
completes, sometime we have to change connector and encoder
type, it looks strange for users. So we construct all possible
sdvo outputs at initialization time.

Signed-off-by: Ma Ling <ling.ma at intel.com>
---
In this version, append connect check in detect function,
based on sdvo lvds patch series.

 drivers/gpu/drm/i915/intel_sdvo.c |  100 ++++++++++++++++++++++++-------------
 1 files changed, 65 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index b7b0d94..44d765f 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1448,19 +1448,20 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector)
 
 static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector)
 {
-	u8 response[2];
+	u16 response;
 	u8 status;
 	struct intel_output *intel_output = to_intel_output(connector);
+	struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
 
 	intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
 	status = intel_sdvo_read_response(intel_output, &response, 2);
 
-	DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]);
+	DRM_DEBUG("SDVO response %d %d\n", response & 0xff, response >> 8);
 
 	if (status != SDVO_CMD_STATUS_SUCCESS)
 		return connector_status_unknown;
 
-	if ((response[0] != 0) || (response[1] != 0)) {
+	if (response & sdvo_priv->controlled_output) {
 		intel_sdvo_hdmi_sink_detect(connector);
 		return connector_status_connected;
 	} else
@@ -1860,7 +1861,10 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int output_device)
 		return 0x72;
 }
 
-bool intel_sdvo_init(struct drm_device *dev, int output_device)
+
+#define MAX_SDVO_OUTPUTS_BITS 0xFFFF
+static int intel_sdvo_outputs_init(struct drm_device *dev, int output_device,
+				   int sdvo_output_id, int sdvo_output_flags)
 {
 	struct drm_connector *connector;
 	struct intel_output *intel_output;
@@ -1875,18 +1879,20 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
 
 	intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
 	if (!intel_output) {
-		return false;
+		return -1;
 	}
 
 	sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1);
 	intel_output->type = INTEL_OUTPUT_SDVO;
 
 	/* setup the DDC bus. */
-	if (output_device == SDVOB)
-		i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB");
-	else
-		i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
-
+	if (output_device == SDVOB) {
+		sprintf(ch, "%s_%d", "SDVOCTRL_E for SDVOB", sdvo_output_id);
+		i2cbus = intel_i2c_create(dev, GPIOE, (const char *)ch);
+	} else {
+		sprintf(ch, "%s_%d", "SDVOCTRL_E for SDVOC", sdvo_output_id);
+		i2cbus = intel_i2c_create(dev, GPIOE, (const char *)ch);
+	}
 	if (!i2cbus)
 		goto err_inteloutput;
 
@@ -1913,10 +1919,13 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
 	}
 
 	/* setup the DDC bus. */
-	if (output_device == SDVOB)
-		ddcbus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS");
-	else
-		ddcbus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS");
+	if (output_device == SDVOB) {
+		sprintf(ch, "%s_%d", "SDVOB DDC BUS", sdvo_output_id);
+		ddcbus = intel_i2c_create(dev, GPIOE, (const char *)ch);
+	} else {
+		sprintf(ch, "%s_%d", "SDVOC DDC BUS", sdvo_output_id);
+		ddcbus = intel_i2c_create(dev, GPIOE, (const char *)ch);
+	}
 
 	if (ddcbus == NULL)
 		goto err_i2c;
@@ -1930,7 +1939,10 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
 	sdvo_priv->is_lvds = false;
 	intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
 
-	if (sdvo_priv->caps.output_flags &
+	if (sdvo_output_flags == MAX_SDVO_OUTPUTS_BITS)
+		sdvo_output_flags = sdvo_priv->caps.output_flags;
+
+	if (sdvo_priv->caps.output_flags & sdvo_output_flags &
 	    (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) {
 		if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
 			sdvo_priv->controlled_output = SDVO_OUTPUT_TMDS0;
@@ -1950,43 +1962,41 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
 						   SDVO_COLORIMETRY_RGB256);
 			connector_type = DRM_MODE_CONNECTOR_HDMIA;
 		}
-	}
-	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_SVID0)
-	{
+	} else if (sdvo_priv->caps.output_flags &
+		 sdvo_output_flags & SDVO_OUTPUT_SVID0) {
+
 		sdvo_priv->controlled_output = SDVO_OUTPUT_SVID0;
 		encoder_type = DRM_MODE_ENCODER_TVDAC;
 		connector_type = DRM_MODE_CONNECTOR_SVIDEO;
 		sdvo_priv->is_tv = true;
 		intel_output->needs_tv_clock = true;
-	}
-	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
-	{
+	} else if (sdvo_priv->caps.output_flags &
+		 sdvo_output_flags & SDVO_OUTPUT_RGB0) {
+
 		sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
 		encoder_type = DRM_MODE_ENCODER_DAC;
 		connector_type = DRM_MODE_CONNECTOR_VGA;
-	}
-	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1)
-	{
+	} else if (sdvo_priv->caps.output_flags &
+		 sdvo_output_flags & SDVO_OUTPUT_RGB1) {
+
 		sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
 		encoder_type = DRM_MODE_ENCODER_DAC;
 		connector_type = DRM_MODE_CONNECTOR_VGA;
-	}
-	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS0)
-	{
+	} else if (sdvo_priv->caps.output_flags &
+		 sdvo_output_flags & SDVO_OUTPUT_LVDS0) {
+
 		sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS0;
 		encoder_type = DRM_MODE_ENCODER_LVDS;
 		connector_type = DRM_MODE_CONNECTOR_LVDS;
 		sdvo_priv->is_lvds = true;
-	}
-	else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_LVDS1)
-	{
+	} else if (sdvo_priv->caps.output_flags &
+		 sdvo_output_flags & SDVO_OUTPUT_LVDS1) {
+
 		sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1;
 		encoder_type = DRM_MODE_ENCODER_LVDS;
 		connector_type = DRM_MODE_CONNECTOR_LVDS;
 		sdvo_priv->is_lvds = true;
-	}
-	else
-	{
+	} else {
 		unsigned char bytes[2];
 
 		sdvo_priv->controlled_output = 0;
@@ -2040,7 +2050,7 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device)
 		  sdvo_priv->caps.output_flags &
 			(SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N');
 
-	return true;
+	return sdvo_output_flags & (~sdvo_priv->controlled_output);
 
 err_i2c:
 	if (ddcbus != NULL)
@@ -2049,5 +2059,25 @@ err_i2c:
 err_inteloutput:
 	kfree(intel_output);
 
-	return false;
+	return -1;
 }
+
+bool intel_sdvo_init(struct drm_device *dev, int output_device)
+{
+	int sdvo_output_id;
+	int sdvo_output_flags = MAX_SDVO_OUTPUTS_BITS;
+	bool ret = false;
+
+	for (sdvo_output_id = 1; sdvo_output_flags > 0; sdvo_output_id++) {
+
+		sdvo_output_flags =
+			intel_sdvo_outputs_init(dev, output_device,
+						sdvo_output_id,
+						sdvo_output_flags);
+		if (sdvo_output_flags >= 0)
+			ret = true;
+	}
+
+	return ret;
+}
+
-- 
1.5.4.4






More information about the Intel-gfx mailing list