1/*
2 * Copyright 2003, Thomas Kurschel. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Copyright 2006-2013 Haiku, Inc. All rights reserved.
6 * Distributed under the terms of the MIT License.
7 *
8 * Authors:
9 *	Thomas Kurschel
10 *	Bill Randle, billr@neocat.org
11 */
12#ifndef _EDID_RAW_H
13#define _EDID_RAW_H
14
15
16#include "bendian_bitfield.h"
17
18
19/*!	Raw EDID data block.
20
21	Raw data are packed in a really weird way. Never even
22	think about using it directly, instead translate it via decode_edid()
23	first.
24*/
25
26#define EDID1_NUM_DETAILED_MONITOR_DESC 4
27#define EDID1_NUM_STD_TIMING 8
28#define EDID1_NUM_EXTRA_STD_TIMING 6
29#define EDID1_EXTRA_STRING_LEN 13
30#define EDID1_NUM_EXTRA_WHITEPOINTS 2
31
32
33// header
34typedef struct _PACKED {
35	int8 pad[8];		// contains 0, -1, -1, -1, -1, -1, -1, 0
36} edid1_header_raw;
37
38
39// vendor info
40typedef struct _PACKED {
41	BBITFIELD8_3 (		// manufacturer
42		pad : 1,
43		c1 : 5,			// add '@' to get ascii
44		c2_high : 2
45	);
46	BBITFIELD8_2 (
47		c2_low : 3,
48		c3 : 5
49	);
50	uint16 prod_id;
51	uint32 serial;
52	uint8 week;
53	uint8 year;			// x+1990
54} edid1_vendor_raw;
55
56
57// version info
58typedef struct _PACKED {
59	uint8 version;
60	uint8 revision;
61} edid1_version_raw;
62
63
64// analog input parameters
65typedef struct _PACKED {
66	BBITFIELD8_7 (
67		input_type : 1,		// 0 : analog, 1 : digital
68		input_voltage : 2,	// 0=0.7V/0.3V, 1=0.714V/0.286,
69							// 2=1V/0.4V, 3=0.7V/0V
70		setup : 1,			// true if voltage configurable
71		sep_sync : 1,
72		comp_sync : 1,
73		sync_on_green : 1,
74		sync_serr : 1
75	);
76} edid1_analog_params_raw;
77
78
79// digital input parameters
80typedef struct _PACKED {
81	BBITFIELD8_3 (
82		input_type : 1,	// 0 : analog, 1 : digital
83		bit_depth : 3,	// 0=undefined, 1=6,2=8,3=10,4=12,5=14,6=16,7=reserved
84		interface : 4	// 0=undefined, 1=DVI, 2=HDMIa, 3=HDMIb
85						// 4=MDDI, 5=DisplayPort
86	);
87} edid1_digital_params_raw;
88
89
90// display info
91typedef struct _PACKED {
92	union {
93		edid1_analog_params_raw	analog_params;
94		edid1_digital_params_raw digital_params;
95	};
96	uint8 h_size;
97	uint8 v_size;
98	uint8 gamma;	// (x+100)/100
99	BBITFIELD8_7 (
100		dpms_standby : 1,
101		dpms_suspend : 1,
102		dpms_off : 1,
103		display_type : 2,	// 0=mono, 1=rgb, 2=multicolour
104		// since EDID version 1.1
105		std_colour_space : 1,
106		preferred_timing_mode : 1,
107		gtf_supported : 1
108	);
109	BBITFIELD8_4 (		// low bits of red_x etc.
110		red_x_low : 2,
111		red_y_low : 2,
112		green_x_low : 2,
113		green_y_low : 2
114	);
115	BBITFIELD8_4 (
116		blue_x_low : 2,
117		blue_y_low : 2,
118		white_x_low : 2,
119		white_y_low : 2
120	);
121	uint8 red_x;		// all colours are 0.10 fixed point
122	uint8 red_y;
123	uint8 green_x;
124	uint8 green_y;
125	uint8 blue_x;
126	uint8 blue_y;
127	uint8 white_x;
128	uint8 white_y;
129} edid1_display_raw;
130
131
132// raw standard timing data
133typedef union _PACKED {
134	struct _PACKED {
135		uint8 h_size;		// (x+31)*8
136		BBITFIELD8_2 (
137			ratio : 2,		// 0=1:1, 1=3/4, 2=4/5, 3=9/16
138			refresh : 6		// (x+60)
139		);
140	} timing;
141	uint16 id;
142} edid1_std_timing_raw;
143
144
145// list of supported fixed timings
146typedef struct _PACKED {
147	BBITFIELD8_8 (
148		res_720x400x70 : 1,
149		res_720x400x88 : 1,
150		res_640x480x60 : 1,
151		res_640x480x67 : 1,
152		res_640x480x72 : 1,
153		res_640x480x75 : 1,
154		res_800x600x56 : 1,
155		res_800x600x60 : 1
156	);
157	BBITFIELD8_8 (
158		res_800x600x72 : 1,
159		res_800x600x75 : 1,
160		res_832x624x75 : 1,
161		res_1024x768x87i : 1,
162		res_1024x768x60 : 1,
163		res_1024x768x70 : 1,
164		res_1024x768x75 : 1,
165		res_1280x1024x75 : 1
166	);
167	BBITFIELD8_2 (
168		res_1152x870x75 : 1,
169		pad : 7
170	);
171} edid1_established_timing;
172
173
174// types of detailed monitor description
175enum {
176	EDID1_SERIAL_NUMBER = 0xff,
177	EDID1_ASCII_DATA = 0xfe,
178	EDID1_MONITOR_RANGES = 0xfd,
179	EDID1_MONITOR_NAME = 0xfc,
180	EDID1_ADD_COLOUR_POINTER = 0xfb,
181	EDID1_ADD_STD_TIMING = 0xfa,
182	EDID1_IS_DETAILED_TIMING = 1
183};
184
185
186// monitor frequency range
187typedef struct _PACKED {
188	uint8 min_v;
189	uint8 max_v;
190	uint8 min_h;
191	uint8 max_h;
192	uint8 max_clock;	// in 10 MHz (!)
193} edid1_monitor_range;
194
195
196// additional whitepoint
197typedef struct _PACKED {
198	uint8 index1;
199	BBITFIELD8_3 (
200		pad1 : 4,
201		white_x1_low : 2,
202		white_y1_low : 2
203	);
204	uint8 white_x1;
205	uint8 white_y1;
206	uint8 gamma1;	// (x+100)/100
207	uint8 index2;
208	BBITFIELD8_3 (
209		pad2 : 4,
210		white_x2_low : 2,
211		white_y2_low : 2
212	);
213	uint8 white_x2;
214	uint8 white_y2;
215	uint8 gamma2;	// (x+100)/100
216} edid1_whitepoint_raw;
217
218
219// detailed timing description
220typedef struct _PACKED {
221	uint16 pixel_clock; // in 10 kHz (!)
222	uint8 h_active;
223	uint8 h_blank;
224	BBITFIELD8_2 (
225		h_active_high : 4,
226		h_blank_high : 4
227	);
228	uint8 v_active;
229	uint8 v_blank;
230	BBITFIELD8_2 (
231		v_active_high : 4,
232		v_blank_high : 4
233	);
234	uint8 h_sync_off;
235	uint8 h_sync_width;
236	BBITFIELD8_2 (
237		v_sync_off : 4,
238		v_sync_width : 4
239	);
240	BBITFIELD8_4 (
241		h_sync_off_high : 2,
242		h_sync_width_high : 2,
243		v_sync_off_high : 2,
244		v_sync_width_high : 2
245	);
246	uint8 h_size;
247	uint8 v_size;
248	BBITFIELD8_2 (
249		h_size_high : 4,
250		v_size_high : 4
251	);
252	uint8 h_border;
253	uint8 v_border;
254	BBITFIELD8_5 (
255		interlaced : 1,
256		stereo : 2,		// upper bit set - left on sync
257						// lower bit set - right on sync
258		sync : 2,
259		misc : 2,
260		stereo_il : 1
261	);
262} edid1_detailed_timing_raw;
263
264
265// detailed monitor description
266typedef union _PACKED {
267	edid1_detailed_timing_raw detailed_timing;
268	struct _PACKED {
269		uint8 zero_0[3];
270		uint8 monitor_desc_type;
271		uint8 zero_4;
272		union _PACKED {
273			uint8 serial_number[EDID1_EXTRA_STRING_LEN];
274			uint8 ascii_data[EDID1_EXTRA_STRING_LEN];
275			uint8 monitor_name[EDID1_EXTRA_STRING_LEN];
276			edid1_monitor_range monitor_range;
277			edid1_whitepoint_raw whitepoint;
278			edid1_std_timing_raw std_timing[EDID1_NUM_EXTRA_STD_TIMING];
279		} data;
280	} extra;
281} edid1_detailed_monitor_raw;
282
283
284// raw EDID data
285// everything is packed data, mixture of little endian and big endian
286// and a bit brain dead overall - nothing your dad would be proud of
287typedef struct _PACKED {
288	edid1_header_raw header; 						// 8 bytes
289	edid1_vendor_raw vendor;						// 10 bytes
290	edid1_version_raw version;						// 2 bytes
291	edid1_display_raw display;						// 15 bytes
292	edid1_established_timing established_timing;	// 3 bytes
293	edid1_std_timing_raw std_timing[EDID1_NUM_STD_TIMING];
294													// 8 a 2 bytes -> 16 bytes
295
296	// since EDID version 1.2
297	edid1_detailed_monitor_raw detailed_monitor[EDID1_NUM_DETAILED_MONITOR_DESC];
298													// 4 a 18 bytes -> 72 bytes
299
300	uint8 num_sections; 							// 1 byte
301	uint8 check_sum;								// 1 byte
302} edid1_raw;										// total: 128 bytes
303
304typedef union _PACKED {
305	struct _PACKED {
306		BBITFIELD8_3 (
307			reserved : 1,
308			format_code : 4,
309			reserved2 : 3
310		);
311	} descr;
312	struct _PACKED {
313		BBITFIELD8_3 (
314			reserved : 1,
315			format_code : 4,
316			max_channels : 3
317		);
318		BBITFIELD8_8 (
319			reserved2 : 1,
320			can_192khz : 1,
321			can_176khz : 1,
322			can_96khz : 1,
323			can_88khz : 1,
324			can_48khz : 1,
325			can_44khz : 1,
326			can_32khz : 1
327		);
328		BBITFIELD8_4 (
329			reserved3 : 5,
330			can_24bit : 1,
331			can_20bit : 1,
332			can_16bit : 1
333		);
334	} descr_1;
335	struct _PACKED {
336		BBITFIELD8_3 (
337			reserved : 1,
338			format_code : 4,
339			max_channels : 3
340		);
341		BBITFIELD8_8 (
342			reserved2 : 1,
343			can_192khz : 1,
344			can_176khz : 1,
345			can_96khz : 1,
346			can_88khz : 1,
347			can_48khz : 1,
348			can_44khz : 1,
349			can_32khz : 1
350		);
351		uint8 maximum_bitrate;
352	} descr_2_8;
353
354} audio_descr;
355
356#if !defined(__GNUC__) || __GNUC__ < 3
357#define FLEXIBLE_ARRAY_LENGTH 0
358#else
359#define FLEXIBLE_ARRAY_LENGTH
360#endif
361typedef struct _PACKED {
362	BBITFIELD8_2 (
363		tag_code : 3,
364		length : 5
365	);
366	union _PACKED {
367		uint8 extended_tag_code;
368
369		struct _PACKED {
370			uint8 vic0;
371			uint8 vic[FLEXIBLE_ARRAY_LENGTH];
372		} video;
373
374		struct _PACKED {
375			audio_descr desc0;
376			audio_descr desc[FLEXIBLE_ARRAY_LENGTH];
377		} audio;
378
379		struct _PACKED {
380			uint8 ouinum0;
381			uint8 ouinum1;
382			uint8 ouinum2;
383			union _PACKED {
384				struct _PACKED {
385					struct _PACKED {
386						BBITFIELD8_2 (
387							a : 4,
388							b : 4
389						);
390						BBITFIELD8_2 (
391							c : 4,
392							d : 4
393						);
394					} source_physical_address;
395					BBITFIELD8_7 (
396						supports_ai : 1,
397						dc_48bit : 1,
398						dc_36bit : 1,
399						dc_30bit : 1,
400						dc_y444 : 1,
401						reserved : 2,
402						dvi_dual : 1
403					);
404					uint8 max_tmds_clock;
405					uint8 reserved2[2];
406					BBITFIELD8_2 (
407						vic_length : 3,
408						length_3d : 5
409					);
410					uint8 vic[FLEXIBLE_ARRAY_LENGTH];
411				} hdmi;
412				struct _PACKED {
413					uint8 version;
414					uint8 max_tmds_rate;
415					BBITFIELD8_8 (
416						scdc_present : 1,
417						scdc_read_request_capable : 1,
418						supports_cable_status : 1,
419						supports_color_content_bits : 1,
420						supports_scrambling : 1,
421						supports_3d_independent : 1,
422						supports_3d_dual_view : 1,
423						supports_3d_osd_disparity : 1
424					);
425					BBITFIELD8_5 (
426						max_frl_rate : 4,
427						supports_uhd_vic : 1,
428						supports_16bit_deep_color_4_2_0 : 1,
429						supports_12bit_deep_color_4_2_0 : 1,
430						supports_10bit_deep_color_4_2_0 : 1
431					);
432				} hdmi_forum;
433			};
434		} vendor_specific;
435
436		struct _PACKED {
437			BBITFIELD8_8 (
438				FLW_FRW : 1,
439				RLC_RRC : 1,
440				FLC_FRC : 1,
441				BC : 1,
442				BL_BR : 1,
443				FC : 1,
444				LFE : 1,
445				FL_FR : 1
446			);
447			BBITFIELD8_8 (
448				TpSiL_TpSiR : 1,
449				SiL_SiR : 1,
450				TpBC : 1,
451				LFE2 : 1,
452				LS_RS : 1,
453				TpFC : 1,
454				TpC : 1,
455				TpFL_TpFH : 1
456			);
457			BBITFIELD8_6 (
458				reserved: 3,
459				LSd_RSd : 1,
460				TpLS_TpRS : 1,
461				BtFL_BtFR : 1,
462				BtFC : 1,
463				TpBL_TpBR : 1
464			);
465		} speaker_allocation_map;
466
467		struct _PACKED {
468			uint8 extended_tag_code;
469			BBITFIELD8_8 (
470				BT2020RGB : 1,
471				BT2020YCC : 1,
472				BT2020cYCC : 1,
473				opRGB : 1,
474				opYCC601 : 1,
475				sYCC601 : 1,
476				xvYCC709 : 1,
477				xvYCC601 : 1
478			);
479			BBITFIELD8_2 (
480				DCIP3 : 1,
481				reserved : 7
482			);
483		} colorimetry;
484
485		struct _PACKED {
486			uint8 extended_tag_code;
487			uint8 bitmap[FLEXIBLE_ARRAY_LENGTH];
488		} YCbCr_4_2_0_capability_map;
489
490		struct _PACKED {
491			uint8 extended_tag_code;
492			BBITFIELD8_5 (
493				QY : 1,
494				QS : 1,
495				S_PT : 2,
496				S_IT : 2,
497				S_CE : 2
498			);
499		} video_capability;
500
501		struct _PACKED {
502			uint8 extended_tag_code;
503			BBITFIELD8_7 (
504				reserved : 2,
505				ET_5 : 1,
506				ET_4 : 1,
507				ET_3 : 1,
508				ET_2 : 1,
509				ET_1 : 1,
510				ET_0 : 1
511			);
512			BBITFIELD8_8 (
513				SM_7 : 1,
514				SM_6 : 1,
515				SM_5 : 1,
516				SM_4 : 1,
517				SM_3 : 1,
518				SM_2 : 1,
519				SM_1 : 1,
520				SM_0 : 1
521			);
522			uint8 desired_content_max_luminance;
523			uint8 desired_content_max_frame_average_luminance;
524			uint8 desired_content_min_luminance;
525		} hdr_static_metadata;
526
527		struct _PACKED {
528			uint8 extended_tag_code;
529			// TODO extend
530		} hdr_dyn_metadata;
531
532		uint8 buffer[127];
533	};
534} cta_data_block;
535
536typedef struct _PACKED {
537	uint8 tag;
538	uint8 revision;
539	uint8 offset;
540	BBITFIELD8_5 (
541		underscan : 1,
542		audio : 1,
543		ycbcr444 : 1,
544		ycbcr422 : 1,
545		num_native_detailed : 4
546	);
547	cta_data_block data_blocks[0];
548
549	uint8 reserved[123];
550	uint8 check_sum;								// 1 byte
551} cta_raw;											// total: 128 bytes
552
553typedef struct _PACKED {
554	uint8 tag;
555	uint8 version;
556	uint8 length;
557	uint8 reserved;
558	uint8 extension_count;
559	uint8 reserved2[123];
560} displayid_raw;									// total: 128 bytes
561
562#endif
563