Try to read the Data from the SDVO SPD ROM, DDC1, DDC2, DDC3. Use the new mechanism to detect SDVO card. --- drivers/gpu/drm/drm_edid.c | 6 ++ drivers/gpu/drm/i915/intel_sdvo.c | 88 ++++++++++++++++++++++++++++++++++---- 2 files changed, 87 insertions(+), 7 deletions(-) Index: linux-2.6.32-rc4/drivers/gpu/drm/i915/intel_sdvo.c =================================================================== --- linux-2.6.32-rc4.orig/drivers/gpu/drm/i915/intel_sdvo.c 2009-10-14 11:40:33.000000000 +0800 +++ linux-2.6.32-rc4/drivers/gpu/drm/i915/intel_sdvo.c 2009-10-16 10:04:48.000000000 +0800 @@ -47,7 +47,7 @@ "SECAM_K" , "SECAM_K1", "SECAM_L" , "SECAM_60" }; - +u8 spd_buffer[256]; #define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names)) struct intel_sdvo_priv { @@ -2666,6 +2666,19 @@ return; } +static void sdvo_print_spd() +{ + int i; + printk(KERN_DEBUG "SPD ROM"); + for (i = 0; i < 256; i++) { + if (i % 16 ==0) + printk("\n\t%x, ", spd_buffer[i]); + else + printk("%x ", spd_buffer[i]); + } + printk(KERN_DEBUG "End SPD ROM\n"); + return; +} bool intel_sdvo_init(struct drm_device *dev, int output_device) { struct drm_connector *connector; @@ -2699,16 +2712,79 @@ /* Save the bit-banging i2c functionality for use by the DDC wrapper */ intel_sdvo_i2c_bit_algo.functionality = intel_output->i2c_bus->algo->functionality; - + if (output_device == SDVOB) + { + u8 out_buf; + struct i2c_msg temp_msgs[] = { + { + .addr = DDC_ADDR, + .flags = 0, + .len = 1, + .buf = &out_buf, + }, + { + .addr = DDC_ADDR, + .flags = I2C_M_RD, + .len = 128, + .buf = spd_buffer, + }, + }; + out_buf = 0; + /* switch to SPD DDC */ + printk(KERN_DEBUG "Switch to SDVO SPD ROM\n"); + intel_sdvo_set_control_bus_switch(intel_output, 1); + if (i2c_transfer(intel_output->i2c_bus, temp_msgs, 2) == 2) { + sdvo_print_spd(); + } else { + printk(KERN_DEBUG "Can't read the SDVO SPD ROM\n"); + } + /* switch to SDVO DDC1 */ + printk(KERN_DEBUG "Switch to SDVO DDC1\n"); + intel_sdvo_set_control_bus_switch(intel_output, 2); + if (i2c_transfer(intel_output->i2c_bus, temp_msgs, 2) == 2) { + sdvo_print_spd(); + } else { + printk(KERN_DEBUG "Can't read the SDVO DDC1\n"); + } + /* switch to SPD DDC2 */ + printk(KERN_DEBUG "Switch to SDVO DDC2\n"); + intel_sdvo_set_control_bus_switch(intel_output, 4); + if (i2c_transfer(intel_output->i2c_bus, temp_msgs, 2) == 2) { + sdvo_print_spd(); + } else { + printk(KERN_DEBUG "Can't read the SDVO DDC2\n"); + } + /* switch to SPD DDC3 */ + printk(KERN_DEBUG "Switch to SDVO DDC3\n"); + intel_sdvo_set_control_bus_switch(intel_output, 8); + if (i2c_transfer(intel_output->i2c_bus, temp_msgs, 2) == 2) { + sdvo_print_spd(); + } else { + printk(KERN_DEBUG "Can't read the SDVO DDC3\n"); + } + } /* Read the regs to test if we can talk to the device */ + /* At the same time it is also used to switch the SDVO device from + * PROM to SDVO-only state. + * when it fails, we will contine to check whether the capibility + * is detected. + */ for (i = 0; i < 0x40; i++) { if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) { - DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", + DRM_DEBUG_KMS("Failure in state transistion on SDVO%c\n", output_device == SDVOB ? 'B' : 'C'); - goto err_i2c; + break; } } - + /* + * According to the SDVO spec, the capability is mandatory. The + * failure indicates that no SDVO device is detected. + */ + if (!intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps)) { + DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", + output_device == SDVOB ? 'B' : 'C'); + goto err_i2c; + } /* setup the DDC bus. */ if (output_device == SDVOB) { intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); @@ -2726,8 +2802,6 @@ /* Wrap with our custom algo which switches to DDC mode */ intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; - /* In defaut case sdvo lvds is false */ - intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps); if (intel_sdvo_output_setup(intel_output, sdvo_priv->caps.output_flags) != true) { Index: linux-2.6.32-rc4/drivers/gpu/drm/drm_edid.c =================================================================== --- linux-2.6.32-rc4.orig/drivers/gpu/drm/drm_edid.c 2009-10-14 11:40:33.000000000 +0800 +++ linux-2.6.32-rc4/drivers/gpu/drm/drm_edid.c 2009-10-14 11:42:40.000000000 +0800 @@ -1057,6 +1057,12 @@ ret = -1; } end: + printk(KERN_DEBUG "Read EDID for connector %s, DDC bus name %s\n", + drm_get_connector_name(connector), adapter->name); + if (ret) + printk(KERN_DEBUG "Incorrect EDID\n"); + else + printk(KERN_DEBUG "EDID is obtained\n"); return ret; }