• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef DI_DISPLAYID_H
2 #define DI_DISPLAYID_H
3 
4 /**
5  * libdisplay-info's low-level API for VESA Display Identification Data
6  * (DisplayID).
7  *
8  * The library implements DisplayID version 1.3, available at:
9  * https://vesa.org/vesa-standards/
10  */
11 
12 #include <stdbool.h>
13 #include <stdint.h>
14 
15 /**
16  * DisplayID data structure.
17  */
18 struct di_displayid;
19 
20 /**
21  * Get the DisplayID version.
22  */
23 int
24 di_displayid_get_version(const struct di_displayid *displayid);
25 
26 /**
27  * Get the DisplayID revision.
28  */
29 int
30 di_displayid_get_revision(const struct di_displayid *displayid);
31 
32 /**
33  * Product type identifier, defined in section 2.3.
34  */
35 enum di_displayid_product_type {
36 	/* Extension section */
37 	DI_DISPLAYID_PRODUCT_TYPE_EXTENSION = 0x00,
38 	/* Test structure or equipment */
39 	DI_DISPLAYID_PRODUCT_TYPE_TEST = 0x01,
40 	/* Display panel or other transducer, LCD or PDP module, etc. */
41 	DI_DISPLAYID_PRODUCT_TYPE_DISPLAY_PANEL = 0x02,
42 	/* Standalone display device, desktop monitor, TV monitor, etc. */
43 	DI_DISPLAYID_PRODUCT_TYPE_STANDALONE_DISPLAY = 0x03,
44 	/* Television receiver */
45 	DI_DISPLAYID_PRODUCT_TYPE_TV_RECEIVER = 0x04,
46 	/* Repeater/translator */
47 	DI_DISPLAYID_PRODUCT_TYPE_REPEATER = 0x05,
48 	/* Direct drive monitor */
49 	DI_DISPLAYID_PRODUCT_TYPE_DIRECT_DRIVE = 0x06,
50 };
51 
52 /**
53  * Get the DisplayID product type.
54  */
55 enum di_displayid_product_type
56 di_displayid_get_product_type(const struct di_displayid *displayid);
57 
58 /**
59  * DisplayID data block tag.
60  */
61 enum di_displayid_data_block_tag {
62 	/*Product Identification Data Block */
63 	DI_DISPLAYID_DATA_BLOCK_PRODUCT_ID = 0x00,
64 	/* Display Parameters Data Block */
65 	DI_DISPLAYID_DATA_BLOCK_DISPLAY_PARAMS = 0x01,
66 	/* Color Characteristics Data Block */
67 	DI_DISPLAYID_DATA_BLOCK_COLOR_CHARACT = 0x02,
68 	/* Video Timing Modes Type I - Detailed Timings Data Block */
69 	DI_DISPLAYID_DATA_BLOCK_TYPE_I_TIMING = 0x03,
70 	/* Video Timing Modes Type II - Detailed Timings Data Block */
71 	DI_DISPLAYID_DATA_BLOCK_TYPE_II_TIMING = 0x04,
72 	/* Video Timing Modes Type III - Short Timings Data Block */
73 	DI_DISPLAYID_DATA_BLOCK_TYPE_III_TIMING = 0x05,
74 	/* Video Timing Modes Type IV - DMT Timings Data Block */
75 	DI_DISPLAYID_DATA_BLOCK_TYPE_IV_TIMING = 0x06,
76 	/* Supported Timing Modes - VESA DMT Timings Data Block */
77 	DI_DISPLAYID_DATA_BLOCK_VESA_TIMING = 0x07,
78 	/* Supported Timing Modes - CTA-861 Timings Data Block */
79 	DI_DISPLAYID_DATA_BLOCK_CEA_TIMING = 0x08,
80 	/* Video Timing Range Data Block */
81 	DI_DISPLAYID_DATA_BLOCK_TIMING_RANGE_LIMITS = 0x09,
82 	/* Product Serial Number Data Block */
83 	DI_DISPLAYID_DATA_BLOCK_PRODUCT_SERIAL = 0x0A,
84 	/* General-purpose ASCII String Data Block */
85 	DI_DISPLAYID_DATA_BLOCK_ASCII_STRING = 0x0B,
86 	/* Display Device Data Data Block */
87 	DI_DISPLAYID_DATA_BLOCK_DISPLAY_DEVICE_DATA = 0x0C,
88 	/* Interface Power Sequencing Data Block */
89 	DI_DISPLAYID_DATA_BLOCK_INTERFACE_POWER_SEQ = 0x0D,
90 	/* Transfer Characteristics Data Block */
91 	DI_DISPLAYID_DATA_BLOCK_TRANSFER_CHARACT = 0x0E,
92 	/* Display Interface Data Block */
93 	DI_DISPLAYID_DATA_BLOCK_DISPLAY_INTERFACE = 0x0F,
94 	/* Stereo Display Interface Data Block */
95 	DI_DISPLAYID_DATA_BLOCK_STEREO_DISPLAY_INTERFACE = 0x10,
96 	/* Video Timing Modes Type V - Short Timings Data Block */
97 	DI_DISPLAYID_DATA_BLOCK_TYPE_V_TIMING = 0x11,
98 	/* Tiled Display Topology Data Block */
99 	DI_DISPLAYID_DATA_BLOCK_TILED_DISPLAY_TOPO = 0x12,
100 	/* Video Timing Modes Type VI - Detailed Timings Data Block */
101 	DI_DISPLAYID_DATA_BLOCK_TYPE_VI_TIMING = 0x13,
102 };
103 
104 /**
105  * A DisplayID data block.
106  */
107 struct di_displayid_data_block;
108 
109 /**
110  * Get a DisplayID data block tag.
111  */
112 enum di_displayid_data_block_tag
113 di_displayid_data_block_get_tag(const struct di_displayid_data_block *data_block);
114 
115 /**
116  * Display parameters feature support flags, defined in section 4.2.3.
117  */
118 struct di_displayid_display_params_features {
119 	/* Audio support on video interface */
120 	bool audio;
121 	/* Audio inputs are provided separately from the video interface */
122 	bool separate_audio_inputs;
123 	/* Audio information received via the video interface will automatically
124 	 * override any other audio input channels provided */
125 	bool audio_input_override;
126 	/* Display supports the VESA Display Power Management (DPM) standard */
127 	bool power_management;
128 	/* Display is capable of only a single fixed timing */
129 	bool fixed_timing;
130 	/* Display is capable of supporting timings at only a single fixed pixel
131 	 * format */
132 	bool fixed_pixel_format;
133 	/* Display supports ACP, ISRC1 or ISRC2 packets */
134 	bool ai;
135 	/* Display by default will de-interlace any interlaced video input */
136 	bool deinterlacing;
137 };
138 
139 /**
140  * Display parameters data block, defined in section 4.2.
141  */
142 struct di_displayid_display_params {
143 	/* Image size in millimeters accurate to the thenths place, zero if unset */
144 	float horiz_image_mm, vert_image_mm;
145 	/* Native format size in pixels, zero if unset */
146 	int32_t horiz_pixels, vert_pixels;
147 	/* Feature flags */
148 	const struct di_displayid_display_params_features *features;
149 	/* Transfer characteristic gamma, zero if unset */
150 	float gamma;
151 	/* Aspect ratio (long axis divided by short axis) */
152 	float aspect_ratio;
153 	/* Color bit depth (dynamic range) */
154 	int32_t bits_per_color_overall, bits_per_color_native;
155 };
156 
157 /**
158  * Get display parameters from a DisplayID data block.
159  *
160  * Returns NULL if the data block tag isn't
161  * DI_DISPLAYID_DATA_BLOCK_DISPLAY_PARAMS.
162  */
163 const struct di_displayid_display_params *
164 di_displayid_data_block_get_display_params(const struct di_displayid_data_block *data_block);
165 
166 enum di_displayid_type_i_ii_vii_timing_stereo_3d {
167 	/* This timing is always displayed monoscopic (no stereo) */
168 	DI_DISPLAYID_TYPE_I_II_VII_TIMING_STEREO_3D_NEVER = 0x00,
169 	/* This timing is always displayed in stereo */
170 	DI_DISPLAYID_TYPE_I_II_VII_TIMING_STEREO_3D_ALWAYS = 0x01,
171 	/* This timing is displayed in mono or stereo depending on a user action
172 	 * (wearing the stereo glasses, etc.) */
173 	DI_DISPLAYID_TYPE_I_II_VII_TIMING_STEREO_3D_USER = 0x02,
174 };
175 
176 enum di_displayid_timing_aspect_ratio {
177 	DI_DISPLAYID_TIMING_ASPECT_RATIO_1_1 = 0x00,
178 	DI_DISPLAYID_TIMING_ASPECT_RATIO_5_4 = 0x01,
179 	DI_DISPLAYID_TIMING_ASPECT_RATIO_4_3 = 0x02,
180 	DI_DISPLAYID_TIMING_ASPECT_RATIO_15_9 = 0x03,
181 	DI_DISPLAYID_TIMING_ASPECT_RATIO_16_9 = 0x04,
182 	DI_DISPLAYID_TIMING_ASPECT_RATIO_16_10 = 0x05,
183 	DI_DISPLAYID_TIMING_ASPECT_RATIO_64_27 = 0x06,
184 	DI_DISPLAYID_TIMING_ASPECT_RATIO_256_135 = 0x07,
185 	DI_DISPLAYID_TIMING_ASPECT_RATIO_UNDEFINED = 0x08,
186 };
187 
188 enum di_displayid_type_i_ii_vii_timing_sync_polarity {
189 	DI_DISPLAYID_TYPE_I_II_VII_TIMING_SYNC_NEGATIVE = 0x00,
190 	DI_DISPLAYID_TYPE_I_II_VII_TIMING_SYNC_POSITIVE = 0x01,
191 };
192 
193 /**
194  * Type I timing, defined in DisplayID 1.3 section 4.4.1 and
195  * Type II timing, defined in DisplayID 1.3 section 4.4.2 and
196  * Type VII timing, defined in DisplayID 2.0 section 4.3.1.
197  */
198 struct di_displayid_type_i_ii_vii_timing {
199 	double pixel_clock_mhz; /* mega-hertz */
200 	bool preferred;
201 	enum di_displayid_type_i_ii_vii_timing_stereo_3d stereo_3d;
202 	bool interlaced;
203 	enum di_displayid_timing_aspect_ratio aspect_ratio;
204 	int32_t horiz_active, vert_active;
205 	int32_t horiz_blank, vert_blank;
206 	int32_t horiz_offset, vert_offset;
207 	int32_t horiz_sync_width, vert_sync_width;
208 	enum di_displayid_type_i_ii_vii_timing_sync_polarity horiz_sync_polarity, vert_sync_polarity;
209 };
210 
211 /**
212  * Get type I timings from a DisplayID data block.
213  *
214  * The returned array is NULL-terminated.
215  *
216  * Returns NULL if the data block tag isn't
217  * DI_DISPLAYID_DATA_BLOCK_TYPE_I_TIMING.
218  */
219 const struct di_displayid_type_i_ii_vii_timing *const *
220 di_displayid_data_block_get_type_i_timings(const struct di_displayid_data_block *data_block);
221 
222 /**
223  * Get type II timings from a DisplayID data block.
224  *
225  * The returned array is NULL-terminated.
226  *
227  * Returns NULL if the data block tag isn't
228  * DI_DISPLAYID_DATA_BLOCK_TYPE_II_TIMING.
229  */
230 const struct di_displayid_type_i_ii_vii_timing *const *
231 di_displayid_data_block_get_type_ii_timings(const struct di_displayid_data_block *data_block);
232 
233 /**
234  * Behavior when more than 1 tile and less than total number of tiles are driven
235  * by the source.
236  */
237 enum di_displayid_tiled_topo_missing_recv_behavior {
238 	/* Undefined */
239 	DI_DISPLAYID_TILED_TOPO_MISSING_RECV_UNDEF = 0,
240 	/* The image is displayed on the tile only */
241 	DI_DISPLAYID_TILED_TOPO_MISSING_RECV_TILE_ONLY = 1,
242 };
243 
244 /**
245  * Behavior of this tile when it is the only tile receiving an image from the
246  * source.
247  */
248 enum di_displayid_tiled_topo_single_recv_behavior {
249 	/* Undefined */
250 	DI_DISPLAYID_TILED_TOPO_SINGLE_RECV_UNDEF = 0,
251 	/* Image is displayed on the tile only */
252 	DI_DISPLAYID_TILED_TOPO_SINGLE_RECV_TILE_ONLY = 1,
253 	/* Image is scaled to fit the entire tiled display */
254 	DI_DISPLAYID_TILED_TOPO_SINGLE_RECV_SCALED = 2,
255 	/* Image is cloned to all other tiles of the entire tiled display */
256 	DI_DISPLAYID_TILED_TOPO_SINGLE_RECV_CLONED = 3,
257 };
258 
259 /**
260  * Tiled display capabilities.
261  */
262 struct di_displayid_tiled_topo_caps {
263 	/* The tiled display is within a single physical display enclosure */
264 	bool single_enclosure;
265 
266 	/* Behavior when subsets of the tiles of the entire tiled display are
267 	 * receiving images from source */
268 	enum di_displayid_tiled_topo_missing_recv_behavior missing_recv_behavior;
269 	enum di_displayid_tiled_topo_single_recv_behavior single_recv_behavior;
270 };
271 
272 /**
273  * Tiled display bezel information.
274  *
275  * The lengths are measured in pixels, accurate to the tenths place.
276  */
277 struct di_displayid_tiled_topo_bezel {
278 	float top_px, bottom_px, right_px, left_px;
279 };
280 
281 /**
282  * Tiled display topology, defined in section 4.14.
283  */
284 struct di_displayid_tiled_topo {
285 	/* Capabilities */
286 	const struct di_displayid_tiled_topo_caps *caps;
287 
288 	/* Total number of horizontal/vertical tiles */
289 	int32_t total_horiz_tiles, total_vert_tiles;
290 	/* Horizontal/vertical tile location */
291 	int32_t horiz_tile_location, vert_tile_location;
292 	/* Horizontal/vertical size in pixels */
293 	int32_t horiz_tile_pixels, vert_tile_lines;
294 
295 	/* Bezel information, NULL if unset */
296 	const struct di_displayid_tiled_topo_bezel *bezel;
297 
298 	/* Vendor PnP ID, product code and serial number */
299 	char vendor_id[3];
300 	uint16_t product_code;
301 	uint32_t serial_number;
302 };
303 
304 /**
305  * Get tiled display topology from a DisplayID data block.
306  *
307  * Returns NULL if the data block tag isn't
308  * DI_DISPLAYID_DATA_BLOCK_TILED_DISPLAY_TOPO.
309  */
310 const struct di_displayid_tiled_topo *
311 di_displayid_data_block_get_tiled_topo(const struct di_displayid_data_block *data_block);
312 
313 /**
314  * Formula/algorithm for type III timings.
315  */
316 enum di_displayid_type_iii_timing_algo {
317 	/* VESA CVT, standard blanking */
318 	DI_DISPLAYID_TYPE_III_TIMING_CVT_STANDARD_BLANKING = 0,
319 	/* VESA CVT, reduced blanking */
320 	DI_DISPLAYID_TYPE_III_TIMING_CVT_REDUCED_BLANKING = 1,
321 };
322 
323 /**
324  * Type III timing, defined in section 4.4.3.
325  */
326 struct di_displayid_type_iii_timing {
327 	bool preferred;
328 	enum di_displayid_type_iii_timing_algo algo;
329 	enum di_displayid_timing_aspect_ratio aspect_ratio;
330 	/* Horizontal Active Image (in pixels) */
331 	int32_t horiz_active;
332 	bool interlaced;
333 	/* Frame/Field Refresh Rate (in Hz) */
334 	int32_t refresh_rate_hz;
335 };
336 
337 /**
338  * Get type III timings from a DisplayID data block.
339  *
340  * The returned array is NULL-terminated.
341  *
342  * Returns NULL if the data block tag isn't
343  * DI_DISPLAYID_DATA_BLOCK_TYPE_III_TIMING.
344  */
345 const struct di_displayid_type_iii_timing *const *
346 di_displayid_data_block_get_type_iii_timings(const struct di_displayid_data_block *data_block);
347 
348 /**
349  * Get DisplayID data blocks.
350  *
351  * The returned array is NULL-terminated.
352  */
353 const struct di_displayid_data_block *const *
354 di_displayid_get_data_blocks(const struct di_displayid *displayid);
355 
356 #endif
357