From 88ece11d6c45c6f4b94f7fb2da64a46e879d7c27 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 3 Dec 2007 15:47:39 -0500 Subject: [PATCH] Start E-EDID support in the DDC module. Since there's no way to safely know how many blocks xf86DoEDID_DDC2 would return, add a new xf86DoEEDID entrypoint to do that, and implement the one in terms of the other. --- hw/xfree86/ddc/xf86DDC.c | 110 ++++++++++++++++++++++----------------- hw/xfree86/ddc/xf86DDC.h | 2 + 2 files changed, 65 insertions(+), 47 deletions(-) diff --git a/hw/xfree86/ddc/xf86DDC.c b/hw/xfree86/ddc/xf86DDC.c index 28e2ead28..98f60061e 100644 --- a/hw/xfree86/ddc/xf86DDC.c +++ b/hw/xfree86/ddc/xf86DDC.c @@ -2,6 +2,14 @@ * * Copyright 1998,1999 by Egbert Eich */ + +/* + * Note that DDC1 does not define any method for returning blocks beyond + * the first. DDC2 does, but the original implementation would only ever + * read the first block. If you want to read and parse all blocks, use + * xf86DoEEDID(). + */ + #ifdef HAVE_XORG_CONFIG_H #include #endif @@ -31,11 +39,6 @@ static unsigned int *FetchEDID_DDC1( register unsigned int (*)(ScrnInfoPtr) ); -static unsigned char* EDID1Read_DDC2( - int scrnIndex, - I2CBusPtr pBus -); - static unsigned char * DDCRead_DDC2( int scrnIndex, I2CBusPtr pBus, @@ -107,6 +110,59 @@ xf86DoEDID_DDC1( return tmp; } +/** + * Attempts to probe the monitor for EDID information, if NoDDC and NoDDC2 are + * unset. EDID information blocks are interpreted and the results returned in + * an xf86MonPtr. Unlike xf86DoEDID_DDC[12](), this function will return + * the complete EDID data, including all extension blocks. + * + * This function does not affect the list of modes used by drivers -- it is up + * to the driver to decide policy on what to do with EDID information. + * + * @return pointer to a new xf86MonPtr containing the EDID information. + * @return NULL if no monitor attached or failure to interpret the EDID. + * + * nblocks is an in/out parameter. If non-zero, it defines the number of + * blocks to read from the monitor; zero (or NULL pointer) means read all. + * If non-NULL, on return it will be filled in with the number of blocks + * read. + */ +xf86MonPtr +xf86DoEEDID(int scrnIndex, I2CBusPtr pBus, int *nblocks) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + unsigned char *EDID_block = NULL; + xf86MonPtr tmp = NULL; + /* Default DDC and DDC2 to enabled. */ + Bool noddc = FALSE, noddc2 = FALSE; + OptionInfoPtr options; + + options = xnfalloc(sizeof(DDCOptions)); + memcpy(options, DDCOptions, sizeof(DDCOptions)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); + + xf86GetOptValBool(options, DDCOPT_NODDC, &noddc); + xf86GetOptValBool(options, DDCOPT_NODDC2, &noddc2); + xfree(options); + + if (noddc || noddc2) + return NULL; + + EDID_block = DDCRead_DDC2(scrnIndex, pBus, 0, EDID1_LEN); + + if (EDID_block) + tmp = xf86InterpretEDID(scrnIndex, EDID_block); + + if (nblocks) { + if (tmp) + *nblocks = tmp->no_sections; + else + *nblocks = 0; + } + + return tmp; +} + /** * Attempts to probe the monitor for EDID information, if NoDDC and NoDDC2 are * unset. EDID information blocks are interpreted and the results returned in @@ -121,42 +177,8 @@ xf86DoEDID_DDC1( xf86MonPtr xf86DoEDID_DDC2(int scrnIndex, I2CBusPtr pBus) { - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - unsigned char *EDID_block = NULL; - xf86MonPtr tmp = NULL; - /* Default DDC and DDC2 to enabled. */ - Bool noddc = FALSE, noddc2 = FALSE; - OptionInfoPtr options; - - options = xnfalloc(sizeof(DDCOptions)); - (void)memcpy(options, DDCOptions, sizeof(DDCOptions)); - xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); - - xf86GetOptValBool(options, DDCOPT_NODDC, &noddc); - xf86GetOptValBool(options, DDCOPT_NODDC2, &noddc2); - xfree(options); - - if (noddc || noddc2) - return NULL; - - EDID_block = EDID1Read_DDC2(scrnIndex,pBus); - - if (EDID_block){ - tmp = xf86InterpretEDID(scrnIndex,EDID_block); - } else { -#ifdef DEBUG - ErrorF("No EDID block returned\n"); -#endif - return NULL; - } -#ifdef DEBUG - if (!tmp) - ErrorF("Cannot interpret EDID block\n"); - else - ErrorF("Sections to follow: %i\n",tmp->no_sections); -#endif - - return tmp; + int nblocks = 1; + return xf86DoEEDID(scrnIndex, pBus, &nblocks); } /* @@ -226,12 +248,6 @@ FetchEDID_DDC1(register ScrnInfoPtr pScrn, return (ptr); } -static unsigned char* -EDID1Read_DDC2(int scrnIndex, I2CBusPtr pBus) -{ - return DDCRead_DDC2(scrnIndex, pBus, 0, EDID1_LEN); -} - static unsigned char * DDCRead_DDC2(int scrnIndex, I2CBusPtr pBus, int start, int len) { diff --git a/hw/xfree86/ddc/xf86DDC.h b/hw/xfree86/ddc/xf86DDC.h index 3b072dda7..6e5bf6f7a 100644 --- a/hw/xfree86/ddc/xf86DDC.h +++ b/hw/xfree86/ddc/xf86DDC.h @@ -35,6 +35,8 @@ extern xf86MonPtr xf86DoEDID_DDC2( I2CBusPtr pBus ); +extern xf86MonPtr xf86DoEEDID(int scrnIndex, I2CBusPtr pBus, int *nblocks); + extern xf86MonPtr xf86PrintEDID( xf86MonPtr monPtr );