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