1
/* $XFree86: xc/programs/Xserver/hw/xfree86/ddc/interpret_edid.c,v 1.7 2000/04/17 16:29:55 eich Exp $ */
3
/* interpret_edid.c: interpret a primary EDID block
5
* Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE>
7
#ifdef HAVE_XORG_CONFIG_H
8
#include <xorg-config.h>
13
#include "xf86_ansic.h"
14
#include "xf86_OSproc.h"
18
static void get_vendor_section(Uchar*, struct vendor *);
19
static void get_version_section(Uchar*, struct edid_version *);
20
static void get_display_section(Uchar*, struct disp_features *,
21
struct edid_version *);
22
static void get_established_timing_section(Uchar*, struct established_timings *);
23
static void get_std_timing_section(Uchar*, struct std_timings *,
24
struct edid_version *);
25
static void get_dt_md_section(Uchar *, struct edid_version *,
26
struct detailed_monitor_section *det_mon);
27
static void copy_string(Uchar *, Uchar *);
28
static void get_dst_timing_section(Uchar *, struct std_timings *,
29
struct edid_version *);
30
static void get_monitor_ranges(Uchar *, struct monitor_ranges *);
31
static void get_whitepoint_section(Uchar *, struct whitePoints *);
32
static void get_detailed_timing_section(Uchar*, struct detailed_timings *);
33
static Bool validate_version(int scrnIndex, struct edid_version *);
37
xf86InterpretEDID(int scrnIndex, Uchar *block)
41
if (!block) return NULL;
42
if (! (m = xnfcalloc(sizeof(xf86Monitor),1))) return NULL;
43
m->scrnIndex = scrnIndex;
46
get_vendor_section(SECTION(VENDOR_SECTION,block),&m->vendor);
47
get_version_section(SECTION(VERSION_SECTION,block),&m->ver);
48
if (!validate_version(scrnIndex, &m->ver)) goto error;
49
get_display_section(SECTION(DISPLAY_SECTION,block),&m->features,
51
get_established_timing_section(SECTION(ESTABLISHED_TIMING_SECTION,block),
53
get_std_timing_section(SECTION(STD_TIMING_SECTION,block),m->timings2,
55
get_dt_md_section(SECTION(DET_TIMING_SECTION,block),&m->ver, m->det_mon);
56
m->no_sections = (int)*(char *)SECTION(NO_EDID,block);
66
get_vendor_section(Uchar *c, struct vendor *r)
74
r->serial = SERIAL_NO;
80
get_version_section(Uchar *c, struct edid_version *r)
83
r->revision = REVISION;
87
get_display_section(Uchar *c, struct disp_features *r,
88
struct edid_version *v)
90
r->input_type = INPUT_TYPE;
91
if (!DIGITAL(r->input_type)) {
92
r->input_voltage = INPUT_VOLTAGE;
93
r->input_setup = SETUP;
95
} else if (v->version > 1 || v->revision > 2)
101
r->display_type = DISPLAY_TYPE;
114
get_established_timing_section(Uchar *c, struct established_timings *r)
122
get_std_timing_section(Uchar *c, struct std_timings *r,
123
struct edid_version *v)
127
for (i=0;i<STD_TIMINGS;i++){
131
r[i].refresh = REFRESH_R;
132
r[i].id = STD_TIMING_ID;
134
r[i].hsize = r[i].vsize = r[i].refresh = r[i].id = 0;
141
get_dt_md_section(Uchar *c, struct edid_version *ver,
142
struct detailed_monitor_section *det_mon)
146
for (i=0;i<DET_TIMINGS;i++) {
147
if (ver->version == 1 && ver->revision >= 1 && IS_MONITOR_DESC) {
149
switch (MONITOR_DESC_TYPE) {
151
det_mon[i].type = DS_SERIAL;
152
copy_string(c,det_mon[i].section.serial);
155
det_mon[i].type = DS_ASCII_STR;
156
copy_string(c,det_mon[i].section.ascii_data);
159
det_mon[i].type = DS_RANGES;
160
get_monitor_ranges(c,&det_mon[i].section.ranges);
163
det_mon[i].type = DS_NAME;
164
copy_string(c,det_mon[i].section.name);
166
case ADD_COLOR_POINT:
167
det_mon[i].type = DS_WHITE_P;
168
get_whitepoint_section(c,det_mon[i].section.wp);
170
case ADD_STD_TIMINGS:
171
det_mon[i].type = DS_STD_TIMINGS;
172
get_dst_timing_section(c,det_mon[i].section.std_t, ver);
175
det_mon[i].type = DS_DUMMY;
179
det_mon[i].type = DT;
180
get_detailed_timing_section(c,&det_mon[i].section.d_timings);
187
copy_string(Uchar *c, Uchar *s)
191
for (i = 0; (i < 13 && *c != 0x0A); i++)
194
while (i-- && (*--s == 0x20)) *s = 0;
198
get_dst_timing_section(Uchar *c, struct std_timings *t,
199
struct edid_version *v)
203
for (j = 0; j < 5; j++) {
206
t[j].refresh = REFRESH_R;
207
t[j].id = STD_TIMING_ID;
213
get_monitor_ranges(Uchar *c, struct monitor_ranges *r)
220
if(MAX_CLOCK != 0xff) /* is specified? */
221
r->max_clock = MAX_CLOCK * 10;
223
r->gtf_2nd_f = F_2ND_GTF;
224
r->gtf_2nd_c = C_2ND_GTF;
225
r->gtf_2nd_m = M_2ND_GTF;
226
r->gtf_2nd_k = K_2ND_GTF;
227
r->gtf_2nd_j = J_2ND_GTF;
233
get_whitepoint_section(Uchar *c, struct whitePoints *wp)
235
wp[1].white_x = WHITEX1;
236
wp[1].white_y = WHITEY1;
237
wp[2].white_x = WHITEX2;
238
wp[2].white_y = WHITEY2;
239
wp[1].index = WHITE_INDEX1;
240
wp[2].index = WHITE_INDEX2;
241
wp[1].white_gamma = WHITE_GAMMA1;
242
wp[2].white_gamma = WHITE_GAMMA2;
246
get_detailed_timing_section(Uchar *c, struct detailed_timings *r)
248
r->clock = PIXEL_CLOCK;
249
r->h_active = H_ACTIVE;
250
r->h_blanking = H_BLANK;
251
r->v_active = V_ACTIVE;
252
r->v_blanking = V_BLANK;
253
r->h_sync_off = H_SYNC_OFF;
254
r->h_sync_width = H_SYNC_WIDTH;
255
r->v_sync_off = V_SYNC_OFF;
256
r->v_sync_width = V_SYNC_WIDTH;
259
r->h_border = H_BORDER;
260
r->v_border = V_BORDER;
261
r->interlaced = INTERLACED;
263
r->stereo_1 = STEREO1;
270
validate_version(int scrnIndex, struct edid_version *r)
274
if (r->revision > 3) {
275
xf86DrvMsg(scrnIndex, X_ERROR,"EDID Version 1.%i not yet supported\n",