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 <linux/bitops.h> 25 #include <linux/bug.h> 26 #include <linux/errno.h> 27 #include <linux/export.h> 28 #include <linux/hdmi.h> 29 #include <linux/string.h> 30 #include <linux/device.h> 31 32 #define hdmi_log(fmt, ...) dev_printk(level, dev, fmt, ##__VA_ARGS__) 33 34 static u8 hdmi_infoframe_checksum(u8 *ptr, size_t size) 35 { 36 u8 csum = 0; 37 size_t i; 38 39 /* compute checksum */ 40 for (i = 0; i < size; i++) 41 csum += ptr[i]; 42 43 return 256 - csum; 44 } 45 46 static void hdmi_infoframe_set_checksum(void *buffer, size_t size) 47 { 48 u8 *ptr = buffer; 49 50 ptr[3] = hdmi_infoframe_checksum(buffer, size); 51 } 52 53 /** 54 * hdmi_avi_infoframe_init() - initialize an HDMI AVI infoframe 55 * @frame: HDMI AVI infoframe 56 * 57 * Returns 0 on success or a negative error code on failure. 58 */ 59 int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame) 60 { 61 memset(frame, 0, sizeof(*frame)); 62 63 frame->type = HDMI_INFOFRAME_TYPE_AVI; 64 frame->version = 2; 65 frame->length = HDMI_AVI_INFOFRAME_SIZE; 66 67 return 0; 68 } 69 EXPORT_SYMBOL(hdmi_avi_infoframe_init); 70 71 /** 72 * hdmi_avi_infoframe_pack() - write HDMI AVI infoframe to binary buffer 73 * @frame: HDMI AVI infoframe 74 * @buffer: destination buffer 75 * @size: size of buffer 76 * 77 * Packs the information contained in the @frame structure into a binary 78 * representation that can be written into the corresponding controller 79 * registers. Also computes the checksum as required by section 5.3.5 of 80 * the HDMI 1.4 specification. 81 * 82 * Returns the number of bytes packed into the binary buffer or a negative 83 * error code on failure. 84 */ 85 ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer, 86 size_t size) 87 { 88 u8 *ptr = buffer; 89 size_t length; 90 91 length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; 92 93 if (size < length) 94 return -ENOSPC; 95 96 if (frame->picture_aspect > HDMI_PICTURE_ASPECT_16_9) 97 return -EINVAL; 98 99 memset(buffer, 0, size); 100 101 ptr[0] = frame->type; 102 ptr[1] = frame->version; 103 ptr[2] = frame->length; 104 ptr[3] = 0; /* checksum */ 105 106 /* start infoframe payload */ 107 ptr += HDMI_INFOFRAME_HEADER_SIZE; 108 109 ptr[0] = ((frame->colorspace & 0x3) << 5) | (frame->scan_mode & 0x3); 110 111 /* 112 * Data byte 1, bit 4 has to be set if we provide the active format 113 * aspect ratio 114 */ 115 if (frame->active_aspect & 0xf) 116 ptr[0] |= BIT(4); 117 118 /* Bit 3 and 2 indicate if we transmit horizontal/vertical bar data */ 119 if (frame->top_bar || frame->bottom_bar) 120 ptr[0] |= BIT(3); 121 122 if (frame->left_bar || frame->right_bar) 123 ptr[0] |= BIT(2); 124 125 ptr[1] = ((frame->colorimetry & 0x3) << 6) | 126 ((frame->picture_aspect & 0x3) << 4) | 127 (frame->active_aspect & 0xf); 128 129 ptr[2] = ((frame->extended_colorimetry & 0x7) << 4) | 130 ((frame->quantization_range & 0x3) << 2) | 131 (frame->nups & 0x3); 132 133 if (frame->itc) 134 ptr[2] |= BIT(7); 135 136 ptr[3] = frame->video_code & 0x7f; 137 138 ptr[4] = ((frame->ycc_quantization_range & 0x3) << 6) | 139 ((frame->content_type & 0x3) << 4) | 140 (frame->pixel_repeat & 0xf); 141 142 ptr[5] = frame->top_bar & 0xff; 143 ptr[6] = (frame->top_bar >> 8) & 0xff; 144 ptr[7] = frame->bottom_bar & 0xff; 145 ptr[8] = (frame->bottom_bar >> 8) & 0xff; 146 ptr[9] = frame->left_bar & 0xff; 147 ptr[10] = (frame->left_bar >> 8) & 0xff; 148 ptr[11] = frame->right_bar & 0xff; 149 ptr[12] = (frame->right_bar >> 8) & 0xff; 150 151 hdmi_infoframe_set_checksum(buffer, length); 152 153 return length; 154 } 155 EXPORT_SYMBOL(hdmi_avi_infoframe_pack); 156 157 /** 158 * hdmi_spd_infoframe_init() - initialize an HDMI SPD infoframe 159 * @frame: HDMI SPD infoframe 160 * @vendor: vendor string 161 * @product: product string 162 * 163 * Returns 0 on success or a negative error code on failure. 164 */ 165 int hdmi_spd_infoframe_init(struct hdmi_spd_infoframe *frame, 166 const char *vendor, const char *product) 167 { 168 memset(frame, 0, sizeof(*frame)); 169 170 frame->type = HDMI_INFOFRAME_TYPE_SPD; 171 frame->version = 1; 172 frame->length = HDMI_SPD_INFOFRAME_SIZE; 173 174 strncpy(frame->vendor, vendor, sizeof(frame->vendor)); 175 strncpy(frame->product, product, sizeof(frame->product)); 176 177 return 0; 178 } 179 EXPORT_SYMBOL(hdmi_spd_infoframe_init); 180 181 /** 182 * hdmi_spd_infoframe_pack() - write HDMI SPD infoframe to binary buffer 183 * @frame: HDMI SPD infoframe 184 * @buffer: destination buffer 185 * @size: size of buffer 186 * 187 * Packs the information contained in the @frame structure into a binary 188 * representation that can be written into the corresponding controller 189 * registers. Also computes the checksum as required by section 5.3.5 of 190 * the HDMI 1.4 specification. 191 * 192 * Returns the number of bytes packed into the binary buffer or a negative 193 * error code on failure. 194 */ 195 ssize_t hdmi_spd_infoframe_pack(struct hdmi_spd_infoframe *frame, void *buffer, 196 size_t size) 197 { 198 u8 *ptr = buffer; 199 size_t length; 200 201 length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; 202 203 if (size < length) 204 return -ENOSPC; 205 206 memset(buffer, 0, size); 207 208 ptr[0] = frame->type; 209 ptr[1] = frame->version; 210 ptr[2] = frame->length; 211 ptr[3] = 0; /* checksum */ 212 213 /* start infoframe payload */ 214 ptr += HDMI_INFOFRAME_HEADER_SIZE; 215 216 memcpy(ptr, frame->vendor, sizeof(frame->vendor)); 217 memcpy(ptr + 8, frame->product, sizeof(frame->product)); 218 219 ptr[24] = frame->sdi; 220 221 hdmi_infoframe_set_checksum(buffer, length); 222 223 return length; 224 } 225 EXPORT_SYMBOL(hdmi_spd_infoframe_pack); 226 227 /** 228 * hdmi_audio_infoframe_init() - initialize an HDMI audio infoframe 229 * @frame: HDMI audio infoframe 230 * 231 * Returns 0 on success or a negative error code on failure. 232 */ 233 int hdmi_audio_infoframe_init(struct hdmi_audio_infoframe *frame) 234 { 235 memset(frame, 0, sizeof(*frame)); 236 237 frame->type = HDMI_INFOFRAME_TYPE_AUDIO; 238 frame->version = 1; 239 frame->length = HDMI_AUDIO_INFOFRAME_SIZE; 240 241 return 0; 242 } 243 EXPORT_SYMBOL(hdmi_audio_infoframe_init); 244 245 /** 246 * hdmi_audio_infoframe_pack() - write HDMI audio infoframe to binary buffer 247 * @frame: HDMI audio infoframe 248 * @buffer: destination buffer 249 * @size: size of buffer 250 * 251 * Packs the information contained in the @frame structure into a binary 252 * representation that can be written into the corresponding controller 253 * registers. Also computes the checksum as required by section 5.3.5 of 254 * the HDMI 1.4 specification. 255 * 256 * Returns the number of bytes packed into the binary buffer or a negative 257 * error code on failure. 258 */ 259 ssize_t hdmi_audio_infoframe_pack(struct hdmi_audio_infoframe *frame, 260 void *buffer, size_t size) 261 { 262 unsigned char channels; 263 u8 *ptr = buffer; 264 size_t length; 265 266 length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; 267 268 if (size < length) 269 return -ENOSPC; 270 271 memset(buffer, 0, size); 272 273 if (frame->channels >= 2) 274 channels = frame->channels - 1; 275 else 276 channels = 0; 277 278 ptr[0] = frame->type; 279 ptr[1] = frame->version; 280 ptr[2] = frame->length; 281 ptr[3] = 0; /* checksum */ 282 283 /* start infoframe payload */ 284 ptr += HDMI_INFOFRAME_HEADER_SIZE; 285 286 ptr[0] = ((frame->coding_type & 0xf) << 4) | (channels & 0x7); 287 ptr[1] = ((frame->sample_frequency & 0x7) << 2) | 288 (frame->sample_size & 0x3); 289 ptr[2] = frame->coding_type_ext & 0x1f; 290 ptr[3] = frame->channel_allocation; 291 ptr[4] = (frame->level_shift_value & 0xf) << 3; 292 293 if (frame->downmix_inhibit) 294 ptr[4] |= BIT(7); 295 296 hdmi_infoframe_set_checksum(buffer, length); 297 298 return length; 299 } 300 EXPORT_SYMBOL(hdmi_audio_infoframe_pack); 301 302 /** 303 * hdmi_vendor_infoframe_init() - initialize an HDMI vendor infoframe 304 * @frame: HDMI vendor infoframe 305 * 306 * Returns 0 on success or a negative error code on failure. 307 */ 308 int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame) 309 { 310 memset(frame, 0, sizeof(*frame)); 311 312 frame->type = HDMI_INFOFRAME_TYPE_VENDOR; 313 frame->version = 1; 314 315 frame->oui = HDMI_IEEE_OUI; 316 317 /* 318 * 0 is a valid value for s3d_struct, so we use a special "not set" 319 * value 320 */ 321 frame->s3d_struct = HDMI_3D_STRUCTURE_INVALID; 322 323 return 0; 324 } 325 EXPORT_SYMBOL(hdmi_vendor_infoframe_init); 326 327 static int hdmi_vendor_infoframe_length(const struct hdmi_vendor_infoframe *frame) 328 { 329 /* for side by side (half) we also need to provide 3D_Ext_Data */ 330 if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) 331 return 6; 332 else if (frame->vic != 0 || frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) 333 return 5; 334 else 335 return 4; 336 } 337 338 /** 339 * hdmi_vendor_infoframe_pack() - write a HDMI vendor infoframe to binary buffer 340 * @frame: HDMI infoframe 341 * @buffer: destination buffer 342 * @size: size of buffer 343 * 344 * Packs the information contained in the @frame structure into a binary 345 * representation that can be written into the corresponding controller 346 * registers. Also computes the checksum as required by section 5.3.5 of 347 * the HDMI 1.4 specification. 348 * 349 * Returns the number of bytes packed into the binary buffer or a negative 350 * error code on failure. 351 */ 352 ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame, 353 void *buffer, size_t size) 354 { 355 u8 *ptr = buffer; 356 size_t length; 357 358 /* only one of those can be supplied */ 359 if (frame->vic != 0 && frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) 360 return -EINVAL; 361 362 frame->length = hdmi_vendor_infoframe_length(frame); 363 364 length = HDMI_INFOFRAME_HEADER_SIZE + frame->length; 365 366 if (size < length) 367 return -ENOSPC; 368 369 memset(buffer, 0, size); 370 371 ptr[0] = frame->type; 372 ptr[1] = frame->version; 373 ptr[2] = frame->length; 374 ptr[3] = 0; /* checksum */ 375 376 /* HDMI OUI */ 377 ptr[4] = 0x03; 378 ptr[5] = 0x0c; 379 ptr[6] = 0x00; 380 381 if (frame->s3d_struct != HDMI_3D_STRUCTURE_INVALID) { 382 ptr[7] = 0x2 << 5; /* video format */ 383 ptr[8] = (frame->s3d_struct & 0xf) << 4; 384 if (frame->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) 385 ptr[9] = (frame->s3d_ext_data & 0xf) << 4; 386 } else if (frame->vic) { 387 ptr[7] = 0x1 << 5; /* video format */ 388 ptr[8] = frame->vic; 389 } else { 390 ptr[7] = 0x0 << 5; /* video format */ 391 } 392 393 hdmi_infoframe_set_checksum(buffer, length); 394 395 return length; 396 } 397 EXPORT_SYMBOL(hdmi_vendor_infoframe_pack); 398 399 /* 400 * hdmi_vendor_any_infoframe_pack() - write a vendor infoframe to binary buffer 401 */ 402 static ssize_t 403 hdmi_vendor_any_infoframe_pack(union hdmi_vendor_any_infoframe *frame, 404 void *buffer, size_t size) 405 { 406 /* we only know about HDMI vendor infoframes */ 407 if (frame->any.oui != HDMI_IEEE_OUI) 408 return -EINVAL; 409 410 return hdmi_vendor_infoframe_pack(&frame->hdmi, buffer, size); 411 } 412 413 /** 414 * hdmi_infoframe_pack() - write a HDMI infoframe to binary buffer 415 * @frame: HDMI 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 ssize_t 428 hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer, size_t size) 429 { 430 ssize_t length; 431 432 switch (frame->any.type) { 433 case HDMI_INFOFRAME_TYPE_AVI: 434 length = hdmi_avi_infoframe_pack(&frame->avi, buffer, size); 435 break; 436 case HDMI_INFOFRAME_TYPE_SPD: 437 length = hdmi_spd_infoframe_pack(&frame->spd, buffer, size); 438 break; 439 case HDMI_INFOFRAME_TYPE_AUDIO: 440 length = hdmi_audio_infoframe_pack(&frame->audio, buffer, size); 441 break; 442 case HDMI_INFOFRAME_TYPE_VENDOR: 443 length = hdmi_vendor_any_infoframe_pack(&frame->vendor, 444 buffer, size); 445 break; 446 default: 447 WARN(1, "Bad infoframe type %d\n", frame->any.type); 448 length = -EINVAL; 449 } 450 451 return length; 452 } 453 EXPORT_SYMBOL(hdmi_infoframe_pack); 454 455 static const char *hdmi_infoframe_type_get_name(enum hdmi_infoframe_type type) 456 { 457 if (type < 0x80 || type > 0x9f) 458 return "Invalid"; 459 switch (type) { 460 case HDMI_INFOFRAME_TYPE_VENDOR: 461 return "Vendor"; 462 case HDMI_INFOFRAME_TYPE_AVI: 463 return "Auxiliary Video Information (AVI)"; 464 case HDMI_INFOFRAME_TYPE_SPD: 465 return "Source Product Description (SPD)"; 466 case HDMI_INFOFRAME_TYPE_AUDIO: 467 return "Audio"; 468 } 469 return "Reserved"; 470 } 471 472 static void hdmi_infoframe_log_header(const char *level, 473 struct device *dev, 474 struct hdmi_any_infoframe *frame) 475 { 476 hdmi_log("HDMI infoframe: %s, version %u, length %u\n", 477 hdmi_infoframe_type_get_name(frame->type), 478 frame->version, frame->length); 479 } 480 481 static const char *hdmi_colorspace_get_name(enum hdmi_colorspace colorspace) 482 { 483 switch (colorspace) { 484 case HDMI_COLORSPACE_RGB: 485 return "RGB"; 486 case HDMI_COLORSPACE_YUV422: 487 return "YCbCr 4:2:2"; 488 case HDMI_COLORSPACE_YUV444: 489 return "YCbCr 4:4:4"; 490 case HDMI_COLORSPACE_YUV420: 491 return "YCbCr 4:2:0"; 492 case HDMI_COLORSPACE_RESERVED4: 493 return "Reserved (4)"; 494 case HDMI_COLORSPACE_RESERVED5: 495 return "Reserved (5)"; 496 case HDMI_COLORSPACE_RESERVED6: 497 return "Reserved (6)"; 498 case HDMI_COLORSPACE_IDO_DEFINED: 499 return "IDO Defined"; 500 } 501 return "Invalid"; 502 } 503 504 static const char *hdmi_scan_mode_get_name(enum hdmi_scan_mode scan_mode) 505 { 506 switch (scan_mode) { 507 case HDMI_SCAN_MODE_NONE: 508 return "No Data"; 509 case HDMI_SCAN_MODE_OVERSCAN: 510 return "Overscan"; 511 case HDMI_SCAN_MODE_UNDERSCAN: 512 return "Underscan"; 513 case HDMI_SCAN_MODE_RESERVED: 514 return "Reserved"; 515 } 516 return "Invalid"; 517 } 518 519 static const char *hdmi_colorimetry_get_name(enum hdmi_colorimetry colorimetry) 520 { 521 switch (colorimetry) { 522 case HDMI_COLORIMETRY_NONE: 523 return "No Data"; 524 case HDMI_COLORIMETRY_ITU_601: 525 return "ITU601"; 526 case HDMI_COLORIMETRY_ITU_709: 527 return "ITU709"; 528 case HDMI_COLORIMETRY_EXTENDED: 529 return "Extended"; 530 } 531 return "Invalid"; 532 } 533 534 static const char * 535 hdmi_picture_aspect_get_name(enum hdmi_picture_aspect picture_aspect) 536 { 537 switch (picture_aspect) { 538 case HDMI_PICTURE_ASPECT_NONE: 539 return "No Data"; 540 case HDMI_PICTURE_ASPECT_4_3: 541 return "4:3"; 542 case HDMI_PICTURE_ASPECT_16_9: 543 return "16:9"; 544 case HDMI_PICTURE_ASPECT_64_27: 545 return "64:27"; 546 case HDMI_PICTURE_ASPECT_256_135: 547 return "256:135"; 548 case HDMI_PICTURE_ASPECT_RESERVED: 549 return "Reserved"; 550 } 551 return "Invalid"; 552 } 553 554 static const char * 555 hdmi_active_aspect_get_name(enum hdmi_active_aspect active_aspect) 556 { 557 if (active_aspect < 0 || active_aspect > 0xf) 558 return "Invalid"; 559 560 switch (active_aspect) { 561 case HDMI_ACTIVE_ASPECT_16_9_TOP: 562 return "16:9 Top"; 563 case HDMI_ACTIVE_ASPECT_14_9_TOP: 564 return "14:9 Top"; 565 case HDMI_ACTIVE_ASPECT_16_9_CENTER: 566 return "16:9 Center"; 567 case HDMI_ACTIVE_ASPECT_PICTURE: 568 return "Same as Picture"; 569 case HDMI_ACTIVE_ASPECT_4_3: 570 return "4:3"; 571 case HDMI_ACTIVE_ASPECT_16_9: 572 return "16:9"; 573 case HDMI_ACTIVE_ASPECT_14_9: 574 return "14:9"; 575 case HDMI_ACTIVE_ASPECT_4_3_SP_14_9: 576 return "4:3 SP 14:9"; 577 case HDMI_ACTIVE_ASPECT_16_9_SP_14_9: 578 return "16:9 SP 14:9"; 579 case HDMI_ACTIVE_ASPECT_16_9_SP_4_3: 580 return "16:9 SP 4:3"; 581 } 582 return "Reserved"; 583 } 584 585 static const char * 586 hdmi_extended_colorimetry_get_name(enum hdmi_extended_colorimetry ext_col) 587 { 588 switch (ext_col) { 589 case HDMI_EXTENDED_COLORIMETRY_XV_YCC_601: 590 return "xvYCC 601"; 591 case HDMI_EXTENDED_COLORIMETRY_XV_YCC_709: 592 return "xvYCC 709"; 593 case HDMI_EXTENDED_COLORIMETRY_S_YCC_601: 594 return "sYCC 601"; 595 case HDMI_EXTENDED_COLORIMETRY_OPYCC_601: 596 return "opYCC 601"; 597 case HDMI_EXTENDED_COLORIMETRY_OPRGB: 598 return "opRGB"; 599 case HDMI_EXTENDED_COLORIMETRY_BT2020_CONST_LUM: 600 return "BT.2020 Constant Luminance"; 601 case HDMI_EXTENDED_COLORIMETRY_BT2020: 602 return "BT.2020"; 603 case HDMI_EXTENDED_COLORIMETRY_RESERVED: 604 return "Reserved"; 605 } 606 return "Invalid"; 607 } 608 609 static const char * 610 hdmi_quantization_range_get_name(enum hdmi_quantization_range qrange) 611 { 612 switch (qrange) { 613 case HDMI_QUANTIZATION_RANGE_DEFAULT: 614 return "Default"; 615 case HDMI_QUANTIZATION_RANGE_LIMITED: 616 return "Limited"; 617 case HDMI_QUANTIZATION_RANGE_FULL: 618 return "Full"; 619 case HDMI_QUANTIZATION_RANGE_RESERVED: 620 return "Reserved"; 621 } 622 return "Invalid"; 623 } 624 625 static const char *hdmi_nups_get_name(enum hdmi_nups nups) 626 { 627 switch (nups) { 628 case HDMI_NUPS_UNKNOWN: 629 return "Unknown Non-uniform Scaling"; 630 case HDMI_NUPS_HORIZONTAL: 631 return "Horizontally Scaled"; 632 case HDMI_NUPS_VERTICAL: 633 return "Vertically Scaled"; 634 case HDMI_NUPS_BOTH: 635 return "Horizontally and Vertically Scaled"; 636 } 637 return "Invalid"; 638 } 639 640 static const char * 641 hdmi_ycc_quantization_range_get_name(enum hdmi_ycc_quantization_range qrange) 642 { 643 switch (qrange) { 644 case HDMI_YCC_QUANTIZATION_RANGE_LIMITED: 645 return "Limited"; 646 case HDMI_YCC_QUANTIZATION_RANGE_FULL: 647 return "Full"; 648 } 649 return "Invalid"; 650 } 651 652 static const char * 653 hdmi_content_type_get_name(enum hdmi_content_type content_type) 654 { 655 switch (content_type) { 656 case HDMI_CONTENT_TYPE_GRAPHICS: 657 return "Graphics"; 658 case HDMI_CONTENT_TYPE_PHOTO: 659 return "Photo"; 660 case HDMI_CONTENT_TYPE_CINEMA: 661 return "Cinema"; 662 case HDMI_CONTENT_TYPE_GAME: 663 return "Game"; 664 } 665 return "Invalid"; 666 } 667 668 /** 669 * hdmi_avi_infoframe_log() - log info of HDMI AVI infoframe 670 * @level: logging level 671 * @dev: device 672 * @frame: HDMI AVI infoframe 673 */ 674 static void hdmi_avi_infoframe_log(const char *level, 675 struct device *dev, 676 struct hdmi_avi_infoframe *frame) 677 { 678 hdmi_infoframe_log_header(level, dev, 679 (struct hdmi_any_infoframe *)frame); 680 681 hdmi_log(" colorspace: %s\n", 682 hdmi_colorspace_get_name(frame->colorspace)); 683 hdmi_log(" scan mode: %s\n", 684 hdmi_scan_mode_get_name(frame->scan_mode)); 685 hdmi_log(" colorimetry: %s\n", 686 hdmi_colorimetry_get_name(frame->colorimetry)); 687 hdmi_log(" picture aspect: %s\n", 688 hdmi_picture_aspect_get_name(frame->picture_aspect)); 689 hdmi_log(" active aspect: %s\n", 690 hdmi_active_aspect_get_name(frame->active_aspect)); 691 hdmi_log(" itc: %s\n", frame->itc ? "IT Content" : "No Data"); 692 hdmi_log(" extended colorimetry: %s\n", 693 hdmi_extended_colorimetry_get_name(frame->extended_colorimetry)); 694 hdmi_log(" quantization range: %s\n", 695 hdmi_quantization_range_get_name(frame->quantization_range)); 696 hdmi_log(" nups: %s\n", hdmi_nups_get_name(frame->nups)); 697 hdmi_log(" video code: %u\n", frame->video_code); 698 hdmi_log(" ycc quantization range: %s\n", 699 hdmi_ycc_quantization_range_get_name(frame->ycc_quantization_range)); 700 hdmi_log(" hdmi content type: %s\n", 701 hdmi_content_type_get_name(frame->content_type)); 702 hdmi_log(" pixel repeat: %u\n", frame->pixel_repeat); 703 hdmi_log(" bar top %u, bottom %u, left %u, right %u\n", 704 frame->top_bar, frame->bottom_bar, 705 frame->left_bar, frame->right_bar); 706 } 707 708 static const char *hdmi_spd_sdi_get_name(enum hdmi_spd_sdi sdi) 709 { 710 if (sdi < 0 || sdi > 0xff) 711 return "Invalid"; 712 switch (sdi) { 713 case HDMI_SPD_SDI_UNKNOWN: 714 return "Unknown"; 715 case HDMI_SPD_SDI_DSTB: 716 return "Digital STB"; 717 case HDMI_SPD_SDI_DVDP: 718 return "DVD Player"; 719 case HDMI_SPD_SDI_DVHS: 720 return "D-VHS"; 721 case HDMI_SPD_SDI_HDDVR: 722 return "HDD Videorecorder"; 723 case HDMI_SPD_SDI_DVC: 724 return "DVC"; 725 case HDMI_SPD_SDI_DSC: 726 return "DSC"; 727 case HDMI_SPD_SDI_VCD: 728 return "Video CD"; 729 case HDMI_SPD_SDI_GAME: 730 return "Game"; 731 case HDMI_SPD_SDI_PC: 732 return "PC General"; 733 case HDMI_SPD_SDI_BD: 734 return "Blu-Ray Disc (BD)"; 735 case HDMI_SPD_SDI_SACD: 736 return "Super Audio CD"; 737 case HDMI_SPD_SDI_HDDVD: 738 return "HD DVD"; 739 case HDMI_SPD_SDI_PMP: 740 return "PMP"; 741 } 742 return "Reserved"; 743 } 744 745 /** 746 * hdmi_spd_infoframe_log() - log info of HDMI SPD infoframe 747 * @level: logging level 748 * @dev: device 749 * @frame: HDMI SPD infoframe 750 */ 751 static void hdmi_spd_infoframe_log(const char *level, 752 struct device *dev, 753 struct hdmi_spd_infoframe *frame) 754 { 755 u8 buf[17]; 756 757 hdmi_infoframe_log_header(level, dev, 758 (struct hdmi_any_infoframe *)frame); 759 760 memset(buf, 0, sizeof(buf)); 761 762 strncpy(buf, frame->vendor, 8); 763 hdmi_log(" vendor: %s\n", buf); 764 strncpy(buf, frame->product, 16); 765 hdmi_log(" product: %s\n", buf); 766 hdmi_log(" source device information: %s (0x%x)\n", 767 hdmi_spd_sdi_get_name(frame->sdi), frame->sdi); 768 } 769 770 static const char * 771 hdmi_audio_coding_type_get_name(enum hdmi_audio_coding_type coding_type) 772 { 773 switch (coding_type) { 774 case HDMI_AUDIO_CODING_TYPE_STREAM: 775 return "Refer to Stream Header"; 776 case HDMI_AUDIO_CODING_TYPE_PCM: 777 return "PCM"; 778 case HDMI_AUDIO_CODING_TYPE_AC3: 779 return "AC-3"; 780 case HDMI_AUDIO_CODING_TYPE_MPEG1: 781 return "MPEG1"; 782 case HDMI_AUDIO_CODING_TYPE_MP3: 783 return "MP3"; 784 case HDMI_AUDIO_CODING_TYPE_MPEG2: 785 return "MPEG2"; 786 case HDMI_AUDIO_CODING_TYPE_AAC_LC: 787 return "AAC"; 788 case HDMI_AUDIO_CODING_TYPE_DTS: 789 return "DTS"; 790 case HDMI_AUDIO_CODING_TYPE_ATRAC: 791 return "ATRAC"; 792 case HDMI_AUDIO_CODING_TYPE_DSD: 793 return "One Bit Audio"; 794 case HDMI_AUDIO_CODING_TYPE_EAC3: 795 return "Dolby Digital +"; 796 case HDMI_AUDIO_CODING_TYPE_DTS_HD: 797 return "DTS-HD"; 798 case HDMI_AUDIO_CODING_TYPE_MLP: 799 return "MAT (MLP)"; 800 case HDMI_AUDIO_CODING_TYPE_DST: 801 return "DST"; 802 case HDMI_AUDIO_CODING_TYPE_WMA_PRO: 803 return "WMA PRO"; 804 case HDMI_AUDIO_CODING_TYPE_CXT: 805 return "Refer to CXT"; 806 } 807 return "Invalid"; 808 } 809 810 static const char * 811 hdmi_audio_sample_size_get_name(enum hdmi_audio_sample_size sample_size) 812 { 813 switch (sample_size) { 814 case HDMI_AUDIO_SAMPLE_SIZE_STREAM: 815 return "Refer to Stream Header"; 816 case HDMI_AUDIO_SAMPLE_SIZE_16: 817 return "16 bit"; 818 case HDMI_AUDIO_SAMPLE_SIZE_20: 819 return "20 bit"; 820 case HDMI_AUDIO_SAMPLE_SIZE_24: 821 return "24 bit"; 822 } 823 return "Invalid"; 824 } 825 826 static const char * 827 hdmi_audio_sample_frequency_get_name(enum hdmi_audio_sample_frequency freq) 828 { 829 switch (freq) { 830 case HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM: 831 return "Refer to Stream Header"; 832 case HDMI_AUDIO_SAMPLE_FREQUENCY_32000: 833 return "32 kHz"; 834 case HDMI_AUDIO_SAMPLE_FREQUENCY_44100: 835 return "44.1 kHz (CD)"; 836 case HDMI_AUDIO_SAMPLE_FREQUENCY_48000: 837 return "48 kHz"; 838 case HDMI_AUDIO_SAMPLE_FREQUENCY_88200: 839 return "88.2 kHz"; 840 case HDMI_AUDIO_SAMPLE_FREQUENCY_96000: 841 return "96 kHz"; 842 case HDMI_AUDIO_SAMPLE_FREQUENCY_176400: 843 return "176.4 kHz"; 844 case HDMI_AUDIO_SAMPLE_FREQUENCY_192000: 845 return "192 kHz"; 846 } 847 return "Invalid"; 848 } 849 850 static const char * 851 hdmi_audio_coding_type_ext_get_name(enum hdmi_audio_coding_type_ext ctx) 852 { 853 if (ctx < 0 || ctx > 0x1f) 854 return "Invalid"; 855 856 switch (ctx) { 857 case HDMI_AUDIO_CODING_TYPE_EXT_CT: 858 return "Refer to CT"; 859 case HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC: 860 return "HE AAC"; 861 case HDMI_AUDIO_CODING_TYPE_EXT_HE_AAC_V2: 862 return "HE AAC v2"; 863 case HDMI_AUDIO_CODING_TYPE_EXT_MPEG_SURROUND: 864 return "MPEG SURROUND"; 865 case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC: 866 return "MPEG-4 HE AAC"; 867 case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC_V2: 868 return "MPEG-4 HE AAC v2"; 869 case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_AAC_LC: 870 return "MPEG-4 AAC LC"; 871 case HDMI_AUDIO_CODING_TYPE_EXT_DRA: 872 return "DRA"; 873 case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_HE_AAC_SURROUND: 874 return "MPEG-4 HE AAC + MPEG Surround"; 875 case HDMI_AUDIO_CODING_TYPE_EXT_MPEG4_AAC_LC_SURROUND: 876 return "MPEG-4 AAC LC + MPEG Surround"; 877 } 878 return "Reserved"; 879 } 880 881 /** 882 * hdmi_audio_infoframe_log() - log info of HDMI AUDIO infoframe 883 * @level: logging level 884 * @dev: device 885 * @frame: HDMI AUDIO infoframe 886 */ 887 static void hdmi_audio_infoframe_log(const char *level, 888 struct device *dev, 889 struct hdmi_audio_infoframe *frame) 890 { 891 hdmi_infoframe_log_header(level, dev, 892 (struct hdmi_any_infoframe *)frame); 893 894 if (frame->channels) 895 hdmi_log(" channels: %u\n", frame->channels - 1); 896 else 897 hdmi_log(" channels: Refer to stream header\n"); 898 hdmi_log(" coding type: %s\n", 899 hdmi_audio_coding_type_get_name(frame->coding_type)); 900 hdmi_log(" sample size: %s\n", 901 hdmi_audio_sample_size_get_name(frame->sample_size)); 902 hdmi_log(" sample frequency: %s\n", 903 hdmi_audio_sample_frequency_get_name(frame->sample_frequency)); 904 hdmi_log(" coding type ext: %s\n", 905 hdmi_audio_coding_type_ext_get_name(frame->coding_type_ext)); 906 hdmi_log(" channel allocation: 0x%x\n", 907 frame->channel_allocation); 908 hdmi_log(" level shift value: %u dB\n", 909 frame->level_shift_value); 910 hdmi_log(" downmix inhibit: %s\n", 911 frame->downmix_inhibit ? "Yes" : "No"); 912 } 913 914 static const char * 915 hdmi_3d_structure_get_name(enum hdmi_3d_structure s3d_struct) 916 { 917 if (s3d_struct < 0 || s3d_struct > 0xf) 918 return "Invalid"; 919 920 switch (s3d_struct) { 921 case HDMI_3D_STRUCTURE_FRAME_PACKING: 922 return "Frame Packing"; 923 case HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE: 924 return "Field Alternative"; 925 case HDMI_3D_STRUCTURE_LINE_ALTERNATIVE: 926 return "Line Alternative"; 927 case HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL: 928 return "Side-by-side (Full)"; 929 case HDMI_3D_STRUCTURE_L_DEPTH: 930 return "L + Depth"; 931 case HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH: 932 return "L + Depth + Graphics + Graphics-depth"; 933 case HDMI_3D_STRUCTURE_TOP_AND_BOTTOM: 934 return "Top-and-Bottom"; 935 case HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF: 936 return "Side-by-side (Half)"; 937 default: 938 break; 939 } 940 return "Reserved"; 941 } 942 943 /** 944 * hdmi_vendor_infoframe_log() - log info of HDMI VENDOR infoframe 945 * @level: logging level 946 * @dev: device 947 * @frame: HDMI VENDOR infoframe 948 */ 949 static void 950 hdmi_vendor_any_infoframe_log(const char *level, 951 struct device *dev, 952 union hdmi_vendor_any_infoframe *frame) 953 { 954 struct hdmi_vendor_infoframe *hvf = &frame->hdmi; 955 956 hdmi_infoframe_log_header(level, dev, 957 (struct hdmi_any_infoframe *)frame); 958 959 if (frame->any.oui != HDMI_IEEE_OUI) { 960 hdmi_log(" not a HDMI vendor infoframe\n"); 961 return; 962 } 963 if (hvf->vic == 0 && hvf->s3d_struct == HDMI_3D_STRUCTURE_INVALID) { 964 hdmi_log(" empty frame\n"); 965 return; 966 } 967 968 if (hvf->vic) 969 hdmi_log(" HDMI VIC: %u\n", hvf->vic); 970 if (hvf->s3d_struct != HDMI_3D_STRUCTURE_INVALID) { 971 hdmi_log(" 3D structure: %s\n", 972 hdmi_3d_structure_get_name(hvf->s3d_struct)); 973 if (hvf->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) 974 hdmi_log(" 3D extension data: %d\n", 975 hvf->s3d_ext_data); 976 } 977 } 978 979 /** 980 * hdmi_infoframe_log() - log info of HDMI infoframe 981 * @level: logging level 982 * @dev: device 983 * @frame: HDMI infoframe 984 */ 985 void hdmi_infoframe_log(const char *level, 986 struct device *dev, 987 union hdmi_infoframe *frame) 988 { 989 switch (frame->any.type) { 990 case HDMI_INFOFRAME_TYPE_AVI: 991 hdmi_avi_infoframe_log(level, dev, &frame->avi); 992 break; 993 case HDMI_INFOFRAME_TYPE_SPD: 994 hdmi_spd_infoframe_log(level, dev, &frame->spd); 995 break; 996 case HDMI_INFOFRAME_TYPE_AUDIO: 997 hdmi_audio_infoframe_log(level, dev, &frame->audio); 998 break; 999 case HDMI_INFOFRAME_TYPE_VENDOR: 1000 hdmi_vendor_any_infoframe_log(level, dev, &frame->vendor); 1001 break; 1002 } 1003 } 1004 EXPORT_SYMBOL(hdmi_infoframe_log); 1005 1006 /** 1007 * hdmi_avi_infoframe_unpack() - unpack binary buffer to a HDMI AVI infoframe 1008 * @buffer: source buffer 1009 * @frame: HDMI AVI infoframe 1010 * 1011 * Unpacks the information contained in binary @buffer into a structured 1012 * @frame of the HDMI Auxiliary Video (AVI) information frame. 1013 * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4 1014 * specification. 1015 * 1016 * Returns 0 on success or a negative error code on failure. 1017 */ 1018 static int hdmi_avi_infoframe_unpack(struct hdmi_avi_infoframe *frame, 1019 void *buffer) 1020 { 1021 u8 *ptr = buffer; 1022 int ret; 1023 1024 if (ptr[0] != HDMI_INFOFRAME_TYPE_AVI || 1025 ptr[1] != 2 || 1026 ptr[2] != HDMI_AVI_INFOFRAME_SIZE) 1027 return -EINVAL; 1028 1029 if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AVI)) != 0) 1030 return -EINVAL; 1031 1032 ret = hdmi_avi_infoframe_init(frame); 1033 if (ret) 1034 return ret; 1035 1036 ptr += HDMI_INFOFRAME_HEADER_SIZE; 1037 1038 frame->colorspace = (ptr[0] >> 5) & 0x3; 1039 if (ptr[0] & 0x10) 1040 frame->active_aspect = ptr[1] & 0xf; 1041 if (ptr[0] & 0x8) { 1042 frame->top_bar = (ptr[5] << 8) + ptr[6]; 1043 frame->bottom_bar = (ptr[7] << 8) + ptr[8]; 1044 } 1045 if (ptr[0] & 0x4) { 1046 frame->left_bar = (ptr[9] << 8) + ptr[10]; 1047 frame->right_bar = (ptr[11] << 8) + ptr[12]; 1048 } 1049 frame->scan_mode = ptr[0] & 0x3; 1050 1051 frame->colorimetry = (ptr[1] >> 6) & 0x3; 1052 frame->picture_aspect = (ptr[1] >> 4) & 0x3; 1053 frame->active_aspect = ptr[1] & 0xf; 1054 1055 frame->itc = ptr[2] & 0x80 ? true : false; 1056 frame->extended_colorimetry = (ptr[2] >> 4) & 0x7; 1057 frame->quantization_range = (ptr[2] >> 2) & 0x3; 1058 frame->nups = ptr[2] & 0x3; 1059 1060 frame->video_code = ptr[3] & 0x7f; 1061 frame->ycc_quantization_range = (ptr[4] >> 6) & 0x3; 1062 frame->content_type = (ptr[4] >> 4) & 0x3; 1063 1064 frame->pixel_repeat = ptr[4] & 0xf; 1065 1066 return 0; 1067 } 1068 1069 /** 1070 * hdmi_spd_infoframe_unpack() - unpack binary buffer to a HDMI SPD infoframe 1071 * @buffer: source buffer 1072 * @frame: HDMI SPD infoframe 1073 * 1074 * Unpacks the information contained in binary @buffer into a structured 1075 * @frame of the HDMI Source Product Description (SPD) information frame. 1076 * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4 1077 * specification. 1078 * 1079 * Returns 0 on success or a negative error code on failure. 1080 */ 1081 static int hdmi_spd_infoframe_unpack(struct hdmi_spd_infoframe *frame, 1082 void *buffer) 1083 { 1084 u8 *ptr = buffer; 1085 int ret; 1086 1087 if (ptr[0] != HDMI_INFOFRAME_TYPE_SPD || 1088 ptr[1] != 1 || 1089 ptr[2] != HDMI_SPD_INFOFRAME_SIZE) { 1090 return -EINVAL; 1091 } 1092 1093 if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(SPD)) != 0) 1094 return -EINVAL; 1095 1096 ptr += HDMI_INFOFRAME_HEADER_SIZE; 1097 1098 ret = hdmi_spd_infoframe_init(frame, ptr, ptr + 8); 1099 if (ret) 1100 return ret; 1101 1102 frame->sdi = ptr[24]; 1103 1104 return 0; 1105 } 1106 1107 /** 1108 * hdmi_audio_infoframe_unpack() - unpack binary buffer to a HDMI AUDIO infoframe 1109 * @buffer: source buffer 1110 * @frame: HDMI Audio infoframe 1111 * 1112 * Unpacks the information contained in binary @buffer into a structured 1113 * @frame of the HDMI Audio information frame. 1114 * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4 1115 * specification. 1116 * 1117 * Returns 0 on success or a negative error code on failure. 1118 */ 1119 static int hdmi_audio_infoframe_unpack(struct hdmi_audio_infoframe *frame, 1120 void *buffer) 1121 { 1122 u8 *ptr = buffer; 1123 int ret; 1124 1125 if (ptr[0] != HDMI_INFOFRAME_TYPE_AUDIO || 1126 ptr[1] != 1 || 1127 ptr[2] != HDMI_AUDIO_INFOFRAME_SIZE) { 1128 return -EINVAL; 1129 } 1130 1131 if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(AUDIO)) != 0) 1132 return -EINVAL; 1133 1134 ret = hdmi_audio_infoframe_init(frame); 1135 if (ret) 1136 return ret; 1137 1138 ptr += HDMI_INFOFRAME_HEADER_SIZE; 1139 1140 frame->channels = ptr[0] & 0x7; 1141 frame->coding_type = (ptr[0] >> 4) & 0xf; 1142 frame->sample_size = ptr[1] & 0x3; 1143 frame->sample_frequency = (ptr[1] >> 2) & 0x7; 1144 frame->coding_type_ext = ptr[2] & 0x1f; 1145 frame->channel_allocation = ptr[3]; 1146 frame->level_shift_value = (ptr[4] >> 3) & 0xf; 1147 frame->downmix_inhibit = ptr[4] & 0x80 ? true : false; 1148 1149 return 0; 1150 } 1151 1152 /** 1153 * hdmi_vendor_infoframe_unpack() - unpack binary buffer to a HDMI vendor infoframe 1154 * @buffer: source buffer 1155 * @frame: HDMI Vendor infoframe 1156 * 1157 * Unpacks the information contained in binary @buffer into a structured 1158 * @frame of the HDMI Vendor information frame. 1159 * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4 1160 * specification. 1161 * 1162 * Returns 0 on success or a negative error code on failure. 1163 */ 1164 static int 1165 hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame, 1166 void *buffer) 1167 { 1168 u8 *ptr = buffer; 1169 size_t length; 1170 int ret; 1171 u8 hdmi_video_format; 1172 struct hdmi_vendor_infoframe *hvf = &frame->hdmi; 1173 1174 if (ptr[0] != HDMI_INFOFRAME_TYPE_VENDOR || 1175 ptr[1] != 1 || 1176 (ptr[2] != 4 && ptr[2] != 5 && ptr[2] != 6)) 1177 return -EINVAL; 1178 1179 length = ptr[2]; 1180 1181 if (hdmi_infoframe_checksum(buffer, 1182 HDMI_INFOFRAME_HEADER_SIZE + length) != 0) 1183 return -EINVAL; 1184 1185 ptr += HDMI_INFOFRAME_HEADER_SIZE; 1186 1187 /* HDMI OUI */ 1188 if ((ptr[0] != 0x03) || 1189 (ptr[1] != 0x0c) || 1190 (ptr[2] != 0x00)) 1191 return -EINVAL; 1192 1193 hdmi_video_format = ptr[3] >> 5; 1194 1195 if (hdmi_video_format > 0x2) 1196 return -EINVAL; 1197 1198 ret = hdmi_vendor_infoframe_init(hvf); 1199 if (ret) 1200 return ret; 1201 1202 hvf->length = length; 1203 1204 if (hdmi_video_format == 0x2) { 1205 if (length != 5 && length != 6) 1206 return -EINVAL; 1207 hvf->s3d_struct = ptr[4] >> 4; 1208 if (hvf->s3d_struct >= HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF) { 1209 if (length != 6) 1210 return -EINVAL; 1211 hvf->s3d_ext_data = ptr[5] >> 4; 1212 } 1213 } else if (hdmi_video_format == 0x1) { 1214 if (length != 5) 1215 return -EINVAL; 1216 hvf->vic = ptr[4]; 1217 } else { 1218 if (length != 4) 1219 return -EINVAL; 1220 } 1221 1222 return 0; 1223 } 1224 1225 /** 1226 * hdmi_infoframe_unpack() - unpack binary buffer to a HDMI infoframe 1227 * @buffer: source buffer 1228 * @frame: HDMI infoframe 1229 * 1230 * Unpacks the information contained in binary buffer @buffer into a structured 1231 * @frame of a HDMI infoframe. 1232 * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4 1233 * specification. 1234 * 1235 * Returns 0 on success or a negative error code on failure. 1236 */ 1237 int hdmi_infoframe_unpack(union hdmi_infoframe *frame, void *buffer) 1238 { 1239 int ret; 1240 u8 *ptr = buffer; 1241 1242 switch (ptr[0]) { 1243 case HDMI_INFOFRAME_TYPE_AVI: 1244 ret = hdmi_avi_infoframe_unpack(&frame->avi, buffer); 1245 break; 1246 case HDMI_INFOFRAME_TYPE_SPD: 1247 ret = hdmi_spd_infoframe_unpack(&frame->spd, buffer); 1248 break; 1249 case HDMI_INFOFRAME_TYPE_AUDIO: 1250 ret = hdmi_audio_infoframe_unpack(&frame->audio, buffer); 1251 break; 1252 case HDMI_INFOFRAME_TYPE_VENDOR: 1253 ret = hdmi_vendor_any_infoframe_unpack(&frame->vendor, buffer); 1254 break; 1255 default: 1256 ret = -EINVAL; 1257 break; 1258 } 1259 1260 return ret; 1261 } 1262 EXPORT_SYMBOL(hdmi_infoframe_unpack); 1263