xf86MonPtr xf86DoEDID_DDC2(int scrnIndex, I2CBusPtr pBus) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; unsigned char *EDID_block = NULL; unsigned char *VDIF_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"); ErrorF("Sections to follow: %i\n",tmp->no_sections); #endif VDIF_Block = VDIFRead(scrnIndex, pBus, EDID1_LEN * (tmp->no_sections + 1)); tmp->vdif = xf86InterpretVdif(VDIF_Block); return tmp; }
xf86MonPtr xf86DoEDID_DDC1( int scrnIndex, void (*DDC1SetSpeed)(ScrnInfoPtr, xf86ddcSpeed), unsigned int (*DDC1Read)(ScrnInfoPtr) ) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; unsigned char *EDID_block = NULL; xf86MonPtr tmp = NULL; EDID_block = EDIDRead_DDC1(pScrn,DDC1SetSpeed,DDC1Read); if (EDID_block){ tmp = xf86InterpretEDID(scrnIndex,EDID_block); } else LOGV("No EDID block returned\n"); if (!tmp) LOGV("Cannot interpret EDID block\n"); return tmp; }
xf86MonPtr xf86DoEDID_DDC2(int scrnIndex, I2CBusPtr pBus) { unsigned char *EDID_block = NULL; xf86MonPtr tmp = NULL; EDID_block = EDID1Read_DDC2(scrnIndex,pBus); if (EDID_block){ tmp = xf86InterpretEDID(scrnIndex,EDID_block); } else { LOGV("No EDID block returned\n"); return NULL; } if (!tmp) LOGV("Cannot interpret EDID block\n"); else LOGV("Sections to follow: %d\n",tmp->no_sections); return tmp; }
xf86MonPtr xf86DoEDID_DDC1( int scrnIndex, void (*DDC1SetSpeed)(ScrnInfoPtr, xf86ddcSpeed), unsigned int (*DDC1Read)(ScrnInfoPtr) ) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; unsigned char *EDID_block = NULL; xf86MonPtr tmp = NULL; int sigio; /* Default DDC and DDC1 to enabled. */ Bool noddc = FALSE, noddc1 = 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_NODDC1, &noddc1); xfree(options); if (noddc || noddc1) return NULL; sigio = xf86BlockSIGIO(); EDID_block = EDIDRead_DDC1(pScrn,DDC1SetSpeed,DDC1Read); xf86UnblockSIGIO(sigio); if (EDID_block){ tmp = xf86InterpretEDID(scrnIndex,EDID_block); } #ifdef DEBUG else ErrorF("No EDID block returned\n"); if (!tmp) ErrorF("Cannot interpret EDID block\n"); #endif return tmp; }
/** * Attempts to probe the monitor for EDID information, if NoDDC and NoDDC1 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_DDC1(ScrnInfoPtr pScrn, DDC1SetSpeedProc DDC1SetSpeed, unsigned int (*DDC1Read) (ScrnInfoPtr)) { unsigned char *EDID_block = NULL; xf86MonPtr tmp = NULL; /* Default DDC and DDC1 to enabled. */ Bool noddc = FALSE, noddc1 = 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_NODDC1, &noddc1); free(options); if (noddc || noddc1) return NULL; OsBlockSignals(); EDID_block = EDIDRead_DDC1(pScrn, DDC1SetSpeed, DDC1Read); OsReleaseSignals(); if (EDID_block) { tmp = xf86InterpretEDID(pScrn->scrnIndex, EDID_block); } #ifdef DEBUG else ErrorF("No EDID block returned\n"); if (!tmp) ErrorF("Cannot interpret EDID block\n"); #endif return tmp; }
static xf86MonPtr imxDisplayGetEdid(ScrnInfoPtr pScrn, const char* fbId, Uchar edidDataBytes[], const int edidDataMaxBytes) { /* Loop through each sysnode entry looking for the EDID info. */ int iEntry; for (iEntry = 0; iEntry < imxSysnodeNameMonitorInfoCount; ++iEntry) { char sysnodeName[80]; /* Look for this sysnode entry which contains the id */ /* of the associated frame buffer device driver. */ strcpy(sysnodeName, imxSysnodeNameMonitorInfoArray[iEntry]); strcat(sysnodeName, "fb_name"); FILE* fp = fopen(sysnodeName, "r"); if (NULL == fp) { continue; } /* The name of the frame buffer device */ char linebuf[80] = ""; const BOOL bNoName = (NULL == fgets(linebuf, sizeof(linebuf), fp)); fclose(fp); if (bNoName || (0 != strncmp(linebuf, fbId, strlen(fbId)))) { continue; } /* Look for sysnode entry which contains cable state info. */ strcpy(sysnodeName, imxSysnodeNameMonitorInfoArray[iEntry]); strcat(sysnodeName, "cable_state"); fp = fopen(sysnodeName, "r"); if (NULL == fp) { continue; } /* Read the line that contains the cable state. */ char strCableState[80]; strcpy(strCableState, ""); const Bool bNoInfo = (NULL == fgets(strCableState, sizeof(strCableState), fp)); fclose(fp); if (bNoInfo) { continue; } imxRemoveTrailingNewLines(strCableState); /* Determine cable state from the string. */ if (0 != strcmp(strCableState, "plugin")) { continue; } /* Look for this sysnode entry which contains EDID info. */ strcpy(sysnodeName, imxSysnodeNameMonitorInfoArray[iEntry]); strcat(sysnodeName, "edid"); fp = fopen(sysnodeName, "r"); if (NULL == fp) { continue; } /* The bytes in the sysnode entry are stored in */ /* ASCII 0x%02x format. */ unsigned int byte; int nBytes; for (nBytes = 0; nBytes < edidDataMaxBytes; ++nBytes) { if (1 != fscanf(fp, "%i", &byte)) { break; } edidDataBytes[nBytes] = byte; } fclose(fp); /* Were all the bytes successfully read? */ if (edidDataMaxBytes != nBytes) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "sysnode '%s' contains only %d of %d bytes\n", sysnodeName, nBytes, edidDataMaxBytes); continue; } /* Interpret the EDID monitor info. */ xf86MonPtr pMonitor = xf86InterpretEDID(pScrn->scrnIndex, edidDataBytes); if (NULL == pMonitor) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "cannot interpret EDID info in sysnode '%s'\n", sysnodeName); continue; } return pMonitor; } return NULL; }
static DisplayModePtr output_get_modes(xf86OutputPtr output) { struct output_private *priv = output->driver_private; drmModeConnectorPtr drm_connector = priv->drm_connector; drmModeModeInfoPtr drm_mode = NULL; drmModePropertyPtr props = NULL; xf86MonPtr ddc_mon = NULL; DisplayModePtr modes = NULL, mode = NULL; int i; for (i = 0; i < drm_connector->count_props; i++) { props = drmModeGetProperty(priv->fd, drm_connector->props[i]); if (!props) continue; if (!(props->flags & DRM_MODE_PROP_BLOB)) goto out_free; if (!strcmp(props->name, "EDID")) { if (priv->edid_blob) drmModeFreePropertyBlob(priv->edid_blob); priv->edid_blob = drmModeGetPropertyBlob(priv->fd, drm_connector->prop_values[i]); } out_free: drmModeFreeProperty(props); } if (priv->edid_blob) { ddc_mon = xf86InterpretEDID(output->scrn->scrnIndex, priv->edid_blob->data); if (ddc_mon && priv->edid_blob->length > 128) ddc_mon->flags |= MONITOR_EDID_COMPLETE_RAWDATA; } xf86OutputSetEDID(output, ddc_mon); for (i = 0; i < drm_connector->count_modes; i++) { drm_mode = &drm_connector->modes[i]; if (drm_mode) { mode = calloc(1, sizeof(DisplayModeRec)); if (!mode) continue; mode->Clock = drm_mode->clock; mode->HDisplay = drm_mode->hdisplay; mode->HSyncStart = drm_mode->hsync_start; mode->HSyncEnd = drm_mode->hsync_end; mode->HTotal = drm_mode->htotal; mode->VDisplay = drm_mode->vdisplay; mode->VSyncStart = drm_mode->vsync_start; mode->VSyncEnd = drm_mode->vsync_end; mode->VTotal = drm_mode->vtotal; mode->Flags = drm_mode->flags; mode->HSkew = drm_mode->hskew; mode->VScan = drm_mode->vscan; mode->VRefresh = xf86ModeVRefresh(mode); mode->Private = (void *)drm_mode; mode->type = 0; if (drm_mode->type & DRM_MODE_TYPE_PREFERRED) mode->type |= M_T_PREFERRED; if (drm_mode->type & DRM_MODE_TYPE_DRIVER) mode->type |= M_T_DRIVER; xf86SetModeDefaultName(mode); modes = xf86ModesAdd(modes, mode); xf86PrintModeline(0, mode); } } return modes; }
static DisplayModePtr drmmode_output_get_modes(xf86OutputPtr output) { drmmode_output_private_ptr drmmode_output = output->driver_private; drmModeConnectorPtr koutput = drmmode_output->mode_output; drmmode_ptr drmmode = drmmode_output->drmmode; int i; DisplayModePtr Modes = NULL, Mode; drmModePropertyPtr props; struct fixed_panel_lvds *p_lvds; drmModeModeInfo *mode_ptr; /* look for an EDID property */ for (i = 0; i < koutput->count_props; i++) { props = drmModeGetProperty(drmmode->fd, koutput->props[i]); if (!props) continue; if (!(props->flags & DRM_MODE_PROP_BLOB)) { drmModeFreeProperty(props); continue; } if (!strcmp(props->name, "EDID")) { drmModeFreePropertyBlob(drmmode_output->edid_blob); drmmode_output->edid_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]); } drmModeFreeProperty(props); } if (drmmode_output->edid_blob) xf86OutputSetEDID(output, xf86InterpretEDID(output->scrn->scrnIndex, drmmode_output->edid_blob->data)); else xf86OutputSetEDID(output, xf86InterpretEDID(output->scrn->scrnIndex, NULL)); /* modes should already be available */ for (i = 0; i < koutput->count_modes; i++) { Mode = xnfalloc(sizeof(DisplayModeRec)); drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], Mode); Modes = xf86ModesAdd(Modes, Mode); } p_lvds = drmmode_output->private_data; /* * If the connector type is LVDS, we will traverse the kernel mode to * get the panel limit. * If it is incorrect, please fix me. */ if ((koutput->connector_type == DRM_MODE_CONNECTOR_LVDS) && p_lvds) { p_lvds->hdisplay = 0; p_lvds->vdisplay = 0; for (i = 0; i < koutput->count_modes; i++) { mode_ptr = &koutput->modes[i]; if ((mode_ptr->hdisplay >= p_lvds->hdisplay) && (mode_ptr->vdisplay >= p_lvds->vdisplay)) { p_lvds->hdisplay = mode_ptr->hdisplay; p_lvds->vdisplay = mode_ptr->vdisplay; } } if (!p_lvds->hdisplay || !p_lvds->vdisplay) xf86DrvMsg(output->scrn->scrnIndex, X_ERROR, "Incorrect KMS mode.\n"); drmmode_output_lvds_edid(output, p_lvds); } return Modes; }