• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <assert.h>
2 #include <errno.h>
3 #include <inttypes.h>
4 #include <math.h>
5 #include <stdlib.h>
6 #include <string.h>
7 
8 #include "bits.h"
9 #include "cta.h"
10 #include "log.h"
11 #include "edid.h"
12 #include "displayid.h"
13 
14 /**
15  * Number of bytes in the CTA header (tag + revision + DTD offset + flags).
16  */
17 #define CTA_HEADER_SIZE 4
18 /**
19  * Exclusive upper bound for the detailed timing definitions in the CTA block.
20  */
21 #define CTA_DTD_END 127
22 /**
23  * Number of bytes in a CTA short audio descriptor.
24  */
25 #define CTA_SAD_SIZE 3
26 /**
27  * Number of bytes in a HDMI 3D audio descriptor.
28  */
29 #define CTA_HDMI_AUDIO_3D_DESCRIPTOR_SIZE 4
30 
31 const struct di_cta_video_format *
di_cta_video_format_from_vic(uint8_t vic)32 di_cta_video_format_from_vic(uint8_t vic)
33 {
34 	if (vic > _di_cta_video_formats_len ||
35 	    _di_cta_video_formats[vic].vic == 0)
36 		return NULL;
37 	return &_di_cta_video_formats[vic];
38 }
39 
40 static void
add_failure(struct di_edid_cta * cta,const char fmt[],...)41 add_failure(struct di_edid_cta *cta, const char fmt[], ...)
42 {
43 	va_list args;
44 
45 	va_start(args, fmt);
46 	_di_logger_va_add_failure(cta->logger, fmt, args);
47 	va_end(args);
48 }
49 
50 static void
add_failure_until(struct di_edid_cta * cta,int revision,const char fmt[],...)51 add_failure_until(struct di_edid_cta *cta, int revision, const char fmt[], ...)
52 {
53 	va_list args;
54 
55 	if (cta->revision > revision) {
56 		return;
57 	}
58 
59 	va_start(args, fmt);
60 	_di_logger_va_add_failure(cta->logger, fmt, args);
61 	va_end(args);
62 }
63 
64 static struct di_cta_svd *
parse_svd(struct di_edid_cta * cta,uint8_t raw,const char * prefix)65 parse_svd(struct di_edid_cta *cta, uint8_t raw, const char *prefix)
66 {
67 	struct di_cta_svd svd, *svd_ptr;
68 
69 	if (raw == 0 || raw == 128 || raw >= 254) {
70 		/* Reserved */
71 		add_failure_until(cta, 3,
72 				  "%s: Unknown VIC %" PRIu8 ".",
73 				  prefix,
74 				  raw);
75 		return NULL;
76 	} else if (raw <= 127 || raw >= 193) {
77 		svd = (struct di_cta_svd) {
78 			.vic = raw,
79 		};
80 	} else {
81 		svd = (struct di_cta_svd) {
82 			.vic = get_bit_range(raw, 6, 0),
83 			.native = true,
84 		};
85 	}
86 
87 	svd_ptr = calloc(1, sizeof(*svd_ptr));
88 	if (!svd_ptr)
89 		return NULL;
90 	*svd_ptr = svd;
91 	return svd_ptr;
92 }
93 
94 static bool
parse_video_block(struct di_edid_cta * cta,struct di_cta_video_block * video,const uint8_t * data,size_t size)95 parse_video_block(struct di_edid_cta *cta, struct di_cta_video_block *video,
96 		  const uint8_t *data, size_t size)
97 {
98 	size_t i;
99 	struct di_cta_svd *svd;
100 
101 	if (size == 0)
102 		add_failure(cta, "Video Data Block: Empty Data Block");
103 
104 	for (i = 0; i < size; i++) {
105 		svd = parse_svd(cta, data[i], "Video Data Block");
106 		if (!svd)
107 			continue;
108 		assert(video->svds_len < EDID_CTA_MAX_VIDEO_BLOCK_ENTRIES);
109 		video->svds[video->svds_len++] = svd;
110 	}
111 
112 	return true;
113 }
114 
115 static bool
parse_ycbcr420_block(struct di_edid_cta * cta,struct di_cta_video_block * ycbcr420,const uint8_t * data,size_t size)116 parse_ycbcr420_block(struct di_edid_cta *cta,
117 		     struct di_cta_video_block *ycbcr420,
118 		     const uint8_t *data, size_t size)
119 {
120 	size_t i;
121 	struct di_cta_svd *svd;
122 
123 	if (size == 0)
124 		add_failure(cta, "YCbCr 4:2:0 Video Data Block: Empty Data Block");
125 
126 	for (i = 0; i < size; i++) {
127 		svd = parse_svd(cta, data[i], "YCbCr 4:2:0 Video Data Block");
128 		if (!svd)
129 			continue;
130 		assert(ycbcr420->svds_len < EDID_CTA_MAX_VIDEO_BLOCK_ENTRIES);
131 		ycbcr420->svds[ycbcr420->svds_len++] = svd;
132 	}
133 
134 	return true;
135 }
136 
137 static bool
parse_sad_format(struct di_edid_cta * cta,uint8_t code,uint8_t code_ext,enum di_cta_audio_format * format,const char * prefix)138 parse_sad_format(struct di_edid_cta *cta, uint8_t code, uint8_t code_ext,
139 		 enum di_cta_audio_format *format, const char *prefix)
140 {
141 	switch (code) {
142 	case 0x0:
143 		add_failure_until(cta, 3, "%s: Audio Format Code 0x00 is reserved.", prefix);
144 		return false;
145 	case 0x1:
146 		*format = DI_CTA_AUDIO_FORMAT_LPCM;
147 		break;
148 	case 0x2:
149 		*format = DI_CTA_AUDIO_FORMAT_AC3;
150 		break;
151 	case 0x3:
152 		*format = DI_CTA_AUDIO_FORMAT_MPEG1;
153 		break;
154 	case 0x4:
155 		*format = DI_CTA_AUDIO_FORMAT_MP3;
156 		break;
157 	case 0x5:
158 		*format = DI_CTA_AUDIO_FORMAT_MPEG2;
159 		break;
160 	case 0x6:
161 		*format = DI_CTA_AUDIO_FORMAT_AAC_LC;
162 		break;
163 	case 0x7:
164 		*format = DI_CTA_AUDIO_FORMAT_DTS;
165 		break;
166 	case 0x8:
167 		*format = DI_CTA_AUDIO_FORMAT_ATRAC;
168 		break;
169 	case 0x9:
170 		*format = DI_CTA_AUDIO_FORMAT_ONE_BIT_AUDIO;
171 		break;
172 	case 0xA:
173 		*format = DI_CTA_AUDIO_FORMAT_ENHANCED_AC3;
174 		break;
175 	case 0xB:
176 		*format = DI_CTA_AUDIO_FORMAT_DTS_HD;
177 		break;
178 	case 0xC:
179 		*format = DI_CTA_AUDIO_FORMAT_MAT;
180 		break;
181 	case 0xD:
182 		*format = DI_CTA_AUDIO_FORMAT_DST;
183 		break;
184 	case 0xE:
185 		*format = DI_CTA_AUDIO_FORMAT_WMA_PRO;
186 		break;
187 	case 0xF:
188 		switch (code_ext) {
189 		case 0x04:
190 			*format = DI_CTA_AUDIO_FORMAT_MPEG4_HE_AAC;
191 			break;
192 		case 0x05:
193 			*format = DI_CTA_AUDIO_FORMAT_MPEG4_HE_AAC_V2;
194 			break;
195 		case 0x06:
196 			*format = DI_CTA_AUDIO_FORMAT_MPEG4_AAC_LC;
197 			break;
198 		case 0x07:
199 			*format = DI_CTA_AUDIO_FORMAT_DRA;
200 			break;
201 		case 0x08:
202 			*format = DI_CTA_AUDIO_FORMAT_MPEG4_HE_AAC_MPEG_SURROUND;
203 			break;
204 		case 0x0A:
205 			*format = DI_CTA_AUDIO_FORMAT_MPEG4_AAC_LC_MPEG_SURROUND;
206 			break;
207 		case 0x0B:
208 			*format = DI_CTA_AUDIO_FORMAT_MPEGH_3D;
209 			break;
210 		case 0x0C:
211 			*format = DI_CTA_AUDIO_FORMAT_AC4;
212 			break;
213 		case 0x0D:
214 			*format = DI_CTA_AUDIO_FORMAT_LPCM_3D;
215 			break;
216 		default:
217 			add_failure_until(cta, 3, "%s: Unknown Audio Ext Format 0x%02x.",
218 					  prefix, code_ext);
219 			return false;
220 		}
221 		break;
222 	default:
223 		add_failure_until(cta, 3, "%s: Unknown Audio Format 0x%02x.", prefix, code);
224 		return false;
225 	}
226 
227 	return true;
228 }
229 
230 static bool
parse_sad(struct di_edid_cta * cta,struct di_cta_audio_block * audio,const uint8_t data[static CTA_SAD_SIZE])231 parse_sad(struct di_edid_cta *cta, struct di_cta_audio_block *audio,
232 	  const uint8_t data[static CTA_SAD_SIZE])
233 {
234 	enum di_cta_audio_format format;
235 	struct di_cta_sad_priv *priv;
236 	struct di_cta_sad *sad;
237 	struct di_cta_sad_sample_rates *sample_rates;
238 	struct di_cta_sad_lpcm *lpcm;
239 	struct di_cta_sad_mpegh_3d *mpegh_3d;
240 	struct di_cta_sad_mpeg_aac *mpeg_aac;
241 	struct di_cta_sad_mpeg_surround *mpeg_surround;
242 	struct di_cta_sad_mpeg_aac_le *mpeg_aac_le;
243 	struct di_cta_sad_enhanced_ac3 *enhanced_ac3;
244 	struct di_cta_sad_mat *mat;
245 	struct di_cta_sad_wma_pro *wma_pro;
246 	uint8_t code, code_ext;
247 
248 	code = get_bit_range(data[0], 6, 3);
249 	code_ext = get_bit_range(data[2], 7, 3);
250 
251 	if (!parse_sad_format(cta, code, code_ext, &format, "Audio Data Block"))
252 		return true;
253 
254 	priv = calloc(1, sizeof(*priv));
255 	if (!priv)
256 		return false;
257 
258 	sad = &priv->base;
259 	sample_rates = &priv->supported_sample_rates;
260 	lpcm = &priv->lpcm;
261 	mpegh_3d = &priv->mpegh_3d;
262 	mpeg_aac = &priv->mpeg_aac;
263 	mpeg_surround = &priv->mpeg_surround;
264 	mpeg_aac_le = &priv->mpeg_aac_le;
265 	enhanced_ac3 = &priv->enhanced_ac3;
266 	mat = &priv->mat;
267 	wma_pro = &priv->wma_pro;
268 
269 	sad->format = format;
270 
271 	/* TODO: Find DRA documentation */
272 
273 	switch (format) {
274 	case DI_CTA_AUDIO_FORMAT_LPCM:
275 	case DI_CTA_AUDIO_FORMAT_AC3:
276 	case DI_CTA_AUDIO_FORMAT_MPEG1:
277 	case DI_CTA_AUDIO_FORMAT_MP3:
278 	case DI_CTA_AUDIO_FORMAT_MPEG2:
279 	case DI_CTA_AUDIO_FORMAT_AAC_LC:
280 	case DI_CTA_AUDIO_FORMAT_DTS:
281 	case DI_CTA_AUDIO_FORMAT_ATRAC:
282 	case DI_CTA_AUDIO_FORMAT_ONE_BIT_AUDIO:
283 	case DI_CTA_AUDIO_FORMAT_ENHANCED_AC3:
284 	case DI_CTA_AUDIO_FORMAT_DTS_HD:
285 	case DI_CTA_AUDIO_FORMAT_MAT:
286 	case DI_CTA_AUDIO_FORMAT_DST:
287 	case DI_CTA_AUDIO_FORMAT_WMA_PRO:
288 	case DI_CTA_AUDIO_FORMAT_MPEG4_HE_AAC:
289 	case DI_CTA_AUDIO_FORMAT_MPEG4_HE_AAC_V2:
290 	case DI_CTA_AUDIO_FORMAT_MPEG4_AAC_LC:
291 	/* DRA is not documented but this is what edid-decode does */
292 	case DI_CTA_AUDIO_FORMAT_DRA:
293 	case DI_CTA_AUDIO_FORMAT_MPEG4_HE_AAC_MPEG_SURROUND:
294 	case DI_CTA_AUDIO_FORMAT_MPEG4_AAC_LC_MPEG_SURROUND:
295 		sad->max_channels = get_bit_range(data[0], 2, 0) + 1;
296 		break;
297 	case DI_CTA_AUDIO_FORMAT_LPCM_3D:
298 		sad->max_channels = (get_bit_range(data[0], 2, 0) |
299 				     (get_bit_range(data[0], 7, 7) << 3) |
300 				     (get_bit_range(data[1], 7, 7) << 4)) + 1;
301 		break;
302 	case DI_CTA_AUDIO_FORMAT_MPEGH_3D:
303 	case DI_CTA_AUDIO_FORMAT_AC4:
304 		break;
305 	}
306 
307 	switch (format) {
308 	case DI_CTA_AUDIO_FORMAT_LPCM:
309 	case DI_CTA_AUDIO_FORMAT_AC3:
310 	case DI_CTA_AUDIO_FORMAT_MPEG1:
311 	case DI_CTA_AUDIO_FORMAT_MP3:
312 	case DI_CTA_AUDIO_FORMAT_MPEG2:
313 	case DI_CTA_AUDIO_FORMAT_AAC_LC:
314 	case DI_CTA_AUDIO_FORMAT_DTS:
315 	case DI_CTA_AUDIO_FORMAT_ATRAC:
316 	case DI_CTA_AUDIO_FORMAT_ONE_BIT_AUDIO:
317 	case DI_CTA_AUDIO_FORMAT_ENHANCED_AC3:
318 	case DI_CTA_AUDIO_FORMAT_DTS_HD:
319 	case DI_CTA_AUDIO_FORMAT_MAT:
320 	case DI_CTA_AUDIO_FORMAT_DST:
321 	case DI_CTA_AUDIO_FORMAT_WMA_PRO:
322 	/* DRA is not documented but this is what edid-decode does */
323 	case DI_CTA_AUDIO_FORMAT_DRA:
324 	case DI_CTA_AUDIO_FORMAT_MPEGH_3D:
325 	case DI_CTA_AUDIO_FORMAT_LPCM_3D:
326 		sample_rates->has_192_khz = has_bit(data[1], 6);
327 		sample_rates->has_176_4_khz = has_bit(data[1], 5);
328 		/* fallthrough */
329 	case DI_CTA_AUDIO_FORMAT_MPEG4_HE_AAC:
330 	case DI_CTA_AUDIO_FORMAT_MPEG4_HE_AAC_V2:
331 	case DI_CTA_AUDIO_FORMAT_MPEG4_AAC_LC:
332 	case DI_CTA_AUDIO_FORMAT_MPEG4_HE_AAC_MPEG_SURROUND:
333 	case DI_CTA_AUDIO_FORMAT_MPEG4_AAC_LC_MPEG_SURROUND:
334 		sample_rates->has_96_khz = has_bit(data[1], 4);
335 		sample_rates->has_88_2_khz = has_bit(data[1], 3);
336 		sample_rates->has_48_khz = has_bit(data[1], 2);
337 		sample_rates->has_44_1_khz = has_bit(data[1], 1);
338 		sample_rates->has_32_khz = has_bit(data[1], 0);
339 		break;
340 	case DI_CTA_AUDIO_FORMAT_AC4:
341 		sample_rates->has_192_khz = has_bit(data[1], 6);
342 		sample_rates->has_96_khz = has_bit(data[1], 4);
343 		sample_rates->has_48_khz = has_bit(data[1], 2);
344 		sample_rates->has_44_1_khz = has_bit(data[1], 1);
345 		break;
346 	}
347 	sad->supported_sample_rates = sample_rates;
348 
349 	switch (format) {
350 	case DI_CTA_AUDIO_FORMAT_AC3:
351 	case DI_CTA_AUDIO_FORMAT_MPEG1:
352 	case DI_CTA_AUDIO_FORMAT_MP3:
353 	case DI_CTA_AUDIO_FORMAT_MPEG2:
354 	case DI_CTA_AUDIO_FORMAT_AAC_LC:
355 	case DI_CTA_AUDIO_FORMAT_DTS:
356 	case DI_CTA_AUDIO_FORMAT_ATRAC:
357 		sad->max_bitrate_kbs = data[2] * 8;
358 		break;
359 	default:
360 		break;
361 	}
362 
363 	switch (format) {
364 	case DI_CTA_AUDIO_FORMAT_LPCM:
365 	case DI_CTA_AUDIO_FORMAT_LPCM_3D:
366 		lpcm->has_sample_size_24_bits = has_bit(data[2], 2);
367 		lpcm->has_sample_size_20_bits = has_bit(data[2], 1);
368 		lpcm->has_sample_size_16_bits = has_bit(data[2], 0);
369 		sad->lpcm = lpcm;
370 	default:
371 		break;
372 	}
373 
374 	switch (format) {
375 	case DI_CTA_AUDIO_FORMAT_MPEG4_HE_AAC:
376 	case DI_CTA_AUDIO_FORMAT_MPEG4_HE_AAC_V2:
377 	case DI_CTA_AUDIO_FORMAT_MPEG4_AAC_LC:
378 	case DI_CTA_AUDIO_FORMAT_MPEG4_HE_AAC_MPEG_SURROUND:
379 	case DI_CTA_AUDIO_FORMAT_MPEG4_AAC_LC_MPEG_SURROUND:
380 		mpeg_aac->has_frame_length_1024 = has_bit(data[2], 2);
381 		mpeg_aac->has_frame_length_960 = has_bit(data[2], 1);
382 		sad->mpeg_aac = mpeg_aac;
383 		break;
384 	default:
385 		break;
386 	}
387 
388 	if (format == DI_CTA_AUDIO_FORMAT_MPEG4_AAC_LC) {
389 		mpeg_aac_le->supports_multichannel_sound = has_bit(data[2], 0);
390 		sad->mpeg_aac_le = mpeg_aac_le;
391 	}
392 
393 	switch (format) {
394 	case DI_CTA_AUDIO_FORMAT_MPEG4_HE_AAC_MPEG_SURROUND:
395 	case DI_CTA_AUDIO_FORMAT_MPEG4_AAC_LC_MPEG_SURROUND:
396 		mpeg_surround->signaling = has_bit(data[2], 0);
397 		sad->mpeg_surround = mpeg_surround;
398 		break;
399 	default:
400 		break;
401 	}
402 
403 	if (format == DI_CTA_AUDIO_FORMAT_MPEGH_3D) {
404 		mpegh_3d->low_complexity_profile = has_bit(data[2], 0);
405 		mpegh_3d->baseline_profile = has_bit(data[2], 1);
406 		mpegh_3d->level = get_bit_range(data[0], 2, 0);
407 		if (mpegh_3d->level > DI_CTA_SAD_MPEGH_3D_LEVEL_5) {
408 			add_failure_until(cta, 3,
409 					  "Unknown MPEG-H 3D Audio Level 0x%02x.",
410 					  mpegh_3d->level);
411 			mpegh_3d->level = DI_CTA_SAD_MPEGH_3D_LEVEL_UNSPECIFIED;
412 		}
413 		sad->mpegh_3d = mpegh_3d;
414 	}
415 
416 	if (format == DI_CTA_AUDIO_FORMAT_ENHANCED_AC3) {
417 		enhanced_ac3->supports_joint_object_coding =
418 			has_bit(data[2], 0);
419 		enhanced_ac3->supports_joint_object_coding_ACMOD28 =
420 			has_bit(data[2], 1);
421 		sad->enhanced_ac3 = enhanced_ac3;
422 	}
423 
424 	if (format == DI_CTA_AUDIO_FORMAT_MAT) {
425 		mat->supports_object_audio_and_channel_based =
426 			has_bit(data[2], 0);
427 		if (mat->supports_object_audio_and_channel_based)
428 			mat->requires_hash_calculation = !has_bit(data[2], 0);
429 		sad->mat = mat;
430 	}
431 
432 	if (format == DI_CTA_AUDIO_FORMAT_WMA_PRO) {
433 		wma_pro->profile = get_bit_range(data[2], 2, 0);
434 		sad->wma_pro = wma_pro;
435 	}
436 
437 	switch (format) {
438 	case DI_CTA_AUDIO_FORMAT_ONE_BIT_AUDIO:
439 	case DI_CTA_AUDIO_FORMAT_DTS_HD:
440 	case DI_CTA_AUDIO_FORMAT_DST:
441 		/* TODO data[2] 7:0 contains unknown Audio Format Code dependent value */
442 		break;
443 	default:
444 		break;
445 	}
446 
447 	if (format == DI_CTA_AUDIO_FORMAT_AC4) {
448 		/* TODO data[2] 2:0 contains unknown Audio Format Code dependent value */
449 	}
450 
451 	switch (format) {
452 	case DI_CTA_AUDIO_FORMAT_LPCM:
453 	case DI_CTA_AUDIO_FORMAT_WMA_PRO:
454 		if (has_bit(data[0], 7) || has_bit(data[1], 7) ||
455 		    get_bit_range(data[2], 7, 3) != 0)
456 			add_failure_until(cta, 3,
457 					  "Bits F17, F27, F37:F33 must be 0.");
458 		break;
459 	case DI_CTA_AUDIO_FORMAT_AC3:
460 	case DI_CTA_AUDIO_FORMAT_MPEG1:
461 	case DI_CTA_AUDIO_FORMAT_MP3:
462 	case DI_CTA_AUDIO_FORMAT_MPEG2:
463 	case DI_CTA_AUDIO_FORMAT_AAC_LC:
464 	case DI_CTA_AUDIO_FORMAT_DTS:
465 	case DI_CTA_AUDIO_FORMAT_ATRAC:
466 	case DI_CTA_AUDIO_FORMAT_ONE_BIT_AUDIO:
467 	case DI_CTA_AUDIO_FORMAT_ENHANCED_AC3:
468 	case DI_CTA_AUDIO_FORMAT_DTS_HD:
469 	case DI_CTA_AUDIO_FORMAT_MAT:
470 	case DI_CTA_AUDIO_FORMAT_DST:
471 		if (has_bit(data[0], 7) || has_bit(data[1], 7))
472 			add_failure_until(cta, 3,
473 					  "Bits F17, F27 must be 0.");
474 		break;
475 	case DI_CTA_AUDIO_FORMAT_MPEG4_HE_AAC:
476 	case DI_CTA_AUDIO_FORMAT_MPEG4_HE_AAC_V2:
477 	case DI_CTA_AUDIO_FORMAT_MPEG4_AAC_LC:
478 	case DI_CTA_AUDIO_FORMAT_MPEG4_HE_AAC_MPEG_SURROUND:
479 	case DI_CTA_AUDIO_FORMAT_MPEG4_AAC_LC_MPEG_SURROUND:
480 		if (has_bit(data[0], 7) || get_bit_range(data[2], 7, 5) != 0)
481 			add_failure_until(cta, 3,
482 					  "Bits F17, F27:F25 must be 0.");
483 		break;
484 	case DI_CTA_AUDIO_FORMAT_MPEGH_3D:
485 		if (has_bit(data[0], 7) || has_bit(data[1], 7) ||
486 		    has_bit(data[2], 2))
487 			add_failure_until(cta, 3,
488 					  "Bits F17, F27, F32 must be 0.");
489 		break;
490 	case DI_CTA_AUDIO_FORMAT_AC4:
491 		if ((data[0] & 0x87) != 0 || (data[1] & 0xA9) != 0)
492 			add_failure_until(cta, 3,
493 					  "Bits F17, F12:F10, F27, F25, F23, "
494 					  "F20 must be 0.");
495 		break;
496 	/* DRA documentation missing */
497 	case DI_CTA_AUDIO_FORMAT_DRA:
498 	case DI_CTA_AUDIO_FORMAT_LPCM_3D:
499 		break;
500 	}
501 
502 	assert(audio->sads_len < EDID_CTA_MAX_AUDIO_BLOCK_ENTRIES);
503 	audio->sads[audio->sads_len++] = priv;
504 	return true;
505 }
506 
507 static bool
parse_audio_block(struct di_edid_cta * cta,struct di_cta_audio_block * audio,const uint8_t * data,size_t size)508 parse_audio_block(struct di_edid_cta *cta, struct di_cta_audio_block *audio,
509 		  const uint8_t *data, size_t size)
510 {
511 	size_t i;
512 
513 	if (size % 3 != 0)
514 		add_failure(cta, "Broken CTA-861 audio block length %d.", size);
515 
516 	for (i = 0; i + 3 <= size; i += 3) {
517 		if (!parse_sad(cta, audio, &data[i]))
518 			return false;
519 	}
520 
521 	return true;
522 }
523 
524 static bool
parse_speaker_alloc(struct di_edid_cta * cta,struct di_cta_speaker_allocation * speaker_alloc,const uint8_t data[3],const char * prefix)525 parse_speaker_alloc(struct di_edid_cta *cta, struct di_cta_speaker_allocation *speaker_alloc,
526 		    const uint8_t data[3], const char *prefix)
527 {
528 	bool rlc_rrc;
529 
530 	speaker_alloc->flw_frw = has_bit(data[0], 7);
531 	rlc_rrc = has_bit(data[0], 6);
532 	speaker_alloc->flc_frc = has_bit(data[0], 5);
533 	speaker_alloc->bc = has_bit(data[0], 4);
534 	speaker_alloc->bl_br = has_bit(data[0], 3);
535 	speaker_alloc->fc = has_bit(data[0], 2);
536 	speaker_alloc->lfe1 = has_bit(data[0], 1);
537 	speaker_alloc->fl_fr = has_bit(data[0], 0);
538 	if (rlc_rrc) {
539 		if (cta->revision >= 3)
540 			add_failure(cta, "%s: Deprecated bit F16 must be 0.", prefix);
541 		else
542 			speaker_alloc->bl_br = true;
543 	}
544 
545 	speaker_alloc->tpsil_tpsir = has_bit(data[1], 7);
546 	speaker_alloc->sil_sir = has_bit(data[1], 6);
547 	speaker_alloc->tpbc = has_bit(data[1], 5);
548 	speaker_alloc->lfe2 = has_bit(data[1], 4);
549 	speaker_alloc->ls_rs = has_bit(data[1], 3);
550 	speaker_alloc->tpfc = has_bit(data[1], 2);
551 	speaker_alloc->tpc = has_bit(data[1], 1);
552 	speaker_alloc->tpfl_tpfr = has_bit(data[1], 0);
553 
554 	if (get_bit_range(data[2], 7, 4) != 0)
555 		add_failure(cta, "%s: Bits F37, F36, F34 must be 0.", prefix);
556 	if (cta->revision >= 3 && has_bit(data[2], 3))
557 		add_failure(cta, "%s: Deprecated bit F33 must be 0.", prefix);
558 	speaker_alloc->btfl_btfr = has_bit(data[2], 2);
559 	speaker_alloc->btfc = has_bit(data[2], 1);
560 	speaker_alloc->tpbl_tpbr = has_bit(data[2], 0);
561 
562 	return true;
563 }
564 
565 static bool
parse_speaker_alloc_block(struct di_edid_cta * cta,struct di_cta_speaker_alloc_block * speaker_alloc,const uint8_t * data,size_t size)566 parse_speaker_alloc_block(struct di_edid_cta *cta,
567 			  struct di_cta_speaker_alloc_block *speaker_alloc,
568 			  const uint8_t *data, size_t size)
569 {
570 	if (size < 3) {
571 		add_failure(cta,
572 			    "Speaker Allocation Data Block: Empty Data Block with length %zu.",
573 			    size);
574 		return false;
575 	}
576 
577 	parse_speaker_alloc(cta, &speaker_alloc->speakers, data,
578 			    "Speaker Allocation Data Block");
579 
580 	return true;
581 }
582 
583 static bool
parse_video_cap_block(struct di_edid_cta * cta,struct di_cta_video_cap_block * video_cap,const uint8_t * data,size_t size)584 parse_video_cap_block(struct di_edid_cta *cta,
585 		      struct di_cta_video_cap_block *video_cap,
586 		      const uint8_t *data, size_t size)
587 {
588 	if (size < 1) {
589 		add_failure(cta,
590 			    "Video Capability Data Block: Empty Data Block with length %u.",
591 			    size);
592 		return false;
593 	}
594 
595 	video_cap->selectable_ycc_quantization_range = has_bit(data[0], 7);
596 	video_cap->selectable_rgb_quantization_range = has_bit(data[0], 6);
597 	video_cap->pt_over_underscan = get_bit_range(data[0], 5, 4);
598 	video_cap->it_over_underscan = get_bit_range(data[0], 3, 2);
599 	video_cap->ce_over_underscan = get_bit_range(data[0], 1, 0);
600 
601 	if (!video_cap->selectable_rgb_quantization_range && cta->revision >= 3)
602 		add_failure(cta,
603 			    "Video Capability Data Block: Set Selectable RGB Quantization to avoid interop issues.");
604 	/* TODO: add failure if selectable_ycc_quantization_range is unset,
605 	 * the sink supports YCbCr formats and the revision is 3+ */
606 
607 	switch (video_cap->it_over_underscan) {
608 	case DI_CTA_VIDEO_CAP_ALWAYS_OVERSCAN:
609 		if (cta->flags.it_underscan)
610 			add_failure(cta, "Video Capability Data Block: IT video formats are always overscanned, but bit 7 of Byte 3 of the CTA-861 Extension header is set to underscanned.");
611 		break;
612 	case DI_CTA_VIDEO_CAP_ALWAYS_UNDERSCAN:
613 		if (!cta->flags.it_underscan)
614 			add_failure(cta, "Video Capability Data Block: IT video formats are always underscanned, but bit 7 of Byte 3 of the CTA-861 Extension header is set to overscanned.");
615 	default:
616 		break;
617 	}
618 
619 	return true;
620 }
621 
622 static bool
check_vesa_dddb_num_channels(enum di_cta_vesa_dddb_interface_type interface,uint8_t num_channels)623 check_vesa_dddb_num_channels(enum di_cta_vesa_dddb_interface_type interface,
624 			     uint8_t num_channels)
625 {
626 	switch (interface) {
627 	case DI_CTA_VESA_DDDB_INTERFACE_VGA:
628 	case DI_CTA_VESA_DDDB_INTERFACE_NAVI_V:
629 	case DI_CTA_VESA_DDDB_INTERFACE_NAVI_D:
630 		return num_channels == 0;
631 	case DI_CTA_VESA_DDDB_INTERFACE_LVDS:
632 	case DI_CTA_VESA_DDDB_INTERFACE_RSDS:
633 		return true;
634 	case DI_CTA_VESA_DDDB_INTERFACE_DVI_D:
635 		return num_channels == 1 || num_channels == 2;
636 	case DI_CTA_VESA_DDDB_INTERFACE_DVI_I_ANALOG:
637 		return num_channels == 0;
638 	case DI_CTA_VESA_DDDB_INTERFACE_DVI_I_DIGITAL:
639 		return num_channels == 1 || num_channels == 2;
640 	case DI_CTA_VESA_DDDB_INTERFACE_HDMI_A:
641 		return num_channels == 1;
642 	case DI_CTA_VESA_DDDB_INTERFACE_HDMI_B:
643 		return num_channels == 2;
644 	case DI_CTA_VESA_DDDB_INTERFACE_MDDI:
645 		return num_channels == 1 || num_channels == 2;
646 	case DI_CTA_VESA_DDDB_INTERFACE_DISPLAYPORT:
647 		return num_channels == 1 || num_channels == 2 || num_channels == 4;
648 	case DI_CTA_VESA_DDDB_INTERFACE_IEEE_1394:
649 	case DI_CTA_VESA_DDDB_INTERFACE_M1_ANALOG:
650 		return num_channels == 0;
651 	case DI_CTA_VESA_DDDB_INTERFACE_M1_DIGITAL:
652 		return num_channels == 1 || num_channels == 2;
653 	}
654 	abort(); /* unreachable */
655 }
656 
657 static void
parse_vesa_dddb_additional_primary_chromaticity(struct di_cta_vesa_dddb_additional_primary_chromaticity * coords,uint8_t low,const uint8_t high[static2])658 parse_vesa_dddb_additional_primary_chromaticity(struct di_cta_vesa_dddb_additional_primary_chromaticity *coords,
659 						uint8_t low,
660 						const uint8_t high[static 2])
661 {
662 	uint16_t raw_x, raw_y; /* only 10 bits are used */
663 
664 	raw_x = (uint16_t) ((high[0] << 2) | get_bit_range(low, 3, 2));
665 	raw_y = (uint16_t) ((high[1] << 2) | get_bit_range(low, 1, 0));
666 
667 	*coords = (struct di_cta_vesa_dddb_additional_primary_chromaticity) {
668 		.x = (float) raw_x / 1024,
669 		.y = (float) raw_y / 1024,
670 	};
671 }
672 
673 static bool
parse_vesa_dddb(struct di_edid_cta * cta,struct di_cta_vesa_dddb * dddb,const uint8_t * data,size_t size)674 parse_vesa_dddb(struct di_edid_cta *cta, struct di_cta_vesa_dddb *dddb,
675 		const uint8_t *data, size_t size)
676 {
677 	const size_t offset = 2; /* CTA block header */
678 	uint8_t interface_type, num_channels, content_protection, scan_direction,
679 		subpixel_layout;
680 
681 	if (size + offset != 32) {
682 		add_failure(cta, "VESA Video Display Device Data Block: Invalid length %u.", size);
683 		return false;
684 	}
685 
686 	interface_type = get_bit_range(data[0x02 - offset], 7, 4);
687 	num_channels = get_bit_range(data[0x02 - offset], 3, 0);
688 	switch (interface_type) {
689 	case 0x0: /* Analog */
690 		/* Special case: num_channels contains the detailed interface
691 		 * type. */
692 		switch (num_channels) {
693 		case 0x0:
694 			dddb->interface_type = DI_CTA_VESA_DDDB_INTERFACE_VGA;
695 			break;
696 		case 0x1:
697 			dddb->interface_type = DI_CTA_VESA_DDDB_INTERFACE_NAVI_V;
698 			break;
699 		case 0x2:
700 			dddb->interface_type = DI_CTA_VESA_DDDB_INTERFACE_NAVI_D;
701 			break;
702 		default:
703 			add_failure(cta,
704 				    "VESA Video Display Device Data Block: Unknown analog interface type 0x%x.",
705 				    num_channels);
706 			return false;
707 		}
708 		num_channels = 0;
709 		break;
710 	case 0x1:
711 		dddb->interface_type = DI_CTA_VESA_DDDB_INTERFACE_LVDS;
712 		break;
713 	case 0x2:
714 		dddb->interface_type = DI_CTA_VESA_DDDB_INTERFACE_RSDS;
715 		break;
716 	case 0x3:
717 		dddb->interface_type = DI_CTA_VESA_DDDB_INTERFACE_DVI_D;
718 		break;
719 	case 0x4:
720 		dddb->interface_type = DI_CTA_VESA_DDDB_INTERFACE_DVI_I_ANALOG;
721 		break;
722 	case 0x5:
723 		dddb->interface_type = DI_CTA_VESA_DDDB_INTERFACE_DVI_I_DIGITAL;
724 		break;
725 	case 0x6:
726 		dddb->interface_type = DI_CTA_VESA_DDDB_INTERFACE_HDMI_A;
727 		break;
728 	case 0x7:
729 		dddb->interface_type = DI_CTA_VESA_DDDB_INTERFACE_HDMI_B;
730 		break;
731 	case 0x8:
732 		dddb->interface_type = DI_CTA_VESA_DDDB_INTERFACE_MDDI;
733 		break;
734 	case 0x9:
735 		dddb->interface_type = DI_CTA_VESA_DDDB_INTERFACE_DISPLAYPORT;
736 		break;
737 	case 0xA:
738 		dddb->interface_type = DI_CTA_VESA_DDDB_INTERFACE_IEEE_1394;
739 		break;
740 	case 0xB:
741 		dddb->interface_type = DI_CTA_VESA_DDDB_INTERFACE_M1_ANALOG;
742 		break;
743 	case 0xC:
744 		dddb->interface_type = DI_CTA_VESA_DDDB_INTERFACE_M1_DIGITAL;
745 		break;
746 	default:
747 		add_failure(cta,
748 			    "VESA Video Display Device Data Block: Unknown interface type 0x%x.",
749 			    interface_type);
750 		return false;
751 	}
752 
753 	if (check_vesa_dddb_num_channels(dddb->interface_type, num_channels))
754 		dddb->num_channels = num_channels;
755 	else
756 		add_failure(cta,
757 			    "VESA Video Display Device Data Block: Invalid number of lanes/channels %u.",
758 			    num_channels);
759 
760 	dddb->interface_version = get_bit_range(data[0x03 - offset], 7, 4);
761 	dddb->interface_release = get_bit_range(data[0x03 - offset], 3, 0);
762 
763 	content_protection = data[0x04 - offset];
764 	switch (content_protection) {
765 	case DI_CTA_VESA_DDDB_CONTENT_PROTECTION_NONE:
766 	case DI_CTA_VESA_DDDB_CONTENT_PROTECTION_HDCP:
767 	case DI_CTA_VESA_DDDB_CONTENT_PROTECTION_DTCP:
768 	case DI_CTA_VESA_DDDB_CONTENT_PROTECTION_DPCP:
769 		dddb->content_protection = content_protection;
770 		break;
771 	default:
772 		add_failure(cta,
773 			    "VESA Video Display Device Data Block: Invalid content protection 0x%x.",
774 			    content_protection);
775 	}
776 
777 	dddb->min_clock_freq_mhz = get_bit_range(data[0x05 - offset], 7, 2);
778 	dddb->max_clock_freq_mhz =
779 		(get_bit_range(data[0x05 - offset], 1, 0) << 8) | data[0x06 - offset];
780 	if (dddb->min_clock_freq_mhz > dddb->max_clock_freq_mhz) {
781 		add_failure(cta,
782 			    "VESA Video Display Device Data Block: Minimum clock frequency (%d MHz) greater than maximum (%d MHz).",
783 			    dddb->min_clock_freq_mhz, dddb->max_clock_freq_mhz);
784 		dddb->min_clock_freq_mhz = dddb->max_clock_freq_mhz = 0;
785 	}
786 
787 	dddb->native_horiz_pixels = data[0x07 - offset] | (data[0x08 - offset] << 8);
788 	dddb->native_vert_pixels = data[0x09 - offset] | (data[0x0A - offset] << 8);
789 
790 	dddb->aspect_ratio = (float)data[0x0B - offset] / 100 + 1;
791 	dddb->default_orientation = get_bit_range(data[0x0C - offset], 7, 6);
792 	dddb->rotation_cap = get_bit_range(data[0x0C - offset], 5, 4);
793 	dddb->zero_pixel_location = get_bit_range(data[0x0C - offset], 3, 2);
794 	scan_direction = get_bit_range(data[0x0C - offset], 1, 0);
795 	if (scan_direction != 3)
796 		dddb->scan_direction = scan_direction;
797 	else
798 		add_failure(cta,
799 			   "VESA Video Display Device Data Block: Invalid scan direction 0x%x.",
800 			   scan_direction);
801 
802 	subpixel_layout = data[0x0D - offset];
803 	switch (subpixel_layout) {
804 	case DI_CTA_VESA_DDDB_SUBPIXEL_UNDEFINED:
805 	case DI_CTA_VESA_DDDB_SUBPIXEL_RGB_VERT:
806 	case DI_CTA_VESA_DDDB_SUBPIXEL_RGB_HORIZ:
807 	case DI_CTA_VESA_DDDB_SUBPIXEL_EDID_CHROM_VERT:
808 	case DI_CTA_VESA_DDDB_SUBPIXEL_EDID_CHROM_HORIZ:
809 	case DI_CTA_VESA_DDDB_SUBPIXEL_QUAD_RGGB:
810 	case DI_CTA_VESA_DDDB_SUBPIXEL_QUAD_GBRG:
811 	case DI_CTA_VESA_DDDB_SUBPIXEL_DELTA_RGB:
812 	case DI_CTA_VESA_DDDB_SUBPIXEL_MOSAIC:
813 	case DI_CTA_VESA_DDDB_SUBPIXEL_QUAD_ANY:
814 	case DI_CTA_VESA_DDDB_SUBPIXEL_FIVE:
815 	case DI_CTA_VESA_DDDB_SUBPIXEL_SIX:
816 	case DI_CTA_VESA_DDDB_SUBPIXEL_CLAIRVOYANTE_PENTILE:
817 		dddb->subpixel_layout = subpixel_layout;
818 		break;
819 	default:
820 		add_failure(cta,
821 			   "VESA Video Display Device Data Block: Invalid subpixel layout 0x%x.",
822 			   subpixel_layout);
823 	}
824 
825 	dddb->horiz_pitch_mm = (float)data[0x0E - offset] * 0.01f;
826 	dddb->vert_pitch_mm = (float)data[0x0F - offset] * 0.01f;
827 
828 	dddb->dithering_type = get_bit_range(data[0x10 - offset], 7, 6);
829 	dddb->direct_drive = has_bit(data[0x10 - offset], 5);
830 	dddb->overdrive_not_recommended = has_bit(data[0x10 - offset], 4);
831 	dddb->deinterlacing = has_bit(data[0x10 - offset], 3);
832 	if (get_bit_range(data[0x10 - offset], 2, 0) != 0)
833 		add_failure(cta, "VESA Video Display Device Data Block: Reserved miscellaneous display capabilities bits 2-0 must be 0.");
834 
835 	dddb->audio_support = has_bit(data[0x11 - offset], 7);
836 	dddb->separate_audio_inputs = has_bit(data[0x11 - offset], 6);
837 	dddb->audio_input_override = has_bit(data[0x11 - offset], 5);
838 	if (get_bit_range(data[0x11 - offset], 4, 0) != 0)
839 		add_failure(cta, "VESA Video Display Device Data Block: Reserved audio bits 4-0 must be 0.");
840 
841 	dddb->audio_delay_provided = data[0x12 - offset] != 0;
842 	dddb->audio_delay_ms = 2 * get_bit_range(data[0x12 - offset], 6, 0);
843 	if (!has_bit(data[0x12 - offset], 7))
844 		dddb->audio_delay_ms = -dddb->audio_delay_ms;
845 
846 	dddb->frame_rate_conversion = get_bit_range(data[0x13 - offset], 7, 6);
847 	dddb->frame_rate_range_hz = get_bit_range(data[0x13 - offset], 5, 0);
848 	dddb->frame_rate_native_hz = data[0x14 - offset];
849 
850 	dddb->bit_depth_interface = get_bit_range(data[0x15 - offset], 7, 4) + 1;
851 	dddb->bit_depth_display = get_bit_range(data[0x15 - offset], 3, 0) + 1;
852 
853 	dddb->additional_primary_chromaticities_len = get_bit_range(data[0x17 - offset], 1, 0);
854 	parse_vesa_dddb_additional_primary_chromaticity(&dddb->additional_primary_chromaticities[0],
855 							get_bit_range(data[0x16 - offset], 7, 4),
856 							&data[0x18 - offset]);
857 	parse_vesa_dddb_additional_primary_chromaticity(&dddb->additional_primary_chromaticities[1],
858 							get_bit_range(data[0x16 - offset], 3, 0),
859 							&data[0x1A - offset]);
860 	parse_vesa_dddb_additional_primary_chromaticity(&dddb->additional_primary_chromaticities[2],
861 							get_bit_range(data[0x17 - offset], 7, 4),
862 							&data[0x1C - offset]);
863 	if (get_bit_range(data[0x17 - offset], 3, 2) != 0)
864 		add_failure(cta, "VESA Video Display Device Data Block: Reserved additional primary chromaticities bits 3-2 of byte 0x17 must be 0.");
865 
866 	dddb->resp_time_transition = has_bit(data[0x1E - offset], 7);
867 	dddb->resp_time_ms = get_bit_range(data[0x1E - offset], 6, 0);
868 
869 	dddb->overscan_horiz_pct = get_bit_range(data[0x1F - offset], 7, 4);
870 	dddb->overscan_vert_pct = get_bit_range(data[0x1F - offset], 3, 0);
871 
872 	return true;
873 }
874 
875 static bool
parse_colorimetry_block(struct di_edid_cta * cta,struct di_cta_colorimetry_block * colorimetry,const uint8_t * data,size_t size)876 parse_colorimetry_block(struct di_edid_cta *cta,
877 			struct di_cta_colorimetry_block *colorimetry,
878 			const uint8_t *data, size_t size)
879 {
880 	if (size < 2) {
881 		add_failure(cta, "Colorimetry Data Block: Empty Data Block with length %u.",
882 			    size);
883 		return false;
884 	}
885 
886 	colorimetry->bt2020_rgb = has_bit(data[0], 7);
887 	colorimetry->bt2020_ycc = has_bit(data[0], 6);
888 	colorimetry->bt2020_cycc = has_bit(data[0], 5);
889 	colorimetry->oprgb = has_bit(data[0], 4);
890 	colorimetry->opycc_601 = has_bit(data[0], 3);
891 	colorimetry->sycc_601 = has_bit(data[0], 2);
892 	colorimetry->xvycc_709 = has_bit(data[0], 1);
893 	colorimetry->xvycc_601 = has_bit(data[0], 0);
894 
895 	colorimetry->st2113_rgb = has_bit(data[1], 7);
896 	colorimetry->ictcp = has_bit(data[1], 6);
897 
898 	if (get_bit_range(data[1], 5, 0) != 0)
899 		add_failure_until(cta, 3,
900 				  "Colorimetry Data Block: Reserved bits MD0-MD3 must be 0.");
901 
902 	return true;
903 }
904 
905 static float
parse_max_luminance(uint8_t raw)906 parse_max_luminance(uint8_t raw)
907 {
908 	if (raw == 0)
909 		return 0;
910 	return 50 * powf(2, (float) raw / 32);
911 }
912 
913 static float
parse_min_luminance(uint8_t raw,float max)914 parse_min_luminance(uint8_t raw, float max)
915 {
916 	if (raw == 0)
917 		return 0;
918 	return max * powf((float) raw / 255, 2) / 100;
919 }
920 
921 static bool
parse_hdr_static_metadata_block(struct di_edid_cta * cta,struct di_cta_hdr_static_metadata_block_priv * metadata,const uint8_t * data,size_t size)922 parse_hdr_static_metadata_block(struct di_edid_cta *cta,
923 				struct di_cta_hdr_static_metadata_block_priv *metadata,
924 				const uint8_t *data, size_t size)
925 {
926 	uint8_t eotfs, descriptors;
927 
928 	if (size < 2) {
929 		add_failure(cta, "HDR Static Metadata Data Block: Empty Data Block with length %u.",
930 			    size);
931 		return false;
932 	}
933 
934 	metadata->base.eotfs = &metadata->eotfs;
935 	metadata->base.descriptors = &metadata->descriptors;
936 
937 	eotfs = data[0];
938 	metadata->eotfs.traditional_sdr = has_bit(eotfs, 0);
939 	metadata->eotfs.traditional_hdr = has_bit(eotfs, 1);
940 	metadata->eotfs.pq = has_bit(eotfs, 2);
941 	metadata->eotfs.hlg = has_bit(eotfs, 3);
942 	if (get_bit_range(eotfs, 7, 4))
943 		add_failure_until(cta, 3, "HDR Static Metadata Data Block: Unknown EOTF.");
944 
945 	descriptors = data[1];
946 	metadata->descriptors.type1 = has_bit(descriptors, 0);
947 	if (get_bit_range(descriptors, 7, 1))
948 		add_failure_until(cta, 3, "HDR Static Metadata Data Block: Unknown descriptor type.");
949 
950 	if (size > 2)
951 		metadata->base.desired_content_max_luminance = parse_max_luminance(data[2]);
952 	if (size > 3)
953 		metadata->base.desired_content_max_frame_avg_luminance = parse_max_luminance(data[3]);
954 	if (size > 4) {
955 		if (metadata->base.desired_content_max_luminance == 0)
956 			add_failure(cta, "HDR Static Metadata Data Block: Desired content min luminance is set, but max luminance is unset.");
957 		else
958 			metadata->base.desired_content_min_luminance =
959 				parse_min_luminance(data[4], metadata->base.desired_content_max_luminance);
960 	}
961 
962 	return true;
963 }
964 static bool
parse_hdr_dynamic_metadata_block(struct di_edid_cta * cta,struct di_cta_hdr_dynamic_metadata_block_priv * priv,const uint8_t * data,size_t size)965 parse_hdr_dynamic_metadata_block(struct di_edid_cta *cta,
966 				 struct di_cta_hdr_dynamic_metadata_block_priv *priv,
967 				 const uint8_t *data, size_t size)
968 {
969 	struct di_cta_hdr_dynamic_metadata_block *base;
970 	struct di_cta_hdr_dynamic_metadata_block_type1 *type1;
971 	struct di_cta_hdr_dynamic_metadata_block_type2 *type2;
972 	struct di_cta_hdr_dynamic_metadata_block_type3 *type3;
973 	struct di_cta_hdr_dynamic_metadata_block_type4 *type4;
974 	struct di_cta_hdr_dynamic_metadata_block_type256 *type256;
975 	size_t length;
976 	int type;
977 
978 	base = &priv->base;
979 	type1 = &priv->type1;
980 	type2 = &priv->type2;
981 	type3 = &priv->type3;
982 	type4 = &priv->type4;
983 	type256 = &priv->type256;
984 
985 	if (size < 3) {
986 		add_failure(cta, "HDR Dynamic Metadata Data Block: Empty Data Block with length %u.",
987 			    size);
988 		return false;
989 	}
990 
991 	while (size >= 3) {
992 		length = data[0];
993 
994 		if (size < length + 1) {
995 			add_failure(cta, "HDR Dynamic Metadata Data Block: Length of type bigger than block size.");
996 			return false;
997 		}
998 
999 		if (length < 2) {
1000 			add_failure(cta, "HDR Dynamic Metadata Data Block: Type has wrong length.");
1001 			return false;
1002 		}
1003 
1004 		type = (data[2] << 8) | data[1];
1005 		switch (type) {
1006 		case 0x0001:
1007 			if (length < 3) {
1008 				add_failure(cta, "HDR Dynamic Metadata Data Block: Type 1 missing Support Flags.");
1009 				break;
1010 			}
1011 			if (length != 3)
1012 				add_failure(cta, "HDR Dynamic Metadata Data Block: Type 1 length must be 3.");
1013 			type1->type_1_hdr_metadata_version = get_bit_range(data[3], 3, 0);
1014 			base->type1 = type1;
1015 			if (get_bit_range(data[3], 7, 4) != 0)
1016 				add_failure(cta, "HDR Dynamic Metadata Data Block: Type 1 support flags bits 7-4 must be 0.");
1017 			break;
1018 		case 0x0002:
1019 			if (length < 3) {
1020 				add_failure(cta, "HDR Dynamic Metadata Data Block: Type 2 missing Support Flags.");
1021 				break;
1022 			}
1023 			if (length != 3)
1024 				add_failure(cta, "HDR Dynamic Metadata Data Block: Type 2 length must be 3.");
1025 			type2->ts_103_433_spec_version = get_bit_range(data[3], 3, 0);
1026 			if (type2->ts_103_433_spec_version == 0) {
1027 				add_failure(cta, "HDR Dynamic Metadata Data Block: Type 2 spec version of 0 is not allowed.");
1028 				break;
1029 			}
1030 			type2->ts_103_433_1_capable = has_bit(data[3], 4);
1031 			type2->ts_103_433_2_capable = has_bit(data[3], 5);
1032 			type2->ts_103_433_3_capable = has_bit(data[3], 6);
1033 			base->type2 = type2;
1034 			if (has_bit(data[3], 7) != 0)
1035 				add_failure(cta, "HDR Dynamic Metadata Data Block: Type 1 support flags bit 7 must be 0.");
1036 			break;
1037 		case 0x0003:
1038 			if (length != 2)
1039 				add_failure(cta, "HDR Dynamic Metadata Data Block: Type 3 length must be 2.");
1040 			base->type3 = type3;
1041 			break;
1042 		case 0x0004:
1043 			if (length < 3) {
1044 				add_failure(cta, "HDR Dynamic Metadata Data Block: Type 4 missing Support Flags.");
1045 				break;
1046 			}
1047 			if (length != 3)
1048 				add_failure(cta, "HDR Dynamic Metadata Data Block: Type 4 length must be 3.");
1049 			type4->type_4_hdr_metadata_version = get_bit_range(data[3], 3, 0);
1050 			base->type4 = type4;
1051 			if (get_bit_range(data[3], 7, 4) != 0)
1052 				add_failure(cta, "HDR Dynamic Metadata Data Block: Type 4 support flags bits 7-4 must be 0.");
1053 			break;
1054 		case 0x0100:
1055 			if (length < 3) {
1056 				add_failure(cta, "HDR Dynamic Metadata Data Block: Type 256 missing Support Flags.");
1057 				break;
1058 			}
1059 			if (length != 3)
1060 				add_failure(cta, "HDR Dynamic Metadata Data Block: Type 256 length must be 3.");
1061 			type256->graphics_overlay_flag_version = get_bit_range(data[3], 3, 0);
1062 			base->type256 = type256;
1063 			if (get_bit_range(data[3], 7, 4) != 0)
1064 				add_failure(cta, "HDR Dynamic Metadata Data Block: Type 256 support flags bits 7-4 must be 0.");
1065 			break;
1066 		default:
1067 			add_failure(cta, "HDR Dynamic Metadata Data Block: Unknown Type 0x%04x.", type);
1068 			break;
1069 		}
1070 
1071 		size -= length + 1;
1072 		data += length + 1;
1073 	}
1074 
1075 	return true;
1076 }
1077 
1078 static bool
parse_vesa_transfer_characteristics_block(struct di_edid_cta * cta,struct di_cta_vesa_transfer_characteristics * tf,const uint8_t * data,size_t size)1079 parse_vesa_transfer_characteristics_block(struct di_edid_cta *cta,
1080 					  struct di_cta_vesa_transfer_characteristics *tf,
1081 					  const uint8_t *data, size_t size)
1082 {
1083 	size_t i;
1084 
1085 	if (size != 7 && size != 15 && size != 31) {
1086 		add_failure(cta, "Invalid length %u.", size);
1087 		return false;
1088 	}
1089 
1090 	tf->points_len = (uint8_t) size + 1;
1091 	tf->usage = get_bit_range(data[0], 7, 6);
1092 
1093 	tf->points[0] = get_bit_range(data[0], 5, 0) / 1023.0f;
1094 	for (i = 1; i < size; i++)
1095 		tf->points[i] = tf->points[i - 1] + data[i] / 1023.0f;
1096 	tf->points[i] = 1.0f;
1097 
1098 	return true;
1099 }
1100 
1101 static bool
parse_video_format_pref_block(struct di_edid_cta * cta,struct di_cta_video_format_pref_block * vfpdb,const uint8_t * data,size_t size)1102 parse_video_format_pref_block(struct di_edid_cta *cta,
1103 			      struct di_cta_video_format_pref_block *vfpdb,
1104 			      const uint8_t *data, size_t size)
1105 {
1106 	struct di_cta_svr *svr;
1107 	size_t i;
1108 	uint8_t code;
1109 
1110 	for (i = 0; i < size; i++) {
1111 		code = data[i];
1112 
1113 		if (code == 0 ||
1114 		    code == 128 ||
1115 		    (code >= 161 && code <= 192) ||
1116 		    code == 255) {
1117 			add_failure(cta, "Video Format Preference Data Block: "
1118 				    "using reserved Short Video Reference value %u.",
1119 				    code);
1120 			continue;
1121 		}
1122 
1123 		svr = calloc(1, sizeof(*svr));
1124 		if (!svr)
1125 			return false;
1126 
1127 		if ((code >= 1 && code <= 127) ||
1128 		    (code >= 193 && code <= 253)) {
1129 			svr->type = DI_CTA_SVR_TYPE_VIC;
1130 			svr->vic = code;
1131 		} else if (code >= 129 && code <= 144) {
1132 			svr->type = DI_CTA_SVR_TYPE_DTD_INDEX;
1133 			svr->dtd_index = code - 129;
1134 		} else if (code >= 145 && code <= 160) {
1135 			svr->type = DI_CTA_SVR_TYPE_T7T10VTDB;
1136 			svr->dtd_index = code - 145;
1137 		} else if (code == 254) {
1138 			svr->type = DI_CTA_SVR_TYPE_FIRST_T8VTDB;
1139 		} else {
1140 			abort(); /* unreachable */
1141 		}
1142 
1143 		assert(vfpdb->svrs_len < EDID_CTA_MAX_VIDEO_FORMAT_PREF_BLOCK_ENTRIES);
1144 		vfpdb->svrs[vfpdb->svrs_len++] = svr;
1145 	}
1146 
1147 	return true;
1148 }
1149 
1150 
1151 static void
parse_ycbcr420_cap_map(struct di_edid_cta * cta,struct di_cta_ycbcr420_cap_map * ycbcr420_cap_map,const uint8_t * data,size_t size)1152 parse_ycbcr420_cap_map(struct di_edid_cta *cta,
1153 		       struct di_cta_ycbcr420_cap_map *ycbcr420_cap_map,
1154 		       const uint8_t *data, size_t size)
1155 {
1156 	if (size == 0) {
1157 		ycbcr420_cap_map->all = true;
1158 		return;
1159 	}
1160 
1161 	assert(size <= sizeof(ycbcr420_cap_map->svd_bitmap));
1162 	memcpy(ycbcr420_cap_map->svd_bitmap, data, size);
1163 }
1164 
1165 static bool
parse_hdmi_audio_3d_descriptor(struct di_edid_cta * cta,struct di_cta_sad_priv * sad,const uint8_t * data,size_t size)1166 parse_hdmi_audio_3d_descriptor(struct di_edid_cta *cta,
1167 			       struct di_cta_sad_priv *sad,
1168 			       const uint8_t *data, size_t size)
1169 {
1170 	/* Contains the same data as the Short Audio Descriptor, packed differently */
1171 	struct di_cta_sad *base = &sad->base;
1172 	struct di_cta_sad_sample_rates *sample_rate = &sad->supported_sample_rates;
1173 	struct di_cta_sad_lpcm *lpcm = &sad->lpcm;
1174 	uint8_t code;
1175 
1176 	assert(size >= CTA_HDMI_AUDIO_3D_DESCRIPTOR_SIZE);
1177 
1178 	code = get_bit_range(data[0], 3, 0);
1179 	if (!parse_sad_format(cta, code, 0, &base->format, "HDMI Audio Data Block"))
1180 		return false;
1181 
1182 	if (base->format != DI_CTA_AUDIO_FORMAT_LPCM &&
1183 	    base->format != DI_CTA_AUDIO_FORMAT_ONE_BIT_AUDIO) {
1184 		add_failure(cta,
1185 			    "HDMI Audio Data Block: Unsupported 3D Audio Format 0x%04x.",
1186 			    code);
1187 		return false;
1188 	}
1189 
1190 	base->max_channels = get_bit_range(data[1], 4, 0) + 1;
1191 	sample_rate->has_192_khz = has_bit(data[2], 6);
1192 	sample_rate->has_176_4_khz = has_bit(data[2], 5);
1193 	sample_rate->has_96_khz = has_bit(data[2], 4);
1194 	sample_rate->has_88_2_khz = has_bit(data[2], 3);
1195 	sample_rate->has_48_khz = has_bit(data[2], 2);
1196 	sample_rate->has_44_1_khz = has_bit(data[2], 1);
1197 	sample_rate->has_32_khz = has_bit(data[2], 0);
1198 	base->supported_sample_rates = sample_rate;
1199 
1200 	if (base->format == DI_CTA_AUDIO_FORMAT_LPCM) {
1201 		lpcm->has_sample_size_24_bits = has_bit(data[3], 2);
1202 		lpcm->has_sample_size_20_bits = has_bit(data[3], 1);
1203 		lpcm->has_sample_size_16_bits = has_bit(data[3], 0);
1204 		base->lpcm = lpcm;
1205 	}
1206 
1207 	if (base->format == DI_CTA_AUDIO_FORMAT_ONE_BIT_AUDIO) {
1208 		/* TODO data[3] 7:0 contains unknown Audio Format Code dependent value */
1209 	}
1210 
1211 	return true;
1212 }
1213 
1214 static bool
parse_hdmi_audio_block(struct di_edid_cta * cta,struct di_cta_hdmi_audio_block_priv * priv,const uint8_t * data,size_t size)1215 parse_hdmi_audio_block(struct di_edid_cta *cta,
1216 		       struct di_cta_hdmi_audio_block_priv *priv,
1217 		       const uint8_t *data, size_t size)
1218 {
1219 	struct di_cta_hdmi_audio_block *hdmi_audio = &priv->base;
1220 	struct di_cta_hdmi_audio_multi_stream *ms = &priv->ms;
1221 	struct di_cta_hdmi_audio_3d *a3d = &priv->a3d;
1222 	uint8_t multi_stream;
1223 	bool ms_non_mixed;
1224 	size_t num_3d_audio_descs;
1225 	size_t num_descs;
1226 	struct di_cta_sad_priv *sad_priv;
1227 	uint8_t channels;
1228 
1229 	if (size < 1) {
1230 		add_failure(cta, "HDMI Audio Data Block: Empty Data Block with length 0.");
1231 		return false;
1232 	}
1233 
1234 	multi_stream = get_bit_range(data[0], 1, 0);
1235 	ms_non_mixed = has_bit(data[0], 2);
1236 
1237 	if (multi_stream > 0) {
1238 		hdmi_audio->multi_stream = ms;
1239 		ms->max_streams = multi_stream + 1;
1240 		ms->supports_non_mixed = ms_non_mixed;
1241 	} else if (ms_non_mixed) {
1242 		add_failure(cta, "HDMI Audio Data Block: MS NonMixed support indicated but "
1243 				 "Max Stream Count == 0.");
1244 	}
1245 
1246 	if (size < 2)
1247 		return true;
1248 
1249 	num_3d_audio_descs = get_bit_range(data[1], 2, 0);
1250 	if (num_3d_audio_descs == 0)
1251 		return true;
1252 
1253 	/* If there are 3d Audio Descriptors, there is one last Speaker Allocation Descriptor */
1254 	num_descs = num_3d_audio_descs + 1;
1255 
1256 	/* Skip to the first descriptor */
1257 	size -= 2;
1258 	data += 2;
1259 
1260 	/* Make sure there is enough space for the descriptors */
1261 	if (num_descs > size / CTA_HDMI_AUDIO_3D_DESCRIPTOR_SIZE) {
1262 		add_failure(cta, "HDMI Audio Data Block: More descriptors indicated than block size allows.");
1263 		return true;
1264 	}
1265 
1266 	hdmi_audio->audio_3d = a3d;
1267 	a3d->sads = (const struct di_cta_sad * const*)priv->sads;
1268 
1269 	/* First the 3D Audio Descriptors, the last one is the 3D Speaker Allocation Descriptor */
1270 	while (num_descs > 1) {
1271 		sad_priv = calloc(1, sizeof(*sad_priv));
1272 		if (!sad_priv)
1273 			return false;
1274 
1275 		if (!parse_hdmi_audio_3d_descriptor(cta, sad_priv, data, size)) {
1276 			free(sad_priv);
1277 			goto skip;
1278 		}
1279 
1280 		assert(priv->sads_len < EDID_CTA_MAX_HDMI_AUDIO_BLOCK_ENTRIES);
1281 		priv->sads[priv->sads_len++] = sad_priv;
1282 
1283 skip:
1284 		num_descs--;
1285 		size -= CTA_HDMI_AUDIO_3D_DESCRIPTOR_SIZE;
1286 		data += CTA_HDMI_AUDIO_3D_DESCRIPTOR_SIZE;
1287 	}
1288 
1289 	channels = get_bit_range(data[3], 7, 4);
1290 
1291 	switch (channels) {
1292 	case DI_CTA_HDMI_AUDIO_3D_CHANNELS_UNKNOWN:
1293 	case DI_CTA_HDMI_AUDIO_3D_CHANNELS_10_2:
1294 	case DI_CTA_HDMI_AUDIO_3D_CHANNELS_22_2:
1295 	case DI_CTA_HDMI_AUDIO_3D_CHANNELS_30_2:
1296 		a3d->channels = channels;
1297 		break;
1298 	default:
1299 		a3d->channels = DI_CTA_HDMI_AUDIO_3D_CHANNELS_UNKNOWN;
1300 		break;
1301 	}
1302 
1303 	parse_speaker_alloc(cta, &a3d->speakers, data, "Room Configuration Data Block");
1304 
1305 	return true;
1306 }
1307 
1308 static struct di_cta_infoframe_descriptor *
parse_infoframe(struct di_edid_cta * cta,uint8_t type,const uint8_t * data,size_t size)1309 parse_infoframe(struct di_edid_cta *cta, uint8_t type,
1310 		const uint8_t *data, size_t size)
1311 {
1312 	struct di_cta_infoframe_descriptor infoframe = {0};
1313 	struct di_cta_infoframe_descriptor *ifp;
1314 
1315 	if (type >= 8 && type <= 0x1f) {
1316 		add_failure(cta, "InfoFrame Data Block: Type code %u is reserved.",
1317 			    type);
1318 		return NULL;
1319 	}
1320 
1321 	if (type >= 0x20) {
1322 		add_failure(cta, "InfoFrame Data Block: Type code %u is forbidden.",
1323 			    type);
1324 		return NULL;
1325 	}
1326 
1327 	if (type == 1) {
1328 		/* No known vendor specific InfoFrames, yet */
1329 		return NULL;
1330 	} else {
1331 		switch (type) {
1332 		case 0x02:
1333 			infoframe.type = DI_CTA_INFOFRAME_TYPE_AUXILIARY_VIDEO_INFORMATION;
1334 			break;
1335 		case 0x03:
1336 			infoframe.type = DI_CTA_INFOFRAME_TYPE_SOURCE_PRODUCT_DESCRIPTION;
1337 			break;
1338 		case 0x04:
1339 			infoframe.type = DI_CTA_INFOFRAME_TYPE_AUDIO;
1340 			break;
1341 		case 0x05:
1342 			infoframe.type = DI_CTA_INFOFRAME_TYPE_MPEG_SOURCE;
1343 			break;
1344 		case 0x06:
1345 			infoframe.type = DI_CTA_INFOFRAME_TYPE_NTSC_VBI;
1346 			break;
1347 		case 0x07:
1348 			infoframe.type = DI_CTA_INFOFRAME_TYPE_DYNAMIC_RANGE_AND_MASTERING;
1349 			break;
1350 		default:
1351 			abort(); /* unreachable */
1352 		}
1353 	}
1354 
1355 	ifp = calloc(1, sizeof(*ifp));
1356 	if (!ifp)
1357 		return NULL;
1358 
1359 	*ifp = infoframe;
1360 	return ifp;
1361 }
1362 
1363 static bool
parse_infoframe_block(struct di_edid_cta * cta,struct di_cta_infoframe_block_priv * ifb,const uint8_t * data,size_t size)1364 parse_infoframe_block(struct di_edid_cta *cta,
1365 		      struct di_cta_infoframe_block_priv *ifb,
1366 		      const uint8_t *data, size_t size)
1367 {
1368 	size_t index = 0, length;
1369 	uint8_t type;
1370 	struct di_cta_infoframe_descriptor *infoframe;
1371 
1372 	if (size < 2) {
1373 		add_failure(cta, "InfoFrame Data Block: Empty Data Block with length %u.",
1374 			    size);
1375 		return false;
1376 	}
1377 
1378 	ifb->block.num_simultaneous_vsifs = data[1] + 1;
1379 	ifb->block.infoframes = (const struct di_cta_infoframe_descriptor *const *)ifb->infoframes;
1380 
1381 	index = get_bit_range(data[0], 7, 5) + 2;
1382 	if (get_bit_range(data[0], 4, 0) != 0)
1383 		add_failure(cta, "InfoFrame Data Block: InfoFrame Processing "
1384 				 "Descriptor Header bits F14-F10 shall be 0.");
1385 
1386 	while (true) {
1387 		if (index == size)
1388 			break;
1389 		if (index > size) {
1390 			add_failure(cta, "InfoFrame Data Block: Payload length exceeds block size.");
1391 			return false;
1392 		}
1393 
1394 		length = get_bit_range(data[index], 7, 5);
1395 		type = get_bit_range(data[index], 4, 0);
1396 
1397 		if (type == 0) {
1398 			add_failure(cta, "InfoFrame Data Block: Short InfoFrame Descriptor with type 0 is forbidden.");
1399 			return false;
1400 		} else if (type == 1) {
1401 			length += 4;
1402 		} else {
1403 			length += 1;
1404 		}
1405 
1406 		if (index + length > size) {
1407 			add_failure(cta, "InfoFrame Data Block: Payload length exceeds block size.");
1408 			return false;
1409 		}
1410 
1411 		infoframe = parse_infoframe(cta, type, &data[index], length);
1412 		if (infoframe) {
1413 			assert(ifb->infoframes_len < EDID_CTA_INFOFRAME_BLOCK_ENTRIES);
1414 			ifb->infoframes[ifb->infoframes_len++] = infoframe;
1415 		}
1416 
1417 		index += length;
1418 	}
1419 
1420 	return true;
1421 }
1422 
1423 static double
decode_coord(unsigned char x)1424 decode_coord(unsigned char x)
1425 {
1426 	signed char s = (signed char)x;
1427 
1428 	return s / 64.0;
1429 }
1430 
1431 static bool
parse_room_config_block(struct di_edid_cta * cta,struct di_cta_room_configuration * rc,const uint8_t * data,size_t size)1432 parse_room_config_block(struct di_edid_cta *cta,
1433 			struct di_cta_room_configuration *rc,
1434 			const uint8_t *data, size_t size)
1435 {
1436 	bool has_display_coords;
1437 	bool has_speaker_count;
1438 
1439 	if (size < 4) {
1440 		add_failure(cta, "Room Configuration Data Block: Empty Data Block with length %u.",
1441 			    size);
1442 		return false;
1443 	}
1444 
1445 	has_display_coords = has_bit(data[0], 7);
1446 	has_speaker_count = has_bit(data[0], 6);
1447 	rc->has_speaker_location_descriptors = has_bit(data[0], 5);
1448 
1449 	if (has_speaker_count) {
1450 		rc->speaker_count = get_bit_range(data[0], 4, 0) + 1;
1451 	} else {
1452 		if (get_bit_range(data[0], 4, 0) != 0) {
1453 			add_failure(cta, "Room Configuration Data Block: "
1454 					 "'Speaker' flag is 0, but the Speaker Count is not 0.");
1455 		}
1456 
1457 		if (rc->has_speaker_location_descriptors) {
1458 			add_failure(cta, "Room Configuration Data Block: "
1459 					 "'Speaker' flag is 0, but there are "
1460 					 "Speaker Location Descriptors.");
1461 		}
1462 	}
1463 
1464 	parse_speaker_alloc(cta, &rc->speakers, &data[1], "Room Configuration Data Block");
1465 
1466 	rc->max_x = 16;
1467 	rc->max_y = 16;
1468 	rc->max_z = 8;
1469 	rc->display_x = 0.0;
1470 	rc->display_y = 1.0;
1471 	rc->display_z = 0.0;
1472 
1473 	if (size < 7) {
1474 		if (has_display_coords)
1475 			add_failure(cta, "Room Configuration Data Block: "
1476 					 "'Display' flag is 1, but the Display and Maximum coordinates are not present.");
1477 		return true;
1478 	}
1479 
1480 	rc->max_x = data[4];
1481 	rc->max_y = data[5];
1482 	rc->max_z = data[6];
1483 
1484 	if (size < 10) {
1485 		if (has_display_coords)
1486 			add_failure(cta, "Room Configuration Data Block: "
1487 					 "'Display' flag is 1, but the Display coordinates are not present.");
1488 		return true;
1489 	}
1490 
1491 	rc->display_x = decode_coord(data[7]);
1492 	rc->display_y = decode_coord(data[8]);
1493 	rc->display_z = decode_coord(data[9]);
1494 
1495 	return true;
1496 }
1497 
1498 static bool
parse_speaker_location_block(struct di_edid_cta * cta,struct di_cta_speaker_location_block * sldb,const uint8_t * data,size_t size)1499 parse_speaker_location_block(struct di_edid_cta *cta,
1500 			     struct di_cta_speaker_location_block *sldb,
1501 			     const uint8_t *data, size_t size)
1502 {
1503 	struct di_cta_speaker_locations speaker_loc, *slp;
1504 
1505 	if (size < 2) {
1506 		add_failure(cta, "Speaker Location Data Block: Empty Data Block with length %u.",
1507 			    size);
1508 		return false;
1509 	}
1510 
1511 	while (size >= 2) {
1512 		speaker_loc.has_coords = has_bit(data[0], 6);
1513 		speaker_loc.is_active = has_bit(data[0], 5);
1514 		speaker_loc.channel_index = get_bit_range(data[0], 4, 0);
1515 		speaker_loc.speaker_id = get_bit_range(data[1], 4, 0);
1516 
1517 		if (has_bit(data[0], 7) || get_bit_range(data[1], 7, 5) != 0) {
1518 			add_failure(cta, "Speaker Location Data Block: Bits F27-F25, F17 must be 0.");
1519 		}
1520 
1521 		if (speaker_loc.has_coords && size >= 5) {
1522 			speaker_loc.x = decode_coord(data[2]);
1523 			speaker_loc.y = decode_coord(data[3]);
1524 			speaker_loc.z = decode_coord(data[4]);
1525 			size -= 5;
1526 			data += 5;
1527 		} else if (speaker_loc.has_coords) {
1528 			add_failure(cta, "Speaker Location Data Block: COORD bit "
1529 					 "set but contains no Coordinates.");
1530 			return false;
1531 		} else {
1532 			size -= 2;
1533 			data += 2;
1534 		}
1535 
1536 		slp = calloc(1, sizeof(*slp));
1537 		if (!slp)
1538 			return false;
1539 
1540 		*slp = speaker_loc;
1541 		assert(sldb->locations_len < EDID_CTA_MAX_SPEAKER_LOCATION_BLOCK_ENTRIES);
1542 		sldb->locations[sldb->locations_len++] = slp;
1543 	}
1544 
1545 	return true;
1546 }
1547 
1548 static bool
parse_did_type_vii_timing(struct di_edid_cta * cta,struct di_displayid_type_i_ii_vii_timing * t,const uint8_t * data,size_t size)1549 parse_did_type_vii_timing(struct di_edid_cta *cta,
1550 			  struct di_displayid_type_i_ii_vii_timing *t,
1551 			  const uint8_t *data, size_t size)
1552 {
1553 	uint8_t revision;
1554 
1555 	if (size != 21) {
1556 		add_failure(cta, "DisplayID Type VII Video Timing Data Block: "
1557 				 "Empty Data Block with length %u.", size);
1558 		return false;
1559 	}
1560 
1561 	if (get_bit_range(data[0], 6, 4) != 0) {
1562 		add_failure(cta, "DisplayID Type VII Video Timing Data Block: "
1563 				 "T7_M shall be 000b.");
1564 		return false;
1565 	}
1566 
1567 	revision = get_bit_range(data[0], 2, 0);
1568 	if (revision != 2) {
1569 		add_failure(cta, "DisplayID Type VII Video Timing Data Block: "
1570 				 "Unexpected revision (%u != %u).",
1571 			    revision, 2);
1572 		return false;
1573 	}
1574 
1575 	if (has_bit(data[0], 3)) {
1576 		add_failure(cta, "DisplayID Type VII Video Timing Data Block: "
1577 				 "DSC_PT shall be 0.");
1578 	}
1579 	if (has_bit(data[0], 7)) {
1580 		add_failure(cta, "DisplayID Type VII Video Timing Data Block: "
1581 				 "Block Revision and Other Data Bit 7 must be 0.");
1582 	}
1583 
1584 	data += 1;
1585 	size -= 1;
1586 
1587 	if (!_di_displayid_parse_type_1_7_timing(t, cta->logger,
1588 						 "DisplayID Type VII Video Timing Data Block",
1589 						 data, true))
1590 		return false;
1591 
1592 	return true;
1593 }
1594 
1595 static void
destroy_data_block(struct di_cta_data_block * data_block)1596 destroy_data_block(struct di_cta_data_block *data_block)
1597 {
1598 	size_t i;
1599 	struct di_cta_video_block *video;
1600 	struct di_cta_audio_block *audio;
1601 	struct di_cta_infoframe_block_priv *infoframe;
1602 	struct di_cta_speaker_location_block *speaker_location;
1603 	struct di_cta_video_format_pref_block *vfpdb;
1604 	struct di_cta_hdmi_audio_block_priv *hdmi_audio;
1605 
1606 	switch (data_block->tag) {
1607 	case DI_CTA_DATA_BLOCK_VIDEO:
1608 		video = &data_block->video;
1609 		for (i = 0; i < video->svds_len; i++)
1610 			free(video->svds[i]);
1611 		break;
1612 	case DI_CTA_DATA_BLOCK_YCBCR420:
1613 		video = &data_block->ycbcr420;
1614 		for (i = 0; i < video->svds_len; i++)
1615 			free(video->svds[i]);
1616 		break;
1617 	case DI_CTA_DATA_BLOCK_AUDIO:
1618 		audio = &data_block->audio;
1619 		for (i = 0; i < audio->sads_len; i++)
1620 			free(audio->sads[i]);
1621 		break;
1622 	case DI_CTA_DATA_BLOCK_INFOFRAME:
1623 		infoframe = &data_block->infoframe;
1624 		for (i = 0; i < infoframe->infoframes_len; i++)
1625 			free(infoframe->infoframes[i]);
1626 		break;
1627 	case DI_CTA_DATA_BLOCK_SPEAKER_LOCATION:
1628 		speaker_location = &data_block->speaker_location;
1629 		for (i = 0; i < speaker_location->locations_len; i++)
1630 			free(speaker_location->locations[i]);
1631 		break;
1632 	case DI_CTA_DATA_BLOCK_VIDEO_FORMAT_PREF:
1633 		vfpdb = &data_block->video_format_pref;
1634 		for (i = 0; i < vfpdb->svrs_len; i++)
1635 			free(vfpdb->svrs[i]);
1636 		break;
1637 	case DI_CTA_DATA_BLOCK_HDMI_AUDIO:
1638 		hdmi_audio = &data_block->hdmi_audio;
1639 		for (i = 0; i < hdmi_audio->sads_len; i++)
1640 			free(hdmi_audio->sads[i]);
1641 		break;
1642 	default:
1643 		break; /* Nothing to do */
1644 	}
1645 
1646 	free(data_block);
1647 }
1648 
1649 static bool
parse_data_block(struct di_edid_cta * cta,uint8_t raw_tag,const uint8_t * data,size_t size)1650 parse_data_block(struct di_edid_cta *cta, uint8_t raw_tag, const uint8_t *data, size_t size)
1651 {
1652 	enum di_cta_data_block_tag tag;
1653 	uint8_t extended_tag;
1654 	struct di_cta_data_block *data_block;
1655 
1656 	data_block = calloc(1, sizeof(*data_block));
1657 	if (!data_block) {
1658 		return false;
1659 	}
1660 
1661 	switch (raw_tag) {
1662 	case 1:
1663 		tag = DI_CTA_DATA_BLOCK_AUDIO;
1664 		if (!parse_audio_block(cta, &data_block->audio, data, size))
1665 			goto error;
1666 		break;
1667 	case 2:
1668 		tag = DI_CTA_DATA_BLOCK_VIDEO;
1669 		if (!parse_video_block(cta, &data_block->video, data, size))
1670 			goto error;
1671 		break;
1672 	case 3:
1673 		/* Vendor-Specific Data Block */
1674 		goto skip;
1675 	case 4:
1676 		tag = DI_CTA_DATA_BLOCK_SPEAKER_ALLOC;
1677 		if (!parse_speaker_alloc_block(cta, &data_block->speaker_alloc,
1678 					       data, size))
1679 			goto error;
1680 		break;
1681 	case 5:
1682 		tag = DI_CTA_DATA_BLOCK_VESA_DISPLAY_TRANSFER_CHARACTERISTIC;
1683 		if (!parse_vesa_transfer_characteristics_block(cta,
1684 							       &data_block->vesa_transfer_characteristics,
1685 							       data, size))
1686 			goto error;
1687 		break;
1688 	case 6:
1689 		tag = DI_CTA_DATA_BLOCK_VIDEO_FORMAT;
1690 		break;
1691 	case 7:
1692 		/* Use Extended Tag */
1693 		if (size < 1) {
1694 			add_failure(cta, "Empty block with extended tag.");
1695 			goto skip;
1696 		}
1697 
1698 		extended_tag = data[0];
1699 		data = &data[1];
1700 		size--;
1701 
1702 		switch (extended_tag) {
1703 		case 0:
1704 			tag = DI_CTA_DATA_BLOCK_VIDEO_CAP;
1705 			if (!parse_video_cap_block(cta, &data_block->video_cap,
1706 						   data, size))
1707 				goto skip;
1708 			break;
1709 		case 2:
1710 			tag = DI_CTA_DATA_BLOCK_VESA_DISPLAY_DEVICE;
1711 			if (!parse_vesa_dddb(cta, &data_block->vesa_dddb,
1712 					     data, size))
1713 				goto skip;
1714 			break;
1715 		case 5:
1716 			tag = DI_CTA_DATA_BLOCK_COLORIMETRY;
1717 			if (!parse_colorimetry_block(cta,
1718 						     &data_block->colorimetry,
1719 						     data, size))
1720 				goto skip;
1721 			break;
1722 		case 6:
1723 			tag = DI_CTA_DATA_BLOCK_HDR_STATIC_METADATA;
1724 			if (!parse_hdr_static_metadata_block(cta,
1725 							     &data_block->hdr_static_metadata,
1726 							     data, size))
1727 				goto skip;
1728 			break;
1729 		case 7:
1730 			tag = DI_CTA_DATA_BLOCK_HDR_DYNAMIC_METADATA;
1731 			if (!parse_hdr_dynamic_metadata_block(cta,
1732 							      &data_block->hdr_dynamic_metadata,
1733 							      data, size))
1734 				goto skip;
1735 			break;
1736 		case 8:
1737 			tag = DI_CTA_DATA_BLOCK_NATIVE_VIDEO_RESOLUTION;
1738 			break;
1739 		case 13:
1740 			tag = DI_CTA_DATA_BLOCK_VIDEO_FORMAT_PREF;
1741 			if (!parse_video_format_pref_block(cta,
1742 							   &data_block->video_format_pref,
1743 							   data, size))
1744 				goto skip;
1745 			break;
1746 		case 14:
1747 			tag = DI_CTA_DATA_BLOCK_YCBCR420;
1748 			if (!parse_ycbcr420_block(cta,
1749 						  &data_block->ycbcr420,
1750 						  data, size))
1751 				goto skip;
1752 			break;
1753 		case 15:
1754 			tag = DI_CTA_DATA_BLOCK_YCBCR420_CAP_MAP;
1755 			parse_ycbcr420_cap_map(cta,
1756 					       &data_block->ycbcr420_cap_map,
1757 					       data, size);
1758 			break;
1759 		case 18:
1760 			tag = DI_CTA_DATA_BLOCK_HDMI_AUDIO;
1761 			if (!parse_hdmi_audio_block(cta,
1762 						    &data_block->hdmi_audio,
1763 						    data, size))
1764 				goto skip;
1765 			break;
1766 		case 19:
1767 			tag = DI_CTA_DATA_BLOCK_ROOM_CONFIG;
1768 			if (!parse_room_config_block(cta,
1769 						     &data_block->room_config,
1770 						     data, size))
1771 				goto skip;
1772 			break;
1773 		case 20:
1774 			tag = DI_CTA_DATA_BLOCK_SPEAKER_LOCATION;
1775 			if (!parse_speaker_location_block(cta,
1776 							  &data_block->speaker_location,
1777 							  data, size))
1778 				goto skip;
1779 			break;
1780 		case 32:
1781 			tag = DI_CTA_DATA_BLOCK_INFOFRAME;
1782 			if (!parse_infoframe_block(cta,
1783 						   &data_block->infoframe,
1784 						   data, size))
1785 				goto skip;
1786 			break;
1787 		case 34:
1788 			tag = DI_CTA_DATA_BLOCK_DISPLAYID_VIDEO_TIMING_VII;
1789 			if (!parse_did_type_vii_timing(cta,
1790 						       &data_block->did_vii_timing,
1791 						       data, size))
1792 				goto skip;
1793 			break;
1794 		case 35:
1795 			tag = DI_CTA_DATA_BLOCK_DISPLAYID_VIDEO_TIMING_VIII;
1796 			break;
1797 		case 42:
1798 			tag = DI_CTA_DATA_BLOCK_DISPLAYID_VIDEO_TIMING_X;
1799 			break;
1800 		case 120:
1801 			tag = DI_CTA_DATA_BLOCK_HDMI_EDID_EXT_OVERRIDE;
1802 			break;
1803 		case 121:
1804 			tag = DI_CTA_DATA_BLOCK_HDMI_SINK_CAP;
1805 			break;
1806 		case 1: /* Vendor-Specific Video Data Block */
1807 		case 17: /* Vendor-Specific Audio Data Block */
1808 			goto skip;
1809 		default:
1810 			/* Reserved */
1811 			add_failure_until(cta, 3,
1812 					  "Unknown CTA-861 Data Block (extended tag 0x"PRIx8", length %zu).",
1813 					  extended_tag, size);
1814 			goto skip;
1815 		}
1816 		break;
1817 	default:
1818 		/* Reserved */
1819 		add_failure_until(cta, 3, "Unknown CTA-861 Data Block (tag 0x"PRIx8", length %zu).",
1820 				  raw_tag, size);
1821 		goto skip;
1822 	}
1823 
1824 	data_block->tag = tag;
1825 	assert(cta->data_blocks_len < EDID_CTA_MAX_DATA_BLOCKS);
1826 	cta->data_blocks[cta->data_blocks_len++] = data_block;
1827 	return true;
1828 
1829 skip:
1830 	free(data_block);
1831 	return true;
1832 
1833 error:
1834 	destroy_data_block(data_block);
1835 	return false;
1836 }
1837 
1838 bool
_di_edid_cta_parse(struct di_edid_cta * cta,const uint8_t * data,size_t size,struct di_logger * logger)1839 _di_edid_cta_parse(struct di_edid_cta *cta, const uint8_t *data, size_t size,
1840 		   struct di_logger *logger)
1841 {
1842 	uint8_t flags, dtd_start;
1843 	uint8_t data_block_header, data_block_tag, data_block_size;
1844 	size_t i;
1845 	struct di_edid_detailed_timing_def_priv *detailed_timing_def;
1846 
1847 	assert(size == 128);
1848 	assert(data[0] == 0x02);
1849 
1850 	cta->logger = logger;
1851 
1852 	cta->revision = data[1];
1853 	dtd_start = data[2];
1854 
1855 	flags = data[3];
1856 	if (cta->revision >= 2) {
1857 		cta->flags.it_underscan = has_bit(flags, 7);
1858 		cta->flags.basic_audio = has_bit(flags, 6);
1859 		cta->flags.ycc444 = has_bit(flags, 5);
1860 		cta->flags.ycc422 = has_bit(flags, 4);
1861 		cta->flags.native_dtds = get_bit_range(flags, 3, 0);
1862 	} else if (flags != 0) {
1863 		/* Reserved */
1864 		add_failure(cta, "Non-zero byte 3.");
1865 	}
1866 
1867 	if (dtd_start == 0) {
1868 		return true;
1869 	} else if (dtd_start < CTA_HEADER_SIZE || dtd_start >= size) {
1870 		errno = EINVAL;
1871 		return false;
1872 	}
1873 
1874 	i = CTA_HEADER_SIZE;
1875 	while (i < dtd_start) {
1876 		data_block_header = data[i];
1877 		data_block_tag = get_bit_range(data_block_header, 7, 5);
1878 		data_block_size = get_bit_range(data_block_header, 4, 0);
1879 
1880 		if (i + 1 + data_block_size > dtd_start) {
1881 			add_failure(cta, "Data Block at offset %zu overlaps Detailed Timing "
1882 					 "Definitions. Skipping all further Data Blocks.", i);
1883 			break;
1884 		}
1885 
1886 		if (!parse_data_block(cta, data_block_tag,
1887 				      &data[i + 1], data_block_size)) {
1888 			_di_edid_cta_finish(cta);
1889 			return false;
1890 		}
1891 
1892 		i += 1 + data_block_size;
1893 	}
1894 
1895 	if (i != dtd_start)
1896 		add_failure(cta, "Offset is %"PRIu8", but should be %zu.",
1897 			    dtd_start, i);
1898 
1899 	for (i = dtd_start; i + EDID_BYTE_DESCRIPTOR_SIZE <= CTA_DTD_END;
1900 	     i += EDID_BYTE_DESCRIPTOR_SIZE) {
1901 		if (data[i] == 0)
1902 			break;
1903 
1904 		detailed_timing_def = _di_edid_parse_detailed_timing_def(&data[i]);
1905 		if (!detailed_timing_def) {
1906 			_di_edid_cta_finish(cta);
1907 			return false;
1908 		}
1909 		assert(cta->detailed_timing_defs_len < EDID_CTA_MAX_DETAILED_TIMING_DEFS);
1910 		cta->detailed_timing_defs[cta->detailed_timing_defs_len++] = detailed_timing_def;
1911 	}
1912 
1913 	/* All padding bytes after the last DTD must be zero */
1914 	while (i < CTA_DTD_END) {
1915 		if (data[i] != 0) {
1916 			add_failure(cta, "Padding: Contains non-zero bytes.");
1917 			break;
1918 		}
1919 		i++;
1920 	}
1921 
1922 	cta->logger = NULL;
1923 	return true;
1924 }
1925 
1926 void
_di_edid_cta_finish(struct di_edid_cta * cta)1927 _di_edid_cta_finish(struct di_edid_cta *cta)
1928 {
1929 	size_t i;
1930 
1931 	for (i = 0; i < cta->data_blocks_len; i++) {
1932 		destroy_data_block(cta->data_blocks[i]);
1933 	}
1934 
1935 	for (i = 0; i < cta->detailed_timing_defs_len; i++) {
1936 		free(cta->detailed_timing_defs[i]);
1937 	}
1938 }
1939 
1940 int
di_edid_cta_get_revision(const struct di_edid_cta * cta)1941 di_edid_cta_get_revision(const struct di_edid_cta *cta)
1942 {
1943 	return cta->revision;
1944 }
1945 
1946 const struct di_edid_cta_flags *
di_edid_cta_get_flags(const struct di_edid_cta * cta)1947 di_edid_cta_get_flags(const struct di_edid_cta *cta)
1948 {
1949 	return &cta->flags;
1950 }
1951 
1952 const struct di_cta_data_block *const *
di_edid_cta_get_data_blocks(const struct di_edid_cta * cta)1953 di_edid_cta_get_data_blocks(const struct di_edid_cta *cta)
1954 {
1955 	return (const struct di_cta_data_block *const *) cta->data_blocks;
1956 }
1957 
1958 enum di_cta_data_block_tag
di_cta_data_block_get_tag(const struct di_cta_data_block * block)1959 di_cta_data_block_get_tag(const struct di_cta_data_block *block)
1960 {
1961 	return block->tag;
1962 }
1963 
1964 const struct di_cta_svd *const *
di_cta_data_block_get_svds(const struct di_cta_data_block * block)1965 di_cta_data_block_get_svds(const struct di_cta_data_block *block)
1966 {
1967 	if (block->tag != DI_CTA_DATA_BLOCK_VIDEO) {
1968 		return NULL;
1969 	}
1970 	return (const struct di_cta_svd *const *) block->video.svds;
1971 }
1972 
1973 const struct di_cta_svd *const *
di_cta_data_block_get_ycbcr420_svds(const struct di_cta_data_block * block)1974 di_cta_data_block_get_ycbcr420_svds(const struct di_cta_data_block *block)
1975 {
1976 	if (block->tag != DI_CTA_DATA_BLOCK_YCBCR420) {
1977 		return NULL;
1978 	}
1979 	return (const struct di_cta_svd *const *) block->ycbcr420.svds;
1980 }
1981 
1982 const struct di_cta_svr *const *
di_cta_data_block_get_svrs(const struct di_cta_data_block * block)1983 di_cta_data_block_get_svrs(const struct di_cta_data_block *block)
1984 {
1985 	if (block->tag != DI_CTA_DATA_BLOCK_VIDEO_FORMAT_PREF) {
1986 		return NULL;
1987 	}
1988 	return (const struct di_cta_svr *const *) block->video_format_pref.svrs;
1989 }
1990 
1991 const struct di_cta_sad *const *
di_cta_data_block_get_sads(const struct di_cta_data_block * block)1992 di_cta_data_block_get_sads(const struct di_cta_data_block *block)
1993 {
1994 	if (block->tag != DI_CTA_DATA_BLOCK_AUDIO) {
1995 		return NULL;
1996 	}
1997 	return (const struct di_cta_sad *const *) block->audio.sads;
1998 }
1999 
2000 const struct di_cta_speaker_alloc_block *
di_cta_data_block_get_speaker_alloc(const struct di_cta_data_block * block)2001 di_cta_data_block_get_speaker_alloc(const struct di_cta_data_block *block)
2002 {
2003 	if (block->tag != DI_CTA_DATA_BLOCK_SPEAKER_ALLOC) {
2004 		return NULL;
2005 	}
2006 	return &block->speaker_alloc;
2007 }
2008 
2009 const struct di_cta_colorimetry_block *
di_cta_data_block_get_colorimetry(const struct di_cta_data_block * block)2010 di_cta_data_block_get_colorimetry(const struct di_cta_data_block *block)
2011 {
2012 	if (block->tag != DI_CTA_DATA_BLOCK_COLORIMETRY) {
2013 		return NULL;
2014 	}
2015 	return &block->colorimetry;
2016 }
2017 
2018 const struct di_cta_hdr_static_metadata_block *
di_cta_data_block_get_hdr_static_metadata(const struct di_cta_data_block * block)2019 di_cta_data_block_get_hdr_static_metadata(const struct di_cta_data_block *block)
2020 {
2021 	if (block->tag != DI_CTA_DATA_BLOCK_HDR_STATIC_METADATA) {
2022 		return NULL;
2023 	}
2024 	return &block->hdr_static_metadata.base;
2025 }
2026 
2027 const struct di_cta_hdr_dynamic_metadata_block *
di_cta_data_block_get_hdr_dynamic_metadata(const struct di_cta_data_block * block)2028 di_cta_data_block_get_hdr_dynamic_metadata(const struct di_cta_data_block *block)
2029 {
2030 	if (block->tag != DI_CTA_DATA_BLOCK_HDR_DYNAMIC_METADATA) {
2031 		return NULL;
2032 	}
2033 	return &block->hdr_dynamic_metadata.base;
2034 }
2035 
2036 const struct di_cta_video_cap_block *
di_cta_data_block_get_video_cap(const struct di_cta_data_block * block)2037 di_cta_data_block_get_video_cap(const struct di_cta_data_block *block)
2038 {
2039 	if (block->tag != DI_CTA_DATA_BLOCK_VIDEO_CAP) {
2040 		return NULL;
2041 	}
2042 	return &block->video_cap;
2043 }
2044 
2045 const struct di_cta_vesa_dddb *
di_cta_data_block_get_vesa_dddb(const struct di_cta_data_block * block)2046 di_cta_data_block_get_vesa_dddb(const struct di_cta_data_block *block)
2047 {
2048 	if (block->tag != DI_CTA_DATA_BLOCK_VESA_DISPLAY_DEVICE) {
2049 		return NULL;
2050 	}
2051 	return &block->vesa_dddb;
2052 }
2053 
2054 bool
di_cta_ycbcr420_cap_map_supported(const struct di_cta_ycbcr420_cap_map * cap_map,size_t svd_index)2055 di_cta_ycbcr420_cap_map_supported(const struct di_cta_ycbcr420_cap_map *cap_map,
2056 				  size_t svd_index)
2057 {
2058 	size_t byte, bit;
2059 
2060 	if (cap_map->all)
2061 		return true;
2062 
2063 	byte = svd_index / 8;
2064 	bit = svd_index % 8;
2065 
2066 	if (byte >= EDID_CTA_MAX_YCBCR420_CAP_MAP_BLOCK_ENTRIES)
2067 		return false;
2068 
2069 	return cap_map->svd_bitmap[byte] & (1 << bit);
2070 }
2071 
2072 const struct di_cta_ycbcr420_cap_map *
di_cta_data_block_get_ycbcr420_cap_map(const struct di_cta_data_block * block)2073 di_cta_data_block_get_ycbcr420_cap_map(const struct di_cta_data_block *block)
2074 {
2075 	if (block->tag != DI_CTA_DATA_BLOCK_YCBCR420_CAP_MAP) {
2076 		return NULL;
2077 	}
2078 	return &block->ycbcr420_cap_map;
2079 }
2080 
2081 const struct di_cta_hdmi_audio_block *
di_cta_data_block_get_hdmi_audio(const struct di_cta_data_block * block)2082 di_cta_data_block_get_hdmi_audio(const struct di_cta_data_block *block)
2083 {
2084 	if (block->tag != DI_CTA_DATA_BLOCK_HDMI_AUDIO) {
2085 		return NULL;
2086 	}
2087 	return &block->hdmi_audio.base;
2088 }
2089 
2090 const struct di_cta_infoframe_block *
di_cta_data_block_get_infoframe(const struct di_cta_data_block * block)2091 di_cta_data_block_get_infoframe(const struct di_cta_data_block *block)
2092 {
2093 	if (block->tag != DI_CTA_DATA_BLOCK_INFOFRAME) {
2094 		return NULL;
2095 	}
2096 	return &block->infoframe.block;
2097 }
2098 
2099 const struct di_cta_speaker_locations *const *
di_cta_data_block_get_speaker_locations(const struct di_cta_data_block * block)2100 di_cta_data_block_get_speaker_locations(const struct di_cta_data_block *block)
2101 {
2102 	if (block->tag != DI_CTA_DATA_BLOCK_SPEAKER_LOCATION) {
2103 		return NULL;
2104 	}
2105 	return (const struct di_cta_speaker_locations *const *) block->speaker_location.locations;
2106 }
2107 
2108 const struct di_displayid_type_i_ii_vii_timing *
di_cta_data_block_get_did_type_vii_timing(const struct di_cta_data_block * block)2109 di_cta_data_block_get_did_type_vii_timing(const struct di_cta_data_block *block)
2110 {
2111 	if (block->tag != DI_CTA_DATA_BLOCK_DISPLAYID_VIDEO_TIMING_VII) {
2112 		return NULL;
2113 	}
2114 	return &block->did_vii_timing;
2115 }
2116 
2117 const struct di_edid_detailed_timing_def *const *
di_edid_cta_get_detailed_timing_defs(const struct di_edid_cta * cta)2118 di_edid_cta_get_detailed_timing_defs(const struct di_edid_cta *cta)
2119 {
2120 	return (const struct di_edid_detailed_timing_def *const *) cta->detailed_timing_defs;
2121 }
2122 
2123 const struct di_cta_vesa_transfer_characteristics *
di_cta_data_block_get_vesa_transfer_characteristics(const struct di_cta_data_block * block)2124 di_cta_data_block_get_vesa_transfer_characteristics(const struct di_cta_data_block *block)
2125 {
2126 	if (block->tag != DI_CTA_DATA_BLOCK_VESA_DISPLAY_TRANSFER_CHARACTERISTIC) {
2127 		return NULL;
2128 	}
2129 	return &block->vesa_transfer_characteristics;
2130 }
2131 
2132 const struct di_cta_room_configuration *
di_cta_data_block_get_room_configuration(const struct di_cta_data_block * block)2133 di_cta_data_block_get_room_configuration(const struct di_cta_data_block *block)
2134 {
2135 	if (block->tag != DI_CTA_DATA_BLOCK_ROOM_CONFIG) {
2136 		return NULL;
2137 	}
2138 	return &block->room_config;
2139 }
2140