First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / ddc / print_edid.c
blob30b607d4fdf9b9dc3a6f4e78a2fa79b863d941bd
2 /* print_edid.c: print out all information retrieved from display device
3 *
4 * Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE>
5 */
6 #ifdef HAVE_XORG_CONFIG_H
7 #include <xorg-config.h>
8 #endif
10 #include "misc.h"
11 #include "xf86.h"
12 #include "xf86_OSproc.h"
13 #include "xf86DDC.h"
15 static void print_vendor(int scrnIndex, struct vendor *);
16 static void print_version(int scrnIndex, struct edid_version *);
17 static void print_display(int scrnIndex, struct disp_features *,
18 struct edid_version *);
19 static void print_established_timings(int scrnIndex,
20 struct established_timings *);
21 static void print_std_timings(int scrnIndex, struct std_timings *);
22 static void print_detailed_monitor_section(int scrnIndex,
23 struct detailed_monitor_section *);
24 static void print_detailed_timings(int scrnIndex, struct detailed_timings *);
26 static void print_input_features(int scrnIndex, struct disp_features *);
27 static void print_dpms_features(int scrnIndex, struct disp_features *,
28 struct edid_version *v);
29 static void print_whitepoint(int scrnIndex, struct disp_features *);
30 static void print_number_sections(int scrnIndex, int);
32 #define EDID_WIDTH 16
34 xf86MonPtr
35 xf86PrintEDID(xf86MonPtr m)
37 CARD16 i, j;
38 char buf[EDID_WIDTH * 2 + 1];
40 if (!(m)) return NULL;
42 print_vendor(m->scrnIndex,&m->vendor);
43 print_version(m->scrnIndex,&m->ver);
44 print_display(m->scrnIndex,&m->features, &m->ver);
45 print_established_timings(m->scrnIndex,&m->timings1);
46 print_std_timings(m->scrnIndex,m->timings2);
47 print_detailed_monitor_section(m->scrnIndex,m->det_mon);
48 print_number_sections(m->scrnIndex,m->no_sections);
50 xf86DrvMsg(m->scrnIndex, X_INFO, "EDID (in hex):\n");
52 for (i = 0; i < 128; i += j) {
53 for (j = 0; j < EDID_WIDTH; ++j) {
54 sprintf(&buf[j * 2], "%02x", m->rawData[i + j]);
56 xf86DrvMsg(m->scrnIndex, X_INFO, "\t%s\n", buf);
59 return m;
62 static void
63 print_vendor(int scrnIndex, struct vendor *c)
65 xf86DrvMsg(scrnIndex, X_INFO, "Manufacturer: %s Model: %x Serial#: %u\n",
66 (char *)&c->name, c->prod_id, c->serial);
67 xf86DrvMsg(scrnIndex, X_INFO, "Year: %u Week: %u\n", c->year, c->week);
70 static void
71 print_version(int scrnIndex, struct edid_version *c)
73 xf86DrvMsg(scrnIndex,X_INFO,"EDID Version: %u.%u\n",c->version,
74 c->revision);
77 static void
78 print_display(int scrnIndex, struct disp_features *disp,
79 struct edid_version *version)
81 print_input_features(scrnIndex,disp);
82 xf86DrvMsg(scrnIndex,X_INFO,"Max H-Image Size [cm]: ");
83 if (disp->hsize)
84 xf86ErrorF("horiz.: %i ",disp->hsize);
85 else
86 xf86ErrorF("H-Size may change, ");
87 if (disp->vsize)
88 xf86ErrorF("vert.: %i\n",disp->vsize);
89 else
90 xf86ErrorF("V-Size may change\n");
91 xf86DrvMsg(scrnIndex,X_INFO,"Gamma: %.2f\n", disp->gamma);
92 print_dpms_features(scrnIndex,disp,version);
93 print_whitepoint(scrnIndex,disp);
96 static void
97 print_input_features(int scrnIndex, struct disp_features *c)
99 if (DIGITAL(c->input_type)) {
100 xf86DrvMsg(scrnIndex,X_INFO,"Digital Display Input\n");
101 if (DFP1(c->input_dfp))
102 xf86DrvMsg(scrnIndex,X_INFO,"DFP 1.x compatible TMDS\n");
103 } else {
104 xf86DrvMsg(scrnIndex,X_INFO,"Analog Display Input, ");
105 xf86ErrorF("Input Voltage Level: ");
106 switch (c->input_voltage){
107 case V070:
108 xf86ErrorF("0.700/0.300 V\n");
109 break;
110 case V071:
111 xf86ErrorF("0.714/0.286 V\n");
112 break;
113 case V100:
114 xf86ErrorF("1.000/0.400 V\n");
115 break;
116 case V007:
117 xf86ErrorF("0.700/0.700 V\n");
118 break;
119 default:
120 xf86ErrorF("undefined\n");
122 if (SIG_SETUP(c->input_setup))
123 xf86DrvMsg(scrnIndex,X_INFO,"Signal levels configurable\n");
124 xf86DrvMsg(scrnIndex,X_INFO,"Sync:");
125 if (SEP_SYNC(c->input_sync))
126 xf86ErrorF(" Separate");
127 if (COMP_SYNC(c->input_sync))
128 xf86ErrorF(" Composite");
129 if (SYNC_O_GREEN(c->input_sync))
130 xf86ErrorF(" SyncOnGreen");
131 if (SYNC_SERR(c->input_sync))
132 xf86ErrorF("Serration on. "
133 "V.Sync Pulse req. if CompSync or SyncOnGreen\n");
134 else xf86ErrorF("\n");
138 static void
139 print_dpms_features(int scrnIndex, struct disp_features *c,
140 struct edid_version *v)
142 if (c->dpms) {
143 xf86DrvMsg(scrnIndex,X_INFO,"DPMS capabilities:");
144 if (DPMS_STANDBY(c->dpms)) xf86ErrorF(" StandBy");
145 if (DPMS_SUSPEND(c->dpms)) xf86ErrorF(" Suspend");
146 if (DPMS_OFF(c->dpms)) xf86ErrorF(" Off");
147 } else
148 xf86DrvMsg(scrnIndex,X_INFO,"No DPMS capabilities specified");
149 switch (c->display_type){
150 case DISP_MONO:
151 xf86ErrorF("; Monochorome/GrayScale Display\n");
152 break;
153 case DISP_RGB:
154 xf86ErrorF("; RGB/Color Display\n");
155 break;
156 case DISP_MULTCOLOR:
157 xf86ErrorF("; Non RGB Multicolor Display\n");
158 break;
159 default:
160 xf86ErrorF("\n");
161 break;
163 if (STD_COLOR_SPACE(c->msc))
164 xf86DrvMsg(scrnIndex,X_INFO,
165 "Default color space is primary color space\n");
166 if (PREFERRED_TIMING_MODE(c->msc))
167 xf86DrvMsg(scrnIndex,X_INFO,
168 "First detailed timing is preferred mode\n");
169 else if (v->version == 1 && v->revision >= 3)
170 xf86DrvMsg(scrnIndex,X_INFO,
171 "First detailed timing not preferred "
172 "mode in violation of standard!");
173 if (GFT_SUPPORTED(c->msc))
174 xf86DrvMsg(scrnIndex,X_INFO,
175 "GTF timings supported\n");
178 static void
179 print_whitepoint(int scrnIndex, struct disp_features *disp)
181 xf86DrvMsg(scrnIndex,X_INFO,"redX: %.3f redY: %.3f ",
182 disp->redx,disp->redy);
183 xf86ErrorF("greenX: %.3f greenY: %.3f\n",
184 disp->greenx,disp->greeny);
185 xf86DrvMsg(scrnIndex,X_INFO,"blueX: %.3f blueY: %.3f ",
186 disp->bluex,disp->bluey);
187 xf86ErrorF("whiteX: %.3f whiteY: %.3f\n",
188 disp->whitex,disp->whitey);
191 static void
192 print_established_timings(int scrnIndex, struct established_timings *t)
194 unsigned char c;
196 if (t->t1 || t->t2 || t->t_manu)
197 xf86DrvMsg(scrnIndex,X_INFO,"Supported VESA Video Modes:\n");
198 c=t->t1;
199 if (c&0x80) xf86DrvMsg(scrnIndex,X_INFO,"720x400@70Hz\n");
200 if (c&0x40) xf86DrvMsg(scrnIndex,X_INFO,"720x400@88Hz\n");
201 if (c&0x20) xf86DrvMsg(scrnIndex,X_INFO,"640x480@60Hz\n");
202 if (c&0x10) xf86DrvMsg(scrnIndex,X_INFO,"640x480@67Hz\n");
203 if (c&0x08) xf86DrvMsg(scrnIndex,X_INFO,"640x480@72Hz\n");
204 if (c&0x04) xf86DrvMsg(scrnIndex,X_INFO,"640x480@75Hz\n");
205 if (c&0x02) xf86DrvMsg(scrnIndex,X_INFO,"800x600@56Hz\n");
206 if (c&0x01) xf86DrvMsg(scrnIndex,X_INFO,"800x600@60Hz\n");
207 c=t->t2;
208 if (c&0x80) xf86DrvMsg(scrnIndex,X_INFO,"800x600@72Hz\n");
209 if (c&0x40) xf86DrvMsg(scrnIndex,X_INFO,"800x600@75Hz\n");
210 if (c&0x20) xf86DrvMsg(scrnIndex,X_INFO,"832x624@75Hz\n");
211 if (c&0x10) xf86DrvMsg(scrnIndex,X_INFO,"1024x768@87Hz (interlaced)\n");
212 if (c&0x08) xf86DrvMsg(scrnIndex,X_INFO,"1024x768@60Hz\n");
213 if (c&0x04) xf86DrvMsg(scrnIndex,X_INFO,"1024x768@70Hz\n");
214 if (c&0x02) xf86DrvMsg(scrnIndex,X_INFO,"1024x768@75Hz\n");
215 if (c&0x01) xf86DrvMsg(scrnIndex,X_INFO,"1280x1024@75Hz\n");
216 c=t->t_manu;
217 if (c&0x80) xf86DrvMsg(scrnIndex,X_INFO,"1152x870@75Hz\n");
218 xf86DrvMsg(scrnIndex,X_INFO,"Manufacturer's mask: %X\n",c&0x7F);
221 static void
222 print_std_timings(int scrnIndex, struct std_timings *t)
224 int i;
225 char done = 0;
226 for (i=0;i<STD_TIMINGS;i++) {
227 if (t[i].hsize > 256) { /* sanity check */
228 if (!done) {
229 xf86DrvMsg(scrnIndex,X_INFO,"Supported Future Video Modes:\n");
230 done = 1;
232 xf86DrvMsg(scrnIndex,X_INFO,
233 "#%i: hsize: %i vsize %i refresh: %i vid: %i\n",
234 i, t[i].hsize, t[i].vsize, t[i].refresh, t[i].id);
239 static void
240 print_detailed_monitor_section(int scrnIndex,
241 struct detailed_monitor_section *m)
243 int i,j;
245 for (i=0;i<DET_TIMINGS;i++) {
246 switch (m[i].type) {
247 case DT:
248 print_detailed_timings(scrnIndex,&m[i].section.d_timings);
249 break;
250 case DS_SERIAL:
251 xf86DrvMsg(scrnIndex,X_INFO,"Serial No: %s\n",m[i].section.serial);
252 break;
253 case DS_ASCII_STR:
254 xf86DrvMsg(scrnIndex,X_INFO," %s\n",m[i].section.ascii_data);
255 break;
256 case DS_NAME:
257 xf86DrvMsg(scrnIndex,X_INFO,"Monitor name: %s\n",m[i].section.name);
258 break;
259 case DS_RANGES:
260 xf86DrvMsg(scrnIndex,X_INFO,
261 "Ranges: V min: %i V max: %i Hz, H min: %i H max: %i kHz,",
262 m[i].section.ranges.min_v, m[i].section.ranges.max_v,
263 m[i].section.ranges.min_h, m[i].section.ranges.max_h);
264 if (m[i].section.ranges.max_clock != 0)
265 xf86ErrorF(" PixClock max %i MHz\n",m[i].section.ranges.max_clock);
266 else
267 xf86ErrorF("\n");
268 if (m[i].section.ranges.gtf_2nd_f > 0)
269 xf86DrvMsg(scrnIndex,X_INFO," 2nd GTF parameters: f: %i kHz "
270 "c: %i m: %i k %i j %i\n",
271 m[i].section.ranges.gtf_2nd_f,
272 m[i].section.ranges.gtf_2nd_c,
273 m[i].section.ranges.gtf_2nd_m,
274 m[i].section.ranges.gtf_2nd_k,
275 m[i].section.ranges.gtf_2nd_j);
276 break;
277 case DS_STD_TIMINGS:
278 for (j = 0; j<5; j++)
279 xf86DrvMsg(scrnIndex,X_INFO,"#%i: hsize: %i vsize %i refresh: %i "
280 "vid: %i\n",i,m[i].section.std_t[i].hsize,
281 m[i].section.std_t[j].vsize,m[i].section.std_t[j].refresh,
282 m[i].section.std_t[j].id);
283 break;
284 case DS_WHITE_P:
285 for (j = 0; j<2; j++)
286 if (m[i].section.wp[j].index != 0)
287 xf86DrvMsg(scrnIndex,X_INFO,
288 "White point %i: whiteX: %f, whiteY: %f; gamma: %f\n",
289 m[i].section.wp[j].index,m[i].section.wp[j].white_x,
290 m[i].section.wp[j].white_y,
291 m[i].section.wp[j].white_gamma);
292 break;
293 case DS_DUMMY:
294 default:
295 break;
300 static void
301 print_detailed_timings(int scrnIndex, struct detailed_timings *t)
304 if (t->clock > 15000000) { /* sanity check */
305 xf86DrvMsg(scrnIndex,X_INFO,"Supported additional Video Mode:\n");
306 xf86DrvMsg(scrnIndex,X_INFO,"clock: %.1f MHz ",t->clock/1000000.0);
307 xf86ErrorF("Image Size: %i x %i mm\n",t->h_size,t->v_size);
308 xf86DrvMsg(scrnIndex,X_INFO,
309 "h_active: %i h_sync: %i h_sync_end %i h_blank_end %i ",
310 t->h_active, t->h_sync_off + t->h_active,
311 t->h_sync_off + t->h_sync_width + t->h_active,
312 t->h_active + t->h_blanking);
313 xf86ErrorF("h_border: %i\n",t->h_border);
314 xf86DrvMsg(scrnIndex,X_INFO,
315 "v_active: %i v_sync: %i v_sync_end %i v_blanking: %i ",
316 t->v_active, t->v_sync_off + t->v_active,
317 t->v_sync_off + t->v_sync_width + t->v_active,
318 t->v_active + t->v_blanking);
319 xf86ErrorF("v_border: %i\n",t->v_border);
320 if (IS_STEREO(t->stereo)) {
321 xf86DrvMsg(scrnIndex,X_INFO,"Stereo: ");
322 if (IS_RIGHT_STEREO(t->stereo)) {
323 if (!t->stereo_1)
324 xf86ErrorF("right channel on sync\n");
325 else
326 xf86ErrorF("left channel on sync\n");
327 } else if (IS_LEFT_STEREO(t->stereo)) {
328 if (!t->stereo_1)
329 xf86ErrorF("right channel on even line\n");
330 else
331 xf86ErrorF("left channel on evel line\n");
333 if (IS_4WAY_STEREO(t->stereo)) {
334 if (!t->stereo_1)
335 xf86ErrorF("4-way interleaved\n");
336 else
337 xf86ErrorF("side-by-side interleaved");
343 static void
344 print_number_sections(int scrnIndex, int num)
346 if (num)
347 xf86DrvMsg(scrnIndex,X_INFO,"Number of EDID sections to follow: %i\n",
348 num);