• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef DI_EDID_H
2 #define DI_EDID_H
3 
4 /**
5  * libdisplay-info's low-level API for Extended Display Identification
6  * Data (EDID).
7  *
8  * EDID 1.4 is defined in VESA Enhanced Extended Display Identification Data
9  * Standard release A revision 2.
10  */
11 
12 #include <stdbool.h>
13 #include <stddef.h>
14 #include <stdint.h>
15 
16 /**
17  * EDID data structure.
18  */
19 struct di_edid;
20 
21 /**
22  * Get the EDID version.
23  */
24 int
25 di_edid_get_version(const struct di_edid *edid);
26 
27 /**
28  * Get the EDID revision.
29  */
30 int
31 di_edid_get_revision(const struct di_edid *edid);
32 
33 /**
34  * EDID vendor & product identification.
35  */
36 struct di_edid_vendor_product {
37 	char manufacturer[3];
38 	uint16_t product;
39 	uint32_t serial; /* zero if unset */
40 
41 	/* These fields are zero if unset */
42 	int manufacture_week;
43 	int manufacture_year;
44 	int model_year;
45 };
46 
47 const struct di_edid_vendor_product *
48 di_edid_get_vendor_product(const struct di_edid *edid);
49 
50 /**
51  * EDID analog signal level standard.
52  */
53 enum di_edid_video_input_analog_signal_level_std {
54 	/* 0.700 : 0.300 : 1.000 V p-p */
55 	DI_EDID_VIDEO_INPUT_ANALOG_SIGNAL_LEVEL_0 = 0x00,
56 	/* 0.714 : 0.286 : 1.000 V p-p */
57 	DI_EDID_VIDEO_INPUT_ANALOG_SIGNAL_LEVEL_1 = 0x01,
58 	/* 1.000 : 0.400 : 1.400 V p-p */
59 	DI_EDID_VIDEO_INPUT_ANALOG_SIGNAL_LEVEL_2 = 0x02,
60 	/* 0.700 : 0.000 : 0.700 V p-p */
61 	DI_EDID_VIDEO_INPUT_ANALOG_SIGNAL_LEVEL_3 = 0x03,
62 };
63 
64 /**
65  * EDID analog video setup.
66  */
67 enum di_edid_video_input_analog_video_setup {
68 	/* Blank level equals black level */
69 	DI_EDID_VIDEO_INPUT_ANALOG_BLANK_LEVEL_EQ_BLACK = 0,
70 	/* Blank-to-black setup or pedestal */
71 	DI_EDID_VIDEO_INPUT_ANALOG_BLANK_TO_BLACK_SETUP_PEDESTAL = 1,
72 };
73 
74 /**
75  * EDID analog video input basic information, defined in section 3.6.1.
76  */
77 struct di_edid_video_input_analog {
78 	enum di_edid_video_input_analog_signal_level_std signal_level_std;
79 	enum di_edid_video_input_analog_video_setup video_setup;
80 
81 	/* Separate Sync H & V Signals are supported */
82 	bool sync_separate;
83 	/* Composite Sync Signal on Horizontal is supported */
84 	bool sync_composite;
85 	/* Composite Sync Signal on Green Video is supported */
86 	bool sync_on_green;
87 	/* Serration on the Vertical Sync is supported */
88 	bool sync_serrations;
89 };
90 
91 /**
92  * Get the analog video input basic information.
93  *
94  * Returns NULL if this isn't an analog display.
95  */
96 const struct di_edid_video_input_analog *
97 di_edid_get_video_input_analog(const struct di_edid *edid);
98 
99 /**
100  * Digital video input interface standard.
101  */
102 enum di_edid_video_input_digital_interface {
103 	DI_EDID_VIDEO_INPUT_DIGITAL_UNDEFINED = 0x00,
104 	DI_EDID_VIDEO_INPUT_DIGITAL_DVI = 0x01,
105 	DI_EDID_VIDEO_INPUT_DIGITAL_HDMI_A = 0x02,
106 	DI_EDID_VIDEO_INPUT_DIGITAL_HDMI_B = 0x03,
107 	DI_EDID_VIDEO_INPUT_DIGITAL_MDDI = 0x04,
108 	DI_EDID_VIDEO_INPUT_DIGITAL_DISPLAYPORT = 0x05,
109 };
110 
111 /**
112  * EDID digital video input basic information, defined in section 3.6.1.
113  */
114 struct di_edid_video_input_digital {
115 	/* EDID 1.2 and 1.3 */
116 	bool dfp1; /* Compatible with VESA DFP 1.x TDMS CRGB */
117 
118 	/* EDID 1.4 and later */
119 	int color_bit_depth; /* zero if undefined */
120 	enum di_edid_video_input_digital_interface interface;
121 };
122 
123 /**
124  * Get the digital video input basic information.
125  *
126  * Returns NULL if this isn't a digital display.
127  */
128 const struct di_edid_video_input_digital *
129 di_edid_get_video_input_digital(const struct di_edid *edid);
130 
131 struct di_edid_screen_size {
132 	/* Physical size in centimeters, zero if unset */
133 	int width_cm, height_cm;
134 	/* Aspect ratio rounded to the hundredth decimal place, zero if unset. */
135 	float landscape_aspect_ratio, portait_aspect_ratio;
136 };
137 
138 /**
139  * Get the screen size.
140  */
141 const struct di_edid_screen_size *
142 di_edid_get_screen_size(const struct di_edid *edid);
143 
144 /**
145  * Get the display transfer characteristics from the basic EDID parameters, also
146  * known as "gamma".
147  *
148  * Returns 0 if unset (ie, stored in an extension block).
149  */
150 float
151 di_edid_get_basic_gamma(const struct di_edid *edid);
152 
153 /**
154  * Supported legacy Display Power Management Signaling (DPMS) states, defined in
155  * section 3.6.4.
156  *
157  * Display Power Management (DPM) compliant displays only support "off".
158  */
159 struct di_edid_dpms {
160 	bool standby;
161 	bool suspend;
162 	bool off;
163 };
164 
165 /**
166  * Get the set of supported legacy DPMS states.
167  */
168 const struct di_edid_dpms *
169 di_edid_get_dpms(const struct di_edid *edid);
170 
171 /**
172  * Display color type.
173  */
174 enum di_edid_display_color_type {
175 	/* Monochrome or grayscale display */
176 	DI_EDID_DISPLAY_COLOR_MONOCHROME = 0x00,
177 	/* RGB color display */
178 	DI_EDID_DISPLAY_COLOR_RGB = 0x01,
179 	/* Non-RGB color display */
180 	DI_EDID_DISPLAY_COLOR_NON_RGB = 0x02,
181 	/* Undefined */
182 	DI_EDID_DISPLAY_COLOR_UNDEFINED = 0x03,
183 };
184 
185 /**
186  * Get the display color type.
187  *
188  * For digital displays using EDID 1.4 and later, DI_EDID_DISPLAY_COLOR_UNDEFINED
189  * is always returned.
190  */
191 enum di_edid_display_color_type
192 di_edid_get_display_color_type(const struct di_edid *edid);
193 
194 /**
195  * Basic color encoding formats, defined in section 3.6.4.
196  */
197 struct di_edid_color_encoding_formats {
198 	bool rgb444; /* RGB 4:4:4 */
199 	bool ycrcb444; /* YCrCb 4:4:4 */
200 	bool ycrcb422; /* YCrCb 4:2:2 */
201 };
202 
203 /**
204  * Get the set of supported color encoding formats.
205  *
206  * Returns NULL if the display is analog or if the color encoding formats are
207  * not specified.
208  */
209 const struct di_edid_color_encoding_formats *
210 di_edid_get_color_encoding_formats(const struct di_edid *edid);
211 
212 /**
213  * Miscellaneous basic features, defined in section 3.6.4.
214  *
215  * Note, the enum values don't match the specification.
216  */
217 struct di_edid_misc_features {
218 	/**
219 	 * First detailed timing is the preferred timing.
220 	 *
221 	 * Always set for EDID 1.4 and later.
222 	 */
223 	bool has_preferred_timing;
224 	/**
225 	 * GTF using the default parameters is supported.
226 	 *
227 	 * Never set for EDID 1.4 and later.
228 	 */
229 	bool default_gtf;
230 	/**
231 	 * sRGB standard default color space is primary color space.
232 	 */
233 	bool srgb_is_primary;
234 	/**
235 	 * Preferred timing mode includes native pixel format and rate.
236 	 *
237 	 * Never set for EDID 1.3 and earlier.
238 	 */
239 	bool preferred_timing_is_native;
240 	/**
241 	 * GTF or CVT generated timings within the display's range limits are
242 	 * accepted.
243 	 *
244 	 * Never set for EDID 1.3 and earlier.
245 	 */
246 	bool continuous_freq;
247 };
248 
249 /**
250  * Get the set of miscellaneous basic features.
251  */
252 const struct di_edid_misc_features *
253 di_edid_get_misc_features(const struct di_edid *edid);
254 
255 /**
256  * EDID display chromaticity coordinates, defined in section 3.7.
257  *
258  * The values are accurate to the thousandth place. The red, green and blue
259  * values are zero for monochrome displays.
260  */
261 struct di_edid_chromaticity_coords {
262 	float red_x, red_y;
263 	float green_x, green_y;
264 	float blue_x, blue_y;
265 	float white_x, white_y;
266 };
267 
268 /**
269  * Get chromaticity coordinates.
270  */
271 const struct di_edid_chromaticity_coords *
272 di_edid_get_chromaticity_coords(const struct di_edid *edid);
273 
274 /**
275  * Established timings I and II, defined in section 3.8.
276  */
277 struct di_edid_established_timings_i_ii {
278 	/* Established timings I */
279 	bool has_720x400_70hz; /* 720 x 400 @ 70Hz (IBM, VGA) */
280 	bool has_720x400_88hz; /* 720 x 400 @ 88Hz (IBM, XGA2) */
281 	bool has_640x480_60hz; /* 640 x 480 @ 60Hz (IBM, VGA) */
282 	bool has_640x480_67hz; /* 640 x 480 @ 67Hz (Apple, Mac II) */
283 	bool has_640x480_72hz; /* 640 x 480 @ 72Hz (VESA) */
284 	bool has_640x480_75hz; /* 640 x 480 @ 75Hz (VESA) */
285 	bool has_800x600_56hz; /* 800 x 600 @ 56Hz (VESA) */
286 	bool has_800x600_60hz; /* 800 x 600 @ 60Hz (VESA) */
287 
288 	/* Established timings II */
289 	bool has_800x600_72hz; /* 800 x 600 @ 72Hz (VESA) */
290 	bool has_800x600_75hz; /* 800 x 600 @ 75Hz (VESA) */
291 	bool has_832x624_75hz; /* 832 x 624 @ 75Hz (Apple, Mac II) */
292 	bool has_1024x768_87hz_interlaced; /* 1024 x 768 @ 87Hz interlaced (IBM) */
293 	bool has_1024x768_60hz; /* 1024 x 768 @ 60Hz (VESA) */
294 	bool has_1024x768_70hz; /* 1024 x 768 @ 70Hz (VESA) */
295 	bool has_1024x768_75hz; /* 1024 x 768 @ 75Hz (VESA) */
296 	bool has_1280x1024_75hz; /* 1280 x 1024 @ 75Hz (VESA) */
297 
298 	bool has_1152x870_75hz; /* 1152 x 870 @ 75Hz (Apple, Mac II) */
299 };
300 
301 /**
302  * Get established timings I and II.
303  */
304 const struct di_edid_established_timings_i_ii *
305 di_edid_get_established_timings_i_ii(const struct di_edid *edid);
306 
307 /**
308  * Aspect ratio for an EDID standard timing.
309  */
310 enum di_edid_standard_timing_aspect_ratio {
311 	DI_EDID_STANDARD_TIMING_16_10 = 0, /* 16:10 */
312 	DI_EDID_STANDARD_TIMING_4_3 = 1, /* 4:3 */
313 	DI_EDID_STANDARD_TIMING_5_4 = 2, /* 5:4 */
314 	DI_EDID_STANDARD_TIMING_16_9 = 3, /* 16:9 */
315 };
316 
317 /**
318  * EDID standard timing, defined in section 3.9.
319  */
320 struct di_edid_standard_timing {
321 	/* Horizontal addressable pixels */
322 	int32_t horiz_video;
323 	/* Aspect ratio */
324 	enum di_edid_standard_timing_aspect_ratio aspect_ratio;
325 	/* Field Refresh Rate in Hz */
326 	int32_t refresh_rate_hz;
327 };
328 
329 /**
330  * Get the vertical addressable line count of an EDID standard timing.
331  */
332 int32_t
333 di_edid_standard_timing_get_vert_video(const struct di_edid_standard_timing *t);
334 
335 /* See <libdisplay-info/dmt.h> */
336 struct di_dmt_timing;
337 
338 /**
339  * Get the VESA Display Monitor Timing (DMT), if any.
340  *
341  * NULL is returned if the standard timing doesn't have a DMT.
342  */
343 const struct di_dmt_timing *
344 di_edid_standard_timing_get_dmt(const struct di_edid_standard_timing *t);
345 
346 /**
347  * Get a list of EDID standard timings.
348  *
349  * The returned array is NULL-terminated.
350  */
351 const struct di_edid_standard_timing *const *
352 di_edid_get_standard_timings(const struct di_edid *edid);
353 
354 /**
355  * Stereo viewing support.
356  */
357 enum di_edid_detailed_timing_def_stereo {
358 	/* Normal Display – No Stereo */
359 	DI_EDID_DETAILED_TIMING_DEF_STEREO_NONE,
360 	/* Field sequential stereo, right image when stereo sync signal = 1 */
361 	DI_EDID_DETAILED_TIMING_DEF_STEREO_FIELD_SEQ_RIGHT,
362 	/* Field sequential stereo, left image when stereo sync signal = 1 */
363 	DI_EDID_DETAILED_TIMING_DEF_STEREO_FIELD_SEQ_LEFT,
364 	/* 2-way interleaved stereo, right image on even lines */
365 	DI_EDID_DETAILED_TIMING_DEF_STEREO_2_WAY_INTERLEAVED_RIGHT,
366 	/* 2-way interleaved stereo, left image on even lines */
367 	DI_EDID_DETAILED_TIMING_DEF_STEREO_2_WAY_INTERLEAVED_LEFT,
368 	/* 4-way interleaved stereo */
369 	DI_EDID_DETAILED_TIMING_DEF_STEREO_4_WAY_INTERLEAVED,
370 	/* Side-by-Side interleaved stereo */
371 	DI_EDID_DETAILED_TIMING_DEF_STEREO_SIDE_BY_SIDE_INTERLEAVED,
372 };
373 
374 /**
375  * Signal definitions for EDID detailed timings, defined in notes for table 3.22.
376  */
377 enum di_edid_detailed_timing_def_signal_type {
378 	/* Analog composite */
379 	DI_EDID_DETAILED_TIMING_DEF_SIGNAL_ANALOG_COMPOSITE = 0x00,
380 	/* Bipolar analog composite */
381 	DI_EDID_DETAILED_TIMING_DEF_SIGNAL_BIPOLAR_ANALOG_COMPOSITE = 0x01,
382 	/* Digital composite */
383 	DI_EDID_DETAILED_TIMING_DEF_SIGNAL_DIGITAL_COMPOSITE = 0x02,
384 	/* Digital separate */
385 	DI_EDID_DETAILED_TIMING_DEF_SIGNAL_DIGITAL_SEPARATE = 0x03,
386 };
387 
388 /**
389  * Digital separate sync polarity for EDID detailed timings.
390  */
391 enum di_edid_detailed_timing_def_sync_polarity {
392 	DI_EDID_DETAILED_TIMING_DEF_SYNC_NEGATIVE = 0,
393 	DI_EDID_DETAILED_TIMING_DEF_SYNC_POSITIVE = 1,
394 };
395 
396 /**
397  * Flags for ANALOG_COMPOSITE signals
398  */
399 struct di_edid_detailed_timing_analog_composite {
400 	/* Sync with serrations (H-sync during V-sync) */
401 	bool sync_serrations;
402 	/* Sync on green signal only (as opposed to all three
403 	 * RGB video signals) */
404 	bool sync_on_green;
405 };
406 
407 /**
408  * Flags for BIPOLAR_ANALOG_COMPOSITE signals
409  */
410 struct di_edid_detailed_timing_bipolar_analog_composite {
411 	/* Sync with serrations (H-sync during V-sync) */
412 	bool sync_serrations;
413 	/* Sync on green signal only (as opposed to all three
414 	 * RGB video signals) */
415 	bool sync_on_green;
416 };
417 
418 /**
419  * Flags for DIGITAL_COMPOSITE signals
420  */
421 struct di_edid_detailed_timing_digital_composite {
422 	/* Sync with serrations (H-sync during V-sync) */
423 	bool sync_serrations;
424 	/* Horizontal polarity (outside of V-sync) */
425 	enum di_edid_detailed_timing_def_sync_polarity sync_horiz_polarity;
426 };
427 
428 /**
429  * Flags for DIGITAL_SEPARATE signals
430  */
431 struct di_edid_detailed_timing_digital_separate {
432 	/* Vertical polarity */
433 	enum di_edid_detailed_timing_def_sync_polarity sync_vert_polarity;
434 	/* Horizontal polarity (outside of V-sync) */
435 	enum di_edid_detailed_timing_def_sync_polarity sync_horiz_polarity;
436 };
437 
438 /**
439  * EDID detailed timing definition, defined in section 3.10.2.
440  */
441 struct di_edid_detailed_timing_def {
442 	/* Pixel clock */
443 	int32_t pixel_clock_hz;
444 	/* Horizontal/Vertical Addressable Video in pixels/lines */
445 	int32_t horiz_video, vert_video;
446 	/* Horizontal/Vertical Blanking in pixels/lines */
447 	int32_t horiz_blank, vert_blank;
448 	/* Horizontal/Vertical Front Porch in pixels/lines */
449 	int32_t horiz_front_porch, vert_front_porch;
450 	/* Horizontal/Vertical Sync Pulse Width in pixels/lines */
451 	int32_t horiz_sync_pulse, vert_sync_pulse;
452 	/* Horizontal/Vertical Addressable Video Image Size in mm, zero if unset */
453 	int32_t horiz_image_mm, vert_image_mm;
454 	/* Horizontal/Vertical Border in pixels/lines */
455 	int32_t horiz_border, vert_border;
456 	/* Interlaced signal */
457 	bool interlaced;
458 	/* Stereo Viewing Support */
459 	enum di_edid_detailed_timing_def_stereo stereo;
460 	/* Signal type */
461 	enum di_edid_detailed_timing_def_signal_type signal_type;
462 	/* Flags for ANALOG_COMPOSITE signals, NULL otherwise */
463 	const struct di_edid_detailed_timing_analog_composite *analog_composite;
464 	/* Flags for BIPOLAR_ANALOG_COMPOSITE signals, NULL otherwise */
465 	const struct di_edid_detailed_timing_bipolar_analog_composite *bipolar_analog_composite;
466 	/* Flags for DIGITAL_COMPOSITE signals, NULL otherwise */
467 	const struct di_edid_detailed_timing_digital_composite *digital_composite;
468 	/* Flags for DIGITAL_SEPARATE signals, NULL otherwise */
469 	const struct di_edid_detailed_timing_digital_separate *digital_separate;
470 };
471 
472 /**
473  * Get a list of EDID detailed timing definitions.
474  *
475  * The returned array is NULL-terminated.
476  */
477 const struct di_edid_detailed_timing_def *const *
478 di_edid_get_detailed_timing_defs(const struct di_edid *edid);
479 
480 /**
481  * EDID display descriptor.
482  */
483 struct di_edid_display_descriptor;
484 
485 /**
486  * Get a list of EDID display descriptors.
487  *
488  * The returned array is NULL-terminated.
489  */
490 const struct di_edid_display_descriptor *const *
491 di_edid_get_display_descriptors(const struct di_edid *edid);
492 
493 /**
494  * EDID display descriptor tag, defined in section 3.10.3.
495  */
496 enum di_edid_display_descriptor_tag {
497 	/* Display Product Serial Number */
498 	DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_SERIAL = 0xFF,
499 	/* Alphanumeric Data String (ASCII) */
500 	DI_EDID_DISPLAY_DESCRIPTOR_DATA_STRING = 0xFE,
501 	/* Display Range Limits */
502 	DI_EDID_DISPLAY_DESCRIPTOR_RANGE_LIMITS = 0xFD,
503 	/* Display Product Name */
504 	DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_NAME = 0xFC,
505 	/* Color Point Data */
506 	DI_EDID_DISPLAY_DESCRIPTOR_COLOR_POINT = 0xFB,
507 	/* Standard Timing Identifications */
508 	DI_EDID_DISPLAY_DESCRIPTOR_STD_TIMING_IDS = 0xFA,
509 	/* Display Color Management (DCM) Data */
510 	DI_EDID_DISPLAY_DESCRIPTOR_DCM_DATA = 0xF9,
511 	/* CVT 3 Byte Timing Codes */
512 	DI_EDID_DISPLAY_DESCRIPTOR_CVT_TIMING_CODES = 0xF8,
513 	/* Established Timings III */
514 	DI_EDID_DISPLAY_DESCRIPTOR_ESTABLISHED_TIMINGS_III = 0xF7,
515 	/* Dummy Descriptor */
516 	DI_EDID_DISPLAY_DESCRIPTOR_DUMMY = 0x10,
517 };
518 
519 /**
520  * Get the tag of an EDID display descriptor.
521  */
522 enum di_edid_display_descriptor_tag
523 di_edid_display_descriptor_get_tag(const struct di_edid_display_descriptor *desc);
524 
525 /**
526  * Get the contents of a product serial number, a data string, or a product name
527  * display descriptor.
528  *
529  * Returns NULL if the display descriptor tag isn't either
530  * DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_SERIAL_NUMBER,
531  * DI_EDID_DISPLAY_DESCRIPTOR_DATA_STRING or
532  * DI_EDID_DISPLAY_DESCRIPTOR_PRODUCT_NAME.
533  */
534 const char *
535 di_edid_display_descriptor_get_string(const struct di_edid_display_descriptor *desc);
536 
537 /**
538  * EDID display range limits type.
539  *
540  * The values do not match the EDID specification.
541  *
542  * The CVT entry was introduced in EDID 1.4.
543  */
544 enum di_edid_display_range_limits_type {
545 	/* Range Limits Only - no additional timing information is provided */
546 	DI_EDID_DISPLAY_RANGE_LIMITS_BARE,
547 	/* Default GTF supported */
548 	DI_EDID_DISPLAY_RANGE_LIMITS_DEFAULT_GTF,
549 	/* Secondary GTF supported */
550 	DI_EDID_DISPLAY_RANGE_LIMITS_SECONDARY_GTF,
551 	/* CVT supported */
552 	DI_EDID_DISPLAY_RANGE_LIMITS_CVT,
553 };
554 
555 struct di_edid_display_range_limits_secondary_gtf {
556 	/* Start break frequency in Hz */
557 	int start_freq_hz;
558 	/* C, M, K, J parameters */
559 	float c, m, k, j;
560 };
561 
562 enum di_edid_cvt_aspect_ratio {
563 	DI_EDID_CVT_ASPECT_RATIO_4_3 = 1 << 7,
564 	DI_EDID_CVT_ASPECT_RATIO_16_9 = 1 << 6,
565 	DI_EDID_CVT_ASPECT_RATIO_16_10 = 1 << 5,
566 	DI_EDID_CVT_ASPECT_RATIO_5_4 = 1 << 4,
567 	DI_EDID_CVT_ASPECT_RATIO_15_9 = 1 << 3,
568 };
569 
570 enum di_edid_cvt_scaling {
571 	DI_EDID_CVT_SCALING_HORIZ_SHRINK = 1 << 7,
572 	DI_EDID_CVT_SCALING_HORIZ_STRETCH = 1 << 6,
573 	DI_EDID_CVT_SCALING_VERT_SHRINK = 1 << 5,
574 	DI_EDID_CVT_SCALING_VERT_STRETCH = 1 << 4,
575 };
576 
577 struct di_edid_display_range_limits_cvt {
578 	int32_t version, revision;
579 	/* Maximum active pixels per line, zero for no limit */
580 	int32_t max_horiz_px;
581 	/* Supported aspect ratio, bitfield of enum di_edid_cvt_aspect_ratio */
582 	uint32_t supported_aspect_ratio;
583 	/* Preferred aspect ratio */
584 	enum di_edid_cvt_aspect_ratio preferred_aspect_ratio;
585 	/* Whether standard CVT blanking is supported */
586 	bool standard_blanking;
587 	/* Whether reduced CVT blanking is supported */
588 	bool reduced_blanking;
589 	/* Supported types of display scaling, bitfield of
590 	 * enum di_edid_cvt_scaling */
591 	uint32_t supported_scaling;
592 	/* Preferred vertical refresh rate, in Hz */
593 	int32_t preferred_vert_refresh_hz;
594 };
595 
596 /**
597  * EDID display range limits, defined in section 3.10.3.3.1.
598  */
599 struct di_edid_display_range_limits {
600 	/* Vertical rate limits in Hz, from 1 Hz to 510 Hz */
601 	int32_t min_vert_rate_hz, max_vert_rate_hz;
602 	/* Horizontal rate limits in Hz, from 1 KHz to 510 KHz, rounded to the
603 	 * nearest multiple of 1 KHz */
604 	int32_t min_horiz_rate_hz, max_horiz_rate_hz;
605 
606 	/* Maximum pixel clock in Hz, zero if unset, rounded to the nearest
607 	 * multiple of 0.25 MHz if CVT, otherwise to the nearest multiple of
608 	 * 10 MHz */
609 	int64_t max_pixel_clock_hz;
610 
611 	enum di_edid_display_range_limits_type type;
612 
613 	/* For SECONDARY_GTF limits, NULL otherwise */
614 	const struct di_edid_display_range_limits_secondary_gtf *secondary_gtf;
615 	/* For CVT limits, NULL otherwise */
616 	const struct di_edid_display_range_limits_cvt *cvt;
617 };
618 
619 /**
620  * Get the contents of a display range limits descriptor.
621  *
622  * Returns NULL if the display descriptor tag isn't
623  * DI_EDID_DISPLAY_DESCRIPTOR_RANGE_LIMITS.
624  */
625 const struct di_edid_display_range_limits *
626 di_edid_display_descriptor_get_range_limits(const struct di_edid_display_descriptor *desc);
627 
628 /**
629  * Get a standard timing list from an EDID display descriptor.
630  *
631  * The returned array is NULL-terminated.
632  *
633  * Returns NULL if the display descriptor tag isn't
634  * DI_EDID_DISPLAY_DESCRIPTOR_STD_TIMING_IDS.
635  */
636 const struct di_edid_standard_timing *const *
637 di_edid_display_descriptor_get_standard_timings(const struct di_edid_display_descriptor *desc);
638 
639 /**
640  * EDID Color Points, defined in section 3.10.3.5.
641  */
642 struct di_edid_color_point {
643 	/* White point index number */
644 	int index;
645 	/* The white chromaticity values, accurate to the thousandth place */
646 	float white_x, white_y;
647 	/* Gamma, zero if unset (ie, stored in an extension block) */
648 	float gamma;
649 };
650 
651 /**
652  * Get a color point list from an EDID display descriptor.
653  *
654  * The returned array is NULL-terminated.
655  *
656  * Returns NULL if the display descriptor tag isn't
657  * DI_EDID_DISPLAY_DESCRIPTOR_COLOR_POINT.
658  *
659  * Upstream is not aware of any EDID blob containing Color Point Descriptors.
660  * If such a blob is found, please share it with upstream!
661  */
662 const struct di_edid_color_point *const *
663 di_edid_display_descriptor_get_color_points(const struct di_edid_display_descriptor *desc);
664 
665 /**
666  * Get a list of established timings III from an EDID display descriptor.
667  *
668  * The returned array is NULL-terminated.
669  *
670  * Returns NULL if the display descriptor tag isn't
671  * DI_EDID_DISPLAY_DESCRIPTOR_ESTABLISHED_TIMINGS_III.
672  */
673 const struct di_dmt_timing *const *
674 di_edid_display_descriptor_get_established_timings_iii(const struct di_edid_display_descriptor *desc);
675 
676 /**
677  * EDID display Color Management Data, defined in section 3.10.3.7
678  *
679  * Contains the coefficients for the function `L = a₃ × v³ + a₂ × v²`
680  * describing the luminance response L to some voltage v [0, 0.7] for each color
681  * channel.
682  *
683  * For more information see VESA DCM Standard, Version 1; January 6, 2003
684  */
685 struct di_edid_color_management_data {
686 	int version;
687 	/* red polynomial coefficient a3 */
688 	float red_a3;
689 	/* red polynomial coefficient a2 */
690 	float red_a2;
691 	/* green polynomial coefficient a3 */
692 	float green_a3;
693 	/* green polynomial coefficient a2 */
694 	float green_a2;
695 	/* blue polynomial coefficient a3 */
696 	float blue_a3;
697 	/* blue polynomial coefficient a2 */
698 	float blue_a2;
699 };
700 
701 /**
702  * Get the contents of a Display Color Management (DCM) Data descriptor.
703  *
704  * Returns NULL if the display descriptor tag isn't
705  * DI_EDID_DISPLAY_DESCRIPTOR_DCM_DATA.
706  *
707  * Upstream is not aware of any EDID blob containing DCM Data descriptors.
708  * If such a blob is found, please share it with upstream!
709  */
710 const struct di_edid_color_management_data *
711 di_edid_display_descriptor_get_color_management_data(const struct di_edid_display_descriptor *desc);
712 
713 /**
714  * Aspect ratio for an EDID CVT Timing Code.
715  */
716 enum di_edid_cvt_timing_code_aspect_ratio {
717 	DI_EDID_CVT_TIMING_CODE_4_3 = 0, /* 4:3 */
718 	DI_EDID_CVT_TIMING_CODE_16_9 = 1, /* 16:9 */
719 	DI_EDID_CVT_TIMING_CODE_16_10 = 2, /* 16:10 */
720 	DI_EDID_CVT_TIMING_CODE_15_9 = 3, /* 15:9 */
721 };
722 
723 /**
724  * Preferred Vertical Rate for an EDID CVT Timing Code.
725  */
726 enum di_edid_cvt_timing_code_preferred_vrate {
727 	DI_EDID_CVT_TIMING_CODE_PREFERRED_VRATE_50HZ = 0, /* 50 Hz */
728 	DI_EDID_CVT_TIMING_CODE_PREFERRED_VRATE_60HZ = 1, /* 60 Hz */
729 	DI_EDID_CVT_TIMING_CODE_PREFERRED_VRATE_75HZ = 2, /* 75 Hz */
730 	DI_EDID_CVT_TIMING_CODE_PREFERRED_VRATE_85HZ = 3, /* 85 Hz */
731 };
732 
733 /**
734  * EDID CVT Timing Code, defined in section 3.10.3.8
735  *
736  * For more information see VESA Coordinated Video Timings (CVT) Standard.
737  */
738 struct di_edid_cvt_timing_code {
739 	int32_t addressable_lines_per_field;
740 	enum di_edid_cvt_timing_code_aspect_ratio aspect_ratio;
741 	bool supports_50hz_sb;
742 	bool supports_60hz_sb;
743 	bool supports_75hz_sb;
744 	bool supports_85hz_sb;
745 	bool supports_60hz_rb;
746 	enum di_edid_cvt_timing_code_preferred_vrate preferred_vertical_rate;
747 };
748 
749 /**
750  * Get a list of CVT timing codes from an EDID display descriptor.
751  * The highest priority code comes first, the lowest priority code last.
752  *
753  * The returned array is NULL-terminated.
754  *
755  * Returns NULL if the display descriptor tag isn't
756  * DI_EDID_DISPLAY_DESCRIPTOR_CVT_TIMING_CODES.
757  */
758 const struct di_edid_cvt_timing_code *const *
759 di_edid_display_descriptor_get_cvt_timing_codes(const struct di_edid_display_descriptor *desc);
760 
761 /**
762  * Get a list of EDID extensions.
763  *
764  * The returned array is NULL-terminated.
765  */
766 const struct di_edid_ext *const *
767 di_edid_get_extensions(const struct di_edid *edid);
768 
769 /**
770  * EDID extension block tags, defined in section 2.2.4.
771  */
772 enum di_edid_ext_tag {
773 	/* CEA 861 Series Extension */
774 	DI_EDID_EXT_CEA = 0x02,
775 	/* Video Timing Block Extension */
776 	DI_EDID_EXT_VTB = 0x10,
777 	/* Display Information Extension */
778 	DI_EDID_EXT_DI = 0x40,
779 	/* Localized String Extension */
780 	DI_EDID_EXT_LS = 0x50,
781 	/* Digital Packet Video Link Extension */
782 	DI_EDID_EXT_DPVL = 0x60,
783 	/* Extension Block Map */
784 	DI_EDID_EXT_BLOCK_MAP = 0xF0,
785 	/* Extension defined by the display manufacturer */
786 	DI_EDID_EXT_VENDOR = 0xFF,
787 
788 	/* DisplayID Extension */
789 	DI_EDID_EXT_DISPLAYID = 0x70,
790 };
791 
792 /**
793  * EDID extension block.
794  */
795 struct di_edid_ext;
796 
797 /**
798  * Get the tag of an EDID extension block.
799  */
800 enum di_edid_ext_tag
801 di_edid_ext_get_tag(const struct di_edid_ext *ext);
802 
803 /* See <libdisplay-info/cta.h> */
804 struct di_edid_cta;
805 
806 /**
807  * Get a CTA-861 extension block.
808  *
809  * Returns NULL if the extension block tag is not DI_EDID_EXT_CEA.
810  */
811 const struct di_edid_cta *
812 di_edid_ext_get_cta(const struct di_edid_ext *ext);
813 
814 /* See <libdisplay-info/displayid.h> */
815 struct di_displayid;
816 
817 /**
818  * Get a DisplayID extension block.
819  *
820  * Returns NULL if the extension block tag is not DI_EDID_EXT_DISPLAYID.
821  */
822 const struct di_displayid *
823 di_edid_ext_get_displayid(const struct di_edid_ext *ext);
824 
825 #endif
826