This is an automatic generated email to let you know that the following patch 
were queued at the 
http://git.linuxtv.org/cgit.cgi/v4l-utils.git tree:

Subject: edid-decode: add SCDC read and parse code
Author:  Hans Verkuil <[email protected]>
Date:    Mon May 11 08:18:19 2026 +0200

This allows you to read the SCDC data from the DDC line and to
parse that data.

Signed-off-by: Hans Verkuil <[email protected]>

 utils/edid-decode/ddc.cpp          |  57 +++++++++++
 utils/edid-decode/edid-decode.1.in |  11 ++-
 utils/edid-decode/edid-decode.cpp  | 104 +++++++++++++++++++-
 utils/edid-decode/edid-decode.h    |   5 +
 utils/edid-decode/meson.build      |   3 +-
 utils/edid-decode/parse-scdc.cpp   | 196 +++++++++++++++++++++++++++++++++++++
 6 files changed, 371 insertions(+), 5 deletions(-)

---

http://git.linuxtv.org/cgit.cgi/v4l-utils.git/commit/?id=3ab9884b6846b9f8555d804a051e8148d0870388
diff --git a/utils/edid-decode/ddc.cpp b/utils/edid-decode/ddc.cpp
index a74e884a4706..26db094d2ef1 100644
--- a/utils/edid-decode/ddc.cpp
+++ b/utils/edid-decode/ddc.cpp
@@ -41,6 +41,9 @@
 #define EDID_ADDR 0x50
 #define SEGMENT_POINTER_ADDR 0x30
 
+// i2c address for SCDC
+#define SCDC_ADDR 0x54
+
 // i2c addresses for HDCP
 #define HDCP_PRIM_ADDR 0x3a
 #define HDCP_SEC_ADDR 0x3b
@@ -417,3 +420,57 @@ int read_hdcp_ri(int adapter_fd, double ri_time)
        }
        return 0;
 }
+
+static int read_scdc_registers(int adapter_fd, __u8 *scdc, bool update_only)
+{
+       struct i2c_rdwr_ioctl_data data;
+       struct i2c_msg write_message;
+       struct i2c_msg read_message;
+       __u8 offset = update_only ? 0x10 : 0;
+       int err;
+
+       write_message = {
+               .addr = SCDC_ADDR,
+               .len = 1,
+               .buf = &offset
+       };
+       read_message = {
+               .addr = SCDC_ADDR,
+               .flags = I2C_M_RD,
+               .len = (__u16)(update_only ? 2 : 128),
+               .buf = scdc
+       };
+
+       struct i2c_msg msgs[2] = { write_message, read_message };
+
+       data.msgs = msgs + update_only;
+       data.nmsgs = ARRAY_SIZE(msgs) - update_only;
+       err = ioctl(adapter_fd, I2C_RDWR, &data);
+
+       if (err < 0) {
+               fprintf(stderr, "Unable to read SCDC %02x-%02x: %s\n",
+                       offset, offset + read_message.len - 1, strerror(errno));
+               return -1;
+       }
+       if (update_only)
+               return 0;
+       offset = 128;
+       data.msgs[1].buf = scdc + 128;
+       err = ioctl(adapter_fd, I2C_RDWR, &data);
+
+       if (err < 0) {
+               fprintf(stderr, "Unable to read SCDC %02x-%02x: %s\n",
+                       offset, offset + read_message.len - 1, strerror(errno));
+               return -1;
+       }
+       return 0;
+}
+
+int read_scdc(int adapter_fd, parse_data &pdata, bool update_only)
+{
+       if (read_scdc_registers(adapter_fd, pdata.buf, update_only))
+               return -1;
+
+       pdata.buf_size = update_only ? 2 : 256;
+       return 0;
+}
diff --git a/utils/edid-decode/edid-decode.1.in 
b/utils/edid-decode/edid-decode.1.in
index 9b93b1a8f3a1..3bbcdd0f97f6 100644
--- a/utils/edid-decode/edid-decode.1.in
+++ b/utils/edid-decode/edid-decode.1.in
@@ -131,7 +131,7 @@ DDDB: VESA Display Device Data Block (DDDB) Standard, 
Version 1
 .TP
 HDMI 1.4b: High-Definition Multimedia Interface, Version 1.4b
 .TP
-HDMI 2.1b: High-Definition Multimedia Interface, Version 2.1b
+HDMI 2.2: High-Definition Multimedia Interface, Version 2.2
 .TP
 HDCP 1.4: High-bandwidth Digital Content Protection System, Revision 1.4
 .TP
@@ -238,6 +238,9 @@ On Linux systems ELD can be extracted via the amixer 
command (copy all hex after
     
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
 
+.TP
+\fB\-D\fR, \fB\-\-scdc\fR \fI<file>\fR
+Parse the given SCDC file. Read data from stdin if '-' was passed as argument.
 .TP
 \fB\-J\fR, \fB\-\-hdcp\fR \fI<file>\fR
 Parse the given HDCP file. Read data from stdin if '-' was passed as argument.
@@ -341,6 +344,12 @@ Read and parse the HDCP data from the i2c adapter.
 \fB\-\-i2c\-hdcp-ri\fR \fI<t>\fR
 Every \fI<t>\fR seconds read and report the HDCP Ri value from the i2c adapter.
 .TP
+\fB\-\-i2c\-scdc\fR
+Read and parse the SCDC data from the i2c adapter.
+.TP
+\fB\-\-i2c\-scdc\-update\fR
+Read and parse the SCDC Update Flags from the i2c adapter.
+.TP
 \fB\-\-i2c\-test\-reliability\fR 
[\fBduration\fR=\fI<secs>\fR][,\fBsleep\fR=\fI<msecs>\fR]
 Read the EDID continuously for \fI<secs>\fR seconds (default is 0, meaning 
forever),
 with a sleep of \fI<msecs>\fR milliseconds (default value is 50 ms) in between
diff --git a/utils/edid-decode/edid-decode.cpp 
b/utils/edid-decode/edid-decode.cpp
index 00092f2108b0..d9fc7b37cd82 100644
--- a/utils/edid-decode/edid-decode.cpp
+++ b/utils/edid-decode/edid-decode.cpp
@@ -44,6 +44,7 @@ enum Option {
        OptBlockHexDump = 'b',
        OptCheck = 'c',
        OptCheckInline = 'C',
+       OptSCDC = 'D',
        OptEld = 'E',
        OptFBModeTimings = 'F',
        OptHelp = 'h',
@@ -67,6 +68,8 @@ enum Option {
        OptVersion,
        OptDiag,
        OptI2CEDID,
+       OptI2CSCDC,
+       OptI2CSCDCUpdate,
        OptI2CHDCP,
        OptI2CHDCPRi,
        OptI2CTestReliability,
@@ -115,6 +118,8 @@ static struct option long_options[] = {
 #ifdef __HAS_I2C_DEV__
        { "i2c-adapter", required_argument, 0, OptI2CAdapter },
        { "i2c-edid", no_argument, 0, OptI2CEDID },
+       { "i2c-scdc-update", no_argument, 0, OptI2CSCDCUpdate },
+       { "i2c-scdc", no_argument, 0, OptI2CSCDC },
        { "i2c-hdcp", no_argument, 0, OptI2CHDCP },
        { "i2c-hdcp-ri", required_argument, 0, OptI2CHDCPRi },
        { "i2c-test-reliability", optional_argument, 0, OptI2CTestReliability },
@@ -134,6 +139,7 @@ static struct option long_options[] = {
        { "list-rids", no_argument, 0, OptListRIDs },
        { "infoframe", required_argument, 0, OptInfoFrame },
        { "eld", required_argument, 0, OptEld },
+       { "scdc", required_argument, 0, OptSCDC },
        { "hdcp", required_argument, 0, OptHDCP },
        { 0, 0, 0, 0 }
 };
@@ -180,6 +186,8 @@ static void usage(void)
               "  -a, --i2c-adapter <dev> Use <dev> to access the DDC lines.\n"
               "                        If <dev> starts with a digit, then 
/dev/i2c-<dev> is used.\n"
               "  --i2c-edid            Read the EDID from the DDC lines.\n"
+              "  --i2c-scdc            Read the SCDC from the DDC lines.\n"
+              "  --i2c-scdc-update     Read the SCDC Update information (bytes 
0x10-0x11) from the DDC lines.\n"
               "  --i2c-hdcp            Read the HDCP from the DDC lines.\n"
               "  --i2c-hdcp-ri=<t>     Read and print the HDCP Ri information 
every <t> seconds.\n"
               "  --i2c-test-reliability [duration=<secs>][,sleep=<msecs>]\n"
@@ -232,9 +240,9 @@ static void usage(void)
               "  --list-rids           List all known RIDs.\n"
               "  --list-rid-timings <rid> List all timings for RID <rid> or 
all known RIDs if <rid> is 0.\n"
               "  -I, --infoframe <file> Parse the InfoFrame from <file> (or 
stdin if '-' was specified) that was sent to this display.\n"
-              "                        This option can be specified multiple 
times for different InfoFrame files.\n"
               "  -E, --eld <file>      Parse the EDID-Like Data, ELD from 
<file> (or stdin if '-' was specified).\n"
               "                        This option can be specified multiple 
times for different ELD files.\n"
+              "  -D, --scdc <file>     Parse the SCDC data from <file> (or 
stdin if '-' was specified).\n"
               "  -J, --hdcp <file>     Parse the HDCP data from <file> (or 
stdin if '-' was specified).\n"
               "  -h, --help            Display this help message.\n");
 }
@@ -1663,7 +1671,7 @@ int edid_state::parse_edid()
        return failures ? -2 : 0;
 }
 
-/* InfoFrame/HDCP/ELD parsing */
+/* InfoFrame/ELD/SCDC/HDCP parsing */
 
 static unsigned char infoframe[32];
 
@@ -1683,6 +1691,15 @@ static struct parse_data eld_pdata = {
        0
 };
 
+static unsigned char scdc[256];
+
+static struct parse_data scdc_pdata = {
+       "SCDC",
+       scdc,
+       sizeof(scdc),
+       0
+};
+
 // primary data, KSV FIFO data, and secondary data
 static unsigned char hdcp[256 + 128 * 5 + 256];
 
@@ -1988,6 +2005,58 @@ int edid_state::parse_eld_file(const std::string &fname)
        return failures ? -2 : 0;
 }
 
+int edid_state::parse_scdc_pdata(parse_data &pdata)
+{
+       state.block_nr = 0;
+       state.data_block.clear();
+
+       if (!options[OptSkipHexDump]) {
+               printf("edid-decode %s (hex):\n\n", pdata.name);
+               if (pdata.buf_size == 2) {
+                       hex_block("", pdata.buf, pdata.buf_size, false);
+               } else {
+                       hex_block("", pdata.buf, 128, false);
+                       if (pdata.buf_size > 128) {
+                               printf("\n");
+                               hex_block("", pdata.buf + 128, pdata.buf_size - 
128, false);
+                       }
+               }
+               if (options[OptOnlyHexDump])
+                       return 0;
+               printf("\n----------------\n\n");
+       }
+
+       if (pdata.buf_size < 2) {
+               fail("%s is too small to parse.\n", pdata.name);
+               return -1;
+       }
+
+       parse_scdc(pdata.buf, pdata.buf_size == 2 ? 2 : (pdata.buf_size <= 128 
? 128 : 256));
+
+       if (!options[OptCheck] && !options[OptCheckInline])
+               return 0;
+
+       printf("\n----------------\n");
+
+       if (!options[OptSkipSHA] && strlen(STRING(SHA))) {
+               options[OptSkipSHA] = 1;
+               printf("\n");
+               print_version();
+       }
+
+       if (options[OptCheck]) {
+               if (warnings)
+                       show_data_msgs(pdata.name, true);
+               if (failures)
+                       show_data_msgs(pdata.name, false);
+       }
+
+       printf("\n%s conformity: %s\n",
+              state.data_block.empty() ? pdata.name : state.data_block.c_str(),
+              failures ? "FAIL" : "PASS");
+       return failures ? -2 : 0;
+}
+
 static int hdcp_from_file(parse_data &pdata, const char *from_file)
 {
        int ret = data_from_file(pdata, from_file);
@@ -2619,6 +2688,7 @@ int main(int argc, char **argv)
        double hdcp_ri_sleep = 0;
        std::vector<std::string> if_names;
        std::vector<std::string> eld_names;
+       std::string scdc_name;
        std::string hdcp_name;
        unsigned test_rel_duration = 0;
        unsigned test_rel_msleep = 50;
@@ -2773,6 +2843,9 @@ int main(int argc, char **argv)
                case OptInfoFrame:
                        if_names.push_back(optarg);
                        break;
+               case OptSCDC:
+                       scdc_name = optarg;
+                       break;
                case OptHDCP:
                        hdcp_name = optarg;
                        break;
@@ -2833,6 +2906,10 @@ int main(int argc, char **argv)
                                ret = 0;
                        }
                } else if (adapter_fd >= 0) {
+                       if (options[OptI2CSCDC])
+                               ret = read_scdc(adapter_fd, scdc_pdata, false);
+                       if (!ret && options[OptI2CSCDCUpdate])
+                               ret = read_scdc(adapter_fd, scdc_pdata, true);
                        if (!ret && options[OptI2CHDCP])
                                ret = read_hdcp(adapter_fd, hdcp_pdata);
                        if (!ret && options[OptI2CHDCPRi])
@@ -2840,7 +2917,8 @@ int main(int argc, char **argv)
                        if (options[OptI2CTestReliability])
                                ret = test_reliability(adapter_fd, 
test_rel_duration, test_rel_msleep);
                } else if ((options[OptInfoFrame] || options[OptEld] ||
-                           options[OptHDCP]) && !options[OptGTF]) {
+                           options[OptSCDC] || options[OptHDCP]) &&
+                          !options[OptGTF]) {
                        ret = 0;
                } else {
                        ret = edid_from_file("-", stdout);
@@ -2889,6 +2967,26 @@ int main(int argc, char **argv)
 
        bool show_line = state.edid_size;
 
+       if (scdc_name.length()) {
+               int r = data_from_file(scdc_pdata, scdc_name.c_str());
+               if (r && !ret)
+                       ret = r;
+       }
+       if (scdc_pdata.buf_size) {
+               if (show_line)
+                       printf("\n================\n\n");
+               show_line = true;
+
+               state.warnings = state.failures = 0;
+               for (unsigned i = 0; i < EDID_MAX_BLOCKS + 1; i++) {
+                       s_msgs[i][0].clear();
+                       s_msgs[i][1].clear();
+               }
+               int r = state.parse_scdc_pdata(scdc_pdata);
+               if (r && !ret)
+                       ret = r;
+       }
+
        if (hdcp_name.length()) {
                int r = hdcp_from_file(hdcp_pdata, hdcp_name.c_str());
                if (r && !ret)
diff --git a/utils/edid-decode/edid-decode.h b/utils/edid-decode/edid-decode.h
index 8ecd44f312fd..9a527818875f 100644
--- a/utils/edid-decode/edid-decode.h
+++ b/utils/edid-decode/edid-decode.h
@@ -565,6 +565,9 @@ struct edid_state {
        int parse_eld_file(const std::string &fname);
        void parse_eld_baseline(const unsigned char *x, unsigned size);
 
+       int parse_scdc_pdata(parse_data &pdata);
+       void parse_scdc(const unsigned char *scdc, unsigned size);
+
        int parse_hdcp_pdata(parse_data &pdata);
        void parse_hdcp(const unsigned char *hdcp, unsigned size);
 };
@@ -657,6 +660,7 @@ int read_edid(int adapter_fd, unsigned char *edid, bool 
silent = false);
 int test_reliability(int adapter_fd, unsigned secs, unsigned msleep);
 int read_hdcp(int adapter_fd, parse_data &pdata);
 int read_hdcp_ri(int adapter_fd, double ri_time);
+int read_scdc(int adapter_fd, parse_data &pdata, bool update_only);
 
 #else
 
@@ -664,6 +668,7 @@ static inline int read_edid(int adapter_fd, unsigned char 
*edid) { return -ENODE
 static inline int test_reliability(int adapter_fd, unsigned secs, unsigned 
msleep) { return -ENODEV; }
 static inline int read_hdcp(int adapter_fd) { return -ENODEV; }
 static inline int read_hdcp_ri(int adapter_fd, double ri_time) { return 
-ENODEV; }
+static inline int read_scdc(int adapter_fd, parse_data &pdata, bool 
update_only) { return -ENODEV; }
 
 #endif
 
diff --git a/utils/edid-decode/meson.build b/utils/edid-decode/meson.build
index d0fd3d094e37..1906826cc69b 100644
--- a/utils/edid-decode/meson.build
+++ b/utils/edid-decode/meson.build
@@ -9,8 +9,9 @@ edid_decode_sources = [
        'parse-ls-ext-block.cpp',
        'parse-vtb-ext-block.cpp',
        'parse-if.cpp',
-       'parse-eld.cpp',
+       'parse-scdc.cpp',
        'parse-hdcp.cpp',
+       'parse-eld.cpp',
 ]
 
 edid_decode_args = []
diff --git a/utils/edid-decode/parse-scdc.cpp b/utils/edid-decode/parse-scdc.cpp
new file mode 100644
index 000000000000..d27972ee7a0c
--- /dev/null
+++ b/utils/edid-decode/parse-scdc.cpp
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright 2024 Cisco Systems, Inc. and/or its affiliates. All rights 
reserved.
+ *
+ * Author: Hans Verkuil <[email protected]>
+ */
+
+#include <stdio.h>
+
+#include "edid-decode.h"
+
+static void print_scdc_update(const unsigned char *scdc_update)
+{
+       unsigned char flags = scdc_update[0];
+
+       printf("Update Flags: 0x%02x 0x%02x\n", flags, scdc_update[1]);
+       if (flags & 0x01)
+               printf("\tStatus_Update\n");
+       if (flags & 0x02)
+               printf("\tCED_Update\n");
+       if (flags & 0x04)
+               printf("\tRR_Test\n");
+       if (flags & 0x08)
+               printf("\tSource_Test_Update\n");
+       if (flags & 0x10)
+               printf("\tFRL_start\n");
+       if (flags & 0x20)
+               printf("\tFLT_update\n");
+       if (flags & 0x40)
+               printf("\tRSED_Update\n");
+       if (flags & 0x80)
+               printf("\tLIP_Update\n");
+}
+
+void edid_state::parse_scdc(const unsigned char *scdc, unsigned size)
+{
+       static const char *frl_rates[] = {
+               "Disable FRL",
+               "3 Lanes at 3 Gbps per Lane",
+               "3 Lanes at 6 Gbps per Lane",
+               "4 Lanes at 6 Gbps per Lane",
+               "4 Lanes at 8 Gbps per Lane",
+               "4 Lanes at 10 Gbps per Lane",
+               "4 Lanes at 12 Gbps per Lane",
+               "4 Lanes at 16 Gbps per Lane",
+               "4 Lanes at 20 Gbps per Lane",
+               "4 Lanes at 24 Gbps per Lane",
+       };
+       unsigned char v;
+
+       if (size == 2) {
+               print_scdc_update(scdc);
+               return;
+       }
+
+       printf("Sink Version: %u Source Version: %u\n", scdc[0x01], scdc[0x02]);
+
+       v = scdc[0x03];
+       printf("Sink Supported Features: 0x%02x\n", v);
+       if (v & 0x80)
+               printf("\tSink_LIP_Sup\n");
+
+       v = scdc[0x05];
+       printf("Source Supported Features: 0x%02x\n", v);
+       if (v & 0x80)
+               printf("\tSource_LIP_Sup\n");
+
+       print_scdc_update(scdc + 0x10);
+
+       v = scdc[0x20];
+       printf("TMDS Configuration: 0x%02x\n", v);
+       if (v & 0x01)
+               printf("\tScrambling_Enable\n");
+       printf("\tTMDS_Bit_Clock_Ratio: 1/%u\n", (v & 0x02) ? 40 : 10);
+
+       v = scdc[0x21];
+       printf("TMDS Scrambler Status: 0x%02x\n", v);
+       if (v & 0x01)
+               printf("\tTMDS_Scrambling_Status\n");
+
+       v = scdc[0x30];
+       printf("Sink Configuration: 0x%02x 0x%02x\n", v, scdc[0x31]);
+       if (v & 0x01)
+               printf("\tRR_Enable\n");
+       if (v & 0x02)
+               printf("\tFLT_no_retrain\n");
+       if (v & 0x04)
+               printf("\tDAISY_ERR\n");
+       if (v & 0x08)
+               printf("\tMONO_DIR_ON\n");
+       if (v & 0x10)
+               printf("\tMONO_DIR_ERR\n");
+       if (v & 0x20)
+               printf("\tCA_PWR_ERR\n");
+       v = scdc[0x31];
+       if ((v & 0xf) >= ARRAY_SIZE(frl_rates))
+               printf("\tFRL_Rate: %u\n", v & 0xf);
+       else
+               printf("\tFRL_Rate: %s\n", frl_rates[v & 0xf]);
+       printf("\tFFE_Levels: %u\n", v >> 4);
+
+       bool uses_4lanes = (v & 0xf) >= 3;
+
+       v = scdc[0x35];
+       printf("Source Test Configuration: 0x%02x\n", v);
+       if (v & 0x02)
+               printf("\tTxFFE_Pre_Shoot_Only\n");
+       if (v & 0x04)
+               printf("\tTxFFE_De_Emphasis_Only\n");
+       if (v & 0x08)
+               printf("\tTxFFE_No_FFE\n");
+       if (v & 0x20)
+               printf("\tFLT_no_timeout\n");
+       if (v & 0x40)
+               printf("\tDSC_FRL_Max\n");
+       if (v & 0x80)
+               printf("\tFRL_Max\n");
+
+       v = scdc[0x40];
+       printf("Status Flags: 0x%02x 0x%02x 0x%02x\n", v, scdc[0x41], 
scdc[0x42]);
+       if (v & 0x01)
+               printf("\tClock_Detected\n");
+       if (v & 0x02)
+               printf("\tCh0_Ln0_Locked\n");
+       if (v & 0x04)
+               printf("\tCh1_Ln1_Locked\n");
+       if (v & 0x08)
+               printf("\tCh2_Ln2_Locked\n");
+       if (v & 0x10)
+               printf("\tLane3_Locked\n");
+       if (v & 0x40)
+               printf("\tFLT_Ready\n");
+       if (v & 0x80)
+               printf("\tDSC_DecodeFail\n");
+       if (scdc[0x41] || scdc[0x42]) {
+               v = scdc[0x41];
+               printf("\tLn0_LTP_req: %u\n", v & 0xf);
+               printf("\tLn1_LTP_req: %u\n", v >> 4);
+               v = scdc[0x42];
+               printf("\tLn2_LTP_req: %u\n", v & 0xf);
+               printf("\tLn3_LTP_req: %u\n", v >> 4);
+       }
+
+       if ((scdc[0x51] & 0x80) || (scdc[0x53] & 0x80) || (scdc[0x55] & 0x80) ||
+           (scdc[0x58] & 0x80) || (scdc[0x5a] & 0x80)) {
+               printf("Character Error Detection:\n");
+               unsigned short cnt = scdc[0x51] << 8 | scdc[0x50];
+               if (cnt & 0x8000)
+                       printf("\tChannel 0 Error Count: %u\n", cnt & 0x7fff);
+               cnt = scdc[0x53] << 8 | scdc[0x52];
+               if (cnt & 0x8000)
+                       printf("\tChannel 1 Error Count: %u\n", cnt & 0x7fff);
+               cnt = scdc[0x55] << 8 | scdc[0x54];
+               if (cnt & 0x8000)
+                       printf("\tChannel 2 Error Count: %u\n", cnt & 0x7fff);
+               cnt = scdc[0x58] << 8 | scdc[0x57];
+               if (cnt & 0x8000)
+                       printf("\tLane 3 Error Count: %u\n", cnt & 0x7fff);
+               unsigned char sum = 0;
+               for (unsigned i = 0x50; i <= 0x55; i++)
+                       sum += scdc[i];
+               if (uses_4lanes)
+                       sum += scdc[0x57] + scdc[0x58];
+               sum = 0xff - sum;
+               sum++;
+               if (sum != scdc[0x56])
+                       printf("\tInvalid Checksum: expected 0x%02x, got 
0x%02x\n",
+                              sum, scdc[0x56]);
+               cnt = scdc[0x5a] << 8 | scdc[0x59];
+               if (cnt & 0x8000)
+                       printf("\tReed-Solomon Corrections Counter: %u\n", cnt 
& 0x7fff);
+       } else {
+               printf("Character Error Detection: no errors detected\n");
+       }
+
+       v = scdc[0xc0];
+       if (v) {
+               printf("Test Read Request: 0x%02x\n", v);
+               if (v & 0x80)
+                       printf("\tTestReadRequest\n");
+               printf("\tTestReadRequestDelay: %ums\n", v & 0x7f);
+       }
+
+       if (scdc[0xd0] || scdc[0xd1] || scdc[0xd2]) {
+               printf("Manufacturer Specific:\n");
+               printf("\tOUI: %02x-%02x-%02x\n", scdc[0xd2], scdc[0xd1], 
scdc[0xd0]);
+               char s[9] = {};
+               memcpy(s, scdc + 0xd3, 8);
+               printf("\tDevice_ID_String: '%s'\n", s);
+               printf("\tHW Revision: %u.%u SW Revision: %u.%u\n",
+                      scdc[0xdb] >> 4, scdc[0xdb] & 0xf,
+                      scdc[0xdc], scdc[0xdd]);
+       } else {
+               printf("Manufacturer Specific: none\n");
+       }
+}
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to