diff options
author | Hans Verkuil <hverkuil-cisco@xs4all.nl> | 2021-03-20 11:22:29 +0100 |
---|---|---|
committer | Hans Verkuil <hverkuil-cisco@xs4all.nl> | 2021-03-20 11:22:29 +0100 |
commit | 6cac3c2ff82a4cedf3ee5a5bc0c7be2291765494 (patch) | |
tree | 2aa12cf58f0c17e4274ab3f23619a9a56ea3e64d | |
parent | 3439c85d254774bd6debaedcfcb7fbab21d8a360 (diff) | |
download | v4l-utils-6cac3c2ff82a4cedf3ee5a5bc0c7be2291765494.tar.gz |
v4l2-ctl: add --show-edid, add new test EDIDs
Add a new --show-edid option that dumps the EDID you would write
with --set-edid.
Updated existing EDIDs (fixing small edid-decode conformity warnings)
and add new EDIDs for displayport and 3 and 4 block EDIDs.
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
-rw-r--r-- | utils/v4l2-ctl/v4l2-ctl-edid.cpp | 273 | ||||
-rw-r--r-- | utils/v4l2-ctl/v4l2-ctl.cpp | 1 | ||||
-rw-r--r-- | utils/v4l2-ctl/v4l2-ctl.h | 1 |
3 files changed, 236 insertions, 39 deletions
diff --git a/utils/v4l2-ctl/v4l2-ctl-edid.cpp b/utils/v4l2-ctl/v4l2-ctl-edid.cpp index 9f7f6007..f27613fc 100644 --- a/utils/v4l2-ctl/v4l2-ctl-edid.cpp +++ b/utils/v4l2-ctl/v4l2-ctl-edid.cpp @@ -119,8 +119,10 @@ void edid_usage() { printf("\nEDID options:\n" " --set-edid pad=<pad>[,type=<type>|file=<file>][,format=<fmt>][modifiers]\n" - " <pad> is the input or output index for which to set the EDID.\n" + " <pad> is the input index for which to set the EDID.\n" " <type> can be 'hdmi', 'hdmi-4k-170mhz', 'hdmi-4k-300mhz', 'hdmi-4k-600mhz',\n" + " 'hdmi-4k-600mhz-with-displayid', 'displayport', 'displayport-with-cta861',\n" + " 'dvid' or 'vga'. A predefined EDID suitable for that connector type will be\n" " 'dvid' or 'vga'. A predefined EDID suitable for that connector type will be\n" " set. It has a 1920x1080p60 native resolution for the non-4k variants and a\n" " 3840x2160 resolution for the 4k variants (4kp30 YCbCr 4:2:0 for 170mhz, 4kp30\n" @@ -200,9 +202,12 @@ void edid_usage() " hdr: toggle the Traditional gamma HDR bit.\n" " smpte2084: toggle the SMPTE ST 2084 bit.\n" " hlg: toggle the Hybrid Log-Gamma bit.\n" - " --clear-edid <pad> clear the EDID for the input or output index <pad>.\n" + " --clear-edid <pad> clear the EDID for the input index <pad>.\n" " --info-edid <pad> print the current EDID's modifiers\n" " <pad> is the input or output index for which to get the EDID.\n" + " --show-edid [type=<type>|file=<file>][,format=<fmt>][modifiers]\n" + " Same as --set-edid, but only dumps the resulting EDID in hex\n" + " instead of actually setting the EDID.\n" " --get-edid pad=<pad>,startblock=<startblock>,blocks=<blocks>,format=<fmt>,file=<file>\n" " <pad> is the input or output index for which to get the EDID.\n" " <startblock> is the first block number you want to read. Default 0.\n" @@ -378,24 +383,31 @@ static void printedid(FILE *f, struct v4l2_edid *e, enum format gf) } } +static unsigned find_cta_offset(const unsigned char *edid, unsigned size) +{ + for (unsigned i = 1; i < size / 128; i++) + if (edid[i * 128] == 0x02) + return i * 128; + return 0; +} + static int get_edid_tag_location(const unsigned char *edid, unsigned size, unsigned char want_tag, __u32 ext_tag) { + unsigned offset = find_cta_offset(edid, size); unsigned char d; - if (size < 256) - return -1; - - if (edid[0x7e] != 1 || edid[0x80] != 0x02 || edid[0x81] != 0x03) + if (!offset) return -1; + edid += offset; /* search tag */ - d = edid[0x82] & 0x7f; + d = edid[0x02] & 0x7f; if (d <= 4) return -1; - int i = 0x84; - int end = 0x80 + d; + int i = 0x04; + int end = 0x00 + d; do { unsigned char tag = edid[i] >> 5; @@ -414,14 +426,14 @@ static int get_edid_tag_location(const unsigned char *edid, unsigned size, edid[i + 1] == (ext_tag & 0xff) && edid[i + 2] == ((ext_tag >> 8) & 0xff) && edid[i + 3] == ((ext_tag >> 16) & 0xff)) - return i; + return offset + i; /* * Tag 7 has an extended tag, others (0-2, 4-6) * have no identifiers. */ if ((tag < EXTENDED_TAG && tag != VSDB_TAG) || (tag == EXTENDED_TAG && len >= 1 && edid[i + 1] == ext_tag)) - return i; + return offset + i; i += len + 1; } while (i < end); return -1; @@ -429,13 +441,9 @@ static int get_edid_tag_location(const unsigned char *edid, unsigned size, static int get_edid_cta861_hdr_location(const unsigned char *edid, unsigned size) { - if (size < 256) - return -1; + unsigned offset = find_cta_offset(edid, size); - if (edid[0x7e] != 1 || edid[0x80] != 0x02 || edid[0x81] != 0x03) - return -1; - - return 0x83; + return offset ? offset + 3 : -1; } static int get_edid_spa_location(const unsigned char *edid, unsigned size) @@ -764,20 +772,20 @@ static uint8_t hdmi_edid[256] = { 0x45, 0x59, 0x81, 0x80, 0x81, 0x40, 0x90, 0x40, 0x95, 0x00, 0xa9, 0x40, 0xb3, 0x00, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c, - 0x45, 0x00, 0xe0, 0x0e, 0x11, 0x00, 0x00, 0x1e, + 0x46, 0x00, 0xe0, 0x0e, 0x11, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x55, 0x18, 0x5e, 0x11, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x68, 0x64, 0x6d, 0x69, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc4, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc3, 0x02, 0x03, 0x2d, 0xf1, 0x4c, 0x10, 0x1f, 0x04, 0x13, 0x22, 0x21, 0x20, 0x05, 0x14, 0x02, 0x11, 0x01, 0x23, 0x09, 0x07, 0x07, 0x83, 0x01, 0x00, 0x00, 0x68, 0x03, 0x0c, 0x00, 0x10, 0x00, 0x00, - 0x22, 0x01, 0xe2, 0x00, 0xea, 0xe3, 0x05, 0x00, + 0x22, 0x01, 0xe2, 0x00, 0xca, 0xe3, 0x05, 0x00, 0x00, 0xe3, 0x06, 0x01, 0x00, 0x1a, 0x36, 0x80, 0xa0, 0x70, 0x38, 0x1f, 0x40, 0x30, 0x20, 0x35, 0x00, 0xe0, 0x0e, 0x11, 0x00, 0x00, 0x1a, 0x1a, @@ -788,7 +796,7 @@ static uint8_t hdmi_edid[256] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, }; static uint8_t hdmi_edid_4k_170[256] = { @@ -813,7 +821,7 @@ static uint8_t hdmi_edid_4k_170[256] = { 0x13, 0x22, 0x21, 0x20, 0x05, 0x14, 0x02, 0x11, 0x01, 0x23, 0x09, 0x07, 0x07, 0x83, 0x01, 0x00, 0x00, 0x68, 0x03, 0x0c, 0x00, 0x10, 0x00, 0x00, - 0x22, 0x01, 0xe2, 0x00, 0xea, 0xe4, 0x0e, 0x5f, + 0x22, 0x01, 0xe2, 0x00, 0xca, 0xe4, 0x0e, 0x5f, 0x5e, 0x5d, 0xe3, 0x05, 0x00, 0x00, 0xe3, 0x06, 0x01, 0x00, 0x1a, 0x36, 0x80, 0xa0, 0x70, 0x38, 0x1f, 0x40, 0x30, 0x20, 0x35, 0x00, 0xc0, 0x1c, @@ -824,7 +832,7 @@ static uint8_t hdmi_edid_4k_170[256] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, }; static uint8_t hdmi_edid_4k_300[256] = { @@ -851,7 +859,7 @@ static uint8_t hdmi_edid_4k_300[256] = { 0x83, 0x01, 0x00, 0x00, 0x6d, 0x03, 0x0c, 0x00, 0x10, 0x00, 0x00, 0x3c, 0x21, 0x00, 0x60, 0x01, 0x02, 0x03, 0x67, 0xd8, 0x5d, 0xc4, 0x01, 0x00, - 0x00, 0x00, 0xe2, 0x00, 0xea, 0xe3, 0x05, 0x00, + 0x00, 0x00, 0xe2, 0x00, 0xca, 0xe3, 0x05, 0x00, 0x00, 0xe3, 0x06, 0x01, 0x00, 0xa3, 0x66, 0x00, 0xa0, 0xf0, 0x70, 0x1f, 0x80, 0x30, 0x20, 0x35, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, 0x1e, 0x1a, @@ -860,7 +868,7 @@ static uint8_t hdmi_edid_4k_300[256] = { 0x1a, 0x1a, 0x1d, 0x00, 0x80, 0x51, 0xd0, 0x1c, 0x20, 0x40, 0x80, 0x35, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd2, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, }; static uint8_t hdmi_edid_4k_600[256] = { @@ -887,7 +895,60 @@ static uint8_t hdmi_edid_4k_600[256] = { 0x07, 0x07, 0x83, 0x01, 0x00, 0x00, 0x6d, 0x03, 0x0c, 0x00, 0x10, 0x00, 0x00, 0x3c, 0x21, 0x00, 0x60, 0x01, 0x02, 0x03, 0x67, 0xd8, 0x5d, 0xc4, - 0x01, 0x78, 0x00, 0x00, 0xe2, 0x00, 0xea, 0xe3, + 0x01, 0x78, 0x00, 0x00, 0xe2, 0x00, 0xca, 0xe3, + 0x05, 0x00, 0x00, 0xe3, 0x06, 0x01, 0x00, 0x4d, + 0xd0, 0x00, 0xa0, 0xf0, 0x70, 0x3e, 0x80, 0x30, + 0x20, 0x35, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, + 0x1e, 0x1a, 0x36, 0x80, 0xa0, 0x70, 0x38, 0x1f, + 0x40, 0x30, 0x20, 0x35, 0x00, 0xc0, 0x1c, 0x32, + 0x00, 0x00, 0x1a, 0x1a, 0x1d, 0x00, 0x80, 0x51, + 0xd0, 0x1c, 0x20, 0x40, 0x80, 0x35, 0x00, 0xc0, + 0x1c, 0x32, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, +}; + +static uint8_t hdmi_edid_4k_600_with_displayid[512] = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x31, 0xd8, 0x34, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x1a, 0x01, 0x03, 0x80, 0x60, 0x36, 0x78, + 0x0f, 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26, + 0x0f, 0x50, 0x54, 0x2f, 0xcf, 0x00, 0x31, 0x59, + 0x45, 0x59, 0x81, 0x80, 0x81, 0x40, 0x90, 0x40, + 0x95, 0x00, 0xa9, 0x40, 0xb3, 0x00, 0x08, 0xe8, + 0x00, 0x30, 0xf2, 0x70, 0x5a, 0x80, 0xb0, 0x58, + 0x8a, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, 0x1e, + 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x55, 0x18, + 0x87, 0x3c, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x68, + 0x64, 0x6d, 0x69, 0x20, 0x34, 0x2d, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x73, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe4, + + 0xf0, 0x02, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, + + 0x02, 0x03, 0x3f, 0xf1, 0x51, 0x61, 0x60, 0x5f, + 0x5e, 0x5d, 0x10, 0x1f, 0x04, 0x13, 0x22, 0x21, + 0x20, 0x05, 0x14, 0x02, 0x11, 0x01, 0x23, 0x09, + 0x07, 0x07, 0x83, 0x01, 0x00, 0x00, 0x6d, 0x03, + 0x0c, 0x00, 0x10, 0x00, 0x00, 0x3c, 0x21, 0x00, + 0x60, 0x01, 0x02, 0x03, 0x67, 0xd8, 0x5d, 0xc4, + 0x01, 0x78, 0x00, 0x00, 0xe2, 0x00, 0xca, 0xe3, 0x05, 0x00, 0x00, 0xe3, 0x06, 0x01, 0x00, 0x4d, 0xd0, 0x00, 0xa0, 0xf0, 0x70, 0x3e, 0x80, 0x30, 0x20, 0x35, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, @@ -896,7 +957,113 @@ static uint8_t hdmi_edid_4k_600[256] = { 0x00, 0x00, 0x1a, 0x1a, 0x1d, 0x00, 0x80, 0x51, 0xd0, 0x1c, 0x20, 0x40, 0x80, 0x35, 0x00, 0xc0, 0x1c, 0x32, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, + + 0x70, 0x12, 0x79, 0x03, 0x00, 0x00, 0x00, 0x1c, + 0x4c, 0x4e, 0x58, 0x34, 0x12, 0x56, 0x34, 0x12, + 0x00, 0x22, 0x10, 0x10, 0x48, 0x44, 0x4d, 0x49, + 0x20, 0x2b, 0x20, 0x44, 0x69, 0x73, 0x70, 0x6c, + 0x61, 0x79, 0x49, 0x44, 0x01, 0x00, 0x0c, 0x80, + 0x25, 0x18, 0x15, 0x00, 0x0f, 0x70, 0x08, 0x80, + 0x78, 0x4e, 0x77, 0x0f, 0x00, 0x0a, 0x71, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x01, 0x14, 0x07, 0xe8, 0x00, 0x80, 0xff, + 0x0e, 0x2f, 0x02, 0xaf, 0x80, 0x57, 0x00, 0x6f, + 0x08, 0x59, 0x00, 0x07, 0x80, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x90, +}; + +static uint8_t displayport_edid[256] = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x31, 0xd8, 0x34, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x1a, 0x01, 0x04, 0xa1, 0x30, 0x1e, 0x78, + 0x07, 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26, + 0x0f, 0x50, 0x54, 0x2f, 0xcf, 0x00, 0x31, 0x59, + 0x45, 0x59, 0x81, 0x80, 0x81, 0x40, 0x90, 0x40, + 0x95, 0x00, 0xa9, 0x40, 0xb3, 0x00, 0x28, 0x3c, + 0x80, 0xa0, 0x70, 0xb0, 0x23, 0x40, 0x30, 0x20, + 0x36, 0x00, 0xe0, 0x2c, 0x11, 0x00, 0x00, 0x1a, + 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x55, 0x18, + 0x5e, 0x11, 0x04, 0x12, 0x00, 0xf0, 0xf8, 0x58, + 0xf0, 0x3c, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x64, + 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x70, 0x6f, + 0x72, 0x74, 0x0a, 0x20, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc2, + + 0x70, 0x12, 0x79, 0x03, 0x00, 0x00, 0x00, 0x17, + 0x4c, 0x4e, 0x58, 0x34, 0x12, 0x56, 0x34, 0x12, + 0x00, 0x22, 0x10, 0x0b, 0x44, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x50, 0x6f, 0x72, 0x74, 0x01, + 0x00, 0x0c, 0xc0, 0x12, 0xb8, 0x0b, 0x80, 0x07, + 0xb0, 0x04, 0x10, 0x78, 0x3c, 0x77, 0x0f, 0x00, + 0x0a, 0xa4, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x45, 0x00, 0x00, 0x03, 0x01, 0x14, 0x27, 0x3c, + 0x00, 0x80, 0x7f, 0x07, 0x9f, 0x00, 0x2f, 0x80, + 0x1f, 0x00, 0xaf, 0x04, 0x22, 0x00, 0x02, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9, 0x90, +}; + +static uint8_t displayport_edid_with_cta861[384] = { + 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x31, 0xd8, 0x34, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x22, 0x1a, 0x01, 0x04, 0xa5, 0x30, 0x1b, 0x78, + 0x0f, 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26, + 0x0f, 0x50, 0x54, 0x2f, 0xcf, 0x00, 0x31, 0x59, + 0x45, 0x59, 0x81, 0x80, 0x81, 0x40, 0x90, 0x40, + 0x95, 0x00, 0xa9, 0x40, 0xb3, 0x00, 0x02, 0x3a, + 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c, + 0x45, 0x00, 0xe0, 0x0e, 0x11, 0x00, 0x00, 0x1e, + 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18, 0x55, 0x18, + 0x5e, 0x11, 0x04, 0x12, 0x04, 0xf0, 0xf8, 0x38, + 0xf0, 0x3c, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x44, + 0x50, 0x2b, 0x43, 0x54, 0x41, 0x38, 0x36, 0x31, + 0x0a, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0d, + + 0x02, 0x03, 0x24, 0xf1, 0x4c, 0x10, 0x1f, 0x04, + 0x13, 0x22, 0x21, 0x20, 0x05, 0x14, 0x02, 0x11, + 0x01, 0x23, 0x09, 0x07, 0x07, 0x83, 0x01, 0x00, + 0x00, 0xe2, 0x00, 0xca, 0xe3, 0x05, 0x00, 0x00, + 0xe3, 0x06, 0x01, 0x00, 0x1a, 0x36, 0x80, 0xa0, + 0x70, 0x38, 0x1f, 0x40, 0x30, 0x20, 0x35, 0x00, + 0xe0, 0x0e, 0x11, 0x00, 0x00, 0x1a, 0x1a, 0x1d, + 0x00, 0x80, 0x51, 0xd0, 0x1c, 0x20, 0x40, 0x80, + 0x35, 0x00, 0xe0, 0x0e, 0x11, 0x00, 0x00, 0x1c, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, + + 0x70, 0x12, 0x79, 0x03, 0x00, 0x00, 0x00, 0x24, + 0x4c, 0x4e, 0x58, 0x34, 0x12, 0x56, 0x34, 0x12, + 0x00, 0x22, 0x10, 0x18, 0x44, 0x69, 0x73, 0x70, + 0x6c, 0x61, 0x79, 0x50, 0x6f, 0x72, 0x74, 0x20, + 0x77, 0x69, 0x74, 0x68, 0x20, 0x43, 0x54, 0x41, + 0x2d, 0x38, 0x36, 0x31, 0x0f, 0x00, 0x0a, 0xa4, + 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x0c, 0xc0, 0x12, 0x8c, 0x0a, + 0x80, 0x07, 0x38, 0x04, 0x90, 0x78, 0x4e, 0x77, + 0x03, 0x01, 0x14, 0x01, 0x3a, 0x00, 0x80, 0x7f, + 0x07, 0x17, 0x01, 0x57, 0x80, 0x2b, 0x00, 0x37, + 0x04, 0x2c, 0x00, 0x03, 0x80, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x90, }; /******************************************************/ @@ -907,6 +1074,7 @@ void edid_cmd(int ch, char *optarg) switch (ch) { case OptSetEdid: + case OptShowEdid: memset(&sedid, 0, sizeof(sedid)); file_in = nullptr; if (!optarg) @@ -988,9 +1156,6 @@ void edid_cmd(int ch, char *optarg) std::exit(EXIT_FAILURE); } switch (opt) { - case 0: - sedid.pad = strtoul(value, nullptr, 0); - break; case 1: case 2: /* keep edid for compat reasons, it's the same as type */ if (!strcmp(value, "dvid")) { @@ -1001,16 +1166,25 @@ void edid_cmd(int ch, char *optarg) sedid.blocks = sizeof(vga_edid) / 128; } else if (!strcmp(value, "hdmi-4k-170mhz")) { sedid.edid = hdmi_edid_4k_170; - sedid.blocks = sizeof(hdmi_edid) / 128; + sedid.blocks = sizeof(hdmi_edid_4k_170) / 128; } else if (!strcmp(value, "hdmi-4k-300mhz")) { sedid.edid = hdmi_edid_4k_300; - sedid.blocks = sizeof(hdmi_edid) / 128; + sedid.blocks = sizeof(hdmi_edid_4k_300) / 128; + } else if (!strcmp(value, "hdmi-4k-600mhz-with-displayid")) { + sedid.edid = hdmi_edid_4k_600_with_displayid; + sedid.blocks = sizeof(hdmi_edid_4k_600_with_displayid) / 128; } else if (!strcmp(value, "hdmi-4k-600mhz")) { sedid.edid = hdmi_edid_4k_600; - sedid.blocks = sizeof(hdmi_edid) / 128; + sedid.blocks = sizeof(hdmi_edid_4k_600) / 128; } else if (!strcmp(value, "hdmi")) { sedid.edid = hdmi_edid; sedid.blocks = sizeof(hdmi_edid) / 128; + } else if (!strcmp(value, "displayport-with-cta861")) { + sedid.edid = displayport_edid_with_cta861; + sedid.blocks = sizeof(displayport_edid_with_cta861) / 128; + } else if (!strcmp(value, "displayport")) { + sedid.edid = displayport_edid; + sedid.blocks = sizeof(displayport_edid) / 128; } else { edid_usage(); std::exit(EXIT_FAILURE); @@ -1100,9 +1274,15 @@ void edid_cmd(int ch, char *optarg) case 54: toggle_speaker3_flags |= SPEAKER3_BTFC; break; case 55: toggle_speaker3_flags |= SPEAKER3_BTFL_BTFR; break; case 56: toggle_speaker3_flags |= SPEAKER3_TPLS_TPRS; break; + case 0: + if (ch == OptSetEdid) { + sedid.pad = strtoul(value, nullptr, 0); + break; + } + // fall through default: - edid_usage(); - std::exit(EXIT_FAILURE); + edid_usage(); + std::exit(EXIT_FAILURE); } } break; @@ -1190,7 +1370,7 @@ void edid_set(cv4l_fd &_fd) doioctl(fd, VIDIOC_S_EDID, &edid); } - if (options[OptSetEdid]) { + if (options[OptSetEdid] || options[OptShowEdid]) { FILE *fin = nullptr; bool must_fix_edid = options[OptFixEdidChecksums]; @@ -1291,11 +1471,26 @@ void edid_set(cv4l_fd &_fd) } if (must_fix_edid) fix_edid(&sedid); - print_edid_mods(&sedid); - if (verify_edid(&sedid)) + if (verbose && options[OptSetEdid]) + print_edid_mods(&sedid); + if (options[OptShowEdid]) { + for (unsigned b = 0; b < sedid.blocks; b++) { + if (b) + printf("\n"); + for (unsigned i = 0; i < 128; i += 16) { + for (unsigned j = i; j < i + 16; j++) { + if (j > i) + printf(" "); + printf("%02x", sedid.edid[b * 128 + j]); + } + printf("\n"); + } + } + } else if (verify_edid(&sedid)) { doioctl(fd, VIDIOC_S_EDID, &sedid); - else + } else { fprintf(stderr, "EDID not set due to checksum errors\n"); + } if (fin) { if (sedid.edid) { free(sedid.edid); diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp index 9b70be56..d91577e1 100644 --- a/utils/v4l2-ctl/v4l2-ctl.cpp +++ b/utils/v4l2-ctl/v4l2-ctl.cpp @@ -217,6 +217,7 @@ static struct option long_options[] = { {"clear-edid", optional_argument, nullptr, OptClearEdid}, {"get-edid", optional_argument, nullptr, OptGetEdid}, {"info-edid", optional_argument, nullptr, OptInfoEdid}, + {"show-edid", required_argument, nullptr, OptShowEdid}, {"fix-edid-checksums", no_argument, nullptr, OptFixEdidChecksums}, {"tuner-index", required_argument, nullptr, OptTunerIndex}, {"list-buffers", no_argument, nullptr, OptListBuffers}, diff --git a/utils/v4l2-ctl/v4l2-ctl.h b/utils/v4l2-ctl/v4l2-ctl.h index 74cf7c83..f9bad45c 100644 --- a/utils/v4l2-ctl/v4l2-ctl.h +++ b/utils/v4l2-ctl/v4l2-ctl.h @@ -194,6 +194,7 @@ enum Option { OptClearEdid, OptGetEdid, OptInfoEdid, + OptShowEdid, OptFixEdidChecksums, OptFreqSeek, OptEncoderCmd, |