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