diff options
author | Csillag Kristof <csillag.kristof@united-consult.hu> | 2009-10-04 18:18:56 -0400 |
---|---|---|
committer | Alex Deucher <alexdeucher@gmail.com> | 2009-10-04 23:48:14 -0400 |
commit | f8471512ea9f1d38140dfe98a0f832e9f935f51b (patch) | |
tree | 36350b8ab5bffb4caf15c1f632c716784c734d56 /src | |
parent | 60d9685abddccec17c1a9a5ec48cbe9c92543e0f (diff) |
radeon: add support for Custom EDID
Allows you to specify an edid per output from a file
to override what is detected by DDC. Useful for
problematic monitors or KVM switches that block
DDC. Specifying an EDID that is not compatible with
your monitor could damage your monitor so use with
caution.
agd5f: cache the custom edid at startup so we don't
have to read it from file every time the output is
queried.
Diffstat (limited to 'src')
-rw-r--r-- | src/radeon.h | 1 | ||||
-rw-r--r-- | src/radeon_driver.c | 1 | ||||
-rw-r--r-- | src/radeon_output.c | 61 | ||||
-rw-r--r-- | src/radeon_probe.h | 3 |
4 files changed, 65 insertions, 1 deletions
diff --git a/src/radeon.h b/src/radeon.h index 9d283bb..7fd297e 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -176,6 +176,7 @@ typedef enum { #endif #endif OPTION_IGNORE_EDID, + OPTION_CUSTOM_EDID, OPTION_DISP_PRIORITY, OPTION_PANEL_SIZE, OPTION_MIN_DOTCLOCK, diff --git a/src/radeon_driver.c b/src/radeon_driver.c index e0ba9ba..d039920 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -161,6 +161,7 @@ static const OptionInfoRec RADEONOptions[] = { #endif #endif { OPTION_IGNORE_EDID, "IgnoreEDID", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_CUSTOM_EDID, "CustomEDID", OPTV_ANYSTR, {0}, FALSE }, { OPTION_DISP_PRIORITY, "DisplayPriority", OPTV_ANYSTR, {0}, FALSE }, { OPTION_PANEL_SIZE, "PanelSize", OPTV_ANYSTR, {0}, FALSE }, { OPTION_MIN_DOTCLOCK, "ForceMinDotClock", OPTV_FREQ, {0}, FALSE }, diff --git a/src/radeon_output.c b/src/radeon_output.c index 30f6f3b..36ef1aa 100644 --- a/src/radeon_output.c +++ b/src/radeon_output.c @@ -32,6 +32,7 @@ #include <string.h> #include <stdio.h> +#include <fcntl.h> /* X and server generic header files */ #include "xf86.h" @@ -215,6 +216,60 @@ monitor_is_digital(xf86MonPtr MonInfo) return (MonInfo->rawData[0x14] & 0x80) != 0; } +static void +RADEONGetHardCodedEDIDFromFile(xf86OutputPtr output) +{ + ScrnInfoPtr pScrn = output->scrn; + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONOutputPrivatePtr radeon_output = output->driver_private; + char *EDIDlist = (char *)xf86GetOptValString(info->Options, OPTION_CUSTOM_EDID); + + radeon_output->custom_edid = FALSE; + radeon_output->custom_mon = NULL; + + if (EDIDlist != NULL) { + unsigned char edid[128]; + char *name = output->name; + char *outputEDID = strstr(EDIDlist, name); + + if (outputEDID != NULL) { + char *end; + int fd; + + outputEDID += strlen(name) + 1; + end = strstr(outputEDID, ";"); + if (end != NULL) + *end = 0; + + fd = open (outputEDID, O_RDONLY); + if (fd >= 0) { + read(fd, edid, 128); + close(fd); + if (edid[1] == 0xff) { + radeon_output->custom_mon = xf86InterpretEDID(output->scrn->scrnIndex, edid); + radeon_output->custom_edid = TRUE; + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Successfully read Custom EDID data for output %s from %s.\n", + name, outputEDID); + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Custom EDID data for %s read from %s was invalid.\n", + name, outputEDID); + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Could not read custom EDID for output %s from file %s.\n", + name, outputEDID); + } + } else { + xf86DrvMsg(pScrn->scrnIndex, X_WARNING, + "Could not find EDID file name for output %s; using auto detection.\n", + name); + } + } +} + + static RADEONMonitorType radeon_ddc_connected(xf86OutputPtr output) { @@ -224,7 +279,10 @@ radeon_ddc_connected(xf86OutputPtr output) xf86MonPtr MonInfo = NULL; RADEONOutputPrivatePtr radeon_output = output->driver_private; - if (radeon_output->pI2CBus) { + if (radeon_output->custom_edid) { + MonInfo = xnfcalloc(sizeof(xf86Monitor), 1); + *MonInfo = *radeon_output->custom_mon; + } else if (radeon_output->pI2CBus) { if (info->get_hardcoded_edid_from_bios) MonInfo = RADEONGetHardCodedEDIDFromBIOS(output); if (MonInfo == NULL) { @@ -2802,6 +2860,7 @@ Bool RADEONSetupConnectors(ScrnInfoPtr pScrn) xf86OutputPtr output = xf86_config->output[i]; output->possible_clones = radeon_output_clones(pScrn, output); + RADEONGetHardCodedEDIDFromFile(output); } return TRUE; diff --git a/src/radeon_probe.h b/src/radeon_probe.h index 9b2cd70..0ae3a87 100644 --- a/src/radeon_probe.h +++ b/src/radeon_probe.h @@ -261,6 +261,9 @@ typedef struct _RADEONOutputPrivateRec { I2CBusPtr pI2CBus; RADEONI2CBusRec ddc_i2c; Bool shared_ddc; + + Bool custom_edid; + xf86MonPtr custom_mon; // router info // HDP info |