[PATCH] drm/edid: Add support for extension blocks beyond the first
Jean Delvare
jdelvare at suse.de
Wed Dec 7 06:11:07 PST 2011
When 2 or more EDID extension blocks are present, segment must be
selected prior to reading the extended EDID block over the DDC
channel. Add support for this.
Signed-off-by: Jean Delvare <jdelvare at suse.de>
Cc: Adam Jackson <ajax at redhat.com>
---
This needs testing by someone with access to such a display.
drivers/gpu/drm/drm_edid.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
--- linux-3.2-rc3.orig/drivers/gpu/drm/drm_edid.c 2011-11-09 15:53:31.000000000 +0100
+++ linux-3.2-rc3/drivers/gpu/drm/drm_edid.c 2011-12-03 10:12:47.000000000 +0100
@@ -242,7 +242,8 @@ static int
drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
int block, int len)
{
- unsigned char start = block * EDID_LENGTH;
+ unsigned char segment = block >> 1;
+ unsigned char start = (block & 0x01) * EDID_LENGTH;
int ret, retries = 5;
/* The core i2c driver will automatically retry the transfer if the
@@ -254,6 +255,11 @@ drm_do_probe_ddc_edid(struct i2c_adapter
do {
struct i2c_msg msgs[] = {
{
+ .addr = DDC_SEGMENT_ADDR,
+ .flags = 0,
+ .len = 1,
+ .buf = &segment,
+ }, {
.addr = DDC_ADDR,
.flags = 0,
.len = 1,
@@ -265,7 +271,18 @@ drm_do_probe_ddc_edid(struct i2c_adapter
.buf = buf,
}
};
- ret = i2c_transfer(adapter, msgs, 2);
+
+ /* Don't write segment if it is 0, for compatibility */
+ if (segment) {
+ ret = i2c_transfer(adapter, msgs, 3);
+ /* The E-DDC specification says that the first ack is
+ * optional, so retry in ignore-nak mode if we get no
+ * ack at first.
+ */
+ if (ret == -ENXIO)
+ msgs[0].flags |= I2C_M_IGNORE_NAK;
+ } else
+ ret = i2c_transfer(adapter, msgs + 1, 2);
} while (ret != 2 && --retries);
return ret == 2 ? 0 : -1;
--
Jean Delvare
Suse L3
More information about the dri-devel
mailing list