summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/radeon.h1
-rw-r--r--src/radeon_driver.c1
-rw-r--r--src/radeon_output.c61
-rw-r--r--src/radeon_probe.h3
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