EDID 1.4: Decode CVT 3-byte codes and add them to the mode pool.
Section 3.10.3.8: CVT 3 Byte Code Descriptor Definition.
This commit is contained in:
parent
f6df66cc89
commit
a948216dcc
|
@ -449,17 +449,33 @@ struct whitePoints{
|
|||
float white_gamma;
|
||||
};
|
||||
|
||||
struct cvt_timings {
|
||||
int width;
|
||||
int height;
|
||||
int rate;
|
||||
int rates;
|
||||
};
|
||||
|
||||
/*
|
||||
* Be careful when adding new sections; this structure can't grow, it's
|
||||
* embedded in the middle of xf86Monitor which is ABI. Sizes below are
|
||||
* in bytes, for ILP32 systems. If all else fails just copy the section
|
||||
* literally like serial and friends.
|
||||
*/
|
||||
struct detailed_monitor_section {
|
||||
int type;
|
||||
union {
|
||||
struct detailed_timings d_timings;
|
||||
struct detailed_timings d_timings; /* 56 */
|
||||
Uchar serial[13];
|
||||
Uchar ascii_data[13];
|
||||
Uchar name[13];
|
||||
struct monitor_ranges ranges;
|
||||
struct std_timings std_t[5];
|
||||
struct whitePoints wp[2];
|
||||
} section;
|
||||
struct monitor_ranges ranges; /* 40 */
|
||||
struct std_timings std_t[5]; /* 80 */
|
||||
struct whitePoints wp[2]; /* 32 */
|
||||
/* color management data */
|
||||
struct cvt_timings cvt[4]; /* 64 */
|
||||
/* established timings III */
|
||||
} section; /* max: 80 */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -174,6 +174,34 @@ get_established_timing_section(Uchar *c, struct established_timings *r)
|
|||
r->t_manu = T_MANU;
|
||||
}
|
||||
|
||||
static void
|
||||
get_cvt_timing_section(Uchar *c, struct cvt_timings *r)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (c[0] && c[1] && c[2]) {
|
||||
r[i].height = (c[0] + ((c[1] & 0xF0) << 8) + 1) * 2;
|
||||
switch (c[1] & 0xc0) {
|
||||
case 0x00: r[i].width = r[i].height * 4 / 3; break;
|
||||
case 0x40: r[i].width = r[i].height * 16 / 9; break;
|
||||
case 0x80: r[i].width = r[i].height * 16 / 10; break;
|
||||
case 0xc0: r[i].width = r[i].height * 15 / 9; break;
|
||||
}
|
||||
switch (c[2] & 0x60) {
|
||||
case 0x00: r[i].rate = 50; break;
|
||||
case 0x20: r[i].rate = 60; break;
|
||||
case 0x40: r[i].rate = 75; break;
|
||||
case 0x60: r[i].rate = 85; break;
|
||||
}
|
||||
r[i].rates = c[2] & 0x1f;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
c += 3;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_std_timing_section(Uchar *c, struct std_timings *r,
|
||||
struct edid_version *v)
|
||||
|
@ -232,6 +260,7 @@ get_dt_md_section(Uchar *c, struct edid_version *ver,
|
|||
break;
|
||||
case CVT_3BYTE_DATA:
|
||||
det_mon[i].type = DS_CVT;
|
||||
get_cvt_timing_section(c, det_mon[i].section.cvt);
|
||||
break;
|
||||
case ADD_EST_TIMINGS:
|
||||
det_mon[i].type = DS_EST_III;
|
||||
|
|
|
@ -235,6 +235,24 @@ print_std_timings(int scrnIndex, struct std_timings *t)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_cvt_timings(int si, struct cvt_timings *t)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (t[i].height) {
|
||||
xf86DrvMsg(si, X_INFO, "%dx%d @ %s%s%s%s%s Hz\n",
|
||||
t[i].width, t[i].height,
|
||||
t[i].rates & 0x10 ? "50," : "",
|
||||
t[i].rates & 0x08 ? "60," : "",
|
||||
t[i].rates & 0x04 ? "75," : "",
|
||||
t[i].rates & 0x02 ? "85," : "",
|
||||
t[i].rates & 0x01 ? "60RB" : "");
|
||||
} else break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
print_detailed_monitor_section(int scrnIndex,
|
||||
|
@ -296,7 +314,8 @@ print_detailed_monitor_section(int scrnIndex,
|
|||
break;
|
||||
case DS_CVT:
|
||||
xf86DrvMsg(scrnIndex, X_INFO,
|
||||
"CVT 3-byte-code modes: (not decoded)\n");
|
||||
"CVT 3-byte-code modes:\n");
|
||||
print_cvt_timings(scrnIndex, m[i].section.cvt);
|
||||
break;
|
||||
case DS_EST_III:
|
||||
xf86DrvMsg(scrnIndex, X_INFO,
|
||||
|
|
|
@ -354,6 +354,36 @@ DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
|
|||
return Mode;
|
||||
}
|
||||
|
||||
static DisplayModePtr
|
||||
DDCModesFromCVT(int scrnIndex, struct cvt_timings *t)
|
||||
{
|
||||
DisplayModePtr modes = NULL;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (t[i].height) {
|
||||
if (t[i].rates & 0x10)
|
||||
modes = xf86ModesAdd(modes,
|
||||
xf86CVTMode(t[i].width, t[i].height, 50, 0, 0));
|
||||
if (t[i].rates & 0x08)
|
||||
modes = xf86ModesAdd(modes,
|
||||
xf86CVTMode(t[i].width, t[i].height, 60, 0, 0));
|
||||
if (t[i].rates & 0x04)
|
||||
modes = xf86ModesAdd(modes,
|
||||
xf86CVTMode(t[i].width, t[i].height, 75, 0, 0));
|
||||
if (t[i].rates & 0x02)
|
||||
modes = xf86ModesAdd(modes,
|
||||
xf86CVTMode(t[i].width, t[i].height, 85, 0, 0));
|
||||
if (t[i].rates & 0x01)
|
||||
modes = xf86ModesAdd(modes,
|
||||
xf86CVTMode(t[i].width, t[i].height, 60, 1, 0));
|
||||
} else break;
|
||||
}
|
||||
|
||||
return modes;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
@ -527,6 +557,10 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
|
|||
quirks);
|
||||
Modes = xf86ModesAdd(Modes, Mode);
|
||||
break;
|
||||
case DS_CVT:
|
||||
Mode = DDCModesFromCVT(scrnIndex, det_mon->section.cvt);
|
||||
Modes = xf86ModesAdd(Modes, Mode);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user