xref: /freebsd/sys/compat/linuxkpi/common/src/linux_hdmi.c (revision c89d94ad5d95fd15e891b2723caae8a6104ee153)
1 /*
2  * Copyright (C) 2012 Avionic Design GmbH
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sub license,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the
12  * next paragraph) shall be included in all copies or substantial portions
13  * of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #ifdef __linux__
25 #include <drm/display/drm_dp.h>
26 #endif
27 #include <linux/bitops.h>
28 #include <linux/bug.h>
29 #include <linux/errno.h>
30 #include <linux/export.h>
31 #include <linux/hdmi.h>
32 #include <linux/string.h>
33 #include <linux/device.h>
34 
35 #define hdmi_log(fmt, ...) dev_printk(level, dev, fmt, ##__VA_ARGS__)
36 
hdmi_infoframe_checksum(const u8 * ptr,size_t size)37 static u8 hdmi_infoframe_checksum(const u8 *ptr, size_t size)
38 {
39 	u8 csum = 0;
40 	size_t i;
41 
42 	/* compute checksum */
43 	for (i = 0; i < size; i++)
44 		csum += ptr[i];
45 
46 	return 256 - csum;
47 }
48 
hdmi_infoframe_set_checksum(void * buffer,size_t size)49 static void hdmi_infoframe_set_checksum(void *buffer, size_t size)
50 {
51 	u8 *ptr = buffer;
52 
53 	ptr[3] = hdmi_infoframe_checksum(buffer, size);
54 }
55 
56 /**
57  * hdmi_avi_infoframe_init() - initialize an HDMI AVI infoframe
58  * @frame: HDMI AVI infoframe
59  */
hdmi_avi_infoframe_init(struct hdmi_avi_infoframe * frame)60 void hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame)
61 {
62 	memset(frame, 0, sizeof(*frame));
63 
64 	frame->type = HDMI_INFOFRAME_TYPE_AVI;
65 	frame->version = 2;
66 	frame->length = HDMI_AVI_INFOFRAME_SIZE;
67 }
68 EXPORT_SYMBOL(hdmi_avi_infoframe_init);
69 
hdmi_avi_infoframe_check_only(const struct hdmi_avi_infoframe * frame)70 static int hdmi_avi_infoframe_check_only(const struct hdmi_avi_infoframe *frame)
71 {
72 	if (frame->type != HDMI_INFOFRAME_TYPE_AVI ||
73 	    frame->version != 2 ||
74 	    frame->length != HDMI_AVI_INFOFRAME_SIZE)
75 		return -EINVAL;
76 
77 	if (frame->picture_aspect > HDMI_PICTURE_ASPECT_16_9)
78 		return -EINVAL;
79 
80 	return 0;
81 }
82 
83 /**
84  * hdmi_avi_infoframe_check() - check a HDMI AVI infoframe
85  * @frame: HDMI AVI infoframe
86  *
87  * Validates that the infoframe is consistent and updates derived fields
88  * (eg. length) based on other fields.
89  *
90  * Returns 0 on success or a negative error code on failure.
91  */
hdmi_avi_infoframe_check(struct hdmi_avi_infoframe * frame)92 int hdmi_avi_infoframe_check(struct hdmi_avi_infoframe *frame)
93 {
94 	return hdmi_avi_infoframe_check_only(frame);
95 }
96 EXPORT_SYMBOL(hdmi_avi_infoframe_check);
97 
98 /**
99  * hdmi_avi_infoframe_pack_only() - write HDMI AVI infoframe to binary buffer
100  * @frame: HDMI AVI infoframe
101  * @buffer: destination buffer
102  * @size: size of buffer
103  *
104  * Packs the information contained in the @frame structure into a binary
105  * representation that can be written into the corresponding controller
106  * registers. Also computes the checksum as required by section 5.3.5 of
107  * the HDMI 1.4 specification.
108  *
109  * Returns the number of bytes packed into the binary buffer or a negative
110  * error code on failure.
111  */
hdmi_avi_infoframe_pack_only(const struct hdmi_avi_infoframe * frame,void * buffer,size_t size)112 ssize_t hdmi_avi_infoframe_pack_only(const struct hdmi_avi_infoframe *frame,
113 				     void *buffer, size_t size)
114 {
115 	u8 *ptr = buffer;
116 	size_t length;
117 	int ret;
118 
119 	ret = hdmi_avi_infoframe_check_only(frame);
120 	if (ret)
121 		return ret;
122 
123 	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
124 
125 	if (size < length)
126 		return -ENOSPC;
127 
128 	memset(buffer, 0, size);
129 
130 	ptr[0] = frame->type;
131 	ptr[1] = frame->version;
132 	ptr[2] = frame->length;
133 	ptr[3] = 0; /* checksum */
134 
135 	/* start infoframe payload */
136 	ptr += HDMI_INFOFRAME_HEADER_SIZE;
137 
138 	ptr[0] = ((frame->colorspace & 0x3) << 5) | (frame->scan_mode & 0x3);
139 
140 	/*
141 	 * Data byte 1, bit 4 has to be set if we provide the active format
142 	 * aspect ratio
143 	 */
144 	if (frame->active_aspect & 0xf)
145 		ptr[0] |= BIT(4);
146 
147 	/* Bit 3 and 2 indicate if we transmit horizontal/vertical bar data */
148 	if (frame->top_bar || frame->bottom_bar)
149 		ptr[0] |= BIT(3);
150 
151 	if (frame->left_bar || frame->right_bar)
152 		ptr[0] |= BIT(2);
153 
154 	ptr[1] = ((frame->colorimetry & 0x3) << 6) |
155 		 ((frame->picture_aspect & 0x3) << 4) |
156 		 (frame->active_aspect & 0xf);
157 
158 	ptr[2] = ((frame->extended_colorimetry & 0x7) << 4) |
159 		 ((frame->quantization_range & 0x3) << 2) |
160 		 (frame->nups & 0x3);
161 
162 	if (frame->itc)
163 		ptr[2] |= BIT(7);
164 
165 	ptr[3] = frame->video_code & 0x7f;
166 
167 	ptr[4] = ((frame->ycc_quantization_range & 0x3) << 6) |
168 		 ((frame->content_type & 0x3) << 4) |
169 		 (frame->pixel_repeat & 0xf);
170 
171 	ptr[5] = frame->top_bar & 0xff;
172 	ptr[6] = (frame->top_bar >> 8) & 0xff;
173 	ptr[7] = frame->bottom_bar & 0xff;
174 	ptr[8] = (frame->bottom_bar >> 8) & 0xff;
175 	ptr[9] = frame->left_bar & 0xff;
176 	ptr[10] = (frame->left_bar >> 8) & 0xff;
177 	ptr[11] = frame->right_bar & 0xff;
178 	ptr[12] = (frame->right_bar >> 8) & 0xff;
179 
180 	hdmi_infoframe_set_checksum(buffer, length);
181 
182 	return length;
183 }
184 EXPORT_SYMBOL(hdmi_avi_infoframe_pack_only);
185 
186 /**
187  * hdmi_avi_infoframe_pack() - check a HDMI AVI infoframe,
188  *                             and write it to binary buffer
189  * @frame: HDMI AVI infoframe
190  * @buffer: destination buffer
191  * @size: size of buffer
192  *
193  * Validates that the infoframe is consistent and updates derived fields
194  * (eg. length) based on other fields, after which it packs the information
195  * contained in the @frame structure into a binary representation that
196  * can be written into the corresponding controller registers. This function
197  * also computes the checksum as required by section 5.3.5 of the HDMI 1.4
198  * specification.
199  *
200  * Returns the number of bytes packed into the binary buffer or a negative
201  * error code on failure.
202  */
hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe * frame,void * buffer,size_t size)203 ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame,
204 				void *buffer, size_t size)
205 {
206 	int ret;
207 
208 	ret = hdmi_avi_infoframe_check(frame);
209 	if (ret)
210 		return ret;
211 
212 	return hdmi_avi_infoframe_pack_only(frame, buffer, size);
213 }
214 EXPORT_SYMBOL(hdmi_avi_infoframe_pack);
215 
216 /**
217  * hdmi_spd_infoframe_init() - initialize an HDMI SPD infoframe
218  * @frame: HDMI SPD infoframe
219  * @vendor: vendor string
220  * @product: product string
221  *
222  * Returns 0 on success or a negative error code on failure.
223  */
hdmi_spd_infoframe_init(struct hdmi_spd_infoframe * frame,const char * vendor,const char * product)224 int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame,
225 			    const char *vendor, const char *product)
226 {
227 	size_t len;
228 
229 	memset(frame, 0, sizeof(*frame));
230 
231 	frame->type = HDMI_INFOFRAME_TYPE_SPD;
232 	frame->version = 1;
233 	frame->length = HDMI_SPD_INFOFRAME_SIZE;
234 
235 	len = strlen(vendor);
236 	memcpy(frame->vendor, vendor, min(len, sizeof(frame->vendor)));
237 	len = strlen(product);
238 	memcpy(frame->product, product, min(len, sizeof(frame->product)));
239 
240 	return 0;
241 }
242 EXPORT_SYMBOL(hdmi_spd_infoframe_init);
243 
hdmi_spd_infoframe_check_only(const struct hdmi_spd_infoframe * frame)244 static int hdmi_spd_infoframe_check_only(const struct hdmi_spd_infoframe *frame)
245 {
246 	if (frame->type != HDMI_INFOFRAME_TYPE_SPD ||
247 	    frame->version != 1 ||
248 	    frame->length != HDMI_SPD_INFOFRAME_SIZE)
249 		return -EINVAL;
250 
251 	return 0;
252 }
253 
254 /**
255  * hdmi_spd_infoframe_check() - check a HDMI SPD infoframe
256  * @frame: HDMI SPD infoframe
257  *
258  * Validates that the infoframe is consistent and updates derived fields
259  * (eg. length) based on other fields.
260  *
261  * Returns 0 on success or a negative error code on failure.
262  */
hdmi_spd_infoframe_check(struct hdmi_spd_infoframe * frame)263 int hdmi_spd_infoframe_check(struct hdmi_spd_infoframe *frame)
264 {
265 	return hdmi_spd_infoframe_check_only(frame);
266 }
267 EXPORT_SYMBOL(hdmi_spd_infoframe_check);
268 
269 /**
270  * hdmi_spd_infoframe_pack_only() - write HDMI SPD infoframe to binary buffer
271  * @frame: HDMI SPD infoframe
272  * @buffer: destination buffer
273  * @size: size of buffer
274  *
275  * Packs the information contained in the @frame structure into a binary
276  * representation that can be written into the corresponding controller
277  * registers. Also computes the checksum as required by section 5.3.5 of
278  * the HDMI 1.4 specification.
279  *
280  * Returns the number of bytes packed into the binary buffer or a negative
281  * error code on failure.
282  */
hdmi_spd_infoframe_pack_only(const struct hdmi_spd_infoframe * frame,void * buffer,size_t size)283 ssize_t hdmi_spd_infoframe_pack_only(const struct hdmi_spd_infoframe *frame,
284 				     void *buffer, size_t size)
285 {
286 	u8 *ptr = buffer;
287 	size_t length;
288 	int ret;
289 
290 	ret = hdmi_spd_infoframe_check_only(frame);
291 	if (ret)
292 		return ret;
293 
294 	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
295 
296 	if (size < length)
297 		return -ENOSPC;
298 
299 	memset(buffer, 0, size);
300 
301 	ptr[0] = frame->type;
302 	ptr[1] = frame->version;
303 	ptr[2] = frame->length;
304 	ptr[3] = 0; /* checksum */
305 
306 	/* start infoframe payload */
307 	ptr += HDMI_INFOFRAME_HEADER_SIZE;
308 
309 	memcpy(ptr, frame->vendor, sizeof(frame->vendor));
310 	memcpy(ptr + 8, frame->product, sizeof(frame->product));
311 
312 	ptr[24] = frame->sdi;
313 
314 	hdmi_infoframe_set_checksum(buffer, length);
315 
316 	return length;
317 }
318 EXPORT_SYMBOL(hdmi_spd_infoframe_pack_only);
319 
320 /**
321  * hdmi_spd_infoframe_pack() - check a HDMI SPD infoframe,
322  *                             and write it to binary buffer
323  * @frame: HDMI SPD infoframe
324  * @buffer: destination buffer
325  * @size: size of buffer
326  *
327  * Validates that the infoframe is consistent and updates derived fields
328  * (eg. length) based on other fields, after which it packs the information
329  * contained in the @frame structure into a binary representation that
330  * can be written into the corresponding controller registers. This function
331  * also computes the checksum as required by section 5.3.5 of the HDMI 1.4
332  * specification.
333  *
334  * Returns the number of bytes packed into the binary buffer or a negative
335  * error code on failure.
336  */
hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe * frame,void * buffer,size_t size)337 ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame,
338 				void *buffer, size_t size)
339 {
340 	int ret;
341 
342 	ret = hdmi_spd_infoframe_check(frame);
343 	if (ret)
344 		return ret;
345 
346 	return hdmi_spd_infoframe_pack_only(frame, buffer, size);
347 }
348 EXPORT_SYMBOL(hdmi_spd_infoframe_pack);
349 
350 /**
351  * hdmi_audio_infoframe_init() - initialize an HDMI audio infoframe
352  * @frame: HDMI audio infoframe
353  *
354  * Returns 0 on success or a negative error code on failure.
355  */
hdmi_audio_infoframe_init(struct hdmi_audio_infoframe * frame)356 int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame)
357 {
358 	memset(frame, 0, sizeof(*frame));
359 
360 	frame->type = HDMI_INFOFRAME_TYPE_AUDIO;
361 	frame->version = 1;
362 	frame->length = HDMI_AUDIO_INFOFRAME_SIZE;
363 
364 	return 0;
365 }
366 EXPORT_SYMBOL(hdmi_audio_infoframe_init);
367 
hdmi_audio_infoframe_check_only(const struct hdmi_audio_infoframe * frame)368 static int hdmi_audio_infoframe_check_only(const struct hdmi_audio_infoframe *frame)
369 {
370 	if (frame->type != HDMI_INFOFRAME_TYPE_AUDIO ||
371 	    frame->version != 1 ||
372 	    frame->length != HDMI_AUDIO_INFOFRAME_SIZE)
373 		return -EINVAL;
374 
375 	return 0;
376 }
377 
378 /**
379  * hdmi_audio_infoframe_check() - check a HDMI audio infoframe
380  * @frame: HDMI audio infoframe
381  *
382  * Validates that the infoframe is consistent and updates derived fields
383  * (eg. length) based on other fields.
384  *
385  * Returns 0 on success or a negative error code on failure.
386  */
hdmi_audio_infoframe_check(const struct hdmi_audio_infoframe * frame)387 int hdmi_audio_infoframe_check(const struct hdmi_audio_infoframe *frame)
388 {
389 	return hdmi_audio_infoframe_check_only(frame);
390 }
391 EXPORT_SYMBOL(hdmi_audio_infoframe_check);
392 
393 static void
hdmi_audio_infoframe_pack_payload(const struct hdmi_audio_infoframe * frame,u8 * buffer)394 hdmi_audio_infoframe_pack_payload(const struct hdmi_audio_infoframe *frame,
395 				  u8 *buffer)
396 {
397 	u8 channels;
398 
399 	if (frame->channels >= 2)
400 		channels = frame->channels - 1;
401 	else
402 		channels = 0;
403 
404 	buffer[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7);
405 	buffer[1] = ((frame->sample_frequency & 0x7) << 2) |
406 		 (frame->sample_size & 0x3);
407 	buffer[2] = frame->coding_type_ext & 0x1f;
408 	buffer[3] = frame->channel_allocation;
409 	buffer[4] = (frame->level_shift_value & 0xf) << 3;
410 
411 	if (frame->downmix_inhibit)
412 		buffer[4] |= BIT(7);
413 }
414 
415 /**
416  * hdmi_audio_infoframe_pack_only() - write HDMI audio infoframe to binary buffer
417  * @frame: HDMI audio infoframe
418  * @buffer: destination buffer
419  * @size: size of buffer
420  *
421  * Packs the information contained in the @frame structure into a binary
422  * representation that can be written into the corresponding controller
423  * registers. Also computes the checksum as required by section 5.3.5 of
424  * the HDMI 1.4 specification.
425  *
426  * Returns the number of bytes packed into the binary buffer or a negative
427  * error code on failure.
428  */
hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe * frame,void * buffer,size_t size)429 ssize_t hdmi_audio_infoframe_pack_only(const struct hdmi_audio_infoframe *frame,
430 				       void *buffer, size_t size)
431 {
432 	u8 *ptr = buffer;
433 	size_t length;
434 	int ret;
435 
436 	ret = hdmi_audio_infoframe_check_only(frame);
437 	if (ret)
438 		return ret;
439 
440 	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
441 
442 	if (size < length)
443 		return -ENOSPC;
444 
445 	memset(buffer, 0, size);
446 
447 	ptr[0] = frame->type;
448 	ptr[1] = frame->version;
449 	ptr[2] = frame->length;
450 	ptr[3] = 0; /* checksum */
451 
452 	hdmi_audio_infoframe_pack_payload(frame,
453 					  ptr + HDMI_INFOFRAME_HEADER_SIZE);
454 
455 	hdmi_infoframe_set_checksum(buffer, length);
456 
457 	return length;
458 }
459 EXPORT_SYMBOL(hdmi_audio_infoframe_pack_only);
460 
461 /**
462  * hdmi_audio_infoframe_pack() - check a HDMI Audio infoframe,
463  *                               and write it to binary buffer
464  * @frame: HDMI Audio infoframe
465  * @buffer: destination buffer
466  * @size: size of buffer
467  *
468  * Validates that the infoframe is consistent and updates derived fields
469  * (eg. length) based on other fields, after which it packs the information
470  * contained in the @frame structure into a binary representation that
471  * can be written into the corresponding controller registers. This function
472  * also computes the checksum as required by section 5.3.5 of the HDMI 1.4
473  * specification.
474  *
475  * Returns the number of bytes packed into the binary buffer or a negative
476  * error code on failure.
477  */
hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe * frame,void * buffer,size_t size)478 ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame,
479 				  void *buffer, size_t size)
480 {
481 	int ret;
482 
483 	ret = hdmi_audio_infoframe_check(frame);
484 	if (ret)
485 		return ret;
486 
487 	return hdmi_audio_infoframe_pack_only(frame, buffer, size);
488 }
489 EXPORT_SYMBOL(hdmi_audio_infoframe_pack);
490 
491 #ifdef __linux__
492 /**
493  * hdmi_audio_infoframe_pack_for_dp - Pack a HDMI Audio infoframe for DisplayPort
494  *
495  * @frame:      HDMI Audio infoframe
496  * @sdp:        Secondary data packet for DisplayPort.
497  * @dp_version: DisplayPort version to be encoded in the header
498  *
499  * Packs a HDMI Audio Infoframe to be sent over DisplayPort. This function
500  * fills the secondary data packet to be used for DisplayPort.
501  *
502  * Return: Number of total written bytes or a negative errno on failure.
503  */
504 ssize_t
hdmi_audio_infoframe_pack_for_dp(const struct hdmi_audio_infoframe * frame,struct dp_sdp * sdp,u8 dp_version)505 hdmi_audio_infoframe_pack_for_dp(const struct hdmi_audio_infoframe *frame,
506 				 struct dp_sdp *sdp, u8 dp_version)
507 {
508 	int ret;
509 
510 	ret = hdmi_audio_infoframe_check(frame);
511 	if (ret)
512 		return ret;
513 
514 	memset(sdp->db, 0, sizeof(sdp->db));
515 
516 	/* Secondary-data packet header */
517 	sdp->sdp_header.HB0 = 0;
518 	sdp->sdp_header.HB1 = frame->type;
519 	sdp->sdp_header.HB2 = DP_SDP_AUDIO_INFOFRAME_HB2;
520 	sdp->sdp_header.HB3 = (dp_version & 0x3f) << 2;
521 
522 	hdmi_audio_infoframe_pack_payload(frame, sdp->db);
523 
524 	/* Return size =  frame length + four HB for sdp_header */
525 	return frame->length + 4;
526 }
527 EXPORT_SYMBOL(hdmi_audio_infoframe_pack_for_dp);
528 #endif
529 
530 /**
531  * hdmi_vendor_infoframe_init() - initialize an HDMI vendor infoframe
532  * @frame: HDMI vendor infoframe
533  *
534  * Returns 0 on success or a negative error code on failure.
535  */
hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe * frame)536 int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame)
537 {
538 	memset(frame, 0, sizeof(*frame));
539 
540 	frame->type = HDMI_INFOFRAME_TYPE_VENDOR;
541 	frame->version = 1;
542 
543 	frame->oui = HDMI_IEEE_OUI;
544 
545 	/*
546 	 * 0 is a valid value for s3d_struct, so we use a special "not set"
547 	 * value
548 	 */
549 	frame->s3d_struct = HDMI_3D_STRUCTURE_INVALID;
550 	frame->length = HDMI_VENDOR_INFOFRAME_SIZE;
551 
552 	return 0;
553 }
554 EXPORT_SYMBOL(hdmi_vendor_infoframe_init);
555 
hdmi_vendor_infoframe_length(const struct hdmi_vendor_infoframe * frame)556 static int hdmi_vendor_infoframe_length(const struct hdmi_vendor_infoframe *frame)
557 {
558 	/* for side by side (half) we also need to provide 3D_Ext_Data */
559 	if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
560 		return 6;
561 	else if (frame->vic != 0 || frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID)
562 		return 5;
563 	else
564 		return 4;
565 }
566 
hdmi_vendor_infoframe_check_only(const struct hdmi_vendor_infoframe * frame)567 static int hdmi_vendor_infoframe_check_only(const struct hdmi_vendor_infoframe *frame)
568 {
569 	if (frame->type != HDMI_INFOFRAME_TYPE_VENDOR ||
570 	    frame->version != 1 ||
571 	    frame->oui != HDMI_IEEE_OUI)
572 		return -EINVAL;
573 
574 	/* only one of those can be supplied */
575 	if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID)
576 		return -EINVAL;
577 
578 	if (frame->length != hdmi_vendor_infoframe_length(frame))
579 		return -EINVAL;
580 
581 	return 0;
582 }
583 
584 /**
585  * hdmi_vendor_infoframe_check() - check a HDMI vendor infoframe
586  * @frame: HDMI infoframe
587  *
588  * Validates that the infoframe is consistent and updates derived fields
589  * (eg. length) based on other fields.
590  *
591  * Returns 0 on success or a negative error code on failure.
592  */
hdmi_vendor_infoframe_check(struct hdmi_vendor_infoframe * frame)593 int hdmi_vendor_infoframe_check(struct hdmi_vendor_infoframe *frame)
594 {
595 	frame->length = hdmi_vendor_infoframe_length(frame);
596 
597 	return hdmi_vendor_infoframe_check_only(frame);
598 }
599 EXPORT_SYMBOL(hdmi_vendor_infoframe_check);
600 
601 /**
602  * hdmi_vendor_infoframe_pack_only() - write a HDMI vendor infoframe to binary buffer
603  * @frame: HDMI infoframe
604  * @buffer: destination buffer
605  * @size: size of buffer
606  *
607  * Packs the information contained in the @frame structure into a binary
608  * representation that can be written into the corresponding controller
609  * registers. Also computes the checksum as required by section 5.3.5 of
610  * the HDMI 1.4 specification.
611  *
612  * Returns the number of bytes packed into the binary buffer or a negative
613  * error code on failure.
614  */
hdmi_vendor_infoframe_pack_only(const struct hdmi_vendor_infoframe * frame,void * buffer,size_t size)615 ssize_t hdmi_vendor_infoframe_pack_only(const struct hdmi_vendor_infoframe *frame,
616 					void *buffer, size_t size)
617 {
618 	u8 *ptr = buffer;
619 	size_t length;
620 	int ret;
621 
622 	ret = hdmi_vendor_infoframe_check_only(frame);
623 	if (ret)
624 		return ret;
625 
626 	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
627 
628 	if (size < length)
629 		return -ENOSPC;
630 
631 	memset(buffer, 0, size);
632 
633 	ptr[0] = frame->type;
634 	ptr[1] = frame->version;
635 	ptr[2] = frame->length;
636 	ptr[3] = 0; /* checksum */
637 
638 	/* HDMI OUI */
639 	ptr[4] = 0x03;
640 	ptr[5] = 0x0c;
641 	ptr[6] = 0x00;
642 
643 	if (frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) {
644 		ptr[7] = 0x2 << 5;	/* video format */
645 		ptr[8] = (frame->s3d_struct & 0xf) << 4;
646 		if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
647 			ptr[9] = (frame->s3d_ext_data & 0xf) << 4;
648 	} else if (frame->vic) {
649 		ptr[7] = 0x1 << 5;	/* video format */
650 		ptr[8] = frame->vic;
651 	} else {
652 		ptr[7] = 0x0 << 5;	/* video format */
653 	}
654 
655 	hdmi_infoframe_set_checksum(buffer, length);
656 
657 	return length;
658 }
659 EXPORT_SYMBOL(hdmi_vendor_infoframe_pack_only);
660 
661 /**
662  * hdmi_vendor_infoframe_pack() - check a HDMI Vendor infoframe,
663  *                                and write it to binary buffer
664  * @frame: HDMI Vendor infoframe
665  * @buffer: destination buffer
666  * @size: size of buffer
667  *
668  * Validates that the infoframe is consistent and updates derived fields
669  * (eg. length) based on other fields, after which it packs the information
670  * contained in the @frame structure into a binary representation that
671  * can be written into the corresponding controller registers. This function
672  * also computes the checksum as required by section 5.3.5 of the HDMI 1.4
673  * specification.
674  *
675  * Returns the number of bytes packed into the binary buffer or a negative
676  * error code on failure.
677  */
hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe * frame,void * buffer,size_t size)678 ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
679 				   void *buffer, size_t size)
680 {
681 	int ret;
682 
683 	ret = hdmi_vendor_infoframe_check(frame);
684 	if (ret)
685 		return ret;
686 
687 	return hdmi_vendor_infoframe_pack_only(frame, buffer, size);
688 }
689 EXPORT_SYMBOL(hdmi_vendor_infoframe_pack);
690 
691 static int
hdmi_vendor_any_infoframe_check_only(const union hdmi_vendor_any_infoframe * frame)692 hdmi_vendor_any_infoframe_check_only(const union hdmi_vendor_any_infoframe *frame)
693 {
694 	if (frame->any.type != HDMI_INFOFRAME_TYPE_VENDOR ||
695 	    frame->any.version != 1)
696 		return -EINVAL;
697 
698 	return 0;
699 }
700 
701 /**
702  * hdmi_drm_infoframe_init() - initialize an HDMI Dynaminc Range and
703  * mastering infoframe
704  * @frame: HDMI DRM infoframe
705  *
706  * Returns 0 on success or a negative error code on failure.
707  */
hdmi_drm_infoframe_init(struct hdmi_drm_infoframe * frame)708 int hdmi_drm_infoframe_init(struct hdmi_drm_infoframe *frame)
709 {
710 	memset(frame, 0, sizeof(*frame));
711 
712 	frame->type = HDMI_INFOFRAME_TYPE_DRM;
713 	frame->version = 1;
714 	frame->length = HDMI_DRM_INFOFRAME_SIZE;
715 
716 	return 0;
717 }
718 EXPORT_SYMBOL(hdmi_drm_infoframe_init);
719 
hdmi_drm_infoframe_check_only(const struct hdmi_drm_infoframe * frame)720 static int hdmi_drm_infoframe_check_only(const struct hdmi_drm_infoframe *frame)
721 {
722 	if (frame->type != HDMI_INFOFRAME_TYPE_DRM ||
723 	    frame->version != 1)
724 		return -EINVAL;
725 
726 	if (frame->length != HDMI_DRM_INFOFRAME_SIZE)
727 		return -EINVAL;
728 
729 	return 0;
730 }
731 
732 /**
733  * hdmi_drm_infoframe_check() - check a HDMI DRM infoframe
734  * @frame: HDMI DRM infoframe
735  *
736  * Validates that the infoframe is consistent.
737  * Returns 0 on success or a negative error code on failure.
738  */
hdmi_drm_infoframe_check(struct hdmi_drm_infoframe * frame)739 int hdmi_drm_infoframe_check(struct hdmi_drm_infoframe *frame)
740 {
741 	return hdmi_drm_infoframe_check_only(frame);
742 }
743 EXPORT_SYMBOL(hdmi_drm_infoframe_check);
744 
745 /**
746  * hdmi_drm_infoframe_pack_only() - write HDMI DRM infoframe to binary buffer
747  * @frame: HDMI DRM infoframe
748  * @buffer: destination buffer
749  * @size: size of buffer
750  *
751  * Packs the information contained in the @frame structure into a binary
752  * representation that can be written into the corresponding controller
753  * registers. Also computes the checksum as required by section 5.3.5 of
754  * the HDMI 1.4 specification.
755  *
756  * Returns the number of bytes packed into the binary buffer or a negative
757  * error code on failure.
758  */
hdmi_drm_infoframe_pack_only(const struct hdmi_drm_infoframe * frame,void * buffer,size_t size)759 ssize_t hdmi_drm_infoframe_pack_only(const struct hdmi_drm_infoframe *frame,
760 				     void *buffer, size_t size)
761 {
762 	u8 *ptr = buffer;
763 	size_t length;
764 	int i;
765 
766 	length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
767 
768 	if (size < length)
769 		return -ENOSPC;
770 
771 	memset(buffer, 0, size);
772 
773 	ptr[0] = frame->type;
774 	ptr[1] = frame->version;
775 	ptr[2] = frame->length;
776 	ptr[3] = 0; /* checksum */
777 
778 	/* start infoframe payload */
779 	ptr += HDMI_INFOFRAME_HEADER_SIZE;
780 
781 	*ptr++ = frame->eotf;
782 	*ptr++ = frame->metadata_type;
783 
784 	for (i = 0; i < 3; i++) {
785 		*ptr++ = frame->display_primaries[i].x;
786 		*ptr++ = frame->display_primaries[i].x >> 8;
787 		*ptr++ = frame->display_primaries[i].y;
788 		*ptr++ = frame->display_primaries[i].y >> 8;
789 	}
790 
791 	*ptr++ = frame->white_point.x;
792 	*ptr++ = frame->white_point.x >> 8;
793 
794 	*ptr++ = frame->white_point.y;
795 	*ptr++ = frame->white_point.y >> 8;
796 
797 	*ptr++ = frame->max_display_mastering_luminance;
798 	*ptr++ = frame->max_display_mastering_luminance >> 8;
799 
800 	*ptr++ = frame->min_display_mastering_luminance;
801 	*ptr++ = frame->min_display_mastering_luminance >> 8;
802 
803 	*ptr++ = frame->max_cll;
804 	*ptr++ = frame->max_cll >> 8;
805 
806 	*ptr++ = frame->max_fall;
807 	*ptr++ = frame->max_fall >> 8;
808 
809 	hdmi_infoframe_set_checksum(buffer, length);
810 
811 	return length;
812 }
813 EXPORT_SYMBOL(hdmi_drm_infoframe_pack_only);
814 
815 /**
816  * hdmi_drm_infoframe_pack() - check a HDMI DRM infoframe,
817  *                             and write it to binary buffer
818  * @frame: HDMI DRM infoframe
819  * @buffer: destination buffer
820  * @size: size of buffer
821  *
822  * Validates that the infoframe is consistent and updates derived fields
823  * (eg. length) based on other fields, after which it packs the information
824  * contained in the @frame structure into a binary representation that
825  * can be written into the corresponding controller registers. This function
826  * also computes the checksum as required by section 5.3.5 of the HDMI 1.4
827  * specification.
828  *
829  * Returns the number of bytes packed into the binary buffer or a negative
830  * error code on failure.
831  */
hdmi_drm_infoframe_pack(struct hdmi_drm_infoframe * frame,void * buffer,size_t size)832 ssize_t hdmi_drm_infoframe_pack(struct hdmi_drm_infoframe *frame,
833 				void *buffer, size_t size)
834 {
835 	int ret;
836 
837 	ret = hdmi_drm_infoframe_check(frame);
838 	if (ret)
839 		return ret;
840 
841 	return hdmi_drm_infoframe_pack_only(frame, buffer, size);
842 }
843 EXPORT_SYMBOL(hdmi_drm_infoframe_pack);
844 
845 /*
846  * hdmi_vendor_any_infoframe_check() - check a vendor infoframe
847  */
848 static int
hdmi_vendor_any_infoframe_check(union hdmi_vendor_any_infoframe * frame)849 hdmi_vendor_any_infoframe_check(union hdmi_vendor_any_infoframe *frame)
850 {
851 	int ret;
852 
853 	ret = hdmi_vendor_any_infoframe_check_only(frame);
854 	if (ret)
855 		return ret;
856 
857 	/* we only know about HDMI vendor infoframes */
858 	if (frame->any.oui != HDMI_IEEE_OUI)
859 		return -EINVAL;
860 
861 	return hdmi_vendor_infoframe_check(&frame->hdmi);
862 }
863 
864 /*
865  * hdmi_vendor_any_infoframe_pack_only() - write a vendor infoframe to binary buffer
866  */
867 static ssize_t
hdmi_vendor_any_infoframe_pack_only(const union hdmi_vendor_any_infoframe * frame,void * buffer,size_t size)868 hdmi_vendor_any_infoframe_pack_only(const union hdmi_vendor_any_infoframe *frame,
869 				    void *buffer, size_t size)
870 {
871 	int ret;
872 
873 	ret = hdmi_vendor_any_infoframe_check_only(frame);
874 	if (ret)
875 		return ret;
876 
877 	/* we only know about HDMI vendor infoframes */
878 	if (frame->any.oui != HDMI_IEEE_OUI)
879 		return -EINVAL;
880 
881 	return hdmi_vendor_infoframe_pack_only(&frame->hdmi, buffer, size);
882 }
883 
884 /*
885  * hdmi_vendor_any_infoframe_pack() - check a vendor infoframe,
886  *                                    and write it to binary buffer
887  */
888 static ssize_t
hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe * frame,void * buffer,size_t size)889 hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame,
890 			       void *buffer, size_t size)
891 {
892 	int ret;
893 
894 	ret = hdmi_vendor_any_infoframe_check(frame);
895 	if (ret)
896 		return ret;
897 
898 	return hdmi_vendor_any_infoframe_pack_only(frame, buffer, size);
899 }
900 
901 /**
902  * hdmi_infoframe_check() - check a HDMI infoframe
903  * @frame: HDMI infoframe
904  *
905  * Validates that the infoframe is consistent and updates derived fields
906  * (eg. length) based on other fields.
907  *
908  * Returns 0 on success or a negative error code on failure.
909  */
910 int
hdmi_infoframe_check(union hdmi_infoframe * frame)911 hdmi_infoframe_check(union hdmi_infoframe *frame)
912 {
913 	switch (frame->any.type) {
914 	case HDMI_INFOFRAME_TYPE_AVI:
915 		return hdmi_avi_infoframe_check(&frame->avi);
916 	case HDMI_INFOFRAME_TYPE_SPD:
917 		return hdmi_spd_infoframe_check(&frame->spd);
918 	case HDMI_INFOFRAME_TYPE_AUDIO:
919 		return hdmi_audio_infoframe_check(&frame->audio);
920 	case HDMI_INFOFRAME_TYPE_VENDOR:
921 		return hdmi_vendor_any_infoframe_check(&frame->vendor);
922 	default:
923 		WARN(1, "Bad infoframe type %d\n", frame->any.type);
924 		return -EINVAL;
925 	}
926 }
927 EXPORT_SYMBOL(hdmi_infoframe_check);
928 
929 /**
930  * hdmi_infoframe_pack_only() - write a HDMI infoframe to binary buffer
931  * @frame: HDMI infoframe
932  * @buffer: destination buffer
933  * @size: size of buffer
934  *
935  * Packs the information contained in the @frame structure into a binary
936  * representation that can be written into the corresponding controller
937  * registers. Also computes the checksum as required by section 5.3.5 of
938  * the HDMI 1.4 specification.
939  *
940  * Returns the number of bytes packed into the binary buffer or a negative
941  * error code on failure.
942  */
943 ssize_t
hdmi_infoframe_pack_only(const union hdmi_infoframe * frame,void * buffer,size_t size)944 hdmi_infoframe_pack_only(const union hdmi_infoframe *frame, void *buffer, size_t size)
945 {
946 	ssize_t length;
947 
948 	switch (frame->any.type) {
949 	case HDMI_INFOFRAME_TYPE_AVI:
950 		length = hdmi_avi_infoframe_pack_only(&frame->avi,
951 						      buffer, size);
952 		break;
953 	case HDMI_INFOFRAME_TYPE_DRM:
954 		length = hdmi_drm_infoframe_pack_only(&frame->drm,
955 						      buffer, size);
956 		break;
957 	case HDMI_INFOFRAME_TYPE_SPD:
958 		length = hdmi_spd_infoframe_pack_only(&frame->spd,
959 						      buffer, size);
960 		break;
961 	case HDMI_INFOFRAME_TYPE_AUDIO:
962 		length = hdmi_audio_infoframe_pack_only(&frame->audio,
963 							buffer, size);
964 		break;
965 	case HDMI_INFOFRAME_TYPE_VENDOR:
966 		length = hdmi_vendor_any_infoframe_pack_only(&frame->vendor,
967 							     buffer, size);
968 		break;
969 	default:
970 		WARN(1, "Bad infoframe type %d\n", frame->any.type);
971 		length = -EINVAL;
972 	}
973 
974 	return length;
975 }
976 EXPORT_SYMBOL(hdmi_infoframe_pack_only);
977 
978 /**
979  * hdmi_infoframe_pack() - check a HDMI infoframe,
980  *                         and write it to binary buffer
981  * @frame: HDMI infoframe
982  * @buffer: destination buffer
983  * @size: size of buffer
984  *
985  * Validates that the infoframe is consistent and updates derived fields
986  * (eg. length) based on other fields, after which it packs the information
987  * contained in the @frame structure into a binary representation that
988  * can be written into the corresponding controller registers. This function
989  * also computes the checksum as required by section 5.3.5 of the HDMI 1.4
990  * specification.
991  *
992  * Returns the number of bytes packed into the binary buffer or a negative
993  * error code on failure.
994  */
995 ssize_t
hdmi_infoframe_pack(union hdmi_infoframe * frame,void * buffer,size_t size)996 hdmi_infoframe_pack(union hdmi_infoframe *frame,
997 		    void *buffer, size_t size)
998 {
999 	ssize_t length;
1000 
1001 	switch (frame->any.type) {
1002 	case HDMI_INFOFRAME_TYPE_AVI:
1003 		length = hdmi_avi_infoframe_pack(&frame->avi, buffer, size);
1004 		break;
1005 	case HDMI_INFOFRAME_TYPE_DRM:
1006 		length = hdmi_drm_infoframe_pack(&frame->drm, buffer, size);
1007 		break;
1008 	case HDMI_INFOFRAME_TYPE_SPD:
1009 		length = hdmi_spd_infoframe_pack(&frame->spd, buffer, size);
1010 		break;
1011 	case HDMI_INFOFRAME_TYPE_AUDIO:
1012 		length = hdmi_audio_infoframe_pack(&frame->audio, buffer, size);
1013 		break;
1014 	case HDMI_INFOFRAME_TYPE_VENDOR:
1015 		length = hdmi_vendor_any_infoframe_pack(&frame->vendor,
1016 							buffer, size);
1017 		break;
1018 	default:
1019 		WARN(1, "Bad infoframe type %d\n", frame->any.type);
1020 		length = -EINVAL;
1021 	}
1022 
1023 	return length;
1024 }
1025 EXPORT_SYMBOL(hdmi_infoframe_pack);
1026 
hdmi_infoframe_type_get_name(enum hdmi_infoframe_type type)1027 static const char *hdmi_infoframe_type_get_name(enum hdmi_infoframe_type type)
1028 {
1029 	if (type < 0x80 || type > 0x9f)
1030 		return "Invalid";
1031 	switch (type) {
1032 	case HDMI_INFOFRAME_TYPE_VENDOR:
1033 		return "Vendor";
1034 	case HDMI_INFOFRAME_TYPE_AVI:
1035 		return "Auxiliary Video Information (AVI)";
1036 	case HDMI_INFOFRAME_TYPE_SPD:
1037 		return "Source Product Description (SPD)";
1038 	case HDMI_INFOFRAME_TYPE_AUDIO:
1039 		return "Audio";
1040 	case HDMI_INFOFRAME_TYPE_DRM:
1041 		return "Dynamic Range and Mastering";
1042 	}
1043 	return "Reserved";
1044 }
1045 
hdmi_infoframe_log_header(const char * level,struct device * dev,const struct hdmi_any_infoframe * frame)1046 static void hdmi_infoframe_log_header(const char *level,
1047 				      struct device *dev,
1048 				      const struct hdmi_any_infoframe *frame)
1049 {
1050 	hdmi_log("HDMI infoframe: %s, version %u, length %u\n",
1051 		hdmi_infoframe_type_get_name(frame->type),
1052 		frame->version, frame->length);
1053 }
1054 
hdmi_colorspace_get_name(enum hdmi_colorspace colorspace)1055 static const char *hdmi_colorspace_get_name(enum hdmi_colorspace colorspace)
1056 {
1057 	switch (colorspace) {
1058 	case HDMI_COLORSPACE_RGB:
1059 		return "RGB";
1060 	case HDMI_COLORSPACE_YUV422:
1061 		return "YCbCr 4:2:2";
1062 	case HDMI_COLORSPACE_YUV444:
1063 		return "YCbCr 4:4:4";
1064 	case HDMI_COLORSPACE_YUV420:
1065 		return "YCbCr 4:2:0";
1066 	case HDMI_COLORSPACE_RESERVED4:
1067 		return "Reserved (4)";
1068 	case HDMI_COLORSPACE_RESERVED5:
1069 		return "Reserved (5)";
1070 	case HDMI_COLORSPACE_RESERVED6:
1071 		return "Reserved (6)";
1072 	case HDMI_COLORSPACE_IDO_DEFINED:
1073 		return "IDO Defined";
1074 	}
1075 	return "Invalid";
1076 }
1077 
hdmi_scan_mode_get_name(enum hdmi_scan_mode scan_mode)1078 static const char *hdmi_scan_mode_get_name(enum hdmi_scan_mode scan_mode)
1079 {
1080 	switch (scan_mode) {
1081 	case HDMI_SCAN_MODE_NONE:
1082 		return "No Data";
1083 	case HDMI_SCAN_MODE_OVERSCAN:
1084 		return "Overscan";
1085 	case HDMI_SCAN_MODE_UNDERSCAN:
1086 		return "Underscan";
1087 	case HDMI_SCAN_MODE_RESERVED:
1088 		return "Reserved";
1089 	}
1090 	return "Invalid";
1091 }
1092 
hdmi_colorimetry_get_name(enum hdmi_colorimetry colorimetry)1093 static const char *hdmi_colorimetry_get_name(enum hdmi_colorimetry colorimetry)
1094 {
1095 	switch (colorimetry) {
1096 	case HDMI_COLORIMETRY_NONE:
1097 		return "No Data";
1098 	case HDMI_COLORIMETRY_ITU_601:
1099 		return "ITU601";
1100 	case HDMI_COLORIMETRY_ITU_709:
1101 		return "ITU709";
1102 	case HDMI_COLORIMETRY_EXTENDED:
1103 		return "Extended";
1104 	}
1105 	return "Invalid";
1106 }
1107 
1108 static const char *
hdmi_picture_aspect_get_name(enum hdmi_picture_aspect picture_aspect)1109 hdmi_picture_aspect_get_name(enum hdmi_picture_aspect picture_aspect)
1110 {
1111 	switch (picture_aspect) {
1112 	case HDMI_PICTURE_ASPECT_NONE:
1113 		return "No Data";
1114 	case HDMI_PICTURE_ASPECT_4_3:
1115 		return "4:3";
1116 	case HDMI_PICTURE_ASPECT_16_9:
1117 		return "16:9";
1118 	case HDMI_PICTURE_ASPECT_64_27:
1119 		return "64:27";
1120 	case HDMI_PICTURE_ASPECT_256_135:
1121 		return "256:135";
1122 	case HDMI_PICTURE_ASPECT_RESERVED:
1123 		return "Reserved";
1124 	}
1125 	return "Invalid";
1126 }
1127 
1128 static const char *
hdmi_active_aspect_get_name(enum hdmi_active_aspect active_aspect)1129 hdmi_active_aspect_get_name(enum hdmi_active_aspect active_aspect)
1130 {
1131 	if (active_aspect < 0 || active_aspect > 0xf)
1132 		return "Invalid";
1133 
1134 	switch (active_aspect) {
1135 	case HDMI_ACTIVE_ASPECT_16_9_TOP:
1136 		return "16:9 Top";
1137 	case HDMI_ACTIVE_ASPECT_14_9_TOP:
1138 		return "14:9 Top";
1139 	case HDMI_ACTIVE_ASPECT_16_9_CENTER:
1140 		return "16:9 Center";
1141 	case HDMI_ACTIVE_ASPECT_PICTURE:
1142 		return "Same as Picture";
1143 	case HDMI_ACTIVE_ASPECT_4_3:
1144 		return "4:3";
1145 	case HDMI_ACTIVE_ASPECT_16_9:
1146 		return "16:9";
1147 	case HDMI_ACTIVE_ASPECT_14_9:
1148 		return "14:9";
1149 	case HDMI_ACTIVE_ASPECT_4_3_SP_14_9:
1150 		return "4:3 SP 14:9";
1151 	case HDMI_ACTIVE_ASPECT_16_9_SP_14_9:
1152 		return "16:9 SP 14:9";
1153 	case HDMI_ACTIVE_ASPECT_16_9_SP_4_3:
1154 		return "16:9 SP 4:3";
1155 	}
1156 	return "Reserved";
1157 }
1158 
1159 static const char *
hdmi_extended_colorimetry_get_name(enum hdmi_extended_colorimetry ext_col)1160 hdmi_extended_colorimetry_get_name(enum hdmi_extended_colorimetry ext_col)
1161 {
1162 	switch (ext_col) {
1163 	case HDMI_EXTENDED_COLORIMETRY_XV_YCC_601:
1164 		return "xvYCC 601";
1165 	case HDMI_EXTENDED_COLORIMETRY_XV_YCC_709:
1166 		return "xvYCC 709";
1167 	case HDMI_EXTENDED_COLORIMETRY_S_YCC_601:
1168 		return "sYCC 601";
1169 	case HDMI_EXTENDED_COLORIMETRY_OPYCC_601:
1170 		return "opYCC 601";
1171 	case HDMI_EXTENDED_COLORIMETRY_OPRGB:
1172 		return "opRGB";
1173 	case HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM:
1174 		return "BT.2020 Constant Luminance";
1175 	case HDMI_EXTENDED_COLORIMETRY_BT2020:
1176 		return "BT.2020";
1177 	case HDMI_EXTENDED_COLORIMETRY_RESERVED:
1178 		return "Reserved";
1179 	}
1180 	return "Invalid";
1181 }
1182 
1183 static const char *
hdmi_quantization_range_get_name(enum hdmi_quantization_range qrange)1184 hdmi_quantization_range_get_name(enum hdmi_quantization_range qrange)
1185 {
1186 	switch (qrange) {
1187 	case HDMI_QUANTIZATION_RANGE_DEFAULT:
1188 		return "Default";
1189 	case HDMI_QUANTIZATION_RANGE_LIMITED:
1190 		return "Limited";
1191 	case HDMI_QUANTIZATION_RANGE_FULL:
1192 		return "Full";
1193 	case HDMI_QUANTIZATION_RANGE_RESERVED:
1194 		return "Reserved";
1195 	}
1196 	return "Invalid";
1197 }
1198 
hdmi_nups_get_name(enum hdmi_nups nups)1199 static const char *hdmi_nups_get_name(enum hdmi_nups nups)
1200 {
1201 	switch (nups) {
1202 	case HDMI_NUPS_UNKNOWN:
1203 		return "Unknown Non-uniform Scaling";
1204 	case HDMI_NUPS_HORIZONTAL:
1205 		return "Horizontally Scaled";
1206 	case HDMI_NUPS_VERTICAL:
1207 		return "Vertically Scaled";
1208 	case HDMI_NUPS_BOTH:
1209 		return "Horizontally and Vertically Scaled";
1210 	}
1211 	return "Invalid";
1212 }
1213 
1214 static const char *
hdmi_ycc_quantization_range_get_name(enum hdmi_ycc_quantization_range qrange)1215 hdmi_ycc_quantization_range_get_name(enum hdmi_ycc_quantization_range qrange)
1216 {
1217 	switch (qrange) {
1218 	case HDMI_YCC_QUANTIZATION_RANGE_LIMITED:
1219 		return "Limited";
1220 	case HDMI_YCC_QUANTIZATION_RANGE_FULL:
1221 		return "Full";
1222 	}
1223 	return "Invalid";
1224 }
1225 
1226 static const char *
hdmi_content_type_get_name(enum hdmi_content_type content_type)1227 hdmi_content_type_get_name(enum hdmi_content_type content_type)
1228 {
1229 	switch (content_type) {
1230 	case HDMI_CONTENT_TYPE_GRAPHICS:
1231 		return "Graphics";
1232 	case HDMI_CONTENT_TYPE_PHOTO:
1233 		return "Photo";
1234 	case HDMI_CONTENT_TYPE_CINEMA:
1235 		return "Cinema";
1236 	case HDMI_CONTENT_TYPE_GAME:
1237 		return "Game";
1238 	}
1239 	return "Invalid";
1240 }
1241 
hdmi_avi_infoframe_log(const char * level,struct device * dev,const struct hdmi_avi_infoframe * frame)1242 static void hdmi_avi_infoframe_log(const char *level,
1243 				   struct device *dev,
1244 				   const struct hdmi_avi_infoframe *frame)
1245 {
1246 	hdmi_infoframe_log_header(level, dev,
1247 				  (const struct hdmi_any_infoframe *)frame);
1248 
1249 	hdmi_log("    colorspace: %s\n",
1250 			hdmi_colorspace_get_name(frame->colorspace));
1251 	hdmi_log("    scan mode: %s\n",
1252 			hdmi_scan_mode_get_name(frame->scan_mode));
1253 	hdmi_log("    colorimetry: %s\n",
1254 			hdmi_colorimetry_get_name(frame->colorimetry));
1255 	hdmi_log("    picture aspect: %s\n",
1256 			hdmi_picture_aspect_get_name(frame->picture_aspect));
1257 	hdmi_log("    active aspect: %s\n",
1258 			hdmi_active_aspect_get_name(frame->active_aspect));
1259 	hdmi_log("    itc: %s\n", frame->itc ? "IT Content" : "No Data");
1260 	hdmi_log("    extended colorimetry: %s\n",
1261 			hdmi_extended_colorimetry_get_name(frame->extended_colorimetry));
1262 	hdmi_log("    quantization range: %s\n",
1263 			hdmi_quantization_range_get_name(frame->quantization_range));
1264 	hdmi_log("    nups: %s\n", hdmi_nups_get_name(frame->nups));
1265 	hdmi_log("    video code: %u\n", frame->video_code);
1266 	hdmi_log("    ycc quantization range: %s\n",
1267 			hdmi_ycc_quantization_range_get_name(frame->ycc_quantization_range));
1268 	hdmi_log("    hdmi content type: %s\n",
1269 			hdmi_content_type_get_name(frame->content_type));
1270 	hdmi_log("    pixel repeat: %u\n", frame->pixel_repeat);
1271 	hdmi_log("    bar top %u, bottom %u, left %u, right %u\n",
1272 			frame->top_bar, frame->bottom_bar,
1273 			frame->left_bar, frame->right_bar);
1274 }
1275 
hdmi_spd_sdi_get_name(enum hdmi_spd_sdi sdi)1276 static const char *hdmi_spd_sdi_get_name(enum hdmi_spd_sdi sdi)
1277 {
1278 	if (sdi < 0 || sdi > 0xff)
1279 		return "Invalid";
1280 	switch (sdi) {
1281 	case HDMI_SPD_SDI_UNKNOWN:
1282 		return "Unknown";
1283 	case HDMI_SPD_SDI_DSTB:
1284 		return "Digital STB";
1285 	case HDMI_SPD_SDI_DVDP:
1286 		return "DVD Player";
1287 	case HDMI_SPD_SDI_DVHS:
1288 		return "D-VHS";
1289 	case HDMI_SPD_SDI_HDDVR:
1290 		return "HDD Videorecorder";
1291 	case HDMI_SPD_SDI_DVC:
1292 		return "DVC";
1293 	case HDMI_SPD_SDI_DSC:
1294 		return "DSC";
1295 	case HDMI_SPD_SDI_VCD:
1296 		return "Video CD";
1297 	case HDMI_SPD_SDI_GAME:
1298 		return "Game";
1299 	case HDMI_SPD_SDI_PC:
1300 		return "PC General";
1301 	case HDMI_SPD_SDI_BD:
1302 		return "Blu-Ray Disc (BD)";
1303 	case HDMI_SPD_SDI_SACD:
1304 		return "Super Audio CD";
1305 	case HDMI_SPD_SDI_HDDVD:
1306 		return "HD DVD";
1307 	case HDMI_SPD_SDI_PMP:
1308 		return "PMP";
1309 	}
1310 	return "Reserved";
1311 }
1312 
hdmi_spd_infoframe_log(const char * level,struct device * dev,const struct hdmi_spd_infoframe * frame)1313 static void hdmi_spd_infoframe_log(const char *level,
1314 				   struct device *dev,
1315 				   const struct hdmi_spd_infoframe *frame)
1316 {
1317 	u8 buf[17];
1318 
1319 	hdmi_infoframe_log_header(level, dev,
1320 				  (const struct hdmi_any_infoframe *)frame);
1321 
1322 	memset(buf, 0, sizeof(buf));
1323 
1324 	strncpy(buf, frame->vendor, 8);
1325 	hdmi_log("    vendor: %s\n", buf);
1326 	strncpy(buf, frame->product, 16);
1327 	hdmi_log("    product: %s\n", buf);
1328 	hdmi_log("    source device information: %s (0x%x)\n",
1329 		hdmi_spd_sdi_get_name(frame->sdi), frame->sdi);
1330 }
1331 
1332 static const char *
hdmi_audio_coding_type_get_name(enum hdmi_audio_coding_type coding_type)1333 hdmi_audio_coding_type_get_name(enum hdmi_audio_coding_type coding_type)
1334 {
1335 	switch (coding_type) {
1336 	case HDMI_AUDIO_CODING_TYPE_STREAM:
1337 		return "Refer to Stream Header";
1338 	case HDMI_AUDIO_CODING_TYPE_PCM:
1339 		return "PCM";
1340 	case HDMI_AUDIO_CODING_TYPE_AC3:
1341 		return "AC-3";
1342 	case HDMI_AUDIO_CODING_TYPE_MPEG1:
1343 		return "MPEG1";
1344 	case HDMI_AUDIO_CODING_TYPE_MP3:
1345 		return "MP3";
1346 	case HDMI_AUDIO_CODING_TYPE_MPEG2:
1347 		return "MPEG2";
1348 	case HDMI_AUDIO_CODING_TYPE_AAC_LC:
1349 		return "AAC";
1350 	case HDMI_AUDIO_CODING_TYPE_DTS:
1351 		return "DTS";
1352 	case HDMI_AUDIO_CODING_TYPE_ATRAC:
1353 		return "ATRAC";
1354 	case HDMI_AUDIO_CODING_TYPE_DSD:
1355 		return "One Bit Audio";
1356 	case HDMI_AUDIO_CODING_TYPE_EAC3:
1357 		return "Dolby Digital +";
1358 	case HDMI_AUDIO_CODING_TYPE_DTS_HD:
1359 		return "DTS-HD";
1360 	case HDMI_AUDIO_CODING_TYPE_MLP:
1361 		return "MAT (MLP)";
1362 	case HDMI_AUDIO_CODING_TYPE_DST:
1363 		return "DST";
1364 	case HDMI_AUDIO_CODING_TYPE_WMA_PRO:
1365 		return "WMA PRO";
1366 	case HDMI_AUDIO_CODING_TYPE_CXT:
1367 		return "Refer to CXT";
1368 	}
1369 	return "Invalid";
1370 }
1371 
1372 static const char *
hdmi_audio_sample_size_get_name(enum hdmi_audio_sample_size sample_size)1373 hdmi_audio_sample_size_get_name(enum hdmi_audio_sample_size sample_size)
1374 {
1375 	switch (sample_size) {
1376 	case HDMI_AUDIO_SAMPLE_SIZE_STREAM:
1377 		return "Refer to Stream Header";
1378 	case HDMI_AUDIO_SAMPLE_SIZE_16:
1379 		return "16 bit";
1380 	case HDMI_AUDIO_SAMPLE_SIZE_20:
1381 		return "20 bit";
1382 	case HDMI_AUDIO_SAMPLE_SIZE_24:
1383 		return "24 bit";
1384 	}
1385 	return "Invalid";
1386 }
1387 
1388 static const char *
hdmi_audio_sample_frequency_get_name(enum hdmi_audio_sample_frequency freq)1389 hdmi_audio_sample_frequency_get_name(enum hdmi_audio_sample_frequency freq)
1390 {
1391 	switch (freq) {
1392 	case HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM:
1393 		return "Refer to Stream Header";
1394 	case HDMI_AUDIO_SAMPLE_FREQUENCY_32000:
1395 		return "32 kHz";
1396 	case HDMI_AUDIO_SAMPLE_FREQUENCY_44100:
1397 		return "44.1 kHz (CD)";
1398 	case HDMI_AUDIO_SAMPLE_FREQUENCY_48000:
1399 		return "48 kHz";
1400 	case HDMI_AUDIO_SAMPLE_FREQUENCY_88200:
1401 		return "88.2 kHz";
1402 	case HDMI_AUDIO_SAMPLE_FREQUENCY_96000:
1403 		return "96 kHz";
1404 	case HDMI_AUDIO_SAMPLE_FREQUENCY_176400:
1405 		return "176.4 kHz";
1406 	case HDMI_AUDIO_SAMPLE_FREQUENCY_192000:
1407 		return "192 kHz";
1408 	}
1409 	return "Invalid";
1410 }
1411 
1412 static const char *
hdmi_audio_coding_type_ext_get_name(enum hdmi_audio_coding_type_ext ctx)1413 hdmi_audio_coding_type_ext_get_name(enum hdmi_audio_coding_type_ext ctx)
1414 {
1415 	if (ctx < 0 || ctx > 0x1f)
1416 		return "Invalid";
1417 
1418 	switch (ctx) {
1419 	case HDMI_AUDIO_CODING_TYPE_EXT_CT:
1420 		return "Refer to CT";
1421 	case HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC:
1422 		return "HE AAC";
1423 	case HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC_V2:
1424 		return "HE AAC v2";
1425 	case HDMI_AUDIO_CODING_TYPE_EXT_MPEG_SURROUND:
1426 		return "MPEG SURROUND";
1427 	case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC:
1428 		return "MPEG-4 HE AAC";
1429 	case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC_V2:
1430 		return "MPEG-4 HE AAC v2";
1431 	case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_AAC_LC:
1432 		return "MPEG-4 AAC LC";
1433 	case HDMI_AUDIO_CODING_TYPE_EXT_DRA:
1434 		return "DRA";
1435 	case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC_SURROUND:
1436 		return "MPEG-4 HE AAC + MPEG Surround";
1437 	case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_AAC_LC_SURROUND:
1438 		return "MPEG-4 AAC LC + MPEG Surround";
1439 	}
1440 	return "Reserved";
1441 }
1442 
hdmi_audio_infoframe_log(const char * level,struct device * dev,const struct hdmi_audio_infoframe * frame)1443 static void hdmi_audio_infoframe_log(const char *level,
1444 				     struct device *dev,
1445 				     const struct hdmi_audio_infoframe *frame)
1446 {
1447 	hdmi_infoframe_log_header(level, dev,
1448 				  (const struct hdmi_any_infoframe *)frame);
1449 
1450 	if (frame->channels)
1451 		hdmi_log("    channels: %u\n", frame->channels - 1);
1452 	else
1453 		hdmi_log("    channels: Refer to stream header\n");
1454 	hdmi_log("    coding type: %s\n",
1455 			hdmi_audio_coding_type_get_name(frame->coding_type));
1456 	hdmi_log("    sample size: %s\n",
1457 			hdmi_audio_sample_size_get_name(frame->sample_size));
1458 	hdmi_log("    sample frequency: %s\n",
1459 			hdmi_audio_sample_frequency_get_name(frame->sample_frequency));
1460 	hdmi_log("    coding type ext: %s\n",
1461 			hdmi_audio_coding_type_ext_get_name(frame->coding_type_ext));
1462 	hdmi_log("    channel allocation: 0x%x\n",
1463 			frame->channel_allocation);
1464 	hdmi_log("    level shift value: %u dB\n",
1465 			frame->level_shift_value);
1466 	hdmi_log("    downmix inhibit: %s\n",
1467 			frame->downmix_inhibit ? "Yes" : "No");
1468 }
1469 
hdmi_drm_infoframe_log(const char * level,struct device * dev,const struct hdmi_drm_infoframe * frame)1470 static void hdmi_drm_infoframe_log(const char *level,
1471 				   struct device *dev,
1472 				   const struct hdmi_drm_infoframe *frame)
1473 {
1474 	int i;
1475 
1476 	hdmi_infoframe_log_header(level, dev,
1477 				  (struct hdmi_any_infoframe *)frame);
1478 	hdmi_log("length: %d\n", frame->length);
1479 	hdmi_log("metadata type: %d\n", frame->metadata_type);
1480 	hdmi_log("eotf: %d\n", frame->eotf);
1481 	for (i = 0; i < 3; i++) {
1482 		hdmi_log("x[%d]: %d\n", i, frame->display_primaries[i].x);
1483 		hdmi_log("y[%d]: %d\n", i, frame->display_primaries[i].y);
1484 	}
1485 
1486 	hdmi_log("white point x: %d\n", frame->white_point.x);
1487 	hdmi_log("white point y: %d\n", frame->white_point.y);
1488 
1489 	hdmi_log("max_display_mastering_luminance: %d\n",
1490 		 frame->max_display_mastering_luminance);
1491 	hdmi_log("min_display_mastering_luminance: %d\n",
1492 		 frame->min_display_mastering_luminance);
1493 
1494 	hdmi_log("max_cll: %d\n", frame->max_cll);
1495 	hdmi_log("max_fall: %d\n", frame->max_fall);
1496 }
1497 
1498 static const char *
hdmi_3d_structure_get_name(enum hdmi_3d_structure s3d_struct)1499 hdmi_3d_structure_get_name(enum hdmi_3d_structure s3d_struct)
1500 {
1501 	if (s3d_struct < 0 || s3d_struct > 0xf)
1502 		return "Invalid";
1503 
1504 	switch (s3d_struct) {
1505 	case HDMI_3D_STRUCTURE_FRAME_PACKING:
1506 		return "Frame Packing";
1507 	case HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE:
1508 		return "Field Alternative";
1509 	case HDMI_3D_STRUCTURE_LINE_ALTERNATIVE:
1510 		return "Line Alternative";
1511 	case HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL:
1512 		return "Side-by-side (Full)";
1513 	case HDMI_3D_STRUCTURE_L_DEPTH:
1514 		return "L + Depth";
1515 	case HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH:
1516 		return "L + Depth + Graphics + Graphics-depth";
1517 	case HDMI_3D_STRUCTURE_TOP_AND_BOTTOM:
1518 		return "Top-and-Bottom";
1519 	case HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF:
1520 		return "Side-by-side (Half)";
1521 	default:
1522 		break;
1523 	}
1524 	return "Reserved";
1525 }
1526 
1527 static void
hdmi_vendor_any_infoframe_log(const char * level,struct device * dev,const union hdmi_vendor_any_infoframe * frame)1528 hdmi_vendor_any_infoframe_log(const char *level,
1529 			      struct device *dev,
1530 			      const union hdmi_vendor_any_infoframe *frame)
1531 {
1532 	const struct hdmi_vendor_infoframe *hvf = &frame->hdmi;
1533 
1534 	hdmi_infoframe_log_header(level, dev,
1535 				  (const struct hdmi_any_infoframe *)frame);
1536 
1537 	if (frame->any.oui != HDMI_IEEE_OUI) {
1538 		hdmi_log("    not a HDMI vendor infoframe\n");
1539 		return;
1540 	}
1541 	if (hvf->vic == 0 && hvf->s3d_struct == HDMI_3D_STRUCTURE_INVALID) {
1542 		hdmi_log("    empty frame\n");
1543 		return;
1544 	}
1545 
1546 	if (hvf->vic)
1547 		hdmi_log("    HDMI VIC: %u\n", hvf->vic);
1548 	if (hvf->s3d_struct != HDMI_3D_STRUCTURE_INVALID) {
1549 		hdmi_log("    3D structure: %s\n",
1550 				hdmi_3d_structure_get_name(hvf->s3d_struct));
1551 		if (hvf->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF)
1552 			hdmi_log("    3D extension data: %d\n",
1553 					hvf->s3d_ext_data);
1554 	}
1555 }
1556 
1557 /**
1558  * hdmi_infoframe_log() - log info of HDMI infoframe
1559  * @level: logging level
1560  * @dev: device
1561  * @frame: HDMI infoframe
1562  */
hdmi_infoframe_log(const char * level,struct device * dev,const union hdmi_infoframe * frame)1563 void hdmi_infoframe_log(const char *level,
1564 			struct device *dev,
1565 			const union hdmi_infoframe *frame)
1566 {
1567 	switch (frame->any.type) {
1568 	case HDMI_INFOFRAME_TYPE_AVI:
1569 		hdmi_avi_infoframe_log(level, dev, &frame->avi);
1570 		break;
1571 	case HDMI_INFOFRAME_TYPE_SPD:
1572 		hdmi_spd_infoframe_log(level, dev, &frame->spd);
1573 		break;
1574 	case HDMI_INFOFRAME_TYPE_AUDIO:
1575 		hdmi_audio_infoframe_log(level, dev, &frame->audio);
1576 		break;
1577 	case HDMI_INFOFRAME_TYPE_VENDOR:
1578 		hdmi_vendor_any_infoframe_log(level, dev, &frame->vendor);
1579 		break;
1580 	case HDMI_INFOFRAME_TYPE_DRM:
1581 		hdmi_drm_infoframe_log(level, dev, &frame->drm);
1582 		break;
1583 	}
1584 }
1585 EXPORT_SYMBOL(hdmi_infoframe_log);
1586 
1587 /**
1588  * hdmi_avi_infoframe_unpack() - unpack binary buffer to a HDMI AVI infoframe
1589  * @frame: HDMI AVI infoframe
1590  * @buffer: source buffer
1591  * @size: size of buffer
1592  *
1593  * Unpacks the information contained in binary @buffer into a structured
1594  * @frame of the HDMI Auxiliary Video (AVI) information frame.
1595  * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
1596  * specification.
1597  *
1598  * Returns 0 on success or a negative error code on failure.
1599  */
hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe * frame,const void * buffer,size_t size)1600 static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame,
1601 				     const void *buffer, size_t size)
1602 {
1603 	const u8 *ptr = buffer;
1604 
1605 	if (size < HDMI_INFOFRAME_SIZE(AVI))
1606 		return -EINVAL;
1607 
1608 	if (ptr[0] != HDMI_INFOFRAME_TYPE_AVI ||
1609 	    ptr[1] != 2 ||
1610 	    ptr[2] != HDMI_AVI_INFOFRAME_SIZE)
1611 		return -EINVAL;
1612 
1613 	if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AVI)) != 0)
1614 		return -EINVAL;
1615 
1616 	hdmi_avi_infoframe_init(frame);
1617 
1618 	ptr += HDMI_INFOFRAME_HEADER_SIZE;
1619 
1620 	frame->colorspace = (ptr[0] >> 5) & 0x3;
1621 	if (ptr[0] & 0x10)
1622 		frame->active_aspect = ptr[1] & 0xf;
1623 	if (ptr[0] & 0x8) {
1624 		frame->top_bar = (ptr[6] << 8) | ptr[5];
1625 		frame->bottom_bar = (ptr[8] << 8) | ptr[7];
1626 	}
1627 	if (ptr[0] & 0x4) {
1628 		frame->left_bar = (ptr[10] << 8) | ptr[9];
1629 		frame->right_bar = (ptr[12] << 8) | ptr[11];
1630 	}
1631 	frame->scan_mode = ptr[0] & 0x3;
1632 
1633 	frame->colorimetry = (ptr[1] >> 6) & 0x3;
1634 	frame->picture_aspect = (ptr[1] >> 4) & 0x3;
1635 	frame->active_aspect = ptr[1] & 0xf;
1636 
1637 	frame->itc = ptr[2] & 0x80 ? true : false;
1638 	frame->extended_colorimetry = (ptr[2] >> 4) & 0x7;
1639 	frame->quantization_range = (ptr[2] >> 2) & 0x3;
1640 	frame->nups = ptr[2] & 0x3;
1641 
1642 	frame->video_code = ptr[3] & 0x7f;
1643 	frame->ycc_quantization_range = (ptr[4] >> 6) & 0x3;
1644 	frame->content_type = (ptr[4] >> 4) & 0x3;
1645 
1646 	frame->pixel_repeat = ptr[4] & 0xf;
1647 
1648 	return 0;
1649 }
1650 
1651 /**
1652  * hdmi_spd_infoframe_unpack() - unpack binary buffer to a HDMI SPD infoframe
1653  * @frame: HDMI SPD infoframe
1654  * @buffer: source buffer
1655  * @size: size of buffer
1656  *
1657  * Unpacks the information contained in binary @buffer into a structured
1658  * @frame of the HDMI Source Product Description (SPD) information frame.
1659  * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
1660  * specification.
1661  *
1662  * Returns 0 on success or a negative error code on failure.
1663  */
hdmi_spd_infoframe_unpack(struct hdmi_spd_infoframe * frame,const void * buffer,size_t size)1664 static int hdmi_spd_infoframe_unpack(struct hdmi_spd_infoframe *frame,
1665 				     const void *buffer, size_t size)
1666 {
1667 	const u8 *ptr = buffer;
1668 	int ret;
1669 
1670 	if (size < HDMI_INFOFRAME_SIZE(SPD))
1671 		return -EINVAL;
1672 
1673 	if (ptr[0] != HDMI_INFOFRAME_TYPE_SPD ||
1674 	    ptr[1] != 1 ||
1675 	    ptr[2] != HDMI_SPD_INFOFRAME_SIZE) {
1676 		return -EINVAL;
1677 	}
1678 
1679 	if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(SPD)) != 0)
1680 		return -EINVAL;
1681 
1682 	ptr += HDMI_INFOFRAME_HEADER_SIZE;
1683 
1684 	ret = hdmi_spd_infoframe_init(frame, ptr, ptr + 8);
1685 	if (ret)
1686 		return ret;
1687 
1688 	frame->sdi = ptr[24];
1689 
1690 	return 0;
1691 }
1692 
1693 /**
1694  * hdmi_audio_infoframe_unpack() - unpack binary buffer to a HDMI AUDIO infoframe
1695  * @frame: HDMI Audio infoframe
1696  * @buffer: source buffer
1697  * @size: size of buffer
1698  *
1699  * Unpacks the information contained in binary @buffer into a structured
1700  * @frame of the HDMI Audio information frame.
1701  * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
1702  * specification.
1703  *
1704  * Returns 0 on success or a negative error code on failure.
1705  */
hdmi_audio_infoframe_unpack(struct hdmi_audio_infoframe * frame,const void * buffer,size_t size)1706 static int hdmi_audio_infoframe_unpack(struct hdmi_audio_infoframe *frame,
1707 				       const void *buffer, size_t size)
1708 {
1709 	const u8 *ptr = buffer;
1710 	int ret;
1711 
1712 	if (size < HDMI_INFOFRAME_SIZE(AUDIO))
1713 		return -EINVAL;
1714 
1715 	if (ptr[0] != HDMI_INFOFRAME_TYPE_AUDIO ||
1716 	    ptr[1] != 1 ||
1717 	    ptr[2] != HDMI_AUDIO_INFOFRAME_SIZE) {
1718 		return -EINVAL;
1719 	}
1720 
1721 	if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AUDIO)) != 0)
1722 		return -EINVAL;
1723 
1724 	ret = hdmi_audio_infoframe_init(frame);
1725 	if (ret)
1726 		return ret;
1727 
1728 	ptr += HDMI_INFOFRAME_HEADER_SIZE;
1729 
1730 	frame->channels = ptr[0] & 0x7;
1731 	frame->coding_type = (ptr[0] >> 4) & 0xf;
1732 	frame->sample_size = ptr[1] & 0x3;
1733 	frame->sample_frequency = (ptr[1] >> 2) & 0x7;
1734 	frame->coding_type_ext = ptr[2] & 0x1f;
1735 	frame->channel_allocation = ptr[3];
1736 	frame->level_shift_value = (ptr[4] >> 3) & 0xf;
1737 	frame->downmix_inhibit = ptr[4] & 0x80 ? true : false;
1738 
1739 	return 0;
1740 }
1741 
1742 /**
1743  * hdmi_vendor_any_infoframe_unpack() - unpack binary buffer to a HDMI
1744  * 	vendor infoframe
1745  * @frame: HDMI Vendor infoframe
1746  * @buffer: source buffer
1747  * @size: size of buffer
1748  *
1749  * Unpacks the information contained in binary @buffer into a structured
1750  * @frame of the HDMI Vendor information frame.
1751  * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
1752  * specification.
1753  *
1754  * Returns 0 on success or a negative error code on failure.
1755  */
1756 static int
hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe * frame,const void * buffer,size_t size)1757 hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame,
1758 				 const void *buffer, size_t size)
1759 {
1760 	const u8 *ptr = buffer;
1761 	size_t length;
1762 	int ret;
1763 	u8 hdmi_video_format;
1764 	struct hdmi_vendor_infoframe *hvf = &frame->hdmi;
1765 
1766 	if (size < HDMI_INFOFRAME_HEADER_SIZE)
1767 		return -EINVAL;
1768 
1769 	if (ptr[0] != HDMI_INFOFRAME_TYPE_VENDOR ||
1770 	    ptr[1] != 1 ||
1771 	    (ptr[2] != 4 && ptr[2] != 5 && ptr[2] != 6))
1772 		return -EINVAL;
1773 
1774 	length = ptr[2];
1775 
1776 	if (size < HDMI_INFOFRAME_HEADER_SIZE + length)
1777 		return -EINVAL;
1778 
1779 	if (hdmi_infoframe_checksum(buffer,
1780 				    HDMI_INFOFRAME_HEADER_SIZE + length) != 0)
1781 		return -EINVAL;
1782 
1783 	ptr += HDMI_INFOFRAME_HEADER_SIZE;
1784 
1785 	/* HDMI OUI */
1786 	if ((ptr[0] != 0x03) ||
1787 	    (ptr[1] != 0x0c) ||
1788 	    (ptr[2] != 0x00))
1789 		return -EINVAL;
1790 
1791 	hdmi_video_format = ptr[3] >> 5;
1792 
1793 	if (hdmi_video_format > 0x2)
1794 		return -EINVAL;
1795 
1796 	ret = hdmi_vendor_infoframe_init(hvf);
1797 	if (ret)
1798 		return ret;
1799 
1800 	hvf->length = length;
1801 
1802 	if (hdmi_video_format == 0x2) {
1803 		if (length != 5 && length != 6)
1804 			return -EINVAL;
1805 		hvf->s3d_struct = ptr[4] >> 4;
1806 		if (hvf->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) {
1807 			if (length != 6)
1808 				return -EINVAL;
1809 			hvf->s3d_ext_data = ptr[5] >> 4;
1810 		}
1811 	} else if (hdmi_video_format == 0x1) {
1812 		if (length != 5)
1813 			return -EINVAL;
1814 		hvf->vic = ptr[4];
1815 	} else {
1816 		if (length != 4)
1817 			return -EINVAL;
1818 	}
1819 
1820 	return 0;
1821 }
1822 
1823 /**
1824  * hdmi_drm_infoframe_unpack_only() - unpack binary buffer of CTA-861-G DRM
1825  *                                    infoframe DataBytes to a HDMI DRM
1826  *                                    infoframe
1827  * @frame: HDMI DRM infoframe
1828  * @buffer: source buffer
1829  * @size: size of buffer
1830  *
1831  * Unpacks CTA-861-G DRM infoframe DataBytes contained in the binary @buffer
1832  * into a structured @frame of the HDMI Dynamic Range and Mastering (DRM)
1833  * infoframe.
1834  *
1835  * Returns 0 on success or a negative error code on failure.
1836  */
hdmi_drm_infoframe_unpack_only(struct hdmi_drm_infoframe * frame,const void * buffer,size_t size)1837 int hdmi_drm_infoframe_unpack_only(struct hdmi_drm_infoframe *frame,
1838 				   const void *buffer, size_t size)
1839 {
1840 	const u8 *ptr = buffer;
1841 	const u8 *temp;
1842 	u8 x_lsb, x_msb;
1843 	u8 y_lsb, y_msb;
1844 	int ret;
1845 	int i;
1846 
1847 	if (size < HDMI_DRM_INFOFRAME_SIZE)
1848 		return -EINVAL;
1849 
1850 	ret = hdmi_drm_infoframe_init(frame);
1851 	if (ret)
1852 		return ret;
1853 
1854 	frame->eotf = ptr[0] & 0x7;
1855 	frame->metadata_type = ptr[1] & 0x7;
1856 
1857 	temp = ptr + 2;
1858 	for (i = 0; i < 3; i++) {
1859 		x_lsb = *temp++;
1860 		x_msb = *temp++;
1861 		frame->display_primaries[i].x = (x_msb << 8) | x_lsb;
1862 		y_lsb = *temp++;
1863 		y_msb = *temp++;
1864 		frame->display_primaries[i].y = (y_msb << 8) | y_lsb;
1865 	}
1866 
1867 	frame->white_point.x = (ptr[15] << 8) | ptr[14];
1868 	frame->white_point.y = (ptr[17] << 8) | ptr[16];
1869 
1870 	frame->max_display_mastering_luminance = (ptr[19] << 8) | ptr[18];
1871 	frame->min_display_mastering_luminance = (ptr[21] << 8) | ptr[20];
1872 	frame->max_cll = (ptr[23] << 8) | ptr[22];
1873 	frame->max_fall = (ptr[25] << 8) | ptr[24];
1874 
1875 	return 0;
1876 }
1877 EXPORT_SYMBOL(hdmi_drm_infoframe_unpack_only);
1878 
1879 /**
1880  * hdmi_drm_infoframe_unpack() - unpack binary buffer to a HDMI DRM infoframe
1881  * @frame: HDMI DRM infoframe
1882  * @buffer: source buffer
1883  * @size: size of buffer
1884  *
1885  * Unpacks the CTA-861-G DRM infoframe contained in the binary @buffer into
1886  * a structured @frame of the HDMI Dynamic Range and Mastering (DRM)
1887  * infoframe. It also verifies the checksum as required by section 5.3.5 of
1888  * the HDMI 1.4 specification.
1889  *
1890  * Returns 0 on success or a negative error code on failure.
1891  */
hdmi_drm_infoframe_unpack(struct hdmi_drm_infoframe * frame,const void * buffer,size_t size)1892 static int hdmi_drm_infoframe_unpack(struct hdmi_drm_infoframe *frame,
1893 				     const void *buffer, size_t size)
1894 {
1895 	const u8 *ptr = buffer;
1896 	int ret;
1897 
1898 	if (size < HDMI_INFOFRAME_SIZE(DRM))
1899 		return -EINVAL;
1900 
1901 	if (ptr[0] != HDMI_INFOFRAME_TYPE_DRM ||
1902 	    ptr[1] != 1 ||
1903 	    ptr[2] != HDMI_DRM_INFOFRAME_SIZE)
1904 		return -EINVAL;
1905 
1906 	if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(DRM)) != 0)
1907 		return -EINVAL;
1908 
1909 	ret = hdmi_drm_infoframe_unpack_only(frame, ptr + HDMI_INFOFRAME_HEADER_SIZE,
1910 					     size - HDMI_INFOFRAME_HEADER_SIZE);
1911 	return ret;
1912 }
1913 
1914 /**
1915  * hdmi_infoframe_unpack() - unpack binary buffer to a HDMI infoframe
1916  * @frame: HDMI infoframe
1917  * @buffer: source buffer
1918  * @size: size of buffer
1919  *
1920  * Unpacks the information contained in binary buffer @buffer into a structured
1921  * @frame of a HDMI infoframe.
1922  * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
1923  * specification.
1924  *
1925  * Returns 0 on success or a negative error code on failure.
1926  */
hdmi_infoframe_unpack(union hdmi_infoframe * frame,const void * buffer,size_t size)1927 int hdmi_infoframe_unpack(union hdmi_infoframe *frame,
1928 			  const void *buffer, size_t size)
1929 {
1930 	int ret;
1931 	const u8 *ptr = buffer;
1932 
1933 	if (size < HDMI_INFOFRAME_HEADER_SIZE)
1934 		return -EINVAL;
1935 
1936 	switch (ptr[0]) {
1937 	case HDMI_INFOFRAME_TYPE_AVI:
1938 		ret = hdmi_avi_infoframe_unpack(&frame->avi, buffer, size);
1939 		break;
1940 	case HDMI_INFOFRAME_TYPE_DRM:
1941 		ret = hdmi_drm_infoframe_unpack(&frame->drm, buffer, size);
1942 		break;
1943 	case HDMI_INFOFRAME_TYPE_SPD:
1944 		ret = hdmi_spd_infoframe_unpack(&frame->spd, buffer, size);
1945 		break;
1946 	case HDMI_INFOFRAME_TYPE_AUDIO:
1947 		ret = hdmi_audio_infoframe_unpack(&frame->audio, buffer, size);
1948 		break;
1949 	case HDMI_INFOFRAME_TYPE_VENDOR:
1950 		ret = hdmi_vendor_any_infoframe_unpack(&frame->vendor, buffer, size);
1951 		break;
1952 	default:
1953 		ret = -EINVAL;
1954 		break;
1955 	}
1956 
1957 	return ret;
1958 }
1959 EXPORT_SYMBOL(hdmi_infoframe_unpack);
1960