Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
DISCONTINUED:openSUSE:11.1:Update
xorg-x11-server
hdmi-eedid.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File hdmi-eedid.diff of Package xorg-x11-server
diff --git a/hw/xfree86/ddc/DDC.HOWTO b/hw/xfree86/ddc/DDC.HOWTO index 833a7ab..1d06ca1 100644 --- a/hw/xfree86/ddc/DDC.HOWTO +++ b/hw/xfree86/ddc/DDC.HOWTO @@ -6,24 +6,24 @@ When implementing DDC in the driver one has the choice between DDC1 and DDC2. - DDC1 data is contiuously transmitted by a DDC1 capable display + DDC1 data is continuously transmitted by a DDC1 capable display device. The data is send serially over a data line; the Vsync signal serves as clock. Only one EDID 1.x data block can be transmitted using DDC1. Since transmission of an EDID1 block using a regular Vsync frequency would take up several seconds the driver can increase the Vsync frequency to up to 25 kHz as - soon as it detects DDC1 activety on the data line. + soon as it detects DDC1 activity on the data line. DDC2 data is transmitted using the I2C protocol. This requires an additional clock line. DDC2 is capable of transmitting EDID1 and EDID2 block as well as a VDIF block on display devices that support these. Display devices switch into the DDC2 mode as soon as they detect - activety on the DDC clock line. Once the are in DDC2 mode they + activity on the DDC clock line. Once the are in DDC2 mode they stop transmitting DDC1 signals until the next power cycle. Some graphics chipset configurations which are not capable of DDC2 might still be able to read DDC1 data. Where available - DDC2 it is preferrable. + DDC2 it is preferable. All relevant prototypes and defines are in xf86DDC.h. DDC2 additionally requires I2C support. The I2C prototypes @@ -37,7 +37,7 @@ unsigned int XXX_ddc1Read(ScrnInfoPtr pScrn) - Additionally a function is required to inclrease the Vsync + Additionally a function is required to increase the Vsync frequency to max. 25 kHz. void XXX_ddc1SetSpeed(ScrnInfoPtr pScrn, xf86ddcSpeed speed) @@ -58,7 +58,7 @@ in PreInit(). DDC1SetSpeed is a pointer to the SetSpeed() function, DDC1Read has to point to the DDC1 read function. The function will return a pointer to the xf86Monitor structure - which contains all information retreived by DDC. + which contains all information retrieved by DDC. NULL will be returned on failure. DDC2 Support @@ -73,7 +73,7 @@ to the I2CBusRec of the appropriate I2C Bus has to be passed as the second argument. The function will return a pointer to the xf86Monitor structure - which contains all information retreived by DDC. + which contains all information retrieved by DDC. NULL will be returned on failure. Printing monitor parameters @@ -86,7 +86,7 @@ is provided. Further processing of the xf86Monitor structure is not yet - implemented. Howerver it is planned to use the information + implemented. However, it is planned to use the information about video modes, gamma values etc. Therefore it is strongly recommended to read out DDC data before any video mode processing is done. diff --git a/hw/xfree86/ddc/Makefile.in b/hw/xfree86/ddc/Makefile.in index 9016bc2..7d73c82 100644 --- a/hw/xfree86/ddc/Makefile.in +++ b/hw/xfree86/ddc/Makefile.in @@ -112,10 +112,6 @@ CFLAGS = @CFLAGS@ COMPILEDDEFAULTFONTPATH = @COMPILEDDEFAULTFONTPATH@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DARWIN_LIBS = @DARWIN_LIBS@ DBUS_CFLAGS = @DBUS_CFLAGS@ @@ -146,14 +142,13 @@ DRIVER_MAN_SUFFIX = @DRIVER_MAN_SUFFIX@ DRI_DRIVER_PATH = @DRI_DRIVER_PATH@ DSYMUTIL = @DSYMUTIL@ DTRACE = @DTRACE@ -ECHO = @ECHO@ +DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ -F77 = @F77@ -FFLAGS = @FFLAGS@ +FGREP = @FGREP@ FILE_MAN_DIR = @FILE_MAN_DIR@ FILE_MAN_SUFFIX = @FILE_MAN_SUFFIX@ FREETYPE_CFLAGS = @FREETYPE_CFLAGS@ @@ -177,6 +172,7 @@ KDRIVE_LOCAL_LIBS = @KDRIVE_LOCAL_LIBS@ KDRIVE_PURE_INCS = @KDRIVE_PURE_INCS@ KDRIVE_PURE_LIBS = @KDRIVE_PURE_LIBS@ LAUNCHD = @LAUNCHD@ +LD = @LD@ LDFLAGS = @LDFLAGS@ LD_EXPORT_SYMBOLS_FLAG = @LD_EXPORT_SYMBOLS_FLAG@ LEX = @LEX@ @@ -190,6 +186,7 @@ LIBTOOL = @LIBTOOL@ LIB_MAN_DIR = @LIB_MAN_DIR@ LIB_MAN_SUFFIX = @LIB_MAN_SUFFIX@ LINUXDOC = @LINUXDOC@ +LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ @@ -204,6 +201,7 @@ MISC_MAN_SUFFIX = @MISC_MAN_SUFFIX@ MKDIR_P = @MKDIR_P@ MKFONTDIR = @MKFONTDIR@ MKFONTSCALE = @MKFONTSCALE@ +NM = @NM@ NMEDIT = @NMEDIT@ OBJC = @OBJC@ OBJCCLD = @OBJCCLD@ @@ -214,6 +212,8 @@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OPENSSL_CFLAGS = @OPENSSL_CFLAGS@ OPENSSL_LIBS = @OPENSSL_LIBS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ @@ -246,9 +246,13 @@ VENDOR_NAME = @VENDOR_NAME@ VENDOR_NAME_SHORT = @VENDOR_NAME_SHORT@ VENDOR_RELEASE = @VENDOR_RELEASE@ VERSION = @VERSION@ +VNCMODULES_CFLAGS = @VNCMODULES_CFLAGS@ +VNCMODULES_LIBS = @VNCMODULES_LIBS@ X11APP_ARCHS = @X11APP_ARCHS@ X11EXAMPLES_DEP_CFLAGS = @X11EXAMPLES_DEP_CFLAGS@ X11EXAMPLES_DEP_LIBS = @X11EXAMPLES_DEP_LIBS@ +XCLIPLIST_CFLAGS = @XCLIPLIST_CFLAGS@ +XCLIPLIST_LIBS = @XCLIPLIST_LIBS@ XDMCP_CFLAGS = @XDMCP_CFLAGS@ XDMCP_LIBS = @XDMCP_LIBS@ XDMXCONFIG_DEP_CFLAGS = @XDMXCONFIG_DEP_CFLAGS@ @@ -320,6 +324,10 @@ XTSTEXAMPLES_DEP_CFLAGS = @XTSTEXAMPLES_DEP_CFLAGS@ XTSTEXAMPLES_DEP_LIBS = @XTSTEXAMPLES_DEP_LIBS@ XVFB_LIBS = @XVFB_LIBS@ XVFB_SYS_LIBS = @XVFB_SYS_LIBS@ +XVNCCONFIG_DEP_CFLAGS = @XVNCCONFIG_DEP_CFLAGS@ +XVNCCONFIG_DEP_LIBS = @XVNCCONFIG_DEP_LIBS@ +XVNC_CFLAGS = @XVNC_CFLAGS@ +XVNC_LIBS = @XVNC_LIBS@ XWINMODULES_CFLAGS = @XWINMODULES_CFLAGS@ XWINMODULES_LIBS = @XWINMODULES_LIBS@ XWIN_LIBS = @XWIN_LIBS@ @@ -338,8 +346,7 @@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_F77 = @ac_ct_F77@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -375,6 +382,7 @@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ logdir = @logdir@ +lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ moduledir = @moduledir@ diff --git a/hw/xfree86/ddc/ddcProperty.c b/hw/xfree86/ddc/ddcProperty.c index 02125df..a4384f1 100644 --- a/hw/xfree86/ddc/ddcProperty.c +++ b/hw/xfree86/ddc/ddcProperty.c @@ -83,13 +83,18 @@ addRootWindowProperties(ScrnInfoPtr pScrn, xf86MonPtr DDC) } if (makeEDID1prop) { - if ((EDID1rawdata = xalloc(128*sizeof(CARD8)))==NULL) + int size = 128; + + if (DDC->flags & EDID_COMPLETE_RAWDATA) + size += DDC->no_sections * 128; + + if ((EDID1rawdata = xalloc(size*sizeof(CARD8)))==NULL) return; EDID1Atom = MakeAtom(EDID1_ATOM_NAME, sizeof(EDID1_ATOM_NAME) - 1, TRUE); - memcpy(EDID1rawdata, DDC->rawData, 128); + memcpy(EDID1rawdata, DDC->rawData, size); xf86RegisterRootWindowProperty(scrnIndex, EDID1Atom, XA_INTEGER, 8, - 128, (unsigned char *)EDID1rawdata); + size, (unsigned char *)EDID1rawdata); } if (makeEDID2prop) { diff --git a/hw/xfree86/ddc/edid.h b/hw/xfree86/ddc/edid.h index a4e79da..b556003 100644 --- a/hw/xfree86/ddc/edid.h +++ b/hw/xfree86/ddc/edid.h @@ -12,6 +12,12 @@ #ifndef _EDID_H_ #define _EDID_H_ +#include <X11/Xmd.h> + +#ifndef _X_EXPORT +# include <X11/Xfuncproto.h> +#endif + /* read complete EDID record */ #define EDID1_LEN 128 #define BITS_PER_BYTE 9 @@ -531,6 +537,9 @@ struct detailed_monitor_section { } section; /* max: 80 */ }; +/* flags */ +#define EDID_COMPLETE_RAWDATA 0x1 + typedef struct { int scrnIndex; struct vendor vendor; @@ -539,11 +548,11 @@ typedef struct { struct established_timings timings1; struct std_timings timings2[8]; struct detailed_monitor_section det_mon[4]; - void *vdif; /* unused */ + unsigned long flags; int no_sections; Uchar *rawData; } xf86Monitor, *xf86MonPtr; -extern xf86MonPtr ConfiguredMonitor; +extern _X_EXPORT xf86MonPtr ConfiguredMonitor; #endif /* _EDID_H_ */ diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c index 958247c..c0e3df9 100644 --- a/hw/xfree86/ddc/interpret_edid.c +++ b/hw/xfree86/ddc/interpret_edid.c @@ -115,12 +115,16 @@ handle_edid_quirks(xf86MonPtr m) } } - if (real_hsize && real_vsize) { + if (!real_hsize || !real_vsize) { + m->features.hsize = m->features.vsize = 0; + } else if ((m->features.hsize * 10 == real_hsize) && + (m->features.vsize * 10 == real_vsize)) { + /* exact match is just unlikely, should do a better check though */ + m->features.hsize = m->features.vsize = 0; + } else { /* convert mm to cm */ m->features.hsize = (real_hsize + 5) / 10; m->features.vsize = (real_vsize + 5) / 10; - } else { - m->features.hsize = m->features.vsize = 0; } xf86Msg(X_INFO, "Quirked EDID physical size to %dx%d cm\n", @@ -159,6 +163,20 @@ xf86InterpretEDID(int scrnIndex, Uchar *block) return NULL; } +xf86MonPtr +xf86InterpretEEDID(int scrnIndex, Uchar *block) +{ + xf86MonPtr m; + + m = xf86InterpretEDID(scrnIndex, block); + if (!m) + return NULL; + + /* extension parse */ + + return m; +} + static void get_vendor_section(Uchar *c, struct vendor *r) { @@ -390,14 +408,14 @@ get_monitor_ranges(Uchar *c, struct monitor_ranges *r) static void get_whitepoint_section(Uchar *c, struct whitePoints *wp) { - wp[1].white_x = WHITEX1; - wp[1].white_y = WHITEY1; - wp[2].white_x = WHITEX2; - wp[2].white_y = WHITEY2; - wp[1].index = WHITE_INDEX1; - wp[2].index = WHITE_INDEX2; - wp[1].white_gamma = WHITE_GAMMA1; - wp[2].white_gamma = WHITE_GAMMA2; + wp[0].white_x = WHITEX1; + wp[0].white_y = WHITEY1; + wp[1].white_x = WHITEX2; + wp[1].white_y = WHITEY2; + wp[0].index = WHITE_INDEX1; + wp[1].index = WHITE_INDEX2; + wp[0].white_gamma = WHITE_GAMMA1; + wp[1].white_gamma = WHITE_GAMMA2; } static void @@ -441,3 +459,56 @@ validate_version(int scrnIndex, struct edid_version *r) return TRUE; } + +/* + * Returns true if HDMI, false if definitely not or unknown. + */ +Bool +xf86MonitorIsHDMI(xf86MonPtr mon) +{ + int i = 0, version, offset; + char *edid = NULL; + + if (!mon) + return FALSE; + + if (!(mon->flags & EDID_COMPLETE_RAWDATA)) + return FALSE; + + if (!mon->no_sections) + return FALSE; + + edid = (char *)mon->rawData; + if (!edid) + return FALSE; + + /* find the CEA extension block */ + for (i = 1; i <= mon->no_sections; i++) + if (edid[i * 128] == 0x02) + break; + if (i == mon->no_sections + 1) + return FALSE; + edid += (i * 128); + + version = edid[1]; + offset = edid[2]; + if (version < 3 || offset < 4) + return FALSE; + + /* walk the cea data blocks */ + for (i = 4; i < offset; i += (edid[i] & 0x1f) + 1) { + char *x = edid + i; + + /* find a vendor specific block */ + if ((x[0] & 0xe0) >> 5 == 0x03) { + int oui = (x[3] << 16) + (x[2] << 8) + x[1]; + + /* find the HDMI vendor OUI */ + if (oui == 0x000c03) + return TRUE; + } + } + + /* guess it's not HDMI after all */ + return FALSE; +} diff --git a/hw/xfree86/ddc/print_edid.c b/hw/xfree86/ddc/print_edid.c index df11bfb..7b6e298 100644 --- a/hw/xfree86/ddc/print_edid.c +++ b/hw/xfree86/ddc/print_edid.c @@ -168,7 +168,7 @@ print_dpms_features(int scrnIndex, struct disp_features *c, } else if (v->revision == 3) { xf86DrvMsg(scrnIndex,X_INFO, "First detailed timing not preferred " - "mode in violation of standard!"); + "mode in violation of standard!\n"); } if (v->revision >= 4) { @@ -463,22 +463,28 @@ print_number_sections(int scrnIndex, int num) xf86MonPtr xf86PrintEDID(xf86MonPtr m) { - CARD16 i, j; + CARD16 i, j, n; char buf[EDID_WIDTH * 2 + 1]; - if (!(m)) return NULL; + if (!m) return NULL; - print_vendor(m->scrnIndex,&m->vendor); - print_version(m->scrnIndex,&m->ver); - print_display(m->scrnIndex,&m->features, &m->ver); - print_established_timings(m->scrnIndex,&m->timings1); - print_std_timings(m->scrnIndex,m->timings2); - print_detailed_monitor_section(m->scrnIndex,m->det_mon); - print_number_sections(m->scrnIndex,m->no_sections); + print_vendor(m->scrnIndex, &m->vendor); + print_version(m->scrnIndex, &m->ver); + print_display(m->scrnIndex, &m->features, &m->ver); + print_established_timings(m->scrnIndex, &m->timings1); + print_std_timings(m->scrnIndex, m->timings2); + print_detailed_monitor_section(m->scrnIndex, m->det_mon); + print_number_sections(m->scrnIndex, m->no_sections); + + /* extension block section stuff */ xf86DrvMsg(m->scrnIndex, X_INFO, "EDID (in hex):\n"); - - for (i = 0; i < 128; i += j) { + + n = 128; + if (m->flags & EDID_COMPLETE_RAWDATA) + n += m->no_sections * 128; + + for (i = 0; i < n; i += j) { for (j = 0; j < EDID_WIDTH; ++j) { sprintf(&buf[j * 2], "%02x", m->rawData[i + j]); } diff --git a/hw/xfree86/ddc/xf86DDC.c b/hw/xfree86/ddc/xf86DDC.c index 28e2ead..dba14d5 100644 --- a/hw/xfree86/ddc/xf86DDC.c +++ b/hw/xfree86/ddc/xf86DDC.c @@ -2,6 +2,14 @@ * * Copyright 1998,1999 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE> */ + +/* + * 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 <xorg-config.h> #endif @@ -31,18 +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, - int start, - int len -); - typedef enum { DDCOPT_NODDC1, DDCOPT_NODDC2, @@ -67,7 +63,7 @@ static const OptionInfoRec DDCOptions[] = { * @return pointer to a new xf86MonPtr containing the EDID information. * @return NULL if no monitor attached or failure to interpret the EDID. */ -xf86MonPtr +xf86MonPtr xf86DoEDID_DDC1( int scrnIndex, DDC1SetSpeedProc DDC1SetSpeed, unsigned int (*DDC1Read)(ScrnInfoPtr) @@ -107,10 +103,107 @@ xf86DoEDID_DDC1( return tmp; } +static I2CDevPtr +DDC2MakeDevice(I2CBusPtr pBus, int address, char *name) +{ + I2CDevPtr dev = NULL; + + if (!(dev = xf86I2CFindDev(pBus, address))) { + dev = xf86CreateI2CDevRec(); + dev->DevName = name; + dev->SlaveAddr = address; + dev->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */ + dev->StartTimeout = 550; + dev->BitTimeout = 40; + dev->AcknTimeout = 40; + + dev->pI2CBus = pBus; + if (!xf86I2CDevInit(dev)) { + xf86DrvMsg(pBus->scrnIndex, X_PROBED, "No DDC2 device\n"); + return NULL; + } + } + + return dev; +} + +static I2CDevPtr +DDC2Init(int scrnIndex, I2CBusPtr pBus) +{ + I2CDevPtr dev = NULL; + + /* + * Slow down the bus so that older monitors don't + * miss things. + */ + pBus->RiseFallTime = 20; + + dev = DDC2MakeDevice(pBus, 0x00A0, "ddc2"); + if (xf86I2CProbeAddress(pBus, 0x0060)) + DDC2MakeDevice(pBus, 0x0060, "E-EDID segment register"); + if (xf86I2CProbeAddress(pBus, 0x0062)) + DDC2MakeDevice(pBus, 0x0062, "EDID EEPROM interface"); + if (xf86I2CProbeAddress(pBus, 0x006E)) + DDC2MakeDevice(pBus, 0x006E, "DDC control interface"); + + return dev; +} + +/* Mmmm, smell the hacks */ +static void +EEDIDStop(I2CDevPtr d) +{ +} + +/* block is the EDID block number. a segment is two blocks. */ +static Bool +DDC2Read(I2CDevPtr dev, int block, unsigned char *R_Buffer) +{ + unsigned char W_Buffer[1]; + int i, segment; + I2CDevPtr seg; + void (*stop)(I2CDevPtr); + + for (i = 0; i < RETRIES; i++) { + /* Stop bits reset the segment pointer to 0, so be careful here. */ + segment = block >> 1; + if (segment) { + Bool b; + + if (!(seg = xf86I2CFindDev(dev->pI2CBus, 0x0060))) + return FALSE; + + W_Buffer[0] = segment; + + stop = dev->pI2CBus->I2CStop; + dev->pI2CBus->I2CStop = EEDIDStop; + + b = xf86I2CWriteRead(seg, W_Buffer, 1, NULL, 0); + + dev->pI2CBus->I2CStop = stop; + if (!b) { + dev->pI2CBus->I2CStop(dev); + continue; + } + } + + W_Buffer[0] = (block & 0x01) * EDID1_LEN; + + if (xf86I2CWriteRead(dev, W_Buffer, 1, R_Buffer, EDID1_LEN)) { + if (!DDC_checksum(R_Buffer, EDID1_LEN)) + return TRUE; + } + } + + return FALSE; +} + /** * 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. + * an xf86MonPtr. Unlike xf86DoEDID_DDC[12](), this function will return + * the complete EDID data, including all extension blocks, if the 'complete' + * parameter is TRUE; * * 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. @@ -119,46 +212,72 @@ xf86DoEDID_DDC1( * @return NULL if no monitor attached or failure to interpret the EDID. */ xf86MonPtr -xf86DoEDID_DDC2(int scrnIndex, I2CBusPtr pBus) +xf86DoEEDID(int scrnIndex, I2CBusPtr pBus, Bool complete) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; unsigned char *EDID_block = NULL; xf86MonPtr tmp = NULL; + I2CDevPtr dev = NULL; /* Default DDC and DDC2 to enabled. */ Bool noddc = FALSE, noddc2 = FALSE; OptionInfoPtr options; - options = xnfalloc(sizeof(DDCOptions)); - (void)memcpy(options, DDCOptions, sizeof(DDCOptions)); + options = xalloc(sizeof(DDCOptions)); + if (!options) + return NULL; + 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 (!(dev = DDC2Init(scrnIndex, pBus))) + return NULL; - if (EDID_block){ - tmp = xf86InterpretEDID(scrnIndex,EDID_block); - } else { -#ifdef DEBUG - ErrorF("No EDID block returned\n"); -#endif + EDID_block = xcalloc(1, EDID1_LEN); + if (!EDID_block) return NULL; + + if (DDC2Read(dev, 0, EDID_block)) { + int i, n = EDID_block[0x7e]; + + if (complete && n) { + EDID_block = xrealloc(EDID_block, EDID1_LEN * (1+n)); + + for (i = 0; i < n; i++) + DDC2Read(dev, i+1, EDID_block + (EDID1_LEN * (1+i))); + } + + tmp = xf86InterpretEEDID(scrnIndex, EDID_block); } -#ifdef DEBUG - if (!tmp) - ErrorF("Cannot interpret EDID block\n"); - else - ErrorF("Sections to follow: %i\n",tmp->no_sections); -#endif - + + if (tmp && complete) + tmp->flags |= EDID_COMPLETE_RAWDATA; + 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. + * + * 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. + */ +xf86MonPtr +xf86DoEDID_DDC2(int scrnIndex, I2CBusPtr pBus) +{ + return xf86DoEEDID(scrnIndex, pBus, FALSE); +} + /* * read EDID record , pass it to callback function to interpret. * callback function will store it for further use by calling @@ -225,68 +344,3 @@ FetchEDID_DDC1(register ScrnInfoPtr pScrn, } while(--count); 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) -{ - I2CDevPtr dev; - unsigned char W_Buffer[2]; - int w_bytes; - unsigned char *R_Buffer; - int i; - - /* - * Slow down the bus so that older monitors don't - * miss things. - */ - pBus->RiseFallTime = 20; - - if (!(dev = xf86I2CFindDev(pBus, 0x00A0))) { - dev = xf86CreateI2CDevRec(); - dev->DevName = "ddc2"; - dev->SlaveAddr = 0xA0; - dev->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */ - dev->StartTimeout = 550; - dev->BitTimeout = 40; - dev->AcknTimeout = 40; - - dev->pI2CBus = pBus; - if (!xf86I2CDevInit(dev)) { - xf86DrvMsg(scrnIndex, X_PROBED, "No DDC2 device\n"); - return NULL; - } - } - if (start < 0x100) { - w_bytes = 1; - W_Buffer[0] = start; - } else { - w_bytes = 2; - W_Buffer[0] = start & 0xFF; - W_Buffer[1] = (start & 0xFF00) >> 8; - } - R_Buffer = xcalloc(1,sizeof(unsigned char) - * (len)); - for (i=0; i<RETRIES; i++) { - if (xf86I2CWriteRead(dev, W_Buffer,w_bytes, R_Buffer,len)) { - if (!DDC_checksum(R_Buffer,len)) - return R_Buffer; - -#ifdef DEBUG - else ErrorF("Checksum error in EDID block\n"); -#endif - } -#ifdef DEBUG - else ErrorF("Error reading EDID block\n"); -#endif - } - - xf86DestroyI2CDevRec(dev,TRUE); - xfree(R_Buffer); - return NULL; -} diff --git a/hw/xfree86/ddc/xf86DDC.h b/hw/xfree86/ddc/xf86DDC.h index 3b072dd..07411b8 100644 --- a/hw/xfree86/ddc/xf86DDC.h +++ b/hw/xfree86/ddc/xf86DDC.h @@ -24,35 +24,42 @@ typedef enum { typedef void (* DDC1SetSpeedProc)(ScrnInfoPtr, xf86ddcSpeed); -extern xf86MonPtr xf86DoEDID_DDC1( +extern _X_EXPORT xf86MonPtr xf86DoEDID_DDC1( int scrnIndex, DDC1SetSpeedProc DDC1SetSpeed, unsigned int (*DDC1Read)(ScrnInfoPtr) ); -extern xf86MonPtr xf86DoEDID_DDC2( +extern _X_EXPORT xf86MonPtr xf86DoEDID_DDC2( int scrnIndex, I2CBusPtr pBus ); -extern xf86MonPtr xf86PrintEDID( +extern _X_EXPORT xf86MonPtr xf86DoEEDID(int scrnIndex, I2CBusPtr pBus, Bool); + +extern _X_EXPORT xf86MonPtr xf86PrintEDID( xf86MonPtr monPtr ); -extern xf86MonPtr xf86InterpretEDID( +extern _X_EXPORT xf86MonPtr xf86InterpretEDID( + int screenIndex, Uchar *block +); + +extern _X_EXPORT xf86MonPtr xf86InterpretEEDID( int screenIndex, Uchar *block ); -extern void +extern _X_EXPORT void xf86DDCMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC); -extern Bool xf86SetDDCproperties( +extern _X_EXPORT Bool xf86SetDDCproperties( ScrnInfoPtr pScreen, xf86MonPtr DDC ); -DisplayModePtr xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC); - -#endif +extern _X_EXPORT DisplayModePtr xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC); +extern _X_EXPORT Bool +xf86MonitorIsHDMI(xf86MonPtr mon); +#endif diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 20e230d..76f359e 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -2637,7 +2637,7 @@ xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus) ScrnInfoPtr scrn = output->scrn; xf86MonPtr mon; - mon = xf86DoEDID_DDC2 (scrn->scrnIndex, pDDCBus); + mon = xf86DoEEDID (scrn->scrnIndex, pDDCBus, TRUE); if (mon) xf86DDCApplyQuirks (scrn->scrnIndex, mon);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor