Codebase list edid-decode / 77700d6
edid-decode: add support for DisplayID data blocks 0x0d and 0x0f Support Interface Power Sequencing and Display Interface. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Hans Verkuil 4 years ago
1 changed file(s) with 129 addition(s) and 27 deletion(s). Raw diff Collapse all Expand all
1010
1111 #include "edid-decode.h"
1212
13 static const char *bpc444[] = {"6", "8", "10", "12", "14", "16", NULL, NULL};
14 static const char *bpc4xx[] = {"8", "10", "12", "14", "16", NULL, NULL, NULL};
15 static const char *audiorates[] = {"32", "44.1", "48", NULL, NULL, NULL, NULL, NULL};
16
1317 // misc functions
18
19 static void print_flags(const char *label, unsigned char flag_byte,
20 const char **flags, bool reverse = false)
21 {
22 if (!flag_byte)
23 return;
24
25 unsigned countflags = 0;
26
27 printf("%s: ", label);
28 for (unsigned i = 0; i < 8; i++) {
29 if (flag_byte & (1 << (reverse ? 7 - i : i))) {
30 if (countflags)
31 printf(", ");
32 if (flags[i])
33 printf("%s", flags[i]);
34 else
35 printf("Undefined (%u)", i);
36 countflags++;
37 }
38 }
39 printf("\n");
40 }
1441
1542 static void check_displayid_datablock_revision(const unsigned char *x)
1643 {
535562 v = x[0x0f];
536563 printf(" Response time for %s transition: %u ms\n",
537564 (v & 0x80) ? "white-to-black" : "black-to-white", v & 0x7f);
565 }
566
567 // tag 0x0d
568
569 static void parse_displayid_intf_power_sequencing(const unsigned char *x)
570 {
571 check_displayid_datablock_revision(x);
572
573 if (!check_displayid_datablock_length(x, 6, 6))
574 return;
575
576 printf(" Power Sequence T1: %.1f-%u.0 ms\n", (x[3] >> 4) / 10.0, (x[3] & 0xf) * 2);
577 printf(" Power Sequence T2: 0.0-%u.0 ms\n", (x[4] & 0x3f) * 2);
578 printf(" Power Sequence T3: 0.0-%u.0 ms\n", (x[5] & 0x3f) * 2);
579 printf(" Power Sequence T4: 0.0-%u.0 ms\n", (x[6] & 0x7f) * 10);
580 printf(" Power Sequence T5: 0.0-%u.0 ms\n", (x[7] & 0x3f) * 10);
581 printf(" Power Sequence T6: 0.0-%u.0 ms\n", (x[8] & 0x3f) * 10);
538582 }
539583
540584 // tag 0x0e
579623 }
580624 offset += samples;
581625 len -= samples;
626 }
627 }
628
629 // tag 0x0f
630
631 static void parse_displayid_display_intf(const unsigned char *x)
632 {
633 check_displayid_datablock_revision(x);
634
635 if (!check_displayid_datablock_length(x, 10, 10))
636 return;
637
638 printf(" Interface Type: ");
639 switch (x[3] >> 4) {
640 case 0x00:
641 switch (x[3] & 0xf) {
642 case 0x00: printf("Analog 15HD/VGA\n"); break;
643 case 0x01: printf("Analog VESA NAVI-V (15HD)\n"); break;
644 case 0x02: printf("Analog VESA NAVI-D\n"); break;
645 default: printf("Reserved\n"); break;
646 }
647 break;
648 case 0x01: printf("LVDS\n"); break;
649 case 0x02: printf("TMDS\n"); break;
650 case 0x03: printf("RSDS\n"); break;
651 case 0x04: printf("DVI-D\n"); break;
652 case 0x05: printf("DVI-I, analog\n"); break;
653 case 0x06: printf("DVI-I, digital\n"); break;
654 case 0x07: printf("HDMI-A\n"); break;
655 case 0x08: printf("HDMI-B\n"); break;
656 case 0x09: printf("MDDI\n"); break;
657 case 0x0a: printf("DisplayPort\n"); break;
658 case 0x0b: printf("Proprietary Digital Interface\n"); break;
659 default: printf("Reserved\n"); break;
660 }
661 if (x[3] >> 4)
662 printf(" Number of Links: %u\n", x[3] & 0xf);
663 printf(" Interface Standard Version: %u.%u\n",
664 x[4] >> 4, x[4] & 0xf);
665 print_flags(" Supported bpc for RGB encoding", x[5], bpc444);
666 print_flags(" Supported bpc for YCbCr 4:4:4 encoding", x[6], bpc444);
667 print_flags(" Supported bpc for YCbCr 4:2:2 encoding", x[7], bpc4xx);
668 printf(" Supported Content Protection: ");
669 switch (x[8] & 0xf) {
670 case 0x00: printf("None\n"); break;
671 case 0x01: printf("HDCP "); break;
672 case 0x02: printf("DTCP "); break;
673 case 0x03: printf("DPCP "); break;
674 default: printf("Reserved "); break;
675 }
676 if (x[8] & 0xf)
677 printf("%u.%u\n", x[9] >> 4, x[9] & 0xf);
678 unsigned char v = x[0x0a] & 0xf;
679 printf(" Spread Spectrum: ");
680 switch (x[0x0a] >> 6) {
681 case 0x00: printf("None\n"); break;
682 case 0x01: printf("Down Spread %.1f%%\n", v / 10.0); break;
683 case 0x02: printf("Center Spread %.1f%%\n", v / 10.0); break;
684 case 0x03: printf("Reserved\n"); break;
685 }
686 switch (x[3] >> 4) {
687 case 0x01:
688 printf(" LVDS Color Mapping: %s mode\n",
689 (x[0x0b] & 0x10) ? "6 bit compatible" : "normal");
690 if (x[0x0b] & 0x08) printf(" LVDS supports 2.8V\n");
691 if (x[0x0b] & 0x04) printf(" LVDS supports 12V\n");
692 if (x[0x0b] & 0x02) printf(" LVDS supports 5V\n");
693 if (x[0x0b] & 0x01) printf(" LVDS supports 3.3V\n");
694 printf(" LVDS %s Mode\n", (x[0x0c] & 0x04) ? "Fixed" : "DE");
695 if (x[0x0c] & 0x04)
696 printf(" LVDS %s Signal Level\n", (x[0x0c] & 0x02) ? "Low" : "High");
697 else
698 printf(" LVDS DE Polarity Active %s\n", (x[0x0c] & 0x02) ? "Low" : "High");
699 printf(" LVDS Shift Clock Data Strobe at %s Edge\n", (x[0x0c] & 0x01) ? "Rising" : "Falling");
700 break;
701 case 0x0b:
702 printf(" PDI %s Mode\n", (x[0x0b] & 0x04) ? "Fixed" : "DE");
703 if (x[0x0b] & 0x04)
704 printf(" PDI %s Signal Level\n", (x[0x0b] & 0x02) ? "Low" : "High");
705 else
706 printf(" PDI DE Polarity Active %s\n", (x[0x0b] & 0x02) ? "Low" : "High");
707 printf(" PDI Shift Clock Data Strobe at %s Edge\n", (x[0x0b] & 0x01) ? "Rising" : "Falling");
708 break;
582709 }
583710 }
584711
769896
770897 // tag 0x26
771898
772 static const char *bpc444[] = {"6", "8", "10", "12", "14", "16", NULL, NULL};
773 static const char *bpc4xx[] = {"8", "10", "12", "14", "16", NULL, NULL, NULL};
774 static const char *audiorates[] = {"32", "44.1", "48", NULL, NULL, NULL, NULL, NULL};
775
776899 static const char *colorspace_eotf_combinations[] = {
777900 "sRGB",
778901 "BT.601",
809932 "Hybrid Log",
810933 "Custom"
811934 };
812
813 static void print_flags(const char *label, unsigned char flag_byte,
814 const char **flags, bool reverse = false)
815 {
816 if (!flag_byte)
817 return;
818
819 unsigned countflags = 0;
820
821 printf("%s: ", label);
822 for (unsigned i = 0; i < 8; i++) {
823 if (flag_byte & (1 << (reverse ? 7 - i : i))) {
824 if (countflags)
825 printf(", ");
826 if (flags[i])
827 printf("%s", flags[i]);
828 else
829 printf("Undefined (%u)", i);
830 countflags++;
831 }
832 }
833 printf("\n");
834 }
835935
836936 static void parse_displayid_interface_features(const unsigned char *x)
837937 {
11161216 case 0x0a:
11171217 case 0x0b: parse_displayid_string(x + offset); break;
11181218 case 0x0c: parse_displayid_display_device(x + offset); break;
1219 case 0x0d: parse_displayid_intf_power_sequencing(x + offset); break;
11191220 case 0x0e: parse_displayid_transfer_characteristics(x + offset); break;
1221 case 0x0f: parse_displayid_display_intf(x + offset); break;
11201222 case 0x11:
11211223 for (i = 0; i < len / 7; i++)
11221224 parse_displayid_type_5_timing(&x[offset + 3 + (i * 7)]);