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